next up previous contents
Next: Poznámka: Up: Funkční část Previous: Zajištění konzistence

Transformace do CCS

Transformace do CCS je řešena metodou GEditor::getCCSdf, která volá metody GBox::getRestriction a GBox::getRelabeling. Tyto metody implementují algoritmus navržený v kapitole gif na straně gif. V této sekci popíšeme technické prvky jeho implementace a zejména úpravu pro změnu v syntaxi GCCS, kterou jsme zavedli možností vzájemného propojení dvou portů bez nutnosti použít sběrnici.

Postupně procházíme všechna rozhraní sítě a voláním výše uvedených metod pro každé z nich vypočítáme globální (celého systému na dané úrovni abstrakce) a lokální (podsystémů) restrikce a přejmenování. Pokud je na rozhraní napojena podsíť, voláme její metodu GEditor::getCCSdf, čímž získáme CCS výraz podsystému. Pokud není podsíť napojena, využijeme textového řetězce CCS popisujícího podsystém (není-li prázdný, jinak definujeme podsystém jako proces nil). V těchto metodách používáme datových struktur, jejichž přehled je uveden v tabulce gif.

  
Table: Tabulka datových struktur použivaných při transformaci do CCS



-1



1

Vnitřní sběrnice v síti mají prázdné jméno. Z toho důvodu musíme takové vnitřní sběrnice, které jsou pro transformaci významné (tj. jsou napojeny na nějaký port), pro účely transformace pojmenovat různými interními jmény (viz v algoritmu gif z kapitoly gif). Pomocí těchto jmen se budou příslušné porty synchronizovat a tato interní jména budou součástí globální restrikce R. Po ukončení transformace je nutno jména těchto sběrnic opět nahradit prázdným řetězcem. K tomu slouží právě seznam intb. Ke generování jmen interních sběrnic se používá aktuální hodnoty proměnné l. Aby nedocházelo ke konfliktu jmen akcí, zvolili jsme následující tvar: '', kde za l se dosadí příslušná hodnota.

Výpočet globálního přejmenování F se provádí postupně procházením volných portů a pojmenovaných sběrnic podsystémů. Abychom zaručili jednoznačné ošetřující jméno pro každý problémový port, generujeme toto jméno pomocí čítače r, který pro každý problémový port inkrementujeme.

Extenzi syntaxe GCCS o možnost propojení dvou portů překládáme do CCS jako propojení portů přes vnitřní sběrnici. Přitom musíme zajistit jednoznačné jméno této pomyslné sběrnice (představující komunikační akci, na níž jsou synchronizovány příslušné podsystémy). Abychom zaručili přejmenování obou portů na stejné interně vygenerované jméno, uložíme jej do tabulky com_port_map k ukazateli na partnera prvně procházeného procesu. Partnerský port si potom z tabulky toto jméno převezme. Pro zajištění jednoznačnosti jmen jsme zvolili následující tvar tohoto interního jména: '', kde za port1 se dosadí jméno počátečního portu spoje a za port2 jméno jeho partnera (tedy koncového portu spoje). Pro zajištění jednoznačnosti propojení v případě, že se dané jméno portu vyskytuje u více dvojic vzájemně propojených portů v síti, je součástí interního jména číslo k vyjadřující aktuální počet položek v tabulce com_port_map. Vzhledem ke způsobu konstrukce této tabulky toto číslo zajišťuje jednoznačnost generovaného jména.

Schematický popis implementace:

  1. Označíme všechny sítě za nenavštívené pomocí metody Main::setAllNetsVisited( FALSE ).
  2. Pro aktivní síť zavoláme metodu Main::getCCSdf():
    1. Inicializace:
      • intb, F_i_list := prázdný seznam
      • F, R := prázdný řetězec, l, r
      • com_port_map := prázdná tabulka
    2. označ síť za navštívenou (GEditor::setVisited( TRUE ))
    3. zatřiď do F_i_list všechny problémové porty ze seznamu volných portů
    4. Pro každé rozhraní ze seznamu všech rozhraní sítě:
      1. pokud poprvé, vygeneruj pravou stranu výsledné CCS definice obsahující jméno sítě 'proc `GEditor::netName()` ='
      2. jinak přidej operátor paralelní kompozice '|'
      3. přidej jméno aktuálního rozhraní (GBox::name())
      4. pokud je napojen podsystém, vypočítej lokální restrikci voláním
        GBox::getRestriction() aktuálního rozhraní:
        • načti z podsítě jména všech volných portů a sběrnic
          (GEditor::getAllNamesOfNetsInterface())
        • vrať všechna jména portů a sběrnic, pro něž v otcovské síti neexistuje odpovídající port (porovnáním jmen získaných v předchozím kroku se seznamem volných portů aktuální sítě)
      5. rozšiř generovaný CCS výraz o výše získanou restrikci ''
      6. vypočti lokální a globální přejmenování a globální restrikci voláním
        GBox::getRelabeling(F_i_list, com_port_map, F, R, intb, l, r) pro aktuální rozhraní
      7. rozšiř generovaný CCS výraz o lokální restrikci vygenerovanou v předchozím kroku a o aktualizovanou globální restrikci a přejmenování R a F
      8. pokud je na aktuální rozhraní napojen podsystém, zavolej jeho metodu GEditor::getCCSdf() a rozšiř generovaný CCS řetězec o její výsledek (po přidání znaku konce řádky)
      9. jinak pokud je v rozhraní obsažen CCS kód procesu (GBox::getCCSprocess(), rozšiř o něj generovaný CCS řetězec (po přidání konce řádky)
      10. není-li CCS řetěz v předchozím kroku definován, rozšiř generovaný CCS kód o 'proc `GBox::name()` = nil`, kde metoda GBox::name() vrací jméno aktuálního rozhraní

Schematický popis metody GBox::getRelabeling:

  1. pro každý port rozhraní:
    1.   zjisti ze setříděného seznamu F_i_list, zda aktuální port není problémový
    2. pokud je problémový, rozšiř generované lokální přejmenování o řetěz '',
      kde a je jméno příslušného problémového portu a r hodnota příslušného čítače, a F o reverzní přejmenování ''
    3. pokud je aktuální port napojen na pojmenovanou sběrnici, rozšiř generované přejmenování o 'b/a', kde a je jméno aktuálního portu a b jméno příslušné sběrnice
    4. je-li aktuální port napojen na vnitřní sběrnici, pak:
      • vygeneruj pro tuto sběrnici interní jméno '' a inkrementuj l
      • přejmenuj tuto sběrnici nově vygenerovaným jménem (GBus::setName())
      • rozšiř generované lokální přejmenování o '', kde a je jméno aktuálního portu
      • do globální restrikce R přiřetěz ''
    5. je-li aktuální port napojen přes spoj přímo na jiný port, pak:
      • pokud existuje záznam v tabulce com_port_map pro aktuální port, pak stejně jako v předchozím případě rozšiř generované lokální přejmenování, R a F o jméno získané z tabulky,
      • jinak vygeneruj jméno '', kde port1 je jméno počátečního a port2 koncového portu spoje a k je počet položek tabulky com_port_map, rozšiř generované přejmenování o '' (resp. '') a do tabulky com_port_map ulož toto jméno pro partnera aktuálního portu.
        Partner je zjištěn pomocí metody GPort::getConnectedElement().
  2. vrať získaný řetězec lokálního přejmenování

Výsledný kód CCS je zobrazen v jednoduchém textovém editoru, z něhož je možné jej exportovat do textového souboru (kompatibilního s programem CWB-NC).

Implementace seznamu problémových portů pomocí setříděného seznamu zefektivňuje prohledávání v kroku (gif). Výpočet průniku množin portů (rozhraní) z návrhu algoritmu je řešen logaritmickým vyhledáváním portů v tomto seznamu. Konstrukce tohoto seznamu se při analýze každé sítě provádí vždy jedenkrát sekvenčním průchodem setříděným seznamem všech jejích volných portů, z něhož vybereme problémové lineárním průchodem tak, že přidáme vždy port, jehož jméno se vyskytuje v procházeném seznamu alespoň dvakrát. Procházený seznam je setříděný, stačí tedy při průchodu porovnávat jména předchozího a aktuálního portu. Zkonstruovaný seznam v čase setřídíme (knihovní metoda QList::sort).


next up previous contents
Next: Poznámka: Up: Funkční část Previous: Zajištění konzistence

David Safranek
Fri Apr 6 23:53:25 MET DST 2001