. Teoria Retelelor Petri Si Modelarea Sistemelor

CUPRINS

Introducere

Modelare

Caracteristici ale sistemelor

1.3 Dezvoltarea inițială a rețelelor Petri

1.4 Aplicații ale teoriei rețelelor Petri

1.5 Teoria rețelelor Petri: teoretic și aplicativ

1.6 Scurtă istorie despre rețelele Petri

2. Definiții fundamentale

2.1 Structura unei rețele Petri

2.2 Grafuri pentru rețele Petri

2.3 Marcajele rețelelor Petri

2.4 Reguli de funcționare pentru rețele Petri

2.5 Spațiul stărilor unei rețele Petri

2.6 Forme alternative pentru definirea rețelelor Petri

3. Modelarea cu ajutorul rețelelor Petri

3.1 Evenimente și condiții

3.2 Concurență și conflicte

3.3 Componenta hardware a calculatorului

3.4 Componenta software

3.5 Alte sisteme

3.6 Alte studii

4. Analiza rețelelor Petri

4.1 Probleme de analizat pentru rețelele Petri

4.2 Tehnici de analiză

4.3 Alte studii

5. Complexitate și decidabilitate

5.1 Reducere între probleme de analiză

5.2 Probleme de accesibilitate

5.3 Structuri mărginite de rețele Petri

5.4 Viabilitate și accesibilitate

5.5 Rezultate nedecidabile

5.6 Complexitatea problemei de accesibilitate

5.7 Alte studii

6. Limbaje pentru rețele Petri

6.1 Motivație

6.2 Concepte înrudite din teoria limbajelor formale

6.3 Definiția limbajelor rețelelor Petri

6.4 Proprietățile limbajelor rețelelor Petri

6.5 Proprietăți de închidere

6.6 Limbajele de rețele Petri și alte clase de limbaje

6.7 Rezultate suplimentare

6.8 Alte studii

7. Modele de rețele Petri extinse sau restricționate

7.1 Limitări ale modelării cu ajutorul rețelelor Petri

7.2 Extensii

7.3 Rețele Petri extinse și dispozitive de recunoaștere (Register Machines)

7.4 Subclase de rețele Petri

8. Modele înrudite pentru calculul parallel

8.1 Automate cu stări finite

8.2 Grafuri marcate

8.3 Grafuri computaționale [Karp și Miller 1966]

8.4 Sisteme P / V [Dijkstra 1968; Bruno et. al. 1972]

8.5 Sisteme de transmitere a mesajelor [Riddle 1971]

8.6 Grafuri UCLA [Ciostelow 1971; Cerf et. al. 1971; Cerf 1972; Cerf et. al. 1972]

8.7 Adunarea vectorilor și sisteme de înlocuire

8.8 Rețele Petri extinse

O scurtă teorie a multiseturilor

134 pagini

=== Teoria retelelor Petri si modelarea sistemelor ===

Teoria rețelelor Petri și modelarea sistemelor

Introducere

Rețelele Petri sunt un instrument pentru studiul sistemelor. Teoria rețelelor Petri permite unui sistem să fie modelat de către o rețea Petri, realizându-se astfel o reprezentare matematică a sistemului. Analiza rețelei Petri poate apoi să furnizeze informații importante despre structura și comportamentul dinamic al sistemului modelat, putând fi folosită pentru a evalua sistemul modelat și pentru a sugera îmbunătățiri sau schimbări. Astfel, dezvoltarea unei teorii a rețelelor Petri se bazează pe aplicarea rețelelor Petri în modelarea și proiectarea sistemelor.

Modelare

Rețelele Petri sunt folosite în modelare. În multe domenii, un fenomen nu este studiat direct, ci indirect cu ajutorul unui model al fenomenului. Un model este o reprezentare, cel mai adesea în termeni matematici, a ceea ce par a fi caracteristici importante ale obiectului sau sistemului studiat. Prin manipularea reprezentării se speră că se vor obține noi cunoștințe despre fenomenul modelat evitând pericolul, costul sau inconvenientele reprezentate de manipularea fenomenului real propriu-zis. Exemple ale utilizării modelării includ astronomia (unde modele ale nașterii, morții și interacțiunii dintre stele permit studierea teoriilor care se desfășoară pe perioade lungi de timp și cu mari cantități de materie și energie), fizica nucleară (unde atomii radioactivi și particulele subatomice studiate există pentru perioade foarte scurte de timp), sociologie (unde directa manipulare a grupurilor de oameni studiate poate crea probleme etice), biologie (unde modelele de sisteme biologice cer puțin spațiu, timp și hrană pentru a se dezvolta), și așa mai departe.

Majoritatea modelelor folosesc matematica. Caracteristicile importante ale celor mai multe fenomene fizice pot fi descrise numeric, iar relațiile dintre acestea prin ecuații sau inegalități. În particular, în științele naturale și inginerie, proprietăți precum masa, poziția, accelerația și forțele se pot descrie cu ajutorul ecuațiilor. Pentru a utiliza cu succes tehnica modelării, este necesară o bună cunoaștere atât a fenomenului modelat cât și a proprietăților tehnicilor de modelare. Astfel, matematica s-a dezvoltat ca o știință în parte datorită utilității sale în modelarea fenomenelor altor științe. De exemplu, calculele diferențiale s-au dezvoltat ca un răspuns indirect la necesitatea de a găsi o cale pentru modelarea proprietăților în continuă schimbare, precum poziția, viteza, și accelerația în fizică.

Dezvoltarea vitezei computerelor a crescut considerabil aria de utilizare și utilitatea modelării. Prin reprezentarea unui sistem ca un model matematic care va fi apoi implementat și rulat pe un computer devine posibilă modelarea de sisteme mai mari și mai complexe. Acest fapt a determinat apariția a numeroase studii referitoare la computere și tehnici de modelare pe computer. Computerele sunt implicate în modelare și ca o temă de modelare.

Caracteristici ale sistemelor

Sistemele computaționale sunt foarte complexe, chiar mari, fiind sisteme cu multe componente ce interacționează. Fiecare componentă poate fi suficient de complexă și la fel și modul în care interacționează cu alte componente din sistem. Acest fapt este valabil și în multe alte sisteme. Sistemele economice, sistemele legale, sistemele pentru controlul traficului și sistemele chimice, toate presupun componente individuale ce interacționează cu alte componente, posibil în moduri complexe.

Astfel, în ciuda diversității sistemelor de modelat, există totuși și multe părți comune. Acestea ar trebui să fie caracteristicile unui model folositor pentru aceste sisteme. O idee fundamentală este aceea că sistemul este compus din componente separate, ce interacționează între ele. Fiecare componentă poate fi la rândul ei un sistem, dar comportamentul ei poate fi descris independent de celelalte componente. Fiecare componentă are propria sa stare curentă. Starea curentă a unei componente este o abstractizare a informației relevante necesare pentru descrierea acțiunilor sale (viitoare). Cel mai adesea starea curentă a unei componente depinde de stările anterioare ale acesteia. De aceea, starea unei componente se poate schimba în timp. Conceptul de "stare" este foarte important în modelarea unei componente. De exemplu, în modelarea în sistem liniar a unei bănci, pot fi câțiva furnizori și câțiva clienți. Un furnizor poate fi fie liber (în așteptarea unui client care să-i solicite serviciile), fie ocupat (servind un client). În mod similar, un client poate fi fie liber (așteptând ca unul dintre furnizori să devină liber pentru a-l putea servi), fie ocupat (servit de un furnizor). În modelarea unui spital, starea unui pacient poate fi critică, gravă, bunicică, bună, sau excelentă.

Componentele unui sistem pot implica noțiunile de concurență sau paralelism. Activarea unei componente a unui sistem se poate produce simultan cu o altă activare a unei alte componente. Într-un sistem computațional, de exemplu, dispozitivele periferice pot opera toate concurent, controlate de către computer. Într-un sistem economic, fabricile pot produce unele produse în timp ce vânzătorii vând alte produse și consumatorii folosesc și ei alte produse, toate acestea în același timp.

Concurența activităților într-un sistem creează unele dificultăți în modelarea acestuia. De vreme ce componentele sistemului interacționează, este necesară realizarea unei sincronizări. Transferul de informație sau materiale de la o componentă la o alta necesită sincronizarea activării componentelor implicate. Această operație poate provoca situația în care o componentă așteaptă după o alta. Modalitatea de acționare a diferitelor componente poate fi foarte complexă și interacțiunile dintre componente greu de descris.

Dezvoltarea inițială a rețelelor Petri

Rețelele Petri sunt proiectate special pentru a modela sisteme cu componente cu interacțiune concurentă. Rețelele Petri au la bază studiile lui Carl Adam Petri. În lucrarea sa de doctorat, "Communikation mit Automaten" (Comunicarea cu automate), Petri formulează fundamentele unei teorii a comunicațiilor între componente asincrone ale unui sistem computațional, oprindeu-se mai ales asupra descrierii relațiilor cauzale dintre evenimente. Această lucrare a fost în principal o dezvoltare teoretică a conceptelor fundamentale pornind de la care s-a dezvoltat mai apoi teoria rețelelor Petri.

Munca lui Petri a ajuns în atenția lui A.W. Holt și a altora care lucrau la proiectul pentru teoria sistemelor informaționale (Information System Theory Project) în cadrul ADR (Applied Data Research, Inc.). Multe din teoriile inițiale, notațiile și reprezentările rețelelor Petri s-au dezvoltat prin munca la acest proiect (Information System Theory Project) și au fost publicate în raportul final al proiectului [Holt, ed. 1968], și într-un raport separat intitulat "Event and Conditions" (Evenimente și condiții) [Holt and Commoner, ed. 1970]. Această muncă a arătat cum pot fi aplicate rețelele Petri în modelarea și analiza sistemelor cu componente concurente.

Munca lui Petri a atras de asemenea atenția proiectului M.A.C. de la Institutul de Tehnologie din Massachusetts (M.I.T.). "The Computation Structures Camp" coordonat de profesorul Jack B. Dennis, a fost sursa a numeroase cercetări și articole publicate despre rețelele Petri, și de asemenea a numeroase dizertații și rapoarte. "The Computation Structures Camp" a ținut două conferințe asupra rețelelor Petri: Conferința proiectului M.A.C. asupra sistemelor concurente și calculului paralel, în 1970 la Woods Hole [Dennis, 1970] și conferința despre rețelele Petri și metodele aferente, din 1975 de la M.I.T. Ambele au fost utile pentru selectarea rezultatelor și abordărilor utile referitoare la teoria rețelelor Petri.

Utilizarea și studiul rețelelor Petri s-au răspândit mult în ultimii ani. Un laborator de lucru cu rețele Petri s-a ținut în Paris în 1977 ca o avanpremieră la cursul de "Teoria generală a rețelelor" (General Net Theory) din 1979 de la Hamburg. Un grup de studiu pentru rețelele Petri s-a format în Germania, în scopul cercetării și răspândirii ariei de aplicare a acestora.

Aplicații ale teoriei rețelelor Petri

Aplicarea practică a rețelelor Petri în proiectarea și analiza sistemelor se poate realiza în mai multe moduri. O abordare consideră rețelele Petri ca un instrument de analiză auxiliar. Pentru această abordare, sunt folosite tehnici de proiectare convenționale pentru a specifica un sistem. Acest sistem este modelat ca o rețea Petri și această rețea Petri este apoi analizată. Orice problemă de analiză se regăsește în fluxurile proiectate, de aceea trebuiesc efectuate modificări pentru a corecta fluxurile. Proiectul modificat poate apoi să fie modelat și analizat din nou. Ciclul se repetă până când se elimină toate problemele inacceptabile. Această abordare este reprezentată în diagrama din figura 1.1. Se poate observa că această abordare poate fi folosită de asemenea pentru a analiza un sistem existent, operațional.

Abordarea convențională descrisă mai sus pentru folosirea rețelelor Petri în proiectarea unui sistem necesită conversia construcției sistemului proiectat într-un model de rețea Petri. A mai fost de asemenea sugerată o abordare alternativă. În această abordare mai radicală, întreaga proiectare și documentare se face în termeni de rețele Petri. Tehnicile de analiză se aplică numai atât cât este necesar pentru a crea o rețea Petri fără erori. Apoi problema este de a transforma reprezentarea sub formă de rețea Petri în sistemul funcțional ce interesează. Aceste două abordări ale folosirii rețelelor Petri în proiectarea proceselor oferă diferite tipuri de probleme pentru cercetarea în domeniul rețelelor Petri.

În primul caz, trebuiesc dezvoltate tehnicile de modelare în vederea transformării sistemelor într-o reprezentare sub formă de rețea Petri; în al doilea caz, trebuiesc dezvoltate tehnicile de implementare pentru a transforma reprezentările sub formă de rețea Petri în sisteme. În ambele cazuri sunt necesare tehnici de analiză în vederea determinării proprietăților modelului nostru de rețea Petri. De aceea, prima noastră grijă în dezvoltarea unei teorii a rețelelor Petri este studierea proprietăților rețelelor Petri în sine.

Figura 1.1: Utilizarea rețelelor Petri în analiza și modelarea sistemelor

Sistemul este mai întâi modelat ca o rețea Petri și apoi acest model este analizat. Înțelegerea sistemului rezultat din analize va conduce spre un sistem ce se speră a fi mai bun. Cercetarea este orientată spre dezvoltarea de tehnici automate pentru modelarea și analiza sistemelor cu ajutorul rețelelor Petri.

Teoria rețelelor Petri: teoretic și aplicativ

Studiul rețelelor Petri s-a dezvoltat în două direcții;

Teoria rețelelor Petri aplicată (Applied Petri Net Theory) se ocupă mai ales cu aplicarea rețelelor Petri în modelarea sistemelor, analiza acestor sisteme, și introducerea rezultatului în sistemul modelat. Lucrul cu succes în acest domeniu necesită o bună cunoaștere a domeniului de aplicare, a rețelelor Petri, și a tehnicilor folosite împreună cu rețelele Petri.

Teoria pură a rețelelor Petri este studiul rețelelor Petri în vederea dezvoltării instrumentelor fundamentale, a tehnicilor și conceptelor necesare pentru aplicarea rețelelor Petri. Deși motivația pentru cercetarea în domeniul rețelelor Petri se bazează pe aplicații, este necesară o bază solidă a teoriei rețelelor Petri pentru a putea fii capabili să aplicăm rețelele Petri. Multă din munca efectuată cu rețele Petri s-a concentrat în acest punct asupra teoriei fundamentale despre teoria rețelelor, dezvoltând instrumente și abordări care s-ar putea să fie utile într-o bună zi în aplicarea rețelelor Petri pentru a specifica probleme din lumea reală. Acest studiu se concentrează în principal asupra teoriei fundamentale, păstrând rezultate din ambele direcții de cercetare ale rețelelor Petri. Aplicațiile care sunt date intenționează mai ales să demonstreze complexitatea și puterea rețelelor Petri și să motiveze dezvoltarea tehnicilor de analiză.

În acest sens, nu se încearcă tratarea amănunțită a întregii game de subiecte legate de rețelele Petri, dar se dorește să se ofere o bază solidă de termeni, concepții, abordări, rezultate și istorisiri despre rețele Petri, pentru a permite utilizarea și înțelegerea studiilor aprofundate asupra rețelelor Petri și pentru a oferi capacitatea aplicării acestei teorii pentru o gamă largă de aplicații. Vom începe cu câteva definiții formale și exemple de rețele Petri în capitolul 2, apoi vom demonstra puterea și utilitatea acestora.

Scurtă istorie despre rețelele Petri

Certificatul de naștere al rețelelor Petri a fost dizertația lui Petri, dar majoritatea studiilor din Statele Unite se bazează de asemenea pe raportul final al proiectului pentru teoria sistemelor informaționale (Information System Theory Project) care nu numai că a tradus în engleză studiul lui Petri, dar l-a și îmbunătățit considerabil. Raportul intitulat "Event and Conditions" [Holt and Commoner, ed. 1970], a fost de asemenea o parte importantă în dezvoltarea teoriei rețelelor Petri. Petri a prezentat un scurt raport la Congresul IFIP din 1962 care a fost tipărit în cele ce au urmat [Petri 1962b]. Acest raport se bazează pe ideile din studiul său.

Abordarea prezentată în această lucrare derivă din munca la "The Computation Structures Camp" la M.I.T. și s-a dezvoltat din munca lui Dennis [1970a], Patil [1970a], și a altora, culminând cu studiile lui Hack [1975c]. Keller a avut de asemenea o mare influență cu raportul său despre sistemele de înlocuire a vectorilor [Keller 1972] și prin punctul său de vedere asupra modelării [Keller 1975a].

Definiții fundamentale

În acest capitol vom da definiții formale pentru conceptele de bază din teoria rețelelor Petri. Conceptele de bază sunt folosite în cadrul prezentului studiu asupra rețelelor Petri și de aceea sunt fundamentale pentru o corectă înțelegere a rețelelor Petri.

Formalismele utilizate se bazează pe teoria multiseturilor, o extensie a teoriei mulțimilor. Conceptele relevante pentru această teorie a multiseturilor sunt prezentate în anexă.

Definițiile oferite aici sunt similare ca formă cu cele din teoria automatelor [Hopcroft and Ullman, 1969]. În fapt, ele definesc o nouă clasă de mașini, și anume automate rețele Petri. După cum vom vedea mai târziu (în capitolele 5, 6, 7 și 8), acest punct de vedere poate conduce la unele rezultate interesante în teoria limbajelor formale și în cea a automatelor.

Structura unei rețele Petri

O rețea Petri este compusă din patru părți:

o mulțime de locații S;

o mulțime de tranziții T;

o funcție de intrare I;

o funcție de ieșire O.

Funcțiile de intrare și ieșire sunt relații între T (mulțimea de tranziții) și S (mulțimea de locații). Funcția de intrare I este o funcție de la o tranziție tj la o colecție de locații I(tj) care poartă numele de locațiile de intrare ale tranziției. Funcția de ieșire O este o funcție de la o tranziție tj la o colecție de locații O(tj) care poartă numele de locațiile de ieșire ale tranziției. Structura unei rețele Petri este definită de locațiile și tranzițiile sale, de funcția sa de intrare și de cea de ieșire.

Definiția 2.1:

O structură de rețea Petri C este un 4-tuplu C = (P,T, I, O), unde:

P = {p1,…,pn} este o mulțime finită de locații, n 0;

T = {t1,…,tm} este o mulțime finită de tranziții, m 0;

Mulțimea locațiilor și mulțimea tranzițiilor sunt disjuncte: P T = .

I : T P este funcția de intrare, o funcție de la mulțimea tranzițiilor la colecția de locații

O : T P este funcția de ieșire, o funcție de la mulțimea tranzițiilor la colecția de locații

Cardinalitatea mulțimii P este n, și cardinalitatea mulțimii T este m. Vom nota un element arbitrar din P cu pi, 1 i n, și un element arbitrar din T cu tj, 1 j m.

Exemple de structuri de rețele Petri sunt date în figurile 2.1, 2.2 și 2.3.

Figura 2.1:

O structură de rețea Petri reprezentată ca un 4-tuplu.

C = (P, T, I, O), unde:

P = {p1,…,p5}

T = {t1,…,t4}

I(t1) = {p1}, I(t2) = {p2, p3, p5}, I(t3) = {p3}, I(t4) = {p4}

O(t1) = { p2, p3, p5}, O(t2) = {p5}, I(t3) = {p4}, I(t4) = {p2, p4}

Figura 2.2:

O structură de rețea Petri reprezentată ca un 4-tuplu.

C = (P, T, I, O), unde:

P = {p1,…,p6}

T = {t1,…,t5}

I(t1) = {p1}, I(t2) = {p3}, I(t3) = {p2, p3}, I(t4) = {p4, p5, p5, p6}, I(t5) = {p2}

O(t1) = { p2, p3}, O(t2) = {p3, p5, p5}, O(t3) = {p2, p4}, O(t4) = {p4}, O(t5) = {p6}

Figura 2.3:

O structură de rețea Petri reprezentată ca un 4-tuplu.

C = (P, T, I, O), unde:

P = {p1,…,p9}

T = {t1,…,t6}

I(t1) ={p1}, I(t2) = {p8}, I(t3) = {p2, p5}, I(t4) = {p3}, I(t5) = {p6, p7}, I(t6) = {p4, p9}

O(t1) = { p2, p3}, O(t2) = {p1, p7}, O(t3) = {p6}, O(t4) = {p4}, O(t5) = {p9}, O(t6) = {p7, p8}

O tranziție pi este o tranziție de intrare a unei tranziții tj dacă pi I(tj); pi este o tranziție de ieșire a unei tranziții tj dacă pi O(tj); Un multiset este o generalizare a noțiunii de mulțime care permite apariția în mod repetat a unui element. Anexa conține o descriere a acestei teorii. Folosirea multiseturilor în locul mulțimilor pentru intrări și ieșiri permite unei locații să fie intrare sau locație multiplă pentru o tranziție. Multiplicitatea unei locații de intrare pi a unei tranziții tj este numărul de apariții ale locației în multisetul de intrare al tranziției #(pi, I(tj)). Similar, multiplicitatea unei locații de ieșire pi a unei tranziții tj este numărul de apariții ale locației în multisetul de ieșire al tranziției #(pi, O(tj)). Dacă intrările și ieșirile sunt mulțimi (nu multiseturi), atunci multiplicitatea fiecărei locații este fie 0, fie 1.

Funcțiile de intrare și ieșire pot fi ușor extinse la funcții ce duc și locații în multiseturi de tranziții, în plus față de tranziții în multiseturi de locații. Definim o tranziție tj ca fiind o intrare a unei locații pi, dacă pi este o ieșire a tranziției tj. O tranziție tj este o ieșire a unei locații pi dacă pi este o intrare a tranziției tj.

Definiția 2.2:

Definim funcția de intrare I și funcția de ieșire O după cum urmează:

I : T P , O : T P, unde: #(tj, I(pi)) = #(pi, O(tj))

#(tj, O(pi)) = #(pi, I(tj))

Pentru rețeaua Petri din figura 2.1 funcțiile de intrare și ieșire extinse sunt:

I(p1) = {t1}, I(p2) = {t1, t4}, I(p3) = {t1,t4}, I(p4) = {t3}, I(p5) = {t1,t2}

O(p1) = {t1}, O(p2) = {t2}, I(p3) = { t1, t3}, I(p4) = {t4}, I(p5) = {t2}

Grafuri pentru rețele Petri

Majoritatea rezultatelor teoretice referitoare la rețele Petri se bazează pe definițiile formale ale structurilor de rețea Petri date în capitolul anterior. Totuși, o reprezentare grafică a unei structuri de rețea Petri este mult mai folositoare pentru a ilustra conceptele teoriei rețelelor Petri. Un graf pentru o rețea Petri este un multigraf orientat bipartit.

O structură de rețea Petri constă din locații și tranziții. Corespunzător acestora, un graf de rețea Petri are două tipuri de noduri. Un cerc reprezintă o locație; o bară reprezintă o tranziție. Deoarece un cerc reprezintă o locație, am numit cercurile locații. Similar, am numit barele tranziții.

Arcele direcționate (săgețile) conectează locațiile și tranzițiile, unele fiind direcționate de la locații la tranziții, altele de la tranziții la locații. Un arc direcționat de la o locație pi la o tranziție tj definește locația ca fiind o intrare a tranziției. Intrările multiple într-o tranziție sunt indicate prin arce multiple de la locațiile de intrare la tranziții. O locație de ieșire este indicată printr-un arc de la o tranziție la o locație. De asemenea, ieșirile multiple se indică prin arce multiple.

O rețea Petri este un multigraf, de vreme ce acceptă arce multiple de la un nod al grafului la un altul. În plus, deoarece arcele sunt direcționate, este un multigraf direcționat. Deoarece nodurile grafului pot fi partiționate în două rețele (locații și tranziții), astfel încât fiecare arc este direcționat de la un element al unei rețele (locație sau tranziție) la un element al celeilalte rețele (tranziție sau locație), acesta este un "graf orientat bipartit". Ne vom referi la el pur și simplu ca la un graf pentru rețelele Petri.

Definiția 2.3:

Un graf de rețea Petri este un "multigraf orientat bipartit" G = (V, A), unde V = {v1,…,vs} este o mulțime de vârfuri și A = {a1,…,ar} este un multiset de arce direcționate ai = (vj, vk), cu vj, vk V. Rețeaua V poate fi partiționată în două rețele disjuncte P și T astfel încât V = P T, P T = și pentru fiecare arc distinct ai A, dacă ai = (vj, vk), atunci fie vj P și vk T, fie vj T și vk P.

Figura 2.4: Un graf de rețea Petri echivalent cu structura din figura 2.1

Figura 2.5: Un graf de rețea Petri echivalent cu structura din figura 2.2

Figura 2.6: Un graf de rețea Petri echivalent cu structura din figura 2.3

Figurile 2.4, 2.5 și 2.6 reprezintă grafuri de rețele echivalente cu structurile de rețele Petri din figurile 2.1, 2.2 și 2.3.

Pentru a demonstra echivalența acestor două reprezentări ale rețelelor Petri, ca structură respectiv ca graf, vom arăta cum se transformă una în cealaltă. Să presupunem că avem C = (P, T, I, O) cu P = {p1,…,pn}, T = {t1,…,tm}. Acum putem defini un graf Petri după cum urmează:

Definiția 2.4:

Definim V= P T. Definim A ca un multiset de arce direcționate, pentru toate pi P și tj T:

#((pi, tj), A) = #(pi, I(tj))

#((tj, pi), A) = #(pi, O(tj))

G = (V, A) este un graf de rețea Petri care este echivalent cu structura C = (P, T, I, O) de rețea Petri.

Conversia în direcția opusă (dintr-un graf de rețea Petri într-o structură de rețea Petri) este similară. Apare o problemă interesantă la transformarea dintr-un graf de rețea Petri într-o structură de rețea Petri, și anume dacă mulțimea de vârfuri este partiționată în două mulțimi S și R, care mulțime va fi mulțimea locațiilor și care cea a tranzițiilor? Ambele selecții posibile permit definirea unei rețele Petri deoarece cele două structuri rezultate au locațiile și tranzițiile interschimbabile.

Duala unei rețele Petri C = (P, T, I, O) este rețeaua Petri = (T, P, I, O) rezultată din interschimbarea locațiilor și tranzițiilor. Structura grafului se păstrează, interschimbând cercurile și barele grafului pentru a indica schimbarea suferită. Figura 2.7 indică duala rețelei Petri din figura 2.4. Duala este un aspect des utilizat în teoria grafurilor și se va dovedi că este, de asemenea, un concept interesant vizavi de rețelele Petri. Totuși, acest concept de dualitate nu a fost folosit în cercetările efectuate asupra rețelelor Petri, datorită mai ales faptului că este dificil de definit duala unei rețele Petri marcate. Rețelele Petri marcate vor fi discutate în cele ce urmează.

Figura 2.7 Duala rețelei Petri din figura 2.4

Marcajele rețelelor Petri

Un marcaj este o asignare de jetoane locațiilor unei rețele Petri. Conceptul de jeton este un concept fundamental în teoria rețelelor Petri (la fel ca locațiile și tranzițiile). Jetoanele sunt asignate locațiilor unei rețele Petri și pot fi gândite ca aparținând acestora. Numărul și poziția jetoanelor se pot schimba în timpul funcționării unei rețele Petri. Jetoanele sunt folosite pentru a defini funcționarea unei rețele Petri.

Definiția 2.5:

Un marcaj al unei rețele Petri C = (P, T, I, O) este o funcție de la mulțimea locațiilor P la mulțimea numerelor naturale N, și anume : P N.

Marcajul poate fi, de asemenea, definit ca un vector n-dimensional = (1…n), unde n = card(P) și i = 1..n, i N. Vectorul dă pentru fiecare locație pi din rețeaua Petri numărul de jetoane pentru acea locație. Numărul de jetoane pentru poziția pi este i , unde i = 1..n.

Definițiile unui marcaj ca o funcție și ca un vector se bazează, în mod evident, pe relația (pi) = i. Notația funcțională este oarecum mai generală și de aceea mai des folosită.

O rețea marcată M = (C, ) este formată dintr-o structură de rețea Petri C = (P, T, I, O) și un marcaj . Acest fapt se mai notează uneori M = (P, T, I, O, ).

Într-un graf de rețea Petri, jetoanele se reprezintă printr-un mic punct în cercurile care reprezintă locațiile unei rețele Petri. Figurile 2.11 și 2.12 sunt exemple de grafuri reprezentate ca rețele Petri marcate.

Figura 2.8: O rețea Petri marcată. Structura de rețea Petri este aceeași ca în figurile 2.1 și 2.4. Marcajul este = (1 2 0 0 1).

Figura 2.9 O rețea Petri marcată. Structura de rețea Petri este aceeași ca în Figura 2.1, dar marcajul este diferit.

Deoarece numărul de jetoane care pot fi asignate unei locații a unei rețele Petri este nemărginit, există o infinitate de marcaje pentru o rețea Petri. Mulțimea tuturor marcajelor pentru o rețea Petri cu n locații este mulțimea tuturor vectorilor n-dimensionali din Nn. Această mulțime, de asemenea tot infinită, este desigur nenumărabilă.

Reguli de funcționare pentru rețele Petri

Funcționarea unei rețele Petri este controlată de numărul și distribuția jetoanelor în rețeaua Petri. Jetoanele sunt rezidente în locații și controlează execuția tranzițiilor rețelei. O rețea Petri se execută prin declanșarea tranzițiilor. O tranziție se declanșează prin mutarea jetoanelor din locațiile de intrare și crearea de noi jetoane care sunt distribuite în locațiile de ieșire.

O tranziție se poate declanșa dacă este posibilă. O tranziție este posibilă dacă fiecare dintre locațiile sale de intrare conține un număr de jetoane mai mare sau egal cu numărul de arce de la acea locație la tranziție. Sunt necesare jetoane multiple pentru arce multiple de intrare. Jetoanele din locațiile de intrare care permit o tranziție sunt jetoanele sale de validare. De exemplu, dacă locațiile p1 și p2 sunt intrările tranziției t4, atunci t4 este permisă dacă atât p1 cât și p2 au fiecare cel puțin un jeton. Pentru o tranziție t7 cu multisetul de intrare {p6, p6, p4}, locația p6 trebuie să aibă cel puțin trei jetoane pentru a face posibilă tranziția t7.

Definiția 2.6:

O tranziție tj T dintr-o rețea Petri marcată C = (P, T, I, O) cu marcajul este permisă dacă pentru toate pi P, (pi) #(pi, I(tj)).

O tranziție se declanșează prin mutarea tuturor jetoanelor posibile din locațiile de intrare și depozitarea lor în fiecare dintre locațiile de ieșire, câte un jeton pentru fiecare arc de la tranziție la locație. Jetoanele multiple sunt produse pentru arce de ieșire multiple. O tranziție t3 cu I(t3) = {p2} și O(t3) = {p7, p13} este posibilă ori de câte ori există cel puțin un jeton în poziția p2. Tranziția p3 se declanșează prin mutarea unui jeton din poziția p2 și depozitarea unui jeton în poziția p7 și a altuia în poziția p13. Jetoanele suplimentare din locația p2 nu sunt afectate de declanșarea tranziției t3 (deși pot valida declanșări suplimentare ale t3). O tranziție t2 cu I(t2) = {p21, p23} și O(t2) = {p23, p25, p25} se declanșează prin mutarea unui jeton din p21 și a unuia din p23 și depozitarea unui jeton în p23 și a două jetoane în p25 (deoarece p25 are multiplicitatea doi).

Declanșarea unei tranziții va schimba în general marcajul al rețelei Petri într-un nou marcaj '. Se observă că, deoarece numai tranzițiile permise se pot declanșa, numărul de jetoane din fiecare locație rămâne întotdeauna pozitiv la declanșarea unei tranziții. Prin declanșarea unei tranziții nu se va încerca niciodată să se mute un jeton care nu este acolo. Dacă nu sunt suficiente jetoane în oricare dintre locațiile de intrare ale unei tranziții, atunci aceasta nu este posibilă și nu se poate declanșa.

Definiția 2.7:

O tranziție tj într-o rețea Petri marcată cu marcajul se poate declanșa de fiecare dată când este posibilă. Declanșarea unei tranziții tj posibile produce un nou marcaj ' definit de relația:

'(pi) = (pi) – #(pi, I(tj)) + #(pi, O(tj))

Figura 2.10: Ilustrează cum marcajul unei locații se schimbă când o tranziție tj se declanșează. Fiecare locație poate sau nu să fie intrare sau ieșire a tranziției. Această figură ilustrează numai cazurile în care multiplicitatea este zero sau unu.

Ca un exemplu, vom considera rețeaua Petri marcată din figura 2.11. Cu acest marcaj, trei tranziții sunt posibile, și anume tranzițiile t1, t3 și t4. Tranziția t2 nu este posibilă deoarece nu se află nici un jeton în nici una din locațiile p2 sau p3, care sunt amândouă intrări ale tranziției t2. Deoarece tranzițiile t1, t3 și t4 sunt toate posibile, oricare dintre acestea se poate declanșa. Dacă tranziția t4 se declanșează, mută câte un jeton din fiecare intrare și depozitează câte un jeton în fiecare ieșire. Astfel, mută un jeton din p5, depozitează un jeton în p3 și crește numărul de jetoane din p4 de la doi la trei. Astfel, noul marcaj ce rezultă din declanșarea tranziției t4 este cel din figura 2.12.

În rețeaua Petri marcată din figura 2.12, numai tranzițiile t1 și t3 sunt posibile. Prin declanșarea tranziției t1 se va muta un jeton din p1 și se vor depozita jetoane în p2, p3 și p4 (două jetoane în p4 deoarece este o ieșire multiplă a tranziției t1). Acest fapt produce marcajul din figura 2.13. În această rețea Petri marcată, tranzițiile t2 și t3 sunt posibile. Declanșarea tranziției t3 va determina producerea marcajului din figura 2.14, unde două jetoane au fost mutate din p4 și unul a fost depozitat în p5.

Declanșarea tranzițiilor poate continua atâta timp cât există cel puțin o tranziție posibilă. Când nu mai există nici o tranziție posibilă, execuția se oprește.

Figura 2.11: O rețea Petri marcată pentru a ilustra regulile de declanșare. Tranzițiile t1, t3 și t4 sunt posibile.

Figura 2.12 Marcajul rezultat din declanșarea tranziției t4 din figura 2.11.

Figura 2.13 Marcajul rezultat din declanșarea tranziției t1 din figura 2.12.

Figura 2.14: Marcajul rezultat din declanșarea tranziției t3 din figura 2.13

Spațiul stărilor unei rețele Petri

Starea unei rețele Petri este definită de marcajul său. Declanșarea unei tranziții reprezintă o schimbare în starea rețelei Petri printr-o schimbare în marcajul rețelei. Spațiul stărilor unei rețele Petri cu n locații este mulțimea tuturor marcajelor, adică Nn. Schimbarea de stare cauzată de declanșarea unei tranziții este definită de o funcție de schimbare numită funcție de tranziție, care se aplică unui marcaj (stare) și unei tranziții tj și produce noul marcaj (stare) care rezultă din declanșarea tranziției tj în marcajul . Deoarece tranziția tj poate să se declanșeze numai dacă este posibilă, atunci (, tj) = ', unde ' este marcajul care rezultă din jetoanele rămase în intrările lui tj și cele adăugate în ieșirile lui tj.

Definiția 2.8:

Funcția de tranziție : Nn x T Nn pentru o rețea Petri C = (P, T, I, O) cu marcajul și tranzițile tj T este definită dacă și numai dacă (pi) #(pi, I(tj)), pentru toți pi P.

Dacă (, tj) este definită, atunci (, tj) = ', unde ' = (pi) – #(pi, I(tj)) + #(pi, O(tj)), pentru toți pi P.

Dată fiind o rețea Petri C = (P, T, I, O) și un marcaj inițial o, putem executa rețeaua Petri prin declanșări succesive de tranziții. Declanșarea unei tranziții posibile tj în marcajul inițial produce un nou marcaj 1 = (o, tj). În acest nou marcaj, putem să declanșăm orice tranziție posibilă, să spunem tk, ceea ce va determina apariția unui nou marcaj 2 = (1, tk). Această operație poate continua atâta timp cât există cel puțin o tranziție posibilă în fiecare marcaj. Dacă ajungem la un marcaj în care nici o tranziție nu este posibilă, atunci nici o tranziție nu poate să se declanșeze, și deci funcția de tranziție este nedefinită pentru toate tranzițiile. Prin urmare execuția trebuie să se oprească.

Din execuția unei rețele Petri rezultă două secvențe: secvența de marcaje (o, 1, 2,…) și secvența de tranziții (tjo, tj1, tj2,…). Legătura dintre aceste două secvențe este dată de relația

(k, tjk) = k+1, pentru k = 0,1,2,…. Dată fiind o secvență de tranziții și o, putem cu ușurință deriva secvența de marcaje pentru execuția rețelei Petri, și, cu excepția câtorva cazuri degenerative, dată fiind o referință la secvența de marcaje, putem deriva secvența de tranziții. De aceea, amândouă aceste secvențe oferă o înregistrare a modului de execuție a rețelei Petri.

Într-un marcaj , o mulțime de tranziții va fi posibilă și va putea să se declanșeze. Rezultatul declanșării unei tranziții dintr-un marcaj este un nou marcaj '. Spunem că ' este "direct accesibil" din ; de aceea putem ajunge direct în starea ' din starea .

Definiția 2.9:

Pentru o rețea Petri C = (P, T, I, O) cu marcajul , un marcaj ' este "direct accesibil" din dacă există o tranziție tj T astfel încât (, tj) = '.

Putem extinde acest concept pentru a defini mulțimea de marcaje "accesibile" pentru o rețea Petri marcată. Dacă ' este direct accesibil din , și '' este direct accesibil din ', atunci spunem că '' este accesibil din . Vom defini mulțimea "de accesibilitate" R(C, ) a unei rețele Petri C cu marcajul ca fiind mulțimea formată din toate marcajele "accesibile" din . Un marcaj ' este în R(C, ) dacă există o secvență de declanșări de tranziții care va schimba marcajul în marcajul '. Relația de "accesibilitate" este închiderea tranzitivă și reflexivă a relației de "direct accesibilitate".

Definiția 2.10:

Mulțimea de accesibilitate R(C, ) pentru o rețea Petri C = (P, T, I, O) cu marcajul este cea mai mică mulțime de marcaje definită după cum urmează:

R(C, );

Dacă ' R(C, ) și '' = (', tj) pentru unii tj T, atunci '' R(C, ).

Pentru rețeaua Petri din figura 2.15 și marcajul = (1 0 0), două marcaje sunt direct accesibile: (0 1 0) și (1 0 1). Din (0 1 0) nu este accesibil nici un marcaj, deoarece nu este posibilă nici o tranziție. Totuși, din (1 0 1) sunt accesibile marcajele (0 1 1) și (1 0 2). Folosind tehnicile ce vor fi dezvoltate în capitolul 4, putem arăta că mulțimea de accesibilitate R(C, ) este {(1 0 n), (0 1 n) / n 0}.

Este utilă extinderea funcției de tranziție la o funcție care să ducă un marcaj și o secvență de tranziții într-un nou marcaj. Pentru o secvență de tranziții tj1, tj2,…, tjk și un marcaj , marcajul ' = (, tj1, tj2,…, tjk) este rezultatul declanșării mai întâi a tranziției tj1, apoi a tranziției tj2, și așa mai departe până la tranziția tjk. (Acest fapt este posibil, desigur, numai dacă fiecare dintre aceste tranziții este posibilă atunci când îi vine rândul să fie declanșată.)

Definiția 2.11:

Funcția de tranziție extinsă este definită pentru un marcaj și o secvență de tranziții T* după cum urmează:

(, ) =

(, tj) = ((, tj), )

În general se folosește această funcție de tranziție extinsă.

Figura 2.15: O rețea Petri marcată

Forme alternative pentru definirea rețelelor Petri

Teoria rețelelor Petri a fost dezvoltată de un număr mare de oameni, ce au lucrat la momente diferite în locuri diferite, folosind instrumente diferite de studiu. În parte și datorită acestei diversități, multe dintre conceptele fundamentale au fost definite de diverși cercetători în moduri diferite. Vom prezenta unele dintre aceste variante pentru a ilustra că nu există o diferență substanțială între definiții.

Rețelele Petri originale [Petri 1962a], de exemplu, nu permiteau arce multiple între locații și tranziții. Acest fapt este echivalent cu a defini intrările și ieșirile unei tranziții ca fiind mulțimi de locații (nu multiseturi). Mai mult, regula de declanșare a fost restricționată la a cere existența unui jeton în fiecare locație de intrare și a nici unuia în locațiile de ieșire. O tranziție se declanșează prin mutarea jetoanelor din intrări (care acum devin astfel vide) și depozitarea acestora în ieșiri (care anterior erau vide și devin pline prin această operație). O tranziție poate să nu se declanșeze dacă se află deja un jeton într-o locație de ieșire. De aceea, un marcaj asignează pentru fiecare locație fie zero, fie un singur jeton și avem : P {0,1}. Ar trebui să fie evident că o rețea cu numai n locații are exact 2n marcaje posibile, un număr finit de stări.

Munca de pionierat a ADR, prin Holt și "The Information System Theory Project" [Holt 1968], a continuat cu aceste definiții, dar pe măsură ce munca progresa, limitările acestui model au devenit evidente. Studiile lui Holt și Commoner prezentate la conferința de la Woods Hole [Holt and Commoner 1970] au generalizat clasa de marcaje și regula de declanșare pentru a permite marcaje arbitrare, : P {0,1,2,…}. Aceste noțiuni stau la baza modelului de rețea Petri așa cum este el definit astăzi (cu excepția caracteristicii de a avea arce multiple).

Multe din cercetările inițiale nu dau o descriere formală a modelelor, ci mai degrabă una informativă asupra componentelor relevante, precum locații, jetoane, tranziții și reguli de declanșare. Una dintre primele definiții formale a fost dată de Patil [1970a] în lucrarea sa de doctorat, unde o rețea Petri a fost definită ca un 4-tuplu (T, P, A, B), unde T este mulțimea tranzițiilor, P mulțimea locațiilor, A mulțimea arcelor și B marcajele inițiale. Arcele din mulțimea A conectează fie o locație cu o tranziție, fie o tranziție cu o locație. Astfel, A (P x T) (T x P). Multe studii referitoare la rețelele Petri se bazează pe această definiție și definesc o rețea Petri ca un triplet (P, T, A) cu o funcție separată de marcaje.

Conversia de la forma (P, T, A) a definiției, la funcții de intrare și ieșire separate este descrisă în linii mari în cele ce urmează. Mulțimea de arce este împărțită într-o mulțime de arce de intrare {(pi, tj) / (pi, tj) A} și una de arce de ieșire {(tj, pi) / (tj, pi) A}. Această formă conduce direct la generalizarea prin care se permit intrări și ieșiri multiple. Este necesar doar să se atașeze o multiplicitate fiecărui arc de intrare și de ieșire.

Hack [1975c] a stabilit o definiție a rețelelor Petri ca un 4-tuplu (P, T, F, B), unde P este mulțimea de locații și T mulțimea de tranziții. F și B sunt funcții ce duc locații și tranziții în numărul de jetoane necesare pentru intrare (F), sau produse pentru ieșire (B). Astfel, o tranziție tj poate să se declanșeze numai dacă în fiecare locație pi P sunt cel puțin F(tj, pi) jetoane. O tranziție se declanșează prin mutarea a F(tj, pi) jetoane din fiecare locație de intrare și depozitarea a B(tj, pi) jetoane în fiecare locație de ieșire. Funcțiile F și B pot fi reprezentate în formă matriceală.

În studiul său, Peterson [Peterson 1973] a încercat să combine tranzițiile cu intrările și ieșirile acestora prin definirea unei tranziții ca o pereche ordonată de multiseturi de locații,

tj P x P. Prima componentă a perechii este multisetul de intrări în tranziții; a doua componentă este multisetul de ieșiri din tranziții. Această abordare reduce conceptele fundamentale ale teoriei la locații și jetoane, deoarece tranzițiile sunt structuri compuse din locații și fost utilă în particular pentru a permite definirea simplă a tranzițiilor pentru o rețea Petri existentă.

Aceste definiții diferă de cea prezentată aici numai prin notații. Pentru majoritatea studiilor asupra rețelelor Petri, diferențele în definiții apar numai la nivel de notații. Totuși, în unele cazuri, definițiile pot restricționa clasa rețelelor Petri nepermițând arce de intrare sau ieșire multiple, sau restricționând forma tranzițiilor, astfel încât acestea să trebuiască să aibă o mulțime de locații de intrare nevidă și o mulțime de locații de ieșire nevidă, sau astfel încât mulțimea locațiilor de intrare și cea a locațiilor de ieșire să fie disjuncte (fără bucle).

Dar, chiar și aceste diferențe sunt neimportante, după cum se va vedea în capitolul 5.

Modelarea cu ajutorul rețelelor Petri

Rețelele Petri au fost proiectate și folosite mai ales pentru modelare. Multe sisteme, în special acelea cu componente separate, pot fi modelate cu ajutorul rețelelor Petri. Sistemele pot fi de multe tipuri diferite: computer hardware, computer software, sisteme fizice, sisteme sociale și așa mai departe. Rețelele Petri sunt folosite pentru a modela apariția a numeroase evenimente și activități dintr-un sistem. În particular, rețelele Petri pot modela fluxul de informații sau alte resurse dintr-un sistem.

În acest capitol vor fi prezentate câteva exemple de tipuri de sisteme care au fost modelate cu ajutorul rețelelor Petri. Din această prezentare se va vedea marea clasă a sistemelor care pot fi modelate cu ajutorul rețelelor Petri, unele din tehnicile de modelare care sunt folosite, și unele din proprietățile pe care dorim să le aibă sistemele modelate.

Evenimente și condiții

O privire simplă asupra unui sistem din punctul de vedere al rețelelor Petri se concentrează asupra a două concepte de bază: evenimente și condiții. Evenimentele sunt acțiuni care au loc în sistem. Apariția acestor evenimente este controlată de starea sistemului. Starea sistemului poate fi descrisă ca o mulțime de condiții. O condiție este un predicat sau descriere logică a stării sistemului. Astfel, o condiție poate fi fie adevărată, fie falsă.

Deoarece evenimentele sunt acțiuni, ele se pot produce. Pentru ca un eveniment să se producă, s-ar putea să fie necesar ca anumite condiții să fie adevărate. Acestea se numesc precondițiile evenimentului. Apariția evenimentului poate determina ca precondițiile să nu mai fie adevărate, și poate stabili ca alte condiții, numite postcondiții, să devină adevărate.

Ca un exemplu, considerăm problema modelării unui atelier simplu. Atelierul așteaptă până când apare un ordin și apoi îl prelucrază și îl trimite afră pentru distribuire. Condițiile pentru sistem sunt:

Atelierul este în așteptare.

A sosit un ordin și este în așteptare.

Atelierul prelucrează ordinul.

Prelucrarea ordinului s-a încheiat.

Evenimentele vor fi:

Sosirea unui ordin.

Atelierul începe prelucrarea ordinului.

Atelierul termină prelucrearea ordinului.

Ordinul este trimis pentru distribuire.

Precondițiile evenimentului 2 („Atelierul începe prelucrarea ordinului.”) sunt evidente: (a)

„Atelierul este în așteptare.” și (b) „A sosit un ordin și este în așteptare.”. Postcondiția evenimentului 2 este (c) „Atelierul prelucrează ordinul.”. Similar, putem să definim precondițiile și postcondițiile celorlalte evenimente și să construim următorul tabel de evenimente cu precondițiile și postcondițiile corespunzătoare.

O astfel de privire asupra unui sistem poate fi ușor modelată ca o rețea Petri. Condițiile sunt modelate ca locații într-o rețea Petri; evenimentele sunt modelate prin tranziții. Intrăriile unei tranziții sunt precondițiile evenimentului corespunzător; ieșirile sunt postcondițiile. Apariția unui eveniment corespunde cu declanșarea tranziției corespunzătoare. O condiție adevărată este reprezentată de existența unui jeton în locația corespunzătoare condiției. Când o tranziție se declanșează, mută jetoanele de validare reprezentând îndeplinirea precondițiilor și creează noi jetoane reprezentând îndeplinirea postcondițiilor.

Rețeaua Petri din figura 3.1 este un model de rețea Petri pentru exemplul de mai sus cu atelierul. Am etichetat fiecare tranziție și locație cu evenimentul sau condiția corespunzătoare.

Figura 3.1: Un model de rețea Petri pentru un atelier simplu

De asemenea, pot fi modelate sisteme mai complicate. Atelierul poate avea trei mașini diferite M1, M2, și M3 și doi operatori F1 și F2. Operatorul F1 poate opera mașinile M1 și M2, iar operatorul F2 poate opera mașinile M1 și M3. Lucrările necesită două stagii de prelucrare. Mai întâi acestea trebuie prelucrate de mașina M1, apoi de oricare dintre mașinile M2, sau M3. Acest sistem mai complicat va avea următoarele condiții:

A sosit o lucrare și așteaptă să fie prelucrată de M1.

O lucrare a fost prelucrată de M1 și așteaptă să fie prelucrată de M2 sau M3.

Prelucrarea lucrării s-a terminat.

Mașina M1 este liberă.

Mașina M2 este liberă.

Mașina M3 este liberă.

Operatorul F1 este liber.

Operatorul F2 este liber.

Mașina M1 este operată de F1.

Mașina M1 este operată de F2.

Mașina M2 este operată de F1.

Mașina M3 este operată de F2.

Pot apărea următoarele evenimente:

Sosește un ordin.

Operatorul F1 pornește prelucrarea lucrării pe mașina M1.

Operatorul F1 termină prelucrarea lucrării pe mașina M1.

Operatorul F2 pornește prelucrarea lucrării pe mașina M1.

Operatorul F2 termină prelucrarea lucrării pe mașina M1.

Operatorul F1 pornește prelucrarea lucrării pe mașina M2.

Operatorul F1 termină prelucrarea lucrării pe mașina M2.

Operatorul F2 pornește prelucrarea lucrării pe mașina M3.

Operatorul F2 termină prelucrarea lucrării pe mașina M3.

Ordinul este trimis pentru livrare.

Precondițiile și postcondițiile fiecărui eveniment sunt:

Rețeaua Petri pentru acest sistem este reprezentată în Figura 3.2.

Figura 3.2: Un exemplu de atelier mai complex, modelat ca o rețea Petri

Un exemplu similar poate fi prezentat pentru un sistem de calcul care procesează sarcini de la un dispozitiv de intrare și scoate rezultatele pe un dispozitiv de ieșire. Sarcinile apar pe dispozitivul de intrare. Când procesorul este liber și se află o sarcină pe dispozitivul de intrare, procesorul începe prelucrarea sarcinii. Când prelucrarea sarcinii este completă, aceasta este trimisă pe dispozitivul de ieșire; procesorul fie continuă cu o altă sarcină, dacă mai există vreuna disponibilă, fie așteaptă până când sosește o nouă sarcină pe dispozitivul de ieșire. Acest sistem poate fi modelat cu ajutorul rețelei Petri din figura 3.3.

Figura 3.3: Modelarea unui sistem de calcul simplu

Concurență și conflicte

Aceste exemple ilustrează unele probleme vizavi de rețelele Petri și de sistemele care pot fi modelate de către acestea. O problemă este paralelismul (concurența) inerent. În modelul de rețea Petri, două evenimente care sunt permise și nu interacționează se pot produce independent. Nu este necesară sincronizarea evenimentelor, decât dacă acest fapt este cerut de către sistemul care este modelat. Când este necesară sincronizarea, este simplu de modelat și acest lucru. Astfel, sistemele Petri par ideale pentru modelarea sistemelor cu control distribuit cu procese multiple ce se execută concurent în timp.

O altă caracteristică majoră a rețelelor Petri este natura lor asincronă. Nu există o măsură inerentă pentru fluxul de timp într-o rețea Petri. Aceasta reflectă o filozofie a timpului care arată că singura proprietate importantă a acestuia, dintr-un punct de vedere logic, constă în definirea unei ordini parțiale a apariției evenimentelor. Evenimentele consumă cantități diferite de timp în viața reală, și variabilitatea lor este reflectată în modelele realizate cu ajutorul rețelelor Petri prin faptul că se realizează controlul secvenței de evenimente fără a depinde de noțiunea de timp. Structura de rețea Petri în sine conține toate informațiile necesare pentru a defini secvențele posibile de evenimente. Astfel, în figura 3.3, evenimentul „Un job este terminat” trebuie să fie ulterior evenimentului „A început un job.”. Totuși, nici o informație nu este dată și nici necesară, referitor la cantitatea de timp necesară pentru executarea unei sarcini.

Executarea unei rețele Petri (și comportamentul sistemului pe care îl modelează) este văzută aici ca o secvență de evenimente discrete. Ordinea apariției evenimentelor este una din cele mai multe permise de structura de bază. Aceste fapte conduc la un nedeterminism aparent în execuția rețelelor Petri. Dacă, la orice moment, este posibilă mai mult de o tranziție, atunci oricare dintre cele câteva tranziții posibile poate fi următoarea ce se va declanșa. Din punctul de vedere al modelului de execuție clasic, alegerea tranziției care se va declanșa se face într-o manieră nedeterministă, adică aleatoriu. Această caracteristică a rețelelor Petri reflectă faptul că în situațiile din viața reală în care unele lucruri se întâmplă concurent, ordinea aparentă a apariției evenimentelor nu este unică, ci poate apărea orice mulțime de secvențe de evenimente. Totuși, ordinea parțială în care evenimentele se întâmplă este unică.

Teoria relativității trebuie de asemenea considerată. Unul dintre conceptele de bază ale teoriei relativității este acela că comunicarea nu este instantanee, dar informația despre apariția unui eveniment se propagă prin spațiu cu o viteză mărginită de viteza luminii. Concluzia este că, dacă două evenimente pot apărea simultan, fără nici o relație cauzală între ele, atunci ordinea de apariție poate părea diferită pentru doi observatori diferiți. Pentru două evenimente A și B care apar în același timp, un observator staționat lângă evenimentul A va primi informația referitoare la evenimentul A înaintea celei referitoare la evenimentul B. Observatorul poate deduce astfel că evenimentul A s-a întâmplat înaintea evenimentului B. Pe de altă parte, un observator diferit staționat lângă evenimentul B, poate determina că exact secvența inversă de evenimente s-a întâmplat.

Aceste considerații, deși necesare pentru o înțelegere completă a evenimentelor, introduce o complexitate considerabilă în descrierea și analiza comportamentului dinamic al unei rețele Petri când este văzut ca o secvență de tranziții ce se declanșează. Pentru limitarea acestei complexități este acceptată, în general, o limitare a sistemelor modelate cu ajutorul rețelelor Petri. Declanșarea unei tranziții (și a evenimentului asociat) este considerată a fi un eveniment instantaneu, care ia zero unități de timp, iar apariția a două evenimente simultan nu este posibilă. Evenimentele modelate se numesc evenimente primare; evenimentele primare sunt instantanee și nu sunt simultane. (Se afirmă uneori că timpul este o variabilă reală continuă. De aceea, dacă asociem un timp de apariție fiecărui eveniment, probabilitatea ca două variabile reale continue alese separat să fie identic egale este zero, și de aceea evenimentele nu sunt simultane.)

Un eveniment care nu este primar este un eveniment care nu ia zero unități de timp. Operațiile care nu sunt primare pot fi simultane și de aceea se pot suprapune în timp. Deoarece majoritatea evenimentelor din lumea reală durează, acestea sunt evenimente care nu sunt primare și de aceea nu pot fi corect modelate prin tranziții într-o rețea Petri. Totuși, acest fapt nu cauzează probleme în modelarea unui sistem. Un eveniment care nu este primar poate fi descompus în două evenimente primare: „Începe evenimentul care nu este primar.” și „Se termină evenimentul care nu este primar” și o condiție, „Se întâmplă evenimentul care nu este primar”. Acest lucru poate fi modelat așa cum se arată în figura 3.4

Figura 3.4: Modelarea unui eveniment care nu este primar

Petri și ceilalți au sugerat că evenimentele care nu sunt primare ar trebui reprezentate într-o rețea Petri printr-un dreptunghi [Petri 1975], așa cum se arată în figura 3.5, cu evenimentele primare reprezentate prin bare, ca și mai înainte. Astfel se vor simplifica unele rețele Petri, cum este cea din figura 3.6, care este echivalentă cu rețeaua Petri din figura 3.3. Totuși, deoarece conceptul sugerat poate, în principal, să fie explicat în termeni de construcții mai simple, nu vom folosi notația cu dreptunghi în acest text. Notația cu dreptunghi poate fi considerată valoroasă în modelarea unui sistem complex cu câteva nivele ierarhice, deoarece permite tuturor subrețelelor să fie abstractizate la un singur element al rețelei. Este similar ca sens conceptelor de subrutină sau macro din limbajele de programare.

Declanșarea nedeterministă și nesimultană a tranzițiilor în modelarea sistemelor concurente este indicată în figura 3.7. În această situație, cele două tranziții posibile nu se afectează reciproc în nici un fel, și secvențele posibile de evenimente includ unele în care apare mai întâi una dintre tranziții, și altele în care apare mai întâi cealaltă tranziție.

Figura 3.7: Concurența

Aceste două tranziții se pot declanșa în orice ordine.

Cealaltă situație în care simultaneitatea este mai dificil de mânuit și care poate fi controlată prin definirea de evenimente care nu apar simultan, este ilustrată în figura 3.8. Aici, cele două tranziții posibile sunt în conflict. Se poate declanșa numai o singură tranziție, deoarece, prin declanșare, jetonul din intrarea comună este mutat și dezactivează cealaltă tranziție.

Figura 3.8: Conflict

Tranzițiile tj și tk sunt în conflict deoarece prin declanșarea oricăreia dintre ele jetonul din pi va fi mutat, făcând imposibillă declanșarea celeilalte tranziții.

Aceste considerații cer înțelegerea completă a sistemelor ce urmează a fi modelate cu ajutorul rețelelor Petri pentru a realiza o modelare corectă a comportamentului sistemului. Din nefericire, multe dintre cercetările asupra rețelelor Petri s-au axat asupra proprietăților unei rețele date sau ale unei clase de rețele.

Totuși, sunt unele zone în care rețelele Petri par să fie instrumentul perfect pentru modelare: acele zone în care evenimentele apar asincron și independent. Pentru a da o explicație asupra modelării cu ajutorul rețelelor Petri, vom arăta în acest capitol cum rețelele Petri pot fi folosite pentru a modela componenta hardware a calculatorului, componenta software a calculatorului și alte sisteme.

Componenta hardware a calculatorului

Componenta hardware a calculatorului poate fi gândită pe câteva nivele, iar cu ajutorul rețelelor Petri se poate modela oricare dintre aceste nivele. La un prim nivel, computerele sunt construite din dispozitive de memorie și circuite poartă; la un al doilea nivel, unități funcționale și regiștrii sunt folosite drept componente fundamentale ale sistemului. La un al treilea nivel, întregul sistem computațional poate fi considerat ca o componentă într-o rețea cu mai multe calculatoare. Unul dintre punctele forte al rețelelor Petri este abilitatea acestora de a modela fiecare dintre aceste nivele. Vom demonstra această abilitate printr-o scurtă discuție și unele exemple.

Automate cu stări finite

La cel mai jos nivel, sistemul computațional poate fi descris ca un automat cu stări finite. Un automat cu stări finite este un 5-tuplu (Q, , , , ), unde:

Q este o mulțime finită de stări

este un alfabet de intrare finit

este un alfabet de ieșire finit

: Q x Q este funcția de tranziție, care leagă starea curentă și intrarea curentă de starea următoare

: Q x este funcție de ieșire, care leagă starea curentă și intrarea curentă de simbolul de ieșire.

Un automat cu stări finite este deseori reprezentat printr-o diagramă de stare, precum cea din figura 3.9. Într-o diagramă de stare, stările sunt reprezentate prin cercuri care sunt nodurile grafului. Un arc de la starea qi la starea qj etichetat a/b spune că, din starea qi cu intrarea a, automatul va trece în starea qj și va scoate la ieșire b. Formal vom avea: (qi,a) = qj și (qi,a) = b. Alfabetul de intrare definește intrările în automat din lumea exterioară, în timp ce alfabetul de ieșire definește ieșirile din automat către lumea exterioară.

Figura 3.9: O diagramă de stare pentru un automat cu stări finite care calculează complementul în baza 2 a unui număr binar

De exemplu, vom considera automatul cu stări finite din figura 3.9. Acest automat convertește un număr binar prezentat de la bitul cu cel mai mic ordin în complementul său negativ în baza 2. Alfabetul său de intrare și cel de ieșire constă din trei simboluri: 0, 1 și 2. Starea de start este starea q1. Simbolul de revenire (r) semnalează sfârșitul (sau începutul) unui număr și readuce automatul în starea sa inițială. Ieșirea automatului pentru simbolul de revenire este pur și simplu un ecou al simbolului de revenire.

Un automat cu stări finite similar este prezentat în figura 3.10. Cu aceleași intrări, acest automat calculează paritatea numărului. Starea de start este starea q1. Ieșirea nu face altceva decât să copieze intrarea până când simbolul de intrare este un simbol de revenire. Ieșirea pentru simbolul de revenire este 0 pentru un număr impar și 1 pentru un număr cu par.

Figura 3.10: O mașină de stare pentru calcularea parității unui număr binar dat ca intrare

Reprezentarea unui automat finit ca o rețea Petri necesită puțină gândire, deoarece nu s-a menționat nici o cale de comunicare între rețelele Petri și lumea exterioară. Rețelele Petri sunt în general studiate izolat. Modelarea interacțiunilor cu lumea exterioară se poate face în mai multe feluri. Pentru problema curentă, am modelat această interacțiune cu ajutorul unei mulțimi speciale de locații. Fiecare simbol de intrare va fi reprezentat printr-o locație. De asemenea, fiecare simbol de ieșire va fi reprezentat printr-o locație. Vom presupune că lumea exterioară va depozita un jeton în locația corespunzătoare unui simbol de intrare și apoi va aștepta apariția unui jeton într-o locație corespunzătoare unui simbol de ieșire care va fi apoi mutat. Această secvență se va repeta apoi de câte ori se dorește. Figura 3.11 ilustrează schema generală.

Figura 3.11: O abordare generală pentru a modela comunicrea dintre o rețea Petri și lumea exterioară

Se observă că ne aflăm într-o situație în care pot apărea confuzii datorate notației, de vreme ce locațiile asociate cu simbolurile de intrare și cele asociate cu simbolurile de ieșire se numesc locații de intrare și locații de ieșire ale rețelei. Acestea nu trebuie confundate totuși cu locațiile de intrare și cele de ieșire ale unei tranziții. În ciuda acestei potențiale confuzii, termenii sunt cei mai naturali pentru ambele concepte.

O abordare alternativă pentru modelarea intrărilor și ieșirilor unei rețele ar fi folosind tranzițiile. Pentru a indica următorul simbol de intrare, lumea exterioară va selecta o tranziție de intrare și o va declanșa. Rețeaua Petri va răspunde declanșând (eventual) tranziția dintr-o mulțime de tranziții de ieșire, corespunzătoare ieșirii potrivite. Lumea exterioară va declanșa apoi următoarea tranziție de intrare, și tot așa. Acest fapt este ilustrat în figura 3.12. Se poate arăta cu ușurință că aceste două abordări sunt echivalente, fapt pentru care vom folosi prima abordare, cu locații modelând simbolurile de intrare și ieșire.

Figura 3.12: O abordare alternativă pentru a reprezenta comunicarea dintre o rețea Petri și lumea exterioară, folosind tranziții în loc de locații.

Dată fiind reprezentarea prin locații a simbolurilor de intrare și ieșire, putem prezenta modelarea automatelor cu stări finite. Vom reprezenta fiecare stare a automatului printr-o locație în rețeaua Petri. Locația curentă este marcată cu un jeton; toate celelalte locații sunt goale. Acum pot fi definite tranzițiile pentru ca să schimbe starea și să definească ieșirile. Pentru fiecare pereche formată dintr-o stare și un simbol de intrare, definim o tranziție ale cărei locații de intrare sunt locațiile corespunzătoare stării și simbolului de intrare și ale cărei locații de ieșire sunt locațiile corespunzătoare stării următoare și ieșirii.

Pentru un automat cu stări finite (Q, , , , ), definim o rețea Petri (P, T, I, O) astfel:

P = Q

T = tq,, q Q și

I(tq,) = q,

O(tq,) = (q,), (q,)

Această rețea Petri este un model pentru automatul cu stări finite. Figura 3.13 reprezintă rețeaua Petri corespunzătoare automatului cu stări finite din figura 3.9. Figura 3.14 reprezintă rețeaua Petri corespunzătoare automatului cu stări finite din figura 3.10.

Comparând rețelele Petri din figurile 3.13 și 3.14 cu automatele echivalente din figurile 3.9, respectiv 3.10, se pot ridica câteva întrebări. Prima dintre ele este: „De ce este de preferat modelarea cu ajutorul rețelelor Petri descrierii cu ajutorul automatelor cu stări finite?”. Descrierea cu ajutorul automatelor cu stări finite este mai ușor de înțeles decât cea cu ajutorul rețelelor Petri, cu cele 6 tranziții, 24 de arce și 7 sau 8 locații. Admitem acest lucru.

Totuși, am arătat că cu ajutorul rețelelor Petri poate fi reprezentat orice sistem care poate fi reprezentat ca un automat finit, ceea ce demonstrează puterea modelelor realizate cu ajutorul rețelelor Petri.

În plus, modelul realizat cu ajutorul rețelelor Petri are anumite avantaje evidente. De exemplu, observăm că alfabetul de ieșire al automatului din figura 3.13 este identic cu alfabetul de intrare al automatului din figura 3.14. Rulând ieșirea din figura 3.13 ca intrare în figura 3.14, putem construi o rețea compusă care calculează complementul negativ în baza 2 și paritatea sa. Reprezentarea acestei combinații sub formă de automat cu stări finite este complexă, necesită o stare compusă cu componente ale ambelor automate, adică un automat cross-product. Pe de altă parte, pentru un model realizat cu ajutorul rețelelor Petri, compunerea înseamnă pur și simplu suprapunerea locațiilor de ieșire ale primei rețele cu locațiile de intrare ale celei de-a doua rețele. În figura 3.15 este reprezentat automatul cross-product, în timp ce în figura 3.16 este reprezentat automatul compus din rețele Petri.

Figura 3.15: Automatul compus reprezentând compunerea serială a automatelor din figurile 3.9 și 3.10.

Figura 3.16: Rețeaua Petri compusă reprezentând compunerea serială a rețelelor Petri din figurile 3.13 și 3.14

Figura 3.17: O compunere paralelă a rețelelor Petri din figurile 3.13 și 3.14. Este necesară o subrețea care să ofere intrări pentru ambele rețele Petri componente

Un alt avantaj al reprezentării cu ajutorul rețelelor Petri apare în cazul altor compuneri. De exemplu, o compunere paralelă permite execuția simultană a automatelor componente. Pentru un automat cu stări finite, acest fapt implică încă o dată automatele cross-product, în timp ce pentru o rețea Petri, presupune doar duplicarea jetoanelor de intrare care reprezintă simbolurile de intrare și potrivirea acestora în fiecare rețea Petri componentă. În cele din urmă, pentru ieșire selectăm locația de ieșire potrivită. De exemplu, dacă dorim să combinăm paralel cele două automate reprezentate cu ajutorul rețelelor Petri în figurile 3.13 și 3.14, vom obține o reprezentare ca cea din figura 3.17, care calculează complementul negativ al unui număr negativ în baza 2 și paritatea sa. Paritatea este ieșire când simbolul de revenire este intrare.

Calculatoare asamblate

Capacitatea de a modela paralelisme și de a combina cu ușurință subsisteme modelate cu ajutorul rețelelor Petri, face modelarea cu ajutorul rețelelor Petri foarte utilă pentru modelarea de componente hardware mai complexe. Sistemele computaționale sunt construite din multe componente, și mulți proiectanți încearcă să crească viteza prin execuția în paralel a anumitor funcții. De aceea rețelele Petri sunt o reprezentare foarte potrivită pentru un asemenea sistem.

Un exemplu al acestei abordări în construirea unui computer de mare performanță este folosirea benzilor de producție [Chen 1971]. Această tehnică este similară cu operarea unei linii de asamblare și este deosebit de utilă pentru procesarea vectorilor și a tablourilor. O bandă de asamblare este compusă dintr-un număr de nivele, care pot fi în execuție simultan. Când nivelul k se termină, transmite rezultatele sale nivelului k + 1 și trece la nivelul k – 1 pentru o nouă lucrare. Dacă fiecare nivel consumă t unități de timp și sunt n nivele, atunci terminarea operației pentru un operand durează nt unități de timp. Totuși, dacă banda de asamblare este alimentată continuu cu noi operanzi, poate întoarce rezultate cu rata de unu la t unități de timp.

Ca un exemplu, vom considera adunarea a două numere în virgulă mobilă. Principalii pași sunt următorii:

Extragerea exponenților celor două numere.

Compararea exponenților și interschimbarea, în cazul în care este necesar, pentru a ordona corect cel mai mare și cel mai mic exponent.

Deplasarea celei mai mici fracții pentru a egaliza exponenții.

Adunarea fracțiilor.

Postnormalizarea.

Considerarea depășirii inferioare sau superioare a exponentului și obținerea exponentului și fracției rezultatului.

Fiecare dintre acești pași poate fi efectuat de o unitate computațională separată, prin trecerea unui operand particular de la o unitate la alta pentru terminarea operației de adunare. Acest fapt va permite efectuarea simultană de până la 6 adunări.

Coordonarea diferitelor unități se poate face în diverse moduri. Tipic, controlul unei benzi de asamblare este sincron, iar timpul alocat pentru fiecare nivel al benzii de asamblare este o constantă de timp t fixată. La fiecare t unități de timp rezultatul fiecărei unități este deplasat în jos pe banda de asamblare pentru a deveni intrare pentru următoarea unitate. Abordarea sincronă poate să țină inutil în loc procesarea, fiind necesară totuși deoarece timpul trebuincios poate varia de la unitate la unitate, ba chiar și în interiorul aceleiași unități, funcție de intrări. De exemplu, pasul de postnormalizare în adunarea a două numere în virgulă mobilă poate consuma diferite cantități de timp în funcție de cât de lungă trebuie să fie deplasarea de normalizare și dacă se va face la dreapta sau la stânga. În acest context, de vreme ce timpul t trebuie selectat ca fiind timpul maxim necesar pentru cea mai înceată unitate a benzii de asamblare, ar putea apărea situația în care toate unitățile stau inactive cea mai mare parte a timpului așteptând trecerea a ceea ce a mai rămas din cele t unități de timp.

O bandă de asamblare asincronă poate mări viteza, în medie, anunțând când fiecare nivel al benzii de asamblare este complet și gata să paseze operanzii săi și să primească alții noi. Rezultatul nivelului k al benzii de asamblare poate fi trimis la nivelul k + 1 imediat ce nivelul k s-a terminat și nivelul k + 1 este liber. Vom considera un nivel arbitrar în banda de asamblare. Evident, trebuie să existe un loc unde să se depoziteze intrările și ieșirile în vreme ce acestea sunt folosite sau produse. Tipic, se folosesc regiștrii: unitatea folosește valorile din registrul său de intrare (buffer) pentru a produce valori în registrul său de ieșire (buffer). Unitatea trebuie apoi să aștepte până când

registrul său de ieșire a fost golit prin copierea în registrul de intrare al următorului nivel, și

o nouă intrare este disponibilă în registrul său de intrare.

Astfel, controlul pentru nivelul k al benzii de asamblare trebuie să știe când următoarele propoziții sunt adevărate:

Registru de intrare plin

Registru de intrare gol

Registru de ieșire plin

Registru de ieșire gol

Unitate ocupată

Unitate neocupată

Are loc copierea

Figurile 3.18 și 3.19 arată cum poate fi modelată o bandă de asamblare asincronă de acest tip. Figura 3.18 reprezintă o diagramă bloc a unei benzi de asamblare care este apoi modelată ca o rețea Petri în figura 3.19.

Se observă că în acest model am modelat execuția actuală a unităților benzii de asamblare ca evenimente care nu sunt primare. Acest fapt ne permite să ignorăm, la acest nivel, detaliile specifice despre ceea ce face fiecare unitate și să ne concentrăm asupra modului în care interacționează. Fiecare operație poate fi de asemenea modelată ca o rețea Petri. Rețelele Petri pentru fiecare unitate pot apoi să fie înlocuite în rețeaua Petri din figura 3.19, pentru a obține o rețea Petri mai detaliată. Această abilitate de a modela un sistem la mai multe nivele diferite de abstractizare, într-o manieră ierarhică, poate fi foarte utilă.

Unități funcționale multiple

Structura de control a benzii de asamblare din secțiunea precedentă este o abordare folosită pentru a construi sisteme computaționale foarte mari și rapide. Altă abordare, folosită în CDC 6600 [Thornton 1970] și IBM 360/91 [Anderson at. Al. 1967], de exemplu, este de a oferi multiple unități funcționale. Pe 6600 sunt disponibile 10 unități funcționale: o unitate de salt (pentru salturi condiționale), o unitate booleană (pentru operații booleene), o unitate de deplasare, o unitate de adunare în virgulă mobilă, o unitate de adunare în punct fix, 2 unități de înmulțire, o unitate de împărțire și două unități de incrementare (pentru indexare). În plus, sunt disponibili regiștrii multipli pentru a păstra intrările și ieșirile unităților funcționale. Unitatea de control a calculatorului încearcă să realizeze funcționarea simultană a mai multor unități independente.

De exemplu, vom considera următoarea secvență de instrucțiuni pe un sistem computațional CDC 6600.

Înmulțirea lui x1 cu x1 dă x0

Înmulțirea lui x3 cu x1 dă x3

Adunarea lui x2 cu x4 dă x4

Adunarea lui x0 cu x3 dă x3

Împărțirea lui x0 la x4 dă x6

Când aceste instrucțiuni sunt executate, unitatea de control trimite prima instrucțiune către o unitate de înmulțire. Apoi, deoarece sunt două unități de înmulțire, a doua instrucțiune poate de asemenea să fie prelucrată. Observăm că ambele unități pot să citească conținutul lui x1 fără să apară vreo problemă. Instrucțiunea 3 poate fi efectuată de unitatea de adunare. Acum, pentru a prelucra instrucțiunea 4, trebuie să așteptăm până când instrucțiunile 1, 2 și 3 se termine, deoarece instrucțiunea 4 folosește unitatea de adunare (care este ocupată de instrucțiunea 3) pentru a prelucra x0 (care este calculat de instrucțiunea 1) și x3 (care este calculat de instrucțiunea 2). Instrucțiunea 5 trebuie să aștepte terminarea instrucțiunii 1 (care calculează x0) și terminarea instrucțiunii 3 (care calculează x4).

Introducerea acestui tip de paralelism, prin care se execută simultan câteva instrucțiuni ale unui program, trebuie controlată astfel încât rezultatele executării programului cu sau fără paralelism să fie identice. Unele instrucțiuni în program vor cere ca rezultatele instrucțiunilor anterioare să fi fost corect calculate înainte de procesarea următoarelor instrucțiuni. Un sistem care introduce paralelismul într-un program secvențial menținând astfel rezultatele corecte se numește determinat. Condițiile pentru menținerea determinării au fost considerate de Bernstein [1966]. Acestea sunt următoarele: Pentru două operații a și b astfel încât a o precede pe b în precedența liniară a programului, b poate să înceapă înaintea lui a dacă și numai dacă b nu are nevoie de rezultatele lui a ca intrări și rezultatele lui b nu modifică nici intrările, nici rezultatele lui a.

Un tabel de rezervare este o metodă de aplicare a acestor constrângeri la construcția unei unități de control pentru procesarea instrucțiunilor de separare a unităților funcționale. O instrucțiune pentru unitatea funcțională u ce folosește regiștrii i, j și k poate fi procesată numai dacă toate cele patru componente ale sale nu sunt rezervate; când instrucțiunea este prelucrată, toate cele patru devin rezervate. Dacă instrucțiunea nu poate fi prelucrată la acest moment deoarece fie unitatea funcțională fie unul dintre regiștrii este în uz, unitatea de control așteaptă până când instrucțiunea poate fi prelucrată înainte de a continua cu următoarea instrucțiune.

Acest tip de schemă poate fi modelat cu ajutorul unei rețele Petri. Fiecărei unități funcționale și fiecărui registru îi asociem o locație. Dacă fie unitatea, fie registrul sunt libere, un jeton se va afla în locație; dacă nu, în locație nu se va afla nici un jeton. Unități funcționale multiple identice pot fi indicate prin jetoane multiple în locații. Figura 3.10 arată o porțiune a unei rețele Petri care poate fi folosită pentru a modela execuția unei instrucțiuni folosind unitatea u și regiștrii i, j și k. Modelarea întregii unități de control va genera, desigur, o rețea Petri mult mai mare.

Schema descrisă mai sus este o metodă foarte simplă pentru introducerea paralelismului și nu ia în considerare, de exemplu, faptul că unități funcționale multiple pot folosi simultan același registru ca intrare. De aceea, această schemă nu poate produce programări cu paralelism maxim [Keller 1975b]. Totuși, există alte scheme care pot face acest lucru. Aceste scheme (mai complicate) pot fi modelate de asemenea de rețele Petri (mai complicate), care pot fi foarte mari. Considerăm că CDC 6600 are 24 de regiștrii diferiți și 64 de instrucțiuni diferite. Dacă fiecare instrucțiune și triplet de regiștrii are nevoie de o locație corespunzătoare „unității u care operează cu regiștrii i, j și k”, atunci vor fi necesare o jumătate de milion de locații și tranziții. Problema principală aici este dificultatea modelării faptului că conținutul unui registru intern poate specifica care unități și regiștrii vor fi folosiți (adică indexare). (Orice program dat nu va folosi toate combinațiile posibile de regiștrii și unități, totuși acest fapt a permis lui Shapiro și Saint [1970] să modeleze un sistem computațional 6600 cu ajutorul unei rețele Petri. Acest model de rețea Petri a fost folosit pentru a optimiza generarea codului pentru un compilator FORTRAN, după cum se va vedea în secțiunea 3.5.)

Componenta software

La fel ca și componenta hardware, și componenta software poate fi modelată cu ajutorul rețelelor Petri. Aceasta este probabil cea mai obișnuită utilizare a rețelelor Petri și are cel mai mare potențial în obținerea de rezultate folositoare. Multe sisteme au fost dezvoltate peste ani pentru descrierea și modelarea componentei hardware, dar de abia în ultimii ani s-au făcut eforturi pentru realizarea unui model formal al componentei software. Multe dintre aceste eforturi s-au concentrat asupra analizei, specificării și descrierii programelor secvențiale; sistemele cu procese concurente constituie una dintre principalele direcții de cercetare. În acest capitol vom arăta cum rețelele Petri pot modela cu succes multe modele cu procese concurente.

Scheme logice de program

Cazul degenerat al unui sistem cu procese concurente este un sistem cu exact un proces. Examinăm mai întâi cum un singur proces poate fi reprezentat printr-o rețea Petri și apoi combinând rețelele Petri corespunzătoare proceselor vom obține rețeaua Petri corespunzătoare sistemului cu procese concurente.

Un singur proces este descris printr-un program. Acest program poate fi scris în multe limbaje, dar pentru simplitate, vom considera un limbaj corespunzător scopului general, precum ALGOL, FORTRAN, DL/1, COBOL, Pascal, Basic, sau chiar limbaje de asamblare. Programul reprezintă două aspecte separate ale procesului; calculul și controlul. Calculul se ocupă cu operațiile aritmetice și logice actuale, intrările și ieșirile și manipularea generală a locațiilor de memorie și a valorilor acestora. Controlul, pe de altă parte, nu se ocupă cu valorile sau calculele de efectuat, ci numai cu ordinea efectuării acestora.

Rețelele Petri pot să reprezinte cel mai bine structura de control a programelor. Rețelele Petri intenționează să modeleze secvența de instrucțiuni și fluxul de informații și calculele și nu valorile informației. Un model al unui sistem, prin natura sa, este o abstractizare a sistemului de modelat. Detaliile specifice se ignoră pe cât posibil. Dacă s-ar modela toate detaliile, atunci modelul ar fi o dublură a sistemului de modelat, nu o abstractizare.

O reprezentare standard a structurii de control a unui program este cu ajutorul schemelor logice. O schemă logică reprezintă fluxul de control într-un program. De exemplu, programul din figura 3.20 este reprezentat prin schema logică din figura 3.22. Se observă că schema logică din figura 3.22 nu specifică calculele ce urmează a fi făcute, ci numai structura programului, fiind o schemă logică neinterpretată. Figura 3.23 ne arată cum poate fi aplicată o interpretare acțiunilor schemei logice de program pentru a reprezenta programul din figura 3.20.

Astfel, arătând cum o schemă logică de program poate fi reprezentată cu ajutorul unei rețele Petri, am arătat cum se reprezintă un program neinterpretat cu ajutorul unei rețele Petri.

O schemă logică de program poate părea foarte asemănătoare cu o rețea Petri, deoarece este compusă din noduri (de două tipuri: de decizie, reprezentate prin romburi, și de calcul, reprezentate prin dreptunghiuri) și arce ce le unesc. O cale simplă de a executa o schemă logică de program este de a introduce un jeton care reprezintă instrucțiunea curentă. La executarea instrucțiunii, jetonul se mută în schemă. Similitudinea între această reprezentare grafică a unui program și o rețea Petri pare să indice că putem înlocui nodurile schemei prin locații și arcele prin tranziții pentru a crea o rețea Petri echivalentă. Aceasta este metoda de convertire a unui automat cu stări finite într-o rețea Petri (vezi secțiunea 3.3.1).

Totuși, considerăm că în modelul realizat cu ajutorul rețelelor Petri tranzițiile modelează acțiuni, în timp ce în modelul schemei logice a programului, nodurile modelează acțiuni. De asemenea, dacă jetonul de instrucțiune curentă dintr-o schemă logică de program vrea să meargă „la rest”, atunci se va opri între noduri, pe un arc, nu într-un dreptunghi.

De aceea, translatarea corectă dintr-o schemă logică de program într-o rețea Petri înlocuiește nodurile schemei cu tranziții în rețeaua Petri, și arcele schemei cu locații în rețeaua Petri. Fiecare arc al schemei este reprezentat prin exact o locație în rețeaua Petri corespunzătoare. Nodurile schemei sunt reprezentate în diferite moduri, în funcție de tipul lor (de decizie sau de calcul). Figura 3.23 ilustrează cele două metode de translatare. Figura 3.24 aplică această translatare schemei logice de program din figura 3.22 pentru a produce o rețea Petri echivalentă.

Figura 3.23: Translatarea nodurilor de decizie și de calcul dintr-o schemă logică în tranziții într-o rețea Petri

Figura 3.24: Reprezentarea sub formă de rețea Petri a figurii 3.21 derivată din schema logică din figura 3.22

Referitor la rețeaua Petri din figura 3.24 trebuie de asemenea de studiat semnificația componentelor. Care este semnificația locațiilor? Cel mai simplu răspuns este de a considera programul numărător al fluxului jetoanelor. În acest sens, un jeton într-o locație semnifică faptul că programul numărător este poziționat gata să execute următoarea instrucțiune.

Fiecare locație are o singură tranziție de ieșire, cu excepția locațiilor care preced deciziile; aceste locații au două tranziții de ieșire corespunzătoare valorilor fals sau adevărat pe care le poate lua predicatul de decizie.

Tranzițiile sunt evident asociate cu acțiunile programului: calcule și decizii. Dacă dorim să interpretăm rețeaua Petri, trebuie să realizăm o interpretare pentru fiecare tranziție. Se observă de asemenea că tranzițiile pentru acțiunile de calcul au o unică intrare și o unică ieșire, și că nu poate exista nici un conflict pentru o tranziție reprezentând un calcul, de vreme ce locația sa de intrare nu mai este locație de intrare pentru nici o altă tranziție. Acțiunile de decizie pot introduce conflicte în rețea, dar într-un fel foarte restrâns: se poate face orice alegere. Alegerea poate fi făcută fie nedeterminist (adică aleatoriu), fie poate fi controlată de aceeași forță externă (adică de un agent) care calculează adevărul sau falsitatea deciziei și forțează declanșarea tranziției corecte. Distincția între aceste două interpretări ale rezolvării conflictelor este o chestiune de filozofie.

Paralelism

Paralelismul (concurența) poate fi introdus acum în câteva moduri. Vom considera cazul a două procese concurente. Fiecare proces poate fi reprezentat printr-o rețea Petri. De aceea, rețeaua Petri compusă, care este pur și simplu uniunea rețelelor Petri pentru fiecare din cele două procese, poate reprezenta execuția concurentă a celor două procese. Marcajul inițial al rețelei Petri compuse are două jetoane, unul în fiecare locație, reprezentând programul de numărare inițial al procesului. Acest fapt introduce un paralelism care nu poate fi reprezentat printr-o schemă logică și pentru care reprezentarea ca rețea Petri reprezintă o soluție foarte utilă.

O altă abordare este să considerăm cum paralelismul va fi introdus normal într-un proces într-un sistem computațional. S-au făcut unele propuneri. Una din cele mai simple presupune operațiile de ramificare (derivare)(FORK) și uniune (JOIN) propuse inițial de Dennis și Van Horn [1966]. O operație de ramificare executată la locația i determină continuarea procesului curent la locația i + 1 și crearea unui nou proces cu începerea execuției la locația j. O operație de uniune va recombina două procese într-unul (sau, echivalent, va distruge unul din două și îl va lăsa pe celălalt să se efectueze). Aceste operații pot fi modelate de o rețea Petri, după cum se arată în figura 3.25.

Figura 3.25: Modelarea operațiilor FORK și JOIN cu ajutorul rețelelor Petri

(a) FORK (executată la locația i, creează două noi procese la locațiile j și k)

(b) JOIN (unifică cele două procese care se termină la locațiile i și j într-un proces care continuă la locația k)

O altă sugestie pentru introducerea paralelismului este introducerea structurii de control parbegin .. parend [Dijkstra 1968]. Această structură de control a fost sugertă de Dijkstra și are forma generală:

parbegin

S1;

S2;

Sn;

parend

unde Si sunt descrieri de instrucțiuni în limbaj de programare. Semnificația structurii parbegin /parend este aceea că instrucțiunile S1, S2,…, Sn se execută în paralel. Această construcție poate fi reprezentată ca o rețea Petri, după cum se arată în figura 3.26.

Figura 3.26: Modelarea structurii parbegin S1, S2,…, Sn parend sub formă de rețea Petri. Fiecare dintre pătratele din rețea reprezintă una din instrucțiunile S1, S2,…, Sn. Figura ilustrează de asemenea natura ierarhică a modelării cu ajutorul rețelelor Petri

Coordonare

Paralelismul este util de introdus în soluționarea unei probleme numai dacă procesele concurente pot coopera în soluționarea problemei. O astfel de cooperare presupune informații și resurse comune pentru procese. Acest acces comun trebuie controlat pentru a asigura funcționarea corectă a sistemului. O varietate de probleme de coordonare s-a propus în literatură pentru a ilustra tipurile de probleme care pot apărea între procesele ce cooperează.

Apar astfel următoarele probleme: problema excluziunii mutuale [Dijkstra 1965], problema producător /consumator [Dijkstra 1968], problema filozofilor care iau masa împreună [Dijkstra 1968], și problema cititori /scriitori [Courtais at. Al. 1971].

Aceste probleme sunt probleme clasice de coordonare; orice nouă sugestie pentru un mecanism de coordonare trebuie să poată să rezolve trei probleme. Deși rețelele Petri sunt o schemă de modelare și nu un mecanism de coordonare, rețelele Petri trebuie cu siguranță să poată modela mecanismele de coordonare care rezolvă aceste probleme. De aceea, vom prezenta aici soluții la aceste probleme în modelarea cu ajutorul rețelelor Petri. Această prezentare se bazează parțial de lucrarea lui Cooprider [1976].

Problema excluziunii mutuale

Să presupunem că anumite procese au acces comun la o variabilă, înregistrare, fișier, sau altă dată internă. Această dată cu acces comun poate fi folosită în câteva moduri de către procese, dar această utilizare trebuie clasificată din punct de vedere al modului în care e folosită: fie citire a valorii datei la care se are acces comun, fie scriere a unei noi valori. Aceste două operații sunt de obicei numai operații primare, ccea ce înseamnă că pentru a modifica valoarea datei cu acces comun, un proces trebuie mai întâi să citească vechea valoare, apoi să calculeze noua valoare și în cele din urmă să scrie în loc noua valoare. Pot părea probleme dacă două procese încearcă să execute în același timp această secvență de instrucțiuni. Poate apărea următoarea secvență:

Primul proces citește valoarea x din obiectul la care se are acces comun

Al doilea proces citește valoarea x din obiectul la care se are acces comun

Primul proces calculează o valoare nouă x’=f(x)

Al doilea proces calculează o valoare nouă x’’=g(x)

Primul proces scrie x’ în obiectul la care se are acces comun

Al doilea proces scrie x’’ în obiectul la care se are acces comun, distrugând valoarea x’.

Prin urmare, rezultatul obținut prin calculul efectuat de primul proces s-a pierdut, deoarece acum valoarea obiectului la care se are acces comun este g(x), în loc de g(f(x)), sau f(g(x)). [Considerăm cazul în care g(x) este „o retragere de 1000 $ din contul x”, iar f(x) este „o depunere de 1000 $ în contul x” și procesele 1 și 2 sunt funcționari bancari.]

Pentru a preveni acest tip de probleme, este necesară folosirea unui mecanism pentru excluziunea mutuală. Excluziunea mutuală este o tehnică de a defini cod de intrare și ieșire astfel încât un singur proces să poată avea acces la o resursă comună la un moment dat. Codul care accesează obiectul cu acces comun și are nevoie de protecție pentru a nu intra în interferență cu alte procese se numește secțiune critică. Ideea este aceea că atunci când un proces urmează să execute porțiunea sa critică, așteaptă mai întâi ca nici un alt proces să nu mai execute această porțiune critică, apoi „blochează” accesul la aceasta, prevenind accesul altui proces în porțiunea sa critică. În cele din urmă intră în porțiunea sa critică, o execută și atunci când o părăsește o „deblochează” pentru a permite altor procese să o acceseze.

Această problemă poate fi rezolvată cu ajutorul unei rețele Petri ca cea din figura 3.27. Locația m reprezintă permisiunea de a intra în secțiunea critică. Pentru ca un proces să intre în secțiunea critică, trebuie să aibă un jeton în p1 sau p2, după caz, care să anunțe că se dorește intrarea în secțiunea critică, și de asemenea trebuie să existe un jeton în m care să semnalizeze permisiunea de a intra. Dacă ambele procese doresc să intre simultan, atunci tranzițiile t1 și t2 sunt în conflict, și numai una dintre ele se poate declanșa. Declanșarea lui t1 va dezactiva tranziția t2 cerând procesului 2 să aștepte până când procesul 1 va ieși din porțiunea sa critică și va pune înapoi un jeton în locația m.

Figura 3.27: Excluziunea mutuală Accesul la secțiunea critică a celor două procese este controlat astfel încât cele două procese nu-și pot executa simultan secțiunea critică

Problema producător /consumator

Problema producător /consumator implică de asemenea un obiect la care se are acces comun, dar în acest caz acest obiect este specificat a fi un buffer. Procesul producător creează obiecte care sunt puse în buffer; procesul consumator așteaptă până când un obiect a fost pus în buffer, îl ia de acolo și îl consumă. Acest fapt poate fi modelat după cum se vede în figura 3.28. Locația B reprezintă bufferul; fiecare jeton reprezintă un articol care a fost produs dar nu a fost încă consumat.

Figura 3.28: Problema producător /consumator modelată ca o rețea Petri

O variantă la această problemă este problema multipli producători /multipli consumatori. În această variantă, mai mulți producători produc articole care sunt plasate într-un buffer comun pentru mai mulți consumatori. Figura 3.29 reprezintă rețeaua Petri soluție a acestei probleme care coincide cu cea din figura 3.28, cu excepția faptului că pentru a reprezenta s producători și t consumatori am pornit sistemul cu s jetoane în locația inițială a procesului producător și t jetoane în locația inițială a procesului consumator. Astfel am reprezentat s producători și t consumatori ce execută fragmente de cod reentrant, comun. O alternativă ar fi duplicarea codului pentru procesele producător și consumator, dar acest fapt provoacă același comportament cu cel al unei rețele mult mai mari.

Figura 3.29: Problema multipli producători /multipli consumatori. Sunt s producători și t consumatori, cu s și t fixate

O altă variantă este problema producător /consumator pentru un buffer finit. În această versiune a problemei producător /consumator, se cunoaște că buffer-ul dintre producător și consumator este finit, adică are numai n locații pentru articole. De aceea producătorul nu poate întotdeauna să producă atât de rapid pe cât dorește, dar trebuie să aștepte dacă consumatorul este încet și buffer-ul plin. Figura 3.30 este o soluție la această problemă. Bufferul finit este reprezentat de două locații: B reprezintă numărul de articole care au fost produse dar nu au fost încă consumate (numărul de locații ocupate), iar B’ reprezintă numărul de locații libere în buffer. Inițial B’ are n jetoane și B nici unul. Dacă buffer-ul se umple, atunci B’ nu va avea nici un jeton, iar B va avea n jetoane. În acest punct, dacă producătorul încearcă să pună un alt articol în buffer, va fi oprit deoarece nu există nici un jeton în B’ pentru a valida această tranziție.

Figura 3.30: Problema producător /consumator cu buffer finit. Bufferul, reprezentat prin locațiile B și B’ este limitat la cel mult n articole

Problema filozofilor care iau masa împreună

Problema filozofilor care iau masa împreună a fost sugerată de Dijkstra [1968] și privește cinci filozofi care gândesc și mănâncă alternativ. Filozofii sunt așezați la o masă mare rotundă pe care se află o mare cantitate de preparate chinezești. Între fiecare filozof se află câte un bețișor. Totuși, pentru a mânca mâncare chinezească, sunt necesare două bețișoare; de aceea fiecare filozof trebuie să ridice ambele bețișoare, adică atât pe cel situat în stânga sa, cât și pe cel situat în dreapta sa. Problema, desigur, este că dacă toți filozofii ridică bețișorul din stânga lor și așteaptă apoi pentru cel din dreapta, vor avea de așteptat mult și bine și se vor înfometa (o situație de interblocare).

Figura 3.31 ilustrează rețeaua Petri soluție a acestei probleme. Locațiile C1,..,C5 reprezintă bețișoarele, și de vreme ce fiecare este inițial liber, se află un jeton în fiecare în marcajul inițial. Fiecare filozof este reprezentat prin două locații, Mi și Ei reprezentând stările de meditare, respectiv cea în care mănâncă. Pentru ca un filozof să treacă din starea de meditație în cea în care mănâncă, ambele bețișoare (cel din stânga și cel din dreapta) trebuie să fie disponibile. Acest fapt este simplu modelat printr-o rețea Petri.

Figura 3.31: Problema filozofilor care iau masa împreună. Fiecare filozof este modelat prin două locații, meditare (Mi) și mâncare (Ei).

Problema cititori /scriitori

Există câteva variante ale problemei cititori /scriitori [Courtais at. al. 1971], dar structura de bază este aceeași. Există două tipuri de procese: procese cititor și procese scriitor. Toate procesele au în comun o variabilă, un fișier sau un obiect. Procesele cititor nu modifică niciodată obiectul, în timp ce procesele scriitor îl modifică. De aceea, procesele scriitor trebuie să excludă mutual toate celelalte procese cititor și scriitor, dar o aceeași dată poate fi simultan accesată de mai multe procese cititor. Problema este aceea de a defini o structură de control care nu duce la interblocare sau care nu produce violări ale criteriului de excludere mutuală.

Figura 3.32 ilustrează o soluție când numărul de procese cititor este maxim n. Într-un sistem în care numărul de procese cititor nu este limitat, numai n cititori pot citi la un moment dat.

Apare totuși o problemă în cazul în care numărul de cititori nu este limitat și dorim să permitem unui număr nelimitat de cititori să citească simultan. În acest caz, poate fi demonstrat că va fi necesar pentru cititori să țină evidența numărului de cititori ce citesc. Fiecare cititor adaugă unu la această numărătoare când începe citirea, și scade unu la terminarea citirii. Acest fapt poate fi ușor modelat cu ajutorul unei locații ce conține un număr de jetoane egal cu numărul de cititori. Totuși, acum, pentru a permite unui scriitor să înceapă scrierea, este necesar ca această numărătoare să indice zero, adică locația corespunzătoare să fie goală, iar în rețelele Petri nu există nici un mecanism care să permită ca o locație nemărginită să fie testată pentru a nu fi zero. De aceea, problema cititori /scriitori cu număr nelimitat de cititori nu poate fi rezolvată cu ajutorul rețelelor Petri. Aceasta este prima oară când indicăm că rețelele Petri nu pot modela toate sistemele și este un subiect care merită să fie studiat mai amănunțit (capitolul 7).

Figura 3.32: Problema cititori /scriitori când numărul de cititori este maxim n. Inițial sunt s cititori și t scriitori

Sisteme P și V

Majoritatea problemelor de sincronizare nu vor fi rezolvate direct cu ajutorul de rețelelor Petri, ci mai întâi în termenii unui mecanism de sincronizare stabilit. În particular, unul dintre cele mai populare mecanisme de sincronizare îl constituie operațiile P și V pe semafoare, definite inițial de Dijkstra [1968]. Un semafor este un tip de dată care poate să ia numai valori întregi nenegative. Operația V crește valoarea cu 1, în timp ce operația P o micșorează cu 1. Operația P poate apărea numai atunci când valoarea semaforului va rămâne nenegativă după executare; dacă valoarea semaforului este zero, operația P va trebui să aștepte până ce un alt proces execută o operație V. Amândouă operațiile P și V sunt definite pentru a fi primare; nici o altă operație nu poate modifica simultan valoarea semaforului.

Aceste operații pot fi cu ușurință modelate cu ajutorul rețelelor Petri, așa cum se arată în figura 3.33. Fiecare semafor este modelat cu ajutorul unei locații; numărul de jetoane din această locație indică valoarea semaforului. O operație P folosește locația semaforului ca intrare; o operație V folosește locația semaforului ca ieșire. Avantajul acestei abilități de a modela operațiile P și V este acela că multe sisteme sunt scrise sau proiectate folosind operațiile P și V. De exemplu, sistemul de operare Venus [Liskov 1972] folosește operațiile P și V ca principal mecanism de comunicare între procese. De aceea, aceste sisteme pot fi modelate cu ajutorul rețelelor Petri.

Figura 3.33: Modelarea operațiilor P și V pe un semafor S

Alte sisteme

Sistemele care au fost descrise până acum sunt tipice pentru modelarea cu ajutorul rețelelor Petri. Dar, acest “tipic” este, în mare parte, rezultatul faptului că rețelele Petri au fost definite și dezvoltate în special pentru acest scop. Rețelele Petri pot fi, de asemenea, aplicate direct în modelarea unui mare număr de alte sisteme, unele complet diferite de sistemele computaționale. În această secțiune, vom trece în revistă sumar unele dintre aceste sisteme pentru care rețelele Petri au fost aplicate sau ar putea să fie aplicate.

Graficele PERT au fost îndelung folosite în planificarea și programarea proiectelor de amploare. Un grafic PERT este o reprezentare grafică a relațiilor dintre diferitele activități care alcătuiesc un proiect de amploare. Un proiect constă dintr-un anumit număr de activități; unele activități trebuie să se termine înainte ca alte activități să poată să înceapă. În plus, la fiecare activitate este asociat un timp indicând durata activității. (Uneori, fiecărei activități i se asociază trei timpi – timpul minim, timpul mediu, timpul maxim). Activitățile sunt reprezentate grafic sub formă de noduri; arcele sunt folosite pentru a conecta nodurile-activități în scopul de a indica precedențele.

Graficele Petri au același tip de constrângeri de programare ca și rețelele Petri. Putem cu ușurință să convertim un grafic PERT la o rețea Petri. Fiecare activitate într-un grafic PERT este reprezentată printr-o locație, în timp ce constrângerile de precedență sunt reprezentate de tranziții. Graficul PERT din figura 3.34 poate fi convertit la rețeaua Petri echivalentă din figura 3.35.

Figura 3.34: Un grafic PERT al construcției unei case (Din “Introducere în metoda drumurilor critice în programarea industrială” , de F. Levy, G. Thompson și G. Wiest, 1963)

Figura 3.35: O rețea Petri reprezentând graficul PERT din figura 3.34. Se observă că au fost adăugate câteva noduri suplimentare, necesare pentru o reflectare corectă a constrângerilor de precedență și pentru o referire corectă a situațiilor în care trebuie să apară așteptarea

Rețelele Petri sunt un instrument perfect pentru reprezentarea concurenței și a constrângerilor de precedență ale graficelor PERT, dar graficele PERT oferă, de asemenea, informații despre timp care sunt necesare pentru determinarea timpului minim necesar pentru terminarea proiectului, a celui mai târziu timp pentru începerea unei activități astfel încât proiectul să nu fie întârziat și așa mai departe. O rețea Petri nu oferă nici o informație de acest tip. Adăugarea de informație despre timp poate oferi o nouă facilitate importantă rețelelor Petri, dar nu este posibilă dacă considerăm rețelele Petri în forma lor actuală. Se fac cercetări pentru a extinde în această direcție rețelele Petri.

Banda de asamblare din capitolul 3.3.2 este un caz special de sistem de producție [Hack 1972]. O linie de producție este un alt exemplu de sistem de producție. Sistemele de producție și liniile de asamblare pot fi modelate cu ajutorul rețelelor Petri.

Una dintre primele aplicații pentru rețelele Petri a fort o unealtă pentru generarea de cod optim pentru un compilator CDC 6600 FORTRAN. Abordarea sugerată de Shapiro și Saint [1970] a fost aceea de a modela programul FORTRAN ca o rețea Petri, într-o manieră similară cu modelarea schemelor logice în capitolul 3.4.1. Apoi se trece la examinarea instrucțiunilor individuale ale programului pentru a determina numărul minim de constrângeri de precedență între instrucțiuni, permițând eliminarea din rețelele Petri a unor secvențe de constrângeri artificiale ale programului. Aceste constrângeri artificiale sunt introduse deoarece programatorul în FORTRAN trebuie să exprime instrucțiunile din program într-o ordine totală, deși este necesară doar una parțială. De exemplu, vom considera următoarele trei instrucțiuni:

10 x = x + 1

20 y = y + 1

30 z = x + y

Instrucțiunile 10 și 20 sunt scrise “instrucțiunea 10 înaintea instrucțiunii 20”, dar această constrângere nu este necesară. Instrucțiunile 10 și 20 pot fi executate în orice ordine (sau concurent), fără nici un efect asupra programului. Instrucțiunea 30, totuși, este constrânsă de a urma ambelor instrucțiuni: 10 și 20. Controlul fluxului trebuie și el considerat în acest cadru al cerințelor de secvențiere. Această analiză este aplicarea condițiilor Bernstein pentru asigurarea determinării.

Rezultatul acestei analize este o rețea Petri care reprezintă programul cu număr minim de constrângeri de secvențiere, adică un program ce permite un paralelism maxim. Acum problema este de a compila acest program. Pentru aceasta este necesară reprezentarea variabilelor în regiștri și ordonarea instrucțiunilor pentru a produce o secvență complet ordonată de instrucțiuni în limbaj mașină. 6600 este un computer cu regiștri multipli și unități funcționale multiple, după cum a fost descris în capitolul 3.3.3. Deoarece unitățile funcționale pot executa în paralel instrucțiuni separate, este foarte importantă generarea instrucțiunilor într-o ordine ce maximizează paralelismul în execuția unităților funcționale. Paralelismul este de asemenea afectat de reprezentarea variabilelor în regiștri. Modelul de rețea Petri al constrângerilor programului este combinat cu un model de rețea Petri al unității de control CDC 6600, reprezentând constrângerile impuse de componenta hardware. Această rețea compusă reprezintă acum toate secvențele posibile de instrucțiuni care se pot executa cu componenta hard existentă și care să efectueze algoritmul programului. Această rețea este apoi executată pentru a produce toate aceste secvențe de instrucțiuni. Două (sau mai multe secvențe) sunt create de fiecare dată când două (sau mai multe) tranziții sunt simultan activate. Declanșarea unei tranziții va produce o secvență; declanșarea alteia va produce o altă secvență. De exemplu, rețeaua Petri din figura 3.36 reprezintă secvențele a b c d e f, b a c d e f, a b c e d f și b a c e d f. Pe măsură ce aceste secvențe sunt produse, este calculată cantitatea de timp necesară pentru executarea fiecăreia, iar secvența cea mai rapidă este generată mai târziu de compilator pentru actuala execuție.

Figura 3.36: O rețea Petri care reprezintă câteva secvențe de execuții de instrucțiuni

Sistemele chimice sunt un alt exemplu de sisteme care pot fi modelate cu ajutorul rețelelor Petri. Ecuațiile chimice sunt modelate prin tranziții; reactanții sunt modelați prin locații. Numărul de jetoane dintr-o locație indică cantitatea din acel reactant în sistem. De exemplu, rețeaua Petri din figura 3.37 reprezintă următoarele două ecuații chimice:

H2C2O4 2CO2 + 2H+ + 2e-

2e- + 2H+ + H2O2 2H2O

Figura 3.37: O rețea Petri reprezentând oxido-reducerea acidului oxalic și a peroxidului de hidrogen în dioxid de carbon și apă

Reacțiile catalitice pot fi, de asemenea, reprezentate. Combinația de hidrogen și etilen pentru a forma etan (H2 + C2H4 C2H6) se execută numai în prezența platinei.. Diagrama din figura 3.38 reprezintă această situație.

Figura 3.38: Producerea etanului din hidrogen și etilen în prezența catalizatorului platină

Meldman și Holt [1971] au sugerat că sistemele legale pot fi modelate cu ajutorul rețelelor Petri. În aceste sisteme, unii actori (judecători, avocați, inculpați, funcționari, și așa mai departe) pot efectua concurent activități în funcție de un anumit aspect legal. Activitățile și relațiile dintre ele pot fi reprezentate cu ajutorul unei rețele Petri.

O altă utilizare posibilă a rețelelor Petri a fost în modelarea și analiza protocoalelor de comunicație [Merlin 1975]. Rețelele de calculatoare și sistemele cu procese distribuite trebuie să aibă abilitatea de a transmite informații între computere. Aceasta implică intrinsec paralelismul și de aceea se situează în clasa de probleme pentru care rețelele Petri au fost definite. Farber și studenții săi [Merlin 1974, Pastel 1974, Merlin și Farber 1976, Pastel și Farber 1976] au dezvoltat metodologii pentru specificarea, proiectarea și analiza protocoalelor simple de comunicație folosind rețelele Petri și alte modele similare.

Alte sisteme care pot fi modelate cu ajutorul rețelelor Petri includ rețelele de servire /așteptare (unde cozile de așteptare vor fi reprezentate prin locații și job-urile prin jetoane), modelele neuronale (declanșările neuronale vor fi modelate prin declanșări de tranziții), calcule propoziționale [Genrich 1975, Genrich și Lantenbach 1972] (locațiile reprezintă literali și tranzițiile îi combină pentru a defini clauze în forma normală conjuctivă), și multe altele. Lista este mărginită în general de timp și imaginația modelatorului, și nu de proprietățile rețelelor Petri. Totuși, am văzut cel puțin un exemplu (problema cititori/scriitori) care nu poate fi modelat cu ajutorul unei rețele Petri. De asemenea, deși modelarea ca rețea Petri poate ajuta la descrierea sistemului, este necesar să dezvoltăm instrumente de analiză care ne vor permite să examinăm o rețea Petri și să-i determinăm proprietățile. Aceasta ne conduce la următorul capitol, în care prezentăm metode de analiză pentru rețelele Petri.

Alte studii

Multe dintre cercetările asupra rețelelor Petri s-au făcut mai mult asupra analizei, nu modelării. Cercetări asupra aplicabilității rețelelor Petri în modelare au apărut în [Peterson 1977, Agerwola 1978]. Modelarea componentei hard a fost considerată în [Denis 1970a, Huen și Siewarek 1975]. Studiul lui Shapiro și Saint [1970] combină modelarea componentelor hard și soft pentru a implementa un compilator. Studiile lui Cooprider sunt concentrate asupra modelării sistemelor software cu ajutorul rețelelor Petri. Teza de masterat a lui Hack [Hack 1972] se referă la modelarea schemelor de producție care includ sisteme de tip linie de asamblare.

Baer și Ellis [1977] au folosit rețelele Petri pentru a modela un compilator, în timp ce Nee [1971] și Best [1976] au folosit rețelele Petri pentru a modela sisteme de operare. Nee și Kahl [1975] au modelat componenta hardware a unui sistem computațional. Azena și ceilalți [1975], Azena și ceilalți [1976] și Too și Musgrave [1975] au sugerat folosirea rețelelor Petri pentru proiectarea automatelor.

Munca de cercetare a lui Nee și Nutt este în special îndreptată asupra modelării sistemelor pentru a determina proprietățile de performanță. Munca lor [Nee 1971, Nutt 1972a, Nutt 1972b, Nee și Nutt 1973], conduce eventual la dezvoltarea unui model, E-nets, care este legat de rețelele Petri.

Analiza rețelelor Petri

În ultimul capitol am demonstrat puterea de modelare a rețelelor Petri. Rețelele Petri sunt capabile să modeleze o mare varietate de sisteme, reprezentând corect interacțiunile între diferitele tipuri de acțiuni care pot apărea. Marele avantaj al rețelelor Petri este, desigur, utilizarea în modelarea sistemelor concurențiale; concurența este modelată într-un mod natural și convenabil. Un model de rețea Petri poate fi folosit pentru a reprezenta și comunica proiectarea unui sistem concurent

Totuși, modelarea ca atare are o utilitate mărginită. Este necesară analiza sistemului modelat. Această modelare va conduce către concluzii importante asupra comportamentului sistemului modelat. De aceea, vom prezenta în acest capitol tehnici de analiză pentru rețelele Petri. Deși s-au dezvoltat tehnici pentru analiza rețelelor Petri, multe probleme sunt încă deschise. Pentru o mai bună evaluare a utilității tehnicilor de analiză care au fost dezvoltate, vom considera mai întâi ce tip de probleme necesită rezolvare în cazul rețelelor Petri. Obiectivul analizei rețelelor Petri este determinarea răspunsului la o întrebare despre rețelele Petri: ce tip de întrebări pot fi puse despre rețelele Petri?

Probleme de analizat pentru rețelele Petri

Următoarele proprietăți și întrebări au fost considerate în literatură despre rețelele Petri. Vom defini și ilustra aceste proprietăți în prima parte a acestui capitol și vom arăta tehnicile potrivite de analiză în a doua parte a acestui capitol.

Siguranța

Pentru o rețea Petri care modelează un dispozitiv hard real, una dintre cele mai importante proprietăți este siguranța. O locație din rețeaua Petri este sigură dacă numărul de jetoane din acea locație nu este niciodată mai mare ca 1. O rețea Petri este sigură dacă toate locațiile din rețea sunt sigure.

Definiția 4.1:

O locație pi a unei rețele Petri C = (P, T, I, O) cu marcajul inițial este sigură dacă pentru toate

’ R(C, ), ’ 1. O rețea este sigură dacă fiecare locație din rețea este sigură.

Siguranța este o proprietate foarte importantă pentru dispozitivele hard. Dacă o locație este sigură, atunci numărul de jetoane din acea locație este fie 0, fie 1. astfel locația poate fi influențată de o singură basculare (flip-flop).

Rețelele Petri originale erau sigure prin definiție, de vreme ce o tranziție nu putea să se declanșeze decât dacă toate locațiile sale de ieșire erau goale (și nu erau permise arce multiple). Acest fapt a fost motivat prin interpretarea unei locații ca reprezentând o condiție. O condiție, fiind o instrucțiune logică, este fie adevărată (atunci când în locație se află un jeton), fie falsă (atunci când în locație nu se află nici un jeton), iar jetoanele multiple nu au nici o interpretare. De aceea, marcajul fiecărei locații ar trebui să fie sigur într-o interpretare în termeni de condiții și evenimente.

Atâta timp cât o locație nu este o intrare multiplă sau o ieșire multiplă a unei tranziții, este posibilă forțarea acelei locații de a fi sigură. O locație pi care va fi forțată să fie sigură va fi suplimentată printr-o altă locație . Tranzițiile care folosesc pi ca intrare sau ieșire, se modifică după cum urmează:

Dacă pi I(tj) și pi O(tj) atunci se adaugă la O(tj).

Dacă pi O(tj) și pi I(tj) atunci se adaugă la I(tj).

Scopul acestei noi locații este acela de a reprezenta condiția “pi este goală”. De aceea, pi și sunt complementare, adică pi are un jeton numai dacă nu are nici unul, și viceversa. Orice tranziție care mută un jeton din pi trebuie să depoziteze unul în , și orice tranziție care mută un jeton din trebuie să depoziteze unul în pi. Marcajul inițial trebuie și el să fie modificat pentru a oferi exact un jeton fie lui pi, fie lui (Presupunem că marcajul inițial este sigur.) Observăm că această forțare a siguranței este posibilă numai pentru locațiile care sunt sigure în marcajul inițial și a căror multiplicitate de intrare și de ieșire este 0 sau 1, pentru toate tranzițiile. O locație care are o multiplicitate de doi pentru o tranziție va primi două jetoane la declanșarea tranziției respective, și de aceea nu poate să fie sigură. Figura 4.1 este o rețea Petri simplă care a fost forțată să fie sigură în figura 4.2.

Mărginire

Siguranța este un caz special al proprietății mai generale de mărginire. Gândindu-ne la limitările reale în implementarea locațiilor pentru componenta hard observăm că nu este necesar să cerem siguranță. Siguranța permite unei locații să fie influențată de o basculare (flip-flop), dar, mai general, ar putea fi folosit un dispozitiv de numărare. Totuși, orice astfel dispozitiv de numărare va fi limitat de numărul maxim care poate să fie reprezentat. O locație este k-sigură, sau k-mărginită dacă numărul de jetoane din acea locație nu poate fi mai mare de k.

Definiția 4.2:

O locație pi P a unei rețele Petri C = (P, T, I, O) cu un marcaj inițial este k-sigură dacă pentru fiecare ’ R(C, ), ’ k.

O locație care este 1-sigură este simplu numită sigură. Observăm că limita k a numărului de jetoane care se pot afla într-o locație poate fi o funcție a locației (exp: locația p1 este 3-sigură, în timp ce locația p2 este 8-sigură). Totuși, dacă o locație pi este k-sigură, atunci este, de asemenea, k’- sigură, pentru toți k’ k. De vreme ce există numai un număr finit de locații, putem alege k ca fiind maximul limitelor fiecărei locații și să definim o rețea Petri ca fiind k-sigură de vreme ce fiecare locație a rețelei este k-sigură.

Uneori ne poate preocupa numai dacă numărul de jetoane dintr-o locație este mărginit sau nu, și nu numărul exact ce reprezintă această limită. O locație este mărginită dacă este kj-sigură pentru unii kj. O rețea Petri este mărginită dacă toate locațiile sunt mărginite. O rețea Petri mărginită poate fi realizată în componenta hardware, în timp ce o rețea Petri cu o locație nemărginită nu poate fi în general implementată pe componenta hardware (Vă amintim că aceste definiții sunt independente de interpretare. În implementare, o locație poate să reprezinte o entitate care este mărginită, deși structura rețelei nu reflectă acest fapt.)

Conservativitatea

Rețelele Petri pot fi folosite pentru a modela sisteme de alocare a resurselor. Spre exemplu, o rețea Petri poate modela cererile, alocările și eliberările pentru dispozitivele de intrare /ieșire dintr-un sistem computațional. În aceste sisteme unele jetoane pot reprezenta resursele. O mulțime de trei imprimante este reprezentată printr-o locație cu un marcaj inițial cu trei jetoane. O cerere pentru o imprimantă este o tranziție care are această locație ca intrare; imprimanta este mai târziu eliberată de o tranziție cu o ieșire la locația asociată imprimantei.

Pentru aceste tipuri de rețele Petri, printre altele, conservativitatea este o proprietate importantă. Am vrea să arătăm că jetoanele care reprezintă resursele nu sunt nici create nici distruse. Cel mai simplu mod de a face aceasta este să cerem ca numărul total de jetoane din rețea să rămână constant.

Definiția 4.3:

O rețea Petri C = (P, T, I, O) cu marcajul inițial este strict conservativă dacă pentru toate

’ R(C, ), .

Conservativitatea strictă este o relație foarte puternică. De exemplu, putem arăta imediat că numărul de intrări pentru fiecare tranziție trebuie să fie egal cu numărul de ieșiri, adică |I(tj)| = |O(tj)|, deoarece în caz contrar declanșarea tranziției tj ar modifica numărul de jetoane din rețea.

Pentru o vedere mai largă, totuși, vom considera figura 4.3 ce reprezintă o rețea strict conservativă deoarece declanșarea oricăreia dintre tranzițiile t1 sau t2 va micșora numărul de jetoane cu 1, în timp ce declanșarea oricăreia dintre tranzițiile t3 sau t4 va adăuga un jeton la marcaj. Am putea, totuși, să convertim rețeaua Petri din figura 4.3 la rețeaua Petri din figura 4.4 , care este strict conservativă.

O rețea Petri ar trebui să conserve resursa pe care o modelează. Totuși, nu există o corespondență de 1 la 1 între jetoane și resurse. Unele jetoane reprezintă programe sau alte articole; alte jetoane pot reprezenta resurse reprezentate printr-un jeton. Acest jeton este folosit mai târziu pentru a crea jetoane multiple (unul pentru fiecare resursă) prin declanșarea unei tranziții cu mai multe ieșiri decât intrări. În general, am vrea să definim o pondere a jetoanelor. Suma ponderilor pentru toate marcajele accesibile ar trebui să fie constantă. Jetoanelor care nu sunt importante li se poate atașa o pondere 0; altor jetoane li se pot atașa ponderi de 1, 2, 3 sau orice alt întreg. (Numerele raționale vor fi acceptate de vreme ce ponderile pot fi înmulțite cu un numitor comun pentru a defini o pondere întreagă. Ponderile iraționale nu par a fi necesare.)

Un jeton este definit de locația sa în rețea, iar toate jetoanele dintr-o locație sunt identice. De aceea, ponderile sunt asociate cu fiecare locație a rețelei Petri. Un vector de ponderi w = (w1, … ,wn) definește o pondere wi pentru fiecare locație pi P.

Definiția 4.4:

O rețea Petri C = (P, T, I, O) cu marcajul inițial este conservativă cu respectarea unui vector de ponderi w, w = (w1, … , wn), n = |P|, wi 0, dacă pentru toate ’ R(C, ), .

O rețea Petri strict conservativă este conservativă cu respectarea vectorului de ponderi (1,…,1). Toate rețelele Petri sunt conservative cu respectarea vectorului de ponderi (0,…,0). Ultima observație ne deranjează deoarece am vrea să definim o rețea Petri ca fiind conservativă dacă este conservativă cu respectarea aceluiași vector de ponderi, și deoarece fiecare rețea Petri este conservativă cu respectarea vectorului zero, condiția dată nu este satisfăcătoare. Astfel, o rețea Petri este conservativă dacă este conservativă cu respectarea aceluiași vector nenegativ de ponderi, w > 0 (cu ponderi pozitive diferite de zero wi > 0).

De aceea, rețeaua Petri din figura 4.3 este conservativă, fiind conservativă cu respectarea vectorului de ponderi (1, 1, 2, 2, 1). Rețeaua Petri din figura 4.5 nu este conservativă.

Figura 4.5: O rețea Petri neconservativă

Viabilitatea

Motivația pentru considerarea conservativității într-o rețea Petri a fost alocarea resurselor într-un sistem de operare computațional. O altă problemă care poate apărea în alocarea resurselor pentru un sistem computațional este interblocarea. Interblocarea a fost subiectul a numeroase studii în știința calculatoarelor [Hebalker 1970]. Un exemplu simplu poate să ilustreze cel mai bine această problemă. Considerăm un sistem cu două resurse diferite q și r și două procese a și b. Dacă ambele procese au nevoie de ambele resurse, va fi nevoie să le folosească în comun. Pentru a realiza aceasta, vom cere fiecărui proces să ceară o resursă și mai târziu să o elibereze. Procesul a cere mai întâi resursa q și apoi resursa r, eliberând în final atât resursa q cât și resursa r. Procesul b este similar, doar că cere mai întâi resursa r și apoi resursa q. Figura 4.6 ilustrează aceste două procese și alocarea resurselor cu ajutorul unei rețele Petri.

Figura 4.6: Alocarea resurselor pentru două procese (a și b) și două resurse (q modelată de p4 și r modelată de p5)

Inițial, indicatoarele de marcaj q (p4) și r (p5) sunt disponibile și procesele a și b sunt pregătite. O execuție a acestei rețele este t1 t2 t3 t4 t5 t6; o alta este t4 t5 t6 t1 t2 t3 . Nici una dintre aceste execuții nu generează interblocare. Totuși, dacă considerăm secvența t1 t4, procesul a are q și cere r, iar procesul b are r și cere q, prin urmare sistemul este interblocat și nici un proces nu poate continua.

O interblocare într-o rețea Petri desemnează faptul că există o tranziție (sau o mulțime de tranziții) care nu se poate declanșa. În figura 4.6, interblocarea apare dacă tranzițiile t2 și t5 nu se pot declanșa. O tranziție este activă dacă nu este interblocată, și aceasta nu înseamnă că tranziția este executată, ci că poate fi executată. O tranziție tj a unei rețele Petri C este potențial declanșabilă într-un marcaj , dacă există un marcaj ’ R(C, ) astfel încât tj este posibilă în ’. O tranziție este activă într-un marcaj dacă este potențial declanșabilă în fiecare marcaj din R(C, ). Astfel, dacă o tranziție este activă, atunci este întotdeauna posibil să manevrăm rețeaua Petri din marcajul său curent către un marcaj care va permite tranziției să se declanșeze.

Mai sunt și alte concepte legate de viabilitate care au fost considerate în studiile despre interblocare [Commoner 1972]. Acestea pot fi grupate pe nivele de viabilitate și pot fi definite pentru o rețea Petri C cu marcajul după cum urmează:

Nivelul 0: O tranziție tj este activă la nivelul 0 dacă nu poate fi niciodată declanșată.

Nivelul 1: O tranziție tj este activă la nivelul 1 dacă este potențial declanșabilă; adică, dacă există

un marcaj ’ R(C, ) astfel încât tj să fie posibilă în ’.

Nivelul 2: O tranziție tj este activă la nivelul 2 dacă pentru fiecare întreg n există o secvență de

declanșare în care tj apare de cel puțin n ori.

Nivelul 3: O tranziție tj este activă la nivelul 3 dacă există o secvență de declanșare infinită în care

tj se petrece de un număr infinit de ori.

Nivelul 4: O tranziție tj este activă la nivelul 4 dacă pentru fiecare marcaj ’ R(C, ) există o

secvență de declanșare astfel încât tj să fie posibilă în (’, ).

O tranziție care este activă la nivelul 0 este blocată (dead). O tranziție care este activă la nivelul 4 este activă. O rețea este activă la nivelul i dacă fiecare tranziție este activă la nivelul

i = 1…4.

Pentru a exemplifica aceste nivele de viabilitate, considerăm figura 4.7. Tranziția t0 nu se poate declanșa niciodată, deci este blocată. Tranziția t1 se poate declanșa o singură dată, deci este activă la nivelul 1. tranziția t2 poate fi făcută să se declanșeze de un număr arbitrar de ori, dar acest număr este dependent de numărul de declanșări ale lui t3. Dacă dorim să declanșăm t2 de cinci ori, atunci declanșăm t3 de cinci ori, apoi t1 și apoi t2 de cinci ori. Totuși, odată ce t1 se declanșează (și t1 trebuie să se declanșeze înainte să se poată declanșa t2), t2 poate declanșa de un număr de ori fixat. Astfel, t2 este activă la nivelul 2, dar nu la nivelul 3. Tranziția t3, pe de altă parte, poate fi declanșată de un număr infinit de ori, de aceea este activă la nivelul 3, dar nu la nivelul 4, deoarece o dată declanșată t1, t3 nu mai poate fi declanșată.

Figura 4.7: O rețea Petri ce ilustrează diferitele nivele de viabilitate

Accesibilitate și acoperire

Multe dintre problemele care au fost menționate până acum se concentrează asupra marcajelor accesibile. Probabil cea mai simplă problemă (de stabilit) este problema accesibilității.

Definiția 4.5:

Problema accesibilității. Dată fiind o rețea Petri cu marcajul și un marcaj ’, ’ R(C, )?

Problema accesibilității este probabil cea mai simplă problemă de analiză asupra rețelelor Petri; multe alte probleme pot fi stabilite în termeni de accesibilitate. De exemplu, pentru rețeaua Petri din figura 4.6, interblocarea poate apărea dacă starea (0, 1, 0, 0, 0, 0, 1, 0) este accesibilă.

Figura 4.8 ilustrează o rețea Petri care își propune să rezolve problema excluziunii mutuale: locațiile p4 și p9 se așteaptă să se excludă mutual. Dorim să știm dacă orice stare este accesibilă cu p4 1 și p9 1. Această problemă este similară cu accesibilitatea, dar este ușor diferită și se numește problema acoperii. Un marcaj ’’ acoperă un marcaj ’ dacă ’’ ’.

Figura 4.8: O rețea Petri reprezentând soluția lui Hyman pentru problema excluziunii mutuale [Hyman 1966]. Datorită folosirii repetate a pozițiilor k0, k1, b1 și b0, acestea sunt repetate în graf pentru a-l face mai ușor de citit. Toate pozițiile etichetate k0 desemnează o singură locație.

Definiția 4.6:

Problema acoperirii. Dată fiind o rețea Petri C cu marcajul inițial ’, există un marcaj accesibil ’’ R(C, ) astfel încât ’’ ’?

O altă posibilă utilizare a problemelor de tip accesibilitate ar fi să ridicăm la pătrat conținutul unor locații, concentrându-ne numai asupra potrivirilor sau acoperind conținutul unor câteva locații importante. De exemplu, în rețeaua din figura 4.8, interesul nostru este concentrat asupra locațiilor p4 și p9; marcajele celorlalte locații nu sunt importante. Astfel, putem considera accesibilitatea sau acoperirea modulo o mulțime de locații. Astfel apar problema accesibilității submarcajului și problema acoperii submarcajului.

Aceste probleme pot fi complicate în continuare dacă vom dori să știm accesibilitatea sau acoperirea pentru o mulțime de marcaje. Problemele rezultate astfel se numesc problema accesibilității mulțimii și problema acoperirii mulțimii. Totuși, dacă mulțimea este finită, aceste probleme pot fi rezolvate prin soluționări repetate ale unor probleme de accesibilitate și acoperire pentru un marcaj.

Secvențe de declanșare

O altă abordare a analizei care a fost sugerată se concentrează mai mult asupra secvențelor de tranziții ce se declanșează decât asupra stărilor. Această abordare este legată de viabilitate, de vreme ce ne putem întreba: poate tranziția tj să fie declanșată (adică, este blocată)? Mai general, putem dori să determinăm dacă o secvență anume de tranziții ce se declanșează este posibilă, sau dacă este posibilă orice secvență dintr-o mulțime de secvențe ce se declanșează. În figura 4.8, spre exemplu, excluziunea mutuală va fi violată dacă poate apărea una din secvențele t3 t9 sau t4 t10, sau mai general t3 t9, unde este orice secvență de declanșări ce nu conține t4. Aceste întrebări de analiză introduc conceptul de limbaj al rețelelor Petri ce va fi investigat în detaliu în capitolul 6.

Probleme de echivalență și submulțime

O ultimă clasă de probleme apare din considerații legate de optimizare. Dacă o rețea Petri dă dovadă de un anumit comportament, după cum indică mulțimea sa de secvențe ce se declanșează și mulțimea sa de accesibilitate, poate rețeaua Petri să fie schimbată (optimizată) fără a-i afecta comportamentul? Această optimizare poate presupune ștergerea tranzițiilor blocate (dead – care nu pot fi niciodată declanșate) și a locațiilor moarte (care nu pot fi niciodată marcate), sau poate redefinirea unor tranziții. Putem noi arăta că două rețele Petri diferit marcate cu același număr de tranziții (dar probabil număr diferit de locații) vor genera aceeași secvență de tranziții ce se declanșează sau că două rețele Petri marcate diferit cu același număr de locații (dar probabil număr diferit de tranziții) vor genera aceeași mulțime de accesibilitate? Acese considerații ne-ar putea permite să modificăm rețelele Petri pentru a crește paralelismul, scădea costul implementării, sau alte optimizări.

În acest caz, suntem preocupați să stabilim dacă două rețele Petri sunt echivalente, sau dacă una este o submulțime a celeilalte. Trebuie să fim atenți cu aceste probleme, pentru a defini corect noțiunea de echivalență sau incluziune. Dacă definim echivalența ca rețele egal accesibile, atunci nu putem schimba numărul de locații, în vreme ce dacă cerem egalitatea mulțimilor de secvențe de tranziții care se declanșează, s-ar putea să nu putem schimba tranzițiile. Definirea problemei este de aceea foarte importantă.

Tehnici de analiză

Mai sunt și alte probleme care pot fi considerate, dar cele prezentate aici sunt problemele cel mai des întâlnite în literatură; vom menționa altele pe măsură ce va deveni necesar să le introducem. Se va putea vedea că există, pentru rețelele Petri, o serie de probleme care necesită soluții.

Se pune întrebarea dacă putem dezvolta tehnici de analiză pentru a rezolva aceste probleme, și se dorește, desigur, ca aceste tehnici să poată fi ușor implementate pe un computer, pentru a permite analiza automată a sistemelor modelate.

Au fost sugerate două tehnici majore de analiză a rețelelor Petri, care vor fi prezentate în această secțiune. Aceste tehnici oferă mecanisme de soluționare pentru câteva dintre problemele anterioare. Tehnica principală care s-a folosit pentru analiza rețelelor Petri este arborele de accesibilitate. Cealaltă tehnică presupune ecuații cu matrice. Le vom discuta pe fiecare din acestea pe rând.

Arbore de accesibilitate

Arborele de accesibilitate reprezintă mulțimea de accesibilitate a unei rețele Petri. Pentru exemplificare, vom considera rețeaua Petri marcată din figura 4.9. Marcajul inițial este (1 0 0). În acest marcaj inițial două tranziții sunt posibile t1 și t2. Deoarece dorim să considerăm întreaga mulțime de accesibilitate, definim noi noduri în arborele de accesibilitate pentru marcajele (accesibile) care rezultă din declanșarea ambelor tranziții. Un arc etichetat de tranziția declanșată, merge de la marcajul inițial la fiecare dintre noile marcaje (figura 4.10). Acest arbore (parțial) arată toate marcajele care sunt direct accesibile din marcajul inițial.

Acum trebuie să considerăm toate marcajele accesibile din aceste noi marcaje. Din marcajul (1 1 0) putem declanșa din nou t1 [rezultând (1 2 0)] și t2 [rezultând (0 2 1)], iar din marcajul (0 1 1) putem declanșa t3 [rezultând (0 0 1)]. Astfel rezultă arborele din figura 4.11.

Figura 4.11: Al doilea pas în construirea unui arbore de accesibilitate

Cu cele trei noi marcaje, trebuie să repetăm procesul, producând noi marcaje ce se adaugă la arbore, care va arăta acum ca în figura 4.12. Se observă că marcajul (0 0 1) este blocat (dead), deoarece nici o tranziție nu este posibilă și astfel nici o tranziție nu mai este produsă în arbore de către acest marcaj mort (dead). De asemenea, observăm că marcajul produs prin declanșarea tranziției t3 în (0 2 1) este (0 1 1), care a fost, de asemenea, produs direct din marcajul inițial prin declanșarea tranziției t2.

Figura 4.12: Al treilea pas în construirea unui arbore de accesibilitate

Dacă această procedură este repetată la infinit, fiecare marcaj accesibil va fi eventual produs. Totuși, arborele de accesibilitate rezultat s-ar putea foarte bine să fie infinit. Dacă fiecare marcaj este în mulțimea de accesibilitate, atunci s-ar putea ca arborele de accesibilitate corespunzător să fie de asemenea infinit. Chiar și o rețea Petri cu o mulțime de accesibilitate finită poate avea un arbore infinit (figura 4.13). Arborele reprezintă toate secvențele posibile de secvențe care se declanșează. Fiecare drum în arbore, pornind de la rădăcină, corespunde unei secvențe legale de tranziții. Deoarece arborele s-a dovedit a fi un bun instrument de analiză, trebuie să găsim o cale să-l limităm la o dimensiune finită. (Observăm că dacă reprezentarea unei mulțimi infinite este finită, atunci un număr infinit de marcaje trebuie să apară pe aceeași reprezentare. Aceasta va determina, în general, o pierdere de informație, care poate însemna că unele proprietăți ale rețelelor Petri nu pot fi determinate, dar aceasta depinde de cum este realizată reprezentarea.)

Figura 4.13: O rețea Petri simplă cu un arbore infinit de accesibilitate

Reducerea la o reprezentare finită poate fi realizată prin mai multe metode. Trebuie să găsim o metodă de a limita noile marcaje (numite noduri de frontieră) introduse la fiecare pas. Această operație este facilitată de nodurile moarte (dead), adică acele marcaje în care nici o tranziție nu este posibilă. Aceste marcaje moarte (dead) sunt cunoscute sub numele de noduri terminale. O altă clasă de marcaje sunt acele marcaje care au apărut anterior în arbore. Aceste marcaje duplicate sunt cunoscute ca noduri duplicate, și nu este necesar să se considere nici un succesor al unui astfel de nod, deoarece toți succesorii vor fi produși de la prima apariție în arbore a marcajului. De aceea, în arborele din figura 4.12 marcajul (0 1 1) care rezultă din secvența t1 t2 t3 nu produce noduri următoare în arbore, de vreme ce a mai apărut mai devreme în arbore ca rezultat al secvenței t2 din marcajul inițial.

Mai există o metodă care poate fi folosită pentru a reduce arborele de accesibilitate la o reprezentare finită. Pentru aceasta considerăm o secvență de tranziții care se declanșează care începe cu un marcaj și se sfârșește cu un marcaj ’, astfel încât ’ > . Marcajul ’ este același cu marcajul , cu excepția faptului că are câteva jetoane “suplimentare” în unele locații, ceea ce înseamnă că ’ = + (’ – ) și ’ – > 0. Acum, deoarece declanșările tranzițiilor nu sunt afectate de jetoanele suplimentare, secvența poate fi declanșată din nou, începând din ’ și terminând în ’’. Deoarece efectul secvenței de tranziții a fost să adauge ’ – jetoane la marcajul , la această nouă declanșare va mai adăuga încă ’’ – jetoane la marcajul ’, astfel încât ’’ = ’ + (’ – ) [sau ’’ = + 2(’ – )]. În general, putem să declanșăm secvența de n ori pentru a produce un marcaj + n(’ – ). Astfel, pentru acele locații care au câștigat jetoane de la secvența putem crea un număr arbitrar de mare de jetoane doar prin repetarea secvenței de câte ori dorim. În rețeaua Petri din figura 4.9, de exemplu, putem declanșa tranziția t1 de câte ori este nevoie pentru a construi un număr arbitrar de jetoane în p2.

Reprezentăm numărul infinit de marcaje care rezultă din aceste tipuri de bucle folosind un simbol special w, pe care îl putem gândi ca “infinit” și care reprezintă un număr de jetoane care poate fi făcut arbitrar de mare. Pentru orice constantă a, definim operațiile : w + a = w; w – a = w; a < w; w w, singurele necesare pentru construirea arborelui de accesibilitate.

Actualul algoritm pentru construirea arborelui de accesibilitate poate fi acum precizat exact. Fiecărui nod i din arbore i se asociază un marcaj extins [i], pentru a permite astfel ca numărul de jetoane dintr-un marcaj să fie fie un întreg nenegativ, fie simbolul w. Fiecare nod este clasificat, de asemenea, ca nod de frontieră, terminal, duplicat, sau interior. Nodurile de frontieră sunt nodurile care nu au fost încă procesate de algoritm; ele sunt convertite de algoritm în noduri terminale, duplicate sau interioare.

Algoritmul începe prin definirea marcajului inițial ca rădăcină a arborelui, și inițial, nod de frontieră. Atâta timp cât există noduri de frontieră, ele sunt procesate de algoritm.

Fie x un nod de frontieră ce urmează să fie procesat.

Dacă există un alt nod y în arbore care nu este nod de frontieră și are același marcaj asociat, adică (x) = (y), atunci nodul x este un nod duplicat.

Dacă nici o tranziție nu este posibilă pentru marcajul [x] (adică, ([x], tj) nu este definită pentru nici un tj T), atunci x este nod terminal.

Pentru toate tranzițiile tj T care sunt posibile în [x] (adică, ([x], tj) este definită), creează un nou nod z în arborele de accesibilitate. Marcajul [z] asociat cu acest nou nod este, pentru fiecare locație pi:

Dacă [x]j = w, atunci [z]i = w.

Dacă există un nod y pe drumul de la rădăcină la nodul x cu [y] < ([x], tj) și

[y]i < ([x], tj)i, atunci [z]i = w.

Altfel, [z]i < ([x], tj)i.

Un arc, etichetat tj, este direcționat de la nodul x la nodul z. Nodul x este redefinit ca un nod

interior; nodul z devine un nod de frontieră. Când toate nodurile au fost clasificate ca terminale, duplicate sau interioare, algoritmul se oprește.

Figura 4.14 reprezintă arborele de accesibilitate al rețelei Petri din figura 4.9. Arborele de accesibilitate al rețelei Petri din figura 4.15 este arătat în figura 4.16.

Figura 4.14: Arborele de accesibilitate pentru rețeaua Petri din figura 4.9.

Figura 4.15: O rețea Petri pentru a ilustra

construcția arborelui de accesibilitate.

O proprietate foarte importantă a algoritmului pentru construirea arborelui de accesibilitate este faptul că se termină. Pentru a demonstra aceasta trebuie să arătăm că algoritmul nu poate continua să creeze la infinit noi noduri de frontieră. Demonstrarea acestei proprietăți necesită trei leme.

Lema 1:

În orice arbore direcționat infinit în care fiecare nod are numai un număr finit de succesori direcți, există un drum infinit ce pornește de la rădăcină.

Demonstrație:

Începem de la rădăcină cu nodul x0. Deoarece există numai un număr finit de succesori direcți ai lui x0, dar numărul total de noduri din arbore este infinit, cel puțin unul dintre succesorii direcți ai lui x0 trebuie să fie rădăcina unui subarbore infinit (dacă toți subarborii având ca rădăcini succesorii direcți ai lui x0 ar fi finiți, atunci arborele cu rădăcina x0 ar fi finit.) Se alege un nod x1 care este un succesor direct al lui x0 și rădăcină a unui subarbore infinit. Acum, unul dintre succesorii săi direcți este, de asemenea, rădăcina unui subarbore infinit; alegem x2 un astfel de succesor direct. Continuând în această manieră, obținem un drum infinit x0, x1, x2 … în arbore.

Lema 2:

Fiecare secvență infinită de întregi nenegativi conține o secvență infinită care nu este descrescătoare.

Demonstrație:

Apar două cazuri:

Dacă un element al secvenței apare de o infinitate de ori, atunci fie x0 un astfel de element. Secvența infinită x0, x0, … este o subsecvență infinită care nu este descrescătoare.

Dacă nici un element nu apare de o infinitate de ori, atunci fiecare element apare numai de un număr finit de ori. Fie x0 un element arbitrar al secvenței. Sunt cel mult x0 întregi care sunt nenegativi și mai mici decât x0 [0, 1,…, x0 – 1], și fiecare dintre aceștia apare în secvență numai de un număr finit de ori. Astfel, mergând suficient de departe în secvență, trebuie să întâlnim un element x1 cu x1 x0. Similar, trebuie să existe un x2 mai departe în secvență, cu x2 x1, și așa mai departe. Definim astfel o secvență infinită care nu este descrescătoare: x0, x1, x2, ….

În fiecare dintre aceste două cazuri, există o secvență infinită care nu este descrescătoare.

Lema 4.3:

Fiecare secvență infinită de vectori de dimensiune n peste întregii nenegativi extinși (întregi nenegativi plus simbolul w) conține o subsecvență infinită care nu este descrescătoare.

Demonstrație:

Prin inducție după n, dimensiunea spațiului vectorial:

Verificare:

(n=1)

Dacă există un număr infinit (w) de vectori în secvență, atunci aceștia formează o secvență infinită care nu este descrescătoare. Dacă nu, secvența infinită formată prin ștergerea unui număr finit de vectori (v) conține o subsecvență infinită care nu este descrescătoare, conform lemei 4.2.

Ipoteza de inducție:

(Presupunem că lema este adevărată pentru n și demonstrăm că este adevărată și pentru n+1)

Considerăm prima coordonată. Dacă există un număr infinit de vectori cu w prima coordonată, atunci selectăm această subsecvență infinită care nu este descrescătoare (este constantă) în prima coordonată. Dacă există numai un număr finit de vectori cu w prima coordonată, atunci considerăm secvența infinită de întregi care au prima coordonată ca în lema 4.2. Această secvență conține o subsecvență infinită care nu este descrescătoare. Astfel, definim o subsecvență infinită de vectori care nu sunt descrescători în prima coordonată.

În fiecare caz, avem o secvență de vectori care nu sunt descrescători în prima coordonată. Aplicăm ipoteza de inducție pe secvența de vectori de dimensiune n, care rezultă prin ignorarea primei componente a fiecărui vector. Subsecvența infinită care se obține astfel nu este descrescătoare în nici o coordonată.

Acum putem demonstra următoarea teoremă:

Teorema 4.1:

Arborele de accesibilitate al unei rețele Petri este finit.

Demonstrație:

Vom face demonstrația prin reducere la absurd.

Presupunem prin absurd că există un arbore de accesibilitate infinit. Atunci, conform lemei 4.1, există un drum infinit x0, x1, x2, … de la rădăcina x0. (Numărul de succesori pentru fiecare nod din arbore este limitat de m, numărul de tranziții.) Apoi, [x0], [x1], [x2], … este o secvență infinită de vectori de dimensiune n peste H {w} și, conform lemei 4.3, conține o subsecvență . Dar, din construcție, nu putem avea [xi] = [xj], deoarece astfel unul ar fi un nod duplicat și nu ar avea succesori. Astfel, trebuie să avem o secvență infinită strict crescătoare . Dar, din nou din construcție, deoarece [xi] < [xj], ar trebui să înlocuim cel puțin o componentă a lui [xi] printr-un w în [xj]. Astfel, are cel puțin o componentă care este w, are cel puțin două componente care sunt w, iar are cel puțin n componente care sunt w. Deoarece marcajele sunt n-dimensionale, are toate componentele w. Dar apoi nu poate fi mai mare decât . Aceasta este o contradicție, ceea ce demonstrează că presupunerea noastră că ar exista un arbore de accesibilitate infinit era incorectă.

Construcția arborelui de accesibilitate a fost mai întâi descrisă de Karp și Miller [1968]. O variantă a fost dată de Keller [1972]. Demonstrația dată aici a faptului că arborele de accesibilitate este finit a fost dată de Hack [1974a], care s-a bazat în demonstrația sa pe demonstrația formulată de Miller [1968].

Arborele de accesibilitate este un instrument extrem de util pentru analiza rețelelor Petri, și de aceea vom arăta, în următoarele secțiuni, cum poate fi folosit pentru rezolvarea câtorva din problemele prezentate în secțiunea 4.1

Siguranță și mărginire

O rețea Petri este sigură dacă numărul de jetoane din fiecare locație este cel mult 1; o rețea Petri este mărginită dacă există un întreg k astfel încât numărul de jetoane din fiecare locație să nu fie mai mare de k. Fiecare dintre aceste proprietăți poate fi testată folosind arborele de accesibilitate. O rețea Petri este mărginită dacă și numai dacă simbolul w nu apare niciodată în arborele său de accesibilitate. Apariția simbolului w ca parte a unui arbore de accesibilitate arată că numărul de jetoane este “potențial nelimitat”; există o secvență de tranziții ce se declanșează care poate fi repetată de un număr arbitrar de ori pentru a crește numărul de jetoane la un număr arbitrar, nelimitat . Astfel, dacă apare simbolul w, rețeaua nu este mărginită. În plus, simbolul w indică prin poziția sa care locație nu este mărginită.

Desigur, dacă rețeaua Petri nu este mărginită, atunci numărul de marcaje accesibile este infinit. Deoarece arborele de accesibilitate este finit, simbolul w trebuie să apară pentru a reprezenta numărul infinit de marcaje accesibile.

Dacă rețeaua Petri este mărginită și simbolul w nu apare în arborele de accesibilitate, atunci rețeaua Petri reprezintă un sistem cu stări finite. În acest caz, arborele de accesibilitate este esențial un graf de stări și va conține un nod corespunzător fiecărui marcaj accesibil. Aceasta permite ca fiecare altă problemă de analiză să fie rezolvată printr-o simplă examinare exhaustivă a mulțimii finite de marcaje accesibile. De exemplu, pentru a determina mărginirea unei locații anume, se generează arborele și apoi se parcurge căutându-se cea mai mare valoare a componentei marcajelor corespunzătoare acelei locații. Aceasta este limita numărului de jetoane pentru acea locație. Dacă limita pentru toate locațiile este 1, atunci rețeaua este sigură.

Figura 4.17 demonstrează folosirea arborelui de accesibilitate pentru determinarea mărginirii

Observăm că, chiar și pentru rețelele Petri care nu sunt mărginite (deoarece unele locații sunt nemărginite) este posibil să determinăm limitele pentru acele locații din arborele de accesibilitate care sunt mărginite. De aceea, arborele de accesibilitate rezolvă efectiv analiza rețelelor Petri pentru a determina mărginirea și siguranța pentru locații independente din întreaga rețea.

Figura 4.17: Determinarea mărginirii pentru

o rețea Petri folosind arborele de accesibilitate

Conservativitate

O rețea Petri este conservativă dacă nu pierde sau câștigă jetoane, ci doar le mută. De aceea, două jetoane pot fi interpretate ca un jeton care mai târziu determină o tranziție să se declanșeze, creând două jetoane, un vector de ponderi definește valoarea unui jeton în fiecare locație; ponderile sunt nenegative. O rețea Petri este conservativă cu respectarea unui vector de ponderi dacă suma ponderilor jetoanelor este constantă peste toate marcajele accesibile.

Conservativitatea poate fi efectiv testată folosind arborele de accesibilitate. Deoarece arborele de accesibilitate este finit, suma ponderilor poate fi calculată pentru fiecare marcaj. Dacă sumele sunt aceleași pentru fiecare marcaj accesibil, atunci rețeaua este conservativă cu respectarea ponderilor date. Dacă sumele nu sunt egale, rețeaua nu este conservativă.

Simbolul w trebuie să fie considerat cu atenție în evaluarea conservării. Dacă un marcaj are w ca marcaj pentru locația pi, atunci ponderea locației trebuie să fie “0” pentru ca rețeaua să fie conservativă. Vă reamintim că simbolul w reprezintă o mulțime infinită de valori. Deoarece toate ponderile sunt nenegative, ponderea trebuie să fie zero (indicând faptul că valoarea numărului de jetoane din locație nu este importantă), sau pozitivă: “Dacă ponderea este pozitivă, atunci suma va varia pentru două marcaje care diferă în componenta care este w.” De aceea, dacă există un marcaj cu ponderea nonzero w, atunci rețeaua nu este conservativă.

Considerațiile de mai sus se referă la conservativitatea cu respectarea unor ponderi definite. O rețea Petri este conservativă dacă este conservativă cu respectarea unui vector de ponderi w, cu wj > 0. Arborele de accesibilitate poate fi folosit pentru a determina dacă o rețea Petri este conservativă prin găsirea unui vector pozitiv de ponderi w, dacă există un astfel de vector. Pentru a determina un vector pozitiv de ponderi în raport cu care rețeaua Petri să fie conservativă, observăm mai întâi că rețeaua trebuie să fie mărginită. După cum am arătat anterior, o locație care nu este mărginită trebuie să aibă o pondere zero, lucru care nu este posibil într-o rețea cu un vector de ponderi pozitiv. (Dacă dorim să permitem componente zero, setăm ponderile tuturor locațiilor nemărginite la zero și considerăm mai departe numai componentele rămase.) Acum, dacă rețeaua este conservativă, există o sumă a ponderilor, notată cu S și un vector de ponderi w = (w1, w2,…, wn). Pentru fiecare marcaj [x] al arborelui de accesibilitate trebuie să avem:

w1[x]1 + w2[x]2 + … + wn[x]n = S.

Aceasta definește, pentru k noduri din arborele de accesibilitate, o mulțime de k ecuații liniare cu n + 1 necunoscute. Dacă adăugăm la acestea constrângerile wi 0, i = 1…n, avem definite constrângerile pentru vectorul de ponderi.

Soluționarea acestui sistem de ecuații liniare este o problemă bine cunoscută, cu mulți algoritmi de rezolvare. Putem considera o problemă de programare liniară sau pur și simplu un sistem de ecuații liniare. În oricare dintre aceste cazuri, dacă există o soluție, aceasta poate fi calculată. (În general, soluțiile pentru aceste sisteme vor fi numere raționale, nu întregi, dar ponderile pot fi înmulțite cu un numitor comun pentru a produce o soluție întreagă.)

Dacă ponderile au prea multe constrângeri și de aceea nu există nici un vector de ponderi, acest fapt va fi determinat. În fiecare caz se poate determina dacă rețeaua Petri este sau nu conservativă, și dacă este, se produce un vector de ponderi.

Acoperabilitatea

O ultimă problemă care poate fi rezolvată cu ajutorul arborelui de accesibilitate este problema acoperirii. Pentru această problemă, dorim să determinăm, pentru un marcaj dat ’ dacă un marcaj ’’ ’ este accesibil. Dat fiind un marcaj inițial , construim arborele de accesibilitate. Apoi, putem căuta orice nod x, cu [x] ’. Dacă nu se găsește nici un astfel de nod, marcajul ’ nu este acoperit de nici un marcaj accesibil; dacă este găsit un astfel de nod, [x] dă un marcaj accesibil care acoperă.

Drumul de la rădăcină la marcajul acoperitor definește secvența de tranziții care conduce de la marcajul inițial la marcajul acoperitor, iar marcajul asociat cu acel nod definește marcajul acoperitor. Din nou, desigur, simbolul w trebuie tratat ca reprezentând o mulțime infinită de valori. Dacă o componentă a marcajului acoperitor este w, atunci va exista o buclă în drumul de la rădăcină la marcajul acoperitor. Va fi necesar să parcurgem această buclă de un număr de ori suficient de mare pentru a crește componentele corespunzătoare astfel încât să nu fie mai mici decât marcajul dat.

Observăm că dacă în marcajul acoperitor sunt mai multe componente care sunt w, s-ar putea să apară o interacțiune între schimbările din marcaj care rezultă prin parcurgerea buclelor. Considerăm rețeaua Petri din figura 4.12 și arborele său de accesibilitate dat în figura 4.19. În concordanță cu algoritmul de analiză dat, marcajul (0 14 1 7) este acoperit în mulțimea de accesibilitate. Drumul pentru generarea marcajului acoperitor constă din mai multe declanșări ale t1, urmate de o declanșare a lui t2, și apoi mai multe declanșări ale lui t3. Problema este să determinăm de câte ori t1 și de câte ori t3. De vreme ce vrem 14 jetoane în p2 și t1 pune un jeton în p2, putem încerca t1 de 14 ori. Totuși, avem nevoie de t3 de 7 ori, și fiecare t3 mută un jeton din p2, așa că de fapt avem nevoie de t1 de cel puțin 21 de ori, apoi t2 și în cele din urmă de t3 de cel puțin 7 ori (dar nu atât de mulți t3 astfel încât să golim p2 de prea multe ori). Karp și Miller [1968] dau un algoritm care va determina numărul minim de declanșări de tranziții necesare pentru a acoperi un marcaj dat.

Limitări ale arborelui de accesibilitate

După cum am văzut, arborele de accesibilitate poate fi folosit pentru a rezolva problema siguranței, a mărginirii, a conservării și pe cea a acoperabilității. Din nefericire nu poate, în general, să rezolve problema accesibilității și a viabilității sau să definească sau să determine care secvențe de declanșare sunt posibile. Aceste probleme sunt mărginite de existența simbolului w. Simbolul w reprezintă o pierdere de informație.

Considerăm, de exemplu, rețelele Petri din figurile 4.20 și 4.21, pentru care arborele de accesibilitate este dat în figura 4.20. Același arbore de accesibilitate reprezintă acolo două rețele Petri similare (dar diferite). Mulțimile de accesibilitate nu sunt aceleași, totuși. În rețeaua Petri din figura 4.18, numărul de jetoane din locația p2 este întotdeauna un număr par (până când se declanșează t1), în timp ce în figura 4.19 poate fi un întreg oarecare. Simbolul w nu permite acestui tip de informație să fie detectată, făcând imposibilă folosirea arborelui de accesibilitate în rezolvarea problemei accesibilității.

Figura 4.20: Arborele de accesibilitate al rețelelor Petri din figurile 4.20 și 4.21

O problemă similară există pentru problema viabilității. Figurile 4.23 și 4.24 sunt două rețele Petri pentru care arborele de accesibilitate este dat în figura 4.23. Totuși, rețeaua din figura 4.21 se poate interbloca (secvența t1 t2 t3 spre exemplu), în timp ce rețeaua din figura 4.22 nu. Din nou, totuși, arborele de accesibilitate nu poate distinge între aceste două cazuri.

Figura 4.23: Arborele de accesibilitate al rețelelor Petri din figurile 4.23 și 4.24

Observăm că deși arborele de accesibilitate nu conține neapărat suficientă informație pentru a rezolva întotdeauna problemele accesibilității și viabilității, o rețea al cărei arbore de accesibilitate conține un nod terminal (un nod fără succesori) nu este activă (deoarece unele marcaje accesibile nu au succesori). Similar, un marcaj ’ al unei probleme de accesibilitate poate să apară în arborele de accesibilitate, și dacă se întâmplă așa, acesta este accesibil. De asemenea, dacă un marcaj nu este acoperit de un nod al arborelui de accesibilitate, atunci nu este accesibil.

Aceste condiții sunt suficiente pentru a rezolva unele probleme de accesibilitate și viabilitate, dar ele nu rezolvă aceste probleme în general. De aceea, pentru a rezolva aceste două probleme, sunt necesare alte abordări.

Ecuații matriceale

O a doua abordare în analiza rețelelor Petri se bazează pe o vedere matricială a rețelelor Petri. O alternativă la definirea (P, T, I, O) a rețelelor Petri este să definim două matrice D– și D+ pentru a reprezenta funcțiile de intrare și ieșire. (Acestea sunt echivalente cu funcțiile F și B din definiția rețelelor Petri a lui Hack, prezentate în secțiunea 2.6). Fiecare matrice are m linii (una pentru fiecare tranziție) și n coloane (una pentru fiecare locație). Definim D–(j,i) = #(pi, I(tj)) și D+(j,i) = #(pi, O(tj)). D— definește intrările tranzițiilor și D+ definește ieșirile.

Această formă de definire matricială a unei rețele Petri, (P, T, D–, D+), este echivalentă cu forma standard pe care am utilizat-o, dar permite exprimarea ei în termeni de vectori și matrice. Fie e[j] un vector unitate de dimensiune m care este zero peste tot cu excepția componentei j. Tranziția tj este reprezentată de vectorul unitar m-dimensional e[j].

Acum, o tranziție tj este posibilă într-un marcaj dacă e[j] D–, și rezultatul declanșării tranziției tj în marcajul , dacă este posibilă, este:

(, ti) = – e[j] D– + e[j] D+ = + e[j] (-D– +D+) = + e[j] D, unde am definit matricea de schimbare compusă D = D+ – D–.

Acum, pentru o secvență de tranziții ce se declanșează = , avem:

(,) = (, ) = – e[j1] D + e[j2] D + … + e[jk] D = + (e[j1] + e[j2] + … + e[jk]) D = + f() D.

Vectorul f() = e[j1] + e[j2] + … + e[jk] se numește vector de declanșări al secvenței

= . Al i-ulea element al lui f(), f()i, reprezintă numărul de declanșări ale tranziției ti în secvența . Astfel, vectorul de declanșări este un vector de întregi nenegativi. (Vectorul f() este reprezentarea Parikh a secvenței [Parikh, 1966]).

Pentru a da un exemplu de utilitate a abordării matriciale a rețelelor Petri, considerăm problema conservării: dată fiind o rețea Petri marcată, este ea conservativă? Pentru a arăta conservativitatea, este necesar să găsim un vector de ponderi diferit de zero pentru care suma ponderilor peste toate marcajele accesibile este constantă. Fie w un vector coloană de dimensiune n x 1. Apoi, dacă este marcajul inițial și ’ este un marcaj accesibil arbitrar, trebuie ca: w = ’w.

Acum, deoarece ’ este accesibil, există o tranziție de tranziții care se declanșează și care trece rețeaua de la marcajul la marcajul ’. Astfel, ’ = (,) = + f() D.

De vreme ce această relație trebuie să fie adevărată pentru toți f(), rezultă că trebuie să avem Dw = 0.

Deci, o rețea Petri este conservativă dacă și numai dacă există un vector pozitiv w astfel încât Dw = 0, oferindu-se astfel un test simplu pentru conservativitate. Se produce, de asemenea, vectorul w al ponderilor.

Dezvoltarea acestei teorii matriciale a rețelelor Petri oferă un instrument folositor pentru a ataca problema accesibilității. Să presupunem că un marcaj ’ este accesibil dintr-un marcaj . Există astfel o secvență (posibil nulă) de tranziții ce se declanșează, care ne conduce din spre ’. Aceasta înseamnă că f() este o soluție în întregi nenegativi în următoarea ecuație matricială în x:

(4.1)

Astfel, dacă ’ este accesibil din , ecuația 4.1 are o soluție în întregi nenegativi. Dacă ecuația 4.1 nu are nici o soluție, atunci ’ nu este accesibil din .

Spre exemplu, vom considera rețeaua Petri marcată din figura 4.24.

Figura 4.24: O rețea Petri pentru a ilustra analiza cu ajutorul ecuațiilor matriciale

Matricele D— și D+ sunt

și , deci matricea D este .

Cu un marcaj inițial = (1, 0, 1, 0), tranziția t3 este posibilă și conduce la marcajul ’, unde .

Secvența = t3 t2 t3 t2 t1 este reprezentată de vectorul de declanșări f() = (1 2 2) și produce marcajul:

.

Pentru a determina dacă marcajul (1 8 0 1) este accesibil din marcajul (1 0 1 0), avem ecuația:

, care are o soluție x = (0, 4, 5) care corespunde secvenței = t3 t2 t3 t2 t3 t2 t3 t2 t3.

Arătăm mai departe că marcajul (1 7 0 1) nu este accesibil din marcajul (1 0 1 0), deoarece ecuația matricială:

nu are soluții.

Abordarea matricială a analizei rețelelor Petri este promițătoare, dar de asemenea creează câteva probleme. Mai întâi observăm că matricea D nu reflectă corect structura rețelei Petri. Tranzițiile care au atât intrări cât și ieșiri în /din aceeași locație (bucle) vor fi reprezentate pe aceeași poziție în matricile D— și D+, și astfel se vor anula în matricea D = D+ – D–. Acest lucru s-a reflectat în exemplul anterior pentru locația p1 și tranziția t1.

O altă problemă este pierderea de informație reprezentativă în vectorul de declanșări. Considerăm rețeaua Petri din figura 4.25.

Figura 4.25: O altă rețea Petri pentru analiza cu ajutorul ecuațiilor matriciale

Presupunem că dorim să determinăm dacă marcajul (0 0 0 0 1) este accesibil din (1 0 0 0 0). Singura ecuație este:

. Această ecuație nu are o soluție unică, dar reduce mulțimea soluțiilor la { / f() = (1, x2, x6 – 1, 2×6, x6 – 1, x6)}. Aceasta definește relațiile între declanșările de tranziții. Dacă luăm x6 = 1 și x2 = 1, avem f() = (1 1 0 2 0 1), secvențele t1 t2 t4 t4 t6 și t1 t4 t2 t4 t6 corespunzând acestui vector de declanșări. Astfel, deși cunoaștem numărul de declanșări ale tranzițiilor, nu cunoaștem ordinea în care se produc aceste declanșări.

O altă problemă este aceea că deși o soluție pentru ecuația 4.1 este necesară pentru accesibilitate, ea nu este și suficientă. Considerăm pentru aceasta rețeaua Petri din figura 4.26.

Figura 4.26: O rețea Petri care arată că o soluție a ecuației matriciale este o condiție necesară, dar nu suficientă pentru accesibilitate

Dacă dorim să determinăm dacă (0 0 0 1) este accesibil pentru (1 0 0 0) trebuie să rezolvăm ecuația:

.

Această ecuație are soluția f() = (1, 1), corespunzătoare reprezentărilor t1 t2 și t2 t1, dar nici una dintre aceste două secvențe de tranziții nu este posibilă, deoarece nici t1 nici t2 nu este activă în (1 0 0 0). Astfel, o soluție a ecuației 4.1 nu este suficientă pentru a demonstra accesibilitatea.

Posibilitatea de soluții false (aparente) pentru ecuația 4.1 – soluții care nu corespund secvențelor de tranziții posibile – a rezultat numai la cercetarea mărginită asupra rețelelor Petri în cazul reprezentării matriciale.

Alte studii

Holt at al. [1968] și Holt și Commoner [1970] au definit unele dintre primele probleme de analiză asupra rețelelor Petri – viabilitatea și siguranța – care au continuat apoi să fie tratate ca probleme fundamentale de analiză. Viabilitatea a fost studiată de Commoner [1972], Lautenbach [1973] și Lien [1976 a]. Keller [1972] a considerat de asemenea viabilitatea împreună cu alte probleme. Lien [1976 a] a definit problema conservării.

Karp și Miller [1968] au descris mai întâi modul de construcție al arborelui de accesibilitate și au dovedit că este finit. Problemele acoperabilității și accesibilității au fost definite de ei, la fel și problemele echivalenței și incluziunii. Aceste probleme au fost subiectul pentru [Baker 1973 b], în vreme ce [Hash 1973] este o scurtă prezentare a problemei accesibilității. Hack [1974] pune majoritatea acestor probleme împreună și arată cum arborele de accesibilitate poate fi folosit pentru unele dintre ele.

Abordarea matriceală a fost considerată de Peterson [1973], dar s-a descoperit că utilitatea sa este mărginită. Murata, cu o bază algebrică mai solidă, a realizat ceva mai mult cu această abordare [Murata și Church 1975; Murata 1975; Murata at al 1975; Murata 1977 a; Murata 1977 b].

Complexitate și decidabilitate

În capitolul 4 am prezentat un număr de probleme care au fost definite pentru rețelele Petri. Aceste probleme privesc diverse proprietăți ale structurii și comportamentului rețelelor Petri care, în anumite circumstanțe, sunt de interes pentru utilizatorii rețelelor Petri.

Au fost prezentate de asemenea două tehnici de soluționare: arborele de accesibilitate și abordarea cu ecuații matriciale. Aceste tehnici permit determinarea pentru rețelele Petri a proprietăților de siguranță, mărginire, conservare și acoperabilitate. De asemenea, a fost stabilită o condiție necesară pentru accesibilitate. Totuși, aceste tehnici de analiză nu sunt suficiente pentru a rezolva câteva alte probleme, în special problema viabilității, a accesibilității și a echivalenței. În acest capitol studiem aceste probleme, fie pentru a găsi soluții la ele, fie pentru a învăța măcar mai multe despre proprietățile rețelelor Petri.

Reducere între probleme de analiză

Un concept fundamental pe care noi îl folosim este reducerea [Karp 1972]. Rezolvarea unei probleme implică reducerea ei la o altă problemă pe care deja știm cum să o rezolvăm. De exemplu, în capitolul anterior, problema determinării dacă o rețea Petri este conservativă a fost redusă la rezolvarea unui sistem de ecuații liniare. Problema rezolvării sistemului de ecuații liniare a fost redusă la o secvență definită de operații algebrice (adunare, scădere, înmulțire, împărțire și comparări). Astfel, de vreme ce operațiile aritmetice de bază pot fi calculate, conservarea poate fi determinată.

Un alt exemplu privește problema egalității și problema submulțimii pentru mulțimi de accesibilitate.

Definiția 5.1:

Problema egalității. Date fiind două rețele Petri marcate Ci = (Pi, Ti, Ii, Oi), i = 1…2, cu marcajele i, i = 1… 2, avem R(C1, 1) = R(C2, 2)?

Definiția 5.2:

Problema submulțimii. Date fiind două rețele Petri marcate Ci = (Pi, Ti, Ii, Oi), i = 1…2, cu marcajele i, i = 1…2, avem R(C1, 1) R(C2, 2)?

Aceste două probleme pot fi foarte importante dacă rețelele Petri urmează să fie optimizate sau dacă urmează să se facă compararea între rețelele a două sisteme. Totuși, observăm că dacă se poate găsi o soluție la problema submulțimii, problema egalității este de asemenea rezolvată. Dacă dorim să determinăm dacă R(C1, 1) = R(C2, 2), putem să folosim mai întâi algoritmul pentru problema submulțimii pentru a determina dacă R(C1, 1) R(C2, 2), și apoi să folosim același algoritm pentru a determina dacă R(C2, 2) R(C1, 1).

R(C1, 1) = R(C2, 2) dacă și numai dacă R(C1, 1) R(C2, 2) și R(C2, 2) R(C1, 1). Astfel putem reduce problema egalității la problema submulțimii.

Mai există două alte considerații importante atunci când considerăm probleme de analiză și reducere. În primul rând, în încercarea de găsire a unei soluții, trebuie să considerăm posibilitatea ca o problemă să nu aibă nici o tehnică de soluționare; spunem despre o astfel de problemă că nu este decidabilă. În al doilea rând, dacă există tehnici de soluționare, trebuie să considerăm costul acestora: cât timp și memorie sunt necesare? Pentru ca rețelele Petri să poată fi larg utilizate, problemele de analiză trebuie să poată fi rezolvate și acest lucru trebuie să fie realizat de către algoritmi care nu sunt excesiv de costisitori de spațiu și timp (pentru calculator).

Reducerea joacă un rol important în ambele probleme. Reducerea problemelor una la alta este des folosită pentru a arăta că o problemă este sau nu decidabilă. Abordarea noastră asupra teoriei decidabilității [Davis 1958, Minsky 1967] se bazează în principal pe studiile lui Turing și pe modelul său de calcul: mașina Turing. Importanța mașinii Turing este aceea că se poate arăta că nu există nici un algoritm care să poată rezolva anumite probleme despre mașini Turing, în special problema opririi. Pornind de la acestea, s-a găsit o colecție de probleme care nu sunt decidabile. Importanța acestei teorii este aceea că nu este posibilă crearea unui program pentru un calculator care să rezolve aceste probleme. Astfel, pentru analize practice, problemele nedecidabile trebuie evitate, sau întrebările puse vor rămâne fără răspuns (este important de subliniat aici că problemele nedecidabile produc întrebări la care nu că nu s-a găsit încă un răspuns, și nu se poate găsi un răspuns). Întrebările pot fi fără răspuns încă, deși există posibilitatea să se găsească un răspuns; aceasta înseamnă, în principal, că nimeni nu a găsit încă un răspuns, dar că acesta există.

Acum presupunem că o problemă A este reductibilă la o problemă B: o instanță a problemei A poate fi transformată într-o instanță a problemei B. Dacă problema B este decidabilă, atunci problema A este decidabilă și algoritmul pentru problema B poate fi folosit pentru a rezolva problema A. O instanță a problemei A poate fi rezolvată transformând-o într-o instanță a problemei B și aplicând algoritmul pentru problema B pentru a determina soluția. Astfel, dacă problema A se reduce la problema B și problema B este decidabilă, atunci problema A este decidabilă.

Negația este de asemenea adevărată: dacă problema A se reduce la problema B și problema A este nedecidabilă, atunci problema B este nedecidabilă; dacă problema B ar fi fost decidabilă, procedura de mai sus este o tehnică de decizie pentru problema A, ceea ce contrazice nedecibilitatea sa. Aceste două fapte controlează cele mai multe tehnici de decidabilitate. Pentru a arăta că o problemă este decidabilă, se reduce la o problemă despre care se știe că este decidabilă.; pentru a arăta că o problemă este nedecidabilă, se reduce la o problemă despre care se știe că este nedecidabilă.

Trebuie să folosim corect această abordare pentru a reduce cantitatea de muncă pe care trebuie să o depunem. De exemplu, deoarece problema egalității pentru mulțimi de accesibilitate se reduce la problema submulțimii, vrem să dezvoltăm fie

o procedură de soluționare pentru problema submulțimii, fie

a demonstrație a faptului că problema egalității este nedecidabilă.

Dacă putem să arătăm (1), avem o tehnică de soluționare a ambelor probleme, iar dacă arătăm (2) vom ști că ambele probleme sunt nedecidabile.

În unele cazuri, putem obține chiar rezultate mai bune. Două probleme sunt echivalente dacă se pot reduce reciproc una la alta. Aceasta înseamnă că problema A este echivalentă cu problema B dacă problema A se poate reduce la problema B și problema B se poate reduce la problema A. În acest caz, fie ambele probleme sunt decidabile, fie ambele sunt nedecidabile, și putem lucra pe una singură. (Observăm că toate acestea nu sunt valabile în general. De exemplu, dacă vrem să arătăm că problema submulțimii pentru mulțimi de accesibilitate este nedecidabilă, aceasta nu ne va spune nimic despre decidabilitatea sau nedecidabilitatea problemei egalității.)

A doua considerație pentru investigarea problemelor de analiză este aceea că dacă există o tehnică de soluționare, ea trebuie să fie și rezonabilă din punctul de vedere al eficienței, adică timpul și spațiul de memorie necesare algoritmului pentru a rezolva o instanță a problemei să nu fie excesive. Studiul costului executării unui algoritm este o parte a teoriei complexității. Teoria complexității se ocupă cu cantitatea de timp și spațiu necesare pentru rezolvarea unei probleme. Evident, cantitatea de timp și spațiul nu vor fi constante, dar vor varia odată cu mărimea problemei de rezolvat. Pentru rețelele Petri, cerințele de timp și spațiu vor fi probabil funcție de numărul de locații și tranziții. Alți factori care pot influența lucrurile sunt numărul de jetoane din marcajul inițial, sau numărul de intrări și ieșiri pentru fiecare tranziție și locație (numărul de arce din graf).

Timpul și spațiul necesare vor varia în funcție de instanța particulară a problemei de rezolvat. De aceea, rezultatele de complexitate se pot referi la cel mai bun rezultat (limita inferioară) sau la cea mai proastă realizare (limita superioară) a unui algoritm. Deoarece nu se cunoaște dinainte dacă o instanță va fi o realizare bună sau proastă, se presupune de obicei cazul celei mai proaste realizări, și complexitatea unui algoritm este cea mai mare cantitate de timp sau spațiu necesară, funcție de mărimea intrării.

Analiza complexității se concentrează în principal asupra complexității problemei de bază și nu asupra unei anume implementări a unui algoritm particular. De aceea, teoria complexități ignoră factorii constanți. Complexitatea pentru o problemă de dimensiune n este determinată a fi de ordin n2, sau sau ignorând termenii mai mici și factorii constanți. În particular, sunt importante două clase generale de algoritmi: algoritmii cu complexitate polinomială (n, n2, , nq, și așa mai departe) și aceia cu complexitate nepolinomială (în special exponențială, 2n, și factorială (n!)).

Analiza complexității se aplică în general la algoritmi specifici, dar se poate de asemenea aplica și la probleme generale. În acest caz, se determină o limită inferioară a complexității tuturor algoritmilor de rezolvare a problemei. Astfel se obține un rezultat de complexitate independent de algoritm, care poate fi util pentru a arăta că un anume algoritm este optim (în interiorul unei constante) și pentru a semnala cazul în care un marcaj ulterior produce un algoritm de rezolvare a problemei nesemnificativ mai bun. De exemplu, este bine cunoscut faptul că sortarea a n numere este de complexitate . Astfel, algoritmii de complexitate nu pot fi semnificativ îmbunătățiți.

Reducerea poate fi utilă în determinarea complexității. Dacă o problemă A poate fi redusă la o problemă B și B are o complexitate fB(n), atunci complexitatea lui A este cel mult complexitatea lui B plus costul transformării de la A la B (Ținând minte că dimensiunea problemei se poate de asemenea schimba în transformare.) Complexitatea transformărilor este în general constantă sau liniară și de aceea este des ignorată. Astfel, reducerea problemei A la problema B ne dă fie o limită superioară pentru complexitatea lui A (dacă complexitatea lui B este cunoscută), fie o limită inferioară pentru B (dacă complexitatea lui A este cunoscută). Folosind din nou ca exemplu problemele egalității și submulțimii, cantitatea de muncă necesară pentru a rezolva problema egalității nu este mai mare decât de două ori cantitatea de muncă pentru problema submulțimii. Deoarece aceasta este un factor constant, complexitatea problemei submulțimii ar trebui să fie aceeași cu complexitatea problemei egalității.

Aceste două proprietăți ale analizei rețelelor Petri – decidabilitatea și complexitatea – sunt de importanță majoră pentru folosirea rețelelor Petri. În acest capitol sunt prezentate unele rezultate care au fost obținute. Una dintre tehnicile folosite este reducerea unei probleme de rețele Petri la o alta.

Probleme de accesibilitate

Problema accesibilității este una dintre cele mai importante probleme în analiza rețelelor Petri. S-au pus următoarele patru probleme de accesibilitate pentru o rețea Petri C = (P, T, I, O) cu marcajul inițial .

Definiția 5.3:

Problema accesibilității. Dat fiind marcajul ’, avem ’ R(C, )?

Definiția 5.4:

Problema accesibilității submarcajului. Pentru o submulțime P’ P și un marcaj ’, există ’’ R(C, ) astfel încât ’’ (pi) = ’ (pi) pentru toți pi P’?

Definiția 5.5:

Problema zero-accesibilității.

Există ’ R(C, ) astfel încât ’(pi) = 0 pentru toți pi P? [0 R(C, )?]

Definiția 5.6:

Problema zero-accesibilității pentru o singură locație. Pentru o poziție dată pi P, există ’ R(C, ) cu ’(pi) = 0?

Problema accesibilității submarcajului restricționează problema accesibilității la a considera numai o submulțime de locații, fără a ține seama de marcajele altor locații. Problema zero-accesibilității se întreabă dacă marcajul cu zero jetoane în toate pozițiile este accesibil. Problema zero-accesibilității pentru o singură poziție se întreabă dacă este posibilă golirea unei poziții anume de toate jetoanele.

Deși aceste patru probleme sunt toate diferite, sunt, de asemenea, toate echivalente. Anumite relații sunt evidente. Problema zero-accesibilității este reductibilă la problema accesibilității. Luăm ’ = 0 pentru problema accesibilității. Similar, problema accesibilității este reductibilă la problema accesibilității submarcajului, considerând submulțimea P’ = P. Problema zero-accesibilității pentru o singură locație este reductibilă la problema accesibilității submarcajului considerând P’ = {pi} și ’ = 0. Mai dificil de arătat este că problema accesibilității submarcajului este reductibilă la problema zero-accesibilității și că problema zero-accesibilități este reductibilă la problema zero-accesibilității pentru o singură locație. Această întreagă mulțime de relații este ilustrată în figura 5.1.

Figura 5.1: Reducerea problemelor de accesibilitate. Un arc de la o problemă la alta indică faptul că prima se reduce la a doua

Mai întâi arătăm că problema accesibilității submarcajului se reduce la problema zero-accesibilității. Presupunem dată o rețea Petri C1 = (P1, T1, I1, O1) cu marcajul inițial 1, o submulțime de locații P’ P1, și un submarcaj ’. Vrem să știm dacă există ’’ R(C1, 1) cu ’’ (pi) = ’ (pi) pentru toate pi P’. O abordare este crearea unei noi rețele Petri C2 = (P2, T2, I2, O2) cu marcajul inițial 2 astfel încât să existe ’’ R(C1, 1) cu ’’ (pi) = ’ (pi) pentru toate pi P’ dacă și numai dacă 0 R(C2, 2).

Construcția lui C2 pornind de la C1 este descrisă în continuare.

Începem cu C2 la fel cu C1. Pentru a permite oricărei locații pi care nu este în P’ să se golească adăugăm o tranziție cu intrarea {pi} și ieșirea nulă. Această tranziție se declanșează de fiecare dată când există un jeton în pi, pentru a goli această locație de orice jeton care s-ar putea afla aici. Acest fapt ne permite să ignorăm aceste poziții, fiind siguri că ele pot întotdeauna să ajungă la un marcaj zero.

Presupunem că în locația pi din P’ sunt exact ’(pi) jetoane. Pentru a ne asigura de aceasta, creăm o nouă locație pentru fiecare pi P’ cu un marcaj inițial de ’(pi) jetoane și o tranziție cu intrarea {pi, } și ieșirea nulă. Dacă în pi sunt exact ’(pi) jetoanei, atunci tranziția corespunzătoare se poate declanșa de exact ’(pi) ori, reducând marcajele lui pi și la zero. Dacă numărul de jetoane din pi nu este ’(pi), atunci tranziția poate să se declanșeze de un număr de ori egal cu minimul dintre cele două marcaje, și astfel vor rămâne jetoane fie în pi, fie în , fapt care împiedică ajungerea la un marcaj zero.

Figura 5.2 ilustrează cele două tipuri de tranziții introduse.

Figura 5.2: O rețea Petri ce arată că problema accesibilității submarcajului poate fi redusă la problema zero-accesibilității. Submulțimea de poziții P’ va avea marcajul ’ în rețeaua originală dacă și numai dacă marcajul zero este accesibil în rețea așa cum este modificată aici.

Formal, definim C2 astfel:

P2 = P1 { / pi P’}

T2 = T1 { / P1}

I2(tj) = I1(tj) pentru tj T1

I2() = {pi} pentru pi P’ = {pi, } pentru pi P’

O2(tj) = O1(tj) pentru tj T1

O2() = {} pentru pi P1,

cu un marcaj inițial 2(pi) = 1(pi), pi P1, 2() = ’(pi), pi P’.

Teorema 5.1:

Problema accesibilității submarcajului este reductibilă la problema zero-accesibilității.

Demonstrație:

Arătăm că pentru rețeaua Petri C2 construită mai sus din C1, 0 R(C2, 2) dacă și numai dacă ’’ R(C1, 1), cu ’’(pi) = ’(pi), pentru toate pi P’.

Pentru a arăta că 0 R(C2, 2) dacă și numai dacă există un marcaj ’’ R(C1, 1), cu ’’(pi) = ’(pi), pentru toate pi P’, presupunem mai întâi că există ’’ în R(C1, 1). Apoi, în C2, putem de asemenea ajunge la marcajul ’’ din locațiile pi P1, declanșând numai tranzițiile din T1. Acum, pentru fiecare pi P’, putem să declanșăm de exact ’(pi) ori, reducând atât pe pi cât și pe la zero. Apoi putem să declanșăm pentru fiecare pi P’ de câte ori este nevoie pentru a ajunge aici la zero jetoane, adică să avem 0 R(C2, 2).

Acum presupunem 0 R(C2, 2), deci presupunem că există o secvență de tranziții care se declanșează care ne conduce de la 2 la 0. Această secvență va conține exact ’(pi) declanșări ale lui pentru pi P’ (pentru a elimina jetoanele din ) și un număr de declanșări ale lui pentru pi P’. Observăm că prin declanșarea tranzițiilor doar sunt mutate jetoane din C1 și deoarece (’, tj) este definită de fiecare dată când (, tj) este definită, pentru ’ (jetoane suplimentare nu strică niciodată), secvența cu toate declanșate eliminate este de asemenea legală și va conduce la un marcaj ’’ cu exact ’(pi) jetoane în pi, pentru pi P’. Astfel, dacă 0 R(C2, 2), atunci ’’ R(C1, 1), cu ’’(pi) = ’(pi), pentru toate pi P’.

Următoarea noastră sarcină este să arătăm că problema zero-accesibilității este reductibilă la problema zero-accesibilității pentru o singură locație. Demonstrația acestei afirmații implică din nou o construcție. Dată fiind o rețea Petri C1 = (P1, T1, I1, O1) cu marcajul inițial 1, vrem să determinăm dacă 0 R(C1, 1). Pornind de la C1 construim o nouă rețea Petri C2 cu o locație suplimentară (P2 = P {}) astfel încât să existe un marcaj ’ R(C2, 2) cu ’() = 0 dacă și numai dacă 0 R(C1, 1).

Construcția lui C2 definește astfel încât la orice moment numărul de jetoane din este egal cu suma numărului de jetoane din toate pozițiile lui C1. Astfel, dacă ’() = 0, atunci sunt 0 jetoane în toate locațiile lui C1 și viceversa. Definim marcajul inițial 2 prin 2(pi) = 1(pi) pentru pi P1, cu (Acum, fiecare tranziție tj T1 este completată în C2 cu arce către locația .) Definim . Astfel, dj înregistrează modificarea numărului de jetoane care rezultă prin declanșarea tranziției tj. Dacă dj > 0, atunci dj jetoane trebuie adăugate locației s, și de aceea adăugăm dj arce de la tj la s; dacă dj < 0, atunci -dj jetoane trebuie scoase din locația s prin -dj arce de la s la tj.

Dacă dj > 0 atunci #(s, I(tj)) = 0 și #(s, O(tj)) = dj.

Dacă dj < 0 atunci #(s, I(tj)) = -dj și #(s, O(tj)) = 0.

Dacă dj = 0 atunci #(s, I(tj)) = 0 și #(s, O(tj)) = 0.

Cu această construcție, orice secvență de tranziții care se declanșează și care conduce C1 către marcajul 0, va conduce C2 către un marcaj ’ cu ’(s) = 0 [’(pi) = 0, de asemenea] și viceversa.

Teorema 5.2:

Problema zero-accesibilității este reductibilă la problema zero-accesibilității pentru o singură locație.

Demonstrație:

Demonstrația formală, bazată pe construcția de mai sus, este ușor de redactat.

Cu aceste două teoreme, și observațiile evidente, putem acum concluziona următoarele:

Teorema 5.3:

Următoarele probleme de accesibilitate sunt echivalente:

Problema accesibilității

Problema zero-accesibilității

Problema accesibilității submarcajului

Problema zero-accesibilității pentru o singură locație.

Aceste teoreme și demonstrațiile lor se datorează în special lui Hack [1975c].

Structuri mărginite de rețele Petri

Primele studii asupra rețelelor Petri, și unele contemporane, au definit rețelele Petri mai

restrictiv decât cum s-a făcut aici în capitolul 2. În particular, sunt uneori forțate următoarele două restricții.

Restricția 5.1:

Multiplicitatea oricărei locații este întotdeauna mai mică sau egală cu 1. Deci, #(pi, I(tj)) 1 și #(pi, O(tj)) 1 pentru toți pi P și tj T. Aceasta restricționează categoriile de intrare și ieșire la a fi mulțimi.

Restricția 5.2:

Nici o locație nu poate fi atât intrare cât și ieșire a aceleiași tranziții, adică I(tj) O(tj) = . Acest fapt se scrie de obicei #(pi, I(tj)) #(pi, O(tj)) = 0 pentru toți pi și tj.

Rețelele Petri care satisfac restricția 1 se numesc rețele Petri ordinare. Rețelele Petri care satisfac cea de-a doua restricție se numesc rețele Petri nereflexive. Rețelele Petri care satisfac ambele restricții se numesc rețele Petri restricționate. Relațiile dintre aceste clase de rețele Petri sunt ilustrate în figura 5.3

Figura 5.3: Relațiile dintre clasele de rețele Petri. Un arc indică includerea; arcele pentru indicarea reductibilității vor fi direcționate în direcția opusă

Aceste subclase ale modelului general de rețea Petri au fost considerate pentru câteva motive. Un motiv important este acela că propagarea conceptelor despre rețelele Petri a fost informativă în teoria inițială. Nevoia de arce multiple sau bucle nu a apărut de la bun început în modelare. De asemenea, s-a simțit probabil că teoria ar fi mai ușoară fără aceste complicații suplimentare. Totuși, cum teoria s-a dezvoltat, a devenit evident că nu este mult mai dificil să se lucreze cu definiții mai generale. Munca contemporană folosind modele cu aceste restricții este, de aceea, fie rezultatul unei timidități exagerate din partea cercetătorilor, sau rezultatul necesității unei expuneri mai rapide, care conduce la definiții mai simple.

Totuși, aceste definiții nu adaugă nimic la abilitatea noastră de a analiza rețelele Petri. Vom considera problema accesibilități pentru aceste clase de rețele. Pentru a arăta echivalența esențială a acestor patru clase de rețele Petri, vom demonstra următoarele.

Teorema 5.4:

Problemele accesibilității pentru următoarele clase de rețele Petri sunt echivalente:

Rețele Petri generale

Rețele Petri ordinare

Rețele Petri fără bucle

Rețele Petri restricționate

Demonstrație:

Următoarele reduceri sunt evidente din definiții:

Problema accesibilității pentru rețele Petri ordinare este reductibilă la problema accesibilității pentru rețele Petri generale.

Problema accesibilității pentru rețele Petri fără bucle este reductibilă la problema accesibilității pentru rețele Petri generale.

Problema accesibilității pentru rețele Petri restricționate este reductibilă atât la problema accesibilității pentru rețele Petri ordinare cât și la problema accesibilității pentru rețele Petri fără bucle.

Arătăm că rețelele Petri generale pot fi transformate în rețele Petri restricționate în sensul că

putem reduce problema accesibilității pentru rețele Petri generale la problema accesibilității pentru rețele Petri restricționate. Astfel se demonstrează că cele patru probleme de accesibilitate sunt echivalente.

Pentru a transforma o rețea Petri generală într-o rețea Petri restricționată folosim următoarea

abordare fundamentală prin care fiecare locație din rețeaua Petri generală este înlocuită de un inel de locații în rețeaua Petri restricționată. Figura 5.4 arată forma generală a unui inel de locații. Observăm că o colecție de jetoane plasate în inel se poate mișca liber prin acesta în orice poziție la orice moment; ele se pot toate grupa în locația pi,1 sau se pot răspândi uniform pentru a acoperi toate cele ki locații din inel. Astfel, o tranziție care are nevoie de trei jetoane din locația pi poate lua câte unul din pi,1, pi,2, și pi,3, mai degrabă decât pe toți trei din pi. Similar, o tranziție care folosește pi atât ca intrare cât și ca ieșire (o buclă) poate intra prin pi,1 și ieși prin pi,1, eliminând bucla.

Figura 5.4: Un inel de locații pentru a fi folosit într-o rețea Petri restricționată pentru a reprezenta o locație într-o rețea Petri generală. Numărul ki de locații reprezentând o locație pi este determinat de suma multiplicităților maxime ale locației

Formal, pentru o rețea Petri generală C1 = (P1, T1, I1, O1) cu marcajul 1 definim o rețea Petri restricționtă C2 = (P2, T2, I2, O2) cu marcajul 2 după cum urmează. Mai întâi definim pentru fiecare pi P1 un întreg ki prin:

Rețeaua Petri restricționată C2 este definită prin:

P2 = {pi,h / pi P1, h 1..ki}

T2 = T1 {ti,h / pi,h P2}

Funcțiile de intrare și ieșire pentru tranzițiile “normale” sunt definite astfel:

1, dacă h = 1 .. #(pi, I1(tj))

#(pi,h, I2(tj)) =

0, altfel

1, dacă h = #(pi, I1(tj)) + 1 .. #(pi, I1(tj)) + #(pi, O1(tj))

#(pi,h, O2(tj)) =

0, altfel

în timp ce pentru tranzițiile inel avem: I2(ti,h) = {pi,h}, O2 = {pi,h / n = 1 + (h mod ki)}

Marcajul 2 este definit prin:

2(pj,1) = 1(pi) pentru pi P1

2(pi,h) = 0 pentru h > 1

Prin construcție, pentru orice marcaj care este accesibil în C2, există un marcaj ’ al lui C2 astfel încât:

pentru toți pi P1.

În particular, este posibil să se mute în C2 toate jetoanele din pi,h în pi,1, la orice moment. Astfel putem defini un marcaj ’ după cum urmează:

’(pi,1) = (pi) pentru pi P1

’(pi,h) = 0 pentru h > 1 și ’ este accesibil în rețeaua Petri restricționată C2 dacă și numai dacă este accesibil în C1.

Astfel, din punctul de vedere al analizelor, rețelele Petri generale și aceste trei clase restricționate ale rețelelor Petri generale – rețele Petri ordinare, rețele Petri fără bucle și rețele Petri restricționate – sunt echivalente, deoarece fiecare poate fi transformată într-o rețea similară a unei alte clase, permițând ca o problemă de accesibilitate dintr-una să fie redusă la o problemă de accesibilitate din cealaltă. Construcțiile din acest capitol se datorează lui Hack [1974a].

Figura 5.5: Reductibilitatea problemei accesibilității pentru clasele de rețele Petri mărginite

Viabilitate și accesibilitate

Accesibilitatea este o problemă importantă, dar nu singura problemă rămasă pentru rețelele Petri. Viabilitatea este o altă problemă care a primit multă atenție în literatura de specialitate. Așa cum s-a arătat în capitolul 4.1.4, viabilitatea este legată de noțiunea de interblocare. Sunt considerate aici două probleme de viabilitate pentru rețeaua Petri C = (P, T, I, O) cu marcajul inițial . O rețea Petri este activă dacă fiecare tranziție este activă. O tranziție tj este activă într-un marcaj dacă pentru fiecare ’ R(C, ) există o secvență astfel încât tj este posibilă în (’, ). O tranziție tj este moartă (blocată) într-un marcaj dacă nu există nici un marcaj accesibil în care să se poată declanșa.

Definiția 5.7:

Problema viabilității. Pentru toate tranzițiile tj T, este tj activă?

Definiția 5.8:

Problema viabilității pentru o singură tranziție. Dată tranziția tj T, este aceasta activă?

Problema viabilității este evident reductibilă la problema viabilității pentru o singură tranziție. Pentru a rezolva problema viabilității, rezolvăm problema viabilității pentru o singură tranziție pentru fiecare tj T; dacă |T| = m, atunci trebuie să rezolvăm m probleme de viabilitate pentru o singură tranziție.

Problema accesibilității poate de asemenea fi redusă la problema viabilității. Deoarece multele variante ale problemei accesibilității sunt echivalente, vom folosi problema zero-accesibilității pentru o singură locație. Dacă avem oricare dintre celelalte probleme de accesibilitate, acestea pot fi reduse la problema zero-accesibilității pentru o singură locație, așa cum s-a arătat în capitolul 5.2. Acum, dacă dorim să determinăm dacă locația pi poate fi zero în orice marcaj accesibil pentru o rețea Petri C1 = (P1, T1, I1, O1) cu marcajul inițial 1, construim o rețea Petri C2 = (P2, T2, I2, O2) cu un marcaj inițial 2, care este activă dacă și numai dacă marcajul zero nu este accesibil din 1.

Rețeaua Petri C2 este construită din C1 prin adăugarea a două locații, r1 și r2, și a trei tranziții, s1, s2 și s3. Mai întâi modificăm toate tranzițiile lui T1 pentru a include r1 atât ca intrare cât și ca ieșire. Marcajul inițial 2 va include un jeton în r1. Locația r1 este o locație de rulare, deoarece atâta timp cât jetonul rămâne în r1, tranzițiile din T1 se pot declanșa normal. Astfel, orice marcaj care este accesibil în locațiile lui P1 în C1 este de asemenea accesibil și în C2. Tranziția s1 este definită ca având r1 ca intrare și o ieșire nulă. Aceasta permite mutarea jetonului din r1, dezactivarea tuturor tranzițiilor din T1 și “înghețarea” marcajului lui P1. (Observăm că toate tranzițiile din T1 sunt în conflict și, prin construcție, dacă nu prin definiție, nu se poate declanșa mai mult de o tranziție la un anumit moment.)

Locația r1 și tranziția s1 permit rețelei C1 să atingă orice marcaj accesibil și apoi, pentru s1, să declanșeze și să înghețe rețeaua la acest marcaj. Acum avem nevoie să vedem dacă locația pi este zero. Introducem o nouă locație r2 și o tranziție s2 care are pi ca intrare și r2 ca ieșire. Dacă pi poate să devină vreodată zero, această tranziție nu este activă; de fapt, întreaga rețea este blocată (moartă) dacă tranziția s1 se declanșează în acest marcaj. Din acest motiv, dacă pi poate fi zero, rețeaua nu este activă. Dacă pi nu poate fi zero, atunci s2 se poate declanșa întotdeauna, punând un jeton în r2. În acest caz trebuie să punem înapoi un jeton în r1 și să ne asigurăm că toate tranzițiile din C2 sunt active. Trebuie să ne asigurăm că C2 este activă, chiar dacă C1 nu este. Acest fapt este realizat de o tranziție s3 care “inundă” rețeaua C2 cu jetoane, asigurându-ne că fiecare tranziție este activă, dacă întotdeauna este pus un jeton în r2. Tranziția s3 are r2 ca intrare și fiecare locație a lui C2 (toate pi din C1 plus r1 și r2) este ieșire. Această construcție este ilustrată în figura 5.6.

Figura 5.6: O construcție ce convertește problema zero-accesibilității într-o singură locație (este un marcaj accesibil cu (pi) = 0?) la problema viabilității(este această rețea activă?)

Acum, dacă un marcaj este accesibil în R(C1, 1) cu (pi) = 0, atunci rețeaua C2 poate, de asemenea, atinge acest marcaj pe locațiile din P1 executând aceeași secvență de tranziții care se declanșează. Astfel, s1 se poate declanșa, înghețând submulțimea C1. Atâta vreme cât (pi) = 0, tranziția s2 nu se poate declanșa și C2 este blocată (moartă). Prin urmare, dacă pi poate deveni zero, atunci C2 nu este activă.

Reciproc, dacă C2 nu este activă, atunci un marcaj trebuie să fie accesibil în fiecare (r2) = 0 și nu există nici o stare accesibilă în care r2 să conțină un jeton. (Dacă r2 are un jeton, s3 este posibilă și s3 poate fi declanșată în mod repetat de suficient de multe ori pentru a face posibile anumite (sau toate) tranziții, și astfel rețeaua este activă.) Dacă r2 nu are nici un jeton și nu poate primi nici unul, atunci marcajul lui pi trebuie, de asemenea, să fie zero. Astfel, dacă C2 nu este activă, atunci un marcaj este accesibil acolo unde marcajul lui pi este zero.

Pe baza acestei construcții s-a obținut următorul rezultat:

Teorema 5.5:

Problema accesibilității este reductibilă la problema viabilității.

Acum avem nevoie să arătăm următoarele.

Teorema 5.6:

Problema viabilității pentru o singură tranziție este reductibilă la problema accesibilității.

Demonstrația că problema viabilității pentru o singură tranziție este reductibilă la problema accesibilității se rezumă la testarea accesibilității pentru fiecare mulțime finită de submarcaje maximale tj-blocate. O rețea Petri nu este activă pentru o tranziție tj dacă și numai dacă un marcaj este accesibil acolo unde tranziția tj nu se poate declanșa și nu poate deveni declanșabilă. Un marcaj de acest tip se numește tj-blocat. Pentru orice marcaj putem testa dacă este tj-blocat construind arborele de accesibilitate cu rădăcina și testând dacă tranziția tj se poate declanșa oriunde în arbore. Dacă nu poate, atunci este tj-blocat. Astfel, pentru a se verifica dacă tranziția tj este viabilă, trebuie să se verifice dacă vreun marcaj tj-blocat este accesibil.

În general, totuși, s-ar putea să existe un număr infinit de marcaje tj-blocate și o mulțime infinită de marcaje în care să găsim marcaje tj-blocate. Mulțimea de marcaje care trebuie verificate pentru accesibilitate se reduce la un număr finit cu ajutorul a două proprietăți. În primul rând, dacă un marcaj este tj-blocat, atunci orice marcaj ’ este de asemenea tj-blocat. (Orice secvență de declanșare posibilă din ’ este, de asemenea, posibilă și din , astfel că dacă ’ poate conduce la declanșarea lui tj, același lucru îl poate face și .) În al doilea rând, marcajele anumitor locații nu vor afecta tj-interblocarea unui marcaj, și astfel marcajele din aceste locații sunt “nu-mi pasă”; ele pot fi arbitrare. Împrumutând de la construcția arborelui de accesibilitate, înlocuim aceste componente “nu-mi pasă” cu w pentru a indica faptul că în această locație se poate afla un număr arbitrar de mare de jetoane fără a afecta tj-interblocarea marcajului. Acum, de vreme ce orice ’ este tj-blocat dacă este tj-blocat, nu trebuie să considerăm aceste locații pi cu (pi) = w. Aceasta înseamnă că folosim problema accesibilității submarcajului cu P’ = {pi / (pi) 20}.

Pentru a exemplifica, considerăm rețeaua Petri din figura 5.7. Marcajele (2, 0), (1, 0), (0, 0), (0, 1), (0, 2), (0, 3), . . . sunt tj-blocate, dar ele pot fi finit reprezentate prin mulțimea {(2, 0), (1, 0), (0, 20)}.

Figura 5.7: O rețea Petri Pentru a ilustra marcajele tj-blocate (moarte)

Hack [1974c, 1975c] arată că pentru o rețea Petri C (extinsă pentru a include w) există o mulțime finită de marcaje Dt astfel încât C este activă dacă și numai dacă nici un marcaj din Dt nu este accesibil. Dacă un marcaj din Dt conține w, este implicată accesibilitatea submarcajului.

Mai departe, Dt poate fi efectiv calculată. De vreme ce Dt este finită, componentele diferite de w ale marcajelor au o margine superioară b. Marginea b este caracterizată ca cel mai mic număr astfel încât pentru orice marcaj cu (pi) b + 1 pentru toate pi, dacă este tj-blocat, atunci submarcajul ’, cu ’(pi) = (pi), este tj-blocat dacă (pi) b și ’(pi) = w dacă (pi) = 1 + b. Cu această caracterizare a lui b, vom construi Dt după cum urmează:

Calculez b. Pornesc cu b = 0‚ și îl măresc până când găsesc o valoare a lui b care să satisfacă caracterizarea de mărginire definită mai sus. Testarea pentru b necesită verificarea tuturor celor (b + 2)n marcaje cu componente mai mici sau egale cu b + 1.

Calculez Dt prin testarea tuturor marcajelor și submarcajelor cu componente mai mici sau egale cu b, sau egale cu w. Dt este mulțimea de marcaje tj-blocate din această mulțime de (b + 1)n marcaje.

Odată ce am construit Dt, aplicăm problema accesibilității submarcajului pentru fiecare element al lui Dt. Dacă există un element al lui Dt din marcajul inițial care este accesibil, rețeaua Petri nu este activă; dacă nici un element al lui Dt nu este accesibil, rețeaua Petri este accesibilă.

Din aceste două teoreme avem următoarele:

Teorema 5.7:

Următoarele probleme sunt echivalente.

Problema accesibilității

Problema viabilității

Problema viabilității pentru o singură tranziție.

Demonstrații mai formale ale reducerii viabilității la accesibilitate pot fi găsite în [Hack 1974c; Hack 1975c].

Rezultate nedecidabile

În secțiunea 5.4 am arătat că o serie de probleme de accesibilitate și viabilitate sunt echivalente, dar nu s-a obținut încă nici un rezultat referitor la decidabilitatea acestor probleme. Pentru a arăta decidabilitatea este necesară reducerea unei probleme cu rețele Petri la o problemă pentru care se cunoaște o metodă de soluționare. Pentru a arăta nedecidabilitatea este necesară reducerea unei probleme despre care se știe că este nedecidabilă la o problemă cu rețele Petri. Primul rezultat important de acest gen a fost cel al lui Robin [Baker 1973b]. Robin a arătat că pentru două rețele Petri C1 cu marcajul 1 și C2 cu marcajul 2 nu se poate decide dacă R(C1, 1) R(C2, 2).

Mai târziu Hack [1975a] a întărit acest rezultat arătând că nu se poate decide dacă R(C1, 1) = R(C2, 2). Demonstrația acestor afirmații se bazează pe a zecea problemă a lui Hilbert (în 1900, D. Hilbert a prezentat 23 de probleme la o conferință a matematicienilor, iar aceasta a fost a zecea pe lista sa).

Definiția 5.9:

Dat un polinom P cu n variabile și coeficienți întregi, există un vector (x1, …, xn) de întregi astfel încât P(x1, …, xn) = 0?

Ecuația P(x1, …, xn) = 0 se numește ecuație diofantică. În general, va fi o sumă de termeni:

, .

Ecuațiile diofantice includ x1 = 0, 3x1x2 + 6×3 = 0, și așa mai departe.

În 1970, Matijasevic a demonstrat că a zecea problemă a lui Hilbert era nedecidabilă [Davis 1973; David și Hersh 1973]. Nu există un algoritm general pentru a determina dacă o ecuație diofantică arbitrară are o rădăcină (o mulțime de valori pentru care polinomul este zero). Acest lucru a stat la baza demonstrației faptului că problema egalității pentru mulțimi de accesibilitate pentru rețele Petri este nedecidabilă. Strategia este de a construi pentru un polinom diofantic o rețea Petri care (într-un sens) calculează toate valorile polinomului.

Problema incluziunii grafurilor polinomiale

Demonstrația nedecidabilității problemei egalității se face în trei pași (figura 5.8). Mai întâi, a zecea problemă a lui Hilbert este redusă la problema incluziunii grafurilor polinomiale. Apoi, problema incluziunii grafurilor polinomiale este redusă la problema submulțimii pentru mulțimi de accesibilitate ele rețelelor Petri. În cele din urmă, problema submulțimii pentru mulțimi de accesibilitate ele rețelelor Petri este redusă la problema egalității pentru mulțimi de accesibilitate ele rețelelor Petri. Aceasta arată că a zecea problemă a lui Hilbert, despre care se știe că este nedecidabilă, este reductibilă la problema egalității, despre care tragem astfel concluzia că este tot nedecidabilă.

Problema a zecea a lui Hilbert

Problema incluziunii grafurilor polinomiale

Problema submulțimii pentru mulțimi de accesibilitate pentru rețele Petri

Problema egalității pentru mulțimi de accesibilitate pentru rețele Petri

Figura 5.8: Reduceri arătând că problemele egalității (și a submulțimii) pentru mulțimi de accesibilitate pentru rețele Petri sunt nedecidabile

Definiția 5.10:

Graful G(P) al unui polinom diofantic P(x1, …, xn) cu coeficienți nenegativi este mulțimea:

G(P) = { (x1, …, xn, J) / J P(x1, …, xn) cu 0 x1, …, xn}.

Definiția 5.11:

Problema incluziunii grafurilor polinomiale este de a determina pentru polinoamele A și B dacă G(A) G(B).

Arătăm mai întâi că a zecea problemă a lui Hilbert se reduce la problema incluziunii grafurilor polinomiale. Aceasta va demonstra următoarele.

Teorema 5.8:

Problema incluziunii grafurilor polinomiale este nedecidabilă.

Demonstrație:

Reducem demonstrația noastră la probleme cu soluții nenegative. Dacă (x1,…, xn) este o soluție pentru P(x1,…, xn) = 0, cu xi < 0, atunci (x1,…, -xi,…, xn) este soluție pentru P(x1,…, -xi,…, xn) = 0. Astfel, pentru a determina soluția unui polinom arbitrar, trebuie doar să testăm fiecare dintre cele 2n polinoame care rezultă din schimbarea semnului unei submulțimi de variabile pentru soluțiile nenegative.

Similar, de vreme ce P2(x1,…,xn) = 0 dacă și numai dacă P(x1,…,xn) = 0, avem nevoie să considerăm numai polinoamele unde valoarea este nenegativă.

Acum putem separa orice polinom P(x1,…,xn) în două polinoame Q1(x1,…,xn) și Q2(x1,…,xn) astfel încât P(x1,…,xn) = Q1(x1,…,xn) – Q2(x1,…,xn) punând toți termenii cu coeficienți pozitivi în Q1 și toți termenii cu coeficienți negativi în Q2. Deoarece P(x1,…,xn) 0 (conform punctului (2) de mai sus), avem Q1(x1,…,xn) Q2(x1,…,xn) și P(x1,…,xn) = 0 dacă și numai dacă Q1(x1,…,xn) = Q2(x1,…,xn).

Considerăm două grafuri polinomiale:

G(Q1) = {(x1,…,xn, y) / y Q1(x1,…,xn)}

G(1 + Q2) = {(x1,…,xn, y) / y 1 + Q2(x1,…,xn)}

Acum, G(1 + Q2) G (Q1) dacă și numai dacă pentru toate x1,…, xn nenegative și y, y 1 + Q2(x1, …,xn) implică y Q1(x1, …,xn). Această relație este adevărată dacă și numai dacă nu există x1,…,xn și z astfel încât Q1(x1, …,xn) < y 1 + Q2(x1, …,xn).

Dar, din punctul (3) de mai sus Q1 Q2, astfel încât

Q1(x1, …,xn) < y 1 + Q2(x1, …,xn) 1 + Q1(x1, …,xn) și, deoarece toți cuantificatorii sunt întregi, y = 1 + Q2(x1,…,xn) =1 + Q1(x1,…,xn) este adevărată dacă și numai dacă Q1 = Q2. Astfel, vedem că G(Q2 + 1) G(Q1) dacă și numai dacă nu există x1, …, xn astfel încât Q1(x1, …,xn) = Q2(x1, …,xn), adică nu există x1, …, xn astfel încât P(x1, …,xn) = 0.

De aceea, pentru a determina că ecuația P(x1, …,xn) = 0 are o soluție, trebuie să arătăm numai că nu suntem în cazul în care G(Q2 + 1) G(Q1).

Calcule slabe (weak computation)

Acum avem nevoie să arătăm că rețelele Petri pot calcula (într-un sens) valoarea unui polinom Q(x1, …, xn). Am mărginit cu atenție polinomul Q astfel încât să aibă o valoare nenegativă, coeficienți nenegativi și variabile nenegative, pentru a putea codifica valorile variabilelor și valoarea polinomului prin numărul de jetoane din locațiile unei rețele Petri. Figura 5.9 arată schema generală. Valorile de intrare x1, …, xn sunt codificate de xi jetoane în pi, pentru i = 1…n. Inițial, se află un jeton și în locația de pornire. Execuția rețelei se va termina prin plasarea unui jeton în locația “quit”(de terminare). În acest moment, locația “de ieșire” va avea y jetoane, unde y Q(x1,…xn).

Figura 5.9: Structura de bază a unei rețele Petri pentru a calcula slab valoarea polinomului Q(x1, …xn)

Această rețea Petri va calcula slab valoarea Q(x1, …xn). Calcul slab înseamnă că deși valoarea calculată nu va depăși Q(x1, …xn), ea poate fi orice valoare nenegativă mai mică decât Q(x1, …xn). Acest tip de calcul este necesar pentru rețelele Petri datorită naturii permisive a declanșărilor de tranziții; o rețea Petri nu poate fi forțată să se încheie. Definiția unui graf polinomial G(Q) a fost dată ținând cont de acest aspect.

Vom arăta acum că pot fi construite subrețele care calculează slab funcția de înmulțire (binară). De aici, vom putea construi o rețea compusă care să calculeze slab valoarea fiecărui termen al unui polinom prin subrețele succesive de înmulțire. Ieșirea din fiecare subrețea corespunzătoare unui termen va fi depozitată în locația de ieșire pentru polinom. Astfel, numărul de jetoane din locația de ieșire va fi suma ieșirilor pentru fiecare termen.

Subrețeaua de înmulțire este cea în figura 5.10.

Figura 5.10: O subrețea pentru înmulțire. Această subrețea calculează slab produsul dintre x și y

Această rețea va calcula slab produsul numerelor, x și y, de jetoane din cele două locații de intrare și va plasa tot atâtea jetoane în locația de ieșire. Funcționarea rețelei este simplă. Pentru a calcula produsul dintre x și y, se declanșează mai întâi tranziția t1, mutând un jeton din px în p2. Acest jeton activează tranziția t3, care poate acum să copieze y jetoane din poziția py, punându-le în p3, și punând y jetoane în poziția pxy de ieșire. Acum se poate declanșa tranziția t2, ce pune jetonul din p2 înapoi în p1. Se activează astfel tranziția t1, care poate copia cele y jetoane din p3 înapoi în py. Acest întreg proces poate fi repetat de exact x ori, de fiecare dată punându-se y jetoane în pxy. Apoi, marcajul locației px este redus la zero și rețeaua trebuie să se oprească. Numărul total de jetoane din locația pxy este produsul dintre x și y.

Cazul de mai sus surprinde situația cea mai bună, în sensul că numărul de jetoane din locația de ieșire este exact xy. Totuși, jetoanele din locația p2 activează atât tranziția t3 cât și tranziția t2, și este posibil ca t2 să se declanșeze înainte ca toate cele y jetoane să fie copiate din py în p3 și să fie adăugate la pxy. În acest caz, numărul de jetoane depozitate în pxy va fi mai mic decât xy. Deoarece t3 se poate declanșa de maximum y ori pentru fiecare declanșare a lui t1 și t1 se poate declanșa de maximum x ori, putem fi siguri că numărul de jetoane din pxy nu depășește niciodată xy, dar, datorită naturii permisive a declanșării tranzițiilor, nu putem fi siguri că numărul de jetoane din pxy va fi exact xy; s-ar putea să fie mai mic. Astfel, această rețea Petri calculează slab produsul dintre x și y. Acum, pentru a calcula slab un termen Ri care este produsul construim o rețea Petri de forma celei din figura 5.11. Deoarece fiecare subrețea calculează slab produsul a doi termeni, întreaga subrețea calculează slab valoarea termenului Ri.

Figura 5.11: O structură de rețea Petri pentru a calcula slab un termen al unui polinom diofantic. Fiecare dreptunghi este o rețea de forma celei din figura 5.10.

În acest caz, figura 5.12 arată cum poate fi calculat slab un polinom P = R1 + … + Rk. Fiecare subrețea este de forma arătată în figura 5.11 și calculează slab valoarea unui termen. Ieșirile celor k subrețele pentru fiecare termen au fost unite dând o valoare totală care este suma tuturor termenilor.

Pentru a crea mulțimile de accesibilitate specifice necesare sunt adăugate tranziții și locații de control. Mai întâi trebuie să putem produce o valoare arbitrară pentru fiecare din variabilele x1,…,xn și să înregistrăm această valoare în locațiile p1,…,pn.

Pentru fiecare pi este creată o tranziție ti cu intrare nulă și ieșire prin pi astfel încât fiecare locație care este o intrare corespunde lui xi într-un termen Rj care folosește xi.

De aceea, în polinomul x1 + x1x2 vom avea o tranziție t1 cu ieșiri în p1 și la cele t1 intrări ale celor doi termeni x1 și x1x2 care folosesc x1; t2 va ieși în p2 și la cele x2 intrări ale termenului x1x2.

Figura 5.12: O rețea Petri pentru a calcula slab P(x1,…, xn) folosind o colecție de subrețele de forma celor din figura 5.11

Aceste tranziții pot să se declanșeze de un număr arbitrar de ori, creând orice valoare în p1,…,pn. Astfel, pentru fiecare y P(x1, …,xn) este accesibil un marcaj cu (p1) = x1, …, (pn) = xn și (ieșire) = y. Valoarea y = P(x1, …,xn) poate fi atinsă declanșând mai întâi t1 de x1 ori, punând x1 jetoane în p1, apoi declanșând t2 de x2 ori, și așa mai departe până când tn se declanșează de xn ori. Subrețeaua pentru fiecare termen Ri al polinomului se poate apoi executa, cu valoarea rezultată pentru polinom pusă în locația de ieșire.

Pentru a reduce problema incluziunii grafurilor polinomiale la problema submulțimii pentru mulțimi de accesibilitate pentru rețele Petri efectuăm următorii pași. Pentru polinoamele A și B, dorim să determinăm dacă G(A) G(B).

Construim rețeaua Petri CA care calculează slab A(x1, …,xn) și rețeaua Petri CB care calculează slab B(x1, …,xn).

Dacă numărul de locații din cele două rețele nu este egal, adăugăm locații în cea care are mai puține pentru a egaliza numărul de locații. Aceste locații sunt inițial nemarcate și nu sunt folosite de nici una din tranzițiile din rețea.

Acum trebuie să eliminăm efectele tuturor locațiilor interne mulțimilor de accesibilitate. Se pune în evidență o mulțime de n + 1 locații în fiecare dintre rețelele CA și CB, locațiile corespunzătoare valorilor x1, …,xn și ieșirea pentru fiecare rețea. Toate celelalte locații sunt locații interne, ale căror marcaje nu sunt importante. Totuși, putem găsi că pentru o locație internă pi din CA și corespunzător din CB există un marcaj din R(CA, A) diferit de marcajul ’ din R(CB, B), deoarece (pi) ’’ (pi) pentru toate ’’ din R(CB, B).

Pentru a preveni această problemă adăugăm la CA două noi locații, q și r, (rezultând ), și la CB alte două locații, q’ și r’, (rezultând ). În , q și r nu sunt folosite pentru nici o tranziție, și inițial r este goală iar q este marcată cu un jeton. În , r’ este o locație de pornire care este inițial marcată. Fiecare tranziție din este modificată pentru a include r’ atât ca intrare cât și ca ieșire. Astfel, atâta timp cât jetonul rămâne în r’, rețeaua poate funcționa ca înainte. O nouă tranziție transferă jetonul de activare de la r’ la q’, dezactivând toate tranzițiile din și “înghețând” marcajul. Acum adăugăm două noi tranziții pentru fiecare locație internă din .

Pentru fiecare locație internă pi unde marcajul este neimportant, o tranziție are locațiile p’ și pi ca intrări și numai pe q’ ca ieșire (permițând marcajului din pi să fie decrementat cu 1), și o altă tranziție are q’ ca intrare și atât q’ cât și pi ca ieșiri (permițând marcajului din pi să fie incrementat cu 1). Aceste tranziții permit ca marcajul fiecărei locații interne să fie atins arbitrar de către o secvență potrivită de declanșări ce incrementează sau decrementează.

Noua construcție este ilustrată în figura 5.13. Pentru aceste două rețele Petri, și cu marcajele inițiale , respectiv , G(A) G(B) dacă și numai dacă R(,) R(, ). Mulțimile de accesibilitate ale lui și sunt după cum urmează.

Pentru :

Pentru :

Astfel, dacă G(A) G(B), atunci R(,) R(, ) și reciproc, dacă R(,) R(, ) atunci G(A) G(B).

Astfel se încheie demonstrația pentru următorul rezultat:

Teorema 5.9:

Problema incluziunii grafurilor polinomiale este reductibilă la problema submulțimii pentru mulțimi de accesibilitate pentru rețele Petri.

Demonstrația acestei teoreme a fost luată din [Hack 1975a, Hack 1975c].

Figura 5.13: Rețeaua Petri construită pentru a testa incluziunea grafurilor polinomiale

Problema egalității

Mai avem acum de arătat doar că problema submulțimii pentru mulțimi de accesibilitate pentru rețele Petri se reduce la problema egalității.

Presupunem că avem două rețele Petri A și B și dorim să determinăm dacă R(A, A) R(B, B) (problema submulțimii). Arătăm că două rețele Petri D și E pot fi definite astfel încât R(A, A) R(B, B) dacă și numai dacă R(D, D) = R(E, E). Ne bazăm în această demonstrație pe următorul rezultat: R(A, A) R(B, B) dacă și numai dacă R(B, B) = R(A, A) R(B, B). Atât D cât și E sunt construite dintr-o subrețea comună, C. Rețeaua C codifică mulțimile de accesibilitate ale rețelelor A și B astfel încât să producă uniunea lor. Figura 5.14 ilustrează construcția de bază. Cele n locații p1, …,pn se comportă fie ca n locații ale rețelei A, fie ca n locații ale rețelei B. Inițial ele sunt nemarcate. Se adaugă două noi locații, rA și rB, ca locații de pornire pentru rețeaua A, respectiv pentru rețeaua B. Toate tranzițiile rețelei A sunt modificate pentru a include rA atât ca intrare cât și ca ieșire, și, de asemenea, toate tranzițiile rețelei B sunt modificate pentru a include rB atât ca intrare cât și ca ieșire.

Figura 5.14: Construcția rețelelor Petri C, D și E din A și B. Această construcție este folosită pentru a arăta că problema submulțimii se reduce la problema egalității pentru mulțimi de accesibilitate.

Se adăugă încă o locație, s, și două noi tranziții, tA și tB. Marcajul inițial pentru această întreagă rețea (incluzând A și B ca subrețele cu locații comune, locațiile rA, rB și s și tranzițiile tA și tB) este format dintr-un jeton în s și zero jetoane oriunde altundeva.

Tranziția tA are locația s ca intrare și produce la ieșire marcajul inițial pentru rețeaua A plus un jeton în rA; tranziția tB are locația s ca intrare și produce la ieșire marcajul inițial pentru rețeaua B plus un jeton în rB. Astfel, dacă se declanșează tA, subrețeaua A are marcajul său inițial, și oricare dintre tranzacțiile sale se poate declanșa normal de vreme ce în rA se află un jeton. Totuși, subrețeaua B este complet dezactivată, deoarece în rB nu se află nici un jeton. Dacă se declanșează mai întâi tB, atunci subrețeaua B poate funcționa și A este dezactivată. Mulțimea de secvențe care se declanșează pentru C este atunci orice secvență de forma:

tA, <orice secvență de declanșări din A>,

sau orice secvență de forma:

tB, <orice secvență de declanșări din B>.

Rețeaua D este obținută din C prin adăugarea unei noi tranziții qB. Tranziția qB are locația rB ca intrare și nici o ieșire. Observăm că qB se poate declanșa numai dacă tranziția tB s-a declanșat prima; dacă s-a declanșat prima tranziția tA, atunci locația rB este goală și qB nu se poate declanșa.

Rețeaua E este construită din D prin adăugarea unei noi tranziții qA. Tranziția qA are locația rA ca intrare și nici o ieșire. Observăm că qA se poate declanșa numai dacă tranziția tA s-a declanșat prima. Observăm că rețeaua E este construită din D, nu (direct) din C. Astfel, E conține atât tranziția qA cât și tranziția qB.

Acum să examinăm mulțimile de accesibilitate ale rețelelor Petri C, D și E. În mulțimea de accesibilitate a lui C sunt toate marcajele de forma:

Rețeaua Petri D adaugă o altă clasă de marcaje la mulțimea sa de accesibilitate:

Și rețeaua Petri E mai adaugă o clasă la acestea:

Acum, dacă R(A, A) R(B, B), atunci ultima clasă din R(E, E) [marcajele de forma (0, 0, 0, ) cu R(A, A)] este inclusă în ultima clasă din R(D, D) [marcajele de forma (0, 0, 0, ) cu R(B, B)]. De vreme ce toate celelalte marcaje sunt aceleași, R(D, D) = R(E, E) dacă R(A, A) R(B, B).

Similar, dacă R(D, D) = R(E, E), atunci trebuie să avem R(A, A) R(B, B), de vreme ce pentru fiecare marcaj (0, 0, 0, ) cu R(A, A) din R(E, E) trebuie să existe un marcaj egal în R(D, D). Dar, toate marcajele cu (s, rA, rB) = (0, 0, 0) sunt de forma (0, 0, 0, ) cu R(B, B), așa că R(A, A) R(B, B).

Astfel, această construcție conduce la următorul rezultat.

Teorema 5.11:

Următoarele probleme sunt nedecidabile:

Problema incluziunii grafurilor polinomiale

Problema submulțimii pentru mulțimi de accesibilitate pentru rețele Petri

Problema egalității pentru mulțimi de accesibilitate pentru rețele Petri

Aceste teoreme și demonstrațiile aferente se datorează lui Hack [1975a, 1975c].

Complexitatea problemei de accesibilitate

Nedecidabilitatea problemelor submulțimii și egalității pentru mulțimi de accesibilitate pentru rețele Petri creează posibilitatea ca problema accesibilități însăși să fie de asemenea nedecidabilă. Totuși, la acest moment, decidabilitatea (sau nedecidabilitatea) problemei accesibilități este încă o problemă deschisă. În prezent nu există nici un algoritm care să rezolve problema accesibilității, și de asemenea nu există nici o demonstrație a faptului că un astfel de algoritm nu poate să existe.

În 1977, a fost prezentată o “demonstrație” a decidabilității problemei accesibilități la simpozionul ACM de teorie computațională [Sacordate și Tenney 1977]. Totuși, această demonstrație avea câteva scăpări serioase, și încercarea de a le corecta, pentru a produce o demonstrație corectă, a eșuat. Totuși, sentimentul predominant este că problema accesibilității este decidabilă – se crede că există un algoritm și că acesta va fi descoperit în timp.

Presupunând că există un algoritm pentru rezolvarea problemei accesibilității, este foarte probabil ca acesta să fie foarte complex. Întrebarea evidentă este: Dacă există un algoritm pentru rezolvarea problemei accesibilității, cât de complex trebuie să fie? Unele limite ale complexității sale pot fi stabilite fără a se face referință la nici un algoritm specificat.

Lipton [1976] a arătat că orice algoritm pentru a rezolva problema accesibilității va necesita cel puțin o cantitate exponențială (2cn) de spațiu pentru depozitare și o cantitate exponențială de timp. Exponentul (n) este o măsură a dimensiunii problemei și în cazul lui Lipton reflectă numărul de locații și interconectările lor în tranziții.

Lipton a demonstrat că este necesar un spațiu exponențial arătând că poate fi construită o rețea Petri în care o locație se comportă precum un program de numărare a numerelor 0, 1, …, . Reprezentarea acestui fapt în algoritmul problemei accesibilității va necesita cel puțin log2() = 2n biți. La fel de important este că în construcție se folosesc cel mult hn locații (pentru o anumită constantă h).

Demonstrația lui Lipton se bazează pe posibilitatea de a crea o rețea cu numai hn locații care să poată număra până la . Parte din constrângeri rezultă din nevoia de a testa locațiile sale pentru marcajul zero. Desigur, rețelele Petri au fost gândite astfel încât nu există o cale directă de a efectua acest test. Totuși, o tehnică obișnuită folosită cu rețelele Petri pentru a permite testarea pentru marcajul zero este de a folosi două locații p și p’ astfel încât (p) + (p’) să fie o constantă. Dacă știm că (p) + (p’) = k, atunci putem testa dacă (p) este zero testând dacă (p’) are k jetoane; dacă (p’) are k jetoane, atunci (p) are zero jetoane și viceversa. O locație poate fi testată pentru valori diferite de zero folosind-o într-o buclă. Observăm că pentru a menține această abilitate trebuie să menținem natura constantă a lui (p) + (p’); în acest context, rețeaua trebuie să fie conservativă, cel puțin cu respectarea acestor două locații.

Pentru numere k mici, putem testa dacă marcajul unei locații este k considerând locația ca fiind intrare pentru o tranziție de k ori (figura 5.15).

Figura 5.15: Testarea unei locații mărginite pentru un marcaj 0, 1 sau 2. Toate tranzițiile trebuie să păstreze suma marcajelor

Totuși, arcele contribuie la dimensiunea problemei, și de aceea nu putem proceda în acest fel în general. Lipton a arătat că dacă suma constantă a două locații (pk, ) este k, și k este un produs a doi factori întregi mai mici (k = k1k2) care sunt sumele constante a două alte perechi de locații ( și ) și putem testa dacă () = 0 și () = 0, atunci putem testa dacă (pk) = 0. Acest fapt i-a permis lui Lipton să construiască subrețele de genul celor din figura 5.16. Aceste rețele le folosim mai târziu pentru a controla rețelele de înmulțire similar cu modul în care se calculează slab graful polinomial (vezi figura 5.10). Rețeaua testare-pentru-zero permite rețelei Petri să calculeze produsul exact (nu un produs slab care este de obicei mărginit de produsul real).

Figura 5.16: Forma rețelelor Petri pe care le folosește Lipton pentru a construi o rețea mai mare care poate testa o numărătoare mai mare pentru zero

Aceste rețele simple îi permit lui Lipton să construiască o rețea, pentru un n dat, care poate genera exact jetoane într-o locație (p), cu zero jetoane în p’ și posibilitatea de a testa (p) pentru zero. Numărul de locații folosite este de numai n ori un factor constant. Existența unei astfel de rețele Petri arată că problema accesibilității necesită cantități de timp și spațiu cel puțin exponențiale, deci rezolvarea ar fi foarte costisitoare.

Construcția unei rețele Petri care să poată număra până la are, de asemenea, un corolar foarte important. Rețeaua Petri care se construiește este mărginită, de vreme ce numărul de jetoane din orice locație dată nu poate fi mai mare de . Aceasta înseamnă că orice algoritm pentru determinarea limitei (mărginirii) unei rețele Petri trebuie de asemenea să necesite timp și spațiu exponențiale. Astfel, chiar și problemele simple pentru rețele Petri, deși decidabile, pot cere pentru soluționare mari cantități de spațiu și timp.

Ar trebui de amintit că acestea sunt limite inferioare, adică descriu comportamentul algoritmului în cazul cel mai prost. S-ar putea să existe cazul când multe probleme interesante sunt decidabile relativ eficient pentru majoritatea rețelelor Petri. Aceste rezultate de complexitate arată că, chiar dacă un algoritm lucrează foarte bine în majoritatea timpului, există o rețea Petri care necesită mult timp și spațiu pentru analiză.

Știm că problema accesibilității necesită spațiu cel puțin exponențial. S-ar putea să existe cazuri chiar mai proaste decât cazul exponențial. Rackoff [1977] a dezvoltat un algoritm pentru a determina mărginirea în timp exponențial, astfel că problema mărginirii este cunoscută a fi de complexitate exponențială. Totuși, problema accesibilității este cunoscută a fi de complexitate cel puțin exponențială (și s-ar putea chiar să nu fie decidabilă).

Un alt rezultat, al lui Mayr [1977], a arătat că problemele submulțimii și egalității pentru mulțimi de accesibilitate mărginite pentru rețele Petri sunt de complexitate nonprimitive recursive. Aceste rezultate indică faptul că unele probleme pentru rețele Petri, deși decidabile, sunt prea complexe din punct de vedere computațional.

Alte studii

Teoria decidabilității este o parte de început a teoriei computaționale și a fost dezvoltată de către Turing, Kleene, Gödel și Church. Davis [1958] și Minsky [1967] oferă explicații folositoare. Karp [1972] arată cum reducerea poate fi folosită pentru rezultate de decidabilitate și complexitate.

Problema accesibilității a apărut mai întâi în [Karp și Miller 1968] și a fost raportată ca o problemă de cercetare în [Nash 1973]. Rezultate preliminare au fost raportate în [Van Leeuwen 1974, Hopcroft și Pansiot 1976], dar acestea nu sunt generale.

Majoritatea rezultatelor din acest capitol se datorează cercetărilor lui Hack [1974a, c, 1975a, c]. Hack a fost unul dintre cei mai mari cercetători ai problemelor de decizie pentru rețelele Petri. Alți cercetători ai proprietăților deciziei sunt [Araki și Kasami 1976, 1967; Mayr 1977]. Rezultate de complexitate au fost date de către Lipton [1976], Rackoff [1976] și Jones et. al. 1976]. Alte rezultate legate indirect de rețelele Petri au fost date de [Cardoza 1975, Cardoza et. al. 1976].

Limbaje pentru rețele Petri

Discuțiile din capitolele 4 și 5 s-au concentrat pe probleme legate de accesibilitate, lucrând mai ales cu probleme cu marcaje accesibile. O abordare înrudită, dar complet diferită este să ne concentrăm nu pe ce marcaje sunt accesibile, ci cum ajungem la ele. Primul obiect de interes este astfel tranziția, și în particular secvențele de tranziții care ne conduc de la un marcaj la altul într-o rețea Petri.

O secvență de tranziții este un șir, iar o mulțime de șiruri formează un limbaj. Astfel, în acest capitol, ne vom concentra asupra limbajelor definite de rețelele Petri și asupra proprietăților acestora.

Motivație

Rețelele Petri au fost dezvoltate pentru două scopuri majore:

descrierea sistemelor propuse sau existente

analiza sistemelor care pot fi modelate printr-o descriere de rețea Petri.

Analiza unei rețele Petri încearcă să determine proprietățile rețelei și pe cele ale sistemului pe care-l modelează. Una din cele mai importante proprietăți ale unui sistem este mulțimea de acțiuni care pot apărea. Mulțimea tuturor secvențelor posibile de acțiuni caracterizează sistemul.

Într-o rețea Petri, acțiunile sunt modelate prin tranziții și apariția unei acțiuni este modelată prin declanșarea unei tranziții. Secvențele de acțiuni sunt modelate prin secvențe de tranziții. Astfel, mulțimea secvențelor de tranziții permise caracterizează o rețea Petri și (în măsura în care rețeaua Petri modelează corect un sistem) sistemul modelat.

Aceste secvențe de tranziții pot fi de maximă importanță în folosirea rețelelor Petri. Să presupunem că a fost proiectat un nou sistem pentru a înlocui unul existent. Comportamentul noului sistem este identic cu al vechiului sistem (dar noul sistem este mai ieftin, mai rapid, mai ușor de reparat, etc.). Dacă ambele sisteme sunt modelate ca rețele Petri, atunci, deoarece comportamentele acestor două rețele sunt identice, și limbajele lor ar trebui să fie egale. Două rețele Petri sunt echivalente dacă limbajele lor sunt egale. Astfel se asigură o bază fermă pentru stabilirea echivalenței a două sisteme.

O situație particulară în care echivalența este importantă este optimizarea. Optimizarea unei rețele Petri presupune crearea unei noi rețele Petri echivalente (limbajele sunt egale), dar care este “mai bună” decât cea veche (într-un anume sens). De exemplu, dacă o rețea Petri va fi direct implementată pe componenta hard, atunci o rețea Petri cu mai puține locații, tranziții și arce va fi mai ieftină de construit, de vreme ce are mai puține componente. Astfel, o problemă de optimizare poate să reducă |P| + |T| fără să se schimbe comportamentul rețelei.

Din motive de optimizare, s-ar putea să fie utilă o mulțime de transformări care conservă limbajul. Dacă o transformare aplicată unei rețele Petri produce o nouă rețea Petri cu același limbaj, atunci aceasta este o rețea cu conservarea limbajului. O rețea Petri optimă poate fi produsă prin aplicarea de transformări care conservă limbajul unei rețele Petri care nu este optimă. Prin urmare, folosirea practică a unui sistem a cărui modelare și analiză se bazează pe o rețea Petri va necesita o colecție de transformări care conservă limbajul.

Limbajele rețelelor Petri pot de asemenea să fie utile pentru analiza rețelelor Petri. În capitolul 4 s-au dezvoltat tehnici pentru determinarea de proprietăți specifice ale rețelelor Petri, precum siguranța, mărginirea, conservativitatea, viabilitatea, accesibilitatea, acoperabilitatea. Deși aceste proprietăți sunt importante (și greu de stabilit), ele nu sunt singurele proprietăți care trebuiesc de analizat la o rețea Petri. S-ar putea să fie necesar de stabilit corectitudinea modelării unui sistem arătând că proprietățile specifice sistemului sunt satisfăcute. Pentru aceasta trebuie de dezvoltat fie noi tehnici pentru fiecare nouă proprietate, fie o tehnică generală de analiză pentru rețelele Petri.

O clasă largă de întrebări poate fi pusă în termeni de secvențe de acțiuni care sunt posibile în sistem. Dacă definim mulțimea de secvențe de acțiuni posibile în sistem ca fiind limbajul sistemului, atunci putem analiza sistemul analizând limbajul sistemului. Aceasta ne poate oferi o tehnică generală de analiză a proprietăților specifice sistemului pentru sisteme arbitrare. Riddle [1972] a investigat analizele bazate pe limbajul sistemului modelat.

O altă utilizare a limbajelor rețelelor Petri ar fi în specificarea și sinteza automată a rețelelor Petri. Dacă comportamentul care este dorit poate fi specificat ca limbaj, atunci este posibil să se sintetizeze automat o rețea Petri al cărei limbaj este limbajul specificat. Această rețea Petri poate fi folosită ca un controlor, garantând că sunt posibile toate secvențele specificate și numai acestea. Ambele expresii [Lauer și Campbell 1974] au fost dezvoltate pentru a defini secvențele de acțiuni posibile. Au fost dezvoltate tehnici pentru a crea automat o rețea Petri pornind de la o expresie dată.

O altă motivație pentru studiul limbajelor rețelelor Petri vine din dorința de a determina rezultate de decidabilitate pentru rețele Petri. Decidabilitatea multor proprietăți ale rețelelor Petri este necunoscută. Decidabilitatea câtorva întrebări de bază asupra rețelelor Petri, precum accesibilitatea, face obiectul multor studii curente. O zonă în care întrebările asupra decidabilității au fost considerate este teoria limbajelor formale. Considerând limbajele rețelelor Petri, pot fi folosite concepte și tehnici ale teoriei limbajelor formale pentru probleme legate de rețele Petri. Astfel se pot produce noi rezultate privitoare la rețelele Petri și întrebările de decidabilitate aferente. Este de asemenea posibilă folosirea de metode din teoria rețelelor Petri pentru a obține noi rezultate folositoare, referitoare la limbajele formale.

Concepte înrudite din teoria limbajelor formale

Teoria referitoare la rețelele Petri care s-a dezvoltat până acum este similară cu dezvoltarea altor părți din teoria limbajelor formale. Câteva cărți prezintă teoria clasică a limbajelor formale [Hopcroft și Ullman 1969, Saloma 1993, Ginsburg 1966]. Multe dintre conceptele fundamentale din teoria limbajelor rețelelor Petri au fost împrumutate din teoria clasică a limbajelor formale.

Un alfabet este o mulțime finită de simboluri. Un șir este orice secvență de lungime finită de simboluri din alfabet. Șirul vid (nul) este șirul cu nici un simbol și de lungime zero. Dacă este un alfabet, atunci * este mulțimea tuturor șirurilor de simboluri din , inclusiv șirul vid. + este mulțimea tuturor șirurilor nevide peste alfabetul .

* = + {}.

Un limbaj este o mulțime de cuvinte peste un alfabet. Limbajele pot fi în general infinite, și de aceea reprezentarea limbajului poate fi o problemă. S-au dezvoltat două abordări pentru reprezentarea limbajelor. O abordare este să se definească un automat care atunci când generează un cuvânt dintr-un limbaj, să genereze simultan toate cuvintele limbajului. Alternativ, se poate defini o gramatică care specifică cum să se genereze un șir dintr-un limbaj prin aplicări succesive ale producțiilor gramaticii.

Restricțiile asupra formei automatelor și gramaticilor care generează limbajele definesc clase de limbaje. Clasele de limbaje tradiționale sunt: limbaje regulate (regular), independente de context (context-fee), dependente de context (context-sensitive) și limbaje de tip 0, corespunzând la automate, automate push-down, automate liniare finite respectiv mașini Turing. Fiecare dintre aceste clase de limbaje este generată de clasa de automate corespunzătoare. Acest fapt conferă un excelent sens legăturii dintre teoria rețelelor Petri și teoria limbajelor formale: definim clasa limbajelor rețelelor Petri ca fiind acea clasă de limbaje generată de rețele Petri. Detaliile definiției trebuie să fie similare cu detaliile pentru oricare dintre celelalte clase de limbaje.

Pentru exemplificare, să considerăm automatul cu stări finite. Un automat cu stări finite C este un 5-uplu (Q, , , s, F), unde Q este o mulțime finită de stări, este un alfabet de simboluri, : Q x Q este o funcție de tranziție, s Q este starea inițială și F Q este o mulțime finită de stări finale. Funcția de tranziție este extinsă în mod natural la o funcție de la Q x * la Q. Limbajul L(C) generat de automatul cu stări finite este mulțimea de șiruri peste definită prin L(C) = { * / (s,) F}.

Fiecărui automat cu stări finite i se asociază un limbaj și clasa tuturor limbajelor care pot fi generate de automate cu stări finite formează clasa limbajelor regulate. Limbajul unui automat cu stări finite este o trăsătură caracteristică a automatului. Dacă două automate cu stări finite au același limbaj, atunci ele sunt echivalente.

Definiția limbajelor rețelelor Petri

Aceleași concepte fundamentale folosite de un automat cu stări finite pentru a produce un limbaj regulat pot fi aplicate rețelelor Petri pentru a produce o teorie a limbajelor rețelelor Petri. În plus față de structura de rețea Petri definită de mulțimile de locații și tranziții (care corespund în general mulțimii stărilor și funcției de tranziție a automatului cu stări finite) este necesar să definim o stare inițială, un alfabet și o mulțime de stări finale. Specificarea acestor trăsături pentru o rețea Petri poate da naștere la diferite clase de limbaje pentru rețele Petri. Vom considera pe rând fiecare dintre aceste clase.

Starea inițială

Starea inițială a unei rețele Petri poate fi definită în mai multe feluri. Cea mai comună definiție este să se permită unui marcaj inițial să fie specificat drept stare inițială. Totuși, această definiție poate fi modificată în câteva moduri. O limitare convenabilă este să restricționăm starea inițială la un marcaj cu un jeton într-o locație de pornire și zero jetoane oriunde altundeva [Peterson 1976]. O altă definiție mai generală acceptă o mulțime de marcaje inițiale mai degrabă decât un singur marcaj.

Aceste trei definiți spun în esență același lucru. Desigur, definiția locației de pornire este un caz special al definiției marcajului inițial, care este un caz special al definiției mulțimii de marcaje inițiale. Totuși, dacă o mulțime M = {1, …,k} de marcaje inițiale este necesară cu o definiție a locației de pornire, putem pur și simplu să îmbogățim rețeaua Petri cu o locație suplimentară p0 și o mulțime de tranziții . Tranziția va avea ca intrare un jeton din p0 și ca ieșire marcajul j. Astfel, comportamentul rețelei îmbogățite va fi identic cu cel al unei rețele Petri cu o mulțime de marcaje inițiale, exceptând faptul că fiecare secvență de tranziții va fi precedată de dacă pentru începerea execuției a fost folosit marcajul j.

Vedem astfel că aceste trei definiții ale stărilor inițiale pentru o rețea Petri sunt în esență echivalente. Fără a respecta trandiția, definim un limbaj al unei rețele Petri ca începând dintr-un marcaj simplu arbitrar .

Etichetarea rețelelor Petri

Pentru noțiunea de etichetare a rețelelor Petri există de asemenea mai multe definiții. Trebuie să definim ce ar trebui să fie alfabetul al unei rețele Petri și cum se asociază acesteia. Am indicat că simbolurile sunt asociate cu tranzițiile, astfel încât o secvență de tranziții ce se declanșează generează un șir de simboluri pentru limbaj. Asocierea simbolurilor la tranziții se face cu o funcție de etichetare : T . Variațiile în definiția limbajului pot rezulta din diferite restricții asupra funcției de etichetare.

O rețea Petri liber etichetată (free-labeled) este o rețea Petri unde toate tranzițiile sunt etichetate distinct [i.e., dacă (tj) = (ti), atunci ti = tj]. Clasa limbajelor de rețele Petri liber etichetate este o submulțime a clasei rețelelor Petri cu o funcție de etichetare mai generală care nu cere etichete distincte.

A fost considerată o funcție de etichetare chiar mai generală care admite tranziții cu etichetă nulă, (tj) = . Aceste tranziții -etichetate nu apar într-o propoziție a unui limbaj Petri și de aceea apariția lor în execuția unei rețele Petri trece neînregistrată. Aceste trei clase de funcții de etichetare (libere, -libere și cu -tranziții) definesc trei variante de limbaje pentru rețele Petri.

Fără investigări ulterioare, nu este evident care dintre aceste trei definiții de funcții de etichetare este cea mai rezonabilă. Probabil fiecare dintre cele trei este funcția de etichetare cea mai folositoare pentru anumite aplicații. De aceea, va trebui să considerăm limbajele rezultate din fiecare definiție posibilă a funcției de etichetare.

Stările finale ale unei rețele Petri

Definiția stărilor finale pentru o rețea Petri are un efect major asupra limbajului unei rețele Petri. Au fost sugerate patru definiții complet diferite ale mulțimii stărilor finale ale unei rețele Petri. Fiecare dintre acestea poate produce limbaje diferite pentru rețele Petri.

O definiție este derivată din conceptul analog pentru automate cu stări finite. Se definește mulțimea stărilor finale F ca o mulțime finită de marcaje finale. Pentru această definiție definim clasa de limbaje pentru rețele Petri de tipul L.

Definiția 6.1:

Un limbaj L este un limbaj pentru rețele Petri de tipul L dacă există o structură (P, T, I, O) de rețea Petri , o etichetare a tranzițiilor :T , un marcaj inițial și o mulțime finită F de marcaje finale astfel încât L = {() * / T* și (, ) F}.

Clasa de limbaje pentru rețele Petri de tipul L este bogată și puternică, dar s-a sugerat că cerința pentru ca un cuvânt să rezulte în exact o stare finală în scopul de a fi generat este contrară filozofiei inițiale a rețelelor Petri. Acest comentariu se bazează pe observația că dacă (, tj) este definită pentru un marcaj și o tranziție tj, atunci (’, tj) este definită pentru orice ’ . Din acest comentariu definim o nouă clasă de limbaje, clasa de limbaje pentru rețele Petri de tipul G, după cum urmează.

Definiția 6.2:

Un limbaj L este un limbaj pentru rețele Petri de tipul G dacă există o structură (P, T, I, O) de rețea Petri, o funcție de etichetare :T , marcajul și o mulțime finită F de marcaje finale astfel încât L = {() * / T* și există f F astfel încât (, ) f}.

O a treia clasă de limbaje pentru rețele Petri este clasa de limbaje pentru rețele Petri de tipul T. Ele sunt definite identificând mulțimea de stări finale folosită în definiția limbajelor de tipul L cu mulțimea (nu neapărat finită) a stărilor terminale. O stare t este terminală dacă (t, tj) nu este definită pentru nici un tj T. Astfel, clasa limbajelor pentru rețele Petri de tipul T este după cum urmează.

Definiția 6.3:

Un limbaj L este limbaj pentru rețele Petri de tipul T dacă există o structură (P, T, I, O) de rețea Petri, o funcție de etichetare : T și un marcaj inițial astfel încât L = {() * / T* și (, ) este definită, dar ((, ), tj) nu este definită pentru nici un tj T}.

Încă o a patra clasă de limbaje este clasa limbajelor pentru rețele Petri de tipul P a căror mulțime de stări finale include toate stările accesibile. Aceste limbaje au proprietatea prefixului de vreme ce dacă * este un element al unui limbaj de tipul P, atunci toate prefixele ale lui ( = x pentru unii x *) sunt elemente ale aceluiași limbaj.

Definiția 6.4:

Un limbaj L este limbaj pentru rețele Petri de tipul P dacă există o structură (P, T, I, O) de rețea Petri, o funcție de etichetare : T și un marcaj inițial astfel încât L = {() * / T* și (, ) este definită}.

Clase de limbaje pentru rețele Petri

În plus față de cele patru clase de limbaje bazate pe specificațiile diferite ale mulțimii stărilor finale, am menționat anterior variații datorate funcției de etichetare. În figura 6.1 există cele 12 clase de limbaje care rezultă din produsul direct al celor patru tipuri de specificări ale stărilor finale cu cele trei tipuri de funcții de etichetare. În fiecare celulă din figura 6.1 se află notația care este folosită pentru referirea la fiecare clasă de limbaje ale rețelelor Petri.

Figura 6.1: Cele 12 clase de limbaje pentru rețelele Petri

Pentru a specifica un limbaj anume pentru rețelele Petri, trebuie definite patru cantități: structura de rețea Petri C = (P, T, I, O); funcția de etichetare : T *; marcajul inițial : P N și mulțimea de marcaje finale F (pentru limbajele de tip L și G). Definim = (C, , , F) ca fiind o rețea Petri etichetată cu structura de rețea Petri C, funcția de etichetare , marcajul inițial și mulțimea stărilor finale F. Pentru o rețea Petri etichetată , pot fi definite 12 limbaje: L(), G(), T(), P(), Lt(), Gt(), Tt(), Pt(), L(), G(), T() și P().

Diferitele definiții ale limbajelor rețelelor Petri pot asocia limbaje diferite la o rețea Petri dată. Să considerăm, spre exemplu, rețeaua Petri din figura 6.2.

Figura 6.2: Un exemplu de rețea Petri pentru a ilustra diferitele clase de limbaje. Fiecare tranziție este etichetată cu eticheta sa.

Marcajul inițial (1, 0, 0, 0) este dat pe rețea și fiecare tranziție tj este etichetată cu (tj). Dacă definim F = {(0, 0, 1, 0)} (un jeton în locația p3), limbajul de tipul L este {ancbn / n 0}, limbajul de tipul G este {amcbn / m n 0}, limbajul de tipul T este {amcbnd / m n 0} și limbajul de tipul P este {am / m 0} {amcbn / m n 0} {amcbnd / m n 0}. Pentru acest exemplu, toate cele patru tipuri de limbaje sunt diferite. Funcția de etichetare dată este o funcție de etichetare liberă, dar prin folosirea diferitelor funcții de etichetare, pot fi produse, de asemenea, alte limbaje.

În ciuda diferențelor între definiții, clasele de limbaje pentru rețele Petri sunt mult înrudite. De exemplu, mulțimea de etichete libere este o submulțime a mulțimii de etichete non-, care este o submulțime a mulțimii de -etichete. Astfel, Lt L L, Gt G G, Tt T T și Pt P P. De asemenea, fiecare limbaj de tip P este un limbaj de tip G unde F = {(0, 0,…, 0)}. Astfel: Pt Gt, P G și P G.

Putem de asemenea arăta că fiecare limbaj de tip G sau G este de asemenea un limbaj de tip L respectiv L. Fie G un limbaj de tip G pentru o structură de rețea Petri (P, T, I, O), cu marcajul inițial și mulțimea stărilor finale F.

Construim o nouă rețea Petri etichetată cu aceleași locații, dar cu tranziții suplimentare, după cum se arată în următoarele.

Pentru fiecare tj T, fie Bj mulțimea tuturor submultiseturilor corecte ale O(tj). Fiecare submultiset din Bj este folosit pentru a defini o nouă tranziție cu aceeași etichetă și intrări ca și tj, dar cu submultisetul drept ieșire. Aceste noi tranziții le adăugăm la mulțimea anterioară de tranziții. De exemplu, dacă considerăm tranziția etichetată cu a din rețeaua Petri din figura 6.2, multisetul său de intrare este {p1}, iar cel de ieșire {p1, p2}. Submultiseturile lui {p1, p2} sunt {p1}, {p2} și {} (= ). Această tranziție va da naștere altor trei noi tranziții care se vor adăuga la rețea. Toate aceste trei tranziții vor fi etichetate cu a și vor avea ca intrare multisetul {p1}, dar multiseturile de ieșire vor fi cele trei subcategorii enumerate mai sus (o tranziție pentru fiecare subcategorie). Vor fi de asemenea adăugate noi tranziții pentru tranzițiile etichetate cu b, c, și d, care vor avea aceleași intrări, dar ieșiri nule (vide) (deoarece ieșirile curente sunt multiseturi singleton și de aceea singurul submultiset este ). Această nouă rețea este ilustrată în figura 6.3.

Figura 6.3: O rețea Petri al cărei limbaj de tip L este același cu limbajul de tip G al rețelei Petri din figura 6.2

Această nouă rețea a fost modificată astfel încât jetoanele suplimentare care depășesc o stare finală din F nu mai trebuie produse, dacă unul selectează noua tranziție care are mai puține ieșiri. Astfel, limbajul de tipul L al noii rețele este același cu limbajul de tipul G al vechii rețele.

Această construcție impune crearea de noi tranziții, astfel încât nu poate fi trasă nici o concluzie despre relația dintre Gt și Lt. Dar, G L, G L.

Construcția de mai sus poate fi, de asemenea, ușor modificată pentru a arăta că o generalizare a definiției limbajelor de tipul L (pentru a permite marcaje finale cu specificare incompletă) nu schimbă clasele L și L. Fie un marcaj final pentru o rețea Petri cu n locații un n-vector peste H {w}. Dacă o componentă a unui marcaj final este w, aceasta înseamnă că nu ne interesează care este valoarea acestei componente într-o stare finală. O stare s este stare finală dacă există un marcaj final f astfel încât pentru toți i, i = 1…n, dacă fi w atunci si = fi. Aceasta este evident o definiție mai generală decât definiția limbajelor de tipul L dată mai devreme.

Acum considerăm un limbaj care este definit printr-o rețea Petri și un marcaj final f incomplet specificat. Fie mulțimea tuturor locațiilor pentru care fi = w. Pentru fiecare tranziție tj T pentru care O(tj) , fie j = O(tj) și j = O(tj) – j. Multisetul j conține toate locațiile unde marcajele nu contează, în timp ce multisetul j conține toate locațiile unde marcajele trebuie să fie exact cum s-a specificat în marcajul final f.

Adăugăm noi tranziții rețelei cu multisetul de etichete și intrări același cu multisetul de etichete și intrări pentru tj, dar cu colecția de ieșire j + , unde acoperă toate subultiseturile lui j. Această construcție nu modifică în nici un fel comportamentul acelor locații care nu sunt în , dar permite acelor locații care nu contează să aibă orice număr de jetoane mai mic sau egal cu numărul de jetoane care ar fi apărut în rețeaua originală. Astfel, fiecare cuvânt din limbajul generalizat al rețelei originale atinge o stare s astfel încât s*i = fi pentru fi w și si = 0 pentru fi = w. Astfel, limbajul de tip L pentru rețeaua Petri construită cu un marcaj final f’ (unde toate w-urile din marcajul f specificat incomplet au fost înlocuite cu 0) este același cu limbajul generalizat al rețelei originale (așa cum este definit de marcajul final f incomplet specificat).

Pentru un limbaj definit de o mulțime de marcaje incomplet specificate (în opoziție cu cazul unui singur astfel de marcaj, pe care tocmai l-am discutat) folosim faptul că limbajele L (și L) sunt închise la reuniune (vezi capitolul 6.5.2) pentru a arăta că limbajul este încă un limbaj de tipul L (sau L).

Cu introducerea marcajelor finale incomplet specificate putem arăta că limbajele de tipul T sunt de asemenea limbaje de tipul L (cu excepția probabil a limbajelor libere de tipul L).

O stare finală pentru un limbaj de tipul T este astfel încât nici o tranziție tj nu se poate declanșa (adică, I(tj) oricare ar fi tj T). Condiția care specifică o stare finală pentru un limbaj de tipul T este de aceea exact condiția opusă condiției care specifică o stare finală pentru un limbaj de tipul G (Putem numi limbajele de tipul T inversele limbajelor de tipul G). Nu este dificil de văzut că o astfel de mulțime de marcaje poate fi descrisă printr-o mulțime finită de marcaje incomplet specificate (cum s-a făcut în capitolul 5.4). De exemplu, condiția [ (2,0) și (1,1)] este echivalentă cu [ = (0,20) sau = (1,0)]. Un limbaj de tipul T (sau, mai general, un limbaj invers unui limbaj de tipul G) poate astfel fi rescris ca un limbaj de tipul L generalizat (adică, incomplet specificat) și deci ca un limbaj de tipul L. Astfel, T L și T L.

Se știe că fiecare limbaj de tipul L poate fi generat de către o rețea Petri în care fiecare tranziție are o locație de intrare, și în care unicul marcaj final este marcajul zero, în care nici o tranziție nu se poate declanșa [Hack 1975b]. Dacă adăugăm la fiecare locație o -tranziție cu o singură intrare și o singură ieșire a acelei locații (adică, o buclă), atunci limbajul nu este schimbat și marcajul zero devine singurul marcaj terminal.

Figura 6.4 reprezintă grafic relațiile dintre clasele de limbaje pentru rețele Petri pe care tocmai le-am obținut. Un arc între clase indică faptul că o clasă de limbaje pentru rețelele Petri este inclusă într-o altă clasă de limbaje pentru rețelele Petri.

Figura 6.4: Relațiile cunoscute între clasele de limbaje pentru rețele Petri. Un arc de la o clasă A la o clasă B înseamnă că clasa A conține clasa B

Proprietățile limbajelor rețelelor Petri

Studiul limbajelor rețelelor Petri este de abia la început și cunoștințele actuale despre proprietățile claselor de limbaje nou definite sunt mărginite. Puterea rețelelor Petri este reflectată de varietatea de clase potențial diferite de limbaje pentru rețele Petri care pot fi definite. Stadiul incipient în care se află cercetările în această direcție este reflectat de incapacitatea de a arăta relațiile complete dintre aceste limbaje, sau de a argumenta că numai câteva dintre aceste clase sunt importante. Aceasta dă naștere la o largă zonă de studiu, în necesitatea de a dezvolta proprietățile a 12 clase diferite de limbaje.

Evident nu este posibilă dezvoltarea aici a tuturor celor 12 clase, și de aceea ne vom limita la a considera numai o clasă de limbaje pentru rețele Petri, limbajele de tipul L. Motivele principale pentru această limitare sunt spațiul și faptul că acest limbaj a fost cercetat în literatură (Peterson, 1973, Hack 1975b, Peterson 1976). Unele rezultate au fost de asemenea obținute de Hack [1975b] pentru limbajele prefixate (de tipul P) și vor fi prezentate în acest rezumat. Limbajele de tipul G și cele de tipul T au fost definite, dar nu s-au făcut studii asupra lor. Amintiți-vă de asemenea că clasa de limbaje de tipul L include clasele de limbaje de tipul G, T și P. Astfel, limbajele de tipul L sunt într-un anumit sens clasa de limbaje pentru rețele Petri cea mai cuprinzătoare, și astfel este potrivit ca această clasă să fie cercetată mai întâi.

Cercetarea noastră asupra proprietăților limbajelor rețelelor Petri de tipul L se va concentra asupra a două aspecte. Mai întâi vom prezenta proprietățile de închidere ale rețelelor Petri în cazul câtorva operații comune (concatenare, reuniune, concurență, intersecție, inversare, complementare, concatenare infinită și substituție). Apoi vom considera relația dintre limbajele rețelelor Petri și limbajele formale clasice: regulate, independente de context, dependente de context și de tipul zero. Această prezentare oferă o înțelegere a puterii și limitărilor limbajelor rețelelor Petri de tipul L, indicând de asemenea care este modul în care trebuie cercetate celelalte clase de limbaje pentru rețele Petri.

Deși suntem interesați de întreaga clasă a limbajelor pentru rețele Petri de tipul L, vom limita discuția numai la o mulțime finită de rețele Petri în forma standard. Această limitare este făcută cu scopul de a ne putea concentra atenția asupra demonstrațiilor și construcțiilor și nu limitează clasa limbajelor rețelelor Petri. Pentru fiecare limbaj al rețelelor Petri, pot fi multe rețele Petri care să genereze acel limbaj; alegem să lucrăm numai cu acele rețele care au anumite proprietăți. Pentru a arăta că astfel nu se reduce mulțimea limbajelor, vom arăta că pentru fiecare limbaj de rețea Petri de tipul L există o rețea Petri în formă standard care îl generează.

Definiția 6.5:

O rețea Petri etichetată = (C, , , F) cu limbajul L() în forma standard satisface următoarele proprietăți:

Marcajul inițial are exact un jeton într-o locație de pornire p și zero jetoane în restul locațiilor, pj O(tj) pentru nici un tj T.

Există o locație pf P astfel încât:

F = {pf} dacă L(), sau F = {pf, ps} dacă L()

pf I(tj) pentru nici un tj T

(’, tj) este nedefinită pentru toți tj T și ’ R(C, ) care are un jeton în pf [adică, ’(pf) > 0]

Execuția unei rețele Petri în forma standard începe cu un jeton în locația de pornire. Prima

tranziție care se declanșează mută jetonul din locația de pornire, și după această declanșare locația de pornire este întotdeauna goală. Eventual, rețeaua Petri se poate opri punând un jeton în locația finală. Acest jeton nu poate fi mutat din locația finală deoarece nici o tranziție nu are intrarea din locația finală și deoarece toate tranzițiile sunt dezactivate. Astfel, execuția unei rețele Petri în formă standard este simplă și finită. Aceste fapte sunt foarte utile când se construiesc componentele rețelei Petri. Pentru a arăta că rețelele Petri în forma standard nu sunt mai puțin puternice decât cele în forma generală, vom demonstra următoarea teoremă:

Teorema 6.1:

Fiecare rețea Petri este echivalentă cu o rețea Petri în forma normală.

Demonstrație:

Demonstrația este constructivă. Fie = (C, , , F) o rețea Petri etichetată, cu C = (P, T, I, O). Arătăm cum se construiește o rețea ’ = (C’, ’, ’, F’), cu C’ = (P’, T’, I’, O’) dată în formă normală (figura 6.5).

Pentru început, definim trei noi locații pr, pf și ps care nu sunt în P. Locația ps este locația de pornire, locația pf este locația finală și pr este o locație de rulare; un jeton trebuie să fie în pr pentru a permite oricărei tranziții din T să se declanșeze. Marcajul inițial al lui C’ va avea un jeton în ps dacă L(C’), sau în pf dacă L(C’).

Figura 6.5: Construcția unei rețele Petri în forma standard. Execuția rețelei este aceeași cu cea a rețelei originale

Acum dorim să fim siguri că fiecare secvență de tranzacții din C care ne conduce de la marcajul inițial la marcajele finale este minimizată în C`. Pentru aceasta considerăm trei tipuri de șiruri în L(). Mai întâi, șirul vid este corect mânuit de definiția lui F`. Putem determina dacă L() verificând dacă marcajul inițial este și marcaj final, adică dacă F.

În al doilea rând, pentru toate șirurile de lungime 1 din L(), includem în C` o tranziție specială de la ps la pf după cum urmează: pentru cu L(), definim t T` cu I(t) = {ps} și O(t) = {pf}. Eticheta pentru t este . Putem determina dacă L() prin verificarea tuturor tranzițiilor tj T cu (tj) = , pentru a vedea dacă (, tj) F.

În cele din urmă, considerăm toate șirurile de lungime mai mare sau egală cu 1. Aceste șiruri rezultă dintr-o secvență de tranziții . Am putea să definim o secvență , cu a și b tranziții noi. Noua tranziție a va avea ca intrare un jeton din ps și va scoate la ieșire marcajul inițial al lui C, plus un jeton în pr. Fiecare tranziție din T’ este aceeași cu secvența tj din T cu excepția faptului că are pe pr atât ca intrare cât și ca ieșire. Aceasta ne permite să dezactivăm toate tranzițiile din T’ prin mutarea jetonului din pr. În cele din urmă, tranziția b va muta jetonul din pr, va scoate un marcaj final și va duce un jeton la pj. Cu această construcție, jetonul din poziția de intrare se va muta în poziția finală din C’ numai ca rezultat al unei secvențe care corespunde unei secvențe care ne conduce de la la un marcaj final din C.

Din nefericire, în acest mod se va produce o secvență care este prea lungă, deoarece simbolurile suplimentare corespunzătoare tranzițiilor a și b există pentru C’ dar nu și pentru C. O soluție ar fi o etichetare nulă a tranzițiilor a și b, dar limbajele de tipul L nu permit etichete nule. Pentru a rezolva această problemă vom încerca să reunim tranzițiile a și într-o tranziție , și tranzițiile b și într-o tranziție . Pentru aceasta, pentru toți tj T vom defini următoarele tranziții în T’:

Definim T, cu I() = I(tj) {pr} și O() = O(tj) {pr}

Dacă I(tj) (adică intrările pentru tj sunt o submulțime a marcajului inițial, astfel încât tj poate fi prima tranziție care se declanșează), atunci definim o tranziție cu I() = {ps} și O() = – I(tj) + O(tj) {pr}.

Dacă O(tj) ’ pentru unele marcaje ’ F (adică tj poate fi ultima tranziție care se declanșează, care conduce la un marcaj final), atunci definim o tranziție cu I() = ’ – O(tj) + I(tj) {p} și O() = {pf}.

Acum definim funcția de etichetare ’ prin ’() = ’() = ’() = (tj). Orice șir

L() este prin definiție generat de o secvență cu = (). Prin construcție, = ’ (), și astfel L(’). Prin urmare, deoarece L() = L(’), cele două rețele și ’ sunt echivalente. Prin construcție, ’ este în forma standard.

Figura 6.6 dă o rețea Petri simplă care nu este în forma standard. Aplicând construcția din demonstrație acestei rețele se produce rețeaua Petri în forma standard din figura 6.7.

Proprietăți de închidere

Vom examina acum proprietățile de închidere ale limbajelor rețelelor Petri pentru câteva forme de compunere (reuniune, intersecție, concatenare, concurență și substituție) și pentru unele operații (inversare, complementare și concatenare infinită). Motivația acestei examinări are două puncte. Mai întâi, ne face să înțelegem mai bine proprietățile și limitele ca limbaje ale limbajelor rețelelor Petri. În al doilea rând, multe dintre aceste două compuneri reflectă cât de largi sisteme se pot construi prin compunerea de sisteme mai mici. Astfel, această investigare ne poate ajuta în dezvoltarea de tehnici de sinteză.

Cea mai mare parte a proprietăților de compunere se ocupă de compuneri de limbaje de rețele Petri. Pentru aceasta, presupunem două limbaje de rețele Petri, L1 și L2. Știm că fiecare dintre aceste limbaje este generat de niște rețele în formă standard. De aceea, considerăm două rețele Petri etichetate în formă standard, i = (Ci, i, i, Fi), i = 1…2 cu Li = L(i). Deoarece sunt în forma standard, rețeaua i are o locație de pornire Pi. De asemenea, Fi = {, } sau {}, i = 1…2.

Arătăm cum, din aceste două rețele Petri etichetate, se construiește o nouă rețea Petri etichetată ’ = (C’, ’, ’, F’) cu limbajul L(’) care este compunerea dorită a lui L1 cu L2. Ilustrăm aceste construcții cu exemple de rețele Petri. Vom începe considerând compunerea a două limbaje de rețele Petri prin concatenare, reuniune, intersecție și concurență. Apoi vom considera inversa și complementara unui limbaj de rețea Petri și, în final, substituția.

Concatenarea

Multe sisteme sunt compuse din două subsisteme secvențiale. Fiecare dintre subsisteme poate fi exprimat individual ca o rețea Petri cu propriul său limbaj de rețea Petri. Când cele două sisteme sunt combinate secvențial, execuția rezultată este concatenarea execuției limbajului primei rețele Petri cu o execuție a celui de-al doilea. Concatenarea a două limbaje poate fi formal exprimată astfel: L1L2 = {x1x2 / x1 L1, x2 L2}.

Teorema 6.2:

Dacă L1 și L2 sunt limbaje de rețele Petri, atunci L1L2 este un limbaj de rețea Petri.

Demonstrație:

Definim astfel încât locația finală a lui 1 să se suprapună peste locația de pornire a lui 2. Astfel, tranziția care pune un jeton în semnalând sfârșitul execuției lui 1, semnalează de asemenea începutul unei execuții a lui 2. De aceea, orice șir din concatenarea lui L1 cu L2 trasează o cale de la la și apoi la în rețeaua Petri compusă și este un element al L(’). Similar, dacă un șir este generat de C’, trebuie să fie compus dintr-un șir generat de 1 și un șir generat de 2.

Definiția formală a lui ’ trebuie să ia în considerare șirul vid și astfel este mai complexă, dar poate fi definită ca uniunea lui 1 și 2 la care se adaugă următoarele tranziții suplimentare. Pentru fiecare tranziție tj T2 cu I2(tj) = {}, introducem o nouă tranziție cu I’() = {} și O’() = O2(tj). Dacă F1, atunci adăugăm de asemenea cu I’() = {} și O’() = O2(tj). Definim ’() = 2(tj) și ’() = 2(tj). Noua mulțime finală este F’ = F1 F2 dacă F2; altfel, F’ = F2.

Această teoremă arată că limbajele rețelelor Petri sunt închise la concatenare. Figura 6.8 prezintă construcția pentru L1 = (a + b)+ și L2 = anbn.

Figura 6.8: Ilustrează concatenarea a două limbaje de rețele Petri

Uniunea

O altă metodă comună de combinare a sistemelor este uniunea. În această compunere va fi executat un singur subsistem. Aceasta este similară cu reuniunea mulțimilor și este o compunere de limbaje obișnuită ce poate fi definită prin: L1 L2 = {x / x L1 sau x L2}.

Teorema 6.3:

Dacă L1 și L2 sunt limbaje de rețele Petri, atunci L1 L2 este un limbaj de rețea Petri.

Demonstrație:

Demonstrația acestei teoreme este similară cu demonstrația teoremei anterioare. Definim o nouă rețea Petri ’ astfel încât L(’) = L1 L2. Noua rețea Petri combină cele două locații de pornire într-o nouă locație de pornire. Apoi, prima tranziție care se declanșează mută jetonul din poziția de intrare și fie rețeaua Petri 1 (dacă tranziția a fost în T1), fie rețeaua Petri 2 (dacă tranziția a fost în T2) continuă să funcționeze la fel cum ar fi făcut singură.

Formal definim o nouă locație de pornire și noi tranziții pentru fiecare T1 cu I() = {} și pentru fiecare T2 cu I() = {}. Definim I’() = {} și I’() = {} cu O’() = O1() și O’() = O2(). Funcția de etichetare ’() = 1() și ’() = 2(). Noul marcaj inițial are un jeton în Noua mulțime finală este F’ = F1 F2. Dacă F1 sau F2 atunci F’.

Figura 6.9 ilustrează construcția cu L1 = a(a + b)b și L2 = ambn (m > n > 1).

Figura 6.9: Ilustrarea uniunii a două limbaje de rețele Petri. L(C’) = a(a+b)b + ambn,

(m > n > 1)

Concurența

O altă cale de combinare a două rețele Petri este prin a permite ca execuțiile a două sisteme să se realizeze concurent. Astfel se realizează toate intercalările posibile ale unei execuții a unei rețele Petri cu o execuție a unei alte rețele Petri. Riddle [1972] a introdus operatorul || pentru a reprezenta această concurență. Acesta poate fi definit pentru a, b și x1, x2 * prin:

a || = || a = a

ax1 || bx2 = a(x1 || bx2) + b(ax1 || x2)

Compunerea concurentă a două limbaje este atunci L1 || L2 = {x1 || x2 / x1 L1, x2 L2}.

Ca un exemplu simplu, dacă L1 = {ab} și L2 = {c} atunci L1 || L2 = {abc, acb, cab}.

Este ușor de arătat că limbajele regulate, dependente de context și de tipul 0 sunt închise la concurență demonstrând că produsul direct a două automate cu stări finite, automate liniare finite sau mașini Turing este tot un automat cu stări finite, un automat liniar finit, respectiv o mașină Turing. Deoarece produsul direct a două automate stivă push-down nu poate fi transformat într-un alt automat stivă push-down, limbajele independente de context nu sunt închise la concurență. Pentru limbajele de rețele Petri, avem următoarea teoremă.

Teorema 6.4:

Dacă L1 și L2 sunt limbaje de rețele Petri, atunci L1 || L2 este un limbaj de rețea Petri.

Demonstrație:

Rețeaua Petri construită pentru a genera compunerea concurentă a lui L1 cu L2 (se dau rețelele Petri ce generează aceste limbaje de rețele Petri) este practic o rețea Petri care pune jetoane în pozițiile de pornire atât ale lui 1 cât și ale lui2, ca marcaj inițial, și definește noua mulțime de marcaje finale ca fiind compusă din orice marcaj care este în F1 (peste locațiile din P1) și în F2 (peste pozițiile din P2).

Această construcție este ilustrată în figura 6.10 pentru L1 = a(a + b)+ și L2 = ca3ncb2nc.

Figura 6.10: Ilustrează compunerea concurentă a două limbaje de rețele Petri

Intersecția

Ca și în cazul uniunii, compunerea prin intersecție este similară cu operația de intersecție din teoria mulțimilor și este dată pentru un limbaj de rețea Petri prin L1 L2 = {x / x L1 și x L2}.

Teorema 6.5:

Dacă L1 și L2 sunt limbaje de rețele Petri, atunci L1 L2 este un limbaj de rețea Petri.

Demonstrație:

Construcția unei rețele Petri pentru a genera intersecția a două limbaje de rețele Petri este destul de complexă. La un anumit punct în șirul generat, dacă o tranziție se declanșează într-una din rețelele Petri, atunci trebuie să existe o tranziție în cealaltă rețea Petri, cu aceeași etichetă, care să se declanșeze de asemenea. Când în fiecare rețea Petri există mai mult de o tranziție cu aceeași etichetă trebuie să considerăm toate perechile posibile de tranziții din cele două rețele Petri. Pentru fiecare din aceste două perechi, creăm o nouă tranziție care se declanșează dacă și numai dacă în vechile rețele se declanșează ambele tranziții. Aceasta se realizează egalând multisetul de intrare (ieșire) al noii tranziții cu multisetul sumă (vezi anexa) al multiseturilor de intrare (ieșire) ale perechilor de tranziții din vechile rețele Petri. Astfel, dacă tj T1 și tk T2 sunt astfel încât (tj) = (tk), atunci avem o tranziție tj,k T’ cu I’(tj,k) = I1(tj) + I2(tk) și O’(tj,k) = O1(tj) + O2(tk). Unele dintre aceste tranziții au intrări care includ locația de pornire. Dacă pentru o tranziție tj,k din T’, așa cum s-a definit mai sus, I’(tj,k) = {}, atunci înlocuim tranziția cu o nouă tranziție , unde I’() = {}.

Această construcție plasează cele două rețele Petri inițiale într-un mod de execuție identic pe pași. Rețeaua Petri compusă generează intersecția limbajelor L1 și L2. Construcția este demonstrată în figura 6.11.

Figura 6.11: Ilustrează intersecția a două limbaje de rețele Petri

Inversa

Spre deosebire de operațiile de compunere pe care le-am studiat anterior, operația de inversare pare să prezinte interes doar din punct de vedere academic.

Inversa unei propoziții xR este propoziția x cu simbolurile în ordine inversă. Definim aceasta recursiv prin:

aR = a

(ax)R = xRa, pentru a , x +

Atunci pentru un limbaj avem LR = {xR / x L}.

Teorema 6.6:

Dacă L este un limbaj de rețea Petri, atunci și LR este un limbaj de rețea Petri.

Demonstrație:

Construcția este trivială. Marcajul de pornire și cel final se interschimbă și la fel și multiseturile de intrare și ieșire pentru fiecare tranziție. Apoi, L(’) = L()R. Acesta doar pornește rețeaua Petri în sens invers și inversează toate șirurile generate.

Complementara

Complementara I a unui limbaj L peste un alfabet este mulțimea tuturor șirurilor din * care nu sunt în L. Această relație poate fi exprimată prin I = * – L, sau I = {x * / x L}.

Operația de complementare asupra unui limbaj de rețea Petri poate fi utilă în analiza rețelelor Petri deoarece în verificările secvențelor de stări s-au putea să fie mai ușor de verificat existența în complementară decât nonexistența în limbajul rețelei Petri.

Închiderea la complementară pentru limbajele Petri de tipul L este o problemă deschisă. Totuși, Crespi-Reghizzi și Mandrioli [1977] au arătat că unele limbaje de rețele Petri nu sunt închise la complementară; aceasta înseamnă că există limbaje de rețele Petri ale căror complemente nu sunt tot limbaje de rețele Petri.

Compunerea repetată

Până acum am considerat operațiile de uniune, intersecție, concatenare, concurență, inversă și complementare. Cu excepția ultimei operații, am putut să realizăm construcții astfel încât să arătăm că limbajele de rețele Petri sunt închise la operațiile respective.

Din aceste rezultate putem să demonstrăm imediat următorul corolar.

Corolar 6.1:

Limbajele de rețele Petri sunt închise la aplicarea de un număr finit de ori, în orice ordine, a operațiilor de uniune, intersecție, inversare, concurență și concatenare.

Demonstrație:

Demontrația rezultă din teoremele de mai sus.

Se poate defini o nouă operație prin eliminarea constrângerii de a se permite numai un număr finit de aplicări. Concatenarea indefinită (închiderea Kleene) a unui limbaj este mulțimea tuturor elementelor construite (de orice lungime) din acest limbaj. Închiderea Kleene a unui limbaj L este reprezentată prin L* și este definit prin L* = L LL LLL …

Operația poate fi de utilitate practică. Concatenarea infinită este similară cu modelarea unei bucle. De asemenea, este cunoscut că limbajele regulate, independente de context și cele de tipul 0 sunt închise la concatenarea indefinită [Hopcroft și Ullman 1969]. Din acest motiv, este neașteptat și poate un ghinion că limbajele de rețele Petri nu sunt închise la concatenarea indefinită.

Această situație a apărut datorită naturii finite a combinației rețelelor Petri (cu număr finit de locații și tranziții) și a naturii permisive a stărilor [declanșarea tranzițiilor este permisă, dar nu este obligatorie]. Pentru a construi o rețea Petri care să genereze concatenarea indefinită a unui limbaj de rețea Petri, se impune, în general, reutilizarea unor porțiuni din rețeaua Petri. Aceasta permite jetoanelor să fie generate și depozitate în unele dintre locațiile care sunt refolosite. La o repetare ulterioară a rețelei Petri, aceste jetoane pot fi folosite pentru a permite tranzițiilor să se declanșeze când nu ar trebui.

Demonstrația că rețelele Petri nu sunt închise la concatenarea indefinită apare ca fiind foarte dificilă. Probabil o idee despre abordare poate fi dată prin considerarea unui exemplu. Am văzut deja că anbn (n > 1) este un limbaj de rețea Petri. Afirmăm că (anbn)* nu este un limbaj de rețea Petri. Toate generatoarele lui (anbn)* trebuie să aibă unele locații, sau mulțimi de locații, care codifică numărul n pentru fiecare porțiune a șirului. Aceste jetoane controlează generarea simbolurilor b. Pentru ca o rețea Petri să genereze (anbn)* este necesar să se folosească aceste locații mai mult decât o dată. Dar, de vreme ce rețeaua este permisivă, nu există nici o cale de a garanta că aceste locații sunt vide înainte de a fi refolosite. Astfel, pentru fiecare rețea Petri care încearcă să genereze (anbn)* există anumiți i, j, k astfel încât rețeaua Petri să genereze, de asemenea, niște șiruri de forma următoare: , cu ni > nj. Kosaraju [1973] a dat bazele pentru o demonstrație formală a faptului că limbajele de rețele Petri nu sunt închise la concatenarea indefinită.

Pentru cei familiarizați cu teoria limbajelor formale a familiei limbajelor abstracte (AFL) [Ginsburg 1975], este ușor de probat că limbajele de rețele Petri nu sunt închise la concatenarea infinită. Este bine cunoscut că cele mai mici AFL închise la intersecție și conținând {anbn} conțin orice mulțime recursiv enumerativă. Astfel, deoarece limbajele de rețele Petri sunt închise la intersecție și {anbn} este un limbaj de rețea Petri, dacă ar fi închise la concatenare indefinită, ar fi un astfel de AFL. Totuși, știm că {wwR} nu este un limbaj de rețea Petri (vezi secțiunea 6.6.2) și astfel limbajele de rețea Petri nu sunt închise la concatenarea indefinită. Această argumentare se datorează lui Mandrioli.

Există totuși o subclasă de limbaje de rețele Petri care este închisă la concatenarea nedefinită. Aceasta este clasa de limbaje de rețele Petri pentru acele rețele Petri care sunt corect terminate. Corect terminarea a fost definită de Gostelow [1971] pentru modele de calcul complexe cu grafuri cu bucle duble.

Definiția 6.6:

O rețea Petri este corect terminată dacă de fiecare dată când se termină este sigur că:

în rețeaua Petri rămâne numai un jeton și că acesta este în locația finală, și că

numărul de jetoane folosite în rețeaua Petri este finit.

Observăm mai întâi că a doua parte a definiției nu este de fapt o restricție deoarece dacă rețeaua Petri se termină, atunci ea se termină într-o cantitate finită de timp și de aceea generează numai un număr finit de jetoane. Dar prima parte a definiției este o restricție. Putem vedea rețeaua Petri ca un automat care generează șiruri de simboluri. Punem un jeton în intrarea automatului și un șir de simboluri este tipărit pe o bucată de bandă, pentru noi. Eventual, un semnal luminos ne poate avertiza când automatul se oprește (adică nu mai sunt tranziții active). Într-o utilizare normală, înainte de a putea utiliza ieșirea printată, trebuie să ne uităm în interiorul automatului și să verificăm dacă s-a ajuns la un marcaj final. Dacă nu s-a ajuns la un marcaj final, atunci trebuie să respingem ieșirea și să încercăm din nou. Dacă rețeaua Petri se termină corect, atunci nu mai este nevoie să ne uităm în interiorul automatului, deoarece ni se garantează că s-a ajuns la un marcaj final.

Iată cum poate fi folosită o rețea Petri care se termină corect pentru a construi o rețea Petri care să genereze concatenarea indefinită a limbajului său:

Conectăm locația finală cu locația de pornire.

Cum despre rețeaua Petri se știe că trebuie să fie vidă de fiecare dată când un jeton apare în locația finală, nu se va lăsa nici un jeton în rețeaua Petri pentru a cauza tranziții fictive la reutilizarea rețelei Petri.

Din nefericire, această subclasă de rețele Petri nu este foarte interesantă de vreme ce putem arăta că toate rețelele Petri care se termină corect sunt automate cu stări finite și viceversa. Prin urmare, limbajele rețelelor Petri care se termină corect sunt limbaje regulate și este deja cunoscut că această clasă de limbaje este închisă la concatenarea indefinită. Astfel vedem că proprietățile sistemelor modelate de limbajele rețelelor Petri sunt mărginite la repetări finite de subsisteme mai mici, sau la repetări indefinite de subsisteme finite mai mici.

Substituția

Am menționat că sistemele pot fi proiectate și modelate ierarhic cu ajutorul rețelelor Petri.

Aceasta implică specificarea în primul rând a unei ieșiri a sistemului care să fie rafinată mai apoi prin substituiri ale operațiilor în termeni de alte operații. Cu rețelele Petri acest rafinament poate lua forma substituirii unei tranziții sau a unei locații dintr-o rețea Petri completă. De aceea ne-am limitat atenția la a considera problema substituirii unei tranziții (sau operații) într-o subrețea a unei rețele Petri.

Când se dorește să se substituie o rețea Petri printr-o altă rețea Petri acest lucru se poate considera ca fiind o compunere a limbajelor celor două rețele Petri. Deoarece operația este reprezentată printr-un simbol din , substituția limbajului L2 al unei rețele Petri pentru un simbol într-un alt limbaj de rețea Petri L1 este definită ca înlocuirea tuturor aparițiilor lui din L1 prin mulțimea de șiruri din L2. Limbajele rețelelor Petri sunt închise la substituție dacă rezultatul unei substituții ce implică un limbaj de rețea Petri este de asemenea tot un limbaj de rețea Petri. Variații asupra substituției includ substituția finită, când L2 trebuie să fie o mulțime finită de șiruri, și homeomorfismul, când L2 trebuie să fie un șir simplu (single-string).

Din nou, din nefericire, avem un rezultat negativ. Limbajele de rețele Petri nu sunt închise la substituția generală. Aceasta se arată imediat considerând L1 = c* și substituirea lui L2 = anbn prin c în L1. Problema este din nou rezolvată printr-o posibilă reutilizare a unei rețele Petri. Totuși, pentru substituția finită și homeomorfism, vedem că L2 este un limbaj regulat și de aceea pentru a-l genera se poate construi o rețea Petri cu terminare corectă. Aceasta conduce la următoarele rezultate:

Teorema 6.7:

Dacă L2 este un limbaj regulat și L1 este un limbaj de rețea Petri, atunci rezultatul substituirii lui L2 printr-un simbol în L1 este un limbaj de rețea Petri.

Corolar 6.2:

Limbajele de rețele Petri sunt închise la substituția finită și homeomorfism.

Limbajele de rețele Petri și alte clase de limbaje

Considerând proprietățile limbajelor de rețele Petri ca o clasă de limbaje, ne întoarcem să cercetăm relația dintre limbajele de rețele Petri și alte clase de limbaje. În principal, vom considera clasa limbajelor regulate, a celor independente de context, dependente de context și a celor de tip 0.

Limbajele regulate

Una din cele mai simple și cele mai studiate clase de limbaje formale este clasa limbajelor regulate. Aceste limbaje sunt generate de gramatici regulate și automate cu stări finite și sunt caracterizate de expresii regulate. Problemele echivalenței și a includerii unui limbaj regulat în alt limbaj regulat sunt decidabile și există algoritmi pentru rezolvarea lor [Hopcroft și Ullman, 1969]. Cu o astfel de mulțime de proprietăți, este încurajator că avem următoarea teoremă.

Teorema 6.8:

Fiecare limbaj regulat este un limbaj de rețea Petri.

Demonstrația acestei teoreme se bazează pe faptul că fiecare limbaj regulat este generat de un automat cu stări finite și am arătat (capitolul 3.3.1) că fiecare automat cu stări finite poate fi transformat într-o rețea Petri echivalentă.

Reciproca acestei teoreme nu este adevărată. Figura 6.12 ilustrează o rețea Petri care generează limbajul {anbn / n > 1} independent de context. Deoarece acest limbaj nu este regulat, știm că nu toate limbajele de rețele Petri sunt limbaje regulate.

Figura 6.12: Un limbaj de rețea Petri independent de context care nu este un limbaj regulat

Limbaje independente de context

Figura 6.12 demonstrează că nu toate limbajele de rețele Petri sunt limbaje regulate

expunând un limbaj de rețea Petri care este independent de context, dar nu este regulat. Figura 6.13 arată că nu toate limbajele de rețele Petri sunt independente de context expunând un limbaj de rețea Petri care este dependent de context, dar nu este independent de context.

Figura 6.13: Un limbaj de rețea Petri dependent de context, dar nu independent de context

Se poate arăta că există limbaje independente de context care nu sunt limbaje de rețele Petri. Un exemplu de astfel de limbaj este limbajul {wwR / w *} independent de context. De aici rezultă următoarea teoremă.

Teorema 6.9:

Există limbaje independente de context care nu sunt limbaje de rețele Petri.

Demonstrație:

Presupunem că există o rețea cu n locații și m tranziții care generează limbajul {wwR}. Fie k numărul de simboluri din , k > 1. Pentru un șir de intrare xxR, fie r = |x| lungimea lui x. Deoarece sunt kr șiruri de intrare x posibile, rețeaua Petri trebuie ca după r tranziții să aibă k’ stări accesibile distincte, pentru a-și aminti întregul șir x. Dacă nu avem atât de multe stări, atunci pentru unele șiruri x1 și x2 avem (, x1) = (, x2), pentru x1 x2.

Apoi vedem că (, ) = ((, x1),) = ((, x2),) = (, ) F și ca urmare rețeaua Petri va genera incorect x1.

În capitolul 4.4.2 am arătat că pentru fiecare tranziție tj există un vector vj = e[j].D astfel încât dacă (q, tj) este definită, atunci valoarea lui (q, tj) este q + vj. Apoi după r intrări avem o stare q, unde , pentru o secvență de tranziții . O altă cale de a exprima această sumă este: , unde fj este numărul de apariții ale tranziției tj în secvența [f = (f1f2…fm) este vectorul declanșărilor]. De asemenea, avem constrângerea .

În cazul cel mai bun, vectorii v1v2…vm vor fi liniar independenți și pentru fiecare vector de declanșări (f1f2…fm) va reprezanta o singură stare qr. Deoarece suma coeficienților este r, vectorul (f1f2…fm) este o partiție a întregului r în m părți. Knuth [1973] a arătat că numărul de partiții ale unui întreg r în m părți este .

Acum, deoarece , înseamnă că după r intrări în mulțimea stărilor accesibile sunt mai puțin de (r + m)m stări accesibile. Pentru un r suficient de mare, avem deci și este imposibil să fie k’ stări distincte pentru fiecare din cele k’ șiruri de intrare posibile. Astfel, este imposibil ca o rețea Petri să genereze limbajul {wwR}.

Demonstrația faptului că {wwR} nu este un limbaj de rețea Petri lămurește întrucâtva limitările rețelelor Petri ca automate și astfel și natura limbajelor rețelelor Petri. Rețelele Petri nu sunt capabile să-și amintească arbitrar secvențe lungi de simboluri arbitrare. Din demonstrație, vedem că rețelele Petri își pot aminti secvențe de o anumită lungime maximă (dar acest lucru îl pot face și automatele cu stări finite). O altă capacitate a rețelelor Petri este aceea de a-și aminti numărul de apariții ale unui simbol, spre exemplu anbncn, un lucru pe care generatoarele de limbaje regulate și independente de context nu-l pot face. Totuși, un limbaj Petri nu poate simula puterea unui automat stivă push-down necesar pentru a genera un limbaj independent de context. Rata de creștere a spațiului stărilor accesibile pentru o rețea Petri este combinatorială cu lungimea intrării și nu exponențială ca în cazul automatului stivă push-down.

Motivul pentru care rețelele Petri sunt capabile să genereze limbaje pe care un automat stivă push-down nu le poate genera în ciuda celui mai mic spațiu de stare este acela că într-o rețea Petri interconectările între stări sunt mai flexibile spre deosebire de cazul automatului stivă push-down în care sunt permise căi restrictive între stări. Acest fapt rezultă din faptul că un automat stivă push-down nu poate accesa decât starea din vârful stivei, în timp ce o rețea Petri poate acesa orice stare la orice moment.

După ce am arătat că nu toate limbajele independente de context sunt limbaje de rețele Petri și că nu toate limbajele de rețele Petri sunt limbaje independente de context, apare întrebarea care este clasa limbajelor care sunt atât limbaje independente de context cât și limbaje de rețele Petri. În prezent, nu putem răspunde în întregime la această întrebare, dar putem da o indicație asupra unor membri ai acestei intersecții. O submulțime atât a limbajelor independente de context cât și a limbajelor de rețele Petri este, desigur, clasa limbajelor regulate. O altă submulțime este mulțimea limbajelor mărginite independente de context [Ginsburg 1966].

Limbaje mărginite independente de context

Un limbaj independent de context L este un limbaj mărginit independent de context dacă

există cuvinte w1,…, wn din * astfel încât L .

Adjectivul “mărginit” se referă la numărul finit de cuvinte, w1,…, wn. Ginsburg a dezvoltat o cercetare minuțioasă a propietăților limbajelor mărginite independente de context. El a menționat că, la momentul cercetării sale, nu erau cunoscute întrebări interesante privind limbajele mărginite independente de context care să nu se poată rezolva. Mai sunt însă unele întrebări deschise.

Limbajele mărginite independente de context sunt caracterizate de următoarea teoremă a lui Ginsburg [1966, Th 5.4].

Teorema 6.10:

Familia de limbaje mărginite independente de context este cea mai mică familie de mulțimi definite de următoarele reguli:

Dacă W este o submulțime finită a lui *, atunci W este mărginit independent de context.

Dacă W1 și W2 sunt mărginite independente de context, atunci W1 W2 și W1W2 sunt mărginite independente de context.

Dacă W este mărginită independentă de context și x, y *, atunci {xiWyi / i 0} este mărginită independentă de context

Am arătat deja în secțiunea 3.3.1 că fiecare automat cu stări finite, și de aceea fiecare limbaj

regulat și fiecare submulțime finită a lui * este un limbaj de rețea Petri. În capitolele 6.5.1 și 6.5.2 am arătat că limbajele de rețele Petri sunt închise la concatenare și uniune. Astfel, mai avem de arătat doar că pasul 3 de mai sus este satisăcut pentru limbaje de rețele Petri. Pentru a arăta aceasta, vom construi o rețea Petri ’ = (C’, , ’, F’ ) care generează limbaje de rețea Petri {xiwyi / i 0} dându-se rețelele Petri în forma standard x = (Cx, , x, Fx ), y = (Cy, , y, Fy ), w = (Cw, , w, Fw ) care generează x, y, respectiv w. ’ combină rețelele Petri x, y, w și o nouă locație p astfel încât de fiecare dată când x este executată, se pune un jeton în locația p. Locația p numără de câte ori este executată x. După ce x s-a executat de câte ori se dorește, se execută w. În final y este executată în mod repetat, mutând câte un jeton din p la fiecare repetare. Deoarece șirul de intrare este corect generat numai dacă rețeaua Petri este goală (cu excepția lui F’ care este definită ca fiind Fy), suntem siguri că numărul de execuții ale lui x este egal cu numărul de execuții ale lui y.

Această construcție, care este ilustrată în figura 6.14 pentru x = ab, y = b(a + b) și w = b+a, arată că {xiwyi / i 0} este un limbaj de rețea Petri. Astfel, orice limbaj mărginit independent de context este un limbaj de rețea Petri.

Figura 6.14: O rețea Petri care să genereze limbajul {xiwyi / i 0}. Construcția arată că toate limbajele mărginite independente de context sunt de asemenea limbaje de rețele Petri

Mai există alte limbaje independente de context care sunt și limbaje de rețele Petri dar nu sunt mărginite? Din nefericire, răspunsul este da. Ginsburg a arătat că expresia regulată (a + b)n nu este un limbaj mărginit independent de context. Deoarece acest limbaj este un limbaj de rețea Petri independent de context, vedem că limbajele mărginite independente de context sunt numai o submulțime bună a familiei de limbaje de rețele Petri independente de context. De asemenea, limbajul {(a + b)+anbn / n > 1} este un limbaj de rețea Petri independent de context, dar nu este nici mărginit, nici regulat. Este necesar ca studiile ulterioare să completeze caracterizarea mulțimii de limbaje de rețele Petri independente de context.

Faptul că atât mulțimea limbajelor regulate cât și mulțimiea limbajelor mărginite independente de context sunt submulțimi ale clasei de limbaje de rețele Petri este încurajator, deoarece ambele clase de limbaje au câteva proprietăți dorite și unele caracteristici interesante de analizat.

Limbaje dependente de context

Am cercetat relația dintre limbajele rețelelor Petri și limbajele regulate și pe cea dintre

limbajele rețelelor Petri și cele independente de context. Acum ne vom ocupa de limbajele dependente de context. Figura 6.13 a arătat că unele limbaje de rețele Petri nu sunt dependente de context; mai jos vom demonstra că toate limbajele de rețele Petri sunt dependente de context. Deoarece știm că toate limbajele independente de context sunt de asemenea dependente de context și că există limbaje independente de context care nu sunt limbaje de rețele Petri, știm că există limbaje dependente de context care nu sunt limbaje de rețele Petri.

Teorema 6.11:

Toate limbajele de rețele Petri sunt limbaje dependente de context.

Demonstrația că toate limbajele de rețele Petri sunt dependente de context este destul de complexă. Sunt două metode de a arăta că un limbaj este dependent de context: construind o gramatică dependentă de context care să-l genereze, sau specificând un automat mărginit liniar nedeterminist care să-l genereze. Peterson [1973] a arătat cum să se definească o gramatică dependentă de context care să genereze un limbaj de rețea Petri; aici arătăm de ce un automat mărginit liniar poate să genereze un limbaj de rețea Petri.

Un automat mărginit liniar este similar cu o mașină Turing. Are un centru finit de stări, un cap de citire /scriere, și o bandă (infinită în ambele părți). Proprietatea de mărginire care deosebește un automat mărginit liniar de o mașină Turing este dată de faptul că limita cantității finite de bandă care poate fi folosită în cazul automatului pentru a genera un șir de intrare dat este dată de o funcție liniară de lungimea șirului de intrare. În acest sens, un automat stivă liniar este similar cu automatul stivă push-down folosit pentru a genera limbaje independente de context (deoarece lungimea maximă a stivei este dată de o funcție liniară de șirul de intrare) exceptând faptul că automatul mărginit liniar are acces oriunde în memoria sa, în timp ce automatul stivă push-down are acces numai la sfârșitul memoriei sale.

Pentru a genera un limbaj de rețea Petri, putem simula rețeaua Petri rememorând, după fiecare intrare, numărul de jetoane din fiecare locație. Cât de repede poate numărul de jetoane să crească ca o funcție de intrare? Considerăm numărul de jetoane după declanșarea a r tranziții. Acest număr, notat cu c, este, pentru o secvență de tranziții , . Deoarece numerele #(pk, O(tj)) și #(pk, I(tj)), și deci și numerele |O(tj)| și |I(tj)| (cardinalitatea multiseturilor de intrare și ieșire), sunt fixate de structura rețelei Petri, există o valoare maximă l a lor, , și astfel .

Numărul de jetoane, și deci cantitatea de memorie necesară pentru a le rememora, este mărginit de o funcție liniară de lungimea intrării. Astfel, limbajele de rețele Petri pot fi generate de un automat mărginit liniar.

Cu această demonstrație, am arătat că toate limbajele de rețele Petri sunt limbaje dependente de context.

Am rezumat rezultatele referitoare la relația dintre clasa limbajelor de rețele Petri și alte clase de limbaje în graful și diagrama Venn din figura 6.15.

Figura 6.15: Ilustrarea rezumat a relației limbajelor de rețele Petri cu clasele tradiționale de structuri de limbaje

Figura 6.16: Rezumatul proprietăților unora dintre limbajele de rețele Petri

Rezultate suplimentare

Multe dintre rezultatele prezentate aici au fost dezvoltate atât în [Peterson 1976] cât și în

[Hack 1975b]. În plus, Hack a cercetat un număr de probleme de decidabilitate pentru limbajele rețelelor Petri. Problema apartenenței [este un șir un element al unui limbaj L()?] este decidabilă, în timp ce problema vidității [este vid (gol) limbajul L()?] se poate vedea ușor că este echivalentă cu problema accesibilității. Este nedecidabil dacă două limbaje de rețele Petri sunt egale sau dacă unul este inclus în altul (problemele echivalenței și incluziunii).

Figura 6.17 rezumă aceste rezultate.

Figura 6.17: Tabel ce rezumă proprietățile decidabile ale limbajelor de tipul L și ale celor de tipul P (D înseamnă decidabil, N înseamnă nedecidabil).

O abordare diferită în studiul rețelelor Petri folosind teoria limbajelor formale a fost considerată de Crespi-Reghizzi și Mandrioli [1974]. Ei au observat similitudinea între declanșarea unei tranziții și aplicarea unei producții în derivare, gândindu-se la locații ca la niște neterminale și la jetoane ca la instanțe separate ale neterminalelor. Diferența principală este, desigur, lipsa informației de ordine care este conținută în forma sentențială a unei derivări. Astfel s-au definit gramaticile comutative care sunt izomorfe cu rețelele Petri.

Alte studii

Sunt trei studii importante asupra limbajelor rețelelor Petri. [Peterson 1976[, sau [Peterson

1977] este probabil cel mai simplu de înțeles deși [Hack 1975b] este un studiu mai riguros și mai complet. [Crespi-Reghizzi și Mandrioli 1977] este mai greu de găsit, dar cuprinde o muncă de cercetare excelentă, inventivă și bine explicată.

Deși s-a început bine în cercetarea proprietăților limbajelor rețelelor Petri, mai rămân încă multe de făcut. Dintre clasele de limbaje care au fost definite, numai două, clasele de limbaje de tipul P și clasele de limbaje de tipul L, au fost studiate și acestea numai pentru rețele Petri generalizate. Au fost definite câteva submulțimi ale mulțimii de rețele Petri generalizate, incluzând graful marcajelor, rețele fără conflicte, rețele restricționate și rețele cu alegere liberă (free-choice), după cum se va vedea în capitolul 7. Fiecare dintre aceste clase de rețele Petri are propria sa clasă de limbaje și propriile sale proprietăți distinctive.

S-au făcut anumite cercetări asupra acestor clase. Este cunoscut [Hack 1975b] că clasele L, L, G, G, P și P pentru rețele Petri restricționate [fără bucle, fără arce multiple; adică toate multiseturile sunt mulțimi, și pentru fiecare tj, I(tj) O(tj) = ] sunt identice cu clasele corespunzătoare pentru rețele Petri generalizate. De asemenea, nu este dificil de văzut că clasele L, G și P nu sunt schimbate prin restricționarea rețelelor la rețele cu alegere liberă (secțiunea 7.4.3). Cu toate acestea, rămân încă multe cazuri interesante de studiat. În particular, limbajele generate de grafuri de marcaje, sau de rețele fără conflicte, în general, par să aibă o structură care amintește de limbajele deterministe independente de context, iar studiul lor pare a fi foarte promițător.

O altă problemă deschisă importantă privește distincția dintre limbajele -libere (L, P,…) și limbajele nerestricționate (L, P,…). Spre exemplu, nu se știe dacă L = L, sau nu.

Modele de rețele Petri extinse sau restricționate

În capitolul 3 am arătat că rețelele Petri pot fi folosite pentru a modela o varietate mare de sisteme: componente hardware și software, chimice, sociale și așa mai departe. Totuși, această largă gamă de sisteme arată că rețelele Petri pot modela numai anumite sisteme și că pot exista sisteme care să nu poată fi modelate corect cu ajutorul rețelelor Petri. De aceea, s-ar putea să existe limitări ale puterii de modelare a rețelelor Petri.

În plus, în capitolul 5 am arătat că nu toate secvențele de analiză sunt decidabile pentru rețelele Petri. Problemele incluziunii și echivalenței pentru mulțimi accesibile ale rețelelor Petri și pentru limbaje de rețele Petri sunt nedecidabile, dar aceste probleme pot fi fosrte importante pentru a produce rețele Petri optime. Chiar și acele întrebări de analiză care sunt decidabile sunt foarte dificile, în sensul că ele necesită o cantitate de memorie pentru calcule.

În acest capitol cercetăm sugestiile care au fost făcute pentru a depăși aceste două limitări ale rețelelor Petri: limitarea puterii de modelare și limitarea puterii de decizie. Ne vom ocupa mai întâi de unele sugestii de extensii ale modelului de rețea Petri. Extinderea modelului de rețea Petri ar trebui să crească puterea de modelare a rețelelor Petri, dar, de asemenea, ar putea să micșoreze puterea de decizie a acestora. Efectele oricărei extensii asupra puterii de decizie a modelului extins trebuie luate în considerare cu mare atenție.

După cum modelele de rețea Petri extinse tind să reducă puterea de decizie, tot la fel puterea de decizie poate fi mărită restricționând modelul de rețea Petri. S-au sugerat numeroase subclase ale modelului de rețea Petri. Aceste modele sunt produse prin restricții asupra structurii rețelei Petri. Trebuie să cercetăm efectul acestor restricționări atât asupra puterii de modelare cât și asupra puterii de decizie.

Această cercetare arată cum pot fi tratate puterea de modelare și decizie, pentru a se realiza un echilibru, și de asemenea indică limitele amândoura pentru modelul de rețea Petri.

Limitări ale modelării cu ajutorul rețelelor Petri

Câteva cercetări care au folosit rețelele Petri pentru a modela sisteme au găsit că este foarte simplu și relativ ușor de a modela astfel sisteme reale. Astfel, a existat o tendință marcantă de a extinde modelul pentru a-l face mai ușor de folosit. Aceste extensii au fost de câteva tipuri.

Patil [1970a] a sugerat extinderea rețelelor Petri astfel încât să includă constrângeri. O constrângere este o mulțime de locații. Mulțimea de tranziții care se declanșează este modificată pentru a permite tranzițiilor să se declanșeze dacă și numai dacă marcajul rezultat nu are toate locațiile care sunt într-o constrângere simultan marcate. Spre exemplu, dacă {p1, p4} este o constrângere, atunci fie p1, fie p4 trebuie să nu conțină niciodată nici un jeton. Dacă p1 este marcată, atunci nu se poate pune un jeton în p4 până când nu sunt scoase toate jetoanele din p1, și invers.

Noe, în modelul său pentru sistemul de operare CDC 6400 [Noe 1971], a introdus o extensie diferită: tranziția SAU-exclusiv (figura 7.1).

Figura 7.1: O tranziție SAU-exclusiv.

Tranziția tj se poate declanșa numai dacă fie pi fie pk are un jeton și cealaltă nu

În mod normal, o tranziție a unei rețele Petri se declanșează când toate intrările sale conțin jetoane; aceasta se numește ȘI-logic, de vreme ce trebuie să avem jetoane și în prima, și în a doua, și în a treia, și în toate intrările. Tranziția SAU-exclusiv se poate declanșa dacă și numai dacă una numai una dintre intrările sale conține jetoane, iar restul nu. Astfel, regula de funcționare este ca prima intrare să aibă un jeton, sau a doua intrare să aibă un jeton (dar nu amândouă). Când tranziția se declanșează, mută un jeton numai din intrarea care conținea jetoane.

O extensie similară a fost folosită de Baer în modelul său pentru un compilator [Baer 1973b]. Baer a introdus comutatoarele (figura 7.2). Un comutator este o tranziție specială cu o intrare specială numită intrare switch și cu exact două ieșiri (una etichetată cu e, de la empty (gol) și cealaltă etichetată cu f, de la full (plin)). O tranziție comutator se declanșează când este permisă (ignorând starea intrărilor speciale).

Figura 7.2: Declanșarea unei tranziții comutator. Locația în formă de săgeată reprezintă intrarea comutator. (a) Comutator gol (b) Comutator plin

La declanșare, se pune un jeton în ieșirea etichetată cu e, dacă intrarea comutatorului este goală, sau în cea etichetată cu f, dacă intrarea comutatorului este plină. Astfel, declanșarea unei tranziții comutator va da naștere la unul sau la două marcaje, în funcție de starea comutatorului. Un jeton este mutat din intrarea comutatorului, dacă are unul, astfel încât aceasta devine goală (vidă) după declanșarea tranziției comutator.

Aceste extensii ale rețelelor Petri au fost create pentru a rezolva anumite probleme pe care cercetătorii le-au întâlnit în încercările lor de a modela sisteme reale. Totuși, principala preocupare a muncii lor a fost modelarea, nu puterea teoretică a rețelelor Petri, astfel că nu s-a făcut nici o încercare de a arăta dacă aceste extensii sunt necesare sau suficiente pentru a mânui probleme generale de modelare. De fapt, în toate aceste cazuri, rețelele implicate erau sigure, și de aceea mulțimea de accesibilitate este finită, adică aceste rețele pot fi reprezentate ca automate cu stări finite, care am văzut (capitolul 3.3.1) că pot fi reprezentate cu ușurință ca rețele Petri obișnuite. Astfel, în aceste cazuri, aceste „extensii” nu sunt necesare, deși sunt convenabile. Am văzut de asemenea în capitolul 5.3 că multe extensii ale modelului de rețea Petri restricționat, precum arce multiple și bucle, nu sunt de fapt extensii, dar sunt utile.

Rămâne astfel întrebarea: dacă există, care sunt limitările rețelelor Petri? Răspunsul la această întrebare a fost găsit ca urmare a studiului unor întrebări similare asupra operațiilor lui Dijkstra, P și V, cu semafoare.

Dijkstra a definit operațiile P și V cu semafoare pentru a facilita coordonarea și comunicațiile în sisteme cu procese concurente [Dijkstra 1968]. Un semafor poate fi gândit ca o variabilă întreagă care ia numai valori nenegative. O operație V a unui semafor S mărește valoarea semaforului cu unu, adică S = S + 1. Operația P a unui semafor, pe de altă parte, micșorează S cu unu atâta timp cât rezultatul este un număr nenegativ; sistemul trebuie să aștepte până când S poate fi decrementat înainte de a continua. Relația dintre semafoare și rețelele Petri a fost examinată în capitolul 3.4.8.

De vreme ce operațiile P și V au fost propuse ca mecanismul pentru rezolvarea tuturor problemelor de coordonare între programe, apar în mod natural întrebări referitoare la completitudinea lor, adică întrebări referitoare la capacitatea lor de a rezolva toate problemele de coordonare ce pot apărea. Patil [1971] a demonstrat că operațiile P și V nu sunt suficient de puternice pentru a demonstra toate problemele de coordonare. Abordarea lui a fost chiar simplă: a creat o problemă de coordonare care nu a putut fi rezolvată cu ajutorul operațiilor P și V. Problema pusă a fost problema fumătorilor de țigări.

Problema fumătorilor de țigări constă din (cel puțin) patru procese: un agent și trei fumători. Fiecare fumător face în mod continuu câte o țigară și o fumează. Dar, pentru a face o țigară sunt necesare trei ingrediente: tabac, hârtie și chibrituri. Unul dintre procese are hârtie, un altul tabac și al treilea are chibrituri. Agentul are un depozit infinit din toate cele trei ingrediente. Agentul pune două dintre ingrediente pe masă. Fumătorul care capătă astfel cel de-al treilea ingredient poate face o țigară, s-o fumeze și să semnalizeze agentul după ce o termină de fumat. În acest moment agentul pune pe masă alte două din cele trei ingrediente și ciclul se repetă.

În termeni de semafoare, problema se pune asociind un semafor cu fiecare ingredient. Aceste semafoare sunt inițial zero. Agentul va incrementa două dintre cele trei semafoare cu ajutorul operației V, și apoi va aștepta un semafor „gata”. Procesul corespunzător trebuie să decrementeze cele două semafoare (cu ajutorul operației P), să facă și să fumeze țigara și să incrementeze semaforul „gata”. Problema este definirea codului proceselor astfel încât să se poată determina care dintre cele trei procese ar trebui să acționeze; agentul este fix și nu poate fi schimbat.

Figura 7.3 ilustrează „soluția” evidentă. Problema cu această „soluție” este simplă: presupunem că agentul pune pe masă tabac și hârtie [V(t); V(p)]. Apoi, fumătorul cu hârtia poate lua tabacul [P(t)] și fumătorul cu tabacul poate lua hârtia [P(p)], dând naștere la o interblocare. Patil a demonstrat că uneori nu există nici o secvență de operații P și V care să poată rezolva această problemă, demonstrând că deși toate „soluțiile” obținute cu ajutorul operațiilor P și V pot fi modelate ca rețele Petri de un anumit tip (fiecare tranziție are cel mult două intrări), soluția este o rețea Petri de un alt tip, și că nu este posibil să se convertească o rețea de un tip într-o rețea din celălalt tip fără a exista pericolul interblocării.

Figura 7.3: Problema fumătorilor de țigări

Acestea au fost problemele cu soluția lui Patil – ce lucrează în mod special cu tablouri de semafoare (vezi [Parnas 1972]) – dar conceptul este corect. Kosaraju [1973] și Argewola și Flynn [1973] au continuat munca lui Patil pentru a produce o problemă care să nu poată fi rezolvată cu operații P și V, sau cu rețele Petri. Această limitare a fost descoperită mai devreme de către Keller [1972].

Problema găsită de Kosaraju, Argewala și Flynn este cât se poate de reală. Presupunem că avem două procese producător și două procese consumator. Procesul producător P1 creează articole pentru primul proces consumator C1, iar celălalt proces producător, P2, produce pentru cel de-al doilea proces consumator, C2. Articolele care sunt produse, dar nu sunt încă consumate, sunt puse într-un buffer, și anume în bufferul B1 pentru (P1, C1) și în bufferul B2 pentru (P2, C2). Transmisia de la buffere către consumatori se face printr-un canal distribuit. Canalul poate transmite un singur articol la un anumit moment de timp, dar poate transmite de la orice buffer către orice consumator. Producătorii numai pun articole în buffere; consumatorii trebuie să coordoneze folosirea canalului în comun. Consumatorul ce deține controlul spune canalului să aducă un articol de la bufferul corespunzător.

Problema principală cu acest sistem este alocarea canalului. Perechea producător-consumator (P1, C1) se cere să aibă prioritate față de perechea (P2, C2) în folosirea canalului. De aceea, canalul nu este niciodată folosit pentru a transmite articole de la bufferul B2 la consumatorul C2 atâta timp cât bufferul B1 nu este gol.

Toate acestea sunt schițate în figura 7.4.

Figura 7.4: Modelul producător /consumator cu buffer și canal distribuit

Această regulă de prioritate face ca acest sistem să nu poată fi modelat cu o rețea Petri. Demonstrația este relativ simplă. Să presupunem că suntem într-o stare cu articole atât în bufferul B1 cât și în bufferul B2. Acum, dacă producătorul P1 ia o pauză, atunci ar putea apărea eventual cazul în care toate articolele din bufferul B1 au fost transmise consumatorului C1, astfel încât bufferul B1 este gol. Această situație va permite ca un articol din bufferul B2 să fie adus la consumatorul C2. Astfel, există un drum de la la o stare ’ în care consumatorul C2 poate folosi canalul.

Acum, dacă din contră producătorul P1 produce k articole în plus, vom fi în starea + k, mai degrabă decât în starea . Dar, datorită naturii permisive a declanșărilor în rețelele Petri, secvența de declanșări care ne conduce din starea în starea ’ va fi încă posibilă și ne va duce din starea + k în starea ’ + k. Deoarece consumatorul i poate folosi canalul în ’ și rețelele Petri sunt permisive, consumatorul C2 poate să folosească în continuare canalul, în ciuda prezenței celor k articole în bufferul B1. Astfel, natura permisivă a declanșărilor într-o rețea Petri nu permite acestui sistem de priorități să fie modelat corect.

Mai precis, limitarea modelării cu ajutorul rețelelor Petri constă în incapacitatea de a testa pentru un exact anume marcaj într-o locație nemărginită și a executa o acțiune la sfârșitul testului. Acest fapt se formulează în general ca o incapacitate de a testa pentru un marcaj zero într-o locație, și astfel această proprietate este cunoscută sub numele de testul zero [Keller 1972]. Rețelele Petri nu pot testa o locație nemărginită pentru un marcaj zero. [Dacă locația este mărginită, se poate face testul pentru marcajul zero. Pentru o locație mărginită pi cu marginea k, putem crea o locație complementară astfel încât suma (pi) + () să fie constantă k pentru toate marcajele accesibile. Aceasta ne permite să testăm dacă (pi) este zero testând dacă () este k (vezi capitolul 5.6).]

Extensii

Care este relația dintre aceste limitări ale modelării cu rețele Petri și extensiile pentru rețele

Petri care au fost sugerate? Toate extensiile sugerate au dorit să ofere rețelelor Petri abilitatea de a testa după marcajul zero.

Cele mai simple extensii la rețelele Petri care permit testarea după marcajul zero sunt arcele inhibitoare. Un arc inhibitor de la o locație pi la o tranziție tj este reprezentat printr-o linie cu un cerculeț în capăt în loc de o săgeată. Această notație este împrumutată din teoria comutatoarelor unde cerculețele înseamnă „nu”. Regula de declanșare este schimbată după cum urmează: o tranziție este activă când se află jetoane în toate intrările sale (normale) și nu se află nici un jeton în nici una din intrările sale inhibitoare. Tranziția se declanșează prin mutarea jetoanelor din toate intrările sale „normale”.

Astfel, în rețeaua Petri extinsă din figura 7.5 tranziția c2 se poate declanșa numai dacă se află câte un jeton în b2 și p4 și nici unul în b1. Această rețea este o soluție la problema priorității în canalul distribuit pe care Kosaraju l-a definit pentru a arăta limitările rețelelor Petri.

Figura 7.5: O rețea Petri extinsă cu un arc inhibitor

Rețelele Petri cu arce inhibitoare sunt intuitiv cea mai directă abordare pentru creșterea puterii de modelare a rețelelor Petri. De asemenea, toate celelalte extensii ale rețelelor Petri care au fost sugerate, fie nu sunt într-adevăr extensii (ci sunt de fapt echivalente cu rețelele Petri obișnuite), fie sunt echivalente cu rețelele Petri cu arce inhibitoare. Pentru a ilustra aceste lucruri, vom discuta mai jos câteva dintre extensiile sugerate.

Restricții

Restricțiile au fost propuse de Patil [1970a] pentru a îmbunătăți puterea de modelare a rețelelor Petri. În contextul propus de Patil, restricțiile aveau numai rolul de a face modelarea mai ușoară și nu de a mări puterea de modelare, deoarece în munca lui Patil, toate locațiile erau mărginite. Totuși, restricțiile definite nu se limitează la rețelele Petri mărginite, și pentru clase de rețele Petri mai generale, sunt echivalente cu arcele inhibitoare.

Pentru a arăta echivalența restricțiilor cu arcele inhibitoare presupunem că avem o rețea Petri C = (P, T, I, O) cu o restricție Q P. Trebuie să ne asigurăm că toate locațiile din Q nu sunt marcate în nici un marcaj accesibil. Singura modalitate prin care toate locațiile din Q ar pute fi marcate ar fi prin declanșarea unei tranziții tj care să pună jetoane în acele locații din restricție care nu erau marcate înainte de declanșarea tranziției. Astfel, pentru fiecare tranziție tj cu locații de ieșire care sunt în restricție, trebuie să ne asigurăm că, după declanșarea tranziției, cel puțin unul din membrii constrângerii nu va fi marcat. Pentru aceasta, creăm o nouă tranziție tj,k pentru fiecare locație pk din restricția Q care nu este în Q(tj). Tranziția tj,k este identică cu tranziția tj cu excepția faptului că mai are în plus un arc inhibitor de la pk la tj,k. Efectul declanșării tranziției tj,k este același cu al declanșării tranziției tj, și dacă tj poate fi declanșată fără violarea unei restricții, atunci se poate declanșa cel puțin una dintre tranzițiile tj,k.

Pentru a exemplifica pentru această construcție, considerăm rețeaua Petri din figura 7.6. Dacă impunem restricția {p3, p7} (adică, p3 și p7 nu pot fi simultan marcate în nici un marcaj), atunci rețeaua Petri echivalentă cu arce inhibitoare este arătată în figura 7.7.

Transformarea de la arce inhibitoare la restricții este ceva mai dificilă. Nu putem doar să spunem că nici o ieșire a unei tranziții nu poate fi marcată în același timp ca intrare inhibitoare, deoarece există alte tranziții care pot pune jetoane în ieșiri. De aceea, trebuie să ne concentrăm asupra tranzițiilor. Aceasta presupune divizarea fiecărei tranziții tj în două tranziții și și o locație . Definim I() = I(tj) (fără arce inhibitoare) și O() = O(tj). Locația reprezintă declanșarea tranziției tj, deci O() = {} = I(). Acest fapt este ilustrat în figura 7.8. Acum, pentru fiecare locație pi care este o intrare inhibitoare pentru tj, definim o restricție {pj, }. Acesta ne asigură că tranziția nu se poate declanșa dacă marcajul lui pi este diferit de zero.

Figura 7.8: Convertirea unei tranziții într-o tranziție de început și una de final și o locație reprezentând declanșarea tranziției

Tranziții SAU-exclusiv și comutatoare

O tranziție SAU-exclusiv tj cu intrarea I(tj) cere ca una și numai una dintre intrările sale să fie zero pentru a se activa. Acest fapt este echivalent cu o mulțime de tranziții, una pentru fiecare element din I(tj). Fiecare tranziție are o intrare (normală) și restul intrărilor sunt arce inhibitoare. Figura 7.9 este un astfel de exemplu.

Figura7.9: Convertirea (a) unei tranziții SAU-exclusiv (b) în arce inhibitoare

Comutatoarele pot fi de asemenea transformate cu ușurință în arce inhibitoare. Acest fapt este ilustrat în figura 7.10.

Figura 7.10: Convertirea (a) comutatoarelor în (b) rețele Petri cu arce inhibitoare

Nu este imediat evident cum arcele inhibitoare pot fi convertite în comutatoare sau în tranziții SAU-exclusiv, dar este sigur că acest lucru este posibil.

Alte extensii

Au mai fost sugerate alte două alte extensii importante ale rețelelor Petri. Tranzițiilor li se pot asocia priorități astfel încât dacă tj și tk sunt amândouă active, să se declanșeze mai întâi tranziția cu prioritatea cea mai ridicată [Hack 1975c]. Rețelele Petri cu timp atașat [Merlin 1974] asociază fiecărei tranziții tj doi timpi, 1,j și 2,j. O tranziție tj se poate declanșa numai dacă a fost activată cel târziu la momentul 1,j și, de asemenea, trebuie să se declanșeze înainte de momentul 2,j, dacă este activă. Amândouă aceste extensii pot fi folosite pentru a testa după marcajul zero.

În cazul priorităților, putem testa cu ușurință dacă o locație p este zero. Această situație este ilustrată în figura 7.11. Dacă punem un jeton în locația p = 0? și definim prioritatea tranziției t1 mai mare decât prioritatea tranziției t2, atunci vom obține un jeton într-una din cele două locații din dreapta în funcție de marcajul locației p. Aceasta rezultă din faptul că tranziția t1 se poate declanșa numai dacă este activă, și este activă numai dacă în locația p se află un jeton. Tranziția t2 se poate activa numai în cazul în care tranziția t1 nu se poate activa deoarece locația p este goală.

Figura 7.11: Folosirea priorităților pentru a testa dacă marcajul unei locații p este zero sau nu. Tranziția t1 are prioritate asupra tranziției t2.

Hack a realizat construcții complete pentru convertirea rețelelor Petri cu priorități în rețele Petri cu arce inhibitoare și viceversa [Hack 1975a]. Rețelele Petri cu timp atașat pot să testeze de asemenea o locație pentru zero simulând priorități. Dacă avem două tranziții tj și tk și setăm 2,j < 1,k, atunci tranziția tj are prioritate asupra tranziției tk deoarece tj trebuie să se declanșeze (dacă este activă) înainte să i se permită tranziției tk să se declanșeze.

Rețele Petri extinse și dispozitive de recunoaștere (Register Machines)

Am arătat că toate extensiile sugerate permit testarea pentru marcajul zero. Cum este acest lucru important pentru puterea de decizie a unei rețele Petri? Afectează acest lucru abilitatea de a analiza rețelele Petri?

Testarea pentru marcajul zero micșorează puterea de decizie a rețelelor Petri. Argewala [1974a], Hack [1975c], Thomas [1976] și alții au arătat că adăugarea la o rețea Petri a capacității de a testa pentru marcajul zero permite rețelei Petri să simuleze o mașină Turing.

Astfel, o rețea Petri care are capacitatea de a testa pentru marcajul zero produce o schemă de modelare care poate modela orice sistem. În acest caz însă aproape toate întrebările de analiză pentru rețele Petri devin nedecidabile, deoarece ele sunt nedecidabile pentru mașini Turing.

Demonstrația echivalenței dintre rețelele Petri extinse și mașinile Turing este relativ simplă și mai ușor de dat în termeni de dispozitive de recunoaștere [Shepardson și Sturgis 1963] sau mașini cu program [Minsky 1967].

Un dispozitiv de recunoaștere este un dispozitiv ca un computer cu un număr de regiștrii care sunt folosiți pentru a memora arbitrar numere mari. Există un program scris pentru a manipula regiștrii. Programul este o succesiune de instrucțiuni precum „mărește registrul n cu 1”, „micșorează registrul n cu 1 (numai dacă registrul n nu este 0)”, „salt la instrucțiunea 5 dacă registrul n nu ete 0” și așa mai departe. De exemplu, în continuare este prezentat un program care adaugă conținutul registrului 2 la registrul 1.

Dacă registrul 2 este zero, mergi la instrucțiunea 5.

Scade 1 din registrul 2.

Adaugă 1 la registrul 1.

Mergi la instrucțiunea 1.

Halt.

Shepardson și Sturgis au arătat că un dispozitiv de recunoaștere cu următoarele instrucțiuni este echivalent cu o mașină Turing.

P(n): Mărește registrul n cu 1.

D(n): Micșorează registrul n cu 1 (registrul n nu este zero).

J(n)[s]: Salt la instrucțiunea s dacă registrul n este zero.

Astfel, dacă un dispozitiv de recunoaștere poate fi convertit într-o rețea Petri extinsă echivalentă, vedem că rețelele Petri extinse sunt echivalente cu dispozitivele de recunoaștere. Această conversie este relativ evidentă.

Pentru a reprezenta un dispozitiv de recunoaștere ca o rețea Petri extinsă, reprezentăm cei n regiștrii folosiți într-un program prin n locații, . De asemenea folosim s – 1 locații pentru a reprezenta poziția registrului de control înainte de instrucțiunea 1 (marcajul inițial), sau după instrucțiunea i, i = 1 … s, într-un program cu s instrucțiuni. Fiecare instrucțiune din program este reprezentată printr-o tranziție. Figura 7.12 arată cum va fi reprezentată într-o rețea Petri extinsă fiecare dintre cele trei instrucțiuni de mai sus.

Figura 7.12: Conversia unei instrucțiuni (la locația i) pentru un dispozitiv de recunoaștere la o tranziție într-o rețea Petri extinsă folosind arce inhibitoare. (a) P(n) (b) D(n) (c) J(n)[s]

Aceasta arată că un dispozitiv de recunoaștere poate fi poate fi convertit într-o rețea Petri extinsă și de aceea o rețea Petri extinsă este echivalentă cu o mașină Turing. Această echivalență cu mașinile Turing distruge orice speranță de a putea anliza rețelele Petri extinse, demonstrând totuși că rețelele Petri extinse pot modela orice sistem (sau cel puțin orice sistem calculabil). Astfel, observăm că o creștere a puterii de modelare, în acest caz, conduce la o scădere a puterii de decizie.

De asemenea observăm că punctul cheie în demonstrarea echivalenței rețelelor Petri extinse cu dispozitivele de recunoaștere și cu mașinile Turing este capacitatea de a testa pentru marcajul zero o singură locație. Astfel, toate extensiile care au fost sugerate – restricții, tranziții SAU-exclusiv, comutatoare, priorități, timpi și arce inhibitoare – extind modelul de rețea Petri la nivel de mașini Turing.

Au fost și alte sugestii pentru extinderea rețelelor Petri care nu au adus rețelele Petri la nivel de mașini Turing. Inițial s-au sugerat ca extensii buclele, intrările multiple și arcele de ieșire, dar, așa cum se vede din capitolul 5.3, rețelele extinse astfel sunt echivalente de fapt cu rețelele Petri restricționate. Similar, permițând intrări SAU-inclusiv, ieșiri SAU-inclusiv, sau ieșiri SAU-exclusiv nu se produce o creștere a puterii de modelare a rețelelor Petri.

În general, se pare că orice extensie care nu permite testarea pentru marcajul zero nu va crește de fapt puterea de modelare (sau nu va scădea puterea de decizie) a rețelelor Petri, ci numai va da naștere unei alte formulări echivalente a modelului de bază al rețelelor Petri (Se pote ca astfel să se ușureze modelarea.) În același timp, orice extensie care permite testarea pentru marcajul zero va mări puterea de modelare la nivelul mașinilor Turing și va scădea la zero puterea de decizie. Prin urmare, extensiile rețelelor Petri au puține avantaje practice în analize.

Subclase de rețele Petri

Obiectivul extinderii rețelelor Petri este mărirea puterii de modelare; un efect lateral nefericit este acela că puterea de decizie a rețelelor Petri extinse este mult redusă. Puterea de decizie a rețelelor Petri normale are o valoare acceptabilă datorită complexității și costului (Rezultate despre complexitatea problemelor de accesibilitate și mărginire se află în capitolul 5.8.). Aceasta a dat naștere cercetării câtorva subclase ale rețelelor Petri. Obiectivul acestor studii este de a determina restricționări structurale rezonabile ale rețelelor Petri care vor crește puterea de decizie a modelelor de rețele Petri restricționate fără să restricționeze esențial puterea de modelare.

Se pot face multe cu subclasele rețelelor Petri. Scopul acestei părți a cercetării rețelelor Petri este simplu. Definim o subclasă a rețelelor Petri care poate modela o gamă largă de sisteme (toate sau aproape toate interesante) și care totuși păstrează proceduri simple de analiză (cel puțin pentru problemele interesante). Este de asemenea necesar să existe un test simplu pentru a determina dacă este un sistem este membru al subclasei definite. Subclasele care au fost definite sunt toate subclase sintactice sau structurale; putem cu ușurință examina o structură de rețea Petri pentru a determina dacă este membru al subclasei specificate. Aceste subclase sunt diferite de cele ce pot fi definite în concordanță cu proprietățile dinamice, cum sunt, spre exemplu, rețelele Petri persistente [Landweber și Robertson 1975] sau rețelele Petri mărginite. Aceste clase pot avea proprietăți foarte interesante, dar s-ar putea să fie foarte dificil de determinat dacă o rețea Petri arbitrară dată este o rețea Petri persistentă sau mărginită.

Au fost intens studiate numai două subclase importante ale rețelelor Petri: mașini de stare și grafuri marcate. În plus, Hack [1972] a studiat o subclasă numită rețele Petri cu alegere liberă și a sugerat că o altă subclasă, rețele Petri simple, ar putea avea proprietăți bune de decizie. Prezentăm fiecare dintre aceste clase și indicăm proprietățile lor cele mai importante, avantaje și dezavantaje.

Mașini de stare

O mașină de stare este o rețea Petri în care fiecare tranziție este restricționată să aibă exact o intrare și exact o ieșire.

Definiția 7.1:

O mașină de stare este o rețea Petri C = (P, T, I, O) astfel încât pentru fiecare tj T, |I(tj)| = 1 și |O(tj)| = 1.

Câteva proprietăți ale mașinilor de stare sunt imediat evidente. Mai întâi, o mașină de stare este strict conservativă. Aceasta înseamnă că numărul de jetoane dintr-o mașină de stare nu se schimbă niciodată, dând naștere unui sistem finit. Prin urmare, arborele de accesibilitate pentru o mașină de stare este finit, și de aceea toate întrebările de analiză sunt decidabile pentru mașinile de stare. De fapt, o mașină de stare este echivalentă cu un automat cu stări finite din teoria automatelor și a limbajelor formale (vezi capitolul 3.3.1). Astfel, aceste modele sunt de interes redus în ciuda puterii mari de decizie, datorită puterii mărginite de modelare a automatelor cu stări finite.

Grafuri marcate

O altă subclasă a rețelelor Petri care este des menționată în literatură este clasa grafurilor marcate. Un graf marcat este o rețea Petri în care fiecare locație este intrare pentru exact o tranziție și ieșire pentru exact o tranziție. Alternativ, putem spune că fiecare locație are exact o intrare și o ieșire.

Definiția 7.2:

Un graf marcat este o rețea Petri C = (P, T, I, O) astfel încât pentru fiecare pi P, |I(pi)| = |{tj | pi O(tj)}| = 1 și |O(pi)| = |{tj | pi I(tj)}| = 1.

Grafurile marcate sunt dualele mașinilor de stare (într-o reutilizare a cuvântului din teoria grafurilor), deoarece în cazul mașinilor de stare tranzițiile au o singură intrare și o singură ieșire, în timp ce în cazul grafurilor de stare cele care au o singură intrare și o singură ieșire sunt locațiile. Sunt de asemenea duale din punctul de vedere al modelării. O mașină de stare poate cu ușurință reprezenta conflicte printr-o locație cu câteva ieșiri dar nu poate modela crearea jetoanelor necesare pentru a modela concurența sau așteptarea care caracterizează sincronizarea. Grafurile marcate, pe de altă parte, pot modela concurența și sincronizarea dar nu pot modela conflicte sau decizii dependente de date.

Proprietățile care au fost cercetate pentru grafurile marcate au fost viabilitatea, siguranța și accesibilitatea. În cercetarea acestor proprietăți, partea structurală majoră a unui graf marcat de interes sunt ciclurile acestuia. Un ciclu într-un graf marcat este o secvență de tranziții astfel încât pentru fiecare și din secvență există o locație cu O(), I() și . Un ciclu este astfel un drum închis de la o tranziție înapoi la aceeași tranziție.

De exemplu, în graful marcat din figura 7.13 secvența t1 t2 t1 este un ciclu, la fel ca și secvențele t4 t3 t4 și t2 t4 t3 t1 t2.

Figura 7.13: Un graf marcat

Importanța ciclurilor pentru grafurile marcate derivă din următoarea teoremă:

Teorema 7.1:

Numărul de jetoane dintr-un ciclu al unui graf marcat nu se schimbă în urma declanșării tranzițiilor.

Cu ajutorul acestei teoreme se arată ușor următoarele:

Teorema 7.2:

Un marcaj este activ dacă și numai dacă numărul de jetoane din fiecare ciclu al grafului marcat este cel puțin 1.

Teorema 7.3:

Un marcaj activ este sigur dacă și numai dacă fiecare locație din graful marcat este într-un ciclu cu un jeton.

Aceste teoreme oferă o cale simplă și ușoară de a inspecta structura unui graf marcat și de a determina din structură și din marcajul inițial dacă graful marcat este activ și sigur. Se poate de asemenea arăta că problema accesibilității pentru marcajele unui graf marcat este decidabilă.

Teorema 7.4:

Într-un graf marcat tare conex, un marcaj ’ este accesibil dintr-un marcaj activ dacă numărul total de jetoane din fiecare ciclu al grafului marcat este același atât în cât și în ’.

Puterea mare de decizie a grafurilor marcate este evidentă din teoremele de mai sus și din studiile dedicate subiectului [Holt și Commoner 1970; Commoner et. al. 1971; Genrich și Lautenbach 1973; Izbicki 1973; Murata 1977b]. Cum însă există un echilibru între puterea de decizie și puterea de modelare, puterea mare de decizie a grafurilor marcate rezultă în parte din puterea scăzută de modelare. Astfel, cercetătorii au încercat să dezvolte o altă subclasă a rețelelor Petri care să păstreze puterea mare de decizie a grafurilor marcate și să crească în același timp puterea de modelare.

Rețele Petri cu alegere liberă

Hack, în lucrarea sa de master la M.I.T. [Hack 1972], a definit și a investigat o subclasă a rețelelor Petri numită clasa rețelelor Petri cu alegere liberă. Această clasă modelează atât conflictele mașinilor de stare cât și concurența grafurilor marcate, dar într-o manieră mai restrânsă decât în modelul general de rețea Petri.

Definiția 7.3:

O rețea Petri cu alegere liberă este o rețea Petri C = (P, T, I, O) astfel încât pentru fiecare tj T și pi I(tj), sau I(tj) = {pi} sau |O(tj)| = {pi}.

Importanța acestei definiții este dată de modul în care permite controlul conflictelor. Conflicte apar numai atunci când o locație este intrare pentru mai multe tranziții. Prin modul în care au fost definite rețelele Petri cu alegere liberă, dacă o locație este intrare pentru mai multe tranziții (conflict potențial), atunci este singura intrare pentru toate aceste tranziții. De aceea, fie toate aceste tranziții conflictuale sunt simultan active, fie nu este nici una. Aceasta permite ca alegerea (pentru rezolvarea conflictului) tranziției care să se declanșeze să se facă liber; prezența altor jetoane în alte locații nu influențează alegerea tranziției care să se declanșeze.

Această formă restricționată de conflict i-a permis lui Hack să demonstreze condițiile necesare și suficiente pentru ca o rețea Petri cu alegere liberă să fie activă și sigură. Condiția de viabilitate este legată de marcarea capcanelor și blocărilor din rețea.

O capcană este o mulțime de locații astfel încât fiecare tranziție care are locația de intrare în această mulțime are și locația de ieșire tot în această mulțime. Aceasta înseamnă că odată ce una dintre locațiile unei capcane are un jeton, va exista întotdeauna un jeton în una din locațiile capcanei. Declanșările de tranziții pot să mute jetonul între locații, dar nu pot să scoată jetonul din capcană.

O mulțime de blocare definitivă (deadlock) este o mulțime de locații astfel încât fiecare tranziție care are locația de ieșire în această mulțime are și locația de intrare tot în această mulțime. Aceasta înseamnă că odată ce toate locațiile din mulțime devin nemarcate nici o tranziție nu mai poată să pună jetoane în locațiile din această mulțime deoarece nu mai există nici un jeton aici care să activeze o tranziție cu ieșire tot aici.

Hack a demonstrat că o condiție necesară și suficientă pentru viabilitate într-o rețea Petri marcată cu alegere liberă este ca fiecare mulțime de blocare definitivă să conțină o capcană marcată. Această teoremă se bazează pe studiile lui Commoner [Commoner 1972, Hack 1972]. Condițiile necesare și suficiente pentru siguranță implică demonstrarea faptului că rețeaua Petri cu alegere liberă este acoperită de o reuniune de mașini de stare. Detalii se pot găsi în Hack [1972].

Rețele Petri simple

Hack a definit de asemenea o altă clasă a rețelelor Petri numită clasa rețelelor Petri simple [Hack 1972]. Rețelele simple presupun ca fiecare tranziție să aibă cel mult o locație de intrare comună cu intrarea altei tranziții servind astfel și la restricționarea modului în care pot apărea conflicte. Nu s-a făcut nici o cercetare asupra proprietăților acestei subclase a rețelelor Petri.

Figura 7.14: Un grafic ce indică unele dintre configurațiile structurale permise și nepermise pentru unele subclase de rețele Petri

Modele înrudite pentru calculul paralel

Rețelele Petri au fost definite ca modele ale sistemelor concurente. După cum am văzut, rețelele Petri au o bună putere de modelare, fiind capabile să modeleze o gamă largă de sisteme. Totuși, rețelele Petri nu sunt singurul model pentru calculul paralel; s-au definit, cercetat și folosit de asemenea și alte modele. În acest capitol, prezentăm unele din aceste modele și examinăm relația dintre acestea și rețelele Petri. Scopul acestui capitol este de a sugera varietatea de modele care pot fi folosite în modelarea sistemului și puterea relativă de modelare a modelelor.

O problemă majoră care a apărut din dorința de a găsi relații între diversele modele este aceea de a stabili o metodă potrivită pentru a compara modelele calculului paralel. Vrem să putem să demonstrăm că un model A este „mai puțin puternic” decât un model B sau este „echivalent”. Noțiunile de echivalență și incluziune sunt de importanță critică aici.

S-au realizat câteva studii asupra relațiilor între diferitele modele. Cercetările lui Bredt [1970a], Boer [1973a] și Miller [1973] au ajutat la centralizarea descrierilor câtorva modele. În particular, Bredt a oferit o definiție generală a unei structuri centrale care permite ca diferitele modele să fie definite într-o manieră unitară. Aceasta a condus la rezultatele din [Peterson 1973] și [Peterson și Bredt 1974] care compară diferitele modele pentru a crea o ierarhie de modele, legate prin puterea lor de modelare. Separat, Argewala [1974b] a comparat o mulțime generoasă de modele și a produs o altă ierarhie cu o structură similară.

Rezultatele, atât ale lui Peterson și Bredt [1974] cât și ale lui Argewala [1974b], au fost obținute prin compararea limbajele modelelor. O clasă de modele A definește o clasă de limbaje L(A). Spunem că două clase de modele A și B sunt echivalente dacă L(A) = L(B). Aceasta înseamnă că pentru orice instanță a a unei clase de modele A cu limbajul L(a) există o instanță b a clasei B cu un limbaj identic L(a) = L(b).

Dacă limbajele caracterizează într-adevăr modelele, atunci ele sunt un instrument potrivit pentru a compara două clase de modele.

Totuși, după cum am văzut, nu este chiar evident cum să definim un limbaj pentru un model al calculului paralel. Cercetările limbajelor rețelelor Petri au dat naștere la 12 definiții diferite pentru limbaje, majoritatea dintre ele aparent distincte. Aceste limbaje diferite pot da naștere la relații diferite de echivalență și incluziune între modele. Pe de altă parte, dacă diferențele dintre modele sunt într-adevăr semnificative, s-ar putea să fie insensibile la variații (minore) în definirea echivalenței și incluziunii. Astfel, rezultatele diferite ale lui Argewala [1974b] și ale lui Peterson și Bredt [1974] sunt mai semnificative datorită definițiilor diferite folosite pentru relațiile de echivalență și incluziune.

Totuși aceasta nu înseamnă că aceste rezultate sunt dincolo de orice dispută. Lipton et. al. [1974] a comparat de asemenea un număr mare de modele ale calculului paralel și a ajuns la rezultate diferite. Această comparație se bazează pe o analiză detaliată a structurii spațiului stărilor instanțelor specifice unei clase de modele și astfel rezultatele obținute diferă semnificativ de cele ale lui Argewala [1974b] și ale lui ale lui Peterson și Bredt [1974].

Astfel, dat fiind faptul că există unele diferențe de opinie între cercetători despre cum ar trebui de comparat modelele, cum ar trebui să le comparăm? Ar fi mai bine să considerăm o abordare conservativă, și astfel să ne bazăm în comparațiile din acest capitol atât pe caracteristicile structurale cât și pe cele de comportament. Spunem că o clasă de modele A este de putere mai mică sau egală cu (inclusă în) o clasă de modele B dacă fiind dată o instanță a a clasei A există un algoritm pentru a crea o instanță b a clasei B astfel încât:

Fiecare componentă structurală a modelului a este reprezentată printr-o mulțime (mică) identificabilă de componente ale modelului b. Dimensiunea modelului b (numărul de părți) este în cel mai prost caz un multiplu constant al dimensiunii modelului a, cu constanta determinată de clasele de modele A și B și nu de instanțele a și b.

Orice secvență de acțiuni din a poate fi simulată de o secvență din b, cu lungimea secvenței din b cel mult un multiplu constant al lungimii secvenței din a.

Modelul b se blochează definitiv numai când modelul a o face. Un model se blochează definitiv dacă toate acțiunile devin imposibile.

Motivația acestor constrângeri ar trebui să fie relativ evidentă. Prima constrângere încearcă să stabilească numai dacă cele două modele sunt similare structural; a doua constrângere se asigură că cele două modele se comportă la fel. Totuși, nu cerem ca cele două modele să corespundă exact; este permis să reprezentăm o acțiune într-un model printr-o secvență (scurtă) de acțiuni din celălalt model sau o componentă (precum o locație sau o tranziție) printr-un (mic) multiset de componente. Astfel, o acțiune dintr-un model poate fi modelată printr-o secvență de două acțiuni din celălalt model. Ultima constrângere cere ca modelul cel mai puternic să nu poată face o greșeală atunci când cel mai puțin puternic nu face. Aceasta permite construirea unui model care alege nedeterminist o acțiune din mai multe și anulează singur alegerea dacă găsește că aceasta nu este cea potrivită.

Două modele sunt echivalente dacă fiecare îl include pe celălalt. Aceasta permite ca orice instanță a oricăruia dintre modele să fie convertită la o instanță a celuilalt model.

Cu aceste considerații în minte, vom considera acum relația dintre următoarele modele de calcul paralel:

Automate cu stări finite [Hopcraft și Ullman 1969; Bredt 1970b; Gilbert și Chandler 1972]

Grafuri marcate [Commoner et. al. 1971]

Grafuri computaționale [Karp și Miller 1966]

Sisteme P / V [Dijkstra 1968; Bruno et. al. 1972]

Sisteme „mesaj” [Riddle 1971]

Grafuri UCLA [Ciostelow 1971; Cerf et. al. 1971; Cerf 1972; Cerf et. al. 1972]

Sisteme de adunare a vectorilor [Karp și Miller 1968]

Sisteme de înlocuire a vectorilor [Keller 1972]

Rețele Petri extinse [capitolul 7]

Pentru fiecare clasă de modele definim mai întâi modelul și apoi dăm un exemplu. Discutăm apoi relațiile dintre acesta și alte modele ale calculului paralel.

Automate cu stări finite

Am văzut deja în capitolele 3.3.1 și 7.4.1 că automatele cu stări finite pot fi cu ușurință transformate în rețele Petri. Automatele cu stări finite au fost folosite de câțiva cercetători ca model pentru calculul paralel. Bredt [1970a] a definit un model bazat pe componenta hardware a calculatorului. Fiecare procesor este modelat ca un automat cu stări finite cu linii de intrare și ieșire care conectează un procesor la alți procesori. Starea fiecărei linii de intrare și ieșire este 0 sau 1. De vreme ce fiecare linie de ieșire pentru un procesor este linie de intrare pentru alt procesor și există un număr finit de procesori și un număr finit de linii fiecare cu o stare finită, întregul sistem este unul cu stări finite.

Gilbert și Chandler [1972] au folosit un model cu memorie comună în loc de unul cu linii de comunicare. Aceasta înseamnă că modelul lor este orientat mai mult înspre modelarea proceselor software cu memorie comună decât înspre modelul bazat pe componenta hardware al lui Bredt. Acest model este însă unul cu stări finite și de aceea inclus în modelul de rețea Petri.

Grafuri marcate

Grafurile marcate au fost discutate în capitolul 7.4.2. Ca o subclasă a rețelelor Petri, grafurile marcate au evident o putere mai mică de modelare decât rețelele Petri. Grafurile marcate nu sunt direct comparabile cu automatele cu stări finite. Se obțin astfel relațiile din figura 8.1 dintre rețelele Petri, automatele cu stări finite și grafurile marcate.

Figura 8.1: Relațiile dintre rețelele Petri, automatele cu stări finite și grafurile marcate

Grafuri computaționale [Karp și Miller 1966]

Unul dintre primele modele ale calculului paralel a fost modelul grafului computațional [Karp și Miller 1966]. Acest model a fost în principal proiectat pentru a reprezenta execuția în paralel a expresiilor aritmetice programabile.

Un graf computațional G este definit printr-un graf orientat G = (V, A), unde V = {v1, …,vn} este o mulțime de vârfuri și A = {a1, …,am} este o mulțime de arce.

Fiecare arc ai A este o pereche ordonată de vârfuri (vj, vk) care reprezintă un arc de la vj la vk. Fiecărui arc ai = (vj, vk) i se asociază un cvadruplu (Ij,k, Vj,k, Wj,k, Tj,k). Fiecare arc reprezintă o coadă de date produse de procesor pentru nodul vj pentru a fi folosite de procesor pentru nodul vk. Ij,k dă numărul inițial de date din coadă pentru arcul de la vj la vk. Un nod vk este activ dacă sunt cel puțin Ij,k date pe fiecare arc orientat spre vk dinspre nodul vj. Tj,k este un prag. Operația asociată nodului vk se execută prin mutarea a Wj,k date din coadă (Wj,k Tj,k) pentru fiecare arc îndreptat spre vk. Când funcționarea pentru vk se termină, pune vk,r date în coada asociată fiecărui arc (vk, vr) îndreptat de la un nod vk la un nod vr. Figura 8.2 este un exemplu de graf computațional. În starea inițială, nodul v1 este activat, de vreme ce are o intrare și această intrare are trei date în coada sa. Când v1 se execută mută un articol din acestă coadă și după terminare pune un articol pe arcul de la v1 la v2. În această nouă stare se pot executa fie v1, fie v2 de vreme ce fiecare dintre ele au în coada atașată suficiente articole pentru a-și satisface pragurile.

Figura 8.2: Un graf computațional

Un graf computațional este ușor de modelat ca o rețea Petri. Fiecare arc este reprezentat printr-o locație, și fiecare nod al grafului computațional devine o tranziție. Tranziția corespunzătoare nodului vk are Tj,k arce de intrare din locația ce reprezintă un arc de la vj la vk. Acest fapt ne asigură că tranziția este activă numai dacă este atins pragul. Totuși, când tranziția se declanșează poate să mute numai Wj,k din aceste jetoane, astfel că de la tranziția vk la locația reprezentând arcul de la vj la vk sunt Tj,k – Wj,k arce direcționate. În plus, se pun Vk,r jetoane în locații reprezentând arce de la nodul vk la nodul vr. Marcajul inițial este determinat de Ij,k, după cum puteam să ne așteptăm.

Figura 8.3 arată rețeaua Petri construită astfel din graful computațional din figura 8.2.

Figura 8.3: O rețea Petri echivalentă cu graful computațional din figura 8.2

După o scurtă privire se poate observa că grafurile marcate pot fi modelate ca grafuri computaționale cu Tj,k = Wj,k pentru toate nodurile vj = vk. Totuși, grafurile computaționale sunt mai puternice decât grafurile marcate din cauză că pot avea Tj,k > Wj,k.

Pe de altă parte, grafurile cu stări finite și automatele cu stări finite sunt incomparabile, la fel cum sunt și grafurile marcate cu automatele cu stări finite. Grafurile computaționale nu pot să modeleze decizii sau execuții condiționate – aceeași limitare pe care o au și grafurile marcate.

Astfel, ierarhia modelelor în acest punct arată ca în figura 8.4.

Figura 8.4: Adăugarea grafurilor de calcul la ierarhie

Karp și Miller [1966] au cercetat grafurile computaționale, în special problemele legate de viabilitate și siguranță. De fapt, Karp și Miller erau interesați în a se asigura că un graf computațional va determina și nu va fi determinat de condițiile pentru ca un graf computațional să se termine (adică, să nu mai fie activ). Deoarece arcele (locațiile) reprezintă cozi de date, cercetările lui Karp și Miller asupra mărginirii se transmit asupra determinării lungimii maxime a cozilor. Aceste diferențe în notație și motivație, la fel ca și diferența în definirea modelelor pentru grafuri computaționale și pentru grafuri marcate arată că nimeni nu a încercat să compare rezultatele și algoritmul lui Karp și Miller [1966] despre grafuri computaționale cu rezultatele obținute pentru grafuri marcate [Commoner et. al. 1971].

Sisteme P / V [Dijkstra 1968; Bruno et. al. 1972]

Operațiile P și V cu semafoare au fost mai întâi introduse de Dijkstra [1968] pentru a ajuta la rezolvarea problemelor de coordonare (sincronizare) în sisteme cu procese paralele, putând fi folosite pentru a modela sincronizarea și comunicațiile la fel ca și rețelele Petri. Patil a folosit această abordare când a definit problema fumătorilor de țigări pentru a arăta limitările sistemelor care pot folosi numai operații P și V între procese. Cu toate acestea, sistemele P și V sunt foarte populare și literatura de specialitate abundă în discuții și aplicații ale acestora; spre exemplu, Liskov [1972].

Capitolul 3.4.8 a arătat că operațiile P și V pot fi modelate cu ajutorul rețelelor Petri, iar demonstrația lui Patil [Patil 1971] a arătat că incluziunea este corectă. Acestea sunt problemele (spre exemplu, problema fumătorilor de țigări) care pot fi rezolvate cu ajutorul rețelelor Petri și nu numai cu operații P și V. Totuși, sistemele P/V sunt suficient de puternice pentru a include atât modelele grafurilor computaționale [Lipton și Snyder 1974] cât și modelele automatelor cu stări finite.

Pentru a converti un automat cu stări finite într-un sistem P/V, folosim un proces separat pentru a modela fiecare stare a automatului cu stări finite. Asociem un semafor fiecărei stări. Fie Q = {q1, …,qn} mulțimea de stări și : Q x I Q funcția de tranziție, cu o mulțime de acțiuni . Asociem stării qi o stare si și un proces. Procesul execută mai întâi o P(Si). În general va aștepta aici până când starea automatului va deveni qi. După P(si), procesul declanșează arbitrar orice pentru care (qi, ) este definită și execută P(Sj), unde qj = (qi, ). Apoi acest proces revine la P(Si) – ul său. Figura 8.5 ilustrează această conversie într-un sistem P/V a automatului cu stări finite din figura 8.6. Semafoarele sunt inițial 0, cu excepția celui atașat stării inițiale, care este inițializat la valoarea 1.

Figura 8.5: Un automat cu stări finite

Figura 8.6: Sistem P/V pentru automatul cu stări finite din figura 8.5

Pentru a converti un graf computațional la un sistem P/V, asociem un semafor Sj,k cu fiecare arc (vj, vk) din graf. Valoarea semaforului va fi numărul de articole care așteaptă în coada atașată acelui arc. Astfel, valoarea semaforului Sj,k este inițial Ij,k. Pentru fiecare nod din graful computațional se crează un proces. Procesul nodului vk execută mai întâi Tj,k P operații asupra semaforului Sj,k pentru toate arcele (vj, vk) îndreptate spre vk. Aceasta ne asigură că fiecare coadă are cel puțin Tj,k articole. Apoi, deoarece fiecare operație P a decrementat semaforul și efectul corect este acela de a micșora Sj,k cu Wj,k, executăm Tj,k – Wj,k V operații asupra semaforului Sj,k pentru a reface valoarea corectă a lui Sj,k. Acum terminăm procesul pentru nodul vk executând vk,r operații asupra semaforului Sk,r pentru fiecare arc (vk, vr) care iese din vk.

Conversia este ilustrată în figura 8.7 pentru nodurile v3 și v4 ale grafului computațional din figura 8.2.

Figura 8.7: Procesele sistemului P/V pentru două din nodurile grafului computațional din figura 8.2

Observăm că graful computațional poate să testeze și să introducă din mai multe surse în același timp, în timp ce sistemele P/V pot să testeze și să introducă din mai multe surse printr-o secvență de teste și intrări din surse simple. Incapacitatea de a testa și de a introduce din mai multe surse simultan este cheia demonstrației lui Patil referitoare la limitările sistemelor P/V, problema fiind că un alt proces poate să ocupe a doua sursă în timp ce Dvs. o ocupați pe prima, ceea ce conduce la o blocare definitivă (deadlock). Aceasta nu este și o problemă a grafurilor computaționale deoarece sursele nu sunt împărțite între procesori – niciodată două noduri nu împart un arc de intrare. Această idee este crucială pentru a construi un sistem P/V care să nu se blocheze definitiv (deadlock)(termine) până când graful computațional corespunzător nu se blochează definitiv de asemenea (termină). Prin adăugarea sistemelor P/V la ierarhia noastră se obține figura 8.8.

Figura 8.8: Adăugarea sistemelor P/V la ierarhia de modele

Sisteme de transmitere a mesajelor [Riddle 1971]

Sistemele în care procesele comunică prin operații P și V cu semafoare nu sunt dintre cele mai performante. Sugestia noastră pentru mecanisme mai bune sunt mesajele. Un sistem „mesaj” este o colecție de procese care comunică prin mesaje. Sunt posibile două operații cu mesaje: trimitere și primire. Trimiterea unui mesaj este similară cu o operație V; primirea unui mesaj este similară cu o operație P. Dacă este prezent un mesaj când se execută o primire, receptorul așteaptă până când este trimis un mesaj.

Acest mecanism a fost folosit ca bază a unei scheme de modelare de către Riddle [1972]. Acest model pare mult mai potrivit pentru modelarea protocoalelor într-o rețea de calculatoare. Riddle a considerat o mulțime (finită) de procese care comunică prin intermediul mesajelor. Mesajele sunt trimise către și cerute de către procese speciale numite procese de legătură (cutii poștale). Procesele de legătură oferă o colecție de mesaje care au fost trimise și nu au fost încă primite, sau cereri pentru mesaje care au fost făcute dar nu au fost încă satisfăcute. Celelalte procese ale sistemului se numesc procese de program și sunt reprezentate în limbajul de modelare al proceselor program (PPML).

Un sistem exemplu cu trei procese este dat în figura 8.9.

Figura 8.9: Un sistem de procese descrise în limbajul de modelare al proceselor program (PPML)

După cum se poate vedea, descrierea PPML a proceselor este în mod esențial o schemă. Este interesantă numai activitatea legată de transmiterea mesajelor în sistem. Mesajele sunt articole abstracte a căror singură caracteristică este un tip. Într-un sistem poate fi numai un număr finit de tipuri de mesaje. Mesajele sunt trimise din și primite într-un buffer de mesaje în fiecare proces. Fiecărui proces îi corespunde un singur buffer. Articolele în PPML sunt:

set t: pune un mesaj de tipul t în bufferul de mesaje

send l: trimite mesajul din bufferul de mesaje la procesul de legătură l

receive l: cere un mesaj de la procesul de legătură l. Așteaptă (dacă este necesar) până când unul este returnat. Mesajul este plasat în bufferul de mesaje

unless t s: testează tipul mesajului din bufferul de mesaje și sare la instrucțiunea s numai dacă mesajul nu este de tipul t

if – internal – test s: modelează un test intern, dependent de date. Fie continuă cu următoarea instrucțiune, fie sare la instrucțiunea etichetată cu s

go-to s: transferă controlul instrucțiunii s

end: termină procesul

Sistemul PPML modelează o mulțime de procese paralele. Fiecare proces este pornit la începutul programului său și execută acest program până când întâlnește o instrucțiune end. Riddle a arătat cum se construiește o expresie de transfer mesaj care să reprezinte fluxul posibil de mesaje în sistem și a folosit această expresie pentru a examina structura sistemului pentru o utilizare corectă. Această expresie de transfer mesaj este folosită în același scop ca limbajul unei rețele Petri. De aceea, vom arăta cum o descriere PPML a unui sistem de procese poate fi convertită într-o rețea Petri al cărei limbaj este egal cu expresia de transfer mesaj din analiza lui Riddle. Această conversie ignoră execuția instrucțiunilor individuale ale descrierilor PPML, deși ele pot fi reprezentate în limbajul rețelei Petri numai cu niște modificări minore.

Pentru a modela un proces ca o rețea Petri, folosim, pentru fiecare proces, un jeton pe post de numărător de program (program counter). Prezența unui mesaj într-un proces de legătură este de asemenea reprezentată printr-un jeton. Deoarece mesajele sunt identificate prin tip, este necesar ca modelarea fiecărui tip de mesaj într-un proces de legătură să se facă printr-o locație separată. O proprietate foarte importantă a sistemelor PPML este aceea că numărul tipurilor de mesaje este finit. Fiecare proces program este de asemenea finit. Numai coada de mesaje presupune o dimensiune potențial nelimitată a spațiului de stocare. Astfel, capacitatea de a modela procesele de legătură și de a reprezenta corect instrucțiunile de trimitere (send) și primire (receive) este aspectul cel mai important al transformării unei descrieri PPML într-o rețea Petri. Prin modelarea proceselor de legătură printr-o mulțime de locații (una pentru fiecare tip de mesaj), putem reprezenta o instrucțiune de trimitere (send) printr-o tranziție care pune un jeton în locația reprezentând procesul de legătură și tipul de mesaj corespunzător. Instrucțiunea de primire (receive) mută numai un jeton din oricare dintre locațiile unui proces de legătură. Locația care furnizează jetonul determină tipul mesajului care a fost primit. Această informație poate fi folosită în orice subsecvență, dar nu în instrucțiuni.

Singurul simbol în expresia de transfer mesaj sunt tipurile mesajelor pentru mesajele care sunt trimise către sau primite de la un proces de legătură. Deoarece fiecare tranziție din rețeaua Petri produce un simbol în limbajul acelei rețele Petri, pot fi modelate numai instrucțiunile send și receive într-un sistem PPML. Astfel apar două tipuri de locații într-o rețea Petri. Un tip de locații, etichetate se comportă ca un numărător pentru mesajele de tipul mj din procesul de legătură li. Celălalt tip de locații reprezintă instrucțiunile send și receive ale programelor PPML. Fie instrucțiunile etichetate unic s1,…,st. Etichetăm locația reprezentând o instrucțiune si cu un mesaj mj din bufferul de mesaje, și anume prin . Un jeton într-o locație asociată cu o instrucțiune si înseamnă că instrucțiunea si tocmai a fost executată. Figura 8.10 ilustrează cum poate fi modelată într-o rețea Petri o instrucțiune de trimitere (primire) la (de la) sk. În figura 8.10, locația reprezintă locația asociată cu orice instrucțiune care precede instrucțiune sk.

Figura 8.10: Transformarea din instrucțiuni send și receive în tranziții ale unei rețele Petri.

Modelarea unei instrucțiuni de trimitere la sk cu un mesaj de tipul m din bufferul de mesaje. Procesul de legătură este lj.

Modelarea instrucțiunii de primire la sk de la un proces de legătură lj. Tipurile de mesaje posibile din lj sunt m1, m2, mt.

Mai rămâne de arătat că este posibil să se determine ce instrucțiuni pot precede alte instrucțiuni în programul PPML. Observăm că trebuie să considerăm fiecare instrucțiune ca o pereche constând dintr-un tip de mesaj și un număr de instrucțiune, deoarece aceeași instrucțiune cu un tip diferit de mesaj în bufferul de mesaje va fi modelată altfel în rețeaua Petri. Cea mai evidentă metodă de a determina predecesorii unei instrucțiuni este de a porni de la începutul fiecărui program PPML cu o instrucțiune de pornire specială (care va deveni locația de pornire) și de a urma descrierea programului generând toate instrucțiunile send și receive posibile care pot urma acestă instrucțiune cu conținuturile bufferelor de mesaje corespunzătoare. Acest proces se repetă pentru toate instrucțiunile nou accesibile până când toate aceste astfel de instrucțiuni send și receive au fost generate și succesori lor identificați. Deoarece numărul de instrucțiuni dintr-o descriere PPML și numărul de tipuri de mesaje sunt finite, se poate genera numai un număr finit de perechi de instrucțiuni/tipuri de mesaje. Această procedură este similară cu ecuațiile caracteristice folosite de Riddle [1972] pentru a construi expresia de transfer mesaj. Figura 8.11 listează instrucțiunile și posibilii succesori pentru sistemul PPML din figura 8.9.

Figura 8.11: Instrucțiunile succesor pentru sistemul PPML din figura 8.9

Odată ce sucesorii unei instrucțiuni au fost determinați, această instrucțiune poate fi folosită pentru a identifica posibilii succeori ai unei alte instrucțiuni și astfel pentru a construi o rețea Petri care este echivalentă cu sistemul PPML, folosind tranzițiile așa cum se arată în figura 8.10. O locație specială de pornire este predecesorul primelor instrucțiuni ale fiecăruia dintre procesele sistemului. Figura 8.12 transformă sistemul PPML din figura 8.9 în rețeaua Petri echivalentă.

Figura 8.12: O rețea Petri echivalentă cu sistemul PPML din figura 8.9

Această scurtă descriere a transformării unui sistem de transmitere mesaje într-o rețea Petri arată că acest model este inclus în puterea de modelare a rețelelor Petri, și că mulțimea de expresii de transfer mesaje, considerată ca o clasă a limbajelor, este o submulțime a clasei limbajelor rețelelor Petri.

Deoarece sistemul P/V poate fi modelat ca un sistem de transmitere de mesaje ce are toste mesajele de același tip, sistemul P/V este inclus în sistemele de transmitere mesaje. Este relativ ușor de construit un sistem de transmitere de mesaje care să rezolve problema fumătorilor de țigări, deci incluziunea sistemelor P/V în sistemele de transmitere mesaje este corectă. Pe de altă parte, sistemele de transmitere de mesaje pierd capacitatea de a avea intrări de la mai multe surse simultan, și de accea nu sunt echivalente cu rețelele Petri. În încercarea de a modela o tranziție cu mai multe intrări va apărea unul din următoarele două cazuri:

Un proces va aștepta să primească jetoane (mesaje) de la toate intrările sale, dar s-ar putea să nu se întâmple așa și astfel va reține jetoane care s-ar putea să fie necesare pentru a permite altor tranziții să continue. Aceasta va duce la o blocare definitivă în sistemul de trimitere mesaje, care nu corespunde cu blocările definitive din rețelele Petri, violând a treia restricție.

Procesul va evita să creeze false blocări definitive determinând dacă jetoanele care mai sunt necesare nu există și returnând jetoanele pe care le-a primit locațiilor (proceselor de legătură) de la care le-a primit. Această activitate s-ar putea să se desfășoare oricât de des și aceasta înseamnă că nu există nici o margine superioară a lungimii secvenței de acțiuni în sistemul de transmitere mesaje ce corespunde unei secvențe mărginite de tranziții care se declanșează dintr-o rețea Petri. Acest fapt violează cea de-a doua restricție.

Riddle [1974] a prezentat o transformare care se află în cazul 1, conducând deci la false blocări definitive. În oricare dintre cazuri, vedem că sistemele de transmitere mesaje nu pot modela orice rețea Petri respectând constrângerile. Se obține astfel ierarhia din figura 8.13.

Figura 8.13: Adăugarea sistemelor de transmitere mesaje la ierarhie

Grafuri UCLA [Ciostelow 1971; Cerf et. al. 1971; Cerf 1972; Cerf et. al. 1972]

Rețelele Petri modelează în termeni de grafuri calculul paralel. O altă modelare în termeni de grafuri a fost dezvoltată la Universitatea California din Los Angeles sub îndrumarea profesorului Estrin. Acest model este modelul calculului unui digraf complex (graful UCLA) [Baer 1968; Baer et. al. 1970; Valansky 1970; Gastelow 1971; Cerf 1972]. În acest model, sistemele sunt reprezentate prin grafuri cu arce complexe orientate. Un arc complex este un arc cu (potențiale) multiple surse și destinații.

Operațiile logice controlează secvența de operațiuni în noduri. Dacă intrarea logică a unui nod este AND (*), sunt necesare jetoane pe fiecare arc de intrare pentru a activa o operație. Pentru OR (+) logic, sunt necesare jetoane numai pe un arc de intrare. Execuția nodului scoate jetoanele de activare de pe arcele de intrare și pune jetoane pe arcele de ieșire, în concordanță cu ieșirea logică. Pentru ieșirea logică AND, se pun jetoane pe toate arcele de ieșire, iar pentru OR logic, se pun jetoane pe orice arc de ieșire. Numărul de jetoane implicate pentru o pereche nod – arc dată dă gradul (sau multiplicitatea) acestei perechi, și poate fi orice număr întreg nenegativ.

Figura 8.14 este un exemplu de graf UCLA: Observăm că unele arce au surse (cozi) și destinații (capete) multiple. De asemenea observăm că operatorul logic al fiecărei perechi arc – nod este marcat fie prin *, pentru AND logic, fie prin +, pentru OR logic. Gradul unui arc este indicat printr-un număr mic acolo unde arcul întâlnește nodul. Gradul este omis dacă este 1, la fel și operatorul logic când nodul are ca intrare un singur arc. În exemplul dat, nodul a poate să se declanșeze de fiecare dată când arcul S are un jeton. Când nodul a se declanșează, scoate jetonul din arcul S și pune jetoane atât pe arcul A cât și pe arcul B (AND logic). Pe de altă parte, nodul g va pune un jeton fie pe arcul K fie pe arcul G (OR logic). Nodul i este activ de fiecare dată când sunt două jetoane pe arcul J, sau un jeton pe arcul K.

Figura 8.14: Un graf orientat complex (graf UCLA)

Definiția 8.1:

Un graf UCLA este un 6-uplu C = (V, A, L, Q, S, F) unde:

V = {v1, …,vr} este o mulțime de vârfuri

A = {a1, …, as} este o mulțime de arce

L = {L-, L+}: V {*, +} sunt intrările (L-) și ieșirile (L+) logice corespunzătoare fiecărui vârf

Q = {Q-, Q+}: V x A N sunt gradele de intrare (Q -) și ieșire (Q+) pentru fiecare pereche arc – vârf

S A este arcul de pornire, F A este arcul final

Arcele grafului sunt definite ca perechi ordonate de mulțimi de vârfuri. Prima componentă a perechii este mulțimea de vârfuri de intrare și a doua componentă este mulțimea de vârfuri de ieșire. Arcul de pornire are o mulțime vidă de vârfuri de intrare, și arcul final are o mulțime vidă de vârfuri de ieșire.

Transformarea grafului UCLA într-o rețea Petri este directă, datorită similitudinilor existente între cele două sisteme. Fiecare arc dintr-un graf UCLA este reprezentat printr-o locație într-o rețea Petri. În plus, reprezentăm un nod v printr-o locație pv și două tranziții și . Prima tranziție reprezintă inițierea operației asociate cu nodul v, iar a doua tranziție reprezintă terminarea operației. Aceste fapte sunt schițate în figura 8.15. (Modelarea nodurilor unui graf UCLA prin tranziții de inițiere și terminare nu este neapărat necesară, dar este utilă.)

Figura 8.15: Reprezentarea de bază a elementelor unui graf UCLA ca rețele Petri

Figura 8.16 indică cum sunt reprezentate într-o rețea Petri echivalentă intrările și ieșirile logice ale unui graf UCLA. Gradele mai mari decât 1 sunt modelate într-o rețea Petri prin arce multiple între locații și tranziții.

Figura 8.16: Transformarea diferitelor părți ale unui graf UCLA în rețele Petri

Figura 8.17 transformă graful UCLA din figura 8.14 într-o rețea Petri echivalentă.

Această transformare arată faptul că puterea de modelare a grafurilor UCLA este inclusă în puterea de modelare a rețelelor Petri. Ar trebui să fie evident că o rețea Petri poate fi convertită într-un graf UCLA echivalent în care locațiile sunt reprezentate ca arce ale unui graf UCLA și tranzițiile ca noduri cu intrarea AND și ieșire logică. Astfel, aceste două modele sunt echivalente ca putere de modelare. Figura 8.18 arată ierarhia modificată de modele.

Figura 8.18: Adăugarea grafurilor UCLA la ierarhie

Figura 8.17: Rețeaua Petri echivalentă cu graful UCLA din figura 8.14

Adunarea vectorilor și sisteme de înlocuire

Sistemele de adunare a vectorilor au fost introduse de către Karp și Miller [1968] ca un instrument matematic pentru analiza sistemelor cu procese paralele. Datorită formulării lor matematice simple, sistemele de adunare a vectorilor sunt de obicei folosite pentru demonstrații formale ale proprietăților sistemelor Petri sau ale unor sisteme similare.

Definiția 8.2:

Un sistem de adunare a vectorilor V este o pereche V = (B, s), unde B = {b1, …,bm} este o mulțime de m vectori, numiți vectori de bază sau deplasare. Vectorul s este vectorul de pornire. Toți vectorii sunt compuși din n valori întregi. Elementele lui s sunt nenegative.

Mulțimea de accesibilitate a unui sistem de adunare a vectorilor V este notată cu R(V) și poate fi definită fie recursiv, prin următoarea definiție:

Definiția 8.2:

Mulțimea de accesibilitate R(V) a unui sistem de adunare a vectorilor V = (B, s) este cea mai mică mulțime cu proprietățile:

s R(V)

dacă x R(V) și x + bj 0, atunci x + bj R(V)

sau prin:

Definiția 8.4:

x R(V) dacă există o secvență de vectori de bază astfel încât:

Cu aceste definiții este ușor de văzut că sistemele de adunare a vectorilor sunt echivalente cu rețelele Petri. Dată o rețea Petri, putem să construim un sistem de adunare a vectorilor unde vectorul de pornire s este marcajul inițial, cu un vector de bază pentru fiecare tranziție. Cele n componente ale vectorilor sistemului de adunare a vectorilor corespund marcajelor celor n locații ale rețelei Petri, sau în cazul vectorilor de bază, schimbărilor în marcaje datorate declanșării tranzițiilor asociate.

Similar, un sistem de adunare a vectorilor poate fi convertit într-o rețea Petri echivalentă, folosind locații pentru componentele vectorilor și tranziții pentru a reprezenta vectorii de bază.

De fapt, sistemele de adunare a vectorilor sunt echivalente cu rețelele Petri fără bucle, deoarece pentru o buclă schimbarea este zero, dar numărul de jetoane din locația buclă trebuie să fie diferit de zero. Acest lucru nu diminuează puterea sistemelor de adunare a vectorilor deoarece, așa cum s-a văzut în capitolul 5.3, rețelele Petri fără bucle sunt echivalente cu rețelele Petri generale. Totuși, pentru o modelare mai directă a rețelelor Petri cu bucle ca sisteme de adunare a vectorilor, Keller a definit sistemele de înlocuire a vectorilor Keller [1972].

Definiția 8.3:

Un sistem de înlocuire a vectorilor constă dintr-un vector de pornire s 0 și din m perechi de vectori (Ui, Vi), astfel încât Ui Vi.

Vectorii Ui se numesc vectori test. Mulțimea de accesibilitate este definită astfel încât s să aparțină acesteia, și dacă x este în mulțimea de accesibilitate astfel încât x Ui 0, atunci x Vi este în mulțimea de accesibilitate.

Sistemul de înlocuire a vectorilor modelează separat testul pentru activarea unei tranziții de acțiunea de declanșare a tranziției. Echivalența dintre sistemele de înlocuire a vectorilor și rețelele Petri (generale) este evidentă.

Prin adăugarea în ierarhie a sistemelor de adunare a vectorilor și a sistemelor de înlocuire a vectorilor se obține figura 8.19. Importanța sistemelor de adunare a vectorilor și a celor de înlocuire a vectorilor rezultă din definițiile lor matematice concise și utilitatea acestor definiții în demonstrarea proprietăților matematice ale sistemelor.

Figura 8.19: Adăugarea sistemelor de adunare a vectorilor și a sistemelor de înlocuire a vectorilor la ierarhie

Rețele Petri extinse

Ca o ultimă adăugare la ierarhie, menționăm din nou rețelele Petri extinse studiate în capitolul 7: rețele Petri cu restricții, tranziții SAU-exclusiv, comutatoare, arce inhibitoare, priorități sau temporizate. Am văzut că toate aceste modele sunt echivalente cu mașinile Turing. Astfel, aceste modele includ modelele de rețele Petri. Ierarhia finală este prezentată în figura 8.21.

Figur 8.21: Ierarhia completă a modelelor calculului paralel

A O scurtă teorie a multiseturilor

Teoria mulțimilor a fost îndelung utilizată în matematică și informatică. Teoria multiseturilor este o extensie naturală a teoriei mulțimilor. Un multiset, asemenea unei mulțimi, este o colecție de elemente peste același domeniu. Totuși, spre deosebire de mulțimi, multiseturile permit apariți multiple ale elementelor. În teoria mulțimilor, un element este fie membru al unei mulțimi, fie nu. În teoria multiseturilor un element poate să fie într-un multiset de zero ori (nu este în multiset) sau o dată, de două ori, de trei ori, sau de un număr oarecare, specificat, de ori.

Teoria multiseturilor a fost dezvoltată în [Cerf et. al. 1971] și [Peterson 1976]. Spre exemplu, considerăm următoarele multiseturi peste domeniul {a, b, c, d}: B1 = {a,b,c}, B2 = {a}, B3 = {a, b, c, c}, B4 = {a, a, a}, B5 = {b, c, b, c}, B6 = {c, c, b, b}, B7 = {a, a, a, a, a, b, b, c, d, d, d, d, d, d, d}. Unele multiseturi sunt mulțimi, spre exemplu B1 și B2. De asemenea, ca și în cazul mulțimilor, ordinea elementelor nu este importantă, astfel că B5 și B6 desemnează același multiset (multiseturile ordonate sunt secvențe).

În teoria mulțimilor, conceptul de bază este relația de apartenență. Relația este definită între elemente și mulțimi și numește care elemente sunt membri ai căror mulțimi. Conceptul de bază în teoria multiseturilor este funcția „număr de apariții”. Această funcție definește numărul de apariții ale unui element într-un multiset. Pentru un element x și un multiset B, notăm numărul de apariții ale lui x în B prin #(x, B) și înțelegem „numărul de x din B”.

Cu aceste concepte de bază, putem defini noțiunile fundamentale ale teoriei multiseturilor. Multe dintre concepte și notații sunt împrumutate din teoria mulțimilor într-un mod cât se poate de evident. Dacă restricționăm numărul de elemente dintr-un multiset astfel încât 0 #(x, B) 1, atunci dăm peste teoria mulțimilor.

A.1 Apartenența

Funcția #(x, B) definește numărul de apariții ale unui element x într-un multiset B. De aici rezultă că #(x, B) 0 pentru toți x din B. Distingem două cazuri: număr de apariții zero și număr de apariții diferit de zero. Un element x este membru al unui multiset B dacă #(x, B) > 0. Acest fapt se notează prin x B. Similar, dacă #(x, B) = 0, atunci x B.

Definim multisetul vid ca fiind multisetul fără nici un element. Pentru toți x, #(x, ) = 0.

A.2 Cardinalitatea

Cardinalitatea |B| a unui multiset B reprezintă numărul total de apariții ale elementelor din multiset, .

A.3 Incluziune și egalitate

Un multiset A este submultiset al unui multiset B (notăm A B) dacă fiecare element al lui A este de asemenea un element al lui B de cel puțin atâtea ori:

A B dacă #(x, A) #(x, B) pentru toți x

Două multiseturi sunt egale (A = B) dacă #(x, A) = #(x, B) pentru toți x. Din aceste definiții putem arăta imediat că:

A = B dacă A B și B A

B oricare ar fi B multiset

A = B implică |A| = |B|

A B implică |A| |B|

Un multiset A este inclus strict într-un multiset B (A B) dacă A B și A B. Observăm că #(x, A) < #(x, B) nu rezultă din A B, deși avem că |A| < |B|.

A.4 Operații

Sunt definite patru operații cu multiseturi. Pentru două multiseturi A și B definim:

– reuniunea A B: #(x, A B) = max {#(x, A), #(x, B)}

– intersecția A B: #(x, A B) = min {#(x, A), #(x, B)}

– suma A + B: #(x, A + B) = #(x, A) + #(x, B)

– diferența A – B: #(x, A – B) = #(x, A) – #(x, A B)

Acești operatori au majoritatea proprietăților pe care vă așteptați să le aibă. Reuniuna, intersecția și suma sunt comutative și asociative. În plus:

A B A A B

A – B A A + B

Distincția dintre reuniune și sumă se vede clar din următoarele relații:

|A B| |A| + |B|

|A + B| = |A| + |B|

Din nefericire nu există astfel de relații și între A B și A – B. Stabilirea unei astfel de relații este complicată de imposibilitatea de a scoate elemente dintr-un multiset care nu sunt acolo.

A.5 Spații de multiseturi

Numim un domeniu D ca fiind o mulțime de elemente din care sunt construite multiseturi. Spațiul de multiseturi Dn este mulțimea tuturor multiseturilor ale căror elemente sunt în D astfel încât nici un element nu apare mai mult de o dată. Astfel, pentru toate B Dn:

x B implică x Dn

#(x, B) n pentru toți n

Mulțimea D este mulțimea tuturor multiseturilor peste un domeniu D; nu există nici o limită a numărului de apariții ale unui element într-un multiset.

A.6 Reprezentarea Parikh

Pentru un domeniu D = {d1, …,dn} există o corespondență naturală între fiecare multiset B peste D și vectorul n-dimensional f = (f1, …, fn) definit de fi = #(di, B).

Acest vector este cunoscut ca reprezentarea Parikh.

A.7 Exemple

Fie D = {a, b, c, d} un domeniu. Atunci, pentru multiseturile A = {a,b}, B = {a, a, b, c}, C = {a, a, a, c, c} avem:

|A| = 2, |C| = 5

A B = {a, a, b, c} = B

A C = {a}

A C = {a, a, a, b, b, c} = B C

B C = {a, a, c}

A + B = {a, a, a, b, b, c}

A – B =

C – A = {a, a, c, c}

C – B = {a, c}

Similar Posts