hio_plant.cppGo to the documentation of this file.00001 /** @file hio_plant.cpp Generator with I/O-plant attributes */ 00002 00003 /* Hierarchical IO Systems Plug-In for FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2006 Sebastian Perk 00006 Copyright (C) 2006 Thomas Moor 00007 Copyright (C) 2006 Klaus Schmidt 00008 00009 */ 00010 00011 #include "hio_plant.h" 00012 00013 namespace faudes { 00014 00015 // IsHioPlantForm() 00016 bool IsHioPlantForm(HioPlant& rHioPlant, 00017 StateSet& rQYpYe, 00018 StateSet& rQUp, 00019 StateSet& rQUe, 00020 EventSet& rErrEvSet, 00021 TransSet& rErrTrSet, 00022 StateSet& rErrStSet, 00023 std::string& rReportStr) 00024 { 00025 FD_DF("IsHioPlantForm("<< rHioPlant.Name() << ",...)"); 00026 00027 // prepare results 00028 rQYpYe.Clear(); 00029 rQUp.Clear(); 00030 rQUe.Clear(); 00031 00032 rErrEvSet.Clear(); 00033 rErrEvSet.Name("rErrEvSet"); 00034 00035 rErrTrSet.Clear(); 00036 rErrTrSet.Name("rErrTrSet"); 00037 00038 rErrStSet.Clear(); 00039 rErrStSet.Name("rErrStSet"); 00040 00041 // used to locally store error states/transitions on each condition 00042 StateSet locErrStSet; 00043 TransSet locErrTrSet; 00044 00045 rReportStr.clear(); 00046 00047 // meant to be set false on violation of any condition: 00048 bool finalResult = true; 00049 // used to locally store result on each condition 00050 bool localResult = true; 00051 00052 // helpers 00053 00054 EventSet yp = rHioPlant.YpEvents(); 00055 EventSet up = rHioPlant.UpEvents(); 00056 EventSet ye = rHioPlant.YeEvents(); 00057 EventSet ue = rHioPlant.UeEvents(); 00058 00059 StateSet initStates = rHioPlant.InitStates(); 00060 StateSet accessibleStates = rHioPlant.AccessibleSet(); 00061 00062 EventSet::Iterator evit; 00063 StateSet::Iterator sit; 00064 TransSet::Iterator tit; 00065 00066 // Info string header 00067 rReportStr.append("#########################################################\n"); 00068 rReportStr.append("########## IsHioPlantForm("+rHioPlant.Name()+",...) - test results:\n"); 00069 00070 /**************************** Precondition: determinism ***********************/ 00071 // HioPlant must be deterministic 00072 if(!rHioPlant.IsDeterministic()){ 00073 rReportStr.append("##### fail: generator is not deterministic!\n"); 00074 if(initStates.Size()>1) { 00075 rErrStSet = initStates; 00076 rReportStr.append("##### (amongst others, there is more than one initial state)\n"); 00077 } 00078 finalResult = false; 00079 } 00080 00081 rReportStr.append("#####\n"); 00082 00083 // test all conditions verifying I/O-plant form: 00084 00085 /**************************** Condition (i) ***********************/ 00086 localResult = true; 00087 rReportStr.append("########## Condition (i):\n"); 00088 00089 //YP, UP, YE, UE nonempty? 00090 if (yp.Empty()) { 00091 rReportStr.append("##### fail: empty YP alphabet.\n"); 00092 localResult=false; 00093 finalResult = false; 00094 } 00095 if (up.Empty()) { 00096 rReportStr.append("##### fail: empty UP alphabet.\n"); 00097 localResult=false; 00098 finalResult = false; 00099 } 00100 if (ye.Empty()) { 00101 rReportStr.append("##### fail: empty YE alphabet.\n"); 00102 localResult=false; 00103 finalResult = false; 00104 } 00105 if (ue.Empty()) { 00106 rReportStr.append("##### fail: empty UE alphabet.\n"); 00107 localResult=false; 00108 finalResult = false; 00109 } 00110 00111 // check for disjoint eventsets YP, YE, UP, UE and for 00112 // YP u YE u UP u UE == Sigma, ie unique HioEventFlags. 00113 // note: testing disjoint P- and E-Alphabet is sufficient 00114 // as properties U and Y are exclusive by construction. 00115 00116 rErrEvSet=(rHioPlant.PEvents()*rHioPlant.EEvents()) + (rHioPlant.Alphabet()-rHioPlant.PEvents()-rHioPlant.EEvents()); 00117 00118 // In case of failing condition (i) further inspection is omitted, as too many consecutive faults are expected. 00119 if(!rErrEvSet.Empty()){ 00120 rReportStr.append("##### fail: found events with missing or ambiguous attribute, see rErrEvSet:\n"); 00121 rReportStr.append(rErrEvSet.ToString()+"\n"); 00122 rReportStr.append("##### Condition (i) failed.\n"); 00123 rReportStr.append("########## Termination due to crucial failure. ##########\n"); 00124 rReportStr.append("#########################################################\n"); 00125 return false; 00126 } 00127 if(localResult) rReportStr.append("##### Condition (i) passed.\n"); 00128 else rReportStr.append("##### Condition (i) failed.\n"); 00129 rReportStr.append("#####\n"); 00130 /*************************** Condition (i) finished *****************************/ 00131 00132 00133 /*************************** Condition (ii) ***********************/ 00134 localResult = true; 00135 rReportStr.append("########## Condition (ii):\n"); 00136 00137 // check if in states QYpYe, QUp and QUe only Y-, UP- and UE-events are active, respectively. 00138 for(sit = accessibleStates.Begin(); sit != accessibleStates.End(); ++sit) { 00139 00140 bool isY = false; 00141 bool isUp = false; 00142 bool isUe = false; 00143 bool goodState = true; 00144 00145 EventSet activeEv = rHioPlant.ActiveEventSet(*sit); 00146 00147 if(activeEv.Empty()) { 00148 //deadlocks are always QYpYe -states 00149 rQYpYe.Insert(*sit); 00150 rHioPlant.SetQYpYe(*sit); 00151 } 00152 else { 00153 00154 // get attribute of first event and compare with remaining events 00155 evit = activeEv.Begin(); 00156 isY = rHioPlant.IsY(*evit); 00157 isUp = rHioPlant.IsUp(*evit); 00158 isUe = rHioPlant.IsUe(*evit); 00159 00160 for(; evit != activeEv.End(); evit++) { 00161 if( (isY && !rHioPlant.IsY(*evit)) || 00162 (isUp && !rHioPlant.IsUp(*evit)) || 00163 (isUe && !rHioPlant.IsUe(*evit)) ) { 00164 goodState = false; 00165 localResult = false; 00166 finalResult = false; 00167 // add state to error set, go to next state 00168 locErrStSet.Insert(*sit); 00169 rErrStSet.Insert(*sit); 00170 break; // leave loop over active events 00171 } 00172 } 00173 00174 activeEv.Clear(); 00175 00176 if(!goodState) continue; // if undecidable go on with next state 00177 00178 // set state attribute 00179 if(isY) { 00180 rQYpYe.Insert(*sit); 00181 rHioPlant.SetQYpYe(*sit); 00182 } 00183 else if(isUp) { 00184 rQUp.Insert(*sit); 00185 rHioPlant.SetQUp(*sit); 00186 } 00187 else if(isUe){ 00188 rQUe.Insert(*sit); 00189 rHioPlant.SetQUe(*sit); 00190 } 00191 } 00192 } 00193 00194 if(localResult) rReportStr.append("##### Condition (ii) passed.\n"); 00195 // In case of failing condition (ii) further inspection is omitted, as too many consecutive faults are expected. 00196 else { 00197 rReportStr.append("##### fail: found states with undecidable attribute:\n"); 00198 rReportStr.append(locErrStSet.ToString()+"\n"); 00199 locErrStSet.Clear(); 00200 rReportStr.append("##### Condition (ii) failed.\n"); 00201 rReportStr.append("########## Termination due to crucial failure. ##########\n"); 00202 rReportStr.append("###################### No success. ######################\n"); 00203 rReportStr.append("#########################################################\n"); 00204 return false; 00205 } 00206 rReportStr.append("#####\n"); 00207 /*************************** Condition (ii) finished ****************************/ 00208 00209 00210 /*************************** Condition (iii) **********************/ 00211 localResult = true; 00212 rReportStr.append("########## Condition (iii):\n"); 00213 00214 //check if the initial state is a QYpYe-state 00215 if(!(initStates <= rQYpYe)) { 00216 rReportStr.append("##### fail: some init state(s) is (are) not a QYpYe-state:\n"); 00217 locErrStSet=initStates-rQYpYe; 00218 rErrStSet.SetUnion(locErrStSet); 00219 rReportStr.append(locErrStSet.ToString()+"\n"); 00220 locErrStSet.Clear(); 00221 localResult = false; 00222 finalResult = false; 00223 } 00224 if(localResult) rReportStr.append("##### Condition (iii) passed.\n"); 00225 else rReportStr.append("##### Condition (iii) failed.\n"); 00226 rReportStr.append("#####\n"); 00227 00228 /*************************** Condition (iii) finished ***************************/ 00229 00230 00231 /*************************** Condition (iv) ***********************/ 00232 localResult = true; 00233 rReportStr.append("########## Condition (iv):\n"); 00234 00235 // YP-events have to lead to a QUp-state, while a YE-events 00236 // have to lead to a QUe-state. 00237 for(sit = rQYpYe.Begin(); sit != rQYpYe.End(); ++sit) { 00238 for(tit = rHioPlant.TransRelBegin(*sit); tit != rHioPlant.TransRelEnd(*sit); ++tit) { 00239 // YP-event to QUp-state, YE-event to QUe-state 00240 if( (rHioPlant.IsYp(tit->Ev) && !(rQUp.Exists(tit->X2) || rQUe.Exists(tit->X2)))) { 00241 // add transition to error transition set 00242 rErrTrSet.Insert(*tit); 00243 locErrTrSet.Insert(*tit); 00244 finalResult = false; 00245 localResult = false; 00246 } 00247 } 00248 } 00249 00250 if(localResult) rReportStr.append("##### Condition (iv) passed.\n"); 00251 else { 00252 rReportStr.append("##### fail: found YP- or YE-transitions leading to wrong states:\n"); 00253 rReportStr.append(locErrTrSet.ToString()+"\n"); 00254 locErrTrSet.Clear(); 00255 rReportStr.append("##### Condition (iv) failed.\n"); 00256 } 00257 rReportStr.append("#####\n"); 00258 /*************************** Condition (iv) finished ****************************/ 00259 00260 00261 /*************************** Condition (v) ************************/ 00262 localResult = true; 00263 rReportStr.append("########## Condition (v):\n"); 00264 00265 // UP-events have to lead to a QYpYe-state 00266 for(sit = rQUp.Begin(); sit != rQUp.End(); ++sit) { 00267 for(tit = rHioPlant.TransRelBegin(*sit); tit != rHioPlant.TransRelEnd(*sit); ++tit) { 00268 if(!rQYpYe.Exists(tit->X2)) { 00269 rErrTrSet.Insert(*tit); 00270 locErrTrSet.Insert(*tit); 00271 finalResult = false; 00272 localResult = false; 00273 } 00274 } 00275 } 00276 00277 if(localResult) rReportStr.append("##### Condition (v) passed.\n"); 00278 else { 00279 rReportStr.append("##### fail: found UP-transitions leading to wrong states:\n"); 00280 rReportStr.append(locErrTrSet.ToString()+"\n"); 00281 locErrTrSet.Clear(); 00282 rReportStr.append("##### Condition (v) failed.\n"); 00283 } 00284 rReportStr.append("#####\n"); 00285 /*************************** Condition (v) finished *****************************/ 00286 00287 00288 /*************************** Condition (vi) ***********************/ 00289 localResult = true; 00290 rReportStr.append("########## Condition (vi):\n"); 00291 00292 // UE-events have to lead to a QYpYe-state 00293 for(sit = rQUe.Begin(); sit != rQUe.End(); ++sit) { 00294 for(tit = rHioPlant.TransRelBegin(*sit); tit != rHioPlant.TransRelEnd(*sit); ++tit) { 00295 if(!rQYpYe.Exists(tit->X2)) { 00296 rErrTrSet.Insert(*tit); 00297 locErrTrSet.Insert(*tit); 00298 finalResult = false; 00299 localResult = false; 00300 } 00301 } 00302 } 00303 00304 if(localResult) rReportStr.append("##### Condition (vi) passed.\n"); 00305 else { 00306 rReportStr.append("##### fail: found UE-transitions leading to wrong states:\n"); 00307 rReportStr.append(locErrTrSet.ToString()+"\n"); 00308 locErrTrSet.Clear(); 00309 rReportStr.append("##### Condition (vi) failed.\n"); 00310 } 00311 rReportStr.append("#####\n"); 00312 /*************************** Condition (vi) finished ****************************/ 00313 00314 00315 /*************************** Condition (vii) **********************/ 00316 localResult = true; 00317 rReportStr.append("########## Condition (vii):\n"); 00318 00319 // UP must be free in QUp-states 00320 for(sit = rQUp.Begin(); sit != rQUp.End(); ++sit) { 00321 00322 if(!(up <= rHioPlant.ActiveEventSet(*sit))) { 00323 rErrStSet.Insert(*sit); 00324 locErrStSet.Insert(*sit); 00325 finalResult = false; 00326 localResult = false; 00327 } 00328 } 00329 00330 if(localResult) rReportStr.append("##### Condition (vii) passed.\n"); 00331 else { 00332 rReportStr.append("##### fail: found QUp-states with inactive UP-events:\n"); 00333 rReportStr.append(locErrStSet.ToString()+"\n"); 00334 locErrStSet.Clear(); 00335 rReportStr.append("##### Condition (vii) failed.\n"); 00336 } 00337 rReportStr.append("#####\n"); 00338 /*************************** Condition (vii) finished ***************************/ 00339 00340 00341 /*************************** Condition (viii) **********************/ 00342 localResult = true; 00343 rReportStr.append("########## Condition (viii):\n"); 00344 00345 // UE must be free in QUe-states 00346 for(sit = rQUe.Begin(); sit != rQUe.End(); ++sit) { 00347 00348 if(!(ue <= rHioPlant.ActiveEventSet(*sit))) { 00349 rErrStSet.Insert(*sit); 00350 locErrStSet.Insert(*sit); 00351 finalResult = false; 00352 localResult = false; 00353 } 00354 } 00355 00356 if(localResult) rReportStr.append("##### Condition (viii) passed.\n"); 00357 else { 00358 rReportStr.append("##### fail: found QUe-states with inactive UE-events:\n"); 00359 rReportStr.append(locErrStSet.ToString()+"\n"); 00360 locErrStSet.Clear(); 00361 rReportStr.append("##### Condition (viii) failed.\n"); 00362 } 00363 rReportStr.append("#####\n"); 00364 /*************************** Condition (vii) finished ***************************/ 00365 00366 //###### Condition ix is outdated since we introduced marking!!! 00367 // /*************************** Condition (ix) ***********************/ 00368 // localResult = true; 00369 // rReportStr.append("########## Condition (ix):\n"); 00370 00371 // // Qm==Q? 00372 // if(!(accessibleStates<=rHioPlant.MarkedStates())) { 00373 // finalResult = false; 00374 // localResult = false; 00375 // } 00376 00377 // if(localResult) rReportStr.append("##### Condition (ix) passed.\n"); 00378 // else { 00379 // rReportStr.append("##### fail: not all accessible states are marked:\n"); 00380 // locErrStSet = accessibleStates - rHioPlant.MarkedStates(); 00381 // rErrStSet.SetUnion(locErrStSet); 00382 // rReportStr.append(locErrStSet.ToString()+"\n"); 00383 // locErrStSet.Clear(); 00384 // rReportStr.append("##### Condition (ix) failed.\n"); 00385 // } 00386 // rReportStr.append("#####\n"); 00387 // /*************************** Condition (ix) finished ****************************/ 00388 00389 00390 /*************************** Condition (x) ************************/ 00391 rReportStr.append("########## Condition (x):\n"); 00392 00393 // make accessible if necessary 00394 if(!rHioPlant.IsAccessible()) { 00395 rHioPlant.Accessible(); 00396 rReportStr.append("##### warning: non-accessible states have been removed.\n"); 00397 rReportStr.append("##### Condition (x) repaired.\n"); 00398 } 00399 else rReportStr.append("##### Condition (x) passed.\n"); 00400 /*************************** Condition (x) finished *****************************/ 00401 00402 00403 00404 /*************************** Final Result ************************/ 00405 00406 rReportStr.append("##################### Final result: #####################\n"); 00407 if(finalResult) { 00408 rReportStr.append("############## Generator is in HioPlantForm. ##############\n"); 00409 rReportStr.append("#########################################################\n"); 00410 return true; 00411 } 00412 else { 00413 rReportStr.append("############ Generator is NOT in HioPlantForm. ###########\n"); 00414 rReportStr.append("#########################################################\n"); 00415 return false; 00416 } 00417 00418 }// END OF IsHioPlantForm() 00419 00420 00421 //IsHioPlantForm wrapper functions 00422 bool IsHioPlantForm(HioPlant& rHioPlant, std::string& rReportStr) 00423 { 00424 StateSet QYpYe, QUp, QUe; 00425 EventSet ErrEvSet; 00426 TransSet ErrTrSet; 00427 StateSet ErrStSet; 00428 00429 return IsHioPlantForm(rHioPlant, QYpYe, QUp, QUe, ErrEvSet, ErrTrSet, ErrStSet,rReportStr); 00430 } 00431 00432 // rti function interface 00433 bool IsHioPlantForm(HioPlant& rHioPlant) 00434 { 00435 StateSet QYpYe, QUp, QUe; 00436 EventSet ErrEvSet; 00437 TransSet ErrTrSet; 00438 StateSet ErrStSet; 00439 std::string ReportStr; 00440 00441 return IsHioPlantForm(rHioPlant, QYpYe, QUp, QUe, ErrEvSet, ErrTrSet, ErrStSet,ReportStr); 00442 } 00443 00444 // rti function interface 00445 void HioStatePartition(HioPlant& rHioPlant) { 00446 IsHioPlantForm(rHioPlant); 00447 } 00448 00449 } // end namespace libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |