hio_plant.cpp

Go 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