3.4 Muuttujat 3.4. MUUTTUJAT Sidonta Esittely sitoo (binds) nimeen joitakin ominaisuuksia (attributes). Jotkin ominaisuudet

Samankaltaiset tiedostot
3.5. TYYPIT 43. g(x) muuten. että tämä funktio todella kuuluu funktioalueeseen.

samalla seuraavaan puoliavaruuteen (sukupolveen), jota siivotaan harvemmin.

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

1 Määrittelyjä ja aputuloksia

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

2. Minkä joukon määrittelee kaava P 0 (x 0 ) P 1 (x 0 ) mallissa M = ({0, 1, 2, 3}, P M 0, P M 1 ), kun P M 0 = {0, 1} ja P M 1 = {1, 2}?

Rekursiiviset tyypit

TIEA341 Funktio-ohjelmointi 1, kevät 2008

Analyysi 1. Harjoituksia lukuihin 1 3 / Syksy Osoita täsmällisesti perustellen, että joukko A = x 4 ei ole ylhäältä rajoitettu.

14.1 Rekursio tyypitetyssä lambda-kielessä

Täydellisyysaksiooman kertaus

Luku 3. Listankäsittelyä. 3.1 Listat

Matematiikan tukikurssi, kurssikerta 3

Konvergenssilauseita

Diskreetin matematiikan perusteet Laskuharjoitus 2 / vko 9

missä on myös käytetty monisteen kaavaa 12. Pistä perustelut kohdilleen!

Matematiikan tukikurssi

Matematiikan tukikurssi

Matematiikan tukikurssi, kurssikerta 2

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

TIES542 kevät 2009 Denotaatio

ITKP102 Ohjelmointi 1 (6 op)

Luonnollisten lukujen ja kokonaislukujen määritteleminen

MS-A0402 Diskreetin matematiikan perusteet Esimerkkejä, todistuksia ym., osa I

MS-A0402 Diskreetin matematiikan perusteet Esimerkkejä, todistuksia ym., osa I

2.4 Normaalimuoto, pohja ja laskentajärjestys 2.4. NORMAALIMUOTO, POHJA JA LASKENTAJÄRJESTYS 13

Lukujonon raja-arvo 1/7 Sisältö ESITIEDOT: lukujonot

Matemaatiikan tukikurssi

Tämän vuoksi kannattaa ottaa käytännöksi aina kirjoittaa uuden funktion tyyppi näkyviin, ennen kuin alkaa sen määritemää kirjoittamaan.

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

Ohjelmoinnin peruskurssien laaja oppimäärä

Olio-ohjelmointi Syntaksikokoelma

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Matematiikan johdantokurssi, syksy 2016 Harjoitus 11, ratkaisuista

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

Vaihtoehtoinen tapa määritellä funktioita f : N R on

TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 26. kesäkuuta 2013

Rekursio. Funktio f : N R määritellään yleensä antamalla lauseke funktion arvolle f (n). Vaihtoehtoinen tapa määritellä funktioita f : N R on

Ohjelmoinnin peruskurssien laaja oppimäärä

Kuvaus eli funktio f joukolta X joukkoon Y tarkoittaa havainnollisesti vastaavuutta, joka liittää joukon X jokaiseen alkioon joukon Y tietyn alkion.

missä on myös käytetty monisteen kaavaa 12. Pistä perustelut kohdilleen!

TIES542 kevät 2009 Rekursiiviset tyypit

Matematiikan tukikurssi

Yhtälönratkaisusta. Johanna Rämö, Helsingin yliopisto. 22. syyskuuta 2014

12. Monimuotoisuus 12.1

Alkioiden x ja y muodostama järjestetty pari on jono (x, y), jossa x on ensimmäisenä ja y toisena jäsenenä.

Kuvaus eli funktio f joukolta X joukkoon Y tarkoittaa havainnollisesti vastaavuutta, joka liittää joukon X jokaiseen alkioon joukon Y tietyn alkion.

