我有一个列表,所有对都包含1..3,希望列表中的所有对彼此不同。例如,对于以下事实,预期结果是
[[1, 1], [1, 2], [2, 1], [1, 3], [2, 3], [3, 1], [3, 2], [2, 2], [3, 3]]
然而,使用我的函数,似乎Prolog没有派生出该变量,输出仍然是临时变量_4848
而不是数字2.
[[1, 1], [1, 2], [2, 1], [1, 3], [_4848, 3], [3, 1], [3, 2], [2, 2], [3, 3]]
以下是我的功能参考:
Grid([[1,1],[1,2],[2,1],[1,3],[_,3],[3,1],[3,2],[2,2],[3,3]]).
completegrid(G) :-
append(G, Vs),
Vs ins 1..3,
is_set(G).
我用
运行它Grid(G), completegrid(G).
有人可以解释一下吗?谢谢。
答案 0 :(得分:4)
您的实施中存在两个问题,首先事实不能从资本开始:
Grid([[1,1],[1,2],[2,1],[1,3],[_,3],[3,1],[3,2],[2,2],[3,3]]).
应该是:
grid([[1,1],[1,2],[2,1],[1,3],[_,3],[3,1],[3,2],[2,2],[3,3]]).
否则会出现语法错误,与Grid(G), completegrid(G).
相同应该是:grid(G), completegrid(G)
。
第二个也是最重要的错误是Vs ins 1..3
在Vs的元素中设置约束,但不评估,因此变量将保留变量(约束为值1..3时实例化),您需要使用label/2
进行实例化:
:- use_module(library(clpfd)).
grid([[1,1],[1,2],[2,1],[1,3],[_,3],[3,1],[3,2],[2,2],[3,3]]).
completegrid(G) :-
append(G, Vs),
Vs ins 1..3, label(Vs),
is_set(G).
示例:
?- grid(G), completegrid(G).
G = [[1, 1], [1, 2], [2, 1], [1, 3], [2, 3], [3, 1], [3, 2], [2, 2], [3, 3]] ;
false.
更重要的一点是:
is_set / 2是非单调的
这意味着您放置影响is_set/2
参数的约束会影响谓词的行为,例如:
completegrid(G) :-
append(G, Vs),
Vs ins 1..3,
is_set(G),label(Vs).
^^^^^^
现在尝试:
?- grid(G), completegrid(G).
G = [[1, 1], [1, 2], [2, 1], [1, 3], [1, 3], [3, 1], [3, 2], [2|...], [...|...]] [write]
G = [[1, 1], [1, 2], [2, 1], [1, 3], [1, 3], [3, 1], [3, 2], [2, 2], [3, 3]] ;%WRONG !!
G = [[1, 1], [1, 2], [2, 1], [1, 3], [2, 3], [3, 1], [3, 2], [2, 2], [3, 3]] ;
G = [[1, 1], [1, 2], [2, 1], [1, 3], [3, 3], [3, 1], [3, 2], [2, 2], [3, 3]]. %WRONG !!
答案 1 :(得分:1)
人们对clpfd
犯下的一个常见错误就是:
X in 1..3
执行不将值分配给X
。它向X
添加约束。如果我们在终端中写这个,我们得到:
?- use_module(library(clpfd)).
true.
?- X in 1..3.
X in 1..3.
只有当您使用变量列表调用label/1
时,Prolog才会搜索变量的配置,以便验证这些约束。
由于您没有X
,因此过去is_set/1
的列表仍会包含一个自由变量。现在is_set
对项目执行重复检查,但它仅检查术语是否完全相等。因此is_set([X,Y])
被认为是真的,is_set([[1,2],[1,X]])
也是如此。它不添加X
应与X
不同的约束。
但是有一个dif/2
谓词,允许用来表示差异约束。我们可以定义dif_all/1
谓词:
dif_all([]).
dif_all([H|T]) :-
maplist(dif(H),T),
dif_all(T).
现在我们的程序可以改为:
completegrid(G) :-
append(G, Vs),
Vs ins 1..3,
dif_all(G),
label(G).