% A sample database.  

% Percent-sign ('%') marks comments to end-of-line.

% FACTS
male(abe).
male(homer).
male(bart).

parent(jackie,marge).

parent(abe,homer).
parent(mona,homer).

parent(homer,bart).
parent(marge,bart).

parent(homer,lisa).
parent(marge,lisa).

parent(homer,maggie).
parent(marge,maggie).

parent(bart,bartJr).
parent(bart,cowabunga).
parent(bartJr,bartJrII).

parent(lisa,lisaJr).
parent(lisaJr,lisaJrII).


% Task: give me a rule for `father/2`.
father(Old,Yng) :- parent(Old,Yng),  male(Old).




% Task: `father/1`
father(Prsn) :- father(Prsn,_).

%%%% Define grandparent/2:
%%%% (What is the def'n in English, for "Old is a grandparent of Yng"?)
grandparent(Old,Yng) :- parent(Old,Middle), parent(Middle,Yng).


%%%% Task: define *ancestor*:
%anc(Old,Yng) :- parent(Old,Yng).
%anc(Old,Yng) :- parent(Old, Middle), parent(Middle, Yng).
%anc(Old,Yng) :- parent(Old, P1), parent(P1,P2), parent(P2, Yng).
%anc(Old,Yng) :- parent(Old, P1), parent(P1,P2), parent(P2,P3), parent(P3, Yng).

%%%...uh-oh, this is going to take a while.
%%% Try a recursive formulation:
anc(Old,Yng) :- Old=Yng.
anc(Old,Yng) :- parent(Old,X), anc(X,Yng).

%%%%% note: why a treenode is (trivially) its own ancestor:
% In css, I want all `td` elements to be right-aligned, when I'm inside a `class='numeric'`.
% So I can write `.numeric td { text-align: right; }`, and now I can add `class='numeric'` to
% the entire table, or just the `tr`, .... but NOT the td itself, argh!
% Moreover, there isn't even a CSS selector for "and". There is a hack for elt.class, but that's ad hoc.  Why not `and`, `or`, parens?
% So I happen to be able to use `.numeric td, td.numeric { ... }`

%%%%%


% ask: Old=bart,Yng=bartJr ?      Yes, by first rule, since parent(bart,bartJr).
% ask: Old=homer,Yng=bartJr ?     parent(homer,P), anc(P,bartJr) -- P=bart works (by prev case)
% ask: Old=abe,Yng=bartJr ?  parent(abe,P), anc(P,bartJr).  Yes, P=homer works (by prev case).




% define firstCousin/2
%firstCousin(P1,P2) :- .   % (in terms of sibling, perhaps?)

%alternate def'n: in terms of grandparent ?
%firstCousin(P1,P2) :- .





%%% A and B are 1st-cousins, or 2nd-cousins, or 3rd-cousins, etc.
%%%   N.B. 0th cousins are siblings?
%%%   N.B. -1st cousin is yourself!?!?  ("Nota Bene" -- latin for "notice" or "take note")

%%% Task: write a generalized 'nthCousin':
% are P1 and P2 nth-cousins (for any n=-1,0,1,2,3,...?)



%%nthCousin(A,B) :- A's parent("AP") and B's parent("BP") are nth cousins.
%% We yearn to say        nthCousin( parent(A), parent(B) )
%% but can't, since Prolog only has T/F predicates (not functions that return people).
%% Instead, we use the predicates+solving to give names to the parents:

% As before, we can re-write `nthCousin(A,B) :- A=B.` as:













%%%%

