|
|
pl:dydaktyka:krr:lab_baza_wiedzy [2013/02/27 09:33] gjn [Źródła] |
pl:dydaktyka:krr:lab_baza_wiedzy [2019/06/27 15:50] |
====== 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. | |
| |
<code prolog> | |
rodzic(kasia,robert). | |
rodzic(tomek,robert). | |
rodzic(tomek,eliza). | |
| |
kobieta(kasia). | |
kobieta(eliza). | |
| |
mezczyzna(tomek). | |
mezczyzna(robert). | |
</code> | |
| |
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//: | |
| |
<code prolog> | |
woman(mia). | |
woman(jody). | |
woman(yolanda). | |
playsAirGuitar(jody). | |
party. | |
</code> | |
| |
==== 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: | |
<code prolog> | |
matka(M,D) :- | |
rodzic(M,D), | |
kobieta(M). | |
| |
ojciec(O,D) :- | |
rodzic(O,D), | |
mezczyzna(O). | |
</code> | |
| |
| |
pf2.pl | |
<code prolog> | |
happy(yolanda). | |
listens2Music(mia). | |
listens2Music(yolanda):- happy(yolanda). | |
playsAirGuitar(mia):- listens2Music(mia). | |
playsAirGuitar(yolanda):- listens2Music(yolanda). | |
</code> | |
| |
===== Wyszukiwanie wszystkich rozwiązań rozwiązań ===== | |
| |
Po niektórych pytaniach można nacisnąć średnik ";"... | |
| |
| |
===== Bazy danych ===== | |
| |
<code prolog> | |
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,_,_,_). | |
</code> | |
| |
Brak I/O | |
<code prolog> | |
% 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) | |
</code> | |
| |
===== 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 | |
<code prolog> | |
% 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). | |
| |
</code> | |
| |
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ń]] | |
| |