Family Database in Prolog - prolog

I have written a program in Prolog for the database of a family. I have defined a few predicates like mother_of, father_of, son_of , grandparent(G,X). I was supposed to define the above-mentioned rules. I am new to Prolog. Can someone please let me know if my code is right or if I am on the right path?
man(dan).
man(joe).
man(paul).
woman(marry).
woman(susie).
parent(joe,susie). % means adam is parent of peter
parent(joe,dan) :- child(dan,joe).
parent(marry,susie).
parent(giuseppe,margaret).
parent(giuseppe,evelyn).
parent(giuseppe,robert).
parent(giuseppe,grace).
parent(giuseppe,fred).
parent(giuseppe,mary).
parent(giuseppe,estelle).
parent(albina,margaret).
parent(albina,evelyn).
parent(albina,robert).
parent(albina,grace).
parent(albina,fred).
parent(albina,mary).
parent(albina,estelle).
parent(ida,catherine).
parent(ida,juanita).
parent(ida,edythe).
parent(ida,george).
parent(johnMiddleton,catherine).
parent(georgeAlexandar,juanita).
parent(georgeAlexandar,edythe).
parent(georgeAlexandar,george).
parent(estelle,steve).
parent(estelle,judy).
parent(estelle,david).
parent(estelle,marilyn).
parent(estelle,john).
parent(george,steve).
parent(george,judy).
parent(george,david).
parent(george,marilyn).
parent(george,john).
parent(marry,dan).
father_of(F,C):-man(F),parent(F,C).
mother_of(M,C):-woman(M),parent(M,C).
son_of(C,F) :-man(C),child(C,F).
brother(B,P) :- man(B),
mother(M,B),
mother(M,P),
father(F,B),
father(F,P).
sister(S,P) :- woman(S),
mother(M,S),
mother(M,P),
father(F,S),
father(F,P).
grandparent(G,X) :- parent(G,P),
parent(P,X).
grandparent(G,john).

I have added
child(C, P) :-
parent(P, C).
and commented out
% parent(joe,dan) :- child(dan,joe).
and
% grandparent(G, john).
Now you can try
?- child(evelyn, giuseppe).
true .
as expected.
All the code for your reference
man(dan).
man(joe).
man(paul).
woman(marry).
woman(susie).
parent(joe, susie).
% Do not use this as it cause stack overflow due to child/2 definition later on
parent(joe, dan).
% :- child(dan, joe).
parent(marry, susie).
parent(giuseppe, margaret).
parent(giuseppe, evelyn).
parent(giuseppe, robert).
parent(giuseppe, grace).
parent(giuseppe, fred).
parent(giuseppe, mary).
parent(giuseppe, estelle).
parent(albina, margaret).
parent(albina, evelyn).
parent(albina, robert).
parent(albina, grace).
parent(albina, fred).
parent(albina, mary).
parent(albina, estelle).
parent(ida, catherine).
parent(ida, juanita).
parent(ida, edythe).
parent(ida, george).
parent(johnMiddleton, catherine).
parent(georgeAlexandar, juanita).
parent(georgeAlexandar, edythe).
parent(georgeAlexandar, george).
parent(estelle, steve).
parent(estelle, judy).
parent(estelle, david).
parent(estelle, marilyn).
parent(estelle, john).
parent(george, steve).
parent(george, judy).
parent(george, david).
parent(george, marilyn).
parent(george, john).
parent(marry, dan).
father_of(F, C) :-
man(F),
parent(F, C).
mother_of(M, C) :-
woman(M),
parent(M, C).
son_of(C, F) :-
man(C),
child(C, F).
brother(B, P) :-
man(B),
mother(M, B),
mother(M, P),
father(F, B),
father(F, P).
sister(S, P) :-
woman(S),
mother(M, S),
mother(M, P),
father(F, S),
father(F, P).
grandparent(G, X) :-
parent(G, P),
parent(P, X).
% ???
% grandparent(G, john).
child(A, B) :-
parent(B, A).

Related

How to form list (Father, Mother, ChildrenList)

