Lista 1 - Instytut Sterowania i Systemów Informatycznych

Transkrypt

Lista 1 - Instytut Sterowania i Systemów Informatycznych
Uniwersytet Zielonogórski
Instytut Sterowania i Systemów Informatycznych
Teoretyczne Podstawy Informatyki
Lista 1 – Poprawność algorytmów1
1
Wprowadzenie
Metoda niezmienników to jedna z najbardziej popularnych metod sprawdzania poprawności algorytmów. Jest
ona stałym elementem wielu programów, gdzie objawia się stosowaniem asercji, czyli warunków które powodują
zatrzymanie się programu w przypadku, jeśli warunek nie jest spełniony.
Definicja 1 Asercją nazywamy trójkę {p}code{q}, gdzie code jest programem natomiast p i q są formułami
rachunku predykatów, nazywane warunkiem wstępnym oraz warunkiem końcowym.
Warunki te są sprawdzane w czasie wykonywania się programu (ang. run-time).
Poprawność danego algorytmu A względem dwóch warunków, początkowego oznaczanego często też przez
α oraz końcowego β, zazwyczaj dowodzi się przez wykazanie, że algorytm A posiada trzy własności:
1. dla każdych danych wejściowych spełniających warunek początkowy α jeżeli obliczenie algorytmu A dochodzi do punktu końcowego, to otrzymane wyniki spełniają warunek końcowy β
2. dla każdych danych wejściowych spełniających warunek początkowy α obliczenie algorytmu A nie jest
przerwane
3. dla każdych danych wejściowych spełniających warunek początkowy α obliczenie algorytmu A nie jest
nieskończone
O algorytmie A powiemy, że jest częściowo poprawny względem warunku początkowego i końcowego jeśli
zachodzi warunek (1). Gdy zachodzi warunek (2) to algorytm A posiada własność określoności obliczeń. Ostatni
warunek (3) decyduje o tym, czy dany algorytm A posiada własność stopu względem warunku początkowego α.
Definicja 2 Jeżeli |= {p}code{q}, to program code jest częściowo poprawny względem p i q.
Zasadniczym pojęciem w przypadku poprawności jest niezmiennik pętli. Niezmiennik jest prawdziwy przed
wejściem do pętli, pozostaje prawdziwy w trakcie działanie pętli oraz jest prawdziwy po jej zakończeniu.
Twierdzenie 1 (O niezmienniku pętli)
Przypuśćmy, że p jest niezmiennikiem pętli „while w do code” oraz że zdanie p jest prawdziwe, kiedy wykonuje
się treść pętli. W takim przypadku zdanie p jest prawdziwe po każdej iteracji pętli. Gdy pętla, kończy swoje
działanie, to po jej zakończeniu zdanie p jest prawdziwe, a zdanie w jest fałszywe.
Algorytm dzielenia całkowitego to znakomity przykład, aby zaprezentować sposób dowodzenia metodą niezmienników częściowej poprawności algorytmu oraz jego określoności. Sam algorytm dzielenia można zapisać w
następujący sposób:
procedure i n t d i v ( x , y : integer ; var q , r : integer ) ;
begin { warunek α : 0 ¬ x ∧ 0 ¬ y }
q : = 0 ; r :=x ;
while y ¬ r do
begin
q:=q+ 1 ;
r := r −y ;
end ;
{ warunek β : x := qy + r ∧ 0 ¬ r < y }
end ;
1 Opracowano
na podstawie pozycji wymienionych w literaturze. by M.S. lipiec,sierpień 2005.
1
Twierdzenie 2 Algorytm dzielenia całkowitego jest częściowo poprawny.
Dowód
W algorytmie jawnie zostały wskazane dwa warunki, na początku procedury (oznaczony jako warunek α) oraz
na końcu procedury (oznaczony jako warunek β). W analizie poprawności brać pod uwagę będziemy także
warunek znajdujący w pętli: y ¬ r.
Wiadomo, że jeśli pętla rozpocznie swoje działanie to spełniony jest warunek α. Głównym zadaniem jest
wykazanie, że jeśli pętla zakończy swoje działanie to prawdziwy będzie warunek końcowy β. W tym celu należy
zbudować dodatkowy warunek γ, który będzie prawdziwy przez cały proces obliczeń w pętli. Tworząc ten
warunek należy wykorzystać końcową informację o wartości jaka ma zostać ostatecznie obliczona w algorytmie.
Każda iteracja pętli może być iteracją ostatnią, więc warunek γ powinnień posiadać następującą postać:
γ : x := qy + r ∧ 0 ¬ r ∧ 0 ¬ y
Teraz po określeniu postaci γ łatwo wykazać, że jeśli algorytm rozpoczyna się przy stanie spełniającym α zawsze
dojdzie do pętli. Przypisanie wartości w zmiennych q oraz r spełniają utworzony przez nas warunek.
Dalsza analiza dotyczy samej pętli, jeśli warunek pętli dopóki jest spełniony to wykonywane są dwa przypi0
sania. Zmiennej q nadawana jest nowa wartość o postaci q = q +1 natomiast drugie przypisanie zmienia wartość
0
zmiennej r w następujący sposób: r = r − y. Najważniejszym elementem jest sprawdzenie, czy po podstawieniu
nowych wartości do γ otrzymane wartości nadal spełniają narzucone wcześniej ograniczenia:
0
0
0
0
0
γ(x, y, q , r ) ≡ x = q y + r ∧ 0 ¬ r ∧ 0 ¬ y ≡ x = (q + 1)y + (r − y) ∧ 0 ¬ r − y ∧ 0 ¬ y ,
ostatecznie po elementarnych przekształceniach otrzymamy:
x = qy + r ∧ 0 ¬ r − y ∧ 0 ¬ y .
Jak widać wartość x spełnia wcześniejsze założenia γ. Również prawdziwy jest warunek 0 ¬ r − y ponieważ
zapewnia to warunek pętli: y ¬ r. Również prawdziwy jest trzeci składnik, ponieważ wartość zmiennej y nie
jest zmieniana w badanej pętli. Można teraz ponownie wykonać kolejną iterację, aby przekonać się, że warunki
nadal będą prawdzie czyli inaczej mówiąc zastosować indukcję przy założeniu y ¬ r aby otrzymać, że warunek
γ zawsze jest spełniony.
Jeśli, warunek pętli przestanie być spełniony to pętla zakończy swoje działanie co pociągnie za sobą prawdziwość faktu iż y > r co naturalnie oznacza, że stan algorytmu spełnia ostatni warunek β. 1.1
Własność stopu algorytmów
W analogiczny sposób jak w przypadku niezmienników można dowodzić własność stopu algorytmów dwoma
metodami: metodą liczników iteracji oraz metodą malejących wielkości.
Rozpatrujemy algorytm A o ogólnej postaci (postaci pierwotnej):
while γ do K
Zestaw instrukcji K będziemy także nazywać algorytmem. Aby rozpatrywać własność stopu do algorytmu wprowadzamy dodatkową zmienną l, która nie jest w żaden sposób związana z przedstawionym powyżej schematem.
Wartość zmiennej l przed właściwym algorytmem przyjmuje zazwyczaj wartość 0 bądź 1. Uzyskujemy w ten
sposób rozszerzoną postać algorytmu A:
{α}
l :=0|1;
while γ do
begin
K;
l := l +1;
end ;
{β }
Idea dowodu polega na tym, aby wyznaczyć wyrażenie arytmetyczne τ , którego wielkość w trakcie realizacji
rozszerzonego algorytmu A ograniczałaby wartość zmiennej l. Oczywiście wartości w warunku τ nie są zmieniane
w wyrażeniu K; l := l + 1;. Określamy także warunek δ analogicznie jak przy metodzie niezmienników, który
łączy w sobie zależności pomiędzy zmiennymi podczas sprawdzania warunku pętli γ. Wobec tych postanowień
zachodzi następujące twierdzenie:
2
Twierdzenie 3 (O liczniku iteracji)
Jeśli następujące warunki są spełnione:
1. warunek δ ∧ τ ­ l jest w algorytmie A niezmiennikiem instrukcji iteracyjnej while przy warunku początkowym α
2. algorytm K ma własność stopu względem warunku δ ∧ γ.
Rozszerzony algorytm A i jego wersja pierwotna mają własność stopu względem warunku początkowego α.
Dowodzenie warunku stopu w przytoczonym twierdzeniu polega na wykazaniu, iż licznik iteracji jest ograniczony
przez pewną wielkość. Każda iteracja powinna zwiększać ów licznik, a po osiągnięciu przewidzianej wielkości
algorytm skończy swoje działanie. Wskazana własność pozwala na podanie poniższego lematu:
Lemat 1 Konstrukcja pętli o postaci:
for i := v to w do K ;
zawsze posiada własności stopu pod warunkiem, że zmienna i nie jest modyfikowana przez program K.
Zamiast dowodzenia wzrostu pewnej wielkości można również dowodzić własność stopu dla licznika który
zmniejsza swoją wartość. Wymaga to zmiany rozszerzonej postaci algorytmu A. Przedstawia się on tym razem
w następującej postaci:
{α}
i :=w+1;
while γ do
begin
i :=w ;
K;
end ;
{β }
Podobnie jak poprzedniej technice tworzymy warunek δ. Twierdzenie przyjmuje następującą postać:
Twierdzenie 4 (O malejących wartościach)
Jeżeli spełnione są poniższe warunki:
1. warunek δ ∧ i > w ∧ w ­ 0 jest niezmiennikiem instrukcji iteracyjnej while przy zadanym warunku
początkowym α
2. algorytm A ma własność stopu względem warunku początkowego δ ∧ γ
Obie postaci algorytmu A mają własność stopu względem warunku początkowego α.
Zastosowanie pierwszego twierdzenia zostanie zaprezentowany na algorytmie dzielenia:
procedure i n t d i v ( x , y : integer ; var q , r : integer ) ;
begin { warunek α : x ­ 0 ∧ y > 0 }
q : = 0 ; r :=x ;
while r ­ y do
begin
q:=q+ 1 ;
r := r −y ;
end ;
{ warunek β : x := qy + r ∧ 0 ¬ r < y }
end ;
Twierdzenie 5 Algorytm dzielenia całkowitego posiada własność stopu.
Dowód
Względem poprzedniej wersji algorytm różni się on tylko istotną zmianą w postaci warunku początkowego.
Algorytm możemy wykorzystać do wykazania własności stopu bez żadnych zmian ponieważ rolę licznika iteracji
pełni zmienna q. Warunek τ ma postać: τ : x/y, natomiast druga część niezmiennika jest w postaci δ : x =
3
qy + r ∧ r ­ 0 ∧ x ­ 0 ∧ y > 0. Innymi słowy należy wykazać, że warunek z twierdzenia o zmienionej postaci
(prawa część koniunkcji zmieniona miejscami i zmieniony znak), bo δ ∧ q ¬ x/y jest niezmiennikiem instrukcji
pętli. W pierwszej kolejności sprawdzimy, czy prawdziwy jest warunek δ, a potem prawa część koniunkcji, czyli
q ¬ x/y. Warunek ten zachodzi naturalnie przed pętla, ponieważ przypisanie zera do zmiennej q powoduje, że
wartość δ na pewno jest mniejsza niż x/y.
0
Sprawdźmy teraz w jaki sposób zachowuje się warunek w pętli po przypisaniu nowych wartości q = q + 1 i
0
r = r − y:
(x = qy + r ∧ r ­ 0 ∧ x ­ 0 ∧ y > 0) ≡ (x = (q + 1)y + (r − y)) ∧ r ­ 0 ∧ x ­ 0 ∧ y > 0)
po kilku przekształceniach otrzymamy:
(x = qy + r ∧ r ­ 0 ∧ x ­ 0 ∧ y > 0)
W ten sposób dowiedzieliśmy, że pętla przy każdej iteracji spełnia warunek δ. Należy teraz pokazać, że nierówność
q ¬ x/y wynika z warunku δ. Należy bowiem x = qy + r podzielić przez y, a następnie uporządkować wyrażenie
do postaci:
q = x/y − r/y
Ponieważ z warunku δ wiemy, że r ­ 0 oraz y > 0 to q ¬ x/y, ponieważ po podstawieniu w miejsce q wyrażenia
x/y − r/y oraz uporządkowaniu otrzymamy:
x/y ¬ x/y + r/y
W ten sposób pokazaliśmy ograniczenie na wielkość q która określa też maksymalną ilość iteracji jak zostanie
wykonana przez algorytm. 1.2
Najsłabszy warunek wstępny
Podczas określania postaci warunków w technice niezmienników należy dobierać w miarę możliwości jak najbardziej ogólne postaci warunków. Bardzo często tego rodzaju warunek nazywa się najsłabszym warunkiem
wstępnym (w skrócie nww). Następująca definicja określa nam najsłabszą formułę w rozpatrywanym w danym
momencie zbiorze formuł:
Definicja 3 Formuła A jest słabsza od formuły B, jeśli B → A. Dla danego zbioru formuł {A1 , A2 , . . .} formuła
Ai , jest najsłabszą formułą tego zbioru, jeśli Aj → Ai dla każdego j.
Najsłabszy warunek wstępny jest bardzo przydatny w procesie określenia asercji dla instrukcji bądź zbioru
instrukcji S.
Definicja 4 Niech będzie danych program S oraz formuła q, najsłabszym warunkiem wstępnym S oraz q nazwiemy taką formułę p dla której zachodzi |= {p}S{q}. Co oznaczymy jako nww(S, q).
O czym mówi również poniższy lemat:
Lemat 2 |= {p}S{q} wtedy i tylko wtedy, gdy |= p → nww(S, q)
Najsłabszy warunek przydaje się do wyznaczania niezmienników bądź warunków wstępnych. Można je stosować do wszystkich podstawowych instrukcji jak przypisanie, pętla while, instrukcja warunkowa.
Definicja 5 (Przypisanie)
nww(x := t, p(x)) = p(x){x ← t}
Definicja 6 (Sekwencja)
nww(S1 ; S2 , q) = nww(S1 , nww(S2 , q))
Definicja 7 (Druga definicja o niezmienniku)
N nazwiemy niezmiennikiem wtedy i tylko wtedy, gdy nww(S, N ) = N
Definicja 8 (O instrukcji warunkowej)
nww(if W then S1 else S2 , q) = (W → nww(S1 , q)) ∧ (¬W → nww(S2 , q))
lub
nww(if W then S1 else S2 , q) = (W ∧ nww(S1 , q)) ∨ (¬W ∧ nww(S2 , q))
4
Definicja 9 (O pętli dopóki)
nww(while W do S, q) = (¬W → q) ∧ (W → nww(S; while W do S, q))
lub
nww(while W do S, q) = (¬W ∧ q) ∨ (W ∧ nww(S; while W do S, q))
Poniższe twierdzenie jest użyteczne do łączenie warunków podczas wyprowadzania najsłabszego warunku wstępnego dla pętli oraz instrukcji warunkowej.
Twierdzenie 6 (O rozdzielaniu nww)
|= nww(S, p) ∧ nww(S, q) ⇔ nww(S, p ∧ q)
Dla definicji nww dla instrukcji warunkowej oraz pętli alternatywna wersja reguły wynika z równoważności
rachunku zdań: (p → q) ∧ (¬p → r) ≡ (p ∧ q) ∨ (¬p ∧ r). Definicje te są bardzo przydatne podczas wyznaczania
najsłabszego warunku wstępnego, co potwierdzić może następujący przykład związany z instrukcją warunkową:
nww(if y = 0 then x := 0 else x := y + 1, x = y)
= (y = 0 → nww(x := 0, x = y)) ∧ (y 6= 0 → nww(x := y + 1, x = y))
= ((y = 0) → (y = 0)) ∧ ((y 6= 0) → (y + 1 = y))
= true ∧ ((y 6= 0) → f alse)
= ¬(y 6= 0)
= y = 0.
1.3
System dowodzenia HL
System dowodzenia HL (inaczej logika Hoare’a) dość często jest utożsamiany z semantyką aksjomatyczną konstrukcji imperatywnych. Aksjomaty bądź reguły tego systemu można sprowadzić do następującej notacji podstawowej:
{P } code {Q}
Aksjomat przypisania:
` {p(x){x ← t}} x := t {p(x)}
(1)
` {P } code1 {Q}, ` {Q} code2 {R}
` {P } code1 ; code2 {R}
(2)
` {P ∧ B}code1 {Q}, ` {P ∧ (¬B)}code2 {Q}
` {P } if B then code1 else code2 endif {Q}
(3)
` {P ∧ B}code{Q}, ` {P ∧ (¬B)} ⇒ Q
` {P } if B then code endif {Q}
(4)
` {P ∧ B}code{P }
` {P } while {B} do code{(¬B) ∧ P }
(5)
Sekwencja instrukcji (reguła złożenia):
Instrukcja if-else:
Instrukcja if-then:
Opis pętli:
Reguła konsekwencji:
` p1 → p
1.3.1
` {p}code{b} ` b → b1
` {p1 }code{b1 }
(6)
Weryfikacja programów
Zastosowanie systemu HL zostanie ukazane na przykładzie poniższego programu który wyznacza iloczyn dwóch
zmiennych a oraz b.
5
{true}
x :=0;
{x = 0}
y:=b ;
{x = 0 ∧ y = b}
while y 6= 0 do
begin {x = (b − y)a}
x:=x+a ;
y:=y− 1 ;
end ;
{x = ab}
Chcemy udowodnić, że powyższy program P reprezentowany jako sekwencja (cały program powstaje jako wynik
wielokrotnego zastosowania reguły sekwencji):
{p1 }code1 {p2 }code2 . . . {pn }coden {pn+1 }
jest częściowo poprawny. Inaczej mówiąc, chcemy udowodnić poniższe twierdzenie:
Twierdzenie 7 ` {true} P {x = ab}
Dowód
Pierwsza linia programu to przypisanie zera do zmiennej x. Aksjomat przypisania może przyjąć następującą
postać:
{0 = 0}x := 0{x = 0}
Jednakże należy wziąć pod uwagę wartość true, czyli warunek początkowy. Wykorzystać należy regułę konsekwencji, z następującą przesłanką true → (0 = 0). Otrzymamy aksjomat o postaci:
{true}x := 0{x = 0}
Analogicznie postępujemy w przypadku drugiej linii przypisania. Początkowo aksjomat ma postać: {b = b}y :=
b{x = 0 ∧ y = b}. Przesłanka ma postać x = 0 → (b = b), ostatecznie otrzymamy:
{x = 0}y := b{x = 0 ∧ y = b}
Najważniejszym elementem w programie P jest pętla while. Niech p będzie formułą w postaci x = (b − y)a.
Należy teraz wykazać czy p jest niezmiennikiem pętli. Wykorzystamy w tym celu pojęcie najsłabszego warunku
wstępnego. Przedstawia się to następująco:
nww(x := x + a; y := y − 1, x = (b − y)a)
= nww(x := x + a, nww(y := y − 1, x = (b − y)a))
= nww(x := x + a, x = (b − y + 1)a)
= x + a = (b − y + 1)a ≡ x = (b − y)a
Wykazaliśmy, że p jest niezmiennikiem pętli, co pozwala nam na opis całej reguły w następujący sposób:
{p}
while y6= 0 do
begin
x:=x+a ;
y:=y− 1 ;
end ;
{p ∧ ¬(y 6= 0)}
Warunek zakończenia pętli można zapisać także jako p ∧ (y = 0). Wykorzystując regułę konsekwencji a bardziej
bezpośrednio podstawiając wartość y równą zero do niezmiennika pętli otrzymamy końcowy warunek x = ab.
6
2
Indukcja strukturalna
Zasada indukcji matematycznej jest podawana w następującej postaci:
• Zasada indukcji matematycznej: Jeśli dowiedziona zostanie prawdziwość S(i) oraz następnie zostanie
wykazane, że dla dowolnego n ­ i, S(n) implikuje S(n + 1), to można stąd wywnioskować S(n) dla
wszystkich n ­ i.
Dość często dowód przez indukcję można przeprowadzić przy zastosowaniu bardziej ogólnego schematu.
Schemat ten może przyjąć dwa uogólnienia:
1. W podstawie można analizować kilka podstawowych przypadków. Innymi słowy, dowodzimy, że prawdziwe
jest S(i), S(i + 1), . . . , S(j) dla pewnego j > i.
2. Dowodząc prawdziwości S(n + 1), wykorzystywane są wszystkie podstawowe przypadki:
S(i), S(i + 1), . . . , S(n).
Co więcej, jeśli zostały dowiedzione przypadki wejściowe do S(n) włącznie, to zamiast n ­ i można przyjąć
iż n ­ j.
Wnioskiem z podstawy i kroku indukcyjnego jest to, że S(n) jest prawdziwe dla dowolnego n ­ i.
Ogólny schemat indukcji prowadzi do indukcji strukturalnej. Niech S(X) będzie stwierdzeniem dotyczącym
struktur X zdefiniowanych za pomocą pewnej konkretnej definicji rekurencyjnej.
1. Jako podstawy dowodzi się prawdziwości S(X) dla podstawowej struktury bądź struktur X.
2. W kroku indukcyjnym analizowana jest struktura X, która według danej definicji rekurencyjnej została
stworzona ze struktur Y1 , Y2 , . . . , Yk . Zakładamy, że stwierdzenia S(Y1 ), S(Y2 ), . . . , S(Yk ) są prawdziwe i
są stosowane do dowiedzenia prawdziwości S(X).
3
Zadania
Zadania opracowane na podstawie pozycji wymienionych w literaturze.
1. Udowodnić twierdzenie (1).
2. Udowodnić lemat (2).
3. Udowodnić twierdzenie (3).
4. Udowodnić twierdzenie (4).
5. Udowodnić twierdzenie (6).
6. Udowodnić następujące twierdzenie:
Twierdzenie 8 Każde drzewo ma o jeden wierzchołek więcej niż krawędzi.
Przy wykorzystaniu następującej definicji rekurencyjnej:
Podstawa: Pojedynczy wierzchołek jest drzewem, którego korzeniem jest ten wierzchołek.
Krok indukcyjny: Jeśli T1 , T2 , . . . , Tk są drzewami, to możemy utworzyć nowe drzewo w następujący
sposób:
(a) Rozpoczynamy od nowego wierzchołka N , będącego korzeniem tego drzewa.
(b) Dodajemy kopie wszystkich drzew T1 , T2 , . . . , Tk .
(c) Dodajemy krawędzie z wierzchołka N do korzenia każdego z drzew T1 , T2 , . . . , Tk .
7. Udowodnić następujące twierdzenie:
7
Twierdzenie 9 Każde wyrażenie arytmetyczne ma jednakową liczbę prawych i lewych nawiasów.
Przy wykorzystaniu następującej definicji rekurencyjnej:
Podstawa: Liczba bądź litera (a nawet wyraz) reprezentująca zmienną jest wyrażeniem arytmetycznym.
Krok indukcyjny: Jeśli E oraz F są wyrażeniami arytmetycznymi, to są nimi również E + F , E ∗ F ,
E − F , E/F oraz (E).
8. Wykaż, że warunek:
k
X
2i = 2k+1 − 1
i=0
jest niezmiennikiem następującej pętli:
k :=0;
while 0 ¬ k do
begin
Pk
i
k+1
if
− 1 then k:=k+1;
i=0 2 = 2
end ;
9. Wykazać, że podane warunki są niezmiennikami pętli:
while 1 <= n do
begin
m:=m+1;
n:=n+1;
end ;
(a) m + n jest liczbą parzystą
(b) m + n jest liczbą nieparzystą
10. Dysponujemy pętlą:
while j >= n do
begin
i := i +2;
j := j +1;
end ;
Zmienne i, j są liczbami całkowitymi. Czy poniższe warunki są niezmiennikami pętli:
(a) i < j 2 oraz n = 1
(b) i ¬ j 2 oraz n = 0
11. Pokazać częściową poprawność algorytmu dzielenia całkowitego liczb naturalnych.
12. Pokazać, czy dla argumentów x = 0 oraz y = 0 algorytm dzielenia całkowitego liczb naturalnych jest
skończony.
13. Podać jakie własności posiada relacja osiągalności obiektu w liście o następującej definicji:
Definicja 10 Niech obiekty a, d będą obiektami należącymi do jednokierunkowej listy L. Obiekt d nazywamy obiektem osiągalnym z obiektu a tzn. a → d, jeśli następującą pętla dojdzie do punktu końcowego
β:
p := a ;
while p 6= d do
p := p ˆ . n e x t ;
{β : p u n k t końcowy }
8
14. Dysponujemy listą jednokierunkową o elementach pewnego typu T .
(a) zdefiniować funkcję która sprawdzi, czy określony element typu T znajduje się na liście w dwóch
wersjach: dla listy z wartownikiem, dla listy bez wartownika
(b) udowodnić czy zdefiniowane funkcje posiadają własności: poprawności i określoności obliczeń
Wykorzystać relację osiągalności z zadania poprzedniego.
15. Oto algorytm szybkiego podnoszenia liczby do potęgi:
p:=1;
q:=a ;
i :=n ;
while i > 0 do
begin
i f not ( ( i mod 2 ) = 0 ) then p:=p∗q ;
q:=q∗q ;
i := i div 2 ;
end
gdzie a, n ∈ N, a wynikiem jest p = an . Czy warunek q i p = an jest niezmiennikiem oraz czy algorytm po
opuszczeniu pętli daje poprawny wynik p = an ?
16. Udowodnić częściową poprawność poniższego algorytmu który oblicza xn metodą binarną:
var
x , y , z : real ;
m, n : integer ;
begin
read ( x ) ; read ( n ) ;
{ α:n­0 }
z :=x ; y : = 1 ; m:=n ;
repeat {γ : xn = yz m ∧ m ­ 0}
i f odd (m) then y:=y∗ z ;
m:=m div 2 ; z := z ∗ z ;
{γ : xn = yz m ∧ m ­ 0}
until m = 0 ;
write ( y ) ; {β : y = xn }
end ;
17. Udowodnić własność stopu algorytmu dzielenia całkowitego.
18. Wykazać własność stopu za pomocą kryterium malejących wielkości:
{ α : x ¬ 100 }
y:=x ;
z :=1;
while ( y ¬ 1 0 0 ) ∨ ( z 6= 1 ) do
begin
i f y ¬ 100 then
begin
y:=y+ 1 1 ;
z := z+ 1 ;
end
else
begin
y:=y− 1 0 ;
z := z− 1 ;
end ;
end ;
9
19. Wykazać dla algorytmu sortowania przez wstanie o następującej postaci:
const n = i l o ś ć e l e m e n t ó w ;
a : array of [ 0 . . n ] of L ;
{ min −− w a r t o ś ć n a j m n i e j s z a w d z i e d z i e n i e i n t e g e r }
var
i , j : integer ;
v : L;
begin
{ α:n­1 }
f or i :=2 to n do
begin
{ min = a[0] ¬ a[1] ¬ . . . ¬ a[i − 1] }
i f a [ i − 1 ] > a [ i ] then
begin
v:=a [ i ] ;
j := i − 1 ;
repeat
a [ j +1]:= a [ j ] ;
j := j − 1 ;
{ min = a[0] ¬ a[1] ¬ . . . ¬ a[j] ∧ v ¬ a[j + 2] ¬ . . . ¬ a[i] }
until a [ j ] ¬ v ;
a [ j +1]:= v ;
{min = a[0] ¬ a[1] ¬ . . . ¬ a[i]}
end ;
{β : a[1] ¬ a[2] ¬ . . . ¬ a[n]}
end ;
(a) częściową poprawność
(b) własność stopu
20. Wykazać własność stopu dla algorytmu member:
{ α : head 6= nil ∧ sentinel 6= nil ∧ head → sentinel }
p:= head ;
s e n t i n e l ˆ . a:=x ;
i :=0;
while p ˆ . a 6= x do
begin
p:=p ˆ . next ;
i := i +1;
end ;
21. Podać możliwe warunki wstępne oraz wskazać nww dla następujących wyrażeń:
(a) x := 2y + 1 {(x ¬ 7) ∧ (y ¬ 3)}
(b) x := 2y + 1 {(x ¬ 7) ∧ (y ¬ 3) ∧ (x + y) ­ 10)}
(c) y := y − 1 {(y ­ 0)}
22. Dokonać formalnej weryfikacji częściowej poprawności dla następującego programu:
{true}
x :=0;
{x = 0}
y:=b ;
{x = 0 ∧ y = b}
while y 6= 0 do
begin {x = (b − y)a}
10
x:=x+a ;
y:=y− 1 ;
end ;
{x = ab}
Wykorzystać logikę HL.
23. Udowodnić częściową poprawność wykorzystując system HL:
{a ­ 0}
x :=0; y :=1;
while y ¬ a do
begin
x:=x+1;
y:=y+2∗x+1;
end ;
2
{ 0 ¬ x2 ¬ a < (x + 1) }
24. Udowodnić częściową poprawność wykorzystując system HL:
{a > 0 ∧ b > 0}
x:=a ; y:=b ;
while x 6= y do
i f x > y then
x:=x−y
else
y:=y−x ;
{ x = nwd(a, b) }
25. Udowodnić częściową poprawność wykorzystując system HL:
{a > 0 ∧ b > 0}
x:=a ; y:=b ;
while x 6= y do
while x > y do x:=x−y ;
while y > x do y:=y−x ;
end ;
{ x = nwd(a, b) }
26. Udowodnić częściową poprawność wykorzystując system HL:
{a ­ 0 ∧ b ­ 0}
x:=a ; y:=b ; z : = 1 ;
while y 6= 0 do
begin
i f odd ( y ) then
begin
y:=y− 1 ;
z :=x∗ z ;
end
else
begin
x:=x∗x ;
y:=y div 2 ;
end ;
end ;
{ z = ab }
Dla miłośniczek oraz miłośników logiki
11
27. Udowodnić dualizm nww: |= ¬nww(S, ¬p) → nww(S, p)
28. Udowodnić monotoniczność nww: p → q ⇒ nww(S, p) → nww(S, q)
29. Udowodnić poprawność systemu HL tzn: `HL {p}code{q} ⇒ |= {p}code{q}
30. Udowodnić pełność systemu HL tzn: |= {p}code{q} ⇒ `HL {p}code{q}
4
Dalsze informacje
Poniższe pozycje odnoszą się do wszystkich list z ćwiczeniami z przedmiotu teoretyczne podstawy informatyki.
Literatura
[1]
David Harel: Rzecz o istocie informatyki Algorytmika, Edycja polska Wydanie drugie Wydawnictwa
Naukowo-Techniczne 2000
[2]
Tomasz Bilski, Krzysztof Chmiel, Janusz Stokłosa: Zbiór zadań ze złożoności obliczeniowej algorytmów.
Politechnika Poznańska 1992
[3]
Janusz Stokłosa: Zadania ze złożoności obliczeniowej algorytmów, Politechnika Poznańska 1989
[4]
L. Banachowski, Antoni Kreczmar: Elementy analizy algorytmów, Wydawnictwa Naukowo-Techniczne
1982
[5]
John E.Hopcroft, Jeffrey D.Ullman: Wprowadzenie do teorii automatów, języków i obliczeń. Wydawnictwo Naukowe PWN 2003
[6]
John E.Hopcroft, Jeffrey D.Ullman: Wprowadzenie do teorii automatów, języków i obliczeń. Wydanie
drugie, Wydawnictwo Naukowe PWN 2005
[7]
Mordechai Ben-Ari: Logika matematyczna w informatyce, Wydawnictwa Naukowo-Techniczne 2005
[8]
Christos H.Papadimitriou: Złożoność obliczeniowa, Wydawnictwa Naukowo-Techniczne 2002
[9]
R.L. Graham, D.E. Knuth, O.Patashnik: Matematyka konkretna,Wydawnictwo Naukowe PWN 2002
[10]
Kenneth A.Ross, Charles R.B.Wright: Matematyka dyskretna, Wydawnictwo Naukowe PWN 2000
[11]
Piotr Wróblewski,: Algorytmy struktury danych i techniki programowania, Helion 1997
12

Podobne dokumenty