Vaucanson 1.4
|
00001 // letter_to_letter_composition.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 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_LETTER_TO_LETTER_COMPOSITION_HXX 00018 # define VCSN_ALGORITHMS_LETTER_TO_LETTER_COMPOSITION_HXX 00019 00020 # include <vaucanson/automata/concept/transducer_base.hh> 00021 # include <vaucanson/misc/usual_macros.hh> 00022 00023 # include <set> 00024 # include <map> 00025 00026 namespace vcsn { 00027 00028 00029 template <class Self, class T> 00030 Element<Self, T> 00031 do_letter_to_letter_composition(const TransducerBase<Self>& s, 00032 const Element<Self, T>& f, 00033 const Element<Self, T>& g) 00034 { 00035 typedef Element<Self, T> transducer_t; 00036 AUTOMATON_TYPES(transducer_t); 00037 typedef std::map<std::pair<hstate_t, hstate_t>, hstate_t> assoc_t; 00038 typedef std::list<htransition_t> delta_ret_t; 00039 00040 semiring_t output_series(f.series().semiring().semiring(), 00041 f.series().semiring().monoid()); 00042 series_set_t series(output_series, g.series().monoid()); 00043 automata_set_t structure(series); 00044 transducer_t output(s); 00045 assoc_t conv; 00046 series_set_elt_t zero = 00047 algebra::zero_as<series_set_elt_value_t>::of(output.series()); 00048 00049 for_all_const_states(s, f) 00050 for_all_const_states(t, g) 00051 { 00052 hstate_t ns = output.add_state(); 00053 conv[std::make_pair(*s, *t)] = ns; 00054 output.set_initial(ns, 00055 f.get_initial(*s) * g.get_initial(*t)); 00056 output.set_final(ns, 00057 f.get_final(*s) * g.get_final(*t)); 00058 00059 } 00060 00061 for_all_const_states(s, f) 00062 for_all_const_states(t, g) 00063 { 00064 for (delta_iterator lhs_e(f.value(), *s); ! lhs_e.done(); lhs_e.next()) 00065 { 00066 series_set_elt_t l = f.series_of(*lhs_e); 00067 for (delta_iterator rhs_e(g.value(), *s); ! rhs_e.done(); rhs_e.next()) 00068 { 00069 series_set_elt_t l_ = g.series_of(*rhs_e); 00070 series_set_elt_t l__(series); 00071 typedef typename series_set_t::support_t support_t; 00072 for_all_const_(support_t, supp, l.supp()) 00073 { 00074 semiring_elt_t ol = l.get(*supp); 00075 typedef typename semiring_elt_t::support_t wsupport_t; 00076 wsupport_t wsupp = ol.supp(); 00077 series_set_t ts(series, monoid_elt_t(*supp)); 00078 for_all_const_(wsupport_t, ss, wsupp) 00079 l__ += ts * l_.get(*ss); 00080 } 00081 if (l__ != zero) 00082 { 00083 output.add_series_transition(conv[std::make_pair(*s, *t)], 00084 conv[std::make_pair(f.dst_of(*lhs_e), 00085 g.dst_of(*rhs_e)) 00086 ], 00087 l__); 00088 } 00089 } 00090 } 00091 } 00092 return output; 00093 } 00094 00095 template <class S, class T> 00096 Element<S, T> 00097 letter_to_letter_composition(const Element<S, T>& lhs, 00098 const Element<S, T>& rhs) 00099 { 00100 BENCH_TASK_SCOPED("letter_to_letter_composition"); 00101 return do_letter_to_letter_composition(lhs.structure(), lhs, rhs); 00102 } 00103 00104 } // vcsn 00105 00106 #endif // ! VCSN_ALGORITHMS_LETTER_TO_LETTER_COMPOSITION_HXX