Iti0210lab8: erinevus redaktsioonide vahel

Allikas: Lambda
Mine navigeerimisribale Mine otsikasti
PriitJ (arutelu | kaastöö)
Resümee puudub
PriitJ (arutelu | kaastöö)
 
(ei näidata sama kasutaja 8 vahepealset redaktsiooni)
1. rida: 1. rida:
= Teadmusbaas Prologis =
= Teadmusbaas Prologis =


== Sissejuhatus ==
== Ülesanne ==


[[Image:Ifi6057lab81.png|150px|right|kollimaailm]]
Lahenda PROLOG-i abil:


Proovime Prologis teha teadmusbaasi, mis võimaldab teha järeldusi kollimaailma kohta. Kollimaailm on kirjeldatud õpikus [''AIMA''] 7.2.
<pre>
 
Marcus on mees.
Teadmusbaas peaks koosnema kahest osast:
Marcus on Pompej elanik.
 
Marcus sündis aastal 40.
* reeglid, mis kirjeldavad, kuidas kollimaailm töötab
Kõik mehed on surelikud.
* faktid, mis kirjeldavad, mida kollimaailmas tegutsev agent seni teinud ja kogenud on
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?
</pre>


Ehk siis vaatame mingit kindlat ajahetke nagu näiteks joonisel:
Proovi teadmus edasi anda lihtsate faktide ja reeglitena. Tegu on teadmuse esituse, mitte programmeerimisülesandega.


[[Image:Ifi6057lab82.png|150px|kolliolek]]
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.


Teeme järeldusi selle ajahetke kohta. Minimaalselt peaks saama järeldada, kas mingi ruut on turvaline, järgmine samm oleks järeldada, mis on õige järgmine käik.
Märkus: aasta 40 on 1. sajandil, mitte lühend aastast 1940 20. sajandil :-)


Eesmärgiks on teha midagi, mis vastab teadmusbaasi arhitektuurile: <code>reeglid + faktid => järeldused</code>. Tee nii palju kui suudad! Siin ülesanded pole "valmis" olemise kriteeriumi.
Täienda eelnevat teadmist antud uute faktidega ja proovi lahendada:
 
Toimivat kollimaailma mängu või simulatsiooni pole tarvis teha. Samas, kui see teeb lahendamise huvitavamaks, on see muidugi lubatud.
 
== Reeglid ja faktid ==
 
Kollimaailma reeglid, mida oleks minimaalselt vaja:


<pre>
<pre>
Squares adjacent to wumpus are smelly
Jaan on mees.
Squares adjacent to pit are breezy
Jaan sündis aastal 1977.
Glitter iff gold is in the same square
Kas Jaan on surnud?
</pre>
</pre>
Eeldatud on, et liikumine samasse ruutu, kus on auk või koll lõpeb agendi jaoks halvasti. Lisaks arvesta, et kolle (''wumpus'') on ainult üks, aukude arv pole määratud. Ülesande lahendamise lihtsustamiseks võib esialgu tegeleda ainult ühe ohuga, näiteks aukudega.
Lisareeglid, mis pole tingimata turvalisuse järeldamiseks vajalikud:


<pre>
<pre>
Shooting kills wumpus if you are facing it
Francesco on Pompej elanik.
Shooting uses up the only arrow
Francesco sündis aastal 1989.
Grabbing picks up gold if in same square
Kas Francesco on surnud?
Releasing drops the gold in same square
</pre>
</pre>


Kasuta fakte, mida agent ise teab või on kogenud:
== Aruanne ==
* kus agent on viibinud
* kus oli tuuletõmbus (''breeze'')
* kus oli hais (''stench'')


== Turvalisuse ja käigu küsimine ==
Selle ülesande puhul pole PDF kujul aruannet tarvis esitada. Esita moodles ainult oma Prologi kood.
 
Näide, kuidas teadmusbaasist pärimine võiks välja näha:
 
<pre>
?- safe(2, 2).
no.
 
?- nextmove(X).
X = up.
</pre>
 
Enda lahenduses ei pea samamoodi tegema. Katseta järeldamist erinevate seisude pealt, ehk siis muuda fakte ja vaata, kas järeldused muutuvad vastavalt.


== Abiks ==
== Abiks ==


* http://learnprolognow.org
* http://learnprolognow.org
* [http://www.amzi.com/AdventureInProlog/a1start.php Adventure in Prolog]
* Lihtsaid katsetusi saab teha veebis, ilma midagi installimata: [http://swish.swi-prolog.org/ SWISH].  
* Lihtsaid katsetusi saab teha veebis, ilma midagi installimata: [http://swish.swi-prolog.org/ SWISH].  
* Arvutiklassis on olemas SWI-Prolog. Linuxi jaoks soovitaks GNU Prologi, mis on antud ülesande jaoks täiesti piisav.
* 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.
* 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:
Mõned lihtsamad reeglid:
121. rida: 99. rida:
   alive(mccartney).
   alive(mccartney).


Kui mingit asja tahetakse dünaamiliselt modifitseerida, siis tuleb seda Prologile ette deklareerida.
Aritmeetika:
 
  :- dynamic(person/1).
 
Peale seda query <code>?- retract(person(sokrates)).</code> õnnestub.
 
Kui mingi predikaat on dünaamiline, siis saab selle kohta ka reegleid teha, ilma et predikaat ise oleks defineeritud. Alljärgnev on OK, isegi kui <code>breeze</code> fakte Prologi andmebaasis ei leidu:
 
  :- dynamic(breeze/1).
  agentpos(1, 1, 1).  % agent asus ajahetkel 1 kohal 1, 1
  breezy(X, Y):-        % koordinaat X, Y on tuuline, kui
    agentpos(X, Y, T),  % agent on kohal X, Y ajahetkel T ja
    breeze(T).          % agent tajub tuuletõmmet ajahetkel T
 
Alakriips on anonüümne muutuja (meid ei huvita, mis ta väärtus on):


   visited(X, Y) :-
   increment(X, Y):-
     agentpos(X, Y, _). % agendi positsioon mingil suvalisel ajahetkel oli X, Y
     X is Y + 1.


Tuleb tähelepanelik olla, mis on tundmatud muutujad ja mis on teadmusbaasist tuletatavad.
Proovi <code>?- increment(X, 2).</code> jne.


  nopit(X, Y) :-              % saab küsida nopit(X, Y).
[[Category:Iti0210]]
    visited(L, Y),
    X is L + 1,              % kui X on tundmatu, siis arvutatakse ta visited(L, Y) abil leitud L-ist
    \+ breezy(L, Y).
 
  nopit_katki(X, Y) :-        % nopit_katki(X, Y) annab vea. Suudab ainult kontollida väiteid nagu nopit_katki(1,2).
    visited(L, Y),
    L is X - 1,              % kui X on tundmatu, siis Prolog L-i väärtust kontrollida ei oska :-(
    \+ breezy(L, Y).

Viimane redaktsioon: 16. märts 2021, kell 09:26

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.