Analiza algorytmu Euklidesa
Należy udowodnić że algorytm zawsze kończy obliczenia.
Zacznijmy od obserwacji, że algorytm Euklidesa w niestandardowym modelu liczb naturalnych może nie zakończyć obliczeń.
Na jakich podstawach ma się oprzeć dowód własności stop algorytmu?
Algorytmiczne aksjomaty liczb naturalnych:
- (N1) (∀n)(n+1≠0)
- (N2) (∀n)(∀m)(n+1=m+1⇒n=m)
- (N3) (∀n)[m:=0;while m≠n do n:=n+1 od](m=n)
Możemy zdefiniować relacje mniejszości
Definicja
x\lty df≡ ¬(x=y)∧[r:=0;while r≠x∧r≠ydor:=r+1od](r=x) |
Definicja
x≤y df≡ [r:=0;while r≠x∧r≠ydor:=r+1od](r=x) |
oraz operację odejmowania
Definicja
Jeśli y<x
x.−y df≡ [r:=y; q:=0;while r≠x dor:=r+1; q:=q+1 od;](wynik=q)
i operację dodawania
Definicja Operacja dodawania jest określona tak
x+y df≡ [r:=x; q:=0;while q≠y dor:=r+1; q:=q+1 od;](wynik=r)
Lemat (aksjomat Archimedesa)
Jeśli 0\ltn<m
Dowód własności stop algorytmu Euklidesa
Gdyby algorytm Euklidesa miał obliczenie nieskończone dla pewnych liczb naturalnych n i m to stanowiłoby to zaprzeczenie aksjomatu (N3) liczb naturalnych.
W algorytmie występuje pętla zewnętrzna i dwie po kolei pętle wewnętrzne. W każdym przypadku obliczenia pętli wewnętrznych są skończone. Wynika to wprost z aksjomatu (N3).
Nieco trudniej jest zauważyć, że obliczenie pętli wewnętrznej jest także skończone. Wychodząc z drugiej pętli wewnętrznej osiągnęliśmy większą z dwu liczb n, m zaczynając od zera i dodając pracowicie jeden.
W każdym kolejnym wykonaniu instrukcji iterowanych w pętli zewnętrznej większa z liczb n,m jest zmniejszana bo n≠m
{r:=0;while r≠n do r:=r+1 od} r=n
Wykorzystując następującą regułę wnioskowania
α⇒βwhile β do K od ¬β⇒while α do K od ¬α
wnioskujemy, że
{r:=0;while r≠n∧r≠m do r:=r+1 od} (r=n∨r=m)
Z założenia n≠m
{r:=0;while r≠n∧r≠m do r:=r+1 od} (r=min(n,m))
Udowodniliśmy więc, że
{if n≠mthenr:=0;while r≠n∧r≠m do r:=r+1 od;if r=nthenn_mniejsze:=true; max:=melsen_mniejsze:=false; max:=nfi;fi} ((r=n∧n\ltm)∨(r=m∧m\gtn)∧max=max(n,m))
Jeszcze raz korzystamy z aksjomatu (N3)
{r:=0;while r≠max do r:=r+1 od} r=max
{if n≠mthenr:=0;while r≠n∧r≠m do r:=r+1 od;if r=nthenn_mniejsze:=true; max:=melsen_mniejsze:=false; max:=nfi;r:=0;while r≠max do r:=r+1 odfi} (r=max∧max=max(n,m))
Skorzystam z prawa przerwania i wznowienia podróży
{r:=0;while r≠max(n,m)dor:=r+1od;} (r=max(n,m))≡{r:=0;while r≠min(n,m)dor:=r+1od;if r=nthenn_mniejsze:=true;max:=melsen_mniejsze:=false;max:=nfi;while r≠maxdor:=r+1od} (r=max(n,m))
by uzyskać
{if n≠mthenr:=0;while r≠n∧r≠m do r:=r+1 od;if r=nthenn_mniejsze:=true; max:=melsen_mniejsze:=false; max:=nfi;q:=0while r≠maxdor:=r+1; q:=q+1odfi}((r=max∧max=max(n,m))∧((n_mniejsze∧q=m−n)∨(¬n_mniejsze∧n=n−m)))
w tym programie wstawiam instrukcję
if n\_mniejsze then m:=q else n := q fi
{if n≠mthenr:=0;while r≠n∧r≠m do r:=r+1 od;if r=nthenn_mniejsze:=true; max:=melsen_mniejsze:=false; max:=nfi;q:=0while r≠maxdor:=r+1; q:=q+1od;if n_mniejsze then m:=q else n:=q fi;fi} (r=max∧max=max(n,m))
Dowód poprawności algorytmu Euklidesa
Należy wykazać, że wynik algorytmu Euklidesa to największy wspólny dzielnik.
Z postaci programu widać, że wynik jest największą liczbą n
- ⟨n1,m1⟩=⟨x,y⟩
- ⟨ni+1,mi+1⟩={⟨ni−mi,mi⟩gdy ni\gtmi⟨ni,mi−ni⟩gdy ni\ltminiezdefiniowanygdy ni=mi
zachodzi przy tym
- NWD(ni+1,mi+1)=NWD(ni,mi)
Ciąg wartości max(ni,mi)
- przejdź do algorytmu Euklidesa
-
- powrót do wybrane przykłady