diag_eventdiagnosis.cppGo to the documentation of this file.00001 /** @file diag_eventdiagnosis.cpp 00002 Functions to check a system's event-diagnosability and computation of an event-diagnoser. Covers diagnosability with respect to failure events (diagnosability, I-diagnosability). 00003 */ 00004 00005 #include "diag_eventdiagnosis.h" 00006 00007 using namespace std; 00008 00009 namespace faudes { 00010 00011 00012 // IsEventDiagnosable() 00013 bool IsEventDiagnosable(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap, string& rReportString) { 00014 Diagnoser genGobs; 00015 System genGd; 00016 map<pair<Idx,Idx>,Idx> reverseCompositionMap; 00017 map<pair<Idx,Idx>,Idx>::iterator rcmIt; 00018 StateSet::Iterator stateIt; 00019 TaNameSet<AttributeFailureEvents>::Iterator ftIt; 00020 EventSet::Iterator evIt; 00021 00022 // reset report 00023 rReportString.clear(); 00024 00025 FD_DD("IsEventDiagnosable()"); 00026 // TODO: throw exception, dont report 00027 // check for indicator events (which should not exist) 00028 for (ftIt = rFailureTypeMap.mFailureTypeMap.Begin(); ftIt != rFailureTypeMap.mFailureTypeMap.End(); ftIt++) { 00029 if (!rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.Empty()) { 00030 FD_DD("IsEventDiagnosable(): Warning: Existing indicator events are ignored! If you want to check for I-diagnosability use IsIdiagnosable() instead."); 00031 rReportString.append("IsEventDiagnosable(): Warning: Existing indicator events are ignored! If you want to check for I-diagnosability use IsIdiagnosable() instead.\n"); 00032 break; 00033 } 00034 } 00035 00036 // check if assumptions are met 00037 // TODO: convention: "Check" rather than "Meet" 00038 if (!MeetsDiagnosabilityAssumptions(rGen, rFailureTypeMap, rReportString)) { 00039 return false; 00040 } 00041 00042 // Implementation of Remark 2: Applying Algorithm 1 for each failure type on its own 00043 for (ftIt = rFailureTypeMap.mFailureTypeMap.Begin(); ftIt != rFailureTypeMap.mFailureTypeMap.End(); ftIt++) { 00044 FD_DD("Testing for failure type " + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) \ 00045 + " with failures " + rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents.ToString()); 00046 00047 // 3 Steps of Algorithm 1 00048 // Step 1: Generate G_o 00049 FD_DD("__Step 1__"); 00050 ComputeGobs(rGen, rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt), rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents, genGobs); 00051 //genGobs.Write("tmp_Gobs_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen"); 00052 //genGobs.GraphWrite("tmp_Gobs_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png"); 00053 00054 // Step 2: Generate G_d = G_o || G_o 00055 // State names/attributes are not copied to new generator G_d 00056 // but can be obtained via reverse composition map and the corresponding elements of G_o 00057 FD_DD("__Step 2__"); 00058 ComputeGd(genGobs, reverseCompositionMap, genGd); 00059 //genGd.Write("tmp_Gd_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen"); 00060 //genGd.GraphWrite("tmp_Gd_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png"); 00061 00062 // Step 3: Check for cycles in G_d which contain states with different failure labels 00063 FD_DD("__Step 3__"); 00064 if(ExistsViolatingCyclesInGd(genGd, genGobs, reverseCompositionMap, rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt), rReportString)) { 00065 //genGd.Write("tmp_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen"); 00066 //genGd.GraphWrite("tmp_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png"); 00067 return false; 00068 } else { 00069 //genGd.Write("tmp_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen"); 00070 //genGd.GraphWrite("tmp_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png"); 00071 } 00072 00073 } 00074 return true; 00075 } 00076 00077 // rti function interface 00078 bool IsEventDiagnosable(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap) { 00079 std::string ignore; 00080 return IsEventDiagnosable(rGen,rFailureTypeMap,ignore); 00081 } 00082 00083 00084 // IsIdiagnosable() 00085 bool IsIndicatorEventDiagnosable(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap, string& rReportString) { 00086 Diagnoser genGobs; 00087 System genGd; 00088 map<pair<Idx,Idx>,Idx> reverseCompositionMap; 00089 map<pair<Idx,Idx>,Idx>::iterator rcmIt; 00090 StateSet::Iterator stateIt; 00091 TaNameSet<AttributeFailureEvents>::Iterator ftIt; 00092 EventSet::Iterator evIt; 00093 rReportString.clear(); 00094 00095 FD_DD("IsIndicatorEventDiagnosable()"); 00096 // check for indicator events (which should exist) 00097 for (ftIt = rFailureTypeMap.mFailureTypeMap.Begin(); ftIt != rFailureTypeMap.mFailureTypeMap.End(); ftIt++) { 00098 if (rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.Empty()) { 00099 FD_DD("IsIndicatorEventDiagnosable(): Warning: There are no indicator events for failure type " << rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) << "!"); 00100 rReportString.append("IsIndicatorEventDiagnosable(): Warning: There are no indicator events for failure type " + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + "!\n"); 00101 } 00102 } 00103 00104 // check if assumptions are met 00105 if (!MeetsDiagnosabilityAssumptions(rGen, rFailureTypeMap, rReportString)) { 00106 return false; 00107 } 00108 00109 // Implementation of Remark 2: Applying Algorithm 1 for each failure type on its own 00110 for (ftIt = rFailureTypeMap.mFailureTypeMap.Begin(); ftIt != rFailureTypeMap.mFailureTypeMap.End(); ftIt++) { 00111 FD_DD("Testing for failure type " + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) \ 00112 + " with failures/indicators " + rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).ToString()); 00113 00114 // 3 Steps of Algorithm 1 00115 // Step 1: Generate G_o 00116 FD_DD("__Step 1__"); 00117 ComputeGobs(rGen, rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt), rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents, genGobs); 00118 //genGobs.Write("tmp_I_Gobs_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen"); 00119 //genGobs.GraphWrite("tmp_I_Gobs_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png"); 00120 00121 // Step 2: Generate G_d = G_o || G_o 00122 // State names/attributes are not copied to new generator G_d 00123 // but can be obtained via reverse composition map and the corresponding elements of G_o 00124 FD_DD("__Step 2__"); 00125 ComputeGd(genGobs, reverseCompositionMap, genGd); 00126 //genGd.Write("tmp_I_Gd_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen"); 00127 //genGd.GraphWrite("tmp_I_Gd_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png"); 00128 00129 // Additionally for I-diagnosability: Remove all traces which do not contain a failure event followed by an indicator event 00130 FD_DD("Removing all traces not containing an indicator event " + rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.ToString()); 00131 TrimNonIndicatorTracesOfGd(genGd, genGobs, *ftIt, rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents, reverseCompositionMap); 00132 //genGd.Write("tmp_I_Gd_iTraces_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen"); 00133 //genGd.GraphWrite("tmp_I_Gd_iTraces_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png"); 00134 00135 // Step 3: Check for cycles in G_d which contain states with different failure labels 00136 FD_DD("__Step 3__"); 00137 if(ExistsViolatingCyclesInGd(genGd, genGobs, reverseCompositionMap, rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt), rReportString)) { 00138 //genGd.Write("tmp_I_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen"); 00139 //genGd.GraphWrite("tmp_I_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png"); 00140 return false; 00141 } else { 00142 //genGd.Write("tmp_I_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen"); 00143 //genGd.GraphWrite("tmp_I_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png"); 00144 } 00145 00146 } 00147 return true; 00148 } 00149 00150 00151 00152 // rti function interface 00153 bool IsIndicatorEventDiagnosable(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap) { 00154 std::string ignore; 00155 return IsEventDiagnosable(rGen,rFailureTypeMap,ignore); 00156 } 00157 00158 00159 // MeetsDiagnosabilityAssumptions() 00160 bool MeetsDiagnosabilityAssumptions(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap, string& rReportString) { 00161 TaNameSet<AttributeFailureEvents>::Iterator ftIt; 00162 EventSet::Iterator evIt; 00163 00164 // check if failure and indicator events are part of the generators alphabet 00165 for (ftIt = rFailureTypeMap.mFailureTypeMap.Begin(); ftIt != rFailureTypeMap.mFailureTypeMap.End(); ftIt++) { 00166 // check if all failures are valid events of generator 00167 for (evIt = rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents.Begin(); evIt != rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents.End(); evIt++) { 00168 if (!rGen.Alphabet().Exists(*evIt)) { 00169 stringstream errstr; 00170 errstr << "Failure " << rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents.SymbolicName(*evIt) << " is not in alphabet of generator!" << endl; 00171 throw Exception("MeetsDiagnosabilityAssumptions()", errstr.str(), 302); 00172 } 00173 } 00174 // check if all indicator events are valid events of generator 00175 for (evIt = rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.Begin(); evIt != rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.End(); evIt++) { 00176 if (!rGen.Alphabet().Exists(*evIt)) { 00177 stringstream errstr; 00178 errstr << "Indicator " << rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.SymbolicName(*evIt) << " is not in alphabet of generator!" << endl; 00179 throw Exception("MeetsDiagnosabilityAssumptions()", errstr.str(), 303); 00180 } 00181 } 00182 } 00183 00184 // Assumption A1: Liveness 00185 if (!IsLive(rGen, rReportString)) { 00186 FD_DD("MeetsDiagnosabilityAssumptions(): Generator is not live!"); 00187 rReportString.append("Generator is not live!\n"); 00188 return false; 00189 } 00190 00191 // Assumption A3: All failure events are unobservable 00192 if (!FailuresUnobservable(rGen, rFailureTypeMap, rReportString)) { 00193 FD_DD("MeetsDiagnosabilityAssumptions(): Not all failure events are unobservable!"); 00194 rReportString.append("Not all failure events are unobservable!\n"); 00195 return false; 00196 } 00197 00198 // Assumption A2: No cycles of unobservable events 00199 if (CycleOfUnobsEvents(rGen, rReportString)) { 00200 FD_DD("MeetsDiagnosabilityAssumptions(): Generator contains cycle of unobservable events!"); 00201 rReportString.append("Generator contains cycle of unobservable events!\n"); 00202 return false; 00203 } 00204 00205 // otherwise 00206 return true; 00207 } 00208 00209 // ConvertParallelCompositionMap() 00210 void ConvertParallelCompositionMap( const map<pair<Idx,Idx>,Idx>& rReverseCompositionMap, 00211 map<Idx,pair<Idx,Idx> >& rCompositionMap) { 00212 // invert rReverseCompositionMap (possible, as map is expected to be from parallel composition 00213 // and thus must be bijective) 00214 map<pair<Idx,Idx>,Idx>::const_iterator iter; 00215 00216 FD_DD("ConvertParallelCompositionMap()"); 00217 rCompositionMap.clear(); 00218 for(iter = rReverseCompositionMap.begin(); iter != rReverseCompositionMap.end(); iter++) { 00219 rCompositionMap.insert(make_pair(iter->second,iter->first)); 00220 } 00221 } 00222 00223 // IsLive() 00224 // TODO: inefficient set of active vents; have method in Generator 00225 bool IsLive(const System& rGen, string& rReport) { 00226 StateSet states; 00227 StateSet::Iterator it; 00228 FD_DD("IsLive()"); 00229 states = rGen.States(); 00230 for (it = states.Begin(); it != states.End(); it++) { 00231 if (rGen.ActiveEventSet(*it).Empty()) { 00232 rReport.append("Missing transition at state " + ToStringInteger(*it) + " --> "); 00233 return false; 00234 } 00235 } 00236 return true; 00237 } 00238 00239 // CycleOfUnobsEvents() 00240 // TODO: inefficient copy; have method in Generator 00241 bool CycleOfUnobsEvents(const System& rGen, string& rReport) { 00242 TransSet transitionsToDelete; 00243 TransSet::Iterator it; 00244 System genCopy; 00245 00246 FD_DD("CycleOfUnobsEvents()"); 00247 transitionsToDelete.Clear(); 00248 // make a copy of generator 00249 genCopy = rGen; 00250 // parse through all its transitions and delete the observable ones 00251 for (it = genCopy.TransRelBegin(); it != genCopy.TransRelEnd(); it++) { 00252 if (genCopy.Observable(it->Ev)) { 00253 transitionsToDelete.Insert(*it); 00254 } 00255 } 00256 for (it = transitionsToDelete.Begin(); it != transitionsToDelete.End(); it++) { 00257 FD_DD("delete " << it->X1 << " --" << genCopy.EventName(it->Ev) << "--> " << it->X2); 00258 genCopy.ClrTransition(*it); 00259 } 00260 // check for cycles within the remaining unobservable events 00261 return ExistsCycle(genCopy, rReport); 00262 } 00263 00264 // FailuresUnobservable() 00265 bool FailuresUnobservable(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap, string& rReport) { 00266 EventSet failures, unobsEvents; 00267 EventSet::Iterator evIt; 00268 00269 FD_DD("FailuresUnobservable()"); 00270 failures = rFailureTypeMap.AllFailureEvents(); 00271 unobsEvents = rGen.UnobservableEvents(); 00272 for (evIt = failures.Begin(); evIt != failures.End(); evIt++) { 00273 if (!unobsEvents.Exists(*evIt)) { 00274 FD_DD("FailuresUnobservable(): Failure event \"" << failures.SymbolicName(*evIt) << "\" is not unobservable in generator!"); 00275 rReport.append("Failure event \"" + failures.SymbolicName(*evIt) + "\" is observable in generator --> "); 00276 return false; 00277 } 00278 } 00279 return true; 00280 } 00281 00282 // ExistsCycle() 00283 bool ExistsCycle(const System& rGen, string& rReport) { 00284 StateSet todo, path; 00285 StateSet::Iterator stateIt; 00286 00287 FD_DD("ExistsCycle()"); 00288 todo = rGen.States(); 00289 path.Clear(); 00290 for (stateIt = rGen.InitStatesBegin(); stateIt != rGen.InitStatesEnd(); ++stateIt) { 00291 FD_DD("Start cycle search at initial state"); 00292 if (ExistsCycleSearch(rGen, todo, *stateIt, path, rReport)) { 00293 return true; 00294 } 00295 } 00296 while (!todo.Empty()) { 00297 FD_DD("Start cycle search at some state.."); 00298 if (ExistsCycleSearch(rGen, todo, *todo.Begin(), path, rReport)) { 00299 return true; 00300 } 00301 } 00302 return false; 00303 } 00304 00305 // ExistsCycleSearch() 00306 bool ExistsCycleSearch(const System& rGen, StateSet& rTodo, Idx currState, StateSet statesOnPath, string& rReport) { 00307 StateSet successors, newStatesOnPath; 00308 StateSet::Iterator stateIt; 00309 00310 FD_DD("ExistsCycleSearch() for State " << currState); 00311 rTodo.Erase(currState); 00312 statesOnPath.Insert(currState); 00313 00314 successors = rGen.SuccessorStates(currState); 00315 // parse through active state set of currState 00316 for (stateIt = successors.Begin(); stateIt != successors.End(); stateIt++) { 00317 if (statesOnPath.Exists(*stateIt)) { 00318 FD_DD("Cycle found at state " << *stateIt); 00319 rReport.append("Cycle found at state " + ToStringInteger(*stateIt) + " --> "); 00320 return true; 00321 } 00322 // call ExistsCycleSearch() for next successor state and with updated state set newStatesOnPath 00323 newStatesOnPath.Clear(); 00324 newStatesOnPath.InsertSet(statesOnPath); 00325 newStatesOnPath.Insert(*stateIt); 00326 if (ExistsCycleSearch(rGen, rTodo, *stateIt, newStatesOnPath, rReport)) { 00327 return true; 00328 } 00329 } 00330 return false; 00331 } 00332 00333 // CycleStartStates() 00334 void CycleStartStates(const System& rGen, StateSet& rCycleOrigins) { 00335 StateSet todo, path; 00336 00337 FD_DD("ExistsCycle()"); 00338 rCycleOrigins.Clear(); 00339 todo = rGen.States(); 00340 if (!rGen.InitStatesEmpty()) { 00341 FD_DD("Start cycle search at initial state"); 00342 path.Clear(); 00343 CycleStartStatesSearch(rGen, todo, rGen.InitState(), path, rCycleOrigins); 00344 } 00345 while (!todo.Empty()) { 00346 FD_DD("Start cycle search at some state.."); 00347 path.Clear(); 00348 CycleStartStatesSearch(rGen, todo, *todo.Begin(), path, rCycleOrigins); 00349 } 00350 return; 00351 } 00352 00353 // CycleStartStatesSearch() 00354 void CycleStartStatesSearch(const System& rGen, StateSet& rTodo, Idx currState, StateSet statesOnPath, StateSet& rCycleOriginStates) { 00355 StateSet successors, newStatesOnPath; 00356 StateSet::Iterator stateIt; 00357 00358 FD_DD("CycleStartStatesSearch() for State " << currState); 00359 rTodo.Erase(currState); 00360 statesOnPath.Insert(currState); 00361 00362 successors = rGen.SuccessorStates(currState); 00363 // parse through active state set of currState 00364 for (stateIt = successors.Begin(); stateIt != successors.End(); stateIt++) { 00365 if (statesOnPath.Exists(*stateIt)) { 00366 FD_DD("Cycle found at state " << *stateIt); 00367 rCycleOriginStates.Insert(*stateIt); 00368 return; 00369 } 00370 // call ExistsCycleSearch() for next successor state and with updated state set newStatesOnPath 00371 newStatesOnPath.Clear(); 00372 newStatesOnPath.InsertSet(statesOnPath); 00373 newStatesOnPath.Insert(*stateIt); 00374 CycleStartStatesSearch(rGen, rTodo, *stateIt, newStatesOnPath, rCycleOriginStates); 00375 } 00376 return; 00377 } 00378 00379 // ExistsViolatingCyclesInGd() 00380 bool ExistsViolatingCyclesInGd(System& rGd, const Diagnoser& rGobs, map<pair<Idx,Idx>,Idx>& rReverseCompositionMap, const string& rFailureType, string& rReportString) { 00381 map<pair<Idx,Idx>,Idx>::iterator rcmIt; 00382 const TaIndexSet<DiagLabelSet>* fLabel1; 00383 const TaIndexSet<DiagLabelSet>* fLabel2; 00384 TaIndexSet<DiagLabelSet>::Iterator fL1Begin; 00385 TaIndexSet<DiagLabelSet>::Iterator fL2Begin; 00386 00387 FD_DD("ExistsViolatingCyclesInGd()"); 00388 // Therefore parse through reverse composition map 00389 for (rcmIt = rReverseCompositionMap.begin(); rcmIt != rReverseCompositionMap.end();) { 00390 FD_DD("state " << rcmIt->second << " (" << rcmIt->first.first << "," << rcmIt->first.second << ")"); 00391 // if both states in G_o are equal or just contain the same failure label: delete corresponding state in G_d 00392 if (rcmIt->first.first == rcmIt->first.second) { 00393 FD_DD(" --> delete (same G_o state)"); 00394 rGd.DelState(rcmIt->second); 00395 rReverseCompositionMap.erase(rcmIt++); 00396 } else { 00397 fLabel1 = rGobs.StateAttribute(rcmIt->first.first).DiagnoserStateMapp(); 00398 fLabel2 = rGobs.StateAttribute(rcmIt->first.second).DiagnoserStateMapp(); 00399 fL1Begin = fLabel1->Begin(); 00400 fL2Begin = fLabel2->Begin(); 00401 if (fLabel1->Attribute(*fL1Begin) == fLabel2->Attribute(*fL2Begin)) { 00402 FD_DD(" --> delete (same failure label)"); 00403 rGd.DelState(rcmIt->second); 00404 rReverseCompositionMap.erase(rcmIt++); 00405 } else { 00406 ++rcmIt; 00407 } 00408 } 00409 FD_DD(""); 00410 } 00411 // if there exists a cycle in the remainder graph the system rGen is not diagnosable 00412 if (ExistsCycle(rGd,rReportString)) { 00413 FD_DD("Detected cycle in G_d"); 00414 rReportString.append("While checking diagnosability for failure type " + rFailureType + ": " + \ 00415 "G_d contains a cycle of states with unequal failure labels, i.e. there exists an " + \ 00416 rFailureType + "-indeterminate cycle in the diagnoser.\n"); 00417 return true; 00418 } 00419 return false; 00420 } 00421 00422 // ComputeGobs() 00423 void ComputeGobs(const System& rOrigGen, const string& rFailureType, const EventSet& rFailureEvents, Diagnoser& rGobs) { 00424 AttributeFailureTypeMap singleFailureTypeMap; 00425 singleFailureTypeMap.Clear(); 00426 singleFailureTypeMap.AddFailureTypeMapping(rFailureType, rFailureEvents); 00427 ComputeGobs(rOrigGen, singleFailureTypeMap, rGobs); 00428 } 00429 00430 // ComputeGobs() 00431 void ComputeGobs(const System& rOrigGen, const AttributeFailureTypeMap& rAttrFTMap, Diagnoser& rGobs) { 00432 EventSet failureEvents; 00433 EventSet gObservableEvents, gUnobservableEvents; 00434 StateSet newGobsStates; 00435 Idx currDState = 0; 00436 Idx nextDState = 0; 00437 00438 FD_DD("ComputeGobs()"); 00439 // check if FailureTypeMap is empty 00440 if (rAttrFTMap.Empty()) { 00441 FD_DD("WARNING - ComputeGobs(): failure type map is empty!"); 00442 } 00443 00444 // clear Gobs 00445 rGobs.Clear(); 00446 rGobs.ClearAttributes(); 00447 00448 // copy attribute failure type map to Gobs 00449 rGobs.GlobalAttribute(rAttrFTMap); 00450 00451 // get observable events of original generator 00452 gObservableEvents = rOrigGen.ObservableEvents(); 00453 FD_DD("Observable events: " << gObservableEvents.ToString()); 00454 00455 // get unobservable events of original generator 00456 gUnobservableEvents = rOrigGen.UnobservableEvents(); 00457 FD_DD("Unobservable events: " << gUnobservableEvents.ToString()); 00458 00459 // copy all failure events into one single EventSet 00460 failureEvents = rGobs.GetAllFailureEvents(); 00461 FD_DD("Failure events: " << failureEvents.ToString()); 00462 00463 // create initial state of Gobs and its attribute with label "normal" 00464 #ifdef FAUDES_CHECKED 00465 if(rOrigGen.InitStatesSize() != 1) { 00466 std::stringstream errstr; 00467 errstr << "original generator has no unique initial state" << std::endl; 00468 throw Exception("ComputeGobs()", errstr.str(), 301); 00469 } 00470 #endif 00471 Idx gInitState = rOrigGen.InitState(); 00472 currDState = rGobs.InsInitState(); 00473 newGobsStates.Insert(currDState); 00474 rGobs.InsStateLabelMapping(currDState,gInitState,DiagLabelSet::IndexOfLabelN()); 00475 00476 Idx gStateEstimate = 0; 00477 Idx newState = 0; 00478 00479 map<Idx,multimap<Idx,DiagLabelSet> > reachMap; // maps executable events to all reachable states and occuring relative failure types 00480 map<Idx,multimap<Idx,DiagLabelSet> >::iterator it; 00481 00482 multimap<Idx,DiagLabelSet>::iterator mmit, mmit2; 00483 00484 pair<Idx,DiagLabelSet> reachMapPair; 00485 00486 TransSet transitions; 00487 DiagLabelSet oldLabel, newLabel, occFailureTypes; 00488 DiagLabelSet::Iterator labelIt; 00489 StateSet gObsStates; 00490 StateSet::Iterator stateIt; 00491 EventSet activeEvents; 00492 AttributeDiagnoserState newAttr; 00493 AttributeDiagnoserState currDStateAttr; 00494 TaIndexSet<DiagLabelSet> currDStateMap; 00495 TaIndexSet<DiagLabelSet>::Iterator currDStateMapIt; 00496 00497 // parse through new Gobs states 00498 while (!newGobsStates.Empty()) { 00499 // set current Gobs state 00500 currDState = *newGobsStates.Begin(); 00501 00502 currDStateAttr = rGobs.StateAttribute(currDState); 00503 currDStateMap = currDStateAttr.DiagnoserStateMap(); 00504 00505 // parse through state estimates of current Gobs state 00506 for(currDStateMapIt = currDStateMap.Begin(); currDStateMapIt != currDStateMap.End(); ++ currDStateMapIt){ 00507 gStateEstimate = *currDStateMapIt; 00508 00509 // generate reachMap for current state estimate 00510 ComputeReachability(rOrigGen, gUnobservableEvents, failureEvents, gStateEstimate, rAttrFTMap, reachMap); 00511 00512 #ifdef FAUDES_DEBUG_DIAGNOSIS 00513 FD_DD(endl << "reachMap: "); 00514 for (it = reachMap.begin(); it != reachMap.end(); it++) { 00515 //print reachMap for current event 00516 FD_DD("_" << rOrigGen.EventName(it->first) << " ("<< it->second.size() << " state estimates)"); 00517 for (mmit = it->second.begin(); mmit != it->second.end(); mmit++) { 00518 FD_DD(mmit->first << " " << mmit->second.ToString()); 00519 } 00520 } 00521 FD_DD(""); 00522 #endif 00523 00524 // parse through reachMap (eventwise) 00525 for (it = reachMap.begin(); it != reachMap.end(); it++) { 00526 //print reachMap for current event 00527 #ifdef FAUDES_DEBUG_DIAGNOSIS 00528 FD_DD(endl << "_" << rOrigGen.EventName(it->first) << " ("<< it->second.size() << " state estimates)"); 00529 for (mmit = it->second.begin(); mmit != it->second.end(); mmit++) { 00530 FD_DD(mmit->first << " " << mmit->second.ToString()); 00531 } 00532 #endif 00533 00534 // get label set of current state estimate 00535 oldLabel = currDStateMap.Attribute(*currDStateMapIt); 00536 FD_DD("old label: " << oldLabel.ToString()); 00537 00538 newState = 0; 00539 // parse through state failure type map (for current event in reachMap) 00540 for (mmit = it->second.begin(); mmit != it->second.end(); mmit++) { 00541 newState = mmit->first; 00542 FD_DD("new state: " << newState); 00543 occFailureTypes = mmit->second; 00544 FD_DD("failure types occurred: " << occFailureTypes.ToString()); 00545 LabelPropagation(oldLabel, occFailureTypes, newLabel); 00546 FD_DD("new label: " << newLabel.ToString()); 00547 newAttr.Clear(); 00548 newAttr.AddStateLabelMap(newState,newLabel); 00549 00550 // if newAttr equals any existing state attribute than we create a transition to this very state 00551 gObsStates = rGobs.States(); 00552 stateIt = gObsStates.Begin(); 00553 while (stateIt != gObsStates.End()) { 00554 if (newAttr == rGobs.StateAttribute(*stateIt)) { 00555 FD_DD("realising as back- or self-loop to existing state " << *stateIt); 00556 rGobs.InsEvent(it->first); 00557 rGobs.SetTransition(currDState,it->first,*stateIt); 00558 break; 00559 } 00560 stateIt++; 00561 } 00562 // if newAttribute is new to Gobs 00563 if (stateIt == gObsStates.End()) { 00564 // create new Gobs state and add it to new states 00565 nextDState = rGobs.InsState(); 00566 FD_DD("Create new state " << nextDState << " and transition " << currDState << " --" << rOrigGen.EventName(it->first) << "--> " << nextDState); 00567 newGobsStates.Insert(nextDState); 00568 rGobs.InsEvent(it->first); 00569 rGobs.SetTransition(currDState,it->first,nextDState); 00570 rGobs.StateAttribute(nextDState, newAttr); 00571 00572 FD_DD("Print Gobs label of state " << nextDState); 00573 FD_DD(rGobs.StateAttributep(nextDState)->ToString()); 00574 } 00575 } 00576 } 00577 } 00578 00579 activeEvents = rGobs.ActiveEventSet(currDState); 00580 transitions = rGobs.ActiveTransSet(currDState); 00581 00582 // delete current Gobs state from new states 00583 newGobsStates.Erase(currDState); 00584 } 00585 } 00586 00587 // ComputeGd() 00588 void ComputeGd(const Diagnoser& rGobs, map<pair<Idx,Idx>,Idx>& rReverseCompositionMap, System& rGd) { 00589 string stateName; 00590 map<pair<Idx,Idx>,Idx>::iterator rcmIt; 00591 rReverseCompositionMap.clear(); 00592 00593 FD_DD("ComputeGd()"); 00594 FD_DD("Performing parallel compostion of G_o with itself ..."); 00595 Parallel(rGobs, rGobs, rReverseCompositionMap, rGd); 00596 FD_DD("Writing G_d state names ..."); 00597 for (rcmIt = rReverseCompositionMap.begin(); rcmIt != rReverseCompositionMap.end(); rcmIt++) { 00598 stateName = ToStringInteger(rcmIt->second) + "{" + \ 00599 rGobs.SAStr(rcmIt->first.first) + "'" + \ 00600 rGobs.SAStr(rcmIt->first.second) +"}"; 00601 rGd.StateName(rcmIt->second, stateName); 00602 } 00603 } 00604 00605 // TrimNonIndicatorTracesOfGd() 00606 void TrimNonIndicatorTracesOfGd(System& rGd, const Diagnoser& rGobs, const Idx rFailureType, 00607 const EventSet& rIndicatorEvents, const map<pair<Idx,Idx>,Idx>& rReverseCompositionMap) { 00608 StateSet statesDone; 00609 map<Idx,pair<Idx,Idx> > CompositionMap; 00610 00611 FD_DD("TrimNonIndicatorTracesOfGd()"); 00612 ConvertParallelCompositionMap(rReverseCompositionMap, CompositionMap); 00613 statesDone.Clear(); 00614 TrimNonIndicatorTracesOfGdRecursive(rGd, rGobs, rFailureType, rIndicatorEvents, CompositionMap, rGd.InitState(), statesDone); 00615 } 00616 00617 // TrimNonIndicatorTracesOfGdRecursive() 00618 void TrimNonIndicatorTracesOfGdRecursive(System& rGd, const Diagnoser& rGobs, const Idx rFailureType, 00619 const EventSet& rIndicatorEvents, map<Idx,pair<Idx,Idx> >& rCompositionMap, 00620 Idx state, StateSet& rStatesDone) { 00621 TransSet trans, backTrans; 00622 TransSet::Iterator it; 00623 Idx nextState = 0; 00624 const TaIndexSet<DiagLabelSet>* pDiagState1; 00625 const TaIndexSet<DiagLabelSet>* pDiagState2; 00626 map<Idx,pair<Idx,Idx> >::iterator compMapIt; 00627 bool failureHasAlreadyOccurred = false; 00628 00629 FD_DD("TrimNonIndicatorTracesOfGdRecursive() for state " + ToStringInteger(state)); 00630 00631 // return if this state has already been processed 00632 if (rStatesDone.Exists(state)) { 00633 return; 00634 } 00635 rStatesDone.Insert(state); 00636 trans = rGd.ActiveTransSet(state); 00637 00638 // if state has no successors than delete it 00639 if (trans.Empty()) { 00640 rGd.DelState(state); 00641 FD_DD("removing state " << state); 00642 return; 00643 } 00644 00645 // If there exists a self-loop of an indicator event (after the occurrence of a failure event), return. 00646 // This needs to be checked because otherwise the following for-loop could cut parts of the future traces before noticing the self-loop. 00647 for (it = trans.Begin(); it != trans.End(); it++) { 00648 if (it->X1 == it->X2) { 00649 if (rIndicatorEvents.Exists(it->Ev)) { 00650 compMapIt = rCompositionMap.find(it->X2); 00651 pDiagState1 = rGobs.StateAttribute(compMapIt->second.first).DiagnoserStateMapp(); 00652 pDiagState2 = rGobs.StateAttribute(compMapIt->second.second).DiagnoserStateMapp(); 00653 if (*(pDiagState1->Attribute(*(pDiagState1->Begin())).mDiagLabels.Begin()) == rFailureType) { 00654 return; 00655 } 00656 if (*(pDiagState2->Attribute(*(pDiagState2->Begin())).mDiagLabels.Begin()) == rFailureType) { 00657 return; 00658 } 00659 } 00660 } 00661 } 00662 00663 // parse through transitions of active transition set 00664 for (it = trans.Begin(); it != trans.End(); it++) { 00665 nextState = it->X2; 00666 failureHasAlreadyOccurred = false; 00667 00668 // if event is an indicator: check if corresponding failure type has already occurred 00669 // by checking if there exists a corresponding failure in the _next_ failure label in G_d 00670 // (we use the _next_ label (and not the last one) to make sure not to miss out failures that occur immediately before the indicator event) 00671 if (rIndicatorEvents.Exists(it->Ev)) { 00672 compMapIt = rCompositionMap.find(nextState); 00673 pDiagState1 = rGobs.StateAttribute(compMapIt->second.first).DiagnoserStateMapp(); 00674 pDiagState2 = rGobs.StateAttribute(compMapIt->second.second).DiagnoserStateMapp(); 00675 if (*(pDiagState1->Attribute(*(pDiagState1->Begin())).mDiagLabels.Begin()) == rFailureType) { 00676 failureHasAlreadyOccurred = true; 00677 } 00678 if (*(pDiagState2->Attribute(*(pDiagState2->Begin())).mDiagLabels.Begin()) == rFailureType) { 00679 failureHasAlreadyOccurred = true; 00680 } 00681 } 00682 00683 // if transition event is not an indicator event or there did not occur a failure _before_ the indicator 00684 if (!rIndicatorEvents.Exists(it->Ev) || !failureHasAlreadyOccurred) { 00685 // remove transition 00686 rGd.ClrTransition(*it); 00687 FD_DD("removing transition " << it->X1 << "--" << rGd.EventName(it->Ev) << "-->" << it->X2 ); 00688 // remove state if it does not have any transitions left 00689 if (rGd.ActiveTransSet(state).Empty()) { 00690 rGd.DelState(state); 00691 FD_DD("removing state " << state ); 00692 } 00693 // if there do not exist any further transitions form other states into the next state: continue trimming at next state 00694 backTrans = ActiveBackwardTransSet(rGd, nextState); 00695 if (backTrans.Empty() || ((backTrans.Size() == 1) && (backTrans.Begin()->X2 == nextState))) { 00696 TrimNonIndicatorTracesOfGdRecursive(rGd, rGobs, rFailureType, rIndicatorEvents, rCompositionMap, nextState, rStatesDone); 00697 } 00698 } 00699 } 00700 } 00701 00702 // ComputeReachability() 00703 void ComputeReachability(const System& rGen, const EventSet& rUnobsEvents, const EventSet& rFailures, Idx State, 00704 const AttributeFailureTypeMap& rAttrFTMap, map<Idx,multimap<Idx,DiagLabelSet> >& rReachabilityMap) { 00705 DiagLabelSet FTonPath; 00706 00707 FD_DD("ComputeReachability() for state " << State << "..."); 00708 rReachabilityMap.clear(); 00709 FTonPath.Clear(); 00710 ComputeReachabilityRecursive(rGen, rUnobsEvents, rFailures, State, rAttrFTMap, rReachabilityMap, FTonPath); 00711 00712 multimap<Idx,DiagLabelSet>::iterator mmLabelIt; 00713 map<Idx,multimap<Idx,DiagLabelSet> >::iterator it; 00714 00715 #ifdef FAUDES_DEBUG_DIAGNOSIS 00716 FD_DD("rReachabilityMap: "); 00717 for (it = rReachabilityMap.begin(); it != rReachabilityMap.end(); it++) { 00718 // print rReachabilityMap for current event 00719 FD_DD("_" << rGen.EventName(it->first) << " ("<< it->second.size() << " state estimates)"); 00720 for (mmLabelIt = it->second.begin(); mmLabelIt != it->second.end(); mmLabelIt++) { 00721 FD_DD(mmLabelIt->first << " " << mmLabelIt->second.ToString()); 00722 } 00723 } 00724 FD_DD(""); 00725 #endif 00726 } 00727 00728 // ComputeReachabilityRecursive() 00729 void ComputeReachabilityRecursive(const System& rGen, const EventSet& rUnobsEvents, 00730 const EventSet& rFailures, Idx State, const AttributeFailureTypeMap& rAttrFTMap, 00731 map<Idx,multimap<Idx,DiagLabelSet> >& rReachabilityMap, const DiagLabelSet FToccurred) { 00732 TransSet trans; 00733 TransSet::Iterator tIt; 00734 EventSet tmpFailureSet; 00735 EventSet::Iterator evIt; 00736 multimap<Idx,DiagLabelSet> stateFailureTypeMap; // maps generator states onto occurred failure types (=labels), part of rReachabilityMap 00737 multimap<Idx,DiagLabelSet>::iterator mmLabelIt; 00738 map<Idx,multimap<Idx,DiagLabelSet> >::iterator it; 00739 Idx failureType; 00740 DiagLabelSet newFT; 00741 bool mappingExists; 00742 00743 trans = rGen.ActiveTransSet(State); 00744 00745 FD_DD("ComputeReachabilityRecursive() for state " << State); 00746 // parse through active transitions of current generator state 00747 for (tIt = trans.Begin(); tIt != trans.End(); tIt++) { 00748 FD_DD(tIt->X1 << "--" << rGen.EventName(tIt->Ev) << "-->" << tIt->X2 << " for " << FToccurred.ToString()); 00749 // if current event is unobservable 00750 if (rUnobsEvents.Exists(tIt->Ev)) { 00751 // if it is a failure as well add its failure type 00752 if (rFailures.Exists(tIt->Ev)) { 00753 FD_DD(rGen.EventName(tIt->Ev) << " is a failure"); 00754 newFT = FToccurred; 00755 newFT.Erase(DiagLabelSet::IndexOfLabelN()); 00756 failureType = rAttrFTMap.FailureType(tIt->Ev); 00757 newFT.Insert(failureType); 00758 FD_DD("new failure path: " << newFT.ToString()); 00759 } else { 00760 FD_DD(rGen.EventName(tIt->Ev) << " is unobservable but no failure"); 00761 newFT = FToccurred; 00762 } 00763 // call ComputeReachabilityRecursive for successor state 00764 ComputeReachabilityRecursive(rGen, rUnobsEvents, rFailures, tIt->X2, rAttrFTMap, rReachabilityMap, newFT); 00765 } 00766 // if current event is observable add failure type path to rReachabilityMap 00767 else { 00768 FD_DD(rGen.EventName(tIt->Ev) << " is observable: add it to rReachabilityMap " << FToccurred.ToString()); 00769 // get old entry of rReachabilityMap if it exists 00770 stateFailureTypeMap.clear(); 00771 if (rReachabilityMap.find(tIt->Ev) != rReachabilityMap.end()) { 00772 stateFailureTypeMap = rReachabilityMap[tIt->Ev]; 00773 #ifdef FAUDES_DEBUG_DIAGNOSIS 00774 FD_DD("old entry of rReachabilityMap for " << rGen.EventName(tIt->Ev)); 00775 for (mmLabelIt = stateFailureTypeMap.begin(); mmLabelIt != stateFailureTypeMap.end(); mmLabelIt++) { 00776 FD_DD(mmLabelIt->first << " " << mmLabelIt->second.ToString()); 00777 } 00778 #endif 00779 } 00780 // if no failure occurred add normal label 00781 newFT = FToccurred; 00782 if (newFT.Empty()) { 00783 newFT.Insert(DiagLabelSet::IndexOfLabelRelN()); 00784 } 00785 // check if new mapping does already exist 00786 mappingExists = false; 00787 for (mmLabelIt = stateFailureTypeMap.lower_bound(tIt->X2); mmLabelIt != stateFailureTypeMap.upper_bound(tIt->X2); mmLabelIt++) { 00788 if (mmLabelIt->second == newFT) { 00789 mappingExists = true; 00790 } 00791 } 00792 // if new mapping does not yet exist: add it to rReachabilityMap 00793 if (!mappingExists) { 00794 stateFailureTypeMap.insert(pair<Idx,DiagLabelSet>(tIt->X2,newFT)); 00795 rReachabilityMap[tIt->Ev] = stateFailureTypeMap; 00796 } 00797 } 00798 } 00799 } 00800 00801 // ActiveBackwardTransSet() 00802 TransSet ActiveBackwardTransSet(const System& rGen, Idx state) { 00803 TransSet result; 00804 TransSetX2EvX1 transByX2; 00805 TransSetX2EvX1::Iterator it; 00806 00807 rGen.TransRel(transByX2); 00808 for (it = transByX2.BeginByX2(state); it != transByX2.EndByX2(state); it++) { 00809 result.Insert(*it); 00810 } 00811 return result; 00812 } 00813 00814 00815 // EventDiagnoser() 00816 void EventDiagnoser(const System& rOrigGen, const map<string,EventSet>& rFailureTypeMap, Diagnoser& rDiagGen) { 00817 FD_DD("EventDiagnoser()"); 00818 AttributeFailureTypeMap attrFT; 00819 attrFT.AddFailureTypeMap(rFailureTypeMap); 00820 EventDiagnoser(rOrigGen, attrFT, rDiagGen); 00821 } 00822 00823 // EventDiagnoser() 00824 void EventDiagnoser(const System& rOrigGen, const AttributeFailureTypeMap& rAttrFTMap, Diagnoser& rDiagGen) { 00825 EventSet failureEvents; 00826 EventSet gObservableEvents, gUnobservableEvents; 00827 StateSet newDiagStates; 00828 Idx currDState = 0; 00829 Idx nextDState = 0; 00830 string reportString; 00831 00832 FD_DD("EventDiagnoser()"); 00833 // check if FailureTypeMap is empty 00834 if (rAttrFTMap.Empty()) { 00835 FD_DD( endl << "WARNING - EventDiagnoser(): failure type map is empty!" << endl); 00836 } 00837 00838 // Necessary assumption: No cycles of unobservable events 00839 reportString.clear(); 00840 if (CycleOfUnobsEvents(rOrigGen,reportString)) { 00841 FD_DD( "EventDiagnoser(): Generator contains cycle of unobservable events! Aborting.."); 00842 FD_DD(reportString); 00843 return; 00844 } 00845 00846 // clear diagnoser 00847 rDiagGen.Clear(); 00848 rDiagGen.ClearAttributes(); 00849 00850 // copy attribute failure type map to diagnoser 00851 rDiagGen.GlobalAttribute(rAttrFTMap); 00852 00853 // get observable events of original generator 00854 gObservableEvents = rOrigGen.ObservableEvents(); 00855 FD_DD("Observable events: " << gObservableEvents.ToString()); 00856 00857 // get unobservable events of original generator 00858 gUnobservableEvents = rOrigGen.UnobservableEvents(); 00859 FD_DD("Unobservable events: " << gUnobservableEvents.ToString()); 00860 00861 // copy all failure events into one single EventSet 00862 failureEvents = rDiagGen.GetAllFailureEvents(); 00863 FD_DD("Failure events: " << failureEvents.ToString()); 00864 00865 // create initial state of diagnoser and its attribute with label "normal" 00866 #ifdef FAUDES_CHECKED 00867 if(rOrigGen.InitStatesSize() != 1) { 00868 std::stringstream errstr; 00869 errstr << "original generator has no unique initial state" << std::endl; 00870 throw Exception("EventDiagnoser()", errstr.str(), 301); 00871 } 00872 #endif 00873 Idx gInitState = rOrigGen.InitState(); 00874 currDState = rDiagGen.InsInitState(); 00875 newDiagStates.Insert(currDState); 00876 rDiagGen.InsStateLabelMapping(currDState,gInitState,DiagLabelSet::IndexOfLabelN()); 00877 00878 Idx gStateEstimate = 0; 00879 Idx newState = 0; 00880 00881 map<Idx,multimap<Idx,DiagLabelSet> > reachMap; // maps executable events to all reachable states and occuring relative failure types 00882 map<Idx,multimap<Idx,DiagLabelSet> > reachMapWholeState; // map for whole diagnoser state, contains propagated absolute failure type labels 00883 map<Idx,multimap<Idx,DiagLabelSet> >::iterator it; 00884 00885 multimap<Idx,DiagLabelSet> tmpPropagatedLabels; 00886 multimap<Idx,DiagLabelSet> bufferPropLabels; 00887 multimap<Idx,DiagLabelSet>::iterator mmit, mmit2; 00888 00889 //pair<Idx,DiagLabelSet> stateLabelPair; 00890 pair<Idx,DiagLabelSet> reachMapPair; 00891 00892 TransSet transitions; 00893 TransSet::Iterator transIt; 00894 DiagLabelSet oldLabel, newLabel, occFailureTypes; 00895 DiagLabelSet::Iterator labelIt; 00896 StateSet diagStates; 00897 StateSet::Iterator stateIt; 00898 EventSet activeEvents; 00899 AttributeDiagnoserState newAttr; 00900 bool stateLabelExists = false; 00901 AttributeDiagnoserState currDStateAttr; 00902 TaIndexSet<DiagLabelSet> currDStateMap; 00903 TaIndexSet<DiagLabelSet>::Iterator currDStateMapIt; 00904 00905 // parse through new diagnoser states 00906 while (!newDiagStates.Empty()) { 00907 // set current diagnoser state 00908 currDState = *newDiagStates.Begin(); 00909 00910 reachMapWholeState.clear(); 00911 00912 currDStateAttr = rDiagGen.StateAttribute(currDState); 00913 currDStateMap = currDStateAttr.DiagnoserStateMap(); 00914 00915 // parse through state estimates of current diagnoser state 00916 for(currDStateMapIt = currDStateMap.Begin(); currDStateMapIt != currDStateMap.End(); ++ currDStateMapIt){ 00917 gStateEstimate = *currDStateMapIt; 00918 // generate reachMap for current state estimate 00919 ComputeReachability(rOrigGen, gUnobservableEvents, failureEvents, gStateEstimate, rAttrFTMap, reachMap); 00920 // parse through reachMap (eventwise), propagate label and copy it to reachMapWholeState 00921 for (it = reachMap.begin(); it != reachMap.end(); it++) { 00922 // get label set of current state estimate 00923 oldLabel = currDStateMap.Attribute(*currDStateMapIt); 00924 newState = 0; 00925 tmpPropagatedLabels.clear(); 00926 // parse through state failure type mappings of state failure type map (for current event in reachMap) 00927 for (mmit = it->second.begin(); mmit != it->second.end(); mmit++) { 00928 newState = mmit->first; 00929 occFailureTypes = mmit->second; 00930 LabelPropagation(oldLabel, occFailureTypes, newLabel); 00931 // check if this combination of state and label does already exist 00932 stateLabelExists = false; 00933 for (mmit2 = tmpPropagatedLabels.lower_bound(newState); mmit2 != tmpPropagatedLabels.upper_bound(newState); mmit2++) { 00934 if (mmit2->second == newLabel) { 00935 stateLabelExists = true; 00936 } 00937 } 00938 // insert new state-label-pair if it does not exist yet 00939 if (!stateLabelExists) { 00940 tmpPropagatedLabels.insert(pair<Idx,DiagLabelSet>(newState,newLabel)); 00941 } 00942 } 00943 00944 // if event is already mapped: add new Labels to multimap and insert it afterwards 00945 if (reachMapWholeState.find(it->first) != reachMapWholeState.end()) { 00946 bufferPropLabels = reachMapWholeState[it->first]; 00947 00948 // parse throught tmpPropagatedLabels and check for every combination of state and label 00949 // if it does already exist in bufferPropLabels 00950 for (mmit = tmpPropagatedLabels.begin(); mmit != tmpPropagatedLabels.end(); mmit++) { 00951 stateLabelExists = false; 00952 for (mmit2 = bufferPropLabels.lower_bound(mmit->first); mmit2 != bufferPropLabels.upper_bound(mmit->first); mmit2++) { 00953 if (mmit2->second == mmit->second) { 00954 stateLabelExists = true; 00955 } 00956 } 00957 // insert new state-label-pair if it does not exist yet 00958 if (!stateLabelExists) { 00959 bufferPropLabels.insert(pair<Idx,DiagLabelSet>(mmit->first,mmit->second)); 00960 } 00961 } 00962 reachMapWholeState[it->first] = bufferPropLabels; 00963 } 00964 // if not just insert the new labels 00965 else { 00966 reachMapWholeState[it->first] = tmpPropagatedLabels; 00967 } 00968 } 00969 } 00970 activeEvents = rDiagGen.ActiveEventSet(currDState); 00971 transitions = rDiagGen.ActiveTransSet(currDState); 00972 00973 for (it = reachMapWholeState.begin(); it != reachMapWholeState.end(); it++) { 00974 LabelCorrection(it->second,newAttr); 00975 // if newAttr equals any existing state attribute than create a transition to this very state 00976 diagStates = rDiagGen.States(); 00977 stateIt = diagStates.Begin(); 00978 while (stateIt != diagStates.End()) { 00979 if (newAttr == rDiagGen.StateAttribute(*stateIt)) { 00980 // realising as back- or self-loop to existing state *stateIt 00981 rDiagGen.InsEvent(it->first); 00982 rDiagGen.SetTransition(currDState,it->first,*stateIt); 00983 break; 00984 } 00985 stateIt++; 00986 } 00987 // if newAttr is new to diagnoser 00988 if (stateIt == diagStates.End()) { 00989 // if current event is executable from current diagnoser state 00990 if (activeEvents.Exists(it->first)) { 00991 // this event is executable from current diagnoser state 00992 // find successor state nextDState 00993 transIt = transitions.Begin(); 00994 while (transIt != transitions.End()) { 00995 if (transIt->Ev == it->first) { 00996 nextDState = transIt->X2; 00997 break; 00998 } 00999 transIt++; 01000 } 01001 } 01002 // if event is not executable from current diagnoser state 01003 else { 01004 // this event is not yet executable from current diagnoser state: create new diagnoser state 01005 // creat new diagnoser state and add it to new states 01006 nextDState = rDiagGen.InsState(); 01007 newDiagStates.Insert(nextDState); 01008 rDiagGen.InsEvent(it->first); 01009 rDiagGen.SetTransition(currDState,it->first,nextDState); 01010 } 01011 rDiagGen.StateAttribute(nextDState, newAttr); 01012 } 01013 } 01014 // delete current diagnoser state from new states 01015 newDiagStates.Erase(currDState); 01016 } 01017 } 01018 01019 // LabelPropagation() 01020 void LabelPropagation(const DiagLabelSet& lastLabel, const DiagLabelSet& failureTypes, DiagLabelSet& newLabel) { 01021 FD_DD("LabelPropagation()"); 01022 newLabel.Clear(); 01023 01024 // if no failure occurred 01025 if (failureTypes.Size() == 1 && failureTypes.Exists(DiagLabelSet::IndexOfLabelRelN())) { 01026 // if label = {"N"} 01027 if (lastLabel.Size() == 1 && lastLabel.Exists(DiagLabelSet::IndexOfLabelN())) { 01028 newLabel.Insert(DiagLabelSet::IndexOfLabelN()); 01029 return; 01030 } 01031 // if label = {"A"} 01032 if (lastLabel.Size() == 1 && lastLabel.Exists(DiagLabelSet::IndexOfLabelA())) { 01033 newLabel.Insert(DiagLabelSet::IndexOfLabelA()); 01034 return; 01035 } 01036 } 01037 // otherwise: 01038 newLabel.InsertSet(lastLabel); 01039 newLabel.InsertSet(failureTypes); 01040 newLabel.Erase(DiagLabelSet::IndexOfLabelN()); 01041 newLabel.Erase(DiagLabelSet::IndexOfLabelA()); 01042 newLabel.Erase(DiagLabelSet::IndexOfLabelRelN()); 01043 return; 01044 } 01045 01046 // LabelCorrection() 01047 void LabelCorrection(const multimap<Idx,DiagLabelSet>& mm, AttributeDiagnoserState& attr) { 01048 multimap<Idx,DiagLabelSet>::const_iterator mmit; 01049 multimap<Idx,DiagLabelSet>::const_iterator mmit_ub; 01050 DiagLabelSet label; 01051 Idx state; 01052 01053 FD_DD("LabelCorrection()"); 01054 attr.Clear(); 01055 mmit = mm.begin(); 01056 // parse through propagated labels 01057 while (mmit != mm.end()) { 01058 // if there is only one label for a particular state: no correction is needed and the label is copied to diagnoser state attribute 01059 if (mm.count(mmit->first) == 1) { 01060 attr.AddStateLabelMap(mmit->first,mmit->second); 01061 mmit++; 01062 } 01063 // if there are several labels: correct label before adding it to the diagnoser state attribute 01064 else { 01065 mmit_ub = mm.upper_bound(mmit->first); 01066 state = mmit->first; 01067 01068 label = mmit->second; 01069 mmit++; 01070 for ( ; mmit != mmit_ub; mmit++) { 01071 label = label * mmit->second; 01072 } 01073 label.Insert(DiagLabelSet::IndexOfLabelA()); 01074 attr.AddStateLabelMap(state,label); 01075 } 01076 } 01077 } 01078 01079 01080 } // namespace faudes libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |