spot
0.8.2
|
00001 // Copyright (C) 2009, 2011 Laboratoire de Recherche et Développement 00002 // de l'Epita (LRDE). 00003 // 00004 // This file is part of Spot, a model checking library. 00005 // 00006 // Spot is free software; you can redistribute it and/or modify it 00007 // under the terms of the GNU General Public License as published by 00008 // the Free Software Foundation; either version 2 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // Spot is distributed in the hope that it will be useful, but WITHOUT 00012 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 00013 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 00014 // License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with Spot; see the file COPYING. If not, write to the Free 00018 // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00019 // 02111-1307, USA. 00020 00021 #ifndef SPOT_TGBA_TAATGBA_HH 00022 # define SPOT_TGBA_TAATGBA_HH 00023 00024 #include <set> 00025 #include <iosfwd> 00026 #include <vector> 00027 #include "misc/hash.hh" 00028 #include "ltlast/formula.hh" 00029 #include "bdddict.hh" 00030 #include "tgba.hh" 00031 00032 namespace spot 00033 { 00036 class taa_tgba : public tgba 00037 { 00038 public: 00039 taa_tgba(bdd_dict* dict); 00040 00041 struct transition; 00042 typedef std::list<transition*> state; 00043 typedef std::set<state*> state_set; 00044 00046 struct transition 00047 { 00048 bdd condition; 00049 bdd acceptance_conditions; 00050 const state_set* dst; 00051 }; 00052 00053 void add_condition(transition* t, const ltl::formula* f); 00054 00056 virtual ~taa_tgba(); 00057 virtual spot::state* get_init_state() const; 00058 virtual tgba_succ_iterator* 00059 succ_iter(const spot::state* local_state, 00060 const spot::state* global_state = 0, 00061 const tgba* global_automaton = 0) const; 00062 virtual bdd_dict* get_dict() const; 00063 virtual std::string format_state(const spot::state* state) const = 0; 00064 virtual bdd all_acceptance_conditions() const; 00065 virtual bdd neg_acceptance_conditions() const; 00066 00067 protected: 00068 virtual bdd compute_support_conditions(const spot::state* state) const; 00069 virtual bdd compute_support_variables(const spot::state* state) const; 00070 00071 typedef std::vector<taa_tgba::state_set*> ss_vec; 00072 00073 bdd_dict* dict_; 00074 mutable bdd all_acceptance_conditions_; 00075 mutable bool all_acceptance_conditions_computed_; 00076 bdd neg_acceptance_conditions_; 00077 taa_tgba::state_set* init_; 00078 ss_vec state_set_vec_; 00079 00080 private: 00081 // Disallow copy. 00082 taa_tgba(const taa_tgba& other); 00083 taa_tgba& operator=(const taa_tgba& other); 00084 }; 00085 00087 class state_set : public spot::state 00088 { 00089 public: 00090 state_set(const taa_tgba::state_set* s, bool delete_me = false) 00091 : s_(s), delete_me_(delete_me) 00092 { 00093 } 00094 00095 virtual int compare(const spot::state*) const; 00096 virtual size_t hash() const; 00097 virtual state_set* clone() const; 00098 00099 virtual ~state_set() 00100 { 00101 if (delete_me_) 00102 delete s_; 00103 } 00104 00105 const taa_tgba::state_set* get_state() const; 00106 private: 00107 const taa_tgba::state_set* s_; 00108 bool delete_me_; 00109 }; 00110 00111 class taa_succ_iterator : public tgba_succ_iterator 00112 { 00113 public: 00114 taa_succ_iterator(const taa_tgba::state_set* s, bdd all_acc); 00115 virtual ~taa_succ_iterator(); 00116 00117 virtual void first(); 00118 virtual void next(); 00119 virtual bool done() const; 00120 00121 virtual state_set* current_state() const; 00122 virtual bdd current_condition() const; 00123 virtual bdd current_acceptance_conditions() const; 00124 00125 private: 00128 typedef taa_tgba::state::const_iterator iterator; 00129 typedef std::pair<iterator, iterator> iterator_pair; 00130 typedef std::vector<iterator_pair> bounds_t; 00131 typedef Sgi::hash_map< 00132 const spot::state_set*, std::vector<taa_tgba::transition*>, 00133 state_ptr_hash, state_ptr_equal> seen_map; 00134 00135 struct distance_sort : 00136 public std::binary_function<const iterator_pair&, 00137 const iterator_pair&, bool> 00138 { 00139 bool 00140 operator()(const iterator_pair& lhs, const iterator_pair& rhs) const 00141 { 00142 return std::distance(lhs.first, lhs.second) < 00143 std::distance(rhs.first, rhs.second); 00144 } 00145 }; 00146 00147 std::vector<taa_tgba::transition*>::const_iterator i_; 00148 std::vector<taa_tgba::transition*> succ_; 00149 bdd all_acceptance_conditions_; 00150 seen_map seen_; 00151 }; 00152 00155 template<typename label, typename label_hash> 00156 class taa_tgba_labelled : public taa_tgba 00157 { 00158 public: 00159 taa_tgba_labelled(bdd_dict* dict) : taa_tgba(dict) {}; 00160 00161 void set_init_state(const label& s) 00162 { 00163 std::vector<label> v(1); 00164 v[0] = s; 00165 set_init_state(v); 00166 } 00167 void set_init_state(const std::vector<label>& s) 00168 { 00169 init_ = add_state_set(s); 00170 } 00171 00172 transition* 00173 create_transition(const label& s, 00174 const std::vector<label>& d) 00175 { 00176 state* src = add_state(s); 00177 state_set* dst = add_state_set(d); 00178 transition* t = new transition; 00179 t->dst = dst; 00180 t->condition = bddtrue; 00181 t->acceptance_conditions = bddfalse; 00182 src->push_back(t); 00183 return t; 00184 } 00185 transition* 00186 create_transition(const label& s, const label& d) 00187 { 00188 std::vector<std::string> vec; 00189 vec.push_back(d); 00190 return create_transition(s, vec); 00191 } 00192 00193 void add_acceptance_condition(transition* t, const ltl::formula* f) 00194 { 00195 if (dict_->acc_map.find(f) == dict_->acc_map.end()) 00196 { 00197 int v = dict_->register_acceptance_variable(f, this); 00198 bdd neg = bdd_nithvar(v); 00199 neg_acceptance_conditions_ &= neg; 00200 00201 // Append neg to all acceptance conditions. 00202 typename ns_map::iterator i; 00203 for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i) 00204 { 00205 taa_tgba::state::iterator i2; 00206 for (i2 = i->second->begin(); i2 != i->second->end(); ++i2) 00207 (*i2)->acceptance_conditions &= neg; 00208 } 00209 00210 all_acceptance_conditions_computed_ = false; 00211 } 00212 00213 bdd_dict::fv_map::iterator i = dict_->acc_map.find(f); 00214 assert(i != dict_->acc_map.end()); 00215 f->destroy(); 00216 bdd v = bdd_ithvar(i->second); 00217 t->acceptance_conditions |= v & bdd_exist(neg_acceptance_conditions_, v); 00218 } 00219 00228 virtual std::string format_state(const spot::state* s) const 00229 { 00230 const spot::state_set* se = down_cast<const spot::state_set*>(s); 00231 assert(se); 00232 const state_set* ss = se->get_state(); 00233 return format_state_set(ss); 00234 } 00235 00237 void output(std::ostream& os) const 00238 { 00239 typename ns_map::const_iterator i; 00240 for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i) 00241 { 00242 taa_tgba::state::const_iterator i2; 00243 os << "State: " << label_to_string(i->first) << std::endl; 00244 for (i2 = i->second->begin(); i2 != i->second->end(); ++i2) 00245 { 00246 os << " " << format_state_set((*i2)->dst) 00247 << ", C:" << (*i2)->condition 00248 << ", A:" << (*i2)->acceptance_conditions << std::endl; 00249 } 00250 } 00251 } 00252 00253 protected: 00254 typedef label label_t; 00255 00256 typedef Sgi::hash_map< 00257 const label, taa_tgba::state*, label_hash 00258 > ns_map; 00259 typedef Sgi::hash_map< 00260 const taa_tgba::state*, label, ptr_hash<taa_tgba::state> 00261 > sn_map; 00262 00263 ns_map name_state_map_; 00264 sn_map state_name_map_; 00265 00267 virtual std::string label_to_string(const label_t& lbl) const = 0; 00268 00271 virtual label_t clone_if(const label_t& lbl) const = 0; 00272 00273 private: 00276 taa_tgba::state* add_state(const label& name) 00277 { 00278 typename ns_map::iterator i = name_state_map_.find(name); 00279 if (i == name_state_map_.end()) 00280 { 00281 const label& name_ = clone_if(name); 00282 taa_tgba::state* s = new taa_tgba::state; 00283 name_state_map_[name_] = s; 00284 state_name_map_[s] = name_; 00285 return s; 00286 } 00287 return i->second; 00288 } 00289 00291 taa_tgba::state_set* add_state_set(const std::vector<label>& names) 00292 { 00293 state_set* ss = new state_set; 00294 for (unsigned i = 0; i < names.size(); ++i) 00295 ss->insert(add_state(names[i])); 00296 state_set_vec_.push_back(ss); 00297 return ss; 00298 } 00299 00300 std::string format_state_set(const taa_tgba::state_set* ss) const 00301 { 00302 state_set::const_iterator i1 = ss->begin(); 00303 typename sn_map::const_iterator i2; 00304 if (ss->empty()) 00305 return std::string("{}"); 00306 if (ss->size() == 1) 00307 { 00308 i2 = state_name_map_.find(*i1); 00309 assert(i2 != state_name_map_.end()); 00310 return "{" + label_to_string(i2->second) + "}"; 00311 } 00312 else 00313 { 00314 std::string res("{"); 00315 while (i1 != ss->end()) 00316 { 00317 i2 = state_name_map_.find(*i1++); 00318 assert(i2 != state_name_map_.end()); 00319 res += label_to_string(i2->second); 00320 res += ","; 00321 } 00322 res[res.size() - 1] = '}'; 00323 return res; 00324 } 00325 } 00326 }; 00327 00328 class taa_tgba_string : 00329 public taa_tgba_labelled<std::string, string_hash> 00330 { 00331 public: 00332 taa_tgba_string(bdd_dict* dict) : 00333 taa_tgba_labelled<std::string, string_hash>(dict) {}; 00334 ~taa_tgba_string(); 00335 protected: 00336 virtual std::string label_to_string(const std::string& label) const; 00337 virtual std::string clone_if(const std::string& label) const; 00338 }; 00339 00340 class taa_tgba_formula : 00341 public taa_tgba_labelled<const ltl::formula*, ltl::formula_ptr_hash> 00342 { 00343 public: 00344 taa_tgba_formula(bdd_dict* dict) : 00345 taa_tgba_labelled<const ltl::formula*, ltl::formula_ptr_hash>(dict) {}; 00346 ~taa_tgba_formula(); 00347 protected: 00348 virtual std::string label_to_string(const label_t& label) const; 00349 virtual ltl::formula* clone_if(const label_t& label) const; 00350 }; 00351 } 00352 00353 #endif // SPOT_TGBA_TAATGBA_HH