[I7] Family Relations

I’m trying to create a system by which people are related to other people based on their familial connections. This worked out well for a while, but after introducing Uncleship, it doesn’t quite work. That is, the uncles don’t quite list all their nephews and the nephews don’t list the uncles. I have a good idea why this is happening, but it seems like its gonna take a good bit of seemingly redundant code in my ‘calculate relations’ function. I was wondering if anyone has any advice/tips/shortcuts. I looked in the Public Library, and I didn’t see this functionality. If there is already an extension for it, that’d be great. Pretty much any help is appreciated. Anyways, here’s the code:

[code]Marriage relates one person (called spouse) to another.
The verb to be married to means the marriage relation.

Paternity relates various people to various people.
The verb to be the parent of means the paternity relation.
The verb to be the child of means the reversed paternity relation.

Fraternity relates people to each other in groups.
The verb to be siblings with means the fraternity relation.

Grandpaternity relates various people to various people.
The verb to be the grandparent of means the grandpaternity relation.
The verb to be the grandchild of means the reversed grandpaternity relation.

Cousinship relates people to each other in groups.
The verb to be cousins with means the cousinship relation.

Uncleship relates various people to various people.
The verb to be the uncle of means the uncleship relation.
The verb to be the nephew of means the reversed uncleship relation.

Definition: A person is married rather than single if their spouse is a person.

Workspace is a room.

Kelsey is a woman in Workspace.
Alex is a man in Workspace.

Kelsey is the child of Catherine.
Stanton is the child of Kelsey.
Catherine is the child of Frances.
Stuart is the child of Frances.
Richard is the child of Frances.
Debbie is married to Richard.
Kelsey is the child of Chuck.
Kelsey is married to Alex.
Dale is married to Miriam.
Carl is siblings with Dale.
Alex is the child of Dale.
Travis is the child of Dale.
Stephen is siblings with Travis.
Alex, Stuart, Richard, Dale, Stephen and Travis are men.
Kelsey, Catherine, and Debbie are women.

When play begins:
calculate relatives;
repeat with John running through people:
say “[bold type][John][roman type]:[line break]”;
say “Spouse: [spouse of John][line break]”;
say “Parents: [list of people who are the parent of John][line break]”;
say “Children: [list of people who are the child of John][line break]”;
say “Sisters: [list of women who are siblings with John][line break]”;
say “Brothers: [list of men who are siblings with John][line break]”;
say “Grandparents: [list of people who are the grandparent of John][line break]”;
say “Grandchildren: [list of people who are the grandchild of John][line break]”;
say “Aunts: [list of women who are the uncle of John][line break]”;
say “Uncles: [list of men who are the uncle of John][line break]”;
say “Nieces: [list of women who are the nephew of John][line break]”;
say “Nephews: [list of men who are the nephew of John][line break]”;
say paragraph break;

To calculate relatives:
repeat with John running through people:
if John is married to someone (called the parent):
now every person who is the child of John is the child of the parent;
if John is the parent of someone (called the child):
now every person who is the child of John is siblings with the child;
repeat with John running through people:
if John is married to someone (called the parent):
now every person who is the child of John is the child of the parent;
if John is the parent of someone (called the child):
now every person who is the child of John is siblings with the child;
repeat with grandpa running through people who are the parent of John:
now grandpa is the grandparent of every person who is the child of John;
repeat with unky running through people who are siblings with John:
if unky is not John:
now unky is the uncle of every person who is the child of John;[/code]

Rather than updating the relations like that at compile time, I would recommend using conditional relations. Read about those in section 13.12. Define a few relationships like you are now, and then the rest will automatically get set. I think I’d make marriage and maternity be the primary relations and then define paternity, siblings, grandparents/children, cousins, uncles, aunties, nephews and nieces from those two primary relations.

Dannii is right about the general strategy that is more likely to work, rather than trying to manage all these relationships separately. For the specific problem you’re having now: What’s missing? I noticed that Carl isn’t set to be a man or a woman, so he isn’t getting printed in your summaries during When play begins. Also, avuncular relationships aren’t traced through marriage; that appears to be intentional (and it would not be easy to fix). The only arguable bug I noticed is that Stephen didn’t get Dale and Miriam as parents; you need a phrase like “now every person who is siblings with John is the child of every person who is the parent of John” in your loop to fix that.

But seriously, use conditional relations. Your life will be much, much easier.

I found my Family Tree in my harddrives that might be interest to you; it’s in Prolog and I did this a long long time ago. This is a small and simplified version of the original code (the real thing is too complicated to paste here).


male(Shridhar).
male(Sanjeev).
male(Rajeev).
male(Vivek).
male(Ashu).
male(Pavas).
male(Naman).
male(Pranav).

female(Mithilesh).
female(Archana).
female(Aradhana).
female(Sandhya).
female(Shweta).
female(Priyanka).

parent(Shridhar, Vivek).
parent(Shridhar, Rajeev)
parent(Shridhar, Sanjeev).
parent(Mithilesh, Vivek).
parent(Mithilesh, Rajeev).
parent(Mithilesh, Sanjeev).

parent(Vivek, Naman).
parent(Vivek, Pranav).

parent(Rajeev, Ashu).
parent(Rajeev, Priyanka).
parent(Rajeev, Shweta).

parent(Sanjeev, Pavas).


father(X, Y) :- parent(X, Y), male(X).
mother(X, Y) :- parent(X, Y), female(X).
son(X, Y) :- parent(Y, X), male(X).
daughter(X, Y) :- parent(Y, X), female(X).
grandfather(X, Y) :- father(Z, Y), father(X, Z).
grandmother(X, Y) :- father(Z, Y), mother(X, Z).
brother(X, Y) :- mother(Z, X),"mother(Z, Y), male(X).
paternal_uncle(X,Y) :- father(Z, Y), brother(Z, Y).
....

If you don’t know Prolog, male(Naman) means ,in super-simpified terms, that Naman is male; father(Vivek, Naman) is “Vivek is father of Naman”; father(X, Y) :- parent(X, Y), male(X). means that “X is father of Y if X is parent of Y and X is male”. The above code is pretty simple but you can make it as complicated as you want (mothers_bother_friends_sons_daughter(X, Y) :- …) I guess you have an working idea now.

Veering off-topic: Naman, you might get a kick out of the second half of this lightening talk, which uses an elaborate set of [admittedly heterocentric and binarist] Prolog conditions to sort out the relationships in a comedic song about being one’s own grandfather:
youtube.com/watch?v=Q663XyxmGUk starting at 5:20 (and at “All right. Second example” in the transcript).

First thing I’ll do after posting this reply is find that song :slight_smile:
Thanks for the pointer