(1) Poprawność Algorytmów

Podobne dokumenty
Poprawność semantyczna

Podstawy Programowania Algorytmy i programowanie

Zapisywanie algorytmów w języku programowania

Wykład 2. Poprawność algorytmów

INFORMATYKA W SZKOLE. Podyplomowe Studia Pedagogiczne. Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227

Matematyka Dyskretna. Andrzej Szepietowski. 25 czerwca 2002 roku

Zapisywanie w wybranej notacji algorytmów z warunkami i iteracyjnych

Podstawy Informatyki. Algorytmy i ich poprawność

Definicje. Algorytm to:

Zapis algorytmów: schematy blokowe i pseudokod 1

Za pierwszy niebanalny algorytm uważa się algorytm Euklidesa wyszukiwanie NWD dwóch liczb (400 a 300 rok przed narodzeniem Chrystusa).

Elżbieta Kula - wprowadzenie do Turbo Pascala i algorytmiki

Indukcja. Materiały pomocnicze do wykładu. wykładowca: dr Magdalena Kacprzak

1 Podstawy c++ w pigułce.

Zadanie 1 Przygotuj algorytm programu - sortowanie przez wstawianie.

ALGORYTMY. 1. Podstawowe definicje Schemat blokowy

Algorytm poprawny jednoznaczny szczegółowy uniwersalny skończoność efektywność (sprawność) zmiennych liniowy warunkowy iteracyjny

1 Wprowadzenie do algorytmiki

Wstęp do informatyki. Maszyna RAM. Schemat logiczny komputera. Maszyna RAM. RAM: szczegóły. Realizacja algorytmu przez komputer

Przeszukiwanie z nawrotami. Wykład 8. Przeszukiwanie z nawrotami. J. Cichoń, P. Kobylański Wstęp do Informatyki i Programowania 238 / 279

Wstęp do programowania

3. Podaj elementy składowe jakie powinna uwzględniać definicja informatyki.

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 1. Karol Tarnowski A-1 p.

LABORATORIUM 3 ALGORYTMY OBLICZENIOWE W ELEKTRONICE I TELEKOMUNIKACJI. Wprowadzenie do środowiska Matlab

1 Podstawy c++ w pigułce.

Wstęp do Programowania potok funkcyjny

Informatyka 1. Plan dzisiejszych zajęć. zajęcia nr 1. Elektrotechnika, semestr II rok akademicki 2008/2009

Pętle i tablice. Spotkanie 3. Pętle: for, while, do while. Tablice. Przykłady

Algorytmy i struktury danych

Wstęp do programowania

Komentarze w PHP (niewykonywane fragmenty tekstowe, będące informacją dla programisty)

Temat 20. Techniki algorytmiczne

Wstęp do programowania

Liczby losowe i pętla while w języku Python

SCENARIUSZ LEKCJI. Streszczenie. Czas realizacji. Podstawa programowa

Podstawy programowania Laboratorium. Ćwiczenie 2 Programowanie strukturalne podstawowe rodzaje instrukcji

Technologie informacyjne - wykład 12 -

KARTA KURSU. Wstęp do programowania

I. KARTA PRZEDMIOTU CEL PRZEDMIOTU WYMAGANIA WSTĘPNE W ZAKRESIE WIEDZY, UMIEJĘTNOŚCI I INNYCH KOMPETENCJI EFEKTY KSZTAŁCENIA

Algorytm. a programowanie -

Algorytm. Krótka historia algorytmów

Algorytmy, reprezentacja algorytmów.

Pętle. Dodał Administrator niedziela, 14 marzec :27

Podstawy Programowania C++

Algorytmika i pseudoprogramowanie

ALGORYTMY. 1. Podstawowe definicje Schemat blokowy

Algorytmika i programowanie. dr inż. Barbara Fryc Wyższa Szkoła Informatyki i Zarządzania w Rzeszowie

Technologie cyfrowe. Artur Kalinowski. Zakład Cząstek i Oddziaływań Fundamentalnych Pasteura 5, pokój 4.15

ECDL Podstawy programowania Sylabus - wersja 1.0

Programowanie i techniki algorytmiczne

