4
votes

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.

1
One issue I see is that your rule for niece doesn't enforce gender. You should be more specific about what you mean by, This rule currently doesn't work. Since a niece is female, I would have expected something a little different. Also, sameparent(X,Y) could be true if X and Y have the same father and the same mother, or just he same mother but not the same father, or just the same mother. Is that what you intended? As far as how the rules work, the comma (,) is like AND. Also, married(X,Y), married(X,Y). is redundant.lurker
I actually believe i figured it out with this: niece(X,Y) :- female(X), sameparent(Y,F), parent(F,X).user3068177
I'm still a little suspicious that the rule for sameparent i asymmetrical, unless that's how you intend he definition of sameparent.lurker
Assuming the sets of fathers and mothers are disjoint, not(samefather(X,Y)) in the 2nd clause of sameparent will always succeed as X is instatiated by a mother. So this call can be deleted.migfilg

1 Answers

2
votes

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).