con_decomposability_extension.cpp

Go to the documentation of this file.
00001 /** @file con_decomposability_extension.cpp Conditionaldecomposability */
00002 
00003 /*
00004  * Implementation of the Conditionally decomposable extension algorithm
00005  *
00006  * Copyright (C) 2012  Tomas Masopust
00007  *
00008  */
00009 
00010 
00011 #include "con_decomposability_extension.h"
00012 #include <vector>
00013 
00014 namespace faudes {
00015 
00016 void ConDecExtension(const Generator& gen, const EventSetVector& rAlphabets, EventSet& ek) {
00017   
00018   // the generator must be deterministic
00019   if (gen.IsDeterministic() == false) {
00020     std::stringstream errstr;
00021     errstr << "Generator must be deterministic, but is nondeterministic";
00022     throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 201);
00023   }
00024 
00025   // the generator must be trimed
00026   if (gen.IsTrim() == false) {
00027     std::stringstream errstr;
00028     errstr << "Generator must be trim, but is blocking";
00029     throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 201);
00030   }
00031 
00032   // at least two alphabets in the vector
00033   if (rAlphabets.Size() < 2) {
00034     std::stringstream errstr;
00035     errstr << "At least two alphabets must be included in the EventSetVector";
00036     throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 201);
00037   }
00038 
00039   Idx i;
00040       EventSetVector ee = rAlphabets;   // Vector of input alphabets
00041   EventSet unionset;      // contains union of Ei
00042   EventSet shared;      // contains union of intersections
00043 
00044   // Compute unionset
00045   for (i = 0; i < ee.Size(); i++) {
00046     SetUnion(unionset,ee.At(i),unionset);
00047   }
00048 
00049   // Compute the set of shared events
00050   for (i = 0; i < ee.Size(); i++) {
00051     for (Idx j = 0; j < ee.Size(); j++) {
00052       if (j != i) {
00053     EventSet eHelpInt;
00054     SetIntersection(ee.At(i),ee.At(j),eHelpInt);
00055     SetUnion(shared,eHelpInt,shared);
00056       }
00057     }
00058   }
00059 
00060     // Alphabet of the generator must be under union Ei 
00061   bool ok = SetInclusion(gen.Alphabet(),unionset);
00062     if (ok == false) {
00063     std::stringstream errstr;
00064     errstr << "Generator alphabet is not included in union of the alphabets";
00065     throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 100);
00066     }
00067 
00068     // Alphabet of the generator must contain Ek
00069   ok = SetInclusion(ek,gen.Alphabet());
00070     if (ok == false) {
00071     std::stringstream errstr;
00072     errstr << "Generator alphabet does not include the alphabet ek";
00073     throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 100);
00074     }
00075 
00076     // Ek must contain all shared events
00077   ok = SetInclusion(shared,ek);
00078     if (ok == false) {
00079     std::stringstream errstr;
00080     errstr << "Ek does not include all shared events";
00081     throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 100);
00082     }
00083 
00084   // Compute tilde G
00085   Generator tildeG;
00086   tildeG = ComputeTildeG(unionset,ee,ek,gen);
00087   
00088   // if Ek changed, set b = true and recompute tilde G
00089   while ( isExtendedEk(tildeG,gen,ek) ) {
00090     tildeG = ComputeTildeG(unionset,ee,ek,gen);
00091   }
00092 }
00093 
00094 Generator ComputeTildeG(const EventSet& unionset, const EventSetVector& ee, const EventSet& ek, const Generator& gen) {
00095   // Make copies of the generator
00096   GeneratorVector copies;
00097   EventSet unionsetNew = unionset;  // unionset with new events
00098   EventSet::Iterator eit;
00099 
00100   for (Idx i = 0; i < ee.Size(); i++) {
00101     EventSet uEiEk;
00102     SetUnion(ee.At(i),ek,uEiEk);
00103     EventSet EiEkdifUnionset;
00104     SetDifference(unionset,uEiEk,EiEkdifUnionset);
00105     Generator copy = gen;
00106     for (eit = EiEkdifUnionset.Begin(); eit != EiEkdifUnionset.End(); ++eit) {
00107       copy.EventRename(*eit,copy.UniqueEventName(""));
00108     }
00109     copies.Append(copy);
00110     SetUnion(unionsetNew,copy.Alphabet(),unionsetNew);
00111   }
00112 
00113   Generator g = copies.At(0);
00114     for (Idx i = 1; i < copies.Size(); i++) {
00115         Parallel(g,copies.At(i),g);
00116     }
00117     Trim(g);
00118     return g;
00119 }
00120 
00121 // go through tilde G and check if all corresponding transitions are possible in G
00122 bool isExtendedEk(const Generator& tildeGen, const Generator& rGen, EventSet& ek) {
00123     // shared events
00124     EventSet sharedalphabet = tildeGen.Alphabet() * rGen.Alphabet();
00125     // todo stack
00126   std::stack< std::pair<Idx,Idx> > todo;
00127   // tested transitions are stored here
00128     std::map< std::pair<Idx,Idx>, Idx> testedTrans;
00129     testedTrans.clear();
00130   // current pair, new pair
00131   std::pair<Idx,Idx> currentstates, newstates;
00132   // state
00133   Idx tmpstate = 1;  
00134   StateSet::Iterator lit1, lit2;
00135   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00136   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00137 
00138     // push all combinations of initial states on todo stack
00139     for (lit1 = tildeGen.InitStatesBegin(); lit1 != tildeGen.InitStatesEnd(); ++lit1) {
00140         for (lit2 = rGen.InitStatesBegin(); lit2 != rGen.InitStatesEnd(); ++lit2) {
00141             currentstates = std::make_pair(*lit1, *lit2);
00142             todo.push(currentstates);
00143             testedTrans[currentstates] = tmpstate++;
00144         }
00145     }
00146 
00147   // start algorithm
00148     while (! todo.empty()) {
00149         // get next reachable state from todo stack
00150         currentstates = todo.top();
00151         todo.pop();
00152         // iterate over all tildeGen transitions (includes execution of shared events)
00153         tit1 = tildeGen.TransRelBegin(currentstates.first);
00154         tit1_end = tildeGen.TransRelEnd(currentstates.first);
00155         for (; tit1 != tit1_end; ++tit1) {
00156           // if event not shared
00157           if (! sharedalphabet.Exists(tit1->Ev)) {
00158             newstates = std::make_pair(tit1->X2, currentstates.second);
00159             // add to todo list if new
00160             rcit = testedTrans.find(newstates);
00161             if (rcit == testedTrans.end()) {
00162               todo.push(newstates);
00163               testedTrans[newstates] = tmpstate++;
00164             }
00165             else {
00166               tmpstate = rcit->second;
00167             }
00168           }
00169           // shared event
00170           else {
00171             // find shared transitions
00172             tit2 = rGen.TransRelBegin(currentstates.second, tit1->Ev);
00173             tit2_end = rGen.TransRelEnd(currentstates.second, tit1->Ev);
00174       // problematic event add it to Ek and leave the procedure
00175       if (tit2 == tit2_end) {
00176     if (! ek.Exists(tit1->Ev)) {
00177       ek.Insert(tit1->Ev);
00178       std::cerr << "ConDecExtension: Event " << rGen.EventName(tit1->Ev) 
00179       << " has been added to Ek." << std::endl;
00180       return true;
00181       }
00182       }
00183       for (; tit2 != tit2_end; ++tit2) {
00184               newstates = std::make_pair(tit1->X2, tit2->X2);
00185               // add to todo list if composition state is new
00186               rcit = testedTrans.find(newstates);
00187               if (rcit == testedTrans.end()) {
00188                 todo.push(newstates);
00189                 testedTrans[newstates] = tmpstate++;
00190               }
00191               else {
00192                 tmpstate = rcit->second;
00193               }
00194             }
00195           }
00196         }
00197       }
00198       return false;
00199 }
00200 
00201 } // name space 
00202 
00203 
00204 

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen