【问题标题】:What are the uses of the fail predicate in Prolog?Prolog中失败谓词的用途是什么?
【发布时间】:2010-06-08 22:35:43
【问题描述】:

我想不出我需要它的情况。

【问题讨论】:

    标签: prolog prolog-dif


    【解决方案1】:

    优雅的系统提供false/0 作为命令式fail/0 的声明同义词。一个有用的示例是当您手动想要强制回溯以产生副作用时,例如:

    ?- between(1,3,N), format("line ~w\n", [N]), false.
    line 1
    line 2
    line 3
    

    除了false/0,您还可以使用任何失败的目标,例如短一点:

    ?- between(1,3,N), format("line ~w\n", [N]), 0=1.
    line 1
    line 2
    line 3
    

    因此,false/0 不是绝对需要的,但非常好。

    编辑:我有时会看到初学者想要声明例如“我的关系不适用于空列表”,然后添加:

    my_relation([]) :- false.

    到他们的代码。这不是必要的,并且不是使用false/0 的一个很好的例子,除了在以编程方式生成的故障切片中。相反,专注于陈述持有关于你们关系的事情。在这种情况下,只需省略整个子句,只为不为空的列表定义关系,即至少有一个元素:

    my_relation([L|Ls]) :- etc.

    或者,如果您还描述了列表之外的其他术语,请使用如下约束:

    my_relation(T) :- dif(T, []), etc.

    仅给定这两个子句中的一个(甚至两个),查询?- my_relation([]). 将自动失败。没有必要为此目的引入一个永远不会成功的附加条款。

    【讨论】:

    • s/优雅/优雅和符合/
    【解决方案2】:

    显式失败。 fail 通常与 cut: ... !, fail. 结合使用以强制失败。

    对于所有构造。 显式使用fail/false 来枚举通过回溯是一个非常容易出错的活动。考虑一个案例:

    ... ( generator(X), action(X), fail ; true ), ...
    

    因此,这个想法是为所有X“做”动作。但是,如果action(X) 失败会发生什么?这个结构只是继续下一个候选人——就好像什么都没发生一样。通过这种方式,某些错误可能会在很长一段时间内未被检测到。

    对于这种情况,最好使用失败的\+ ( generator(X), \+ action(X) ),如果action(X) 对某些X 失败。一些系统将其作为内置的forall/2 提供。就个人而言,我更喜欢在这种情况下使用\+,因为\+ 更清楚地表明该构造不会留下绑定。

    Failure-slice. 出于诊断目的,将false 有意添加到您的程序中通常很有用。详情请见

    【讨论】:

      【解决方案3】:

      一个案例(取自Constraint Logic Programming using Eclipse)是not/1的实现:

      :- op(900, fy, not).
      not Q :- Q, !, fail.
      not _ .
      

      如果 Q 成功,cut (!) 会导致第二个 not 子句被丢弃,而 fail 确保否定结果。如果 Q 失败,则第二个 not 子句首先触发。

      【讨论】:

        【解决方案4】:

        fail 的另一个用途是在使用带有副作用的谓词时强制回溯:

        writeall(X) :- member(A,X), write(A), fail.
        writeall(_).
        

        不过,有些人可能并不认为这种特别好的编程风格。 :)

        【讨论】:

        • 糟糕,看起来 mat 打败了我。
        【解决方案5】:

        fail/0 是一个特殊的符号,当prolog遇到它作为目标时会立即失败。

        fail 通常与 CUT(!) 结合使用以强制失败。

        like(me,X) :- chess(X),!,fail.
        like(me,X) :- games(X).
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多