diag_modulardiagnosis.cpp

Go to the documentation of this file.
00001 /** @file diag_modulardiagnosis.cpp Functions to test modular diagnosability and compute modular diagnosers.
00002 */
00003 
00004 /*
00005 
00006 Copyright Tobias Barthel, Klaus Schmidt, Thomas Moor
00007 
00008 */
00009 
00010 #include "diag_modulardiagnosis.h"
00011 
00012 
00013 using namespace std;
00014 
00015 namespace faudes {
00016 
00017 ///////////////////////////////////////////////////////////////////////////////
00018 // Functions for modular diagnosability
00019 ///////////////////////////////////////////////////////////////////////////////
00020 
00021 
00022 // IsModularDiagnosable(): RTI wrapper
00023 bool IsModularDiagnosable(const SystemVector& rGsubs, const GeneratorVector& rKsubs, string& rReportString) {
00024   FD_DD("IsModularDiagnosable()");
00025 
00026   // if the vectors have different size, the input is invalid
00027   if(rGsubs.Size() != rKsubs.Size() ){
00028     stringstream errstr;
00029     errstr << "Number of specifications (" << rKsubs.Size() << ") does not equal number of subsystems ("<< rGsubs.Size() << ")" << endl;
00030     throw Exception("IsModularDiagnosable()", errstr.str(), 304); 
00031   }
00032   
00033   // reorganize as std vector
00034   std::vector<const System*> gen;
00035   std::vector<const Generator*> spec;
00036   Idx i; 
00037 
00038   for(i = 0; i < rGsubs.Size(); ++i) 
00039     gen.push_back(&rGsubs.At(i));
00040   for(i = 0; i < rKsubs.Size(); ++i)
00041     spec.push_back(&rKsubs.At(i));
00042   
00043   // invoke function
00044   return IsModularDiagnosable(gen, spec, rReportString);
00045 }
00046 
00047 
00048 
00049 // IsModularDiagnosable()
00050 bool IsModularDiagnosable(const vector< const System* >& rGSubs, const vector< const Generator* >& rKSubs, std::string& rReportString) {
00051   
00052   FD_DD("IsModularDiagnosable()");
00053   
00054   // clear report
00055   rReportString.clear();
00056   // verify dimensions  
00057   if(rGSubs.size() != rKSubs.size()) {
00058     stringstream errstr;
00059     errstr << "Number of specifications (" << rKSubs.size() << ") does not equal number of subsystems ("<< rGSubs.size() << ")" << endl;
00060     throw Exception("IsModularDiagnosable()", errstr.str(), 304);
00061   }
00062   // assemble shared events
00063   EventSet sigmaCup;
00064   EventSet sigmaCap;
00065   vector<EventSet> sigmaiCapVector;
00066   for(unsigned int i = 0; i < rGSubs.size(); ++i) // alphabet union
00067     sigmaCup.InsertSet(rGSubs.at(i)->Alphabet());
00068 
00069   FD_DD("all events: " + sigmaCup.ToString());
00070   for(EventSet::Iterator eit=sigmaCup.Begin(); eit!=sigmaCup.End(); eit++) { // overall shared events
00071     int cnt=0;
00072     for(unsigned int i = 0; i < rGSubs.size(); ++i) {
00073       if(rGSubs.at(i)->ExistsEvent(*eit)) 
00074   cnt++;
00075       if(cnt>1){ 
00076   sigmaCap.Insert(*eit); 
00077   break;
00078       }
00079     }
00080   }
00081   sigmaCup.Name("Sigma_cup");
00082   sigmaCap.Name("Sigma_cap");
00083   FD_DD("Shared Events: " << sigmaCap.ToString());
00084   // shared events per component
00085   for(unsigned int i = 0; i < rGSubs.size(); ++i)
00086     sigmaiCapVector.push_back(sigmaCap * rGSubs.at(i)->Alphabet() );
00087   
00088   // Compute abstraction alphabet for each component such that loop-preserving observer is fulfilled
00089   vector<EventSet> sigmaAbstVector;
00090   vector<System> genAbstVector;
00091   EventSet sigmaAbst;
00092   for(Idx i = 0; i < rGSubs.size(); ++i){
00093     sigmaAbstVector.push_back(EventSet() );
00094     LoopPreservingObserver(*rGSubs.at(i), sigmaiCapVector.at(i), sigmaAbstVector[i]);
00095     sigmaAbst = sigmaAbst + sigmaAbstVector.at(i); // overall abstraction alphabet
00096     // Compute the abstraction of each subsystem
00097     genAbstVector.push_back(System() );
00098     Project(*rGSubs.at(i),sigmaAbstVector.at(i),genAbstVector[i]);
00099     FD_DD("AbstractionAlphabet of Automaton " + ToStringInteger(i) + " " + sigmaAbstVector.at(i).ToString());
00100   }
00101   // Verify modular diagnosability for each subsystem
00102   EventSet obsEvents;
00103   System plant, plantAbst, spec;
00104   cParallel(genAbstVector,plantAbst); // abstracted plant
00105   bool diagnosable = true;
00106   for(unsigned int i = 0; i < rGSubs.size(); ++i){  
00107     plant.Clear();
00108     Parallel(*rGSubs.at(i),plantAbst,plant); // plant for verification
00109     Parallel(plant,*rKSubs.at(i),spec);
00110     plant.ClrObservable(plant.Alphabet() ); 
00111     plant.SetObservable(rGSubs.at(i)->ObservableEvents() ); // only observable events of the subsystem are observable
00112     std::string reportString;
00113     if(IsLanguageDiagnosable(plant,spec,reportString) == false ){
00114       FD_DD("Plant " + ToStringInteger(i) + " fails");
00115       diagnosable = false;
00116       rReportString += "Subsystem " + ToStringInteger(i) + " fails ";
00117     }
00118     else{
00119       FD_DD("Plant " + ToStringInteger(i) + " works");
00120       rReportString += "Subsystem " + ToStringInteger(i) + " works ";
00121     }
00122   }
00123   return diagnosable;
00124 }
00125 
00126 
00127 // IsModularDiagnosable(): RTI wrapper
00128 bool ModularDiagnoser(const SystemVector& rGsubs, const GeneratorVector& rKsubs, GeneratorVector& rDiagSubs, string& rReportString) {
00129   FD_DD("ModularDiagnoser");
00130 
00131   // if the vectors have different size, the input is invalid
00132   if(rGsubs.Size() != rKsubs.Size() ){
00133     stringstream errstr;
00134     errstr << "Number of specifications (" << rKsubs.Size() << ") does not equal number of subsystems ("<< rGsubs.Size() << ")" << endl;
00135     throw Exception("ModularDiagnoser()", errstr.str(), 304); 
00136   }
00137 
00138 
00139   // reorganize as std vector
00140   std::vector<const System*> gen;
00141   std::vector<const Generator*> spec;
00142   Idx i; 
00143   for(i = 0; i < rGsubs.Size(); ++i) 
00144     gen.push_back(&rGsubs.At(i));
00145   for(i = 0; i < rKsubs.Size(); ++i)
00146     spec.push_back(&rKsubs.At(i));
00147   
00148   // prepare result
00149   std::vector<Diagnoser*> diag;
00150 
00151   // invoke function
00152   bool diagnosable = ModularDiagnoser(gen, spec, diag, rReportString);
00153 
00154   // retrieve result (no copy, using explicit reference)
00155   for(i = 0; i < diag.size(); i++)
00156     rDiagSubs.Append(diag.at(i) );
00157   rDiagSubs.TakeOwnership();
00158 
00159   // done
00160   return diagnosable;
00161 }
00162 
00163 
00164 // ModularDiagnoser(rGsubs, rKsubs, rDiagsubs, rReportString)
00165 bool ModularDiagnoser(const std::vector< const System* >& rGSubs, const std::vector< const Generator* >& rKSubs, std::vector<Diagnoser*>& rDiagSubs, std::string& rReportString){
00166   
00167   FD_DD("ModularDiagnoser()");
00168   
00169   // clear report
00170   rReportString.clear();
00171 
00172   // verify dimensions  
00173   if(rGSubs.size() != rKSubs.size()) {
00174     stringstream errstr;
00175     errstr << "Number of specifications (" << rKSubs.size() << ") does not equal number of subsystems ("<< rGSubs.size() << ")" << endl;
00176     throw Exception("ModularDiagnoser()", errstr.str(), 304);
00177   }
00178 
00179   // assemble shared events
00180   EventSet sigmaCup;
00181   EventSet sigmaCap;
00182   vector<EventSet> sigmaiCapVector;
00183   for(unsigned int i = 0; i < rGSubs.size(); ++i) // alphabet union
00184     sigmaCup.InsertSet(rGSubs.at(i)->Alphabet());
00185 
00186   FD_DD("all events: " + sigmaCup.ToString());
00187   for(EventSet::Iterator eit=sigmaCup.Begin(); eit!=sigmaCup.End(); eit++) { // overall shared events
00188     int cnt=0;
00189     for(unsigned int i = 0; i < rGSubs.size(); ++i) {
00190       if(rGSubs.at(i)->ExistsEvent(*eit)) 
00191   cnt++;
00192       if(cnt>1){ 
00193   sigmaCap.Insert(*eit); 
00194   break;
00195       }
00196     }
00197   }
00198   sigmaCup.Name("Sigma_cup");
00199   sigmaCap.Name("Sigma_cap");
00200   FD_DD("Shared Events: " << sigmaCap.ToString());
00201   // shared events per component
00202   for(unsigned int i = 0; i < rGSubs.size(); ++i)
00203     sigmaiCapVector.push_back(sigmaCap * rGSubs.at(i)->Alphabet() );
00204   
00205   // Compute abstraction alphabet for each component such that loop-preserving observer is fulfilled
00206   vector<EventSet> sigmaAbstVector;
00207   vector<System> genAbstVector;
00208   EventSet sigmaAbst;
00209   for(Idx i = 0; i < rGSubs.size(); ++i){
00210     sigmaAbstVector.push_back(EventSet() );
00211     LoopPreservingObserver(*rGSubs.at(i), sigmaiCapVector.at(i), sigmaAbstVector[i]);
00212     sigmaAbst = sigmaAbst + sigmaAbstVector.at(i); // overall abstraction alphabet
00213     // Compute the abstraction of each subsystem
00214     genAbstVector.push_back(System() );
00215     Project(*rGSubs.at(i),sigmaAbstVector.at(i),genAbstVector[i]);
00216     FD_DD("AbstractionAlphabet of Automaton " + ToStringInteger(i) + " " + sigmaAbstVector.at(i).ToString());
00217   }
00218   // Verify modular diagnosability for each subsystem
00219   EventSet obsEvents;
00220   System plant, plantAbst, spec;
00221   cParallel(genAbstVector,plantAbst); // abstracted plant
00222   bool diagnosable = true;
00223   for(unsigned int i = 0; i < rGSubs.size(); ++i){  
00224     plant.Clear();
00225     Parallel(*rGSubs.at(i),plantAbst,plant); // plant for verification
00226     Parallel(plant,*rKSubs.at(i),spec);
00227     plant.ClrObservable(plant.Alphabet() ); 
00228     plant.SetObservable(rGSubs.at(i)->ObservableEvents() ); // only observable events of the subsystem are observable
00229     std::string reportString;
00230     rDiagSubs.push_back( new Diagnoser() );
00231 
00232     if(IsLanguageDiagnosable(plant,spec,reportString) == false ){
00233       FD_DD("Plant " + ToStringInteger(i) + " fails");
00234       diagnosable = false;
00235       rReportString += "Subsystem " + ToStringInteger(i) + " fails ";
00236     }
00237     else{
00238       FD_DD("Plant " + ToStringInteger(i) + " works");
00239       LanguageDiagnoser(plant,spec,*rDiagSubs[i]);
00240       rReportString += "Subsystem " + ToStringInteger(i) + " works ";
00241 
00242     }
00243   }
00244   return diagnosable;
00245 }
00246 
00247 ///////////////////////////////////////////////////////////////////////////////
00248 // RTI wrapper
00249 ///////////////////////////////////////////////////////////////////////////////
00250 
00251 // IsModularDiagnosable()
00252 bool IsModularDiagnosable(const SystemVector& rGsubs, const GeneratorVector& rKsubs) {
00253   std::string ignore;
00254   return IsModularDiagnosable(rGsubs, rKsubs, ignore);
00255 }
00256 
00257 
00258 
00259 // ModularDiagnoser()
00260 bool ModularDiagnoser(const SystemVector& rGsubs, const GeneratorVector& rKsubs, GeneratorVector& rDiagsubs) {
00261   std::string ignore;
00262   return ModularDiagnoser(rGsubs, rKsubs, rDiagsubs, ignore);
00263 }
00264 
00265 ///////////////////////////////////////////////////////////////////////////////
00266 // Auxiliary Functions  
00267 ///////////////////////////////////////////////////////////////////////////////
00268 
00269 // cParallel()
00270 void cParallel(const vector<System>& rGens, System& rResGen) {
00271   unsigned int i = 0;
00272   rResGen.Clear();
00273   if (rGens.size() == 0) return;
00274   rResGen = rGens.at(0);
00275   
00276   for (i = 1; i < rGens.size(); ++i) {
00277     aParallel(rResGen,rGens.at(i),rResGen);  
00278   }  
00279 }
00280 
00281 
00282 } // namespace faudes

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen