TÍPUSKIKÖVETKEZTETÉSI MÓDSZEREK

Hasonló dokumentumok
Nyelvek típusrendszere (IPM-08sztNYTRE, IPM-08EsztNYTRE)

Kaposi Ambrus. Informatikai Kar. Pannonhalmi Bencés Gimnázium november 24.

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

FUNKCIONÁLIS PROGRAMOZÁS

Kaposi Ambrus. University of Nottingham Functional Programming Lab. Hackerspace Budapest január 6.

Nyelvek típusrendszere (jegyzet)

Programok értelmezése

A Feldspar fordító, illetve Feldspar programok tesztelése

A DEBRECENI MÉRNÖK INFORMATIKUS KÉPZÉS TAPASZTALATAIRÓL. Kuki Attila Debreceni Egyetem, Informatikai Kar. Összefoglaló

Chomsky-féle hierarchia

Segédanyagok. Formális nyelvek a gyakorlatban. Szintaktikai helyesség. Fordítóprogramok. Formális nyelvek, 1. gyakorlat

A szemantikus elemzés elmélete. Szemantikus elemzés (attribútum fordítási grammatikák) A szemantikus elemzés elmélete. A szemantikus elemzés elmélete

A digitális számítás elmélete

Logika és informatikai alkalmazásai kiskérdések február Mikor mondjuk, hogy az F formula a G-nek részformulája?

Kiterjesztések sek szemantikája

A fröccs szintaxisa és operációs szemantikája

FUNKCIONÁLIS PROGRAMOZÁS GYAKORLAT JEGYZET

Az impulzusnyomatékok általános elmélete

... S n. A párhuzamos programszerkezet két vagy több folyamatot tartalmaz, melyek egymással közös változó segítségével kommunikálnak.

FUNKCIONÁLIS PROGRAMNYELVEK IMPLEMENTÁCIÓJA

Formális szemantika. Kifejezések szemantikája. Horpácsi Dániel ELTE Informatikai Kar

Magasabbrendű funkcionális programozás

Általános algoritmustervezési módszerek

3. előadás. Programozás-elmélet. A változó fogalma Kiterjesztések A feladat kiterjesztése A program kiterjesztése Kiterjesztési tételek Példa

Chomsky-féle hierarchia

3. Előadás. Megyesi László: Lineáris algebra, oldal. 3. előadás Lineáris egyenletrendszerek

Alap fatranszformátorok II

Házi feladatok megoldása. Nyelvek használata adatszerkezetek, képek leírására

A TANTÁRGY ADATLAPJA

Automaták és formális nyelvek

KOMPUTER-ALGEBRA RENDSZEREK VERIFIKÁCIÓJA

2019, Funkcionális programozás. 2. el adás. MÁRTON Gyöngyvér

ALAPFOGALMAK 1. A reláció az program programfüggvénye, ha. Azt mondjuk, hogy az feladat szigorúbb, mint az feladat, ha

1. Homogén lineáris egyenletrendszer megoldástere

FUNKCIONÁLIS PROGRAMOZÁS ELŐADÁS JEGYZET

