La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Haskell: Programmazione con Tuple, Liste

Presentazioni simili


Presentazione sul tema: "Haskell: Programmazione con Tuple, Liste"— Transcript della presentazione:

1 Haskell: Programmazione con Tuple, Liste
Linguaggi Funzionali /aa M.Bellia Haskell: Programmazione con Tuple, Liste Tipi Strutturati: Tuple Liste Pattern matching Esempi di programmi Proof. :/++ Induzione Strutturale Proof. reverse Stream e List Comprehension Esercizi 12/7/2018

2 Tipi Strutturati: Tuple
Linguaggi Funzionali /aa M.Bellia Tipi Strutturati: Tuple Tuple = Tipi Prodotto -- (t1,t2) = t1 x t2 di tipi diversi type Pair = (Char,Int) type Triple = (Char, Int, Pair) valori records senza selettori espliciti x = (“Carlo”, 22) Operazioni: selettori (impliciti) fst:: (a,b) -> a snd::(a,b) -> b 12/7/2018

3 Liste Stesso tipo Operazioni
Liste = sequenze omogenee -- [t] = [] + t x [t] Stesso tipo type PairList= [Pair] type DataBase = [Records] Operazioni : :: a -> [a] -> [a] ++ :: [a] -> [a] -> [a] head :: [a] -> a tail :: [a] -> [a] Prelude -- !!, concat, length, head, drop, zip, take, splitAt, reverse, sum, product…, 12/7/2018

4 Esempi di programmi !!:: [t] -> Int -> t
!! l n | (n<0) = error "indice negativo" | (n==0) = if (l /= []) then head l else error "indice troppo grande" | (l==[]) = error "indice troppo grande" | otherwise = !! (tail l) (n-1) concat:: [[t]] -> [t] concat l | (l==[]) = [] | otherwise = (head l) ++ (concat (tail l)) 12/7/2018

5 Linguaggi Funzionali /aa. 03 - M.Bellia
Pattern Matching Type and Data constructor Type C. : [t] = [] + t x [t] (sono 3) data A t = B | L t (A t) Data C. : [t] = [] + t x [t] (sono 2) Data Constructor: K = {[], [ _ ],…} Variable: V Atomic Values: W Pattern:   V + W + {(A u1…un) :: t | A::t1…tn->t  K, (1≤i≤n) ui  & ui::ti } 12/7/2018

6 Esempi di programmi length length:: [t] -> Int
Length (x:xs) = 1+ length xs length:: [t] -> Int length [] = 0 Length (_:xs) = 1+ length xs drop wildcard: _V (Anonimous variables) drop:: Int -> [t] -> [t] drop n x | (n<0) = error “indice negativo” | (n==) = x drop n+1 (x:xs) = drop n xs reverse ++ reverse:: [t] -> [t] reverse [] = [] reverse (x:xs) = reverse xs ++ [x] ++:: [t] -> [t] -> [t] [] ++ y = y (x:xs) ++ y = x:(xs ++ y) 12/7/2018

7 Proof: A | C -- lemma :/++
++:: [t] -> [t] -> [t] [] ++ y = y (x:xs) ++ y = x:(xs ++ y) (1) (2) da ++ A: segue C: (x:xs) ++ y = [x]++(xs ++ y) Lemma:/++ Proof: (riduzione di termini uguali) (x:zs) ++ ys = x:(zs++y) -- (2) ma, per ogni w: [x]++w = (x:[])++w -- defs(:) = x:([]++w) -- (2) = x:w -- (1) anche per w=(zs++y) Proof: (riduzione di termini uguali) [x]++(zs++y) = (x:[])++(zs++y) -- defs(:) = x:([]++(zs++y)) -- (2) = x:(zs++y) -- (1) = (x:zs)++y -- (2R) 12/7/2018

