omg_rabinctrlpartialobs.cpp
Go to the documentation of this file.
1 /** @file omg_rabinctrlpartialobs.cpp Rabin control synthesis under partial observation */
2 
4 
5 namespace faudes {
6 
7 // ============================================================================
8 // Helper Functions
9 // ============================================================================
10 
11 // ExtractEventAttributes(rSys, rControllableEvents, rObservableEvents)
12 void ExtractEventAttributes(const System& rSys,
13  EventSet& rControllableEvents,
14  EventSet& rObservableEvents) {
15  FD_DF("ExtractEventAttributes()");
16 
17  rControllableEvents.Clear();
18  rObservableEvents.Clear();
19 
20  // Extract controllable events
21  rControllableEvents = rSys.ControllableEvents();
22 
23  // Extract observable events
24  rObservableEvents = rSys.ObservableEvents();
25 
26  FD_DF("ExtractEventAttributes: controllable events: " << rControllableEvents.ToString());
27  FD_DF("ExtractEventAttributes: observable events: " << rObservableEvents.ToString());
28 }
29 
30 // RabinCtrlPartialObsConsistencyCheck
32  const RabinAutomaton& rSpec,
33  const EventSet& rControllableEvents,
34  const EventSet& rObservableEvents) {
35  FD_DF("RabinCtrlPartialObsConsistencyCheck()");
36 
37  // Check that alphabets match
38  if (rPlant.Alphabet() != rSpec.Alphabet()) {
39  EventSet only_in_plant = rPlant.Alphabet() - rSpec.Alphabet();
40  EventSet only_in_spec = rSpec.Alphabet() - rPlant.Alphabet();
41  only_in_plant.Name("OnlyInPlant");
42  only_in_spec.Name("OnlyInSpec");
43  std::stringstream errstr;
44  errstr << "Alphabets of plant and specification do not match.";
45  if(!only_in_plant.Empty())
46  errstr << " " << only_in_plant.ToString() << ".";
47  if(!only_in_spec.Empty())
48  errstr << " " << only_in_spec.ToString() << ".";
49  throw Exception("RabinCtrlPartialObs", errstr.str(), 100);
50  }
51 
52  // Check that controllable events are subset of alphabet
53  if (!(rControllableEvents <= rPlant.Alphabet())) {
54  EventSet not_in_alphabet = rControllableEvents - rPlant.Alphabet();
55  std::stringstream errstr;
56  errstr << "Controllable events not subset of alphabet: "
57  << not_in_alphabet.ToString();
58  throw Exception("RabinCtrlPartialObs", errstr.str(), 305);
59  }
60 
61  // Check that observable events are subset of alphabet
62  if (!(rObservableEvents <= rPlant.Alphabet())) {
63  EventSet not_in_alphabet = rObservableEvents - rPlant.Alphabet();
64  std::stringstream errstr;
65  errstr << "Observable events not subset of alphabet: "
66  << not_in_alphabet.ToString();
67  throw Exception("RabinCtrlPartialObs", errstr.str(), 306);
68  }
69 
70  // Check that plant and spec are deterministic
71  bool plant_det = rPlant.IsDeterministic();
72  bool spec_det = rSpec.IsDeterministic();
73 
74  if (!plant_det && !spec_det) {
75  throw Exception("RabinCtrlPartialObs",
76  "Both plant and specification must be deterministic", 204);
77  } else if (!plant_det) {
78  throw Exception("RabinCtrlPartialObs",
79  "Plant must be deterministic", 201);
80  } else if (!spec_det) {
81  throw Exception("RabinCtrlPartialObs",
82  "Specification must be deterministic", 203);
83  }
84 
85  FD_DF("RabinCtrlPartialObsConsistencyCheck: passed all checks");
86 }
87 
88 // ============================================================================
89 // Main API Functions
90 // ============================================================================
91 
92 // RabinCtrlPartialObs (System interface - automatic event attribute extraction)
93 void RabinCtrlPartialObs(const System& rPlant,
94  const RabinAutomaton& rSpec,
95  RabinAutomaton& rSupervisor) {
96  FD_DF("RabinCtrlPartialObs: System interface");
97 
98  // Extract controllable and observable events from System
99  EventSet controllableEvents, observableEvents;
100  ExtractEventAttributes(rPlant, controllableEvents, observableEvents);
101 
102  // Events extracted successfully
103 
104  // Call main implementation with the System cast to RabinAutomaton
105  RabinCtrlPartialObs(static_cast<const RabinAutomaton&>(rPlant),
106  controllableEvents, observableEvents, rSpec, rSupervisor);
107 }
108 
109 // RabinCtrlPartialObs (explicit event sets)
111  const EventSet& rControllableEvents,
112  const EventSet& rObservableEvents,
113  const RabinAutomaton& rSpec,
114  RabinAutomaton& rSupervisor) {
115  FD_DF("RabinCtrlPartialObs: explicit event sets");
116 
117  // CONSISTENCY CHECKS
118  if (rControllableEvents.Empty()) {
119  throw Exception("RabinCtrlPartialObs", "Empty controllable event set", 300);
120  }
121 
122  if (rObservableEvents.Empty()) {
123  throw Exception("RabinCtrlPartialObs", "Empty observable event set", 301);
124  }
125 
126  if (rSpec.Empty()) {
127  throw Exception("RabinCtrlPartialObs", "Empty specification language", 302);
128  }
129 
130  RabinCtrlPartialObsConsistencyCheck(rPlant, rSpec, rControllableEvents, rObservableEvents);
131 
132  // PREPARE RESULT
133  RabinAutomaton* pSupervisor = &rSupervisor;
134  if (&rSupervisor == &rPlant || &rSupervisor == &rSpec) {
135  pSupervisor = new RabinAutomaton();
136  }
137  pSupervisor->Clear();
138  pSupervisor->Name("RabinCtrlPartialObs(" + rPlant.Name() + "," + rSpec.Name() + ")");
139 
140  try {
141  FD_DF("RabinCtrlPartialObs: Starting synthesis algorithm");
142 
143  // STEP 1: Compute synchronous product of plant and specification
144  FD_DF("RabinCtrlPartialObs: Step 1 - Computing product");
146  RabinBuechiProduct(rSpec, rPlant, Product);
147 
148  if (Product.Empty()) {
149  throw Exception("RabinCtrlPartialObs",
150  "Product of plant and specification is empty", 302);
151  }
152 
153  FD_DF("RabinCtrlPartialObs: Product computed, states: " << Product.Size());
154 
155  // STEP 2: Apply epsilon observation directly on product (skip control pattern expansion)
156  FD_DF("RabinCtrlPartialObs: Step 2 - Applying epsilon observation directly on product");
157  RabinAutomaton epsObserved;
158 
159  Product.SetControllable(rControllableEvents);
160 
161  EventSet allProductEvents = Product.Alphabet();
162  Product.ClrObservable(allProductEvents);
163  Product.SetObservable(rObservableEvents);
164  // Apply epsilon observation directly on the product
165  EpsObservation(Product, epsObserved);
166 
167  if (epsObserved.Empty()) {
168  throw Exception("RabinCtrlPartialObs",
169  "Epsilon observation resulted in empty automaton", 303);
170  }
171 
172  FD_DF("RabinCtrlPartialObs: Epsilon observation applied, states: " << epsObserved.Size());
173 
174  // STEP 3: Pseudo-determinize the result
175  FD_DF("RabinCtrlPartialObs: Step 3 - Pseudo-determinization");
176  PseudoDet(epsObserved, *pSupervisor);
177 
178  if (pSupervisor->Empty()) {
179  throw Exception("RabinCtrlPartialObs",
180  "Pseudo-determinization resulted in empty automaton", 303);
181  }
182 
183  FD_DF("RabinCtrlPartialObs: Pseudo-determinization completed, states: " << pSupervisor->Size());
184 
185  // Keep the alphabet as computed by PseudoDet (includes epsilon events)
186  // Do not reset to original plant alphabet since we need eps events
187 
188  FD_DF("RabinCtrlPartialObs: Synthesis completed successfully");
189 
190  } catch (const Exception& ex) {
191  FD_DF("RabinCtrlPartialObs: Exception caught: " << ex.What());
192 
193  // Clean up and re-throw
194  if (pSupervisor != &rSupervisor) {
195  delete pSupervisor;
196  }
197  throw;
198  }
199 
200  // Copy result if needed
201  if (pSupervisor != &rSupervisor) {
202  rSupervisor = *pSupervisor;
203  delete pSupervisor;
204  }
205 
206  FD_DF("RabinCtrlPartialObs: completed");
207 }
208 
209 // ControlAut - Apply controller to filter transitions and create Buchi automaton
210 void ControlAut(const RabinAutomaton& rsDRA,
211  const TaIndexSet<EventSet>& rController,
212  Generator& rRes) {
213  FD_DF("ControlAut()");
214 
215  // Clear result automaton
216  Generator* pRes = &rRes;
217  if (&rRes == &rsDRA) {
218  pRes = new Generator();
219  }
220  pRes->Clear();
221  pRes->Name("ControlAut(" + rsDRA.Name() + ")");
222 
223  // Copy alphabet from source automaton
224  pRes->InjectAlphabet(rsDRA.Alphabet());
225 
226  // Copy only states that are in the controller
227  StateSet::Iterator sit;
228  for (sit = rsDRA.StatesBegin(); sit != rsDRA.StatesEnd(); ++sit) {
229  if (rController.Exists(*sit)) {
230  pRes->InsState(*sit);
231  }
232  }
233 
234  // Set initial states (only if they exist in the controller)
235  StateSet::Iterator iit;
236  for (iit = rsDRA.InitStatesBegin(); iit != rsDRA.InitStatesEnd(); ++iit) {
237  if (rController.Exists(*iit)) {
238  pRes->SetInitState(*iit);
239  }
240  }
241 
242  // Mark all states (create Buchi automaton)
243  for (sit = pRes->StatesBegin(); sit != pRes->StatesEnd(); ++sit) {
244  pRes->SetMarkedState(*sit);
245  }
246 
247  // Add self-loops for unobservable events in each state (step 2)
248  EventSet unobservableEvents = rsDRA.Alphabet() - rsDRA.ObservableEvents();
249  for (sit = pRes->StatesBegin(); sit != pRes->StatesEnd(); ++sit) {
250  EventSet::Iterator eit;
251  for (eit = unobservableEvents.Begin(); eit != unobservableEvents.End(); ++eit) {
252  pRes->SetTransition(*sit, *eit, *sit);
253  FD_DF("ControlAut: Adding unobservable self-loop " << *sit << " --" <<
254  rsDRA.EventName(*eit) << "--> " << *sit);
255  }
256  }
257 
258  // Filter transitions based on controller
259  TransSet::Iterator tit;
260  for (tit = rsDRA.TransRelBegin(); tit != rsDRA.TransRelEnd(); ++tit) {
261  Idx state = tit->X1;
262  Idx event = tit->Ev;
263  Idx nextState = tit->X2;
264 
265  // Check if this state has controller restrictions
266  if (rController.Exists(state)) {
267  const EventSet& allowedEvents = rController.Attribute(state);
268  // Only add transition if event is allowed by controller
269  if (allowedEvents.Exists(event)) {
270  pRes->SetTransition(state, event, nextState);
271  FD_DF("ControlAut: Adding transition " << state << " --" <<
272  rsDRA.EventName(event) << "--> " << nextState);
273  } else {
274  FD_DF("ControlAut: Filtering out transition " << state << " --" <<
275  rsDRA.EventName(event) << "--> " << nextState << " (not allowed by controller)");
276  }
277  } else {
278  // Skip transitions from states not in controller (they are deleted)
279  FD_DF("ControlAut: Skipping transition " << state << " --" <<
280  rsDRA.EventName(event) << "--> " << nextState << " (state not in controller)");
281  }
282  }
283 
284  // Copy result if needed
285  if (pRes != &rRes) {
286  rRes = *pRes;
287  delete pRes;
288  }
289 
290 
291  FD_DF("ControlAut: Generated Buchi automaton with " << rRes.Size() <<
292  " states and " << rRes.TransRelSize() << " transitions");
293  FD_DF("ControlAut: All " << rRes.MarkedStatesSize() << " states are marked");
294 }
295 
296 // ============================================================================
297 // Epsilon Observation Functions
298 // ============================================================================
299 
300 void EpsObservation(const RabinAutomaton& rGen, RabinAutomaton& rRes) {
301  rRes = rGen; // Copy original automaton
302 
303  // Get unobservable events
304  EventSet unobservableEvents = rRes.UnobservableEvents();
305 
306  // If no unobservable events, return original automaton
307  if(unobservableEvents.Size() == 0) {
308  return;
309  }
310 
311  // Create single epsilon event
312  std::string epsEventName = "eps";
313  Idx epsEvent = rRes.InsEvent(epsEventName);
314 
315  // Set epsilon event as uncontrollable and unobservable
316  rRes.ClrControllable(epsEvent);
317  rRes.ClrObservable(epsEvent);
318  rRes.ClrForcible(epsEvent);
319 
320  // Step 1: Replace transitions
321  TransSet originalTransitions = rRes.TransRel(); // Get copy of original transition relation
322 
323  TransSet::Iterator tit;
324  for(tit = originalTransitions.Begin(); tit != originalTransitions.End(); ++tit) {
325  if(unobservableEvents.Exists(tit->Ev)) {
326  // This transition uses an unobservable event that should be replaced
327 
328  // Remove original transition
329  rRes.ClrTransition(tit->X1, tit->Ev, tit->X2);
330 
331  // Add new transition using epsilon
332  rRes.SetTransition(tit->X1, epsEvent, tit->X2);
333  }
334  }
335 
336  // Step 2: Remove old unobservable events from alphabet
337  EventSet::Iterator uit;
338  for(uit = unobservableEvents.Begin(); uit != unobservableEvents.End(); ++uit) {
339  rRes.DelEvent(*uit);
340  }
341 }
342 
343 void EpsObservation(const System& rGen, System& rRes) {
344  rRes = rGen; // Copy original generator
345 
346  // Get unobservable events
347  EventSet unobservableEvents = rRes.UnobservableEvents();
348 
349  // If no unobservable events, return original generator
350  if(unobservableEvents.Size() == 0) {
351  return;
352  }
353 
354  // Create single epsilon event
355  std::string epsEventName = "eps";
356  Idx epsEvent = rRes.InsEvent(epsEventName);
357 
358  // Set epsilon event as uncontrollable and unobservable
359  rRes.ClrControllable(epsEvent);
360  rRes.ClrObservable(epsEvent);
361  rRes.ClrForcible(epsEvent);
362 
363  // Step 1: Replace transitions
364  TransSet originalTransitions = rRes.TransRel(); // Get copy of original transition relation
365 
366  TransSet::Iterator tit;
367  for(tit = originalTransitions.Begin(); tit != originalTransitions.End(); ++tit) {
368  if(unobservableEvents.Exists(tit->Ev)) {
369  // This transition uses an unobservable event that should be replaced
370 
371  // Remove original transition
372  rRes.ClrTransition(tit->X1, tit->Ev, tit->X2);
373 
374  // Add new transition using epsilon
375  rRes.SetTransition(tit->X1, epsEvent, tit->X2);
376  }
377  }
378 
379  // Step 2: Remove old unobservable events from alphabet
380  EventSet::Iterator uit;
381  for(uit = unobservableEvents.Begin(); uit != unobservableEvents.End(); ++uit) {
382  rRes.DelEvent(*uit);
383  }
384 }
385 
386 // ============================================================================
387 // Language Verification Functions
388 // ============================================================================
389 
390 Generator CreateMutedAutomaton(const Generator& rOriginal, const StateSet& rStatesToMute) {
391  Generator muted = rOriginal;
392 
393  // Remove transitions to and from muted states
394  TransSet::Iterator tit = muted.TransRelBegin();
395  while (tit != muted.TransRelEnd()) {
396  if (rStatesToMute.Exists(tit->X1) || rStatesToMute.Exists(tit->X2)) {
397  TransSet::Iterator tit_del = tit;
398  ++tit;
399  muted.ClrTransition(*tit_del);
400  } else {
401  ++tit;
402  }
403  }
404 
405  // Remove muted states from state set
406  StateSet::Iterator sit;
407  for (sit = rStatesToMute.Begin(); sit != rStatesToMute.End(); ++sit) {
408  if (muted.ExistsState(*sit)) {
409  muted.DelState(*sit);
410  }
411  }
412 
413  return muted;
414 }
415 
416 bool RabinLanguageInclusion(const System& rGenL, const RabinAutomaton& rRabK) {
417  FD_DF("RabinLanguageInclusion(): Starting language inclusion verification");
418 
419  // Step 1: Create copies of genL and rabK
420  Generator genL_copy = rGenL; // Buechi automaton to accept L
421  RabinAutomaton rabK_copy = rRabK; // Rabin automaton to accept K
422 
423  // Step 2: Apply BuechiTrim and RabinTrim respectively
424  bool genL_trim_result = IsBuechiTrim(genL_copy);
425  bool rabK_trim_result = IsRabinTrim(rabK_copy);
426 
427  if (!genL_trim_result) {
428  FD_DF("RabinLanguageInclusion(): genL trim failed");
429  return false;
430  }
431 
432  if (!rabK_trim_result) {
433  FD_DF("RabinLanguageInclusion(): rabK trim failed");
434  return false;
435  }
436 
437  // Step 3: Mark all states to generate closure(L) and closure(K)
438  genL_copy.InjectMarkedStates(genL_copy.States());
439  rabK_copy.InjectMarkedStates(rabK_copy.States());
440 
441  // Step 4: Test ordinary *-language inclusion: closure(L) ⊆ closure(K)
442  bool closure_inclusion = LanguageInclusion(genL_copy, rabK_copy);
443 
444  if (closure_inclusion) {
445  std::cout << "✓ closure(SupervisedSystem) ⊆ closure(specification)" << std::endl;
446  return true;
447  }
448  else {
449  std::cout << "RabinLanguageInclusion(): Closure inclusion failed - bailing out" << std::endl;
450  return false;
451  }
452 
453  // Step 5: Use Automaton() on original genL and rabK to make them full
454  Generator genL_full = rGenL;
455  RabinAutomaton rabK_full = rRabK;
456 
457  // Make automata complete (full)
458  genL_full.Complete();
459  rabK_full.Complete();
460 
461  FD_DF("RabinLanguageInclusion(): Step 5: Made automata complete - genL: " << genL_full.Size()
462  << " states, rabK: " << rabK_full.Size() << " states");
463 
464  // Step 6: Use RabinBuechiAutomaton to construct product system
465  RabinAutomaton rgProduct;
466  RabinBuechiAutomaton(rabK_full, genL_full, rgProduct);
467  rgProduct.Name("Product System (rabK x genL)");
468 
469  if (rgProduct.Size() == 0) {
470  FD_DF("RabinLanguageInclusion(): Empty product system - languages are disjoint");
471  return false;
472  }
473 
474  // Make product accessible
475  rgProduct.Accessible();
476 
477  // Step 7: Continue with SCC analysis on rgProduct
478 
479  // Identify L-marked states in product (corresponding to genL marked states)
480  StateSet lMarkedInProduct;
481  StateSet::Iterator sit;
482  for (sit = rgProduct.StatesBegin(); sit != rgProduct.StatesEnd(); ++sit) {
483  if (rgProduct.ExistsMarkedState(*sit)) {
484  lMarkedInProduct.Insert(*sit);
485  }
486  }
487 
488  FD_DF("RabinLanguageInclusion(): Found " << lMarkedInProduct.Size() << " L-marked states in product");
489 
490  // Process each Rabin pair from original specification
491  const RabinAcceptance& acceptance = rRabK.RabinAcceptance();
492  RabinAcceptance::CIterator rait;
493 
494  for (rait = acceptance.Begin(); rait != acceptance.End(); ++rait) {
495  const StateSet& R = rait->RSet(); // R set (must be visited infinitely often)
496  const StateSet& I = rait->ISet(); // I set (complement will be muted)
497 
498  FD_DF("RabinLanguageInclusion(): Processing Rabin pair: R=" << R.ToString() << ", I=" << I.ToString());
499 
500  // Create states to mute: L-marked states + complement of I
501  StateSet statesToMute = lMarkedInProduct;
502 
503  // Add complement of I to muted states
504  for (sit = rgProduct.StatesBegin(); sit != rgProduct.StatesEnd(); ++sit) {
505  if (!I.Exists(*sit)) {
506  statesToMute.Insert(*sit);
507  }
508  }
509 
510  FD_DF("RabinLanguageInclusion(): Muting " << statesToMute.Size() << " states (L-marked + complement of I)");
511 
512  // Create muted automaton
513  Generator mutedProduct = CreateMutedAutomaton(rgProduct, statesToMute);
514 
515  if (mutedProduct.Size() == 0) {
516  FD_DF("RabinLanguageInclusion(): Muted product is empty - continuing to next Rabin pair");
517  continue;
518  }
519 
520  // Compute SCCs in muted product using libFAUDES function
521  std::list<StateSet> sccList;
522  StateSet sccRoots;
523  ComputeScc(mutedProduct, sccList, sccRoots);
524 
525  FD_DF("RabinLanguageInclusion(): Found " << sccList.size() << " SCCs in muted system");
526 
527  // Check if any SCC contains R-marked states
528  bool foundProblematicSCC = false;
529  std::list<StateSet>::iterator sccIt;
530  int sccIndex = 0;
531  for (sccIt = sccList.begin(); sccIt != sccList.end(); ++sccIt, ++sccIndex) {
532  bool hasRMarked = false;
533  StateSet::Iterator sccit;
534  for (sccit = sccIt->Begin(); sccit != sccIt->End(); ++sccit) {
535  if (R.Exists(*sccit)) {
536  hasRMarked = true;
537  break;
538  }
539  }
540 
541  if (hasRMarked && sccIt->Size() > 1) { // Non-trivial SCC with R-marked state
542  FD_DF("RabinLanguageInclusion(): Found problematic SCC " << sccIndex << " with R-marked states");
543  foundProblematicSCC = true;
544  break;
545  }
546  }
547 
548  if (foundProblematicSCC) {
549  FD_DF("RabinLanguageInclusion(): Language inclusion violated for Rabin pair");
550  return false;
551  }
552  }
553 
554  FD_DF("RabinLanguageInclusion(): All tests passed - language inclusion L ⊆ K holds");
555  return true;
556 }
557 
558 } // namespace faudes
#define FD_DF(message)
virtual const char * What() const
const std::string & Name(void) const
Definition: cfl_types.cpp:422
bool Exists(const Idx &rIndex) const
Iterator End(void)
Iterator Begin(void)
Iterator Begin(void) const
Iterator End(void) const
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)
const ATransSet & TransRel(void) const
const Attr & Attribute(const Idx &rElem) const
Definition: cfl_indexset.h:559
void ClrControllable(Idx index)
void ClrObservable(Idx index)
EventSet ControllableEvents(void) const
void ClrForcible(Idx index)
EventSet UnobservableEvents(void) const
EventSet ObservableEvents(void) const
void RabinAcceptance(const faudes::RabinAcceptance &rRabAcc)
Definition: omg_rabinaut.h:326
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Definition: cfl_types.cpp:175
StateSet::Iterator StatesBegin(void) const
StateSet::Iterator InitStatesBegin(void) const
bool SetTransition(Idx x1, Idx ev, Idx x2)
TransSet::Iterator TransRelBegin(void) const
void ClrTransition(Idx x1, Idx ev, Idx x2)
bool DelEvent(Idx index)
void InjectMarkedStates(const StateSet &rNewMarkedStates)
Idx MarkedStatesSize(void) const
void SetInitState(Idx index)
bool ExistsState(Idx index) const
bool DelState(Idx index)
StateSet::Iterator StatesEnd(void) const
TransSet::Iterator TransRelEnd(void) const
bool IsDeterministic(void) const
void SetMarkedState(Idx index)
bool Empty(void) const
StateSet::Iterator InitStatesEnd(void) const
Idx TransRelSize(void) const
std::string EventName(Idx index) const
Idx Size(void) const
virtual void Clear(void)
bool ExistsMarkedState(Idx index) const
const StateSet & States(void) const
void InjectAlphabet(const EventSet &rNewalphabet)
bool Empty(void) const
Definition: cfl_baseset.h:1904
bool Exists(const T &rElem) const
Definition: cfl_baseset.h:2322
virtual void Clear(void)
Definition: cfl_baseset.h:2104
Iterator End(void) const
Definition: cfl_baseset.h:2098
Iterator Begin(void) const
Definition: cfl_baseset.h:2093
Idx Size(void) const
Definition: cfl_baseset.h:1899
vGenerator Generator
bool LanguageInclusion(const Generator &rGen1, const Generator &rGen2)
bool ComputeScc(const Generator &rGen, const SccFilter &rFilter, std::list< StateSet > &rSccList, StateSet &rRoots)
void Product(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
void RabinBuechiAutomaton(const RabinAutomaton &rRAut, const Generator &rBAut, RabinAutomaton &rRes)
void RabinBuechiProduct(const RabinAutomaton &rRAut, const Generator &rBAut, RabinAutomaton &rRes)
bool IsRabinTrim(const RabinAutomaton &rRAut)
void PseudoDet(const RabinAutomaton &rGen, RabinAutomaton &rRes)
uint32_t Idx
void RabinCtrlPartialObs(const System &rPlant, const RabinAutomaton &rSpec, RabinAutomaton &rSupervisor)
Rabin control synthesis under partial observation (System interface)
void ExtractEventAttributes(const System &rSys, EventSet &rControllableEvents, EventSet &rObservableEvents)
Extract controllable and observable events from System attributes.
bool RabinLanguageInclusion(const System &rGenL, const RabinAutomaton &rRabK)
Verify language inclusion for Rabin automata.
void ControlAut(const RabinAutomaton &rsDRA, const TaIndexSet< EventSet > &rController, Generator &rRes)
Apply controller to filter transitions and create Buchi automaton.
TrGenerator< RabinAcceptance, AttributeVoid, AttributeCFlags, AttributeVoid > RabinAutomaton
Definition: omg_rabinaut.h:226
Generator CreateMutedAutomaton(const Generator &rOriginal, const StateSet &rStatesToMute)
Create muted automaton by removing specified states and their transitions.
bool IsBuechiTrim(const vGenerator &rGen)
void RabinCtrlPartialObsConsistencyCheck(const RabinAutomaton &rPlant, const RabinAutomaton &rSpec, const EventSet &rControllableEvents, const EventSet &rObservableEvents)
Check consistency of control problem setup.
void EpsObservation(const RabinAutomaton &rGen, RabinAutomaton &rRes)
Epsilon observation for Rabin automata.

libFAUDES 2.33l --- 2025.09.16 --- c++ api documentaion by doxygen