AZ EGYETEM TÖRTÉNETE. Az Eötvös Loránd Tudományegyetem Magyarország legrégebbi folyamatosan m{köd[, s egyben legnagyobb egyeteme.

FFT. Második nekifutás. Czirbusz Sándor ELTE IK, Komputeralgebra Tanszék október 2.

Algoritmuselmélet. Katona Gyula Y. Számítástudományi és Információelméleti Tanszék Budapesti Műszaki és Gazdaságtudományi Egyetem. 13.

2018, Funkcionális programozás

Csempe átíró nyelvtanok

Emlékeztető: LR(0) elemzés. LR elemzések (SLR(1) és LR(1) elemzések)

A Formális nyelvek vizsga teljesítése. a) Normál A vizsgán 60 pont szerezhet, amely két 30 pontos részb l áll össze az alábbi módon:

Házi feladatok megoldása. Nyelvek felismerése. Házi feladatok megoldása. Házi feladatok megoldása. Formális nyelvek, 5. gyakorlat

Funkcionális Nyelvek 2 (MSc)

6. Függvények. Legyen függvény és nem üreshalmaz. A függvényt az f K-ra való kiterjesztésének

Alapok. tisztán funkcionális nyelv, minden függvény (a konstansok is) nincsenek hagyományos változók, az első értékadás után nem módosíthatók

6. Függvények. 1. Az alábbi függvények közül melyik szigorúan monoton növekvő a 0;1 intervallumban?

Logika es sz am ıt aselm elet I. r esz Logika 1/36

Funkcionális és logikai programozás. { Márton Gyöngyvér, 2012} { Sapientia, Erdélyi Magyar Tudományegyetem }

Diszkrét Matematika MSc hallgatók számára. 4. Előadás

2. Rekurzió. = 2P2(n,n) 2 < 2P2(n,n) 1

HALLGATÓI KÉRDŐÍV ÉS TESZT ÉRTÉKELÉSE

1. Példa. A gamma függvény és a Fubini-tétel.

Java programozási nyelv

Vektorterek. Több esetben találkozhattunk olyan struktúrával, ahol az. szabadvektorok esetében, vagy a függvények körében, vagy a. vektortér fogalma.

NP-teljesség röviden

Hadamard-mátrixok Előadó: Hajnal Péter február 23.

S0-02 Típusmodellek (Programozás elmélet)

Algoritmusok és adatszerkezetek II.

Egyenletek, egyenlőtlenségek, egyenletrendszerek I.

Dualitás Dualitási tételek Általános LP feladat Komplementáris lazaság 2017/ Szegedi Tudományegyetem Informatikai Intézet

Formális nyelvek - 5.

MŰSZAKI TUDOMÁNY AZ ÉSZAK-ALFÖLDI RÉGIÓBAN 2010

Logika es sz am ıt aselm elet I. r esz Logika Harmadik el oad as 1/33

A STRATÉGIAALKOTÁS FOLYAMATA

FUNKCIONÁLIS PROGRAMNYELVEK IMPLEMENTÁCIÓJA

A SZAKDOLGOZAT SZERKESZTÉSE

A logikai következmény

Differenciálegyenletek megoldása próbafüggvény-módszerrel

Programtervező informatikus MSc nappali tagozat ajánlott tanterv 2018

Programtervező informatikus MSc nappali tagozat ajánlott tanterv 2018

Diszkrét matematika 2. estis képzés

Predikátumkalkulus. 1. Bevezet. 2. Predikátumkalkulus, formalizálás. Predikátumkalkulus alapfogalmai, formalizálás, tagadás, logikailag igaz formulák.

Elsőrendű logika szintaktikája és szemantikája. Logika (3. gyakorlat) 0-adrendű szemantika 2009/10 II. félév 1 / 1

Diszkrét matematika 2.C szakirány

II. Két speciális Fibonacci sorozat, szinguláris elemek, természetes indexelés

f(x) vagy f(x) a (x x 0 )-t használjuk. lim melyekre Mivel itt ɛ > 0 tetszőlegesen kicsi, így a a = 0, a = a, ami ellentmondás, bizonyítva

Diszkrét matematika 2.C szakirány

Diszkrét matematika I.

Diszkrét matematika I.

2016, Funkcionális programozás

Algoritmusok helyességének bizonyítása. A Floyd-módszer

Függvények július 13. f(x) = 1 x+x 2 f() = 1 ()+() 2 f(f(x)) = 1 (1 x+x 2 )+(1 x+x 2 ) 2 Rendezés után kapjuk, hogy:

minden x D esetén, akkor x 0 -at a függvény maximumhelyének mondjuk, f(x 0 )-at pedig az (abszolút) maximumértékének.

A Formális nyelvek vizsga teljesítése. a) Normál A vizsgán 60 pont szerezhet, amely két 30 pontos részb l áll össze az alábbi módon:

MBNK12: Permutációk (el adásvázlat, április 11.) Maróti Miklós

ÍTÉLETKALKULUS (NULLADRENDŰ LOGIKA)

Program ekvivalencia és logikai relációk

A törzsszámok sorozatáról

Kifejezések. Kozsik Tamás. December 11, 2016

A fordítóprogramok szerkezete. Kódoptimalizálás. A kódoptimalizálás célja. A szintézis menete valójában. Kódoptimalizálási lépések osztályozása

Diszkrét matematika I.

