ProgramozásMódszertan
10. előadás’2004
(vázlat)

A Programírási folyamat elemei

1. Programtesztelés

1.0. A cél, alapfogalmak és -elvek

Minél több (az összes?) hiba föllelése, minél „olcsóbban”, azaz minél kevesebb vizsgálattal.

Összes lefutás (»[1] összes bemenő adat kombinációja) helyett szisztematikus „próbálgatás”, de úgy hogy esély legyen minden hiba földerítésére.

Megjegyzem: a tesztelés nemcsak a hibásság felderítéshez nélkülözhetetlen, hanem a haté­konyság szempontjából kritikus pontok felderítéséhez is.

Def:

A teszteset a bemeneti adat (esetleg feltétel) és a hozzátartozó kimeneti adat (esetleg fel­tétel) kettőse.

Def:

Próba a tesztesetek azon halmaza, amelyre korlátozzuk a vizsgálatot a teszteléskor.

Def:

Ideális próba, amellyel a program összes hibája kideríthető.

Def:

e-szinten megbízható próba, amellyel 1-e valószínűséggel derítjük ki a program összes hibáját.

Def:

A program érvényes bemenete azon adatok együttese, amelyek teljesítik a program elő­feltételét. Amik nem, azok alkotják az érvénytelen bemenetek halmazát. [2]

A jó teszt tulajdonságai:

1.      Csak olyan teszteseteket tartalmaz, amelyek nagy valószínűséggel egy még felfedetlen hi­bát mutatnak ki a programban. (Pl. LNKO(x,y)-ra az [(5,5); 5][SzP1]  után fölösleges a [(10,10); 10][SzP2] .)

2.      A meg nem ismételhető tesztesetek kerülendők.[3]

3.      Teszteseteket mind az érvénytelen, mind az érvényes adatokra kell készíteni.

4.      Minden tesztesetből a lehető legtöbb információt „ki kell bányászni”. (Eközben persze feltételezésekkel élhetünk a program működésének logikájára vonatkozólag. Pl. mikor jo­gos kijelenteni „LNKO(x,y)-ra az [(5,5); 5] után fölösleges a [(10,10); 10]”, s mikor nem[SzP3] ?) Mit tapasztaltunk mi helyett?

5.      A programtesztelő csak a program írójától eltérő („elfogulatlan”) személy lehet, mert a szerző nem képes hatékonyan „rombolni saját hitelét”.

1.1. Módszerosztályok

Statikus: „papíron”/„fejben” végzett ellenőrzés (esetleges számítógépes „támogatással”, ami­kor a számítógép csak adatokkal szolgál a program szerkezetére, alkotó elemeire vonatko­zólag). Ekkor nincsenek bemenőadatok.

Dinamikus: a program futtatása (számítógépen). Módszerek abban térnek el egymástól, hogy más és más módon válogatnak a bemenőadatok közül.

1.2. Statikus módszerek

1.2.1. Kódellenőrzés

A tesztelő igyekszik a kódot megérteni. (Nagy szerepe van a technikai elvek betartásának!)

Leghatásosabb, ha a szerző maga magyarázza el a programját (a tesztelőnek).

1.2.2. Formai ellenőrzés

Formai hibák legegyszerűbbike: a szintaktikus hiba. (Ezeket a fordítóprogramok automa­tikusan kiszűrik. Az értelmezőprogramok pedig valamely dinamikus módszerrel vehetők rá ezek felderítésére.)

Rafináltabb formai hibák (tekinthetők egyszerűbb szemantikai hibáknak is) kiderítésére cél­szerű speciális programokat, vagy a fordítóprogram esetleg meglévő speciális szolgáltatásait felhasználni. Ilyen mellékesen nyerhető információ a kereszt(„be-kasul”)hivatkozási táblázat (cross reference table) korábban említett fajtája:

objektum

előfordulási hely

hatáskör

információhaladási irány

N

Program

globális

input-output

N

Beolvas

paraméter

output

N

Feldolgoz

paraméter

input

I

Feldolgoz

lokális/saját

(input-output)

Van

Program

globális

input-output

Van

Feldolgoz

paraméter

output

vagy az alábbi fajtája:

objektum

típus

előfordulási hely/hozzáférés

Program.N

Egész

55(K), Beolvas.18(V), Feldolgoz.15(K), Feldolgoz.17(V/K)

Feldolgoz.i

Egész

