tags:

views:

41

answers:

3

Every member of this club is either educated or rich or both.

I wanted to write a statement very similar to above in my PROLOG code. I wrote everything else.

edu(X);rich(X) :- member(X).

This is what I had written. But then PROLOG does allow any operators in the head clause. I have spent 5 hours till now trying to do various things with this statement but unable to reach a solution that works. :(

+1  A: 

See http://en.wikipedia.org/wiki/Horn%5Fclause for am explanation of the form of logic Prolog is based on.

Given your statement, ("Every member of this club is either educated or rich or both."), the only things you can declare to be true are:

  • A person is educated if they are a member and not rich.
  • A person is rich if they are a member and not educated.

The following, for example, are not necessarily true:

  • A person who is rich and educated is a member.
  • A member who is rich is educated.
  • A member who is rich is not educated.
z5h
+1  A: 

You can't combine multiple heads. If you want edu(X) and rich(X) to be true when member(X) is true, you have to define them separately ("every member of this club is educationed" and "every member of this club is rich"):

edu(X) :-
   member(X).
rich(X) :-
   member(X).

The tricky part is that your original statement is not well-formed. It says that some members may be rich but not educated or vice versa. This is problematic. For example, let's take the naive case that if a member isn't rich, he's educated, and the reverse:

edu(X) :-
    member(X), \+ rich(X).
rich(X) :-
    member(X), \+ edu(X).

Now, according to these rules, nobody is automatically rich and educated. So long as we define every member as at least one of the two, this is fine. However, consider these facts:

member(alice).
member(bob).
member(charlie).
member(dave).

rich(alice).
edu(bob).
rich(charlie).
edu(charlie).

In this case, rich(alice) works fine, because it's a fact. edu(alice) will result in no. The reverse is true for bob. With charlie, we've defined both as facts, so both are true. But what about dave? Both edu(dave) and rich(dave) refer back to the other, creating an infinite recursion. Without any further knowledge of what you're doing, the best we can do to resolve this is to default either edu(X) or rich(X) to true:

edu(X) :-
    member(X).
rich(X) :-
    member(X), \+ edu(X).

Now everyone is assumed to be educated unless we explicitly declare otherwise. You could do the same thing defaulting to rich if you preferred. Short of additional information, this is the best you can do.

Pesto
A: 

Maybe you want to write:

member(X) :- edu(X) ; rich(X)

If someone is educated, rich or both, is a member of the club.

Juanjo Conti
akshar100 wants `if X is a member of the club then X is rich or educated`. What you have is the converse of that.
humble coffee