Vaucanson 1.4
|
00001 // boost_graph.hxx: this file is part of the Vaucanson project. 00002 // 00003 // Vaucanson, a generic library for finite state machines. 00004 // 00005 // Copyright (C) 2007, 2008 The Vaucanson Group. 00006 // 00007 // This program is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 00010 // of the License, or (at your option) any later version. 00011 // 00012 // The complete GNU General Public Licence Notice can be found as the 00013 // `COPYING' file in the root directory. 00014 // 00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file. 00016 // 00017 00018 #ifndef VCSN_AUTOMATA_IMPLEMENTATION_BMIG_GRAPH_LETTERS_SPEC_HXX_ 00019 # define VCSN_AUTOMATA_IMPLEMENTATION_BMIG_GRAPH_LETTERS_SPEC_HXX_ 00020 00021 # include <vaucanson/automata/implementation/bmig_graph_letters_spec.hh> 00022 00023 namespace vcsn 00024 { 00025 namespace bmig 00026 { 00027 00028 /*--------------------. 00029 | Convenient macros. | 00030 `--------------------*/ 00031 00032 # define BMIGRAPH_TPARAM \ 00033 template <class WordValue, \ 00034 class SeriesValue, class Letter, class Tag, class GeometryCoords> 00035 00036 # define BMIGRAPH \ 00037 Graph<labels_are_letters, WordValue, bool, SeriesValue, Letter, Tag, GeometryCoords> 00038 00039 /*-------------------------. 00040 | Graph's implementation. | 00041 `-------------------------*/ 00042 00043 /*---------------. 00044 | Constructors. | 00045 `---------------*/ 00046 00047 BMIGRAPH_TPARAM 00048 inline 00049 BMIGRAPH::Graph () 00050 : initial_bitset_(0), 00051 final_bitset_(0), 00052 number_of_epsilon_(0), 00053 number_of_state_(0) 00054 { 00055 } 00056 00066 BMIGRAPH_TPARAM 00067 BMIGRAPH::Graph (unsigned initial_number_of_states, 00068 unsigned) 00069 : initial_bitset_(initial_number_of_states), 00070 final_bitset_(initial_number_of_states), 00071 number_of_epsilon_(0), 00072 number_of_state_(initial_number_of_states), 00073 states_(initial_number_of_states) 00074 { 00075 for (unsigned i = 0; i < initial_number_of_states; ++i) 00076 { 00077 boost::shared_ptr<unsigned> p(new unsigned(i)); 00078 states_[i] = p; 00079 } 00080 } 00081 00082 BMIGRAPH_TPARAM 00083 BMIGRAPH::Graph (const self_t& g) 00084 { 00085 tag_ = g.tag_; 00086 initial_bitset_ = g.initial_bitset_; 00087 final_bitset_ = g.final_bitset_; 00088 number_of_epsilon_ = g.number_of_epsilon_; 00089 number_of_state_ = g.number_of_state_; 00090 00091 initial_.clear(); 00092 final_.clear(); 00093 graph_.clear(); 00094 typename geometry_t::transitions_geometry_map_t& map_transitions = geometry_.transitions(); 00095 map_transitions.clear(); 00096 00097 states_.resize(g.number_of_state_); 00098 for (unsigned i = 0; i < g.number_of_state_; ++i) 00099 { 00100 boost::shared_ptr<unsigned> p(new unsigned(i)); 00101 states_[i] = p; 00102 } 00103 for (typename graph_data_t::const_iterator i = g.graph_.begin(); 00104 i != g.graph_.end(); 00105 ++i) 00106 graph_.insert(edge_data_t(states_[*i->from_], 00107 states_[*i->to_], 00108 i->label_)); 00109 for (initial_t::iterator it = g.initial_.begin(); it != g.initial_.end(); ++it) 00110 initial_.insert(states_[**it]); 00111 for (final_t::iterator it = g.final_.begin(); it != g.final_.end(); ++it) 00112 final_.insert(states_[**it]); 00113 00114 # define VCSN_COPY_GEOMETRY(Type) \ 00115 { \ 00116 typename geometry_t::Type##_geometry_map_t& map_##Type = geometry_.Type(); \ 00117 map_##Type.clear(); \ 00118 for (typename geometry_t::Type##_geometry_map_t::const_iterator i = g.geometry_.Type().begin(); \ 00119 i != g.geometry_.Type().end(); \ 00120 ++i) \ 00121 map_##Type[i->first] = i->second; \ 00122 } 00123 VCSN_COPY_GEOMETRY(states) 00124 VCSN_COPY_GEOMETRY(initials) 00125 VCSN_COPY_GEOMETRY(finals) 00126 # undef VCSN_COPY_GEOMETRY 00127 { 00128 for (typename geometry_t::transitions_geometry_map_t::const_iterator i = g.geometry_.transitions().begin(); 00129 i != g.geometry_.transitions().end(); 00130 ++i) 00131 { 00132 typename graph_data_t::const_iterator tmp = find_edge(states_[*i->first.value()->from_], 00133 states_[*i->first.value()->to_], 00134 i->first.value()->label_); 00135 if (tmp != graph_.end()) 00136 map_transitions[htransition_t(tmp)] = i->second; 00137 } 00138 } 00139 } 00140 00141 /*--------------. 00142 | Destructors. | 00143 `--------------*/ 00144 00145 BMIGRAPH_TPARAM 00146 inline 00147 BMIGRAPH::~Graph () 00148 { 00149 } 00150 00151 BMIGRAPH_TPARAM 00152 typename BMIGRAPH::self_t& 00153 BMIGRAPH::operator= (const self_t& g) 00154 { 00155 if (this == &g) 00156 return *this; 00157 tag_ = g.tag_; 00158 initial_bitset_ = g.initial_bitset_; 00159 final_bitset_ = g.final_bitset_; 00160 number_of_epsilon_ = g.number_of_epsilon_; 00161 number_of_state_ = g.number_of_state_; 00162 00163 initial_.clear(); 00164 final_.clear(); 00165 graph_.clear(); 00166 typename geometry_t::transitions_geometry_map_t& map_transitions = geometry_.transitions(); 00167 map_transitions.clear(); 00168 00169 states_.resize(g.number_of_state_); 00170 for (unsigned i = 0; i < g.number_of_state_; ++i) 00171 { 00172 boost::shared_ptr<unsigned> p(new unsigned(i)); 00173 states_[i] = p; 00174 } 00175 for (typename graph_data_t::const_iterator i = g.graph_.begin(); 00176 i != g.graph_.end(); 00177 ++i) 00178 graph_.insert(edge_data_t(states_[*i->from_], 00179 states_[*i->to_], 00180 i->label_)); 00181 for (initial_t::iterator it = g.initial_.begin(); it != g.initial_.end(); ++it) 00182 initial_.insert(states_[**it]); 00183 for (final_t::iterator it = g.final_.begin(); it != g.final_.end(); ++it) 00184 final_.insert(states_[**it]); 00185 00186 # define VCSN_COPY_GEOMETRY(Type) \ 00187 { \ 00188 typename geometry_t::Type##_geometry_map_t& map_##Type = geometry_.Type(); \ 00189 map_##Type.clear(); \ 00190 for (typename geometry_t::Type##_geometry_map_t::const_iterator i = g.geometry_.Type().begin(); \ 00191 i != g.geometry_.Type().end(); \ 00192 ++i) \ 00193 map_##Type[i->first] = i->second; \ 00194 } 00195 VCSN_COPY_GEOMETRY(states) 00196 VCSN_COPY_GEOMETRY(initials) 00197 VCSN_COPY_GEOMETRY(finals) 00198 # undef VCSN_COPY_GEOMETRY 00199 for (typename geometry_t::transitions_geometry_map_t::const_iterator i = g.geometry_.transitions().begin(); 00200 i != g.geometry_.transitions().end(); 00201 ++i) 00202 { 00203 typename graph_data_t::const_iterator tmp = find_edge(states_[*i->first.value()->from_], 00204 states_[*i->first.value()->to_], 00205 i->first.value()->label_); 00206 if (tmp != graph_.end()) 00207 map_transitions[htransition_t(tmp)] = i->second; 00208 } 00209 return *this; 00210 } 00211 00212 /*------------------. 00213 | Basic accessors. | 00214 `------------------*/ 00215 00216 BMIGRAPH_TPARAM 00217 typename BMIGRAPH::states_t 00218 BMIGRAPH::states() const 00219 { 00220 return misc::Support<states_data_t>(states_); 00221 } 00222 00223 BMIGRAPH_TPARAM 00224 typename BMIGRAPH::edges_t 00225 BMIGRAPH::edges() const 00226 { 00227 return edges_t(graph_); 00228 } 00229 00230 BMIGRAPH_TPARAM 00231 typename BMIGRAPH::initial_support_t 00232 BMIGRAPH::initial () const 00233 { 00234 return initial_support_t(initial_); 00235 } 00236 00237 BMIGRAPH_TPARAM 00238 typename BMIGRAPH::final_support_t 00239 BMIGRAPH::final () const 00240 { 00241 return final_support_t(final_); 00242 } 00243 00244 00245 /*----------------------. 00246 | State manipulations. | 00247 `----------------------*/ 00248 00249 BMIGRAPH_TPARAM 00250 bool 00251 BMIGRAPH::has_state (const hstate_t& s) const 00252 { 00253 return s < states_.size(); 00254 } 00255 00256 BMIGRAPH_TPARAM 00257 typename BMIGRAPH::hstate_t 00258 BMIGRAPH::add_state () 00259 { 00260 initial_bitset_.append(false); 00261 final_bitset_.append(false); 00262 boost::shared_ptr<unsigned> p(new unsigned(number_of_state_++)); 00263 state_t h(p); 00264 states_.push_back(h); 00265 return hstate_t(h); 00266 } 00267 00268 BMIGRAPH_TPARAM 00269 typename BMIGRAPH::hstate_t 00270 BMIGRAPH::get_state (unsigned s) const 00271 { 00272 precondition(s < states_.size()); 00273 return hstate_t(states_[s]); 00274 } 00275 00276 BMIGRAPH_TPARAM 00277 void 00278 BMIGRAPH::del_state (const hstate_t& s) 00279 { 00280 precondition (has_state(s)); 00281 00282 // One removes the state h 00283 graph_.get<src>().erase(s.value()); 00284 graph_.get<dst>().erase(s.value()); 00285 00286 if (number_of_state_ > 1 && s != (number_of_state_ - 1)) 00287 { 00288 state_t lastone = states_.back(); 00289 states_[s] = lastone; 00290 # define VCSN_UPDATE(Set) \ 00291 if (Set##bitset_[*lastone]) \ 00292 { \ 00293 if (Set##bitset_[s]) \ 00294 Set.erase(s.value()); \ 00295 else \ 00296 Set##bitset_[s] = true; \ 00297 } \ 00298 else \ 00299 { \ 00300 if (Set##bitset_[s]) \ 00301 { \ 00302 Set##bitset_[s] = false; \ 00303 Set.erase(s.value()); \ 00304 } \ 00305 } 00306 00307 //Updating initial/final states information 00308 VCSN_UPDATE(initial_) 00309 VCSN_UPDATE(final_) 00310 # undef VCSN_UPDATE 00311 *lastone = *s.value(); 00312 } 00313 else 00314 { 00315 initial_.erase(s.value()); 00316 final_.erase(s.value()); 00317 } 00318 00319 --number_of_state_; 00320 states_.pop_back(); 00321 postcondition(states_.size() == number_of_state_); 00322 initial_bitset_.resize(number_of_state_); 00323 final_bitset_.resize(number_of_state_); 00324 00325 //Useless postcondition since the states are renumbered 00326 //postcondition(!has_state(h)); 00327 } 00328 00329 BMIGRAPH_TPARAM 00330 void 00331 BMIGRAPH::set_initial (const hstate_t& s, 00332 const series_set_elt_value_t& v, 00333 const series_set_elt_value_t& z) 00334 { 00335 precondition(has_state(s)); 00336 if (z == v) 00337 { 00338 initial_.erase (s.value()); 00339 initial_bitset_[s] = false; 00340 } 00341 else 00342 { 00343 initial_.insert (s.value()); 00344 initial_bitset_[s] = true; 00345 } 00346 } 00347 00348 BMIGRAPH_TPARAM 00349 const typename BMIGRAPH::series_set_elt_value_t& 00350 BMIGRAPH::get_initial(const hstate_t& s, const series_set_elt_value_t &) const 00351 { 00352 precondition(has_state(s)); 00353 return initial_bitset_[s]; 00354 } 00355 00356 BMIGRAPH_TPARAM 00357 bool 00358 BMIGRAPH::is_initial(const hstate_t& s, const series_set_elt_value_t&) const 00359 { 00360 precondition(has_state(s)); 00361 return initial_bitset_[s]; 00362 } 00363 00364 BMIGRAPH_TPARAM 00365 void 00366 BMIGRAPH::clear_initial() 00367 { 00368 initial_.clear(); 00369 initial_bitset_.reset(); 00370 } 00371 00372 BMIGRAPH_TPARAM 00373 void 00374 BMIGRAPH::set_final(const hstate_t& s, 00375 const series_set_elt_value_t& v, 00376 const series_set_elt_value_t& z) 00377 { 00378 precondition(has_state(s)); 00379 if (z == v) 00380 { 00381 final_.erase (s.value()); 00382 final_bitset_[s] = false; 00383 } 00384 else 00385 { 00386 final_.insert (s.value()); 00387 final_bitset_[s] = true; 00388 } 00389 } 00390 00391 BMIGRAPH_TPARAM 00392 const typename BMIGRAPH::series_set_elt_value_t& 00393 BMIGRAPH::get_final(const hstate_t& s, const series_set_elt_value_t &) const 00394 { 00395 precondition(has_state(s)); 00396 return final_bitset_[s]; 00397 } 00398 00399 BMIGRAPH_TPARAM 00400 bool 00401 BMIGRAPH::is_final(const hstate_t& s, const series_set_elt_value_t&) const 00402 { 00403 precondition(has_state(s)); 00404 return final_bitset_[s]; 00405 } 00406 00407 BMIGRAPH_TPARAM 00408 void 00409 BMIGRAPH::clear_final() 00410 { 00411 final_.clear(); 00412 final_bitset_.reset(); 00413 } 00414 00415 /*---------------------. 00416 | Edge manipulations. | 00417 `---------------------*/ 00418 00419 BMIGRAPH_TPARAM 00420 bool 00421 BMIGRAPH::has_edge (const hedge_t& h) const 00422 { 00423 succ_range r = graph_.equal_range(boost::make_tuple(*h.value()->from_, 00424 h.value()->label_)); 00425 succ_iterator it; 00426 state_t to = h.value()->to_; 00427 for (it = r.first; it != r.second && it->to_ != to; ++it) 00428 /*Nothing*/; 00429 00430 return it != r.second; 00431 } 00432 00433 BMIGRAPH_TPARAM 00434 typename BMIGRAPH::hedge_t 00435 BMIGRAPH::add_edge (const hstate_t& from, const hstate_t& to, const label_t& l) 00436 { 00437 return hedge_t (graph_.insert (edge_data_t (from.value(), to.value(), l)).first); 00438 } 00439 00440 BMIGRAPH_TPARAM 00441 void 00442 BMIGRAPH::del_edge (const hedge_t& h) 00443 { 00444 precondition (has_edge(h)); 00445 graph_.erase(h.value()); 00446 00447 // h points to an invalid edgeValue since it is already destroyed. 00448 // We can't check this postcondition anymore! 00449 //postcondition(!has_edge(h)); 00450 } 00451 00452 BMIGRAPH_TPARAM 00453 typename BMIGRAPH::hstate_t 00454 BMIGRAPH::src_of (const hedge_t& h) const 00455 { 00456 return hstate_t(h.value()->from_); 00457 } 00458 00459 BMIGRAPH_TPARAM 00460 typename BMIGRAPH::hstate_t 00461 BMIGRAPH::dst_of (const hedge_t& h) const 00462 { 00463 return hstate_t(h.value()->to_); 00464 } 00465 00466 BMIGRAPH_TPARAM 00467 const typename BMIGRAPH::label_t& 00468 BMIGRAPH::label_of (const hedge_t& h) const 00469 { 00470 return h.value()->label_; 00471 } 00472 00473 BMIGRAPH_TPARAM 00474 void 00475 BMIGRAPH::update(const hedge_t& h, const label_t& l) 00476 { 00477 graph_.modify(h.value(), update_hlabel<label_t>(l)); 00478 } 00479 00480 BMIGRAPH_TPARAM 00481 template <class S> 00482 bool 00483 BMIGRAPH::exists (const AutomataBase<S>& s) const 00484 { 00485 typename WordValue::iterator it; 00486 typename label_t::const_iterator r; 00487 label_t l; 00488 WordValue w; 00489 00490 for (typename graph_data_t::iterator i = graph_.begin(); i != graph_.end(); ++i) 00491 { 00492 // Make sure that source and destination of edge are part of the 00493 // automaton. 00494 if (!has_state(dst_of(hedge_t(i))) || 00495 !has_state(src_of(hedge_t(i)))) 00496 return false; 00497 00498 // Make sure that every letter of the edge is in the alphabet. 00499 l = label_of(hedge_t(i)); 00500 for (r = l.begin(); r != l.end(); ++r) 00501 { 00502 w = r->first; 00503 for (it = w.begin(); it != w.end(); ++it) 00504 if (!s.series().monoid().alphabet().contains(*it)) 00505 return false; 00506 } 00507 } 00508 return true; 00509 } 00510 00511 BMIGRAPH_TPARAM 00512 inline 00513 typename BMIGRAPH::tag_t& 00514 BMIGRAPH::tag () 00515 { 00516 return tag_; 00517 } 00518 00519 BMIGRAPH_TPARAM 00520 inline 00521 const typename BMIGRAPH::tag_t& 00522 BMIGRAPH::tag () const 00523 { 00524 return tag_; 00525 } 00526 00527 BMIGRAPH_TPARAM 00528 inline 00529 typename BMIGRAPH::geometry_t& 00530 BMIGRAPH::geometry () 00531 { 00532 return geometry_; 00533 } 00534 00535 BMIGRAPH_TPARAM 00536 inline 00537 const typename BMIGRAPH::geometry_t& 00538 BMIGRAPH::geometry () const 00539 { 00540 return geometry_; 00541 } 00542 00543 template <class WordValue, class SeriesValue, 00544 class Letter, class Tag, class GeometryCoords, class I> 00545 Tag& 00546 op_tag(const AutomataBase<I>&, BMIGRAPH &g) 00547 { 00548 return g.tag(); 00549 } 00550 00551 template <class WordValue, class SeriesValue, 00552 class Letter, class Tag, class GeometryCoords, class I> 00553 const Tag& 00554 op_tag(const AutomataBase<I>&, BMIGRAPH &g) 00555 { 00556 return g.tag(); 00557 } 00558 00559 template <class WordValue, class SeriesValue, 00560 class Letter, class Tag, class GeometryCoords, class I> 00561 typename BMIGRAPH::geometry_t& 00562 op_geometry(const AutomataBase<I>&, BMIGRAPH &g) 00563 { 00564 return g.geometry(); 00565 } 00566 00567 template <class WordValue, class SeriesValue, 00568 class Letter, class Tag, class GeometryCoords, class I> 00569 const typename BMIGRAPH::geometry_t& 00570 op_geometry(const AutomataBase<I>&, const BMIGRAPH &g) 00571 { 00572 return g.geometry(); 00573 } 00574 00575 BMIGRAPH_TPARAM 00576 typename BMIGRAPH::graph_data_t::const_iterator 00577 BMIGRAPH::find_edge(const state_t& from, const state_t& to, 00578 const label_t& label) const 00579 { 00580 succ_range r = graph_.equal_range(::boost::make_tuple(from, label)); 00581 for (succ_iterator i = r.first; i != r.second; ++i) 00582 if (i->to_ == to) 00583 return i; 00584 return graph_.end(); 00585 } 00586 00587 /*------------------. 00588 | Delta functions. | 00589 `------------------*/ 00590 # define DEFINE_DELTA_FUNCTION(FunName, DeltaKind, Target, GetElt) \ 00591 BMIGRAPH_TPARAM \ 00592 template <typename OutputIterator, typename Query> \ 00593 void \ 00594 BMIGRAPH::FunName(OutputIterator res, \ 00595 const typename BMIGRAPH::hstate_t& s, \ 00596 const Query& query, \ 00597 ::vcsn::delta_kind::DeltaKind) const \ 00598 { \ 00599 assertion(has_state(s)); \ 00600 Target##_range r = graph_.get<Target>().equal_range(s.value()); \ 00601 for (Target##_iterator e = r.first; e != r.second; ++e) \ 00602 if (query(hedge_t(graph_.project<0>(e)))) \ 00603 *res++ = GetElt; \ 00604 } 00605 00606 DEFINE_DELTA_FUNCTION (delta, transitions, src, hedge_t(graph_.project<0>(e))); 00607 DEFINE_DELTA_FUNCTION (delta, states, src, hstate_t(e->to_)); 00608 DEFINE_DELTA_FUNCTION (rdelta, transitions, dst, hedge_t(graph_.project<0>(e))); 00609 DEFINE_DELTA_FUNCTION (rdelta, states, dst, hstate_t(e->from_)); 00610 00611 # undef DEFINE_DELTA_FUNCTION 00612 00613 00614 // End of syntactic sugar 00615 # undef BMIGRAPH_TPARAM 00616 # undef BMIGRAPH 00617 } // End of namespace boost 00618 } // End of namespace vcsn 00619 00620 #endif // !VCSN_AUTOMATA_IMPLEMENTATION_BMIG_GRAPH_IMPL_HXX_ //