Programming in Prolog: Family Tree

Illustrated here is a program written in the logical language of Prolog.

This particular program defines facts as the simple relationships between an example family, followed by the rules that represent the organization of a family in general.


female(diana).
female(margaret).
female(julie).
female(mary).

male(jacob).
male(mark).
male(bob).
male(jeff).
male(tim).

father(jacob, margaret).
father(jacob, bob).
father(mark, mary).
father(mark, jeff).
father(bob, tim).
mother(diana, margaret).
mother(diana, bob).
mother(margaret, mary).
mother(margaret, jeff).
mother(julie, tim).

offspring(Y, X) :- father(X, Y).
offspring(Y, X) :- mother(X, Y).

grandparent(X, Z) :- offspring(Z, Y), offspring(Y, X).

mother-in-law(X, Y) :- mother(Y, W), father(Z, W), mother(X, Z).
mother-in-law(X, Y) :- father(Y, W), mother(Z, W), mother(X, Z).
father-in-law(X, Y) :- mother(Y, W), father(Z, W), father(X, Z).
father-in-law(X, Y) :- father(Y, W), mother(Z, W), father(X, Z).

aunt(X, Y) :- offspring(Y, Z), offspring(Z, A), offspring(X, A), female(X).
uncle(X, Y) :- offspring(Y, Z), offspring(Z, A), offspring(X, A), male(X).

cousin(X, Y) :- offspring(Y, Z), uncle(Z, X).
cousin(X, Y) :- offspring(Y, Z), aunt(Z, X).

In logical programming, the programs are not written to solve a particular problem. They are instead given information such as facts and rules and the problem is stated at runtime. Take a look at the following input and output.

