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

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

Algorytmy sortowania i porządkowania
Algorytmy sortowania i przeszukiwania
Instrukcje - wprowadzenie
Ćwiczenie (1) Dostosuj poniższy program do potrzeb zdefiniowanych w treści programu zaliczeniowego: #include void dodaj(){}; void edytuj(){}; void usun(){};
Grażyna Mirkowska PJWSTK, 10 stycznia 2001
Grażyna Mirkowska PJWSTK 15 listopad 2000
Wykład 10 Metody Analizy Programów Specyfikacja Struktur Danych
Wykład 06 Metody Analizy Programów System Hoare
Programowanie I Rekurencja.
Języki programowania C++
PROGRAMOWANIE STRUKTURALNE
Historia liczby.
algorytm znajdowania największego wspólnego dzielnika (NWD)
Złożoność obliczeniowa
Liczby Pierwsze - algorytmy
AUTOMATYCZNE DOWODZENIE TWIERDZEŃ.
Opracowała: Elżbieta Fedko
Turbo pascal – instrukcje warunkowe, iteracyjne,…
Programowanie imperatywne i język C
Programowanie imperatywne i język C Copyright, 2005 © Jerzy R. Nawrocki Wstęp.
Programowanie imperatywne i język C Copyright, 2004 © Jerzy R. Nawrocki Wprowadzenie.
ALGORYTMY I STRUKTURY DANYCH
Materiały pomocnicze do wykładu
Liczby pierwsze.
NOWA PODSTAWA PROGRAMOWA
Wstęp do interpretacji algorytmów
Dr Anna Kwiatkowska Instytut Informatyki
Podstawy programowania
POJĘCIE ALGORYTMU Pojęcie algorytmu Etapy rozwiązywania zadań
Zbiór do posortowania mieści się w pamięci
Rekurencja.
ALGORYTMY KLASYCZNE ________ FRAKTALE
Prowadzący: Dr inż. Jerzy Szczygieł
Projekt AS KOMPETENCJI jest współfinansowany przez Unię Europejską w ramach środków Europejskiego Funduszu Społecznego Program Operacyjny Kapitał Ludzki.
WITAMY W ŚWIECIE MATEMATYKI
Algorytmy rekurencyjne - przykład
Rachunki Gentzena Joanna Witoch.
Początek, koniec lub przerwanie algorytmu
Liczby rzeczywiste ©M.
Algorytm testujący czy liczba jest liczbą pierwszą czy złożoną
Składnia pętli do … while do instrukcja while (wyrażenie); gdzie: instrukcja – instrukcja pojedyncza lub blok instrukcji wyrażenie – wyrażenie przyjmujące.
Wykład 7 Synchronizacja procesów i wątków
1. Współczesne generacje technologii
Semantyczna teoria prawdy Tarskiego
Algorytmika Iteracje autor: Tadeusz Lachawiec.
szeregowe, z rozgałęzieniami, zawierające pętle
Algorytmy i Struktury Danych
Szyfrowanie i deszyfrowanie
Iteracje w C# Informatyka Cele lekcji: Wiadomości: Uczeń potrafi:
Obliczanie NWD- algorytm Euklidesa
POZNAJ ŚWIAT LICZB CAŁKOWITYCH
Algorytm znajdowania Największego Wspólnego Dzielnika.
Algorytmy równoległe Algorytm równoległy pozwala na wykonywanie w danej chwili więcej niż jednej operacji. EREW - wyłączny odczyt i wyłączny zapis; CREW.
Algorytmy – wprowadzenie
Największy Wspólny Dzielnik (NWD) Najmniejsza Wspólna Wielokrotność (NWW) Zajęcia 12.
Wstęp do interpretacji algorytmów
Pętle – instrukcje powtórzeń
Materiały pochodzą z Platformy Edukacyjnej Portalu Wszelkie treści i zasoby edukacyjne publikowane na łamach Portalu
RODZAJE ALGORYTMÓW 2.-warunkowe 1.-liniowe i=i+1 3.-iteracyjne.
Programowanie strukturalne i obiektowe Klasa I. Podstawowe pojęcia dotyczące programowania 1. Problem 2. Algorytm 3. Komputer 4. Program komputerowy 5.
Liczbami naturalnymi nazywamy liczby 0,1,2,3,..., 127,... Liczby naturalne poznaliśmy już wcześniej; służą one do liczenia przedmiotów. Zbiór liczb.
Sposoby zapisu algorytmu
Zbiory – podstawowe wiadomości
Liczby pierwsze: szukanie, rozmieszczenie, zastosowanie, ciekawostki. Liczby pierwsze: szukanie, rozmieszczenie, zastosowanie, ciekawostki. Kinga Cichoń.
ALGORYTMY I STRUKTURY DANYCH
Programowanie I Rekurencja.
ALGORYTMY I STRUKTURY DANYCH
ALGORYTMY I STRUKTURY DANYCH
ALGORYTMY I STRUKTURY DANYCH
Zapis prezentacji:

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

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.

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników while(k>=4) k=k+1;

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników Przykład 1. Algorytm NWD Euklidesa. Zapis w pseudokodzie Jak znaleźć niezmiennik pętli?

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników Najpierw należy pokazać, że

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

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

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

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

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

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

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

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

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników Przykład 2. Rozważmy algorytm dzielenia całkowitego liczb naturalnych. 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 .

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. 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.

Semantyczna poprawność algorytmów – dowodzenie za pomocą niezmienników bezpośrednio z początku algorytmu 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. z pętli Możemy dojść do p dwiema drogami:

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 . 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. 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 . Ale x=(q+1)*y+(r-y)=q*y+r 0<=r’=r-y, bo y<=r i 0<=y.

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. 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!

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

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. zmienna l jest licznikiem iteracji, służy do obliczania liczby wykonań instrukcji iterowanej K Kryterium liczników iteracji Jeżeli:  i >=l jest w algorytmie M niezmiennikiem instrukcji iteracyjnej „while” przy warunku początkowym , K ma własność stopu względem  i p, to M oraz „while(p)do K” mają własność stopu względem .

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium liczników iteracji. Przykład 3. !! void dzielenie1 (int x,y) { //1: 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. M:{ l=c; while(p)do { K; l=l+1; } Zmienna q pełni rolę licznika iteracji.

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium liczników iteracji. void dzielenie1 (int x,y) { //1: 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. 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.

(r>=0,y>0) q<=x/y Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium liczników iteracji. void dzielenie1 (int x,y) { //1: 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. M:{ l=c; while(p)do { K; l=l+1; } : x/y oraz : x=q*y+r i r>=0 i 0<y. Ćwiczenie! Łatwo pokazać, że te nowe zmienne spełniają warunek , a nierówność q<=x/y wynika z , bo: 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.

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ści Jeżeli:  i i>w, i w>=0 jest w algorytmie M niezmiennikiem instrukcji iteracyjnej „while” przy warunku początkowym , K ma własność stopu względem  i p, to M oraz „while(p)do K” mają własność stopu względem .

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium malejących wielkości. 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. Przykład 4. void dzielenie2 (int x,y) { //2: 0<=x i 0<y int 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.

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium malejących wielkości. void dzielenie2 (int x,y) { //2: 0<=x i 0<y int 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.

Semantyczna poprawność algorytmów – dowodzenie własności stopu – kryterium malejących wielkości. void dzielenie2 (int x,y) { //2: 0<=x i 0<y int 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.