Geneeriset tyypit. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Kaikki kurssin laskuharjoitukset pidetään Exactumin salissa C123. Malliratkaisut tulevat nettiin kurssisivulle.

sama tyyppi (joka vastaa kaikkien mahdollisten arvojen summa-aluetta). Esimerkiksi

Yksinkertaiset tyypit

Lyhyt kertaus osoittimista

1 Supremum ja infimum

Kesälukio 2000 PK2 Tauluharjoituksia I Mallivastaukset

Ydin-Haskell Tiivismoniste

Logiikan kertausta. TIE303 Formaalit menetelmät, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos.

ITKP102 Ohjelmointi 1 (6 op)

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta

T Syksy 2004 Logiikka tietotekniikassa: perusteet Laskuharjoitus 7 (opetusmoniste, kappaleet )

Laajennetaan vielä Ydin-Haskellia ymmärtämään vakiomäärittelyt. Määrittely on muotoa

Haskell ohjelmointikielen tyyppijärjestelmä

MS-A0402 Diskreetin matematiikan perusteet Esimerkkejä ym., osa I

Matematiikan tukikurssi

Ohjelmoinnin peruskurssien laaja oppimäärä

DIFFERENTIAALI- JA INTEGRAALILASKENTA I.1. Ritva Hurri-Syrjänen/Syksy 1999/Luennot 6. FUNKTION JATKUVUUS

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 16. maaliskuuta 2011

1 sup- ja inf-esimerkkejä

Joukot. Georg Cantor ( )

Luku 2. Ohjelmointi laskentana. 2.1 Laskento

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A.

1 sup- ja inf-esimerkkejä

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Funktiot. funktioita f : A R. Yleensä funktion määrittelyjoukko M f = A on jokin väli, muttei aina.

TIES542 kevät 2009 Tyyppijärjestelmän laajennoksia

Luku 2. Jatkuvien funktioiden ominaisuuksia.

MS-A0402 Diskreetin matematiikan perusteet Esimerkkejä ym., osa I

ITKP102 Ohjelmointi 1 (6 op)

Ohjelmoinnin peruskurssien laaja oppimäärä

Diskreetin matematiikan perusteet Malliratkaisut 2 / vko 38

Approbatur 3, demo 1, ratkaisut A sanoo: Vähintään yksi meistä on retku. Tehtävänä on päätellä, mitä tyyppiä A ja B ovat.

Todista raja-arvon määritelmään perustuen seuraava lause: Jos lukujonolle a n pätee lima n = a ja lima n = b, niin a = b.

Ohjelmoinnin peruskurssien laaja oppimäärä

Oliot ja tyypit. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos

z 1+i (a) f (z) = 3z 4 5z 3 + 2z (b) f (z) = z 4z + 1 f (z) = 12z 3 15z 2 + 2

Reaaliluvut. tapauksessa metrisen avaruuden täydellisyyden kohdalla. 1 fi.wikipedia.org/wiki/reaaliluku 1 / 13

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIE448 Kääntäjätekniikka, syksy Antti-Juhani Kaijanaho. 27. lokakuuta 2009

MS-A010{3,4} (ELEC*) Differentiaali- ja integraalilaskenta 1 Luento 3: Jatkuvuus

Jatkeet. TIES341 Funktio ohjelmointi 2 Kevät 2006

T Syksy 2005 Logiikka tietotekniikassa: perusteet Laskuharjoitus 8 (opetusmoniste, kappaleet )

Reaaliarvoisen yhden muuttujan funktion raja arvo LaMa 1U syksyllä 2011

saadaan kvanttorien järjestystä vaihtamalla ehto Tarkoittaako tämä ehto mitään järkevää ja jos, niin mitä?

Demo 7 ( ) Antti-Juhani Kaijanaho. 9. joulukuuta 2005

