Inkrementelle metoder til REA-baseret rapportering

Størrelse: px
Starte visningen fra side:

Download "Inkrementelle metoder til REA-baseret rapportering"

Transkript

1 Inkrementelle metoder til REA-baseret rapporterg Speciale Daniel Brixen Januar 2005 Datalogisk Institut Københavns Universitet

2 Abstract This thesis describes a method for automatic generation of cremental programs from their noncremental counterparts. The method is spired by work by Annie Liu on cremental computation and by Robert Paige on fite differencg. The language FunSETL is defed. It is a first-order functional language, which is used to express programs which implement accountg-reports based on a simple REA-model. REA (Ressource- Event-Agent) was origally a model for designg databasesystems and ERP-systems. Reportprograms for a REA-model are obvious candidates for transformation to cremental versions, because they perform the same calculations over and over aga. We illustrate how the described method is able to automatically derive cremental versions of some typical accountg reports, and how these cremental versions has significantly better performance than the origal programs. The method is implemented along with a prototype compiler for FunSETL. 1

3 Indholdsfortegnelse 1 Indledng Formål Sammenfatng Læsevejledng REA-modellen Introduktion Indholdet i REA-modellen Egenskaber ved REA-modellen Implementerg af REA-modellen Tilføjelser til REA-modellen En simplificeret REA-model REA-baseret rapporterg Overordnet om rapporterg Resultatopgørelse Balance Likviditetsbeskrivelse Eksempel-rapporter FunSETL Sprogdefition Typekorrekthed Semantik Inkrementelle metoder Fælles deludtryk Strength reduction Formel differentierg Fite differencg Inkrementel beregng Inkrementaliserg af FunSETL Extend-transformationen Recordtyper Eksempler Standardværdier Transformerg af udtryk Transformerg af funktioner Transformerg af programmer Egenskaber for Extend e Egenskab for Extend

4 INDHOLDSFORTEGNELSE INDHOLDSFORTEGNELSE 7 Clean-transformationen Statisk evaluerg af recordudtryk Indlejrede let-udtryk Transformationen Clean Egenskaber for normlets Egenskaber for elimreclabs Clean er semantikbevarende Inkrementaliserg Eksempel Defition af opdatergsoperation Transformationen unfoldlet Relationen simp Inkrementaliserg af en funktion uden funktionskald Inkrementaliserg af funktionskald Egenskab for c Samlet metode Implementerg af FunSETL Udvidelse af sproget Oversættelse til ML Eksekverg af et program Kommandolieværktøjet compiler Kommandolieværktøjet crementalizer Visualiserg Resultater Typiske funktioner Om prissætng af varer Kørsler Konklusion Sammenligng med eksisterende metoder Litteratur 94 A Rapportprogrammer 97 A.1 Resultatopgoerelse.cfg A.2 Resultatopgoerelse.fs A.3 Balance.cfg A.4 Balance.fs A.5 Likviditetsbeskrivelse.cfg A.6 Likviditetsbeskrivelse.fs A.7 Basefunktioner B Inkrementaliserede rapportprogrammer 109 B.1 ResultatopgoerelseInc.fs B.2 BalanceInc.fs B.3 LikviditetsbeskrivelseInc.fs B.4 Basefunktioner.sig B.5 Basefunktioner.sml

5 INDHOLDSFORTEGNELSE INDHOLDSFORTEGNELSE C Sprogdefition 156 C.1 FunSETLPos.sig C.2 FunSETLPos.sml C.3 Lexer.lex C.4 Parser.grm D Inkrementalisergsmetode 166 D.1 Extend.sig D.2 Extend.sml D.3 Clean.sig D.4 Clean.sml D.5 Inc.sig D.6 Inc.sml D.7 Incrementalizer.sml

6 Kapitel 1 Indledng Denne opgave udgør et speciale fra Datalogisk Institut, Københavns Universitet. Specialet er udarbejdet som en del af NEXT-projektet, der er et forskngssamarbejde mellem Microsoft Busess Solutions, IT-Universitetet i København og Datalogisk Institut på Københavns Universitet 1. Fritz Hengle har været vejleder på specialet. 1.1 Formål REA-modellen er en hændelsesorienteret model til at designe bogførgssystemer (for eksempel ERP-systemer), hvor der skelnes mellem basale data og formationer, der kan afledes herfra. I s simpleste form registeres kun basale data, og afledte formationer vedligeholdes ved rapportprogrammer, der bygger på de basale data. En krementel version af et program, er et transformeret program, der genbruger værdier fra tidligere beregnger til at give en mere effektiv måde at beregne resultatet af det origale program. Denne opgave har til formål at Undersøge eksisterende metoder til at konstruere krementelle programmer ud fra ikkekrementelle versioner (for eksempel fite differencg ). Defere en REA-baseret model der kan udtrykke sædvanlige fansielle rapporter som for eksempel Resultatopgørelse, Balance og Likviditetsbeskrivelse ved hjælp af et funktionsorienteret programmergssprog. Demonstrere eller afvise brugbarheden af systematisk og automatisk konstruktion af krementelle versioner af de nævnte funktioner i den opstillede kontekst. 1.2 Sammenfatng I opgaven udvikles en metode til automatisk genererg af krementelle programmer ud fra ikkekrementelle versioner. Metoden er spireret af arbejde udført af blandt andre Annie Liu og Robert Paige. Sproget, der behandles, er et førsteordens funktionsorienteret sprog, og i opgaven vises, hvordan det kan bruges til at udtrykke programmer, der implementerer bogførgsrapporter baseret på en simpel REA-model. Den udviklede metode er implementeret, og afprøvng viser, at de automatisk genererede programmer har et lavere tidsforbrug end de origale rapport-programmer. 1 Se 5

7 Indledng 1.3 Læsevejledng Ideen med at bruge krementelle metoder til at løse effektivitets-problemer i forbdelse med REA-rapporterg kommer fra artiklen [1], der dog kun viser et enkelt eksempel. Jeg er ikke bekendt med, at der tidligere er publiceret resultater af arbejde med at implementere en automatisk krementalisergsteknik i forbdelse med REA-baseret rapporterg. 1.3 Læsevejledng I kapitel 2 troduceres REA-modellen, og en simpel version bruges i kapitel 3 til at udtrykke bogførgsrapporterne. I kapitel 4 deferes sproget FunSETL, og der vises nogle egenskaber ved dets semantik. Den sidste del af kapitlet deholder beviser for disse egenskaber. Ved gennemlæsng kan man eventuelt sprge beviserne over, og gå videre til kapitel 5, der giver et kort overblik over nogle eksisterende krementelle metoder. Kapitlet afsluttes med et overblik over den udviklede metode. De tre kapitler 6, 7 og 8 beskriver detaljerne i de tre tr, der udgør den udviklede krementalisergsmetode. Kapitlerne begynder med eksempler og motiverg og afsluttes med at bevise nogle egenskaber for transformationerne. Som før kan man eventuelt sprge beviserne over og gå videre til næste kapitel. Kapitel 9 beskriver, hvordan FunSETL-programmer eksekveres. Til det formål er der implementeret en prototypeoversætter fra FunSETL til Standard ML. I kapitel 10 vendes tilbage til bogførgsrapporterne fra kapitel 3, og resultaterne, der fremkommer ved at krementalisere rapporterne med den udviklede metode, diskuteres. Kapitel 11 deholder en konklusion og sammenligner den udviklede metode med eksisterende arbejde. Bilag A-D deholder kildekode fra opgaven. Kildekoden til oversætteren er udeladt af pladshensyn den fylder omkrg 80 sider. På kan man fde en fil, der deholder den samlede kildekode. Det vil være en fordel, hvis læseren er bekendt med Annie Lius arbejde med cremental computation, men det er ikke et krav. 6

8 Kapitel 2 REA-modellen I dette kapitel troduceres REA-modellen. Først ser vi på, hvilke dele modellen består af, og dernæst beskrives nogle af modellens karakteristika. Artiklen [2] deholder den oprdelige beskrivelse af REA-modellen. Her beskrives REAmodellen som en model, der kan bruges til at designe databasesystemer til bogførgssystemer. Senere er der beskrevet ændrger og en række tilføjelser til modellen. Nogle af disse nævnes i afsnit 2.5. I afsnit 2.6 viser vi et eksempel på en simplificeret REA-model, der bruges i kapitel 3 som udgangspunkt for at udtrykke sædvanlige bogførgsrapporter. 2.1 Introduktion Betegnelsen REA er en forkortelse for økonomiske ressourcer (resource), økonomiske hændelser (event) og økonomiske agenter (agent). Kort fortalt er REA-modellen en generaliseret E-R-model 1 for en database, hvis hovedbestanddelene er mængder, der repræsenterer ressourcer, hændelser og agenter. Ifølge [2] skal arbejdet med at lave et databasedesign resultere i to tg: en (global) datamodel og en række (lokale) views. Datamodellen i E-R-form er én måde at betragte data på. De lokale views er andre måder at betragte data på, og for hvert lokalt view, skal der være en beskrivelse af, hvordan det kan afledes fra den globale model. Et eksempel på et simpelt view kunne være, at udvælge dele af den globale model. I [2] bruger McCarthy betegnelserne konceptuelt og eksternt skema om henholdsvis den globale model og de lokale views. Hoveddholdet i [2] er at beskrive, hvordan REA-modellen kan bruges som værktøj til at producere og udtrykke det konceptuelle skema. 2.2 Indholdet i REA-modellen Entiteterne ressource, hændelse og agent deferes nærmere i [2] vi nøjes her med en tuitiv forståelse af, at en ressource for eksempel er en salgsvare, penge eller en serviceydelse, en agent for eksempel er en person eller et firma, og at en hændelse er en overførsel af en resource fra en agent til en anden. Udover de nævnte entiteter er der i den grundlæggende REA-model 3 relationer: stock-flow, dualitet og deltagelse. Relationen stock-flow relaterer ressourcer med hændelser, for eksempel kan en hændelse beskrive overførslen af 3 ressourcer. En hændelse repræsenterer en stigng eller et fald i antallet af ressourcer. Relationen dualitet bruges til at koble en hændelse, der giver en stigng, sammen med en hændelse, der giver et fald. 1 Entity-Relation modellen er beskrevet i database-litteraturen, se for eksempel [3]. 7

9 REA-modellen 2.3 Egenskaber ved REA-modellen For en hændelse, der repræsenterer et varesalg (altså et fald i antallet af varer på lager), kunne den duale hændelse være betalg af varen (altså en stigng af kassebeholdngen). Relationen deltagelse relaterer agenter med hændelser. Figur 2.1 viser et billede af den simple REA-model, hvor entiteterne ressource, hændelse (event) og agent er forkortet med henholdsvis R, E og A. Figur 2.1: Forenklet version af REA-modellen 2.3 Egenskaber ved REA-modellen REA-modellen blev udviklet som et forsøg på at løse problemer, der fandtes i traditionelle bogførgssystemer, der brugte dobbelt bogholderi (se kapitel 3 for yderligere formation). Et af problemerne var, at i stedet for at registrere basale data, blev der registreret sammenfattede formationer. For eksempel kan ét system registrere en mængde af lønudbetalger, mens et andet kun registrerer den samlede lønudbetalg pr. måned. I [2] angives det som et problem, fordi datasamlgen sandsynligvis skal være en del af et større ERP-system i virksomheden, og andre dele af systemet kan have brug for andre måder at sammenfatte data på. Som en konsekvens af dette registreres der i REA-modellen kun basale data, og ikke data, der kan afledes fra de basale data. Betragt som et naivt eksempel, hvordan en bankkonto kan modelleres: de basale data er en mængde af transaktioner, der overfører penge til eller fra kontoen. En afledt eller sammenfattet formation er den aktuelle saldo på kontoen. Hvis det kun er saldoen der vedligeholdes, er det ikke muligt at give svar på spørgsmål som for eksempel: Er huslejen for januar måned betalt?, eller hvor stor en del af saldoen kommer fra løndbetalger?. Hvis det derimod er de basale data, der registreres, kan den aktuelle saldo beregnes ved at se på transaktionerne, og de nævnte spørgsmål kan besvares ud fra transaktionerne. Det giver altså en større fleksibilitet at registrere de basale data frem for sammenfattede data. 2.4 Implementerg af REA-modellen Artiklen [2] deholder nogle overvejelser omkrg, hvordan det konceptuelle skema fra REAmodellen omsættes til et ternt skema, der kan bruges til implementerg. Et kernepunkt er, hvordan de afledte formationer skal vedligeholdes, når der tilføjes data, uden at det giver problemer med for stort tidsforbrug. McCarthy fører begrebet konklusions materialiserg, der betyder, at der periodisk tages et øjebliksbillede af (nogle af) de afledte formationer. Dette øjebliksbillede er konsistent med databasen, dtil der tilføjes nye data. Hvis de afledte formationer skal være konsistente med data i databasen, skal der tages et øjebliksbillede hver gang der tilføjes nye data, men hvis det ikke er nødvendigt at have et øjebliksbillede, der er helt konstistent med databasen, kan man nøjes med at lave nye øjebliksbilleder sjældnere. Artiklens bud på, hvordan man løser problemet med tidsforbrug i forbdelse med at vedligeholde afledte formationer, er at give køb på at have formationer, der er konsistente på ethvert tidspunkt. Betragt igen eksemplet med modellerg af en bankkonto, hvor der registreres overførsler til og fra kontoen. Saldoen på kontoen er en funktion af transaktionerne til og fra kontoen. På en konto skal saldoen måske kun bruges et par gange hver måned, mens der er transaktioner hver 8

10 REA-modellen 2.5 Tilføjelser til REA-modellen dag. Så er det kun nødvendigt at opdatere saldoen den ene gang pr. måned. Men hvis der er mange transaktioner på kontoen, er det stadig en tidskrævende operation at behandle alle transaktioner for at fde den opdaterede saldo. Løsngen fra [2] kan altså give færre beregnger ved tilføjelse af nye data, men giver ikke nogen ideer til, hvordan de afledte formationer kan opdateres, uden at gøre det på den direkte måde ved at betragte alle basale data. Vi vender tilbage til denne problemstillg i kapitel 5. Figur 2.2: Tilføjelse af commitments (C) og agreements (Agr) til REA-modellen 2.5 Tilføjelser til REA-modellen I dette afsnit ser vi på nogle af de udvidelser, der er foreslået til REA-modellen. I artiklen [4] beskrives REA-modellen som en ontologi. Desuden foreslås en række ændrger til modellen, hvoraf vi viser en enkelt her. De resterende består af tilføjelse af to abstrakte lag, der giver mulighed for at give typer til entiteter, og at beskrive relationer mellem typer. Disse udvidelser beskrives ikke, da de ikke er relevante for denne opgave Forpligtelser og kontrakter Begrebet forpligtelser (commitments) dbygges i REA-modellen ved at tilføje to entiteter og fire relationer. En forpligtelse er et løfte om, at en agent udfører en given hændelse senest på et bestemt tidspunkt i fremtiden. På samme måde som for hændelser, relateres forpligtelser med handen, så en stigng i antallet af ressourcer relateres med et korresponderende fald i antallet af ressourcer og omvendt. Det er relationen reciprok der bruges til dette. Relationen udfører bruges til at relatere en forpligtelse med de hændelser, som opfylder forpligtelsen. 9

11 REA-modellen 2.6 En simplificeret REA-model Relationerne reserverer og partner bruges til at koble ressourcer og agenter sammen med forpligtelser. Hvis en forpligtelse reserverer en ressource betyder det, at i de hændelser, der opfylder forpligtelsen, overføres de nævnte ressourcer. Til sidst tilføjes entiteten kontrakt, der i [4] kaldes agreement. En kontrakt består af en samlg forpligtelser, hvilket registreres med entiteten kontrakt og relationen opfylder. Figur 2.2 viser et billede af den udvidede model Perspektiver REA-modellen, som den er præsenteret i [4], er perspektiv-afhængig. Det betyder kort sagt, at overførsler foregår mellem agenter, der er klassificerede som terne eller eksterne. Det er naturligvis afhængig af, hvilket perspektiv overførslen betragtes fra: i en overførsel fra en produktionsafdelg til en salgsafdelg, er produktionsafdelgen tern set fra den ene side, og ekstern set fra den anden side. I [5] behandles dette emne mere dgående, og der foreslås ændrger til REA-modellen fra [4], så den bliver uafhængig af perspektiv. Modellen, der præsenteres, er desuden ændret så nogle af de aksiomer der gives i [4] er dbygget i modellen. Det gør, at modellen kommer til at deholde mange entiteter og relationer 2 og derfor bliver uoverskuelig og vanskelig at arbejde med. Problemstillgen omkrg perspektivuafhængighed er ikke vigtig for denne opgave, så vi undlader at bruge ændrgerne, der er foreslået i [5]. Yderligere formation om REA-modellen kan fdes i [6], [7], [8] og [9]. 2.6 En simplificeret REA-model En af hovedpåstandene i artikelen [2] er, at datamodeller for bogførgssystemer ikke skal deholde elementer fra det dobbelte bogholderi, som for eksempel konti, debet eller kredit. Disse er i stedet afledte formationer fra data, der skal bruges til at konstruere for eksempel årsregnskaber. Vi ser nu på, hvordan en simpel REA-model kan give mulighed for at udtrykke bogførgsrapporter. Modellen fra figur 2.2 er brugt som udgangspunkt. De følgende afsnit beskriver den datamodel, der er fremkommet ved samtidig specificerg af bogførgsrapporterne og simplificerg af REAmodellen. Intuitionen bag simplificergen af datamodellen er, at vi ønsker en model, der er så simpel som muligt, men ikke for simpel forstået på den måde, at modellen skal kunne give mulighed for at udtrykke de tre bogførgsrapporter, der beskrives i kapitel 3, og samtidig være simpel, for at lette arbejdet med krementalisergen Ressourcer I den udviklede datamodel repræsenteres en ressource ved en endelig afbildng [s 1 pr 1, s 2 pr 2,..., s n pr n ] Her er s 1,... s n tegnstrenge, og pr 1,..., pr n er primitive ressourcer. En primitiv ressource er enten et reelt tal, eller et terval bestående af to tidsangivelser, for eksempel 4.5 eller [1/1 2004, 31/ ]. Ressourcen [ ] Cykel 3.0, DKR , Avis [1/3 2004, 30/4 2004] repræsenterer altså 3 cykler, 210,25 danske kroner og et avisabbonnement på 2 måneder. 2 Der er 23 entiteter og 36 relationer i den ændrede REA-model, hvilket skal sammenlignes med de 5 entiteter og 8 relationer, der er i modellen fra [4]. 10

12 REA-modellen 2.6 En simplificeret REA-model Hændelser En hændelse repræsenteres som en record med felterne type, from, to, resource og time. Feltet type deholder en beskrivelse af hændelsestypen, for eksempel varekøb eller ventarkøb. Feltet resource deholder den ressource, der overføres ved hændelsen. I feltet from er det angivet, hvilken agent, der overfører ressourcen, og to er modtageren af ressourcen. Det sidste felt time angiver på hvilket tidspunkt, hændelsen dtrådte. Det bemærkes, at entiteterne ressource og agent fra REA-modellen ikke repræsenteres som selvstændige entiteter i datamodellen, men blot er attributter ved hændelses-entiteten Kontrakter Vi dfører den begrænsng, at en kontrakt består af netop to forpligtelser (commitments). Det betyder, at det ikke er nødvendigt at bruge entiteten forpligtelser eller relationen reciprok. På samme måde som for hændelser kluderes ressourcer og agenter i attributterne for kontrakten, derfor er relationerne reserverer og partner ikke nødvendige. En kontrakt repræsenteres som en record, der har følgende felter: type, from1, from2, to1, to2, resource1, resource2, time1 og time2. Feltet type angiver, som for hændelser, en beskrivelse af kontrakt-typen, som for eksempel arbejdsløn, admistrationsydelse. Felterne resource1, from1, to1 og time1 angiver, at agenten from1 forpligter sig til at overføre ressourcen resource1 til agenten to1 senest på tidspunktet time1. Tilsvarende for resource2, from2, to2 og time2. Det er nu kun relationerne dualitet og udfører fra figur 2.2, der ikke er repræsenterede. De tages ikke med, fordi det viser sig, at de ikke er nødvendige for at kunne udtrykke de tre bogførgsrapporter, hvilket kort sagt skyldes, at dualiteten kun er nødvendig for forpligtelser, og reciprok-relationen er gjort eksplicit i repræsentationen af kontrakter Journal Vi dfører betegnelsen journal om et par bestående af to multimængder: en hvor elementerne er kontrakter, og en hvor elementerne er hændelser. Intuitivt er en multimængde en mængde, hvor der kan optræde flere forekomster af det samme element Eksempler Betragt situationen, hvor der dgås en kontrakt mellem en grossist og et firma om, at grossisten skal levere et antal varer til firmaet mod en overførsel af penge den anden vej, og hvor der efterfølgende overføres først varer fra grossisten til firmaet og derefter penge til grossisten. Det kan beskrives ved 1 kontrakt og 2 hændelser: {type := varekøb,from1 := grossist, to1 := firma, resource1 := [varea 62.0], time1 := 07/ , from2 := firma, to2 := grossist, resource2 := [DKR ], time2 := 08/ } {type := varekøb, from := grossist, to := firma, ressource := [varea 62.0], time := 7/ } {type := varekøb-betalg, from := firma, to := grossist, ressource := [DKR ], time := 7/ } Datamodellen har altså to dele: kontrakter og hændelser, der har følgende form: {type := s, from1 := a 1, to1 := a 2, resource1 := r 1, time1 := t 1, from2 := a 3, to2 := a 4, resource2 := r 2, time2 := t 2} {type := s, from := a 1, to := a 2, ressource := r, time := t} 11

13 REA-modellen 2.6 En simplificeret REA-model hvor s er en tegnstreng, a 1, a 2, a 3, a 4 er agenter (for eksempel repræsenteret som tegnstrenge), r, r 1, r 2 er ressourcer (som beskrevet i afsnit 2.6.1), og t, t 1, t 2 er tidsangivelser (for eksempel i form af en dato). I næste kapitel ser vi på, hvordan bogførgsrapporter kan udtrykkes ud fra en journal. 12

14 Kapitel 3 REA-baseret rapporterg Datamodellen fra kapitel 2 kan bruges som udgangspunkt for at implementere bogførgsrapporter som for eksempel Resultatopgørelse. Den simple datamodel er baseret på REA-modellen, så vi bruger udtrykket REA-baseret rapporterg om rapporter, der udtrykkes ved hjælp af den beskrevne datamodel. 3.1 Overordnet om rapporterg Som nævnt i kapitel 2 deholder REA-modellen ikke elementer fra det dobbelte bogholderi. Tg som for eksempel konti, saldo osv. er derfor afledte formationer fra de basale data i modellen. En rapport er en samlg af sådanne afledte formationer eller med andre ord et program, der udtrykkes ud fra datamodellen. Sproget SQL er et eksempel på et sprog, der kan bruges til at aflede formationer fra data i en database ved for eksempel at udvælge og summere data. SQL er blot ét ud af mange sprog der kan bruges til at lave forespørgsler til en database. Generelle programmergssprog som for eksempel C eller Java kan også bruges til at udtrykke rapporter. I denne opgave vælges en mellemløsng, hvor der deferes et funktionsorienteret sprog, der bruges til at udtrykke rapporterne. Sproget giver mulighed for at defere funktioner, hvilket ikke er muligt i SQL. Til gengæld er sproget ikke så generelt som for eksempel Standard ML, idet der ikke tillades rekursive funktionskald. I dette kapitel viser vi, hvordan tre rapporter udtrykkes i sproget. Vi venter med en formel defition af syntaks, typesystem og semantik til kapitel 4 og nøjes her med at vise eksempelprogrammer, der giver en fornemmelse for hvordan semantikken er Tre typiske rapporter Der er valgt tre rapport-typer, som er typiske rapporter i et bogførgssystem: Resultatopgørelsen, Balancen og Likviditetsbeskrivelsen. Disse tre er valgt, fordi de er grundlæggende elementer for en af bogførgens vigtigste opgaver: at lave et årsregnskab, og fordi de er repræsentative, idet deres byggesten er basale operationer på data. I resten af kapitlet specificeres konkrete stanser af de tre rapporter. Rapporterne udføres for en fiktiv handelsvirksomhed DKHandel, hvis virksomhed består i at dkøbe varer fra grossister og videresælge til kunder. Grundbegreberne i bogførg og det dobbelte bogholderi er beskrevet i grundbøgerne [10], [11] og [12] Operationer på ressourcer I rapporterne får vi brug for forskellige operationer på ressourcer: 13

15 REA-baseret rapporterg 3.2 Resultatopgørelse addition To ressourcer [s 1 pr 1,..., s n pr n ] og [s 1 pr 1,..., s m pr m] kan adderes ved at konstruere en ny ressource, hvor domænet er mængden bestående af elementerne {s 1,... s n, s 1,... s m}. Hvis en streng s i forekommer i de to summander og bliver afbildet til pr i henholdsvis pr j, afbildes s i til summen af pr i og pr j i den nye ressource. For primitive ressourcer deferes addition for to reelle tal ved den sædvanlige addition 1. Hvis en streng s i bliver afbildet til pr i af den ene summand, og ikke forekommer i den anden, afbildes s i til pr i i den nye ressource. valuerg Danske kroner dgår som en primitiv ressource på lige fod med andre primitive ressourcer, som for eksempel euro eller frimærker. En afledt formation kan altså for eksempel være en ressource, der består af danske kroner og euro. For at forskellige resultater fra en rapport skal være direkte sammenlignelige, valueres en ressource til danske kroner. For eksempel valueres 100 euro ved at multiplicere med vekselkursen. Vi antager, at funktionen valuer(res, v) valuerer ressourcen res ud fra formationer i afbildngen v. For eksempel gælder valuer([dkr -> 10.50, euro -> 100.0], [euro -> 7.44]) = periodiserg For visse typer af kontrakter angives der et tidsterval, som overførslen dækker eller gælder for for eksempel ved udbetalg af løn eller betalg af en abonnementsordng. Ved opgørelser der falder den for det angivne terval, skal ressourcen periodeafgrænses (se kapitel 2 i [10]). Til dette bruges funktionen periodiser, der tager tre argumenter: den ressource, der skal afgrænses, tervallet som ressourcen gælder for, samt hvilket terval der skal afgrænses med hensyn til. Hvis ressourcen [DKR 100.0] gælder for tervallet [15/ , 17/1 2004], og der skal afgrænses til tervallet [1/1 2004, 31/ ], er resultatet af periodiser 50.0 svarende til, at halvdelen af det terval, som ressourcen dækker, falder den for afgrænsngstervallet. 3.2 Resultatopgørelse I dette afsnit beskrives rapporten Resultatopgørelse. Med udgangspunkt i [10] dføres 9 kontrakttyper. Tabel 3.1 beskriver, hvordan de forskellige typer skal bruges. For eksempel betyder den første lie i tabellen, at for typen varesalg angives nogle varer i resource1, der skal overføres fra firmaet i from1 til kunden i to1, og at kunden i to2 skal overføre en ressource ( resource2 ), der valueres til DKR. Nogle af typerne er markeret med en stjerne, hvilket betyder, at ressourcen i resource2 skal periodiseres, og at tidsformationen skal være i resource1. Type from1 to1 resource1 from2 to2 resource2 varesalg firma kunde varer kunde firma DKR varekøb grossist firma varer firma grossist DKR arbejdsløn-salg* ansat firma tid firma ansat DKR salg-omkostnger div firma div firma kunde DKR distribution speditør firma ydelse firma speditør DKR arbejdsløn-adm* ansat firma tid firma ansat DKR admistration-ydelse* leverandør firma div firma leverandør DKR ventar-afskrivng* firma firma tid firma firma DKR renter* kreditor firma tid firma kreditor DKR skat* kommune firma tid firma kommune DKR Tabel 3.1: Oversigt over kontrakt-typerne 1 For to tidstervaller [t 1, t 2 ] og [t 3, t 4 ] deferes summen ved [max(t 1, t 3 ), max(t 2, t 4 )]. I de tre rapporter får vi ikke brug for at addere tervaller. 14

