815338A Ohjelmointikielten periaatteet: Logiikkaohjelmointi. Logiikkaohjelmointi

Samankaltaiset tiedostot
815338A Ohjelmointikielten periaatteet

FI3 Tiedon ja todellisuuden filosofia LOGIIKKA. 1.1 Logiikan ymmärtämiseksi on tärkeää osata erottaa muoto ja sisältö toisistaan:


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

LOGIIKKA johdantoa

Nimitys Symboli Merkitys Negaatio ei Konjuktio ja Disjunktio tai Implikaatio jos..., niin... Ekvivalenssi... jos ja vain jos...

811120P Diskreetit rakenteet

Insinöörimatematiikka A

Prolog kielenä Periaatteet Yhteenveto. Prolog. Toni ja Laura Fadjukoff. 9. joulukuuta 2010

-Matematiikka on aksiomaattinen järjestelmä. -uusi tieto voidaan perustella edellisten tietojen avulla, tätä kutsutaan todistamiseksi

811120P Diskreetit rakenteet

Pikapaketti logiikkaan

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

Predikaattilogiikkaa

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

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

Logiikka 1/5 Sisältö ESITIEDOT:

Kesälukio 2000 PK2 Tauluharjoituksia I Mallivastaukset

Diskreetit rakenteet. 3. Logiikka. Oulun yliopisto Tietojenkäsittelytieteiden laitos 2015 / 2016 Periodi 1

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

HY / Matematiikan ja tilastotieteen laitos Johdatus logiikkaan I, syksy 2018 Harjoitus 4 Ratkaisuehdotukset

Lisää kvanttoreista ja päättelyä sekä predikaattilogiikan totuustaulukot 1. Negaation siirto kvanttorin ohi

815338A Ohjelmointikielten periaatteet Harjoitus 7 Vastaukset

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

Luonnollisen päättelyn luotettavuus

PROPOSITIOLOGIIKAN RIITTÄMÄTTÖMYYS

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

MS-A0402 Diskreetin matematiikan perusteet

Loogiset konnektiivit

Tehtävä 1. Päättele resoluutiolla seuraavista klausuulijoukoista. a. 1 {p 3 } oletus. 4 {p 1, p 2, p 3 } oletus. 5 { p 1 } (1, 2) 7 (4, 6)

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

Johdatus logiikkaan I Harjoitus 4 Vihjeet

811120P Diskreetit rakenteet

Matematiikan tukikurssi

T kevät 2007 Laskennallisen logiikan jatkokurssi Laskuharjoitus 1 Ratkaisut

Todistusteoriaa. Kun kielen syntaksi on tarkasti määritelty, voidaan myös määritellä täsmällisesti, mitä pätevällä päättelyllä tarkoitetaan.

811120P Diskreetit rakenteet

Matematiikan johdantokurssi, syksy 2016 Harjoitus 11, ratkaisuista

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

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

Johdatus matematiikkaan

T Kevät 2006 Logiikka tietotekniikassa: perusteet Laskuharjoitus 8 (opetusmoniste, kappaleet )

Lause 5. (s. 50). Olkoot A ja B joukkoja. Tällöin seuraavat ehdot ovat

1 Logiikkaa. 1.1 Logiikan symbolit

Kirjoita käyttäen propositiosymboleita, konnektiiveja ja sulkeita propositiologiikan lauseiksi:

Propositiot: Propositiot ovat väitelauseita. Totuusfunktiot antavat niille totuusarvon T tai E.

Ratkaisu: Käytetään induktiota propositiolauseen A rakenteen suhteen. Alkuaskel. A = p i jollain i N. Koska v(p i ) = 1 kaikilla i N, saadaan

4 Matemaattinen induktio

T Syksy 2004 Logiikka tietotekniikassa: perusteet Laskuharjoitus 2 (opetusmoniste, lauselogiikka )

T Logiikka tietotekniikassa: perusteet Kevät 2008 Laskuharjoitus 11 (predikaattilogiikka )

13. Loogiset operaatiot 13.1

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

1. Logiikan ja joukko-opin alkeet

