Tämä tarina on Fibonaccin lukujen ongelman alkuperäinen muotoilu.

Koko: px
Aloita esitys sivulta:

Download "Tämä tarina on Fibonaccin lukujen ongelman alkuperäinen muotoilu."

Transkriptio

1 Rekursiosta ja iteraatiosta Oletetaan että meillä on aluksi yksi vastasyntynyt kanipari, joista toinen on uros ja toinen naaras. Kanit saavuttavat sukukypsyyden yhden kuukauden ikäisinä. Kaninaaraan raskaus kestää yhden kuukauden, jonka jälkeen hän synnyttää uuden tällaisen vastasyntyneen parin. Oletetaan, etteivät kanit kuole ja että juuri synnyttänyt naaras tulee heti uudelleen raskaaksi. Montako sukukypsää kaniparia meillä on kunkin kuukauden alussa? Tämä tarina on Fibonaccin lukujen ongelman alkuperäinen muotoilu. Rekursiivinen ratkaisu voidaan kehittää kahtena funktiona nuoret t = vastasyntyneiden kaniparien lukumäärä ajanhetkellä t vanhat t = sukukypsien kaniparien lukumäärä ajanhetkellä t kirjoittamalla auki se, mitä tarina niistä meille kertoo. Sen tuttu muotoilu yhtenä funktiona saadaan huomaamalla, että nuoret on niin yksinkertainen funktio, että se voidaan sijoittaa helposti funktioon vanhat. Iteratiivinen ratkaisu voidaan kehittää laskemalla laiskasti, miten populaatio kehittyy ajan kuluessa: Nykyinen populaatio esitetään parina (vanhat,nuoret). Seuraava populaatio on tarinan mukaan aina (vanhat+nuoret,vanhat). Ensimmäinen populaatio on (0,1). Sen tuttu muotoilu silmukkana saadaan huomaamalla, että emme tarvitsekaan populaation koko historiaa, vaan pelkästään sen nykyisen arvon. fibrek = let nuoret 0 = 1 nuoret t = vanhat (t-1) vanhat 0 = 0 vanhat t = vanhat (t-1) + nuoret (t-1) in vanhat fibit = map fst $ iterate (\ (vanhat,nuoret) -> (vanhat+nuoret,vanhat)) (0,1) Listojen luonti erikoissyntaksilla Haskell tarjoaa listojen luontiin erikoissyntaksin, joka on helppolukuisempi kuin perussyntaksi. Tämän erikoissyntaksin lähtökohta ovat matemaattiset joukkomerkinnät listoihin sovellettuina. 40

2 Matematiikassa luemme joukkomerkinnän {0, 2, 4,...,100} tarkoittamaan sitä joukkoa, joka saadaan luettelemalla sen alkiot alkaen luvusta 0 jatkuen siitä aina lisäämällä edelliseen lukuun 2, kuten 0, 2, 4 näyttää malliksi päättyen lukuun 100. Sen vastine listana olisi siis takewhile (<= 100) (iterate (+ 2) 0) joka voidaan kirjoittaa erikoissyntaksilla listana [0,2..100] eli sallimme vain yhden (emmekä kahta) mallia siitä, miten luettelo jatkuu. Yleisesti listojen erikoissyntaksi [eka,toka..vika] tarkoittaa siis samaa kuin takewhile (<= vika) (iterate (+ (toka - eka)) eka) Jos toka puuttuu, niin operaationa tuloslistan seuraava alkio on (+ 1) eli seuraava. Esimerkiksi [3..7] = [3,4,5,6,7] Samaa käytetään myös liukulukulistoille, vaikka se ei ole seuraava liukuluku. Jos vika puuttuu, niin koko takewhile-loppuehto jää pois, ja tuloksena on ääretön lista. Esimerkiksi [1,3..] = kaikki parittomat positiiviset kokonaisluvut. Matematiikassa luemme myös mutkikaampia joukkomerkintöjä. Esimerkiksi { a, b,c b N, a {1, 2, 3,...,b 1}, c = } a 2 + b 2 N määrittelee Pythagoraan kolmikot. Eli ne luonnolliset luvut a < b < c joille Pythagoraan lause a 2 + b 2 = c 2 pätee eli kolmio jonka sivujen pituudet ovat a, b ja c on suorakulmainen. Siinä on kolmenlaisia osia: tulos pystyviivan (tai kaksoispisteen : ) vasemmalla puolella muuttujia arvoalueineen oikealla puolella ehtoja muuttujien arvoille oikealla puolella 41

3 jossa oikealla puolella olevat osat on eroteltu pilkuilla, (tai sanalla ja tai konjunktiomerkillä ). Luemme sen niin, että tulokset on saatu valitsemalla muuttujille niiden arvoalueilta sellaiset arvot, että ehdot ovat voimassa. Luemme merkinnän vasemmalta oikealle: ensin valitaan b, sitten sen pohjalta a ja sitten niiden pohjalta c. Listojen erikoissyntaksissa on vastaava ilmaus [tulos osa, osa, osa,..., osa] jonka jokainen osa on Hahmo <- lauseke jossa lauseke :: [t] ja Hahmo :: t let-lauseke, mutta ilman in-lauseketta ehto :: Bool. Tällaisen Hahmon tai letin oikealla puolella olevat osat sekä tuloslauseke voivat käyttää sen tekemiä nimentöjä. Koko ilmauksen tyyppi on [u] jossa tulos :: u. Ilmauksen deklaratiivinen merkitys on: Hahmo <- lauseke tarkoittaa valitse Hahmoon sopiva alkio siitä listasta, jonka lauseke tuottaa muistisäääntönä <- on ehto tarkoittaa varmista että se on True näin tehdyillä valinnoilla letillä voi tehdä apumääritelmiä tavalliseen tapaan Jokaisesta näin varmistetusta valinnasta tulee yksi tulos ilmauksen tuottamaan listaan. suorakolmiot = [(a,b,c) b <- [2,3..], a <- [1..b-1], let d = aˆ2 + bˆ2 c = isqrt d, d == cˆ2 ] -- Varoitus: Jos argumentin arvo on niin suuri, -- että se ei mahdu Doubleen ilman pyöristystä, -- niin tämä helppo tapa tuottaakin väärän vastauksen! isqrt :: Int -> Int isqrt = floor. (sqrt :: Double -> Double). fromintegral Ilmauksen operationaalinen merkitys on näiden varmistettujen valintojen syvyyssuuntainen etsintä (depth-first search). 42

4 Siksi ilmauksen osat kannattaa järjestää siten, että aikaisemmat niistä rajoittavat mahdollisimman tehokkaasti myöhäisempiä. Erityisesti korkeintaan yksi Hahmo <- lauseke kannattaa olla sellainen, jonka lauseke tuottaa äärettömän listan, ja se kannattaa sijoittaa heti ensimmäiseksi osaksi. Lisäksi ehto kannattaa sijoittaa heti kun kaikki sen tarvitsemat muuttujat ovat saaneet arvonsa, jotta etsintää ei jatkettaisi turhaan. Haskell muuntaa tämän etsinnän siten, että epäonnistumisten ja peruuttamisen (backtracking) sijasta tuotetaankin lista onnistumisia (turning failure into a list of successes) jossa epäonnistuminen on tyhjä lista [] onnistuminen on yksialkioinen lista [tulos]. Laiska suoritus tekee tästä etsinnästä syvyys- eikä leveyssuuntaista, koska nämä listat lasketaan alkio kerrallaan eikä kokonaan. Tämä käännösaikainen rekursiivinen muunnos on seuraava: [tulos True] on [tulos] [tulos osa] on [tulos osa, True] jossa käsitellään viimeistä osaa. [tulos ehto, osia] on if ehto then [tulos osia] else [] [tulos Hahmo <- lauseke, osia] on let ok Hahmo = [tulos osia] ok _ = [] in concatmap ok lauseke jossa käytetään Preluden funktioita concatmap ok = concat. map ok concat = foldr (++) [] [tulos let määritelmät, osia] on let määritelmät in [tulos osia] Äärelliset, äärettömät ja määrittelemättömät arvot Tähän mennessä olemme nähneet, että listatyypin [t] arvoihin kuuluu sekä äärellisiä että äärettömiä listoja. Miten voisimme kuvailla, mitkä arvot siihen tarkkaan ottaen kuuluvat? Merkitään A τ = tyypin τ kaikkien mahdollisten arvojen joukko. Listojen määritelmän mukaan e A [t] e on tyhjä lista [] tai muotoa x:xs jossa x A t ja xs A [t]. (10) Millaisia ovat sen mukaiset joukot A [t]? 43

