1
votes

I'm using SWI for Windows and I'm trying out an exercise in Learn Prolog Now!

travel(Start,Dest,X) :-
    (byCar(Start,Dest); byTrain(Start,Dest); byPlane(Start,Dest)),
    X = go(Start,Dest).

In this code if the you can reach Dest from Start, Prolog says:

true.

X = go(Start,Dest).

and just says false otherwise.

However in this code when I removed the parenthesis it only says true if valid and false if invalid. The answer is correct but why doesn't it output X?

travel(Start,Dest,X) :-
    byCar(Start,Dest); byTrain(Start,Dest); byPlane(Start,Dest),
    X = go(Start,Dest).

Is it because of operator precedence in which AND gets evaluated first? Even if thats the case shouldn't X still be equal to go(Start,Dest)?

The way Prolog assigns values to variables confuses me.

2

2 Answers

3
votes

you're right, precedence of and is lower that or. When unsure, you can use write_canonical

4 ?- write_canonical((travel(Start,Dest,X) :-
    byCar(Start,Dest); byTrain(Start,Dest); byPlane(Start,Dest),
    X = go(Start,Dest))).
:-(travel(A,B,C),;(byCar(A,B),;(byTrain(A,B),','(byPlane(A,B),=(C,go(A,B))))))
true.

5 ?- write_canonical((travel(Start,Dest,X) :-
    (byCar(Start,Dest); byTrain(Start,Dest); byPlane(Start,Dest)),
    X = go(Start,Dest))).
:-(travel(A,B,C),','(;(byCar(A,B),;(byTrain(A,B),byPlane(A,B))),=(C,go(A,B))))
true.

and current_op to check beforehand

6 ?- current_op(P,A,(,)).
P = 1000,
A = xfy.

7 ?- current_op(P,A,(;)).
P = 1100,
A = xfy.
1
votes

you first code is equivalent to

travel(Start,Dest,X) :- byCar(Start,Dest), X = go(Start,Dest).
travel(Start,Dest,X) :- byTrain(Start,Dest), X = go(Start,Dest).
travel(Start,Dest,X) :- byPlane(Start,Dest), X = go(Start,Dest).

if any of the byNNN predicate succeed, whatever bindings they produced for their arguments will be reflected by X's binding. If you see X = go(Start,Dest) as the output, it means that byNNN succeeded without instantiating its arguments.

the second is equivalent to

travel(Start,Dest,X) :- byCar(Start,Dest).
travel(Start,Dest,X) :- byTrain(Start,Dest).
travel(Start,Dest,X) :- byPlane(Start,Dest), X = go(Start,Dest).

so when it succeeds by way of its first or second clause, it doesn't involve X at all.