TL;DR:这个问题是关于评估候选故障片的一个特定方面。
以下代码ancestor_of/2
表示 的传递闭包child_of/2
:
祖先_of(X,Y):- child_of(Y, X)。 祖先_of(X,Z):- child_of(Z, Y), 祖先_of(X,Y)。
如果我们定义child_of/2
并包含几个循环......
child_of(xx, xy)。 child_of(xy, xx)。 child_of(x, x)。
...ancestor_of(X, Y)
不会普遍终止:
?-祖先_of(X,Y),假的。 **循环**
使用 SWI-Prolog,我们可以限制在执行查询中投入的工作量:
?-时间( call_with_inference_limit ((ancestor_of(_,_),false), 10000 , R))。 % 10,008 次推理,0.002 秒内 0.002 CPU(100% CPU,4579243 唇) R = inference_limit_exceeded ; % 5 次推断,0.000 秒内 0.000 CPU(85% CPU,235172 唇) 错误的。
好吧,但 它可能会更好!
- 首先,我们或许能够明确地证明目标循环。
- 其次,我们也许可以用更少的努力做到这一点。
让我们添加一个额外的参数来ancestor_of/2
传输调用堆栈信息!
祖先_of_open(X,Y,打开):- G = 祖先_of(X,Y), (成员(G,公开) -> 抛出(循环(G,打开)) ; 祖先_of_aux(X,Y,[G|打开]) )。 祖先_of_aux(X,Y,_Open):- child_of(Y, X)。 祖先_of_aux(X,Z,打开):- child_of(Z, Y), 祖先_of_open(X,Y,打开)。
示例查询:
?-时间(ancestor_of_open(X,Y,[]))。 % 4 推论,0.000 CPU 在 0.000 秒内(92% CPU,219696 唇) X = xy, Y = xx; % 1 推理,0.000 CPU 在 0.000 秒内(79% CPU,61839 唇) X = xx, Y = xy ; % 1 推理,0.000 CPU 在 0.000 秒内(79% CPU,61084 唇) X = Y, Y = x; % 8 次推理,0.000 CPU 在 0.000 秒内(87% CPU,317473 唇) X = Y, Y = xx; % 11 次推断,0.000 秒内 0.000 CPU(90% CPU,262530 唇) 错误:未处理的异常:循环(ancestor_of(_G282,xx),[ancestor_of(_G282,xy),ancestor_of(_G282,xx)])
是这个吗?!那太容易了。这是否涵盖一般情况?
我觉得我错过了一些重要的东西,但我不能完全指出它。请帮忙!