你能帮我理解回答下一个查询的引擎吗?
?- _ = _.
?- _ = 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
将变量CCD_ 5与化合物项CCD_。_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