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

- File List
- File Members

# 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