<#71002#>;; <#62696#><#12932#>!<#12932#> <#12933#>:<#12933#> <#12934#>N<#12934#> <#12935#><#12935#><#12936#>-;SPMgt;<#12936#><#12937#><#12937#> <#12938#>N<#12938#><#62696#><#71002#> <#12939#>;; to computeIt consumes a natural number and produces one. Specifying its input-output relationship is a bit more tricky. We know, of course, what the product of <#62697#><#12947#>1<#12947#><#62697#>, <#62698#><#12948#>2<#12948#><#62698#>, and <#62699#><#12949#>3<#12949#><#62699#> is, so we should have#tex2html_wrap_inline73028#<#12939#> <#12940#>(define<#12940#> <#12941#>(!<#12941#> <#12942#>n)<#12942#> <#12943#>...)<#12943#>
<#12954#>(!<#12954#> <#12955#>3)<#12955#> <#12956#>=<#12956#> <#12957#>6<#12957#> <#12958#>;and, similarly, <#12958#> <#12959#>(!<#12959#> <#12960#>10)<#12960#> <#12961#>=<#12961#> <#12962#>3628800<#12962#>The real question is what to do with the input <#62700#><#12966#>0<#12966#><#62700#>. According to the informal description of the task, <#62701#><#12967#>!<#12967#><#62701#> is supposed to produce the product of all numbers between <#62702#><#12968#>0<#12968#><#62702#> (exclusive) and <#62703#><#12969#>n<#12969#><#62703#> (inclusive), the argument. Since <#62704#><#12970#>n<#12970#><#62704#> is <#62705#><#12971#>0<#12971#><#62705#>, this request is rather strange because there are no numbers between <#62706#><#12972#>0<#12972#><#62706#> (exclusive) and <#62707#><#12973#>0<#12973#><#62707#> (inclusive). We solve the problem by following mathematical convention and set that <#62708#><#12974#>(!<#12974#>\ <#12975#>0)<#12975#><#62708#> evaluates to <#62709#><#12976#>1<#12976#><#62709#>. From here, the rest is straightforward. The template for <#62710#><#12977#>!<#12977#><#62710#> is clearly that of a natural number-processing function:
<#12982#>(d<#12982#><#12983#>efine<#12983#> <#12984#>(!<#12984#> <#12985#>n)<#12985#> <#12986#>(c<#12986#><#12987#>ond<#12987#> <#12988#>[<#12988#><#12989#>(zero?<#12989#> <#12990#>n)<#12990#> <#12991#>...]<#12991#> <#12992#>[<#12992#><#12993#>else<#12993#> <#12994#>...<#12994#> <#12995#>(!<#12995#> <#12996#>(sub1<#12996#> <#12997#>n))<#12997#> <#12998#>...]<#12998#><#12999#>))<#12999#>The answer in the first <#62711#><#13003#>cond<#13003#><#62711#>-clause is given: <#62712#><#13004#>1<#13004#><#62712#>. In the second clause, the recursion produces the product of the first <#62713#><#13005#>n<#13005#>\ <#13006#>-<#13006#><#13007#> <#13007#><#13008#>1<#13008#><#62713#> numbers, <#13009#>e.g.<#13009#>, for <#62714#><#13010#>n<#13010#>\ <#13011#>=<#13011#>\ <#13012#>3<#13012#><#62714#>, <#62715#><#13013#>(!<#13013#>\ <#13014#>(sub1<#13014#>\ <#13015#>n))<#13015#><#62715#> evaluates to <#62716#><#13016#>2<#13016#><#62716#>. To get the product of the first <#62717#><#13017#>n<#13017#><#62717#> numbers, we just need to multiply the (value of the) recursion by <#62718#><#13018#>n<#13018#><#62718#>. Figure~#figfact#13019>
<#13051#>Exercise 11.4.2<#13051#>
Second, we can follow our design recipe, starting with a precise
characterization of the function's input. Obviously, the inputs belong to
the natural numbers, but we know more than that. It belongs the following
collection of numbers: <#62741#><#13068#>20<#13068#><#62741#>, <#62742#><#13069#>21<#13069#><#62742#>, <#62743#><#13070#>22<#13070#><#62743#>, ...By now
we know how to describe such a set precisely with a data definition:
A <#72202#><#71003#>natural number <#62744#><#13072#>[<#13072#><#13073#>;SPMgt;=<#13073#>\ <#13074#>20]<#13074#><#62744#><#71003#><#72202#> is either
Using the new data definition, we can formulate a contract for
<#62751#><#13092#>product-from-20<#13092#><#62751#>:
Notation: In contracts, we use <#62749#><#13084#>N<#13084#>\ <#13085#>[<#13085#><#13086#>;SPMgt;=<#13086#>\ <#13087#>20]<#13087#><#62749#> instead of ``natural numbers <#62750#><#13088#>[<#13088#><#13089#>;SPMgt;=<#13089#>\ <#13090#>20]<#13090#><#62750#>.'' <#71004#>;; <#62752#><#13097#>product-from-20:<#13097#> <#13098#>N<#13098#> <#13099#>[<#13099#><#13100#>;SPMgt;=<#13100#> <#13101#>20]<#13101#> <#13102#><#13102#><#13103#>-;SPMgt;<#13103#><#13104#><#13104#> <#13105#>N<#13105#><#62752#><#71004#>
<#13106#>;; to compute
Here is a first example for <#62753#><#13114#>product-from-20<#13114#><#62753#>'s input-output specification:
<#13119#>(product-from-20<#13119#> <#13120#>21)<#13120#>
<#13121#>=<#13121#> <#13122#>21<#13122#>
Since the function multiplies all numbers between <#62754#><#13126#>20<#13126#><#62754#> (exclusively)
and its input, <#62755#><#13127#>(product-from-20<#13127#>\ <#13128#>21)<#13128#><#62755#> must produce <#62756#><#13129#>21<#13129#><#62756#>, which is the only
number in the interval. Similarly,
<#13134#>(product-from-20<#13134#> <#13135#>22)<#13135#>
<#13136#>=<#13136#> <#13137#>462<#13137#>
for the same reason. Finally, we again follow mathematical convention and
agree that
<#13145#>(product-from-20<#13145#> <#13146#>20)<#13146#>
<#13147#>=<#13147#> <#13148#>1<#13148#>
The template for <#62757#><#13152#>product-from-20<#13152#><#62757#> is a straightforward adaptation of the
template for <#62758#><#13153#>!<#13153#><#62758#>, or any natural number-processing function:
<#13158#>(d<#13158#><#13159#>efine<#13159#> <#13160#>(product-from-20<#13160#> <#13161#>n-above-20)<#13161#>
<#13162#>(c<#13162#><#13163#>ond<#13163#>
<#13164#>[<#13164#><#13165#>(=<#13165#> <#13166#>n-above-20<#13166#> <#13167#>20)<#13167#> <#13168#>...]<#13168#>
<#13169#>[<#13169#><#13170#>else<#13170#> <#13171#>...<#13171#> <#13172#>(product-from-20<#13172#> <#13173#>(sub1<#13173#> <#13174#>n-above-20))<#13174#> <#13175#>...]<#13175#><#13176#>))<#13176#>
The input <#62759#><#13180#>n-above-20<#13180#><#62759#> is either <#62760#><#13181#>20<#13181#><#62760#> or larger. If it is
<#62761#><#13182#>20<#13182#><#62761#>, it does not have any components according to the data
definition. Otherwise, it is the result of adding <#62762#><#13183#>1<#13183#><#62762#> to a
natural number <#62763#><#13184#>[<#13184#><#13185#>;SPMgt;=<#13185#>\ <#13186#>20]<#13186#><#62763#>, and we can recover this ``component'' by
subtracting <#62764#><#13187#>1<#13187#><#62764#>. The value of this selector expression belongs to
the same class of data as the input and is thus a candidate for natural
recursion.
Completing the template is equally straightforward. As specified, the
result of <#62765#><#13188#>(product-from-20<#13188#>\ <#13189#>20)<#13189#><#62765#> is <#62766#><#13190#>1<#13190#><#62766#>, which determines the answer
for
the first <#62767#><#13191#>cond<#13191#><#62767#>-clauses. Otherwise, <#62768#><#13192#>(product-from-20<#13192#>\ <#13193#>(sub1<#13193#>\ <#13194#>n-above-20))<#13194#><#62768#>
already produces the product of all the numbers between <#62769#><#13195#>20<#13195#><#62769#>
(exclusive) and <#62770#><#13196#>n-above-20<#13196#>\ <#13197#>-<#13197#>\ <#13198#>1<#13198#><#62770#>. The only number not included in this
range is <#62771#><#13199#>n-above-20<#13199#><#62771#>. Hence, <#62772#><#13200#>(*<#13200#>\ <#13201#>n-above-20<#13201#>\ <#13202#>(product-from-20<#13202#>\ <#13203#>(sub1<#13203#>\ <#13204#>n-above-20)))<#13204#><#62772#> is the
correct answer in the second clause. Figure~#figfact#13205>
<#13209#>Exercise 11.4.3<#13209#>
<#71005#>;; <#62792#><#13249#>!<#13249#> <#13250#>:<#13250#> <#13251#>N<#13251#> <#13252#><#13252#><#13253#>-;SPMgt;<#13253#><#13254#><#13254#> <#13255#>N<#13255#><#62792#><#71005#>
<#13256#>;; to compute
<#13341#>Figure: Computing factorial, product-from-20, and product<#13341#>
A comparison of <#62796#><#13343#>!<#13343#><#62796#> and <#62797#><#13344#>product-from-20<#13344#><#62797#> suggests the
natural question of how to design a function that multiplies <#13345#>all<#13345#>
natural numbers in some range. Roughly speaking, <#62798#><#13346#>product<#13346#><#62798#> is like
<#62799#><#13347#>product-from-20<#13347#><#62799#> except that the limit is not a part of the function
definition. Instead, it is another input, which suggests the following
contract:
<#71008#>;; <#62800#><#13352#>product:<#13352#> <#13353#>N<#13353#> <#13354#>N<#13354#> <#13355#><#13355#><#13356#>-;SPMgt;<#13356#><#13357#><#13357#> <#13358#>N<#13358#><#62800#><#71008#>
<#62801#>;; to compute
The intention is that <#62802#><#13368#>product<#13368#><#62802#>, like <#62803#><#13369#>product-from-20<#13369#><#62803#>, computes the
product from <#62804#><#13370#>limit<#13370#><#62804#> (exclusive) to some number <#62805#><#13371#>n<#13371#><#62805#>
(inclusive) that is greater or equal to <#62806#><#13372#>limit<#13372#><#62806#>.
Unfortunately, <#62807#><#13373#>product<#13373#><#62807#>'s contract, in contrast <#62808#><#13374#>product-from-20<#13374#><#62808#>'s, is
rather imprecise. In particular, it does not describe the collection of
numbers that <#62809#><#13375#>product<#13375#><#62809#> consumes as the second input. Given its first
input, <#62810#><#13376#>limit<#13376#><#62810#>, we know that the second input belongs to
<#62811#><#13377#>limit<#13377#><#62811#>, <#62812#><#13378#>(add1<#13378#>\ <#13379#>limit)<#13379#><#62812#>, <#62813#><#13380#>(add1<#13380#>\ <#13381#>(add1<#13381#>\ <#13382#>limit))<#13382#><#62813#>,
<#13383#>etc<#13383#>. While it is easy to enumerate the possible second inputs, it also
shows that the description of the collection <#13384#>depends on the first input<#13384#>---an unusal situation that we have not encountered before.
Still, if we assume limit is some number, the data description for the
second input is nearly obvious:
Let <#62814#><#13386#>limit<#13386#><#62814#> be a natural number. A <#72203#><#71009#>natural number <#62815#><#13387#>[<#13387#><#13388#>;SPMgt;=<#13388#>\ <#13389#>limit]<#13389#><#62815#><#71009#><#72203#> (<#62816#><#13390#>N<#13390#><#13391#>[<#13391#><#13392#>;SPMgt;=limit]<#13392#><#62816#>) is either
In other words, the data definition is like that for natural numbers
<#62821#><#13403#>[<#13403#><#13404#>;SPMgt;=<#13404#>\ <#13405#>limit]<#13405#><#62821#> with <#62822#><#13406#>20<#13406#><#62822#> replaced by a variable
<#62823#><#13407#>limit<#13407#><#62823#>. Of course, in high school, we refer to
<#62824#><#13408#>N<#13408#><#13409#>[<#13409#><#13410#>;SPMgt;=0]<#13410#><#62824#> as <#13411#>the<#13411#> natural numbers, and
<#62825#><#13412#>N<#13412#><#13413#>[<#13413#><#13414#>;SPMgt;=1]<#13414#><#62825#> as <#13415#>the<#13415#> positive integers.
With this new data definition, we specify the contract for <#62826#><#13416#>product<#13416#><#62826#>
as follows:
<#71010#>;; <#62827#><#13421#>product:<#13421#> <#13422#>N<#13422#><#13423#>[<#13423#><#13424#>limit]<#13424#> <#13425#>N<#13425#> <#13426#>[<#13426#><#13427#>;SPMgt;=<#13427#> <#13428#>limit]<#13428#> <#13429#><#13429#><#13430#>-;SPMgt;<#13430#><#13431#><#13431#> <#13432#>N<#13432#><#62827#><#71010#>
<#62828#>;; to compute
That is, we name the first input, a natural number, with the notation
<#62829#><#13442#>[<#13442#><#13443#>limit]<#13443#><#62829#> and specify the second input using the name for the
first one.
The rest of the program development is straightforward. It is basically
the same as that for <#62830#><#13444#>product-from-20<#13444#><#62830#> with <#62831#><#13445#>20<#13445#><#62831#> replaced by
<#62832#><#13446#>limit<#13446#><#62832#> throughout. The only modification concerns the natural
recusion in the function template. Since the function consumes a
<#62833#><#13447#>limit<#13447#><#62833#> and a <#62834#><#13448#>N<#13448#>\ <#13449#>[<#13449#><#13450#>;SPMgt;=<#13450#>\ <#13451#>limit]<#13451#><#62834#>, the template
must contain an application of <#62835#><#13452#>product<#13452#><#62835#> to <#62836#><#13453#>limit<#13453#><#62836#> and
<#62837#><#13454#>(sub1<#13454#>\ <#13455#>n)<#13455#><#62837#>:
<#13460#>(d<#13460#><#13461#>efine<#13461#> <#13462#>(product<#13462#> <#13463#>limit<#13463#> <#13464#>n)<#13464#>
<#13465#>(c<#13465#><#13466#>ond<#13466#>
<#13467#>[<#13467#><#13468#>(=<#13468#> <#13469#>n<#13469#> <#13470#>limit)<#13470#> <#13471#>...]<#13471#>
<#13472#>[<#13472#><#13473#>else<#13473#> <#13474#>...<#13474#> <#13475#>(product<#13475#> <#13476#>limit<#13476#> <#13477#>(sub1<#13477#> <#13478#>n))<#13478#> <#13479#>...]<#13479#><#13480#>))<#13480#>
Otherwise things remain the same. The full function definition is
contained in figure~#figfact#13484>
<#13487#>Exercise 11.4.5<#13487#>
<#13520#>(c<#13520#><#13521#>ons<#13521#> <#13522#>(make-posn<#13522#> <#13523#>3<#13523#> <#13524#>2.4)<#13524#>
<#13525#>(c<#13525#><#13526#>ons<#13526#> <#13527#>(make-posn<#13527#> <#13528#>2<#13528#> <#13529#>3.4)<#13529#>
<#13530#>(c<#13530#><#13531#>ons<#13531#> <#13532#>(make-posn<#13532#> <#13533#>1<#13533#> <#13534#>3.6)<#13534#>
<#13535#>(c<#13535#><#13536#>ons<#13536#> <#13537#>(make-posn<#13537#> <#13538#>0<#13538#> <#13539#>3.0)<#13539#>
<#13540#>empty))))<#13540#>
If we prefer a list of <#62850#><#13544#>posn<#13544#><#62850#>s in <#13545#>ascending<#13545#> order, we
must look at a different data collection, natural numbers up to a
certain point in the chain:
A <#72204#><#71011#>natural number <#62851#><#13547#>[<#13547#><#13548#>;SPMlt;=<#13548#>\ <#13549#>20]<#13549#><#62851#><#71011#><#72204#> (<#62852#><#13550#>N<#13550#><#13551#>[<#13551#><#13552#>;SPMlt;=20]<#13552#><#62852#>) is either
Of course, in high school, we refer to <#62857#><#13563#>N<#13563#><#13564#>[<#13564#><#13565#>;SPMlt;=-1]<#13565#><#62857#>
as <#13566#>the<#13566#> negative integers.
Develop the function
<#71012#>;; <#62858#><#13571#>tabulate-f-up-to-20<#13571#> <#13572#>:<#13572#> <#13573#>N<#13573#> <#13574#>[<#13574#><#13575#>;SPMlt;=<#13575#> <#13576#>20]<#13576#> <#13577#><#13577#><#13578#>-;SPMgt;<#13578#><#13579#><#13579#> <#13580#>N<#13580#><#62858#><#71012#>
<#13581#>(define<#13581#> <#13582#>(tabulate-f-up-to-20<#13582#> <#13583#>n-above-20)<#13583#> <#13584#>...)<#13584#>
which tabulates the values of <#62859#><#13588#>f<#13588#><#62859#> for natural numbers less than
<#62860#><#13589#>20<#13589#><#62860#>. Specifically, it consumes a natural number <#62861#><#13590#>n<#13590#><#62861#> less
or equal to <#62862#><#13591#>20<#13591#><#62862#> and produces a list of <#62863#><#13592#>posn<#13592#><#62863#>s, each of
which has the shape <#62864#><#13593#>(make-posn<#13593#>\ <#13594#>n<#13594#>\ <#13595#>(f<#13595#>\ <#13596#>n))<#13596#><#62864#> for some <#62865#><#13597#>n<#13597#><#62865#>
between <#62866#><#13598#>0<#13598#><#62866#> and <#62867#><#13599#>n<#13599#><#62867#> (inclusively). Solution<#62868#><#62868#>
<#13605#>Exercise 11.4.7<#13605#>