• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

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, 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 #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     BENCH_TASK_SCOPED("is_sub_normalized");
00040     AUTOMATON_TYPES(Auto);
00041     typedef typename series_set_elt_t::support_t support_t;
00042 
00043     for_all_const_initial_states(i, a)
00044     {
00045       series_set_elt_t label = a.get_initial(*i);
00046       for (typename support_t::const_iterator it = label.supp().begin();
00047            it != label.supp().end(); ++it)
00048         if ((*it).first.size() > 1 || (*it).second.size() > 1)
00049           return false;
00050     }
00051 
00052     for_all_const_final_states(f, a)
00053     {
00054       series_set_elt_t label = a.get_final(*f);
00055       for (typename support_t::const_iterator it = label.supp().begin();
00056            it != label.supp().end(); ++it)
00057         if ((*it).first.size() > 1 || (*it).second.size() > 1)
00058           return false;
00059     }
00060 
00061     for_all_const_transitions(e, a)
00062     {
00063       series_set_elt_t label = a.series_of(*e);
00064       for (typename support_t::const_iterator it = label.supp().begin();
00065            it != label.supp().end(); ++it)
00066         if ((*it).first.size() > 1 || (*it).second.size() > 1)
00067           return false;
00068     }
00069 
00070     return true;
00071   }
00072 
00073 
00074   /*--------------.
00075   | sub_normalize |
00076   `--------------*/
00077 
00078   template <class Auto, class Label>
00079   int do_sub_normalize_initial_final(Auto& a,
00080                                   typename Auto::hstate_t s,
00081                                   const Label& label, bool initial)
00082   {
00083     BENCH_TASK_SCOPED("sub_normalize_transition");
00084     AUTOMATON_TYPES(Auto);
00085     hstate_t                    s0;
00086     hstate_t                    s1;
00087     typedef typename monoid_elt_t::first_monoid_elt_value_t
00088       first_monoid_elt_value_t;
00089     typedef typename monoid_elt_t::second_monoid_elt_value_t
00090       second_monoid_elt_value_t;
00091     typedef typename series_set_elt_t::support_t        support_t;
00092 
00093     monoid_elt_t m1(a.structure().series().monoid(),
00094                     *(label.supp().begin()));
00095     first_monoid_elt_value_t w1 = m1.value().first;
00096     second_monoid_elt_value_t w2 = m1.value().second;
00097 
00098     int size1 = w1.size();
00099     int size2 = w2.size();
00100 
00101     unsigned int size = std::max(w1.size(), w2.size());
00102 
00103                 if(size>0 || label.supp().size()>1)
00104             {
00105               if(initial)
00106               {
00107                     s0 = a.add_state();
00108                     s1 = s;
00109                     a.set_initial(s0);
00110                     a.unset_initial(s);
00111               }
00112                   else // case final
00113               {
00114                     s0 = s;
00115                     s1 = a.add_state();
00116                     a.set_final(s1);
00117                     a.unset_final(s);
00118               }
00119           for_all_(support_t, supp, label.supp())
00120               {
00121                 const monoid_elt_t       supp_elt (a.structure().series().monoid(), *supp);
00122                 const semiring_elt_t weight = label.get(supp_elt);
00123             series_set_elt_t in_series(a.structure().series());
00124                 in_series.assoc(supp_elt, weight);
00125                     a.add_series_transition(s0, s1, in_series);
00126               }
00127             }
00128                 return 0;
00129   }
00130 
00131   template <class Auto, class Label>
00132   int do_sub_normalize_transition(Auto& a,
00133                                   typename Auto::hstate_t start,
00134                                   typename Auto::hstate_t stop,
00135                                   const Label& label)
00136   {
00137     BENCH_TASK_SCOPED("sub_normalize_transition");
00138     AUTOMATON_TYPES(Auto);
00139     hstate_t                    s0;
00140     hstate_t                    s1;
00141     typedef typename monoid_elt_t::first_monoid_elt_t first_monoid_elt_t;
00142     typedef typename monoid_elt_t::second_monoid_elt_t
00143       second_monoid_elt_t;
00144     typedef typename monoid_elt_t::first_monoid_elt_value_t
00145       first_monoid_elt_value_t;
00146     typedef typename monoid_elt_t::second_monoid_elt_value_t
00147       second_monoid_elt_value_t;
00148 
00149     first_monoid_elt_value_t m1_ident =
00150       algebra::identity_as<first_monoid_elt_value_t>
00151       ::of(a.structure().series().monoid().first_monoid()).value();
00152     second_monoid_elt_value_t m2_ident =
00153       algebra::identity_as<second_monoid_elt_value_t>
00154       ::of(a.structure().series().monoid().second_monoid()).value();
00155 
00156     semiring_elt_t s_ident =
00157       algebra::identity_as<semiring_elt_value_t>
00158       ::of(a.structure().series().semiring());
00159 
00160 
00161     monoid_elt_t m1(a.structure().series().monoid(),
00162                     *(label.supp().begin()));
00163     first_monoid_elt_value_t w1 = m1.value().first;
00164     second_monoid_elt_value_t w2 = m1.value().second;
00165 
00166     int size1 = w1.size();
00167     int size2 = w2.size();
00168     int cpt1 = 0;
00169     int cpt2 = 0;
00170 
00171     unsigned int size = std::max(w1.size(), w2.size());
00172 
00173     if (size > 1)
00174     {
00175       monoid_elt_t m(a.structure().series().monoid());
00176 
00177       semiring_elt_t s = label.get(m1);
00178       series_set_elt_t in_series(a.structure().series());
00179           
00180       m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00181                          cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00182 
00183       in_series.assoc(m, s);
00184 
00185         s0 = start;
00186         s1 = a.add_state();
00187         a.add_series_transition(s0, s1, in_series);
00188 
00189       for (unsigned int i = 1; i < size - 1; ++i)
00190       {
00191         m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00192                            cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00193         s0 = s1;
00194         s1 = a.add_state();
00195         series_set_elt_t series(a.structure().series());
00196         series.assoc(m, s_ident);
00197         a.add_series_transition(s0, s1, series);
00198       }
00199 
00200       m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00201                          cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00202 
00203       series_set_elt_t out_series(a.structure().series());
00204       out_series.assoc(m, s_ident);
00205 
00206         a.add_series_transition(s1, stop, out_series);
00207 
00208       return 1;
00209     }
00210 
00211     return 0;
00212   }
00213 
00214 
00215   template <class M1, class M2, class Auto, class Ret>
00216   void do_sub_normalize(const algebra::FreeMonoidProduct<M1, M2>&,
00217                         const Auto& a,
00218                         Ret& res)
00219   {
00220     BENCH_TASK_SCOPED("sub_normalize");
00221     AUTOMATON_TYPES(Ret);
00222     typedef std::vector<hstate_t> vector_t;
00223 
00224     auto_copy(res, cut_up(a));
00225 
00226     vector_t i_states; i_states.reserve(res.initial().size());
00227     vector_t f_states; f_states.reserve(res.final().size());
00228 
00229     for_all_const_initial_states(f, res)
00230       i_states.push_back(*f);
00231     for_all_const_final_states(i, res)
00232       f_states.push_back(*i);
00233 
00234     for_all_(vector_t, i, i_states)
00235       do_sub_normalize_initial_final(res, *i,
00236                                   res.get_initial(*i), true);
00237 
00238     for_all_(vector_t, f, f_states)
00239       do_sub_normalize_initial_final(res, *f,
00240                                   res.get_final(*f), false);
00241     //transitions may have be modified by initial and final treatment.
00242     transitions_t transitions = res.transitions();
00243 
00244     for_all_(transitions_t, e, transitions)
00245       if (do_sub_normalize_transition(res, res.src_of(*e), res.dst_of(*e),
00246                                       res.series_of(*e)))
00247         res.del_transition(*e);
00248   }
00249 
00250 
00251   /*---------.
00252   | Wrappers |
00253   `---------*/
00254 
00255   template <class S, class T>
00256   Element<S, T>
00257   sub_normalize(const Element<S, T>& a)
00258   {
00259     Element<S, T> res(a.structure());
00260     do_sub_normalize(a.structure().series().monoid(), a, res);
00261 
00262     return res;
00263   }
00264 
00265 
00266   template <class S, class T>
00267   void
00268   sub_normalize(const Element<S, T>& a, Element<S, T>& res)
00269   {
00270     do_sub_normalize(a.structure().series().monoid(), a, res);
00271   }
00272 
00273   template <class S, class T>
00274   void
00275   sub_normalize_here(Element<S, T>& a)
00276   {
00277     do_sub_normalize (a.structure().series().monoid(), a, a);
00278   }
00279 
00280   template <class S, class T>
00281   bool is_sub_normalized(const Element<S, T>& a)
00282   {
00283     return do_is_sub_normalized(a.structure().series().monoid(), a);
00284   }
00285 
00286 } // ! vcsn
00287 
00288 #endif // ! VCSN_ALGORITHMS_SUB_NORMALIZE_HXX

Generated on Fri Jul 8 2011 22:07:00 for Vaucanson by  doxygen 1.7.1