Lets say I have a relations
Happy(james)
Happy(harry)
unhappy(Tom)
unhappy(Ben)
unhappy(Dick)
And then a list of people
[Ben, James, Harry, Tom, Dick]
How can I iterate the list and check the boolean of each list element as to whether they are happy or not?
Well, first of all, in Prolog, if a word starts with a capital letter, it means that it is a variable. So you should be careful with that.
This is my database after the correction:
and I added a recursive rule that helps me see who is happy and who is not from a given list:
Here is the result:
Here is another approach to dealing with this task. This answer doesn't fuss with with IO, which is unnecessary here, and it goes into some detail about the strategy employed:
I'm working with the following facts:
Your desired end can be achieved with a simple predicate establishing a relationship between a name and the
happy/1
andunhappy/1
predicates:This
person_happiness/2
exploits the homoiconic nature of Prolog. The instance ofhappy/1
appearing in the rule's body is a call to the predicate, and it is true just in casePerson
can be unified in a call to the facthappy/1
. The instance ofhappy/1
occurring in the second argument ofperson_happiness/2
functions as a data structure, and essentially works to labelPerson
as happy. This second argument could be replaced withhappy-Person
,happy/Person
,happy=Person
,emotion(Person, happy)
, and many other things besides.With this predicate alone, we can generate a report of all the happy and unhappy people by backtracking over free variables:
We can also find the Happiness for a particular person:
And we can find all the people who share a common quality:
The queries above work just by consulting the facts
happy/1
andunhappy/2
, but you want to check these facts against the names in your list. We can usemember/2
in conjunction withperson_happiness/2
to achieve everything you want with backtracking:To get all of these results in one go, we can use
maplist/3
to applyperson_happiness/2
to each member of thePeople
inpeople(People)
: