diag_modulardiagnosis.cpp
Go to the documentation of this file.
1/** @file diag_modulardiagnosis.cpp Functions to test modular diagnosability and compute modular diagnosers.
2*/
3
4/*
5
6Copyright Tobias Barthel, Klaus Schmidt, Thomas Moor
7
8*/
9
11
12
13using namespace std;
14
15namespace faudes {
16
17///////////////////////////////////////////////////////////////////////////////
18// Functions for modular diagnosability
19///////////////////////////////////////////////////////////////////////////////
20
21
22// IsModularDiagnosable(): RTI wrapper
23bool IsModularDiagnosable(const SystemVector& rGsubs, const GeneratorVector& rKsubs, string& rReportString) {
24 FD_DD("IsModularDiagnosable()");
25
26 // if the vectors have different size, the input is invalid
27 if(rGsubs.Size() != rKsubs.Size() ){
28 stringstream errstr;
29 errstr << "Number of specifications (" << rKsubs.Size() << ") does not equal number of subsystems ("<< rGsubs.Size() << ")" << endl;
30 throw Exception("IsModularDiagnosable()", errstr.str(), 304);
31 }
32
33 // reorganize as std vector
34 std::vector<const System*> gen;
35 std::vector<const Generator*> spec;
36 Idx i;
37
38 for(i = 0; i < rGsubs.Size(); ++i)
39 gen.push_back(&rGsubs.At(i));
40 for(i = 0; i < rKsubs.Size(); ++i)
41 spec.push_back(&rKsubs.At(i));
42
43 // invoke function
44 return IsModularDiagnosable(gen, spec, rReportString);
45}
46
47
48
49// IsModularDiagnosable()
50bool IsModularDiagnosable(const vector< const System* >& rGSubs, const vector< const Generator* >& rKSubs, std::string& rReportString) {
51
52 FD_DD("IsModularDiagnosable()");
53
54 // clear report
55 rReportString.clear();
56 // verify dimensions
57 if(rGSubs.size() != rKSubs.size()) {
58 stringstream errstr;
59 errstr << "Number of specifications (" << rKSubs.size() << ") does not equal number of subsystems ("<< rGSubs.size() << ")" << endl;
60 throw Exception("IsModularDiagnosable()", errstr.str(), 304);
61 }
62 // assemble shared events
63 EventSet sigmaCup;
64 EventSet sigmaCap;
65 vector<EventSet> sigmaiCapVector;
66 for(unsigned int i = 0; i < rGSubs.size(); ++i) // alphabet union
67 sigmaCup.InsertSet(rGSubs.at(i)->Alphabet());
68
69 FD_DD("all events: " + sigmaCup.ToString());
70 for(EventSet::Iterator eit=sigmaCup.Begin(); eit!=sigmaCup.End(); eit++) { // overall shared events
71 int cnt=0;
72 for(unsigned int i = 0; i < rGSubs.size(); ++i) {
73 if(rGSubs.at(i)->ExistsEvent(*eit))
74 cnt++;
75 if(cnt>1){
76 sigmaCap.Insert(*eit);
77 break;
78 }
79 }
80 }
81 sigmaCup.Name("Sigma_cup");
82 sigmaCap.Name("Sigma_cap");
83 FD_DD("Shared Events: " << sigmaCap.ToString());
84 // shared events per component
85 for(unsigned int i = 0; i < rGSubs.size(); ++i)
86 sigmaiCapVector.push_back(sigmaCap * rGSubs.at(i)->Alphabet() );
87
88 // Compute abstraction alphabet for each component such that loop-preserving observer is fulfilled
89 vector<EventSet> sigmaAbstVector;
90 vector<System> genAbstVector;
91 EventSet sigmaAbst;
92 for(Idx i = 0; i < rGSubs.size(); ++i){
93 sigmaAbstVector.push_back(EventSet() );
94 LoopPreservingObserver(*rGSubs.at(i), sigmaiCapVector.at(i), sigmaAbstVector[i]);
95 sigmaAbst = sigmaAbst + sigmaAbstVector.at(i); // overall abstraction alphabet
96 // Compute the abstraction of each subsystem
97 genAbstVector.push_back(System() );
98 Project(*rGSubs.at(i),sigmaAbstVector.at(i),genAbstVector[i]);
99 FD_DD("AbstractionAlphabet of Automaton " + ToStringInteger(i) + " " + sigmaAbstVector.at(i).ToString());
100 }
101 // Verify modular diagnosability for each subsystem
102 EventSet obsEvents;
103 System plant, plantAbst, spec;
104 cParallel(genAbstVector,plantAbst); // abstracted plant
105 bool diagnosable = true;
106 for(unsigned int i = 0; i < rGSubs.size(); ++i){
107 plant.Clear();
108 Parallel(*rGSubs.at(i),plantAbst,plant); // plant for verification
109 Parallel(plant,*rKSubs.at(i),spec);
110 plant.ClrObservable(plant.Alphabet() );
111 plant.SetObservable(rGSubs.at(i)->ObservableEvents() ); // only observable events of the subsystem are observable
112 std::string reportString;
113 if(IsLanguageDiagnosable(plant,spec,reportString) == false ){
114 FD_DD("Plant " + ToStringInteger(i) + " fails");
115 diagnosable = false;
116 rReportString += "Subsystem " + ToStringInteger(i) + " fails ";
117 }
118 else{
119 FD_DD("Plant " + ToStringInteger(i) + " works");
120 rReportString += "Subsystem " + ToStringInteger(i) + " works ";
121 }
122 }
123 return diagnosable;
124}
125
126
127// IsModularDiagnosable(): RTI wrapper
128bool ModularDiagnoser(const SystemVector& rGsubs, const GeneratorVector& rKsubs, GeneratorVector& rDiagSubs, string& rReportString) {
129 FD_DD("ModularDiagnoser");
130
131 // if the vectors have different size, the input is invalid
132 if(rGsubs.Size() != rKsubs.Size() ){
133 stringstream errstr;
134 errstr << "Number of specifications (" << rKsubs.Size() << ") does not equal number of subsystems ("<< rGsubs.Size() << ")" << endl;
135 throw Exception("ModularDiagnoser()", errstr.str(), 304);
136 }
137
138
139 // reorganize as std vector
140 std::vector<const System*> gen;
141 std::vector<const Generator*> spec;
142 Idx i;
143 for(i = 0; i < rGsubs.Size(); ++i)
144 gen.push_back(&rGsubs.At(i));
145 for(i = 0; i < rKsubs.Size(); ++i)
146 spec.push_back(&rKsubs.At(i));
147
148 // prepare result
149 std::vector<Diagnoser*> diag;
150
151 // invoke function
152 bool diagnosable = ModularDiagnoser(gen, spec, diag, rReportString);
153
154 // retrieve result (no copy, using explicit reference)
155 for(i = 0; i < diag.size(); i++)
156 rDiagSubs.Append(diag.at(i) );
157 rDiagSubs.TakeOwnership();
158
159 // done
160 return diagnosable;
161}
162
163
164// ModularDiagnoser(rGsubs, rKsubs, rDiagsubs, rReportString)
165bool ModularDiagnoser(const std::vector< const System* >& rGSubs, const std::vector< const Generator* >& rKSubs, std::vector<Diagnoser*>& rDiagSubs, std::string& rReportString){
166
167 FD_DD("ModularDiagnoser()");
168
169 // clear report
170 rReportString.clear();
171
172 // verify dimensions
173 if(rGSubs.size() != rKSubs.size()) {
174 stringstream errstr;
175 errstr << "Number of specifications (" << rKSubs.size() << ") does not equal number of subsystems ("<< rGSubs.size() << ")" << endl;
176 throw Exception("ModularDiagnoser()", errstr.str(), 304);
177 }
178
179 // assemble shared events
180 EventSet sigmaCup;
181 EventSet sigmaCap;
182 vector<EventSet> sigmaiCapVector;
183 for(unsigned int i = 0; i < rGSubs.size(); ++i) // alphabet union
184 sigmaCup.InsertSet(rGSubs.at(i)->Alphabet());
185
186 FD_DD("all events: " + sigmaCup.ToString());
187 for(EventSet::Iterator eit=sigmaCup.Begin(); eit!=sigmaCup.End(); eit++) { // overall shared events
188 int cnt=0;
189 for(unsigned int i = 0; i < rGSubs.size(); ++i) {
190 if(rGSubs.at(i)->ExistsEvent(*eit))
191 cnt++;
192 if(cnt>1){
193 sigmaCap.Insert(*eit);
194 break;
195 }
196 }
197 }
198 sigmaCup.Name("Sigma_cup");
199 sigmaCap.Name("Sigma_cap");
200 FD_DD("Shared Events: " << sigmaCap.ToString());
201 // shared events per component
202 for(unsigned int i = 0; i < rGSubs.size(); ++i)
203 sigmaiCapVector.push_back(sigmaCap * rGSubs.at(i)->Alphabet() );
204
205 // Compute abstraction alphabet for each component such that loop-preserving observer is fulfilled
206 vector<EventSet> sigmaAbstVector;
207 vector<System> genAbstVector;
208 EventSet sigmaAbst;
209 for(Idx i = 0; i < rGSubs.size(); ++i){
210 sigmaAbstVector.push_back(EventSet() );
211 LoopPreservingObserver(*rGSubs.at(i), sigmaiCapVector.at(i), sigmaAbstVector[i]);
212 sigmaAbst = sigmaAbst + sigmaAbstVector.at(i); // overall abstraction alphabet
213 // Compute the abstraction of each subsystem
214 genAbstVector.push_back(System() );
215 Project(*rGSubs.at(i),sigmaAbstVector.at(i),genAbstVector[i]);
216 FD_DD("AbstractionAlphabet of Automaton " + ToStringInteger(i) + " " + sigmaAbstVector.at(i).ToString());
217 }
218 // Verify modular diagnosability for each subsystem
219 EventSet obsEvents;
220 System plant, plantAbst, spec;
221 cParallel(genAbstVector,plantAbst); // abstracted plant
222 bool diagnosable = true;
223 for(unsigned int i = 0; i < rGSubs.size(); ++i){
224 plant.Clear();
225 Parallel(*rGSubs.at(i),plantAbst,plant); // plant for verification
226 Parallel(plant,*rKSubs.at(i),spec);
227 plant.ClrObservable(plant.Alphabet() );
228 plant.SetObservable(rGSubs.at(i)->ObservableEvents() ); // only observable events of the subsystem are observable
229 std::string reportString;
230 rDiagSubs.push_back( new Diagnoser() );
231
232 if(IsLanguageDiagnosable(plant,spec,reportString) == false ){
233 FD_DD("Plant " + ToStringInteger(i) + " fails");
234 diagnosable = false;
235 rReportString += "Subsystem " + ToStringInteger(i) + " fails ";
236 }
237 else{
238 FD_DD("Plant " + ToStringInteger(i) + " works");
239 LanguageDiagnoser(plant,spec,*rDiagSubs[i]);
240 rReportString += "Subsystem " + ToStringInteger(i) + " works ";
241
242 }
243 }
244 return diagnosable;
245}
246
247///////////////////////////////////////////////////////////////////////////////
248// RTI wrapper
249///////////////////////////////////////////////////////////////////////////////
250
251// IsModularDiagnosable()
252bool IsModularDiagnosable(const SystemVector& rGsubs, const GeneratorVector& rKsubs) {
253 std::string ignore;
254 return IsModularDiagnosable(rGsubs, rKsubs, ignore);
255}
256
257
258
259// ModularDiagnoser()
260bool ModularDiagnoser(const SystemVector& rGsubs, const GeneratorVector& rKsubs, GeneratorVector& rDiagsubs) {
261 std::string ignore;
262 return ModularDiagnoser(rGsubs, rKsubs, rDiagsubs, ignore);
263}
264
265///////////////////////////////////////////////////////////////////////////////
266// Auxiliary Functions
267///////////////////////////////////////////////////////////////////////////////
268
269// cParallel()
270void cParallel(const vector<System>& rGens, System& rResGen) {
271 unsigned int i = 0;
272 rResGen.Clear();
273 if (rGens.size() == 0) return;
274 rResGen = rGens.at(0);
275
276 for (i = 1; i < rGens.size(); ++i) {
277 aParallel(rResGen,rGens.at(i),rResGen);
278 }
279}
280
281
282} // namespace faudes
const std::string & Name(void) const
virtual void InsertSet(const NameSet &rOtherSet)
bool Insert(const Idx &rIndex)
virtual const T & At(const Position &pos) const
virtual void Clear(void)
const TaEventSet< EventAttr > & Alphabet(void) const
void ClrObservable(Idx index)
void SetObservable(Idx index)
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
virtual void Append(const Type &rElem)
#define FD_DD(message)
Definition diag_debug.h:13
Iterator End(void) const
Iterator Begin(void) const
NameSet EventSet
void LanguageDiagnoser(const System &rGen, const System &rSpec, Diagnoser &rDiagGen)
void LoopPreservingObserver(const System &rGen, const EventSet &rInitialHighAlph, EventSet &rHighAlph)
TcGenerator< AttributeVoid, AttributeVoid, AttributeCFlags, AttributeVoid > System
void aParallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
void Project(const Generator &rGen, const EventSet &rProjectAlphabet, Generator &rResGen)
void Parallel(const Generator &rGen1, const Generator &rGen2, Generator &rResGen)
uint32_t Idx
bool ModularDiagnoser(const SystemVector &rGsubs, const GeneratorVector &rKsubs, GeneratorVector &rDiagSubs, string &rReportString)
bool IsLanguageDiagnosable(const System &rGen, const System &rSpec)
TdiagGenerator< AttributeFailureTypeMap, AttributeDiagnoserState, AttributeCFlags, AttributeVoid > Diagnoser
void cParallel(const std::vector< const System * > &rGens, System &rResGen)
bool IsModularDiagnosable(const SystemVector &rGsubs, const GeneratorVector &rKsubs, string &rReportString)
std::string ToStringInteger(Int number)
Definition cfl_utils.cpp:43

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