Matematiikan tukikurssi, kurssikerta 2

Lisää pysähtymisaiheisia ongelmia

FORMAALI SYSTEEMI (in Nutshell): aakkosto: alkeismerkkien joukko kieliopin määräämä syntaksi: sallittujen merkkijonojen rakenne, formaali kuvaus

5.1 Semanttisten puiden muodostaminen

3. Predikaattilogiikka

Toinen muotoilu. {A 1,A 2,...,A n,b } 0, Edellinen sääntö toisin: Lause 2.5.{A 1,A 2,...,A n } B täsmälleen silloin kun 1 / 13

T Kevät 2005 Logiikka tietotekniikassa: erityiskysymyksiä I Kertausta Ratkaisut

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

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

T Kevät 2009 Logiikka tietotekniikassa: perusteet Laskuharjoitus 8 (Predikaattilogiikka )

ITKP102 Ohjelmointi 1 (6 op)

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

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

T Logiikka tietotekniikassa: perusteet Kevät 2008 Laskuharjoitus 5 (lauselogiikka ) A ( B C) A B C.

Todistamisessa on tärkeää erottaa tapaukset, kun sääntö pätee joillakin tai kun sääntö pätee kaikilla. Esim. On olemassa reaaliluku x, jolle x = 5.

Karteesinen tulo. Olkoot A = {1, 2, 3, 5} ja B = {a, b, c}. Näiden karteesista tuloa A B voidaan havainnollistaa kuvalla 1 / 21

13. Loogiset operaatiot 13.1

Tehtäväsarja I Seuraavissa tehtävissä harjoitellaan erilaisia todistustekniikoita. Luentokalvoista 11, sekä voi olla apua.

LOGIIKKA, TIETÄMYS JA PÄÄTTELY

Predikaattilogiikan malli-teoreettinen semantiikka

Ratkaisu: Yksi tapa nähdä, että kaavat A (B C) ja (A B) (A C) ovat loogisesti ekvivalentit, on tehdä totuustaulu lauseelle

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

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

HY / Matematiikan ja tilastotieteen laitos Johdatus logiikkaan I, syksy 2018 Harjoitus 5 Ratkaisuehdotukset

Johdatus matemaattiseen päättelyyn

b) Määritä myös seuraavat joukot ja anna kussakin tapauksessa lyhyt sanallinen perustelu.

Algoritmit. Ohjelman tekemisen hahmottamisessa käytetään

Reaalifunktioista 1 / 17. Reaalifunktioista

Todistusmenetelmiä Miksi pitää todistaa?

TAMPEREEN YLIOPISTO Pro gradu -tutkielma. Heidi Luukkonen. Sahlqvistin kaavat

Diskreetin matematiikan perusteet Laskuharjoitus 2 / vko 9

11.4. Context-free kielet 1 / 17

Rakenteiset päättelyketjut ja avoin lähdekoodi

TAMPEREEN YLIOPISTO Pro gradu -tutkielma. Roosa Niemi. Riippuvuuslogiikkaa

MS-A0402 Diskreetin matematiikan perusteet

Ensimmäinen induktioperiaate

Johdatus matemaattiseen päättelyyn

(1) refleksiivinen, (2) symmetrinen ja (3) transitiivinen.


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

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

Sekalaiset tehtävät, 11. syyskuuta 2005, sivu 1 / 13. Tehtäviä

MS-A0401 Diskreetin matematiikan perusteet Yhteenveto, osa I

Ensimmäinen induktioperiaate

Matematiikassa ja muuallakin joudutaan usein tekemisiin sellaisten relaatioiden kanssa, joiden lakina on tietyn ominaisuuden samuus.

Cantorin joukon suoristuvuus tasossa

1 Määrittelyjä ja aputuloksia

Transkriptio:

