List 序言两个列表完全相同

List 序言两个列表完全相同,list,prolog,List,Prolog,我想写一个函数,如果两个列表的元素顺序完全相同,则返回true 我这样试过: same([ ], [ ]). same([H1|R1], [H2|R2]):- H1 == H2, same(R1, R2). 当两个列表相同时,它返回true,如果有 ?- same(X, [1, 2, 3]). 我要它回来 X = [1, 2, 3]. 但如果输入是这样的话,它就不起作用了。以下是我得到的一些示例输出: ?- same([1, 2], [1, 2]). true.

我想写一个函数,如果两个列表的元素顺序完全相同,则返回true

我这样试过:

same([ ], [ ]).   
same([H1|R1], [H2|R2]):-
    H1 == H2,
    same(R1, R2).
当两个列表相同时,它返回true,如果有

?- same(X, [1, 2, 3]).
我要它回来

X = [1, 2, 3].
但如果输入是这样的话,它就不起作用了。以下是我得到的一些示例输出:

?- same([1, 2], [1, 2]).

true.

?- same([2, 1], [1, 2]).

false.

?- same(X, [1, 2, 3]).

false.

?- same([1, 2, 3], [1, 2, X]).

false.

如何修复它?

问题在于,您使用==/2检查两个项是否实例化为相同的,而不是=/2检查两个项是统一的还是可统一的。只要换成统一:

same([], []).

same([H1|R1], [H2|R2]):-
    H1 = H2,
    same(R1, R2).
然后,这将具有您正在寻找的行为:

| ?- same(X, [1, 2, 3]).

X = [1,2,3] ? a

no
| ?- same([1, 2], [1, 2]).

(1 ms) yes
| ?- same([2, 1], [1, 2]).

no
| ?- same([1, 2, 3], [1, 2, X]).

X = 3

(1 ms) yes
| ?- same([A,B,C], L).

L = [A,B,C]

yes
% In this last example, A, B, and C are variables. So it says L is [A,B,C],
% whatever A, B, and C are.
如果在Prolog中查询X==3,并且X未绑定到值3,或者只是未绑定,那么它将失败。如果X是未绑定的,并且您查询X=3,那么Prolog将把X绑定到3,并且它将成功

有关=/2和==/2之间差异的更多信息,请参阅

您还可以使用maplist获得一个简洁的解决方案。maplist对于遍历列表非常方便:

same(L1, L2) :- maplist(=, L1, L2).
这里仍然使用unification=/2,原因与上面完全相同。 最后,@Boris指出,在Prolog中,统一谓词将在整个列表上工作。在这种情况下,这就足够了:

same(L1, L2) :- L1 = L2.
或相当于:

same(L, L).  % Would unify L1 and L2 queried as same(L1, L2)
如果列表相同,或者试图通过依次统一每个元素来统一它们,则此操作将成功

| ?- same([1,2,X], [1,2,3]).    % Or just [1,2,X] = [1,2,3]

X = 3

yes
| ?- same([1,2,X], [1,2,3,4]).  % Or just [1,2,X] = [1,2,3,4]

no

前面更详细的方法被认为是列表处理中的一个练习,以供说明。但是比较和/或统一列表的最简单和最正确的方法是L1=L2。

问题是,您使用==/2检查两个项目是否实例化相同,而不是=/2检查两个项目是否统一或可统一。只要换成统一:

same([], []).

same([H1|R1], [H2|R2]):-
    H1 = H2,
    same(R1, R2).
然后,这将具有您正在寻找的行为:

| ?- same(X, [1, 2, 3]).

X = [1,2,3] ? a

no
| ?- same([1, 2], [1, 2]).

(1 ms) yes
| ?- same([2, 1], [1, 2]).

no
| ?- same([1, 2, 3], [1, 2, X]).

X = 3

(1 ms) yes
| ?- same([A,B,C], L).

L = [A,B,C]

yes
% In this last example, A, B, and C are variables. So it says L is [A,B,C],
% whatever A, B, and C are.
如果在Prolog中查询X==3,并且X未绑定到值3,或者只是未绑定,那么它将失败。如果X是未绑定的,并且您查询X=3,那么Prolog将把X绑定到3,并且它将成功

有关=/2和==/2之间差异的更多信息,请参阅

您还可以使用maplist获得一个简洁的解决方案。maplist对于遍历列表非常方便:

same(L1, L2) :- maplist(=, L1, L2).
这里仍然使用unification=/2,原因与上面完全相同。 最后,@Boris指出,在Prolog中,统一谓词将在整个列表上工作。在这种情况下,这就足够了:

same(L1, L2) :- L1 = L2.
或相当于:

same(L, L).  % Would unify L1 and L2 queried as same(L1, L2)
如果列表相同,或者试图通过依次统一每个元素来统一它们,则此操作将成功

| ?- same([1,2,X], [1,2,3]).    % Or just [1,2,X] = [1,2,3]

X = 3

yes
| ?- same([1,2,X], [1,2,3,4]).  % Or just [1,2,X] = [1,2,3,4]

no

前面更详细的方法被认为是列表处理中的一个练习,以供说明。但是比较和/或统一列表的最简单和最正确的方法是L1=L2。

这个答案和最初的问题一样奇怪。为什么你不直接统一这两个列表?“鲍里斯,如果你认为这是列表处理中的一个练习,这个问题就不奇怪了。但你的答案是对的。我忘记了最简单的方法,因为我在演示列表处理之后提供了一个答案。谢谢你指出。事实上,sameX,X.已经足够了,但这实际上是=X,X。如果你不关心顺序,你会怎么做?@hiswendy最简单的方法是使用msort将它们排序,而不是删除重复项,然后再尝试将它们统一起来。所以,sameL1,L2:-msortL1,S1,msortL2,S2,S1=S2。一个较长的方法,但不太必要,是逐个元素并使用select/3。这个答案和原来的问题一样奇怪。为什么你不直接统一这两个列表?“鲍里斯,如果你认为这是列表处理中的一个练习,这个问题就不奇怪了。但你的答案是对的。我忘记了最简单的方法,因为我在演示列表处理之后提供了一个答案。谢谢你指出。事实上,sameX,X.已经足够了,但这实际上是=X,X。如果你不关心顺序,你会怎么做?@hiswendy最简单的方法是使用msort将它们排序,而不是删除重复项,然后再尝试将它们统一起来。所以,sameL1,L2:-msortL1,S1,msortL2,S2,S1=S2。一个较长的方法,但不太必要,是逐个元素并使用select/3。