谓词需要比较两个列表(一个变量之一,一个常数(:
?- 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(?
您可以在每个两个不同的变量变量之间添加 dif/2
约束。
我们可以通过 term_variables/2
获得变量列表,然后我们可以通过使用 maplist/2
来设计一个在每两个不同变量之间应用dif
的谓词all_diff/1
,喜欢:
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/3
is/2
作为目标。
例如:
?- 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 ",因此最终不在左列表中的所有元素,都在右列表中的值。