Logiikkaohjelmointi Tässä osassa käsitellään toista deklaratiivisen ohjelmoinnin paradigmaa eli logiikkaohjelmointia. Pääasiallisena lähteenä on käytetty Sebestan ([Seb]) lukua 16. Maarit Harsun teoksen [Har] luvussa 14 perehdytään myös logiikkaohjelmointiin. Symboliseen logiikkaan perustuvaa ohjelmointia nimitetään logiikkaohjelmoinniksi ja tällaiseen ohjelmointiin soveltuvia kieliä logiikkaohjelmointikieliksi. Joissakin yhteyksissä nimitys deklaratiivinen kieli rajataan koskemaan pelkästään logiikkaohjelmointikieliä. Logiikkaohjelmointikielen syntaksi ja semantiikka eroaa imperatiivisen ohjelmointikielen vastaavista vielä voimakkaammin kuin funktionaalisten kielten. Logiikkaohjelmoinnissa ohjelmoija ei määrittele ratkaisuun johtavia toimenpiteitä, vaan ratkaisuun johtavia ominaisuuksia eli väittämiä, joiden oikeellisuuden ohjelma pyrkii päättelemään vertailemalla niitä tunnettuihin tosiasioihin. Tulos true merkitsee, että väittämä on oikea, mutta false merkitsee yleensä vain, että väittämää ei pystytty todistamaan oikeaksi. Ihannetapauksessa ohjelmoijan ei tarvitse keskittyä ratkaisuun johtavien toimenpiteiden ohjelmoimiseen vaan ratkaisun löytämisen logiikkaan. 1. Symbolisesta logiikasta Koska logiikkaohjelmointi perustuu vahvasti symbolisen logiikan käyttöön, tarkastellaan hieman sen ominaisuuksia. Diskreettien rakenteiden kurssissa käsitellään myös propositio- ja predikaattilogiikkaa (ks. [Kor], Luku 3). Propositio on looginen väittämä, jolla on totuusarvo. Symbolinen logiikka yksinkertaisimmillaan on propositio- eli lauselogiikkaa. Symbolisen logiikan avulla esitetään propositioiden välisiä suhteita ja johdetaan uusia väittämiä olemassa olevista. Propositiosymboleita (joilla usein on jokin tulkinta, esimerkiksi "On kylmä" tai "Sataa") yhdistellään käyttämällä loogisia konnektiiveja; nämä ovat

Nimi Symboli Esimerkki Semantiikka Negaatio a ei a Konjunktio a b a ja b Disjunktio a b a tai b Implikaatio tai a b a b a:sta seuraa b b:stä seuraa a Ekvivalenssi a b a ja b yhtäpitävät Propositiologiikassa negaatiolla on korkein preferenssi, minkä jälkeen tulevat konjunktio, disjunktio ja ekvivalenssi, jotka ovat preferenssiltään korkeammalla kuin implikaatio. Päättely-operaattoreiden = > ja < = > avulla voidaan muodostaa päättelyketjuja, joiden avulla saadaan uusia lauseita esimerkiksi seuraavasti: On kylmä Palelee On kylmä => Palelee Logiikkaohjelmoinnissa tarvittava symbolinen logiikka on predikaattilogiikkaa, jota kuvataan hieman seuraavaksi. Itse asiassa logiikkaohjelmoinnin käyttämä logiikka on jossakin propositio- ja predikaattilogiikan välimaastossa. Propositiologiikka ei sisällä muuttujia, joten se on liian yksinkertaista, predikaattilogiikka taas on ratkeamaton, ts. ei ole tehokasta algoritmia, jonka avulla voitaisiin päätellä onko jokin predikaatti tosi. Predikaattilogiikan avulla voidaan muodostaa ilmauksia, jotka koskevat propositiojoukkoja. Tätä varten loogisten lauseiden esittämisessä sallitaan lisäksi muuttujat, jotka esiintyvät aina kvanttoreiden (universaalikvanttori) ja

