<#59211#>(define-struct<#59211#> <#59212#>person<#59212#> <#59213#>(name<#59213#> <#59214#>social<#59214#> <#59215#>father<#59215#> <#59216#>mother<#59216#> <#59217#>children))<#59217#>The goal is to create family trees that consist of <#70443#><#59221#>person<#59221#><#70443#> structures. A person structure has five fields. The contents of each is specified by the following data definition:
An <#70444#><#59223#>family tree node<#59223#><#70444#> (<#70445#><#59224#>ftn<#59224#><#70445#>) is eitherAs usual, the <#70457#><#59245#>false<#59245#><#70457#> in the definition of <#70458#><#59246#>family<#59246#><#59247#> <#59247#><#59248#>tree<#59248#>\ <#59249#>node<#59249#><#70458#>s represents missing information about a portion of the family tree.A <#70448#><#59229#>person<#59229#><#70448#> is a structure:
- <#70446#><#59226#>false<#59226#><#70446#> or
- a <#70447#><#59227#>person<#59227#><#70447#>.
<#72107#><#70449#><#59230#>(make-person<#59230#>\ <#59231#>n<#59231#>\ <#59232#>s<#59232#>\ <#59233#>f<#59233#>\ <#59234#>m<#59234#>\ <#59235#>c)<#59235#><#70449#><#72107#> where <#70450#><#59236#>n<#59236#><#70450#> is a symbol, <#70451#><#59237#>s<#59237#><#70451#> is number, <#70452#><#59238#>f<#59238#><#70452#> and <#70453#><#59239#>m<#59239#><#70453#> are <#70454#><#59240#>ftn<#59240#><#70454#>s, and <#70455#><#59241#>c<#59241#><#70455#> is a <#70456#><#59242#>(listof<#59242#>\ <#59243#>person)<#59243#><#70456#>.
<#72109#>;; <#70465#><#59264#>add-child!<#59264#> <#59265#>:<#59265#> <#59266#>symbol<#59266#> <#59267#>number<#59267#> <#59268#>person<#59268#> <#59269#>person<#59269#> <#59270#><#59270#><#59271#>-;SPMgt;<#59271#><#59272#><#59272#> <#59273#>person<#59273#><#70465#><#72109#> <#72110#>;; to construct a <#70466#><#59274#>person<#59274#><#70466#> structure for a newborn <#72110#> <#72111#>;; effect: to add the new structure to the cildren of <#70467#><#59275#>father<#59275#><#70467#> and <#70468#><#59276#>mother<#59276#><#70468#><#72111#> <#59277#>(define<#59277#> <#59278#>(add-child!<#59278#> <#59279#>name<#59279#> <#59280#>soc-sec<#59280#> <#59281#>father<#59281#> <#59282#>mother)<#59282#> <#59283#>...)<#59283#>Its task is to create a new structure for a newborn child and to add the structure to an existing family tree. The function consumes the child's name, social security number, and the structures representing the father and the mother. The first step of the design of <#70469#><#59287#>add-child!<#59287#><#70469#> is to create the new structure for the child:
<#59292#>(d<#59292#><#59293#>efine<#59293#> <#59294#>(add-child!<#59294#> <#59295#>name<#59295#> <#59296#>soc-sec<#59296#> <#59297#>father<#59297#> <#59298#>mother)<#59298#> <#59299#>(l<#59299#><#59300#>ocal<#59300#> <#59301#>((d<#59301#><#59302#>efine<#59302#> <#59303#>the-child<#59303#> <#59304#>(make-person<#59304#> <#59305#>name<#59305#> <#59306#>soc-sec<#59306#> <#59307#>father<#59307#> <#59308#>mother<#59308#> <#59309#>empty)))<#59309#> <#59310#>...))<#59310#>This covers the first part of the contract. By naming the structure in a <#59314#>local<#59314#>-expression\ we can mutate it in the body of the expression. The second step of the design of <#70470#><#59315#>add-child!<#59315#><#70470#> is to add a body to the <#59316#>local<#59316#>-expression\ that performs the desired effects:
<#59321#>(d<#59321#><#59322#>efine<#59322#> <#59323#>(add-child!<#59323#> <#59324#>name<#59324#> <#59325#>soc-sec<#59325#> <#59326#>father<#59326#> <#59327#>mother)<#59327#> <#59328#>(l<#59328#><#59329#>ocal<#59329#> <#59330#>((d<#59330#><#59331#>efine<#59331#> <#59332#>the-child<#59332#> <#59333#>(make-person<#59333#> <#59334#>name<#59334#> <#59335#>soc-sec<#59335#> <#59336#>father<#59336#> <#59337#>mother<#59337#> <#59338#>empty)))<#59338#> <#59339#>(b<#59339#><#59340#>egin<#59340#> <#59341#>(set-person-children!<#59341#> <#59342#>father<#59342#> <#59343#>(cons<#59343#> <#59344#>the-child<#59344#> <#59345#>(person-children<#59345#> <#59346#>father)))<#59346#> <#59347#>(set-person-children!<#59347#> <#59348#>mother<#59348#> <#59349#>(cons<#59349#> <#59350#>the-child<#59350#> <#59351#>(person-children<#59351#> <#59352#>mother)))<#59352#> <#59353#>the-child)))<#59353#>Since there are two specified effects and since the purpose statement also specifies a result, the body of the <#59357#>local<#59357#>-expression\ is a <#59358#>begin<#59358#>-expression\ with three subexpressions. The first mutates <#70471#><#59359#>father<#59359#><#70471#>, adding <#70472#><#59360#>the-child<#59360#><#70472#> to the list of children. The second mutates <#70473#><#59361#>mother<#59361#><#70473#> in an analogous manner. The last one produces the desired result. Figure~#figbuildafamily#59362>
<#59368#>(add-child!<#59368#> <#59369#>'<#59369#><#59370#>Ludwig<#59370#> <#59371#>3<#59371#> <#59372#>(make-person<#59372#> <#59373#>'<#59373#><#59374#>Adam<#59374#> <#59375#>...<#59375#> <#59376#>...<#59376#> <#59377#>...)<#59377#> <#59378#>(make-person<#59378#> <#59379#>'<#59379#><#59380#>Eve<#59380#> <#59381#>...<#59381#> <#59382#>...<#59382#> <#59383#>...))<#59383#>The top-half shows the new structure for <#70475#><#59387#>'<#59387#><#59388#>Ludwig<#59388#><#70475#> and how it refers to the <#70476#><#59389#>father<#59389#><#70476#> and <#70477#><#59390#>mother<#59390#><#70477#> structures. Just as in section~#secstructinstruct#59391>
<#72112#>;; <#70485#><#59408#>add-child!<#59408#> <#59409#>:<#59409#> <#59410#>symbol<#59410#> <#59411#>number<#59411#> <#59412#>ftn<#59412#> <#59413#>ftn<#59413#> <#59414#><#59414#><#59415#>-;SPMgt;<#59415#><#59416#><#59416#> <#59417#>person<#59417#><#70485#><#72112#>The function otherwise behaves just like the original version. Once we have the modified function, there is no need for <#70486#><#59421#>make-person<#59421#><#70486#> any more. We can create all forms of <#70487#><#59422#>person<#59422#><#70487#> structures with <#70488#><#59423#>add-child!<#59423#><#70488#> directly. Transliterate the family tree in figure~#figfamilyA#59424>
<#59470#>(define-struct<#59470#> <#59471#>node<#59471#> <#59472#>(name<#59472#> <#59473#>to))<#59473#>The <#70501#><#59477#>name<#59477#><#70501#> field records the name of the node, and the <#70502#><#59478#>to<#59478#><#70502#> field specifies to which other node it is connected. Second, we need a data definition:
An <#70503#><#59480#>simple graph node<#59480#><#70503#> (<#70504#><#59481#>node<#59481#><#70504#>) is a structure:The data definition is unusual in that it is self-referential, but it doesn't consist of several clauses. This immediately raises the question of how we can construct a node that complies with this definition. Clearly, applying <#70509#><#59489#>make-node<#59489#><#70509#> doesn't work; instead, we need to define a generalized constructor that immediately sets the <#70510#><#59490#>to<#59490#><#70510#> field of a node. The generalized constructor consumes the atomic data for a <#70511#><#59491#>node<#59491#><#70511#> structure and constructs a legal node structure from there:
<#72113#><#70505#><#59482#>(make-node<#59482#>\ <#59483#>n<#59483#>\ <#59484#>t)<#59484#><#70505#><#72113#> where <#70506#><#59485#>n<#59485#><#70506#> is a symbol and <#70507#><#59486#>t<#59486#><#70507#> is a <#70508#><#59487#>node<#59487#><#70508#>.
<#72114#>;; <#70512#><#59496#>create-node<#59496#> <#59497#>:<#59497#> <#59498#>symbol<#59498#> <#59499#><#59499#><#59500#>-;SPMgt;<#59500#><#59501#><#59501#> <#59502#>node<#59502#><#70512#><#72114#> <#72115#>;; to create a simple legal graph node with <#70513#><#59503#>a-name<#59503#><#70513#> in the name field<#72115#> <#59504#>(d<#59504#><#59505#>efine<#59505#> <#59506#>(create-node<#59506#> <#59507#>a-name)<#59507#> <#59508#>(local<#59508#> <#59509#>((define<#59509#> <#59510#>the-node<#59510#> <#59511#>(make-node<#59511#> <#59512#>a-name<#59512#> <#59513#>false)))<#59513#> <#59514#>...))<#59514#>The natural candidate to place into the <#70514#><#59518#>to<#59518#><#70514#> field is the node itself. In other words, the generalized constructor creates a node that contains itself:
<#72116#>;; <#70515#><#59523#>create-node<#59523#> <#59524#>:<#59524#> <#59525#>symbol<#59525#> <#59526#><#59526#><#59527#>-;SPMgt;<#59527#><#59528#><#59528#> <#59529#>node<#59529#><#70515#><#72116#> <#72117#>;; to create a simple graph node that contains <#70516#><#59530#>a-name<#59530#><#70516#> and itself<#72117#> <#59531#>(d<#59531#><#59532#>efine<#59532#> <#59533#>(create-node<#59533#> <#59534#>a-name)<#59534#> <#59535#>(l<#59535#><#59536#>ocal<#59536#> <#59537#>((define<#59537#> <#59538#>the-node<#59538#> <#59539#>(make-node<#59539#> <#59540#>a-name<#59540#> <#59541#>false)))<#59541#> <#59542#>(b<#59542#><#59543#>egin<#59543#> <#59544#>(set-node-to!<#59544#> <#59545#>the-node<#59545#> <#59546#>the-node)<#59546#> <#59547#>the-node)))<#59547#>The generalized constructor makes the node using the ordinary constructor, initializing the <#70517#><#59551#>name<#59551#><#70517#> field properly and putting <#70518#><#59552#>false<#59552#><#70518#> into the <#70519#><#59553#>to<#59553#><#70519#> field. Although the latter is an improper action according to our data definition, it is acceptable because it is immediately corrected in the <#59554#>local<#59554#>-expression's body. Hence, the result of an application of <#70520#><#59555#>create-node<#59555#><#70520#> produces a <#70521#><#59556#>node<#59556#><#70521#> as promised. With <#70522#><#59557#>create-node<#59557#><#70522#> we can create the nodes in a graph, but we can't establish the connections between them. To connect two nodes, we must modify the <#70523#><#59558#>to<#59558#><#70523#> field of one of the structures so that it contains the other. While this suggestion is generally on target, it raises the problem of how to identify the nodes. The family tree example suggests one solution, namely, to introduce one variable definition per node. Another comes from our orginal work with graphs, where we represented graphs as lists of symbolic pairs of connections or lists of nodes or vectors of nodes. Here we pursue the second option:
An <#70524#><#59560#>simple graph<#59560#><#70524#> is a <#70525#><#59561#>(listof<#59561#>\ <#59562#>node)<#59562#><#70525#>.Assuming we have a list of all nodes, say <#70526#><#59564#>the-graph<#59564#><#70526#>, and a function for looking up the node with a given name, say <#70527#><#59565#>lookup-node<#59565#><#70527#>, we can create a connection from one node to the other with a structure mutation:
<#59570#>(set-node-to!<#59570#> <#59571#>(lookup-node<#59571#> <#59572#>from-name<#59572#> <#59573#>the-graph)<#59573#> <#59574#>(lookup-node<#59574#> <#59575#>to-name<#59575#> <#59576#>the-graph))<#59576#>We can make connecting two nodes more convenient than that with an auxiliary function:
<#72118#>;; <#70528#><#59584#>connect-nodes<#59584#> <#59585#>:<#59585#> <#59586#>symbol<#59586#> <#59587#>symbol<#59587#> <#59588#>graph<#59588#> <#59589#><#59589#><#59590#>-;SPMgt;<#59590#><#59591#><#59591#> <#59592#>void<#59592#><#70528#><#72118#> <#72119#>;; effect: to mutate the <#70529#><#59593#>to<#59593#><#70529#> field in the structure with<#72119#> <#72120#>;; <#70530#><#59594#>from-name<#59594#><#70530#> in the <#70531#><#59595#>name<#59595#><#70531#> field so that it contains<#72120#> <#72121#>;; the structure with <#70532#><#59596#>to-name<#59596#><#70532#> in the <#70533#><#59597#>name<#59597#><#70533#> field<#72121#> <#59598#>(d<#59598#><#59599#>efine<#59599#> <#59600#>(connect-nodes<#59600#> <#59601#>from-name<#59601#> <#59602#>to-name<#59602#> <#59603#>a-graph)<#59603#> <#59604#>(set-node-to!<#59604#> <#59605#>(lookup-node<#59605#> <#59606#>from-name<#59606#> <#59607#>a-graph)<#59607#> <#59608#>(lookup-node<#59608#> <#59609#>to-name<#59609#> <#59610#>a-graph)))<#59610#>Defining <#70534#><#59614#>lookup-node<#59614#><#70534#> is a exercise in structural function design, though it is best done using Scheme's <#70535#><#59615#>assf<#59615#><#70535#> function, which abstracts this situation.
<#72122#>;; <#70536#><#59620#>create-node<#59620#> <#59621#>:<#59621#> <#59622#>symbol<#59622#> <#59623#><#59623#><#59624#>-;SPMgt;<#59624#><#59625#><#59625#> <#59626#>node<#59626#><#70536#><#72122#> <#59627#>;; to create a simple graph node that contains itself<#59627#> <#59628#>(d<#59628#><#59629#>efine<#59629#> <#59630#>(create-node<#59630#> <#59631#>name)<#59631#> <#59632#>(l<#59632#><#59633#>ocal<#59633#> <#59634#>((define<#59634#> <#59635#>the-node<#59635#> <#59636#>(make-node<#59636#> <#59637#>name<#59637#> <#59638#>false)))<#59638#> <#59639#>(b<#59639#><#59640#>egin<#59640#> <#59641#>(set-node-to!<#59641#> <#59642#>the-node<#59642#> <#59643#>the-node)<#59643#> <#59644#>the-node)))<#59644#> <#72123#>;; <#70537#><#59645#>connect-nodes<#59645#> <#59646#>:<#59646#> <#59647#>symbol<#59647#> <#59648#>symbol<#59648#> <#59649#>graph<#59649#> <#59650#><#59650#><#59651#>-;SPMgt;<#59651#><#59652#><#59652#> <#59653#>void<#59653#><#70537#><#72123#> <#72124#>;; effect: to mutate the <#70538#><#59654#>to<#59654#><#70538#> field in the structure named <#72124#> <#72125#>;; <#70539#><#59655#>from-name<#59655#><#70539#> so that it contains the structure named <#70540#><#59656#>to-name<#59656#><#70540#><#72125#> <#59657#>(d<#59657#><#59658#>efine<#59658#> <#59659#>(connect-nodes<#59659#> <#59660#>from-name<#59660#> <#59661#>to-name<#59661#> <#59662#>a-graph)<#59662#> <#59663#>(set-node-to!<#59663#> <#59664#>(lookup-node<#59664#> <#59665#>from-name<#59665#> <#59666#>a-graph)<#59666#> <#59667#>(lookup-node<#59667#> <#59668#>to-name<#59668#> <#59669#>a-graph)))<#59669#> <#72126#>;; <#70541#><#59670#>lookup-node<#59670#> <#59671#>:<#59671#> <#59672#>symbol<#59672#> <#59673#>graph<#59673#> <#59674#><#59674#><#59675#>-;SPMgt;<#59675#><#59676#><#59676#> <#59677#>node<#59677#> <#59678#>or<#59678#> <#59679#>false<#59679#><#70541#><#72126#> <#72127#>;; to lookup up the node named <#70542#><#59680#>x<#59680#><#70542#> in <#70543#><#59681#>a-graph<#59681#><#70543#><#72127#> <#59682#>(define<#59682#> <#59683#>(lookup-node<#59683#> <#59684#>x<#59684#> <#59685#>a-graph)<#59685#> <#59686#>...)<#59686#> <#72128#>;; <#70544#><#59687#>the-graph<#59687#> <#59688#>:<#59688#> <#59689#>graph<#59689#><#70544#><#72128#> <#59690#>;; the list of all available nodes <#59690#> <#59691#>(d<#59691#><#59692#>efine<#59692#> <#59693#>the-graph<#59693#> <#59694#>(list<#59694#> <#59695#>(create-node<#59695#> <#59696#>'<#59696#><#59697#>A)<#59697#> <#59698#>(create-node<#59698#> <#59699#>'<#59699#><#59700#>B)<#59700#> <#59701#>(create-node<#59701#> <#59702#>'<#59702#><#59703#>C)<#59703#> <#59704#>(create-node<#59704#> <#59705#>'<#59705#><#59706#>D)<#59706#> <#59707#>(create-node<#59707#> <#59708#>'<#59708#><#59709#>E)<#59709#> <#59710#>(create-<#59710#><#59711#>node<#59711#> <#59712#>'<#59712#><#59713#>F)))<#59713#> <#59714#>(b<#59714#><#59715#>egin<#59715#> <#59716#>(connect-nodes<#59716#> <#59717#>'<#59717#><#59718#>A<#59718#> <#59719#>'<#59719#><#59720#>B<#59720#> <#59721#>the-graph)<#59721#> <#59722#>(connect-nodes<#59722#> <#59723#>'<#59723#><#59724#>B<#59724#> <#59725#>'<#59725#><#59726#>C<#59726#> <#59727#>the-graph)<#59727#> <#59728#>(connect-nodes<#59728#> <#59729#>'<#59729#><#59730#>C<#59730#> <#59731#>'<#59731#><#59732#>E<#59732#> <#59733#>the-graph)<#59733#> <#59734#>(connect-nodes<#59734#> <#59735#>'<#59735#><#59736#>D<#59736#> <#59737#>'<#59737#><#59738#>E<#59738#> <#59739#>the-graph)<#59739#> <#59740#>(connect-nodes<#59740#> <#59741#>'<#59741#><#59742#>E<#59742#> <#59743#>'<#59743#><#59744#>B<#59744#> <#59745#>the-graph))<#59745#><#59749#>Figure: Creating a simple graph via mutation<#59749#>
The first step is to create a list of all the nodes and to name it. The second
step is to establish the connections according to this
table. Figure~#figsgimp#59759>
<#59764#>Exercise 43.2.5<#59764#>
<#59789#>(d<#59789#><#59790#>efine<#59790#> <#59791#>the-graph<#59791#>
<#59792#>(symbolic-graph-to-structures<#59792#> <#59793#>'<#59793#><#59794#>((A<#59794#> <#59795#>B)<#59795#> <#59796#>(B<#59796#> <#59797#>C)<#59797#> <#59798#>(C<#59798#> <#59799#>E)<#59799#> <#59800#>(D<#59800#> <#59801#>E)<#59801#> <#59802#>(E<#59802#> <#59803#>B)<#59803#> <#59804#>(F<#59804#> <#59805#>F))))<#59805#>
Evaluating this definition is equivalent to evaluating the definitions in
figure~#figsgimp#59809>
Once we have a method for representing simple graphs, we can turn our
attention to the problem of finding a route from one node in the graph to
another. Recall the original specification from
section~#seclossgenerative#59817><#72129#>;; <#70552#><#59822#>route-exists?<#59822#> <#59823#>:<#59823#> <#59824#>node<#59824#> <#59825#>node<#59825#> <#59826#>simple-graph<#59826#> <#59827#><#59827#><#59828#>-;SPMgt;<#59828#><#59829#><#59829#> <#59830#>boolean<#59830#><#70552#><#72129#>
<#72130#>;; to determine whether there is a route from <#70553#><#59831#>orig<#59831#><#70553#> to <#70554#><#59832#>dest<#59832#><#70554#> in <#70555#><#59833#>sg<#59833#><#70555#><#72130#>
<#59834#>(define<#59834#> <#59835#>(route-exists?<#59835#> <#59836#>orig<#59836#> <#59837#>dest<#59837#> <#59838#>sg)<#59838#> <#59839#>...)<#59839#>
Of course, we must re-interpret the names for our data classes in the new
context but otherwise the specification is perfectly fine.
The development of the original function demonstrated two new ideas. First, the
function uses generative recursion. Once it is known that <#70556#><#59843#>orig<#59843#><#70556#> and
<#70557#><#59844#>dest<#59844#><#70557#> are distinct nodes, the search resumes from the node to which
<#70558#><#59845#>orig<#59845#><#70558#> is connected. Second, the function requires an accumulator to
remember which nodes have been visited. Without the accumulator, the
function may re-visit the same node over and over again.
So, let's start from the template for generative recursion:
<#59850#>(d<#59850#><#59851#>efine<#59851#> <#59852#>(route-exists?<#59852#> <#59853#>orig<#59853#> <#59854#>dest<#59854#> <#59855#>sg)<#59855#>
<#59856#>(c<#59856#><#59857#>ond<#59857#>
<#59858#>[<#59858#><#59859#>(eq-node?<#59859#> <#59860#>orig<#59860#> <#59861#>dest)<#59861#> <#59862#>true]<#59862#>
<#59863#>[<#59863#><#59864#>else<#59864#>
<#59865#>(route-exists?<#59865#> <#59866#>...<#59866#> <#72314#>
The function <#70560#><#59875#>eq-node?<#59875#><#70560#> determines whether the two nodes are the same;
this may just use <#70561#><#59876#>eq?<#59876#><#70561#>, Scheme's intentional equality predicate, or
it may compare the names of the nodes, assuming they are unique. If the
nodes are the same, a route exists. If not, we can generate a new,
potentially useful problem by moving to the node to which <#70562#><#59877#>orig<#59877#><#70562#> is
connected. In the graph representation of section~#seclossgenerative#59878><#59887#>(d<#59887#><#59888#>efine<#59888#> <#59889#>(route-exists?<#59889#> <#59890#>orig<#59890#> <#59891#>dest<#59891#> <#59892#>sg)<#59892#>
<#59893#>(c<#59893#><#59894#>ond<#59894#>
<#59895#>[<#59895#><#59896#>(eq-node?<#59896#> <#59897#>orig<#59897#> <#59898#>dest)<#59898#> <#59899#>true]<#59899#>
<#59900#>[<#59900#><#59901#>else<#59901#> <#59902#>(route-exists?<#59902#> <#59903#>(node-to<#59903#> <#59904#>orig)<#59904#> <#59905#>dest<#59905#> <#59906#>sg)]<#59906#><#59907#>))<#59907#>
The function definition shows that, so far, <#70567#><#59911#>sg<#59911#><#70567#> is useless. Because a
node in the new graph representation contains its neighbors, the neighbor
contains its neighbor, and so on, there is no need to use the table.
The termination argument for this function fails, just as for the original
one in section~#seclossgenerative#59912><#59923#>(route-exists?<#59923#> <#59924#>(lookup-node<#59924#> <#59925#>the-graph<#59925#> <#59926#>'<#59926#><#59927#>F)<#59927#> <#59928#>(lookup-node<#59928#> <#59929#>the-graph<#59929#> <#59930#>'<#59930#><#59931#>A))<#59931#>
we see that <#70572#><#59935#>route-exists?<#59935#><#70572#> repeatedly visits the node <#70573#><#59936#>'<#59936#><#59937#>F<#59937#><#70573#>. In
short, it forgets what it has processed so far.
We know that equipping <#70574#><#59938#>route-exists?<#59938#><#70574#> with an accumulator overcomes
this lack of knowledge, but that requires another table lookup. We can do
better than that with a structure mutation that records a visit by the
<#70575#><#59939#>route-exists?<#59939#><#70575#> function. To do that, the <#70576#><#59940#>node<#59940#><#70576#> structures
need an addtional field; we call it <#70577#><#59941#>visited<#59941#><#70577#>:
<#59946#>(define-struct<#59946#> <#59947#>node<#59947#> <#59948#>(name<#59948#> <#59949#>visited<#59949#> <#59950#>to))<#59950#>
Initially the field contains <#70578#><#59954#>false<#59954#><#70578#>. As <#70579#><#59955#>route-exists?<#59955#><#70579#>
visits a node, it puts <#70580#><#59956#>true<#59956#><#70580#> into the field:
<#59961#>(d<#59961#><#59962#>efine<#59962#> <#59963#>(route-exists?<#59963#> <#59964#>orig<#59964#> <#59965#>dest<#59965#> <#59966#>sg)<#59966#>
<#59967#>(c<#59967#><#59968#>ond<#59968#>
<#59969#>[<#59969#><#59970#>(eq-node?<#59970#> <#59971#>orig<#59971#> <#59972#>dest)<#59972#> <#59973#>true]<#59973#>
<#59974#>[<#59974#><#59975#>(node-visited<#59975#> <#59976#>orig)<#59976#> <#59977#>false]<#59977#>
<#59978#>[<#59978#><#59979#>e<#59979#><#59980#>lse<#59980#>
<#59981#>(b<#59981#><#59982#>egin<#59982#>
<#59983#>(set-node-visited!<#59983#> <#59984#>orig<#59984#> <#59985#>true)<#59985#>
<#59986#>(route-exists?<#59986#> <#59987#>(node-to<#59987#> <#59988#>orig)<#59988#> <#59989#>dest<#59989#> <#59990#>sg))]<#59990#><#59991#>))<#59991#>
To exploit this new knowledge, the function checks the new structure field
as one of the new termination condition. If <#70581#><#59995#>orig<#59995#><#70581#> has been visited
before, there is no route because the function has discovered a cycle in
the graph.
The second structure mutation of this example illustrates two ideas. First,
structure mutation can replace a table-based accumulator. In general,
though, it is best to study a table-based version and to add structure
mutations based on a solid understanding of the accumulated
knowledge. Second, structure mutations can play a role in termination test
for generative recursion. After all, state change is motivated by the
desire to remember things across function applications and termination
tests must discover whether things have changed. While the combination is
rare, it is useful and appears time and again in the study of algorithms.
<#59998#>Exercise 43.2.8<#59998#>
<#60034#>Hint:<#60034#> \ Instead of using a list, the manager should use a node sequence,
which is analogous to the <#70599#><#60035#>hand<#60035#><#70599#> structure from
section~#secdesignmutex2#60036><#60041#>(define-struct<#60041#> <#60042#>sequence<#60042#> <#60043#>(node<#60043#> <#60044#>next))<#60044#>
A sequence is similar to a list, but it supports structure
mutations.~ Solution<#70600#><#70600#>
The discussion of this section confirms the usefulness of the design recipes,
even for collections of structures that refer to each other. The most
important lesson is that such situations call for a generalized constructor, a
function that creates a structure and immediately establishes the necessary
connections. Generalized constructors correspond to the initializers of
section~#secsetbang#60055>