% 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(F,C) :- male(F), parent(F,C). % Task: `isADad/1` isADad(P) :- father(P,X). %%%% 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(P,P). anc(Old,Yng) :- parent(Old,P), anc(P,Yng). % 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) :- parent(ParentOfP1, P1), parent(ParentOfP2, P2), sibling( ParentOfP1, ParentOfP2 ). sibling(A,B) :- parent(P, A), parent(P, B). firstCousin(P1,P2) :- grandparent(X,P1), grandparent(X,P2). % (well not quite) % parent(X,Middle1), parent(Middle1,P1), % parent(X,Middle2), parent(Middle2,P2), % Middle1 \= Middle2. % are P1 and P2 nth-cousins (for any n=-1,0,1,2,3,...?) nthCousin(P,P). nthCousin(P1,P2) :- parent(X,P1), parent(Y,P2), nthCousin(X,Y). % (two possible ways -- one in terms of siblings?) %%% 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': %nthCousin(A,B) :- A=B. %%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: %%%%