Family relations

The SDB language is particularly suited to compactly representing knowledge such as family relations. In this example we will do it in two parts. The first defines a specific family tree, and the second part a general set of operators that apply to any family tree. We start with this sample family tree:

|context> => |family tree>

mother |sally> => |trude>
father |sally> => |tom>
age |sally> => |16>

mother |erica> => |trude>
father |erica> => |tom>
age |erica> => |12>

mother |trude> => |sara>
father |trude> => |sam>
husband |trude> => |tom>
daughter |trude> => |sally> + |erica>
age |trude> => |38>

mother |peter> => |ruth>
father |peter> => |mike>
age |peter> => |26>

mother |tom> => |ruth>
father |tom> => |mike>
wife |tom> => |trude>
daughter |tom> => |sally> + |erica>
age |tom> => |40>

husband |sara> => |sam>
daughter |sara> => |trude>
age |sara> => |56>

wife |sam> => |sara>
daughter |sam> => |trude>
age |sam> => |56>

mother |ruth> => |gina>
husband |ruth> => |mike>
son |ruth> => |tom> + |peter>
age |ruth> => |57>

mother |mike> => |mary>
father |mike> => |mark>
wife |mike> => |ruth>
son |mike> => |tom> + |peter>
age |mike> => |60>

daughter |gina> => |ruth>
age |gina> => |76>

husband |mary> => |mark>
son |mary> => |mike>
age |mary> => |76>

wife |mark> => |mary>
son |mark> => |mike>
age |mark> => |78>        

Which using graphviz and the dot language becomes: family tree

Next, we define a collection of operators that apply to traversing family trees in general. The intent is that you define a specific family tree with a small subset of operators defined, and then load the family-relations.sw3 file to reason with that family tree.

-- Family relations operators:
-- Given only operators for: mother, father, son, daughter, wife, husband, age
-- We can construct the following collection of family related operators:
-- updated to the version 3.1.1 language


-- define our not operator:
not |yes> => |no>
not |no> => |yes>
not |don't know> => |don't know>


child |*> #=> (son + daughter) |_self>
parent |*> #=> (mother + father) |_self>
sibling |*> #=> drop (clean child parent + -1) |_self>
brother |*> #=> drop (clean son parent + -1) |_self>
sister |*> #=> drop (clean daughter parent + -1) |_self>
brother-and-sister |*> #=> sibling |_self>

half-brother |*> #=> drop son (mother + -1 father) |_self> + drop son (father + -1 mother) |_self>
half-sister |*> #=> drop daughter (mother + -1 father) |_self> + drop daughter (father + -1 mother) |_self>


grand-parent |*> #=> parent parent |_self>
grand-mother |*> #=> mother parent |_self>
grand-father |*> #=> father parent |_self>
grand-child |*> #=> child child |_self>
grand-son |*> #=> son child |_self>
grand-daughter |*> #=> daughter child |_self>
great-grand-child |*> #=> child child child |_self>
great-grand-son |*> #=> son child child |_self>
great-grand-daughter |*> #=> daughter child child |_self>
great-grand-parent |*> #=> parent parent parent |_self>
great-grand-mother |*> #=> mother parent parent |_self>
great-grand-father |*> #=> father parent parent |_self>

uncle |*> #=> brother parent |_self> 
aunt |*> #=> sister parent |_self>
aunt-and-uncle |*> #=> (aunt + uncle) |_self>
great-uncle |*> #=> brother grand-parent |_self>
great-aunt |*> #=> sister grand-parent |_self>
great-aunt-and-uncle |*> #=> (great-aunt + great-uncle) |_self>

cousin |*> #=> clean child aunt-and-uncle |_self>
niece |*> #=> daughter brother-and-sister |_self>
nephew |*> #=> son brother-and-sister |_self>

brother-in-law |*> #=> (brother wife + brother husband + husband sister) |_self>
sister-in-law |*> #=> (sister wife + sister husband + wife brother) |_self>
mother-in-law |*> #=> mother (wife + husband) |_self>
father-in-law |*> #=> father (wife + husband) |_self>
spouse |*> #=> (wife + husband) |_self>
is-married |*> #=> do-you-know spouse |_self>
is-not-married |*> #=> not do-you-know spouse |_self>



-- now a collection of is-a-x rules:
is-a-father |*> #=> is-mbr(|_self>) clean father child |_self>
is-a-mother |*> #=> is-mbr(|_self>) clean mother child |_self>
is-a-parent |*> #=> do-you-know child |_self>
is-a-son |*> #=> is-mbr(|_self>) clean son parent |_self>
is-a-daughter |*> #=> is-mbr(|_self>) clean daughter parent |_self>

is-a-grand-mother |*> #=> is-mbr(|_self>) clean mother parent child^2 |_self>
is-a-grand-father |*> #=> is-mbr(|_self>) clean father parent child^2 |_self>
is-a-grand-parent |*> #=> do-you-know child^2 |_self>

is-a-great-grand-mother |*> #=> is-mbr(|_self>) clean mother parent^2 child^3 |_self>
is-a-great-grand-father |*> #=> is-mbr(|_self>) clean father parent^2 child^3 |_self>
is-a-great-grand-parent |*> #=> do-you-know child^3 |_self>

is-a-male |*> #=> is-a-son |_self> || is-a-father |_self>
is-a-female |*> #=> is-a-daughter |_self> || is-a-mother |_self>

is-an-uncle |*> #=> is-a-male |_self> && do-you-know child sibling |_self>
is-an-aunt |*> #=> is-a-female |_self> && do-you-know child sibling |_self>

