I'm a beginner in Prolog and I am dealing with a problem that might seem stupid to you, but I really can't understand what I'm doing wrong! Ok, I have this file fruits.pl and inside that I have something like this:
fruit(apple,small,sweet).
fruit(lemon,small,nosweet).
fruit(melon,big,sweet).
I have already (inside that file made a coexist(X,Y) atom that checks if two fruits can be put together in a plate. It works fine! But now I can't create a suggest(X) that takes as a parameter a fruit and returns a list of fruits that can be put together in the same plate. The thing is I was trying to make something like that
suggest(X) :- findall(Y,fruit(Y,_,_), List), coexist(X,Y).
What do you think? Every time I try to run this in swi prolog there is a warning 'singleton variable' and when I press
suggest(apple).
then it says false.. sorry for my english :/
Predicates in Prolog do not return anything. You have goals that are satisfied or not and you can interpret that as returning true
or false
.
Your predicate suggest(X)
should contain another parameter that will be bound to the list of fruits that go together with X
. An option would be: suggest(X, List)
which describes the following relation: List
represents all the fruits that go together with X
. Then, you could ask:
?- suggest(apple, List).
List = [pear, cherry].
The goal findall(Y, ... , ...)
uses the Y
variable internally and Y
is still unbound after the goal is satisfied. So, you should move coexist(X,Y)
inside the second argument of findall/3
which is the goal that is satisfied in all possible ways. Th rule below works only if X
is instantiated (suggest(+X, -List)
).
suggest(X, List) :- findall(Y, (fruit(Y,_,_), coexist(X, Y)), List).
You can read this as follows: "List
represents all fruits Y
that coexist with X
".