I wrote the following knowledge base in Prolog:
likes(yamini,chocolate).
likes(anuj,apple).
likes(yamini,book).
likes(john,book).
likes(john,france).
Now, when I consult the above file and try the following commands:
| ?- likes(anuj,apple).
(1 ms) yes
| ?- likes(yamini,chocolate).
true ? ;
no
I want to understand when does Prolog replies a 'yes' versus when does it replies 'true'.
That output depends on the toplevel you are using. It seems you are using GProlog. It will output yes when the query succeeds and there are no choice points left (no other possible solutions).
And it will answer true when the query succeeds but there are still other possible solutions to be checked.
This is an artefact of the toplevel (Prolog command line) implementation. Apparently you implementation says true when it could prove a goal and it is unsure whether there may be more solutions. If it is sure that there is only one solution, it says yes.
Here is what SWI-Prolog does:
?- likes(anuj,apple).
true.
Prolog could successfully prove the goal likes(anuj,apple) and it is also sure there are no other ways to prove it otherwise one would see something like this:
?- member(X,[1,2]).
X = 1 ;
X = 2.
where an X that makes the goal true has been found as 1 but there may be other solutions. And indeed there are, namely 2.
Back to our example:
?- likes(yamini,chocolate).
true.
Related
I have this prolog program.
red(rose).
red(anthurium).
white(rose).
white(gardenia).
white(jasmine).
like(Y,X) :-
red(X),!,
fail
;
white(X).
And below is how it responds to different queries.
?- like(rose,gardenia).
true.
?- like(rose,P).
false.
?- like(Val,anthurium).
false.
?- like(rose,X).
false
The problem I now have is this:
When querying with a variable within the query (Eg: ?- like(rose,X).), Prolog usually responds by returning a value, (something like X=some_val). Why I don't get any value for those variables, but either true or false?
All helpful answers are highly appreciated. Thanks in advance.
Think about what Prolog is doing here:
like(rose,P) succeeds if red(P), so it grabs a possible substitution for P, namely rose or anthurium. Then it traverses the cut and then it fails. But "failing" means that the proof search down that path didn't bring any solution, there are no successful bindings to report (the only fail to get information out of a failing branch is to side-effect to a log file and read check it later). In fact, all bindings will be undone on backtracking. The second branch is white(X), but rose is not white, so we fail here, too.
You can also write:
like(_,X) :- \+ red(X).
like(_,X) :- white(X).
which is a bit more readable. One notices that when calling like(_,X), the goal enclosed by the negation-as-failure operator \+ is nonground. This is bad, and causes a floundering query (in other words, don't do that). I have written this little page on "floundering".
I am examining a Prolog example as a tutorial. In this example I have a predicate with Zero operand like this:
print_all_solutions :-
findall(_,print_solution,_).
how can I call print_all_solution in the console?
When I ask this in the Prolog console I get nothing:
?- print_all_solutions
no answer, also :
?- print_all_solutions.
no answer.
While i get correct answers to other questions like:
?- goal(state([],right,[a,b,c,d],12)).
true.
?- goal(state([],right,[a,b,c,d],19)).
false.
How should I ask a question about predicates with no operand ( /0 ), to see the solution in the console?
I guess your problem is that either init(State) or, more probably, solve(State,Solution,EndState) don't work.
You need to debug: enter these commands after you consulted the source file
?- leash(-all),trace.
?- print_solution.
and you'll get some clue from the Prolog engine
I simply typed this in the console:
findall(_,print_all_solutions,_).
and i get the answer.
I'm new to Prolog and having a bit of difficulty. I have:
man(ken).
man(tom).
woman(juli).
father(ken, tom).
father(ken, juli).
male(A) :- man(A).
brother(A,B) :- male(A), father(C,A), father(C,B), (A \= B).
I know the male/man is redundant, but it's part of the assignment. Anyway, when I try something like:
|?- brother(tom, juli).
I get "no" as the response. I'm sure I've made a stupid, simple mistake, but my lack of understanding is making it very hard to find. Can anyone see what my problem is?
When you enter:
|?- brother(tom, juli).
You'll see a response something like this (SWI Prolog):
true ? ;
no
| ?-
So it first responds with "true" (gives a match) and then, after you enter ; to show more solutions, it says "no" to indicate there are no further solutions. Some prolog interpreters may say "no" or "false" in this case, with the same meaning. This response from the prolog interpreters initially throws many a new prolog user.
You could, alternatively, press "enter" which just means you're done and don't want to see any further solutions:
true ?
yes
| ?-
Then you get "yes".
I'm new to prolog and I'm trying to write a predicate that returns "Yes" if two train stations are on the same line.
line(1,[a,b,c,d,e]);
line(2,[b,g,f,e,i,h]);
line(3,[l,m,g,n,f,o,p,q,i,j]);
same_line(X,Y):-
line(_,L),
member(X,L),
member(Y,L).
Example:
?- same_line(n,j).
Yes
However, I get this error in WIN-PROLOG when compiling: ! Error 67 : Predicate Protected
What am I doing wrong?
Just answering, so that the question goes off the list of unanswered
questions: Yes the (;)/2 is a problem. Further if you really only
want a yes or no, you could also try memberchk/2 instead of member/2.
The code would read:
line(1,[a,b,c,d,e]).
line(2,[b,g,f,e,i,h]).
line(3,[l,m,g,n,f,o,p,q,i,j]).
same_linechk(X,Y):-
line(_,L),
memberchk(X,L),
memberchk(Y,L).
And works as expected:
?- same_linechk(n,j).
true.
The predicate memberchk/2 is part of SWI-Prolog and does not
backtrack after the first time it has found a matching member.
It is essentially a menber/2 with a builtin cut and thus in
the average twice as fast.
Bye
I am learning Prolog for an university exam using SWI Prolog and I have some question about this simple program that implement the different predicate that say TRUE if two element are different (if they do not match) and say FALSE if they match.
This is the code:
different(X,X) :- !,
fail.
diferent(_,_).
The problem is that if I try to execute the following query in the Prolog shell I always obtain FALSE:
[debug] 10 ?- different(a,b).
false.
[debug] 11 ?- different(a,a).
false.
As you can see the first query have to say TRUE because a don't match with b
Why?
change diferent(_,_) to different(_,_). Ie it is a spelling error.
Your second predicate is not being examined as it does not match your query.
The program should be
different(X,X) :- !,fail.
different(_,_).
This "exercise" is pointless. Use prolog-dif!
IMO the only reasonable definition of different/2 is:
different(A,B) :- dif(A,B).
If you are using emacs for editing your prolog files (If not I strongly recommend you switching to it) I suggest you using hi-lock-mode. I will highlight in a pattern-like fashion all matches in the file whenever the cursor is over a word. It can save you hours of pain when you develop bigger projects.