hio_controller.cpp
Go to the documentation of this file.
1 /** @file hio_controller.cpp Generator with I/O-controller attributes */
2 
3 /* Hierarchical IO Systems Plug-In for FAU Discrete Event Systems Library (libfaudes)
4 
5  Copyright (C) 2006 Sebastian Perk
6  Copyright (C) 2006 Thomas Moor
7  Copyright (C) 2006 Klaus Schmidt
8 
9 */
10 
11 #include "hio_controller.h"
12 
13 namespace faudes {
14 
15 // IsHioControllerForm()
16 bool IsHioControllerForm(HioController& rHioController,
17  StateSet& rQUc,
18  StateSet& rQYP,
19  StateSet& rQUp,
20  StateSet& rQYcUp,
21  EventSet& rErrEvSet,
22  TransSet& rErrTrSet,
23  StateSet& rErrStSet,
24  std::string& rReportStr)
25  {
26  FD_DF("IsHioControllerForm("<< rHioController.Name() << ",...)");
27 
28  // prepare results
29  rQUc.Clear();
30  rQYP.Clear();
31  rQUp.Clear();
32  rQYcUp.Clear();
33 
34  rErrEvSet.Clear();
35  rErrEvSet.Name("rErrEvSet");
36 
37  rErrTrSet.Clear();
38  rErrTrSet.Name("rErrTrSet");
39 
40  rErrStSet.Clear();
41  rErrStSet.Name("rErrStSet");
42 
43  // used to locally store error states/transitions on each condition
44  StateSet locErrStSet;
45  TransSet locErrTrSet;
46 
47  rReportStr.clear();
48 
49  // meant to be set false on violation of any condition:
50  bool finalResult = true;
51  // used to locally store result on each condition
52  bool localResult = true;
53 
54  // helpers
55 
56  EventSet yp = rHioController.YpEvents();
57  EventSet up = rHioController.UpEvents();
58  EventSet yc = rHioController.YcEvents();
59  EventSet uc = rHioController.UcEvents();
60 
61  StateSet initStates = rHioController.InitStates();
62  StateSet accessibleStates = rHioController.AccessibleSet();
63  StateSet deadEnds;
64 
65  EventSet::Iterator evit;
66  StateSet::Iterator sit;
68 
69  // Info string header
70  rReportStr.append("#########################################################\n");
71  rReportStr.append("########## IsHioControllerForm("+rHioController.Name()+",...) - test results:\n");
72 
73  /**************************** Precondition: determinism ***********************/
74  // HioController must be deterministic
75  if(!rHioController.IsDeterministic()){
76  rReportStr.append("##### fail: generator is not deterministic!\n");
77  if(initStates.Size()>1) {
78  rErrStSet = initStates;
79  rReportStr.append("##### (amongst others, there is more than one initial state)\n");
80  }
81  finalResult = false;
82  }
83 
84  rReportStr.append("#####\n");
85 
86  // test all conditions verifying I/O-controller form:
87 
88  /**************************** Condition (i) ***********************/
89  localResult = true;
90  rReportStr.append("########## Condition (i):\n");
91 
92  //YP, UP, YC, UC nonempty?
93  if (yp.Empty()) {
94  rReportStr.append("##### fail: empty YP alphabet.\n");
95  localResult=false;
96  finalResult = false;
97  }
98  if (up.Empty()) {
99  rReportStr.append("##### fail: empty UP alphabet.\n");
100  localResult=false;
101  finalResult = false;
102  }
103  if (yc.Empty()) {
104  rReportStr.append("##### fail: empty YC alphabet.\n");
105  localResult=false;
106  finalResult = false;
107  }
108  if (uc.Empty()) {
109  rReportStr.append("##### fail: empty UC alphabet.\n");
110  localResult=false;
111  finalResult = false;
112  }
113 
114  // check for disjoint eventsets YP, YC, UP, UC and for
115  // YP u YC u UP u UC == Sigma, ie unique HioEventFlags.
116  // note: testing disjoint C- and P-Alphabet is sufficient
117  // as properties U and Y are exclusive by construction.
118 
119  rErrEvSet=(rHioController.PEvents()*rHioController.CEvents()) + (rHioController.Alphabet()-rHioController.PEvents()-rHioController.CEvents());
120 
121  // In case of failing condition (i) further inspection is omitted, as too many consecutive faults are expected.
122  if(!rErrEvSet.Empty()){
123  rReportStr.append("##### fail: found events with missing or ambiguous attribute, see rErrEvSet:\n");
124  rReportStr.append(rErrEvSet.ToString()+"\n");
125  rReportStr.append("##### Condition (i) failed.\n");
126  rReportStr.append("########## Termination due to crucial failure. ##########\n");
127  rReportStr.append("#########################################################\n");
128  return false;
129  }
130  if(localResult) rReportStr.append("##### Condition (i) passed.\n");
131  else rReportStr.append("##### Condition (i) failed.\n");
132  rReportStr.append("#####\n");
133  /*************************** Condition (i) finished *****************************/
134 
135 
136  /*************************** Condition (ii) ***********************/
137  localResult = true;
138  rReportStr.append("########## Condition (ii):\n");
139 
140  // Check if in states QUc, QYcUp, QUp and QYP only UC-, YC-/UP-, UP and YP-events are active, respectively.
141  // Also, dead ends are stored for condition (xi)
142  for(sit = accessibleStates.Begin(); sit != accessibleStates.End(); ++sit) {
143 
144  bool isUc = false;
145  bool isYcUp = false;
146  bool isUp = false;
147  bool isYp = false;
148  bool goodState = true;
149 
150  EventSet activeEv = rHioController.ActiveEventSet(*sit);
151 
152  if(activeEv.Empty()) {
153  //dead ends violate condition (xi)
154  deadEnds.Insert(*sit);
155  }
156  else {
157 
158  // get attribute of first event and compare with remaining events
159  evit = activeEv.Begin();
160  isUc = rHioController.IsUc(*evit);
161  isYcUp = rHioController.IsYc(*evit); // YcEvents can only be active in YcUp states
162  isUp = rHioController.IsUp(*evit); // is reset (and YcUp is set) in case YcEvent is found in activeEv
163  isYp = rHioController.IsYp(*evit);
164 
165  for(; evit != activeEv.End(); evit++) {
166  if( (isUc && !rHioController.IsUc(*evit)) ||
167  ((isYcUp||isUp) && (!rHioController.IsYc(*evit) && (!rHioController.IsUp(*evit)))) ||
168  (isYp && !rHioController.IsYp(*evit)) ){
169  goodState = false;
170  localResult = false;
171  finalResult = false;
172  // add state to error set, go to next state
173  locErrStSet.Insert(*sit);
174  break; // leave loop over active events
175  }
176  if(isUp && rHioController.IsYc(*evit)) {
177  isYcUp = true;
178  isUp = false;
179  }
180  }
181 
182  activeEv.Clear();
183 
184  if(!goodState) continue; // if undecidable go on with next state
185 
186  // set state attribute
187  if(isUc) {
188  rQUc.Insert(*sit);
189  rHioController.SetQUc(*sit);
190  }
191  else if(isYcUp) {
192  rQYcUp.Insert(*sit);
193  rHioController.SetQYcUp(*sit);
194  }
195  else if(isUp) {
196  rQUp.Insert(*sit);
197  rHioController.SetQUp(*sit);
198  }
199  else if(isYp){
200  rQYP.Insert(*sit);
201  rHioController.SetQYp(*sit);
202  }
203  }
204  }
205 
206  if(localResult) rReportStr.append("##### Condition (ii) passed.\n");
207  // In case of failing condition (ii) further inspection is omitted, as too many consecutive faults are expected.
208  else {
209  rReportStr.append("##### fail: found states with undecidable attribute:\n");
210  rReportStr.append(locErrStSet.ToString()+"\n");
211  rReportStr.append("##### Condition (ii) failed.\n");
212  rReportStr.append("########## Termination due to crucial failure. ##########\n");
213  rReportStr.append("###################### No success. ######################\n");
214  rReportStr.append("#########################################################\n");
215  rErrStSet.InsertSet(locErrStSet);
216  locErrStSet.Clear();
217  return false;
218  }
219  rReportStr.append("#####\n");
220  /*************************** Condition (ii) finished ****************************/
221 
222 
223  /*************************** Condition (iii) **********************/
224  localResult = true;
225  rReportStr.append("########## Condition (iii):\n");
226 
227  //check if the initial state is a QYP-state
228  if(!(initStates <= rQYP)) {
229  rReportStr.append("##### fail: some init state(s) is (are) not a QYP-state:\n");
230  locErrStSet=initStates-rQYP;
231  rReportStr.append(locErrStSet.ToString()+"\n");
232  rErrStSet.InsertSet(locErrStSet);
233  locErrStSet.Clear();
234  localResult = false;
235  finalResult = false;
236  }
237  if(localResult) rReportStr.append("##### Condition (iii) passed.\n");
238  else rReportStr.append("##### Condition (iii) failed.\n");
239  rReportStr.append("#####\n");
240 
241  /*************************** Condition (iii) finished ***************************/
242 
243 
244  /*************************** Condition (iv) ***********************/
245  localResult = true;
246  rReportStr.append("########## Condition (iv):\n");
247 
248  // YP-events have to lead to a QYcUp or a QUp-state
249  for(sit = rQYP.Begin(); sit != rQYP.End(); ++sit) {
250  for(tit = rHioController.TransRelBegin(*sit); tit != rHioController.TransRelEnd(*sit); ++tit) {
251  // YP-event to QYcUp or QUp-state
252  if ( !( rQYcUp.Exists(tit->X2) || rQUp.Exists(tit->X2) ) ) {
253  // add transition to error transition set
254  locErrTrSet.Insert(*tit);
255  rErrTrSet.Insert(*tit);
256  finalResult = false;
257  localResult = false;
258  }
259  }
260  }
261 
262  if(localResult) rReportStr.append("##### Condition (iv) passed.\n");
263  else {
264  rReportStr.append("##### fail: found YP-transitions leading to wrong states:\n");
265  rReportStr.append(locErrTrSet.ToString()+"\n");
266  locErrTrSet.Clear();
267  rReportStr.append("##### Condition (iv) failed.\n");
268  }
269  rReportStr.append("#####\n");
270  /*************************** Condition (iv) finished ****************************/
271 
272 
273  /*************************** Condition (v) ************************/
274  localResult = true;
275  rReportStr.append("########## Condition (v):\n");
276 
277  // UP-events have to lead to a QYP-state
278  for(sit = rQUp.Begin(); sit != rQUp.End(); ++sit) {
279  for(tit = rHioController.TransRelBegin(*sit); tit != rHioController.TransRelEnd(*sit); ++tit) {
280  if(!rQYP.Exists(tit->X2)) {
281  locErrTrSet.Insert(*tit);
282  rErrTrSet.Insert(*tit);
283  finalResult = false;
284  localResult = false;
285  }
286  }
287  }
288 
289  if(localResult) rReportStr.append("##### Condition (v) passed.\n");
290  else {
291  rReportStr.append("##### fail: found UP-transitions leading to wrong states, see rErrTrSet:\n");
292  rReportStr.append(locErrTrSet.ToString()+"\n");
293  locErrTrSet.Clear();
294  rReportStr.append("##### Condition (v) failed.\n");
295  }
296  rReportStr.append("#####\n");
297  /*************************** Condition (v) finished *****************************/
298 
299 
300  /*************************** Condition (vi) ***********************/
301  localResult = true;
302  rReportStr.append("########## Condition (vi):\n");
303 
304  // From QYcUp states, UP-events have to lead to a QYP-state and YC-events
305  // have to lead to a UC-state
306  for(sit = rQYcUp.Begin(); sit != rQYcUp.End(); ++sit) {
307  for(tit = rHioController.TransRelBegin(*sit); tit != rHioController.TransRelEnd(*sit); ++tit) {
308 
309  if( (rHioController.IsUp(tit->Ev) && !rQYP.Exists(tit->X2)) ||
310  (rHioController.IsYc(tit->Ev) && !rQUc.Exists(tit->X2)) ){
311  rErrTrSet.Insert(*tit);
312  locErrTrSet.Insert(*tit);
313  finalResult = false;
314  localResult = false;
315  }
316  }
317  }
318 
319  if(localResult) rReportStr.append("##### Condition (vi) passed.\n");
320  else {
321  rReportStr.append("##### fail: found YC- or UP-transitions leading to wrong states:\n");
322  rReportStr.append(locErrTrSet.ToString()+"\n");
323  locErrTrSet.Clear();
324  rReportStr.append("##### Condition (vi) failed.\n");
325  }
326  rReportStr.append("#####\n");
327  /*************************** Condition (vi) finished ****************************/
328 
329 
330  /*************************** Condition (vii) ************************/
331  localResult = true;
332  rReportStr.append("########## Condition (vii):\n");
333 
334  // UC-events have to lead to a QUp-state
335  for(sit = rQUc.Begin(); sit != rQUc.End(); ++sit) {
336  for(tit = rHioController.TransRelBegin(*sit); tit != rHioController.TransRelEnd(*sit); ++tit) {
337  if(!rQUp.Exists(tit->X2)) {
338  locErrTrSet.Insert(*tit);
339  rErrTrSet.Insert(*tit);
340  finalResult = false;
341  localResult = false;
342  }
343  }
344  }
345 
346  if(localResult) rReportStr.append("##### Condition (vii) passed.\n");
347  else {
348  rReportStr.append("##### fail: found UC-transitions leading to wrong states:\n");
349  rReportStr.append(locErrTrSet.ToString()+"\n");
350  locErrTrSet.Clear();
351  rReportStr.append("##### Condition (vii) failed.\n");
352  }
353  rReportStr.append("#####\n");
354  /*************************** Condition (vii) finished *****************************/
355 
356 
357  /*************************** Condition (viii) **********************/
358  localResult = true;
359  rReportStr.append("########## Condition (viii):\n");
360 
361  // UC must be free in QUc-states
362  for(sit = rQUc.Begin(); sit != rQUc.End(); ++sit) {
363 
364  if(!(uc <= rHioController.ActiveEventSet(*sit))) {
365  locErrStSet.Insert(*sit);
366  rErrStSet.Insert(*sit);
367  finalResult = false;
368  localResult = false;
369  }
370  }
371 
372  if(localResult) rReportStr.append("##### Condition (viii) passed.\n");
373  else {
374  rReportStr.append("##### fail: found QUc-states with inactive UC-events:\n");
375  rReportStr.append(locErrStSet.ToString()+"\n");
376  locErrStSet.Clear();
377  rReportStr.append("##### Condition (viii) failed.\n");
378  }
379  rReportStr.append("#####\n");
380  /*************************** Condition (viii) finished ***************************/
381 
382 
383  /*************************** Condition (ix) **********************/
384  localResult = true;
385  rReportStr.append("########## Condition (ix):\n");
386 
387  // YP must be free in QYP-states
388  for(sit = rQYP.Begin(); sit != rQYP.End(); ++sit) {
389 
390  if(!(yp <= rHioController.ActiveEventSet(*sit))) {
391  locErrStSet.Insert(*sit);
392  rErrStSet.Insert(*sit);
393  finalResult = false;
394  localResult = false;
395  }
396  }
397 
398  if(localResult) rReportStr.append("##### Condition (ix) passed.\n");
399  else {
400  rReportStr.append("##### fail: found QYP-states with inactive YP-events:\n");
401  rReportStr.append(locErrStSet.ToString()+"\n");
402  locErrStSet.Clear();
403  rReportStr.append("##### Condition (ix) failed.\n");
404  }
405  rReportStr.append("#####\n");
406  /*************************** Condition (ix) finished ***************************/
407 
408 
409  /*************************** Condition (x) ***********************/
410  localResult = true;
411  rReportStr.append("########## Condition (x):\n");
412 
413  // Qm==Q?
414  if(!(accessibleStates<=rHioController.MarkedStates())) {
415  finalResult = false;
416  localResult = false;
417  }
418 
419  if(localResult) rReportStr.append("##### Condition (x) passed.\n");
420  else {
421  rReportStr.append("##### fail: not all accessible states are marked:\n");
422  locErrStSet = accessibleStates - rHioController.MarkedStates();
423  rErrStSet.InsertSet(locErrStSet);
424  rReportStr.append(locErrStSet.ToString()+"\n");
425  locErrStSet.Clear();
426  rReportStr.append("##### Condition (x) failed.\n");
427  }
428  rReportStr.append("#####\n");
429  /*************************** Condition (x) finished ****************************/
430 
431 
432  /*************************** Condition (xi) ************************/
433  localResult = true;
434  rReportStr.append("########## Condition (xi):\n");
435 
436  // found dead ends?
437  if(!deadEnds.Empty()) {
438  finalResult = false;
439  localResult = false;
440  rErrStSet.InsertSet(deadEnds);
441  rReportStr.append("##### fail: found dead ends:\n");
442  rReportStr.append(deadEnds.ToString()+"\n");
443  deadEnds.Clear();
444  rReportStr.append("##### Condition (xi) failed.\n");
445  }
446  rReportStr.append("##### Condition (xi) passed.\n");
447  /*************************** Condition (xi) finished *****************************/
448 
449 
450  /*************************** Condition (xii) ************************/
451  rReportStr.append("########## Condition (xii):\n");
452 
453  // make accessible if necessary
454  if(!rHioController.IsAccessible()) {
455  rHioController.Accessible();
456  rReportStr.append("##### warning: non-accessible states have been removed.\n");
457  rReportStr.append("##### Condition (xii) repaired.\n");
458  }
459  else rReportStr.append("##### Condition (xii) passed.\n");
460  /*************************** Condition (xii) finished *****************************/
461 
462 
463 
464  /*************************** Final result ****************************/
465  rReportStr.append("##################### Final result: #####################\n");
466  if(finalResult) {
467  rReportStr.append("######### Generator is in HioControllerForm. #########\n");
468  rReportStr.append("#########################################################\n");
469  return true;
470  }
471  else {
472  rReportStr.append("########### Generator is NOT in HioControllerForm. ###########\n");
473  rReportStr.append("#########################################################\n");
474  return false;
475  }
476 
477 }// END OF IsHioControllerForm()
478 
479 //IsHioControllerForm wrapper functions
480 bool IsHioControllerForm(HioController& rHioController,std::string& rReportStr)
481 {
482  StateSet QUc, QYP, QUp, QYcUp;
483  EventSet ErrEvSet;
484  TransSet ErrTrSet;
485  StateSet ErrStSet;
486 
487  return IsHioControllerForm(rHioController, QUc, QYP, QUp, QYcUp, ErrEvSet, ErrTrSet, ErrStSet, rReportStr);
488 }
489 
490 bool IsHioControllerForm(HioController& rHioController)
491 {
492  StateSet QUc, QYP, QUp, QYcUp;
493  EventSet ErrEvSet;
494  TransSet ErrTrSet;
495  StateSet ErrStSet;
496  std::string ReportStr;
497 
498  return IsHioControllerForm(rHioController, QUc, QYP, QUp, QYcUp, ErrEvSet, ErrTrSet, ErrStSet, ReportStr);
499 }
500 
501 // rti function interface
502 void HioStatePartition(HioController& rHioController) {
503  IsHioControllerForm(rHioController);
504 }
505 
506 } // end namespace
#define FD_DF(message)
Debug: optional report on user functions.
Set of indices.
Definition: cfl_indexset.h:78
Idx Insert(void)
Insert new index to set.
Set of indices with symbolic names.
Definition: cfl_nameset.h:69
EventSet PEvents(void) const
Get EventSet with P-events.
EventSet YcEvents(void) const
Get EventSet with Yc-events.
void SetQYcUp(Idx index)
Mark event as QYcUp-state (by index)
EventSet CEvents(void) const
Get EventSet with E-events.
void SetQUc(Idx index)
Mark event as QUc-state (by index)
EventSet UcEvents(void) const
Get EventSet with Uc-events.
EventSet YpEvents(void) const
Get EventSet with Yp-events.
bool IsUc(Idx index) const
Is event Uc-event (by index)
void SetQYp(Idx index)
Mark state as QYP-state (by index)
bool IsUp(Idx index) const
Is event Up-event(by index)
void SetQUp(Idx index)
Mark event as QUp-state (by index)
bool IsYp(Idx index) const
Is event Yp-event(by index)
EventSet UpEvents(void) const
Get EventSet with Up-events.
bool IsYc(Idx index) const
Is event Yc-event (by index)
bool Insert(const Transition &rTransition)
Add a Transition.
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Iterator on transition.
Definition: cfl_transset.h:269
const TaEventSet< EventAttr > & Alphabet(void) const
Return const reference to alphabet.
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Write configuration data to a string.
Definition: cfl_types.cpp:169
const StateSet & MarkedStates(void) const
Return const ref of marked states.
EventSet ActiveEventSet(Idx x1) const
Return active event set at state x1.
const StateSet & InitStates(void) const
Const ref to initial states.
TransSet::Iterator TransRelBegin(void) const
Iterator to Begin() of transition relation.
bool Accessible(void)
Make generator accessible.
bool IsAccessible(void) const
Check if generator is accessible.
StateSet AccessibleSet(void) const
Compute set of accessible states.
void Name(const std::string &rName)
Set the generator's name.
TransSet::Iterator TransRelEnd(void) const
Iterator to End() of transition relation.
bool IsDeterministic(void) const
Check if generator is deterministic.
bool Empty(void) const
Test whether if the TBaseSet is Empty.
Definition: cfl_baseset.h:1824
bool Exists(const T &rElem) const
Test existence of element.
Definition: cfl_baseset.h:2115
virtual void Clear(void)
Clear all set.
Definition: cfl_baseset.h:1902
Iterator End(void) const
Iterator to the end of set.
Definition: cfl_baseset.h:1896
virtual void InsertSet(const TBaseSet &rOtherSet)
Insert elements given by rOtherSet.
Definition: cfl_baseset.h:1987
Iterator Begin(void) const
Iterator to the begin of set.
Definition: cfl_baseset.h:1891
const std::string & Name(void) const
Return name of TBaseSet.
Definition: cfl_baseset.h:1755
Idx Size(void) const
Get Size of TBaseSet.
Definition: cfl_baseset.h:1819
Generator with I/O-controller attributes.
libFAUDES resides within the namespace faudes.
bool IsHioControllerForm(HioController &rHioController, StateSet &rQUc, StateSet &rQYP, StateSet &rQUp, StateSet &rQYcUp, EventSet &rErrEvSet, TransSet &rErrTrSet, StateSet &rErrStSet, std::string &rReportStr)
IsHioControllerForm: check if rHioController is in I/O-controller form and assign state attributes.
void HioStatePartition(HioConstraint &rHioConstraint)
Function definition for run-time interface.

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