(eksistenssikvanttori) yhteydessä. Ensin mainittu tarkoittaa, että jokin ominaisuus pätee kaikilla arvoilla ja toinen, että on olemassa jokin arvo, jolle ominaisuus pätee, ts. Y:P Z:Q Kaikilla arvoilla Y P on tosi On olemassa sellainen Z että Q on tosi Presedenssijärjestyksessä kvanttorit ovat samalla tasolla kuin negaatio. Propositio on suljettu lause ja predikaatti on avoin lause, joka saadaan parametrisoimalla propositio. Predikaatista saadaan propositio korvaamalla parametrit eli muuttujat joillakin vakioilla. Predikaattilogiikan perusosat ovat: Vakiot, jotka edustavat tunnettuja alkioita. Vakioita merkitään yleensä pienillä kirjaimilla alkavilla tunnisteilla; lisäksi kokonaisluvut ovat vakioita. Muuttujat, jotka edustavat tuntemattomia alkioita. Niitä merkitään yleensä isoilla kirjaimilla alkavilla tunnisteilla. Funktiosymbolit eli funktorit (nimeävät funktioita). Predikaattisymbolit eli predikaatit, jotka määrittelevät alkioiden väliset relaatiot. Esimerkiksi ">": p(x,y)= X > Y. Termit ovat lausekkeita jotka koostuvat vakioista, muuttujista ja funktoreista. Esimerkiksi f(x) + Y + 10. Atomikaava koostuu predikaatista, jonka argumenttina voi olla termi. Esimerkiksi f(z)-x < 0. Kaava saadaan yhdistelemällä atomikaavoja loogisilla konnektiiveilla ja kvanttoreillla. Esimerkiksi Y X: (f(x) < 1) (Y > 0) Loogisella päättelyllä tarkoitetaan johtopäätösten muodostamista premisseistä (tunnetuista lauseista) loogisten päättelysääntöjen nojalla. Formaalisti oikea päättely tapahtuu siten, että kaavojen tai lauseiden semantiikka esitetään formaalisti ja noudatetaan korrektia semantiikkaa kussakin päättelysäännössä. Johtopäätökset vastaavat (yleensä) ihmisen käsitystä loogisista seurauksista. Yksinkertaisimmat lauseet, joita käytetään logiikkaohjelmoinnissa, ovat atomisia propositioita, nämä koostuvat yhdistetyistä termeistä, jotka kirjoitetaan

funktiokutsumaisessa muodossa. Yhdistetty termi muodostuu kahdesta osasta; funktorista ja järjestetystä parametrien listasta, esimerkiksi lammas(dolly) syö(dolly,ruoho) ovat yhdistettyjä termejä. Tässä esitetään ainoastaan, että relaatio lammas sisältää alkion {dolly} ja että relaatio syö sisältää järjestetyn kaksikon {dolly,ruoho}. Lauseiden semantiikka on deklaratiivista, ts. se on välittömästi nähtävissä lauseesta itsestään. Mitään tulkintaa lauseisiin ei kuitenkaan sinänsä sisälly. Esimerkiksi jälkimmäinen termi voi tarkoittaa, että dolly syö ruohoa, ruoho syö dollyä tai lause voi tarkoittaa jotakin aivan muuta. Ylläesitetyt lauseet koostuvat vakioista, mutta propositioissa voi myös esiintyä muuttujia. Atomisten propositioiden ja konnektiivien avulla voidaan muodostaa koottuja propositioita, esimerkiksi lammas(dolly) nisäkäs(dolly) syö(dolly,x) liha(x) Jotta logiikkaohjelmointi olisi lainkaan hyödyllistä, siinä täytyy olla jonkinlaisia mekanismeja, joiden avulla johdetaan uusia sääntöjä. Sääntö voidaan johtaa annetuista tosista lauseista soveltamalla niihin äärellistä määrää peräkkäisiä päättelyjä. Logiikkaohjelmoinnissa päättelymekanismit perustuvat modus ponens- sääntöön ja universaalikvanttorin eliminointiin. Modus ponens: Lause A (A B) voidaan korvata termillä B Universaalikvanttorin eliminoimissääntö: Lause X:A(X) voidaan korvata lauseella, jossa kaikki muuttujan X vapaat esiintymät on korvattu jollakin termillä. Koneellisessa loogisessa päättelyssä suureksi ongelmaksi muodostuu keskenään ekvivalenttien lauseiden joukko, joka on kooltaan valtava. Siksi olisi toivottavaa

