INF2810: Funksjonell Programmering. Dataabstraksjon og Trerekursjon

Like dokumenter
INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering. Lokale variabler. Og trær.

INF2810: Funksjonell Programmering. Lokale variabler. Og trær.

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

Høyere-ordens prosedyrer

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

INF2810: Funksjonell Programmering. Trær og mengder

INF2810: Funksjonell Programmering

INF2810: Funksjonell Programmering

Rekursjon og lister. Stephan Oepen & Erik Velldal. 1. februar, Universitetet i Oslo

INF2810: Funksjonell Programmering. Kommentarer til prøveeksamen

INF2810: Funksjonell Programmering. Mer om verditilordning. Tabeller. Og strømmer.

INF2810: Funksjonell Programmering. Mer om verditilordning. Tabeller. Og strømmer.

INF2810: Funksjonell Programmering. Strømmer og utsatt evaluering

UNIVERSITETET I OSLO

INF2810: Funksjonell Programmering. Eksamensforberedelser

INF2810: Funksjonell Programmering. Huffman-koding

INF2810: Funksjonell Programmering. Mer om verditilordning og muterbare data.

INF2810: Funksjonell Programmering. Huffman-koding

INF2810: Funksjonell Programmering. Mer om verditilordning og muterbare data.

INF2810: Funksjonell Programmering. Strømmer

INF2810: Funksjonell Programmering. En metasirkulær evaluator

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme

INF2810: Funksjonell Programmering. En metasirkulær evaluator

INF2810: Funksjonell Programmering. Strømmer

UNIVERSITETET I OSLO

INF2810: Funksjonell Programmering. Køer, tabeller, og (litt om) parallelitet

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Strømmer og utsatt evaluering

INF2810: Funksjonell Programmering. Lister og høyereordens prosedyrer

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Køer, tabeller, og (litt om) parallelitet

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

INF2810: Funksjonell Programmering. En metasirkulær evaluator, del 2

INF2810: Funksjonell Programmering. En metasirkulær evaluator, del 2

INF2810: Funksjonell Programmering. Mengder og lokal tilstand

INF2810: Funksjonell Programmering. Mer om strømmer

INF2810: Funksjonell Programmering. Muterbare data

INF2810: Funksjonell Programmering. Tilstand og verditilordning

INF2810: Funksjonell Programmering. Mer om strømmer

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

INF2810: Funksjonell programmering: Mer om Scheme. Rekursjon og iterasjon.

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Huffmankoding

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Utsatt evaluering og strømmer

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Oppsummering og eksamensforberedelser

INF2810: Funksjonell Programmering. Huffman-koding

Par og Lister (først et par sider fra forrige uke) Par er byggestener for lister og trær og sammensatte datatyper.

Innlevering 2a i INF2810, vår 2017

Side 1. Oppgave 1. Prosedyrer 1.1. Prosedyrene f og g skal begge returnere prosedyrer. a. Skriv f slik at ((f a) b) returnerer summen av a og b.

INF2810: Funksjonell Programmering. Huffman-koding

IN2040: Funksjonell programmering. Trær, mengder og huffmankoding

INF2810: Funksjonell Programmering. Huffman-koding

Vi skal se på lambda-uttrykk. Følgende er definerte og vil bli brukt gjennom oppgaven

UNIVERSITETET I OSLO

Eksamen i HUMIT 2710, Funksjonell programmering, våren Ingen hjelpemidler er tillatt. <resten av forsiden> Side 1 av 7

UNIVERSITETET I OSLO

Innlevering 2b i INF2810, vår 2017

(define (naer-nok-kuberot? y x) (< (abs (- (kube y) x)) 0.001)) (define (naermere-kuberot y x) (/ (+ (* y 2) (/ x (kvadrat y))) 3))

INF2810: Funksjonell programmering: Introduksjon

Eksamen i SLI230, vår 2003.

INF2810: Funksjonell Programmering. Huffman-koding

INF2810: Funksjonell Programmering. Muterbare data

Gjennomgåelse av eksamensoppgaven i HUMIT2710 fra våren 2004

Det er ikke tillatt med andre hjelpemidler enn de to sidene som er vedlagt oppgavesettet. Følgende funksjoner er definert og brukes i oppgaven:

Oppgave 1 Minimum edit distance

INF2810: Funksjonell Programmering. Mer om Scheme. Rekursjon og iterasjon.

INF2810: Funksjonell Programmering. Eksamensforberedelser

Memoisering, utsatt evaluering og strømmer

Memoisering, utsatt evaluering og strømmer

