Prolog 比较列表结构

jve*_*len 1 list prolog

我正在尝试比较序言中的两个列表,例如

?- compare([[X],Y,Z],[[A],B,C]).
true.
?- compare([X,Y,Z],[[A],B,C]).
false.
Run Code Online (Sandbox Code Playgroud)

我不能使用 ==/2 运算符,因为逻辑变量不相同,因此这两种情况都会评估为 false。而且我显然不能使用 =/2 因为这在两种情况下都会评估为真。

有关如何解决此问题的任何建议?

Pau*_*ura 5

检查两个术语是否具有相同结构的另一种解决方案是使用 ISO Prolog 标准谓词subsumes_term/2variant/2当一个术语是另一个术语的变体时,以下谓词为真:

variant(Term1, Term2) :-
    \+ \+ subsumes_term(Term1, Term2),
    \+ \+ subsumes_term(Term2, Term1).
Run Code Online (Sandbox Code Playgroud)

双重否定的使用避免了在参数中实例化任何变量。使用例如 GNU Prolog 进行测试:

| ?- variant([[X],Y,Z],[[A],B,C]).

(1 ms) yes
| ?- variant([X,Y,Z],[[A],B,C]).

no
Run Code Online (Sandbox Code Playgroud)

  • 它不应该是因为`[A,B]` 不是`[B,A]` 的变体,除非`A = B`。例如,如果你做`A = 1, B = 2`,你会得到`variant([1,2], [2,1])`。但是实现 `variant/2` 或 `(=@=)/2` 的 Prolog 编译器会警告你不要在它们的参数之间使用共享变量调用这些谓词。 (3认同)