määritellä jokin standardimuoto, jonka avulla propositiot voitaisiin esittää. Eräs tällainen on klausuuli. Klausuulin muoto on B1 B2... BN A1 A2... AM Missä A:t ja B:t ovat termejä. Klausuulin semantiikka: Jos kaikki A:t ovat tosia, ainakin yksi B on tosi. Oikeaa puolta kutsutaan edellytykseksi (antecedent) ja vasenta puolta seuraukseksi (consequent). Vasen puoli toteutuu, kunhan vain oikea puoli voidaan osoittaa todeksi. Voidaan osoittaa, että kaikki predikaattilogiikan propositiot on algoritmisesti mahdollista muuttaa klausuuleiksi. Logiikkaohjelmoinnissa käytetään yleisesti erikoistapausta B A1 A2... AM jota kutsutaan Hornin klausuuliksi. Esimerkiksi syö(dolly,timotei) syö(dolly,ruoho) ruoho(timotei) Mikäli Hornin klausuuli käsittää ainoastaan seurauksen (oikea puoli on tyhjä), sen vasen puoli on varauksetta tosi. Joskus tällaisia klausuuleja sanotaan myös faktoiksi. Alan Robinson kehitti vuonna 1965 ns. resoluutioperiaatteen tutkiessaan mahdollisuuksia automatisoida lauseiden todistusmekanismeja. Resoluutio on päättelymekanismi, jonka avulla annetuista propositioista johdetaan uusia propositioita. Resoluutioaskeleen periaate on hyvin yksinkertainen ja se perustuu modus ponens-eliminointisääntöön. Oletetaan esimerkiksi, että seuraavat säännöt ovat voimassa: P Q (1) R P (2) Tästä saadaan johdettua sääntö R Q (3)

Ensimmäisistä klausuuleista voidaan päätellä eräänlainen supistamismekanismi: kirjoitetaan P R Q P Ja "supistetaan" P pois, jolloin jäljelle jää klausuuli (3). Logiikkaohjelmoinnissa resoluutiomekanismissa joudutaan vielä huomioimaan muuttujat ja käyttämään lisäksi universaalikvanttorin eliminointisääntöä. Resoluutio yleistyy myös Hornin klausuuleille, joissa oikealla puolella on useampi termi. Resoluutiomekanismin käyttö logiikkaohjelmassa toimii seuraavasti: Kun halutaan todistaa jokin väite, se esitetään Hornin klausuulin oikeana puolena. Klausuuli yhdistetään tunnettuihin sääntöihin ja mikäli onnistutaan resoluution avulla saavuttamaan tyhjä klausuuli, on väite tosi. Väitettä voidaan myös nimittää kyselyksi (query). Esimerkki. Oletetaan säännöt (1) jalat(x,2) nisäkäs(x) kädet(x,2) (2) jalat(x,4) nisäkäs(x) kädet(x,0) (3) nisäkäs(lammas) (4) kädet(lammas,0) Halutaan todistaa väite jalat(lammas,4) Aluksi kirjoitetaan väite Hornin klausuulin oikeana puolena jalat(lammas,4) Yhdistetään tämä sääntöön (2), jolloin saadaan jalat(x,4) nisäkäs(x) kädet(x,0) jalat(lammas,4)

Korvataan x vakiolla lammas: jalat(lammas,4) nisäkäs(lammas) kädet(lammas,0) jalat(lammas,4) Resoluutiolla saadaan supistettua jalat(lammas,4) pois, joten tullaan lausekkeeseen nisäkäs(lammas) kädet(lammas,0) Yhdistetään tämä sääntöön (3): nisäkäs(lammas) nisäkäs(lammas) kädet(lammas,0) Resoluutiolla saadaan supistettua nisäkäs(lammas) pois ja lauseke saadaan muotoon kädet(lammas,0) Yhdistetään lopuksi tämä neljänteen sääntöön ja käytetään taas resoluutiota supistamaan kädet(lammas,0) pois: kädet(lammas,0) kädet(lammas,0) Päästiin siis tyhjään klausuuliin, joten väite on tosi.

