【问题标题】:Prolog cut and fail not working as expectedProlog 剪切和失败未按预期工作
【发布时间】:2021-06-21 16:58:20
【问题描述】:

我正在学习 prolog,并且遇到了“cut and fail”组合,据我了解,它们可以用作保护子句。我已经尝试过使用它,但它没有按预期工作。

old(person1).
old(person2).
skilled(person1).
skilled(person2).
skilled(person3).
skilled(person4).
possible_employee(X):-
    old(X),!,fail.
possible_employee(X):-
    skilled(X).

在上面的示例中,它应该“过滤掉”old 人,但它会过滤掉所有人并在查询 possible_employee 时返回 false。是我的代码有缺陷还是我对概念的理解有缺陷?

【问题讨论】:

  • 你想完成什么?如果你能展示你期望得到的东西,它会更容易帮助你。
  • @NicholasCarey 我期待“possible_employee(X)”将 X 与所有不老且有技能的人(X=person3;X=person4)统一起来,但我得到了一个简单的“假”

标签: prolog swi-prolog


【解决方案1】:

(old(X) ; skilled(X)), possible_employee(X) 会做你想做的事。

member(X, [person1, person2, person3, person4]), possible_employee(X) 会做你想做的事。

您的谓词过滤 解决方案。由于切割,它不能以生成方式使用。只要满足old(X),谓词possible_employee/1就会按照规定不可撤销地失败。所以它必须提供更多的可能性,从一些外部来源。它本身就是在那个时候完成的。

您的谓词(重新)实现的是“not”、\+

在 Prolog 中,not 不是 "not"。它必须被理解为“不能证明 ...”。

在这个阅读下,possible_employee(X)的意思是,“不能证明old(X),可以证明skilled(X)”。但是old(X) 与新鲜的X 可以总是 被证明,用那个知识库。

如果切换子句顺序,它会完全改变谓词的含义。谓词的(几个)子句在隐含的析取中,“或”:

possible_employee(X):-
    skilled(X).
possible_employee(X):-
    old(X),!,fail.

的意思是,“可以证明skilled(X)”,没有别的意思(你明白为什么吗?)。那么,在

old(person1).
old(person2).
skilled(person1).
skilled(person2).
skilled(person3).
skilled(person4).
possible_employee(X):-
    skilled(X).
possible_employee(X):-
    old(X),!,fail.

呼叫possible_employee(X) 应该成功四次,对于所有四个人。确实如此,尽管他们两个也是old/1

所以你看,cut 的存在改变了一切。它使谓词的含义完全依赖于操作语义。

在逻辑上,A ; BB ; A 相同。但在操作上并非如此。

切入,忘记逻辑,开始思考Prolog解释的操作细节。

【讨论】:

    【解决方案2】:

    Prolog 中的概念执行模型是一个搜索树。 Prolog 的推理引擎对树进行深度优先、从左到右的搜索,寻找与谓词中的所有约束匹配的解决方案(叶节点)。

    切割 (!) 消除了选择点——例如,它修剪了搜索树。

    所以你的 possible_employee/1 谓词

    possible_employee(X) :- old(X), !, fail.
    possible_employee(X) :- skilled(X).
    

    一旦满足old(X),就会完全失败。这就是!, fail 的意思。不会尝试old(X) 的替代解决方案;也不会尝试谓词的第二项。

    Prolog 是一种描述性 语言:用您在评论中所做的相同描述您的解决方案:

    我期待“possible_employee(X)”将 X 与所有不老且有技能的人统一起来 (X=person3;X=person4)。

    这将我们引向这个简单的解决方案,这几乎就是您的问题陈述:

    possible_employee(X) :- % a possible employee is one who
      skilled(X) ,          % - is skilled, and
      \+ old(X)  .          % - is not old
    

    \+/1 既是一元前缀运算符,又是表示“不可证明”的谓词。

    https://www.swi-prolog.org/pldoc/doc_for?object=(%5C%2B)/1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-05
      • 1970-01-01
      相关资源
      最近更新 更多