hio_plant.cpp
Go to the documentation of this file.
1 /** @file hio_plant.cpp Generator with I/O-plant 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_plant.h"
12 
13 namespace faudes {
14 
15 // IsHioPlantForm()
16 bool IsHioPlantForm(HioPlant& rHioPlant,
17  StateSet& rQYpYe,
18  StateSet& rQUp,
19  StateSet& rQUe,
20  EventSet& rErrEvSet,
21  TransSet& rErrTrSet,
22  StateSet& rErrStSet,
23  std::string& rReportStr)
24  {
25  FD_DF("IsHioPlantForm("<< rHioPlant.Name() << ",...)");
26 
27  // prepare results
28  rQYpYe.Clear();
29  rQUp.Clear();
30  rQUe.Clear();
31 
32  rErrEvSet.Clear();
33  rErrEvSet.Name("rErrEvSet");
34 
35  rErrTrSet.Clear();
36  rErrTrSet.Name("rErrTrSet");
37 
38  rErrStSet.Clear();
39  rErrStSet.Name("rErrStSet");
40 
41  // used to locally store error states/transitions on each condition
42  StateSet locErrStSet;
43  TransSet locErrTrSet;
44 
45  rReportStr.clear();
46 
47  // meant to be set false on violation of any condition:
48  bool finalResult = true;
49  // used to locally store result on each condition
50  bool localResult = true;
51 
52  // helpers
53 
54  EventSet yp = rHioPlant.YpEvents();
55  EventSet up = rHioPlant.UpEvents();
56  EventSet ye = rHioPlant.YeEvents();
57  EventSet ue = rHioPlant.UeEvents();
58 
59  StateSet initStates = rHioPlant.InitStates();
60  StateSet accessibleStates = rHioPlant.AccessibleSet();
61 
62  EventSet::Iterator evit;
63  StateSet::Iterator sit;
65 
66  // Info string header
67  rReportStr.append("#########################################################\n");
68  rReportStr.append("########## IsHioPlantForm("+rHioPlant.Name()+",...) - test results:\n");
69 
70  /**************************** Precondition: determinism ***********************/
71  // HioPlant must be deterministic
72  if(!rHioPlant.IsDeterministic()){
73  rReportStr.append("##### fail: generator is not deterministic!\n");
74  if(initStates.Size()>1) {
75  rErrStSet = initStates;
76  rReportStr.append("##### (amongst others, there is more than one initial state)\n");
77  }
78  finalResult = false;
79  }
80 
81  rReportStr.append("#####\n");
82 
83  // test all conditions verifying I/O-plant form:
84 
85  /**************************** Condition (i) ***********************/
86  localResult = true;
87  rReportStr.append("########## Condition (i):\n");
88 
89  //YP, UP, YE, UE nonempty?
90  if (yp.Empty()) {
91  rReportStr.append("##### fail: empty YP alphabet.\n");
92  localResult=false;
93  finalResult = false;
94  }
95  if (up.Empty()) {
96  rReportStr.append("##### fail: empty UP alphabet.\n");
97  localResult=false;
98  finalResult = false;
99  }
100  if (ye.Empty()) {
101  rReportStr.append("##### fail: empty YE alphabet.\n");
102  localResult=false;
103  finalResult = false;
104  }
105  if (ue.Empty()) {
106  rReportStr.append("##### fail: empty UE alphabet.\n");
107  localResult=false;
108  finalResult = false;
109  }
110 
111  // check for disjoint eventsets YP, YE, UP, UE and for
112  // YP u YE u UP u UE == Sigma, ie unique HioEventFlags.
113  // note: testing disjoint P- and E-Alphabet is sufficient
114  // as properties U and Y are exclusive by construction.
115 
116  rErrEvSet=(rHioPlant.PEvents()*rHioPlant.EEvents()) + (rHioPlant.Alphabet()-rHioPlant.PEvents()-rHioPlant.EEvents());
117 
118  // In case of failing condition (i) further inspection is omitted, as too many consecutive faults are expected.
119  if(!rErrEvSet.Empty()){
120  rReportStr.append("##### fail: found events with missing or ambiguous attribute, see rErrEvSet:\n");
121  rReportStr.append(rErrEvSet.ToString()+"\n");
122  rReportStr.append("##### Condition (i) failed.\n");
123  rReportStr.append("########## Termination due to crucial failure. ##########\n");
124  rReportStr.append("#########################################################\n");
125  return false;
126  }
127  if(localResult) rReportStr.append("##### Condition (i) passed.\n");
128  else rReportStr.append("##### Condition (i) failed.\n");
129  rReportStr.append("#####\n");
130  /*************************** Condition (i) finished *****************************/
131 
132 
133  /*************************** Condition (ii) ***********************/
134  localResult = true;
135  rReportStr.append("########## Condition (ii):\n");
136 
137  // check if in states QYpYe, QUp and QUe only Y-, UP- and UE-events are active, respectively.
138  for(sit = accessibleStates.Begin(); sit != accessibleStates.End(); ++sit) {
139 
140  bool isY = false;
141  bool isUp = false;
142  bool isUe = false;
143  bool goodState = true;
144 
145  EventSet activeEv = rHioPlant.ActiveEventSet(*sit);
146 
147  if(activeEv.Empty()) {
148  //deadlocks are always QYpYe -states
149  rQYpYe.Insert(*sit);
150  rHioPlant.SetQYpYe(*sit);
151  }
152  else {
153 
154  // get attribute of first event and compare with remaining events
155  evit = activeEv.Begin();
156  isY = rHioPlant.IsY(*evit);
157  isUp = rHioPlant.IsUp(*evit);
158  isUe = rHioPlant.IsUe(*evit);
159 
160  for(; evit != activeEv.End(); evit++) {
161  if( (isY && !rHioPlant.IsY(*evit)) ||
162  (isUp && !rHioPlant.IsUp(*evit)) ||
163  (isUe && !rHioPlant.IsUe(*evit)) ) {
164  goodState = false;
165  localResult = false;
166  finalResult = false;
167  // add state to error set, go to next state
168  locErrStSet.Insert(*sit);
169  rErrStSet.Insert(*sit);
170  break; // leave loop over active events
171  }
172  }
173 
174  activeEv.Clear();
175 
176  if(!goodState) continue; // if undecidable go on with next state
177 
178  // set state attribute
179  if(isY) {
180  rQYpYe.Insert(*sit);
181  rHioPlant.SetQYpYe(*sit);
182  }
183  else if(isUp) {
184  rQUp.Insert(*sit);
185  rHioPlant.SetQUp(*sit);
186  }
187  else if(isUe){
188  rQUe.Insert(*sit);
189  rHioPlant.SetQUe(*sit);
190  }
191  }
192  }
193 
194  if(localResult) rReportStr.append("##### Condition (ii) passed.\n");
195  // In case of failing condition (ii) further inspection is omitted, as too many consecutive faults are expected.
196  else {
197  rReportStr.append("##### fail: found states with undecidable attribute:\n");
198  rReportStr.append(locErrStSet.ToString()+"\n");
199  locErrStSet.Clear();
200  rReportStr.append("##### Condition (ii) failed.\n");
201  rReportStr.append("########## Termination due to crucial failure. ##########\n");
202  rReportStr.append("###################### No success. ######################\n");
203  rReportStr.append("#########################################################\n");
204  return false;
205  }
206  rReportStr.append("#####\n");
207  /*************************** Condition (ii) finished ****************************/
208 
209 
210  /*************************** Condition (iii) **********************/
211  localResult = true;
212  rReportStr.append("########## Condition (iii):\n");
213 
214  //check if the initial state is a QYpYe-state
215  if(!(initStates <= rQYpYe)) {
216  rReportStr.append("##### fail: some init state(s) is (are) not a QYpYe-state:\n");
217  locErrStSet=initStates-rQYpYe;
218  rErrStSet.InsertSet(locErrStSet);
219  rReportStr.append(locErrStSet.ToString()+"\n");
220  locErrStSet.Clear();
221  localResult = false;
222  finalResult = false;
223  }
224  if(localResult) rReportStr.append("##### Condition (iii) passed.\n");
225  else rReportStr.append("##### Condition (iii) failed.\n");
226  rReportStr.append("#####\n");
227 
228  /*************************** Condition (iii) finished ***************************/
229 
230 
231  /*************************** Condition (iv) ***********************/
232  localResult = true;
233  rReportStr.append("########## Condition (iv):\n");
234 
235  // YP-events have to lead to a QUp-state, while a YE-events
236  // have to lead to a QUe-state.
237  for(sit = rQYpYe.Begin(); sit != rQYpYe.End(); ++sit) {
238  for(tit = rHioPlant.TransRelBegin(*sit); tit != rHioPlant.TransRelEnd(*sit); ++tit) {
239  // YP-event to QUp-state, YE-event to QUe-state
240  if( (rHioPlant.IsYp(tit->Ev) && !(rQUp.Exists(tit->X2) || rQUe.Exists(tit->X2)))) {
241  // add transition to error transition set
242  rErrTrSet.Insert(*tit);
243  locErrTrSet.Insert(*tit);
244  finalResult = false;
245  localResult = false;
246  }
247  }
248  }
249 
250  if(localResult) rReportStr.append("##### Condition (iv) passed.\n");
251  else {
252  rReportStr.append("##### fail: found YP- or YE-transitions leading to wrong states:\n");
253  rReportStr.append(locErrTrSet.ToString()+"\n");
254  locErrTrSet.Clear();
255  rReportStr.append("##### Condition (iv) failed.\n");
256  }
257  rReportStr.append("#####\n");
258  /*************************** Condition (iv) finished ****************************/
259 
260 
261  /*************************** Condition (v) ************************/
262  localResult = true;
263  rReportStr.append("########## Condition (v):\n");
264 
265  // UP-events have to lead to a QYpYe-state
266  for(sit = rQUp.Begin(); sit != rQUp.End(); ++sit) {
267  for(tit = rHioPlant.TransRelBegin(*sit); tit != rHioPlant.TransRelEnd(*sit); ++tit) {
268  if(!rQYpYe.Exists(tit->X2)) {
269  rErrTrSet.Insert(*tit);
270  locErrTrSet.Insert(*tit);
271  finalResult = false;
272  localResult = false;
273  }
274  }
275  }
276 
277  if(localResult) rReportStr.append("##### Condition (v) passed.\n");
278  else {
279  rReportStr.append("##### fail: found UP-transitions leading to wrong states:\n");
280  rReportStr.append(locErrTrSet.ToString()+"\n");
281  locErrTrSet.Clear();
282  rReportStr.append("##### Condition (v) failed.\n");
283  }
284  rReportStr.append("#####\n");
285  /*************************** Condition (v) finished *****************************/
286 
287 
288  /*************************** Condition (vi) ***********************/
289  localResult = true;
290  rReportStr.append("########## Condition (vi):\n");
291 
292  // UE-events have to lead to a QYpYe-state
293  for(sit = rQUe.Begin(); sit != rQUe.End(); ++sit) {
294  for(tit = rHioPlant.TransRelBegin(*sit); tit != rHioPlant.TransRelEnd(*sit); ++tit) {
295  if(!rQYpYe.Exists(tit->X2)) {
296  rErrTrSet.Insert(*tit);
297  locErrTrSet.Insert(*tit);
298  finalResult = false;
299  localResult = false;
300  }
301  }
302  }
303 
304  if(localResult) rReportStr.append("##### Condition (vi) passed.\n");
305  else {
306  rReportStr.append("##### fail: found UE-transitions leading to wrong states:\n");
307  rReportStr.append(locErrTrSet.ToString()+"\n");
308  locErrTrSet.Clear();
309  rReportStr.append("##### Condition (vi) failed.\n");
310  }
311  rReportStr.append("#####\n");
312  /*************************** Condition (vi) finished ****************************/
313 
314 
315  /*************************** Condition (vii) **********************/
316  localResult = true;
317  rReportStr.append("########## Condition (vii):\n");
318 
319  // UP must be free in QUp-states
320  for(sit = rQUp.Begin(); sit != rQUp.End(); ++sit) {
321 
322  if(!(up <= rHioPlant.ActiveEventSet(*sit))) {
323  rErrStSet.Insert(*sit);
324  locErrStSet.Insert(*sit);
325  finalResult = false;
326  localResult = false;
327  }
328  }
329 
330  if(localResult) rReportStr.append("##### Condition (vii) passed.\n");
331  else {
332  rReportStr.append("##### fail: found QUp-states with inactive UP-events:\n");
333  rReportStr.append(locErrStSet.ToString()+"\n");
334  locErrStSet.Clear();
335  rReportStr.append("##### Condition (vii) failed.\n");
336  }
337  rReportStr.append("#####\n");
338  /*************************** Condition (vii) finished ***************************/
339 
340 
341  /*************************** Condition (viii) **********************/
342  localResult = true;
343  rReportStr.append("########## Condition (viii):\n");
344 
345  // UE must be free in QUe-states
346  for(sit = rQUe.Begin(); sit != rQUe.End(); ++sit) {
347 
348  if(!(ue <= rHioPlant.ActiveEventSet(*sit))) {
349  rErrStSet.Insert(*sit);
350  locErrStSet.Insert(*sit);
351  finalResult = false;
352  localResult = false;
353  }
354  }
355 
356  if(localResult) rReportStr.append("##### Condition (viii) passed.\n");
357  else {
358  rReportStr.append("##### fail: found QUe-states with inactive UE-events:\n");
359  rReportStr.append(locErrStSet.ToString()+"\n");
360  locErrStSet.Clear();
361  rReportStr.append("##### Condition (viii) failed.\n");
362  }
363  rReportStr.append("#####\n");
364  /*************************** Condition (vii) finished ***************************/
365 
366  //###### Condition ix is outdated since we introduced marking!!!
367  // /*************************** Condition (ix) ***********************/
368  // localResult = true;
369  // rReportStr.append("########## Condition (ix):\n");
370 
371  // // Qm==Q?
372  // if(!(accessibleStates<=rHioPlant.MarkedStates())) {
373  // finalResult = false;
374  // localResult = false;
375  // }
376 
377  // if(localResult) rReportStr.append("##### Condition (ix) passed.\n");
378  // else {
379  // rReportStr.append("##### fail: not all accessible states are marked:\n");
380  // locErrStSet = accessibleStates - rHioPlant.MarkedStates();
381  // rErrStSet.InsertSet(locErrStSet);
382  // rReportStr.append(locErrStSet.ToString()+"\n");
383  // locErrStSet.Clear();
384  // rReportStr.append("##### Condition (ix) failed.\n");
385  // }
386  // rReportStr.append("#####\n");
387  // /*************************** Condition (ix) finished ****************************/
388 
389 
390  /*************************** Condition (x) ************************/
391  rReportStr.append("########## Condition (x):\n");
392 
393  // make accessible if necessary
394  if(!rHioPlant.IsAccessible()) {
395  rHioPlant.Accessible();
396  rReportStr.append("##### warning: non-accessible states have been removed.\n");
397  rReportStr.append("##### Condition (x) repaired.\n");
398  }
399  else rReportStr.append("##### Condition (x) passed.\n");
400  /*************************** Condition (x) finished *****************************/
401 
402 
403 
404  /*************************** Final Result ************************/
405 
406  rReportStr.append("##################### Final result: #####################\n");
407  if(finalResult) {
408  rReportStr.append("############## Generator is in HioPlantForm. ##############\n");
409  rReportStr.append("#########################################################\n");
410  return true;
411  }
412  else {
413  rReportStr.append("############ Generator is NOT in HioPlantForm. ###########\n");
414  rReportStr.append("#########################################################\n");
415  return false;
416  }
417 
418 }// END OF IsHioPlantForm()
419 
420 
421 //IsHioPlantForm wrapper functions
422 bool IsHioPlantForm(HioPlant& rHioPlant, std::string& rReportStr)
423 {
424  StateSet QYpYe, QUp, QUe;
425  EventSet ErrEvSet;
426  TransSet ErrTrSet;
427  StateSet ErrStSet;
428 
429  return IsHioPlantForm(rHioPlant, QYpYe, QUp, QUe, ErrEvSet, ErrTrSet, ErrStSet,rReportStr);
430 }
431 
432 // rti function interface
433 bool IsHioPlantForm(HioPlant& rHioPlant)
434 {
435  StateSet QYpYe, QUp, QUe;
436  EventSet ErrEvSet;
437  TransSet ErrTrSet;
438  StateSet ErrStSet;
439  std::string ReportStr;
440 
441  return IsHioPlantForm(rHioPlant, QYpYe, QUp, QUe, ErrEvSet, ErrTrSet, ErrStSet,ReportStr);
442 }
443 
444 // rti function interface
445 void HioStatePartition(HioPlant& rHioPlant) {
446  IsHioPlantForm(rHioPlant);
447 }
448 
449 } // 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
bool IsUp(Idx index) const
Is event Up-event(by index)
Definition: hio_plant.h:1095
void SetQYpYe(Idx index)
Mark state as QYpYe-state (by index)
Definition: hio_plant.h:1317
EventSet EEvents(void) const
Get EventSet with E-events.
Definition: hio_plant.h:1300
bool IsUe(Idx index) const
Is event Ue-event (by index)
Definition: hio_plant.h:1229
bool IsY(Idx index) const
Is event Y-event? (by index)
Definition: hio_plant.h:949
void SetQUe(Idx index)
Mark state as QUe-state (by index)
Definition: hio_plant.h:1480
EventSet UeEvents(void) const
Get EventSet with Ue-events.
Definition: hio_plant.h:1252
EventSet UpEvents(void) const
Get EventSet with Up-events.
Definition: hio_plant.h:1118
bool IsYp(Idx index) const
Is event Yp-event(by index)
Definition: hio_plant.h:1083
EventSet PEvents(void) const
Get EventSet with P-events.
Definition: hio_plant.h:1289
void SetQUp(Idx index)
Mark state as QUp-state (by index)
Definition: hio_plant.h:1398
EventSet YpEvents(void) const
Get EventSet with Yp-events.
Definition: hio_plant.h:1107
EventSet YeEvents(void) const
Get EventSet with Ye-events.
Definition: hio_plant.h:1241
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
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-plant attributes.
libFAUDES resides within the namespace faudes.
void HioStatePartition(HioConstraint &rHioConstraint)
Function definition for run-time interface.
bool IsHioPlantForm(HioPlant &rHioPlant, StateSet &rQYpYe, StateSet &rQUp, StateSet &rQUe, EventSet &rErrEvSet, TransSet &rErrTrSet, StateSet &rErrStSet, std::string &rReportStr)
IsHioPlantForm: check if rHioPlant is in I/O-plant form and assign state attributes.
Definition: hio_plant.cpp:16

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