cfl_graphfncts.h

Go to the documentation of this file.
00001 /** @file cfl_graphfncts.h 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 #ifndef FAUDES_GRAPHFNCTS_H
00024 
00025 #include "cfl_definitions.h"
00026 #include "cfl_generator.h"
00027 #include <stack>
00028 
00029 namespace faudes {
00030 
00031 
00032 /**
00033  * Filter for strictly connected components (SCC) search/compute routines.
00034  *
00035  * When ComputeScc()/HasScc()/NextScc()  traverse a specified transition sytem in their
00036  * search, a SccFilter parameter can mute certain transitions. The respective
00037  * filter conditions are set by the constructor and consist of a flag word (mMode)
00038  * and additional parameters (depending on the flags). The Flags can be combined
00039  * from the following: 
00040  *
00041  * - NoFilter: std textbook beheviour;
00042  * - FindFirst: stop the search after one SCC has been found;
00043  * - IgnoreTrivial: dont report singleton SCCs without selfloop;
00044  * - StatesAvoid: mute specified states from trasition structure;
00045  * - StatesRequire: dont report SCCs that fail to contain at least one state from the specified set;
00046  * - EventsAvoid: mute any transitions with an event label from the specified set.
00047  *
00048  * Convenience modes set up the state related filter conditions from the set of marked states:
00049  *
00050  * - IgnoreLiveLocks: set StatesRequire to the marked states of a specified Generator;
00051  * - LiveLocksOnly: set StatesAvoid to the marked states of a specified Generator;
00052  * - IgnoreUnaccessible: initialise todo list with accessible states only.
00053  *
00054  * Technical note: SccFilters interally use references to condition 
00055  * parameters that are required to exist during the life time of the filter object. 
00056  *
00057  * Technical note: currently, there is no EventsRequire filter because the implementation 
00058  * interprets the transition relation primarily from a directed graph perspective; while StatesRequire
00059  * makes sense for marked states semantics, we are not aware of any applications for
00060  * a corresponding version of EventsRequire; please let us know if you require such an extension. 
00061  *
00062  * @ingroup GeneratorFunctions
00063  */
00064 class SccFilter {
00065 
00066   // Allow search function access
00067   friend void SearchScc(
00068     const Idx vState,           
00069     int& vRcount,               
00070     const Generator& rGen,      
00071     const SccFilter& rFilter,
00072     StateSet&  rTodo,           
00073     std::stack<Idx>& rStack,    
00074     StateSet& rStackStates,     
00075     std::map<const Idx, int>& rDfn,
00076     std::map<const Idx, int>& rLowLnk, 
00077     std::list<StateSet>& rSccList,  
00078     StateSet& rRoots);       
00079   friend bool ComputeNextScc(
00080     const Generator& rGen,
00081     SccFilter& rFilter,
00082     StateSet& rScc
00083   );
00084 
00085 public:
00086 
00087   /** Typedef for filter modes */
00088   typedef enum { 
00089     FmNoFilter=0x00,             //// no filters at all (default)
00090     FmFindFirst=0x01,            //// only report first valid SCC
00091     FmIgnoreTrivial=0x02,        //// ignore non-cycles, aka singletons without selfloop
00092     FmStatesAvoid=0x10,          //// filter by avoiding specified states
00093     FmStatesRequire=0x20,        //// filter by requireing specified states
00094     FmEventsAvoid=0x40,          //// filter by avoiding specified events
00095     FmIgnoreLiveLocks=0x1000,    //// ignore cycles with unmarked states only
00096     FmLiveLocksOnly =0x2000,     //// ignore cycles with one or more marked states
00097     FmIgnoreUnaccessible=0x4000  //// only inspect accessible part
00098   } FMode;
00099 
00100   /** Constructor (no filter) */
00101   SccFilter(void);
00102 
00103   /** Constructor (copy constructor) */
00104   SccFilter(const SccFilter& rSrc);
00105 
00106   /** Constructor (from flags w.r.t. Generator) */
00107   SccFilter(int mode, const Generator& rGen);
00108 
00109   /** Constructor (from flags and state set, either avoid or require) */
00110   SccFilter(int mode, const StateSet& rStatesAvoidRequire);
00111 
00112   /** Constructor (from flags and state sets) */
00113   SccFilter(int mode, const StateSet& rStatesAvoid, const StateSet& rStatesRequire);
00114 
00115   /** Constructor (from flags and event sets) */
00116   SccFilter(int mode, const EventSet& rEventsAvoid);
00117 
00118   /** Constructor (from flags and sets) */
00119   SccFilter(int mode, const StateSet& rStatesAvoid, const StateSet& rStatesRequire, 
00120      const EventSet& rEventsAvoid);
00121 
00122   /** Destructor */
00123   ~SccFilter(void);
00124 
00125   /** Member access */
00126   int Mode(void) const { return mMode;};
00127 
00128   /** Member access */
00129   const StateSet& StatesAvoid(void) const { return *pStatesAvoid;};
00130 
00131   /** Member access */
00132   const StateSet& StatesRequire(void) const { return *pStatesRequire;};
00133 
00134   /** Edit filter (RTI): no filter */
00135   void Clear(void);
00136 
00137   /** Edit filter (RTI): set avoid states */
00138   void StatesAvoid(const StateSet& rStatesAvoid);
00139 
00140   /** Edit filter (RTI): set required states */
00141   void StatesRequire(const StateSet& rStatesRequire);
00142 
00143   /** Edit filter (RTI): set avoid events */
00144   void EventsAvoid(const EventSet& rEventsAvoid);
00145 
00146   /** Edit filter (RTI): ignore trivial */
00147   void IgnoreTrivial(bool flag);  
00148 
00149   /** Edit filter (RTI): find first */
00150   void FindFirst(bool flag);  
00151 
00152 
00153 protected:
00154 
00155   /** Edit filter (RTI): avoid states */
00156   void MergeStatesAvoid(const StateSet& rStatesAvoid);
00157 
00158   /** Flag, combining bit masks from Mode */
00159   int mMode; 
00160   /** States to avoid (if flag StatesAvoid is set) */
00161   const StateSet* pStatesAvoid;
00162   /** States to require (if flag StatesRequire is set) */
00163   const StateSet* pStatesRequire;
00164   /** Events to avoid (if flag EventssAvoid is set) */
00165   const EventSet* pEventsAvoid;
00166 
00167   /** Local sets (optional) */
00168   StateSet* mpStatesAvoid;
00169   StateSet* mpStatesRequire;
00170   EventSet* mpEventsAvoid;
00171 
00172   /** Static emptysets */
00173   const static StateSet msEmptyStates;
00174   const static EventSet msEmptyEvents;
00175 };
00176 
00177 
00178 /**
00179  *
00180  * Search for strongly connected components (SCC). 
00181  * 
00182  * This function partitions the stateset of a generator into equivalent 
00183  * classes such that states x1 and x2 are equivalent iff there is a path from x1
00184  * to x2 AND a path from x2 to x1. 
00185  *
00186  * This function implements the algorithm based on a recursive depth first search
00187  * presented in:
00188  *
00189  * -- Aho, Hopcroft, Ullman: The Design and Analysis of Computer Algorithms --
00190  *
00191  * While the original algorithm works on a directed graph, this
00192  * implementation adds some features that refer to transition systems and
00193  * allow to filter SCCs on the run. The filter condition is specified by the
00194  * SccFilter parameter rFilter.
00195  *
00196  * Note: this version is derived from earlier implementations used in 
00197  * various plug-ins; in due course, this version will replace earlier versions. 
00198  *
00199  * Note: Due to the recursive implementation, this function requires a stack 
00200  * size proportional to the largest SCC. We have experienced typical default
00201  * configurations to be good for a depth of about 80000 (Mac OSX 10.6, Debian 7.4). 
00202  * For SCCs exceeding the default stack size, you may adjust the operating system 
00203  * parameters accordingly. On Unix/Linux/MacOsX this is done by the shell command 
00204  * "ulimit -s hard". A future revision of SearchSCC() may be re-designed to
00205  * circumvent this inconvenient issue.
00206  *
00207  * Note: for a convenience API see also ComputeScc()
00208  *
00209  * @param vState
00210  *   State, from which the current recursion is started.
00211  * @param vRcount
00212  *   Denotes the current depth of the recursion.
00213  * @param rGen
00214  *   Transition system to investigate
00215  * @param rFilter
00216  *   Filter out specified transitions
00217  * @param rTodo
00218  *   Set of states that up to now were not found by the
00219  *   depth first search.
00220  * @param rStack
00221  *   Stack of states to represent current path.
00222  * @param rStackStates
00223  *   Set of states that are in rStack
00224  * @param rDfn
00225  *   Map assigning to each state idx its Depth-First Number.
00226  * @param rLowLnk
00227  *   Map assigning to each state its LOWLINK Number.
00228  * @param rSccList
00229  *   Set SCCs (accumulative result).
00230  * @param rRoots
00231  *   Set of states that each are root of some SCC (accumulative result).
00232  *
00233  * 
00234  */
00235 void SearchScc(
00236   const Idx vState,           
00237   int& vRcount,               
00238   const Generator& rGen,      
00239   const SccFilter& rFilter,
00240   StateSet&  rTodo,           
00241   std::stack<Idx>& rStack,    
00242   StateSet& rStackStates,     
00243   std::map<const Idx, int>& rDfn,
00244   std::map<const Idx, int>& rLowLnk, 
00245   std::list<StateSet>& rSccList,  
00246   StateSet& rRoots);       
00247 
00248 
00249 /**
00250  * Compute strongly connected components (SCC) 
00251  *
00252  * This function is a API wrapper that calls the recursive implementation
00253  * SearchScc().
00254  *
00255  * 
00256  * @param rGen
00257  *   Generator under investigation
00258  * @param rFilter
00259  *   Filter specified transitions
00260  * @param rSccList
00261  *   List of SCCs (result)
00262  * @param rRoots
00263  *   Set of states that each are root of some SCC (result).
00264  *
00265  * @return
00266  *   True if SCCs have been found, false if not.
00267  *
00268  * @ingroup GeneratorFunctions
00269  * 
00270  */
00271 bool ComputeScc(
00272   const Generator& rGen,
00273   const SccFilter& rFilter,
00274   std::list<StateSet>& rSccList,
00275   StateSet& rRoots);
00276 
00277 
00278 /**
00279  * Compute strongly connected components (SCC) 
00280  *
00281  * This function is a API wrapper that calls the recursive implementation
00282  * SearchScc().
00283  *
00284  * @param rGen
00285  *   Generator under investigation
00286  * @param rSccList
00287  *   List of SCCs (result)
00288  * @param rRoots
00289  *   Set of states that each are root of some SCC (result).
00290  *
00291  * @return
00292  *   True if SCCs have been found, false if not.
00293  *   Since there are no filters, true is returned iff the
00294  *   the state set is non-empty.
00295  *
00296  * @ingroup GeneratorFunctions
00297  * 
00298  */
00299 bool ComputeScc(
00300   const Generator& rGen,
00301   std::list<StateSet>& rSccList,
00302   StateSet& rRoots);
00303   
00304 
00305   
00306 /**
00307  * Compute strongly connected component (SCC) 
00308  *
00309  * This function is a API wrapper that calls the recursive implementation
00310  * SearchScc(). It internally edits the filter to require the specified
00311  * initial state and to stop on the first SCC found. In particular, any
00312  * other state requirement will be ignored.
00313  *
00314  * @param rGen
00315  *   Generator under investigation
00316  * @param rFilter
00317  *   Filter specified transitions
00318  * @param q0
00319  *   Initial state for SCC.
00320  * @param rScc
00321  *   SCC (result)
00322  *
00323  * @return
00324  *   True if an SCC has been found, false if not.
00325  *
00326  * @ingroup GeneratorFunctions
00327  * 
00328  */
00329 bool ComputeScc(
00330   const Generator& rGen,
00331   const SccFilter& rFilter,
00332   Idx q0, 
00333   StateSet& rScc
00334 );
00335 
00336 
00337 
00338 /**
00339  * Compute one strongly connected components (SCC) 
00340  *
00341  * This functions searchs for the first SCC of the generator rGen 
00342  * while applying the filter rFilter; see SCCFilter for details.
00343  *
00344  * Technically, this function is a API wrapper that calls the recursive implementation
00345  * SearchScc() as presented in 
00346  *
00347  * -- Aho, Hopcroft, Ullman: The Design and Analysis of Computer Algorithms --
00348  * 
00349  * @param rGen
00350  *   Generator under investigation
00351  * @param rFilter
00352  *   Filter out specified transitions
00353  * @param rScc
00354  *   First SCC that has been found, empty if no such.
00355  *
00356  * @return
00357  *   True if SCCs have been found, false if not.
00358  *
00359  * @ingroup GeneratorFunctions
00360  * 
00361  */
00362 
00363 bool ComputeScc(
00364   const Generator& rGen,
00365   const SccFilter& rFilter,
00366   StateSet& rScc
00367 );
00368 
00369 /**
00370  * Test for strongly connected components (SCC) 
00371  *
00372  * This functions searchs for the first SCC of the generator rGen 
00373  * while applying the filter rFilter; see SCCFilter for details.
00374  *
00375  * Technically, this function is an API wrapper that calls the recursive implementation
00376  * SearchScc() as presented in 
00377  * 
00378  * -- Aho, Hopcroft, Ullman: The Design and Analysis of Computer Algorithms --
00379  *
00380  * @param rGen
00381  *   Generator under investigation
00382  * @param rFilter
00383  *   Filter out specified transitions
00384  *
00385  * @return
00386  *   True if SCCs have been found, false if not.
00387  *
00388  * @ingroup GeneratorFunctions
00389  * 
00390  */
00391 bool HasScc(
00392   const Generator& rGen,
00393   const SccFilter& rFilter
00394 );
00395 
00396 
00397 /**
00398  * Compute next SCC
00399  *
00400  * This function provides an API for the iterative computation
00401  * of SCCs. It invokes SearchScc() to find the next SCC and then
00402  * adds the SCC to the StatesAvoid Filter. This approach is 
00403  * not computationally efficient but it allows for simple Lua wrappers.
00404  *    
00405  * @param rGen
00406  *   Generator under investigation
00407  * @param rFilter
00408  *   Filter out specified transitions
00409  * @param rScc
00410  *   First SCC that has been found, empty if no such.
00411  *
00412  * @return
00413  *   True if an SCC has been found, false if not.
00414  *
00415  * @ingroup GeneratorFunctions
00416  * 
00417  */
00418 bool ComputeNextScc(
00419   const Generator& rGen,
00420   SccFilter& rFilter,
00421   StateSet& rScc
00422 );
00423 
00424 } // namespace
00425 #endif

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen