evaluation.hxx

00001 // evaluation.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_EVALUATION_HXX
00018 # define VCSN_ALGORITHMS_EVALUATION_HXX
00019 
00020 # include <vaucanson/algorithms/internal/evaluation.hh>
00021 
00022 # include <vaucanson/automata/concept/transducer_base.hh>
00023 
00024 # include <vaucanson/algorithms/product.hh>
00025 # include <vaucanson/algorithms/trim.hh>
00026 # include <vaucanson/algorithms/standard.hh>
00027 # include <vaucanson/algorithms/standard_of.hh>
00028 # include <vaucanson/algorithms/aut_to_exp.hh>
00029 # include <vaucanson/algorithms/extension.hh>
00030 # include <vaucanson/algorithms/image.hh>
00031 # include <vaucanson/algorithms/aut_to_exp.hh>
00032 # include <vaucanson/misc/usual_macros.hh>
00033 
00034 namespace vcsn {
00035 
00036   template <typename SA, typename ST, typename SRET,
00037             typename Auto_t, typename Trans_t, typename Ret_t>
00038   void
00039   do_evaluation(const AutomataBase<SA>&,
00040                 const TransducerBase<ST>&,
00041                 const AutomataBase<SRET>&,
00042                 const Auto_t& a,
00043                 const Trans_t& t,
00044                 Ret_t& ret)
00045   {
00046     image(trim(product(t, extension(a, t))), ret);
00047   }
00048 
00049   template<typename SA, typename TA, typename ST,
00050            typename TT, typename SRET, typename TRET>
00051   void
00052   evaluation(const Element<SA, TA>& a, const Element<ST, TT>& t,
00053              Element<SRET, TRET>& ret)
00054   {
00055     do_evaluation(a.structure(), t.structure(), ret.structure(), a, t, ret);
00056   }
00057 
00058   template<typename U, typename V,
00059            typename Trans_t, typename M>
00060   void
00061   do_partial_evaluation(const U& E,
00062                         const TransducerBase<V>&,
00063                         const Trans_t& S,
00064                         const typename Trans_t::hstate_t& p,
00065                         M& res)
00066   {
00067     // type helpers
00068     typedef typename Trans_t::value_t W;
00069     typedef typename output_projection_helper<V, W>::ret Auto_t;
00070     AUTOMATON_TYPES(Auto_t);
00071     AUTOMATON_TYPES_(Trans_t, t_);
00072     typedef typename Auto_t::set_t Auto_set_t;
00073     typedef typename Auto_set_t::series_set_t Auto_series_set_t;
00074     typedef series_set_elt_t exp_t;
00075     typedef t_series_set_elt_t t_exp_t;
00076     typedef std::map<t_hstate_t, std::pair<t_hstate_t, t_hstate_t> >
00077     state_pair_map_t;
00078     typedef std::map<t_hstate_t, hstate_t> state_state_map_t;
00079     typedef std::pair<t_hstate_t, exp_t> se_pair_t;
00080     Auto_set_t auto_structure(Auto_series_set_t(S.structure().series().semiring()));
00081 
00082     //
00083     // Part 1.
00084     // Construct A = standard_of(E).
00085     //
00086 
00087     // Hold standard_of(E).
00088     Auto_t A(auto_structure);
00089     // The expression must come from a realtime automaton.
00090     assertion(E.supp().size() == 1);
00091     monoid_elt_t word(E.structure().monoid(), *E.supp().begin());
00092     standard_of(A, E.get(word).value());
00093 
00094     //
00095     // Part 2.
00096     // Sp construction.
00097     //
00098 
00099     // Does a copy of S,
00100     Trans_t Sp = S;
00101     state_state_map_t Sp_to_S;
00102     for_all_const_initial_states_(t_, q, Sp)
00103     {
00104       if (*q == Sp.get_state(size_t(p)))
00105         Sp.set_initial(*q);
00106       else
00107         Sp.unset_initial(*q);
00108     }
00109     // FIXME: initial or all states?
00110     for_all_const_states_(t_, q, Sp)
00111     Sp_to_S[*q] = S.get_state(size_t(*q));
00112 
00113     //
00114     // evaluation(A, Sp)
00115     // Evaluation: we keep some information for later.
00116     //
00117 
00118     // extension
00119     Trans_t tmp_trans(Sp.structure());
00120     tmp_trans = extension(A, Sp);
00121 
00122     // product
00123     Trans_t pro(Sp.structure());
00124     state_pair_map_t sp_m;
00125     pro = product(tmp_trans, Sp, sp_m);
00126 
00127     // build map we will reuse later
00128     std::map<typename Trans_t::hstate_t, typename Trans_t::hstate_t>    states_map_for_sp_m;
00129     for_all_iterator (typename state_pair_map_t::iterator, i, sp_m)
00130     states_map_for_sp_m.insert(std::make_pair(pro.get_state(size_t(i->first)), i->first));
00131 
00132     // image
00133     Auto_t G(auto_structure);
00134     state_state_map_t proj_m;
00135     G = image(pro, proj_m);
00136 
00137     std::map<typename Trans_t::hstate_t, typename Trans_t::hstate_t>    states_map_for_proj_m;
00138     for_all_iterator (typename state_state_map_t::iterator, i, proj_m)
00139     states_map_for_proj_m.insert(std::make_pair(G.get_state(size_t(i->first)), i->first));
00140 
00141     // add i state
00142     const hstate_t i = G.add_state();
00143     for_all_const_initial_states(r, G)
00144     {
00145       exp_t old_label = G.get_initial(*r);
00146       G.add_series_transition(i, *r, old_label);
00147       G.unset_initial(*r);
00148     }
00149     G.set_initial(i);
00150 
00151     //
00152     // Part 3.
00153     // Initialize map.
00154     //
00155 
00156     G.clear_final();
00157     state_state_map_t state_of, is_state_of;
00158     for_all_const_states_(t_, u, Sp)
00159     {
00160       hstate_t new_state = G.add_state();
00161       state_of[*u] = new_state;
00162       is_state_of[new_state] = *u;
00163       G.set_final(new_state);
00164     }
00165 
00166     //
00167     // Part 4.
00168     // Create spontaneous transitions.
00169     //
00170 
00171     for_all_const_states(ig, G)
00172     {
00173       if (*ig != i && !G.is_final(*ig))
00174       {
00175         t_hstate_t t = sp_m[states_map_for_sp_m[proj_m[states_map_for_proj_m[*ig]]]].first;
00176         t_hstate_t u = sp_m[states_map_for_sp_m[proj_m[states_map_for_proj_m[*ig]]]].second;
00177 
00178         if (tmp_trans.is_final(t))
00179           G.add_spontaneous(*ig, state_of[u]);
00180       }
00181     }
00182 
00183     //
00184     // Part 5.
00185     // Construct the output map.
00186     //
00187 
00188     M se;
00189     partial_elimination(G, se);
00190 
00191     for_all_(M, p, se)
00192     {
00193       se_pair_t my_pair = std::make_pair(Sp_to_S[is_state_of[(*p).first]], p->second);
00194       res.insert(my_pair);
00195     }
00196   }
00197 
00198   template<typename S1, typename T1, 
00199   typename S2, typename T2, 
00200   typename M>
00201   void
00202   partial_evaluation(const Element<S1, T1>& E,
00203                      const Element<S2, T2>& S,
00204                      const typename Element<S2, T2>::hstate_t& p,
00205                      M& res)
00206   {
00207     do_partial_evaluation(E, S.structure(), S, p, res);
00208   }
00209 
00210   template<typename S, typename Auto_t, typename M, typename Chooser_t>
00211   void
00212   do_partial_elimination(const AutomataBase<S>&,
00213                          const Auto_t& a,
00214                          Chooser_t chooser,
00215                          M& state_exp_pair_set)
00216   {
00217     AUTOMATON_TYPES(Auto_t);
00218     typedef typename std::set<htransition_t>            htransition_set_t;
00219     typedef typename Auto_t::hstate_t                   hstate_t;
00220     typedef std::map<hstate_t, series_set_elt_t>        sums_t;
00221 
00222     typename htransition_set_t::const_iterator          i, j;
00223     hstate_t                                            q;
00224     htransition_set_t                                   transitions;
00225 
00226     Auto_t b = a;
00227 
00228     // Save a map linking hstates between automata a and b.
00229     // This is needed to be able to fill state_exp_pair_set with correct hstates.
00230     std::map<hstate_t, hstate_t>                        states_map;
00231     for (state_iterator i = a.states().begin(), j = b.states().begin(),
00232          end_ = a.states().end();
00233          i != end_;
00234          ++i, ++j)
00235       states_map.insert(std::make_pair(*j, *i));
00236 
00237     // FIXME: check dead code
00238 //    standardize(b);
00239 
00240     // all final states and the initial state.
00241     int num = b.final().size() + b.initial().size();
00242 
00243     while (int(b.states().size()) != num)
00244     {
00245       series_set_elt_t loop_sum(b.series());
00246       sums_t       in_sums, out_sums;
00247       typename sums_t::iterator f;
00248       q = chooser(b);
00249       if (b.is_initial(q) || b.is_final(q))
00250         continue;
00251 
00252       transitions.clear();
00253       // FIXME: use a new version of delta !
00254       b.deltac(transitions, q, delta_kind::transitions());
00255       for (i = transitions.begin(); i != transitions.end(); i = j)
00256       {
00257         j = i; ++j;
00258 
00259         if (b.dst_of(*i) == q)
00260           loop_sum += b.series_of(*i);
00261         else if ((f = out_sums.find(b.dst_of(*i))) !=
00262                  out_sums.end())
00263           f->second += b.series_of(*i);
00264         else
00265           out_sums.insert(std::make_pair(b.dst_of(*i), b.series_of(*i)));
00266         b.del_transition(*i);
00267       }
00268       transitions.clear();
00269       // FIXME: use a new version of delta !
00270       b.rdeltac(transitions, q, delta_kind::transitions());
00271       for (i = transitions.begin(); i != transitions.end(); i = j)
00272       {
00273         j = i; ++j;
00274         // here all loops have already been removed
00275         if ((f = in_sums.find(b.src_of(*i))) !=
00276             in_sums.end())
00277           f->second += b.series_of(*i);
00278         else
00279           in_sums.insert(std::make_pair(b.src_of(*i), b.series_of(*i)));
00280         b.del_transition(*i);
00281       }
00282       loop_sum.star();
00283       for_all_const_(sums_t, in, in_sums)
00284         for_all_const_(sums_t, out, out_sums)
00285         {
00286           series_set_elt_t res = in->second * loop_sum * out->second;
00287           b.add_series_transition(in->first, out->first, res);
00288         }
00289       b.del_state(q);
00290     }
00291 
00292     typedef std::map<hstate_t, series_set_elt_t>   se_map_t;
00293     typedef std::pair<hstate_t, series_set_elt_t>  state_exp_pair_t;
00294     se_map_t se_m;
00295 
00296     // maybe there are more than one transition comming to one final state
00297     // we must sum the labels
00298     for_all_transitions(e, b)
00299     {
00300       hstate_t dst = b.dst_of(*e);
00301       typename se_map_t::iterator i = se_m.find(dst);
00302       if (i == se_m.end())
00303         se_m.insert(std::make_pair(dst,
00304                                    series_set_elt_t (b.structure().series(),
00305                                                      b.label_of(*e))));
00306       else
00307         i->second += b.label_of(*e);
00308     }
00309 
00310     for_all_final_states(p, b)
00311     {
00312       typename se_map_t::iterator i = se_m.find(*p);
00313       if (i != se_m.end())
00314         state_exp_pair_set.insert(std::make_pair(states_map[*p], i->second));
00315     }
00316   }
00317 
00318   /*------------.
00319   | elimination |
00320   `------------*/
00321   // FIXME: add the generalized automaton precondition
00322   // preconditions :
00323   //   - hope that automaton's labels are sufficient to support "star"
00324   //     => in fact, generalized automaton are generally expected here.
00325   template<typename A, typename T, typename M>
00326   void
00327   partial_elimination(const Element<A, T>& a,
00328                       M& state_exp_pair_set)
00329   {
00330     do_partial_elimination(a.structure(),
00331                            a,
00332                            DefaultChooser(),
00333                            state_exp_pair_set);
00334   }
00335 
00336 } // ! vcsn
00337 
00338 #endif // ! VCSN_ALGORITHMS_EVALUATION_HXX

Generated on Thu Oct 9 20:22:34 2008 for Vaucanson by  doxygen 1.5.1