syn_tsupcon.cpp
Go to the documentation of this file.
1/** @file syn_tsupcon.cpp Supremal TDES-controllable sublanguage */
2
3/* FAU Discrete Event Systems Library (libfaudes)
4
5 Copyright (C) 2013 Thomas Moor
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
20
21
22#include "syn_tsupcon.h"
23
24
25namespace faudes {
26
27
28
29
30/*
31***************************************************************************************
32***************************************************************************************
33 Implementation
34***************************************************************************************
35***************************************************************************************
36*/
37
38
39// SupTconUnchecked(rPlantGen, rCAlph, rFAlph, rPAlph, rCPAlph, rSupCandGen)
41 const Generator& rPlantGen, // aka G
42 const EventSet& rCAlph,
43 const EventSet& rFAlph,
44 const EventSet& rPAlph,
45 const EventSet& rCPAlph,
46 Generator& rSupCandGen // aka H
47)
48{
49 FD_DF("SupTconUnchecked(" << &rSupCandGen << "," << &rPlantGen << ")");
50
51 // bail out if plant or candidate contain no initial states
52 if(rPlantGen.InitStatesEmpty() || rSupCandGen.InitStatesEmpty())
53 return;
54
55 // todo stack (pairs of states)
56 std::stack<Idx> todog, todoh;
57 // set of already processed states of H (this is why we need H-states)
58 StateSet processed;
59
60 // critical states
61 StateSet critical;
62
63 // push combined initial state on todo stack
64 todog.push(*rPlantGen.InitStatesBegin());
65 todoh.push(*rSupCandGen.InitStatesBegin());
66 FD_DF("SupCon: todo push: (" << rPlantGen.SStr(*rPlantGen.InitStatesBegin()) << "|"
67 << rSupCandGen.SStr(*rSupCandGen.InitStatesBegin()) << ")");
68
69 // process todo stack
70 while(!todog.empty()) {
71 // allow for user interrupt
72 // LoopCallback();
73 // allow for user interrupt, incl progress report
74 FD_WPC(1,2,"TdesControllability(): iterating states");
75 // get top element from todo stack
76 Idx currentg = todog.top();
77 Idx currenth = todoh.top();
78 todog.pop();
79 todoh.pop();
80 FD_DF("SupCon: todo pop: (" << rPlantGen.SStr(currentg) << "|"
81 << rSupCandGen.SStr(currenth) << ")");
82
83 // break on doublets (tmoor 201104)
84 if(processed.Exists(currenth)) continue;
85 processed.Insert(currenth);
86
87#ifdef FAUDES_DEBUG_FUNCTION
88 TransSet::Iterator _titg, _tith;
89 // print all transitions of current states
90 FD_DF("SupCon: transitions from current states:");
91 for (_titg = rPlantGen.TransRelBegin(currentg); _titg != rPlantGen.TransRelEnd(currentg); ++_titg)
92 FD_DF("SupCon: g: " << rPlantGen.SStr(_titg->X1) << "-"
93 << rPlantGen.EStr(_titg->Ev) << "-" << rPlantGen.SStr(_titg->X2));
94 for (_tith = rSupCandGen.TransRelBegin(currenth); _tith != rSupCandGen.TransRelEnd(currenth); ++_tith)
95 FD_DF("SupCon: h: " << rSupCandGen.SStr(_tith->X1) << "-"
96 << rSupCandGen.EStr(_tith->Ev) << "-" << rSupCandGen.SStr(_tith->X2));
97#endif
98
99 // loop vars
100 TransSet::Iterator tith, tith_end, titg, titg_end;
101
102 // test current state ...
103 bool pass=false;
104
105 // 1. figure disabled in the plant g by the loop g x h
106 EventSet disabled;
107 tith = rSupCandGen.TransRelBegin(currenth);
108 tith_end = rSupCandGen.TransRelEnd(currenth);
109 titg = rPlantGen.TransRelBegin(currentg);
110 titg_end = rPlantGen.TransRelEnd(currentg);
111 while( (tith != tith_end) && (titg != titg_end)) {
112 if(tith->Ev > titg->Ev) {
113 disabled.Insert(titg->Ev);
114 ++titg;
115 } else if(tith->Ev == titg->Ev) {
116 ++titg;
117 ++tith;
118 } else {
119 ++tith; // cannot happen
120 }
121 }
122
123 // 2. pass, if all disabled are controllable
124 if(disabled <= rCAlph) {
125 pass=true;
126 }
127
128 // 3. is a forcible event enabled for the loop g x h ?
129 bool fenabled=false;
130 if(!pass) {
131 tith = rSupCandGen.TransRelBegin(currenth);
132 tith_end = rSupCandGen.TransRelEnd(currenth);
133 titg = rPlantGen.TransRelBegin(currentg);
134 titg_end = rPlantGen.TransRelEnd(currentg);
135 while( (tith != tith_end) && (titg != titg_end)) {
136 if(tith->Ev > titg->Ev) {
137 ++titg;
138 } else if(tith->Ev == titg->Ev) {
139 if(rFAlph.Exists(titg->Ev)) {fenabled=true; break;}
140 ++titg;
141 ++tith;
142 } else {
143 ++tith; // cannot happen
144 }
145 }
146 }
147
148 // 4. pass if all uncontr. disabled events are preempted by a forcible event
149 if((!pass) && fenabled) {
150 if(disabled <= rCPAlph) pass=true;
151 }
152
153 // 5. record non-passed as critical
154 if(!pass) {
155 critical.Insert(currenth);
156 FD_DF("SupCon: todo pop: (" << rPlantGen.SStr(currentg) << "|"
157 << rSupCandGen.SStr(currenth) << "): FAIL");
158 continue;
159 }
160
161 // 6. if passed, stack successor state
162 if(pass) {
163 // process all h transitions while there could be matching g transitions
164 titg = rPlantGen.TransRelBegin(currentg);
165 titg_end = rPlantGen.TransRelEnd(currentg);
166 tith = rSupCandGen.TransRelBegin(currenth);
167 tith_end = rSupCandGen.TransRelEnd(currenth);
168 while ((tith != tith_end) && (titg != titg_end)) {
169 // increment tith and titg case A: process common events
170 if(titg->Ev == tith->Ev) {
171 FD_DF("SupCon: processing common event " << rPlantGen.EStr(titg->Ev));
172 // add to todo list if state not processed (tmoor 201104: record next H state on stack)
173 if(!processed.Exists(tith->X2)) {
174 todog.push(titg->X2);
175 todoh.push(tith->X2);
176 FD_DF("SupCon: todo push: (" << rPlantGen.SStr(titg->X2) << "|"
177 << rSupCandGen.SStr(tith->X2) << ")");
178 }
179 FD_DF("SupCon: incrementing g and h transrel");
180 ++titg;
181 ++tith;
182 }
183 // increment tith and titg case B: process g event that is not enabled in h
184 else if (titg->Ev < tith->Ev) {
185 FD_DF("SupCon: incrementing g transrel");
186 ++titg;
187 }
188 // increment tith and titg case C: process h event that is not enabled in g
189 else {
190 FD_DF("SupCon: incrementing h transrel"); // cannot happen
191 ++tith;
192 }
193 } // end while tith and titg
194 } // end if passed
195
196 } //end while todo
197
198
199 // remove all states that have been identified as critical or that have
200 // been not processed
201 critical = rSupCandGen.States() - ( processed - critical );
202 rSupCandGen.DelStates(critical);
203}
204
205
206
207
208
209
210// SupTconUnchecked(rPlantGen, rCAlph, rFAlph, rPAlph, rSpecGen, rCompositionMap, rResGen)
212 const Generator& rPlantGen,
213 const EventSet& rCAlph,
214 const EventSet& rFAlph,
215 const EventSet& rPAlph,
216 const Generator& rSpecGen,
217 std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap,
218 Generator& rResGen)
219{
220 FD_DF("SupTcon(" << &rPlantGen << "," << &rSpecGen << ")");
221
222 // PREPARE RESULT:
223 Generator* pResGen = &rResGen;
224 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
225 pResGen= rResGen.New();
226 }
227 pResGen->Clear();
228 pResGen->Name(CollapsString("SupTcon(("+rPlantGen.Name()+"),("+rSpecGen.Name()+"))"));
229 pResGen->InjectAlphabet(rPlantGen.Alphabet());
230
231 // controllable events
232 FD_DF("SupTcon: controllable events: " << rCAlph.ToString());
233 FD_DF("SupTcon: forcible events: " << rFAlph.ToString());
234 FD_DF("SupTcon: preemptyble events: " << rPAlph.ToString());
235
236 // weakly controllable
237 EventSet cpalph = rCAlph + rPAlph;
238
239 // ALGORITHM:
240 FD_DF("SupTcon(): SupConProduct on #" << rPlantGen.Size() << "/ #" << rSpecGen.Size());
241 SupConProduct(rPlantGen, cpalph, rSpecGen, rCompositionMap, *pResGen);
242
243
244 // make resulting generator trim until it's fully tdes controllable
245 while(true) {
246 if(pResGen->Empty()) break;
247 Idx state_num = pResGen->Size();
248 FD_DF("SupTcon(): SupConClosed on #" << rPlantGen.Size() << "/ #" << pResGen->Size());
249 SupConClosedUnchecked(rPlantGen, cpalph, *pResGen);
250 FD_DF("SupTcon(): SupTcon on #" << rPlantGen.Size() << "/ #" << pResGen->Size());
251 SupTconUnchecked(rPlantGen, rCAlph, rFAlph, rPAlph, cpalph, *pResGen);
252 FD_DF("SupTcon(): Trim on #" << pResGen->Size());
253 pResGen->Trim();
254 if(pResGen->Size() == state_num) break;
255 }
256
257 // convenience state names
258 if(rPlantGen.StateNamesEnabled() && rSpecGen.StateNamesEnabled() && rResGen.StateNamesEnabled())
259 SetComposedStateNames(rPlantGen, rSpecGen, rCompositionMap, *pResGen);
260 else
261 pResGen->StateNamesEnabled(false);
262
263 // copy result
264 if(pResGen != &rResGen) {
265 pResGen->Move(rResGen);
266 delete pResGen;
267 }
268
269}
270
271
272
273// SupTcon(rPlantGen, rCAlph, rFAlph, rSpecGen, rResGen)
275 const Generator& rPlantGen,
276 const EventSet& rCAlph,
277 const EventSet& rFAlph,
278 const EventSet& rPAlph,
279 const Generator& rSpecGen,
280 Generator& rResGen)
281{
282
283 // CONSISTENCY CHECK:
284 ControlProblemConsistencyCheck(rPlantGen, rCAlph, rSpecGen);
285
286 // HELPERS:
287 std::map< std::pair<Idx,Idx>, Idx> rcmap;
288
289 // ALGORITHM:
290 SupTconUnchecked(rPlantGen, rCAlph, rFAlph, rPAlph, rSpecGen, rcmap, rResGen);
291}
292
293
294
295// supcon for Systems
296// uses and maintains controllablity from plant
298 const System& rPlantGen,
299 const Generator& rSpecGen,
300 Generator& rResGen) {
301
302 // prepare result
303 Generator* pResGen = &rResGen;
304 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
305 pResGen= rResGen.New();
306 }
307
308 // default preemptable but not controllable
309 EventSet palph;
310 palph.Insert("tick");
311 EventSet calph(rPlantGen.ControllableEvents());
312 calph=calph - palph;
313
314 // execute
315 SupTcon(rPlantGen, calph, rPlantGen.ForcibleEvents(), palph, rSpecGen,*pResGen);
316
317 // copy all attributes of input alphabet
318 pResGen->EventAttributes(rPlantGen.Alphabet());
319
320 // copy result
321 if(pResGen != &rResGen) {
322 pResGen->Move(rResGen);
323 delete pResGen;
324 }
325
326}
327
328} // name space
#define FD_WPC(cntnow, contdone, message)
#define FD_DF(message)
const std::string & Name(void) const
bool Exists(const Idx &rIndex) const
bool Insert(const Idx &rIndex)
const TaEventSet< EventAttr > & Alphabet(void) const
EventSet ControllableEvents(void) const
EventSet ForcibleEvents(void) const
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
StateSet::Iterator InitStatesBegin(void) const
const EventSet & Alphabet(void) const
virtual void Move(vGenerator &rGen)
bool InitStatesEmpty(void) const
TransSet::Iterator TransRelBegin(void) const
virtual vGenerator * New(void) const
void DelStates(const StateSet &rDelStates)
TransSet::Iterator TransRelEnd(void) const
std::string EStr(Idx index) const
bool Empty(void) const
virtual void EventAttributes(const EventSet &rEventSet)
bool StateNamesEnabled(void) const
Idx Size(void) const
std::string SStr(Idx index) const
virtual void Clear(void)
const StateSet & States(void) const
void InjectAlphabet(const EventSet &rNewalphabet)
bool Exists(const T &rElem) const
void SupTcon(const Generator &rPlantGen, const EventSet &rCAlph, const EventSet &rFAlph, const EventSet &rPAlph, const Generator &rSpecGen, Generator &rResGen)
uint32_t Idx
void SetComposedStateNames(const Generator &rGen1, const Generator &rGen2, const std::map< std::pair< Idx, Idx >, Idx > &rCompositionMap, Generator &rGen12)
void ControlProblemConsistencyCheck(const GeneratorVector &rPlantGenVec, const EventSet &rConAlph, const GeneratorVector &rSpecGenVec)
void SupTconUnchecked(const Generator &rPlantGen, const EventSet &rCAlph, const EventSet &rFAlph, const EventSet &rPAlph, const EventSet &rCPAlph, Generator &rSupCandGen)
void SupConClosedUnchecked(const Generator &rPlantGen, const EventSet &rCAlph, Generator &rSupCandGen)
void SupConProduct(const Generator &rPlantGen, const EventSet &rCAlph, const Generator &rSpecGen, std::map< std::pair< Idx, Idx >, Idx > &rCompositionMap, Generator &rResGen)
std::string CollapsString(const std::string &rString, unsigned int len)
Definition cfl_utils.cpp:91

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