如何比较常量列表和变量列表

时间:2019-05-01 19:05:00

标签: prolog

谓词需要像这样比较两个列表(一个变量,一个常量):

?- 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)?

1 个答案:

答案 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 ”函子,因此最终将右列表中的值取消左列表中的所有元素。