sub_normalize.hxx

Go to the documentation of this file.
00001 // sub_normalize.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 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_ALGORITHMS_SUB_NORMALIZE_HXX
00018 # define VCSN_ALGORITHMS_SUB_NORMALIZE_HXX
00019 
00029 namespace vcsn {
00030 
00031   /*------------------.
00032   | is_sub_normalized |
00033   `------------------*/
00034 
00035   template <class M1, class M2, class Auto>
00036   bool do_is_sub_normalized(const algebra::FreeMonoidProduct<M1, M2>&,
00037                             const Auto& a)
00038   {
00039     AUTOMATON_TYPES(Auto);
00040     typedef typename series_set_elt_t::support_t support_t;
00041 
00042     for_all_initial_states(i, a)
00043     {
00044       series_set_elt_t label = a.get_initial(*i);
00045       for (typename support_t::const_iterator it = label.supp().begin();
00046            it != label.supp().end(); ++it)
00047         if ((*it).first.size() > 1 || (*it).second.size() > 1)
00048           return false;
00049     }
00050 
00051     for_all_final_states(f, a)
00052     {
00053       series_set_elt_t label = a.get_initial(*f);
00054       for (typename support_t::const_iterator it = label.supp().begin();
00055            it != label.supp().end(); ++it)
00056         if ((*it).first.size() > 1 || (*it).second.size() > 1)
00057           return false;
00058     }
00059 
00060     for_all_transitions(e, a)
00061     {
00062       series_set_elt_t label = a.series_of(*e);
00063       for (typename support_t::const_iterator it = label.supp().begin();
00064            it != label.supp().end(); ++it)
00065         if ((*it).first.size() > 1 || (*it).second.size() > 1)
00066           return false;
00067     }
00068 
00069     return true;
00070   }
00071 
00072 
00073   /*--------------.
00074   | sub_normalize |
00075   `--------------*/
00076 
00077   template <class Auto, class Label>
00078   int do_sub_normalize_transition(Auto& a,
00079                                   hstate_t start, hstate_t stop,
00080                                   const Label& label, bool initial, bool final)
00081   {
00082     AUTOMATON_TYPES(Auto);
00083     hstate_t                    s0;
00084     hstate_t                    s1;
00085     typedef typename monoid_elt_t::first_monoid_elt_t first_monoid_elt_t;
00086     typedef typename monoid_elt_t::second_monoid_elt_t
00087       second_monoid_elt_t;
00088     typedef typename monoid_elt_t::first_monoid_elt_value_t
00089       first_monoid_elt_value_t;
00090     typedef typename monoid_elt_t::second_monoid_elt_value_t
00091       second_monoid_elt_value_t;
00092 
00093     first_monoid_elt_value_t m1_ident =
00094       algebra::identity_as<first_monoid_elt_value_t>
00095       ::of(a.structure().series().monoid().first_monoid()).value();
00096     second_monoid_elt_value_t m2_ident =
00097       algebra::identity_as<second_monoid_elt_value_t>
00098       ::of(a.structure().series().monoid().second_monoid()).value();
00099 
00100     semiring_elt_t s_ident =
00101       algebra::identity_as<semiring_elt_value_t>
00102       ::of(a.structure().series().semiring());
00103 
00104 
00105     monoid_elt_t m1(a.structure().series().monoid(),
00106                     *(label.supp().begin()));
00107     first_monoid_elt_value_t w1 = m1.value().first;
00108     second_monoid_elt_value_t w2 = m1.value().second;
00109 
00110     int size1 = w1.size();
00111     int size2 = w2.size();
00112     int cpt1 = 0;
00113     int cpt2 = 0;
00114 
00115     unsigned int size = std::max(w1.size(), w2.size());
00116 
00117     if (size > 1)
00118     {
00119       monoid_elt_t m(a.structure().series().monoid());
00120 
00121       semiring_elt_t s = label.get(m1);
00122       series_set_elt_t in_series(a.structure().series());
00123 
00124       m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00125                          cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00126 
00127       in_series.assoc(m, s);
00128 
00129       if (initial)
00130       {
00131         s0 = a.add_state();
00132         a.set_initial(s0, in_series);
00133         a.unset_initial(stop);
00134         s1 = s0;
00135       }
00136       else
00137       {
00138         s0 = start;
00139         s1 = a.add_state();
00140         a.add_series_transition(s0, s1, in_series);
00141       }
00142 
00143       for (unsigned int i = 1; i < size - 1; ++i)
00144       {
00145         m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00146                            cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00147         s0 = s1;
00148         s1 = a.add_state();
00149         series_set_elt_t series(a.structure().series());
00150         series.assoc(m, s_ident);
00151         a.add_series_transition(s0, s1, series);
00152       }
00153 
00154       m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00155                          cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00156 
00157       series_set_elt_t out_series(a.structure().series());
00158       out_series.assoc(m, s_ident);
00159 
00160       if (final)
00161       {
00162         a.unset_final(start);
00163         a.set_final(s1, out_series);
00164       }
00165       else
00166         a.add_series_transition(s1, stop, out_series);
00167 
00168       return 1;
00169     }
00170 
00171     return 0;
00172   }
00173 
00174 
00175 
00176   template <class M1, class M2, class Auto, class Ret>
00177   void do_sub_normalize(const algebra::FreeMonoidProduct<M1, M2>&,
00178                         const Auto& a,
00179                         Ret& res)
00180   {
00181     AUTOMATON_TYPES(Ret);
00182     typedef std::vector<hstate_t> vector_t;
00183 
00184     auto_copy(res, cut_up(a));
00185 
00186     transitions_t transitions = res.transitions();
00187     vector_t i_states; i_states.reserve(res.initial().size());
00188     vector_t f_states; f_states.reserve(res.final().size());
00189 
00190     for_all_initial_states(f, res)
00191       i_states.push_back(*f);
00192     for_all_final_states(i, res)
00193       f_states.push_back(*i);
00194 
00195     for_all_(vector_t, i, i_states)
00196       do_sub_normalize_transition(res, hstate_t(), *i,
00197                                   res.get_initial(*i), true, false);
00198 
00199     for_all_(vector_t, f, f_states)
00200       do_sub_normalize_transition(res, *f, hstate_t(),
00201                                   res.get_final(*f), false, true);
00202 
00203     for_all_(transitions_t, e, transitions)
00204       if (do_sub_normalize_transition(res, res.src_of(*e), res.dst_of(*e),
00205                                       res.series_of(*e), false, false))
00206         res.del_transition(*e);
00207   }
00208 
00209 
00210   /*---------.
00211   | Wrappers |
00212   `---------*/
00213 
00214   template <class S, class T>
00215   Element<S, T>
00216   sub_normalize(const Element<S, T>& a)
00217   {
00218     Element<S, T> res(a.structure());
00219     do_sub_normalize(a.structure().series().monoid(), a, res);
00220 
00221     return res;
00222   }
00223 
00224 
00225   template <class S, class T>
00226   void
00227   sub_normalize(const Element<S, T>& a, Element<S, T>& res)
00228   {
00229     do_sub_normalize(a.structure().series().monoid(), a, res);
00230   }
00231 
00232   template <class S, class T>
00233   void
00234   sub_normalize_here(Element<S, T>& a)
00235   {
00236     do_sub_normalize (a.structure().series().monoid(), a, a);
00237   }
00238 
00239   template <class S, class T>
00240   bool is_sub_normalized(const Element<S, T>& a)
00241   {
00242     return do_is_sub_normalized(a.structure().series().monoid(), a);
00243   }
00244 
00245 } // ! vcsn
00246 
00247 #endif // ! VCSN_ALGORITHMS_SUB_NORMALIZE_HXX

Generated on Sat Jul 29 17:13:11 2006 for Vaucanson by  doxygen 1.4.6