-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprolog_notes1.txt
173 lines (133 loc) · 6.02 KB
/
prolog_notes1.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
% Променливи:
Започват с главна буква или с подчертавка.
_ - анонимна променлива, хваща всякакви типове данни.
Съставени от [a-z][A-Z][0-9][_]
Var, X, Y, This_is_a_var, _Kosio
% Константи:
%% Атоми:
Всичко заградено от ' ' ('тест')
Започващи с малка буква и [a-z]...[_]
[], !, ;, {}
Поредица от странни символи - *,+,\,/,@,...
%% Числа - Number
Цели - integer
Реални - real
%% Съставни термове - позволяват да представяме по-сложни структури
Пр. foo(bar(0), baz(bag(1),1)).
^~~~principal functor
%% Списъци
[a, b, c] <--> .(a, .(b, .(c, [])))
. - ./2 - principal functor
[] - списък
Х и Y - обекти -> [X|Y]
%% Оператори
Приоритет - 1 до 1200
Тип - инфиксен, постфиксен, префиксен
?- Х = 3 + 1.
Х = 3 + 1
?- А + В = 3 + 1.
^~~~ унифициращ оператор
А = 3
B = 1
?- X = [a, b, c].
?- X = [H|T].
H = a
T = [b, c]
?- foo(X, alvin) = foo(ben, Y).
X = ben
Y = alvin
т1, т2 - термове
База:
Ако са един и същ атом, то са унифицируеми.
Ако т1 е променлива, то инстанцираме т1 със значението на т2.
Ако т2 е променлива, то инстанцираме т2 със значението на т1.
Ако т1 и т2 са съставни термове, то сравняваме арността и principal
functor. Ако са еднакви, то <A1, ..., An> арност на т1 и
<B1, ..., Bn> арност на т2; прилагаме рекурсивно процедурата за
всяка двойка <Ai, Bi> за 1 <= i <= n.
%% Arithmetic simplification
%% Унифициране
\= проверява дали двойка е унифицируема
=:= аритметично равно
=\= аритметично неравно
=< Равно или по-малко
>= По-голямо или равно
< По-малко
> По-голямо
%% Предикати
С малка буква, могат да започват и с $.
%% Клаузи
Програмни клаузи и целеви клаузи:
VVVV
Какви неща са истина в нашия свят.
Факти.
Правила на извод: можем да извеждаме нови факти с тях.
A :- B1, ..., Bn
^~~~~~ Body
^~~~~~~ Neck
^~~ Head
Тоест B1 & ... & Bn => A.
Резултатът от всяка формула да се записва в променливи.
%%%%
Va <--> not Ja not
%%%%
%... - коментар
% Всяка нова променлива е под действието на екзистенциален квантор.
% (За Всяко a)Ф == (Не Същ a)Не-Ф
% За всяко а <> Не Същ а Не
% p(x, y) - х е родител на у
% Как е vnuk(x, y)?
% Пр. y - z - x
% p(maria, ivan).
% p(maria, hristo).
% p(ivan, peter).
% vnuk(x, y) :- p(y, z), p(z, x).
% ?- vnuk(maria, peter). % Петър внук ли е на Мария?
% ?- vnuk(maria, x). % Кои са внуците на Мария?
% ?- vnuk(x, maria). % Кои са прародителите на Мария?
% ?- vnuk(x, y). % Кои са двойките прародител-внук?
% Как се правят структури от данни?
% Пример: свързан списък
% add(X, L, N). % X - какво, L - къде, N - резултат.
% member(X, L). % Как?
% Ще кодираме списъкът като терм.
% Трябва ни функционален символ f(...).
% Два вида списъци - празни и непразни (n и e).
% n(H, T).
% e = [].
% Елементите НЕ са тип данни, а релации.
% [1, 2, 3]
% n(1, n(2, n(3, e))).
% add(X, L, n(X, L)). % n(X, L) е нова променлива - същият списък, но с Х в началото.
% add(X, n(H, T), n(H, T1)) :- add(X, T, T1). % Добавя елемент някъде във вътрешността.
% "Добавям Х към списък с начало H и останали елементи Т,
% получаваме списък с начало Н и останали елементи Т1, ако като добавим Х към Т получим Т1.
% [ H | T1 ]
% |
% V
% [ H | T ]
% member(X, n(X, T)). % *** - факт
% member(X, n(H, T)) :- member(X, T). % ^^^ - правило
% ?- member(2, n(1, e)). % Първо запитваме ***, после ^^^, откъдето следва и рекурсията.
% Няма ситуация, в която да напаснем n(X, e) на T в member(X, T).
% Тъй като няма факт member(X, e), няма да е изпълнена дясната част на правилото.
% [ A1, A2, ..., An | T ] - Първите n елемента на списъка и Т са всички останали.
% [ A, B, C | T ]
% [ 1, 2, 3, 4, 5 ] - A = 1, B = 2, C = 3, T = [ 4, 5 ]
% [ 1, 2, 3 ] - A = 1, B = 2, C = 3, T = []
% [ 1, 2 ] - Няма такъв шаблон!
% [ 1, 2, _ ] - Ще пасне, но не можем да остойностим C
% _ - анонимна променлива
% member(H, [ H | T ]).
% member(X, [ H | T ]) :- member(X, T).
% A -> [ H | A ]
% append(A, B, C). % A + B -> C % [ H | A ] + [ B ] + [ H | C ]
% append([], B, B).
% append([ H | A], B, [ H | C ]) :- append(A, B, C).
% first(F, L) :- [ F | _ ] = L.
% Homework: last(F, L)
% Last:
% last(F, [ F | [] ]). OR last(F, [ F ] ).
% last(F, [ _ | T ]) :- last(F, T).
% OR
% last(F, L) :- append(_, [ F ], L). % Тоест, дали има такъв списък, че като залепим синглетон F отзад ще получим списък L?