Reaalilukuvälit, leikkaus ja unioni (1/2)

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 8. syyskuuta 2016

Ohjelmoinnin peruskurssien laaja oppimäärä

ABHELSINKI UNIVERSITY OF TECHNOLOGY

Vieruskaverisi on tämän päivän luennolla työtoverisi. Jos sinulla ei ole vieruskaveria, siirry jonkun viereen. Esittäytykää toisillenne.

4.3. Matemaattinen induktio

Transkriptio:

3.4. MUUTTUJAT 35 3.3.2 Sidonta Esittely sitoo (binds) nimeen joitakin ominaisuuksia (attributes). Jotkin ominaisuudet ovat staattisia: nämä ominaisuudet ovat täysin määrättyjä jo ennen suoritusaikaa. Loput ominaisuudet ovat dynaamisia ja ovat osittain tai kokonaan määrättävissä vain suoritusaikana. Esimerkiksi symboliset vakiot ovat nimiä, joihin liittyy yksi oleellinen staattinen ominaisuus: arvo. 3.4 Muuttujat Muuttujat ovat nimiä. Jokaiseen muuttujaan on sidottu olio. Muuttujan arvolla tarkoitetaan muuttujaan sidotun olion arvoa. Käytännössä muuttujan sidonta olioon toteutetaan siten, että muuttujaan liittyy staattisena ominaisuutena olion osoite. Joissakin tilanteissa se on kuitenkin toteutettu laatikoinnilla (boxing): muuttujaan liittyy apuolio, joka sisältää pelkästään tuon varsinaisen olion osoitteen. Tällöin kaikki muuttujan kautta tapahtuva olion käsittely tapahtuu apuolion kautta (niin, että tämä välikäden kautta kulkeminen ei näy muuttujan käyttäjälle). Jokaiseen muuttujaan liittyy ominaisuutena myös tyyppi. Mikäli tämä ominaisuus on dynaaminen, puhutaan dynaamisesti tyypitetystä kielestä. Tällöin muuttuja voi periaatteessa olla sidottu mihin tahansa olioon sen tyypistä riippumatta, ja muuttujan tyyppi on sama asia kuin muuttujan olion tyyppi. Mikäli muuttujan tyyppi on aina staattinen ominaisuus, puhutaan staattisesti tyypitetystä kielestä. Tällöin muuttujan olion tyypin tulee olla aina sama kuin muuttujan tyyppi (joissakin kielissä sallitaan joissakin tai kaikissa tilanteissa, että olion tyyppi on muuttujan tyypin alityyppi). Muuttujan käsitteeseen liittyy keskeisenä sijoitusoperaation (assignment) käsite. Sijoituksen perusideana on muuttaa muuttujan arvoa. Tähän on kaksi tapaa: joko sijoitus käy muuttamassa olion arvoa tai sitten se sitoo muuttujan uuteen olioon. Edellisessä tapauksessa kielessä sanotaan olevan käytössä arvosemantiikka (value semantics), jälkimmäisessä tapauksessa viitesemantiikka (reference semantics). Käytännössä viitesemantiikan toteuttaminen vaatii, että kaikki muuttujat ovat laatikoituja. Viitesemantiikkakielissä voi olla muita operaatioita, jotka muuttavat olion arvoa. Muuttuja voi olla sidottu olioon, jonka ainoana sisältönä on jonkin toisen olion osoite. Tällaista muuttujaa sanotaan osoittimeksi. Osoittimen arvoksi sanotaan sitä osoitetta, joka on osoittimeen sidotun olion sisältönä. Osoitin voi olla myös nollaosoitin (null pointer), josta tiedetään, ettei se osoita mihinkään olioon.