6. Előadás. Megyesi László: Lineáris algebra, oldal. 6. előadás Bázis, dimenzió

Formális nyelvek - 9.

Az optimális megoldást adó algoritmusok

2012. október 2 és 4. Dr. Vincze Szilvia

Számelméleti alapfogalmak

Nagy Gábor compalg.inf.elte.hu/ nagy

Fordító részei. Fordító részei. Kód visszafejtés. Izsó Tamás szeptember 29. Izsó Tamás Fordító részei / 1

8. Egyenletek, egyenlőtlenségek, egyenletrendszerek II.

Átírás:

TÍPUSKIKÖVETKEZTETÉSI MÓDSZEREK THE METHODS OF TYPE INFERENCE Csörnyei Zoltán 1, Nagy Sára 2 ELTE Informatikai Kar, Programozási Nyelvek és Fordítóprogramok Tanszék 1 ELTE Informatikai Kar, Algoritmusok és Alkalmazásaik Tanszék 2 Összefoglaló Előadásunkban a típuselmélet egyik speciális területével, a típuskikövetkeztetéssel foglalkozunk. Nem minden programnyelvben kötelező a típusok megadása, vannak olyan nyelvek is, ahol egyáltalán nem kell a programozónak a típusokkal foglalkoznia. Viszont a típusok, a lehetséges típusok ismerete feltétlenül szükséges a program helyességének a vizsgálatához. A típuskikövetkeztetés feladata a típusok pontos meghatározása. Először a legegyszerűbb módszert, a Curry-típuskikövetkeztetést mutatjuk be, majd a polimorfikus let-utasításon tanulmányozzuk a Hindley-Milner-algoritmust. Megadunk környezetfüggő és környezetfüggetlen módszereket, és megmutatjuk a korlátozások generálásának és az egységesítésnek az alkalmazását. Foglalkozunk a rekurzióval is, megadjuk a mai modern programnyelvekben alkalmazott Hindley-Mycroft-típuskikövetkeztető eljárást is. Típuskikövetkeztetéssel, különböző részletességgel, az ELTE Doktori Iskolájában, a programtervező informatikus MSc-képzésben foglalkozunk, és egy rövid összefoglaló szerepel a programtervező matematikus szak tantervében is. Kulcsszavak típuselmélet, típuskikövetkeztetés, fordítóprogramok Abstract We will discuss a particular area of the type theory, the type inference. Prescribing the types is not always mandatory: There are languages in which not all of types have to be given. In some languages the programmer does not need to consider types at all. However, the knowledge of the possible types is essential for checking the correctness of softwares. Type inference describes the types exactly. First we present the simplest method, the Curry-inference method, then we study the Hindley- Milner algorithm on the polymorphic let-statement. We present context dependent and context free methods, and the applications of generating constrains and of unification. We will consider recursion, and will present the Hindley-Mycroft type inference that is used by modern programming languages. In Eotvos University, we teach type inference - in different depths in PhD courses and in an MSc course. The curriculum of BSc degree also includes a brief summary of type inference. Keywords type theory, type inference, compilers 1

