user210767
user210767

Reputation: 69

Using And clause in HEAD of a prolog statement

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 doesn't allow any operators in the clause head. I have spent 5 hours till now trying to do various things with this statement but unable to reach a solution that works. :(

Upvotes: 0

Views: 704

Answers (4)

Alexander Serebrenik
Alexander Serebrenik

Reputation: 3577

As a side note: the idea of using disjunctions in heads of clauses has lead to disjunctive logic programming, see, e.g., "Foundations of Disjunctive Logic Programming" by Jorge Lobo, Jack Minker, Arcot Rajaseka. edu(X);rich(X) :- member(X). would be a valid disjunctive clause. A related topic, disjunctive Datalog, has been explored by Nicola Leone, Gerald Pfeifer and Wolfgang Faber in the DLV project: http://www.dbai.tuwien.ac.at/proj/dlv/

Upvotes: 0

Juanjo Conti
Juanjo Conti

Reputation: 30073

Maybe you want to write:

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

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

Upvotes: -1

Pesto
Pesto

Reputation: 23901

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.

Upvotes: 1

Mark Bolusmjak
Mark Bolusmjak

Reputation: 24419

See http://en.wikipedia.org/wiki/Horn_clause 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.

Upvotes: 1

Related Questions