谓词需要像这样比较两个列表(一个变量,一个常量):
?- test([A,B,B],[1,2,3]).
false.
?- test([A,B,B],[1,2,2]).
true.
?- test([A,B,C],[1,2,2]).
false.
首先,我将此谓词与每个变量关联到其常量:
set([],[]).
set([X],[Y]):-X is Y.
set([H1|T1],[H2|T2]):-H1 is H2, set(T1,T2).
它适用于上面的前两个示例,但是没有写“ true”。同样,它对于第三个也不起作用:
?- set([A,B,C],[1,2,2]).
A = 1,
B = C, C = 2
我该如何修改此谓词,以便它检查T1是否已被使用,并且在这种情况下,它是否已与另一个变量关联(因此返回false)?
答案 0 :(得分:1)
您可以在每两个不同的变量之间添加一个dif/2
constraint。
我们可以使用term_variables/2
获取变量列表,然后例如可以设计一个谓词all_diff/1
,该谓词dif
通过使用{{3 }},例如:
all_diff([]).
all_diff([H|T]) :-
maplist(dif(H), T),
all_diff(T).
因此我们可以将set/2
定义为:
set(V, W) :-
term_variables(V, VV),
all_diff(VV),
maplist(is, V, W).
原始set/2
可以写为maplist/2
,以maplist/3
为目标。
例如:
?- set([A,B,B], [1,2,2]).
A = 1,
B = 2.
?- set([A,B,C], [1,2,2]).
false.
如果第二个列表仅包含术语,并且您不要评估表达式,我们可以-如@DanielLyons所说-只需使用V = W
:
set(V, W) :-
term_variables(V, VV),
all_diff(VV),
V = W.
由于统一算法将“ peal ”函子,因此最终将右列表中的值取消左列表中的所有元素。