Hamza
Hamza

Reputation: 167

Prolog goal with multiple results

spec(comp1, pc, 32).                                      /* Fact  1 */
spec(comp2, mac, 128).                                    /* Fact  2 */
spec(comp3, pc, 64).                                      /* Fact  3 */
runs(pc, movie_edit, 96).                                 /* Fact  4 */
runs(pc, vb, 16).                                         /* Fact  5 */
runs(pc, cpp, 28).                                        /* Fact  6 */
runs(mac, vb, 24).                                        /* Fact  7 */
runs(mac, prolog, 128).                                   /* Fact  8 */
access(judy, comp1).                                      /* Fact  9 */
access(peter, comp3).                                     /* Fact 10 */
access(david, comp1).                                     /* Fact 11 */
access(david, comp2).                                     /* Fact 12 */
can_use(P, SW) :- access(P, Comp), can_run(Comp, SW).     /* Rule  1 */

can_run(Comp, SW) :- spec(Comp, CompType, MemAvail),
                   runs(CompType, SW, MemNeeded),
                   MemAvail >= MemNeeded.               /* Rule   2 */

?- can_use(judy, vb).
?- can_use(david, prolog).

The first goal returns: true, false. Whereas the second one returns only true.
My question is why in the first goal we have that extra information.
I'm using SWI-Prolog 7.6.4 version

Upvotes: 1

Views: 510

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476719

The reason this happens is because in the former case, there is still "opportunity" for backtracking whereas in the latter, there is no such opportunity.

If we call the goal with the trace, we see:

[trace]  ?- can_use(judy, vb).
   Call: (8) can_use(judy, vb) ? creep
   Call: (9) access(judy, _2968) ? creep
   Exit: (9) access(judy, comp1) ? creep
   Call: (9) can_run(comp1, vb) ? creep
   Call: (10) spec(comp1, _2968, _2970) ? creep
   Exit: (10) spec(comp1, pc, 32) ? creep
   Call: (10) runs(pc, vb, _2970) ? creep
   Exit: (10) runs(pc, vb, 16) ? creep
   Call: (10) 32>=16 ? creep
   Exit: (10) 32>=16 ? creep
   Exit: (9) can_run(comp1, vb) ? creep
   Exit: (8) can_use(judy, vb) ? creep
true ;
   Redo: (10) runs(pc, vb, _2970) ? 

We here thus make a call to runs/3 with runs(pc, vb, MemNeeded) and Prolog finds a first answer with 16. But it sets a backtracking point to look for other runs/3 facts with runs(pc, vb, MemNeeded). Imagine that there is another fact later in the source code, for example runs(pc, vb, 14) at the end, then this can produce another answer.

If we however call the second goal, we see:

[trace]  ?- can_use(david, prolog).
   Call: (8) can_use(david, prolog) ? creep
   Call: (9) access(david, _3726) ? creep
   Exit: (9) access(david, comp1) ? creep
   Call: (9) can_run(comp1, prolog) ? creep
   Call: (10) spec(comp1, _3726, _3728) ? creep
   Exit: (10) spec(comp1, pc, 32) ? creep
   Call: (10) runs(pc, prolog, _3728) ? creep
   Fail: (10) runs(pc, prolog, _3728) ? creep
   Fail: (9) can_run(comp1, prolog) ? creep
   Redo: (9) access(david, _3726) ? creep
   Exit: (9) access(david, comp2) ? creep
   Call: (9) can_run(comp2, prolog) ? creep
   Call: (10) spec(comp2, _3726, _3728) ? creep
   Exit: (10) spec(comp2, mac, 128) ? creep
   Call: (10) runs(mac, prolog, _3728) ? creep
   Exit: (10) runs(mac, prolog, 128) ? creep
   Call: (10) 128>=128 ? creep
   Exit: (10) 128>=128 ? creep
   Exit: (9) can_run(comp2, prolog) ? creep
   Exit: (8) can_use(david, prolog) ? creep
true.

Here we call runs(mac, prolog, MemNeeded)., and this is the last fact of runs/3, hence there is no other possibility to satisfy runs/3 otherwise: since Prolog runs top to bottom, if we have satisfied the last fact/clause, we know that there is no other option.

Since all other calls also take the last predicate as well, or with a different constant as first parameter (SWI-Prolog looks at the first argument when it compiles the source code as an optimization), there are no other backtracking points, and thus there is no way to Redo a certain call.

Upvotes: 1

Related Questions