1 / 18

Avaluació mandrosa. Idea

Avaluació mandrosa. Idea. Ens centrarem ara en l’estudi de llenguatges mandrosos. Aquests llenguatges es basen en la tècnica d’avaluació mandrosa que ens assegura que només s’avaluaran les estructures estrictament necessàries per a obtenir un valor al nivell superior.

aolani
Download Presentation

Avaluació mandrosa. Idea

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Avaluació mandrosa. Idea • Ens centrarem ara en l’estudi de llenguatges mandrosos. Aquests llenguatges es basen en la tècnica d’avaluació mandrosa que ens assegura que només s’avaluaran les estructures estrictament necessàries per a obtenir un valor al nivell superior. • L’avaluació mandrosa té conseqüències interessants ja que ens permetrà definir estructures de dades infinites i incrementar l’eficiència de la computació. • Des del punt de vista del model de computació ens permetrà descriure els programes interactius de forma funcional. Tanmateix, prodrem veure les funcions com a processos que es comuniquen.

  2. Ordre d’avaluació • Les funcions es poden veure com a lleis. Així, suposant que hem definit les funcions g i h, si definim: • fun f x = g(h x x) • estem dient que per a tot valor x el valor denotat per f x és igual al valor denotat per g(h x x). • També podem veure les funcions com a procediments per avaluar una expressió via substitucions per tal d’arribar a trobar la forma canònica a partir d’una expressió original. En l’exemple anterior podem dir que f x es pot reescriure com g (h x x) per tal de ser avaluada. • Aquestes dues visions són compatibles ja que el resultat d’una avaluació que termina (reescriptura) dóna una expressió simplificada (forma canònica) del valor de l’expressió original. • Ara bé l’estratègia de simplificació pot determinar que es trobi l’element canònic o no. En cas de trobar-se qualsevol estratègia ens donarà el mateix resultat.

  3. Exemple • Amb la següent estratègia (call by name, normal order evaluation, outermost reduction order) obtenim un resultat, avaluem abans les funcions que els arguments: • f 3 == g (h 3 3) == 5 fun g x = 5 fun h x y = h y x fun f x = g (h x x) amb l’estratègia següent (call by value, eager evaluation, applicative order evaluation) no n’obtenim cap, avaluem primer els arguments: f 3 == g (h 3 3) == g (h 3 3) == ... A l’avaluar, en ordre normal, una expressió E1 E2, avaluem primer E1 fins que obtenim una funció. L’aplicació de la funció sobre E2 és aleshores avaluada de tal manera que E2 es simplifica tant poc com sigui possible, només s’avaluarà si és necessari per determinar una resposta.

  4. Avaluació mandrosa • L’avaluació normal és segura en el sentit que produeix un resultat sempre que aquest existeix. L’avaluació avariciosa no ho és. • L’avaluació normal pot ser molt ineficient ja que pot requerir l’avaluació d’un argument més d’una vegada. • fun double x = plus x x • double(fact 5) == plus (fact 5) (fact 5) • farem l’avaluació del factorial de 5 dos cops! • L’avaluació mandrosa (o call by need) utilitza un mecanisme d’avaluació més sofisticat que evita aquesta avaluació utilitzant mecanismes de compartició de dades. Una imatge visual podria ser: • double(fact 5) == plus • (fact 5)

  5. Una funció es diu estricta si el seu resultat és indefinit quan s’aplica sobre un argument indefinit. No-estricta altrament. • Amb avaluació mandrosa els constructors són no-estrictes i les funcions definides pel programadors són estrictes només si així es requereix, es a dir, si inspeccionen els arguments per acarament de formes. • Amb avaluació ansiosa els constructors són estrictes i les noves funcions també.

  6. Terminació • En els llenguatges funcionals l’únic problema a considerar quan es parla d’estratègies d’avaluació és el de la terminació. Diferents estratègies donen diferents comportaments de terminació. • Introduirem una abreujatura, ž, per a denotar una expressió que està totalment indefinida i que no termina sota cap estratègia. Per exemple • ž = let fun f x = f x in f () end • Amb avaluació no-estricta tenim: • ž :: E ° ž ; E :: ž ° ž ; ž :: ž ° ž • i llavors amb la definició • fun tl (a :: x) = x • | tl [] = error “indefinit” • tenim que tl(ž::E) == E, mentre que tl(ž) és indefinit.

  7. Ajornament de l’avaluació • Una de les idees centrals de l’avaluació mandrosa és ajornar l’avaluació de les expressions fins que és necessari obtenir el seu valor. • Com a exemples d’ajornament considereu els exemples següents. El condicional és un exemple d’avaluació no-estricta en qualsevol llenguatge. En un llenguatge mandrós els condicionals no són un cas especial: fun true & b = b | false & b = false fun true or b = true | false or b = b if true then E1 else ž = E1 if false then ž else E2 = E2 if ž then E1 else E2 = ž fun cond true x y = x | cond false x y = y ;;llavors cond true E1 ž = E1 cond false ž E2 = E2 cond ž E1 E2 = ž

  8. Exemples • Com a exemple d’estalvi en l’avaluació d’arguments vegeu la igualtat en llistes: fun ([] = []) = true | ((a::x) = (b::y)) = (a =b) & (x = y) | ((a::x) = []) = false | ([] = (a::x)) = false ;;així 1::E1 = 2::E2 == (1 = 2) & (E1 = E2) == false & (E1 = E2) == false L’exemple següent sobre la comparació de les fulles d’un arbre dóna una idea molt clara del guany d’eficiència datatype ‘a bintree = Lf of ‘a | /\ of (‘a bintree * ‘a bintree) fun eqleaves t1 t2 = leavesof t1 = leavesof t2 and leavesof (Lf x) = [x] | leavesof (t1 /\ t2) = leavesof t1 @ leavesof t2

  9. Currents (Streams) • Una tècnica de programació molt important en la programació mandrosa és el disseny de programes seguint el paradigma de disseny de circuits. La idea bàsica és descomposar els programes en funcions que facin explícita l'estructura de fluxe de senyal. Vegeu les funcions: • fun sumqsen (Lf a) = if odd a then a * a else 0 • | sumqsen (t1 /\ t2) = sumarqsen t1 + sumarqsen t2 • fun fibsenars n = • letfun seguent k = • if k > n then [] • elselet val f = fib k • in if odd f then f::seguent (k + 1) • else seguent (k + 1) • in seguent 1 end

  10. Esquema de fluxe de senyal • sumqsen • * Enumerar les fulles d'un arbre. • * Filtrar-les seleccionant-ne les senars. • * Calcular els quadrats de les seleccionades. • * Acumular els resultats. • fibsenars • * Enumerar els enters de 1 a N. • * Calcular el número de Fibonacci per cada enter. • * Filtrar seleccionant els senars. • * Acumular els resultats en una llista. ENUMERAR fulles arbre FILTER senar? MAP quadrat ACUMULAR +, 0 ENUMERAR enters MAP fib FILTER senar? ACUMULAR cons, nil

  11. Exemples amb currents • Les funcions anteriors prenen ara la forma: fun sumqsen t = accumulate plus 0 (map (fn x => x * x) (filter odd (btreeop (consonto []) append t))) fun fibsenars n = accumulate cons [] (filter odd (map fib (enumerateint 1 n)))

  12. Estructures de dades infinites • Fins ara els objectes que no eren funcions, que es podien definir de forma recursiva, s’asumia que eren finits. Definir valors infinits és possible, i interessant, amb l’us de tècniques d’avaluació mandrosa. • L’us d’estructures infinites permet, de vegades, trobar solucions més simples. Així podriem definir (no admès en SML): val rec infbt1 = (Lf 6 /\ infbt1) val rec infbt2 = (infbt2 /\ Lf 2) /\ (Lf 3 /\ infbt1) Un cop definits aquests objectes els podem fer servir en computacions de forma segura ja que només una part de l’estructura serà expandida. leftmostleaf infbt1 == leftmostleaf (Lf 6 /\ infbt1) == leftmostleaf (Lf 6) == 6

  13. Més exemples • Vegeu exemples elegants val rec ones = 1::ones front 5 (map double (leavesof infbt1)) fun from n = n::from (n + 1) val nat = from 1 val rec nat = zip plus ones (0::nat) val rec factorials = 1::zip times nat factorials local fun sift a x = filter (non (multipleof a)) x in fun sieve (a::x) = a::sieve (sift a x) end Sieve Hd :: Tl Filter: Non multipleof Sieve val primers = sieve (from 2)

  14. Forma normal feble de capçal • El terme forma normal s’utilitza per anomenar una expressió que no es pot simplificar més. Una forma normal feble és una expressió que està en forma normal excepte per alguna subexpressió que denota el cos d’alguna funció no aplicada. • Ja que els valors funcionals (les expressions denotant el cos d’una funció) no tenen representació canònica no cal inspeccionar el cos de les funcions no aplicades per mostrar els resultats d’avaluaació. Per tant l’avaluació ha de produir expressions en forma normal feble. • En el cas de l’avaluació mandrosa sembla útil el concepte de forma normal feble de capçal. Aquesta forma normal pot tenir subexpressions no avaluades, però si l’expressió té un constructor aplicat sobre arguments no avaluats, la subsequent avalació dels arguments no farà variar el capçal de l’expressió. Per tant l’avaluació lazy d’una expressió es detè després de produir una forma normal de capçal feble i s’analitza per on continuar l’avaluació. • Per exemple: • 3+2 :: tl ones està en forma normal feble de capçal • (op ::)(3+2, tl ones)

  15. Exemple: Nombres de Hamming fun merge2 (a::x) (b::y)= if a < b then a::merge2 x (b::y) elseif a > b then b::merge2 (a::x) y else a::merge2 x y fun merge3 x y z = merge2 x (merge2 y z) val rec hamming = 1::merge3 (map (times 2) hamming) (map (times 3) hamming) (map (times 5) hamming) • Els nombres de Hamming són: • H={2p * 3q * 5r | p, q, r són enters no negatius} • El problema consisteix en generar-los en ordre:

  16. Usos de l’avaluació mandrosa • L’avaluació mandrosa ens permet entendre els programes interactius amb una visió funcional neta. El teclat i la pantalla es poden entendre com a currents, i els programes interactius com a funcions que s’apliquen sobre el current d’entrada i generen elements en el current de sortida. • Tanmateix, es poden obtenir guanys en eficiència molt importants amb aquesta avaluació. Normalment és una bona pràctica començar amb un programa menys eficient, amb avaluació ansiosa, i, després, derivar una versió més eficient a partir d’ell. • Ho veurem amb un exemple molt comú. Moltes vegades es fa necessari recorrer una estructura de dades més d’una vegada per a realitzar ub càlcul. Amb avaluació mandrosa amb una única passada pot ser suficient.

  17. replacemin • El problema consisteix en transformar una arbre binari en un altre d’idèntic però amb els valors de les fulles contenint, totes elles, el valor mínim de les fulles de l’arbre original. • La solució directe és recorrer l’arbre per trobar el valor mínim i tornar-lo a recórrer per generar-ne el nou. fun replaceandmin (Lf a, repval) = (Lf repval, a) | replaceandmin (t1 /\ t2, repval) = letval (newt1, min1) = replaceandmin(t1, repval) and (newt2, min2) = replaceandmin(t2, repval) in (newt1 /\ newt2, min min1 min2) end fun replacemin bt = let val rec (newbt, minval)=replaceandmin(bt,minval) in newbt end

  18. Una altra versió • La versió següent és compatible també amb una avaluació ansiosa utilitzant programació d’ordre superior. fun fmin (Lf a) = let fun f m = Lf m in (f, a) end | fmin (t1 /\ t2) = let val (f1, min1) = fmin t1 and (f2, min2) = fmin t2 fun f m = f1 m /\ f2 m in (f, min min1 min2) end fun replacemin bt = let val (f, m) = fmin bt in f m end

More Related