8 Induzione Strutturale
Ingredienti: D0,< D = dominio discreto (numerabile) < = semiordinamento (rel. bin., rifl., trans., anti.) ben fondato (x D, k  Naturali: #{y<x}<k) 0 D (x D, 0<x) P su D |- x D, P(x) La tecnica: Base: |- P(0) Generale: x D,  P(y)y{z<x} |- P(x) La prova La regola d’inferenza: - (a1) && (a2) ma,  x D: not P(x) Sia: U={x | not P(x)}, U = D\U x0= min< U Allora 2 casi: x0  U => {z< x0} U =>(a2)P(x0) x0  U => U = {} (a1) |- P(0) (a2) x D, P(y)y{z<x} |- P(x) (c) x D, P(x) 12/7/2018

9 Proof: A | C -- reverse 1 da A: segue Cxs,ys: reverse:: [t] -> [t]
reverse (x:xs) = reverse xs ++ [x] (1) (2) da A: segue Cxs,ys: reverse (xs ++ ys) = (reverse ys) ++ (reverse xs) Proof: (Induzione sulla size delle liste) base: |xs|=0 => xs=[] & xs++ys = ys => reverse ([]++ys) = reverse ys ++ reverse[] |xs|=1 => xs=[x] => reverse([x]++ys) = reverse(x:[]++ys) = reverse(x:ys) -- defs(:) = reverse ys ++ [x] --- (2) = reverse ys ++ reverse [x] --- lemma rev[] generale: ind.hyp  k: xs: |xs|<k => Cxs,ys Sia xs: |xs| = k>1 => xs = x:zs per |zs|<k => => reverse(xs ++ ys) = reverse(x:zs ++ ys) = reverse([x] ++ (zs ++ ys)) lemma :/++ = reverse(zs ++ ys) ++ (reverse [x]) --- ind.hyp = (reverse ys) ++ (reverse zs) ++ (reverse [x]) --- ind.hyp = (reverse ys) ++ ((reverse zs) ++ (reverse [x])) --- ass++ = (reverse ys) ++ (reverse ([x]++zs)) --- ind.hypR = (reverse ys) ++ (reverse xs) 12/7/2018

10 Proof: A | C --- reverse 2
reverse:: [t] -> [t] reverse [] = [] reverse (x:xs) = reverse xs ++ [x] (1) (2) da A: segue Cxs,ys: reverse (xs ++ ys) = (reverse ys) ++ (reverse xs) Proof: (Induzione sulla size delle liste) base: |xs|+|ys|=0 => xs=[]=ys & xs++ys=[] => reverse [] = reverse [] ++ reverse[] generale: induc-hyp:  k: xs,ys: |xs|+|ys|<k => Cxs,ys Sia xs, ys: |xs|+|ys|=k>0 & |xs|≠0≠|ys| => xs = x:zs per |zs|+|ys|<k => => reverse(xs ++ ys) = reverse(x:zs ++ ys) = reverse(x:(zs ++ ys)) def(++(2)) = reverse(zs ++ ys) ++ [x] (2) = ((reverse ys) ++ (reverse zs)) ++ [x] ind.hyp. |zs|+|ys|<k = (reverse ys) ++ ((reverse zs) ++ [x]) lemma ass.++ = (reverse ys) ++ (reverse x:zs) (2R) = (reverse ys) ++ (reverse xs) Quando |xs|≠0&|ys|=0 ? inutile ed errata 12/7/2018

11 Proof: lemmi da A: segue: [] ++ ys = ys (x:xs) ++ ys = x:(xs++ys)
reverse [] = [] reverse (x:xs) = reverse xs ++ [x] da A: segue: lemma ass.++ (xs ++ ys) ++ zs = xs ++ (ys++zs) lemma rev[] reverse[x] = [x] 12/7/2018

12 Liste Intervallo e Stream
Linguaggi Funzionali /aa M.Bellia Liste Intervallo e Stream Estensione della (usuale) lista finita Intervallo su ENUM Equipaggiati di succ, pred [n..m]  [n1,…,nk] n1= n i, ni+1= (op ni) op = succ se n<m op = pred se n>m nk rel m & not((op nk) rel m) rel = ≤ se n<m rel = ≥ se n>m Haskell [n..m]  [n1,…,nk] se n<m [n..m]  [] se n≥m n1= n i, ni+1= (succ ni) nk ≤ m & (succ nk)>m [n,p..m]  [n1,…,nk] se (p-n)*(m-n)≥0 [n,p..m]  [] otherwiswe n1= n & n2 = p i, ni+1= (ni + (p-n)) nk ≤ m & (nk+(p-n))>m Stream = lista razionale = infinita ma finitamente approssimabile Un primo caso Intervallo aperto [n..] » [n, p..] 12/7/2018

13 Esempi [2..8] [4.5..9] [2..2] [2..] [a..] [2,1..(-10)] [a,e..z] [e,a..] pari = [0,2..] dispari = [1,3..] 12/7/2018

14 Linguaggi Funzionali /aa. 03 - M.Bellia
List Comprehension Liste come generatori [ex1,..,xn | x1 <- G1,…, xn <- Gn, P1 ,…, Pk] Gi :: [ti] xi :: ti Pi :: Bool tipo -- [e | x1 <- G1,…, xn <- Gn, P1 ,…, Pk] :: [t] se e::t e = trasformatore G = generatore P = filtro/predicato Scope 12/7/2018

15 Esempi di programmi [ 2*n | n <- [0..] ]
pari = [ 2*n | n <- [0..] ] sommaCoppie = [(n+m) | n <- [2..10], m <- [7..(-5)] quadrato n = (sum.(take n)) [1,3..] tuttiQuadrati = quad 0 [1,3..] where quad x (y:ys) = (x+y):(quad(x+y)ys) 12/7/2018

16 Aumentiamo Espressività: Controllo
Let_expression Introduce variabili locali fib n | n <0 = error “fib not defined on negative int” | otherwise = memoizedFib n memoizedFib 0 = (1,1) memoizedFib 1 = (1,1) memoizedFib n+2 = let (p,q) = memoizedFib(n+1) in (q,p+q) Allineamento? Tutti gli algoritmi iterativi possono essere espressi con algoritmi ricorsivi aventi identica complessità 12/7/2018

17 Esercizi Modulo Picture: rote90 Modulo PictureT1.hs:
box chess8 Prime - stream dei numeri primi dimostrare che: x,y,z: (x ++ y) ++ z = x ++ (y ++ z) rote90 :: Picture -> Picture rote90 p = let (u,v)=size p in if v==0 then [] else ((reverse.leftCol) p):((rote90.dropCol) p) where leftCol = map head dropCol = map tail prime = sieve [2..] where sieve (x:xs) = x:(sieve [y| y <- xs, (y `mod` x)/= 0]) 12/7/2018

18 Esercizi Prime_bis - stream dei numeri primi
prime_bis = 1:2:(sieveN 3) where sieveN n = n:[x | x<- sieveN (n+2), (x `mod` n)/= 0] EnumFromI - intervallo ([n,m..k] - stream [n,m..]) enumFromI::Enum a => a -> a -> a -> [a] enumFromI n m k | empty n m k = [] | otherwise = n:(enumFromI m (succI m ((fE m)-(fE n))) k) where fE = fromEnum empty n m k = ((fE m)-(fE n))*((fE k)-(fE n))< 0 succI n step = toEnum((fE n)+step) 12/7/2018

19 Proof: A | C --- ass++ da A: segue Cx,y,z:
++:: [t] -> [t] -> [t] [] ++ y = y (x:xs) ++ y = x:(xs ++ y) (1) (2) da A: segue Cx,y,z: (x ++ y) ++ z = x ++ (y ++ z) Proof: (Induzione sulla size delle liste) base: |x|+|y|+|z|=0 => x=[]=y=z => ([] ++ []) ++ [] = [] ++ ([] ++ []) generale: induc-hyp:  k: x,y,z: |x|+|y+|z| <k => Cx,y,z Sia x, y, z: |x|+|y+|z|=k>0. Due casi 1) |x|=0 => x=[] & ([]++y) ++ z = y ++ z (1) = [] ++ (y ++ z) (1R) 2) |x|≠0 => x = u:xs per |xs|+|y|+|z|<k => => ((u:xs) ++ y) ++ z = u:(xs ++ y) ++ z (2) = u:((xs ++ y) ++ z) (2) = u:(xs ++ (y ++ z)) ind.hyp. |xs|+|y|+|z|<k = (u:xs) ++ (y ++ z) (2R) 12/7/2018


Scaricare ppt "Haskell: Programmazione con Tuple, Liste"

Presentazioni simili


Annunci Google