- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# bmig_graph_impl.hxx

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