54 std::vector< std::vector<Idx> >
pre;
62 std::string
setstr(
const std::set<Idx>& sset) {
63 std::set<Idx>::const_iterator ssit;
64 std::stringstream str;
66 for(ssit = sset.begin(); ssit != sset.end(); ++ssit)
75 std::string
vecstr(
const std::vector<Idx>& svec) {
76 std::vector<Idx>::const_iterator ssit;
77 std::stringstream str;
79 for(ssit = svec.begin(); ssit != svec.end(); ++ssit)
88 std::vector< std::vector<Idx> >
blocks;
103 #ifdef FAUDES_CHECKED
105 throw Exception(
"StateMin",
"input automaton non-deterministic", 101);
113 std::map<Idx,Idx> smap;
114 std::map<Idx,Idx> emap;
124 StateSet::Iterator sit=acc.
Begin();
125 for(; sit != acc.
End(); ++sit) {
132 if(!acc.
Exists(tit->X1))
continue;
133 if(!acc.
Exists(tit->X2))
continue;
134 states[smap[tit->X2]].pre[emap[tit->Ev]].push_back(smap[tit->X1]);
137 FD_DF(
"Hopcroft::Initialize(): states #" <<
states.size()-1);
158 if(
states.size()-1 == 0) {
159 FD_DF(
"Hopcroft::Minimize(): generator size 0");
164 if(
states.size()-1 == 1) {
165 FD_DF(
"Hopcroft::Minimize(): generator size 1");
173 std::stack<Idx> active;
174 std::vector<Idx>::iterator ssit;
175 std::vector<Idx>::iterator ssit_end;
177 std::vector<Idx> dpp;
183 std::vector<Idx> bnm;
186 else bnm.push_back(q);
189 blocks.push_back(std::vector<Idx>());
191 active.push(
blocks.size()-1);
192 FD_DF(
"Hopcroft::Minimize(): initial partition not-marked #" <<
blocks.back().size());
195 blocks.push_back(std::vector<Idx>());
197 active.push(
blocks.size()-1);
198 FD_DF(
"Hopcroft::Minimize(): initial partition not-marked #" <<
blocks.back().size());
202 while(!active.empty()) {
203 FD_WPC(
blocks.size()-active.size(),
blocks.size(),
"StateMin: blocks/active: " <<
blocks.size() <<
" / " << active.size());
204 FD_DF(
"Hopcroft::Minimize(): active blocks #" << active.size());
207 std::vector<Idx> b_current(
blocks.at(active.top()));
208 FD_DF(
"StateMin: getting active block B[" << active.top() <<
"] = { #" << b_current.size() <<
"}");
213 for(; ev!=
events.size(); ++ev){
216 ssit = b_current.begin();
217 ssit_end = b_current.end();
218 for(; ssit != ssit_end; ++ssit) {
220 std::vector<Idx>& preevx2=
states[*ssit].pre[ev];
221 std::vector<Idx>::iterator rit = preevx2.begin();
222 std::vector<Idx>::iterator rit_end = preevx2.end();
223 for (; rit != rit_end; ++rit) c.push_back(*rit);
225 std::sort(c.begin(),c.end());
227 if(c.empty())
continue;
229 FD_DF(
"StateMin: computed predecessor states C = {#" << c.size() <<
"} for event " <<
gen->
EventName(
events[ev]));
233 const std::vector<Idx>& d_current =
blocks[j];
235 if(d_current.size()==1)
continue;
236 FD_DF(
"StateMin: examining block D=B[" << j <<
"] = {#" << d_current.size() <<
"}");
239 std::set_intersection(d_current.begin(), d_current.end(), c.begin(), c.end(),
240 std::inserter(dp, dp.begin()));
242 if(dp.empty() || (dp.size()==d_current.size()))
continue;
243 FD_DF(
"StateMin: -> split:");
246 std::set_difference(d_current.begin(), d_current.end(), dp.begin(), dp.end(),
247 std::inserter(dpp,dpp.begin()));
249 if(dp.size() < dpp.size()) dp.swap(dpp);
253 blocks.push_back(std::vector<Idx>());
255 FD_DF(
"StateMin: new block D' as B[" << j <<
"] = " <<
vecstr(dp));
256 FD_DF(
"StateMin: new block D'' as B[" <<
blocks.size()-1 <<
"] = " <<
vecstr(dpp));
275 FD_DF(
"Hopcroft:Partition: building minimized generator #" <<
blocks.size());
288 std::map<Idx,Idx> minstatemap;
294 FD_DF(
"StateMin: block " <<
vecstr(
blocks.at(i)) <<
" -> new state " << newstate);
295 std::ostringstream ostr;
296 std::vector<Idx>::iterator ssit =
blocks[i].begin();
297 std::vector<Idx>::iterator ssit_end =
blocks[i].end();
298 for(; ssit != ssit_end; ++ssit) {
301 minstatemap[orgstate] = newstate;
309 FD_DF(
"StateMin: -> initial state");
314 FD_DF(
"StateMmin: -> marked state");
318 std::string statename = ostr.str();
319 if(statename!=
"") statename.erase(statename.length()-1);
320 statename =
"{" + statename +
"}";
327 std::map<Idx,Idx>::iterator xit1=minstatemap.find(tit->X1);
328 std::map<Idx,Idx>::iterator xit2=minstatemap.find(tit->X2);
329 if(xit1==minstatemap.end())
continue;
330 if(xit2==minstatemap.end())
continue;
335 if(pResGen != &rResGen) {
336 pResGen->
Move(rResGen);
349 void Partition(std::vector< StateSet >& rSubsets, std::vector<Idx>& rNewIndices){
351 FD_DF(
"Hopcroft:Partition: returning blocks #" <<
blocks.size());
357 rNewIndices.push_back(newstate);
359 std::vector<Idx>::iterator ssit =
blocks[i].begin();
360 std::vector<Idx>::iterator ssit_end =
blocks[i].end();
362 for(; ssit != ssit_end; ++ssit) {
366 rSubsets.push_back(block);
388 std::vector<StateSet>& rSubsets, std::vector<Idx>& rNewIndices) {
389 FD_DF(
"StateMin: *** computing state space minimization of generator "
392 FD_DF(
"StateMin: restrict to accessible states");
396 if(acc.
Size() == 0) {
397 FD_DF(
"StateMin: generator size 0. returning given generator");
402 if(rGen.
Size() == 1) {
403 FD_DF(
"StateMin: generator size 1. returning given generator");
406 rSubsets.push_back(rResGen.
States() );
407 rNewIndices.push_back(*( rResGen.
States().
Begin() ) );
412 #ifdef FAUDES_CHECKED
414 throw Exception(
"StateMin",
"input automaton nondeterministic", 101);
421 if(&rResGen==&rGen) {
422 pResGen= pResGen->
New();
427 pResGen->
Name(rGen.
Name()+
" [minstate]");
431 std::vector<StateSet>& b = rSubsets;
434 std::set<Idx> active;
435 std::set<Idx>::iterator ait;
441 StateSet::Iterator sit;
448 if(marked.
Size() > 0) {
449 FD_DF(
"StateMin: new block B[" << i <<
"] = {" << marked.
ToString() <<
"}");
454 if(notmarked.
Size() > 0) {
455 notmarked.
Name(
"B[i]");
456 FD_DF(
"StateMin: new block B[" << i <<
"] = {" << notmarked.
ToString() <<
"}");
457 b.push_back(notmarked);
464 while(! active.empty()) {
465 FD_WPC(b.size()-active.size(), b.size(),
"StateMin: blocks/active: " << b.size() <<
" / " << active.size());
466 #ifdef FAUDES_DEBUG_FUNCTION
467 FD_DF(
"StateMin: while there is an active block B...");
468 std::set<Idx>::iterator _it1;
469 std::stringstream str;
470 for (_it1 = active.begin(); _it1 != active.end(); ++_it1) {
473 FD_DF(
"StateMin: active: "+str.str());
474 std::vector<StateSet>::iterator _it2;
477 for (_it2 = b.begin(); _it2 != b.end(); ++_it2) {
478 str <<
"{" << _it2->ToString() <<
"} "<<std::endl;
481 FD_DF(
"B: "+str.str());
484 i = *(active.begin());
486 active.erase(active.begin());
487 FD_DF(
"StateMin: getting active block B[" << i <<
"] = {" <<
488 b.at(i).ToString() <<
"}");
494 EventSet::Iterator eit;
499 for (sit = b_current.
Begin(); sit != b_current.
End(); ++sit) {
502 rtit_end = rtransrel.
EndByEvX2(*eit, *sit);
503 for (; rtit != rtit_end; ++rtit) {
508 if(c.
Empty())
continue;
510 FD_DF(
"StateMin: computed predecessor states C = {" << c.
ToString()
511 <<
"} for event " << rGen.
EventName(*eit));
513 for (j=0; j < b.size(); ++j) {
515 const StateSet& d_current = b.at(j);
516 FD_DF(
"StateMin: examining block B[" << j <<
"] = {" <<
523 FD_DF(
"StateMin: -> no split");
526 FD_DF(
"StateMin: -> split:");
533 FD_DF(
"StateMin: new block B[" << j <<
"] = {" << d_.
ToString() <<
"}");
534 FD_DF(
"StateMin: new block B[" << b.size()-1 <<
"] = {" << d__.
ToString() <<
"}");
536 if(active.find(j) != active.end()) {
537 active.insert((
Idx)b.size()- 1);
538 FD_DF(
"StateMin: mark active: " << b.size()-1);
544 FD_DF(
"StateMin: mark active: " << j);
546 active.insert((
Idx)b.size()-1);
547 FD_DF(
"StateMin: mark active: " << b.size()-1);
554 FD_DF(
"StateMin: *** building minimized generator ***");
556 std::map<Idx,Idx> minstatemap;
559 for (i = 0; i < b.size(); ++i) {
562 rNewIndices.push_back(newstate);
563 FD_DF(
"StateMin: block {" << b.at(i).ToString()
564 <<
"} -> new state " << newstate);
565 std::ostringstream ostr;
566 for (sit = b.at(i).Begin(); sit != b.at(i).End(); ++sit) {
568 minstatemap[*sit] = newstate;
580 FD_DF(
"StateMin: -> initial state");
585 FD_DF(
"StatMmin: -> marked state");
589 std::string statename = ostr.str();
590 if(statename!=
"") statename.erase(statename.length()-1);
591 statename =
"{" + statename +
"}";
597 if(!acc.
Exists(tit->X1))
continue;
598 if(!acc.
Exists(tit->X2))
continue;
599 pResGen->
SetTransition(minstatemap[tit->X1], tit->Ev, minstatemap[tit->X2]);
600 FD_DF(
"statemin: adding transition: "
601 << minstatemap[tit->X1] <<
"-" << tit->Ev <<
"-"
602 << minstatemap[tit->X2]);
606 if(pResGen != &rResGen) {
607 pResGen->
Move(rResGen);
633 std::vector< StateSet >& rSubsets, std::vector<Idx>& rNewIndices){
#define FD_WPC(cntnow, contdone, message)
void Partition(std::vector< StateSet > &rSubsets, std::vector< Idx > &rNewIndices)
std::vector< Idx > events
std::vector< State > states
std::string vecstr(const std::vector< Idx > &svec)
void Partition(Generator &rResGen)
Hopcroft(const Generator &rGen)
std::string setstr(const std::set< Idx > &sset)
std::vector< std::vector< Idx > > blocks
Iterator EndByEvX2(Idx ev, Idx x2) const
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Iterator BeginByEvX2(Idx ev, Idx x2) const
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
const TransSet & TransRel(void) const
bool SetTransition(Idx x1, Idx ev, Idx x2)
const StateSet & MarkedStates(void) const
const EventSet & Alphabet(void) const
virtual void Move(vGenerator &rGen)
TransSet::Iterator TransRelBegin(void) const
void RestrictStates(const StateSet &rStates)
EventSet::Iterator AlphabetBegin(void) const
virtual vGenerator * New(void) const
void SetInitState(Idx index)
StateSet AccessibleSet(void) const
std::string StateName(Idx index) const
void Name(const std::string &rName)
TransSet::Iterator TransRelEnd(void) const
bool IsDeterministic(void) const
void SetMarkedState(Idx index)
virtual void EventAttributes(const EventSet &rEventSet)
bool StateNamesEnabled(void) const
std::string EventName(Idx index) const
EventSet::Iterator AlphabetEnd(void) const
bool ExistsInitState(Idx index) const
bool ExistsMarkedState(Idx index) const
const StateSet & States(void) const
void InjectAlphabet(const EventSet &rNewalphabet)
bool Exists(const T &rElem) const
Iterator Begin(void) const
const std::string & Name(void) const
void StateMin(const Generator &rGen, Generator &rResGen)
void aStateMin(const Generator &rGen, Generator &rResGen)
void StateMin_org(const Generator &rGen, Generator &rResGen, std::vector< StateSet > &rSubsets, std::vector< Idx > &rNewIndices)
std::string ToStringInteger(Int number)
std::vector< std::vector< Idx > > pre