如何将常数列表与变量列表进行比较



谓词需要比较两个列表(一个变量之一,一个常数(:

?- 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 ",因此最终不在左列表中的所有元素,都在右列表中的值。

最新更新