首页 > 解决方案 > 匿名变量 - prolog - 一些查询

问题描述

你能帮我理解回答下一个查询的引擎吗?

?- _ = _.
?- _ = 1.
?- A = _, B = _, C = A + B + 1.

还有一些额外的查询(与匿名变量无关):

?- B = A + 1, A = C, C = B - 1.

我知道上述查询的答案,但我想了解 prolog 如何找到这些答案:)

谢谢!

标签: prologprolog-anonymous-variable

解决方案


_被称为 _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

推荐阅读