Prolog to system realizujący użycie logiki jako paradygmatu „programowania” (PROgrammation en LOGique, PROgramming in LOGic). Wybrane informacje:
Więcej wskazówek związanych z uczeniem się Prologu można znaleźć na głównej stronie laboratorium.
Uwaga: nie należy za bardzo przejmować się hasłem o Prologu w Wikipedii – jest źle napisane!
Prolog dostarcza metodę reprezentacji wiedzy (klauzule Horna), która pozwala na opis i budowę bazy wiedzy (ang. knowledge base).
Prolog jest wyposażony w system automatycznego wnioskowania (ang. automated reasoning), który pozwala w szczególności na automatyczne wyszukiwanie rozwiązań problemów/zadań opisanych przy pomocy bazy wiedzy.
Praca z systemem obejmuje:
Co za tym idzie Prolog nie jest „językiem programowania” ile systemem rozwiązywania problemów, obejmującym język ich opisu.
Współcześnie jest dostępnych szereg implementacji Prologu, w tym swobodnie dostępne kompilatory Prologu:
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.
Ć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?
SWI dostarcza przede wszystkim zaawansowanej powłoki, wyposażonej w bibliotekę GNU ReadLine.
Cennym uzupełnieniem jest edytor GNU Emacs ze środowiskiem edycyjnym (trybem) 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
).
Baza wiedzy obejmuje dwa rodzaje sformułowań, prostszym z nich są fakty.
Ćwiczenie
Proszę przyjrzeć się poniższej, prostej bazie wiedzy.
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 tekst, dotyczący własnej (albo innej) rodziny. Mniej ambitni mogą po prostu przepisać… Program należy zapisać w pliku fam1.pl.
Inny przykład pf1.pl:
woman(mia). woman(jody). woman(yolanda). playsAirGuitar(jody). party.
Aby użyć bazy wiedzy należy w powłoce załadować plik przy pomocy predykatu consult/1
(skrót: [nazwa].
)
Operację tę należy powtarzać po każdej modyfikacji pliku bazy wiedzy.
Ćwiczenie
W powłoce SWI należy wczytać powyższe pliki:
?- [fam1].
?- [pf1].
Zawarta w nich wiedza dodawana do bazy wiedzy dostępnej z powłoki SWI.
?- listing.
Dysponując bazą wiedzy można zadawać pytania/cele.
Czy Kasia jest kobietą?
?- kobieta (kasia).
Czy Mia jest kobietą?
Czy Tomek jest rodzicem Elizy?
Uwaga: Prolog zawsze „wie”. Ale wie dokładnie tyle ile mu powiemy:
Czy Kopernik jest kobietą?
Czy Vincent jest kobietą?
Nazywamy to closed world assumption.
Inny ogólniejszy rodzaj pytań.
Czy znasz/istnieją jakieś Kobiety?
?- kobieta(_).
Czy Tomek jest rodzicem?
Poza odpowiadaniem na pytania Prolog potrafi wyszukiwać - generować rozwiązania.
Jakie znasz/są/istnieją kobiety?
?- kobieta(Kto).
Kto jest rodzicem?
?- rodzic(R,_).
Czy znasz rodziców, którzy mają synów-dzieci, które są mężczyznami?
?- rodzic(R,S),mezczyzna(S).
Kto jest ojcem, tj. rodzicem, który jest mężczyzną:
?- rodzic(R,S),mezczyzna(R).
Reguły pozwalają na uchwycenie pewnych prawidłowości i generowanie w procesie wnioskowania nowej wiedzy, nie reprezentowanej explicite.
Dopisz do poprzednich plików i zapisz pod nową nazwą, następnie wczytaj (consult).
fam2.pl:
matka(M,D) :- rodzic(M,D), kobieta(M). ojciec(O,D) :- rodzic(O,D), mezczyzna(O).
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.
pf2.pl
happy(yolanda). listens2Music(mia). listens2Music(yolanda):- happy(yolanda). playsAirGuitar(mia):- listens2Music(mia). playsAirGuitar(yolanda):- listens2Music(yolanda).
Po niektórych pytaniach można nacisnąć średnik „;”…
book(signature_1,title_1,author_1,publisher_1,year_1). book(signature_2,title_2,author_2,publisher_2,year_2). book(signature_3,title_3,author_1,publisher_3,year_3). book(signature_4,title_4,author_4,publisher_4,year_4). book(signature_5,title_5,author_1,publisher_5,year_5). journal(journal_id_1,title_1,volume_1,number_1,year_1). journal(journal_id_2,title_2,volume_2,number_2,year_2). journal(journal_id_3,title_3,volume_3,number_3,year_3). journal(journal_id_4,title_4,volume_4,number_4,year_4). journal(signature_5,title_5,volume_5,number_5,year_5). user(id_1,surname_1,forename_1,born_1,address_1). user(id_2,surname_2,forename_2,born_2,address_2). user(id_3,surname_3,forename_3,born_3,address_3). user(id_4,surname_4,forename_4,born_4,address_4). user(id_5,surname_5,forename_5,born_5,address_5). register(id_1,signature_1,borrow_date_1,return_date_1). register(id_1,signature_2,borrow_date_2,return_date_2). register(id_2,signature_1,borrow_date_3,return_date_3). %%% Algebraic operations sum(Id,Title,Year):- book(Id,Title,_,_,Year); journal(Id,Title,_,_,Year), not(book(Id,Title,_,_,Year)). intersect(Id,Title,Year):- book(Id,Title,_,_,Year), journal(Id,Title,_,_,Year). except(Id,Title,Year):- book(Id,Title,_,_,Year), not(journal(Id,Title,_,_,Year)). projection(Title,Author,Year):- book(_,Title,Author,_,Year). selection(Signature,Title,Author,Publisher,Year):- book(Signature,Title,Author,Publisher,Year), Author = author_1. cartesian_product(Signature,Uid):- book(Signature,_,_,_,_), user(Uid,_,_,_,_). who_what_book(Uid,Surname,Name,Signature,Title,BorrowDate,ReturnDate):- register(Uid,Signature,BorrowDate,ReturnDate), user(Uid,Surname,Name,_,_), book(Signature,Title,_,_,_).
Brak I/O
% Definicje działania bramek podstawowych not(1,0). not(0,1). and(0,0,0). and(0,1,0). and(1,0,0). and(1,1,1). or(0,0,0). or(0,1,1). or(1,0,1). or(1,1,1). % Definicja przykładowego układu - xor xor(Input1,Input2,Output) :- not(Input1,N1), not(Input2,N2), and(Input1,N2,N3), and(Input2,N1,N4), or(N3,N4,Output). % Przykładowe testy: % xor(1,0,W), xor(1,I,1), xor(I1,I2,0)
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)).
)
Ć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ę.
liczby-send.pl
% Fakty: definicja dostępnych cyfr. cyfra(0). cyfra(1). cyfra(2). cyfra(3). cyfra(4). cyfra(5). cyfra(6). cyfra(7). cyfra(8). cyfra(9). % Skrót nazwy predykatu cyfra/1. c(X) :- cyfra(X). % Rozwiązanie dla problemu SEND + MORE = MONEY solve(S,E,N,D,M,O,R,E,Y) :- c(M),M > 0, c(S),c(E), c(N), c(D), c(M), c(O), c(R), c(Y), S \= E, S \= N, S \= D, S \= M, S \= O, S \= R, S \= Y, E \= N, E \= D, E \= M, E \= O, E \= R, E \= Y, N \= D, N \= M, N \= O, N \= R, N \= Y, D \= M, D \= O, D \= R, D \= Y, M \= O, M \= R, M \= Y, O \= R, O \= Y, R \= Y, L1 is S*1000 + E*100 + N*10 + D, L2 is M*1000 + O*100 + R*10 + E, L3 is M*10000 + O*1000 + N*100 + E*10 + Y, Q is (L1 + L2) - L3, % write(Q),nl, Q = 0. sm : - solve(S,E,N,D,M,O,R,E,Y), write(' '),write(S),write(E),write(N),write(D),nl, write('+'),write(M),write(O),write(R),write(E),nl, write(M),write(O),write(N),write(E),write(Y).
Dalsza rozbudowa bazy wiedzy PF, przepisz treść i zadaj pytania podane w LPN.