2. Prolog Tarkastellaan yleisimmän logiikkaohjelmointikielen Prologin ominaisuuksia. Prologin perusrakenteen suunnittelivat Colmerauer, Roussel sekä Kowalski, ja ensimmäinen Prolog-tulkki implementoitiin Marseillessa vuonna 1972. Kielestä on syntynyt monia murteita, joilla voi olla hyvinkin erilaiset syntaksit. Edinburghin yliopistossa luotu versio on kuitenkin saavuttanut jonkinlaisen standardin aseman. Kielelle on laadittu vuonna 1995 ISO-standardi, joka pohjautuu Edinburghin versioon. Prolog ei ole puhtaasti logiikkaohjelmointikieli, vaan sisältää piirteitä myös imperatiivisista ohjelmointikielistä. Prologin ominaisuuksia kuvataan tässä lähinnä Loudenin ([Lou], kappale 11) ja Sebestan ([Seb], kappaleet 16.5 16.7) mukaisesti. Prologissa käytetään samankaltaista notaatiota Hornin klausuuleille kuin yllä on esitetty, mutta nuolimerkintä on korvattu merkinnällä :- ja and -merkintä pilkulla, ts. Prologissa kirjoitettaisiin esi_isa(x,y) :- vanhempi(x,z), esi_isa(z,y). Prologissa erotetaan muuttujien ja vakioiden sekä predikaattien nimet siten, että muuttujien nimet alkavat isolla kirjaimella. Muuten alkukirjaimena käytetään pientä kirjainta. Prologin jokainen lause päättyy pisteeseen. Prologissa peruslauseista muodostuu oletetun tiedon tietokanta, jota hyväksi käyttäen voidaan johtaa uutta tietoa. Prologissa käytetään kahdentyyppisiä peruslauseita: Lauseet, jotka vastaavat Hornin klausuulien vasenta puolta ja lauseet jotka vastaavat varsinaisia Hornin klausuuleja. Ensin mainitut katsotaan faktoiksi, ts. loogisesti ne tulkitaan tosiksi lauseiksi. Toisen tyypin peruslauseita sanotaan myös säännöiksi. Prologissa väitteitä, joita halutaan todistaa, kutsutaan kyselyiksi (query) tai maalilauseiksi (goal) ja nämä esitetään Prolog -tulkille samassa muodossa kuin faktatkin. Oletetaan, että tietokantaan on syötetty lauseet esi_isa(x,y) :- vanhempi(x,z), esi_isa(z,y). esi_isa(x,x). vanhempi(nooa,haam).

Tällöin kysely esi_isa(nooa,haam) tuottaa tuloksen yes (tai true) ja kysely esi_isa(haam,nooa) tuloksen no (tai false). Samoin voidaan tehdä kysely esi_isa(x,haam) jolloin vastauksena saadaan X = nooa ->; (haetaan lisää) X = haam Prolog sisältää määrittelyt aritmeettisille operaatiolle ja niiden evaluoinnille. Prologille on kuitenkin kerrottava, milloin aritmeettista lauseketta tarkastellaan lausekkeena ja milloin se on evaluoitava. Esimerkiksi kirjoittamalla write(5+6). saa vastaukseksi 5+6. Mikäli haluaa Prologin evaluoivan summan, on kirjoitettava esimerkiksi X is 5+6, write(x). jolloin saa vastaukseksi X=11. Tästä aiheutuu mm. se että aritmeettisten lausekkeiden vertailu tuottaa tuloksen "no" mikäli lausekkeet ovat erilaiset siitä huolimatta, että niiden arvot olisivat samat. Siten 3+5 = 5+3 antaa tuloksen no. Jos halutaan vertailla lausekkeita niiden arvon perusteella, voidaan kirjoittaa predikaatti sama_arvo(termi1,termi2) :- X is Termi1, Y is Termi2, X=Y.

