2. Plan prezentacji
• Formuły (rachunek zdań)
• Rezolucja
• Termy i unifikacja
• Program w Prologu (rachunek predykatów)
• SLD-rezolucja i niedeterminizm
• Korutyny
Uwaga: to są notatki (formalnie będzie na wykładzie)
3. Literatura
• William F. Clocksin, Chris Mellish. Prolog.
Programowanie, Helion, 2003.
• Robert Kowalski. Logika w
rozwiązywaniu zadań, WNT, 1989.
• Jan Wielemaker. SWI-Prolog 6.0.
Reference Manual, University of
Amsterdam, 2012.
4. Formuły i
wartościowanie
• Postać CNF
• Literały
• Formuły jako zbiory
• Wartościowanie
• Spełnialność
8. Wartościowanie
• Każdej zmiennej przypisuje się wartość
równą TRUE albo FALSE.
• Wartościowanie zmiennych jednoznacznie
wyznacza wartość formuły.
9. Spełnialność
• Formuła jest spełnialna gdy istnieje
wartościowanie, w którym ma ona wartość
TRUE.
• Wartościowanie spełnia formułę, gdy ma
ona w nim wartość TRUE.
• Spełnić formułę = spełnić każdą jej klauzulę.
• Spełnić klauzulę = spełnić któryś jej literał.
10. • Klauzula zawierająca
komplementarną parę literałów jest
spełniona przez każde wartościowanie.
• Klauzula pusta nie jest spełniona przez
żadne wartościowanie.
• Formuła pusta jest spełniona przez każde
wartościowanie.
12. Logiczna konsekwencja
• Wartościowanie spełniające zbiór formuł
nazywamy modelem dla tych formuł.
• Formułę C nazywamy
logiczną konsekwencją zbioru formuł A
wtedy i tylko wtedy, gdy każde
wartościowanie będące modelem dla A
spełnia C.
• Zapis A ⊧ C wyraża, że formuła C jest
logiczną konsekwencją zbioru formuł A.
13. Zasada rezolucji
• Niech C i C2 będą dwiema klauzulami
1
zawierającymi komplementarne literały,
odpowiednio, L1 i L2.
• Mówimy, że klauzule C i C kolidują.
1 2
• Rezolwentą kolidujących klauzul C i C
1 2 jest
klauzula res(C1, C2)=(C1-{L1})∪(C2-{L2}).
•C 1i C2 są przesłankami a rezolwenta
res(C1, C2) jest konkluzją z tych przesłanek.
15. • Formuła A ⊧ C iff zbiór formuł A∪{¬C} nie
jest spełnialny.
• Zbiór formuł nie jest spełnialny gdy można
bezpośrednio lub pośrednio wyprowadzić z
niego rezolwentę będącą klauzulą pustą.
18. • dokładnie jedna spośród zmiennych {p, q, r}
ma wartość TRUE
F1={{p, q, r}, {¬p, ¬q}, {¬p, ¬r}, {¬q, ¬r}}
• dokładnie dwie spośród zmiennych {q, r, s}
ma wartość TRUE
F2={{¬q, ¬r, ¬s}, {q, r}, {q, s}, {r, s}}
19. • Założenia:
A = F1 ∪ F2
• Czy A ⊧ ¬p? Czy A ⊧ s?
• Czy A∪{p} jest sprzeczny? Czy z A∪{p}
można wyprowadzić klauzulę pustą?
• Czy A∪{¬s} jest sprzeczny? Czy z A∪{¬s}
można wyprowadzić klauzulę pustą?
23. Termy i unifikacja
• Stałe i zmienne
• Termy złożone
• Podstawienia, składanie podstawień
• Uzgadnianie i unifikator
• Najbardziej ogólny unifikator
24. Zmienne i stałe
• Stałe zapisywane są najczęściej jako
identyfikatory alfanumeryczne
rozpoczynające się małą literą.
• Dowolny ciąg znaków może być stałą jeśli
umieści się go między apostrofami '...'.
• Stałymi są również liczby całkowite i
rzeczywiste.
26. • Zmienne zapisuje się jako identyfikatory
alfanumeryczne rozpoczynające się od
wielkiej litery.
• Szczególną rolę odgrywa zmienna
anonimowa _ (podkreślenie) oznaczająca
nieistotną wartość.
• Stałe i zmienne to termy proste.
28. Termy złożone
• Termy złożone buduje się łącząc
pewną liczbę termów w jeden.
• Do łączenia służą funktory.
• Funktory zapisuje się jako identyfikatory
alfanumeryczne rozpoczynające się od
małej litery.
30. • Szczególną rolę odgrywa funktor . (kropka)
łączący pierwszy element listy (głowę) z
listą pozostałych elementów (ogonem).
• Stała [ ] (dwa kwadratowe nawiasy)
oznacza listę pustą.
[]
.(a, [ ])
.(a, .(b, [ ]))
.(.(a, [ ]), .(.(a, .(b, [ ])), [ ]))
31. • Czytelny dla człowieka zapis listy polega na
wymienieniu między nawiasami
kwadratowymi kolejnych elementów
oddzielonych przecinkami.
[]
[a] = .(a, [ ])
[a, b] = .(a, .(b, [ ]))
[[a], [a, b]] = .(.(a, [ ]), .(.(a, .(b, [ ])), [ ]))
32. • W zapisie list pionową kreską | można
oddzielać początkowe elementy od listy
pozostałych.
[a] = [a | [ ]]
[a, b] = [a | [b]] = [a, b | [ ]]
[a,b,c] = [a|[b,c]] = [a,b|[c]] = [a,b,c|[ ]]
33. Podstawienia
• Podstawieniem nazywamy zbiór {X ←t , 1 1
X2←t2, ..., Xn←tn}, gdzie X1, X2, ..., Xn są
różnymi zmiennymi a t1, t2, ..., tn
są dowolnymi termami.
• Podstawienia oznaczamy literami alfabetu
greckiego.
• Podstawienie ∅ oznaczamy literą ε.
34. • Zastosowanie podstawienia δ do termu t
zapisujemy tδ.
• Jeśli t jest stałą, to tδ=t.
• Jeśli t jest zmienną X podstawianą w δ, to
i
tδ=ti.
• Jeśli t jest zmienną niepodstawianą w δ, to
tδ=t.
• Jeśli t jest termem złożonym f(s , s , ..., s
1 2 m),
to tδ=f(s1δ, s2δ, ..., smδ).
35. • Złożeniem δ={X ←t , X ←t , ..., X ←t } z
1 1 2 2 n n
σ={Y1←s1,Y2←s2, ...,Ym←sm} jest
podstawienie δσ uzyskane ze zbioru
{X1←t1σ, X2←t2σ, ..., Xn←tnσ,Y1←s1,
Y2←s2, ...,Ym←sm}, przez wykreślenie tych
Xi←tiσ, w których tiσ=Xi oraz tych Yj←sj,
że Yj ∈ {X1, X2, ..., Xn}.
36. • Złożenie podstawień δσ ma tę własność, że
dla dowolnego termu t zachodzi:
t(δσ)=(tδ)σ.
37. Uzgadnianie
• Mówimy, że dwa termy t i s są uzgadnialne
jeśli istnieje podstawienie δ, tż. tδ=sδ.
• Podstawienie δ uzgadniające termy t i s
nazywamy unifikatorem termów t i s.
• Nie każde dwa termy są uzgadnialne.
38. term t term s unifikator
a b brak
a a ε
X a {X←a}
X Y {X←Y}
para(a, b) para(X,Y) {X←a,Y←b}
para(a, b) para(X, X) brak
X f(X) brak1)
f(A, B, C) f(a, g(A, A), g(B, B)) {A←a, B←g(a,a), C←g(g(a,a),g(a,a))}
1) W unifikatorze nie można podstawiać pod zmienną termu, który ją zawiera.
39. Najbardziej ogólny
unifikator
• Mówimy, że unifikator δ jest najbardziej
ogólnym unifikatorem dla termów t i s, jeśli
dla każdego unifikatora σ, termów t i s,
istnieje podstawienie μ tż. σ=δμ.
• Najbardziej ogólny unifikator termów t i s
oznacza się mgu(t, s) (ang. most general
unifier).
40. • Podstawienie σ={X←a,Y←a, Z←a} jest
unifikatorem termów f(X,Y) i f(Z, Z) ale
najbardziej ogólnym ich unifikatorem jest
δ={X←Z,Y←Z}.
• Podstawieniem ukonkretniającym
najbardziej ogólny unifikator δ do postaci σ
jest μ={Z←a}.
41. Algorytm unifikacji
• Układ równań na termach {t =s , t =s , ...,
1 1 2 2
tk=sk} jest w postaci rozwiązanej jeśli {t1,
t2, ..., tk} są różnymi zmiennymi i żadna z
nich nie występuje w termach {s1, s2, ..., sk}.
• Postaci rozwiązanej odpowiada
podstawienie {t1←s1, t2←s2, ..., tk←sk}.
• Algorytm unifikacje przekształca układ
równań na termach do postaci rozwiązanej.
42. let S be the set {t1=s1, t2=s2, ..., tk=sk};
repeat
select t=s from S;
case t=s of
X = X:
remove t=s from S;
f(u1, u2, ..., un)=g(w1, w2, ..., wm) where n≠m or f≠g:
return FALSE;
f(u1, u2, ..., un)=f(w1, w2, ..., wn):
replace t=s with u1=w1, u2=w2, ..., un=wn;
u=X where u is not a variable:
replace t=s with s=t;
X=u where u contains X:
return FALSE;
X=u and X occurs in the other equation:
substitute u for X in the other equations;
end case;
until S does not change;
45. {f(A, B, C, D) = f(a, g(A, A), g(B, B), g(C, C)}
{A = a, B = g(A, A), C = g(B, B), D = g(C, C)}
{A = a, B = g(a, a), C = g(B, B), D = g(C, C)}
{A = a, B = g(a, a), C = g(g(a, a), g(a, a)), D = g(C, C)}
{A = a, B = g(a, a), C = g(g(a, a), g(a, a)), D = g(g(g(a, a),
g(a, a)), g(g(a, a), g(a, a)))}
46. Program w Prologu
• Klauzule Horna
• Predykaty
• Składnia Prologu
• Przykłady programów i zapytań
47. Klauzule Horna
• Szczególną rolę odgrywają w Prologu
klauzule, które zawierają dokładnie jeden
literał pozytywny.
• Klauzule z dokładnie jednym literałem
pozytywnym nazywa się klauzulami Horna.
• Tylko literał pozytywny = fakt.
• Literał pozytywny i literały negatywne =
reguła.
• p∨¬q ∨¬q ∨...∨¬q
1 2 k ≡ (q1∧q2∧...∧qk)→p
48. Rozpatrzmy klauzule {{pada}, {¬pada, mokro}}.
Program w Prologu:
pada.
mokro :- pada.
Zadane pytanie:
?- mokro.
true.
Negacja warunku podanego w pytaniu zostaje
dołączona do programu i system stara się wyprowadzić
klauzulę pustą stosując zasadę rezolucji.
49. Predykaty
• Predykat to warunek wyrażający
relację między obiektami opisanymi
termami.
• Niech stałe jan i adam reprezentują ludzi.
• Dwuargumentowy predykat rodzic(jan,
adam) wyraża relację między Adamem i
jego rodzicem Janem.
• Jednoargumentowy predykat
mezczyzna(jan) wyraża, że Jan jest
mężczyzną.
50. • Predykat ojciec(X,Y), wyrażający
relację między osobą Y i jej ojcem X, można
zapisać w postaci reguły ojciec(X,Y) :-
rodzic(X,Y), mezczyzna(X).
• Reguła dziadek(X, Z) :- ojciec(X,Y),
rodzic(Y, Z) definiuje relację między
dziadkiem X a wnukiem/wnuczką Z.
51. Składnia Prologu
TERM ::= STAŁA | ZMIENNA | FUNKTOR ( TERMY )
TERMY ::= TERM | TERM , TERMY
ATOM ::= PREDYKAT | PREDYKAT ( TERMY )
ATOMY ::= ATOM | ATOM , ATOMY
KLAUZULA ::= FAKT | REGUŁA
FAKT ::= ATOM .
REGUŁA ::= ATOM :- ATOMY .
PROGRAM ::= KLAUZULA | KLAUZULA PROGRAM
52. Przykład 1
?- a = a.
true.
?- a = b.
false.
?- f(a, b) = f(X, Y).
X = a,
Y = b.
?- f(a, b) = f(X, X).
false.
?- f(A, B, C, D) = f(a, g(A, A), g(B, B), g(C, C)).
A = a,
B = g(a, a),
C = g(g(a, a), g(a, a)),
D = g(g(g(a, a), g(a, a)), g(g(a, a), g(a, a))).
55. Przykład 3
element(X, para(X, _)).
element(X, para(_, X)).
?- P = para(a, para(b, c)), element(E, P), element(E2, E).
P = para(a, para(b, c)),
E = para(b, c),
E2 = b ;
P = para(a, para(b, c)),
E = para(b, c),
E2 = c ;
false.
56. Przykład 4
element(X, para(X, _)).
element(X, para(_, X)).
wystepuje_w(X, Y) :- element(X, Y).
wystepuje_w(X, Z) :- element(Y, Z), wystepuje_w(X, Y).
?- P = para(a, para(b, c)), wystepuje_w(E, P).
P = para(a, para(b, c)),
E = a ;
P = para(a, para(b, c)),
E = para(b, c) ;
P = para(a, para(b, c)),
E = b ;
P = para(a, para(b, c)),
E = c ;
false.
61. SLD-wywód
• Cel ma postać A , A , ..., A , gdzie każde A
1 2 n i
jest atomem.
• Z programu wybierana jest klauzula postaci
B0 :- B1, B2, ..., Bk, dla której po
przemianowaniu zmiennych istnieje
unifikator δ=mgu(A1, B0).
• Nowym celem jest (B , B , ..., B , A , ..., A )δ.
1 2 k 2 n
• Wywód kończy się sukcesem, jeśli cel
zostaje zredukowany do klauzuli pustej .
62. Wyliczona odpowiedź
• Jeśli w SLD-wywodzie zakończonym
sukcesem znajdowano kolejno unifikatory
δ1, δ2, ..., δm, to wyliczoną odpowiedzią jest
złożenie podstawień δ1δ2... δm ograniczone
do zmiennych występujących w zadanym
celu.
63. Możliwe SLD-wywody
• sukces = SLD-wywód zakończony pustym
celem
• niepowodzenie = SLD-wywód
zakończony niepustym celem, którego nie
można dalej przekształcać zgodnie z SLD-
rezolucją.
• nieskończony SLD-wywód
64. SLD-drzewo
• Wszystkie SLD-wywody danego celu
można zebrać w postaci SLD-drzewa.
• W korzeniu SLD-drzewa znajduje
się zadany cel.
• Każda gałąź SLD-drzewa to jeden SLD-
wywód.
• Każdy węzeł w SLD-drzewie ma skończenie
wiele synów ale niektóre gałęzie
mogą być nieskończone.
70. Odraczanie celu
• Cel X = 2, X > 1 kończy się powodzeniem.
• Cel X > 1, X = 2 kończy się błędem.
• Sprawdzenie warunku X > 1 należy
odroczyć do czasu gdy zmienna X przyjmie
wartość.
• Dzięki odraczaniu celów Prolog może
być bardziej deklaratywny (koniunkcja
znowu jest przemienna).
71. Predykat freeze/2
• Meta-predykat freeze(Var, Goal) odracza
sprawdzenie celu Goal do chwili gdy
zmienna Var przyjmie wartość.
• Cel sprawdzany jest natychmiast po tym jak
zmienna przyjmie wartość.
• Niepowodzenie celu powoduje
natychmiastowe wycofanie się.
72. ?- freeze(X, X > 1), X = 2.
X = 2.
?- freeze(X, writeln(x=X)), freeze(Y, writeln(y=Y)),
f(X, Y) = f(a, b).
x=a
y=b
X = a,
Y = b.
?- freeze(X, writeln(x=X)), freeze(Y, writeln(y=Y)),
f(Y, X) = f(a, b).
y=a
x=b
X = b,
Y = a.
73. ?- freeze(X, (writeln(x=X), Z = c)), freeze(Y, writeln(y=Y)),
freeze(Z, writeln(z=Z)), f(X, Y) = f(a, b).
x=a
z=c
y=b
X = a,
Z = c,
Y = b.
?- X = Y, X = a, Y = b.
false.
?- freeze(X, freeze(Y, X = Y)), X = a, Y = b.
X = a,
Y = b.
?- freeze(X, freeze(Y, X = Y)), X = a.
X = a,
freeze(Y, a=Y).
?- freeze(X, freeze(Y, X = Y)), Y = b.
Y = b,
freeze(X, freeze(b, X=b)).
74. Predykat when/2
• Meta-predykat when(Condition, Goal)
odracza sprawdzenie celu Goal do
momentu gdy warunek Condition będzie
spełniony.
• Warunek Condition może mieć
następującą postać: (X ?= Y), nonvar(X),
ground(X), (Cond1, Cond2) lub (Cond1;
Cond2).
• freeze(X, G) ≡ when(nonvar(X), G) ≢
when(ground(X), G)
75. ?- freeze(X, writeln(x=X)), X = f(Y), Y = a.
x=f(_G430)
X = f(a),
Y = a.
?- when(ground(X), writeln(x=X)), X = f(Y), Y = a.
x=f(a)
X = f(a),
Y = a.
?- when((nonvar(X), nonvar(Y)), writeln(f(X, Y))), X = a, Y = b.
f(a,b)
X = a,
Y = b.
?- when((nonvar(X); nonvar(Y)), writeln(f(X, Y))), X = a, Y = b.
f(a,_G424)
X = a,
Y = b.
76. Predykat dif/2
• Predykat dif(Term , Term ) narzuca
1 2
ograniczenie, że termy Term1 i Term2 są
różnymi termami.
• Jeśli Term
1 i Term2 nie są unifikowalne, to
dif(Term1, Term2) jest natychmiast spełniony.
• Jeśli Term
1 i Term2 są identyczne, to
dif(Term1, Term2) natychmiast zawodzi.
• Jeśli Term
1i Term2 mogą zunifikować się,
wówczas dif(Term1, Term2) odracza warunki
zapewniające różność Term1 i Term2.
77. ?- dif(f(X, Y), f(X, Y)).
false.
?- dif(f(X, a), f(b, b)).
true.
?- dif(f(X, Y), f(Y, X)).
dif(Y, X).
?- dif(f(X, a), f(b, Y)).
dif(f(X, Y), f(b, a)).
?- dif(f(X, a), f(b, Y)), X = a.
X = a.
?- dif(f(X, a), f(b, Y)), X = b.
X = b,
dif(f(b, Y), f(b, a)).
?- dif(f(X, a), f(b, Y)), X = b, Y = a.
false.
78. Listy otwarte
• Lista otwarta reprezentuje strumień
termów, przy czym w strumieniu tym
mogą pojawiać się kolejne termy.
• Pusty strumień reprezentowany jest
nieukonkretnioną zmienną _.
• Kolejne termy wpisywane są do
nieukonkretnionego ogona otwartej listy.
79. • Pusty strumień termów S spełnia warunek
warunek var(S).
• Jeśli strumień termów S nie jest pusty, to
unifikuje się on ze wzorcem [H | T], gdzie H
jest zmienną, pod którą podstawiany jest
pierwszy term w strumieniu S, natomiast T
jest zmienną, pod którą podstawiany jest
strumień pozostałych termów.
• Aby zakończyć strumień termów S należy
zunifikować go z listą pustą [ ].
81. Przykład 1
generowanie 1, 2, 3, 4, 5 podwajanie 2, 4, 6, 8, 10 drukuj
2
4
6
?- X = 0, Y = X+1. 8
10
X = 0,
Y = 0+1.
?- X is 0, Y is X+1.
X = 0,
Y = 1.
?- (a = a -> X = tak; X = nie).
X = tak.
?- (a = b -> X = tak; X = nie).
X = nie.
82. generowanie(I, J, S) :-
( I =< J
-> S = [I | T],
I1 is I+1,
generowanie(I1, J, T)
; S = []).
?- generowanie(1, 5, S).
S = [1, 2, 3, 4, 5] .
83. zle_drukuj([]).
zle_drukuj([H | T]) :-
writeln(H),
zle_drukuj(T).
?- zle_drukuj(S).
S = [] ;
_G2871
S = [_G2871] ;
_G2874
S = [_G2871, _G2874] ;
_G2877
S = [_G2871, _G2874, _G2877] .
?- zle_drukuj(S), generowanie(1, 5, S).
_G2917
_G2920
_G2923
_G2926
_G2929
S = [1, 2, 3, 4, 5] .