:- module(_,_,[]).

% Expressing disequality as a relation (instead of using \== or \=)

% We assign a number to the people in our database:
person_num(john,    0).
person_num(peter,   s(0)).
person_num(mary,    s(s(0))).
person_num(michael, s(s(s(0)))).
person_num(david,   s(s(s(s(0))))).
person_num(jill,    s(s(s(s(s(0)))))).

% Defining disequality of (Peano) numbers:
diffnat(0,s(_)).                    % 0 differs from any s(...)
diffnat(s(_),0).                    % any s(...) differs from 0
diffnat(s(X),s(Y)) :- diffnat(X,Y). % same depth: look further in

% We can now define disequality of people:
different_person(X,Y) :-
    person_num(X,NX),
    person_num(Y,NY),
    diffnat(NX,NY).

% Try:
% ?- different_person(john,mary).
% ?- different_person(john,john).
% And it enumerates! (it is a real relation):
% ?- different_person(john,X).      
% ?- different_person(X,Y).

% Compare with the built-in, which is not a relation:
% ?- john \= mary.
% ?- X \= Y.                     % 'yes', although X and Y may be the same:
% ?- X = john, Y = mary, X \= Y. % 'no'

% The family database, to try sibling/2:
father_of(john, peter).
father_of(john, mary).
father_of(peter, michael).

mother_of(mary, david).
mother_of(jill, john).

parent(X,Y) :- father_of(X,Y).
parent(X,Y) :- mother_of(X,Y).

sibling(X,Y) :- parent(P,X), parent(P,Y), different_person(X,Y).

% ?- sibling(X,Y).
% ?- sibling(peter,peter).
