Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

30
Wprowadzimy teraz pojęcie niezmiennika pętli, które jest często wykorzystywane do projektowania algorytmów i dowodzenia ich poprawności. Rozważmy pętlę „while”, która ma postać: Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

description

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników. Wprowadzimy teraz pojęcie niezmiennika pętli , które jest często wykorzystywane do projektowania algorytmów i dowodzenia ich poprawności. Rozważmy pętlę „ while ”, która ma postać:. - PowerPoint PPT Presentation

Transcript of Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 1: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Wprowadzimy teraz pojęcie niezmiennika pętli, które jest często

wykorzystywane do projektowania algorytmów i dowodzenia ich

poprawności. Rozważmy pętlę „while”, która ma postać:

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 2: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 3: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 4: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Ostatnie stwierdzenie dotyczące prawdziwości zdania g po zakończeniu pętli jest tak oczywistym, że często się o nim zapomina.

Jednak dostarcza ono ważnych informacji pozwalających uzasadnić semantyczną poprawność algorytmów. Dlatego zostało umieszczone w treści twierdzenia.

Page 5: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

k=4;while(k>=4) k=k+1;

Page 6: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Przykład 1.Algorytm NWD Euklidesa.

Zapis w pseudokodzie

Jak znaleźć niezmiennik pętli?

Page 7: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Najpierw należy pokazać, że

Page 8: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 9: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 10: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 11: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 12: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 13: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Ćwiczenie

Page 14: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 15: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Page 16: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Przykład 2.Rozważmy algorytm dzielenia całkowitego liczb naturalnych.

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

void dzielenie (int x,y){ //: 0<=x i 0<=y int q,r; q=0; r=x; while(y<=r) //p: x=q*y+r i 0<=r i 0<=y

{ q=q+1; r=r-y;};

} //: x=q*y+r i 0<=r<y.

Pokażemy, że algorytm ten jest częściowo poprawny względem warunku początkowego i końcowego .

Page 17: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Należy udowodnić pewną własność obliczeń algorytmu, która łączy

zachodzenie warunku początkowego z warunkiem końcowym.

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Jaki warunek spełniają x, y, q, r w pętli „while” w chwili sprawdzenia warunku „y<=r” sterującego iteracją?

Określamy niezmiennik p.

Wykażemy, że za każdym razem, gdy obliczenie algorytmu rozpoczyna się stanem spełniającym warunek początkowy oraz dochodzi do warunku iteracji, to spełniony jest warunek p.

Page 18: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

void dzielenie (int x,y){ //: 0<=x i 0<=y int q,r; q=0; r=x; while(y<=r) //p: x=q*y+r i 0<=r i 0<=y{ q=q+1; r=r-y;};

} //: x=q*y+r i 0<=r<y.

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Możemy dojść do p dwiema drogami:

bezpośrednio z początku algorytmu

z pętli

Page 19: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

void dzielenie (int x,y){ //: 0<=x i 0<=y int q,r; q=0; r=x; while(y<=r) //p: x=q*y+r i 0<=r i 0<=y

{ q=q+1; r=r-y;};

} //: x=q*y+r i 0<=r<y.

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Jeśli dojdziemy do p z początku algorytmu, to q=0, r=x i p jest spełniony, bo zachodzi .

Jeśli już przejdziemy przez pętlę „while” i dojdziemy do p, to wiemy, że y<=r i zaszedł już warunek p: x=q*y+r i 0<=r i 0<=y .

Wtedy zostaje wykonana instrukcja złożona: q’=q+1;r’=r-y. Trzeba sprawdzić, czy dla q’ i r’ zachodzi warunek p:p: x=q’*y+r’ i 0<=r’ i 0<=y .

Alex=(q+1)*y+(r-y)=q*y+r0<=r’=r-y, bo y<=r i 0<=y.

Page 20: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

void dzielenie (int x,y){ //: 0<=x i 0<=y int q,r; q=0; r=x; while(y<=r) //p: x=q*y+r i 0<=r i 0<=y

{ q=q+1; r=r-y;};

} //: x=q*y+r i 0<=r<y.

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników

Stosując teraz indukcję względem liczby wykonanych sprawdzeń warunku iteracji „y<=r”, wnioskujemy, że przy każdym sprawdzeniu warunku iteracji zachodzi p.

Zatem, albo cały czas zachodzi „y<=r”i wtedy nie dochodzimy do , albo w pewnej chwili „y>r” i wtedy dochodzimy do , ale ponieważ p był spełniony, więc musi być spełniony .

Zwróćmy uwagę, że jeśli x=0 i y=0, to obliczenie algorytmu jest nieskończone, a więc według podanych warunków algorytm jest tylko częściowo poprawny i ma własność określoności obliczeń, ale nie ma własności stopu!

Page 21: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie własności stopu.

Dowodzenie własności stopu

Kryterium liczników iteracji

Kryterium malejących wielkości

Page 22: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium liczników iteracji.

Załóżmy, że dany jest algorytm:

M:{ l=c; while(p)do

{ K;

l=l+1; } }

Dobieramy teraz dwie wielkości: takie, że l<= oraz takie, które wyjaśnia zależność między wartościami zmiennych w chwili sprawdzania warunku (niezmiennika) p.

Kryterium liczników iteracjiJeżeli:1) i >=l jest w algorytmie M niezmiennikiem instrukcji

iteracyjnej „while” przy warunku początkowym ,2)K ma własność stopu względem i p,to M oraz „while(p)do K” mają własność stopu względem .

