Reputation: 147
Here is my problem.
My facts and rules:
fact1(green, red, blue).
fact1(purple, white, gray).
fact2(green, orange).
fact2(purple, cyan).
fact3(green, pink).
fact3(purple, black).
foo(A,B,C,D,E) :-
fact1(A,B,C),
fact2(A,D),
fact3(A,E),
write(A),
write(B).
Now if I ask SWI-Prolog foo(A,B,C,D,E).
the output is
?- foo(A,B,C,D,E).
greenred
A = green, B = red, C = blue, D = orange, E = pink ;
purplewhite
A = purple, B = white, C = gray, D = cyan, E = black.
My goal is that the user only sees the lines
greenred
purplewhite
In order to achieve this I tried changing the definition of foo
like so:
foo() :-
fact1(A,B,C),
fact2(A,D),
fact3(A,E),
write(A),
write(B).
But the output of this predicate is only:
?- foo().
greenred
true.
and not what I would expect:
?- foo().
greenred
purplewhite
true.
Any help is very welcome.
Upvotes: 1
Views: 887
Reputation: 24976
Adding fail/0 at the end tuns this into a failure driven loop so that once an answer is given, the predicate fails and tries the other choice points.
foo :-
fact1(A,B,_),
fact2(A,_),
fact3(A,_),
write(A),
write(B),
nl,
fail.
Example run.
?- foo.
greenred
purplewhite
false.
To get Prolog to return true, (In the the background an evil voice says, "We have ways of making you give us the truth"), it needs to succeed after failing so Prolog looks for another clause named foo
. By adding just foo.
as a second clause Prolog can now find this clause and execute it. Since it does nothing, it succeeds and returns true.
foo.
Example run
?- foo.
greenred
purplewhite
true.
Complete source code
foo :-
fact1(A,B,_),
fact2(A,_),
fact3(A,_),
write(A),
write(B),
nl,
fail.
foo.
Upvotes: 1