spot  0.8.3
tgbaexplicit.hh
Go to the documentation of this file.
00001 // Copyright (C) 2009, 2010, 2011 Laboratoire de Recherche et Développement
00002 // de l'Epita (LRDE).
00003 // Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de
00004 // Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
00005 // Université Pierre et Marie Curie.
00006 //
00007 // This file is part of Spot, a model checking library.
00008 //
00009 // Spot is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by
00011 // the Free Software Foundation; either version 2 of the License, or
00012 // (at your option) any later version.
00013 //
00014 // Spot is distributed in the hope that it will be useful, but WITHOUT
00015 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00016 // or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
00017 // License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with Spot; see the file COPYING.  If not, write to the Free
00021 // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00022 // 02111-1307, USA.
00023 
00024 #ifndef SPOT_TGBA_TGBAEXPLICIT_HH
00025 # define SPOT_TGBA_TGBAEXPLICIT_HH
00026 
00027 #include "misc/hash.hh"
00028 #include <list>
00029 #include "tgba.hh"
00030 #include "ltlast/formula.hh"
00031 #include <cassert>
00032 
00033 namespace spot
00034 {
00035   // Forward declarations.  See below.
00036   class state_explicit;
00037   class tgba_explicit_succ_iterator;
00038   class tgba_explicit;
00039 
00042   class state_explicit: public spot::state
00043   {
00044   public:
00045     state_explicit()
00046     {
00047     }
00048 
00049     virtual int compare(const spot::state* other) const;
00050     virtual size_t hash() const;
00051 
00052     virtual state_explicit* clone() const
00053     {
00054       return const_cast<state_explicit*>(this);
00055     }
00056 
00057     bool empty() const
00058     {
00059       return successors.empty();
00060     }
00061 
00062     virtual
00063     void destroy() const
00064     {
00065     }
00066 
00068     struct transition
00069     {
00070       bdd condition;
00071       bdd acceptance_conditions;
00072       const state_explicit* dest;
00073     };
00074 
00075     typedef std::list<transition> transitions_t;
00076     transitions_t successors;
00077   private:
00078     state_explicit(const state_explicit& other);
00079     state_explicit& operator=(const state_explicit& other);
00080 
00081     virtual ~state_explicit()
00082     {
00083     }
00084     friend class tgba_explicit_string;
00085     friend class tgba_explicit_formula;
00086     friend class tgba_explicit_number;
00087   };
00088 
00089 
00092   class tgba_explicit: public tgba
00093   {
00094   public:
00095     typedef state_explicit state;
00096     typedef state_explicit::transition transition;
00097 
00098     tgba_explicit(bdd_dict* dict);
00099 
00101     virtual state* add_default_init() = 0;
00102 
00103     transition*
00104     create_transition(state* source, const state* dest);
00105 
00106     void add_condition(transition* t, const ltl::formula* f);
00108     void add_conditions(transition* t, bdd f);
00109 
00114     void copy_acceptance_conditions_of(const tgba *a);
00115 
00117     void set_acceptance_conditions(bdd acc);
00118 
00119     bool has_acceptance_condition(const ltl::formula* f) const;
00120     void add_acceptance_condition(transition* t, const ltl::formula* f);
00122     void add_acceptance_conditions(transition* t, bdd f);
00123 
00124     // tgba interface
00125     virtual ~tgba_explicit();
00126     virtual spot::state* get_init_state() const;
00127     virtual tgba_succ_iterator*
00128     succ_iter(const spot::state* local_state,
00129               const spot::state* global_state = 0,
00130               const tgba* global_automaton = 0) const;
00131     virtual bdd_dict* get_dict() const;
00132 
00133     virtual bdd all_acceptance_conditions() const;
00134     virtual bdd neg_acceptance_conditions() const;
00135 
00136     virtual std::string format_state(const spot::state* s) const = 0;
00137 
00138   protected:
00139     virtual bdd compute_support_conditions(const spot::state* state) const;
00140     virtual bdd compute_support_variables(const spot::state* state) const;
00141 
00142     bdd get_acceptance_condition(const ltl::formula* f);
00143 
00144     bdd_dict* dict_;
00145     state_explicit* init_;
00146     mutable bdd all_acceptance_conditions_;
00147     bdd neg_acceptance_conditions_;
00148     mutable bool all_acceptance_conditions_computed_;
00149 
00150   private:
00151     // Disallow copy.
00152     tgba_explicit(const tgba_explicit& other);
00153     tgba_explicit& operator=(const tgba_explicit& other);
00154   };
00155 
00156 
00157 
00160   class tgba_explicit_succ_iterator: public tgba_succ_iterator
00161   {
00162   public:
00163     tgba_explicit_succ_iterator(const state_explicit::transitions_t* s,
00164                                 bdd all_acc);
00165 
00166     virtual void first();
00167     virtual void next();
00168     virtual bool done() const;
00169 
00170     virtual state_explicit* current_state() const;
00171     virtual bdd current_condition() const;
00172     virtual bdd current_acceptance_conditions() const;
00173 
00174   private:
00175     const state_explicit::transitions_t* s_;
00176     state_explicit::transitions_t::const_iterator i_;
00177     bdd all_acceptance_conditions_;
00178   };
00179 
00181   template<typename label, typename label_hash>
00182   class tgba_explicit_labelled: public tgba_explicit
00183   {
00184   protected:
00185     typedef label label_t;
00186     typedef Sgi::hash_map<label, state_explicit*,
00187                           label_hash> ns_map;
00188     typedef Sgi::hash_map<const state_explicit*, label,
00189                           ptr_hash<state_explicit> > sn_map;
00190     ns_map name_state_map_;
00191     sn_map state_name_map_;
00192   public:
00193     tgba_explicit_labelled(bdd_dict* dict) : tgba_explicit(dict) {};
00194 
00195     bool has_state(const label& name)
00196     {
00197       return name_state_map_.find(name) != name_state_map_.end();
00198     }
00199 
00200     const label& get_label(const state_explicit* s) const
00201     {
00202       typename sn_map::const_iterator i = state_name_map_.find(s);
00203       assert(i != state_name_map_.end());
00204       return i->second;
00205     }
00206 
00207     const label& get_label(const spot::state* s) const
00208     {
00209       const state_explicit* se = down_cast<const state_explicit*>(s);
00210       assert(se);
00211       return get_label(se);
00212     }
00213 
00216     state* add_state(const label& name)
00217     {
00218       typename ns_map::iterator i = name_state_map_.find(name);
00219       if (i == name_state_map_.end())
00220         {
00221           state_explicit* s = new state_explicit;
00222           name_state_map_[name] = s;
00223           state_name_map_[s] = name;
00224 
00225           // The first state we add is the inititial state.
00226           // It can also be overridden with set_init_state().
00227           if (!init_)
00228             init_ = s;
00229 
00230           return s;
00231         }
00232       return i->second;
00233     }
00234 
00235     state*
00236     set_init_state(const label& state)
00237     {
00238       state_explicit* s = add_state(state);
00239       init_ = s;
00240       return s;
00241     }
00242 
00243 
00244     transition*
00245     create_transition(state* source, const state* dest)
00246     {
00247       return tgba_explicit::create_transition(source, dest);
00248     }
00249 
00250     transition*
00251     create_transition(const label& source, const label& dest)
00252     {
00253       // It's important that the source be created before the
00254       // destination, so the first source encountered becomes the
00255       // default initial state.
00256       state* s = add_state(source);
00257       return tgba_explicit::create_transition(s, add_state(dest));
00258     }
00259 
00260     void
00261     complement_all_acceptance_conditions()
00262     {
00263       bdd all = all_acceptance_conditions();
00264       typename ns_map::iterator i;
00265       for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i)
00266         {
00267           state_explicit::transitions_t::iterator i2;
00268           for (i2 = i->second->successors.begin();
00269                i2 != i->second->successors.end(); ++i2)
00270             {
00271               i2->acceptance_conditions = all - i2->acceptance_conditions;
00272             }
00273         }
00274     }
00275 
00276     void
00277     declare_acceptance_condition(const ltl::formula* f)
00278     {
00279       int v = dict_->register_acceptance_variable(f, this);
00280       f->destroy();
00281       bdd neg = bdd_nithvar(v);
00282       neg_acceptance_conditions_ &= neg;
00283 
00284       // Append neg to all acceptance conditions.
00285       typename ns_map::iterator i;
00286       for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i)
00287         {
00288           state_explicit::transitions_t::iterator i2;
00289           for (i2 = i->second->successors.begin();
00290                i2 != i->second->successors.end(); ++i2)
00291             i2->acceptance_conditions &= neg;
00292         }
00293 
00294       all_acceptance_conditions_computed_ = false;
00295     }
00296 
00297 
00298     void
00299     merge_transitions()
00300     {
00301       typename ns_map::iterator i;
00302       for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i)
00303         {
00304           state_explicit::transitions_t::iterator t1;
00305           for (t1 = i->second->successors.begin();
00306                t1 != i->second->successors.end(); ++t1)
00307             {
00308               bdd acc = t1->acceptance_conditions;
00309               const state* dest = t1->dest;
00310 
00311               // Find another transition with the same destination and
00312               // acceptance conditions.
00313               state_explicit::transitions_t::iterator t2 = t1;
00314               ++t2;
00315               while (t2 != i->second->successors.end())
00316                 {
00317                   state_explicit::transitions_t::iterator t2copy = t2++;
00318                   if (t2copy->acceptance_conditions == acc
00319                       && t2copy->dest == dest)
00320                     {
00321                       t1->condition |= t2copy->condition;
00322                       i->second->successors.erase(t2copy);
00323                     }
00324                 }
00325             }
00326         }
00327     }
00328 
00329 
00330     virtual
00331     ~tgba_explicit_labelled()
00332     {
00333       // These have already been destroyed by subclasses.
00334       // Prevent destroying by tgba::~tgba.
00335       last_support_conditions_input_ = 0;
00336       last_support_variables_input_ = 0;
00337     }
00338 
00339   };
00340 
00341 #ifndef SWIG
00342   class tgba_explicit_string:
00343     public tgba_explicit_labelled<std::string, string_hash>
00344   {
00345   public:
00346     tgba_explicit_string(bdd_dict* dict):
00347       tgba_explicit_labelled<std::string, string_hash>(dict)
00348     {};
00349     virtual ~tgba_explicit_string();
00350     virtual state* add_default_init();
00351     virtual std::string format_state(const spot::state* s) const;
00352 
00355     virtual
00356     void add_state_alias(const std::string& alias_name,
00357                          const std::string& real_name)
00358     {
00359       name_state_map_[alias_name] = add_state(real_name);
00360     }
00361   };
00362 #else
00363   class tgba_explicit_string: public tgba
00364   {
00365   };
00366 #endif
00367 
00368 #ifndef SWIG
00369   class tgba_explicit_formula:
00370     public tgba_explicit_labelled<const ltl::formula*, ltl::formula_ptr_hash>
00371   {
00372   public:
00373     tgba_explicit_formula(bdd_dict* dict):
00374       tgba_explicit_labelled<const ltl::formula*, ltl::formula_ptr_hash>(dict)
00375     {};
00376     virtual ~tgba_explicit_formula();
00377     virtual state* add_default_init();
00378     virtual std::string format_state(const spot::state* s) const;
00379   };
00380 #else
00381   class tgba_explicit_formula: public tgba
00382   {
00383   };
00384 #endif
00385 
00386 #ifndef SWIG
00387   class tgba_explicit_number:
00388     public tgba_explicit_labelled<int, identity_hash<int> >
00389   {
00390   public:
00391     tgba_explicit_number(bdd_dict* dict):
00392       tgba_explicit_labelled<int, identity_hash<int> >(dict)
00393     {};
00394     virtual ~tgba_explicit_number();
00395     virtual state* add_default_init();
00396     virtual std::string format_state(const spot::state* s) const;
00397   };
00398 #else
00399   class tgba_explicit_number: public tgba
00400   {
00401   };
00402 #endif
00403 }
00404 
00405 #endif // SPOT_TGBA_TGBAEXPLICIT_HH

Please comment this page and report errors about it on the RefDocComments page.
Generated on Fri Mar 9 2012 13:52:09 for spot by doxygen 1.7.6.1