prolog约束编程与forall/2

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

我正在使用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_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
在概念上也肯定是一个整数,但它尚未实例化为基本术语。