Vaucanson 1.4
automata_ops.hxx
00001 // automata_ops.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 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 #ifndef VCSN_AUTOMATA_CONCEPT_AUTOMATA_OPS_HXX
00018 # define VCSN_AUTOMATA_CONCEPT_AUTOMATA_OPS_HXX
00019 
00020 # include <iterator>
00021 # include <set>
00022 # include <vaucanson/misc/random.hh>
00023 # include <vaucanson/misc/contract.hh>
00024 # include <vaucanson/algebra/concept/series_base.hh>
00025 
00026 namespace vcsn {
00027 
00028 #define AutoType(Type)                          \
00029   typename Element<S, T>::Type
00030 
00031   template<typename S, typename T, typename U>
00032   void
00033   op_assign(const AutomataBase<S>& concept, T& dst, const U& src)
00034   {
00035     dst = op_convert(concept, dst, src);
00036   }
00037 
00038   template<typename S, typename T>
00039   void
00040   op_assign(const AutomataBase<S>&, T& dst, const T& src)
00041   {
00042     dst = src;
00043   }
00044 
00045   template<typename S, typename T>
00046   const T& op_convert(const AutomataBase<S>&,
00047                       SELECTOR(T), const T& from_data)
00048   {
00049     return from_data;
00050   }
00051 
00052   template<typename S, typename R, typename T>
00053   R op_convert(const AutomataBase<S>& concept,
00054                SELECTOR(R), const T& src)
00055   {
00056     typedef typename automaton_traits<R>::hstate_t dst_hstate_t;
00057     typedef typename automaton_traits<T>::hstate_t src_hstate_t;
00058     typedef typename automaton_traits<T>::transition_iterator transition_iterator;
00059     typedef typename automaton_traits<T>::final_iterator final_iterator;
00060     typedef typename automaton_traits<T>::initial_iterator initial_iterator;
00061     typedef typename automaton_traits<T>::state_iterator state_iterator;
00062 
00063     R dst;
00064     std::map<src_hstate_t, dst_hstate_t> states_map;
00065 
00066     //Mapping src's states to dst's states
00067     for (state_iterator s = op_states(concept, src).begin(),
00068           s_end = op_states(concept, src).end(); s != s_end; ++s)
00069       states_map[*s] = op_add_state(concept, dst);
00070 
00071     //Adding all transitions
00072     for (transition_iterator t = op_transitions(concept, src).begin(),
00073           t_end = op_transitions(concept, src).end(); t != t_end; ++t)
00074       op_add_series_transition(concept,
00075                         dst,
00076                         states_map[op_src_of(concept, src, *t)],
00077                         states_map[op_dst_of(concept, src, *t)],
00078                         op_label_of(concept, src, *t));
00079 
00080     //Adding initial states
00081     for (initial_iterator i = op_initial(concept, src).begin(),
00082           i_end = op_initial(concept, src).end(); i != i_end; ++i)
00083       op_set_initial(concept,
00084                      dst,
00085                      states_map[*i],
00086                      op_get_initial(concept, src, *i));
00087 
00088     //Adding final states
00089     for (final_iterator f = op_final(concept, src).begin(),
00090           f_end = op_final(concept, src).end(); f != f_end; ++f)
00091       op_set_final(concept,
00092                    dst,
00093                    states_map[*f],
00094                    op_get_final(concept, src, *f));
00095 
00096     //FIXME: geometry isn't preserved during this conversion.
00097 
00098     return dst;
00099   }
00100 
00101 
00102   template <class S, class T>
00103   const typename automaton_traits<T>::tag_t&
00104   op_get_tag(const AutomataBase<S>&, const T& v)
00105   {
00106     return v.tag();
00107   }
00108 
00109   template <class S, class T>
00110   typename automaton_traits<T>::tag_t&
00111   op_get_tag(const AutomataBase<S>&, T& v)
00112   {
00113     return v.tag();
00114   }
00115 
00116   template <class S, class T>
00117   const typename automaton_traits<T>::geometry_t&
00118   op_get_geometry(const AutomataBase<S>&, const T& v)
00119   {
00120     return v.geometry();
00121   }
00122 
00123   template <class S, class T>
00124   typename automaton_traits<T>::geometry_t&
00125   op_get_geometry(const AutomataBase<S>&, T& v)
00126   {
00127     return v.geometry();
00128   }
00129 
00130   template <class S, class T>
00131   bool
00132   op_exists(const AutomataBase<S>& s, const T& v)
00133   {
00134     return v.exists(s);
00135   }
00136 
00137   template <class S, class T>
00138   typename automaton_traits<T>::states_t
00139   op_states(const AutomataBase<S>&, const T& v)
00140   {
00141     return v.states();
00142   }
00143 
00144   template <class S, class T>
00145   typename automaton_traits<T>::hstate_t
00146   op_get_state(const AutomataBase<S>&, const T& v, int state)
00147   {
00148     return v.get_state(state);
00149   }
00150 
00151   template <class S, class T>
00152   typename automaton_traits<T>::transitions_t
00153   op_transitions(const AutomataBase<S>&, const T& v)
00154   {
00155     return v.edges();
00156   }
00157 
00158   template <class S, class T>
00159   typename automaton_traits<T>::initial_support_t
00160   op_initial(const AutomataBase<S>&, const T& v)
00161   {
00162     return v.initial();
00163   }
00164 
00165   template <class S, class T>
00166   typename automaton_traits<T>::final_support_t
00167   op_final(const AutomataBase<S>&, const T& v)
00168   {
00169     return v.final();
00170   }
00171 
00172   template <class S, class T>
00173   void
00174   op_set_initial(const AutomataBase<S>& ss, T& v,
00175                  const typename automaton_traits<T>::hstate_t& state,
00176                  const AutoType(series_set_elt_t)& s)
00177   {
00178     typedef
00179       typename Element<S, T>::series_set_elt_value_t series_set_elt_value_t;
00180     v.set_initial(state,
00181                   s.value(),
00182                   zero_value(ss.series(),
00183                              SELECT(series_set_elt_value_t)));
00184   }
00185 
00186   template <class S, class T>
00187   typename Element<S, T>::series_set_elt_t
00188   op_get_initial(const AutomataBase<S>& s,
00189                  const T& v,
00190                  const typename automaton_traits<T>::hstate_t& state)
00191   {
00192     return typename Element<S, T>::series_set_elt_t
00193       (s.series(),
00194        v.get_initial(state,
00195                      zero_value(s.series(),
00196                                 SELECT(AutoType(series_set_elt_value_t)))));
00197   }
00198 
00199   template <class S, class T>
00200   bool
00201   op_is_initial(const AutomataBase<S>& s,
00202                  const T& v,
00203                  const typename automaton_traits<T>::hstate_t& state)
00204   {
00205     return v.is_initial(state, zero_value(s.series(),
00206                                 SELECT(AutoType(series_set_elt_value_t))));
00207   }
00208 
00209   template <class S, class T>
00210   void
00211   op_set_final(const AutomataBase<S>& ss, T& v,
00212                const typename automaton_traits<T>::hstate_t& state,
00213                const typename Element<S, T>::series_set_elt_t& s)
00214   {
00215     v.set_final(state,
00216                 s.value(),
00217                 zero_value(ss.series(),
00218                            SELECT(AutoType(series_set_elt_value_t))));
00219   }
00220 
00221   template <class S, class T>
00222   void
00223   op_set_initial(const AutomataBase<S>& ss, T& v,
00224                  int state,
00225                  const AutoType(series_set_elt_t)& s)
00226   {
00227     op_set_initial(ss, v, op_get_state(ss, v, state), s);
00228   }
00229 
00230   template <class S, class T>
00231   typename Element<S, T>::series_set_elt_t
00232   op_get_initial(const AutomataBase<S>& s,
00233                  const T& v,
00234                  int state)
00235   {
00236     return op_get_initial(s, v, op_get_state(s, v, state));
00237   }
00238 
00239   template <class S, class T>
00240   bool
00241   op_is_initial(const AutomataBase<S>& s,
00242                 const T& v,
00243                 int state)
00244   {
00245     return op_is_initial(s, v, op_get_state(s, v, state));
00246   }
00247 
00248   template <class S, class T>
00249   void
00250   op_set_final(const AutomataBase<S>& ss, T& v,
00251                int state,
00252                const typename Element<S, T>::series_set_elt_t& s)
00253   {
00254     op_set_final(ss, v, op_get_state(ss, v, state), s);
00255   }
00256 
00257   template <class S, class T>
00258   typename Element<S, T>::series_set_elt_t
00259   op_get_final(const AutomataBase<S>& s,
00260                const T& v,
00261                const typename automaton_traits<T>::hstate_t& state)
00262   {
00263     return typename Element<S, T>::series_set_elt_t
00264       (s.series(),
00265        v.get_final(state,
00266                    zero_value(s.series(),
00267                               SELECT(AutoType(series_set_elt_value_t)))));
00268   }
00269 
00270   template <class S, class T>
00271   typename Element<S, T>::series_set_elt_t
00272   op_get_final(const AutomataBase<S>& s,
00273                const T& v,
00274                int state)
00275   {
00276     return op_get_final(s, v, op_get_state(s, v, state));
00277   }
00278 
00279   template <class S, class T>
00280   bool
00281   op_is_final(const AutomataBase<S>& s,
00282               const T& v,
00283               const typename automaton_traits<T>::hstate_t& state)
00284   {
00285     return v.is_final(state, zero_value(s.series(),
00286                               SELECT(AutoType(series_set_elt_value_t))));
00287   }
00288 
00289   template <class S, class T>
00290   bool
00291   op_is_final(const AutomataBase<S>& s,
00292               const T& v,
00293               int state)
00294   {
00295     return op_is_final(s, v, op_get_state(s, v, state));
00296   }
00297 
00298   template <class S, class T>
00299   void
00300   op_clear_initial(const AutomataBase<S>&, T& v)
00301   {
00302     return v.clear_initial();
00303   }
00304 
00305   template <class S, class T>
00306   void
00307   op_clear_final(const AutomataBase<S>&, T& v)
00308   {
00309     return v.clear_final();
00310   }
00311 
00312   template <class S, class T>
00313   typename automaton_traits<T>::hstate_t
00314   op_add_state(const AutomataBase<S>&, T& v)
00315   {
00316     return v.add_state();
00317   }
00318 
00319   template <class S, class T>
00320   typename automaton_traits<T>::hstate_t
00321   op_choose_state(const AutomataBase<S>& s, const T& v)
00322   {
00323     typedef typename automaton_traits<T>::states_t states_t;
00324     typedef typename states_t::const_iterator state_iterator;
00325     const states_t& st = op_states(s, v);
00326     assertion(st.size() > 0);
00327     int n = misc::random::generate(0, int(st.size() - 1));
00328     state_iterator ss = st.begin();
00329     for (; n > 0; --n)
00330       ++ss;
00331     return *ss;
00332   }
00333 
00334   template <class S, class T>
00335   typename automaton_traits<T>::htransition_t
00336   op_add_transition(const AutomataBase<S>&, T& v,
00337                     const typename automaton_traits<T>::hstate_t& from,
00338                     const typename automaton_traits<T>::hstate_t& to,
00339                     const typename Element<S, T>::label_t& label)
00340   {
00341     return v.add_edge(from, to, label);
00342   }
00343 
00344   template <class S, class T>
00345   typename automaton_traits<T>::htransition_t
00346   op_add_transition(const AutomataBase<S>& s, T& v,
00347                     int from,
00348                     int to,
00349                     const typename Element<S, T>::label_t& label)
00350   {
00351     return op_add_transition(s, v, op_get_state(s, v, from),
00352                              op_get_state(s, v, to), label);
00353   }
00354 
00355   template<class S, class T>
00356   typename automaton_traits<T>::htransition_t
00357   op_add_weighted_transition(const AutomataBase<S>& s, T& v,
00358                              const typename automaton_traits<T>::hstate_t& from,
00359                              const typename automaton_traits<T>::hstate_t& to,
00360                              const typename Element<S, T>::semiring_elt_t& w,
00361                              const typename Element<S, T>::monoid_elt_value_t& m)
00362   {
00363     typename Element<S, T>::series_set_elt_t series (s.series());
00364     series.assoc(m, w.value());
00365     return op_add_series_transition(s, v, from, to, series);
00366   }
00367 
00368   template<class S, class T>
00369   typename automaton_traits<T>::htransition_t
00370   op_add_weighted_transition(const AutomataBase<S>& s, T& v,
00371                              int from,
00372                              int to,
00373                              const typename Element<S, T>::semiring_elt_t& w,
00374                              const typename Element<S, T>::monoid_elt_value_t& m)
00375   {
00376     return op_add_weighted_transition(s, v, op_get_state(s, v, from),
00377                                       op_get_state(s, v, to), w, m);
00378   }
00379 
00380   template <class S, class T>
00381   typename automaton_traits<T>::htransition_t
00382   op_add_series_transition(const AutomataBase<S>& s, T& v,
00383                            const typename automaton_traits<T>::hstate_t& from,
00384                            const typename automaton_traits<T>::hstate_t& to,
00385                            const typename Element<S, T>::series_set_elt_t& l)
00386   {
00387     return op_add_transition(s, v, from, to, l.value());
00388   }
00389 
00390   template <class S, class T>
00391   typename automaton_traits<T>::htransition_t
00392   op_add_series_transition(const AutomataBase<S>& s, T& v,
00393                            int from,
00394                            int to,
00395                            const typename Element<S, T>::series_set_elt_t& l)
00396   {
00397     return op_add_series_transition(s, v, op_get_state(s, v, from),
00398                                     op_get_state(s, v, to), l);
00399   }
00400 
00401   template <class S, class T>
00402   typename automaton_traits<T>::htransition_t
00403   op_add_spontaneous(const AutomataBase<S>& s, T& v,
00404                      const typename automaton_traits<T>::hstate_t& from,
00405                      const typename automaton_traits<T>::hstate_t& to,
00406                      const typename Element<S, T>::semiring_elt_t& w)
00407   {
00408     AutoType(series_set_elt_t) ss(s.series());
00409     ss.assoc(algebra::identity_as<AutoType(monoid_elt_value_t)>::
00410              of(s.series().monoid()), w);
00411     return op_add_series_transition(s, v, from, to, ss);
00412   }
00413 
00414   template <class S, class T>
00415   typename automaton_traits<T>::htransition_t
00416   op_add_spontaneous(const AutomataBase<S>& s, T& v,
00417                      int from,
00418                      int to,
00419                      const typename Element<S, T>::semiring_elt_t& w)
00420   {
00421     return op_add_spontaneous(s, v, op_get_state(s, v, from),
00422                               op_get_state(s, v, to), w);
00423   }
00424 
00425   template <class S, class T>
00426   typename automaton_traits<T>::htransition_t
00427   op_add_letter_transition(const AutomataBase<S>& s, T& v,
00428                            const typename automaton_traits<T>::hstate_t& from,
00429                            const typename automaton_traits<T>::hstate_t& to,
00430                            const typename Element<S, T>::letter_t& l)
00431   {
00432     return op_add_transition(s, v, from, to, l);
00433   }
00434 
00435   template <class S, class T>
00436   typename automaton_traits<T>::htransition_t
00437   op_add_letter_transition(const AutomataBase<S>& s, T& v,
00438                            int from,
00439                            int to,
00440                            const typename Element<S, T>::letter_t& l)
00441   {
00442     return op_add_letter_transition(s, v, op_get_state(s, v, from),
00443                                     op_get_state(s, v, to), l);
00444   }
00445 
00446   template <class S, class T>
00447   void
00448   op_update(const AutomataBase<S>&, T& v,
00449             const typename automaton_traits<T>::htransition_t&  e,
00450             const AutoType(label_t)& l)
00451   {
00452     // FIXME: test that l != 0.
00453     v.update(e, l);
00454   }
00455 
00456   template <class S, class T>
00457   void
00458   op_del_state(const AutomataBase<S>&, T& v,
00459                const typename automaton_traits<T>::hstate_t& s)
00460   {
00461     v.del_state(s);
00462   }
00463 
00464   template <class S, class T>
00465   void
00466   op_del_state(const AutomataBase<S>& s, T& v,
00467                int state)
00468   {
00469     op_del_state(s, v, op_get_state(s, v, state));
00470   }
00471 
00472   template <class S, class T>
00473   void
00474   op_del_transition(const AutomataBase<S>&, T& v,
00475                     const typename automaton_traits<T>::htransition_t& e)
00476   {
00477     v.del_edge(e);
00478   }
00479 
00480   template <class S, class T>
00481   bool
00482   op_has_state(const AutomataBase<S>&, const T& v,
00483                const typename automaton_traits<T>::hstate_t& s)
00484   {
00485     return v.has_state(s);
00486   }
00487 
00488   template <class S, class T>
00489   bool
00490   op_has_state(const AutomataBase<S>& s, const T& v,
00491                int state)
00492   {
00493     return op_has_state(s, v, op_get_state(s, v, state));
00494   }
00495 
00496   template <class S, class T>
00497   bool
00498   op_has_transition(const AutomataBase<S>&, const T& v,
00499                     const typename automaton_traits<T>::htransition_t& e)
00500   {
00501     return v.has_edge(e);
00502   }
00503 
00504   template <class S, class T>
00505   typename automaton_traits<T>::hstate_t
00506   op_src_of(const AutomataBase<S>&, const T& v,
00507             const typename automaton_traits<T>::htransition_t& e)
00508   {
00509     return v.src_of(e);
00510   }
00511 
00512   template <class S, class T>
00513   typename automaton_traits<T>::hstate_t
00514   op_dst_of(const AutomataBase<S>&, const T& v,
00515             const typename automaton_traits<T>::htransition_t& e)
00516   {
00517     return v.dst_of(e);
00518   }
00519 
00520   template <class S, class T>
00521   typename Element<S, T>::label_t
00522   op_label_of(const AutomataBase<S>&, const T& v,
00523               const typename automaton_traits<T>::htransition_t& e)
00524   {
00525     return v.label_of(e);
00526   }
00527 
00528   template <class S, class T>
00529   const typename Element<S, T>::series_set_elt_t
00530   op_series_of(const AutomataBase<S>& s, const T& v,
00531                const typename automaton_traits<T>::htransition_t& e)
00532   {
00533     return typename Element<S, T>::series_set_elt_t
00534       (s.series(),
00535        v.label_of(e));
00536   }
00537 
00538   template <class S, class T>
00539   typename Element<S, T>::series_set_elt_value_t
00540   op_series_value_of(const AutomataBase<S>& s, const T& v,
00541                      const typename automaton_traits<T>::htransition_t& e)
00542   {
00543     return op_series_of(s, v, e).value();
00544   }
00545 
00546   template <class S, class T>
00547   typename Element<S, T>::monoid_elt_t
00548   op_word_of(const AutomataBase<S>& s, const T& v,
00549              const typename automaton_traits<T>::htransition_t& e)
00550   {
00551     return typename Element<S, T>::monoid_elt_t
00552       (s.series().monoid(),
00553        v.label_of(e));
00554   }
00555 
00556   template <class S, class T>
00557   typename Element<S, T>::semiring_elt_t
00558   op_weight_of(const AutomataBase<S>& s, const T& v,
00559                const typename automaton_traits<T>::htransition_t& e)
00560   {
00561     return op_series_of(s, v, e).get(op_word_of(s, v, e));
00562   }
00563 
00564   template <class S, class T>
00565   typename Element<S, T>::monoid_elt_value_t
00566   op_word_value_of(const AutomataBase<S>& s, const T& v,
00567                    const typename automaton_traits<T>::htransition_t& e)
00568   {
00569     return op_word_of(s, v, e).value();
00570   }
00571 
00572   template <class S, class T>
00573   typename Element<S, T>::letter_t
00574   op_letter_of(const AutomataBase<S>&, const T& v,
00575                const typename automaton_traits<T>::htransition_t& e)
00576   {
00577     return v.label_of(e);
00578   }
00579 
00580   template <class S, class T>
00581   bool
00582   op_is_spontaneous(const AutomataBase<S>& s, const T& v,
00583                     const typename automaton_traits<T>::htransition_t& e)
00584   {
00585     return (op_series_of(s, v, e) ==
00586             algebra::identity_as<AutoType(series_set_elt_value_t)>::of(s.series()));
00587   }
00588 
00589 } // vcsn
00590 
00591 # undef AutoType
00592 
00593 #endif // ! VCSN_AUTOMATA_CONCEPT_AUTOMATA_OPS_HXX