1(V), 2(K), 3(V), 5(K)

Program.Van

Logikai

75(V), Kiír.6(V)

Feldolgoz.Van

Byte

Feldolgoz.8(V), Feldolgoz.16(K)

 

Magyarázatok az utóbbi táblázathoz:

·        Az objektum megadása: programegység-azonosító + „.” + egyedi azonosító (pl. Program.N[SzP4] ), ha egy adathoz a „Program” egység-azonosító van hozzárendelve, ak­kor garantáltan globális adatról van szó.

·        az „előfordulási hely/hozzáférés” tartalmazza azon forrás sorok felsorolását (prog­ramegység + „.” + relatív sorszám formájában; pl. Beolvas.18), ahol akár az ér­tékére (K), akár a címére történik hivatkozás (V), más szóval akár felhasználjuk az értékét, akár módosítjuk azt.

(Egy roppant „gyenge epigon”, Turbo Pascal lehetőségre láthatunk példát, amelyhez a fordí­táshoz előzetesen beállítandó: Option/Linker/Detailed, s keletkezik egy ún. MAP-file, legalább minimális szerkezeti információt szerezzünk a programbeli fontosabb „tárgyia­sult” fogalmak –úm. konstans, változó, eljárás stb.– memóriában elhelyezkedéséről.)

1.2.3. Tartalmi ellenőrzés

Például a fenti táblázat és a kód összevetése segíthet az alábbi anomáliák felderítésében:

·        felhasználatlan objektum – nem (csak) ott deklarálódik, ahol felhasználódik
Gyakran ez történik, amikor „lendületből” deklarálunk munkaváltozókat, majd –praktikus okok miatt– később a vele kapcsolatos munkálatokat belefoglaljuk egy/több alprogramba, de a deklaráció „mementóként” őrzi egy elhamarkodott döntésünk emlékét…

·        felhasználatlan érték – pl. ugyanarra vonatkozó „közeli” értékadás
(
i:=1; For i:=1 to N do …)
Létrejöttének szokványos magyarázata:
While-os ciklusnak indult (pl. a keresés tétel ré­szeként), de később (pl. a kiválogatás tételbeli) For-ossá lett.

·        értéknélküli változó – előbb hivatkozunk rá, mint értéket kap
(
Procedure Elj(Const l:Integer);
   Var i,j:Byte;
 Begin
   If T(x[l]) then i:=1 else j:=2;
   k:=i; …
)

·        identikus transzformáció („áltranszformáció”) –

X:=1*J-0

1ÛI ???
0ÛO ???

·        konstans értékű kifejezések

While (i<1) And (i>N) do …

i<1) And (i>N) º False (ha N³1)
<Û>  ??  >Û< ??

·        végtelen ciklus

a hibás

a helyes?

While (i<=N) And … do
Begin
 
  i:=+1
End;

While (i<=N) And … do
Begin
  
  i:=i+1 ???
End;

i:=1;
While i<=N do
Begin
 
  i:=i+1
[SzP5] 
End;

For i:=1 to N do
Begin
 
End;

               vagy

a hibás

a probléma forrása

While f(i) do
Begin
  i:=i+1;
  x:=g(x,i)
End;

 

 

 

g(x,y) nem y-invariáns

·         értéknélküli függvény, operátor

Function Abs(Const x:Real):Real;
Begin
  If x<0 then Abs:=-x else Abs:=x;
End;

·        algebrai „képtelenségek”

If f(x)+f(x)<>2*f(x) then …

If (p(x) And q(x))<>
   (q(x) And p(x)) then …

??? f(x) nem x-invariáns
           
Þ  a+a¹2*a ???

??? p(x),q(x) nem x-invariánsak
           
Þ  a Ù b ¹ b Ù a ???

1.3. Dinamikus módszerek

A programot ez esetben működés közben vizsgáljuk. Cél, hogy lehető legkevesebb számú tesztesettel a lehető legnagyobb számú hibát derítsünk föl. Hogy hogyan válogassuk össze a teszteseteket? Válasz: vagy a programból, vagy a feladatból kiindulva.

A program „belsejének” (szövegének) „ismertsége” szempontjából beszélhetünk:

·        fekete doboz módszerről (vagy adatvezéreltről)

·        fehér doboz módszerről (vagy logikavezéreltről)

1.3.1. Fekete doboz módszerek

Többnyire a feladatspecifikáció alapján kell a teszteset-csoportokat kitalálni.

