Förändringsr dt (muteringsr dt?, eng. mutle dt) (define (list (list ) c d)) (define y (list e f)) Finns det ett sätt tt påverk strukturer uppygd med pr, som liknr set! för primitiv dt? c d Finns det ett sätt tt inte kopier strukturer vid list- eller träderetning? (Kom ihåg tt vrje cons eller list skpr ny celler.) y set-cr! set-cdr! e f Jcek Mlec, Dept. of Computer Science, Lund University 207 Jcek Mlec, Dept. of Computer Science, Lund University 208 (set-cr! y) (define z (cons y (cdr ))) c d c d z y y e f e f
(set-cdr! y) c d Fktiskt kn vi uttryck cons m.h.. set-cr!, set-cdr! och new (som skpr ett nytt, tomt pr): (define (cons y) (let ((new (get-new-pir))) (set-cr! new ) (set-cdr! new y) new)) En ny ppend: y e f (define (ppend y) (if (null? ) y (cons (cr ) (ppend (cdr ) y)))) (define (ppend! y) (set-cdr! (lst-pir ) y) ) (define (lst-pir ) (if (null? (cdr )) (lst-pir (cdr )))) Jcek Mlec, Dept. of Computer Science, Lund University 211 Jcek Mlec, Dept. of Computer Science, Lund University 212 Delning v celler, identitet (define (list )) (define z1 (cons )) (define z2 (cons (list ) (list ))) z2 z1
eq? vs. equl? eq? är snn för identisk ojekt (pilen pekr på smm sk). I synnerhet, ll tomer (symoler) är identisk (d.v.s. är lltid lik med ). Men med tl är det nnorlund, liksom med cellstrukturer. equl? är snn för ojekt som ser ut på smm sätt, d.v.s. hr smm struktur. I rent funktionell progrm (de som nvänder enrt cons, cr och cdr, liknnde vs. likheten spelr ingen roll - smm effekter ändå. Men i progrm som nvänder tilldelning är situtionen nnorlund: vi kn ändr en dtstruktur utn tt det direkt syns. Mutering och tilldelning är en och smm sk! Den gml versionen, utn tilldelning: (define (cons y) (define (disptch m) (cond ((eq? m cr) ) ((eq? m cdr) y) (else (error "Undefined opertion -- CONS" m)))) disptch) (define (cr z) (z cr)) (define (cdr z) (z cdr)) Jcek Mlec, Dept. of Computer Science, Lund University 215 Jcek Mlec, Dept. of Computer Science, Lund University 216 Versionen med tilldelning: (define (cons y) (define (set-! v) (set! v)) (define (set-y! v) (set! y v)) (define (disptch m) (cond ((eq? m cr) ) ((eq? m cdr) y) ((eq? m set-cr!) set-!) ((eq? m set-cdr!) set-y!) (else (error "Undefined opertion -- CONS" m)))) disptch) (define (cr z) (z cr)) (define (cdr z) (z cdr)) (define (set-cr! z new-vlue) ((z set-cr!) new-vlue) z) (define (set-cdr! z new-vlue) ((z set-cdr!) new-vlue) z) Köer Börjn (front) Slutet (end) q B B 1 2 3 4 (insert-queue! q 5) q B 1 2 3 4 5 (delete-queue! q) q 2 3 4 5 FIFO-uffert (First In First Out) S S S
Dtstrktionen: En ättre (Θ(1)) lösning: ett pr med en front-pekre och en slut-pekre Konstruktorn (mke-queue) Selektorer (empty-queue? kö), (front-queue kö) q front-ptr rer-ptr Muteringr (insert-queue! kö ojekt), (delete-queue! kö) En rimlig representtion en list Om vi hde endst en list, då voredet ineffektivt tt sättinettnyttelement (kompleitet Θ(n)) eftersom mn måste gå genom (cdr) hel listn. c (define (front-ptr queue) (cr queue)) (define (rer-ptr queue) (cdr queue)) (define (set-front-ptr! queue item) (set-cr! queue item)) (define (set-rer-ptr! queue item) (set-cdr! queue item)) (define (mke-queue) (cons () ())) Jcek Mlec, Dept. of Computer Science, Lund University 219 Jcek Mlec, Dept. of Computer Science, Lund University 220 (define (empty-queue? queue) (null? (front-ptr queue))) (define (front-queue queue) (if (empty-queue? queue) (error "FRONT clled with n empty queue" queue) (cr (front-ptr queue)))) (define (insert-queue! queue item) (let ((new-pir (cons item ()))) (cond ((empty-queue? queue) (set-front-ptr! queue new-pir) (set-rer-ptr! queue new-pir) queue) (else (set-cdr! (rer-ptr queue) new-pir) (set-rer-ptr! queue new-pir) queue)))) (define (delete-queue! queue) (cond ((empty-queue? queue) (error "DELETE! clled with n empty queue" queue)) (else (set-front-ptr! queue (cdr (front-ptr queue))) queue))) Nu hr vi llt som ehövs för tt mnipuler köer.
Implementtionsförslg: Teller Ett eempel (tänk på omdirigeringsteller från kpitel 2): v 1 v 2 y v 3 v 4 z v 5 v 6 Enklste fllet endimensionell teller: v 1 y v 2 v y v z v 1 2 3 Vi ehöver ett ryggen : t1 *tle* z v 3 v y v z v 1 2 3 Jcek Mlec, Dept. of Computer Science, Lund University 223 Jcek Mlec, Dept. of Computer Science, Lund University 224 Dtstrktionen Konstruktorn (mke-tle) Selektorn (lookup nyckel tell) Muttorn (insert! nyckel värde tell) (define (lookup key tle) (let ((record (ssoc key (cdr tle)))) (if record (cdr record) #f))) (define (ssoc key records) (cond ((null? records) #f) ((equl? key (cr records)) (cr records)) (else (ssoc key (cdr records))))) (define (insert! key vlue tle) (let ((record (ssoc key (cdr tle)))) (if record (set-cdr! record vlue) (set-cdr! tle (cons (cons key vlue) (cdr tle))))) ok)
Tvådimensionell teller t1 *tle* key1 v 4 key2 v 5 v y v z v 1 2 3 (define (lookup key-1 key-2 tle) (let ((sutle (ssoc key-1 (cdr tle)))) (if sutle (let ((record (ssoc key-2 (cdr sutle)))) (if record (cdr record) #f)) #f))) (define (insert! key-1 key-2 vlue tle) (let ((sutle (ssoc key-1 (cdr tle)))) (if sutle (let ((record (ssoc key-2 (cdr sutle)))) (if record (set-cdr! record vlue) (set-cdr! sutle (cons (cons key-2 vlue) (cdr sutle))))) (set-cdr! tle (cons (list key-1 (cons key-2 vlue)) (cdr tle))))) ok) Jcek Mlec, Dept. of Computer Science, Lund University 227 Jcek Mlec, Dept. of Computer Science, Lund University 228 Lokl teller (define (mke-tle) (let ((locl-tle (list *tle*))) (define (lookup key-1 key-2) (let ((sutle (ssoc key-1 (cdr locl-tle)))) (if sutle (let ((record (ssoc key-2 (cdr sutle)))) (if record (cdr record) #f)) #f))) (define (insert! key-1 key-2 vlue) (let ((sutle (ssoc key-1 (cdr locl-tle)))) (if sutle (let ((record (ssoc key-2 (cdr sutle)))) (if record (set-cdr! record vlue) (set-cdr! sutle (cons (cons key-2 vlue) (cdr sutle))))) (set-cdr! locl-tle (cons (list key-1 (cons key-2 vlue)) (cdr locl-tle))))) ok) (define (disptch m) (cond ((eq? m lookup-proc) lookup) ((eq? m insert-proc!) insert!) (else (error "Unknown opertion -- TABLE" m)))) disptch)) ;;; slut på (define (mke-tle) ;;; nyttig omdöpningr (define opertion-tle (mke-tle)) (define get (opertion-tle lookup-proc)) (define put (opertion-tle insert-proc!))
Två intressnt eempel 3.3.4 simulering v digitl kretsr 3.3.5 egränsning-serde eräkningr Händelsestyrd simulering v digitl kretsr (event-driven simultion) Ojekt: kopplingr (wires) med digitl (0 eller 1) signler melln grindr grindr (function oes) (not, icke) Kopplingrn modellers som ojekt som innehåller: signl (0 eller 1) Primitiver: get-signl, set-signl! ction-procedurer, som utförs när en signl ändrs Primitiv: dd-ction! för tt lägg till en ny procedur till en koppling (nd, och) Grindrn modellers som procedurer. (or, eller) Jcek Mlec, Dept. of Computer Science, Lund University 231 Jcek Mlec, Dept. of Computer Science, Lund University 232 Hlv-dderre A B (define (mke-wire)) (define (mke-wire)) (define c (mke-wire)) (define d (mke-wire)) (define e (mke-wire)) (define s (mke-wire)) (or-gte d) (nd-gte c) (inverter c e) (nd-gte d e s) D E S C (define (hlf-dder s c) (let ((d (mke-wire)) (e (mke-wire))) (or-gte d) (nd-gte c) (inverter c e) (nd-gte d e s) ok)) (define (full-dder c-in sum c-out) (let ((s (mke-wire)) (c1 (mke-wire)) (c2 (mke-wire))) (hlf-dder c-in s c1) (hlf-dder s sum c2) (or-gte c1 c2 c-out) ok)) A B Cin hlv dderre hlv dderre S Cout
Eempel Astrktioner (get-signl wire) (set-signl! (dd-ction! wire new-vlue) wire procedure) dd-ction! sätter proceduren procedure på listn v de, som ör körs lltid när signlen ändrs. På dett sätt förflytts signländringen vidre i systemet. fter-dely dely procedure) fter-dely evluerr proceduren procedure efter fördröjningen dely (define (inverter input output) (define (invert-input) (let ((new-vlue (logicl-not (get-signl input)))) (fter-dely inverter-dely (lmd () (set-signl! output new-vlue))))) (dd-ction! input invert-input) ok) (define (logicl-not s) (cond ((= s 0) 1) ((= s 1) 0) (else (error "Invlid signl" s)))) Jcek Mlec, Dept. of Computer Science, Lund University 235 Jcek Mlec, Dept. of Computer Science, Lund University 236 Eempel - forts. (define (nd-gte 1 2 output) (define (nd-ction-procedure) (let ((new-vlue (logicl-nd (get-signl 1) (get-signl 2)))) (fter-dely nd-gte-dely (lmd () (set-signl! output new-vlue))))) (dd-ction! 1 nd-ction-procedure) (dd-ction! 2 nd-ction-procedure) ok) Vi hr skpt en modell för logisk kretsr genom tt skp ett språk(!) (se vsnitt 1.1 i kursoken) som hr: primitive epressions grundläggnde ojekt mens of comintion smmnsättning v ojekt från mer grundläggnde ojekt mens of strction smmnstt ojekt kn ges nmn och hnters som en enhet Sedn ehöver vi en evlutor för vårt språk. Evlutorn är intressnt eftersom den är åde: tidsstyrd progrmdelr läggs på kö och väntr på sin tur tt eräkns propgernde om en ändring sker så skll den propgers vidre Tillsmmns: händelsestyrd simulering
Kopplingrn En koppling är en procedurojekt med två tillstånd: signlvärde (0 eller 1) Tid i systemet Vid vrje grind uppstår en tidsfördröjning. Vi introducerr en konstnt tidsfördröjning (inverter-dely, nd-gte-dely, etc.) för vrje grindtyp. list v de ction-procedurer som skll utförs när en signl ändrs Primitiver: (define (get-signl wire) (wire get-signl)) (define (set-signl! wire new-vlue) ((wire set-signl!) new-vlue)) (define (dd-ction! wire ction-procedure) ((wire dd-ction!) ction-procedure)) Jcek Mlec, Dept. of Computer Science, Lund University 239 Jcek Mlec, Dept. of Computer Science, Lund University 240 (define (mke-wire) (let ((signl-vlue 0) (ction-procedures ())) (define (set-my-signl! new-vlue) (if (not (= signl-vlue new-vlue)) (egin (set! signl-vlue new-vlue) (cll-ech ction-procedures)) done)) (define (ccept-ction-procedure! proc) (set! ction-procedures (cons proc ction-procedures)) (proc)) ;;; (define (mke-wire)...) fortsätter ;;; på näst ild ;;; (define (mke-wire)...) fortsätter här (define (disptch m) (cond ((eq? m get-signl) signl-vlue) ((eq? m set-signl!) set-my-signl!) ((eq? m dd-ction!) ccept-ction-procedure!) (else (error "Unknown opertion -- WIRE" m)))) disptch)) (define (cll-ech procedures) (if (null? procedures) done (egin ((cr procedures)) (cll-ech (cdr procedures)))))
Simuleringsrutinen Efetrsom simuleringen är tidseroende skpr vi en gend där vi lgrr vrje händelse med tiden då händelsen skll utförs. Skp gendn: (define the-gend (mke-gend)) Lägg til ny händelse med en fördröjning: (define (fter-dely dely ction) (dd-to-gend! (+ dely (current-time the-gend)) ction the-gend)) Drivrutinen: (define (propgte) (if (empty-gend? the-gend) done (let ((first-item (first-gend-item the-gend))) (first-item) (remove-first-gend-item! the-gend) (propgte)))) Jcek Mlec, Dept. of Computer Science, Lund University 243 Jcek Mlec, Dept. of Computer Science, Lund University 244 Eempel Hjälpfunktionen (för tt oserver simuleringen): (define (proe nme wire) (dd-ction! wire (lmd () (newline) (disply nme) (disply " ") (disply (current-time the-gend)) (disply " New-vlue= ") (disply (get-signl wire))))) (define the-gend (mke-gend)) (define inverter-dely 2) (define nd-gte-dely 3) (define or-gte-dely 5) (define input-1 (mke-wire)) (define input-2 (mke-wire)) (define sum (mke-wire)) (define crry (mke-wire)) (hlf-dder input-1 input-2 sum crry) ;;; skriv ut vid ändring (proe sum sum) (proe crry crry) (set-signl! input-1 1) (propgte) sum hr ändrts, tid=8, nyt värde=1 (set-signl! input-2 1) (propgte) crry hr ändrts, tid=11, nyt värde=1 sum hr ändrts, tid=16, nyt värde=0