Tällöin syöttämällä sama_arvo(3+5,5+3) saadaan tulokseksi yes. Instantiointi tarkoittaa tyypin ja arvon liittämistä muuttujaan. Liittämisellä (unification) tarkoitetaan Prologissa prosessia, jolla kaksi muuttujaa instantioidaan sillä tavoin, että muuttujat täsmäävät resoluutiossa. Näin ollen liittäminen tarkoittaa jossakin mielessä kahden termin tekemistä samoiksi. Liittäminen ilmaistaan yhtäsuuruudella, esimerkiksi a = a -> yes (liittäminen onnistui) a = b -> no (eri vakioiden liittäminen ei onnistu) a = X -> X = a (muuttuja, jota ei ole instantioitu, liittyy mihin tahansa ja instantioituu tällä) f(a,z) = f(y,b) -> Z = b -> Y = a (liittäminen onnistuu kun Z=b ja Y = a) f(x) = g(x) -> no (kahden eri funktion liittäminen ei onnistu) Tarkastellaan seuraavaksi resoluution mekanismia Prologissa, ts. minkälaista hakustrategiaa käytetään johdettaessa tulosta. Resoluutiota sovelletaan täysin lineaarisesti siten, että maaleja korvataan vasemmalta oikealle ja tietokannan klausuuleja käydään läpi ylhäältä alaspäin. Alimaalit tarkastellaan välittömästi, kun ne on määrätty. Tällaista strategiaa sanotaan syvyyssuntaiseksi (depth-first). Palataan aiempaan esimerkkiin

esi_isa(x,y) :- vanhempi(x,z), esi_isa(z,y). esi_isa(x,x). vanhempi(nooa,haam). Olkoon annettu maali esi_isa(x,haam). Tällöin alimaalit muodostavat seuraavan hakupuun: Prolog palauttaa ensimmäisen vastaantulevan ratkaisun ja mikäli ratkaisuja halutaan lisää, puussa peräydytään (backtrack), kunnes löydetään uusia haaroja joita voidaan kulkea. Tämän kaltainen hakustrategia on tehokas, mutta kärsii samasta ongelmasta kuin rekursiivisesti laskeutuva jäsentäjä: säännöissä ei saa olla vasemmanpuoleista rekursiota. Jos ensimmäinen sääntö olisi kirjoitettu esi_isa(x,y) :- esi_isa(z,y), vanhempi(x,z).

Prolog joutuisi ikuiseen silmukkaan maalin johdossa yrittäessään toteuttaa lauseen esi_isa(z,y) soveltamalla toistuvasti ensimmäistä lausetta. Prologin peräytymismekanismia voidaan käyttää silmukoiden ja toistuvien hakujen toteuttamiseen, kunhan vain jotenkin pakotetaan etsinnän jatkaminen, vaikka ratkaisu löytyykin. Tätä varten Prologissa on predikaatti fail. Lisäksi haku voidaan katkaista operaattorilla!, joten ikuiset hakuprosessit voidaan ehkäistä. Tässä ei perehdytä näiden mekanismien yksityiskohtiin. Tarkastellaan vielä Prologin listarakenteita, jotka ovat Prolog-ohjelmoinnissa keskeisessä asemassa. Prologissa listaa merkitään hakasulkeilla, joiden sisällä ovat listan alkiot pilkulla erotettuna (esimerkiksi [a,b,c]), joten syntaksiltaan Prologin listat muistuttavat Haskellin listoja. Merkintä [] tarkoittaa tyhjää listaa. Prologissa ei ole listojen muodostamiseen ja purkamiseen erillisiä funktioita; sen sijaan kielessä käytetään merkintää [H T] tarkoittamaan listaa, jonka pää on H ja häntä T. Prologin listojen muodostamisen perusoperaatioita on append, joka liittää listoja yhteen, esimerkiksi?- Lista = [eka, toka, kolmas]. Lista = [eka, toka, kolmas].?- append($lista,[nelj],klista). Klista = [eka, toka, kolmas, nelj].