1.3.1.1. Ekvivalencia osztályok

Bemeneti adatok halmazát partícionáljuk („hézagmentesen” és egyértelműen felosztjuk), majd minden osztályból egy-egy reprezentánst jelölünk ki, amelyre alapozunk egy-egy teszt­esetet. A partícionáláshoz alapul az utófeltétel szolgál.

Specifikáció

Ekvivalenciaosztályok/Próba

[(N,(x1:?T(x1)… xN:?T(xN)));(Vane,Sorsz)][SzP6] 

(Lineáris) keresés(H*,F(H,L)):L ÈL´N

Be:      NÎN, XÎH*, T:H®N

Ki:       VaneÎL, SorszÎN

Ef:       N=Hossz(X)

Uf:       Vane º $iÎ[1..N] : T(xi)  Ù
            Vane
Þ SorszÎ[1..N] Ù T(xSorsz)

Vane=Igaz    ® [(1,(x1:T(x1)));(Igaz,1)]

Vane=Hamis ® [(1,(x1:ØT(x1)));(Hamis)]

Az előfeltétel által meghatározott érvényes és érvénytelen adatokat is külön osztálynak kell tekinteni.

Specifikáció

Ekvivalenciaosztályok/Próba

[(N,(x1:?T(x1)… xN:?T(xN)));Sorsz]

Kiválasztás(H*,F(H,L)):N

Be:      NÎN, XÎH*, T:H®L

Ki:      SorszÎN

Ef:       N=Hossz(X)  Ù  $iÎ[1..N] : T(xi)

Uf:       SorszÎ[1..N]  Ù  T(xSorsz)

Ef=Igaz    ® [(1,(x1:T(x1));1]

Ef=Hamis ® [(1,(x1:ØT(x1));HIBA]

A HIBA: a program jelzése az Ef nem teljesü­lésekor. (Az Ef-beli N=Hossz(X) figyelem­bevételére nincs igazán mód!)

1.3.1.2. Határesetek

Érdemes a partíciók „határainál” külön eseteket definiálni.

Specifikáció

Ekvivalenciaosztályok/Próba

[(N,(x1:?T(x1)… xN:?T(xN)));(Vane,Sorsz)]

(Lineáris) keresés(H*,F(H,L)):L ÈL´N

Be:      NÎN, XÎH*, T:H®N

Ki:       VaneÎL, SorszÎN

Ef:       N=Hossz(X)

Uf:       Vane º $iÎ[1..N] : T(xi)  Ù
            Vane
Þ SorszÎ[1..N] Ù T(xSorsz)

N=0 ®
  [(0,());(Hamis)]

N>0 ®

  Vane=Igaz  Ù  N=3 (utolsó olyan) ®
    [(3,(x1:
ØT(x1),x2:ØT(x2),x3:T(x3));(Igaz,3)]

  Vane=Igaz  Ù  N=3  (belső olyan)®
    [(3,(x1:
ØT(x1),x2:T(x2),x3:T(x3));(Igaz,1)]

  Vane=Igaz  Ù  N=3  (első olyan) ®
    [(3,(x1:T(x1),x2:
ØT(x2),x3:T(x3));(Igaz,1)]

  Vane=Hamis ®
    [(1,(x1:
ØT(x1));(Hamis)]

Összefoglalóan az osztályok megalkotásáról:

a)      adatÎ[a..b] ® O(adat)=O1ÈO2ÈO3ÈO4ÈO5, ahol O1:={x: xÎ(a..b)}, O2:={x: x<a}, O3:={x: x=a}, O4:={x: x=b}, O5:={x: x>b}

b)      adatÎN  [pl. darabszám] ® O(adat)=O1ÈO2ÈO3ÈO4ÈO5, ahol O1:={x: xÎ(0..max)}, O2:={x: x<0}, O3:={x: x=0}, O4:={x: x=max}, O5:={x: x>max} – nem elfelejtendő, hogy a programbeli adat-megfelelőt teszteljük, s így valójában –legalább– Z-beli. (Gondoljunk a „Bolondbiztosság” elvre!)

c)      adat: ?T(adat) ® O(adat)=O1ÈO2, ahol O1:={x: T(x)}, O2:={x: ØT(x)}.

… a reprezentáns megválasztásáról:

a)      több szempont szerinti osztályozás esetén célszerű úgy választani a reprezentánst, hogy egy teszteset több (igaz más-más szempont szerinti) osztályt is érintsen.

Pálda:

az előbbi LineárisKeresés-es példában N=3 helyett N=MaxN-t választva két legyet is ütünk egy csapásra: 1) N felső határértékénél tesztelünk, 2) a sorozat egyik szélsőséges helyzetű (azaz utolsó) elem megtalálására is rákérdezünk.