36 LUKU 3. MUUTTUJAT, ARVOT, OLIOT JA TYYPIT Muuttujan käsite voidaan nähdä toisellakin tavalla: muuttuja on aliohjelman parametri ja muuttujan alustus on funktion kutsu. Esimerkiksi seuraavat ohjelmanpätkät tekevät samaa (nämäkin esimerkit on kirjoitettu kuvitteellisella, demoissa käsitellyn kielen muunnelmalla): begin var i; i :=! ; put i; end begin sub foo(i) put i; bus; call foo(! ); end Jos käytetyssä kielessä funktiot ovat arvoja ja on mahdollista määritellä nimettömiä funktioita, jälkimmäinen esimerkki voidaan kirjoittaa toisinkin: begin call ( sub(i) put i; bus ) (! ); end Tällainen muuttujakäsite on yleinen funktiokielissä, vaikka sitä voidaan käyttää myös käskykielissä. Esimerkiksi Scheme-kielessä paikallisia muuttujia määrittelevä let-lauseke on määritelty kertomalla, mitä funktio ja funktiokutsu -rakennetta se vastaa. Toteutustapana tämä on järkevä vain, mikäli funktiokutsuja optimoidaan tehokkaasti 5, mutta vaikkei sitä käyttäisi toteutustapana, se on silti hyvä tapa määritellä muuttujan käsite. 3.5 Tyypit Tyyppejä voidaan ajatella kolmella tasolla: arvotasolla, oliotasolla ja kielitasolla. 5. Katso esim. Andrew W. Appelin kirjaa Compiling with continuations, Cambridge, Cambridge University Press, 1992.

3.5. TYYPIT 37 3.5.1 Arvotason tyypit: Scottin alueet Arvotasolla tyyppi on joukko arvoja. Tietyistä teknisistä syistä johtuen (jotka liittyvät itseviittauksen problematiikkaan, vertaa naiivin joukko-opin paradokseihin) mikä tahansa joukko ei kuitenkaan kelpaa tyypin määrittelyn lähtökohdaksi. Dana Scott kehitti 1960-luvun lopulla matemaattisen teorian, jota voitaneen kutsua tyyppien teoriaksi. Tuota nimeä ei kuitenkaan käytetä, sillä tyyppiteorialla on perinteisesti tarkoitettu aivan eri asiaa, nimittäin tietynlaista muodollista logiikkaa. Siksi nykyisin puhutaan Scottin alueista (Scott domains). Seuraavassa luetellaan muutamia teknisiä määritelmiä. Ne voidaan tarvittaessa hypätä yli. Määritelmä 3.5.1 (Osittaisjärjestys) Olkoon S joukko ja olkoon ( ) S S relaatio. Mikäli seuraavat ehdot pitävät paikkaansa, relaatio ( ) on osittaisjärjestys ja joukko S on järjestetty osittain relaatiolla ( ) (englanniksi sanotaan, että (S, ) on poset). refleksiivisyys Kaikilla s S pätee s s. transitiivisuus Kaikilla s, t, u S, jos pätee s t ja t u, niin pätee s u. antisymmetrisyys Kaikilla s, t S, jos pätee s t ja t s, niin pätee s = t. Huomaa, että osittaisjärjestyksessä voi hyvin olla niin, että kahden alkion s, t S välillä ei päde s t sen paremmin kuin t s. Kaikki Scottin alueet ovat osittaisjärjestyksiä. Niissä relaation ( ) intuitiivinen tulkinta on alkioiden määräisyyden (definiteness) vertaaminen: jos s t, niin t on ainakin yhtä määrätty, mahdollisesti myös määrätympi kuin s. Toinen tapa ajatella asiaa on ajatella alkioiden informaatiosisältöä: jos s t pätee, niin t:ssä on kaikki se informaatio mikä on s:ssäkin, mahdollisesti jopa enemmän. Määritelmä 3.5.2 Olkoon S järjestetty osittain relaatiolla ( ) S S ja olkoon A S. Nyt A:n alaraja on se s S jolla kaikilla a A pätee s a, yläraja on se s S jolla kaikilla a A pätee a s, infimum (merkitään inf A) on suurin A:n alaraja, supremum (merkitään sup A) on pienin A:n yläraja, minimi (merkitään min A) on inf A, mikäli pätee inf A A, sekä maksimi (merkitään max A) on sup A, mikäli pätee sup A A. Osajoukko A on ylhäältä rajoitettu, jos sillä on yläraja, ja alhaalta rajoitettu, jos sillä on ajaraja. Se on rajoitettu, jos se on sekä ylhäältä että alhaalta rajoitettu.

