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