I was trying to figure out how to get the desired output, I managed to get the desired result but now I want to take it a step further and form a complete list of a family for all parents and children.
So what I have right now is.
parent_children(pam, bob).
parent_children(tom, bob).
parent_children(tom, liz).
parent_children(bob, ann).
parent_children(bob, pat).
parent_children(pam, ann).
parent_children(pat, jim).
parent_children(bob, peter).
parent_children(peter, jim).
female(pam). female(liz). female(ann).
male(tom). male(bob). male(pat). male(jim). male(peter).
age(pam, 40). age(liz, 14). age(ann, 12). age(tom, 20). age(bob, 20). age(pat, 60). age(jim, 16).
father(F, Y) :- parent_children(F, Y), male(F).
mother(M, Y) :- parent_children(M, Y), female(M).
two_parents(F, M, C) :- father(F, C), mother(M, C).
:-dynamic children/1.
family(Father, Mother, _) :-
two_parents(Father, Mother, C),
\+assertz(children(C)),
fail.
family(_, _, Children) :-
extract_children(Children).
extract_children([Y|Children]) :-
retract(children(Y)), !,
extract_names(Children).
extract_names([]).
So the output I'm getting is the following.
family(Pam, Tom, C) C = [bob]
I'm trying to get is
Family = pam, tom, [bob, liz, jim], bob, pam, [ann].

SWI prolog return true instead of variable

here is my code
/*facts*/
male(James).
male(Charles).
male(William).
female(Megan).
male(George).
female(Catherine).
female(Diana).
female(Elizabith).
parent(James,Charles).
parent(James,Elizabeth).
parent(Charles,Catherine).
parent(Charles,William).
parent(Charles,Megan).
parent(Elizabeth,Diana).
parent(Diana,George).
/*rules*/
different(X,Y):- X\=Y.
father(X, Y) :- parent(X,Y), male(X).
mother(X, Y) :- parent(X,Y), female(X).
grandparent(X,Y):- parent(X,F), parent(F,Y).
grandma(X,Y):- parent(X,F), parent(F,Y),female(X).
sister(X,Y):-female(X), parent(F,X), parent(F,Y),different(X,Y) .
brother(X,Y):-male(X), parent(F,X), parent(F,Y),different(X,Y).
aunt(X,Y):-parent(F,Y), sister(X,F), female(X).
uncle(X,Y):-parent(F,Y), brother(X,F), male(X).
i write mother(X,Y). expecting return name not true or false .
same with all statements
Your facts use variables and not constants. Constants and functors start with a lowercase, so james, charles, megan and diana, not James, Charles, Megan and Diana:
male(james).
male(charles).
male(william).
female(megan).
male(george).
female(catherine).
female(diana).
female(elizabith).
parent(james, charles).
parent(james, elizabeth).
parent(charles, catherine).
parent(charles, william).
parent(charles, megan).
parent(elizabeth, diana).
parent(diana, george).

prolog finding first cousins in family

Trying to do a prolog question to find first cousins!
/* first person is parent of second person */
parent(a, b).
parent(b, f).
parent(a, d).
parent(f, g).
parent(a, k).
parent(f, h).
parent(k, l).
parent(f, i).
parent(k, m).
parent(l, t).
parent(b, e).
sibling(X,Y) :- parent(Z,X), parent(Z,Y), not(X=Y).
grandparent(X, Z) :-
parent(X, Y),
parent(Y, Z).
cousin1(Child1,Child2) :-
grandparent(Y1,Child1),
grandparent(Y2,Child2),
not(sibling(Child1,Child2)),
Y1=Y2 .
Seems to be working, but is there a way to stop it from returning true if the same child is input?
EDIT: final answer
cousin1(Child1,Child2) :-
parent(Y1,Child1),
parent(Y2,Child2),
sibling(Y1,Y2).
Final answer!
cousin1(Child1,Child2) :-
parent(Y1,Child1),
parent(Y2,Child2),
sibling(Y1,Y2).
Write a .not-self predicate, which returns false if the children are equal. Add that to your cousin predicate.

Prolog defining a male

