prolog约束编程与forall/2
我正在使用SWI 7.2.3,并有以下程序:prolog约束编程与forall/2,prolog,clpfd,Prolog,Clpfd,我正在使用SWI 7.2.3,并有以下程序: ?-use_module(library(clpfd)). :- dynamic size/2,wall/2. in_board(X,Y):-X #> 0,Y #> 0,size(N,M),X #=< N,Y #=< M. wall_exists_line(X,Y,W) :- wall(X,Z),(Y #=< Z,W #=< Y;Y#=< W,Z#=< Y). wall_not_exists_li
?-use_module(library(clpfd)).
:- dynamic size/2,wall/2.
in_board(X,Y):-X #> 0,Y #> 0,size(N,M),X #=< N,Y #=< M.
wall_exists_line(X,Y,W) :- wall(X,Z),(Y #=< Z,W #=< Y;Y#=< W,Z#=< Y).
wall_not_exists_line(X,Y,W) :- not(wall_exists_line(X,Y,W)).
same_line(X,Y,Z,W):- X #= Z,in_board(Z,W),in_board(X,Y),wall_not_exists_line(X,Y,W).
不幸的是,
not(wall(X,Z))
的意思是“没有X或Z存在,而wall(X,Z)是真的”,我不想要这个,因为wall
是动态的,我不能用它做任何事情。我找到了解决方案
not(wall\u exists\u line(X,Y,W))
将检查X
和Y
和W
的每个值,如果它们没有固定值
in_board(X,Y)
约束间隔中的X
和Y
,但不是固定值,因此not
将尝试间隔中的每个值
解决方案是在输入not
之前实例化变量X、Y、W
,这是通过将主板中的更改为:
in_board(X,Y):-size(N,M),between(0,N,X),between(0,M,Y).
通过这种方式,between
将实例化X
和Y
,幸运的是between
给出了间隔中的所有值
clpfd和just之间的主要区别在于,clpfd返回域,而之间的——如果第三个参数没有实例化——返回两个值之间的每个值。我找到了解决方案
not(wall\u exists\u line(X,Y,W))
将检查X
和Y
和W
的每个值,如果它们没有固定值
in_board(X,Y)
约束间隔中的X
和Y
,但不是固定值,因此not
将尝试间隔中的每个值
解决方案是在输入not
之前实例化变量X、Y、W
,这是通过将主板中的更改为:
in_board(X,Y):-size(N,M),between(0,N,X),between(0,M,Y).
通过这种方式,between
将实例化X
和Y
,幸运的是between
给出了间隔中的所有值
clpfd和just之间的主要区别在于,clpfd返回域,而之间的-如果第三个参数未实例化-返回两个值之间的每个值。使用CLP(FD)约束时,您不再需要介于/3
之间:使用枚举谓词indomain/1
,label/1
或labeling/2
可在需要时获得地面解决方案。更优雅的做法是将剩下的谓词泛化为也可以处理任意变量,而不仅仅是地面整数!我试过indomain
,label
等等,我不知道如何使用它们。无论如何,我不明白你的上一句话,你说的“地面整数”是什么意思?如果X
受到足够的约束,例如X在0..N
中,你可以简单地声明indomain(X)
来获得X
的拟合整数。“基本整数”指的是1、7、10等术语。请注意,如果我们在0..5
中有一个约束X,那么X
在概念上也肯定是一个整数,但它尚未实例化为基本项。当使用CLP(FD)约束时,您不再需要between/3
:在需要时使用枚举谓词indomain/1
、label/1
或labeling/2
,以获得基本解决方案。更优雅的做法是将剩下的谓词泛化为也可以处理任意变量,而不仅仅是地面整数!我试过indomain
,label
等等,我不知道如何使用它们。无论如何,我不明白你的上一句话,你说的“地面整数”是什么意思?如果X
受到足够的约束,例如X在0..N
中,你可以简单地声明indomain(X)
来获得X
的拟合整数。“基本整数”指的是1、7、10等术语。请注意,如果我们在0..5
中有一个约束X,那么X
在概念上也肯定是一个整数,但它尚未实例化为基本术语。