38 LUKU 3. MUUTTUJAT, ARVOT, OLIOT JA TYYPIT Samat käsitteet määritellään myös S:n jonoille (a i ) i I tarkastelemalla jonon alkioiden muodostamaa joukkoa. Määritelmä 3.5.3 (Järjestetty ja hyvinjärjestetty joukko) Olkoon S joukko, joka on järjestetty osittain relaatiolla ( ). S on järjestetty joukko ja ( ) on täydellinen järjestys, mikäli kaikilla s, t S pätee s t tai t s (tai molemmat). Järjestetyn joukon täydellistä järjestystä merkitään yleensä ( ):llä. Mikäli järjestetyssä joukossa S jokainen osajoukko on alhaalta rajoitettu, se on hyvinjärjestetty joukko ja ( ) on S:n hyvinjärjestys. Määritelmä 3.5.4 (Jono) Olkoot S joukko ja olkoon I hyvinjärjestetty joukko. Funktioita I:ltä S:lle sanotaan S:n jonoiksi. Jonoa merkitään tavallisesti (a i ) i I, jolloin merkinnällä a i tarkoitetaan tuon jonon arvoa kohdassa i ja merkinnällä {a i } i I tarkoitetaan joukkoa { x: i I: x = a i }. Määritelmä 3.5.5 (Nouseva ketju) Olkoon S järjestetty osittain relaatiolla ( ) S S ja olkoon (a i ) i I S:n jono. Jono (a i ) i I on nouseva ketju, mikäli jokaisella i, j I joilla i j pätee a i a j. Scottin alueiden tapauksessa nousevan ketjussa eteenpäin mentäessä alkioiden sisältämä tieto tarkentuu. Määritelmä 3.5.6 (Koherentti ja täydellinen osittaisjärjestys) Olkoon S järjestetty osittain relaatiolla ( ) S S. Se on koherentti mikäli jokaisella sen rajoitetulla osajoukolla on supremum. Se on täydellinen, mikäli on olemassa min S (merkitään S ) ja sen jokaisella nousevalla ketjulla on supremum. Määritelmä 3.5.7 (Kompakti alkio) Olkoon S järjestetty osittain relaatiolla ( ) S S ja olkoon s S alkio. Jos jokaisella S:n jonolla (a i ) i I siitä, että s sup(a i ) I pätee, seuraa se, että s a j pätee jollakin j I, niin s on kompakti alkio. Määritelmä 3.5.8 (Algebrallinen osittaisjärjestys) Olkoon S järjestetty osittain relaatiolla ( ) S S ja olkoon ( ) täydellinen osittaisjärjestys. Jos jokaiselle s S on olemassa nouseva ketju (a i ) i I siten, että { x S: x = a i jollakin i I x s x on kompakti alkio } ja s = sup(a i ) i I, niin ( ) on algeballinen osit-

