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