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 Tomas Masopust
7  *
8  */
9 
10 
12 #include <vector>
13 
14 namespace faudes {
15 
16 void 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  SetUnion(unionset,ee.At(i),unionset);
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  EventSet eHelpInt;
54  SetIntersection(ee.At(i),ee.At(j),eHelpInt);
55  SetUnion(shared,eHelpInt,shared);
56  }
57  }
58  }
59 
60  // Alphabet of the generator must be under union Ei
61  bool ok = SetInclusion(gen.Alphabet(),unionset);
62  if (ok == false) {
63  std::stringstream errstr;
64  errstr << "Generator alphabet is not included in union of the alphabets";
65  throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 100);
66  }
67 
68  // Alphabet of the generator must contain Ek
69  ok = SetInclusion(ek,gen.Alphabet());
70  if (ok == false) {
71  std::stringstream errstr;
72  errstr << "Generator alphabet does not include the alphabet ek";
73  throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 100);
74  }
75 
76  // Ek must contain all shared events
77  ok = SetInclusion(shared,ek);
78  if (ok == false) {
79  std::stringstream errstr;
80  errstr << "Ek does not include all shared events";
81  throw Exception("ConditionalDecomposabilityExtension", errstr.str(), 100);
82  }
83 
84  // Compute tilde G
85  Generator tildeG;
86  tildeG = ComputeTildeG(unionset,ee,ek,gen);
87 
88  // if Ek changed, set b = true and recompute tilde G
89  while ( isExtendedEk(tildeG,gen,ek) ) {
90  tildeG = ComputeTildeG(unionset,ee,ek,gen);
91  }
92 }
93 
94 Generator ComputeTildeG(const EventSet& unionset, const EventSetVector& ee, const EventSet& ek, const Generator& gen) {
95  // Make copies of the generator
96  GeneratorVector copies;
97  EventSet unionsetNew = unionset; // unionset with new events
98  EventSet::Iterator eit;
99 
100  for (Idx i = 0; i < ee.Size(); i++) {
101  EventSet uEiEk;
102  SetUnion(ee.At(i),ek,uEiEk);
103  EventSet EiEkdifUnionset;
104  SetDifference(unionset,uEiEk,EiEkdifUnionset);
105  Generator copy = gen;
106  for (eit = EiEkdifUnionset.Begin(); eit != EiEkdifUnionset.End(); ++eit) {
107  copy.EventRename(*eit,copy.UniqueEventName(""));
108  }
109  copies.Append(copy);
110  SetUnion(unionsetNew,copy.Alphabet(),unionsetNew);
111  }
112 
113  Generator g = copies.At(0);
114  for (Idx i = 1; i < copies.Size(); i++) {
115  Parallel(g,copies.At(i),g);
116  }
117  Trim(g);
118  return g;
119 }
120 
121 // go through tilde G and check if all corresponding transitions are possible in G
122 bool isExtendedEk(const Generator& tildeGen, const Generator& rGen, EventSet& ek) {
123  // shared events
124  EventSet sharedalphabet = tildeGen.Alphabet() * rGen.Alphabet();
125  // todo stack
126  std::stack< std::pair<Idx,Idx> > todo;
127  // tested transitions are stored here
128  std::map< std::pair<Idx,Idx>, Idx> testedTrans;
129  testedTrans.clear();
130  // current pair, new pair
131  std::pair<Idx,Idx> currentstates, newstates;
132  // state
133  Idx tmpstate = 1;
134  StateSet::Iterator lit1, lit2;
135  TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
136  std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
137 
138  // push all combinations of initial states on todo stack
139  for (lit1 = tildeGen.InitStatesBegin(); lit1 != tildeGen.InitStatesEnd(); ++lit1) {
140  for (lit2 = rGen.InitStatesBegin(); lit2 != rGen.InitStatesEnd(); ++lit2) {
141  currentstates = std::make_pair(*lit1, *lit2);
142  todo.push(currentstates);
143  testedTrans[currentstates] = tmpstate++;
144  }
145  }
146 
147  // start algorithm
148  while (! todo.empty()) {
149  // get next reachable state from todo stack
150  currentstates = todo.top();
151  todo.pop();
152  // iterate over all tildeGen transitions (includes execution of shared events)
153  tit1 = tildeGen.TransRelBegin(currentstates.first);
154  tit1_end = tildeGen.TransRelEnd(currentstates.first);
155  for (; tit1 != tit1_end; ++tit1) {
156  // if event not shared
157  if (! sharedalphabet.Exists(tit1->Ev)) {
158  newstates = std::make_pair(tit1->X2, currentstates.second);
159  // add to todo list if new
160  rcit = testedTrans.find(newstates);
161  if (rcit == testedTrans.end()) {
162  todo.push(newstates);
163  testedTrans[newstates] = tmpstate++;
164  }
165  else {
166  tmpstate = rcit->second;
167  }
168  }
169  // shared event
170  else {
171  // find shared transitions
172  tit2 = rGen.TransRelBegin(currentstates.second, tit1->Ev);
173  tit2_end = rGen.TransRelEnd(currentstates.second, tit1->Ev);
174  // problematic event add it to Ek and leave the procedure
175  if (tit2 == tit2_end) {
176  if (! ek.Exists(tit1->Ev)) {
177  ek.Insert(tit1->Ev);
178  std::cerr << "ConDecExtension: Event " << rGen.EventName(tit1->Ev)
179  << " has been added to Ek." << std::endl;
180  return true;
181  }
182  }
183  for (; tit2 != tit2_end; ++tit2) {
184  newstates = std::make_pair(tit1->X2, tit2->X2);
185  // add to todo list if composition state is new
186  rcit = testedTrans.find(newstates);
187  if (rcit == testedTrans.end()) {
188  todo.push(newstates);
189  testedTrans[newstates] = tmpstate++;
190  }
191  else {
192  tmpstate = rcit->second;
193  }
194  }
195  }
196  }
197  }
198  return false;
199 }
200 
201 } // name space
202 
203 
204 

libFAUDES 2.24g --- 2014.09.15 --- c++ api documentaion by doxygen