迫切;
需要下一个解决方案。如您所知,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.