PROGRAMMAZIONE 2 15bis. OCaML: un veloce...
Transcript of PROGRAMMAZIONE 2 15bis. OCaML: un veloce...
1PR22017-2018
PROGRAMMAZIONE215bis.OCaML:unveloceripasso
Los&lefunzionale
• InJava(maancheinC)l’effe;oosservabilediunprogrammaèlamodificadellostato
• InOCaMLilrisultatodellacomputazioneèlaproduzione
diunnuovovalore
temp=pair.x;pair.x=pair.y;pair.y=temp;
letx=5in(x,x)
PR22017-2018 2
Value-orientedprogramming
• Programmazionefunzionale:“value-orientedprogramming”o unprogrammaOCaMLèunaespressioneo unaespressioneOCaMLdenotaunvalore
• L’esecuzionediunprogrammaOCaMLpuòesserevistacomeunasequenzadipassidicalcolo(semplificazionidiespressioni)cheallafineproduceunvalore
PR22017-2018 3
Espressioni
• Sintassi:regoledibuonaformazione• Seman&ca
o regoleditypechecking(&pooerrore)o regolediesecuzionechegaran&sconocheespressioni&pateproduconounvalore
PR22017-2018 4
Valori
• Unvaloreèunaespressionechenondeveesserevalutataulteriormenteo 34èunvaloredi&pointo 34+17èun’espressionedi&pointmanonèunvalore
PR22017-2018 5
Valori
• Lanotazione<exp>⇒<val>indicachel’espressione<exp>quandovalutatacalcolailvalore<val>
3⇒3(valoridibase)3+4⇒72*(4+5)⇒18
eval(e)=vmeta-notazionepere⇒v
PR22017-2018 6
let
• Sintassi:letx=e1ine2o xiden%fiero e1,e2espressionio letx=e1ine2espressioneo x=e1binding
• letx=2inx+xletincx=x+1ininc10lety="programmazione"in(letz="2"iny^z)
PR22017-2018 7
let
• letx=e1ine2• Regoladivalutazione
o eval(e1)=v1o sos&tuireilvalorev1pertu;eleoccorrenzedixine2o;enendol’espressionee2’
o subst(e2,x,v1)=e2’o eval(e2’)=vo eval(letx=e1ine2)=v
PR22017-2018 8
let
eval(e1) = v1 subst(e2, x,v1) = e2' eval(e2') = veval(let x = e1 in e2) = v
PR22017-2018 9
Esempio
• eval(letx=1+4inx*3)o eval(1+4)=5
• eval(letx=5inx*3)o subst(x*3,x,5)=5*3
• eval(5*3)=15• eval(letx=1+4inx*3)=15
PR22017-2018 10
letbinding=scope
let x = 42 in(* y non è visibile *)
x + (let y = "3110" in (* y è visibile *)
int_of_string y)
PR22017-2018 11
scope:overlapping
let x = 5 in ((let x = 6 in x) + x)
duecasi ((let x = 6 in x) + 5) ((let x = 6 in 5) + 5)
PR22017-2018 12
scope:overlapping
let x = 5 in ((let x = 6 in x) + x)
duecasi ((let x = 6 in x) + 5) ((let x = 6 in 5) + 5)
PR22017-2018 13
scope:overlapping
let x = 5 in ((let x = 6 in x) + x)
duecasi ((let x = 6 in x) + 5) ((let x = 6 in 5) + 5)
PR22017-2018 14
Alphaconversione
• L’iden&tàpuntualedellevariabililegatenonhaalcunsenso!!• Inmatema&ca
– f(x)=x*x– f(y)=y*y
sonolamedesimafunzione!!• Ininforma&ca
– letx=5in((letx=6inx)+x)– letx=5in((lety=6iny)+x)
PR22017-2018 15
Dichiarazionedifunzioni
let f (x : int) : int = let y = x * 10 in y * y;;
PR22017-2018 16
Funzioniricorsive
let rec pow x y = if y = 0 then 1 else x * pow x (y - 1);;
PR22017-2018 17
Applicazionedifunzioni
let f (x : int) : int = let y = x * 10 in y * y;;
f 5;; - : int = 2500
PR22017-2018 18
Applicazionedifunzioni
let rec pow x y = if y = 0 then 1 else x * pow x (y - 1);;
pow 2 3;;-: int 8
PR22017-2018 19
Dichiarazione
• Lavalutazionediunadichiarazionediunafunzioneèlafunzionestessao lefunzionisonovalori
PR22017-2018 20
Applicazione
• eval(e0e1...en)=v'seo eval(e0)=letfx1...xn=eo eval(e1)=v1...eval(en)=vno subst(e,x1,…,xn,v1,...,vn)=e'o eval(e')=v'
PR22017-2018 21
Esempi
• letdouble(x:int):int=2*x;;• letsquare(x:int):int=x*x;;• letquad(x:int):int=double(doublex);;• letfourth(x:int):int=square(squarex)
PR22017-2018 22
Esempi
• lettwice((f:int->int),(x:int)):int=f(fx)
• letquad(x:int):int=twice(double,x)• letfourth(x:int):int=twice(square,x)
• twiceo higher-orderfunc%on:unafunzionedafunzioniadaltrivalori
PR22017-2018 23
Funzionihigher-order
• letcompose((f,g):(int->int)*(int->int))• (x:int):int=f(gx)
• letrecn&mes((f,n):(int->int)*int)=ifn=0then(fun(x:int)->x)elsecompose(f,n&mes(f,n-1))
PR22017-2018 24
OCaMLList
• letlst=[1;2;3];;• letempty=[];;• letlonger=5::lst;;• letanother=5::1::2::3::[]
PR22017-2018 25
List:sintassi
• []lalistavuota– nilderivatodalLISP
• e1::e2inseriscel’elementoe1intestaallalistae2– ::=LISPcons
• [e1;...;en]notazionesintamcaperlalistae1::...::en::[]
PR22017-2018 26
Accedereaunalista
• Stru;uralmenteunalistapuòessereo nil,[]o lalistao;enutamedianteunaoperazionediconsdiunelementoaunalista
• Idea:usareilpa^ernmatchingperaccedereaglielemen&dellalista
• letemptylst=matchlstwith[]->true|h::t->false
PR22017-2018 27
Esempi
• letrecsumxs=matchxswith[]->0|h::t->h+sumt
• letrecconcatss=matchsswith[]->""
|s::ss'->s^(concatss')• letrecappendlst1lst2=matchlst1with
[]->lst2|h::t->h::(appendtlst2)
PR22017-2018 28
Pa;ernMatching
• matchewithp1->e1|p2->e2|...|pn->en
• Leespressionipisichiamanopa6ern
PR22017-2018 29
Pa;ernmatching
• Ilpa;ern[]“match”solamenteilvalore[]• match[]with
[]->0|h::t->1
(*res&tuisceilvalore0*)• match[]with
h::t->0|[]->1
(*res&tuisceilvalore1*)
PR22017-2018 30
Pa;ernmatching
• Ilpa;ernh::t“match”unaqualsiasilistaconalmenounelemento,einoltrehal’effe;odilegarequell’elementoallavariabilehelalistarimanenteallavariabilet
• match[1;2;3]with
[]->0|h::t->h(*res&tuisceilvalore1*)
• match[1;2;3]with[]->[]|h::t->t(*res&tuisceilvalore[2;3]*)
PR22017-2018 31
Altriesempi
• Ilpa;erna::[]“match”tu;elelisteconesa;amenteunelemento
• Ilpa;erna::b“match”tu;elelisteconalmenounelemento• Ilpa;erna::b::[]“match”tu;elelisteconesa;amentedue
elemen&• Ilpa;erna::b::c::d“match”tu;elelisteconalmenotre
elemen&
PR22017-2018 32
Unesempiopiùcomplicato
• letrecdrop_valvlst=matchlstwith[]->[]|h::t->lett'=drop_valvtin ifh=vthent'elseh::t'
PR22017-2018 33
Unaltroesempio
• letrecmax_list=funcbon[]->???|h::t->maxh(max_listt)
• Cosamemamoalpostodi????
– min_intèunasceltapossibile...– osollevareunaexcep&on...
• InJava,avremmopotutores&tuirenull...– …masiamoinOCaML,checifornisceunaaltrasoluzione
PR22017-2018 34
Op&ontype
• letrecmax_list=funcbon[]->None|h::t->matchmax_listtwith |None->Someh |Somex->Some(maxhx)
(*max_list:'alist->'aop&on*)
PR22017-2018 35
Iteratori
• letrecmapf=funcbon[]->[]|x::xs->(fx)::(mapfxs)
• map:('a->'b)->'alist->'blist
• letis_evenx=(xmod2=0);;• letlst=mapis_even[1;2;3;4];;
Parametroimpicitodi&polista
PR22017-2018 36
Iteratori
• letrecmapf=funcbon[]->[]|x::xs->(fx)::(mapfxs)
• map:('a->'b)->'alist->'blist
• letis_evenx=(xmod2=0);;• letlst=mapis_even[1;2;3;4];;
• Risultato[false;true;false;true]
PR22017-2018 37
Definire&pididatoinOCaML
OCaMLperme;ealprogrammatoredidefinirenuovi&pididato
typegiorno=Lunedi|Martedi|Mercoledi|Giovedi|Venerdi|Sabato|Domenica
Dichiarazionedi&po
Nomedel&poCostru;ori
Icostru;oridefinisconoivaloridel&podidatoSabatoha&pogiorno[Venerdi,Sabato,Domenica]ha&pogiornolist
PR22017-2018 38
Pa;ernmatching
Ilpa;ernmatchingfornisceunmodoefficienteperaccedereaivaloridiun&podidato
letstring_of_g(g:giorno):string=matchgwithLunedi->"Lunedi"|Martedi->"Martedi”|:|Domenica->"Domenica”
Ilpa;ernmatchingseguelastru;urasintamcadeivaloridel&podidato:icostru;ori
PR22017-2018 39
Astrazionisuida&
• Avremmopotutorappresentareil&podidatogiornotramitedeisemplicivaloriinteri– Lunedi=1,Martedi=2,…,Domenica=7
• Ma…– il&podidatoprimi&vointfornisceuninsiemedioperazionidifferen&daquellesignifica&vesul&podidatogiorno,Mercoledi–Domenicanonavrebbealcunsenso
– esistonounnumeromaggioredivaloriinterichedivaloridel&pogiorno
• Morale:ilinguaggidiprogrammazionemoderni(Java,OCaML,C#,C++,…)fornisconostrumen&perdefinire&pididato
PR22017-2018 40
OCaMLType
• Icostru;oripossonotrasportare“valori”
#typefoo=Nothing|Intofint|Pairofint*int|Stringofstring;;typefoo=Nothing|Intofint|Pairofint*int|Stringofstring
NothingInt3Pair(4,5)String"hello"...
Valoridel&pofoo
Dichiarazionedavalutare
Risultato
PR22017-2018 41
Pa;ernmatching
letget_count(f:foo):int=matchfwithNothing->0|Int(n)->n|Pair(n,m)->n+m|String(s)->0
PR22017-2018 42
Tipididatoricorsivi
#typetree=Leafofint|Nodeoftree*int*tree;;typetree=Leafofint|Nodeoftree*int*tree
lett1=Leaf3lett2=Node(Leaf3,2,Leaf4)lett3=Node(Leaf3,2,Node(Leaf5,4,Leaf6))
PR22017-2018 43
Tipididatoricorsivi
#typetree=Leafofint|Nodeoftree*int*tree;;typetree=Leafofint|Nodeoftree*int*tree
Quan&divoihannoprogrammatoconstru;ureda&del&potree?
PR22017-2018 44
Alberibinari
Radice
foglie
So;oalberosinistro
So;oalberodestro
vuoto
Liavetevis&aalgoritmica!!!!
PR22017-2018 45
AlberibinariinOCaML
typetree=Empty|Nodeoftree*int*tree
lett:tree=Node(Node(Empty,1,Empty),3Node(Empty,2,Node(Empty,4,Empty)))
3
1 2
4
PR22017-2018 46
Ricercainunalbero
letreccontains(t:tree)(n:int):bool=matchtwithEmpty->false|Node(lt,x,rt)->x=n||(containsltn)||(containsrtn)
Lafunzionecontainseffe;uaunaricercadelvalorensull’alberotCasopeggiore:devevisitaretu;ol’albero
PR22017-2018 47
Alberibinaridiricerca
Idea:ordinareida&suiqualivienefa;alaricercaUnalberobinariodiricerca(BST)èunalberobinariochedevesoddisfarealcuneproprietàinvarian&addizionali
• Node(lt,x,rt)èunBSTse• ltertsonoBST• tuminodidiltcontengonovalori<x• tuminodidirtcontengonovalori>x
• Empty(l’alberovuoto)èunBST
INVARIANTEDIRAPPRESENTAZIONE
PR22017-2018 48
Esempio
L’invariantedirappresentazionedeiBSTèsoddisfa;oComesidimostra?RicordateletecnichecheaveteimparatoaLPP!!!
PR22017-2018 49
RicercasuunBST
(*Ipotesi:tèunBST*)letreclookup(t:tree)(n:int):bool=matchtwithEmpty->false|Node(lt,x,rt)->ifx=nthentrueelseifn<xthen(lookupltn)else(lookuprtn)
Osservazione1:L’invariantedirappresentazioneguidalaricercaOsservazione2:Laricercapuòres&tuirevalorinoncorremseapplicataaunalberochenonsoddisfal’invariantedirappresentazione
PR22017-2018 50
lookup(t,3)
PR22017-2018 51
ComecostruiamounBST
• Opzione1– costruiamounalberoepoicontrolliamo(check)sevalel’invariantedi
rappresentazione
• Opzione2– definirelefunzionichecostruisconoBSTapar&redaBST(adesempio,la
funzionecheinserisceunelementoinunBSTeres&tuisceunBST)– definireunafunzionechecostruisceilBSTvuoto– tu;equestefunzionisoddisfanol’invariantedirappresentazione,
pertanto“percostruzione”o;eniamounBST– nonsideveeffe;uarenessuncontrolloaposteriori!!– questopassome;einevidenzailruolodellateoriaininforma&ca(&pi
algebrici):neparleremonelseguitodelcorso
PR22017-2018 52
insert(t,4)
PR22017-2018 53
insert(t,4)
PR22017-2018 54
insert
(*InsertnnelBSTt*)letrecinsert(t:tree)(n:int):tree=matchtwithEmpty->Node(Empty,n,Empty)|Node(lt,x,rt)->ifx=nthent
elseifn<xthenNode(insertltn,x,rt) elseNode(lt,x,insertrtn)
Perqualemo&vol’alberocostruitodallafunzioneinsertèunBST?
PR22017-2018 55
delete(t,5)
L’operazionedirimozioneèpiùcomplicata:sidevepromuoverelafoglia3aradicedell’albero!!! 56
Funzioneausiliaria
letrectree_max(t:tree):int=matchtwithNode(_,x,Empty)->x|Node(_,_,rt)->tree_maxrt|_->failwith"tree_maxcalledonEmpty”
L’invariantedirappresentazionegaran&scecheilvaloremaxsitrovanellapartepiùadestradell’albero
PR22017-2018 57
delete
letrecdelete(t:tree)(n:int):tree=matchtwithEmpty->Empty|Node(lt,x,rt)->ifx=nthenbeginmatch(lt,rt)with
(Empty,Empty)->Empty |(Node_,Empty)->lt |(Empty,Node_)->rt |_->letm=tree_maxltin Node(deleteltm,m,rt) end
elseifn<xthenNode(deleteltn,x,rt) elseNode(lt,x,deletertn)
PR22017-2018 58
Funzionigeneriche
letreclength(l:intlist):int=matchlwith[]->0|_::tl->1+lengthtl
letreclength(l:stringlist):int=matchlwith[]->0|_::tl->1+lengthtl
Analizziamolafunzionelengthapplicataaintlistestringlist
Lefunzionisonoiden&che,ecce;ol’annotazionedi&po
PR22017-2018 59
GenericiinOCaML
letreclength(l:'alist):int=matchlwith[]->0|_::tl->1+(lengthtl)
Lanotazione'alistindicaunalistagenericalength[1;2;3]applicalafunzioneaintlistlength["a";"b";"c"]applicalafunzioneastringlist
PR22017-2018 60
Appendgenerico
letrecappend(l1:'alist)(l2:'alist):'alist=matchl1with[]->l2|h::tl->h::(appendtll2)
Ilpa;ernmatchingperme;edioperaresu&pigenericihha&po'atlha&po'alist
PR22017-2018 61
Genericzip
letreczip(l1:'alist)(l2:'blist):('a*'b)list=match(l1,l2)with(h1::t1,h2::t2)->(h1,h2)::(zipt1t2)|_->[]
Lafunzioneoperasu&pigenericimul&pli(da'aliste'blistverso('a*'b)list)zip[1;2;3]["a";"b";"c"]=[(1,"a");(2,"b");(3,"c")]:(int*string)list
PR22017-2018 62
Generictree
type'atree=Empty|Nodeof'atree*'a*'atree
Sino&l’u&lizzodelparametrodi&po'a
PR22017-2018 63
GenericBST
letrecinsert(t:'atree)(n:'a):'atree=matchtwithEmpty->Node(Empty,n,Empty)|Node(lt,x,rt)->ifx=nthent
elseifn<xthenNode(insertltn,x,rt) elseNode(lt,x,insertrtn)
Glioperatoridirelazione=e<operanosuogni&podidato
PR22017-2018 64
Collec&on(Set)
• Uninsiemeèunacollezionedida&omogeneiconoperazionidiunione,intersezione,etc.
• UnSetèsostanzialmenteunalistanellaquale– lastru;urad’ordinenonèimportante– nonsonopresen&duplica&manonèunbpoprimibvoinOCaML
• Stru;ureda&comeSetsonousateinmolteapplicazioni– interrogazioniSQL(insiemedeglistuden&iscrimaInforma&ca,
insiemedeirisulta&diunaricercasulwebconGoogle,insiemedeida&diunesperimentoalCERN,…)
• DiversimodiperimplementareSet
PR22017-2018 65
Set
• UnBSTdefinisceunaimplementazionedellastru;uraSeto l’insiemevuoto(bstempty)o determinaretu@glielemen%cheappartengonoall’insieme(visitadell’albero)
o definireunaoperazionepertestarel’appartenenzadiunelementoauninsieme(lookup)
o definireunioneeintersezione(tramiteinsertedelete)
PR22017-2018 66
OCaML:SetInterface
moduletypeSet=sigtype'asetvalempty:'asetvaladd:'a->'aset->'asetvalremove:'a->'aset->'asetvallist_to_set:'alist->'asetvalmember:'a->'aset->boolvalelements:'aset->'alistend
Moduletype(inunfile.mli)perdichiarareunTdAsig...endracchiudonounasegnatura,chedefinisceilTdAeleoperazionival:nomedeivalorichedevonoesseredefini&edeiloro&pi
Idea(solita):fornirediversefunzionalitànascondendolaloroimplementazione
PR22017-2018 67
ModuliinOCaML
moduleMyset:Set=struct…(*implementa&onsofalltheopera&ons*):end
NomedelmoduloSignaturechedeveessereimplementata
PR22017-2018 68
“dotnota&on”
lets1=Myset.add3Myset.emptylets2=Myset.add4Myset.emptylets3=Myset.add4s1lettest():bool=(Myset.member3s1)=true;;run_test"Myset.member3s1"testlettest():bool=(Myset.member4s3)=true;;run_test"Myset.member4s3"test
PR22017-2018 69
Openmodule
Alterna&va:aprireloscopedelmodulo(open)perportareinominell’ambientedelprogrammainesecuzione
;;openMysetlets1=add3emptylets2=add4emptylets3=add4s1lettest():bool=(member3s1)=true;;run_test"Myset.member3s1"testlettest():bool=(member4s3)=true;;run_test"Myset.member4s3"test
PR22017-2018 70
Implementazionebasatasulist
moduleMySet2:Set=structtype'aset='alistletempty:'aset=[]...end
Una definizione concreta
per il tipo Set
PR22017-2018 71
Domande
openMySetlets1:intset=Empty
Superalafasedicontrollodei&pi?
PR22017-2018 72
Domande
openMySetlets1:intset=Empty
Superalafasedicontrollodei&pi?No:ilcostu;oreEmptynonèvisibileesternamentealmodulo!!!
PR22017-2018 73
CompilareprogrammiOCaML
ocamlc
program.ml(sorgente)
program.cmo(bytecode)a.out(bytecodeeseguibile)
h;p://caml.inria.fr/pub/docs/manual-ocaml/comp.html
PR22017-2018 74
EseguirebytecodeOCaML
ocamlrun
h;p://caml.inria.fr/pub/docs/manual-ocaml-400/manual024.html
a.out(bytecodeeseguibile)
result
PR22017-2018 75