[comp.lang.prolog] Finding all solutions in Prolog

F0O@psuvm.psu.edu (08/04/90)

     I have a fairly simple question, but yet have never ran across any
book that explains it.

     If you have a simple PDC prolog program like:

          predicates
               person(symbol)

          clauses
               person(jack).
               person(jill).
               person(mary).

 and from the goal prompt type: person(X), you will get all 3 persons.
But if you have an internal goal like:
         person(X), write(X),nl.

prolog will only find the first person.  You would have to use the fail
predicate to force Prolog to find all solutions.

     Why does Prolog only find the first solution on internal goals?  I'd
think finding all solutions to a query would be more common than only
finding one.
     I can see that only finding one solution and then using the fail
predicate gives you control over the search, however you could also use
the cut if you wanted to limit the search.

     Am I missing something fundamental here?

                                                    [Tim]

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (08/06/90)

In article <90216.112514F0O@psuvm.psu.edu>, F0O@psuvm.psu.edu writes:
>      If you have a simple PDC prolog program like:
>           predicates
>                person(symbol)
> 
>           clauses
>                person(jack).
>                person(jill).
>                person(mary).
> and from the goal prompt type: person(X), you will get all 3 persons.

That is a rather nasty peculiarity of PDC Prolog.  Most sensible Prologs
give you one answer at a time, and you have to type something to get the
next answer.  That is, after all, the thing which distinguishes Prolog
from a relational query language:  the language really does find ONE
solution at a time.

> But if you have an internal goal like:
>          person(X), write(X),nl.
> 
> Prolog will only find the first person.

Not quite.  Prolog will find the first solution, and report it, leaving
a suspension ready to look for the next solution.  When that suspension
is activated (by being "failed into") it will look for another solution.
(Actually, another proof.)  Let's face it, a Prolog variable can only be
bound to ONE value, so Prolog _can_ only report one solution at a time.

>      Why does Prolog only find the first solution on internal goals?

Because that's how Prolog works.  You could have a query language
(such as Aditi or NAIL!) which uses Prolog-like syntax but which notionally
finds all solutions, no reason why not.  But it wouldn't be Prolog.  The
point of Prolog is to provide a fast cheap programming language which works
pretty much like Lisp or Pascal, and to do that it works by finding one
proof at a time, using backtracking to go on to the next one.

>      I can see that only finding one solution and then using the fail
> predicate gives you control over the search, however you could also use
> the cut if you wanted to limit the search.

But you can only use the cut to control the search BECAUSE Prolog finds
one solution at a time; the cut has the effect of preventing other solutions
being looked for.  How could you stop other branches of the tree being
explored if they had already been explored?

>      Am I missing something fundamental here?

You have been confused by a poorly chosen interface in PDC ``Prolog''.
(It is not uncommon for a top level query to have _millions_ of answers;
it really is _not_ helpful to display them all.)

-- 
Distinguishing between a work written in Hebrew and one written in Aramaic
when we have only a Latin version made from a Greek translation is not easy.
(D.J.Harrington, discussing pseudo-Philo)