Vaucanson 1.4
letter_to_letter_composition.hxx
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