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

# normalized.hxx

    00001 // normalized.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, 2007 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_NORMALIZED_HXX
    00018 # define VCSN_ALGORITHMS_NORMALIZED_HXX
    00019
    00020 # include <vaucanson/algorithms/normalized.hh>
    00021 # include <vaucanson/algorithms/internal/has_neighbour.hh>
    00022
    00023 # include <vaucanson/automata/concept/automata_base.hh>
    00024 # include <vaucanson/misc/usual_macros.hh>
    00025 # include <vaucanson/algorithms/sum.hh>
    00026
    00027 # include <stack>
    00028
    00029 namespace vcsn {
    00030
    00031   /*-----------.
    00032   | normalized |
    00033   `-----------*/
    00034   template <class A_, typename Auto_>
    00035   void
    00036   do_normalize_here(const AutomataBase<A_>&,
    00037                     Auto_& a)
    00038   {
    00039     TIMER_SCOPED("normalize");
    00040     AUTOMATON_TYPES(Auto_);
    00041
    00042     hstate_t h = a.add_state();
    00043
    00044     for_all_initial_states(i, a)
    00045       a.add_series_transition(h, *i, a.get_initial(*i));
    00046
    00047     a.clear_initial();
    00048     a.set_initial(h);
    00049
    00050     h = a.add_state();
    00051
    00052     for_all_final_states(i, a)
    00053       a.add_series_transition(*i, h, a.get_final(*i));
    00054
    00055     a.clear_final();
    00056     a.set_final(h);
    00057   }
    00058
    00059   template <typename A, typename T>
    00060   Element<A, T>
    00061   normalize(const Element<A, T>& a)
    00062   {
    00063     Element<A, T> result(a);
    00064     do_normalize_here(result.structure(), result);
    00065     return result;
    00066   }
    00067
    00068   template<typename A, typename T>
    00069   void
    00070   normalize_here(Element<A, T>& a)
    00071   {
    00072     do_normalize_here(a.structure(), a);
    00073   }
    00074
    00075
    00076   /*--------------------.
    00077   | union_of_normalized |
    00078   `--------------------*/
    00079
    00080   template <typename A, typename lhs_t, typename rhs_t>
    00081   void do_union_of_normalized_here(const AutomataBase<A>&,
    00082                                    lhs_t& lhs,
    00083                                    const rhs_t& rhs)
    00084   {
    00085     TIMER_SCOPED("union_of_normalized");
    00086     AUTOMATON_TYPES(lhs_t);
    00087     monoid_elt_t monoid_identity =
    00088       lhs.series().monoid().identity(SELECT(monoid_elt_value_t));
    00089     hstate_t new_i = lhs.add_state();
    00090     hstate_t new_f = lhs.add_state();
    00091
    00092     sum_here(lhs, rhs);
    00093
    00094     for_all_initial_states(i, lhs)
    00095       lhs.add_spontaneous(new_i, *i, lhs.get_initial(*i).get(monoid_identity));
    00096     typename lhs_t::initial_iterator i;
    00097     for (typename lhs_t::initial_iterator next = lhs.initial().begin();
    00098          next != lhs.initial().end();)
    00099     {
    00100       i = next;
    00101       ++next;
    00102       lhs.unset_initial(*i);
    00103     }
    00104
    00105     for_all_final_states(f, lhs)
    00106       lhs.add_spontaneous(*f, new_f, lhs.get_final(*f).get(monoid_identity));
    00107     typename lhs_t::final_iterator f;
    00108     for (typename lhs_t::final_iterator next = lhs.final().begin();
    00109          next != lhs.final().end();)
    00110     {
    00111       f = next;
    00112       ++next;
    00113       lhs.unset_final(*f);
    00114     }
    00115     lhs.set_final(new_f);
    00116     lhs.set_initial(new_i);
    00117   }
    00118
    00119   template<typename A, typename T, typename U>
    00120   void union_of_normalized_here(Element<A, T>& lhs,
    00121                                 const Element<A, U>& rhs)
    00122   {
    00123     // assertion(lhs.structure() == rhs.structure())
    00124     do_union_of_normalized_here(lhs.structure(), lhs, rhs);
    00125   }
    00126
    00127   template<typename A, typename T, typename U>
    00128   Element<A, T>
    00129   union_of_normalized(const Element<A, T>& lhs,
    00130                       const Element<A, U>& rhs)
    00131   {
    00132     // assertion(lhs.structure() == rhs.structure())
    00133     Element<A, T> ret(lhs);
    00134     do_union_of_normalized_here(ret.structure(), ret, rhs);
    00135     return ret;
    00136   }
    00137
    00138   /*--------------.
    00139   | is_normalized |
    00140   `--------------*/
    00141   template <typename A, typename auto_t>
    00142   bool
    00143   do_is_normalized(const AutomataBase<A>&,
    00144                    const auto_t& a)
    00145   {
    00146     TIMER_SCOPED("is_normalized");
    00147     typedef typename auto_t::series_set_elt_value_t     series_set_elt_value_t;
    00148     typedef typename auto_t::series_set_elt_t           series_set_elt_t;
    00149
    00150     series_set_elt_t series_identity =
    00151       a.series().identity(SELECT(series_set_elt_value_t));
    00152
    00153     if (a.initial().size() != 1
    00154         || a.final().size() != 1
    00155         || a.get_initial(*a.initial().begin()) != series_identity
    00156         || a.get_final(*a.final().begin()) != series_identity)
    00157       return false;
    00158
    00159     // Check that there is no input transition on the initial state
    00160     // and no output transition on the final state.
    00161     return !has_successors(a, *a.final().begin())
    00162       && !has_predecessors(a, *a.initial().begin());
    00163   }
    00164
    00165   template<typename A, typename T>
    00166   bool
    00167   is_normalized(const Element<A, T>& a)
    00168   {
    00169     return do_is_normalized(a.structure(), a);
    00170   }
    00171
    00172   /*--------------------------.
    00173   | concatenate_of_normalized |
    00174   `--------------------------*/
    00175   template <typename A, typename lhs_t, typename rhs_t>
    00176   void do_concatenate_of_normalized_here(const AutomataBase<A>&,
    00177                                          lhs_t& lhs,
    00178                                          const rhs_t& rhs)
    00179   {
    00180     TIMER_SCOPED("concatenate_of_normalized");
    00181     AUTOMATON_TYPES(rhs_t);
    00182     typedef std::map<hstate_t, hstate_t>        map_lhs_rhs_t;
    00183     typedef std::set<htransition_t>             delta_ret_t;
    00184
    00185     hstate_t    glue_state = *lhs.final().begin();
    00186
    00187     /*-----------------.
    00188     | Concat of states |
    00189     `-----------------*/
    00190     map_lhs_rhs_t       map_h;
    00191
    00192     // If rhs initial multiplicity is 1 and so is lhs final multiplicity,
    00193     // we can merge the lhs final state and the rhs initial state.
    00194     bool merge_lhs_final_and_rhs_initial =
    00195       (lhs.get_final(*lhs.final().begin()).value() ==
    00196        lhs.series().identity(SELECT(series_set_elt_value_t)) &&
    00197        rhs.get_initial(*rhs.initial().begin()).value() ==
    00198        rhs.series().identity(SELECT(series_set_elt_value_t)));
    00199
    00200     for_all_states(s, rhs)
    00201     {
    00202       hstate_t new_state;
    00203
    00204       if (merge_lhs_final_and_rhs_initial)
    00205       {
    00206         if (rhs.is_initial(*s))
    00207           new_state = glue_state;
    00208         else
    00209           new_state = lhs.add_state();
    00210       }
    00211       else
    00212         new_state = lhs.add_state();
    00213       map_h[*s] = new_state;
    00214       lhs.set_final(new_state, rhs.get_final(*s));
    00215     }
    00216
    00217     /*------------------------.
    00218     | Concat of transitions.  |
    00219     `------------------------*/
    00220     for_all_transitions(t, rhs)
    00221       lhs.add_transition(map_h[rhs.src_of(*t)],
    00222                          map_h[rhs.dst_of(*t)],
    00223                          rhs.label_of(*t));
    00224
    00225     // If initial multiplicity of rhs isn't 1, add a spontaneous transition
    00226     // between lhs final state and rhs initial state, with lhs final
    00227     // multiplicity * rhs initial multiplicity.
    00228     if (!merge_lhs_final_and_rhs_initial)
    00229     {
    00230       monoid_elt_t monoid_identity =
    00231         rhs.series().monoid().identity(SELECT(monoid_elt_value_t));
    00232       hstate_t i = *rhs.initial().begin();
    00233       hstate_t f = *lhs.final().begin();
    00234
    00235       lhs.add_spontaneous(f, map_h[i],
    00236                           lhs.get_final(f).get(monoid_identity) *
    00237                           rhs.get_initial(i).get(monoid_identity));
    00238       lhs.unset_final(f);
    00239       lhs.unset_initial(map_h[i]);
    00240     }
    00241   }
    00242
    00243   template<typename A, typename T, typename U>
    00244   void concatenate_of_normalized_here(Element<A, T>& lhs,
    00245                                       const Element<A, U>& rhs)
    00246   {
    00247     // assertion(lhs.structure() == rhs.structure())
    00248     do_concatenate_of_normalized_here(lhs.structure(), lhs, rhs);
    00249   }
    00250
    00251   template<typename A, typename T, typename U>
    00252   Element<A, T>
    00253   concatenate_of_normalized(const Element<A, T>& lhs,
    00254                             const Element<A, U>& rhs)
    00255   {
    00256     // assertion(lhs.structure() == rhs.structure())
    00257     Element<A, T> ret(lhs);
    00258     do_concatenate_of_normalized_here(ret.structure(), ret, rhs);
    00259     return ret;
    00260   }
    00261
    00262   /*-------------------.
    00263   | star_of_normalized |
    00264   `-------------------*/
    00265   template <typename A, typename auto_t>
    00266   void do_star_of_normalized_here(const AutomataBase<A>&,
    00267                                   auto_t& a)
    00268   {
    00269     TIMER_SCOPED("star_of_normalized");
    00270     AUTOMATON_TYPES(auto_t);
    00271     monoid_elt_t monoid_identity =
    00272       a.series().monoid().identity(SELECT(monoid_elt_value_t));
    00273     hstate_t old_i = *a.initial().begin();
    00274     hstate_t old_f = *a.final().begin();
    00275     hstate_t new_i = a.add_state();
    00276     hstate_t new_f = a.add_state();
    00277
    00278     a.add_spontaneous(old_f, old_i, a.get_initial(old_i).get(monoid_identity));
    00279     a.add_spontaneous(new_i, old_i, a.get_initial(old_i).get(monoid_identity));
    00280     a.add_spontaneous(old_f, new_f, a.get_final(old_f).get(monoid_identity));
    00281     a.add_spontaneous(new_i, new_f);
    00282     a.set_final(new_f);
    00283     a.unset_final(old_f);
    00284     a.set_initial(new_i);
    00285     a.unset_initial(old_i);
    00286   }
    00287
    00288   template<typename A, typename T>
    00289   void star_of_normalized_here(Element<A, T>& a)
    00290   {
    00291     do_star_of_normalized_here(a.structure(), a);
    00292   }
    00293
    00294   template<typename A, typename T>
    00295   Element<A, T>
    00296   star_of_normalized(const Element<A, T>& a)
    00297   {
    00298     // assertion(lhs.structure() == rhs.structure())
    00299     Element<A, T> ret(a);
    00300     do_star_of_normalized_here(ret.structure(), ret);
    00301     return ret;
    00302   }
    00303
    00304 } // vcsn
    00305
    00306 #endif // ! VCSN_ALGORITHMS_NORMALIZED_HXX