Iti0210lab8
Teadmusbaas Prologis
Ülesanne
Lahenda PROLOG-i abil:
Marcus on mees. Marcus on Pompej elanik. Marcus sündis aastal 40. Kõik mehed on surelikud. Kõik Pompej elanikud surid vulkaanipurske tagajärjel aastal 79. Ükski surelik ei ela rohkem kui 150 aastat. Praegu on aasta 2019. Kas Marcus on elus?
Proovi teadmus edasi anda lihtsate faktide ja reeglitena. Tegu on teadmuse esituse, mitte programmeerimisülesandega.
Lihtsustus: antud faktide pealt on natuke mugavam teha päringut, kas Marcus on surnud või mitte. Sellest võib juba ilma PROLOG-ita järeldada, kas ta on elus.
Märkus: aasta 40 on 1. sajandil, mitte lühend aastast 1940 20. sajandil :-)
Täienda eelnevat teadmist antud uute faktidega ja proovi lahendada:
Jaan on mees. Jaan sündis aastal 1977. Kas Jaan on surnud?
Francesco on Pompej elanik. Francesco sündis aastal 1989. Kas Francesco on surnud?
Aruanne
Selle ülesande puhul pole PDF kujul aruannet tarvis esitada. Esita moodles ainult oma Prologi kood.
Abiks
- http://learnprolognow.org
- Lihtsaid katsetusi saab teha veebis, ilma midagi installimata: SWISH.
- Arvutiklassis on olemas SWI-Prolog. Linuxi jaoks soovitaks GNU Prologi, mis on antud ülesande jaoks täiesti piisav.
- SWI-Prologis pane faililaiendiks ".pl". Siis käsitleb SWI-Prolog seda kui Prologi koodi, muidu võivad menüüdest vajalikud asjad puudu olla.
Siin osas olevad Prologi näited on lihtsalt süntaksi näited, mitte vihjed õige lahenduse suunas
Mõned lihtsamad reeglid:
person(sokrates). % Sokrates on inimene mortal(X):- % kõik inimesed on surelikud person(X). mortal(X):- % teine reegel surelikkuse kohta. Prolog vaatab ükshaaval kõiki reegleid dead(X). dead(platon). % veel üks fakt
Kui me teeme päringu ?- mortal(platon).
või ?- mortal(sokrates).
, siis mõlemale saame vastuseks "yes" (või midagi analoogset, sõltuvalt Prologi versioonist). ?- dead(sokrates).
annab aga vastuse "no", kuna selle kohta otsest fakti, ega ka sobivat reeglit ei eksisteeri.
Rekursiivne reegel:
% faktid parent(john,paul). % paul on johni vanem parent(paul,tom). % tom on pauli vanem parent(tom,mary). % mary on tomi vanem % reegel: esivanema leidmine ancestor(X,Y):- % baasjuhtum. Kui Y on X otsene vanem, siis ta ongi kohe esivanem parent(X,Y). ancestor(X,Y):- % rekursiivne reegel parent(X,Z), % Valime mingi Z-i, kes on X-i vanem ja vaatame, kas temale ancestor(Z,Y). % on võimalik rekursiivselt esivanemat leida. Z esivanem on ka X esivanem.
Prologis on küll sisse ehitatud debugger, aga esialgu võib vigade otsimise jaoks lihtsam olla teksti välja trükkida. See näeb välja protseduurilise programmeerimise moodi, aga write/1
ja nl/0
on lihtsalt loogikapredikaadid, mille väärtus on alati true
.
mortal(X):- write('kas X on inimene?'), nl, person(X). mortal(X):- write('kas X on surnud?'), nl, dead(X).
Cut ("!") on kasulik, kui tahetakse otsingut varakult lõpetada. Näiteks, kui ma teen eelnevate näidete puhul
päringu ?- mortal(X).
, pakutakse mulle nii Sokratest, kui Platonit. Kui ma tean ette, et mind huvitab ainult üks vastus, siis ma võin teha nii:
existmortal(X):- mortal(X), !. % Kui Prolog ühe sobiva X väärtuse on leidnud ja siia kohta jõudnud % siis ta rohkem enam ei proovi.
Eituse jaoks on sümbol "\+" (siin on pikem seletus):
deceased(X):- mortal(X), \+ alive(X). mortal(mccartney). mortal(lennon). alive(mccartney).
Aritmeetika:
increment(X, Y):- X is Y + 1.
Proovi ?- increment(X, 2).
jne.