Semantyka i weryfikacja programów/Ćwiczenia 14: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Sl (dyskusja | edycje)
Nie podano opisu zmian
Dorota (dyskusja | edycje)
Nie podano opisu zmian
Linia 1: Linia 1:


== Zawartość ==
== Zawartość ==
Linia 60: Linia 59:




Oprócz samego niezmiennika, musimy też ,,odgadnąć" asercję, którą wpiszemy w miejsce znaku zapytania.
Oprócz samego niezmiennika, musimy też odgadnąć asercję, którą wpiszemy w miejsce znaku zapytania.
Warunek, którego potrzebujemy to <math>N \land i \leq k < j</math>.
Warunek, którego potrzebujemy to <math>N \land i \leq k < j</math>.


Linia 107: Linia 106:
</math>
</math>


Wciąz jest on jednak za słaby! Nie potrafimy skorzystać z wiedzy o tym, że A[1 .. n] jest posortowana, bo nie wiemy, czy i,j nalezą do zakresu tablicy! Oto prawidłowy niezmiennik:
Wciąż jest on jednak za słaby! Nie potrafimy skorzystać z wiedzy o tym, że A[1 .. n] jest posortowana, bo nie wiemy, czy <math>i,j</math> należą do zakresu tablicy! Oto prawidłowy niezmiennik:


<math>
<math>
Linia 165: Linia 164:




Zmieniliśmy warunek instrukcji warunkowej na ,,i zna j".  
Zmieniliśmy warunek instrukcji warunkowej na "i zna j".  
Dzięki temu nie musimy wpisywać do asercji założenia <math>\forall i, j. A[i, j] \in \{ 0, 1 \}</math>.
Dzięki temu nie musimy wpisywać do asercji założenia <math>\forall i, j. A[i, j] \in \{ 0, 1 \}</math>.


Linia 213: Linia 212:
</math>
</math>


Niemiennik <math>N</math> zawiera w sobie zdanie warunkowe: ,,jeśli wśród 1 .. n istnieje znakomitość to ..".
Niemiennik <math>N</math> zawiera w sobie zdanie warunkowe: "jeśli wśród 1 .. n istnieje znakomitość to ..".
Zatem w dowodzie tej implikacji najpierw zakładamy przesłankę całej implikacji, a następnie
Zatem w dowodzie tej implikacji najpierw zakładamy przesłankę całej implikacji, a następnie
zakładamy, że wśród 1 .. n istnieje znakomitość.
zakładamy, że wśród 1 .. n istnieje znakomitość.
Linia 280: Linia 279:
* wierzchołki x, y należą do tej samej klasy abstrakcji podziału P wtw. gdy x i y są połączone ścieżką w <math>T</math>
* wierzchołki x, y należą do tej samej klasy abstrakcji podziału P wtw. gdy x i y są połączone ścieżką w <math>T</math>
* elementy kolejki <math>Q</math> należą do <math>E \setminus T</math>
* elementy kolejki <math>Q</math> należą do <math>E \setminus T</math>
* jeśli krawędź <math>e</math> nie należy do <math>Q</math>, to obydwa końce krawędzi e należą do tej samej klasy podziału <math>P</math>.
* jeśli krawędź <math>e</math> nie należy do <math>Q</math>, to obydwa końce krawędzi <math>e>/math> należą do tej samej klasy podziału <math>P</math>.


Ostatni warunek można też sformułować tak: jeśli krawędź <math>e</math> nie należy do <math>Q</math> i nie należy do drzewa <math>T</math>, to <math>T \cup \{e\}</math> ma cykl.
Ostatni warunek można też sformułować tak: jeśli krawędź <math>e</math> nie należy do <math>Q</math> i nie należy do drzewa <math>T</math>, to <math>T \cup \{e\}</math> ma cykl.
Linia 328: Linia 327:


Przykładowo, pierwsza implikacja wymaga wykazania, że <math>T \cup \{ e \}</math> jest podzbiorem minimalnego drzewa rozpinającego,
Przykładowo, pierwsza implikacja wymaga wykazania, że <math>T \cup \{ e \}</math> jest podzbiorem minimalnego drzewa rozpinającego,
wiedząc, że T jest takim podzbiorem, że e nie tworzy cyklu z krawędziami z T, oraz że e jest najmniejszą krawędzią
wiedząc, że T jest takim podzbiorem, że <math>e</math> nie tworzy cyklu z krawędziami z <math>T</math>, oraz że <math>e</math> jest najmniejszą krawędzią
o tej własności.
o tej własności.
Prawdziwość tego zdania wynika stąd, że poddzbiory drzew rozpinających stranowią strukturę zwaną ''matroidem''.
Prawdziwość tego zdania wynika stąd, że poddzbiory drzew rozpinających stanowią strukturę zwaną ''matroidem''.
Pomijamy dalsze szczegóły.
Pomijamy dalsze szczegóły.


Linia 400: Linia 399:


{{cwiczenie|4|cw4.dom|
{{cwiczenie|4|cw4.dom|
Przeprowadź jeszcze jeden dowód poprawności częściowej programu znajującego znakomitość, względem
Przeprowadź jeszcze jeden dowód poprawności częściowej programu znajdującego znakomitość względem
innych asercji:
innych asercji:
}}
}}

