====== 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//