1

我对使用某些规则的查询期间发生的事情感到有些困惑。这是我笔记中的示例代码。

link(fortran, algol60).
link(algol60,cpl).
link(cpl, bcpl).
link(bcpl, c).
link(c, cplusplus).
link(algol60, simula67).
link(simula67, cplusplus).
link(simula67, smalltalk80).

path(L,M) :-   %first path
    link(L,M). %first link

path(L,M) :-   %second path
    link(L,X), %second link
    path(X,M). %third path



 | ?- path(X,bcpl).

当我们查询这个时,我们将调用第一个路径并且 X 将被启动到 cpl,因为 link(cpl,bcpl) 是我们数据库中第一个匹配的东西。所以现在 L = cpl 和 M = bcpl。X = cp?; 然后我们继续按;

接下来发生什么?我们称第一条路径还是第二条路径?如果我们失败了规则会发生什么,我们是否从第一条路径开始?

4

1 回答 1

1

迫切;需要下一个解决方案。如您所知,Prolog 中的替代项用多个子句表示。

确实,从上到下,从左到右的抽象解释不会尝试第一个或第二个路径/2,而是会先尝试看看是否有另一个link(X,bcpl)

由于索引,SWI-Prolog 不会尝试调用其中任何一个(它知道没有另一个合适的链接/2),而是会回溯并尝试下一个路径/2(第二条规则)。

这是一个(部分)跟踪:当您看到 时Redo,这意味着它正在选择下一个可用的替代方案。括号之间的数字是call level,但是你可以看到,对于一些实现细节,证明不是从 1 开始的。

?- leash(-all), trace, path(X,bcpl).
   Call: (7) path(_G2093, bcpl)
   Call: (8) link(_G2093, bcpl)
   Exit: (8) link(cpl, bcpl)
   Exit: (7) path(cpl, bcpl)
X = cpl ;
   Redo: (7) path(_G2093, bcpl)
   Call: (8) link(_G2093, _G2262)
   Exit: (8) link(fortran, algol60)
   Call: (8) path(algol60, bcpl)
   Call: (9) link(algol60, bcpl)
   Fail: (9) link(algol60, bcpl)
   Redo: (8) path(algol60, bcpl)
   Call: (9) link(algol60, _G2262)
   Exit: (9) link(algol60, cpl)
   Call: (9) path(cpl, bcpl)
   Call: (10) link(cpl, bcpl)
   Exit: (10) link(cpl, bcpl)
   Exit: (9) path(cpl, bcpl)
   Exit: (8) path(algol60, bcpl)
   Exit: (7) path(fortran, bcpl)
X = fortran ;
   Redo: (9) path(cpl, bcpl)
...
   Fail: (8) path(cplusplus, bcpl)
   Redo: (8) link(_G2093, _G2262)
   Exit: (8) link(simula67, smalltalk80)
   Call: (8) path(smalltalk80, bcpl)
   Call: (9) link(smalltalk80, bcpl)
   Fail: (9) link(smalltalk80, bcpl)
   Redo: (8) path(smalltalk80, bcpl)
   Call: (9) link(smalltalk80, _G2262)
   Fail: (9) link(smalltalk80, _G2262)
   Fail: (8) path(smalltalk80, bcpl)
   Fail: (7) path(_G2093, bcpl)
false.
于 2013-03-13T13:15:52.943 回答