mtc_parallel.cpp
Go to the documentation of this file.
1 /** @file mtc_parallel.cpp
2 
3 Methods for parallel composition of multitasking generators
4 
5 */
6 
7 /* FAU Discrete Event Systems Library (libfaudes)
8 
9  Copyright (C) 2008 Matthias Singer
10  Copyright (C) 2007 Thomas Moor
11  Exclusive copyright is granted to Klaus Schmidt
12 
13  This library is free software; you can redistribute it and/or
14  modify it under the terms of the GNU Lesser General Public
15  License as published by the Free Software Foundation; either
16  version 2.1 of the License, or (at your option) any later version.
17 
18  This library is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  Lesser General Public License for more details.
22 
23  You should have received a copy of the GNU Lesser General Public
24  License along with this library; if not, write to the Free Software
25  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
26 
27 
28 #include "mtc_parallel.h"
29 
30 namespace faudes {
31 
32 void mtcParallel(const MtcSystem& rGen1, const MtcSystem& rGen2, MtcSystem& rResGen) {
33  // inputs have to agree on controllability of shared events:
34 #ifdef FAUDES_CHECKED
35  EventSet inconsistent = (rGen1.ControllableEvents()*rGen2.UncontrollableEvents())
36  +(rGen1.UncontrollableEvents()*rGen2.ControllableEvents());
37  if(!inconsistent.Empty()) {
38  std::stringstream errstr;
39  errstr << "mtcParallel: inconsistent controllability flags";
40  throw Exception("mtcParallel::inconsistent controllability flags", errstr.str(), 500);
41  }
42 #endif
43  // prepare result
44  rResGen.Clear();
45 
46  std::map< std::pair<Idx,Idx>, Idx> rcmap;
47 
48  // make parallel composition of inputs
49  mtcParallel(rGen1, rGen2, rcmap, rResGen);
50 
51  // copy controllability of input alphabets (TODO: copy all event attributes as in a Parallel)
52  rResGen.SetControllable(rGen1.ControllableEvents());
53  rResGen.SetControllable(rGen2.ControllableEvents());
54 }
55 
56 
57 // Parallel(rGen1, rGen2, rReverseCompositionMap, res)
58 void mtcParallel(const MtcSystem& rGen1, const MtcSystem& rGen2,
59  std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap,
60  MtcSystem& rResGen) {
61  FD_DF("mtcParallel(" << &rGen1 << "," << &rGen2 << ")");
62  // prepare result
63  rResGen.Clear();
64  rResGen.Name(rGen1.Name()+"||"+rGen2.Name());
65  // rGen1.events() \ rGen2.events()
66  EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet();
67  FD_DF("mtcParallel: shared events: " << sharedalphabet.ToString());
68 
69  // create res alphabet
70  EventSet::Iterator eit;
71  for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) {
72  rResGen.InsEvent(*eit);
73  }
74  for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) {
75  rResGen.InsEvent(*eit);
76  }
77  FD_DF("mtcParallel: inserted indices in rResGen.alphabet( "
78  << rResGen.AlphabetToString() << ")");
79 
80  // todo stack
81  std::stack< std::pair<Idx,Idx> > todo;
82  // actual pair, new pair
83  std::pair<Idx,Idx> currentstates, newstates;
84  // state
85  Idx tmpstate;
86 
87  StateSet::Iterator lit1, lit2;
88  TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
89  std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
90 
91  ColorSet colors1, colors2, composedSet;
92  rGen1.Colors(colors1);
93  rGen2.Colors(colors2);
94 
95  // push all combinations of initial states on todo stack
96  FD_DF("mtcParallel: adding all combinations of initial states to todo:");
97  for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) {
98  for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) {
99  currentstates = std::make_pair(*lit1, *lit2);
100  todo.push(currentstates);
101  tmpstate = rReverseCompositionMap[currentstates] = rResGen.InsInitState();
102  ComposedColorSet(rGen1, *lit1, colors1, rGen2, *lit2, colors2, composedSet);
103  rResGen.InsColors(tmpstate, composedSet);
104  FD_DF("mtcParallel: (" << *lit1 << "|" << *lit2 << ") -> "
105  << rReverseCompositionMap[currentstates]);
106  }
107  }
108 
109  // start algorithm
110  FD_DF("mtcParallel: processing reachable states:");
111  while (! todo.empty()) {
112  // get next reachable state from todo stack
113  currentstates = todo.top();
114  todo.pop();
115  FD_DF("mtcParallel: processing (" << currentstates.first << "|"
116  << currentstates.second << ") -> "
117  << rReverseCompositionMap[currentstates]);
118  // iterate over all rGen1 transitions
119  // (includes execution of shared events)
120  tit1 = rGen1.TransRelBegin(currentstates.first);
121  tit1_end = rGen1.TransRelEnd(currentstates.first);
122  for (; tit1 != tit1_end; ++tit1) {
123  // if event not shared
124  if (! sharedalphabet.Exists(tit1->Ev)) {
125  FD_DF("mtcParallel: exists only in rGen1");
126  newstates = std::make_pair(tit1->X2, currentstates.second);
127  // add to todo list if composition state is new
128  rcit = rReverseCompositionMap.find(newstates);
129  if (rcit == rReverseCompositionMap.end()) {
130  todo.push(newstates);
131  tmpstate = rResGen.InsState();
132  ComposedColorSet(rGen1, tit1->X2, colors1, rGen2, currentstates.second, colors2, composedSet);
133  rResGen.InsColors(tmpstate, composedSet);
134  rReverseCompositionMap[newstates] = tmpstate;
135  FD_DF("mtcParallel: todo push: (" << newstates.first << "|"
136  << newstates.second << ") -> "
137  << rReverseCompositionMap[newstates]);
138  }
139  else {
140  tmpstate = rcit->second;
141  }
142  rResGen.SetTransition(rReverseCompositionMap[currentstates], tit1->Ev,
143  tmpstate);
144  FD_DF("mtcParallel: add transition to new generator: "
145  << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-"
146  << tmpstate);
147  }
148  // if shared event
149  else {
150  FD_DF("mtcParallel: common event");
151  // find shared transitions
152  tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev);
153  tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev);
154  for (; tit2 != tit2_end; ++tit2) {
155  newstates = std::make_pair(tit1->X2, tit2->X2);
156  // add to todo list if composition state is new
157  rcit = rReverseCompositionMap.find(newstates);
158  if (rcit == rReverseCompositionMap.end()) {
159  todo.push(newstates);
160  tmpstate = rResGen.InsState();
161  ComposedColorSet(rGen1, tit1->X2, colors1, rGen2, tit2->X2, colors2, composedSet);
162  rResGen.InsColors(tmpstate, composedSet);
163  rReverseCompositionMap[newstates] = tmpstate;
164  FD_DF("mtcParallel: todo push: (" << newstates.first << "|"
165  << newstates.second << ") -> "
166  << rReverseCompositionMap[newstates]);
167  }
168  else {
169  tmpstate = rcit->second;
170  }
171  rResGen.SetTransition(rReverseCompositionMap[currentstates],
172  tit1->Ev, tmpstate);
173  FD_DF("mtcParallel: add transition to new generator: "
174  << rReverseCompositionMap[currentstates] << "-"
175  << tit1->Ev << "-" << tmpstate);
176  }
177  }
178  }
179  // iterate over all rGen2 transitions
180  // (without execution of shared events)
181  tit2 = rGen2.TransRelBegin(currentstates.second);
182  tit2_end = rGen2.TransRelEnd(currentstates.second);
183  for (; tit2 != tit2_end; ++tit2) {
184  if (! sharedalphabet.Exists(tit2->Ev)) {
185  FD_DF("mtcParallel: exists only in rGen2");
186  newstates = std::make_pair(currentstates.first, tit2->X2);
187  // add to todo list if composition state is new
188  rcit = rReverseCompositionMap.find(newstates);
189  if (rcit == rReverseCompositionMap.end()) {
190  todo.push(newstates);
191  tmpstate = rResGen.InsState();
192  ComposedColorSet(rGen1, currentstates.first, colors1, rGen2, tit2->X2, colors2, composedSet);
193  rResGen.InsColors(tmpstate, composedSet);
194  rReverseCompositionMap[newstates] = tmpstate;
195  FD_DF("mtcParallel: todo push: (" << newstates.first << "|"
196  << newstates.second << ") -> "
197  << rReverseCompositionMap[newstates]);
198  }
199  else {
200  tmpstate = rcit->second;
201  }
202  rResGen.SetTransition(rReverseCompositionMap[currentstates],
203  tit2->Ev, tmpstate);
204  FD_DF("mtcParallel: add transition to new generator: "
205  << rReverseCompositionMap[currentstates] << "-"
206  << tit2->Ev << "-" << tmpstate);
207  }
208  }
209  }
210 }
211 
212  // compose colors
213 void ComposedColorSet(const MtcSystem& rGen1, const Idx sidx1, ColorSet& rColors1,
214  const MtcSystem& rGen2, const Idx sidx2, ColorSet& rColors2,
215  ColorSet& composedSet) {
216 
217  composedSet.Clear();
218 
219  AttributeColoredState attr1, attr2;
220  ColorSet::Iterator cit;
221 
222 #ifdef FAUDES_CHECKED
223  try {
224  attr1 = rGen1.States().Attribute(sidx1);
225  }
226  catch (faudes::Exception& exception){
227  std::stringstream errstr;
228  errstr << "Index " << sidx1 << " not member of set" << std::endl;
229  throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, composedSet)",
230  errstr.str(), 200);
231  }
232  try {
233  attr2 = rGen2.States().Attribute(sidx2);
234  }
235  catch (faudes::Exception& exception){
236  std::stringstream errstr;
237  errstr << "Index " << sidx2 << " not member of set" << std::endl;
238  throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, composedSet)",
239  errstr.str(), 200);
240  }
241 #else
242  attr1 = rGen1.States().Attribute(sidx1);
243  attr2 = rGen2.States().Attribute(sidx2);
244 #endif
245 
246  if(!attr1.IsDefault()) {
247  // iterate over colors in current state of generator 1
248  for (cit = attr1.ColorsBegin(); cit != attr1.ColorsEnd(); cit++) {
249 #ifdef FAUDES_CHECKED
250  if (!rColors1.Exists(*cit))
251  throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, rGenRes, sidxRes)",
252  "Color index \""+ToStringInteger(*cit)+"\" not found in generator's color set rColors1", 201);
253 #endif
254  if(rColors2.Exists(*cit)) {
255  // color also exists in second generator
256  if(!attr2.IsDefault() && attr2.Colors().Exists(*cit)) {
257  // current color exists in second generator's current state
258  // -> insert into composedSet
259  composedSet.Insert(*cit);
260  }
261  }
262  else {
263  // current color does not exist in generator 2
264  // -> insert into composedSet
265  composedSet.Insert(*cit);
266  }
267  }
268  }
269 
270  if(!attr2.IsDefault()) {
271  // iterate over second generator's colors
272  for (cit = attr2.ColorsBegin(); cit != attr2.ColorsEnd(); cit++) {
273 #ifdef FAUDES_CHECKED
274  if (!rColors2.Exists(*cit))
275  throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, rGenRes, sidxRes)",
276  "Color index \""+ToStringInteger(*cit)+"\" not found in generator's color set rColors2", 201);
277 #endif
278  if (!rColors1.Exists(*cit)) {
279  // color does not exist in generator 1
280  // -> insert into composedSet
281  composedSet.Insert(*cit);
282  }
283  }
284  }
285 }
286 
287 } // namespace faudes
#define FD_DF(message)
NameSet::Iterator ColorsEnd() const
const ColorSet & Colors(void) const
NameSet::Iterator ColorsBegin() const
bool Exists(const Idx &rIndex) const
bool Insert(const Idx &rIndex)
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Definition: cfl_transset.h:273
virtual void Clear(void)
bool InsEvent(Idx index)
const TaStateSet< StateAttr > & States(void) const
const TaEventSet< EventAttr > & Alphabet(void) const
bool SetTransition(Idx x1, Idx ev, Idx x2)
EventSet UncontrollableEvents(void) const
EventSet ControllableEvents(void) const
void SetControllable(Idx index)
void InsColors(Idx stateIndex, const ColorSet &rColors)
void Colors(ColorSet &rColors) const
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Definition: cfl_types.cpp:170
StateSet::Iterator InitStatesBegin(void) const
TransSet::Iterator TransRelBegin(void) const
EventSet::Iterator AlphabetBegin(void) const
void Name(const std::string &rName)
TransSet::Iterator TransRelEnd(void) const
StateSet::Iterator InitStatesEnd(void) const
EventSet::Iterator AlphabetEnd(void) const
std::string AlphabetToString(void) const
bool Empty(void) const
Definition: cfl_baseset.h:1841
virtual void Clear(void)
Definition: cfl_baseset.h:1919
void mtcParallel(const MtcSystem &rGen1, const MtcSystem &rGen2, MtcSystem &rResGen)
uint32_t Idx
std::string ToStringInteger(Int number)
Definition: cfl_utils.cpp:43
void ComposedColorSet(const MtcSystem &rGen1, const Idx sidx1, ColorSet &rColors1, const MtcSystem &rGen2, const Idx sidx2, ColorSet &rColors2, ColorSet &composedSet)

libFAUDES 2.33b --- 2025.05.07 --- c++ api documentaion by doxygen