5 Voimme lukea määritelmän (10) erikseen kumpaankin suuntaan: : Sääntönä jos e on tyhjä lista [] tai muotoa x:xs jossa x A t ja xs A [t], niin myöskin e A [t]. : Joukon A [t] pitää olla suljettu (closed) tämän säännön suhteen, eli A [t] ei enää saa muuttua, vaikka sääntöä sovellettaisiin uudelleen. Matemaattisesti puhutaan tämän säännön kiintopisteen muodostamisesta eli sellaisen joukon muodostamisesta, jota sääntö ei enää muuta. Matematiikassa ns. Knasterin ja Tarskin kiintopistelause takaa, että tällaiset tietojenkäsittelyteorian tarvitsemat kiintopisteet ovat olemassa. Tällä määritelmän (10) lukutavalla saadaan sen pienin (least) kiintopiste: Laskentasääntönä: A pienin [t] = vain ne alkiot, jotka täytyy ottaa mukaan 1 Aloitetaan tyhjästä joukosta A pienin [t] =. 2 Tyhjä lista [] täytyy ottaa mukaan joukkoon A pienin [t]. 3 Jos x A t ja xs on jo otettu mukaan joukkoon A pienin [t], niin myöskin x:xs täytyy ottaa mukaan joukkoon A pienin [t]. 4 Toista askelta 3 (ikuisesti...) kunnes joukko A pienin [t] ei enää kasva. Voimme osoittaa listainduktiolla että jokin väite φ pätee kaikille tämän joukon A pienin [t] alkioille: Perustapaus on osoittaa, että φ pätee tyhjälle listalle []. Induktiivinen tapaus ❶ olettaa, että φ pätee listalle xs A pienin [t] ❷ osoittaa induktio-oletuksen ❶ perusteella, että φ pätee myös jokaiselle listalle x:xs A pienin [t] jossa x A t on mielivaltainen. Silloin φ pätee kaikille joukon A pienin [t] alkioille, koska askeleen 4 mukaan käsittelimme kaikki eri tavat joilla siihen on voitu lisätä alkioita. Vertaa tätä listainduktiota tuttuun luonnollisten lukujen N induktioon: Siinä N on kuin A pienin [()]. Vertaa tätä listainduktiota myös foldr-rekursioon. Osoitetaan listainduktiolla, että poly1 [c 0, c 1, c 2,...,c n ] x = n c i x i. (11) i=0 Toisin sanoen, jos listana on polynomin p kertoimet pienimmästä suurimpaan, niin lasketaan sen arvo p(x) annetulla x. Näin laskemalla vältetään potenssiinkorotukset x i. 44

