6 listopada 2010
1 U»ycie klauzul
2 U»ycie struktur
3 Zmienne i ich ukonkretnianie
Prolog jest realizacj¡ paradygmatu "PROgraming in LOGic", opartego na metodzie rezolucji zastosowanej do j¦zyków I-go rz¦du.
Denicja
Formuªa w postaci klauzulowej jest klauzul¡ hornowsk¡ lub programow¡, je±li jest uniwersalna: wszystkie zmienne w niej wyst¦puj¡ce s¡ zwi¡zane kwantykatorem uniwersalnym, a ka»da klauzula zawiera co najwy»ej jeden literaª pozytywny.
Klauzule hornowskie mog¡ wi¦c mie¢ nast¦puj¡cy ksztaªt:
1 Faktu: ∀x1. . . ∀xnr(t1, . . . ,tm), gdzie r jest symbolem relacji, ti termami.
2 Reguªy: ∀x1. . . ∀xnq1∧ . . . ∧qm⇒q, gdzie qi,q s¡ literaªami.
Literaª q jest postaci r(t1, . . . ,tm). Wtedy r nazywamy nagªówkiem reguªy lub faktu.
3 Klauzuli celu: ∀x1. . . ∀xnq1∧ . . . ∧qm⇒, która jest logicznie równowa»na z ∀x1. . . ∀xn¬(q1∧ . . . ∧qm).
Denicja
Program logiczny to sko«czony zbiór faktów i reguª. Procedur¡
nazywamy podzbiór klauzul o tym samym nagªówku.
Przykªad 1.
lubi(jan, waniliowe). (1)
lubi(karol, pistacjowe). (2)
lubi(adam, waniliowe). (3)
lubi(jan, pistacjowe). (4)
bratni(X , Y ) : −lubi(X , Z), lubi(Y , Z). (5) Najprostsze pytania:
lubi(jan,waniliowe).
lubi(karol,waniliowe).
Ogólniejsze:
lubi(jan,X).
Co lubi jan? lubi(X,Y).
Wyszukanie wszystkich par lubi¡cych si¦. Mo»emy u»y¢ zmiennych do wyra»enia zale»no±ci. Nazwa zmiennej u»ytej w pytaniu nie ma zwi¡zku z rzeczywist¡ zmienn¡. W istocie s¡ to nazwy typu _G123.
Rozwa»my trudniejszy przykªad:
bratni(jan,adam).
bratni(jan,karol).
bratni(X,jan).
W szczególno±ci otrzymamy, »e jan jest bratni ze sob¡.
bratni(X,Y).
Ogólniejszy od poprzedniego.
Sk¡d takie zale»no±ci si¦ bior¡? Z ukonkretniania zmiennych.
W jakiej roli wyst¦puj¡ struktury?
Przypomnijmy najpierw kilka denicji:
1 Struktura to twór postaci funktor(listaParametrów), gdzie parametry s¡ atomami, zmiennymi lub innymi strukturami, rozdzielonymi przecinkami.
2 Term to staªa, zmienna lub struktura.
3 Staªa mo»e by¢ atomem (skªadnia jak typowy identykator zaczynaj¡cy si¦ od maªej litery lub napis uj¦ty w apostrofy) lub liczb¡. System typów Prologu jest niezbyt rozbudowany i zazwyczaj obejmuje liczby caªkowite, zmiennopozycyjne oraz napisy, przy czym napisy w podwójnych cudzysªowach uto»samiane s¡ z list¡ kodów znaków, za± napisy w apostrofach z atomami.
4 Nazwy zmiennych zaczynaj¡ si¦ od du»ej litery.
Struktury mog¡ wyst¦powa¢ zarówno w roli danych, jak i w roli zbli»onej do funkcji w klasycznych j¦zykach programowania.
W rozwa»anym dotychczas przykªadzie struktury z funktorem lubi uznaliby±my zapewne za dane, natomiast struktur¦ z funktorem bratni za co± w rodzaju funkcji. Podziaª ten jest jednak sztuczny i bierze si¦ po prostu z naszych przyzwyczaje«. Prolog traktuje wszystkie struktury tak samo, wykorzystuj¡c je w uzgodnieniach.
Zauwa»my, »e do naszego programu mogliby±my doda¢ klauzul¦:
lubi(_, pistacjowe).
Mo»na j¡ interpretowa¢ jako stwierdzenie, »e wszyscy lubi¡
pistacjowe. W tej sytuacji funktor lubi przestaje oznacza¢ tylko dane... Zauwa»my, »e taka klauzula pozwala interpreterowi odpowiedzie¢ twierdz¡co np. na poni»sze pytania:
lubi(X, pistacjowe). lubi(lip, pistacjowe). lubi(lip, _).
Równie» pytaj¡c lubi(lip, X).
dostaniemy sensown¡ odpowied¹: X = pistacjowe.
Uwaga techniczna je±li jaka± zmienna wyst¦puje w klauzuli tylko raz, to nale»y j¡ zapisa¢ jako zmienn¡ anonimow¡, czyli znak podkre±lenia. Taka sytuacja oznacza, »e warto±¢ tej zmiennej nie b¦dzie potrzebna w »adnym innym miejscu. W szczególno±ci dwa wyst¡pienia znaku podkre±lenia oznaczaj¡ dwie zupeªnie nie zwi¡zane ze sob¡ zmienne anonimowe. Tak wi¦c np. klauzula zna(X, X) oznacza ka»dy zna samego siebie, natomiast zna(_, _)
ka»dy zna ka»dego. Zmienna anonimowa u»yta we wpisanym celu oznacza, »e nie chcemy zna¢ warto±ci, jakie interpreter nada tej zmiennej, próbuj¡c osi¡gn¡¢ cel.
Powró¢my do kwestii reprezentowania danych przez struktury prologowe. Przykªad struktur z funktorem lubi kojarzy nam si¦ by¢
mo»e nie tyle z reprezentacj¡ obiektów pierwotnych bazy danych (czyli, powiedzmy, rekordów w tabeli w relacyjnej bazie danych), co raczej z reprezentacj¡ zale»no±ci mi¦dzy takimi obiektami.
Popatrzmy wi¦c na taki przykªad:
pracownik(imi¦(jan), nazwisko(kowalski), adres(ulica(dªuga), nr(2), miasto (kraków)), telefon('0123456789')).
pracownik(imi¦(jerzy), nazwisko(nowak), adres(ulica(krótka), nr(123), miasto(kraków)), telefon('0987654321')).
U»yli±my tu zagnie»d»onych struktur do reprezentacji danych pracowników. W potocznym rozumieniu owi pracownicy s¡
obiektami pierwotnymi. Zauwa»my jednak, »e w Prologu sposób reprezentowania jest w obydwu przypadkach w istocie taki sam.
Reprezentacja taka jak powy»ej daje nam mo»liwo±ci podobne do rekordów przy znacznie wi¦kszej elastyczno±ci. Przyjrzyjmy si¦
ponownie pracownikom:
1 Funktor pracownik u»yty jest w roli podobnej do nazwy typu.
2 Funktory imi¦, nazwisko itp. speªniaj¡ rol¦ analogiczn¡ do pól rekordu.
3 Atomy i liczby zachowuj¡ si¦ jak warto±ci pól.
Mamy tu obiekty (pracowników) opisane w sposób samoistny bez odwoªywania si¦ do zewn¦trznych denicji typów. Mechanizm ten, chocia» nie pozwala np. na statyczne sprawdzenie zgodno±ci typu, ma cechy przyzwoitego typowania. Otó» wszelkie
wykorzystanie takich obiektów musi nast¦powa¢ przez uzgodnienie, a »eby ono si¦ powiodªo, konieczna jest peªna zgodno±¢ struktur (nazwy, arno±ci i podstruktury). Dodajmy, »e atomy mo»na traktowa¢ jako funktory zeroargumentowe.
Zmienne w Prologu s¡ zupeªnie odmienne od zmiennych w j¦zykach imperatywnych i tylko troch¦ podobne do zmiennych w j¦zykach funkcyjnych. Owo podobie«stwo polega na tym, »e zmienna prologowa nie mo»e dowolnie zmienia¢ warto±ci tak, jak si¦ to dzieje przy podstawieniach tych zreszt¡ w ogóle w Prologu nie ma. W Prologu nadawanie warto±ci zmiennym nast¦puje w wyniku uzgodnie«; b¦dziemy o nich mówili obszerniej w drugiej cz¦±ci wykªadu.
Ukonkretnianie zmiennych
Zmienna w programie prologowym reprezentuje zupeªnie nieokre±lony byt, bez typu. W trakcie oblicze«, w rezultacie uzgodnie« nast¦puje ukonkretnianie zmiennej, czyli bli»sze
okre±lenie bytu reprezentowanego przez zmienn¡. Ów byt b¦dziemy nazywali konkretyzacj¡ zmiennej.
Ukonkretnienie mo»e by¢ caªkowite zmienna uto»samia si¦
wówczas z termem niezawieraj¡cym zmiennych i nie podlega dalszemu ukonkretnianiu.
W tym momencie mo»na j¡ postrzega¢ jak zainstancjonowan¡
zmienn¡ w programie funkcyjnym. Ukonkretnienie mo»e jednak by¢
tylko cz¦±ciowe zmienna reprezentuje wtedy term, który wci¡»
zawiera inne zmienne, i mo»e by¢ ukonkretniana dalej.
Ciekawym przypadkiem jest ukonkretnienie, które nast¦puje przy uzgadnianiu dwóch dotychczas nieukonkretnionych zmiennych. Nie pojawia si¦ wtedy »aden bardziej szczegóªowy opis struktury reprezentowanej przez zmienn¡, gdy» obydwie zmienne na razie reprezentuj¡ byty nieokre±lone. Dwie zmienne zostaj¡ natomiast uto»samione, czyli odt¡d ka»de wyst¡pienie i ukonkretnienie jednej z nich odnosi si¦ tak samo do drugiej.
Ukonkretnienie zmiennej nie mo»e zosta¢ zmienione na inne, mo»e natomiast zosta¢ anulowane w wyniku nawrotu. Generalnie odnosi si¦ to do ostatniego etapu ukonkretnienia zmienna wraca do poprzedniej konkretyzacji, a nie do stanu caªkowicie nie
ukonkretnionego. Tu ponownie odsyªamy Czytelnika do drugiej cz¦±ci wykªadu.
Przykªady ukonkretniania
Rozwa»my teraz par¦ przykªadów ukonkretnienia.
Przykªad pierwszy: mamy dotychczasowy program o lodach"i wpisujemy cel bratni(jan, X). W pierwszym etapie nast¦puje dopasowanie owego celu do denicji bratni(X, Y), co skutkuje dwoma uzgodnieniami:
1 Atom jan zostaje dopasowany do zmiennej X z denicji. W rezultacie zmienna X zostaje ukonkretniona do warto±ci jan.
2 Zmienna X z celu zostaje uzgodniona ze zmienn¡ Y z denicji.
W rezultacie powstaje jedna zmienna.
3 Oczywi±cie zmienna X, której konkretyzacj¡ jest atom jan, nie ma nic wspólnego z t¡ drug¡.
Przykªad drugi: mamy w programie opisanych wcze±niej pracowników i wpisujemy cel pracownik(X, Y, Z, telefon('0123456789')). Cel pasuje do denicji jednego, konkretnego pracownika, a zatem mamy trzy uzgodnienia z nast¦puj¡cymi skutkami:
1 Zmienna X zostaje ukonkretniona do imi¦(jan).
2 Zmienna Y zostaje ukonkretniona do nazwisko(kowalski).
3 Zmienna Z zostaje ukonkretniona do adres(ulica(dªuga), nr(2), miasto(kraków)).
Zauwa»my, »e warto±ciami zmiennych staj¡ si¦ tu caªe struktury, a nie pojedyncze atomy. Druga obserwacja to to, »e interpretera Prologu mo»na u»y¢ wprost jako mechanizmu wyszukiwania w bazie danych podajemy znane elementy (tu: telefon), a interpreter znajduje wszystkie pasuj¡ce rekordy.
Przykªad trzeci: ponownie mamy baz¦ pracowników; wpisujemy cel pracownik(imi¦(X), nazwisko(Y), adres(A1, A2, A3), telefon(Z)).
Tym razem cel pasuje do obydwu pracowników, wi¦c mamy jeden zestaw ukonkretnie«, nawrót (a wi¦c anulowanie ukonkretnie«) i drugi zestaw. Konkretyzacje zmiennych X, Y, A1, A2, A3 i Z w poszczególnych zestawach to oczywi±cie dane dwóch pracowników:
1 X = jan, Y = kowalski, A1 = ulica(dªuga), A2 = nr(2), A3 = miasto(kraków), Z = '0123456789'.
2 X = jerzy, Y = nowak, A1 = ulica(krótka), A2 = nr(123), A3
= miasto(kraków), Z = '0987654321'.
W przypadku zmiennych X, Y i Z dotarli±my tu ju» do atomów, natomiast w przypadku A1, A2 i A3 otrzymujemy struktury, gdy»
na tym poziomie zagnie»d»enia odbyªo si¦ uzgodnienie.
Dwa ostatnie przykªady pokazuj¡, »e uzgodnienia mog¡ by¢ na ró»nych poziomach zagnie»d»enia. Pozwala to zadawa¢ pytania o ró»nym stopniu szczegóªowo±ci. Trzeba natomiast pami¦ta¢, »e zawsze nale»y przestrzega¢ arno±ci funktora. A zatem niepoprawne, wªa±nie ze wzgl¦du na niewªa±ciw¡ arno±¢, s¡ cele:
1 pracownik(imi¦(X), nazwisko(Y), adres(A), telefon(Z)).
2 pracownik(imi¦(X), nazwisko(Y), adres(A1, A2), telefon(Z)).