3.5. TYYPIT 39 taisjärjestys S:ssä. Määritelmän 3.5.8 intuitiivinen idea on se, että algebrallisen osittaisjärjestyksen jokaista alkiota voidaan arvioida alhaalta päin sitä pienemmillä kompakteilla alkioilla. Määritelmä 3.5.9 (Scottin alue) Scottin alue on joukko, jossa on koherentti, algebrallinen osittaisjärjestys. Scottin alueet ovat siis tietynlaisia joukkoja. Näissä joukoissa voidaan joitakin alkioita vertailla keskenään määräisyyden (informaatiosisällön) suhteen: kaksi alkiota voivat olla yhtäläisesti määrättyjä (jolloin niissä on oleellisesti sama informaatio) tai toinen voi olla määrätympi (jolloin siinä on enemmän informaatiota kuin toisessa ja niiden informaatiosisältö on yhtäpitävää). Kaikissa Scottin alueissa on yksi täysin määräämätön alkio ( ), jota määrätympiä kaikki muut alkiot ovat. Muita alkioita ei välttämättä voi verrata keskenään määräisyyden suhteen. Tavalliset matemaattiset joukot S (kuten ) saadaan tehtyä Scottin alueeksi lisäämällä niihin uusi alkio S ja määrittelemällä sinne yksinkertainen osittaisjärjestys: kun x, y S, pätee x y joss x = S tai x = y. Näitä Scottin alueita sanotaan yksinkertaisiksi (elementary) tai tasaisiksi (flat), koska niillä on hyvin yksinkertainen rakenne. Kannattaa huomata, että osittaisjärjestyksenä ei käytetä joukon omaa järjestystä. Esimerkki 3 Seuraavat yksinkertaiset alueet ovat tavanomaisia: Fail = { Fail } Void = { Void, } Nat = { Nat } = { Nat, 0, 1, 2,... } Int = { Int } = { Int,..., 2, 1, 0, 1, 2,... } Bool = { Bool, True, False} Char = { Char } {Jonkin yhteydestä selvän merkkijoukon alkiot} Yksinkertaisista alueista luodaan kolmen aluekoostimen (domain constructor) avulla monimutkaisempia, rakenteisia alueita. Nämä koostimet ovat tulo-, summa- ja funktiokoostin. Tuloalueet Kahden Scottin alueen S ja T tulojoukko S T = { (s, t): s S t T } on myös Scottin alue. Tässä osittaisjärjestys ( S T ) määritellään seuraavasti: kai-

