Reductiemachine Functionele talen en dus de -calculus, worden vaak geïmplementeerd door een reductiemachine. De elementaire stap is een reductie, en de.

Slides:



Advertisements
Verwante presentaties
Life in the universe.
Advertisements

Les 2 klassediagrammen II
Sudoku puzzels: hoe los je ze op en hoe maak je ze?
KINN 2010 •OOP •O Object •O Georiënteerd •P Programmeren.
Programmeren met Alice
ADS Verborgen bestanden (stromen) Cum 13 juli 2008 Rudiger.
PHP & MYSQL LES 03 PHP & DATABASES. PHP & MYSQL 01 PHP BASICS 02 PHP & FORMULIEREN 03 PHP & DATABASES 04 CMS: BEST PRACTICE.
Lijsten in de -calculus Een lijst [E 1, E 2,..., E n ] kan in de -calculus voorgesteld worden als z.((z E 1 ) z.((z E 2 )... z.((z E n ) nil)...) met nil.
Uitwerking tentamen Functioneel Programmeren 29 januari 2009.
Practica Computerlinguistiek Tekst en uitleg:
Hogere-ordefuncties nEen lijst langs lopen en met elk element iets doen nEen lijst langs lopen en sommige elementen selecteren map filter.
Klassen en objecten.
Programmeerparadigma’s
Hoofdstuk 6: Controle structuren
 - congruentie -regel:
Compositionaliteit, bereik en lambda’s
1 Datastructuren Sorteren: alleen of niet alleen vergelijkingen College 5.
Hogere-orde functies: herhaald patroon? Parametrizeer! product :: [Int]  Int product [ ]= product (x:xs)= 1 product xs x * and :: [Bool]  Bool and [
Functies op Proposities evalueer:: Bedeling  Prop  Bool tautologie:: Prop  Bool contradictie:: Prop  Bool equivalentie:: Prop  Prop  Bool vervulbaar::
Hoger-ordefuncties op lijsten nDoorloop een lijst en... map :: (a  b)  [a]  [b] filter :: (a  Bool)  [a]  [a] foldr :: (a  a  a)  a  [a]  a.
Parallelle Algoritmen String matching. 1 Beter algoritme patroonanalyse Bottleneck in eenvoudig algoritme: WITNESS(j) (j = kandidaat in eerste i-blok)
Assenstelsels en het plotten van Functies in LOGO
Deel I: Functionele Programmeertalen Hoofdstuk 5: Implementatie- technieken.
1 Prof. Dr. Martine De Cock academiejaar Lambdarekenen.
Natuurlijke-Taalinterfaces week 3 1. evaluatie van een formule in een model 2. vraag-antwoord dialogen 3. Modellen en applicaties.
Normalisatie Relationeel databaseontwerp:
Natuurlijke-Taalinterfaces week 5 Lambda-termen en Lambda-conversie.
T U Delft Parallel and Distributed Systems group PGS Fundamentele Informatica in345 Deel 2 College 5 Cees Witteveen.
Het verbeteren van een modulaire verificatie techniek voor aspect georiënteerd programmeren Alfons Laarman.
Functies als Getallen Jan Martin Jansen.
Numerieke Natuurkunde
-calculus.
Functies definiëren nDoor combinatie van standaardfuncties fac :: Int  Int fac n = product [1..n] oneven :: Int  Bool oneven n = not (even n) negatief.
Char en String nCharéén letter uord ::Char  Int uchr ::Int  Char nString[Char] uwords :: String  [String] uunwords :: [String]  String ”hoi” ”CKI”
Hogere-ordefuncties nVoeg de elementen van een lijst samen nCombineer twee functies foldr :: (a  b  b)  b  [a]  b [a] (.) :: (b  c)  (a  b)  a.
Reguliere talen nReguliere grammatica: versimpelde Contextvrije grammatica nFinite-state Automaton: andere manier om een taal te beschrijven nReguliere.
Optuigen van datastructuren
Imperatief programmeren nProgramma bestaat uit nRunnen is opdrachten gegroepeerd in methoden één voor één uitvoeren te beginnen met main.
Functioneel Programmeren Daan Leijen. Wat gaan we doen? 3 fundamentele principes van computatie Equationeel redeneren IO-monad GUI's in Haskell (wxHaskell)
Looking at Code Size and Performance Kevin Muys.  Hoe efficiënt is C++ vergeleken met C  Hoe beïnvloed C++ het benodigde geheugen  Oplossingen voor.
1 Datastructuren Een informele inleiding tot Skiplists Onderwerp 13.
Eenvoudig voorbeeld: Steden in Belgie
PHP & MYSQL LES 02 PHP & FORMULIEREN. PHP & MYSQL 01 PHP BASICS 02 PHP & FORMULIEREN 03 PHP & DATABASES 04 CMS: BEST PRACTICE.
Hoe brei een team?.
Werken in K.U.Loket Syllabi. 1 ZoekmogelijkhedenVolledige lijst opvragen is ook mogelijk, maar kan lang duren Start in K.U.Loket de toepassing “mijn syllabi”
Taal nEen Alfabet is… een eindige verzameling symbolen nEen Taal is… een deelverzameling van T* bij een bepaald alfabet T nEen Zin is… een element van.
AI101  Historisch Perspectief Weak Methods Logic Theorist General Problem Solver  Resolution Theorem Proving Leeswijzer: Hoofdstuk 13.0, 13.1, 13.2 AI.
Samenvatting hst. 3 sec. 1-3 ( ) :: Parser a b  Parser a b  Parser a b ( ) :: Parser a (b  c)  Parser a b  Parser a c ( ) :: (b  c)  Parser a b.
Tircms03-p les 2 Hfdst 3,4 Meer operatoren Functies.
Tircms02-p les 3 Functies Strings Structuren. Functies 1. main() 2. { int k; k = 10 ; printf(“%d\n”,fac(k)); } 3. int fac(n) int n; 4. { int f; f= 1;
Tircms02-p les 2 Meer operatoren Arrays en pointers Types en conversie.
tircms02-p les 1 Operating Systems practicum
1 XSLT processing & control Datamodellering 2006.
PROGRAMMEREN LOGISCH en FUNCTIONEEL Ik zeg wat ik denk!
Functioneel programmeren Een snelle herhaling…. Functie-definitie static int kwad (int x) { return x*x ; } kwad x = x * x Haskell kwad :: Int  Int.
Instructie Programmeren Task 7
?.
Les 0 Structured Query Language SQL. Programma Les 0 – Introductieopdracht Les 1 Les 2 Les 3 Schriftelijke toets.
Programmeren.
Hoorcollege 1: efficiëntie en complexiteitsontwikkeling.
Hoorcollege 1: efficiëntie en complexiteitsontwikkeling.
Hoe maak ik een PowerPoint presentatie?
Codetuts Academy Les 6 Module 2a Php Fundamentals 1.
Les 3 - Operators Workshop Php Basic. ICT Academy Php Basic Content Operators Wiskundig Toewijzing Vergelijking.
Doorzoeken van grafen Algoritmiek. Algoritmiek: Divide & Conquer2 Vandaag Methoden om door grafen te wandelen –Depth First Search –Breadth First Search.
GUI & classes Een Gui in een class steken en het object gebruiken.
Berekening van de Orde Van een Algoritme
Tinpro015b-les3 Hfdst 3,4 Meer operatoren Functies.
Het postkantoor van windows
-calculus versus Scheme
Transcript van de presentatie:

Reductiemachine Functionele talen en dus de -calculus, worden vaak geïmplementeerd door een reductiemachine. De elementaire stap is een reductie, en de "machinetaal" bestaat uit reductiestappen. In principe kan men die in hardware realiseren (LISP machine). Het uit te voeren programma is één -expressie, die stapsgewijs gereduceerd wordt tot normaalvorm. De expressie kan als een string symbolen voorgesteld worrden, maar dat vereist veel kopieerwerk. Daarom gebruiken moderne implementaties een graph voorstelling. Dat maakt wel het memory-management moeilijker, en heeft geleid tot de ontwikkeling van allerlei technieken voor garbage collection. In de vorm die we totnogtoe gezien hebben zijn  -conversie en  -reductie nog te complex om als één stap gezien te worden, we vervangen ze door meer elementaire stappen.

let en eval Om het programmeren te vergemakkelijken voert men "syntactic sugar" toe, zoals de mogelijkheid om hulpfuncties te definiëren (let) en om de evaluatie expliciet te starten (eval) staat voor: let f = E 1 let g = E 2 eval E 3 ( f.( g.E3 E2) E1)

Graph voorstelling Een -expressie wordt voorgesteld door haar parse tree, maar met extra pijlen die ervoor zorgen dat er cycli kunnen voorkomen. Dit betekent dat het originele programma gemakkelijk terug gereconstrueerd kan worden: in principe volstaat een depth-first doortocht van de parse tree. Soorten knopen: abstractie: x applicatie: : infix lijstconstructor:, lijst-einde of lege lijst: [ ] numerieke waarde: # variabele: x,y,z,... combinator: Y, true, false operator: head, tail, cons, +, -,... renaming: {z/x}

Graph voorstelling: voorbeelden (( x. y.(x (y x)) 2) [E,F]) y :,, [ ] x 2 ::: xxy E F

Graph voorstelling: voorbeelden let fact = n.(((iszero n) 1) ((mult n) (fact (pred n)))) eval E : : : : n fact : iszero E : 1 * n pred : : nn

De regels Voor  -conversie en  -reductie gebruikten we totnogtoe volgende regels.  -regel: x.E  z.{z/x}E  -regel: ( x.E Q)  [Q/x]E Daarnaast zijn er de regels voor lijsten en constante symbolen. Omdat de expressies willekeurig complex kunnen zijn kan men het uitvoeren van die substituties niet als een elementaire stap opvatten. Daarom vervangen we deze regels door nieuwe, die wel elementaire stappen voorstellen. De regels voor lijsten worden iets sterker; we laten toe de applicatie van een lijst om te zetten in een lijst van applicaties - dit leidt tot de zgn.  -regels.

Aangepaste regels Voor  -conversie:  1 : {z/x}x  z  2 : {z/x}E  E als x niet vrij in E  3 : {z/x} y.E  y.{z/x}E als x, y en z verschillend  4 : {z/x}(E 1 E 2 )  ({z/x}E 1 {z/x}E 2 )  5 : {z/x}[E 1,...,E n ]  [{z/x}E 1,..., {z/x}E n ] De {z/x} wordt dus gewoon doorgeschoven naar binnen in de expressie.

Aangepaste regels Voor  -conversie:  1 : ( x.x Q)  Q  2 : ( x.E Q)  E als x niet vrij in E  3 : ( x. y.E Q)  z.( x.{z/y}E Q) als x verschillend van y, en z komt niet voor in E of in Q  4 : ( x.(E 1 E 2 ) Q)  (( x.E 1 Q) ( x.E 2 Q)) Voor  3 : we willen ( x. y.E Q)  [Q/x] y.E maar alleen als y "veilig" is. Dus beginnen we met y alvast te vervangen door een "verse" z. Omdat die uiteraard verschillend is van x kunnen we de x naar binnen schuiven, voorbij de z.

Aangepaste regels: de  - regels ( x.[E 1,...,E n ] Q)  [( x.E 1 Q),..., ( x.E n Q)] Voor lijsten vervangt men de regel Door de zgn.  -regels:  1 : ([E 1,...,E n ] Q)  [(E 1 Q),..., (E n Q)] en  2 : x.[E 1,...,E n ]  [ x.E 1,..., x.E n ] Deze regels, samen met die voor de combinatoren en operatoren, kunnen nu omgezet worden naar elementaire stappen voor de reductiemachine.

Stappen:  -regels {z/x}x  z {z/x}E  E als x niet vrij in E {z/x} y.E  y.{z/x} E als x  y  z y z/x x z x E y E y E   

Stappen:  -regels {z/x}(E 1 E 2 )  ({z/x}E 1 {z/x}E 2 ) {z/x}[E 1,...,E n ]  [{z/x}E 1,...,{z/x}E n ] z/x : E1E1 E2E2 : : E1E1 E2E2,, A B, A B  

Stappen:  -regels  1 : ( x.x Q)  Q x x Q :  x x  2 : ( x.E Q)  E als x niet vrij in E x Q : E x E 

Stappen:  -regels  3 : ( x. y.E Q)  z.( x.{z/y}E Q) als x en y verschillen, en z is vers: noch vrij, noch gebonden in (E Q) y x Q : E Q y x E z x z/y : 

Stappen:  -regels  4 : ( x.((E 1 E 2 ) Q)  (( x.E 1 Q) ( x.E 2 Q))  x Q : : E1E1 E2E2 x Q : : E1E1 E2E2 : x x :

Stappen:  -regels  1 : ([E 1,...,E n ] Q)  [(E 1 Q),..., (E n Q)] , C : A B, C, A B : :

Stappen:  -regels  2 : x.[E 1,...,E n ]  [ x.E 1,..., x.E n ] , A B x, A B x x,

In plaats van de cyclische representatie te gebruiken, kunnen we ook de Y-combinator expliciet voorstellen, en volgende regel gebruiken. Het gebruik van de cyclische representatie van recursieve functies blijkt gewoonlijk efficiënter te zijn. Y combinator  : Y F : Y F :

Opmerkingen Ook voor de combinators null, +, head,... zijn er uiteraard dergelijke operaties. De operaties behouden altijd de knopen aan de linkerkant (er kunnen nog andere pijlen zijn naar die knopen) en wijzigen enkel van de root het label. Op die manier is het duidelijk hoe het vervangen deel van de graph vasthangt aan de rest. De operaties voeren nooit nieuwe cycli in; de enige cycli zijn die veroorzaakt door recursieve definities.

Implementatie Om de knopen voor te stellen gebruikt men bv. 4 velden : ( code, op 1, op 2, marker) (marker voor de garbage collector). Het herkennen van een patroon in een graph is in het algemeen een moeilijk probleem. Gelukkig zijn de te herkennen patronen hier erg klein. Om een  -redex te vinden: gebruik een depth-first traversal om het volgende patroon op te sporen: : x N1N1 N2N2 N3N3

Implementatie Als N 2 geen abstractieknoop is, dan is N 1 niet de root van een  -redex. Anders, zoek een vrije occurence van x in de boom onder N 3. Als er geen te vinden is, dan hebben we een  2 -redex. Als er wel een gevonden wordt, dan bepaalt het veld code van N 3 of we een redex voor  1,  3 of  4 herkennen. Als N 3 noch een variable-, noch een abstractie-, noch een applicatieknoop is, dan is N 1 niet de root van een  -redex. Het zoeken naar een vrije occurence van x voor herkennen van een  2 - redex kan uitgevoerd worden in een depth-first doortocht. Ook voor  -redexen kunnen we volstaan met het onderzoeken van 2 knopen, met weer een extra test voor  2.

Evaluatie-orde Doordat we nu andere regels hebben is normal order evaluatie niet meer helemaal wat we nodig hebben: bv (( x. y.E P) Q)  (  3 ) ( z.( x.{z/y}E P) Q)  (  4 ) (( z. x.{z/y}E Q) ( z.P Q))  (  3 ) ( v.( z.{v/x}{z/y}E Q) ( z.P Q))  (  4 ) (( v. z.{v/x}{z/y}E ( z.P Q)) ( v.Q ( z.P Q))) ... Afspraak: na  3 verder gaan met het deel na de nieuwe (meest linkse).

Evaluatie-orde Eager, applivative order: argumenten eerst. Demand - driven: argumenten pas evalueren als nodig. Lazy: ook de argumenten maar partieel evalueren als dat volstaat. Normal order: meest linkse redex. In ons systeem komt dat overeen met lazy. Lazy evaluatie is niet altijd efficiënt: ( x.((+ x)(pred x)) ((* 5) (succ 3)))  (  4 ) met Q = ((* 5) (succ 3)) (( x.(+ x) Q) ( x.(pred x) Q))  (  4 ) ((( x.+ Q) ( x.x Q)) ( x.(pred x) Q))  (  1,  2 ) ((+ ((* 5) (succ 3))) ( x.(pred x) Q))  (regels voor *, succ) ((+ 20) ( x.(pred x) Q)) ... en Q moet opnieuw geëvalueerd worden.

Graph reductie De boom van Q = ((* 5) (succ 3)) wordt niet gedupliceerd: 3 : :: : : : : 5 pred x + x * succ x  44

Graph reductie 3 : :: : : : : 5 pred x + x * succ x : : x x

Opmerkingen Deze reductiemachine kan uiteraard geperfectioneerd worden, bv, door parallellisme te gebruiken. Moderne implementaties halen de efficiëntie van een behoorlijke C compiler. I/O, of andere neveneffecten, kan men inbouwen door gebruik te maken van monads: interpreteer sommige symbolen m als acties; en bekijk paren (m,a), met m een actie en a een waarde. Er is een sequencing operatie >>= van type m a  ( a  m b )  m b Informeel: een actie die een a oplevert kan samengesteld worden met een functie die op basis van een a een actie geeft die een b oplevert. Het resultaat is een actie die een b oplevert.

Unificatie In Haskell wordt pattern matching gebruikt in de definitie van functies, bv. in qsort: matching qsort [x:xs] met [3,2,4,1,5] resulteert in de binding van x aan 3 en van xs aan [2,4,1,5]. Ook by typechecking komt een dergelijke situatie voor: als men een functie f wil toepassen op een argument arg, dan moet de typedescriptor van f van de vorm td 1  td 2 zijn, en als arg typedescriptor td arg heeft, dan moeten td 1 en td arg "gelijk gemaakt" kunnen worden, door vereenvoudigingen, maar ook door de vervanging van typevariabelen door meer concrete typedescriptoren. Dit "gelijk maken" (en tegelijk variabelen binden) noemt men unificatie Ook in logische talen speelt unificatie een belangrijke rol.

Unificatie qsort(cons(x, xs)) en cons(3, cons(2, cons(4, cons(1, cons(5, [ ]))))) (in gewone mathematische notatie) resultaat: x = 3 xs = cons(2, cons(4, cons(1, cons(5, [ ])))) mult(add(4, 5), minus(y)) en mult(add(x,y), z) resultaat: x = 4 y = 5 z = minus(5) mult(add(4, 5), minus(y)) en mult(add(x,y), 8) resultaat: fail

Unificatie: algemeen Gegeven: twee termen, T 1 en T 2, opgebouwd uit - variabelen - constanten - functie-applicaties ("Functoren", in logisch programmeren) Gevraagd: een meest algemene unifier (most general unifier, MGU) voor T 1 en T 2 unifier: een substitutie  (afbeelding van de variabelen naar de termen) die voldoet aan  ( T 1 ) =  ( T 2 ) most general unifier: een unifier met de eigenschap dat, voor elke andere unifier  ', geldt dat  '( T 1 ) een instantie is van  ( T 1 ), m.a.w. er is een substitutie  die van  ( T 1 )  '( T 1 ) maakt:  (  ( T 1 )) =  '( T 1 ) (er geldt dan ook  (  ( T 2 )) =  '( T 2 ) natuurlijk).

Unificatie: algoritme van Robinson MGU = { }; WS = { (T 1, T 2 ) } repeat verwijder een paar (R 1, R 2 ) uit WS; case R 1 en R 2 zijn twee identieke variabelen of constanten: skip; R 1 is een variabele die niet voorkomt in R 2 : vervang, overal in WS en MGU, R 1 door R 2 ; voeg (R 1, R 2 ) toe aan MGU; R 2 is een variabele die niet voorkomt in R 1 : vervang, overal in WS en MGU, R 1 door R 2 ; voeg (R 1, R 2 ) toe aan MGU; R 1 = f(y 1,...,y n ) en R 2 = f(z 1,...,z n ): voeg {(y 1,z 1 ),...,(y n,z n )} toe aan WS otherwise return(fail) end case until WS = { }