omg_rabinctrlrk.cpp
Go to the documentation of this file.
1/** @file omg_rabinctrlrk.cpp Synthesis omega languages accepted by Rabin automata */
2
3/* FAU Discrete Event Systems Library (libFAUDES)
4
5Copyright (C) 2025 Changming Yang, Thomas Moor
6
7This library is free software; you can redistribute it and/or
8modify it under the terms of the GNU Lesser General Public
9License as published by the Free Software Foundation; either
10version 2.1 of the License, or (at your option) any later version.
11
12This library is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public
18License along with this library; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
20
21
22
23/*
24This is an alternative implementation to compute the controllable set
25aka the controllability prefix. Doublets w.r.t. the the base implementation
26have been suffixed "_RK". From my petrspective, they can be safely removed
27(for classs definitions they dont generate symbols in the bbject file and
28the only doublet function RabinCtrlPfx is not invoked anywhere).
29
30See also the heeder omg_rabinctrlrk.h.
31
32CY/TM, 2025/07.
33*/
34
35
36#include "omg_rabinctrlrk.h"
37#include "syn_include.h"
38
39// local degug
40//#undef FD_DF
41//#define FD_DF(m) FD_WARN(m)
42
43namespace faudes {
44
45/*
46Base class for my operators to hold context
47*/
49protected:
50 /** record context references */
57public:
58 /** construct to record context */
60 const vGenerator& gen, const TransSetX2EvX1& revtrans, const EventSet& sigctrl)
61 :
63 rGen(gen),
64 rDomain(gen.States()),
65 rMarkedStates(gen.MarkedStates()),
66 rTransRel(gen.TransRel()),
67 rRevTransRel(revtrans),
68 mSigmaCtrl(sigctrl)
69 {
70 Name("void base class operator");
71 mArgCount=0;
72 };
73 /** overaall stateset */
74 virtual const StateSet& Domain(void) const {
75 return rDomain;
76 }
77};
78
79/*
80Extended base class for operators that track state rankings for feedback construction
81*/
83protected:
84 /** state ranking map for feedback construction */
86 /** current iteration levels */
87 mutable int mCurrentMuLevel;
88 mutable int mCurrentNuLevel;
89 mutable int mCurrentBranchType;
90
91public:
92 /** construct to record context */
94 const vGenerator& gen, const TransSetX2EvX1& revtrans, const EventSet& sigctrl)
95 :
96 RabinInvDynOperator_RK(gen, revtrans, sigctrl),
97 mpStateRanking(nullptr),
101 {
102 Name("base class operator with ranking");
103 };
104
105 /** set state ranking map pointer */
107 mpStateRanking = pRanking;
108 }
109
110 /** set current iteration levels */
111 void SetCurrentLevels(int muLevel, int nuLevel, int branchType) const {
112 mCurrentMuLevel = muLevel;
113 mCurrentNuLevel = nuLevel;
114 mCurrentBranchType = branchType;
115 }
116
117protected:
118 /** record state ranking when adding states to result */
119 void RecordStateRanking(const StateSet& rNewStates) const {
120 if (mpStateRanking == nullptr) return;
121
123 for (StateSet::Iterator it = rNewStates.Begin(); it != rNewStates.End(); ++it) {
124 // Only record if this state hasn't been ranked yet (first time added)
125 if (!mpStateRanking->Exists(*it)) {
126 mpStateRanking->Insert(*it, ranking);
127 }
128 }
129 }
130};
131
132
133/*
134Inverse dynamics operator theta
135
136Cite Thistle/Wonham "Control of w-Automata, Church's Problem, and the Emptiness
137Problem for Tree w-Automata", 1992, Def 8.2:
138
139theta(X1,X2) = "the set of states, from which the automaton can be controlled to
140enter X1 union X2 in a single transition without being prevented from entering X1."
141
142Rephrase: X1 is the target T, X1 union X2 is the domain D; control such that immediate
143successors stay within within D and there is the chance to enter the T.
144
145We use "Z1/Z2" argument names to avoid confusion with libFAUDES naming conventions.
146*/
148public:
149 /** construct to record context */
151 const vGenerator& gen, const TransSetX2EvX1& revtrans, const EventSet& sigctrl)
152 :
153 RabinInvDynOperator_RK(gen,revtrans,sigctrl)
154 {
155 FD_DF("RabinInvDynTheta(): instantiated for " << rGen.Name());
156 Name("theta([Z1,Z2])");
157 mArgNames= std::vector<std::string>{"Z1","Z2"};
158 mArgCount=2;
159 };
160protected:
161 /** actual operator implementation */
162 virtual void DoEvaluate(StateSetVector& rArgs, StateSet& rRes) {
163 // convenience acsesors
164 const StateSet& Z1=rArgs.At(0);
165 const StateSet& Z2=rArgs.At(1);
166 // do operate
168 StateSet::Iterator sit=rRes.Begin();
169 StateSet::Iterator sit_end=rRes.End();
170 while(sit!=sit_end){
172 TransSet::Iterator tit_end=rTransRel.End(*sit);
173 bool enterZ1 = false;
174 bool exitZ12 = false;
175 for(;tit!=tit_end;++tit){
176 // successor is in Z1: will not disable, found evidence to enter Z1
177 if(Z1.Exists(tit->X2)) {enterZ1=true; continue;}
178 // successor is in Z2: will not disable
179 if(Z2.Exists(tit->X2)) {continue;}
180 // sucessor is neither in Z1 nor Z2: need to disable
181 if(!mSigmaCtrl.Exists(tit->Ev)){ exitZ12 = true; break;}
182 }
183 if(!enterZ1 || exitZ12) rRes.Erase(sit++);
184 else ++sit;
185 }
186 };
187};
188
189
190/*
191Inverse dynamics operator theta-tilde
192
193Cite Thistle/Wonham "Control of w-Automata, Church's Problem, and the Emptiness
194Problem for Tree w-Automata", 1992, Def 8.3:
195
196"theta_tilde(X1,X2)=nu X3 mu X4 theta( X1 + (X4 - R), (X3 - R) * X2 ) ")
197
198We first implement the core formula without the nu/mu iteration and then apply nu/mu.
199We use "Y1/Y2/Y3/Y4" and "Z1/Z2" argument names to
200*/
202public:
203 /** construct to record context */
205 const vGenerator& gen, const TransSetX2EvX1& revtrans, const EventSet& sigctrl)
206 :
207 RabinInvDynTheta_RK(gen,revtrans,sigctrl)
208 {
209 FD_DF("RabinInvDynThetaTildeCore(): instantiated for " << rGen.Name());
210 Name("theta_tilde_core([Y1,Y2,Y3,Y4])");
211 mArgNames= std::vector<std::string>{"Y1","Y2","Y3","Y4"};
212 mArgCount=4;
213 };
214protected:
215 /** actual operator implementation */
216 virtual void DoEvaluate(StateSetVector& rArgs, StateSet& rRes) {
217 // convenience acsesors
218 const StateSet& Y1=rArgs.At(0);
219 const StateSet& Y2=rArgs.At(1);
220 const StateSet& Y3=rArgs.At(2);
221 const StateSet& Y4=rArgs.At(3);
222 StateSetVector args;
223 args.Size(2);
224 StateSet& Z1=args.At(0);
225 StateSet& Z2=args.At(1);
226 // do operate
227 Z1= Y1 + (Y4 - rMarkedStates);
228 Z2= Y2 * (Y3 - rMarkedStates);
230 };
231};
232
233
234/*
235Inverse dynamics operator theta tilde, outer nu/mu iteration
236*/
238protected:
239 /** additional context */
243public:
244 /** construct to record context */
246 const vGenerator& gen, const TransSetX2EvX1& revtrans, const EventSet& sigctrl)
247 :
248 RabinInvDynOperator_RK(gen,revtrans,sigctrl),
249 mThetaCore(gen,revtrans,sigctrl),
252 {
253 FD_DF("RabinInvDynThetaTilde(): instantiated for " << rGen.Name());
254 Name("theta_tilde([W1,W2])");
255 mArgNames= std::vector<std::string>{"W1","W2"};
256 mArgCount=2;
257 };
258protected:
259 /** actual operator implementation */
260 virtual void DoEvaluate(StateSetVector& rArgs, StateSet& rRes) {
261 mNuMuThetaCore.Evaluate(rArgs, rRes);
262 };
263};
264
265
266/*
267P-reach operator
268
269Cite Thistle/Wonham "Control of w-Automata, Church's Problem, and the Emptiness
270Problem for Tree w-Automata", 1992, Def 8.4
271
272p-reach(X1,X2)= mu X3 . theta-tilde(X1,X) union theta-tilde((X1 u X2 u X3, I_p))
273
274We first implement the core formular without the nu/mu iteration, and then do the
275mu iteration
276
277We use "U1/U2/U3" and "W1/W2" argument names
278*/
280 /** additional context */
281 RabinAcceptance::CIterator mRPit;
282public:
283 /** construct to record context */
285 const RabinAutomaton& raut, const TransSetX2EvX1& revtrans, const EventSet& sigctrl)
286 :
287 RabinInvDynThetaTilde_RK(raut,revtrans,sigctrl),
288 mRPit(raut.RabinAcceptance().Begin())
289 {
290 FD_DF("RabinInvDynPReachCore(): instantiated for " << rGen.Name());
291 Name("invdyn_op([U1,U2,U3)");
292 mArgNames= std::vector<std::string>{"U1","U2","U3"};
293 mArgCount=3;
294 };
295protected:
296 /** actual operator implementation */
297 virtual void DoEvaluate(StateSetVector& rArgs, StateSet& rRes) {
298 // convenience accessors
299 const StateSet& U1=rArgs.At(0);
300 const StateSet& U2=rArgs.At(1);
301 const StateSet& U3=rArgs.At(2);
302 StateSetVector args;
303 args.Size(2);
304 StateSet& W1=args.At(0);
305 StateSet& W2=args.At(1);
306 // do operate
307 W1=U1;
308 W2=Domain();
310 W1=U1+U2+U3;
311 W2=mRPit->ISet();
312 StateSet rhs;
314 rRes.InsertSet(rhs);
315 };
316};
317
318/** p-reach operator, mu iteration */
320protected:
321 /** have additional context */
324public:
325 /** construct to record context */
327 const RabinAutomaton& raut, const TransSetX2EvX1& revtrans, const EventSet& sigctrl)
328 :
329 RabinInvDynOperator_RK(raut,revtrans,sigctrl),
330 mPReachCore(raut,revtrans,sigctrl),
332 {
333 FD_DF("RabinInvDynPReach(): instantiated for " << rGen.Name());
334 Name("p_reach_op([O1,O2])");
335 mArgNames= std::vector<std::string>{"O1","O2"};
336 mArgCount=2;
337 };
338protected:
339 /** actual operator implementation */
340 virtual void DoEvaluate(StateSetVector& rArgs, StateSet& rRes) {
341 mMuPReachCore.Evaluate(rArgs, rRes);
342 };
343};
344
345/*
346Controllable subset
347
348Cite Thistle/Wonham "Control of w-Automata, Church's Problem, and the Emptiness
349Problem for Tree w-Automata", 1992, Def 8.5
350
351CA = mu X1 nu X2 . p-reach(X1, X2 * R)
352
353We first implement the core formular without the mu/nu iteration, and then do the mu/nu.
354
355*/
357 /** additional context */
358 RabinAcceptance::CIterator mRPit;
359public:
360 /** construct to record context */
362 const RabinAutomaton& raut, const TransSetX2EvX1& revtrans, const EventSet& sigctrl)
363 :
364 RabinInvDynPReach_RK(raut,revtrans,sigctrl),
365 mRPit(raut.RabinAcceptance().Begin())
366 {
367 FD_DF("RabinInvDynCtrlCore(): instantiated for " << rGen.Name());
368 Name("ctrl([X1,X2])");
369 mArgNames= std::vector<std::string>{"X1","X2"};
370 mArgCount=2;
371 };
372protected:
373 /** actual operator implementation */
374 virtual void DoEvaluate(StateSetVector& rArgs, StateSet& rRes) {
375 // convenience accessors
376 const StateSet& X1=rArgs.At(0);
377 const StateSet& X2=rArgs.At(1);
378 StateSetVector args;
379 args.Size(2);
380 StateSet& O1=args.At(0);
381 StateSet& O2=args.At(1);
382 // do operate
383 O1=X1;
384 O2=X2 * mRPit->RSet();
386 };
387};
388
389/** ctrollable set, mu-nu iteration */
391protected:
392 /** have additional context */
396public:
397 /** construct to record context */
399 const RabinAutomaton& raut, const TransSetX2EvX1& revtrans, const EventSet& sigctrl)
400 :
401 RabinInvDynOperator_RK(raut,revtrans,sigctrl),
402 mCtrlCore(raut,revtrans,sigctrl),
405 {
406 FD_DF("RabinInvDynCtrl(): instantiated for " << rGen.Name());
407 Name("ctrl()");
408 mArgCount=0;
409 };
410protected:
411 /** actual operator implementation */
412 virtual void DoEvaluate(StateSetVector& rArgs, StateSet& rRes) {
413 mMuNuCtrlCore.Evaluate(rArgs, rRes);
414 };
415};
416
417
418
419// doublet: see ong_rabinctrl.cpp --- can be safely removed
421 const RabinAutomaton& rRAut, const EventSet& rSigmaCtrl,
422 StateSet& rCtrlPfx){
423 // we can only handle one Rabin pair
424 if(rRAut.RabinAcceptance().Size()!=1){
425 std::stringstream errstr;
426 errstr << "the current implementation requires exactly one Rabin pair";
427 throw Exception("RabinCtrlPfx", errstr.str(), 80);
428 }
429 // set up various helper
430 TransSetX2EvX1 revtrans(rRAut.TransRel());
431 EventSet sigctrl(rSigmaCtrl);
432 // have operator
433 RabinInvDynCtrl_RK ctrl(rRAut,revtrans,sigctrl);
434 // run
435 ctrl.Evaluate(rCtrlPfx);
436};
437
438
439
440/*
441Extended controllable subset operator with state ranking tracking
442*/
444protected:
445 /** additional context */
447 RabinAcceptance::CIterator mRPit;
448
449public:
450 /** construct to record context */
452 const RabinAutomaton& raut, const TransSetX2EvX1& revtrans, const EventSet& sigctrl)
453 :
454 RabinInvDynOperatorWithRanking(raut, revtrans, sigctrl),
455 mRAut(raut),
456 mRPit(raut.RabinAcceptance().Begin())
457 {
458 FD_DF("RabinInvDynCtrlWithRanking(): instantiated for " << rGen.Name());
459 Name("ctrl_with_ranking()");
460 mArgCount=0;
461 };
462
463protected:
464 /** actual operator implementation */
465 virtual void DoEvaluate(StateSetVector& rArgs, StateSet& rRes) {
466 // Implementation of the nested mu-nu fixpoint with ranking tracking
467 rRes.Clear();
468
469 // Outer mu-iteration: C^A = μX1. νX2. ρ^A_p(X1, X2∩R_p)
470 StateSet X1_current; // Start with empty set for mu-iteration
471 StateSet X1_prev;
472 int muLevel = 0;
473
474 do {
475 X1_prev = X1_current;
476 ++muLevel;
477
478 // Inner nu-iteration: νX2. ρ^A_p(X1_current, X2∩R_p)
479 StateSet X2_current = Domain(); // Start with full domain for nu-iteration
480 StateSet X2_prev;
481 int nuLevel = 0;
482
483 do {
484 X2_prev = X2_current;
485 ++nuLevel;
486
487 // Compute ρ^A_p(X1_current, X2_current ∩ R_p)
488 StateSet pReachResult;
489 ComputePReachWithRanking(X1_current, X2_current * mRPit->RSet(), pReachResult, muLevel, nuLevel);
490
491 X2_current = X2_current * pReachResult; // Intersection for nu-iteration
492
493 } while (X2_current != X2_prev);
494
495 X1_current = X1_current + X2_current; // Union for mu-iteration
496
497 } while (X1_current != X1_prev);
498
499 rRes = X1_current;
500 };
501
502private:
503 /** compute p-reach operator with ranking tracking */
504 void ComputePReachWithRanking(const StateSet& X1, const StateSet& X2, StateSet& rRes,
505 int muLevel, int nuLevel) const {
506 // This implements: μX3. θ̃(X1, Domain) ∪ θ̃(X1∪X2∪X3, I_p)
507 rRes.Clear();
508 StateSet X3_current; // Start with empty set for mu-iteration
509 StateSet X3_prev;
510 int pReachLevel = 0;
511
512 do {
513 X3_prev = X3_current;
514 ++pReachLevel;
515
516 // First branch: θ̃(X1, Domain)
517 StateSet branch1;
518 ComputeThetaTildeWithRanking(X1, Domain(), branch1, muLevel, nuLevel, 0);
519
520 // Second branch: θ̃(X1∪X2∪X3_current, I_p)
521 StateSet branch2;
522 ComputeThetaTildeWithRanking(X1 + X2 + X3_current, mRPit->ISet(), branch2, muLevel, nuLevel, 1);
523
524 StateSet newStates = (branch1 + branch2) - X3_current;
525 if (!newStates.Empty()) {
526 SetCurrentLevels(muLevel, nuLevel, 0); // Branch type will be set in theta-tilde
527 RecordStateRanking(newStates);
528 }
529
530 X3_current = X3_current + branch1 + branch2; // Union for mu-iteration
531
532 } while (X3_current != X3_prev);
533
534 rRes = X3_current;
535 }
536
537 /** compute theta-tilde operator with ranking tracking */
538 void ComputeThetaTildeWithRanking(const StateSet& W1, const StateSet& W2, StateSet& rRes,
539 int muLevel, int nuLevel, int branchType) const {
540 // This implements: νX3. μX4. θ(W1 ∪ (X4 - R), (X3 - R) ∩ W2)
541 rRes.Clear();
542 StateSet X3_current = Domain(); // Start with full domain for nu-iteration
543 StateSet X3_prev;
544
545 do {
546 X3_prev = X3_current;
547
548 // Inner mu-iteration: μX4. θ(W1 ∪ (X4 - R), (X3_current - R) ∩ W2)
549 StateSet X4_current; // Start with empty set for mu-iteration
550 StateSet X4_prev;
551
552 do {
553 X4_prev = X4_current;
554
555 // Compute θ(W1 ∪ (X4_current - R), (X3_current - R) ∩ W2)
556 StateSet thetaResult;
557 ComputeThetaWithRanking(W1 + (X4_current - mRPit->RSet()),
558 (X3_current - mRPit->RSet()) * W2,
559 thetaResult, muLevel, nuLevel, branchType);
560
561 X4_current = X4_current + thetaResult; // Union for mu-iteration
562
563 } while (X4_current != X4_prev);
564
565 X3_current = X3_current * X4_current; // Intersection for nu-iteration
566
567 } while (X3_current != X3_prev);
568
569 rRes = X3_current;
570 }
571
572 /** compute basic theta operator with ranking tracking */
573 void ComputeThetaWithRanking(const StateSet& Z1, const StateSet& Z2, StateSet& rRes,
574 int muLevel, int nuLevel, int branchType) const {
575 // This implements the basic inverse dynamics operator θ(Z1, Z2)
577 StateSet::Iterator sit = rRes.Begin();
578 StateSet::Iterator sit_end = rRes.End();
579
580 while (sit != sit_end) {
582 TransSet::Iterator tit_end = rTransRel.End(*sit);
583 bool enterZ1 = false;
584 bool exitZ12 = false;
585
586 for (; tit != tit_end; ++tit) {
587 // successor is in Z1: will not disable, found evidence to enter Z1
588 if (Z1.Exists(tit->X2)) {
589 enterZ1 = true;
590 continue;
591 }
592 // successor is in Z2: will not disable
593 if (Z2.Exists(tit->X2)) {
594 continue;
595 }
596 // successor is neither in Z1 nor Z2: need to disable
597 if (!mSigmaCtrl.Exists(tit->Ev)) {
598 exitZ12 = true;
599 break;
600 }
601 }
602
603 if (!enterZ1 || exitZ12) {
604 rRes.Erase(sit++);
605 } else {
606 ++sit;
607 }
608 }
609
610 // Record ranking for newly computed states
611 SetCurrentLevels(muLevel, nuLevel, branchType);
612 }
613};
614
615
616/*
617State feedback constructor based on state rankings
618*/
620private:
624
625public:
627 const StateRankingMap& ranking)
628 : mRAut(raut), mSigmaCtrl(sigctrl), mStateRanking(ranking) {}
629
630 /** construct state feedback mapping based on Theorem 6.4 */
631 void ConstructStateFeedback(const StateSet& rCtrlPfx, StateFeedbackMap& rFeedback) const {
632 rFeedback.Clear();
633
634 // Get Rabin pair (we assume exactly one pair)
635 RabinAcceptance::CIterator rpIt = mRAut.RabinAcceptance().Begin();
636 const StateSet& RSet = rpIt->RSet();
637 const StateSet& ISet = rpIt->ISet();
638
639 // For each controllable state, construct its control pattern
640 for (StateSet::Iterator sit = rCtrlPfx.Begin(); sit != rCtrlPfx.End(); ++sit) {
641 Idx state = *sit;
642 EventSet controlPattern;
643
644 // Get state ranking
645 if (!mStateRanking.Exists(state)) {
646 // If no ranking found, use default safe control (allow all controllable events)
647 controlPattern = mSigmaCtrl;
648 } else {
649 const StateRanking& ranking = mStateRanking.Attribute(state);
650
651 // Construct control pattern based on ranking and Theorem 6.4
652 constructControlPatternForState(state, ranking, RSet, ISet, controlPattern);
653 }
654
655 // Always include uncontrollable events
656 EventSet uncontrollableEvents = mRAut.Alphabet() - mSigmaCtrl;
657 controlPattern.InsertSet(uncontrollableEvents);
658
659 rFeedback.Insert(state, controlPattern);
660 }
661 }
662
663private:
664 /** construct control pattern for a specific state based on its ranking */
666 const StateSet& RSet, const StateSet& ISet,
667 EventSet& rPattern) const {
668 rPattern.Clear();
669
670 // Get all outgoing transitions from this state
672 TransSet::Iterator tit_end = mRAut.TransRelEnd(state);
673
674 for (; tit != tit_end; ++tit) {
675 Idx event = tit->Ev;
676 Idx successor = tit->X2;
677
678 // Check if this event should be enabled based on control strategy
679 bool enableEvent = false;
680
681 // Get successor's ranking if it exists
682 if (mStateRanking.Exists(successor)) {
683 const StateRanking& succRanking = mStateRanking.Attribute(successor);
684
685 // Apply control rules based on Theorem 6.4:
686 // 1. If successor has lower or equal ranking, enable the event
687 // 2. If we're in I_p and successor is in I_p, enable to maintain invariance
688 // 3. If successor is in R_p and we need to visit R_p, enable the event
689
690 if (succRanking < ranking || succRanking.muLevel == ranking.muLevel) {
691 enableEvent = true;
692 } else if (ISet.Exists(state) && ISet.Exists(successor)) {
693 enableEvent = true; // Stay within invariant set
694 } else if (RSet.Exists(successor) && ranking.branchType == 0) {
695 enableEvent = true; // Allow reaching recurrent set when needed
696 }
697 } else {
698 // If successor is not controllable, be conservative
699 if (ISet.Exists(successor)) {
700 enableEvent = true; // Safe to go to invariant states
701 }
702 }
703
704 // Always enable uncontrollable events
705 if (!mSigmaCtrl.Exists(event)) {
706 enableEvent = true;
707 }
708
709 if (enableEvent) {
710 rPattern.Insert(event);
711 }
712 }
713
714 // Ensure we have at least one enabled controllable event to avoid deadlock
715 bool hasControllableEvent = false;
716 for (EventSet::Iterator eit = rPattern.Begin(); eit != rPattern.End(); ++eit) {
717 if (mSigmaCtrl.Exists(*eit)) {
718 hasControllableEvent = true;
719 break;
720 }
721 }
722
723 // If no controllable events are enabled, enable all to avoid deadlock
724 if (!hasControllableEvent) {
725 rPattern.InsertSet(mSigmaCtrl);
726 }
727 }
728};
729
730
731
733 const RabinAutomaton& rRAut, const EventSet& rSigmaCtrl, TaIndexSet<EventSet>& rController) {
734
735 // we can only handle one Rabin pair
736 if(rRAut.RabinAcceptance().Size()!=1){
737 std::stringstream errstr;
738 errstr << "the current implementation requires exactly one Rabin pair";
739 throw Exception("RabinCtrlPfxWithFeedback", errstr.str(), 80);
740 }
741
742 // set up various helper
743 TransSetX2EvX1 revtrans(rRAut.TransRel());
744 EventSet sigctrl(rSigmaCtrl);
745
746 // State ranking map to track fixpoint computation
747 StateRankingMap stateRanking;
748
749 // have operator with ranking capability
750 RabinInvDynCtrlWithRanking ctrl(rRAut, revtrans, sigctrl);
751 ctrl.SetStateRankingMap(&stateRanking);
752
753 StateSet rCtrlPfx;
754 // run computation
755 ctrl.Evaluate(rCtrlPfx);
756
757 // construct state feedback mapping
758 StateFeedbackMap rStateFeedback;
759 StateFeedbackConstructor feedbackConstructor(rRAut, sigctrl, stateRanking);
760 feedbackConstructor.ConstructStateFeedback(rCtrlPfx, rStateFeedback);
761
762 // clear and populate controller with state -> EventSet mapping
763 rController.Clear();
764 for (StateFeedbackMap::Iterator it = rStateFeedback.Begin(); it != rStateFeedback.End(); ++it) {
765 rController.Insert(*it, rStateFeedback.Attribute(*it));
766 }
767};
768
769
770
771} // namespace faudes
772
#define FD_DF(message)
const std::string & Name(void) const
bool Exists(const Idx &rIndex) const
virtual void InsertSet(const NameSet &rOtherSet)
bool Insert(const Idx &rIndex)
virtual void DoEvaluate(StateSetVector &rArgs, StateSet &rRes)
RabinAcceptance::CIterator mRPit
RabinInvDynCtrlCore_RK(const RabinAutomaton &raut, const TransSetX2EvX1 &revtrans, const EventSet &sigctrl)
virtual void DoEvaluate(StateSetVector &rArgs, StateSet &rRes)
void ComputeThetaWithRanking(const StateSet &Z1, const StateSet &Z2, StateSet &rRes, int muLevel, int nuLevel, int branchType) const
RabinAcceptance::CIterator mRPit
void ComputeThetaTildeWithRanking(const StateSet &W1, const StateSet &W2, StateSet &rRes, int muLevel, int nuLevel, int branchType) const
RabinInvDynCtrlWithRanking(const RabinAutomaton &raut, const TransSetX2EvX1 &revtrans, const EventSet &sigctrl)
void ComputePReachWithRanking(const StateSet &X1, const StateSet &X2, StateSet &rRes, int muLevel, int nuLevel) const
RabinInvDynCtrl_RK(const RabinAutomaton &raut, const TransSetX2EvX1 &revtrans, const EventSet &sigctrl)
virtual void DoEvaluate(StateSetVector &rArgs, StateSet &rRes)
RabinInvDynCtrlCore_RK mCtrlCore
void SetStateRankingMap(StateRankingMap *pRanking)
RabinInvDynOperatorWithRanking(const vGenerator &gen, const TransSetX2EvX1 &revtrans, const EventSet &sigctrl)
void RecordStateRanking(const StateSet &rNewStates) const
void SetCurrentLevels(int muLevel, int nuLevel, int branchType) const
virtual const StateSet & Domain(void) const
const TransSetX2EvX1 & rRevTransRel
RabinInvDynOperator_RK(const vGenerator &gen, const TransSetX2EvX1 &revtrans, const EventSet &sigctrl)
RabinAcceptance::CIterator mRPit
virtual void DoEvaluate(StateSetVector &rArgs, StateSet &rRes)
RabinInvDynPReachCore_RK(const RabinAutomaton &raut, const TransSetX2EvX1 &revtrans, const EventSet &sigctrl)
virtual void DoEvaluate(StateSetVector &rArgs, StateSet &rRes)
RabinInvDynPReach_RK(const RabinAutomaton &raut, const TransSetX2EvX1 &revtrans, const EventSet &sigctrl)
RabinInvDynPReachCore_RK mPReachCore
virtual void DoEvaluate(StateSetVector &rArgs, StateSet &rRes)
RabinInvDynThetaTildeCore_RK(const vGenerator &gen, const TransSetX2EvX1 &revtrans, const EventSet &sigctrl)
RabinInvDynThetaTilde_RK(const vGenerator &gen, const TransSetX2EvX1 &revtrans, const EventSet &sigctrl)
RabinInvDynThetaTildeCore_RK mThetaCore
virtual void DoEvaluate(StateSetVector &rArgs, StateSet &rRes)
virtual void DoEvaluate(StateSetVector &rArgs, StateSet &rRes)
RabinInvDynTheta_RK(const vGenerator &gen, const TransSetX2EvX1 &revtrans, const EventSet &sigctrl)
StateSet & RSet(void)
StateSet & ISet(void)
const StateRankingMap & mStateRanking
StateFeedbackConstructor(const RabinAutomaton &raut, const EventSet &sigctrl, const StateRankingMap &ranking)
void ConstructStateFeedback(const StateSet &rCtrlPfx, StateFeedbackMap &rFeedback) const
void constructControlPatternForState(Idx state, const StateRanking &ranking, const StateSet &RSet, const StateSet &ISet, EventSet &rPattern) const
std::vector< std::string > mArgNames
StateSetVector::Position mArgCount
void Evaluate(StateSetVector &rArgs, StateSet &rRes) const
virtual const T & At(const Position &pos) const
StateSet PredecessorStates(Idx x2) const
Iterator Begin(void) const
Iterator End(void) const
const TaEventSet< EventAttr > & Alphabet(void) const
const ATransSet & TransRel(void) const
const Attr & Attribute(const Idx &rElem) const
void RabinAcceptance(const faudes::RabinAcceptance &rRabAcc)
TransSet::Iterator TransRelBegin(void) const
TransSet::Iterator TransRelEnd(void) 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
virtual bool Erase(const T &rElem)
void RabinCtrlPfxWithFeedback(const RabinAutomaton &rRAut, const EventSet &rSigmaCtrl, TaIndexSet< EventSet > &rController)
uint32_t Idx
void RabinCtrlPfx_RK(const RabinAutomaton &rRAut, const EventSet &rSigmaCtrl, StateSet &rCtrlPfx)

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