is-a-husband |*> #=> is-a-male |_self> && do-you-know wife |_self>
is-a-wife |*> #=> is-a-female |_self> && do-you-know husband |_self>

is-a-brother |*> #=> is-a-male |_self> && do-you-know sibling |_self>
is-a-sister |*> #=> is-a-female |_self> && do-you-know sibling |_self>


-- define some is-a-x rules that require knowledge of age:
is-a-child |*> #=> is-in-range[0,17] age |_self>
is-a-teenager |*> #=> is-in-range[13,19] age |_self>
is-an-adult |*> #=> not is-in-range[0,17] age |_self>
is-a-man |*> #=> is-a-male |_self> && is-an-adult |_self>
is-a-woman |*> #=> is-a-female |_self> && is-an-adult |_self>
is-a-boy |*> #=> is-a-male |_self> && not is-an-adult |_self>
is-a-girl |*> #=> is-a-female |_self> && not is-an-adult |_self>
is-male-or-female |*> #=> is-a-male |_self> || is-a-female |_self>

is-a-senior-citizen |*> #=> not is-in-range[0,59] age |_self>


-- now a collection of have-a-x rules:
have-a-child |*> #=> do-you-know child |_self>
have-a-brother |*> #=> do-you-know brother |_self>
have-a-sister |*> #=> do-you-know sister |_self>
have-a-wife |*> #=> do-you-know wife |_self>
have-a-husband |*> #=> do-you-know husband |_self>
have-an-uncle |*> #=> do-you-know uncle |_self>
have-an-aunt |*> #=> do-you-know aunt |_self>
have-a-cousin |*> #=> do-you-know cousin |_self>
have-a-niece |*> #=> do-you-know niece |_self>
have-a-nephew |*> #=> do-you-know nephew |_self>


-- now a collection of how-many rules:
how-many-children |*> #=> how-many child |_self>
how-many-grand-children |*> #=> how-many child^2 |_self>
how-many-great-grand-children |*> #=> how-many child^3 |_self>
how-many-brothers |*> #=> how-many brother |_self>
how-many-sisters |*> #=> how-many sister |_self>
how-many-uncles |*> #=> how-many uncle |_self>
how-many-aunts |*> #=> how-many aunt |_self>
how-many-cousins |*> #=> how-many cousin |_self>
how-many-nieces |*> #=> how-many niece |_self>
how-many-nephews |*> #=> how-many nephew |_self>


-- some more rules about number of children:
have-1-child |*> #=> is-equal[1] how-many-children |_self>
have-2-children |*> #=> is-equal[2] how-many-children |_self>
have-3-children |*> #=> is-equal[3] how-many-children |_self>
have-4-children |*> #=> is-equal[4] how-many-children |_self>

Now, we load both files into the SDB shell, and then we can ask some simple questions about the loaded knowledge:

$ ./SDB3_1 -iq family-tree.sw3 family-relations.sw3

Welcome to the Semantic DB version 3.1.1 shell.
Last updated 18th June 2021.
Type h for help.
Online info for the SDB language at http://semantic-db.org/docs/usage3/

sa: sister |sally>
|erica>

sa: grand-mother |sally>
|sara> + |ruth>

sa: age grand-mother |sally>
|56> + |57>

sa: great-grand-father |sally>
|mark>

sa: age great-grand-father |sally>
|78>

sa: aunt |sally>
|>

sa: uncle |sally>
|peter>

sa: is-an-uncle |peter>
|yes>

sa: age uncle |sally>
|26>

sa: is-married |sally>
|no>

sa: is-married |ruth>
|yes>

sa: grand-child |ruth>
|sally> + |erica>

sa:

Or we could just display a table with some chosen operators:

sa: table[person, mother, father, age, sister, brother, grand-mother, grand-father, is-a-female, is-a-male] such-that[is-male-or-female] rel-kets[*]
+--------+--------+--------+-----+--------+---------+--------------+--------------+-------------+-----------+
| person | mother | father | age | sister | brother | grand-mother | grand-father | is-a-female | is-a-male |
+--------+--------+--------+-----+--------+---------+--------------+--------------+-------------+-----------+
| sally  | trude  | tom    | 16  | erica  |         | sara + ruth  | sam + mike   | yes         | no        |
| erica  | trude  | tom    | 12  | sally  |         | sara + ruth  | sam + mike   | yes         | no        |
| trude  | sara   | sam    | 38  |        |         |              |              | yes         | no        |
| peter  | ruth   | mike   | 26  |        | tom     | gina + mary  | mark         | no          | yes       |
| tom    | ruth   | mike   | 40  |        | peter   | gina + mary  | mark         | no          | yes       |
| sara   |        |        | 56  |        |         |              |              | yes         | no        |
| sam    |        |        | 56  |        |         |              |              | no          | yes       |
| ruth   | gina   |        | 57  |        |         |              |              | yes         | no        |
| mike   | mary   | mark   | 60  |        |         |              |              | no          | yes       |
| gina   |        |        | 76  |        |         |              |              | yes         | no        |
| mary   |        |        | 76  |        |         |              |              | yes         | no        |
| mark   |        |        | 78  |        |         |              |              | no          | yes       |
+--------+--------+--------+-----+--------+---------+--------------+--------------+-------------+-----------+
|table>

where we have filtered the output of rel-kets[*] to kets that are male or female, ie, people, using the such-that[is-male-or-female] operator. Otherwise our table would include a couple of kets that are not people. Note that the blanks in the table correspond to operators that return the empty ket when applied to the given ket/person.

Raw files here and here.