00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 #ifndef VCSN_ALGORITHMS_RW_COMPOSITION_HXX
00019 # define VCSN_ALGORITHMS_RW_COMPOSITION_HXX
00020 
00021 # include <map>
00022 # include <queue>
00023 # include <set>
00024 
00025 # include <vaucanson/algorithms/rw_composition.hh>
00026 # include <vaucanson/algorithms/realtime.hh>
00027 # include <vaucanson/automata/concept/transducer.hh>
00028 
00029 
00030 # include <vaucanson/automata/implementation/geometry.hh>
00031 # include <vaucanson/algorithms/internal/evaluation.hh>
00032 
00033 namespace vcsn
00034 {
00035   template <typename U, typename Trans_t>
00036   void
00037   do_rw_composition(const TransducerBase<U>&,
00038                     const Trans_t& R,
00039                     const Trans_t& S,
00040                     Trans_t& T)
00041   {
00042     BENCH_TASK_SCOPED("rw_composition");
00043 
00044     
00045     precondition(is_realtime(S));
00046 
00047     
00048     AUTOMATON_TYPES(Trans_t);
00049     typedef series_set_elt_t exp_t;
00050     typedef typename series_set_elt_t::semiring_elt_t output_exp_t;
00051     typedef std::set<std::pair<hstate_t, output_exp_t> > state_exp_pair_set_t;
00052     typedef typename std::map<hstate_t, typename Trans_t::geometry_t::coords_t>::const_iterator geom_iter_t;
00053     typedef std::pair<hstate_t, hstate_t> state_pair_t;
00054     typedef std::queue<state_pair_t> state_pair_queue_t;
00055     typedef std::map<state_pair_t, hstate_t> state_pair_map_t;
00056     typedef std::set<htransition_t> set_of_transitions_t;
00057 
00058     
00059     state_pair_queue_t queue;
00060 
00061     
00062     
00063     
00064     state_exp_pair_set_t sep_set;
00065 
00066     
00067     
00068     
00069     state_pair_map_t Tstates;
00070 
00071     
00072     double xgeom;
00073     double ygeom;
00074     geom_iter_t iter;
00075 
00076     
00077     
00078     
00079     
00080 
00081     monoid_elt_t Ridentity = R.series().monoid().identity(SELECT(monoid_elt_value_t));
00082     monoid_elt_t Sidentity = S.series().monoid().identity(SELECT(monoid_elt_value_t));
00083     monoid_elt_t Tidentity = T.series().monoid().identity(SELECT(monoid_elt_value_t));
00084 
00085     for_all_const_initial_states (p, R)
00086     {
00087       
00088       
00089       
00090       
00091       output_exp_t E = R.get_initial(*p).get(Ridentity);
00092 
00093       for_all_const_initial_states (q, S)
00094       {
00095         
00096         
00097         output_exp_t F = S.get_initial(*q).get(Sidentity);
00098 
00099         
00100         sep_set.clear();
00101         partial_evaluation(E, S, *q, sep_set);
00102 
00103         
00104         for_all_const_(state_exp_pair_set_t, ig, sep_set)
00105         {
00106           
00107           state_pair_t sp;
00108           sp.first = *p;
00109           sp.second = (*ig).first;
00110 
00111           if (Tstates.find(sp) == Tstates.end())
00112           {
00113             
00114 
00115             
00116             hstate_t new_state = T.add_state();
00117 
00118             
00119             iter = R.geometry().states().find(*p);
00120             if (iter != R.geometry().states().end())
00121               xgeom = (*iter).second.first;
00122             else
00123               xgeom = 0;
00124             iter = S.geometry().states().find(*q);
00125             if (iter != S.geometry().states().end())
00126               ygeom = (*iter).second.second;
00127             else
00128               ygeom = 0;
00129             T.geometry().states()[new_state] = std::make_pair(xgeom, ygeom);
00130 
00131             
00132             Tstates[sp] = new_state;
00133 
00134             
00135             series_set_elt_t new_series(T.series());
00136             new_series.assoc(Tidentity, F * ((*ig).second));
00137             T.set_initial(new_state, new_series);
00138 
00139             
00140             queue.push(sp);
00141           }
00142           else
00143           {
00144             
00145             
00146             series_set_elt_t new_series(T.series());
00147             new_series.assoc(Tidentity, T.get_initial(Tstates[sp]).get(Tidentity) + F * ((*ig).second));
00148             T.set_initial(Tstates[sp], new_series);
00149           }
00150         } 
00151       } 
00152     } 
00153 
00154     
00155     
00156     
00157     
00158 
00159     while (not queue.empty())
00160     {
00161       
00162       const state_pair_t sp = queue.front();
00163       queue.pop();
00164 
00165       const hstate_t p = sp.first;
00166       const hstate_t q = sp.second;
00167 
00168       
00169       for (delta_iterator e(R.value(), p); !e.done(); e.next())
00170       {
00171         hstate_t s = R.dst_of(*e);
00172         exp_t E = R.series_of(*e);
00173 
00174         
00175         
00176         for_all_const_(series_set_elt_t::support_t, y, E.supp())
00177         {
00178           const monoid_elt_t x(E.structure().monoid(), *y);
00179 
00180           
00181           sep_set.clear();
00182           partial_evaluation(E.get(x), S, q, sep_set);
00183 
00184           for_all_const_(state_exp_pair_set_t, ig, sep_set)
00185           {
00186             
00187             state_pair_t sp1;
00188             sp1.first = s;
00189             sp1.second = (*ig).first;
00190 
00191             if (Tstates.find(sp1) == Tstates.end())
00192             {
00193               
00194 
00195               
00196               hstate_t new_state = T.add_state();
00197 
00198               
00199               iter = R.geometry().states().find(sp1.first);
00200               if (iter != R.geometry().states().end())
00201                 xgeom = (*iter).second.first;
00202               else
00203                 xgeom = 0;
00204               iter = S.geometry().states().find(sp1.second);
00205               if (iter != S.geometry().states().end())
00206                 ygeom = (*iter).second.second;
00207               else
00208                 ygeom = 0;
00209               T.geometry().states()[new_state] = std::make_pair(xgeom, ygeom);
00210 
00211               
00212               Tstates[sp1] = new_state;
00213 
00214               
00215               queue.push(sp1);
00216             }
00217 
00218             exp_t Gexp(R.structure().series());
00219             Gexp.assoc(x, (*ig).second);
00220             T.add_series_transition(Tstates[sp], Tstates[sp1], Gexp);
00221           } 
00222         } 
00223       } 
00224 
00225       
00226       if (R.is_final(p))
00227       {
00228         
00229         
00230         sep_set.clear();
00231         partial_evaluation(R.get_final(p).get(Ridentity), S, q, sep_set);
00232 
00233         for_all_const_(state_exp_pair_set_t, ig, sep_set)
00234         {
00235           const hstate_t r = (*ig).first;
00236           if (S.is_final(r))
00237           {
00238             series_set_elt_t new_series(T.series());
00239             
00240             new_series.assoc(Tidentity, (*ig).second * S.get_final(r).get(Sidentity));
00241             T.set_final(Tstates[sp], new_series);
00242           }
00243         }
00244       } 
00245     } 
00246   }
00247 
00248   
00249   template <typename S, typename T>
00250   void
00251   rw_composition(const Element<S, T>& lhs,
00252                  const Element<S, T>& rhs,
00253                  Element<S, T>& ret)
00254   {
00255     
00256     typedef Element<S, T> auto_t;
00257     AUTOMATON_TYPES(auto_t);
00258 
00259     
00260     
00261     
00262     precondition(&ret != &lhs);
00263     precondition(&ret != &rhs);
00264 
00265     
00266     for_all_states (s, ret)
00267       ret.del_state(*s);
00268 
00269     do_rw_composition(lhs.structure(), lhs, rhs, ret);
00270   }
00271 
00272   
00273   
00274   template <typename S, typename T>
00275   Element<S, T>
00276   rw_composition(const Element<S, T>& lhs, const Element<S, T>& rhs)
00277   {
00278     
00279     Element<S, T> ret(lhs.structure());
00280 
00281     do_rw_composition(lhs.structure(), lhs, rhs, ret);
00282     return ret;
00283   }
00284 
00285 } 
00286 
00287 #endif // ! VCSN_ALGORITHMS_RW_COMPOSITION_HXX