Bevezetés A típus már a kezdetektől fogva a számítástudomány központi fogalma. A típusrendszerek vizsgálata az utóbbi évek fontos kutatási területévé vált, az eredmények sikeresen alkalmazhatók a programozási nyelvek tervezésében, nagyhatékonyságú fordítóprogramok implementációjában és a típus nem utolsósorban a biztonságos programok létrehozásának egyik eszköze. Közismert Robin Milnernek az a mondása, hogy egy jól típusozott program nem futhat rosszul. Ezt az állítást már sokan finomították, pontosabbá tették, precízebben megfogalmazták, de ez a kijelentés jól mutatja a típusnak, a típuselméletnek a programozási nyelvekben betöltött szerepét. 1. A Curry-típusrendszer Nem minden programnyelvben kötelező a típusok megadása, vannak olyan nyelvek, ahol nem kell minden típust megadni, és vannak, ahol egyáltalán nem kell a programozónak a típusokkal foglalkoznia. A típusok, a lehetséges típusok ismerete viszont feltétlenül szükséges a program helyességének a vizsgálatához, a típuskikövetkeztetés feladata a típusok pontos meghatározása. A Curry-típusos λ-kalkulust röviden Curry-típusrendszernek nevezzük. A Currytípusrendszer típusai nem alaptípusokból, hanem típusváltozókból épülnek fel. A típusváltozók konkrét típusértéket majd a típuskikövetkeztetés folyamán kapnak. A Curry-típusrendszer szintaxisa: <típus>::= <típuváltozó> ( <típus> <típus>) <λ kifejezés >::= <változó> ( λ<változó>.<λ kifejezés > ) ( <λ kifejezés > <λ kifejezés >) A kifejezések típusát mindig egy <váltózó>:<típus> párokból álló típuskörnyezetből kiindulva a Curry-típusrendszer szabályainak felhasználásával bizonyítjuk. A kifejezések szabad változóinak típusa a típuskörnyezetből olvasható ki. A környezet üres is lehet. A Curry-típusrendszerben is háromfajta következtetés van, az első kettő a szintaktikus helyességgel foglalkozik, a harmadik egy jól formált kifejezés típusát adja meg: Ha -ból E:τ, akkor -ban az E kifejezés típusaτ. Azt mondjuk, hogy egy E:τ következtetés érvényes a típuskörnyezetben, ha bizonyítható a Curry-típusrendszer szabályaival. A típus meghatározásával kapcsolatban három kérdés merül fel, ezekben a típuskörnyezet mindig üres: 1. típuskikövetkeztetés: ha adott az E kifejezés, van-e olyan A típus, melyre E:A, 2. típusellenőrzés: ha adott az E kifejezés és az A típus, akkor teljesül-e az, hogy E:A, 3. típus-reprezentáció: ha adott az A típus, van-e olyan E kifejezés, melyre E:A. 2

2. A Curry-típuskikövetkeztetés A fentiek szerint legyen E a Curry-típusrendszer egy kifejezése, és azt vizsgáljuk, hogy van-e olyan A típus, hogy E:A. Típusváltozók szimultán helyettesítését az [α 1 :=A 1,, α n := A n ] leírással adjuk meg, és ha s egy típusváltozó helyettesítés, akkor az A típus s helyettesítését As alakban írjuk le. Azt mondjuk, hogy az A típus a B típus variánsa, ha van olyan s 1 és s 2 helyettesítések, hogy As 1 B és Bs 2 A. Ha pedig As Bs, akkor s az A és B egyesítő helyettesítése. Az A típus általánosabb típus a B típusnál, ha létezik olyan s helyettesítés, hogy B As. Ezt a tulajdonságot B A val jelöljük. Ha üres típuskörnyezetből következik, hogy E:A és A a legáltalánosabb típus, akkor A-t principális típusnak nevezzük. A feladat tehát az, hogy meghatározzuk, kikövetkeztessük az E kifejezés principális típusát. A típuskikövetkeztetés két műveletre, a korlátozások generálására és az egyesítésre bontható fel. A korlátozások típusok közötti egyenlőségek. A korlátozások generálása azt jelenti, hogy a típusrendszer levezetési szabályainak felhasználásával az E kifejezésre és részkifejezéseire nem adunk meg konkrét típusokat, hanem új típusváltozók alkalmazásával egyenleteket generálunk. A korlátozások egyenletrendszerét az egyesítés lépése oldja meg. Az egyesítés a generált típusváltozókhoz konkrét típuskifejezéseket rendel, az E-hez tartozó típusváltozóhoz rendelt típuskifejezés lesz majd az E típusa. A korlátozások generálását a T(,E,A ) leképezéssel végezzük, ahol egy típuskörnyezet, E egy kifejezés és A egy típus. A T(,E,A ) leképezést az E szerkezete szerint adjuk meg: 1. T(,x,A ) {A = (x)} 2. T(, x.e,a ) T({,x: },E, ) {A = },ahol és új típusváltozók, 3. T(,EF,A ) T(,E, A ) T(,F, ),ahol új típusváltozó. Az egyesítés feladat a korlátozások egyenletrendszerének olyan megoldása, ami a korlátozásokat adó kifejezés principális típusa lesz. Ha egy E kifejezés korlátozásait a fenti leképezéssel határozzuk meg és eredményül egy egyenletrendszert kapunk, akkor az egyesítés eljárással meghatározzuk az egyenletrendszer legáltalánosabb megoldását, és ebből már meg tudjuk határozni a principális típust. 3. A let-kifejezés bevezetése 3.1. Az egyszerű let-kifejezés és típuskikövetkeztetése A Curry-típusos λ-kalkulust egy új kifejezéssel bővítjük, a let-kifejezéssel. Ezt az indokolja, hogy a let-kifejezés a legtöbb funkcionális programnyelvben benne van, és kezelése az eddig megismert módszerekkel nem valósítható meg. A let-kifejezés szintaktikája: let <változó> = <λ kifejezés 1 > in <λ kifejezés 2 > 3