16 REA-baseret rapporterg 3.2 Resultatopgørelse I det følgende beskrives, hvordan de enkelte dele af resultatopgørelsen deferes. Vi nøjes med at angive defitionerne og henviser til [10] eller [12] for diskussion af og motiverg for de enkelte dele. Resultatopgørelsen viser for et tidsterval I (typisk et regnskabsår), om firmaet har skabt et overskud eller underskud, samt hvordan det er fremkommet. Det er kontrakterne, der udgør fundamentet for resultatopgørelsen. I afsnit 3.3 beskrives, hvordan eventuelle forskelle mellem kontrakter og hændelser håndteres Selektion og summerg For at undersøge hvor meget firmaet DKHandel har omsat ved at sælge varer, udvælges de varesalgs-kontrakter, der falder den for tervallet I, og betalgerne summeres. Det kan udtrykkes ved følgende funktionsdefition: fun NettoOmsætng(J : journal, I : terval, v : resource) = sum (c valuer(#resource2(c), v)) select (x #startdate(i) #time2(x) and #time2(x) #enddate(i)) select (x #to2(x) = DKHandel ) select (x #type(x) = varesalg ) #contracts(j) Her er brugt to operationer: sum og select. I operationen select (x e 1 ) e 2 skal e 2 evaluere til en multimængde, og e 1 er et udtryk, hvor x er en fri variabel. Så returnerer udtrykket en multimængde bestående af de elementer, hvor funktionen λx.e 1 evaluerer til true. I udtrykket sum (x e 1 ) e 2 skal e 2 evaluere til en multimængde, og sum-udtrykket returnerer så en værdi, der fås ved at summere resultateterne af at evaluere funktionen λx.e 1 for alle elementer i multimængden. For at udvælge en komponent af en record bruges #label. Defitionen af funktionen NettoOmsætng kan altså læses på følgende måde: først udvælges de kontrakter, der har typen varesalg, og af disse udvælges dem, hvor det er firmaet DKHandel, der sælger en vare. For de kontrakter, der falder den for tervallet I, valueres ressourcen, der udgør betalgen, og summen udgør nettoomsætngen. Denne funktion er et typisk eksempel på hvordan formation kan afledes fra de basale data i journalen. For typerne salg-omkostnger og distribution deferes på tilsvarende måde funktioner OmkostngerSalg og DistributionsOmkostnger der udvælger og summerer kontrakter af de respektive typer Selektion og summerg med periodiserg For de typer, der er markeret med stjerner i tabel 3.1, dføres funktioner, hvor der udover valuergen foretages periodiserg som tidligere beskrevet. For typen arbejdsløn-salg deferes følgende funktion fun OmkostngerArbejdsloenSalg(J : journal, I : terval, v : resource) = sum (c valuer(periodiser(#resource2(c), #resource1(c), I), v)) select (x #startdate(i) #time2(x) and #time2(x) #enddate(i)) select (x #to2(x) = DKHandel ) select (x #type(x) = arbejdsløn-salg ) #contracts(j) Tilsvarende deferes funktionerne OmkostngerArbejdslønAdm, OmkostngerAdmistrationØvrige, AfskrivngInventar, RenteUdgifter og Skat for kontrakttyperne arbejdsløn-adm, admistration-ydelse, ventar-afskrivng, renter og skat. 15

17 REA-baseret rapporterg 3.2 Resultatopgørelse Prissætng af solgte varer Nettoomsætngen er en optællg af, hvor stor omsætng DKHandel havde på varesalg. For at fde størrelsen af overskuddet eller underskuddet skal værdien af de solgte varer trækkes fra. Værdien af de solgte varer kan fastsættes på forskellige måder. I [11] er der blandt andre nævnt gennemsnitsmetoden og FIFO-metoden. Vi antager, at de varer, der sælges, er blevet dkøbt som følge af kontrakter med typen varekøb. Prissætng af en ressource foregår ved at summere resultaterne af at prissætte hver enkelt primitiv ressource. Gennemsnitsmetoden Ved prissætng af et antal primitive ressourcer med gennemsnitsmetoden, fdes antallet af dkøbte primitive ressourcer, og den samlede pris fdes. Det giver en gennemsnitsstykpris, som bruges til at fastsætte en værdi af et antal primitive ressourcer af den givne type. Gennemsnitsmetoden kan udtrykkes ved de fire funktioner købte, samletpris, gnmindkøbsprisdel og gnmindkøbspris. Funktionen købte giver en ressource, der er summen af alle dkøbte varer af en given type op til et bestemt tidspunkt. Den samlede pris for dkøbene kan fdes med funktionen samletpris. Med de to funktioner kan vi fde en stykpris og bruge den til at prissætte et antal af given primitiv ressource. Den samlede prissætng af en ressource fås ved at summere resultaterne for hver af de primitive ressourcer. De fire funktioner er vist i bilag A.4. FIFO-metoden Ved prissætng med FIFO-metoden antages, at de dkøbte varer sælges i en first--first-out rækkefølge, altså at det er de ældste varer, der sælges først. For at fde værdien af salget af x stk. varer af typen pr kan vi benytte følgende fremgangsmåde: Opbyg mængden dkøb, der består af elementer af formen {time = t, res = r, stykpris = p} ud fra mængden af kontrakter med typen varekøb. Komponenten time angiver tidspunktet for varekøbet, res angiver hvilken ressource, der er købt, og stykpris angiver stykprisen for det pågældende dkøb. Opbyg en afbildng, der afbilder tallene 0, 1,..., n til elementer fra dkøb sorteret i ikkefaldende rækkefølge efter komponenten time, hvor n er antallet af elementer i dkøb. Fd antallet af solgte varer af typen pr. Fra afbildngen fjernes ressourcer svarende til antallet af solgte varer, begyndende fra de ældste dkøb. Ud fra den modificerede afbildng fdes den samlede pris for antallet x. Bortset fra sortergen kan ovenstående implementeres med funktioner, der ikke bruger anden form for gentagelse end foldng af en funktion over en multimængde (se også kapitel 4). Detaljerne i funktionsdefitionerne er vist i bilag A.4. Vi kan nu defere funktionen OmkostngerSolgteVarer, der ud fra en af de to prissætngsmetoder fder værdien af de varer, der er solgt i perioden I: 16

18 REA-baseret rapporterg 3.3 Balance fun OmkostngerSolgteVarer(J : journal, I : terval, v : resource) = sum (c gnmindkøbspris(#resource1(c), #time1(c), I, v)) select (x #startdate(i) #time1(x) and #time1(x) #enddate(i)) select (x #from1(x) = DKHandel ) select (x #type(x) = varesalg ) #contracts(j) Hvis der ønskes prissætng med FIFO-metoden, udskiftes kaldet af gnmindkøbspris med kald til fifoindkøbspris Samlefunktioner Ud fra de dførte funktioner kan vi nu defere de resterende dele af Resultatopgørelsen, nemlig de afledte formationer Omkostnger, BruttoResultat, AdmistrationsOmkostnger, ResultatAf- PrimaerDrift, ResultatOrdaerDrift og ÅretsResultat. Omkostnger er de samlede udgifter ved salg af varer: fun Omkostnger(J : journal, I : terval, v : resource) = OmkostngerSolgteVarer(J, I, v) + OmkostngerArbejdslønSalg(J, I, v) + OmkostngerSalg(J, I, v) BruttoResultatet er nettoomsætngen fratrukket omkostnger ved salget: fun BruttoResultat(J : journal, I : terval, v : resource) = NettoOmsætng(J, I, v) - Omkostnger(J, I, v) AdmistrationsOmkostnger er de samlede omkostnger til admistrationen: fun AdmistrationsOmkostnger(J : journal, I : terval, v : resource) = OmkostngerArbejdslønAdm(J, I, v) + OmkostngerAdmistrationØvrige(J, I, v) + AfskrivngInventar(J, I, v) De sidste tre funktioner deferes på følgende måde: fun ResultatPrimaerDrift(J : journal, I : terval, v : resource) = (BruttoResultat(J, I, v) - DistributionsOmkostnger(J, I, v)) - AdmistrationsOmkostnger(J, I, v) fun ResultatOrdaerDrift(J : journal, I : terval, v : resource) = ResultatPrimaerDrift(J, I, v) - RenteUdgifter(J, I, v) fun ÅretsResultat(J : journal, I : terval, v : resource) = ResultatOrdaerDrift(J, I, v) - Skat(J, I, v) Det afslutter defitionen af rapporten Resultatopgørelse. I afsnit 3.5 gennemgås et eksempel, der giver et overblik over rapporten. 17

19 REA-baseret rapporterg 3.3 Balance Type from1 to1 resource1 from2 to2 resource2 ventarkøb møbelfirma firma ventar firma møbelfirma DKR forskng forsker firma viden firma forsker DKR grundkøb mægler firma grund firma mægler DKR kassekreditlån kreditor firma DKR firma kreditor DKR obligationslån kreditor firma DKR firma kreditor DKR 3.3 Balance Tabel 3.2: De sidste kontrakt-typer For at udtrykke rapporten Balance, dføres fem nye kontrakttyper, som angivet i tabel 3.2. Balancen er en opstillg af DKHandels aktiver og passiver op til et tidspunkt t (se [10]). Som tidligere nævnt består en kontrakt af to overførsler og skal efterfølges af to hændelser, der opfylder kontrakten. Hændelser, der realiserer den første overførsel (fra from1 til to1 fra kontrakten), har samme type som kontrakten (for eksempel varekøb ), mens hændelser, der realiserer den anden overførsel (fra from2 til to2 ), får tilføjet -betalg til typen (for eksempel varekøbbetalg ). Balancen, der er de samlede aktiver fratrukket de samlede passiver, skal være 0. Vi viser ikke detaljerne for de funktioner, der udgør Balancen, da de konstrueres på samme måde, som de allerede viste funktioner. Vi nøjes med en beskrivelse af de enkelte dele og henviser til bilag A.4 for detaljerne Aktiver Aktiverne består af to dele: anlægsaktiver og omsætngsaktiver. Anlægsaktiver Anlægsaktiverne udgøres af aktiverne forskng, grunde og ventar fratrukket andelen af afskrivng på ventaret. De tre funktioner ForskngAktiv, GrundAktiv og InventarAktiv optæller som tidligere vist, hvor mange penge der er brugt på kontrakter af typerne forskng, grundkøb henholdsvis ventarkøb. Som angivet i 3.1 skal kontrakter af typen ventar-afskrivng periodiseres, hvilket gøres i funktionen Inventarafskrivng. De fire funktioner er vist i bilag A.4 sammen med defitionen af funktionen AnlægsAktiver. Omsætngsaktiver Overordnet set består omsætngsaktiverne af 4 dele: varebeholdng, kassebeholdng, tilgodehavender og forudbetalger. Aktivet varebeholdng fdes ved at trække værdien af de solgte varer fra den samlede pris for varekøb. Der vælges samme metode til prissætng af solgte varer som i Resultatopgørelsen. Kassebeholdngen fdes ved at trække summen af udbetalger fra summen af dbetalger. Det er hændelserne, der udgør basis for beregng af kassebeholdngen, og ikke kontrakterne, hvilket betyder, at det er d- og udbetalger, som rent faktisk har fundet sted, der regnes på. Hvis der er kunder, der ikke har betalt for de varer, de har købt fra DKHandel, er det beløb, der mangler at blive betalt, et aktiv: TilgodehavendeVaresalg. Det svarer til, at det samlede beløb, der er overført ved varesalg-betalg, er mdre end det samlede beløb, der ifølge kontrakterne med typen varesalg skulle betales. Det sidste aktiv udgøres af eventuelle forudbetalger. Hvis det samlede beløb, der er overført ved hændelser af typen arbejdsløn-salg for eksempel er højere end det, der ifølge kontrakterne 18

20 REA-baseret rapporterg 3.4 Likviditetsbeskrivelse skulle være overført, er der tale om forudbetalt løn, som bogføres som et aktiv. For hver af typerne arbejdsløn-salg, salg-omkostnigner, distribution, arbejdsløn-adm, admistrationydelse, renter, skat, forskng, grundkøb, ventarkøb og varekøb er der tale om forudbetalgs-aktiv, hvis summen af ressourcer fra hændelser er større en summen af ressourcer fra kontrakter af den givne type Passiver DKHandels passiver består af to dele: egenkapital og gæld. Egenkapital fdes ved at summere ÅretsResultat (som deferet i afsnit 3.2) for de foregående år. Hvis der for eksempel er registreret kontrakter i år 2002, 2003 og 2004, fdes egenkapitalen for et tidspunkt i 2004 ved at summere ÅretsResultat for årene 2002, 2003 og Denne gentagelse kan realiseres ved en foldngsfunktion, som vist i bilag A.4. Gæld Firmaet DKHandels gæld udgøres af fire dele: gæld fra kassekreditlån, gæld fra kreditforengslån, overbetalg for varesalg og andre skyldige beløb. Gælden for kassekreditlån og kreditforengslån kan fdes ved at sammenligne det lånte beløb med de hændelser, der tilbagebetaler (dele af) lånebeløbet. Hvis de faktiske betalger (dvs. beløb fra hændelser) for varesalg overstiger de forventede betalger (dvs. beløb fra kontrakter), så er der tale om en overbetalg, der skal betales tilbage til kunderne, altså et passiv. For hver af typerne arbejdsløn-salg, salg-omkostnger, distribution, arbejdsløn-salg, admistration-ydelse, renter, skat, forskng, grundkøb, ventarkøb og varekøb gælder, at hvis det samlede beløb, der skal betales ifølge kontrakterne, er større end det, der er blevet betalt (ifølge hændelserne), skal forskellen betales på et tidspunkt, og der er altså tale om et passiv. Den samlede rapport er vist i bilag A Likviditetsbeskrivelse Rapporten Likviditetsbeskrivelse er deferet på baggrund af [11], og gælder for et tidsterval I. Den kan opsummeres som følger: ResultatPrimærDrift + AfskrivngInventar Indtjengsbidrag varedebitorer forudbetalger varelager + varekreditorer DriftensLikviditetsvirkng anlægsaktiver + gæld + RenteUdgifter + Skat PeriodensLikviditetsvirkng + LikviderPrimo LikviderUltimo Den afledte formation dtjengsbidrag er altså summen af ResultatPrimærDrift og AfskrivngInventar fra Resultatopgørelsen. 19

21 REA-baseret rapporterg 3.5 Eksempel-rapporter varedebitorer er tilvæksten i aktivet TilgodehavendeVaresalg i løbet af perioden. forudbetalger er tilvæksten i aktiverne for forudbetalger. varelager er tilvæksten i aktivet Varebeholdng- Aktiv. varekreditorer er tilvæksten i passiverne Overbetalg og de skyldige beløb (se afsnit 3.3.2). Tilsvarende er anlægsaktiver og gæld, tilvæksten i AnlægsAktiver og Gæld. RenteUdgifter og Skat er som deferet for Resultatopgørelsen. Posten LikviderPrimo udgøres af passivet Kassebeholdng. Den samlede rapport vises i bilag A Eksempel-rapporter Vi slutter kapitlet med at vise et eksempel på en journal og tilhørende rapporter. Eksemplet er et modificeret eksempel fra [10]. Journalen består af 13 kontrakter og 24 hændelser. Der dgås kontrakter, om at følgende skal ske den udgangen af år 2004: 1. DKHandel låner DKR på en kassekredit 2. Der dkøbes ventar for DKR 3. DKHandel køber 62 varea fra en grossist til en samlet pris af DKR 4. DKHandel betaler husleje for perioden 1/ til 31/ på DKR 5. Der betales elregng for perioden 1/ til 1/ på DKR 6. Der betales avisabonnement for perioden 1/ til 1/ på 5000 DKR 7. Der betales løn til en sælger for perioden 1/ til 14/ på DKR 8. Der betales løn til en sælger for perioden 1/ til 14/ på DKR 9. Der betales løn til en ansat i admistrationen for perioden 1/ til 14/ på 4000 DKR 10. Der betales løn til en ansat i admistrationen for perioden 1/ til 14/ på 2000 DKR 11. Der sælges 25 stk. varea til en kunde for DKR 12. Der sælges 24 stk. varea til en kunde for DKR 13. Der afskrives DKR på ventar for perioden 1/ til 31/ De 24 hændelser beskriver, at i 2004 dtræder der hændelser, der opfylder de nævnte punkter bortset fra følgende: DKHandel låner DKR, men betaler ikke noget tilbage i år 2004 Der købes ventar for DKR, men der betales kun DKR De 2000 DKR, der skal betales til en ansat i admistrationen, betales ikke 20

22 REA-baseret rapporterg 3.5 Eksempel-rapporter Eksempel på Resultatopgørelse Med den beskrevne journal kommer resultatopgørelsen for perioden 1/ til 31/ til at se ud som følger: NettoOmsætng OmkostngerSolgteVarer OmkostngerArbejdslønSalg OmkostngerSalg 0 Omkostnger BruttoResultat DistributionsOmkostnger 0 OmkostngerArbejdslønAdm 6000 OmkostngerAdmistrationØvrige 38473,48 AfskrivngInventar AdmistrationsOmkokostnger 60473,48 ResultatPrimærDrift 5526,51 RenteUdgifter 0 ResultatOrdærDrift 5526,51 Skat 0 ÅretsResultat 5526,51 Altså har DKHandel et overskud på godt 5000 DKR for året Eksempel på Balance Balancen består af to dele: aktiver og passiver. Med de beskrevne opsummeres aktiverne på følgende måde: ForskngAktiv 0 GrundAktiv 0 InventarAktiv InventarAfskrivng AnlægsAktiver VarebeholdngAktiv TilgodehavendeVaresalg 0 ForudbetaltArbejdslønSalg 0 ForudbetaltSalgOmkostnger 0 ForudbetaltDistribution 0 ForudbetaltArbejdslønAdmistration 0 ForudbetaltOmkostngerAdmistration 1526,51 ForudbetaltRenter 0 ForudbetaltSkat 0 ForudbetaltForskng 0 ForudbetaltGrundkøb 0 ForudbetaltInventarkøb 0 ForudbetaltVarekøb 0 Kassebeholdng OmsætngsAktiver ,51 Aktiver ,51 21

23 REA-baseret rapporterg 3.5 Eksempel-rapporter Passiverne fordeler sig på følgende måde: Egenkapital 5526,51 Kassekreditlån Kreditforengslån 0 Overbetalg 0 SkyldigArbejdslønSalg 0 SkyldigSalgOmkostnger 0 SkyldigDistribution 0 SkyldigArbejdslønAdmistration 2000 SkyldigAdmistrationsOmkostnger 0 SkyldigRenter 0 SkyldigSkat 0 SkyldigForskng 0 SkyldigGrundkøb 0 SkyldigInventarkøb SkyldigVarekøb 0 Gæld Passiver ,51 Balance Eksempel på Likviditetsbeskrivelse Som det sidste vises Likviditetsbeskrivelsen for de konkrete data: Indtjengsbidrag 21526,52 varedebitorer 0 varelager forudbetalger -1526,52 varekreditorer DriftensLikviditetsvirkng anlægsaktiver gæld RenteUdgifter 0 Skat 0 PeriodensLikviditetsvirkng LikviderPrimo 0 LikviderUltimo

24 Kapitel 4 FunSETL I dette kapitel beskrives sproget FunSETL. Det er et simpelt førsteordens funktionsorienteret programmergssprog. Sproget hedder FunSETL, fordi det kan betragtes som en funktionel udgave af sproget SETL omend i en meget begrænset udgave. Det betyder fx, at multimængder og endelige afbildnger er dbyggede datatyper. Intuitivt er en multimængde en mængde, hvor der kan optræde flere forekomster af det samme element. Sproget SETL er beskrevet i bogen [13]. FunSETL adskiller sig først og fremmest fra andre funktionsorienterede sprog ved, at der ikke tillades rekursion. Til gengæld er der dbygget mulighed for at folde en funktion over en multimængde. Hvad der menes med dette uddybes senere. FunSETL kan bruges til at udtrykke bogførgsrapporterne fra kapitel 3. Til dette formål skal der bruges en række operationer, der kan manipulere multimængder og endelige afbildnger. Det sprog, der deferes her, kan ses som et kernesprog, hvor mængden af operationer ikke specificeres i detaljer. I kapitel 9 beskrives en implementerg af sproget, hvor det naturligvis er nødvendigt at angive hvilke operationer, der skal kluderes. Indtil da kan man tænke på, at sproget deholder operationer som for eksempel forengsmængde, tilføjelse af et element til en mængde osv. Beskrivelsen af syntaks, typesystem og semantik følger metoderne beskrevet i Glynn Wskels bog [14]. 4.1 Sprogdefition Vi deferer et kernesprog med mulighed for udvidelser og antager følgende syntaktiske mængder givne: Const En mængde af konstanter Var En mængde af variabelnavne Funname En mængde af funktionsnavne Ty En mængde af typer Ops En mængde af navne på operationer på udtryk Vi specificerer ikke disse mængder yderligere. Dog antager vi, at mængden Ty deholder symbolet bool, samt at for alle t Ty er også mset(t) Ty. Elementer fra de nævnte mængder kan sættes sammen til at give udtryk (mængden Exp), funktionsdefitioner (mængden Fundef) og programmer (mængden Program). Vi deferer de tre mængder ved hjælp af BNF-regler. I resten af opgaven bruger vi følgende konventioner: c er et element i Const 23

25 FunSETL 4.2 Typekorrekthed v, a, b er elementer i Var f er et element i Funname t er et element i Ty er et element i Ops p er et element i Program fundef er et element i Fundef e er et element i Exp Desuden bruges fodtegn og mærker, så fx e 1, e 2,..., e n er elementer fra Exp, og t 1, t, t 2 er elementer fra Ty. Med disse konventioner kan vi give en defition af mængderne Program, Fundef og Exp: p ::= fundef 1 fundef 2... fundef n fundef ::= fun f(v 1 : t 1, v 2 : t 2,..., v n : t n ) = e e ::= v c if e 1 then e 2 else e 3 let v = e 1 e 2 fold (a, b => e 1 ) e 2 e 3 f(e 1, e 2,..., e n ) (e 1, e 2,..., e n ) Et FunSETL-program p er en følge af én eller flere funktionsdefitioner. En funktionsdefition består af et funktionsnavn, en (evt. tom) følge af parameternavne og -typer, samt et udtryk, der udgør funktionskroppen. Et udtryk kan være et variabelnavn (en parameter eller en let-bundet variabel), en konstant, et betget udtryk, en let-bdg, en foldng, et funktionskald eller en operation på nul eller flere udtryk. Betgede udtryk, let-bdger, funktionskald og brug af operationer har den sædvanlige betydng. Intuitivt er fold (a, b => e 1 ) e 2 e 3 en forkortelse for f(e n, f(e n 1,..., f(e 2(f(e 1, e 2 ))...)), hvor e 3 er multimængden {e 1, e 2,..., e n}, og f er funktionen λ(a, b).e 1. Vi kalder funktionen f for fold-funktionen. Vi bruger notationen {c 1, c 2,..., c n } om multimængder i Const. Den samme notation bruges som sædvanlig om mængder. Når der er tale om syntaks fra FunSETL, betegner notationen elementer fra Const, og ellers er der tale om mængder i sædvanlig forstand. I afsnit 4.3 gives en operationssemantik for FunSETL, men først beskrives typesystemet. 4.2 Typekorrekthed Vi skal nu defere, hvad det vil sige, at et FunSETL program p er typekorrekt. Mængden af typer Ty er ikke fastlagt, men vi kan give et typesystem, der er parametriseret ved følgende afbildnger, som vi antager givne: Constty : Const Ty Opsty : Ops Ty Ty Her angiver Ty mængden af endelige lister t 1, t 2,... t n af elementer fra Ty. Afbildngen Constty afbilder en konstant over i dens type. Opsty er en partiel afbildng, der afbilder et operationsnavn samt en følge af typer over i en type. Intuitionen er, at disse to afbildnger bruges til at dkode typeformation for sprogets konstanter og operationer. Bemærk, at eksistensen af disse afbildnger har følgende konsekvenser: 24

26 FunSETL 4.2 Typekorrekthed En konstant c Const har netop én type. Altså kan konstanten 1 ikke være både et heltal og et reelt tal. I praksis benyttes derfor konstanten 1.0 til at angive tallet 1 som reelt tal. En operation kan være overloadet, sålænge de forskellige udgaver kan adskilles ved andet end returtypen Antagelser om Constty Vi antager at følgende to biimplikationer gælder: Constty(c) = bool c = true c = false Constty(c) = mset(t) c = {c 1,... c n } hvor n 0 og Constty(c i ) = t Den første biimplikation siger, at de eneste konstanter, der har typen bool, er true og false. Den anden beskriver formen af de konstanter, der har typen mset(t) for et t Ty Defition af typerelation Typerelationen deferes ud fra en mængde af regler. Undervejs opbygges og bruges to forskellige endelige afbildnger: en afbildng σ : Var Ty der bder variabelnavne til typer, en afbildng Γ : Funname Ty Ty der bder et funktionsnavn til en returtype samt en følge af argumenttyper. σ betegnes som variabelomgivelser og Γ som funktionsomgivelser. Vi deferer relationen σ, Γ e : t for e Exp og t Ty. Hvis σ, Γ e : t siger vi, at e har typen t (i omgivelserne σ og Γ). Hvis der fdes σ, Γ og t så Γ er funktionsomgivelser for p, og σ, Γ e : t siger vi, at e er typekorrekt med hensyn til p med typen t. Vi skriver e : t som en forkortelse for [ ], [ ] e : t. Relationen deferes som den mdste relation, der er lukket mht. følgende regler: Var: σ, Γ v : t (hvis σ(v) = t) Const: σ, Γ c : t (hvis Constty(c) = t) If: σ, Γ e 1 : bool σ, Γ e 2 : t 1 σ, Γ e 3 : t 2 σ, Γ if e 1 then e 2 else e 3 : t 1 (hvis t 1 = t 2 ) Let: σ, Γ e 1 : t 1 σ[v t 1 ], Γ e 2 : t σ, Γ let v = e 1 e 2 : t Fold: σ, Γ e 2 : t σ, Γ e 3 : mset(t ) σ[v 1 t, v 2 t], Γ e 1 : t σ, Γ fold (v 1, v 2 => e 1 ) e 2 e 3 : t Call: σ, Γ e 1 : t 1 σ, Γ e 2 : t 2 σ, Γ e n : t n σ, Γ f(e 1, e 2,..., e n ) : t (hvis Γ(f) = (t, t 1, t 2,..., t n )) Op: σ, Γ e 1 : t 1 σ, Γ e 2 : t 2 σ, Γ e n : t n σ, Γ (e 1, e 2,..., e n ) : t (hvis Opsty(, t 1, t 2,..., t n ) = t) Hvis en variabel er bundet til en type t i σ, så er t typen for variablen. En konstant c gives en type ved hjælp af Constty. Et betget udtryk if e 1 then e 2 else e 3 har typen t, hvis betgelsen e 1 har typen bool, og begge grene e 2 og e 3 har typen t. 25

27 FunSETL 4.3 Semantik Udtrykket let v = e 1 e 2 har typen t, hvis e 1 har typen t 1, og e 2 har typen t i variabelomgivelser, der er udvidet med en bdg af variablen v til typen t 1. For at fold-udtrykket fold (v 1, v 2 => e 1 ) e 2 e 3 skal have typen t, kræves e 2 er typekorrekt med typen t 1 e 3 er typekorrekt med typen mset(t 2 ) e 1 er typekorrekt med typen t 1 hvis variablene v 1 og v 2 bdes til hhv. t 2 og t 1 For et funktionskald f(e 1, e 2,..., e n ) sammenlignes typerne af argumentudtrykkene med dholdet i Γ(f), og hvis de stemmer overens, er typen af hele udtrykket returtypen for f, der er angivet i Γ. Anvendelse af en operator gives en type på tilsvarende måde, blot bruges afbildngen Opsty i stedet for Γ. Vi deferer relationen Γ fundef : Γ for fundef Fundef ved følgende regel: [v 1 t 1, v 2 t 2,..., v n t n ], Γ e : t Γ fun f(v 1 : t 1, v 2 : t 2,..., v n : t n ) = e : Γ[f (t, t 1, t 2,..., t n )] Hvis funktionskroppen har typen t i variabelomgivelserne, der er angivet af de formelle parametre til funktionen, så udvides funktionsomgivelserne med en bdg for f, hvor typen t angives som returtype. Til sidst deferes en relation p : Γ for et program p. Hvis p : Γ siger vi, at Γ er funktionsomgivelser for p, og at p er typekorrekt. Relationen deferes ved følgende regel: [ ] fundef 1 : Γ 1 Γ 1 fundef 2 : Γ 2 Γ n 1 fundef n : Γ n fundef 1 fundef 2... fundef n : Γ n Som en konsekvens af defitionen af et typekorrekt program p gælder, at p ikke kan være typekorrekt, hvis der fdes en funktion f, i hvis krop der optræder et kald til funktionen f selv, eller til funktioner der er deferet senere end f i p. Med andre ord er rekursion ikke tilladt, og en funktion skal være deferet, før den kan kaldes. 4.3 Semantik Vi er nu klar til at give en operationssemantik for FunSETL. Mere præcist, så vil vi give en semantik for lukkede FunSETL-udtryk i konteksten af et typekorrekt program p Lukkede udtryk Et e Exp kaldes lukket, hvis det ikke dholder frie variable. Funktionen fv : Exp Var der angiver mængden af frie variable for et udtryk e kan deferes ved strukturel duktion over e på den oplagte måde: fv(v) = {v} fv(c) = fv(if e 1 then e 2 else e 3 ) = fv(e 1 ) fv(e 2 ) fv(e 3 ) fv(let v = e 1 e 2 ) = ( fv(e 2 )\{v} ) fv(e 1 ) fv(fold (a, b => e 1 ) e 2 e 3 ) = ( fv(e 1 )\{a, b} ) fv(e 2 ) fv(e 3 ) fv(f(e 1, e 2,..., e n )) = fv(e 1 ) fv(e 2 ) fv(e n ) fv( (e 1, e 2,..., e n )) = fv(e 1 ) fv(e 2 ) fv(e n ) 26

28 FunSETL 4.3 Semantik Substituerg af udtryk for variabel Før vi præsenterer semantikken, deferes det, hvad der menes med at substituere et udtryk e for en variabel v i et udtryk e. Dette benyttes til at defere semantikken for let-, fold og funktionskaldsudtryk. Vi deferer e[e /v] ved strukturel duktion over e: w[e /v] = c[e /v] = c { e hvis w = v w ellers (if e 1 then e 2 else e 3 )[e /v] = if e 1 [e /v] then e 2 [e /v] else e 3 [e /v] { (let w = e 1 e 2 )[e let w = e1 [e /v] = /v] e 2 hvis w = v let w = e 1 [e /v] e 2 [e /v] ellers { (fold (a, b => e 1 ) e 2 e 3 )[e fold (a, b => e1 ) e /v] = 2 [e /v] e 3 [e /v] hvis a = v eller b = v fold (a, b => e 1 [e /v]) e 2 [e /v] e 3 [e /v] ellers (f(e 1, e 2,..., e n ))[e /v] = f(e 1 [e /v], e 2 [e /v],..., e n [e /v]) ( (e 1, e 2,..., e n ))[e /v] = (e 1 [e /v], e 2 [e /v],..., e n [e /v]) For e 1, e 2,... e n og v 1, v 2,... v n hvor v-erne er parvis forskellige, deferes samtidig substitution af e i for v i i et udtryk e skrevet e[e 1/v 1, e 2/v 2,, e n / v n ] på tilsvarende måde. En substitution θ er en partiel afbildng Var Exp. For en substitution θ = [v 1 e 1,..., v n e n ] deferes e[θ] for e Exp ved: e[θ] = e[e 1 /v 1,..., e n /v n ] Operationssemantik for lukkede udtryk I dette afsnit deferes relationen EvRel p Exp Const for et typekorrekt program p. (e, c) EvRel p skrives e p c. Vi skriver d e p c, hvis d er en afledng af e p c, og e p c, hvis der fdes en afledng d med d e p c. Normalt er det underforstået, at der med e p c menes e p c. Hvis e p c siger vi, at e evaluerer til c (i p). For alle operationer Ops lader vi være implementergen af. For eksempel er implementergen for plus-operationen, der tager to heltal som argumenter, den sædvanlige heltalsaddition. Vi antager, at for alle Ops er en total funktion. Relationen deferes som den mdste relation, der er afsluttet mht. følgende regler: Const: If(1): c p c e 1 p true e 2 p c if e 1 then e 2 else e 3 p c If(2): e 1 p false e 3 p c if e 1 then e 2 else e 3 p c Let: e 1 p c e 2 [c/v] p c let v = e 1 e 2 p c 27

29 FunSETL 4.3 Semantik Fold(1): e 3 p {c 1,..., c n } e 2 p c fold (v 1, v 2 => e 1 ) c {c 1,..., c n } p fold c fold (v 1, v 2 => e 1 ) e 2 e 3 p c Call: e 1 p c 1 c 2 p c 2... e n p c n e f [c 1 /v 1 c n /v n ] p c f(e 1, e 2,..., e n ) p c (hvor fun f(v 1 : t 1,... v n : t n ) = e f i p) Op: e 1 p c 1 c 2 p c 2 e n p c n (e 1, e 2,..., e n ) p c (hvor (c 1,..., c n ) = c) Samtidig deferes relationen fold (v 1, v 2 => e 1 ) c {c 1,..., c n } p fold c for v 1, v 2 Var, e 1 Exp og c, c, c 1, c 2,... c n Const og typekorrekt p ved følgende to regler: Fold(2): fold (v 1, v 2 => e 1 ) c {} p fold c Fold(3): fold (v 1, v 2 => e 1 ) c {c 1,..., c n 1 } p fold c e 1 [c n /v 1, c /v 2 ] p c fold (v 1, v 2 => e 1 ) c {c 1,..., c n } p fold c Reglen Const siger, at en konstant evaluerer til sig selv. Der er ikke nogen regel for variable, da vi kun deferer relationen for lukkede udtryk. Af reglerne If(1) og If(2) ser vi, at hvis betgelsen i et betget udtryk evaluerer til konstanten true, så evaluerer hele udtrykket til c, hvis thengrenen evaluerer til c, og hvis betgelsen evaluerer til false, så evaluerer hele udtrykket til c, hvis else-grenen gør det. Udtrykket let v = e 1 e 2 evaluerer til c, hvis e 1 evaluerer til c, og e 2 med c substitueret for v evaluerer til c. I reglen Fold(1) bruges relationen p fold. Intuitionen er, at først evalueres udtrykket e 3 til en multimængde, dernæst evalueres udtrykket e 2 til en konstant c, og til sidst foldes funktionen λ(v 1, v 2 ).e 1 over multimængden, med c som startværdi. Reglerne Fold(2) og Fold(3) deferer dette nærmere. Grundtilfældet, hvor multimængden er tom, behandles i Fold(2). Reglen Fold(3) beskriver duktivt, hvordan en foldng udføres for en multimængde med n 1 elementer. Et funktionskald evaluerer til c, hvis kroppen af den kaldte funktion med konstanter c i substitueret d for de formelle parametre evaluerer til c. Desuden skal argumentudtrykkene e i evaluere til c i. En operatoranvendelse (e 1, e 2,..., e n ) evaluerer til c, hvis parameterudtrykkene e i evaluerer til c i, og implementergen (c 1,... c n ) giver c Semantikken er determistisk Som det sidste i dette kapitel vises et par egenskaber ved relationen p. For det første vises, at relationen er determistisk. Desuden vises, at relationen er total, dvs. at der for ethvert lukket udtryk e fdes en konstant c, så e evaluerer til c. Altså er relationen p en funktion. At semantikrelationen er total betyder tuitivt, at ethvert FunSETL-program termerer. Dette gælder, fordi den eneste løkke-konstruktion er fold-udtryk, og der er her tale om en kontrolleret form for gentagelse, idet antallet af iterationer er givet på forhånd som antallet af elementer i multimængden, der foldes over. Det første lemma viser, at semantikrelationen er total. Lemmaet bevises ved et duktionsbevis, hvor der i fold-tilfældet dlejres et nyt lemma, der udtaler sig om p fold relationen. Dette dlejrede lemma vises ved matematisk duktion efter antallet af konstanter i multimængden, der foldes over. Det illustrerer en teknik der er brugbar i mange tilfælde, og som vil optræde ofte i denne opgave, derfor giver vi beviset i detaljer. 28

30 FunSETL 4.3 Semantik Lemma 1 Lad p være et typekorrekt program og e et lukket udtryk, der er typekorrekt mht. p. For alle konstanter c 1 og c 2 gælder: e p c 1 e p e 2 c 1 = c 2 Bevis: Lad p og e være givne. Vi viser lemmaet egenskab ved fuldstændig duktion 1 på aflednger med relationen (ægte delafledng). Vi deferer egenskaben P for en afledng d: P (d) e, c 1, c 2.e lukket ( d e p c 1 e p c 2 c 1 = c 2 ) Lad d være en afledng. Vi antager som duktionshypotese: d.d d P (d ) (4.1) Ifølge duktionsprcippet er det nok at vise P (d). Lad altså e, c 1 og c 2 være givne og antag, at e er lukket, og d e p c 1 og e p c 2. Vi skal så vise c 1 = c 2. Vi kan antage at d 1 e p c 2 for en afledng d 1. Vi deler op i tilfælde efter strukturen af e. e = c Vi har d = c p c og d 1 = c p c, så c 1 = c 2 = c som ønsket. e = if e 1 then e 2 else e 3 Der er to muligheder for hvilken regel, der er den sidst anvendte i d. Antag først, at det er reglen If(1). Så har vi altså: d = d 1 d 2 e 1 p e true 2 p c 1 if e 1 then e 2 else e 3 p c 1 Da d 1 d har vi fra duktionsantagelsen, at P (d 1) gælder. Vi kan altså ikke have e 1 p c for et c true. Derfor må den sidst anvendte regel i d 1 også være If(1), så d 1 har formen: d 1 =.. e 1 p e true 2 p c 2 if e 1 then e 2 else e 3 p c 2 Specielt har vi e 2 p c 2. Da d 2 d har vi P (d 2), og dermed c 1 = c 2 som ønsket. Tilfældet, hvor den sidst anvendte regel i d er If(2), vises tilsvarende. e = let v = e 1 e 2 Vi har og d = d 1 = d 1 d 2 e 1 p c e 2 [c 1/v] p c 1 1 let v = e 1 e 2 p c 1. e 1 p c 1. e 2 [c 1/v] p c 2 let v = e 1 e 2 p c 2 Da d 1 d har vi fra (4.1), at c 1 = c 1. Da d 2 d og e 2 [c 1/v] er lukket har vi ifølge (4.1) at c 1 = c 2 som ønsket. 1 Betegnelsen fuldstændig duktion bruges om det engelske well-founded duction, som er beskrevet i [14]. 29

31 FunSETL 4.3 Semantik e = fold (a, b => e 1 ) e 2 e 3 Vi har d = og d 1 e 3 p {c 1,..., c n} d 2 e 2 p c 1 fold (a, b => e 1 ) e 2 e 3 p c 1 d 3 fold (a, b => e 1 ) c 1 {c 1,..., c n} p fold c 1 d 1 =. e 3 p {c 1,..., c m}. e 2 p c 2 Da d 1 d får vi fra (4.1) at m = n og c i = c i c 1 = c 2. Vi dskyder nu et lemma: Lemma 2 fold (a, b => e 1 ) e 2 e 3 p c 2. fold (a, b => e 1 ) c 2 {c 1,..., c m} p fold c 2 for i = 1,... n. Tilsvarende giver d 2 d at c, c, c, c 1,.c 2,... c n, d. d d ( d fold (a, b => e1 ) c {c 1,..., c n} p fold c fold (a, b => e 1) c {c 1,..., c n} p fold c c = c ) Hvis det dskudte lemma gælder, får vi (da d 3 d) at c 1 = c 2 som ønsket. Det dlejrede lemma bevises ved duktion efter n. I basistilfældet har vi n = 0. Antag c, c, c og d givne med d fold (a, b => e 1 ) c {} p fold c og fold (a, b => e 1 ) c {} p fold c. Fra reglerne for relationen p fold ses, at den eneste mulighed er, at afledngerne bruger reglen Fold(2). Derfor gælder c = c = c som ønsket. Lad nu et n 0 > 0 være givet. Antag c, c, c, c 1,.c 2,... c n0, d. d d ( d fold (a, b => e1 ) c { c 1,..., c n0 } p fold c fold (a, b => e 1 ) c { c 1,..., c n0 } p fold c c = c ) (4.2) Lad c, c, c 1, c 2,..., c n0+1 og d være givne, og antag at d d og d fold (a, b => e 1 ) c { c 1,..., c n0+1} p fold c og d 1 fold (a, b => e 1 ) c { c 1,..., c n0+1} p fold c. Vi har nu d = og d 2 fold (a, b => e 1 ) c { c 1,..., c n0 } p fold c fold (a, b => e 1 ) c { c 1,..., c n0+1} p fold c d 3 e 1 [ c n0+1/a, c/b] p fold c d 1 =. fold (a, b => e 1 ) c { c 1,..., c n0 } p fold c fold (a, b => e 1 ) c { c 1,..., c n0+1} p fold c. e 1 [ c n0+1/a, c /b] p fold c Fra (4.2) får vi (da d 2 d d) at c = c. Da d 3 d d får vi fra (4.1) at c = c som ønsket. Det afslutter beviset for det dlejrede lemma. e = f(e 1, e 2,..., e n ) c 1 = c 2 kan vises ved at bruge duktionsantagelsen (4.1) på samme måde som tidligere vist. e = (e 1, e 2,..., e n ) c 1 = c 2 kan vises ved at bruge duktionsantagelsen (4.1) på samme måde som tidligere vist. 30

32 FunSETL 4.3 Semantik Semantikken er total Før vi kan vise, at evaluergsrelationen er total, skal vi bruge et resultat om, hvordan substituerg opfører sig i forhold til typerelationen. Resultatet siger, at hvis et udtryk e har typen t under antagelse af, at en variabel v har typen t, så kan vi substituere en vilkårlig konstant af typen t d for v i e uden at ændre typen: Lemma 3 Lad e være et udtryk. Hvis σ[v t], Γ e : t så gælder σ, Γ e[c/v] : t for alle c med c : t. Lemmaet kan bevises ved strukturel duktion over e med brug af duktionsantagelsen e. e e ( σ, Γ, t, t, c. σ[v t], Γ e : t c : t σ, Γ e [c/v] : t ) Vi kan nu formulere og bevise resultatet, at evaluergsrelationen er total. Lemma 4 Lad p være et program, og antag p : Γ. Lad e være et lukket udtryk med [ ], Γ e : t. Der fdes en konstant c, så e p c og c : t. Bevis: Strukturel duktion over e er ikke velegnet, da der i semantikken benyttes substituerg, og derfor optræder der udtryk, der ikke er ægte deludtryk af det origale udtryk. Induktion efter størrelsen af et udtryk e er ikke tilstrækkelig stærkt til at bevise lemmaet i funktionskaldstilfældet, hvilket skyldes, at funktionskroppen ikke nødvendigvis er mdre end kaldudtrykket, så duktionsantagelsen giver gen formation om evaluergen af funktionskroppen. Det kan vi reparere på ved at bruge en stærkere duktionsantagelse. Størrelsen af et udtryk e kan deferes på oplagt måde. Lad f være en funktion i programmet p, og betragt kaldgrafen G for f. Knuderne i grafen er navne på de funktioner, der bliver kaldt (transitivt) fra f, og der er en kant fra g til h, hvis g kalder h. Da der ikke tillades rekursion, og f kun kan kalde funktioner, der er deferet senere end f, er G en DAG (orienteret acyklisk graf), hvor knuden f ikke har nogen dgående kanter. Højden af kaldgrafen deferes som den længste sti startende fra f. Vi kan nu defere funktionen maxhøjde for et udtryk e: lad f 1,... f n (n 0) være navnene på de funktioner, der kaldes (direkte) fra e. maxhøjde(e) er så den maksimale højde af kaldgraferne for f 1,... f n. Relationen deferes ved: e 1 e 2 maxhøjde(e 1 )<maxhøjde(e 2 ) (maxhøjde(e 1 ) = maxhøjde(e 2 ) e 1 < e 2 Relationen er et leksiografisk produkt af to relationer, der er well-founded (se [14]), så derfor er den well-founded (hvilket vises i [14] kapitel 10). Vi beviser lemmaet ved fuldstændig duktion på Exp med relationen. Lad p være givet, og antag p : Γ. Lad ē være givet og antag, at ē er lukket og at [ ], Γ ē : t. Vi antager som duktionsantagelse: e.e e e lukket ( t.[ ], Γ e : t c.e p c c : t ) (4.3) Ifølge duktionsprcippet er det nok at vise c.ē p c c : t. Vi deler op i tilfælde efter strukturen af ē, og skal altså angive et c så ē p c og c : t. ē = c Vi må have t = Constty(c). Vi kan tage c = c. ē = if e 1 then e 2 else e 3 Fra antagelsen [ ], Γ ē : t får vi, at [ ], Γ e 1 : bool, [ ], Γ e 2 : t og [ ], Γ e 3 : t. For i = 1, 2, 3 har vi e i ē og e i er lukket, så fra (4.3) får vi, at der fdes c 1, c 2, c 3 med e 1 p c 1 c 1 : bool e 2 p c 2 c 2 : t e 3 p c 3 c 3 : t 31

33 FunSETL 4.3 Semantik Fra antagelsen i afsnit får vi, at c 1 = true, eller c 1 = false. Hvis c 1 = true, kan vi tage c = c 2, og hvis c 1 = false kan vi tage c = c 3. ē = f(e 1, e 2,..., e n ) e i ē. For i = 1,... n har vi maxhøjde(e i ) maxhøjde(ē) så da e i < ē får vi Fra antagelsen [ ], Γ ē : t får vi, at Γ(f) = (t, t 1,..., t n ) og [ ], Γ = e i : t i for i = 1,... n. Fra (4.3) får vi så, at der fdes c 1,... c n med e i p c i og c i : t i for i = 1,... n. Vi kan antage, at f er deferet ved f(v 1 : t 1, v 2 : t 2,..., v n : t n ) = e f. Betragt kaldgrafen f G for f. Grafen har en kant fra f til hver af de funktioner, der optræder i funktionskroppen e f. Vi har derfor maxhøjde(e f )<maxhøjde(ē), og dermed også maxhøjde(e f [c 1 /v 1,, c n /v n ])<maxhøjde(ē). Derfor har vi e f [c 1 /v 1,, c n /v n ] ē. Da Γ(f) = (t, t 1,..., t n ) må det gælde, at [v 1 t 1,..., v n t n ], Γ e f : t hvor Γ er Γ uden bdger for f og de funktioner, der deferes senere end f i p. Gentagen anvendelse af lemma 3 giver så, at [ ], Γ e f [c 1 /v 1, c n /v n ] : t og dermed [ ], Γ e f [c 1 /v 1, c n /v n ] : t. Fra (4.3) fås derfor, at der fdes et c med e f [c 1 /v 1, c n /v n ] p c og c t som ønsket. ē = fold (a, b => e 1 ) e 2 e 3 Vi har pr. antagelser at [ ], Γ e 2 : t, [ ], Γ e 3 : mset( t) for et t og [a t, b t], Γ e 1 : t. Da e 2 ē og e 3 ē får vi fra (4.3), at der fdes c 2 og c 3 så e 2 p c 2, e 3 p c 3, c 2 : t og c 3 : mset( t). Fra antagelsen i afsnit får vi, at c 3 = { c 1,... c n } hvor n 0 og c i : t for i = 1,... n. Vi dskyder et lemma: Lemma 5 c, c 1,..., c n. c : t c i : t for i = 1,... n c.fold (a, b => e 1 ) c { c 1,..., c n } p fold c c : t Fra det dskudte lemma får vi, at der fdes et c så fold (a, b => e 1 ) c 2 { c 1,..., c n } p fold c og c : t. Vi kan altså tage c = c. Det dskudte lemma vises ved duktion over n, hvor der i duktionstrnet anvendes (4.3) samt lemma 3. De resterende tilfælde (let og operationsanvendelse) vises ved at bruge duktionsantagelsen (4.3) og kombere resultaterne på samme måde, som det er vist ovenfor. Vi slutter kapitlet med et korrolar til lemma 1 og 4. I kapitel 9 vender vi tilbage til hvordan sproget kan implementeres ved oversættelse til Standard ML. Korrolar 1 Lad p være et typekorrekt program, og lad e og e være lukkede udtryk, der er typekorrekte mht. p. Hvis c.e p c e p c så c.e p c e p c Bevis: Antag c.e p c e p c, og lad c være en vilkårlig konstant. Vi skal vise e p c e p c. Antag e p c. Ifølge lemma 4 fdes et ĉ så e p ĉ. Fra antagelsen har vi så e p ĉ. Ifølge lemma 1 har vi så c = ĉ, og dermed e p c som ønsket. 32

34 Kapitel 5 Inkrementelle metoder REA-modellen blev beskrevet i kapitel 2. Den adskiller sig fra traditionelle måder at lave bogførgssystemer på ved fokusergen på basale data fremfor afledte data. Det blev også skitseret, hvordan det i systemer, der er implementeret direkte efter REA-modellen, giver anledng til problemer med et stort tidsforbrug til at vedligeholde afledte formationer. Denne problemstillg behandles kort i aftiklen [1], der foreslår, at der bruges en teknik kaldet krementel beregng til at løse problemet. I artiklen skitseres i generelle termer, hvordan denne metode kan give gode resultater for forespørgselssproget OQL. Men forfatterne har ikke implementeret metoden, som de skitserer, og beskrivelsen er ikke tilstrækkelig detaljeret til at bruges som udgangspunkt for en implementerg. I dette kapitel beskrives nogle forskellige metoder, der alle kan kaldes krementelle metoder. Kapitlet afsluttes med en overordnet beskrivelse af en teknik, der er udviklet til at effektivisere rapporter skrevet i sproget FunSETL fra kapitel 4. De følgende kapitler beskriver i detaljer, hvordan metoden virker, og viser egenskaber ved den. Denne opgave kan altså ses som en opfølgng på manglerne i arbejdet, der er beskrevet i [1]. Betegnelsen krementelle metoder bruges om programtransformationer, der forsøger at udnytte kendskab til tidligere beregnger til at effektivisere en beregng. I det følgende beskrives en række sådanne metoder i forskellig detaljergsgrad. 5.1 Fælles deludtryk I artiklen [15] beskriver Fong en programtransformationsteknik for et mængde-teoretisk sprog som for eksempel SETL. Metoden er en slags generaliseret elimerg af fælles deludtryk 1, der her illustreres ved et eksempel. Betragt følgende programsekvens bestående af 3 tildelgssætnger i et sprog med mængder: n 1 : X = (A B) C n 2 : A = A {x} n 3 : Z = D\(A B) Deludtrykket A B optræder både i n 1 og n 3, men i n 2 ændres værdien af A, så udtrykket A B ikke længere er tilgængeligt i n 3 og derfor skal beregnes forfra udfra A og B, hvilket tager tid proportionelt med størrelsen af mængderne. Metoden fra [15] går ud på at dentificere, at A kun ændres lidt, så ved at dføre en 1 Elimerg af fælles deludtryk er en klassisk programtransformation, der for eksempel er beskrevet i [16]. 33

35 Inkrementelle metoder 5.2 Strength reduction midlertidig variabel T kan vi undgå at skulle genberegne A B: m 1 : T = A B m 2 : X = T C m 3 : T = T {x} m 4 : A = A {x} m 5 : Z = D\T Deludtrykket A B gemmes altså i T, og ændrgsoperationen udføres nu på både A og T, hvilket sikrer, at ved tildelgen m 5 deholder T den korrekte værdi af A B. Nettoeffekten er, at en forengsmængde-operation er udskiftet med en operation, der tilføjer et enkelt element til en mængde. Det antages, at sidstnævnte operation kan udføres i konstant tid. Den transformerede programsekvens repræsenterer altså en forbedrg i tidsforbruget i forhold til den origale sekvens. 5.2 Strength reduction Betragt et udtryk f(x 1,... x n ), der er gemt i variablen C. Hvis udtrykket bruges gentagne gange i en region R, der modificerer en eller flere af parametrene x i, kan beregngen af udtrykket ikke flyttes udenfor R. Men hvis udtrykket er tilgængeligt i C ved alle dgange til regionen R, og hvis der for hver operation, der ændrer en parameter x i også udføres en ændrg på C så C hele tiden deholder værdien af f(x 1,..., x n ), kan man måske undgå at beregne f(x 1,..., x n ) forfra og i stedet bruge værdien i C. Dette kan ses som en slags generaliseret strengh reduction for mængde-teoretiske sprog 2. Fong har undersøgt denne teknik i detaljer i blandt andre artiklerne [18] og [19]. Her beskrives det, hvordan denne transformation kan foretages for konstruktioner der opbygger mængder, for eksempel {x A ϕ(x)}, hvor ϕ er en funktion af x. 5.3 Formel differentierg Metoden formel differentierg er udviklet af Robert Paige og er beskrevet i bogen [20], der er en revideret udgave af hans ph.d.-afhandlg. Den deholder en grundig behandlg af metoden, mens artiklen [21] beskriver doldet af metoden i kort form. I den nævnte artikel bruges betegnelsen formel differentierg om teknikken beskrevet i forrige afsnit (generaliseret strength reduction ). Med betegnelserne fra afsnit 5.2 bemærkes det, at hvis der skal være tale om en forbedrg, så skal det være nemmere at udføre opdatergsoperationerne end at beregne udtrykket f(x 1,..., x n ) forfra. Derfor dføres i [21] begrebet kontuitet, der tuitivt betyder, at hvis der for en lille ændrg x i af en parameter kan udføres en lille ændrg af udtrykket f(x 1,..., x n ), så værdien bliver den samme som f(x 1,..., x i 1, h(x i, x i ), x i+1,..., x n ), hvor h(x i, x i ) er et udtryk, der afhænger af x i og x i, så er udtrykket f(x 1,..., x n ) kontuert med hensyn til operationen x i. For eksempel er udtrykket A B kontuert med hensyn til ændrgerne A = A {x} og B = B {x}. Formel differentierg af udtrykket C = A B med hensyn til ændrgen A = A {x} er sekvensen: C = A B C = C {x} A = A {x} Efter den sidste tildelg deholder C den aktuelle værdi af A B. Artiklen [21] identificerer en række udtryk, der er kontuerte i deres parametre, og beskriver, hvordan de kan differentieres formelt. I artiklen bemærkes det, at det er tvivlsomt, at der kan 2 Transformationen strength reduction er beskrevet i [17]. 34

36 Inkrementelle metoder 5.4 Fite differencg konstrueres et system, der automatisk udfører de optimerger, der skal til for at bruge formel differentierg, så i stedet foreslås en semi-automatisk fremgangsmetode. Fong og Paiges arbejde er begge videreudviklg af en metode beskrevet af Early som iterator version. I [22] beskrives, at Paiges metode er mere generel end Fongs. 5.4 Fite differencg I artiklen [23] bruges betegnelsen fite differencg om teknikkerne strength reduction og formel differentierg. Artiklen er på mange måder en sammenfatng af bogen [20], men deholder også nyt materiale. En forskel i forhold til metoden fra afsnit 5.2 er, at der dsættes opdatergskode både før og efter de operationer, der ændrer ved parametre x i som udtrykket E = f(x 1,..., x n ) afhænger af. Differentialet for E med hensyn til opdatergsoperationen x i kaldes E B, og består af følgende sekvens: E x i x i + E x i hvor E x i og + E x i er præ- og postopdatergskode for udtrykket E med hensyn til ændrgen x i. I den resulterende kodesekvens udskiftes brug af f(x 1,..., x n ) med E, hvis E er tilgængelig. Hvis vi for eksempel har E = {x A x mod 2 = 0}, kan vi tage E A = A {x} til den betgede sætng if x mod 2 = 0 then E = E {x} og vi kan tage + E A = A {x} til den tomme sekvens. I [23] er der angivet en tabel med en oversigt over E x i og + E x i for forskellige E og x i. Sammen med en kæderegel bruges den til at differentiere sammensatte udtryk, der er kontuerte (som beskrevet i afsnit 5.3) i alle deres parametre. Der gives eksempler på udtryk, der afhænger diskontuert af en parameter, men hvor der kan differentieres ved at vedligeholde forskellige hjælpeudtryk. Yderlige behandlg af teknikken fite differencg kan fdes i [24], [25] og [22]. Sidstnævnte beskriver en top-down tilgang i modsætng til Paiges bottom-up -metode, men den giver med forfatterens ord problemer i en implementerg og er bedst egnet til manuel transformerg. 5.5 Inkrementel beregng Metoden krementel beregng (cremental computation) dføres af Annie Liu i hendes ph.d.- afhandlg [26]. Indholdet i afhandlgen er publiseret som fire seperate artikler [27], [28], [29] og [30], og i [31] gives et overblik over metoden. Vi nøjes her med et kort overblik over metoden, og henviser til de nævnte artikler for yderligere formation. Lad f være et program og en operation. Hvis f beregner f(x y) ud fra f(x) kalder Liu f for en krementel version af f. Metoden går ud på at konstruere f ud fra f og, hvilket kaldes at krementalisere f med hensyn til. Sproget, der behandles, er et førsteordens funktionsorienteret sprog, hvor et program består af en række dbyrdes rekursive funktioner. Inkrementalisergen opdeles i tre dele: f konstrueres ved at bruge returværdien f(x) f konstrueres ved at bruge mellemresultater fra f(x), dvs. værdier der beregnes som en del af f(x), men som ikke nødvendigvis er returværdien 35

37 Inkrementelle metoder 5.6 Inkrementaliserg af FunSETL f konstrueres ved at vedligeholde hjælperesultater, dvs. værdier der bruges af f, men ikke beregnes af f(x) og som kan vedligeholdes billigt Disse tre punkter kommenteres yderligere i de følgende afsnit Brug af returværdien Antag at resultatet af f(x) er r, og at vi ønsker en krementel version af f med hensyn til. For at konstruere f ud fra kendskab til værdien af f(x) gøres følgende: først udfoldes udtrykket f(x y) ved hjælp af defitionen af f. Dernæst udføres simplificerger, og hvis værdien f(x) optræder, udskifter vi den med en reference til cache-parameteren r. Det udtryk, der fås, udgør kroppen af en ny funktion f, der har x, y og r som argumenter, og som opfylder, at hvis f (x, y, r) = r, så gælder f(x y) = r, hvis r = f(x). Metoden, der bruges til at identificere f(x) i det udfoldede udtryk, kan være simpel lighed af udtryk, eller mere avancerede analyser, der udnytter semantiske egenskaber ved sproget. Artiklen [27] deholder detaljerede formationer om hvordan krementalisergen foregår Brug af mellemresultater Programmet f ændres til f, der returnerer alle mellemresultater fra f. Med metoden fra forrige afsnit krementaliseres f med hensyn til operationen til f. Til sidst analyseres f for at fde ud af hvilke mellemresultater, der er nødvendige for at f kan beregne sit resultat, og resten fjernes fra både f og f, hvilket resulterer i ˆf og ˆf. Denne to-delte proces kaldes cache-and-prune og beskrives i detaljer i artiklen [28] Brug af hjælperesultater Mellemresultater i f(x y), der ikke udregnes af f(x), anses som kandidater for hjælperesultater. De kandidater, der kan vedligeholdes billigt, tilføjes som mellemresultater og der krementaliseres som beskrevet i afsnit Detaljerne kan fdes i [29]. Lius metode adskiller sig fra Paiges ved for det første at behandle et sædvanligt førsteordens funktionsorienteret sprog, fremfor et høj-niveau mængde-teoretisk sprog som SETL. Paiges metode går ud på at konstruere regler, der kan bruges til at transformere dyre primitive operationer til mere effektive krementelle udgaver. Lius metode er baseret på at udnytte program-semantik, og ikke specielle egenskaber ved enkelte sprog-primitiver. 5.6 Inkrementaliserg af FunSETL Som det sidste i dette kapitel beskrives metoden, der er udviklet til krementaliserg af FunSETLprogrammer. Metoden er spireret af Lius metode til krementel beregng. Først forklares, hvad der menes med at krementalisere et FunSETL-program, og dernæst beskrives de tre tr, som metoden består af Opdatergsoperation Lad f være et FunSETL-program, som for eksempel et af rapportprogrammerne beskrevet i kapitel 3. En basal opdatergsoperation for en rapport er tilføjelse af en ny kontrakt eller en ny hændelse til journalen. Vi er teresserede i at konstruere en krementel version f med hensyn til de to opdatergsoperationer tilføjelse af en kontrakt og tilføjelse af en hændelse. Vi formulerer dog metoden mere generelt. En opdatergsoperation har formen [x 1,... x n ] [y 1,..., y m ] = [e 1,..., e n ], hvor udtrykkene e i kan deholde forekomster af variablene x 1,..., x n og y 1,..., y m. 36

38 Inkrementelle metoder 5.6 Inkrementaliserg af FunSETL For rapporten Resultatopgørelse kan opdatergen tilføjelse af en kontrakt udtrykkes på følgende måde: [J, I, v] [c new ] = [{contracts := #contracts(j) with c new, events := #events(j)}, I, v] altså ændres journalen, så der tilføjes en ny kontrakt c new. Opdatergsoperationen tilføjelse af en ny hændelse kan angives på tilsvarende måde. Målet er at konstruere et program f, så f (x 1,..., x n, y 1,..., y m, r) = f(e 1,..., e n ) hvis r = f(x 1,..., x n ). Mengen er altså, at f skal kaldes med returværdien fra f i parameteren r. Denne parameter kaldes derfor for cachen for f Transformationen Extend Det første tr i krementalisergen kaldes Extend og består af en transformation, der ændrer programmet f til ˆf, hvor tuitionen er, at ˆf foruden den origale returværdi (fra f) returnerer værdien af funktionskald foretaget i f. Det svarer til, at der gemmes flere formationer i cachen, hvilket giver mulighed for at flere deludtryk kan hentes fra cachen i stedet for at blive beregnet fra grunden. Transformationen Extend, der er spireret af [28], er beskrevet i detaljer i kapitel 6, hvor der også gives eksempler. Der er ikke tale om en ændrg af det asymptotiske tidsforbrug, da de mellemresultater, der returneres i f, også beregnes af f. Dog er der et større pladsforbrug, men det anses her som et mdre problem Transformationen Clean Brugen af Extend-transformationen efterlader programmet ˆf med funktionskroppe, der deholder mange record-operationer, der kan optimeres væk, og let-bdger, der kan udfoldes. For at rydde op i dem bruges transformationen Clean, der er spireret af [32]. Kapitel 7 beskriver transformationen i detaljer sammen med eksempler på dens brug Transformationen IncProgram For at krementalisere en funktion ˆf med hensyn til opdatergsoperationen [x 1,... x n ] [y 1,..., y m ] = [e 1,..., e n ] udføres følgende punkter: Udtrykket ˆf(x 1,..., x n ) udfoldes, og resultatet bruges som udgangspunkt for at opbygge cachen C, der altså deholder returværdien af ˆf, hvilket kluderer mellemresultater fra f. Udtrykket ˆf(e 1,..., e n ) udfoldes, og efter simplificerger ledes efter deludtryk, der kan udskiftes med referencer til cachen. Hvis det resulterende udtryk deholder funktionskald, krementaliseres disse, og kaldene forsøges udskiftet med kald til de krementelle versioner. Der deferes en ny funktion ˆf med parametre x 1,..., x n, y 1,..., y m, r, hvor funktionskroppen er udtrykket fra sidste punkt. Funktionen opfylder, at ˆf(x 1,..., x n, y 1,..., y m, r) = ˆf(e 1,..., e n ), hvis r = ˆf(x 1,..., x n ). Betgelsen r = ˆf(x 1,..., x n ) kalder vi for kaldbetgelsen for ˆf. I det følgende beskrives hvilke simplificerger, der er tale om, samt hvordan funktionskald håndteres. 37

39 Inkrementelle metoder 5.6 Inkrementaliserg af FunSETL Simplificerger Nøglen til krementalisergen af FunSETL-programmer ligger i det faktum, at den eneste form for gentagelse er fold-udtryk. For fold-udtryk er følgende omskrivng semantikbevarende: fold (a, b => e 1 ) e 2 (S with e) e 1 [e/a, (fold (a, b => e 1 ) e 2 S)/b] Omskrivngen beskriver en udfoldng af fold-udtrykket. Hvis udtrykket fold (a, b => e 1 ) e 2 S) kan fdes i cachen med udtrykket h(r), kan vi yderlige simplificere til e 1 [e/a, h(r)/b] hvilket svarer til en enkelt evaluerg af fold-funktionen frem for en foldng over hele multimængden S with a. Altså kan fold-funktionen bruges som krementel version af fold-udtrykket. I afsnit 8.4 i kapitel 8 beskrives en transformation, der blandt andet realiserer fold-omskrivngen Funktionskald Hvis funktionen, der krementaliseres, deholder et funktionskald g(e 1,..., e k ), krementaliseres g, og hvis kald-forudsætngen for den resulterende funktion g er opfyldt, udskiftes kaldet af g med et kald af g. For at krementalisere g skal det angives, hvilken opdatergsoperation der er tale om. En opdatergsoperation for g består som beskrevet af tre dele: variable x 1,..., x k, ȳ 1,..., ȳ p og udtryk ē 1,..., ē k. Ud fra opdatergsoperationen [x 1,... x n ] [y 1,..., y m ] = [e 1,..., e n ] og parameterudtrykkene e 1,..., e k på kaldstedet, skal vi altså angive nye x og y-variable [ x 1,..., x k ] og [ȳ 1,..., ȳ p ] og nye udtryk [ē 1,..., ē k ], hvor de frie variable i udtrykkene er deholdt i de nye x- og y-variable. Generaliserg Det første tr i denne process er at generalisere parameterudtrykkene e 1,..., e k til ē 1,..., ē k med en substitution θ, så ē i [θ] = e i, og hvor ē i er en variabel eller et udtryk, der ikke deholder frie forekomster af variablene y 1,..., y m. Hvis opdatergsoperationen for eksempel er [J, I, v] [c new ] = [{contracts = #contracts(j) with c new, events = #events(j)}, I, v] og funktionskaldet er g(i, v, {contracts = #contracts(j) with c new, events = #events(j)}) så er [ē 1, ē 2, ē 3] = [e 1, e 2, e 3] og θ = [ ], men hvis kaldet er g(e(i), e (v), {contracts = #contracts(j) with c new, events = #events(j)}) hvor e(i) og e (v) repræsenterer udtryk, der afhænger af I henholdsvis v, så bliver [ē 1, ē 2, ē 3] = [ϕ 1, ϕ 2, {contracts = #contracts(j) with c new, events = #events(j)} og θ = [ϕ 1 e(i), ϕ 2 e (v)], hvor ϕ 1 og ϕ 2 er nye variabelnavne. Denne generaliserg udføres for at give en funktion g, der er mere generel end den, der skal bruges på kaldstedet i håb om, at andre kald af g kan udskiftes med kald af den samme g. Nye x- og y-variable Vi har nu beskrevet, hvordan de nye udtryk [ē 1,..., ē k ] fdes. Vi mangler så at angive de nye x og y-variable til opdatergsoperationen. Opgaven er altså at opdele de frie variable fra [ē 1,..., ē k ] i x-variable og y-variable. 38

40 Inkrementelle metoder 5.6 Inkrementaliserg af FunSETL De nye y-variable tager vi til ( fv(e 1 ) fv(e k) ) {y 1,..., y m } altså en delmængde af de gamle y-variable. De nye x-variable fdes ved at bruge funktionen extract, der for hver af udtrykkene ē i returnerer en x-variabel på følgende måde: hvis ē i er en x-variabel, returneres den uændret. Hvis ē i er en y-variabel returneres et nyt navn for at undgå overlap med y-variablene. Hvis ē i er en variabel, der ikke er x- eller y-variabel, bruges den uændret som x-variabel. I det sidste tilfælde, hvor ē i ikke er en variabel, skal den deholde netop én x- variabel, som benyttes som ny x-variabel. Til sidst fjernes eventuelle gentagelser i listen af nye x-variable. For eksempel har vi og extract[v, I, {contracts = #contracts(j) with c new, events = #events(j)}] = [v, I, J] extract[v, ϕ, {contracts = #contracts(j) with c new, events = #events(j)}] = [v, ϕ, J] Den beskrevne metode til at generalisere ved behandlg af funktionskald mder om metoden, der bruges af Liu i [27]. Brug af krementelle funktioner Undervejs i krementalisergen opbygges og benyttes en afbildng D, der deholder formationer om, hvilke funktioner der er blevet krementaliserede. Et funktionsnavn bdes til den opdatergsoperation, som den er blevet krementaliseret med hensyn til, samt kaldbetgelsen for den krementelle version. Når der under krementalisergen stødes på et funktionskald, undersøges det først ved hjælp af D, om der allerede eksisterer en krementel version af funktionen, som kan bruges Sammenligng med Lius metode Som nævnt tidligere er den metode, der udvikles i denne opgave spireret af Lius metode til krementel beregng. Her beskrives nogle af forskellene på de to metoder. I den første del af Lius metode bruges der en bevis-generator (theorem prover) til at undersøge, om deludtryk kan udskiftes med referencer til cachen. Denne opgaves metode bruger kun simpel syntaktisk lighed, hvilket fjerner en stor del af komplikationen ved at implementere metoden, samt sikrer, at den kan være automatisk. Introducerg og oprydng af mellemresultater er anderledes, idet Lius metode deholder en beskærgsfase efter krementaliserg, hvor nogle af mellemresultaterne fjernes fra det krementelle program. Ved arbejdet med at udvikle og afprøve metoden, der præsenteres i denne opgave, viste det sig, at oprydngen med Clean før krementalisergen var tilstrækkelig, da FunSETL er et simplere sprog end det, Liu behandler, og derfor er der gen beskærgsfase. Den sidste del af Lius metode går ud på at forsøge at identificere hjælpeudtryk, der kan gøre et krementelt program mere effektivt. Det gøres ved en række transformationer, hvor udtryk, der beregnes af det krementelle program, anses som kandidater til udtryk, der skal vedligeholdes krementelt. Metoden, der udvikles i denne opgave, kluderer ikke en tilsvarende fase, da det ville føre for vidt. Dette kommenteres yderligere i kapitel

41 Kapitel 6 Extend-transformationen I dette kapitel præsenteres Extend-transformationen. Først vises nogle eksempler, der giver en fornemmelse for, hvordan Extend virker. Derefter deferes transformationen, og til sidst vises nogle egenskaber ved transformationen. 6.1 Recordtyper Vi antager, at FunSETL deholder record-typer. Det betyder, at mængden Ty deholder elementer af formen: {lab 1 : t 1, lab 2 : t 2,... lab n : t n } for n 1, hvor lab i er labels (for eksempel endelige tegnstrenge), t i er typer, og lab 1,... lab n er parvis forskellige. Desuden antager vi, at operationen {lab 1 := e 1,... lab n := e n } konstruerer udtryk af recordtype, og at udtrykket #lab(e) bruges til at fde værdien af det udtryk, der er bundet til lab i udtrykket e, hvor e har en recordtype, hvor lab dgår. Mængden af konstanter, der har typen {lab 1 : t 1,... lab n : t n }, er mængden bestående af elementer af formen {lab 1 := c 1,... lab n := c n }, hvor Constty(c i ) = t i for i = 1,..., n. 6.2 Eksempler Formålet med Extend-transformationen er at give mulighed for, at flere mellemresultater gemmes i cachen, så der er flere udtryk, der kan hentes fra cachen i stedet for at blive beregnet. Det gøres ved at ændre funktionsdefitionerne, så hver funktion sammen med den oprdelige returværdi returnerer de mellemresultater, der er udregnet undervejs Operatoranvendelse Som et eksempel på et program med en operatoranvendelse ser vi på det simple program 1. Alene ud fra returværdien for f er det ikke muligt at få adgang til værdien af g(x). Hvis programmet ændres til program 2, får vi adgang til mellemresultaterne g(x) og h(x). Det ændrede program returnerer altså en record, hvor den origale returværdi er placeret ved labelen 1. Extend-transformationen virker ved at ændre alle funktionsdefitioner, så der returneres en record af formen {1 := e 1, 2 := e 2,..., n := e n }, hvor e 1 giver den origale returværdi. 40

42 Extend-transformationen 6.2 Eksempler Program 1 Simpelt program med operatoranvendelse fun g(x : t) = x fun h(x : t) = x fun f(x : t) = g(x) + h(x) Program 2 Mellemresultater returneres fun g(x : t) = x fun h(x : t) = x fun f(x : t) = let v 1 = g(x) let v 2 = h(x) {1 := v 1 + v 2, 2 := v 1, 3 := v 3 } Betgede udtryk Betragt program 3. Det ændrede program skal returnere værdierne g(4) og g(5) sammen med deres Program 3 Simpelt eksempelprogram med betget udtryk fun g(x : t) = x fun f(x : bool) = if x then g(4) + g(5) else 10 sum, hvis x er sand. Det er et typekrav, at de to grene har samme type, så hvis then-grenen returnerer en record bestående af tre elementer (g(4) + g(5), g(4) og g(5)), så skal else-grenen det også. For at løse dette problem lader vi else-grenen returnere en record, hvor det første element er 10, og hvor de to næste elementer er standard -værdier af heltalstype. Program 4 viser det ændrede program. Program 4 Brug af Standard -værdier i et betget udtryk fun g(x : t) = x fun f(x : bool) = if x then let v 1 = g(4) let v 2 = g(5) {1 := v 1 + v 2, 2 := v 1, 3 := v 2 } else {1 := 10, 2 := 0, 3 := 0} Mere generelt: hvis der i then-grenen produceres mellemresultater v 2, v 3,..., v n med typerne t 2, t 3,... t n, og der i else-grenen produceres mellemresultater v 2, v 3,... v m med typerne t 2, t 3,... t m, så kan vi lade then-grenen returnere følgende record: {1 := w, 2 := v 2, 3 := v 3,..., n := v n, n + 1 := vs 2, n + 2 := vs 3,..., n + (m 1) := vs m } og else-grenen returnere følgende record: {1 := w, 2 := vs 2, 3 := vs 3,..., n := vs n, n + 1 := v 2, n + 2 := v 3,..., n + (m 1) := v m} Hvor w er den origale returværdi, vs 2,... vs m er standardværdier for typerne t 2,..., t m og vs 1,... vs n er standardværdier for typerne t 2,..., t m. De to grene i det betgede udtryk har 41

43 Extend-transformationen 6.2 Eksempler så samme type. Intuitivt kan vi sige, at der i de to grene bruges standardværdier til at fylde hullerne ud med så den record, der returneres, har samme struktur i begge grene Let-bdger Program 5 Simpelt eksempelprogram med Let-bdg fun g(x : t) = x fun f(x : t) = let w = g(x) + h(x) 3 + g(w) I program 5 er variablen w kun bundet i udtrykket 3 + g(w). Hvis vi sørger for, at w bdes til den samme værdi i det ændrede program, kan vi returnere mellemresultatet g(w). Det er illustreret i program 6. Program 6 Transformerg af let-udtryk fun g(x : t) = x fun f(x : t) = let v 1 = g(x) let v 2 = h(x) let w = v 1 + v 2 let v 3 = g(w) {1 := 3 + v 3, 2 := v 1, 3 := v 2, 4 := v 3 } Vi bemærker, at i program 6 bdes der en værdi til w, før der refereres til w, og derfor kan mellemresultatet g(w) returneres fra funktionen Fold-udtryk Det sidste eksempel, vi skal se på, er et program, der deholder et fold-udtryk. Dette tilfælde er lidt mere kompliceret end de foregående. Program 7 er et simpelt eksempel på et program, der deholder et fold-udtryk. Program 7 Simpelt eksempelprogram med fold-udtryk fun g(x : t) = x fun f(x : mset(t)) = fold (a, b => b + g(a)) g(0) x Et første forsøg på at ændre programmet så mellemresultater returneres, kunne se ud som i program 8. Der er to problemer med program 8: ved den første forekomst af variablen a er der ikke bundet en værdi til a, så programmet er ikke typekorrekt. For det andet har fold-udtrykket ikke den samme værdi som i det origale program, idet der bruges en fast værdi i stedet for det aktuelle element fra multimængden, når der foldes. I let-tilfældet er problemet med scope løst ved at sørge for, at let-variablen bliver bundet. I fold-tilfældet er det skiftende værdier, der skal bdes til a, så der kan ikke bruges samme fremgangsmåde som for let-udtryk. I stedet kan vi forsøge med en løsng som i program 9. 42

44 Extend-transformationen 6.2 Eksempler Program 8 Forsøg med fold-udtryk - ikke korrekt fun g(x : t) = x fun f(x : mset(t)) = let v 1 = g(a) let v 2 = g(0) {1 := fold (a, b => b + v 1 ) v 2 x, 2 := v 1, 3 := v 2 } Program 9 Andet forsøg med fold-udtryk - ikke korrekt fun g(x : t) = x fun f(x : mset(t)) = let v 2 = g(0) {1 := fold (a, b => let v 1 = g(a) {1 := b + v 1, 2 := v 1 } ) v 2 x, 2 := v 2 } Program 10 Sidste forsøg med fold-udtryk fun g(x : t) = x fun f(x : mset(t)) = let v 2 = g(0) {1 := fold (a, b => let v 1 = g(a) b + v 1 ) v 2 x, 2 := v 2 } Nu optræder a ikke i en kontekst, hvor den ikke er bundet. Til gengæld er programmet ikke typekorrekt, da fold-funktionen har ændret returtype - i stedet for en værdi af typen t returneres en record bestående af 2 elementer. For at rette på dette problem kan program 10 bruges. Vi ser, at mellemresultater, der beregnes i fold-funktionen, ikke returneres fra funktionen f. I det konkrete tilfælde beregnes mellemresultatet h(a) én gang for hvert element i multimængden x. Antallet af mellemresultater er derfor afhængigt af ddata til funktionen, men antallet af elementer i returtypen skal være fast. Derfor kan mellemresultaterne fra fold-funktionen ikke returneres på samme måde som de andre mellemresultater. Vi vælger derfor løsngen som i program Tilbagevendende eksempel De foregående afsnit forsøger at give en fornemmelse for, hvordan Extend-transformationen fungerer for de forskellige udtrykstyper. Vi viser transformationen af et komplet program. Programmet bruges også som eksempel i kapitlerne 7 og 8. Det origale program ser ud som følger: fun g(x : mset(t)) = fold (a, b => b + a) 0 x fun f(x : mset(t)) = let v = g(x) x with v Programmet består af to funktioner f og g der begge har ét argument, der er en multimængde af heltal. Funktionen g returnerer summen af elementerne i mængden, og funktionen f kalder g og tilføjer returværdien til værdien, der gives som parameter. Ved at transformere programmet med Extend fås følgende program: 43

45 Extend-transformationen 6.3 Standardværdier fun ĝ(x : mset(t)) = let Z 2 = {1 := 0} let Z 3 = {1 := x} fun ˆf(x : mset(t)) = {1 := fold (a, b => let Z 1 = let Z 4 = {1 := b} #1(Z 2 ), #1(Z 3 ))} let Z 5 = {1 := a} {1 := #1(Z 4 ) + #1(Z 5 )} #1(Z 1 ), let Z 6 = let Z 8 = {1 := x} let Z 9 = ĝ(#1(z 8 )) {1 := #1(Z 9 ), 2 := Z 9 } let v = #1(Z 6 ) let Z 7 = let Z 10 = {1 := x} let Z 11 = {1 := v} {1 := #1(Z 10 )with#1(z 11 )} {1 := #1(Z 7 ), 2 := #2(Z 6 )} De nye funktioner ĝ og ˆf returnerer altså en record. I ˆf returneres mellemresultatet, der fås ved kald af ĝ som en del af returværdien, og den origale returværdi returneres med navnet 1. I kapitel 7 vises, hvordan der kan ryddes op i ovenstående program, så mange af de troducerede record-operationer kan elimeres. 6.3 Standardværdier Som beskrevet i afsnit har vi brug for at kunne konstruere en standardværdi for enhver type t. Vi antager, at funktionen val for en type t returnerer en værdi c af typen t. For et betget udryk if e 1 then e 2 else e 3 transformeres udtrykkene e 2 og e 3 med Extend til e 2 og e 3. Vi skal så bruge val-funktionen til konstruere udtryk e 2 og e 3 der har samme type, som beskrevet i afsnit Det kræver, at vi kender typerne for udtrykkene e 2 og e 3. Det kan gøres ved, at vi lader Extend returnere et transformeret udtryk sammen med dets type. Hvis e er et udtryk med σ, Γ e : t så antager vi, at funktionen typeof (e) σ Γ returnerer typen t. Funktionen typeof kan deferes ud fra reglerne for typerelationen på oplagt måde. 6.4 Transformerg af udtryk Vi er nu klar til at defere relationen Extend e. Relationen deferes for udtryk e, variabelomgivelser σ, funktionsomgivelser Γ og og udtryk e og typer t. Vi skriver (e, σ, Γ,, e, t ) Extend e som Extend e (e) σ Γ = (e, t ). Mengen er, at hvis Extend e (e) σ Γ = (e, t ), er e et udtryk, der er transformeret, så mellemresultaterne er gjort eksplicitte, og t er typen af e i omgivelserne σ og. Intuitivt gælder, at #1(e ) = e. Når en funktion f transformeres til ˆf (beskrives i afsnit 6.5) ændres dens returtype. Funktionsomgivelserne Γ skal deholde formation om funktionen f, mens skal deholde formation om ˆf. I defitionen af Extend e betegner v 1, v 2,... navne, der dføres af transformationen. Det antages, at de tages fra en følge af unikke navne, der ikke forekommer i det origale udtryk. 44

46 Extend-transformationen 6.4 Transformerg af udtryk Relationen Extend e deferes ved strukturel duktion over udtrykket e. I afsnit 6.7 og 6.8 vises nogle egenskaber ved relationen. Bemærk, at hvis Extend e (e) σ Γ = (e, t ), så er e et stykke syntaks, og ikke noget der skal fortolkes Variabeludtryk og konstantudtryk Tilfældene hvor e er en variabel eller en konstant deferes på følgende måde: Extend e (v) σ Γ = ({1 := v}, {1 : t}) hvor typeof (v)σγ = t Extend e (c) σ Γ = ({1 := c}, {1 : t}) hvor typeof (c)σγ = t Altså pakkes udtrykket blot d i en record med et element Operatoranvendelse For operatoranvendelse bruges følgende regel: Extend e ( (e1, e 2,..., e m ) ) σ Γ = ( let v 1 = e 1 let v 2 = e 2... let v m = e m hvor {1 := (#1(v 1 ), #1(v 2 ),..., #1(v m )), 2 := #2(v 1 ), 3 := #3(v 1 ),..., n 1 := #n 1 (v 1 ), n := #2(v 2 ), n := #3(v 2 ),..., n 1 + (n 2 1) := #n 2 (v 2 ), n 1 + (n 2 1) + 1 := #2(v 3 ), n 1 + (n 2 1) + 2 := #3(v 3 ),...,. n 1 + (n 2 1) + + (n m 1 1) + 1 := #2(v m ), n 1 + (n 2 1) + (n 3 1) := #n 3 (v 3 ), n 1 + (n 2 1) + + (n m 1 1) + 2 := #3(v m ),..., {1 : typeof ( (e 1, e 2,..., e m ) ) σγ, 2 : t 12, 3 : t 13,..., n 1 : t 1n1, n : t 22, n : t 23,..., n 1 + (n 2 1) : t 2n2,. n 1 + (n 2 1) + + (n m 1) := #n m (v m )}, n 1 + (n 2 1) + (n 3 1) + + (n m 1 1) + 1 : t m2,..., ) n 1 + (n 2 1) + (n 3 1) + + (n m 1) : t mnm } Extend e ( e1 ) σ Γ = (e 1, {1 : t 11, 2 : t t12,..., n 1 : t 1n1 } ) Extend e ( e2 ) σ Γ = (e 2, {1 : t 21, 2 : t t22,..., n 2 : t 2n2 } ). Extend e ( em ) σ Γ = (e m, {1 : t m1, 2 : t tm2,..., n m : t mnm } ) Notationen er lidt tung, hvilket først og fremmest skyldes, at den record, der returneres, bruger navne, der er fortløbende startende fra 1. Vi ser på et eksempel for at illustrere defitionen. Indtil videre har vi kun set, hvordan variabel- og konstantudtryk transformeres, så eksemplet bliver ret 45

47 Extend-transformationen 6.4 Transformerg af udtryk simpelt: Extend e ( (3, w, 5) ) σ Γ = ( let v 1 = {1 := 3} let v 2 = {1 := w} let v 3 = {1 := 5} {1 := (#1(v 1 ), #1(v 2 ), #1(v 3 ))}, ) {1 : typeof ( (3, w, 5)) σ Γ} Extend e bruges altså rekursivt på deludtrykkene. Invarianten #1(e ) = e bibeholdes, fordi vi har #1(v 1 ) = 3, #1(v 2 ) = w og #1(v 3 ) = 5, så i det transformerede udtryk anvendes operatoren på de samme værdier som i det origale udtryk Funktionskald Vi viser nu reglen for transformerg af funktionskald. Først gives et eksempel: Extend e ( f(3, w) ) σ Γ = ( let v 1 = {1 := 3} let v 2 = {1 := w} let v 3 = ˆf(#1(v 1 ), #1(v 2 )) {1 := #1(v 3 ), 2 := v 3 }, ) {1 : typeof (f(3, w)) σ Γ, 2 : t} Her er ˆf den transformerede udgave af f, og t er returtypen for ˆf (der fdes i ). Først bdes resultatet af at transformere parameterudtrykkene til nye variable. Dernæst kaldes den transformerede funktion ˆf. For ˆf gælder varianten #1( ˆf(e 1, e 2 )) = f(e 1, e 2 ). Som før bruges #1(v 1 ) og #1(v 2 ) som argumenter til funktionskaldet. Invarianten #1(e ) = e bibeholdes ved at placere #( ˆf(#1(v 1 ), #1(v 2 )) som det første element i recorden, der returneres. Som andet element returneres returværdien fra ˆf. 46

48 Extend-transformationen 6.4 Transformerg af udtryk Extend e ( f(e1, e 2,..., e m ) ) σ Γ = ( let v 1 = e 1 let v 2 = e 2... let v m = e m let v m+1 = ˆf(#1(v 1 ), #1(v 2 ),..., #1(v m )) hvor {1 := #1(v m+1 ), 2 := #2(v 1 ), 3 := #3(v 1 ),..., n 1 := #n 1 (v 1 ), n := #2(v 2 ), n := #3(v 2 ),..., n 1 + (n 2 1) := #n 2 (v 2 ), n 1 + (n 2 1) + 1 := #2(v 3 ), n 1 + (n 2 1) + 2 := #3(v 3 ),..., n 1 + (n 2 1) + (n 3 1) := #n 3 (v 3 ),. n 1 + (n 2 1) + + (n m 1 1) + 1 := #2(v m ), n 1 + (n 2 1) + + (n m 1 1) + 2 := #3(v m ),..., n 1 + (n 2 1) + + (n m 1) := #n m (v m ), n 1 + (n 2 1) + + (n m 1) + 1 := v m+1 }, {1 : typeof ( f(e 1, e 2,..., e m ) ) σγ, 2 : t 12, 3 : t 13,..., n 1 : t 1n1, n : t 22, n : t 23,..., n 1 + (n 2 1) : t 2n2,. n 1 + (n 2 1) + (n 3 1) + + (n m 1 1) + 1 : t m2,..., n 1 + (n 2 1) + (n 3 1) + + (n m 1) : t mnm, ) n 1 + (n 2 1) + (n 3 1) + + (n m 1) + 1 : t} Extend e ( e1 ) σ Γ = (e 1, {1 : t 11, 2 : t t12,..., n 1 : t 1n1 } ) Extend e ( e2 ) σ Γ = (e 2, {1 : t 21, 2 : t t22,..., n 2 : t 2n2 } ). Extend e ( em ) σ Γ = (e m, {1 : t m1, 2 : t tm2,..., n m : t mnm } ) ( ˆf) = (t, ) Let-udtryk Reglen for let-udtryk er som følger: Extend e ( let w = e1 e 2 ) σ Γ = ( let v 1 = e 1 let w = #1(v 1 ) let v 2 = e 2 hvor {1 := #1(v 2 ), 2 := #2(v 1 ), 3 := #3(v 1 ),..., n 1 := #n 1 (v 1 ), n := #2(v 2 ), n := #3(v 2 ),..., n 1 + (n 2 1) := #n 2 (v 2 )}, {1 : typeof ( let v = e 1 e 2 ) σγ, 2 : t 12, 3 : t 13,..., n 1 : t 1n1, ) n : t 22, n : t 23,..., n 1 + (n 2 1) : t 2n2 } Extend e ( e1 ) σ Γ = (e 1, {1 : t 11, 2 : t t12,..., n 1 : t 1n1 } ) Extend e ( e2 ) σ[w t11 ] Γ = (e 2, {1 : t 21, 2 : t t22,..., n 2 : t 2n2 } ) 47

49 Extend-transformationen 6.4 Transformerg af udtryk Et eksempel på brugen af denne regel (sammen med reglen for funktionskald) er: Extend e ( let w = 3 g(w) ) σ Γ = ( let v 1 = {1 := 3} let w = #1(v 1 ) let v 2 = ( let v 3 = {1 := 3} let v 4 = ˆf(#1(v 3 )) {1 := #1(v 4 ), 2 := v 4 } ) {1 := #1(v 2 ), 2 := #(v 2 )}, {1 : typeof (let w = 3 g(w)) σ Γ, 2 : t}, 2 : t ) Her er t returtypen for ˆf i. Altså bruges Extend e først på det første deludtryk af let-udtrykket. Dernæst bdes der en værdi til let-variablen w. Da #1(v 1 ) = 3 er det den samme værdi, der bdes til w i det transformerede udtryk som i det origale udtryk. Til sidst bruges Extend e på det andet deludtryk af let-udtrykket Fold-udtryk Reglen for fold-udtryk er: Extend e ( fold (a, b => e1 ) e 2 e 3 ) σ Γ = ( let v 2 = e 2 let v 3 = e 3 hvor {1 := fold (a, b => let v 1 = e 1 #1(v 1 )) #1(v 2 ) #1(v 3 ), 2 := #2(v 2 ), 3 := #3(v 2 ),..., n 2 := #n 2 (v 2 ), n := #2(v 3 ), n := #3(v 3 ),..., n 2 + (n 3 1) := #n 3 (v 3 )}, {1 : typeof ( fold (a, b => e 1 ) e 2 e 3 ) σγ, 2 : t 22, 3 : t 23,..., n 2 : t 2n2, ) n : t 32, n : t 33,..., n 2 + (n 3 1) : t 3n3 } Extend e ( e2 ) σ Γ = (e 2, {1 : t 21, 2 : t t22,..., n 2 : t 2n2 } Extend e ( e3 ) σ Γ = (e 3, {1 : mset(t 31 ), 2 : t t32,..., n 3 : t 3n3 } Extend e ( e1 ) σ[a t31, b t 21 ] Γ = (e 1, {1 : t 11, 2 : t t12,..., n 1 : t 1n1 } Som beskrevet i afsnit returneres mellemresultater fra fold-funktionen ikke. Et eksempel illustrerer: Extend e ( fold (a, b => f(a)) x y ) σ Γ = ( let v 1 = {1 := x} let v 2 = {1 := y} {1 := fold ( a, b => let v 3 = (let v 4 = {1 := a} let v 5 = ˆf(#1(v 4 )) #1(v 3 ) ) #1(v 1 ) #1(v 2 )}, ) {1 : typeof (fold (a, b => f(a)) x y) σ Γ} {1 := #1(v 5 ), 2 := v 5 }) 48

50 Extend-transformationen 6.4 Transformerg af udtryk Betgede udtryk Det sidste tilfælde er if - then- else-udtryk. Her benyttes funktionen val som beskrevet i afsnit til at konstruere standardværdier. Vi ser først på et eksempel, hvor der i then-grenen er et funktionskald, og hvor else-grenen ikke har funktionskald: Extend e ( if x then f(y) else 3 ) σ Γ = ( let v 1 = {1 := x} if #1(v 1 ) then let v 2 = ( let v 3 = {1 := y} let v 4 = ˆf(#1(v 3 )) {1 := #1(v 4 ), 2 := v 4 } ) {1 := #1(v 4 ), 2 := v 4 } else let v 5 = {1 := 3} {1 := #1(v 5 ), 2 := val(t)}, ) {1 : typeof (if x then f(y) else 3) σ Γ, 2 : t} hvor t er returtypen for ˆf i. Den record, der returneres i then-grenen, deholder den origale værdi af udtrykket og mellemresultatet ˆf(y). I else-grenen returneres også en record med to elementer, hvor den første deholder den origale værdi, og den anden deholder en standardværdi med samme type som returtypen for ˆf. På den måde konstrueres et typekorrekt udtryk e, der opfylder, at #1(e ) = e. Defitionen af Extend e for betgede udtryk er: Extend e ( if e1 then e 2 else e 3 ) σ Γ = ( let v 1 = e 1 hvor if #1(v 1 ) then let v 2 = e 2 {1 := #1(v 2 ), 2 := #2(v 1 ), 3 := #3(v 1 ),..., #n 1 (v 1 ), n := #2(v 2 ), n := #3(v 2 ),..., n 1 + (n 2 1) := #n 2 (v 2 ), n 1 + (n 2 1) + 1 := val ( t 32 ),..., n1 + (n 2 1) + (n 3 1) := val ( t 3n3 ) } else let v 3 = e 3 {1 := #1(v 3 ), 2 := #2(v 1 ), 3 := #3(v 1 ),..., #n 1 (v 1 ), n := val ( t 22 ), n1 + 2 := ( t 23 ),..., n1 + (n 2 1) := ( t 2n2 ), n 1 + (n 2 1) + 1 := #2(v 3 ),..., n 1 + (n 2 1) + (n 3 1) := #n 3 (v 3 )}, {1 : typeof ( if e 1 then e 2 else e 3 ) σγ, 2 : t 12, 3 : t 13,..., n 1 : t 1n1, n : t 22, n : t 23,..., n 1 + (n 2 1) : t 2n2, ) n 1 + (n 2 1) + 1 : t 32,..., n 1 + (n 2 1) + (n 3 1) : t 3n3 } Extend e ( e1 ) σ Γ = (e 1, {1 : t 11, 2 : t t12,..., n 1 : t 1n1 } ) Extend e ( e2 ) σ Γ = (e 2, {1 : t 21, 2 : t t22,..., n 2 : t 2n2 } ) Extend e ( e3 ) σ Γ = (e 3, {1 : t 31, 2 : t t32,..., n 3 : t 3n3 } ) 49

51 Extend-transformationen 6.5 Transformerg af funktioner 6.5 Transformerg af funktioner I dette afsnit deferer vi relationen Extend fun for funktionsdefitioner fundef og funktionsomgivelser Γ,,. Mengen er, at hvis Extend fun (fundef ) Γ = (fundef, ), så er fundef funktionsdefitionen fundef, hvor kroppen er transformeret med Extend e, og i er der en bdg for den transformerede funktion (returtypen er anderledes end for den origale funktion). Relationen deferes ved en enkelt regel: Extend fun ( fun f(v1 : t 1, v 2 : t 2,..., v n : t n ) = e ) Γ = (fundef, ) hvor Extend e (e)[v 1 t 1, v 2 t 2,... v n t n ]Γ = (e, t) fundef = fun ˆf(v 1 : t 1, v 2 : t 2,..., v n : t n ) = e = [ ˆf (t, [t 1, t 2,..., t n ])] ) 6.6 Transformerg af programmer Til sidst deferer vi relationen Extend for programmer p, p og funktionsomgivelser Γ og. Intentionen er, at hvis Extend(p) Γ = (p, ), så er p et program, hvor alle funktioner fra p er blevet transformerede med Extend fun, og er funktionsomgivelser for p. Relationen deferes på følgende måde: Extend ( ) ( ) fundef 1 fundef 2... fundef n Γ = fundef 1 fundef 2... fundef n, n hvor Extend fun ( fundef 1 ) Γ [ ] = (fundef 1, 1 ) Extend fun ( fundef 2 ) Γ 1 = (fundef 2, 2 ) Extend fun ( fundef n ) Γ n 1 = (fundef n, n ). 6.7 Egenskaber for Extend e Det første resultat om relationen Extend e er, at det er en funktion. Det er dholdet af lemma 6. Det andet resultat formaliserer tuitionen om, at hvis e er fremkommet ved at bruge Extend e på udtrykket e, så gælder #1(e ) = e. Lemma 6 Lad e være et udtryk, der er typekorrekt mht. typeomgivelserne σ og Γ. Hvis er funktionsomgivelser gælder: Der fdes e, t så Extend e (e) σ Γ = (e, t ) For alle e 1, e 2, t 1, t 2 gælder: Extend e (e) σ Γ = (e 1, t 1 ) Extend e (e) σ Γ = (e 2, t 2 ) e 1 = e 2 t 1 = t 2 Den første egenskab kan vises ved fuldstændig duktion over størrelsen af e, hvor der dskydes et lemma i fold-tilfældet, der vises ved duktion over antallet af elementer i den multimængde der foldes over. Vi viser ikke detaljerne i beviset her. Den anden egenskab kan vises ved fuldstændig duktion med relationen ægte delafledng på samme måde som i beviset for lemma 1, og derfor viser vi ikke beviset her. Før vi formulerer og viser hovedresultatet om Extend e dfører vi følgende defition: 50

52 Extend-transformationen 6.7 Egenskaber for Extend e Defition 1 Et udtryk e har unikke navne, hvis alle variable der bdes af let- eller fold-udtryk i e kun bdes én gang, og hvis v fv(e), så bdes v ikke af let- eller fold-udtryk i e. En funktionsdefition fun f(v 1 : t 1, v 2 : t 2,..., v n : t n ) = e f e f har unikke navne. har unikke navne, hvis udtrykket Et program har unikke navne, hvis alle funktionsdefitioner har unikke navne. Lemma 7 Lad p og p være programmer. Lad e være et udtryk med fv(e) = {w 1,... w q } (q 0). Lad σ : Var Ty være variabelomgivelser med σ(w i ) = t i for i = 1,..., q. Lad Γ og være funktionsomgivelser for henholdsvis p og p. Antag at e er typekorrekt mht. σ og Γ. Hvis der gælder: og ( fun f(v 1 : t 1, v 2 : t 2,..., v k : t k) = e f ) p. ( fun ˆf(v 1 : t 1, v 2 : t 2,..., v k : t k) = e ˆf ) p ( c1,..., c k.e f [c 1 /v 1,, c k /v k ] p c m, c 2,..., c m.e ˆf [c 1 /v 1,, c k /v k ] p {1 := c, 2 := c 2,..., m := c m } ) så har vi: Extend e (e) σ Γ = (e, t) c 1,... c q, c. e[c 1 /w 1,, c q /w q ] p c m, c 2,... c m.e [c 1 /w 1,, c q /w q ] p {1 := c, 2 := c 2,..., m := c m } σ, e : t m, t 1,..., t m.t = {1 : t 1,..., m : t m } e har unikke navne, hvis e har det Bevis: Lad p og p være givne. Antag ( fun f(v 1 : t 1, v 2 : t 2,..., v k : t k) = e f ) p. ( fun ˆf(v 1 : t 1, v 2 : t 2,..., v k : t k) = e ˆf ) p ( θdata.e f [θ data ] p c m, c 2,..., c m.e ˆf [θ data ] p {1 := c, 2 := c 2,..., m := c m } ) hvor θ data = [v 1 c 1,..., v k c k ]. For udtryk e deferes egenskaben P : P (e) σ, e, t.fv(e) dom(σ) Extend e (e) σ Γ = (e, t) t = {1 : t 1,..., m : t m } ( θdata, c.e[θ data ] p c m, c 2,..., c m.e [θ data ] p {1 := c, 2 := c 2,..., m := t m } ) hvor θ data = [w 1 c 1,..., w q c q ] hvis fv(e) = {w 1,..., w q }. Vi skal vise P (e) for vilkårligt e. Det viser den første påstand i lemmaet. Af pladshensyn viser vi ikke beviserne for de to sidste påstande i detaljer. Vi viser P (e) for alle e ved fuldstændig duktion over størrelsen af udtryk på Exp. Lad et typekorrekt e være givet. Som duktionsantagelser bruger vi: e. e < e P (e ) (6.1) 51

53 Extend-transformationen 6.7 Egenskaber for Extend e Ifølge duktionsprcippet er det nok at vise P (e) for det givne e. Lad σ være givet med fv(e) = {w 1,..., w q } dom(σ), og antag Extend e (e) σ Γ = (e, t) hvor t = {1 : t 1,..., m : t m }. Lad θ data = [w 1 c 1,..., w q c q ] være givet og antag e[θ data ] p c. Vi skal vise m, c 2,..., c m.e [θ data ] p {1 := c, 2 := c 2,..., m := c m } (6.2) Vi deler op i tilfælde efter strukturen af e. e = v Der må fdes et i {1,... q} så v = w i. Vi har pr. antagelse v[θ data ] p c, så vi må have c = c i. Vi har e = {1 := v}, så vi kan konstruere altså gælder (6.2). v[θ data ] p c i {1 := v}[θ data ] p {1 := c i } e = c Vi har e = {1 := c} så vi kan konstruere c p c {1 := c} p {1 := c} så (6.2) gælder da c = c. (e 1,..., e m ) e er som angivet i defitionen på side 45. Pr. antagelse har vi, at der fdes c 1,..., c m med e i [θ data ] p c i for i = 1,..., m og (c 1,..., c m ) = c. Da e i < e får vi fra (6.1) at P (e i ) gælder. Desuden har vi fv(e i ) fv(e) dom(σ). Antag for i = 1,..., m at Extend e (e i ) σ Γ = (e i, {1 : t i1, 2 : t i2,..., n i : t i }). Fra P (e i ) får vi så, at der for i = 1,..., m fdes n i, c i2, c i3,..., c i med e i [θ data] p {1 := c i, 2 := c i2, 3 := c i3,..., n i := c i }. Vi dfører betegnelsen c i = {1 := c i, 2 := c i2, 3 := c i3,..., n i := c i } for i = 1,..., m. Lad nu ē={1 := (#1(v 1 ),..., #1(v m )), 2 := #2(v 1 ),..., n 1 := #n 1 (v 1 ), n := #2(v 2 ),..., n 1 + (n 2 1) := #n 2 (v 2 ),..., n 1 + (n 2 1) + + (n m 1 1) + 1 := #2(v m ),..., n 1 + (n 2 1) + (n m 1) := #n m (v m )} Vi har så e = ( let v 1 = e 1 let v 2 = e 2 let v m = e m ē ). Navnene v 1,..., v m er taget fra en følge af unikke navne, hvor hvert navn ikke optræder i de origale udtryk. Det betyder, at gen af dem optræder i e i for i = 1,..., m, og at de er parvist forskellige fra w 1,..., w q. Derfor har vi: og e 2[θ data ][ c 1 /v 1 ] = e 2[θ data ] e 3[θ data ][ c 1 /v 1 ][ c 2 /v 2 ] = e 3[θ data ] (6.3).. e m[θ data ][ c 1 /v 1 ] [ c m 1 /v m 1 ] = e m[θ data ] ( let v1 = e 1 let v 2 = e 2 let v m = e m ē ) [θ data ] = let v 1 = e 1[θ data ] let v 2 = e 2[θ data ] let v m = e m[θ data ] ē[θ data ] 52

54 Extend-transformationen 6.7 Egenskaber for Extend e Hvis vi kan konstruere et bevis for (ē[ c 1 /v 1,, c m /v m ] ) [θ data ] p Så kan vi ved hjælp af (6.3) konstruere c e m[θ data ][ c 1 /v 1,, c m 1 /v m 1 ] p c m ē[θ data ][ c 1 /v 1,, c m /v m ] p c ( let vm = e m ē ) [θ data ][ c 1 /v 1,,.vbb m 1 /v m 1 ] p c e 2[θ data ][ c 1 /v 1 ] p c 2. ( e 1[θ data ] p c 1 let v2 = e 2 let v m = e m ē ) [θ data ][ c 1 /v 1 ] p c ( let v1 = e 1 let v 2 = e 2 let v m = e m ē ) [θ data ] p c For i = 1,..., m har vi: #1( c i )[θ data ] p #2( c i )[θ data ] p #3( c i )[θ data ] p c i c i2 c i3. #n i ( c i )[θ data ] p c i Derfor gælder ē[ c 1 /v 1,, c m /v m ] p {1 := c, 2 := c 12,..., n 1 := c 1n1, n := c 22,..., n 1 + (n 2 1) := c 2n2,..., n 1 + (n 2 1) + + (n m 1 1) + 1 := c m1,..., n 1 + (n 2 1) + (n m 1) := c mnm } Altså gælder (6.2). e = f(e 1, e 2,..., e k ) I dette tilfælde kan vi vise (6.2) på samme måde som i tilfældet for operatoranvendelse, dog får vi brug for antagelsen om p og p, der giver, at der fdes m, c 2,..., c m så e ˆf [c 1 /a 1,, c k /a k ] p {1 := c, 2 := c 2,..., m := c m } Hvor e ˆf er kroppen af funktionen ˆf i p, og a 1,..., a k er de formelle parametre for f. e = if e 1 then e 2 else e 3 Der er to tilfælde: e 1 [θ data ] p true og e 1 [θ data ] p false. I begge tilfælde kan vi bruge duktionsantagelsen for e 1, e 2 og e 3 og vise (6.2) på samme måde som i tilfældet for operatoranvendelse. e = let v = e 1 e 2 Da e 1 < e kan vi bruge til at konkludere, at der fdes m, c 2,..., c m så e 1[θ data ] p {1 := c 1, 2 := c 2,..., m := c m } hvor e 1 er fremkommet ved at bruge Extend e på e 1, og hvor e 1 [θ data ] p c 1. Da e 2 [c 1 /v] = e 2 og fv(e 2 [c 1 /v]) (fv(e)) får vi fra duktionsantagelsen, at der fdes n, c 2,..., c n så e 2[c 1 /v][θ data ] p {1 := c, 2 := c 2,..., n := c n}, hvor e 2 er fremkommet ved at bruge Extend e på e 2, og hvor e 2 [c 1 /v][θ data ] p c. Vi kan kombere disse to fakta som før og konkludere, at (6.2) gælder. e = fold (a, b => e 1 ) e 2 e 3 Vi bruger igen duktionsantagelsen for e 1, e 2. Sammen med et dskudt lemma (hvor e 1 er fremkommet ved brug af Extend på e 1 som angivet i defitionen på side 48) kan vi konstruere en afledng, der viser, at (6.2) gælder. Lemmaet kan vises ved duktion efter n: 53

55 Extend-transformationen 6.8 Egenskab for Extend Lemma 8 c, c 1,..., c n. ( fold (a, b => e 1 ) c, {c 1,..., c n } ) [θ data ] p fold c c 2,..., c m. ( fold (a, b => let v1 = e 1 #1(v 1 )) c, {c 1,..., c n } ) [θ data ] p fold {1 := c, 2 := c 2,..., m := c m} Vi viser ikke detaljerne i beviset for det dskudte lemma, da det er de samme teknikker som tidligere i beviset, der anvendes. Beviset for lemma 7 er hermed afsluttet. 6.8 Egenskab for Extend Som det sidste i dette kapitel viser vi en egenskab ved relationen Extend. Vi viser, at i et program, der er blevet transformeret med Extend, returnerer et kald af en funktion ˆf en record, hvis første element har samme værdi, som man ville få ved at kalde den oprdelige funktion f. Lemma 10 præciserer dette. Først formuleres et par hjælperesultater, som vi får brug for i beviset. Det første hjælperesultat siger, at hvis et udtryk e evaluerer til en konstant c i et program p, så evaluerer e stadig til c, hvis vi tilføjer en ny funktionsdefition til programmet p. Det andet hjælperesultat siger, at hvis udtrykket e evaluerer til c uden at bruge funktionen f i p, så kan vi fjerne f fra programmet, uden at ændre på det faktum, at e evaluerer til c. Vi nøjes med at formulere hjælperesultaterne uden beviser. Lemma 9 Lad p og p være typekorrekte programmer, og lad e være et udtryk, der er typekorrekt mht. p. Der gælder så: e p c e p c hvis p er p, hvor der er tilføjet en funktionsdefition e p c e p c hvis p er p, hvor der er fjernet funktionsdefitionen af en funktion f, som ikke bliver kaldt fra e. Lemma 10 Lad p n = fundef 1 fundef 2... fundef n være et program med unikke navne, og lad Γ være funktionsomgivelser for p n. Hvis Extend(p n ) Γ = (p n, ) gælder: ( fun f(v 1 : t 1, v 2 : t 2,..., v k : t k ) = e f ) pn. p n har unikke navne c, c 1,..., c k. f(c 1,..., c k ) pn c m, c 2,... c m. ˆf(c 1,..., c k ) p n {1 := c, 2 := c2,..., m := c m } er funktionsomgivelser for p n Bevis: Lad p n og Γ være givne. Lemmaet bevises ved duktion over antallet af funktionsdefitioner i p n. I basistilfældet har vi n = 1. Så vi har Så må vi have p 1 = fun f(v 1 : t 1, v 2 : t 2,..., v k : t k ) = e f Γ = [f (t f, t 1,..., t k )] p 1= fun ˆf(v 1 : t 1, v 2 : t 2,..., v k : t k ) = e ˆf = [ ˆf (t ˆf, t 1,..., t k )] hvor Extend e (e f ) [v 1 t 1,..., v k t k ] Γ [ ] = (e ˆf, t ˆf ). Fra lemma 7 får vi, at [v 1 t 1,..., v k t k ], Γ e ˆf : t ˆf, så er funktionsomgivelser for p 1. Lemma 7 giver også, at e ˆf har unikke navne, så p 1 har unikke navne. 54

56 Extend-transformationen 6.8 Egenskab for Extend Antag c, c 1,..., c k givne med f(c 1,..., c k ) p1 c. Vi har så e f [c 1 /v 1,, c k /v k ] p1 c. Udtrykket e f kan ikke deholde funktionskald, da den eneste funktion i p 1 er f, og der ikke tillades rekursion. Derfor har vi e f [c 1 /v 1,, c k /v k ] [ ] c. Fra lemma 7 får vi så, at der fdes m, c 2,..., c m så e ˆf [c 1 /v 1,, c k /v k ] [ ] {1 := c, 2 := c 2,..., m := c m } Fra lemma 9 får vi så e ˆf [c 1 /v 1,, c k /v k ] p 1 {1 := c, 2 := c2,..., m := c m } Altså gælder ˆf(c 1,..., c k ) p 1 {1 := c, 2 := c2,..., m := c m } som ønsket, så lemmaets påstand gælder i basistilfældet. Lad nu et n 0 2 være givet, og antag, at lemmaets påstand gælder for alle Γ og og alle programmer med n 0 funktionsdefitioner. Lad p n0+1 være et program med n 0 +1 funktionsdefitioner, og lad Γ være funktionsomgivelser for p n0+1, og antag at p n0+1 har unikke navne. Vi kan antage, at p n0+1 har formen: fun f 1 (v 1,1 : t 1,1, v 1,2 : t 1,2,..., v 1,k1 : t 1,k1 ) = e f1 fun f 2 (v 2,1 : t 2,1, v 2,2 : t 2,2,..., v 2,k2 : t 2,k2 ) = e f2. fun f n0+1(v n0+1,1 : t n0+1,1, v n0+1,2 : t n0+1,2,..., v n0+1,k n0 +1 : t n0+1,k n0 +1) = e fn0 +1 Lad fun f(v 1 : t 1, v 2 : t 2,..., v k : t k ) = e f være en funktionsdefition fra p n0+1, og lad c, c 1,..., c k være givne med f(c 1,..., c k ) pn Vi skal vise m, c 2,... c m. ˆf(c 1,..., c k ) p n 0+1 {1 := c, 2 := c2,..., m := c m } (6.4) hvor Extend(p n0+1)γ = (p n 0+1, ), og at er funktionsomgivelser for p n 0+1, samt at p n 0+1 har unikke navne. Vi kan antage, at f = f n0+1. Lad p n0 være programmet, der fås ved at fjerne funktionsdefitionen for f fra p n0+1. Vi har så Extend(p n0 ) Γ = (p n 0, ) Extend fun (fundef f ) Γ = (fundef ˆf, ) hvor fundef f og fundef ˆf er funktionsdefitionerne for henholdsvis f og ˆf. Fra duktionsantagelsen får vi, at er funktionsomgivelser for p n 0, og fra lemma 7 fås at [v 1 t 1,..., v k t k ], e ˆf : t ˆf, så = [ ˆf (t ˆf, t 1,..., t k )] er funktionsomgivelser for p n 0+1. Induktionsantagelsen sammen med lemma 7 giver også, at p n 0+1 har unikke navne. Da der ikke tillades rekursion, deholder e fn0 +1 ikke kald af f n 0+1, så e fn0 +1 pn 0 c. Fra lemma 7 får vi så, at der fdes m, c 2,..., c m så Fra lemma 9 får vi så hvilket viser (6.4) e ˆf [c 1 /v 1 c k /v k ] p n 0 {1 := c, 2 := c 2,..., m := c m } e ˆf [c 1 /v 1 c k /v k ] p n 0 +1 {1 := c, 2 := c 2,..., m := c m } 55

57 Kapitel 7 Clean-transformationen Hvis et program transformeres med Extend fra forrige kapitel, deholder funktionerne i det transformerede program en masse let-bdger, som ikke er nødvendige i den forstand, at det navn, der deferes, kun benyttes én gang. I dette kapitel præsenterer vi en transformation Clean, der rydder op i funktionskroppe ved at elimere let-bdger, og forsøger at evaluere recordudtryk statisk. Først vises nogle eksempler, der giver et dtryk af, hvordan transformationen Clean fungerer, og hvordan den kan deferes. Derefter deferes transformationen som en relation, og til sidst vises nogle egenskaber ved relationen, for eksempel at funktionen Clean er veldeferet og semantikbevarende. 7.1 Statisk evaluerg af recordudtryk Betragt udtrykket let v 1 = {1 := 3} let v 2 = {1 := 4} {1 := #1(v 1 ) + #1(v 2 )} der kunne være fremkommet ved at bruge transformationen Extend e fra kapitel 6. De to letbdger kan fjernes, og record-udtrykkene evalueres statisk, så udtrykket i stedet bliver det noget simplere: {1 := 3 + 4} Det første, vi bemærker, er, at hvis vi husker, at udtrykket {1 := 3} er bundet til v 1, kan vi erstatte forekomster af #1(v 1 ) med 3 i kroppen af det første let-udtryk. På denne måde omskrives det origale udtryk til: let v 1 = {1 := 3} let v 2 = {1 := 4} {1 := 3 + 4} De to let-bdger kan nu fjernes, så der kun er {1 := 3 + 4} tilbage. Teknikken går altså ud på at forsøge at reducere udtryk af formen #lab(e) og at udfolde let-bdger Eksemplet fra afsnit Kapitel 6 beskrev resultatet af at transformere et eksempelprogram p med Extend til ˆp (se side 43). Vi viser her, hvordan ˆp transformeres med Clean: 56

58 Clean-transformationen 7.1 Statisk evaluerg af recordudtryk fun ĝ(x : mset(t)) = {1 := fold (a, b => b + a) 0 x)} fun ˆf(x : mset(t)) = let Z 9 = ĝ(x) let v = #1(Z 9 ) {1 := x with v, 2 := Z 9 } Hvis man sammenligner med det oprdelige program p, bemærker man, at strukturen kan genfdes i ovenstående program, og hvis man sammenligner med ˆp, bemærker man, at programmet er blevet væsentlig mere læsbart, hvilket letter den videre behandlg Udfoldng af let-udtryk Udfoldng af let-udtryk kan give anledng til, at beregnger gentages som beskrevet i kapitel 5 af [33]. Vi kan approksimere, hvor mange gange en let-bunden variabel bliver refereret, og bruge denne formation til kun at udfolde let-udtryk, hvor den bundne variabel bliver refereret højst én gang. På denne måde kan vi konservativt sikre os mod, at det transformerede udtryk gentager beregnger i forhold til det origale udtryk Relationen elimreclabs Vi deferer nu relationen elimreclabs for udtryk e, e og partielle afbildnger I : Var Exp, skrevet elimreclabs(e) I = e. Intentionen er, at afbildngen I udvides ved let-udtryk, og udtryk af formen #lab(v) erstattes med e i, hvis I deholder bdgen v {lab 1 := e 1,..., lab n := e n } og lab = lab i. Afsnit 7.5 viser, at e elimreclabs(e) I er en funktion. Den deferes på følgende måde: elimreclabs(v)i = v elimreclabs(c)i = c elimreclabs ( #lab(v) ) e i hvis I(v) = {l 1 := e 1, l 2 := e 2,..., l n := e n } I = og lab = l i for et i {1, 2,..., n} #lab(v) ellers elimreclabs ( #lab(e) ) I = #lab(elimreclabs(e)i) hvis e ikke er en variabel elimreclabs(if e 1 then e 2 else e 3 )I = if elimreclabs(e 1 )I then elimreclabs(e 2 )I else elimreclabs(e 3 )I { e elimreclabs(let v = e 1 e 2 )I = 2 [e 1/v] hvis cnt(v, e 2) < 2 let v = e 1 e 2 ellers hvor v er en Extend-variabel og elimreclabs(e 1 )I = e 1 elimreclabs(e 2 )I[v e 1] = e 2 elimreclabs(let v = e 1 e 2 )I = let v = elimreclabs(e 1 )I elimreclabs(e 2 )I hvor v ikke er en Extend-variabel elimreclabs(fold (a, b => e 1 ) e 2 e 3 )I = fold (a, b => elimreclabs(e 1 )I) elimreclabs(e 2 )I elimreclabs(e 3 )I elimreclabs(f(e 1, e 2,..., e n ))I = f(elimreclabs(e 1 )I,..., elimreclabs(e n )I) elimreclabs( (e 1, e 2,..., e n ))I = (elimreclabs(e 1 )I,..., elimreclabs(e n )I) 57

59 Clean-transformationen 7.2 Indlejrede let-udtryk Variable og konstanter lades uberørt af elimreclabs. I tilfældet for #lab(v) forsøges afbildngen I brugt som tidligere beskrevet. For let-udtryk, der er dført af Extend-transformationen fra kapitel 6, transformeres de to deludtryk rekursivt, og hvis variablen v forekommer højst 1 gang i kroppen af det reducerede let-udtryk, så udfoldes let-bdgen. Under transformergen af kroppen af let-udtrykket udvides afbildngen I med en bdg for den bundne variabel. Funktionen cnt bruges til at tælle forekomster af en variabel i et udtryk. For let-udtryk, der ikke er dført af Extend-transformationen, beholdes let-bdgen, men hvor de to deludtryk transformeres. På denne måde beholdes noget af strukturen fra det origale udtryk. I de resterende tilfælde transformeres deludtrykkene på den oplagte måde Funktionen cnt Funktionen cnt(v, e) deferes ved strukturel duktion over e: { 1 hvis v = v1 cnt(v, v 1 ) = 0 ellers cnt(v, c) = 0 cnt(v, if e 1 then e 2 else e 3 ) = cnt(v, e 1 ) + max(cnt(v, e 2 ), cnt(v, e 3 )) { cnt(v, e1 ) hvis v = w cnt(v, let w = e 1 e 2 ) = cnt(v, e 1 ) + cnt(v, e 2 ) ellers { cnt(v, e2 ) + cnt(v, e cnt(v, fold (a, b => e 1 ) e 2 e 3 ) = 3 ) hvis v = a v = b cnt(v, e 1 ) + cnt(v, e 2 ) + cnt(v, e 3 ) ellers cnt(v, f(e 1, e 2,..., e n )) = cnt(v, e 1 ) + cnt(v, e 2 ) + + cnt(v, e n ) cnt(v, (e 1, e 2,..., e n )) = cnt(v, e 1 ) + cnt(v, e 2 ) + + cnt(v, e n ) 7.2 Indlejrede let-udtryk Vi viser først et eksempel på et udtryk, hvor transformationen elimreclabs ikke er god nok, dvs. ikke fjerner så mange let-udtryk, som det kunne ønskes. Dernæst præsenterer vi en transformerg, der reparerer dette problem. Det følgende udtryk er et typisk eksempel på resultatet af at bruge Extend e : ( ē = let v 0 = let v 1 = ( let v 2 = f(a) {1 := #1(v 2 ), 2 := v 2 } ) ) {1 := #1(v 2 ) + b, 2 := v 2 } #1(v 0 ) Ved at bruge elimreclabs(ē)[ ] fås følgende udtryk (vi antager, at v 0, v 1 og v 2 er dført af Extend e ): ( #1 let v 1 = ( let v 2 = f(a) {1 := #1(v 2 ), 2 := v 2 } ) ) {1 := #1(v 2 ) + b, 2 := v 2 } Værdien af hele udtrykket er den samme som for udtrykket e = #1(f(a)) + b, så det ville være bedre, hvis det transformerede udtryk var e. Ved at bruge følgende omskrivng: let v = ( let v = e 1 e ) 2 e2 ) let v = e 1 ( let v = e ) 2 e 2 der er gyldig, hvis v ikke forekommer i e 2, bliver udtrykket ē omskrevet til: ē = let v 2 = f(a) (let v 1 = {1 := #1(v 2 ), 2 := v 2 } ( let v 0 = {1 := #1(v 2 ) + b, 2 := v 2 } #1(v 0 ) )) 58

60 Clean-transformationen 7.3 Transformationen Clean og elimreclabs(ē ) [ ] = #1(f(a)) + b som ønsket. Vi deferer relationen normlets, der udfører den nævnte omskrivng af dlejrede let-udtryk. Relationen deferes for e og e, skrevet normlets(e) = e på følgende måde (afsnit 7.4 viser, at normlets er en funktion): normlets(v) = v normlets(c) = c normlets(if e 1 then e 2 else e 3 ) = if normlets(e 1 ) then normlets(e 2 ) else normlets(e 3 ) normlets(let v = (let v = e 1 e 2) e 2 ) = normlets ( let v = e 1 let v = e 2 e 2 ) normlets(let v = e 1 e 2 ) = let v = normlets(e 1 ) normlets(e 2 ) hvor e 1 let v = e 1 e 2 normlets(fold (a, b => e 1 ) e 2 e 3 ) = fold (a, b => normlets(e 1 )) normlets(e 2 ) normlets(e 3 ) normlets(f(e 1, e 2,..., e n )) = f(normlets(e 1 ), normlets(e 2 ),..., normlets(e n )) normlets( (e 1, e 2,..., e n )) = (normlets(e 1 ), normlets(e 2 ),..., normlets(e n )) Afsnit 7.4 viser, at transformationen normlets er semantikbevarende, hvis den bruges på udtryk med unikke navne. 7.3 Transformationen Clean Relationen Clean fun deferes for funktionsdefitioner fundef og fundef, skrevet Clean fun (fundef ) = fundef på følgende måde: Clean fun (fun f(v 1 : t 1, v 2 : t 2,..., v n : t n ) = e) = fun f(v 1 : t 1, v 2 : t 2,..., v n : t n ) = elimreclabs ( normlets(e) ) [ ] Kroppen af funktionen transformeres altså først med normlets, så dlejrede let-udtryk omskrives, og dernæst med elimreclabs. Et program transformeres med Clean ved at bruge Clean fun på hver af funktionsdefitionerne: Clean(fundef 1 fundef 2... fundef n ) = Clean fun (fundef 1 ) Clean fun (fundef 2 )... Clean fun (fundef n ) 7.4 Egenskaber for normlets Vi viser to resultater om relationen normlets fra afsnit 7.2. Det første siger, at relationen er en funktion, altså at relationen er total og determistisk. Intuitivt gælder det, fordi hvis normlets(e) gør brug af normlets(e ), så er e mdre end e, eller antallet af dlejrede let-udtryk i e er mdre end i e. Det andet resultat siger, at hvis udtrykket e har unikke navne, så har normlets(e) samme betydng som e. 59

61 Clean-transformationen 7.4 Egenskaber for normlets normlets er total og determistisk Vi deferer funktionen levels : Exp N ved strukturel duktion over e. Mengen er, at hvis levels(e) = n, så er n det maksimale antal dlejrede let-udtryk i e: levels(v) = 0 levels(c) = 0 levels(if e 1 then e 2 else e 3 ) = max ( levels(e 1 ), levels(e 2 ), levels(e 3 ) ) { 1 + levels(e1 ) hvis e levels(let v = e 1 e 2 ) = 1 = let v = e 1 e 2 0 ellers levels(fold (a, b => e 1 ) e 2 e 3 ) = max ( levels(e 1 ), levels(e 2 ), levels(e 3 ) ) levels(f(e 1, e 2,..., e n )) = max i=1,...,n (levels(e i )) levels( (e 1, e 2,..., e n )) = max i=1,...,n (levels(e i )) For e 1, e 2 deferes relationen ved e 1 e 2 ( e 1, levels(e 1 )) < lex ( e 2, levels(e 2 )), hvor < lex angiver leksiografisk ordng. Der kan ikke konstrueres en uendelig kæde e i e 1 e 0, så relationen er well-founded. Det tilhørende duktionsprcip er: ( e e.p (e) e.( e.p (e ) ) ) P (e) hvor P (e) er en egenskab for et udtryk. Vi er nu klar til at vise følgende lemma: Lemma 11 Lad e være et udtryk. Relationen normlets er en funktions, dvs: Der fdes e Exp så normlets(e) = e (7.1) normlets(e) = e 1 normlets(e) = e 2 e 1 = e 2 for alle e 1, e 2 (7.2) Bevis: Lemmaet bevises ved fuldstændig duktion over Exp med relationen som deferet tidligere. Lad e være givet. Vi deler op i tilfælde efter strukturen af e. e = c e = v Vi har normlets(c) = c, så (7.1) og (7.2) gælder. Vi har normlets(v) = v, så (7.1) og (7.2) gælder. e = if e 1 then e 2 else e 3 For i = 1, 2, 3 gælder e i e, så fra duktionsantagelsen får vi, at der fdes e i med normlets(e i) = e i, altså gælder (7.1). Antag normlets(e) = ē 1 og normlets(e) = ē 2. Så fdes der ē 1, ē 1, ē 1 så ē 1 = if ē 1 then ē 1 else ē og ē 2, ē 2, ē 2 så ē 2 = if ē 2 then ē 2 else ē 2. Fra duktionsantagelsen får vi, at ē 1 = ē 2, ē 1 = ē 2 og ē 1 = ē 2, så ē 1 = ē 2 som ønsket. e = let v = (let v = e 1 e 2) e 2 Lad ē = let v = e 1 (let v = e 2 e 2 ), så har vi normlets(e) = ē. Vi har e = e 1 + e 2 + e 2 = 1 + e e 2 + e 2 = ē desuden er { levels(e) = 1 + levels(let v = e 1 e 1 + levels(e 2) = ) hvis e 1 = let w = e 1 e 1 0 ellers { 1 + levels(e levels(ē) = 1 ) hvis e 1 = let w = e 1 e 1 0 ellers 1, Vi har altså levels(ē)<levels(e), så ē e. Derfor følger (7.1) og (7.2) direkte fra duktionsantagelsen. 60

62 Clean-transformationen 7.4 Egenskaber for normlets e = let v = e 1 e 2 hvor e 1 ikke er et let-udtryk. Vi har e 1 e og e 2 e, så (7.1) og (7.2) følger fra duktionsantagelsen som vist i tilfældet for if - then- else-udtryk. I de resterende tilfælde bruger vi duktionsantagelsen på deludtrykkene og konkluderer (7.1) og (7.2) som vist tidligere normlets er semantikbevarende Vi kan nu vise, at transformationen normlets er semantikbevarende for udtryk med unikke navne. Lemma 12 Lad p være et typekorrekt program, og lad e være et udtryk, der er typekorrekt mht. p, og med fv(e) {v 1,..., v n }. Hvis e har unikke navne, så gælder c, c 1,... c n.e[c 1 /v 1,, c n /v n ] p c (normlets(e))[c 1 /v 1,, c n /v n ] p c normlets(e) har unikke navne fv(normlets(e)) {v 1,..., v n } Bevis: Transformationen normlets dfører ikke nye navne, så normlets(e) har unikke navne, hvis e har det. Vi giver detaljerne i beviset for den første påstand i lemmaet. For udtryk e deferes egenskaben P (e): P (e) e har unikke navne fv(e) {v 1,..., v n } ( ) θ data, c.e[θ data ] p c (normlets(e))[θ data ] p c hvor θ data = [v 1 c 1,..., v n c n ]. Vi viser P (e) for alle e ved fuldstændig duktion med relationen som deferet tidligere. Lad e være et udtryk med unikke navne, og fv(e) {v 1,... v n }. Lad desuden c 1,..., c n være givne og antag e[θ data ] p c hvor θ data = [v 1 c 1,..., v n c n ]. Vi deler op i tilfælde efter strukturen af e. e = c Vi har normlets(c) = c, så P (e) gælder trivielt. Tilfældet for variable er tilsvarende. e = if e 1 then e 2 else e 3 Vi har normlets(e) = if normlets(e 1 ) then normlets(e 2 ) else normlets(e 3 ) Fra antagelsen e[θ data ] p c ser vi, at der er to muligheder: e 1 [θ data ] p true eller e 1 [θ data ] p false. Antag e 1 [θ data ] p true. Vi har så pr. antagelse, at e 2 [θ data ] p c. Da e 1 e og e 2 e har vi P (e 1 ) og P (e 2 ). Da e 1 og e 2 har unikke navne og fv(e i ) fv(e) for i = 1, 2 har vi altså (normlets(e 1 ))[θ data ] p true og (normlets(e 2 ))[θ data ] p c. Vi har altså (normlets(e))[θ data ] p c som ønsket. e = let v = (let v = e 1 e 2) e 2 Lad ē = let v = e 1 (let v = e 2 e 2 ). Med argumenter som i beviset for lemma 11 har vi ē e. Da ē har unikke navne, og fv(ē) = fv(e), får vi fra duktionsantagelsen, at Afledngen af e[θ data ] p c må have formen: d 1 ē[θ data ] p c normlets(ē)[θ data ] p c (7.3) d 2 e 1[θ data ] p ((e 2[θ data ])[ c 1 /v ] p c 2 c 1 ( d 3 let v = e 1 e 2) [θdata ] p c 2 (e 2 [θ data ])[ c 2 /v] p c ( ) let v = (let v = e 1 e 2) e 2 [θdata ] p c 61

63 Clean-transformationen 7.4 Egenskaber for normlets hvor vi har udnyttet, at e har unikke navne, så v og v forekommer ikke i dom(θ data ). Da e har unikke navne, og v ikke er i scope i e 2, forekommer v ikke i e 2, altså gælder (e 2 [θ data ])[ c 1 /v ] = e 2 [θ data ]. Vi kan så konstruere: d 1 e 1[θ data ] p c 1 d 2 d 3 (e 2[θ data ])[ c 1 /v ] p c 2 (e 2 [θ data ])[ c 1 /v ][ c 2 /v] p c ( (let v = e 2 e 2 )[θ data ] ) [ c 1 /v ] p c ( let v = e 1 (let v = e 2 e 2 ) [θdata ] p c altså har vi ē[θ data ] p c, så fra (7.3) får vi (normlets(ē))[θ data ] p c som ønsket. e = fold (a, b => e 1 ) e 2 e 3 Fra antagelsen e[θ data ] p c får vi: e 3 [θ data ] p { c 1,..., c k } e 2 [θ data ] p c fold (a, b => e 1 [θ data ]) c { c 1,..., c k } p fold c Da e 3 e får vi fra duktionsantagelsen, at (normlets(e 3 ))[θ data ] p { c 1,..., c k }. Tilsvarende får vi da e 2 e, at (normlets(e 2 )[θ data ] p c. Vi mangler så at vise, at fold (a, b => (normlets(e 1 )[θ data ])) c { c 1,..., c k } p fold dskyder et lemma, som giver det ønskede. Lemma 13 For alle c, c, c 1,..., c k gælder fold (a, b => e 1 [θ data ])) c { c 1,..., c k } p fold c Det dskudte lemma vises ved duktion over k. fold (a, b => (normlets(e 1 )[θ data ])) c { c 1,..., c k } p fold c c. Vi I basistilfældet er k = 0. Antag fold (a, b => e 1 [θ data ])) c {} p fold c. Vi har så c = c, og dermed gælder også fold (a, b => (normlets(e 1 )[θ data ])) c {} p fold c. Lad nu et k 0 > 0 være givet, og antag at der for alle c, c, c 1,..., c k0 gælder: fold (a, b => e 1 [θ data ])) c { c 1,..., c k0 } p fold c (7.4) fold (a, b => (normlets(e 1 )[θ data ])) c { c 1,..., c k0 } p fold c Lad c, c, c 1,..., c k0+1 være givne med fold (a, b => e 1 [θ data ])) c { c 1,..., c k0 } p fold c. Fra defitionen af p fold-relationen får vi: fold (a, b => e 1 [θ data ])) c { c 1,..., c k0 } p fold c (e 1 [θ data ])[ c k0+1/a, c /b] p c (7.5) Fra (7.4) får vi så fold (a, b => (normlets(e 1 )[θ data ])) c { c 1,..., c k0 } p fold c. Vi har (e 1 [θ data ])[ c k0+1/a, c /b] = (e 1 [ c k0+1/a, c /b])[θ data ], og e 1 [ c k0+1/a, c /b] e, så da fv(e 1 [ c k0+1/a, c /b]) fv(e) får vi fra P (e 1 ) at (e 1 [ c k0+1/a, c /b])[θ data ] p c ( normlets(e 1 [ c k0+1/a, c /b])) ) [θ data ] p c Da a, b / {v 1,..., v n } får vi fra (7.5) at ( (e 1 [ c k0+1/a, c /b] ) ( [θ data ] p c. Altså gælder normlets(e1 [ c k0+1/a, c /b])) ) [θ data ] p c. Der gælder så (hvilket kan vises ved et seperat bevis) ( normlets(e 1 )[ c k0+1/a, c /b] ) [θ data ] p c. Vi kan nu konstruere fold (a, b => (normlets(e 1 )[θ data ])) c { c 1,..., c k0 } p fold c som ønsket. fold (a, b => (normlets(e 1 )[θ data ])) c { c 1,..., c k0+1} p fold c ( normlets(e1 )[θ data ] ) [ c k0+1/a, c /b] p c 62

64 Clean-transformationen 7.5 Egenskaber for elimreclabs De resterende tilfælde vises på tilsvarende måde ved at bruge duktionsantagelsen på deludtrykkene og kombere resultaterne som vist. 7.5 Egenskaber for elimreclabs Ligesom for normlets viser vi to egenskaber ved relationen elimreclabs: først vises, at e elimreclabs(e)i er en funktion, og dernæst vises, i hvilken forstand elimreclabs er semantikbevarende elimreclabs er total og determistisk Lemma 14 Lad e være et udtryk, og I : Var Exp en partiel afbildng. Så fdes der et e Exp, så elimreclabs(e) I = e, og for alle e 1, e 2 gælder e 1 = e 2 hvis elimreclabs(e) I = e 1 elimreclabs(e) I = e 2. Lemmaet kan bevises ved strukturel duktion over e, med duktionsantagelsen I.e e P (e ) hvor P er påstanden i lemmaet elimreclabs er semantikbevarende Lemma 15 Lad p være et typekorrekt program, og lad e være et udtryk med unikke navne, og fv(e) {w 1,..., w m }. Hvis I = [v 1 e 1,..., v n e n ] med v i fv(e) og n i=1 fv(e i) fv(e), så gælder: ( c 1,..., c m, c. e[θ data ] p c ( e[i] ) ) [θ data ] p c e[θ data ] p c (elimreclabs(e) I)[θ data ] p c hvor θ data = [w 1 c 1,..., w m c m ] elimreclabs(e) I har unikke navne Lemmaet kan bevises ved fuldstændig duktion over e. Som duktionsantagelse bruges e. e < e P (e ), hvor egenskaben P er deferet på følgende måde: ( P (e) I, e, θ data, e. e e ( e [θ data ] p c (e [I])[θ data ] p c )) I, θ data, c.e[θ data ] p c (elimreclabs(e)i)[θ data ] p c I tilfældet for fold vises implikationen ved duktion over k. c, c, c 1,..., c k.fold (a, b => e 1 [θ data ]) c { c 1,..., c k }) p fold c 7.6 Clean er semantikbevarende fold (a, b => (elimreclabs(e 1 )I)[θ data ]) c { c 1,..., c k }) Ved hjælp af resultaterne for normlets og elimreclabs kan vi nu bevise, at hvis et udtryk e evaluerer til en konstant c i programmet p, så evaluerer e også til c i programmet p, der er transformeret med Clean. Lemma 16 Lad p n være et typekorrekt program med unikke navne med n funktionsdefitioner, og lad e være et lukket udtryk, der er typekorrekt mht. p. Antag Γ er funktionsomgivelser for p. Så gælder: c.e p c e Clean(pn) c 63

65 Clean-transformationen 7.6 Clean er semantikbevarende Clean(p n ) har unikke navne Γ er funktionsomgivelser for Clean(p n ) Bevis: For udtryk e deferes egenskaben P (e): P (e) n N, c. e lukket ( e pn c e Clean(pn) ) Vi viser P (e) for alle udtryk ved fuldstændig duktion over størrelsen af udtryk e. Lad et lukket e være givet, og antag som duktionsantagelse: e. e < e P (e ) Lad p n være et program med n funktionsdefitioner, og antag e pn efter strukturen af e. c. Vi deler op i tilfælde e = (e 1, e 2,..., e k ) Fra antagelsen e pn c får vi, at der fdes c 1,... c k, så e i pn c i for i = 1,..., k, og (c 1,..., c k ) = c. Da e i < e får vi fra duktionsantagelsen at e i Clean(pn) c i for i = 1,..., k. Vi har så e = (e 1, e 2,..., e k ) Clean(pn) c som ønsket. e = f(e 1, e 2,..., e k ) Vi viser P (e) ved duktion over n. Vi har antaget e pn c. Derfor fdes c 1,... c k så e i pn c i for i = 1,..., k e f [c 1 /v 1,, c k /v k ] pn c hvor e f er kroppen af f. Fra duktionsantagelsen får vi e i Clean(pn) c i for i = 1,..., k. Vi mangler så at vise e f [c 1 /v 1,, c k /v k ] Clean(pn) c (7.6) hvilket bevises ved duktion over n, der er antallet af funktionsdefitioner i programmet. I basistilfældet har vi n = 1. Vi kan så antage, at programmet p 1 deholder den ene funktionsdefition: Så består Clean(p 1 ) af funktionsdefitionen: fun f(v 1 : t 1, v 2 : t 2,..., v k : t k ) = e f fun f(v 1 : t 1, v 2 : t 2,..., v k : t k ) = elimreclabs ( normlets(e f ) ) [ ] Vi har (7.6) hvis ( ) elimreclabs(normlets(e f ) [ ] [c 1 /v 1,, c k /v k ] p1 c (7.7) Fra lemma 12 og lemma 15 får vi, at (7.7) gælder. Lad nu et n 0 > 1 være givet, og antag, at det for alle programmer med n 0 funktioner f 1,..., f n0, hvis kroppe er e f1, e f2,..., e fn0 gælder i, c, c 1,..., c k. e fi [c 1 /v 1,, c k /v k ] pn 0 c efi [c 1 /v 1,, c k /v k ] Clean(pn 0 ) c (7.8) hvor v 1,..., v k er de formelle parametre til funktionen med funktionskrop e fi. 64

66 Clean-transformationen 7.6 Clean er semantikbevarende Lad p n0+1 være et program med n funktioner f 1,..., f n0+1. Vi kan antage, at f = f n0+1. Fra antagelsen e f [c 1 /v 1,, c k /v k ] pn 0 +1 c får vi fra lemma 12 og 15, at ( (normlets(ef ) ) [ ]) [c 1 /v 1,, c k /v k ] pn 0 +1 c Da rekursion ikke er tilladt, er der gen kald af f i e f og dermed heller ikke i elimreclabs ( normlets(e f ) ) [ ], så vi har ( (normlets(ef ) ) [ ]) [c 1 /v 1,, c k /v k ] pn 0 c Fra (7.8) får vi så, at ( (normlets(ef ) ) [ ]) [c 1 /v 1,, c k /v k ] Clean(pn 0 ) c og dermed (ifølge lemma 9 fra side 54): ( (normlets(ef ) ) [ ]) [c 1 /v 1,, c k /v k ] Clean(pn 0 +1) c som ønsket. De resterende tilfælde vises ved at bruge duktionsantagelsen på deludtrykkene. I tilfældet for fold-udtryk vises c.c 1,..., c k.fold (a, b => e 1 ) c {c 1,..., c k } pn fold c fold (a, b => e 1) c {c 1,..., c k } Clean(pn) fold c ved duktion over k. 65

67 Kapitel 8 Inkrementaliserg I dette kapitel ser vi på de sidste transformationer, der sammen med Extend og Clean fra de forrige kapitler giver mulighed for at krementalisere et program. Først vises, hvordan eksempelprogrammet fra afsnit kan krementaliseres ved at følge de fire punkter, der angives i afsnit Eksempel Det oprdelige eksempelprogram fra kapitel 6 er efter transformation med Extend og Clean blevet til følgende: fun ĝ(x : mset(t)) = {1 := fold (a, b => b + a) 0 x)} fun ˆf(x : mset(t)) = let Z 9 = ĝ(x) let v = #1(Z 9 ) {1 := x with v, 2 := Z 9 } Vi viser nu de overordnede tr, der udføres af krementalisergsmetoden ved krementaliserg af ovenstående program med hensyn til operationen [x] [y] = [x with y]. Der er fire tr, som beskrevet i afsnit Udfoldng Udtrykket ˆf(x) udfoldes til Cachen C bliver så {1 := x with (#1(ĝ(x))), 2 := ĝ(x)} C = [x with (#1(ĝ(x))) #1(r), ĝ(x) #2(r)] hvilket for eksempel betyder, at værdien ĝ(x) kan fås ved at bruge udtrykket #2(r), hvor r er den parameter, der bruges til at deholde cache-værdien. Simplificerg Udtrykket ˆf(x with y) udfoldes til let Z 9 = ĝ(x with y) let v = #1(Z 9 ) {1 := (w with y) with v, 2 := Z 9 } Funktionskald Det udfoldede udtryk deholder et funktionskald til ĝ, der derfor krementaliseres. Resultatet bliver en funktion ĝ (x, y, r), der opfylder, at hvis r = ĝ(x), så er ĝ (x, y, r) = ĝ(x with y). På kaldstedet deholder udtrykket #2(r) ifølge cachen kaldbetgelsen ĝ(x), så kaldet ĝ(x with y) kan udskiftes med ĝ (x, y, #2(r)). 66

68 Inkrementaliserg 8.2 Defition af opdatergsoperation Funktionsdefition Til sidst deferes funktionen ˆf : fun ˆf (x : mset(t), y : t, Z 18 : {1 : mset(t), 2 : {1 : t}}) = let Z 9 = ĝ (x, y, #2(Z 18 )) let v = #1(Z 9 ) {1 := (x with y) with v, 2 := Z 9 } der opfylder, at hvis r = ˆf(x), så er ˆf (x, y, r) = ˆf(x with y). Den krementelle version af programmet kommer til at se ud som følger: fun ĝ (x : mset(t), y : t, Z 19 : {1 : t}) = {1 := #1(Z 19 ) + y} fun ˆf (x : mset(t), y : t, Z 18 : {1 : mset(t), 2 : {1 : t}}) = let Z 9 = ĝ (x, y, #2(Z 18 )) let v = #1(Z 9 ) {1 := (x with y) with v, 2 := Z 9 } Bemærk at i ĝ er en foldngsoperation skiftet ud med en enkelt addition, hvilket repræsenterer en forbedrg i køretid fra O(n) til O(1), hvor n er antallet af elementer i x. I de følgende afsnit vises detaljerne i krementalisergstransformationen. 8.2 Defition af opdatergsoperation Vi begynder med en defition af, hvad der menes med en opdatergsoperation: Defition 2 (xs, ys, es) er en opdatergsoperation, hvis xs = [x 1 : t 1,..., x n : t n] hvor n 0 og x i Var, t i Ty for i = 1,..., n ys = [y 1 : t 1,..., y m : t m] hvor m 0 og y i Var, t i Ty for i = 1,..., m es = [e 1,..., e r ] hvor r r og e i Exp for i = 1,..., r Opdatergsoperationen er typekorrekt mht. et program p og en funktion f fra p, hvis f er deferet ved fun f(v 1 : t 1, v 2 : t 2,..., v n : t n ) = e f i p x 1,..., x n, y 1,..., y m er parvis forskellige n = r t i = t i for i = 1,..., n [x 1 t 1,..., x n t n, y 1 t 1,..., y m t m], Γ e i : t i for i = 1,..., n, hvor Γ er funktionsomgivelser for p 8.3 Transformationen unfoldlet For at gøre det lettere at undersøge, om et udtryk fdes i cachen, udfoldes let-bdger i de udtryk, der dsættes i cachen. Relationen unfoldlet udfører denne udfoldng. Den deferes for udtryk e og e, og vi skriver unfoldlet(e) = e, hvis e og e er relaterede ved unfoldlet. 67

69 Inkrementaliserg 8.4 Relationen simp unfoldlet(v) = v unfoldlet(c) = c unfoldlet(if e 1 then e 2 else e 3 ) = if unfoldlet(e 1 ) then unfoldlet(e 2 ) else unfoldlet(e 3 ) unfoldlet(let v = e 1 e 2 ) = unfoldlet ( e 2 [e 1 /v] ) unfoldlet(fold (a, b => e 1 ) e 2 e 3 ) = fold (a, b => unfoldlet(e 1 )) unfoldlet(e 2 ) unfoldlet(e 3 ) unfoldlet(f(e 1, e 2,..., e n )) = f(unfoldlet(e 1 ), unfoldlet(e 2 ),..., unfoldlet(e n )) unfoldlet( (e 1, e 2,..., e n )) = (unfoldlet(e 1 ), unfoldlet(e 2 ),..., unfoldlet(e n )) Egenskaber ved relationen unfoldlet Det første vi bemærker er, at relationen unfoldlet er en funktion. Det kan vises ved fuldstændig duktion med relationen, der deferes som følger: Lad lets være en funktion, der angiver antallet af let-bdger i et udtryk. Vi kan så defere relationen ved: e e (lets(e), e )< lex (lets(e ), e ) Det andet vi bemærker er, at unfoldlet er semantikbevarende i følgende forstand: Lemma 17 Lad p være et typekorrekt program, og e et udtryk, der er typekorrekt mht. p, hvor fv(e) {v 1,..., v n }. For alle c 1,..., c n gælder: e[c 1 /v 1,, c n /v n ] p c unfoldlet(e)[c 1 /v 1,, c n /v n ] p c Lemmaet kan bevises ved fuldstændig duktion med relationen som deferet ovenfor, hvor der i fold-tilfældet vises et dskudt lemma ved duktion over antallet af elementer i den multimængde, der foldes over. Undervejs i beviset benyttes følgende resultat, der kan vises ved strukturel duktion over e 2 : c, c 1,..., c n. ( let v = e 1 e 2 ) [c1 /v 1,, c n /v n ] p c ( e 2 [e 1 /v] ) [c 1 /v 1,, c n /v n ] p c 8.4 Relationen simp I dette afsnit viser vi en relation, der transformerer et udtryk ved hjælp af følgende omskrivnger, der beskriver statisk evaluerg af udtryk: fold (v 1, v 2 => e 1 ) e 2 {} e 2 fold (v 1, v 2 => e 1 ) e 2 (S with e) e 1 [e/v 1, (fold (v 1, v 2 => e 1 ) e 2 S)/v 2 ] #lab({l 1 := e 1,... l n := e n }) e i hvis lab = l i 68

70 Inkrementaliserg 8.4 Relationen simp Relationen simp Exp Exp deferes ved følgende regler (relationen context deferes senere): Const: Var: c simp c v simp v If: Let: Fold(1): Call: Op: e 1 simp e 1 e 2 simp e 2 e 3 simp e 3 if e 1 then e 2 else e 3 simp if e 1 then e 2 else e 3 e 1 simp e 1 e 2 simp e 2 let v = e 1 e 2 context e let v = e 1 e 2 simp e e 1 simp e 1 e 2 simp e 2 e 3 simp e 3 fold (v 1, v 2 => e 1) e 2 e 3 context e fold (v 1, v 2 => e 1 ) e 2 e 3 simp e e 1 simp e 1 e 2 simp e 2... e n simp e n f(e 1, e 2,..., e n) context e f(e 1, e 2,..., e n ) simp e e 1 simp e 1 e 2 simp e 2... e n simp e n (e 1, e 2,..., e n) context e (e 1, e 2,..., e n ) simp e ( hvor e2 {} og e 3 S with e ) Lab(1): e simp e #lab(e ) context e #lab(e) simp e (hvor e {l 1 := e 1,..., l n := e n }) Fold(2): Fold(3): e 2 simp e 2 fold (v 1, v 2 => e 1 ) e 2 {} simp e 2 e 1 [e/v 1, (fold (v 1, v 2 => e 1 ) e 2 S)/v 2 ] simp ē fold (v 1, v 2 => e 1 ) e 2 (S with e) simp ē Lab(2): e i simp e i #lab({l 1 := e 1,... l n := e n }) simp e i (hvor lab = l i ) Hvis e simp e siger vi, at e kan simplificeres til e. Hvis vi i første omgang ser bort fra context - relationen, så kan defitionen af simp forklares på følgende måde: De første 8 regler beskriver, at et udtryk simplificeres ved at simplificere deludtrykkene. Reglerne Fold(2), Fold(3) og Lab(2) beskriver de før omtalte omskrivnger. Vi ser nu på et eksempel. Udtrykket har samme værdi som udtrykket der kan simplificeres til #lab(if e 1 then {lab := e 2 } else {lab := e 3 }) if e 1 then #lab({lab := e 2 }) else #lab({lab := e 3 }) if e 1 then e 2 else e 3 For at realisere denne simplificerg bruges en kontekst-regel, der løfter et betget udtryk ud af en kontekst. Lad være et symbol, der ikke forekommer i noget program. En kontekst 69

71 Inkrementaliserg 8.4 Relationen simp deferes så, som et udtryk med et hul ved følgende grammatik: C ::= #lab( ) let v = e 2 fold (a, b => e 1 ) e 3 fold (a, b => e 1 ) e 2 f(e 1,..., e j 1,, e j+1,..., e n ) for j {1,..., n} (e 1,..., e j 1,, e j+1,..., e n ) for j {1,..., n} Hvis C er en kontekst, skriver vi C[e] for det udtryk, der fås ved at erstatte med e. Vi kan nu defere relationen context Exp Exp ved reglerne: Context(1): Context(2): if e 1 then C[e 2 ] else C[e 3 ] simp e C[if e 1 then e 2 else e 3 ] context e C[e] context e (hvor e if e 1 then e 2 else e 3 ) Vi har for eksempel x simp x.. e simp e (a + b)[y/a, e /b] simp y + e if x then e else (fold (a, b => a + b) 0 (S with y)) simp if x then e else y + e fold (a, b => a + b) 0 (if x then S else S with y) context if x then e else y + e hvor e = fold (a, b => a + b) 0 S, altså fold (a, b => a + b) 0 (if x then S else S with y) simp if x then e else y + e hvilket illustrerer, at ved at løfte det betgede udtryk ud af fold-konteksten, kan der udføres simplificerg af fold-udtrykket Transformationen simp er semantikbevarende Vi viser et lemma, der siger, at hvis e simp e, så har e samme betydng som e: Lemma 18 Lad p være et typekorrekt program, og e et udtryk der er typekorrekt mht. p. Antag, at fv(e) {v 1,..., v n } og lad θ data = [v 1 c 1,..., v n c n ]. Hvis e har unikke navne gælder: ( ) e.e simp e c, θ data.e[θ data ] p c e [θ data ] p c Bevis: Lemmaet vises ved regelduktion. Med P (e, e ) deferet ved P (e, e ) c, θ data.e[θ data ] p c e [θ data ] p c viser vi P (e, e ) for alle e, e hvor e simp e. Vi ser på hver regel for sig. Const P (c, c) gælder trivielt Var P (v, v) gælder trivielt If Antag P (e i, e i ) for i = 1, 2, 3. Vi skal vise P (if e 1 then e 2 else e 3, if e 1 then e 2 else e 3). Antag derfor if e 1 then e 2 else e 3 p c. Der er to tilfælde: e 1 p true og e 1 p false. I begge tilfælde har vi fra P (e 1, e 1), at e 1 evaluerer til det samme som e 1, og ved at bruge P (e 2, e 2) og P (e 3, e 3), får vi det ønskede. 70

72 Inkrementaliserg 8.4 Relationen simp Let Betragt reglen e 1 simp e 1 e 2 simp e 2 if ē 1 then C[ē 2 ] else C[ē 3 ] simp ē let v = e 1 e 2 simp ē hvor let v = e 1 e 2 = C[if ē 1 then ē 2 else ē 3 ]. Vi skal vise P (let v = e 1 e 2, ē), antag derfor let v = e 1 e 2 p c. Vi må have C = let v = e 2, så e 1 = if ē 1 then ē 2 else ē 3. Vi skal vise ē[θ data ] p c, og vi har pr. antagelse, at e 1 [θ data ] p c 1 og e 2 [θ data ][c 1 /v] p c. Fra P (e 1, e 1) får vi så e 1[θ data ] p c 1, og fra P (e 2, e 2) får vi e 2[θ data ][c 1 /v] p c. Ifølge duktionsantagelsen har vi P (if ē 1 then C[ē 2 ] else C[ē 3 ], ē), så det er nok at vise Vi har (if ē 1 then C[ē 2 ] else C[ē 3 ])[θ data ] p c } {{ } ē ē = if ē 1 then (let v = ē 2 e 2) else (let v = ē 3 e 2) Antag først ē 1 [θ data ] p true. Så har vi ē 2 [θ data ] p c 1 og kan dermed konstruere ē 2 [θ data ] p c 1 e 2[θ data ][c 1 /v] p c ē 1 [θ data ] p true (let v = ē 2 e 2)[θ data ] p c (if ē 1 then (let v = ē 2 e 2) else (let v = ē 3 e 2))[θ data ] p c som ønsket. Tilfældet hvor ē 1 [θ data ] p false vises tilsvarende. Hvis let v = e 1 e 2 C[if ē 1 then ē 2 else ē 3 ], så ser let-reglen ud som følger: e 1 simp e 1 e 2 simp e 2 let v = e 1 e 2 context let v = e 1 e 2 let v = e 1 e 2 simp let v = e 1 e 2 og P (let v = e 1 e 2, let v = e 1 e 2) kan vises ved oplagt brug af P (e 1, e 1) og P (e 2, e 2). Tilfældene for reglerne Call, Op, Lab(1) og Fold(1) vises på tilsvarende måde ved at opdele i to tilfælde, afhængig af hvilken regel der er brugt i context -relationen, og bruge duktionsantagelsen. Vi afslutter beviset med at se på de tre teressante tilfælde Fold(2), Fold(3) og Lab(2). Fold(2) Betragt reglen e 2 simp e 2 fold (v 1, v 2 => e 1 ) e 2 {} simp e 2 Vi skal vise P (fold (v 1, v 2 => e 1 ) e 2 {}, e 2) under antagelsen P (e 2, e 2). Antag derfor fold (v 1, v 2 => e 1 ) e 2 {} p c Vi har {}[θ data ] p {}, så fra semantikken ser vi, at {}[θ data ] p {}. e 2 [θ data ] p c (fold (v 1, v 2 => e 1 ) c {})[θ data ] p fold c (fold (v 1, v 2 => e 1 ) e 2 {})[θ data ] p c specielt e 2 [θ data ] p c. P (e 2, e 2) giver så e 2[θ data ] p c som ønsket. 71

73 Inkrementaliserg 8.4 Relationen simp Fold(3) Vi ser nu på tilfældet for reglen e 1 [e/v 1, (fold (v 1, v 2 => e 1 ) e 2 S)/v 2 ] simp ē fold (v 1, v 2 => e 1 ) e 2 (S with e) simp ē Antag P (e 1 [e/v 1, (fold (v 1, v 2 => e 1 ) e 2 S)/v 2 ], ē) (fold (v 1, v 2 => e 1 ) e 2 (S with e))[θ data ] p c Vi skal så vise ē[θ data ] p c. Ifølge duktionsantagelsen er det nok at vise (e 1 [e/v 1, (fold (v 1, v 2 => e 1 ) e 2 S)/v 2 ])[θ data ] p c Fra antagelsen (fold (v 1, v 2 => e 1 ) e 2 (S with e))[θ data ] p c ser vi, at der fdes c 1,..., c n og c, så (S with e)[θ data ] p {c 1,..., c n } og e 2 [θ data ] p c med (fold (v 1, v 2 => e 1 ) c {c 1,..., c n })[θ data ] p fold c Fra (S with e)[θ data ] p {c 1,..., c n } får vi S[θ data ] p {c 1,..., c n 1 } e[θ data ] p c n specielt n 1. Fra semantikken ser vi, at der må fdes et c, så Vi har så (fold (v 1, v 2 => e 1 ) c {c 1,..., c n 1 })[θ data ] p fold c (e 1 [θ data ])[c n /v 1, c /v 2 ] p c S[θ data ] p {c 1,..., c n 1 } e 2 [θ data ] p c (fold (v 1, v 2 => e 1 ) c {c 1,..., c n 1 })[θ data ] p fold c Alt i alt har vi nu (fold (v 1, v 2 => e 1 ) e 2 S)[θ data ] p c e[θ data ] p c n (fold (v 1, v 2 => e 1 ) e 2 S)[θ data ] p c e 1 [c n /v 1, c /v 2 ][θ data ] p c så der gælder ( ) e 1 [e/v 1, (fold (v 1, v 2 => e 1 ) e 2 S)/v 2 ] [θ data ] p c som ønsket. Lab(2) I tilfældet for reglen e i simp e i #lab({l 1 := e 1,... l n := e n }) simp e i (hvor lab = l i ) antages P (e i, e i ) og #lab({l 1 := e 1,..., l n := e n })[θ data ] p c. Vi skal så vise e i [θ data] p c. Der må fdes c 1,..., c n med e 1 [θ data ] p c 1 e 2 [θ data ] p c 2... e n [θ data ] p c n og c = c i. Fra P (e i, e i ) får vi e i [θ data] p c i som ønsket. 72

74 Inkrementaliserg 8.5 Inkrementaliserg af en funktion uden funktionskald 8.5 Inkrementaliserg af en funktion uden funktionskald Vi ser nu på, hvordan en funktion kan krementaliseres. I første omgang ser vi kun på funktioner der ikke deholder funktionskald. I afsnit 8.6 ser vi på, hvordan funktionskald kan behandles Brug af cachen En cache er en partiel afbildng C : Exp Exp, der afbilder udtryk til udtryk. Intentionen er, at hvis C(e) = e, så kan udtrykket e udskiftes med e, uden at betydngen ændres, og e tager ikke længere tid end e at beregne. For et udtryk e forsøger vi at udskifte deludtryk med udtryk fra cachen baseret på lighed af udtryk. Hvis cachen C deholder bdgen [3 + x #1(r)], bliver udtrykket let x = x ændret til let x = 7 #1(r), der ikke nødvendigvis har den samme værdi som det origale udtryk. Vi dfører derfor et krav om, at hvis v er en fri variabel i dom(c), så må v ikke være en fri variabel i det udtryk, der skal transformeres. Relationen ccalls har to opgaver: udskiftng af udtryk med elementer fra cachen, samt at forsøge at udskifte funktionskald g(x) med funktionskald til en krementel version af g. Vi viser her defitionen af relationen, hvor vi i første omgang ser bort fra tilfældet for funktionskald. Afsnit 8.6 viser og kommenterer tilfældet for funktionskald. Funktionen cr (cache-retrieval) bruges til at undersøge, om et udtryk e kan udskiftes med en reference til cachen C: { e hvis C(e) = e cr(e)c = e ellers Relationen ccalls benytter værdien cr til at forsøge at udskifte deludtryk med referencer til cachen C. Vi viser nu defitionen af ccalls. Værdierne xs, ys, I, D, F, Γ og A benyttes i forbdelse med funktionskald, så man kan se bort fra dem i første omgang. ccalls(v) xs ys I C D F Γ A = (v, D, F ) ccalls(c) xs ys I C D F Γ A = (c, D, F ) ccalls(if e 1 then e 2 else e 3 )xs ys I C D F Γ A = ( if cr(e 1 )C then cr(e 2)C else cr(e 3)C, D, F ) hvor ccalls(e 1 ) xs ys I C D F Γ A = (e 1, D, F ) ccalls(e 2 ) xs ys I C D F Γ A = (e 2, D, F ) ccalls(e 3 ) xs ys I C D F Γ A = (e 3, D, F ) ccalls(let v = e 1 e 2 ) xs ys I C D F Γ A = ( let v = cr(e 1 )C cr(e 2)C, D, F ) hvor ccalls(e 1 ) xs ys I C D F Γ A = (e 1, D, F ) e 1 = e 1[I] I = I[v e 1] ccalls(e 2 ) xs ys I C D F Γ A = (e 2, D, F ) 73

75 Inkrementaliserg 8.5 Inkrementaliserg af en funktion uden funktionskald ccalls(fold (a, b => e 1 ) e 2 e 3 ) xs ys I C D F Γ A = ( fold (a, b => cr(e 1 )C) cr(e 2)C cr(e 3)C, D, F ) hvor ccalls(e 1 ) xs ys I C D F Γ A {a, b} = (e 1, D, F ) ccalls(e 2 ) xs ys I C D F Γ A = (e 2, D, F ) ccalls(e 3 ) xs ys I C D F Γ A = (e 3, D, F ) ccalls( (e 1, e 2,..., e n )) xs ys I C D F Γ A = ( (cr(e 1 )C, cr(e 2)C,..., cr(e n)c), D n, F n ) hvor ccalls(e 1 ) xs ys I C D F Γ A = (e 1, D 1, F 1 ) ccalls(e 2 ) xs ys I C D 1 F 1 Γ A = (e 2, D 2, F 2 ).. ccalls(e n ) xs ys I C D n 1 F n 1 Γ A = (e n, D n, F n ) I de beskrevne tilfælde ændres der ikke ved D og F, så der sker blot det, at funktionen cr anvendes på deludtryk Relationen c Vi kan nu beskrive, hvordan en funktion, hvis krop ikke deholder funktionskald, kan krementaliseres. Hvis f er en funktion, og (xs, ys, es) er en opdatergsoperation, kan vi konstruere en krementel funktion f på følgende måde: let-bdger i kroppen af f udfoldes for at lette opslag i cachen. I det resulterende udtryk er de frie variable parameternavnene v 1,..., v n fra defitionen af f. De udskiftes med navnene xs fra opdatergsoperationen. Det resulterende udtryk simplificeres med simp -relationen. Hvis det simplificerede udtryk er {lab 1 := e c 1,..., lab s := e c s}, lader vi cachen C være [e c 1 #lab 1 (r),..., e c s #lab s (r)], hvor r er et nyt navn. I den oprdelige funktionskrop substitueres udtrykkene es fra opdatergsoperationen d for de formelle parametre. Det resulterende udtryk simplificeres med simp -relationen. I det simplificerede udtryk forsøges deludtryk erstattet med udtryk fra cachen C. Vi deferer en ny funktion f ved fun f (x 1 : t 1,..., x n : t n, y 1 : t 1,..., y m : t m, r : t) = e, hvor de første n + m parametre er som angivet i opdatergsoperationen (xs og ys), og t er returtypen for f, og e er udtrykket, der fremkom ved brug af cachen. Hvis f kaldes med værdien af f som sidste parameter, så returneres samme værdi, som man ville have fået ved at kalde f med opdaterede data, som angivet af opdatergsoperationen. Relationen c udfører de beskrevne punkter, og er deferet på følgende måde: 74

76 Inkrementaliserg 8.6 Inkrementaliserg af funktionskald c(f) (xs, ys, es) D F Γ = ((f, [x 1,..., x n ], [y 1,..., y m ]), D, F ) hvor xs = [x 1 : t 1,..., x n : t n] ys = [y 1 : t 1,..., y m : t m] es = [e 1,..., e n ] fun f(v 1 : t 1, v 2 : t 2,..., v n : t n ) = body unfoldlet(body) = body body = body [x 1 /v 1, x 2 /v 2,, x n /v n ] body simp {lab 1 := e c 1, lab 2 := e c 2,... lab j := e c j} C = [e c 1 #lab 1 (r), e c 2 #lab 2 (r),..., e c j #lab j (r)] hvor r er et nyt navn ē 1 = body[e 1 /v 1, e 2 /v 2,, e n /v n ] ē 1 simp ē 2 ccalls(ē 2 ) xs ys [ ] C D F Γ = (ē 3, D, F ) Γ(f) = (t, ) D = D [f (es, (f, [x 1,..., x n ], [y 1,..., y m ]), f(x 1,..., x n ))] F = F {fun f (x 1 : t 1,..., x n : t n, y 1 : t 1,..., y m : t m, r : t) = ē 3 } Afbildngen D og mængden F bruges til at deholde formation om funktioner, der allerede er krementaliserede. I næste afsnit beskrives, hvordan de bruges. 8.6 Inkrementaliserg af funktionskald Vi viser nu det sidste tilfælde i defitionen af transformationen ccalls, der beskriver, hvordan funktionskald håndteres. Efter defitionen kommenteres de forskellige dele, der dgår. 75

77 Inkrementaliserg 8.6 Inkrementaliserg af funktionskald ccalls(f(e 1, e 2,..., e k )) xs ys I C D F Γ A = ( f ( x 1 [θ],..., x n [θ], ȳ 1 [θ],..., ȳ j [θ], e), D, F ) hvis mdst et af udtrykkene e 1,..., e k afhænger af en variabel x {x 1,... x n } og ( fv(e 1) fv(e 2) fv(e k) ) A = og D(f) = ( [ē 1,..., ē k ], (f, [ x 1,... x n ], [ȳ 1,..., ȳ m ]), e R ) og der fdes et θ så ē 1 [θ] = e 1,..., ē k [θ] = e k og C(e R [θ]) = e hvor (e 1,..., e k) = (e 1 [I],..., e k [I]) xs = [x 1 : t 1,..., x n : t n ] ys = [y 1 : t 1,..., y m : t m] ( f ( x 1 [θ],..., x k [θ], ȳ 1 [θ],... ȳ i [θ], e), D, F ) hvis mdst et af udtrykkene e 1,..., e k afhænger af en variabel x {x 1,... x n } og ( fv(e 1) fv(e 2) fv(e k) ) A = og D(f) = og C(f( x 1 [θ],..., x k [θ])) = e og extract ( [ē 1,..., ē k ], {x 1,..., x n }, {y 1,..., y m } ) = [ x 1,..., x k ] hvor generalize[e 1,..., e k] {y 1,..., y m } = ( [ē 1,..., ē k ], θ ) ( fv(e 1 ) fv(e k) ) {y 1,..., y m } = {ȳ 1,..., ȳ j } c(f)[ x 1 : t f 1,... x k : t f k ] [ȳ 1 : t 1,... ȳ j : t j ] [ē 1,..., ē k ] D F Γ = ( (f, [ x 1,..., x k ], [ȳ 1,..., ȳ i ]), D, F ) (e 1,..., e k) = (e 1 [I],..., e k [I]) xs = [x 1 : t 1,..., x n : t n ] ys = [y 1 : t 1,..., y m : t m] Γ(f) = ( t, [t f 1,..., tf n] ) t p = t q hvis ȳ p = y q for p {1,..., j}, q {1,..., m} ( f(cr(e1 )C,..., cr(e k )C), D, F ) ellers Argumentudtrykkene e 1,..., e k til funktionskaldet kan deholde forekomster af let-bundne variable. Argumentet I til transformationen er en substitution, der deholder formation om hvilke udtryk, sådanne variable er bundet til. Afbildngen D deholder bdger af formen f ( es, (f, xs, ys), e R ). En sådan bdg betyder, at funktionen f er blevet krementaliseret til f mht. opdatergsoperationen (xs, ys, es), og at kaldbetgelsen er e R. Hvis kaldbetgelsen opfyldes af et udtryk e, kan et kald af f med argumenterne es altså udskiftes med et kald af f (xs, ys, e). Mængden F deholder funktionsdefitioner for de funktioner, der er blevet krementaliserede. Mængden A bruges til at deholde navne på variable, der er bundet af fold-udtryk. Afsnittene og beskriver generalize og extract i detaljer, så vi undlader at vise defitionerne her. Håndtergen af funktionskald er delt op i tre dele, der kommenteres i det følgende Brug af en allerede krementaliseret funktion Det første tilfælde beskriver situationen, hvor afbildngen D deholder en bdg for den kaldte funktion, hvilket betyder, at der fdes en krementel version f af den kaldte funktion f. 76

78 Inkrementaliserg 8.7 Egenskab for c Hvis argumentudtrykkene matcher den opdatergsoperation, som f er blevet krementaliseret med hensyn til, og hvis kaldbetgelsen kan hentes fra cachen, så udskiftes kaldet af f med et kald til f. Hvis mdst et af argumentudtrykkene afhænger af en fold-bundet variabel, udskiftes funktionskaldet ikke. Det skyldes, at den værdi, der bdes til variablen, skifter for hver fold-iteration, så det er ikke nok, at kaldbetgelsen fdes i cachen for én af dem Introduktion af ny funktion Hvis den kaldte funktion ikke er blevet krementaliseret, beskriver det andet tilfælde, hvordan en krementel version konstrueres og forsøges brugt. Transformationen c bruges til at krementalisere den kaldte funktion, og hvis cachen deholder kaldbetgelsen, udskiftes kaldet. Som beskrevet i afsnit generaliseres argumentudtrykkene i funktionskaldet, og de nye udtryk bruges som udgangspunkt for den opdatergsoperation, som gives til c Basistilfælde I de resterende tilfælde efterlades funktionskaldet takt, bortset fra at funktionen cr anvendes på argumentudtrykkene for at forsøge at udskifte deludtryk med referencer til cachen. 8.7 Egenskab for c I dette afsnit præciseres det, i hvilken forstand implikationen f(x) = r f (x, y, r) = f(x y) gælder, hvis f er en krementel version af f med hensyn til operationen x y. Først præsenteres et lemma om c, og derefter et korrolar, der viser den ønskede implikation. Lemma 19 Lad p være et program med unikke navne, og lad ˆf være en funktion fra p. Lad [x 1 : t 1,... x n : t n ], [y 1 : t } {{ } 1,... y m : t m], [e 1,..., e n ] være en opdatergsoperation, der er typekorrekt } {{ } } {{ } xs ys es mht. p og ˆf. Lad F være en følge af funktionsdefitioner. Lad Γ være funktionsomgivelser for p, og lad D være en partiel afbildng Funname (Exp (Funname Var Var ) Exp), og antag c( ˆf) xs ys I D F Γ = ( ( ˆf, [x 1,..., x n ], [y 1,..., y m ]), D, F ) så gælder P (ĝ, D, p, F, Γ) for alle ĝ F og Q( ˆf, [e 1,..., e n ], p, F ) hvis P (ĝ, D, p, F, Γ). Egenskaberne P og Q er deferet på følgende måde: Q( ˆf, [e 1,..., e n ], p, p ) c 1,..., c n, c 1,..., c m, c, c. ˆf(c 1,..., c n ) p c ( ˆf(e1 [θ xy ],..., e n [θ xy ]) p c ˆf (c 1,..., c n, c 1,..., c m, c) p p c) 77

79 Inkrementaliserg 8.7 Egenskab for c P ( ˆf, D, p, p, Γ) hvis ˆf er deferet i p ved fun ˆf (a 1 : t 1,..., a k : t k ) = og D( ˆf) = ( [e 1,..., e n ], ( ˆf, [x 1,..., x n ], [y 1,..., y m ]), e ) og n + m + 1 = k og ˆf er deferet i p ved fun ˆf(x 1 : t 1,..., x n : t n ) = fv(e i ) {x 1,..., x n, y 1,..., y m } og fv(e) {x 1,..., x n } og og [x 1 t 1,..., x n t n ], Γ e : t k så gælder c 1,..., c n, c 1,..., c m, c, c.e[θ x ] p c ( ˆf(e1 [θ xy ],..., e n [θ xy ]) p c ˆf (c 1,..., c n, c 1,..., c m, c) p p c hvor θ x = [x 1 c 1,..., x n c n ] og θ xy = [x 1 c 1,..., x n c n, y 1 c 1,..., y m c m] Bevis: Betragt kaldgrafen G for ˆf i programmet p. Da der ikke tillades rekursion, og en funktion først kan kaldes efter dens defition, deholder G gen kredse. Relationen < ka, der deferes ved f< ka g, hvis f kaldes af g, altså hvis der er en kant fra g til f i G, er en well-founded relation, da det ikke er muligt at konstruere en uendelig kæde < ka g i < ka < ka g 2 < ka g 1. Lad ˆf være en funktion i G. Som duktionsantagelse antager vi, at lemmaets påstand gælder for alle funktioner h, der kaldes af ˆf. Ifølge prcippet for fuldstændig duktion, er det nok at vise lemmaets påstand for den givne funktion ˆf. Antag xs, ys, es, F, Γ, D, D, F givne som beskrevet i lemmaet. Ud fra antagelsen h F.P (h, D, p, F, Γ) skal vi vise h F.P (h, D, p, F, Γ) Q(f, [e 1,..., e n ], p, F ). Vi har pr. antagelse fun f(v 1 : t 1, v 2 : t 2,..., v n : t n ) = body unfoldlet(body) = body body = body [x 1 /v 1, x 2 /v 2,, x n /v n ] body simp {lab 1 := e c 1, lab 2 := e c 2,... lab j := e c j} C = [e c 1 #lab 1 (r), e c 2 #lab 2 (r),..., e c j #lab j (r)] hvor r er et nyt navn ē 1 = body[e 1 /v 1, e 2 /v 2,, e n /v n ] ē 1 simp ē 2 ccalls(ē 2 ) xs ys [ ] C D F Γ = (ē 3, D, F ) Γ(f) = (t, ) D = D [f (es, (f, [x 1,..., x n ], [y 1,..., y m ]), f(x 1,..., x n ))] F = F {fun f (x 1 : t 1,..., x n : t n, y 1 : t 1,..., y m : t m, r : t) = ē 3 } Vi skitserer et bevis for Q( ˆf, [e 1,..., e n ], p, F ). Lad c 1,..., c n, c 1,..., c n, c, c være givne og antag ˆf(c 1,..., c n ) p c (8.1) ˆf(e 1 [θ xy ],..., e n [θ xy ]) p c (8.2) hvor θ xy = [x 1 c 1,..., x n c n, y 1 c 1,..., y m c m]. Vi skal vise ˆf (c 1,..., c n, c 1,..., c p F m, c) c. Fra (8.1) får vi body[θ x ] p c. Fra lemma 17 får vi unfoldlet(body)[v 1 c 1,... v n c n ] p c, altså body [v 1 c 1,... v n c n ] p c, og dermed body [θ x ] p c hvor θ x = [x 1 c 1,... x n c n ]. Fra lemma 18 får vi ( ) {lab 1 := e c 1,..., lab j := e C j } [θ x ] p c 78

80 Inkrementaliserg 8.8 Samlet metode Ifølge (8.2) har vi ē 1 [θ xy ] p c. Fra lemma 18 får vi ē 2 [θ xy ] p c. Vi skal vise ˆf (c 1,..., c n, c 1,..., c p F m, c) c. I p F er ˆf deferet som fun ˆf (x 1 : t 1,..., x n : t n, y 1 : t 1,..., y m : t m, r : t) = ē 3 p F Vi skal altså vise ē 3 [θ xy ][c/r] c, hvilket kan vises ved et hjælperesultat om ccalls, der kan vises ved strukturel duktion over størrelsen af ē 3.. Vi angiver et korrolar til lemma 19, der deholder det ønskede udsagn: Korrolar 2 Lad p være et typekorrekt program, og ˆf en funktion i p. Lad (xs, ys, es) være en opdatergsoperation og Γ funktionsomgivelser for p. Antag Så gælder c( ˆf) xs ys [ ] [ ] Γ = ( ( ˆf,, ),, F ) c 1,..., c n, c 1,..., c m, c, c. ˆf(c 1,..., c n ) p c ( ˆf(e1 [θ xy ],..., e n [θ xy ]) p c ˆf (c 1,..., c n, c 1,..., c m, c) p F c) hvor θ xy = [x 1 c 1,..., x n c n, y 1 c 1,..., y m c m] og xs = [x 1 : t 1,... x n : t n ], ys = [y 1 : t 1,... y m : t m] og es = [e 1,..., e n ]. Korrolaret følger af lemma 19, og korrolar 1 fra side 32 i kapitel Samlet metode Vi kan nu præsentere en samlet metode til at krementalisere et FunSETL-program. Vi ønsker at krementalisere rapporterne fra kapitel 3 med hensyn til opdatergerne tilføjelse af kontrakt og tilføjelse af hændelse. Vi dfører derfor betegnelsen krementalisergs-konfiguration (eller blot konfiguration) for et program p og en funktion f om (xs, ys, zs, es 1, es 2 ), hvor (xs, ys, es 1 ) og (xs, zs, es 2 ) er to opdatergsoperationer for f. Inkrementalisergen af et program p med hensyn til en konfiguration deferes på følgende måde: Incrementalize(f, p) cfg Γ = (p F 1 F 2, cfg 2, f, f ) hvor normalizenames(p) = p 1 Extend(p 1 ) Γ = (p 2, Γ ) Clean(p 2 ) = p 3 extendconfig(cfg) Γ Γ = cfg 1 cleanconfig(cfg 1 ) = cfg 2 c(f)(xs, ys, es 1 ) [ ] [ ] Γ = ( (f,, ),, F 1 ) c(f)(xs, zs, es 2 ) [ ] [ ] Γ = ( (f,, ),, F 2 ) cfg 2 = (xs, ys, zs, es 1, es 2 ) Inkrementelisergen af en funktion f i et program p giver et nyt program og en ny konfiguration sammen med navnene på de to krementelle versioner af f. Funktionen normalizenames transformerer et program p til p 1, hvor p 1 har unikke navne. Ved at bruge Extend og Clean opnås programmet p 3. Transformationerne extendconfig og cleanconfig bruger Extend og Clean på udtrykkene i en konfiguration. Det resulterer i en ny konfiguration, og de to opdatergsoperationer bruges til at krementalisere programmet p 3. I det krementelle program gælder r = ˆf(xs) ˆf (xs, ys, r) = ˆf(es 1 ) r = ˆf(xs) ˆf (xs, zs, r) = ˆf(es 2 ) 79

81 Inkrementaliserg 8.8 Samlet metode Funktionen ˆf er fremkommet ved at bruge Extend på funktionen f, så der gælder #1( ˆf(es 1 )) = f(es 1 ), og tilsvarende for es 2. Derfor kan funktionerne ˆf og ˆf bruges til at beregne resultatet af f, men på en mere effektiv måde. I kapitel 10 vises resultatet af at bruge Incrementalize på rapporterne fra kapitel 3, men først beskrives en implementerg af FunSETL og krementalisergsmetoden. 80

82 Kapitel 9 Implementerg af FunSETL I dette kapitel beskrives, hvordan et FunSETL-program kan eksekveres ved hjælp af oversættelse til Standard ML. Det første afsnit beskriver, hvordan kernesproget fra kapitel 4 bruges som grundlag for en praktisk implementerg. I afsnit 9.2 gives et overblik over, hvordan sproget kan oversættes til Standard ML, og i afsnit 9.3 forklares, hvordan det resulterende program kan eksekveres. Afsnit 9.5 deholder en oversigt over implementergen af krementalisergsmetoden beskrevet i de forrige kapitler. 9.1 Udvidelse af sproget I sprogbeskrivelsen i kapitel 4 er der set bort fra detaljerne omkrg, hvilke typer og operationer sproget FunSETL deholder. Disse detaljer gives i dette afsnit Typer Typerne i sproget har følgende syntaks: t ::= t id bool t real date strg t 1 + t 2 {lab 1 : t 1,..., lab n : t n } map(t 1, t 2 ) mset(t) hvor der gives mulighed for at dføre typedefitioner af formen type t id = t der dfører typenavnet t id for typen t. En type kan således være et tidligere deferet typenavn, en basistype som for eksempel t, en sum-type, en recordtype, en endelig afbildng eller en multimængde. For en recordtype {lab 1 : t 1,..., lab n : t n } kræves, at n 1, samt at lab 1, lab 2,..., lab n er forskellige. En label er en ikke-tom tegnstreng bestående af alfanumeriske tegn. Typen map(t 1, t 2 ) er typen for endelige afbildnger, der afbilder elementer af typen t 1 til elementer af typen t 2. Typen mset(t) er typen for multimængder hvis elementer har typen t. Et typenavn skal være deferet, før det kan anvendes, og det samme navn må ikke deferes flere gange. 81

83 Implementerg af FunSETL 9.1 Udvidelse af sproget Operationer Vi viser her en kort oversigt over de forskellige operationer i sproget. Syntaksen fra kapitel 4 udvides med følgende udtryk: e ::= i r dd-mm-yyyy s true false L(e) as t R(e) as t vall(e) valr(e) {lab 1 := e 1,..., lab n := e n } #lab(e) [e 1 e 1,..., e n e n] as t e 1 [e 2 ] {e 1,..., e n } as t e 1 + e 2 e 1 - e 2 e 1 * e 2 e 1 / e 2 e 1 = e 2 e 1 < e 2 e 1 and e 2 e 1 or e 2 not e 2 e 1 with e 2 e 1 union e 2 ter e 2 e 1 diff e 2 e 1 e 2 subset e 2 e[e 1 e 1,..., e n e n] dom(e) toset(e) call(o, e 1, e 2,..., e n ) sum (a => e 1 ) e 2 select (a => e 1 ) e 2 Operationerne kan deles op i syv klasser: Konstruktion og dekonstruktion Sproget deholder udtryk til at konstruere og dekonstruere værdier af de beskrevne typer. Basetyperne t, real, strg, date og bool kan konstrueres ved konstantudtrykkene i, r, dd-mm-yyyy, s, true og false, hvor i er et heltal, r er et reelt tal (fx 1.2), s er en (evt. tom) tegnfølge omsluttet af anførselstegn, og dd-mm-yyyy angiver en dato. Værdier af sum-type kan konstrueres med udtrykkene L(e) as t og R(e) as t, hvor t angiver typen af udtrykket, og de dekonstrueres med vall(e) og valr(e). Recordværdier kan konstrueres med udtrykket {lab 1 := e 1,..., lab n := e n } og de dekonstrueres med #lab(e). Endelige afbildnger kan konstrueres med udtrykket [e 1 e 1,..., e n e n] as t, hvor t angiver typen for udtrykket og n 0, og de dekonstrueres med opslag i afbildngen e 1 [e 2 ]. Multimængder kan konstrueres med {e 1,..., e n } as t, hvor t angiver typen af udtrykket, og n 0. For at dekonstruere en multimængde kan der bruges fold-udtryk. Aritmetiske operationer Operationerne +, -, * og / angiver de sædvanlige aritmetiske operationer. Boolske operationer Operationerne and, or og not er de sædvanlige operationer på boolske værdier, og = og < er sammenligngsoperationer. Multimængdeoperationer For multimængder dføres seks operationer: with, union, ter, diff, og subset. with angiver tilføjelse af et element til en multimængde, union og ter er operationer til forengsmængde henholdsvis fællesmængde, diff er mængdedifferens, undersøger, om et element fdes i en multimængde, og subset undersøger, om en multimængde er delmængde af en anden. Afbildngsoperationer Operationen e 1 [e 2 e 3 ] bruges til at udvide afbildngen e 1 med en bdg af e 2 til e 3. Operationen dom(e) returnerer en multimængde bestående af elementerne fra domænet af e, og toset(e) returnerer en multimængde bestående af de bdger, som e deholder. Eksterne operationer Med udtrykket call(o, e 1, e 2,..., e n ) kaldes en ekstern basefunktion o med argumenterne e 1,..., e n. På denne måde kan der bruges Standard ML-funktioner til operationer, der ville være besværlige at programmere i FunSETL. Syntaktisk sukker Udtrykkene sum og select er specialtilfælde af fold-udtrykket. Med select (a => e 1 ) e 2 udvælges de elementer fra multimængden e 2, der opfylder prædikatet λa.e 1. Med sum (a => e 1 ) e 2 summeres værdien af λa.e 1 for elementerne i multimængden e 2. 82

84 Implementerg af FunSETL 9.2 Oversættelse til ML 9.2 Oversættelse til ML Mange af de typer og operationer, som FunSETL deholder, fdes allerede som dbyggede typer og operationer i Standard ML, derfor er det naturligt at implementere FunSETL ved oversættelse til Standard ML. Basetyperne t, real, bool, strg og operationer på dem fdes allerede i ML. Basetypen date kan implementeres ved at bruge modulet Date, fra Standard ML Basis Library 1 Sumtyper fra FunSETL implementeres i ML ved at bruge datatypen: datatype ( a, b) sumt = InL of a InR of b Recordtyper fdes allerede i ML, så de kan oversættes direkte. Typen for multimængder implementeres sammen med de beskrevne operationer ved et MLmodul RunTimeMSet, der bruger lister til at repræsentere en multimængde. En mere effektiv implementerg kunne være baseret på hashg. Tilsvarende implementerer modulet RunTimeMap endelige afbildnger sammen med deres operationer. De logiske operationer and, or og not fdes allerede i ML. Tilbage er så de aritmetiske operationer og sammenligngsoperationerne = og <. Disse fdes allerede i ML for eksempel for typerne t og real. For typer, hvor operationerne ikke er dbyggede i ML, konstrueres ML-funktioner, der implementerer dem. Vi viser som en opfølgng på afsnit 3.1.2, hvordan addition for ressourcer implementeres. Ressourcer kan repræsenteres på følgende måde som FunSETL-værdier: type pr = real + terval type resource = map(strg, pr) Addition for typen resource implementeres af funktionen plus res, der deferes på følgende måde: fun plus_res(r1, r2) = let fun add((k, v), m) = case RunTimeMap.lookup(m, k) of NONE => RunTimeMap.sert(m, k, v) SOME v => RunTimeMap.sert(m, k, plus_pr(v, v)) foldr add r1 (RunTimeMap.toList r2) end Additionen r 1 + r 2 implementeres ved en foldng af den lokale funktion add over bdgerne i r 2. Funktionen plus res benytter funktionen plus pr til at addere værdier af typen pr. fun plus_pr(v1, v2) = case (v1, v2) of (InL w1, InL w2) => InL(w1 + w2) (InR w1, InR w2) => InR(plus_terval(w1, w2)) _ => raise RunTimeError("plus_pr")) Det vil føre for vidt at gennemgå alle detaljerne i oversættelsesprocessen her, så der henvises til kildekoden, der kan fdes på Eksekverg af et program Overordnet kan et FunSETL-program eksekveres på to måder: offle eller onle. At eksekvere et program p med offle-metoden er den sædvanlige metode, hvor p dlæser nogle data, beregner 1 Se 83

85 Implementerg af FunSETL 9.3 Eksekverg af et program et resultat, og udskriver resultatet. Mere præcist, så foregår offle-eksekverg af p på følgende måde: Antag at den sidst deferede funktion i p har formen fun f(v 1 : t 1,..., v n : t n ) = e For ddata c 1,..., c n hvor c i : t i for i = 1,..., n udskrives værdien c, hvis f(c 1,..., c n ) p c, og programmet termerer. Eksekverg af p med onle-metoden foregår efter en slags client-server-model, hvor p dlæser nogle startdata og derefter udfører beregnger og udskriver et resultat hver gang, der kommer nye data. En konfiguration (dvs. to opdatergsoperationer) beskriver, hvordan nye data skal behandles: hvis konfigurationen består af xs 1 ys = es 1 og xs 2 zs = es 2, så foregår onleeksekverg af p på følgende måde (hvor der bruges de betegnelser, der blev dført ovenfor): Funktionen f anvendes på startdata c 1,..., c n, og resultatet udskrives. I stedet for at termere ventes på ddata, der består af værdier for ys eller værdier for zs. Hvis der modtages ys-værdier, opdateres xs ved hjælp af operationen xs 1 ys = es 1, og hvis der modtages zs-værdier er det xs 2 zs = es 2, der angiver opdatergen. Dernæst beregnes f(xs) for de opdaterede xs-værdier, resultatet udskrives, og der ventes igen på ddata. Ved krementel-eksekverg af et program p bruges krementelle versioner af f til at vedligeholde xs-værdierne. I stedet for at beregne f(xs) forfra hver gang, genbruges beregnger fra forrige eksekverg. Hvis programmet p deholder funktioner f og f der er krementelle versioner af f med hensyn til de to opdatergsoperationer, så foregår krementel eksekverg på samme måde som onle-eksekverg, bortset fra at i stedet for at kalde f(xs), kaldes f (xs, ys, r) eller f (xs, zs, r), hvor r er resultatet af den forrige iteration. For at sammenligne tidsforbruget for to forskellige FunSETL-programmer, vedligeholdes der i ML-koden en række tællere, der tæller antallet af udførte operationer under eksekverg. Der bruges seks tællere, der tæller antallet af aritmetiske operationer, operationer på sumtyper, operationer på records, operationer på multimængder, operationer på afbildnger, samt antallet af kontrolstruktur-operationer (for eksempel if-then-else-udtryk) Eksempler For at illustrere eksekvergsmetoderne ser vi på rapporten Resultatopgørelse fra kapitel 3. Den sidste funktion i programmet er ÅretsResultat, der har tre argumenter J, I og v. Offle-eksekverg Ved offle-eksekverg dlæses startdata J 0, I 0, v 0, og resultatet af ÅretsResultat(J 0, I 0, v 0 ) udskrives. Onle-eksekverg Opdatergsoperationerne tilføjelse af kontrakt og tilføjelse af hændelse kan som tidligere nævnt udtrykkes som: [J, I, v] 1 [c new ] = [{contracts := #contracts(j) with c new, events := #events(j)}, I, v] [J, I, v] 2 [e new ] = [{contracts := contracts(j), events := #events(j) with e new }, I, v] Ved onleeksekverg af Resultatopgørelse dlæses startdata [J 0, I 0, v 0 ], og der ventes på opdatergsdata. Hvis der dlæses en ny kontrakt c new1, udføres opdatergen [J 1, I 1, v 1 ] [c new1 ] = [{contracts := #contracts(j 0 ) with c new1, events := #events(j 0 )}, I 0, v 0 ] og resultatet af ÅretsResultat(J 1, I 1, v 1 ) udskrives. Ved dlæsng af en ny hændelse, deferes [J 1, I 1, v 1 ] ud fra den anden opdatergsoperation. På denne måde udskrives resultatet af kaldene ÅretsResultat(J i, I i, v i ) for en følge (J i, I i, v i ) i 1. 84

86 Implementerg af FunSETL 9.4 Kommandolieværktøjet compiler Inkrementel-eksekverg Antag at hvis r = ÅretsResultat(J, I, v) så gælder og ÅretsResultat({contracts := #contracts(j) with c new, events := #events(j)}, I, v) = ÅretsResultat (J, I, v, c new, r) ÅretsResultat({contracts := #contracts(j), events := #events(j) with e new }, I, v) = ÅretsResultat (J, I, v, e new, r) Ved krementel-eksekverg af p udskrives først resultatet r 0 = ÅretsResultat(J 0, I 0, v 0 ), og følgen (J i, I i, v i ) er som beskrevet i onle-tilfældet. Hvis der for eksempel dlæses en ny kontrakt c new1 beregnes resultatet r 1 = ÅretsResultat (J 0, I 0, v 0, c new1, r 0 ). Ifølge antagelsen om den krementelle funktion ÅretsResultat gælder r 1 = ÅretsResultat(J 1, I 1, v 1 ) Værdien r 1 bruges nu som cache ved det næste kald. På denne måde udskrives den samme følge af resultater som ved onle-eksekverg af p, men hvor det er de krementelle funktioner, der bruges frem for at starte forfra for hver ny kontrakt eller hændelse. 9.4 Kommandolieværktøjet compiler Programmet compiler implementerer oversættelsen af et FunSETL-program til et ML-program og konstruerer ML-kode, der implementerer de tre forskellige eksekvergs-metoder. Oversætteren forventer en række argumenter på kommandolien, der har følgende form: compiler (-offle -onle <config-file> -c <config-file> -origfname <funname> -C <funname> -E <funname>) -m <modulename> [-b <basefile>] [-basename <basemodulename>] <putfile> Argumenterne -m og <putfile> er obligatoriske og angiver hvilket navn, der skal bruges til ML-modulerne der konstrueres ved oversættelsen, samt navnet på den fil der deholder FunSETLprogrammet. Desuden skal der angives netop ét af argumenterne -offle, -onle eller -c, der angiver hvilken eksekvergsmetode, der skal genereres kode for. For -onle og -c angives en konfigurationsfil, og for -c angives yderligere navnene på de funktioner, der skal kaldes (den origale funktion, samt de to krementelle versioner). Med argumentet -b kan der angives et navn på en fil, der deholder signaturer for de basefunktioner, der bruges i programmet. Med -basename angives et eventuelt eksisterende ML-modul der implementerer basefunktionerne. Hvis filen ResOpg.fs deholder et program, og ResOpg.cfg deholder en konfiguration til programmet, kan programmet oversættes til eksekverg på onle-metoden med: compiler -onle ResOpg.cfg -m ResOpgML -b BaseFkt.spec ResOpg.fs Resultatet bliver en række ML-moduler, der kan oversættes med ML-oversætteren. Oversætteren er programmeret i ML med brug af oversætteren Moscow ML 2. Kildekoden består af en række moduler: FunSETLPos Deferer den abstrakte syntaks for FunSETL. Syntaksen er annoteret med positionsangivelser, der bruges ved udskrivng af fejlbeskeder. 2 Se sestoft/mosml.html. 85

87 Implementerg af FunSETL 9.5 Kommandolieværktøjet crementalizer FunSETL Deferer den abstrakte syntaks for FunSETL (uden positionsangivelser). Lexer En specifikation, som bruges af mosmllex til at generere et modul til leksikalsk analyse for FunSETL. Parser En specifikation, som bruges af mosmlyac til at producere en parser for FunSETL. Preprocessor Ved hjælp af!clude "<filnavn>" kan et FunSETL-program kludere dholdet af en anden fil. Modulet Preprocessor sørger for denne kluderg, samt holder styr på filnavne og lienumre til brug for udskrivng af fejlbeskeder. TypeCheck Deferer funktioner til at typechecke FunSETL-programmer. BuildOps Indeholder funktioner, der konstruerer ML-funktioner, der implementerer FunSETLoperationer, som for eksempel addition for ressourcer som tidligere beskrevet. BuildRunStruct Dette modul konstruerer et ML-modul, der implementerer den eksekvergsmetode, der er valgt. Der bruges FIFO-pipes til at udveksle data mellem processer. BuildBuilders Konstruerer funktioner, der bruges ved eksekvergen til at repræsentere FunSETLdata som ML-data. BuildToStrg Konstruerer funktioner, der genererer tekststrenge ud fra ML-værdier. Translate Oversætter et FunSETL-program til ML-kode. TranslateUtil Indeholder fælles hjælpefunktioner for de andre moduler. Defs Indeholder prædeferede undtagelser og typer til det genererede ML-program. Pretty En pretty-prter for FunSETL. Compiler Deferer kommandolieprogrammet compiler. 9.5 Kommandolieværktøjet crementalizer Inkrementalisergsmetoden implementeres af værktøjer crementalizer, der bruges til at krementalisere et FunSETL-program ud fra en konfiguration. Programmet forventer følgende parametre: crementalizer -c <configfile> [-b <basefile>] [-op <file>] [-oc <file>] <prg> Med -c angives en fil, der deholder en konfiguration, og med -b angives eventuelt en specifikationsfil for basefunktioner i programmet (den bruges til typecheck). FunSETL-programmet i <prg> krementaliseres, hvilket resulterer i et krementelt program og en ny konfiguration. Med argumenterne -op og -oc kan der angives filnavne for disse. Programmet crementalizer benytter modulerne Extend, Clean og Inc, der implementerer de 3 tr i krementalisergsmetoden, der er beskrevet i kapitlerne 6, 7 og 8. Kildekoden til crementalizer og de tre moduler er vist i bilag D Visualiserg Der er implementeret et simpelt visualisergssystem for de tre rapporter fra kapitel 3. Det består af to simple Perl-programmer, hvor det ene producerer en følge af nye kontrakter og hændelser, og det andet læser uddata fra rapportprogrammet og tegner et søjlediagram over resultaterne. Desuden vises, hvor mange operationer FunSETL-programmet har udført. Ved onle- eller krementeleksekverg er grafen teraktiv, idet den ændres, hver gang der kommer nye data. 86

88 Implementerg af FunSETL 9.6 Visualiserg Systemet er implementeret i Lux, og programmerne bruger named pipes til at kommunikere med handen. Nedenstående figur viser et eksempel på visualiserg af rapporten Resultatopgørelse. Grafen viser det seneste resultat af rapporten, og antallet af operationer er vist. 87

Eksempel på årsafslutning i en produktionsvirksomhed (Der ses overalt bort fra moms og skat)

Eksempel på årsafslutning i en produktionsvirksomhed (Der ses overalt bort fra moms og skat) Side 1 af 9 Eksempel på årsafslutning i en produktionsvirksomhed (Der ses overalt bort fra moms og skat) A/S NUTS har netop ansat Claus Konto som bogholder i deres maskinfabrik. A/S NUTS producerer specialkomponenter

Læs mere

Omkostninger Indtægter Aktiver Passiver. 2110: Variable produktionsomkostninger. 2210 Lokaleomkostninger (produktion)

Omkostninger Indtægter Aktiver Passiver. 2110: Variable produktionsomkostninger. 2210 Lokaleomkostninger (produktion) Konteringsvejledning Omkostninger Indtægter Aktiver Passiver Returvarer og returemballage fra kunder Dekorter til kunder 1100: Nettoomsætning (Saldo) Kontantsalg af varer, tjenesteydelse og emballage salg

Læs mere

Skriftlig prøve i fag nr. 3533 + 3510 + 3511 + 3502 BOGFØRING

Skriftlig prøve i fag nr. 3533 + 3510 + 3511 + 3502 BOGFØRING HA-, HA(dat.)-, HA(jur.)-, BA(int.)-STUDIET 1. DEL Sommereksamen 7. august 2002 Skriftlig prøve i fag nr. 3533 + 3510 + 3511 + 3502 BOGFØRING Varighed: 3 timer Hjælpemidler: Ingen Denne 3-timers prøve

Læs mere

Dokumentation Afstemning af Danmarks aktiver og passiver over for udlandet

Dokumentation Afstemning af Danmarks aktiver og passiver over for udlandet DANMARKS NATIONALBANK Statistisk Afdeling 24. juni 2010 Dokumentation Afstemning af Danmarks aktiver og passiver over for udlandet Med udgivelsen af kvartalsvise finansielle sektorkonti i januar 2010 er

Læs mere

DATO: 21. MAJ 2015 INDHOLD

DATO: 21. MAJ 2015 INDHOLD CASEEKSAMEN Erhvervsøkonomi NIVEAU D DATO: 21. MAJ 2015 OPGAVE På adr. http://ekstranet.learnmark.dk/eud-eksamen2015/ finder du Opgaven elektronisk Eksamensplan 2.doc - skal afleveres i 1 eksemplar på

Læs mere

Bilag E: Konteringsvejledning for personligt ejede handels- og servicevirksomheder

Bilag E: Konteringsvejledning for personligt ejede handels- og servicevirksomheder Konteringsvejledning Omkostninger Indtægter Aktiver Passiver Returvarer og returemballage fra kunder Dekorter til kunder 1100: Nettoomsætning (Saldo) Kontantsalg af varer, tjenesteydelse og emballage salg

Læs mere

Kapitel 5 - Registrering i virksomheder

Kapitel 5 - Registrering i virksomheder Kapitel 5 - Registrering i virksomheder Opgave 5.1 1. Udfor hver af nedenstående regnskabskonti skal du sætte 2 krydser. Et kryds, hvor du angiver, om kontoen er en omkostning, en indtægt, et aktiv eller

Læs mere

ER-modellen. Databaser, efterår 2002. Troels Andreasen. Efterår 2002

ER-modellen. Databaser, efterår 2002. Troels Andreasen. Efterår 2002 Databaser, efterår 2002 ER-modellen Troels Andreasen Datalogiafdelingen, hus 42.1 Roskilde Universitetscenter Universitetsvej 1 Postboks 260 4000 Roskilde Telefon: 4674 2000 Fax: 4674 3072 www.dat.ruc.dk

Læs mere

Præsentation Uddelingskopier

Præsentation Uddelingskopier Præsentation Uddelingskopier Se præsentationen med animationer på www.systime.dk Indholdsfortegnelse Saldobalancen Resultatopgørelsen Balancen Afslutning & link til video Fashion SHOE skal nu i gang med

Læs mere

ER-modellen. Databaser, efterår Troels Andreasen. Efterår 2002

ER-modellen. Databaser, efterår Troels Andreasen. Efterår 2002 Databaser, efterår 2002 ER-modellen Troels Andreasen Datalogiafdelingen, hus 42.1 Roskilde Universitetscenter Universitetsvej 1 Postboks 260 4000 Roskilde Telefon: 4674 2000 Fax: 4674 3072 www.dat.ruc.dk

Læs mere

Præsentation Opgørelse af egenkapitalen i en personligt ejet virksomhed. Uddelingskopier

Præsentation Opgørelse af egenkapitalen i en personligt ejet virksomhed. Uddelingskopier i en personligt ejet virksomhed Præsentation Uddelingskopier Se præsentationen med animationer på www.systime.dk i en personligt ejet virksomhed Indholdsfortegnelse Når overskuddet er større end privatforbrug

Læs mere

Placering af resultat- og balancekonti 45965

Placering af resultat- og balancekonti 45965 Lektionsplan Placering af resultat- og balancekonti 45965 Bemærk: Der er her tale om uddrag af materialet. Du finder hele materialet med lærebog, opgaver og løsninger i Undervisningsbanken. Placering af

Læs mere

Import af rekursivt (parent-child) hierarki i Palo

Import af rekursivt (parent-child) hierarki i Palo Import af rekursivt (parent-child) hierarki i Palo Dette dokument beskriver hvordan et simpelt rekursivt (parent-child) hierarki kan importeres ind i Palo på forskellige måder via SQL og samtidig bibeholde

Læs mere

26 Programbeviser I. Noter. PS1 -- Programbeviser I. Bevis kontra 'check af assertions' i Eiffel. Betingelser og bevisregler.

26 Programbeviser I. Noter. PS1 -- Programbeviser I. Bevis kontra 'check af assertions' i Eiffel. Betingelser og bevisregler. 26 Programbeviser I. Bevis kontra 'check af assertions' i Eiffel. Betingelser og bevisregler. Hvad er programverifikation? Bevisregel for 'tom kommando'. Bevisregel for assignment. Bevisregler for selektive

Læs mere

Bilag C: Konteringsvejledning for personligt ejede handels- og servicevirksomheder

Bilag C: Konteringsvejledning for personligt ejede handels- og servicevirksomheder C: Konteringsvejledning for personligt ejede handels- og servicevirksomheder 1100: Nettoomsætning Returvarer og returemballage Kontantsalg fra kunder salg Dekorter til kunder 2100: Vareforbrug Overførsel

Læs mere

Appendix til kapitel 7 - Koncernregnskab

Appendix til kapitel 7 - Koncernregnskab 13. Koncernregnskab Koncerner skal aflægge koncernregnskab. Formålet med at udarbejde et koncernregnskab er at vise den finansielle stilling for en sammenslutning af flere virksomheder. Opstillingen af

Læs mere

EKSTERNT REGNSKAB 11 KONCERNREGNSKABER (2)

EKSTERNT REGNSKAB 11 KONCERNREGNSKABER (2) EKSTERNT REGNSKAB 11 KONCERNREGNSKABER (2) KONCERNREGNSKABER 3 TYPER REGNSKABER I EN KONCERN: a) Et regnskab for modervirksomheden b) Et regnskab for hvert enkelt dattervirksomhed c) Et regnskab for hele

Læs mere

ERHVERVSØKONOMI NIVEAU: D 8. JANUAR 2015

ERHVERVSØKONOMI NIVEAU: D 8. JANUAR 2015 CASEEKSAMEN ERHVERVSØKONOMI NIVEAU: D 8. JANUAR 2015 OPGAVE På adr. http://ekstranet.learnmark.dk/eud-eksamen2015/ finder du Opgaven elektronisk Eksamensplan 2.doc - skal afleveres i 1 eksemplar på case

Læs mere

Brd. Klee A/S. CVR.nr Delårsrapport for perioden 1. oktober marts 2014

Brd. Klee A/S. CVR.nr Delårsrapport for perioden 1. oktober marts 2014 Brd. Klee A/S CVR.nr. 46 87 44 12 Delårsrapport for perioden 1. oktober 2013 31. marts 2014 For yderligere oplysninger kan direktør Lars Ejnar Jensen kontaktes på telefon 43 86 83 33 Brd. Klee A/S Delårsrapport

Læs mere

1.4. Handels- og fremstillingsvirksomheder kan karakteriseres ved deres varetransaktioner... 16

1.4. Handels- og fremstillingsvirksomheder kan karakteriseres ved deres varetransaktioner... 16 Indholdsfortegnelse Kapitel 1 Virksomhedens regnskab som en del af en større helhed... 11 1.1. Introduktion... 11 1.2. Handlinger er bundet sammen i handlingskæder... 12 1.3. Virksomhedens grundlæggende

Læs mere

Man har i Mikkels Dyrerige registreret følgende indtægter og omkostninger for år 1:

Man har i Mikkels Dyrerige registreret følgende indtægter og omkostninger for år 1: Opgave 4.1 Mikkels Dyrerige MIKKELS DYRERIGE Man har i Mikkels Dyrerige registreret følgende indtægter og omkostninger for år 1: Omsætning kr. 850.000 Salgsfremmende omk. kr. 20.000 Renteomkostninger kr.

Læs mere

Skriftlig prøve i fag nr. 3533 + 3510 + 3511 + 3502 BOGFØRING

Skriftlig prøve i fag nr. 3533 + 3510 + 3511 + 3502 BOGFØRING HA-, HA(DAT.)-, HA(JUR.)-, HA(INT)-studiet 1. del Vintereksamen 3. august 2000 Skriftlig prøve i fag nr. 3533 + 3510 + 3511 + 3502 BOGFØRING Varighed: 3 timer Hjælpemidler: Ingen Denne 3-timers prøve er

Læs mere

Moduler i Standard ML

Moduler i Standard ML Moduler i Standard ML Hans Hüttel December 2001 I løbet af datalogikurset har vi haft glæde af en hel række forskellige standardmoduler som f.eks. Math, Int, Real og String. Disse moduler kan, har vi set,

Læs mere

17.2g Salon Hairstyle [S01]

17.2g Salon Hairstyle [S01] 17.2g Salon Hairstyle [S01] Tomas Haahr startede 1. januar 2011 sin egen frisørsalon under navnet Salon Hairstyle. Frisørsalonen ligger i Saksild, hvor Tomas Haahr har lejet et godt beliggende forretningslokale

Læs mere

Præstensgaard Holding ApS Mosehøjvej 18, 2920 Charlottenlund

Præstensgaard Holding ApS Mosehøjvej 18, 2920 Charlottenlund Præstensgaard Holding ApS Mosehøjvej 18, 2920 Charlottenlund CVR-nr. 35 47 53 03 Årsrapport 1. januar - 31. december 2015 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den

Læs mere

GUIDE Udskrevet: 2018

GUIDE Udskrevet: 2018 GUIDE Sådan arbejder I med foreningens budgetter og regnskaber Udskrevet: 2018 Indhold Sådan arbejder I med foreningens budgetter og regnskaber............................. 3 2 Guide Sådan arbejder I med

Læs mere

GUIDE Udskrevet: 2016

GUIDE Udskrevet: 2016 GUIDE Sådan arbejder I med foreningens budgetter og regnskaber Udskrevet: 2016 Sådan arbejder I med foreningens budgetter og regnskaber Her finder du en af tre guide som viser, hvordan økonomi typisk styres

Læs mere

Global Techtrans ApS Universitetsparken Roskilde. CVR-nr Årsrapport for 2015/16

Global Techtrans ApS Universitetsparken Roskilde. CVR-nr Årsrapport for 2015/16 Multi Revision - Hos os er du i centrum Universitetsparken 7 4000 Roskilde CVR-nr. 32676138 Årsrapport for 2015/16 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 11-10-2016

Læs mere

Programmering og Problemløsning, 2017

Programmering og Problemløsning, 2017 Programmering og Problemløsning, 2017 Typer og Mønstergenkendelse Martin Elsman Datalogisk Institut Københavns Universitet DIKU 23. Oktober, 2017 Martin Elsman (DIKU) Programmering og Problemløsning, 2017

Læs mere

DATABASE - MIN MUSIKSAMLING

DATABASE - MIN MUSIKSAMLING DATABASE - MIN MUSIKSAMLING I dette forløb skulle vi lære om databaser, som bruger sproget SQL. SQL står for Structured Query Language. Det bruges til at vise og manipulere data, gemt i en database. I

Læs mere

Netdania Markets ApS. Kronprinsessegade 36, 1., 1306 København. Årsrapport for

Netdania Markets ApS. Kronprinsessegade 36, 1., 1306 København. Årsrapport for Netdania Markets ApS Kronprinsessegade 36, 1., 1306 København Årsrapport for 2015 CVR-nr. 33 06 48 29 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 2. juni 2016. Jonas

Læs mere

DATALOGI 1E. Skriftlig eksamen torsdag den 3. juni 2004

DATALOGI 1E. Skriftlig eksamen torsdag den 3. juni 2004 Københavns Universitet Naturvidenskabelig Embedseksamen DATALOGI 1E Skriftlig eksamen torsdag den 3. juni 2004 Opgaverne vægtes i forhold til tidsangivelsen herunder, og hver opgaves besvarelse bedømmes

Læs mere

Præsentation Uddelingskopier

Præsentation Uddelingskopier Præsentation Uddelingskopier Se præsentationen med animationer på www.systime.dk Indholdsfortegnelse n Afslutning af: Resultatopgørelsen Balancen Afslutning Fashion SHOE skal nu udarbejde årsregnskab for

Læs mere

Kapitel 8 Vareregnskabet

Kapitel 8 Vareregnskabet Kapitel 8 Vareregnskabet Varekøb Opgave 8.1 1. Registrer følgende bilag for Emil: 12110 Varelager 14261 Købsmoms 12310 Kasse Bilag 212 11.000 2.750 13.750 12110 Varelager 14261 Købsmoms 142203 Computergrossisten

Læs mere

Præsentation Uddelingskopier

Præsentation Uddelingskopier 17.2 Årsregnskab Præsentation Uddelingskopier Se præsentationen med animationer på www.systime.dk 17.2 Årsregnskab Indholdsfortegnelse Resultatopgørelsen Balancen Afslutning & link 17.2 Årsregnskab På

Læs mere

Listen over reserverede ord er meget lang, men de væsentligste vil jeg beskrive her i denne artikel:

Listen over reserverede ord er meget lang, men de væsentligste vil jeg beskrive her i denne artikel: Denne guide er oprindeligt udgivet på Eksperten.dk SQL og ASP En artikel omkring simpel SQL og hvordan disse opbygges, udformes og udføres, sådan at man kan få et brugbart resultat i ASP. Dette ligefra

Læs mere

Side 1. Databaser og SQL. Dagens gang. Databasebegreber. Introduktion til SQL Kap 1-5

Side 1. Databaser og SQL. Dagens gang. Databasebegreber. Introduktion til SQL Kap 1-5 Databaser og SQL Introduktion til SQL Kap 1-5 1 Dagens gang Databaser Database begreber Mapning af klasser til relationel model Normalisering Opgaver til næste gang 2 Databasebegreber A database is a:

Læs mere

Skriftlig eksamen i Erhvervsøkonomi

Skriftlig eksamen i Erhvervsøkonomi Skriftlig eksamen i Erhvervsøkonomi 4 timers skriftlig prøve Dette opgavesæt består af 4 delopgaver, der indgår i bedømmelsen af den samlede opgavebesvarelse med følgende omtrentlige vægte: Opgave 1 30%

Læs mere

Dm071 / Dm072 - Obligatorisk projekt 3: Design af model

Dm071 / Dm072 - Obligatorisk projekt 3: Design af model Dm071 / Dm072 - Obligatorisk projekt 3: Design af model Fag: Projektet omhandler emner fra fagene Software Design og Software Konstruktion. Formål: Formålet med projektet er at give dig mulighed for sammen

Læs mere

Sproget Six. Til brug i rapportopgaven på kurset Oversættere. Vinter 2006. Abstract

Sproget Six. Til brug i rapportopgaven på kurset Oversættere. Vinter 2006. Abstract Sproget Six Til brug i rapportopgaven på kurset Oversættere Vinter 2006 Abstract Six er baseret på det sprog, der vises i figur 6.2 og 6.4 i Basics of Compiler Design. Den herværende tekst beskriver basissproget

Læs mere

Vejledning til kontering af udgiftsbilag

Vejledning til kontering af udgiftsbilag Vejledning til kontering af udgiftsbilag - til bogholderen i den mindre virksomhed Version 2.0 Indholdsfortegnelse Forord:... 3 Råd før læsning:... 3 Fremgangsmåde ved kontering af udgiftsbilag:... 4 1)

Læs mere

Skriftlig prøve i fag nr. 3533 + 3510 + 3511 + 3502 BOGFØRING

Skriftlig prøve i fag nr. 3533 + 3510 + 3511 + 3502 BOGFØRING HA-, HA(dat.)-, HA(jur.)-, BA(int.)-STUDIET 1. DEL Sommereksamen 9. august 2001 Skriftlig prøve i fag nr. 3533 + 3510 + 3511 + 3502 BOGFØRING Varighed: 3 timer Hjælpemidler: Ingen Denne 3-timers prøve

Læs mere

RDS Förlag ApS. Arne Jacobsens Allé 7,5, 2300 København S. Årsrapport for. 17. juni december 2014

RDS Förlag ApS. Arne Jacobsens Allé 7,5, 2300 København S. Årsrapport for. 17. juni december 2014 Edison Park 4 DK-6715 Esbjerg N Tlf. 76 11 44 00 Fax 76 11 44 01 www.martinsen.dk CVR-nr. 32 28 52 01 RDS Förlag ApS Arne Jacobsens Allé 7,5, 2300 København S Årsrapport for 17. juni - 31. december 2014

Læs mere

Årsrapport for 2016/ (1. regnskabsår)

Årsrapport for 2016/ (1. regnskabsår) Årsrapport for 2016/17 28.10.16-30.06.17 (1. regnskabsår) Bygman IVS H. C. Ørsteds Vej 50 C, 1 1879 Frederiksberg C CVR-nr. 38139886 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling

Læs mere

K.H. ApS. Nørrebrogade 18, 1 tv 8000 Aarhus C. Årsrapport 1. januar december 2017

K.H. ApS. Nørrebrogade 18, 1 tv 8000 Aarhus C. Årsrapport 1. januar december 2017 K.H. ApS Nørrebrogade 18, 1 tv 8000 Aarhus C Årsrapport 1. januar 2017-31. december 2017 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 21/03/2018 Kristoffer Nikolaj

Læs mere

Kom godt i gang med Årsregnskabet i Spejdernes Medlemsservice

Kom godt i gang med Årsregnskabet i Spejdernes Medlemsservice Kom godt i gang med Årsregnskabet i Spejdernes Medlemsservice Gode råd ved opgørelsen af årsregnskabet Spejdernes Medlemsservice I/S December 2017 Version 1.1.3 Side 1 af 10 Indholdsfortegnelse 1.1 Opmærksomhedspunkter

Læs mere

Møller og Wulff Logistik ApS

Møller og Wulff Logistik ApS Møller og Wulff Logistik ApS Teglvænget 89 7400 Herning Årsrapport 28. oktober 2016-31. december 2017 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 23/03/2018 Daniel

Læs mere

Algoritmeskabeloner: Sweep- og søgealgoritmer C#-version

Algoritmeskabeloner: Sweep- og søgealgoritmer C#-version Note til Programmeringsteknologi Akademiuddannelsen i Informationsteknologi Algoritmeskabeloner: Sweep- og søgealgoritmer C#-version Finn Nordbjerg 1/9 Indledning I det følgende introduceres et par abstrakte

Læs mere

Anette Sand. Bogen om bogføring for begyndere

Anette Sand. Bogen om bogføring for begyndere Anette Sand Bogen om bogføring for begyndere Bogen om bogføring for begyndere af Anette Sand Regnskabsskolen A/S 2014 Udgivet af Regnskabsskolen Wesselsgade 2 2200 København N Tlf. 3333 0161 www.regnskabsskolen.dk

Læs mere

MD Thai Cucine ApS. Knabrostræde København K. Årsrapport 1. januar december Årsrapporten er godkendt den 19/09/2018

MD Thai Cucine ApS. Knabrostræde København K. Årsrapport 1. januar december Årsrapporten er godkendt den 19/09/2018 MD Thai Cucine ApS Knabrostræde 3 1210 København K Årsrapport 1. januar 2017-31. december 2017 Årsrapporten er godkendt den 19/09/2018 Kritsakda Suraphut Dirigent Side 2 af 11 Indhold Virksomhedsoplysninger

Læs mere

Generelt for eksternt regnskab

Generelt for eksternt regnskab Generelt for eksternt regnskab Der er samme regnskabsprincip om regnskabet aflægges efter A eller B Forskellen er i opstillingen! Begge indebærer oprettelse af anlægskartotek og beregning af udskudt skat

Læs mere

Objektorientering. Programkvalitet

Objektorientering. Programkvalitet 1 PROSA-Bladet nr. 4 1993 Objektorientering = Programkvalitet? Af Finn Nordbjerg, adjunkt ved Datamatikeruddannelsen, Aalborg Handelskole 1. Indledning Objektorientering er blevet et edb-fagets mest udbredte

Læs mere

Løsning af møntproblemet

Løsning af møntproblemet Løsning af møntproblemet Keld Helsgaun RUC, oktober 1999 Antag at tilstandene i problemet (stillingerne) er repræsenteret ved objekter af klassen State. Vi kan da finde en kortest mulig løsning af problemet

Læs mere

PACTA SUNT SERVANDA ApS

PACTA SUNT SERVANDA ApS Halsskovgade 4 3 305 2100 København Ø CVR-nr. 31170672 Årsrapport for 2017 10. regnskabsår Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 15-03-2018 Christian Petri Dirigent

Læs mere

Kim Hersland Holding ApS. Årsrapport for 2017

Kim Hersland Holding ApS. Årsrapport for 2017 Rustenborgvej 9a 2800 Kongens Lyngby CVR-nr. 37352764 Årsrapport for 2017 2. regnskabsår Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 31-05-2018 Kim Hersland Dirigent

Læs mere

Murermester Jensen ApS

Murermester Jensen ApS Murermester Jensen ApS Blødevej 9 3600 Frederikssund Årsrapport 1. juli 2016-30. juni 2017 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 20/11/2017 Thomas Jensen Dirigent

Læs mere

22 Hobe. Noter. PS1 -- Hobe. Binære hobe. Minimum-hob og maximum-hob. Den abstrakte datatype minimum-hob. Opbygning af hobe. Operationen siv-ned.

22 Hobe. Noter. PS1 -- Hobe. Binære hobe. Minimum-hob og maximum-hob. Den abstrakte datatype minimum-hob. Opbygning af hobe. Operationen siv-ned. 22 Hobe. Binære hobe. Minimum-hob og maximum-hob. Den abstrakte datatype minimum-hob. Opbygning af hobe. Operationen siv-ned. Indsættelse i hobe. Sletning af minimalt element i hobe. Repræsentation. 327

Læs mere

BG Logistik ApS Helenevej 5. CVR-nr Årsrapport

BG Logistik ApS Helenevej 5. CVR-nr Årsrapport Multi Revision - Hos os er du i centrum BG Logistik ApS Helenevej 5 4270 Høng CVR-nr. 36682507 Årsrapport 16-03-2015-31-12-2015 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling

Læs mere

Det Rene Videnregnskab

Det Rene Videnregnskab Det Rene Videnregnskab Visualize your knowledge Det rene videnregnskab er et værktøj der gør det muligt at redegøre for virksomheders viden. Modellen gør det muligt at illustrere hvordan viden bliver skabt,

Læs mere

CASEEKSAMEN. FAG erhvervsøkonomi NIVEAU: E

CASEEKSAMEN. FAG erhvervsøkonomi NIVEAU: E CASEEKSAMEN FAG erhvervsøkonomi NIVEAU: E DATO 8. januar 2015 OPGAVE På adr. http://ekstranet.learnmark.dk/eud-eksamen2015/ finder du Opgaven elektronisk Eksamensplan 2.doc - skal afleveres i 1 eksemplar

Læs mere

Erhvervsøkonomi 3. semester Gammel ordning med 4 t. eksamen

Erhvervsøkonomi 3. semester Gammel ordning med 4 t. eksamen Side 1 af 5 sider Syddansk Universitet HD - Studierne Erhvervsøkonomisk Diplomuddannelse HD 1. del Eksamen, januar 2008 Skriftlig reeksamen i faget Erhvervsøkonomi 3. semester Gammel ordning med 4 t. eksamen

Læs mere

Revisorerne Bastian og Krause. Årsrapport 2016/17

Revisorerne Bastian og Krause. Årsrapport 2016/17 Registrerede revisorer ApS Guldborgvej 8 st. tv. 2000 Frederiksberg CVR-nr. 27335616 Årsrapport 2016/17 14. regnskabsår Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den

Læs mere

Indholdsfortegnelse Ledelsespåtegning...3 Virksomhedsoplysninger...4 Anvendt regnskabspraksis...5 Resultatopgørelse...7 Balance...8 Noter

Indholdsfortegnelse Ledelsespåtegning...3 Virksomhedsoplysninger...4 Anvendt regnskabspraksis...5 Resultatopgørelse...7 Balance...8 Noter Forhåbningsholms Allé 2, st. 1904 Frederiksberg C CVR nr. 32082823 Årsrapport for 2015 7. regnskabsår Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 25. april 2016 Ying

Læs mere

PC APPS ApS. Årsrapport 1. juli juni Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 19/12/2014

PC APPS ApS. Årsrapport 1. juli juni Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 19/12/2014 PC APPS ApS Årsrapport 1. juli 2013-30. juni 2014 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 19/12/2014 Peter Carlslund Dirigent Side 2 af 10 Indhold Virksomhedsoplysninger

Læs mere

Abonnementsstyring. Start af Stellar Abonnement. Indledende tekst. Indholdsfortegnelse

Abonnementsstyring. Start af Stellar Abonnement. Indledende tekst. Indholdsfortegnelse Abonnementsstyring Indledende tekst Indholdsfortegnelse Start af Stellar Abonnement... 1 Kom godt i gang med abonnement... 2 Vare/Ydelser i Stellar Office Pro... 2 Abonnements oversigt... 2 Fanebladet

Læs mere

Præsentation Uddelingskopier

Præsentation Uddelingskopier 8.3 Varekøb på kredit Præsentation Uddelingskopier Se præsentationen med animationer på www.systime.dk Indholdsfortegnelse Konto 14220: Varekreditorer Varekøb på kredit (faktura fra en leverandør) Kreditnota

Læs mere

Sproget Rascal (v. 2)

Sproget Rascal (v. 2) Sproget Rascal (v. 2) Til brug i K1 på kurset Oversættere Opdateret 29/11 2004 Abstract Rascal er et simpelt Pascal-lignende imperativt sprog. Dette dokument beskriver uformelt Rascals syntaks og semantik

Læs mere

VIRKSOMHEDENS ØKONOMISTYRING

VIRKSOMHEDENS ØKONOMISTYRING VIRKSOMHEDENS ØKONOMISTYRING LEKTION 3 Likviditetsbudgettering LIKVIDITETSBUDGETTERING Økonomistyring Lektion 3, Likviditetsbudgettering 2 1 LIKVIDITET OG BUDGETTERING LIKVIDITET er en vigtig forudsætning

Læs mere

SKANDERBY KONFIG.PAK 15

SKANDERBY KONFIG.PAK 15 SKANDERBY KONFIG.PAK 15 Nummer Navn Kontotype Type Sammentælling BogføringstypeVirksomhedsbogføringsgruppe Produktbogføringsgruppe Momsvirksomhedsbogf.gruppe Momsproduktbogf.gruppe 10000 Resultatopgørelse

Læs mere

BB Sædding ApS. Årsrapport for 2015/16

BB Sædding ApS. Årsrapport for 2015/16 Fyrvej 34 6710 Esbjerg V CVR-nr. 32776663 Årsrapport for 2015/16 6. regnskabsår Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 30-08-2016 Liselotte Brix Jensen Dirigent

Læs mere

AT BENYTTE VALUTA BETYDER... 2 VALUTAKODER... 2 VALUTAKURSER...

AT BENYTTE VALUTA BETYDER... 2 VALUTAKODER... 2 VALUTAKURSER... Valuta Du kan fakturere og bogføre i fremmed valuta og få det omregnet til regnskabets grundvaluta. I alle posteringsoversigter vises både beløbet i valuta og beløbet i regnskabets grundvaluta (standardvaluta).

Læs mere

EKSTERNT REGNSKAB 5 VARELAGRE

EKSTERNT REGNSKAB 5 VARELAGRE EKSTERNT REGNSKAB 5 VARELAGRE LAGERLIGNINGEN Beholdning primo + Tilgang i perioden = Til rådighed for forbrug - Forbrug i perioden = Beholdning ultimo Gælder for alle balanceposter - såvel for fysiske

Læs mere

RISØR S.M.B.A. Årsrapport 2016/17

RISØR S.M.B.A. Årsrapport 2016/17 Bolandsvej 18 Meløse 3320 Skævinge CVR-nr. 34487308 Årsrapport 2016/17 5. regnskabsår Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 15. oktober 2017 Lotte Risør Helms

Læs mere

Regnskabsanalyse: Common-size analyse og indeksanalyse af regnskab

Regnskabsanalyse: Common-size analyse og indeksanalyse af regnskab Regnskabsanalyse: Commonsize analyse og indeksanalyse af regnskab Commonsize analyse af resultatopgørelse () Commonsize Analyse Virksomhed: Det Lune Brød Virksomhed: Bageriet Kr. % Kr. % 1,125,465.0% 54,545,640.0%

Læs mere

CASEEKSAMEN. Erhvervsøkonomi NIVEAU: E. Torsdag, den 21. maj 2015

CASEEKSAMEN. Erhvervsøkonomi NIVEAU: E. Torsdag, den 21. maj 2015 CASEEKSAMEN Erhvervsøkonomi NIVEAU: E Torsdag, den 21. maj 2015 OPGAVE På adr. http://ekstranet.learnmark.dk/eud-eksamen2015/ finder du Opgaven elektronisk Eksamensplan 2.doc - skal afleveres i 1 eksemplar

Læs mere

Møllegarden IVS. Årsrapport 2016

Møllegarden IVS. Årsrapport 2016 Ørestads Boulevard 55, 30. 6. 2300 København S CVR-nr. 37451657 Årsrapport 2016 1. regnskabsår Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 31. maj 2017 Veronica Antosova

Læs mere

Rekord Rens Nord ApS. Årsrapport 1. juli juni 2017 (Opstillet uden revision eller review)

Rekord Rens Nord ApS. Årsrapport 1. juli juni 2017 (Opstillet uden revision eller review) Kirkepladsen 5A 9900 Frederikshavn CVR-nr. 35816631 Årsrapport 1. juli 2016-30. juni 2017 (Opstillet uden revision eller review) 3. regnskabsår Årsrapporten er fremlagt og godkendt på selskabets ordinære

Læs mere

Præsentation Uddelingskopier

Præsentation Uddelingskopier 30.6 Præsentation af årsregnskabet Præsentation Uddelingskopier Se præsentationen med animationer på www.systime.dk 30.6 Præsentation af årsregnskabet Indholdsfortegnelse Resultatopgørelsen Balancen Afslutning

Læs mere

Undervisningsnote 2: Sammenhængen mellem bogføring og regnskab

Undervisningsnote 2: Sammenhængen mellem bogføring og regnskab HA, 3. SEMESTER 2002 ÅRSREGNSKAB Undervisningsnote 2: Sammenhængen mellem bogføring og regnskab Valdemar Nygaard Temaet vil blive gennemgået med udgangspunkt i lærebogens kapitel 2. Indledning: Den nye

Læs mere

HDR - TVÆRFAGLIG PRØVE, JUNI 2004 Side 1 af 9 LØSNINGSFORSLAG

HDR - TVÆRFAGLIG PRØVE, JUNI 2004 Side 1 af 9 LØSNINGSFORSLAG HDR - TVÆRFAGLIG PRØVE, JUNI 2004 Side 1 af 9 OPGAVE 1 Spørgsmål 1.1 T500 T600 T900 Okt. Nov. Dec. Okt. Nov. Dec. Okt. Nov. Dec. Lager primo 200 450 700 500 250 250 240 390 240 + produktion 1.250 1.250

Læs mere

Årsrapport for (4. regnskabsår)

Årsrapport for (4. regnskabsår) Årsrapport for 2017 01.01.17-31.12.17 (4. regnskabsår) Sulsted Murerfirma ApS Milbakvej 30 9381 Sulsted CVR-nr. 36200758 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den

Læs mere

DEN GODE MODEL: OPSAMLING PÅ MODELLERINGSOPGAVER OG INTRO TIL MODELLERINGSALTERNATIVER

DEN GODE MODEL: OPSAMLING PÅ MODELLERINGSOPGAVER OG INTRO TIL MODELLERINGSALTERNATIVER DEN GODE MODEL: OPSAMLING PÅ MODELLERINGSOPGAVER OG INTRO TIL MODELLERINGSALTERNATIVER KIRSTINE ROSENBECK GØEG Tema Titel Materiale 1 IS i sundhedssektoren Patientdatas anvendelighed Lynge et al. 2 Registrering

Læs mere

Databasesystemer. IT Universitetet i København 16. januar 2006

Databasesystemer. IT Universitetet i København 16. januar 2006 Databasesystemer IT Universitetet i København 16. januar 2006 Eksamenssættet består af 5 opgaver med 16 spørgsmål, fordelt på 6 sider (inklusiv denne side), samt et svarark, hvor visse spørgsmål skal besvares.

Læs mere

Dorthes Bog Centrum har ca forskellige bøger (bibliografiske enheder), som alle skal være søgbare fra prototypen.

Dorthes Bog Centrum har ca forskellige bøger (bibliografiske enheder), som alle skal være søgbare fra prototypen. Afleveringsopgave Hermed afleveringsopgaven for kurset. Besvarelsen, der gerne må udfærdiges i grupper, er del af den mundtlige eksamen (som i øvrigt er individuel). Problemet Efter flere møder med firmaet

Læs mere

Induktive og rekursive definitioner

Induktive og rekursive definitioner Induktive og rekursive definitioner Denne note omhandler matematiske objekter, som formelt er opbygget fra et antal basale byggesten, kaldet basistilfælde eller blot basis, ved gentagen brug af et antal

Læs mere

Denne artikel omhandlende tilgodehavender har følgende indhold:

Denne artikel omhandlende tilgodehavender har følgende indhold: Regnskab Forlaget Andersen 8.6 Tilgodehavender Af revisor Lasse Glud Dybbøl, Beierholm lgd@beierholm.dk Indhold Denne artikel omhandlende tilgodehavender har følgende indhold: 1. Generelt om tilgodehavender

Læs mere

MEDICAL DISTRIBUTION HOLDING ApS

MEDICAL DISTRIBUTION HOLDING ApS MEDICAL DISTRIBUTION HOLDING ApS Årsrapport 1. januar 2014-31. december 2014 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 02/06/2015 Gry Hafstrøm Dirigent Side 2 af

Læs mere

Kontoplan Plus. Felter i Plus+ kontoplanen... 3. Eksternkonto... 3. Effekt... 3. Primo... 3. MomsABC... 3. Årskode... 3. Prv... 3. KontoNavn2...

Kontoplan Plus. Felter i Plus+ kontoplanen... 3. Eksternkonto... 3. Effekt... 3. Primo... 3. MomsABC... 3. Årskode... 3. Prv... 3. KontoNavn2... Kontoplan plus... 2 Felter i Plus+ kontoplanen... 3 Eksternkonto... 3 Effekt... 3 Primo... 3 MomsABC... 3 Årskode... 3 Prv... 3 KontoNavn2... 4 Funktioner i kontoplan plus... 4 Konteringsvejledning...

Læs mere

GRUNDEJERFORENINGEN BAKKEN

GRUNDEJERFORENINGEN BAKKEN GRUNDEJERFORENINGEN BAKKEN Kassereren Bakken 27 3050 Humlebæk ÅRSRAPPORT 2018 Havnegade 2 4300 Holbæk CVR-nr. 33 78 05 24 T: 5943 8100 F: 5943 8191 E: rir@rir.dk www.rir.dk Uafhængigt medlem af RevisorGruppen

Læs mere

DANSK MEDIA DISTRIBUTION ApS

DANSK MEDIA DISTRIBUTION ApS DANSK MEDIA DISTRIBUTION ApS Årsrapport 1. januar 2014-31. december 2014 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 29/05/2015 Emil B. Bredel Dirigent Side 2 af 11

Læs mere

Revisionsfirmaet Per Kronborg ApS. Årsrapport for 2017

Revisionsfirmaet Per Kronborg ApS. Årsrapport for 2017 Fuglebækvej 3A, 1 2770 Kastrup CVR-nr. 26659817 Årsrapport for 2017 16. regnskabsår Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 10-07-2018 Per Kronborg Dirigent Indholdsfortegnelse

Læs mere

EKSTERNT REGNSKAB 10 KONCERNREGNSKABER

EKSTERNT REGNSKAB 10 KONCERNREGNSKABER EKSTERNT REGNSKAB 10 KONCERNREGNSKABER KONCERNREGNSKABER 3 TYPER REGNSKABER I EN KONCERN: a) Et regnskab for modervirksomheden b) Et regnskab for hvert enkelt dattervirksomhed c) Et regnskab for hele koncernen

Læs mere

MQM Biler ApS. Årsrapport 17. marts juni Gl. Landevej Fredericia. CVR-nr

MQM Biler ApS. Årsrapport 17. marts juni Gl. Landevej Fredericia. CVR-nr Gl. Landevej 86 7000 Fredericia CVR-nr. 35805176 Årsrapport 17. marts 2014-30. juni 2015 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 30. november 2015 Qais Ahmad Habibi

Læs mere

CPH Håndværker Gruppen 786 ApS

CPH Håndværker Gruppen 786 ApS CPH Håndværker Gruppen 786 ApS Vesterbrogade 104 1620 København V Årsrapport 1. juli 2017-30. juni 2018 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 07/01/2019 Muhammad

Læs mere

Bridgewalk Invest ApS

Bridgewalk Invest ApS Fagerlien 11 7000 Fredericia CVR-nr. 37117668 Årsrapport for 2017 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 1. maj 2018 Tommy Lyndegaard Dirigent Indholdsfortegnelse

Læs mere

Præsentation Uddelingskopier

Præsentation Uddelingskopier 8.4 Varesalg på kredit Præsentation Uddelingskopier Se præsentationen med animationer på www.systime.dk Indholdsfortegnelse Konto 12210: Varedebitorer Varesalg på kredit (faktura til en kunde) nota til

Læs mere

EKSTERNT REGNSKAB 13 PENGESTRØMSOPGØRELSEN

EKSTERNT REGNSKAB 13 PENGESTRØMSOPGØRELSEN EKSTERNT REGNSKAB 13 PENGESTRØMSOPGØRELSEN PENGESTRØMSOPGØRELSE DET ORDINÆRE REGNSKAB viser: Balance: Resultatopgørelse: Øjeblikkelig økonomisk position Periodens ændring i egenkapitalen Basis: Periodisering

Læs mere

Database for udviklere. Jan Lund Madsen PBS10107

Database for udviklere. Jan Lund Madsen PBS10107 Database for udviklere Jan Lund Madsen PBS10107 Indhold LINQ... 3 LINQ to SQL og Arkitektur... 3 O/R designere... 5 LINQ Den store introduktion med.net 3.5 er uden tvivl LINQ(udtales link): Language-INtegrated

Læs mere

Klient Haslev Festdage UREVIDERET BALANCE Periode...: Dato 01/11-12 Side 1

Klient Haslev Festdage UREVIDERET BALANCE Periode...: Dato 01/11-12 Side 1 ERKLÆRING FRA VIRKSOMHEDENS LEDELSE Jeg skal hermed bekræfte, at bilag og øvrige regnskabsmæssige oplysninger, der ligger til grund for den af revisor opstillede balance, er godkendte. Indehaver/direktør

Læs mere

Kønig & Partnere Advokatfirma I/S Amaliegade 22, 1., 1256 København K

Kønig & Partnere Advokatfirma I/S Amaliegade 22, 1., 1256 København K Kønig & Partnere Advokatfirma I/S Amaliegade 22, 1., 1256 København K CVR-nr. 26 43 86 32 Årsrapport 2015 Årsrapporten er fremlagt og godkendt på selskabets ordinære generalforsamling den 25. april 2016.

Læs mere