Programozási Módszertan definíciók, stb. 1. Bevezetés Egy adat típusát az adat által felvehető lehetséges értékek halmaza (típusérték halmaz, TÉH), és az ezen értelmezett műveletek (típusműveletek) együttesen határozzák meg (vagy más szóval specifikálják). Természetes szám típus ( 0, ); Egész szám típus (, +, ); Valós szám (, +, ); Logikai típus ( ); Karakter típus (, műv: (x), (x)); Halmaz típus (TÉ: véges elemszámú halmazok E alaphalmazból, ez fölött: 2 E ); Sorozat típus (TÉ: véges sorozatok, E alaphalmazból: E*, műv: s, s i ); Vektor típus, 1D tömb (véges sorozatok n től m ig cimkézve E alaphalmazból: E n m=1); Mátrix típus (azonos méretű téglalapba rendezett elem együttesek E elemi halmaz fölött: E mxn kxl=1x1)... Állapottér (ÁT): Legyenek A 1,A 2,,A n tetszőleges véges vagy megszámlálható nem üres halmazok: ezek a típusértékhalmazok (TÉH). Rendeljük hozzájuk egyértelmű módon a páronként különböző c 1,..., c n címkéket. Ekkor a {{c 1 : a 1,..., c n : a n } a i A i (i= 1,...,n)} halmazt az A 1,A 2,...,A n TÉH okból képzett állapottérnek nevezzük, amit a továbbiakban a (c 1 : A 1,..., c n : A n ) szimbólummal jelölünk. Ha a cimkéknek rögzítjük a sorrendjét, akkor az A= A 1 A 2... A n halmazt (Descart szorzatot) is állapottérnek nevezzük. Állapotok: az ÁT elemei. Ezek maguk is halmazt alkotnak: a cimkézett értékek halmazát. Feladatnak nevezzük az F A A relációt. Az F reláció ÉT a ( F ) a feladat kezdőállapotait jelöli ki. Egy adott F re az F( ) képhalmaz az kezdőállapothoz tartozó célállapotokat tartalmazza. A ** : az A halmaz elemeiből képzett összes (véges és végtelen hosszú) sorozatot tartalmazóhalmaz A : a végtelen hosszúsorozatok halmaza red(α): az α sorozat redukáltja (azaz az eredeti sorozat minden azonos elemekből álló részsorozatát az ismétlődő egyetlen elemmel helyettesítjük) τ (α): a véges sorozat utolsó eleme Program: az S A A** reláció, ha S = A A: α S( ) : α 1 = α S : α = red(α). Programfüggvény, (hatásreláció): p(s) A A reláció az S A A** program PrFv e, ha: D p(s) = { A S( ) A*} D p(s) p(s)(a) = { b A α S( ) : ( ) = b }. Megoldás: Az S program megoldja az F feladatot, ha F p(s) F : p(s)( ) F( ). 1
:megoldás LGyEF: Leggyengébb előfeltétel: Legyen S A A** program, R: A állítás. Ekkor az S program R utófeltételhez tartozó LGyEF e az az állítás, amelyre: (S, R) = { p(s) p(s)( ) R }. A leggyengébb előfeltétel tehát pontosan azokban a pontokban igaz, ahonnét kiindulva az S program biztosan terminál, és az összes lehetséges végállapotra igaz R. Néhány fontos tulajdonság: Legyen S A A** program, R 1, R 2 : A állítások. Ekkor:. (S, HAMIS) = HAMIS (a csoda kizárásának elve). Ha R 1 R 2, akkor (S, R 1 ) (S, R 2 ) (monotonitási tulajdonság). (S, R 1 ) ^ (S, R 2 ) = (S, R 1^R 2 ). (S, R 1 ) v (S, R 2 ) (S, R 1 v R 2 ) A feladat specifikációja: Általában a feladat nem függ az ÁT összes komponensétől, azaz az ÁT több pontjához is ugyanazt rendeli. Ezeket a pontokat fogjuk össze egy ponttá a paramétertér segítségével. Paraméter: Legyen F A A feladat. A B halmazt a feladat pm ének nevezzük, ha van olyan F1 és F2 reláció, hogy F1 A B F2 B A F = F2 F1, ahol az ún. reláció kompozicióművelet. Specifikáció tétele: Legyen F A A feladat, B az F egy paramétertere, F1 A B, F2 B A, F=F2 F1. Jelölje B, és definiáljuk a következő állításokat az F feladat Q b előfeltételére, ill. R b utófeltételére): Q b = { A (, ) F1} = F1 ( 1) ( ) R b = { A (, ) F2} = F2( ) Ekkor ha B: Q b (S,R b ), akkor az S program megoldja az F feladatot. 2. Elemi programok Elemi program: egy A állapottéren egy S program, ha: A : S( ) {< >,<,,,...>,<, > }. Üres program, SKIP: nem csinál semmit: A : SKIP( ) = {< >}. Rossz program, törlődés, ABORT: soha sem terminál: A : ABORT( ) = {<,,,... >}. Értékadás (ÉA): programváltozó (~az akt. állapot egy komponense) új értéket kap (~megváltozik). Új állapot: ezzel az egy komponenssel tér el az előző állapottól. Az ÁT en 1 lépést: 2 állapotból álló végrehajtási sorozatot eredményez. ÉA: S program, ami az ÁT bármelyik állapotához a belőle kiinduló 2elemű állapotsorozatot rendeli. 2
Szimultán ÉA: Egy időben több változónak is új értéket adunk (állapotkülönbség több komponensű ) Egyszerű ÉA: csak egy változó értékét változtatja meg. Értékkiválasztás: az ÉA nem determinisztikus. Jelölés: : F( ) ( legyen eleme ) Értékadás: az F reláció függvény determinisztikus. Jelölés: := F( ) ( legyen egyenlő ) Parciális értékkiválasztás: F A és az ÉA nem determinisztikus. Parciális ÉA: F A és az F determinisztikus (F parciális függvény) Általános ÉA: Legyen A = A 1... A n, F = (F 1,..., F n ), ahol F i A A i. Az S program általános értékadás, ha: I n i=1 S = { (, red(<, >)), A ^ D Fi ^ F( ) } { (,<,,,...>) A ^ }. Elemi pr. ok programfüggvénye: p(skip)=id A, p(abort)=, p( :=F( )) = F, p( : F( )) = F. El.pr. ok LGyEF e: (SKIP,R) = R ; (ABORT,R) = hamis ; ÉA ok: F:A A globális fv: ( :=F( ),R) = { A F( ) R } = F ( 1) ( R )= R F F: parciális fv: ( :=F( ),R) = { A F( ) R } F = F ( 1) ( R ) F I n D Fi i=1 3. Programkonstrukciók 2 : α A * és β A **. 2 (α, β) = red( kon(α, β) ). Szekvencia: Legyenek S 1, S 2 A A ** programok. Az S A A ** relációt az S 1 és S 2 szekvenciájának nevezzük, és (S 1 ; S 2 ) vel jelöljük, ha A: S( ) = { α A α S 1 ( ) } { 2 (α, β) A ** α S 1 ( ) A * ^ β S 2 (τ(α)) }. Elágazás: Legyenek π 1,..., π n : A feltételek, S 1,..., S n programok A n. Ekkor az IF A A ** relációt az S i kből képzett π i k által meghatározott elágazásnak nevezzük és (π 1 :S 1,..., π n :S n ) el jelöljük, ha A: IF( ) = U n i= 1 i ( ) 0 ( ) ahol [1.. ]: n : α 1,,α n 1 A * és α n A **. n (α 1,,α n ) = red( kon(α 1,,α n ) ). : α A * ( ). (α 1,α 2, ) = red( kon(α 1,α 2, ) ). 3
Ciklus: Legyen π feltétel és S 0 program A n. A DO A A ** relációt az S 0 ból a π feltétellel képzett ciklusnak nevezzük, és (π, S 0 ) lal jelöljük, ha π : DO( ) = {< >}, és π : { α A ** α 1,, α n A ** : α= n (α 1,, α n ) ^ α 1 S 0 ( ) ^ [1.. 1]:(α i A * ^ α i+1 S 0 (τ(α i )) ^ π(τ(α i ))) ^ (α n A v (α n A * ^ π(τ(α n )) )) } { α A : α i A * : α= (α 1,α 2, ) ^ α 1 S 0 ( ) ^ α i+1 S 0 (τ(α i )) ^ π(τ(α i )) }. Levezetési szabályok: Szekvencia lev.sz.: Legyen S = (S 1 ; S 2 ), és adott Q, R és Q' állítás A n. Ha Q (S 1,Q') és Q' (S 2,R) akkor: Q (S, R). Elágazás lev.sz.: Legyen IF =(π 1 :S 1,..., π n :S n ), és adott Q, R állítás A n. Ha, és [1.. ]: Q ^ π i (S i, R), akkor: Q (IF, R). Ciklus lev.sz.: Legyen DO =(π, S 0 ), és adott I (invariáns), Q, R állítás A n, valamint t:a (termináló) függvény. Ha: Q I ; I^π (S 0,I) ; I^ π R ; I^π t>0 ; I^π^t=t 0 (S 0, t<t 0 ) : akkor: Q (DO, R). 4. Levezetés Megengedett program: az üres program; a megengedett F relációjú : F( ) értékadás; valamint a szekvencia, a megengedett feltételeket használó elágazás és a megengedett ciklusfeltételű ciklus programszerkezeteinek segítségével az üres programból és megengedett értékadásokból felépített program. Megengedett elemek: megengedett típusok (bevezetett és kiegészített) ; megengedett relációk (+eng. típ.műveletek kompoz. jával) ; megengedett értékadás ( : F( ) ban F +eng.) ; megengedett feltételek (+eng. műv. log.kif.) A programtervezés célja az, hogy egy feladatot egy megengedett programmal oldjunk meg. Ha a triviális megoldás nem megengedett, részfeladatokra kell bontani, finomítani, újra részletezni, amíg csupa +eng. nem lesz. Finomítás: Egy (rész)fa. ot triviálisan megoldó nem megengedett ÉA t: vagy egy bonyolultabb szerkezetű programmal helyettesítjük (procedurális programtervezés) ; vagy pedig az ÉA. jobboldali kifejezésének kiszámításánál használt, nem +eng. típusműveleteket valósítjuk meg (típus orientális programtervezés). Procedurális programtervezés: Levezetés: top down módszer; a feladatból (azaz a triviálisan megoldó nem megengedett értékadásból) indulunk ki, és azt a programszerkezetek levezetési szabályainak segítségével bontjuk részfeladatokra. 4
Visszavezetés: korábbi megoldás (minta) alapján, azaz analóg módon oldjuk meg; a mintafeladat és az új feladat eltéréseit a mintaprogram megoldására átvezetjük. példák 5. Visszavezetés Analóg programozás: Ha egy FA. megoldását egy hozzá hasonló, már korábban megoldott FA. megoldása alapján, a két FA. hasonlóságára építve készítjük el, ezt analóg programozásnak nevezzük. Ez sokféle módon valósulhat meg. Analóg levezetés: A mintafeladatot megoldó program előállítási folyamatát másoljuk le az adott feladat levezetésének elkészítéséhez; azaz egy kitaposott út mentén hozott korábbi döntéseket (mi legyen a programszerkezet, a ciklus invariáns, stb.) kölcsönözzük. Analóg visszavezetés: Közvetlenül a mintafeladatot megoldó programot nem pedig előállításának folyamatát használjuk fel; azaz a mintaprogramot módosítjuk a kitűzött és a mintafeladat közötti különbségek alapján. Összegzés: Legyen adott az : függvény. Feladatunk az, hogy egy adott [.. ] intervallumban összegezzük az függvény értékeit.: A = ( :, :, : ) Q = ( = ^ = ) R = (Q ^ = ) Bővítsük ki az állapotteret k komponenssel: A' = ( :, :, :, : ) Ekkor az invariáns: I = (Q ^ [.. +1] ^ = ) Az összegzés programozási A levezetési szabályok vizsgálata: tétele: Q I Ez nem teljesül, csak ha egy értékadást (k, s := m, 0) beteszünk a ciklus elé: Q (, :=, 0, I) =(Q ^ [.. +1] ^ 0 = ) I^ π R I^π t>0 Ebből meghatározhatjuk a ciklus feltételét: π = ( 1 = ), azaz π = ( +1) Legyen = +1; ez pozitív lesz P és π miatt. I^π ^ = 0 (S 0, < 0 ) A ciklusmag csökkenti a terminálófüggvényt, ha növeli értékét ( := +1). I^π ^ +1= 0 ( := +1, +1< 0 ) = < 0 I^π (S 0,I) Vizsgáljuk meg I leggyengébb feltételét, ha (k := k+1) et végrehajtjuk. ( := +1, I) = (Q ^ +1 [.. +1] ^ = ) = Q.Kell még egy utasítás ( := + ( )) a ciklusmagba: I ^π ( := + ( ), Q ) = (Q ^ [.. +1] ^ + ( )= ) példák analóg levezetéssel, visszavezetéssel, behelyettesítéssel 5
6. Programozási tételek Számlálás: Adott egy β: [m..n] feltétel. Határozzuk meg, hogy az [m..n] intervallumon a β feltétel hányszor veszi fel az értéket. Levezetése: Kibővítjük az ÁT. ünket: Így az invariáns: Analóg levezetéshez az összegzés használható. Maximumkeresés: Adott egy : [.. ] függvény, amelynek értékkészletén definiáltunk egy teljes rendezési relációt. Határozzuk meg, hogy az függvény hol veszi fel az [.. ] nem üres intervallumon a legnagyobb értéket, és mondjuk meg, mekkora ez a maximális érték! _ ÁT et kibővítjük egy komponenssel. Az invariáns: Itt nem engedjük meg az üres intervallumot (mint az előbb), mivel nincs értelme annak maximumát keresni. Lineáris keresés: Adott az β: [.. ] feltétel. Keressük meg az [.. ] intervallumban balról az első olyan számot, amely kielégíti a β feltételt! Most nincs szükség állapottérbővítésre, az változó megteszi. Az invariáns: 6
Kiválasztás: Adott az β: feltétel, valamint egy egész szám. Keressük meg az számtól jobbra eső (az et is beleértve) az első olyan számot, amely kielégíti a β feltételt, ha tudjuk, hogy van ilyen szám! (Ez egy spec. keresés.) Az invariáns: Feltételes maximumkeresés: Adott egy : [.. ] függvény, amelynek értékkészletén definiáltunk egy teljes rendezési relációt és adott egy β: [.. ] feltétel. Határozzuk meg, hogy az függvény hol veszi fel az [.. ] intervallum β t kielégítő elemei közül a legnagyobb értéket, és mondjuk meg, mekkora ez a maximális érték! Feltétel fennállásáig tartó keresés: Adott egy egész szám, és egy olyan δ: feltétel, amely az egészek számegyenesén től jobbra valahol biztosan felvesz egy értéket. Legyen az egész számokon től jobbra értelmezve egy β : feltétel. Keressük meg az számtól jobbra eső (az et is beleértve) az első olyan számot, amely kielégíti a β feltételt azon az [.. ] intervallumon, ahol [.. ]:δ( ), de δ( +1) teljesül! Kibővitjük az állapotteret egy : komponenssel, amely mindaddig értékű lesz, amig az től jobbfelé haladva csak olyan számokkal találkozunk, amelyekre a δ feltétel teljesül. 7