libFAUDES

Sections

Index

cfl_graphfncts.cpp

Go to the documentation of this file.
00001 /** @file cfl_graphfncts.cpp Operations on (directed) graphs. */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005    Copyright (C) 2009  Thomas Moor, Klaus Schmidt, Sebastian Perk
00006    Exclusive copyright is granted to Klaus Schmidt
00007 
00008    This library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Lesser General Public
00010    License as published by the Free Software Foundation; either
00011    version 2.1 of the License, or (at your option) any later version.
00012 
00013    This library is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Lesser General Public License for more details.
00017 
00018    You should have received a copy of the GNU Lesser General Public
00019    License along with this library; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00021 
00022 
00023 #include "cfl_graphfncts.h"
00024 
00025 
00026 namespace faudes {
00027 
00028 /*
00029 **********************************************************************
00030 **********************************************************************
00031 **********************************************************************
00032 
00033 Search for strongly connected ycless components (SCC)
00034 
00035 **********************************************************************
00036 **********************************************************************
00037 **********************************************************************
00038 */
00039 
00040 // Filter class for SCC search: statics
00041 const StateSet SccFilter::msEmptyStates=StateSet();
00042 const EventSet SccFilter::msEmptyEvents=EventSet();
00043 
00044 // Filter class for SCC search: destructor
00045 SccFilter::~SccFilter(void) {
00046   if(mpStatesAvoid) delete mpStatesAvoid;
00047   if(mpStatesRequire) delete mpStatesRequire;
00048   if(mpEventsAvoid) delete mpEventsAvoid;
00049 }
00050 
00051 // Filter class for SCC search: constructors
00052 SccFilter::SccFilter(void) :
00053   mMode(0x00),
00054   pStatesAvoid(&msEmptyStates),
00055   pStatesRequire(&msEmptyStates),
00056   pEventsAvoid(&msEmptyEvents),
00057   mpStatesAvoid(0),
00058   mpStatesRequire(0),
00059   mpEventsAvoid(0)
00060 {}
00061 
00062 
00063 // Filter class for SCC search: constructors
00064 SccFilter::SccFilter(const SccFilter& rSrc) :
00065   mMode(rSrc.mMode),
00066   pStatesAvoid(rSrc.pStatesAvoid),
00067   pStatesRequire(rSrc.pStatesRequire),
00068   pEventsAvoid(rSrc.pEventsAvoid),
00069   mpStatesAvoid(0),
00070   mpStatesRequire(0),
00071   mpEventsAvoid(0)
00072 {}
00073 
00074 // Filter class for SCC search: constructors
00075 SccFilter::SccFilter(int mode, const StateSet& rStatesAvoidRequire) :
00076   mMode(mode),
00077   pStatesAvoid(&msEmptyStates),
00078   pStatesRequire(&msEmptyStates),
00079   pEventsAvoid(&msEmptyEvents),
00080   mpStatesAvoid(0),
00081   mpStatesRequire(0),
00082   mpEventsAvoid(0)
00083 {
00084   // no special events
00085   mMode &= ~FmEventsAvoid;
00086   // use states for require
00087   if(mMode & FmStatesRequire)
00088     pStatesRequire=&rStatesAvoidRequire;
00089   // use states for avoid
00090   if(mMode & FmStatesAvoid)
00091     pStatesAvoid=&rStatesAvoidRequire;
00092 }
00093 
00094 // Filter class for SCC search: constructors
00095 SccFilter::SccFilter(int mode, const StateSet& rStatesAvoid, const StateSet& rStatesRequire): 
00096   mMode(mode),
00097   pStatesAvoid(&msEmptyStates),
00098   pStatesRequire(&msEmptyStates),
00099   pEventsAvoid(&msEmptyEvents),
00100   mpStatesAvoid(0),
00101   mpStatesRequire(0),
00102   mpEventsAvoid(0)
00103 {
00104   // no special events
00105   mMode &= ~FmEventsAvoid;
00106   // but special states
00107   mMode |= FmStatesRequire;
00108   mMode |= FmStatesAvoid;
00109   // set internal pointers
00110   pStatesAvoid=&rStatesAvoid;
00111   pStatesRequire=&rStatesRequire;
00112 }
00113 
00114 
00115 // Filter class for SCC search: constructors
00116 SccFilter::SccFilter(int mode, const Generator& rGen) :
00117   mMode(mode),
00118   pStatesAvoid(&msEmptyStates),
00119   pStatesRequire(&msEmptyStates),
00120   pEventsAvoid(&msEmptyEvents),
00121   mpStatesAvoid(0),
00122   mpStatesRequire(0),
00123   mpEventsAvoid(0)
00124 {
00125   // sets all empty by default
00126   mMode &= ~(FmStatesAvoid | FmStatesRequire | FmEventsAvoid );
00127   // ignore livelocks ==> require at least one marked state
00128   if(mode & FmIgnoreLiveLocks) {
00129     pStatesRequire=&rGen.MarkedStates();
00130     mMode |= FmStatesRequire;
00131   }
00132   // livelocks only ==> avoid marked states
00133   if(mode & FmLiveLocksOnly) {
00134     pStatesAvoid=&rGen.MarkedStates();
00135     mMode |= FmStatesAvoid;
00136   }
00137   // accessible only ==> deal with this in api wrappers
00138   if(mode & FmIgnoreUnaccessible) {
00139     (void) mode;
00140   }  
00141 }
00142 
00143 
00144 // Filter class for SCC search: clear
00145 void SccFilter::Clear(void) {
00146   if(mpStatesAvoid) delete mpStatesAvoid;
00147   if(mpStatesRequire) delete mpStatesRequire;
00148   if(mpEventsAvoid) delete mpEventsAvoid;
00149   mpStatesAvoid=0;
00150   mpStatesRequire=0;
00151   mpEventsAvoid=0;
00152   mMode=0x00;
00153   pStatesAvoid=&msEmptyStates;
00154   pStatesRequire=&msEmptyStates;
00155   pEventsAvoid=&msEmptyEvents;
00156 }
00157 
00158 // Filter class for SCC search: edit
00159 void SccFilter::StatesAvoid(const StateSet& rStatesAvoid) {
00160   if(mpStatesAvoid) delete mpStatesAvoid;
00161   mpStatesAvoid=0;
00162   mMode |= FmStatesAvoid;
00163   pStatesAvoid=&rStatesAvoid;
00164 }
00165 
00166 // Filter class for SCC search: edit
00167 void SccFilter::StatesRequire(const StateSet& rStatesRequire) {
00168   if(mpStatesRequire) delete mpStatesRequire;
00169   mpStatesRequire=0;
00170   mMode |= FmStatesRequire;
00171   pStatesRequire=&rStatesRequire;
00172 }
00173 
00174 // Filter class for SCC search: edit
00175 void SccFilter::MergeStatesAvoid(const StateSet& rStatesAvoid) {
00176   if(mpStatesAvoid==0) mpStatesAvoid= new IndexSet(*pStatesAvoid);
00177   mpStatesAvoid->InsertSet(rStatesAvoid);
00178   mpStatesAvoid->Name("StatesAvoid");
00179   pStatesAvoid=mpStatesAvoid;
00180 } 
00181 
00182 // Filter class for SCC search: edit
00183 void SccFilter::EventsAvoid(const EventSet& rEventsAvoid) {
00184   if(mpEventsAvoid) delete mpEventsAvoid;
00185   mpEventsAvoid=0;
00186   mMode |= FmEventsAvoid;
00187   pEventsAvoid=&rEventsAvoid;
00188 }
00189 
00190 // Filter class for SCC search: edit
00191 void SccFilter::IgnoreTrivial(bool flag) {
00192   mMode &= ~FmIgnoreTrivial;
00193   if(flag) mMode |= FmIgnoreTrivial;
00194 }
00195 
00196 // Filter class for SCC search: edit
00197 void SccFilter::FindFirst(bool flag) {
00198   mMode &= ~FmFindFirst;
00199   if(flag) mMode |= FmFindFirst;
00200 }
00201 
00202 
00203 
00204 
00205 // Recursive function to search for SCCs.
00206 // The algorithm is a minor variation of the one prsented in
00207 //  -- Aho, Hopcroft, Ullman: The Design and Analysis of Computer Algorithms
00208 void SearchScc(
00209   const Idx vState,            // Current state under investigation
00210   int& vRcount,                // Depth count of recursion
00211   const Generator& rGen,       // Graph to inspect
00212   const SccFilter& rFilter,    // Filter to ignore transitions with specified events
00213   StateSet&  rTodo,            // States not dealt with so far
00214   std::stack<Idx>& rStack,     // Stack of currently considered states
00215   StateSet& rStackStates,      // Stack contents as set
00216   std::map<const Idx, int>& rDfn, // Map assigning to each state its depth-first count
00217   std::map<const Idx, int>& rLowLnk, // Map assigning to each state its LOWLINK Number
00218   std::list<StateSet>& rSccList,  // Record result: list of SCCs 
00219   StateSet& rRoots)             // Record result: one state per SCC
00220 {
00221   FD_DF("SerchScc: -- recursive search from state "<< vState << " at level " << vRcount << " --");
00222   // Take current state from todo list
00223   rTodo.Erase(vState);
00224   // Ignore filter: avoid states
00225   if(rFilter.mMode & SccFilter::FmStatesAvoid)
00226   if(rFilter.pStatesAvoid->Exists(vState)) return;
00227   // Ignore filter: break recursion on find first
00228   if(rFilter.mMode & SccFilter::FmFindFirst)
00229   if(!rSccList.empty()) return;
00230   // Record depth-first level for current state and initialise low-link level
00231   rDfn[vState]=vRcount;
00232   rLowLnk[vState]=vRcount;
00233   // Increment depth-first level
00234   vRcount++;
00235   // Push state on stack;
00236   rStack.push(vState);
00237   rStackStates.Insert(vState);
00238   /*
00239   std::list<Idx>::iterator vsit = --rStack.end();
00240   */
00241   // Create set of successor states "L[state]" 
00242   StateSet SuccStates = StateSet();
00243   TransSet::Iterator tit = rGen.TransRelBegin(vState);
00244   TransSet::Iterator tit_end = rGen.TransRelEnd(vState);
00245   for(; tit != tit_end; ++tit) {
00246     // Ignore avoid: avoid states
00247     if(rFilter.mMode & SccFilter::FmStatesAvoid)
00248     if(rFilter.pStatesAvoid->Exists(tit->X2)) continue;
00249     // Ignore filter: avoid events
00250     if(rFilter.mMode & SccFilter::FmEventsAvoid)
00251     if(rFilter.pEventsAvoid->Exists(tit->Ev)) continue;
00252     // Record
00253     SuccStates.Insert(tit->X2);
00254   }
00255   // Iterate over vertices *sit of L[state] 
00256   StateSet::Iterator sit = SuccStates.Begin();
00257   StateSet::Iterator sit_end = SuccStates.End();
00258   for(; sit != sit_end; ++sit) {
00259     // Successors that are on the todo list get ... 
00260     if(rTodo.Exists(*sit)) {        
00261        // ... searched recursively, and ...
00262        SearchScc(*sit, vRcount, rGen, rFilter, rTodo, rStack, rStackStates, rDfn, rLowLnk, rSccList, rRoots);
00263        // ... the current low-link gets updated to the new minimum.
00264        if(rLowLnk[*sit]<rLowLnk[vState]) rLowLnk[vState]=rLowLnk[*sit];
00265        // Break recursion on find first
00266        if(rFilter.mMode & SccFilter::FmFindFirst)
00267        if(!rSccList.empty()) return;
00268     }
00269     // Successors that are not on the todo list ...
00270     else {
00271       // ... if they have a lower deph-first level ...
00272       if(rDfn[*sit]<rDfn[vState])  
00273       // ... and if they are on the stack at all ...
00274       if(rStackStates.Exists(*sit)) 
00275       // ... set the current low-link to the new minimum 
00276       if(rDfn[*sit]<rLowLnk[vState]) rLowLnk[vState]=rDfn[*sit];
00277     }
00278   }//end for: iterate successors
00279 
00280   // If the current state is the root of a SCC, record the result
00281   if((rLowLnk[vState]==rDfn[vState])) {
00282     FD_DF("SearchScc: retrieving SCC from stack, root " << vState);        
00283     bool record=true;
00284     // Technically, each state that fails to be part of a cycle forms an
00285     // SCC. We optionally ignore those trivial SCCs. They are identified by consisting of
00286     // one state only and having no (relevant) selfloop.
00287     if(rFilter.mMode & SccFilter::FmIgnoreTrivial) {
00288       if(rStack.top()==vState) {
00289         TransSet::Iterator tit = rGen.TransRelBegin(vState);
00290         TransSet::Iterator tit_end = rGen.TransRelEnd(vState);
00291         for(; tit != tit_end; ++tit) {
00292           // no self loop
00293           if(tit->X2!=vState) continue;
00294           // fail for avoid event
00295           if(rFilter.mMode & SccFilter::FmEventsAvoid)
00296     if(rFilter.pEventsAvoid->Exists(tit->Ev)) 
00297             continue;
00298           /*
00299           // fail no required event
00300           if(rFilter.mMode & SccFilter::FmEventsRequire)
00301     if(!rFilter.pEventsRequire->Exists(tit->Ev)) 
00302             continue;
00303     */
00304           // found relevant selfloop
00305           break;
00306         }
00307         if(tit==tit_end) record=false;
00308       }
00309 #ifdef FAUDES_DEBUG_FUNCTION
00310      if(!record) FD_DF("SearchScc: trivial loop, ignored");
00311 #endif
00312     }
00313     /*
00314     // Inspect for required events (TODO: perhaps record path incl. events?)
00315     if(rFilter.mMode & SccFilter::EventsRequire) {
00316       bool reqevent=false;
00317       for(;vsit!=rStack.end();) {
00318         Idx x1, x2;
00319         x1=*vsit;
00320         if(++vsit==rStack.end()) x2=vState;
00321         else x2=*vsit;
00322         TransSet::Iterator tit = rGen.TransRelBegin(x1);
00323         TransSet::Iterator tit_end = rGen.TransRelEnd(x1);
00324         for(; tit != tit_end; ++tit) {
00325           // not on my path
00326           if(tit->X2!=x2) continue;
00327           // event not found
00328           if(!rFilter.pEventsRequire->Exists(tit->Ev)) continue;
00329           // found
00330           reqevent=true;
00331         }
00332       }
00333       if(reqevent==false) record=false;
00334     }
00335     */
00336     // Retrieve SCC from stack, inspect required states
00337     rSccList.push_back(StateSet());
00338     rRoots.Insert(vState);
00339     Idx top;
00340     bool reqstate=false;
00341     do {
00342       // Pop top of stack
00343       top=rStack.top();
00344       rStackStates.Erase(top);
00345       rStack.pop();
00346       // Record/track state requirements
00347       if(record) {
00348         rSccList.back().Insert(top);
00349         // Required state?
00350         if(rFilter.mMode & SccFilter::FmStatesRequire)
00351   if(rFilter.pStatesRequire->Exists(top)) 
00352           reqstate=true;
00353       }
00354     } while(top!=vState);
00355     // Invalidate missed requirements
00356     if(rFilter.mMode & SccFilter::FmStatesRequire)
00357     if(!reqstate)
00358       record=false;
00359     // Invalidate result
00360     if(!record) {
00361       rSccList.pop_back();
00362       rRoots.Erase(vState);
00363     }
00364   } // end if: record
00365 }
00366 
00367 
00368 // ComputeScc(Generator, SccList, Roots)
00369 bool ComputeScc(
00370   const Generator& rGen,
00371   const SccFilter& rFilter,
00372   std::list<StateSet>& rSccList,
00373   StateSet& rRoots)
00374 {
00375   FD_DF("CompteScc(" << rGen.Name() << ")");
00376 
00377   // inititalize results:
00378   rRoots.Clear();
00379   rSccList.clear();
00380 
00381   // initialize counter for depthfirstnumbers(DFN):
00382   int count=1;
00383 
00384   // provide local variables 
00385   std::stack<Idx> stack;
00386   StateSet stackstates;
00387   StateSet todostates;
00388   std::map<const Idx, int> dfn;
00389   std::map<const Idx, int> lowlnk;
00390 
00391   // initialise todo list
00392   if(rFilter.Mode() & SccFilter::FmIgnoreUnaccessible)
00393     todostates=rGen.AccessibleSet();
00394   else
00395     todostates=rGen.States();
00396   if(rFilter.Mode() & SccFilter::FmStatesAvoid)
00397     todostates = todostates - rFilter.StatesAvoid();
00398 
00399   // start recursive depth-first search for Scc's:
00400   while(!todostates.Empty()) {
00401     SearchScc(*todostates.Begin(), count, rGen, rFilter, todostates, stack, stackstates, 
00402       dfn, lowlnk,rSccList, rRoots);
00403   }
00404 
00405   // done
00406   return !rSccList.empty();
00407 }
00408 
00409 // ComputeScc(Generator, SccList, Roots)
00410 bool ComputeScc(
00411   const Generator& rGen,
00412   std::list<StateSet>& rSccList,
00413   StateSet& rRoots)
00414 {
00415   FD_DF("CompteScc(" << rGen.Name() << ") [std]");
00416 
00417   // dummy
00418   const static SccFilter msFilter = SccFilter();
00419 
00420   // doit
00421   return ComputeScc(rGen,msFilter,rSccList,rRoots);
00422 }
00423 
00424 
00425 // ComputeScc(Generator, Filter, q0, Scc)
00426 bool  ComputeScc(
00427   const Generator& rGen,
00428   const SccFilter& rFilter,
00429   Idx q0, 
00430   StateSet& rScc)
00431 {
00432   FD_DF("ComputeScc(" << rGen.Name() << ")");
00433 
00434   // inititalize result
00435   rScc.Clear();
00436 
00437   // initialize counter for depthfirstnumbers:
00438   int count=1;
00439 
00440   // provide local variables 
00441   std::stack<Idx> stack;
00442   StateSet stackstates;
00443   StateSet todostates;
00444   std::map<const Idx, int> dfn;
00445   std::map<const Idx, int> lowlnk;
00446   std::list<StateSet> scclist;
00447   StateSet roots;
00448 
00449   // initialise todo list
00450   if(rFilter.Mode() & SccFilter::FmIgnoreUnaccessible)
00451     todostates=rGen.AccessibleSet();
00452   else
00453     todostates=rGen.States();
00454   if(rFilter.Mode() & SccFilter::FmStatesAvoid)
00455     todostates = todostates - rFilter.StatesAvoid();
00456 
00457   // copy and edit the filter
00458   SccFilter filter(rFilter);
00459   filter.FindFirst(true);
00460   StateSet reqstate;
00461   reqstate.Insert(q0);
00462   filter.StatesRequire(reqstate);
00463 
00464   // start recursive depth-first search for Scc's:
00465   while(!todostates.Empty()) {
00466     SearchScc(*todostates.Begin(), count, rGen, filter, todostates, stack, stackstates, 
00467       dfn, lowlnk, scclist, roots);
00468   }
00469 
00470   // copy (!) result
00471   if(!scclist.empty()) rScc=*scclist.begin();
00472 
00473   // done
00474   return !rScc.Empty();
00475 }
00476 
00477 
00478 // ComputeScc(Generator, Filter, Scc)
00479 bool ComputeScc(
00480   const Generator& rGen,
00481   const SccFilter& rFilter,
00482   StateSet& rScc)
00483 {
00484   FD_DF("ComputeScc(" << rGen.Name() << ")");
00485 
00486   // inititalize result
00487   rScc.Clear();
00488 
00489   // initialize counter for depthfirstnumbers:
00490   int count=1;
00491 
00492   // provide local variables 
00493   std::stack<Idx> stack;
00494   StateSet stackstates;
00495   StateSet todostates;
00496   std::map<const Idx, int> dfn;
00497   std::map<const Idx, int> lowlnk;
00498   std::list<StateSet> scclist;
00499   StateSet roots;
00500 
00501   // initialise todo list
00502   if(rFilter.Mode() & SccFilter::FmIgnoreUnaccessible)
00503     todostates=rGen.AccessibleSet();
00504   else
00505     todostates=rGen.States();
00506   if(rFilter.Mode() & SccFilter::FmStatesAvoid)
00507     todostates = todostates - rFilter.StatesAvoid();
00508 
00509   // copy and edit the filter
00510   SccFilter filter(rFilter);
00511   filter.FindFirst(true);
00512 
00513   // start recursive depth-first search for Scc's:
00514   while(!todostates.Empty()) {
00515     SearchScc(*todostates.Begin(), count, rGen, filter, todostates, stack, stackstates, 
00516       dfn, lowlnk, scclist, roots);
00517   }
00518 
00519   // copy (!) result
00520   if(!scclist.empty()) rScc=*scclist.begin();
00521 
00522   // done
00523   return !rScc.Empty();
00524 }
00525 
00526 // HasScc(Generator, Filter)
00527 bool HasScc(
00528   const Generator& rGen,
00529   const SccFilter& rFilter)
00530 {
00531   FD_DF("HasScc(" << rGen.Name() << ") [boolean only]");
00532 
00533   // initialize counter for depthfirstnumbers:
00534   int count=1;
00535 
00536   // provide local variables 
00537   std::stack<Idx> stack;
00538   StateSet stackstates;
00539   StateSet todostates;
00540   std::map<const Idx, int> dfn;
00541   std::map<const Idx, int> lowlnk;
00542   std::list<StateSet> scclist;
00543   StateSet roots;
00544 
00545   // initialise todo list
00546   if(rFilter.Mode() & SccFilter::FmIgnoreUnaccessible)
00547     todostates=rGen.AccessibleSet();
00548   else
00549     todostates=rGen.States();
00550   if(rFilter.Mode() & SccFilter::FmStatesAvoid)
00551     todostates = todostates - rFilter.StatesAvoid();
00552 
00553   // copy and edit the filter
00554   SccFilter filter(rFilter);
00555   filter.FindFirst(true);
00556 
00557 
00558   // start recursive depth-first search for Scc's:
00559   while(!todostates.Empty()) {
00560     SearchScc(*todostates.Begin(), count, rGen, filter, todostates, stack, stackstates, 
00561       dfn, lowlnk, scclist, roots);
00562   }
00563 
00564   // done
00565   return !scclist.empty();
00566 
00567 }
00568 
00569 
00570 // RTI wrapper
00571 bool ComputeNextScc(
00572   const Generator& rGen,
00573   SccFilter& rFilter,
00574   StateSet& rScc
00575 ) {
00576   // find first
00577   rFilter.FindFirst(true);
00578   bool res = ComputeScc(rGen,rFilter,rScc);
00579   // fix filter
00580   if(res) rFilter.MergeStatesAvoid(rScc);
00581   rFilter.FindFirst(false);
00582   // done
00583   return res;
00584 }
00585 
00586 
00587 
00588 /*
00589 
00590 // WriteStateSets(rStateSets)
00591 // Write set of StateSet's to console.
00592 void WriteStateSets(
00593   const std::set<StateSet>& rStateSets)
00594 {
00595   FD_DF("WriteStateSets()");
00596   std::cout<<std::endl;
00597   if(rStateSets.empty()) {
00598     std::cout<<"WriteStateSets: Set of state sets is empty."<<std::endl;
00599     FD_DF("WriteStateSets: Set of state sets is empty.");
00600     return;
00601   }
00602   std::cout<<">WriteStateSets: Set of state sets begin:"<< std::endl;
00603   std::set<StateSet>::iterator StateSetit = rStateSets.begin();
00604   std::set<StateSet>::iterator StateSetit_end = rStateSets.end();
00605   for (; StateSetit != StateSetit_end; ++StateSetit) {
00606     std::cout<<std::endl<<"  >> State set begin:"<< std::endl;
00607     StateSet::Iterator sit = StateSetit->Begin();
00608     StateSet::Iterator sit_end = StateSetit->End();
00609     for (; sit != sit_end; ++sit) {
00610       std::cout<<"  >> "<<*sit<<std::endl;
00611     }
00612     std::cout<<"  >> State set end."<< std::endl;
00613   }  
00614   std::cout<<std::endl<<">WriteStateSets: Set of state sets end."<<std::endl;
00615 }
00616 
00617 // WriteStateSets(rGen,rStateSets)
00618 // Write set of StateSet's to console.
00619 // Use rGen for symbolic state names
00620 void WriteStateSets(
00621   const Generator& rGen,
00622   const std::set<StateSet>& rStateSets)
00623 {
00624   FD_DF("WriteStateSets()");
00625   std::cout<<std::endl;
00626   if(rStateSets.empty()) {
00627     std::cout<<"WriteStateSets: Set of state sets is empty."<<std::endl;
00628     FD_DF("WriteStateSets: Set of state sets is empty.");
00629     return;
00630   }
00631   std::cout<<">WriteStateSets: Set of state sets begin:"<< std::endl;
00632   std::set<StateSet>::iterator StateSetit = rStateSets.begin();
00633   std::set<StateSet>::iterator StateSetit_end = rStateSets.end();
00634   for (; StateSetit != StateSetit_end; ++StateSetit) {
00635     std::cout<<std::endl<<"  >> State set begin:"<< std::endl;
00636     std::cout<<"  "<<rGen.StateSetToString(*StateSetit)<<std::endl;
00637     std::cout<<"  >> State set end."<< std::endl;
00638   }  
00639   std::cout<<std::endl<<">WriteStateSets: Set of state sets end."<<std::endl;
00640 }
00641 
00642 */
00643 
00644 }//namespace faudes
00645 

libFAUDES 2.22s --- 2013.10.07 --- c++ source docu by doxygen