user3068177
user3068177

Reputation: 357

Creating a Niece Rule in Prolog

Using a family database, I need to create a niece rule (niece(X,Y))in swi-prolog which is defined as "X is a niece of Y if X is a daughter of Y's brother or sister." This is the given database with my already designed rules:

% family DB

grandfather(don,who).

father(don,ted).
father(don,barb).
father(don,paula).
father(greg,erin).
father(greg,austin).
father(wes,alyssa).
father(ted,jessica).
father(ted,david).
%mother(ted, john).

mother(audrey,ted).
mother(audrey,barb).
mother(audrey,paula).
mother(paula,erin).
mother(paula,austin).
mother(barb,alyssa).

married(don,audrey).
married(wes,barb).
married(greg,paula).

male(don).
male(ted).
male(wes).
male(greg).
male(austin).
male(david).

female(audrey).
female(barb).
female(paula).
female(alyssa).
female(jessica).
female(erin).

parent(X,Y) :-
    father(X,Y)
  ; mother(X,Y).

grandfather(X,Y) :-
   father(X,Z),
   (  father(Z,Y)
   ;  mother(Z,Y)
   ).

samefather(X,Y) :- 
   father(F,X),
   father(F,Y).

samemother(X,Y) :- 
   mother(M,X),
   mother(M,Y).

sameparent(X,Y) :-
   samefather(X,Y).
sameparent(X,Y) :-
   samemother(X,Y),
   not(samefather(X,Y)).

couple(X,Y) :- 
   married(X,Y),
   married(X,Y).

Here is my initial try at the niece rule:

niece(X,Y) :-
   parent(F,X),
   sameparent(Y,F).

My idea is to use the sameparent rule to check if Y and F are siblings and then check if F is the parent of X. This rule currently doesn't work. I'm still struggling to understand the syntax of combining multiple rules. If anyone could help me by using this same logic, it would be greatly appreciated.

Upvotes: 4

Views: 2245

Answers (2)

For me it worked well.

sameparent(X,Y):- parent(A,X),parent(A,Y).

niece(X,Y) :- female(X),parent(Z,X),sameparent(Z,Y),Z=Y.

Upvotes: 0

Rafalon
Rafalon

Reputation: 4515

Removing unnecessary rules :

parent(don,ted).
parent(don,barb).
parent(don,paula).
parent(greg,erin).
parent(greg,austin).
parent(wes,alyssa).
parent(ted,jessica).
parent(ted,david).

parent(audrey,ted).
parent(audrey,barb).
parent(audrey,paula).
parent(paula,erin).
parent(paula,austin).
parent(barb,alyssa).

male(don).
male(ted).
male(wes).
male(greg).
male(austin).
male(david).

female(audrey).
female(barb).
female(paula).
female(alyssa).
female(jessica).
female(erin).

father(X,Y) :-
    male(X),
    parent(X,Y).

mother(X,Y) :-
    female(X),
    parent(X,Y).

sameparent(X,Y) :-
   parent(A,X),
   parent(A,Y).

Gives you :

niece(X,Y) :-
    female(X),
    parent(Z,X),
    sameparent(Z,Y),
    Z \= Y.

Meaning line by line :

  • X is a niece of Y if
  • X is a female and
  • one parent of X
  • has a parent in common with Y
  • who isn't himself/herself.

This gives you :

| ?- niece(X,Y).

X = alyssa
Y = ted;

X = alyssa
Y = paula;

X = jessica
Y = barb;

X = jessica
Y = paula;

X = erin
Y = ted;

X = erin
Y = barb

Twice because in the case of your database every brothers/sisters share the same two parents.

For example, if A is the daughter of B and B is the half-brother of C, A is still the niece of C.


If you want that rule to be false and A to be the niece of C only if B and C are brothers/sisters (and not only half), you can change the niece rule to the following :

sameFather(X,Y) :-
    father(A,X),
    father(A,Y).

sameMother(X,Y) :-
    mother(A,X),
    mother(A,Y).

niece(X,Y) :-
    female(X),
    parent(Z,X),
    sameFather(Z,Y),
    sameMother(Z,Y),
    Z \= Y.

Then you won't get duplicate results whith niece(X,Y).

Upvotes: 2

Related Questions