hyb_5_controlB.cpp
Go to the documentation of this file.
1 /** @file hyb_5_controlB.cpp
2 
3 Tutorial, hybrid systems plugin. This tutorial demonstrates
4 how to compute a finite abstraction for the purpose of
5 control.
6 
7 @ingroup Tutorials
8 
9 @include hyb_5_ControlB.cpp
10 
11 */
12 
13 #include "libfaudes.h"
14 
15 // make the faudes namespace available to our program
16 using namespace faudes;
17 
18 /**
19  * In this example, dynamics are given programtically, i.e. by
20  * a customised instance of CompatibleStates as opposed to the
21  * ready-to-use versions for DES or LHA.
22  *
23  * The plant we implement consits simple tank with two input
24  * symbols for fill '+' and drain '-' and two output symbols for
25  * full 'F' and and empty 'E'. Inputs symbols and output symbols
26  * alternate.
27  */
28 
30 
31 protected:
32  /** one single "real" interval of compatible continuous states */
33  double mXmin;
34  double mXmax;
35  bool mLopen;
36  bool mHopen;
37  /** recent input as discrete state, values "+", "-", none "~", init "0" */
38  char mU;
39  /** transition result */
40  std::map<Idx, ExbCompatibleStates*> mReachSets;
41  /** event symbol table (cosmetic) */
43 
44 public:
45 
46  /** construct/destruct */
47  ExbCompatibleStates(const EventSet& alph) :
49  rAlphabet(alph) {
50  };
52  Clear();
53  };
54 
55  /** allway initialisation with no constraints, i.e., time invariant system */
56  void InitialiseFull(void) {
57  mXmin=0; mXmax=30; mLopen=false; mHopen=false; mU='0';
58  };
60  InitialiseFull();
61  }
62 
63  /** debug dump */
64  void DWrite(void) const {
65  std::cout << "continuous state set: ";
66  if(mLopen) std::cout << "(";
67  else std::cout << "[";
68  std::cout << mXmin << ", " << mXmax;
69  if(mHopen) std::cout << ")";
70  else std::cout << "]";
71  std::cout << " last input " << mU << std::endl;
72  }
73 
74  /** implement dynamics */
75  virtual void ExecuteTransitions(void) {
76  FD_DF("ExampleB: execute dynamics");
77  Clear();
79  switch(mU) {
80  // last event was an input symbol, thus we generate an output sybol
81  case '+':
82  case '-':
83  case '0':
84  // can we generate 'E'?
85  if( mXmin < 15 || ((mXmin == 15) && (mLopen == false)) ) {
86  ncs=new ExbCompatibleStates(rAlphabet);
87  ncs->mXmin=mXmin;
88  ncs->mLopen = mLopen;
89  ncs->mXmax = (mXmax <= 15 ? mXmax : 15);
90  ncs->mHopen = (mXmax <= 15 ? mHopen : false);
91  ncs->mU='~';
92  mReachSets[rAlphabet.Index("E")]=ncs;
93  }
94  // can we generate 'F'?
95  if(mXmax > 15) {
96  ncs=new ExbCompatibleStates(rAlphabet);
97  ncs->mXmax=mXmax;
98  ncs->mHopen = mHopen;
99  ncs->mXmin = (mXmin > 15 ? mXmin : 15);
100  ncs->mLopen = (mXmin > 15 ? mLopen : true);
101  mReachSets[rAlphabet.Index("F")]=ncs;
102  ncs->mU='~';
103  }
104  break;
105  // last event was an output symbol, this we accept and execute any input symbol
106  case '~':
107  // perform '+'
108  ncs=new ExbCompatibleStates(rAlphabet);
109  ncs->mXmax =mXmax+10;
110  ncs->mHopen = mHopen;
111  ncs->mXmin = mXmin+10;
112  ncs->mLopen = mLopen;
113  if(ncs->mXmax>=30) {ncs->mXmax=30; ncs->mHopen=false;}
114  if(ncs->mXmin>=30) {ncs->mXmin=30; ncs->mLopen=false;}
115  mReachSets[rAlphabet.Index("+")]=ncs;
116  ncs->mU='+';
117  // perform '-'
118  ncs=new ExbCompatibleStates(rAlphabet);
119  ncs->mXmax =mXmax-10;
120  ncs->mHopen = mHopen;
121  ncs->mXmin = mXmin-10;
122  ncs->mLopen = mLopen;
123  if(ncs->mXmax<=0) {ncs->mXmax=0; ncs->mHopen=false;}
124  if(ncs->mXmin<=0) {ncs->mXmin=0; ncs->mLopen=false;}
125  mReachSets[rAlphabet.Index("-")]=ncs;
126  ncs->mU='-';
127  }
128  FD_DF("ExampleB: execute dynamics: ok.");
129  }
130 
131  // read out
133  std::map<Idx, ExbCompatibleStates*>::iterator sit=mReachSets.find(ev);
134  if(sit==mReachSets.end()) return 0;
135  ExbCompatibleStates* res= sit->second;
136  sit->second=0;
137  return res;
138  }
139 
140  // support
141  void Clear(void) {
142  std::map<Idx, ExbCompatibleStates*>::iterator sit=mReachSets.begin();
143  std::map<Idx, ExbCompatibleStates*>::iterator sit_end=mReachSets.end();
144  for(;sit!=sit_end;++sit) {
145  if(sit->second) delete sit->second;
146  }
147  mReachSets.clear();
148  }
149 
150 };
151 
152 
153 
154 /** Run the tutorial */
155 int main() {
156 
157  // have alphabet
158  EventSet alph;
159  alph.FromString("<A> F E \"+\" \"-\" </A>");
160 
161  // compile l-complete abstraction
162  ExbCompatibleStates* comp = new ExbCompatibleStates(alph);
163  comp->InitialiseFull();
164  Experiment* exp = new Experiment(alph);
165  exp->InitialStates(comp);
166  LbdAbstraction tivabs;
167  tivabs.Experiment(exp);
168  tivabs.RefineUniformly(4);
169  tivabs.Experiment().DWrite();
170  Generator lcabs = tivabs.TivAbstraction();
171  lcabs.StateNamesEnabled(false);
172  //StateMin(lcabs,lcabs);
173  lcabs.GraphWrite("tmp_hyb_5tiv2.png");
174 
175  // have a specification
176  Generator spec;
177  spec.FromString(
178  "<Generator> <T> 1 E 2 1 F 2 2 \"+\" 3 2 \"-\" 3 3 E 4 3 F 4 4 - 5 4 \"+\" 5 5 F 5 5 \"+\" 5 5 \"-\" 5 </T> <I> 1 </I></Generator>");
179 
180  // set up uncontrollable events
181  EventSet ucevents;
182  ucevents.FromString("<A> E F </A>");
183 
184  // learning by doing
185  while(1) {
186 
187  // synthesise controller
188  Generator loop;
189  loop.StateNamesEnabled(true);
190  spec.StateNamesEnabled(true);
191  lcabs.StateNamesEnabled(true);
192  ProductCompositionMap psmap;
193  Parallel(lcabs,spec,psmap,loop);
194  while(1) {
195  Idx sz =loop.Size();
196  loop.Complete();
197  loop.Accessible();
198  StateSet fail;
199  StateSet::Iterator sit=loop.StatesBegin();
200  StateSet::Iterator sit_end=loop.StatesEnd();
201  for(;sit!=sit_end;++sit) {
202  Idx pstate = psmap.Arg1State(*sit);
203  EventSet penabled=lcabs.ActiveEventSet(pstate);
204  EventSet lenabled=loop.ActiveEventSet(*sit);
205  if(penabled * ucevents <= lenabled) continue;
206  fail.Insert(*sit);
207  }
208  loop.DelStates(fail);
209  if(loop.Size()==sz) break;
210  }
211  if(loop.Size()>0) {
212  std::cout << " Synthesis succeeded ";
213  loop.GraphWrite("tmp_hyb_5sup.png");
214  break;
215  }
216 
217 
218  // refinement candidates
219  StateSet leaves = tivabs.Experiment().Leaves();
220  std::cout << "refinement candidates (leaves)" << std::endl;
221  leaves.Write();
222 
223  // search for refinement candidates, "Step 1/2"
224  Generator loop12;
225  Generator spec12;
226  spec12.StateNamesEnabled(false);
227  Parallel(lcabs,spec,psmap,spec12);
228  StateSet::Iterator sit=spec12.StatesBegin();
229  StateSet::Iterator sit_end=spec12.StatesEnd();
230  for(;sit!=sit_end;++sit) {
231  if(!leaves.Exists(psmap.Arg1State(*sit))) continue;
232  spec12.ClrTransitions(*sit);
233  EventSet::Iterator eit=spec12.AlphabetBegin();
234  EventSet::Iterator eit_end=spec12.AlphabetEnd();
235  for(;eit!=eit_end;++eit) spec12.SetTransition(*sit,*eit,*sit);
236  }
237  spec12.Accessible();
238  spec12.GraphWrite("tmp_hyb_5spec12.png");
239  loop12.StateNamesEnabled(true);
240  spec12.StateNamesEnabled(true);
241  lcabs.StateNamesEnabled(true);
242  Parallel(lcabs,spec12,psmap,loop12);
243  //loop12.GraphWrite("tmp_hyb_5ctrllp.png");
244  while(1) {
245  Idx sz =loop12.Size();
246  loop12.Complete();
247  loop12.Accessible();
248  StateSet fail;
249  sit=loop12.StatesBegin();
250  sit_end=loop12.StatesEnd();
251  for(;sit!=sit_end;++sit) {
252  Idx pstate = psmap.Arg1State(*sit);
253  EventSet penabled=lcabs.ActiveEventSet(pstate);
254  EventSet lenabled=loop12.ActiveEventSet(*sit);
255  if(penabled * ucevents <= lenabled) continue;
256  fail.Insert(*sit);
257  }
258  loop12.DelStates(fail);
259  if(loop12.Size()==sz) break;
260  }
261  loop12.GraphWrite("tmp_hyb_5ctrl12.png");
262  StateSet step12;
263  sit=loop12.StatesBegin();
264  sit_end=loop12.StatesEnd();
265  for(;sit!=sit_end;++sit)
266  if(leaves.Exists(psmap.Arg1State(*sit))) step12.Insert(psmap.Arg1State(*sit));
267  std::cout << "refinement candidates (step12)" << std::endl;
268  step12.Write();
269 
270 
271  // search for refinement candidates, "cpx"
272  Generator loopcpx;
273  loopcpx.StateNamesEnabled(false);
274  Parallel(lcabs,spec,psmap,loopcpx);
275  while(1) {
276  Idx sz =loopcpx.Size();
277  loopcpx.Complete();
278  StateSet fail;
279  StateSet::Iterator sit=loopcpx.StatesBegin();
280  StateSet::Iterator sit_end=loopcpx.StatesEnd();
281  for(;sit!=sit_end;++sit) {
282  Idx pstate = psmap.Arg1State(*sit);
283  EventSet penabled=lcabs.ActiveEventSet(pstate);
284  EventSet lenabled=loopcpx.ActiveEventSet(*sit);
285  if(penabled * ucevents <= lenabled) continue;
286  fail.Insert(*sit);
287  }
288  loopcpx.DelStates(fail);
289  if(loopcpx.Size()==sz) break;
290  }
291  loopcpx.GraphWrite("tmp_hyb_5ctrlcpx.png");
292  StateSet qcpx;
293  sit=loopcpx.StatesBegin();
294  sit_end=loopcpx.StatesEnd();
295  for(;sit!=sit_end;++sit)
296  qcpx.Insert(psmap.Arg1State(*sit));
297  StateSet stepcpx = leaves - qcpx;
298  std::cout << "refinement candidates (cpx)" << std::endl;
299  stepcpx.Write();
300 
301 
302 
303  // do refinement
304  StateSet refine = stepcpx * step12;
305  if(refine.Size()==0) break;
306  sit=refine.Begin();
307  sit_end=refine.End();
308  for(;sit!=sit_end;++sit)
309  tivabs.RefineAt(*sit);
310  lcabs = tivabs.TivAbstraction();
311 
312 
313  }
314 
315 
316  // done
317  return 0;
318 }
319 
320 
321 
#define FD_DF(message)
Debug: optional report on user functions.
#define FAUDES_API
Interface export/import symbols: windows.
Definition: cfl_platform.h:81
In this example, dynamics are given programtically, i.e.
virtual void ExecuteTransitions(void)
implement dynamics
void DWrite(void) const
debug dump
std::map< Idx, ExbCompatibleStates * > mReachSets
transition result
ExbCompatibleStates * TakeByEvent(Idx ev)
char mU
recent input as discrete state, values "+", "-", none "~", init "0"
double mXmin
one single "real" interval of compatible continuous states
void InitialiseFull(void)
allway initialisation with no constraints, i.e., time invariant system
ExbCompatibleStates(const EventSet &alph)
construct/destruct
const EventSet & rAlphabet
event symbol table (cosmetic)
Abstract dynamics operator, i.e., some set of states, that knows where it eveolves when it next trigg...
Finite fragment of a computation tree.
void InitialStates(CompatibleStates *istates)
Set of indices.
Definition: cfl_indexset.h:78
Idx Insert(void)
Insert new index to set.
void RefineUniformly(unsigned int depth)
const Generator & TivAbstraction(void)
void Experiment(faudes::Experiment *exp)
Set of indices with symbolic names.
Definition: cfl_nameset.h:69
Idx Index(const std::string &rName) const
Index lookup.
Rti-wrapper for composition maps.
Definition: cfl_parallel.h:43
Idx Arg1State(Idx s12) const
void FromString(const std::string &rString, const std::string &rLabel="", const Type *pContext=0)
Read configuration data from a string.
Definition: cfl_types.cpp:275
void Write(const Type *pContext=0) const
Write configuration data to console.
Definition: cfl_types.cpp:139
Base class of all FAUDES generators.
StateSet::Iterator StatesBegin(void) const
Iterator to Begin() of state set.
bool SetTransition(Idx x1, Idx ev, Idx x2)
Add a transition to generator by indices.
EventSet ActiveEventSet(Idx x1) const
Return active event set at state x1.
bool Accessible(void)
Make generator accessible.
void ClrTransitions(Idx x1, Idx ev)
Remove a transitions by state and event.
EventSet::Iterator AlphabetBegin(void) const
Iterator to Begin() of alphabet.
StateSet::Iterator StatesEnd(void) const
Iterator to End() of state set.
void DelStates(const StateSet &rDelStates)
Delete a set of states Cleans mpStates, mInitStates, mMarkedStates, mpTransrel, and mpStateSymboltabl...
bool StateNamesEnabled(void) const
Whether libFAUEDS functions are requested to generate state names.
void GraphWrite(const std::string &rFileName, const std::string &rOutFormat="", const std::string &rDotExec="dot") const
Produce graphical representation of this generator.
EventSet::Iterator AlphabetEnd(void) const
Iterator to End() of alphabet.
Idx Size(void) const
Get generator size (number of states)
bool Complete(void)
Make generator Complete.
bool Exists(const T &rElem) const
Test existence of element.
Definition: cfl_baseset.h:2115
Iterator End(void) const
Iterator to the end of set.
Definition: cfl_baseset.h:1896
Iterator Begin(void) const
Iterator to the begin of set.
Definition: cfl_baseset.h:1891
Idx Size(void) const
Get Size of TBaseSet.
Definition: cfl_baseset.h:1819
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
Parallel composition.
int main()
Run the tutorial.
Includes all libFAUDES headers, incl plugings
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)

libFAUDES 2.32b --- 2024.03.01 --- c++ api documentaion by doxygen