Vaucanson 1.4
rw_to_fmp.hxx
00001 // rw_to_fmp.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_RW_TO_FMP_HXX
00018 # define VCSN_ALGORITHMS_RW_TO_FMP_HXX
00019 
00020 # include <vaucanson/algebra/concept/freemonoid_product.hh>
00021 # include <vaucanson/automata/concept/transducer.hh>
00022 # include <vaucanson/automata/concept/automata.hh>
00023 # include <map>
00024 
00025 namespace vcsn
00026 {
00027   template<typename S, typename T,
00028            typename SS, typename TT,
00029            typename Self>
00030   void
00031   do_rw_to_fmp(const vcsn::TransducerBase<S>&,
00032                const vcsn::AutomataBase<SS>&,
00033                const vcsn::algebra::FreeMonoidProductBase<Self>&,
00034                const vcsn::Element<S, T>& trans,
00035                vcsn::Element<SS, TT>& res)
00036   {
00037     typedef typename T::hstate_t hstate_t;
00038     //Map source states with result states
00039     std::map<hstate_t, hstate_t> m;
00040 
00041     //Input transducer type
00042     typedef vcsn::Element<S, T> Trans_t;
00043 
00044     //Output FMP Automaton type
00045     typedef vcsn::Element<SS, TT> FMP_t;
00046 
00047     typename FMP_t::monoid_t fmp(trans.structure().series().monoid(),
00048                                  trans.structure().series().monoid());
00049     typename FMP_t::semiring_t sg;
00050     typename FMP_t::series_set_t ss(sg, fmp);
00051 
00052     typedef vcsn::Element<typename FMP_t::monoid_t::first_monoid_t,
00053       typename FMP_t::monoid_elt_value_t::first_type>
00054       first_monoid_elt_t;
00055     typedef vcsn::Element<typename FMP_t::monoid_t::second_monoid_t,
00056       typename FMP_t::monoid_elt_value_t::second_type>
00057       second_monoid_elt_t;
00058     typedef vcsn::Element<typename Trans_t::series_set_t,
00059       typename Trans_t::series_set_elt_value_t>
00060       mult_elt_t;
00061 
00062 
00063     /*----------------------------.
00064     | Creating the FMP automaton. |
00065     `----------------------------*/
00066 
00067     // Adding states
00068     for (typename Trans_t::state_iterator St = trans.states().begin();
00069          St != trans.states().end();
00070          ++St)
00071       m[*St] = res.add_state();
00072 
00073     typename Trans_t::series_set_elt_t id_series(trans.structure().series());
00074     id_series = vcsn::algebra::
00075       identity_as<typename Trans_t::series_set_elt_value_t>::
00076       of(trans.structure().series());
00077 
00078 
00079     /*------------------------.
00080     | Setting initial states. |
00081     `------------------------*/
00082 
00083     for (typename Trans_t::initial_iterator St, next = trans.initial().begin();
00084          next != trans.initial().end();)
00085     {
00086       //We need to store the next iterator before using the current one
00087       //to avoid an invalid iterator after having called set_final.
00088       //Indeed, set_final can delete the iterator if its second parameter
00089       //is the zero of the serie.
00090       St = next;
00091       next++;
00092 
00093       typename FMP_t::series_set_elt_t s(ss);
00094       typename FMP_t::monoid_elt_t mon(res.structure().series().monoid());
00095       first_monoid_elt_t
00096         first(res.structure().series().monoid().first_monoid());
00097       second_monoid_elt_t
00098         second(res.structure().series().monoid().second_monoid());
00099       typename FMP_t::semiring_elt_t
00100         weight(res.structure().series().semiring());
00101 
00102       mult_elt_t mult = trans.get_initial(*St);
00103       if (mult != id_series)
00104       {
00105         hstate_t tmp = res.add_state();
00106         typename mult_elt_t::support_t mult_supp = mult.supp();
00107         for_all_const_(mult_elt_t::support_t, i, mult_supp)
00108         {
00109           first = *i;
00110 
00111           typename Trans_t::semiring_elt_t
00112             output(trans.structure().series().semiring(), mult.get(*i));
00113           typename Trans_t::semiring_elt_t::support_t
00114             output_supp = output.supp();
00115           for_all_const_(Trans_t::semiring_elt_t::support_t,
00116                          j,
00117                          output_supp)
00118           {
00119             second = *j;
00120             weight = output.get(*j);
00121             mon = typename FMP_t::monoid_elt_value_t(first.value(),
00122                                                      second.value());
00123             s.assoc(mon, weight);
00124           }
00125         }
00126         res.add_series_transition(tmp, m[*St], s);
00127         res.set_initial(tmp);
00128       }
00129       else
00130         res.set_initial(m[*St]);
00131     }
00132 
00133 
00134     /*----------------------.
00135     | Setting final states. |
00136     `----------------------*/
00137 
00138     for (typename Trans_t::final_iterator St, next = trans.final().begin();
00139          next != trans.final().end();)
00140     {
00141       //We need to store the next iterator before using the current one
00142       //to avoid an invalid iterator after having called set_final.
00143       //Indeed, set_final can delete the iterator if its second parameter
00144       //is the zero of the serie.
00145       St = next;
00146       next++;
00147 
00148       typename FMP_t::series_set_elt_t s(ss);
00149       typename FMP_t::monoid_elt_t mon(res.structure().series().monoid());
00150       first_monoid_elt_t
00151         first(res.structure().series().monoid().first_monoid());
00152       second_monoid_elt_t
00153         second(res.structure().series().monoid().second_monoid());
00154       typename FMP_t::semiring_elt_t
00155         weight(res.structure().series().semiring());
00156 
00157       mult_elt_t mult = trans.get_final(*St);
00158       if (mult != id_series)
00159       {
00160         hstate_t tmp = res.add_state();
00161 
00162         typename mult_elt_t::support_t mult_supp = mult.supp();
00163         for_all_const_(mult_elt_t::support_t, i, mult_supp)
00164         {
00165           first = *i;
00166 
00167           typename Trans_t::semiring_elt_t
00168             output(trans.structure().series().semiring(), mult.get(*i));
00169           typename Trans_t::semiring_elt_t::support_t
00170             output_supp = output.supp();
00171           for_all_const_(Trans_t::semiring_elt_t::support_t,
00172                          j,
00173                          output_supp)
00174           {
00175             second = *j;
00176             weight = output.get(*j);
00177             mon = typename FMP_t::monoid_elt_value_t(first.value(),
00178                                                      second.value());
00179             s.assoc(mon, weight);
00180           }
00181         }
00182         res.add_series_transition(m[*St], tmp, s);
00183         res.set_final(tmp);
00184       }
00185       else
00186         res.set_final(m[*St]);
00187     }
00188 
00189 
00190     /*-----------------------.
00191     | Creating transitions.  |
00192     `-----------------------*/
00193 
00194     for (typename Trans_t::transition_iterator Ed = trans.transitions().begin();
00195          Ed != trans.transitions().end();
00196          ++Ed)
00197     {
00198       typename FMP_t::series_set_elt_t s(ss);
00199 
00200       first_monoid_elt_t first(trans.structure().series().monoid());
00201       second_monoid_elt_t
00202         second(trans.structure().series().semiring().monoid());
00203       typename FMP_t::monoid_elt_t
00204         mon(res.structure().series().monoid());
00205 
00206       typename Trans_t::series_set_elt_t
00207         series_elt(trans.structure().series());
00208       series_elt = trans.series_of(*Ed);
00209 
00210       for (typename Trans_t::series_set_elt_t::support_t::const_iterator
00211              i = series_elt.supp().begin();
00212            i != series_elt.supp().end();
00213            ++i)
00214       {
00215         first = *i;
00216 
00217         typename Trans_t::semiring_elt_t
00218           mult(trans.structure().series().semiring());
00219         mult = series_elt.get(first);
00220 
00221         //FIXME
00222         //If we don't use a copy of the support we don't get ALL the
00223         //element of the series when card(mult) > 1.
00224         typename Trans_t::semiring_elt_t::support_t
00225           mult_supp = mult.supp();
00226         for (typename Trans_t::semiring_elt_t::support_t::const_iterator
00227                j = mult_supp.begin();
00228              j != mult_supp.end();
00229              ++j)
00230         {
00231           second = *j;
00232 
00233           mon = typename FMP_t::monoid_elt_value_t(first.value(),
00234                                                    second.value());
00235           s.assoc(mon, trans.output_of(*Ed).get(second));
00236         }
00237       }
00238       res.add_series_transition(m[trans.src_of(*Ed)],
00239                                 m[trans.dst_of(*Ed)],
00240                                 s);
00241     }
00242   }
00243 
00244   template<typename S, typename T,
00245            typename SS, typename TT>
00246   vcsn::Element<SS, TT>&
00247   rw_to_fmp(const vcsn::Element<S, T>& trans, vcsn::Element<SS, TT>& res)
00248   {
00249     do_rw_to_fmp(trans.structure(), res.structure(),
00250                  res.structure().series().monoid(),
00251                  trans, res);
00252     return res;
00253   }
00254 }
00255 
00256 #endif // ! VCSN_ALGORITHMS_RW_TO_FMP_HXX