You are on page 1of 156

Programowanie w logice

Prolog
Piotr Fulmaski
Piotr Fulmaski
1
Wydzia Matematyki i Informatyki,
e-mail: fulmanp@math.uni.lodz.pl Uniwersytet dzki
Banacha 22, 90-238, d
Polska
Data ostaniej modykacji: 18 maja 2009
Spis treci
Wstp i
1 Podstawy 1
1.1 Zdumiewajcy pocztek . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Obiekty i relacje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2.1 Obiekt klasyczny . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2.2 Obiekt w Prologu . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Program w Prologu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3.1 Struktura i skadnia . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3.2 Praca z programem zapytania . . . . . . . . . . . . . . . . . . . . 8
1.4 Pytania i odpowiedzi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2 Skadnia Prologu 11
2.1 Termy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2 Klauzule, program i zapytania . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3 Pytania i odpowiedzi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3 Ewaluacja zapytania 21
3.1 Dopasowywanie wyrae . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2 Obliczanie celu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.3 Pytania i odpowiedzi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4 Listy 33
4.1 Skadnia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.2 Gowa i ogon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.3 Pytania i odpowiedzi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5 Odcicie 41
5.1 Wiele rozwiza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.2 Odcicie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
5.3 Pytania i odpowiedzi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
6 Wejcie i wyjcie. Operatory 53
6.1 Czytanie i pisanie termw . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.1.1 Czytanie termw . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.1.2 Pisanie termw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.2 Czytanie i pisanie znakw . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.2.1 Czytanie znakw . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
4 SPIS TRECI
6.2.2 Pisanie znakw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.3 Czytanie z pliku i pisanie do pliku . . . . . . . . . . . . . . . . . . . . . . 57
6.3.1 Czytanie z pliku . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.3.2 Pisanie do pliku . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
6.4 Operatory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
6.4.1 Priorytet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
6.4.2 -xowo operatora . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.4.3 czno . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.4.4 Deniowanie wasnych operatorw . . . . . . . . . . . . . . . . . . 63
6.5 Pytania i odpowiedzi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
7 Predeniowane predykaty 67
7.1 Sprawdzanie typu termw . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
7.2 Konstruowanie i dekompozycja termw . . . . . . . . . . . . . . . . . . . . 69
7.3 Podstawienia, funktor, argument . . . . . . . . . . . . . . . . . . . . . . . 71
7.4 Rne rnoci, rne rwnoci . . . . . . . . . . . . . . . . . . . . . . . . 71
7.5 Manipulowanie baz danych . . . . . . . . . . . . . . . . . . . . . . . . . . 73
7.6 Pytania i odpowiedzi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
8 Powtarzamy wiadomoci 75
8.1 O rekurencji raz jeszcze . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
8.1.1 Sposb 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
8.1.2 Sposb 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
8.1.3 Sposb 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
8.1.4 Sposb 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
8.2 Akumulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
8.2.1 Przykad z list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
8.2.2 Przykad z liczbami . . . . . . . . . . . . . . . . . . . . . . . . . . 77
8.3 Z gry na d czy od dou do gry? . . . . . . . . . . . . . . . . . . . . . . 78
8.3.1 Z gry na d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
8.3.2 Z dou do gry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
8.4 Pytania i odpowiedzi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
9 Sortowanie 81
9.1 Sortowanie naiwne . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
9.2 Sortowanie bbelkowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
9.3 Sortowanie przez wstawianie . . . . . . . . . . . . . . . . . . . . . . . . . . 86
9.4 Sortowanie przez czenie . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
9.5 Pytania i odpowiedzi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
10 Od problemu do jego (efektywnego) rozwizania 91
10.1 Rebus i jego pierwsze rozwizanie . . . . . . . . . . . . . . . . . . . . . . . 91
10.2 Rozwizanie drugie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
10.3 Rozwizanie trzecie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
10.4 Rozwizanie czwarte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
10.5 Rozwizanie pite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
10.6 Rozwizanie szste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
10.7 Rozwizanie sidme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
SPIS TRECI 5
11 Efektywny Prolog 99
11.1 Czy tylko deklaratywno? . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
11.2 Zmniejsza przestrze rozwaa . . . . . . . . . . . . . . . . . . . . . . . . 100
11.3 Niech pracuj za nas inni . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
11.4 Pracuj na gowie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
11.5 . . . albo odcinaj to co zbdne . . . . . . . . . . . . . . . . . . . . . . . . . 103
12 Rachunek zda 105
12.1 Posta normalna . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
12.1.1 Przeksztacanie do postaci normalnej . . . . . . . . . . . . . . . . . 110
12.2 Formua Horna . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
12.3 twierdzenie tutu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
12.4 Rezolucja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
12.5 Pytania i odpowiedzi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
13 wiczenia 115
13.1 wiczenie 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
13.1.1 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
13.1.2 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
13.1.3 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
13.1.4 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
13.1.5 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
13.2 wiczenie 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
13.2.1 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
13.2.2 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
13.2.3 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
13.2.4 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
13.2.5 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
13.2.6 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
13.2.7 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
13.3 wiczenie 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
13.3.1 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
13.3.2 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
13.3.3 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
13.3.4 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
13.3.5 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
13.3.6 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
13.3.7 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
13.3.8 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
13.3.9 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
13.3.10Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
13.3.11Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
13.4 wiczenie 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
13.4.1 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
13.4.2 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
13.4.3 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
13.4.4 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
13.4.5 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
6 SPIS TRECI
13.4.6 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
13.5 wiczenie 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
13.5.1 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
13.5.2 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
13.5.3 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
13.5.4 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
13.5.5 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
13.6 wiczenie 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
13.6.1 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
13.6.2 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
13.7 wiczenie 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
13.7.1 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
13.7.2 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
13.8 wiczenie 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
13.8.1 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
13.8.2 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
13.8.3 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
13.9 wiczenie 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
13.9.1 Zadanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
14 Rozwizania wicze 129
14.1 Odpowiedzi do zadania 13.1 . . . . . . . . . . . . . . . . . . . . . . . . . . 130
14.1.1 Odpowiedzi do zadania 13.1.1 . . . . . . . . . . . . . . . . . . . . . 130
14.1.2 Odpowiedzi do zadania 13.1.2 . . . . . . . . . . . . . . . . . . . . . 130
14.1.3 Odpowiedzi do zadania 13.1.3 . . . . . . . . . . . . . . . . . . . . . 131
14.1.4 Odpowiedzi do zadania 13.1.4 . . . . . . . . . . . . . . . . . . . . . 131
14.1.5 Odpowiedzi do zadania 13.1.5 . . . . . . . . . . . . . . . . . . . . . 132
14.2 Odpowiedzi do zadania 13.2 . . . . . . . . . . . . . . . . . . . . . . . . . . 133
14.2.1 Odpowiedzi do zadania 13.2.1 . . . . . . . . . . . . . . . . . . . . . 133
14.2.2 Odpowiedzi do zadania 13.2.2 . . . . . . . . . . . . . . . . . . . . . 133
14.2.3 Odpowiedzi do zadania 13.2.3 . . . . . . . . . . . . . . . . . . . . . 133
14.2.4 Odpowiedzi do zadania 13.2.4 . . . . . . . . . . . . . . . . . . . . . 133
14.2.5 Odpowiedzi do zadania 13.2.5 . . . . . . . . . . . . . . . . . . . . . 134
14.2.6 Odpowiedzi do zadania 13.2.6 . . . . . . . . . . . . . . . . . . . . . 134
14.2.7 Odpowiedzi do zadania 13.2.7 . . . . . . . . . . . . . . . . . . . . . 134
14.3 Odpowiedzi do zadania 13.3 . . . . . . . . . . . . . . . . . . . . . . . . . . 135
14.3.1 Odpowiedzi do zadania 13.3.1 . . . . . . . . . . . . . . . . . . . . . 135
14.3.2 Odpowiedzi do zadania 13.3.2 . . . . . . . . . . . . . . . . . . . . . 135
14.3.3 Odpowiedzi do zadania 13.3.3 . . . . . . . . . . . . . . . . . . . . . 135
14.3.4 Odpowiedzi do zadania 13.3.4 . . . . . . . . . . . . . . . . . . . . . 135
14.3.5 Odpowiedzi do zadania 13.3.5 . . . . . . . . . . . . . . . . . . . . . 135
14.3.6 Odpowiedzi do zadania 13.3.6 . . . . . . . . . . . . . . . . . . . . . 135
14.3.7 Odpowiedzi do zadania 13.3.7 . . . . . . . . . . . . . . . . . . . . . 135
14.3.8 Odpowiedzi do zadania 13.3.8 . . . . . . . . . . . . . . . . . . . . . 135
14.3.9 Odpowiedzi do zadania 13.3.9 . . . . . . . . . . . . . . . . . . . . . 136
14.3.10Odpowiedzi do zadania 13.3.10 . . . . . . . . . . . . . . . . . . . . 136
14.3.11Odpowiedzi do zadania 13.3.11 . . . . . . . . . . . . . . . . . . . . 136
14.4 wiczenie 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
SPIS TRECI 7
14.4.1 Odpowiedzi do zadania 13.4.1 . . . . . . . . . . . . . . . . . . . . . 137
14.4.2 Odpowiedzi do zadania 13.4.2 . . . . . . . . . . . . . . . . . . . . . 137
14.4.3 Odpowiedzi do zadania 13.4.3 . . . . . . . . . . . . . . . . . . . . . 137
14.4.4 Odpowiedzi do zadania 13.4.4 . . . . . . . . . . . . . . . . . . . . . 137
14.4.5 Odpowiedzi do zadania 13.4.5 . . . . . . . . . . . . . . . . . . . . . 137
14.4.6 Odpowiedzi do zadania 13.4.6 . . . . . . . . . . . . . . . . . . . . . 137
14.5 wiczenie 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
14.5.1 Odpowiedzi do zadania 13.5.1 . . . . . . . . . . . . . . . . . . . . . 138
14.5.2 Odpowiedzi do zadania 13.5.2 . . . . . . . . . . . . . . . . . . . . . 138
14.5.3 Odpowiedzi do zadania 13.5.3 . . . . . . . . . . . . . . . . . . . . . 138
14.5.4 Odpowiedzi do zadania 13.5.4 . . . . . . . . . . . . . . . . . . . . . 138
14.5.5 Odpowiedzi do zadania 13.5.5 . . . . . . . . . . . . . . . . . . . . . 138
14.6 wiczenie 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
14.6.1 Odpowiedzi do zadania 13.6.1 . . . . . . . . . . . . . . . . . . . . . 139
14.6.2 Odpowiedzi do zadania 13.6.2 . . . . . . . . . . . . . . . . . . . . . 140
14.7 wiczenie 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
14.7.1 Odpowiedzi do zadania 13.7.1 . . . . . . . . . . . . . . . . . . . . . 142
14.7.2 Odpowiedzi do zadania 13.7.2 . . . . . . . . . . . . . . . . . . . . . 142
14.8 wiczenie 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
14.8.1 Odpowiedzi do zadania 13.8.1 . . . . . . . . . . . . . . . . . . . . . 143
14.8.2 Odpowiedzi do zadania 13.8.2 . . . . . . . . . . . . . . . . . . . . . 143
14.8.3 Odpowiedzi do zadania 13.8.3 . . . . . . . . . . . . . . . . . . . . . 143
14.9 wiczenie 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
14.9.1 Odpowiedzi do zadania 13.9.1 . . . . . . . . . . . . . . . . . . . . . 144
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
8 SPIS TRECI
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Wstp
Niniejszy podrcznik stanowi sformalizowan wersj notatek jakie sporzdzaem dla sie-
bie prowadzc zajcia Programowanie w logice. Cel jaki przywieca mi, to ch poka-
zania, e wiat jzykw programowania nie koczy si na programowaniu obiektowym.
Wykorzystanie jzyka logiki do opisu otaczajcej nas rzeczywistoci odwzorowywanej w
rodowisku komputerowym, daje nam zupenie inn jako i uczy cakowicie odmiennego
spojrzenia na problem programu i jego kodu. I cho przydatno takich jzykw moe
by dyskusyjna
1
to jednak wydaje mi si, e ich elementarna znajomo jest konieczna
dla osb, ktre chc zosta informatykiem.
W prezentowanym materiale gwny nacisk pooony jest na zdobycie praktycznej
umiejtnoci posugiwania si takim jzykiem i jego czucia, ni teorii programowania
w logice. Niemniej pewna cz materiau powicona jest take zagadnieniom natury
teoretycznej. Wybranym jzykiem jest Prolog a wszystkie przykady zostay przetesto-
wane przy uyciu jednej z jego najbardziej popularnych wersji SWI-Prolog
2
w wersji
5.6.59.
Ze wzgldu na form zaj, cao materiau podzielona zostaa na dwie zasadni-
cze cz: wykadow i wiczeniow. Materia kadej z czci powinien wystarczy do
przeprowadzenia semstralnych zaj. Cz wykadowa obejmuje rozdziay ???? i po-
wicona jest nastpujcym zagadnieniom
a
Cz wiczeniowa zawiera materia czy to do samodzielnej pracy, czy te nadajcy
si do przeprowadzenia zaj na pracowni komputerowej. Zbir zada sukcesywnie jest
poszerzany, ale nie jest to wcale takie atwe. Wbrew pozorom trudno jest znale zadania
rne (na tyle, aby ich rozwizanie wymagao przynajmniej w pewnej ich czci innego
podejcia ni zadania poprzednie) i zarazem na tyle atwe aby dao si je w prosty
sposb wytumaczy. Dobrze przy tym aby zadania nie byy cakiem abstrakcyjnym
manipulowaniem symbolami w stylu sztuka dla sztuki. Daltego jeli ktokolwiek czytajc
ten podrcznik wpadnie na jakie nowe zadanie albo alternatywne rozwizanie dla tych
ju podanych, to z wielk chci je zamieszcze.
Na zakoczenie pragn podzikowa (nielicznym niestety) studentom, ktrzy z jednej
strony wykazali zainteresowanie przedmiotem, z drugiej za wzbogacili ten podrcznik a
przede wszystkim:
Pani Magdalenie Zych za opracownie bardzo wyczerpujcych odpowiedzi do pyta
jakie stawiam na koniec kadego rozdziau (wykadu).
1
Wynika to zwykle z problemw zwizanych z wykorzystaniem jzyka logicznego w realnej aplikacji.
2
www.swi-prolog.org
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
ii ROZDZIA 0. WSTP
Panu Krzysztofowi Jastrzbskiemu za mozolne i niestrudzone rozwizywanie zada
jakie stawiaem na wiczeniach.
Piotr Fulmaski
d, 2008
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 1
Podstawy
1.1 Zdumiewajcy pocztek
Ju sama nazwa jzyka Prolog niesie w sobie informacj o jego przeznaczeniu. Sowo
prolog pochodzi bowiem od sformuowania programmation en logique co w jzyku fran-
cuskim oznacza wanie programowanie w logice. Prolog zosta stworzony w 1971 roku
przez Alaina Colmeraurera i Phillipea Roussela. Cho jego teoretyczne podstawy sta-
nowi rachunek predykatw pierwszego rzdu, to jednak ogranicza si tylko do klauzul
Horna (o czym wicej powiemy w rozdziale ??). Jeszcze w pierwszych latach XXI wieku
by bardzo chtnie uywany w wielu programach zwizanych z
logik matematyczn (automatyczne dowodzenie twierdze);
przetwarzaniem jzyka naturalnego;
symbolicznym rozwizywaniem rwna;
sztuczn inteligencj;
przechowywaniem i przetwarzaniem danych.
I cho powoli jego miejsce zajmuj wygodniejsze narzdzia jak na przykad silniki regu-
owe (o czym powiemy w rozdziale ??), to wci stanowi wspaniay model dydaktyczny.
Najwaniejsz i zarazem czsto najbardziej zaskakujc i zdumiewajc rzecz zwi-
zan z Prologiem jest to, e
Pisanie programu w Prologu nie polega na opisywaniu algorytmu!
Jak to? Przecie od lat, z mozoem i w wielkim trudzie wpajano nam do gowy, e zanim
zaczniemy pisa program to musimy uoy odpowiedni algorytm. Gdy si ju tego na-
uczylimy i przyjlimy za pewnik, nagle okazuje si, e wcale tak nie musi by. Niestety
bardzo trudno jest przesta myle algorytmicznie o problemie. Jest to silniejsze od nas,
bo tak nas nauczono. Tym czasem w Prologu istotne jest co zupenie innego. Oto bo-
wiem zamiast opisywa algorytmu, opisujemy obiekty zwizane z problemem i relacje
pomidzy tymi obiektami. Std wanie Prolog czsto bywa okrelany jako jzyk opi-
sowy i deklaratywny. Oznacza to, e implementujc rozwizanie jakiego problemu
nie podajemy jak go rozwiza (jak to ma miejsce w imperatywnych jzykach progra-
mowania tj. C lub Java) ale okrelamy czego on dotyczy uywajac do tego faktw i
regu. Rol Prologu jest wywnioskowanie rozwizania na podstawie podanych przez
nas informacji.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
2 ROZDZIA 1. PODSTAWY
1.2 Obiekty i relacje
Programowanie w Prologu polega na deniowaniu obiektw i okrelaniu wicych
ich relacji. Odmienne jednake od tradycyjnego (tzn. wystpujcego w klasycznym
programowaniu obiektowym) jest pojmowanie obiektu.
1.2.1 Obiekt klasyczny
Pomimo, i zajmujemy si Prologiem to aby uwiadomi sobie co jest w nim tak od-
miennego od innych jzykw, powimy troch miejsca na przypomnienie, czym jest
klasyczny obiekt, znany z takich jzykw jak np. C++ czy Java. W tym ujciu obiekt
to podstawowe pojcie wchodzce w skad paradygmatu obiektowoci w analizie i pro-
jektowaniu oprogramowania oraz w programowaniu. Jego koncepcja ma uatwi cyfrow
reprezentacj realnych obiektw. Czym charakteryzuj si rzeczywiste obiekty?
Obiekty jakie otaczj nas w rzeczywistym wiecie posiadaj dwie istotne cechy: stan
w jakim w danej chwili si znajduj
1
oraz zachowanie jakie dla nich jest typowe. I tak
psy maj swj stan (kolor, wag, s godne lub najedzone. . . ) oraz zachowanie (szczeka-
nie, bieg, leenie, merdanie ogonem. . . ). Take telewizory maj swj stan (wczony lub
wyczony, gono, numer programu. . . ) oraz zachowanie (zmiana gonoci lub pro-
gramu, wczenie, wyczenie. . . ). Prawidowe okrelenie stanu i zachowania ma bardzo
due znaczenie dla dalszego sposobu i komfortu obsugi obiektu w programie.
Obiekt w ujciu jzykw obiektowych jest bardzo podobny do obiektw wiata rze-
czywistego: take posiada stany (cechy) i przypisane jemu zachowanie. Taki obiekt
przechowuje swoje stany w zmiennych zwanych polami a wpyw na jego zachowanie
mamy za porednictwem funkcji, nazywanych te metodami. Metody operujc na po-
lach dostarczaj jednoczenie podstawowych mechanizmw komunikacji obiektobiekt.
Zasada ukrywania stanw wewntrznych obiektu i interakcja z nim tylko poprzez do-
brze zdeniowany zbir metod znana jest pod nazw enkapsulacji danych i stanowi
fundamentaln zasad programowania zorientowanego obiektowo.
Kady utworzony przez programist obiekt jest instancj pewnej klasy. W tym
ujciu, klasa zdeniowana przez programist, staje si nowym typem, ktry moe by
uywany na rwni z typami wbudowanymi. Jako przykad takiej klasy rozwamy klas
Punkt umoliwiajc utworzenie dowolnej iloci obiektw opisujcych (rne) punkty.
class Punkt
{
private:
double x;
double y;
public:
Punkt(double x, double y);
void Przesun(Wektor w);
};
Jeli ponad to zaoymy, e mamy dostpn klas Wektor, wwczas staje si moliwe
napisanie kodu jak poniej
Punkt p(1.0,2.0);
1
Lub cechy jakie posiadaj.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
1.2. OBIEKTY I RELACJE 3
Wektor w(2.5,-1.5);
p.Przesun(w);
Posumowujc:
Programowanie zorientowane obiektowo (ang. OOP, object-oriented programming)
to paradygmat (sposb) programowania posugujcy si pojciem obiektu jako
metody reprezentacji danych w programie.
Kady obiekt, bdcy instancj pewnej klasy, posiada zbir cech (bdcych zmien-
nymi pewnych typw) go opisujcych oraz zbir metod (funkcji) ktrych wywoanie
na rzecz tego obiektu ma sens.
W tym ujciu, klasa zdeniowana przez programist, staje si nowym typem, ktry
moe by uywany na rwni z typami wbudowanymi.
Z OOP nierozerwalnie zwizane s pojcia enkapsulacji danych, dziedziczenia, po-
limorzmu.
Wiedzc czym s, najlepiej chyba wszystkim znane, obiekty z jzykw OOP wystar-
czy teraz powiedzie, e obiekt Prologowy nie jest takim wanie obiektem nawet w
najmniejszej czci. Jaki wic jest?
1.2.2 Obiekt w Prologu
Obiekt w sensie Prologu jest czym, co moemy nazwa bytem. Nie deniujemy z czego
si on skada i co mona z nim zrobi (co ma miejsce w OOP), ale jaki jest. Dodat-
kowo, dla kadego obiektu deniujemy relacje jakim obiekt ten podlega. Przy pomocy
obiektw opisujemy interesujcy nas wycinek wiata. Dziaanie programu prologowego
objawia si moliwoci stawiania pyta zwizanych z uprzednio opisanym wiatem.
Najprostszym sposobem opisu wiata (problemu), jest podanie faktw z nim zwiza-
nych, jak na przykad:
ciezszy(pomarancz,jablko).
ciezszy(jablko,mandarynka).
ciezszy(arbuz,pomarancz).
ciezszy(jablko,winogrono).
Powysze fakty stwierdzaj, e
ciezszy(pomarancz,jablko). pomaracz jest cisza od jabka,
ciezszy(jablko,mandarynka). jabko jest cisze od mandarynki,
itd.
Tak wic powyej okrelilimy kilka obiektw (pomarancz, jablko, itd) i powizalimy
je midzy sob relacj ciezszy wyraajc, ktry z obiektw jest ciszy od innych.
Istotne jest to, e nadal nie jest nam znana masa adnego z obiektw one po prostu
nie posiadaj cech.
Okazuje si zdumiewajce, e ju nawet jeden fakt jest poprawnym (przynajmniej
skadniowo) programem Prologu. Po uruchomieniu takiego programu, moemy zada-
wa pytania zwizane z rzeczywistoci jak opisuje
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
4 ROZDZIA 1. PODSTAWY
?- ciezszy(pomarancz,jablko).
Yes
W ten oto sposb otrzymujemy twierdzc odpowiedz na pytanie: Czy pomaracz jest
cisza od jabka?. Bdc precyzyjniejszym, to pytanie brzmi: Czy wiadomo co na temat
tego, e pomaracz jest cisza od jabka?. Jest to istotne rozrnienie, gdy wwczas
reakcj
?- ciezszy(winogrono,arbuz).
No
naley odczytywa jako: Nic nie wiadomo na temat tego, e winogrono jest cisze od
arbuza. Nie oznacza to jednak, e tak nie jest. Taka interpretacja jest waciwsza, co
pokazuje kolejny przykad
?- ciezszy(arbuz,winogrono).
No
Z podanych faktw, przez przechodnio i znajomo pojcia ciaru moemy wywnio-
skowa, e odpowied powinna by twierdzca, wedug rozumowania
poniewa prawd jest, e
ciezszy(arbuz,pomarancz)
i prawd jest, e
ciezszy(pomarancz,jablko)
i prawd jest, e
ciezszy(jablko,winogrono).
czyli
arbuz > pomarancz > jablko > winogrono
inaczej
arbuz > ... > winogrono
wic prawd jest, e
ciezszy(arbuz,winogrono)
Jednak Prolog nie wie, e w stosunku do relacji ciezszy moe przechodnio stosowa,
w zwizku z czym, w wietle znanych faktw i zwizkw, udziela odpowiedzi ne-
gatywnej. W ten oto sposb dochodzimy do sytuacji, gdy musimy poinformowa Prolog
o pewnych relacjach, czyli okreli reguy.
Zajmijmy si zatem relacj przechodnioci i utworzeniem dla niej odpowiednich regu.
W matematyce relacja (dwuargumentowa) R na zbiorze A, co zapisujemy R A
2
jest
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
1.2. OBIEKTY I RELACJE 5
przechodnia, gdy dla wszystkich elementw a, b, c A, jeeli elementy (a, b) s w relacji
R i elementy (b, c) s w relacji R, to take elementy (a, c) s w relacji R. Jako przykady
takich relacji mona poda np. relacje wikszoci, relacja zawierania zbiorw czy relacj
by rodzestwem. Przechodnia nie jest natomiast relacja rnoci, relacja by rodzicem
czy by przyjacielem. W przypadku rozwaanej przez nas relacji wystarczy doda tak
regu
2
ciezszy(X,Y) :- ciezszy(X,Z),ciezszy(Z,Y).
W powyszej regule symbol :- oznacza jeli (jeli zachodzi prawa strona to zachodzi lewa)
a symbol przecinka (,) peni rol operatora logicznego i (AND). Symbole X, Y oraz Z s
nazwami zmiennych (w Prologu nazwa zmiennej rozpoczyna si od duej litery).
Umieszczajc fakty i regu w jednym pliku (owoce.pl) moemy teraz przetestowa
dziaanie programu. Uruchamiamy zatem interpreter
fulmanp@fulmanp-laptop-fs12:~$ swipl
Welcome to SWI-Prolog (Multi-threaded, Version 5.6.47)
Copyright (c) 1990-2007 University of Amsterdam.
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.
For help, use ?- help(Topic). or ?- apropos(Word).
i wczytujemy program
?- [owoce].
% t compiled 0.00 sec, 1,176 bytes
Yes
Zrbmy test na znajomo elementarnych faktw:
?- ciezszy(pomarancz,jablko).
More? [ENTER]
Yes
Chwilowo pomijamy znaczenie komunikatu More? i naciskamy ENTER gdy si on pokae.
Wszystko si zgadza, zatem pora na test przechodnioci:
?- ciezszy(arbuz,winogrono).
More? [ENTER]
Yes
Tym razem odtrzymalimy odpowied zgodn z oczekiwaniem. Moemy jednak dowie-
dzie si znacznie wicej, zadajc np. pytanie od jakich obiektw jest ciszy arbuz:
2
Regua ta nie do koca jest poprawna i zasadniczo problem powinien zosta rozwizany w inny
sposb, ale na tym etapie poznawania Prologa jest to rozwizanie akceptowalne.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
6 ROZDZIA 1. PODSTAWY
?- ciezszy(arbuz,X).
X = pomarancz [;]
X = jablko [;]
X = mandarynka [;]
X = winogrono [;]
ERROR: Out of local stack
Po wywietleniu kadej z moliwoci, Prolog czeka na nasz decyzj: nacinicie ENTER
oznacza zakoczenie poszukiwania alternatywnych odpowiedzi, rednik (;) oznacza kon-
tynuowanie poszukiwania. Niemiy komunikat pojawiajcy si na kocu
3
naley w tym
przypadku odczyta jako nie wiadomo nic o innych moliwociach (obiektach). Symbol
rednika (;), zgodnie z intuicj, czytamy jako lub (OR). Z operatorw logicznych moemy
skorzysta take podczas formuowania zapytania, np. czy istniej owoce X, Y takie, e
arbuz jest ciszy od X i jednoczenie X jest ciszy od Y :
?- ciezszy(arbuz,X),ciezszy(X,Y).
X = pomarancz,
Y = jablko [;]
X = pomarancz,
Y = mandarynka [ENTER]
Yes
1.3 Program w Prologu
1.3.1 Struktura i skadnia
Wiedzc ju jak naley rozumie pojcie obiektu i regu go opisujcych, moemy spr-
bowa w bardziej kompletny sposb przedstawi struktur i skadni programu Prologo-
wego.
Przede wszystkim, powtrzmy to jeszcze raz, programowanie w Prologu polega na
deniowaniu obiektw i okrelaniu wicych ich relacji. Zatem przystpujc do roz-
wizania jakiego problemu musimy bardzo uwanie si zastanowi
1. z jakimi obiektami mamy do czynienia,
2. jakie relacje (zwizki) cz wytypowane przez nas obiekty.
Musimy przy tym zdawa sobie jasno spraw z kilku faktw.
1. Z punktu widzenia jzyka, obiekty nie s rozrnialne semantycznie. Oznacza to,
e obiekt slon i slonia w poniszych faktach
3
Pomijamy na tym etapie powd jego pojawienia si.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
1.3. PROGRAM W PROLOGU 7
jestDuzy(slon).
lubi(zosia,slonia).
s rnymi obiektami, pomimo tego, e my wiemy i s tym samym.
2. Nie wszystkie relacje jawnie okrelaj wszystkie obiekty, ktrych dotycz.
brakuje mi przykladu
3. Wybr formy relacji (reguy) powinien by wystarczajco precyzyjny aby mg by
potraktowany jak denicja w problemie jaki rozwizujemy.
Praca z Prologiem skada si zwykle z nastpujcych etapw:
1. Deniowanie obiektw poprzez deniowanie faktw dotyczcych obiektw i zwiz-
kw midzy nimi.
2. Deniowanie regu dotyczcych obiektw i zwizkw midzy nimi.
3. Zapytania o obiekty i zwizki midzy nimi.
Podczas zapisywania programu
4
stosujemy nastpujc konwencj.
Nazwy relacji i obiektw musz zaczyna si maymi literami.
Nazwy rozpoczynajce si od duej litery oznaczaj zmienne.
Najpierw zapisujemy relacj, a potem, rozdzielone przecinkami i ujte w nawias
okrgy, obiekty ktrych ona dotyczy.
Nazwy obiektw wystpujcych w nawiasach nazywamy argumentami.
Nazw relacji znajdujcej si przed nawiasem nazywamy predykatem.
Nie mona jako predykatu uy zmiennej. Innymi sowy, nie mona si dowiedzie
jaka relacja czy obiekty jas i malgosia
X(jas,malgosia).
Fakt i regu koczymy znakiem kropki.
Kolejno obiektw umieszczonych w nawiasie jest dowolna, ale trzeba stosowa j
konsekwentnie. O ile bowiem dobrze znanym faktem jest to, e Ala lubi swojego
kota, to nie oznacza to, e kot ten lubi Al.
Zbir faktw i regu nazywamy baz danych.
Skadnia reguy jest nastpujca
<lewaCzesc> :- <prawaCzesc>.
4
Kod programu jest zwykym plikiem tekstowym z rozszerzeniem pl
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
8 ROZDZIA 1. PODSTAWY
co moemy czyta jako
lewaCzesc zachodzi (jest prawd), gdy zachodzi prawaCzesc (jest prawda),
gdzie
<lewaCzesc> to predykat i ewentualne argumenty umieszczone w nawiasach
okrgych, np.
lubi(X,Y)
silnia(0,X)
<prawaCzesc> to jedno lub wicej wyrae atomowych poczonych opera-
torami logicznymi: i (,) oraz lub (;) i poprzedzonych ewentualnie operatorem
negacji (\+). Wyraenie atomowe w tym kontekcie to wyraenie, dla kt-
rego mona obliczy warto logiczn, a ktre nie moe by ju rozoone na
wyraenia prostsze, np.:
N>0
A is B-1
silnia(N,X)
\+ lubi(malgosia,X)
1.3.2 Praca z programem zapytania
Praca z programem Prologowym take odbywa si inaczej ni w innych jzykach progra-
mowania. Raczej trudno mwi o uruchamianiu programu i jego dziaaniu jako samo-
dzielnej i niezalenej aplikacji, gdy programy Prologu z natury s raczej interakcyjne.
Bardziej adekwatnym okreleniem zamiast uruchamianie wydaje si by formuowanie
zapyta lub te interakcyjny tryb zapytanieodpowied
5
.
Zapisany program wczytujemy poleceniem (znaki ?- s tzw. znakiem zachty)
?- [plikBezRozszerzenia].
i od tego momentu moemy formuowa zapytania, np.
?- posiada(piotr,ksiazka).
Zapytanie to, w jzyku naturalnym brzmiaoby
Czy Piotr ma ksik?
Na potrzeby przetwarzania przez Prolog naley czyta je jednak troch inaczej
Czy istnieje fakt mwicy, e Piotr ma ksik?
Prolog przeszuka ca dostpn baz wiedzy (w postaci faktw i regu) i jeli zosta-
nie znalezione co co pasuje do zapytania i zwraca przy tym warto logiczn prawda,
wwczas zostanie zwrcona odpowied yes; w przeciwnym razie no. Raz jeszcze zazna-
czamy, e no nie oznacza nie, ale nie wiem. Sam proces przeszukiwania, o ktrym
5
S to moje propozycje na okrelenie tego z czym mamy do czynienia. Ewentualne zamienniki s
mile widziane.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
1.4. PYTANIA I ODPOWIEDZI 9
powiemy sobie w dalszej czci (patrz rozdzia ?? tutu), odbywa si linia po linii, czyli
fakty i reguy rozpatrywane s w kolejnoci ich umieszczenia w pliku.
Zamiast szuka odpowiedzi na pytanie
Czy Piotr ma ksik?
moemy chcie zapyta
Co ma Piotr?
co w jzyku Prologu bardziej naley czyta jako
Jeli Piotr ma X, to X jest tym czego szukam.
?- posiada(piotr,X).
Majac wicej faktw
lubi(jas,piernik).
lubi(jas,malgosia).
lubi(malgosia,cukierek).
lubi(malgosia,piernik).
moemy konstruowa zapytania zoone, np.
?- lubi(jas,malgosia), lubi(malgosia,jas).
czyli
Czy prawd jest, e Ja lubi Magosi i Magosia lubi Jasia?
lub
?- lubi(jas,X), lubi(malgosia,X).
czyli
Szukam tego wszystkiego co lubi zarwno Jas jak i Magosia.
Odpowied na pytanie o to co lubi Ja lub Magosia uzyskamy zapytaniem
?- lubi(jas,X); lubi(malgosia,X).
1.4 Pytania i odpowiedzi
Pytanie 1.1. Co oznacza programowanie w logice? Programowanie w logice opiera
si na rachunku kwantykatorw (tzn. rachunku predykatw pierwszego rzdu). Podajc
zbir predykatw i podstawiajc do nich stae programista tworzy baz faktw, nastpnie
okrelajc zwizki logiczne midzy nimi otrzymuje zbir regu. Jednym z jzykw tak
rozumianego programowania jest Prolog. Praca z Prologiem moe zatem polega na:
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
10 ROZDZIA 1. PODSTAWY
uzyskiwaniu odpowiedzi TAK/NIE na pytanie o prawdziwo pewnego zdania
6
. Z uwagi
na to, e rachunek kwantykatorw nie jest rozsztrzygalny odpowied negatywna
oznacza, e
podane zdanie jest rozstrzygalne i nieprawdziwe lub
zdanie jest nierozstrzygalne;
uzyskiwaniu odpowiedzi na pytanie o ekstensj funkcji zdaniowej
7
przy czym zwra-
cana jest odp. NIE jeli ekstensja funkcji jest pusta.
Pytanie 1.2. Jak naley rozumie pojcie obiektu wystpujce w Prologu?
Tak samo jak w OOP? Pojcie obiekt w jzykach zorientowanych obiektowo oznacza
jednoznacznie identykowaln (np. poprzez adres) struktur zawierajc pewne parametry
jako dane i zbir operacji/procedur/funkcji okrelonych na tych parametrach. Wartoci
parametrw okrelaj stan obiektu, ktry moe zmienia si w trakcie pracy programu.
W Prologu natomiast denicja obiektu jest denicj operacyjn
8
: podaje si zbir predy-
katw spenianych przez deniowane obiekty.
Uwaga: Obiekty mog pozostawa we wzajemnych zalenociach wyraanaych za pomoc
implikacji, ktrej poprzednikiem i nastpnikiem s okrelone formuy zdaniowe. Moemy
zatem deniowa jedne obiekty poprzez inne w ten sposb, e z prawdziwoci pewnych
predykatw okrelonych na znanych ju obiektach i na tym deniowanym wynika praw-
dziwo jakiego predykatu okrelonego (midzy innymi) na obiekcie deniowanym.
Pytanie 1.3. Co nazywamy relacj, faktem, regu?
Relacja: zwizek midzy obiektami wyraony za pomoc predykatu przez nie spenianego.
Inaczej, mona powiedzie, e predykat okrelony na pewnym zbiorze zmiennych
jest konkretn, nazwan relacj midzy obiektami bdcymi wartociami zmiennych
z jego dziedziny. Np.: predykat p(A,B,C,D) prawdziwy dla wektorw (a,b,c,d);
(e,f,g,h) i nieprawdziwy dla (a,f,c,h) wyznacza zarwno relacj midzy obiektami
(a,b,c,d); (e,f,g,h) ale take midzy (a,f,g,h)
9
.
Fakt: zdanie otrzymane przez wstawienie do okrelonego w programie predykatu war-
toci zmiennych (a zatem obiektw), dla ktrych jest ono prawdziwe. Podana tu
denicja faktu odnosi go cakowicie do formlizmu stosowanego w Prologu, w istocie
fakt ma odzwierciedla pewien elementarny fragment rzeczywistoci modelowanej w
programie.
Regua: zdanie prawdziwe wice implikacj obiekty i relacje wchodzce w jego skad.
6
Zdanie powinno by konsystentne (konsystentny wewntrznie spjny lub zgodny z czym) w formie
zapsiu z baz a jego dziedzina musi si zawiera w zbiorze staych wystpujcych w bazie.
7
Ekstensja funkcji zdaniowej zakres funkcji zdaniowej wyznaczony przez zbir przedmiotw, ktrych
nazwy wstawione w miejsce zmiennych wolnych zmieniaj t funkcje w zdanie prawdziwe.
8
Denicja operacyjna to taka denicja, w ktrej znaczenie deniowanej nazwy okrelane jest drog
podania czynnoci (operacji) niezbdnych do okrelenia znaczenia tej nazwy.
9
Wana jest take przynalenoci staych do dziedziny predykatu, gdy jak to zostao wspomniane,
odpowied negatywna na postawione pytanie zostanie udzielona przez Prolog take wtedy, gdy dla repre-
zentowanej przez wstawione do relacji stae rzeczywistoci utworzone zdanie jest nie tyle nieprawdziwe
co pozbawione sensu.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 2
Skadnia Prologu
2.1 Termy
Program Prologu skada si z termw. Wyrniamy cztery rodzaje termw: atomy
(ang. atoms), liczby (ang. numbers), zmienne (ang. variables) i termy zoone (ang.
compound terms). Atomy i liczby wsplnie okrelane s jako stae (ang. constants).
Zbir zoony z atomw i termw zoonych nazywany jest te zbiorem predykatw
1
.
Kady term zapisywany jest jako cig znakw pochodzcych z nastpujcych czterech
kategorii:
due litery: A-Z
mae litery: a-z
cyfry: 0-9
znaki specjalne: % + - * / \ ~ ^ < > : . ? @ # $ &
Zbir ten uzupenia znak podkrelenia (_), ktry zwykle traktowany jest jak litera.
Atomy
Atom jest cigiem znakw utworzonym z
maych i duych liter, cyfr i znaku podkrelenia z zastrzeeniem, e pierwszym
znakiem musi by maa litera, np.
jas, a, aLA, x_y_z, abc
dowolnego cigu znakw ujtego w apostrofy, np.
To te jest atom
symboli, np. ?- lub :- .
1
Tak przyjta terminologia odbiega troch od poj i terminw uywanych w rachunku predykatw
(nazywanym te rachunkiem predykatw pierwszego rzdu (ang. rst order predicate calculus), logik
pierwszego rzdu (ang. rst-order logic), rachunkiem kwantykatorw). Troch wicej na ten temat
powiemy w rozdziale ??.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
12 ROZDZIA 2. SKADNIA PROLOGU
Liczby
W SWI-Prologu dostpne s zarwno liczby cakowite jak i rzeczywiste
-17, 23, 99.9, 123e-3
Zmienne
Zmienna jest cigiem znakw utworzonym z maych i duych liter, cyfr i znaku podkre-
lenia z zastrzeeniem, e pierwszym znakiem musi by dua litera lub znak podkrelenia,
np.
X, Kto, _123, X_1_2, _
Ostatni z wymienionych przykadw, pojedynczy znak podkrelenia, to tak zwana zmienna
anonimowa. Korzystamy z niej zawsze wtedy, gdy interesuje nas tylko czy co jest
prawd, ale zupenie nie interesuje nas co, np.
Czy kto lubi Jasia?
?- lubi(_,jas).
Naley pamita, e wielokrotnym wystpieniom zmiennej anonimowej w jednym wyra-
eniu mog by przypisane rne wartoci.
?- a(1,2)=a(X,Y).
X = 1,
Y = 2
?- a(1,2)=a(X,X).
No
?- a(1,2)=a(_,_).
Yes
Termy zoone
Term zoony, inaczej struktura, to obiekt zoony z innych obiektw, czyli atomw,
liczb, zmiennych a take innych termw zoonych. Termy zoone maj posta
f(arg_1,...,arg_n)
gdzie arg_1,. . . ,arg_n s termami, natomiast f jest atomem (nazw relacji). Korzystajc
z moliwoci zagniedania innych termw w termach zoonych, moemy lepiej opisa
interesujcy nas problem. Fakty
posiada(piotr,auto).
posiada(marcin,auto).
pozwalaj jedynie stwierdzi, e obiekty piotr i marcin zwizane s relacj posiada z
obiektem auto, czyli mwic normalnie, Piotr i Marci maj auto. Trudno powiedzie
jakie to jest auto i czy przypadkiem to nie jest to samo auto. Zapisujc te fakty inaczej
posiada(piotr,auto(nissan,almera)).
posiada(marcin,auto(fiat,punto)).
maAuto(X) :- posiada(X,auto(_,_)).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
2.2. KLAUZULE, PROGRAM I ZAPYTANIA 13
wci mamy moliwo dowiedzenie si czy obaj maj auto, ale jeli bdziemy chcieli, to
moemy zapyta o co bardziej szczegowego, np. marka i model
?- maAuto(piotr).
Yes
?- posiada(piotr,auto(X,Y)).
X = nissan,
Y = almera
2.2 Klauzule, program i zapytania
W rozdziale 1 zawarto elementarne informacje zwizane z programami Prologu, ich skad-
ni i struktur. Jak wiemy, program Prologu skada si zasadniczo z dwch rodzai kon-
strukcji programistycznych, jeli mona takiego terminu uy. S to fakty i reguy, ktre
okrelane s jednym terminem klauzule (ang. clauses).
Fakty
Fakty (ang. fact) jest to predykat zakoczony znakiem kropka (.), np.
lubi(piotr,ciastko).
toJuzKoniec.
Intuicyjnie rozumiany termin fakt jest stwierdzeniem o rozpatrywanych obiektach, ktre
bezdyskusyjnie uwaamy za prawdziwe.
Reguy
Kada regua (ang. rule) skada si z dwch czci: gowy (ang. head) i ciaa (ang.
body). Gowa to jeden predykat, natomiast ciao to jeden lub wicej predykatw roz-
dzielonych przecinkami (,) i/lub rednikami (;). Regua koczy si znakiem kropki.
Przecinek lub rednik peni rol operatorw logicznych, oznaczajacych odpowiednio
koniunkcj (co zapisywa bdziemy te jako: i, and, &) i alternatyw (co zapisywa b-
dziemy te jako: lub, or, |). Z tego te powodu dopuszczalne jest uycie nawiasw
okrgych w charakterze elementu grupujcego. Gowa od ciaa oddzielona jest opera-
torem :- (gowa jest po lewej stronie operatora).
a(X,Y) :- b(X,Z), c(Z,Y).
nieWiekszy(X,Y) :- mniejszy(X,Y); rowny(X,Y).
a(X,Y) :- b(X,Z); (c(X,Y), d(X,Y)).
a(X,Y) :- b(X,Z); (c(Y,X); c(X,Z), d(Z,Y)).
Intuicyjnie rozumiany termin regua jest zbiorem warunkw (ciao) jakie musz by spe-
nione aby cel (gowa) zosta speniony (spenienie oznacza w tym przypadku moliwo
przypisania/stwierdzenia dla danego elementu wartoci logicznej prawda).
Program
Program w Prologu to uporzdkowany zbir klauzul. Sowo uporzdkowany jest w
tym przypadku istotne, gdy kolejno klauzul w pliku rdowym ma istotne znaczenie
klauzule rozpatrywane s w kolejnoci wystpowania o czym mona si przekona
porwnujc wyniki dziaania dwch programw
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
14 ROZDZIA 2. SKADNIA PROLOGU
Program 1 Program 2
a(b). a(c).
a(c). a(d).
a(d). a(b).
?- a(X). ?- a(X).
X = b ; X = c ;
X = c ; X = d ;
X = d X = b
Zapytania
Zapytanie ma tak sam struktur jak ciao reguy i tak jak ono koczy si kropk.
Zatwierdzenie zapytania, ktre wpisujemy po znaku zachty ?-, nastpuje po naciniciu
klawisza [ENTER]. Naley rozumie to jako zlecenie Prologowi poszukiwania, czy mona,
na podstawie podanych faktw i regu, wykaza prawdziwo predykatw tworzcych
zapytanie a w konsekwencji i jego samego. Odpowied Yes oznacza, e istnieje taki cig
przeksztace i podstawie, ktry pozwala wykaza prawdziwo zapytania. Odpowied
No oznacza, e na podstawie wiedzy posiadanej w postaci faktw i regu, nie mona tego
wykaza. Nie oznacza to jednak, e tak nie jest.
Zapytanie nie zawierajce adnej zmiennej, np.
a(b,c).
nazywane jest zapytaniem elementarnym (?) (ang. ground query). Oczekiwan
odpowiedzi na takie zapytanie jest yes lub no (tak/nie, prawda/fasz). Teoretycznie,
zapytania tego typu s znacznie atwiejsze do werykacji, gdy czsto wystarczy znale
dpowiedni fakt. Dla programu jak poniej
a(1,2).
a(2,3).
a(3,4).
a(4,5).
przykadowym elementarnym zapytaniem bdzie
?- a(2,3).
Yes
Zapytania zawierajce zmienn nazywane s zapytaniami nieelementarnymi (?) (ang.
non-ground query). W tym przypadku, znalezienie odpowiedzi moe zaj wicej czasu.
Odpowiedzi oczekiwan na takie zapytanie jest znalezienie waciwego podstawienia dla
zmiennych. Przyjrzyjmy si prostemu programowi mnocemu dwie liczby naturalne
mul(0,_,0).
mul(1,X,X).
mul(X,Y,R) :- X > 1, X1 is X-1, mul(X1,Y,R1), R is R1 + Y.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
2.2. KLAUZULE, PROGRAM I ZAPYTANIA 15
Wystpujc w regule formu X1 is X-1 rozumiemy nastpujco: X1 przyjmuje warto
bdc wynikiem wykonania operacji X-1. Powyszy program opiera si na rekurencyjnej
denicji mnoenia. Ot iloczyn dwch liczb x i y, dla x > 1 deniujemy rekurencyjnie
jako
x y = y + (x 1) y.
Dla x = 0 albo x = 1 mamy
x y = 0, dla x = 0,
x y = y, dla x = 1.
Efekty dziaania zgodne s z oczekiwaniem
?- mul(4,3,X).
X = 12 [ENTER]
Yes
?- mul(0,3,X).
X = 0 [ENTER]
Yes
?- mul(1,3,X).
X = 3 [ENTER]
Yes
?- mul(4,3,12).
More? [ENTER]
Yes
Pierwsze z zapyta zmusza Prolog do dosy dugiego cigu poszukiwa celem znalezienia
waciwej odpowiedzi.
1. Pocztek obliczania celu dla zapytania mul(4,3,X)., czyli poszukiwanie odpowie-
dzi na pytanie: Ile to jest cztery razy trzy?
2. Zgodnie z denicj rekurencyjn, aby obliczy wynik dla 4 3, naley do wyniku
operacji r1 = 3 3 doda 3. Ale w tym momencie nie mamy wyniku r1. Trzeba go
najpierw obliczy, czyli przechodzimy do kolejnego kroku oblicze.
3. Aby obliczy wynik dla 33, naley do wyniku operacji r2 = 23 doda 3. Ale w tym
momencie nie mamy wyniku r2. Trzeba go najpierw obliczy, czyli przechodzimy
do kolejnego kroku oblicze.
4. Aby obliczy wynik dla 23, naley do wyniku operacji r3 = 13 doda 3. Ale w tym
momencie nie mamy wyniku r3. Trzeba go najpierw obliczy, czyli przechodzimy
do kolejnego kroku oblicze.
5. Wynik dla 1 3, podany jest jako fakt. Oznacza to, e moemy okreli wynik tego
dziaania. Wynosi on 3. Znajc ten wynik, moemy go zwrci do poprzedniego
wywoania (majcego miejsce w punkcie 4).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
16 ROZDZIA 2. SKADNIA PROLOGU
6. Cofamy si do wywoania z punktu 4. Teraz znamy warto zmiennej r3 (zostaa
ona obliczona przez wywoanie z punktu 5) i moemy dziki temu obliczy wynik
dla 2 3 = r3 + 3 = 6. Wynik ten przekazujemy do wywoania poprzedzajcego
(punkt 3).
7. Cofamy si do wywoania z punktu 3. Teraz znamy warto zmiennej r2 (zostaa
ona obliczona przez wywoanie z punktu 4) i moemy dziki temu obliczy wynik
dla 3 3 = r2 + 6 = 9. Wynik ten przekazujemy do wywoania poprzedzajcego
(punkt 2).
8. Cofamy si do wywoania z punktu 2. Teraz znamy warto zmiennej r1 (zostaa
ona obliczona przez wywoanie z punktu 3) i moemy dziki temu obliczy wynik
dla 4 3 = r1 + 9 = 12. Wynik ten przekazujemy do wywoania poprzedzajcego
(punkt 1).
9. Cofamy si do wywoania z punktu 1. Poszukiwanym wynikiem jest X=12.
Opisane drzewo wywoa wyglda nastpujco
mul(4,3,X)
|
3 + mul(3,3,X)
. |
. 3 + mul(2,3,X)
. . |
. . 3 + mul(1,3,X)
. . . |
. . . X=3
. . . |
. . 3 + 3
. . |
. . X=6
. . |
. 3 + 6
. |
. X=9
. |
3 + 9
|
X=12
Jednak nie zawsze musi by tak prosto zapytanie wygldajce jak zapytanie elemen-
tarne, moe te pociga za sob znaczn ilo operacji i oblicze, co pokazuje ostatnie
z zapyta, tj. mul(4,3,12).. W istocie, pociga ono za sob identyczn sekwencj
wywoa jak dla zapytania pierwszego.
2.3 Pytania i odpowiedzi
Pytanie 2.1. Czym sa w Prologu stae, zmienne, struktury? Podaj przykad.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
2.3. PYTANIA I ODPOWIEDZI 17
staa: konkretny obiekt (np: a, kowalski, 65748) lub konkretna relacja (litera, nazwisko,
liczba, :- ). Stae dziel si na:
liczby;
atomy (s zbudowane z dowolnych symboli ewentualnie ujtych w pojedynczy
cudzysw przy czym zawsze zaczynaj si ma liter);
zmienna: relacja moe by rozumiana jako funkcja okrelona na pewnym zbiorze obiek-
tw. Wwczas przez zmienn rozumiemy dowolny ale nie ustalony element z dzie-
dziny jakiej relacji. Nazwy zmiennych s atomami rozpoczynajcymi si zawsze
wielk liter. Np.: wemy relacj student/2, ktra jest prawdziwa jeli argumen-
tami s nazwisko studenta i nazwa przedmiotu na egzaminie z ktrego ciga.
Wstawiajc do niej zmienne (Kowalski, Origami) otrzymamy predykat prawdziwy
dla par utworzonych przez konkretne nazwisko i odpowiadajcy mu przedmiot(y).
Jeli baz programu jest zbir:
student(a,teoria_pola).
student(b,mechanika_kwantowa).
student(c,wychowanie_fizyczne).
student(d,szkolenie_bhp).
student(d,geometria_rniczkowa).
to w wyniku ledztwa przeprowadzonego w Prologu otrzymamy:
1 ?- student(Kowalski,Origami).
Kowalski = a,
Origami = teoria_pola ;
Kowalski = b,
Origami = mechanika_kwantowa ;
Kowalski = c,
Origami = wychowanie_fizyczne ;
Kowalski = d,
Origami = szkolenie_bhp ;
Kowalski = d,
Origami = geometria_rniczkowa ;
No
2 ?-
Istnieje szczeglny typ zmiennej tzw. zmienna anonimowa, oznaczana znakiem
podkrelenia (_) ktrej uycie w zapytaniu np.:
?- pytanie(_,co).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
18 ROZDZIA 2. SKADNIA PROLOGU
powoduje uzyskanie odpowiedzi TAK/NIE na pytanie czy istnieje w bazie staa
speniajca relacj pytanie jednoczenie ze sta co? (Innymi sowy: czy ist-
nieje w bazie staa bdca w relacji pytanie z co?).
struktura: majc zdeniowane pewne obiekty moemy, traktujc je jak stae, zdenio-
wa nowe, zoone z nich obiekty nazywane strukturami. Kontynuujc przykad
kryminalny, okrelmy relacj wykroczenie/2 ktra przyjmuje za argumenty rok po-
penienia wykroczenia i pozycj niegodziwca na spoecznej drabinie U; przykadowy
obiekt wyglda wwczas nastpujco:
wykroczenie(2007,student(d,szkolenie_bhp)).
Uwaga: wszystkie opisane tu pojcia nazywamy wsplnie termami.
Pytanie 2.2. Co to jest predykat? Bardzo czsto nie mamy moliwoci opisania
zbioru wymieniajc jego elementy. Wwczas uyteczny okazuje si sposb deniowania
zbioru przez okrelenie waciwoci wsplnych dla wszystkich elementw tego zbioru. Za-
pis
{x|P(x)}
oznacza zbir wszystkich takich elementw x, dla ktrych wyraenie P(x), gdzie x jest
zmienn a P stwierdzeniem, jest prawdziwe. Na przykad
{x|x jest liczb cakowit wiksz ni 3 i niewiksz ni 10}
oznacza zbir liczb {4, 5, 6, 7, 8, 9, 10}.
Tak wic elementem zbioru {x|P(x)} jest kady obiekt t, dla ktrego wyraenie P(t)
jest prawdziwe. Wyraenie P(x) nazywane jest predykatem, funkcj zdaniow lub
form zdaniow. W jzyku angielskim funkcjonuje okrelenie propositional function
oddajce to, e, kadorazowy wybr konkretnego podstawienia za zmienn x powoduje
utworzenie zdania (ktre mona rozumie jako propozycj okrelenia czego jako co,
twierdzenie, wniosek), ktre jest albo faszywe albo prawdziwe.
W rachunku predykatw pierwszego rzdu (ang. rst-order logic, predykat moe pe-
ni rol waciwoci przypisanej obiektom lub relacji je czcej. Przypatrzmy si takim
zdaniom
Mi jest ty
2
.
Banan jest ty.
Samochd Ferrari jest ty
3
.
Wszystkie one pasuj do szablonu . . . x . . . jest ty. Wyraenie jest ty to wa-
nie predykat opisujcy cech bycia tym. Jeli przyjmiemy oznacza ten predykat jako
jest_zolty lub krcej zolty, wwczas kade zdanie zolty(x) czytamy jako x jest ty,
co rozumiemy jako obiekt x posiada cech mwic o tym, e jest ty.
Z kolei zdania
2
Chodzi o Kubusia Puchatka w wizualizacji The Walt Disney Company
3
Zdaniem mionikw marki, prawdziwe Ferrari powinno by pomalowane na czerwono. Wzio si to
ze zwyczaju zaoyciela, ktry malowa swoje samochody wycigowe na tzw. rosso corsa. Do dzi
czerwony kolor jest najpopularniejszy wrd samochodw Ferrari, mimo e ocjalnym kolorem jest
kanarkowy ty giallo modena, taki jak ten w tle znaczka Ferrari, przejty przez zaoyciela z herbu
miasta Modena, w ktrym si urodzi.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
2.3. PYTANIA I ODPOWIEDZI 19
Ja da piernika Magosi.
Cezary da ksik Gosi.
powstay przez odpowiednie podstawienia w szablonie . . . x . . . da . . . y . . . z . . . . Szablon
kto da co komu jest predykatem opisujcym w tym przypadku zwizek (relacj) po-
midzy obiektami. Take i w tym przypadku czciej bdzie si uywao jego krtszych
wersji, np. dal(x,y,z).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
20 ROZDZIA 2. SKADNIA PROLOGU
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 3
Ewaluacja zapytania
3.1 Dopasowywanie wyrae
Dwa termy nazwiemy pasujcymi do siebie (ang. match) jeli s identyczne lub mog sta
si identyczne w wyniku podstawienia odpowiednich wartoci za zmienne (ang. variable
instantiation). Istotnym jest, aby podstawienie za zmienne byo identyczne w caym
wyraeniu. Jedynym wyjtkiem jest zmienna anonimowa, ktra moe mie inna warto
w rnych miejscach. Na przykad dwa termy
jakisTerm(a,b)
jakisTerm(a,X)
pasuj do siebie, gdy podstawienie za zmienn X atomu b czyni te termy identycznymi
?- jakisTerm(a,b)=jakisTerm(a,X).
X = b
Nie bd natomiast pasowa termy w nastpujcych przykadach
?- jakisTerm(a,b)=jakisTerm(X,X).
No
?- jakisTerm(a,X)=jakisTerm(X,b).
No
gdy X nie moe mie jednoczenie nadanej wartoci a i b. Zastpienie X zmienn anoni-
mow (_) powoduje, e wyraenia zaczynaj pasowa do siebie
?- jakisTerm(a,b)=jakisTerm(a,_).
Yes
?- jakisTerm(a,_)=jakisTerm(_,b).
Yes
Dopasowywanie do siebie wcale nie jest takim trywialnym procesem, o czym moemy si
przekona patrzc na poniszy przykad
?- b(X,a)=b(f(Y),Y), d(f(f(a)))=d(U), c(X)=c(f(Z)).
X = f(a),
Y = a,
U = f(f(a)),
Z = a
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
22 ROZDZIA 3. EWALUACJA ZAPYTANIA
Opisany powyej proces dopasowywania nazywany jest take unikacj (ang. unica-
tion).
Algorytm unikacji
Niech T1 i T2 bd termami.
Jeli algorytm zwrci warto FAIL oznacza to, e unikacja nie jest moliwa.
Jeli algorytm zwrci warto NULL oznacza to, e wyraenia pasuj do siebie
bez koniecznoci dokonywania podstawienia.
Jeli algorytm zwrci podstawienie typu a|b oznacza to, e nie ma wicej podsta-
wie koniecznych do unikacji T1 i T2.
Jeli algorytm zwrci list SUBST, to zawiera ona wszystkie podstawienie nie-
zbdne do unikacji T1 i T2.
1. Jeli T1 i T2 nie s jednoczenie termem zoonym, wwczas
(a) Jeli T1 i T2 s identyczne, wwczas zwr NULL.
(b) Jeli T1 jest zmienn i jeli T1 wystpuje w T2, wwczas zwr FAIL, w
przeciwnym razie zwr T2|T1.
(c) Jeli T2 jest zmienn i jeli T2 wystpuje w T1, wwczas zwr FAIL, w
przeciwnym razie zwr T1|T2.
(d) Zwr FAIL.
2. Jeli T1 i T2 s jednoczenie termem zoonym, wwczas
(a) Jeli nazwy termw T1 i T2 s rne, wwczas zwr FAIL.
(b) Jeli termy T1 i T2 maj rn ilo argumentw, wwczas zwr FAIL.
(c) Wyczy list SUBST. Lista ta bdzie zawieraa wszystkie podstawienia
niezbdne do unikacji T1 i T2.
(d) Dla i zmieniajcego si od 1 do iloci argumentw termu T1 wykonaj
i. Wywoaj algorytm unikacji dla i-tego argumentu z T1 i i-tego argumentu
z T2. Wynik zapisz z zmiennej S.
ii. Jeli S zawiera FAIL, wwczas zwr FAIL.
iii. Jeli S jest rne od NULL, wwczas
A. Zastosuj S do pozostaych czci termw T1 i T2.
B. Dodaj do listy SUBST podstawienia z S.
(e) Zwr SUBST.
Kroki 1 (b) i 1 (c) s warunkami chronicymi przed prb unikacji zmiennej z wy-
raeniem zawierajacym t zmienn, co mogoby prowadzi do nieskoczonej rekurencji,
np.
X i a(X)
lub
a(X,X) i a(b(X),b(X))
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
3.2. OBLICZANIE CELU 23
3.2 Obliczanie celu
Zatwierdzenie zapytania powoduje uruchomienie procesu majcego na celu wykazanie,
e istnieje cig podstawie i przeksztace pozwalajcy przypisa zapytaniu warto lo-
giczna prawda. Poszukiwanie takiego dowodu nazywane jest obliczaniem celu (ang.
goal execution). Kady predykat wchodzcy w skad zapytania staje si (pod)celem,
ktry Prolog stara si speni jeden po drugim. Jeli identyczne zmienne wstpuj w
kilku podcelach, wwczas, jak to byo ju opisane, zwizane jest z nimi identyczne pod-
stawienie.
Jeli cel pasuje do gowy reguy, wwczas maj miejsce odpowiednie podstawienia
wewntrz reguy
1
i tym samym otrzymujemy nowy cel, zastpujcy niejako cel poczt-
kowy. Jeli cel ten skada si z kilku predykatw, wwczas zostaje on podzielony na kilka
podceli, przy czym kady z nich traktujemy jak cel pierwotny. Proces zastpowania
wyraenia przez inne wyraenie nazywamy rezolucj i mona opisa go nastpujcym
algorytmem
1. Dopki zapytanie nie jest puste, wykonuj:
(a) Wybierz term z zapytania
2
.
(b) Znajd fakt lub regu unikujc si z termem
3
. Jeli nie ma adnego faktu
lub reguy, zwr FAIL, w przeciwnym razie kontynuuj.
i. Jeli znaleziono fakt, usu go z zapytania.
ii. Jeli znaleziono regu, zastp term ciaem reguy.
2. Zwr SUCCESS.
Stosowanie unikacji i rezolucji pozwala na wykazanie prawdziwoci lub jej braku,
wedug nastpujcych zasad
1. Jeli cel jest zbiorem pustym, zwr prawd.
2. Jeli nie ma gw regu lub faktw unikujcych si z rozwaanym wyraeniem,
zwr fasz.
3. W przypadku niepowodzenia (otrzymanie wartoci fasz), wr do takiego miejsca,
w ktrym stosujc rezolucj moesz uzyska inne wyraenie i ponw cay proces.
Zasada ta nazywana jest nawracaniem (ang. backtracking) (wicej przykadw
zwizanych z nawracaniem podanych zostanie w rozdziale 5).
W opisie tym szczeglnie istotny jest krok 3, ktry niejako powoduje restart caego al-
gorytmu. Oznacza to, e Prolog w punkcie 1 (b) zapamituje miejsce wystpowania
unikatora i w odpowiednim momencie jest w stanie poszukiwa kolejnych unikatorw
wystpujcych za wanie wybranym. Powysze zasady stosujemy tak dugo, a wyczer-
piemy wszystkie moliwoci wybierajc na kadym z etapw kolejne dostpne wyraenia.
Dziki temu mamy moliwo znalezienia kilku rnych dowodw.
Pokaemy teraz prosty przykad, ktry pozwoli lepiej pokaza kiedy mamy do czy-
nienia z unikacj a kiedy z rezolucj. Dla programu
1
Wewntrz (w ciele) reguy, czyli po prawej stronie operatora :-
2
Zwykle termy wybierane s od lewej do prawej.
3
Zwykle fakty i reguy przeszukiwane s w kolejnoci ich wystpowania w pliku.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
24 ROZDZIA 3. EWALUACJA ZAPYTANIA
a(b,c).
a(c,d).
aa(X,Y) :- a(X,Z),a(Z,Y).
zapytanie
aa(b,A).
pociga za sob nastpujcy proces.
Krok 1. Rezultatem unikacji dla aa(b,A) oraz aa(X,Y) jest podstawienie
X = a A = Y
Resolucja: zastpujc aa(b,A) przez a(X,Z), a(Z,Y) i stosujc uzyskane podsta-
wienie otrzymujemy nowe zapytanie:
a(b,Z),a(Z,Y).
Krok 2. Z uzyskanego w poprzednim kroku zapytania wybieramy atom a(b,Z) i w
wyniku unikacji z faktem a(b,c) otrzymujemy podstawienie
Z=c
Rezolucja: poniewa unikacja dotyczya faktu wic rozpatrywany atom z zapy-
tania zostaje usunity (zastpiony przez element pusty) po czym do otrzymanego
w ten sposb wyraenia stosujemy unikacj w wyniku czego otrzymujemy kolejne
zapytanie
a(c,Y).
Krok 3. W uzyskanym w poprzednim kroku zapytaniu wystpuje tylko jeden atom
a(c,Y) i w wyniku unikacji z faktem a(c,d) otrzymujemy podstawienie
Y=d
Rezolucja: poniewa unikacja dotyczya faktu wic rozpatrywany atom z zapy-
tania zostaje usunity w wyniku czego otrzymujemy puste zapytanie, co oznacza
koniec procesu.
Innymi sowy mona powiedzie, e unikacja jest, podobnie jak w tradycyjnym
programowaniu, przypisywaniem wartoci do zmiennych, natomiast rezolucja sposobem
przekonstruowywania zapytania.
Wicej szczegw na ten temat podamy w dalszej czci wykadu (patrz rozdzia
??) teraz zaley nam gwnie na wyrobieniu waciwej intuicji.
Kolejny przykad pokae, e proces unikacji, rezolucji i nawracania prowadzi czsto
do rezultatw sprzecznych z oczekiwaniem. Rozwamy taki program
mniej(p1,p2).
mniej(p2,p3).
mniej(p3,p4).
mniej(X,Y) :- mniej(X,Z),mniej(Z,Y).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
3.2. OBLICZANIE CELU 25
Intencja jest jasna: deniujemy kilka obiektw (tj. p1, p2, p3, p4) powizanych relacj
mniej. Do tego wprowadzamy regu przechodnioci, ktra w zaoeniu ma pozwoli na
powizanie ze sob np. obiektu p1 i p4. Niestety zapytanie
?- mniej(A,B).
nie zwraca tego co, naszym zdaniem, powinno zwrci
A = p1,
B = p2 ;
A = p2,
B = p3 ;
A = p3,
B = p4 ;
A = p1,
B = p3 ;
A = p1,
B = p4 ;
ERROR: Out of local stack
Jest para (A=p2, B=p3), ale gdzie para (A=p2, B=p4)? Wytumaczenie tego jest na-
stpujce (rwnolegle z opisem prosz ledzi drzewo wywoa, bo cho nie pozbawione
wad, moe uatwi kontrolowanie co i kiedy jest wywoywane). Ponumerujmy najpierw
linie programu, aby atwiej nam byo si do nich odnosi
1 mniej(p1,p2).
2 mniej(p2,p3).
3 mniej(p3,p4).
4 mniej(X,Y) :- mniej(X,Z),mniej(Z,Y).
Zapytanie mniej(A,B). powoduje, ze Prolog, szuka (od poczatku pliku, po kolei) czego,
co moe z tym zapytaniem zosta zunikowane. Tak wic po kolei, pasuje fakt 1 (linia 2
w drzewie wywoa patrz dalej), wic jako wynik mamy
A = p1,
B = p2 ;
Szukajc dalej, pasuje fakt 2 (linia 3 w drzewie wywoa) i mamy
A = p2,
B = p3 ;
i pasuje te fakt 3 (linia 4 w drzewie wywoa), w zwizku z czym mamy
A = p3,
B = p4 ;
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
26 ROZDZIA 3. EWALUACJA ZAPYTANIA
Szukamy dalej a dalej mamy regu (4) (linia 5 w drzewie wywoa). A wic sprbujemy
uy reguy, do tego aby znale podstawienie za A i B. Aby jednak uy reguy, naley
speni dwa warunki jakie w niej wystpuj. Pierwszym warunkiem jest poszukiwanie
czego, co speni mniej(X,Z) (linia 6 w drzewie wywoa (d.w.)). Poniewa w tym
momencie mniej(X,Z) peni rol podcelu, wic rozpoczynamy przeszukiwanie pliku od
pocztku. Dla tego podcelu znajdujemy fakt 1, ktry do niego pasuje (linia 7 w d.w.).
To powoduje, e mamy podstawienie (X=p1, Z=p2), dziki czemu moemy przej do
prby wykazania drugiej czci reguy, ktra teraz przyjmuje posta z linii 8 drzewa
wywoa i staje si nowym podcelem. Ponownie rozpoczynamy przeszukiwanie pliku
od poczatku w celu znalezienia czego co unikuje si z tym podcelem. Jako pierwsz
pasujc znajdujemy regu 2 (linia 9 w d.w.). Dopasowanie to powoduje, e Y przyjmuje
warto p3. W tym momencie, wszystkie podcele reguy z linii 5 d.w. s spenione
(podstawienia to X=p1, Z=p2, Y=p3) i moe zosta zwrcony nastpujcy wynik
A = p1,
B = p3 ;
Kontynuujemy poszukiwania tego co moe speni podcel m(p2,Y) (linia 8 w d.w.). Fakt
3 nie pasuje, ale mamy regu (4, linia 10 w d.w.). W tym momencie, w wyniku wcze-
niejszych podstawie, regula ta jest wywoana jako mniej(p2,Y) w wyniku czego jej
podcele przyjm posta mniej(p2,Z) i mniej(Z,Y). Zauwamy, e speniajc regu z
linii 10 d.w. speniamy tym samym drugi warunek (linia 8 w d.w.) reguy z linii 5 d.w.
a wic i nasz gwny cel. Aby j speni naley znale co co speni jej pierwsza cz,
ktra przyjmuje posta mniej(p2,Z) (linia 11 w d.w.). Podobnie jak wczeniej (linia 8 w
d.w.), widzimy, e pierwszy podcel spenia fakt 2. Zatem wiemy ju, e Z ma wartosc p3
(linia 12 w d.w.). Zatem aby speni drug cz reguy, trzeba znale fakt lub regu
speniajc mniej(p3,Y) (linia 13 w d.w.). Spelnia to fakt 3 i w zwizku z tym mamy
podstawienie Y=p4. Majc spenione podcele z linii 11 i 13 d.w. moemy powiedzie, e
speniony jest podcel z linii 8 d.w. a w konsekwencji regua z linii 5 d.w. Wszystko to
zachodzi przy nastpujcych podstawieniach: X=p1 Y=p4 (i cho to mao dla nas istotne,
take Z=p2). Potwierdzeniem takiego rozumowania jest kolejny wynik zwrcony przez
Prolog
A = p1,
B = p4 ;
Powracamy do podcelu z linii 13 d.w. i kontynuujemy poszukiwania tego co go spenia.
Kolejn, nierozpatrywan rzecz (w sensie fakt, regua), jest regua 4 (linia 15 w d.w.).
W tym momencie, w wyniku wczeniejszych podstawie, regua ta jest wywoana jako
mniej(p3,Y) w wyniku czego jej podcele przyjm posta mniej(p3,Z) i mniej(Z,Y).
Zauwamy, e regua z linii 15 spenia podcel z linii 13, co z koleii powoduje spenienie
reguy z linii 10 d.w.. Speniamy tym samym drugi warunek (linia 8 w d.w.) reguy z
linii 5 d.w. a wic i nasz gwny cel. Aby jednak speni regu z linii 15 naley znale
fakt lub regu speniajce jej pierwsz cz, ktra przyjmuje posta mniej(p3,Z) (linia
16 w d.w.). Widzimy, e podcel ten spenia regua 3 (linia 17 w d.w.). Zatem wiemy ju,
e Z ma wartosc p4. Zatem aby speni drug cz reguy, trzeba znale fakt lub regu
speniajc mniej(p4,Y) (linia 18 w d.w.). aden fakt tego nie spenia, ale moe speni
regua (4) (linia 19 w d.w.). Aby jednak regua moga by speniona, naley speni
jej dwa podcele. Pierwszy podcel, w wyniku podstawie przyjmuje posta mniej(p4,Z)
(linia 20 w d.w.). Podobnie jak to byo przed chwil, aden fakt tego nie spenia, ale
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
3.2. OBLICZANIE CELU 27
moe speni regua (4) (linia 21 w d.w.). Aby jednak regua moga by speniona,
naley speni jej dwa podcele. Pierwszy podcel, w wyniku podstawie przyjmuje posta
mniej(p4,Z) (linia 22 w d.w.). Podobnie jak to byo przed chwil jedynym faktem lub
regu, ktre mog ewentualnie speni ten podcel, jest znowu regua (4) (linia 23 w
d.w.). Jak widzimy regua bdzie wywoywa regu, ktra znowu wywoa regu itd.
To dlatego jako ostatni widoczny efekt dziaania otrzymujemy
ERROR: Out of local stack
czyli przepenienie stosu w wyniku zbyt duej iloci wywoa rekurencyjnych.
Drzewo wywoa dla programu
mniej(p1,p2).
mniej(p2,p3).
mniej(p3,p4).
mniej(X,Y) :- mniej(X,Z),mniej(Z,Y).
i zapytania
mniej(A,B).
1 m(A ,B).
|
2 +-m(p1,p2).
|
3 +-m(p2,p3).
|
4 +-m(p3,p4).
|
5 +-m(X,Y) :- m(X,Z),m(Z,Y).
|
6 +---m(X ,Z)
| |
7 | +-m(p1,p2).
|
8 +-------------,m(p2,Y)
|
9 +-m(p2,p3).
|
10 +-m(X,Y) :- m(X,Z),m(Z,Y).
|
11 +---m(p2,Z)
| |
12 | +-m(p2,p3).
|
13 +-------------,m(p3,Y)
|
14 +-m(p3,p4).
|
15 +-m(X,Y) :- m(X,Z),m(Z,Y).
|
16 +---m(p3,Z)
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
28 ROZDZIA 3. EWALUACJA ZAPYTANIA
| |
17 | +-m(p3,p4).
|
18 +-------------,m(p4,Y)
|
19 +-m(X,Y) :- m(X,Z),m(Z,Y).
|
20 +---m(p4,Z)
|
21 +-m(X,Y) :- m(X,Z),m(Z,Y).
|
22 +---m(p4,Z)
|
23 +-m(X,Y) :- ...
|
... ...
Jak wic widzimy powodem niepowodzenia jest dopuszczenie do sytuacji, w ktrej
regua bdzie wywoywa sam siebie. Co gorsza podcel reguy bdzie si tylko unikowa
z gow reguy (np. linie 18 i 19, 20 i 21, 22 i 23 itd.). W takich (dosy typowych)
sytuacjach problematycznych, rozwizaniem jest uycie innych nazw dla faktw, gowy
reguy i przynajmniej czsciowe przekonstruowanie reguy/faktw, np. w nastpujcy
sposb
mniej(p1,p2).
mniej(p2,p3).
mniej(p3,p4).
jestMniejszy(X,Y) :- mniej(X,Y).
jestMniejszy(X,Y) :- mniej(X,Z),jestMniejszy(Z,Y).
Ten program daje ju poprawne i zgodne z oczekiwaniami wyniki
?- jestMniejszy(X,Y).
X = p1,
Y = p2 ;
X = p2,
Y = p3 ;
X = p3,
Y = p4 ;
X = p1,
Y = p3 ;
X = p1,
Y = p4 ;
X = p2,
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
3.3. PYTANIA I ODPOWIEDZI 29
Y = p4 ;
No
3.3 Pytania i odpowiedzi
Pytanie 3.1. Co to jest unikacja? Unikacja (ang. unication) oznacza ujednoli-
canie, ktre w konkretnych dyscyplinach naukowych moe by rnie rozumiane
4
.
Logika W logice jest to proces ujednolicania, w wyniku ktrego zakresy pojciowe lub
znaczenia niezwizane ze sob lub w jaki sposb niezgodne, nabywaj zgodnoci i
staj si czci wikszej caoci.
Informatyka W informatyce unikacj okreli moemy jako operacj na dwch lub
wikszej iloci drzew, ktra znajduje takie przyporzdkowanie zmiennych, e drzewa
te s rwne. Stosujc do zapisu drzewa notacj polsk
5
, drzewa
(+ x 2)
(+ (+ y 3) z)
s unikowalne dla
z=2
x=(+ y 3)
Nie s unikowalne
(+ x 2) i (+ y 3)
(+ x 2) i (- x x)
(+ 2 3) i (+ 3 2).
Otrzymany zbir przyporzdkowa nazywamy unikatorem.
Matematyka Niech E bdzie wyraeniem skadajcym si ze zmiennych x
1
, . . . , x
n
i sta-
ych, natomiast t
1
, . . . , t
n
bd wyraeniami. Zbir przyporzdkowa = {t
1
|x
1
, ..., t
n
|x
n
}
6
nazywamy podstawieniem. Wyraenie E

nazywane jest instancj wyraenia E


jeli otrzymane jest z E przez zastpienie wszystkich wystpie zmiennych x
i
przez
odpowiadajce im wyraenia t
i
, i = 1, . . . , n. Podstawienie nazywamy unika-
torem dla zbioru wyrae {E
1
, . . . , E
m
} jeli E
1

= = E
m

. Dla wyrae
E
1
= x
2
,
E
2
= y
3
unikatorem jest
= {z
3
|x, z
2
|y}.
4
Rnie nie w sensie odmiennie, ale w sensie specycznie.
5
Czyli najpierw warto wza a potem jego dzieci.
6
Zapis t
i
|x
i
naley czyta: wyraenie t
i
podstawione za zmienn x
i
.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
30 ROZDZIA 3. EWALUACJA ZAPYTANIA
Prolog W Prologu unikacja oznacza proces, w ktrym dla dwch atomw (jednego z
zapytania, drugiego bdcego faktem lub gow reguy
7
) poszukiwane jest takie pod-
stawienie, dziki ktremu stan si one identyczne.
Pytanie 3.2. Co to jest rezolucja? Rezolucja to metoda automatycznego dowodzenia
twierdze oparta na generowaniu nowych klauzul (wyrae) a dojdzie si do sprzecznoci.
W ten sposb mona udowodni, e dane twierdzenie nie jest spenialne, lub te, co
jest rwnowane, e jego zaprzeczenie jest tautologi. Metoda ta pozwala w oparciu o
dwa wyraenia zawierajce dopeniajce si postaci literau, wygenerowa nowe wyraenie
zawierajce wszystkie literay z wyjtkiem dopeniajcych si, zgodnie z ponisz regu
wnioskowania
a|b, ~a|c
---------
b|c
Wedug tej reguy, jeli przyjmiemy, e a lub b jest prawd i jednoczenie, e a jest faszem
lub c jest prawd, wwczas b lub c jest prawd. Istotnie, jeli a jest prawd, wwczas aby
drugie wyraenie byo prawdziwe (a takie jest zaoenie), c musi by prawd. Jeli a jest
faszem, wwczas aby pierwsze wyraenie byo prawdziwe (a takie jest zaoenie), b musi
by prawd. Tak wic niezalenie od wartoci logicznej a, jeli przyjmiemy prawdziwo
zaoe, wwczas b lub c musi by prawd.
Rozwamy nastpujcy przykad. Z zaoenia prawdziwoci regu
Jeli zachodzi b to zachodzi a.
oraz
Jeli zachodzi c to zachodzi b.
wynika, e zachodzi a jeli tylko zachodzi c. Dokadnie taki sam wynik uzyskamy
stosujc rezolucje. Zapiszmy podane reguy
a :- b
b :- c
ktre zgodnie z prawem
x => y x|y,
gdzie symbol oznacza negacj, przeksztacamy do postaci
~b | a
~c | b
gdzie symbol ~ oznacza negacj. Stosujc rezolucj otrzymujemy
~c | a
co w postaci reguy mona zapisa jako
a :- c
7
Gow, czyli czci wystpujc po lewej stronie operatora :-.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
3.3. PYTANIA I ODPOWIEDZI 31
Pytanie 3.3. Co to jest nawracanie? Wielokrotnie w Prologu zdarza si, e cel
moe zosta speniony na wiele alternatywnych sposobw. Za kadym razem, gdy za-
chodzi konieczno wybrania jednej z wielu moliwoci, Prolog wybiera pierwsz z nich
(w kolejnoci wystpowania w pliku) zapamitujc przy okazji miejsce w ktrym wybr
ten zosta dokonany. Jeli w jakim momencie nie powiedzie si prba obliczenia celu,
system ma moliwo powrcenia do miejsca otatnio dokonanego wyboru i zastpienia go
wyborem alternatywnym. Zachowanie takie nazywamy nawracaniem (wicej przykadw
zwizanych z nawracaniem podanych jest w rozdziale 5).
Prawd mwic, dokadnie ten sam mechanizm dziaa take, gdy powiedzie si obli-
czanie celu. O ile jedak w poprzednim przypadku pozwala on na znalezienie cho jednego
rozwizania, to w tym przypadku pozwala znale rozwizania alternatywne.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
32 ROZDZIA 3. EWALUACJA ZAPYTANIA
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 4
Listy
4.1 Skadnia
Lista jest uporzdkowanym cigiem elementw o dowolnej dugoci. Jako element listy
moe by uyty kady prawidowy term Prologu, tzn. atom, liczba, zmienna, term
zoony w tym take inna lista. Umieszczamy je pomidzy nawiasami kwadratowymi ([
i ]) i rozdzielamy przecinkiem (,), np.
[a, X, [], b(c, Y), [a, d, e], 123]
Lista pusta zapisywana jest jako para pustych nawiasw
[]
Wewntrzna reprezentacja listy opiera si o dwuargumentowy funktor kropka (.). Z re-
prezentacji tej mona korzysta tak samo jak z notacji z nawiasami kwadratowymi. Cho
jest ona mniej wygodna, to czasem uatwia zrozumienie, dlaczego nasz program zacho-
wuje si tak a nie inaczej, gdy przetwarza list.
Korzystajac z tego funktora, list zawierajc jeden element a moemy zapisa jako
.(a,[])
co na rysunku mona przedstawi w nastpujcy sposb
. .-[]
/ \ |
a [] a
List zawierajc 3 elementy: a,b,c moemy zapisa jako
.(a,.(b,.(c,[])))
co na rysunku mona przedstawi jako
. .-.-.-[]
/ \ | | |
a . a b c
/ \
b .
/ \
c []
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
34 ROZDZIA 4. LISTY
W notacji z nawiasami kwadratowymi powysze przykady zapisujemy, odpowiednio,
jako
[a]
[a,b,c]
4.2 Gowa i ogon
Listy zawsze przetwarza si dzielc je na dwie (logiczne) czci: gow (ang. head), ktr
stanowi pierwszy element listy (i zarazem pierwszy argument funktora .) i ogon (ang.
tail) (stanowicego drugi argument funktora .), ktry jest wszystkim co pozostao z listy
po odjciu od niej gowy. Lista pusta nie ma gowy ani tym bardziej ogona. Gow
listy zawierajcej tylko jeden element jest ten wanie element, natomiast ogon jest list
pust.
Do rozdzielenia (rozoenia) listy
1
na gow i ogon suy symbol |. Elementy po lewej
stronie symbolu odnosz si do gowy lub do kilku pierwszych elementw listy, natomiast
po prawej oznaczaj gow
?- []=[H|T].
No
?- [1,2]=[H|T].
H = 1,
T = [2]
?- [1]=[H|T].
H = 1,
T = []
?- [1,[2,3]]=[H|T].
H = 1,
T = [[2, 3]]
?- [[1,2],3]=[H|T].
H = [1, 2],
T = [3]
?- [1,2,3,4]=[Ha,Hb|T].
Ha = 1,
Hb = 2,
T = [3, 4]
?- [[1,2,3],4]=[[H1|T1]|T2].
H1 = 1,
T1 = [2, 3],
T2 = [4]
Przygldajc si powyszym przykadom zauwaamy, e
1
Uywany take do konstruowania listy.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
4.2. GOWA I OGON 35
Ogon listy, jeli tylko istnieje, jest zawsze list (pust lub nie, ale list).
Gowa (a w oglnoci: wszystkie elementy wystpujce przed |) jest elementem
listy i jako element listy moe by dowolnym termem (a zatem moe, ale nie musi
by list).
Zaskakujce, e to ju wszystko co o listach, rozpatrywanych czysto teoretycznie,
mona powiedzie. Zaskakujce dlatego, e lista jest gwn (w sensie siy czy moli-
woci) struktur danych Prologu. Prostota ta sprawia, e czasem a trudno uwierzy, e
co bedzie dziaa, a gdy ju dziaa to trudno zrozumie jak to si dzieje. Dlatego, celem
lepszego zapoznania ze sposobami postpowania z listami, sprbujemy zdeniowa kilka
predykatw, pozwalajcych wykona pewne elementarne operacje na listach.
Predykat sprawdzajcy czy co jest list.
Waciwie kady sposb w jaki staramy si rozwiza problem w Prologu to rekurencja.
Zaczynamy od najprostszego przypadku, po czym uoglniamy go na dowolnie zoony.
Nie inaczej jest w przypadku predykatu sprawdzajcego, czy co jest list. Najprostszy
przykad listy, to lista pusta. Wszystkie inne listy daj si natomiast rozoy na gow
i ogon, przy czym ogon musi by list. Std ostatecznie otrzymujemy
czyLista([]).
czyLista([H|T]) :- czyLista(T).
Predykat sprawdzajcy czy co naley do listy
W tym przypadku najprostszy warunek jest nastpujcy: element X naley do listy, jeli
X jest gow listy
isMember(X,[X|_]).
lub to samo w inny sposb
isMember(X,[Y|_]) :- X=Y.
Jeli natomiast nie jest gow, to musi nelee do ogona listy
isMember(X,[_|Y]) :- isMember(X,Y).
Jak to jednak czsto w Prologu bywa, zwykle kady predykat mona uy w celu zupenie
innym ni ten, do ktrego zosta przewidziany. W tym przypadku predykat isMemeber/2
moe zosta uyty po to aby wygererowa wszystkie elementy nalece do listy
?- isMember(X,[a,b,c]).
X = a ;
X = b ;
X = c ;
No
?- isMember(X,[a,[b,c],d]).
X = a ;
X = [b, c] ;
X = d ;
No
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
36 ROZDZIA 4. LISTY
Predykat czcy dwie listy
Przypadek elementarny: lista pusta poczona z list List daje w wyniku niezmienion
list
polacz([],List,List).
Przypadek oglny, ktry mona wyrazi opisowo: aby poczy co ([H|T]) z list (List),
trzeba najpierw doczy ogon tego czego (T) do listy (List) a nastpnie do wyniku tego
poczenia (Res) dopisa gow (H)
polacz([H|T],List,[H|Res]) :- polacz(T,List,Res).
Dziaanie zgodne jest z oczekiwaniem
?- polacz([1,2,3],[a,b,c],Res).
Res = [1, 2, 3, a, b, c]
a cig wywoa wyglda jak poniej
?- polacz([1,2,3],[a,b,c],Res).
gowa 1, cze [2, 3] z [a, b, c]
gowa 2 cze [3] z [a, b, c]
gowa 3 cze [] z [a, b, c] wynik to [a, b, c]
wynik to [3, a, b, c]
wynik to [2, 3, a, b, c]
Res = [1, 2, 3, a, b, c]
Podobnie jak poprzednio, take i tym razem moemy predykat polacz/3 uy, niezgod-
nie z jego pierwotnym przeznaczeniem, do znalezienia odpowiedzi na pytanie, jak list
naley poczy z list [1,2,3] aby otrzyma list [1,2,3,a,b,c]
?- polacz([1,2,3],X,[1,2,3,a,b,c]).
X = [a, b, c]
Co wicej, moemy poszukiwa wszystkich par list, ktre poczone daj nam [1,2,3,a,b,c]
?- polacz(X,Y,[1,2,3,a,b,c]).
X = [],
Y = [1, 2, 3, a, b, c] ;
X = [1],
Y = [2, 3, a, b, c] ;
X = [1, 2],
Y = [3, a, b, c] ;
X = [1, 2, 3],
Y = [a, b, c] ;
X = [1, 2, 3, a],
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
4.3. PYTANIA I ODPOWIEDZI 37
Y = [b, c] ;
X = [1, 2, 3, a, b],
Y = [c] ;
X = [1, 2, 3, a, b, c],
Y = [] ;
4.3 Pytania i odpowiedzi
Pytanie 4.1. Czym jest lista w prologu? Majc niepusty zbir obiektw K moemy
utworzy zbir jego wszystkich podzbiorw oznaczany formalnie 2
K
. List elementw z
K moemy zatem utosami z pewnym elmentem nalecym do 2
K
. Generalnie lista
ma suy reprezentacji jakich danych, a te s z kolei reprezentowane w Prologu przez
termy. Listy s zatem take reprezentowane przez pewne termy i co wane, moe si to
odbywa na rne sposoby. W kadej licie moemy wyodrbni gow czyli jej pierwszy
element, (ktry sam moe by jak list!) oraz ogon, czyli pozosta jej cz.
Pytanie 4.2. Wymie moliwe sposoby zapisu listy.
.(X,Y) lista o nieokrelonej liczbie elementw. Jej gow jest X, ogonem Y.
[X|Y] j.w.
[X,Y] dokadnie dwuelementowa lista o gowie X i ogonie Y, przy czym zarwno X
jak i Y mog by listami.
Oto kilka przykadw mogcych uatwi zrozumienie rznic midzy powyszymi repre-
zentacjami. Bazuj one na zmuszeniu Prologu do rozwizania za nas problemu: ktre z
tych schematw i kiedy s sobie rwnowane?
?- .(X,X)=X.
X = [**, **, **, **, **, **, **, **, **|...] ;
No
?- [X,X]=X.
X = [**, **] ;
No
?- [X|X]=X.
X = [**, **, **, **, **, **, **, **, **|...] ;
No
?- [1,X] = X.
X = [1, **] ;
No
?- [1|X] = X.
X = [1, 1, 1, 1, 1, 1, 1, 1, 1|...] ;
No
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
38 ROZDZIA 4. LISTY
?- .(1,X) = X.
X = [1, 1, 1, 1, 1, 1, 1, 1, 1|...] ;
No
?- [X,Y] = [X|Y].
Y = [**] ;
No
?- [X,Y] = [X|[Y]].
Yes
?- .(X,Y) = [X,Y].
Y = [**] ;
No
?- .(X,.(Y,[])) = [X,Y].
Yes
?- .(X,Y) = [X|Y].
Yes
Pytanie 4.3. Podaj przykad wykorzystania listy. Wemy program, ktry liczy
ilo elementw listy:
card([],0).
card([H|T], X) :- card(T, Y), X is Y + 1.
Mona go wykorzysta do dalszego sprawdzania jak dziaaj reprezentacje list:
?- card([a|[b]],Y).
Y = 2 ;
No
?- card([a|[b,c,d]],Y).
Y = 4 ;
No
?- card([a,[b,c,d]],Y).
Y = 2 ;
No
?- card([a,b,c,d],Y).
Y = 4 ;
No
Mona si w ten sposb bardzo dugo bawi... warto jednak uwanie spojrze na ponisze
wyniki:
?- card([a,Y],H).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
4.3. PYTANIA I ODPOWIEDZI 39
H = 2 ;
No
?- card([a|Y],H).
Y = [],
H = 1 ;
Y = [_G266],
H = 2 ;
Y = [_G266, _G269],
H = 3 ;
Y = [_G266, _G269, _G272],
H = 4 ;
Y = [_G266, _G269, _G272, _G275],
H = 5
[Ctrl+C]
Action (h for help) ? [b] break
?- card(.(a,Y),H).
Y = [],
H = 1 ;
Y = [_G813],
H = 2 ;
Y = [_G813, _G816],
H = 3 ;
Y = [_G813, _G816, _G819],
H = 4
[Ctrl+C]
Action (h for help) ? [b] break
Powyszy eksperyment potwierdza tezy dotyczce iloci elementw na poszczeglnych li-
stach.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
40 ROZDZIA 4. LISTY
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 5
Odcicie
5.1 Wiele rozwiza
Mechanizm odcicia pozwala zaniecha nawracania przez Prolog do wczeniej dokona-
nych wyborw. Zajmijmy si na pocztek wieloma rozwizaniami. Zamy, i mamy w
bazie nastpujce fakty
a(b,c).
a(b,d).
a(e,f).
a(d,g).
Wydajc zapytanie
?- a(X,Y).
otrzymamy nastpujacy cig odpowiedzi
?- a(X,Y).
X = b Y = c ;
X = b Y = d ;
X = e Y = f ;
X = d Y = g ;
No
Dziki nawracaniu znajdowane s wszystkie rozwizania z bazy danych. Prolog w
adnym przypadku nie analizuje czy te nie zapamituje zwracanych wynikw. Std te
wynikiem zapytania
?- a(X,_).
jest
?- a(X,_).
X = b ;
X = b ;
X = e ;
X = d ;
No
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
42 ROZDZIA 5. ODCICIE
Jak wida odpowied X = b pojawia si dwukrotnie, ale z punktu widzenia jzyka s to
dwa rne rozwizania.
Pamitajmy, e w Prologu istotna jest kolejno wystpowania faktw i regu. Dla
programu
a(c).
a(X) :- b(X).
b(d).
b(e).
a(f).
a(g).
b(h).
a(i).
efektem zapytania a(X) jest
?- a(X).
X = c ;
X = d ;
X = e ;
X = h ;
X = f ;
X = g ;
X = i ;
No
Kolejno otrzymanych wynikw na pierwszy rzut oka moe by zaskoczeniem, ale po
uwaniejszym przyjrzeniu si im, wszystko powinno sta si jasne.
Krok 1 Prolog przeszukuje swoj baz wiedzy w poszukiwaniu faktu/reguy, ktre po-
zwol jemu ukonkretni zmienn X w zapytaniu a(X). Jako pierwszy z zapytaniem
unikuje si fakt a(c) i std pierwsza odpowied X = c.
Krok 2 Nastpnie z zapytaniem unikuje si regua a(X) :- b(X)., w zwizku z czym
Prolog bdzie stara si obliczy wszystkie cele z niej wynikajce, czyli w tym
przypadku b(X).
Krok 2.1 Z podcelem b(X) jako pierwszy unikuje si fakt b(d). To powoduje
spenienie caej reguy a(X) :- b(X). a tym samym i zapytania a(X) i std
druga odpowied X = d.
Krok 2.2 Nastpnie z podcelem b(X) unikuje si fakt b(e). To powoduje spe-
nienie caej reguy a(X) :- b(X). a tym samym i zapytania a(X) i std
trzecia odpowied X = e.
Krok 2.3 Nastpnie z podcelem b(X) unikuje si fakt b(h). To powoduje spe-
nienie caej reguy a(X) :- b(X). a tym samym i zapytania a(X) i std
czwarta odpowied X = h.
Krok 2.4 Poniewa nie ma ju niczego co pozwoli obliczy podcel b(X), wic tym
samym Prolog powraca do ostatniego punktu decyzyjnego, czyli poszukuje
faktu/reguy wystpujcych po regule a(X) :- b(X). i speniajcych zapy-
tanie a(X)..
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
5.1. WIELE ROZWIZA 43
Krok 3 Jako kolejny, z zapytaniem a(X) unikuje si fakt a(f). i std pita odpowied
X = f.
Krok 4 Jako kolejny, z zapytaniem a(X) unikuje si fakt a(f). i std szsta odpowied
X = g.
Krok 5 Jako kolejny, z zapytaniem a(X) unikuje si fakt a(f). i std sidma odpo-
wied X = i.
Krok 6 Brak unikatorw dla a(X). Zakoczenie oblicze dla zapytania.
Rozwamy teraz przykad z dwoma celami majcymi po kilka rozwiza.
a(X,Y) :- b(X), c(Y).
b(d).
b(e).
b(f).
c(g).
c(h).
c(i).
A oto uzyskany 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
Ponownie przeanalizujmy dlaczego otrzymalimy taki wanie wynik.
Krok 1 Prolog przeszukuje swoj baz wiedzy w poszukiwaniu faktu/reguy, ktre po-
zwol jemu ukonkretni zmiene X i Y w zapytaniu a(X,Y). Jako pierwsza z za-
pytaniem unikuje si regua a(X,Y) :- b(X), c(Y)., w zwizku z czym Prolog
bdzie stara si obliczy wszystkie cele z niej wynikajce, czyli w tym przypadku
najpierw b(X).
Krok 2.1 Z podcelem b(X) jako pierwszy unikuje si fakt b(d). To powoduje
spenienie pierwszego podcelu i ukonkretyzowanie zmiennej X przez d.
Krok 2.1.1 Prolog prbuje obliczy drugi z podceli reguy a(X,Y) :- b(X), c(Y).,
czyli c(Y). Jako pierwszy z takim podcelem unikuje si fakt c(g). To po-
woduje spenienie drugiego podcelu i ukonkretyzowanie zmiennej Y przez
g. Poniewa spenione zostay wszystkie podcele reguy, wic prolog
zwraca pierwsz odpowied X = d Y = g.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
44 ROZDZIA 5. ODCICIE
Krok 2.1.2 Nastpnie z podcelem c(Y) unikuje si fakt c(h). To powo-
duje spenienie drugiego podcelu i ukonkretyzowanie zmiennej Y przez h.
Poniewa spenione zostay wszystkie podcele reguy, wic prolog zwraca
drug odpowied X = d Y = h.
Krok 2.1.3 Nastpnie z podcelem c(Y) unikuje si fakt c(i). To powo-
duje spenienie drugiego podcelu i ukonkretyzowanie zmiennej Y przez i.
Poniewa spenione zostay wszystkie podcele reguy, wic prolog zwraca
trzeci odpowied X = d Y = i.
Krok 2.1.4 Poniewa nie ma ju niczego co pozwoli obliczy podcel c(Y),
wic tym samym Prolog powraca do ostatniego punktu decyzyjnego, czyli
poszukuje faktu/reguy wystpujcych po fakcie b(d) i pozwalajcych
obliczy podcel b(X).
Krok 2.2 Jako kolejny z podcelem b(X) unikuje si fakt b(e). To powoduje
spenienie pierwszego podcelu i ukonkretyzowanie zmiennej X przez e.
Krok 2.2.1 Prolog prbuje obliczy drugi z podceli reguy a(X,Y) :- b(X), c(Y).,
czyli c(Y). Jako pierwszy z takim podcelem unikuje si fakt c(g). To po-
woduje spenienie drugiego podcelu i ukonkretyzowanie zmiennej Y przez
g. Poniewa spenione zostay wszystkie podcele reguy, wic prolog
zwraca czwart odpowied X = e Y = g.
Krok 2.2.2 Nastpnie z podcelem c(Y) unikuje si fakt c(h). To powo-
duje spenienie drugiego podcelu i ukonkretyzowanie zmiennej Y przez h.
Poniewa spenione zostay wszystkie podcele reguy, wic prolog zwraca
pit odpowied X = e Y = h.
Krok 2.2.3 Nastpnie z podcelem c(Y) unikuje si fakt c(i). To powo-
duje spenienie drugiego podcelu i ukonkretyzowanie zmiennej Y przez i.
Poniewa spenione zostay wszystkie podcele reguy, wic prolog zwraca
szst odpowied X = e Y = i.
Krok 2.2.4 Poniewa nie ma ju niczego co pozwoli obliczy podcel c(Y),
wic tym samym Prolog powraca do ostatniego punktu decyzyjnego, czyli
poszukuje faktu/reguy wystpujcych po fakcie b(e) i pozwalajcych
obliczy podcel b(X).
Krok 2.3 Jako kolejny z podcelem b(X) unikuje si fakt b(f). To powoduje
spenienie pierwszego podcelu i ukonkretyzowanie zmiennej X przez f.
Krok 2.3.1 Prolog prbuje obliczy drugi z podceli reguy a(X,Y) :- b(X), c(Y).,
czyli c(Y). Jako pierwszy z takim podcelem unikuje si fakt c(g). To po-
woduje spenienie drugiego podcelu i ukonkretyzowanie zmiennej Y przez
g. Poniewa spenione zostay wszystkie podcele reguy, wic prolog
zwraca czwart odpowied X = f Y = g.
Krok 2.3.2 Nastpnie z podcelem c(Y) unikuje si fakt c(h). To powo-
duje spenienie drugiego podcelu i ukonkretyzowanie zmiennej Y przez h.
Poniewa spenione zostay wszystkie podcele reguy, wic prolog zwraca
pit odpowied X = f Y = h.
Krok 2.3.3 Nastpnie z podcelem c(Y) unikuje si fakt c(i). To powo-
duje spenienie drugiego podcelu i ukonkretyzowanie zmiennej Y przez i.
Poniewa spenione zostay wszystkie podcele reguy, wic prolog zwraca
szst odpowied X = f Y = i.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
5.1. WIELE ROZWIZA 45
Krok 2.3.4 Poniewa nie ma ju niczego co pozwoli obliczy podcel c(Y),
wic tym samym Prolog powraca do ostatniego punktu decyzyjnego, czyli
poszukuje faktu/reguy wystpujcych po fakcie b(f) i pozwalajcych
obliczy podcel b(X).
Krok 3 Brak unikatorw dla a(X,Y). Zakoczenie oblicze dla zapytania.
Czasem nawet, celowo lub przez przypadek, moemy wygenerowa nieskoczon ilo
rozwiza
a(0).
a(X) :- a(Y), X is Y+1.
Wydajc teraz zapytanie a(X), otrzymywa bdziemy wszystkie kolejne liczby cakowite
poczwszy od 0.
?- a(X).
X = 0 ;
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
X = 5
...
itd.
Wyjanienie takiego zachowania Prologu jest bardzo proste (prosz porwna z drzewem
wywoa).
Krok 1 Prolog przeszukuje swoj baz wiedzy w poszukiwaniu faktu/reguy, ktre po-
zwol jemu ukonkretni zmienn X w zapytaniu a(X). Jako pierwszy z zapytaniem
unikuje si fakt a(0) i std pierwsza odpowied X = 0.
Krok 2 Nastpnie z zapytaniem unikuje si regua a(X) :- a(Y), X is Y+1., w zwizku
z czym Prolog bdzie stara si obliczy wszystkie cele z niej wynikajce, czyli w
tym przypadku a(Y) oraz X is Y+1..
Krok 2.1 Z podcelem a(Y) jako pierwszy unikuje si fakt a(0). To powoduje
spenienie pierwszego podcelu i ukonkretyzowanie zmiennej Y przez warto
0. Prolog zwraca pierwsz odpowied X = 0.
Krok 2.1.1 Prolog prbuje obliczy drugi z podceli reguy, czyli X is Y+1.
Obliczenie tego podcelu powoduje ukonkretyzowanie zmiennej X przez
warto 1. Prolog zwraca drug odpowied X = 1.
Krok 2.2 Nastpnie z podcelem a(Y) unikuje si regua a(X) :- a(Y), X is Y+1.,
w zwizku z czym Prolog bdzie stara si obliczy wszystkie cele z niej wy-
nikajce, czyli w tym przypadku a(Y) oraz X is Y+1..
Krok 2.2.1 Z podcelem a(Y) jako pierwszy unikuje si fakt a(0). To powo-
duje spenienie pierwszego podcelu i ukonkretyzowanie zmiennej Y przez
warto 0.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
46 ROZDZIA 5. ODCICIE
Krok 2.2.1.1 Prolog prbuje obliczy drugi z podceli reguy, czyli X is Y+1.
Obliczenie tego podcelu powoduje ukonkretyzowanie zmiennej X przez
warto 1. Tak wic w tym momencie, spenione s wszystkie podcele
podcelu a(Y) z kroku 2.2, co pozwala na ukonkretyzowanie zmiennej
Y z kroku 2 przez warto 1.
Krok 2.2.2 Prolog prbuje obliczy drugi z podceli reguy z kroku 2, czyli
X is Y+1. Obliczenie tego podcelu powoduje ukonkretyzowanie zmiennej
X przez warto 2. Prolog zwraca trzeci odpowied X = 2. Nastpnie
Prolog kontynuuje prby unikacji za krokiem 2.2.1.
Krok 2.2.3 Kontynuacja prby unikacji za krokiem 2.2.1 a wic poszuki-
wanie unikatora dla a(Y) co pozwoli speni pierwszy podcel z kroku
2.2. Kolejnym unikatorem (pierwszym by fakt a(0) z kroku 2.2.1) jest
regua a(X) :- a(Y), X is Y+1.
. . . itd . . .
a(X).
|
1 +-a(0).
|
2 +-a(X):-a(Y),X is Y+1.---------+
| |(2.2.2)
2.1 +-a(0).-+ +-X=1+1--+-X=2+1--+-X=3+1
| | . . .
2.1.1 | +-X=0+1. . . .
| . . .
2.2 +-a(X):-a(Y),X is Y+1.-+--------+--------+
| . | |
2.2.1 +-a(0).-+ . +-X=1+1 +-X=2+1
| | . . .
2.2.1.1 | +------X=0+1 . .
| . .
2.2.3 +-a(X):-a(Y),X is Y+1.--+--------+
| . |
+-a(0).-+ . +-X=1+1
| | . .
| +-------X=0+1. .
| .
+-a(X):-a(Y),X is Y+1.---+------
| .
+-a(0).-+ .
| | .
| +--------------X=0+1.
|
+-a(X):-a(Y),X is Y+1.
... itd ...
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
5.2. ODCICIE 47
5.2 Odcicie
Wszystkie przykady jakie mielimy okazj do tej pory zobaczy w tym rozdziale, ilu-
struj mechanizm nawracania. Aby cho troch kontrolowa sposb realizacj programu w
Prologu moemy uywa operatora odcicia: !. Jeli Prolog natra na operator odcicia
w regule, nie bdzie nawraca z wyborem do wczeniejszych moliwoci. Przyjrzyjmy si
nastpujcemu programowi (rozwaanemu ju w tym rozdziale, ale bez symbolu odcicia)
a(X, Y) :- b(X), !, c(Y).
b(d).
b(e).
b(f).
c(g).
c(h).
c(i).
Po wydaniu zapytania a(X,Y). Prolog udzieli nastpujcych 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 ktrych X skonkretyzowane
zostao przez d.
Kiedy Prolog prbuje udzieli odpowiedzi na zapytanie a(X,Y) korzysta najpierw z
pierwszej linii programu. Aby jednak udzieli odpowidzi, musi najpierw zbada b(X), co
udaje si skonkretyzowa dla X = d. Nastpnie Prolog natraa na odcicie, co powoduje,
e ustala X = d jako jedyne rozwizanie dla X. Kontynuujc, badane jest wyraenie c(Y).
Pierwszym moliwym ukonkretyzowaniem zmiennej Y jes d. Nacinicie ; powoduje, i
Prolog poszukuje alternatywnych rozwiza dla c(Y). Zauwamy, e symbol odcicia
wystpi przed ukonkretyzowaniem zmiennej Y, przez co wci mona poszukiwa alter-
natyw dla Y. Nie moe jednak szuka alternatyw dla X.
Przyjrzyjmy si poniszemu przykadowi, pokazujcemu jak symbol odcicia moe
zmieni program. Teoretycznie z podanych niej faktw wida, e gdy X = e, wwczas
spenione jest b oraz c.
a(X) :- b(X), !, c(X).
b(d).
b(e).
b(f).
c(e).
Zastosowanie symbolu odcicia daje jednak, by moe nieoczekiwan, odpowied:
?- a(X).
No
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
48 ROZDZIA 5. ODCICIE
Gdyby pomin symbol odcicia, wwczas odpowiedzi byoby oczywicie
?- a(X).
X = e ;
No
Odcicie bdzie miao take wpyw na stosowanie innych regu. Zamy, e pewien
program ma dwie reguy dla celu a
a(X) :- b(X), !, c(X).
a(X) :- d(X).
b(e).
b(f).
c(g).
d(f).
Jeli teraz Prolog natra na odcicie w pierwszej regule, wwczas nie tylko bdzie to od-
cicie nawracania przy konkretyzowaniu zmiennej X, ale zostan take odcite pozostae
reguy dla a(X). Prolog nie bdzie bra pod uwag drugiej reguy. W tym przypadku
zapytanie a(X). zwrci
?- a(X).
No
Widzimy, i Prolog teoretycznie moe speni cel podstawiajc X = f. Najpierw jednak
Prolog stara si wykorzysta pierwsz regu, ale po natraeniu na odcicie musi on
porzuci wszystkie alternatywy dla a(X).
Zauwamy, e program zwrci No take dla zapytania a(f). Kiedy bowiem Prolog
stara si speni a(f) rozpoczyna od pierwszej reguy, gdzie pocztkowo odnosi sukces
speniajc regu b(f). Nastpnie natraa na symbol odcicia. Prbuje regu dla c(f),
lecz takich nie znajduje. Symbol odcicia powoduje, e nie moe on skorzysta z adnej
innej reguy poza tymi wykorzystanymi przed odciciem.
5.3 Pytania i odpowiedzi.
Pytanie 5.1. Jak dziaa mechanizm nawracania w Prologu? Podaj przykad.
Przypumy, e mamy pewien predykat a okrelony w programie przez zdania i reguy.
Zapiszmy oglnie regu dla a w postaci a() :- b(), c(), d(). przy czym funkcje b
, c , d s take deniowane zarwno przez fakty, jak i reguy oraz mog by relacjami
midzy jakimi zmiennymi. Mechanizm nawracania (czyli schemat postpowania Prologu
podczas przeszukiwania bazy wiedzy w celu udzielenia odpowiedzi na pytanie ?- a())
mona przedstawi nastpujco:
Przeszukiwanie linia po linii kodu programu w poszukiwaniu predykatu lub reguy o
nazwie a. Jeli jest to zdanie Prolog sprawdza, czy dla podanych zmiennych jest
ono prawdziwe. Wwczas zwraca Yes i sprawdza kolejn lini kodu. W pozostaych
przypadkach (zdanie jest faszywe lub nie da si okreli jego wartoci logicznej)
Prolog przechodzi od razu do kolejnej linii kodu.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
5.3. PYTANIA I ODPOWIEDZI. 49
Jeli odnaleziona bdzie regua, Prolog zacznie przeszukiwanie bazy w celu znale-
zienia odpowiedzi na zapytanie ?-b(). Uwaga: Baza wiedzy jest przeszukiwana
znw od pierwszej linii a nie od miejsca w ktrym wystpia regua dla a. Po znale-
zieniu piewszego zdania lub reguy dla b powtarza si schemat z poprzedniego punktu
i tak a do skonkretyzowania wszystkich argumentw b.
Nastpnie powtarzane s kroki z poprzednich punktw dla c oraz d i udzielana jest
odpwied Yes /No lub zwracane s wartoci zmiennych ktre speniaj zadan regu
i da si je znale w pierwszym kroku (np. jakiej iteracji).
Prolog kontynuuje poszukiwania zda/regu okrelajcych d (przy ustalonych uprzed-
nio zmiennych wystpujcych w a, b, c) i po znalezieniu odpowiedzi lub kolejnej
wartoci zmienej wypisuje odpowied. Dopiero wtedy, gdy wszystkie moliwoci
skonkretyzowania wolnych zmiennych w predykacie d zostan wyczerpane, Prolog
zaczyna poszukiwa kolejnych zda/regu dla c nie zmieniajc zmiennych zwi-
zanych przy okrelaniu b. Powtarzane s kroki z podpunktw 2 i dalszych a do
ponownego wypisania odpowiedzi lub wartoci zmiennych.
Po wyczerpaniu moliwoi okrelenia b Prolog kontynuuje szukanie zda/regu dla
a. Po znalezieniu kadej kolejnej powtarzane s znw wszystkie opisane ju kroki
a do wypisania odpowiedzi.
Mona przekona si o susznoci powyszej interpretacji na przykadzie programu znaj-
dujcego permutacje elemntw listy (z sortowania naiwnego). Kod programu:
usun(X,[X|Xs],Xs).
usun(X,[Y|Ys],[Y|Zs]) :- usun(X,Ys,Zs).
permutacja([],[]).
permutacja(Xs,[Z|Zs]) :- usun(Z,Xs,Ys), permutacja(Ys,Zs).
... i jego dziaanie:
6 ?- permutacja([6,3,4,7,9],X).
X = [6, 3, 4, 7, 9] ;
X = [6, 3, 4, 9, 7] ;
X = [6, 3, 7, 4, 9] ;
X = [6, 3, 7, 9, 4] ;
X = [6, 3, 9, 4, 7] ;
X = [6, 3, 9, 7, 4] ;
X = [6, 4, 3, 7, 9] ;
X = [6, 4, 3, 9, 7] ;
X = [6, 4, 7, 3, 9] ;
X = [6, 4, 7, 9, 3] ;
X = [6, 4, 9, 3, 7] ;
X = [6, 4, 9, 7, 3] ;
X = [6, 7, 3, 4, 9] ;
X = [6, 7, 3, 9, 4] ;
X = [6, 7, 4, 3, 9] ;
X = [6, 7, 4, 9, 3] ;
X = [6, 7, 9, 3, 4] ;
X = [6, 7, 9, 4, 3] ;
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
50 ROZDZIA 5. ODCICIE
X = [6, 9, 3, 4, 7] ;
X = [6, 9, 3, 7, 4] ;
X = [6, 9, 4, 3, 7] ;
X = [6, 9, 4, 7, 3] ;
X = [6, 9, 7, 3, 4] ;
X = [6, 9, 7, 4, 3] ;
X = [3, 6, 4, 7, 9] ;
X = [3, 6, 4, 9, 7] ;
X = [3, 6, 7, 4, 9] ;
X = [3, 6, 7, 9, 4] ;
X = [3, 6, 9, 4, 7] ;
X = [3, 6, 9, 7, 4]
Tak jak si tego spodziewalimy - najpierw poszukiwane s odpowiedzi dla pierwszych
ustalonych przez program argumentw, czyli znjdowana jest permutacja [6,3,4,7,9],
nastpnie cyfra 7 jest zastpowana kolejn moliw (9) i wyznaczana jest ostatnia cyfra
cigu (7), itd.
Pytanie 5.2. Na ile istotna dla Prologu jest kolejno faktw i regu? Podaj
przykad. Jeli program dziaa deterministycznie i nie ma w nim odci, to kolejeno
faktw i regu ma wpyw jedynie na kolejno znajdowania (a zatem i wypisywania na
ekranie) odpowiedzi. Dokadniej jest o tym mowa w poprzednim pytaniu. Jeli nasze
zapytanie nie jest deterministyczne tzn. moe zosta wygenerowany nieskoczony cig
odpowiedzi, to kolejno predykatw w reguach i faktw moe by istotna. Np:
a(X,Y) :- c(X), b(Y).
c(0).
c(X) :- c(Y), X is Y-1.
b(0).
b(X) :- b(Y), X is Y+1.
zadziaa inaczej ni:
a(X,Y) :- b(X), c(Y).
c(0).
c(X) :- c(Y), X is Y-1.
b(0).
b(X) :- b(Y), X is Y+1.
o czym przekonuj nas wyniki, odpowiednio
?- a(C,D).
C = 0,
D = 0 ;
C = 0,
D = 1 ;
C = 0,
D = 2 ;
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
5.3. PYTANIA I ODPOWIEDZI. 51
oraz
?- a(C,D).
C = 0,
D = 0 ;
C = 0,
D = -1 ;
C = 0,
D = -2 ;
Formalnie pene zbiory odpowiedzi na powysze zapytanie dla obu regu s identyczne,
lecz biorc pod uwag fakt, e dysponujemy skoczonym czasem na znalezienie rozwiza,
wygenerowane zbiory nie bd si pokrywa poza punktem C=0, D=0.
Pytanie 5.3. Co nazywamy odcieciem? Zilustruj dziaanie tego mechanizmu
na przykaadzie. Operator odcicia (!) pojawiajcy si w regule spenia rol trwaego
podstawienia staych w miejsce zmiennych poprzedzajcych ten operator w obrbie reguy.
Jego dziaanie rozciga si jednak na wszystkie kolejne pojawienia si tych zmienych w
programie. Mona powiedzie, e ! przesuwa pocztek reguy do miejsca pojawienia si
w niej i redukuje ilo zmiennych w dalszym kodzie programu. Poniewa dziaanie tego
operatora zostao ju poparte przykadami na wykadzie proponuj, zbada jak zachowa
si nastpujcy program
eksperyment(Y) :- !.
spjrzmy:
?- eksperyment(X).
Yes
?- eksperyment(a).
Yes
?- eksperyment(1).
Yes
?- eksperyment(*).
Yes
?- eksperyment(_).
Yes
Okazuje si zatem, e powyszy zapis oznacza po prostu zdanie prawdziwe a zmienna X
nie ma okrelonego typu.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
52 ROZDZIA 5. ODCICIE
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 6
Wejcie i wyjcie. Operatory
6.1 Czytanie i pisanie termw
6.1.1 Czytanie termw
Najprostszym sposobem pobierania danych od uytkownika jest odczytywanie informacji
wprowadzonych za pomoc urzdzenia standardowego wejcia jakim zwykle jest klawia-
tura. Zadanie to realizuje predykat read. Niech dany bdzie nastpujcy program
a(1,b).
a(1,c).
a(2,d).
a(2,e).
e(X) :- read(Y),a(Y,X).
Efektem jego dziaania jest
?- e(X).
|: [1.][ENTER]
X = b ;
X = c ;
No
Zauwamy, e
Wprowadzony term musi koczy si znakiem kropki (.).
Predykat read mona uzgodni tylko raz. Jak wida w powyszym przykadzie,
Prolog podczas nawracania nie pyta ju o kolejne liczby. W tym przypadku na-
wracanie to mona wymusi predykatem repeat modykujc regu do postaci
e(X) :- repeat,read(Y),a(Y,X).
w efekcie czego otrzymujemy
?- e(X).
|: [1.][ENTER]
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
54 ROZDZIA 6. WEJCIE I WYJCIE. OPERATORY
X = b ;
X = c ;
|: [2.][ENTER]
X = d ;
X = e ;
...
Oglnie mwic predykat repeat/0 koczy si zawsze sukcesem przy pierwszym
jego wywoaniu a take we wszystkich wywoaniach bdcych wynikiem nawra-
cania. Predykaty wystpujce za repeat s wywoywane dopki wszystkie nie
zakocz si sukcesem. Dlatego najprostszym przykadem ptli nieskoczonej
w Prologu jest schemat repeat, ..., fail. Poniej przedstawiamy inny prosty
program wykorzystujcy predykat repeat
command_loop:-
write(repeat example),nl,
repeat,
write(Enter command (end to exit): ),
read(X),
write(X), nl,
X = end.
Efektem dziaania programu jest
?- command_loop.
Enter command (end to exit): [ala.][ENTER]
ala
Enter command (end to exit): [ma.][ENTER]
ma
Enter command (end to exit): [kota.][ENTER]
kota
Enter command (end to exit): [end.][ENTER]
end
More? [n] ;
Enter command (end to exit): [end.][ENTER]
end
More? [ENTER]
Yes
Jak widzimy SWI-Prolog zachowuje si w tym przypadku troch inaczej ni tego
si spodziewalimy. Mianowicie po wpisaniu end. wcale nie koczy dziania, ale
daj nam moliwo poszukiwania rozwiza alternatywnych. Jest to kontrolowana
anomalia ktrej wyjanienie jest nastpujce
1
.
1
rdo: http://gollem.science.uva.nl/twiki/pl/bin/view/FAQ/MorePrompt, stan z dnia 24
marca 2009 roku.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
6.1. CZYTANIE I PISANIE TERMW 55
SWI-Prolog prompts using "more?"
SWI-Prolog has two modes for prompting after proving a toplevel goal that is
controlled by the Prolog ag prompt_alternatives_on. Classical Prolog systems
prompt for alternatives if the toplevel goal contains variable, regardless whether or
not Prolog knows there are no alternatives. This mode is supported by the value
groundness for the prompt_alternatives_on ag.
By default however, prompt_alternatives_on is set to determinism, which means
Prolog prompts for alternatives if the goal succeeded with at least one choicepoint.
So, a goal as below indeed prompts for the proper alternatives.
test :-
member(X, [hello, world]), writeln(X).
?- test.
hello
More? ;
world
More? ;
No
Especially for the more serious developer, it is important that predicates that are
designed to leave no choicepoints actually behave like this. This current prompt
mode often spots such problems during the debugging phase, where developers
often run test queries from the toplevel. You can use the graphical debugger
(gtrace/0) to nd the choicepoint.
Inny prosty przykad programu pobierajcego dane, to program obliczajcy pole
powierzchni kwadratu
kwadrat :- read(X), licz(X).
licz(stop) :- !.
licz(X) :- C is X * X, write(C),kwadrat.
i efekt jego dziaania
?- kwadrat.
|: 4. [ENTER]
16 [ENTER]
|: stop. [ENTER]
Yes
6.1.2 Pisanie termw
Do wprowadzania informacji za pomoc urzdzenia standardowego wyjcia jakim zwy-
kle jest ekran suy predykat write. Predykat nl powoduje przejcie do nowej linii.
Podobnie jak read oba predykaty mona uzgodni tylko raz.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
56 ROZDZIA 6. WEJCIE I WYJCIE. OPERATORY
a(0) :- !.
a(N) :- write(ala ), nl, N1 is N-1, a(N1).
i efekt jego dziaania
?- a(3).
ala
ala
ala
Yes
6.2 Czytanie i pisanie znakw
6.2.1 Czytanie znakw
Do pobierania pojedyczych znakw sluy predykat get_char
?- get_char(Znak).
|: ala [ENTER]
Znak = a
Poniej przedstawiamy inny prosty przykad programu pobierajcego pojedycze
znaki tak dugo, jak wprowadzony znak rny jest od znaku q
a :- get_char(Z),write(wprowadzony znak: ), write(Z), nl, \+ (Z=q), a.
?- a.
|: ala ma kota [ENTER]
wprowadzony znak: a
wprowadzony znak: l
wprowadzony znak: a
wprowadzony znak:
wprowadzony znak: m
wprowadzony znak: a
wprowadzony znak:
wprowadzony znak: k
wprowadzony znak: o
wprowadzony znak: t
wprowadzony znak: a
wprowadzony znak:
|: q
wprowadzony znak: q
No
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
6.3. CZYTANIE Z PLIKU I PISANIE DO PLIKU 57
6.2.2 Pisanie znakw
Wywoanie celu put_char(X), w przypadku gdy zmienna X ukonkretniona jest znakiem,
powoduje jego wypisanie.
?- put_char(a).
a
Yes
?- put_char(a).
a
Yes
6.3 Czytanie z pliku i pisanie do pliku
6.3.1 Czytanie z pliku
W Prologu, jak wikszoci jzykw programowania, pojcie standardowego wejcia/wyjcia
uoglnia si na pojcie strumienia wejciowego/wyjciowego, ktre zwizane mog by
z dowolnym urzdzeniem wprowadzajcym/wyprowadzajcym dane jak np. klawiatura,
monitor, plik itd.
Isniejce w Prologu wbudowane strumienie user_input oraz user_output odpowia-
daj klawiaturze i monitorowi. Praca z plikami moliwa jest dziki predykatom
open jest to predykat sucy do powizania strumienia z plikiem.
close jest to predykat pozwalajcy zakoczy prac z plikiem.
Typowy program czytajcy dane z pliku ma nastpujcy schemat
czytajPlik :-
open(dane.txt,read,X),
kodOdczytujacy(X),
close(X).
Argumenty predykatu open maj nastpujce znaczenie
Pierwszy argument (dane.txt) to nazwa pliku, ktry chcemy otworzy.
Drugi argument (read) to jeden z trybw:
read otwarcie do odczytu istniejcego pliku;
write utworzenie nowego pliku do zapisu (jeli plik istnieje, zostanie usu-
nity);
readwrite tryb zapisu i odczytu (jeli plik istnieje to zostanie otworzony
plik istniejcy w przeciwnym razie plik zostanie utworzony);
append istniejcy plik zostanie otworzony do dopisywania.
Trzeci argument (X) to zmienna, ktra zostanie zwizana ze strumieniem.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
58 ROZDZIA 6. WEJCIE I WYJCIE. OPERATORY
Aby w predykacie kodOdczytujacy mc odczyta (zapisa) dane z (do) pliku, jak
ze standardowego wejcia (wyjcia), naley najpierw zmieni strumie wejciowy (wyj-
ciowy). Zmiana biecego strumienia wejciowego i wyjciowego odbywa si za pomoc
predykatw set_input oraz set_output. Predykaty current_input oraz current_output
pozwalaj sprawdzi jak aktualnie ustawione s strumienie.
Uwzgldniajc te nowe predykaty, typowy program czytajcy plik powinien wyglda
tak
czytajPlik :-
open(dane.txt,read,X),
current_input(CI),
set_input(X),
kodOdczytujacy,
close(X),
set_input(CI).
Uzupenijmy teraz kod o brakujcy predykat kodOdczytujcy
czytajPlik :-
open(dane.txt,read,X),
current_input(CI),
set_input(X),
kodOdczytujacy,
close(X),
set_input(CI).
kodOdczytujacy :- read(Term), obsluz(Term).
obsluz( end_of_file ) :- !.
obsluz(Term) :- write(Term),nl,kodOdczytujacy.
Efekt dziaania tego programu na pliku dane.txt
linia. 1.
linia. 2.
linia. 3.
i. linia. 4.
a. to. jest. ostatnia. linia. 5.
wyglda nastpujco
?- czytajPlik.
linia
1
linia
2
linia
3
i
linia
4
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
6.3. CZYTANIE Z PLIKU I PISANIE DO PLIKU 59
a
to
jest
ostatnia
linia
5
Yes
Zwrmy uwag na konieczno uywania znaku kropki (.) po kadym wyrazie. Jego
pominicie w pliku z danymi, np.
linia. 1.
linia 2.
linia. 3.
powoduje wypisanie komunikatu
?- czytajPlik.
linia
1
ERROR: (dane.txt:2):
Unhandled exception: dane.txt:2:0: Syntax error: Operator expected
Znak kropki mona pomin jeli uyjemy w odpowiednim miejscu znaku apostrof ()
lub cudzysw ("). Uywajc znaku , np.
linia. 1.
linia 2.
linia. 3.
efektem dziaania programu jest
?- czytajPlik.
linia
1
linia 2
linia
3
Yes
Uywajc znaku ", np.
linia. 1.
"linia 2".
linia. 3.
efektem dziaania programu jest
?- czytajPlik.
linia
1
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
60 ROZDZIA 6. WEJCIE I WYJCIE. OPERATORY
[108, 105, 110, 105, 97, 32, 50]
linia
3
Yes
6.3.2 Pisanie do pliku
Na podobnych zasadach opiera si pisanie do pliku. Uruchamiajc program
zapisz :-
open(out.txt,write,X),
current_output(CO),
set_output(X),
kodZapisujacy,
close(X),
set_output(CO).
kodZapisujacy :- read(X),\+ (X=quit),write(X),nl,flush,kodZapisujacy.
i wprowadzajc dane jak poniej
?- zapisz.
|: ala ma kota.
|: w jasne ciapki.
|: quit.
No
w pliku out.txt powinny znale si nastpujce dane
ala ma kota
w jasne ciapki
6.4 Operatory
6.4.1 Priorytet
Kolejno znakw (, /, +, ) to jedne z pierwszych praw matematycznych jakie
poznajemy na samym pocztku naszej edukacji. Potem dowiadujemy si, e te znaki na-
zywa si operatorami a kolejno ich rozpatrywania w wyraeniu to wanie priorytet
(ang. precedence). Dziki temu wiemy, e wynikiem dziaania
5 + 3 4
nie jest 32 lecz 17. Mocniejsze wizanie operatora sprawia, e najpierw musimy wykona
mnoenie 3 prze 4 a dopiero potem wykona dodawanie. Gdyby oba operatory miay
identyczny priorytet, wwczas aby zachowa tak kolejno naleao by uy nawiasw
5 + (3 4).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
6.4. OPERATORY 61
W Prologu z kadym operatorem zwizana jest liczba cakowita nieujemna
2
okrela-
jca jego priorytet. Im mniejsza liczba tym wyszy priorytet operatora. Na przykad
operator * ma priorytet 400, natomiast + ma priorytet 500. Priorytet termw okrelony
jest przez liczb 0.
6.4.2 -xowo operatora
Kady operator moe wystpowa w jednej lub kilku wersjach, ktre nazywa bdziemy
xowoci (?), okrelajcych jego pooenie wzgldem operandw. Wyrniamy opera-
tory
inxowe a wic takie, ktre wystpuj pomidzy operandami, np. operator +
traktowany jako operator dodawania dwch liczb;
prexowe a wic takie, ktre wystpuj przed operandem, np. operator + trakto-
wany jako operator okrelajcy znak liczby;
postxowe a wic takie, ktre wystpuj za operandem, np. operator ! oznacza-
jcy silnie.
6.4.3 czno
Ostatni rzecz jaka pozostaje do prawidowego okrelenia operatora, jest jego aczno
(ang. associativity). Bez tego trudno jest powiedzie, czy wynikiem dziaania
9 6 2
bdzie 1 czy 5. W przypadku arytmetyki obowizuje zasada wykonywania dziaa o
identycznym priorytecie od lewej strony do prawej. Inaczej mwic, operatory te s
lewostronnie czne (ang. left-associative), czyli wymuszaj nastpujc kolejno
wykonywania dziaa
(9 6) 2
W Prologu czno okrelana jest za pomoc atomw (wzorcw) postaci afb, gdzie
a i b mog przyj warto x lub y, natomiast f okrela pooenie operatora. Znak
y powinno si rozumie jako na tej pozycji wystpuje term o priorytecie nie wikszym
od priorytetu operatora, natomiast x rozumiemy jako na tej pozycji wystpuje term o
priorytecie mniejszym od priorytetu operatora. Wszystkie moliwe wzorce przedstawiono
w tabeli 6.1. Zauwamy, e nie jest moliwe zagniedanie operatorw nie posiadajcych
cznoci (np. is, wzorzec xfx). Podobnie zachowuje si wzorzec fx, nie pozwalajc
napisa np. --3.
Sprawdmy jak okrelone s operatory wbudowane. Najpierw konkretny wybrany
?- current_op(Priorytet, Lacznosc, +).
Priorytet = 500,
Lacznosc = fx ;
Priorytet = 500,
2
W bdcym przedmiotem naszego zainteresowania SWI-Prolog-u mieci si ona pomidzy 0 a 1200.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
62 ROZDZIA 6. WEJCIE I WYJCIE. OPERATORY
Wzorzec czno Przykady
fx prex non-associative -
fy prex aczny (prawostronny)
xf postx non-associative
yf postx aczny (lewostronny)
xfx inx non-associative =, is
xfy inx prawostronnie czny ,
yfy inx nie ma sensu
yfx inx lewostronnie czny +, *
Tablica 6.1: Wzorce okrelajce czno operatorw w Prologu.
Lacznosc = yfx ;
No
Jak wida operator + wystpuje zarwno w wersji prexowej jak i inxowej. Teraz
sprbujmy wywietli informacje o wszystkich wbudowanych operatorach
?- current_op(Priorytet, Lacznosc, Operator).
Priorytet = 1150,
Lacznosc = fx,
Operator = (volatile) ;
Priorytet = 400,
Lacznosc = yfx,
Operator = << ;
Priorytet = 1200,
Lacznosc = fx,
Operator = (:-) ;
Priorytet = 1200,
Lacznosc = xfx,
Operator = (:-) ;
Priorytet = 700,
Lacznosc = xfx,
Operator = (@=<) ;
Priorytet = 700,
Lacznosc = xfx,
Operator = (is) ;
Priorytet = 500,
Lacznosc = yfx,
Operator = \/ ;
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
6.4. OPERATORY 63
Priorytet = 1200,
Lacznosc = xfx,
Operator = (-->) ;
Jak wida operator :- okrelania reguy take wystpuje zarwno w wersji prexowej
jak i inxowej. Sens wersji prexowej poznamy niebawem. Poza tym na licie znale
mona wiele egzotycznych operatorw, ktrych jeszcze nie poznalimy, jak np. @=< czy
-->.
6.4.4 Deniowanie wasnych operatorw
Zanim przejdziemy do deniowania wasnych operatorw zauwamy, e zapis
a-b*c
to inna forma zapisu
-(a,*(b,c))
Std wynika fakt, e operator arytmetyczny nie powoduje wykonania jakichkolwiek ob-
licze. Zapis 1+2 to nie jest to samo co 3. Jest to po prostu inny sposb zapisania
wyraenia +(1,2). I wanie wedg tej zasady moemy chcie zamiast
lubi(jas,malgosie).
pisa
jas lubi malgosie.
gdzie lubi to nasz operator. Prba jego uycia bez wczeniejszego zdeniowania skazana
jest na porak
?- jas lubi malgosie.
ERROR: Syntax error: Operator expected
ERROR: jas
ERROR: ** here **
ERROR: lubi malgosie .
Zdeniujmy zatem nasz operator
?- op(500, xfx, lubi).
Yes
i sprbujmy go uy. Najpierw elementarny test, np.
?- lubi(jas,malgosie) = jas lubi malgosie.
Yes
Natomiast program
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
64 ROZDZIA 6. WEJCIE I WYJCIE. OPERATORY
lubi(zosia,karola).
kaska lubi antka.
pojdaDoKawiarni(X,Y) :- X lubi Y.
zwrci nastpujce wyniki
?- pojdaDoKawiarni(X,Y).
X = zosia,
Y = karola ;
X = kaska,
Y = antka
Konieczno deniowania operatorw za kadym razem gdy uruchamiamy Prolog jest
bardzo mao praktyczna, ale na szczcie mona deniowa obiekty na etapie kompilacji
programu. Pozwala na to moliwo tworzenia regu bez gowy. Napiszmy np. taki
program
:- write(Witaj swiecie).
:- write(Witaj jeszcze raz).
Uruchomienie programu spowoduje wykonanie wszystkich regu bez gowy
?- [t].
Witaj swiecieWitaj jeszcze raz
% t compiled 0.00 sec, -120 bytes
Yes
lub
?- consult(t).
Witaj swiecieWitaj jeszcze raz
% t compiled 0.00 sec, 0 bytes
Yes
Zatem wystarczy do programu doda regu
:- op(500, xfx, lubi).
i po uruchomieniu moemy korzysta z operatora lubi
?- [t].
% t compiled 0.00 sec, 1,140 bytes
Yes
?- zosia lubi karola.
Yes
Ciekawym, cho raczej mao uytecznym, rozwizaniem jest moliwo przeciania
operatorw wbudowanych
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
6.5. PYTANIA I ODPOWIEDZI 65
?- X is 2+3*5.
X = 17
Yes
?- op(100,yfx,+).
Yes
?- X is 2+3*5.
X = 25
Yes
6.5 Pytania i odpowiedzi
Pytanie 6.1. Co to jest operator?
Pytanie 6.2. Co okrela operator?
Pytanie 6.3. Podaj przykad wasnego operatora i jego uycia
Pytanie 6.4. Co to jest priorytet operatora?
Pytanie 6.5. Co to jest czno operatora?
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
66 ROZDZIA 6. WEJCIE I WYJCIE. OPERATORY
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 7
Predeniowane predykaty
7.1 Sprawdzanie typu termw
Prolog umoliwia manipulowanie termami (staymi, zmiennymi, liczbami, atomami) w
zalenoci od ich rodzaju dziki specjalnym procedurom systemowym pozwalajcym
okreli ich typ.
Predykat var(X) jest speniony, jeeli X jest zmienn woln (nie zwizan).
Predykat nonvar(X) jest speniony, jeeli X jest termem innym ni zmienna lub
jest zmienn zwizan.
Predykat integer(X) jest prawdziwy, jeeli X jest sta lub zmienn zwizan
cakowitoliczbow.
Predykat real(X) jest prawdziwy, jeeli X jest sta lub zmienn zwizan rzeczy-
wist.
Predykat atom(X) jest speniony, jeeli X jest sta lub zmienn zwizan atomow.
Predykat atomic(X) jest prawdziwy, jeeli X jest sta lub zmienn zwizan licz-
bow lub atomow.
?- var(X),X=2.
X = 2
Yes
?- X=2,var(X).
No
?- integer(X),X=2.
No
?- X=2,integer(X).
X = 2
?- X=2,integer(X),nonvar(X).
X = 2
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
68 ROZDZIA 7. PREDEFINIOWANE PREDYKATY
Yes
?- X = 1+1,integer(X).
No
?- X is 1+1,integer(X).
X = 2
?- X is 0.5+0.5,integer(X).
No
?- X is 0.5+0.5,float(X).
X = 1.0
?- atom(2).
No
?- atom(a).
Yes
?- atom(>).
Yes
?- atomic(2).
Yes
?- X=2,atomic(X).
X = 2
?- X=b,atomic(X).
X = b
?- atomic(p(1)).
No
?-
Rozwamy nastpujcy progrm Prologu
count(_,[],0).
count(A,[A|T],N) :- !,count(A,T,N1), N is N1 + 1.
count(A,[_|T],N) :- count(A,T,N).
Intencj nasz byo, aby predykat count(A,B,C) zlicza ilo C elementw A zadanej listy
B.
Yes
?- count(a,[a,b,a,a],N).
N = 3 ;
No
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
7.2. KONSTRUOWANIE I DEKOMPOZYCJA TERMW 69
?- count(a,[a,b,X,Y],N).
X = a
Y = a
N = 3 ;
No
?- Lista=[a,b,X,Y],count(a,Lista,Na),count(b,Lista,Nb).
Lista = [a, b, a, a]
X = a
Y = a
Na = 3
Nb = 1 ;
No
Jak jednak wida dziaanie nie do koca zgodne jest z naszymi oczekiwaniami. Zgodnie
bowiem z denicj predykatu count sprawdzane s nie faktyczne wystpienia szukanego
termu, lecz jego moliwe dopasowania.
Modykujc nieznacznie program i wykorzystaujac predykat atom uzyskamy pier-
wotnie planowane dziaanie.
count(_,[],0).
count(A,[B|T],N) :- atom(B),A=B,!,count(A,T,N1), N is N1 + 1.
count(A,[_|T],N) :- count(A,T,N).
Efekt dziaania zmodykowanego programu
?- Lista=[a,b,X,Y],count(a,Lista,Na),count(b,Lista,Nb).
Lista = [a, b, _G189, _G192]
X = _G189
Y = _G192
Na = 1
Nb = 1 ;
No
7.2 Konstruowanie i dekompozycja termw
Jak wiemy, w Prologu nie ma moliwoci zapytania o predykat, a wic nie jest moliwe
np. takie zapytanie
X(jas,malgosia).
ktre intuicyjnie rozumiemy jako pytanie o relacj laczc obiekt jas z obiektem malgosia.
Na szczcie w Prolog mamy do dyspozycji predykaty systemowe przeznaczone do kon-
struowania i dekompozycji termw. Predykat =.. suy do konstruowania termu z listy
atomw. Cel Term =.. Lista jest speniony, jeeli lista Lista zawiera nazw funktora
termu Term i wszystkie jego kolejne argumenty.
?- f(a,b)=..L.
L = [f, a, b]
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
70 ROZDZIA 7. PREDEFINIOWANE PREDYKATY
?- T=..[rectangle,3,5].
T = rectangle(3, 5)
?- Z=..[p,X,f(X,Y)].
Z = p(X, f(X, Y))
Predykat =.. wykorzysta mona do manipulowania termami opisujcymi rne klasy
obiektw w celu wykonania na nich jednej (tej samej) operacji, ale majcej inny przebieg
dla kadej klasy.
Zamy, e mamy pewien zestaw termw reprezentujcych gury geometryczne, np.
kwadrat(X),prostokat(X,Y), itd. Jako przykad rozwamy teraz term sucy do po-
wikszania gur o zadany czynnik. Chcieli bymy mc napisa
powieksz(FigOld,Czynnik,FigNew)
co powinno spowodowa powikszenie gury FigOld o czynnik Czynnik w wyniku czego
otrzymamy FigNew. Zadanie to moemy rozwiza w nastpujcy sposb.
powieksz(kwadrat(X),Y,kwadrat(X1)) :- X1 is F * X.
powieksz(prostokat(X,Y),Z,prostokat(X1,Y1)) :-
X1 is F * X, Y1 is F * Y.
Efektem dziaania bdzie
?- powieksz(kwadrat(3),3,kwadrat(X)).
X = 9
?- powieksz(kwadrat(3),3,A).
A = kwadrat(9)
Rozwizanie takie jest jak najbardziej poprawne, cho ma jedn wad: musimy z gry
uwzgldni wszystkie gury geometryczne, ewentualnie w razie koniecznoci, rozszerzy
denicj powieksz/3. Uoglniona denicja moe wyglda jak poniej.
powieksz(FO,C,FN) :- FO=..[Typ|Arg],
mnozliste(Arg,C,ArgNew),
FN=..[Typ|ArgNew].
mnozliste([],_,[]).
mnozliste([X|T],C,[X1|T1]) :-
X1 is X * C, mnozliste(T,C,T1).
Tym razem predykat powieksz bedzie dziaa dla dowolnych predykatw, bez potrzeby
ich wczeniejszego deniowania
?- powieksz(kwadrat(3),3,kwadrat(X)).
X = 9
?- powieksz(kwadrat(3),3,A).
A = kwadrat(9)
?- powieksz(szczupak(3,4,5),3,A).
A = szczupak(9, 12, 15)
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
7.3. PODSTAWIENIA, FUNKTOR, ARGUMENT 71
7.3 Podstawienia, funktor, argument
Do podstawiania za term innego termu suy predykat subst(SubT,T,Sub,Res). Jest on
speniony, jeeli wszystkie wystpienia termu SubT w termie T zostan zastpione przez
term Sub i otrzymamy w efekcie term Res.
?- subst(sin(x),2*sin(x)*f(sin(x)),t,F).
F = 2*t*f(t)
?- subst(a+b,f(a,A+B),v,T).
T = f(a,v)
A = a
B = b
Dla osb dociekliwych pokazujemy jak moe wyglda denicja tego predykatu
subst(Term,Term,Term1,Term1) :- !.
subst(_,Term,_,Term) :- atomic(Term),!.
subst(SubT,T,SubT1,T1):-
T=..[F|Arg],
substlist(SubT,Arg,SUbT1,Arg1),
T1=..[F|Arg1].
substlist(_,[],_,[]).
substlist(Sub,[T|Ts],Sub1,[T1|Ts1]):-
subst(Sub,T,Sub1,T1),
substlist(Sub,Ts,Sub1,Ts1).
Predykat functor(Term,F,N) jest speniony, jeeli F jest gwnym funktorem termu
Term, ktrego aruno wynosi N.
Predykat arg(N,Term,A) jest speniony, jeeli A jest N-tym argumentem termu Term,
przy zaoeniu, e numerowanie zaczyna si od 1.
?- functor(t(f(X),X,t),Func,Arity).
Func = t
Arity = 3
?- arg(2,f(X,t(a),t(b)),Y).
X = _G184
Y = t(a)
?- functor(D,data,3),
arg(1,D,30),
arg(2,D,czerwca),
arg(3,D,2007).
D = data(30,czerwca,2007).
7.4 Rne rnoci, rne rwnoci
Rodzaje relacji rwnoci/rnoci w Prologu:
X=Y, prawdziwy, gdy term X i Y unikuj si;
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
72 ROZDZIA 7. PREDEFINIOWANE PREDYKATY
X is E, prawdziwy, gdy X unikuje si z wartoci wyraenia E;
E1 =:= E2, prawdziwy, gdy wartoci wyrae E1 i E2 s rwne;
E1 =\= E2, prawdziwy, gdy wartoci wyrae E1 i E2 s rne;
T1 == T2, prawdziwy, gdy termy T1 i T2 s identyczne (identykuj si leksyklanie,
cznie z nazwami zmiennych);
T1 \== T2, prawdziwy, gdy termy T1 i T2 nie s identyczne.
?- X=5,X=5.
X = 5
?- X=5,X=2+3.
No
?- 5=X.
X = 5
?- 2+3=X.
X = 2+3
?- X=5,X is 2+3.
X = 5
?- 2+3 = 2+3.
Yes
?- 2+3 is 2+3.
No
?- X=2+3, X = 2+3.
X = 2+3
?- X=2+3, X is 2+3.
No
?- X=2+3, X =:= 2+3.
X = 2+3
?- 2+3 =:= 2+3.
Yes
?- X=2+3, 2+3 =:= X.
X = 2+3
?- 2+3 =:= 5.
Yes
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
7.5. MANIPULOWANIE BAZ DANYCH 73
?- 5 =:= 2+3.
Yes
?- f(a,b)==f(a,b).
Yes
?- f(a,b)==f(a,X).
No
?- f(a,X)==f(a,Y).
No
?- X\==Y.
Yes
?- t(X,f(a,Y))==f(X,f(a,Y)).
Yes
7.5 Manipulowanie baz danych
Traktujc program Prologu jako baz danych wyrni moemy
klauzule bezwarunkowe fakty reprezentujce jawne relacje;
klauzule warunkowe fakty reprezentujce niejawne relacje.
Do manipulowania baz klauzul su:
assert(C) zawsze speniony cel dodajcy klauzul C;
asserta(C) zawsze speniony cel dodajcy klauzul C na pocztku bazy;
assertz(C) zawsze speniony cel dodajcy klauzul C na kocu bazy;
retract(C) zawsze speniony cel usuwajcy klauzul C;
?- assert(p(a)),assert(p(b)),assertz(p(c)),assert(p(d)),asserta(p(e)).
Yes
?- p(X).
X = e ;
X = a ;
X = b ;
X = c ;
X = d
Dodawane klauzule funkcjonuj dokadnie tak samo jak klauzule zawarte w pierwotnym
programie. Zastosowanie powyszych predykatw umoliwia adaptowanie programu do
zmieniajcych si warunkw dziaania.
Niech dana bdzie nastpujca baza
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
74 ROZDZIA 7. PREDEFINIOWANE PREDYKATY
jestFajnie :- jestSlonce,not(padaDeszcz).
mozeByc :- jestSlonce,padaDeszcz.
jestBeznadziejnie :- padaDeszcz,jestMgla.
padaDeszcz.
jestMgla.
Operacje na bazie
?- jestFajnie.
No
?- jestBeznadziejnie.
Yes
?- retract(jestMgla).
Yes
?- jestBeznadziejnie.
No
?- assert(jestSlonce).
Yes
?- mozeByc.
Yes
?- retract(padaDeszcz).
Yes
?- jestFajnie.
Yes
7.6 Pytania i odpowiedzi
Pytanie 7.1. Kiedy i jak mona wykorzysta moliwos sprawdzania typu
termw?
Pytanie 7.2. W jaki sposb moemy uzyska informaj o funktorze lub jego
argumentach?
Pytanie 7.3. W jaki sposb moemy wpywa na struktur programu (np.
zmienia jego fakty)?
Pytanie 7.4. Jaka jest rnica pomidzy operatorem = a is?.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 8
Powtarzamy wiadomoci
8.1 O rekurencji raz jeszcze
W wiczeniach 13.1 pisalimy midzy innymi funkcje okrelajce pokrewiestwo. Za-
my, e dopiszemy teraz nastpujc relacj
potomek(Nastepca,Przodek) :- rodzic(Przodek,Nastepca).
potomek(Nastepca,Przodek) :- rodzic(Ktos,Nastepca),potomek(Ktos,Przodek).
Pierwsza denicja ma zastosowanie w prostej linii czyli w bezporedniej relacji Przodek
Nastepca. Druga denicja stosowana jest wwczas gdy Nastepca nie jest bezposrednio
potomkiem Przodka, ale za to ma rodzica (Ktos) ktry jest potomkiem Przodka i tutaj
oczywicie traamy na rekurencj.
Moe si to wydawa zaskakujce, ale sam rekurencj moemy napisa na wiele
sposobw.
8.1.1 Sposb 1
potomek(Nastepca,Przodek) :- rodzic(Ktos,Nastepca),potomek(Ktos,Przodek).
Od tego sposobu zaczlimy ten podrozdzia jest to chyba najbardziej naturalne po-
dejcie. Rozpoczynamy od poszukiwania rodzica Nastepcy a nastpnie pytamy, czy ten
rodzic (Ktos) jest potomkiem Przodka.
Poszukiwanie takie jest charakterystyczne wwczas gdy znamy Nastepce a poszuku-
jemy Przodka.
8.1.2 Sposb 2
potomek(Nastepca,Przodek) :- potomek(Ktos,Przodek),rodzic(Ktos,Nastepca).
Sposb bardzo podobny do poprzedniego, ale z zamienion kolejnocia celw w regule.
Rozpoczynamy od poszukiwania jakiegokolwiek potomka Przodka a nastpnie spraw-
dzamy czy znaleziony potomek (Ktos) jest rodzicem Nastepcy.
Zauwamy, e w tej sytuacji zanim natramy na waciwego nastpc (Ktos) Przodka
ktry okae si rodzicem Nastepcy moe mie miejsce wiele wywoa rekurencyjnych i
moemy otrzyma wielu potomkw, ktrzy jednak nie bd rodzicem Nastpcy. Z tego
te powodu, nie zaleca si stosowania rekurencji jako pierwszej z regu, cho czsto jest
to najbardziej intuicyjne podejcie.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
76 ROZDZIA 8. POWTARZAMY WIADOMOCI
8.1.3 Sposb 3
potomek(Nastepca,Przodek) :- rodzic(Przodek,Ktos),potomek(Nastepca,Ktos).
Porwnywalne do sposbu 1 jest nastpujce podejcie: szukamy kogo (Ktos) rodzicem
by Przodek a nastepnie sprawdzamy czy istnieje relacja potomek pomidzy Nastepca a
Ktos.
Poszukiwanie takie jest charakterystyczne wwczas gdy znamy Przodka a poszuku-
jemy Nastepcy. Zauwamy, e sposb ten okae si mniej wydajny od sposobu 1 jeli
ilo dzieci bdzie wiksza od 2 (ilo rodzicw wynosi 2).
8.1.4 Sposb 4
potomek(Nastepca,Przodek) :- potomek(Nastepca,Ktos),rodzic(Przodek,Ktos).
Ponownie, jak to miao miejsce dla sposobu 2, moemy opierajc si na sposobie 3 skon-
struowa sposb 4, ale z zamienion kolejnocia celw w regule. Z przyczyn opisanych
powyej, taki sposb zapisu nie jest zalecany ze wzgldu na moliwe obnienie wydajno-
ci.
8.2 Akumulator
Z pewnoci ju nie raz zetknlimy si z akumulatorem, cho wcale nie musielimy
zdawa sobie z tego sprawy. Czym wic jest w akumulator?
8.2.1 Przykad z list
Przyjrzyjmy si nastpujcym dwm denicjom funkcji obliczajcej dugo listy
1. len([],0).
len([_|Tail],Len) :- len(Tail,LenTail),
Len is LenTail + 1.
2. lenA(List,Len) :- lenA(List,0,Len).
lenA([],Len,Len).
lenA([_|Tail],Acc,Len) :- NewAcc is Acc + 1,
lenA(Tail,NewAcc,Len).
Zasadnicz rnic jest miejsce obliczania wyniku: len robi to powracajc z rekurencji,
natomiast lenA schodzc w rekurencji.
Przyjrzyjmy si co dokaadniej dziej si w obu funkcjach.
Funkcja len
?-len([a,b,c],X).
(11) X = 3
len([_|Tail],Len) <--- (1) pasuje do tego 2 + 1
(1) len([a,b,c] ,X) :- len([a,b],LenTail), (10) Len is LenTail + 1
(9) LenTail = 2
len([_|Tail],Len) 1 + 1
(2) len([a,b] ,LenTail) :- len([a],LenTail), (8) Len is LenTail + 1
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
8.2. AKUMULATOR 77
(7) LenTail = 1
len([_|Tail],Len) 0 + 1
(3) len([a] ,LenTail) :- len([],LenTail), (6) Len is LenTail + 1
(5) LenTail = 0
len([],0)
(4) len([],0)
Funkcja lenA
?-lenA([a,b,c],X).
(11) X = 3
lenA(List ,Len)
(1) lenA([a,b,c],X) :- lenA([a,b,c],0,Len).
(10) Len = 3
lenA([_|Tail],Acc,Len)
(2) lenA([a,b,c] ,0 ,Len) :- NewAcc is 0 + 1, lenA([b,c],1,Len)
(9) Len = 3
lenA([_|Tail],Acc,Len)
(3) lenA([b,c] ,1 ,Len) :- NewAcc is 1 + 1, lenA([c],2,Len)
(8) Len = 3
lenA([_|Tail],Acc,Len)
(4) lenA([c ],2 ,Len) :- NewAcc is 2 + 1, lenA([],3,Len)
(7) Len = 3
lenA([],Len,Len).
(5) lenA([],3 ,Len)
(6) Len = 3
Uycie akumulatora wymusza uycie dodatkowego argumentu w predykacie w przy-
kadzie jest to drugi argument: Acc. Dlatego zwykle uywa si funkcji opakowujcej np.
postaci
lenA(List,Len) :- lenA(List,0,Len).
co zwalnia uytkownika z koniecznoci podawania w zapytaniu wartoci inicjujcej (w
tym przypadku zera).
8.2.2 Przykad z liczbami
W wiczeniach 13.2 posugiwalimy si dosy specyczn denicj liczby naturalnej.
Majc funkcj nastpnika f moglimy dowoln liczb zapisa jako nastpnik nastpnika
nastpnika . . . nastpnika zera, np. 3 = f(f(f(0))). Okrelilimy tam m.in. dodawanie
takich liczb jako
add(0,X,X).
add(f(X),Y,f(Z)) :- add(X,Y,Z).
co powoduje nastpujcy cig wywoa
?-add(f(f(0)),f(f(f(0))),X).
(7) X = f(f(f(f(f(0)))))
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
78 ROZDZIA 8. POWTARZAMY WIADOMOCI
add(f(X) ,Y ,f(Z)) Z
(1) add(f(f(0)),f(f(f(0))),X ) :- add(f(0),f(f(f(0))),X)
(6) Z = f(f(f(f(0))))
add(f(X),Y ,f(Z)) Z
(2) len(f(0),f(f(f(0))),Z ) :- add(0,f(f(f(0))),X)
(5) Z = f(f(f(0)))
add(0,X ,X)
(3) len(0,f(f(f(0))),Z)
(4) Z = f(f(f(0)))
Wersja akumulatorowa dodawania przedstawia si nastpujco
addA(0,X,X).
addA(f(X),Y,Z) :- addA(X,f(Y),Z).
co powoduje nastpujcy cig wywoa
?-addA(f(f(0)),f(f(f(0))),X).
(7) X = f(f(f(f(f(0)))))
addA(f(X) ,Y ,Z) f(Y ) Z
(1) addA(f(f(0)),f(f(f(0))),X) :- addA(f(0),f(f(f(f(0)))),X)
(6) Z = f(f(f(f(f(0)))))
addA(f(X),Y ,Z) f(Y ) Z
(2) lenA(f(0),f(f(f(f(0)))),X) :- addA(0,f(f(f(f(f(0))))),X)
(5) Z = f(f(f(f(f(0)))))
addA(0,X ,X)
(3) lenA(0,f(f(f(f(f(0))))),Z)
(4) Z = f(f(f(f(f(0)))))
8.3 Z gry na d czy od dou do gry?
8.3.1 Z gry na d
Metoda obliczeniowa z gry na d (ang. top down computation), typowa dla Prologu,
rozpoczyna od problemu wyjciowego a nastpnie rozkad go na podproblemy prostsze
a te z kolei na jeszcze prostsze itd. a dojdzie do przykadu trywialnego. W ten oto
sposb rozwizanie duego zagadnienia stanowi rozwizanie wielu podproblemw prost-
szych. Jednym z najprostszych przykadw ilustrujcych tak metodologi obliczeniow
i programistyczn jest obliczanie wyrazw cigu Fibonacciego.
fibTD(0,0).
fibTD(1,1).
fibTD(N,X) :- N>1,
N1 is N-1,
N2 is N-2,
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
8.4. PYTANIA I ODPOWIEDZI 79
fibTD(N1,X1),
fibTD(N2,X2),
X is X1 + X2.
Jeli szukamy liczby Fibonacciego dla N > 1 obliczamy najpierw liczby Fibonacciego dla
N 1 oraz N 2 i uywajc tych rezultatw porednich obliczamy ostatecznie warto
dla N.
8.3.2 Z dou do gry
Metoda obliczeniowa z dou do gry (ang. bottom up computation) rozpoczyna od
znanych faktw a nastpnie rozszerza je w oparciu o posiadane reguy i fakty tak dugo
a nie zostanie rozwizany problem wyjciowy.
W oglnoci metoda ta jest mniej efektywna w porwnaniu z metod z gry na d
co spowodowane jest generowaniem duej iloci faktw nie majcych nic wsplnego z
poszukiwanym rozwizaniem. Z tego powodu w Prologu uywana jest metoda z gry
na d cho moliwe jest symulowanie metody z dou do gry przy wykorzystaniu
dodatkowych zmiennych wanie poznanych akumulatorw. Dziaanie takie ma o tyle
sens, e czsto funkcje wykorzystujce akumulator (czyli dziaajce z dou do gry)
okazuj si wydajniejsze od funkcji z gry na d.
fibBU(N,X) :- fibBU(0,0,1,N,X).
fibBU(N,X,_,N,X)
fibBU(N1,X1,X2,N,X) :- N1<N,
N2 is N1 + 1,
X3 is X1 + X2,
fibBU(N2,X2,X3,N,X).
Zauwamy, e zoono obliczeniowa dla tego przypadku jest liniowa w przeciwniestwie
do metody poprzedniej, gdzie bya wykadnicza.
8.4 Pytania i odpowiedzi
Pytanie 8.1. Co to jest akumulator? Podaj przykad.
Pytanie 8.2. Obliczenia z gry na d czy z dou do gry? Dlaczego?
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
80 ROZDZIA 8. POWTARZAMY WIADOMOCI
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 9
Sortowanie
W tym rozdziale nie poznamy raczej niczego nowego, ale wzorem rozdziau poprzed-
niego zawarte tutaj treci potraktujemy jako przypomnienie tego wszystkiego co byo
omawiane do tej pory. Jako przypomnienie, ale zarazem jako praktyczne wykorzysta-
nie do rozwizania konkretnych problemw. Przedmiotem naszych rozwaa bd rne
algorytmy sortujce. Zapewne doskonale znane s nam ich implementacje w jzykach
np. zorientowanych obiektowo, wic atwo bdziemy mogli porwna i oceni stopie
zoonoci kodu.
9.1 Sortowanie naiwne
Sortowanie naiwne to chyba najprostszy przykad sortowania. Algorytm jest niezwykle
prosty. Niech {c
i
}
i=1,...,n
bdzie cigiem, ktry ma zosta posortowany.
1. Wykonaj podstawienie {t
i
}
i=1,...,n
= {c
i
}
i=1,...,n
.
2. Sprawd czy cig {t
i
}
i=1,...,n
jest posortowany. Jeli tak, przejd do 5, jeli nie
kontynuuj.
3. Wygeneruj now permutacj cigu {c
i
}
i=1,...,n
i oznacz j t
{t
i
}
i=1,...,n
= perm({c
i
}
i=1,...,n
).
4. Id do 2.
5. Cig {t
i
}
i=1,...,n
jest posortowanym cigiem {c
i
}
i=1,...,n
. Koniec algorytmu.
Jak wic wida, generujemy kolejne permutacj zadanego cigu, sprawdzajc za ka-
dym razem, czy wygenerowana permutacja nie zawiera elementw w dobrej kolejnoci.
Implementacja tego algorytmu w Prologu jest niezwykle prosta.
nSort(X,Y) :- permutacja(X,Y), uporzadkowana(Y).
usun(X,[X|Xs],Xs).
usun(X,[Y|Ys],[Y|Zs]) :- usun(X,Ys,Zs).
permutacja([],[]).
permutacja(Xs,[Z|Zs]) :- usun(Z,Xs,Ys), permutacja(Ys,Zs).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
82 ROZDZIA 9. SORTOWANIE
uporzadkowana([_]).
uporzadkowana([X,Y|R]) :- X =< Y, uporzadkowana([Y|R]).
Schemat czynnoci wykonywanych podczas wykonywania przez programy wszelakich al-
gorytmw najatwiej zrozumie na przykadzie. Zacznijmy od sortowania listy jednoele-
mentowej, czyli zapytania, np.: ?- nSort([1],Y).
zgodnie z powyszym algorytmem wywoywany jest term
nSort([1],Y) :- permutacja([1],Y), uporzadkowana(Y).
Prolog natraa na term permutacja([1],Y), wic sprawdza swoj baz wiedzy w
poszukiwaniu odpowiedzi na pytanie ?- permutacja([1],Y).
Po dojciu do odpowiedniego termu Prolog buduje zdanie
permutacja([1],[Z|Zs]) :- usun(Z,[1],Ys), permutacja(Ys,Zs).
Teraz odszukiwana jest funkcja usun w celu otrzymania odpowiedzi na pytanie
?- usun(Z,[1],Ys). Zobaczmy, co Prolog znajduje
?- usun(Z,[1],Ys).
Z = 1,
Ys = [] ;
No
Majc powysze wartoci Z oraz Ys program moe je podstawi w odpowiednim
miejscu, co daje
permutacja([1],[1|Zs]) :- usun(1,[1],[]), permutacja([],Zs).
w bazie wiedzy odnajdywane jest zdanie permutacja([],[])., co prowadzi do
podstawienia Zs=[] i w konsekwencji okrelenia wartoci zmiennej Y w sposb:
Y=[1|[]]=[1].
Prolog kontynuuje obliczenia dla wyjciowego termu poszukujc w bazie wie-
dzy odpowiedzi na pytanie ?- uporzadkowana([1]). Poniewa znajduje si ono
explicite w bazie, udzielana jest odpowied Yes, zatem cay poprzednik wyjciowej
implikacji jest prawdziwy i wszystkie wolne zmienne (a zwaszcza Y) zostay podsta-
wione przez stae, co prowdzi do okelenia przez Prolog zdania nSort([1],[1]).
jako prawdziwego i w konsekwencji do wypisania na ekranie odpowiedzi
?- nSort([1],Y).
Y = [1] ;
No
Algorytm sortowania listy dwuelementowej bdzie rni si od powyszego gwnie na
etapie korzystania z funkcji permutacja(X,Y). Zatem przeledmy ten fragment dla
zapytania ?- permutacja([1,2],Y).:
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
9.1. SORTOWANIE NAIWNE 83
wywoywany jest term
permutacja([1,2],[Z|Zs]) :- usun(Z,[1,2],Ys), permutacja(Ys,Zs).
zatem (podobnie jak poprzednio) znajdowany jest zakres:
?- usun(Z,[1,2],Ys).
Z = 1,
Ys = [2] ;
Z = 2,
Ys = [1] ;
No
Zmienne s ukonkretniane najpierw przez pierwsz par Z=1,Ys=[2], zatem. . .
. . . Prolog stawia kolejne pytanie ?- permutacja([2],Zs). Zgodnie z analiz za-
chowania si Prologu w takiej sytuacji (przeprowadzon dla sortowania listy jed-
noelementowej) zostanie znaleziona warto Zs=[2].
Majc wszystkie zmienne okrelone i warto logiczn poprzednika implikacji prawda
program moe wypisa pierwsz permutacj, gdy [Z|Zs]=[1,2].
Nastpnym krokiem Prologu jest ukonkretnienie zmiennych Z i Ys przez drug
znalezion przez funkcj usun(Z,[1,2],Ys). par, mianowicie Z=2,Ys=[1]. Dalsze
postpowanie jest oczywicie identczne jak dla poprzedniej pary, doprowadzi wic
do znalezienia szukanej permutacji Y=[Z|Zs]=[2,1].
Zastanwmy si teraz jak zostanie rozwizany problem permutacji listy trjelemen-
towej [1,2,3]:
najpierw uruchomiona zostanie funkcja
?- usun(Z,[1,2,3],Ys).
Z = 1,
Ys = [2, 3] ;
Z = 2,
Ys = [1, 3] ;
Z = 3,
Ys = [1, 2] ;
No
a za pierwsz par rozwiza podstawione zostan Z=1,Ys=[2,3].
wywoanie funkcji permutacja([2,3],Zs). uruchomi algorytm znany z poprzed-
niego przykadu, czyli doprowadzi do znalezienia dwch pierwszych rozwiza w
postaci list [1,2,3], [1,3,2].
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
84 ROZDZIA 9. SORTOWANIE
podstawianie za zmienne Z oraz Ys kolejnych rozwiza da nastpne permutacje.
atwo domyli si, e rozwizania pojawi si w kolejnoci
[2,1,3], [2,3,1], [3,1,2], [3,2,1]
Oczywicie kadorazowo po znalezieniu jakiej permutacji wyjciowej listy (tzn. tej, ktra
jest argumentem f-cji nSort) wykonywana jest rekurencja uporzdkowana i dopiero, gdy
jest ona dla konkrtnej permutacji zdaniem prawidziwym, wypisywane jest rozwizanie
w postaci posortowanej listy lub... list! Niestety, gdy sortujemy t metod listy nier-
nowartociowe, to ilo (identycznych) rozwiza, ktre pojawi si na ekranie wynosi:
k

i=1
N
i
! gdzie k oznacza ilo rnych liczb w licie natomiast N
i
jest krotnosci wystpie-
nia itej wartoci. Np.: wyniki sortowania listy [1,1,1,2,2] pojawi si 12 razy. Mona
temu zapobiec, uywajc symbolu odcicia
nSort(X,Y) :- permutacja(X,Y), uporzadkowana(Y),!.
Symbol ten jest tym bardziej wskazany, gdy doskonale wiemy, e po znalezieniu posor-
towanej sekwencji nie ma sensu kontynuowa poszukiwa, bo innych sekwencji i tak si
nie znajdzie. Co najwyej znajdzie si sekwencje jedynie przez Prolog traktowane jako
inne
1
, np. wspomnian sekwencj [1,1,1,2,2], ktra wywietlona zostanie a 12 razy,
cho za kadym razem jest to taka sama sekwencja.
9.2 Sortowanie bbelkowe
Dziaanie algorytmu sortowania bbelkowego polega na porwnywaniu par elementw
znajdujcych si obok siebie i, jeli okazuje si to potrzebne, zmienianiu ich kolejnoci.
Kady element jest tak dugo przesuwany w cigu, a napotkany zostanie element wikszy
od niego, wtedy w nastpnych krokach przesuwany jest ten wikszy element.
Po pierwszym przebiegu cig nie musi by jeszcze uporzdkowany, ale na ostatniej
pozycji znajduje si maksymalny element cigu. Zatem w drugim przebiegu mona
sortowa krtszy podcig (z pominiciem elementu ostatniego). Po drugim przebiegu,
dwa najwiksze elementy s na swoich miejscach (na kocu cigu), a wic wystarczy
posortowa podcig o dwa elementy krtszy, itd
2
. Sortowanie koczy si, gdy podczas
kolejnego przejcia nie dokonano adnej zmiany.
Implementacja algorytmu w Prologu wyglda nastpujco.
bSort(List,Sorted) :- swap(List,List1), !, bSort(List1,Sorted).
bSort(Sorted,Sorted).
swap([X,Y|Rest],[Y,X|Rest]) :- X > Y.
swap([Z|Rest],[Z|Rest1]) :- swap(Rest,Rest1).
Zacznijmy tym razem od przeledzenia sortowania listy pustej, czyli od zapytania
?- bSort([],Sorted).
1
Traktowane jako inne, gdy w inny sposb uzyskane.
2
Algorytm mona usprawni jeszcze bardziej. Jeeli w pewnej iteracji ostatnia zamiana nastpia na
pozycji i, to w nastpnej wystarczy sortowa tylko elementy na pozycjach od 1 do i 1.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
9.2. SORTOWANIE BBELKOWE 85
Rozpatrywana jest pierwsza regua dotyczca tej funkcji, czyli
bSort([],Sorted) :- swap([],List1), !, bSort(List1,Sorted).
nastpnie, zgodnie z powyszym zapisem, poszukiwana jest odpowied na pytanie
?- swap([],List1).
Lista pusta nie pasuje do adnego z deniujcych swap schematw, wic zwracana
jest odpowied No i w konsekwencji regua nie jest speniona, zatem. . .
. . . Prolog przechodzi do prbowania drugiej, co skutkuje podstawieniem za zmienn
Sorted (w drugiej linii programu) listy pustej, co jest ostatecznym rozwizaniem
problemu, gdy otrzymujemy prawdziwe zdanie: bSort([],[]).
Sortowanie bbelkowe listy jednoelementowej jest analogiczne take i w tym przy-
padku predykat swap bdzie faszywy, wic pierwsza regua bSort nie zostanie speniona,
druga za zwraca wejciow list.
Przyjrzyjmy si sortowaniu listy dwuelementowej, np. [2,1].
Pierwsza regua, po podstawieniu argumentu, wyglda nastpujco
bSort([2,1],Sorted) :- swap([2,1],List1), !, bSort(List1,Sorted).
Prolog zaczyna wic znw od funkcji swap.
Na pytanie
?- swap([2,1],List1).
odpowiedzi udzieli ju pierwsza regua okrelajca ten predykat, gdy zmienne X i
Y s ju ukonkretnione odpowiednio przez 2 i 1, zatem speniony jest warunek X>Y
. Zostanie ukonkretniona zmienna List1=[1,2].
Poniewa Prolog zawsze szuka odpowiedzi posuwajc si jak najbardziej w gb,
a do znalezienia pierwszego rozwizania rozpatrywanego problemu, wic w tym
przypadku oznacza to, e nie zostanie wyprbowana druga z regu okrelajcych
swap. Dodatkowo symbol odcicia gwarantuje ustalenie zmiennej List1 a do
koca rozwizywania zadanego sortowania. Teraz program musi poradzi sobie z
zapytaniem
?- bSort([1,2],Sorted).
(), co oznacza, e znw uruchomi funkcj swap .
Dokadniej, po ukonkretnieniu zmiennych X i Z mamy
?- swap([1,2|[]],[2,1|[]]) :- 1>2.
zatem brana jest pod uwag druga regua
swap([1|[2]],[1|Rest1]) :- swap([2],Rest1).
Zgodnie z dyskusj sortowania listy jednoelementowej, udzielona zostanie odpo-
wied No, zatem zastosowana zostanie druga regua dotyczca bSort dla listy [1,2]
w punkcie (). Oznacza to, e otrzymamy Sorted=[1,2], co jest jednoczenie szu-
kanym wynikiem.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
86 ROZDZIA 9. SORTOWANIE
9.3 Sortowanie przez wstawianie
Sortowanie przez wstawianie przypomina postpowanie osoby ukadajcej ksiki na
pce. Wybieramy jedn ksik i szukamy (poczwszy od miejsca w ktrym ta ksika
si znajduje a do pierwszej ksiki od lewej) takiego miejsca aby tak ksika bya wysza
lub rwna od innej ksiki i jednoczenie mniejsza od kolejnej. Jeli znajdziemy takie
miejsce to wstawiamy w nie wybran ksik i bierzemy kolejn, ktra za ni wystpo-
waa. Jeli takiego miejsca nie znajdziemy to pozostawiamy j na dotychczasowej pozycji
i bieemy ksik nastpn.
Niech {a
i
}
i=1,...,n
bdzie sortowanym cigiem.
1. Niech j = 2.
2. Porwnywa element a
j
, po kolei, ze wszystkimi elementami a
i
, i = j 1, . . . , 1 do
momentu, gdy zostanie znaleziony taki element a
i
, dla ktrego zachodzi bdzie
nierwno a
i
a
j
. Wwczas element a
j
naley usun z jego dotychczasowej
pozycji, wstawi pomidzy elementy a
i
oraz a
i+1
i przej do kroku nastpnego.
3. Zwikszy j o jeden.
4. Jeli j > n to przejd do 6.
5. Powrt do 2.
6. Koniec.
Implementacja algorytmu w Prologu wyglda nastpujco.
iSort([],[]).
iSort([X|Tail],Sorted) :- iSort(Tail,SortedTail), insert(X,SortedTail,Sorted).
insert(X,[Y|Sorted],[Y|Sorted1]) :- X>Y, !, insert(X,Sorted,Sorted1).
insert(X,Sorted,[X|Sorted]).
Zacznijmy analiz od sortowania listy jednoelementowej:
?- iSort([1],Sorted).
Pierwsza w kodzie programu odpowiednia dla tego przypadku regua, to
iSort([1|[]],Sorted) :- iSort([],SortedTail),insert(1,SortedTail,Sorted).
Prolog prbuje zatem odpowiedzie na pytanie
?- iSort([],SortedTail).
co udaje si dziki pierwszej regule w programie. Otrzymujemy w ten sposb
podstawienie SortedTail=[].
Kolejne zapytanie, jakie napotyka program, to term
?- insert(1,[],Sorted).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
9.4. SORTOWANIE PRZEZ CZENIE 87
Z uwagi na argumenty, jakie ju si znajduj wewntrz tej funkcji, pierwsza regua
dla insert nie jest speniona, druga zwraca za zmienn Sorted=[1|[]]. Jej
ukonkretnienie powoduje spenenie pierwszej reguy dla iSort i jednoczenie jest
ona wypisywanym na ekran wynikiem.
Sortowanie listy dwuelementowej, czyli pytamy
?- iSort([1,2],Sorted).
Znw, pierwsza regua, ktr Prolog moe dopasowa do zapytania, to
iSort([1|[2]],Sorted) :- iSort([2],SortedTail),insert(1,SortedTail,Sorted).
Pierwsze napotkane w tej regule zapytanie iSort([2],SortedTail). ju rozpa-
trywalimy. Zmienna SortedTail zostaje skonkretyzowana list [2]. Prolog kon-
tynuuje regu, std pojawia si pytanie
?- insert(1,[2],Sorted).
ktre prowadzi do skorzystania z reguy
insert(1,[2|[]],[2|Sorted1]) :- 1>2,!,insert(1,[],Sorted1).
ktra oczywicie nie jest w tym przypadku speniona. Prolog przechodzi zatem
dalej: insert(1,[2],[1|[2]]). Zmienna Sorted z reguy iSort zostaje podsta-
wiona przez [1|[2]]=[1,2], co jest ostatecznym wynikiem sortowania.
9.4 Sortowanie przez czenie
Sortowanie przez scalanie (ang. merge sort), to rekurencyjny algorytm sortowania danych
realizujcy metod rozwizywania problemw typu dziel i zwyciaj (ang. divide and
conquer). Ide dziaania tego typu algorytmw jest podzia problemu na mniejsze czci,
ktrych rozwizanie jest ju atwiejsze a nastpnie w oparciu o rozwizane podproblemy
konstruowanie rozwizania problemu wyjciowego.
W algorytmie wyrniamy trzy zasadnicze kroki
1. Podzia sortowanego cigu na dwa podcigi o rwnej dugoci
3
.
2. Zastosowane sortowania przez scalanie dla kadego z podcigw niezalenie (o ile
tylko rozwaany podcig ma wicej ni jeden element).
3. Poczenie posortowanych podcigw w jeden cig posortowany.
Procedura scalania dwch podcigw {a
i
}
i=1,...,n
i {b
j
}
j=1,...,m
w cig {c
k
}
k=1,...,n+m
jest
prosta i szybka, gdy kady z podcigw jest ju posortowany.
3
Rwno ta nie musi by dosowna. Jeden z cigw moe by troch duszy. Termin troch jest
wzgldny i zaley od dugoci sortowanego cigu, ale jego intuicyjne znaczenie jest takie, e dugo obu
cigw powinna by, na ile to tylko moliwe, taka sama (zbliona).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
88 ROZDZIA 9. SORTOWANIE
1. Utworzenie wskanikw i i j wskazujcych na pocztki cigw {a
i
}
i=1,...,n
i {b
j
}
j=1,...,m
:
i = 1, j = 1.
2. Jeeli a
i
b
j
to naley element a
i
wstawi jako kolejny element cigu {c
k
}
k=1,...,n+m
i zwikszy i o jeden. W przeciwnym przypadku naley element b
j
wstawi jako
kolejny element cigu {c
k
}
k=1,...,n+m
i zwikszy j o jeden.
3. Jeeli i = n + 1 (przepisano ostatni element z cigu {a
i
}
i=1,...,n
), wwczas naley
do cigu {c
k
}
k=1,...,n+m
przepisa wszystkie nieprzepisane jeszcze elementy z cigu
{b
j
}
j=1,...,m
i przej do 6.
4. Jeeli j = m+1 (przepisano ostatni element z cigu {b
j
}
j=1,...,m
), wwczas naley
do cigu {c
k
}
k=1,...,n+m
przepisa wszystkie nieprzepisane jeszcze elementy z cigu
{a
i
}
i=1,...,n
i przej do 6.
5. Wr do 2.
6. Koniec.
Implementacja algorytmu w Prologu wyglda nastpujco
4
.
mSort([],[]).
mSort([X],[X]).
mSort(List,Sorted):- List=[_,_|_],polowa(List,L1,L2),
mSort(L1,Sorted1),mSort(L2,Sorted2),
myMerge(Sorted1,Sorted2,Sorted).
myMerge([],L,L).
myMerge(L,[],L) :- L\=[].
myMerge([X|T1],[Y|T2],[X|T]) :- X=<Y,myMerge(T1,[Y|T2],T).
myMerge([X|T1],[Y|T2],[Y|T]) :- X>Y,myMerge([X|T1],T2,T).
polowa(L,A,B):-polowa2(L,L,A,B).
polowa2([],R,[],R).
polowa2([_],R,[],R).
polowa2([_,_|T],[X|L],[X|L1],R) :- polowa2(T,L,L1,R).
W tekcie programu pojawiaj si jawnie predykaty okrelajce sortowanie listy pu-
stej i jednoelementowej zacznijmy wic od ?- mSort([1,2],Sorted).
Regua pozwalajca zacz rozwizywanie problemu przyjmuje posta
mSort([1,2],Sorted):- [1,2]=[_,_|_],polowa([1,2|[]],L1,L2),
mSort(L1,Sorted1),mSort(L2,Sorted2),
myMerge(Sorted1,Sorted2,Sorted).
po przypisaniu do wejciowej listy schematu w pierwszym kroku uruchamiana jest
funkcja ?- polowa([1,2|[]],L1,L2). Reguy dla tej funkcji daj
polowa([1,2|[]],A,B):-polowa2([1,2|[]],[1,2|[]],A,B).
4
W wiczeniu 9.2 zamieszczono inn wersj tego programu.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
9.4. SORTOWANIE PRZEZ CZENIE 89
a w konsekwencji
polowa2([1,2|[]],[1|[2]],[1|L1],R) :- polowa2([],[2],L1,R).
Teraz Prolog moe okreli zmienne L1=[] i R=[2] co daje z kolei skonkretyzowa
L1=A=[1] i L2=B=R=[2] z wyjciowego wywoania funkcji polowa.
Kolejny krok to udzielenie odpowiedzi na pytanie ?- mSort([1],Sorted1). Otrzy-
mujemy je z drugiej reguy okrelajcej ten predykat, tzn. Sorted1=[1]. Podobnie,
w kolejnym kroku znajdowana jest warto zmiennej Sorted2=[2].
Nastpny ruch Prologu to wywoanie
?- myMerge([1],[2],Sorted).
Pierwsza regua, ktrej schemat danych odpowiada temu zapytaniu, to
myMerge([1|[]],[2|[]],[1|T]) :- 1=<2,myMerge([],[2|[]],T).
Korzystajc nastpnie z pierwszej reguy dla myMerge okrelana jest zmienna T=[2|[]]=[2],
std za wynika, e zmienna Sorted ma warto [1|[2]]. Okrelone s zatem
wszystkie zmienne w caej regule sortowania dla wejciowej listy. Zwrcona zosta-
nie warto Sorted=[1,2]
Sortowanie listy trjelementowej, np. [3,2,1] przebiega oczywicie zgodnie ze sche-
matem narzuconym przez trzeci regu dla funkcji mSort. Algorytm zaczyna si jak
zwykle. . .
Okrelona zostaje zmienna List=[3,2|[1]].
Wywoywana jest funkcja ?- polowa([3,2|[1]],L1,L2). Oczywicie dopiero trze-
cia regua dla funkcji polowa2 jest speniona przez nasz schemat zmiennej List,
mamy zatem
polowa2([3,2|[1]],[3|[2,1]],[3|L1],R) :- polowa2([1],[2,1],L1,R).
w wyniku zadziaania drugiej reguy dla polowa2 okrelone zostaj zmienne L1=[]
oraz R=[2,1] , co daje wartoci L1=[3] oraz L2=[2,1] (dla funkcji polowa).
uruchamiana jest funkcja mSort kolejno dla list L1=[3] oraz L2=[2,1]. W konse-
kwencji zwracane s wartoci zmienych Sorted1=[3] oraz Sorted2=[1,2].
Kolejny krok to znalezienie wartoci zmiennej Sorted dziki regule
myMerge([3|[]],[1|[2]],[1|T]) :- 3>1,myMerge([3|[]],[2],T).
Dziaanie funkcji myMerge dla list jednoelementowych jest ju znane. Otrzymamy
T=[2,3]. Std, Sorted=[1|T]=[1,2,3]., co jest wynikem wypisanym przez Prolog
na ekranie.
Warto zauway, e funkcja myMerge(Lista1,Lista2,Wynik) wstawia po kolei elementy
z Lista1 do listy Lista2 tworzc list posortowan dziki temu e obie z list podanych
jako jej argumenty ju s posortowane.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
90 ROZDZIA 9. SORTOWANIE
9.5 Pytania i odpowiedzi
Pytanie 9.1. Przeprowad analiz dziaania algorytmu sortowania szybkiego.
Implementacja algorytmu sortowania szybkiego w Prologu
qSort([],[]).
qSort([X|Tail], Sorted) :-
split(X, Tail, Small, Big),!,
qSort(Small, SortedSmall),
qSort(Big, SortedBig),
lacz(SortedSmall, [X|SortedBig], Sorted).
split(H,[],[],[]).
split(H,[X|T],[X|L],G) :- X=<H,split(H,T,L,G).
split(H,[X|T],L,[X|G]) :- X>H,split(H,T,L,G).
lacz([], L, L).
lacz([X|L1], L2, [X|L3]) :- lacz(L1, L2, L3).
Pytanie 9.2. Przeprowad analiz dziaania predykatw polowa oraz polacz z
programu implementujcego sortowanie przez czenie.
Implementacja algorytmu sortowania przez czenie
mSort([X],[X]).
mSort(List,Sorted):- List=[_,_|_],polowa(List,L1,L2),
mSort(L1,Sorted1),mSort(L2,Sorted2),
polacz(Sorted1,Sorted2,Sorted).
polowa([],[],[]).
polowa([X],[X],[]).
polowa([X,Y|T],[X|L1],[Y|R1]) :- polowa(T,L1,R1).
polacz([],L,L).
polacz(L,[],L).
polacz([LH|LT],[RH|RT],[LH|T]) :- LH < RH, polacz(LT,[RH|RT],T).
polacz([LH|LT],[RH|RT],[RH|T]) :- LH > RH, polacz(RT,[LH|LT],T).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 10
Od problemu do jego (efektywnego)
rozwizania
10.1 Rebus i jego pierwsze rozwizanie
W rozdziale tym sprbujemy pokaza jak rozwizywa konkretne problemy przy pomocy
Prologa. Caa sztuka polega bowiem na tym, aby z jednej strony wykorzysta potencja
drzemicy w jzyku a z drugiej umie dopomc jemu ten potencja ujawni.
Rozwiemy nastpujc zagadk logiczn.
Naley znale takie przyporzdkowanie cyfr do liter aby rebus
DONALD
+ GERALD
=========
= ROBERT
by prawdziwym dziaaniem matematycznym. Przyporzdkowanie jest rnowartociowe,
tzn. kadej literze odpowiada inna cyfra.
Najbardziej uniwersalne rozwizanie polega na generowaniu wszystkich moliwych przy-
porzdkowa cyfr za litery i sprawdzaniu czy otrzymujemy poprawne rozwizanie. Ge-
nerowanie permutacji zostao opisane w rozdziale powiconym sortowaniu przy okazji
omawiania sortowania naiwnego. Dlatego tutaj jedynie przypomnimy niezbdny frag-
ment kodu
permutacja([],[]).
permutacja(Xs,[Z|Zs]) :- usun(Z,Xs,Ys), permutacja(Ys,Zs).
usun(X,[X|Xs],Xs).
usun(X,[Y|Ys],[Y|Zs]) :- usun(X,Ys,Zs).
Teraz moemy napisa waciwy program
imiona:- permutacja([0,1,2,3,4,5,6,7,8,9],X),
[A,B,D,E,G,L,N,O,R,T]=X,
X1 is D*100000+O*10000+N*1000+A*100+L*10+D,
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
92
ROZDZIA 10. OD PROBLEMU DO JEGO (EFEKTYWNEGO)
ROZWIZANIA
X2 is G*100000+E*10000+R*1000+A*100+L*10+D,
X3 is R*100000+O*10000+B*1000+E*100+R*10+T,
suma(X1,X2,S),wypisz(X3,S,X).
i uzupeni go o brakujce predykaty pomocnicze
suma(X1,X2,X3):- X3 is X1+X2.
wypisz(X1,X2,X):- X1=X2,write(X).
To ju wszystko. Program skadajcy si z tych trzech czci, na komputerze autora,
znajduje rozwizanie rebusu w 22.32s
A, B, D, E, G, L, N, O, R, T
4, 3, 5, 9, 1, 8, 6, 2, 7, 0
526485
+ 197485
=========
= 723970
Jest to rozwizanie najbardziej uniwersalne, gdy pozwala rozwiza kady tego typu
rebus. Niestety cen jest czas, ktry bez dodatkowych zabiegw pozostaje bardzo dugi.
Dlatego w kolejnych podrozdziaach bdziemy prbowali, w oparciu o wiedz jak dodat-
kowo potramy uzyska przygldajc si bliej problemowi, przyspieszy dziaanie pro-
gramu. Jak wiadomo, czas oblicze jest cile zalny od posiadanego systemu. Dlatego
bdziemy posugiwa si pewnymi abstrakcyjnymi jednostkami pozwalajcymi odda za-
lenoci procentowe co pozwoli oceni zysk stosowanych rozwiza niezaleny od sprztu.
Dlatego przyjmujemy, e czas wykonania pierwszej wersji programu wynosi 100%.
10.2 Rozwizanie drugie
23 sekundy to duo czasu. Przyjrzyjmy si wic uwaniej rebusowi. . .
Zauwamy, e w ostatniej kolumnie mamy nastpujce dziaanie D + D = T. Zatem
mamy zaleno jak musz spenia litery D oraz T
T = 2D jeeli D < 5,
T = 2D 10 jeeli D > 4.
(10.1)
Uwzgldnienie tak prostego warunku, poprzez wprowadzenie niewielkiej modykacji do
programu pozwala na zmniejszenie czasu poszukiwania rozwizania do wartoci 50.98%
(11.38s).
warunek(D,T):-D<5,T is 2*D.
warunek(D,T):-D>4,T is 2*D-10.
imiona:- permutacja([0,1,2,3,4,5,6,7,8,9],X),[A,B,D,E,G,L,N,O,R,T]=X,
warunek(D,T),
X1 is D*100000+O*10000+N*1000+A*100+L*10+D,
X2 is G*100000+E*10000+R*1000+A*100+L*10+D,
X3 is R*100000+O*10000+B*1000+E*100+R*10+T,
suma(X1,X2,S),wypisz(X3,S,X).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
10.3. ROZWIZANIE TRZECIE 93
Co jest interesujce, zyskalimy tylko i wycznie na obliczeniach arytmetycznych, gdy
to wanie one nie s wykonywane gdy predykat warunek1 nie jest speniony. Dalej
natomiast generowane s wszystkie moliwe permutacje zbioru cyfr.
10.3 Rozwizanie trzecie
Warunek (10.1) wyraony jest bardzo oglnie, ale my doskonale wiemy, e ilo par
(D,T), ktra go spenia jest skoczona i wcale nie taka dua. Wykorzystajmy wic i ten
fakt i zmodykujmy program do nastpujcej postaci
warunek(1,2).
warunek(2,4).
warunek(3,6).
warunek(4,8).
warunek(5,0).
warunek(6,2).
warunek(7,4).
warunek(8,6).
warunek(9,8).
imiona:- permutacja([0,1,2,3,4,5,6,7,8,9],X),[A,B,D,E,G,L,N,O,R,T]=X,
warunek(D,T),
X1 is D*100000+O*10000+N*1000+A*100+L*10+D,
X2 is G*100000+E*10000+R*1000+A*100+L*10+D,
X3 is R*100000+O*10000+B*1000+E*100+R*10+T,
suma(X1,X2,S),wypisz(X3,S,X).
Niby jest to niewielka zmiana, ale wyposaajc Prolog w wiedz w postaci gotowych
faktw redukujemy ilo wykonywanych operacji. Skutkuje to zmniejszeniem czasu wy-
konania programu do 40.00% (9.15s).
10.4 Rozwizanie czwarte
Przygldajc si zadaniu raz jeszcze zauwaamy, e przedostatnia kolumna to podobny
zwizek jak w kolumnie ostatniej, ktry dotyczy liter L oraz R. Tym razem jednak musimy
pamita o uwzgldnieniu ewentualnego przeniesienia z kolumny ostatniej. Tak wic
rozpatrywa bdziemy dwa przypadki.
Jeli z kolumny ostatniej nie bdzie przeniesienia (co nastpi wtedy gdy D < 5)
wwczas kolumna ostatnia nie wpywa w aden sposb na przedostatni i para
(L, R) spenia warunki (10.1) wyraone z pomoc faktw warunek(1,2), . . . , warunek(9,8).
W Prologu zapiszemy to jako (zamiast warunek piszemy w1, gdy zamiast jednego
warunku jak poprzednio bdziemy mie dwa warunki)
w2(L,R,D):-D<5,w1(L,R).
Jeli nastpi przeniesienie z ostatniej kolumny (co nastpi wtedy gdy D > 4)
wwczas do kolumny przedostatniej dodawana jest warto jeden. Oznacza to, e
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
94
ROZDZIA 10. OD PROBLEMU DO JEGO (EFEKTYWNEGO)
ROZWIZANIA
dla D > 4 odpowiedni warunek przyjmuje posta
L + L + 1
. .
suma powikszona o 1
= R
co w Prologu zapiszemy
w2(L,R,D):-D>4,RR is R-1,w1(L,RR).
W ten oto sposb znowu odrzucamy cz oblicze, ktre i tak nie mogy by okaza
si prawidowym rozwizaniem (ze wzgldu na niespenianie powyszych warunkw) i
zmniejszamy czas do 35.66% (7.96s).
Zanim przejdziemy do kolejnej modykacji zauwamy jeszcze tylko, e warunek dla
D > 4 moemy take zapisa w nastpujcy sposb
w2(L,R,D):-D>4,Tmp is 2*L-10+1,R=Tmp.
co jednak nie wpywa na czas wykonania.
10.5 Rozwizanie pite
Ostatnie zaprezentowane rozwizanie waciwie wyczerpao moliwoci skrcenia wyko-
nania programu przez eliminacj oblicze. W tym momencie zasadniczym rdem spo-
wolnienia jest generowanie wszystkich permutacji. Co wicej, generowane s permutacje,
ktre i tak nie mog by rozwizaniem. Wiemy, e para (D, T) spenia musi odpowied-
nie warunki wyraone za pomoc faktw warunek(1,2),. . . ,warunek(9,8). Tak wic np.
ma sens generowanie permutacji zbioru {0, 3, 4, 5, 6, 7, 8, 9} gdy przyjmiemy, e D = 1,
T = 2, ale zupenie nie ma to sensu, gdy D = 2, T = 1.
Napiszmy zatem predykat p(Lista) generujcy takie permutacje, e przyporzdko-
wanie dla D i T ma sens. Najprociej jest to zrealizowa w oparciu o fakty warunek(1,2),
. . . ,warunek(9,8). Rozpoczniemy wic od
p([D,T|List]) :- warunek(D,T)
gdzie List to permutacja zbioru {0, . . . , 9} pomniejszonego o elementy przypisane do D
oraz T. Permutacja zbioru to w Prologu permutacja listy, a jej pomniejszenie to usu-
nicie elementu. Zatem otrzymujemy kolejne fragmenty predykatu. Najpierw usunicie
elementw
LL=[0,1,2,3,4,5,6,7,8,9],usun(D,LL,L1),usun(T,L1,L2)
a nastpnie permutacja tak zmienionej listy
permutacja(L2,List)
Wszystko razem daje poszukiwany predykat
p([D,T|List]) :- warunek(D,T),
LL=[0,1,2,3,4,5,6,7,8,9],
usun(D,LL,L1),
usun(T,L1,L2),
permutacja(L2,List).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
10.6. ROZWIZANIE SZSTE 95
Na zakoczenie musimy umieci wywoanie celu p(X) w ciele celu imiona i zmieni
kolejno elementw na licie, tak aby D oraz T byy pierwszymi elementami
imiona:- p(X),[D,T,A,B,E,G,L,N,O,R]=X,
X1 is D*100000+O*10000+N*1000+A*100+L*10+D,
X2 is G*100000+E*10000+R*1000+A*100+L*10+D,
X3 is R*100000+O*10000+B*1000+E*100+R*10+T,
suma(X1,X2,S),wypisz(X3,S,X).
Decyzja o takim kierunku modykacji okazuje si suszna co potwierdza osignity re-
zultat (2.5s) rwny 11.2% pocztkowego czasu (dla pierwszego programu).
Cay program w tej wersji wyglda nastpujco
usun(X,[X|Xs],Xs).
usun(X,[Y|Ys],[Y|Zs]) :- usun(X,Ys,Zs).
permutacja([],[]).
permutacja(Xs,[Z|Zs]) :- usun(Z,Xs,Ys), permutacja(Ys,Zs).
suma(X1,X2,X3):- X3 is X1+X2.
wypisz(X1,X2,X):- X1=X2,write(X).
warunek(1,2).
warunek(2,4).
warunek(3,6).
warunek(4,8).
warunek(5,0).
warunek(6,2).
warunek(7,4).
warunek(8,6).
warunek(9,8).
p([D,T|List]) :- warunek(D,T),
LL=[0,1,2,3,4,5,6,7,8,9],
usun(D,LL,L1),
usun(T,L1,L2),
permutacja(L2,List).
imiona:- p(X),[D,T,A,B,E,G,L,N,O,R]=X,
X1 is D*100000+O*10000+N*1000+A*100+L*10+D,
X2 is G*100000+E*10000+R*1000+A*100+L*10+D,
X3 is R*100000+O*10000+B*1000+E*100+R*10+T,
suma(X1,X2,S),wypisz(X3,S,X).
10.6 Rozwizanie szste
Powodzenie modykacji wprowadzonej w poprzedniej wersji programu pozwala mie na-
dziej, e analogiczna poprawka dotyczca liter L oraz R take przyniesie nam oszczd-
noci czasowe. Wymaga to zmodykowania predykatu p(Lista) do postaci
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
96
ROZDZIA 10. OD PROBLEMU DO JEGO (EFEKTYWNEGO)
ROZWIZANIA
p([D,T,L,R|List]) :- warunek(D,T),
n(D,T,L,R),
LL=[0,1,2,3,4,5,6,7,8,9],
usun(D,LL,L1),
usun(T,L1,L2),
usun(L,L2,L3),
usun(R,L3,L4),
permutacja(L4,List).
oraz programu gwnego
imiona:- p(X),[D,T,L,R,A,B,E,G,N,O]=X,
X1 is D*100000+O*10000+N*1000+A*100+L*10+D,
X2 is G*100000+E*10000+R*1000+A*100+L*10+D,
X3 is R*100000+O*10000+B*1000+E*100+R*10+T,
suma(X1,X2,S),wypisz(X3,S,X).
Pozostaje teraz napisa predykat n(D,T,L,R), ktry dla zadanej pary (D, T) zwrci
odpowiedni par (L, R). Pamita naley, e para (L, R)
nie moe zawiera cyfr przyporzdkowanych dla D i T;
musi spenia warunki z rozwizania czwartego dotyczce zalenoci pomidzy D,
L oraz R.
Zdeniujmy ten predykat jako
n(D,T,L,RR) :- D>4, l(D,T,L), R is L*2+1,r(R,RR).
n(D,T,L,RR) :- D<5, l(D,T,L), R is L*2,r(R,RR).
gdzie l(D,T,L) to peredykat, ktry przy ustalonych wartociach dla D i T daje wszystkie
mozliwosci dla L, rne od D i T, natomiast r(R,RR) to predykat obliczajcy warto
dla R zalenie od wartoci L.
Predykat r(R,RR) jest bardzo prosty do napisania
r(R,RR):-R>9,RR is R-10.
r(R,R):-R<10.
Predykat l(D,T,L) wcale nie jest duo trudniejszy
l(D,T,L) :- LL=[1,2,3,4,5,6,7,8,9,0],usun(D,LL,L1),usun(T,L1,L2),jest(L,L2).
jest(X,[X|_]).
jest(X,[Y|Ys]) :- jest(X,Ys).
Zauwamy, e predykat jest/2 to nic innego jak predykat member/2 sprawdzajacy czy
zadany element naley do listy. Jest to kolejny przykad kiedy uycie w Prologu predy-
katu w sposb odmienny od jego pierwotnego przeznaczenia pozwala otrzyma podane
zachowanie (w tym przypadku chodzi nam o moliwo wymienienia wszystkich elemen-
tw listy).
Tym oto sposobem udaje si osiagn wynik rwny 1.12% (0.25s).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
10.7. ROZWIZANIE SIDME 97
10.7 Rozwizanie sidme
Ostatni otrzymany wynik jest ju akceptowalny, ale zauwamy, e moemy go poprawi.
Oto bowiem w trzeciej kolumnie od koca mamy zaleno analogiczn do zalenoci
w kolumnie ostatniej i przedostatniej. Wykorzystujc zatem zdobyte do tej pory do-
wiadczenie, moemy zmodykowa program tak aby zostay uwzgldnione odpowiednie
warunki dla liter A oraz E. Finalna wersja programu przedstawia si nastpujco
usun(X,[X|Xs],Xs).
usun(X,[Y|Ys],[Y|Zs]) :- usun(X,Ys,Zs).
permutacja([],[]).
permutacja(Xs,[Z|Zs]) :- usun(Z,Xs,Ys), permutacja(Ys,Zs).
suma(X1,X2,X3):- X3 is X1+X2.
wypisz(X1,X2,X):- X1=X2,write(X).
warunek(1,2).
warunek(2,4).
warunek(3,6).
warunek(4,8).
warunek(5,0).
warunek(6,2).
warunek(7,4).
warunek(8,6).
warunek(9,8).
n(D,T,L,RR) :- D>4, l(D,T,L), R is L*2+1,r(R,RR).
n(D,T,L,RR) :- D<5, l(D,T,L), R is L*2,r(R,RR).
r(R,RR):-R>9,RR is R-10.
r(R,R):-R<10.
l(D,T,L) :- LL=[1,2,3,4,5,6,7,8,9,0],usun(D,LL,L1),usun(T,L1,L2),jest(L,L2).
jest(X,[X|_]).
jest(X,[Y|Ys]) :- jest(X,Ys).
p([D,T,L,R,A,E|List]) :- warunek(D,T),
n(D,T,L,R),
n(L,R,A,E),
LL=[0,1,2,3,4,5,6,7,8,9],
usun(D,LL,L1),
usun(T,L1,L2),
usun(L,L2,L3),
usun(R,L3,L4),
usun(A,L4,L5),
usun(E,L5,L6),
permutacja(L6,List).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
98
ROZDZIA 10. OD PROBLEMU DO JEGO (EFEKTYWNEGO)
ROZWIZANIA
imiona:- p(X),
[D,T,L,R,A,E,B,G,N,O]=X,
X1 is D*100000+O*10000+N*1000+A*100+L*10+D,
X2 is G*100000+E*10000+R*1000+A*100+L*10+D,
X3 is R*100000+O*10000+B*1000+E*100+R*10+T,
suma(X1,X2,S),wypisz(X3,S,X).
W tej wersji czas dziaania wynosi zaledwie 0.13% (0.03s) pierwotnego czasu dziaania
dla pierwszej wersji programu.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 11
Efektywny Prolog
W niniejszym rozdziale sprbujemy zebra w jedn cao wszystkie porady jakie do tej
pory si pojawiy a jakie zwizane byy ze sposobem pisania programw w Prologu. Jak
ju wielokrotnie mielimy okazj si przekona, wszybko dziaania programu zaley od
tego w jaki sposb go napiszemy a e napisa mona go na mnstwo rnych sposobw
wic i dylematw jest wiele.
11.1 Czy tylko deklaratywno?
Deklaratywno rozumiemy jako
W tym kontekcie Prolog uwaany jest za jzyk deklaratywny lub mwic inaczej,
jzyk ktry nie jest proceduralny. Teoretycznie jest to prawd, ale w praktyce na kod
programu (tj. reguy) trzeba patrze zarwno jak na wyraenia deklaratywne deniujce
pewne informacje jak i sposoby (procedury) uycia tych informacji. Std na regu
postaci
a(X,b) :- a(X,c)
moemy spojrze dwojako.
Jak na denicj: X jest w relacji a z b jeli X jest w relacji a z c.
Jak na procedur obliczeniow (algorytm): aby wykaza, e X jest w relacji a z b
naley wykaza, e X jest w relacji a z c.
Dla jasnoci powiedzmy, e taka dwoisto wystpuje te w przypadku proceduralnych
jzykw programowania. Na instrukcj jzyka C
x = y + z;
take moemy spojrze dwojako.
Jak na denicj (wzr matematyczny): x jest rwne sumie elemntu y i z.
Jak na procedur obliczeniow (algorytm):
1. Pobierz warto y.
2. Pobierz warto z.
3. Dodaj do siebie dwie ostatnio pobrane wartoci.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
100 ROZDZIA 11. EFEKTYWNY PROLOG
4. Wynik ostatniej operacji arytmetycznej zapisz w zmiennej x.
To, ktry ze sposobw interpretacji wybierzemy, czsto zaley od kontekstu. Doskonale
wiadomo, e deklaratywne spojrzenie na instrukcje jzyka C podobn do poprzedniej, tj.
x = x + 1;
prowadzi do sprzecznoci a jednak z dowiadczenia wiemy, e ta instrukcja jest jak najbar-
dziej poprawna. Na marginesie zaznaczmy tylko, e bardzo czsto wanie pocztkujcy
programici maj duy kopot wanie z takimi instrukcjami. Jako, e pocztkujcy,
wic nieprzyzwyczajeni do mylenia proceduralnego, patrz na kod jak na denicje co
wprowadza w ich gowach zament, bo jak niby x moe by rwny x plus 1 i co to waciwie
znaczy?!
A teraz wrmy do przykadu, ktry pojawi si ju w rozdziale 3, strona 24. Wy-
stpuje tam regua postaci
mniej(X,Y) :- mniej(X,Z),mniej(Z,Y).
ktra z deklaratywnego punktu widzenia jest czci poprawnej logicznie denicji pojcia
mniej. Oto dwa obiekty X i Y s w relacji mniej (mniejszoci) gdy istnieje taki trzeci
obiekt Z dla ktrego X jest mniejszy od Z i jednoczenie Z jest mniejszy od Y. Teoretycznie
denicji tej nic nie mona zarzuci a jednak wiemy, e nie jest ona poprawna i prowadzi
do zaptlenia programu. Przyczyna zaptlenia staje si jasna, gdy spojrzymy na
zapis z proceduralnego (obliczeniowego) punktu widzenia. Oto gdy zarwno Z jak i Y
nie s znane cel mniej(X,Z) niczym nie rni si od mniej(X,Y). Mona powiedzie, e
mamy wwczas regu postaci
mniej(X,Y) :- mniej(X,Y).
To jednak dostrzec moemy wtedy, gdy spojrzymy na ca regu nie jak na denicj,
ale jak na algorytm. Rozwizaniem w tym przypadku jest niedopuszczenie do samowy-
woania co osignelimy przez wprowadzenie nastpujcej zmiany
jestMniejszy(X,Y) :- mniej(X,Z),jestMniejszy(Z,Y).
Wniosek jest wic taki: w Prologu musimy myle zarwno deklaratywnie jak i pro-
ceduralnie.
11.2 Zmniejsza przestrze rozwaa
Jedna z najwaniejszych rad prologowych jest nastpujca
Jeli jaki test moe nie by prawdziwy to niech to si stanie tak szybko jak tylko jest
to moliwe.
Z problemem tym spotkalimy si ju w podrozdziale 8.1 a take przy okazji optymalizacji
rozwizania problemu z rozdziau 10.
W pierwszym przypadku mielimy do czynienia z sytuacj, w ktrej istotn rel
odgrywaa kolejno wywoania podceli. Zredukowanie przestrzeni rozwaa osiga si
tutaj dziki spostrzeeniu, e jeli spenienie jednego warunku jest mniej prawdopodobne
(zdarza si rzadziej) ni innego, to warunek ten korzystnie jest umieci jako pierwszy,
wedug schematu
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
11.3. NIECH PRACUJ ZA NAS INNI 101
test(X) :- warunekRzadki(X),warunekCzesty(X).
a nie wedug schematu
test(X) :- warunekCzesty(X),warunekRzadki(X).
W drugim przypadku wymagane byo przekonstruowanie programu a czasem jest to
wrcz zmiana logiki jego dziaania. Dla zilustrowania tego problemu zamy, e mamy
zestaw predykatw pozwalajcych manipulowa zbiorami. Zbiory w tym przypadku re-
prezentowane oczywicie bd za pomoc list. Zamy dalej, e naley dopisa predykat
sprawdzajcy czy dwa zbiory s identyczne. Bardzo naiwne rozwizanie tego problemu
jest nastpujce
takieSame(Set1,Set2) :- permutacja(Set1,Perm),Perm=Set2.
Taki predykat bdzie dziaa tyle tylko, e czas jego dziaania bdzie niakceptowalnie
dugi. Duo rozsdniej jest napisa
takieSame(Set1,Set2) :- sortuj(Set1,Sort1),sortuj(Set2,Sort2),Sort1=Sort2.
Podejcie to jednak wymaga zmiany koncepcji rozwizania problemu co nie zawsze jest
takie proste jak w tym przypadku. Czsto si jednak opaca.
11.3 Niech pracuj za nas inni
Przyzwyczajenia jakie zostay u nas wyrobione przez lata stykania si z pewnymi (utar-
tymi) metodami postpowania bywaj tak silne, e czsto majc do dyspozycji nawet
znacznie silniejsze narzdzia, korzystamy z tych ktre dobrze znamy (a waciwie to za-
pamitalimy) a nie tych, ktre s efektywne. Wikszo z nas wie co naley zrobi aby
w danym jzyku programowania, np. C, pomnoy skalarnie przez siebie dwa wektory.
Piszemy ptle, mnoymy element po elemencie i wszystko sumujemy. Moe to wyglda
np. tak
iloczyn=0;
for(i=0;i<10;i++)
{
iloczyn+=wektor1[i]*wektor2[i];
}
W rodowisku obliczeniowym Scilab (lub jego komercyjnym odpowiedniku: Matlab)
wektory i macierze funkcjonuj jako typ wbudowany. Wystarczy w nich wic napisa
iloczyn=wektor1*wektor2;
Problem polega na tym, e wiele osb na pocztku, niejako odruchowo, wybiera pierw-
szy sposb mimo, e rodowisko dostarcza znacznie efektywniejszego narzdzia.
Nie inaczej sytuacja wyglda w Prologu, w ktrym narzdziem takim jest unikacja.
Unikacja a wic dopasowywanie jest mechanizmem, ktry czy tego chcemy czy nie i tak
uruchamiany jest przy kadej, nazwijmy to, prbie wywoania predykatu. Skoro i tak
musi ten mechanizm zadziaa, to mona pozwoli jemu, aby cz pracy wykona za nas.
Spotkalimy si ju z tym w rozdziale 10. W podrozdziale 10.2 udao nam si ustali
warunki jakie musz spenia pewne dane D i T, przy zaoeniu, e s rne i przyjmuj
wartoci co najwyej ze bioru wszystkich cyfr dziesitnych
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
102 ROZDZIA 11. EFEKTYWNY PROLOG
warunek(D,T):-D<5,T is 2*D.
warunek(D,T):-D>4,T is 2*D-10.
W dalszej czci korzystalimy z tego predykatu. Potem (podrozdzia 10.3) udaje nam
si jednak dostrzec, e przy warunkach zadania zbir par (D, T) jest may i rwnie dobrze
mona zastpi go zbiorem faktw
warunek(1,2).
warunek(2,4).
warunek(3,6).
warunek(4,8).
warunek(5,0).
warunek(6,2).
warunek(7,4).
warunek(8,6).
warunek(9,8).
i pozwoli wkroczy do akcji unikacji.
Problem ten ilustruje take bardzo dobrze nastpujce zadanie: napisa predykat
sprawczajcy czy na licie s dokadnie dwa elementy. Najbardziej uniwersalny sposb
jest nastpujcy
dokladnieDwa(Lista) :- dlugosc(Lista,Dlugosc),Dlugosc=2.
Jest to sposb najbardziej uniwersalny (najbardziej oglny) przez co najwolniejszy. Wy-
korzystujc specyk problemu, moemy napisa znacznie szybsz wersj w postaci
dokladnieDwa(Lista) :- dlugosc(Lista,3).
lub wrcz tak
dokladnieDwa([_,_]).
Nie ma te nic prostszego jak napisanie programu zamieniajcego elementy listy
dwuelementowej o ile tylko porzucimy utarte schematy mylenia. Normalnie zamian
elemntw realizuje si przy pomocy trzeciej zmiennej pomocniczej, ale w Prologu mona
to przerzuci na mechanizm unikacji piszc
zamien([A,B],[B,A]).
Na koniec zauwamy, e baz faktw
f(z,a).
f(z,b).
f(z,c).
f(z,d).
f(z,e).
moemy te przedstawi jako
f(a,z).
f(b,z).
f(c,z).
f(d,z).
f(e,z).
Druga wersja jest szybsza, gdy umoliwia odrzucenie niepasujcych faktw ju na etapie
sprawdzania pierwszego argumentu.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
11.4. PRACUJ NA GOWIE. . . 103
11.4 Pracuj na gowie. . .
Najlepiej dziaa na gowie a precyzyjniej rzecz ujmujc na kilku pierwszych elementach
listy. Chodzi o to aby nie trzeba byo czsto przebiega przez ca list celem wykonania
pewnej pracy na jej ostatnich lub wrcz ostatnim elemencie. W zadaniu 13.4.4 z wicze-
nia 13.4 rozpatrujemy problem odwracania listy. Rozwizanie jakie podajemy wyglda
nastpujco
odwroc([],[]).
odwroc([X|Xs],Zs) :- odwroc(Xs,Ys), dodajNaKoncu(Ys,[X],Zs).
Nie jest to rozwizanie najlepsze, ale ze wzgldu na to e pewne pojcia zostan wpro-
wadzone dopiero w dalszej czsci, na tamtym etapie wystarczajce (akceptowalne). Za-
uwamy jednak, e predykat dodajNaKoncu musi przej po wszystkich elementach listy
zanim znajdzie si na samym jej kocu i dopiero wtedy dodaje zadany element. Mona
to rozwiza znacznie szybciej przy wykorzystaniu zmiennej akumulatorowej
odwroc(L1,L2) :- odwroc(L1,[],L2).
odwroc([H|T],Tmp,Res) :- odwroc(T,[H|Tmp],Res).
odwroc([],Res,Res).
Rozwizanie to jest znacznie szybsze, gdy operujemy tylko na pierwszych elementach
listy, zarwno zdejmujc elementy jak i wkadajc je do niej.
11.5 . . . albo odcinaj to co zbdne
sgn(X) :- X=0, write(zero).
sgn(X) :- X>0, write(dodatnie).
sgn(X) :- X<0, write(ujemne).
sgn(0) :- write(zero).
sgn(X) :- X>0, write(dodatnie).
sgn(X) :- X<0, write(ujemne).
sgn(0) :- write(zero),!.
sgn(X) :- X>0,write(dodatnie),!.
sgn(X) :- X<0, write(ujemne).
sgn(0) :- write(zero),!.
sgn(X) :- X>0,write(dodatnie),!.
sgn(_) :- write(ujemne).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
104 ROZDZIA 11. EFEKTYWNY PROLOG
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 12
Rachunek zda
Rachunek zda (ang. propositional calculus, propositional logic, sentential calculus) to
dzia logiki matematycznej badajcy, jak prawdziwo zda zoonych tworzonych przy
pomocy rnych spjnikw zaley od prawdziwoci wchodzcych w ich skad zda pro-
stych. Zdania proste s najmniejsz, niepodzieln jednostk skadow dowolnego zda-
nia (zoonego) i dlatego nazywa si je take formuami atomowymi (ang. atomic
sentences). W klasycznym rachunku zda przyjmuje si zaoenie, e kademu zdaniu
mona przypisa jedn z dwu wartoci logicznych prawd albo fasz, ktre umownie
przyjto oznacza 1 i 0. Przedmiotem bada rachunku zda s formalne reguy pozwala-
jce okreli jak prawdziwo zda atomowych wpywa na prawdziwo zdania zoonego.
Na przykad o zdaniach
p = d jest stolic Polski.
q = Warszawa jest stolic Polski.
zgodnie z posiadan przez nas wiedz powiemy odpowiednio fasz i prawda. Co ciekawe,
w rachunku zda tre rozpatrywanych zda nie ma znaczenia. Istotna jest jedynie ich
warto logiczna. Warto logiczn zda zoonych powstaych przez zastosowanie
spjnikw zdaniowych wyznaczona jest jednoznacznie przez wasnoci tyche spj-
nikw i zaley wycznie od prawdziwoci lub faszywoci zda skadowych, nie zaley
natomiast od ich treci. Tak wic jeli z dwch zda atomowych
p

= d jest stolic Polski. (fasz)


q

= Agent 007 to James Bond. (prawda)


utworzymy zdanie zoone za pomoc spjnika i to cho bdzie ono bez sensu z punktu
widzenia niesionej treci, to jego warto logiczna bdzie taka sama jak warto logiczna
zdania utworzonego ze zda p i q.
Zdeniujemy teraz formalnie syntaktyk rachunku zda.
Denicja 12.1 (Syntaktyka rachunku zda). Zdanie atomowe (formua atomowa)
jest najmniejsz, niepodzieln jednostk zdaniow, ktrej mona przypisa jedn z dwch
wartoci logicznych prawd lub fasz. Zdanie (zoone), nazywane dalej oglnie
formu, deniujemy rekurencyjnie w nastpujcy sposb
1. Kada formua atomowa jest formu.
2. Dla kadej formuy f, f te jest formu. Formu f nazywamy negacj (ang.
negation) (formuy) f.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
106 ROZDZIA 12. RACHUNEK ZDA
3. Dla wszystkich formu f i g, f g te jest formu. Formu f g nazywamy
dysjunkcj (ang. disjunction) (formu) f i g.
4. Dla wszystkich formu f i g, f g te jest formu. Formu f g nazywamy
koniunkcj (ang. conjunction) (formu) f i g.
5. Kada formua f bdca czci innej formuy g nazywa si jej podformu.
Zwrmy uwag na fakt, e wedug powyszej denicji formua to nic innego jak
pewien napis zbudowany wedug okrelonych regu. Wszak o tym mwi wanie syn-
taktyka. Abymy mogli czyta np. symbol jako nie musimy okreli teraz znaczenie
wprowadzonych symboli a wic ich semantyk.
Denicja 12.2 (Semantyka rachunku zda). Niech L bdzie zbiorem wartoci {0, 1}
nazywanym zbiorem wartoci logicznych. Element 0 nazywamy faszem, element 1 na-
zywamy prawd. Dalej, niech A bdzie zbiorem formu atomowych a A : A L funkcj
przyporzdkowujc kadej formule atomowej element prawda albo fasz. Rozszerzmy te-
raz funkcj A do funkcji F : F L, gdzie F A jest zbiorem formu jakie mona
zbudowa z formu atomowych nalecych do zbioru A. Funkcj F deniujemy nastpu-
jco
1. Dla kadej formuy atomowej a A, F(a) = A(a).
2. Dla kadych dwch formu f, g
F((f g)) =
_
1, jeli F(f) = 1 i F(g) = 1
0, w przeciwnym razie
3. Dla kadych dwch formu f, g
F((f g)) =
_
1, jeli F(f) = 1 lub F(g) = 1
0, w przeciwnym razie
4. Dla kadej formuy f
F((f)) =
_
1, jeli F(f) = 0
0, w przeciwnym razie
W dalszej czci o A lub F mwi bdziemy po prostu przyporzdkowanie (ang. assi-
gnment).
W oparciu o powysz denicj moemy teraz nada znaczenie poszczeglnym sym-
bolom czytajc je jako i (), lub (), nie (). Ponad to moemy kady z nich opisa za
pomoc tzw. tablicy prawdy
f g f g f g f
0 0 0 0 1
0 1 0 1
1 0 0 1 0
1 1 1 1
Zauwamy, e zgodnie z powysz denicj moemy powiedzie, e symbole , oraz
s symbolami operatorw. Skoro za mwimy o operatorach to zwykle wymagane jest
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
107
okrelenie ich priorytetowoci. Teoretycznie w naszym przypadku nie musimy tego robi,
poniewa priorytety wymuszone s przez nawiasy i nie moe zdarzy si na przykad taka
formua
f g f
Jeli ju to albo taka
(f g) f
albo taka
f (g f).
Ze wzgldw czysto praktycznych (bardziej czytelny i zwarty zapis) wprowadzimy jednak
priorytety (zachowujac przy tym molwio uycia nawiasw do grupowania jeli zajdzie
taka potrzeba) okrelajc, e symbol rozpatrywany jest przed za przed .
Denicja 12.3. Niech f bdzie formu a F przyporzdkowaniem. Jeli F okrelone jest
dla kadej formuy atomowej wystpujcej w f, wwczas o F powiemy, e jest odpowied-
nie (ang. suitable) dla f lub e jest odpowiednim przyporzdkowaniem (ang. suitable
assignment).
Denicja 12.4. Jeli F jest odpowiednie dla f i F(f) = 1 wwczas powiemy, e F
jest modelem (ang. model) dla f lub, e f zachodzi (ang. hold) dla przypisania F.
Zapisywa bdziemy to w nastpujcy sposb
F |= f.
W przeciwnym razie piszemy
F |= f.
Denicja 12.5. Formua f jest spenialna (ang. satisable) jeli istnieje dla f co
najmniej jedne model. W przeciwnym przypadku formu f nazywamy niespenialn
(ang. unsatisable) lub sprzeczn (ang. contradictory). Zbir formu S nazywamy
spenialnym jeli istnieje model F taki, e F |= f, gdzie f jest dowoln formu ze zbioru
S.
Denicja 12.6. Formu f nazywamy prawdziw (ang. valid) lub tautologi (ang.
tautology) jeli kade odpowiednie przyporzdkowanie jest modelem dla f. Zapisywa
bdziemy to jako
|= f.
W przeciwnym razie piszemy
|= f.
Z powyszych denicji wynika, e aby (skoczon) formu f nazwa spenialn (tau-
tologi), wystarczy sprawdzi skoczon ilo przyporzdkowa dla formu atomowych z
f. Jeli bowiem formua f skada si z n formu atomowych a
1
, . . . , a
n
wwczas istnieje
dokadnie 2
n
rnych przyporzdkowa. Sprawdzenia takiego mona wic dokona w
usystematyzowany sposb za pomoc tablicy prawdy (ang. truth-table)
a
1
a
2
a
n
f
F
1
0 0 0 F
1
(f)
F
2
0 0 1 F
2
(f)
.
.
.
.
.
.
.
.
.
F
2
n 1 1 1 F
2
n(f)
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
108 ROZDZIA 12. RACHUNEK ZDA
Jeli formua f jest spenialna to w ostatniej kolumnie przynajmniej w jednym wierszu
powinnimy otrzyma warto 1. Jeli formua f jest tautologi to ostatnia kolumna
powinna zawiera tylko i wycznie wartoci 1.
Twierdzenie 12.1. Formua f jest tautologi wtedy i tylko wtedy, gdy f jest niespe-
nialna.
Dowd. Dowd pozostawiamy jako wiczenie.
Twierdzenie 12.2. Dla dowolnych formu f, g i h zachodz nastpujce rwnowanoci
1. przemienno (ang. commutativty)
f g g f
f g g f
2. czno (ang. associativity)
(f g) h f (g h)
(f g) h f (g h)
3. rozdzielno (ang. distributivity)
f (g h) (f g) (f h)
f (g h) (f g) (f h)
4. pochanianie (absorpcja) (ang. absorption)
f (f g) f
f (f g) f
5. prawo podwjnego przeczenia (ang. double negation)
f f
6. prawo deMorgana (ang. deMorgans laws)
(f g) f g
(f g) f g
7. idempotentno (ang. idempotency)
f f f
f f f
8. (???) identycznoci(ang. identity) w uoglnionej wersji (ang. tautology laws)
f g f, jeli f jest tautologi
f g g, jeli f jest tautologi
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
12.1. POSTA NORMALNA 109
9. spenialno (ang. unsatisability laws)
f g g, jeli f nie jest spenialne
f g f, jeli f nie jest spenialne
Dowd. Dowd z wykorzystaniem denicji semantycznej lub tablic prawdy pozosta-
wiamy jako wiczenie.
W dalszej czci przyjmujemy nastpujce skrcone formy zapisu
zamiast f g piszemy f g,
zamiast (f g) (f g) piszemy f g,
zamiast (f g) (g f) piszemy f g,
zamiast a
1
a
n
piszemy
_
n
i=1
a
i
,
zamiast a
1
a
n
piszemy
_
n
i=1
a
i
.
Twierdzenie 12.3. Formua g jest nazywana wnioskiem (ang. consequence) ze zbioru
formu {f
1
, . . . , f
n
} jeli dla kadego przypisania F odpowiadajcego wszystkim formuom
{f
1
, . . . , f
n
} oraz formule g zachodzi, e jeli F jest modelem dla {f
1
, . . . , f
n
} wwczas
jest take modelem dla g. Nastpujce stwierdzenia s rwnowane
1. g jest wnioskiem z formu {f
1
, . . . , f
n
}.
2. (
_
n
i=1
f
i
) g jest tautologi.
3. (
_
n
i=1
f
i
) g jest niespenialne.
Dowd. Dowd tutu.
12.1 Posta normalna
Okazuje si, e kada formua, bez wzgldu na to jak by skomplikowan si wydawaa,
daje si zapisa w pewien uniwersalny (znormalizowany) sposb.
Denicja 12.7. Formu atomow lub jej negacj oglnie nazywa bdziemy literaem
(ang. literal). W szczeglnoci o literale odpowiadajcym niezanegowanej formule ato-
mowej powiemy, e wystpuje w armacji, a o literale odpowiadajcym zanegowanej
formule atomowej powiemy, e wystpuje w negacji. Ten ostatni nazywa bdziemy
take literaem zanegowanym. Ponad to przyjmujemy nastpujc umow. Jeli l
jest literaem oraz a formu atomow, wwczas l deniujemy jako
l =
_
a jeli l = a,
a jeli l = a,
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
110 ROZDZIA 12. RACHUNEK ZDA
Denicja 12.8 (Posta normalna). Powiemy, e formua f jest w koniunkcyjnej po-
staci normalnej (ang. conjunctive normal form), (CNF) jeli jest koniunkcj dysjunk-
cji literaw, czyli jeli jest postaci
f =
n

i=1
(
m

j=1
a
i,j
),
gdzie a
i,j
s literaami. Formua f jest w dysjunkcyjnej postaci normalnej (ang.
disjunctive normal form), (DNF) jeli jest dysjunkcj koniunkcji literaw, czyli jeli
jest postaci
f =
n

i=1
(
m

j=1
a
i,j
),
gdzie a
i,j
s literaami.
Twierdzenie 12.4. Dla kadej formuy f istnieje rwnowana jej formua f
C
w postaci
CNF i rwnowana jej formua f
D
w postaci DNF.
Dowd. Dowd //tutu//.
12.1.1 Przeksztacanie do postaci normalnej
Podamy teraz dwa sposoby przeksztacenia dowolnej formuy do postaci normalnej.
Sposb I
Chcc przeksztaci dowoln formu f do postaci CNF naley wykona nastujce kroki
1. Dopki jest to moliwe, wykonuj nastpujce podstawienia w formule f
formu g zastp przez formu g,
formu (g h) zastp przez formu g h,
formu (g h) zastp przez formu g h.
2. Dopki jest to moliwe, wykonuj nastpujce podstawienie w formule f: formu
p (q r) zastp przez formu (p q) (p r).
Chcc przeksztaci dowoln formu f do postaci DNF naley w kroku 2, dopki jest to
moliwe, wykonywa nastpujce podstawienie w formule f: formu p (q r) zastp
przez formu (p q) (p r).
Sposb II
Dla formuy f naley skonstruowa tablic prawdy. Aby otrzyma rwnowan posta
CNF naley
1. Odrzuci wszystkie wiersze, dla ktrych przyporzdkowanie zwraca warto 1.
2. Dla kadego z pozostaych wierszy budujemy formu. Jeli w i-tym wierszu przy-
pisanie F
i
dla formuy atomowej a
j
zwraca 1 wwczas do budowanej formuy f
i
formua atomowa wchodzi w negacji, w przeciwnym razie w armacji.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
12.1. POSTA NORMALNA 111
3. Elementy formu f
i
czymy znakiem .
4. Formuy f
i
czymy znakiem .
Przeanalizujemy teraz kady z krokw na przykadzie. Niech dana bdzie formua, dla
ktrej tablica prawdy wyglda w nastpujcy sposb
p q r f
F
1
0 0 0 F
1
(f) = 1
F
2
0 0 1 F
2
(f) = 0
F
3
0 1 0 F
3
(f) = 1
F
4
0 1 1 F
4
(f) = 0
F
5
1 0 0 F
5
(f) = 0
F
6
1 0 1 F
6
(f) = 1
F
7
1 1 0 F
7
(f) = 1
F
8
1 1 1 F
8
(f) = 1
Po wykonaniu kroku 1 tablica przyjmie posta
p q r f
F
2
0 0 1 F
2
(f) = 0
F
4
0 1 1 F
4
(f) = 0
F
5
1 0 0 F
5
(f) = 0
Po wykonaniu kroku 2 na wierszu
i = 2 otrzymujemy f
i
= {p, q, r},
i = 4 otrzymujemy f
i
= {p, q, r},
i = 5 otrzymujemy f
i
= {p, q, r}.
Po wykonaniu kroku 3 na wierszu
i = 2 otrzymujemy f
i
= p q r,
i = 4 otrzymujemy f
i
= p q r,
i = 5 otrzymujemy f
i
= p q r.
Po wykonaniu kroku 4 otrzymujemy ostateczn posta CNF dla formuy f
f
C
= (p q r) (p q r) (p q r).
Aby otrzyma rwnowan posta DNF naley
1. Odrzuci wszystkie wiersze, dla ktrych przyporzdkowanie zwraca warto 0.
2. Dla kadego z pozostaych wierszy budujemy formu. Jeli w i-tym wierszu przy-
pisanie F
i
dla formuy atomowej a
j
zwraca 1 wwczas do budowanej formuy f
i
formua atomowa wchodzi w armacji, w przeciwnym razie w negacji.
3. Elementy formu f
i
czymy znakiem .
4. Formuy f
i
czymy znakiem .
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
112 ROZDZIA 12. RACHUNEK ZDA
12.2 Formua Horna
Denicja 12.9 (Formua Horna). Formu f zapisan w postaci CNF nazywamy for-
mu Horna (ang. Horn formula) jeli kada dysjunkcja zawiera co najwyej jeden litera,
ktry nie jest zanegowany.
Formuy Horna maj dosy ciekaw interpretacj. Ot kada formua tego typu
moe by interpretowana jako cig warunkw typu jeli . . . to. Na przykad formua
f = (f g) (f g h) (f g)
rwnowana jest formule
f = (g f) (f g h) (f g 0)
co mona czyta jako f zachodzi jeli prawd jest, e z g wynika f oraz prawd jest, e
. . . lub inaczej f zachodzi jeli prawd jest, e jeli g to f oraz prawd jest, e jeli. . . .
Formuy Horna maj te bardzo praktyczn wasno. Jak wiemy w oparciu o ta-
blic prawdy moemy sprawdzi spenialno danej formuy. Niestety wraz ze wzrostem
formuy, wykadniczo wzrasta czas na to potrzebny. W przypadku formu Horna istnieje
algorytm dajcy nam odpowied w czasie liniowym (zalenym od ilo formu atomo-
wych).
//tutu// algorytm
//tutu// twierdzenie
12.3 twierdzenie tutu
Twierdzenie 12.5. Zbir formu S jest spenialny wtedy i tylko wtedy gdy kady sko-
czony podzbir zbioru S jest spenialny.
Dowd. Dowd
tutu
.
12.4 Rezolucja
Rezolucja jest prost operacj dokonujc zmiany syntaktycznej na kilku formuach
z dwch formu generowana jest trzecia formua. Formua ta powiksza zbir formu i
moe by uyta w kolejnym kroku rezolucji.
Warunkiem wstpnym dla stosowania rezolucji jest przedstawienie formuy w postaci
CNF. Jak wiemy formua CNF to formua o oglnej postaci
f = (l
1,1
l
1,n
1
) (l
k,1
l
k,n
k
)
Zatem upraszczajc notacj moemy formu f zapisa jako
f = {l
1,1
, . . . , l
1,n
1
}, . . . , {l
k,1
, . . . , l
k,n
k
}.
Mwimy wwczas, e f jest zbiorem klauzul (ang. clauses) postaci {l
i,1
, . . . , l
k,n
i
}.
Elementy kadej kaluzuli traktuje si tak jak elementy poczone za pomoc , kaluzule
natomiast tak jak obiekty poczone za pomoc . Taki sposb zapisu, ma jeszcze jedn
zalet. Zauwamy, e wszelkie prawa jak np. czno czy pochanianie automatycznie
wynika z wasnoci dotyczcych zbiorw.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
12.4. REZOLUCJA 113
Denicja 12.10. Niech c
1
, c
2
i r bd klauzulami. Wwczas r nazywane jest resol-
went (ang. resolvent) c
1
i c
2
jeli istnieje litera l taki, e l c
1
, l c
2
i zachodzi
r = (c
1
{l}) (c
2
{l}).
Inaczej mwic, resolwenta jest efektem zastosowania rezolucji.
W ten oto sposb podalimy formaln denicj pojcia rezolucji, ktre pojawio si w
rozdziale 3. Zauwamy, e rezolucja dotyczy tylko takich klauzul, w ktrych co najmniej
jeden litera ma t wasno, e w jednej klauzuli wystpuje w armacji, w drugiej za w
negacji. W takiej sytuacji w wyniku zastosowania rezolucji otrzymujemy klauzule ktra
jest sum tych dwch klauzul minus litera wystpujcy w armacji i negacji.
Twierdzenie 12.6. Jeli r jest resolwent dwch klauzul Horna, wwczas r take jest
klauzul Horna.
Dowd. Dowd
tutu
.
Twierdzenie 12.7. Niech f bdzie formu postaci CNF i niech r bdzie resolwent
klauzul c
1
, c
2
f. Wwczas zbiory f i f {r} s rwnowane.
Dowd. Dowd
tutu
.
Denicja 12.11. Niech f bdzie zbiorem klauzul. Wyraenie Res(f) deniujemy jako
Res(f) = f {r : r jest resolwent dwch klauzul z f}.
Ponad to deniujemy
Res
0
(f) = f,
Res
k+1
(f) = Res(Res
k
(f))
dla k > 0 oraz
Res

(f) =
_
k0
Res
k
(g).
Twierdzenie 12.8. Dla kadego skoczonego zbioru klauzul f istnieje k 0 takie, e
Res
k
(f) = Res
k+1
(f) = = Res

(f).
Dowd. Dowd
tutu
.
Twierdzenie 12.9. Zbir klauzul f jest niespenialny wtedy i tylko wtedy, gdy gdy klau-
zula pusta naley do Res

(f).
Dowd. Dowd
tutu
.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
114 ROZDZIA 12. RACHUNEK ZDA
12.5 Pytania i odpowiedzi.
Pytanie 12.1. Podaj dowd twierdzenia 12.4.
Pytanie 12.2. Stosujc tablic prawdy sprawd, czy zadana formua f jest
tautologi.
Pytanie 12.3. Podaj dowd twierdzenia 12.2.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 13
wiczenia
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
116 ROZDZIA 13. WICZENIA
13.1 wiczenie 1
13.1.1 Zadanie
Utworzy plik zawierajcy nastpujce fakty:
Piotr lubi gry.
Arek jest wysoki.
Piotr da Hani tulipany.
Micha podruje autobusem do Parya.
Trojkt, kwadrat, okrg to gury.
13.1.2 Zadanie
Utworzy plik zawierajcy reguy opisujce nastpujce zdania o wiecie:
Kady czowiek je tylko miso lub ser lub owoce.
Jeli X jest babci Y, to Y jest wnukiem lub wnuczk.
Dwie osoby s rodzestwem, jeli maj tych samych rodzicw.
X jest gur jeli jest trojkatem lub kwadratem lub okrgiem.
13.1.3 Zadanie
Napisa reguy opisujce nastpujce relacje pokrewiestwa:
jest_matka(X,Y);
jest_synem(X,Y);
brat(X,Y);
babcia(X,Y).
Jeli to okae si potrzebne uyj innych regu, np. ojciec(X,Y), kobieta(X), rodzic(X,Y).
13.1.4 Zadanie
Napisa program obliczajcy silni.
13.1.5 Zadanie
Napisa program obliczajcy n-ty wyraz cigu Fibonacciego.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
13.2. WICZENIE 2 117
13.2 wiczenie 2
Liczby naturalne moemy zdeniowa w nastpujacy sposb
a
0
= 0,
a
1
= 1 = 0 + 1,
a
2
= 2 = 1 + 1,
a
3
= 3 = 2 + 1,
a
4
= 4 = 3 + 1,
. . . ,
a
n
= a
n1
+ 1
Przyjmujc, e mamy funkcj nastpnika f() dajc element nastpny, oraz symbol
pocztkowy 0, moemy to samo zapisa jako
0, 1 = f(0), 2 = f(1), 3 = f(2), . . . , n = f(n 1),
czyli inaczej
0, 1 = f(0), 2 = f(f(0)), 3 = f(f(f(0))), . . .
Std moemy zapisa relacj stwierdzajc czy co jest liczb naturaln w nastpujacy
sposb
lN(0).
lN(f(X)) :- lN(X).
?- lN(f(f(f(0)))). % 3 jest liczba naturalna?
Yes
?-
Przy tak przyjtej denicji liczby naturalnej moemy wprowadzi relacj wiksze lub
rwne (ang. gEq greater or equal).
gEq(X, 0) :- lN(X).
gEq(f(X), f(Y)) :- gEq(X, Y).
13.2.1 Zadanie
Prosz napisa relacj wikszy.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
118 ROZDZIA 13. WICZENIA
13.2.2 Zadanie
Operacj dodawania mona traktowa jako relacj wic dwie (dodawane) liczby z
trzeci bdc ich sum. Rekurencyjnie dodawanie liczb naturalnych moemy opisa
jako:
0 + X = X
f(X) + Y = f(X + Y )
Zatem dodanie liczb 3 i 2 wymaga nastpujcego rozumowania
3 + 2 = f(2) + 2 = f(2 + 2) = f(4) = 5
Prosz napisa (relacje) dodawania.
13.2.3 Zadanie
Prosze napisa relacj mnoenia (pamitajmym, e mnoenie to wielokrotne dodawanie).
13.2.4 Zadanie
Prosze zapisa potgowanie (pamitajmy, e potgowanie to wielokrotne mnoenie)
13.2.5 Zadanie
Prosz napisa program przeliczajcy zapis w postaci cigu nastpnikw na liczb natu-
raln.
13.2.6 Zadanie
Prosz napisa program zamieniajcy liczb naturaln na cig nastpnikw.
13.2.7 Zadanie
Napisz program mnocy dwie liczby naturalne podane jako cig nastpnikw, ktry
bdzie zwraca konkretn warto liczbow (czyli nie cig nastpnikw).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
13.3. WICZENIE 3 119
13.3 wiczenie 3
13.3.1 Zadanie
Zapisa drzewo binarne postaci
10
/ \
4 16
/ \ / \
2 6 12 20
jako struktur rekurencyjn, w ktrej przyjmujemy, e wze drzewa binarnego zawiera
liczb oraz dwa drzewa binarne. Jeli ktre z drzew binarnych w wle nie wystpuje
zapisujemy wwczas w to miejsce pusty.
13.3.2 Zadanie
Napisa predykat sprawdzajacy, czy przekazany argument jest drzewem binarnym (w
sensie takiego drzewa, w ktrym kady wze ma maksymalnie dwoje dzieci).
13.3.3 Zadanie
Napisa predykat sprawdzajacy, czy przekazany argument jest drzewem binarnym (w
sensie takiego drzewa, w ktrym kady wze ma maksymalnie dwoje dzieci oraz lewe
podrzewo ma zawsze elementy mniejsze rwne elementowi w wle a prawe wiksze).
13.3.4 Zadanie
Napisa predykat sprawdzajacy, czy dany element naley do drzewa.
13.3.5 Zadanie
Napisa predykat obliczajcy sum elementw znajdujcych si w wzach drzewa binar-
nego.
13.3.6 Zadanie
Napisa predykat zliczajcy ilo wzw w drzewie binarnym
13.3.7 Zadanie
Napisa predykat przechodzcy po drzewie w porzdku preorder (wze, lewy podwze,
prawy podwze).
13.3.8 Zadanie
Napisa predykat przechodzcy po drzewie w porzdku inorder (lewy podwze, wze,
prawy podwze).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
120 ROZDZIA 13. WICZENIA
13.3.9 Zadanie
Napisa predykat przechodzcy po drzewie w porzdku postorder (lewy podwze, prawy
podwze, wze).
13.3.10 Zadanie
Napisa predykat zwracajcy element maksymalny z drzewa binarnego.
13.3.11 Zadanie
Napisa predykat zliczajcy ilo lici w drzewie.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
13.4. WICZENIE 4 121
13.4 wiczenie 4
13.4.1 Zadanie
Napisa predykat zliczajcy ilo elementw na licie.
13.4.2 Zadanie
Napisa predykat zliczajcy ilo wszystkich elementw na licie wcznie z elementami
podlist.
13.4.3 Zadanie
Napisa predykat usuwajcy pojedycze wystpienie elementu na licie.
13.4.4 Zadanie
Napisa predykat odwracajcy list.
13.4.5 Zadanie
Napisa predykat zwracajcy ostatni element listy.
13.4.6 Zadanie
Napisa predykat zastpujcy wszystkie wystpienia elementu innym elementem.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
122 ROZDZIA 13. WICZENIA
13.5 wiczenie 5
13.5.1 Zadanie
Napisa predykat znajdujcy ostatni element na licie.
13.5.2 Zadanie
Napisa predykat sprawdzajcy czy dwa podane elementy ssiaduj ze sob na licie.
13.5.3 Zadanie
Napisa predykat usuwajcy wszystkie wystpienia zadanego elementu na licie.
13.5.4 Zadanie
Napisa predykat zamieniajcy wskazany element na inny.
13.5.5 Zadanie
Napisa predykat usuwajcy z listy wszystkie powtrzenia.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
13.6. WICZENIE 6 123
13.6 wiczenie 6
13.6.1 Zadanie
Napisa program symulujcy dziaanie maszyny Turinga. Tablica przej okrelana jest
w kodzie, natomiast stan tamy jest argumentem predykatu. Kolejnym argumentem jest
ilo iteracji jakie maj by wykonane. Algorytm powinien wypisywa wszystkie stany
w jakich znalaza si maszyna i zawarto tamy.
13.6.2 Zadanie
Tablice prawdy. Napisa program, ktry oblicza warto logiczn wyraenia boolow-
skiego, dla wszystkich kombinacji zmiennych np. dla wyraenia
and(A,or(not(B),A))
zwrci powinien co w stylu
A = T B = T => T
A = T B = F => T
A = F B = T => F
A = F B = F => F
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
124 ROZDZIA 13. WICZENIA
13.7 wiczenie 7
13.7.1 Zadanie
Napisa program rozpoznajcy wielomiany zmiennej x. Wielomian deniujemy nast-
pujco:
staa jest wielomianem zmiennej x;
x jest wielomianem zmiennej x;
suma, rnica, iloczyn s wielomianami zmiennej x;
wielomian dzielony przez liczb lub sta jest wielomianem.
13.7.2 Zadanie
Napisa program obliczajcy pochodn.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
13.8. WICZENIE 8 125
13.8 wiczenie 8
13.8.1 Zadanie
W ogrodzie siedziay cztery pary narzeczonych zajadajc si liwkami. Andzia zjada
2 liwki, Beata 3, Celina 4, Danusia 5. Ich narzeczeni rwnie nie prnowali.
Andrzej zjad tyle, co jego narzeczona, Bogumi 2 razy tyle, co jego narzeczona, Cezary
3 razy tyle co jego narzeczona, wreszcie Damian 4 razy tyle, co jego narzeczona. Wszyscy
razem zjedli 44 liwki. Jakie s imiona par narzeczonych?
13.8.2 Zadanie
Piecioro przyjaci rywalizowao na biezni. Wincenty ze smutkiem opowiedzia, ze mu sie
nie udao zajac pierwszego miejsca. Grzegorz przybieg na mete jako trzeci po Dymitrze.
Wincenty zauwazy na marginesie, ze Dymitr nie zaja drugiego miejsca, a Andrzej nie
by ani pierwszym ani ostatnim. Borys powiedzia, ze przybieg na mete w slad za
Wincentym.
13.8.3 Zadanie
Szeciu mczyzn o rnych imionach (Andrzej, Dariusz, Mateusz, Micha, Tomasz, Woj-
ciech) jest onatych z kobietami o rnych imionach (Agnieszka, Ewa, Ra, Ania, Alicja,
Ola)
1
oraz posiada sze rnych samochodw (BMW, Fiat, Ford, Mercedes, Opel, Re-
nault) w szeciu rnych kolorach (biay, czerwony, granat, zielony, ty, szary). Kady
pracuje w innym miejscu pracy (bank, hotel, politechnika, restauracja, sd, szpital) i ma
inne hobby(czytanie, fotograa, majsterkowanie, pywanie, rowery, eglarstwo).
Wiedzc, e
Agnieszka i Andrzej s maestwem.
Ola ma czerwony samochd.
Fiat jest zielony.
Waciciel Opla pracuje w restauracji.
Pracownik politechniki lubi czytanie.
Wojciech pywa w wolnych chwilach.
Waciciel granatowego Forda lubi fotografowa.
Tomasz jest wacicielem BMW.
M Ewy lubi eglarstwo.
Dariusz ma biay samochd.
M Ry posiada Mercedesa.
Waciciel szarego auta pracuje w sdzie.
1
Obowizuje monogamia.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
126 ROZDZIA 13. WICZENIA
Po lewej stronie pracownika banku mieszka waciciel ata, a po prawej pasjonat
kolarstwa.
Po lewej stronie pracownika hotelu mieszka waciciel granatowego samochodu, a
z drugiej strony pracownik szpitala.
Micha mieszka na prawo od Ani, a na lewo od niej mieszka Mateusz.
Ssiadem Alicji od lewej strony jest waciciel tego auta, a jego ssiadem od
lewej strony jest znany majsterkowicz.
odpowiedz na pytania
Kto pracuje w szpitalu?
Jaki Kolor ma Renault?
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
13.9. WICZENIE 9 127
13.9 wiczenie 9
13.9.1 Zadanie
Opierajc si na wiadomociach z rozdziau 12 (a w szczeglnoci podrozdziau 12.1)
napisz program ktry dowoln formu rachunku zda sprowadzi do postaci klauzulo-
wej. Zadanie to wykona mona albo przez przeksztacanie formuy (sposb I ze strony
12.1.1), albo za pomoc tablicy prawdy (ktr najpierw naley utworzy w oparciu o
wartoci formuy dla rnych przyporzdkowa, sposb II ze strony 12.1.1).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
128 ROZDZIA 13. WICZENIA
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Rozdzia 14
Rozwizania wicze
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
130 ROZDZIA 14. ROZWIZANIA WICZE
14.1 Odpowiedzi do zadania 13.1
14.1.1 Odpowiedzi do zadania 13.1.1
lubi(piotr,gory).
wysoki(arek).
dal(piotr,hania,tulipan).
podrozuje(michal,autobus,paryz).
figura(trojkat).
figura(kwadrat).
figura(okrag).
?- [t].
\% t compiled 0.00 sec, 1,988 bytes
Yes
?- wysoki(arek).
Yes
?- wysoki(X).
X = arek ;
No
?- figura(trojkat).
Yes
?- figura(X).
X = trojkat ;
X = kwadrat ;
X = okrag ;
No
?- X(trojkat).
ERROR: Syntax error: Operator expected
ERROR: X(trojkat
ERROR: ** here **
ERROR: ) .
?-
14.1.2 Odpowiedzi do zadania 13.1.2
/* Kady czowiek je tylko miso lub ser lub owoce. */
/*
mieso(schab).
ser(gouda).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
14.1. ODPOWIEDZI DO ZADANIA ?? 131
owoce(banan).
je(czlowiek,X) :- mieso(X); ser(X); owoce(X).
*/
jedzenie(mieso).
jedzenie(ser).
jedzenie(owoce).
je(czlowiek,X) :- jedzenie(X).
/* Jeli X jest babci Y, to Y jest wnukiem lub wnuczk X. */
/* raczej nie tak:
wnuk(jan,ada).
wnuczka(ania,ada).
babcia(Y,X) :- wnuk(X,Y); wnuczka(X,Y).
ze wzgldu na zwizek jeli... to...,
ktry zapisujemy jako: to :- jeli
*/
babcia(ala,zosia).
babcia(ala,henio).
wnuk(X,Y) :- babcia(Y,X).
wnuczka(X,Y) :- babcia(Y,X).
/* Dwie osoby s rodzestwem, jeli maj tych samych rodzicw. */
rodzic(ala,ela).
rodzic(ala,adam).
rodzic(jan,ela).
rodzic(jan,adam).
rodzic(henio,fiona).
rodzic(bilbo,antek).
rodzic(bilbo,beata).
rodzenstwo(X,Y) :- rodzic(A,X), rodzic(A,Y), rodzic(B,X), rodzic(B,Y), A\=B.
/* X jest figur jeli jest trojkatem lub kwadratem lub okrgiem. */
figura(trojkat).
figura(kwadrat).
figura(okrag).
jest_figura(X) :- figura(X).
14.1.3 Odpowiedzi do zadania 13.1.3
14.1.4 Odpowiedzi do zadania 13.1.4
silnia(0,F) :- F is 1.
silnia(N1,F1) :- N1>0,
N2 is N1-1,
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
132 ROZDZIA 14. ROZWIZANIA WICZE
silnia(N2,F2),
F1 is N1*F2.
/*
po pierwsze N1 musi byc wieksze od 0,
po drugie musimy najpierw znac warto
silni dla wyrazu o jeden mniejszego
gdy juz te wartosc znamy, to mozemy
obliczyc waciwa wartos czyli F1
*/
14.1.5 Odpowiedzi do zadania 13.1.5
fib(0,F) :- F is 1.
fib(1,F) :- F is 1.
fib(N,F):- N>1,
N1 is N-1,
N2 is N-2,
fib(N1,F1),
fib(N2,F2),
F is (F1 + F2).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
14.2. ODPOWIEDZI DO ZADANIA ?? 133
14.2 Odpowiedzi do zadania 13.2
14.2.1 Odpowiedzi do zadania 13.2.1
gEq(X, 0) :- lN(X),X\=0.
gEq(f(X), f(Y)) :- gEq(X, Y).
lub
gEq(f(X), 0) :- lN(X).
gEq(f(X), f(Y)) :- gEq(X, Y).
14.2.2 Odpowiedzi do zadania 13.2.2
add(0, X, X).
add(f(X), Y, f(Z)) :- add(X, Y, Z).
Dziaanie
?- add(f(f(f(0))), f(f(0)), X).
X = f(f(f(f(f(0)))))
Yes
?-
14.2.3 Odpowiedzi do zadania 13.2.3
mul(0, X, 0).
mul(f(X), Y, Z) :- mul(X, Y, XY), add(XY, Y, Z).
Dziaanie
?- mul(f(f(0)),f(f(f(0))),Z).
Z = f(f(f(f(f(f(0))))))
Yes
?-
Idea, jak to dziaa
mul(f(f(0)),f(f(f(0))),Z)
|
mul(f(0),f(f(f(0))),XY)
|
mul(0,f(f(f(0))),XY) ukonkretnienie XY wartoscia 0
bo pasuje to do mul(0,X,0)
, add(0,f(f(f(0)),XY)
14.2.4 Odpowiedzi do zadania 13.2.4
pow(f(X), 0, 0).
pow(0, f(X), f(0)).
pow(f(N), X, Y) :- pow(N, X, Z), mul(Z, X, Y).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
134 ROZDZIA 14. ROZWIZANIA WICZE
14.2.5 Odpowiedzi do zadania 13.2.5
value(0,0).
value(f(X),Wartosc) :- value(X,WartoscTmp),Wartosc is WartoscTmp+1.
14.2.6 Odpowiedzi do zadania 13.2.6
repr(0,0).
repr(N,f(X)) :- N>0, N1 is N-1, repr(N1,X).
14.2.7 Odpowiedzi do zadania 13.2.7
mulVal(X,Y,V) :- mul(X,Y,Z), value(Z,V).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
14.3. ODPOWIEDZI DO ZADANIA ?? 135
14.3 Odpowiedzi do zadania 13.3
14.3.1 Odpowiedzi do zadania 13.3.1
(10,(4,(2,pusty,pusty),(6,pusty,pusty)),(16,(12,pusty,pusty),(20,pusty,pusty)))
14.3.2 Odpowiedzi do zadania 13.3.2
drzewoB(pusty).
drzewoB((_,Lewe,Prawe)) :- drzewoB(Lewe), drzewoB(Prawe).
14.3.3 Odpowiedzi do zadania 13.3.3
zwroc((X,_,_),X).
db(pusty).
db((_,pusty,pusty)).
db((X,pusty,P)):-db(P),zwroc(P,Z),X<Z.
db((X,L,pusty)):-db(L),zwroc(L,Z),X>=Z.
db((X,L,P)):-db(L),db(P),zwroc(L,Z1),zwroc(P,Z2),X < Z2,X >= Z1.
14.3.4 Odpowiedzi do zadania 13.3.4
elementB(X,(X,_,_)).
elementB(X,(Y,Lewe,Prawe)) :- \+ (X=Y), (elementB(X,Lewe);elementB(X,Prawe)).
14.3.5 Odpowiedzi do zadania 13.3.5
suma(pusty,0).
suma((Element,Lewe,Prawe),Suma) :-
suma(Lewe,SumaL),
suma(Prawe,SumaP),
Suma is SumaL+SumaP+Element.
14.3.6 Odpowiedzi do zadania 13.3.6
ileWezlow(pusty,0).
ileWezlow((_,Lewe,Prawe),Ile) :-
ileWezlow(Lewe,IleL),
ileWezlow(Prawe,IleP),
Ile is IleL+IleP+1.
14.3.7 Odpowiedzi do zadania 13.3.7
preorder((X,L,P),Xs) :- preorder(L,Ls), preorder(P,Ps), append([X|Ls],Ps,Xs).
preorder(pusty,[]).
14.3.8 Odpowiedzi do zadania 13.3.8
inorder((X,L,P),Xs) :- inorder(L,Ls), inorder(P,Ps), append(Ls,[X|Ps],Xs).
inorder(pusty,[]).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
136 ROZDZIA 14. ROZWIZANIA WICZE
14.3.9 Odpowiedzi do zadania 13.3.9
postorder((X,L,P),Xs) :- postorder(L,Ls),postorder(P,Ps),
append(Ps,[X],Ps1),append(Ls,Ps1,Xs).
postorder(pusty,[]).
14.3.10 Odpowiedzi do zadania 13.3.10
max(pusty,fail).
max((Element,_,pusty),Element).
max((_,_,Prawe),Max) :- \+ (Prawe=pusty), max(Prawe,Max).
14.3.11 Odpowiedzi do zadania 13.3.11
ileLisci(pusty,0).
ileLisci((_,pusty,pusty),1).
ileLisci((_,Lewe,Prawe),Ile) :- \+ (Lewe=pusty,Prawe=pusty),
ileLisci(Lewe,IleL),
ileLisci(Prawe,IleP),
Ile is IleL+IleP.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
14.4. WICZENIE 4 137
14.4 wiczenie 4
14.4.1 Odpowiedzi do zadania 13.4.1
co([],0).
co([H|T],X):- co(T,X1), X is X1+1.
14.4.2 Odpowiedzi do zadania 13.4.2
co([],0).
co(H,1) :- \+lista(H).
co([H|T],X):- co(H,X1),co(T,X2), X is X1+X2.
14.4.3 Odpowiedzi do zadania 13.4.3
usun(X,[X|Xs],Xs).
usun(X,[Y|Ys],[Y|Zs]) :- usun(X,Ys,Zs).
14.4.4 Odpowiedzi do zadania 13.4.4
odwroc([],[]).
odwroc([X|Xs],Zs) :- odwroc(Xs,Ys), polacz(Ys,[X],Zs).
14.4.5 Odpowiedzi do zadania 13.4.5
ostatni([X],X).
ostatni([H|T],X) :- ostatni(T,X).
14.4.6 Odpowiedzi do zadania 13.4.6
zastap([],Y1,Y2,[]).
zastap([Y1|T1],Y1,Y2,[Y2|T2]) :- zastap(T1,Y1,Y2,T2).
zastap([H|T1],Y1,Y2,[H|T2]) :- \+ (H =Y1), zastap(T1,Y1,Y2,T2).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
138 ROZDZIA 14. ROZWIZANIA WICZE
14.5 wiczenie 5
14.5.1 Odpowiedzi do zadania 13.5.1
ostatni(X,[X]).
ostatni(X,[_|Y]) :- ostatni(X,Y).
14.5.2 Odpowiedzi do zadania 13.5.2
sasiad(X,Y,[X,Y|_]).
sasiad(X,Y,[_|Z]) :- sasiad(X,Y,Z).
14.5.3 Odpowiedzi do zadania 13.5.3
usunAll(_,[],[]).
usunAll(X,[X|T],Z) :- !, usunAll(X,T,Z).
usunAll(X,[Y|T1],[Y|T2]) :- usunAll(X,T1,T2).
14.5.4 Odpowiedzi do zadania 13.5.4
%elementSzukany,NowyElement,Lista,Wynik
zamien(_,_,[],[]).
zamien(X,Y,[X|T1],[Y|T2]) :- !, zamien(X,Y,T1,T2).
zamien(X,Y,[Z|T1],[Z|T2]) :- !, zamien(X,Y,T1,T2).
14.5.5 Odpowiedzi do zadania 13.5.5
%zmienna A pelni role akumulatora, gromadzacego wszystkie
%pojedyncze wystapienia elementow
usunPowt(L,W) :- usunPowtHelp(L,[],W).
usunPowtHelp([],A,A).
usunPowtHelp([H|T],A,L) :- nalezy(H,A), !, usunPowtHelp(T,A,L).
usunPowtHelp([H|T],A,L) :- usunPowtHelp(T,[H|A],L).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
14.6. WICZENIE 6 139
14.6 wiczenie 6
14.6.1 Odpowiedzi do zadania 13.6.1
Kod programu
%maszyna turinga - definicja funkcji przejscia wg. formatu
%(stan,odczytanySymbol,nowyStan,symbolDoZapisania,kierunek)
d(s,a,1,b,r).
d(d,b,2,a,r).
d(1,a,1,b,l).
d(1,b,k,a,r).
d(2,a,k,b,r).
d(2,b,2,a,l).
%predykaty pomocnicze
odwroc([],[]).
odwroc([X|Xs],Zs) :- odwroc(Xs,Ys), polacz(Ys,[X],Zs).
polacz([],Lista,Lista).
polacz([H|T],Lista,[H|Res]) :- polacz(T,Lista,Res).
%koniec predykatow pomocniczych
%poruszanie sie po tasmie w prawo
%gdy ,,skonczyla sie tasma - dodaje elementy puste
tape([],1,[],[.],[]).
tape([],Pos,[.|L],H,R) :- Pos>1,
PosTmp is Pos -1,
tape([],PosTmp,L,H,R).
%gdy tasma sie nie ,,skonczyla - wykorzystuje elementy, ktore sa
tape([HT|TT],1,[],HT,TT).
tape([HT|TT],Pos,[HT|L],H,R) :- Pos>1,PosTmp is Pos -1,
tape(TT,PosTmp,L,H,R).
%poruszanie sie po tasmie w lewo
%odwracam tasme i stosuje reguly dla poruszania sie w prawo a potem odwracam
%i zamieniam wyniki
tape(List,-1,RRev,H,L) :- odwroc(List,RevList),
tape(RevList,1,L,H,R),
odwroc(R,RRev).
tape(List,Pos,RRev,H,LRev) :- Pos < -1,
PosTmp is Pos * (-1),
odwroc(List,RevList),
tape(RevList,PosTmp,L,H,R),
odwroc(L,LRev),
odwroc(R,RRev).
turing(_,_,_,0) :- !.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
140 ROZDZIA 14. ROZWIZANIA WICZE
turing(Tape,Pos,State,Steps) :- tape(Tape,Pos,L,H,R),
d(State,H,NewState,NewSymbol,Dir),
aktualizujPos(Pos,Dir,NewPos),
aktualizujTasme(L,NewSymbol,R,NewTasma),
wypiszTasme(NewTasma,NewPos),
wypiszStan(NewState),
NewSteps is Steps-1,
turing(NewTasma,NewPos,NewState,NewSteps).
aktualizujPos(P,r,NP) :- NP is P + 1.
aktualizujPos(P,l,NP) :- NP is P - 1.
aktualizujTasme(L,NewSymbol,R,NewTasma) :- polacz(L,[NewSymbol],T),
polacz(T,R,NewTasma).
wypiszTasme(T,P) :- tape(T,P,L,H,R),wyp(L),wypS(H),wyp(R).
wyp([]).
wyp([H|T]) :- write(H),write(,),wyp(T).
wypS(X) :- write(|),write(X),write(|).
wypiszStan(S) :- write( nowy stan: ),write(S),nl.
Wywoanie
?- turing([a,b,a,b,a,a,a,b,a],5,s,3).
a,b,a,b,b,|a|a,b,a, nowy stan: 1
a,b,a,b,|b|b,a,b,a, nowy stan: 1
a,b,a,b,a,|b|a,b,a, nowy stan: k
More?
14.6.2 Odpowiedzi do zadania 13.6.2
Wersja dziaajaca dla okrelonej iloci zmiennych, wymagajca ingerencji w kod przy
zmianie ich iloci.
v(true).
v(fail).
a(A,B):-A,B.
o(A,B):-(A;B),!.
n(A):- \+A.
sprawdz(A,B,C,Expr) :- v(A),v(B),v(C),
write( ),write(A),
write( ),write(B),
write( ),write(C),
write(Expr),calc(Expr),fail.
calc(Expr):- Expr,write( -> T),nl.
calc(Expr):- \+Expr,write( -> F),nl.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
14.6. WICZENIE 6 141
Wersja dziaajaca dla dowolnej iloci zmiennych, ktre musz by przekazane w licie
jako pierwszy argument wywoania, np.
sprawdz([A,B,C],a(A,o(n(B),C))).
Program.
v(true).
v(fail).
a(A,B):-A,B.
o(A,B):-(A;B),!.
n(A):- \+A.
sprawdz([],_).
sprawdz([A|B],Expr) :- v(A),write( ),write(A), sprawdz(B,Expr),calc(Expr),fail.
calc(Expr):- Expr,write( -> T),nl.
calc(Expr):- \+Expr,write( -> F),nl.
Niestety wyniki nie s czytelne
?- sprawdz([A,B,C],a(A,o(n(B),C))).
true true true -> T
fail -> F
fail true -> T
fail -> T
fail true true -> F
fail -> F
fail true -> F
fail -> F
No
Aby poprawi czytelno naley napisa program tak, aby powyszy wynik zosta wy-
wietlony w postaci
?- sprawdz([A,B,C],a(A,o(n(B),C))).
true true true -> T
fail -> F
fail true -> T
fail -> T
fail true true -> F
fail -> F
fail true -> F
fail -> F
No
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
142 ROZDZIA 14. ROZWIZANIA WICZE
14.7 wiczenie 7
14.7.1 Odpowiedzi do zadania 13.7.1
wielomian(X,X).
wielomian(T,X) :- number(T).
wielomian(T,X) :- atom(T).
wielomian(W1+W2, X) :- wielomian(W1, X), wielomian(W2, X).
wielomian(W1-W2, X) :- wielomian(W1, X), wielomian(W2, X).
wielomian(W1*W2, X) :- wielomian(W1, X), wielomian(W2, X).
wielomian(W1/W2, X) :- wielomian(W1, X), (number(W2); atom(W2)).
wielomian(W^N, X) :- wielomian(W, X), integer(N), N>0.
14.7.2 Odpowiedzi do zadania 13.7.2
d(X,X,1) :- !.
d(C,X,0) :- number(C); atom(C).
d(U+V,X,A+B) :- d(U,X,A), d(V,X,B).
d(U-V,X,A-B) :- d(U,X,A), d(V,X,B).
d(C*U,X,C*A) :- (number(C);atom(C)),\+ C=X,d(U,X,A),!. %przypadek szczeglny
d(U*V,X,A*V+U*B) :- d(U,X,A), d(V,X,B).
d(pow(U,C),X,C*pow(U,NC)*W) :- number(C),NC is C - 1,d(U,X,W).
r(W,W) :- (number(W);atom(W)),!.
r(W,N) :- W =..[Oper,L,R],
r(L,Xl),
r(R,Xr),
red(Oper,Xl,Xr,N).
red(+,X,0,X).
red(+,0,X,X).
red(+,X,Y,Z) :- number(X),number(Y),Z is X+Y,!.
red(+,X,Y,X+Y).
red(-,X,0,X).
red(-,0,X,X).
red(-,X,Y,Z) :- number(X),number(Y),Z is X-Y,!.
red(-,X,Y,X-Y).
red(*,_,0,0).
red(*,0,_,0).
red(*,X,1,X).
red(*,1,X,X).
red(*,X,Y,X*Y).
dr(W,X,Wynik) :- d(W,X,WW),r(WW,Wynik).
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
14.8. WICZENIE 8 143
14.8 wiczenie 8
14.8.1 Odpowiedzi do zadania 13.8.1
14.8.2 Odpowiedzi do zadania 13.8.2
14.8.3 Odpowiedzi do zadania 13.8.3
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
144 ROZDZIA 14. ROZWIZANIA WICZE
14.9 wiczenie 9
14.9.1 Odpowiedzi do zadania 13.9.1
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
Bibliograa
[1] I. Bratko, Prolog Programming for Articial Intelligence, 3rd edition, Addison-
Wesley Publishers, 2001.
[2] W. F. Clocksin, C. S. Mellish, Prolog. Programowanie, Wydawnictwo HELION,
Gliwice, 2003.
[3] M. A. Covington, Ecient Prolog: a practical tutorial, Articial Intelligence Re-
view, 273-287, 5 (1991).
[4] M. A. Covington, Research Report AI-1989-08. Ecient Prolog: A Practical Guide,
Articial Intelligence Programs, The University of Georgia, Athens, Georgia 30602,
August 16, 1989.
[5] U. Endriss, Lecture notes. An Introduction to Prolog Programming, University of
Amsterdam, Version: 7 July 2007.
[6] L. Sterling, E. Shapiro. The Art of Prolog, 2nd edition, MIT Press, 1994.
[7] J. Lu, J. J. Mead. Prolog. A Tutorial Introduction, Computer Science Department
Bucknell University Lewisburg, PA 17387.
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)
146 BIBLIOGRAFIA
Programowanie w logice. Prolog c 20072009 by P. Fulmaski (ostatnia modykacja: 18 maja 2009)

You might also like