mtc_project.cpp
Go to the documentation of this file.
1/** @file mtc_project.cpp
2
3Methods for computing the natural projection of multitasking generators
4
5*/
6
7/* FAU Discrete Event Systems Library (libfaudes)
8
9 Copyright (C) 2008 Matthias Singer
10 Copyright (C) 2006 Bernd Opitz
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_project.h"
29#include "cfl_localgen.h"
30
31namespace faudes {
32
33// mtcUniqueInit(rGen&)
35 Idx inituni;
36 StateSet::Iterator lit;
38 // check number of initial states
39 if (rGen.InitStatesSize() <= 1) return;
40 // introduce new initial state
41 if (rGen.StateNamesEnabled()) {
42 std::string initname=rGen.UniqueStateName("InitUni");
43 inituni = rGen.InsState(initname);
44 }
45 else {
46 inituni = rGen.InsState();
47 }
48 FD_DF("mtcUniqueInit: introducing new initial state: " << inituni);
49 // introduce outgoing transitions from initial state
50 FD_DF("mtcUniqueInit: introduce outgoing transitions: ");
51 for (lit = rGen.InitStatesBegin(); lit != rGen.InitStatesEnd(); ++lit) {
52 for (tit = rGen.TransRelBegin(*lit); tit != rGen.TransRelEnd(*lit); ++tit) {
53 rGen.SetTransition(inituni, tit->Ev, tit->X2);
54 FD_DF("mtcUniqueInit: " << inituni << "-" << tit->Ev << "-" << tit->X2);
55 }
56 // colored states
57 const ColorSet& colors = rGen.Colors(*lit);
58 rGen.InsColors(inituni, colors);
59 // marked states
60 if (!rGen.MarkedStatesEmpty()) {
61 rGen.SetMarkedState(inituni);
62 FD_DF("mtcUniqueInit: set marked state: " << inituni);
63 }
64 }
65 // delete old istates
66 rGen.ClearInitStates();
67 // set inituni as new initial state
68 rGen.SetInitState(inituni);
69}
70
71
72// mtcDeterministic(rGen&, rResGen&)
73void mtcDeterministic(const MtcSystem& rGen, MtcSystem& rResGen) {
74 // temporary vectors
75 std::vector<StateSet> power_states;
76 std::vector<Idx> det_states;
77 mtcDeterministic(rGen, power_states, det_states, rResGen);
78}
79
80
81// mtcDeterministic(rGen&, rEntryStatesMap&, rResGen&)
82void mtcDeterministic(const MtcSystem& rGen, std::map<Idx,StateSet>& rEntryStatesMap,
83 MtcSystem& rResGen) {
84 // prepare result:
85 rEntryStatesMap.clear();
86 // helpers:
87 std::vector<StateSet> power_states;
88 std::vector<Idx> det_states;
89 // call Deterministic function
90 mtcDeterministic(rGen, power_states, det_states, rResGen);
91 // build entry states map
92 std::vector<StateSet>::size_type i;
93 for (i = 0; i < power_states.size(); ++i) {
94 rEntryStatesMap.insert(std::pair<Idx,StateSet>(det_states[i], power_states[i]));
95 }
96}
97
98
99void mtcDeterministic(const MtcSystem& rGen, std::vector<StateSet>& rPowerStates,
100 std::vector<Idx>& rDetStates, MtcSystem& rResGen) {
101 // set the name
102 rResGen.Name("Det(" + rGen.Name() + ")");
103
104 // prepare result
105 rPowerStates.clear();
106 rDetStates.clear();
107 rResGen.Clear();
108
109 // copy alphabet
110 rResGen.InjectAlphabet(rGen.Alphabet());
111
112 // helpers
113 TransSetEvX1X2 trel_evx1x2;
114 rGen.TransRel(trel_evx1x2);
115 typedef std::multimap< Idx,std::vector<StateSet>::size_type > T_HASHMAP;
116 T_HASHMAP hashmap;
117 std::vector<StateSet>::size_type current_vecindex;
118 std::pair< std::map<StateSet,Idx>::iterator,bool > result;
119 TransSet::Iterator transrel_end = rGen.TransRelEnd();
120 StateSet newset;
121 StateSet::Iterator lit;
122 const Idx max_idx = std::numeric_limits<Idx>::max();
123 if (rGen.InitStatesEmpty()) {
124 return;
125 }
126// std::map<Idx,ColorSet> CopyMap = rGen.StateColorMap();
127 Idx newstate = rResGen.InsInitState();
128 // initialize rPowerStates with subset of initial states
129 for (lit = rGen.InitStatesBegin(); lit != rGen.InitStatesEnd(); ++lit) {
130 // clear set and insert single state
131 newset.Insert(*lit);
132 const ColorSet& colors = rGen.Colors(*lit);
133 // set colored state if a member state is colored
134 rResGen.InsColors(newstate,colors);
135 }
136 FD_DF("mtcDeterministic: created subset of initial states {"
137 << newset.ToString() << "} with deterministic state index " << rGen.SStr(newstate));
138 // insert newset in rPowerStates
139 rPowerStates.push_back(newset);
140 rDetStates.push_back(newstate);
141 hashmap.insert(std::make_pair(newset.Signature(), (Idx)rPowerStates.size() - 1));
142
143 // iteration over all states
144 for (current_vecindex = 0; current_vecindex < rPowerStates.size(); ++current_vecindex) {
145 FD_DF("mtcDeterministic: current power set: {" << rPowerStates[current_vecindex].ToString() <<
146 "} -> " << rDetStates[current_vecindex]);
147
148 std::vector<StateSet> newset_vec;
149 std::vector<Idx> event_vec;
150
151 // multiway merge begin
152 FD_DF("mtcDeterministic: starting multiway merge...");
153 std::list<TransSet::Iterator> merge_iterators;
154 std::vector<Transition> trans_vec;
155
156 // add transset iterator at begin of each state's transitions
158 for (lit = rPowerStates[current_vecindex].Begin();
159 lit != rPowerStates[current_vecindex].End(); ++lit) {
160 tit = rGen.TransRelBegin(*lit);
161 if (tit != rGen.TransRelEnd(*lit)) {
162 merge_iterators.push_back(tit);
163 FD_DF("mtcDeterministic: added merge iterator: " << rGen.SStr(tit->X1)
164 << "-" << rGen.EStr(tit->Ev) << "-" << rGen.SStr(tit->X2));
165 }
166 }
167
168 // find first iterator with lowest event
169 while (! merge_iterators.empty()) {
170 Idx currentevent = max_idx;
171 std::list<TransSet::Iterator>::iterator i;
172 std::list<TransSet::Iterator>::iterator currentit = merge_iterators.end();
173 for (i = merge_iterators.begin(); i != merge_iterators.end(); ++i) {
174 if ((*i)->Ev < currentevent) {
175 currentevent = (*i)->Ev;
176 currentit = i;
177 }
178 }
179 // currentit now holds the iterator
180 // currentevent holds the lowest event (lowest Idx)
181
182 // merge all transitions with currentevent at each iterator in a row
183 // this is a modification of multiway merge as after projection the
184 // automaton most likely holds states with many transitions that share
185 // the same event. only merging the lowest transition and continue with
186 // search for the lowest event again would be to slow here (because
187 // of too much iterator dereferencing).
188 Idx currentstate;
189 while (currentit != merge_iterators.end()) {
190 currentstate = (*currentit)->X1;
191 TransSet::Iterator& j = *currentit;
192 while (1) {
193 // remove iterator if it reaches the end of the transition set
194 if (j == transrel_end) {
195 std::list<TransSet::Iterator>::iterator tmpit = currentit;
196 ++currentit;
197 merge_iterators.erase(tmpit);
198 break;
199 }
200 // if current iterator is in its original state
201 else if (j->X1 == currentstate) {
202 // if the event is still the same add the transition
203 if (j->Ev == currentevent) {
204 trans_vec.push_back(*j);
205 FD_DF("Determine: adding transition to list: " << rGen.SStr(j->X1)
206 << "-" << rGen.EStr(j->Ev) << "-" << rGen.SStr(j->X2));
207 }
208 // else go to next iterator
209 else {
210 ++currentit;
211 break;
212 }
213 }
214 // if the iterator is beyond its original state remove it
215 else {
216 std::list<TransSet::Iterator>::iterator tmpit = currentit;
217 ++currentit;
218 merge_iterators.erase(tmpit);
219 break;
220 }
221 ++j;
222 }
223 }
224 }
225
226 // partition transition vector by events. optimizable?
227 FD_DF("mtcDeterministic: partitioning the transition vector...");
228 std::vector<Transition>::iterator tv_it;
229 StateSet newset;
230 Idx lastevent = 0;
231 for (tv_it = trans_vec.begin(); tv_it != trans_vec.end(); ++tv_it) {
232 if ((tv_it->Ev == lastevent) || (lastevent == 0)) {
233 newset.Insert(tv_it->X2);
234 lastevent = tv_it->Ev;
235 }
236 else {
237 FD_DF("mtcDeterministic: partition: {" << newset.ToString()
238 << "} with event " << rGen.EStr(lastevent));
239 newset_vec.push_back(newset);
240 event_vec.push_back(lastevent);
241 newset.Clear();
242 newset.Insert(tv_it->X2);
243 lastevent = tv_it->Ev;
244 }
245 }
246 if (! newset.Empty()) {
247 FD_DF("mtcDeterministic: partition: {" << newset.ToString()
248 << "} with event " << rGen.EStr(lastevent));
249 newset_vec.push_back(newset);
250 event_vec.push_back(lastevent);
251 }
252 FD_DF("mtcDeterministic: partitioning the transition vector finished");
253 FD_DF("mtcDeterministic: multiway merge finished");
254 // multiway merge end
255
256 std::vector<StateSet>::size_type nsv_index;
257 for (nsv_index = 0; nsv_index < newset_vec.size(); ++nsv_index) {
258 StateSet& currentset = newset_vec[nsv_index];
259 Idx currentevent = event_vec[nsv_index];
260 Idx tmp_x2 = 0;
261 Idx sig = currentset.Signature();
262 // test if newset signature is already known
263 std::pair<T_HASHMAP::iterator,T_HASHMAP::iterator> phit
264 = hashmap.equal_range(sig);
265 T_HASHMAP::iterator hit = phit.first;
266 for (hit = phit.first; hit != phit.second; ++hit) {
267 // test set of every matching signature for equality
268 if (currentset == rPowerStates[hit->second]) {
269 tmp_x2 = rDetStates[hit->second];
270 break;
271 }
272 }
273
274 // if new set is unique within the existing power sets
275 if (tmp_x2 == 0) {
276 // create new state in res generator
277 tmp_x2 = rResGen.InsState();
278 // insert newset in rPowerStates and get iterator,bool pair
279 rPowerStates.push_back(currentset);
280 rDetStates.push_back(tmp_x2);
281 hashmap.insert(std::make_pair(sig, (Idx)rPowerStates.size() - 1));
282 FD_DF("mtcDeterministic: added new state " << rGen.SStr(tmp_x2)
283 << " for new subset {" << currentset.ToString() << "}");
284 // set colored if one of the states in current set is colored
285 for (lit = currentset.Begin(); lit != currentset.End(); ++lit) {
286 const ColorSet& colors = rGen.Colors(*lit);
287 rResGen.InsColors(tmp_x2,colors);
288 FD_DF("mtcDeterministic: setting as colored: " << rGen.SStr(tmp_x2));
289 }
290 }
291 // introduce transition
292 rResGen.SetTransition(rDetStates[current_vecindex], currentevent, tmp_x2);
293 }
294 }
295 // fix names
296 if (rGen.StateNamesEnabled() && rResGen.StateNamesEnabled()) {
297 FD_DF("mtcDeterministic: fixing names...");
298 // rPowerStates / rDetStates index "iterator"
299 std::vector<StateSet>::size_type i;
300 for (i = 0; i < rPowerStates.size(); ++i) {
301 // temporary state name
302 std::string name = "{";
303 for (lit = rPowerStates[i].Begin(); lit != rPowerStates[i].End(); ++lit) {
304 if (rResGen.StateName(*lit) != "") {
305 name = name + rResGen.StateName(*lit) + ",";
306 }
307 else {
308 name = name + ToStringInteger(*lit) + ",";
309 }
310 }
311 name.erase(name.length() - 1);
312 name = name + "}";
313 rResGen.StateName(rDetStates[i], name);
314 FD_DF("mtcDeterministic: setting state name \"" << name << "\" for index " << rDetStates[i]);
315 }
316 }
317 // Delete unnecessary events and set event attributes
318 rResGen.DelEvents(rResGen.UnusedEvents());
319 EventSet usedEvents = rResGen.UsedEvents();
320 rResGen.SetControllable(rGen.ControllableEvents()*usedEvents);
321 rResGen.SetForcible(rGen.ForcibleEvents()*usedEvents);
322 rResGen.ClrObservable(rGen.UnobservableEvents()*usedEvents);
323}
324
325// mtcProjectNonDet(rGen&, rProjectAlphabet&)
326void mtcProjectNonDet(MtcSystem& rGen, const EventSet& rProjectAlphabet) {
327
328 // HELPERS:
329 StateSet reach; // StateSet for reachable states
330 std::stack<Idx> todo; // todo stack
331 StateSet done; // done set
332 Idx currentstate; // the currently processed state
333 StateSet::Iterator lit;
335 TransSet::Iterator tit_end;
336
337 // ALGORITHM:
338 // initialize algorithm by pushing init states on todo stack
339 for (lit = rGen.InitStatesBegin(); lit != rGen.InitStatesEnd(); ++lit) {
340 FD_DF("mtcProjectNonDet: todo add: " << rGen.SStr(*lit));
341 todo.push(*lit);
342 }
343
344 // process todo stack
345 while (! todo.empty()) {
346 currentstate = todo.top();
347 todo.pop();
348 done.Insert(currentstate); // mark as done
349 FD_DF("mtcProjectNonDet: current state: " << rGen.SStr(currentstate));
350
351 // comp accessible reach
352 reach.Clear();
353 LocalAccessibleReach(rGen, rProjectAlphabet, currentstate, reach);
354 FD_DF("mtcProjectNonDet: local reach: " << reach.ToString());
355
356 // remove all transitions that leave current state
357 // with an invisible event
358 tit = rGen.TransRelBegin(currentstate);
359 tit_end = rGen.TransRelEnd(currentstate);
360 while(tit != tit_end) {
361 FD_DF("mtcProjectNonDet: current transition: " << rGen.SStr(tit->X1)
362 << "-" << rGen.EStr(tit->Ev) << "-" << rGen.SStr(tit->X2));
363 if (! rProjectAlphabet.Exists(tit->Ev)) {
364 FD_DF("mtcProjectNonDet: deleting current transition");
365 TransSet::Iterator tit_tmp = tit;
366 ++tit;
367 rGen.ClrTransition(tit_tmp);
368 }
369 else {
370 ++tit;
371 }
372 }
373
374 // relink outgoing transitions
375 FD_DF("mtcProjectNonDet: relinking outgoing transitions...");
376 for (lit = reach.Begin(); lit != reach.End(); ++lit) {
377 tit = rGen.TransRelBegin(*lit);
378 tit_end = rGen.TransRelEnd(*lit);
379 for (; tit != tit_end; ++tit) {
380 if (rProjectAlphabet.Exists(tit->Ev)) {
381 FD_DF("mtcProjectNonDet: relinking transition: " << rGen.TStr(*tit) << " to " << rGen.SStr(currentstate) << "--(" << rGen.EStr(tit->Ev) << ")-->" << rGen.SStr(tit->X2));
382 rGen.SetTransition(currentstate, tit->Ev, tit->X2);
383 if (! done.Exists(tit->X2)) {
384 FD_DF("mtcProjectNonDet: todo push: " << rGen.SStr(tit->X2));
385 todo.push(tit->X2);
386 }
387 }
388 }
389 // colored status test
390 const ColorSet& colors = rGen.Colors(*lit);
391 if (!colors.Empty()) {
392 FD_DF("mtcProjectNonDet: setting colored state " << rGen.SStr(currentstate));
393 rGen.InsColors(currentstate, colors);
394 }
395 }
396 }
397
398 // inject projection alphabet
399 rGen.InjectAlphabet(rProjectAlphabet);
400
401 EventSet unused = rGen.UnusedEvents();
402 EventSet::Iterator eit;
403 for(eit = unused.Begin(); eit != unused.End(); ++eit){
404 rGen.ClrEventAttribute(*eit);
405 rGen.EventSymbolTablep()->ClrEntry(*eit);
406 rGen.DelEvent(*eit);
407 }
408 // set name
409 rGen.Name("MtcPro(" + rGen.Name() + ")" );
410}
411
412// wrapper
413void mtcProjectNonDet(const MtcSystem& rGen, const EventSet& rProjectAlphabet, MtcSystem& rResGen) {
414 rResGen=rGen;
415 mtcProjectNonDet(rResGen,rProjectAlphabet);
416}
417
418// mtcProject(rGen, rProjectAlphabet, rResGen&)
419void mtcProject(const MtcSystem& rGen, const EventSet& rProjectAlphabet, MtcSystem& rResGen) {
420 // algorithm:
421 // temporary copy of rGen
422 MtcSystem tmp;
423 // temporarily assign rGen to rResGen
424 MtcSystem copyGen = MtcSystem(rGen);
425 // project rResGen with respect to rProjectAlphabet
426 mtcProjectNonDet(copyGen, rProjectAlphabet);
427#ifdef FAUDES_DEBUG_FUNCTION
428 FD_WARN("mtcProject: debug out")
429 copyGen.Write("tmp_project_nd.gen");
430#endif
431 // put deterministic result into tmp
432 mtcDeterministic(copyGen, tmp);
433#ifdef FAUDES_DEBUG_FUNCTION
434 FD_WARN("mtcProject: debug out")
435 tmp.Write("tmp_project_d.gen");
436#endif
437 // minimize states and rewrite result to rResGen
438 mtcStateMin(tmp, rResGen);
439#ifdef FAUDES_DEBUG_FUNCTION
440 FD_WARN("mtcProject: debug out")
441 rResGen.Write("tmp_project_m.gen");
442#endif
443 // set controllability status TODO: other event attributes
444 rResGen.SetControllable(rGen.ControllableEvents()*rProjectAlphabet);
445 // set name
446 rResGen.Name(rResGen.Name()+": mtcProject");
447}
448
449
450// mtcProject(rGen, rProjectAlphabet, rEntryStatesMap&, rResGen&)
451void mtcProject(const MtcSystem& rGen, const EventSet& rProjectAlphabet,
452 std::map<Idx,StateSet>& rEntryStatesMap, MtcSystem& rResGen) {
453 // temporary copy of rGen
454 MtcSystem tmp;
455 MtcSystem copyGen = MtcSystem(rGen);
456 // temporary entry state map
457 std::map<Idx,StateSet> tmp_entrystatemap;
458 // temporarily assign rGen to rResGen
459 // std::cout << " copied low-level generator " << std::endl;
460 // copyGen.DWrite();
461 // project tmp with respect to palphabet
462 mtcProjectNonDet(copyGen, rProjectAlphabet);
463
464 // put deterministic result into tmp
465 mtcDeterministic(copyGen, tmp_entrystatemap, tmp);
466 // write entry state map for minimized generator
467 std::vector<StateSet> subsets;
468 std::vector<Idx> newindices;
469 // minimize states and rewrite result to rResGen
470 mtcStateMin(tmp, rResGen, subsets, newindices);
471 // rResGen.DWrite();
472 // build entry state map
473 std::vector<StateSet>::size_type i;
474 std::map<Idx,StateSet>::iterator esmit;
475 StateSet::Iterator sit;
476 for (i = 0; i < subsets.size(); ++i) {
477 StateSet tmpstates;
478 for (sit = subsets[i].Begin(); sit != subsets[i].End(); ++sit) {
479 esmit = tmp_entrystatemap.find(*sit);
480#ifdef FD_CHECKED
481 if (esmit == tmp_entrystatemap.end()) {
482 FD_WARN("mtcproject internal error");
483 abort();
484 }
485#endif
486 // insert entry states in temporary StateSet
487 tmpstates.InsertSet(esmit->second);
488 }
489
490 rEntryStatesMap.insert(std::make_pair(newindices[i], tmpstates));
491 }
492}
493
494
495// mtcInvProject(rGen&, rProjectAlphabet)
496void mtcInvProject(MtcSystem& rGen, const EventSet& rProjectAlphabet) {
497 // test if the alphabet of the generator is included in the given alphabet
498 if(! (rProjectAlphabet >= rGen.Alphabet() ) ){
499 std::stringstream errstr;
500 errstr << "Input alphabet has to contain alphabet of generator \"" << rGen.Name() << "\"";
501 throw Exception("InvProject(Generator,EventSet)", errstr.str(), 506);
502 }
503 EventSet newevents = rProjectAlphabet - rGen.Alphabet();
504 // insert events into generator
505 rGen.InsEvents(newevents);
506 FD_DF("mtcInvProject: adding events \"" << newevents.ToString() << "\" at every state");
507 StateSet::Iterator lit;
508 EventSet::Iterator eit;
509 for (lit = rGen.StatesBegin(); lit != rGen.StatesEnd(); ++lit) {
510 for (eit = newevents.Begin(); eit != newevents.End(); ++eit)
511 rGen.SetTransition(*lit, *eit, *lit);
512 }
513}
514
515// RTI wrapper
516void mtcInvProject(const MtcSystem& rGen, const EventSet& rProjectAlphabet, MtcSystem& rResGen) {
517 rResGen=rGen;
518 mtcInvProject(rResGen,rProjectAlphabet);
519}
520
521} // namespace faudes
#define FD_WARN(message)
#define FD_DF(message)
const std::string & Name(void) const
Idx Signature(void) const
bool Exists(const Idx &rIndex) const
void ClrEntry(Idx index)
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
virtual void Clear(void)
const TaEventSet< EventAttr > & Alphabet(void) const
bool SetTransition(Idx x1, Idx ev, Idx x2)
const ATransSet & TransRel(void) const
void InjectAlphabet(const EventSet &rNewalphabet)
void ClrObservable(Idx index)
EventSet ControllableEvents(void) const
void SetControllable(Idx index)
EventSet ForcibleEvents(void) const
void SetForcible(Idx index)
EventSet UnobservableEvents(void) const
void InsColors(Idx stateIndex, const ColorSet &rColors)
void Colors(ColorSet &rColors) const
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
void Write(const Type *pContext=0) const
StateSet::Iterator StatesBegin(void) const
StateSet::Iterator InitStatesBegin(void) const
bool InitStatesEmpty(void) const
void DelEvents(const EventSet &rEvents)
TransSet::Iterator TransRelBegin(void) const
void ClrTransition(Idx x1, Idx ev, Idx x2)
SymbolTable * EventSymbolTablep(void) const
bool DelEvent(Idx index)
Idx InitStatesSize(void) const
void InsEvents(const EventSet &events)
bool MarkedStatesEmpty(void) const
void SetInitState(Idx index)
std::string TStr(const Transition &rTrans) const
std::string StateName(Idx index) const
StateSet::Iterator StatesEnd(void) const
TransSet::Iterator TransRelEnd(void) const
std::string EStr(Idx index) const
void SetMarkedState(Idx index)
bool StateNamesEnabled(void) const
StateSet::Iterator InitStatesEnd(void) const
EventSet UsedEvents(void) const
EventSet UnusedEvents(void) const
virtual void ClrEventAttribute(Idx index)
std::string SStr(Idx index) const
std::string UniqueStateName(const std::string &rName) const
bool Empty(void) const
bool Exists(const T &rElem) const
virtual void Clear(void)
Iterator End(void) const
virtual void InsertSet(const TBaseSet &rOtherSet)
Iterator Begin(void) const
void mtcProject(const MtcSystem &rGen, const EventSet &rProjectAlphabet, MtcSystem &rResGen)
void mtcInvProject(MtcSystem &rGen, const EventSet &rProjectAlphabet)
void mtcProjectNonDet(MtcSystem &rGen, const EventSet &rProjectAlphabet)
void mtcDeterministic(const MtcSystem &rGen, MtcSystem &rResGen)
uint32_t Idx
void mtcStateMin(MtcSystem &rGen, MtcSystem &rResGen)
void mtcUniqueInit(MtcSystem &rGen)
TmtcGenerator< AttributeVoid, AttributeColoredState, AttributeCFlags, AttributeVoid > MtcSystem
void LocalAccessibleReach(const Generator &rLowGen, const EventSet &rHighAlph, Idx lowState, StateSet &rAccessibleReach)
std::string ToStringInteger(Int number)
Definition cfl_utils.cpp:43

libFAUDES 2.34d --- 2026.03.11 --- c++ api documentaion by doxygen