Vaucanson 1.4
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_ //