CPSC 322 - Homework Assignment 1 - September 17, 2004

CPSC 322 - Homework Assignment 1

Possible Solutions


Problem 1:

Here's how to compute the number of different interpretations

D = {Charles', William', Harry'}

phi(charles) = Charles' or William' or Harry'         3 choices
phi(william) = William' or Harry' or Charles'         3 
phi(harry) = Harry' or Charles' or William'           3

pi(male)(Charles') = T or F                           2
pi(male)(William') = T or F                           2
pi(male)(Harry') = T or F                             2

pi(parent)(Charles',Charles') = T or F                2
pi(parent)(Charles',William') = T or F                2
pi(parent)(Charles',Harry') = T or F                  2
pi(parent)(William',Charles') = T or F                2
pi(parent)(William',William') = T or F                2
pi(parent)(William',Harry') = T or F                  2
pi(parent)(Harry',Charles') = T or F                  2
pi(parent)(Harry',William') = T or F                  2
pi(parent)(Harry',Harry') = T or F                    2

pi(brother)(Charles',Charles') = T or F               2
pi(brother)(Charles',William') = T or F               2
pi(brother)(Charles',Harry') = T or F                 2
pi(brother)(William',Charles') = T or F               2
pi(brother)(William',William') = T or F               2
pi(brother)(William',Harry') = T or F                 2
pi(brother)(Harry',Charles') = T or F                 2
pi(brother)(Harry',William') = T or F                 2
pi(brother)(Harry',Harry') = T or F                   2

Multiplying all the choices together, we get:
3x3x3x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2 = 56,623,104

There were some students who interpreted the definition
of the phi function on p. 32 of the textbook as meaning that there
is a one-to-one mapping between the constants and the elements of 
D.  It's a reasonable assumption...why have an element in D that 
has no associated constant?  So even though the definition on 
p. 32 says only that every constant must map onto an element of D,
not that every element of D must be mapped onto from some 
constant, we're going to give credit for answers based on that
assumption as well.  The math is just a little bit different,
and the possible choices for phi work out to 3x2x1 instead of 3x3x3, 
giving the following:
3x2x1x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2x2 = 12,582,912

-----------------------------------------------------------------------

Problem 2:

There are really two parts to this problem.  The first part 
involves constructing a family tree that, at a minimum, explicitly 
represents the information given in the diagram.  So there needs 
to be some basic relation (I used "parent" in class and in my 
solution, but students could do something else) which is used to
repeatedly relate all the names in the family tree.  The net 
result is a tree-like data structure built in the knowledge base
via a series of ground facts that look like (but not necessarily
exactly like) "parent(elizabeth,charles"  where "parent" is the
basic relation mentioned above.  There shouldn't be any cycles.

The second part involves the writing of the following 19 
relations:

  parent, mother, father, grandparent, grandmother, grandfather,
  child, daughter, son, grandchild, granddaughter, grandson,
  aunt, uncle, firstcousin, sisterinlaw, brotherinlaw,
  descendant, ancestor

Here's my solution, but it's not necessarily what yours
should look like:

/* the basic family tree */

male(william).
male(harry).
male(peter).
female(zara).
female(beatrice).
female(eugenie).
female(louise).
female(diana).
male(charles).
female(anne).
male(mark).
male(andrew).
female(sarah).
male(edward).
female(sophie).
female(elizabeth).
male(philip).
female(margaret).
male(george).
female(mum).
parent(george,elizabeth).
parent(mum,elizabeth).
parent(george,margaret).
parent(mum,margaret).
parent(elizabeth,charles).
parent(elizabeth,anne).
parent(elizabeth,andrew).
parent(elizabeth,edward).
parent(philip,charles).
parent(philip,anne).
parent(philip,andrew).
parent(philip,edward).
parent(diana,william).
parent(diana,harry).
parent(charles,william).
parent(charles,harry).
parent(anne,peter).
parent(anne,zara).
parent(mark,peter).
parent(mark,zara).
parent(andrew,beatrice).
parent(andrew,eugenie).
parent(sarah,beatrice).
parent(sarah,eugenie).
parent(edward,louise).
parent(sophie,louise).

/* helpful relations for aunts, uncles, and in-laws */
/* As I worked on this, I decided I wanted a "married" predicate,
and I wanted the married relation to be a two-way thing.
But I wanted to avoid the cycles caused by saying something like
   married(X,Y) <- married(Y,X).
So I decided on two one-way marriage predicates, married_fm
(married-female-to-male) and married_mf (married-male-to-female).
Then I wrote all the ...fm's explicitly, wrote a rule to take
care of the ...mf's, and then built my two-way married relationship
on top of that.  Other solutions are possible; your mileage may
vary.  Please note that not including relationships like 
married_mm and married_ff is not intended as either judgment or
commentary on how anyone should live their lives.  It's merely
a reflection of how the Royal Family members live their lives...
at least in public. ;) 
*/

married_fm(diana,charles).
married_fm(anne,mark).
married_fm(sarah,andrew).
married_fm(sophie,edward).
married_fm(elizabeth,philip).
married_fm(mum,george).
married_mf(X,Y) <- married_fm(Y,X).
married(X,Y) <- married_fm(X,Y).
married(X,Y) <- married_mf(X,Y).

different(X,Y) <- X \= Y.

sibling(X,Y) <- parent(Z,Y) & parent(Z,X) & different(X,Y).
brother(X,Y) <- male(X) & sibling(X,Y).
sister(X,Y) <- female(X) & sibling(X,Y).

/* mother */
mother(X,Y) <- female(X) & parent(X,Y).

/* father */
father(X,Y) <- male(X) & parent(X,Y).

/* grandparent */
grandparent(X,Y) <- parent(X,Z) & parent(Z,Y).

/* grandmother */
grandmother(X,Y) <- female(X) & grandparent(X,Y).

/* grandfather */
grandfather(X,Y) <- male(X) & grandparent(X,Y).

/* child */
child(X,Y) <- parent(Y,X).

/* daughter */
daughter(X,Y) <- female(X) & child(X,Y).

/* son */
son(X,Y) <- male(X) & child(X,Y).

/* grandchild */
grandchild(X,Y) <- child(X,Z) & child(Z,Y).

/* granddaughter */
granddaughter(X,Y) <- female(X) & grandchild(X,Y).

/* grandson */
grandson(X,Y) <- male(X) & grandchild(X,Y).

/* aunt */
aunt(X,Y) <- sister(X,Z) & parent(Z,Y).
aunt(X,Y) <- female(X) & married(X,A) & sibling(A,B) & parent(B,Y).

/* uncle */
uncle(X,Y) <- brother(X,Z) & parent(Z,Y).
uncle(X,Y) <- male(X) & married(X,A) & sibling(A,B) & parent(B,Y).

/* firstcousin */
firstcousin(X,Y) <- parent(A,X) & parent(B,Y) & sibling(A,B).

/* sisterinlaw */
sisterinlaw(X,Y) <- female(X) & married(X,Z) & sibling(Z,Y).
sisterinlaw(X,Y) <- female(X) & sibling(X,Z) & married(Z,Y).
sisterinlaw(X,Y) <- female(X) & married(X,Z) & sibling(Z,Q) & married(Q,Y).

/* brotherinlaw */
brotherinlaw(X,Y) <- male(X) & married(X,Z) & sibling(Z,Y).
brotherinlaw(X,Y) <- male(X) & sibling(X,Z) & married(Z,Y).
brotherinlaw(X,Y) <- male(X) & married(X,Z) & sibling(Z,Q) & married(Q,Y).

/* descendant */
descendant(X,Y) <- child(X,Z) & descendant(Z,Y).
descendant(X,Y) <- child(X,Y).

/* ancestor */
ancestor(X,Y) <- parent(X,Z) & ancestor(Z,Y).
ancestor(X,Y) <- parent(X,Y).

-----------------------------------------------------------------------

Problem 3:

/* For this one I started with my solution to Problem 2,
deleted the royal family tree, and inserted the very
weird family not-really-a-tree from the story. */

/* the unusual family tree and poorly-defined relations 
   needed to make the thing work */

married_fm(widow,me).
parent(widow,d).
male(me).
female(widow).
female(d).
parent(f,me).
male(f).
married_fm(d,f).
parent(me,s1).
parent(widow,s1).
male(s1).
parent(f,s2).
parent(d,s2).
male(s2).

/* Then, keeping all the family relationships I defined for
problem 2, I added these.  They represent explicitly the 
loosening-up of the traditional parental relations as they're
defined for problem 2.  For example, X is the father of Y if
X is male and X is a parent of Y.  But the author of the 
story in problem 3 throws up a verbal smokescreen and turns
stepfathers into fathers and that sort of thing.  So the first
rule below says that, in addition to the existing definition of
fatherhood, X is the father of Y if X is male and X is married
to a parent of Y.  It's that sort of thing that makes it possible
to argue that one can be one's own grandfather. */

father(X,Y) <- male(X) & married(X,Z) & parent(Z,Y).
soninlaw(X,Y) <- male(X) & married(X,Z) & father(Y,Z).
mother(X,Y) <- female(X) & married(X,Z) & parent(Z,Y).
uncle(X,Y) <- brother(X,Z) & father(Z,Y).
uncle(X,Y) <- brother(X,Z) & mother(Z,Y).
uncle(X,Y) <- male(X) & married(X,A) & sibling(A,B) & father(B,Y).
uncle(X,Y) <- male(X) & married(X,A) & sibling(A,B) & mother(B,Y).
grandfather(X,Y) <- father(X,Z) & mother(Z,Y).
grandfather(X,Y) <- father(X,Z) & father(Z,Y).

/* the rest of this is just copied from the solution for 
   problem 2, whether it's needed or not */

/* helpful relations for aunts, uncles, and in-laws */
married_mf(X,Y) <- married_fm(Y,X).
married(X,Y) <- married_fm(X,Y).
married(X,Y) <- married_mf(X,Y).

/* and so on.... */

Last revised: October 2, 2004