spot
0.8.2
|
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