你能帮我理解回答下一个查询的引擎吗?
?- _ = _.
?- _ = 1.
?- A = _, B = _, C = A + B + 1.
还有一些额外的查询(与匿名变量无关):
?- B = A + 1, A = C, C = B - 1.
我知道上述查询的答案,但我想了解 prolog 如何找到这些答案:)
谢谢!
你能帮我理解回答下一个查询的引擎吗?
?- _ = _.
?- _ = 1.
?- A = _, B = _, C = A + B + 1.
还有一些额外的查询(与匿名变量无关):
?- B = A + 1, A = C, C = B - 1.
我知道上述查询的答案,但我想了解 prolog 如何找到这些答案:)
谢谢!
_
被称为 _anonymous 变量。每次出现_
都是一个不同的变量。您可以使用标准的write_canonical/1
内置谓词轻松观察它。例如:
| ?- write_canonical(_ = _).
=(_279,_280)
yes
正如您在查询中观察到的,变量可以与任何术语(包括其他变量)统一。请注意,标准=/2
内置谓词执行统一,而不是相等或算术表达式评估。统一采用两个术语,如果这两个术语相同,或者可以通过统一术语中的任何变量使其相同,则统一成功。例如:
| ?- A + 1 = 2 + B.
A = 2
B = 1
(1 ms) yes
一个查询,例如:
| ?- write_canonical(B = A + 1), nl, B = A + 1, write_canonical(B).
=(_279,+(_280,1))
+(_280,1)
B = A+1
yes
B
将变量与复合项统一起来+(A,1)
。_279
和_280
分别是 和 的内部变量B
表示A
。不同的 Prolog 系统以不同的方式打印这些内部表示。例如,使用 SWI-Prolog:
?- write_canonical(B = A + 1), nl, B = A + 1, write_canonical(B).
=(_,+(_,1))
+(_,1)
B = A+1.
关于您的额外查询,B = A + 1, A = C, C = B - 1
它会创建循环术语。考虑更简单的查询:
| ?- X = f(X).
Prolog 顶层的结果和随后的变量绑定报告取决于特定的 Prolog 系统处理循环项。例如,在 GNU Prolog 中,您将获得:
| ?- X = f(X).
cannot display cyclic term for X
yes
而 SICStus Prolog 报告:
| ?- X = f(X).
X = f(f(f(f(f(f(f(f(f(f(...)))))))))) ?
循环项对某些应用程序很有用,例如互归纳逻辑编程。但是循环项的处理不是标准化的,并且在 Prolog 系统中有所不同。ISO Prolog 标准提供了一个内置谓词 ,unify_with_occurs_check/2
它检查统一是否会创建一个循环项,从而阻止它。例如:
| ?- unify_with_occurs_check(X, f(X)).
no
| ?- unify_with_occurs_check(X, Y).
Y = X
(1 ms) yes