我对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)
答案 0 :(得分:3)
有关Prolog ->
运算符的详细信息,请参阅What's the meaning of Prolog operator '->'。您的示例如下所示。
示例1:
Current = b(_,Cost,NewPos),
将Current
与术语b(_, Cost, NewPos)
统一起来。 Prolog中的 Unficiation 不与赋值相同。在统一中,Prolog将尝试匹配=/2
两个可能在两侧实例化变量的参数来实现统一。例如,如果Current
,Cost
和NewPos
都未经实例化,则Current
将使用b(_, Cost, NewPos)
进行实例化(使用相同变量,Cost
和NewPos
。如果稍后使用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
未实例化(然后将none
与Exit
实例化),则会成功;如果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
这个词。 2
与A
统一(因此2
实例化,其值为B
),3
与X
统一{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
B
,Z
和Z is A + B
都已实例化为数值,A + B
成功,因为5
评估为Z
,与5
一致,其值| ?- A = 2, B = 3, Z = 4, Z is A + B.
no
。
A
B
,Z
和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
已使用B
实例化,3
与Z
。 X
与表达式2 + 3
(5
)的评估统一,因此值为var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);
。