SICP · Yr ail argraffiad · Scheme
1.3 Llunio Haniaethau â Gweithdrefnau Trefn Uwch
Rydym wedi gweld mai haniaethau sy'n disgrifio gweithrediadau cyfansawdd ar rifau yn annibynnol ar y rhifau penodol yw gweithdrefnau, i bob pwrpas. Er enghraifft, pan fyddwn yn
(define (cube x) (* x x x))nid ydym yn sôn am giwb rhif penodol, ond yn hytrach am ddull o gael ciwb unrhyw rif. Wrth gwrs, gallem ymdopi heb ddiffinio'r weithdrefn hon byth, drwy ysgrifennu mynegiadau megis
(* 3 3 3)
(* x x x)
(* y y y)bob amser, a heb grybwyll cube yn benodol byth. Byddai hyn yn ein rhoi dan anfantais ddifrifol, gan ein gorfodi i weithio bob amser ar lefel y gweithrediadau penodol sy'n digwydd bod yn gyntefig yn yr iaith (lluosi, yn yr achos hwn) yn hytrach nag yn nhermau gweithrediadau lefel uwch. Byddai ein rhaglenni'n gallu cyfrifiannu ciwbiau, ond ni fyddai gan ein hiaith y gallu i fynegi'r cysyniad o giwbio. Un o'r pethau y dylem eu mynnu gan iaith raglennu bwerus yw'r gallu i adeiladu haniaethau drwy roi enwau i batrymau cyffredin ac yna gweithio'n uniongyrchol yn nhermau'r haniaethau. Mae gweithdrefnau'n darparu'r gallu hwn. Dyma pam mae pob iaith raglennu heblaw'r rhai mwyaf cyntefig yn cynnwys mecanweithiau ar gyfer diffinio gweithdrefnau.
Eto, hyd yn oed mewn prosesu rhifol, bydd ein gallu i greu haniaethau'n gyfyngedig iawn os cawn ein cyfyngu i weithdrefnau y mae'n rhaid i'w paramedrau fod yn rhifau. Yn aml, defnyddir yr un patrwm rhaglennu gyda nifer o weithdrefnau gwahanol. I fynegi patrymau o'r fath fel cysyniadau, bydd angen inni adeiladu gweithdrefnau sy'n gallu derbyn gweithdrefnau yn argiau neu ddychwelyd gweithdrefnau yn werthoedd. Gelwir gweithdrefnau sy'n trin gweithdrefnau yn weithdrefnau trefn uwch. Mae'r adran hon yn dangos sut y gall gweithdrefnau trefn uwch fod yn fecanweithiau haniaethu pwerus, gan gynyddu grym mynegiannol ein hiaith yn aruthrol.
1.3.1Gweithdrefnau fel Argiau
Ystyriwch y tair gweithdrefn ganlynol. Mae'r gyntaf yn cyfrifiannu swm y cyfanrifau o a hyd at ac yn cynnwys b:
(define (sum-integers a b)
(if (> a b)
0
(+ a (sum-integers (+ a 1) b))))Mae'r ail yn cyfrifiannu swm ciwbiau'r cyfanrifau yn yr amrediad penodol:
(define (sum-cubes a b)
(if (> a b)
0
(+ (cube a)
(sum-cubes (+ a 1) b))))Mae'r drydedd yn cyfrifiannu swm dilyniant o dermau yn y gyfres
(define (pi-sum a b)
(if (> a b)
0
(+ (/ 1.0 (* a (+ a 2)))
(pi-sum (+ a 4) b))))Mae'n amlwg fod y tair gweithdrefn hyn yn rhannu patrwm sylfaenol cyffredin. Maent yr un fath gan mwyaf, ac yn wahanol yn unig o ran enw'r weithdrefn, y ffwythiant o a a ddefnyddir i gyfrifiannu'r term sydd i'w adio, a'r ffwythiant sy'n darparu gwerth nesaf a. Gallem gynhyrchu pob un o'r gweithdrefnau drwy lenwi bylchau yn yr un templed:
(define (⟨name⟩ a b)
(if (> a b)
0
(+ (⟨term⟩ a)
(⟨name⟩ (⟨next⟩ a) b))))Mae presenoldeb patrwm cyffredin o'r fath yn dystiolaeth gref fod haniaeth ddefnyddiol yn aros i gael ei dwyn i'r wyneb. Yn wir, adnabu mathemategwyr ers talwm haniaeth symio cyfres a dyfeisiasant “nodiant sigma,” er enghraifft
Yn yr un modd, fel dylunwyr rhaglenni, hoffem i'n hiaith fod yn ddigon pwerus i'n galluogi i ysgrifennu gweithdrefn sy'n mynegi'r cysyniad o symio ei hun, yn hytrach na dim ond gweithdrefnau sy'n cyfrifiannu symiau penodol. Gallwn wneud hynny'n rhwydd yn ein hiaith weithdrefnol drwy gymryd y templed cyffredin a ddangoswyd uchod a thrawsffurfio'r “bylchau” yn baramedrau ffurfiol:
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))Sylwch fod sum yn cymryd y terfynau isaf ac uchaf a a b ynghyd â'r gweithdrefnau term a next yn argiau. Gallwn ddefnyddio sum yn union fel unrhyw weithdrefn arall. Er enghraifft, gallwn ei defnyddio (ynghyd â gweithdrefn inc sy'n cynyddu ei harg 1) i ddiffinio sum-cubes:
(define (inc n) (+ n 1))
(define (sum-cubes a b)
(sum cube a inc b))Gan ddefnyddio hyn, gallwn gyfrifiannu swm ciwbiau'r cyfanrifau o 1 i 10:
(sum-cubes 1 10)
3025
Gyda chymorth gweithdrefn unfathiant i gyfrifiannu'r term, gallwn ddiffinio sum-integers yn nhermau sum:
(define (identity x) x)
(define (sum-integers a b)
(sum identity a inc b))Yna gallwn adio'r cyfanrifau o 1 i 10:
(sum-integers 1 10)
55
Gallwn hefyd ddiffinio pi-sum yn yr un modd:50
(define (pi-sum a b)
(define (pi-term x)
(/ 1.0 (* x (+ x 2))))
(define (pi-next x)
(+ x 4))
(sum pi-term a pi-next b))Gan ddefnyddio'r gweithdrefnau hyn, gallwn gyfrifiannu brasamcan o
(* 8 (pi-sum 1 1000))
3.139592655589783
Unwaith y bydd gennym sum, gallwn ei defnyddio fel bloc adeiladu wrth lunio cysyniadau pellach. Er enghraifft, gellir brasamcanu integryn pendant ffwythiant
(define (integral f a b dx)
(define (add-dx x) (+ x dx))
(* (sum f (+ a (/ dx 2.0)) add-dx b)
dx))
(integral cube 0 1 0.01)
.24998750000000042
(integral cube 0 1 0.001)
.249999875000001
(Gwerth union integryn cube rhwng 0 ac 1 yw 1/4.)
Ymarfer 1.29: Mae Rheol Simpson yn ddull integru rhifiadol mwy cywir na'r dull a ddangoswyd uchod. Gan ddefnyddio Rheol Simpson, brasamcanir integryn ffwythiant
rhwng ac fel lle mae , ar gyfer rhyw eilrif , ac . (Mae cynyddu yn cynyddu cywirdeb y brasamcan.) Diffiniwch weithdrefn sy'n cymryd , , , ac yn argiau ac yn dychwelyd gwerth yr integryn, wedi'i gyfrifiannu drwy Reol Simpson. Defnyddiwch eich gweithdrefn i integru cuberhwng 0 ac 1 (gydagac ), a chymharwch y canlyniadau â rhai'r weithdrefn integrala ddangoswyd uchod.
Ymarfer 1.30: Mae'r weithdrefn
sumuchod yn cynhyrchu dychweliad llinol. Gellir ailysgrifennu'r weithdrefn fel bod y swm yn cael ei gyflawni drwy iteru. Dangoswch sut i wneud hyn drwy lenwi'r mynegiadau coll yn y diffiniad canlynol:(define (sum term a next b) (define (iter a result) (if ⟨??⟩ ⟨??⟩ (iter ⟨??⟩ ⟨??⟩))) (iter ⟨??⟩ ⟨??⟩))
- Y weithdrefn
sumyw'r symlaf yn unig o nifer enfawr o haniaethau tebyg y gellir eu mynegi fel gweithdrefnau trefn uwch.51 Ysgrifennwch weithdrefn gyfatebol o'r enwproductsy'n dychwelyd lluoswm gwerthoedd ffwythiant ar bwyntiau dros amrediad penodol. Dangoswch sut i ddiffiniofactorialyn nhermauproduct. Defnyddiwchproducthefyd i gyfrifiannu brasamcanion odrwy'r fformiwla52 - Os yw eich gweithdrefn
productyn cynhyrchu proses ddychweliadol, ysgrifennwch un sy'n cynhyrchu proses iteru. Os yw'n cynhyrchu proses iteru, ysgrifennwch un sy'n cynhyrchu proses ddychweliadol.
- Dangoswch fod
sumacproduct(Ymarfer 1.31) ill dau yn achosion arbennig o syniad mwy cyffredinol fyth o'r enwaccumulatesy'n cyfuno casgliad o dermau, gan ddefnyddio rhyw ffwythiant cronni cyffredinol:(accumulate combiner null-value term a next b)Mae
Accumulateyn cymryd yr un manylebau termau ac amrediad agsumacproductyn argiau, ynghyd â gweithdrefncombiner(â dau arg) sy'n pennu sut y dylid cyfuno'r term cyfredol â chroniad y termau blaenorol, acnull-valuesy'n pennu pa werth sylfaenol i'w ddefnyddio pan na fydd termau ar ôl. Ysgrifennwchaccumulatea dangoswch sut y gellir diffiniosumacproductill dau fel galwadau syml iaccumulate.- Os yw eich gweithdrefn
accumulateyn cynhyrchu proses ddychweliadol, ysgrifennwch un sy'n cynhyrchu proses iteru. Os yw'n cynhyrchu proses iteru, ysgrifennwch un sy'n cynhyrchu proses ddychweliadol.
Ymarfer 1.33: Gallwch gael fersiwn fwy cyffredinol fyth o
accumulate(Ymarfer 1.32) drwy gyflwyno'r syniad o hidlydd ar y termau sydd i'w cyfuno. Hynny yw, cyfuno dim ond y termau hynny sy'n deillio o werthoedd yn yr amrediad sy'n bodloni amod penodol. Mae'r haniaethfiltered-accumulatesy'n deillio o hyn yn cymryd yr un argiau ag accumulate, ynghyd â thraethiad ychwanegol ag un arg sy'n pennu'r hidlydd. Ysgrifennwchfiltered-accumulatefel gweithdrefn. Dangoswch sut i fynegi'r canlynol gan ddefnyddiofiltered-accumulate:
- swm sgwariau'r rhifau cysefin yn y cyfwng
i (gan dybio bod gennych draethiad prime?wedi'i ysgrifennu eisoes)- lluoswm yr holl gyfanrifau positif sy'n llai nag
ac sy'n gyd-gysefin ag (h.y., pob cyfanrif positif fel bod ).
1.3.2Adeiladu Gweithdrefnau drwy Ddefnyddio Lambda
Wrth ddefnyddio sum fel yn 1.3.1, mae'n ymddangos yn drwsgl iawn gorfod diffinio gweithdrefnau dibwys megis pi-term ac pi-next dim ond er mwyn eu defnyddio yn argiau i'n gweithdrefn trefn uwch. Yn hytrach na diffinio pi-next ac pi-term, byddai'n fwy cyfleus cael ffordd o bennu'n uniongyrchol “y weithdrefn sy'n dychwelyd ei mewnbwn wedi'i gynyddu 4” a “y weithdrefn sy'n dychwelyd cilydd lluoswm ei mewnbwn a'i mewnbwn ynghyd â 2.” Gallwn wneud hyn drwy gyflwyno'r ffurf arbennig lambda, sy'n creu gweithdrefnau. Gan ddefnyddio lambda gallwn ddisgrifio'r hyn a ddymunwn fel
(lambda (x) (+ x 4))a
(lambda (x) (/ 1.0 (* x (+ x 2))))Yna gellir mynegi ein gweithdrefn pi-sum heb ddiffinio unrhyw weithdrefnau ategol fel
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 2))))
a
(lambda (x) (+ x 4))
b))Gan ddefnyddio lambda eto, gallwn ysgrifennu'r weithdrefn integral heb orfod diffinio'r weithdrefn ategol add-dx:
(define (integral f a b dx)
(* (sum f (+ a (/ dx 2.0))
(lambda (x) (+ x dx))
b)
dx))Yn gyffredinol, defnyddir lambda i greu gweithdrefnau yn yr un modd ag define, heblaw na phennir enw ar gyfer y weithdrefn:
(lambda (⟨formal-parameters⟩) ⟨body⟩)Mae'r weithdrefn sy'n deillio o hyn yn weithdrefn lawn cymaint ag un a grëir drwy ddefnyddio define. Yr unig wahaniaeth yw nad yw wedi'i chysylltu ag unrhyw enw yn yr amgylchedd. Yn wir, mae
(define (plus4 x) (+ x 4))yn gyfwerth â
(define plus4 (lambda (x) (+ x 4)))Gallwn ddarllen mynegiad lambda fel a ganlyn:
(lambda (x) (+ x 4))
y weithdrefn ag arg x sy’n adio x a 4
Fel unrhyw fynegiad sydd â gweithdrefn yn werth iddo, gellir defnyddio mynegiad lambda fel y gweithredydd mewn cyfuniad megis
((lambda (x y z) (+ x y (square z))) 1 2 3)
12
neu, yn fwy cyffredinol, mewn unrhyw gyd-destun lle byddem fel arfer yn defnyddio enw gweithdrefn.53
Defnyddio let i greu newidynnau lleol
Defnydd arall o lambda yw creu newidynnau lleol. Yn aml mae angen newidynnau lleol yn ein gweithdrefnau heblaw'r rhai a rwymwyd fel paramedrau ffurfiol. Er enghraifft, tybiwch ein bod am gyfrifiannu'r ffwythiant
(define (f x y)
(define (f-helper a b)
(+ (* x (square a))
(* y b)
(* a b)))
(f-helper (+ 1 (* x y))
(- 1 y)))Wrth gwrs, gallem ddefnyddio mynegiad lambda i bennu gweithdrefn ddienw ar gyfer rhwymo ein newidynnau lleol. Yna mae corff f yn dod yn un alwad i'r weithdrefn honno:
(define (f x y)
((lambda (a b)
(+ (* x (square a))
(* y b)
(* a b)))
(+ 1 (* x y))
(- 1 y)))Mae'r gystrawen hon mor ddefnyddiol fel bod ffurf arbennig o'r enw let i wneud ei defnyddio'n fwy cyfleus. Gan ddefnyddio let, gellid ysgrifennu'r weithdrefn f fel
(define (f x y)
(let ((a (+ 1 (* x y)))
(b (- 1 y)))
(+ (* x (square a))
(* y b)
(* a b))))Ffurf gyffredinol mynegiad let yw
(let ((⟨var₁⟩ ⟨exp₁⟩)
(⟨var₂⟩ ⟨exp₂⟩)
…
(⟨varₙ⟩ ⟨expₙ⟩))
⟨body⟩)y gellir meddwl amdani fel pe bai'n dweud
let ⟨var₁⟩ â’r gwerth ⟨exp₁⟩ ac
⟨var₂⟩ â’r gwerth ⟨exp₂⟩ ac
…
⟨varₙ⟩ â’r gwerth ⟨expₙ⟩
yn ⟨body⟩
Rhan gyntaf y mynegiad let yw rhestr o barau enw–mynegiad. Wrth werthuso'r let, cysylltir pob enw â gwerth y mynegiad cyfatebol. Gwerthusir corff y let gyda'r enwau hyn wedi'u rhwymo fel newidynnau lleol. Mae hyn yn digwydd drwy ddehongli'r mynegiad let fel cystrawen amgen ar gyfer
((lambda (⟨var₁⟩ … ⟨varₙ⟩)
⟨body⟩)
⟨exp₁⟩
…
⟨expₙ⟩)Nid oes angen unrhyw fecanwaith newydd yn y dehonglydd er mwyn darparu newidynnau lleol. Yn syml, siwgr cystrawennol ar gyfer y cymhwysiad lambda sylfaenol yw mynegiad let.
Gallwn weld o'r cywerthedd hwn mai corff y let yw cwmpas newidyn a bennir gan fynegiad let. Mae hyn yn awgrymu:
- Mae
Letyn caniatáu rhwymo newidynnau mor lleol â phosibl i'r man lle cânt eu defnyddio. Er enghraifft, os mai 5 yw gwerthx, gwerth y mynegiad(+ (let ((x 3)) (+ x (* x 10))) x)yw 38. Yma, 3 yw'r
xyng nghorff ylet, felly gwerth y mynegiadletyw 33. Ar y llaw arall, mae'rxsy'n ail arg i'r+mwyaf allanol yn dal yn 5. - Cyfrifiannir gwerthoedd y newidynnau y tu allan i'r
let. Mae hyn o bwys pan fydd y mynegiadau sy'n darparu gwerthoedd y newidynnau lleol yn dibynnu ar newidynnau sydd â'r un enwau â'r newidynnau lleol eu hunain. Er enghraifft, os mai 2 yw gwerthx, bydd gan y mynegiad(let ((x 3) (y (+ x 2))) (* x y))y gwerth 12 oherwydd, y tu mewn i gorff y
let, byddxyn 3 acyyn 4 (sef yrxallanol ynghyd â 2).
Weithiau gallwn ddefnyddio diffiniadau mewnol i gael yr un effaith â let. Er enghraifft, gallem fod wedi diffinio'r weithdrefn f uchod fel
(define (f x y)
(define a
(+ 1 (* x y)))
(define b (- 1 y))
(+ (* x (square a))
(* y b)
(* a b)))Fodd bynnag, mae'n well gennym ddefnyddio let mewn sefyllfaoedd fel hyn, a defnyddio define mewnol ar gyfer gweithdrefnau mewnol yn unig.54
Ymarfer 1.34: Tybiwch ein bod yn diffinio'r weithdrefn
(define (f g) (g 2))Yna mae gennym
(f square) 4 (f (lambda (z) (* z (+ z 1)))) 6Beth sy'n digwydd os gofynnwn (yn wrthnysig) i'r dehonglydd werthuso'r cyfuniad
(f f)? Eglurwch.
1.3.3Gweithdrefnau fel Dulliau Cyffredinol
Cyflwynasom weithdrefnau cyfansawdd yn 1.1.4 fel mecanwaith ar gyfer haniaethu patrymau gweithrediadau rhifol er mwyn eu gwneud yn annibynnol ar y rhifau penodol dan sylw. Gyda gweithdrefnau trefn uwch, megis gweithdrefn integral 1.3.1, dechreuasom weld math mwy pwerus o haniaethu: defnyddio gweithdrefnau i fynegi dulliau cyfrifiannu cyffredinol, yn annibynnol ar y ffwythiannau penodol dan sylw. Yn yr adran hon trafodwn ddwy enghraifft fwy cymhleth—dulliau cyffredinol ar gyfer canfod seroau a phwyntiau sefydlog ffwythiannau—a dangoswn sut y gellir mynegi'r dulliau hyn yn uniongyrchol fel gweithdrefnau.
Canfod gwreiddiau hafaliadau drwy'r dull hanner cyfwng
Mae'r dull hanner cyfwng yn dechneg syml ond pwerus ar gyfer canfod gwreiddiau hafaliad
(define (search f neg-point pos-point)
(let ((midpoint
(average neg-point pos-point)))
(if (close-enough? neg-point pos-point)
midpoint
(let ((test-value (f midpoint)))
(cond
((positive? test-value)
(search f neg-point midpoint))
((negative? test-value)
(search f midpoint pos-point))
(else midpoint))))))Tybiwn ein bod yn cael y ffwythiant
I brofi a yw'r pwyntiau terfyn yn “ddigon agos,” gallwn ddefnyddio gweithdrefn debyg i'r un a ddefnyddiwyd yn 1.1.7 ar gyfer cyfrifiannu gwreiddiau sgwâr:55
(define (close-enough? x y)
(< (abs (- x y)) 0.001))Mae Search yn lletchwith i'w defnyddio'n uniongyrchol, oherwydd gallwn roi iddi ar ddamwain bwyntiau lle nad oes gan werthoedd search drwy'r weithdrefn ganlynol, sy'n gwirio pa un o'r pwyntiau terfyn sydd â gwerth ffwythiant negatif a pha un sydd â gwerth positif, ac yn galw'r weithdrefn search yn unol â hynny. Os oes gan y ffwythiant yr un arwydd ar y ddau bwynt a roddwyd, ni ellir defnyddio'r dull hanner cyfwng, ac yn yr achos hwnnw mae'r weithdrefn yn rhoi signal gwall.56
(define (half-interval-method f a b)
(let ((a-value (f a))
(b-value (f b)))
(cond ((and (negative? a-value)
(positive? b-value))
(search f a b))
((and (negative? b-value)
(positive? a-value))
(search f b a))
(else
(error "Values are not of
opposite sign" a b)))))Mae'r enghraifft ganlynol yn defnyddio'r dull hanner cyfwng i frasamcanu
(half-interval-method sin 2.0 4.0)
3.14111328125
Dyma enghraifft arall, sy'n defnyddio'r dull hanner cyfwng i chwilio am wreiddyn yr hafaliad
(half-interval-method
(lambda (x) (- (* x x x) (* 2 x) 3))
1.0
2.0)
1.89306640625
Canfod pwyntiau sefydlog ffwythiannau
Gelwir rhif fixed-point sy'n cymryd ffwythiant a dyfaliad cychwynnol yn fewnbynnau ac yn cynhyrchu brasamcan o bwynt sefydlog y ffwythiant. Cymhwyswn y ffwythiant dro ar ôl tro nes canfod dau werth olynol y mae eu gwahaniaeth yn llai na rhyw oddefiant penodedig:
(define tolerance 0.00001)
(define (fixed-point f first-guess)
(define (close-enough? v1 v2)
(< (abs (- v1 v2))
tolerance))
(define (try guess)
(let ((next (f guess)))
(if (close-enough? guess next)
next
(try next))))
(try first-guess))Er enghraifft, gallwn ddefnyddio'r dull hwn i frasamcanu pwynt sefydlog y ffwythiant cosin, gan ddechrau ag 1 fel brasamcan cychwynnol:57
(fixed-point cos 1.0)
.7390822985224023
Yn yr un modd, gallwn ganfod datrysiad i'r hafaliad
(fixed-point (lambda (y) (+ (sin y) (cos y)))
1.0)
1.2587315962971173
Mae'r broses pwynt sefydlog yn ein hatgoffa o'r broses a ddefnyddiasom i ganfod gwreiddiau sgwâr yn 1.1.7. Mae'r ddwy'n seiliedig ar y syniad o wella dyfaliad dro ar ôl tro nes bod y canlyniad yn bodloni rhyw faen prawf. Yn wir, gallwn lunio'r cyfrifiad gwreiddyn sgwâr yn rhwydd fel chwiliad am bwynt sefydlog. Mae cyfrifiannu gwreiddyn sgwâr rhyw rif
(define (sqrt x)
(fixed-point (lambda (y) (/ x y))
1.0))Yn anffodus, nid yw'r chwiliad hwn am bwynt sefydlog yn cydgyfeirio. Ystyriwch ddyfaliad cychwynnol
Un ffordd o reoli osgiliadau o'r fath yw atal y dyfaliadau rhag newid cymaint. Gan fod yr ateb bob amser rhwng ein dyfaliad
(define (sqrt x)
(fixed-point
(lambda (y) (average y (/ x y)))
1.0))(Sylwch fod
Gyda'r addasiad hwn, mae'r weithdrefn gwreiddyn sgwâr yn gweithio. Yn wir, os dadblethwn y diffiniadau, gallwn weld bod y dilyniant o frasamcanion o'r gwreiddyn sgwâr a gynhyrchir yma yn union yr un fath â'r un a gynhyrchwyd gan ein gweithdrefn gwreiddyn sgwâr wreiddiol yn 1.1.7. Yn aml, mae'r dull hwn o gyfartaleddu brasamcanion olynol o ddatrysiad, sef techneg a alwn yn ddampio drwy gyfartaleddu, yn helpu chwiliadau am bwyntiau sefydlog i gydgyfeirio.
Ymarfer 1.35: Dangoswch fod y gymhareb aur
(1.2.2) yn bwynt sefydlog y trawsffurfiad , a defnyddiwch y ffaith hon i gyfrifiannu drwy'r weithdrefn fixed-point.
Ymarfer 1.36: Addaswch
fixed-pointfel ei bod yn argraffu'r dilyniant o frasamcanion y mae'n eu cynhyrchu, gan ddefnyddio'r gweithdrefnau cyntefignewlineacdisplaya ddangosir yn Ymarfer 1.22. Yna canfyddwch ddatrysiad idrwy ganfod pwynt sefydlog . (Defnyddiwch weithdrefn gyntefig logScheme, sy'n cyfrifiannu logarithmau naturiol.) Cymharwch nifer y camau y mae hyn yn eu cymryd gyda dampio drwy gyfartaleddu a hebddo. (Sylwch na allwch ddechraufixed-pointâ dyfaliad o 1, gan y byddai hyn yn achosi rhannu â.)
- Mynegiad o'r ffurf
yw ffracsiwn parhaus anfeidraidd. Er enghraifft, gellir dangos bod yr ehangiad ffracsiwn parhaus anfeidraidd lle mae'r a'r i gyd yn hafal i 1 yn cynhyrchu , lle mai yw'r gymhareb aur (a ddisgrifir yn 1.2.2). Un ffordd o frasamcanu ffracsiwn parhaus anfeidraidd yw tocio'r ehangiad ar ôl nifer penodol o dermau. Mae gan docio o'r fath—sef ffracsiwn parhaus meidraidd ffracsiwn parhaus meidraidd o k term—y ffurf Tybiwch fod nacdyn weithdrefnau ag un arg (mynegai'r term) sy'n dychwelyd ac termau'r ffracsiwn parhaus. Diffiniwch weithdrefn cont-fracfel bod gwerthuso(cont-frac n d k)yn cyfrifiannu gwerth y ffracsiwn parhaus meidraidd oterm. Gwiriwch eich gweithdrefn drwy frasamcanu gan ddefnyddio (cont-frac (lambda (i) 1.0) (lambda (i) 1.0) k)ar gyfer gwerthoedd olynol
k. Pa mor fawr y mae'n rhaid gwneudker mwyn cael brasamcan sy'n gywir i 4 lle degol?- Os yw eich gweithdrefn
cont-fracyn cynhyrchu proses ddychweliadol, ysgrifennwch un sy'n cynhyrchu proses iteru. Os yw'n cynhyrchu proses iteru, ysgrifennwch un sy'n cynhyrchu proses ddychweliadol.
Ymarfer 1.38: Ym 1737, cyhoeddodd y mathemategydd Swisaidd Leonhard Euler draethawd De Fractionibus Continuis, a oedd yn cynnwys ehangiad ffracsiwn parhaus ar gyfer
, lle mai yw bôn y logarithmau naturiol. Yn y ffracsiwn hwn, mae'r i gyd yn 1, a'r yn olynol yn 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, …. Ysgrifennwch raglen sy'n defnyddio eich gweithdrefn cont-fraco Ymarfer 1.37 i frasamcanu, yn seiliedig ar ehangiad Euler.
Ymarfer 1.39: Cyhoeddwyd cynrychiolaeth ffracsiwn parhaus o'r ffwythiant tangiad ym 1770 gan y mathemategydd Almaenig J.H. Lambert:
lle mae mewn radianau. Diffiniwch weithdrefn (tan-cf x k)sy'n cyfrifiannu brasamcan o'r ffwythiant tangiad yn seiliedig ar fformiwla Lambert. Maekyn pennu nifer y termau i'w cyfrifiannu, fel yn Ymarfer 1.37.
1.3.4Gweithdrefnau fel Gwerthoedd a Ddychwelir
Mae'r enghreifftiau uchod yn dangos sut mae'r gallu i drosglwyddo gweithdrefnau yn argiau yn gwella grym mynegiannol ein hiaith raglennu yn sylweddol. Gallwn gael mwy fyth o rym mynegiannol drwy greu gweithdrefnau y mae'r gwerthoedd a ddychwelant eu hunain yn weithdrefnau.
Gallwn ddangos y syniad hwn drwy edrych eto ar yr enghraifft pwynt sefydlog a ddisgrifiwyd ar ddiwedd 1.3.3. Lluniasom fersiwn newydd o'r weithdrefn gwreiddyn sgwâr fel chwiliad am bwynt sefydlog, gan ddechrau â'r sylw fod
Gallwn fynegi'r syniad o ddampio drwy gyfartaleddu drwy'r weithdrefn ganlynol:
(define (average-damp f)
(lambda (x)
(average x (f x))))Gweithdrefn yw Average-damp sy'n cymryd gweithdrefn f yn arg ac yn dychwelyd gweithdrefn yn werth (a gynhyrchir gan y lambda) sydd, o'i chymhwyso i rif x, yn cynhyrchu cyfartaledd x ac (f x). Er enghraifft, mae cymhwyso average-damp i'r weithdrefn square yn cynhyrchu gweithdrefn y mae ei gwerth ar ryw rif
((average-damp square) 10)
55
Gan ddefnyddio average-damp, gallwn ail-lunio'r weithdrefn gwreiddyn sgwâr fel a ganlyn:
(define (sqrt x)
(fixed-point
(average-damp
(lambda (y) (/ x y)))
1.0))Sylwch sut mae'r ffurf hon yn gwneud y tri syniad yn y dull yn eglur: chwilio am bwynt sefydlog, dampio drwy gyfartaleddu, a'r ffwythiant
(define (cube-root x)
(fixed-point
(average-damp
(lambda (y)
(/ x (square y))))
1.0))Dull Newton
Pan gyflwynasom y weithdrefn gwreiddyn sgwâr gyntaf, yn 1.1.7, soniasom mai achos arbennig o ddull Newton oedd hon. Os yw
Ar gyfer llawer o ffwythiannau
Er mwyn gweithredu dull Newton fel gweithdrefn, rhaid inni fynegi'r syniad o ddeilliad yn gyntaf. Sylwch fod “deilliad,” fel dampio drwy gyfartaleddu, yn rhywbeth sy'n trawsffurfio ffwythiant yn ffwythiant arall. Er enghraifft, deilliad y ffwythiant
(define (deriv g)
(lambda (x)
(/ (- (g (+ x dx)) (g x))
dx)))ynghyd â'r diffiniad
(define dx 0.00001)Fel average-damp, mae deriv yn weithdrefn sy'n cymryd gweithdrefn yn arg ac yn dychwelyd gweithdrefn yn werth. Er enghraifft, i frasamcanu deilliad
(define (cube x) (* x x x))
((deriv cube) 5)
75.00014999664018
Gyda chymorth deriv, gallwn fynegi dull Newton fel proses pwynt sefydlog:
(define (newton-transform g)
(lambda (x)
(- x (/ (g x)
((deriv g) x)))))
(define (newtons-method g guess)
(fixed-point (newton-transform g)
guess))Mae'r weithdrefn newton-transform yn mynegi'r fformiwla ar ddechrau'r adran hon, a diffinnir newtons-method yn rhwydd yn nhermau hyn. Mae'n cymryd gweithdrefn sy'n cyfrifiannu'r ffwythiant yr ydym am ganfod sero iddo, ynghyd â dyfaliad cychwynnol, yn argiau. Er enghraifft, i ganfod gwreiddyn sgwâr
Mae hyn yn darparu ffurf arall eto ar y weithdrefn gwreiddyn sgwâr:
(define (sqrt x)
(newtons-method
(lambda (y)
(- (square y) x))
1.0))Haniaethau a gweithdrefnau dosbarth cyntaf
Rydym wedi gweld dwy ffordd o fynegi'r cyfrifiad gwreiddyn sgwâr fel enghraifft o ddull mwy cyffredinol, unwaith fel chwiliad am bwynt sefydlog ac unwaith drwy ddefnyddio dull Newton. Gan fod dull Newton ei hun wedi'i fynegi fel proses pwynt sefydlog, mewn gwirionedd gwelsom ddwy ffordd o gyfrifiannu gwreiddiau sgwâr fel pwyntiau sefydlog. Mae pob dull yn dechrau â ffwythiant ac yn canfod pwynt sefydlog rhyw drawsffurfiad o'r ffwythiant. Gallwn fynegi'r syniad cyffredinol hwn ei hun fel gweithdrefn:
(define (fixed-point-of-transform
g transform guess)
(fixed-point (transform g) guess))Mae'r weithdrefn gyffredinol iawn hon yn cymryd gweithdrefn g sy'n cyfrifiannu rhyw ffwythiant, gweithdrefn sy'n trawsffurfio g, a dyfaliad cychwynnol yn argiau. Y canlyniad a ddychwelir yw pwynt sefydlog y ffwythiant wedi'i drawsffurfio.
Gan ddefnyddio'r haniaeth hon, gallwn ail-lunio'r cyfrifiad gwreiddyn sgwâr cyntaf yn yr adran hon (lle chwiliwn am bwynt sefydlog y fersiwn o
(define (sqrt x)
(fixed-point-of-transform
(lambda (y) (/ x y))
average-damp
1.0))Yn yr un modd, gallwn fynegi'r ail gyfrifiad gwreiddyn sgwâr yn yr adran hon (enghraifft o ddull Newton sy'n canfod pwynt sefydlog trawsffurfiad Newton o
(define (sqrt x)
(fixed-point-of-transform
(lambda (y) (- (square y) x))
newton-transform
1.0))Dechreuasom adran 1.3 â'r sylw fod gweithdrefnau cyfansawdd yn fecanwaith haniaethu hanfodol, oherwydd eu bod yn caniatáu inni fynegi dulliau cyfrifiannu cyffredinol fel elfennau penodol yn ein hiaith raglennu. Nawr rydym wedi gweld sut mae gweithdrefnau trefn uwch yn caniatáu inni drin y dulliau cyffredinol hyn i greu haniaethau pellach.
Fel rhaglenwyr, dylem fod yn effro i gyfleoedd i adnabod yr haniaethau sylfaenol yn ein rhaglenni ac adeiladu arnynt a'u cyffredinoli i greu haniaethau mwy pwerus. Nid yw hyn yn golygu y dylid bob amser ysgrifennu rhaglenni yn y ffordd fwyaf haniaethol bosibl; mae rhaglenwyr arbenigol yn gwybod sut i ddewis y lefel haniaethu sy'n briodol i'w tasg. Ond mae'n bwysig gallu meddwl yn nhermau'r haniaethau hyn, er mwyn bod yn barod i'w cymhwyso mewn cyd-destunau newydd. Arwyddocâd gweithdrefnau trefn uwch yw eu bod yn ein galluogi i gynrychioli'r haniaethau hyn yn benodol fel elfennau yn ein hiaith raglennu, fel y gellir eu trin yn union fel elfennau cyfrifiadurol eraill.
Yn gyffredinol, mae ieithoedd rhaglennu yn gosod cyfyngiadau ar y ffyrdd y gellir trin elfennau cyfrifiadurol. Dywedir bod gan yr elfennau sydd â'r lleiaf o gyfyngiadau statws dosbarth cyntaf. Dyma rai o “hawliau a breintiau” elfennau dosbarth cyntaf:64
- Gellir eu henwi drwy newidynnau.
- Gellir eu trosglwyddo yn argiau i weithdrefnau.
- Gellir eu dychwelyd fel canlyniadau gweithdrefnau.
- Gellir eu cynnwys mewn strwythurau data.65
Mae Lisp, yn wahanol i ieithoedd rhaglennu cyffredin eraill, yn rhoi statws dosbarth cyntaf llawn i weithdrefnau. Mae hyn yn creu heriau o ran gweithredu effeithlon, ond mae'r cynnydd mewn grym mynegiannol yn enfawr.66
Ymarfer 1.40: Diffiniwch weithdrefn
cubicy gellir ei defnyddio ynghyd â'r weithdrefnnewtons-methodmewn mynegiadau o'r ffurf(newtons-method (cubic a b c) 1)i frasamcanu seroau'r ciwbig
.
Ymarfer 1.41: Diffiniwch weithdrefn
doublesy'n cymryd gweithdrefn ag un arg yn arg ac yn dychwelyd gweithdrefn sy'n cymhwyso'r weithdrefn wreiddiol ddwywaith. Er enghraifft, os ywincyn weithdrefn sy'n ychwanegu 1 at ei harg, yna dylai(double inc)fod yn weithdrefn sy'n ychwanegu 2. Pa werth a ddychwelir gan(((double (double double)) inc) 5)
Ymarfer 1.42: Gadewch i
ac fod yn ddau ffwythiant ag un arg. Diffinnir y cyfansoddiad ar ôl fel y ffwythiant . Diffiniwch weithdrefn composesy'n gweithredu cyfansoddi. Er enghraifft, os ywincyn weithdrefn sy'n ychwanegu 1 at ei harg,((compose square inc) 6) 49
Ymarfer 1.43: Os yw
yn ffwythiant rhifol ac os yw yn gyfanrif positif, yna gallwn ffurfio cymhwysiad ailadroddus o , a ddiffinnir fel y ffwythiant y mae ei werth ar yn . Er enghraifft, os mai yw'r ffwythiant , yna cymhwysiad ailadroddus o yw'r ffwythiant . Os mai yw'r gweithrediad o sgwario rhif, yna cymhwysiad ailadroddus o yw'r ffwythiant sy'n codi ei arg i'r pŵer . Ysgrifennwch weithdrefn sy'n cymryd gweithdrefn sy'n cyfrifiannu a chyfanrif positif yn fewnbynnau, ac yn dychwelyd y weithdrefn sy'n cyfrifiannu cymhwysiad ailadroddus o . Dylai fod modd defnyddio eich gweithdrefn fel a ganlyn: ((repeated square 2) 5) 625Awgrym: efallai y bydd defnyddio
composeo Ymarfer 1.42 yn gyfleus.
Ymarfer 1.44: Mae'r syniad o lyfnhau ffwythiant yn gysyniad pwysig mewn prosesu signalau. Os yw
yn ffwythiant ac os yw yn rhyw rif bach, yna'r fersiwn lyfn o yw'r ffwythiant y mae ei werth mewn pwynt yn gyfartaledd , , ac . Ysgrifennwch weithdrefn smoothsy'n cymryd gweithdrefn sy'n cyfrifiannuyn fewnbwn ac yn dychwelyd gweithdrefn sy'n cyfrifiannu wedi'i lyfnhau. Weithiau mae'n werthfawr llyfnhau ffwythiant dro ar ôl tro (hynny yw, llyfnhau'r ffwythiant sydd wedi'i lyfnhau, ac ati) i gael y ffwythiant wedi'i lyfnhau n gwaith. Dangoswch sut i gynhyrchu'r ffwythiant wedi'i lyfnhau n gwaith o unrhyw ffwythiant penodol gan ddefnyddio smoothacrepeatedo Ymarfer 1.43.
Ymarfer 1.45: Gwelasom yn 1.3.3 nad yw ceisio cyfrifiannu gwreiddiau sgwâr drwy ganfod pwynt sefydlog
yn ddiniwed yn cydgyfeirio, ac y gellir unioni hyn drwy ddampio drwy gyfartaleddu. Mae'r un dull yn gweithio i ganfod gwreiddiau ciwb fel pwyntiau sefydlog wedi'i dampio drwy gyfartaleddu. Yn anffodus, nid yw'r broses yn gweithio ar gyfer gwreiddiau pedwerydd—nid yw un dampiad drwy gyfartaleddu yn ddigon i beri i chwiliad am bwynt sefydlog gydgyfeirio. Ar y llaw arall, os dampiwn drwy gyfartaleddu ddwywaith (h.y., defnyddio dampiad cyfartaleddu dampiad cyfartaleddu ), mae'r chwiliad am bwynt sefydlog yn cydgyfeirio. Gwnewch rai arbrofion i bennu faint o ddampiadau drwy gyfartaleddu sydd eu hangen i gyfrifiannu gwreiddiau fel chwiliad am bwynt sefydlog sy'n seiliedig ar ddampio drwy gyfartaleddu dro ar ôl tro. Defnyddiwch hyn i weithredu gweithdrefn syml ar gyfer cyfrifiannu gwreiddiau gan ddefnyddio fixed-point,average-damp, a gweithdrefnrepeatedYmarfer 1.43. Tybiwch fod unrhyw weithrediadau rhifyddol sydd eu hangen arnoch ar gael fel gweithrediadau cyntefig.
Ymarfer 1.46: Mae nifer o'r dulliau rhifiadol a ddisgrifir yn y bennod hon yn enghreifftiau o strategaeth gyfrifiadurol hynod gyffredinol a elwir yn welliant drwy iteru. Mae gwelliant drwy iteru yn dweud ein bod, i gyfrifiannu rhywbeth, yn dechrau â dyfaliad cychwynnol o'r ateb, yn profi a yw'r dyfaliad yn ddigon da, ac fel arall yn gwella'r dyfaliad ac yn parhau â'r broses gan ddefnyddio'r dyfaliad gwell yn ddyfaliad newydd. Ysgrifennwch weithdrefn
iterative-improvesy'n cymryd dwy weithdrefn yn argiau: dull o ddweud a yw dyfaliad yn ddigon da a dull o wella dyfaliad. DylaiIterative-improveddychwelyd yn werth weithdrefn sy'n cymryd dyfaliad yn arg ac yn parhau i wella'r dyfaliad nes ei fod yn ddigon da. Ailysgrifennwch weithdrefnsqrt1.1.7 a gweithdrefnfixed-point1.3.3 yn nhermauiterative-improve.
Troednodiadau
49 Leibniz a roddodd y gyfres hon, a ysgrifennir fel arfer yn y ffurf gyfwerth
50 Sylwch ein bod wedi defnyddio strwythur blociau (1.1.8) i fewnosod diffiniadau pi-next ac pi-term o fewn pi-sum, gan ei bod yn annhebygol y bydd y gweithdrefnau hyn yn ddefnyddiol at unrhyw ddiben arall. Byddwn yn gweld sut i gael gwared arnynt yn llwyr yn 1.3.2.
51 Bwriad Ymarfer 1.31 hyd at Ymarfer 1.33 yw dangos y grym mynegiannol a geir drwy ddefnyddio haniaeth briodol i uno llawer o weithrediadau sy'n ymddangos yn wahanol. Fodd bynnag, er bod cronni a hidlo yn syniadau cain, mae ein dwylo wedi'u clymu i ryw raddau wrth eu defnyddio ar hyn o bryd, gan nad oes gennym eto strwythurau data i ddarparu dulliau cyfuno addas ar gyfer yr haniaethau hyn. Byddwn yn dychwelyd at y syniadau hyn yn 2.2.3 pan ddangoswn sut i ddefnyddio dilyniannau fel rhyngwynebau ar gyfer cyfuno hidlyddion a chronwyr i adeiladu haniaethau mwy pwerus fyth. Byddwn yn gweld yno sut mae'r dulliau hyn yn dangos eu gwerth yn llawn fel ffordd bwerus a chain o ddylunio rhaglenni.
52 Darganfuwyd y fformiwla hon gan y mathemategydd Seisnig o'r ail ganrif ar bymtheg John Wallis.
53 Byddai'n gliriach ac yn llai brawychus i bobl sy'n dysgu Lisp pe defnyddid enw mwy amlwg nag lambda, megis make-procedure. Ond mae'r confensiwn wedi hen ymsefydlu. Mabwysiadwyd y nodiant o'r calcwlws λ, ffurfiadaeth fathemategol a gyflwynwyd gan y rhesymegydd mathemategol Alonzo Church (1941). Datblygodd Church y calcwlws λ i ddarparu sylfaen drylwyr ar gyfer astudio'r syniadau o ffwythiant a chymhwyso ffwythiant. Mae'r calcwlws λ wedi dod yn arf sylfaenol ar gyfer ymchwiliadau mathemategol i semanteg ieithoedd rhaglennu.
54 Mae deall diffiniadau mewnol yn ddigon da i fod yn sicr fod rhaglen yn golygu'r hyn a fwriadwn yn gofyn am fodel mwy cymhleth o'r broses werthuso na'r un a gyflwynasom yn y bennod hon. Fodd bynnag, nid yw'r cynildeb hwn yn codi gyda diffiniadau mewnol o weithdrefnau. Byddwn yn dychwelyd at y mater hwn yn 4.1.6, ar ôl dysgu rhagor am werthuso.
55 Defnyddiasom 0.001 fel rhif “bach” cynrychioliadol i ddynodi goddefiant ar gyfer y gwall derbyniol mewn cyfrifiad. Mae'r goddefiant priodol ar gyfer cyfrifiad go iawn yn dibynnu ar y broblem sydd i'w datrys a chyfyngiadau'r cyfrifiadur a'r algorithm. Mae hyn yn aml yn ystyriaeth gynnil iawn, sy'n gofyn am gymorth dadansoddwr rhifiadol neu ryw fath arall o ddewin.
56 Gellir cyflawni hyn drwy ddefnyddio error, sy'n cymryd nifer o eitemau yn argiau ac yn eu hargraffu fel negeseuon gwall.
57 Rhowch gynnig ar hyn yn ystod darlith ddiflas: gosodwch eich cyfrifiannell yn y modd radianau ac yna pwyswch y botwm cos dro ar ôl tro nes cael y pwynt sefydlog.
58 lambda. Mae (lambda (y) (/ x y)), hynny yw, y ffwythiant y mae ei werth ar
59 Sylwch mai cyfuniad yw hwn y mae ei weithredydd ei hun yn gyfuniad. Roedd Ymarfer 1.4 eisoes wedi dangos y gallu i ffurfio cyfuniadau o'r fath, ond dim ond enghraifft degan oedd honno. Yma dechreuwn weld yr angen go iawn am gyfuniadau o'r fath—wrth gymhwyso gweithdrefn a geir fel y gwerth a ddychwelir gan weithdrefn trefn uwch.
60 Gweler Ymarfer 1.45 am gyffredinoliad pellach.
61 Fel arfer, mae llyfrau calcwlws elfennol yn disgrifio dull Newton yn nhermau'r dilyniant o frasamcanion
62 Nid yw dull Newton bob amser yn cydgyfeirio at ateb, ond gellir dangos, mewn achosion ffafriol, fod pob iteriad yn dyblu nifer y digidau cywir yn y brasamcan o'r datrysiad. Mewn achosion o'r fath, bydd dull Newton yn cydgyfeirio'n llawer cyflymach na'r dull hanner cyfwng.
63 Ar gyfer canfod gwreiddiau sgwâr, mae dull Newton yn cydgyfeirio'n gyflym at y datrysiad cywir o unrhyw fan cychwyn.
64 Y gwyddonydd cyfrifiadurol Prydeinig Christopher Strachey (1916-1975) a gyflwynodd y syniad o statws dosbarth cyntaf elfennau ieithoedd rhaglennu.
66 Prif gost gweithredu gweithdrefnau dosbarth cyntaf yw bod caniatáu dychwelyd gweithdrefnau yn werthoedd yn gofyn am gadw lle storio ar gyfer newidynnau rhydd gweithdrefn hyd yn oed pan nad yw'r weithdrefn yn rhedeg. Yng ngweithrediad Scheme y byddwn yn ei astudio yn 4.1, cedwir y newidynnau hyn yn amgylchedd y weithdrefn.