# Homework #4

Due: Mon, Aug 14, 23:59

## How to Submit

• Submit one solution per team (each team can have 1–3 members), through TEACH. Put the names and ONID IDs of all team members as a comment at the top of the file.

• Your submission should consist of one file named `familyTree.<your-username>.pl`, where is the ONID ID of the team member who submitted the file.

• These files must compile without errors in GHCi. Put all non-working parts of your solution in comments! If your file does not compile, the TA will not evaluate it.

• If you can’t solve a problem, you can get partial credit by describing in comments what you tried and where you got stuck.

• Late submissions will not be accepted. Do not send solutions by email.

## Description

In this assignment, you will be working with Prolog to define predicates for building family relations. I have provided some basic predicates in the template below to get you started: `female/1`, `male/1`, `married/2`, and `parent/2`. The template uses these basic predicates to encode the following family tree (which you will use to test your own definitions).

Template: familyTree.template.pl

### Part 1

For each predicate I have provided some example queries and the unifiers (solutions) that should be produced, or `false` if no unifier exists. It is not important what order the unifiers are produced in, and it is OK if a unifier is produced more than once. However, for all queries, all valid unifiers should eventually be produced, no invalid unifiers should be produced, and the query should not induce an infinite loop.

1. Define a predicate `child/2` that inverts the parent relationship.
``````    ?- child(meg,X).
X = lois ;
X = peter .

?- child(X,lois).
X = chris ;
X = meg ;
X = stewie .``````
1. Define two predicates `isMother/1` and `isFather/1`.
``````    ?- isMother(lois).
true .

?- isMother(meg).
false .

?- isFather(X).
X = carter ;
X = frances ;
X = mickey ;
X = peter .``````
1. Define a predicate `grandparent/2`.
``````    ?- grandparent(carter,X).
X = chris ;
X = meg ;
X = stewie ;
X = carolBaby .

?- grandparent(X,carolBaby).
X = babs ;
X = carter .``````
1. Define a predicate `sibling/2`. Siblings share at least one parent.
``````    ?- sibling(lois,X).
X = carol ;
X = patrick .

?- sibling(X,stewie).
X = chris ;
X = meg .``````
1. Define two predicates `brother/2` and `sister/2`.
``````    ?- brother(chris,X).
X = meg ;
X = stewie .

?- brother(X,chris).
X = stewie .

?- sister(meg,X).
X = chris ;
X = stewie .

?- sister(X,meg).
false .``````
1. Define a predicate `siblingInLaw/2`. A sibling-in-law is either married to a sibling or the sibling of a spouse.
``````    ?- siblingInLaw(carol,X).
X = peter .

?- siblingInLaw(patrick,X).
X = peter .

?- siblingInLaw(X,peter).
X = carol ;
X = patrick .``````
1. Define two predicates `aunt/2` and `uncle/2`. Your definitions of these predicates should include aunts and uncles by marriage.
``````    ?- aunt(carol,X).
X = chris ;
X = meg ;
X = stewie .

?- uncle(X,carolBaby).
X = patrick ;
X = peter .``````
1. Define the predicate `cousin/2`.
``````    ?- cousin(meg,X).
X = carolBaby .

?- cousin(X,carolBaby).
X = chris ;
X = meg ;
X = stewie .``````
1. Define the predicate `ancestor/2`.
``````    ?- ancestor(carter,X).
X = carol ;
X = lois ;
X = patrick ;
X = chris ;
X = meg ;
X = stewie ;
X = carolBaby .

?- ancestor(X,stewie).
X = lois ;
X = peter ;
X = babs ;
X = carter ;
X = mickey ;
X = thelma .``````

### Bonus Problems

1. Define the predicate `related/2`. This predicate should be true for any two people connected by a family tree, no matter how distantly. Therefore, a query such as `related(peter,X)` should enumerate every other person in the tree.

The challenge in this problem is structuring your predicate in a way that enumerates all members of the tree and doesn’t infinitely loop. You may want to use a helper predicate