====== LAB: Wprowadzenie do środowiska Prologu ======
===== -. Wprowadzenie do Prologu =====
Prolog to język programowania logicznego, lub dokładniej programowania w logice (//PROgrammation en LOGique, PROgramming in LOGic//).
Uwaga: nie należy za bardzo przejmować się hasłem o Prologu w Wikipedii -- jest //źle// napisane!
Rozwój języka:
* podstawy teoretyczne: logika ([[wp>George_Boole]],[[wp>Gottlob_Frege]],[[wp>Alfred_Tarski]], i inni), [[wp>J._Alan_Robinson]] (rezolucja), [[wp>]] (University of Edinburgh)
* implementacje: [[wp>Alain_Colmerauer]], (University of Aix-Marseille), 1972; [[wp>David_H._D._Warren]] (University of Edinburgh) 1977
Więcej wskazówek związanych z uczeniem się Prologu można znaleźć na [[pl:prolog:prolog_lab#przydatne_materialy|głównej stronie laboratorium]].
===== -. SWI Prolog =====
Współcześnie jest dostępnych szereg implementacji Prologu, w tym swobodnie dostępne kompilatory Prologu:
* Jan Wielemaker, //SWI-Prolog//, http://www.swi-prolog.org
* LIACC/Universidade do Porto, OPPE Sistemas/UFRJ, //YAP//, http://www.ncc.up.pt/~vsc/Yap/
* Daniel Diaz, //GNU-Prolog//, http://gnu-prolog.inria.fr
W czasie zajęć będzie się pracować w środowisku SWI.
Podstawowym interfejsem w SWI jest powłoka. W powłoce pracuje się podobnie jak w powłoce unixowej, oczywiście z uwzględnieniem specyfiki Prologu.
==== Uruchamianie powłoki ====
**Ćwiczenie**
Unix/GNU/Linux: Proszę otworzyć okno terminala, np. ''xterm'' i uruchomić w nim powłokę SWI przez polecenie ''swipl'' (może też być dostępny przez polecenie ''pl'').
Windows: uruchomić za pomoc ikony, menu, itp.
UWAGA: każda //linia kodu// w Prologu musi się kończyć kropką, podobnie linia, polecenie w powłoce!
Proszę sprawdzić działanie systemu pomocy, przez predykat ''help.'', a następnie przeczytać opis do predykatu ''consult/1''.
Proszę wyjść z powłoki przez ''halt.''
Proszę ponownie uruchomić powłokę SWI. Przy pomocy jakiej kombinacji klawiszy można wyjść z powłoki unixowej - analogiczenie w SWI?
==== Środowisko pracy ====
SWI dostarcza przede wszystkim zaawansowanej powłoki, wyposażonej w bibliotekę //GNU ReadLine//.
Cennym uzupełnieniem jest edytor GNU Emacs ze środowiskiem edycyjnym (trybem) //[[http://packages.debian.org/stable/prolog-el|prolog.el]]//.
SWI w wersji rozszerzonej o środowisko XPCE dostarcza również narzędzi programistycznych, takich jak wbudowany edytor //emacs//. Aby z niego skorzystać należy zamiast ''swipl'' wywołać ''xpce'' a potem w powłoce Prologu ''emacs.''.
**Ćwiczenie**
Sprawdzić działanie systemu pracy z linią poleceń (GNU Readline): historia, dopełnianie, skrótu klawiaturowe. Przeglądnąć tryb pracy w GNU Emacs i edytor PCE Emacs (uruchomić SWI Prolog przez ''xpce'').
===== -. Programowanie w Prologu =====
==== Programowanie nieklasyczne ====
Prolog NIE jest klasycznym językiem programowania.
Nie ma w nim:
* słów kluczowych (typu IF THEN ELSE, DO WHILE, GOTO),
* brak rozróżnienia we/wy w sensie klasycznego wywoływania funkcji,
* brak funkcji, (można jednak prowadzić proste obliczenia; funkcje mogą być zastępowane predykatami),
* brak instrukcji podstawienia/przypisania; inne rozumienie zmiennych,
* brak jawnej sekwencyjności, czy iteracyjności (z małymi wyjątkami),
* brak dualizmu dane/program!
Prolog dostarcza:
* metody strukturalizowania informacji, //termy//,
* programowania //deklaratywnego//,
* //rekurencji//, jak metody przetwarzania informacji,
* //unifikacji// - mechanizmy dopasowywania wzorców,
* //rezolucji// - metody wnioskowani logicznego,
* strategii sterowania wnioskowaniem.
==== Budowa programów ====
Elementy składniowe programu:
* //stałe//: stałe znakowe a także liczby (atomy),
* //niewiadome/szukane// (odpowiadają tzw. zmiennym logicznym, które __nie__ mają zbyt wiele wspólnego ze zmiennymi w klasycznych językach programowania),
* //termy//: symbole funkcyjne wraz z argumentami, obiekty strukturalnie złożone.
Program składa się z:
* szeregu //klauzul// (ang. //clause//), wyróżniamy:
* //fakty// (klauzule proste, formuły atomowe/atomiczne),
* //reguły// (klauzule złożone),
* oraz //celu// (ang. //goal//).
==== Prosty program ====
**Ćwiczenie**
Proszę przyjrzeć się poniższemu, prostemu programowi (klasyczny przykład //Rodzina//).
rodzic(kasia,robert).
rodzic(tomek,robert).
rodzic(tomek,eliza).
kobieta(kasia).
kobieta(eliza).
mezczyzna(tomek).
mezczyzna(robert).
Proszę uruchomić wybrany zewnętrzny edytor i wpisać w nim podobny program, dotyczący własnej (albo innej) rodziny. Mniej ambitni mogą po prostu przepisać... Program należy zapisać w pliku //fam2.pl//.
==== Uruchamianie programu ====
Do uruchomienia programu należy w powłoce załadować plik z kodem w Prologu przy pomocy predykatu ''consult/1'' (skrót: ''[nazwa].'')
Operację tę należy powtarzać po każdej modyfikacji kodu bazy wiedzy!
**Ćwiczenie**
W powłoce SWI należy wczytać powyższy program:
?- [fam2].
Program jest kompilowany, a zawarta w nim wiedza dodawana do bazy wiedzy dostępnej z powłoki SWI. Można to sprawdzić:
?- kobieta(X).
Po ukazaniu się 1. odpowiedzi należy wcisnąć klawisz średnika (;).
==== Wyświetlanie bazy wiedzy ====
**Ćwiczenie**
Sprawdzić działanie predykatu ''listing/0''.
Sprawdzić działanie predykatu ''listing/1'':
?- listing(rodzic).
W sytuacjach kiedy nie interesują nas wartości pewnych szukanych w predykacie, możemy użyć tzw. szukanych anonimowych. Na przykład: ''czy Robert ma rodziców?''
?- rodzic(_,robert).
==== Zadawanie celu (pytań) ====
**Ćwiczenie**
Systemowi można teraz zadawać pytania, cele do zrealizowania.
Kto jest mężczyzną?
?- mezczyzna(X).
Czy tomek jest mężczyzną?
?- mezczyzna(tomek).
Czy reksio jest mężczyzną?
?- mezczyzna(reksio).
Czy kasia jest rodzicem roberta?
?- rodzic(kasia,robert).
Czyim rodzicem jest kasia?
?- rodzic(kasia,X).
Czy zamiast X można wpisać inny symbol? Jaki?
Kto jest rodzicem robert?
?- rodzic(Y,robert).
Czy zamiast ''Y'' można wpisać inny symbol?
==== Rozbudowa programu ====
**Ćwiczenie**
Proszę rozbudować program do poniższej, analogicznej (co do liczby osób i zależności) formy:
rodzic(kasia,robert).
rodzic(tomek,robert).
rodzic(tomek,eliza).
rodzic(robert,anna).
rodzic(robert,magda).
rodzic(magda,jan).
kobieta(kasia).
kobieta(eliza).
kobieta(magda).
kobieta(anna).
mezczyzna(tomek).
mezczyzna(robert).
mezczyzna(jan).
Czy kolejność wpisywania linii ma znaczenie?
UWAGA: aby dopisane fakty były dostępne dla Prologu, należy ponownie załadować plik!
Jeżeli koniunkcję celów oznaczamy przecinkiem, to jak zapytać kto jest matką, a kto ojcem roberta?
==== Czy Prolog jest po polsku? ====
**Ćwiczenie**
Proszę spróbować dopisać do programu takie linijki:
famme(kasia).
homme(krzys).
parent(kasia,krzys).
Czy nazwa użytych symboli wpływa na działanie programu?
Jakie są ograniczenia na używane symbole?
==== Reguły wnioskowania ====
**Ćwiczenie**
Proszę dopisać poniższe reguły (klauzule złożone) i sprawdzić ich działanie.
matka(X,Y) :-
rodzic(X,Y),
kobieta(X).
ojciec(X,Y) :-
rodzic(X,Y),
mezczyzna(X).
Proszę zdefiniować reguły opisujące: brata, siostrę, dziadka i babcię. Proszę dokładnie sprawdzić ich działanie.
Jaki pojawia się problem przy bracie/siostrze? Uwaga na operator: ''\=''
Proszę się zastanowić nad własnymi regułami opisującymi relacje w rodzinie.
==== Reguły rekurencyjne ====
**Ćwiczenie**
Rekurencja jest jednym z podstawowych mechanizmów programowania w Prologu. Proszę się przyjrzeć regułom opisującym przodka:
przodek(X,Y) :-
rodzic(X,Y).
przodek(X,Z) :-
rodzic(X,Y),
przodek(Y,Z).
Te dwie klauzule, w tym przypadku reguły, opisują dokładnie jeden predykat: //przodek/2//.
Jak zdefiniować potomka, krewnego?
===== Obserwacje =====
==== Styl ====
Poprawny styl kodowania bardzo wpływa na przejrzystość programów w Prologu. Program w Prologu jest pewną reprezentacją wiedzy, powinien być zrozumiały dla osoby znającej jedynie notację (relacyjną) użytą w Prologu. Czytelnik kodu programu nie musi znać //algorytmu// czy //modelu// (np. obiektowego), żeby zrozumieć program. To sam program JEST algorytmem, modelem.
==== Alternatywa ====
Tak, w Prologu jest operator alternatywy (ang. //OR//), ale //nie//, nie jest niezbędny, ani nie powinno się go używać. W praktyce ten sam efekt uzyskujemy pisząc kolejne klauzule, a zyskujemy na przejrzystości.
==== Klasyczny program ====
Na zakończenie:
?- write('Hello world'), nl.
===== 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//