Looginen ohjelmointi tarkoittaa matemaattisen logiikan käyttöä tietokoneohjelmien kirjoittamisessa. Se on deklaratiivinen ohjelmointiparadigma: ohjelmoija kuvaa, mitä tietojen pitäisi olla ja mitä halutaan johtaa, sen sijaan että kuvailtaisiin vaiheittain, miten asia lasketaan. On olemassa erikoistuneita ohjelmointikieliä, joilla käyttäjä voi syöttää suoraan loogisia lausekkeita. Luultavasti tunnetuin näistä kielistä on nimeltään Prolog, joka perustuu predikaattilogiikan esiintuomiseen ja takaausjäljitykseen perustuviin hakumenetelmiin. Alonzo Church käytti logiikkaohjelmoinnin muotoa, joka tunnetaan nykyään lambdalaskennana. Lambdalaskenta on laskennan teorian keskeinen malli ja on merkittävä erityisesti funktionaalisen ohjelmoinnin perustana. Loogista ohjelmointia on käytetty myös LISP:ssä — esimerkiksi varhaistutkimuksessa ja prototyyppijärjestelmissä, tai yhdistämällä logiikkaa Lispin tapaisiin kieliin.

Looginen ohjelma koostuu yleensä joukosta tosiasioita (facts) ja sääntöjä (rules). Tosiasiat kuvaavat maailmasta suoria väitteitä, säännöt määrittelevät johtamissuhteita lausekkeiden välillä. Ohjelman käyttäjä esittää järjestelmälle kyselyjä (queries), ja järjestelmä yrittää johtaa kyselyn todeksi tosiasioiden ja sääntöjen perusteella.

Peruskäsitteet

  • Predikaatit ja termit: predikaatit kuvaavat ominaisuuksia tai suhteita, termit ovat muuttujia, symboleja ja funktioita.
  • Unifikaatio: laskentamenetelmä, jolla tarkistetaan, voiko kaksi termiä tehdä yhteneviksi asettamalla muuttujille arvoja.
  • Takaisinjälitys (backtracking): automaattinen hakumenetelmä, jossa järjestelmä kokeilee vaihtoehtoja ja palaa aikaisempaan tilaan epäonnistuttuaan, kunnes sopiva ratkaisu löytyy tai vaihtoehdot loppuvat.
  • Resoluutioperiaate ja SLD-päättely: yleinen johtamistekniikka Prolog-tyyppisissä järjestelmissä, joka yhdistää unifikaation ja takaisinjälityksen.
  • Negaatio epäonnistumisena (negation as failure): käytännön tapa käsitellä negaatiota: jos lauseketta p ei voida johtaa, oletetaan että ¬p on tosi. Tämä vastaakin usein niin kutsuttua suljetun maailman oletusta (closed-world assumption), mutta ei ole sama kuin klassinen looginen negaatio.

Miten Prolog toimii käytännössä

Prologissa ehdot ilmaistaan muotoon "päämäärä :- ehto1, ehto2, ...". Kun käyttäjä esittää kyselyn, Prolog etsii säännöistä ja tosiasioista sopivan johtamispolun käyttäen unifikaatiota ja takaisinjälitystä. Muuttujat alkavat yleensä isolla kirjaimella, atomit pienellä. Esimerkiksi:

 parent(maria, joel). parent(joel, anna).  grandparent(X, Z) :- parent(X, Y), parent(Y, Z). 

Kun esitetään kysely ?- grandparent(maria, anna)., järjestelmä yhdistää säännön ehdot tosiasioihin ja johtaa kyselyn todeksi.

Negaatio epäonnistumisena

Useimmissa käytännön loogisen ohjelmoinnin järjestelmissä käytetään niin sanottua negaatiota epäonnistumisena tai heikkoa negaatiota: Tämä tarkoittaa sitä, että jos jotakin lauseketta p {\displaystyle p} {\displaystyle p}ei ole mahdollista johtaa tosiasioista ja säännöistä, järjestelmä olettaa, että sen negaatio on tosi. Tämä toimii monissa käytännön sovelluksissa, mutta voi johtaa virheellisiin johtopäätöksiin, jos tietokanta on epätäydellinen. Klassinen looginen negaatio edellyttäisi täydellisempää tietoa tai erityisiä formaaleja laajennuksia (esim. oletus- tai ei-monotoneja semantiikoita), joita Prologin tavallinen negation-as-failure ei tarjoa.

Sovellukset ja laajennukset

  • Asiantuntijajärjestelmät ja tietämysperusteiset järjestelmät
  • Luonnollisen kielen käsittely (symbolinen tulkinta, parsinta)
  • Tietokannoissa ja sääntöpohjaisissa järjestelmissä käytettävät kysely- ja johtamismekanismit
  • Rajoituksiin perustuva ohjelmointi (Constraint Logic Programming, CLP) yhdistää logiikkaa ja optimointia
  • Answer Set Programming (ASP) tarjoaa vahvempia, ei-monotoneja semantiikkoja ja käsittelee monimutkaisempaa ei-determinismiä

Vahvuudet ja rajoitukset

Looginen ohjelmointi tekee monimutkaisten suhteiden ja sääntöjen ilmaisemisesta luettavaa ja lähellä ihmisen kuvaamaa tietoa. Se soveltuu hyvin symboliseen päättelyyn ja tietämyspohjaisiin sovelluksiin. Rajoituksiin kuuluu suorituskyky haastavissa numeerisissa laskelmissa ja se, että negation as failure perustuu usein suljetun maailman oletukseen, mikä ei aina vastaa todellista tietämystä. Monissa tapauksissa tarvitaan laajennuksia tai erilaisia semantiikkoja (esim. ASP tai CLP) ongelman luonteen mukaan.

Tuotannot ja työkalut

Tunnettuja Prolog-implementaatioita ovat esimerkiksi SWI-Prolog, GNU Prolog ja SICStus Prolog. Niissä on usein laajoja kirjastoja I/O:lle, tietokantaintegraatioille ja rajoiteohjelmoinnille.

Yhteenvetona: looginen ohjelmointi tarjoaa deklaratiivisen tavan ilmaista tietoa ja johtamissääntöjä. Prologin kaltaiset kielet perustuvat unifikaatioon, resoluutioon ja takaisinjälitykseen, ja ne ovat erityisen hyödyllisiä symbolisessa päättelyssä ja tietämysintensiivisissä sovelluksissa. Kuitenkin käytännössä tarvitaan huolellinen ymmärrys negaatioon, avoimen/suljetun maailman oletuksiin ja mahdollisiin laajennuksiin, jotta järjestelmä toimii luotettavasti halutussa käyttötarkoituksessa.