在查询中使用冗余目标
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).
(基于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).