简体   繁体   中英

Use of redundant goals in queries

(Upon the suggestion of @repeat ) Consider a query of a pure program 1 ?- G_0. What use if any would the query ?- G_0, G_0. have?

Footnotes
1 No tabling (to be safe), constraints are OK.
Previous post on the subject.

The query ?- G_0, G_0. helps to identify redundant answers of ?- G_0.

To do so it suffices to compare the number of answers of ?- G_0. with the number of answers of ?- G_0, G_0. . No need to store those answers (which is a frequent source of errors anyway). Just two integers suffice! If they are equal, then there is no redundancy. But if ?- G_0, G_0. has more answers, then there is some redundancy. Here is an example:

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

... and now let's fix this:

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

No need to manually inspect the constraints involved.

This can be further extended when we are explicitly searching for redundant answers only using call_nth/2 .

?- G_0, call_nth(G_0, 2).

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

I see no usefulness of the second goal, especially when tail recursion optimization ( last call optimization ) is ON .

I could realize an GC issue (stack/heap overflow) when the query is resources-greedy and above options are OFF (eg when debugging).

I think the second call is redundant (for pure program) and should be eliminated by the compiler.

Logicians and mathematicians have for long found a first order formulation for checking whether a relation has a unique result. This is used to define when a relation is a function. Its a very easy formulation. A relation R(x,y) has a unique y or no y for some x :

∀y1∀y2(R(x, y1) & R(x, y2) => y1 = y2)

See also here where the uniqueness quantifer ∃! is split into existence and uniqueness clauses. How can we turn the above into a Horn clause goal? We can take its negation, and we will get this formula:

∃y1∃y2(R(x, y1) & R(x, y2) & y1 ≠ y2)

The above is a Horn clause goal when we drop the existential quantifiers ∃y1 and ∃y2 , and a Prolog will deliver us answer substitutions for y1 and y2 . So its not really the pattern G_0, G_0 , but G_0, G_0' with some extra . We can apply it to @false example:

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

And by the help of clause/3 we get:

?- clause(p(X), _, Y1), clause(p(X), _, Y2), Y1 \== Y2.
X = f(b, a),
Y1 = <clause>(0x600000254280),
Y2 = <clause>(0x6000007d2840) ;
X = f(b, a),
Y1 = <clause>(0x6000007d2840),
Y2 = <clause>(0x600000254280) ;
false.

So the term f(b,a) is head instance of two clauses, and thats the only such term.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM