<#42182#>(define-struct<#42182#> <#42183#>child<#42183#> <#42184#>(father<#42184#> <#42185#>mother<#42185#> <#42186#>name<#42186#> <#42187#>date<#42187#> <#42188#>eyes))<#42188#>
A <#67727#><#42193#>node in a family tree<#42193#><#67727#> (short: <#67728#><#42194#>ftn<#42194#><#67728#>) is either
- <#67729#><#42196#>empty<#42196#><#67729#>, or
- <#67730#><#42197#>(make-child<#42197#>\ <#42198#>f<#42198#>\ <#42199#>m<#42199#>\ <#42200#>na<#42200#>\ <#42201#>da<#42201#>\ <#42202#>ec)<#42202#><#67730#> where <#67731#><#42203#>f<#42203#><#67731#> and <#67732#><#42204#>m<#42204#><#67732#> are <#67733#><#42205#>ftn<#42205#><#67733#>s, <#67734#><#42206#>na<#42206#><#67734#> and <#67735#><#42207#>ec<#42207#><#67735#> are symbols, and <#67736#><#42208#>da<#42208#><#67736#> is a number.
<#71662#>;; <#67737#><#42215#>all-blue-eyed-ancestors<#42215#> <#42216#>:<#42216#> <#42217#>ftn<#42217#> <#42218#><#42218#><#42219#>-;SPMgt;<#42219#><#42220#><#42220#> <#42221#>(listof<#42221#> <#42222#>symbol)<#42222#><#67737#><#71662#>
<#71663#>;; to construct a list of all blue-eyed ancestors in <#67738#><#42223#>a-ftree<#42223#><#67738#><#71663#>
<#42224#>(d<#42224#><#42225#>efine<#42225#> <#42226#>(all-blue-eyed-ancestors<#42226#> <#42227#>a-ftree)<#42227#>
<#42228#>(c<#42228#><#42229#>ond<#42229#>
<#42230#>[<#42230#><#42231#>(empty?<#42231#> <#42232#>a-ftree)<#42232#> <#42233#>empty]<#42233#>
<#42234#>[<#42234#><#42235#>else<#42235#> <#42236#>(l<#42236#><#42237#>ocal<#42237#> <#42238#>((d<#42238#><#42239#>efine<#42239#> <#42240#>in-parents<#42240#>
<#42241#>(append<#42241#> <#42242#>(all-blue-eyed-ancestors<#42242#> <#42243#>(child-father<#42243#> <#42244#>a-ftree))<#42244#>
<#42245#>(all-blue-eyed-ancestors<#42245#> <#42246#>(child-mother<#42246#> <#42247#>a-ftree)))))<#42247#>
<#42248#>(c<#42248#><#42249#>ond<#42249#>
<#42250#>[<#42250#><#42251#>(symbol=?<#42251#> <#42252#>(child-eyes<#42252#> <#42253#>a-ftree)<#42253#> <#42254#>'<#42254#><#42255#>blue)<#42255#>
<#42256#>(cons<#42256#> <#42257#>(child-name<#42257#> <#42258#>a-ftree)<#42258#> <#42259#>in-parents)]<#42259#>
<#42260#>[<#42260#><#42261#>else<#42261#> <#42262#>in-parents]<#42262#><#42263#>))]<#42263#><#42264#>))<#42264#>
<#67739#>Figure: Collecting family trees with <#42268#>blue-eyed-ancestor?<#42268#><#67739#>
<#71664#>;; <#67744#><#42279#>all-blue-eyed-ancestors<#42279#> <#42280#>:<#42280#> <#42281#>ftn<#42281#> <#42282#><#42282#><#42283#>-;SPMgt;<#42283#><#42284#><#42284#> <#42285#>(listof<#42285#> <#42286#>symbol)<#42286#><#67744#><#71664#>
<#71665#>;; to construct a list of all blue-eyed ancestors in <#67745#><#42287#>a-ftree<#42287#><#67745#><#71665#>
<#42288#>(d<#42288#><#42289#>efine<#42289#> <#42290#>(all-blue-eyed-ancestors<#42290#> <#42291#>a-ftree0)<#42291#>
<#42292#>(l<#42292#><#42293#>ocal<#42293#> <#42294#>(<#42294#><#71666#>;; <#67746#><#42295#>accumulator<#42295#><#67746#> ...<#71666#>
<#42296#>(d<#42296#><#42297#>efine<#42297#> <#42298#>(all-a<#42298#> <#42299#>a-ftree<#42299#> <#42300#>accumulator)<#42300#>
<#42301#>(c<#42301#><#42302#>ond<#42302#>
<#42303#>[<#42303#><#42304#>(empty?<#42304#> <#42305#>a-ftree)<#42305#> <#42306#>...]<#42306#>
<#42307#>[<#42307#><#42308#>else<#42308#>
<#42309#>(l<#42309#><#42310#>ocal<#42310#> <#42311#>((d<#42311#><#42312#>efine<#42312#> <#42313#>in-parents<#42313#>
<#42314#>(all-a<#42314#> <#42315#>...<#42315#> <#42316#>(child-father<#42316#> <#42317#>a-ftree)<#42317#> <#42318#>...<#42318#>
<#42319#>...<#42319#> <#42320#>accumulator<#42320#> <#42321#>...)<#42321#>
<#42322#>(all-a<#42322#> <#42323#>...<#42323#> <#42324#>(child-mother<#42324#> <#42325#>a-ftree)<#42325#> <#42326#>...<#42326#>
<#42327#>...<#42327#> <#42328#>accumulator<#42328#> <#42329#>...)))<#42329#>
<#42330#>(c<#42330#><#42331#>ond<#42331#>
<#42332#>[<#42332#><#42333#>(symbol=?<#42333#> <#42334#>(child-eyes<#42334#> <#42335#>a-ftree)<#42335#> <#42336#>'<#42336#><#42337#>blue)<#42337#>
<#42338#>(cons<#42338#> <#42339#>(child-name<#42339#> <#42340#>a-ftree)<#42340#> <#42341#>in-parents)]<#42341#>
<#42342#>[<#42342#><#42343#>else<#42343#> <#42344#>in-parents]<#42344#><#42345#>))]<#42345#><#42346#>)))<#42346#>
<#42347#>(all-a<#42347#> <#42348#>a-ftree0<#42348#> <#42349#>...)))<#42349#>
Our next goal is the formulation of an accumulator invariant. The general
purpose of the accumulator is to remember knowledge about <#67747#><#42353#>a-ftree0<#42353#><#67747#>
that <#67748#><#42354#>all-a<#42354#><#67748#> loses as it traverses the tree. A look at the
definition in figure~#figblueeyesrecall#42355><#71667#>;; <#67758#><#42372#>accumulator<#42372#><#67758#> is the list of blue-eyed ancestors<#71667#> <#42373#>;; encountered on the mother-side trees of the path in<#42373#> <#71668#>;; <#67759#><#42374#>a-ftree0<#42374#><#67759#> to <#67760#><#42375#>a-ftree<#42375#><#67760#><#71668#>To maintain the invariant for the natural recursion, we must collect the ancestors on the mother's side of the tree. Since the purpose of <#67761#><#42379#>all-a<#42379#><#67761#> is to collect those ancestors, we use the expression
<#42384#>(all-a<#42384#> <#42385#>(child-mother<#42385#> <#42386#>a-ftree)<#42386#> <#42387#>accumulator)<#42387#>to compute the new accumulator for the application of <#67762#><#42391#>all-a<#42391#><#67762#> to <#67763#><#42392#>(child-father<#42392#>\ <#42393#>a-ftree)<#42393#><#67763#>. Putting everything together for the second <#67764#><#42394#>cond<#42394#><#67764#>-clause yields this:
<#42399#>(l<#42399#><#42400#>ocal<#42400#> <#42401#>((d<#42401#><#42402#>efine<#42402#> <#42403#>in-parents<#42403#>
<#42404#>(a<#42404#><#42405#>ll-a<#42405#> <#42406#>(child-father<#42406#> <#42407#>a-ftree)<#42407#>
<#42408#>(a<#42408#><#42409#>ll-a<#42409#> <#42410#>(child-mother<#42410#> <#42411#>a-ftree)<#42411#>
<#42412#>accumulator))))<#42412#>
<#42413#>(c<#42413#><#42414#>ond<#42414#>
<#42415#>[<#42415#><#42416#>(symbol=?<#42416#> <#42417#>(child-eyes<#42417#> <#42418#>a-ftree)<#42418#> <#42419#>'<#42419#><#42420#>blue)<#42420#>
<#42421#>(cons<#42421#> <#42422#>(child-name<#42422#> <#42423#>a-ftree)<#42423#> <#42424#>in-parents)]<#42424#>
<#42425#>[<#42425#><#42426#>else<#42426#> <#42427#>in-parents]<#42427#><#42428#>))<#42428#>
This leaves us with the answer in the first <#67765#><#42432#>cond<#42432#><#67765#>-clause. Since
<#67766#><#42433#>accumulator<#42433#><#67766#> represents all blue-eyed ancestors encountered so far,
it is the result. Figure~#figblueeyesaccu1#42434><#71669#>;; <#67767#><#42439#>all-blue-eyed-ancestors<#42439#> <#42440#>:<#42440#> <#42441#>ftn<#42441#> <#42442#><#42442#><#42443#>-;SPMgt;<#42443#><#42444#><#42444#> <#42445#>(listof<#42445#> <#42446#>symbol)<#42446#><#67767#><#71669#>
<#71670#>;; to construct a list of all blue-eyed ancestors in <#67768#><#42447#>a-ftree<#42447#><#67768#><#71670#>
<#42448#>(d<#42448#><#42449#>efine<#42449#> <#42450#>(all-blue-eyed-ancestors<#42450#> <#42451#>a-ftree)<#42451#>
<#42452#>(l<#42452#><#42453#>ocal<#42453#> <#42454#>(<#42454#><#71671#>;; <#67769#><#42455#>accumulator<#42455#><#67769#> is the list of blue-eyed ancestors<#71671#>
<#42456#>;; encountered on the mother-side trees of the path in<#42456#>
<#71672#>;; <#67770#><#42457#>a-ftree0<#42457#><#67770#> to <#67771#><#42458#>a-ftree<#42458#><#67771#><#71672#>
<#42459#>(d<#42459#><#42460#>efine<#42460#> <#42461#>(all-a<#42461#> <#42462#>a-ftree<#42462#> <#42463#>accumulator)<#42463#>
<#42464#>(c<#42464#><#42465#>ond<#42465#>
<#42466#>[<#42466#><#42467#>(empty?<#42467#> <#42468#>a-ftree)<#42468#> <#42469#>accumulator]<#42469#>
<#42470#>[<#42470#><#42471#>else<#42471#>
<#42472#>(l<#42472#><#42473#>ocal<#42473#> <#42474#>((d<#42474#><#42475#>efine<#42475#> <#42476#>in-parents<#42476#>
<#42477#>(all-a<#42477#> <#42478#>(child-father<#42478#> <#42479#>a-ftree)<#42479#>
<#42480#>(all-a<#42480#> <#42481#>(child-mother<#42481#> <#42482#>a-ftree)<#42482#> <#42483#>accumulator))))<#42483#>
<#42484#>(c<#42484#><#42485#>ond<#42485#>
<#42486#>[<#42486#><#42487#>(symbol=?<#42487#> <#42488#>(child-eyes<#42488#> <#42489#>a-ftree)<#42489#> <#42490#>'<#42490#><#42491#>blue)<#42491#>
<#42492#>(cons<#42492#> <#42493#>(child-name<#42493#> <#42494#>a-ftree)<#42494#> <#42495#>in-parents)]<#42495#>
<#42496#>[<#42496#><#42497#>else<#42497#> <#42498#>in-parents]<#42498#><#42499#>))]<#42499#><#42500#>)))<#42500#>
<#42501#>(all-a<#42501#> <#42502#>a-ftree<#42502#> <#42503#>empty)))<#42503#>
<#42507#>Figure: Collecting blue-eyed ancestors, accumulator-style (version 1)<#42507#>
<#71673#>;; <#67773#><#42514#>todo<#42514#><#67773#> is the list of family trees <#71673#> <#42515#>;; encountered but not processed <#42515#>Like the accumulator-style <#67774#><#42519#>reverse<#42519#><#67774#>, <#67775#><#42520#>all-a<#42520#><#67775#> initializes <#67776#><#42521#>todo<#42521#><#67776#> to <#67777#><#42522#>empty<#42522#><#67777#>. It updates it by extending the list for the natural recursion:
<#42527#>(l<#42527#><#42528#>ocal<#42528#> <#42529#>((d<#42529#><#42530#>efine<#42530#> <#42531#>in-parents<#42531#>
<#42532#>(a<#42532#><#42533#>ll-a<#42533#> <#42534#>(child-father<#42534#> <#42535#>a-ftree)<#42535#>
<#42536#>(cons<#42536#> <#42537#>(child-mother<#42537#> <#42538#>a-ftree)<#42538#> <#42539#>todo))))<#42539#>
<#42540#>(c<#42540#><#42541#>ond<#42541#>
<#42542#>[<#42542#><#42543#>(symbol=?<#42543#> <#42544#>(child-eyes<#42544#> <#42545#>a-ftree)<#42545#> <#42546#>'<#42546#><#42547#>blue)<#42547#>
<#42548#>(cons<#42548#> <#42549#>(child-name<#42549#> <#42550#>a-ftree)<#42550#> <#42551#>in-parents)]<#42551#>
<#42552#>[<#42552#><#42553#>else<#42553#> <#42554#>in-parents]<#42554#><#42555#>))<#42555#>
The problem now is that when <#67778#><#42559#>all-a<#42559#><#67778#> is applied to the
<#67779#><#42560#>empty<#42560#><#67779#> tree, <#67780#><#42561#>todo<#42561#><#67780#> does not represent the result but what
is left to do for <#67781#><#42562#>all-a<#42562#><#67781#>. To visit all those family trees,
<#67782#><#42563#>all-a<#42563#><#67782#> must be applied to them, one at a time. Of course, if
<#67783#><#42564#>todo<#42564#><#67783#> is <#67784#><#42565#>empty<#42565#><#67784#>, there is nothing left to do; the result is
<#67785#><#42566#>empty<#42566#><#67785#>. If <#67786#><#42567#>todo<#42567#><#67786#> is a list, we pick the first tree on the
list as the next one to be processed:
<#42572#>(c<#42572#><#42573#>ond<#42573#> <#42574#>[<#42574#><#42575#>(empty?<#42575#> <#42576#>todo)<#42576#> <#42577#>empty]<#42577#> <#42578#>[<#42578#><#42579#>else<#42579#> <#42580#>(all-a<#42580#> <#42581#>(first<#42581#> <#42582#>todo)<#42582#> <#42583#>(rest<#42583#> <#42584#>todo))]<#42584#><#42585#>)<#42585#>The rest of the list is what is now left to do.
<#71674#>;; <#67787#><#42593#>all-blue-eyed-ancestors<#42593#> <#42594#>:<#42594#> <#42595#>ftn<#42595#> <#42596#><#42596#><#42597#>-;SPMgt;<#42597#><#42598#><#42598#> <#42599#>(listof<#42599#> <#42600#>symbol)<#42600#><#67787#><#71674#>
<#71675#>;; to construct a list of all blue-eyed ancestors in <#67788#><#42601#>a-ftree<#42601#><#67788#><#71675#>
<#42602#>(d<#42602#><#42603#>efine<#42603#> <#42604#>(all-blue-eyed-ancestors<#42604#> <#42605#>a-ftree0)<#42605#>
<#42606#>(l<#42606#><#42607#>ocal<#42607#> <#42608#>(<#42608#><#71676#>;; <#67789#><#42609#>todo<#42609#><#67789#> is the list of family trees encountered but not processed <#71676#>
<#42610#>(d<#42610#><#42611#>efine<#42611#> <#42612#>(all-a<#42612#> <#42613#>a-ftree<#42613#> <#42614#>todo)<#42614#>
<#42615#>(c<#42615#><#42616#>ond<#42616#>
<#42617#>[<#42617#><#42618#>(empty?<#42618#> <#42619#>a-ftree)<#42619#>
<#42620#>(c<#42620#><#42621#>ond<#42621#>
<#42622#>[<#42622#><#42623#>(empty?<#42623#> <#42624#>todo)<#42624#> <#42625#>empty]<#42625#>
<#42626#>[<#42626#><#42627#>else<#42627#> <#42628#>(all-a<#42628#> <#42629#>(first<#42629#> <#42630#>todo)<#42630#> <#42631#>(rest<#42631#> <#42632#>todo))]<#42632#><#42633#>)]<#42633#>
<#42634#>[<#42634#><#42635#>else<#42635#>
<#42636#>(l<#42636#><#42637#>ocal<#42637#> <#42638#>((d<#42638#><#42639#>efine<#42639#> <#42640#>in-parents<#42640#>
<#42641#>(all-a<#42641#> <#42642#>(child-father<#42642#> <#42643#>a-ftree)<#42643#>
<#42644#>(cons<#42644#> <#42645#>(child-mother<#42645#> <#42646#>a-ftree)<#42646#> <#42647#>todo))))<#42647#>
<#42648#>(c<#42648#><#42649#>ond<#42649#>
<#42650#>[<#42650#><#42651#>(symbol=?<#42651#> <#42652#>(child-eyes<#42652#> <#42653#>a-ftree)<#42653#> <#42654#>'<#42654#><#42655#>blue)<#42655#>
<#42656#>(cons<#42656#> <#42657#>(child-name<#42657#> <#42658#>a-ftree)<#42658#> <#42659#>in-parents)]<#42659#>
<#42660#>[<#42660#><#42661#>else<#42661#> <#42662#>in-parents]<#42662#><#42663#>))]<#42663#><#42664#>)))<#42664#>
<#42665#>(all-a<#42665#> <#42666#>a-ftree0<#42666#> <#42667#>empty)))<#42667#>
<#42671#>Figure: Collecting blue-eyed ancestors, accumulator-style (version 2)<#42671#>
The subset contains only three kinds of expressions: variables, functions
of one argument, and function applications.
Examples:
<#42698#>1.<#42698#> <#42699#>(lamb<#42699#><#42700#>da<#42700#> <#42701#>(x)<#42701#> <#42702#>y)<#42702#>
<#42703#>2.<#42703#> <#42704#>((lam<#42704#><#42705#>bda<#42705#> <#42706#>(x)<#42706#> <#42707#>x)<#42707#>
<#42708#>(lambda<#42708#> <#42709#>(x)<#42709#> <#42710#>x))<#42710#>
<#42711#>3.<#42711#> <#42712#>(((la<#42712#><#42713#>m<#42713#><#42714#>bd<#42714#><#42715#>a<#42715#> <#42716#>(y)<#42716#>
<#42717#>(l<#42717#><#42718#>ambda<#42718#> <#42719#>(x)<#42719#>
<#42720#>y))<#42720#>
<#42721#>(lambda<#42721#> <#42722#>(z)<#42722#> <#42723#>z))<#42723#>
<#42724#>(lambda<#42724#> <#42725#>(w)<#42725#> <#42726#>w))<#42726#>
Represent variables as symbols. Call the class of data <#67799#><#42730#>Lam<#42730#><#67799#>.
Recall that <#67800#><#42731#>lambda<#42731#>-expression<#67800#>s are functions without names. Thus, they bind their
parameter in the body. In other words, the scope of a <#42732#>lambda<#42732#>-expression's parameter
is the body. Explain the scope of each binding occurrence in the above
examples. Draw arrows from all bound occurrences to the binding
occurrences.
If a variable occurs in an expression but has no corresponding binding
occurrence, the occurrence is said to be free. Make up an expression in
which <#67801#><#42733#>x<#42733#><#67801#> occurs both free and bound.~
Solution<#67802#><#67802#>
<#42739#>Exercise 32.1.2<#42739#>
<#71683#>;; <#67803#><#42745#>free-or-bound<#42745#> <#42746#>:<#42746#> <#42747#>Lam<#42747#> <#42748#><#42748#><#42749#>-;SPMgt;<#42749#><#42750#><#42750#> <#42751#>Lam<#42751#><#67803#> <#71683#>
<#71684#>;; to replace each non-binding occurrence of a variable in <#67804#><#42752#>a-lam<#42752#><#67804#> <#71684#>
<#71685#>;; with <#67805#><#42753#>'<#42753#><#42754#>free<#42754#><#67805#> or <#67806#><#42755#>'<#42755#><#42756#>bound<#42756#><#67806#>, depending on whether the <#71685#>
<#42757#>;; occurrence is bound or not.<#42757#>
<#42758#>(define<#42758#> <#42759#>(free-or-bound<#42759#> <#42760#>a-lam)<#42760#> <#42761#>...)<#42761#>
where <#67807#><#42765#>Lam<#42765#><#67807#> is the class of expression representations from
exercise~#exfreebounddd#42766>
Solution<#67808#><#67808#>
<#42772#>Exercise 32.1.3<#42772#>
<#71686#>;; <#67809#><#42778#>unique-binding<#42778#> <#42779#>:<#42779#> <#42780#>Lam<#42780#> <#42781#><#42781#><#42782#>-;SPMgt;<#42782#><#42783#><#42783#> <#42784#>Lam<#42784#><#67809#> <#71686#>
<#42785#>;; to replace variables names of binding occurrences and their bound<#42785#>
<#42786#>;; counterparts so that no name is used twice in a binding occurrence<#42786#>
<#42787#>(define<#42787#> <#42788#>(unique-binding<#42788#> <#42789#>a-lam)<#42789#> <#42790#>...)<#42790#>
where <#67810#><#42794#>Lam<#42794#><#67810#> is the class of expression representations from
exercise~#exfreebounddd#42795>
Solution<#67812#><#67812#>