Először csak olyan let-kifejezéssel foglalkozunk, amelyekben a <változó> nem szerepel a <λ kifejezés 1 > - ben, azaz nincs rekurzió, és feltesszük, hogy a <változó> típusa monomorf. A let-kifejezés operációs szemantikája: let x = E in F F[x := E], és a let-kifejezés típusszabálya: Ha Γ-ból E:A és Γ,x:A-ból F:B, akkor Γ-ból let x=e inf :B. Látható, hogy a λ absztrakcióhoz hasonlóan, a típuskörnyezet x:a eleme beépül a letkifejezésbe. Ennek a let-kifejezésnek a korlátozás-generálása nagyon egyszerű. Legyen α egy új típusváltozó, és tegyük fel, hogy a let-kifejezés típusa A, ekkor a let-kifejezéshez a következő két korlátozás-generálás adható meg: T( Γ, E,α ) és T( {Γ, x:a }, F, A ), ezeknek a megoldása pedig az előző pontban már szerepelt. A korlátozások generálása után a principális típus most is az egységesítés műveletével határozható meg. 3.2. Probléma a let-tel, a polimorfikus let-kifejezés bevezetése A fenti let-kifejezés nagyon jónak tűnik, de sajnos már olyan egyszerű kifejezésre sem alkalmazható, mint például a következő: let f = λx.x in pair (f 0) (f True). A λx.x típusa α α, így az (f 0) típusa Nat Nat, de az (f True) típusa Bool Bool. Az f monomorf típusa miatt ez nem lehetséges. Ezért itt (de csak itt) meg kell engedni a változó polimorf típusát. Ez a let-polimorfizmus, és ez először az ML programnyelvben jelent meg. Ha az f polimorf, akkor a pair (f 0) (f True) kifejezés típusozható, és típusa Pair_Nat_Bool. Ehhez azonban a típus fogalmát is módosítani kell. Az eddigi típust egyszerű típusnak nevezzük, és bevezetjük a típusséma, azaz a polimorfikus típus fogalmát: <típusséma> := <egyszerű típus> <típusváltozó>. <típusséma> A típussémát a σ jellel jelöljük Látható, hogy a kvantor csak a típussémák baloldalán szerepelhet. A kvantor egy kötést valósít meg, a <típusváltozó> kötött lesz az utána következő <típussémá>-ban. Ezt a kötést a típusváltozó helyettesítésekor is figyelembe kell venni. Megadhatjuk egy típusséma gen(γ,σ) általánosítását úgy, hogy univerzális kvantorokkal kötjük a szabad típusváltozóit, és beszélhetünk egy típusséma inst(σ) példányosításáról: ahol a kvantorokkal kötött típusváltozókat egyedi új típusváltozókkal helyettesítjük. Ezeknek a fogalmaknak a bevezetésével már megadhatjuk a polimorfikus let-kifejés típuskikövetkeztetését. 4