TEORETYCZNE PODSTAWY INFORMATYKI

Podstawy Programowania

Wyszukiwanie. Wyszukiwanie binarne

Efektywność algorytmów

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 7 Algorytmy

Programowanie w języku Python. Grażyna Koba

Opis efektów kształcenia dla modułu zajęć

Programowanie - wykład 4

Instrukcje sterujące. wer. 11 z drobnymi modyfikacjami! Wojciech Myszka :53:

a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Poprawność algorytmów

Podstawy i języki programowania

Iteracje. Algorytm z iteracją to taki, w którym trzeba wielokrotnie powtarzać instrukcję, aby warunek został spełniony.

Wydział Elektryczny. Katedra Telekomunikacji i Aparatury Elektronicznej. Konstrukcje i Technologie w Aparaturze Elektronicznej.

Wskazówki dotyczące zmiennych, tablic i procedur 1

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk

7. Pętle for. Przykłady

Paradygmaty programowania

Zadanie 1. Suma silni (11 pkt)

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

ALGORYTMY I PROGRAMY

Nazwa implementacji: Nauka języka Python wyrażenia warunkowe. Autor: Piotr Fiorek. Opis implementacji: Poznanie wyrażeń warunkowych if elif - else.

Wykład z Technologii Informacyjnych. Piotr Mika

PODSTAWY PROGRAMOWANIA STRUKTURALNEGO (C) SYLABUS A. Informacje ogólne

Programowanie. Pascal - język programowania wysokiego poziomu. Klasa 2 Lekcja 9 PASCAL

Programowanie I. O czym będziemy mówili. Plan wykładu nieco dokładniej. Plan wykładu z lotu ptaka. Podstawy programowania w językach. Uwaga!

Złożoność Obliczeniowa Algorytmów

Algorytmy i złożoność obliczeniowa. Wojciech Horzelski

Języki programowania zasady ich tworzenia

KOŁO MATEMATYCZNE LUB INFORMATYCZNE - klasa III gimnazjum, I LO

Algorytm - pojęcie algorytmu, sposób zapisu, poziom szczegółowości, czynności proste i strukturalne. Pojęcie procedury i funkcji.

Wstęp do Programowania potok funkcyjny

Podstawy programowania w języku C

Wstęp do programowania

Algorytmy. dr Dariusz Banaś (UJK) Seminarium w ramach projektu Fascynujący Świat Nauki dla uczniów gimnazjów. wersja 0.9. Start.

TEORETYCZNE PODSTAWY INFORMATYKI

Języki i techniki programowania Ćwiczenia 2

Lekcja 3: Pierwsze kroki z Pythonem. Pętle

Technologia informacyjna Algorytm Janusz Uriasz

WHILE (wyrażenie) instrukcja;

Programowanie funkcyjne wprowadzenie Specyfikacje formalne i programy funkcyjne

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

Projektowanie i Analiza Algorytmów

Podstawy programowania.

Podstawy programowania skrót z wykładów:

Języki programowania C i C++ Wykład: Typy zmiennych c.d. Operatory Funkcje. dr Artur Bartoszewski - Języki C i C++, sem.

napisać konstrukcję instrukcji decyzyjnej If wraz z jej rozwinięciem Else i ElseIf; podać definicję algorytmu z rozgałęzieniami;

Transkrypt:

(1) Algorytmów

Kontakt dr hab. Marcin, Katedra SIAM, PJATK

Polecane Podręczniki: Ogólne: T.Cormen, C.Leiserson, R.Rivest et al. do Algorytmów, PWN 2018 (lub wydanie anglojęzyczne) G.Mirkowska et al. - Zadania, wydawnictwo PJWSTK, 2005 (zbiór zadań i ćwiczeń, częściowo z rozwiązaniami) L.Banachowski, K.Diks, W.Rytter, PWN 2018, (ok. 300 stron), zwięzła książeczka, trudniejsza dla początkujących Algorithms and Datastructures. The Basic Toolbox (MS), K.Mehlhorn P.Sanders, Springer 2008

