Tartalmi kivonat
jegyzet Veszprémi Egyetem Műszaki Informatika Szak 2000 Jegyzet az SDL nyelv oktatásához, mobil hálózati példákkal Készült a Veszprémi Egyetem Információs Rendszerek Tanszék megbízásából Készítették: Éder János Horváth Ervin Lektorálta: Dr. Tarnay Katalin 2 Tartalomjegyzék 1. Bevezetés 1.1 Bevezetés az SDL-be 1.11 Az SDL matematikai alapjai 1.12 A típus és a példány fogalma 1.13 Absztrakt adattípus 1.14 Grafikus és szöveges SDL 2. Alap SDL 2.1 Hierarchikus specifikáció 5 5 5 7 7 8 9 9 2.2 A rendszer specifikálása 2.21 Jelek deklarációja 2.22 Csatornák deklarációja 2.23 Példa a rendszerspecifikációra 10 12 13 14 2.3 Blokk specifikálása 2.31 Jelutak deklarálása 2.32 Jelutak és csatornák összekapcsolása 2.33 Példa a blokkspecifikációra 16 17 17 18 2.4 Processz specifikálása 2.41 Processz-szintű deklaráció 2.411 Érvényes bemeneti jelek halmaza 2.412 Adattípusok deklarációja Új típus deklarációja
2.413 Változók deklarálása 2.414 Időzítő deklarálása 2.415 Nemformális szöveg 2.42 A processz viselkedésének specifikálása 2.421 Állapotátmenetek State, input, nextstate Decision Task Output 2.422 Eltérések a hagyományos véges automata modelltől Processz létrehozása és megszűnése Join Comment Timer Save és implicit átmenet 2.423 A leírást tömörítő formák Implicit jelutak Állapotlista Kötőjeles állapot Bemenet- és mentéslista Kimenetlista 19 21 21 21 22 25 25 26 26 26 26 28 29 30 31 31 35 36 37 38 39 40 41 41 41 42 3. Az alap SDL kiterjesztése 43 3.1 A hierarchia szintek számának növelése 3.11 Kombinált és particionált blokkdeklarálás 3.111 Blokk-alrendszer deklarálása 3.12 Csatorna-alrendszer deklarálása 3.13 Jeldeklaráció finomítása 3.14 Processz szolgálatokra való felbontása 43 43 45 48 50 50 3.2 Eljárások, makrók 3.21 Eljárások deklarálása 3.22 Makrók deklarálása 54 54 57 3 3.3 Folyamatos jel,
feltételes bemenet 3.31 Folyamatos jel 3.32 Feltételes bemenet 58 58 59 3.4 Nemdeterminisztikus viselkedés leírása 3.41 Nemdeterminisztikus döntés 3.42 Nemdeterminisztikus kifejezés 3.43 Spontán átmenet 60 60 61 61 3.5 Változók exportálása / importálása 3.51 Változók exportálása / importálása 62 62 3.6 Opciók 3.61 Konstans értékének külső megadása 3.62 Statikus leírás kiválasztása 3.63 Dinamikus leírás kiválasztása 62 62 63 64 4. Függelék 65 4.1 Adattípusok deklarációja SDL-ben 4.11 Előre definiált típus deklarációk az alap SDL-ben 4.12 Előre definiált generátorok az alap SDL-ben 4.13 ASN1-es típus deklarációkkal kibővített SDL 4.14 ASN1-es generátorokkal kibővített SDL 65 65 67 68 69 4.2 Példa az SDL alkalmazására 4.21 A Wireless Transaction Protocol SDL/GR leírása 4.22 A Wireless Transaction Protocol SDL/PR leírása 70 70 91 Az SDL kulcsszavak mutatója Irodalomjegyzék 98 101 4 1. Bevezetés Az SDL
nyelvet a hetvenes években kezdték el kidolgozni távközlési rendszerek formális (matematikailag egzakt) leírására. A nyelv első verzióját 1976-ban publikálta a CCITT (Comité Consultatif International Telegraphique et Telephonique), jelenleg ITU (International Telecommunication Union) a Z.100 ajánlásában, melyet újabb verziók követtek. Az 1980-as verzióban bevezették a strukturált szerkezetet, és az 1984-es verzióban már absztrakt adattípust használnak az adatok megadására. Az 1988-as verzió [Z100-88] már azt mutatja, hogy a nyelv elérte a kifejlett, stabil állapotot. Az 1992-es verzióban [Z100-92] bevezették az objektum orientáltságot, a távoli eljáráshívást, a nemdeterminisztikus viselkedést és a csomagok használatát. Az 1996-os verzióban pedig kijavítottak néhány felderített hibát. A nyelv neve arra utal, hogy segítségével leírható a specifikálandó rendszer felépítése, szerkezete (specification) és a viselkedése
(description) is. Az SDL a kettőt együtt, komplett egészként kezeli. A hosszú fejlődés és a széleskörű tapasztalatok eredményeként az SDL jelenlegi formájában nem korlátozódik egyedül a távközlés területére, hanem alkalmas tetszőleges valós idejű, interaktív, elosztott rendszer megadására. Másik nagy előnye – és többek között ez különbözteti meg a programnyelvektől, hogy módot ad a rendszer különböző absztrakciós szintű leírására. Keretein belül elkészíthető a teljes rendszert átfogó globális leírás, de jól alkalmazható a részletek kidolgozásánál is. Népszerűségének egyik titka talán, hogy grafikus (SDL/GR) és szöveges (SDL/PR) változata is létezik, melyek kölcsönösen egyértelműen megfelelnek egymásnak. E jegyzetben az SDL nyelvet kívánjuk bemutatni egy mobil hálózati példa segítségével. Ennek során elsősorban a nyelv magját jelentő ún. alap SDL-re fogunk koncentrálni Kevésbé részletesen
foglalkozunk a nyelv kiterjesztésével. Végül egy részletes példával demonstráljuk a teljes rendszerleírás SDL-beli módját. 1.1 Bevezetés az SDL-be 1.11 Az SDL matematikai alapjai Az SDL nyelv a kiterjesztett véges automata modellen alapul. A véges automata modell [DDP-85, BACH-91] az objektumokat a gerjesztésekre adott válaszukkal és állapotváltozásukkal jellemzi. Öt elem határozza meg a modellt: az állapotok véges halmaza, a bemenetek véges halmaza, a kimenetek véges halmaza, a kezdő állapot és az ezeken értelmezett állapot átmeneti (vagy leképzési) függvény. Hasonlóan a véges automatákhoz a kiterjesztett véges automata is gerjesztés-válasz módon határozza meg egy rendszer működését. A változók, a predikátumok és az akciók halmazának bevezetésével jelentősen megnövelték az automaták leíró képességét. Ezek hiányában a véges automata csak állapotterét képes növelni, ami bonyolult rendszerek leírásánál
áttekinthetetlenné teszi a specifikációt, sőt állapotrobbanáshoz is vezethet. A kiterjesztésének azonban megvan az „ára” is Míg a véges automaták megadásánál jól használható és egyértelmű az állapotátmenet gráf illetve diagram, a kiterjesztett automaták egyértelmű megadására új eszközre volt szükség. Az egyik ilyen az SDL, amely tovább is bővíti a lehetőségeket. Az egyik legfontosabb eredménye, hogy jól kidolgozott szintaxisa és szemantikája egyértelmű rendszerleírást tesz lehetővé. 5 A kiterjesztett véges automata (EFSM – Extended Finite-State Machine) egy hetes: EFSM = (S, I, O, V, P, A, s0, fs,i,p), ahol: S I O V P A s0 fs,i,p – az állapotok véges halmaza; – a bemenetek véges halmaza; – a kimenetek véges halmaza; – a változók véges halmaza; – a predikátumok véges halmaza; – az akciók véges halmaza; – a kezdő állapot; – az állapot átmeneti (vagy leképzési) függvény. A bemenetek és a
kimenetek kommunikációs események, melyek az automata és a környezete között zajlanak. A változók a rendszer belső állapotára vonatkozó további részleteket adnak meg, míg a predikátumok azt definiálják, hogy hogyan kell a változók aktuális értékét figyelembe venni egy adott bemenetre való reakció meghatározásánál. Az akciók a bemeneteknek a változókra gyakorolt hatásait adják meg. Az fs,i,p leképezési függvény azt adja meg, hogy az automata egy adott s állapotában az i bemenő esemény hatására igaz p predikátum (feltétel) mellett az a akciót (tevékenységet) hajtja végre, o kimeneti eseményt generál és átmegy az s’ következő állapotba. Az SDL a leírandó objektumot egy rendszernek tekinti, és mindaz, ami nem tartozik hozzá, alkotja a rendszer környezetét (1. ábra) A rendszer több egymással és a rendszerkörnyezettel kommunikáló kiterjesztett véges automatából (processz) áll, ahol a kommunikáció lehetséges
útvonalait csatornákkal és jelutakkal jelölik. A kommunikáció jelekkel történik. Ezek felelnek meg a kiterjesztett véges automata kimeneteinek és bemeneteinek. A kommunikációs útvonalak FIFO (First-In First-Out) elven működnek, vagyis az a jel kerül előbb feldolgozásra, amely előbb került a sorba. Minden processz (automata) egyetlen bemeneti sorral rendelkezik, azaz valamennyi hozzá vezető jelút ebbe az input sorba csatlakozik. környezet rendszer 1. ábra A rendszer és környezete 6 Ezek után egy SDL leírás két fő részből áll: 1. Az automaták elrendezésének, csoportosításának és kapcsolatainak, azaz a kommunikációs útvonalainak megadásából, amit statikus leírásnak is neveznek. 2. Az automaták viselkedésének meghatározásából, ami a dinamikus leírás, azaz, hogy milyen jel hatására, milyen változások következnek be az automata állapotában, változóiban, milyen üzenetet küld stb. A teljes rendszer viselkedését az
egyes automaták viselkedésének összessége határozza meg. Az SDL ily módon jól definiált matematikai alapokkal rendelkezik. Egyértelműen, világosan határozza meg a specifikálandó rendszert, ami alapja lehet a megvalósításnak. Azonban még fontosabb, hogy még a megvalósítás előtt a specifikáció elemezésével felderíthetők bizonyos hibák, ellenőrizhető a fokozatosan kialakított modell konzisztenciája és logikai helyessége. További előny, hogy a megvalósítás részben automatizálható, valamint az előállított kód könnyen módosítható a rendszerspecifikáció módosítása esetén. 1.12 A típus és a példány fogalma Az SDL világában mindenek előtt meg kell érteni és különböztetni a típus és a példány fogalmát. A specifikáció során a típust határozzuk meg Például amikor leírjuk, hogy milyen egy szerver-kliens kommunikációs kapcsolata, akkor ezt mint általános típust definiáljuk. Ugyanakkor a valóságban
rengeteg-féle szerver-kliens kapcsolat létezik, amelyek az általános típus egyes előfordulási példányai. Ezekben már konkrét adatokat cserélhetünk ki, kérhetünk le. Már az 1988-as SDL változást tartalmazta ezt a típus és példány közötti megkülönböztetést, de az 1992-es változat még jobban kihangsúlyozta. Így az SDL rendszerben különböző típusok deklarálhatók a hierarchia minden szintjén, és megadható, hogy egy-egy típusból konkrétan hány példány van jelen éppen a rendszerben. A példányok jelentik a kézzelfogható valóságot, azaz a leírás interpretálásával állnak szoros kapcsolatban. A példányokat létre kell hozni, azoknak élettartamuk van, ami után megszűnnek.Például, típusnak tekinthetünk egy tankönyvet, amit a szerző megírt és a kiadó kiadott.A példányok pedig a diákok által megvásárolt könyvek. A példányok létrejöhetnek a rendszer keletkezésekor, vagy más példányok hozhatják
létre.Megszűntetni ellenben minden példány csak önmagát tudja. Ez egyben azt is jelenti, hogy a különböző példányok egyszerre, párhuzamosan léteznek és működnek a rendszerben. 1.13 Absztrakt adattípus Mint azt már a bevezetőben elmondtuk, az SDL absztrakt adattípusokat használ az adatok megadásánál. Teljesen a felhasználóra van bízva, hogy mit ért adat alatt (pl számok, vegyületek, stb.), a lényeg az, hogy absztrakt módon megadja, hogy hogyan kell bánni ezekkel az adatokkal. Az absztrakt mód azt jelenti, hogy nem kötődik a megvalósításhoz, mint ahogy azt a programnyelveknél megszoktuk, hanem csak a típus értéktartományát és műveleteit határozza meg. Az SDL-ben az egész számok (integer) alatt a matematikai értelemben vett egészeket értjük (mínusz végtelentől plusz végtelenig), nem a programozásban megszokott maximum 16 vagy 32 bites ábrázolásukat. 7 Az absztrakt adattípusok használatához első lépésben meg kell
határozni a típusokat. A típusdefiníció a literálokból (decimális számoknál például a leírásukhoz használt számjegyek 0-tól 9-ig, nyelvnél a betűk listája a-tól z-ig), az értékekből (például 0-tól 100-ig terjedő értéktartomány), a műveletekből (összeadás, kivonás, stb.) és azok értelmezéséből (például mit értünk összeadás alatt) áll. A típusdefiníció alapulhat más, már meglévő típus deklarációján, ilyenkor elég, ha a származtatás módját adjuk meg (például az összes gyümölcs közül hogyan származtathatók a csonthéjasok). Természetesen az SDL is tartalmaz előre definiált típusokat (pl. integer, boolean, stb), az ezekhez tartozó típusdefiníciók megtalálhatók a szabványban. Az előre definiált és a felhasználó által deklarált típusokat az SDL teljesen azonos módon kezeli. A definiált adattípusokat a továbbiakban a rendszerben használt változók és jelek deklarálásakor és kezelésekor
használjuk fel. 1.14 Grafikus és szöveges SDL Már említettük a bevezetőben, hogy az SDL-nek kétféle változata van: grafikus (SDL/GR) és szöveges (SDL/PR). A Z.106-os ajánlás (CIF - Common Interchange Format) segítségével kicserélhetővé vált az SDL/GR leírás is a grafikus információk elvesztése nélkül. Ezáltal lényegesen javult az olvashatóság és a specifikáció felismerése különböző környezetekben. Az SDL grafikus és szöveges változata egymással teljesen egyenértékű, egymásba kölcsönösen egyértelműen átalakítható. A grafikus SDL változat szimbólumok és az azokban elhelyezett szövegrészek segítségével specifikálja a rendszert. A statikus leírásban egymásba helyezett „dobozok” adják meg a rendszer felépítését, és a „dobozokat” összekötő „vonalak” a kommunikációs útvonalakat. Az egyes „dobozok” viselkedését folyamatgráffal határozza meg a dinamikus leírás. Mindez szemléletessé és
könnyen érthetővé teszi a specifikációt még kevésbé tapasztalt szakemberek számára is. A szöveges leírás kulcsszavakkal helyettesíti a grafikus szimbólumokat. Emberek számára kevésbé élvezhető ez a forma, viszont gépi feldolgozásra ez az alkalmasabb. Leginkább egy forrásnyelvi programhoz hasonlít, de az „SDL program” kifejezéstől mégis tartózkodunk kihangsúlyozandó a specifikálónyelv és a programozási nyelv közötti alapvető elvi eltérést. A továbbiakban a nyelv elemeinek tárgyalásakor mindig mindkét formát be fogjuk mutatni. A szövegben a kulcsszavakat vastag betűvel fogjuk jelölni A bemutatás során használjuk még a következő jelöléseket: [] {} { }* { }+ | <> a zárójelben lévő rész opcionális; a zárójelben lévő rész szintaktikai elemek egy csoportja; a zárójelben lévő rész többször is megismételhető, de el is hagyható; a zárójelben lévő résznek legalább egyszer szerepelnie kell, de
többször is megismételhető; alternatívák elválasztása; nemterminális szimbólum. 8 2. Alap SDL 2.1 Hierarchikus specifikáció Eddig nem fejtettük ki az SDL azon tulajdonságát, hogy a rendszert az alkotóelemek hierarchikus felépítéseként deklarálja. A hierarchia legfelső fokán az SDL-ben a specifikálandó objektumot teljes egészében jelképező rendszer, vagyis a system áll (2. ábra) Rendszerből csak egy van Mindaz, ami nem tartozik a rendszerhez, annak környezetét (environment) alkotja. Természetesen környezetből is csak egy van. Ráadásul erről a környezetről rendszerünk feltételezi, hogy ismeri az SDL-t, vagyis SDL-szerűen viselkedik. system rendszer block blokk A block blokk A.A process A.A1 block blokk B block blokk A.B process A.B1 process B.1 process B.2 block blokk C process B.3 process C.1 process C.2 process A.B2 2. ábra Az SDL rendszer hierarchikus felépítése A rendszer (system) a továbbiakban blokkokra (block)
bomlik. A blokkok egymással és a környezettel csatornákon (channel) keresztül tartják a kapcsolatot. A blokkok a rendszer keletkezésével együtt keletkeznek és csak egy-egy példány létezik belőlük. Ugyanez vonatkozik a csatornákra is. Egyszerűbb esetben a blokkok (block) processzekből (process) állnak. Bonyolultabb esetben a blokkok alrendszereket (substructure) is tartalmazhatnak, amelyek azután tovább bonthatók blokkokra, majd processzekre, vagy újabb alrendszerekre. Az alap SDL csak az egyszerűbb esettel foglalkozik. A blokkon belüli processzek egymással és a blokkokhoz kapcsolódó csatornákkal jelutakon (signalroute) keresztül kommunikálnak. A processzek keletkezhetnek a rendszer keletkezésekor, de létrehozhatja őket más, már létező processz is. Egyszerre több példányuk is jelen lehet a rendszerben. A processzek a rendszer valóban aktív elemei. Ezek felelnek meg egy-egy kiterjesztett véges automatának, amelynek a viselkedését
folyamatgráf adja meg. A processzek egyidőben, egymással párhuzamosan léteznek és működnek. A működés vagy viselkedés a bemenő jelek feldolgozását jelenti, aminek következménye lehet műveletek végrehajtása, feltételek ellenőrzése, újabb jelek generálása és végül az állapotváltozás. A teljes rendszer viselkedése alatt a processzek együttes viselkedését értjük. 9 A rendszer felépítését kétféleképpen lehet megadni (3. ábra): helyi (local) vagy távoli (remote) módon. A helyi leírásnál minden elemet közvetlenül az előfordulási helyén specifikálunk. Például egy blokk felépítésének leírásakor minden benne szereplő processz viselkedését azonnal megadjuk. Távoli leírásnál csak azt soroljuk fel, hogy egy elem milyen komponensekből áll, de ezek részletes leírását később adjuk meg, erre a referenced kulcsszóval hivatkozunk. Így például, blokkunk definiálásakor elég, ha megadjuk az őt alkotó processzek
listáját a referenced kulcsszóval kiegészítve. Viselkedésüket később is leírhatjuk system rendszer; system rendszer; block A referenced; block B referenced; block A; process A.1; process A.2; block A; process A.1 referenced; process A.2 referenced; block B; process B.1 referenced; process B.2 referenced; block B; process B.1; process B.2; process A.1; process A.2; process B.1; process B.2; 3. ábra Helyi és távoli specifikáció 2.2 A rendszer specifikálása Az absztrakció legfelső szintjén a világ két részre bomlik: a bennünket érdeklő objektumra és a környezetére. Az SDL-ben a hierarchia legfelsőbb szintje jelzi egyben az absztrakció legfelső fokát is. A rendszer (system) jelenti a specifikálandó objektumot teljes egészében, és a környezet (environment) az azt körülvevő világot. A rendszer lehet nyílt vagy zárt, aszerint, hogy létezik-e kapcsolat a rendszer és környezete között, melyek nyílt rendszer esetén a kapcsolatot
ún. csatornákon (channel) keresztül jelek (signal) segítségével tartják A rendszer és a környezet szétválasztásának kritériuma, hogy mit akarunk leírni. Ennek megfelelően a környezetről semmit sem tudunk azon kívül, hogy SDL-szerűen viselkedik és esetleg jelekkel képes kommunikálni rendszerünkkel. Azonban az, hogy hogyan reagál a jelekre, milyen a felépítése stb. teljesen ismeretlen Ezzel szemben a rendszert azért választottuk ki, mert éppen ezeket a tulajdonságait szeretnénk leírni. Tehát a rendszer strukturálható, viselkedése leírható, ami azt jelenti, hogy legalább egy blokkot tartalmaznia kell, amely szintén legalább egy, dinamikusan is leírt processzből áll. Azonban ez utóbbiak az absztrakció miatt nem láthatók rendszerszinten. A rendszer specifikációja a következőkből áll (4. ábra): − a rendszer neve, − rendszerszintű deklaráció, − blokk-kölcsönhatás leírás. 10 system <rendszer neve>
<rendszerszintű deklaráció> <blokk-kölcsönhatás leírás> System <rendszer neve>; <rendszerszintű deklaráció> <blokk-kölcsönhatás leírás> endsystem [<rendszer neve>]; 4. ábra A rendszerspecifikáció felépítése A rendszer nevét a system kulcsszó után kell megadni a rendszerspecifikáció legelején. A rendszerspecifikáció végét az endsystem kulcsszóval kell jelezni, melyet követhet a rendszer neve is. Grafikusan a rendszert egy téglalap (ún keret vagy frame szimbólum) jelöli bal felső sarkában a rendszer nevével a system kulcsszó után. A téglalap élei jelölik a rendszer határait. Az éleken kívül eső részek jelentik a környezetet A rendszerszintű deklaráció több részből állhat. Itt kell megadni a teljes rendszerre vonatkozó adattípusokat, jeleket és jellistákat, makrókat stb. A szöveges formánál az egyes deklarációkat megfelelő kulcsszavak vezetik be és zárják le. Grafikus leírás
esetén ugyanezt a szöveges leírást egy vagy több szöveg (text) szimbólumban kell elhelyezni (5. ábra) Amennyiben a leírás nem fér ki egyetlen oldalra, a rendszer feliratos keret szimbólumot a következő oldalon megismételve újabb szöveg szimbólum(ok)ban folytatható a deklaráció. A szöveg szimbólumra nem vonatkozik semmilyen különleges megkötés, csak ami nyilvánvaló, hogy a hozzátartozó szöveg nem lóghat ki belőle. <deklaráció> 5. ábra Szöveg szimbólum A blokk-kölcsönhatás leírás a blokkokból és az őket egymással és a környezettel összekötő csatornákból áll (6. ábra) A szöveges leírásban a blokkspecifikáció kezdetét a block kulcsszó és a blokk neve jelöli, a végét az endblock és opcionálisan a neve. Távoli megadásnál csak a block kulcsszó, a blokk neve és a referenced kulcsszó szerepelnek a rendszerleírás ezen pontján. A tényleges blokkleírásra a rendszerspecifikáció végén, az endsystem
kulcsszó után kerülhet sor. Itt ugyancsak a block kulcsszóval és a név megadásával kell kezdeni, és az endblock-kal lezárni a leírást. A csatornadeklarációkat a channel kulcsszóval kell kezdeni és az endchannel-lel befejezni. Grafikusan a blokkokat téglalapok jelölik, a csatornákat pedig irányított egyenesek. Távoli leírás esetén a téglalapba csak a blokk neve kerül. Helyi leírásnál a bal felső sarokban kell feltüntetni a blokk nevét a block kulcsszó után, majd a téglalapba bele kell rajzolni a blokk további felbontását: milyen processzekből áll, ezek hogyan kapcsolódnak egymáshoz és a blokk környezetéhez. A blokkkölcsönhatás leírást csak egyetlen lapon szabad elhelyezni Ebből az is következik, hogy bonyolultabb rendszerek megadásánál célszerű a távoli leírási módot alkalmazni. 11 [ . ] system A CH3 [ . ] block X block Y P1 route2 [ . ] [ . ] CH2 route3 route4 P2 route1 [ . ] CH1 [ . ] 6. ábra
Blokk-kölcsönhatás leírás A rendszerszinten deklarált jelek és csatornák vonatkoznak a rendszer környezetére is. Azaz csak azok a jelek és azokon a csatornákon keresztül érkezhetnek a környezettől, illetve küldhetők a környezetnek, amelyeket rendszerszinten deklaráltunk. Összefoglalva a rendszerspecifikáció szabályai a következők: − A rendszernek legalább egy blokkot tartalmaznia kell; − Az SDL előredefiniált típusai rendszerszinten értendők; − A rendszerszinten használt típusokat, jeleket és csatornákat itt kell definiálni; − A rendszerszintű deklarációk érvényesek a környezetre is. 2.21 Jelek deklarációja Az SDL-ben a kölcsönhatás legfontosabb eszköze a jel (signal). A különböző SDL objektumok jelek küldésével és vételével tartják a kapcsolatot más objektumokkal, illetve a környezettel. Maga az SDL szabvány semmiféle megkötést nem tartalmaz a jel típusára, tartalmára, megjelenésére vonatkozóan. Így az
absztrakt típusok felhasználásával tetszőleges jeltípus definiálható, ami tetszőleges számú és struktúrájú paramétert hordozhat. A jeleket a szöveges formátumban a signal kulcsszó után kell felsorolni a nevükkel és az esetleges paraméterek típusaival megadva (7. ábra) Grafikus formánál ugyanez a szöveges deklaráció jelenik meg a szöveg szimbólumban. 12 signal <jel neve> [(típus neve> {,<típus neve>}*)] {<jel neve> [(típus neve> {,<típus neve>}*)]}; signal <jel neve> [(<típus neve> {,<típus neve>}*)] {,<jel neve> [(<típus neve> {,<típus neve>}*)]}; 7. ábra Jel deklarálása Lehetőség van arra is, hogy a jelek egy-egy csoportjának közös hivatkozási nevet adjunk a signallist kulcsszóval. Ekkor a kulcsszó és a listanév után fel kell sorolni a csoportba tartozó jelek nevét. Grafikusan ezt szintén a szöveg szimbólumban kell megadni (8 ábra) signallist
<jellista neve> = <jel neve> {,<jel neve>}*; signallist <jellista neve> = <jel neve> {,<jel neve>}*; 8. ábra Jellista deklarálása Egy WAP-szerverrel való kommunikáció leírásánál jelként deklarálhatjuk a letölthető tartalmat (binárisan kódolt WML formátumban). A jelek, vagyis a kért HTML ill WML oldalak paraméterei lehetnek például, az elérési út, a speciális belső formátumok (html, asp, cgi), illetve letöltésük hány credit-be (virtuális pénzegység) kerülne. Ekkor a HTMLreq { request = kérelem } ill. a WMLreq a jellista, aminek a segítségével szükség esetén hivatkozhatunk az összes lekérhető oldalra. 2.22 Csatornák deklarációja Rendszerszinten a jeleket csatornák szállítják a blokkok között, valamint a rendszer és a környezet között. A csatornák a FIFO elvnek megfelelően működnek, azt a jelet továbbítják először, amelyik előbb érkezett. Ez egyben azt is jelenti, hogy a csatornák
tároló szerepet játszanak az SDL rendszerben, mert a jelek itt várakoznak továbbításukig. Az SDL-ben a csatorna kapacitása végtelen, tehát tetszőleges számú jel halmozódhat fel benne.A csatornák lehetnek egyirányúak vagy kétirányúak, aszerint, hogy csak az egyik vagy mindkét irányban szállítanak-e jeleket. Továbbá késleltethetik a jeleket vagy sem (A nemkésleltető csatornát az 1992-es SDL-ben vezették be.) A késleltető csatornák nemdeterminisztikusan késleltetnek, vagyis előre nem definiált a késés mértéke. A csatornák megadásánál a channel kulcsszó után meg kell adni a csatorna nevét, a kiindulási és a végponto(ka)t a megfelelő blokk(ok) nevével vagy az env (környezet) kulcsszóval a from, illetve a to után, és a megfelelő irányban szállított jelek listáját a with után. Egy csatorna különböző irányainak deklarálásánál ugyanazon két végpontot szabad csak megadni, természetesen felcserélve azokat. A késleltető
(9 ábra) és a nemkésleltető (10 ábra) csatornát a nodelay kulcsszó különbözteti meg az SDL/PR-ben, és a nyílhegyek elhelyezkedése a grafikus SDL-ben. A grafikus ábrázolásban a szögletes zárójel nem az elhagyhatóságot jelöli, hanem az adott irányhoz rendelt jellista grafikus szimbóluma. 13 A csatornák deklarációjánál figyelembe veendő szabályok: 1. Egy csatorna legalább egyik végpontjának blokknak kell lennie 2. A végpontoknak különbözniük kell egymástól [ <jellista> ] < csatorna neve > [ <jellista ] [ jellista ] < csatorna neve > channel <csatorna neve> from <blokk neve|env> to <blokk neve|env> with jellista; [from <blokk neve|env> to <blokk neve|env> with jellista;] endchannel [<csatorna neve>]; 9. ábra Késleltető csatorna deklarálása [< jellista >] < csatorna neve > [< jellista >] [< jellista >] < csatorna neve > channel <csatorna neve>
nodelay from <blokk neve|env> to <blokk neve|env> with jellista; [from <blokk neve|env> to <blokk neve|env> with jellista;] endchannel [<csatorna neve>]; 10. ábra Nemkésleltető csatorna deklarálása Maradva a WAP-szerver példánál késleltető csatornával írható le a WAP Proxy szerepe, feltéve, hogy a letöltési kérelmeket ugyanolyan sorrendben adja le, illetve szolgáltatja vissza a tartalmat, ahogy azt megkapta. Azért késleltető csatorna, mert a Proxy több kérelmet is fogadhat, esetleg a saját belső ügyeit (pl. loggolás, karbantartás) is intézheti menet közben, ami mind a kérelem továbbításának illetve a kért tartalom kiszolgáltatásának idejét növeli. Ezzel szemben pl nemkésleltető csatorna írhatja le ebből a szempontból a közvetlen szerver-kliens kapcsolatot, ahol a kérelmező a Proxy nélkül direktben, a szervertől kéri le az adatokat. 2.23 Példa a rendszerspecifikációra Az eddigiek alapján a WAP
Network rendszert legalább két blokkból építhetjük fel: a WAP Server-ből és a Wireless Network-ből. A kettőt csatorna köti össze: a WAP Proxy, amely egyik irányba a HTML- és WML.req kérelmeket továbbítja, a másik irányba pedig a binárisan kódolt tartalmat küldi meg. A Proxy által továbbítható potenciális kérelmek listájából összeállítható a WAP hálózatunk kérelmi listája (html.req, wmlreq) A WAP Server kapcsolatban áll még a környezettel (env) oly módon, hogy a környezettől kapja a szerveren nem tárolt, külső információkat (Internetről). Ez késleltető csatorna, mert a kérelem kiadása és a kívánt tartalom megérkezése közti időt a külső hálózati forgalom jelentősen befolyásolja. Természetesen az SDL szempontjából ki kell kötnünk, hogy a kérelmek (request) beérkezésének sorrendje és a tartalom-szolgáltatás sorrendjének meg kell egyeznie. A Wireless Network blokk viszont az Interface (kapcsolódási pont)
nemkésleltető csatornán keresztül tartja a kapcsolatot a környezettel: itt lépnek be a felhasználók. A Hálózat rendszerszintű távoli leírását a 11. ábra mutatja be 14 1. példa system WAP Network; signal HTML(Href, credit, PId), WRML(Href, credit, PId), impulse(time), .; signallist Web=HTML.get, WRMLget, CGIget, ASPget, ; signallist HTML.req=HTML, WRML, CGI, ASP, ; signallist WML.req=WML, Credit Info, ; signallist HTML.source=Text, Picture, ; block WAP Sever referenced; block Wireless Network referenced; channel Internet from env to WAP Server with Web; from WAP Server to env with Net HTML.req, Net WMLreq; endchannel Internet; channel Interface from env to Wireless Network with User; /* Bekapcsolódó felhasználó / from Wireless Network to env with User; /* Kilépő felhasználó / endchannel Interface; channel WAP Proxy from Wireless Network to WAP Server with WML.req, HTMLreq; from WAP Server to Wireles Network with Bin Content; endchannel WAP Proxy; endsystem
WAP Network; block WAP Sever; endblock WAP Server; block Wireless Network; endblock Wireless Network; system WAP Network Internet [ Net HTML.req, Net WML.req ] [ User ] Interface [ Web ] WAP Server [ User ] WAP Proxy [ WML.req, [ Bin Content ] HTML.req ] Wireless Network signallist Web=HTML.get, WRMLget, CGIget, ASPget, ; signallist HTML.req=HTML, WRML, CGI, ASP, ; signallist WML.req=WML, Credit Info, ; signallist HTML.source=Text, Picture, ; signal HTML(Href, credit, PId), VRML(Href, credit, PId), impulse(time), .; 11. ábra A hálózatos példa rendszerszintű leírása 15 2.3 Blokk specifikálása A hierarchia következő fokán a blokkszint található. Itt egy-egy blokk belső felépítését kell megadni, vagyis azt, hogy milyen és hány processzből áll, azokat milyen módon kötik össze a jelutak, valamint, hogy a jelutak hogyan kapcsolódnak a blokkhoz vezető csatornákhoz. Szintén itt kell megadni a blokkon belüli típus, jel, jellista stb
deklarációkat A blokkspecifikáció felépítése a rendszerspecifikációéhoz hasonlít (12. ábra): a blokk nevének a block kulcsszó utáni megadásával kezdődik és az endblock-kal zárul, amit szintén követhet opcionálisan a blokk neve. <csatorna neve> block <blokk neve> <blokkszintű deklaráció> block <blokk neve>; <blokkszintű deklaráció> <processz-kölcsönhatás leírás> endblock [<blokk neve>]; <process-kölcsönhatás leírás> 12. ábra A blokkspecifikáció szerkezete A rendszerszintű deklaráció helyen itt a blokkszintű deklaráció következik, amit grafikusan szintén a szöveg szimbólum segítségével lehet megadni akár több oldalon keresztül. Ezt követi a processz-kölcsönhatás leírás, ami a processzek és a jelutak megadásából áll, de a rendszerszinttől eltérően tartalmazza a jelutak és a csatornák kapcsolódási pontjainak specifikációját is. A processz megadását a process
kulcsszót követő név kezdi és az endprocess, valamint az azt esetleg követő név zárja le. Lehetséges a távoli megadás: ekkor a process kulcsszó, a processznév és a referenced kulcsszó kerül csak a blokkspecifikáció adott részére. Ilyenkor a processz részletes leírására a rendszerspecifikáció végén kerül sor. Grafikus leírás esetén a blokk határait az út jelképező téglalap élei jelentik. Távoli megadás esetén a blokk belső struktúrája egy külön oldalra kerül, ahol ugyancsak a keret szimbólum élei választják el a blokk belsejét a környezetétől, azaz a rendszer többi részétől. A processzeket levágott sarkú téglalapok jelképezik. A processz kölcsönhatás leírást egyetlen oldalon kell elhelyezni. A processzek dinamikus leírása láthatatlan a blokkszint számára is csakúgy, mint a rendszerszint számára. Ahogy korábban említettük, a blokkpéldányok a rendszer keletkezésével együtt keletkeznek. Ez nem igaz a
processzekre A processzpéldányok keletkezhetnek a rendszer keletkezésével együtt, de létrehozhatja őket működése során egy másik, ugyanazon blokkhoz tartozó processzpéldány. Ennek pontos módjáról később lesz szó, azonban itt kell megemlíteni, hogy a processzek megadásánál jelezni kell azt, hogy az adott processzből hány keletkezzen a rendszer keletkezésekor, és hogy egyszerre maximálisan hány példány létezhet belőle. Mind grafikus, mind szöveges formátumnál ezt a processznév után zárójelben szereplő két szám határozza meg. Az első azt jelzi, hogy hány példány keletkezik a rendszer keletkezésekor, a második a példányok számát maximalizálja. Amennyiben ezeket az értékeket nem adjuk meg, akkor alapértelmezés szerint, egy példány keletkezik a rendszer létrehozásakor, és nincs korlátozva a példányok száma, tehát akár végtelen is lehet. 16 Formázott A blokkspecifikációra vonatkozó általános szabályok: 1. A
blokkszintű leírásnak tartalmaznia kell legalább egy processz specifikációját, amelynek legalább egy példánya a rendszer keletkezésekor jön létre. 2. Ha egy blokkon belül egyetlen jelút sincs expliciten megadva, minden szükséges jelút impliciten beleértendő a specifikációba. 3. Minden típust, jelet és jellistát, amit blokkszinten használunk és nem a rendszerszinttől örököltünk ezen a szinten kell megadni. 2.31 Jelutak deklarálása A blokkon belüli kommunikáció útvonalait jelutaknak (signal route) hívják. Működésük annyiban tér el a csatornákétól, hogy nem késleltetik a jeleket. A FIFO elv itt is érvényes, azaz a jelek érkezésük sorrendjében kerülnek továbbításra. A jelutak is lehetnek egy- vagy kétirányúak. A jelutakat a signalroute kulcsszó után nevükkel, kezdő és végpontjukkal (processz vagy környezet, amely alatt itt a blokk környezetét értjük), valamint a szállított jelek irányonkénti listájával kell
megadni. A csatornáktól eltérően deklarációjukat nem kell endsignalroute-tal lezárni, ilyen kulcsszó nincs az SDL-ben! A jelutak grafikus ábrázolása megegyezik a nemkésleltető csatornákéval, csupán a hierarchiaszintbeli eltérés különbözteti meg őket egymástól (13. ábra) A jelutakra vonatkozó szabályok: 1. Egy jelút legalább egyik végpontjának processznek kell lennie 2. A jelút két végpontja nem lehet azonos 3. Ha a jelút kétirányú, akkor az irányokat ugyanazon két végpont között, de ellentétes irányban kell definiálni. [< jellista >] < jelút neve > [< jellista >] [< jellista >] < jelút neve > signalroute <jelút neve> from <processz neve|env> to <processz neve|env> with jellista; [from <processz neve|env> to <processz neve|env> with jellista ;] 13. ábra Jelút deklarálása 2.32 Jelutak és csatornák összekapcsolása A csatornák által szállított jeleket a blokkon
belül jelutak továbbítják. Mivel a jelút megadásánál csak a processzek nevét vagy a környezetét lehet megadni, külön konstrukció határozza meg a jelutak csatornákhoz való kapcsolódását. Vigyázni kell azonban, hogy az összekapcsolt objektumoknak irányonként összességükben azonos jeleket kell tudniuk szállítani. Egy csatorna jellistája nem tartalmazhat olyan jelet, amelyet a csatornához kapcsolódó jelutak egyike sem képes továbbítani, illetve fordítva, valamely jelút sem szállíthat olyan jelet, amelyet nem tud továbbítani a jelúthoz kapcsolt csatorna. Szöveges formátumban az összekapcsolást a connect kulcsszó jelzi, amit először a csatorna neve, majd egy and után a hozzá kapcsolt jelutak listája követ. Az összekapcsolást mindig a blokkspecifikációban közvetlenül kell megadni. A grafikai leírásban a blokkhatárt 17 jelképező élen egy pontban kell összekapcsolni a megfelelő csatornát és a jeluta(ka)t. Helyi
leírásnál ebben a pontban végződik a csatornát jelentő egyenes is és a jelutat jelképező is. Távoli leírásnál a blokkon kívül a csatorna nevével kell felcímkézni ezt a pontot (14. ábra) helyi leírás: <csatorna neve> <jelút neve> Connect <csatorna neve> and <jelút neve> {,<jelút neve>}*; távoli leírás: <csatorna neve> <jelút neve> 14. ábra A csatorna és a jelút összekapcsolása Az összekapcsolás szabályai a következők: 1. Egy csatornához legalább egy jelútnak kell kapcsolódnia 2. A csatorna által szállított jelek halmaza irányonként meg kell, hogy egyezzen a hozzá kapcsolódó jelutak által szállítottakéval. Az 1988-as SDL változat szerint még egy jelút csak egyetlen csatornához kapcsolódhatott. Ezt a korlátozást túl szigorúnak ítélték, így az 1992-es változatban már megengedik a csatornák és a jelutak n:m arányú összekötését. 2.33 Példa a blokkspecifikációra
Fejlesszük tovább elkezdett példánkat a WAP hálózatról. A Wireless Network blokkot kétféle processzre lehet bontani: a Manager-re és a Controller-re. A Manager fogadja a klienseket (User) és amennyiben van még üres kapacitás a hálózat vonalai között, akkor ahhoz a line-hoz „rendeli hozzá”. SDL értelmezésben a Manager processz hozza létre a Controller processzt, ami majd a kliens kérelmeit illetve a taralom kiszolgáltatását, a kapcsolati díj számlázását vezérli. Az első User belépéséig Controller processzpéldány nincs a rendszerben. A Manager további feladatai: a request fogadása, az account információk módosítása, és rendezése (payment). A Controller processz így egy jelúttal kapcsolódik a Manager processzhez, ahol a megengedett jelek: a Bin WML.req és Bin HMLreq kérelem lehetséges elemei, amelyeket a WAP Proxy segítségével konvertál és továbbít a Manager a WAP Server-nek (ezeket a jellistákat még rendszerszintről
örököltük); valamint az impulse, payment jelek (melyeket azonban ezen blokk szintjén kell deklarálnunk). A Bin Content tartalmat a felhasználó közvetlenül a WAP Proxy-tól kapja, ezért a Controller processz egy egyirányú jelúttal kapcsolódik a Proxy csatornájához. Még egy fontos megjegyzés: mivel a hálózatunk korlátos kapacitású – a sávszélesség ill. a szerver teljesítménye miatt –, a Controller processzek száma is korlátozott – jelen példában legyen ez 100 példány. Manager processzből azonban csak egy van, de egy mindig kell, hogy legyen, így ez a processzpéldány a rendszer keletkezésekor létrejön. A példa SDL leírását a 15. ábra mutatja be 18 [ Interface ] block Wireless Network [ User ] Logout [ Interface ] signal account(credit), impulse(credit), payment(credit); Login [ User ] Controller(0,100) Manager(1,1) paying [ account ] [ Bin Content ] send content [ impulse, payment, Bin WML.req, Bin HTML.req ] request
content [ Bin WML.req, Bin HTML.req ] 15. ábra A Wirelss Network blokk specifikációja 2. példa block Wireless Network; signal account(credit), impulse(credit), payment(credit); process Manager(1,1) referenced; process Controller(0,100) referenced; signalroute paying from Controller to Manager with impulse, payment, Bin WML.req, Bin HTMLreq; from Manager to Controller with account; signalroute request content from Manager to env with Bin WML.req, Bin HTMLreq; signalroute send content from env to Controller with Bin Content; signalroute Login from env to Manager with User; signalroute Logout from Controller to env with User; connect WAP Proxy and send content, request content; connect Interface and Login, Logout; endblock Wireless Network; 2.4 Processz specifikálása Már sok mindent tudunk a processzekről: ezek az SDL valóban aktív részei, egy-egy kiterjesztett véges automata írja le a viselkedésüket, mely azonban közvetlenül nem látszik sem rendszer-, sem
blokkszinten. A processzek környezetükkel jelutakon és, ha szükséges, csatornákon keresztül kommunikálnak jelek segítségével. Tehát a processznek képesnek kell lennie jelek fogadására és küldésére. Hasonlóan az eddigiekhez, a processzek megadása is két fő részből áll (16. ábra) a processz-specifikáció kezdetét jelző process kulcsszó, processznév, példányszám, formális paraméterlista és a végét jelző endprocess kulcsszó között. 19 process <processz neve> {([<kezd>] , [<max>])] [<formális paraméterek>] <processz-szintű deklaráció> process <processz neve> [([<kezd>],[<max>])]; [<formális paraméterek>]; <processz-szintű deklaráció> <processztest> endprocess [<processz neve>]; <processzgráf> 16. ábra A processz-specifikáció felépítése A példányszámról már esett szó: itt lehet megadni azt, hogy az adott processzből hány példány
keletkezik a rendszer keletkezésekor (<kezd>), és maximum hány létezhet egyidőben a rendszerben (<max>). Mindkét paraméter opcionális, amennyiben hiányoznak, akkor a <kezd> alapértelmezése egy, a <max> alapértelmezése pedig végtelen, azaz a rendszer keletkezésekor létrejön egy példány az adott processztípusból és a példányok száma nincs korlátozva. Az azonos típusú processzpéldányokat nevük alapján nem lehet megkülönböztetni, ezért az SDL interpreter mindenpéldányhoz keletkezésekor egy egyedi azonosítót rendel. Amint az ábrán látható, a processzek deklarálásánál megadható egy formális paraméterlista is, amit az fpar kulcsszó után a változók és típusuk listájával lehet megadni. Ez az egyik módja, hogy kezdőértéket adjunk egy újonnan létrehozandó processz változóinak. Ezeket a kezdőértékeket csak egy másik, már létező processz adhatja át. Amennyiben a processz a rendszer keletkezésekor
jön létre, a formális paraméterek kezdőértéke nemdefiniált. Eddig nem volt szó a változókról. Többek között ezzel az elemmel bővül a processzszintű deklaráció a rendszer- és a blokkszintűhöz képest További bővítések az időzítő (vagy óra) és az eljárásdeklaráció, amelyekről még részletesebben is szólunk. Itt is érvényes, hogy mindent deklarálni kell, amit nem örököltünk rendszer vagy blokkszintről. A processz-specifikációnak viselkedést leíró része teljesen eltér az eddig bemutatottaktól. A viselkedést grafikusan a processzgráffal, szövegesen a processztesttel kell megadni. A kiterjesztett véges automatát megadó hetesnek megfelelően a processztest az állapotok, a be- és kimenetek, a predikátumok és az akciók olyan megadásából áll, hogy az egyben a leképzési függvény legyen. Ugyanezt grafikusan a processzgráf adja meg, amelyben a különböző elemeket különböző szimbólumok jelölik. Ezek egymás utáni
sorrendjét az őket összekötő nyíl határozza meg. Mielőtt részletesen kitérnénk a viselkedést leíró elemekre érdemes pár szót ejteni ismét a típusokról és a példányokról. Mint láttuk az alap SDL-ben rendszer- és blokkszinten nincs érzékelhető különbség a típus deklarációja és a példány leírása között, mivel egy-egy példány jöhet létre minden deklarált típusból, és ez a példány létre is jön a rendszer keletkezésekor. A processz-szinten jelentős a változás, mert itt a típust adjuk meg a rendszer SDL leírásában és ebből a típusból különböző számú példányok jöhetnek létre a rendszer működése során. Ezt a szemléletet fejlesztették tovább az 1992-es SDL-ben a rendszer-, blokk- és processztípus bevezetésével. Itt sokkal élesebben elkülönül a típus és a példány fogalma, a típusok felhasználhatók és tovább finomíthatók a példányok leírásánál. Ennek a pontos módját a Z.100 ajánlás
1992-es verziója tartalmazza 20 2.41 Processz-szintű deklaráció Processz-szinten, csakúgy mint rendszer- és blokkszinten deklarálhatók a jelek, a jellisták és az adattípusok. Erre csak akkor van szükség, ha azokat a felsőbb szinteken nem adtuk meg, vagyis onnét nem örököltük. Ezeken kívül azonban csak a processz-szintű deklaráció tartalmazhat változó- és időzítő-deklarációkat, valamint az érvényes bemeneti jelek halmazának explicit megadását. 2.411 Érvényes bemeneti jelek halmaza Az első, csak a processz-szintű deklarációra jellemző elem az érvényes bemeneti jelek halmaza. Ez az adott processzben értelmezett jelek közül megadja a bemeneti jelek részhalmazát. A processz csak az így (expliciten vagy impliciten) megadott jeleket fogadja el és dolgozza fel. Impliciten az érvényes bemeneti jelek halmaza tartalmazza valamennyi, a processzhez vezető jelút megfelelő jellistáját, amit, ha a processz más jeleket is képes
fogadni, ki kell egészíteni egy, a signalset kulcsszóval kezdődő jellistával. Ez olyankor fordulhat elő, ha például a processz önmagának is küld jeleket, vagy a jelutakat impliciten adtuk meg. Grafikusan az érvényes bemeneti jelek halmazát a már jól ismert szöveg szimbólumban kell megadni az SDL/PR szintaktika szerint (17. ábra) signalset <jel neve> {,<jel neve>}*; Signalset <jel neve> {,<jel neve>}* ; 17. ábra Az érvényes bemeneti jelek deklarálása Nézzünk egy példát, mikor nem egyezik az érvényes jelek halmaza a jelutak jelkészletével. A Wireless Network-ben a User-ek egymás között is beszélgethetnek (nem csak a szerverrel). Azonban a jelút deklarációjának szintaktikai szabályai nem engedik meg, hogy egy jelút kezdő- és végpontja megegyezzen, azaz mindkettő a Controller processz legyen. Ez nem jelenti azt, hogy SDL-lel nem lehet leírni a vendégek egymás közötti kommunikációját. Ilyenkor a felhasználók
üzeneteit hordozó jeleket a signalset segítségével kell megadni. Természetesen a jelek küldésekor expliciten kell megcímezni azt a processzt, amelyiknek szól az üzenet. Ahhoz persze, hogy ezt meg tudja tenni egy processz, ismernie kell a másik címét, azaz „bemutatásnak” kell megelőznie a beszélgetést. 2.412 Adattípusok deklarációja Mint már mondottuk, az absztrakt adattípusokat a sort (nem a type) szó jelzi az SDLben. Egy absztrakt adattípust három dolog megadásával lehet jellemezni Ezek: − a lehetséges értékek vagy az értéktartomány; − a műveletek és azok értelmezése; − a literálok, azaz a különböző értékek jelölési módja. Az SDL grafikus változatában valamennyi adattípus-deklarációt a szöveg szimbólumban kell megadni az SDL/PR szintaxissal egyező módon, ezért itt csak az SDL/PR formával fogunk foglalkozni. A felhasználó életének megkönnyítése érdekében néhány típus deklarációját előre
definiálták, melyek megtalálhatók a függelék 4.11 fejezetében Továbbá valamennyi típusra impliciten értelmezik az egyenlő (=) és a nem egyenlő (/=) műveleteket. 21 Az előre definiált típusok a következők: Típus Natural Integer Real Boolean Típus Character Halmaza Természetes számok [0 , +∞] Egész számok [-∞ , +∞] Valós számok [-∞ , +∞] Két értékű Halmaza ASCII karakter-készlet Literáljai Példa Számjegyek [0,9] 3 Számjegyek [0,9], [-] -3 Számjegyek [0,9], [-], [.] -3045 true | false true Műveletei + - * stb. + - * stb. + - * stb. not,and,or,xor Műveletei < (kisebb), <=, >, >=, = stb. {az ASCII sorszámuk alapján} first (első karakter), last, length, || (összefűzés) stb. Charstring ASCII karakterekből képezhető véges láncok PId Egyedi processzazonosítók halmaza {az interpreter állítja elő} Time {ua. mint a Real-é}, és <, <=, >, >=, időpontot jelent + {időpont plusz időtartam új
időpont}, - {időpont mínusz időtartam új időpont ill. időpont mínusz időpont időtartam} Duration {ua. mint a Real-é}, és >, -, +, és / (osztás), * (szorzás) időtartamot jelent {mely egy időtartam és egy valós szám között van értelmezve} Új t ípu s deklarác ió ja Új típusok deklarálására többféle lehetőség is van: 1. Egy meglevő típus felhasználásával vezetünk be új típust, amely a kiindulási típusnak részhalmaza, vagy bővítése. Erre a newtype, syntype és synonym kulcsszavakkal kezdődő deklarációk szolgálnak. 2. A másik lehetőség, hogy mi írjuk le a típus minden jellemzőjét, amit szintén a newtype kulcsszó vezet be. Mindkét esetben előfordulhat, hogy bizonyos tulajdonságok azonosak a deklarálandó új típusban (például egy mátrix felépítési módjának meghatározása nem függ attól, hogy a mátrixpontokban egészek, valósak, vagy akár karakterek szerepelnek). Erre a célra tartalmazza az SDL a
paraméterezett generator szerkezetet, mellyel általános formában adhatjuk meg az új típus létrehozásának módját. Természetesen vannak előre definiált generátorok is. Ezek a string (lánc), az array (egydimenziós tömb) és a powerset (halmaz), melyek leírása megtalálható a függelék 4.12 fejezetében Az új típus egy már meglévőből való származtatásának legegyszerűbb esete, amikor csak egyes értékeinek szeretnénk külön nevet adni (konstans definiálás). Ezt a synonym kulcsszó után tehetjük meg az új név, az esetleges típus és érték megjelölésével. synonym <konstans neve> [<típus neve>] = <érték> ; 3. példa synonym adokulcs real = 0.25 ; synonym PI real = 3.141592 ; Ezt a módszert jól lehet alkalmazni manapság, mert ha időnként változik az adókulcs, elég csak a leírás elején a típusdeklarációnál kicserélni az új értékre. 22 A következő eset, amikor egy meglévő típus értéktartományát
akarjuk szűkíteni. Ezt legegyszerűbben a syntype szerkezettel tehetjük meg, ami –mint a neve is jelzi- hasonló típust eredményez. Meg kell adni az új típus nevét, a kiindulási típust (szülő) és opcionálisan az alapértelmezést a default, valamint az értéktartományt a constants kulcsszó után. syntype <típus neve> = <szülő típus neve> [default <kifejezés>] [;] [constants <értéktartomány>] endsyntype [<típus neve>]; 4. példa syntype szamlalo = integer default 0; endsyntype szamlalo; Az értéktartomány külön megadására ebben a példában nincs szükség, ha a leírás során mindig csak növeljük a számláló típusú változó értékét. Ha azonban már csökkenteni is akarjuk, akkor célszerű módosítani a deklarációt: 5. példa syntype szamlalo = integer default 0; constants >= 0 endsyntype szamlalo; Szintén hasonló típust eredményez a newtype szerkezet “egyszerűbb” változata. Ennek a szintaxisa
a következő: newtype <típus neve> [<öröklési szabály> | {<paraméterezett generátor> [;] [adding] }+ | struct <mezőlista> [;] [adding] ] <műveletek> [axioms <axiómák>] [ <literálok leképzése>] [default <kifejezés>] [;] constants <értéktartomány> endnewtype [<típus neve>] ; E szerkezet három lehetőséget is magában rejt: 1. Új típusunk származtatható egy már meglévőből, amit az öröklési szabályok megadásával határozhatunk meg. Ezen a módon átalakíthatjuk a boolean típust úgy, hogy ezután ne a true és a false literálokat használja, hanem pl. 0, 1 -et 2. Egy általánosított típusszármaztatási módot (generator) is használhatunk, melynek paraméterei már létező típusok lesznek. Pl a karakterek egydimenziós tömbjét származtathatjuk az array előre definiált generátor segítségével a character, mint tömbelem, és az integer, mint index, típusok felhasználásával.
3. A harmadik lehetőség, hogy a meglévő típusokat egy struktúrában (rekord) egymással összerendeljük. Ekkor az egyes típusok a struktúra (vagy rekord) mezőit képezik A deklarációban megfelelő sorrendben meg kell adni a mezőneveket és a típusokat. Így pl. összerendelhetjük egy személy nevét (charsting típusú) a személyi számával (integer típusú). Mindhárom esetben lehetőség van a régi típusban deklarált műveletek használatára, azok szűkítésére vagy bővítésére, vagy újak definiálására. Az első két esetben az öröklési szabályokat kell megadni, hogy mely műveleteket akarjuk használni az új típusban. Ennek 23 hiányában csak az egyenlő és a nem egyenlő operátor öröklődik. A harmadik esetben (új definiálás) az adding kulcsszó után deklarált műveletekkel bővül az eddig meghatározott készlet, s végül egyszerűen deklaráljuk az új műveleteket a hozzájuk tartozó axiómákkal. A literálok képzése azt
adja meg, hogy hogyan kell a literálok segítségével előállítani a típus különböző értékeit (pl. a 0, 1, 9 számjegyekből a természetes számokat) Az alapértelmezés és az értéktartomány meghatározásának módja azonos a syntype-nál megismerttel. Nagyon fontos, hogy a deklarált új típus különbözik attól a típustól, amelyből származtattuk és azzal nem is tévesztendő össze, például kifejezésekben! Például, ha a credit típust az egészekből származtatjuk, az összeadás és a kivonás két credit típusú változó között lesz csak értelmezve. Ahhoz, hogy a credit típus valóban olyan legyen, mint szeretnénk, újra kell definiálni a szorzás műveletét, hisz ez felel meg a valóságnak. Ezért egy credit és egy integer típusú változó között kell értelmezni a műveletet: 6. példa newtype credit inherits integer (“+”,”-”) adding operators “*” : credit, integer -> credit endnewtype credit; Nézzük egy példát
arra is, hogyan deklarálhatunk absztrakt adattípusokat. Ehhez felhasználjuk a Wireless Markup Language elemeit. Az első típus az element, melyben értelmezhető művelet a go, do, anchor, select, table. Ezekkel a műveletekkel és a WML leírásnak megfelelő elemek segítségével létrehozhatunk egy deck-et. A következő deck típussal pedig létrehozhatunk egy WML deck-et, melyet a wml művelettel hozhatunk létre a head, access, meta, template és card literálokból. 7. példa newtype element literals href, sendreferer, method, accept-charset, type, label, name, optional, title, name, value, iname, ivalue, multiple, tabindex, align, columns, none operators go : <go>,element, element, element, element,</go> -> deck do : <do>, element, element, element, element,</do> -> deck anchor : <anchor>, element,</anchor> -> deck select : <select>, element, element, element, element, element, element, element,</select> -> deck
table : <table>, element, element, element,</table> -> deck /* a none literál lesz a művelet egyik operandusa, ha csak kevesebb element kell / endnewtype ; newtype deck literals none, head, access, meta, template, card operators wml: deck,deck -> deck /* ha csak egy deck kell, akkor a none literál lesz a művelet egyik operandusa, ha viszont több kell, akkor zárójelet kell használni */ endnewtype ; A Z.105 ajánlás definiálja, hogyan kapcsolódik az ASN1 és az SDL, mely tulajdonképpen kibővítése a Z.100-as ajánlásnak A függelék 413 és 414 fejezetei tartalmazzák azokat a típusokat és generátorokat, melyek segítségével használhatók az ASN.1-es adatok és üzenetek az SDL-ben 24 2.413 Változók deklarálása A processz deklarációs részének következő fontos eleme a változók deklarálása. A változó valamely típus egy konkrét értékének a hordozója. A processzen belül használt változókat expliciten deklarálni kell az
adott processz deklarációs részében. A változókat a dcl kulcsszó utáni névvel, típussal és esetleges kezdőértékkel kell megadni. A processz leírása folyamán a változókra alkalmazhatjuk a típusuk szerint megengedett műveleteket, azaz kifejezésekben használhatjuk fel őket. Azonban ez előtt a változónak kezdőértéket kell kapnia, különben dinamikus hiba lép fel. Ezért, ha a változó értéke nemdefiniált a processz keletkezésekor, annak először egy értékadás bal oldalán kell szerepelnie. dcl <változó neve> {,<változó neve>}* <változó típusa> [:= <kifejezés>]; 8. példa dcl a, b integer := 5 ; dcl name charstring ; dcl WML deck deck; 2.414 Időzítő deklarálása Az SDL-ben minden processzhez időzítőtípusokat lehet deklarálni: timer <időzítő neve> [(<típuslista>)] [:= <időtartam>] {, <időzítő neve> [(<típuslista>)] [:= <időtartam>]}*; Mint látható a deklarált
időzítőtípusok lehetnek paraméterezettek és megadható az időzítés alapértelmezés szerinti értéke is. Ha az időzítőtípusnak nincs egyetlen paramétere sem, akkor az adott típusból csak egyetlen időzítőpéldány keletkezik a processzhez rendelve. Ha paraméterezett, akkor minden paraméterérték kombinációra létezik egy órapéldány. Az időzítőpéldány a processzpéldánnyal együtt keletkezik és azzal együtt szűnik meg. Indítás után azzal párhuzamosan fut, és a beállított időtartam leteltével egy jelet küld a processznek, amely megegyezik az időzítőtípus nevével és hordozza az adott példányhoz tartozó paramétereket. Paraméterezett időzítő deklarálása hasznos lehet olyankor, ha különböző célból akarunk időt mérni. Ekkor paraméterben adhatjuk meg, hogy melyik időzítőt mi célból indítottuk Például a hálózatban levő felhasználók valószínűleg egy bizonyos idő elteltével újra elküldenék a kérelmüket,
ha még nem kaptak volna rá addig választ. Ugyanakkor a Manager is figyeli, hogy minden klienst időben kiszolgálnak-e. Ehhez viszont neki jelölnie kell, hogy melyik órával, melyik User várakozási idejét méri. Így a deklarációk különbözőek lesznek a Controller és a Manager processzben: 9. példa Process Manager; timer system clocks (Pid); Process Controller; timer user clock; 25 2.415 Nemformális szöveg Ezzel az alap SDL processz-szintű deklarációjának végére értünk. Meg kell említeni, hogy az SDL szinte mindenhol - ahol adatokat használ – megengedi a nemformális szöveg (informal text) használatát, ami gyakorlatilag megfelel a charstring típusnak. Ez is az absztrakciót szolgálja, hogy magasabb szintű leírásnál ne kelljen elmerülnünk az olyan részletekben, mint a használt változók típusa, jellemzői, mi a feltétel pontos matematikai megfogalmazása stb. Természetesen egy ilyen nemformális szövegeket tartalmazó
specifikációból nehéz lenne megvalósítást készíteni, az automatikus származtatás pedig egyszerűen lehetetlen, mégis sok segítséget nyújt az embernek a leírás kezdeti stádiumában. Az ilyen szövegrészek az SDL specifikáció szerves részei, míg egy programozási nyelvben legfeljebb csak megjegyzésként szerepelhetnek. (lásd 11 és 13 példa) 2.42 A processz viselkedésének specifikálása 2.421 Állapotátmenetek State, input , nextst ate A kiterjesztett véges automata egy adott pillanatban vagy valamely stabil állapotában van, vagy állapotátmenetet hajt végre. A stabil állapot azt jelenti, hogy külső behatás hiányában az automata akár végtelen ideig is ebben az állapotában maradhat. Csak valamely bemenet hatására kezd bele a megfelelő állapotátmenet végrehajtásába. Ennek során döntéseket hozhat, akciókat hajthat végre, kimeneteket generálhat; és végül elér egy újabb stabil állapotot, amelyben ismét addig marad, míg nem
kap újabb bemenetet. Az SDL-ben az állapotot a state kulcsszó vezeti be, melyet az állapot neve követ. Ezután az input kulcsszóval és a jel nevével megadva a lehetséges bemenetek és az általuk kiváltott állapotátmenetek leírása következik. Minden állapotátmenet leírása a következő állapot (nextstate) megadásával fejeződik be. Az állapot leírását opcionálisan az endstate és az állapot neve zárja le. Grafikusan az állapotot és a következő állapotot azonos szimbólum jelöli! A következő állapot szimbólumot a bemenő nyíl különbözteti meg az állapot szimbólumtól. Egy következő állapot szimbólum lehet egyben állapot szimbólum is, ha bemenetek kapcsolódnak hozzá. Az állapot és a bemenet szimbólumok logikai egységet képeznek, ezért őket ún. kapcsolóvonal (association line) köti össze A bemenet szimbólumtól viszont folyamvonal (flow line) - amit nyíl reprezentál – vezet a lehetséges következő állapotokba. Erre
vannak felfűzve a megfelelő predikátumok (decision), akciók (task) és kimenetek (output). A nyíl irányának a jelölése csak a következő állapotot jelölő szimbólumnál kötelező, valamint akkor, ha hiánya félreértésre adhat okot (18. ábra) 26 <állapot neve> <jel neve> [<állapotátmenet>] State <állapot neve>; input <jel neve> [(<paraméterlista>)]; [<állapotátmenet>] nextstate <állapot neve>; [endstate [<állapot neve>];] <állapot neve> 18. ábra Állapot és állapotátmenet Mint az a szintaktikából látszik, a bemenő jelek paramétereket is hordozhatnak. Az input-ban megadott paraméterlistában a jel által hordozott értékeket fogadó változók neveit kell megadni, egymástól vesszővel elválasztva. Ezeket a változókat ezt megelőzően természetesen deklarálni kell a processzben, és típusuknak azonosnak kell lennie a jeldeklarációban az adott pozícióban meghatározott
paraméter típusával. Amennyiben az input-ban nem adjuk meg a jel paramétereit fogadó változókat, a paraméterértékek elvesznek, és a változók nemdefiniáltak lesznek. A paraméterlista lehet hiányos is, ekkor a hiányzó paraméter helyét vesszővel jelöljük, és a lista végén a vesszőket el is hagyhatjuk. Az SDL interpreter a paramétereket és a változókat a sorrendjük szerint fogja megfeleltetni, ezért ügyelni kell arra, hogy a változók megadása sorrendben és típusban egyezzen a paraméterlistával. 10. példa newtype date; endnewtype date; signal person (charstring, integer, charstring, date, date); /* a paraméterek sorrendben a nevet, a személyi számot, a születési helyet, időt és a munkába lépés dátumát jelentik */ dcl ID Num integer, birth place, name charstring, birth date, work start date; input person (name, ID Num, birth place, birth date, work start); /* minden paraméter a megfelelő változóban kerül eltárolásra / input
person (name, , , , work start); /* csak a név és a munkábalépés dátuma került eltárolásra / input person (name, ID Num, , ,); /* helyette írható a következő is: / input person (name, ID Num); Meg kell azt is határozni, hogy egy adott processz keletkezése után mely állapotba kerül, azaz mi(k) a kezdőállapota(i). A kezdő állapot eléréséhez a processz szintén egy állapotátmenetet hajt végre, melynek során döntéseket hozhat, inicializálhat bizonyos változókat, üzeneteket küldhet. Hasonlítható ez a folyamat az autoexecbat lefutásához, amely 27 az általunk megkívánt kezdő környezetet állítja be. Minthogy azonban ezek a kezdő környezetek is lehetnek különbözőek (kollégánk a mi gépünket használva szeretne más shell-t futtatni alapértelmezésként), több kezdő állapot is lehetséges, melyeket a különböző predikátumok határoznak meg (pl. attól függően ki ült le a gép elé és a configsys menüből melyik
menuitem-et választja). A szöveges SDL-ben a processz viselkedésének leírása a start kulcsszóval kezdődik, ami egyben a kezdő állapotba való átmenet kiindulási pontja is. Grafikusan ezt a kezdőpontot a start szimbólum jelzi (19. ábra) [<állapotátmenet>] Start; [állapotátmenet>] nextstate <állapot neve>; <állapot neve> 19. ábra Kezdő állapot megadása Decision A kiértékelendő predikátumot – a kérdést – a decision kulcsszó után kell megadni kifejezés vagy nemformális szöveg formájában. Ezután kell felsorolni a lehetséges válaszokat a hozzájuk tartozó állapotátmenettel. A válaszok egyike lehet az else, mely a felsorolt válaszok uniójának a komplemense, azaz lefedi az összes másik ágakban fel nem sorolt esetet. A válaszok sorát az enddecision kulcsszó zárja le. Grafikusan a decision kulcsszónak egy rombusz felel meg, amely a kérdést tartalmazza. A lehetséges válaszokat a rombuszból kivezető
éleken kell megadni (20. ábra) A válaszok megadásánál a következő szabályokat kell betartani: 1. A kérdésnek és a válaszoknak azonos típusúaknak, vagy nemformális szövegnek kell lenniük 2. Minden decision után legalább két választ kell megadni 3. A válaszoknak egymást kizáróknak kell lenniük 4. A válaszoknak lehetőleg le kell fedniük a kérdés teljes értéktartományát Ezt a feltételt az SDL interpreter nem ellenőrzi, de dinamikus hibát jelez, ha valamely előforduló érték nem szerepel a válaszok között. 5. A válaszok között csak egyetlen else válasz lehet Egy állapotban egy adott input után csak egyetlen decision szerepelhet, amely azonban lehet összetett is, azaz tartalmazhat beágyazott további döntéseket. 28 decision <kérdés>; (<válasz>): [<állapotátmenet>] <kérdés> { (<válasz>): [<állapotátmenet>]}* <1. válasz> <2. válasz> [<állapotátmenet>]
[<állapotátmenet>] (<válasz>)|else: [<állapotátmenet>] enddecision; 20. ábra Döntés (decision) megadása Példák döntésekre: 11. példa decision ‘Is there any credit left?’; (’yes’): nextstate working; else: nextstate log-off; enddecision; 12. példa decision units; (>10): nextstate browsing; (5:10): nextstate paging; else: nextstate display; enddecision; Task Az állapotátmenet során az akciók elsősorban változókon végrehajtott műveleteket jelentenek. Ezeket a task kulcsszó után lehet megadni értékadó kifejezés, vagy nemformális szöveg formájában. Egyetlen task után vesszővel elválasztva több értékadó kifejezés is szerepelhet. Egy adott állapotátmenetben tetszőleges számú task adható meg Grafikusan a task-ot egy téglalapban megadott értékadó kifejezés, vagy nemformális szöveg jelöli (21. ábra). Az értékadást a “:=” jelenti, melynek bal oldalán egy változó, jobb oldalán pedig egy kifejezés
szerepel. A legfontosabb szabály, hogy a változó és a kifejezés típusának meg kell egyeznie. <értékadás> task <változó> := <kifejezés> {, <változó> := <kifejezés>}* ; 21. ábra Task megadása 29 Példák a task alkalmazására: 13. példa task ‘display time’; task x:=5, y:=’SDL’, z:=true; task a:=b+c; Output Az állapotátmenet harmadik fontos eleme az üzenet küldése. A processzek jelek segítségével üzeneteket küldhetnek egymásnak vagy akár saját maguknak is. Ennek egyetlen feltétele, hogy a küldő és a vevő között létezzen olyan kommunikációs útvonal, amely szállítani tudja a feladott jelet. A küldendő jelet az output kulcsszó után, illetve grafikusan a kimenet szimbólumban kell megadni (22. ábra) A legegyszerűbb eset, amikor csak egyetlen olyan útvonal (explicit vagy implicit) létezik, mely szállítani képes az adott jelet. Ilyenkor a címzett processz impliciten meghatározható –nem
lehet más -, ezért elég csak a jelet megadni. Amennyiben azonban több olyan útvonal is létezik, mely szállíthatja a jelet, akkor a címzettet explicit módon kell megadni. Ez kétféleképpen lehetséges: 1. A via kulcsszó után nevével megadható, hogy mely jelúton, illetve csatornán keresztül kell továbbítani a jelet. Ekkor két dologra kell ügyelni: egyrészt a jelút kezdőpontjának a küldő processznek kell lennie, illetve, ha csatornát adtunk meg, léteznie kell olyan jelútnak, mely a processzt és a csatornát összeköti, másrészt a megadott útvonalak jellistájában szerepelnie kell az elküldendő jel nevének. 2. A to kulcsszó után megadható a címzett processz azonosítója, amely minden processzpéldányra egyedi és PId típusú. Az SDL-ben létezik néhány előre definiált kifejezés, melyek processzek azonosítóit adják vissza: • • • • self sender offspring parent a processz saját azonosítója, az utolsó felhasznált jelet
elküldő processz azonosítója, a processz által utoljára létrehozott új processz azonosítója, a processzt létrehozó processz azonosítója. Az output szintaktikája megengedi, hogy utána több küldendő jelet is felhasználjunk. Ez egyenértékű azzal, mintha minden jel elküldése külön output-tal lenne leírva a megadott sorrendben, és a címzett az eredeti via [all] konstrukcióval lenne megadva. Ez azt is jelenti, hogy a listában csak azok a jelek szerepelhetnek, melyek címzettje azonos módon adható meg. Ebből az is következik, hogy egy állapotátmenetben több output is szerepelhet Az 1992-es szabványmódosítás óta mód van a via után az all kulcsszó használatára is. Ez több jel elküldését jelenti, méghozzá ugyanazon jel különböző, az all-t követően megadott címekre való elküldését. Amennyiben a jel elküldésekor a címzett nem egyértelműen meghatározható, vagy a címzett még nem létezik, dinamikus hiba lép fel. 30
<jel neve> [(paraméterlista)] [ via <útvonal>] [to <PId kif.>] Output <jel neve> [(paraméterlista)] {,<jel neve> [(paraméterlista)]}* [via [all] {<jelút neve> {,<jelút neve>}* | <csatorna neve> {,<csatorna neve}*}] [to <PId kifejezés>]; 22. ábra Output megadása Az input-hoz hasonlóan az output-ban is szerepelhet paraméterlista. Itt is a megfelelő paraméterértékeket hordozó változók nevei vagy kifejezések kerülnek be a listába. Az inputnál ismertetett szabályok az output megadásánál is érvényesek: 1. A változónak vagy kifejezésnek és a paraméternek azonos típusúnak kell lennie 2. A lista részben vagy teljesen elhagyható A fel nem sorolt paraméterek értéke nemdefiniált lesz. A kifejezések és a paraméterek sorrendjük és típusuk szerint kerülnek azonosításra. 3. A lista részbeni elhagyásakor a listavégi vesszők is elhagyhatók Valamennyi jel impliciten hordoz egy paramétert,
mely a jel feladóját azonosítja. Ezt a fent említett sender kifejezéssel kérdezheti le a címzett. Példák az output-ra: 14. példa output HTML(“www.taunet”, 10, 1), WML(“server/indexwml”, 5, 1) to line ; /* a line Pid típusú és a megfelelő Controller processzpéldányt azonosítja. Ez a megadás egyenértékű a következő kettővel együttvéve: */ output HTML(“www.taunet”, 10, 1) to line ; output WML(“server/index.wml”, 5, 1) to line ; output user via logout; /* a felhasználó kilép a rendszerből / output payment; 2.422 Eltérések a hagyományos véges automata modelltől Az SDL a kiterjesztett véges automatához képest bővített akciókészlettel rendelkezik. Ezek a processzek létrehozása és megszüntetése, valamint az időzítő vezérlése, állapotának lekérdezése. A FIFO elv megkerülése a save szerkezettel lehetséges Processz létrehoz ása és megszűnése Az SDL-ben egy processzpéldány vagy a rendszer keletkezésével
egyidőben keletkezik, vagy később, az adott blokkban már létező processzpéldány hozza létre. Erre a create kulcsszó szolgál, mely után meg kell adni a létrehozandó processz nevét és az esetleges paramétereit. A processzpéldány csak akkor jön létre, ha az adott típusú példányok száma nem haladja meg a processztípus-deklarációban meghatározott maximális számot. Ha a létező példányok száma már eléri ezt a számot, akkor az SDL interpreter nem hoz létre újabbat, de ez nem okoz dinamikus hibát. Az offspring értéke a “létrehozandó” processzben az SDL interpreter által az új processznek kiosztott PId típusú egyedi azonosító lesz, ugyanez sikertelen létrehozás esetén null lesz. Az offspring-ben mindig csak a legutoljára létrehozott processz azonosítója tárolódik. A létrehozott processzben a parent a létrehozó processz 31 azonosítóját tartalmazza. Természetesen ez a processz élettartama alatt nem változik A rendszer
keletkezésekor keletkező processzekben a parent értéke null. A létrehozást követően a processzpéldányok egymástól függetlenül működnek. Mégegyszer kiemeljük, hogy egy processzt csak az azonos blokkban lévő, de más típusú processzek valamelyike hozhatja létre. Ez egyben azt is jelenti, hogy a létrehozás nem lehet rekurzív. A paraméterlista megadásánál az input-nál és az output-nál ismertetett szabályok az érvényesek. Az új processzpéldány a specifikációjában, a formális paramétereknél jelzett változók kezdőértékeit a létrehozó processz create-ben megadott változóinak pillanatnyi értéke állítja be. Amennyiben a létrehozó processzben az adott változó még nem volt definiálva, az új processz megfelelő változója is definiálatlan lesz. Hasonló a helyzet, ha valamely paraméter nem szerepel a paraméterlistában. A két processz változói között semmilyen további kapcsolat nem áll fenn. Grafikusan a létrehozást mind
a statikus, mind a dinamikus leírás jelzi. A statikus leírásban a létrehozó processztől szaggatott nyíl vezet a létrehozott processzhez (23. ábra) Ez a szimbólum a szöveges leírásban nem jelenik meg. A dinamikus leírásban a create kulcsszónak egy, az alsó és a felső szélén dupla vonalat tartalmazó téglalap felel meg (24. ábra). <létrehozott processz> <létrehozó processz> 23. ábra Processzlétrehozás grafikus jelölése a statikus leírásban <processz neve> [(akt. paraméterek)] create <processz neve> [(<aktuális paraméterek>)] 24. ábra Processz létrehozása (dinamikus leírás) Korábban említettük már, hogy a létrehozott processzek a továbbiakban egymástól függetlenül működnek, tehát a megszűnés nem függ más processztől. Ez a függetlenség azt jelenti, hogy csak kommunikáció révén, jelek küldésével hatnak egymásra. Egy processzpéldány megszüntetheti önmagát, amit a stop kulcsszó,
illetve grafikusan a stop szimbólum jelez (25. ábra) Ennek hatására megszűnik minden, az adott processzpéldányhoz kapcsolódó más típusú példány is, azaz a változók, a jelutak, az időzítők. Az SDL-ben a következő állapoton (nextstate) kívül a stop az egyetlen olyan szerkezet, mellyel egy állapotátmenetet be lehet fejezni. 32 <állapot neve> state <állapot neve>; input <jel neve> [<paraméterlista>]; <jel neve> <állapotátmenet> [<állapotátmenet>] s top; [endstate [<állapot neve>];] 25. ábra Processz megszűnése Összefoglalóként folytatjuk a WAP hálózatról szóló példánkat: A Wireless Network blokkban a Manager processz hozza létre a User jel érkezésekor a Controller processzpéldányokat. A Controller processz kezdő állapota a User felhasználható rendelkezésre álló egységeitől (units) függenek. A processz többféleképpen is befejeződhet: a User megkapja a kívánt WML
vagy HTML tartalmat, de akár meg is szakadhat a kapcsolat, például felhasználói beavatkozás hatására. Mindezek leírásához az eddig bemutatott SDL dinamikus elemek használatára van szükség (26. ábra és 27 ábra): 15. példa process Manager; start; nextstate idle; state idle; input User (units); /* user login / create controller (units); /* reserving the new user / nextstate - ; endprocess Manager; process Controller; fpar units credit; /* a credit tipus a felhasználható egységek számát jelöli / start; decision units; (>10): output HTML to parent; nextstate browsing; (5:10): output WML to parent; nextstate paging; else: output LogTime Info to parent; nextstate display; enddecision; state quit; input account(credit); task units:=units-credit; output payment(credit) to parent; a: /* konnektor, a join a –val lehet rá hivatkozni / output user via logout; stop; endstate quit; endprocess Controller; 33 process Controller fpar units credit; units > 10
5:10 HTML to parent else LogTime Info to parent WML to parent browsing display paging impulse(time) display time quit a account(credit) units:=units-credit payment(credit) to parent a user via logout 26. ábra A példa grafikus leírása 34 process Manager idle User(units) controller(units) - 27. ábra A példa grafikus leírása Join Ha jól átgondoljuk az előző leírást, kiderül, hogy több helyen is ismétlésekbe kell bocsátkoznunk. Ugyanazokat az eseményeket kell többször leírni a Controller processz viselkedésében. Például az elsõ decision utáni ágakban a kiléptetési folyamat több helyen is elõfordul. Az alap SDL erre egy, a programozásban megszokott ugráshoz (goto) hasonló módszert használ. Szintén címkével kell megjelölni az első helyet, ahova ugrani szeretnénk, de az ugrás helyén a join kulcsszóval kell hivatkozni rá. A join használata a folyamatgráfból ered, ahol a folyamvonalak összekötésével ábrázolják az
ilyen ugrást. Ekkor a grafikus ábrázolásban csak implicit címke van. A másik ábrázolási lehetőség a konnektor szimbólumok használata, melyekben, a szöveges formátumhoz hasonlóan, már expliciten kell jelölni a címkét. Ugyanúgy, mint az állapotoknál, a kimeneti konnektor esetén a folyamvonalra ki kell tenni a nyilat, mert ez különbözteti meg a bemeneti konnektortól. A konnektor szimbólumokat lehet olyankor is használni, amikor a viselkedésgráf nem fér ki egy lapra és azt másik oldalon, vagy máshol kívánjuk folytatni (28. ábra) A konnektorok, illetve ugrás használatánál három szabályra kell ügyelni: 1. Csak egyetlen processzen belül szabad ugrani, mert a címke lokális érvényességű 2. A címkéknek egy processzen belül egyedieknek kell lenniük 3. Állapot (state) és bemenet (input) szimbólumok között tilos konnektort használni! 35 itt folyamvonal a join kulcsszó megfelelője <jel neve> [<állapotátmenet
részlet>] [<állapotátmenet részlet>] <állapot neve> Input <jel neve> [<paraméterlista>]; <állapotátmenet részlet> join a; a: <jel neve> a [<állapotátmenet részlet>] [<állapotátmenet részlet>] a itt konnektor a join kulcsszó megfelelője <állapotátmenet> nextstate <állapot neve>; <állapot neve> 28. ábra Ugrás a viselkedés-leírásban és grafikus ábrázolásai Az utolsó szabályt illetően el kell mondanunk, hogy egy állapot leírását több részre is felbonthatjuk úgy, hogy megismételjük az őt jelképező állapot szimbólumot és folytatjuk a bemenetek és a nekik megfelelő állapotátmenetek megadását. Ekkor arra kell vigyázni, hogy a leírásban egy állapot-bemenet pár csak egyetlen egyszer fordulhat elő. Com ment A 28. ábra tartalmaz egy eddig még be nem mutatott, de nagyon hasznos szimbólumot Ez a szövegkiterjesztés vagy megjegyzés szimbólum, ami
magyarázatoknak a grafikus leírásba való beillesztését teszi lehetővé. A megjegyzés szimbólumot szaggatott vonallal kell ahhoz a szimbólumhoz kötni, amelyre a magyarázat vonatkozik. A szimbólumot mind a statikus, mind a dinamikus leírásban egyformán lehet alkalmazni. A szöveges SDL-ben a grafikussal ekvivalens szintaktikájú magyarázatokat karaktersztringenként a comment kulcsszó után lehet megadni. Ez megtehető minden nyelvi egység végén, a pontosvessző előtt. Például: 36 16. példa channel Internet from env to WAP Server with Web from WAP Server to env with Net HTML.req, Net WMLreq; endchannel Internet comment ‘ez egy kétirányú késleltetõ csatorna’; A szöveges formátumban a magyarázatok másik formája: a “/*” és a “/” szimbólumok közötti tetszõleges szöveg. A magyarázatokra semmiféle egyéb korlátozás nem vonatkozik Timer Azt bemutattuk már, hogy hogyan kell deklarálnunk az időzítőket, de használatukról eddig
nem esett szó. Minden processz keletkezésekor, annyi órapéldány keletkezik, ahány deklarálva volt hozzá. Az órák ekkor passzív állapotban vannak Indítás után az órapéldány aktivizálódik és folyamatosan méri az időt. Amennyiben nem állították meg, vagy nem indították újra, a megadott időtartam elteltével egy, a nevével megegyező jelet tesz a processz bemeneti sorába, de továbbra is aktív marad. Az időzítőt csak az általa generált jel felhasználása, vagy a megállítás dezaktiválhatja. Ilyenkor ismét passzív állapotba kerül Az órajel feladója a processz önmaga, vagyis a sender a self értéket szolgáltatja. Az óra indítását a set, megállítását a reset kulcsszóval, nevével és az esetleges paramétereivel kell megadni. Grafikusan mindkettőt a task szimbólummal kell jelölni (29. ábra) Az aktív óra újraindítása megfelel egy közvetlen egymás után végrehajtott reset és set parancsnak. Az indításnál az indítandó
óra nevén és paraméterein túl meg kell adni az időzítés lejártának pillanatát, kifejezés formájában. Ehhez nyújt segítséget a now kifejezés, mely az aktuális időt adja vissza, és melyből megkaphatjuk a kívánt időpontot, hozzáadva az időzítés időtartamát. Az időzítés lejártának pillanata elhagyható, ha az órához volt alapértelmezés deklarálva. Ekkor az időzítés lejártának pillanata az aktuális idő plusz az alapértelmezés. Amennyiben az időzítés lejártának pillanata kisebb vagy egyenlő az aktuális idővel, az óra aktivizálódik és azonnal beteszi a megfelelő jelet a processz bemeneti sorába. A set és a reset szintaktikája a következő: set ([<idő kif.>,] <időzítő neve> [(kif. lista)]) reset (<időzítő neve> [(kif. lista)]) set ( [<időkifejezés>,] <időzítő neve> [(<kifejezéslista>)] ) {,([<időkifejezés>,] <időzítő neve> [(<kifejezéslista>)] ) }*
reset (<időzítő neve> [(<kifejezéslista>)] {,<időzítő neve> [(<kifejezéslista>)]}*) 29. ábra Időzítő vezérlése 37 Az időkifejezés egy Time típusú kifejezés, mely megadja az időzítés lejártának pillanatát. Az időzítő neve után magadott kifejezéslista elemeinek sorrendjük és típusuk szerint meg kell felelniük az időzítődeklarációban paraméterlistaként megadottakkal. Az órával kapcsolatos további lehetőség az időzítő állapotának lekérdezése. Erre taskokban és decision-ökben felhasználható active (<időzítő neve> [(<paraméterlista>)]) kifejezés szolgál, mely true (igaz) értéket ad vissza, ha az óra aktív, és false-t (hamisat), ha passzív állapotban van. Az óradeklarációnál kétféle órát mutatunk be példaként. Az egyiket a Controller processz használja, a másikat a Manager. A Controller elindítja óráját a tartalomkérés elküldésének pillanatában és
megállítja a tartalom megérkezésekor. Amennyiben az időzítés hamarabb lejár, a felhasználó jelzi a hibát a Manager-nek, hogy nem érkezett meg, amit kért. Ennek elkerülésére használja óráit a Manager. Save és im plicit átmenet Ezen alfejezet elején említettük, hogy bár az SDL-ben a csatornák és a jelutak mind FIFO elven működnek, szükség esetén ezt módosíthatjuk, amit a save szerkezet használatával érhetünk el. Ehhez egy kicsit mélyebben bele kell tekintenünk egy SDL processz működésébe. process A process B process C b d c a . state idle; input c, b; nextstate ready; endstate idle; . 30. ábra A processz bemeneti sora Minden jelút, amely a processzhez vezet, a processz egyetlen bemeneti sorába teszi be a szállított jelpéldányokat. A processz valahányszor stabil állapotba kerül, ellenőrzi a bemeneti sorát, és ha ott jelet talál, azt onnét kivesz és feldolgozza (30. ábra) A feldolgozás során ellenőrzi, hogy az adott
állapotban van-e explicit leírás arra vonatkozóan, hogy milyen állapotátmenetet kell végrehajtania a kivett jel hatására. Ha ilyet nem talál, akkor a jel feldolgozását egy olyan állapotátmenet végrehajtására használja fel, melynek következő állapota megegyezik a kiindulásival (azaz amelyben beolvasta a jelet), és nincs hatással a processz egyetlen változójára, paraméterére stb. sem Ez az úgynevezett implicit átmenet Nem kötelező azonban, hogy a jelek feldolgozási sorrendje megegyezzen a bemeneti sorba érkezésük sorrendjével. Például hiába érkezik meg a második kérelemre a válasz a külsõ hálózatról, ha mi elsõként a korábban kért oldallal szeretnénk foglalkozni. Erre az esetre szolgál a save 38 konstrukció. Egy stabil állapotban, ha a bemeneti sor elején olyan jel áll, amely expliciten fel van sorolva, az állapothoz tartozó save kulcsszó után, azt a processz nem veszi ki a sorból, hanem eltárolja. Így az adott
állapotban az elsõ, a save után fel nem sorolt jel feldolgozásával fogja folytatni a működését (31. ábra) Természetesen a save csak az adott állapotra vonatkozik, ha a processz új állapotba kerül és nincs ismét elmentve az első jel, akkor annak feldolgozásával fogja folytatni a működését. Grafikusan a save szimbólumot, mely egy trapéz, az input-okhoz hasonlóan kapcsoló vonallal kell az állapot szimbólumokhoz kötni, mert azzal logikai egységet képez (32. ábra) Egy állapoton belül egy bemenet csak egyszer, vagy egy input-ban vagy egy save-ben szerepelhet. process A process B process C b d c a . state idle; input c, b; nextstate ready; save a,d; endstate idle; . 31. ábra A bemeneti sor tartalmának feldolgozása save esetén <állapot neve> <jel neve> <jel neve> state <állapot neve>; input <jel neve> {,<jel neve>}* ; save <jel neve> {,<jel neve>}* ; [endstate [<állapot neve>];] 32.
ábra Bemeneti jel mentése Nagyon fontos tehát megjegyezni, hogy az állapotoknál expliciten fel nem sorolt jelek, ha a bemeneti sor elején állnak, nem tárolódnak el automatikusan, hanem az implicit átmenet szerint feldolgozásra kerülnek! Ez a lényeges tulajdonsága az SDL-nek, mert így csak teljesen specifikált automatákat lehet vele leírni. Azaz minden állapot-bemenet párra egyértelműen meghatározott, hogy mi történik az automatával. A modellek validálásakor a teljes-specifikáltság a szempont 2.423 A leírást tömörítő formák Az SDL-ben lehetőség nyílik néhány tömör leírási forma használatára. Ezt az implicit szabályok teszik lehetővé. Eddig szó esett már a megfelelő paragrafusokban az implicit címzésről és az implicit átmenetekről. Most bemutatunk néhány további formát, mely 39 tömörebbé teszi a leírást, és amelyet nem szabad figyelmen kívül hagyni a leírás értelmezésekor. Im plicit jelutak Ha egy
blokkspecifikáción belül teljesen elhagyjuk a jelutak specifikációját, azt úgy kell tekintetni, mintha minden szükséges jelút definiálva lenne! A szükségességet a processzek érvényes bemeneti jeleinek halmaza, a kimenetek és a blokkhoz kapcsolódó csatornák jellistái alapján kell megállapítani. Ez a 33 ábra blokkja esetén azt jelenti, hogy az A és B processzek leírása és a C1, C2 csatornák jellistái határozzák meg, hogy mely jelutak léteznek. Ezek alapján a 34. ábra mutatja be, hogy mely útvonalak vannak impliciten definiálva Ha például a C1 jelút szállítaná a “c” jelet, melyet mind A, mind B processz fel tudna dolgozni, akkor egy újabb jelút lenne definiálva a C1 csatorna és a B processz között is. Természetesen a jellisták módosulnának. Azon szabály, mely szerint csak két különböző processztípus között lehet jelutat definiálni, azt jelenti, hogy az azonos típusú processzek kommunikációs útvonalait csak
impliciten lehet definiálni! Ezt az érvényes bemeneti jelek megadásával tehetjük meg. Ilyenkor a kimenetekben expliciten meg kell határozni a címzettet. [ ca ] C1 [ cb ] C2 block blokk process A . signalset ba, ca; . output ab; . process B . signalset ab, cb; . output ba; . 33. ábra A jelutak elhagyása [ ca ] C1 block blokk [ cb ] C2 R1 [ca] process A . signalset ba, ca; . output ab; . R2 [cb] [ba] [ab] R3 process B . signalset ab, cb; . output ba; . 34. ábra A 33 ábra impliciten definiált jelútjai 40 Állapot lista Abban az esetben, ha egy adott bemenet ugyanazt az állapotátmenetet váltja ki több állapotban is, nem kell valamennyi állapotnál külön leírni. Helyette az állapot szimbólumban, vagy a state kulcsszó után felsorolhatjuk azokat az állapotokat, amelyekre érvényes az átmenet. Természetes, ha több bemenet is azonos átmeneteket vált kis, azokat is hasonlóan adhatjuk meg (35. ábra) <állapotlista> State <állapot
neve> {,<állapot neve>}*; [endstate [<állapot neve> {,<állapot neve>}*];] 35. ábra Állapotlista megadása Amikor egy processz valamennyi állapotára vonatkozik a leírt viselkedési gráf, az állapotlistát helyettesíthetjük a csillag (*) karakterrel. A csillag használatánál megengedett egy másik, komplementer megoldás is. A csillag után zárójelben megadható azon állapotok listája is, amelyekre nem vonatkozik az adott viselkedésleírás (36. ábra) * (<állapotlista>) State * [(<állapot neve> {,<állapot neve>})]; [endstate [* [(<állapot neve> {,<állapot neve>}*)] ];] 36. ábra A csillag karakter használata állapotoknál Kötőjeles állapot Képzeljük el, hogy a processz egy adott akciósort egy adott bemenet hatására több állapotában is végrehajthat. Azonban ez nem változtatja meg a processz eredeti állapotát Ezek az akciók mintegy vargabetűt képeznek a processz viselkedésében.
Amennyiben egy állapotátmenet nem eredményez új következő állapotot, hanem marad a kiindulási, ezt jelölhetjük egy kötőjellel (-) a nextstate kulcsszó után, vagy a következő állapot szimbólumban (37. ábra): - state <állapot neve> nextstate - ; 37. ábra A következő állapot megadása kötőjellel Bemenet- és menté slista A save kulcsszó tárgyalásakor már említettük, hogy utána több jel is megadható. Igaz ez az input-ra is. Hatásukban azonban ezek a jelölések eltérőek, amire érdemes külön is felhívni 41 a figyelmet. Míg az input csak egy, a listában szereplő, és a processz bemeneti sorának legelején álló jel felhasználását jelenti, addig a save hatása azokra terjed ki, melyek szerepelnek a listájában és a processz bemeneti sorának elején az első, a listájában nem szereplő jelig helyezkednek el (38. ábra): process C b d c . state idle; input c, b; nextstate ready; endstate idle; . a process C b d c a .
state idle; input c, b; nextstate ready; save a,d; endstate idle; . 38. ábra A bemenetlista és a mentéslista hatásköre Az állapotokhoz hasonlóan az input és a save esetén is használható a csillag karakter, mely mindkét esetben az adott állapotnál még fel nem sorolt érvényes bemenetek listáját jelenti (39. ábra) Egy adott állapotnál nem szabad egyszerre használni a save * és az input kifejezéseket. * * state <állapot neve>; input * ; [endstate [(<állapot neve>)];] state <állapot neve>; sa ve * ; [endstate [* (<állapot neve>)];] 39. ábra A csillag karakter használata bemenetnél és mentésnél Kimenetlista Az output használatának leírásakor már részletesen foglalkoztunk a kimenetlistával A legfontosabb eltérés, hogy output után nem szabad használni a csillag karaktert! A másik eltérés, hogy az output után felsorolt jelek mindegyikét elküldi a processz a címzetteknek. 42 3. Az alap SDL kiterjesztése
Bonyolult rendszerek leírásához az alap SDL hierarchiájának három szintje kevésnek bizonyulhat, ezért a kiterjesztésben ezek a szintek tovább oszthatók. Erre szolgálnak a rendszer- és blokkszinten definiálható alrendszerek (substructure), valamint a processzen belül definiálható szolgálatok (serveice). További strukturálást tesznek lehetóvé a makrók és az eljárások. Ebben a fejezetben elsősorban ezekről a bővítésekről lesz szó, majd kitérünk más jelekkel kapcsolatos, valamint a nemdeterminisztikus viselkedés leírását lehetővé tevő kiterjesztésekre is. 3.1 A hierarchia szintek számának növelése 3.11 Kombinált és particionált blokkdeklarálás A különböző absztrakciós szintek ábrázolásának az egyik legérdekesebb módja a kombinált blokkdeklaráció (combined block specification). Azért hívják kombináltnak, mert egyszerre tartalmaz processz-szintű leírást és blokkalrendszer-deklarációt (block substructure) (40.
ábra) Értelmezése a következő: Az absztrakció adott szintjén az adott blokk működése felfogható a processzkölcsönhatás leírásnak megfelelően. Ezt a processz-szintű leírás adja meg Azonban ez, ha közelebbről megvizsgáljuk a rendszer viselkedését, tovébb is részletezhető. Ezt tartalmazza a blokkrendszer-deklaráció. Azaz a processz-szintű és a blokk-alrendszer egymással vagylagos viszonyban van. Attól függően, hogy az absztrakció mely szintjén kívánjuk specifikálni a rendszert az egyiket, illetve a másikat kell figyelembe venni. Az SDL leírás interpretálása során csak az egyik verzió lesz értelmezve. < csatorna neve > block <blokk neve> <blokkszintű deklaráció> <processz-kölcsönhatás leírás> block <blokk neve>; /* kombinált blokkdeklaráció / <blokkszintű deklaráció> <processz-kölcsönhatás leírás> <blokkalrendszer-deklaráció> endblock [<blokk neve>];
<blokkalrendszer-deklaráció> 40. ábra Kombinált blokkdeklaráció Az elmondottaknak megfelelően a kombinált blokkdeklaráció csak ott szerepelhet, ahol a processz-kölcsönhatás leírás, azaz valamely bokkon belül. 43 Néhány további figyelembe veendő szempont: 1. A blokk-alrendszer külső kapcsolatai (interfészei) azonosak az őt tartalmazó blokk interfészeivel. 2. A blokk-alrendszer neve megegyezhet az őt tartalmazó blokk nevével Az első pont különös figyelmet érdemel a felhasználó részéről a specifikáció elkészítése során, mivel neki kell gondoskodnia arról, hogy a blokk bármelyik interpretációja képes legyen kommunikálni a blokk környezetével. Ez még azt is eredményezhet, hogy a két verzió eltérően fog viselkedni, mert a részletes leírás során kitérhetünk olyan funkciókra, amelyek az absztrakció magasabb szintjén rejtve maradnak a szemlélő előtt. Ilyen funkció lehet például a processzek címzése. A
blokkalrendszer-deklaráció a substucture kulcsszóval és az alrendszer nevével kezdődik és az endsubstructure kulcsszóval, valamint a azt opcionálisan követő névvel fejeződik be. Természetesen megengedett a távoli leírás, ekkor a referenced kulcsszót kell használni a blokkdeklarációban. A grafikus ábrázolásban a blokk-alrendszert is egy téglalap jelöli. A blokk-alrendszer kapcsolatai nincsenek feltüntetve az őt tartalmazó blokkban, hiszen interpretációja során ennek helyére kell behelyettesíteni. Vegyük ismét a WAP Network példáját. Eddig a Wireless Network blokkot elemeztük, most vessünk egy pillantást a WAP Server blokkra, méghozzá először a felhasználó, aztán a szerver-üzemeltetője szempontjából. A felhasználó szempontjából a WAP Server működése egyszerűen megadható: a Server felfogható mint egyetlen processz, mely a WAP Proxy csatornán keresztül érkező jelek hatására, melyek a kérelmeket tartalmazzák, bizonyos
idő elteltével jeleket küld szintén a Proxy útján, melyek a kívánt tartalmat adják. Nemígy a szerver-üzemeltetője szempontjából. Számára a WAP Server egy bonyolult rendszer, mely további blokkokból és processzekből áll, például megkeresni ill. előállítani a kért oldalakat saját szerverről, ha ott nincs, akkor az Internet más szervereiről letölteni E két szemlélet jól tükrözhető egyetlen SDL leírásban is. Ehhez az üzemeltető szempontjából a WAP Server-t egy alrendszerként fogjuk fel (41. ábra) 18. példa block WAP Server; process Server process; signalroute Gateway from env to Server process with HTML.req, WMLreq; from Server process to env with Content; signalroute Internet Gateway from env to Server process with Web; from Server process to env with Net HTML.req, Net WMLreq; connect Gateway and Wap Proxy; connect Internet and Internet Gateway; substructure WAP Server referenced; endprocess Server Process; endblock WAP Server; 44 WAP
Proxy block WAP Server [ Content ] Gateway [ HTML.req, WML.req ] WAP Server Server process [ Web ] signallist Net WML.req=WML, ; signallist Net HTML.req=HTML, VRML, CGI, ASP, .; Internet Gateway [ Net HTML.req, Net WML.req ] Internet 41. ábra A WAP Server blokk leírása A blokkspecifikáció tartalmazhatja kizárólag a blokk további felosztását deklaráló blokk-alrendszer leírást is. Ezt particionált blokkdeklarációnak (partitioned block specification) hívják. Ennek célja kifejezetten a rendszer több hierarchia szintre bontása Hasonlóan a kombinált blokkdeklarációhoz, az alrendszert a blokk helyére kell behelyettesíteni, a grafikus ábrázolásnál ezt akár azonnal is megtehetjük az alrendszer kiemelése nélkül, ahogy ezt a blokkalrendszer-deklarácó tárgyalása után majd bemutatjuk (44. ábra). 3.111 Blokk-alrendszer deklarálása A blokk-alrendszer deklarálása szintaktikailag szinte teljesen megegyezik a rendszerdeklarálás módjával (42.
ábra) Az egyetlen eltérés abbül adódik, hogy míg a rendszer környezetének felépítését nem ismerjük, addig a blokk-alrendszerét igen. Tehát meg kell adni a rendszeren belüli és a külső csatornák kapcsolódását. Erre szintén a connect kulcsszót kell használni, ahogy ezt a csatornák és a jelutak összekapcsolásánál tettük. Az alrendszeren belüli csatornákat alcsatornáknak is szokás hívni. A követendő szabályok: 1. Minden külső csatornának kapcsolódnia kell legalább egy alcsatornához 2. Egy csatlakozási ponton a külső és a belső csatornák által hordozott jelek halmazának irányonként meg kell egyeznie. A külső és belső csatornák n:m kapcsolási aránya csak az 1992-es SDL verzió szeint lehetséges. A korábbi verziók egy alcsatornának csak egyetlen külső csatornához való kapcsolását engedték meg. 45 substructure <alrendszer neve> <alrendszerszintű deklaráció> substructure <alrendszer neve>; /*
alrendszerdeklaráció / <alrendszerszintű deklaráció> <blokk-kölcsönhatás leírás> endsubstructure [<alrendszer neve>]; <blokk-kölcsönhatás leírás> 42. ábra Alrendszer deklaráció Példaként nézzük meg WAP Server alrendszer egy lehetséges megadását. A WAP Server két részből áll: az első rész a HTML szűrésével foglalkozik, míg a második WML Server feladatokat lát el (43. ábra) A 44. ábra a WAP Server blokk particionált blokk-alrendszerének kétféle grafikus ábrázolását mutatja be. 19. példa substructure WAP Server; block HTML Filter referenced; block WML Server referenced; channel HTML Gateway from env to HTML Filter with HTML.req; from HTML Filter to env with Content; endchannel HTML Gateway; channel WML Gateway from env to WML Server with WML.req; from WML Server to env with Content; endchannel WML Gateway; channel Internet Gateway HTML from env to HTML Filter with Web HTML; from HTML Filter to env with Net
HTML.req; endchannel Internet Gateway HTML; channel Internet Gateway WML from env to WML Server with Web WML; from WML Server to env with Net WML.req; endchannel Internet Gateway WML; connect WAP Proxy and HTML Gateway, WML Gateway; connect Internet and Internet Gateway HTML, Internet Gateway WML; endsubstructure WAP Server; 46 WAP Proxy substructure WAP Server WAP Proxy [ Content ] [ Content ] HTML Gateway WML Gateway [ HTML.req ] [ WML.req ] HTML Filter WML Server [ Web HTML ] Internet Gateway HTML [ Web WML ] Internet Gateway WML [ Net HTML.req ] Internet [ Net WML.req ] Internet 43. ábra A WAP Server blokk-alrendszer block WAP Server WAP Proxy substructure WAP Server WAP Proxy [ Content ] [ Content ] HTML Gateway WML Gateway [ HTML.req ] [ WML.req ] HTML Filter WML Server [ Web HTML ] Internet Gateway HTML [ Web WML ] Internet Gateway WML [ Net HTML.req ] Internet WAP Proxy block WAP Server [ Net WML.req ] Internet WAP Proxy [ Content ] [
Content ] HTML Gateway WML Gateway [ HTML.req ] [ WML.req ] HTML Filter WML Server [ Web HTML ] Internet Gateway HTML [ Web WML ] Internet Gateway WML [ Net HTML.req ] Internet [ Net WML.req ] Internet 44. ábra Partícionált blokk-alrendszer kétféle megadása 47 3.12 Csatorna-alrendszer deklarálása A hierarchia szintek növelhetők csatorna-alrendszer (channel substructure) alkalmazásával. A csatorna-alrendszer egy csatorna működésénak a részletes kifejtése Tehát ezzel a módszerrel is a rendszerleírás egy alacsonyabb absztrakciós szintjére lépünk, ami egyre jobban közelíti a megvalósítást, illetve a valóságot. Csatorna-alrendszer deklarálható a rendszerben bárhol, ahol csatorna deklarálható. Deklarációja is a csatornadeklaráció (channel) része, amely természetesen lehet távoli leírásra való hivatkozás. A csatornadeklaráció végén, az endchannel kulcsszó előtt kell megadni szintén a substructure kulcsszóval az adott
csatorna részletesebb leírását, vagy az arra való hivatkozást. Grafikusan a csatorna-alrendszert szintén egy téglalap jelöli, amit szaggatott vonal köt össze a megfelelő csatornával (45. ábra) Ebből az ábrázolásból egyenesen következnek a legfontosabb szabályok: 1. A csatorna-alrendszer interfészei megegyeznek a csatorna interfészeivel, tehát legfeljebb két külső kapcsolata lehet (blokk vagy környezet), irányonként egy. 2. A csatorna-alrendszer neve megegyezhet a csatorna nevével, amelynek leírását tartalmazza. 3. A csatorna-alrendszer által elfogadott jelek halmaza meg kell egyezzen a csatorna által szállított jelekével. <csatorna neve> [.] [.] <csatorna-alrendszer> channel <csatorna neve>; from {env|<blokk neve>} to {env|<blokk neve>} with <jellista>; [from {env|<blokk neve>} to {env|<blokk neve>} with <jellista>;] substucture <alrendszer neve> referenced; endchannel [<csatorna
neve>]; 45. ábra Csatorna-alrendszer távoli deklarációja A csatorna-alrendszer deklarálásának módja azonos a blokk-alrendszer deklarálásával (42. ábra) Egyetlen helyen van eltérés a kettő között, mégpedig a csatornák összekapcsolásánál, ahol a külső csatorna neve helyett a megfelelő blokk nevét kell megadni. Mivel a csatorna-alrendszer lehet egy olyan csatorna kifejtése is, amely a rendszerkörnyezetet és valamely blokkot köti össze, így a connect kulcsszó után megengedett az env környezetet jelölő kulcsszó is. A rendszerspecifikáció interpretálásakor a csatorna-alrendszer mindig kifejtendő, tehát nem áll fenn olyan vagylagos viszony, mint azt megfigyelhettük a kombinált blokkalrendszernél. A szemléletesség kedvéért nézzük meg, hogy hogyan lehet kifejteni a példánkban szereplő WAP Proxy csatornát, mely a WAP Server és a Wireless Netwok között van. Az absztrakció adott szintjén számunkra megfelelt az egyszerű
csatornadeklaráció, de ha részletezni szeretnénk a Proxy által elvégzett feladatokat, akkor ezt már alrendszernek tekinthetjük. Ezt továbbra is egyetlen blokként írnánk le, ahogy azt a 46 ábra mutatja 48 20. példa system WAP Network; channel WAP Proxy from Wireless Network to WAP Server with WML.req, HTMLreq; from WAP Server to Wireless Network with Bin Content; substructure WAP Proxy referenced; endchannel WAP Proxy; endsystem WAP Network; substructure WAP Proxy; block Encoder referenced; block Decoder referenced; channel operator e from env to Encoder with Content; endchannel operator e; channel client e from Encoder to env with Bin Content; endchannel client e; channel operator from Decoder to env with WML.req, HTMLreq; endchannel operator; channel client from env to Decoder with Bin WML.req, Bin HTMLreq; endchannel client; connect WAP Server and operator e, operator; connect Wireless Network and client e, client; endsubstructure WAP Proxy; system WAP Network
Internet [ Net HTML.req, Net WML.req ] [ User ] Interface [ Web ] [ User ] [ Bin Content ] WAP Server [ WML.req, HTML.req ] Wireless Network WAP Proxy signal . WAP Proxy substructure WAP Proxy WAP Server WAP Server [ Content ] operator e operator [ WML.req, HTML.req ] Encoder Decoder [ Bin Content ] client e client [ Bin WML.req, Bin HTML.req ] Wireless Network Wireless Network 46. ábra A WAP Proxy alrendszer 49 3.13 Jeldeklaráció finomítása A rendszerleírás egyre mélyebb részletezésével előfordulhat, hogy az adott szinten már nem megfelelőek, nem hordoznak eléggé részletes információt, a magasabb szinten deklarált jelek. Az SDL-ben ezekre az esetekre dolgozták ki a jeldeklaráció finomításának technikáját, ami a jelek hierarchiáját eredményezi. Ez a hierarchia azonban nem azt jelenti, hogy egy összetett jelet komponenseire bontunk, hanem hogy egy tetszőleges jelet behelyettesítünk egy alacsonyabb hierarchiaszinthez tartozó
jelkészlettel. Ezeket a jeleket a behelyettesített jel aljeleinek hívjuk. Az aljelek akár ellentétes irányúak is lehetnek a behelyettesített jelhez képest. Jeldeklaráció finomításra a különböző absztrakciós szintek találkozási pontjain van lehetőség, azaz amikor azok kommunikációs útvonalai között megteremtjük a kapcsolatot. Ilyen szintek a - rendszerszint, - blokkszint, - blokkalrendszer-szint, - csatornaalrendszer-szint, - processz-szint. A jeldeklaráció finomításakor a signal kulcsszó után meg kell adni, hogy melyik jelet kívánjuk felbontani, majd a refinement kulcsszó után az aljelek készletét a jeldeklaráció szintaxisa szerint (lsd. 221) Ha az aljelek között van ellentétes irányú is, azt a reverse kulcsszó után kell deklarálni. A jelfinomítást az endrefinement kulcsszó zárja le Grafikusan a jeldeklaráció finomítást is a szöveg szimbólumban kell a szöveges formátummal egyező formában megadni. signal <jel neve>
[<típuslista>] refinement {[reverse] <jeldeklaráció>}+ endrefinement {, <jel neve> [<típuslista>] refinement {[reverse] <jeldeklaráció>}+ endrefinement}*; 3.14 Processz szolgálatokra való felbontása A hierarchiaszintek számának növelése eddig úgy történt, hogy a rendszerspecifikáció egy-egy részletét jobban kidolgoztuk, mintegy nagyító alá vettük. A teljes rendszerleírás ettől egyre terebélyesebb lett, mert a kidolgozott részek általában növelték a rendszerben párhuzamosan működő processzek számát. A rendszerleírás a processz-szint elérése után is tovább finomítható szolgálatok (service) deklarálásával, ami a processztest egy alternatív leírási módját jelenti. Ez azonban már nem jár a rendszer növekedésével, mert a szolgálatok egymás után, sorban aktivizálódnak, mint a processz alkotóelemei. A szolgálatok is kiterkesztett véges autómaták, viselkedésük leírása teljesen analóg a
processz viselkedésének leírásával. A működés során azonban egy processz szolgálatai közül egyszerre mindig csak egyetlen szolgálat hajt végre állapotátmenetet, szemben a processzekkel, melyek egymással párhuzamosan működnek. Egy processz szolgálatokra való felbontásakor a processzspecifikációban a processztestet kell behelyettesíteni a szolgálat-kölcsönhatás leírással, valamint a szolgálattest leírásokkal. Grafikus leírás esetén a processzgráfot kell behelyettesíteni a szolgálatkölcsönhatás leírással és a szolgálatgráfokkal Természetesen mindkét esetben megadhatunk távoli specifikációt (47. ábra) 50 <jelút neve> process <processz neve> [([<kezd>],[<max>])] [formális paraméterek] <processz-szintű deklaráció> process <processz neve> [([kezd], [<max>])] [<formális paraméterek>]; <processz-szintű deklaráció> <szolgálat-kölcsönhatás leírása> endprocess
[<processz neve>]; <szolgálat-kölcsönhatás leírás> 47. ábra Szolgálatok deklarálása a processz specifikációban A processz-kölcsönhatás leírás megadja, hogy az adott processzt milyen szolgálatokra bontottuk fel, és azok között milyen kapcsolatok állnak fel. A szolgálatot jelölő grafikus szimbólumot (ellipszis) a 48. ábra mutatja be A szolgálatok közötti jelutak szintaxisa és működése azonos a processzek között használtakéval. A szolgálatszintű jelutakat is a connect kulcsszó segítségével kell a processz-szintű jelutakhoz kapcsolni. A processzen belül, szolgálatszinten csak akkor deklarálhatók jelutak, ha a processzt tartalmazó blokkon belül deklaráltunk jelutakat. <szolgálat neve> service <szolgálat neve> referenced; 48. ábra Szolgálat jelölése Egy processz szolgálatai számára a parent, offspring, sender és self kifejezések ugyanazt az értéket adják vissza. A szolgálatok között kétféle
kommunikáció lehetséges: a processz változóin keresztül, melyek közösek valamennyi szolgálat számára, vagy belső jelutakon keresztül belső jelek segítségével. Egy processz szolgálatai a külvilág felé a közös jelutakon keresztül kommunikálnak, melyek a processz külső kapcsolatai, továbbá közös a bemeneti soruk, mely a processz bemeneti sora. A belső jel címzettje és feladója egyaránt a processz önmaga (a sender értéke self). Az egyes szolgálatokat nem lehet külön-külön megcímezni, így a bemenet típusa dönti el, hogy éppen melyik szolgálat aktivizálódik. Ezért a deklarálásnál vigyázni kell arra, hogy a szolgálatok bemeneti halmazai diszjunktak legyenek. Az aktivizált szolgálat következő stabil állapota eléréséig marad aktív, azután passzívvá válik. Azt, hogy ezután a processz melyik szolgálata aktivizálódik a következő feldolgozásra kerülő bemeneti jel fogja eldönteni. Az egyes szolgálatokat nem lehet
létrehozni. A processzpéldánnyal együtt keletkeznek, mint annak alkotóelemei. Viszont a szolgálatok önmagukat szüntetik meg Ha egy processz minden szolgálata megszűnt, a processz is megszűnik. Amennyiben egy szolgálat megszűnt, a hozzá tartozó jeleket a processz eldobja. A szolgálatok specifikációja - mint mondottuk -, teljesen analóg a processzek specifikációjával. A deklaráció részben definiált változók stb lokálisak, így a processz és más szolgálatai számára láthatatlanok. A szolgálatok működését szintén viselkedésgráffal, illetve annak szöveges formájával kell megadni (49. ábra) 51 service <szolgálat neve>; <szolgálatszintű deklaráció> service <szolgálat neve>; <szolgálatszintű deklaráció>; <szolgáalttest>; endszevice [<processz neve>]; <szolgálatgráf> 49. ábra Szolgálat specifikáció felépítése Az SDL korábbi verzióiban (1988-asig bezárólag) a belső,
szolgálatok közötti jelek prioritást (priority input) élveznek valamennyi külső, más processztől érkező jellel szemben, így azok előtt kerültek feldolgozásra, elküldésüket a priority output-tal kell megadni. Az 1992-es SDL-ben ezek jelentése megváltozott: a priority input-ot kiterjesztették valamennyi jelre, tehát nemcsak a belső jelek kaphatnak prioritást. A priority output-ot törölték, helyette az output to self kifejezést kell használni. A grafikus szimbólumokat ugyan meghagyták, de használatukat új specifikációkban nem ajánlják (50. ábra) priority input <bemenetlista>; priority output <jel neve> [(<paraméterlista>)] {, <jel neve> [(<paraméterlista>)]}*; 50. ábra Prioritásos bemenet és kimenet A WAP Network rendszer példánkban érdemes lehet szolgálatokra felbontani a Manager munkáját. Feladata több jól körülhatárolható részre bontható: a bekapcsolódó kliensek fogadása, szabad kapacitás
allokálása (lefoglalása) az adott felhasználó számára – amennyiben egyáltalán még képes kiszolgálni őket ( # < 100) - ; továbbá a kérelmek közvetítése (összegyűjtésük), valamint a credit megfelelő rendezése. Mivel egyetlen Manager processzpéldány létezik csak, így teljesül az a feltétel is, hogy mindig csak egyetlen szolgálat lesz aktív. Példánkban az egyszerű megértés kedvéért csak két szolgálatot deklaráltunk: az allocation-t, mely a kliens bekapcsolódásakor létrehozza az új Controller processzt és átadja a counting szolgálatnak az új azonosítót. Erre a counting új „számlát” nyit, ahova feljegyzi az igénybe vett szolgáltatások “díját”. 52 21. példa process Manager; signal line (PId); service allocation referenced; service counting referenced; signalroute login route from env to allocation with User; signalroute paying route from env to counting with impulse, payment, Bin WML.req, Bin HTMLreq; signalroute
request content route from counting to env with Bin WML.req, Bin HTMLreq; signalroute new from allocation to counting with line; connect paying and paying route; connect request content and request content route; connect login and login route; endprocess Manager; service allocation; start; nextstate wait; state wait; input User; create Controller; output line (offset) via new; nextstate wait; endstate wait; endservice allocation; service counting; newtype tomb array (inteder, PId); endnewtype tomb; dcl id PId; dcl units credit; start; nextstate sign in; state sign in; input ; input ; input ; endstate sign in; endservice counting; 53 Login process Manager (1,1) login route paying [ User ] paying route new counting [ impulse, payment, Bin WML.req, Bin HTML.req ] [ line ] request content route allocation signal line(PId); [ Bin WML.req, Bin HTML.req ] request content 51. ábra A Manager processz felbontása szolgálatokra 3.2 Eljárások, makrók Szintén a
rendszerspecifikáció strukturálását, de nem a hierarchiaszintek számának növelését teszik lehetővé az eljárások (procedure) és a makrók (macro). 3.21 Eljárások deklarálása Az SDL eljárások nagyon hasonlítanak a programozási nyelveknél használatosakhoz. Olyankor célszerű eljárást definiálni, amikor a processztest egy része többször is ismétlődik. Ily módon csak egyetlenegyszer, paraméterezett formában kell megírni a processz viselkedésének ezen részletét - ez az eljárás -, majd a szükséges helyeken meghívni. Az eljárásdeklarációt a procedure kulcsszóval és az eljárás nevével kell kezdeni. Távoli leírásnál az eljárás neve után a referenced kulcsszóval hivatkozhatunk az eljárás részletes leírására (52. ábra) <eljárás neve> procedure <eljárás neve> referenced; 52. ábra Eljárás hivatkozása 54 Az eljárás nevét követően az fpar kulcsszó után meg lehet határozni a formális
paramétereket, amelyeksegítségével meghíváskor aktivizálhatjuk az eljárást. Ehhez szükséges a paraméter neve, típusa és az, hogy bemenő (in), vagy be- és kimenő (in/out) paraméter-e. A bemenőként definiált paraméterek lokálisak, azaz értékük az eljárás befejezésekor elvész, míg a be- és kimenő paramétereké átadódik a hívónak. Alapértelmezés szerint a formális paraméterek bemenők, ezért elhagyható az in kulcsszó. Az 1992-es szabványban egy további lehetőséget is deklaráltak, mégpedig azt, hogy az eljárás egy értéket adhat vissza, annak külön in/out-ként való definiálása nélkül. Ez az eljárások függvényszerű használatát teszi lehetővé Így az eljáráshívás már szerepelhet különböző kifejezésekben, például értékadó kifejezések jobb oldalán is, ahogy azt megszoktuk a matematikában: Például: a = lg 215 x = cos α Ehhez az eljárás-deklarációban a formális paraméterek listájának végén a
returns kulcsszó után meg kell adni a visszaadandó értéket hordozó változó nevét és típusát. Az eljárás specifikációja a deklarációrésszel és az eljárástesttel - grafikusan eljárásgráffal - folytatódik, mely utóbbira a processztestre vonatkozó szabályok az érvényesek. Az eljárás-deklaráció végét az endprocedure és esetlegesen az eljárás neve jelzi (53. ábra) procedure <eljárás neve> [<formális paraméterek>] /* lásd a szöveges formátumot. */ <eljárásbeli deklaráció> <eljárásgráf> Procedure <eljárás neve>; [fpar [in|in/out] <változó neve> {,<változó neve>}* <változó típusa> {[in|in/out] <változó neve> {,<változó neve>}* <változó típusa>}*] [returns [<változó neve>] <változó típusa>];] <eljárásbeli deklaráció> <eljárástest> endprocedure [<eljárás neve>]; 53. ábra Eljárás deklarálása Az elmondottakból
látszik, hogy az eljárás is egy kiterjesztett véges automata. Az eljárást a call kulcsszó után megadott névvel és az esetleges aktuális paraméterekkel lehet meghívni, akár kifejezésből is, ha értékvisszaadó eljárásról van szó. Az előző két matematikai függvényt a következő mődon lehet meghívni, feltéve, hogy leírásunkban deklaráltunk lg és cos eljárást: 22. példa task a := call lg (215); task x := call cos (a); Grafikusan a call kulcsszónak aza 52. ábrán bemutatott szimbólum felel meg Azonban, ha kifejezésből hívjukmeg az eljárást, akkor az utasításnak megfelelőszimbólumot (task, decision) kell használni. Híváskor az aktuális és a formális paqraméterlista elemei pozíciójuk és típusuk szerint kerülnek azonosításra. 55 call <eljárás neve> [(<aktuális paraméterek>)]; <eljárás neve> 54. ábra Eljárás hívása Az eljárás híváskor létrejön egy eljáráspéldány és a hívó processz
felfüggeszti működését arra az időre, míg az eljáráspéldány él. Az eljárás addig aktív, míg el nem éri a return-nel jelzett visszatérési pontot. Ekkor az eljáráspéldány megszűnik létezni és a hívó a hívást követő utasítással folytatja saját működését. Az eljárás érvényes bemeneti jeleinek halmaza és bemeneti sora megegyezik a hívó processzéval, azonban saját állapotokkal rendelkezik. Az eljárások belül deklarált változók lokálisak, vagyis csak az eljárás számára hozzáférhetők és az eljáráspéldány megszűnésével együtt megszűnnek létezni. Grafikusan az eljárásgráf kezdetét az eljárás kezdete szimbólummal jelzik, amely a szöveges formátumban a start kulcsszónak felel meg. Az eljárás működésének végét a return kulcsszó illetve szimbólum zárja (55. ábra), amit csak eljárásokban szabad használni Minden eljárásnak legalább egyszer tartalmaznia kell a return-t, amit, ha definiálva volt, a
visszaadandó értéket hordozó változó neve követ. A szolgálattól eltérően, eljárásokban nem szabad használni a stop szimbólumot! Tehát az eljáráspéldány nem szüntetheti meg az őt meghívó processzpéldányt. start; [<változó neve>] return [<változó neve>]; 55. ábra Eljárás deklarálása Eljárás deklarálható - processz-szintű deklarációban; - szolgálatszintű deklarációban; - más eljárásbeli deklarációban. Az eljárásokra vonatkozó szabályok: 1. A formális és az aktuális paraméterlista hossza és az elemek típusa meg kell egyezzen. 2. Bemenő (in) paraméter aktuális értéke elhagyható, ekkor az definiálatlan lesz Ilyenkor a listavégi vesszők is elhagyhatók. 3. Be- és kimenő (in/out) paraméter aktuális értéke sosem hagyható el 4. Legalább egy return-nek kell lennie az eljárásban 5. Eljárásban nem lehet stop 6. Szolgálaton kívül deklarált eljárásnak szolgálatból való hívásakor annak nem
szabad a szolgálatból kivezetnie, azaz csak az adott szolgálatban deklarált állapotokra, ki- és bemenetekre vonatkozhat. 7. Eljáráshívás nem szerepelhet folyamatos jel (continuous signal) és feltételes bemenet feltételét megadó logikai kifejezésben. 56 Távoli, nem az adott processzen belül deklarált eljárás hívását csak az 1992-es szabványban engedték meg. Az eljárások deklarálása során érdemes külön figyelmet fordítani az implicit átmenetekre. Mivel az eljárás az őt meghívó processz bemeneti sorából veszi a bemeneti jeleket, de általában az állapotoknak és a bemeneti jeleknek csak egy részhalmazát fedi le, szándékunk ellenére impliciten "feldolgozhatja" az expliciten meg nem adott bemeneteket. Ennek elkerülésére felhasználhatjuk a csillag szimbólumot a fel nem sorolt bemenetek megőrzésére. 3.22 Makrók deklarálása A makrók (macro) szintén paraméterezett leírásrélszletek, de értelmezésük alapvetően
eltér az eljárásokétól, így alkalmazási területük is más. Az SDL leírás interpretálása előtt a makró meghívásának helyére bemésolják a makrót aktualizált formában. Tehát az interpretáláskor nem is látszik, hogy az adott részlet makróként került a leírásba. Ezért egy makró nem hívhatja meg ismételten önmagát (tilos a rekurzió). A makró nem jelent működő példányt a rendszerben, csupán formai egyszerűsítés a leírásban. Ezért az SDL leírás bármely részletét alkalmazhatjuk, megadhatunk benne ugyanúgy deklarációs részeket, mint viselkedélleírásokat. A makródeklarációk a rendszerleírás tetszőleges szintű deklarációs részében elhelyezhetők. Mivel a makrók az egész rendszerben láthatók, mindegyiknek egyedi nevet kell adnunk. A makródeklaráció a macrodefinition kulcsszóval és a makró nevével kezdődik és az endmacro-val fejeződik be. A makró neve után az fpar kulcsszót követően lehet megadni a
formális paraméterek listáját. Ezt követheti a makrótest, mely tetszőleges SDL leírás, mely azonban nem tartalmazhatja a macrodefinition és az endmacro kulcsszavakat. Használható a macroid előre definiált formális paraméter is, mely az SDL interpreter által generált egyedi nevek alkalmazását teszi lehetővé (56. ábra) macrodefinition <makró neve> [<formális paraméterek>] <makrótest> macrodefinition <makró neve> [fpar <név> {<név>}*]; <makrótest> endmacro [<makró neve>]; 56. ábra Makró deklarálása A makró hívása a macro kulcsszó utáni névvel és az aktuális paraméterekkel történik. paramétereknek számban meg kell egyezniük a formális paraméterlistában magadottakkal. Tilos a listaelemek elhagyása! Grafikusan a makródeklarálás szabályai eltérnek a szövegestől, a két leírási forma között nem lehet kölcsönösen egyértelmű kapcsolatról beszélni. A grafikus leírásban meg
kell jelölni a makróba vezető bejáratokat és az onnét kivezető kijáratokat, vagyis a két leírásrész a hívó és a hívott - kapcsolódási pontjait. A makróhívás minden bejáratához (inlet) egyértelműen hozzá kell rendelni a makróleírás egy-egy kijáratát (outlet). Ha több kijárata is van egy makrónak, akkor azokat címkékkel kell ellátni. (Ugyanúgy, ahogy az elemmel működő tárgyakban meg van határozva, hogy hova kell kerülnie a pozítív és negatív pólusnak.) Ezeket a címkéket a hívásnál is fel kell tüntetni A makróhívás szimbóluma az 57 ábra mutatja. Az 58 ábra pedig egy makródefiníció szöveges és grafikus formáját mutatja be, valamint a makró hívását és a behelyettesítés után kapott leírást mindkét formátumban. 57 call <makró neve> [(<aktuális paraméter> {, <aktuális paraméter>}*]; <makró neve> 57. ábra Makró hívása macrodefinition exam fpar alfa,c,s C [S] 23. példa
macrodefinition exam fpar alfa, c, s, a; block alfa referenced; channel c from a to alfa with s; endchannel c; endmacro exam; alfa a A a exam (B, C1, S1) block A referenced; macro exam (B, C1, S1, A); Behelyettesítés után: A C1 [S1] exam (B, C1, S1) block A referenced; block B referenced; channel C1 from A to B with C1; endchannel C1; 58. ábra Példa makró használatára 3.3 Folyamatos jel, feltételes bemenet 3.31 Folyamatos jel Vannak szituációk, amikor valamilyen állapotváltozás nem egy jel hatására, hanem ellenkezőleg, a jel hiánya miatt következik be. Máskor, szintén bemeneti jel nélkül, csak valamely feltétel beteljesülése eredményez állapotátmenetet. Bár az SDL alapvetően gerjesztés-válasz típusú viselkedés leírására lett kidolgozva, módot ad ilyen esetek kezelésére a folyamatos jel (continuous signal) konstrukcióval. Az állapot-bemenet párok által eredményezett állapotátmenetek között kell megjelölni azokat,
amelyek a bemeneti jel hiánya (üres bemeneti sor) esetén érvényesek. Ezeket logikai feltételekhez kell kötni, melyet a provided kulcsszó után boolean-típusú kifejezésként kell megadni. Ha egy állapothoz több folyamatos jel is tartozik, azok között prioritást lehet 58 megállapítani, amit a priority kulcsszó utáni egész szám nagysága határoz meg. Minél kisebb a szám, annál nagyobb a prioritása. A folyamatos jelek azonban mindig kisebb prioritással rendelkeznek, mint a valóságos bemenetek. Ha több azonos prioritású feltétel is teljesül, véletlenszerűen hajt végre a rendszer egy átmenetet közülük. Folyamatos jeleket az 59 ábra alapján az engedélyező feltétel (enabling condition) szimbólum segítségével lehet megadni. <boolean kifejezés> priority <egész szám> provided <boolean kif.> ; [priority <egész szám> ] ; 59. ábra Folyamatos jel A folyamatos jel konstrukciót implicit jelek segítségével
valósítják meg. Az SDL interpreter annak jelzésére, hogy a bemeneti sor üres és teljesült valamely feltétel, implicit jelet generál. Ebből az is következik, hogy a sender értéke folyamatos jel esetén self lesz Vegyünk egy egyszerű példát a folyamatos jelre. Az egyik processzünk addig várakozik (idle), amíg a ready értéke igaz nem lesz (pl. amíg befejeződik egy sok adatot mozgató társprocessz futása). Valóságos bemeneti jel hatására kimozdul(hat) ebből az állapotból, ha viszont ilyen nem érkezik, de a ready logikai kifejezés értéke időközben valamikor igazra vált, akkor nagy prioritással ezen az ágon hajt végre állapotátmenetet (60. ábra) Ha nem akarnánk feltételhez kötni, akkor a provided után true értéket írva egyszerű feltétel-nélküli átmenetet kapunk. idle 24. példa ready priority 1 state idle; provided ready; priority 1; 60. ábra Példa folyamatos jelre 3.32 Feltételes bemenet Előfordulhat olyan eset is, hogy
egy jel feldolgozását szeretnénk feltételhez kötni. Például ne csukjunk be egy ablakot (hiába is kapunk ilyen jelet a bemenetről), ha az már csukva van. Vagyis a close (becsukás) jelet csak abban az esetben értelmezzük, ha egyáltalán nyitva van az ablakunk (open). (61 ábra) 59 idle 25. példa state idle; input Close; provided open ; Close open 61. ábra Példa feltételes bemenetre A feltételes bemenetnél a feltételben nem szerepelhet olyan érték, melyet valamely jel szállít. Ha egy következő állapot feltételes bemenetet tartalmaz, a feltétel kiértékelése megelőzi az állapotátmenet befejezését. Ha több ilyen bemenet is van, azok véletlenszerű sorrendben értékelődnek ki. A feltételes bemenetben megadott jel, ha elsőként szerepel a processz bemeneti sorában, mindaddig tárolódik, míg a feltétel nem teljesül (a provided utáni rész értéke hamis). Ekkor a bemeneti sorban található többi jel a save-hez hasonlóan
feldolgozásra kerül. Amint a logikai kifejezés értéke igaz lesz, a jel feldolgozásra kerül 3.4 Nemdeterminisztikus viselkedés leírása Előfordulhat, hogy a specifikálandó rendszer valamely részének a viselkedése nem determinisztikus. Vagyis nem tudjuk – nem akarjuk – meghatározni, hogy mi eredményezi egy-egy esemény bekövetkeztét. Például le kell írnunk, hogy mik a következményei egy számítógép meghibásodásnak, de nehezen tudnánk pontosan specifikálni a meghibásodás keletkezésének pontos okát. Az SDL kínál pár eszközt, az ilyen „megbízhatatlan” rendszerek leírására is, ellentétben pl. a programozási nyelvekkel, ahol is mindennek determinisztikusnak kell lennie. 3.41 Nemdeterminisztikus döntés Abban az esetben alkalmazandó, ha ismerjük az alternatív viselkedési módokat, de nem tudjuk megadni a kiválasztás mechanizmusát. A már ismertetett decision szerkezet kérdésének a helyére az any kulcsszót írva nincs szükség
a válaszok megadására, elég az átmeneteket definiálni (62. ábra) any <állapotátmenet> <állapotátmenet> decision any ; (): [<állapotátmenet>] {(): [<állapotátmenet>] }+ enddecision ; 62. ábra Nemdeterminisztikus döntés 60 A nemdeterminisztikus döntésre egy példa lehet az, amikor a kereskedelmi Internetoldalak tetején véletlenszerűen feltűnő reklámhirdetések jelennek meg. 26. példa process advertisement banner; start; decision any; ( ): output ad 1 to parent; nextstate ; ( ): output ad 2 to parent; nextstate ; enddecision; 3.42 Nemdeterminisztikus kifejezés Az any kulcsszót használhatjuk akkor is, ha egy kifejezés értékét szeretnénk nemdeterminisztikusan meghatározni. Ekkor az any után zárójelben kell jelezni, hogy milyen típusú értéket kell visszaadnia a kifejezésnek. any (<típus neve>); Ez a módszer hasonlít a programozásban megszokott random függvényhez, de itt tetszőleges típusra
alkalmazható. Az interpreter a kifejezés kiértékelésekor az adott típus értéktartományából választ egy értéket véletlenszerűen. Egy jó példa a véletlenre a dobókocka: 27. példa newtype dobokocka literals egy, ketto, harom, negy, ot, hat ; endnewtype dobokocka; dcl eredmeny dobokocka; task eredmeny:= any (dobokocka); /* véletlenszerűen a hat lehetséges eredmény egyike lesz / 3.43 Spontán átmenet A számítógép meghibásodását talán az eddig bemutatott eszközökkel is lehetne modellezni, csak kissé körülményesen. Erre a legalkalmasabb a spontán átmenetnek nevezett konstrukció, melyet az input után, vagy a bemenet szimbólumaiban megadott none kulcsszó jelöl. Ebben az esetben a spontán átmenet bármikor bekövetkezhet a bemeneti sor tartalmától függetlenül is ott, ahol ennek lehetőségét deklaráltuk. Az interpreter véletlenszerű implicit jel generálásával valósítja meg ezt az átmenetet, ezért a sender értéke self az
átmenet végrehajtásakor. Itt is lehetnek feltételek a provided kulcsszót követően Nézzük meg a számítógép egy lehetséges meghibásodásának kezelését. (63 ábra) 61 correct 28. példa state correct; input none; nextstate failure; endstate correct; none failure 63. ábra Spontán átmenet megadása 3.5 Változók exportálása / importálása Az SDL-ben, a processzekben deklarált változók lokálisak, ezért más processzpéldányok nem látják őket. Ezt eddig csak üzenetváltással lehetett kikerülni Mivel ez néha körülményes, ezért már az 1988-as SDL szabvány szerint is lehetőség volt azonos blokkon belüli processzpéldányok között a változók exportálására, láthatóvá tételére. Fontos tudni, hogy ez csak a változó értékének leolvasására terjed ki, módosítani nem lehet. Egyik módszert sem szabad alkalmazni eljáráspéldányok lokális változóira. 3.51 Változók exportálása / importálása A változó értékének
exportálása egy egyszerűsített formája a megfelelő jel elküldésének, amit az interpreter implicit jel küldésével valósít meg. Az exportáló a változó birtokosa, az importáló példány pedig szeretné megtudni a változó értékét. Mindkettőnél deklarálni kell egy-egy azonos típusú változót: dcl exported <változó neve> <típus neve>; Míg az importáló processzben az imported kulcsszó segítségével: imported < változó neve> <típus neve>; A konkrét érték exportálásakor az exportáló processz címe is tárolódik: export (<változó neve>); Kiolvasás (ha más értéket nem lehet felvenni, akkor a cím elhagyható): import (<változó neve> [,<processzpéldány azonosító>]); Az 1992-es SDL-ben kibővítették az exportálás tartományát. Blokkon kívülre a remote kulcsszóval tudunk távoli változók között kapcsolatot teremteni. 3.6 Opciók Az SDL-ben ugyanannak a rendszernek különböző
verzióit definiálhatjuk egyszerre. Ahhoz, hogy tudassuk az interpreterrel, hogy éppen melyik verzióval dolgozzon, három eszköz is létezik. 3.61 Konstans értékének külső megadása Az alap SDL-ben bemutatott synonym szerkezet segítségével egy konstans értéket lehet megadni. Néha azonban a konstans értéke nem a rendszertől, hanem külső választástól függ 62 Ekkor alkalmazandó az external kulcsszó, aminek a hatására az SDL interpreter a deklarált konstans aktuális értékét az interpretálás előtt kívülről fogja bekérni. Így a rendszerleírás paraméterezhetővé válik. synonym <konstans neve> [<típus neve>] = {<érték>|external } ; Ha használjuk a külső megadást, akkor nem szabad a típusmeghatározást elhagyni, ami a következők egyike lehet csak: character, charstring, integer, natural, real, PId, duration, time. Leggyakrabban a statikus és a dinamikus leírás megfelelő verzióinak kiválasztására használják
ezt a megoldást, mint azt mindjárt látjuk is egy példában majd. 3.62 Statikus leírás kiválasztása A kombinált blokk-alrendszernél már láttuk, hogy a rendszer egy részének leírása megadható különböző verziókban. Az SDL-ben ez megtehető a teljes rendszerre is A select if kulcsszavak után zárójelben megadott logikai kifejezés dönti el, hogy a továbbiakban az endselect-ig tartó részt mikor kell az interpretálandó rendszer részének tekinteni. A logikai kifejezés nem függhet az opcionális elemektől A select szerkezetet mindig csak az adott szinten megengedett elemekre szabad megadni. Nem alkalmazható processz-, eljárás- vagy szolgálattestben, azaz a dinamikus leírást megadó részekben! A logikai kifejezés csak külső konstansok-tól függhet. Grafikusan egy szaggatott vonallal körülhatárolt sokszög felel meg ennek, lásd 64. ábra <logikai kifejezés> select if (<logikai kifejezés>); {<statikus leírás>}+ endselect;
64. ábra Statikus leírás kiválasztása Ha visszatérünk a hálózatos példához, a select konstrukció segítségével megadható egy általánosabb WAP Network leírása. Az eddigieken kívül az új alkotóelem az, hogy a bővített értelmezésben már más hálózatok is fordulhatnak tartalom-kéréssel a WAP Server felé (pl. desktop gépről). 29. példa system WAP Network; synonym extended charstring=external; block WAP Server referenced; block Wireless Network referenced; channel WAP Proxy from Wireless Network to WAP Server with WML.req, HTMLreq; from WAP Server to Wireles Network with Bin Content; endchannel WAP Proxy; select if (extended=’Other Network’); channel Internet from env to WAP Server with Web; from WAP Server to env with Net HTML.req, Net WMLreq; endchannel Internet; channel Interface from env to Wireless Network with User; from Wireless Network to env with User; endchannel Interface; endselect; endsystem WAP Network; 63 system WAP Network WAP
Server Wireless Network synonym extended charstring=external; Other Network select if extended=external network 65. ábra Példa statikus leírás kiválasztására 3.63 Dinamikus leírás kiválasztása A rendszer kiépítésének módosulásával általában a közös részek viselkedése is módosul. A viselkedésbeli módosításokat meg lehetne adni a már ismert döntés szerkezettel, de ebben az esetben az interpretálás során figyelembe kell venni a rendszer azon részeit is, melyek az aktuális választás miatt sosem fordulhatnak elő, és minden alkalommal a decisionhöz érve újra és újra meghozni a döntést, mely pedig már eldőlt a rendszer felépítésének kiválasztásakor. Ezért vezették be az átmenet opciót (transition option), melyet csak egyszer, az interpretálandó részek kiválasztása során értékelnek ki. Ezért ez csak külső konstansoktól függhet. Ez a szerkezet hasonlít a döntéshez. A decision helyett azonban az alternate és
endalternate kulcsszavakat kell használni. Grafikusan egy egyenlőszárú háromszögben kell megadni a kérdést (66. ábra) <kérdés> <1. válasz> <2. válasz> <állapotátmenet> <állapotátmenet> alternative <kérdés>; (<válasz>): [<állapotátmenet>] {(<válasz>):[<állapotátmenet>]}* (<válasz>)|else:[<állapotátmenet>] endalternative; 66. ábra Dinamikus leírás kiválasztása Például, ha a WTP időzítői és számlálói attól függnek, hogy milyen hordozó csatornán (bearer) keresztül kommunikál, akkor azt a következő módon kell leírni (67. ábra) 30. példa bearer GSM SMS IP supported GSM USSD alternative bearer; (GSM SMS): (GSM USSD): (IP supported): endalternative; 67. ábra A bearer típusától függő viselkedés 64 4. Függelék 4.1 Adattípusok deklarációja SDL-ben 4.11 Előre definiált típus deklarációk az alap SDL-ben NEWTYPE Boolean LITERALS True,False;
OPERATORS "NOT": Boolean -> Boolean; "AND": Boolean, Boolean -> Boolean; "OR" : Boolean, Boolean -> Boolean; "XOR": Boolean, Boolean -> Boolean; "=>" : Boolean, Boolean -> Boolean; ENDNEWTYPE Boolean; NEWTYPE Integer LITERALS NAMECLASS (0:9)+; OPERATORS "-" : Integer -> Integer; "+" : Integer, Integer -> Integer; "-" : Integer, Integer -> Integer; "*" : Integer, Integer -> Integer; "/" : Integer, Integer -> Integer; "MOD": Integer, Integer -> Integer; "REM": Integer, Integer -> Integer; "<" : Integer, Integer -> Boolean; ">" : Integer, Integer -> Boolean; "<=" : Integer, Integer -> Boolean; ">=" : Integer, Integer -> Boolean; Float: Integer -> Real; Fix : Real -> Integer; ENDNEWTYPE Integer; SYNTYPE Natural = Integer CONSTANTS >= 0 ENDSYNTYPE Natural;
NEWTYPE Real LITERALS NAMECLASS ((0:9)+) OR ((0:9)*.(0:9)+); OPERATORS "-" : Real -> Real; "+" : Real,Real -> Real; "-" : Real,Real -> Real; "*" : Real,Real -> Real; "/" : Real,Real -> Real; "<" : Real,Real -> Boolean; ">" : Real,Real -> Boolean; "<=" : Real,Real -> Boolean; ">=" : Real,Real -> Boolean; /* ASN.1 operator: */ Power: Integer, Integer -> Real; ENDNEWTYPE Real; 65 NEWTYPE PId LITERALS Null; OPERATORS unique! : PId -> PId; ENDNEWTYPE PId; NEWTYPE Character LITERALS NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, BS, HT, LF, VT, FF, CR, SO, SI, DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, CAN, EM, SUB, ESC, FS, GS, RS, US, , !, ", #, $, %, &, , (, ), *, +, ,, -, ., /, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ;, <, =, >, ?, @, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, [, , ], ^, , `, a, b, c, d, e, f, g, h,
i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, {, |, }, ~, DEL; /* is an apostrophe, is a space, ~ is a tilde / OPERATORS Chr : Integer -> Character; Num : Character -> Integer; "<" : Character, Character -> Boolean; "<=" : Character, Character -> Boolean; ">" : Character, Character -> Boolean; ">=" : Character, Character -> Boolean; ENDNEWTYPE Character; NEWTYPE Charstring String (Character,) ADDING LITERALS NAMECLASS (( :&) OR OR ((:~))+ ; ENDNEWTYPE Charstring; NEWTYPE Duration LITERALS NAMECLASS ((0:9)+) OR ((0:9)*.(0:9)+); OPERATORS duration!: Real -> Duration; "+" : Duration, Duration -> Duration; "-" : Duration -> Duration; "-" : Duration, Duration -> Duration; "*" : Real, Duration -> Duration; "*" : Duration, Real -> Duration; "/" : Duration, Real -> Duration; "<" : Duration, Duration -> Boolean;
">" : Duration, Duration -> Boolean; "<=" : Duration, Duration -> Boolean; ">=" : Duration, Duration -> Boolean; ENDNEWTYPE Duration; NEWTYPE Time LITERALS NAMECLASS ((0:9)+) OR ((0:9)*.(0:9)+); OPERATORS time!: Duration -> Time; "<" : Time, Time -> Boolean; "<=" : Time, Time -> Boolean; ">" : Time, Time -> Boolean; ">=" : Time, Time -> Boolean; "+" : Duration, Time -> Time; "+" : Time, Duration -> Time; "-" : Time, Duration -> Time; "-" : Time, Time -> Duration; ENDNEWTYPE Time; 66 4.12 Előre definiált generátorok az alap SDL-ben GENERATOR equality(TYPE item) OPERATORS "=" : equality, equality -> Boolean; "/=": equality, equality -> Boolean; ENDGENERATOR; GENERATOR ordered(TYPE item) OPERATORS "<" : ordered, ordered -> Boolean; ">" : ordered, ordered ->
Boolean; "<=" : ordered, ordered -> Boolean; ">=" : ordered, ordered -> Boolean; ENDGENERATOR; GENERATOR String(TYPE Itemsort LITERAL Emptystring) /* Strings are "indexed" from one / LITERALS Emptystring; OPERATORS MkString : Itemsort -> String; Length : String -> Integer; First : String -> Itemsort; Last : String -> Itemsort; "//" : String, String -> String; Extract! : String, Integer -> Itemsort; Modify! : String, Integer, Itemsort -> String; SubString: String, Integer, Integer -> String; ENDGENERATOR String; GENERATOR Powerset(TYPE Itemsort) LITERALS Empty; OPERATORS "IN" : Itemsort, Powerset -> Boolean; Incl : Itemsort, Powerset -> Powerset; Del : Itemsort, Powerset -> Powerset; "<" : Powerset, Powerset -> Boolean; ">" : Powerset, Powerset -> Boolean; "<=" : Powerset, Powerset -> Boolean; ">=" : Powerset, Powerset -> Boolean;
"AND" : Powerset, Powerset -> Powerset; "OR" : Powerset, Powerset -> Powerset; ENDGENERATOR Powerset; GENERATOR Array(TYPE Index, TYPE Itemsort) OPERATORS Make! : Itemsort -> Array; Modify! : Array, Index, Itemsort -> Array; Extract!: Array, Index -> Itemsort; ENDGENERATOR Array; 67 4.13 ASN1-es típus deklarációkkal kibővített SDL SYNTYPE IA5String = Charstring ENDSYNTYPE; SYNTYPE NumericString = Charstring (from ("0"."9")) ENDSYNTYPE; SYNTYPE PrintableString = VisibleString ENDSYNTYPE; SYNTYPE VisibleString = Charstring (from ("A"."Z"|"a""z"|"0""9"|"",(,),+,,,-,,/,:,=,?)) ENDSYNTYPE; NEWTYPE GraphicString inherits Charstring operators all; ENDNEWTYPE GraphicString; NEWTYPE UniversalString inherits Charstring operators all; ENDNEWTYPE UniversalString; NEWTYPE Enumeration operators Pred : Enumeration -> Enumeration; Succ : Enumeration ->
Enumeration; First : Enumeration -> Enumeration; Last : Enumeration -> Enumeration; Num : Enumeration -> Integer; "<" : Enumeration, Enumeration -> Boolean; "<=" : Enumeration, Enumeration -> Boolean; ">" : Enumeration, Enumeration -> Boolean; ">=" : Enumeration, Enumeration -> Boolean; ENDNEWTYPE Enumeration; SYNONYM PLUS INFINITY Real = external; SYNONYM MINUS INFINITY Real = external; NEWTYPE Bit inherits Boolean literals 0 = FALSE, 1 = TRUE; operators all; ENDNEWTYPE Bit; NEWTYPE Bit String String0(Bit,B); adding literals nameclass(0 or 1)*B, nameclass((0:9) or (A:F))*H; operators "NOT": Bit String -> Bit String; "AND": Bit String, Bit String -> Bit String; "OR" : Bit String, Bit String -> Bit String; "XOR": Bit String, Bit String -> Bit String; "=>" : Bit String, Bit String -> Bit String; ENDNEWTYPE Bit String; 68 SYNTYPE Octet = Bit
String constants size (8) ENDSYNTYPE Octet; NEWTYPE Octet String String(Octet,B) literals nameclass((0 or 1)8)+B, nameclass(((0:9) or (A:F))2)+H; operators Bit String : Octet String -> Bit String; Octet String : Bit String -> Octet String; ENDNEWTYPE Octet String; NEWTYPE NULL literals Null; ENDNEWTYPE Null; NEWTYPE Object element literals nameclass (0:9)+; ENDNEWTYPE Object element; NEWTYPE Object Identifier String(Object element,EmptyString) ENDNEWTYPE Object Identifier; NEWTYPE Any type ENDNEWTYPE Any type; ATCTime ::= VisibleString; UTCTime ::= VisibleString; EXTERNAL Type ::= sequence { direct reference Object Identifier optional, indirect reference Integer optional, data value descriptor ObjectDescriptor optional, encoding choice { single ASN1 type Any type, octet aligned Octet String, arbitrary Bit String } }; ObjectDescriptor ::= GraphicString; 4.14 ASN1-es generátorokkal kibővített SDL GENERATOR String0(TYPE Itemsort, LITERAL Emptystring) String(itemsort,Emptystring)
ENDGENERATOR; GENERATOR Bag(type Itemsort) literals Empty; operators Incl : Itemsort, Bag -> Bag; Del : Itemsort, Bag -> Bag; Length : Bag -> Integer; Take : Bag -> Itemsort; Makebag: Itemsort -> Bag; "in" : Itemsort, Bag -> Boolean; "<" : Bag, Bag -> Boolean; ">" : Bag, Bag -> Boolean; "<=" : Bag, Bag -> Boolean; ">=" : Bag, Bag -> Boolean; "AND" : Bag, Bag -> Boolean; "OR" : Bag, Bag -> Boolean; ENDGENERATOR; 69 4.2 Példa az SDL alkalmazására 4.21 A WAP architektúra A Wireless Application Protocol célja különböző mobil eszközök közötti adatkommunikáció létrehozása. A szabványosítás a következő fő pontokra koncentrál: - olyan mobil protokoll létrehozása, mely biztosítja, hogy a különböző gyártóktól származó eszközök kommunikálni képesek egymással - lehetővé tenni megfelelő applikációk készítését ezen eszközökre -
fejlett adatszolgáltatások és Internetes adatok elérhetőségének biztosítása Ezeket a célokat korlátozott erőforrásokkal rendelkező eszközökön kell megvalósítani, tehát fő célkitűzés a megfelelő hatékonyság és a hasznos információk melletti kommunikációs tevékenység minimalizálása. Mobil készülékek általában a következő tulajdonságokkal rendelkeznek az erőforrások tekintetében: - kisebb kijelzők a készüléken - kevesebb memória, kisebb teljesítményű CPU - korlátozott energiaforrások - más típusú adatbeviteli eszközök Ezen kívül az adatkommunikációra jelenleg csak minimális sávszélesség áll rendelkezésre, az adatok viszonylag nagy késleltetéssel jutnak el egyik eszközről a másikra, valamint az időjárási és térbeli viszonyok függvényében nagy lehet az adatveszteség. A Wireless Application Protocol a következő hat réteggel rendelkezik: A WAP protokoll stack 70 4.22 A Wireless Transaction Protocol
SDL/GR leírása A WTP protokoll leírja a kommunikációban részt vevő eszközök közötti tranzakciók lefolyását. A protokoll egy datagram szolgáltatás felett működik, segítségével megkímélhetjük a felsőbb rétegeket az esetlegesen elveszett csomagok miatti üzenetek újraküldésétől. A fő célkitűzés az üzenetek biztonságos továbbítása, úgy, hogy egyensúlyozunk a biztonság és az ahhoz szükséges költségek között. A kommunikációban szereplő eszközök a kliens és a szerver jelzővel illethetők. Előzőre az initiator, míg utóbbira a responder elnevezés terjedt el. A tranzakcióban két fő kommunikációs útvonal található Az egyik az egyes készülékek között található valamilyen közvetítő média (a fizikai réteg) segítségével. A másik útvonal a szolgálati primitívek útja az egyes eszközök WTP User és WTP Provider-ei között. WTP User alatt a WTP szolgáltatás felhasználóit értjük, ez lehet a WSP réteg, vagy
egy applikáció, mely közvetlen tartja a kapcsolatot a WTP-vel. A WTP Provider a tranzakció lebonyolításáért felelős, kéréseket küldhet vagy fogadhat az Usertől, illetve a másik eszközön levő WTP Providertől. A tranzakciós osztályok Három tranzakciós osztályt különböztetünk meg. Class 0 - Nem megbízható hívó üzenet válasz nélkül. A tranzakció során az Initiator egy invoke üzenetet küld a Responder felé. A Responder nem küld sem választ, sem nyugtát erre a hívásra, az Initiator pedig nem küldi újra az üzenetet. Class 1 - Megbízható hívás válasz nélkül. A hívó fél egy invoke-ot küld a másik felé, mely erre válaszul egy nyugtát küld. Ha az Initiator nem kap nyugtát a hívására (ez eredhet akár az invoke, akár az acknowledgement üzenet elveszéséből), akkor újraküldi az üzenetet. Class 2 - Megbízható híváskérés egy megbízható válaszadással. Az Initiator egy invoke üzenetet küld a Responder felé, mely
erre egy result üzenetet küld vissza, ami egyben nyugtázza is a hívást. Ha a kérés kiszolgálása sokáig tart, akkor a Responder először egy hold-on acknowledgement-et küld el, tudatva az Initiatort, hogy még várni kell az eredményre, így az nem küldi újra az üzenetet. Mikor a Responder elküldte az eredményt, akkor azt az Initiator nyugtázza egy acknowledgement üzenettel. Ha a result vagy az acknowledgement üzenetek elvesznek, akkor azokat a megfelelő fél egy idő elteltével újraküldi. Az SDL-es specifikáció Az protokoll SDL leírásának szintjei: 1. WTP system 2. Block WTP Initiator és Block WTP Responder 3. Processzek A rendszer tartalmazza a két blokkot, a blokkok pedig egyenként egy-egy processzt. A processzek állapotainak egy-egy kiterjesztett véges automata felel meg. Az automatákat, mint ahogy az egész protokoll leírását az állapottáblák alapján végeztük el, a teljes protokoll leírás figyelembevételével és - ahol szükséges
volt - kisebb kiegészítésekkel. 71 4.221 A rendszerszint SDL-ben a rendszer jele egy téglalap. Ábránkon a külső keret mutatja a rendszer határait, ami azon belül van az a WTP, ami azon kívül az a külvilág. Egy leírás csak egy rendszert tartalmazhat. Rendszerünk két blokkot tartalmaz, ezek a WTP Initiator és a WTP Responder. A blokkok csatornákon tartják a kapcsolatot a külvilággal illetve egymással, ezen keresztül terjednek a jelek. Esetünkben három csatorna található, Initiator User, Responder User illetve PDU. Mindhárom csatorna nem késleltető kétirányú csatorna. Rendszerszinten adhatunk meg különböző globális deklarációkat is system w tp responder user tr invoke.ind, tr abortind, tr resultcnf tr invoke.res, tr abortreq, tr resultreq w tp responder invoke, result, ack, abort, info tpi pdu invoke, result, ack, abort, info tpi initiator user tr invoke.cnf, tr abortind, tr resultind w tp initiator tr invoke.req, tr abortreq, tr
resultres 72 Ábránkon globálisan csak a jeleket definiáltuk azok argumentumaival és típusaival együtt. A deklarációkat egy szövegbeviteli mezőben kell megadni. Az argumentumok típusaira az SDL-ben előre definiált típusokat használtunk. Ilyenek a boolean, integer, character. Ezek a típusok valamelyest eltérhetnek az általános programozási nyelvekben megszokottaktól, általános jellemzőjük, hogy nincs ábrázolásbeli korlátjuk. Így a character típus akár végtelen hosszú szöveget, míg az integer egy 1 bites vagy akár egy végtelen nagy számot is jelölhet. Mi az egy bites számok jelölésére maradtunk a boolean típusnál, hiszen azok általában valamely flag-et azonosítják. Vannak olyan jelek, ahol nem adtunk meg egyetlen argumentumot sem, ennek oka, hogy a paramétereket nem használjuk a protokoll specifikációja során. Más esetben az összes paramétert deklaráltuk, annak ellenére, hogy csak néhányat használunk fel közülük.
system wtp sig nal invoke(boolean, integer, boolean, boolean, boolean, integer, integer, boolean, boolean, boolean, boolean, integ er); sig nal result(boolean, integer, boolean, boolean, boolean, integer); sig nal ack(boolean, integ er, boolean, boolean, boolean, integer); sig nal abort(boolean, integer, integer, integer, integer); sig nal tr invoke.res(boolean, integ er, boolean); sig nal tr abort.req (integ er, character); sig nal tr result.req ; sig nal tr invoke.ind(boolean); sig nal tr abort.ind, tr result.cnf; sig nal tr invoke.req (boolean, integ er, boolean); sig nal tr result.res(character, boolean); sig nal tr invoke.cnf(boolean, integ er, boolean); sig nal tr result.ind; sig nal info tpi; 73 4.222 A blokkszint A blokk összeköttetést biztosít a rendszer és a processzek között. Példaként az Initiator blokk látható. A Responder blokkja hasonlóképpen néz ki, mindössze a blokk neve és az egyik jelút változik. A jelutak végén meg kell adni az
összeköttetési pontokat is, azt hogy mely csatornával vannak összekötve. Így az Initiator blokk tartalmaz egy PDU összeköttetést, ami a PDU csatornán levő jeleket szállítja a processz szint felé, illetve vissza, valamint egy Initiator User összeköttetést, ami a szolgálati primitívek jeleit szállítja. A Responder blokk szintén rendelkezik a PDU-kat szállító jelúttal, valamint egy másikkal, ami a Responder User jeleit szállítja. A blokkszint is tartalmazhat különböző deklarációkat, esetünkben ezt meghagytuk a következő szintre. Amint az ábrából is látható, ez a szint nem sok új információt ad a rendszerben bemutatottakhoz képest, leginkább az SDL kötelező struktúrájának megtartása miatt kellett elkészíteni. block w tp responder route2 invoke, result, ack, abort, info tpi invoke, result, ack, abort, info tpi responder route1 tr invoke.ind, tr abortind, tr resultcnf tr invoke.res, tr abortreq , tr resultreq block w tp responder
connect pdu and Uname41; connect responder user and Uname43; 74 block w tp initiator route4 tr invoke.cnf, tr abortind, tr resultind tr invoke.req, tr abortreq, tr resultres route3 invoke, result, ack, abort, info tpi initiator invoke, result, ack, abort, info tpi block w tp initiator connect initiator user and Uname57; connect pdu and Uname41; 75 4.223 Processz-szint A következő néhány oldal a processzek szemléltető bemutatásával és leírásával foglalkozik. Mindkét blokk (Initiator és Responder) egy-egy processzt tartalmaz. Ezeket szintén Initiator-nak és Responder-nek neveztük el (Process Initiator és Process Responder). Az Initiator processz 4, míg a Responder 6 állapotot tartalmaz, minden egyes állapot egy véges automatával modellezhető. A processzek érvényes bemeneti jeleinek halmaza tartalmazza az összes jelet, amelyek a blokkszintről érkeznek, valamint a deklarált timerek jeleit. Ez utóbbiakhoz nem kellett jelutakat definiálni.
Ellentétben a rendszer- és blokkszinttől, a processzeknek nem kötelező egy oldalon szerepelniük, ez helyszűke miatt kivitelezhetetlen is lenne. Így egy-egy processz több oldalon keresztül írható le, az oldalak sorrendjének semmilyen szerepük nincs. A processzekre vonatkozó deklarációkat ugyanígy bármelyik oldalon elkészíthetjük, egy-egy szövegbeviteli mező alkalmazásával. A processzek leírásához a következő deklarációkra van szükségünk: - Három időzítőt (timer) használunk, ezeket a timer kulcsszó után soroltuk fel: TimerTo A, TimerTo R és TimerTo W. - A timerekhez szükséges egy-egy időtartam megadása, ezek az A, R, W változók duration típussal, melyek az időzítők lejártának időpontját definiálják. - Integer típusú változók a TID, a Class, az AEC és a RID. Utóbbi kettőt kezdőértékkel is elláttuk. Mindkettő egy-egy számlálót azonosít Az AEC (Acknowledgement Expiration Counter) azt számolja, hogy az A
intervallummal inicializált timer hányszor jár le, míg az RCR (Re-transmission Counter) felelős az újraküldött üzenetek számlálásáért. - Az AEC és RCR számlálókhoz tartozik egy maximális érték is, melyet elérve a tranzakciót abortálni kell. Ezek az AEC MAX és MAX RCR konstansok, melyeket a synonim kulcsszó után kell megadni. Típusuk integer, értékük viszont hálózatfüggő Mivel az SDL-ben kötelező konstansok értékét megadni, ezért kiválasztottunk az Appendixből egy hálózatot (GSM SMS) és annak default értékét vettük. (Bár a protokoll szempontjából nem a legszerencsésebb a kötelező értékadás.) - Vannak még boolean típusú változóink is, melyek a PDU-kban előforduló flag-eket jelölik, illetve van egy szintén boolean típusú logikai változó (Valid TID). 76 process responder listen timer timerto a; timer timerto w; timer timerto r; dcl aec integer := 0; synonym aec max integer = 4; dcl a, r, w duration; dcl rcr
integer := 0; synonym max rcr integer = 4; dcl tid, class integer; dcl uack, con, tidve, tidok, rid, exitinfo boolean; dcl valid tid boolean; Lbl1 (, , tidve = true) ack listen (con, , , , , tid, , , uack, , , class) invoke tidok wait class (= 0) else TID verification tr invoke.ind valid tid listen (false) (true) uack Lbl1 (false) (true) set(now + a, timerto a) uack := true tr invoke.ind invoke resp wait set(now + a, timerto a) uack := false (uack) tr invoke.ind (uack) invoke resp wait 77 process responder tidok wait abort ack(, , tidok) Abort transaction tidok = true listen set(now + a, timerto a) tr invoke.ind invoke resp wait invoke invoke resp wait abort b (uack) tr abort.req c d result wait abort tr abort.req tr abort.ind Abort transaction Abort transaction listen abort(, , 1) listen 78 process responder result resp wait ack abort tr result.cnf tr abort.ind listen tr abort.req Abort transaction Abort transaction
abort(, , 0) listen listen wait timeout timerto w Clear Transaction abort Abort transaction (, , , , rid) invoke rid (true) (false) listen tr abort.ind exitinfo Ignore (true) (false) listen wait timeout ack wait timeout ack (con = true) info tpi wait timeout 79 process responder tidok wait (, , , , rid) invoke rid (true) (false) Ignore ack(, , tidve) Lbl2 tidok wait tidok wait set(now + a, timerto a) result wait invoke resp wait timerto a a tr invoke.res (, class, exitinfo) class (= 2) (= 1) Lbl2 exitinfo (false) (true) wait timeout set(now + w, timerto w) set(now + w, timerto w) Queue(A) Ack PDU with InfoTPI Queue(A) Ack PDU wait timeout 80 process responder result wait timerto a tr result.req ack rcr := 0 wait timeout result wait set(now + r, timerto r) tr abort.req result Abort transaction result resp wait abort(, , 0) result resp wait listen timerto r rcr (= max rcr) (< max rcr) rcr := rcr + 1 result tr
abort.ind (, , , , true) set(now + r, timerto r) Abort transaction listen result resp wait 81 process responder a uack (false) (true) aec (= aec max) (< aec max) Abort transaction class (= 2) (= 1) set(now + a, timerto w) abort(, , 0) listen aec := aec + 1 Queue(A) Ack PDU ack wait timeout result wait set(now + a, timerto a) invoke resp wait b Ignore invoke resp wait c d Abort transaction tr abort.ind Abort transaction abort(, , 1) listen listen 82 process initiator null null tr invoke.req (userack, class, exitinfo) class (2 : 1) (0) sendtid := gentid userack (true) invoke (con, , , , rid, tid, version, tidnew, u p, , , class) (false) Lbl4 dcl rcr integer := 0; dcl aec integer := 0; dcl gentid, sendtid, rcvtid, lasttid integer := 0; dcl holdon, uack boolean := false; synonym rcr max integer = 4; synonym aec max integer = 4; synonym a duration = 10; synonym r duration = 60; synonym w duration = 300; timer timerto r(integer); timer
timerto a(integer); timer timerto w; dcl tid, version, class, aborttype, abortreason, tpilength integer := 0; dcl con, rid, tidnew, u p boolean := false; dcl userack, exitinfo, tidve, tidok boolean := false; sendtid := gentid, rcr := 0, uack := false null set(now + r, timerto r) invoke (con, , , , rid, tid, version, tidnew, false, , , class) result wait 83 process initiator Lbl4 sendtid := gentid, rcr := 0, uack := true result wait set(now + r, timerto r) timerto r(rcr) invoke rcr (< rcr max) (= rcr max) (con, , , , rid, tid, version, tidnew, true, , , class) result wait tidok (false) (true) rcr := rcr + 1 set(now + r, timerto r) (con, , tidok, , rid, tid) ack rcr := rcr + 1 set(now + r, timerto r) result wait invoke Abort transaction tr abort.ind (con, , , , rid, tid, version, tidnew, u p, , , class) result wait null 84 process initiator result wait (con, , tidve, , rid, tid) ack class (2) (1) tidve tidve (true) (false) (true) (false)
reset(timerto r) Ugrlooplabel42 tr invoke.cnf null (uack, class, exitinfo) reset(timerto r) Ugrlooplabel42 tr invoke.cnf (uack, class, exitinfo) holdon := true result wait 85 process initiator result resp wait timerto a (aec) uack (false) (true) aec (= aec max) (< aec max) aec := aec + 1 set(now + a, timerto a) Abort transaction (con, 0, tid, 0) abort result resp wait ack (con, , tidok, , rid, tid) null set(now + w, timerto w) wait timeout 86 process initiator result resp wait (con, aborttype, tid, abortreason) abort tr abort.req Abort transaction (con, 1, tid, 0) abort Abort transaction tr abort.ind null null wait timeout timerto w (con, aborttype, tid, abortreason) abort Clear Transaction null Abort transaction tr abort.ind null 87 process initiator result wait (con, aborttype, tid, abortreason) abort tr abort.req (con, 0, tid, 0) abort tr abort.ind null null result resp wait result (con, , , , rid, tid)
Ignore tr result.res (, exitinfo) exitinfo (true) (false) result resp wait ack ack (true, , tidok, , rid, tid) (con, , tidok, , rid, tid) set(now + w, timerto w) info tpi wait timeout set(now + w, timerto w) wait timeout 88 process initiator wait timeout tr abort.req Abort transaction (con, 1, tid, 0) abort result wait null (con, , , , rid, tid) result class = 2 holdon (true) (false) reset(timerto r) tr invoke.cnf reset(timerto r) tr result.ind tr result.ind set(now + a, timerto a) set(now + a, timerto a) result resp wait result resp wait 89 process initiator wait timeout (con, , , , rid, tid) result rid (true) (false) Ignore exitinfo (true) (false) wait timeout (con, , tidok, , rid, tid) ack wait timeout ack (true, , tidok, , rid, tid) info tpi wait timeout Ugrlooplabel42 (con, , tidok, , rid, tid) ack rcr := (rcr + 1) set(now + r, timerto r) null 90 4.23 A Wireless Transaction Protocol SDL/PR leírása system wtp; channel
pdu nodelay from wtp initiator to wtp responder with invoke,result,ack,abort, info tpi; from wtp responder to wtp initiator with invoke,result,ack,abort,info tpi; endchannel; channel responder user nodelay from wtp responder to env with tr invoke.ind,tr abortind,tr resultcnf; from env to wtp responder with tr invoke.res,tr abortreq,tr resultreq; endchannel; channel initiator user nodelay from wtp initiator to env with tr invoke.cnf,tr abortind,tr resultind; from env to wtp initiator with tr invoke.req,tr abortreq,tr resultres; endchannel; signal invoke(boolean,integer,boolean,boolean,boolean,integer,integer,boolean, boolean,boolean,boolean,integer); signal result(boolean,integer,boolean,boolean,boolean,integer); signal ack(boolean,integer,boolean,boolean,boolean,integer); signal abort(boolean,integer,integer,integer,integer); signal tr invoke.res(boolean,integer,boolean); signal tr abort.req(integer,character); signal tr result.req; signal tr invoke.ind(boolean); signal tr abort.ind,tr
resultcnf; signal tr invoke.req(boolean,integer,boolean); signal tr result.res(character,boolean); signal tr invoke.cnf(boolean,integer,boolean); signal tr result.ind; signal info tpi; block wtp responder; signalroute route1 from responder to env with tr invoke.ind,tr abortind,tr resultcnf; from env to responder with tr invoke.res,tr abortreq,tr resultreq; signalroute route2 from responder to env with invoke,result,ack,abort,info tpi; from env to responder with invoke,result,ack,abort,info tpi; process responder; timer timerto a; timer timerto w; timer timerto r; dcl aec integer:=0; synonym aec max integer=4; dcl a,r,w duration; dcl rcr integer:=0; synonym max rcr integer=4; dcl tid,class integer; dcl uack,con,tidve,tidok,rid,exitinfo boolean; dcl valid tid boolean; start; nextstate listen; state listen; input invoke(con,,,,,tid,,,uack,,,class); decision class; (=0): output tr invoke.ind; nextstate listen; else: task TID verification; decision valid tid; (false): output
ack(,,tidve=true); nextstate tidok wait; 91 (true): decision uack; (false): set(now+a,timerto a); task uack:=false; output tr invoke.ind(uack); nextstate invoke resp wait; (true): set(now+a,timerto a); task uack:=true; output tr invoke.ind(uack); nextstate invoke resp wait; enddecision; enddecision; enddecision; endstate listen; state tidok wait; input invoke(,,,,rid); decision rid; (true): output ack(,,tidve); nextstate tidok wait; (false): task Ignore; nextstate tidok wait; enddecision; input abort; task Abort transaction; nextstate listen; input ack(,,tidok); provided tidok=true; set(now+a,timerto a); output tr invoke.ind(uack); nextstate invoke resp wait; endstate tidok wait; state invoke resp wait; input timerto a; join a; input invoke; join b; input abort; join c; input tr abort.req; join d; input tr invoke.res(,class,exitinfo); decision class; (=2): set(now+a,timerto a); nextstate result wait; (=1): decision exitinfo; (false): set(now+w,timerto w); task Queue(A) Ack PDU;
nextstate wait timeout; (true): set(now+w,timerto w); task Queue(A) Ack PDU with InfoTPI; nextstate wait timeout; enddecision; enddecision; endstate invoke resp wait; connection a:decision uack; (false): decision class; (=2): output ack; nextstate result wait; (=1): set(now+a,timerto w); task Queue(A) Ack PDU; nextstate wait timeout; enddecision; 92 (true): decision aec; (=aec max):task Abort transaction; output abort(,,0); nextstate listen; (<aec max):task aec:=aec+1; set(now+a,timerto a); nextstate invoke resp wait; enddecision; enddecision; endconnection; connection d:task Abort transaction; output abort(,,1); nextstate listen; endconnection; connection c:output tr abort.ind; task Abort transaction; nextstate listen; endconnection; connection b:task Ignore; nextstate invoke resp wait; endconnection; state result wait; input timerto a; output ack; nextstate result wait; input abort; output tr abort.ind; task Abort transaction; nextstate listen; input tr abort.req; task Abort
transaction; output abort(,,1); nextstate listen; input tr result.req; task rcr:=0; set(now+r,timerto r); output result; nextstate result resp wait; endstate result wait; state result resp wait; input timerto r; decision rcr; (=max rcr):output tr abort.ind; task Abort transaction; nextstate listen; (<max rcr):task rcr:=rcr+1; output result(,,,,true); set(now+r,timerto r); nextstate result resp wait; enddecision; input ack; output tr result.cnf; nextstate listen; input abort; output tr abort.ind; task Abort transaction; nextstate listen; input tr abort.req; task Abort transaction; 93 output abort(,,0); nextstate listen; endstate result resp wait; state wait timeout; input tr abort.req; task Abort transaction; output abort(,,0); nextstate listen; input timerto w; task Clear Transaction; nextstate listen; input abort; task Abort transaction; output tr abort.ind; nextstate listen; input invoke(,,,,rid); decision rid; (true): decision exitinfo; (true): output ack(con=true); output
info tpi; nextstate wait timeout; (false): output ack; nextstate wait timeout; enddecision; (false): task Ignore; nextstate wait timeout; enddecision; endstate wait timeout; endprocess responder; connect pdu and Uname41; connect responder user and Uname43; endblock wtp responder; block wtp initiator; signalroute route3 from initiator to env with invoke,result,ack,abort,info tpi; from env to initiator with invoke,result,ack,abort,info tpi; signalroute route4 from initiator to env with tr invoke.cnf,tr abortind,tr resultind; from env to initiator with tr invoke.req,tr abortreq,tr resultres; process initiator; dcl rcr integer:=0; dcl aec integer:=0; dcl gentid,sendtid,rcvtid,lasttid integer:=0; dcl holdon,uack boolean:=false; synonym rcr max integer=4; synonym aec max integer=4; synonym a duration=10; synonym r duration=60; synonym w duration=300; timer timerto r(integer); timer timerto a(integer); timer timerto w; dcl tid,version,class,aborttype,abortreason,tpilength integer:=0; dcl
con,rid,tidnew,u p boolean:=false; dcl userack,exitinfo,tidve,tidok boolean:=false; start; nextstate null; state null; input tr invoke.req(userack,class,exitinfo); decision class; (2:1): decision userack; (true): task sendtid:=gentid,rcr:=0,uack:=true; 94 set(now+r,timerto r); output invoke(con,,,,rid,tid,version,tidnew,true,,,class); nextstate result wait; (false): task sendtid:=gentid,rcr:=0,uack:=false; set(now+r,timerto r); output invoke(con,,,,rid,tid,version,tidnew,false,,,class); nextstate result wait; enddecision; (0): task sendtid:=gentid; output invoke(con,,,,rid,tid,version,tidnew,u p,,,class); nextstate null; enddecision; endstate null; state result wait; input timerto r(rcr); decision rcr; (<rcr max):decision tidok; (false): task rcr:=rcr+1; set(now+r,timerto r); output invoke(con,,,,rid,tid,version,tidnew,u p,,,class); nextstate result wait; (true): task rcr:=rcr+1; set(now+r,timerto r); output ack(con,,tidok,,rid,tid); nextstate result wait; enddecision; (=rcr
max):task Abort transaction; output tr abort.ind; nextstate null; enddecision; endstate result wait; state result wait; input tr abort.req; output abort(con,0,tid,0); nextstate null; input ack(con,,tidve,,rid,tid); decision class; (2): decision tidve; (true): Ugrlooplabel42: output ack(con,,tidok,,rid,tid); task rcr:=(rcr+1); set(now+r,timerto r); nextstate null; (false): reset(timerto r); output tr invoke.cnf(uack,class,exitinfo); task holdon:=true; nextstate result wait; enddecision; (1): decision tidve; (true): join Ugrlooplabel42; (false): reset(timerto r); output tr invoke.cnf(uack,class,exitinfo); nextstate null; enddecision; enddecision; input result(con,,,,rid,tid); provided class=2; decision holdon; (true): reset(timerto r); output tr result.ind; set(now+a,timerto a); nextstate result resp wait; 95 (false): reset(timerto r); output tr invoke.cnf; output tr result.ind; set(now+a,timerto a); nextstate result resp wait; enddecision; input
abort(con,aborttype,tid,abortreason); output tr abort.ind; nextstate null; endstate result wait; state result resp wait; input timerto a(aec); decision uack; (false): output ack(con,,tidok,,rid,tid); set(now+w,timerto w); nextstate wait timeout; (true): decision aec; (=aec max):task Abort transaction; output abort(con,0,tid,0); nextstate null; (<aec max):task aec:=aec+1; set(now+a,timerto a); nextstate result resp wait; enddecision; enddecision; endstate result resp wait; state result resp wait; input result(con,,,,rid,tid); task Ignore; nextstate result resp wait; input tr abort.req; task Abort transaction; output abort(con,1,tid,0); nextstate null; input abort(con,aborttype,tid,abortreason); task Abort transaction; output tr abort.ind; nextstate null; input tr result.res(,exitinfo); decision exitinfo; (true): output ack(true,,tidok,,rid,tid); output info tpi; set(now+w,timerto w); nextstate wait timeout; (false): output ack(con,,tidok,,rid,tid); set(now+w,timerto w); nextstate
wait timeout; enddecision; endstate result resp wait; state wait timeout; input tr abort.req; task Abort transaction; output abort(con,1,tid,0); nextstate null; input timerto w; task Clear Transaction; nextstate null; input abort(con,aborttype,tid,abortreason); task Abort transaction; output tr abort.ind; nextstate null; input result(con,,,,rid,tid); 96 decision rid; (true): decision exitinfo; (true): output ack(true,,tidok,,rid,tid); output info tpi; nextstate wait timeout; (false): output ack(con,,tidok,,rid,tid); nextstate wait timeout; enddecision; (false): task Ignore; nextstate wait timeout; enddecision; endstate wait timeout; endprocess initiator; connect initiator user and Uname57; connect pdu and Uname41; endblock wtp initiator; endsystem wtp; 97 Az SDL kulcsszavak mutatója 98 active, 38 adding, 23, 24, 68 all, 30, 31, 68 alternative, 64 and, 17, 18, 19, 22, 44, 46, 49, 53, 94, 97 any, 29, 60, 61 axioms, 23 block, 9, 11, 15, 16, 19, 43, 44, 45, 46, 49, 58, 63,
91, 94 call, 55, 56, 58 channel, 9, 10, 11, 13, 14, 15, 37, 46, 48, 49, 58, 63, 91 comment, 36, 37 connect, 17, 18, 19, 44, 45, 46, 48, 49, 51, 53, 94, 97 connection, 92, 93 constants, 23, 69 create, 31, 32, 33, 53 dcl, 25, 27, 53, 61, 62, 91, 94 decision, 26, 28, 29, 33, 35, 55, 60, 61, 64, 91, 92, 93, 94, 95, 96, 97 default, 23, 76 else, 28, 29, 33, 64, 91 endalternative, 64 endblock, 11, 15, 16, 19, 43, 44, 94, 97 endchannel, 14, 15, 46, 48, 49, 58, 63, 91 endconnection, 93 enddecision, 28, 29, 33, 60, 61, 92, 93, 94, 95, 96, 97 endmacro, 57, 58 endnewtype, 23, 24, 27, 53, 61 endprocedure, 55 endprocess, 16, 19, 20, 33, 51, 53, 94, 97 endrefinement, 50 endselect, 63 endservice, 53 endstate, 26, 27, 33, 39, 41, 42, 53, 62, 92, 93, 94, 95, 96, 97 endsubstructure, 44, 46, 49 endsyntype, 23 endsystem, 11, 15, 49, 97 env, 13, 14, 15, 17, 19, 37, 44, 46, 48, 49, 53, 63, 91, 94 export, 62 exported, 62 external, 63, 68 fpar, 20, 33, 55, 57, 58 from, 13, 14, 15, 17, 19, 37, 44, 46, 48, 49,
53, 58, 63, 67, 68, 91, 94 generator, 22, 23 if, 63 import, 62 imported, 62 in, 53, 55, 56, 69 inherits, 24, 68 input, 6, 26, 27, 28, 33, 35, 36, 39, 42, 52, 53, 60, 61, 62, 91, 92, 93, 94, 95, 96 join, 33, 35, 36, 92, 95 literals, 24, 61, 68, 69 macro, 54, 57, 58 macrodefinition, 57, 58 macroid, 57 nameclass, 68, 69 newtype, 22, 23, 24, 27, 53, 61 nextstate, 26, 27, 28, 29, 32, 33, 36, 41, 53, 61, 62, 91, 92, 93, 94, 95, 96, 97 nodelay, 13, 14, 91 none, 24, 61, 62 not, 22 now, 37, 92, 93, 95, 96 offspring, 30, 31, 51 operators, 24, 68, 69 99 or, 22, 68, 69 out, 55, 56 output, 26, 30, 31, 33, 42, 52, 53, 61, 91, 92, 93, 94, 95, 96, 97 parent, 30, 31, 33, 51, 61 priority, 52, 59 procedure, 54, 55 process, 9, 16, 19, 20, 25, 33, 44, 51, 53, 61, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 94 provided, 58, 59, 60, 61, 92, 95 referenced, 10, 11, 15, 16, 19, 44, 46, 48, 49, 51, 53, 54, 58, 63 refinement, 50 remote, 10, 62 reset, 37, 95, 96 return, 56 returns, 55 reverse, 50
save, 31, 38, 39, 41, 42 select, 24, 63 self, 30, 37, 51, 52, 59, 61 sender, 30, 31, 37, 51, 59, 61 service, 50, 51, 52, 53 set, 37, 92, 93, 95, 96 signal, 10, 12, 13, 15, 17, 19, 27, 50, 53, 56, 58, 91 signallist, 13, 15 signalroute, 9, 17, 19, 44, 53, 91, 94 signalset, 21 start, 27, 28, 33, 53, 56, 61, 91, 94 state, 26, 27, 33, 35, 39, 41, 42, 53, 59, 60, 62, 91, 92, 93, 94, 95, 96 stop, 32, 33, 56 struct, 23 substructure, 9, 43, 44, 46, 48, 49 synonym, 22, 62, 63, 91, 94 syntype, 22, 23 system, 9, 10, 11, 15, 25, 49, 63, 71, 91 task, 26, 29, 30, 33, 37, 55, 61, 91, 92, 93, 94, 95, 96, 97 timer, 25, 76, 91, 94 to, 13, 14, 15, 17, 19, 30, 31, 33, 37, 44, 46, 48, 49, 52, 53, 58, 61, 63, 91, 94 type, 24, 69 via, 30, 31, 33, 53 with, 13, 14, 15, 17, 19, 37, 44, 46, 48, 49, 53, 58, 63, 91, 92, 94 xor, 22 100 Irodalomjegyzék Törő Mária: SDL - Specification and Description Language, KFKI, Budapest, 1993. J. Ellsberger, D Hogrefe, A Sarma: SDL Formal Object-oriented Languages for
Communicating Systems, Prentice Hal Europe, 1997. ITU-T Recommendation Z.100: Specification and Description Language (SDL) ITU-T Recommendation Z.105: Use of SDL with ASN1 ITU-T Draft Recommendation Z.106: Common Interchange Format (CIF) Telelogic Tau On-Line Help Wireless Appliaction Protocol - Architecture Specification (Version 30-April-1998) Wireless Transaction Protocol Specification (Version 30-April-1998) Wireless Transaction Protocol Corrigendum (Version 6-November-1998) 101