Reputation: 474
I'm new to Prolog and I'm trying to write a predicate, goodveggies(X,Y)
such that the code runs the following way:
?- goodveggies(broc,spinach).
true.
?- goodveggies(X,artichoke).
X = broc
What I've tried:
% Define the facts:
goodveggies(broc,spinach).
goodveggies(broc,artichoke).
% Now make the predicate.
goodveggies(X,Y) :- goodveggies(X,Y).
My program runs fine, but the problem that I am having is that my program crashes when I type something like, goodveggies(broc, tomato).
I don't understand how to filter out the results I don't want in order for the program to run properly.
Upvotes: 1
Views: 86
Reputation: 476574
I don't understand why you define the predicate
goodveggies(X,Y) :- goodveggies(X,Y).
This doesn't make sense at all since goodveggies (X,Y)
appears to be true if it is true. Furthermore say you want to query for goodveggies(broc, tomato)
, it will have the following infinite executation (remarks added):
goodveggies(broc, tomato) :-
goodveggies(broc, spinach); FAIL!
goodveggies(broc,artichoke); FAIL!
goodveggies(broc, tomato) :-
goodveggies(broc, spinach); FAIL!
goodveggies(broc,artichoke); FAIL!
goodveggies(broc, tomato) :-
goodveggies(broc, spinach); FAIL!
goodveggies(broc,artichoke); FAIL!
goodveggies(broc, tomato) :-
...
So you keep querying for the same fact.
You probably want to be able to swap the order in which the values appear, thus:
goodveggies(X,Y) :- goodveggies(Y,X).
Now this won't work either, since it will try:
goodveggies(broc,tomato) :-
goodveggies(tomato,broc) :-
goodveggies(broc,tomato) :-
goodveggies(tomato,broc) :-
...
You can however solve this by defining two predicates:
gv(broc,spinach).
gv(broc,artichoke).
goodveggies(X,Y) :-
gv(X,Y).
goodveggies(X,Y) :-
gv(Y,X).
The first predicate gv/2
defines good combinations of veggies, the second goodveggies/2
tries to query for both orders, if they both fail, the predicate ends.
What you have to understand in prolog is that everything that is not specified as true is false. That's what they call the minimal world assumption. So if you didn't specify goodveggies(broc,tomato)
and it can't be derived by some predicate, the program will return false. In case you didn't want to have a variable order, listing the facts was fine:
goodveggies(broc,spinach).
goodveggies(broc,artichoke).
Upvotes: 1