Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
1
Prolog 3. Using Data Structures
Andrzej Fraś Karol Jeziorski Wojciech Furmanek
2
a + b * c, co jest równoważne + (a, * (b, c))
Struktura drzewa W strukturze drzewa każdy funktor jest węzłem natomiast składniki są gałęziami co umożliwia zagnieżdżanie innych struktur. a + b * c, co jest równoważne + (a, * (b, c))
3
Przykłady sktruktur drzew
Przykład 1: rodzice(Jan, Maria, Ewa) Przykład 2: ksiazka(pan_tadeusz, autor(adam, mickiewicz)
4
Struktura listy Lista jest to ciąg uporządkowanych elementów o dowolnej długości w którym kolejność ma znaczenie. Listę można zapisać w formie specjalnego rodzaju drzewa. Elementami listy mogą być: -stałe -zmienne -struktury -inne listy Pustą listę oznaczamy jako [] W liście wyróżniamy głowę oraz ogon. Ogon oznacza koniec listy zapisywany jako pusta lista.
5
Przykłady list Przykład 1: Lista z jednym elementem „a”: .(a, []),
drzewo listy: Przykład 2: Lista składająca się z atomów (elementów) a, b, c: .(a,.(b,.(c,[]))), drzewo listy: alternatywnie:
6
Przykłady list Poniższa tabelka pokazuje która część listy to głowa a która to ogon Lista Głowa Ogon [a, b, c] a [b, c] [] Brak [[Ala, ma], kota] [Ala, ma] [kota] [Ala, [ma, kota]] Ala [[ma, kota]] [Ala, [ma, czarnego], kota] [[ma, czarnego], kota] [X+Y, x+y] X+Y [x+y]
7
Przeszukiwanie rekurencyjne (Recursive Search)
W prologu w celu sprawdzenia czy dany element znajduje się na liście najpierw sprawdzana jest głowa listy, jeśli w głowie nie ma szukanego elementu to następnie przeszukujemy ogon listy. Za każdym razem sprawdzana jest tylko głowa listy (powstałej z ogona listy poprzedniego sprawdzenia). Gdy natrafimy na pustą listę kończymy przeszukiwanie z negatywnym wynikiem. Zatem klauzula przeszukiwania wygląda następująco: nalezy( X, [X|_]) Jeśli poszukiwany element nie jest w głowie sprawdzamy listę powstałą z „ogona”: nalezy( X, [ _|O]) :- nalezy( X, O)
8
Przeszukiwanie rekurencyjne (Recursive Search) - wykorzystanie
Przeszukiwanie rekurencyjne można wykorzystać na dwa sposoby: Zgodnie z przeznaczeniem tj. do sprawdzania czy dany element należy do listy np. Należy(2, [1, 2, 3]). Uzyskamy true Do uzyskania wszystkich elementów listy np. Należy(X, [1, 2, 3]). Uzyskamy X=1; X=2; X=3
9
Odwzorowanie - mapping
Jest to tzw. Odwzorowanie polegające na przechodzeniu przez kolejne składniki danej struktury tym samym tworząc składniki nowej struktury. Przykładowo: you are a computer i am not a computer do you speak french no i speak german Napisanie programu który dokonałby takiego mapowania polega na wykonaniu kilku prostych kroków: Wprowadzenie zdania od użytkownika Zamiana każdego „you” na „i” Zamiana „are” na „am not” Zamiana każdego „french” na „german” Zamiana „do” na „no”
10
Odwzorowanie – mapping – alter
Aby rozpoznać powiązanie pomiędzy strukturą wejściową a wyjściową używamy predykatu alter. Predykat alter(X, Y) oznacza, iż listę X zamieniamy na listę Y. Po zdefiniowaniu predykatu alter zapytanie powinno wyglądać: ?-alter([do,you,speak,french], X) Na co program powinien odpowiedzieć: X=[no,i,speak,german]. Głównym zadaniem jakie spełnia alter jest zamiana słowa(głowy)H na słowo(głowę)Y oraz zamiana listy(ogona)T na listę(ogon) Y. Odbywa się to poprzez stworzenie bazy zawierającej wyrażenia change(X, Y) oraz pozostawienie bez zmian wyrażeń które owej zmiany nie wymagają change(X, X). W naszym przypadku baza będzie wyglądała następująco: change(you, i) change(are, [am, not]) change(french, german) change(do, no) change(X, X)
11
Odwzorowanie – mapping – alter
Zamieniając pseudokod na kod Prologa dostaniemy: alter([], []). Alter([H|T], [X|Y]):- change (H, X), alter(T, Y) Przykład: ?-alter([you, are, a, computer], Z) Gdzie: H – you, T – [are, a, computer] Następnie: change(you, X) gdzie X – i (X jest głową listy) oraz alter([are, a, computer], Y) Następnie: change(are, Z) gdzie Z – [am, not] oraz alter([a, computer], Y) Jako, że zarówno „a” jak i „computer” nie ma w naszej bazie w związku z czym zachodzi change(X, X). Finalnie alter natrafia na pustą listę co kończy mapping dając wynik: Z=[i,[am,not],a,computer]
12
Łączenie struktur danych - append
W celu łączenia ze sobą list w prologu wykorzystujemy predykat append. Przykładowy predykat append może mieć postać: append([a, b, c], [3, 2, 1], [a, b, c, 3, 2, 1]) Najczęściej wykorzystujemy go aby: Utworzyć nową listę z dwóch osobnych list ?- append([alpha, beta], [gamma, delta], X). X = [alpha, beta, gamma, delta] Znaleźć jedną ze składowych list ?-append(X, [b,c,d],[a,b,c,d]). X=[a]
13
Łączenie struktur danych - append
Definicja predykatu append wygląda następująco: append([], L, L). append([X|L1], L2, [X|L3]) :- append(L1, L2, L3) Warunek brzegowy definicji: Każda lista połączona z pustą listą pozostaje bez zmian. W przeciwnym wypadku: Pierwszy element pierwszej listy (X) będzie zawsze pierwszym elementem listy trzeciej Ogon pierwszej listy (L1) połączony z drugim argumentem predykatu append (L2) zawsze utworzy ogon trzeciej listy (L3).
14
Akumulator Akumulatory to nie tyle element języka Prolog co metoda pisania programu pozwalająca na iteracyjne tworzenie wyniku w każdym przejściu pętli. Zdarzają się problemy w przypadku których sam wynik nie jest dla nas wystarczający. Przykładowo chcąc dostać się pociągiem z miasta A do miasta B (pomiędzy którymi nie ma bezpośredniego połączenia) przyda nam się dokładniejsza informacja niż tylko true lub false. Właśnie w takich przypadkach przyda nam się akumulator będący listą przesiadek. Przykład: Posiadamy następujący zbiór połączeń bezpośrednich: con(gliwice,wroclaw). con(wroclaw,warszawa). con(wroclaw,katowice). con(katowice,warszawa). con(katowice,wroclaw). Dla zapytania przesiadka(A,B,L) potrzebowali będziemy dodatkowej listy-akumulatora, tak więc zacząć musimy od tego że przesiadka/3 (czyli z 3 argumentami) jest spełniona wtedy gdy spełniona jest przesiadka/4 (czyli z dodatkowym akumulatorem)
15
Akumulator przesiadka(A,B,L) :- Aku = [B], przesiadka(A,B,L,[B]),!.
Jeśli szukam połączenia z A do B to szukam takiego C, z którego mogę dojechać do B. Dopisuję więc C na listę miast odwiedzonych, i szukam połączenia z A do C. (...) Jeśli szukam połączenia z A do X, ale X=A (tzn. z miasta początkowego do niego samego) to znaczy że zbudowałem listę przesiadek z A do B, W takim przypadku zwrócę tę listę i zakończę pracę. Załóżmy, że szukamy połączenia z Gliwic do Warszawy (Aku = [warszawa]), więc szukam takiego X, żeby miało połączenie z Warszawą X= Wrocław Szukam połączenia z Gliwic do Wrocławia (Aku = [wroclaw|warszawa]), więc szukam takiego X, żeby miało połączenie z Wrocławiem X= Gliwice Szukam połączenia z Gliwic do Gliwic(Aku = [gliwice|wroclaw,warszawa]), więc mam przypisać L=Aku i zakończyć pracę. Co w kodzie będzie wyglądało następująco: przesiadka(A,B,L) :-Aku = [B], przesiadka(A,B,L,Aku),!. przesiadka(A,A,L,Aku) :- L=Aku. przesiadka(A,B,L,Aku) :- con(X,B), Aku2 = [X|Aku] , przesiadka(A,X,L,Aku2).
16
Prolog 4. Backtracking and the ”Cut”
Andrzej Fraś Karol Jeziorski Wojciech Furmanek
17
Mechanizm nawracania Mechanizm odcięcia pozwala zaniechać nawracania przez Prolog do wcześniej dokonanych wyborów. Zajmijmy się na początek mechanizmem nawracania. Załóżmy, iż mamy w bazie: a(b,c). a(b,d). a(e,f). a(d,g).
18
Mechanizm nawracania Wydając zapytanie ?- a(X,Y).
otrzymamy następujacy ciąg odpowiedzi X = b Y = c ; X = b Y = d ; X = e Y = f ; X = d Y = g ; No
19
Mechanizm nawracania Dzięki nawracaniu znajdowane są wszystkie rozwiązania z bazy danych. Prolog w żadnym przypadku nie analizuje, czy też nie zapamiętuje zwracanych wyników. Stąd też wynikiem zapytania ?- a(X,_). X = b ; X = e ; X = d ; No
20
Mechanizm nawracania Pamiętajmy, że w Prologu istotna jest kolejność występowania faktów i reguł. Dla programu a(c). a(X) :- b(X). b(d). b(e). a(f). a(g). b(h). a(i).
21
Mechanizm nawracania Efektem zapytania a(X) jest: ?- a(X). X = c ;
X = d ; X = e ; X = h ; X = f ; X = g ; X = i ; No Zapytaniem unifikuje się reguła a(X) :- b(X)., w związku z czym Prolog będzie starał się obliczyć wszystkie cele z niej wynikające, czyli w tym przypadku b(X).
22
Mechanizm nawracania – z dwoma celami
Przykład z dwoma celami mającymi po kilka rozwiązań: a(X,Y) :- b(X), c(Y). b(d). b(e). b(f). c(g). c(h). c(i).
23
Mechanizm nawracania – z dwoma celami
Uzyskujemy wynik: ?- a(X,Y). X = d Y = g ; X = d Y = h ; X = d Y = i ; X = e Y = g ; X = e Y = h ; X = e Y = i ; X = f Y = g ; X = f Y = h ; X = f Y = i ; No
24
Mechanizm nawracania – przykład z nieskończoną ilość rozwiązań
Przykład wygenerowania nieskończoną ilość rozwiązań is_integer(0). is_integer(X) :- is_integer(Y), X is Y+1. wtedy otrzymymy wszystkie kolejne liczby całkowite począwszy od 0. ?- is_integer(X). X = 0 ; X = 1 ; X = 2 ; ... itd.
25
Mechanizm nawracania – przykład z nieskończoną ilość rozwiązań
26
Mechanizm nawracania – przykład z nieskończoną ilość rozwiązań
27
Odcięcie Aby choć trochę kontrolować sposób realizacj programu w Prologu możemy używać operatora odcięcia: !. Jeśli Prolog natrafi na operator odcięcia w regule, nie będzie nawracał z wyborem do wcześniejszych możliwości. Przyjrzyjmy się następującemu. a(X, Y) :- b(X), !, c(Y). b(d). b(e). b(f). c(g). c(h). c(i).
28
Odcięcie Po wydaniu zapytania a(X,Y). Prolog udzieli następujących odpowiedzi: ?- a(X,Y). X = d Y = g ; X = d Y = h ; X = d Y = i ; No Jak widać Prolog jako jedyne odpowiedzi wybrał te, dla których X skonkretyzowane zostało przez d.
29
Co nazywamy odcięciem? Można powiedzieć, że działanie rozciąga się na wszystkie kolejne pojawienia się tych zmienych w programie. A więc, ! przesuwa początek reguły do miejsca pojawienia się w niej i redukuje ilość zmiennych w dalszym kodzie programu.
30
Przykład facility(Pers, Fac) :- book_overdue(Pers, Book), !, basic_facility(Fac) facility(Pers, Fac):-general_facility(Fac). basic_facility(reference). basic_facility(enquiries). additional_facility(borrowing). additional_facility(inter_library_loan). general_facility(X) :- basic_facility(X). general_facility(X) :- additional_facility(X).
31
Przykład cd. client(’A.Jones’). client(’W.Metesk’). book_overdue(’C.Watzer’, book10089). book_overdue(’A.Jones’, book29907). ?- client(X), facility(X, Y).
34
Przykład 2 sum_to(N, 1):- N=<1,!. sum_to(N, R):- N1 is N-1, sum_to(N1, R1), R is R1+N. ?- sum_to(5, X). X = 15;
Podobne prezentacje
© 2025 SlidePlayer.pl Inc.
All rights reserved.