Par og Lister (først et par sider fra forrige uke) Par er byggestener for lister og trær og sammensatte datatyper.

INF2810: Funksjonell programmering: Introduksjon

INF2810: Funksjonell Programmering. Mer om Scheme. Rekursjon og iterasjon.

INF2810: Funksjonell Programmering. Mer om Scheme. Rekursjon og iterasjon.

UNIVERSITETET I OSLO

LISP PVV-kurs 25. oktober 2012

INF2220: Forelesning 1. Praktisk informasjon Analyse av algoritmer (kapittel 2) (Binær)trær (kapittel )

INF2810: Funksjonell Programmering. Introduksjon

Plan: Parameter-overføring Alias Typer (Ghezzi&Jazayeri kap.3 frem til 3.3.1) IN 211 Programmeringsspråk

INF3110 Programmeringsspråk. Dagens tema. Typer (Kapittel 3 frem til ) Innføring i ML (Kapittel & ML-kompendiet.) 1/19

Typer. 1 Type: boolean. 2 Verdimengde: {true, false} 3 Operatorer: NOT, AND, OR... 1/19. Forelesning Forelesning

Appendiks A Kontinuasjoner

Innhold uke 7. Objektorientert programmering i Python: Introduksjon. Lite tilbakeblikk: Programflyt og skop. Lite tilbakeblikk: Funksjoner er uttrykk

INF110 Algoritmer og datastrukturer TRÆR. Vi skal i denne forelesningen se litt på ulike typer trær:

UNIVERSITETET I OSLO

INF Gruppelærerenes side

Transkript:

INF2810: Funksjonell Programmering Dataabstraksjon og Trerekursjon Stephan Oepen & Erik Velldal Universitetet i Oslo 15. februar, 2013

Tema 2 Forrige uke Høyere-ordens prosedyrer: Prosedyrer som argumenter Prosedyrer som returverdi Lokale Variabler I dag Noe repetisjon Dataabstraksjon Lister av lister Trerekursjon

reduce 3 En annen klassisk høyere-ordens prosedyre (ved siden av map):? (define (reduce proc init items) (if (null? items) init (proc (car items) (reduce proc init (cdr items)))))? (reduce + 0 (1 2 3 4 5)) 15? (reduce * 1 (1 2 3 4 5)) 120? (reduce cons () (1 2 3 4 5)) (1 2 3 4 5)? (reduce max 0 (1 2 3 4 5)) 5 reduce er også kjent som fold, compress, accumulate, eller inject.

Eksempel på bruk av map + reduce 4 Gitt to vektorer a = 2, 1, 3 b = 1, 3, 0 (define a (list 2 1 3)) (define b (list 1 3 0)) så beregnes prikk-produktet som x y = i x i y i a b = 2 1 + 1 3 + 3 0 = 5 Versjon 2 med modulær design: kjede av høyere-ordens operasjoner over sekvenser. sekvenser som konvensjonell grensesnitt i SICP-terminologi. (define (dot-product x y) (if (null? x) 0 (+ (* (car x) (car y)) (dot-product (cdr x) (cdr y))))) (define (dot-product x y) (reduce + 0 (map * x y))) (dot-product a b) 5

lambda-uttrykk 5? (define square (lambda (x) (* x x)))? (square 4) 16? ((lambda (x) (* x x))) 4) 16? (map (lambda (x) (* x 0.1)) (2 3 4)) (0.2 0.3 0.4)? (map (lambda (x) (list x (* x x))) (2 3 4)) ((2 4) (3 9) (4 16)) lambda-uttrykk returnerer prosedyrer. Trenger ikke nødvendigvis bindes til et symbol; Kan kalles direkte som såkalt anonyme prosedyrer. Brukes ofte i forbindelse med høyere-ordens prosedyrer. Terminologien avslører røttene ved Alonzo Church (på 30-tallet).

Prosedyrer inn, prosedyrer ut 6 Parametriserbar søk-og-erstatt med anonyme høyere-ordens prosedyrer:? (define (make-replacer pred proc) (lambda (z) (if (pred z) (proc z) z)))? (map (make-replacer odd? (lambda (x) (+ 1 x))) (1 42 2 42 3)) (2 42 2 42 4)

Lokale variabler og lambda 7 Formål: normalisere sekvens av tall som prosentandel av summen.? (percentages (10 20 30 40 50)) (6 2 3 13 1 3 20 26 2 3 33 1 3 ) (define (percentages items) (map (lambda (x) (* 100 (/ x (reduce + 0 items)))) items)) (define (percentages items) (define (helper sum) (map (lambda (x) (* 100 (/ x sum))) items)) (helper (reduce + 0 items))) (define (percentages items) ((lambda (sum) (map (lambda (x) (* 100 (/ x sum))) items)) (reduce + 0 items))) Parameteret til den indre prosedyre fungerer som en lokal variable.

