prologprolog-difprolog-cutlogical-purity

Prolog, about how to form better clauses


I have following clauses:

num_parent(adam, X) :- !, X = 0.  
num_parent(eve, X) :- !, X = 0.  
num_parent(X, 2).  

When I typed the query:

num_parent(eve,X).

It only returns:

X = 0.  

which is what I want.

But when I typed this query:

num_parent(X,0).  

it only returns:

X = adam.

So how can I modify the clauses to make it return:

X = adam;
X = eve.

Thanks


Solution

  • First, try to formulate what you want in plain English. You probably want to say:

    Everyone has two parents except Adam and Eve who have none.

    What about Lilith? Never mind, let's stick to your reading.

    num_parent(Person, 2) :-
       dif(Person, adam),
       dif(Person, eve).
    num_parent(adam, 0).
    num_parent(eve, 0).
    

    As you can see, it is a bit cumbersome to define this: You have to mention each exceptional person twice. Easy to make an error.

    With if_/3 available in library(reif) for SICStus and SWI you can write more succinctly:

    num_parent(Person, Num) :-
       if_( ( Person = adam ; Person = eve ), Num = 0, Num = 2 ).
    

    And now some uses:

    ?- num_parent(eve, Num).
       Num = 0.
    ?- num_parent(X, 0).
       X = adam
    ;  X = eve
    ;  false.
    ?- num_parent(X, 2).
       dif(X, eve), dif(X, adam).
    ?- num_parent(lilith, 2).
       true.