Both sides previous revision
Poprzednia wersja
Nowa wersja
|
Poprzednia wersja
|
pl:prolog:prolog_lab:programy [2009/02/24 14:02] holownia |
pl:prolog:prolog_lab:programy [2019/06/27 15:50] (aktualna) |
Predykat //write/1// wypisuje term na wyjście; //nl/0// przechodzi do nowej linii. | Predykat //write/1// wypisuje term na wyjście; //nl/0// przechodzi do nowej linii. |
| |
==== Ćwiczenie: Wypisywanie na wyjściu ==== | **Ćwiczenie** |
| |
Przetestować działanie: | Przetestować działanie: |
| |
| |
==== Temat: Programy interaktywne ==== | ==== Programy interaktywne ==== |
| |
Predykat read/1 pozwala na pobieranie danych od użytkownika. | Predykat read/1 pozwala na pobieranie danych od użytkownika. |
| |
| |
==== Ćwiczenie: Programy interaktywne ==== | **Ćwiczenie** |
| |
Proszę oglądnąć zastosowanie //read/1// na przykładzie programu {{interac.pl}} | Proszę oglądnąć zastosowanie //read/1// na przykładzie programu {{interac.pl}} |
| |
===== -. Wymuszanie nawrotów ===== | ===== -. Wymuszanie nawrotów ===== |
| |
==== Temat: Predykat fail ==== | |
| |
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. | 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. | Przypomnienie: Prolog używa strategii przeszukiwania wgłąb drzewa rozwiązań problemu i zatrzymuje sie po napotkaniu 1. poprawnego rozwiązania. |
| |
| **Ćwiczenie** |
==== Ćwiczenie: Predykat fail ==== | |
| |
Pobrać i wczytać program {{fam2.pl}} | Pobrać i wczytać program {{fam2.pl}} |
===== -. Dynamiczna bazy wiedzy ===== | ===== -. Dynamiczna bazy wiedzy ===== |
| |
==== Temat: Modyfikacja 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. | 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. | Predykat //abolish/1// pozwala usunąć predykat z bazy wiedzy. (np. ''abolish(kobieta/1).'') |
| |
Predykat //retractall/1// pozwala usunąć klauzule danego predykatu z bazy wiedzy. | 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. | Predykaty //see/n//, //tell/told// pozwalają na odczyt, zapis bazy wiedzy z/do pliku. |
| |
==== Ćwiczenie: Modyfikacja bazy wiedzy ==== | **Ćwiczenie** |
| |
Proszę napisać: | Proszę napisać: |
| |
| |
==== Temat: Modyfikacja reguł ==== | ==== Modyfikacja reguł ==== |
| |
assert/retract pozwala również dodawać/usuwać reguły: | assert/retract pozwala również dodawać/usuwać reguły: |
| |
W powyższym programie predykat ''addrule/0'' dodaje (''delrule/0'' usuwa) dynamicznie regułę: | W powyższym programie predykat ''addrule/0'' dodaje (''delrule/0'' usuwa) dynamicznie regułę: |
<code prolog> | <code> |
b(X,Y):-a(X),a(Y). | b(X,Y):-a(X),a(Y). |
</code> | </code> |
| |
| |
===== -. Uruchamianie i debuggowanie programów ===== | ===== -. Zadawanie celu ===== |
| |
==== Temat: Zadanie celu, uruchamianie programów ==== | |
| |
Konstrukcja: | Konstrukcja: |
Uruchomienie programu ze wskazanego pliku (''plik.pl'') z poziomu systemu operacyjnego można zrealizować za pomocą: | Uruchomienie programu ze wskazanego pliku (''plik.pl'') z poziomu systemu operacyjnego można zrealizować za pomocą: |
| |
swipl -t halt -s plik.pl | swipl -s program.pl -g go -t halt |
| |
| ===== -. Śledzenie pracy programu ===== |
| |
==== Temat: Śledzenie pracy programu ==== | Interpretery Prologu pozwalają na śledzenie pracy programu. W tym celu należy ustawić tzw. trace point. |
| |
Interpretery Prologu pozwalają na śledzenie pracy programu. W tym celu należy włączyć śledzenie analizowania konkretnego predykatu przez //spy/1//, a następnie włączyć tryb śledzenia pracy programu przez //trace/0//. | 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. |
| |
Debugger wyłącza się przez //nodebug/0//. | Predykat //debugging/0// wypisuje ustawione trace points. |
| Predykat //debug/0// wchodzi do trybu debug. |
| Predykat //nodebug/0// wychodzi z trybu debug. |
| |
| **Ćwiczenie** |
| |
==== Ćwiczenie: Śledzenie pracy programu ==== | Pobrać i wczytać program {{fam2.pl}} |
| |
Sprawdzić działanie: | Sprawdzić działanie: |
| |
<code prolog> | <code prolog> |
?- [capitals]. | ?- trace(matka). |
?- spy(capital_of). | [debug] ?- matka(kasia,robert). |
[debug] ?- trace. | [debug] ?- ojciec(tomek,robert). |
[trace] ?- capital_of(A,B), write(B), write(' to stolica '), write(A), nl. | [debug] ?- nodebug. |
[trace] ?- capital_of(A,B), write(B), write(' to stolica '), write(A), nl, fail. | ?- 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> | </code> |
| |
W SWI Prologu można też skorzystać z dodatkowego pakietu XPCE, w którym jest też wizualny debugger. | 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 wykonać: | 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. |
| |
<code prolog> | |
?- [capitals]. | |
?- spy(capital_of). | |
[debug] ?- guitracer. | |
[debug] ?- trace. | |
[trace] ?- capital_of(A,B), write(B), write(' to stolica '), write(A), nl, fail. | |
</code> | |
| |
===== -. Arytmetyka w Prologu ===== | ===== -. Arytmetyka w Prologu ===== |
| |
==== Temat: Obliczenia arytmetyczne i operatory porównania ==== | |
| |
W Prologu nie można w sposób //bezpośredni// wykonywać obliczeń arytmetycznych. Służy do tego predykat //is//. | W Prologu nie można w sposób //bezpośredni// wykonywać obliczeń arytmetycznych. Służy do tego predykat //is//. |
| |
| |
==== Ćwiczenie: Obliczenia arytmetyczne i operatory porównania ==== | **Ćwiczenie** |
| |
1. Sprawdzić działanie: | 1. Sprawdzić działanie: |
* ''delta/4'' -- obliczający deltę, argumenty kolejno: a, b, c, wynik, | * ''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. | * ''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://gollem.science.uva.nl/SWI-Prolog/Manual/arith.html|funkcje matematyczne]]. | 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/man?section=arith|funkcje matematyczne]], w szczególności do obliczenia pierwiastka używa się ''sqrt/1''. |
| |
===== -. Rekurencja w Prologu ===== | ===== -. Rekurencja w Prologu ===== |
| |
==== Temat: Rekurencyjne liczenie silni ==== | |
Typowym przykładem wykorzystania mechanizmu rekurencji jest obliczanie wartości funkcji silnia. | Typowym przykładem wykorzystania mechanizmu rekurencji jest obliczanie wartości funkcji silnia. |
Poniżej znajduje się kod realizujący tą funkcjonalność. | Poniżej znajduje się kod realizujący tą funkcjonalność. |
</code> | </code> |
| |
==== Ćwiczenie: Rekurencyjne liczenie silni ==== | |
| **Ćwiczenie** |
Wpisz, przetestuj i przemyśl działanie programu rekurencyjnie liczącego silnię. | Wpisz, przetestuj i przemyśl działanie programu rekurencyjnie liczącego silnię. |
| Uruchom program w trybie śledzenia wykonywania (trace). |
| |
| **Ćwiczenie** |
| |
| Opierając się na silni napisz program wypisujący [[http://pl.wikipedia.org/wiki/Ci%C4%85g_Fibonacciego|Ciąg Fibonacciego]]. |
| |
===== - Wybrane problemy rozwiązane w Prologu ===== | ===== - Wybrane problemy rozwiązane w Prologu ===== |
| |
==== Temat: Wieże Hanoi ==== | ==== Świat klocków ==== |
| Problem [[wp>Blocks_world]] |
| |
| Wczytaj {{:pl:prolog:prolog_lab:blocks.pl|}} |
| |
| Narysuj na kartce zamodelowany świat. |
| Jakie pytania można zadać? |
| <code prolog> |
| above(b1,b2). |
| above(b3,b5). |
| left(b1,b7). |
| left(b3,b3). |
| </code> |
| |
| |
| **Ćwiczenie** |
| |
| Opisz w programie taki świat: |
| <code> |
| a1 |
| a2 |
| a3 c1 c3 |
| a4 a5 c2 c4 |
| </code> |
| |
| ==== Wieże Hanoi ==== |
Problem [[http://pl.wikipedia.org/wiki/Wieże_Hanoi]]. | Problem [[http://pl.wikipedia.org/wiki/Wieże_Hanoi]]. |
| |
Problem [[wp>Towers_of_hanoi]] | Problem [[wp>Towers_of_hanoi]] |
| |
Program {{:pl:prolog:prolog_lab:hanoi.pl|hanoi.pl}} | **Ćwiczenie** |
| |
==== Ćwiczenie: Wieże Hanoi ==== | Proszę pobrać program {{:pl:prolog:prolog_lab:hanoi.pl|hanoi.pl}}. |
Pobrać program {{:pl:prolog:prolog_lab:hanoi.pl|hanoi.pl}} | |
Przetestować i przemyśleć. | 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: | Przykład: |
</code> | </code> |
| |
| Analizując kod programu proszę zauważyć, że algorytm rozwiązania problemu opiera się na dekompozycji na podproblemy. |
| |
==== Temat: Kolorowanie Mapy ==== | ==== Kolorowanie Mapy ==== |
Problem: mamy mapę taką jak poniżej | Problem: mamy mapę taką jak poniżej |
| |
[[wp>Four_color_theorem]] | [[wp>Four_color_theorem]] |
| |
==== Ćwiczenie: Kolorowanie Mapy ==== | |
| **Ćwiczenie** |
Definiujemy 3 kolory: | Definiujemy 3 kolory: |
| |
Uwaga: w Prologu operator ''\='' to nieidentyczność, czy też niemożliwość uzgodnienia termów. | 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 ===== | ===== Obserwacje ===== |