问了一个关于here何时在Prolog中使用新变量确切调用Redo或何时尝试使用新变量的here问题之后,我想我已经弄清楚了。但是,在下面的代码中,我认为应该调用一个附加的Redo,但事实并非如此。

我的知识库如下:

location(desk,office).
location(apple,kitchen).
location(flashlight,desk).
location('washing machine',cellar).
location(nani,'washing machine').
location(broccoli,kitchen).
location(crackers,kitchen).
location(computer,office).

edible(apple).
edible(crackers).

我的查询是
?-location(X,kitchen),edible(X).

具有以下跟踪:
   Call: (9) location(_5612, kitchen) ? creep
   Exit: (9) location(apple, kitchen) ? creep
   Call: (9) edible(apple) ? creep
   Exit: (9) edible(apple) ? creep
X = apple ;
   Redo: (9) location(_5612, kitchen) ? creep       <====
   Exit: (9) location(broccoli, kitchen) ? creep
   Call: (9) edible(broccoli) ? creep
   Fail: (9) edible(broccoli) ? creep
   Redo: (9) location(_5612, kitchen) ? creep
   Exit: (9) location(crackers, kitchen) ? creep
   Call: (9) edible(crackers) ? creep
   Exit: (9) edible(crackers) ? creep
X = crackers.

为什么在第一个解决方案之后沿着Redo行没有附加的Redo: (9) edible(apple)(然后失败,然后继续下一个Redo),因为在代码中还有一个带有functor edible的事实,这意味着存在一个创造的选择点?我发现了相同查询prolog - Prolog中的选择点和重做-LMLPHP的带注释的痕迹。我会从中发布一个简短的代码段,因为它还有我觉得在这里缺少的其他Redo:

ojit_a

在这种情况下,有人可以向我指出正确的方向吗?

谢谢。

最佳答案

您可以在此通过Byrd的盒模型可视化重做
建模谓词调用P具有4个端口:

            +-------+
--- call -->|       |--- exit -->
            |   P   |
<-- fail ---|       |<-- redo ---
            +-------+

通常,当每个导出都没有切路时,将进行重做。而对于每个
调用会在以后的某个时间最终失败,除了SWI-Prolog(也许还有其他一些Prolog系统?)之外:

当P确定性地成功通过时,
  • 重做将被抑制
    当P确定性地成功通过
  • 时,抑制
  • 失败

    确定性成功通常是最后一个子句的结果
    在索引花束中,并且出现在非调试顶层
    分号提示被禁止。另请参阅此处:

    Making "deterministic success" of Prolog goals explicit

    在Jekejeke Prolog中,尚未实现这种“优化”
    用于调试器。它也具有确定性的成功,但是当
    调试器打开,这就是为什么有两个不同的跟踪的原因:

    SWI-Prolog跟踪:
    Welcome to SWI-Prolog (threaded, 64 bits, version 7.5.8)
    SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
    
    ?- location(X,kitchen),edible(X).
       Call: (9) location(_3980, kitchen) ? creep
       Exit: (9) location(apple, kitchen) ? creep
       Call: (9) edible(apple) ? creep
       Exit: (9) edible(apple) ? creep
    X = apple
       Redo: (9) location(_3980, kitchen) ? creep
       Exit: (9) location(broccoli, kitchen) ? creep
       Call: (9) edible(broccoli) ? creep
       Fail: (9) edible(broccoli) ? creep
       Redo: (9) location(_3980, kitchen) ? creep
       Exit: (9) location(crackers, kitchen) ? creep
       Call: (9) edible(crackers) ? creep
       Exit: (9) edible(crackers) ? creep
    X = crackers.
    

    Jekejeke Prolog跟踪:
    Jekejeke Prolog 2, Development Environment 1.2.2
    (c) 1985-2017, XLOG Technologies GmbH, Switzerland
    
    ?- location(X,kitchen),edible(X).
        0 Call location(X, kitchen) ?
        0 Exit location(apple, kitchen) ?
        0 Call edible(apple) ?
        0 Exit edible(apple) ?
    X = apple ;
        0 Redo edible(apple) ?
        0 Fail edible(apple) ?
        0 Redo location(apple, kitchen) ?
        0 Exit location(broccoli, kitchen) ?
        0 Call edible(broccoli) ?
        0 Fail edible(broccoli) ?
        0 Redo location(broccoli, kitchen) ?
        0 Exit location(crackers, kitchen) ?
        0 Call edible(crackers) ?
        0 Exit edible(crackers) ?
    X = crackers ;
        0 Redo edible(crackers) ?
        0 Fail edible(crackers) ?
        0 Redo location(crackers, kitchen) ?
        0 Fail location(X, kitchen) ?
    No
    

    关于prolog - Prolog中的选择点和重做,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45425538/

  • 10-16 14:20