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)
Debug: optional report on user functions.
State attributes for multitasking automata.
NameSet::Iterator ColorsEnd() const
Iterator for last entry in mColors.
const ColorSet & Colors(void) const
Read access to color set.
NameSet::Iterator ColorsBegin() const
Iterator for first entry in mColors.
bool IsDefault(void) const
Test for default value.
Container for colors: this is a NameSet with its own static symboltable.
Definition: mtc_colorset.h:41
Faudes exception class.
Set of indices with symbolic names.
Definition: cfl_nameset.h:69
bool Exists(const Idx &rIndex) const
Test existence of index.
bool Insert(const Idx &rIndex)
Add an element by index.
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Iterator on transition.
Definition: cfl_transset.h:269
Idx InsState(void)
Add new anonymous state to generator.
virtual void Clear(void)
Clear generator data.
bool InsEvent(Idx index)
Add an existing event to alphabet by index.
const TaStateSet< StateAttr > & States(void) const
Return reference to state set.
const TaEventSet< EventAttr > & Alphabet(void) const
Return const reference to alphabet.
bool SetTransition(Idx x1, Idx ev, Idx x2)
Add a transition to generator by indices.
EventSet UncontrollableEvents(void) const
Get EventSet with uncontrollable events.
EventSet ControllableEvents(void) const
Get EventSet with controllable events.
void SetControllable(Idx index)
Mark event controllable (by index)
Allows to create colored marking generators (CMGs) as the common five tupel consisting of alphabet,...
Definition: mtc_generator.h:53
void InsColors(Idx stateIndex, const ColorSet &rColors)
Insert multiple colors from a color set into an existing state.
void Colors(ColorSet &rColors) const
Insert all colors used in the generator to a given ColorSet.
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Write configuration data to a string.
Definition: cfl_types.cpp:169
StateSet::Iterator InitStatesBegin(void) const
Iterator to Begin() of mInitStates.
TransSet::Iterator TransRelBegin(void) const
Iterator to Begin() of transition relation.
EventSet::Iterator AlphabetBegin(void) const
Iterator to Begin() of alphabet.
void Name(const std::string &rName)
Set the generator's name.
TransSet::Iterator TransRelEnd(void) const
Iterator to End() of transition relation.
Idx InsInitState(void)
Create new anonymous state and set as initial state.
StateSet::Iterator InitStatesEnd(void) const
Iterator to End() of mInitStates.
EventSet::Iterator AlphabetEnd(void) const
Iterator to End() of alphabet.
std::string AlphabetToString(void) const
Write generators alphabet to string.
bool Empty(void) const
Test whether if the TBaseSet is Empty.
Definition: cfl_baseset.h:1824
virtual void Clear(void)
Clear all set.
Definition: cfl_baseset.h:1902
void mtcParallel(const MtcSystem &rGen1, const MtcSystem &rGen2, MtcSystem &rResGen)
Parallel composition of two colored marking generators, controllability status is observed.
Methods for parallel composition of multitasking generators.
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
void ComposedColorSet(const MtcSystem &rGen1, const Idx sidx1, ColorSet &rColors1, const MtcSystem &rGen2, const Idx sidx2, ColorSet &rColors2, ColorSet &composedSet)
Compose the color set for a state combined from two states in two distinct automata.
std::string ToStringInteger(Int number)
integer to string
Definition: cfl_helper.cpp:43

libFAUDES 2.32b --- 2024.03.01 --- c++ api documentaion by doxygen