1 ?- trace, cousin(jeff, Who).
   Call: (7) cousin(jeff, _G0) ? creep
   Call: (8) offspring(_G0, _G58) ? creep
   Call: (9) father(_G57, _G0) ? creep
   Exit: (9) father(jacob, margaret) ? creep
   Exit: (8) offspring(margaret, jacob) ? creep
   Call: (8) uncle(jacob, jeff) ? creep
   Call: (9) offspring(jeff, _G58) ? creep
   Call: (10) father(_G57, jeff) ? creep
   Exit: (10) father(mark, jeff) ? creep
   Exit: (9) offspring(jeff, mark) ? creep
   Call: (9) offspring(mark, _G58) ? creep
   Call: (10) father(_G57, mark) ? creep
   Fail: (10) father(_G57, mark) ? creep
   Redo: (9) offspring(mark, _G58) ? creep
   Call: (10) mother(_G57, mark) ? creep
   Fail: (10) mother(_G57, mark) ? creep
   Fail: (9) offspring(mark, _G58) ? creep
   Redo: (10) father(_G57, jeff) ? creep
   Fail: (10) father(_G57, jeff) ? creep
   Redo: (9) offspring(jeff, _G58) ? creep
   Call: (10) mother(_G57, jeff) ? creep
   Exit: (10) mother(margaret, jeff) ? creep
   Exit: (9) offspring(jeff, margaret) ? creep
   Call: (9) offspring(margaret, _G58) ? creep
   Call: (10) father(_G57, margaret) ? creep
   Exit: (10) father(jacob, margaret) ? creep
   Exit: (9) offspring(margaret, jacob) ? creep
   Call: (9) offspring(jacob, jacob) ? creep
   Call: (10) father(jacob, jacob) ? creep
   Fail: (10) father(jacob, jacob) ? creep
   Redo: (9) offspring(jacob, jacob) ? creep
   Call: (10) mother(jacob, jacob) ? creep
   Fail: (10) mother(jacob, jacob) ? creep
   Fail: (9) offspring(jacob, jacob) ? creep
   Redo: (10) father(_G57, margaret) ? creep
   Fail: (10) father(_G57, margaret) ? creep
   Redo: (9) offspring(margaret, _G58) ? creep
   Call: (10) mother(_G57, margaret) ? creep
   Exit: (10) mother(diana, margaret) ? creep
   Exit: (9) offspring(margaret, diana) ? creep
   Call: (9) offspring(jacob, diana) ? creep
   Call: (10) father(diana, jacob) ? creep
   Fail: (10) father(diana, jacob) ? creep
   Redo: (9) offspring(jacob, diana) ? creep
   Call: (10) mother(diana, jacob) ? creep
   Call: (10) mother(diana, jacob) ? creep
   Fail: (10) mother(diana, jacob) ? creep
   Fail: (9) offspring(jacob, diana) ? creep
   Redo: (10) mother(_G57, margaret) ? creep
   Fail: (10) mother(_G57, margaret) ? creep
   Fail: (9) offspring(margaret, _G58) ? creep
   Redo: (10) mother(_G57, jeff) ? creep
   Fail: (10) mother(_G57, jeff) ? creep
   Fail: (9) offspring(jeff, _G58) ? creep
   Fail: (8) uncle(jacob, jeff) ? creep
   Redo: (9) father(_G57, _G0) ? creep
   Exit: (9) father(jacob, bob) ? creep
   Exit: (8) offspring(bob, jacob) ? creep
   Call: (8) uncle(jacob, jeff) ? creep
   Call: (9) offspring(jeff, _G58) ? creep
   Call: (10) father(_G57, jeff) ? creep
   Exit: (10) father(mark, jeff) ? creep
   Exit: (9) offspring(jeff, mark) ? creep
   Call: (9) offspring(mark, _G58) ? creep
   Call: (10) father(_G57, mark) ? creep
   Fail: (10) father(_G57, mark) ? creep
   Redo: (9) offspring(mark, _G58) ? creep
   Call: (10) mother(_G57, mark) ? creep
   Fail: (10) mother(_G57, mark) ? creep
   Fail: (9) offspring(mark, _G58) ? creep
   Redo: (10) father(_G57, jeff) ? creep
   Fail: (10) father(_G57, jeff) ? creep
   Redo: (9) offspring(jeff, _G58) ? creep
   Call: (10) mother(_G57, jeff) ? creep
   Exit: (10) mother(margaret, jeff) ? creep
   Exit: (9) offspring(jeff, margaret) ? creep
   Call: (9) offspring(margaret, _G58) ? creep
   Call: (10) father(_G57, margaret) ? creep
   Exit: (10) father(jacob, margaret) ? creep
   Exit: (9) offspring(margaret, jacob) ? creep
   Call: (9) offspring(jacob, jacob) ? creep
   Call: (10) father(jacob, jacob) ? creep
   Fail: (10) father(jacob, jacob) ? creep
   Redo: (9) offspring(jacob, jacob) ? creep
   Call: (10) mother(jacob, jacob) ? creep
   Fail: (10) mother(jacob, jacob) ? creep
   Fail: (9) offspring(jacob, jacob) ? creep
   Redo: (10) father(_G57, margaret) ? creep
   Fail: (10) father(_G57, margaret) ? creep
   Redo: (9) offspring(margaret, _G58) ? creep
   Call: (10) mother(_G57, margaret) ? creep
   Exit: (10) mother(diana, margaret) ? creep
   Exit: (9) offspring(margaret, diana) ? creep
   Call: (9) offspring(jacob, diana) ? creep
   Call: (10) father(diana, jacob) ? creep
   Fail: (10) father(diana, jacob) ? creep
   Redo: (9) offspring(jacob, diana) ? creep
   Call: (10) mother(diana, jacob) ? creep
   Fail: (10) mother(diana, jacob) ? creep
   Fail: (9) offspring(jacob, diana) ? creep
   Redo: (10) mother(_G57, margaret) ? creep
   Fail: (10) mother(_G57, margaret) ? creep
   Fail: (9) offspring(margaret, _G58) ? creep
   Redo: (10) mother(_G57, jeff) ? creep
   Fail: (10) mother(_G57, jeff) ? creep
   Fail: (9) offspring(jeff, _G58) ? creep
   Fail: (8) uncle(jacob, jeff) ? creep
   Redo: (9) father(_G57, _G0) ? creep
   Exit: (9) father(mark, mary) ? creep
   Exit: (8) offspring(mary, mark) ? creep
   Call: (8) uncle(mark, jeff) ? creep
   Call: (9) offspring(jacob, diana) ? creep
   Call: (10) father(diana, jacob) ? creep
   Fail: (10) father(diana, jacob) ? creep
   Redo: (9) offspring(jacob, diana) ? creep
   Call: (10) mother(diana, jacob) ? creep
   Fail: (10) mother(diana, jacob) ? creep
   Fail: (9) offspring(jacob, diana) ? creep
   Redo: (10) mother(_G57, margaret) ? creep
   Fail: (10) mother(_G57, margaret) ? creep
   Fail: (9) offspring(margaret, _G58) ? creep
   Redo: (10) mother(_G57, jeff) ? creep
   Fail: (10) mother(_G57, jeff) ? creep
   Fail: (9) offspring(jeff, _G58) ? creep
   Fail: (8) uncle(jacob, jeff) ? creep
   Redo: (9) father(_G57, _G0) ? creep
   Exit: (9) father(mark, mary) ? creep
   Exit: (8) offspring(mary, mark) ? creep
   Call: (8) uncle(mark, jeff) ? creep
   Call: (9) offspring(jeff, _G58) ? creep
   Call: (10) father(_G57, jeff) ? creep
   Exit: (10) father(mark, jeff) ? creep
   Exit: (9) offspring(jeff, mark) ? creep
   Call: (9) offspring(mark, _G58) ? creep
   Call: (10) father(_G57, mark) ? creep
   Fail: (10) father(_G57, mark) ? creep
   Redo: (9) offspring(mark, _G58) ? creep
   Call: (10) mother(_G57, mark) ? creep
   Fail: (10) mother(_G57, mark) ? creep
   Fail: (9) offspring(mark, _G58) ? creep
   Redo: (10) father(_G57, jeff) ? creep
   Fail: (10) father(_G57, jeff) ? creep
   Redo: (9) offspring(jeff, _G58) ? creep
   Call: (10) mother(_G57, jeff) ? creep
   Exit: (10) mother(margaret, jeff) ? creep
   Exit: (9) offspring(jeff, margaret) ? creep
   Call: (9) offspring(margaret, _G58) ? creep
   Call: (10) father(_G57, margaret) ? creep
   Exit: (10) father(jacob, margaret) ? creep
   Exit: (9) offspring(margaret, jacob) ? creep
   Call: (9) offspring(mark, jacob) ? creep
   Call: (10) father(jacob, mark) ? creep
   Fail: (10) father(jacob, mark) ? creep
   Redo: (9) offspring(mark, jacob) ? creep
   Call: (10) mother(jacob, mark) ? creep
   Fail: (10) mother(jacob, mark) ? creep
   Fail: (9) offspring(mark, jacob) ? creep
   Redo: (10) father(_G57, margaret) ? creep
   Fail: (10) father(_G57, margaret) ? creep
   Redo: (9) offspring(margaret, _G58) ? creep
   Call: (10) mother(_G57, margaret) ? creep
   Exit: (10) mother(diana, margaret) ? creep
   Exit: (9) offspring(margaret, diana) ? creep
   Call: (9) offspring(mark, diana) ? creep
   Call: (10) father(diana, mark) ? creep
   Fail: (10) father(diana, mark) ? creep
   Redo: (9) offspring(mark, diana) ? creep
   Call: (10) mother(diana, mark) ? creep
   Fail: (10) mother(diana, mark) ? creep
   Fail: (9) offspring(mark, diana) ? creep
   Redo: (10) mother(_G57, margaret) ? creep
   Fail: (10) mother(_G57, margaret) ? creep
   Fail: (9) offspring(margaret, _G58) ? creep
   Redo: (10) mother(_G57, jeff) ? creep
   Fail: (10) mother(_G57, jeff) ? creep
   Fail: (9) offspring(jeff, _G58) ? creep
   Fail: (8) uncle(mark, jeff) ? creep
   Redo: (9) father(_G57, _G0) ? creep
   Exit: (9) father(mark, jeff) ? creep
   Exit: (8) offspring(jeff, mark) ? creep
   Call: (8) uncle(mark, jeff) ? creep
   Call: (9) offspring(jeff, _G58) ? creep
   Call: (10) father(_G57, jeff) ? creep
   Exit: (10) father(mark, jeff) ? creep
   Exit: (9) offspring(jeff, mark) ? creep
   Call: (9) offspring(mark, _G58) ? creep
   Call: (10) father(_G57, mark) ? creep
   Fail: (10) father(_G57, mark) ? creep
   Redo: (9) offspring(mark, _G58) ? creep
   Call: (10) mother(_G57, mark) ? creep
   Fail: (10) mother(_G57, mark) ? creep
   Fail: (9) offspring(mark, _G58) ? creep
   Redo: (10) father(_G57, jeff) ? creep
   Fail: (10) father(_G57, jeff) ? creep
   Redo: (9) offspring(jeff, _G58) ? creep
   Call: (10) mother(_G57, jeff) ? creep
   Exit: (10) mother(margaret, jeff) ? creep
   Exit: (9) offspring(jeff, margaret) ? creep
   Call: (9) offspring(margaret, _G58) ? creep
   Call: (10) mother(jacob, mark) ? creep
   Fail: (10) mother(jacob, mark) ? creep
   Fail: (9) offspring(mark, jacob) ? creep
   Redo: (10) father(_G57, margaret) ? creep
   Fail: (10) father(_G57, margaret) ? creep
   Redo: (9) offspring(margaret, _G58) ? creep
   Call: (10) mother(_G57, margaret) ? creep
   Exit: (10) mother(diana, margaret) ? creep
   Exit: (9) offspring(margaret, diana) ? creep
   Call: (9) offspring(mark, diana) ? creep
   Call: (10) father(diana, mark) ? creep
   Fail: (10) father(diana, mark) ? creep
   Redo: (9) offspring(mark, diana) ? creep
   Call: (10) mother(diana, mark) ? creep
   Fail: (10) mother(diana, mark) ? creep
   Fail: (9) offspring(mark, diana) ? creep
   Redo: (10) mother(_G57, margaret) ? creep
   Fail: (10) mother(_G57, margaret) ? creep
   Fail: (9) offspring(margaret, _G58) ? creep
   Redo: (10) mother(_G57, jeff) ? creep
   Fail: (10) mother(_G57, jeff) ? creep
   Fail: (9) offspring(jeff, _G58) ? creep
   Fail: (8) uncle(mark, jeff) ? creep
   Redo: (9) father(_G57, _G0) ? creep
   Exit: (9) father(bob, tim) ? creep
   Exit: (8) offspring(tim, bob) ? creep
   Call: (8) uncle(bob, jeff) ? creep
   Call: (9) offspring(jeff, _G58) ? creep
   Call: (10) father(_G57, jeff) ? creep
   Exit: (10) father(mark, jeff) ? creep
   Exit: (9) offspring(jeff, mark) ? creep
   Call: (9) offspring(mark, _G58) ? creep
   Call: (10) father(_G57, mark) ? creep
   Fail: (10) father(_G57, mark) ? creep
   Redo: (9) offspring(mark, _G58) ? creep
   Call: (10) mother(_G57, mark) ? creep
   Fail: (10) mother(_G57, mark) ? creep
   Fail: (9) offspring(mark, _G58) ? creep
   Redo: (10) father(_G57, jeff) ? creep
   Fail: (10) father(_G57, jeff) ? creep
   Redo: (9) offspring(jeff, _G58) ? creep
   Call: (10) mother(_G57, jeff) ? creep
   Exit: (10) mother(margaret, jeff) ? creep
   Exit: (9) offspring(jeff, margaret) ? creep
   Call: (9) offspring(margaret, _G58) ? creep
   Call: (10) father(_G57, margaret) ? creep
   Exit: (10) father(jacob, margaret) ? creep
   Exit: (9) offspring(margaret, jacob) ? creep
   Call: (9) offspring(bob, jacob) ? creep
   Call: (10) father(jacob, bob) ? creep
   Exit: (10) father(jacob, bob) ? creep
   Exit: (9) offspring(bob, jacob) ? creep
   Call: (9) male(bob) ? creep
   Exit: (9) male(bob) ? creep
   Exit: (8) uncle(bob, jeff) ? creep
   Exit: (7) cousin(jeff, tim) ? creep
Who = tim .

The output above is quite considerable. It represents each action that occurs by which the program determines “who is the cousin of jeff?”.

The answer to that is Tim. Enchanting isn’t it?

Tim the Enchanter

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>