====== KRR: Prolog - baza wiedzy ======
===== Historia =====
Prolog to system realizujący użycie logiki jako paradygmatu "programowania" (//PROgrammation en LOGique, PROgramming in LOGic//).
Wybrane informacje:
* 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]].
//Uwaga:// nie należy za bardzo przejmować się hasłem o Prologu w Wikipedii -- jest //źle// napisane!
===== Prolog jako system reprezentowania wiedzy i wnioskowania =====
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:
- opis problemu (KB),
- sformułowanie celu (ang. //goal//) czy też pytania (ang. //query//),
- automatyczne wyszukanie rozwiązania.
Co za tym idzie Prolog nie jest "językiem programowania" ile systemem rozwiązywania problemów, obejmującym język ich opisu.
===== 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'').
===== Fakty w bazie wiedzy =====
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.
==== Wczytywanie bazy wiedzy ====
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.
===== Proste pytania =====
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?
===== Generowanie rozwiązań =====
Poza odpowiadaniem na pytania Prolog potrafi wyszukiwać - generować rozwiązania.
Jakie znasz/są/istnieją kobiety?
?- kobieta(Kto).
Kto jest rodzicem?
?- rodzic(R,_).
===== Pytania złożone =====
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 i wnioskowanie =====
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).
===== Wyszukiwanie wszystkich rozwiązań rozwiązań =====
Po niektórych pytaniach można nacisnąć średnik ";"...
===== Bazy danych =====
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)
===== Zapamiętywanie nowych faktów =====
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 {{:pl:prolog:prolog_lab:learner.pl}}
Początkowa baza wiedzy jest w pliku {{:pl:prolog:prolog_lab: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ę//.
===== Dla zaawansowanych =====
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
[[http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse1|LPN]].
===== Źródła =====
* [[http://ai.ia.agh.edu.pl/wiki/pl:prolog:prolog_lab|Prolog Lab]]
* [[http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlch1|Learn Prolog Now]]
* [[http://www.amzi.com/AdventureInProlog|Adventure in Prolog]]
* [[http://ai.ia.agh.edu.pl/wiki/pl:prolog:prolog_lab:constraint_satisfaction_problems|Opisywanie problemów za pomocą ograniczeń]]