1.3.2. Fehér doboz módszerek

A szerint, hogy mennyire akkurátusan végezzük a program ismert szerkezetének bejárását, beszélünk:

·        utasítás (egyszeri) lefedése

·        döntés lefedése

·        részfeltétel lefedése

(próba)stratégiáról.

Lépések:

1)      próbastratégiát választunk,

2)      a stratégia szerinti tesztutakhoz tesztpredikátumot rendelünk,

3)      a predikátumok kijelölte ekvivalencia-osztályokból kiválasztunk egy reprezentánst.

A következő példaprogramot fogjuk boncolgatni:

If f(x) then y:=B(x);
While p(x) do
Begin
  C(x,y,z)
End;

1.3.2.1. Próbastratégiák

1.3.2.1.1. Utasítások (egyszeri) lefedése

kor úgy választjuk ki a teszteseteket, hogy minden utasítást legalább egyszer végrehajtsunk.

A tesztesetekben most csak az inputot jelezzük (a példa „elvi szinten” kezelése miatt az out­putról semmit sem tudván):

If f(x) then y:=B(x);
While p(x) do
Begin
  C(x,y,z)
End;

(x: f(x))

If f(x) then y:=B(x);
While p(x) do
Begin
  C(x,y,z)
End;

(x: p(x)),
sőt mivel p(x) y-független, jó ez is:
(x: f(x)
Ùp(x)),
s így a B(x)-t is végrehajtjuk egy füst alatt.

1.3.2.1.2. Döntés lefedése

…kor minden feltétel teljesülését és nem teljesülését is elő igyekszünk idézni. (Ha ez nem len­ne lehetséges, akkor lenne olyan ága a programnak, amelyet sohasem lehet végrehajtani, tehát fölösleges, vagy valamelyik feltétel hibás.)

If f(x) then y:=B(x);
While p(x) do
Begin
  C(x,y,z)
End;

(x: f(x))

If f(x) then y:=B(x);
While p(x) do
Begin
  C(x,y,z)
End;

(x: Øf(x))

If f(x) then y:=B(x);
While p(x) do
Begin
  C(x,y,z)
End;

(x: p(x))

If f(x) then y:=B(x);
While p(x) do
Begin
  C(x,y,z)
End;

(x: Øp(x))

Megjegyzés:

A fenti 4 esetet kevesebb tesztesettel is le lehet fedni.

Mivel a p(x) ciklusfeltétel, elvárható, hogy előbb-utóbb a ciklus termináljon. Így ele­gendő olyan x, amelyre (legalább egyszer) belép a ciklusba. Ha ui. lenne olyan x, amelyre a C(x,y,z) sohasem állít elő p-t ki nem elégítő értéket, akkor a program végtelen ciklusba kerül, s így hibát derítettünk föl. (Tehát a 4. teszteset nem is szükséges.)

Az is világos, hogy esetleg 2 tesztesettel is próbálkozhatunk: pl. az (x: f(x))Ç(x: p(x))¹Æ esetén az (x: f(x)Ùp(x))-szel, és az (x: Øf(x))Ç(x: Øp(x))¹Æ esetén az (x: Øf(x)Ù Øp(x))-szel. (Persze egyéb kombinációk is kínálkoznak.)

1.3.2.1.3. Részfeltétel lefedése

…kor a feltételek minden egyes részfeltételét mind igazra, mind hamisra igyekszünk beállí­tani. (Ha ez nem lenne lehetséges, akkor van fölösleges vagy rossz részfeltétel.)

(x: f(x)), (x: Øf(x))
(x: g(x)), (x:
Øg(x))
(x: p(x)), (x:
Øp(x))
(x: q(x)), (x:
Øq(x))

Itt is lehetséges, hogy kevesebb tesztesettel is célhoz érhetünk.

1.3.2.2. Tesztpredikátumok generálása

Lépései:

1.        a minimális számú olyan tesztút meghatározása, amelyek a próbastratégiának megfelelően fedik le a programgráfot.

