Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

pl:prolog:prolog_lab:programy [2011/03/08 13:10]
ikaf dla zainteresowanych
pl:prolog:prolog_lab:programy [2019/06/27 15:50]
Linia 1: Linia 1:
-====== LAB: Pisanie programów w Prologu ====== 
  
-===== -. Interakcja z programem ===== 
- 
-==== Wypisywanie na wyjściu ==== 
- 
-Predykat //write/1// wypisuje term na wyjście; //nl/0// przechodzi do nowej linii. 
- 
-**Ćwiczenie** 
- 
-Przetestować działanie: 
- 
-  write('​Ala ma '​),​write('​kota'​),​nl,​write('​w ciapki!'​). 
- 
- 
-==== Programy interaktywne ==== 
- 
-Predykat read/1 pozwala na pobieranie danych od użytkownika. 
- 
- 
-**Ćwiczenie** 
- 
-Proszę oglądnąć zastosowanie //read/1// na przykładzie programu {{interac.pl}} 
- 
-Po załadowaniu proszę wpisać: 
- 
-  ?- go. 
- 
- 
-===== -. Wymuszanie nawrotów ===== 
- 
-Predykat //fail/0// pozwala na wymuszanie nawrotów w procesie poszukiwania rozwiązania,​ co pozwala w szczególności na znalezienie wszystkich rozwiązań problemu. 
- 
-Przypomnienie:​ Prolog używa strategii przeszukiwania wgłąb drzewa rozwiązań problemu i zatrzymuje sie po napotkaniu 1. poprawnego rozwiązania. 
- 
-**Ćwiczenie** 
- 
-Pobrać i wczytać program {{fam2.pl}} 
- 
-Wyświetlić go przez listing. 
- 
-Sprawdzić działanie: 
- 
-  ?- kobieta(K),​write(K),​write('​ to kobieta.'​),​nl. 
- 
-Jak wymusić odnajdywanie kolejnych kobiet. 
- 
-Sprawdzić działanie: 
- 
-  ?- kobieta(K),​write(K),​write('​ to kobieta.'​),​nl,​fail. 
- 
-Sprawdzić działanie: 
- 
-  ?- kobieta(K),​fail. 
- 
-Dlaczego nic się nie pojawia? 
- 
-Pobrać i wczytać program {{capitals.pl}} 
- 
-Sprawdzić działanie: 
- 
-  ?- capital_of(A,​B),​ write(B), write('​ to stolica '), write(A), nl. 
-  ?- capital_of(A,​B),​ write(B), write('​ to stolica '), write(A), nl, fail. 
- 
- 
-===== -. Dynamiczna bazy wiedzy ===== 
- 
-==== Modyfikacja bazy wiedzy ==== 
- 
-Predykaty //​assert/​a/​z /1//, //​retract/​a/​z /1// pozwalają na dodawanie, usuwanie faktów do/z bazy wiedzy, na/do jej początku/​końca. 
- 
-Predykat //​abolish/​1//​ pozwala usunąć predykat z bazy wiedzy. (np. ''​abolish(kobieta/​1).''​) 
- 
-Predykat //​retractall/​1//​ pozwala usunąć klauzule danego predykatu z bazy wiedzy. (np. ''​retractall(kobieta(K)).''​) 
- 
-Predykaty //see/n//, //​tell/​told//​ pozwalają na odczyt, zapis bazy wiedzy z/do pliku. 
- 
-**Ćwiczenie** 
- 
-Proszę napisać: 
- 
-  ?- assert(kobieta(kopernik)). 
- 
-jak zmieniła sie wiedza na temat kobiet? 
- 
-  ?- listing(kobieta). 
- 
-Proszę sprawdzić: 
- 
-  kobieta(K),​write(K),​write('​ to kobieta.'​),​nl,​fail. 
- 
-Uwaga: niektóre kompilatory Prologu (np. SWI) wymagają wcześniejszego zadeklarowania predykatu jako takiego, który może być dynamicznie modyfikowany. Robi się to przez predykat //​dynamic/​1//,​ np. dla predykatu //​kobieta/​1//​ deklaracja w pliku //fam2.pl// ma postać '':​- dynamic(kobieta/​1).''​. 
- 
-Proszę oglądnąć zastosowanie //​assert/​retract//​ na przykładzie programu {{learner.pl}} 
- 
-Początkowa baza wiedzy jest w pliku {{learner_kb.pl}} 
- 
-Należy uruchomić program przez ''​start.''​ 
- 
-Jakie 3 przypadki odpowiedzi są brane pod uwagę? Co dzieje się przy wyjściu z programu i jak to wpływa na jego kolejne uruchamianie?​ 
- 
-Uwaga: operator ''​\+''​ oznacza //​negację//​. 
- 
-Predykat //​dynamic/​1//​ jest potrzebny w niektórych implementacjach Prologu (np. SWI) do umożliwienia wykonywania dynamicznych modyfikacji,​ t.j. //assert// i //​retract//​. 
- 
- 
-==== Modyfikacja reguł ==== 
- 
-assert/​retract pozwala również dodawać/​usuwać reguły: 
- 
-<code prolog> 
-:​-dynamic(a/​1),​ dynamic(b/​2). 
- 
-a(1). a(2). 
- 
-addrule:- assert((b(X,​Y):​-a(X),​a(Y))). 
- 
-delrule:- retract((b(_,​_):​-_)). 
- 
-start:​-addrule,​ b(X,Y), write(X), write(' ​ '), write(Y),​nl,​fail. 
-start. 
-</​code>​ 
- 
-W powyższym programie predykat ''​addrule/​0''​ dodaje (''​delrule/​0''​ usuwa) dynamicznie regułę: 
-<​code>​ 
-b(X,​Y):​-a(X),​a(Y). 
-</​code>​ 
- 
- 
-===== -. Zadawanie celu ===== 
- 
-Konstrukcja:​ 
- 
-  :- cos. 
- 
-pozwala na podanie celu w programie, np.: 
- 
-  :- dynamic(capital_of/​2). 
-  :- go. 
-  :- start. 
- 
-Prolog przystąpi do zrealizowania celu po załadowaniu kodu. 
- 
-Uruchomienie programu ze wskazanego pliku (''​plik.pl''​) z poziomu systemu operacyjnego można zrealizować za pomocą: 
- 
-  swipl -s program.pl -g go -t halt 
- 
-===== -. Śledzenie pracy programu ===== 
- 
-Interpretery Prologu pozwalają na śledzenie pracy programu. W tym celu należy ustawić tzw. trace point. 
- 
-Trace points: 
-  * trace/0 - ustawia trace point na wszystkich predykatach,​ w wersji swi-prolog używanej na laboratorium,​ ''​trace/​0''​ śledzi **następny zadany cel**, np. 
-<code prolog> 
-?- trace,​kobieta(K),​rodzic(K,​_). 
-</​code>​ 
-  * trace/1 - ustawia trace point na wskazanym predykacie, 
-  * trace/2 - modyfikuje dla wskazanego predykatu śledzone zdarzenia (call, redo, exit, fail), np.: 
-    * trace(something/​1,​-all) - zdejmuje trace point ze wskazanego predykatu //​something/​1//,​ 
-    * trace(something,​+call) - ustawia trace point śledzący jedynie wywołania na wskazane predykaty //​something//​ o dowolnej arności. 
- 
-Predykat //​debugging/​0//​ wypisuje ustawione trace points. 
-Predykat //debug/0// wchodzi do trybu debug. 
-Predykat //​nodebug/​0//​ wychodzi z trybu debug. 
- 
-**Ćwiczenie** 
- 
-Pobrać i wczytać program {{fam2.pl}} 
- 
-Sprawdzić działanie: 
- 
-<code prolog> 
-?- trace(matka). 
-[debug] ?- matka(kasia,​robert). 
-[debug] ?- ojciec(tomek,​robert). 
-[debug] ?- nodebug. 
-?- matka(kasia,​robert). 
-?- debug. 
-[debug] ?- trace(matka,​-all). 
-[debug] ?- matka(kasia,​robert). 
-[debug] ?- trace(matka,​+call). 
-[debug] ?- matka(kasia,​robert). 
-[debug] ?- nodebug. 
-?- trace. 
-[debug] ?- matka(kasia,​robert). 
-[debug] ?- nodebug. 
-</​code>​ 
- 
-W SWI Prologu można też skorzystać z dodatkowego pakietu XPCE, w którym jest też wizualny debugger. 
- 
-Należy wyjść z bieżacej sesji SWI. Uruchomić interpreter z powłoki unixa przez przez polecenie ''​xpce''​. Następnie uruchomić graficzny tracer przy użyciu predykatu guitracer/​0. 
- 
-===== -. Arytmetyka w Prologu ===== 
- 
-W Prologu nie można w sposób //​bezpośredni//​ wykonywać obliczeń arytmetycznych. Służy do tego predykat //is//. 
- 
- 
-**Ćwiczenie** 
- 
-1. Sprawdzić działanie: 
- 
-<code prolog> 
-?- X is 2 + 2. 
-?- Y is 2.5 + ( 4 / 2). 
-?- Z is 2 + 0.001. 
-</​code>​ 
- 
-Uwaga: 
- 
-<code prolog> 
-?- A is 3. 
-?- B is A + 4. 
-?- A is 3, B is A + 4. 
-</​code>​ 
- 
-Operacje arytmetyczne:​ 
- 
-<code prolog> 
-?- X is 2 + 2. 
-?- X is 2 * 3. 
-?- X is 4 / 2. 
-?- X is 4 / 3. 
-?- X is 4 // 3. 
-</​code>​ 
-Uwaga na //​podstawianie//:​ 
- 
-<code prolog> 
-?- X is 2 + 5. 
-?- X = 2 + 5. 
-?- 2 + 5 =:= 1 + 4. 
-?- 2 + 5 =:= 3 + 4. 
-?- 2 + 5 =:= 4 + 4. 
-</​code>​ 
- 
-Przećwiczyć użycie operatorów:​ 
- 
-<code prolog> 
-?- 2 < 3. 
-?- 2 > 3. 
-?- 3 > 3. 
-?- 3 >= 3. 
-?- 3 =< 3. 
-</​code>​ 
- 
-2. Napisz program obliczający wynik [[http://​pl.wikipedia.org/​wiki/​R%C3%B3wnanie_kwadratowe|równania kwadratowego]] ([[wp>​Quadratic Equation]]) ''​ax^2 + bx + c = 0''​ w dziedzinie liczb rzeczywistych. 
-Zaimplementuj predykaty: ​ 
-  * ''​delta/​4''​ -- obliczający deltę, argumenty kolejno: a, b, c, wynik, 
-  * ''​kwadrat/​4''​ -- obliczający wynik równania kwadratowego,​ argumenty kolejno: a, b, c, wynik. 
-Zwróć uwagę na niedeterminizm w predykacie ''​kwadrat/​4'',​ który znajduje zero, jedno, albo dwa rozwiązania;​ mogą się przydać [[http://​www.swi-prolog.org/​pldoc/​doc_for?​object=section%282%2c%20%274.25%27%2c%20swi%28%27%2fdoc%2fManual%2farith.html%27%29%29|funkcje matematyczne]]. ​ 
- 
-===== -. Rekurencja w Prologu ===== 
- 
-Typowym przykładem wykorzystania mechanizmu rekurencji jest obliczanie wartości funkcji silnia. 
-Poniżej znajduje się kod realizujący tą funkcjonalność. 
- 
-<code prolog> 
- ​factorial(0,​1). 
- ​factorial(Number,​Result) :- 
-        Number > 0, 
-        NewNumber is  Number-1, 
-        factorial(NewNumber,​NewResult),​ 
-        Result ​ is  Number*NewResult. 
-</​code>​ 
- 
- 
-**Ćwiczenie** 
- 
-Wpisz, przetestuj i przemyśl działanie programu rekurencyjnie liczącego silnię. 
- 
- 
-===== - Wybrane problemy rozwiązane w Prologu ===== 
- 
-==== Wieże Hanoi ==== 
-Problem [[http://​pl.wikipedia.org/​wiki/​Wieże_Hanoi]]. 
- 
-Problem [[wp>​Towers_of_hanoi]] 
- 
-**Ćwiczenie** 
- 
-Proszę pobrać program {{:​pl:​prolog:​prolog_lab:​hanoi.pl|hanoi.pl}}. 
-Przetestować i przemyśleć. 
- 
-Predykat //move/4// działa następująco:​\\ 
-np. //​move(3,​left,​right,​center)//​ przenosi 3 krążki ze stosu //left// na stos //right// przy pomocy stosu //center//. 
- 
-Przykład: 
-<code prolog> 
-?- move(3,​left,​right,​center). 
-Move top disk from left to right 
-Move top disk from left to center 
-Move top disk from right to center 
-Move top disk from left to right 
-Move top disk from center to left 
-Move top disk from center to right 
-Move top disk from left to right 
-</​code>​ 
- 
-Analizując kod programu proszę zauważyć, że algorytm rozwiązania problemu opiera się na dekompozycji na podproblemy. 
- 
-==== Kolorowanie Mapy ==== 
-Problem: mamy mapę taką jak poniżej 
- 
-<code prolog> 
- 
-                 ​|Bialorus 
-                 ​|------------ 
-     ​Polska ​     | 
-  ---------------| 
-       ​| ​        | Ukraina 
- ​Czechy| Slowacja|----------- 
------------------ 
-</​code>​ 
- 
-Należy ja pokolorować 3 kolorami, tak aby żadne sąsiadujące państwa nie miały takiego samego koloru: 
-[[wp>​Four_color_theorem]] 
- 
- 
-**Ćwiczenie** 
- 
-Definiujemy 3 kolory: 
- 
-<code prolog> 
-kolor(czerwony). 
-kolor(zielony). 
-kolor(niebieski). 
-</​code>​ 
- 
-Należy zdefiniować predykat ''​koloruj/​5'',​ tak aby zadając pytanie: 
- 
-  ?- koloruj(Polska,​Bialorus,​Ukraina,​Slowacja,​Czechy). 
- 
-dostać wszystkie możliwości pokolorowania tej konkretnej mapy. 
- 
-Uwaga: predykat ''​koloruj/​5''​ definiuje zależności geograficzne. 
- 
-Uwaga: w Prologu operator ''​\=''​ to nieidentyczność,​ czy też niemożliwość uzgodnienia termów. 
- 
-==== Dla Zainteresowanych ==== 
-Więcej ciekawych problemów [[reprezentacja_wiedzy#​ciekawe_problemy|na kolejnych zajęciach]] 
-oraz w [[prolog:​pllib:​start|bibliotece programów]]. 
- 
-===== Obserwacje ===== 
- 
-W Prologu negacja opiera się o //Closed World Assumption//​! 
- 
-W Prologu nie ma dualizmu "​dane/​kod"​ -> w Prologu jest jedna //baza wiedzy//, zawierająca fakty i reguły, którą można dynamicznie modyfikować. 
- 
-===== Komentarze ===== 
-Z braku lepszego miejsca tutaj studenci wpisują komentarze natury ogólnej do tego lab. 8-) 
- 
- --- //​[[gjn@agh.edu.pl|Grzegorz J. Nalepa]] 2008/02/20 14:34// 
pl/prolog/prolog_lab/programy.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0