Przykłady innych podręczników N.Wirth Algorytmy + = Programy A.Aho, J.Hopcroft, J.Ullman W.Lipski Kombinatoryka dla Programistów, WNT 2004 Do pogłębionych studiów: D.Knuth The Art of Computer Programming (3 tomy) Ch.Papadimitriou Computational Complexity

Algorytm Co oznacza wyraz algorytm?

Algorytm Co oznacza wyraz algorytm? Dokładny opis, przepis, np. w postaci listy kolejnych kroków, jak coś wykonać, etc. (nie tylko zadania obliczeniowe, np. przepis wykonania pewnej potrawy albo dokonania pewnej procedury prawnej, etc.) Wg historyków, słowo to wywodzone jest od arabskiej wersji nazwiska wybitnego matematyka perskiego al-khwarizmi (A.D. 780-850) Algorytmika stanowi serce informatyki. Rola algorytmiki nawet rośnie w czasach ogromnego przyrostu danych ( big data ).

Jeden poziom abstrakcji ponad programowaniem Do zapisu algorytmów używany jest tzw. pseudokod, niebędący żadnym konkretnym językiem programowania, ale podobny do współcześnie używanych, popularnych języków programowania (np. Java, C/C++, Pascal, Python, etc.) Pseudokod abstrakcyjna notacja algorytmów wygląda podobnie do popularnych języków (Java, C/C++, Pascal, Python) rola bardziej informacyjna niż formalna (możliwie rozluźniony formalizm, o ile nie prowadzi do niejednoznaczności) literały (liczby, znaki, łańcuchy, NULL) zmienne (bez konieczności uprzedniej deklaracji) tablice i operator indeksowania [ ] (zakładamy indeksowanie tablic od 0) operatory (przypisanie =, relacyjne ==,<,>, logiczne &,,!, matematyczne +,++,+=, etc. funkcje (w tym rekursja), instrukcja return (zakładamy przesyłanie argumentu dla typów złożonych przez referencję) konstrukcje sterujące: wyrażenia warunkowe (IF, THEN, ELSE), pętle (WHILE, FOR).

Przykład użycia pseudokodu Zadanie: oblicz sumę liczb w tablicy o długości len: sum(array, len){ sum = 0 i = 0 while(i < len){ sum += array[i] i++ return sum Obserwacja: nie jest to żaden konkretny język programowania, ale każdy współczesny programista dokładnie rozumie co się w tym kodzie dzieje.

O czym jest kurs? Zasadniczo składa się z 3 komponentów, które częściowo się nakładają: 1 Analiza algorytmów (dany jest kod, należy zrozumieć co robi i jak efektywnie to robi) 2 Projektowanie algorytmów (dana jest specyfikacja zadania obliczeniowego, należy dokładnie zaprojektować poprawny i efektywny algorytm je rozwiązujący) 3 (dotyczy efektywnej organizacji danych i operacji wykonywanych na nich)

Projektowanie algorytmów Dane jest dobrze wyspecyfikowane zadanie obliczeniowe do wykonania na komputerze (np. obliczenie sumy liczb w tablicy) Zanim rozpoczęta zostanie implementacja, należy zaprojektować algorytm, czyli sposób rozwiązania problemu. Zaprojektowany algorytm zapisać można za pomocą pseudokodu lub tzw. schematu blokowego, zanim zostanie zaimplementowany w konkretnym języku programowania. Po zaprojektowaniu algorytmu i dokonaniu jego analizy sprawdzającej poprawność i efektywność można przystąpić do implementacji. Projekt i analiza algorytmu to niezbędne kroki przed przystąpieniem do implementacji.

Warunki te mogą być sformułowane w języku naturalnym, o ile jest to sformułowanie ścisłe. algorytmu Jest to kluczowe pojęcie, które oznacza w sposób nieco bardziej formalny: co dokładnie algorytm ma zrobić. Definicja: algorytmu wyraża kontrakt algorytmu i składa się z następujących elementów: (opcjonalnie) nazwa algorytmu i następująca po niej lista argumentów w nawiasach (wejście) tzw. warunek początkowy, który dokładnie specyfikuje typy i dopuszczalne wartości poprawnych danych wejściowych (wyjście) tzw. warunek końcowy, który dokładnie specyfikuje prawidłowy wynik (typ i wartość(i)) jaki ma być zwrócony przez algorytm jako funkcja danych wejściowych

Przykład specyfikacji Mamy dane potocznie sformułowane zadanie: zwróć sumę całkowitą liczb całkowitych w podanej tablicy o podanej długości Stwórzmy na jego podstawie bardziej precyzyjną specyfikację: nazwa i argumenty: sum(sequence, len) warunek początkowy (wejście): sequence - tablica liczb całkowitych, len - liczba naturalna będąca deklarowaną długością tablicy warunek końcowy (wyjście): algorytm ma zwrócić liczbę całkowitą będącą sumą pierwszych len elementów tej tablicy lub zero jeśli jest pusta. Obserwacje: ponieważ zdecydowaliśmy, że długość jest liczbą naturalną, więc tablica może mieć poprawnie długość 0 (pusta). Należy więc zdecydować, jaką wartość zwrócić w takim specjalnym przypadku. Zauważmy, że gdyby długość tablicy musiała być dodatnia, nie trzeba by zajmować się w specyfikacji przypadkiem tablicy pustej (ale tak algorytm jest ogólniejszy)

Całkowita poprawność algorytmu poprawne dane wejściowe to takie dane, które spełniają warunek początkowy specyfikacji poprawny wynik algorytmu to taki, który spełnia warunek końcowy specyfikacji Definition Przy danej specyfikacji, algorytm jest całkowicie poprawny wtedy i tylko wtedy, gdy dla każdych poprawnych danych wejściowych zachodzą oba poniższe warunki: 1 algorytm zatrzymuje się po skończonej liczbie kroków (tzw. własność stopu) 2 algorytm przy zatrzymaniu zwraca poprawny wynik (tzw. częściowa poprawność algorytmu) Zauważmy celowy podział na dwie, niezależne części powyżej.

Częściowa poprawność algorytmu Wg poprzedniej definicji, sprawdzanie czy algorytm jest całkowicie poprawny w praktyce dzielone jest na 2 części: 1 sprawdzanie czy algorytm ma własność stopu 2 sprawdzanie (przy założeniu, że się zatrzymuje) czy zwraca poprawny wynik Druga własność powyżej, nazywa się częściową poprawnością algorytmu Definition Algorytm jest częściowo poprawny jeśli spełnia poniższy warunek (w formie implikacji): Jeżeli algorytm zatrzyma się (i otrzymał poprawne dane wejściowe) to zwracany jest poprawny wynik Obserwacja: częściowa poprawność nie gwarantuje zatrzymania się algorytmu

Przykład częściowo poprawnego algorytmu (zadanie obliczania sumy liczb w tablicy) (array - tablica liczb całkowitych, len liczba naturalna (może być 0)) (uwaga: pseudokod może zawierać celową usterkę, aby ćwiczenie miało sens) sum(array, len){ sum = 0 i = 0 while(i < len) sum += array[i] return sum Czy powyższy algorytm: ma własność stopu? kiedykolwiek zatrzymuje się dla jakichś poprawnych danych? jeśli się zatrzymuje, to czy zwraca poprawny wynik? a więc jest częściowo poprawny? czy jest całkowicie poprawny? Jest to więc (nieco sztuczny) przykład ilustrujący fakt, że algorytm może być częściowo poprawny, ale nie całkowicie poprawny

Sprawdzanie własności stopu: przykład sum(array, len){ sum = 0 i = 0 while(i < len){ sum += array[i] i++ return sum Jak udowodnić, że powyższy algorytm ma własność stopu? Wystarczy zaobserwować, że: 1 algorytm zatrzyma się, kiedykolwiek zajdzie i >= len 2 len jest stałą i skończoną liczbą naturalną 3 wartość zmiennej i rośnie o 1 w każdej iteracji A więc, po skończonej liczbie iteracji algorytm zatrzyma się Zwróćmy uwagę na istotność wszystkich detali: np. nie wystarczy sam wzrost zmiennej, ale wystarczy wzrost o stałą wartość, albo nie wystarczy, że len jest stałe, ale także, że jest skończone (liczba naturalna), etc.

Dowodzenie częściowej poprawności - niezmienniki Dowodzenie własności stopu (pierwszy krok całkowitej poprawności) jest na ogół stosunkowo proste. Natomiast dowodzenie częściowej poprawności (drugi krok całkowitej poprawności) jest na ogół trudniejsze, często wymaga pewnej inwencji i zastosowania specjalnego narzędzia: niezmiennika pętli. Obserwacja: większość nietrywialnej aktywności algorytmów odbywa się wewnątrz pętli. niezmiennik pętli jest narzędziem pozwalającym udowodnić poprawność częściową algorytmu zawierającego pętlę. Definition Niezmiennik pętli to logiczny predykat spełniający następujący warunek: jeśli predykat jest spełniony przed wejściem w pewną (dowolną) iterację pętli to jest także spełniony po wyjściu z tej iteracji pętli.

a Indukcja Matematyczna Można zauważyć analogię definicji niezmiennika pętli do tzw kroku indukcyjnego używanego w dowodach przez indukcję matematyczną. Idea jest następująca: Tworzymy niezmiennik tak, aby w momencie zakończenia działania algorytmu był równoważny z warunkiem końcowym specyfikacji jeśli predykat jest spełniony tuż przed pierwszą iteracją pętli (analogia do kroku bazowego w indukcji matematycznej) oraz jeśli dodatkowo jest niezmiennikiem, czyli po wejściu w pętlę, zostanie zachowany przez dowolną skończoną liczbę pojedynczych iteracji to wtedy jest też spełniony na końcu algorytmu (po wyjściu z pętli), niezależnie od tego ile było iteracji algorytmu (co może być zmienne i zależeć od konkretnych danych wejściowych) Jest to analogia do dowodu przez indukcję matematyczną

Przykład użycia niezmiennika Zadanie: mając dany pseudokod algorytmu, zgadnąć co oblicza i udowodnić jego całkowitą poprawność wejście: Arr - tablica liczb całkowitych, len > 0 - jej długość algor1(arr, len){ i = 1 x = Arr[0] while(i < len) if(arr[i] > x){ x = Arr[i] i++ return x Co zwraca ten algorytm?

Przykład użycia niezmiennika Zadanie: mając dany pseudokod algorytmu, zgadnąć co oblicza i udowodnić jego całkowitą poprawność wejście: Arr - tablica liczb całkowitych, len > 0 - jej długość algor1(arr, len){ i = 1 x = Arr[0] while(i < len) if(arr[i] > x){ x = Arr[i] i++ return x Co zwraca ten algorytm? odpowiedź: maksimum z len pierwszych liczb zawartych w tablicy Arr

Przykład użycia niezmiennika Zadanie: mając dany pseudokod algorytmu, zgadnąć co oblicza i udowodnić jego całkowitą poprawność wejście: Arr - tablica liczb całkowitych, len > 0 - jej długość algor1(arr, len){ i = 1 x = Arr[0] while(i < len) if(arr[i] > x){ x = Arr[i] i++ return x Co zwraca ten algorytm? odpowiedź: maksimum z len pierwszych liczb zawartych w tablicy Arr Należy teraz udowodnić całkowitą poprawność algorytmu.

Przykład, c.d. Aby udowodnić całkowitą poprawność, wykonujemy standardowe 2 kroki (jakie?):

Przykład, c.d. Aby udowodnić całkowitą poprawność, wykonujemy standardowe 2 kroki (jakie?): 1 dowód własności stopu 2 dowód częściowej poprawności (przy użyciu niezmiennika pętli) algor1(arr, len){ i = 1 x = Arr[0] while(i < len) if(arr[i] > x){ x = Arr[i] i++ return x (dowód własności stopu jest podobny jak w poprzednim przykładzie)

Przykład, c.d. Aby udowodnić całkowitą poprawność, wykonujemy standardowe 2 kroki (jakie?): 1 dowód własności stopu 2 dowód częściowej poprawności (przy użyciu niezmiennika pętli) algor1(arr, len){ i = 1 x = Arr[0] while(i < len) if(arr[i] > x){ x = Arr[i] i++ return x (dowód własności stopu jest podobny jak w poprzednim przykładzie) Natomiast dowód częściowej poprawności wymaga więcej inwencji i użycia niezmiennika pętli.

Przykład, c.d. - dowód częściowej poprawności Zilustrowane zostanie użycie niezmiennika pętli do dowodu częściowej poprawności algorytmu. Znalezienie użytecznego niezmiennika pętli wymaga pewnej inwencji. Pomocna może być następująca technika: 1 zapisać predykat wyrażający warunek końcowy 2 przekształcić warunek końcowy tak, aby: zawierał wszystkie istotne w algorytmie zmienne wyrażał bieżącą (w bieżącej iteracji) wartość zmiennej zwracanej przez algorytm spełniał definicję niezmiennika pętli. 3 sprawdzić czy zaproponowany niezmiennik jest także spełniony tuż przed wejściem w pierwszą iterację pętli

Przykład dowodu częściowej poprawności, c.d. algor1(arr, len){ i = 1 x = Arr[0] while(i < len) if(arr[i] > x){ x = Arr[i] i++ return x Zadanie: pokazać, że zwracana zmienna x reprezentuje maksimum w tablicy Arr

Przykład dowodu częściowej poprawności, c.d. algor1(arr, len){ i = 1 x = Arr[0] while(i < len) if(arr[i] > x){ x = Arr[i] i++ return x Zadanie: pokazać, że zwracana zmienna x reprezentuje maksimum w tablicy Arr Warunek końcowy: x jest niemniejsze niż dowolna liczba w tablicy Arr i x jest zawarte w Arr. W notacji matematycznej byłoby to zapisane następująco:

Przykład dowodu częściowej poprawności, c.d. algor1(arr, len){ i = 1 x = Arr[0] while(i < len) if(arr[i] > x){ x = Arr[i] i++ return x Zadanie: pokazać, że zwracana zmienna x reprezentuje maksimum w tablicy Arr Warunek końcowy: x jest niemniejsze niż dowolna liczba w tablicy Arr i x jest zawarte w Arr. W notacji matematycznej byłoby to zapisane następująco: ( 0 j<len x Arr[j]) ( 0 j<len (x == Arr[j]))

Przykład, c.d. Mamy więc warunek końcowy: ( 0 j<len x Arr[j]) ( 0 j<len (x == Arr[j])) Teraz spróbujmy przekształcić powyższy warunek końcowy w niezmiennik. Brakuje zmiennej i (licznik iteracji). Niezmiennik powinien wyrażać: w i-tej iteracji x stanowi maksimum pośród i pierwszych wartości w tablicy Arr W zapisie matematycznym powyższy predykat wyglądałby tak: 0 j<i x Arr[j] ( 0 j<len (x == Arr[j])) Zauważmy, że powyższy predykat jest niezmiennikiem (jeśli był prawdziwy w iteracji i to będzie prawdziwy po iteracji i, ze względu na warunkową aktualizację zmiennej x w instrukcji if ) Dodatkowo, powyższy niezmiennik jest też prawdziwy tuż przed pierwszą iteracją pętli (bo i == 1 oraz x = Arr[0]) A więc będzie też prawdziwy po dowolnej liczbie iteracji. W szczególności, gdy algorytm zatrzyma się (dla i==len): (( 0 j<i x Arr[j]) (i == len)) przyjmie on szczególną postać, z której wynika warunek końcowy. ( 0 j<len x Arr[j]) ( 0 j<len (x == Arr[j]))

Co na pewno należy umieć/wiedzieć po tym wykładzie: 1 Umieć podać z pamięci dokładne definicje: specyfikacji algorytmu poprawnych danych wejściowych i wyjściowych całkowitej poprawności algorytmu częściowej poprawności algorytmu niezmiennika pętli 2 mając dane zadanie obliczeniowe stwórz ścisłą specyfikację 3 podać przykład algorytmu częściowo poprawnego, ale bez własności stopu i odwrotnie 4 umieć udowodnić własność stopu podanego algorytmu 5 umieć znaleźć niezmiennik dla danej prostej pętli 6 umieć udowodnić, że predykat jest niezmiennikiem 7 przy użyciu niezmiennika umieć udowodnić częściową poprawność algorytmu

Dziękuję za uwagę