con_decomposability_extension.cpp
Go to the documentation of this file.
1/** @file con_decomposability_extension.cpp Conditionaldecomposability */
2
3/*
4 * Implementation of the Conditionally decomposable extension algorithm
5 *
6 * Copyright (C) 2012, 2015 Tomas Masopust
7 *
8 */
9
10
12#include <vector>
13
14namespace faudes {
15
16void ConDecExtension(const Generator& gen, const EventSetVector& rAlphabets, EventSet& ek) {
17
18 // the generator must be deterministic
19 if (gen.IsDeterministic() == false) {
20 std::stringstream errstr;
21 errstr << "Generator must be deterministic, but is nondeterministic";
22 throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 201);
23 }
24
25 // the generator must be trimed
26 if (gen.IsTrim() == false) {
27 std::stringstream errstr;
28 errstr << "Generator must be trim, but is blocking";
29 throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 201);
30 }
31
32 // at least two alphabets in the vector
33 if (rAlphabets.Size() < 2) {
34 std::stringstream errstr;
35 errstr << "At least two alphabets must be included in the EventSetVector";
36 throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 201);
37 }
38
39 Idx i;
40 EventSetVector ee = rAlphabets; // Vector of input alphabets
41 EventSet unionset; // contains union of Ei
42 EventSet shared; // contains union of intersections
43
44 // Compute unionset
45 for (i = 0; i < ee.Size(); i++) {
46 unionset = unionset + ee.At(i);
47 }
48
49 // Compute the set of shared events
50 for (i = 0; i < ee.Size(); i++) {
51 for (Idx j = 0; j < ee.Size(); j++) {
52 if (j != i) {
53 shared = shared + ( ee.At(i) * ee.At(j) );
54 }
55 }
56 }
57
58 // Alphabet of the generator must be under union Ei
59 bool ok = SetInclusion(gen.Alphabet(),unionset);
60 if (ok == false) {
61 std::stringstream errstr;
62 errstr << "Generator alphabet is not included in union of the alphabets";
63 throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 100);
64 }
65
66 // Alphabet of the generator must contain Ek
67 ok = SetInclusion(ek,gen.Alphabet());
68 if (ok == false) {
69 std::stringstream errstr;
70 errstr << "Generator alphabet does not include the alphabet ek";
71 throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 100);
72 }
73
74 // Ek must contain all shared events
75 ok = SetInclusion(shared,ek);
76 if (ok == false) {
77 std::stringstream errstr;
78 errstr << "Ek does not include all shared events";
79 throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 100);
80 }
81
82 //call CDExtension for each pair (Ei, \cup_{j<>i} Ej)
83 for (Idx i = 0; i < ee.Size(); ++i) {
85 eev.Append(ee.At(i));
86 //union of Ej for j<>i
87 EventSet uset;
88 for (Idx j = 0; j < ee.Size(); ++j) {
89 if ( i == j ) continue;
90 uset = uset + ee.At(j);
91 }
92 eev.Append(uset);
93 CDExt(gen,eev,unionset,ek);
94 }
95
96}
97
98
99void CDExt(const Generator& gen, const EventSetVector& ee, const EventSet& unionset, EventSet& ek) {
100 // Compute tilde G
101 Generator tildeG;
102 tildeG = ComputeTildeG(unionset,ee,ek,gen);
103// tildeG.GraphWrite("tildeG.png");
104
105 // if Ek changed, set b = true and recompute tilde G
106 while ( isExtendedEk(tildeG,gen,ek) ) {
107 tildeG = ComputeTildeG(unionset,ee,ek,gen);
108 }
109}
110
111
112Generator ComputeTildeG(const EventSet& unionset, const EventSetVector& ee, const EventSet& ek, const Generator& gen) {
113 // Make copies of the generator
114 GeneratorVector copies;
115 EventSet unionsetNew = unionset; // unionset with new events
116 EventSet::Iterator eit;
117
118 for (Idx i = 0; i < ee.Size(); i++) {
119 EventSet notInEiEk;
120 notInEiEk = unionset - ( ee.At(i) + ek );
121 Generator copy = gen;
122 for (eit = notInEiEk.Begin(); eit != notInEiEk.End(); ++eit) {
123 copy.EventRename(*eit,copy.UniqueEventName(""));
124 }
125 copies.Append(copy);
126 unionsetNew = unionsetNew + copy.Alphabet();
127 }
128
129 Generator g = copies.At(0);
130 for (Idx i = 1; i < copies.Size(); i++) {
131 Parallel(g,copies.At(i),g);
132 }
133 Trim(g);
134 return g;
135}
136
137// go through tilde G and check if all corresponding transitions are possible in G
138bool isExtendedEk(const Generator& tildeGen, const Generator& rGen, EventSet& ek) {
139 // shared events
140 EventSet sharedalphabet = tildeGen.Alphabet() * rGen.Alphabet();
141 // todo stack
142 std::stack< std::pair<Idx,Idx> > todo;
143 // tested transitions are stored here
144 std::map< std::pair<Idx,Idx>, Idx> testedTrans;
145 testedTrans.clear();
146 // current pair, new pair
147 std::pair<Idx,Idx> currentstates, newstates;
148 // state
149 Idx tmpstate = 1;
150 Idx lastNonEk = -1; //!! Remembers the last symbol from E-Ek that has been read.
151 StateSet::Iterator lit1, lit2;
152 TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
153 std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
154
155 // push all combinations of initial states on todo stack
156 for (lit1 = tildeGen.InitStatesBegin(); lit1 != tildeGen.InitStatesEnd(); lit1++) {
157 for (lit2 = rGen.InitStatesBegin(); lit2 != rGen.InitStatesEnd(); lit2++) {
158 currentstates = std::make_pair(*lit1, *lit2);
159 todo.push(currentstates);
160 testedTrans[currentstates] = tmpstate++;
161// std::cout << "TODO list: "
162// << "(" << tildeGen.StateName(*lit1) << "," << *lit2 << ") "
163// << std::endl;
164 }
165 }
166
167
168
169 // start algorithm
170 while (! todo.empty()) {
171 // get next reachable state from todo stack
172 currentstates = todo.top();
173 todo.pop();
174 // iterate over all tildeGen transitions (includes execution of shared events)
175 tit1 = tildeGen.TransRelBegin(currentstates.first);
176 tit1_end = tildeGen.TransRelEnd(currentstates.first);
177 for (; tit1 != tit1_end; ++tit1) {
178 // if the event not shared
179 if (! sharedalphabet.Exists(tit1->Ev)) {
180 newstates = std::make_pair(tit1->X2, currentstates.second);
181// std::cout << "Non-shared: "
182// << "(" << tildeGen.StateName(currentstates.first) << "," << currentstates.second << ") -- "
183// << tildeGen.EventName(tit1->Ev) << " -- > ("
184// << tildeGen.StateName(newstates.first) << "," << newstates.second <<")"
185// << std::endl;
186 // add to todo list if new
187 rcit = testedTrans.find(newstates);
188 if (rcit == testedTrans.end()) {
189 todo.push(newstates);
190 testedTrans[newstates] = tmpstate++;
191 }
192 else {
193 tmpstate = rcit->second;
194 }
195 }
196 // shared event
197 else {
198 // find shared transitions
199 tit2 = rGen.TransRelBegin(currentstates.second, tit1->Ev);
200 tit2_end = rGen.TransRelEnd(currentstates.second, tit1->Ev);
201// std::cout << "TEST: "
202// << "(" << tit2->X1 << "," << tit2->X2 << ") under "
203// << rGen.EventName(tit2->Ev) << std::endl;
204 // problematic event add it to Ek and leave the procedure
205 if (tit2 == tit2_end) {
206 ek.Insert(lastNonEk);
207 std::cerr << "ConDecExtension: Event " << rGen.EventName(lastNonEk)
208 << " has been added to Ek." << std::endl;
209 return true;
210 }
211 for (; tit2 != tit2_end; ++tit2) {
212 newstates = std::make_pair(tit1->X2, tit2->X2);
213 if (! ek.Exists(tit1->Ev)) {
214 lastNonEk = tit1->Ev;
215// std::cout << "lastNonEk = " << rGen.EventName(tit1->Ev) << std::endl;
216 }
217// std::cout << "Shared: "
218// << "(" << tildeGen.StateName(currentstates.first) << "," << currentstates.second << ") -- "
219// << tildeGen.EventName(tit1->Ev) << " -- > ("
220// << tildeGen.StateName(tit1->X2) << "," << tit2->X2 <<")" << std::endl;
221 // add to todo list if composition state is new
222 rcit = testedTrans.find(newstates);
223 if (rcit == testedTrans.end()) {
224 todo.push(newstates);
225 testedTrans[newstates] = tmpstate++;
226 }
227 else {
228 tmpstate = rcit->second;
229 }
230 }
231 }
232 }
233 }
234 return false;
235}
236
237} // name space
238
239
240
bool Exists(const Idx &rIndex) const
bool Insert(const Idx &rIndex)
virtual const T & At(const Position &pos) const
virtual void Append(const Type &rElem)
StateSet::Iterator InitStatesBegin(void) const
const EventSet & Alphabet(void) const
TransSet::Iterator TransRelBegin(void) const
bool EventRename(Idx event, const std::string &rNewName)
TransSet::Iterator TransRelEnd(void) const
bool IsDeterministic(void) const
StateSet::Iterator InitStatesEnd(void) const
std::string EventName(Idx index) const
bool IsTrim(void) const
bool SetInclusion(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB)
Iterator End(void) const
Iterator Begin(void) const
void ConDecExtension(const Generator &gen, const EventSetVector &rAlphabets, EventSet &ek)
void Trim(vGenerator &rGen)
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
uint32_t Idx
Generator ComputeTildeG(const EventSet &unionset, const EventSetVector &ee, const EventSet &ek, const Generator &gen)
void CDExt(const Generator &gen, const EventSetVector &ee, const EventSet &unionset, EventSet &ek)
bool isExtendedEk(const Generator &tildeGen, const Generator &rGen, EventSet &ek)

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen