diag_modulardiagnosis.cppGo 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 |