Lokale variabler, lambda, og let 8 Bruk av lokale variabler er så vanlig at det finnes en kortform: let. (define (percentages items) ((lambda (sum) (map (lambda (x) (* 100 (/ x sum))) items)) (reduce + 0 items))) (define (percentages items) (let ((sum (reduce + 0 items))) (map (lambda (x) (* 100 (/ x sum)) items)))) let er å regne som syntaktisk sukker i Scheme (gir økt lesbarhet). Navnet gjenspeiler matematisk språkbruk ( Let a be a vector... ).

Lokale variabler, lambda, og let 9 Generell form for let Ekvivalent lambda-uttrykk (let (( var1 exp1 ) ( var2 exp2 ). ( varn expn )) body ) ((lambda ( var1 var2... varn ) body ) exp1 exp2... expn ) Rekkevidden til variablene er kroppen til let-uttrykket. Verdiene ( exp 1... exp n ) beregnes utenfor let-uttrykket. Variablene har ikke tilgang til hverandre under bindingen. let* som kortform for flere omsluttende let-uttrykk.

Noen eksempler med let? (define foo 42)? (let ((x foo) (y 1)) (list x y)) (42 1)? (let ((x foo) (y foo)) (list x y)) (42 42)? (let ((x foo) (y x)) (list x y)) error: x undefined? (let ((foo 7) (y foo)) (list foo y)) (7 42)? (let ((foo 7)) (let ((y foo)) (list foo y))) (7 7)? (let* ((foo 7) (y foo)) (list foo y)) (7 7) 10

Dataabstraksjon 11 Så langt: modularisering og abstraksjon av prosesser (beregninger). Like viktig er modularisering og abstraksjon av data ( kunnskap ). Hvilke typer data kjenner vi (i Scheme)? tall integer, real, rational 42, 3.1415, 2/3 sekvens av tegn string "foo bar" sannhetsverdi boolean #t, #f par (2-tuple) pair (cons) (47. 11) tom sekvens null () funksjoner prosedyre (lambda) +, (lambda (x) (* x x)) Skille mellom abstrakte datatyper og deres implementasjon i Scheme.

Repetisjon: Lister 12 Kjeder av cons-par der siste elementet er den tomme lista; ().? (cons 1 (cons 2 (cons 3 (cons 4 ()))))) (1 2 3 4) Lister kan defineres rekursivt som: () eller et par der cdr er en liste.

Lister som vår første komplekse datatype 13 (define (list? object) (or (null? object) (and (pair? object) (list? (cdr object)))))? (list? (list 1 2 3 4)) #t? (list? (1)) #t? (list? (cons 1 ())) #t? (list? ()) #t? (list? 1) #f? (list? (cons 1 2)) #f

Dataabstraksjon og komplekse data 14 Ofte behov for å binde sammen en gruppe sammenhengende data. Komplekse datatyper grupperer informasjon som konseptuelt hører sammen (compound data), f.eks. rasjonale tall: 1/3. Dataabstraksjon skjuler en datatypes intern representasjon. Familie av prosedyrer som grensesnitt: constructor, selectors, predicate. (define (make-rat n d) (cons n d)) (define (rat-numer r) (car r)) (define (rat-denom r) (cdr r)) (define (rat? r) (pair? r)) Her bruker vi cons for å lime sammen to heltall: teller og nevner. Nok for å definere prosedyrer som konseptuelt regner på rasjonale tall.

Aritmetikk med rasjonale tall 15 a b an a d a+b an a d bn b d = + bn b d an bn a d b n = an b d + b n a d a d b n Operasjoner på rasjonale tall er uavhengig av intern representasjon. Abstraksjonsbarriere: dataabstraksjon skjuler limet (cons-cellen i bunnen). Closure property: limet kan brukes på ting som selv er blitt limet sammen. Hvilken type lim bruker vi i Scheme? Holder oss til bare cons i flere uker. (define (mul-rat a b) (make-rat (* (rat-numer a) (rat-numer b)) (* (rat-denom a) (rat-denom b)))) (define (add-rat a b) (make-rat (+ (* (rat-numer a) (rat-denom b)) (* (rat-numer b) (rat-denom a))) (* (rat-denom a) (rat-denom b))))...

