mtc_statemin.cpp
Go to the documentation of this file.
1/** @file mtc_statemin.cpp
2
3State space minimization
4
5*/
6
7/* FAU Discrete Event Systems Library (libfaudes)
8
9 Copyright (C) 2008 Matthias Singer
10 Copyright (C) 2006 Bernd Opitz
11 Exclusive copyright is granted to Klaus Schmidt
12
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 2.1 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
26
27#include "mtc_statemin.h"
28
29namespace faudes {
30
31// mtcStateMin(rGen, rResGen)
32void mtcStateMin(MtcSystem& rGen, MtcSystem& rResGen) {
33 std::vector<StateSet> subsets;
34 std::vector<Idx> newindices;
35 mtcStateMin(rGen, rResGen, subsets, newindices);
36}
37
38// mtcStateMin(rGen, rResGen, rSubSets, rNewIndices)
39void mtcStateMin(MtcSystem& rGen, MtcSystem& rResGen,
40 std::vector<StateSet>& rSubsets, std::vector<Idx>& rNewIndices) {
41 FD_DF("statemin: *** computing state space minimization of multi-tasking generator "
42 << &rGen << " ***");
43 FD_DF("statemin: making generator accessible");
44#ifdef FAUDES_DEBUG_FUNCTION
45 FD_WARN("mtcStateMin: debug out")
46 rGen.Write("tmp_smin_m.gen");
47#endif
48 // make accessible
49 rGen.Accessible();
50#ifdef FAUDES_DEBUG_FUNCTION
51 FD_WARN("mtcStateMin: debug out")
52 rGen.Write("tmp_smin_a.gen");
53#endif
54
55
56 if (rGen.Size() < 2) {
57 FD_DF("statemin: generator size < 2. returning given generator");
58 //rGen.Copy(rResGen); changed !! test
59 rResGen = rGen;
60 rSubsets.push_back(rGen.States() );
61 rNewIndices.push_back(*( rResGen.States().Begin() ) );
62 return;
63 }
64
65 // ensure generator is deterministic
66 if (! rGen.IsDeterministic()) {
67 throw Exception("mtcStateMin", "input automaton nondeterministic", 505);
68 }
69
70 // prepare result
71 rResGen.Clear();
72 rResGen.Name(rGen.Name()+" [mtc minstate]");
73
74 rResGen.ClearStateAttributes();
75 rResGen.InjectAlphabet(rGen.Alphabet());
76
77 rResGen.SetControllable(rGen.ControllableEvents());
78 rResGen.SetForcible(rGen.ForcibleEvents());
79 rResGen.ClrObservable(rGen.UnobservableEvents());
80
81
82 // blocks B[i]
83 std::vector<StateSet>& b = rSubsets; // convenience notation "b"
84 Idx i, j;
85 // set of active b (iterators)
86 std::set<Idx> active;
87 std::set<Idx>::iterator ait;
88 // reverse transrel
89 TransSetEvX2X1 rtransrel;
90 rGen.TransRel(rtransrel);
91 TransSetEvX2X1::Iterator rtit, rtit_end;
92 // other stuff
93 StateSet::Iterator lit;
95
96 // set up b "B[i]"
97 i = 0;
98
99#ifdef FAUDES_DEBUG_FUNCTION
100 FD_WARN("mtcStateMin: debug out: states");
101 rGen.States().Write();
102 FD_WARN("mtcStateMin: debug out: colored states");
103 rGen.ColoredStates().Write();
104 FD_WARN("mtcStateMin: debug out: unolored states");
105 rGen.UncoloredStates().Write();
106#endif
107
108 if (rGen.UncoloredStates().Size() > 0) {
109 b.push_back(rGen.UncoloredStates());
110 active.insert(i++);
111 FD_DF("statemin: new block B[" << i-1 << "] = {" <<
112 (rGen.UncoloredStates()).ToString() << "}");
113 }
114 // find states that have the same associated colors
115 std::map<Idx,ColorSet> stateColorMap = rGen.StateColorMap();
116 std::map<Idx,ColorSet>::const_iterator sit_end = stateColorMap.end();
117 std::map<ColorSet,StateSet> SameColors;
118 std::map<ColorSet,StateSet>::iterator csit;
119 std::map<Idx,ColorSet>::const_iterator sit;
120
121 for(sit = stateColorMap.begin(); sit != sit_end; ++sit){
122 csit = SameColors.find(sit->second);
123 FD_DF("stateColorMap, state: " << ToStringInteger(sit->first) << ", colors: " << (sit->second).ToString());
124 if(csit != SameColors.end() )
125 csit->second.Insert(sit->first);
126 else{
127 StateSet NewStateSet;
128 NewStateSet.Insert(sit->first);
129 SameColors[sit->second] = NewStateSet;
130 }
131 }
132
133 // create the initial set of equivalence classes
134 std::map<ColorSet,StateSet>::const_iterator csit_end = SameColors.end();
135 for(csit = SameColors.begin(); csit != csit_end; ++csit){
136 b.push_back(csit->second); // Colored StateSets
137 active.insert(i++);
138 FD_DF("statemin: new block B[" << i-1 << "] = {" <<
139 csit->second.ToString() << "}");
140 }
141
142 // while there is an active block B
143 while (! active.empty()) {
144 FD_WP("mtcStateMin: blocks/active: " << b.size() << " / " << active.size());
145#ifdef FD_DF
146 FD_DF("statemin: if there is an active block B...");
147 std::set<Idx>::iterator _it1;
148 std::stringstream str;
149 for (_it1 = active.begin(); _it1 != active.end(); ++_it1) {
150 str << *_it1 << " ";
151 }
152 FD_DF("active: "+str.str());
153 std::vector<StateSet>::iterator _it2;
154 str.clear();
155 for (_it2 = b.begin(); _it2 != b.end(); ++_it2) {
156 str << "{" << _it2->ToString() << "} ";
157 }
158 str << std::endl;
159 FD_DF("B: "+str.str());
160#endif
161 // current block B[i]
162 i = *(active.begin());
163 // inactivate B[i]
164 active.erase(active.begin());
165 FD_DF("statemin: getting active block B[" << i << "] = {" <<
166 b.at(i).ToString() << "}");
167 // b_current <- B[i]
168 StateSet b_current = b.at(i);
169
170 // compute C = f^-1(B[i]) for every event in B[i] (as b_current)
171 StateSet c;
172 EventSet::Iterator eit;
173 // iteration over alphabet
174 for (eit = rGen.AlphabetBegin(); eit != rGen.AlphabetEnd(); ++eit) {
175 c.Clear();
176 // iteration over states in current block
177 for (lit = b_current.Begin(); lit != b_current.End(); ++lit) {
178 // find predecessor states by current ev + x2
179 rtit = rtransrel.BeginByEvX2(*eit, *lit);
180 rtit_end = rtransrel.EndByEvX2(*eit, *lit);
181 for (; rtit != rtit_end; ++rtit) {
182 c.Insert(rtit->X1);
183 }
184 }
185 // if predecessor states where found
186 if (! c.Empty()) {
187 // search for new block on next event or coming end of rtransrel with
188 // x1 as *lit
189 FD_DF("statemin: computed predecessor states C = {" << c.ToString()
190 << "} for event " << rGen.EventName(*eit));
191
192 // foreach block D
193 for (j=0; j < b.size(); ++j) {
194 FD_DF("statemin: examining block B[" << j << "] = {" <<
195 b.at(j).ToString() << "}");
196 // compute D' = D intersection C
197 StateSet d_ = b.at(j) * c;
198 // compute D'' = D - D'; remove D, add D''
199 StateSet d__ = b.at(j) - d_;
200 // check D split by B
201 if (d_.Empty() || d__.Empty()) {
202 FD_DF("statemin: -> no split");
203 continue;
204 }
205 FD_DF("statemin: -> split:");
206 b[j] = d_;
207 FD_DF("statemin: new block B[" << j << "] = {"
208 << d_.ToString() << "}");
209 b.push_back(d__);
210 FD_DF("statemin: new block B[" << b.size()-1 << "] = {"
211 << d__.ToString() << "}");
212 // if D was active
213 if (active.count(j) > 0) {
214 // then mark both D', D'' active
215 active.insert((Idx)b.size()- 1);
216 FD_DF("statemin: mark active: " << b.size()-1);
217 }
218 // else mark smaller of D', D'' active
219 else {
220 if (d_.Size() < d__.Size()) {
221 active.insert(j);
222 FD_DF("statemin: mark active: " << j);
223 }
224 else {
225 active.insert((Idx)b.size()-1);
226 FD_DF("statemin: mark active: " << b.size()-1);
227 }
228 }
229 } // foreach block D
230 c.Clear();
231 }
232 }
233 }
234
235 FD_DF("statemin: *** building minimized generator ***");
236 // build minimized generator
237 std::map<Idx,Idx> minstatemap;
238 Idx newstate;
239 // loop over all blocks B
240 for (i = 0; i < b.size(); i++) {
241 // create state in new generator for every block
242 newstate = rResGen.InsState();
243 rNewIndices.push_back(newstate);
244 FD_DF("statemin: block {" << b.at(i).ToString()
245 << "} -> new state " << newstate);
246 std::ostringstream ostr;
247 Idx count = 0;
248 for (lit = b.at(i).Begin(); lit != b.at(i).End(); lit++) {
249 count++;
250 // set minstatemap entry for every state in gen
251 minstatemap[*lit] = newstate;
252 if (rResGen.StateNamesEnabled()) {
253 FD_DF("StateNamesEnabled: index: \""<< ToStringInteger(*lit) << "\", name: \"" << rGen.StateName(*lit) << "\"");
254 if (rGen.StateName(*lit) == "") {
255 ostr << ToStringInteger(*lit) << ",";
256 FD_DF("StateName \"\", ostr = " << ostr.str());
257 }
258 else {
259 ostr << rGen.StateName(*lit) << ",";
260 FD_DF("StateName exists, ostr = " << ostr.str());
261 }
262 }
263 // set istates
264 if (rGen.ExistsInitState(*lit)) {
265 rResGen.SetInitState(newstate);
266 FD_DF("statemin: -> initial state");
267 }
268 if(count == 1){ //all states in b.at(i) have the same colors
269 std::map<Idx,ColorSet>::const_iterator col_it;
270 col_it = stateColorMap.find(*lit);
271 // are there any colors to set for the current state?
272 if (col_it != stateColorMap.end()) {
273 // insert corresponding colors if they are not already set for the current state
274 FD_DF("mtcStateMin: insert colors " << col_it->second.ToString() << " to state " << newstate);
275 rResGen.InsColors(newstate, col_it->second);
276 }
277 }
278 }
279 if (rResGen.StateNamesEnabled()) {
280 std::string statename = ostr.str();
281 statename.erase(statename.length()-1);
282 statename = "{" + statename + "}";
283 FD_DF("Set state name: name: \"" << statename << "\", index: \"" << newstate << "\"");
284 rResGen.StateName(newstate, statename);
285 }
286 }
287 // create transition relation
288 for (tit = rGen.TransRelBegin(); tit != rGen.TransRelEnd(); ++tit) {
289 rResGen.SetTransition(minstatemap[tit->X1], tit->Ev, minstatemap[tit->X2]);
290 FD_DF("statemin: adding transition: "
291 << minstatemap[tit->X1] << "-" << tit->Ev << "-"
292 << minstatemap[tit->X2]);
293 }
294#ifdef FAUDES_DEBUG_FUNCTION
295 FD_WARN("mtcStateMin: debug out: result")
296 rResGen.Write("tmp_smin_r.gen");
297#endif
298}
299
300// RTI wrapper
301void mtcStateMin(const MtcSystem& rGen, MtcSystem& rResGen) {
302 MtcSystem gen(rGen);
303 mtcStateMin(gen,rResGen);
304
305 FD_WARN("mtcStateMin: debug out")
306 rGen.GraphWrite("tmp_smin_w.png");
307 rGen.DotWrite("tmp_smin_w.dot");
308
309}
310
311} // namespace faudes
#define FD_WARN(message)
#define FD_DF(message)
#define FD_WP(message)
const std::string & Name(void) const
Iterator EndByEvX2(Idx ev, Idx x2) const
Iterator BeginByEvX2(Idx ev, Idx x2) const
virtual void Clear(void)
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 InjectAlphabet(const EventSet &rNewalphabet)
void ClrObservable(Idx index)
EventSet ControllableEvents(void) const
void SetControllable(Idx index)
EventSet ForcibleEvents(void) const
void SetForcible(Idx index)
EventSet UnobservableEvents(void) const
void InsColors(Idx stateIndex, const ColorSet &rColors)
StateSet ColoredStates(Idx colorIndex) const
virtual void DotWrite(const std::string &rFileName) const
std::map< Idx, ColorSet > StateColorMap(void) const
StateSet UncoloredStates() const
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
void Write(const Type *pContext=0) const
TransSet::Iterator TransRelBegin(void) const
EventSet::Iterator AlphabetBegin(void) const
void SetInitState(Idx index)
std::string StateName(Idx index) const
TransSet::Iterator TransRelEnd(void) const
bool IsDeterministic(void) const
bool StateNamesEnabled(void) const
void GraphWrite(const std::string &rFileName, const std::string &rOutFormat="", const std::string &rDotExec="dot") const
std::string EventName(Idx index) const
EventSet::Iterator AlphabetEnd(void) const
Idx Size(void) const
bool ExistsInitState(Idx index) const
bool Empty(void) const
virtual void Clear(void)
Iterator End(void) const
Iterator Begin(void) const
Idx Size(void) const
uint32_t Idx
void mtcStateMin(MtcSystem &rGen, MtcSystem &rResGen)
std::string ToStringInteger(Int number)
Definition cfl_utils.cpp:43

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