Fables Funkcionális programozási nyelv ágens-alapú szimulációkhoz Legéndi Richárd Olivér diplomavédés január 27.
Mi is a Fables? Alapvetően egy funkcionális nyelv: – Funkcionális paradigmák: változók, konstansok, relációk definiálására – Objektum elvűség: ágensek definiálása osztályokkal – Imperatív nyelvi elemek az események leírására Egyszerű, tömör, engedékeny szintaxis – erre törekedtünk Típusnélküliség
Példa model Példa { var x := "String"; konstans = 5; függvény(x) = 2*x; class Ágens { var id; } startUp { new Agent[id:=0]; }
Miért kellett egy új nyelv? A szimulációk eddigi eszközei: – Swarm (1996): az első szimulációs csomag, kísérleti jelleggel – MAML (1999): az első szimulációs nyelv, a Swarmra épül – RePast (2001): Javas szimulációs csomag (API) A problémák: – Elég bonyolultak – Komoly programozói tapasztalatot igényel a használatuk (pl. OO szemlélet, GUI programozás, stb.) – … Elsődleges felhasználói réteg: szociológusok, társadalomkutatók, közgazdászok, …
Cél Egy olyan nyelv létrehozása, amely: – Egyszerű, minimális programozói tapasztalatot feltételez – Nyelvi szinten támogatja ágens-alapú szimulációk létrehozását, irányítását és megfigyelését – Szintaxisa tükrözi a tudományos cikkekben használt formalizmust
Funkcionális paradigmák Változók, konstansok Függvények, Lokális definíciók, Elágazások Felsorolási, intervallum és halmaz típusok var x; méret = 100; randomBit = discreteUniform( 0, 1 ); között(x, y, z) = x < y < z; signum(a) = a -1 | a == 0 => 0 otherwise 1; négyzetszámok = { x^2 : x is [ ] };
Imperatív paradigmák Inicializálás: – seed() beállítása – Paraméterek – Ágensek létrehozása Ütemezők: – Bárhol definiálhatóak – Ciklikus / nem ciklikus – Nevesített: dinamikusan létrehozható/törölhet ő startUp (ágensek) { seed(0); printLn( "Inicializálás..." ); [ new Ágens[ money := 0 ] : _ is [1.. ágensek] ]; } schedule FőÜtemező cyclic 10 { 1 : printLn ("1, 11, 21,...") ; 2 : printLn ("2, 12, 22,...") ; } névListázás = for each a in Ágens do printLn ( a.név ) ;
Példa modell // Vándorló hangyák: ~15 sor kód model Ants { antNum = 100; worldSize = 100; norm (x) = x mod worldSize; class Ant { var pos; move(x) = pos := norm( pos + x ); schedule Stepper cyclic 1 { 1 : move(discreteUniform(-1,0,1)); } antsAt = [ a.pos : a is Ant ]; startUp { seed(1984); [ new Ant[ pos := worldSize/2 ] : i is [1..antNum] ]; }
Az eredmény
A nagyobb részfeladatok Értelmezés: – szintaktikai ellenőrzések – szintaxisfa felhúzása Típusozás – minden kifejezésre, változóra [Charting Wizard] – a lehetséges adatforrások megadása Kódgenerálás, Optimalizáció – modell, GUI, tényleges producerek
Működés Forrásállományok IME Eclipse Compiler Result Fables forrás Java importok Chart leírók Hibalista Modell GUI kód Dokumentációk …
A Compiler Lexer Precompiler Transformator Szintaktikus Elemző Típusozó Informator CP Kódgenerátor Fables forrás Java importok Generált források
Hibajelzés Lexer Precompiler Transformator Szintaktikus Elemző Típusozó Informator Kódgenerátor
A Compiler Lexer Precompiler Transformator Szintaktikus Elemző Típusozó Informator CP Kódgenerátor Fables forrás Java importok Generált források
Dokumentáció generálás Lexer Precompiler Szintaktikus Elemző Típusozó Kódgenerátor Fables forrás Generált doksik
Architektúra IME Fordító Fordító: – Értelmező: source tokenek, szintakszisfa – Előfordító: szintakszisfa reprezentációs fa – Transformator: reprezentációs fán apróbb változtatások – Típusozó: felcímkézi a fát a típusinformációkkal – Fordító Charting Package Új chart létrehozása, meglévő editálása Model informátor: reprezentációs fa chartok – Compiler: reprezentációs objektumok kódobjektumok kódobjektumok generált forrás (Közben optimalizáció) A fordító a végén visszaad egy eredmény objektumot – Hiba és figyelmeztetési listák – Generált forráskódok
Értelmezők JavaCC által generált parser: – Nyelvtan leírás (EBNF) JavaCC Parser Grammar.jjt – Globálisan LL-1 nyelvtan – Lokálisan LL-2 AST objektumok ezekből áll össze a szintaxisfa
Előfordító A szintaxisfa alapján felépítünk egy saját reprezentációt a modell köré. Bejárjuk az egész fát, ez alapján építkezünk. Az eredmény nem egy fa lesz, hanem egy a modellt reprezentáló objektum. A továbbiakban ezen az objektumon dolgozunk.
Transzformációk Apróbb beállítások a modellen, amik feltételezik annak teljességét – Mi legyen konstans, változó ill. függvény? Fablesben definiált konstans nem feltétlen az, sőt! Pl.: random = uniform(0,1); Függőségi halmazok alapján: Ha értéke fordításnál meghatározható => konstans Ha paramétertől függ => inicializálandó változó Ha pl. véletlentől függ => változó Ha olyan konstanstól függ – Lokális változók felcímkézése – …
Típusozás I Az alapötlet: minden típust kideríthetünk az értékadásokból – Konstansok típusa adott (x=5) – Minden változónak csak 1 típusa lehet, azt az értékadásokból derítjük ki (y:=x) – Beépített függvényeknél a típust a paraméterek típusainak ismeretében ki lehet deríteni (z = 2+ 3*x) – Ezek alapján a felhasználói függvények típusai meghatározhatóak rekurzívan ( f(u) = u + 2*z )
Típusozás II Ha még nem ismerjük a paraméterek típusát? – Iteratív feldolgozás Konverziók – x := 5; x:=2.1 – double vagy int? => double upcast – nem castolható eredmények TypeMismatch Mi legyen, ha ugyan az a függvény más-más típusú argumentumokkal szerepel? – Függvénycsaládok generálása pl. f(1);…;f(0.5) => int f(int), double f(double) Értékadás szerű függvények? – Pl. union() halmazokra, mátrix (i,j)-edik elemének beállítása, stb.
Optimalizáció I Függvényekben új lokális konstansok bevezetése – Olyan függvényhívásokra, aminek a függőségei nem változnak a két kódrészlet között Inverz relációk számolása – Adott tulajdonságú ágenseket nem iterálva, hanem hasheléssel keressük meg { a is Agent when a.member == f(x) } => hashset.get(f(x)) { a.member : a is Agent … } => keySet() használatával Ahol lehet, natív tömbhasználat – Vectorok, Set-ek helyett – Nem mindig lehet, függhet a véletlentől, állapotváltozásoktól az iteráció
Optimalizáció II Programinverzió – A felesleges közbülső adatszerkezetek eliminálása Kis ellentmondás: olvasható kód generálása – Haladó felhasználóknak fontos! – Emiatt nem helyettesítjük a konstansokat az értékükkel, nem vonjuk össze a kiértékelhető értékeket, stb.
Segédeszközök Dokumentáció generátló ezsközök – Modellből egy cikk vázlata – Nagyban hasonlít pl. a javadoc-ra – Dokumentációs comment: ”/**” ill. ”*/” – Több formátum: HTML, PDF, RTF, LaTeX forrás Saját Eclipse-alapú fejlesztőkörnyezet RePasttól független megjelenítő csomag: – Egyszerűbb, független – A GUI generálása egy leírófájl alapján történik, amit a Charting Package generál le
Összefoglalás Funkcionális nyelv, tömör szintaxis Típusok nélkül dolgozunk Hasznos eszközkészlettel rendelkezik Köszönöm a figyelmet!