<#17892#>Figure: A descendant family tree<#17892#> <#71086#><#63701#><#17940#>(make-parent<#17940#>\ <#17941#>loc<#17941#>\ <#17942#>n<#17942#>\ <#17943#>d<#17943#>\ <#17944#>e)<#17944#><#63701#><#71086#> where <#63702#><#17945#>loc<#17945#><#63702#> is a list of children, <#63703#><#17946#>n<#17946#><#63703#> and <#63704#><#17947#>e<#17947#><#63704#> are symbols, and <#63705#><#17948#>d<#17948#><#63705#> is a number. A <#63706#><#17949#>list of children<#17949#><#63706#> is either
Representing these new kinds of family trees and their nodes in a computer
requires a different class of data than the ancestor family trees. This
time a node must include information about the children instead of the two
parents. Here is a structure definition:
<#17898#>(define-struct<#17898#> <#17899#>parent<#17899#> <#17900#>(children<#17900#> <#17901#>name<#17901#> <#17902#>date<#17902#> <#17903#>eyes))<#17903#>
The last three fields in a parent structure contain the same basic
information as a corresponding child structure, but the contents of the
first one poses an interesting question. Since a parent may have an
arbitrary number of children, the <#63686#><#17907#>children<#17907#><#63686#> field must contain an
undetermined number of nodes, each of which represents one child.
The natural choice is to insist that the <#63687#><#17908#>children<#17908#><#63687#> field always
stands for a list of <#63688#><#17909#>parent<#17909#><#63688#> structures. The list represents the
children; if a person doesn't have children, the list is <#63689#><#17910#>empty<#17910#><#63689#>.
This decision suggests the following data definition:
A <#17912#>parent<#17912#> is a structure:
Unfortunately, this data definition violates our criteria concerning
definitions. In particular, it mentions the name of a collection that is
not yet defined: list of children.
Since it is impossible to define the class of parents without knowing what
a list of children is, let's start from the latter:
<#63690#><#17914#>(make-parent<#17914#>\ <#17915#>loc<#17915#>\ <#17916#>n<#17916#>\ <#17917#>d<#17917#>\ <#17918#>e)<#17918#><#63690#>
where <#63691#><#17920#>loc<#17920#><#63691#> is a list of children,
<#63692#><#17921#>n<#17921#><#63692#> and <#63693#><#17922#>e<#17922#><#63693#> are symbols,
and <#63694#><#17923#>d<#17923#><#63694#> is a number.
A <#17926#>list of children<#17926#> is either
This second definition looks standard, but it suffers from the same problem
as the one for <#63699#><#17936#>parents<#17936#><#63699#>. The unknown class it refers to is that of
the class of parents, which cannot be defined without a definition for the
list of children, and so on.
The conclusion is that the two data definitions refer to each other and are
only meaningful if introduced <#17937#>together<#17937#>:
where <#63697#><#17932#>p<#17932#><#63697#> is a parent
and <#63698#><#17933#>loc<#17933#><#63698#> is a list of children.
A <#63700#><#17939#>parent<#17939#><#63700#> is a structure:
When two (or more) data definitions refer to each other, they are
said to be <#63711#><#17959#>MUTUALLY RECURSIVE<#17959#><#63711#> or <#63712#><#17960#>MUTUALLY REFERENTIAL<#17960#><#63712#>.
Now we can translate the family tree of figure~#figbufamily#17961>
<#17969#>(define<#17969#> <#17970#>Gustav<#17970#> <#17971#>(make-parent<#17971#> <#17972#>empty<#17972#> <#17973#>'<#17973#><#17974#>Gustav<#17974#> <#17975#>1988<#17975#> <#17976#>blush))<#17976#>
<#17977#>(make-parent<#17977#> <#17978#>(list<#17978#> <#17979#>Gustav)<#17979#> <#17980#>'<#17980#><#17981#>Fred<#17981#> <#17982#>1950<#17982#> <#17983#>yellow)<#17983#>
To create a <#63715#><#17987#>parent<#17987#><#63715#> structure for Fred, we first define one for
Gustav so that we can form <#63716#><#17988#>(list<#17988#>\ <#17989#>Gustav)<#17989#><#63716#>, the list of children for
Fred.
Figure~#figbufamilyS#17990><#17997#>;; Youngest Generation:<#17997#>
<#17998#>(define<#17998#> <#17999#>Gustav<#17999#> <#18000#>(make-parent<#18000#> <#18001#>empty<#18001#> <#18002#>'<#18002#><#18003#>Gustav<#18003#> <#18004#>1988<#18004#> <#18005#>blush))<#18005#>
<#18006#>(define<#18006#> <#18007#>Fred&<#18007#><#18008#>Eva<#18008#> <#18009#>(list<#18009#> <#18010#>Gustav))<#18010#>
<#18011#>;; Middle Generation:<#18011#>
<#18012#>(define<#18012#> <#18013#>Adam<#18013#> <#18014#>(make-parent<#18014#> <#18015#>empty<#18015#> <#18016#>'<#18016#><#18017#>Adam<#18017#> <#18018#>1950<#18018#> <#18019#>yellow))<#18019#>
<#18020#>(define<#18020#> <#18021#>Dave<#18021#> <#18022#>(make-parent<#18022#> <#18023#>empty<#18023#> <#18024#>'<#18024#><#18025#>Dave<#18025#> <#18026#>1955<#18026#> <#18027#>black))<#18027#>
<#18028#>(define<#18028#> <#18029#>Eva<#18029#> <#18030#>(make-parent<#18030#> <#18031#>Fred&<#18031#><#18032#>Eva<#18032#> <#18033#>'<#18033#><#18034#>Eva<#18034#> <#18035#>1965<#18035#> <#18036#>blue))<#18036#>
<#18037#>(define<#18037#> <#18038#>Fred<#18038#> <#18039#>(make-parent<#18039#> <#18040#>Fred&<#18040#><#18041#>Eva<#18041#> <#18042#>'<#18042#><#18043#>Fred<#18043#> <#18044#>1966<#18044#> <#18045#>pink))<#18045#>
<#18046#>(define<#18046#> <#18047#>Carl&<#18047#><#18048#>Bettina<#18048#> <#18049#>(list<#18049#> <#18050#>Adam<#18050#> <#18051#>Dave<#18051#> <#18052#>Eva))<#18052#>
<#18053#>;; Oldest Generation:<#18053#>
<#18054#>(define<#18054#> <#18055#>Carl<#18055#> <#18056#>(make-parent<#18056#> <#18057#>Carl&<#18057#><#18058#>Bettina<#18058#> <#18059#>'<#18059#><#18060#>Carl<#18060#> <#18061#>1926<#18061#> <#18062#>green))<#18062#>
<#18063#>(define<#18063#> <#18064#>Bettina<#18064#> <#18065#>(make-parent<#18065#> <#18066#>Carl&<#18066#><#18067#>Bettina<#18067#> <#18068#>'<#18068#><#18069#>Bettina<#18069#> <#18070#>1926<#18070#> <#18071#>green))<#18071#>
<#18075#>Figure: A Scheme representation of the descendant family tree<#18075#>
Let us now study the development of <#63717#><#18077#>blue-eyed-descendant?<#18077#><#63717#>, the
natural companion of <#63718#><#18078#>blue-eyed-ancestor?<#18078#><#63718#>. It consumes a
<#63719#><#18079#>parent<#18079#><#63719#> structure and determines whether it or any of its
descendants have blue eyes.
<#71087#>;; <#63720#><#18084#>blue-eyed-descendant?<#18084#> <#18085#>:<#18085#> <#18086#>ftn<#18086#> <#18087#><#18087#><#18088#>-;SPMgt;<#18088#><#18089#><#18089#> <#18090#>boolean<#18090#><#63720#><#71087#>
<#71088#>;; to determine whether <#63721#><#18091#>a-parent<#18091#><#63721#> or any of its descendants (children, <#71088#>
<#71089#>;; grandchildren, and so on) have <#63722#><#18092#>'<#18092#><#18093#>blue<#18093#><#63722#> in the <#63723#><#18094#>eyes<#18094#><#63723#> field<#71089#>
<#18095#>(define<#18095#> <#18096#>(blue-eyed-descendant?<#18096#> <#18097#>a-parent)<#18097#> <#18098#>...)<#18098#>
Here are three simple examples:
<#18106#>(blue-eyed-descendant?<#18106#> <#18107#>Gustav)<#18107#>
<#18108#>=<#18108#> <#18109#>false<#18109#>
<#18117#>(blue-eyed-descendant?<#18117#> <#18118#>Eva)<#18118#>
<#18119#>=<#18119#> <#18120#>true<#18120#>
<#18128#>(blue-eyed-descendant?<#18128#> <#18129#>Bettina)<#18129#>
<#18130#>=<#18130#> <#18131#>true<#18131#>
A glance at figure~#figbufamily#18135><#18141#>(d<#18141#><#18142#>efine<#18142#> <#18143#>(blue-eyed-descendant?<#18143#> <#18144#>a-parent)<#18144#>
<#18145#>...<#18145#> <#18146#>(parent-children<#18146#> <#18147#>a-parent)<#18147#> <#18148#>...<#18148#>
<#18149#>...<#18149#> <#18150#>(parent-name<#18150#> <#18151#>a-parent)<#18151#> <#18152#>...<#18152#>
<#18153#>...<#18153#> <#18154#>(parent-date<#18154#> <#18155#>a-parent)<#18155#> <#18156#>...<#18156#>
<#18157#>...<#18157#> <#18158#>(parent-eyes<#18158#> <#18159#>a-parent)<#18159#> <#18160#>...<#18160#> <#18161#>)<#18161#>
The structure definition for <#63725#><#18165#>parent<#18165#><#63725#> specifies four fields so there
are four expressions.
The expressions in the template remind us that the eye color of the parent
is available and can be checked. Hence, we add a <#63726#><#18166#>cond<#18166#>-expression<#63726#>
that compares <#63727#><#18167#>(parent-eyes<#18167#>\ <#18168#>a-parent)<#18168#><#63727#> to <#63728#><#18169#>'<#18169#><#18170#>blue<#18170#><#63728#>:
<#18175#>(d<#18175#><#18176#>efine<#18176#> <#18177#>(blue-eyed-descendant?<#18177#> <#18178#>a-parent)<#18178#>
<#18179#>(c<#18179#><#18180#>ond<#18180#>
<#18181#>[<#18181#><#18182#>(symbol=?<#18182#> <#18183#>(parent-eyes<#18183#> <#18184#>a-parent)<#18184#> <#18185#>'<#18185#><#18186#>blue)<#18186#> <#18187#>true<#18187#><#18188#>]<#18188#>
<#18189#>[<#18189#><#18190#>e<#18190#><#18191#>lse<#18191#>
<#18192#>...<#18192#> <#18193#>(parent-children<#18193#> <#18194#>a-parent)<#18194#> <#18195#>...<#18195#>
<#18196#>...<#18196#> <#18197#>(parent-name<#18197#> <#18198#>a-parent)<#18198#> <#18199#>...<#18199#>
<#18200#>...<#18200#> <#18201#>(parent-date<#18201#> <#18202#>a-parent)<#18202#> <#18203#>...]<#18203#><#18204#>))<#18204#>
The answer is obviously <#63729#><#18208#>true<#18208#><#63729#> if the condition holds. The
<#63730#><#18209#>else<#18209#><#63730#> clause contains the remaining expressions. Of course, the
<#63731#><#18210#>name<#18210#><#63731#> and <#63732#><#18211#>date<#18211#><#63732#> field have nothing to do with the eye color
of a person, so we can ignore them. This leaves us with
<#18216#>(parent-children<#18216#> <#18217#>a-parent)<#18217#>
an expression that extracts the list of children from the <#63733#><#18221#>parent<#18221#><#63733#>
structure.
If the eye color of some <#63734#><#18222#>parent<#18222#><#63734#> structure is not <#63735#><#18223#>'<#18223#><#18224#>blue<#18224#><#63735#>,
we must clearly search the list of children for a blue-eyed descendant.
Following our guidelines for complex functions, we add the function to our
wish list and continue from there. The function that we want to put on a
wish list consumes a list of children and checks whether any of these or
their grandchildren have blue eyes. Here are the contract, header, and
purpose statement:
<#71090#>;; <#63736#><#18229#>blue-eyed-children?<#18229#> <#18230#>:<#18230#> <#18231#>list-of-children<#18231#> <#18232#><#18232#><#18233#>-;SPMgt;<#18233#><#18234#><#18234#> <#18235#>boolean<#18235#><#63736#><#71090#>
<#71091#>;; to determine whether any of the structures on <#63737#><#18236#>aloc<#18236#><#63737#> is blue-eyed<#71091#>
<#18237#>;; or has any blue-eyed descendant<#18237#>
<#18238#>(define<#18238#> <#18239#>(blue-eyed-children?<#18239#> <#18240#>aloc)<#18240#> <#18241#>...)<#18241#>
Using <#63738#><#18245#>blue-eyed-children?<#18245#><#63738#> we can complete the definition of
<#63739#><#18246#>blue-eyed-descendant?<#18246#><#63739#>:
<#18251#>(d<#18251#><#18252#>efine<#18252#> <#18253#>(blue-eyed-descendant?<#18253#> <#18254#>a-parent)<#18254#>
<#18255#>(c<#18255#><#18256#>ond<#18256#>
<#18257#>[<#18257#><#18258#>(symbol=?<#18258#> <#18259#>(parent-eyes<#18259#> <#18260#>a-parent)<#18260#> <#18261#>'<#18261#><#18262#>blue)<#18262#> <#18263#>true<#18263#><#18264#>]<#18264#>
<#18265#>[<#18265#><#18266#>else<#18266#> <#18267#>(blue-eyed-children?<#18267#> <#18268#>(parent-children<#18268#> <#18269#>a-parent))]<#18269#><#18270#>))<#18270#>
That is, if <#63740#><#18274#>a-parent<#18274#><#63740#> doesn't have blue eyes, we just look through
the list of its children.
Before we can test <#63741#><#18275#>blue-eyed-descendant?<#18275#><#63741#>, we must define the
function on our wish list. To make up examples for
<#63742#><#18276#>blue-eyed-children?<#18276#><#63742#>, we use the list-of-children definitions in
figure~#figbufamilyS#18277> <#18282#>(blue-eyed-children?<#18282#> <#18283#>(list<#18283#> <#18284#>Gustav))<#18284#>
<#18285#>=<#18285#> <#18286#>false<#18286#>
<#18294#>(blue-eyed-children?<#18294#> <#18295#>(list<#18295#> <#18296#>Adam<#18296#> <#18297#>Dave<#18297#> <#18298#>Eva))<#18298#>
<#18299#>=<#18299#> <#18300#>true<#18300#>
Gustav doesn't have blue eyes and doesn't have any recorded descendants.
Hence, <#63743#><#18304#>blue-eyed-children?<#18304#><#63743#> produces <#63744#><#18305#>false<#18305#><#63744#> for <#63745#><#18306#>(list<#18306#><#18307#> <#18307#><#18308#>Gustav)<#18308#><#63745#>. In contrast, <#63746#><#18309#>Eva<#18309#><#63746#> has blue eyes, and therefore
<#63747#><#18310#>blue-eyed-children?<#18310#><#63747#> produces <#63748#><#18311#>true<#18311#><#63748#> for the second list of
children.
Since the input for <#63749#><#18312#>blue-eyed-children?<#18312#><#63749#> is a list, the template is
the standard pattern:
<#18317#>(d<#18317#><#18318#>efine<#18318#> <#18319#>(blue-eyed-children?<#18319#> <#18320#>aloc)<#18320#>
<#18321#>(c<#18321#><#18322#>ond<#18322#>
<#18323#>[<#18323#><#18324#>(empty?<#18324#> <#18325#>aloc)<#18325#> <#18326#>...]<#18326#>
<#18327#>[<#18327#><#18328#>e<#18328#><#18329#>lse<#18329#>
<#18330#>...<#18330#> <#18331#>(first<#18331#> <#18332#>aloc)<#18332#> <#18333#>...<#18333#>
<#18334#>...<#18334#> <#18335#>(blue-eyed-children?<#18335#> <#18336#>(rest<#18336#> <#18337#>aloc))<#18337#> <#18338#>...]<#18338#><#18339#>))<#18339#>
Next we consider the two cases. If <#63750#><#18343#>blue-eyed-children?<#18343#><#63750#>'s input is
<#63751#><#18344#>empty<#18344#><#63751#>, the answer is <#63752#><#18345#>false<#18345#><#63752#>. Otherwise we have two
expressions:
Fortunately we already have a function that determines whether a
<#63757#><#18355#>parent<#18355#><#63757#> structure or any of its descendants has blue eyes:
<#63758#><#18356#>blue-eyed-descendant?<#18356#><#63758#>. This suggests that we check whether
<#18361#>(blue-eyed-descendant?<#18361#> <#18362#>(first<#18362#> <#18363#>aloc))<#18363#>
holds and, if so, <#63759#><#18367#>blue-eyed-children?<#18367#><#63759#> can produce <#63760#><#18368#>true<#18368#><#63760#>. If
not, the second expression determines whether we have more luck with the
rest of the list.
Figure~#figblueeyesbu#18369><#71092#>;; <#63766#><#18379#>blue-eyed-descendant?<#18379#> <#18380#>:<#18380#> <#18381#>ftn<#18381#> <#18382#><#18382#><#18383#>-;SPMgt;<#18383#><#18384#><#18384#> <#18385#>boolean<#18385#><#63766#><#71092#>
<#71093#>;; to determine whether <#63767#><#18386#>a-parent<#18386#><#63767#> any of the descendants (children, <#71093#>
<#71094#>;; grandchildren, and so on) have <#63768#><#18387#>'<#18387#><#18388#>blue<#18388#><#63768#> in the <#63769#><#18389#>eyes<#18389#><#63769#> field<#71094#>
<#18390#>(d<#18390#><#18391#>efine<#18391#> <#18392#>(blue-eyed-descendant?<#18392#> <#18393#>a-parent)<#18393#>
<#18394#>(c<#18394#><#18395#>ond<#18395#>
<#18396#>[<#18396#><#18397#>(symbol=?<#18397#> <#18398#>(parent-eyes<#18398#> <#18399#>a-parent)<#18399#> <#18400#>'<#18400#><#18401#>blue)<#18401#> <#18402#>true<#18402#><#18403#>]<#18403#>
<#18404#>[<#18404#><#18405#>else<#18405#> <#18406#>(blue-eyed-children?<#18406#> <#18407#>(parent-children<#18407#> <#18408#>a-parent))]<#18408#><#18409#>))<#18409#>
<#71095#>;; <#63770#><#18410#>blue-eyed-children?<#18410#> <#18411#>:<#18411#> <#18412#>list-of-children<#18412#> <#18413#><#18413#><#18414#>-;SPMgt;<#18414#><#18415#><#18415#> <#18416#>boolean<#18416#><#63770#><#71095#>
<#71096#>;; to determine whether any of the structures in <#63771#><#18417#>aloc<#18417#><#63771#> is blue-eyed<#71096#>
<#18418#>;; or has any blue-eyed descendant<#18418#>
<#18419#>(d<#18419#><#18420#>efine<#18420#> <#18421#>(blue-eyed-children?<#18421#> <#18422#>aloc)<#18422#>
<#18423#>(c<#18423#><#18424#>ond<#18424#>
<#18425#>[<#18425#><#18426#>(empty?<#18426#> <#18427#>aloc)<#18427#> <#18428#>false<#18428#><#18429#>]<#18429#>
<#18430#>[<#18430#><#18431#>e<#18431#><#18432#>lse<#18432#>
<#18433#>(c<#18433#><#18434#>ond<#18434#>
<#18435#>[<#18435#><#18436#>(blue-eyed-descendant?<#18436#> <#18437#>(first<#18437#> <#18438#>aloc))<#18438#> <#18439#>true<#18439#><#18440#>]<#18440#>
<#18441#>[<#18441#><#18442#>else<#18442#> <#18443#>(blue-eyed-children?<#18443#> <#18444#>(rest<#18444#> <#18445#>aloc))]<#18445#><#18446#>)]<#18446#><#18447#>))<#18447#>
<#71097#>;; <#63772#><#18455#>blue-eyed-descendant?<#18455#> <#18456#>:<#18456#> <#18457#>ftn<#18457#> <#18458#><#18458#><#18459#>-;SPMgt;<#18459#><#18460#><#18460#> <#18461#>boolean<#18461#><#63772#><#71097#>
<#71098#>;; to determine whether <#63773#><#18462#>a-parent<#18462#><#63773#> any of the descendants (children, <#71098#>
<#71099#>;; grandchildren, and so on) have <#63774#><#18463#>'<#18463#><#18464#>blue<#18464#><#63774#> in the <#63775#><#18465#>eyes<#18465#><#63775#> field<#71099#>
<#18466#>(d<#18466#><#18467#>efine<#18467#> <#18468#>(blue-eyed-descendant?<#18468#> <#18469#>a-parent)<#18469#>
<#18470#>(or<#18470#> <#18471#>(symbol=?<#18471#> <#18472#>(parent-eyes<#18472#> <#18473#>a-parent)<#18473#> <#18474#>'<#18474#><#18475#>blue)<#18475#>
<#18476#>(blue-eyed-children?<#18476#> <#18477#>(parent-children<#18477#> <#18478#>a-parent))))<#18478#>
<#71100#>;; <#63776#><#18479#>blue-eyed-children?<#18479#> <#18480#>:<#18480#> <#18481#>list-of-children<#18481#> <#18482#><#18482#><#18483#>-;SPMgt;<#18483#><#18484#><#18484#> <#18485#>boolean<#18485#><#63776#><#71100#>
<#71101#>;; to determine whether any of the structures in <#63777#><#18486#>aloc<#18486#><#63777#> is blue-eyed<#71101#>
<#18487#>;; or has any blue-eyed descendant<#18487#>
<#18488#>(d<#18488#><#18489#>efine<#18489#> <#18490#>(blue-eyed-children?<#18490#> <#18491#>aloc)<#18491#>
<#18492#>(c<#18492#><#18493#>ond<#18493#>
<#18494#>[<#18494#><#18495#>(empty?<#18495#> <#18496#>aloc)<#18496#> <#18497#>false<#18497#><#18498#>]<#18498#>
<#18499#>[<#18499#><#18500#>else<#18500#> <#18501#>(or<#18501#> <#18502#>(blue-eyed-descendant?<#18502#> <#18503#>(first<#18503#> <#18504#>aloc))<#18504#>
<#18505#>(blue-eyed-children?<#18505#> <#18506#>(rest<#18506#> <#18507#>aloc)))]<#18507#><#18508#>))<#18508#>
<#18512#>Figure: Two programs for finding a blue-eyed descendants<#18512#>
<#18516#>Exercise 15.1.1<#18516#>
<#18560#>(append<#18560#> <#18561#>(list<#18561#> <#18562#>'<#18562#><#18563#>a<#18563#> <#18564#>'<#18564#><#18565#>b<#18565#> <#18566#>'<#18566#><#18567#>c)<#18567#> <#18568#>(list<#18568#> <#18569#>'<#18569#><#18570#>d<#18570#> <#18571#>'<#18571#><#18572#>e))<#18572#>
<#18573#>=<#18573#> <#18574#>(list<#18574#> <#18575#>'<#18575#><#18576#>a<#18576#> <#18577#>'<#18577#><#18578#>b<#18578#> <#18579#>'<#18579#><#18580#>c<#18580#> <#18581#>'<#18581#><#18582#>d<#18582#> <#18583#>'<#18583#><#18584#>e)<#18584#>
We will discuss the development of functions like <#63794#><#18588#>append<#18588#><#63794#> in the
last section of this part.~ Solution<#63795#><#63795#>