diag_eventdiagnosis.cpp
Go to the documentation of this file.
1/** @file diag_eventdiagnosis.cpp
2Functions to check a system's event-diagnosability and computation of an event-diagnoser. Covers diagnosability with respect to failure events (diagnosability, I-diagnosability).
3*/
4
6
7using namespace std;
8
9namespace faudes {
10
11
12// IsEventDiagnosable()
13bool IsEventDiagnosable(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap, string& rReportString) {
14 Diagnoser genGobs;
15 System genGd;
16 map<pair<Idx,Idx>,Idx> reverseCompositionMap;
17 map<pair<Idx,Idx>,Idx>::iterator rcmIt;
18 StateSet::Iterator stateIt;
19 TaNameSet<AttributeFailureEvents>::Iterator ftIt;
20 EventSet::Iterator evIt;
21
22 // reset report
23 rReportString.clear();
24
25 FD_DD("IsEventDiagnosable()");
26 // TODO: throw exception, dont report
27 // check for indicator events (which should not exist)
28 for (ftIt = rFailureTypeMap.mFailureTypeMap.Begin(); ftIt != rFailureTypeMap.mFailureTypeMap.End(); ftIt++) {
29 if (!rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.Empty()) {
30 FD_DD("IsEventDiagnosable(): Warning: Existing indicator events are ignored! If you want to check for I-diagnosability use IsIdiagnosable() instead.");
31 rReportString.append("IsEventDiagnosable(): Warning: Existing indicator events are ignored! If you want to check for I-diagnosability use IsIdiagnosable() instead.\n");
32 break;
33 }
34 }
35
36 // check if assumptions are met
37 // TODO: convention: "Check" rather than "Meet"
38 if (!MeetsDiagnosabilityAssumptions(rGen, rFailureTypeMap, rReportString)) {
39 return false;
40 }
41
42 // Implementation of Remark 2: Applying Algorithm 1 for each failure type on its own
43 for (ftIt = rFailureTypeMap.mFailureTypeMap.Begin(); ftIt != rFailureTypeMap.mFailureTypeMap.End(); ftIt++) {
44 FD_DD("Testing for failure type " + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) \
45 + " with failures " + rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents.ToString());
46
47 // 3 Steps of Algorithm 1
48 // Step 1: Generate G_o
49 FD_DD("__Step 1__");
50 ComputeGobs(rGen, rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt), rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents, genGobs);
51 //genGobs.Write("tmp_Gobs_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen");
52 //genGobs.GraphWrite("tmp_Gobs_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png");
53
54 // Step 2: Generate G_d = G_o || G_o
55 // State names/attributes are not copied to new generator G_d
56 // but can be obtained via reverse composition map and the corresponding elements of G_o
57 FD_DD("__Step 2__");
58 ComputeGd(genGobs, reverseCompositionMap, genGd);
59 //genGd.Write("tmp_Gd_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen");
60 //genGd.GraphWrite("tmp_Gd_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png");
61
62 // Step 3: Check for cycles in G_d which contain states with different failure labels
63 FD_DD("__Step 3__");
64 if(ExistsViolatingCyclesInGd(genGd, genGobs, reverseCompositionMap, rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt), rReportString)) {
65 //genGd.Write("tmp_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen");
66 //genGd.GraphWrite("tmp_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png");
67 return false;
68 } else {
69 //genGd.Write("tmp_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen");
70 //genGd.GraphWrite("tmp_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png");
71 }
72
73 }
74 return true;
75}
76
77// rti function interface
78bool IsEventDiagnosable(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap) {
79 std::string ignore;
80 return IsEventDiagnosable(rGen,rFailureTypeMap,ignore);
81}
82
83
84// IsIdiagnosable()
85bool IsIndicatorEventDiagnosable(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap, string& rReportString) {
86 Diagnoser genGobs;
87 System genGd;
88 map<pair<Idx,Idx>,Idx> reverseCompositionMap;
89 map<pair<Idx,Idx>,Idx>::iterator rcmIt;
90 StateSet::Iterator stateIt;
91 TaNameSet<AttributeFailureEvents>::Iterator ftIt;
92 EventSet::Iterator evIt;
93 rReportString.clear();
94
95 FD_DD("IsIndicatorEventDiagnosable()");
96 // check for indicator events (which should exist)
97 for (ftIt = rFailureTypeMap.mFailureTypeMap.Begin(); ftIt != rFailureTypeMap.mFailureTypeMap.End(); ftIt++) {
98 if (rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.Empty()) {
99 FD_DD("IsIndicatorEventDiagnosable(): Warning: There are no indicator events for failure type " << rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) << "!");
100 rReportString.append("IsIndicatorEventDiagnosable(): Warning: There are no indicator events for failure type " + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + "!\n");
101 }
102 }
103
104 // check if assumptions are met
105 if (!MeetsDiagnosabilityAssumptions(rGen, rFailureTypeMap, rReportString)) {
106 return false;
107 }
108
109 // Implementation of Remark 2: Applying Algorithm 1 for each failure type on its own
110 for (ftIt = rFailureTypeMap.mFailureTypeMap.Begin(); ftIt != rFailureTypeMap.mFailureTypeMap.End(); ftIt++) {
111 FD_DD("Testing for failure type " + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) \
112 + " with failures/indicators " + rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).ToString());
113
114 // 3 Steps of Algorithm 1
115 // Step 1: Generate G_o
116 FD_DD("__Step 1__");
117 ComputeGobs(rGen, rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt), rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents, genGobs);
118 //genGobs.Write("tmp_I_Gobs_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen");
119 //genGobs.GraphWrite("tmp_I_Gobs_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png");
120
121 // Step 2: Generate G_d = G_o || G_o
122 // State names/attributes are not copied to new generator G_d
123 // but can be obtained via reverse composition map and the corresponding elements of G_o
124 FD_DD("__Step 2__");
125 ComputeGd(genGobs, reverseCompositionMap, genGd);
126 //genGd.Write("tmp_I_Gd_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen");
127 //genGd.GraphWrite("tmp_I_Gd_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png");
128
129 // Additionally for I-diagnosability: Remove all traces which do not contain a failure event followed by an indicator event
130 FD_DD("Removing all traces not containing an indicator event " + rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.ToString());
131 TrimNonIndicatorTracesOfGd(genGd, genGobs, *ftIt, rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents, reverseCompositionMap);
132 //genGd.Write("tmp_I_Gd_iTraces_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen");
133 //genGd.GraphWrite("tmp_I_Gd_iTraces_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png");
134
135 // Step 3: Check for cycles in G_d which contain states with different failure labels
136 FD_DD("__Step 3__");
137 if(ExistsViolatingCyclesInGd(genGd, genGobs, reverseCompositionMap, rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt), rReportString)) {
138 //genGd.Write("tmp_I_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen");
139 //genGd.GraphWrite("tmp_I_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png");
140 return false;
141 } else {
142 //genGd.Write("tmp_I_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".gen");
143 //genGd.GraphWrite("tmp_I_Gd_pruned_" + rFailureTypeMap.mFailureTypeMap.SymbolicName(*ftIt) + ".png");
144 }
145
146 }
147 return true;
148}
149
150
151
152// rti function interface
153bool IsIndicatorEventDiagnosable(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap) {
154 std::string ignore;
155 return IsEventDiagnosable(rGen,rFailureTypeMap,ignore);
156}
157
158
159// MeetsDiagnosabilityAssumptions()
160bool MeetsDiagnosabilityAssumptions(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap, string& rReportString) {
161 TaNameSet<AttributeFailureEvents>::Iterator ftIt;
162 EventSet::Iterator evIt;
163
164 // check if failure and indicator events are part of the generators alphabet
165 for (ftIt = rFailureTypeMap.mFailureTypeMap.Begin(); ftIt != rFailureTypeMap.mFailureTypeMap.End(); ftIt++) {
166 // check if all failures are valid events of generator
167 for (evIt = rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents.Begin(); evIt != rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents.End(); evIt++) {
168 if (!rGen.Alphabet().Exists(*evIt)) {
169 stringstream errstr;
170 errstr << "Failure " << rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mFailureEvents.SymbolicName(*evIt) << " is not in alphabet of generator!" << endl;
171 throw Exception("MeetsDiagnosabilityAssumptions()", errstr.str(), 302);
172 }
173 }
174 // check if all indicator events are valid events of generator
175 for (evIt = rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.Begin(); evIt != rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.End(); evIt++) {
176 if (!rGen.Alphabet().Exists(*evIt)) {
177 stringstream errstr;
178 errstr << "Indicator " << rFailureTypeMap.mFailureTypeMap.Attribute(*ftIt).mIndicatorEvents.SymbolicName(*evIt) << " is not in alphabet of generator!" << endl;
179 throw Exception("MeetsDiagnosabilityAssumptions()", errstr.str(), 303);
180 }
181 }
182 }
183
184 // Assumption A1: Liveness
185 if (!IsLive(rGen, rReportString)) {
186 FD_DD("MeetsDiagnosabilityAssumptions(): Generator is not live!");
187 rReportString.append("Generator is not live!\n");
188 return false;
189 }
190
191 // Assumption A3: All failure events are unobservable
192 if (!FailuresUnobservable(rGen, rFailureTypeMap, rReportString)) {
193 FD_DD("MeetsDiagnosabilityAssumptions(): Not all failure events are unobservable!");
194 rReportString.append("Not all failure events are unobservable!\n");
195 return false;
196 }
197
198 // Assumption A2: No cycles of unobservable events
199 if (CycleOfUnobsEvents(rGen, rReportString)) {
200 FD_DD("MeetsDiagnosabilityAssumptions(): Generator contains cycle of unobservable events!");
201 rReportString.append("Generator contains cycle of unobservable events!\n");
202 return false;
203 }
204
205 // otherwise
206 return true;
207}
208
209// ConvertParallelCompositionMap()
210void ConvertParallelCompositionMap( const map<pair<Idx,Idx>,Idx>& rReverseCompositionMap,
211 map<Idx,pair<Idx,Idx> >& rCompositionMap) {
212 // invert rReverseCompositionMap (possible, as map is expected to be from parallel composition
213 // and thus must be bijective)
214 map<pair<Idx,Idx>,Idx>::const_iterator iter;
215
216 FD_DD("ConvertParallelCompositionMap()");
217 rCompositionMap.clear();
218 for(iter = rReverseCompositionMap.begin(); iter != rReverseCompositionMap.end(); iter++) {
219 rCompositionMap.insert(make_pair(iter->second,iter->first));
220 }
221}
222
223// IsLive()
224// TODO: inefficient set of active vents; have method in Generator
225bool IsLive(const System& rGen, string& rReport) {
226 StateSet states;
227 StateSet::Iterator it;
228 FD_DD("IsLive()");
229 states = rGen.States();
230 for (it = states.Begin(); it != states.End(); it++) {
231 if (rGen.ActiveEventSet(*it).Empty()) {
232 rReport.append("Missing transition at state " + ToStringInteger(*it) + " --> ");
233 return false;
234 }
235 }
236 return true;
237}
238
239// CycleOfUnobsEvents()
240// TODO: inefficient copy; have method in Generator
241bool CycleOfUnobsEvents(const System& rGen, string& rReport) {
242 TransSet transitionsToDelete;
244 System genCopy;
245
246 FD_DD("CycleOfUnobsEvents()");
247 transitionsToDelete.Clear();
248 // make a copy of generator
249 genCopy = rGen;
250 // parse through all its transitions and delete the observable ones
251 for (it = genCopy.TransRelBegin(); it != genCopy.TransRelEnd(); it++) {
252 if (genCopy.Observable(it->Ev)) {
253 transitionsToDelete.Insert(*it);
254 }
255 }
256 for (it = transitionsToDelete.Begin(); it != transitionsToDelete.End(); it++) {
257 FD_DD("delete " << it->X1 << " --" << genCopy.EventName(it->Ev) << "--> " << it->X2);
258 genCopy.ClrTransition(*it);
259 }
260 // check for cycles within the remaining unobservable events
261 return ExistsCycle(genCopy, rReport);
262}
263
264// FailuresUnobservable()
265bool FailuresUnobservable(const System& rGen, const AttributeFailureTypeMap& rFailureTypeMap, string& rReport) {
266 EventSet failures, unobsEvents;
267 EventSet::Iterator evIt;
268
269 FD_DD("FailuresUnobservable()");
270 failures = rFailureTypeMap.AllFailureEvents();
271 unobsEvents = rGen.UnobservableEvents();
272 for (evIt = failures.Begin(); evIt != failures.End(); evIt++) {
273 if (!unobsEvents.Exists(*evIt)) {
274 FD_DD("FailuresUnobservable(): Failure event \"" << failures.SymbolicName(*evIt) << "\" is not unobservable in generator!");
275 rReport.append("Failure event \"" + failures.SymbolicName(*evIt) + "\" is observable in generator --> ");
276 return false;
277 }
278 }
279 return true;
280}
281
282// ExistsCycle()
283bool ExistsCycle(const System& rGen, string& rReport) {
284 StateSet todo, path;
285 StateSet::Iterator stateIt;
286
287 FD_DD("ExistsCycle()");
288 todo = rGen.States();
289 path.Clear();
290 for (stateIt = rGen.InitStatesBegin(); stateIt != rGen.InitStatesEnd(); ++stateIt) {
291 FD_DD("Start cycle search at initial state");
292 if (ExistsCycleSearch(rGen, todo, *stateIt, path, rReport)) {
293 return true;
294 }
295 }
296 while (!todo.Empty()) {
297 FD_DD("Start cycle search at some state..");
298 if (ExistsCycleSearch(rGen, todo, *todo.Begin(), path, rReport)) {
299 return true;
300 }
301 }
302 return false;
303}
304
305// ExistsCycleSearch()
306bool ExistsCycleSearch(const System& rGen, StateSet& rTodo, Idx currState, StateSet statesOnPath, string& rReport) {
307 StateSet successors, newStatesOnPath;
308 StateSet::Iterator stateIt;
309
310 FD_DD("ExistsCycleSearch() for State " << currState);
311 rTodo.Erase(currState);
312 statesOnPath.Insert(currState);
313
314 successors = rGen.SuccessorStates(currState);
315 // parse through active state set of currState
316 for (stateIt = successors.Begin(); stateIt != successors.End(); stateIt++) {
317 if (statesOnPath.Exists(*stateIt)) {
318 FD_DD("Cycle found at state " << *stateIt);
319 rReport.append("Cycle found at state " + ToStringInteger(*stateIt) + " --> ");
320 return true;
321 }
322 // call ExistsCycleSearch() for next successor state and with updated state set newStatesOnPath
323 newStatesOnPath.Clear();
324 newStatesOnPath.InsertSet(statesOnPath);
325 newStatesOnPath.Insert(*stateIt);
326 if (ExistsCycleSearch(rGen, rTodo, *stateIt, newStatesOnPath, rReport)) {
327 return true;
328 }
329 }
330 return false;
331}
332
333// CycleStartStates()
334void CycleStartStates(const System& rGen, StateSet& rCycleOrigins) {
335 StateSet todo, path;
336
337 FD_DD("ExistsCycle()");
338 rCycleOrigins.Clear();
339 todo = rGen.States();
340 if (!rGen.InitStatesEmpty()) {
341 FD_DD("Start cycle search at initial state");
342 path.Clear();
343 CycleStartStatesSearch(rGen, todo, rGen.InitState(), path, rCycleOrigins);
344 }
345 while (!todo.Empty()) {
346 FD_DD("Start cycle search at some state..");
347 path.Clear();
348 CycleStartStatesSearch(rGen, todo, *todo.Begin(), path, rCycleOrigins);
349 }
350 return;
351}
352
353// CycleStartStatesSearch()
354void CycleStartStatesSearch(const System& rGen, StateSet& rTodo, Idx currState, StateSet statesOnPath, StateSet& rCycleOriginStates) {
355 StateSet successors, newStatesOnPath;
356 StateSet::Iterator stateIt;
357
358 FD_DD("CycleStartStatesSearch() for State " << currState);
359 rTodo.Erase(currState);
360 statesOnPath.Insert(currState);
361
362 successors = rGen.SuccessorStates(currState);
363 // parse through active state set of currState
364 for (stateIt = successors.Begin(); stateIt != successors.End(); stateIt++) {
365 if (statesOnPath.Exists(*stateIt)) {
366 FD_DD("Cycle found at state " << *stateIt);
367 rCycleOriginStates.Insert(*stateIt);
368 return;
369 }
370 // call ExistsCycleSearch() for next successor state and with updated state set newStatesOnPath
371 newStatesOnPath.Clear();
372 newStatesOnPath.InsertSet(statesOnPath);
373 newStatesOnPath.Insert(*stateIt);
374 CycleStartStatesSearch(rGen, rTodo, *stateIt, newStatesOnPath, rCycleOriginStates);
375 }
376 return;
377}
378
379// ExistsViolatingCyclesInGd()
380bool ExistsViolatingCyclesInGd(System& rGd, const Diagnoser& rGobs, map<pair<Idx,Idx>,Idx>& rReverseCompositionMap, const string& rFailureType, string& rReportString) {
381 map<pair<Idx,Idx>,Idx>::iterator rcmIt;
382 const TaIndexSet<DiagLabelSet>* fLabel1;
383 const TaIndexSet<DiagLabelSet>* fLabel2;
384 TaIndexSet<DiagLabelSet>::Iterator fL1Begin;
385 TaIndexSet<DiagLabelSet>::Iterator fL2Begin;
386
387 FD_DD("ExistsViolatingCyclesInGd()");
388 // Therefore parse through reverse composition map
389 for (rcmIt = rReverseCompositionMap.begin(); rcmIt != rReverseCompositionMap.end();) {
390 FD_DD("state " << rcmIt->second << " (" << rcmIt->first.first << "," << rcmIt->first.second << ")");
391 // if both states in G_o are equal or just contain the same failure label: delete corresponding state in G_d
392 if (rcmIt->first.first == rcmIt->first.second) {
393 FD_DD(" --> delete (same G_o state)");
394 rGd.DelState(rcmIt->second);
395 rReverseCompositionMap.erase(rcmIt++);
396 } else {
397 fLabel1 = rGobs.StateAttribute(rcmIt->first.first).DiagnoserStateMapp();
398 fLabel2 = rGobs.StateAttribute(rcmIt->first.second).DiagnoserStateMapp();
399 fL1Begin = fLabel1->Begin();
400 fL2Begin = fLabel2->Begin();
401 if (fLabel1->Attribute(*fL1Begin) == fLabel2->Attribute(*fL2Begin)) {
402 FD_DD(" --> delete (same failure label)");
403 rGd.DelState(rcmIt->second);
404 rReverseCompositionMap.erase(rcmIt++);
405 } else {
406 ++rcmIt;
407 }
408 }
409 FD_DD("");
410 }
411 // if there exists a cycle in the remainder graph the system rGen is not diagnosable
412 if (ExistsCycle(rGd,rReportString)) {
413 FD_DD("Detected cycle in G_d");
414 rReportString.append("While checking diagnosability for failure type " + rFailureType + ": " + \
415 "G_d contains a cycle of states with unequal failure labels, i.e. there exists an " + \
416 rFailureType + "-indeterminate cycle in the diagnoser.\n");
417 return true;
418 }
419 return false;
420}
421
422// ComputeGobs()
423void ComputeGobs(const System& rOrigGen, const string& rFailureType, const EventSet& rFailureEvents, Diagnoser& rGobs) {
424 AttributeFailureTypeMap singleFailureTypeMap;
425 singleFailureTypeMap.Clear();
426 singleFailureTypeMap.AddFailureTypeMapping(rFailureType, rFailureEvents);
427 ComputeGobs(rOrigGen, singleFailureTypeMap, rGobs);
428}
429
430// ComputeGobs()
431void ComputeGobs(const System& rOrigGen, const AttributeFailureTypeMap& rAttrFTMap, Diagnoser& rGobs) {
432 EventSet failureEvents;
433 EventSet gObservableEvents, gUnobservableEvents;
434 StateSet newGobsStates;
435 Idx currDState = 0;
436 Idx nextDState = 0;
437
438 FD_DD("ComputeGobs()");
439 // check if FailureTypeMap is empty
440 if (rAttrFTMap.Empty()) {
441 FD_DD("WARNING - ComputeGobs(): failure type map is empty!");
442 }
443
444 // clear Gobs
445 rGobs.Clear();
446 rGobs.ClearAttributes();
447
448 // copy attribute failure type map to Gobs
449 rGobs.GlobalAttribute(rAttrFTMap);
450
451 // get observable events of original generator
452 gObservableEvents = rOrigGen.ObservableEvents();
453 FD_DD("Observable events: " << gObservableEvents.ToString());
454
455 // get unobservable events of original generator
456 gUnobservableEvents = rOrigGen.UnobservableEvents();
457 FD_DD("Unobservable events: " << gUnobservableEvents.ToString());
458
459 // copy all failure events into one single EventSet
460 failureEvents = rGobs.GetAllFailureEvents();
461 FD_DD("Failure events: " << failureEvents.ToString());
462
463 // create initial state of Gobs and its attribute with label "normal"
464 #ifdef FAUDES_CHECKED
465 if(rOrigGen.InitStatesSize() != 1) {
466 std::stringstream errstr;
467 errstr << "original generator has no unique initial state" << std::endl;
468 throw Exception("ComputeGobs()", errstr.str(), 301);
469 }
470 #endif
471 Idx gInitState = rOrigGen.InitState();
472 currDState = rGobs.InsInitState();
473 newGobsStates.Insert(currDState);
474 rGobs.InsStateLabelMapping(currDState,gInitState,DiagLabelSet::IndexOfLabelN());
475
476 Idx gStateEstimate = 0;
477 Idx newState = 0;
478
479 map<Idx,multimap<Idx,DiagLabelSet> > reachMap; // maps executable events to all reachable states and occuring relative failure types
480 map<Idx,multimap<Idx,DiagLabelSet> >::iterator it;
481
482 multimap<Idx,DiagLabelSet>::iterator mmit, mmit2;
483
484 pair<Idx,DiagLabelSet> reachMapPair;
485
486 TransSet transitions;
487 DiagLabelSet oldLabel, newLabel, occFailureTypes;
489 StateSet gObsStates;
490 StateSet::Iterator stateIt;
491 EventSet activeEvents;
493 AttributeDiagnoserState currDStateAttr;
494 TaIndexSet<DiagLabelSet> currDStateMap;
495 TaIndexSet<DiagLabelSet>::Iterator currDStateMapIt;
496
497 // parse through new Gobs states
498 while (!newGobsStates.Empty()) {
499 // set current Gobs state
500 currDState = *newGobsStates.Begin();
501
502 currDStateAttr = rGobs.StateAttribute(currDState);
503 currDStateMap = currDStateAttr.DiagnoserStateMap();
504
505 // parse through state estimates of current Gobs state
506 for(currDStateMapIt = currDStateMap.Begin(); currDStateMapIt != currDStateMap.End(); ++ currDStateMapIt){
507 gStateEstimate = *currDStateMapIt;
508
509 // generate reachMap for current state estimate
510 ComputeReachability(rOrigGen, gUnobservableEvents, failureEvents, gStateEstimate, rAttrFTMap, reachMap);
511
512 #ifdef FAUDES_DEBUG_DIAGNOSIS
513 FD_DD(endl << "reachMap: ");
514 for (it = reachMap.begin(); it != reachMap.end(); it++) {
515 //print reachMap for current event
516 FD_DD("_" << rOrigGen.EventName(it->first) << " ("<< it->second.size() << " state estimates)");
517 for (mmit = it->second.begin(); mmit != it->second.end(); mmit++) {
518 FD_DD(mmit->first << " " << mmit->second.ToString());
519 }
520 }
521 FD_DD("");
522 #endif
523
524 // parse through reachMap (eventwise)
525 for (it = reachMap.begin(); it != reachMap.end(); it++) {
526 //print reachMap for current event
527 #ifdef FAUDES_DEBUG_DIAGNOSIS
528 FD_DD(endl << "_" << rOrigGen.EventName(it->first) << " ("<< it->second.size() << " state estimates)");
529 for (mmit = it->second.begin(); mmit != it->second.end(); mmit++) {
530 FD_DD(mmit->first << " " << mmit->second.ToString());
531 }
532 #endif
533
534 // get label set of current state estimate
535 oldLabel = currDStateMap.Attribute(*currDStateMapIt);
536 FD_DD("old label: " << oldLabel.ToString());
537
538 newState = 0;
539 // parse through state failure type map (for current event in reachMap)
540 for (mmit = it->second.begin(); mmit != it->second.end(); mmit++) {
541 newState = mmit->first;
542 FD_DD("new state: " << newState);
543 occFailureTypes = mmit->second;
544 FD_DD("failure types occurred: " << occFailureTypes.ToString());
545 LabelPropagation(oldLabel, occFailureTypes, newLabel);
546 FD_DD("new label: " << newLabel.ToString());
547 newAttr.Clear();
548 newAttr.AddStateLabelMap(newState,newLabel);
549
550 // if newAttr equals any existing state attribute than we create a transition to this very state
551 gObsStates = rGobs.States();
552 stateIt = gObsStates.Begin();
553 while (stateIt != gObsStates.End()) {
554 if (newAttr == rGobs.StateAttribute(*stateIt)) {
555 FD_DD("realising as back- or self-loop to existing state " << *stateIt);
556 rGobs.InsEvent(it->first);
557 rGobs.SetTransition(currDState,it->first,*stateIt);
558 break;
559 }
560 stateIt++;
561 }
562 // if newAttribute is new to Gobs
563 if (stateIt == gObsStates.End()) {
564 // create new Gobs state and add it to new states
565 nextDState = rGobs.InsState();
566 FD_DD("Create new state " << nextDState << " and transition " << currDState << " --" << rOrigGen.EventName(it->first) << "--> " << nextDState);
567 newGobsStates.Insert(nextDState);
568 rGobs.InsEvent(it->first);
569 rGobs.SetTransition(currDState,it->first,nextDState);
570 rGobs.StateAttribute(nextDState, newAttr);
571
572 FD_DD("Print Gobs label of state " << nextDState);
573 FD_DD(rGobs.StateAttributep(nextDState)->ToString());
574 }
575 }
576 }
577 }
578
579 activeEvents = rGobs.ActiveEventSet(currDState);
580 transitions = rGobs.ActiveTransSet(currDState);
581
582 // delete current Gobs state from new states
583 newGobsStates.Erase(currDState);
584 }
585}
586
587// ComputeGd()
588void ComputeGd(const Diagnoser& rGobs, map<pair<Idx,Idx>,Idx>& rReverseCompositionMap, System& rGd) {
589 string stateName;
590 map<pair<Idx,Idx>,Idx>::iterator rcmIt;
591 rReverseCompositionMap.clear();
592
593 FD_DD("ComputeGd()");
594 FD_DD("Performing parallel compostion of G_o with itself ...");
595 Parallel(rGobs, rGobs, rReverseCompositionMap, rGd);
596 FD_DD("Writing G_d state names ...");
597 for (rcmIt = rReverseCompositionMap.begin(); rcmIt != rReverseCompositionMap.end(); rcmIt++) {
598 stateName = ToStringInteger(rcmIt->second) + "{" + \
599 rGobs.SAStr(rcmIt->first.first) + "'" + \
600 rGobs.SAStr(rcmIt->first.second) +"}";
601 rGd.StateName(rcmIt->second, stateName);
602 }
603}
604
605// TrimNonIndicatorTracesOfGd()
606void TrimNonIndicatorTracesOfGd(System& rGd, const Diagnoser& rGobs, const Idx rFailureType,
607 const EventSet& rIndicatorEvents, const map<pair<Idx,Idx>,Idx>& rReverseCompositionMap) {
608 StateSet statesDone;
609 map<Idx,pair<Idx,Idx> > CompositionMap;
610
611 FD_DD("TrimNonIndicatorTracesOfGd()");
612 ConvertParallelCompositionMap(rReverseCompositionMap, CompositionMap);
613 statesDone.Clear();
614 TrimNonIndicatorTracesOfGdRecursive(rGd, rGobs, rFailureType, rIndicatorEvents, CompositionMap, rGd.InitState(), statesDone);
615}
616
617// TrimNonIndicatorTracesOfGdRecursive()
618void TrimNonIndicatorTracesOfGdRecursive(System& rGd, const Diagnoser& rGobs, const Idx rFailureType,
619 const EventSet& rIndicatorEvents, map<Idx,pair<Idx,Idx> >& rCompositionMap,
620 Idx state, StateSet& rStatesDone) {
621 TransSet trans, backTrans;
623 Idx nextState = 0;
624 const TaIndexSet<DiagLabelSet>* pDiagState1;
625 const TaIndexSet<DiagLabelSet>* pDiagState2;
626 map<Idx,pair<Idx,Idx> >::iterator compMapIt;
627 bool failureHasAlreadyOccurred = false;
628
629 FD_DD("TrimNonIndicatorTracesOfGdRecursive() for state " + ToStringInteger(state));
630
631 // return if this state has already been processed
632 if (rStatesDone.Exists(state)) {
633 return;
634 }
635 rStatesDone.Insert(state);
636 trans = rGd.ActiveTransSet(state);
637
638 // if state has no successors than delete it
639 if (trans.Empty()) {
640 rGd.DelState(state);
641 FD_DD("removing state " << state);
642 return;
643 }
644
645 // If there exists a self-loop of an indicator event (after the occurrence of a failure event), return.
646 // This needs to be checked because otherwise the following for-loop could cut parts of the future traces before noticing the self-loop.
647 for (it = trans.Begin(); it != trans.End(); it++) {
648 if (it->X1 == it->X2) {
649 if (rIndicatorEvents.Exists(it->Ev)) {
650 compMapIt = rCompositionMap.find(it->X2);
651 pDiagState1 = rGobs.StateAttribute(compMapIt->second.first).DiagnoserStateMapp();
652 pDiagState2 = rGobs.StateAttribute(compMapIt->second.second).DiagnoserStateMapp();
653 if (*(pDiagState1->Attribute(*(pDiagState1->Begin())).mDiagLabels.Begin()) == rFailureType) {
654 return;
655 }
656 if (*(pDiagState2->Attribute(*(pDiagState2->Begin())).mDiagLabels.Begin()) == rFailureType) {
657 return;
658 }
659 }
660 }
661 }
662
663 // parse through transitions of active transition set
664 for (it = trans.Begin(); it != trans.End(); it++) {
665 nextState = it->X2;
666 failureHasAlreadyOccurred = false;
667
668 // if event is an indicator: check if corresponding failure type has already occurred
669 // by checking if there exists a corresponding failure in the _next_ failure label in G_d
670 // (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)
671 if (rIndicatorEvents.Exists(it->Ev)) {
672 compMapIt = rCompositionMap.find(nextState);
673 pDiagState1 = rGobs.StateAttribute(compMapIt->second.first).DiagnoserStateMapp();
674 pDiagState2 = rGobs.StateAttribute(compMapIt->second.second).DiagnoserStateMapp();
675 if (*(pDiagState1->Attribute(*(pDiagState1->Begin())).mDiagLabels.Begin()) == rFailureType) {
676 failureHasAlreadyOccurred = true;
677 }
678 if (*(pDiagState2->Attribute(*(pDiagState2->Begin())).mDiagLabels.Begin()) == rFailureType) {
679 failureHasAlreadyOccurred = true;
680 }
681 }
682
683 // if transition event is not an indicator event or there did not occur a failure _before_ the indicator
684 if (!rIndicatorEvents.Exists(it->Ev) || !failureHasAlreadyOccurred) {
685 // remove transition
686 rGd.ClrTransition(*it);
687 FD_DD("removing transition " << it->X1 << "--" << rGd.EventName(it->Ev) << "-->" << it->X2 );
688 // remove state if it does not have any transitions left
689 if (rGd.ActiveTransSet(state).Empty()) {
690 rGd.DelState(state);
691 FD_DD("removing state " << state );
692 }
693 // if there do not exist any further transitions form other states into the next state: continue trimming at next state
694 backTrans = ActiveBackwardTransSet(rGd, nextState);
695 if (backTrans.Empty() || ((backTrans.Size() == 1) && (backTrans.Begin()->X2 == nextState))) {
696 TrimNonIndicatorTracesOfGdRecursive(rGd, rGobs, rFailureType, rIndicatorEvents, rCompositionMap, nextState, rStatesDone);
697 }
698 }
699 }
700}
701
702// ComputeReachability()
703void ComputeReachability(const System& rGen, const EventSet& rUnobsEvents, const EventSet& rFailures, Idx State,
704 const AttributeFailureTypeMap& rAttrFTMap, map<Idx,multimap<Idx,DiagLabelSet> >& rReachabilityMap) {
705 DiagLabelSet FTonPath;
706
707 FD_DD("ComputeReachability() for state " << State << "...");
708 rReachabilityMap.clear();
709 FTonPath.Clear();
710 ComputeReachabilityRecursive(rGen, rUnobsEvents, rFailures, State, rAttrFTMap, rReachabilityMap, FTonPath);
711
712 multimap<Idx,DiagLabelSet>::iterator mmLabelIt;
713 map<Idx,multimap<Idx,DiagLabelSet> >::iterator it;
714
715 #ifdef FAUDES_DEBUG_DIAGNOSIS
716 FD_DD("rReachabilityMap: ");
717 for (it = rReachabilityMap.begin(); it != rReachabilityMap.end(); it++) {
718 // print rReachabilityMap for current event
719 FD_DD("_" << rGen.EventName(it->first) << " ("<< it->second.size() << " state estimates)");
720 for (mmLabelIt = it->second.begin(); mmLabelIt != it->second.end(); mmLabelIt++) {
721 FD_DD(mmLabelIt->first << " " << mmLabelIt->second.ToString());
722 }
723 }
724 FD_DD("");
725 #endif
726}
727
728// ComputeReachabilityRecursive()
729void ComputeReachabilityRecursive(const System& rGen, const EventSet& rUnobsEvents,
730 const EventSet& rFailures, Idx State, const AttributeFailureTypeMap& rAttrFTMap,
731 map<Idx,multimap<Idx,DiagLabelSet> >& rReachabilityMap, const DiagLabelSet FToccurred) {
732 TransSet trans;
734 EventSet tmpFailureSet;
735 EventSet::Iterator evIt;
736 multimap<Idx,DiagLabelSet> stateFailureTypeMap; // maps generator states onto occurred failure types (=labels), part of rReachabilityMap
737 multimap<Idx,DiagLabelSet>::iterator mmLabelIt;
738 map<Idx,multimap<Idx,DiagLabelSet> >::iterator it;
739 Idx failureType;
740 DiagLabelSet newFT;
741 bool mappingExists;
742
743 trans = rGen.ActiveTransSet(State);
744
745 FD_DD("ComputeReachabilityRecursive() for state " << State);
746 // parse through active transitions of current generator state
747 for (tIt = trans.Begin(); tIt != trans.End(); tIt++) {
748 FD_DD(tIt->X1 << "--" << rGen.EventName(tIt->Ev) << "-->" << tIt->X2 << " for " << FToccurred.ToString());
749 // if current event is unobservable
750 if (rUnobsEvents.Exists(tIt->Ev)) {
751 // if it is a failure as well add its failure type
752 if (rFailures.Exists(tIt->Ev)) {
753 FD_DD(rGen.EventName(tIt->Ev) << " is a failure");
754 newFT = FToccurred;
756 failureType = rAttrFTMap.FailureType(tIt->Ev);
757 newFT.Insert(failureType);
758 FD_DD("new failure path: " << newFT.ToString());
759 } else {
760 FD_DD(rGen.EventName(tIt->Ev) << " is unobservable but no failure");
761 newFT = FToccurred;
762 }
763 // call ComputeReachabilityRecursive for successor state
764 ComputeReachabilityRecursive(rGen, rUnobsEvents, rFailures, tIt->X2, rAttrFTMap, rReachabilityMap, newFT);
765 }
766 // if current event is observable add failure type path to rReachabilityMap
767 else {
768 FD_DD(rGen.EventName(tIt->Ev) << " is observable: add it to rReachabilityMap " << FToccurred.ToString());
769 // get old entry of rReachabilityMap if it exists
770 stateFailureTypeMap.clear();
771 if (rReachabilityMap.find(tIt->Ev) != rReachabilityMap.end()) {
772 stateFailureTypeMap = rReachabilityMap[tIt->Ev];
773 #ifdef FAUDES_DEBUG_DIAGNOSIS
774 FD_DD("old entry of rReachabilityMap for " << rGen.EventName(tIt->Ev));
775 for (mmLabelIt = stateFailureTypeMap.begin(); mmLabelIt != stateFailureTypeMap.end(); mmLabelIt++) {
776 FD_DD(mmLabelIt->first << " " << mmLabelIt->second.ToString());
777 }
778 #endif
779 }
780 // if no failure occurred add normal label
781 newFT = FToccurred;
782 if (newFT.Empty()) {
784 }
785 // check if new mapping does already exist
786 mappingExists = false;
787 for (mmLabelIt = stateFailureTypeMap.lower_bound(tIt->X2); mmLabelIt != stateFailureTypeMap.upper_bound(tIt->X2); mmLabelIt++) {
788 if (mmLabelIt->second == newFT) {
789 mappingExists = true;
790 }
791 }
792 // if new mapping does not yet exist: add it to rReachabilityMap
793 if (!mappingExists) {
794 stateFailureTypeMap.insert(pair<Idx,DiagLabelSet>(tIt->X2,newFT));
795 rReachabilityMap[tIt->Ev] = stateFailureTypeMap;
796 }
797 }
798 }
799}
800
801// ActiveBackwardTransSet()
803 TransSet result;
804 TransSetX2EvX1 transByX2;
806
807 rGen.TransRel(transByX2);
808 for (it = transByX2.BeginByX2(state); it != transByX2.EndByX2(state); it++) {
809 result.Insert(*it);
810 }
811 return result;
812}
813
814
815// EventDiagnoser()
816void EventDiagnoser(const System& rOrigGen, const map<string,EventSet>& rFailureTypeMap, Diagnoser& rDiagGen) {
817 FD_DD("EventDiagnoser()");
819 attrFT.AddFailureTypeMap(rFailureTypeMap);
820 EventDiagnoser(rOrigGen, attrFT, rDiagGen);
821}
822
823// EventDiagnoser()
824void EventDiagnoser(const System& rOrigGen, const AttributeFailureTypeMap& rAttrFTMap, Diagnoser& rDiagGen) {
825 EventSet failureEvents;
826 EventSet gObservableEvents, gUnobservableEvents;
827 StateSet newDiagStates;
828 Idx currDState = 0;
829 Idx nextDState = 0;
830 string reportString;
831
832 FD_DD("EventDiagnoser()");
833 // check if FailureTypeMap is empty
834 if (rAttrFTMap.Empty()) {
835 FD_DD( endl << "WARNING - EventDiagnoser(): failure type map is empty!" << endl);
836 }
837
838 // Necessary assumption: No cycles of unobservable events
839 reportString.clear();
840 if (CycleOfUnobsEvents(rOrigGen,reportString)) {
841 FD_DD( "EventDiagnoser(): Generator contains cycle of unobservable events! Aborting..");
842 FD_DD(reportString);
843 return;
844 }
845
846 // clear diagnoser
847 rDiagGen.Clear();
848 rDiagGen.ClearAttributes();
849
850 // copy attribute failure type map to diagnoser
851 rDiagGen.GlobalAttribute(rAttrFTMap);
852
853 // get observable events of original generator
854 gObservableEvents = rOrigGen.ObservableEvents();
855 FD_DD("Observable events: " << gObservableEvents.ToString());
856
857 // get unobservable events of original generator
858 gUnobservableEvents = rOrigGen.UnobservableEvents();
859 FD_DD("Unobservable events: " << gUnobservableEvents.ToString());
860
861 // copy all failure events into one single EventSet
862 failureEvents = rDiagGen.GetAllFailureEvents();
863 FD_DD("Failure events: " << failureEvents.ToString());
864
865 // create initial state of diagnoser and its attribute with label "normal"
866 #ifdef FAUDES_CHECKED
867 if(rOrigGen.InitStatesSize() != 1) {
868 std::stringstream errstr;
869 errstr << "original generator has no unique initial state" << std::endl;
870 throw Exception("EventDiagnoser()", errstr.str(), 301);
871 }
872 #endif
873 Idx gInitState = rOrigGen.InitState();
874 currDState = rDiagGen.InsInitState();
875 newDiagStates.Insert(currDState);
876 rDiagGen.InsStateLabelMapping(currDState,gInitState,DiagLabelSet::IndexOfLabelN());
877
878 Idx gStateEstimate = 0;
879 Idx newState = 0;
880
881 map<Idx,multimap<Idx,DiagLabelSet> > reachMap; // maps executable events to all reachable states and occuring relative failure types
882 map<Idx,multimap<Idx,DiagLabelSet> > reachMapWholeState; // map for whole diagnoser state, contains propagated absolute failure type labels
883 map<Idx,multimap<Idx,DiagLabelSet> >::iterator it;
884
885 multimap<Idx,DiagLabelSet> tmpPropagatedLabels;
886 multimap<Idx,DiagLabelSet> bufferPropLabels;
887 multimap<Idx,DiagLabelSet>::iterator mmit, mmit2;
888
889 //pair<Idx,DiagLabelSet> stateLabelPair;
890 pair<Idx,DiagLabelSet> reachMapPair;
891
892 TransSet transitions;
893 TransSet::Iterator transIt;
894 DiagLabelSet oldLabel, newLabel, occFailureTypes;
896 StateSet diagStates;
897 StateSet::Iterator stateIt;
898 EventSet activeEvents;
900 bool stateLabelExists = false;
901 AttributeDiagnoserState currDStateAttr;
902 TaIndexSet<DiagLabelSet> currDStateMap;
903 TaIndexSet<DiagLabelSet>::Iterator currDStateMapIt;
904
905 // parse through new diagnoser states
906 while (!newDiagStates.Empty()) {
907 // set current diagnoser state
908 currDState = *newDiagStates.Begin();
909
910 reachMapWholeState.clear();
911
912 currDStateAttr = rDiagGen.StateAttribute(currDState);
913 currDStateMap = currDStateAttr.DiagnoserStateMap();
914
915 // parse through state estimates of current diagnoser state
916 for(currDStateMapIt = currDStateMap.Begin(); currDStateMapIt != currDStateMap.End(); ++ currDStateMapIt){
917 gStateEstimate = *currDStateMapIt;
918 // generate reachMap for current state estimate
919 ComputeReachability(rOrigGen, gUnobservableEvents, failureEvents, gStateEstimate, rAttrFTMap, reachMap);
920 // parse through reachMap (eventwise), propagate label and copy it to reachMapWholeState
921 for (it = reachMap.begin(); it != reachMap.end(); it++) {
922 // get label set of current state estimate
923 oldLabel = currDStateMap.Attribute(*currDStateMapIt);
924 newState = 0;
925 tmpPropagatedLabels.clear();
926 // parse through state failure type mappings of state failure type map (for current event in reachMap)
927 for (mmit = it->second.begin(); mmit != it->second.end(); mmit++) {
928 newState = mmit->first;
929 occFailureTypes = mmit->second;
930 LabelPropagation(oldLabel, occFailureTypes, newLabel);
931 // check if this combination of state and label does already exist
932 stateLabelExists = false;
933 for (mmit2 = tmpPropagatedLabels.lower_bound(newState); mmit2 != tmpPropagatedLabels.upper_bound(newState); mmit2++) {
934 if (mmit2->second == newLabel) {
935 stateLabelExists = true;
936 }
937 }
938 // insert new state-label-pair if it does not exist yet
939 if (!stateLabelExists) {
940 tmpPropagatedLabels.insert(pair<Idx,DiagLabelSet>(newState,newLabel));
941 }
942 }
943
944 // if event is already mapped: add new Labels to multimap and insert it afterwards
945 if (reachMapWholeState.find(it->first) != reachMapWholeState.end()) {
946 bufferPropLabels = reachMapWholeState[it->first];
947
948 // parse throught tmpPropagatedLabels and check for every combination of state and label
949 // if it does already exist in bufferPropLabels
950 for (mmit = tmpPropagatedLabels.begin(); mmit != tmpPropagatedLabels.end(); mmit++) {
951 stateLabelExists = false;
952 for (mmit2 = bufferPropLabels.lower_bound(mmit->first); mmit2 != bufferPropLabels.upper_bound(mmit->first); mmit2++) {
953 if (mmit2->second == mmit->second) {
954 stateLabelExists = true;
955 }
956 }
957 // insert new state-label-pair if it does not exist yet
958 if (!stateLabelExists) {
959 bufferPropLabels.insert(pair<Idx,DiagLabelSet>(mmit->first,mmit->second));
960 }
961 }
962 reachMapWholeState[it->first] = bufferPropLabels;
963 }
964 // if not just insert the new labels
965 else {
966 reachMapWholeState[it->first] = tmpPropagatedLabels;
967 }
968 }
969 }
970 activeEvents = rDiagGen.ActiveEventSet(currDState);
971 transitions = rDiagGen.ActiveTransSet(currDState);
972
973 for (it = reachMapWholeState.begin(); it != reachMapWholeState.end(); it++) {
974 LabelCorrection(it->second,newAttr);
975 // if newAttr equals any existing state attribute than create a transition to this very state
976 diagStates = rDiagGen.States();
977 stateIt = diagStates.Begin();
978 while (stateIt != diagStates.End()) {
979 if (newAttr == rDiagGen.StateAttribute(*stateIt)) {
980 // realising as back- or self-loop to existing state *stateIt
981 rDiagGen.InsEvent(it->first);
982 rDiagGen.SetTransition(currDState,it->first,*stateIt);
983 break;
984 }
985 stateIt++;
986 }
987 // if newAttr is new to diagnoser
988 if (stateIt == diagStates.End()) {
989 // if current event is executable from current diagnoser state
990 if (activeEvents.Exists(it->first)) {
991 // this event is executable from current diagnoser state
992 // find successor state nextDState
993 transIt = transitions.Begin();
994 while (transIt != transitions.End()) {
995 if (transIt->Ev == it->first) {
996 nextDState = transIt->X2;
997 break;
998 }
999 transIt++;
1000 }
1001 }
1002 // if event is not executable from current diagnoser state
1003 else {
1004 // this event is not yet executable from current diagnoser state: create new diagnoser state
1005 // creat new diagnoser state and add it to new states
1006 nextDState = rDiagGen.InsState();
1007 newDiagStates.Insert(nextDState);
1008 rDiagGen.InsEvent(it->first);
1009 rDiagGen.SetTransition(currDState,it->first,nextDState);
1010 }
1011 rDiagGen.StateAttribute(nextDState, newAttr);
1012 }
1013 }
1014 // delete current diagnoser state from new states
1015 newDiagStates.Erase(currDState);
1016 }
1017}
1018
1019// LabelPropagation()
1020void LabelPropagation(const DiagLabelSet& lastLabel, const DiagLabelSet& failureTypes, DiagLabelSet& newLabel) {
1021 FD_DD("LabelPropagation()");
1022 newLabel.Clear();
1023
1024 // if no failure occurred
1025 if (failureTypes.Size() == 1 && failureTypes.Exists(DiagLabelSet::IndexOfLabelRelN())) {
1026 // if label = {"N"}
1027 if (lastLabel.Size() == 1 && lastLabel.Exists(DiagLabelSet::IndexOfLabelN())) {
1029 return;
1030 }
1031 // if label = {"A"}
1032 if (lastLabel.Size() == 1 && lastLabel.Exists(DiagLabelSet::IndexOfLabelA())) {
1034 return;
1035 }
1036 }
1037 // otherwise:
1038 newLabel.InsertSet(lastLabel);
1039 newLabel.InsertSet(failureTypes);
1043 return;
1044}
1045
1046// LabelCorrection()
1047void LabelCorrection(const multimap<Idx,DiagLabelSet>& mm, AttributeDiagnoserState& attr) {
1048 multimap<Idx,DiagLabelSet>::const_iterator mmit;
1049 multimap<Idx,DiagLabelSet>::const_iterator mmit_ub;
1050 DiagLabelSet label;
1051 Idx state;
1052
1053 FD_DD("LabelCorrection()");
1054 attr.Clear();
1055 mmit = mm.begin();
1056 // parse through propagated labels
1057 while (mmit != mm.end()) {
1058 // if there is only one label for a particular state: no correction is needed and the label is copied to diagnoser state attribute
1059 if (mm.count(mmit->first) == 1) {
1060 attr.AddStateLabelMap(mmit->first,mmit->second);
1061 mmit++;
1062 }
1063 // if there are several labels: correct label before adding it to the diagnoser state attribute
1064 else {
1065 mmit_ub = mm.upper_bound(mmit->first);
1066 state = mmit->first;
1067
1068 label = mmit->second;
1069 mmit++;
1070 for ( ; mmit != mmit_ub; mmit++) {
1071 label = label * mmit->second;
1072 }
1074 attr.AddStateLabelMap(state,label);
1075 }
1076 }
1077}
1078
1079
1080} // namespace faudes
const TaIndexSet< DiagLabelSet > & DiagnoserStateMap(void) const
void AddStateLabelMap(Idx gstate, const DiagLabelSet &labels)
TaNameSet< AttributeFailureEvents > mFailureTypeMap
void AddFailureTypeMap(const std::map< std::string, EventSet > &rFailureMap)
Idx AddFailureTypeMapping(const std::string &failureType, const EventSet &rfailureEvents)
Idx FailureType(Idx failureEvent) const
NameSet::Iterator Iterator
static Idx IndexOfLabelN(void)
void InsertSet(const DiagLabelSet &rSet)
static Idx IndexOfLabelA(void)
static Idx IndexOfLabelRelN(void)
bool Exists(Idx index) const
bool Exists(const Idx &rIndex) const
void SymbolicName(Idx index, const std::string &rName)
Iterator Begin(void) const
Iterator End(void) const
Iterator BeginByX2(Idx x2) const
bool Insert(const Transition &rTransition)
Iterator EndByX2(Idx x2) const
virtual void Clear(void)
bool InsEvent(Idx index)
const TaStateSet< StateAttr > & States(void) const
const TaEventSet< EventAttr > & Alphabet(void) const
bool SetTransition(Idx x1, Idx ev, Idx x2)
const ATransSet & TransRel(void) const
void GlobalAttribute(const GlobalAttr &rAttr)
void StateAttribute(Idx index, const StateAttr &rAttr)
StateAttr * StateAttributep(Idx index)
const Attr & Attribute(const Idx &rElem) const
EventSet UnobservableEvents(void) const
bool Observable(Idx index) const
EventSet ObservableEvents(void) const
EventSet GetAllFailureEvents(void) const
std::string SAStr(Idx dStateIndex) const
void InsStateLabelMapping(Idx dStateIndex, Idx gStateIndex, Idx labelIndex)
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
StateSet::Iterator InitStatesBegin(void) const
bool InitStatesEmpty(void) const
EventSet ActiveEventSet(Idx x1) const
TransSet::Iterator TransRelBegin(void) const
void ClrTransition(Idx x1, Idx ev, Idx x2)
Idx InitStatesSize(void) const
TransSet ActiveTransSet(Idx x1) const
std::string StateName(Idx index) const
bool DelState(Idx index)
TransSet::Iterator TransRelEnd(void) const
Idx InitState(void) const
StateSet::Iterator InitStatesEnd(void) const
std::string EventName(Idx index) const
virtual void ClearAttributes(void)
StateSet SuccessorStates(Idx x1) const
#define FD_DD(message)
Definition diag_debug.h:13
bool Empty(void) const
bool Exists(const T &rElem) const
virtual void Clear(void)
Iterator End(void) const
virtual void InsertSet(const TBaseSet &rOtherSet)
Iterator Begin(void) const
virtual bool Erase(const T &rElem)
Idx Size(void) const
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
uint32_t Idx
void ConvertParallelCompositionMap(const map< pair< Idx, Idx >, Idx > &rReverseCompositionMap, map< Idx, pair< Idx, Idx > > &rCompositionMap)
bool ExistsViolatingCyclesInGd(System &rGd, const Diagnoser &rGobs, map< pair< Idx, Idx >, Idx > &rReverseCompositionMap, const string &rFailureType, string &rReportString)
bool FailuresUnobservable(const System &rGen, const AttributeFailureTypeMap &rFailureTypeMap, string &rReport)
void ComputeGd(const Diagnoser &rGobs, map< pair< Idx, Idx >, Idx > &rReverseCompositionMap, System &rGd)
TransSet ActiveBackwardTransSet(const System &rGen, Idx state)
bool ExistsCycleSearch(const System &rGen, StateSet &rTodo, Idx currState, StateSet statesOnPath, string &rReport)
bool IsIndicatorEventDiagnosable(const System &rGen, const AttributeFailureTypeMap &rFailureTypeMap, string &rReportString)
bool ExistsCycle(const System &rGen, string &rReport)
void CycleStartStatesSearch(const System &rGen, StateSet &rTodo, Idx currState, StateSet statesOnPath, StateSet &rCycleOriginStates)
void CycleStartStates(const System &rGen, StateSet &rCycleOrigins)
void TrimNonIndicatorTracesOfGd(System &rGd, const Diagnoser &rGobs, const Idx rFailureType, const EventSet &rIndicatorEvents, const map< pair< Idx, Idx >, Idx > &rReverseCompositionMap)
bool IsLive(const System &rGen, string &rReport)
bool IsEventDiagnosable(const System &rGen, const AttributeFailureTypeMap &rFailureTypeMap, string &rReportString)
void ComputeReachability(const System &rGen, const EventSet &rUnobsEvents, const EventSet &rFailures, Idx State, const AttributeFailureTypeMap &rAttrFTMap, map< Idx, multimap< Idx, DiagLabelSet > > &rReachabilityMap)
void EventDiagnoser(const System &rOrigGen, const map< string, EventSet > &rFailureTypeMap, Diagnoser &rDiagGen)
std::string ToStringInteger(Int number)
Definition cfl_utils.cpp:43
void LabelPropagation(const DiagLabelSet &lastLabel, const DiagLabelSet &failureTypes, DiagLabelSet &newLabel)
void ComputeReachabilityRecursive(const System &rGen, const EventSet &rUnobsEvents, const EventSet &rFailures, Idx State, const AttributeFailureTypeMap &rAttrFTMap, map< Idx, multimap< Idx, DiagLabelSet > > &rReachabilityMap, const DiagLabelSet FToccurred)
bool CycleOfUnobsEvents(const System &rGen, string &rReport)
bool MeetsDiagnosabilityAssumptions(const System &rGen, const AttributeFailureTypeMap &rFailureTypeMap, string &rReportString)
void TrimNonIndicatorTracesOfGdRecursive(System &rGd, const Diagnoser &rGobs, const Idx rFailureType, const EventSet &rIndicatorEvents, map< Idx, pair< Idx, Idx > > &rCompositionMap, Idx state, StateSet &rStatesDone)
void LabelCorrection(const multimap< Idx, DiagLabelSet > &mm, AttributeDiagnoserState &attr)
void ComputeGobs(const System &rOrigGen, const string &rFailureType, const EventSet &rFailureEvents, Diagnoser &rGobs)

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen