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