2.        a program „szimbolikus végrehajtásával” az előfeltételt transzformálva állítsuk elő a teszt­predikátumokat.

Figyeljük ezt meg egy példán!

A program

A programgráf


{Bemenőadatok: N,Át
 Ef:
N³0 Ù
    
"iÎ[1..N]: ÁtiÎ[1..5]}

Db:=0;
For i:=1 to N do
[SzP7] 
Begin
  If At[i]>4.5 then Inc(Db)
End;
Writeln(’Db:’,Db);

 

Lássuk a tesztutakat és a tesztpredikátumokat az
Ef:
N³0 Ù "iÎ[1..N]: ÁtiÎ[1..5] előfeltétel mellett!


Db:=0;
For i:=1 to N do
Begin
  If At[i]>4.5 then Inc(Db)
End;
Writeln(’Db:’,Db);

Tesztpredikátum levezetése:

Ef Ù i=1 Ù Øi£N [SzP8] 
Þ
N
³0 … Ù Ø1£N

Þ
N=0


Db:=0;
For i:=1 to N do
Begin
  If At[i]>4.5 then Inc(Db)
End;
Writeln(’Db:’,Db)
;

Tesztpredikátum levezetése (a ciklusmag érintett ága pontosan egyszer fut le):

Ef Ù i=1 Ù i£N Ù
ØÁT1>4.5 Ù Øi+1£N
Þ
N
³0 … Ù ØÁT1>4.5 Ù Ø2£N

Þ
N=1
Ù ÁT1£4.5


Db:=0;
For i:=1 to N do
Begin
  If At[i]>4.5 then Inc(Db)
End;
Writeln(’Db:’,Db)
;

Tesztpredikátum levezetése (a ciklusmag érintett ága pontosan egyszer fut le):

Ef Ù i=1 Ù i£N Ù
ÁT1>4.5
Ù Øi+1£N
Þ
N
³0 … Ù ÁT1>4.5 Ù Ø2£N

Þ
N=1
Ù ÁT1>4.5

A reprezentáns kiválasztását, azaz a tesztesetek megválasztását már az Olvasóra hagyjuk.

2. Hibakeresés és -javítás

2.1. Hibajelenségek

A hibajelenség milyenségétől függhetnek a további teendőink. Ismerjük meg tehát, milyen jel­legzetes hibajelenségekkel találkozhatunk:

·        Szintaktikai hiba („nyelvtani” hiba) – értelmezős nyelveknél

·        Szemantikai hiba (végrehajtási hiba) – a beépített hibafigyelő rendszer jelzései („Range Checking Error”, „Divide by 0”, „Overflow”)

·        Végtelen ciklus – magába mélyed, folyamatosan ugyanazt vagy szisztematikusan, de nem az elvárásoknak megfelelőeket irogat ki a képernyőre (fájlba)…

·        („Normálisnak” tűnő terminálás után) nem jeleníti meg a kívánt eredményt

·        Helytelen eredmény jelenik meg

2.2. Elvek

Ha már vannak „jelenségek”, nekiláthatunk a hiba helyének (okának) felderítésének. Ha van elképzelésünk a hiba természetére, akkor tudunk ellene tenni, azaz nekifoghatunk a hibaja­vításnak. A két elméletileg elkülöníthető lépés (hibakeresés, -javítás) megvalósításához nyúj­tanak támpontot az alábbi elvek.

Hibakeresés:

·        Alaposan végig kell bogarászni… („sohase improvizálj a hibakeresésnél!”)

·        Ha hiba van, akkor másutt is hatása lehet… („hiba hibát szül”)

·        A hibák száma, súlyossága a mérettel lineárisnál jobban nő… :-(

Hibajavítás:

·        Amíg nincs lokalizálva a hiba, ne javítsunk!

·        Nem tünetet, hanem a hibát…

·        Javítás után minden korábbi tesztet újból…

·        A javítás eredményessége a mérettel rohamosan csökken… :-(

·        A javítás visszanyúlhat akár a tervezési fázisba…

2.3. Hibakeresési módszerek

2.3.1. Hibaosztály keresés

Indukciós

Dedukciós

Feltevés:

  Tesztek Þ szabályszerűség alapján: egyre bővülő adatosztály.

Megerősítés:

  újabb teszt, ami igazolja (?)

Feltevés:

  Tesztek Þ szabályszerűség alapján: egyre szűkülő adatosztály.

Megerősítés:

  újabb teszt, ami igazolja (?)

Pl.:

 x=0, 1, 5, 100 – OK

 x=-1, -7, -50 – nem OK.

 Þ negatívakra nem OK (?)

 Újabb teszt: [x=-37; ?]

Pl.:

 x=3, 5, 7 – nem OK

 x=12, 20 – OK.

 Þ nem OK: Prím(x) Ú Páratlan(x) Ú
            x<10
Ú Ø 4½x (?)

 Újabb teszt: [x=37; ?]

A 37 prím is, páratlan is, de nem 10 alatti és nem 4-gyel osztható.

2.3.2. Hibahelykeresés

Egy jól hangzó „elvi” módszer: visszalépéses technika – (fejben) a hibától vissza… amíg jót nem találunk…

Egy praktikusabb: teszteléssel segített

2.4. Eszközök

Erősen függ az alkalmazott fejlesztői környezettől… A legfontosabbak, amelyeket persze ma­gunk is „előidézhetünk” (csak ez sok többlet munkával jár, és számolhatunk a „kvantum­hatással”, azaz a nyomkövetés célú kód „interferálhat” a vizsgált programmal magával):

·        Adatkiírás – adatfigyelés

·        Töréspontok – feltételes, feltétel nélküli, aktuális pontig

·        Nyomkövetések – „makró-” (eljáráshívás 1 lépésben) és „mikró-lépésenként” (kód-utasí­tásonként)

·        Eljárás-verem kiírás – a hívott alprogramok és aktuális paraméterei

 

·        Post mortem lista – hibás megállást megelőző valahány utasítás…

·       

 


Tartalom

A Programírási folyamat elemei 1

1. Programtesztelés. 1

1.0. A cél, alapfogalmak és -elvek. 1

1.1. Módszerosztályok. 2

1.2. Statikus módszerek. 2

1.2.1. Kódellenőrzés. 2

1.2.2. Formai ellenőrzés. 2

1.2.3. Tartalmi ellenőrzés. 3

1.3. Dinamikus módszerek. 5

1.3.1. Fekete doboz módszerek. 5

1.3.1.1. Ekvivalencia osztályok. 5

1.3.1.2. Határesetek. 6

1.3.2. Fehér doboz módszerek. 6

1.3.2.1. Próbastratégiák. 7

1.3.2.2. Tesztpredikátumok generálása. 8

2. Hibakeresés és -javítás. 10

2.1. Hibajelenségek. 10

2.2. Elvek. 11

2.3. Hibakeresési módszerek. 11

2.3.1. Hibaosztályozás. 11

2.3.2. Hibahelykeresés. 12

2.4. Eszközök. 12

 



[1] Lehet több is (gondolj pl. a Randomize-ra) és kevesebb is (ui. több bemenetre is haladhat ugyanazon ágakon).

[2] Gondoljon a feladat- és programspecifikációra! A programspecifikáció többek közt abban tér el a feladatspeci­fikációtól, hogy az eredeti előfeltételnek eleget nem tévő adatokra is „helyesen”, azaz tervezett hibaüzenettel reagál. Ez okból érvényes bemenet alatt –természetesen– a feladatspecifikációban szereplő előfeltételre gondo­lunk első közelítésben, és persze a kódolás adta szűkítő feltételekre.

[3] Apropó: Randomize. A Randomize okozta megismételhetetlenség elkerülése: kiiktatása a programból a tesztelés idejére.


 [SzP1]A jelölésről:  [(x,y); LNKO(x,y)].

 [SzP2]Mivel a megoldó program alighanem oszthatósággal operál, és 10 = 2*5.

 [SzP3]Ha az algoritmusban szerephez juthat a „prímség”, akkor lehetséges, hogy a működésben különbség van; így a 2. teszteset információt hordoz.

 [SzP4]A „Program”-kulcs-szó esetleg elhagyható, ha megállapodunk abban, hogy jelentse ez azt: a program egy globális adatáról van szó.

 [SzP5] [SzP5]Ez az, ami nincs itt.

 [SzP6]A (x1:?T(x1)… xN:?T(xN)) jelölésről: az x-sorozat, amely elemei (egyenként) vagy T-tulajdonságú vagy nem. Dönté­sünktől függően.

 [SzP7]Mindenek előtt While-ciklusra kell áttérni.

 [SzP8]A Db nem szerepel az Ef-ben, ezért nem vesszük figyelembe a levezetésnél.