Programmeerimine loogikas

Loogika on teadaolevatest (tõestest) faktidest õigete (tõeste) järelduste tegemise kunst. Juba Vana-Kreekas saadi aru, et tõeste järelduste saamine toimub kindlate reeglite (loogikareeglite) järgi: kui näiteks A on tõene ja on teada, et A-st järeldub B, siis ka B teab olema tõene. Selliseid reegleid on palju, kuid osutus, et kõigi tõeste järelduste saamiseks pole tarvis teada neid kõikki - piisab mõnest loogikareeglist ja oskusest moodustada elementaarseid (tõeseid) fakte.

Prologi programmid kirjeldavad tegelikkuse aspekte, loovad uurimispiirkonna (DoD, Domain of Discource) loogilise mudeli. Olgu meil tarvis näiteks luua mudel järgmisest osast Vana-Kreeka jumalate maailmast:

Jumal Uranosel on tütar Rhea ja
pojad Okeanos, Iapetos ja Kronos.
Kronosel on tütar Hera ja poeg Zeus;
Iapetosel on poeg Atlas."

Mudeli loomiseks peab määrama:
- uurimispiirkonna konstandid, muutumatud objektid; siin on nendeks jumalad Uranos, Okeanos, Iapetos, Kronos, Zeus, Rhea ja Hera;
- uurimispiirkonna objektide vahelised suhted; siin "(kellegi) poeg on (keegi)", "(kellegi) tütar on (keegi)".

Prologi "keeles", s.t. Prologi süntaksit kasutades tuleb konstandid kirjutada väikese algustähega - suur algustäht on Prologis muutuja tunnuseks. Suhteid kirjeldatakse Prologis predikaatidega ; suhtes olevad objektid (vanem-poeg, vanem-tütar) on predikaatide argumendid, seega kirjeldaks ülalesitatud uurimispiirkonda järgmine Prologi programm:

tytar_on(uranos,rhea).
tytar_on(kronos,hera).
poeg_on(uranos,okeanos).
poeg_on(uranos,iapetos).
poeg_on(uranos,kronos).
poeg_on(kronos,zeus).
poeg_on(iapetos,atlas).

Siin vanem-tütar, vanem-poeg suhted on kirjeldatud kasutades formaati (süntaksit)

tytar_on(Isa, Tütar).
poeg_on(Isa, Poeg).
s.t. tytar_on, poeg_on on mõlemad kahekohalised (kahe argumendiga) predikaadid, mille esimesel kohal (esimene argument) on isa ja teisel vastavalt tütre või poja nimi. Argumendid (isad, pojad, tütred) on konkreetsed isikud, s.t. konstandid, sellepärast tuleb nad kirjutada väikese tähega!

Kuid "terve mõistuse" järgi kehtivad ülalkirjeldatud uurimispiirkonnas veel mitmed suhted: kui näiteks kellelgi isikul Isa (muutuja - selle väärtuseks võib olla ükskõik milline uurimispiirkonna konstantidest) on poeg Poeg (taas muutuja, s.t. ükskõik milline uurimispiirkonna jumalatest) ja isikul Poeg on poeg Pojapoeg (taas muutuja), siis on isik Pojapoeg isiku Isa pojapoeg (suhe!). Seda suhet kirjeldab reegel

pojapoeg_on pojapoeg(Vanaisa,Pojapoeg) :-
poeg_on(Vanaisa,Isa),
poeg_on(Isa,Pojapoeg).

See reegel määrab uue suhte pojapoeg, kasutades varem määratud suhet poeg_on ja muutujaid Vanaisa, Pojapoeg, Isa; nende muutujate väärtusteks võivad olla uurimispiirkonna konstandid, s.t. isikud uranos, okeanos jne).

Kuidas suhteid kirjeldada - kas predikaadi nimeks valida poeg_on või lihtsalt poeg, kas esimene argument on isa ja teine poeg või vastupidi - see on programmeerija otsustada. Vigu tuleb vähem, kui järgitakse loomuliku keele(eesti, inglise jne) süntaksit, sest loomulikus keeles vastab meie maailmakirjeldus kõige meie ootustele, s.t. me saame sellest kõige paremini aru. Eesti keeles vastaksid ülaltoodud andmebaasi kirjetele laused "Uranose tütar on Rhea", "Uranose poeg on Okeanos" jne. See ongi tavaliselt loomuliku keele lausetest predikaatide moodustamisel kõige loomulikum vorm: lause õeldis (õeldisrühm) muutub predikaadiks, alus ja sihitis - predikaadi argumentideks (selles järjekorras).

Kord valitud süntaksit peab igal pool rangelt jälgima, s.t. kui isa-poeg suhted on kirjeldatud predikaadiga poeg_on (nagu ülal), ei oska Prolog kasutada reeglit

pojapoeg(Vanaisa,Pojapoeg) :-
poeg(Vanaisa,Isa),
poeg(Isa,Pojapoeg).

See reegel muutub Prologile arusaadavaks alles siis, kui programmi on lisatud veel üks reegel (selle võib lisada ükskõik kuhu, erinevate predikaatide kirjelduste järjekord programmis ei ole oluline; oluline on sama predikaati kirjeldavate lausete järjekord):

poeg(Isa,Poeg) :-
poeg_on(Isa,Poeg).

Samuti peab jälgima, et kord valitud predikaadi formaati (näiteks et predikaadis poeg_on esimene argument on isa, teine - poeg) kasutatakse kõikjal sama moodi (ei või sisestada fakte poeg_on, kus esimene argument on poeg ja teine - isa; sellest tekivad väga raskesti avastatavad vead). Ja sarnaseid fakte kirjeldatatakse alati sama predikaadiga, s.t. samas programmis ei või kasutada koos "ülalt-alla" predikaate poeg_on, tytar_on ja "alt-üles" predikaate isa_on, ema_on - siis tekivad väga kergesti loogilised vead - mõnda fakti on kirjeldatud kaks korda (erinevate predikaatidega) ja mõnda pole üldse kirjeldatud, ja reeglite kirjeldamine muutub väga keeruliseks. Korrektses (ükskõik millises keeles!) kirjeldatud programmis või andmebaasitabelis kirjeldatakse iga fakti vaid kord (infot ei dubleerita!) ja sarnaseid fakte kirjeldatakse alati sama formaati kasutades.


Ülesandeid:
1. Sademed on kirjeldatud lausetega (väga halb kirjeldus!!!):
sademed:-
vihm.
sademed :-
lumesadu.
lumesadu :-
sademed,
alla_nulli.
lumesadu.
vihm :-
sademed, not(alla_nulli).

Millised vastused saadakse päringutele:

?- alla_nulli.
?- not(alla_nulli).
?- sademed.
?- lumesadu.
2. Kirjelda ülikooli teaduskondade, instituutide, õppetoolida ja õppingurühmade ja nendesse kuuluvate üliõpilaste vahelised suhted. Kas see struktuur on hierarhiline?


Küsimused, probleemid: ©2004 Jaak Henno