6 Perustapaus: poly1 [ ] x = 0 joka on oikein, koska vastaavassa polynomissa p ei ole yhtään termiä, ja sellainen tyhjä summa = yhteenlaskun neutraalialkio. Induktio-oletus: poly1 [c 1, c 2,...,c n ] x = n c i x i 1. Induktiivinen tapaus alkaa koodin algbrallisella käsittelyllä: Siten i=1 poly1 (c:cs) x = foldr (\ c y -> c + x * y) 0 (c:cs) x = c + x * (foldr (\ c y -> c + x * y) 0 cs) = c + x * poly1 cs x poly1 [c 0, c 1, c 2,...,c n ] x =c 0 + x (poly1 [c 1, c 2,...,c n ] x) } {{ } induktio-oletus sopii tähän n =c 0 + x c i x i 1 i=1 joka on haluttu väite. poly1,poly2 :: [Double] -> Double -> Double poly1 cs x = foldr (\ c y -> c + x * y) 0 cs poly2 = foldr (\ c f -> \ x -> c + x * f x) (const 0) Tämä joukko A pienin [t] koostuu täsmälleen kaikista äärellisistä listoista, joiden jokainen alkio on tyyppiä t. Se kuvaa ahkeran ohjelmointikielen tyypin [t]. Laiskan Haskellin tyypissä [t] on kuitenkin myös ne äärettömät listat, joiden jokainen alkio on tyyppiä t. Muodostetaan siis suurin (greatest) kiintopiste A suurin [t] = kaikki ne alkiot, joita ei ole pakko jättää pois lukemalla määritelmä (10) päinvastoin: 45

7 [] alku : [t] A t Kuva 2: Lista-automaatti. : Saamme kontraposition kautta säännön jos e ei ole tyhjä lista [] tai e ei ole muotoa x:xs tai e on sitä muotoa mutta x A t tai xs A suurin [t], niin myöskään e A suurin [t]. : Joukon A suurin [t] pitää olla suljettu tämän alkioiden poistosäännön suhteen. Lopulta tämä joukko A suurin [t] koostuu täsmälleen niistä äärellisistä ja äärettömistä listoista, joiden jokainen alkio ovat tyyppiä t koska täsmälleen niitä ei ollut pakko jättää pois tämän poistosäännön nojalla. Kuvan 2 lista-automaatti esittää määritelmän (10). (Jätetään toistaiseksi huomiotta sen katkoviivoitettu siirtymä, johon palataan hieman myöhemmin.) A pienin [t] A suurin [t] = ne syötteet, jotka se hyväksyy. = ne (myös äärettömät) syötteet, joita se ei hylkää. Syöte hylätään, jos sen lopussa ei olla hyväksyvässä tilassa tai jos nykyisessä tilassa ei ole siirtymää sen seuraavalla syötemerkillä. Siis ääretöntä syötettä ei hylätä täsmälleen silloin jos siirtymiä voi seurata ikuisesti. Tätä joukon A suurin [t] konstruktiota alkioita pois jättämällä kutsutaan koinduktiiviseksi. Tässä joukossa A suurin [t] induktio ei enää pädekään, koska siellä on muutakin kuin vain induktiivisesti muodostettu A pienin [t] siellä on myös ne (oikein muodostetut) äarettömät listat. Esimerkiksi listainduktiolla osoittamamme tulos (11) ei enää pädekään, jos poly1 saakin syötteekseen äärettömän listan [c 0, c 1, c 2,...]: Silloin poly1 jumiutuu päättymättömään rekursioon, vaikka esimerkiksi arvolla x = 0 oikea vastaus olisikin listan ensimmäinen alkio c 0. Yksi laiskan laskennan epämiellyttävistä yllätyksistä siis on, ettei induktio pädekään. Onneksi usein riittää osoittaa Haskell-ohjelman toiminta äärellisillä syötteillä, ja silloin induktio yhä pätee. Tai voi käsitellä sen toiminnan erikseen äärellisillä (käyttäen induktiota) ja äärettömillä syötteillä. Tai voi käyttää induktiivisen sijasta aitoa koinduktiivista päättelyä, joka kuitenkin sivuutetaan tällä kurssilla. 46

8 Yksinkertaista koinduktiivista päättelyä äärettömillä listoilla voi tehdä käyttämällä kuvan 2 lista-automaattia testisyötegeneraattorina. Esimerkiksi voimme laskea poly1 alku x = foldr (\ c y -> c + x * y) 0 alku = foldr (\ c y -> c + x * y) 0 (a:alku) = a + x * (foldr (\ c y -> c + x * y) 0 alku) = a + x * (poly1 alku x) josta havaitsemme, että ikuinen laskenta toistuu ennen kuin tulosta syntyy. Toisaalta laskemalla map g alku = foldr ((:). g) [] alku = foldr ((:). g) [] (a:alku) = (g a) : foldr ((:). g) [] alku = (g a) : map g alku havaitsemme, että map pystyy tuottamaan tuloslistaansa laisksti alkio kerrallaan myös silloinkin, kun sen syötelista on ääretön. Edes tämä koinduktiivinen konstruktio A suurin [t] ei vieläkään kuvaa tarkasti Haskelllistatyypin [t] koko arvojoukkoa A [t] : Laiskan suorituksen vuoksi myös määritelmä ikuinen :: [t] ikuinen = ikuinen hyväksytään ja pysähtyy. Niinpä sen täytyy määritellä tälle muuttujalle jokin arvo. Tätä arvoa kutsutaan tavallisesti nimellä [t] eli tyypin [t] pohja-arvo (bottom). Ahkerassa ohjelmointikielessä tilanne olisi yksinkertaisempi: Yritys tehdä tällainen ikuinen määritelmä johtaisi heti ohjelman jumiutumiseen eli lopputulokseen u joten siellä minkään muuttujan arvo ei voisi olla u. Laiskassa ohjelmointikielessä muuttujan arvoa ei lasketakaan valmiiksi sen määrittelyhetkellä. Sen sijaan muuttujalle annettu arvo on (enemmän tai vähemmän keskeneräinen) laskenta joka sieventyy vaiheittain kohti lopullista arvoaan sitä mukaa kun ohjelman suoritus tarvitsee muuttujan esittämää informaatiota. Sellaisen muuttujan arvo voi siten olla myös sellainen laskenta, joka aikanaan jumiutuu......eli sellainen tietorakenne, jossa aikanaan kohdataan osa u. Listoille esitimme tämän mahdollisuuden katkoviivoitettuna siirtymänä kuvan 2 automaatissa. 47

9 Tämä pätee jo perustyypeissäkin, joten esimerkiksi ja niin edelleen. A Bool = {True,False, Bool } Kun kysytään funktion tulosta, niin sen laskenta voi jumittua, jolloin u on sen luonteva tulos. Mutta onko u luonteva tulos silloinkin, kun vain kysytään jonkin (perustyypin...) muuttujan arvoa? Tämäkin on siis epämiellyttävä yllätys laiskassa laskennassa. Sama u esittää laskentaa, jonka tuloksen tyyppi on u, mutta joka ei pystykään tuottamaan sitä, koska se pyöriikin ikuisessa rekursiossa, tai pysähtyykin ajonaikaiseen virheeseen esimerkiksi siihen, ettei mikään caselausekkeen Hahmoista sopinutkaan. Haskellissa ei voi testata olisiko jonkin lausekkeen arvo u vaiko ei, koska sehän olisi ratkeamatonta Lauseen 4 nojalla. Pienimpien kiintopisteiden teoriaa käytetään esimerkiksi ahkerien (eli lähes kaikkien) ohjelmointikielten teoriassa kuten rekursion ja toistorakenteiden semantiikassa osoitettaessa (esimerkiksi induktiolla) että ohjelman laskema lopputulos on haluttu. Suurimpien kiintopisteiden teoriaa käytetään puolestaan esimerkiksi osoitettaessa sellaisen ohjelman oikeellisuutta, joka ei pysähdy ja anna lopputulosta, vaan jonka on tarkoitus toimia ikuisesti. Sellaisia ovat esimerkiksi tietoliikenneprotokollat, verkko- ja tietokantapalvelimet,... Voidaan tarkastella sellaisen ohjelman periaatteessa äärettömiä mahdollisia toimintahistorioita ja osoittaa, että niillä on halutut ominaisuudet, kuten vaikkapa että jokaiseen saatuun viestiin vastataan Tulkkaamisesta ja kääntämisestä poly2 on sama funktio kuin poly1 mutta niissä laskenta etenee niissä eri tavalla. Tämä samuus tarkoittaa että jokaisella ds ja z pätee poly1 ds z = poly2 ds z jonka voi osoittaa induktiolla listan ds suhteen. poly1 cs x tuottaa foldr-rekursiolla polynomin p arvon tyyppiä Double annetulla x. Siten poly1 cs on funktio, joka odottaa arvoa x, ja sen saatuaan etenee foldrrekursiolla listan cs suhteen. 48

10 poly2 cs tuottaa foldr-rekursiolla nimettömän funktion tyyppiä Double -> Double joka laskee polynomin p arvon kun sille annetaan x. Siten poly2 cs muuntaakin listan cs foldr-rekursiolla funktioksi, joka laskee polynomin p arvoja kun sille annetaan arvoja x. Intuitiivisesti poly1 tulkkaa tietorakenteena esitettyä ohjelmaa cs nykyisellä syötteellä x poly2 ensin kääntää ohjelman cs suorituskelpoiseksi koodiksi jota voi sitten suorittaa eri syötteillä x ja funktionaalisessa ohjelmoinnissa voi ilmaista tämän vaihejaon Tyyppisynonyymit Haskellissa voi määritellä lyhennenimen tyypille. Tämän määritelmän syntaksi on type Lyhenne = PitkäTyyppi Tämän määritelmän nojalla Lyhenne tarkoittaa samaa kuin PitkäTyyppi ja sitä voi käyttää samalla tavalla. Tällainen type-määritelmä on tehtävä lähdekooditiedoston uloimmalla tasolla eli ne eivät saa olla minkään letin tai wheren sisällä. Esimerkiksi vakiokirjasto Prelude määrittelee lyhenteen type String = [Char] koska Haskellissa ei ole erillistä merkkijonotyyppiä, vaan merkkijonot ovat merkkilistoja. Tyyppiparametrit type-määritelmässä voi olla myös yksi tai useampi parametri ennen yhtäsuuruusmerkkiä = samoin kuin Haskell-funktioissa: type Lyhenne par_1 par_2 par_3... par_k = PitkäTyyppi Jokainen parametri on oma muuttuja. Tällainen parametri tarkoittaa vielä tuntematonta Tyyppiä. PitkäTyyppi voi käyttää näitä parametreja perustyyppien tavoin. Tällaisen parametrisoidun määritelmän käyttö Tyyppinä on vastaavasti funktionkutsun kaltainen: Lyhenne Tyyppi_1 Tyyppi_2 Tyyppi_3... Tyyppi_k Se tarkoittaa sellaista PitkäTyyppiä, jossa jokaisen par_i korvasi sitä vastaava Tyyppi_i. Esimerkiksi 49

11 type Nimetty t = [(String,t)] määrittelee lyhenteen Nimetty t tyypille lista, jonka alkiotyyppi on pari, jonka ensimmäinen osa on tyyppiä String ja toinen osa on tyyppiä t. Siten käyttö Nimetty Int on Tyyppinä [(String,Int)] käyttö Nimetty Bool on Tyyppinä [(String,Bool)] käyttö Nimetty (Nimetty Double) on Tyyppinä[(String,Nimetty Double)] eli [(String,[(String,Double)])] ja niin edelleen Uusien tyyppien määrittely Haskellissa voi määritellä myös kokonaan uusia tyyppejä. Tämän määritelmän syntaksi on data Uusi = Konstruktori_1 kentät_1 Konstruktori_2 kentät_2 Konstruktori_3 kentät_3... Konstruktori_p kentät_p deriving (Show) Jokainen Konstruktori_i on kokonaan uusi Nimi jonka määritelmä varaa vain tähän tarkoitukseen eli samaa Konstruktoria ei saa määritellä uudelleen tässä samassa eikä missään muussakaan data-määritelmässä. Sen kentät_i ovat muotoa Tyyppi_i1 Tyyppi_i2 Tyyppi_i3... Tyyppi_iq deriving-osa ei ole välttämätön, mutta ilman sitä Haskell määrittelee sellaisen tyypin, jonka arvoja ei voi tulostaa käyttäjälle. Tällainen data-määritelmä on tehtävä lähdekooditiedoston uloimmalla tasolla. Tämä data-määritelmä luo kokonaan uuden tyypin jonka arvojoukko A Uusi koostuu alkioista Konstruktori_i arvo_i1 arvo_i2 arvo_i3... arvo_iq jossa jokainen arvo_ij :: Tyyppi_ij on vastaavan kentän sisältämä arvo eli sen oman arvojoukon A Tyyppi ij jokin alkio. Koska Haskell on laiska ohjelmointikieli, niin tämä arvojoukko A Uusi on koinduktiivinen A suurin Uusi sisältää pohja-arvon Uusi. Esimerkiksi (valmiiksi määritellyn) totuusarvotyypin määritelmä olisi voinut olla 50

12 data Bool = False True eli sillä on 2 Konstruktoria joilta kummaltakin puuttuvat kaikki kentät. Myös nämä data-määritelmät voivat sisältää samanlaisia tyyppiparametreja kuin type-määritelmätkin. Esimerkiksi vakiokirjasto Prelude sisältää määritelmän data Maybe t = Nothing Just t eli tyyppi, jonka arvot ovat ovat joko Justiinsa tyypin t arvo tai ei mitään joten esimerkiksi A suurin Maybe Bool = { Maybe Bool,Nothing, Prelude sisältää myös määritelmän data Either l r = Left l Right r Just False,Just True,Just Bool }. Lajit Haskellissa on tyyppien tyypit eli lajit (kind): Siten * on tyyppien laji. a -> b on sellaisen 1-parametrisen tyyppikonstruktorin laji, jonka parametrin laji on a ja tuloksen laji on b. a -> b -> c on 2-parametrisen tyyppikonstrukorin laji. Bool :: * Maybe :: * -> * Either :: * -> * -> * Maybe Bool :: * Either (Maybe Bool) :: * -> * ja niin edelleen. Pääasiallisesta tyypistä Tälläinen tyyppiparametrien tarjoama tietorakenteiden ja niiden käsittelyfunktioiden monikäyttöisyys on parametrista monimuotoisuutta (parametric polymorphism). Monimuotoisuutta käsitellään kurssilla lisää myöhemmin. Näiden tyyppiparametrien vuoksi täsmennämme aiempaa täsmällisen tyypityksen periaatettamme: 51

13 Jokaisella lausekkeella on oleellisesti täsmälleen yksi pääasiallinen (principal) tyyppi, josta kaikki sen muut monimuotoiset tyypit saadaan korvaamalla tyypeillä sen tyyppiparametrit. Tässä oleellisesti tarkoittaa, että tyyppiparametreille valitut nimet eivät ole merkityksellisiä (vertaa α-konversio). Siten[t] -> t -> t ja[u] -> u -> u ovat oleellisesti yksi ja sama tyyppi, ja niin edelleen. Esimerkiksi pääasiallinen tyyppi foldr :: (a -> b -> b) -> b -> [a] -> b tarkoittaa, että foldr on myös jokaista tyyppiä, joka saadaan siitä korvaamalla jokainen a keskenään samalla tyypillä t ja jokainen b keskenään samalla tyypillä u. Esimerkiksi... a on b on foldr on Int Bool (Int->Bool->Bool)->Bool->[Int]->Bool Bool Int (Bool->Int->Int)->Int->[Bool]->Int Char Int (Char->Int->Int)->Int->[Char]->Int Int [Int] (Int->[Int]->[Int])->[Int]->[Int]->[Int]... Haskell päättelee tämän pääasiallisen eli yleisimmän tyypin eli rajoittaa tyypinpäättelynsä aikana tyyppejä vain sen verran kuin on pakko. Rekursiiviset tyypit data-määritelmä voi viitata itseensä eli sen Uusi tyyppi(konstruktori) voi esiintyä myös sen omissa kentissä (myös välillisesti muiden Tyyppien kautta). Esimerkiksi (valmiiksi määritellyn) listatyyppikonstruktorin määritelmä olisi voinut olla data [t] = [] t : [t] jossa arvokonstruktorioperaattorin (:) oikeanpuoleisen kentän Tyyppi on tämä sama määriteltävänä oleva [t] itse. Esimerkkinä määritellään binäärinen hakupuu (ilman tasapainottamista). Oppikirjamääritelmän mukaan binäärinen hakupuu on joko tyhjä tai solmu jolla on 4 kenttää: 1 vasen alipuu 2 avain 3 avainta vastaava tietoalkio, ja 4 oikea alipuu. Nämä vasen 1 ja oikea 4 alipuu ovat induktiivisesti myöskin (pienempiä) hakupuita. Sovitaan avainten 2 tyypiksi Int. 52

14 Jätetään tietoalkioiden 3 tyypiksi tyyppiparametri t jotta samalla määritelmällä saadaan hakupuutyypit eri tietoalkiotyypeille. Kirjoitetaan tämä määritelmä Haskelliksi. data Tree t = Empty Node (Tree t) Int t (Tree t) deriving (Show) additem :: Int -> t -> Tree t -> Tree t additem newkey newitem Empty = Node Empty newkey newitem Empty additem newkey newitem (Node left oldkey olditem right) newkey < oldkey = Node (additem newkey newitem left) oldkey olditem right newkey > oldkey = Node left oldkey olditem (additem newkey newitem right) otherwise = Node left oldkey newitem right build :: [(Int,t)] -> Tree t build = foldr (uncurry additem) Empty itemof :: Int -> Tree t -> Maybe t itemof _ Empty = Nothing itemof key (Node left oldkey olditem right) key < oldkey = itemof key left key > oldkey = itemof key right otherwise = Just olditem contentsof :: Tree t -> [(Int,t)] contentsof Empty = [] contentsof (Node left key item right) = contentsof left ++ (key,item) : contentsof right contentsof :: Tree t -> [(Int,t)] contentsof = let cont Empty acc = acc cont (Node left key item right) acc = cont left $ (key,item) : cont right acc in flip cont [] Tällaisen rekursiivisen tyypin arvojoukko A suurin Uusi on korekursiivinen kuten listojen A suurin [t] mutta monimutkaisempi, koska sillä voi olla useita konstruktoreita ja niillä monia rekursiivisia kenttiä. 53

15 Esimerkiksi rusetti = Node rusetti 1 "i" rusetti on määritelmän mukainen hakupuu jonka Tyyppi on Tree String. Tyyppi Maybe t on puolestaan luonteva hakuoperaation itemof tulokselle koska se on Just se jos puussa on annettua avainta key vastaava tietoalkio Nothing jos sellaista ei ole. Siten Maybe on tyyppiturvallinen tapa ilmaista sellaiset funktiot, joilla ei ehkä olekaan mitään oikeaa tulosta. Rakenteinen induktio ja rekursio Aiemmin näimme myös listainduktion, jolla voi osoittaa väitteitä listatyypin arvoista. Se on erikoistapaus rakenteisesta (structural) induktiosta, jolla voi osoittaa väitteitä rekursiivisesti määriteltyjen Tyyppien arvoista. Koska laiskassa kielessä rekursiivisten tyyppien arvojoukot kuten A suurin Uusi sisältävät myös äärettömiä alkioita kuten rusetti ja pohja-arvon kuten Uusi ei induktio taaskaan tarkkaan ottaen päde......mutta se pätee yhä äärellisillä arvoilla A pienin Uusi Asuurin Uusi. Kun halutaan osoittaa väite φ rakenteisella induktiolla jonkin tyypin u kaikille äärellisille arvoille A pienin u niin... perustapauksena tarkastellaan jokaista tyypin u sellaista konstruktoria, jolla ei ole yhtään rekursiivista kenttää, ja osoitetaan että φ pätee sille. Hakupuutyypissämme Tree t osoitettaisiin φ siis sen konstruktorille Empty. induktiivisena tapauksena tarkastellaan jokaista tyypin u sellaista konstruktoria, jolla on rekursiivisia kenttiä, ja osoitetaan että φ pätee sille, kun oletetaan että φ pätee niiden kenttien arvoille. Hakupuutyypissämme Tree t osoitettaisiin φ siis sen konstruktorille Node kun oletetaan, että φ pätee vasemmalle ja oikealle alipuulle left ja right. Jos tyypin u jokaisella konstruktorilla on rekursiivisia kenttiä, niin tyypillä u on vain äärettömiä arvoja (sekä u ) eikä induktio edes lähde käyntiin tämäkin on siis mahdollista laiskassa kielessä. Osoitetaan rakenteisella induktiolla, että funktio contentsof palauttaa saamansa puun (avain,sen tietoalkio)-parit sisäjärjestyksessä. Perustapauksena tyhjä puu Empty palauttaa tyhjän listan [] ja se on oikein, koska tyhjässä puussa ei ole solmuja. Induktiivisena tapauksena tarkastellaan solmua Node left key item right. Induktio-oletuksena on, että contentsof left palautti sen vasemman alipuun ja contentsof right sen oikean alipuun parit sisäjärjestyksessä. 54

16 Sen nojalla myös tämä solmu palauttaa oikean tuloksen, koska vastaavassa rekursiohaarassa sen(key,item)-pari sijoitetaan niiden väliin, eli oikealle paikalleen. Tämä contentsof on funktionaalinen vastine iteraattorille: Sen avulla voimme kulkea puun solmu solmulta (tässä sisäjärjestyksessä) laiskana listana, ilman erityistä iteraattoria (joka olisikin tilallinen idea). Voimme myös ohjelmoida rekursiivisesti määritellyn tietotyypin rakenteen suhteen listarekursion tapaan: Määritellään funktio tapauksina siten, että... perustapauksina käsitellään ne konstruktorit, joissa ei ole rekursiivisia kenttiä. Niissä tulos voidaan määritellä suoraan ilman rekursiokutsuja. rekursiivisina tapauksina käsitellään ne konstruktorit, joissa on rekursiivisia kenttiä. Nämä rekursiiviset kentät käsitellään sopivilla rekursiokutsuilla. Kehitämme esimerkkinä funktion additem, joka lisää annetun avaimen newkey ja sen tietoalkion newitem hakupuuhun. Viittausten läpikuultavuuden vuoksi lisääminen tarkoittaa sellaisen uuden puun rakentamista, jossa on myös tämä uusi (newkey,newitem)-pari. Myös vanha puu säilyy muuttumattomana. Jakaudutaan ensin tapauksiin puutyypin konstruktorien mukaan: additem :: Int -> t -> Tree t -> Tree t additem newkey newitem Empty =? additem newkey newitem (Node left oldkey olditem right) =? Ei-rekursiivisen konstruktorin Empty ei-rekursiivinen haara on 1-solmuinen puu, jossa on vain tämä pari: additem newkey newitem Empty = Node Empty newkey newitem Empty Rekursiivisen konstruktorin Node rekursiivisessa haarassa sen Hahmo antoi nykyisen solmun avaimelle nimen oldkey joten voimme haarautua edelleen veraamalla sitä uuteen avaimeen newkey: additem newkey newitem (Node left oldkey olditem right) = newkey < oldkey =? newkey > oldkey =? otherwise =? Tässä käytetään Preluden määrittelemää vakiota otherwise = True esittämään tällaista viimeistä vartijaa. Tässä otherwise-haarassa oldkey ja newkey ovat siis samat, joten siinä vain korvataan oldkeyn vanha tietoalkio olditem uudella tietoalkiolla newitem: otherwise = Node left oldkey newitem right 55

17 Kun newkey < oldkey niin lisäys tehdään vasempaan alipuuhun, jolle Hahmo antoi nimen left. Koska kyseessä on rekursiivinen kenttä, käytetään rekursiivista kutsua: newkey < oldkey = Node (additem newkey newitem left) oldkey olditem right Ja symmetrisesti lisäys oikeaan alipuuhun nimeltään right: newkey > oldkey = Node left oldkey olditem (additem newkey newitem right) Nyt funktiolla on kaikki haarat eli se on valmis. Jokaisella rekursiivisesti määritellyllä tietotyypillä onkin oma luontainen rekursionsa joka voitaisiin määritellä samaan tapaan kuin foldr listoille. Nämäkin foldit ovat monikäyttöisiä, joskaan eivät aivan yhtä yleisesti käytettyjä kuin listoilla. Samaa luontaisen käsittelytavan ideaa voi käyttää muissakin kuin rekursiivisissa tietotyypeissä. Prelude sisältää esimerkiksi funktion maybe :: b -> (a -> b) -> Maybe a -> b joka esittää luontaisen tavan jolla Tyyppiä Maybe a olevia arvoja käsitellään silloin kun tuloksena halutaan Tyyppiä b oleva arvo: Nothingin vastine on jokin arvo Just x vie arvon x :: a funktioon joka antaa tuloksen Tyyppiä b. Kerääjäparametreista ja jatkeista contentsof on siis hyödyllinen funktio mutta tehoton: Kun contentsof käsittelee nykyistä Nodea, niin se käy läpi koko vasemman alipuunsa left tuottaman listan voidakseen liittää sen perään nykyisen Noden pari (key,item) sekä oikean alipuun right tuottaman listan. Siten contentsof käy samoja pareja läpi yhä uudelleen. Esimerkiksi vasemmalle nojaavassa n-solmuisessa puussa build [(i,()) i <- [1..n]] jokaisen solmun (i,()) lisääminen käy uudelleen läpi koko vasemmassa alipuussa luodun listan ja niin edelleen. [(1,()),(2,()),(3,()),...,(i 1,())] Tämän moninkertaisen läpikäynnin takia contentsof vie kokonaisuudessaan pahimmillaan Ω(n 2 ) askelta. Jotta solmulista olisi riittävän tehokas funktionaalinen vastine iteraattoreille, niin se täytyy pystyä muodostamaan O(n) askeleessa. 56

18 Tämän hitauden syynä on siis, että listan loppuun lisääminen on hidasta mutta alkuun nopeaa. Kehitetään siis funktiosta contentsof versio, jossa pari (key,item) lisätäänkin sopivan listan alkuun. Lähdetään siis kehittämään uutta funktiota cont :: Tree t -> [(Int,t)] -> [(Int,t)] cont puu acc = contentsof puu ++ acc eli jossa lisäparametri acc on se lista jolla vanhan funktion contentsof tulosta pitää jatkaa ja jonka alkuun pari (key,item) voidaan nopeasti liittää. Tässä määritellään se tulos, jonka uusi funktio cont laskee mutta tavoitteenamme on sellainen funktio, joka laskee sen eri tavalla ja nopeammin kuin tämä määritelmä sen tekisi. Lisäparametrin acc alkuarvon voi laskea tuloksen määritelmästä cont puu alkuarvo = contentsof puu ++ alkuarvo ja siitä, että tällä alkuarvolla haluamme lopputulokseksi = contentsof puu josta saadaan alkuarvoksi listojen konkatenaatio-operaattorin (++) (oikeanpuoleinen) neutraalialkio []. Empty-haaran voi laskea cont Empty acc = contentsof Empty ++ acc soveltamalla tuloksen määritelmää vasemmalta oikealle = [] ++ acc funktion contentsof Empty-haarasta = acc Node-haaran voi laskea cont (Node left key item right) acc = contentsof (Node left key item right) ++ acc soveltamalla tuloksen määritelmää vasemmalta oikealle = (contentsof left ++ (key,item) : contentsof right) ++ acc funktion contentsof Node-haarasta. Siihen sovelletaan listojen konkatenaatiooperaattorin (++) liitännäisyyttä (associativity) (x ++ y) ++ z = x ++ (y ++ z) = contentsof left ++ ((key,item) : contentsof right ++ acc) = cont left ((key,item) : cont right acc) soveltamalla kahdesti tuloksen määritelmää oikealta vasemmalle. contentsof yhdistää nämä kolme laskelmaa. 57

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Tällä luennolla Algebralliset tietotyypit Hahmonsovitus (pattern matching) Primitiivirekursio Esimerkkinä binäärinen hakupuu Muistattehan...

Lisätiedot

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

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla 2.5. YDIN-HASKELL 19 tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla kirjaimilla. Jos Γ ja ovat tyyppilausekkeita, niin Γ on tyyppilauseke. Nuoli kirjoitetaan koneella

Lisätiedot

Tyyppejä ja vähän muutakin. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Tyyppejä ja vähän muutakin. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Tyyppejä ja vähän muutakin TIEA341 Funktio ohjelmointi 1 Syksy 2005 Viime luennolla... Haskellin alkeita pääasiassa Hello World!... ja muita tutunoloisia ohjelmia Haskellilla Haskellin voima on kuitenkin

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 10 Todistamisesta Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Samuuden todistaminen usein onnistuu ihan laskemalla

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 5 Ympärysmitta. Puut. Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 CASE: YMPÄRYSMITTA Lasketaan kuvioiden ympärysmittoja

Lisätiedot

Luku 3. Listankäsittelyä. 3.1 Listat

Luku 3. Listankäsittelyä. 3.1 Listat Luku 3 Listankäsittelyä Funktio-ohjelmoinnin tärkein yksittäinen tietorakenne on lista. Listankäsittely on paitsi käytännöllisesti oleellinen aihe, se myös valaisee funktio-ohjelmoinnin ideaa. 3.1 Listat

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 6 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

Hakupuut. tässä luvussa tarkastelemme puita tiedon tallennusrakenteina

Hakupuut. tässä luvussa tarkastelemme puita tiedon tallennusrakenteina Hakupuut tässä luvussa tarkastelemme puita tiedon tallennusrakenteina hakupuun avulla voidaan toteuttaa kaikki joukko-tietotyypin operaatiot (myös succ ja pred) pahimman tapauksen aikavaativuus on tavallisella

Lisätiedot

58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut

58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut 58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut 1. Palautetaan vielä mieleen O-notaation määritelmä. Olkoon f ja g funktioita luonnollisilta luvuilta positiivisille

Lisätiedot

Testaa: Vertaa pinon merkkijono syötteeseen merkki kerrallaan. Jos löytyy ero, hylkää. Jos pino tyhjenee samaan aikaan, kun syöte loppuu, niin

Testaa: Vertaa pinon merkkijono syötteeseen merkki kerrallaan. Jos löytyy ero, hylkää. Jos pino tyhjenee samaan aikaan, kun syöte loppuu, niin Yhteydettömien kielioppien ja pinoautomaattien yhteys [Sipser s. 117 124] Todistamme, että yhteydettömien kielioppien tuottamat kielet ovat tasan samat kuin ne, jotka voidaan tunnistaa pinoautomaatilla.

Lisätiedot

Lisää pysähtymisaiheisia ongelmia

Lisää pysähtymisaiheisia ongelmia Lisää pysähtymisaiheisia ongelmia Lause: Pysähtymättömyysongelma H missä H = { w111x w validi koodi, M w ei pysähdy syötteellä x } ei ole rekursiivisesti lueteltava. Todistus: Pysähtymisongelman komplementti

Lisätiedot

Tyyppiluokat II konstruktoriluokat, funktionaaliset riippuvuudet. TIES341 Funktio-ohjelmointi 2 Kevät 2006

Tyyppiluokat II konstruktoriluokat, funktionaaliset riippuvuudet. TIES341 Funktio-ohjelmointi 2 Kevät 2006 Tyyppiluokat II konstruktoriluokat, funktionaaliset riippuvuudet TIES341 Funktio-ohjelmointi 2 Kevät 2006 Alkuperäislähteitä Philip Wadler & Stephen Blott: How to make ad-hoc polymorphism less ad-hoc,

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 9 Kombinaattoreista Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Currying Haskell-funktio ottaa aina vain yhden

Lisätiedot

Luku 4. Tietorakenteet funktio-ohjelmoinnissa. 4.1 Äärelliset kuvaukset

Luku 4. Tietorakenteet funktio-ohjelmoinnissa. 4.1 Äärelliset kuvaukset Luku 4 Tietorakenteet funktio-ohjelmoinnissa Koska funktio-ohjelmoinnissa ei käytetä tuhoavaa päivitystä (sijoituslausetta ja sen johdannaisia), eivät läheskään kaikki valtavirtaohjelmoinnista tutut tietorakenteet

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA34 Funktio-ohjelmointi, kevät 2008 Luento 3 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 2. tammikuuta 2008 Ydin-Haskell: Syntaksi Lausekkeita (e) ovat: nimettömät funktiot: \x

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 4 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 17. tammikuuta 2008 Modulin viimeistelyä module Shape ( Shape ( Rectangle, E l l i p

Lisätiedot

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset 815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

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

Laajennetaan vielä Ydin-Haskellia ymmärtämään vakiomäärittelyt. Määrittely on muotoa 2.6. TIETOKONE LASKIMENA 23 Edellä esitetty Ydin-Haskell on hyvin lähellä sitä kieltä, jota GHCi (Glasgow Haskell Compiler, Interactive) sekä muut Haskell-järjestelmät suostuvat ymmärtämään. Esimerkiksi:

Lisätiedot

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä Rekursiolause Laskennan teorian opintopiiri Sebastian Björkqvist 23. helmikuuta 2014 Tiivistelmä Työssä käydään läpi itsereplikoituvien ohjelmien toimintaa sekä esitetään ja todistetaan rekursiolause,

Lisätiedot

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

Tämän vuoksi kannattaa ottaa käytännöksi aina kirjoittaa uuden funktion tyyppi näkyviin, ennen kuin alkaa sen määritemää kirjoittamaan. 3.1. LISTAT 35 destaan pisteittäisesti: init :: [α] [α] init (x : []) = [] init (x : xs) = x : init xs Varuskirjastoon kuuluu myös funktiot take ja drop, jotka ottavat tai tiputtavat pois, funktiosta riippuen,

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 2 vastaukset Harjoituksen aiheena on BNF-merkinnän käyttö ja yhteys rekursiivisesti etenevään jäsentäjään. Tehtävä 1. Mitkä ilmaukset seuraava

Lisätiedot

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

Geneeriset tyypit. TIES542 Ohjelmointikielten periaatteet, kevät Antti-Juhani Kaijanaho. Jyväskylän yliopisto Tietotekniikan laitos Geneeriset tyypit TIES542 Ohjelmointikielten periaatteet, kevät 2007 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 6. maaliskuuta 2007 Kysymys Mitä yhteistä on seuraavilla funktioilla?

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 7. huhtikuuta 2017 Vastaa kaikkiin tehtäviin. Tee jokainen tehtävä erilliselle konseptiarkille. Kirjoittamasi luokat, funktiot ja aliohjelmat

Lisätiedot

Tietorakenteet ja algoritmit - syksy 2015 1

Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 2 Tietorakenteet ja algoritmit Johdanto Ari Korhonen Tietorakenteet ja algoritmit - syksy 2015 1. JOHDANTO 1.1 Määritelmiä

Lisätiedot

811120P Diskreetit rakenteet

811120P Diskreetit rakenteet 811120P Diskreetit rakenteet 2016-2017 ari.vesanen (at) oulu.fi 5. Rekursio ja induktio Rekursio tarkoittaa jonkin asian määrittelyä itseensä viittaamalla Tietojenkäsittelyssä algoritmin määrittely niin,

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 11 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Listakomprehensio Uusi tapa luoda (ja muokata) listoja: [ lauseke

Lisätiedot

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 7: Funktionaalista ohjelmointia (mm. SICP 3.5) Riku Saikkonen 13. 11. 2012 Sisältö 1 Laiskaa laskentaa: delay ja force 2 Funktionaalinen I/O 3 Funktionaalista

Lisätiedot

A274101 TIETORAKENTEET JA ALGORITMIT

A274101 TIETORAKENTEET JA ALGORITMIT A274101 TIETORAKENTEET JA ALGORITMIT PUURAKENTEET, BINÄÄRIPUU, TASAPAINOTETUT PUUT MIKÄ ON PUUTIETORAKENNE? Esim. Viereinen kuva esittää erästä puuta. Tietojenkäsittelytieteessä puut kasvavat alaspäin.

Lisätiedot

Esimerkki: Laskin (alkua) TIEA341 Funktio ohjelmointi 1 Syksy 2005

Esimerkki: Laskin (alkua) TIEA341 Funktio ohjelmointi 1 Syksy 2005 Esimerkki: Laskin (alkua) TIEA341 Funktio ohjelmointi 1 Syksy 2005 Esimerkki: Laskin Liukulukulaskentaa Yhteen, vähennys, kerto ja jakolaskut Syötteenä laskutehtävä, tulosteena tulos tai virheilmoitus

Lisätiedot

Vasen johto S AB ab ab esittää jäsennyspuun kasvattamista vasemmalta alkaen:

Vasen johto S AB ab ab esittää jäsennyspuun kasvattamista vasemmalta alkaen: Vasen johto S AB ab ab esittää jäsennyspuun kasvattamista vasemmalta alkaen: S A S B Samaan jäsennyspuuhun päästään myös johdolla S AB Ab ab: S A S B Yhteen jäsennyspuuhun liittyy aina tasan yksi vasen

Lisätiedot

AVL-puut. eräs tapa tasapainottaa binäärihakupuu siten, että korkeus on O(log n) kun puussa on n avainta

AVL-puut. eräs tapa tasapainottaa binäärihakupuu siten, että korkeus on O(log n) kun puussa on n avainta AVL-puut eräs tapa tasapainottaa binäärihakupuu siten, että korkeus on O(log n) kun puussa on n avainta pohjana jo esitetyt binäärihakupuiden operaatiot tasapainotus vie pahimmillaan lisäajan lisäys- ja

Lisätiedot

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016 ICS-C2000 Tietojenkäsittelyteoria Kevät 206 Kierros 0, 2. 24. maaliskuuta Huom! Perjantaina 25. maaliskuuta ei ole laskareita (pitkäperjantai), käykää vapaasti valitsemassanne ryhmässä aiemmin viikolla.

Lisätiedot

koska sellainen vaaditaan jotta oma tyyppimme Tree k t pääsee jäseneksi Luokkaan Eq.

koska sellainen vaaditaan jotta oma tyyppimme Tree k t pääsee jäseneksi Luokkaan Eq. Määritellään esimerkkinä hakupuillemme sellainen samuus x == y joka pätee täsmälleen silloin kun puissa x ja y on samat(avain,tietoalkio)-parit riippumatta siitä minkä muotoisia puut x ja y ovat. Olemme

Lisätiedot

Algoritmit 2. Luento 2 Ke Timo Männikkö

Algoritmit 2. Luento 2 Ke Timo Männikkö Algoritmit 2 Luento 2 Ke 15.3.2017 Timo Männikkö Luento 2 Tietorakenteet Lineaarinen lista, binääripuu Prioriteettijono Kekorakenne Keko-operaatiot Keon toteutus taulukolla Algoritmit 2 Kevät 2017 Luento

Lisätiedot

Taas laskin. TIES341 Funktio ohjelmointi 2 Kevät 2006

Taas laskin. TIES341 Funktio ohjelmointi 2 Kevät 2006 Taas laskin TIES341 Funktio ohjelmointi 2 Kevät 2006 Rakennepuutyyppi data Term = C Rational T F V String Term :+: Term Term : : Term Term :*: Term Term :/: Term Term :==: Term Term :/=: Term Term :

Lisätiedot

Haskell ohjelmointikielen tyyppijärjestelmä

Haskell ohjelmointikielen tyyppijärjestelmä Haskell ohjelmointikielen tyyppijärjestelmä Sakari Jokinen Helsinki 19. huhtikuuta 2004 Ohjelmointikielten perusteet - seminaarityö HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos 1 Johdanto 1 Tyyppien

Lisätiedot

TKT20001 Tietorakenteet ja algoritmit Erilliskoe , malliratkaisut (Jyrki Kivinen)

TKT20001 Tietorakenteet ja algoritmit Erilliskoe , malliratkaisut (Jyrki Kivinen) TKT0001 Tietorakenteet ja algoritmit Erilliskoe 5.1.01, malliratkaisut (Jyrki Kivinen) 1. [1 pistettä] (a) Esitä algoritmi, joka poistaa kahteen suuntaan linkitetystä järjestämättömästä tunnussolmullisesta

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Luento 14: Monadit Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 21. tammikuuta 2008 Tyyppien tyypit eli luonteet engl. kind tyyppinimet, kuten

Lisätiedot

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

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A. Tehtävä. Tämä tehtävä on aineistotehtävä, jossa esitetään ensin tehtävän teoria. Sen jälkeen esitetään neljä kysymystä, joissa tätä teoriaa pitää soveltaa. Mitään aikaisempaa tehtävän aihepiirin tuntemusta

Lisätiedot

Säännöllisten kielten sulkeumaominaisuudet

Säännöllisten kielten sulkeumaominaisuudet Säännöllisten kielten sulkeumaominaisuudet Osoitamme nyt, että säännöllisten kielten joukko on suljettu yhdisteen, konkatenaation ja tähtioperaation suhteen. Toisin sanoen jos A ja B ovat säännöllisiä,

Lisätiedot

Tietorakenteet, laskuharjoitus 7, ratkaisuja

Tietorakenteet, laskuharjoitus 7, ratkaisuja Tietorakenteet, laskuharjoitus, ratkaisuja. Seuraava kuvasarja näyttää B + -puun muutokset lisäysten jälkeen. Avaimet ja 5 mahtuvat lehtisolmuihin, joten niiden lisäys ei muuta puun rakennetta. Avain 9

Lisätiedot

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari 1 1. JOHDANTO 1.1 Määritelmiä 1.2 Tietorakenteen ja algoritmin valinta 1.3 Algoritmit ja tiedon määrä 1.4 Tietorakenteet ja toiminnot 1.5 Esimerkki:

Lisätiedot

3. Hakupuut. B-puu on hakupuun laji, joka sopii mm. tietokantasovelluksiin, joissa rakenne on talletettu kiintolevylle eikä keskusmuistiin.

3. Hakupuut. B-puu on hakupuun laji, joka sopii mm. tietokantasovelluksiin, joissa rakenne on talletettu kiintolevylle eikä keskusmuistiin. 3. Hakupuut Hakupuu on listaa tehokkaampi dynaamisen joukon toteutus. Erityisesti suurilla tietomäärillä hakupuu kannattaa tasapainottaa, jolloin päivitysoperaatioista tulee hankalampia toteuttaa mutta

Lisätiedot

Algoritmit 2. Luento 2 To Timo Männikkö

Algoritmit 2. Luento 2 To Timo Männikkö Algoritmit 2 Luento 2 To 14.3.2019 Timo Männikkö Luento 2 Tietorakenteet Lineaarinen lista, binääripuu Prioriteettijono Kekorakenne Keko-operaatiot Keon toteutus taulukolla Algoritmit 2 Kevät 2019 Luento

Lisätiedot

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

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

Lisätiedot

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit Tietorakenteet ja algoritmit Rekursio Rekursion käyttötapauksia Rekursio määritelmissä Rekursio ongelmanratkaisussa ja ohjelmointitekniikkana Esimerkkejä taulukolla Esimerkkejä linkatulla listalla Hanoin

Lisätiedot

Ei-yhteydettömät kielet [Sipser luku 2.3]

Ei-yhteydettömät kielet [Sipser luku 2.3] Ei-yhteydettömät kielet [Sipser luku 2.3] Yhteydettömille kielille pätee samantapainen pumppauslemma kuin säännöllisille kielille. Siinä kuitenkin pumpataan kahta osamerkkijonoa samaan tahtiin. Lause 2.25

Lisätiedot

Olkoon seuraavaksi G 2 sellainen tasan n solmua sisältävä suunnattu verkko,

Olkoon seuraavaksi G 2 sellainen tasan n solmua sisältävä suunnattu verkko, Tehtävä 1 : 1 a) Olkoon G heikosti yhtenäinen suunnattu verkko, jossa on yhteensä n solmua. Määritelmän nojalla verkko G S on yhtenäinen, jolloin verkoksi T voidaan valita jokin verkon G S virittävä alipuu.

Lisätiedot

Abstraktit tietotyypit. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Abstraktit tietotyypit. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Abstraktit tietotyypit TIEA341 Funktio ohjelmointi 1 Syksy 2005 Data abstraktio Abstraktio on ohjelmoinnin tärkein väline Data abstraktio abstrahoi dataa Abstrakti tietotyyppi Koostuu kolmesta asiasta:

Lisätiedot

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5) Alkuarvot ja tyyppimuunnokset (1/5) Aiemmin olemme jo antaneet muuttujille alkuarvoja, esimerkiksi: int luku = 123; Alkuarvon on oltava muuttujan tietotyypin mukainen, esimerkiksi int-muuttujilla kokonaisluku,

Lisätiedot

(0 1) 010(0 1) Koska kieli on yksinkertainen, muodostetaan sen tunnistava epädeterministinen q 0 q 1 q 2 q3

(0 1) 010(0 1) Koska kieli on yksinkertainen, muodostetaan sen tunnistava epädeterministinen q 0 q 1 q 2 q3 T-79.48 Tietojenkäsittelyteorian perusteet Tentti 25..23 mallivastaukset. Tehtävä: Kuvaa seuraavat kielet sekä säännölisten lausekkeiden että determinististen äärellisten automaattien avulla: (a) L = {w

Lisätiedot

Laiska laskenta, korekursio ja äärettömyys. TIEA341 Funktio ohjelmointi Syksy 2005

Laiska laskenta, korekursio ja äärettömyys. TIEA341 Funktio ohjelmointi Syksy 2005 Laiska laskenta, korekursio ja äärettömyys TIEA341 Funktio ohjelmointi Syksy 2005 Muistatko graafinsievennyksen? DAG esitys ja graafinsievennys DAG esitys Lausekkeen rakennepuu, jossa yhteiset alilausekkeet

Lisätiedot

Algoritmit 1. Luento 3 Ti Timo Männikkö

Algoritmit 1. Luento 3 Ti Timo Männikkö Algoritmit 1 Luento 3 Ti 17.1.2017 Timo Männikkö Luento 3 Algoritmin analysointi Rekursio Lomituslajittelu Aikavaativuus Tietorakenteet Pino Algoritmit 1 Kevät 2017 Luento 3 Ti 17.1.2017 2/27 Algoritmien

Lisätiedot

Algoritmit 1. Luento 1 Ti Timo Männikkö

Algoritmit 1. Luento 1 Ti Timo Männikkö Algoritmit 1 Luento 1 Ti 10.1.2017 Timo Männikkö Luento 1 Algoritmi Algoritmin toteutus Ongelman ratkaiseminen Algoritmin tehokkuus Algoritmin suoritusaika Algoritmin analysointi Algoritmit 1 Kevät 2017

Lisätiedot

Pinot, jonot, yleisemmin sekvenssit: kokoelma peräkkäisiä alkioita (lineaarinen järjestys) Yleisempi tilanne: alkioiden hierarkia

Pinot, jonot, yleisemmin sekvenssit: kokoelma peräkkäisiä alkioita (lineaarinen järjestys) Yleisempi tilanne: alkioiden hierarkia Pinot, jonot, yleisemmin sekvenssit: kokoelma peräkkäisiä alkioita (lineaarinen järjestys) Yleisempi tilanne: alkioiden hierarkia Kukin alkio (viite) talletettuna solmuun (node) vastaa paikan käsitettä

Lisätiedot

8.5 Takarekursiosta. Sanoimme luvun 8.3 foldl -esimerkissämme että

8.5 Takarekursiosta. Sanoimme luvun 8.3 foldl -esimerkissämme että 85 Takarekursiosta Sanoimme luvun 83 foldl -esimerkissämme että foldl :: (a -> b -> a) -> a -> [b] -> a foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs olisi pelkkä silmukka Tämä johtuu siitä, että

Lisätiedot

Algoritmi on periaatteellisella tasolla seuraava:

Algoritmi on periaatteellisella tasolla seuraava: Algoritmi on periaatteellisella tasolla seuraava: Dijkstra(V, E, l, v 0 ): S := { v 0 } D[v 0 ] := 0 for v V S do D[v] := l(v 0, v) end for while S V do valitse v V S jolle D[v] on minimaalinen S := S

Lisätiedot

4. Tehtävässä halutaan todistaa seuraava ongelma ratkeamattomaksi:

4. Tehtävässä halutaan todistaa seuraava ongelma ratkeamattomaksi: T-79.148 Kevät 2004 Tietojenkäsittelyteorian perusteet Harjoitus 12 Demonstraatiotehtävien ratkaisut 4. Tehtävässä halutaan todistaa seuraava ongelma ratkeamattomaksi: Hyväksyykö annettu Turingin kone

Lisätiedot

Matematiikan tukikurssi, kurssikerta 2

Matematiikan tukikurssi, kurssikerta 2 Matematiikan tukikurssi kurssikerta 1 Relaatioista Oletetaan kaksi alkiota a ja b. Näistä kumpikin kuuluu johonkin tiettyyn joukkoon mahdollisesti ne kuuluvat eri joukkoihin; merkitään a A ja b B. Voidaan

Lisätiedot

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

Vaihtoehtoinen tapa määritellä funktioita f : N R on Rekursio Funktio f : N R määritellään yleensä antamalla lauseke funktion arvolle f (n). Vaihtoehtoinen tapa määritellä funktioita f : N R on käyttää rekursiota: 1 (Alkuarvot) Ilmoitetaan funktion arvot

Lisätiedot

58131 Tietorakenteet ja algoritmit (kevät 2014) Uusinta- ja erilliskoe, , vastauksia

58131 Tietorakenteet ja algoritmit (kevät 2014) Uusinta- ja erilliskoe, , vastauksia 58131 Tietorakenteet ja algoritmit (kevät 2014) Uusinta- ja erilliskoe, 10..2014, vastauksia 1. [9 pistettä] (a) Todistetaan 2n 2 + n + 5 = O(n 2 ): Kun n 1 on 2n 2 + n + 5 2n 2 + n 2 +5n 2 = 8n 2. Eli

Lisätiedot

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta

811312A Tietorakenteet ja algoritmit Kertausta kurssin alkuosasta 811312A Tietorakenteet ja algoritmit 2017-2018 Kertausta kurssin alkuosasta II Perustietorakenteet Pino, jono ja listat tunnettava Osattava soveltaa rakenteita algoritmeissa Osattava päätellä operaatioiden

Lisätiedot

Todistusmenetelmiä Miksi pitää todistaa?

Todistusmenetelmiä Miksi pitää todistaa? Todistusmenetelmiä Miksi pitää todistaa? LUKUTEORIA JA TO- DISTAMINEN, MAA11 Todistus on looginen päättelyketju, jossa oletuksista, määritelmistä, aksioomeista sekä aiemmin todistetuista tuloksista lähtien

Lisätiedot

Matematiikan johdantokurssi, syksy 2016 Harjoitus 11, ratkaisuista

Matematiikan johdantokurssi, syksy 2016 Harjoitus 11, ratkaisuista Matematiikan johdantokurssi, syksy 06 Harjoitus, ratkaisuista. Valitse seuraaville säännöille mahdollisimman laajat lähtöjoukot ja sopivat maalijoukot niin, että syntyy kahden muuttujan funktiot (ks. monisteen

Lisätiedot

Algoritmit 1. Luento 12 Ti Timo Männikkö

Algoritmit 1. Luento 12 Ti Timo Männikkö Algoritmit 1 Luento 12 Ti 19.2.2019 Timo Männikkö Luento 12 Osittamisen tasapainoisuus Pikalajittelun vaativuus Lajittelumenetelmien vaativuus Laskentalajittelu Lokerolajittelu Kantalukulajittelu Algoritmit

Lisätiedot

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

Reaalilukuvälit, leikkaus ja unioni (1/2) Luvut Luonnolliset luvut N = {0, 1, 2, 3,... } Kokonaisluvut Z = {..., 2, 1, 0, 1, 2,... } Rationaaliluvut (jaksolliset desimaaliluvut) Q = {m/n m, n Z, n 0} Irrationaaliluvut eli jaksottomat desimaaliluvut

Lisätiedot

ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012

ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012 ALGORITMIT 1 DEMOVASTAUKSET KEVÄT 2012 1.1. (a) Jaettava m, jakaja n. Vähennetään luku n luvusta m niin kauan kuin m pysyy ei-negatiivisena. Jos jäljelle jää nolla, jaettava oli tasan jaollinen. int m,

Lisätiedot

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

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

Lisätiedot

5.5 Jäsenninkombinaattoreista

5.5 Jäsenninkombinaattoreista 5.5. JÄSENNINKOMBINAATTOREISTA 67 type Env α = FiniteMap String α data EnvT m α = MkE (Env Integer m (Env Integer, α)) instance Transformer EnvT where promote mp = MkE $ λenv mp λr return $(env, r) instance

Lisätiedot

811120P Diskreetit rakenteet

811120P Diskreetit rakenteet 811120P Diskreetit rakenteet 2018-2019 1. Algoritmeista 1.1 Algoritmin käsite Algoritmi keskeinen laskennassa Määrittelee prosessin, joka suorittaa annetun tehtävän Esimerkiksi Nimien järjestäminen aakkosjärjestykseen

Lisätiedot

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit IDL - proseduurit 25. huhtikuuta 2017 Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

Jäsennys. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Jäsennys. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Jäsennys TIEA341 Funktio ohjelmointi 1 Syksy 2005 Muistutus: Laskutehtävä ja tulos data Laskutehtava = Luku Double Yhteen Laskutehtava Laskutehtava Vahennys Laskutehtava Laskutehtava Tulo Laskutehtava

Lisätiedot

Tehtävän V.1 ratkaisuehdotus Tietorakenteet, syksy 2003

Tehtävän V.1 ratkaisuehdotus Tietorakenteet, syksy 2003 Tehtävän V.1 ratkaisuehdotus Tietorakenteet, syksy 2003 Matti Nykänen 5. joulukuuta 2003 1 Satelliitit Muunnetaan luennoilla luonnosteltua toteutusta seuraavaksi: Korvataan puusolmun p kentät p. key ja

Lisätiedot

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014 18. syyskuuta 2014 IDL - proseduurit Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

Algoritmit 1. Luento 7 Ti Timo Männikkö

Algoritmit 1. Luento 7 Ti Timo Männikkö Algoritmit 1 Luento 7 Ti 31.1.2017 Timo Männikkö Luento 7 Järjestetty binääripuu Binääripuiden termejä Binääripuiden operaatiot Solmun haku, lisäys, poisto Algoritmit 1 Kevät 2017 Luento 7 Ti 31.1.2017

Lisätiedot

Imperatiivisen ohjelmoinnin peruskäsitteet. Meidän käyttämän pseudokielen lauseiden syntaksi

Imperatiivisen ohjelmoinnin peruskäsitteet. Meidän käyttämän pseudokielen lauseiden syntaksi Imperatiivisen ohjelmoinnin peruskäsitteet muuttuja muuttujissa oleva data voi olla yksinkertaista eli primitiivistä (esim. luvut ja merkit) tai rakenteista jolloin puhutaan tietorakenteista. puhuttaessa

Lisätiedot

Todistus: Aiemmin esitetyn mukaan jos A ja A ovat rekursiivisesti lueteltavia, niin A on rekursiivinen.

Todistus: Aiemmin esitetyn mukaan jos A ja A ovat rekursiivisesti lueteltavia, niin A on rekursiivinen. Lause: Tyhjyysongelma ei ole osittain ratkeava; ts. kieli ei ole rekursiivisesti lueteltava. L e = { w { 0, 1 } L(M w ) = } Todistus: Aiemmin esitetyn mukaan jos A ja A ovat rekursiivisesti lueteltavia,

Lisätiedot

811120P Diskreetit rakenteet

811120P Diskreetit rakenteet 811120P Diskreetit rakenteet 2016-2017 1. Algoritmeista 1.1 Algoritmin käsite Algoritmi keskeinen laskennassa Määrittelee prosessin, joka suorittaa annetun tehtävän Esimerkiksi Nimien järjestäminen aakkosjärjestykseen

Lisätiedot

Laskennan teoria (kevät 2006) Harjoitus 3, ratkaisuja

Laskennan teoria (kevät 2006) Harjoitus 3, ratkaisuja 581336 Laskennan teoria (kevät 2006) Harjoitus 3, ratkaisuja 1. S! axc X! axc X! by c Y! by c Y! " 2. (a) Tehtävänä on konstruoida rajoittamaton kielioppi, joka tuottaa kielen f0 n 1 n jn 1g. Vaihe1: alkutilanteen

Lisätiedot

JFO: Johdatus funktionaaliseen ohjelmointiin

JFO: Johdatus funktionaaliseen ohjelmointiin JFO: Johdatus funktionaaliseen ohjelmointiin Matti Nykänen Tietojenkäsittelytieteen laitos, Itä-Suomen yliopisto matti.nykanen@uef.fi Lukuvuosi 2010-11, IV periodi Sisältö 1 Johdanto 1 1.1 Historiaa.....................................

Lisätiedot

S BAB ABA A aas bba B bbs c

S BAB ABA A aas bba B bbs c T-79.148 Kevät 2003 Tietojenkäsittelyteorian perusteet Harjoitus 8 Demonstraatiotehtävien ratkaisut 4. Tehtävä: Laadi algoritmi, joka testaa onko annetun yhteydettömän kieliopin G = V, Σ, P, S) tuottama

Lisätiedot

M = (Q, Σ, Γ, δ, q 0, q acc, q rej )

M = (Q, Σ, Γ, δ, q 0, q acc, q rej ) 6. LASKETTAVUUSTEORIAA Churchin Turingin teesi: Mielivaltainen (riittävän vahva) laskulaite Turingin kone. Laskettavuusteoria: Tarkastellaan mitä Turingin koneilla voi ja erityisesti mitä ei voi laskea.

Lisätiedot

Tietorakenteet (syksy 2013)

Tietorakenteet (syksy 2013) Tietorakenteet (syksy 2013) Harjoitus 1 (6.9.2013) Huom. Sinun on osallistuttava perjantain laskuharjoitustilaisuuteen ja tehtävä vähintään kaksi tehtävää, jotta voit jatkaa kurssilla. Näiden laskuharjoitusten

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 25.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 25.2.2009 1 / 34 Syötteessä useita lukuja samalla rivillä Seuraavassa esimerkissä käyttäjä antaa useita lukuja samalla

Lisätiedot

Jos sekaannuksen vaaraa ei ole, samastamme säännöllisen lausekkeen ja sen esittämän kielen (eli kirjoitamme R vaikka tarkoitammekin L(R)).

Jos sekaannuksen vaaraa ei ole, samastamme säännöllisen lausekkeen ja sen esittämän kielen (eli kirjoitamme R vaikka tarkoitammekin L(R)). Jos sekaannuksen vaaraa ei ole, samastamme säännöllisen lausekkeen ja sen esittämän kielen (eli kirjoitamme R vaikka tarkoitammekin L(R)). Esimerkkejä: Σ koostuu kaikista aakkoston Σ merkkijonoista ja

Lisätiedot

Laskennan mallit (syksy 2010) Harjoitus 4, ratkaisuja

Laskennan mallit (syksy 2010) Harjoitus 4, ratkaisuja 582206 Laskennan mallit (syksy 2010) Harjoitus 4, ratkaisuja 1. Esitä tilakaaviona NFA N = (Q, Σ, δ, q 0, F ), missä Q = { q 0, q 1, q 2, q 3, q 4, q 5, q 6, q 7 }, Σ = { a, b, c }, F = { q 4 } ja δ on

Lisätiedot

Luonnollisen päättelyn luotettavuus

Luonnollisen päättelyn luotettavuus Luonnollisen päättelyn luotettavuus Luotettavuuden todistamiseksi määrittelemme täsmällisesti, milloin merkkijono on deduktio. Tässä ei ole sisällytetty päättelysääntöihin iteraatiosääntöä, koska sitä

Lisätiedot

Tietorakenteet ja algoritmit syksy Laskuharjoitus 1

Tietorakenteet ja algoritmit syksy Laskuharjoitus 1 Tietorakenteet ja algoritmit syksy 2012 Laskuharjoitus 1 1. Tietojenkäsittelijä voi ajatella logaritmia usein seuraavasti: a-kantainen logaritmi log a n kertoo, kuinka monta kertaa luku n pitää jakaa a:lla,

Lisätiedot

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta 5. 1. Toteuta Pythonilla seuraava ohjelma:

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta 5. 1. Toteuta Pythonilla seuraava ohjelma: Kerta 2 Kerta 3 Kerta 4 Kerta 5 Kerta 2 1. Toteuta Pythonilla seuraava ohjelma: 2. Tulosta Pythonilla seuraavat luvut allekkain a. 0 10 (eli, näyttää tältä: 0 1 2 3 4 5 6 7 8 9 10 b. 0 100 c. 50 100 3.

Lisätiedot

5.3 Ratkeavia ongelmia

5.3 Ratkeavia ongelmia 153 5.3 Ratkeavia ongelmia Deterministisen äärellisten automaattien (DFA) hyväksymisongelma: hyväksyykö annettu automaatti B merkkijonon w? Ongelmaa vastaava formaali kieli on A DFA = { B, w B on DFA,

Lisätiedot

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin Raimo Nikkilä Aalto-yliopiston sähkötekniikan korkeakoulu - Automaation tietotekniikan tutkimusryhmä 17. tammikuuta 2013

Lisätiedot

Matematiikan tukikurssi

Matematiikan tukikurssi Matematiikan tukikurssi Kurssikerta 1 Määrittelyjoukoista Tarkastellaan funktiota, jonka määrittelevä yhtälö on f(x) = x. Jos funktion lähtöjoukoksi määrittelee vaikkapa suljetun välin [0, 1], on funktio

Lisätiedot

Tietueet. Tietueiden määrittely

Tietueet. Tietueiden määrittely Tietueet Tietueiden määrittely Tietue on tietorakenne, joka kokoaa yhteen eri tyyppistä tietoa yhdeksi asiakokonaisuudeksi. Tähän kokonaisuuteen voidaan viitata yhteisellä nimellä. Auttaa ohjelmoijaa järjestelemään

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 4 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten lauseisiin, lausekkeisiin ja aliohjelmiin liittyvät kysymykset. Tehtävä 1. Mitä

Lisätiedot

= 5! 2 2!3! = = 10. Edelleen tästä joukosta voidaan valita kolme särmää yhteensä = 10! 3 3!7! = = 120

= 5! 2 2!3! = = 10. Edelleen tästä joukosta voidaan valita kolme särmää yhteensä = 10! 3 3!7! = = 120 Tehtävä 1 : 1 Merkitään jatkossa kirjaimella H kaikkien solmujoukon V sellaisten verkkojen kokoelmaa, joissa on tasan kolme särmää. a) Jokainen verkko G H toteuttaa väitteen E(G) [V]. Toisaalta jokainen

Lisätiedot

T Syksy 2002 Tietojenkäsittelyteorian perusteet Harjoitus 8 Demonstraatiotehtävien ratkaisut

T Syksy 2002 Tietojenkäsittelyteorian perusteet Harjoitus 8 Demonstraatiotehtävien ratkaisut T-79.148 Syksy 2002 Tietojenkäsittelyteorian perusteet Harjoitus 8 Demonstraatiotehtävien ratkaisut 4. Tehtävä: Laadi algoritmi, joka testaa onko annetun yhteydettömän kieliopin G = V, Σ, P, S tuottama

Lisätiedot

TIEA341 Funktio-ohjelmointi 1, kevät 2008

TIEA341 Funktio-ohjelmointi 1, kevät 2008 TIEA341 Funktio-ohjelmointi 1, kevät 2008 Antti-Juhani Kaijanaho Jyväskylän yliopisto Tietotekniikan laitos 10. tammikuuta 2008 Arvot... ovat laskutoimituksen lopputuloksia... ovat lausekkeita, joihin

Lisätiedot

ELM GROUP 04. Teemu Laakso Henrik Talarmo

ELM GROUP 04. Teemu Laakso Henrik Talarmo ELM GROUP 04 Teemu Laakso Henrik Talarmo 23. marraskuuta 2017 Sisältö 1 Johdanto 1 2 Ominaisuuksia 2 2.1 Muuttujat ja tietorakenteet...................... 2 2.2 Funktiot................................

Lisätiedot

Algoritmit 2. Luento 13 Ti Timo Männikkö

Algoritmit 2. Luento 13 Ti Timo Männikkö Algoritmit 2 Luento 13 Ti 30.4.2019 Timo Männikkö Luento 13 Simuloitu jäähdytys Merkkijonon sovitus Horspoolin algoritmi Ositus ja rekursio Rekursion toteutus Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019

Lisätiedot

14.1 Rekursio tyypitetyssä lambda-kielessä

14.1 Rekursio tyypitetyssä lambda-kielessä Luku 14 Rekursiiviset tyypit Edellisessä luvussa esitetyt tietue- ja varianttityypit eivät yksinään riitä kovin mielenkiintoisten tietorakenteiden toteuttamiseen. Useimmissa ohjelmissa tarvitaan erilaisia

Lisätiedot