Wersja z 15:14, 29 wrz 2006

Zawartość

Kontynuujemy ćwiczenie dowodzenia poprawności częściowej prostych programów. Rozważymy programy operujące na tablicach i na innych strukturach danych.


Tablice

Ćwiczenie 1 (wyszukiwanie binarne)

Przeprowadź dowód poprawności częściowej poniższego programu:


{n1(x.1x<nA[x]A[x+1])(x.1xnA[x]=v)}
i := 1; j := n;
while i < j do
  k := (i + j) div 2;
  if A[k] < v then
    i := k + 1
  else
    j := k
{A[i]=v}


Rozwiązanie

{{{3}}}


Ćwiczenie 2

Dana jest tablica dwuwymiarowa A[1 .. n, 1 .. n] zawierająca tylko liczby 0 i 1, reprezentująca relację znajomości pomiędzy n osobami. Umówmy się, że

  • i zna j A[i, j] = 1
  • i nie zna j A[i, j] = 0.

Powiemy, że i jest znakomitością jeśli zachodzi warunek:

j.(1jnji)(j zna ii nie zna j)

Napisz program znajdujący znakomitość, o ile istnieje. (Czy mogą być dwie różne znakomitości?) Przeprowadź dowód poprawności częściowej tego programu.


Rozwiązanie (część pierwsza: program)

{{{3}}}


Rozwiązanie (część druga: dowód poprawności)

{{{3}}}


Inne struktury danych

Ćwiczenie 3 (algorytm zachłanny)

Niech G=(V,E) będzie spójnym grafem nieskierowanym. Krawędziom grafu przypisane są różnowartościowo wagi liczbowe (czyli nie ma dwóch różnych krawędzi o tej samej wadze). Załóżmy, że mamy do dyspozycji następujące struktury danych:

  • zbiór T krawędzi grafu, z operacjami:
    • inicjuj T jako zbiór pusty
    • dodaj nowy element do T
  • kolejka priorytetowa Q przechowująca krawędzie grafu, z operacjami:
    • inicjuj kolejkę za pomocą zbioru wszystkich krawędzi grafu
    • add(Q, e): dodaj krawędż e do Q
    • deletemin(Q): usuń z Q namniejszy element (krawędź)
    • min(Q): zwróć w wyniku najmniejszy element (krawędź) w Q
  • podział P zbioru wierzchołków grafu, z operacjami:
    • inicjuj P jako zbiór jednoelementowych klas abstrakcji, po jednej dla każdego wierzchołka grafu
    • find(P, x): zwróć klasę abstrakcji wierzchołka x
    • union(P, X, Y): połącz klasy abstrakcji X i Y w jedną klasę XY
    • |P| -- zwróć liczbę klas abstrakcji podziału P.

Graf reprezentowany jest przez dwie operacje pocz(e), kon(e) zwracające wierzchołki będące odpowiednio początkiem i końcem krawędzi e.

Przeprowadź dowód poprawności częściowej programu obliczającego minimalne drzewo rozpinające:


{G=(V,E) jest spójny}

// inicjuj P i Q j.w.
T := ;

while |P| > 1 do
  e := min(Q);
  Q := deletemin(Q);
  x = pocz(e); y := kon(e);
  X := find(P, x);
  Y := find(P, y);

  if X <> Y then
    T := T  {e};
    P := union(P, X, Y)

{T jest minimalnym drzewem rozpinającym graf G}


Rozwiązanie (szkic)

P


Zadania domowe

Ćwiczenie 1

Przeprowadź jeszcze jeden dowód poprawności częściowej wyszukiwania binarnego.


{n1x.1x<nA[x]A[x+1]}
i := 1; j := n;
while i < j do
  k := (i + j) div 2;
  if A[k] < v then
    i := k + 1
  else
    j := k
{(x.1xnA[x]=v)A[i]=v}


Program pozostał ten sam, ale zmienione zostały asercje.


Ćwiczenie 2

Sformalizuj asercję końcową w poniższym programie i przeprowadź dowód poprawności częściowej:


{n1x.1x<nA[x]A[x+1]}
i := 1; p := 0;
while i <= n do
  if A[i] = A[i - p] then
    p := p + 1;
  i := i + 1
{ maksymalna długość stałego odcinka w tablicy A wynosi p}


Ćwiczenie 3

Dana jest tablica A przechowująca wyniki wyborów: A[i] = j oznacza, że i głosował na j. Ordynacja wyborcza jest większościowa: zwycięzcą jest osoba, na którą głosowała przynajmniej połowa uprawnionych. Sformalizuj asercję końcową i przeprowadź dowód poprawności częściowej programu znajdującego zwycięzcę:


{n0odd(n)}
k := A[1]; p := 1; i := 2;
while i <= n do
  if A[i] = k then
    p := p + 1;
  else
    if p > 1 then
      p := p - 1
    else
      k := A[i];
      p := 1;
  i := i + 1
{ jeśli jest zwycięzca to jest nim k}


Ćwiczenie 4

Przeprowadź jeszcze jeden dowód poprawności częściowej programu znajdującego znakomitość względem innych asercji:


{k.1knk jest znakomitością}
i := 1; j := n;
while i <> j do
  if i zna j then
    i := i + 1
  else
    j := j - 1
{i jest znakomitością}