Haskell: Programmazione con Tuple, Liste

Slides:



Advertisements
Presentazioni simili
String c++.
Advertisements

Linguaggi di programmazione
Introduzione alla Object Oriented Programming, OOP E.Mumolo. DEEI
E.Mumolo. DEEI Introduzione alla programmazione ad oggetti in C++ Object Oriented Programming, OOP E.Mumolo. DEEI
Corso di Informatica (Programmazione)
APPUNTI SUL LINGUAGGIO C
1 Implementazione di Linguaggi 2 Implementazione di Linguaggi 2 Federico Bernardi Type checking 2° parte Type checking 2° parte - Equivalenza di type expressions.
Polimorfismo Significato Significato Varie famiglie Varie famiglie Polimorfismo in java Polimorfismo in java Polimorfismo di Sottotipo: Apparato in Java.
Informatica B Allievi Elettrici - AA Fondamenti della programmazione in linguaggio C (II) Istruzioni e strutture di controllo.
1 Tipi di Dato §descrittori, tipi, controllo e inferenza dei tipi §specifica (semantica) e implementazione di tipi di dato l implementazioni “sequenziali”
Case Study - Un (linguaggio) costrutto tipato: Accedere indirizzi fuori dai bounds di un array Char A[n1..n2]; Int i; … i = e … … A[i] … Sono due interi.
1 Programmazione Funzionale: ML 1 implementazione del -calcolo tipato l definizione di nuovi tipi ricorsivi l i valori dei nuovi tipi sono termini, che.
7/14/20151 Haskell: ADT n ADT: pricipi, proprietà n ADT in Haskell: il meccanismo n ADT in Haskell: Hiding e Qualified n Esempi: Store e i problemi di.
7/16/20151 Haskell: Tipi basici e Definizioni n Tipi Atomici (scalari) n Valori e Identificatori n Overloading n Definizioni e Layout n Definizioni ricorsive:
1 Tipi di dato modificabili §a livello semantico, riconduciamo la modificabilità alla nozione di variabile l lo stato “modificabile” corrispondente sarà.
Algoritmo per il calcolo del maggiore tra tre numeri qualsiasi Francesco PUCILLO matr
Prof.ssa Rossella Petreschi Lezione del 29/10/2012 del Corso di Algoritmi e Strutture Dati Riferimenti: Capitolo 19 del testo Cormen, Leiserson, Rivest,
NUMERI RELATIVI I numeri relativi comprendono i numeri positivi, negativi e lo 0 Esempio: +10, -5, +3, 0, -2 I numeri relativi si possono trovare all’interno.
Ambienti di Programmazione per il Software di Base
Algoritmi e Strutture dati a.a.2010/2011 Prof.ssa Rossella Petreschi
Algoritmi e Strutture dati a.a.2010/2011 Prof.ssa Rossella Petreschi
Tecnologie Informatiche ed Elettroniche per le Produzioni Animali
PEDAGOGIA SPERIMENTALE
x : variabile indipendente
7. Strutture di controllo Ing. Simona Colucci
Condizioni decisionali
x : variabile indipendente
7. Strutture di controllo
Universita’ di Milano Bicocca Corso di Basi di dati 1 in eLearning C
Prof.ssa Carolina Sementa
TIPI PRIMITIVI TIPI STRUTTURATI
Programmazione strutturata
Sulla complessità Lezione n°2
PROGRAMMAZIONE BASH – ISTRUZIONE IF
Una possibile prova della congettura di Goldbach
Ripetiamo…! La divisibilità
Haskell: Higher Order Programming
Linguaggio C++ Selezione.
Codicfiche Interi Complemento alla base.
Strutture di Controllo
PEDAGOGIA SPERIMENTALE
Ricorsione 16/01/2019 package.
Introduzione agli Algoritmi e alle Strutture Dati
Schema generale, visita in ampiezza e profondità.
Process synchronization
APPUNTI SUL LINGUAGGIO C
Algoritmi Avanzati a.a.2011/2012 Prof.ssa Rossella Petreschi
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
APPUNTI SUL LINGUAGGIO C
Astrazione e Concretizzazione
Haskell: controllo dei tipi
Corso di Informatica 2 a.a. 2003/04 Lezione 2
APPUNTI SUL LINGUAGGIO C
Condizioni decisionali
APPUNTI SUL LINGUAGGIO C
Programmazione funzionale
Programmazione e Laboratorio di Programmazione
Esercizio Dato un albero binario, definiamo altezza minimale di un nodo v la minima distanza di v da una delle foglie del suo sottoalbero, definiamo invece.
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Esercitazione guidata 1
APPUNTI SUL LINGUAGGIO C
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Haskell: Higher Order & Combinator Programming
concetti ed applicazioni
Modelli stocastici o di Box-Jenkins (approccio moderno post 1925)
ALGORITMO E’ una successione finita di passi che consente di risolvere tutti i problemi di una classe e di determinare il risultato. Caratteristiche: Finito.
Programmazione e Laboratorio di Programmazione
Transcript della presentazione:

Haskell: Programmazione con Tuple, Liste Linguaggi Funzionali /aa. 03 - 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

Tipi Strutturati: Tuple Linguaggi Funzionali /aa. 03 - 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

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

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

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

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

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

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

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

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

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

Liste Intervallo e Stream Linguaggi Funzionali /aa. 03 - 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

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

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

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

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

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

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

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