Joffrey Baratheon
Joffrey Baratheon

Reputation: 474

Writing a Predicate

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

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

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/2defines 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

Related Questions