con_decomposability_extension.cppGo 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 |