FÖRELÄSNING 2 Viss repetition av Fö1 Rekursivt fallanalys Rekursiva beskrivningar BEGREPP HITTILLS Konstant, Namn, Procedur/Funktion, LAMBDA, Parameter, Argument, Kropp, Villkor/Rekursion, Funktionsanrop, Substitutionsmodellen Rekursiva och iterativa processer Scope för namn 1 2 DATORSPRÅK primitiva uttryck (primitive expressions) sammansättningsregler (means of combination) - Procedursammansättning - Sammansättning av primitivdata för att få sammansatt data abstraktioner (means of abstraction) - Svartlåda-tänkande (möjlighet att ignorera detaljer) - Högre-ordningens procedurer - Dataabstraktion - Procedurer som data SAMMANSATTA UTTRYCK - SCHEME Applikation av inbyggda procedurer (inbyggd-fn argument-1 argument-2 argument-n) Applikation av användardefinierade procedurer (användar-fn argument-1 argument-2... argument-n) Undantagsformer (if villkor då-uttrycket annars-uttrycket) (and uttryck-1 uttryck-2 uttryck-n) (or uttryck-1 uttryck-2... uttryck-n) Abstractionsmöjligheter (define namn värde) (lambda parametrar kropp) 3 4
PROGRAMMERING PROGRAMEXEMPEL: AVSTÅNDET MELLAN TVÅ PUNKTER problem problemanalys ~ fallanalys översättning av analysresultatet till programkod testning (define distance (lambda (x1 y1 x2 y2) ( s q r t ( + ( s q u a r e ( - x 2 x 1 ) ) (square (- y2 y1)))))) (define square (lambda (n) (* n n))) 5 6 SUBSTITUTIONSMODELLEN (distance 0 0 3 4) (sqrt (+ (square (- 3 0)) (square (- 4 0)))) (sqrt (+ (square 3) (square 4))))) (sqrt (+ (* 3 3) (* 4 4))) (sqrt (+ 9 16)) (sqrt 25) 5 EVALUERING AV FUNKTIONSANROP/SUBSTITUTIONSMODELL För att evaluera ett anrop som (fn arg1 arg2 argn) Evaluera fn till det entitet den representerar Evaluera argumenten arg1 arg2 argn Ersätt förekomster av parametrar i procedurens kropp med motsvarande argument och evaluera sedan kroppen Detta sätt kallas för det applikativa substitutionsmodellen för beräkning 7 8
UNDANTAGSFORMEN IF Medan alla funktionsanrop evalueras enligt en och samma regel som beskrevs nyss, evalueras undantagsformer (special forms) på andra sätt t ex (if villkor då-uttryck annars-uttrycket) Evaluera villkor, om sant evaluera sedan då-uttrycket annars evaluera annars-uttrycket Resultatet blir antingen värdet på då-uttrycket eller annars-uttrycket SPECIALFORMEN COND (cond (villkor-1 då-uttryck-1) (villkor-2 då-uttryck-2)... (villkor-n då-uttryck-n)) Evaluera villkor-1, om sant, evaluera sedan då-uttryck-1, annars gå till nästa i ordningen Någon av villkoren måste vara sant annars blir det fel Genom att låta villkor-n vara nyckelordet ELSE garanterar vi att då-uttryck-n evalueras i fall de tidigare villkoren varit falska. Så här: (cond (villkor-1 då-uttryck-1) (villkor-2 då-uttryck-2)... (ELSE då-uttryck-n)) 9 10 SPECIALFORMEN AND (and arg-1 arg-2...) SPECIALFORMEN OR (or arg-1 arg-2...) Evaluera argumenten från vänster till höger tills ett falskt värde #f fås, i så fall är and-uttryckets värde #f, annars #t. Evaluera argumenten från vänster till höger till ett #t värde fås, i så fall är värdet på or-uttrycket #t, annars #f 11 12
FÖLJANDE ÄR EKVIVALENTA (FRÅN FÖ 1) (cond ((> x 0) x) ((= x 0) 0) ((< x 0) (- x))) (cond ((> x 0) x) ((= x 0) 0) (else (- x))) (if (> x 0) x (if (= x 0) 0 (- x))) REKURSIVT FALLANALYS Rekursion är ett sätt att få datorn att snurra Rekursion är ett sätt att bryta ner problem till enklare (mindre) problem Beräkningar definieras i termer av sig själva Ett termineringsfall är alltid nödvändigt Ganska vanligt inom matten, t ex, fakultetsfunktionens beskrivning: n! = n(n-1)! när n > 0 0! = 1 13 14 FIBONACCITALEN FIBONACCITALEN 0, 1, 1, 2, 3, 5, 8, 13, Fallanalys fib(0) = 0 fib(1) = 1 fib(n) = fib(n-1)+fib(n-2) (define fib (lambda (n) (cond ((= n 0) 0) ((= n 1) 1) (else (+ (fib (- n 1)) (fib (- n 2))))))) 15 16
FIBONACCITALEN - FALLANALYS 2 0, 1, 1, 2, 3, 5, 8, 13, Fallanalys fibo(0) = 0 fibo(1) = 1 fibo(n) = fibo-iter(n, 0, 1, 1) fibo-iter(n, f0, f1, räknare) = f1 om (n = räknare) fibo-iter(n, f1, f0+f1, räknare+1) annars ITERATIV FIBONACCI (define fibi (lambda (n) (cond ((= n 0) 0) ((= n 1) 1) (else (fiter n 0 1 1))))) (define fibi-iter (lambda (n f0 f1 count) (if (= count n) f1 (fibi-iter n f1 (+ f0 f1) (+ count 1))))) 17 18 FIBONACCITALEN - FALLANALYS 3 0, 1, 1, 2, 3, 5, 8, 13, Fallanalys fibi(0) = 0 fibi(1) = 1 fibi(n) = iter(n, 0, 1) iter(n, f0, f1) = f1 om (n = 1) iter(n-1, f1, f0+f1) annars FALLANALYS Uppdelning av ett större problem i enklare fall kräver att man jobbar med problemet Sällan kommer man på alla korrekta fallen direkt Ibland blir man tvungen att testa ett ofullständigt fallanalys för att bekanta sig med problemet ännu mer - förhoppningsvis kommer man på en fullständig lösning sedan Ibland måste man hitta på flera alternativa fallanalys och bara då kan välja den bästa uppdelningen 19 20
FALLANALYS - YTTERLIGARE EXEMPEL 1 5 5 4 3 2 1 4 4 3 2 1 2 j 3 3 2 1 2 3 2 2 1 2 3 4 1 1 2 3 4 5 1 2 3 4 5 i Fallanalys f(i,j) = j om (i=1) i om (j=1) 1 om (i=j) i-j +1 annars REKURSIVA BESKRIVNINGAR Vissa program kan formuleras som rekursiva beskrivningar (rekursivt fallanalys) Lösningar bryts ner till ett eller flera triviala fall (basfall) och ett eller flera generella fall. De generella fallen är nerskalade varianter på det ursprungliga problemet och därmed självreferens eller rekursion i lösningen Eller? 21 22 PROCEDURER OCH PROCESSER När en procedur evalueras genereras en process. Processerna kan antingen vara Rekursiva, eller Iterativa Rekursiva processer i sin tur kan antingen utgöra en linjär rekursion eller trädrekursion OBS! att i både fallen kan proceduren ha definierats som en rekursiv beskrivning (anropar sig själv) LINJÄR REKURSIVA PROCESSER Procedurbeskrivningen innehåller anrop till sig själv (se fact) Varje rekursivt anrop skapar en fördröjd operation, den fördröjda operationen kombinerar resultatet på det rekursiva anropet med annat, med andra ord, Rekursiva anropet ingår i ett resultat genereande uttrycket Tidskomplexiteten (behovet av beräkningstid) växer linjärt relativt parameterns storlek. I ordonotation: O(n) Rymdkomplexiteten (behovet av datorminne) växer linjärt relativt parameterns storlek. I ordonotation: O(n) 23 24
ITERATIVA PROCESSER Ett rekursivt anrop (se fibo eller fibi) Rekursiva anropet skapar inga fördröjda beräkningar Rekursiva anropet är svaret (ingår inte i annat uttryck) Tidskomplexiteten (behovet av beräkningstid) växer linjärt relativt parameterns storlek. I ordonotation: O(n) Rymdkomplexiteten (behovet av datorminne) är konstant och oberoende av parameterns storlek. I ordonotation: O(k) eller O(1) TRÄDREKURSIVA PROCESSER Proceduren innehåller multipla rekursiva ansrop till själv (se fib) Resultatuttrycket vanligtvis kombinerar resultaten från de rekursiva anropen Fördröjda operationer växer som träd (förgreningen är beroende av antal rekursiva anrop i ett och samma resultatuttryck, t ex, i Fibonacci är förgreningen 2) Tidskomplexiteten växer exponentiellt O(k n ), där k är antalet multipla anrop, t ex, i rekursiva Fibonacci (fib), k=2 Rymdkomplexiteten växer linjärt O(n) 25 26 UPPGIFT f(n) = n if n<3 f(n) = f(n-1)+2f(n-2)+3f(n-3) annars Skriv Schemeprocedurer som implementerar f(n) både som rekursivoch interaktiv process. Försök följa samma mönster som lösningarna för Fibonaccitalen 27