在 Prolog 中使用条件

Use of conditionals in Prolog

我对在序言中如何使用条件感到困惑。 示例 1 是条件语句的情况,而 示例 2 显示的情况是 NewPos = Exit-> 运算符。它是检查 NewPos 是否等于 Exit 还是值 Exit 被分配给 NewPosis 不应该用于在 prolog 中赋值吗?

抱歉,如果这是一个非常基本的语法问题。

示例 1

Current = b(_,Cost,NewPos),
( Exit=none   -> backtrack_path(Current,Visited,RPath)
; Exit=b(5,5) -> backtrack_path(Current,Visited,RPath)

示例 2

Current = b(_,Cost,NewPos),
( Exit=none -> backtrack_path(Current,Visited,RPath)
; otherwise -> NewPos = Exit,
             backtrack_path(Current,Visited,RPath)

要更详细地了解 Prolog -> 运算符,请参阅 。下面介绍了您的示例。

例1:

Current = b(_,Cost,NewPos),

Current 与术语 b(_, Cost, NewPos) 统一起来。 Unficiation 在 Prolog 中 not 与赋值相同。在 unification 中,Prolog 将尝试匹配 =/2 的两个参数,可能在任一侧实例化变量以实现统一。例如,如果 CurrentCostNewPos 都未实例化,则 Current 将与 b(_, Cost, NewPos) 实例化(使用 相同 变量,CostNewPos。如果稍后 Cost 实例化为 10,那么 Current 也将变为, b(_, 10, NewPos), 实际上.

( Exit=none   -> backtrack_path(Current,Visited,RPath)
; Exit=b(5,5) -> backtrack_path(Current,Visited,RPath)

;precedence 低于 ->,所以这实际上是:

(   Exit=none
->  backtrack_path(Current,Visited,RPath)
;   (   Exit=b(5,5)
    ->  backtrack_path(Current,Visited,RPath),
        ...
    ),
    ...
)

Exit = none 将尝试统一 Exit 和原子 none。如果 Exit 未实例化(然后将 Exit 实例化为 none),它将成功,或者如果 Exit 已经被实例化为 none,则可以成功。如果使用与 none.

不匹配的任何术语实例化 Exit,它将失败

如果Exit = none成功,则调用第一个backtrack_path(Current, Visited, RPath)。如果失败,则尝试统一 Exitb(5,5)。如果前面的 Exit = none 失败了,那么我们走到这一步是因为 Exit 已经与不匹配 none 的东西统一了,只有当它成功时 Exit = b(5,5)已经统一了一个看起来像 b(X, Y) 的术语。否则,它也会失败。如果成功,将再次调用 backtrack_path(Current, Visited, RPath)

例二:

Current = b(_,Cost,NewPos),
( Exit=none -> backtrack_path(Current,Visited,RPath)
; otherwise -> NewPos = Exit,
             backtrack_path(Current,Visited,RPath)

, 的优先级最高,其次是 ->,然后是 ;。所以这实际上是:

Current = b(_,Cost,NewPos),
(   Exit=none
->  backtrack_path(Current,Visited,RPath)
;   (   otherwise
    ->  (   NewPos = Exit,
            backtrack_path(Current,Visited,RPath),
            ...
        ),
        ...
    ),
    ...
 )

参见上面关于统一的讨论。如果 Exit = none 成功,则调用 backtrack_path(Current, Visited, RPath)。否则,然后 otherwise 调用完成(请注意,如果 otherwise 是一个代码块,那么运算符优先级会影响我在上面显示的分组,所以我假设 otherwise 是一个块优先于以下 ->).

如果 otherwise 成功,那么 Prolog 会尝试 NewPos = Exit,如果成功,它将继续调用 backtrack_path(Current, Visited, RPath)。如果 NewPos = Exit 统一失败,那么在这种情况下,缺少 "else" 或 "OR" (;) 类型的表达式,它可能会一直回溯到 Current = b(_, Cost, NewPos).它回溯到哪里完全取决于你在这个子句中的其他代码(它有点假设性地呈现,所以它可以是任何东西)。

关于is/2

is/2 用于 (a) 评估作为其第二个参数的数值表达式,以及 (b) 将表达式评估的结果与第一个参数统一。这里有一些例子,也显示了与=/2(统一)的对比:

| ?- X = A + B.

X = A+B

yes

在这里,X 统一 A + B。所以 X 现在用术语 A+B 实例化(这是术语,'+'(A, B)

| ?- A = 2, B = 3, X = A + B.

A = 2
B = 3
X = 2+3

yes

X 统一 A + BA2 统一(因此 A 实例化 的值为 2),而 B 是与 3 统一。所以 X2+3 (或 `'+'(2,3))统一。

| ?- A = 2, B = 3, X is A + B.

A = 2
B = 3
X = 5

yes

is 右侧的表达式(is/2 的第二个参数)被计算为 5。然后X实例化为5.

| ?- A = 2, X is A + B.
uncaught exception: error(instantiation_error,(is)/2)

B 未实例化,因此无法计算表达式 A + B,因此 is/2 由于实例化错误而失败。

| ?- A = 2, B = 3, Z = 5, Z is A + B.

A = 2
B = 3
Z = 5

yes

ABZ 都实例化为数值,Z is A + B 成功,因为 A + B 计算为 5 ,可与 Z 统一,后者的值也为 5.

| ?- A = 2, B = 3, Z = 4, Z is A + B.

no

ABZ 都实例化为数值,并且 Z is A + B 失败,因为 A + B 计算为 5 ,它不能与 Z 统一,其值为 4.

| ?- A = 2, B = 3, X = A + B, Z is X.

A = 2
B = 3
X = 2+3
Z = 5

yes

X 与术语 A + B 统一,这是术语 2 + 3 因为 A 已用 2 实例化,并且 B3Z 与表达式 X(即 2 + 3)的求值统一,因此具有值 5.