- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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