Ifi6057lab3
Ülesanne
Viimases ülesandes tuleb kirjutada Prologis programm, mis oskaks mängida laevade pommitamist. Täpsemalt mängib programm ainult ühte poolt mängust: pakub välja koordinaadid, kuhu järgmisena pommitada ning võtab teadmiseks, kas tegu oli möödalasu, tabamuse või koguni laeva põhja laskmisega. Sellisel viisil kogutud infot kasutab programm siis järgmiste käikude "välja mõtlemiseks". Programmil endal oma laevu pole.

Mängu reeglid on klassikalisest laevade pommitamisest natuke erinevad:
- mängitakse 5x5 ruudustikul
- koordinaadid on mõlemal küljel 1-st 5-ni
- pole täpselt teada, mitu ja kui suurt laeva ruudustikul on. Õppejõud kasutab testimisel max 4 ruudu pikkust laeva
- laevad on sirged ja ei puutu külgi ega nurki pidi kokku
Oluline on, et programm suudaks lõpuks kõik laevad põhja lasta. Maksimaalselt kulub selleks 25 käiku. Et aga paremat hinnet saada, võiks programm üritada ka natuke kavalamalt tegutseda - tabamuste ja põhja minekute alusel on võimalik järeldusi teha, kuhu on eelkõige mõtet järgmist rünnakut suunata. Mida vähema käikude arvuga keskmiselt programm kõik laevad põhja saab, seda parem.
Selleks kasutame Prologi kui teadmusbaasi: paneme sinna sisse reeglid, mille järgi programm oskab järgmist käiku välja mõtelda. Uusi teadmisi paneme sisse asserta/1 või assertz/1 predikaatidega.
Kustutada saab retract/1 või retractall/1 predikaatidega.
See ei ole väga klassikaline ja ilus viis Prologi kasutada, aga see eest on väga lähedane teadmusbaasil põhineva agendi ideele (vt. 8. loengu slaide).
Ülesande tähtaeg (emailiga priit at whitedb.org) on 1. detsembril. Ärge unustage ka kaitsma tulla, eriti kuna selleks on piiratud võimalused (2. detsembri ja 9. detsembri harjutustunnid). Alati on võimalik ka enne tähtaega kaitsta.
Nõuded
Et üliõpilaste programme saaks automatiseeritult testida, peab neil TÄPSELT selline liides olema tehtud, nagu allpool kirjeldatud:
Näide interaktsioonist
Punktid
Kodutöö arvesse minekuks piisab kui teha elementaarne versioon, mis suudab kõiki ruute pommitada, nii et kõik laevad garanteeritult põhjas on lõpuks. Selle jaoks on eelkõige vaja pusida Prologi süntaksi ja tõenäoliselt mitte päris harjumuspärase lähenemisega, seetõttu annab sellise kodutöö esitamine kohe 12 punkti. Programm ise on triviaalne ja selle saab teha paari-kolme reegliga (lisaks kohustuslikele liidese predikaatidele).
Et rohkem punkte saada, võiks hakata ka mingit strateegiat proovima realiseerida. Kui mingisugunegi toimiv loogika on tehtud, mis suudab pommitamist efektiivsemaks teha, tõuseb töö hinne 18 punkti peale.
Lõpuks, kõik kodutööd, eeldusel et neil on nõuetekohane liides, läbivad õppejõu poolt automaatse testimise, mis leiab keskmise käikude arvu ~100 juhuslikult genereeritud laevastiku põhja laskmiseks. Kõige parema tulemusega grupp saab 3 boonuspunkti, teine tulemus 2 punkti ja klassi peale kolmas tulemus 1 boonuspunkti. Neid boonuspunkte jagatakse küll ainult gruppidele, kes on mingi pommitamise strateegia ehitanud.
Abiks
- http://learnprolognow.org
- vaata inspiratsiooniks kollimaailma näidet loengust
- lihtsaid katsetusi saab teha veebis, ilma midagi installimata: SWISH. Teadmusbaasiga toimetamise jaoks see versioon ei sobi.
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 (elementaarse versiooni saab kindlasti ilma teha, aga keerulisemate asjade juures võib kasuks tulla):
% 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 lihtsam olla teksti välja trükkida:
% siia näide
Cut
% näide