Analiza Algorytmów Moduł 2 Poprawność algorytmów Aleksandra Orpel Spis treści 1 Poprawność algorytmów 2 1.1 Niezmienniki pętli... 2 1.2 Algorytm NWD Euklidesa..................... 4 1.3 Wyszukiwanie w tekście maksymalnych prefiksów... 8 2 Bibliografia 13 1
1 Poprawność algorytmów Zkażdym algorytmem A zwiazane sa dwa warunki: warunek poczatkowy α, podajacy ograniczenia na dane wejściowe algorytmu oraz warunek końcowy β,opisuj acy własności danych wyjściowych algorytmu i ich zwiazek z danymi wejściowymi. Wprowadzimy teraz następujace pojęcie: Definicja 1. Mówimy, że algorytm A jest semantycznie poprawny względem warunków poczatkowego α ikońcowego β,jeśli dla każdych danych wejściowych spełniajacych warunek α obliczenie algorytmu A dochodzi do punktu końcowego oraz końcowe wartościowanie zmiennych spełnia warunek β. (Poprawność semantyczna oznacza zatem, że algorytm wykonuje postawione przed nim zadania.) W dowodach poprawności semantycznej algorytmów stosujemy metodę indukcji matematycznej względem liczby powtórzeń instrukcji iteracyjnej lub poziomu zagnieżdżenia realizacji procedury rekurencyjnej. Innym sposobem jest wykorzystanie twierdzenia o niezmiennikach pętli. Oczywiście, aby dowód poprawności był pełny, należy również sprawdzić, czy wszytkie operacje częściowe takie, jak dzielenie czy przechodzenie po dowiazaniu w liście lub drzewie, sa wykonalne. W zwiazku z tym poprawności algorytmu A względem warunków poczatkowego α i końcowego β dowodzimy przez pokazanie, że ma on następujace trzy własności: 1. dla każdych danych wejściowych spełniajacych warunek α, jeżeli obliczenie algorytmu A dochodzi do punktu końcowego, to otrzymane wyniki spełnia warunek β, ( mówimy wówczas, że algorytm jest częściowo poprawny względem warunków poczatkowego α ikońcowego β ); 2. dla każdych danychwejściowych spełniajacych warunek α obliczenie algorytmu nie jest przerwane (mówimy wówczas, że algorytm ma własność określoności obliczeń względem warunku poczatkowego α ); 3. dla każdych danychwejściowych spełniajacych warunek α obliczenie algorytmu nie jest nieskończone (mówimy wówczas, że algorytm ma własność stopu względem warunku poczatkowego α ). 1.1 Niezmienniki pętli Wprowadzimy teraz pojęcie niezmiennika pętli, które jest często wykorzystywane do projektowania algorytmów oraz dowodzenia ich poprawności. W tym celu 2
przyjmiemy pewne oznaczenia dotyczace elementów pętli while, która jest ciagiem kroków w algorytmie lub programie majacym postać while g, do S (P) i oznaczajacym, -(*) sprawdź, czy warunek g jest prawdziwy, - jeśli tak, to wykonaj polecenia S,anastępnie wróć do(*), - jeśli g nie jest spełniony, to omińpętlę i przejdź do poleceńwystępujacych za pętla w programie głównym. Warunek g nazywać będziemy warunkiem dozoru pętli, a S treściapętli. Wykonanie kroków S w pętli (P ) nazywamy jej przebiegiem lub iteracja. Definicja 2. Mówimy, że zdanie p jest niezmiennikiem pętli (P ), gdy spełniony jest następujacy warunek: jeżeli zdania p i g sa prawdziwe zanim wykonamy kroki S, to zdanie p będzie prawdziwe po wykonaniu poleceń S. Twierdzenie 3. (O niezmiennikach pętli) Zał óżmy, że p jest niezmiennikiem pętli (P) oraz, że zdanie p jest prawdziwe przed wejściem w pętlę (P). Wtedy zdanie p jest prawdziwe po każdej iteracji pętli. Jeśli pętla kończy działanie, topojejzakończeniu zdanie p jest również prawdziwe, a zdanie g jest fałszywe. Dowód. Zzałożenia zdanie p jest prawdziwe na poczatku,tzn.po0. iteracji. Przypuśćmy, że zdanie p jest fałszywe po pewnej k. iteracji. Niech teraz n będzie pierwszym numerem iteracji, po której p stało sięfałszywe. Oznacza to, że n jest najmniejsza liczba naturalna-tak a, że po n -tej iteracji p jest fałszywe. (Istnienie takiego n zapewnia zasada dobrego uporzadkowania, zgodnie z która każdy niepusty podzbiór liczb naturalnych ma element najmniejszy.) Wówczas wiemy, że po n 1. iteracji p było jeszcze prawdziwe. Zdanie g było również prawdziwe, gdyż inaczej nie wykonalibyśmy n. iteracji. Zatem p pozostaje prawdziwe po następnym - n. przebiegu, ponieważ p jest niezmiennikiem pętli (P ). To jest jednak sprzeczne z wyborem n. Stad po każdym przebiegu pętli zdanie p pozostaje prawdziwe, w szczególności, jeśli pętla kończy działanie, po ostatnim wykonaniu poleceń S pętli zdanie p nie może być fałszywe. Gdy pętla zakończy się, to zdanie g będzie oczywiście fałszywe, zaś zdanie p będzie prawdziwe. (Ostatnie stwierdzenie dotyczace fałszywości zdania g po zakończeniu pętli jest tak oczywistym spostrzeżeniem, że często się onim zapomina. Jednak, jak pokażemy w przykładach, dostarcza ono ważnych informacji 3
pozwalajacych uzasadnić poprawność semantyczna algorytmów i dlatego zostało ono zamieszczone w treści twierdzenia.) Uwaga: Należy pamiętać, że stwierdzenie, iż zdanie p jest niezmiennikiem pętli (P ) nie pozwala jeszcze skorzystać z twierdzenia o niezmiennikach, a założenie prawdziwości zdania p przed wejściem w pętlę jest bardzo istotne i nie może zostać pominięte. Ilustruje to prosty przykład: k := 4 while k 4 do k := k +1. Rozważmy zdanie p : 5 k <k!. Oczywiście p nie jest prawdziwe przed wejściem w pętlę, gdyż 5 4 > 4!. Zauważmy teraz, że p : 5 k < k! jest niezmiennikiem tej pętli. Istotnie; zakładajac, że 5 k <k! i k 4 możemy uzyskać 5 k+1 < 5 k! (k +1) k! =(k +1)!. Jednak, jak łatwo obliczyć, p nie jest prawdziwe również po pierwszym wykonaniu poleceń pętli, co oznacza, że w tym przypadku pierwsza część tezy twierdzenia 3 nie zachodzi. 1.2 Algorytm NWD Euklidesa Jako ilustrację zastosowania pojęcia niezmiennika pętli zaprezentujemy dowód poprawności semantycznej algorytmu Euklidesa znajdowania największego wspólnego dzielnika dwóch liczb całkowitych. Przypomnijmy treść algorytmu: ENWD(n,m) Dane wejściowe: m,n (dwie liczby naturalne) Dane wyjściowe: nwd (liczba naturalna) begin a:=max(n,m); b:=min(n,m); r:=1;{reszta} while r>0 do begin r:=a mod b; a:=b; b:=r; end; 4
end nwd:=a; Jak szukać niezmiennika pętli? (Przez NWD(m, n) oznaczać będziemy liczbę będac a największym wspólnym dzielnikiem liczb n i m).zauważmy najpierw, że naszym zadaniem jest pokazanie, iż nwd = NWD(m, n). (1) Oczywiste jest, że nwd = NWD(nwd, 0) i jednocześnie, po wyjściu z pętli nwd przyjmuje wartość zmiennej a, b =0 istad nwd = a = NWD(a, 0) = NWD(a, b). Zatem wystarczy wykazać, że po zakończeniu pętli zachodzi równość NWD(a, b) =NWD(m, n). (2) Przed wejściem w pętlę, wobec dokonanych podstawień, zależność ta jest prawdziwa. Jeśli teraz zdołamy pokazać, że zadanie (2) jest niezmiennikiem rozważaniej pętli, to z twierdzenia 3 uzyskamy żadany wniosek: (1). W tym celu zauważmy, że w każdym przebiegu pętli zmienne a i b sa zastępowane przez: odpowiednio b oraz a mod b. Wobec tego w poniższym lemacie wykażemy, iż NWD(a,b)=NWD(b,a mod b). Lemat 4. Jeślimins a liczbami całkowitymi i n 6= 0, to wspólne dzielniki liczbnims a takie same jak liczb n i m mod n. Zatem NWD(m,n)=NWD(n,m mod n). Dowód: Skorzystajmy z zależności m = n(m divn)+mmodn. (3) Jeśli n immodnsa wielokrotnościami d, to również m jest wiekrotnościad, ponieważ zarówno n(m div n), jak i m mod n sa podzielne przez d. I odwrotnie jeślimins a wiekrotnościami pewnej liczby całkowitej e, to z uwagi na (3) stwierdzamy, że m mod n jest również wielokrotnościae.st ad liczby m i n oraz nimmodnmaj a te same zbiory wspólnych dzielników, i dalej, ich największe wspólne dzielniki sa równe. Lemat 5. Zdanie NWD(m, n) =NWD(a, b) jest niezmiennikiem pętli while w algorytmie Euklidesa. Dowód: Załóżmy, że zdanie NWD(m, n) =NWD(a, b) jest prawdziwe zamin wykonamy polecenia zawarte w treści rozważanej pętli oraz, że r>0. Mamy wykazać, że pozostaje ono prawdziwe, gdy dokonamy podstawień r:=a modb,a:=bib:=r,tzn.musimywykazaćnastępujac a równość: NWD(m, n) =NWD(b, a mod b). 5
Na mocy lematu 4. otrzymujemy co należało pokazać. NWD(b, a mod b) =NWD(a, b) =NWD(m, n) Twierdzenie 6. Algorytm ENWD wykonuje co najwyżej 2lg(n+m) przebiegów pętli i wyznacza największy wspólny dzielnik danych liczb całkowitych n i m. Dowód: Wyznaczymy najpierw możliwie najlepsze oszacowanie górne liczby operacji dominujacych. Zauważmy, że liczba wykonań instrukcji iteracyjnej jest równa liczbie wykonań wiersza 6 zawierajacego obliczanie reszty z dzielenia liczb a przez b, które to działanie uznamy za operacjędominuj acawpowyższym algorytmie. Oczywiście liczba wykonań pętli jest skończona. Wynika to z faktu, iżwpętli "while " r jest zastępowane przez r mod a dopóty, dopóki r>0. Zatem nowa wartość r jest liczbanieujemn a, mniejszaniż poprzednia. Kolejne wartości zmiennej r tworzaci ag malejacy liczb całkowitych nieujemnych. Zatem, wobec postaci tego ciagu, stwierdzamy, że r osiagnie wartość 0 i algorytm zatrzyma się. Oznaczmy przez L liczbę przebiegów pętli. Aby wyznaczyć L należy pomocniczo udowodnić, że suma a + b zmniejsza się doconajwyżej 2 3 swojej poprzedniej wartości przy każdym przebiegu pętli. Oznacza to, że dla dowonych liczb naturalnych a, b gdzie a b mamy Istotnie, zapiszmy nieróność (2) następujaco: b + a mod b< 2 (a + b). (4) 3 3b +3(a mod b) < 2a +2b lub równoważnie: b +3(a mod b) < 2a. Jednocześnie wiemy, że Dwie ostatnie relacje daja: a = b(a divb)+a mod b. b +3(a mod b) < 2b(a divb)+2(a mod b) idalej b +(a mod b) < 2b(a divb). 6
Wszystkie powyższe przekształcenia sa równoważne zatem, aby wykazać (2), wystarczy udowodnić ostatniazależność. Ponieważ a b, otrzymujemy a div b 1. Stad, nierówność a mod b < b implikuje b +(amod b) < 2b 1 2b(a divb), co należało pokazać. Stosujac zasadę indukcji matematycznej zupełnej, nierówność (2) pozwala udowonić następujacy fakt: µ k 2 a k + b k (m + n) (5) 3 dla dowolnych k =0, 1,...L,gdziea k,b k oznaczaja wartości liczb odpowiednio a i b po k. przebiegu pętli "while. (Dowód tej nierówności pozostawiamy do samodzielnego wykonania - patrz zadanie 4). Zauważmy teraz, że na mocy zależności (5) i nierówności 1+0 a + b, mamy µ L 2 1 (m + n) 3 po ostatnim - L. wykonaniu instrukcji a mod b, co daje µ L 3 m + n. 2 Logarytmujac obie strony uzyskujemy µ 3 lg(m + n) L lg L(lg 3 1) ¼ L(0, 585) > 1 2 2 L, gdzie lg x =log 2 x. Ostatecznie L 2 lg(m + n). Dowiedziemy teraz poprawności algorytmu. Jak zauważyliśmy, wobec podstawień poczatkowych ( a := max(n, m); b := min(n, m) ) zdanie NWD(m, n) = NWD(a, b) jest prawdziwe przed wejściem w rozważanapętlę "while". Jednocześnie ostatni lemat zapewnia, że jest ono jej niezmiennikiem. Wobec tego, korzystajac z twierdzenia o niezmiennikach pętli, orzekamy, iż zdanie to pozostaje prawdziwe po wyjściu z pętli i r =0 (a stad także b =0). Wówczas co było do okazania. nwd = NWD(nwd, 0) = NWD(a, b) =NWD(m, n), 7
Własność 1. Własność 2. 1.3 Wyszukiwanie w tekście maksymalnych prefiksów Podamy teraz kolejny przykład zastowsowania twierdzenia o niezmiennikach do badania poprawności algorytmu. Rozważać będziemy jeden z algorytmów rozwiazywania problemu wyszukiwania maksymalnych prefiksów. Rozpoczniemy od sformułowania problemu. Dana jest tablica A :array [1..n] of Char. Naszym zadaniem jest wyznaczenie dla dowolnego i 2f1, 2,..., ng maksymalnej wartości t sposród tych wszystkich liczb naturalnych t 2f1, 2,..., i 1g, dla których teksty A[1]A[2]...A[t] (zwany prefiksem całego tekstu A )ia[i t +1]A[i t +2]A[i t +3]...A[i] (będacy końcowym segmentem tekstu A obciętego do i. znaku) satakiesame,tj.dla każdego i 2f1, 2,..., ng należy wyznaczyć wartość funkcji g : f1, 2,..., ng! f0, 1,..., ng danej następujacym wzorem g(i) =maxg(i), dla każdego i 2f1, 2,..., ng, (6) gdzie G(i) =ft 2f0, 1,..., i 1g; 8 A[u] =A[i t + u]g. (7) u2f1;:::;tg Dodatkowo przyjmujemy G(0) :=. Zauważmy, że funkcja g jest poprawnie określona, gdyż dla dowolnego i 2 f1, 2,..., ng zbiór G(i) 6=. W istocie tak jest, ponieważ dlakażdego i 2 f1, 2,..., ng, 0 2 G(i), co wynika z faktu, iż 8 A[u] =A[i t + u], 8 (1 u t ) A[u] =A[i t + u]). 1 u t^u2n u2n (Zatem dla t =0 poprzednik implikacji po prawej stronie równoważności jest fałszywy zatem cała implikacja jest prawdziwa). Podamy teraz podstawowe własności funkcjig g(i) < i dla każdego i 2f1,...ng. dla każdego i 2f0, 1, 2,..., n 1g G(i +1)=f0g[ft +1;t 2 G(i) ^ A[i +1]=A[t +1]g. Dowód. Wykażemy dwie imlikacje. ( ¾ ) Oczywiście 0 2 G(i + 1). Jeśli teraz t 2 G(i)^A[i+1] = A[t+1]g, to z definicji (6) t+1 2 G(i+1). ("½ ") Z drugiej strony, gdy t 2 G(i +1) i t 6= 0, to A[i +1]=A[t] i t 1 2 G(i). Istotnie, t 2 G(i +1), µ 0 t<i+1^ 8 A[u] =A[i +1 t + u]g u2f1;:::;tg 8
Własność 3. µ, 0 t<i+1^a[t] =A[i +1]^ 8 A[u] =A[i (t 1) + u] u2f1;:::;t 1g, (A[t] =A[i +1]^ t 1 2 G(i)). Zauważmy teraz, że Własność 2 pozwala wyznaczyć wartość g(i +1) jako maksimum z 0 i wszystkich tych elementów t zbioru G(i), które spełniaja równość A[t +1] = A[i +1]. Fakt ten zapiszemy w postaci następujacej własności: (wniosek z Własności 2) Dla dowolnego i =0, 1,...n 1 zachodzi wzór g(i +1)=max(f0g, ft +1,t2 G(i) ^ A[t +1]=A[i +1]g). Własność 4. Dla dowolnego i =1,...n zachodzi równość G(i) =fg(i)g[g(g(i)). (8) Dowód. Niech i będzie dowolnym, ustalonym elementem zbioru f1, 2,..., ng. Zauważmy, że jeżeli g(i) =0, to (8) jest oczywista. Rozważymy zatem przypadek, gdy g(i) > 0. Z definicji zbioru G(i) wynika relacja g(i) 2 G(i), i dalej 8 A[w] =A[i g(i)+w]. (9) w2f1;:::;g(i)g Załóżmy, że t 6= g(i) oraz t 2 G(i), co jest równoważne 8 A[u] =A[i t + u], (10) u2f1;:::;tg Zdefinicji funkcji g, g(i) jest maksymalnym elementem spośród wszystkich elemetów zbioru G(i), zatem, wobec założenia t 6= g(i), mamy t < g(i). Z (10), (9) oraz ostaniej nierówności otrzymujemy dla dowolnego u 2f1, 2,..., tg A[u] =A[i t + u] =A[(i g(i)) + (g(i) t + u)] = A[g(i) t + u]. Stad stwierdzamy, że t 2 G(g(i)), tj. G(i) ½fg(i)g [G(g(i)). Należy teraz wykazać inkluzję w druga stronę: G(i) ¾fg(i)g [G(g(i)). Ze względu na definicję g, wystarczy dowieść, że G(i) ¾ G(g(i)). Załóżmy więc, że t 2 G(g(i)), co oznacza 8 A[u] =A[g(i) t + u]. u2f1;:::;tg 9
Zatem dla dowolnego u 2f1, 2,..., tg mamy A[u] =A[g(i) t + u] =A[(i g(i)) + (g(i) t + u)] = A[i t + u], czyli t 2 G(i). Twierdzenie 7. Dla dowolnego i 2f1,..., ng zachodzi następujacy wzór rekurencyjny 8 >< g k (i 1) + 1, g(i) = >: 0 g(1) = 0 gdzie k =minfl; g l (i 1) jest określone i A[i] =A[g l (i 1) + 1]g, jeśli nie istnieje liczba naturalna k opowyższej własności. Dowód. Oczywiście pierwsza równość wynika wprost z własności 1. Z własnosci 4 uzyskujemy: G(i) =fg k (i), k 1 ig k (i) jest określone}. Zatem, wykarzystujac własność 3mamydlai 2f0, 1,..., n 1g g(i +1)=max(f0g, fg k (i)+1,k 1 ^ A[g k (i)+1]=a[i +1]g). Jednocześnie z własnosci 1 wynika, że jeśli g k (i) jest określone, to g(i), g 2 (i),...,g k (i) tworzaci ag malejacy. Fakt ten oraz ostatnia równość implikuja powyższy wzór rekurencyjny. Przedstawimy teraz algorym, rozwiazuj acy nasz problem, czyli obliczajacy funkcję g : Procedure PRM Dane wejściowe: liczba naturalna n 1, A : array [1..n] of char - tekst, w którym wyszukujemy maksymalnego prefiksu. Dane wyjśćiowe: P : array [1..n] of integer - wartość funkcji g. var i, j, k : integer ; begin 1:j := 0; P [1] := 0; i := 2; 2: while i n do begin k := 1; 3: while (j > 0 ^ A[i] 6= A[j + 1]) do begin j := P [j]; k := k +1; end; 4: if A[j +1]=A[i] then 10
5: end; 6: end. begin j := j +1; P [i] :=j; end else P [i] :=0; i := i :+1, Twierdzenie 8. Algorytm PRM jest częściowo poprawny względem warunku poczatkowego α : n 1 i warunku końcowego β : 8 P [i] =g(i). i2f1;:::;ng Zanim przejdziemy do dowodu twierdzenia wykarzemy dwa pomocnicze fakty dotyczace własności wewnętrznej pętli while. Lemat 9. Zdanie γ 3 : 8 P [s] =g(s) ^ n i 2 ^ k 1 ^ j = s2f1;:::;i 1g gk (i 1) 8 u2f1;:::;k 1g (gu (i 1) > 0 ^ A[i] 6= A[g u (i 1) + 1]) jest niezmiennikiem wewnętrznej pętli while. Dowód. Załóżmy, że prawdziwe sa zdania: γ 3 oraz warunek dozoru (j >0 ^ A[i] 6= A[j +1]). W wyniku wykonania poleceńtreści pętli, zmienne j oraz k przybieraja nowe wartości j 1 = P [j] i k 1 = k +1. Na poczatku zauważmy, że 2 pierwsze czynniki koniunkcji γ 3, tj. warunki 8 P [s] =g(s) ^ n i 2 s2f1;:::;i 1g saspełnione z założenia. Oczywiste jest także, iż k 1 1. Dalej zauważmy, że j 1 = P [j],zaś j = g k (i 1) <i 1, awięc g(j) =P [j], zatem j 1 = P [j] =g(j) =g(g k (i 1)) = g k+1 (i 1) = g k 1 (i 1). Wykorzystuj ac teraz zależność j = g k (i 1) oraz warunek dozoru pętli, stwierdzamy natychmiast, iż g k1 1 (i 1) > 0 i A[i] 6= A[g k1 1 (i 1)+1], co wobec założonej prawdziwości γ 3 przed wykonanim treści pętli 8 u2f1;:::;k 1 1g (gu (i 1) > 0 ^ A[i] 6= A[g u (i 1) + 1]). Wykazaliśmy zatem, iż γ 3 pozostaje prawdziwe po wyknaniu poleceń treści pętli, a zatem jest niezmiennikiem pętli while. Lemat 10. Dla każdego i 2f2,..., ng, zachodzi następujaca implikacja: jeżeli γ 3 jest prawdziwe przed wejściem w wewnętrznapętlę while, to jest ona wykonywana nie więcej niż g(i 1) g(i)+2 razy. Dowód. Niech i będzie ustalonym elementem zbioru i 2f2,..., ng. Ponieważ liczba przebiegów pętli jest o jeden większa od k, zatem wystarczy pokazać, że 11
można wartość tej zmiennej oszacować z góry. Z założenia, że γ 3 jest prawdziwe przed wejściem w wewnętrzna pętlę while ifaktu,iż jest ono jej niezmiennikiem (Lemat 9), wnosimy, na mocy twierdzenia o niezmiennikach pętli, że jest ono prawdziwe pokażdej jej iteracji. Zatem j = g k (i 1) 0. Ponieważ dlakażdego l =1, 2,..., n, g(l) l 1, więc g k (i 1) g k 1 (i 1) 1 g k 2 (i 1) 2... g(i 1) (k 1). (11) Na mocy twierdzenia 1 i (11), mamy [g(i) g k (i 1) + 1 g(i 1) k +2], k g(i 1) g(i)+2. Dowód twierdzenia 8. Załóżmy, że spełniony jest warunek α. Pokażemy, że zdanie γ 2 : 8 P [s] =g(s) ^ n +1 i 2 ^ j = g(i 1) s2f1;:::;i 1g jest niezmiennikiem wewnętrznej pętli while. Zakładamy więc, że γ 2 jest prawdziwe oraz i n. Należy wykazać, że dla nowych wartości j 1 oraz i 1 zachodzi 8 1 2 ^ j 1 = g(i 1 1). s2f1;:::;i 1 1g (12) Założenie nasze gwarantuje prawdziwość czterech pierwszych czynników w warunku γ 3. Oczywiście ostatni czynnik jest również prawdziwy, gdyż wtym momencie k =1. Ponieważ γ 3 jest niezmiennikiem wewnętrznej pętli while (lemat 9), która wykonywana jest skończona liczbę razy (lemat 10), stwierdzamy, że po zakończeniu działania pętli γ 3 pozostaje prawdziwe oraz, że j 0 _ A[i] =A[j +1]. Wykażemy teraz, że zachodzi (g k (i 1) = 0 _ A[i] =A[g k (i 1) + 1]). (13) Rozważmy najpierw sytuację, gdy j 0. Wówczas, z prawdziwości warunku γ 3 stwierdzamy, iż j = g k (i 1), aponieważ g przyjmuje tylko wartości nieujemne, mamy g k (i 1) = 0, co implikuje prawdziwość zdania (13). Zajmijmy się teraz przypadkiem, gdy A[i] =A[j +1]. Podobnie jak poprzednio, równość j = g k (i 1) daje A[i] =A[g k (i 1) + 1]), i dalej prawdziwość (13). Dowiedliśmy zatem warunku γ 4 : γ 3 ^ (g k (i 1) = 0 _ A[i] =A[g k (i 1) + 1]). 12
Naszym zadaniem jest zbadanie instrukcji if-else. Korzystajac z twierdzenia 1 mamy, że jeżeli równość A[i] =A[g k (i 1)+1] zachodzi, to g(i) =g k (i 1)+1, w przeciwnym przypadku g(i) =0. Z drugiej strony, gdy A[i] =A[j +1], to zmienne j oraz P [i] przybieraja nowe wartości j 1 = j +1 oraz P [i] =j 1. Ponieważ zprawdziwości γ 3, j = g k (i 1), więc P [i] =g k (i 1) + 1 = g(i). Jeżeli zaś warunek zawarty w instrukcji if nie zachodzi, to j 1 = j i P [i] =0=g(i). Na koniec oznaczmy i 1 = i +1. Podsumowujac, wykazaliśmy P [i 1 1] = g(i 1 1) ^ n +1 i 1 2 ^ j 1 = g(i 1 1), co wobec założenia, daje (12), tj. γ 2 jest niezmiennkiem zewnętrznej pętli while. Ponieważ jednocześnie γ 2 jest prawdziwe przed wejściem w tę pętlę (wówczas zmienne przybierajanastępuj ace wartości: n 1, j = 0, P[1] = 0, i = 2, stad P [1] = 0 = g(1) = j), twierdzenie o niezmiennikach pozwala orzec, iż zdanie to pozostaje prawdziwe po zakończeniu jej działania, tj. zachodzi warunek β. 2 Bibliografia 1. Banachowski L., Kreczmar A., Elementy analizy algorytmów, Wydawnictwo Naukowo-Techniczne, Warszawa 1982. 2. Manber U., Introduction to Algorithms, Addison-Wesley Publishing Company, New York, 1989. 3. Ross K.A., Wright Ch.R.B., Matematyka dyskretna, Wydawnictwo Naukowe PWN, Warszawa 2000. 13