From bbs@floyd.upol.czMon Jan 29 16:34:43 1996 Date: Mon, 29 Jan 1996 16:27:49 +0100 From: BBS Floyd To: hubicka@limax.paru.cas.cz Subject: Skolicka #13-prolog (fwd) *** Forwarded file follows *** Posted By: kotelnik (kotelnik) on 'Linux' Title: Skolicka #13-prolog Date: Tue Jan 16 16:08:37 1996 Tak pisu neco o prologu..Je to jeden z mych nejoblibenejsich jazyku nejen proto, ze je jednodychy a vykony ale hlavne proto ze je to prvni jazyk, co znam, co ma ksichtiky :- ve zdrojacich. Kouknete se na prologacky zdrojak a plesate. Take to je jazyk co neni ani strukturovany ani objektovy a ma scela novy pristup k veci, ktery se nazyva logic programing. To je moc pekny styl, ktery je lidskemu uvazovani mnohem blizsi a proto clovek, ktery si hraje z prologem je strasne tvorivy a dela ruzne zajimave objevy-kdyz pisete program normale vetsinou presne vite co bude delat ale tady to casto tak jiste neni a prolog vas tim casto prijeme prekvapi. Toto o tom pisou autori: Prolog is a simple but powerful programming language developed at the University of Marseilles [Roussel 75], as a practical tool for programming in logic [Kowalski 74] [van Emden 75] [Colmerauer 75]. >From a user's point of view the major attraction of the language is ease of programming. Clear, readable, concise programs can be written quickly with few errors. (nezni to pekne?) Rozhodl jsem se pro zmenu nezacit teorii ale jit hned na vec. Napisem takovou malou adventurku, kde by clovek mohl chodit a neco delat. Proste hru minimalne urovne pomsty sileneho ataristy. Na ni bych chtel ukazat vyhody tohoto noveho pristupu. Nepokousejte se zatim nic do prologu busit jenom se zamyslete, co vsechno nam tento postup usetril. (jeji kompletni zdrojaky ,ukazku funkcnosti a popis co jsme vlastne delali pridam na konec.) Bludiste ======== Kazda textovka obsahuje bludiste. V nem se da nejak pohybovat z mista na misto bud pomoci S J V Z nebo tim, ze napisete kam chcete jit. K tomu potrebujete celkem slozitou datovou strukturu. Je treba aby kazda mistnost mela neco jako: popis seznam predmetu seznam dalsich mistnosti, kam se da jit. Kdybyste to delali v cecku vypadalo by to asi takto: struct mistnost { char *name struct predmet *predmety[MAXPREDMET]; struct mistnost *dalsi[MAXMISTNOST]; } No a ted si prestavte to dynamicky alokovani, nacitani z datovyho fajlu, implementaci funkce jdi, ktera musi cely listing dalsi prohledat a porovnat. Navrh struktury datovyho fajlu-jak budete delat ukazatele kdyby fajl vypadal treba jako: Mistnost:Zachod Popis:Jsi na zachode...Muzes jit na chodbu nebo oknem ven na zahradu Predmety:Papir Cesty:chodba,zahrada A ted to nacist..vyznat se v nem,kdyz nactete cesty:chodba musite si to napred pamatovat jako string a teprve casem-az bude cela databaze v pameti bude mozne nahradit slova ukazatelama-tudiz musite pridat dalsi kolomky do struktury misnost, ktere budou bezne nepouzity. A cely dohromady by to stalo za nic protoze: byl by omezeny pocet predmetu v mistnosti-bud by program hlasil neco jako ze mistnost je plna nebo by proste zbombil byl by omezeny pocet cest-to by vadilo jen navrharum bludiste. U velkych bludisti by nacitani pravdepodobne nebylo nejrychlejsi Bylo by tu umezeni delky radky protoze by jste urcite volali nejakou funkci na cteni ze stringu ktera by to ukladala do STATICKYHO pole. A dalsi problemy V lispu by to slo udelat trochu lepe. Proste byste si udelali strukturu z tema trema polozkama. Cesty i predmety by byly ulozeny jako listy symbolu-takze zadne omezeni na velikost. A vyhledavani by bylo pomoci member. Na pridavani novych cest,predmetu,popisu k mistnosti byste si udelali funkci, ktera by automaticky mistnost zalozila. Ta by byla ulozena v promeny co by se jmenovala stejne jako mistnost takze i ukazatele by byly bez potizi. Fajl z hracim planem by byl v souboru, co by se v includil a co by volal neco jako (location "papir" "zachod") (connect "zachod" "zahrada") (description "zachod" "Jsi na zachode...Muzes jit na chodbu nebo \ oknem ven na zahradu") A bylo by to relativne jednoduche a eleganti a bez omezeni(snad mimo tluceni se jmen mistnosti z funkcema-musely by se pravdepodobne nazvy delat stylu room-) O to by se uz starala nejaka funkce ktera by se volala nejak: (roomsymbol "blbec") => ROOM_BLBEC To je uz lepsi..Ale jak by to delal prolog? Proste nijak. Jednoduse byste mu napsali: |: location(papir,zachod). |: connect(zachod,zahrada). |: connect(zachod,chodba). A protoze cesta chodba->zachod je dvousmerna: |: connect(chodba,zachod). A mate to! bludiste je v pameti! Jak rychle jak efektivne a skvrna od tresni je pryc! A hned se muzete dotazovat.. ?- location(papir,X). X=zachod ?- connect(zachod,X). X=zahrada X=chodba No monkey island to jeste neni ale pametove ulozeni mame a po dvou minutach! Omezeni jsou tu nulovy..format vstupniho fajlu je taky slusny..detekce syntatickych chyb automaticka(interpretrem). Prikaz jdi ========== Implementaci prikazu jdi jsme se uz zabyvali..v cecku smyckou co by prosla vsechny moznosti a porovnala pomoci strcmp a zmenila ukazatel aktualni pozice. V lispu pomoci funkce nejak jako: (let (a (member (roomsymbol mistnost) (mistnost-cesta you)) ( (if (eq a nil) (print "tam jit nemuzes") (setq you (car a)))) (nejsem si zcela jist jestli je spravne..kdyz ne tak me omluvte) a v prologu takto: jdi(X) :- %funkce na chozeni you(L), %do L ulozi vasi pozici connect(L,X),%zjisti jestli vede cesta z L do X-zde muze provadeni selhat retract(you(L)), %Zrusi spojeni ze starou mistnosti assert(you(X)). %Zavede do databaze novou asociaci-you a nova mistnost jdi(X):- %V pripade ze cesta nevede-prvni jdi selhalo write(' Tam to nejde. '),nl. Tomu uz asi moc nerozumite..ale verte ze to je zcela jednoducha konstrukce. Udalosti ======== Je treba aby se ve hre mohlo take neco dit. To je jeden z neprekonatelnych problemu v cecku-vsechno se vetsinou pise rovnou do kodu a je to pak prasarna. V prologu se to dela asi takto: smrt :- you(L), retract(you(L)), assert(you(nebe)). akce :- location(papir,zahrada), retract(location(papir,zahrada)), write(' Vrhla se na tebe diva duchodkyne z holi a utloukla te ze slovy'),nl, write(' Takhle znecistovat zivotni prostredi! Kam se ten svet riti! '), smrt, akce. akce :- nl. Tato akce zjisti jestli je papir na zahrade,vynada vam a pomoci jednoducheho predikatu smrt vas presune do nebe. Nakonec se rekurzivne zavola to je pro situaci kdyby takovych akci bylo v programu vic. A ted staci pridat par jednoduchych prikazu a nejkay user interface A monkey island II je na svete! Nebylo to snadny? Tady je videt rozdil mezi strukturovanym a logickym programovanim. Nerikam ze se prolog hodi na vsechno ale na neco je strasne sikovnej=jen se kouknete kolik nam to usetrilo prace! Jak nas to nutilo udelat ten program pekny, citelny snadno rozsiritelny. Jak jsou reseni v prologu elegantni, jednoducha....kolik to usetrilo prace. ============================================================================= A tvrde na vec ============== (ted je cas nastartovat prolog prikazem pl-distribuci najdete na kazdem mirroru slakwaru v adresari devel/lang/prolog/swi) Co jsme vlastne psali? Atomy ===== Stejne jako lisp ma i prolog atomicky typy.. To jsou cisla: 555 -555 2`1110 je ve dvojkove soustave 6`1323 je v sestkove konstanty: To jsou bezna slova zacinajici na male pismeno,symboly jako !@#$%^&_ a fura dalsich veci. Promene: To jsou retezce zacinajici na velke pismeno:Blbec,AA,X,_AAA Atomy v lispu se jmenujou termy Strukturovane typy ================== Jako lisp stavi vsechno na consu ma i prolog svuj zakladni strukturovany typ. ten se zapisuje: predikat(parametry) tedy treba: blbec(x,y) To vytvori jakesi spojeni mezi symboly. Da se pomoci toho moc pekne delat ruzne diagramy(treba bludiste v nasi hre) Nebo asociativni site: barva(medved,cerveny) a potom se muzete ptat jakou barvu ma medved. Da se i retezit: s(np(john),vp(v(likes),np(mary)) Vytvori takove spojeni: s / \ np vp | / \ john likes mary Z nasi hry znate: location(papir,zachod) (abyste mohli zadavat clausy ze vstupu musite napsat [user]. - prompt se zmeni na |: a muzete je zadat. po ctrl+d se zase dostanete zpet Je tu ale problem protoze po kazdem zadani [user] se stare vazby zrusi. Proto je lepsi priklady zapisovat do fajlu a potom [fajl] je nahrat do interpretru obsah fajlu z priklady dam na konec) nebylo volani funkce, ktera by naplnila nejakou strukturu ale jednoduse si prolog zapamatoval neco takoveho: papir | ma location | v zachod (Takhle se casto zakresluji clausy z dvema parametrama-u tri uz kresleni drhne) Kdybychom napsali: umisteni(papir,wc) rozsirili bychom jeho tabulku na: papir | | location umisteni | | v v zachod wc To prvni slovo je (location,umisteni) je predikat. Zbyle jsou jeho parametry. Trochu to pripomina volani funkce. Muzou byt predikaty bez parametru: smrt. nebo z jednim: barva(zelena). barva(cervena). zelena<-----barva---->cervena a i vice. To se uz celkem spatne maluje do site. Takovymto jednoduchym zpusebem muzeme vystavet libovolnou asociativni sit. Cely program v prologu je do teto site zabudavan tak, ze muzeme udelat asociace, ktere se nevi predem, ale musi se vyvolat nejaky dalsi kod ktery urci jestli spojeni existuje nebo ne. Vytvareni takovych asociaci popisu pozdeji. Cely prologacky program je tedy soubor pravidel, jak neco ma vypadat a prolog se snazi jim vyhovet. Bezne pouzivane konstrukce v prologu jsou listy: . / \ 1 . / \ 2 . / \ 3 [] Tato konctrukce ma zapis: .(1,.(2,.(3,[]))) SAmozdrejme ze existuje i pohlednejsi zapis [1,2,3] A konstrukce: . / \ a . / \ b L jde zapsat [a,b|L] Stringy jsou listy integeru z ascikodama. otazky(direktivy): =================== pomoci ctrl+d se dostanete zpet do otazkoveho modu(prompt je ?-) a muzete se dotazovat na databazi-odpalit to co jste vytvorili: ?- System potom zacne prochazet celou databazi z pokousi se najit dotazovane zpojeni. Muzeme tedy zadat ?- connect(zachod,zahrada). A system odpovi yes protoze spojeni existuje. Jde tu ale jedna moc zajimava vec: ?- connect(zachod,X). System zjisti ze X je promena..pokusi se proto v databazi najit nejakou dobrou hodnotu prot promenou. Mame zpojeni mezi zachodem a zahradou napise tedy: X = zahrada a ceka. Pokud zmacknete enter system usoudi ze nasel zpravne a promenou tak nastavi-v dalsi otazce uz bude X vzdycky jenou zahrada. Ale kdyz zmacknete ; system bude hledat dal..a najde jeste jedno spojeni na chodbu a opet se zepta. Kdyz znova zmacknete strednik nic nenajde a napise no.(Pri experimentech je dobre vzdycky mackat stednik protoze jinak se promena na neco nastavi a vy si musite vyprat nejake jine pismeno pro dalsi testovani) Muzeme pouzivat i predikaty ktere jsme nezadali: ?- member(b,[a,b,c]). [a,b,c] je list. Member se pta jestli b je jeho prvkem. System tedy odpovi: yes Toto je priklad vyvolavani predikatu a dotazovani se na asociaci, ktera se predem nevi-system nema u vsech prvku listu asociaci member ale member je nejaky kus kodu, co to urci. Tedy neco jako funkce, ktera vraci boolean. Zajimave ale je ze i member muzeme volat z promenou: ?- member(X,[a,b,c]). Tohle vypada dost nesmyslne-v normalnim jazyce by to proste napsat neslo. Ale v prologu ano. System najde prvni moznost jak by to mohlo souhlasit tedy a. A celkem spravne se zepta: X = a A vy muzete odpovedet-enter znamena ano to je spravne ; znamena ne..hledej dal..zepta se tedy na b Tady je uz jasny jak funguje. Takovy dotaz se sice zda trochu zbytecny ale verte ze je dost dulezity. Otazky muzeme retezit za sebe: ?- connect(zachod,X),connect(zahrada,X) a vysledky se budou pekne predavat.. podminky ======== Ty se delaji pomoci ksichtiku: :- member(3,[1,2,3]), write(ok). Napise ok protoze 3 je clenem posloupnosti. Provadeni podminky je podobne jako u otazky z tim rozdilem, ze jeji provadeni se preusi jekamile nejaky dotaz odpovi no. Tedy kdyby volani member vratilo no k volani ok by uz nikdy nedoslo. Zaroven write je priklad jak muze predikat suplovat funkci. Vytvareni predikatu =================== Muzeme vytvorit specialni pravidlo-jako member,ktere se predem nevi ale system provede nejaky kod ktery neco zjisti. To se dela napriklad: (V zadavacim modu) zamestnany(X) :- zamestnava(X,Y) (pise se to stejne jako normalni clausa:location(zahrada,zachod) az na to ze misto konstant tam date promene a pak napisete nejake pravidlo) Znamena to neco jako: X je zamestnany, pokud je nejaky Y ktery ho zamestnava. Takovym zpusobem muzeme popsat i dost slozite situace. A v tom zpociva logicke programovani-popiseme vztahy mezi vecma a potom se proste na neco zeptame a system se nam snazi odpovedet. Takovych podminek pro jeden predikat muzeme napsat vic: zamestany(X) :- podnikatel(X) To znamena ze clovek je zamestnany take pokud je podnikatel-podnikatele nikto nezamestnava. Potom kdyz zadame: ?- zamestnany(novak). System se nejprve podiva jestli je nejake spojeni zamestnava(novak,Y) a pokud ne zjisti jestli je v databazi podnikatel(novak) pokud ani to ne odpovi no. Takove predikaty jsou pro prolog vsim. Cely program se pomoci nich pise: Tady je vysvetleni na konstrikci: jdi(X) :- you(L), connect(L,X), retract(you(L)), assert(you(X)). jdi(X) :- write(' Tam to nejde. '),nl. Kdyz se clovek zepta: ?- jdi(zahrada) Provede kod predikatu-to co nasleduje.Tedy podminku. V teto podmince nejprve pomoci: you(L), Ulozi do L tvoji pozici. To by selhat nemelo. Jedine v tom pripade ze by you zadnou pozici nemel a tak by to byla interni chyba programu. connect(L,X) To je otazka jestli existuje spojeni mezi mistnosti kde se zrovna nachazite a X-kam chcete jit. Pokud toto zpojeni neexistuje prerusi se provadeni a jdi selze. Pokud k tomu preruseni dojde zkusi se dalsi mozny predikat,ktery je nadefinovan a tim je: jdi(X) :- write(' Tam to nejde. '),nl. A tan spravne vypise chybu. Pokud ale zpojeni existuje pokracuje provadeni radkem: retract(you(L)), To je volani predikatu, ktery je zabudovan primo do prologu a zrusi platnost closy v jeho parametru. Tedy zrusi spojeni mezi vami a starou mistnosti. Dalsi radek: assert(you(X)), Zavede novou closu do databaze tentokrat spojeni mezi vami a novou mistnosti. A posledni radek: write(' jses na '),write(X),nl. Backtracing =========== Podminky a otazky jsou sice hezka vec. Ale jak jsme si rikali, je nekdy vice reseni. Napriklad napiseme si predikat co odpovi yes prave tehdy kdyz jeho tri parametry jsou za sebou na jedne ceste. cesta(X,Y,Z) :- connect(X,Y), connect(Y,Z). Toto probehne pouze kdyz jsou za sebou. V nasem bludisti to plati pouze pro kombinaci: ?- cesta(chodba,zachod,zahrada). odpovi yes. A k cemu by nam byla takova funkce v normalnim jazyce? K nicemu! To ale neplati v prologu! Zadejte treba: ?- cesta(chodba,Y,zahrada). A co se nestane? system odpovi: Y = zachod yes Stalo se neco zvlastniho....System zauvazoval a nasel spravne reseni. V nasem pripade to je jasne. Predikat se interpretroval jako: ?- connect(zahrada,Y) Y = zachod ?- connect(zachod,chodba) yes A nastavilo se tedy Y. Ale co kdybychom udelali dalsi spoje: |:connect(zahrada,chodba). |:connect(chodba,zahrada). Nyni uz situace neni jednoznacna. bludiste vypada: /--------zachod<--->chodba | ^ Zahrada<-----------------/ A presto system stale spravne odpovida zachod. To je prave podstata logickeho programovani. My jsme napsali pravidlo a system hleda odpoved tim ze zkousi dosadit vsechny mozne postupy a to dela tak dlouho dokud nenajde odpoved na tu se vas prepta a pokud nevyhovi pokracuje v hledani. Prave teto metode se rika backtracing. To znamena ze klidne muzeme zadat: ?- cesta(X,Y,zahod). Tedy ptame se systemu odkud se muzeme dostat pomoci dvou tahu na zachod? A system nam odpovi? X = zahrada Y = chodba a ceka. Pokud zmackeneme enter uz dal nehleda ale pokud dame ; klidne napise: X = chodba Y = zahrada Pokud opet odmitneme odpovi ze uz dalsi reseni nezna. To mi pripomelo davida kaprfilda(nebo jak se pise) a jeho oblibena slova:budu carovat s vami...dejte si prst na obrazovku a vyberte si ctverecek a udelejte tri tahy uhlopricne nebo rovne. A vim ze nejste ve vagone..... Najit takovy postup je celkem slozite ale v prologu by se to psalo jedna basen... Proste by jste si udelali predikaty na posouvani a potom by sjte udelali dotaz kdy predikat najdi_cestu_na_X(X,Y) je nula... Psat neco takoveho v konvencnim jazyce by bylo utrpeni. Dalsi sikovne vyuziti bactracingu je to,ze muze simulovat smycky. Napriklad kdyz chceme vypsat vsechny cesty z mistnosti muzeme udelat: cesty :- you(L), connect(L,X), write(X), write(' '), fail. cesty :- nl. A system napred bude chtit vyhovet prvnimu predikatu. Ten funguje takto: 1) uloz pozici hrace do L. To jde vzdycky. 2) Do X uloz cestu ven. Tech prave muze byt vic. ale do X se da vzdy jen jedna. 3) Vypis X. 4) Vypis mezeru pred dlasim slovem 5) Selzi. Odpoved predikatu fail je vzdy no. Proto chudak system bude zkouset dalsi cestu do X a vypise ji. Nyni muzeme rozsirit go na: go :- write('cesty:'), cesty, write('>> '), read(X), call(X), akce, go. Podobne se necha udelat take seznam predmetu v mistnosti a inventar. Tim jsem snad objasnil zaklady prologu. Je cas ukazat zdrojaky. Funkcni textovka =============================================================================== %Umistime predmety location(papir,zachod). % Bludiste connect(zachod,zahrada). connect(zachod,chodba). connect(chodba,zachod). connect(zahrada,chodba). connect(chodba,zahrada). % Popisy pro jednotlive mistnosti describe(papir,'proste toaletak'). describe(zachod,'Jdi na zachode..nelibe to tu voni'). describe(zahrada,'Jsi na zahrade..ptaci zpivaji, slunce sviti...'). describe(chodba,'Jsi na chodbe..vede ze zachodu na zahradu'). % Predikaty co delaji smycky prez backtracing cesty :- %vypise vsechny cesty s mistnosti you(L), %ulozi do L vasi pozici connect(L,X), %zjisti cestu z L a do X ulozi cil-tady se dela backtracing write(X), %vypise cilovou mistnost write(' '), %oddeli slova fail. %selze,aby se system pokusil najit dalsi cestu a take ji vypsal cesty :- %tohle se vyvola,kdyz uz neni zadna cesta k vypsani nl. %novy radek-konec vypisu vydis :- %vypise predmety v mistnosti you(L), %ulozi do L vasi pozici location(X,L),%najde predmet ktery je v mistnosti L-tady se dela backtracing write(X), %vypise nalezeny predmet write(' '), %oddeli slova fail. %selze vydis :- %tohle se vyvola kdyz uz neni dalsi predmet v mistnosti nl. inventar :- %vypise,co uzivatel nese-funguje stejne jako vidis ale location(X,you), %misto mistnosti testuje you write(X), write(' '), fail. inventar :- nl. popis :- %vypise popis mistnosti you(L), %do L ulozi vasi pozici describe(L,X),%vyhleda popis mistnosti write(X),nl. %a vypise % Jednoduche predikaty na modifikaci herni databaze jdi(X) :- %funkce na chozeni you(L), %do L ulozi vasi pozici connect(L,X),%zjisti jestli vede cesta z L do X-zde muze provadeni selhat retract(you(L)), %Zrusi spojeni ze starou mistnosti assert(you(X)). %Zavede do databaze novou asociaci-you a nova mistnost jdi(X):- %V pripade ze cesta nevede-prvni jdi selhalo write(' Tam to nejde. '),nl. smrt :- %Tento predikat vas zabije you(L), %Do L ulozi vasi pozici retract(you(L)), %Zrusi spoj ze starou mistnosti assert(you(nebe)). %Presune vas do nebe akce :- %Tyto predikaty ridi vsechny udalosti,ktere dejou ve hre location(papir,zahrada), %Pokud jste vyhodili papir na zahradu retract(location(papir,zahrada)),%Zrus spojeni-aby se zabranilo zacykleni write(' Vrhla se na tebe diva duchodkyne z holi a utloukla te ze slovy'),nl, write(' Takhle znecistovat zivotni prostredi! Kam se ten svet riti! '), smrt, %Zabyje vas akce. %Spusti se znova rekurzivne.Touto konstrukci se zarizuje to, %aby bylo mozne takovych akci udelat vic. Proste se pisou za %sebe. Kdyz tento predikat probehne,automaticky zrusi podminky %aby mohl probehnout znova-zrusi papir. Pri dalsim provadenim %selze,vyvola se tedy dalsi mozna situace-dalsi akce ve hre akce :- %Toto je posledni z akci-nic se nestalo. To je proto,aby %volani akce z go neselhalo a nezrusilo tim provadeni cele hry nl. done :- %Tento predikat zjistuje jestli hra nezkoncila you(nebe), write(' Sice jste zemrel ale nevadi...vlastne sjte hru vyhral '). %Hlavni smycka go :- done. %Timto je zaruceno aby hra zkoncila v pripade, ze done zjisti %ze je konec-provede se tato prvni moznost go a ukonci se go :- %Jinak se pokracuje na toto go popis, %Vypise popis mistnosti write('cesty:'),%Vypise vesty z mistnosti cesty, write('vydis:'),%Vypise co vidis vydis, write('>> '), %Prompt read(X), %Nacte closu z klavesnice call(X), %Provede nactenou closu akce, %Akce-tedy duchodkyne go. %Smycka pomoci rekurze %Uzivatelske prikazy zvedni(X) :- %Zvedne predmet you(L), location(X,L),%Zjisti jestli predmet X je v mistnosti L-zde muze selhat retract(location(X,L)),%Zrusi spojeni predmetu z mistnosti assert(location(X,you)),%Zavede zpojeni z vami write(' Zvedl jsi '),write(X),nl.%A hlaska zvedni(X) :- %Pro pripad selhani write(X),write(' tu nikde neni'). poloz(X) :- %Polozi predmet location(X,you), you(L), retract(location(X,you)), assert(location(X,L)), write(' Polozil jsi'),write(X),nl. poloz(X) :- write(X),write(' u sebe nemas'). %Predikaty z vykladu.. cesta(X,Y,Z) :-%Typicky priklad backtracingu connect(X,Y), connect(Y,Z). you(zachod). % Priklad matematiky v prologu mul(R1,I1,R2,I2,R3,I3):-%Nasobeni komplexnich cisel R3=R1*R2-I1*I2, I3=R1*I2-R2*I1. ============================================================================ A priklad pouziti: 1 ?- [pll]. [WARNING: (/root/pll:41) Singleton variables: X] pll compiled, 0.03 sec, 6,300 bytes. Yes 2 ?- go. Jdi na zachode..nelibe to tu voni cesty:zahrada chodba vydis:papir >> |: zvedni(papir). Zvedl jsi papir Jdi na zachode..nelibe to tu voni cesty:zahrada chodba vydis: >> |: jdi(chodba). Jsi na chodbe..vede ze zachodu na zahradu cesty:zachod zahrada vydis: >> |: inventar. papir Jsi na chodbe..vede ze zachodu na zahradu cesty:zachod zahrada vydis: >> |: poloz(papir). Polozil jsipapir Jsi na chodbe..vede ze zachodu na zahradu cesty:zachod zahrada vydis:papir >> |: zvedni(papir). Zvedl jsi papir Jsi na chodbe..vede ze zachodu na zahradu cesty:zachod zahrada vydis: >> |: jdi(zahrada). Jsi na zahrade..ptaci zpivaji, slunce sviti... cesty:chodba vydis: >> |: >> |: poloz(papir). Polozil jsipapir Vrhla se na tebe diva duchodkyne z holi a utloukla te ze slovy Takhle znecistovat zivotni prostredi! Kam se ten svet riti! Sice jste zemrel ale nevadi...vlastne sjte hru vyhral Yes ========================================================================= priklady funkce bactracingoveho predikatu cesta 3 ?- cesta(X,Y,zachod). X = zachod Y = chodba ; X = zahrada Y = chodba ; No 4 ?- cesta(X,zachod,Y). X = chodba Y = zahrada ; X = chodba Y = chodba ; No 5 ?- cesta(zachod,X,Y). X = zahrada Y = chodba ; X = chodba Y = zachod ; X = chodba Y = zahrada ; No 6 ?- cesta(zachod,X,zachod). X = chodba ; No ======================================================================= Trocha matematiky 7 ?- mul(1,2,3,4,I,R). I = 1 * 3 - 2 * 4 R = 1 * 4 - 3 * 2 ; No Vyrazy se vyhodnocuji az kdyz je treba 8 ?- mul(1,2,I,R,I1,R1). I = G792 R = G796 I1 = 1 * G792 - 2 * G796 R1 = 1 * G796 - G792 * 2 ; No Z backtracingem v matematice je to uz horsi..... ======================================================================= Zaver: Jak jste asi videli prolog je velmi jednoduchy jazyk ze scela novym pohledem na svet. Jde v nem udelat hodne zajimavych a slozitech algoritmu. Pri navrhovani programu setri hodne prace a vsechno jde v nem rychle a tedy i bez chyb. Nase velmi jednoducha textovka mela mnohem min problemu nez kdybychom ji delali v cecku. Jedina dira,ktera v ni je, je v go ktery pousti prikazovou radku prologu. Tam by to chtelo vylepsit nacitani do stringu a nejake to zpracovani pred volanim ale jinak cely program nema chybu. Je snadno rozsiritelny, Pridat nove prikazy, akce, mistnosti nebo treba grafiku a zvuk je hrackou. Taky jsem zaradil prolog mezi lispovsky jazyky. To je proto ze stejne jako lisp ma udelane promene, trypy(atomicke atd..) ma podobne rozdeleni interpretru-proto read(X) necetlo string ale celou clausu protoze i v prologu se clause da ulozit do premene. Ma dynamicke usporadani pameti a hodne dalsich spolecnych rysu. Proto existuje hodne prologackych interpretru napsanych v lispovi. O programovacich postupech v prologu by se dalo napsat mnohem vic a asi to jednou udelam. Kotelnik ......a ten nejkotlivejsi......