4. A Hindley-Milner-típuskikövetkeztetés A típuskikövetkeztetés módszerét egymástól függetlenül 1969-ben Hindley, majd 1978- ban Milner publikálta, innen származik Hindley-Milner típuskikövetkeztetés elnevezés. Milner volt az első, aki Robinson egységesítését is alkalmazta, beépítve a típuskikövetkeztést az ML fordítóprogramjának elemző algoritmusai közé. Curry is foglalkozott a típuskikövetkeztetéssel, ezért ezt a módszert gyakran Curry--Hindley típuskikövetkeztetésnek is nevezik. A principális típus tétel bizonyítását Damas adta meg, ezért sokan ennek a módszernek a Damas-Milner típuskikövetkeztetés nevet adták. 4.1. A típusrendszer szabályai Csak a három legfontosabb típusszabályt adjuk meg: Ha Γ-ból E:σ, akkor Γ-ból E:gen(Γ,σ), ha Γ-ból E:σ, akkor Γ-ból E:inst(σ), ha Γ-ból E:σ és Γ,x:σ-ból F: σ, akkor Γ-ból let x = E in F :σ. Látható, hogy a típusséma előfordulhat a kifejezések típusában is, nem csak a típuskörnyezetekben. Ez nehézkessé teszi a típuskikövetkeztetést, ráadásul a kifejezés szintaktikájából egyáltalán nem látszik, hogy mikor kell az általánosítás vagy a példányosítás szabályát alkalmazni. Ezért módosítsuk a let-kifejezés típusszabályát úgy, hogy ez a kifejezés írja bele a típuskörnyezetbe a polimorfikus típust, és hogy a polimorfikus típus ne szerepeljen kifejezések típusában, csak a típuskörnyezetben. ha Γ-ból E:σ és {Γ,x: gen(γ,σ)}-ból F: σ, akkor Γ-ból let x = E in F :σ. A típuskörnyezetből egy változó típusát kiolvashatjuk, de ekkor mindig a példányosítás műveletét kell alkalmazni. 4.2. A W-algoritmus Milner két algoritmust is adott a típuskikövetkeztetésre. Először a W-algoritmussal foglalkozunk. Az algoritmust mintákkal, a kifejezés szerkezete szerint adjuk meg. Az algoritmus egy típuskörnyezetre és a kifejezésre egy típusváltozó helyettesítését határozza meg, vagy hibajelzéssel megáll. Az algoritmust nem részletezzük, csupán két mintára vonatkozó lépését adjuk meg: W(Γ,x) = (Id, inst(σ)), ahol {x:σ} a Γ-ban van. W(Γ,let x=e inf) = (s 1, s 2, τ ), ahol W(Γ,E) = (s 1,τ ) és W({Γs 1,x:gen(Γs 1,τ },F) = (s 2,τ ) A megadott két lépésből is látható, hogy az univerzális kvantoros típusséma a let-kifejezés feldolgozásánál kerül bele a típuskörnyezetbe, és egy változó típusának a típuskörnyezetből való meghatározásánál a példányosítás műveletét alkalmazzuk. Ezek biztosítják azt, hogy például a fenti 5

f = λx.x in pair (f 0) (f True) kifejezésben az f típusa α.α α lesz, és az f 0 kifejezésben az f típusának meghatározásakor a példányosítás művelete az α-hoz a Nat, az f True kifejezésben pedig a Bool típust rendeli hozzá A W-algoritmus helyes, azaz ha W(Γ,E) = (s,τ), akkor Γs-ből valóban az következik, hogy E:τ, és az algoritmus teljes, vagyis a legáltalánosabb típust határozza meg. 4.3. A J-algoritmus A J-algoritmust is Milner definiálta 1978-ban, mint a W-algoritmus egy egyszerűbb formáját, ugyanabban a cikkben, amelyben a W-algoritmus is először szerepel. A J- algoritmust a Haskell programnyelv implementációjában használták. A típuskikövetkeztetés is használ egy s helyettesítést, mint egy globális változót, a típuskikövetkeztetés indításakor s = Id. A helyettesítést azonban csak az egységesítés argumentumainak megadásában használjuk, és ellentétben a W-algoritmussal, a helyettesítés a principális típus végső meghatározásában már nem szerepel. Most is csak két mintára vonatkozó lépést adunk meg: J(Γ,x) = inst(σ), ahol {x:σ} a Γ-ban van, J(Γ,let x=e inf) = τ, ahol J(Γ,E) = τ és W({Γ,x:gen(Γs_1,τ s},f) = τ. Az algoritmus közvetlenül a kifejezés típusát adja meg, és bizonyítható, hogy az algoritmus helyes és teljes. 4.4. Az M-algoritmus Mind a W-, mind a J-algoritmus az EF applikációra úgy működik, hogy először végigszámolta az E-t, majd végigszámolja az F-t, és csak ezután ellenőrzi, hogy az E típusa függvény-e, vagyis az E típus α α alakú-e. Ezért ezeket a típuskikövetkeztetéseket környezetfüggetlen típuskikövetkeztetéseknek nevezzük, hiszen a kifejezések típusát anélkül határozzák meg, hogy megvizsgálnák, azok milyen környezetben vannak. Ezeket az algoritmusokat alulról-felfelé haladó algoritmusoknak is tekinthetjük, hiszen például ha az EF applikációt gráffal ábrázoljuk, az algoritmusok először az E-t, a bal oldali részfát járják be, utána foglalkoznak a jobb oldali F részfájával, és csak ezután lépnek egy szinttel feljebb az applikáció műveletéhez, és csak most vizsgálják meg az applikáció lehetőségét. Ez a működés a hiba felfedezésére is erősen kihat, hiszen ha az applikáció nem lehetséges, ezt a kikövetkeztető algoritmus csak sok munka után, az E és F teljes feldolgozása után fedezi fel. A típuskikövetkeztető rendszer sokkal hamarabb észrevenné a hibát, ha egy EF applikáció esetén az E feldolgozása után azonnal ellenőrizné, hogy az E típusa vajon függvény-e. Ez a gondolat az alapja a típuskikövetkeztetés M-algoritmusának, amit Lee és Yi dolgozott ki 1998-ban. 6

Az M-algoritmus a környezetből meghatározza a várható típust, ezt a típust továbbítja a kifejezés felé, és hibát jelez, ha a kifejezés típusa nem felel meg a várt típusnak. Az algoritmust ezért környezetfüggő típuskikövetkeztetésnek nevezzük. A módszer lényegében egy felülről-lefelé haladó típuskikövetkeztetés. Az EF applikáció gráfját tekintve az algoritmus először meghatározza az applikáció elemeinek várható típusát, és csak ezután járja be az E bal oldali részfát. Csak akkor folytatja a típuskikövetkeztetést a jobb oldali részfával, azaz az F kifejezéssel, ha az E típusa megfelel a várt típusnak. 5. A rekurzió bevezetése és a Milner-Mycroft típuskikövetkeztetés A rekurzív kifejezések típusának leírására a fenti rendszerek nem alkalmasak, ezért bővítsük a rendszerünket a rekurziót leíró fix-kifejezéssel. A fix-kifejezés szintaktikája: fix <változó>. <λ kifejezés>, és operációs szemantikája fix x. E E [x:= fix x. E ]. A fix-kifejezés klasszikus monomorf típusszabályát Mycroft módosította polimorfikus típusokra: ha Γ,x:σ-ból E: σ, akkor Γ-ból fix x. E:σ. A típusok tehát típussémák, és ez biztosítja a polimorfikus típusos rekurzív függvények leírását. Ezt a típusrendszert nevezzük Milner-Mycroft típusrendszernek. A let-kifejezéshez hasonlóan, a fix-kifejezés típusszabálya is módosítható úgy, hogy a kvantoros típussémák csak a típuskörnyezetben szerepeljenek. Ez a típuskikövetkeztetés szintaxisvezérelt végrehajtását teszi lehetővé. A Milner-Mycroft típusrendszer megtartja a Hindley-Milner típusrendszer legtöbb tulajdonságát, például itt is teljesül a tárgy-redukció tétele, és itt is igaz, hogy a típusosan helyes kifejezések nem okoznak run-time típus-hibát. Azonban, míg a Curry- és a Hindley- Milner típusrendszer típus-kikövetkeztetése eldönthető és a probléma általában polinomiális, néhány speciális esetben exponenciális időbonyolultságú, addig a Milner-Mycroft típuskikövetkeztetés nem eldönthető, azaz vannak olyan problémák, amelyekre a kikövetkeztetés nem terminál. Irodalomjegyzék [1] L. Cardelli: Type Systems, Handbook of Computer Science and Engineering, CRC Press, 1997. [2] Z. Csörnyei: Lambda-kalkulus, Typotex, Budapest, 2007. [3] Z. Csörnyei: Típuselmélet (kézirat), 2008. [4] B. C. Pierce: Types and Programming Languages, The MIT Press, Cambridge, 2002. [5] B. C. Pierce (editor):advanced Topics in Types and Programming Languages, The Mit Press, 2005. 7