mat*_*mat 20

优雅的系统false/0作为命令的声明性同义词fail/0.有用的示例是当您手动想要强制回溯副作用时,例如:

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

false/0您也可以使用任何失败的目标,例如更短的目标,而不是:

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

因此,false/0不是严格需要,但非常好.

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

my_relation([]) :- false.

他们的代码.除了例如以编程方式生成的故障切片之外,这不是必需的,并且不是使用的良好示例false/0.相反,集中精力,指出事情保持你的关系.在这种情况下,只需省略整个子句,并仅为非空列表定义关系,即至少有一个元素:

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

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

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

只给出这两个子句中的任何一个(或者两个),查询?- my_relation([]).将自动失败.没有必要引入一个从未为此目的而成功的附加条款.


fal*_*lse 8

明确的失败. fail通常与cut结合使用:... !, fail.强制执行失败.

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

... ( generator(X), action(X), fail ; true ), ...
Run Code Online (Sandbox Code Playgroud)

因此,这个想法是为所有人"做"行动X.但是如果action(X)失败会发生什么?这个结构只是继续下一个候选人 - 好像什么也没发生.以这种方式,某些错误可能长时间未被发现.

对于这种情况,最好使用\+ ( generator(X), \+ action(X) )哪个失败,action(X)对某些人来说应该失败X.有些系统将其作为内置功能提供forall/2.就个人而言,我更喜欢\+在这种情况下使用,因为\+结构不会留下绑定更清楚一点.

故障片.出于诊断目的,将有意添加false到程序中通常很有用.有关详细信息,请参阅.