Vaucanson 1.4
domain.hxx
00001 // domain.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2006, 2011 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_DOMAIN_HXX
00018 # define VCSN_ALGORITHMS_DOMAIN_HXX
00019 
00020 # include <vaucanson/algorithms/domain.hh>
00021 # include <vaucanson/algorithms/cut_up.hh>
00022 
00023 namespace vcsn
00024 {
00025 
00026   /*-----------.
00027   | FMP_Domain |
00028   `-----------*/
00029 
00030   template <typename src_t, typename dst_t>
00031   void
00032   do_fmp_domain(const src_t& input, dst_t& dst, bool weighted)
00033   {
00034     BENCH_TASK_SCOPED("fmp_domain");
00035     AUTOMATON_TYPES_(src_t, trans_);
00036     AUTOMATON_TYPES(dst_t);
00037 
00038     src_t src = cut_up(input);
00039 
00040     typedef typename trans_series_set_elt_t::support_t  trans_support_t;
00041     std::map<trans_hstate_t, hstate_t>  stmap;
00042 
00043     const series_set_t& series = dst.structure().series();
00044     const monoid_t& monoid = dst.structure().series().monoid();
00045     const trans_monoid_t& trans_monoid = src.structure().series().monoid();
00046     const semiring_elt_t& unit = src.structure().series().semiring().wone_;
00047 
00048     for_all_const_states(fmp_s, src)
00049     {
00050       hstate_t s = dst.add_state();
00051       stmap[*fmp_s] = s;
00052 
00053       if (src.is_initial(*fmp_s))
00054         {
00055           const trans_series_set_elt_t trans_series_elt =
00056             src.get_initial(*fmp_s);
00057           trans_support_t trans_supp = trans_series_elt.supp();
00058           const trans_monoid_elt_t trans_monoid_elt(trans_monoid,
00059                                                     *(trans_supp.begin()));
00060 
00061           const monoid_elt_value_t word(trans_monoid_elt.value().first);
00062 
00063           series_set_elt_t series_elt(series);
00064 
00065           series_elt.assoc(monoid_elt_t(monoid, word),
00066                            weighted ?
00067                            trans_series_elt.get(trans_monoid_elt) : unit);
00068           dst.set_initial(s, series_elt);
00069         }
00070       if (src.is_final(*fmp_s))
00071         {
00072           const trans_series_set_elt_t trans_series_elt =
00073             src.get_final(*fmp_s);
00074           trans_support_t trans_supp = trans_series_elt.supp();
00075           const trans_monoid_elt_t trans_monoid_elt(trans_monoid,
00076                                                     *(trans_supp.begin()));
00077 
00078           const monoid_elt_value_t word(trans_monoid_elt.value().first);
00079 
00080           series_set_elt_t series_elt(series);
00081 
00082           series_elt.assoc(monoid_elt_t(monoid, word),
00083                            weighted ?
00084                            trans_series_elt.get(trans_monoid_elt) : unit);
00085 
00086           dst.set_final(s, series_elt);
00087         }
00088     }
00089 
00090     for_all_const_transitions_(trans_, fmp_e, src)
00091     {
00092       const trans_series_set_elt_t trans_series_elt = src.series_of(*fmp_e);
00093       trans_support_t trans_supp = trans_series_elt.supp();
00094       const trans_monoid_elt_t trans_monoid_elt(trans_monoid,
00095                                                 *(trans_supp.begin()));
00096       const monoid_elt_value_t word(trans_monoid_elt.value().first);
00097 
00098       series_set_elt_t series_elt(series);
00099 
00100       series_elt.assoc(monoid_elt_t(monoid, word),
00101                        weighted ? trans_series_elt.get(trans_monoid_elt)
00102                        : unit);
00103 
00104       dst.add_series_transition(stmap[src.src_of(*fmp_e)],
00105                                 stmap[src.dst_of(*fmp_e)], series_elt);
00106     }
00107   }
00108 
00109 
00110   /*----------.
00111   | RW_Domain |
00112   `----------*/
00113 
00114   template <typename src_t, typename dst_t>
00115   void
00116   do_rw_domain(const src_t& src, dst_t& dst)
00117   {
00118     BENCH_TASK_SCOPED("rw_domain");
00119     std::map<typename src_t::hstate_t, typename dst_t::hstate_t> m;
00120     AUTOMATON_TYPES(src_t);
00121 
00122     for_all_const_states(p, src)
00123     {
00124       m[*p] = dst.add_state();
00125     }
00126 
00127     for_all_const_initial_states(p, src)
00128       dst.set_initial(m[*p]);
00129 
00130     for_all_const_final_states(p, src)
00131       dst.set_final(m[*p]);
00132 
00133     for_all_const_transitions(e, src)
00134     {
00135       dst.add_series_transition(m[src.src_of(*e)],
00136                                 m[src.dst_of(*e)],
00137                                 src.input_of(*e));
00138     }
00139   }
00140 
00141 // FIXME: non void version
00142 
00143 
00144   /*-----------------.
00145   | Dispatch methods |
00146   `-----------------*/
00147 
00148   template <typename S, typename S2, typename T, typename T2>
00149   void
00150   domain_dispatch(const AutomataBase<S>&, const Element<S,T>& src, Element<S2, T2>& dst, bool weighted)
00151   {
00152     do_fmp_domain(src, dst, weighted);
00153   }
00154 
00155   template <typename S, typename S2, typename T, typename T2>
00156   void
00157   domain_dispatch(const TransducerBase<S>&, const Element<S,T>& src, Element<S2, T2>& dst, bool)
00158   {
00159     do_rw_domain(src, dst);
00160   }
00161 
00162   template <typename S, typename S2, typename T, typename T2>
00163   void
00164   domain(const Element<S,T>& src, Element<S2, T2>& dst, bool weighted)
00165   {
00166     domain_dispatch(src.structure(), src, dst, weighted);
00167   }
00168 
00169 } // End of namespace vcsn.
00170 
00171 #endif // ! VCSN_ALGORITHMS_DOMAIN_HXX