2

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)])

这个吗?!那容易了。这是否涵盖一般情况?

我觉得我错过了一些重要的东西,但我不能完全指出它。请帮忙!

4

0 回答 0