在查询中使用冗余目标

Use of redundant goals in queries

(基于suggestion of @repeat)考虑一个程序的查询1 ?- G_0.如果查询 ?- G_0, G_0. 有什么吗?

脚注
1 没有表格(安全起见),约束是可以的。
Previous post 关于这个问题。

Consider a query of a pure program1 ?- G_0. What use if any would the query ?- G_0, G_0. have?

我看不出第二个目标有什么用处,尤其是当尾递归优化最后调用优化)是时ON.

当查询是资源贪婪的并且上面的选项是 OFF(例如调试时)时,我可以意识到一个 GC 问题(stack/heap 溢出)。

我认为第二次调用是多余的(对于纯程序),应该由编译器消除。

查询 ?- G_0, G_0. 有助于识别 ?- G_0.

的冗余答案

为此,只需将 ?- G_0. 的答案数与 ?- G_0, G_0. 的答案数进行比较即可。无需存储这些答案(无论如何这是一个常见的错误来源)。两个整数就够了!如果它们相等,则没有冗余。但是如果 ?- G_0, G_0. 有更多的答案,那么就会有一些冗余。这是一个例子:

p(f(_,a)).
p(f(b,_)).

?- p(X).
   X = f(_A, a)
;  X = f(b, _A).  % two answers

?- p(X), p(X).
   X = f(_A, a) 
;  X = f(b, a)
;  X = f(b, a)
;  X = f(b, _A).   % four answers
                   % thus p(X) contains redundancies

...现在让我们解决这个问题:

p(f(B,a)) :-
   dif(B, b).
p(f(b,_)).

?- p(X).
   X = f(_A, a), dif(_A, b)
;  X = f(b, _A).

?- p(X), p(X).
   X = f(_A, a), dif(_A, b), dif(_A, b).
;  X = f(b, _A).    % again two answers, thus no redundancy

无需手动检查涉及的约束。

当我们仅使用 call_nth/2.

明确搜索冗余答案时,这可以进一步扩展
?- G_0, call_nth(G_0, 2).