So my lecturer wrote this code as an answer to one of a question. Today we found out that the rule male and female are both wrong, can somebody confirm this for me? Also, taking advantage of of this post I would like to ask you kind people if you could send/link me a tutorial explaining prolog in detail, if you could do this it'd be great! Thanks a lot.
/* FACTS */
parents(david, george, noreen).
parents(jennifer, george, noreen).
parents(georgejr, george, noreen).
parents(scott, george, noreen).
parents(joanne, george, noreen).
parents(jessica, david, edel).
parents(clara, david, edel).
parents(michael, david, edel).
parents(laura, georgejr, susan).
parents(anna, scott, siobhan).
parents(edel, mick, peggy).
parents(maria, mick, peggy).
parents(assumpta, mick, peggy).
parents(patrick, kevin, maria).
parents(hugh, kevin, maria).
parents(helena, kevin, maria).
parents(roisin, wim, assumpta).
/* Relationships */
father(X, Y) :- parents(Y, X, _).
male(X) :- father(X, _).
mother(X, Y) :- parents(Y, _, X).
female(X) :- mother(X, _).
grandfather(X, Y) :- father(X, Z), father(Z, Y).
grandfather(X, Y) :- father(X, Z), mother(Z, Y).
grandmother(X, Y) :- mother(X, Z), mother(Z, Y).
grandmother(X, Y) :- mother(X, Z), father(Z, Y).
brother(X, Y) :- male(X), father(Z, X), father(Z, Y), X \== Y.
sister(X, Y) :- female(X), father(Z, X), father(Z, Y), X \== Y.
/* New realtionships */
parent(X,Y) :- father(X,Y); mother(X,Y).
uncle(X,Y) :- parent(Z,Y), brother(X,Z), Z \== X.
aunt(X,Y) :- parent(Z,Y), sister(X,Z), Z \== X.
sibling(X,Y) :- brother(X,Y); sister(X,Y).
cousin(X,Y) :- parent(Z,X), parent(W,Y), sibling(Z,W).

Error in Family Tree using Prolog

I have some issues in my family tree. As required, I need to create predicates on father, mother, son, daughter, grandfather, sibling, aunt, uncle, cousin, spouse, parent_of based on the facts of Male, Female, parent_of.
male(jerry).
male(stuart).
male(warren).
male(peter).
female(kather).
female(maryalice).
female(ann).
brother(jerry,stuart).
brother(jerry,kather).
brother(peter, warren).
sister(ann, maryalice).
sister(kather,jerry).
parent_of(warren,jerry).
parent_of(maryalice,jerry).
father(X,Y) :- male(X), parent_of(X,Y).
mother(X,Y) :- female(X), parent_of(X,Y).
son(X,Y) :- male(X), parent_of(Y,X).
daughter(X,Y) :- female(X), parent_of(Y,X).
grandfather(X,Y) :- father(X,P), parent_of(P,Y).
sibling(X,Y):- parent_of(P,X), parent_of(P,Y), X\=Y.
aunt(X,Y) :- sister(X,P), parent_of(P,Y).
uncle(X,Y) :- brother(X,P), parent_of(P,Y).
cousin(X,Y):- sibling(P,Q), parent_of(P,X), parent_of(Q,Y).
spouse(X,Y) :- parent_of(X,P), parent_of(Y,P).
parent_of(X,Y) :- male(X), father(X,Y); female(X), mother(X,Y).
The parent_of predicate gives me an error. Clasues of parent_of/2 are not together in the source file. When I ignore the error and run a query ?- sibling(jerry, stuart), it gives me an error out of local stack. Anyone know how to solve this problem. Your help will be appreicated. Thanks.
Problem 1
The parent_of predicate gives me an error. Clasues of parent_of/2 are not together in the source file.
Simply place definitions of the predicate right next to eachother
Change
parent_of(warren,jerry).
parent_of(maryalice,jerry).
...
spouse(X,Y) :- parent_of(X,P), parent_of(Y,P).
parent_of(X,Y) :- male(X), father(X,Y); female(X), mother(X,Y).
to
parent_of(warren,jerry).
parent_of(maryalice,jerry).
parent_of(X,Y) :- male(X), father(X,Y); female(X), mother(X,Y).
...
spouse(X,Y) :- parent_of(X,P), parent_of(Y,P).
Problem 2
?- sibling(jerry, stuart), it gives me an error out of local stack.
You have a circular logic error. You define parent_of\2 in terms of father\2 and father\2 in terms of parent_of\2. This will cause each to circle off into Prolog never-never-land.

Resources