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)
 
const std::string & Name(void) const
 
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
 
virtual 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
 
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
 
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