A clause will contain a head and possibly a body. A head without a body is a fact.
In the clause
travel_01_helper(X,Y,Path0,[(Mode,Y)|Path0]) :-
(
(byCar(X,Y),Mode = car)
;
(byTrain(X,Y),Mode = train)
;
(byPlane(X,Y),Mode = plane)
),
\+ member((_,Y),Path0).
The head is
travel_01_helper(X,Y,Path0,[(Mode,Y)|Path0])
and the body is
(
(byCar(X,Y),Mode = car)
;
(byTrain(X,Y),Mode = train)
;
(byPlane(X,Y),Mode = plane)
),
\+ member((_,Y),Path0).
Now to help in understanding how a body of a clause works, here are examples that are very simple and get more complex.
Remember that with logic,
if any part of and
expression is false, the entire expression is false
if any part of or
expression is true, the entire expression is true
Remember that in Prolog
,
means logical and
;
means logical or
\+
means logical not
()
group logical expressions.
When SWI-Prolog returns a result that ends with .
there are no more possible answers. When SWI-Prolog returns a result that ends with ;
there are more possible answers, so press the space bar to continue seeing them.
Prolog will keep seeking more answers as long as there is a possible way for the clause (logic) to be true.
Example clauses. Results of running follow.
% true
clause_1 :-
true.
% false
clause_2 :-
false.
% true and true
clause_3 :-
true,
true.
% true and false
clause_4 :-
true,
false.
% false and true
clause_5 :-
false,
true.
% true or true
clause_6 :-
true;
true.
% true or true but done with predicates other than true which output to the screen when executed.
clause_7 :-
format('1',[]);
format('2',[]).
% true or false
clause_8 :-
true;
false.
% false or true
clause_9 :-
false;
true.
% false or false
clause_10 :-
false;
false.
% not true
clause_11 :-
\+ true.
% not false
clause_12 :-
\+ false.
% true or true or false.
clause_13 :-
true ; true ; false.
% true or false or true
clause_14 :-
true ; false ; true.
% false or true or true
clause_15 :-
false ; true ; true.
% (true or false or false) and true
clause_16 :-
(true ; false ; false) , true.
% (true or false or false) and false
clause_17 :-
(true ; false ; false) , false.
% (true or false or false) and not true
clause_18 :-
(true ; false ; false) , \+ true.
Results of running.
% true
?- clause_1.
true.
% false
?- clause_2.
false.
% true and true
?- clause_3.
true.
% true and false
?- clause_4.
false.
% false and true
% Prolog failed on the first part of the and so there was no need to do the second part as the result will always be false.
?- clause_5.
false.
% true or true
% Prolog will try and give you all the true solutions. In this case there are two and they are both true. See next example
?- clause_6.
true ;
true.
% true or true but using format/1.
?- clause_7.
1
true ;
2
true.
% true or false
% Prolog was successful on the first part of the or, so then it did the next part and failed.
% Prolog will keep seeking more answers as long as there is a possible way for the clause (logic) to be true.
?- clause_8.
true ;
false.
% false or true
% Prolog failed on the first part of the or but continued to the next part of the or and succeeded.
% Prolog will keep seeking more answers as long as there is a possible way for the clause (logic) to be true.
?- clause_9.
true.
% false or false
% Prolog failed on the first part of the or but continued to the next part of the or and failed also, so the result is false.
?- clause_10.
false.
% not true
?- clause_11.
false.
% not false
?- clause_12.
true.
% true or true or false.
% Prolog succeeded on the first part of the or, continued to the second part of the or which succeeded, and failed on the third part of the or.
% Prolog will keep seeking more answers as long as there is a possible way for the clause (logic) to be true.
?- clause_13.
true ;
true ;
false.
% true or false or true
% Prolog succeeded on the first part of the or, continued to the second part of the or which failed (which was not reported to the screen), and succeeded on the third part of the or.
% Prolog will keep seeking more answers as long as there is a possible way for the clause (logic) to be true.
?- clause_14.
true ;
true.
% false or true or true
% Prolog failed on the first part of the or (which was not reported to the screen), continued to the second part of the or which succeeded, and succeeded on the third part of the or.
?- clause_15.
true ;
true.
% (true or false or false) and true
% Prolog succeeded on the first part (true or false or false) using the first true, continued to the second part of the and which succeeded.
?- clause_16.
true ;
true.
% (true or false or false) and false
% Prolog succeeded on the first part (true or false or false) using the first true, continued to the second part of the and which failed.
% This is just a more complex version of clause_4.
?- clause_17.
false.
% (true or false or false) and not true
% Prolog succeeded on the first part (true or false or false) using the first true, continued to the second part of the and which succeeded, but then applied not to the second part which was true, which resulted in false which made the entire clause false.
% This is just a more complex version of clause_17.
% This clause is like the one you asked about in the question.
?- clause_18.
false.
Remember that logic expressions are expressions and just like math expressions, there are some substitutions that can be done that will not change the meaning of the code. However in Prolog there are also changes that can dramatically change the meaning of the code.
In other words, the only thing that matters to Prolog when it evaluates the statements in a clause are the statements/predicates are seen as a logic expression and the expression has to evaluate to true. All the rest is side-effects of binding values to variables. So when you ask about the values concerning the location names, those don’t matter if the logic of the clause results in false. Only when the logic of a clause is true will the binding of the variables be returned.
@DaJa
When I wrote the code you are reviewing in detail I wrote it more to show that your O-O
should have been -O
. I knew the code was not the best but did not expect you to examine in such detail.
Here is a much better version that if you plan to study in detail would be better for you.
travel_02(X,Y,Path) :-
travel_02_helper(X,Y,[(start,X)],Path0),
reverse(Path0,Path).
travel_02_mode(X,Y,Mode) :-
(
(byCar(X,Y),Mode = car)
;
(byTrain(X,Y),Mode = train)
;
(byPlane(X,Y),Mode = plane)
).
% base case
travel_02_helper(X,X,Path,Path).
% recursive case
travel_02_helper(X,Z,Path0,Path) :-
travel_02_mode(X,Y,Mode),
\+ member((_,Y),Path0),
travel_02_helper(Y,Z,[(Mode,Y)|Path0],Path).
It returns the same results as the earlier version, but as I noted, logic expressions are like math expressions and certain substitutions are allowed.
?- travel_02(valmont,raglan,Path).
Path = [(start, valmont), (car, saarbruecken), (train, frankfurt), (plane, bangkok), (plane, auckland), (car, hamilton), (car, raglan)] ;
Path = [(start, valmont), (car, saarbruecken), (train, frankfurt), (plane, singapore), (plane, auckland), (car, hamilton), (car, raglan)] ;
Path = [(start, valmont), (car, saarbruecken), (train, paris), (plane, losAngeles), (plane, auckland), (car, hamilton), (car, raglan)] ;
Path = [(start, valmont), (car, metz), (train, frankfurt), (plane, bangkok), (plane, auckland), (car, hamilton), (car, raglan)] ;
Path = [(start, valmont), (car, metz), (train, frankfurt), (plane, singapore), (plane, auckland), (car, hamilton), (car, raglan)] ;
Path = [(start, valmont), (car, metz), (train, paris), (plane, losAngeles), (plane, auckland), (car, hamilton), (car, raglan)] ;
false.