På sidespor: Blanding av datatyper 16 1 + 1 3 = 4 3 3 3 + 1 3 = 4 3 Scheme gjør det enkelt å definere såkalte polymorfe prosedyrer. Bunnoperasjonene avgjør hvordan kombinere forskjellige typer data. (define (add-rat a b) (let ((a (if (integer? a) (make-rat a 1) a)) (b (if (integer? b) (make-rat b 1) b))) (make-rat (+ (* (rat-numer a) (rat-denom b)) (* (rat-numer b) (rat-denom a))) (* (rat-denom a) (rat-denom b)))))? (add-rat 1 (make-rat 1 3)) (4. 3) Inklusjon av datatyper: integer rational automatisk coercion.

Nok en gang: Lister 17 Kjeder av cons-par der siste elementet er den tomme lista; ().? (cons 1 (cons 2 (cons 3 (cons 4 ()))))) (1 2 3 4) closure property: vi kan bygge komplekse strukturer fra bunnen av.

Prosedyrer vs. data 18 Husk at prosedyrer i Scheme er førsteklasses objekter, altså data; f.eks. som argument eller returverdi; Scheme-koden skrives som lister. Prosedyrer kan også brukes som lim til komplekse data, istedenfor cons. (define (cons x y) (lambda (message) (cond ((= message 0) x) ((= message 1) y)))) (define (car proc) (proc 0)) (define (cdr proc) (proc 1))? (cons 1 2)) #<procedure>

Hjelp! Hva skjer? 19 Et par kan bindes sammen som en prosedyre som returnerer enten car-verdien eller cdr-verdien, avhengig av hvilken beskjed den får. Så implementeres car og cdr som oppkalling av cons-prosedyren. Ved denne oppkallingen sender car en beskjed som velger ut riktig. Mindre effisient representasjon enn cons-celle (dvs. par av to pekere). Konseptuelt interessant: message passing; dette kommer vi tilbake til. (define (cons x y) (lambda (proc) (proc x y))) (define (car proc) (proc (lambda (p q) p)))

Lister som hierarkiske strukturer 20 Hvert liste-element kan selv være en liste... Som igjen kan bestå av nye lister.? (cons (list 1 2) (list 3 4)) ((1 2) 3 4)

Lister som trær 21 Lister av lister kan sees som trær: Hvert element i en liste er en gren. Elementer som selv er lister er subtrær. Løvnodene i treet er de atomære elementene som ikke er lister. NB: så langt kan vi bare ha verdier på løvnodene, og vi skal etterhvert lage en generalisert implementasjon av trær.

Rekursjon på lister av lister 22 Må passe på at rekursjonen går ned i hver (element)liste. For eksempel: telle løvnoder (parallelt til length på sekvenser). Må tenke på tre forskjellige situasjoner; Argumentet kan være: den tomme lista en cons-celle (et tre) noe annet (define (count-leaves tree) (cond ((null? tree) 0) ((pair? tree) (+ (count-leaves (car tree)) (count-leaves (cdr tree)))) (else 1)))? (count-leaves ((1 2) 3 4)) 4

Rekursjon på lister av lister (forts.) 23 For eksempel: samle opp løvnoder i en flat list (fringe eller flatten. Må tenke på tre forskjellige situasjoner; Argumentet kan være: den tomme lista en cons-celle (et tre) noe annet (define (fringe tree) (cond ((null? tree) ()) ((pair? tree) (append (fringe (car tree)) (fringe (cdr tree)))) (else (list tree))))? (fringe ((1 2) 3 4)) (1 2 3 4)

Rekursjon på lister av lister 24 map er definert for lister; tree-map kan defineres for lister av lister: (define (tree-map proc tree) (cond ((null? tree) ()) ((pair? tree) (cons (tree-map proc (car tree)) (tree-map proc (cdr tree)))) (else (proc tree))))? (tree-map square ((1 2) 3 4)) ((1 4) 9 16) Alternativt kan map brukes, i kombinasjon med rekursjon: (define (tree-map proc tree) (map (lambda (subtree) (if (pair? subtree) (tree-map proc subtree) (proc subtree))) tree)) Hvorfor trengs det bare én rekursiv oppkalling i denne varianten?

På sidespor: dotted pairs vs. lister 25 Hvordan Scheme viser cons-celler:? (cons 1 2) (1. 2)? (cons 1 (cons 2 ())) (1 2)? (cons (list 1 2) 3) ((1 2). 3) I bunnen er (1 2 3) en cons-kjede (1. (2. (3. ()))); Er cdr-verdien et par sløyfer Scheme punktum og parentes:. (.? (1. (2. (3. ()))) (1 2 3) Dermed kan vi skrive prosedyrer som tar et variabel antall argumenter: (define (map fn. lists)...)