Съществуват различни начини за представяне на графи.
Първият начин е чрез списък от ребрата, т.е. явно задаване на E.
Вторият начин е чрез списъци на съседите (синовете за ориентирания случай) – за всеки връх задаваме множество (за мултиграф задаваме списък, в който може да има повторения) от неговите съседи (синове).
За третия начин дефинираме матрица на съседство за краен ориентиран мултиграф G (V, E, fG) – MG =,
aij = |{ e |e E, fG (e) = (vi, vj) } |. При неориентирани графи не
отчитаме примките, т.е. aii = 0 за i = 1, 2, …, |V|. Ясно е, че при краен неориентиран мултиграф G матрицата MG е симетрична и с нули по диагонала, при неориентирани графи тя е двоична, а при мултиграфи елементите са произволни естествени числа.
Тъй като всяко дърво е граф, то за представяне на дървета можем да използваме начините за представяне на графи. Съществуват, обаче, много по-ефективни представяния. Например, всяко кореново дърво D (V, E) с корен r може да бъде представено със списък на бащите: едномерен масив p с |V| елемента,
като p[v] е върхът, към който е присъединен върха v (бащата на v), по дефиниция p[r] = 0 – несъществуващ връх.
Нека D (V, E) е кореново дърво. За всеки връх v V дефинираме
(v) – разклоненост на v като броят на синовете на v. Максималната разклоненост на върховете в едно кореново дърво наричаме разклоненост на дървото. Кореново дърво с разклоненост 2 наричаме двоично дърво, с разклоненост 3 троично дърво и т.н. с разклоненост m m-ично дърво.
Във всяко двоично дърво може условно да се въведе наредба на синовете – ляв и десен син. По този начин двоичните дървета удобно се представят чрез наредба на синовете – за всеки връх се задава наредена двойка от синовете му – (ляв син, десен син), отсъствието на син задаваме например с 0.
Съвсем аналогично можем да въведем условна наредба на синовете и в m-ично дърво и да представяме m-ичните дървета с наредени m-торки от синове, но това е твърде неефективно, тъй като в таблицата ще има много празни полета. Затова ще разгледаме едно друго представяне.
Нека в кореновото дърво D е въведена наредба на синовете. Съвкупността от всички синове на даден връх ще наричаме братство. Първият син в братството наричаме най-ляв син, а съседът на всеки син, който стои непосредствено отдясно наричаме десен брат. Ясно е, че последният в братството няма десен брат. За коренови дървета с по-голяма разклоненост може да се използва представянето, наречето “най-ляв син, десен брат” – това е списък от наредени двойки, по една за всеки връх, на първо място стои най-левия син на дадения връх (0, ако няма синове), а на второ място стои десният брат на върха (0, ако той е последен в братството).
4. Семантика на рекурсивните програми с предаване на параметрите по стойност.
Ще считаме, че в нашия език за програмиране има само
два типа данни: Nat и Bool. Nat са естествените числа, в Bool има две стойности tt - истина и ff - лъжа. Ще считаме, че разполагаме с определен набор от основни операции oт следните видове:
-
операции f : Natn Nat, n 1, например събиране (+),
умножение (*) и т.н.;
-
операции f : Natn Bool, n 1, например равенство (=), различните видове неравенства (<, , >, ) и т.н.;
-
операции f : Booln Bool, n 1, например конюнкция (&), дизюнкция (), отрицание () и т.н.
Синтактичните елементи на езика са следните:
-
константи от тип Nat и Bool за означаване на елементи
на Nat и Bool;
-
символи за основните операции;
-
обектови променливи, които ще означаваме с главните букви
X, Y, Z, …евентуално с индекси, тези променливи ще приемат стойности естествените числа от Nat;
-
функционални променливи, които ще означаваме с Fkn, където k е индекс, променливата Fkn ще приема стойност частична функция над Nat, n указва броят на аргументите на функцията;
-
точки, запетаи, скоби, чрез които ще постигаме еднозначен синтактичен анализ.
Дефинираме индуктивно понятието терм от тип Nat.
База:
-
Всяка константа от тип Nat е терм от тип Nat.
-
Всяка обектова променлива е терм от тип Nat.
Предположение: Нека 1, 2, …, n са термове от тип Nat.
Стъпка:
-
Ако f : Natn Nat е основна операция, то f (1, 2, …, n) е терм от тип Nat.
-
Ако Fkn е функционална променлива, то Fkn (1, 2, …, n) е терм от тип Nat.
Дефинираме индуктивно понятието терм от тип Bool.
База:
-
Всяка константа от тип Bool е терм от тип Bool.
-
Ако f : Natn Bool е основна операция и 1, 2, …, n са термове от тип Nat, то f (1, 2, …, n) е терм от тип Bool.
Предположение: Нека 1, 2, …, n са термове от тип Bool.
Стъпка: Ако f : Booln Bool е основна операция, то f (1, 2, …, n) е терм от тип Bool.
Дефинираме понятието условен терм. Нека е терм от тип Bool,
1, 2 са термове от тип Nat. Тогава if then 1 else 2 е условен терм.
По-нататък, под терм ще разбираме кой да е от трите вида термове.
Ясно е, че ако е терм, то в участват краен брой обектови и функционални променливи. Ще използваме означението
(X1, …, Xn, , , …, ) за да укажем, че обектовите променливи на са сред X1, …, Xn, а функционалните променливи на са сред , , …, . Понякога ще използваме съкратен запис (X, F). Също, ще си позволяваме да изпускаме броя на аргументите за една функционална променлива, ако той не е съществен.
Нека 1, 2, …, n са термове от тип Nat, (X1, …, Xn, F) е терм.
Означаваме с (X1/1, X2/2, …, Xn/n, F) термът, който се получава от чрез едновременно заместване на всяка от обектовите променливи X1, …, Xn с термовете 1, …, n съответно. Понякога ще използваме съкратен запис (X/, F).
Термове, в които не участват обектови променливи ще наричаме функционални термове. Естествено, в горните означения, ако термовете 1, …, n са функционални, то (X/, F) също е функционален терм.
Програма е синтактичен обект R от следния вид:
0 (X1, …, Xn, , , …, ), where
(X1, …, ) = 1 (X1, …, , , , …, )
(X1, …, ) = 2 (X1, …, , , , …, )
…
(X1, …, ) = k (X1, …, , , , …, )
Тук 0 е терм от тип Nat, 1, …, k са термове от тип Nat или условни термове.
Ще определим операционната семантика на една програма R.
Нека е функционален терм. Израз от вида c, където c е константа от типа на наричаме опростяване на
в програмата R.
Ще дефинираме правила, по които ще се извършва опростяването.
-
c c за всяка константа c (от тип Nat или от тип Bool).
-
Нека f е n-местна основна операция, 1, …, n са функционални термове, 1 c1, 2 c2, …, n cn и
f (c1, …, cn) = c. Тогава f (1, 2, …, n) c. Тук 1, …, n имат типове, които съответстват на типа на операцията f.
-
Нека е функционален терм от тип Bool, 1, 2 са функционални термове от тип Nat.
-
Нека tt и 1 c. Тогава if then 1 else 2 c.
-
Нека ff и 2 c. Тогава if then 1 else 2 c.
3. Нека 1, 2, …, са функционални термове от тип Nat,
1 i k.
Нека 1 c1, 2 c2, …, .
Нека i (X1/c1, X2/c2, …, /, , , …, ) c.
Тогава (1, 2, …, ) c.
От вида на правилото 3. следва, че преди да предадем параметрите на дадена подпрограма трябва задължително да намерим техните стойности.
Казваме, че опростяването c е изводимо по стойност в
програмата R и отбелязваме R c, ако съществува крайна редица S0, S1, …, Sn от множества от опростявания, такава че:
-
S0 = , c Sn.
-
За всяко i = 0, 1, …, n-1 имаме, че Si+1 = Si { c}, където опростяването c e извършено по правило 0. или по едно от правилата 1., 2., 3. с предпоставки елементи на Si.
Числото n наричаме дължина на извода за опростяването c.
Лема (за извода по стойност): Нека R c с дължина на извода k.
-
Ако е константа, то = c.
-
Ако = f (1, 2, …, n), то съществуват константи c1, c2, …, cn, такива че R i ci, i = 1, 2, …, n, при това с дължина на изводите по-малка от k и f (c1, c2, …, cn) = c.
-
Ако = if then 1 else 2, то R tt и R 1 c
с дължина на изводите по-малка от k или R ff и
R 2 c с дължина на изводите по-малка от k.
-
Ако = (1, 2, …, ), то съществуват константи
c1, c2, …, , такива че R j cj, j = 1, 2, …, ni с дължина на изводите по-малка от k и
R i (X1/c1, X2/c2, …, /, F) c с дължина на извода по-малка от k.
С помощта на лемата за извода, лесно може да се докаже следното твърдение:
Твърдение (еднозначност на опростяването по стойност):
Нека е функционален терм, c1 и c2 са константи от типа на и
R c1 и R c2. Тогава c1 = c2.
Дефинираме функция OV (R) : n ,
OV (R) (a1, a2, …, an) b R 0 (X1/a1, X2/a2, …, Xn/an, F) b.
Функцията OV (R) наричаме операционна семантика на програмата R с предаване по стойност.
Определението е коректно, т.е. OV (R) действително е функция, тъй като е в сила еднозначност на опростяването по стойност.
Нека A e произволно множество, в което е въведена частична наредба . Нека съществува A, който е най-малък относно , т.е. a за всяко a A. Нека, освен това, всяка монотонно растяща редица а0 а1 … an …има точна горна граница в A, т.е. съществува a A, такова че an a за всяко n и за всяко
b A, такова че an b за всяко n имаме, че a b. Естествено, точната горна граница a А е единствена, означаваме a = . При тези предположения, наредената тройка (A, , ) наричаме област на Скот.
Ще дадем пример за област на Скот.
С Fn, n ≥ 1 означаваме множеството на всички частични функции на n аргумента над множеството на естествените числа .
В множеството Fn въвеждаме частична наредба:
(f, g Fn) f g за всяко x n, y имаме f (x) y g (x) y. Ако f g, казваме че f е подфункция на g или, че g е продължение на f. Наредбата притежава най-малък елемент – никъде дефинираната функция, която ще означаваме с ! – тя се продължава до всяка функция.
Твърдение: Нека { fk} е монотонно растяща редица от
функции, fk Fn. Дефинираме функцията g по следния начин:
(x n, y ) g (x) y съществува k , такова че fk (x) y.
Тогава g е добре дефинирана n-местна функция, която е точна горна граница на { fk }.
Доказателство: Тривиална проверка.
Като следствие тройката Fn = (Fn, , !) е област на Скот.
Нека A1 = (A1, 1, 1), A2 = (A2, 2, 2), …, An = (An, n, n), n 2 са области на Скот. Означаваме A = A1 x A2 x … x An – декартовото произведение на множествата A1, A2, …, An.
В A въвеждаме релация : за всеки ai Ai, bi Ai, i = 1, 2, …, n,
(a1, a2, …, an) (b1, b2, …, bn) a1 1 b1 и a2 2 b2 и …и an n bn.
Очевидно е, че е частична наредба в А. При това
= (1, 2, …, n) е най-малък елемент в A относно .
Твърдение: Нека { (ak1, ak2, …, akn) } е монотонно растяща редица от елементи на A. Нека ai Ai е точната горна граница на { aki},
i = 1, 2, …, n. Тогава (a1, a2, …, an) A е точна горна граница на
редицата { (ak1, ak2, …, akn) }.
Доказателство: Тривиална проверка.
И така показахме, че A = (A, , ) е област на Скот, където
A = A1 x A2 x … x An, е дефинираната частична наредба,
= (1, 2, …, n). Тази област на Скот наричаме декартово произведение на областите на Скот A1, A2, …, An.
Нека A1 = (A1, 1, 1), A2 = (A2, 2, 2) са области на Скот.
Казваме, че изображението f : A1 A2 е непрекъснато, ако за всяка монотонно растяща редица a0 1 a1 1 …1 an 1 …от елементи на A1 имаме, че f () е точна горна граница на редицата { f (an)} в A2.
Казваме, че изображението f : A1 A2 е монотонно, ако
за всеки a, b A1 имаме a 1 b f (a) 2 f (b).
Твърдение: Всяко непрекъснато изображение f : A1 A2 е монотонно.
Доказателство: За всеки a, b A1 и a 1 b разглеждаме монотонната редица a, b, b, …и използваме непрекъснатостта.
Така, ако f : A1 A2 е непрекъснато изображение и
a0 1 a1 1 …1 an 1 …е монотонно растяща редица в A1, то
f (a0) 2 f (a1) 2 …2 f (an) 2 …е монотонно растяща редица в A2 и
f () = .
Нека A = (A, , ), Ai = (Ai, i, i), i = 1, 2, …, n са области на Скот.
Твърдение: Нека fi : A Ai са непрекъснати изображения,
i = 1, 2, …, n. Дефинираме изображение
f1 x f2 x …fn : A A1 x A2 x … An,
(f1 x f2 x …fn)(a) = (f1 (a), f2 (a), …, fn (a)) за всяко a A.
Твърдим, че f1 x f2 x …x fn е непрекъснато.
Доказателство: Тривиална проверка.
Нека A = (A, , ) e област на Скот и f : A A е тотално изображение.
Казваме, че a A е неподвижна точка на f, ако f (a) = a.
Казваме, че a A е най-малка неподвижна точка на f, ако
f (a) = a и за всяко b A, такова че f (b) = b имаме a b.
Естествено, ако f притежава най-малка неподвижна точка, тя е единствена.
Казваме, че a A е квазинеподвижна точка на f, ако f (a) a.
Казваме, че a A е най-малка квазинеподвижна точка на f,
ако f (a) a и за всяко b A, такова че f (b) b имаме a b.
Естествено, ако f притежава най-малка квазинеподвижна точка, тя е единствена.
Сподели с приятели: |