- 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