Programowanie w logice Wyklad z baz danych dla studentów

Transkrypt

Programowanie w logice Wyklad z baz danych dla studentów
Programowanie w logice
Wykład z baz danych dla studentów matematyki
Zbigniew Jurkiewicz, Instytut Informatyki UW
18 maja 2015
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Programowanie w logice
Programowanie w logice to podejście do programowania,
w którym na program patrzymy nie jak na opis krok po
kroku pewnego sekwencyjnego algorytmu, lecz jak na
teorie˛ logiczna.
˛
Przy tym podejściu koncentrujemy sie˛ na deklaratywnej
specyfikacji co jest problemem do rozwiazania,
˛
a nie na
proceduralnej specyfikacji jak ma on być rozwiazany.
˛
Takie jezyki
˛
programowania oparte sa˛ na rachunku
predykatów pierwszego rz˛edu, wiec
˛ bliskie sa˛ koncepcjom
relacyjnych baz danych.
Przy tym podejściu wywołanie procedury to twierdzenie do
udowodnienia, przekazywane do interprtera jako
zapytanie.
Wykonanie programu odpowiada poszukiwaniu dowodu.
W konsekwencji zmienne w programowaniu w logice maja˛
bardziej matematyczny charakter — można na nie
przypisać wartość tylko raz.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Prolog
Prolog jest najpopularniejszym jezykiem
˛
do
programowania w logice.
Oczywiście nie jest możliwe nauczenie programowania w
Prologu w trakcie pojedynczego wykładu (ani nawet pełne
opisanie go).
Pobieżna znajomość pojeć
˛ programowania w logice
pozwoli nam jednak lepiej zrozumieć źródła dedukcyjnych
baz danych, którymi zajmiemy sie˛ na nastepnym
˛
wykładzie.
Bedziemy
˛
zatem poznawać Prolog głównie przez
przykłady programów.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Warszawskie metro
Warszawskie metro ma (na razie) tylko półtorej linii, ale w
zupełności wystarczy to na pierwszy przykład użycia
Prologu.
Rozpoczniemy od zapisania faktów: informacji o kolejności
stacji na linii
connected(bielany,słodowiec).
connected(słodowiec,marymont).
connected(marymont,placWilsona).
connected(placWilsona,dworzecGdański).
...
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Składnia
Prolog używa dla literałów składni z rachunku predykatów
predykat(term,...term)
Nazwy zmiennych (identyfikatory) musza˛ rozpoczynać sie˛
wielka˛ litera˛ lub znakiem podkreślenia (‘_’)’.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Zapytania
Prologu można używać jak prostej bazy danych.
Najpierw dowiemy sie˛ od interpretera, czy Marymont i Plac
Wilsona sa˛ ze soba˛ połaczone.
˛
| ?- connected(marymont,placWilsona).
yes
Nastepnie
˛
zapytamy o stacje połaczone
˛
z Marymontem
| ?- connected(marymont,X).
X = placWilsona
yes
W zapytaniu użyliśmy zmiennej X. Interpreter zwrócił
wartość zwiazan
˛
a˛ ze zmienna˛ X jako jedyna˛ odpowiedź.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Zapytania
Spytajmy teraz o wszystkie połaczenia
˛
| ?- connected(Start,End).
Start = bielany
End = słodowiec ? ;
Start = słodowiec
End = marymont ? a
Start = marymont
End = placWilsona
Start = placWilsona
End = dworzecGdański
no
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Reguły
Zdefiniujemy dwie stacje jako położone blisko jeśli sa˛ one
połaczone
˛
bezpośrednio lub pomiedzy
˛
nimi jest tylko jedna
stacja.
W rachunku predykatów wyglada
˛ to tak
∀x∀y .connected(x, y ) =⇒ blisko(x, y )
∀x∀y .∀z.connected(x, z) ∧ connected(z, y )) =⇒ blisko(x, y )
Możemy teraz zapisać te formuły jako reguły Prologu
blisko(X,Y) :- connected(X,Y).
blisko(X,Y) :- connected(X,Z),connected(Z,Y).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Reguły
Najpierw łatwe zapytanie
| ?- blisko(bielany,marymont).
yes
Teraz oczekujemy kilku odpowiedzi
| ?- blisko(bielany,What).
What = słodowiec ? ;
What = marymont
yes
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Definiowanie silni
Wprowadzenie do jezyka
˛
programowania nie liczy sie,
˛ jeśli nie
obejmuje silni (albo najwiekszego
˛
wspólnego dzielnika). Pora
wiec
˛ na nia˛
Najpierw definicja funkcyjna
0! = 1
n! = n · (n − 1)!
dla n > 0.
która˛ przekształcimy na relacje˛ factorial
factorial(0, 1)
(∀n)(∀f )n > 0 ∧ factorial(n − 1, f ) =⇒ factorial(n, n · f )
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Definiowanie silni
Pora na Prolog
factorial(0,1).
factorial(N,F) :- N > 0,
N1 is N - 1,
factorial(N1,F1),
F is N * F1.
Nieco testów
| ?- factorial(0,1).
true ?
(1 ms) yes
| ?- factorial(3,X).
X = 6 ?
(1 ms) yes
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Wyrażenia w Prologu
Nasz program składa sie˛ z dwóch klauzul.
Pierwsza z nich to klauzula unarna: tylko nagłówek, bez
treści. Jest to skrót nastepuj
˛ acego
˛
zapisu:
factorial(0,1) :- true.
Klauzule unarne bez zmiennych służa˛ do zapisywania
pojedynczych faktów.
Druga klauzula to reguła, ponieważ posiada niepusta˛ treść.
Treść to wszystkie literały nastepuj
˛ ace
˛ po ’:-’ (możemy go
czytać „jeśli”).
Literały w treści oddzielamy przecinkami, przecinek pełni
role˛ operatora koniunkcji.
Argumenty literałów nazyweamy termami.
Jeśli identyfikator zawarty w termie rozpoczyna sie˛ wielka˛
litera,
˛ to jest to zmienna, w przeciwnym razie jest to stała.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Wyrażenia w Prologu
Klauzule maja˛ intepretacje˛ deklaratywna˛
Klauzula pierwsza mówi: „silnia 0 wynosi 1”.
Klauzula druga mówi: „silnia N wynosi F jeśli N > 0 oraz
jeśli N1 oznacza N − 1, to silnia N1 wynosi F 1 i
F = N ∗ F 1”.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Zapytania
Chcac
˛ obliczyć silnie˛ od 3 musimy podać w zapytaniu zmienna,
˛
na której ma znaleźć sie˛ wynik — niech to bedzie
˛
W:
?- factorial(3,W).
W=6
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Graf obliczeń
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Zapytania
W zapytaniu nie musza˛ wystapić
˛ zmienne:
?- factorial(3,6).
yes
?- factorial(5,2).
no
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Inna definicja silni
silnia(N,F) :- silnia1(N,1,F).
silnia1(0,F,F).
silnia1(N,A,F) :N > 0,
A1 is N * A,
N1 is N - 1,
silnia1(N1,A1,F).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Inna definicja silni
Wprowadziliśmy dodatkowy parametr pełniacy
˛ role˛
akumulatora.
Dzieki
˛ temu nasza definicja ma postać iteracyjna,
˛
ponieważ wywołanie rekurencyjne jest redukcyjne.
Ale nic za darmo: płacimy za to zmniejszona˛ czytelnościa.
˛
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Kolorowanie map
Zasada:
Żadne dwa sasiaduj
˛
ace
˛ regiony nie moga˛ mieć tego
samego koloru.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Mapa
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Sasiedztwo
˛
Informacje o sasiedztwie
˛
można w Prologu zapisać
nastepuj
˛ aco:
˛
adjacent(1,2).
adjacent(1,3).
adjacent(1,4).
adjacent(1,5).
adjacent(2,3).
adjacent(2,4).
adjacent(3,4).
adjacent(4,5).
adjacent(2,1).
adjacent(3,1).
adjacent(4,1).
adjacent(5,1).
adjacent(3,2).
adjacent(4,2).
adjacent(4,3).
adjacent(5,4).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Sasiedztwo
˛
Po załadowaniu faktów do interpretera można badać
sasiedztwo
˛
regionów:
?- adjacent(2,3).
yes
?- adjacent(5,3).
no
?- adjacent(3,R).
R = 1 ;
R = 2 ;
R = 4 ;
no
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Kolorowania
Kolorowania także możemy opisać klauzulami unarnymi.
color(1,red,a).
color(2,blue,a).
color(3,green,a).
color(4,yellow,a).
color(5,blue,a).
color(1,red,b).
color(2,blue,b).
color(3,green,b).
color(4,blue,b).
color(5,green,b).
Kolorowania oznaczyliśmy symbolami a i b.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Kolorowania
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Konflikty
Błedne
˛
kolorowanie musi zawierać konflikt — dwa sasiednie
˛
regiony pokolorowane tym samym kolorem:
conflict(Coloring) :adjacent(X,Y),
color(X,Color,Coloring),
color(Y,Color,Coloring).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Konflikty
Teraz możemy zbadać nasze kolorowania:
?- conflict(a).
no
?- conflict(b).
yes
?- conflict(Which).
Which = b
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Konflikty (3)
Konfliktowość mozna też zdefiniować inaczej:
conflict(R1,R2,Coloring) :adjacent(R1,R2),
color(R1,Color,Coloring),
color(R2,Color,Coloring).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Polimorfizm
Prolog dopuszcza równoczesne definiowanie predykatów o tej
samej nazwie i różnej liczbie parametrów, wewnetrznie
˛
nazywajac
˛ je ’conflict/1’ i ’conflict/3’.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Wiecej
˛
o konfliktach
Możemy poznać konfliktowe regiony, a nawet ich (wspólny)
kolor
?R1
?R1
conflict(R1,R2,b).
= 2
R2 = 4
conflict(R1,R2,b),color(R1,C,b).
= 2
R2 = 4
C = blue
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Rozpoznawanie zwierzat
˛
Spróbujmy na koniec napisać program rozpoznajacy
˛ gatunki
zwierzat
˛ podstawie zaobserwowanych faktów oraz wiedzy
zawartej w faktach i regułach.
zoolog :- hypothesize(Zwierzak),
write(’Przypuszczam, że ten zwierzak to: ’),
write(Zwierzak),
nl,
undo.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Hipotezy
hypothesize(gepard)
:hypothesize(tygrys)
:hypothesize(żyrafa)
:hypothesize(zebra)
:hypothesize(struś)
:hypothesize(pingwin) :hypothesize(albatros) :hypothesize(nie_wiem).
Zbigniew Jurkiewicz, Instytut Informatyki UW
gepard, !.
tygrys, !.
żyrafa, !.
zebra, !.
struś, !.
pingwin, !.
albatros, !.
/* nie udało si˛
e */
Programowanie w logice
Wykład z baz danych dla
Reguły identyfikacji
gepard :- ssak,
drapieżnik,
verify(ma_płowy_kolor),
verify(ma_ciemne_plamy).
tygrys :- ssak,
drapieżnik,
verify(ma_płowy_kolor),
verify(ma_czarne_paski).
żyrafa :- kopytny,
verify(ma_długa_szyj˛
˛
e),
verify(ma_długie_nogi).
zebra :- kopytny,
verify(ma_czarne_paski).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Reguły identyfikacji
struś :- ptak,
verify(nie_lata),
verify(ma_długa_szyj˛
˛
e).
pingwin :- ptak,
verify(nie_lata),
verify(pływa),
verify(jest_czarnobiały).
albatros :- ptak,
verify(wyst˛
epuje_w_opowieściach_morskich),
verify(dobrze_lata).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Reguły klasyfikacji
ssak
ssak
ptak
ptak
::::-
drapieżnik
drapieżnik
kopytny :kopytny :-
verify(ma_sierść), !.
verify(daje_mleko).
verify(ma_pióra), !.
verify(lata),
verify(znosi_jajka).
:- verify(je_mi˛
eso), !.
:- verify(ma_ostre_z˛
eby),
verify(ma_pazury),
verify(ma_oczy_z_przodu).
ssak,
verify(ma_kopyta), !.
ssak,
verify(przeżuwacz).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Zadawanie pytań
ask(Pytanie) :write(’Czy zwierzak ma nast˛
epujac
˛ a˛ cech˛
e: ’),
write(Pytanie),
write(’? ’),
read(Odpowiedz),
nl,
( (Odpowiedz == tak ; Odpowiedz == t)
->
assert(tak(Pytanie)) ;
assert(nie(Pytanie)), fail).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Weryfikacja
verify(S) :- tak(S), true, !.
verify(S) :- nie(S), fail, !.
verify(S) :- ask(S).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Zapamietywanie
˛
odpowiedzi
Aby uniknać
˛ wielokrotonego zadawania tych samych pytań:
Po otrzymaniu odpowiedzi tak na pytanie P zapisujemy te˛
informacje˛ jako fakt
tak(P).
Podobnie po otrzymaniu odpowiedzi nie na pytanie P
zapisujemy te˛ informacje˛ jako fakt
nie(P).
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla
Czyszczenie faktów tak/nie
Po zakończeniu konwersacji troche˛ ekologii — trzeba po sobie
posprzatać
˛
undo :- retract(tak(_)),fail.
undo :- retract(nie(_)),fail.
undo.
Zbigniew Jurkiewicz, Instytut Informatyki UW
Programowanie w logice
Wykład z baz danych dla

Podobne dokumenty