Extended Exercise: Accumulators on Trees

external ~<#42172#>This subsection requires a thorough understanding of tree-processing, not just list-processing. It is possible to skip this subsection and to work through one of the games in the following two subsection.<#42172#> Figure~#figblueeyesrecall#42173> recalls the structure and data definitions of family trees from section~#secstructinstruct#42174> where we developed the function <#67725#><#42175#>blue-eyed-ancestor?<#42175#><#67725#>, which determined whether an ancestor family tree contained a blue-eyed family member. In contrast, <#67726#><#42176#>all-blue-eyed-ancestors<#42176#><#67726#>, the function in figure~#figblueeyesrecall#42177>, collects the names of all blue-eyed family in a given family tree.
<#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
  1. <#67729#><#42196#>empty<#42196#><#67729#>, or
  2. <#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#>
The function's structure is the template that of a tree-processing function. It has two cases: one for the empty tree and another one for a <#67740#><#42270#>child<#42270#><#67740#> node. The latter clause contains two self-references: one per parent. These recursive applications collect the names of all blue-eyed ancestors from the father's and the mother's family tree; <#67741#><#42271#>append<#42271#><#67741#> combines the two lists into one. The <#67742#><#42272#>append<#42272#><#67742#> function is a structurally recursive function. Here it processes the two lists that the natural recursions of <#67743#><#42273#>all-blue-eyed-ancestors<#42273#><#67743#> produce. According to section~#sectwoinputscase1#42274>, this observation suggests that the function is a natural candidate for a transformation into accumulator-style. Let's get started:
<#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> shows two recursive applications. The first one processes <#67749#><#42356#>(child-father<#42356#>\ <#42357#>a-ftree)<#42357#><#67749#>, which means that this application <#67750#><#42358#>all-blue-eyed-ancestors<#42358#><#67750#> loses knowledge about the mother of <#67751#><#42359#>a-ftree<#42359#><#67751#>. Conversely, the second recursive application has no knowledge of the father of <#67752#><#42360#>a-ftree<#42360#><#67752#> as it processes the mother's family tree. At this point, we have two choices:
  1. The accumulator could represent all blue-eyed ancestors encountered so far, including those in the mother's family tree, as it descends into the father's tree.
  2. The alternative is to have the accumulator stand for the lost items in the tree. That is, as <#67753#><#42362#>all-a<#42362#><#67753#> processes the father's family tree, it remembers the mother's tree in the accumulator (and everything else it hasn't seen before).
Let's explore both possibilities, starting with the first. Initially, <#67754#><#42364#>all-a<#42364#><#67754#> has not seen any of the nodes in the family tree, so <#67755#><#42365#>accumulator<#42365#><#67755#> is <#67756#><#42366#>empty<#42366#><#67756#>. As <#67757#><#42367#>all-a<#42367#><#67757#> is about to traverse the father's family tree, we must create a list that represents all blue-eyed ancestors in the tree that we are about to forget, which is the mother's tree. This suggests the following accumulator invariant formulation:
<#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> contains the complete definition.
<#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#>
For the second version, we want the accumulator to represent a list of all of the family trees that haven't been processed yet. Because of the different intention, let us call the accumulator parameter <#67772#><#42509#>todo<#42509#><#67772#>:
<#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#>
Figure~#figblueeyesaccu#42673> contains the complete definition for this second accumulator-style variant of <#67790#><#42674#>all-blue-eyed-ancestors<#42674#><#67790#>. The auxiliary definition is the most unusual recursive function definition we have seen. It contains a recursive application of <#67791#><#42675#>all-a<#42675#><#67791#> in both the first and the second <#67792#><#42676#>cond<#42676#><#67792#>-clause. That is, the function definition does not match the data definition for family trees, the primary inputs. While a function like that can be the result of a careful chain of development steps, starting from a working function developed with a design recipe, it should never be a starting point. The use of accumulators is also fairly common in programs that process representations of programs. We encountered these forms of data in section~#secinterpreter#42677>, and like family trees, they have complicated data definitions. In intermezzo~3, we also discussed some concepts concerning variables and their mutual association, though without processing these concepts. The following exercises introduce simple functions that work with the scope of parameters, binding occurrences of variables, and other notions.
<#42680#>Exercise 32.1.1<#42680#> Develop a data representation for the following tiny subset of Scheme expressions:

#tabular42683#

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.~ external Solution<#67802#><#67802#> <#42739#>Exercise 32.1.2<#42739#> Develop the function
<#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>.~ external Solution<#67808#><#67808#> <#42772#>Exercise 32.1.3<#42772#> Develop the function
<#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>. <#42796#>Hint:<#42796#> \ The function <#67811#><#42797#>gensym<#42797#><#67811#> creates a new and unique symbol from a given symbol. The result is guaranteed to be distinct from all other symbols in the program, including those previously generated with gensym. Use the technique of this section to improve the function. <#42798#>Hint:<#42798#> \ The accumulator relates old parameter names to new parameter names.~ external Solution<#67812#><#67812#>