Förra gången: Primitiva data > 30 30 > 45.56 45.56 Variabler: > (define telnr 6000) > telnr 6000 DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 1 / 24
Förra gången: Procedurapplikation: > (+ 7900000 telnr) 7906000 > (sqrt (+ (expt (- 10 4.5) 2) (expt (- 13.3 3.4) 2))) 11.3251931550857 DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 2 / 24
I dag: Användardefinierade procedurer I vilken ordning beräknas uttryck? Hur definierar man egna procedurer? Hur beräknar man egna procedurer? Hur använder man villkorliga uttryck? Bra om du läst följande avsnitt i AS: Compound Procedures, The Substitution Model for Procedure Application samt Conditional Expression and Predicates. DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 3 / 24
Beräkningsordning för uttryck > (+ (* 2 3) (* 3 4)) Representerat m.hj.a. träd: + * * 2 3 3 4 DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 4 / 24
Motivering Antag att vi vill beräkna kraften f som krävs för att accelerera en fast kropp med massan m och accelerationen a, enligt Newtons lag: m och a förutsätts vara kända. Detta kan vi göra enligt följande steg: (1) > (define m 100) Vi antar att m är 100 kg. (2) > (define a 50) Vi antar dessutom att a är 50 m/s 2. (3) > (define f (* m a)) Sedan beräknar vi kraften f. (4) > f Slutligen ber vi om resultatet. 5000 DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 5 / 24
Motivering... Säg nu att vi ändrar massan m till 200 kg och a är oförändrad. Hur ska vi beräkna f då? DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 6 / 24
Omdefinition av variabler En redan definierad variabel kan omdefinieras med hjälp av en ny definition. > (define m 200) > m 200 Från och med nu, har m värdet 200. Det gamla värdet 100 är bortglömt. Då m har ändrats till 200, är f fortfarande oförändrad. > a 50 > f 5000 DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 7 / 24
Omdefinition av variabler... För att f ska beräknas med hänsyn till det förändrade värdet på m, måste f också beräknas på nytt med en ny definition: > (define f (* m a)) > f 10000 DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 8 / 24
Definition av procedurer Det föregående sättet att använda Newtons formel innebär att samma definition ska skrivas upprepade gånger. Det kan bli lite trist att skriva om samma (långa) formel om och om igen. En lösning är att definiera en procedur för formeln: (lambda (m a) (* m a)) lambda skapar en procedur, m och a anger de 2 formella parametrarna samt deras namn och uttrycket (* m a) är den s.k. procedurkroppen där beräkningen görs (i detta fall). Observera att denna procedur inte har något namn, det är en s.k. anonym procedur. DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 9 / 24
Definition av procedurer... För att proceduren ska bli mer användbar, namnge den m.hj.a. define (define f (lambda (m a) (* m a))) där force kallas för procedurnamn. Man kan använda ett förkortat skrivsätt: (define (f m a) (* m a)) Det förkortade skrivsättet används i boken (AS), men jag kommer oftast använda det längre. DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 10 / 24
Definition av procedurer... Procedurdefinitionen av f i Scheme kan jämföras med den matematiska funktionsdefinitionen: f (m, a) = m a > (define m 100) > (define a 50) > (f m a) 5000 > (define m 200) > (f m a) 10000 DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 11 / 24
Fler egendefinierade procedurer... > (define square (lambda (x) (* x x))) > (square 3) 9 > (square (square 3)) 81 Vi kan använda square som en byggsten när vi konstruerar komplexa procedurer, till exempel för att räkna ut hypotenusan m.hj.a. Pythagoras sats. DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 12 / 24
Fler egendefinierade procedurer... > (define sum-of-square (lambda (x y) (+ (square x) (square y)))) > (sum-of-square 3 4) 25 > (define hypotenusa (lambda (kat1 kat2) (sqrt (sum-of-square kat1 kat2)))) > (hypotenusa 3 4) 5 DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 13 / 24
Beräkningsregler för egendefinierade procedurer Beräkningen av ett uttryck innehållande en egendefinierad procedur utförs genom substitution (substitutionsmodellen): Först ersätts procedurnamnet med procedurkroppen Sedan ersätts formella parametrarna med de aktuella parametrarna Vid beräkningen av t.ex. (hypotenusa 3 4) kommer uttrycket ersättas med procedurkroppen (sqrt (sum-of-square kat1 kat2)) där de formella parametrarna kat1 och kat2 ersätts med 3 och 4 DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 14 / 24
Beräkningsregler för egendefinierade procedurer... =>(sqrt (sum-of-square 3 4)) sum-of-square är i sin tur en egendefinierad procedur, och ersätts med sin procedurkropp vars formella parametrar sedan byts ut mot 3 och 4. =>(sqrt (+ (square 3) (square 4))) square är också egendefinierad procedur: =>(sqrt (+ (* 3 3) (* 4 4))) Då de innersta uttrycken bara innehåller primitiva procedurer, här *, beräknas de innersta uttrycken direkt: DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 15 / 24
Beräkningsregler för egendefinierade procedurer... =>(sqrt (+ 9 16)) =>(sqrt 25) =>5 DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 16 / 24
Villkorliga uttryck Scheme har stöd för hantering av booleska värden. Värdet sant representeras med #t och värdet falskt med #f. > (= 2 (+ 1 1)) ;; ett predikat #t > (= 2 (+ 1 2)) ;; eller booleskt uttryck #f DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 17 / 24
Villkorliga uttryck... Anta att vi vill definiera absoluta beloppet av ett tal i Scheme. Matematiskt kan det skrivas t.ex.: 0 om x = 0 x = x om x > 0 x om x < 0 men kan även skrivas (matematiskt): 0 om x = 0 x = x om x > 0 x annars DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 18 / 24
Villkorliga uttryck... Motsvarande definition i Scheme: > (define abs (lambda (x) (cond ((= x 0) 0) ((> x 0) x) ((< x 0) (- x))))) Ett cond-uttryck har följande form: (cond (predikat1 exp1) ;; alternativ 1 (predikat2 exp2) ;; alternativ 2 (predikat3 exp3) ;; alternativ 3... (predikatn expn));; alternativ n DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 19 / 24
Villkorliga uttryck... Ett cond-uttryck beräknas genom att beräkna predikaten i tur och ordning. När ett predikat returnerar #f ( falskt ), kommer nästa att beräknas. Beräkningen fortsätter tills något predikat returnerar sant. Vid det tillfället beräknas motsvarande uttryck vars värde returneras som värdet av cond-uttrycket. Resterande alternativa grenar hoppas över även om någon av dem skulle ha ett predikat vars beräkning skulle ge #t ( sant ) som resultat. Alternativa definitioner av abs: (define abs (lambda (x) (cond ((>= x 0) x) ((< x 0) (- x))))) DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 20 / 24
Villkorliga uttryck... (define abs (lambda (x) (cond ((>= x 0) x) (else (- x))))) else beräknas till det boolska värdet #t. if-uttryck kan ibland användas istället för cond (define abs (lambda (x) (if (>= x 0) ;; predikat x ;; konsekvens (- x)))) ;; alternativ DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 21 / 24
Villkorliga uttryck... De logiska operatorerna and och or är primitiva procedurer i Scheme: (define lessorequal (lambda (x y) (or (< x y) (= x y)))) (define between (lambda (x y z) (and (lessorequal x y) (lessorequal y z)))) DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 22 / 24
Villkorliga uttryck... Användande av between: > (between 3 4 5) #t > (between 3 2 5) #f DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 23 / 24
Nästa gång Rekursion! Läs gärna i AS: Example: Square Roots by Newton s Method samt Procedures as Black-Box Abstractions Procedures and the Processes They Generate Linear Recursion and Iteration Tree Recursion DA2001 (Föreläsning 3) Datalogi 1 Hösten 2013 24 / 24