Prologin append-operaatiota voidaan soveltaa myös päättelemään, minkä listojen yhdistäminen antaa tuloslistan:?- append(x,y,$lista). X = [], Y = [eka, toka, kolmas]; X = [eka], Y = [toka, kolmas]; X = [eka, toka], Y = [kolmas]; X = [eka, toka, kolmas], Y = []; Esitetään vielä, miten listan kääntämisoperaatio voidaan toteuttaa Prologilla: kaanna([],[]). kaanna([h T],K) :- kaanna(t,k1),append(k1,[h],k). Tyhjän listan kääntäminen tuottaa tyhjän listan. Kun operaatiota sovelletaan epätyhjään listaan, käännetään ensin listan häntä, muodostetaan siitä lista K1 ja lisätään alkuun listan pää. Lopuksi käsitellään Prologin puutteita, jotka ainakin jossakin määrin koskevat yleisesti logiikkaohjelmointikieliä. Logiikkaohjelmointikielten piti alun perin muuttaa ohjelmointi spesifioinniksi ja vapauttaa ohjelmoija ratkaisun ohjelmoinnin yksityiskohdista. Tähän on pystytty vain osittain ja logiikkakielten päättelyissään käyttämät algoritmit ovat tuoneet omia ongelmia näillä kielillä ohjelmointiin. Esimerkiksi Prologin liittämisalgoritmi on itse asiassa epäkorrekti, tietyt määrittelyt johtavat sen ikuisiin silmukoihin (ks. [Lou], 11.5.1.). Prologissa on käytetty yksinkertaista ja tehokasta algoritmia, joka ei toimi oikein kaikissa erikoistapauksissa; tehokkaat ja korrektit algoritmit ovat huomattavasti monimutkaisempia. Looginen negaatio muodostuu ongelmalliseksi käsitteeksi logiikkakielissä niiden "suljetun maailman" oletuksen vuoksi. Logiikkakieli pitää väitettä vääränä, ellei sitä voida johtaa annetuista lauseista. Näin ollen väitteen negaatio on tosi, ellei väitettä

voida johtaa. Siten negaatio tarkoittaa pikemminkin epäonnistumista kuin loogista epätotuutta ja voi johtaa omalaatuisiin tuloksiin. Tietyssä mielessä myös logiikkaohjelmoinnin perimmäinen idea ratkaisun spesifioinnista sen tarkkojen yksityiskohtien ohjelmoimisen sijaan on ongelmallinen. Esimerkiksi lajitteluohjelman kirjoittaminen luonnollisimmalla tavalla johtaa listan kaikkien mahdollisten permutaatioiden generoimiseen, kunnes tavataan sellainen permutaatio, että lista on järjestyksessä. Tämä on luonnollisesti äärettömän tehoton tapa lajitella eikä sovellu käytännön ohjelmiin. Näin ollen ohjelmoijan on kuitenkin ohjelmoitava jokin konkreettinen lajittelualgoritmi, jolloin logiikkaohjelmointi lähestyy perinteisempiä ohjelmointimenetelmiä. (Prologilla voidaan kyllä esimerkiksi lajittelualgoritmeja kirjoittaa varsin näppärästi). Logiikkakielten pääasialliset sovelluskohteet liittyvät tekoälyyn tavalla tai toisella, kielissä on sovellettu mm. luonnollisen kielen käsittelyyn ja asiantuntijajärjestelmien toteuttamiseen. Tekoälysovellusten ulkopuolella logiikkaohjelmointikieliä on käytetty toistaiseksi varsin vähän, mutta relaatiotietokantojen käsittelyyn niitä on ainakin sovellettu. Lähteet [Har] Harsu, Maarit. Ohjelmointikielet, Periaatteet, käsitteet, valintaperusteet, Talentum 2005. [Kor] Kortelainen, Juha. Diskreetit rakenteet 811120P, Luentomoniste. (https://noppa.oulu.fi/noppa/kurssi/811120p/materiaali/811120p_luennot_2.pdf). [Lou] Louden, Kenneth C. Programming Languages, Principles and Practice, PWS-KENT 1993. [Seb] Sebesta, Robert W. Concepts of Programming Languages 10th edition, Pearson 2013.