zmienna l jest licznikiem iteracji, służy do obliczania liczby wykonań instrukcji iterowanej K

Page 23: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Przykład 3.

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium liczników iteracji.

void dzielenie1 (int x,y){ //1: 0<=x i 0<yint q,r;q=0;r=x;while(y<=r) //p: x=q*y+r i 0<=r i 0<y

{ q=q+1; r=r-y;};

} //: x=q*y+r i 0<=r<y.

!!M:{ l=c; while(p)do

{ K;

l=l+1; } }

Zmienna q pełni rolę licznika iteracji.

Page 24: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium liczników iteracji.

void dzielenie1 (int x,y){ //1: 0<=x i 0<yint q,r;q=0;r=x;while(y<=r) //p: x=q*y+r i 0<=r i 0<y

{ q=q+1; r=r-y;};

} //: x=q*y+r i 0<=r<y.

M:{ l=c; while(p)do

{ K;

l=l+1; } }

Określmy : x/y oraz : x=q*y+r i r>=0 i 0<y.Pokażemy, że i q<=x/y jest niezmiennikiem instrukcji iteracyjnej.

Przy wejściu do instrukcji mamy: q=0, r=x, x>=0, y>0, czyli zachodzi i q<=x/y oraz r>=y.

Wtedy dostajemy nowe wartości: q’=q+1 i r’=r-y.

Page 25: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium liczników iteracji.

void dzielenie1 (int x,y){ //1: 0<=x i 0<yint q,r;q=0;r=x;while(y<=r) //p: x=q*y+r i 0<=r i 0<y

{ q=q+1; r=r-y;};

} //: x=q*y+r i 0<=r<y.

M:{ l=c; while(p)do

{ K;

l=l+1; } }

: x/y oraz : x=q*y+r i r>=0 i 0<y.

Łatwo pokazać, że te nowe zmienne spełniają warunek , a nierówność q<=x/y wynika z , bo:

Ćwiczenie!

x=q*y+r, y>0

q=x/y-r/y, y>0

(r>=0,y>0) q<=x/y

Stosując teraz kryterium liczników iteracji wnioskujemy, że algorytm ma własność stopu względem 1. Ponadto nierówność q<=x/y podaje ograniczenie na liczbę wykonywanych iteracji.

Page 26: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium malejących wielkości.

Załóżmy, że dany jest algorytm:

M:{ i=w+1; while(p)do

{ i=w; K;

} }

Dobieramy teraz trzy wielkości: i oraz w będące liczbami całkowitymi i takie, które wyjaśnia zależność między wartościami zmiennych w chwili sprawdzania warunku (niezmiennika) p.

Kryterium malejących wielkościJeżeli:1) i i>w, i w>=0 jest w algorytmie M niezmiennikiem

instrukcji iteracyjnej „while” przy warunku początkowym ,

2)K ma własność stopu względem i p,to M oraz „while(p)do K” mają własność stopu względem .

Page 27: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Metodę malejących wielkości stosuje się, gdy w algorytmie zwiększanie

wartości następuje w sposób nieregularny, czyli niekoniecznie o 1.

Zamiast szacować wzrost rozpatruje się jednak te wielkości, które

zmniejszają swoje wartości w trakcie wykonywania algorytmu i dla

których istnieją wartości ograniczające je z dołu.

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium malejących wielkości.

Page 28: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium malejących wielkości.

Przykład 4.void dzielenie2 (int x,y){ //2: 0<=x i 0<yint q,r; int i;q=0;r=x; i=r+1;while(y<=r) //p: x=q*y+r i 0<=r i 0<y

{ q=q+1; i=r; r=r-y;};

} //: x=q*y+r i 0<=r<y.

M:{ i=w+1; while(p)do

{ i=w; K;

} }

Zmienna r pełni rolę w. Wprowadzamy też pomocniczą zmienną i.

Page 29: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium malejących wielkości.

void dzielenie2 (int x,y){ //2: 0<=x i 0<yint q,r; int i;q=0;r=x; i=r+1;while(y<=r) //p: x=q*y+r i 0<=r i 0<y

{ q=q+1; i=r; r=r-y;};

} //: x=q*y+r i 0<=r<y.

M:{ i=w+1; while(p)do

{ i=w; K;

} }

Ustalamy : y>0 i (i=r+1 i=r+y).∨

Przy wejściu do instrukcji „while” warunek jest spełniony, bo i=r+1.

Page 30: Semantyczna poprawność algorytmów –  dowodzenie za pomocą niezmienników

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium malejących wielkości.

void dzielenie2 (int x,y){ //2: 0<=x i 0<yint q,r; int i;q=0;r=x; i=r+1;while(y<=r) //p: x=q*y+r i 0<=r i 0<y

{ q=q+1; i=r; r=r-y;};

} //: x=q*y+r i 0<=r<y.

M:{ i=w+1; while(p)do

{ i=w; K;

} }

: y>0 i (i=r+1 i=r+y).∨

Warunek zachowuje się przy każdym wykonaniu instrukcji iterowanej, bo jeśli i’ i r’ są nowymi wartościami, to i’=r oraz r’=r-y, czyli i’=r’+y.

Zatem jest niezmiennikiem iteracji.

Ponieważ r>=0, to cały warunek i r<i , i r>=0 jest niezmiennikiem iteracji.Na podstawie kryterium malejących wielkości mamy własność stopu względem 2.