mtc_parallel.cpp
Go to the documentation of this file.
1/** @file mtc_parallel.cpp
2
3Methods 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
30namespace faudes {
31
32void 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())
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)
58void 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
213void 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
const std::string & Name(void) const
bool Exists(const Idx &rIndex) const
bool Insert(const Idx &rIndex)
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
StateSet::Iterator InitStatesBegin(void) const
TransSet::Iterator TransRelBegin(void) const
EventSet::Iterator AlphabetBegin(void) const
TransSet::Iterator TransRelEnd(void) const
StateSet::Iterator InitStatesEnd(void) const
EventSet::Iterator AlphabetEnd(void) const
std::string AlphabetToString(void) const
bool Empty(void) const
virtual void Clear(void)
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.33k --- 2025.09.16 --- c++ api documentaion by doxygen