54 std::vector< std::vector<Idx> >
pre;
62 std::string
setstr(
const std::set<Idx>& sset) {
63 std::set<Idx>::iterator ssit;
64 std::stringstream str;
66 for(ssit = sset.begin(); ssit != sset.end(); ++ssit)
76 std::vector< std::vector<Idx> >
blocks;
93 throw Exception(
"StateMin",
"input automaton non-deterministic", 101);
101 std::map<Idx,Idx> smap;
102 std::map<Idx,Idx> emap;
112 StateSet::Iterator sit=acc.
Begin();
113 for(; sit != acc.
End(); ++sit) {
120 if(!acc.
Exists(tit->X1))
continue;
121 if(!acc.
Exists(tit->X2))
continue;
122 states[smap[tit->X2]].pre[emap[tit->Ev]].push_back(smap[tit->X1]);
125 FD_DF(
"Hopcroft::Initialize(): states #" <<
states.size()-1);
146 if(
states.size()-1 == 0) {
147 FD_DF(
"Hopcroft::Minimize(): generator size 0");
152 if(
states.size()-1 == 1) {
153 FD_DF(
"Hopcroft::Minimize(): generator size 1");
161 std::stack<Idx> active;
162 std::vector<Idx>::iterator ssit;
163 std::vector<Idx>::iterator ssit_end;
165 std::vector<Idx> dpp;
171 std::vector<Idx> bnm;
174 else bnm.push_back(q);
177 blocks.push_back(std::vector<Idx>());
179 active.push(
blocks.size()-1);
180 FD_DF(
"Hopcroft::Minimize(): initial partition not-marked #" <<
blocks.back().size());
183 blocks.push_back(std::vector<Idx>());
185 active.push(
blocks.size()-1);
186 FD_DF(
"Hopcroft::Minimize(): initial partition not-marked #" <<
blocks.back().size());
190 while(!active.empty()) {
191 FD_WPC(
blocks.size()-active.size(),
blocks.size(),
"StateMin: blocks/active: " <<
blocks.size() <<
" / " << active.size());
192 FD_DF(
"Hopcroft::Minimize(): active blocks #" << active.size());
195 std::vector<Idx> b_current(
blocks.at(active.top()));
196 FD_DF(
"StateMin: getting active block B[" << active.top() <<
"] = { #" << b_current.size() <<
"}");
201 for(; ev!=
events.size(); ++ev){
204 ssit = b_current.begin();
205 ssit_end = b_current.end();
206 for(; ssit != ssit_end; ++ssit) {
208 std::vector<Idx>& preevx2=
states[*ssit].pre[ev];
209 std::vector<Idx>::iterator rit = preevx2.begin();
210 std::vector<Idx>::iterator rit_end = preevx2.end();
211 for (; rit != rit_end; ++rit) c.push_back(*rit);
213 std::sort(c.begin(),c.end());
215 if(c.empty())
continue;
217 FD_DF(
"StateMin: computed predecessor states C = {#" << c.size() <<
"} for event " <<
gen->
EventName(
events[ev]));
221 const std::vector<Idx>& d_current =
blocks[j];
223 if(d_current.size()==1)
continue;
224 FD_DF(
"StateMin: examining block D=B[" << j <<
"] = {#" << d_current.size() <<
"}");
227 std::set_intersection(d_current.begin(), d_current.end(), c.begin(), c.end(),
228 std::inserter(dp, dp.begin()));
230 if(dp.empty() || (dp.size()==d_current.size()))
continue;
231 FD_DF(
"StateMin: -> split:");
234 std::set_difference(d_current.begin(), d_current.end(), dp.begin(), dp.end(),
235 std::inserter(dpp,dpp.begin()));
237 if(dp.size() < dpp.size()) dp.swap(dpp);
241 blocks.push_back(std::vector<Idx>());
243 FD_DF(
"StateMin: new block D' as B[" << j <<
"] = " <<
setstr(dp));
244 FD_DF(
"StateMin: new block D'' as B[" <<
blocks.size()-1 <<
"] = " <<
setstr(dpp));
263 FD_DF(
"Hopcroft:Partition: building minimized generator #" <<
blocks.size());
271 pResGen->Name(
gen->
Name()+
" [minstate]");
276 std::map<Idx,Idx> minstatemap;
281 pResGen->InsState(newstate);
282 FD_DF(
"StateMin: block " <<
setstr(
blocks.at(i)) <<
" -> new state " << newstate);
283 std::ostringstream ostr;
284 std::vector<Idx>::iterator ssit =
blocks[i].begin();
285 std::vector<Idx>::iterator ssit_end =
blocks[i].end();
286 for(; ssit != ssit_end; ++ssit) {
289 minstatemap[orgstate] = newstate;
296 pResGen->SetInitState(newstate);
297 FD_DF(
"StateMin: -> initial state");
301 pResGen->SetMarkedState(newstate);
302 FD_DF(
"StateMmin: -> marked state");
306 std::string statename = ostr.str();
307 if(statename!=
"") statename.erase(statename.length()-1);
308 statename =
"{" + statename +
"}";
309 pResGen->StateName(newstate, statename);
315 std::map<Idx,Idx>::iterator xit1=minstatemap.find(tit->X1);
316 std::map<Idx,Idx>::iterator xit2=minstatemap.find(tit->X2);
317 if(xit1==minstatemap.end())
continue;
318 if(xit2==minstatemap.end())
continue;
319 pResGen->SetTransition(xit1->second, tit->Ev, xit2->second);
323 if(pResGen != &rResGen) {
324 pResGen->Move(rResGen);
337 void Partition(std::vector< StateSet >& rSubsets, std::vector<Idx>& rNewIndices){
339 FD_DF(
"Hopcroft:Partition: returning blocks #" <<
blocks.size());
345 rNewIndices.push_back(newstate);
347 std::vector<Idx>::iterator ssit =
blocks[i].begin();
348 std::vector<Idx>::iterator ssit_end =
blocks[i].end();
350 for(; ssit != ssit_end; ++ssit) {
352 block.Insert(orgstate);
354 rSubsets.push_back(block);
376 std::vector<StateSet>& rSubsets, std::vector<Idx>& rNewIndices) {
377 FD_DF(
"StateMin: *** computing state space minimization of generator "
380 FD_DF(
"StateMin: restrict to accessible states");
384 if(acc.
Size() == 0) {
385 FD_DF(
"StateMin: generator size 0. returning given generator");
390 if(rGen.
Size() == 1) {
391 FD_DF(
"StateMin: generator size 1. returning given generator");
394 rSubsets.push_back(rResGen.
States() );
395 rNewIndices.push_back(*( rResGen.
States().
Begin() ) );
400 #ifdef FAUDES_CHECKED
402 throw Exception(
"StateMin",
"input automaton nondeterministic", 101);
409 if(&rResGen==&rGen) {
410 pResGen= pResGen->
New();
415 pResGen->
Name(rGen.
Name()+
" [minstate]");
419 std::vector<StateSet>& b = rSubsets;
422 std::set<Idx> active;
423 std::set<Idx>::iterator ait;
429 StateSet::Iterator sit;
436 if(marked.
Size() > 0) {
437 FD_DF(
"StateMin: new block B[" << i <<
"] = {" << marked.
ToString() <<
"}");
442 if(notmarked.
Size() > 0) {
443 notmarked.
Name(
"B[i]");
444 FD_DF(
"StateMin: new block B[" << i <<
"] = {" << notmarked.
ToString() <<
"}");
445 b.push_back(notmarked);
452 while(! active.empty()) {
453 FD_WPC(b.size()-active.size(), b.size(),
"StateMin: blocks/active: " << b.size() <<
" / " << active.size());
454 #ifdef FAUDES_DEBUG_FUNCTION
455 FD_DF(
"StateMin: while there is an active block B...");
456 std::set<Idx>::iterator _it1;
457 std::stringstream str;
458 for (_it1 = active.begin(); _it1 != active.end(); ++_it1) {
461 FD_DF(
"StateMin: active: "+str.str());
462 std::vector<StateSet>::iterator _it2;
465 for (_it2 = b.begin(); _it2 != b.end(); ++_it2) {
466 str <<
"{" << _it2->ToString() <<
"} "<<std::endl;
469 FD_DF(
"B: "+str.str());
472 i = *(active.begin());
474 active.erase(active.begin());
475 FD_DF(
"StateMin: getting active block B[" << i <<
"] = {" <<
476 b.at(i).ToString() <<
"}");
482 EventSet::Iterator eit;
487 for (sit = b_current.Begin(); sit != b_current.End(); ++sit) {
490 rtit_end = rtransrel.
EndByEvX2(*eit, *sit);
491 for (; rtit != rtit_end; ++rtit) {
496 if(c.
Empty())
continue;
498 FD_DF(
"StateMin: computed predecessor states C = {" << c.
ToString()
499 <<
"} for event " << rGen.
EventName(*eit));
501 for (j=0; j < b.size(); ++j) {
503 const StateSet& d_current = b.at(j);
504 FD_DF(
"StateMin: examining block B[" << j <<
"] = {" <<
510 if(d_.Empty() || (d_.Size()==d_current.
Size())) {
511 FD_DF(
"StateMin: -> no split");
514 FD_DF(
"StateMin: -> split:");
521 FD_DF(
"StateMin: new block B[" << j <<
"] = {" << d_.ToString() <<
"}");
522 FD_DF(
"StateMin: new block B[" << b.size()-1 <<
"] = {" << d__.
ToString() <<
"}");
524 if(active.find(j) != active.end()) {
525 active.insert((
Idx)b.size()- 1);
526 FD_DF(
"StateMin: mark active: " << b.size()-1);
530 if (d_.Size() < d__.
Size()) {
532 FD_DF(
"StateMin: mark active: " << j);
534 active.insert((
Idx)b.size()-1);
535 FD_DF(
"StateMin: mark active: " << b.size()-1);
542 FD_DF(
"StateMin: *** building minimized generator ***");
544 std::map<Idx,Idx> minstatemap;
547 for (i = 0; i < b.size(); ++i) {
550 rNewIndices.push_back(newstate);
551 FD_DF(
"StateMin: block {" << b.at(i).ToString()
552 <<
"} -> new state " << newstate);
553 std::ostringstream ostr;
554 for (sit = b.at(i).Begin(); sit != b.at(i).End(); ++sit) {
556 minstatemap[*sit] = newstate;
568 FD_DF(
"StateMin: -> initial state");
573 FD_DF(
"StatMmin: -> marked state");
577 std::string statename = ostr.str();
578 if(statename!=
"") statename.erase(statename.length()-1);
579 statename =
"{" + statename +
"}";
585 if(!acc.
Exists(tit->X1))
continue;
586 if(!acc.
Exists(tit->X2))
continue;
587 pResGen->
SetTransition(minstatemap[tit->X1], tit->Ev, minstatemap[tit->X2]);
588 FD_DF(
"statemin: adding transition: "
589 << minstatemap[tit->X1] <<
"-" << tit->Ev <<
"-"
590 << minstatemap[tit->X2]);
594 if(pResGen != &rResGen) {
595 pResGen->
Move(rResGen);
621 std::vector< StateSet >& rSubsets, std::vector<Idx>& rNewIndices){