811120P Diskreetit rakenteet Juha Kortelainen Ari Vesanen Syksy 2018
Esipuhe Tämä moniste on pääosin Juha Kortelaisen laatima. Olen muuttanut algoritmien esitystavan ja tehnyt pieniä korjauksia. Ari Vesanen 2
Sisältö 1 Algoritmeista 5 1.1 Algoritmin käsite.......................... 5 1.2 Kontrollirakenteet.......................... 8 1.3 Muita esimerkkejä algoritmeista.................. 12 2 Lukujärjestelmät ja niiden muunnokset; lukujen aritmetiikka 14 2.1 Reaaliluvut ja kymmenjärjestelmä................. 14 2.2 Binaarijärjestelmä.......................... 15 2.3 Muuntaminen kymmenjärjestelmästä binaarijärjestelmään... 16 2.4 Oktaali- ja heksadesimaalijärjestelmät.............. 19 2.5 Aritmetiikka muissa kuin kymmenjärjestelmässsä........ 21 2.6 Lukujen esittäminen tietokoneessa................. 23 2.6.1 Kokonaislukujen esittäminen................ 23 2.6.2 Kokonaislukuaritmetiikka................. 26 2.6.3 Reaalilukujen esittäminen................. 29 2.6.4 Reaalilukuaritmetiikka................... 33 3 Logiikka (propositiokalkyyli, predikaattikalkyylin alkeet) 35 3.1 Propositiot............................. 35 3.2 Loogiset operaatiot (konnektiivit) ja totuustaulut............................. 37 3.3 Yhdistetyt propositiot ja lauselogiikan ilmaisut.......... 39 3.4 Looginen ekvivalenssi........................ 42 3.5 Logiikan lait............................. 44 3.6 Loogisesta päättelystä....................... 47 3.7 Predikaattilogiikka......................... 48 3.8 Todistusmenetelmiä......................... 53 4 Joukot, relaatiot ja funktiot 56 4.1 Johdanto............................... 56 4.2 Osajoukot, joukko-operaatiot ja Vennin diagrammit......................... 57 3
4.3 Joukon koko ja joukkojen karteesinen tulo............ 61 4.4 Joukkojen tietokone-esitys..................... 63 4.5 Relaatiot............................... 64 4.6 Funktiot ja laskenta tietokoneella................. 71 4.7 Yhdistetty funktio ja käänteisfunktio............... 74 4.8 Funktiot ohjelmointikielissä.................... 78 5 Rekursio ja induktio 80 5.1 Rekursio ja jonot.......................... 80 5.2 Todistaminen induktiolla...................... 84 5.3 Induktion yhteys rekursioon.................... 87 5.4 Lineaarinen rekursioyhtälö..................... 88 5.5 Rekursiivisesti määritellyt funktiot ja rekursiiviset algoritmit.. 93 6 Alkeislukuteoria (jaollisuus ja siihen liittyvät algoritmit) 97 6.1 Lukuteoriasta yleisesti....................... 97 6.2 Jaollisuus ja alkuluvut....................... 98 6.3 Suurin yhteinen tekijä ja Eukleideen algoritmi............................... 99 6.4 Kongruenssit............................ 104 6.4.1 Pseudosatunnaislukujen generointi............ 106 7 Kombinatoriikka (lukumäärien laskeminen) 110 7.1 Kombinatoriikka ja laskenta tietokeoneella............ 110 7.2 Summa- ja erotusperiaate..................... 110 7.3 Tuloperiaate............................. 111 7.4 Permutaatiot............................ 112 7.5 Kombinaatiot............................ 113 7.6 Sovellus: Otos palautuksella.................... 115 7.7 Laatikkoperiaate.......................... 117 4
1 Algoritmeista Algoritmin laatiminen on olennainen osa tietokoneohjelmointia. Tässä luvussa perehdytään algoritmin käsitteeseen ja esitellään merkintätapa, jolla algoritmeja voidaan esittää. 1.1 Algoritmin käsite Keskeinen tehtävä laskennassa (joko käsin tai tietokoneella suoritetussa) on sellaisen prosessin suunnittelu, joka suorittaa annetun tehtävän. Tämä tehtävä voi olla esimerkiksi nimien järjestäminen aakkosjärjestykseen; laskentalaitteiden kytkeminen verkkoon mahdollisimman edullisesti; luvun esityksen muuttaminen kantajärjestelmästä toiseen; viestin salaaminen; digitaalisen piirin suunnittelu mikrosiruun; tai robottikäden liikkeen optimointi. Jokaisessa edellä esitetyssä esimerkkitapauksissa ihminen ja/tai tietokone kykenee suorittamaan tehtävän äärellistä ohjejoukkoa käyttäen askelittain ja yksikäsitteisesti; kyse on algoritmisesta toiminnasta. Esimerkki algoritmista: (käteis)automaatin käyttö. 1. Sujauta pankkikorttisi sille varattuun aukkoon. 2. Kirjoita tunnuslukusi (PIN), kun sitä kysytään. 3. Valitse vaihtoehto 'käteisnosto' valikosta. 4. Kirjoita summa, jonka haluat nostaa. 5. Valitse jompikumpi vaihtoehtoisista kirjaustapahtumista: 'näytölle', 'kuitille'. 6. Ota korttisi ja nostamasi summa. 7. Jos olit valinnut kohdassa 5 vaihtoehdon 'kuitille', ota kuitti. 5
Edellä askeleet 1 7 muodostavat ohjejonon, joka voidaan suorittaa peräjälkeen. Kukin ohje on verrattain selkeä ja yksikäsitteinen, joten keskivertoihminen kykenee ohjeita noudattamaan. Lisäksi prosessi pysähtyy äärellisen askelmäärän jälkeen. Olemme kuvanneet algoritmin olennaisia piirteitä. Algoritmilla on mm. seuraavanlaisia ominaisuuksia. 1. Algoritmi annetaan äärellisenä ohjejoukkona (jotain merkintäjärjestelmää/kieltä käyttäen). 2. On olemassa toteuttaja (esimerkiksi ihminen tai kone), joka pystyy seuraamaan ohjeita ja suorittamaan tarvittavat toimenpiteet. 3. On olemassa välineet tiedon tuottamiseen, tallentamiseen ja käyttöönottoon. 4. Algoritmi käsittelee aina tietoa (syöte) ja tulostaa tietoa (tuloste). Toteuttaja reagoi ohjeisiin siten, että millä tahansa sovittua muotoa olevalla syötteellä toimenpiteet ovat yksinkertaisia ja ne suoritetaan askelittain. 5. Algoritmin toimenpiteet suoritetaan deterministisesti. Samalla syötteellä saadaan siten aina sama tulostus. 6. Syötteen tulee olla sovittua muotoa ja äärellisesti määriteltävissä. syötteen koolla ei kuitenkaan ole kiinteää ylärajaa. 7. Tiedon tallentamiseen käytettävän muistitilan koko on äärellinen, mutta ei kiinteä. Muistitilan määrää ei siten ole rajoitettu. 8. Jokaisella sovittua muotoa olevalla syötteellä algoritmi pysähtyy äärellisen askelmäärän jälkeen. 9. Jokaisella sovittua muotoa olevalla syötteellä algoritmi joko ei tulosta mitään tai antaa äärellisen, yksikäsitteisen ja hyvin määritellyn tulosteen. Järjestelmää, joka toteuttaa yllä asetetut ehdot kohtia 8 ja 9 mahdollisesti lukuunottamatta, kutsutaan semialgoritmiksi. On siis mahdollista, että semialgoritmi (vaikka syöte olisi sovittua muotoakin) ei pysähdy äärellisessä askelmäärässä ja sen toiminta voi periaatteessa jatkua rajattomiin. Semialgoritmin ottamien askelten (ja sen suorittamien toimenpiteiden) lukumäärä on tällöin ääretön. Tietysti tulostekin voi tällöin olla äärettömän pituinen. Samalla syötteellä semialgoritmin on kuitenkin aina tuotettava sama tulostus. syötteen ja (mahdollisen) tulostuksen välillä on siten funktionaalinen riippuvuus. Algoritmi muistuttaa selvästi tietokoneohjelmaa. Tietokoneohjelma onkin algoritmin toteutus jollakin ohjelmointikielellä. Käytämme tässä termiä 'ohjel- 6
mointikieli' ei ainoastaan monikäyttöön tarkoitetuista kielistä kuten Pascal, Java, C ja C++, vaan myös erikoiskielistä, kuten makrokäskyjä sisältävistä taulukkolaskenta- ja tietokantakielistä. Algoritmin suunnittelu on yksi askel ohjelmien kirjoittamisessa. Tästä eteenpäin käsittelemme pääosin sellaisia algoritmeja, jotka voidaan toteuttaa tietokoneella. Jotta algoritmien suunnittelu voitaisiin eriyttää jollakin erityisellä kielellä ohjelmoinnista. Kirjoitamme algoritmit pseudokoodia (eli pseudokieltä) käyttäen. Pseudokoodi on strukturoitua suomea (ja englantia) ja se sallii meidän keskittyä algoritmin rakenteeseen ilman että meidän täytyisi muistaa jonkin ohjelmointikielen yksityiskohtia. Esim. 1. Kirjoita algoritmi, joka laskee ympyrän pinta-alan, kun ympyrän säde on annettu. Ratkaisu. Muistetaaan, että r-säteisen ympyrän pinta-ala on π r 2. Algoritmi on seuraavanlainen: Input: Reaaliluku r Output: r-säteisen ympyrän pinta-ala ALA(r) 1. ala = π *r*r 2. return ala Algoritmin otsikossa annetaan algoritmin syöte (Input) ja tulostus (Output). Jälkimmäinen tarkoittaa joko algoritmin paluuarvoa tai muuten sen suorittamisen tulosta. Lisäksi annetaan algoritmin nimi ja parametrilista, jotta sitä voidaan kutsua. Edellisessä esimerkissä algoritmia voitaisiin kutsua esimerkiksi ALA( 1.0), jolloin se palauttaisi 1.0-säteisen ympyrän pinta-alan. Esimerkissä 1 esiintyy myös muita rakenteita, joita käytetään, kun kirjoitetaan algoritmeja pseudokoodilla: askeleet numeroidaan, jotta niihin viittaminen olisi helppoa. Selittäviä tekstejä, jotka eivät suoritukseen kuulu voidaan lisätä kommenttimerkeissä // tai /* */ askelten tekstiin. Näistä // tarkoittaa rivin lopun olevan kommenttia ja merkkien /* ja */ välissä sijaitsevan tekstin olevan kommenttia. Symboli = tarkoittaa sijoituslauseketta; siten askeleessa 1 lausekkeen π r 2 arvo määritetään ja tulos sijoitetaan muuttujan ala arvoksi. Tämä arvo annetaan algoritmin kutsujalle paluuarvona, kun algoritmin suoritus päättyy. Huomaa, että matematiikan kaavat voidaan kirjoittaa matemaattisin merkinnöin, joten meidän ei tarvitse huolehtia siitä miten kaavan yksityiskohdat kirjoitettaisiin ohjelmointikielellä. Tämä koskee edellä symbolia π, jolle ei yleensä ole ohjelmointikielessä omaa merkintää. Laskennan esittämiseen konkreettisesti eri ohjelmointikielillä perehdytään ohjelmoinnin kursseissa. 7
1.2 Kontrollirakenteet Esimerkin 1 algoritmissa askeleet suoritetaan järjestyksessä peräperään. Tavallisesti algoritmit sisältävät kuitenkin kontrollirakenteita, ohjeita, jotka määrittävät kuinka monta kertaa ja/tai millä ehdoilla käskyjä suoritetaan. Itse asiassa nämä kontrollirakenteet (muistin käytöllä terästettynä) aiheuttavat sen, että tietokoneet eroavat laskentakapasiteetiltaan tavanomaisista aritmeettisista laskukoneista. Esim. 2. Kirjoita algoritmi, joka annetusta äärellisestä reaalilukujonosta määrittää sen pienimmän alkion. Ratkaisu. Algoritmin idea: tarkastellaan kutakin jonon lukua erikseen ja pidetään kussakin askeleessa kirjaa siihen asti pienimmästä. Kun lukujono on käyty läpi, tiedetään koko jonon pienin arvo. Merkitään käsiteltävää lukujonoa ikään kuin taulukkona X[1,.., n], jolloin jonon luvut ovat X[1], X[2],..., X[n]. Siten jonon i:s luku on X[i], kun i on jokin kokonaisluku väliltä [1, n]. Input: Reaalilukutaulukko X[1,..,n], n>=1 Output: Taulukon X pienin luku MINIMI(X) 1. min = X[1] 2. for i=2 to n do 3. if X[i] < min then 4. min = X[i] 5. return min Esimerkin 2 algoritmissa esiintyy kaksi kontrollirakennetta: fordo ja ifthen. Näistä ifthen määrittelee ehtolauseen: mikäli avainsanaa if seuraava ehto on tosi, sen jälkeen tulevat sisennetyt lauseet suoritetaan. Ellei ehto ole tosi, ohjelman suoritusta jatketaan lauseesta, joka on sisennetty samalle tasolle kuin if. Käyttämässämme pseudokielessä ilmaistaan kontrollirakenteiden rajat sisennyksellä edellä mainittuun tapaan. Näin ollen kontrollirakenteessa sisennettyjä lauseita käsitellään ikään kuin yhtenä lauseena, jota myös nimitetään yhdistetyksi lauseeksi. Kontrollirakenne fordo määrittelee määrätyn toistolauseen: rivejä 3 ja 4 suoritetaan muuttujan i peräkkäisillä arvolla alkaen arvosta 2 ja päättyen arvoon n. Näin ollen rivien muodostamassa silmukassa verrataan kaikkia taulukon alkioita ensimmäistä lukuunottamatta muuttujan min arvoon. Jos taulukon alkio on tätä pienempi, muuttujan arvo päivitetään. Lopuksi muuttujan arvo on siten pienin taulukon alkioista. 8
Alla olevassa taulukossa listataan tärkeimmät pseudokoodeissamme esiintyvät kontrollirakenteet. Kontrollirakenteet Kontrollirakenne ifthen ifthenelse fordo whiledo dowhile Esimerkki käytöstä if x<0 then x=-x if x >= 0 then y=x else y=-x sum=0 for i=1 to 10 do sum=sum+1 answer='q' while (answer!= 'y' and answer!= 'n') do print 'Vastaa y tai n' read answer do print 'Vastaa y tai n' read answer while (answer!= 'y' and answer!= 'n') Pseudokoodissa esiintyvät muuttujat ovat tavanomaisia matemaattisia muuttujia, jotka voidaan nimetä ja varustaa tarvittaessa alaindekseillä. Pseudokoodin laskuoperaatioita ovat normaalit aritmeettiset laskutoimitukset (esim. yhteen-, vähennys-, kerto- ja jakolasku), joita sovelletaan muuttujiin ja (reaaliluku)vakioihin. Myös tavanomaisia funktioita (esim. potenssiin korotus, juurenotto, eksponentti- ja logaritmifunktiot sekä trigonometriset funktiot) voidaan käyttää. Pseudokielen ehdot ovat muuttujista ja vakioista (ja joskus jopa metakielen sanoista) muodostettuja väittämiä, joiden totuusarvo on aina joko tosi tai epätosi ja joiden todenperäisyys voidaan testata. Lausekkeissa tarvitaan usein seuraavia operaattoreita: 9
operaattori tarkoitus == Vertailee yhtäsuuruutta, esim. x==5 on tosi, jos muuttujan x arvo on 5.!= Vertailee epäsuuruutta, esim. x!=5 on tosi, jos muuttujan x arvo ei ole 5. < Aidosti pienempi, esim. x<5 on tosi, jos muuttujan x arvo pienempi kuin 5. <= Pienempi tai yhtäsuuri, esim. x<=5 on tosi, jos muuttujan x arvo pienempi tai yhtäsuuri kuin 5. > Aidosti suurempi, esim. x>5 on tosi, jos muuttujan x arvo suurempi kuin 5. >= Suurempi tai yhtäsuuri, esim. x>=5 on tosi, jos muuttujan x arvo suurempi tai yhtäsuuri kuin 5. Pseudokielen lauseita ovat, syöttölauseiden (read) ja tulostuslauseiden (print) lisäksi, muiden muassa sijoituslause ja edellä mainitut kontrollilauseet. Näiden muoto ja merkitys on kuvattu seuraavassa. Sijoituslause on muotoa x = q oleva rakenne, missä x on muuttuja ja q voi olla vakio tai muuttuja tai vakioista ja muuttujista aritmeettisia operaatioita ja/tai perusfunktioita käyttäen muodostettu lauseke. Sijoituslauseen suorittamisen jälkeen muuttujan x arvo on sama kuin lausekkeen q arvo. Ehtolause if-then on muotoa if C then S oleva rakenne, missä C on ehto ja S mikä tahansa pseudokielen lause. Jos C on voimassa, suoritetaan S. Jos C ei ole voimassa, ei tehdä mitään ja lause katsotaan suoritetuksi. Edellä S voi olla useammasta lauseesta muodostettu yhdistetty lause. Ehtolause if-then-else on muotoa if C then S 1 else S 2 oleva rakenne, missä C on ehto ja S 1 sekä S 2 mitä tahansa pseudokoodilauseita. Jos C on voimassa, suoritetaan S 1, ellei, suoritetaan S 2. Tämän jälkeen lauseke on suoritettu. Edellä S 1 ja S 2 voivat olla useammasta lauseesta muodostettuja yhdistettyjä lauseita. Määrätyssä toistolauseessa for i = a to b do S on i (indeksi)muuttuja, a ja b kokonaislukuvakioita ja S lause. Jos a b, lause S suoritetaan peräkkäin i:n arvoilla a, a + 1,..., b. Jos a > b, ei tehdä mitään ja lause katsotaan suoritetuksi. Toistolauseessa while C do S on C ehto ja S lause. Jos C on voimassa, lause 10
S suoritetaan ja siirrytään toistolauseen alkuun. Jos C ei ole voimassa, ei tehdä mitään ja toistolause katsotaan suoritetuksi. Täten lauseen S suorittaminen toistuu niin kauan kuin ehto C on voimassa. Edellä S voi olla useammasta lauseesta muodostettu yhdistetty lause. Huomaa, että mikäli ehto C on alussa tosi, lauseen S suorituksen täytyy vaikuttaa ehdon totuusarvoon tai saadaan aikaan ikuisesti suoritettava toistorakenne. Toistolausekkeessa do S while C on S lause ja C ehto. Suoritetaan S ja testataan onko C voimassa. Jos C on voimassa, palataan toistolauseen alkuun. Jos C ei ole voimassa, toistolause on suoritettu. Siten lauseke S suoritetaan kerran ja suorittamista jatketaan kunnes ehto C ei enää ole voimassa. Edellä S voi olla useammasta lauseesta muodostettu yhdistetty lause. Tässäkin tapauksessa ehdon C ollessa alkujaan tosi, lauseen S suorituksen täytyy vaikuttaa ehdon totuusarvoon tai saadaan aikaan ikuisesti suoritettava toistorakenne. Pseudokieliohjelma suoritetaan siten, että sen lauseet suoritetaan kirjoitusjärjestyksessä. Pseudokieli kykenee tarvittaessa käsittelemään lukuja, merkkejä, äärellisiä jonoja, äärellisiä joukkoja, taulukoita, pinoja, verkkoja jne. Kun tarkastellaan algoritmia ja pyritään löytämään siitä mahdolliset virheet, on tärkeää pystyä suorittamaan algoritmia. Tämä tehdään tyypillisesti ajamalla algoritmia joillakin esimerkkisyötteillä rivi kerrallaan. Suoritetaan esimerkin 2 algoritmi esimerkkisyötteellä X = {5, 3, 7, 6} ja n = 4. Siten X[1] = 5, X[2] = 3, X[3] = 7 ja X[4] = 6. Seuraavasta taulukosta käy ilmi algoritmin kulku ja muuttujien kulloisetkin arvot: rivi i X[i] min kommentti 1 - - 5 Ensimmäinen rivi, sijoitetaan taulukon ensimmäinen arvo muuttujaan min. 2 2 3 5 Silmukka alkaa. i = 2. 3 2 3 5 Verrataan taulukon arvoa muuttujaan min arvoon. Arvo pienempi. 4 2 3 3 Sijoitetaan muuttujalle min uusi arvo. 2 3 7 3 Silmukka jatkuu. i = 3. 3 3 7 3 Verrataan taulukon arvoa muuttujaan min arvoon. Arvo ei pienempi. 2 4 6 3 Silmukka jatkuu. i = 3. 3 4 6 3 Verrataan taulukon arvoa muuttujaan min arvoon. Arvo ei pienempi. Silmukka loppuu. 5 - - 3 Algoritmi loppuu ja palauttaa arvon 3. 11
1.3 Muita esimerkkejä algoritmeista Esim. 3. Laadi algoritmi, joka annetusta äärellisestä, n:stä merkistä c 1 c 2 c n koostuvasta merkkijonosta määrittää, koostuuko se pelkästään numeroista vai esiintyykö siinä muitakin symboleita ja tulostaa sitten asianmukaisen ilmoituksen. Ratkaisu. Käydään toistorakenteessa jonon merkit läpi (käyttäen muuttujaa i alaindeksinä). Apumuuttuja d saa arvon 1 ja keskeyttää toiston, jos kohdataan ei-numeerinen merkki. Input: Merkkijono C = c 1 c 2 c n, n >= 1 Output: Tulostus, onko merkkijonossa ainoastaan numeroita vai muitakin symboleita. TARKASTA_MERKIT(C) 1. i = 0 2. d = 0 3. while (i<n and d==0) do 4. i=i+1 5. if (c i ei ole numero) then 6. d=1 7. if d==1 then 8. print Merkkijonossa muitakin kuin numeroita 9. else 10. print Merkkijonossa vain numeroita Esim. 4. Kirjoita algoritmi, joka laskee arvon lausekkeelle x n, missä x on mielivaltainen reaaliluku ja n positiivinen kokonaisluku. Tässä oletetaan, että kertolasku on käytettävissä, mutta potenssiin korotus ei ole. Ratkaisu. Ratkaisun idea: Palautettava arvo on muuttujassa, joka alustetaan arvoon 1. Toistorakenteessa kerrotaan luvulla x muuttujan arvoa n kertaa. Huomaa, että toiston voisi toteuttaa myös for-do-rakenteella. Seuraavassa on kuitenkin valittu while-do-silmukka. Input: Reaaliluku x, positiivinen kokonaisluku n Output: Luku x n POTENSSI(x,n) 1. tulos = 1 2. i = 0 3. while i<n do 4. tulos = tulos*x 5. i=i+1 6. return tulos 12
Esim. 5. Laadi algoritmi, joka vaihtaa kahden muuttujan arvot. Ratkaisu. Input: Muuttujat x ja y Output: Muuttujien arvot vaihdetaan VAIHDA(x,y) 1. temp = x 2. x = y 3. y = temp Esim. 6. Työpaikkaan hakijoille on pidetty soveltuvuustesti, joka koostuu 30 monivalintakysymyksestä. Kullekin testiin osallistujalle on annettu yksikäsitteinen tunnisteluku. Suunnittele algoritmi, joka tulostaa osallistujat (tunnisteluvun mukaan), kunkin osallistujan saaman pistemäärän ja tiedotteen, kutsutaanko hakija haastatteluun (pistemäärä 24), asetetaanko hänet varalle (20 pistemäärä < 24) vai jääkö hakija huomiotta (pistemäärä < 20). Syöte koostuu hakijoiden lukumäärästä, hakijoiden soveltuvuustestivastauksista ja oikeista vastauksista. Ratkaisu. Seuraavassa n on hakijoiden lukumäärä. Oletetaan, että hakijoiden vastaukset tallennetaan kaksiulotteiseen taulukkoon A niin, että A[i][j] on hakijan i vastaus kysymykseen j (i = 1, 2,..., n, j = 1, 2,..., 30). Oikeat vastaukset tallennetaan taulukkoon C siten, että ja C[k] on oikea vastaus kysymykseen k (k = 1, 2,..., 30). Input: Taulukot A[1..n][1..30] ja C[1..30], n>=1 Taulukossa A hakijoiden vastaukset ja taulukossa C oikeat vastaukset Output: Tulostetaan hakijan numero, pistemaara ja status LUOKITTELE(A,C) 1. for i=1 to n do // Hakijan i pisteet 2. pist = 0 3. for j=1 to 30 do // Tarkistetaan vastaukset 4. if A[i][j] == C[j] then 5. pist = pist +1 6. if pist >= 24 then 7. print i,pist, haastatteluun 8. else if pist >= 20 then 9. print i,pist, varalle 10. else 11. print i,pist, huomiotta 13
2 Lukujärjestelmät ja niiden muunnokset; lukujen aritmetiikka Lukuja voidaan esittää usealla tavalla esim. eri kantajärjestelmissä. Tässä luvussa paneudutaan erityisesti lukujen esittämiseen tietokoneella. 2.1 Reaaliluvut ja kymmenjärjestelmä Tärkeimpiä lukujoukkoja ovat N = { 0, 1, 2,...} luonnolliset luvut N + = { 1, 2, 3,...} positiiviset kokonaisluvut Z = {..., 2, 1, 0, 1, 2,... } kokonaisluvut Q on rationaalilukujen joukko, ja R on reaalilukujen joukko. Luku on rationaaliluku, jos se voidaan esittää muodossa p, missä p Z ja q q N +. Reaaliluku, joka ei ole rationaaliluku, on irrationaaliluku. Tuttuja esimerkkejä irrationaaliluvuista ovat 2, Neperin luku e ja π. Reaaliluvut esitetään desimaalijärjestelmässä numerojonona, negatiivisen luvun edessä on miinusmerkki. Numerojono voi myös sisältää desimaalipilkun. Joidenkin lukujen desimaaliesitys on päättymätön; niitä ei voi esittää desimaalijärjestelmässä äärellisellä määrällä numeroita. Desimaalijärjestelmä on ns. paikkaan perustuva lukujärjestelmä; kullakin jonon numerolla on paikka-arvo, joka riippuu numeron sijainnista desimaalipisteeseen nähden. Desimaalipisteestä vasemmalle sijaitsevat järjestyksessä ykköset (10 0 ), kymmenet (10 1 ), sadat (10 2 ), tuhannet (10 3 ) jne... Desimaalipisteestä oikealle puolestaan järjestyksessä kymmenesosat (10 1 ), sadasosat (10 2 ), tuhannesosat (10 3 ), jne... Desimaaliluvun arvo saadaan kertomalla kukin numero paikka-arvollaan ja laskemalla näin 14
saadut luvut yhteen. Esimerkiksi 2386.75 = 2 10 3 + 3 10 2 + 8 10 1 + 6 10 0 + 7 10 1 + 5 10 2. 2.2 Binaarijärjestelmä Mitä tahansa luonnollista lukua, joka on ykköstä suurempi, voidaan käyttää paikkaan perustuvan lukujärjestelmän kantalukuna. Luvun 10 vakiintuminen kantaluvuksi todennäköisesti johtuu siitä, että ihmiset käyttivät muinoin kymmentä sormeaan laskemiseen. Esim. aikaa laskettaessa kantaluku on 60: 2 h 26 m 35 s = 2 60 2 + 26 60 1 + 35 60 0 sekuntia. Binaari- eli binäärijärjestelmässä kantaluku on 2; kun desimaalijärjestelmässä käytetään numeroja 0, 1,..., 9, binaarijärjestelmässä numerot (bitit) valitaan joukosta {0, 1}. Esimerkiksi 1101.01 2 on binaariluku, alaindeksi 2 ilmoittaa kantaluvun. Sekaannusten välttämiseksi kanta ilmoitetaan aina, kun käytössä on muu kuin desimaalijärjestelmä. Binaariluvun (desimaali)lukuarvon laskeminen (ja samalla muuntaminen desimaalijärjestelmään) saadaan kirjoittamalla luku 'auki': 1101.01 2 = 1 2 3 + 1 2 2 + 0 2 1 + 1 2 0 + 0 2 1 + 1 2 2 = 8 + 4 + 1 + 0.25 = 13.25. Digitaalisten tietokoneiden data varastoidaan, siirretään ja muokataan sellaisten tietoelementtien virtana, joita voidaan merkitä symboleilla 0 ja 1. 15
Taulukko binaarinen desimaali binaarinen desimaali 0 0 1 1 1011 11 10 2 1100 12 11 3 1101 13 100 4 1110 14 101 5 1111 15 110 6 10000 16 111 7 10001 17 1000 8 10010 18 1001 9 10011 19 1010 10 10100 20 2.3 Muuntaminen kymmenjärjestelmästä binaarijärjestelmään Kuinka muuntaa desimaalijärjestelmän luku binaariseksi? Ei ole mikään ihme, että tehtävä voidaan hoitaa algoritmilla. Teemme seuraavat huomiot: a) parittomien luonnollisten lukujen binaariesitys päättyy numeroon 1, ja b) parillisten luonnollisten lukujen binaariesitys päättyy numeroon 0. Siispä Luonnollisen luvun binaariesityksen (binaariluvun) viimeinen numero (bitti) saadaan jakojäännäksenä, kun luku jaetaan kahdella. Tarvitsemme seuraavat Pascal-tyyppiset operaatiot: aina, kun n N, on n div 2 se kokonaisosa, joka saadaan, kun n jaetaan kahdella ja n mod 2 se jakojäännös joka saadaan, kun n jaetaan kahdella. Selvästi poistamalla luonnollisen luvun n binaariesityksen viimeinen bitti, saadaan luonnollisen luvun n div 2 binaariesitys. Siten luonnollisen luvun n binaariesityksen toiseksi viimeinen bitti saadaan jakojäännöksenä, kun luku n div 2 jaetaan kahdella. Prosessia toistetaan, kunnes kokonaisosaksi tulee nolla. Kirjoitetaan koko prosessi algoritmiksi: 16
Input: Luonnollinen luku n Output: Luvun n binaariesitys lopusta alkuun tulostettuna MUUNNA_BIN(n) 1. do 2. print n mod 2 3. n = n div 2 4. while n!=0 Algoritmin tulostus luetaan käänteisessä järjestyksessä lopusta alkuun. Sovelletaan menetelmää lukuun n = 6. Askel n Tulostus 1 6-2.1 6 0 2.2 3-2.1 3 1 2.2 1-2.1 1 1 2.2 0 - Siispä luvun 6 binaariesitys on (110) 2. Esim. 1. Mikä on luvun 25 binaariesitys? Ratkaisu. 2 25 12 1 6 0 3 0 1 1 0 1 Siten 25 10 = 11001 2. Huom. 1. Edellistä algoritmia sovellettaessa on yleinen virhe jättää viimeinen askel suorittamatta; algoritmi päättyy vasta, kun jaettava menee nollaksi! Tarkastellaan nyt sitä, miten desimaaliluvun murto-osa muunnetaan binaariseksi. Oletetaan, että haluamme desimaaliluvun 0.375 binaariesityksen. Koska 17
0.375 < 0.5, täytyy desimaalipilkun oikella puolella olevan bitin (eli 'puolikasbitin', jonka paikka-arvo on 1 ) olla 0. Voimme ilmaista asian toisin: puolikasbitti on 0, koska 2 0.375 on vähemmän kuin 1. Olemme kehittäneet 2 säännön: Reaaliluvun x ( 0 x < 1) binaariesityksen puolikasbitti on luvun 2 x kokonaisosa. Tarvitsemme pari uutta merkintää. x on reaaliluvun x kokonaisosa frac(x) on reaaliluvun x murto-osa Esimerkiksi 2.7 = 2 ja frac(2.7) = 0.7. Aikaisemmin tehdyn huomion nojalla kertomalla murto-osaa toistuvasti kahdella, saamme luvun murto-osan binaariesityksen. Prosessi voi olla päättymätön, joten se, kuinka montaa numeroa käytetään, kannattaa ilmoittaa etukäteen. Input: Desimaaliluvun murto-osa x, numeroiden lukumäärä d Output: Luvun x binaariesitys tulostettuna MUUNNA_MURTO_BIN(x,d) 1. print 0. 2. do 3. i = i+1 4. y = 2*x 5. print y 6. x = frac(y) 7. while (x!=0 and i!=d) Esim. 2. Mikä on luvun 0.32 binaariesitys viiden numeron tarkkuudella? Ratkaisu. 32 2 0 64 1 28 0 56 1 12 0 24 18
Tulos luetaan nyt ylhäältä alaspäin (vasemmanpuolinmaisin sarake). Saadaan 0.32 10 = 0.01010. Pyöristystä ei suoriteta. Jos desimaaliluvussa on sekä kokonais- että murto-osa, lasketaan kumpaisenkin binaariesitys erikseen ja saadut tulokset yhdistetään. Siten 25.32 10 = (1101.01 010) 2. 2.4 Oktaali- ja heksadesimaalijärjestelmät Edellisessä kappaleessa esitetyt tekniikat voidaan yleistää koskemaan myäs muita kantajärjestelmiä kuin binaarista. Erityisesti kantoja 8 ja 16 käytetään laskennassa usein; syyt selviävät hetikohta. Kun käytössä on kantaluku 8 on kyse oktaalijärjestelmästä; tällöin luvut esitetään numeroiden 0, 1, 2, 3, 4, 5, 6, 7 avulla. Luvun jokaisen numeron paikkaarvo on tällöin kahdeksan potenssi. Esimerkiksi 374.2 8 = 3 8 2 + 7 8 1 + 4 8 0 + 2 8 1 = 252.25 10. Kantaluvun ollessa 16 olemme heksadesimaalijärjestelmässä ; tälläin tarvitaan 16 numeroa: numerojen 10, 11, 12, 13, 14, 15 sijasta käytetään isoja kirjaimia A, B, C, D, E, F. Siten käytässä on numerojoukko {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F }. Luvun jokaisen numeron paikka-arvo on 16:n potenssi. Esimerkiksi E9C.8 16 = 14 16 2 + 9 16 1 + 12 16 0 + 8 16 1 = 3740.5 10. Kun muunnetaan kymmenjärjestelmän lukua oktaali- tai heksadesimaalijärjestelmään, menetellään vastaavalla tavalla kuin binaaritapauksessa: luku 2 vain korvataan joko 8:lla tai 16:lla jakajana tai kertojana. Esim. 3. Muunna luku 275.4375 10 8-järjestelmään (oktaalijärjestelmään). Ratkaisu. Muunnetaan kokonaisosa. 8 275 34 3 4 2 0 4 19
Siten 275 10 = 423 8. Muunnetaan murto-osa. 4375 8 3 5000 4 0 Saadaan 0.4375 10 = 0.34 8. Yhdistetään tulokset, jolloin 275.4375 10 = 423.34 8. 16-järjestelmään (heksadesimaalijärjes- Esim. 4. Muunna luku 985.78125 10 telmään). Ratkaisu. Muunnetaan kokonaisosa. 16 985 61 9 3 13 0 3 Siten 985 10 = 3D9 16. Muunnetaan murto-osa. 78125 16 12 50000 8 0 Saadaan 0.78125 10 = 0.C8 16. Yhdistetään tulokset, jolloin 985.78125 10 = 3D9.C8 16. Olemme nähneet, että binaarijärjestelmä on luonteva laskennalle; se on järjestelmä, jota tietokoneet sisäisesti käyttävät. Mutta millä tavalla 8- ja 16- järjestelmät ovat hyödyllisiä? Binaarijärjestelmän huonoksi puoleksi voi laskea sen, että suurilla luvuilla on erittäin pitkät binaariesitykset(yli kolme kertaa pitemmät kuin desimaalijärjestelmässä). Suurten kantajärjestelmien etu on se, että luvut voidaan kirjoittaa käyttäen pienempää määrää numeroja. Kymmenjärjestelmä on epäkäytännöllinen, koska muuntaminen kantajärjestelmästä toiseen vaatii laskentakapasiteettia. Oktaali- ja heksadesimaalijärjestelmää käyttämällä vältetään pitkät numerosarjat ja lisäksi muuntaminen sujuu yksinkertaista algoritmia käyttäen. Kun muunnetaaan luku binaarijrjestelmästä 8-järjestelmään, ryhmitellään bitit kolmen pituisikksi jonoiksi molemmin puolin desimaalipistettä. Kukin kolmen bitin jono vastaa lukua 8-järjestelmässä. 20
Esim. 5. Muunna luku 10100011.10111 2 oktaalijärjestelmään. Ratkaisu. Nyt }{{} 010 2 }{{} 100 4 }{{} 011. }{{} 101 3 5 }{{} 110, joten 10100011.10111 2 = 243.56 8. 6 Muuntaminen oktaalijärjestelmästä binaariesitykseen on yhtä helppoa; kukin oktaalijärjestelmän numero korvataan 3-bittisellä binaariesityksellään. Etunollia ei saa jättää pois! Esim. 6. Muunna luku 514.7 8 binaariluvuksi. Ratkaisu. Saadaan 5 {}}{ 101 1 {}}{ 001 4 {}}{ 100. 7 {}}{ 111. Siispä 514.7 8 = 101001100.111 2. Muunto 2- ja 16-järjestelmien välillä on analoginen, paitsi että jokaista heksadesimaalinumeroa vastaa neljä bittiä. Esim. 7. Muunna luku 10111101001.110001 2 heksadesimaaliseksi. Ratkaisu. Nyt 0101 }{{} 1110 }{{} 1001 }{{}. 1100 }{{} 0100 }{{}, joten 5 E 9 C 4 10111101001.110001 2 = 5E9.C4 16. Esim. 8. Muunna luku B2.5D6 16 binaariluvuksi. Ratkaisu. Saadaan B 2 5 {}}{{}}{{}}{{}}{{}}{ 1011 0010. 0101 1101 0110. Siispä D 6 B2.5D6 16 = 10110010.010111010110 2. Heksadesimaalijärjestelmää käytetään tavallisesti esittämään muistiosan tai binaaritiedoston sisältä (ihmiselle) luettavassa muodossa, koska jokainen tavu (joka sisältää kahdeksan bittiä) voidaan esittää kahtena heksadesimaalinumerona. 2.5 Aritmetiikka muissa kuin kymmenjärjestelmässsä Laskutoimitusten (yhteenlasku, vähentäminen, kerto- ja jakolasku) suorittaminen muissa kuin kymmenjärjestelmässä tapahtuu niitä sääntöjä noudattaen, 21
jotka jo peruskoulussa opittiin kymmenjärjestelmälle; vain yhteen- ja kertolaskutaulut ovat erilaiset. Tarkastellaan nyt sitä, miten luonnollisten lukujen yhteen- ja kertolasku tapahtuu binaarijärjestelmässä. Yhteenlaskutaulu on tällöin seuraava. + 0 1 0 0 1 1 1 10 Lukuja lasketaan yhteen allekkain, mutta vain numeroja 0 ja 1 käyttäen. Esim. 9. Laske allekkain 11011 2 + 1110 2 (= 101001 2 ). Vähennyslasku suoritetaan 'tavanomaisesti' (vastaavasti kuin kymmenjärjestelmässä). Tietokone suorittaa vähennyslaskun eri tavalla. Esim. 10. Laske allekkain 11011 2 1110 2 (= 1101 2 ). Binaarijärjestelmän kertolaskutaulu on yksinkertainen: 0 1 0 0 0 1 0 1 'Pitkä kertolasku' binaarijärjestelmässä suoritetaan oikeastaan ilman kertolaskua; kertominenhan tapahtuu nollalla tai ykkäsellä. Esim. 11. Kerro allekkain 11010 2 1011 2 (= 100011110 2 ). 'Pitkä jakolasku' on sekin suoraviivainen suorittaa; tärkeää on muistaa, että murto-osa voi muodostua rajattoman pitkäksi, joten joskus täytyy päättää monenko (merkitsevän) numeron tarkkuudella vastaus annetaan. Esim. 12. Jaa jakokulmassa luku 11101 2 luvulla 101 2 kuuden merkitsevän numeron tarkkuudella. Huom. 2. Kymmenjärjestelmän eli desimaalijärjestelmän kantaluku on 10. Desimaaliluvut ovat kymmenjärjestelmään perustuva tapa esittää reaalilukuja ja niiden likiarvoja. Edellisen nojalla kokonaisluvut ovat desimaalilukuja. Mitä tarkoitetaan (desimaali)luvun merkitsevien numeroiden lukumäärällä? Sääntö on yksinkertainen: 22
(1) desimaaliluvun alussa olevia nollia ei lasketa merkitseviksi numeroiksi; (2) ilman desimaalipistettä esitetyn luvun lopussa olevia nollia ei lasketa merkitseviksi numeroiksi; ja (3) kaikki muut luvussa esiintyvät numerot ovat merkitseviä. Siten sekä luvussa 5300 että luvussa 0071 on kaksi merkitsevää numeroa, luvussa 0.0122 on kolme merkitsevää numeroa ja luvussa 0.0078550 viisi merkitsevää numeroa. Luvussa 10.0070 on kuusi merkitsevää numeroa. Edelleen luvussa 0.8200 10 4 on neljä merkitsevää numeroa, luvussa 0.820 10 4 kolme merkitsevää numeroa ja luvussa 0.82 10 4 kaksi merkitsevää numeroa. 2.6 Lukujen esittäminen tietokoneessa Edellisessä luvussa tarkasteltiin lukujen esittämistä binaarilukujärjestelmässä. Nyt käytämmme oppimiamme tekniikoita tutkiaksemme sitä, miten lukuja esitetään ja käsitellään binaarimuodossa tietokoneessa. Luvut esitetään digitaalisessa tietokoneessa tavallisesti kiinteän pituisina bittijonoina. Kokonaislukuja käsitellään eri tavalla kuin muita reaalilukuja, joten tapaukset tulee pitää erillään. Seuraavassa tarkastellaan verrattain yleisellä tasolla sitä, miten tietokoneet lukuja käsittelevät. Myös kurssissa Tietokonearkkitehtuuri perehdytään digitaalisen tiedon esitysmuotoihin tietokoneessa. 2.6.1 Kokonaislukujen esittäminen Kokonaisluvut (positiiviset, negatiiviset tai nolla) tallennetaan tietokoneessa tavujonoina, missä kukin tavu koostuu 8 bitistä. Ohjelmoija voi tavallisesti valita useammasta kokoluokasta (jotka vastaavat eri tavulukumääriä), mutta suoraan prosessorin käsittelemien kokonaislukujen koko määräytyy prosessorin suunnitteluperiaatteiden mukaan; neljä tavua on tällöin tavanomainen koko. Mukavuussyistä tarkastelemme seuraavassa kaksitavuisia kokonaislukuja, periaatteet ovat täysin samat kuin nelitavuisessa tapauksessa. Kuinka monta eri lukua voidaan tallentaa 16 bitin avulla? Koska kukin bitti voi saada kaksi 23
arvoa ( 0 tai 1), saamme (kombinatoriikan tuloperiaatteen nojalla): 2 2 2 (16 kertaa) = 2 16 = 65536 Esimerkiksi voimme tallentaa minkä tahansa luvun n, joka on välillä 32768 n 32767, asettamalla yksikäsitteisen 16 bitin jonon vastaamaan kutakin välin kokonaislukua. Muitakin arvoalueita voitaisiin käyttää (esim. 0 n 65535), mutta käyttäkelpoisin on tavallisesti sellainen väli, joka sisältää suunnilleen saman määrän positiivisia ja negatiivisia lukuja. Tavanomaisin tapa esittää luku n käyttäen 16 bittiä on seuraava. 1. Ensimmäinen bitti on ns. etumerkkibitti ; se on 0, jos n on nolla tai positiivinen ja 1, jos n on negatiivinen. 2. Jos n 0, loput 15 bittiä ovat n:n binaariesitys (varustettuna etunollilla, mikäli tarpeellista). Jos n < 0, loput 15 bittiä ovat ei-negatiivisen luvun n + 32768 binaariesitys. Luvun 2 15 = 32768 lisääminen lukuun n, kun n < 0 voi äkkiseltään vaikuttaa asioiden mutkistamiselta (mikseivät esim. etumerkin jälkeiset 15 bittiä esittäisi lukua n? 1 ) Syy on se, että lisäämällä luku 32768 lukuun n, saadaan esitystapa, joka yksinkertaistaa aritmeettisten operaatioiden suorittamista, kuten myöhemmin tullaan näkemään. Itse asiassa luvun 32768 lisääminen voidaan suorittaa sen jälkeen, kun luku n on muutettu binaarimuotoon. Tämä käy ilmi seuraavasta esimerkistä. Esim. 13. Määritä (kymmenjärjestelmän) luvun 6772 kuusitoistabittinen tietokone-esitys. Ratkaisu. Muunnetaan 6772 binaarimuotoon käyttäen 15 bittiä ja etunollia tarvittaessa. Saadaan 6772 10 = 001101001110100 2. 1 Merkintä n tarkoittaa luvun n itseisarvoa, joka määritellään: { n jos n 0 n = n jos n < 0 24
Koska luvun 32768 binaariesitys on 1000000000000000 2, meidän tulee suorittaa lasku 1000000000000000 2 001101001110100 2 = 110010110001100 2. Luvun 6772 kuusitoistabittinen tietokone-esitys on siten 1110010110001100. Saamme yleisen menetelmän: 1. Kaikki nollat vähennettävän binaariluvun lopussa (oikeanpuoleisessa päässä) säilyvät nollina vastauksessa. 2. Oikeanpuolimmaisin ykkönen säilyy ykkösenä vastauksessa. 3. kaikki muut bitit muuttuvat (nolla ykköseksi ja ykkönen nollaksi). Algoritmia soveltamalla saadaan positiivisen binaariluvun kakkosen komplementti (kannan 2 suhteen). Siten luvun 001101001110100 2 kakkosen komplementti on 110010110001100 2. Ei-negatiivisen binaariluvun ykkösen komplementti saadaan vaihtamalla sen jokainen bitti säännän 0 1, 1 0 mukaan. Binaariluvun ykkösen komplementti on yhtä pienempi kuin sen kakkosen komplementti. Tarkastellaan tilannetta hiukan yleisemmin. Olkoon n kokonaisluku, jolle 1 n 2 k 1, missä k N +. Oletetaan, että n on annettu k -bittissä binaarimuodossaan. Tälläin n:n k -bittinen kakkosen komplementti on luku 2 k n kirjoitettuna k -bittisessä binaarimuodossaan. Se saadaan soveltamalla yllä kuvattuja askelia lukuun n. Huomattakoon, että edellisiä askelia 1, 2 ja 3 ei voida käyttää luvun 32768 tietokone-esityksen määrittämiseen, koska luvun 32768 esittämiseen tarvitaan 16 bittiä. Tässä tapauksessa vähennyslaskun seurauksena saadaan 15 nollaa ja luvun 32768 tietokone-esitys on siten 1000000000000000. Esim. 14. Etsi seuraavien kokonaislukujen 16-bittinen tietokone-esitysmuoto. a) 9843 b) 15728 c) 4961. Ratkaisu. a) Etumerkkibitti on 0 ja 9843 10 = 010011001110011 2 viittätoista bittiä käyttäen. Siispä 16-bittinen tietokone-esitysmuoto on 0010011001110011. b) Etumerkkibitti on 1 ja 15728 10 = 011110101110000 2 viittätoista bittiä käyttäen. Luvun 011110101110000 2 kakkosen komplementti on 100001010010 25
000 2 Siispä 16-bittinen tietokone-esitysmuoto on 1100001010010000. c) Etumerkkibitti on 1 ja 4961 10 = 001001101100001 2 viittätoista bittiä käyttäen. Luvun 001001101100001 2 kakkosen komplementti on 11011001001 1111 2 Siispä 16-bittinen tietokone-esitysmuoto on 1110110010011111. Jos tietokone käyttää neljää tavua (32 bittiä) kahden sijasta kokonaislukuja tallentaessaan, mikä tahansa luku välillä 2 31 = 21474836648 n 2 31 1 = 21474836647 voidaan yksikäsitteisesti esittää etumerkkibittiä ja 31 muuta bittiä käyttäen analogisesti kahden tavun tapauksen kanssa. Tietysti tällöin luku 32768 korvautuu luvulla 21474836648 ja kakkosen komplementti otetaan 31-bittisestä binaariluvusta 15-bittisen sijasta. 2.6.2 Kokonaislukuaritmetiikka Tarkastellaan seuraavassa sitä miten tietokone suorittaa kokonaislukjen yhteenja vähennyslaskuja. On mukavampaa käsitellä pieniä bittimääriä, paljon pienempiä kuin todelliset tietokoneet käytännössä käsittelevät. Oletetaan, että kuvitteellinen tietokoneemme tallentaa kokonaisluvun käyttäen neljää bittiä. Tällöin ainoastaan kokonaisluvut 8, 7,..., 1, 0, 1,..., 7 voidaan esittää tällä koneella. Meillä on käytössä seuraava taulukko. 26
Taulukko kokonaisluku esitysmuoto -8 1000-7 1001-6 1010-5 1011-4 1100-3 1101-2 1110-1 1111 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 Tutkimalla yllä esitettyä taulukkoa voimme tehdä seuraavat huomiot. 1. Kun kyseessä on luku n {0, 1, 2, 3, 4, 5, 6, 7}, luvun n tietokoneesityksen viimeiset kolme bittiä muodostavat sen 3-bittisen binaariesityksen. Koska etumerkkibitti on 0, tietokone-esitys on luvun n nelibittinen binaariesitys. 2. Kun kyseessä luku n { 8, 7, 6, 5, 4, 3, 2, 1}, luvun n tietokone-esityksen viimeiset kolme bittiä muodostavat luvun n + 8 3-bittisen binaariesityksen. Koska etumerkkibitti on 1 (ja etumerkkibitin paikka-arvo on 2 3 = 8), tietokone-esitys, kun se käsitetään binaariluvuksi, on luvun n + 16 nelibittinen binaariesitys. Oletetaan nyt, että haluamme laskea yhteen kaksi lukua m ja n tällä tietokoneella. Nyt siis m, n { 8, 7,..., 6, 7}; lisäksi oletamme, että summa m + n { 8, 7,..., 6, 7}. Väitämme, että yhteenlasku voidaan suorittaa laskemalla yhteen lukujen m ja n tietokone-esitykset tavanomaisena binaariyhteenlaskuna, kun vain viidenteen sarakkeeseen mahdollisesti tuleva bitti 1 jätetään huomiotta. Luvun n tietokone-esityksen binaariarvo on joko luvun n binaariarvo tai luvun n binaariarvo +16. Siten, kun kaksi tietokone-esitystä lasketaan yhteen, 27
tuloksena on joko yhteenlaskun oikea vastaus, oikea vastaus +16 tai oikea vastaus +32. Oikealta viidennen bitin huomiottajättäminen tapauksessa, jossa se on 1, on yhtäpitävää sen kanssa, että yhteenlaskun tuloksesta vähennetään 16. Jos nyt prosessin lopussa tulos ei ole oikea, se poikkeaa oikeasta 16:n monikerralla. Nyt m, n { 8, 7,..., 6, 7}, joten tuloksen on oltava oikea, koska lukujen m ja n vaihteluväli on vähemmän kuin 16. Esim. 15. Osoita, että seuraavat yhteenlaskut tulevat oikein suoritetuiksi 4- bittisellä tietokoneella. (a) 2 + 3 (b) ( 4) + 7 (c) ( 3) + ( 4) (d) ( 6) + 5. Ratkaisu. Kirjoitetaan kukin yhteenlasku kahdella eri tavalla; kymmenjärjestelmässä ja siten, kun se tietokoneessa suoritetaan. (a) 2 + 3 = 5; 0010 2 + 0011 2 = 0101 2 (b) ( 4) + 7 = 3; 1100 2 + 0111 2 = (1)0011 2 (c) ( 3) + ( 4) = 7; 1101 2 + 1100 2 = (1)1001 2 (d) ( 6) + 5 = 1; 1010 2 + 0101 2 = 1111 2. Jos yritämme laskea yhteen kokonaislukuja, joiden summa ei kuulu sallittuun alueeseen, tulos on (tavallisesti) väärä. Esim 6 + 7 = 13 ja 0110 2 + 0111 2 = 1101 2. Tietokone tulkitsee bittijonon 1101 luvuksi 3. Tämä ylivuoto on kuitenkin suhteellisen helppo huomata. Jos nimittäin yritetään laskea yhteen kaksi (summaltaan liian suurta) positiivista lukua, vastaukseksi tulee negatiivinen luku ja ylivuoto on helppo havaita. Samoin, ynnätessä kaksi (summaltaan liian pientä) negatiivista lukua, tulos on positiivinen ja helposti havaittavissa. Jotkin softat antavat virheilmoituksen, toiset taas eivät anna. Tämän vuoksi ohjelmia kirjoitettaessa tulee tiedostaa ylivuodon mahdollisuus ja osata käsitellä näitä tilanteita. Kokonaislukujen tietokone-esityksiin perustuva vähennyslsku on suoraviivaista, kun seuraavat seikat otetaan huomioon. 1. Vähennyslasku voidaan palauttaa yhteenlaskuksi, tahtoo sanoa, a b = a + ( b). 2. Kokonaisluvun vastaluvun tietokone-esitys on kokonaisluvun kakkosen komplementti. Luvun vähentäminen voidaan siten suorittaa lisäämällä sen kakkosen komplementti. Siispä vähennyslasku muuntuu luiskeasti yhteenlaskuksi. Menetelmän etu on se, että tietokoneen ei tarvitse mikropiiristässä erikseen ylläpitää 'summaimia' ja 'vähentäjiä' (vaikkakin kakkosen komplementin laskeminen tarvitaan). 28
Esim. 16. Arvioi vähennyslaskua 5 3 nelibittisellä tietokoneella. Ratkaisu. Luvun 5 (vast. luvun 3) tietokone-esitys on 0101 (vast. 0011). Luvun 0011 2 kakkosen komplementti on 1101 2. Nyt 0101 2 +1101 2 = 10010 2. Jättämällä huomiotta vasemmanpuolimmaisen bitin 1, saamme tulokseksi tietokoneesityksen 0010, joka edustaa lukua 2. Komplementtiin perustuvaa vähennyslaskua voidaan käyttää missä tahansa kannassa. Palataan asiaan harjoituksissa. 2.6.3 Reaalilukujen esittäminen Reaalilukujen esittäminen on mutkikkaampaa kuin kokonaislukujen, ei ainoastaan tietokoneella, vaan myös kirjoitetussa muodossa. Olemme käsitelleet reaalilukujen esittämistä desimaalijärjestelmässä (kuten binaarijärjestelmässäkin) siten että numerot esiintyvät ennen ja jälkeen desimaalipilkun. Menetelmä ei sovellu tietokone-esitykseksi ei usein liioin kirjoitusesitykseksikään. Syy tähän on se, että useissa käytännön kannalta kiinnostavissa ongelmissa törmätään reaalilukuihin jotka ovat joko erittäin suuria tai erittäin pieniä ja jotka saadaan suorittamalla fyysisiä mittauksia sopivalla tarkkuudella. Likiarvon ja täysin tarkan esityksen ero on hiuksenhieno, mutta merkittävä. Maan massa ilmoitetaan usein lukuna 0.5976 10 25 kg. Huomattakoon, että 21 {}}{ lukua ei ilmoiteta muodossa 5976 00 0. Näin siksi, että em. luku on laskettu fyysisen mittaamisen perusteella ja mittaamiseen liittyy aina tietty epätarkkuus. Emme voi sanoa, että maan massa on täsmälleen 0.5976 10 25 kg, vaan ainoastaan, että se on jossakin 0.59755 10 25 kg:n ja 0.59765 10 25 kg:n välillä. Kun mittausmenetelmät tarkentuvat, arviota voidaan parantaa. Edellisessä esimerkissä käytettyä notaatiota kutsutaan eksponenttinotaatioksi ja se soveltuu erityisen hyvin sellaiseen tieteelliseen tarkasteluun, jossa luvut saadaan fyysisten mittausten perusteella. Eksponenttinotaatioon liittyy tiettyä terminologiaa. Luvussa 0.5976 10 25 on 0.5976 signikantti, 10 on kanta(luku) ja 25 on eksponentti. Jos signikantti m on välillä 0.1 m < 1, on esitys normaalimuodossa. Se, miten reaaliluvut tarkasti esitetään tietokoneessa, riippuu periaatteessa siitä, minkä tyyppisestä koneesta on kysymys. Tosin nykyään käytetään yleisimmin esitysmuotoa, jonka spesioi IEEE:n (Institute of Electrical and Electronics Engineering) standardi 754 (1985, 2008) binaariselle liukulukuaritmetii- 29
kalle. Emme toki tarkasti kuvaa tiettyä esitystapaa, vaan tyydymme yleisesti luonnehtimaan sitä miten reaalilukuja tietokoneessa tallennetaan ja manipuloidaan. Edellä kuvattu eksponentiaalinotaatio muistuttaa reaalilukujen esitystapaa tietokoneessa. Joitakin eroja kuitenkin on olemassa. Tietokoneet käyttävät 2:n potensseja 10:n potenssien sijasta tietoa manipuloidessaan. Myös eksponentti tallennetaan muunnettuun muotoon, kuten tulemme näkemään. Ennenkuin reaaliluvun tietokone-esitys voidaan läytää, se täytyy ensin muuntaa binaarimuotoon ja sen jälkeen esittää normalisoidussa binaarisessa eksponenttimuodossa. Sanomme, että reaaliluku on normalisoidussa binaarisessa eksponenttimuodossa, jos se on ilmaistu muodossa ±m 2 d, missä signikantti m on binaarimuodossa ja välillä 0.1 2 m < 1 2 ja d on kokonaisluku, joka on kirjoitettu desimaalimuodossa. Kantaluku 2 on niin ikään desimaalimuodossa. Muitakin esityksiä normalisoiduksi binaariseksi eksponentiaalimuodoksi voitaisiin käyttää; normalisoinnin tarkoitus on varmistaa jokaiselle luvulle yksikäsitteinen esitystapa. Huomattakoon, että nollaa ei voida esittää normalisoidussa binaarisessa eksponentiaalimuodossa, koska m = 0 ei kuulu m:n sallittuihin arvoihin. Reaaliluvun tallennukseen tietokoneelle tavallisesti käytetään neljää tavua ( 32 bittiä) tai kahdeksaa tavua (64 bittiä) 2. Ensimmäinen bitti on etumerkkibitti, jäljelle jäävät jaetaan eksponentin ja signikantin kesken. Eksponentille varattujen bittien lukumäärä kertoo tallennettavien lukujen arvoalueen; signikantin tallennukseen käytettyjen bittien lukumäärä puolestaan tarkkuuden, jolla luvut esitetään. Kun bittien kokonaismäärä on kiinteä, on kyse aina arvoalueen ja tarkkuuden välisestä kompromissista. Normaali menettelytapa nykyaikaisessa tietokoneessa on 8 bittiä eksponentin tallennukseen ja 23 signikantille, mikäli käytetään 32-bittistä esitysmuotoa. Nykyisin yleisempää on kuitenkin käyttää 64-bittisiä liukulukuja, jolloin eksponentti vie 10 ja signikantti 53 bittiä. Tavallisesti eksponentin binaariesitystä ei sellaisenaan tallenneta, vaan muistiin pistetään luku, jota kutsutaan karakteristikaksi. Karakteristika on ei-negatiivinen kokonaisluku, joka saadaan, kun eksponenttiin lisätään eksponenttipoikkeama, luku, joka on muotoa 2 n 1 1, missä n on eksponenttia varten (ja siten karakteristikan tallentamiseen) varattujen bittien lukumäärä. Kun eksponentti 2 Mikäli molemmat formaatit ovat tietokoneella saatavilla, puhutaan neljän tavun tapauksessa yksinkertaisesta ja kahdeksan tavun tapauksessa kaksinkertaisesta tarkkuudesta 30
tallennetaan edellä kuvatulla tavalla, tietokone voi käyttää yksinkertaisempia algoritmeja reaalilukuaritmetiikkaa toteuttamaan paljolti samalla tavalla kuin kokonaislukuaritmetiikkaa yksinkertaistettiin esittämällä negatiiviset luvut kakkosen komplementtina. Oletetaan, että karakteristikan k tallentamiseen on varattu n bittiä. Karaketristika on ei-negatiivinen kokonaisluku, joten k saa arvoja: 0 2 n 1. Eksponenttia e ja karakteristikaa k sitoo yhtälö k = 2 n 1 1 + e. Siispä e saa arvoja: 0 2 n 1 + 1 2 n 1 (2 n 1 1) eli e : 2 n 1 + 1 2 n 1. Joissakin esitystavoissa (IEEE-standardi mukaanlukien) ensimmäinen signikantin bitti (joka väistämättä on 1) jätetään tallentamatta, jolloin tarkkuutta voidaan lisätä ylimääräisen bitin verran. Kaikissa meidän esimerkeisämme signikantin ensimmäinen bitti on mukana. Esim. 17. Etsi seuraavien lukujen 32-bittinen tietokone-esitys. (a) 0.11001101 2 2 5 (b) 0.110111 2 2 3 missä käytetään 8 bittiä karakteristikaan ja eksponenttipoikkeama on 2 7 1. Ratkaisu. (a) Etumerkkibitti on 0. Karakteristika on luvun 5 + 2 7 1 kahdeksanbittinen binaariesitys, joka saadaan laskemalla yhteen 2 7 :n binaariesitys 10000000 2 ja luvun 4 binaariesitys 100 2. Saadaan 10000000 2 + 100 2 = 10000100 2. Signikantti laajennetaan 23-bittiseksi nollia lisäämällä; saadaan 11001101000000000000000. Huomattakoon, että desimaalipistettä edeltävää nollaa ei tallenneta. Tietokone-esitykseksi saadaan 01000010 01100110 10000000 00000000. (b) Etumerkkibitti on 0. Karakteristika on luvun 3 + 2 7 1 kahdeksanbittinen binaariesitys, joka saadaan yksinkertaisesti laskemalla luvun 4 seitsemänbittinen kakkosen komplementti ja varustamalla tämä etumerkkinollalla. Luvun 4 seitsemänbittinen binaariesitys: 0000100 2. Luvun 0000100 2 kakkosen komplementti: 1111100 2. Karakteristika: 01111100. Tietokone-esitykseksi saadaan 001111110 01101110 00000000 00000000. Reaaliluvun tietokone-esitys voidaan siis löytää seuraavasti. 1. Muuta luku binaarimuotoon; työskentele sillä tarkkuudella, jonka signikanttiin varattujen bittien lukumäärä edellyttää: 31
2. Esitä binaariluku normalisoidussa binaarisessa eksponenttimuodossa. Huomaa, että jos luku on itseisarvoltaan pienempi kuin yksi, desimaalipistettä välittämästi seuraavat nollat (silloin kun niitä on) siirtyvät eksponenttiin ja signikantti voidaan vastaavasti laskea suuremmalla tarkkuudella. 3. Määritä karakteristika. 4. Kirjoita tietokone-esitys. Esim. 18. Etsi 32bittinen tietokone-esitys luvulle 1873.42, kun karakteristikaan käytetään 8 bittiä ja eksponenttipoikkeama on 2 7 1. Ratkaisu. Aikaisemmin esitettyjä tekniikoita käyttäen muunnetaan luku 1873.42 aluksi 23-bittiseksi binaariluvuksi. Saadaan 1873.42 10 = 11101010001.011010111000 2. Ilmoitetaan tulos normalisoidussa binaarisessa eksponenttimuodossa: 11101010001.011010111000 2 = 0.11101010001011010111000 2 11. Etumerkkibitti on 1 ja karakteristika 10001010. Tietokone-esitys on siten 11000101 01110101 00010110 10111000. Edellinen esimerkki osoittaa sen, että reaaliluvun tietokone-esitys voi olla epätarkka, koska binaarimuotoon muutettaessa lukua typistetään käytettävissä olevaan tarkkuuteen. Lisää epätarkkuuksia voi syntyä reaalilukuaritmetiikan pyäristysvirheistä. Tilanne on toinen kuin kokonaislukujen tapauksessa, jolloin lukuja tallennetaan ja käsitellään tarkasti tietokoneessa. Eräs käytännön seuraus tästä on, että reaalilukujen yhtäsuuruuden testaus sisältää riskin. Turvallisempaa on arvioida ovatko kaksi reaallilukua x ja y suunnilleen yhtäsuuria testaamalla onko voimassa x y < q, missä q on pieni positiivinen luku (esim 10 6 ). Minkäkokoisia reaalilukuja tietokoneella sitten kyetään esittämään? Oletetaan, että tietokoneemme tallentaa reaaliluvut 32 bitillä, jossa 8 bittiä on varattu karakteristikalle. Tällöin eksponenttipoikkeama on 2 7 1 ja karakteristika voi saada arvoja 0:sta lukuun 2 8 1. Koska karakteristika = 2 7 1 + eksponentti, 32
voi eksponentti saada arvoja luvusta 0 (2 7 1) lukuun 2 8 1 (2 7 1) eli joukossa 127, 126,..., 127, 128. Signikantti vaihtelee luvusta 0.1 2 lukuun 1 2. Ne positiiviset luvut, joita tietokone voi esittää sijoittuvat siten välille [0.1 2 2 127, 1 2 2 128 ). Huomattakoon, että 0.1 2 2 127 0.29 10 38 ja 1 2 2 128 0.34 10 39. Sellaiset negatiiviset luvut, joiden itseisarvo on yo. välillä, voidaan niinikään esittää tietokoneella. Mikäli laskennan tuloksena saadaan luku, joka ei mainittuihin rajoihin mahdu, tapahtuu joko alivuotoa 3 tai ylivuotoa. Esim. 19. Oletetaan, että tietokone tallentaa reaalilukuja 32 bitillä, jossa 10 bittiä on varattu karakteristikalle ja eksponenttipoikkeama on 2 9 1. Arvioi aluetta, jossa posit. reaalilukuja pystytään tietokoneella esittämään. Ratkaisu. Karakteristika voi saada arvoja 0:sta lukuun 2 10 1, joten eksponentin vaihteluväli on 0 (2 9 1):stä 2 10 (2 9 1) 1:een eli luvusta 511 lukuun 512. Siispä reaalilukuja väliltä [0.1 2 2 511, 1 2 2 512 ) voidaan esittää. Nyt log 10 2 511 = 511 log 10 2 153.8263278. Siksipä 2 511 10 153.8263278 = 10 153 10 0.8263278 0.149 10 153. Lukua 2 512 voidaan arvioida vastaavalla tavalla, jolloin saadaan, että välillä [0.75 10 154, 0.13 10 155 ) olevat luvut ovat tietokoneella esitettävissä. 2.6.4 Reaalilukuaritmetiikka Tarkastellaan seuraavassa hiukan sitä miten aritmeettisia operaatioita suoritetaan normalisoidussa eksponenttimuodossa olevilla reaaliluvuilla. Tämä antaa yleiskuvan siitä miten tietokone suorittaa reaalilukuaritmetiikkaa. Kun halutaan laskea yhteen (vast. vähentää), menetellään seuraavasti. 1. Kirjoitetaan luvut eksponenttimuodossa yhteistä eksponenttia käyttäen siten, että signikantti on pienempi kuin 1. 3 Alivuotoa tapahtuu, kun laskennan tuloksena saadaan reaaliluku, jonka itseisarvo on pienempi kuin pienin posit. luku, joka voidaan esittää. Tilanteesta riippuen voi olla tai olla olematta sopivaa arvioida alivuodon suuruutta nollalla. 33
2. Lasketaan signikantit yhteen (vastaavasti vähennetään signikantit toisistaan); saadaan vastauksen signikantti; yhteinen eksponentti on vastauksen eksponentti. 3. Normalisoidaan vastaus tarvittaessa. Kun halutaan kertoa (vast. jakaa), menetellään seuraavasti. 1. Kerrotaan (vast. jaetaan) signikantit, jolloin saadaan vastauksen signikantti. 2. Lasketaan eksponentit yhteen (vast. vähennetään eksponentit toisistaan), jolloin saadaan tuloksen eksponentti. 3. Normalisoidaan vastaus tarvittaessa. Jäljitelläksemme tapaa, jolla tietokone suorittaa laskutoimituksia, oletetaan seuraavassa, että luvun normalisoidun esityksen signikantissa numerojen lukumäärä on kiinteä ja että vastauksessa signikantti aina pyöristetään lukumäärän mukaisesti. Esim. 20. Suorita laskinta käyttäen seuraavat laskutoimitukset. Oletetaan, että signikantti esitetään neljän numeron tarkkuudella. Ratkaisu. (a) 0.4932 10 3 + 0.2881 10 4 0.3096 10 4 (b) (0.2174 10 5 ) (0.1482 10 7 ) (0.9497 10 4 ) (a) 0.4932 10 3 + 0.2881 10 4 0.3096 10 4 = 0.0493 10 4 + 0.2881 10 4 0.3096 10 4 = 0.0278 10 4 = 0.2870 10 3. (b) (0.2174 10 5 ) (0.1482 10 7 ) (0.9497 10 4 ) = 0.03393 10 2 = 0.3393 10 3. 34
3 Logiikka (propositiokalkyyli, predikaattikalkyylin alkeet) Tässä luvussa tarkastelemme muodollista logiikkaa. Logiikkaa sovelletaan monella alueella tietojenkäsittelyssä, esim. (i) digitaalipiirien suunnittelussa; (ii) kontrollirakenteiden ehtoina ohjelmoinnissa; (iii) tietokantakyselyissä; (iv) asiantuntijajärjestelmien tietämyspohjaisissa ohjelmistoissa; (v) tietokonemallinnuksessa; ja (vi) formaalissa spesioinnissa. Luvu alkuosassa perehdytään propositio- ja loppuosassa predikaattilogiikkaan. 3.1 Propositiot Luvut ovat aritmetiikan perusobjekteja. Vastaavalla tavalla propositiot ovat logiikan keskeisiä rakennuspalikoita. Propositio on väittämä, joka on joko tosi (totuusarvo 1 tai T) tai epätosi (totuusarvo 0 tai F). Esimerkkejä propositioista: 'Canberra on Australian pääkaupunki'; 'Aurinko kiertää maata'; 'Isaac Newton syntyi vuonna 1642'; '5 on suurempi kuin 7'; 'Jokainen kakkosta suurempi parillinen kokonaisluku voidaan ilmaista kahden alkuluvun summana'. 35
Edellä ensimmäinen ja kolmas ovat reaalimaailmassa tosia propositioita; toinen ja neljäs taas epätosia. Tällä hetkellä ei tiedetä onko viides propositio tosi vai epätosi. Kyseessä on ns. Goldbachin väittämä. Seuraavat ilmaisut eivät ole propositioita: 'Minne menet?'; 'Tule tänne!'; 'Tämä lause on epätosi'. Ensimmäinen on kysymys, toinen käsky. Kolmas viittaa itseensä ja johtaa ristiriitaan tai paradoksiin. Jos se on tosi, sen sisältämä väittämä johtaa ristiriitaan oletuksemme kanssa. Jos se taas on epätosi, päättelemme, että se on tosi ja olemme jälleen ristiriidassa oletuksen kanssa. Tarkastellaan ilmaisuja: 'Eläirasvojen syönti ei vaikuta kolesteroliin'; 'Olut on terveellistä'; 'x<8'. Kaksi ensimmäistä ovat ainakin jossain määrin mielipidekysymyksiä; niiden totuudellisuudesta kiisteleminen ei maksa vaivaa tässä yhteydessä. Emme tule tarkastelemaaan propositioina väitteitä, joiden totuusarvo on epäselvä. Viimeinen yllä esitetyistä lausekkeista on predikaatti, väite, josta tulee propostio, kun siinä esiintyvien muuttujien arvot sopivasti kiinnitetään. Hieman tarkemmin: Predikaatti on ilmaisu, joka - sisältää yhden tai useampia muuttujia; - ei ole propositio mutta josta tulee propositio, kun siinä esiintyvien muuttujien arvot sopivasti sidotaan. Tietokoneohjelma (tai algoritmi) voi sisältää lausekkeen ' x < 8' esim. jossakin kontrollirakenteessa. Tällöin sen totuusarvo voidaan määrittää syötteen ja ohjelman sen hetkisen tilan perusteella, joten lauseketta ' x < 8' voidaan kohdella propositiona. 36
3.2 Loogiset operaatiot (konnektiivit) ja totuustaulut Logiikassa ei olla kiinnostuneita edellä tarkasteltujen propositioiden (kuten 'Canberra on Australian pääkaupunki') totuusarvosta. Tarvitaan yleisempi näkökulma. Tarkastellaan nyt propositiota 'Jos Anna ja Pekko eivät molemmat ole onnellisia, niin joko Anna ei ole onnellinen tai Pekko ei ole onnelllinen'. Voidaksemme päätellä, että yo. propositio on tosi, meidän ei tarvitse tietää onko Anna tai Pekko onnellinen. Hetken tuumauksen jälkeen havaitsemme, että se on tosi loogisen rakenteensa perusteella. Mikä tahansa ilmaisu, jolla on sama looginen rakenne on tosi. Esimerkiksi 'Jos luvut a ja ja b eivät molemmat ole rationaalilukuja, niin joko a ei ole rationaaliluku tai b ei ole rationaaliluku'. Propositiologiikassa ollaan kiinnostuneita propositioiden rakenteesta. Em. propositiot ovat yhdistettyjä propositioita, jotka muodostetaan atomisista propositioista käyttämällä loogisia operaatioita eli konnektiiveja. Logiikan konnektiivit vastaavat algebran laskutoimituksia. (Atomisia) propositioita kuvataan propositiomuuttujien avulla; merkitsemme propositiomuuttujia pienillä kirjaimilla p, q ja r mahdollisesti alaindeksillä varustettuna. Käytössämme on viisi konnektiivia seuraavan taulukon mukaisesti: Konnektiivi ja (konjunktio) tai (disjunktio) Taulukko Symboli ei (negaatio) jos-niin (implikaatio) jos-ja-vain-jos (ekvivalenssi) Yllä esitetyt konnektiivit, negaatiota lukuunottamatta, ovat kaksipaikkaisia, eli ne kohdistuvat kahteen propostioon. Kaksipaikkainen konnektiivi asetetaan propositioiden väliin. Jos esimerkiksi p tarkoittaa propositiota 'Tänään on maanantai' ja q propositiota 'Sataa vettä', tarkoittaa p q propositiota 'Tänään on maanantai ja sataa vettä'. Negaatio asetetaan proposition eteen. Niinpä p tarkoittaa propositiota 'Tänään ei ole maanantai'. Loogisten konnektii- 37
vien määrittelyyn käytetään totuustauluja, joissa propositiomuuttujat saavat kaikki mahdolliset arvot. Loogisen operaation ja ( ) totuustaulu on: p q p q T T T T F F F T F F F F Tietysti konnektiivin totuustaulu heijastelee jokapäiväistä käsitystämme siitä mitä ja tarkoittaa: propositio p q on tosi jos sekä p että q ovat tosia ja se on epätosi kaikilla muilla p:n ja q :n totuusarvoilla. Sanaa tai käytetään suomen kielessä kahdessa merkityksessä. Jos tarjolla on teetä tai kahvia, kohteen oletetaan valitsevan jomman kumman, mutta ei molempia vaihtoehtoja; kysymyksessä on tällöin eksklusiivinen tai, vain toinen vaihtoehto tulee kysymykseen. Jos taas alennusta tarjotaan opiskelijoille tai eläkeläisille, henkilö, joka on molempia, saanee alennuksen; tällöin olemme tekemisissä inklusiivisen tain kanssa. Logiikassa symboli merkitsee aina inklusiivista tai -tulkintaa. Operaation totuustaulu on siten: p q p q T T T T F T F T T F F F Operaation ei (negaatio, ) totuustaulu on suoraviivainen: p p T F F T Tarkastellaan jos-niin -konnektiivia. Tarkastellaan lausetta 'Jos tupakoin säännöllisesti, terveyteni huononee'. Lienemme yhtä mieltä siitä, että mikäli on totta, että henkilö tupakoi, on myös totta, että hän vaarantaa terveytensä. Siten (yleisesti) T T -tyyppinen väittämä on tosi. Mitä tapahtuu, jos henkilö ei tupakoi (eli väittämä, että henkilö tupakoi, on epätosi). Onko totta, että hänen terveytensä kärsii? Lautamiesjärki sanoo, että hänen terveytensä voi joko 38
kärsiä (mahdollisesti jostain muusta syystä kuin tupakoinnista) tai sitten ei. Siispä tyyppiä F T ja F F olevia voidaan molempia pitää totena. Ainoastaan väittämä 'Jos tupakoin säännöllisesti, terveyteni ei kärsi' (eli tyyppiä T F) on selvästi epätosi. Edellisen nojalla annamme implikaatiolle seuraavan määritelmän. p q p q T T T T F F F T T F F T Huom. 1. On tärkeää ymmärtää konnnektiivin jos-niin ja algoritmeissa esiintyvän kontrollirakenteen if-then ero; jälkimmäisessä ehtoa seuraa käsky, ei propositio. Väite p q on tosi täsmälleen silloin, kun propositioilla p ja q on samat totuusarvot: p q p q T T T T F F F T F F F T Esim. propositio 'Linnuilla on kolme jalkaa' 2 + 2 = 5 on tosi koska siinä esiintyvät propositiot ovat molemmat epätosia. 3.3 Yhdistetyt propositiot ja lauselogiikan ilmaisut Tarkastellaan seuraavassa yhdistettyjä propositioita symbolimuodossa. Esim. 1. Esitä seuraava propositio symbolisessa muodossa. 'Joko tietokoneohjelmani toimii ja siinä ei ole virheitä tai tietokoneohjelmani sisältää virheitä'. 39
Ratkaisu. Olkoon p propositio: 'Tietokoneohjelmani toimii' ja q propositio 'Tietokoneohjelmani sisältää virheitä'. Tällöin propositio 'Joko tietokoneohjelmani toimii ja siinä ei ole virheitä tai tietokoneohjelmani sisältää virheitä' on symbolisessa muodossa: (p q) q. Huomaa, miten edellisessä propositiossa sulkumerkkejä käytetään propositioiden ryhmittelyyn. Sukumerkit ovat tärkeitä: propositio p ( q q) tarkoittaa 'Tietokoneohjelmani toimii ja joko se ei sisällä virheitä tai se sisältää virheitä'. Sulkumerkkejä tulee käyttää aina, kun väärinymmärtämisen mahdollisuus on olemassa. Teemme seuraavan sopimuksen: konnektiivien vaikutusalueet kasvavassa järjestyksessä ovat:, ja,,. Operaatiot ja ovat vaikutusalueeltaan yhtä vahvat. Täten propositio tarkoittaa propositiota p q r s p r {[( p) q] r} [(s p) ( r)]. Yhdistelemällä propositiomuuttujia konnektiiveja käyttäen, saamme lauselogiikan ilmaisuja, joita myös loogisiksi ilmaisuiksi kutsutaan. Lauselogiikan ilmaisuista tulee (varsinaisia) propositioita vasta, kun korvaamme propositiomuuttujat propositioilla. Meidän mielenkiintomme kohdistuu lauselogiikan ilmaisujen rakenteen tutkimiseen. Esim. lauselogiikan ilmaisu (p q) q voidaan esittää ilmaisupuuna, kts. Kuva 3.1. Ilmaisun (p q) q totuusarvo kullakin p:n ja q :n totuusarvojen kombinaatiolla saadaan konstruoimalla totuustaulu. Esim. 2. Laadi ilmaisun (p q) q totuustaulu. Ratkaisu. Ratkaisu on esitetty alla olevassa taulukossa; kaksi ensimmäistä saraketta sisältävät muuttujien p ja q kaikki mahdolliset arvot; tämän jälkeen ilmaisun (p q) q totuustaulu rakennetaan ilmaisujen q ja p q totuustaulujen avulla konnektiivien määritelmiä käyttäen. p q q p q (p q) q T T F F T T F T T T F T F F T F F T F F 40
q p q Kuva 3.1: Ilmaisupuu Mikäli lauselogiikan ilmaisu sisältää kolme (vast. 4, 5,..., n,...) muuttujaa, on sen totuustaulussa kahdeksan (vast. 2 4, 2 5,..., 2 n,...) riviä. Tarkastellaan uudemman kerran propositiota 'Jos Anna ja Pekko eivät molemmat ole onnellisia, niin joko Anna ei ole onnellinen tai Pekko ei ole onnelllinen'. Olkoon p : 'Anna on onnellinen' ja q : 'Pekko on onnellinen' ja ilmaistaan yo. propositio symbolisesti: (p q) ( p q). Ilmaisun totuustaulu on p q p q (p q) p q p q (p q) ( p q) T T T F F F F T T F F T F T T T F T F T T F T T F F F T T T T T Havaitaan, että totuustaulun viimeinen sarake sisältää vain totuusarvoa T ; 41
siten ilmaisu (p q) ( p q) on aina tosi, riippumatta p:n ja q :n arvoista. Lauselogiikan ilmaisu, joka on aina tosi, on tautologia. Tarkastellaan nyt propositiota 'On tuulista ja sataa ja ei sada '. Tietämättä säästä mitään ymmärrämme, että tämä propositio on epätosi rakenteensa vuoksi. Varmistutaan asiasta esittämällä propositio symbolisessa muodossa ja konstruoimalla sen totuustaulu. p q p q p (p q) q T T T F F T F F F F F T F T F F F F T F Ilmaisua, joka on siinä esiintyvien propositiomuuttujien arvoista riippumatta aina epätosi, kutsutaan ristiriidaksi. Huom. 2. Yhdistetyn proposition perusominaisuus on, että sen totuusarvo määräytyy täysin siinä esiintyvien osapropositioiden ja loogisten operaatioiden perusteella. Lauselogiikan ilmaisun totuustaulu puolestaan määräytyy täysin siinä esiintyvien propositiomuuttujien ja loogisten operaatioiden perusteella. Lauselogiikan ilmaisut voidaan induktiivisesti määritellä seuraavasti: 1. Jokainen propositiomuuttuja on lauselogiikan ilmaisu. 2. Jos p ja q ovat lauselogiikan ilmaisuja, niin p, p q, p q, p q ja p q ovat lauselogiikan ilmaisuja. 3. Ainoastaan sellaiset rakenteet, jotka saadaan sääntöjä 1 ja 2 äärellisen monta kertaa soveltamalla, ovat lauselogiikan ilmaisuja. 3.4 Looginen ekvivalenssi Seuraava propositio on aika monimutkainen: 'Ei ole totta, että syötetiedosto ja tulostetiedosto eivät kumpikaan ole tallennettuna kovalevylle'. Sama asia voidaan esittää yksinkertaisemmin propositiona: 'Joko syötetiedosto tai tulostetiedosto on tallennettuna kovalevylle'. Kun esitämme em. propositiot symbolisessa muodossa, on hyvä syy olettaa, että niiden totuuustaulut ovat samat. Merkitään propositiota 'Syötetiedosto on tallennettuna kovalevylle' symbolilla 42
p ja propositiota 'Tulostetiedosto on tallennettuna kovalevylle' symbolilla q. Laaditaan yhteinen totuustaulu: p q p q p q ( p q) (p q) T T F F F T T T F F T F T T F T T F F T T F F T T T F F Kuudes sarake on ilmaisun ( p q) ja seitsemäs sarake vastaavasti ilmaisun p q) totuustaulu. Näemme, että totuustaulut ovat samat. Kaksi samoista muuttujista koostuvaa loogista ilmaisua p ja q ovat loogisesti ekvivalentit (merk. p q ), jos ne saavat samat totuusarvot kaikilla propositiomuuttujien totuusarvojen valinnoilla. Tämä on yhtäpitävää sen kanssa, että p q on tautologia tai (vähemmän muodollisesti), että niillä on sama totuustaulu. Edelleen sanomme, että q seuraa loogisesti ilmaisusta p (merk. p q ), jos kaikilla propositiomuuttujien totuusarvojen valinnoilla siitä, että p on tosi, seuraa, että q on tosi. Tämä on yhtäpitävää sen kanssa, että ilmaisu p q on tautologia. Huomaa konnektiivin 'ekvivalenssi' ( ) ja käsitteen 'looginen ekvivalenssi' ( ) ero: p q on yksi looginen ilmaisu, joka koskee kahta loogista ilmaisua p ja q ; p q kertoo kahden loogisen ilmaisun p ja q suhteen (niiden totuustaulut ovat samat). Ilmaisun p q konversio on q p. Ilmaisun p q kontrapositio on q p. Esim. 3. Muodosta a) konversio b) kontrapositio propositiolle 'Jos 250 on tasan jaollinen luvulla 4, niin 250 on parillinen luku'. Ratkaisu. Olkoon p propositio ' 250 on tasan jaollinen luvulla 4' ja q propositio '250 on parillinen luku'. Tällöin esimerkin propositio voidaan symbolisesti esittää muodossa p q, jonka konversio on q p eli a) 'Jos 250 on parillinen luku, niin 250 on tasan jaollinen luvulla 4' ja kontrapositio q p eli b) 'Jos 250 ei ole parillinen luku, niin 250 ei ole tasan jaollinen luvulla 4'. Alkuperäinen propositio edellisessä esimerkissä pysyy totena, kun 250 korvataan millä tahansa kokonaisluvulla. Näin käy myös kontraposition suhteen. 43
Konversio sen sijaan on epätosi: luku 250 on parillinen, mutta ei tasan jaollinen luvulla 4. Esimerkistä 3 voi päätellä, että ilmaisu p q ei ole loogisesti ekvivalentti konversionsa kanssa mutta voisi olla loogisesti ekvivalentti kontrapositionsa kanssa. Varmistaudutaan asiasta laatimalla totuustaulut: p q p q q p q p q p T T T T F F T T F F T T F F F T T F F T T F F T T T T T Ilmaisuja p q ja q p vastaavat sarakkeet ovat identtiset, mutta ilmaisuja p q ja q p vastaavat sarakkeet eivät ole. 3.5 Logiikan lait Käytännössä johdutaan usein tilanteeseen, jossa on toivottavaa korvata looginen ilmaisu yksinkertaisemmalla alkuperäisen kanssa loogisesti ekvivalentilla ilmaisulla. Esim. logiikan ilmaisuja ohjelmoinnissa käytettäessä on laskutoimitusten yksinkertaistamiseksi ja virheiden välttämiseksi järkevää käyttää mahdollisimman yksinkertaisia ehtolausekkeista. Loogisesti ekvivalentteja ilmaisuja kutsutaan logiikan laeiksi. Tärkeimpiä logiikan lakeja on listattu alla olevassa taulukossa. Kaksi ensimmäistä lakia auttavat meitä poistamaan konnektiivit ekvivalenssi ( ) ja implikaatio ( ). Loput lait sisältävät vain operaatioita negaatio, disjunktio ja konjunktio. Kaksoiskieltämisen lakia lukuunottamatta säännöt esiintyvät pareittin; toinen laki saadaan ensimmäisestä korvaamalla operaatiolla ja symboli T 0 merkinnällä F 0. Tässä (ja siten alla olevassa taulukossa) T 0 tulkitaan miksi tahansa tautologiaksi ja F 0 mielivaltaiseksi ristiriidaksi. Ensimmäinen laki on aina toisen duaalilaki ja kääntäen. Lakeja on aikamoinen määrä; useat niistä ovat kuitenkin itsestäänselvyyksiä hetken tuumailun jälkeen (esim. kaksoiskieltämisen laki ja idempotenttilait). Vähemmän ilmeisien paikkansapitävyys on syytä tarkistaa totuustaulun avulla. Vielä on syytä havaita, että jotkut lait ovat lukujen algebran sääntöjen kanssa samankaltaisia, kun korvaamme pareissa (=, ), (, ), (+, ), (1, T) ja (0, F) aina vasemmanpuoleisen symbolin oikeanpuoleisella. Kommutatiivisuus-, assosiatiivisuus- ja identtisyyslait ovat tällaisia ja niin on myös 1. distributii- 44
visuuslaki. Toinen distributiivisuuslaki sen sijaan ei noudata samaa kaavaa, koska algebrassa yhtäsuuruus x + (y z) = (x + y) (x + z) ei yleisesti ole voimassa. Logiikan tehtäviä ratkaistaessa tulee jokainen askel kyetä perustelemaaan logiikan lakien avulla. Laki/lait Nimi p q (p q) (q p) Ekvivalensssilaki p q p q Implikaatiolaki p p Kaksoiskieltämisen laki p p p p p p Idempotenttilait p q q p p q q p Kommutatiivisuuslait (p q) r p (q r) (p q) r p (q r) Assosiatiivisuuslait p (q r) p (q r) Distributiivisuuslait (p q) (p r) (p q) (p r) (p q) p q (p q) p q de Morganin lait p T 0 p p F 0 p Identtisyyslaki p F 0 F 0 p T 0 T 0 Annihilaatiolaki p p F 0 p p T 0 Inversiolaki p (p q) p p (p q) p Absorptiolaki Esim. 4. Todista oikeaksi 1. de Morganin laki: (p q) p q. Ratkaisu. Laki voidaan suusanallisesti esittää seuraavasti. Väittämä 'ei ole totta että p ja q ovat molemmat tosia' on yhtäpitävä väittämän 'joko p tai q on epätosi' kanssa. p q p q (p q) p q p q T T T F F F F T F F T F T T F T F T T F T F F F T T T T Koska yllä 4. ilmaisua (p q) vastaava sarake ja 7. ilmaisua p q vastaava sarake ovat samat, on 1. de Morganin laki voimassa. Esim. 5. Yksinkertaista logiikan lakien avulla ilmaisu p ( p q). 45
Ratkaisu. Koska kysymyksessä on ensimmäinen esimerkki, suoritamme yksinkertaistamisen yksityiskohtaisesti. p ( p q) p ( p q) (implikaatiolaki) p (p q) (kaksoiskieltämisen laki) p ( p q) (2. de Morganin laki) (p p) (p q) (2. distribuutiolaki) T 0 (p q) (2. inversiolaki) (p q) T 0 (1. kommutatiivisuuslaki) p q (1. identtisyyslaki) Mitä lakia kussakin tilanteessa tulisi soveltaa? Tähän kysymykseen ei ole yksiselitteistä vastausta. Tietysti konnektiivit ja (jos niitä esiintyy) on syytä poistaa kahden ensimmäisen lain avulla. Kaksi peräkkäistä negaatiota on usein (mutta ei aina) hyvä hävittää, mutta muita peukalosääntöjä on vaikea antaa. Loogisten ilmaisujen yksinkertaistaminen algoritmien ehtolausekkeissa on logiikan lakien eräs käytännön sovellus. Esim. 6. Algoritmi sisältää rivin If (x > 5 x 10) then... Miten tämä voidaan esittää yksinkertaisemmin? Ratkaisu. Ensimmäisen de Morganin lain mukaan lauseke (x > 5 x 10) on yhtäpitävä lausekkeen (x > 5) (x 10) kanssa. Tämä puolestaan on yhtäpitävä lausekkeen (x 5) (x > 10) kanssa. Siispä ohjelmarivi on yksinkertaisemmassa muodossa seuraava: If (x 5) (x > 10) then... Logiikan laeilla voidaan usein korvata totuustaulujen käyttö. Esim. 7. Osoita logiikan lakeja käyttäen, että lauseke [(p q) q] p on tautologia. 46
Ratkaisu. Jälleen yksityiskohtainen tarkastelu: [(p q) q] p [( p q) q] p (implikaatiolaki kahdesti) [ q ( p q)] p (1. kommutatiivisuuslaki) [( q p) ( q q)] p (1. distributiivisuuslaki) [( q p) (q q)] p (1. kommutatiivisuuslaki) [( q p) F 0 ] p (1. inversiolaki) [( q p)] p (2. identtisyyslaki) ( q p) p (1. de Morganin laki) (q p) p (kaksoiskieltämisen laki kahdesti) q (p p) (2. assosiatiivisuuslaki) q T 0 (2. inversiolaki) T 0 (2. annihilaatiolaki) Siispä kyseessä on tautologia. 3.6 Loogisesta päättelystä Päättely on rakenne P 1, P 2,..., P n Q, missä loogiset ilmaisut P 1, P 2,..., P n ovat oletuksia (eli premissejä) ja looginen ilmaisu Q on johtopäätös. Päättely P 1, P 2,..., P n Q on johdonmukainen (eli (loogisesti) oikea tai validi), jos looginen ilmaisu P 1 P 2 P n Q on tautologia (eli Q on looginen seuraus ilmaisusta P 1 P 2 P n. Tämä on tietysti yhtäpitävää sen kanssa, että Q on tosi, jos ilmaisut P 1, P 2,..., P n ovat tosia. Esim. 8. Intuitiivisen logiikan perusteella seuraava järkeily on tosi. 'Jos p:stä seuraa q ja q :sta seuraa r, niin p:stä seuraa r' Osoita päättely loogisesti oikeaksi. Ratkaisu. Meidän täytyy osoittaa, että päättely p q, q r p r on johdonmukainen. Edellä esitetyn nojalla riittää osoittaa, että (p q) (q r) (p r) on tautologia. Se, että näin on, käy ilmi seuraavasta totuustaulusta. 47
p q r {(p q) (q r)} (p r) T T T T T T T T T T F T F F T F T F T F F T T T T F F F F F T F F T T T T T T T F T F T F T T T F F T T T T T T F F F T T T T T 3.7 Predikaattilogiikka Propositiologiikka on hyödyllinen väline, jolla pystymme arvioimaan monentyyppisiä loogisia todisteluja. Kaikkeen se kuitenkaan ei riitä; se ei kykene käsittelemään loogisia rakenteita, joita saattaa esiintyä atomisten propositioiden sisällä. Erityisesti propositiokalkyyli ei ole riittävän vahva väline muuttujia sisältävien väitteiden käsittelyyn. Tarkastellaan seuraavia väitteitä. 'Kaikki parilliset reaaliluvut ovat kokonaislukuja. Luku 8 on parillinen reaaliluku. Siispä 8 on kokonaisluku'. 1 'Ei ole totta, että kaikki alkuluvut ovat parittomia. Siksi täytyy olla olemassa ainakin yksi parillinen alkuluku'. 2 Selvästikin molemmat edellä esitetyt väitteet ovat tosia. Kun yritämme todistaa niitä propositiologiikan avulla, ajaudumme vaikeuksiin. Olkoon p propositio 'kaikki parilliset reaaliluvut ovat kokonaislukuja', q propositio 'luku 8 on parillinen' ja r propositio 'luku 8 on kokonaisluku'. Meillä on muotoa p q r oleva väite. Ilmaisu ei ole tosi, jos p ja q ovat tosia, mutta r on epätosi. Vastaavasti merkitsemällä symbolilla p propositiota 'kaikki alkuluvut ovat pa- 1 Muunnelma klassisesta väitteestä: 'Kaikki ihmiset ovat erehtyväisiä. Sokrates on ihminen. Siispä Sokrates on erehtyväinen'. 2 Lukua 1 suurempi kokonaisluku on alkuluku, jos sen ainoat positiiviset tekijät ovat ykkönen ja luku itse. 48
rittomia' ja q :lla propositiota 'on olemassa ainakin yksi parillinen alkuluku', johdumme ilmaisuun p q, joka on epätosi, jos sekä p että q ovat tosia. Predikaattilogiikka auttaa meitä analysoimaan yllä esitetyn kaltaisia ilmaisuja. Esim. x < 5 on predikaatti; tässä x on muuttuja, joka saa reaalilukuarvoja. Jos korvaamme muuttujan x jollakin reaaliluvulla, saamme proposition, joka on joko tosi tai epätosi; esim 3 < 5 (totuusarvo T) ja 7 < 5 (totuusarvo F). Tietenkään muuttujien ei aina tarvitse olla lukuja: ' x on Oulun yliopiston opiskelija' on validi predikaatti, jossa muuttuja x saa arvoja ihmisten joukossa. Predikaatista voi saada proposition (ja tässä tulee ero propositiolaskentaan) sitomalla sen muuttujat myös muulla tavalla kuin antamalla niille kiinteät arvot. Tarkastellaan predikaattia ' x < 7 tai x > 5'. Väite on tosi kaikilla x:n reaalilukuarvoilla, joten saamme totta olevan proposition kirjoittamalla 'kaikilla x:n reaalilukuarvoilla: x < 7 tai x > 5. Jos asetamme 'kaikilla x:n reaalilukuarvoilla: x < 5, saamme proposition, joka on epätosi. Koska on olemassa reaalilukuja, jotka ovat pienempiä kuin luku 5, saamme totta olevan proposition, kun asetemme 'on olemassa sellainen reaaliluku x, että x < 5. Ilmaisut 'kaikilla' (merk. ) ja 'on olemassa' (merk. ) ovat kvanttoreita, joilla muuttuja voidaan sitoa. Esimerkiksi ilmaisussa 'kaikilla x:n reaalilukuarvoilla: x < 5, kvanttori 'kaikilla x:n reaalilukuarvoilla' sitoo muuttujan x. Predikaatissa esiintyvä muuttuja, jota ei ole sidottu, on vapaa. Käytämme seuraavassa isoja kirjaimia P, Q ja R, mahdollisesti alaindekseillä varustettuna, merkitsemään predikaatteja. Predikaattia P, joka sisältää yhden muuttujan x, merkitään P (x). Predikaattia P, joka sisältää kaksi muuttujaa x ja y, merkitään P (x, y), jne..., predikaattia, joka sisältää n eri muuttujaa x 1, x 2,..., x n, merkitään P (x 1, x 2,..., x n ). Kirjoitamme tästä lähtien x (vast. x) ilmaisun 'kaikilla x' (vast. 'on olemassa x') sijasta. Tässä on universaalikvanttori ja on eksistenssikvanttori ja Esim. 9. Kirjoita symbolisessa muodossa 'on olemassa sellainen reaaliluku x, että x < 4'. Ratkaisu. Sovimme aluksi, että muuttuja x saa arvoja reaalilukujoukossa. 49
Tämäntyyppiset olettamukset voidaan jättää kirjaamatta, kun sekaannusta ei pääse syntymään. Olkoon P (x) predikaatti x < 4. Tällöin haluttu symbolinen muoto on: x P (x). Esim. 10. Kirjoita symbolisessa muodossa 'kaikilla x:n reaalilukuarvoilla: x < 5 tai x 5. Ratkaisu. Olkoon P (x) predikaatti x < 5 ja Q(x) predikaatti x 5. Tällöin haluttu symbolinen muoto on: x[p (x) Q(x)]. Käyttämällä hyväksi sitä, että Q(x) on yhtäpitävä ilmaisun P (x) kanssa, voimme myös kitjoittaa: x[p (x) P (x)] Seuraavassa esimerkki kahden muuuttujan predikaatin käytöstä. Esim. 11. Kirjoita seuraavat propositiot symbolisessa muodossa: 'jokaista kokonaislukua x kohti on olemassa sellainen kokonaisluku y, että y = x + 1' 'on olemassa sellainen kokonaisluku y, että jokaisella kokonaisluvulla x on voimassa y = x + 1' Ratkaisu. Olkoon P (x, y) predikaatti y = x+1. Ensimmäinen propositio saa tällöin muodon x y P (x, y) ja toinen voidaan kirjoittaa y x P (x, y). On syytä tarkasti huomioida edellisen esimerkin propositioiden erot. Ensimmäisessä propositiossa (joka on tosi) luku y voi riippua luvusta x, eli se valitaan luvun x pohjalta ja muuttuu, kun x muuttuu. Toinen, epätosi propositio, edellyttää, että luku y ei riipu x:stä. Havaitsemme, että universaali- ja eksistenssikvanttorin järjestyksellä on merkitystä. Esim. 12. Tarkastellaan teatterin lipunvarausjärjestelmää. Olkoon B(h, p) predikaatti 'henkilö h on varannut paikan p'. Kirjoita seuraavat propositiot symbolisessa muodossa: a) 'paikka p on varattu' b) 'henkilö h on varannut (ainakin yhden) paikan' c) 'kaikki paikat on varattu' d) 'ainoatakaan paikkaa ei ole varannut useampi kuin yksi henkilö' 50
Ratkaisu. a) h B(h, p) b) p B(h, p) c) p h B(h, p) d) h k p [B(h, p) B(k, p) h = k]. Olisi täysin mahdollista listata universaali- ja eksistenssikvanttoreita sisältäviä logiikan lakeja (vastaavasti kuin propositiolaskennan tapauksessa); tarkastelemme kuitenkin seuraavassa vain kvanttoreiden ja sekä operaation välistä yhteyttä. Oletetaan, että haluamme soveltaa negaatiota seuraavaan propositioon: 'kaikki joutsenet ovat mustia' Voimme kirjoittaa yo proposition muodossa x P (x), missä P (x) on predikaatti: 'joutsen x on musta'. Soveltamalla negaatiota alkuperäiseen propositioon, saamme ilmaisun 'ei ole totta, että kaikki joutsenet ovat mustia' joka on yhtäpitävä ilmaisun 'kaikki joutsenet eivät ole mustia' kanssa. Negaatio voidaan muodollisesti kirjoittaa [ x P (x)]. On myös toinen tapa sanoa, että kaikki joutsenet eivät ole mustia; voimme sanoa, että täytyy olla olemassa ainakin yksi joutsen, joka ei ole musta. Siispä alkuperäisen proposition negaation kanssa yhtäpitävä propositio on 'on olemassa joutsen, joka ei ole musta', joka symbolisesti voidaan ilmasta seuraavasti: Olemme kehittäneet logiikan säännön x[ P (x)] [ x P (x)] x[ P (x)] joka sanoo, että muotoa x P (x) olevan proposition negaatio saadaan vaihtamalla universaalikvanttori eksistenssikvanttoriksi ja ottamalla predikaatin negaatio. On olemassa toinen laki, jota voidaan pitää edellisen duaalilakina: [ x P (x)] x[ P (x)] 51
Laki sanoo sen, että muotoa x P (x) olevan proposition negaatio saadaan vaihtamallla eksistenssikvanttori universaalikvanttoriksi ja ottamalla predikaatin negaatio. Esim. 13. Kirjoita seuraavan proposition negaatio. 'jokaista lukua x kohti on olemassa sellainen luku y, että y < x'. Ratkaisu. Kirjoitetaan proposition negaatio symbolisessa muodossa ja sovelletaan logiikan lakeja: [ x y(y < x)] x[{ [ y(y < alx)]} x y[ (y < x)] x y(y x). Selkokielellä 'on olemassa sellainen luku x, että kaikilla luvuilla y on voimassa y x'. On tärkeää aina tarkastaa, että vastaus on järkevä, kun proposition negaatiota määritetään. Logiikan lakeja ei tule soveltaa täysin mekaanisesti. Voimme käyttää edellä esitettyjä sääntöjä todentaessamme kappaleen alussa esitetyn proposition 'Ei ole totta, että kaikki alkuluvut ovat parittomia. Siispä on olemassa ainakin yksi alkuluku, joka ei ole parillinen'. Merkitään P (x):llä predikaattia ' x on alkuluku' ja Q(x):llä predikaattia ' x on pariton'. Tällöin propositio 'kaikki alkuluvut ovat parittomia' voidaan esittää muodossa 'kaikilla x, jos x on alkuluku, se on pariton'. Symbolisessa muodossa: x[p (x) Q(x)] Alkuperäisen proposition negaatio on nyt { x[p (x) Q(x)]} Soveltamalla negaatiota koskevaa lakia ja aikaisempia propositiolaskennan sääntöjä, saamme seuraavaa: { x[p (x) Q(x)]} x{ [P (x) Q(x)]} x{ [ P (x) Q(x)]} x[ P (x) Q(x)] x[p (x) Q(x)] 52
Päättelyketjun viimeinen rivi pitää sisällään: 'On olemassa selainen x, että x on alkuluku ja se ei ole pariton'. Tämä voidaan sanoa toisin: 'On olemassa ainakin yksi alkulku, joka ei ole pariton'. Annamme vielä kaksi tärkeää predikaattikalkyylin lakia. x[p (x) Q(x)]} x[p (x) Q(x)]} x P (x) xq(x) x P (x) x Q(x) 3.8 Todistusmenetelmiä Todistamisella on keskeinen rooli matematiikassa; matematiikan teoriat perustuvat aksiomeihin, todeksi olettetuihin otaksumiin, joita ei todisteta ja jotka määrittävät kyseessä olevan teorian. Esimerkiksi Eukleideen geometrian yksi aksiomi sanoo, että kahden pisteen kautta voidaan aina piirtää suora. Aksiomien pohjalta voidaan päättelysäännöillä johtaa teoreemoja, uusia totta olevia väittämiä. Teoreeman todistus on äärellinen jono ilmaisuja, joista jokainen on joko aksiomi tai jotakin päättelysääntöä soveltamalla saatu jonon aikaisemmista ilmaisuista. Logiikan tärkeä päättelysääntö on ns. 'modus ponens' -sääntö: olkoot p ja q propositioita. Modus ponens -sääntö sanoo: 'jos p on tosi ja p q on tosi, niin q on tosi'. Matematiikan todistukset voidaan esittää hyvin formaalilla tavalla: aksiomit ja teoreemat voidaan kirjoittaa propositio- ja predikaattilogiikan merkinnäin ja päättelysääntöjä voidaan soveltaa joka askeleessa. Tällainen lähestymistapa on aiheellinen joissakin tilanteissa, esim. tietokeoneen suorittaessa mekaanista teoreemantodistamista. Tavallisesti todistukset esitetään normaalikielisinä lauseina, joissa käytetään matematiikan merkintöjä. Esittelemme seuraavassa muutamia todistustekniikoita. Eräs tärkeä menetelmä, induktiotodistus, tulee vastaan myöhemmin. Teoreemojen todistaminen on taito, joka vaatii harjoittelua. Ei ole olemassa yhtä ainoaa menetelmää, joka sopisi jokaiseen tilanteeseen, vaan usein joudutaan kokeilemaan yhden ainoan sijasta useaa todistustapaa ja eri menetelmien sekoituksia. Seuraavassa esimerkkejä. Esim. 14. Osoita, että kahden parillisen kokonaisluvun summa on aina parillinen luku. 53
Ratkaisu. Olkoot x ja y parillisia kokonaislukuja. Siis ne ovat jaollisia luvulla 2, joten x = 2m jollakin kokonaisluvuilla m ja y = 2n jollakin kokonaisluvulla n. Laskemalla summan x + y saamme x + y = 2m + 2n = 2(m + n). Koska m+n on kokonaisluku, on 2(m+n) parillinen. Siispä x+y on parillinen. Edellä esitetty ratkaisu on tyyppiesimerkki niin sanotusta suorasta todistuksesta. Tällöin aloitetaan oletuksista ( x ja y parillisia) ja pidetään mielessä päämäärä, johon pyritään ( x + y on parillinen) sekä edetään sopivin väliaskelin, kunnes voidaan käyttää hyväksi parillisuuden määritelmää summaan x + y. Seuraavassa toinen esimerkki suorasta todistuksesta. Esim. 15. Osoita, että jos x on muotoa 3k + 1 (missä k on kokonaisluku) oleva luku, niin x 2 on myös tätä muotoa. Ratkaisu. Oletetaan, että x = 3k + 1, missä k on kokonaisluku. Tällöin x 2 = (3k + 1) 2 = (3k) 2 + 2 (3k) 1 + 1 2 = 9k 2 + 6k + 1 = 3(3k 2 + 2k) + 1 Asettamalla n = 3k 2 + 2k näemme, että x 2 muotoa. = 3n + 1 ja siten vaadittua Esim. 16. Olkoon x kokonaisluku. Osoita, että jos x 2 on parillinen. on parillinen, niin x Ratkaisu. Nyt suora todistus ei välttämättä johda helposti haluttuun lopputulokseen. Sovelletaan toista tekniikkaa, ns. epäsuoraa todistusta. Muistamme, että propositio p q on loogisesti ekvivalentti kontrapositionsa q p kanssa. Osoitamme oikeaksi alkuperäisen väitteen kontraposition 'Jos x on pariton, niin x 2 on pariton. Oletetaan, että x on pariton. Tälläin x = 2k + 1 missä k on jokin kokonaisluku. Tällöin x 2 = (2k + 1) 2 = 4k 2 + 4k + 1 = 2(2k 2 + 2k) + 1 Asetetaan n = 2k 2 + 2k ja havaitaan, että x 2 = 2n + 1 ja pariton. Esim. 17. Olkoot x, y ja z positiivisia kokonaislukuja. Osoita, että jos xy = z 2 ja x < z, niin y > z. 54
Ratkaisu. Väite voidaan todistaa suoraankin, mutta käytetään tällä kertaa ristiriitatodistusta: tehdään vastaoletus eli oletetaan, että väite (tässä tapauksessa y > z ) ei ole tosi ja johdetaan ristiriita oletusten kanssa. Oletetaan siis, että xy = z 2 ja x < z, mutta y z. Kertomalla viimeinen epäyhtälö puolittain positiivisella kokonaisluvulla x saamme xy xz. Koska x < z, on xy < z 2. Tämä on ristiriidassa sen kanssa, että xy = z 2. Siis vastaoletus on väärä ja väite oikea. Joskus joudumme osoittamaan vääräksi yleisen, esim. kokonaislukuja koskevan väitteet. Tämä voidaan usein tehdä vastaesimerkin avulla. Esim. 18. Osoita vääräksi seuraava väite. Jokainen luonnollinen luku voidaan esittää muodossa x 2 + y 2, missä x ja y ovat luonnollisia lukuja. Ratkaisu. Osoitetaan, että 3 on vastaesimerkki. Osoitamme siis, että lukua 3 ei voida esittää kahden luonnollisen luvun x ja y neliön summana. Jos x 1 ja y 1, niin x 2 + y 2 2 < 3, joten x 2 + y 2 ei voi olla yhtäsuuri kuin 3 tässä tapauksessa. Jos sitten x 2 tai y 2, on x 2 + y 2 4, joten x 2 + y 2 ei voi olla yhtäsuuri kuin 3 tässäkään tapauksessa. Siten lukua 3 ei voi esittää kahden luonnollisen luvun neliön summana. 55
4 Joukot, relaatiot ja funktiot On väitetty, että kaikki moderni matematiikka voidaan esittää joukko-opin ja funktioiden avulla. Myös tietojenkäsittelytieteessä tämän teorian tuntemus on hyödyllistä. Tässä luvussa käsitellään joukko-opin perusteiden lisäksi asiaan läheisesti liittyviä relaatioita ja funktioita. 4.1 Johdanto Matematiikassa joukko on mikä tahansa hyvin määritelty kokoelma objekteja, joita kutsutaan joukon alkioiksi. Esimerkkejä joukoista: tälle luennolle osallistuvat opiskelijat, ASCII-merkit, luvulla viisi tasan jaolliset kokonaisluvut, jne... Joukko voidaan määrittää kahdella tavalla. Joko luettelemalla joukon alkiot ja asettemalla ne aaltosulkeiden sisään tai luonnehtimalla joukkoa jonkin ominaisuuden (predikaatin) perusteella jonka kaikki sen alkiot toteuttavat. Kymmentä pienemmät parittomat positiiviset parittomat kokonaisluvut voidaaan esittää seuraavasti: {1, 3, 5, 7, 9}. Mikäli selkeä sääntö on havaittavissa joukon alkioissa, voimme käyttää kolmea pistettä merkitsemään alkioita, joita ei luetella. Esim. lukua 50 pienempien parittomien positiivisten kokonaislukujen joukko voidaan esittää muodossa {1, 3, 5,..., 49} sen sijaan että jokainen alkio lueteltaisiin. Myös äärettömiä joukkoja voidaan esittää luettelemalla niiden alkiot. Kaikkien positiivisten parittomien kokonaislukujen joukko voidaan antaa muodossa {1, 3, 5,...}. Toinen tapa määrittää joukko käyttää ominaisuutta, jonka kaikki joukon alkiot toteuttavat. Esimerkiksi kaikkien lukua 50 pienempien parittomien positiivisten kokonaislukujen joukko voidaan esittää muodossa { n n on pariton kokonaisluku ja 0 < n < 50 }. 56
Tässä joukkomerkinnässä n kuvaa tietysti (mitä tahansa) joukon alkiota ja pystyviivan takana esitetään ominaisuus, jonka tämä (mikä tahansa) joukon alkio toteuttaa. Kun esitämme joukon muodossa {x P (x) }, missä P (x) on predikaatti, sanomme, että joukko on annettu predikaattimuodossa. Merkitsemme joukkoja isoilla kirjaimilla A, B, C,..., X, Y,... joskus alaindekseillä varustettuna. Joukon alkioita merkitään pienillä kirjaimilla a, b, c,..., x, y,.... Sitä, että alkio a kuuluu joukkoon A merkitään: a A. Jos taas alkio b ei kuulu joukkoon A, merkitään: b / A. Joukko määräytyy täysin alkioidensa kautta. Siten kaksi joukkoa A ja B ovat yhtäsuuret eli samat, merk. A = B, täsmälleen silloin, kun niillä on samat alkiot. Tyhjä joukko, merkitään, on joukko, jossa ei ole yhtään alkiota. Huomattakoon, että { } ei ole tyhjä joukko, vaan yksialkioinen joukko, jonka ainoa alkio on tyhjä joukko. Joskus on järkevää olettaa, että kaikki annetun ongelman yhteydessä käsitellyt alkiot kuuluvat kiinteään perus- eli universaalijoukkon E. Tämä joukko voi vaihdella, kun siirrytään ongelmasta toiseen. Esimerkiksi reaalilukuihin keskityttäessä on järkevää olettaa, että perusjoukko on R. 4.2 Osajoukot, joukko-operaatiot ja Vennin diagrammit Olkoot A ja B joukkoja. Sanomme, että joukko A on joukon B osajoukko, merkitään A B, jos jokainen joukon A alkio on myös B :n alkio. Usean joukon välisiä relaatioita on näppärä kuvata Vennin diagrammin avulla graa- sesti. Osajoukon määritelmän nojalla tyhjä joukko on jokaisen joukon A osajoukko: A. Koska ei sisällä yhtään alkiota, propositio x[x x A] on tosi. Edelleen joukko A on aina itsensä osajoukko: A A. Kun joukko esitetään luettelemalla sen alkiot, ei luettelujärjestyksellä joukon identiteetin kannalta ole merkitystä; siten {a, b, c} = {b, a, c}. Liioin sillä, kuinka monta kertaa alkio luettelossa esiintyy ei ole merkitystä, joten {a, b, c} = {b, a, c, a, b}. Vain sillä, mistä alkioista joukko koostuu, on väliä. Selvästi joukot A ja B ovat samat täsmälleen silloin, kun A B ja B A. Joukko A on joukon B aito osajoukko, jos A B ja A B. Selvästi joukko 57
Kuva 4.1: Joukkojen leikkaus A on joukon B aito osajoukko, täsmälleen silloin, kun A B ja on olemassa b B, jolle b / A. Kahden joukon A ja B leikkaus on joukko A B = { x x A ja x B }. Kuvassa 4.1 joukkojen leikkaus Vennin diagrammilla kuvattuna. Sanomme, että joukot A ja B ovat (pareittain) erilliset eli pistevieraat, jos A B =. Joukot ovat erilliset täsmälleen silloin, kun niissä ei ole yhteisiä alkioita. Kahden joukon A ja B unioni eli yhdiste on joukko A B = { x x A tai x B }. Joukkojen unioni saadaan yhdistämällä niiden alkiot yhdeksi joukoksi. Kuva 4.2 esittää joukkojen unioni Vennin diagrammin avulla. Kahden joukon A ja B erotus eli joukkoerotus on joukko A \ B = { x x A ja x / B }. Joukkojen A ja B erotus saadaan poistamalla A:sta kaikki joukon B alkiot. 58
Kuva 4.2: Joukkojen unioni Kvassa 4.3 on joukkojen erotus Vennin diagrammilla kuvattuna. Perusjoukon E ja joukon A erotusta kutsutaan A:n komplementiksi ja sitä merkitäään A c : A c = E \ A = { x x E ja x / A }. Joukkojen erotus on vähiten käytetty joukko-operaatio. Osittain tämä johtuu siitä, että se voidaan palauttaa komplementtiin (joka tosin yllä määriteltiin erotusta käyttäen). Myöhemmin esitettyjen joukko-opin lakien avulla on helppo osoittaa todeksi yhtäläisyys A \ B = A B c. Esim. 1. Olkoon E = {1, 2, 3,..., 10} universaalijoukko ja A = {2, 4, 7, 9}, B = {1, 4, 6, 7, 10} ja C = {3, 5, 7, 9}. Muodosta joukot a) A B b) A C c) B C c d) (A B c ) C e) (B C) c C. Käytä hyväksi Vennin diagrammeja. Ratkaisu. a) A B = {1, 2, 4, 6, 7, 9, 10} b) A C = {7, 9} c) C c = {1, 2, 4, 6, 8, 10}, joten B C c = {1, 4, 6, 10} d) B c = {2, 3, 5, 8, 9}, joten A B c = {2, 9} ja (A B c ) C = {2, 3, 5, 7, 9} e) B C = {1, 3, 4, 5, 6, 7, 9, 10}, joten (B C) c = {2, 8} ja (B C) c C =. 59
Kuva 4.3: Joukkojen erotus Joukko-opin operaatioilla leikkaus, unioni ja komplementti on luonteva vastineensa logiikan konnektiiveissa konjunktio ('ja'), disjunktio ('tai') ja negaatio ('ei'). Tämän vuoksi logiikan laeista saadaan vastaavat joukko-opin lait. Esimerkiksi logiikan kommutatiivisuuslain p q q p nojalla saamme joukkoopin kommutatiivisuuslain A B = B A. Tämä nähdään seuraavasti: A B = { x x A ja x B} = { x x B ja x A} = B A Joukko-opissa ovat voimassa samankaltaiset lait kuin propositiolaskennassa. Laki Nimi (A c ) c = A Kaksoiskomplementtilaki A A = A A A = A Idempotenttilait A B = B A A B = B A Kommutatiivisuuslait (A B) C = A (B C) (A B) C = A (B C) Assosiatiivisuuslait A (B C) = A (B C) = Distributiivisuuslait (A B) (A C) (A B) (A C) (A B) c = A c B c (A B) c = A c B c de Morganin lait A E = A A = A Identtisyyslait A = A E = E Annihilaatiolait A A c = A A c = E Inversiolait A (A B) = A A (A B) = A Absorptiolait 60
4.3 Joukon koko ja joukkojen karteesinen tulo Joukon A koko eli kardinaalisuus, merkitään A, on sen alkioiden lukumäärä. Siten äärettömän joukon C koko on ääretön; tällöin merkitään C =. Esim. 2. Joukolle A = {1, 2, 3, 5} on A = 4. Joukolle N puolestaan N =. Joukon A kaikkien osajoukkojen muodostamaa joukkoa kutsutaan A:n potenssijoukoksi ja sitä merkitään P(A). Esim. 3. Tarkastellaan kolmen alkion joukkoa A = {a, b, c}. Tällöin P(A) = {, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, b, c}}. Lause 1. äärellisellä joukolla A on 2 A eri osajoukkoa. Todistus. Olkoon A = {a 1, a 2,..., a n } joukko, jossa on n alkiota, n N. Muodostetaan (mielivaltainen) A:n osajoukko B. Voimme tehdä sen seuraavan algoritmin mukaisesti. Tarkastellaan kutakin A:n alkiota erikseen ja päätetään kuuluuko se joukkoon B vai ei. Kuuluuko alkio a 1 joukkoon B? Meillä on kaksi mahdollisuutta: joko a 1 B tai a 1 / B. Samalla tavalla joko a 2 B tai a 2 / B. Jatketaan vastaavalla tavalla alkioiden a 3, a 4,..., a n suhteen. Teemme (ns. kombinatoriikan tuloperiaatteen nojalla) johtopäätöksen, että mahdollisia osajoukkoja on 2 } 2 {{ 2 } = 2 n n kertaa kappaletta. Koska A = n, on väite tosi. Usein on tarpeen tarkastella rakenteita, joissa joukon alkioiden järjestyksellä on merkitystä. Alkioiden a 1, a 2,..., a n, missä n N +, (järjestetty) n-monikko on jono (a 1, a 2,..., a n ), missä siis alkioiden järjestyksellä on merkitystä. Erityisesti 2-monikkoa (vastaavasti 3-monikkoa) kutsutaan järjestetyksi pariksi (vastaavasti järjestetyksi kolmikoksi). Edellisen nojalla n-monikko (a 1, a 2,..., a n ) ja m-monikko (b 1, b 2,..., a m )ovat yhtäsuuret (eli samat), jos edellä n = m ja a i = b i, kun i = 1, 2,..., n. Joukkojen A ja B karteesinen tulo on joukko A B = {(a, b) a A ja b B}. 61
Sanallisesti: A B koostuu kaikista sellaisista järjestetyistä kaksikoista, joissa ensimmäinen alkio kuuluu joukkoon A ja toinen alkio joukkoon B. Yleistetään karteesisen tulon käsitettä. Olkoon n N +. Tällöin joukkojen A 1, A 2,..., A n karteesinen tulo on joukko A 1 A 2 A n = {(a 1, a 2,..., a n ) a i A i kun i = 1, 2,..., n }. Taas sanallisesti: A 1 A 2 A n koostuu kaikista sellaisista n-monikoista, joissa ensimmäinen alkio kuuluu joukkoon A 1, toinen alkio joukkoon A 2, jne..., n. alkio joukkoon A n. Voimme esittää yo karteesisen tulon hivenen ytimekkäämmin logiikan merkinnöin: A 1 A 2 A n = {(a 1, a 2,..., a n ) i {1, 2,..., n} : ai A i }. Esim. 4. Olkoon A = {a, b} ja B = {1, 2, 3}. Esitä karteesinen tulo A B luettelomuodossa. Ratkaisu. Vaadittu karteesinen tulo on A B = { (x, y) x A y B} = { (a, 1), (a, 2), (a, 3), (b, 1), (b, 2), (b, 3) }. Karteesisia tuloja sovelletaan laajasti tietokoneella laskennassa. Joissakin tietokoneissa (käyttöjärjestelmissä) käyttäjä tunnistetaan merkkijonosta, jonka kolme ensimmäistä symbolia ovat kirjaimia, kolme seuraavaa numeroita ja seitsemäs symboli taas kirjain, esim ABC123A. Olkoon L kirjainten ja D numerojen joukko. Tällöin validit merkkijonot saadaan karteesisesta tulosta L L L D D D L. Käyttäjätunnus ABC123A vastaa 7-monikkoa (A, B, C, 1, 2, 3, A) karteesisessa tulossa L L L D D D L. Merkinnöissä on pientä eroa, käsitteellisellä tasolla eroa ei ole. Toisinaan karteesinen tulo halutaan muodostaa vain yhtä joukkoa käyttäen. Joukon A (n-ulotteinen) karteesinen tulo on joukko A n = { (a 1, a 2,..., a n ) i {1, 2,..., n} : ai A }. Yllä karteesinen tulo A A A }{{} n kertaa on kirjoitettu muodossa A n. Koulusta tuttu (reaaliluku)taso R 2 siihen piirrettyine x- ja y -akseleineen on reaalilukujoukon R kaksiulotteisen karteesisen tulon geometrinen esitys. 62
4.4 Joukkojen tietokone-esitys Jotkin ohjelmointikielet (esim. Pascal) sallivat joukkojen käsittelemisen (yhdistettynä) tietorakenteena; tällöin joukon alkiot kuuluvat samaan tietotyyppiin, esim. kokonaislukuihin tai kirjoitusmerkkeihin. Näin ollen ohjelmassa joukko määritellään aina suhteessa perusjoukkoon E. Tällöin herää kysymys: miten joukkoja käsitellään ja miten niitä tallennetaan tietokoneessa? Vastaus tähän riippuu käytettävästä ohjelmointikielestä; esitystapoina käytetään mm. taulukkoja, hash-taulukkoja ja erilaisia puurakenteita. Näitä tietorakenteita käsitellään myöhemmillä kursseilla. Kun perusjoukkoon E kuuluu verrattain vähän alkioita, kätevä tapa esittää joukkoja on bittivektori, jota kuvataan seuraavassa. Kun käytetään bittivektoriesitystä, joukon E alkiot on lueteltu määrätyssä järjestyksessä ja jokainen ohjelmassa käsitelty joukko on E :n osajoukko. Joukko E on äärellinen, olkoon n joukon E koko. Tällöin (universaalijoukon E osajoukko) A tallentuu bittijonona b 1 b 2 b n, missä aina kun i {1, 2,..., n}, bitti b i = 1, jos E :n i. alkio kuuluu joukkoon A ja b i = 0, mikäli E :n i. alkio ei kuulu joukkoon A. Käsittämällä n:n pituinen bittijono b 1 b 2 b n aina joukon B n alkioksi (b 1, b 2,..., b n ), voimme olettaa, että b 1 b 2 b n B n. Edellä B = {0, 1} binaariaakkosto. Esim. 5. Olkoon E = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}. a) Mikä on joukon A = {2, 3, 5, 7} bittimuotoinen (tietokone-)esitys (eli bittijonoesitys)? b) Mikä on bittijonoa 1001011011 vastaava joukko? Ratkaisu. a) Joukon A = {2, 3, 5, 7} bittimuotoinen (tietokone-)esitys on 0110101000. b) Bittijonoa 1001011011 vastaava joukko on {1, 4, 6, 7, 9, 10}. Huomattakoon, että (joukkojen) leikkaus, unioni ja komplementti voidaan suorittaa suoraan joukkojen bittimuotoisille esityksille silloin, kun joukoilla on sama perusjoukko. Esimerkiksi joukon A B bittijonoesityksessä on i. paikassa bitti 1 täsmälleen silloin, kun sekä A:n että B :n bittijonoesityksessä on i. paikasa bitti 1. Edellä A B :n bittimuotoisen esityksen löytäminen tapahtuu bittikohtaista ja-operaatiota käyttäen. Vastaavalla tavalla joukkojen A B ja A c bittijonoesitykset saadaan bittikohtaisia tai- ja ei-operaatioita käyttäen. Esim. 6. Olkoon E = {1, 2, 3, 4, 5, 6, 7, 8}. Oletetaan, että joukon A ja B bittijonoesitykset ovat vastaavasti 00101110 ja 10100101. Määritä joukkojen A B, A B ja A c bittijonoesitykset. 63
Ratkaisu. Suoritetaan bittikohtainen ja, tai ja ei ja saadaan seuraavat bittijonoesitykset A B : 00100100,. A B : 10101111ja A c : 11010001 4.5 Relaatiot Reaalimaailman ongelmia mallinnetaan ja ratkaistaan matematiikan teorioita hyväksikäyttäen; nämä ratkaisut realisoituvat usein tietokoneohjelmina. Reaalimaailman ihmisten ja esineiden välisiä suhteita vastaavat matematiikassa relaatiot, joilla on tärkeitä sovelluksia myös tietokoneella laskennassa. Matematiikassa relaatiot liittyvät aina yhteen tai useampaan joukkoon. Perusmääritelmässä relaation käsitteeseen ei sisällytetä lainkaan semantiikkaa. Olkoon n positiivinen kokonaisluku ja A 1, A 2,..., A n joukkoja. Tällöin joukkojen A 1, A 2,..., A n välinen relaatio on mikä tahansa karteesisen tulon A 1 A 2 A n osajoukko. Esim. 7. Olkoon A 1 = {0, 1}, A 2 = N ja A 3 suomalainen aakkosto. Tällöin joukko T = {(x, y, z) x = 1 y on parillinen z {a, d, r, s}} on joukkojen A 1, A 2 ja A 3 välinen relaatio. Erikoistapauksena edellä esitetystä määritelmästä saadaan seuraavaa. Joukkojen A ja B välinen (binaari)relaatio on mikä tahansa karteesisen tulon A B osajoukko. Kun R on joukon A ja B välinen binaarirelaatio, kirjoitamme usein a R b merkinnän (a, b) R sijasta. Edelleen joukon A n-ulotteinen relaatio on mikä tahansa karteesisen tulon A } A {{ A osajoukko. } n kertaa Ja vielä: joukon A binaarirelaatio on mikä tahansa karteesisen tulon A A osajoukko. 1 1 Sana binaarirelaatio viittaa tässä siihen, että suhde koskee aina kahta joukon A alkiota. 64
Esim. 8. Olkoon I kaikkien ihmisten muodostama joukko. Tällöin F = {(a, b) a on b:n lapsi} on joukon A binaarirelaatio. Vastaavasti = {(x, y) x, y R x y} on joukon R binaarirelaatio. Keskitymme seuraavassa binaarirelaatioihin. Binaarirelaatioiden ja suunnattujen verkkojen välillä on kääntäen yksikäsitteinen vastaavuus. äärellisiä binaarirelaatioita voidaan siten kuvata graasesti. Olkoon A (äärellinen) joukko ja R sen binaarirelaatio. Kutakin joukon A alkiota vastaa suunnatussa verkossa solmu, joka voidaan piirtää mustana täplänä. Solmusta x piirretään nuoli solmuun y täsmälleen silloin, kun (x, y) R. Esim. 9. Esitä graasesti joukon A = {1, 2, 3, 4} N binaarirelaatio = {(x, y) x, y A x y}. Ratkaisu. Seuraava kuva esittää annettua relaatiota suunnattuna verkkona. äärellinen binaarirelaatio voidaan esittää myös relaatiomatriisin avulla. Olkoon n N + ja a 1, a 2,..., a n joukon A alkiot; siis A = n. Joukon A binaarirelaation R relaatiomatriisin rivit ja sarakkeet nimetään joukon A alkioilla a 1, a 2,..., a n. Matriisin paikassa (i, j) (i. vaakarivin ja j. pystyrivin leikkauksessa on T (vast. F), jos (a i, a j ) R (vast. (a i, a j ) / R). Esim. 10. Laadi relaatiomatriisi Esimerkki 9:n binaarirelaatiolle. 65