6.18 Example: A Database¶
This example shows how you can use FriCAS to organize a database of lineage data and then query the database for relationships.
The database is entered as assertions that are really pieces of a function definition.
children("albert") == ["albertJr","richard","diane"]
Type: Void
Each piece children(x)==y means the children of x are y.
children("richard") == ["douglas","daniel","susan"]
Type: Void
This family tree thus spans four generations.
children("douglas") == ["dougie","valerie"]
Type: Void
Say no one else has children.
children(x) == []
Type: Void
We need some functions for computing lineage. Start with childOf.
childOf(x,y) == member?(x,children(y))
Type: Void
To find the parentOf someone, you have to scan the database of people applying children.
parentOf(x) ==
for y in people repeat
(if childOf(x,y) then return y)
"unknown"
Type: Void
And a grandparent of x is just a parent of a parent of x.
grandParentOf(x) == parentOf parentOf x
Type: Void
The grandchildren of x are the people y such that x is a grandparent of y.
grandchildren(x) == [y for y in people | grandParentOf(y) = x]
Type: Void
Suppose you want to make a list of all great-grandparents. Well, a great-grandparent is a grandparent of a person who has children.
greatGrandParents == [x for x in people |
reduce(_or,
[not empty? children(y) for y in grandchildren(x)],false)]
Type: Void
Define descendants to include the parent as well.
descendants(x) ==
kids := children(x)
null kids => [x]
concat(x,reduce(concat,[descendants(y)
for y in kids],[]))
Type: Void
Finally, we need a list of people. Since all people are descendants of albert, let’s say so.
people == descendants "albert"
Type: Void
We have used == to define the database and some functions to query the database. But no computation is done until we ask for some information. Then, once and for all, the functions are analyzed and compiled to machine code for run-time efficiency. Notice that no types are given anywhere in this example. They are not needed.
Who are the grandchildren of richard?
grandchildren "richard"
Compiling function children with type String -> List String
Compiling function descendants with type String -> List String
Compiling body of rule people to compute value of type List String
Compiling function childOf with type (String,String) -> Boolean
Compiling function parentOf with type String -> String
Compiling function grandParentOf with type String -> String
Compiling function grandchildren with type String -> List String
[“dougie”,”valerie”] |
Type: List String
Who are the great-grandparents?
greatGrandParents
Compiling body of rule greatGrandParents to compute value of
type List String
[“albert”] |
Type: List String