MWB
MWB

Reputation: 12567

How would you express mutual exclusion of facts in Prolog?

Suppose you are working with a genealogy database. Some records are missing. You might know that people named "John" were male, and people named "Mary" were female, etc.

male(X)   :- first_name(X, "John").
female(X) :- first_name(X, "Mary").

For people with exotic or foreign names, their gender can be unclear, but it must have been one of the two. Marriage (before this century) was between opposite genders.

female(X) :- wed(X, Y), male  (Y).
male  (X) :- wed(X, Y), female(Y).

Knowing that someone's gender was either male or female (even if you don't know which) is an important tidbit in deciphering identities and relationships.

How would you encode this knowledge in Prolog?


female(X) :- person(X), not(male(X)).

is incorrect, as it makes you conclude that everyone is female unless they can be proven to be male.

Upvotes: 2

Views: 197

Answers (2)

Isabelle Newbie
Isabelle Newbie

Reputation: 9378

incorrect, as it makes you conclude that everyone is female unless they can be proven to be male

This kind of reasoning, slightly refined, is not incorrect. Everyone is potentially female unless they are proven to be male. What else would they be?

possibly_female(Person) :-
    person(Person),
    \+ proven_male(Person).
possibly_female(Person) :-
    proven_female(Person).

possibly_male(Person) :-
    person(Person),
    \+ proven_female(Person).
possibly_male(Person) :-
    proven_male(Person).

Although, depending on what you want to do, rather than using a division into known/possible genders it might be simpler to use a three-way male/female/unknown division:

unknown_gender(Person) :-
    person(Person),
    \+ proven_female(Person),
    \+ proven_male(Person).

(Lots of caveats about gender binarism apply to the real world, though arguably if you're really modeling historical databases based on a binary assumption, it's reasonable to use that model.)

Upvotes: 3

TA_intern
TA_intern

Reputation: 2422

You are making a ton of assumptions about many things. The question is more complicated than it needs to be because of this.

In your case, "is not known to be male" is not enough for "is female", you say. But you also say, "is not known to be male AND is married to a male" is enough.

In some hypothetical program (which we don't have in your question, so it isn't really reproducible) you would maybe write:

is_female(X) :- female(X).
is_female(X) :- \+ is_male(X), married_to(X, Y), is_male(Y).

There is stuff that came from filling in the blanks in your question. Is there need for female/1 and for is_female/1? It depends. Etc

Upvotes: 2

Related Questions