在查询中使用冗余目标


12

(根据@repeat建议)考虑一个程序的查询1 ?- G_0.该查询?- G_0, G_0.有什么用?

脚注
1禁止制表(为了安全起见),约束条件还可以。关于该主题的
上一篇文章


平方结果数?
Willem Van Onsem

1
我认为目标的连续运行不会保留任何状态信息。换句话说,不允许更改问题,例如,是否?- G_0(State), G_0(State).也没有状态从第一个目标的结果传递到第二个目标?
Guy Coder

1
G_0可能是任何(纯粹的)目标,例如G_0 = append(Xs,Ys,Zs)
错误

1
@GuyCoder:必填项。(G_0;G_0可能会测试副作用或性能/缓存/标签问题)

1
顺便说一句,而不是G_0(State),G_0(State)一个宁可写call(G_1,State), call(G_1,State)
错误

Answers:


3

该查询?- 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).

1

考虑对纯程序1?-G_0的查询。查询有什么用?-G_0,G_0。有?

我看不到第二个目标的用处,尤其是当尾递归优化最后一次调用优化)为ON时

当查询为资源贪婪且上述选项为OFF(例如,调试时)时,我可能会意识到GC问题(堆栈/堆溢出)。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.