prolog - Prolog中的感叹号

标签 prolog

鉴于以下事实和谓词:

sound(time1).
sound(time2).
sun(time3).
relax(X):-sound(X),!,sun(X).
relax(_):-sun(_).

执行 relax(S). 时我希望得到 S=time1由于 ! ,这就是说(如果我错了,请纠正我),如果满足'X',则停止回溯。

这是跟踪:
3 ?- trace.
true.

[trace] 3 ?- relax(S).
   Call: (6) relax(_G1831) ? creep
   Call: (7) sound(_G1831) ? creep
   Exit: (7) sound(time1) ? creep
   Call: (7) sun(time1) ? creep
   Fail: (7) sun(time1) ? creep
   Fail: (6) relax(_G1831) ? creep
false.

那么为什么 Prolog 还要检查 sun(time1) ,即使它在满足 sound(X) 后遇到感叹号(因为 sound(time1) 是事实)。

最佳答案

为了更清楚地说明这一点,如果有人仍然对感叹号运算符的工作方式感到困惑(就像我所做的那样),这里有一个例子:

sound(time3).
sound(time1).
sun(time1).
relax(X):-sound(X),!,sun(X).

对于这个特定的例子,如果你向 Prolog 询问 ?-relax(S).这导致 .我们可以这样描述 Prolog 的工作方式:
  • Prolog 搜索询问的谓词 (relax(SOMEVARIABLE unifiable
    在我们的示例中使用 S))。
  • Prolog 找到谓词relax(X)。变量
    X 和 S 现在已绑定(bind)。
  • Prolog 开始评估子句:
  • 声音(X)
  • Prolog 搜索文件中的事实
    满足声音(X)。
  • 它发现事实声音(时间3)。 并将其与我们的变量 X=S=time3 统一起来。
  • !
  • Prolog 继续到下一个子句,即 operator !所以他不会回溯到这个运营商的背后。
  • 太阳(X)
  • Prolog 在文件中搜索满足 sun(X) 的事实。 X 已经绑定(bind),所以它搜索 太阳(time3) 这不
    存在。
  • 结论
  • 在这一点上,如果没有!运算符 Prolog 将返回(回溯)到 sound(X),并将变量 X=S 重新分配为 X=S=time1。最终会导致 真实 因为事实 sun(time1) 存在。
  • Prolog 返回 false,因为他无法匹配任何规则的relax(S)。

  • 反对,就像我在 4. 中所说的那样没有!运算符,结果为 成功 .
    sound(time3).
    sound(time1).
    sun(time1).
    relax(X):-sound(X),sun(X).
    

    如果我在某些时候错了,请随时纠正我。

    关于prolog - Prolog中的感叹号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15065663/

    相关文章:

    prolog - 最少移动次数

    prolog - 为什么这个序言程序会导致无限递归?

    prolog - @< 序言中的符号

    list - Prolog - 递归调用

    prolog - Prolog 99瓶啤酒

    prolog - 可逆树长关系

    input - Prolog-文件意外结束

    prolog - 根据索引交换两个项目

    recursion - 递归地将每隔一个元素移动到列表的末尾

    prolog - SICStus Prolog 中的验证属性