<#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><#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>