Szekvenciális programok kategóriái strukturálatlan strukturált NEM-DETERMINISZTIKUS PROGRAMOK HELYESSÉGE Hoare-Dijkstra-Gries módszere determinisztikus valódi korai nem-determinisztikus általános fejlett Először általában a nem-determinisztikus programok formális helyesség bizonyításait vizsgáljuk Majd a nem-determinisztikus strukturált programok szintéziséről lesz szó 2 Nem-determinisztikus program elemek 1. A számítási csomópontokhoz nem függvényt, hanem relációt (nem-determinisztikus függvényt) rendelünk. 2. Az elágazási csomópontoknál kettőnél több kivezető él lehet, és mindegyikhez tartozik egy feltétel, ám ezek a feltételek nem szükségképpen teljesek és diszjunktak páronként. o Az átfedő feltételek okozzák a nem-determinisztikusságot o Ha egyik feltétel sem teljesül, ekkor hibás lesz a működés 3. Nem-determinisztikus szekvencia, azaz nincs megkötés a szekvenciát alkotó tagprogramok sorrendjére o Ez átvezet a párhuzamos programok vizsgálatához, ezért itt nem is számolunk vele Program-gráf A programok leírására a determinisztikus programoknál bevezetett gráfot használhatjuk: 1. A számítási csomópontokban megengedjük, hogy az f számítás nem-determinisztikus legyen: f A A. v f(v) helyett: v e ha e f(v) (v : f(v) ) Ennek alesete a v f(v) g(v) f, g : A A, amikor v f(v) vagy v g(v) hajtódik végre. 2. Az elágazási csomópontoknál megengedünk kettőnél több kivezető élt is, amelyekhez egy-egy kvantorfüggetlen logikai kifejezés tartozik. Ha egyszerre több kivezető él feltétele is teljesül, akkor az egyik ilyen ág hajtódik végre. Ha egyik feltétel sem teljesül, ekkor hibás működés keletkezik. 3. A gyűjtő csomópontokba kettőnél több él is befuthat. 3 4 Floyd módszerének felidézése Floyd módszer általánosítása Determinisztikus programok esetében egy rögzített kezdő csomóponthoz és kiinduló állapothoz egyértelműen tartozott egy végrehajtás és egy út a program-gráfban. Floyd módszere úgy mutatta meg, hogy bármelyik φ -ből induló végrehajtás ψ-ben áll meg, hogy a program-gráfnak a végrehajtáshoz tartozó útját, pontosabban annak útszakaszait vizsgálta. Ennek alapja az volt, hogy adott kiinduló állapot mellett egy út egyértelműen azonosította a végrehajtást. A nem-determinisztikusság miatt egy rögzített kezdő csomóponthoz és kiinduló állapothoz többféle végrehajtás is tartozhat. Egy végrehajtáshoz ugyan most is egyértelműen tartozik egy út a program-gráfban, de adott kiinduló állapot mellett egy úton több végrehajtás is keletkezhet. A Floyd módszer tehát nem-determinisztikus program esetén is alkalmazható, de az útszakasz jellemzők felírása körülményesebb. Erre megoldást jelenthet, ha sűrűn címkézzük a program-gráfot (minden csomópont előtt és után), de ekkor a helyességbizonyítás a sok útszakasz miatt hosszadalmas. 5 6 1
Nem-determinisztikus strukturált programok A strukturált programokat most is rekurzív módon definiáljuk. Kétféle definíciót is fogunk látni őrfeltételes (parciális) értékadás kiválasztás iteráció kilépéses iteráció Szintaxis 1. S::= skip v f(v) S 1 ; S 2 if 1 S 1 n S n fi do 1 S 1 n S n od do 1 S 1 n S n S e ; exit od ahol S 1, S 2,S n, S e nem-determinisztikus programok f : A A; f(v) kifejezés 1,, n, : A L; i (v), (v) kvantorfüggetlen logikai kifejezések 7 8 Szemantika 1. skip () = () () ( v f(v))( )=, f() ( v f(v))( )=, fail fail, M[S 1 ]() (S 1 ; S 2 )() = S 1 () S 2 (M[S 1 ]() ) fail, M[S 1 ]() (S 1 ; S 2 )() = S 1 () i[1..n]: i() (if 1 S 1 n S n fi)( ) = S i ( ) i[1..n]: i () (if 1 S 1 n S n fi)( ) =, fail i[1..n]: i () (do 1 S 1 n S n od)() = (S i; do 1 S 1 n S n od)() i[1..n]: i () (do 1 S 1 n S n od)( ) = i[1..n]: i () (do 1 S 1 n S n S e ; exit od)() = (S i; do 1 S 1 n S n S e ; exit od)() i[1..n]: i () (do 1 S 1 n S n S e ; exit od)()=s e () Szintaxis 2. S::= skip v: f(v) S 1 ; S 2 if 1 S 1 n S n fi while (v) do S 0 od ahol S 0, S 1, S 2,S n nem-determinisztikus programok f A A 1,, n : A L; i (v) kvantorfüggetlen logikai kifejezések 9 10 Szemantika 2. skip () = (v : f(v))( )= (v), e, ahol e f() fail, M[S 1 ]() (S 1 ; S 2 )() = S 1 () S 2 (M[S 1 ]() ) fail, M[S 1 ]() (S 1 ; S 2 )() = S 1 () i [1..n]: i() (if 1 S 1 n S n fi)( ) = S i( ) i[1..n]: i () (if 1 S 1 n S n fi)( ) =, fail () (while (v) do S 1 od )() = (S 1 ; while (v) do S 1 od )() () (while (v) do S 1 od )() = Leggyengébb előfeltétel (Dijkstra) Legyenek ahol Q, R : A L állítások és S egy program Dijkstra leggyengébb előfeltétele [lf(s,r)] = { σ D p(s) p(s)(σ) [R] } {Q} S {R} helyett használjuk: Q lf(s,r) Teljes helyesség feltétele: lf(s, ) ahol (, ) a feladat specifikációja bb-re: Q b lf(s, R b ) 11 12 2
Hoare axiómái és szabályai a leggyengébb előfeltétel használatával Üres program: Értékadás: lf(skip, R) = R lf(v f(v), R) =R f f totális Szekvencia: Q lf((s 1 ;S 2 ), R) ha Q lf(s 1, Q ) és Q lf(s 2, R) ahol Q : A L Elágazás: Q lf(if then S 1 else S 2 fi, R) ha Q lf(s 1, R) és Q lf(s 2, R) Ciklus: Q lf(while do S 0 od), R) ha Q P és P R és P lf(s 0,P) és P t>0 és t 0 Z: P t=t 0 lf(s 0, t<t 0 ) ahol P : A L, t : A Z Hoare-Dijkstra-Gries módszer axiómái és szabályai nem-determinisztikus programokra Üres program: lf(skip, R) = R Értékadás: lf(v: f(v), R)(v) = v D f e f(v) : R(e) Szekvencia: Q lf((s 1 ;S 2 ), R) ha Q : A L úgy, hogy Q lf(s 1, Q ) és Q lf(s 2, R) Elágazás: Q lf(if 1 S 1 n S n fi, R) ha Q 1 n és i {1.. n}: Q i lf(s i, R) Ciklus: Q lf(while do S 0 od), R) ha I : A L és t : A Z úgy, hogy Q I és I R és I lf(s 0, I) és I t>0 és t 0 Z: I t=t 0 lf(s 0, t<t 0 ) 13 14 Példa Valós szám természetes számú hatványa A = RNR x n h Q = (x=x n=n ) R = (h = x n ) I = (h*x n = x n ) t = n h := 1 n 0 h, n := h * x, n 1 Kell: Q lf(s, R) 1. Q lf(h := 1, I) Q I h 1 2. I lf(while, R) b) I n=0 R c) I n 0 t>0 d) I n 0 t=t 0 lf(h, n := h * x, n 1, I t<t 0 ) h := 1 n 0 I n 0 t=t 0 ( I t<t 0 ) h,n h*x, n-1 n>0 h, n := h * x, n 1 15 16 Példa befejezése I = h*x n = x n 1. Q I h 1 =(h* x n = x n ) h 1 = (x n = x n ) 2. b) I n=0 R ~ h* x n = x n n=0 h = x n c) I n 0 n>0~ h* x n = x n n 0 n>0 (n : N) d) I n 0 n=n 0 ((I n<n 0 ) h,n h*x, n-1 n>0 )= =( h*x* x n-1 = x n n-1<n 0 n>0 ) (n : N) I Példa Két természetes szám legkisebb közös többszöröse A = NNN a b c Q = (a=a b=b a>0 b>0) R = (Q d = lkkt(a,b) ) I = (Q ad bc max(d,c) lkkt(a,b) ) t = lkkt(a,b) max(d,c) d, c := a, b d<c d c d>c d := d+a c := c +b 17 18 3
Kell: Q lf(s, R) 1. Q lf(d,c := a,b, I) Q I d,c a,b 2. I lf(while, R) b) I d=c R c) I d c t>0 d) I d c t=t 0 lf(if, I t<t 0 ) d<c d := d+a d, c := a, b d c d>c c := c +b d) I d c t=t 0 lf(if, I t<t 0 ) i. I d c t=t 0 d<c d>c ii. I d c t=t 0 d<c lf(d := d+a, I t<t 0 ) I d c t=t 0 d<c (I t<t 0 ) d d+a iii. I d c t=t 0 d>c lf(c := c +b, I t<t 0 ) I d c t=t 0 d>c (I t<t 0 ) c c+b 19 20 Példa befejezése I = Q ad bc max(d,c) lkkt(a,b) 1. Q I d,c a,b =(Q ad bc max(d,c) lkkt(a,b)) d,c a,b =(Q aa bb max(a,b) lkkt(a,b) ) 2. b) I d=c R (ad bd d lkkt(a,b) d= lkkt(a,b)) c) I d c lkkt(a,b) max(d,c)>0 (lkkt(a,b) max(d,c)) i. I d c lkkt(a,b) max(d,c)= t 0 d<c d>c ii. I d c lkkt(a,b) max(d,c)=t 0 d<c Q a(d+a) bc max(d+a, c) lkkt(a,b) lkkt(a,b) max(d+a,c)<t 0 iii. I d c lkkt(a,b) max(d,c)=t 0 d>c Q ad b(c+b) max(d,c+b) lkkt(a,b lkkt(a,b) max(d,c+b)<t 0 Axiómák lf(skip, R)=R helyett [lf(skip, R)]=[R] [lf(skip, R)] = { σ D p(skip) p(skip)(σ) [R] } = = { σ A σ [R] } = [R] [lf( v: f(v), R)] = { σ D p(v: f(v)) p(v: f(v))(σ)[r]} = = { σ D f f(σ)[r]} = ( { σ D f e f(σ) : R(e)} ) = = { σ D f σ[r f]} = D f [R f] lf( v: f(v), R)= v D f e f(v) : R(e) helyett [lf(v: f(v), R)]=D f [R f] 21 22 Szekvencia levezetési szabályának Elég belátni: Q lf(s, R) helyett [Q] [lf(s, R)] [Q] [lf(s 1, Q )] [lf(s 1, lf(s 2, R))] = [lf((s 1 ;S 2 ), R)] Monotonítási szabály Szekvencia definíciója Kevésbé formálisan: Az (S 1 ;S 2 ) szekvencia összes végrehajtása (ld. szekvencia definíciója) az S 1 -beli végrehajtással indul. Egy Q-ból induló végrehajtásnak az első szakasza ezért a Q lf(s 1, Q ) miatt véges lépésben eljut Q -be, ahonnan az S 2 folytatja a végrehajtást (ld. szekvencia definíciója). Ez a második szakasz a Q lf(s 2, R) miatt R-ben fog megállni, tehát a szekvencia Q-ból induló végrehajtása R-ben áll meg, azaz Q lf((s 1 ;S 2 ), R). Elágazás levezetési szabályának Bizonyítás: Vegyünk egy Q-beli q állapotot. A q az elágazás valamelyik feltételét biztosan kielégíti a Q 1 n miatt, ezért az elágazás definíciója szerint belőle csak olyan végrehajtások indulnak, amelyeket azok az ágak adják, amelyek feltételét a q állapot kielégíti. Mivel i {1.. n}: Q i lf(s i, R) ezért mindegyik q-ból induló végrehajtás R-ben áll meg, azaz Q lf(if 1 S 1 n S n fi, R). 23 24 4
Ciklus levezetési szabályának Bizonyítás: Egy ciklus minden végrehajtása felbontható a ciklusmag végrehajtásaiból áll szakaszokra (kivéve a -beli állapotból induló végrehajtásokat). ezek a szakaszok mindig egy -beli állapotból indulnak (hiszen S 0 csak ekkor kap szerepet) az I-ből induló szakaszok az I lf(s 0, I) miatt I-ben állnak meg (eredményesen). A ciklus eredményesen megálló végrehajtásai -beli állapotban végződnek vagy -beli állapotból induló egyelemű végrehajtás vagy a végrehajtás legutolsó szakasza -beli állapot kell legyen Ciklus levezetési szabályának Bizonyítás folytatása: A Q-ból induló és eredményesen (-ban) leálló végrehajtások a Q I miatt I-ből indulnak, így aztán minden szakasz határa I-ben lesz, tehát a végrehajtás végállapota is, ami az I R miatt R-ben lesz. A Q-ból induló végrehajtások mind eredményesek, mert az I-ből induló szakaszai mind eredményesek, és végtelen sok szakasz nem lehet. Ez utóbbi esetén ugyanis I t>0 és t 0 Z: I t=t 0 lf(s 0, t<t 0 ) miatt egy szigorúan monoton csökkenő természetes számokból álló sorozatot rendelne a t a szakaszok kezdőállapotaihoz, ami lehetetlen. Tehát Q lf(while do S 0 od), R). 25 26 A módszer helyes, de nem teljes Az előbbi bizonyítások alapján a módszer helyes A bizonyított állításoknak egy kivételével a megfordítása is igaz. o A ciklus levezetési szabályának megfordítása viszont csak akkor igaz, ha a ciklusmag iterációinak száma a feladat kezdőállapotaiban felülről becsülhető. o Van olyan nem-determinisztikus ciklus (program), amely megold egy problémát, de a ciklus levezetési szabályának (leállási) feltételei nem teljesülnek rá. A = Z n Q = (igaz) R = (n=0) n 0 n : N n < 0 n := n 1 27 5