在Prolog中使用条件

时间:2015-06-14 15:11:51

标签: syntax prolog

我对prolog中如何使用条件感到困惑。虽然示例1 是条件的情况,但示例2 显示了NewPos = Exit运算符另一侧的->的情况。是在检查NewPos是否等于Exit还是将值Exit分配给NewPos?不应该使用is来分配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)

1 个答案:

答案 0 :(得分:3)

有关Prolog ->运算符的详细信息,请参阅What's the meaning of Prolog operator '->'。您的示例如下所示。

示例1:

Current = b(_,Cost,NewPos),

Current与术语b(_, Cost, NewPos)统一起来。 Prolog中的 Unficiation 与赋值相同。在统一中,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) 1}},实际上。

;

->的{​​{3}}低于( Exit=none -> backtrack_path(Current,Visited,RPath) ; ( Exit=b(5,5) -> backtrack_path(Current,Visited,RPath), ... ), ... ) ,所以这实际上是:

Exit = none

Exit会尝试统一none和原子Exit。如果Exit未实例化(然后将noneExit实例化),则会成功;如果none已经实例化为Exit,则可以成功。如果none与任何不匹配Exit = none的字词实例化,则会失败。

如果backtrack_path(Current, Visited, RPath)成功,则调用第一个Exit。如果失败,则会尝试将b(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)

示例2:

,

->具有最高优先级,其次是;,后跟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)的块。

如果NewPos = Exit成功,则Prolog会尝试backtrack_path(Current, Visited, RPath),如果成功,则会继续调用NewPos = Exit。如果;统一失败,那么,在这种情况下,缺少"否则"或"或" (Current = b(_, Cost, NewPos))表达式,它可能会一直回溯到is/2。它回溯的地方完全取决于你在这个条款中的其他代码(它有点假设,所以它可以是任何东西)。

关于is/2

=/2用于(a)将数值表达式作为其第二个参数进行计算,并且(b)将表达式求值的结果与第一个参数统一起来。以下是一些示例,还显示了与| ?- 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 + B 统一,其中包含A这个词。 2A统一(因此2 实例化,其值为B),3X统一{1}}。因此,2+3| ?- A = 2, B = 3, X is A + B. A = 2 B = 3 X = 5 yes (或“' +'(2,3))统一。

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 因实例化错误而失败。

A

BZZ is A + B都已实例化为数值,A + B成功,因为5评估为Z,与5一致,其值| ?- A = 2, B = 3, Z = 4, Z is A + B. no

A

BZZ 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已使用B实例化,3ZX与表达式2 + 35)的评估统一,因此值为var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; arr1.push(...arr2);