omg_6_pobsctrl.cpp
Go to the documentation of this file.
1 #include "libfaudes.h"
2 #undef FD_DF
3 
4 // we make the faudes namespace available to our program
5 using namespace faudes;
6 
7 
8 
9 int main() {
10 
11  // Test case selection
12  std::cout << "====== Partial Observable Rabin Control ======" << std::endl;
13 
14  // Compose belt1 dynamics from two very simple machines
15  Generator belt1;
16  belt1.Read("data/omg_6_belt1.gen");
17  belt1.Write("tmp_omg_6_belt1.gen");
18  Generator belt2;
19  belt2.Read("data/omg_6_belt2.gen");
20  belt2.Write("tmp_omg_6_belt2.gen");
21  System plant;
22  Parallel(belt1,belt2,plant);
23  plant.DWrite();
24  plant.Write("tmp_omg_6_plant.gen");
25 
26  // Declare controllable and observable events
27  EventSet allEvents = plant.Alphabet();
28  plant.ClrObservable(allEvents);
29 
30  // Read spec
31  RabinAutomaton spec;
32  spec.Read("data/omg_6_cbspec12.gen");
33  InvProject(spec,plant.Alphabet());
34  spec.Write("tmp_omg_6_spec.gen");
35 
36 
37  // Synthesis complete - ready to call RabinCtrlPartialObs
38 
39  EventSet contevents;
40  contevents.Insert("a");
41  //contevents.Insert("d");
42  contevents.Insert("h");
43 
44  EventSet obsevents;
45  obsevents.Insert("a");
46  //obsevents.Insert("d");
47  obsevents.Insert("h");
48 
49  plant.SetControllable(contevents);
50  EventSet plantEvents = plant.Alphabet();
51  plant.ClrObservable(plantEvents);
52  plant.SetObservable(obsevents);
53 
54 
55  RabinAutomaton ProductPS;
56  RabinBuechiProduct(spec,plant,ProductPS);
57  ProductPS.SetControllable(contevents);
58  EventSet ProductEvents = ProductPS.Alphabet();
59  ProductPS.ClrObservable(ProductEvents);
60  ProductPS.SetObservable(obsevents);
61 
62  ProductPS.Name("Product of plant and Spec");
63  ProductPS.Write("tmp_omg_6_Product.gen");
64  ProductPS.DWrite();
65 
66  // record test case
67  FAUDES_TEST_DUMP("plant", plant);
68  FAUDES_TEST_DUMP("spec", spec);
69  FAUDES_TEST_DUMP("cand", ProductPS);
70 
71 
72  RabinAutomaton NRA;
73  EpsObservation(ProductPS, NRA);
74  NRA.Name("Epsilon Observed Product");
75  NRA.Write("tmp_omg_6_EpsObservedProduct.gen");
76  NRA.DWrite();
77  RabinAutomaton DRA;
78  PseudoDet(NRA, DRA);
79  DRA.Name("Determinized Epsilon Observed Product");
80  DRA.DWrite();
81  DRA.Write("tmp_omg_6_DRA.gen");
82 
83  // record test case
84  FAUDES_TEST_DUMP("eps cand", NRA);
85  FAUDES_TEST_DUMP("det cand", DRA);
86 
87 
88  // // Standard partial observable control synthesis
89  // // std::cout << "====== Standard Synthesis ======" << std::endl;
90  // // RabinAutomaton epsObserved;
91  // // RabinCtrlPartialObs(spec,contevents,obsevents,belt1,epsObserved);
92  // // epsObserved.DWrite();
93  // // epsObserved.Write("tmp_omg_6_ObservedBelt.gen");
94  // // epsObserved.GraphWrite("tmp_omg_6_ObservedBelt.png");
95 
96  // Remove self-loof eps transitions and relink the state only with eps transition
97  RabinAutomaton relinkDRA;
98  RemoveEps(DRA, relinkDRA);
99  relinkDRA.DWrite();
100  relinkDRA.Write("tmp_omg_6_relinkDRA.gen");
101 
102  TaIndexSet<EventSet> controller;
103  RabinCtrlPfx(relinkDRA,contevents,controller);
104  relinkDRA.WriteStateSet(controller);
105  std::cout << std::endl;
106 
107  // record
108  FAUDES_TEST_DUMP("controller", controller);
109 
110  // Test the new CloseLoopSpecification function
111  System CLspec;
112  ControlAut(relinkDRA,controller,CLspec);
113  CLspec.DWrite();
114  CLspec.Write("tmp_omg_6_Controller.gen");
115 
116  // Check if the closed-loop controller is deterministic
117  bool cldet= CLspec.IsDeterministic();
118  if (cldet) {
119  std::cout << "CloseLoopController is Deterministic" << std::endl;
120  } else {
121  std::cout << "CloseLoopController is NOT Deterministic (testcase FAILED)" << std::endl;
122  }
123 
124  // ====== Controllability Verification: IsControllable(Plant, Controller) ======
125  System CLspecProjected = CLspec;
126  InvProject(CLspecProjected, plant.Alphabet());
127 
128  bool controllable = IsControllable(plant, CLspecProjected);
129 
130  if (controllable) {
131  std::cout << "CONTROLLABILITY VERIFIED: Controller is controllable w.r.t. Plant" << std::endl;
132  } else {
133  std::cout << "CONTROLLABILITY FAILED: Controller is NOT controllable w.r.t. Plant" << std::endl;
134  }
135 
136  // ====== Language Inclusion Verification: L(V/G) ⊆ L(E) ======
137 
138  CLspec.Name("Controller (V)");
139  plant.Name("Plant (G)");
140  spec.Name("Specification (E)");
141 
142  // Compute V/G (supervised system)
143  System supervisedSystem;
144  InvProject(CLspec, plant.Alphabet());
145  Product(CLspec, plant, supervisedSystem);
146  supervisedSystem.Name("V/G (Supervised System)");
147  supervisedSystem.Write("tmp_omg_6_supervisedSys.gen");
148 
149  // Perform language inclusion verification: L(V/G) ⊆ L(E)
150  bool result = RabinLanguageInclusion(supervisedSystem, spec);
151 
152  if (result) {
153  std::cout << "VERIFICATION SUCCESSFUL: L(V/G) ⊆ L(E)" << std::endl;
154  std::cout << "The supervised system satisfies the specification." << std::endl;
155  } else {
156  std::cout << "VERIFICATION FAILED: L(V/G) ⊄ L(E)" << std::endl;
157  std::cout << "The supervised system does not satisfy the specification." << std::endl;
158  }
159 
160 
161  // graphical output
162  if(DotReady()) {
163  belt2.GraphWrite("tmp_omg_6_belt2.png");
164  belt1.GraphWrite("tmp_omg_6_belt1.png");
165  spec.GraphWrite("tmp_omg_6_spec.png");
166  DRA.GraphWrite("tmp_omg_6_DRA.png");
167  NRA.GraphWrite("tmp_omg_6_EpsObservedProduct.png");
168  ProductPS.GraphWrite("tmp_omg_6_Product.png");
169  relinkDRA.GraphWrite("tmp_omg_6_relinkDRA.png");
170  CLspec.GraphWrite("tmp_omg_6_Controller.png");
171  }
172 
173  // record
174  FAUDES_TEST_DUMP("validate controlability", controllable);
175  FAUDES_TEST_DUMP("validate determinism", cldet);
176  FAUDES_TEST_DUMP("validate languageinclusion", result);
177 
178  // validate
180 
181 }
#define FAUDES_TEST_DIFF()
Definition: cfl_utils.h:515
#define FAUDES_TEST_DUMP(mes, dat)
Definition: cfl_utils.h:505
const std::string & Name(void) const
Definition: cfl_types.cpp:422
bool Insert(const Idx &rIndex)
const TaEventSet< EventAttr > & Alphabet(void) const
void ClrObservable(Idx index)
void SetControllable(Idx index)
void SetObservable(Idx index)
void DWrite(const Type *pContext=0) const
Definition: cfl_types.cpp:231
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
Definition: cfl_types.cpp:267
void Write(const Type *pContext=0) const
Definition: cfl_types.cpp:145
void WriteStateSet(const StateSet &rStateSet) const
bool IsDeterministic(void) const
void GraphWrite(const std::string &rFileName, const std::string &rOutFormat="", const std::string &rDotExec="dot") const
void Product(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
void InvProject(Generator &rGen, const EventSet &rProjectAlphabet)
void RabinBuechiProduct(const RabinAutomaton &rRAut, const Generator &rBAut, RabinAutomaton &rRes)
void PseudoDet(const RabinAutomaton &rGen, RabinAutomaton &rRes)
void RabinCtrlPfx(const RabinAutomaton &rRAut, const EventSet &rSigmaCtrl, StateSet &rCtrlPfx)
void RemoveEps(const RabinAutomaton &rGen, RabinAutomaton &rRes)
bool IsControllable(const Generator &rPlantGen, const EventSet &rCAlph, const Generator &rSupCandGen)
Definition: syn_supcon.cpp:718
bool DotReady(const std::string &rDotExec)
Definition: cfl_utils.cpp:233
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.
void EpsObservation(const RabinAutomaton &rGen, RabinAutomaton &rRes)
Epsilon observation for Rabin automata.
int main()

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