40 LUKU 3. MUUTTUJAT, ARVOT, OLIOT JA TYYPIT killa (s 1, t 1 ), (s 2, t 2 ) S T määritellään (s 1, t 1 ) S T (s 2, t 2 ) pätemään silloin ja vain silloin, kun s 1 S s 2 ja t 1 T t 2 pätevät. Helposti huomataan, että S T = ( S, T ). Tehtävä 5 Edellä mainittiin, että edustaa päättymätöntä tai virheeseen päättyvää laskentaa. Selvää on, että S T merkitsee sitä, että koko laskenta epäonnistuu. Mitä sitten edustavat ( S, t) ja (s, T ), kun s S ja t T? Tuloalueille on olemassa projektiofunktiot prj 0 : S T S ja prj 1 : S T T, jotka määritellään seuraavasti: { y mikäli x S T, jolloin merkitään x = (y, z), prj 0 (x) = prj 1 (x) = S { z T mikäli x S T, jolloin merkitään x = (y, z), Tehtävä 6 Määritelmän mukaan prj 0 (0, ) = 0. Jos ajatellaan päättymättömänä tai virhetilanteeseen päättyvänä laskentana, pitäisikö kuitenkin määritellä prj 0 (0, ) =? Tuloalueen käsite yleistyy mainiosti myös useammalle kuin kahdelle alueelle. Tällöin määritellään sopiva määrä projektiofunktioita prj i lisää. Summa-alueet Kahden Scottin alueen S ja T erillinen yhdiste S + T = { S+T } { (t, v): (t = 1 v S) (t = 2 v T) } on myös Scottin alue (ns. summa-alue), kun siihen lisätään (kuten edellä) erillinen pohja-arvo S+T. Osittaisjärjestys määritellään paloittain seuraavasti: Jos s 1, s 2 S ja s 1 S s 2 pätevät, niin pätee (1, s 1 ) S+T (1, s 2 ). Jos t 1, t 2 T ja t 1 T t 2 pätevät, niin pätee (2, t 1 ) S+T (2, t 2 ). Kaikilla s S pätee (1, S ) S+T (1, s). Kaikilla t T pätee (2, T ) S+T (1, t). Pätee S+T S+T S+T. Missään muussa tapauksessa eivät alkiot ole keskenään verrattavissa. Tämän laputuksen (eli 1:n ja 2:n käytön parin ensimmäisenä alkiona) tarkoituksena on varmistaa, että vaikka S ja T eivät olisikaan erillisiä, niin silti jokaisesta summa-alueen alkiosta (paitsi S+T ) voidaan sanoa, kumman alueen

3.5. TYYPIT 41 inj 1 : S S + T inj 1 s = (1, s) inj 2 : T S + T inj 2 t = (2, t) sel 1 : S + T S { v jos a = (1, v) sel 1 a = S sel 2 : S + T T { v jos a = (2, v) sel 2 a = T tst 1 : S + T Bool True jos a = (1, v) jollakin v tst 1 a = False jos a = (2, v) jollakin v Bool tst 2 : S + T Bool False jos a = (1, v) jollakin v tst 2 a = True jos a = (2, v) jollakin v Bool Taulukko 3.1: Summa-alueen koostimet, projektiot ja testaimet alkiota se vastaa. Ei ole merkitystä, mitä arvoja käytetään lappuina, kunhan laput ovat keskenään erilaisia. Käytännössä tavallista on käyttää lappuna jotain kuvaavaa merkkijonoa. Summa-alueelle määritellään kaksi koostinta (inj i ), kaksi projektiota (sel i ) ja kaksi testainta (tst i ) taulukon 3.1 mukaisesti. Myös summa-alueet yleistyvät helposti monen alueen tapaukseen. Esimerkki 4 Alueyhtälö String = Void + (Char String) määrittelee implisiittisesti merkkilistojen (merkkijonojen) alueen String.

42 LUKU 3. MUUTTUJAT, ARVOT, OLIOT JA TYYPIT Yleisemmin, jos D on alue, määrittelee alueyhtälö D:n listojen alueen D. D = Void + (D D ) Listoille on tapana määritellä seuraavat funktiot (nimet ovat traditionaalisia ja peräisin Lispistä): car: D D car = prj 1 sel 2 cdr: D D cdr = prj 2 sel 2 nullp: D Bool nullp = tst 1 Funktio car antaa listan ensimmäisen alkion, cdr antaa listan, josta on ensimmäinen alkio poistettu. Funktio nullp palauttaa totuusarvon, joka kertoo, onko lista tyhjä. Funktioalueet Funktioalueet ovat hieman kinkkisempi juttu. Jos S ja T ovat alueita, niiden välisten funktioiden joukko on liian laaja alueeksi. Syy tähän on se, että monet funktioista, joita on tarkoitus tarkastella, operoivat funktioilla ja palauttavat funktioita ja ovat lisäksi rekursiivisesti määriteltyjä. Yleisillä funktioilla päädytään tällä tavalla nopeasti joukko-opin paradokseihin, joten sallittuja funktioita on rajattava jotenkin. Asetetaan seuraava merkintä: kun S ja T ovat Scottin alueita, on S T suurin sellainen joukko, jolle pätee seuraavaa: 1. S T sisältää kaikki S:n ja T:n väliset funktiot, sekä 2. jokaisella f S T ja jokaisella nousevalla S:n ketjulla (a i ) i I pätee f(sup(a i ) i I ) = sup(f(a i )) i I. Osittaisjärjestys määritellään luonnollisesti: Olkoot f, g S T. Nyt jos kaikilla s S pätee f(s) T g(s), niin pätee myös f S T g. Tehtävä 7 Todista, että tulo- ja summa-alueille edellä määritellyt funktiot kuuluvat sopiviin funktioalueisiin. Funktioita on tapana merkitä λ-notaatiolla λx.e, joka luetaan x:n funktio E tai E x:n funktiona. Sen, mihin alueeseen funktio kuuluu, tulee selvitä yh-

3.5. TYYPIT 43 teydestä. On myös mahdollista ilmaista parametrin alue tyyliin λx : S.E, joka tarkoittaa, että kyseinen funktio kuuluu alueeseen S T jollakin T (T on yleensä johdettavissa E:n rakenteesta). Helposti nähdään, että S T on vakiofunktio λx : S. T. Funktiot jaetaan kahteen luokkaan sen mukaan, miten ne käyttäytyvät silloin, kun argumenttina on. Monet funktiot ovat tiukkoja (strict), mutta jotkut ovat väljiä (nonstrict): funktio f S T on tarkka, mikäli pätee f( S ) = T, se on väljä. Tässä esitetyllä tavalla käsiteltynä kaikki funktiot ovat yksipaikkaisia. Monipaikkaisia funktioita voidaan simuloida kahdella tavalla: funktio voi kuulua alueeseen (S 1 S 2 ) T, jolloin se on yksipaikkainen funktio, joka ottaa parin parametrinaan; toisaalta funktio voi kuulua alueeseen S 1 (S 2 T), jolloin se on yksipaikkainen funktio, joka palauttaa toisen yksipaikkaisen funktion. Jälkimmäistä tapaa sanotaan currymaiseksi (curried) loogikko Haskell B. Curryn (1900 1982) mukaan, edellistä voisi kutsua vastaavasti epäcurrymaiseksi (uncurried). Sulut on edellä esitetyistä kaavoista tapana jättää pois: S 1 S 2 T ja S 1 S 2 T. Tuloalueen koostin siis sitoo tiukemmin kuin funktioalueen koostin, joka sitoo oikealle (associates to the right). Currymaisen tavan kautta tulkittuna myös monipaikkaiset funktiot voidaan luokitella kunkin parametrinsa osalta tiukaksi tai väljäksi. Esimerkiksi monissa kielissä looginen ja -operaattori käyttää ns. oikosulkulaskentaa eli on toisen parametrinsa suhteen väljä: jos ensimmäinen argumentti on epätosi, operaation tuloksena on epätosi riippumatta toisesta argumentista. Funktioille on määritelty yhdistämisfunktiot ( ): (T U) (S T) (S U) ( ) = λf.λg.λx.f(g(x)) ( ): (S T) (S T) (S T) { f(x) mikäli f(x) T, ( ) = λf.λg.λx. g(x). Matemaattisesti suuntautuneelle opiskelijalle jääköön harjoitustehtäväksi todistaa, että tämä funktio todella kuuluu funktioalueeseen. Funktioita on käytännöllistä määritellä paloittain ja yhdistellä määritelmät käyttäen ( )-funktiota. Varsin usein määritelmässä käytetään hyväksi hahmonsovitusta (pattern matching): parametrissa nimen sijasta annetaan jokin pari, jonka alkiona voi olla jokin toinen samanlainen pari tai sitten vakiolauseke

44 LUKU 3. MUUTTUJAT, ARVOT, OLIOT JA TYYPIT tai nimi. Operatiivisena tulkintana on se, että jos argumentin rakenne on sama kuin parametrin, parametrissa esiintyvien nimien arvoksi sidotaan vastaavassa paikassa argumenttia olevat arvot. Puoliformaalisti tämä määritellään rekursiona seuraavasti: ((λx.((λy.e)(prj 2 z)))(prj 1 z)) jos z S T λ(x, y): e = λz. ((λy.e)(sel x z)) jos z S + T ja tst x z = True. missä z on nimi, joka ei esiinny vapaana e:ssä. Esimerkki 5 Lisp-kielestä tuttu funktio cadr voidaan määritellä seuraavasti: cadr: S S cadr = λ(2, (x, (2, (y, z)))).y Olisi sen myös voinut määritellä lausekkeella car cdr.