17 #ifndef VCSN_ALGORITHMS_SHUFFLE_HXX
18 # define VCSN_ALGORITHMS_SHUFFLE_HXX
29 # endif // ! VCSN_NDEBUG
31 # include <vaucanson/automata/concept/automata_base.hh>
32 # include <vaucanson/misc/usual_macros.hh>
33 # include <vaucanson/automata/implementation/geometry.hh>
42 template<
typename A,
typename T,
typename U>
46 typedef AutomataBase<A> structure_t;
47 typedef Element<A, T> lhs_t;
48 typedef Element<A, U> rhs_t;
49 typedef lhs_t output_t;
50 typedef std::map<
typename output_t::hstate_t,
51 std::pair<typename lhs_t::hstate_t, typename rhs_t::hstate_t> >
54 Shuffle (
const structure_t& structure,
55 const bool use_geometry)
56 : use_geometry_(use_geometry),
57 series_(structure.series()),
58 monoid_(series_.monoid()),
59 semiring_zero_(series_.semiring().zero(
SELECT(semiring_elt_value_t)))
65 operator() (output_t& output,
70 BENCH_TASK_SCOPED(
"shuffle");
76 this->initialize_queue(output, lhs, rhs, m);
78 while (not to_process_.empty())
80 const pair_hstate_t current_pair = to_process_.front();
83 const hstate_t lhs_s = current_pair.first;
84 const hstate_t rhs_s = current_pair.second;
85 const hstate_t current_state = visited_[current_pair];
87 output.set_initial(current_state,
88 lhs.get_initial(lhs_s) * rhs.get_initial(rhs_s));
89 output.set_final(current_state,
90 lhs.get_final(lhs_s) * rhs.get_final(rhs_s));
92 for (
typename lhs_t::delta_iterator l(lhs.value(), lhs_s);
96 const pair_hstate_t new_pair(lhs.dst_of(*l), rhs_s);
97 typename visited_t::const_iterator found = visited_.find(new_pair);
100 if (found == visited_.end())
102 dst = output.add_state();
104 this->add_state_to_process(output, lhs, rhs, m, dst, new_pair);
108 output.add_series_transition(current_state, dst, lhs.series_of(*l));
110 for (
typename rhs_t::delta_iterator r(rhs.value(), rhs_s);
114 const pair_hstate_t new_pair(lhs_s, rhs.dst_of(*r));
115 typename visited_t::const_iterator found = visited_.find(new_pair);
118 if (found == visited_.end())
120 dst = output.add_state();
122 this->add_state_to_process(output, lhs, rhs, m, dst, new_pair);
126 output.add_series_transition(current_state, dst, rhs.series_of(*r));
132 merge_transitions(output);
138 void merge_transitions(output_t& a)
140 typedef std::map<hstate_t, series_set_elt_t> map_t;
145 for (delta_iterator e(a.value(), *s); ! e.done(); e.next())
147 hstate_t target = a.dst_of(*e);
148 transitions.push_back(*e);
149 typename map_t::iterator it = map.find(target);
151 map.insert(std::pair<hstate_t, series_set_elt_t>(target,
154 it->second += a.series_of(*e);
156 for_all_(std::list<htransition_t>, e, transitions)
157 a.del_transition(*e);
158 for_all_(map_t, it, map)
159 if(it->second != a.series().zero_)
160 a.add_series_transition(*s, it->first, it->second);
168 template <
typename Output,
typename Lhs,
typename Rhs>
170 setcoordfrom (Output& a,
173 const typename Output::hstate_t state,
174 const typename Lhs::hstate_t x_state,
175 const typename Rhs::hstate_t y_state)
177 typename std::map<
typename Lhs::hstate_t,
178 typename Lhs::geometry_t::coords_t>::const_iterator iter;
179 typename std::map<
typename Rhs::hstate_t,
180 typename Rhs::geometry_t::coords_t>::const_iterator iter2;
183 iter = lhs.geometry().states().find(x_state);
184 if (iter != lhs.geometry().states().end())
185 x = iter->second.first;
187 iter2 = rhs.geometry().states().find(y_state);
188 if (iter2 != rhs.geometry().states().end())
189 y = iter2->second.second;
191 a.geometry().states()[state] = std::make_pair(x, y);
200 std::map<hstate_t,bool> visited;
201 std::stack<hstate_t> stack;
203 for_all_const_states(i, a)
210 for_all_const_initial_states(i, a)
214 while (!stack.empty())
216 hstate_t i = stack.top();
223 a.geometry()[i] = std::make_pair(x, x);
226 for (delta_iterator j(a.value(), i);
229 stack.push(a.dst_of(*j));
238 template <
typename Output,
typename Lhs,
typename Rhs>
240 setcoordfrom (Output& a,
243 const typename Output::hstate_t state,
244 const typename Lhs::hstate_t x_state,
245 const typename Rhs::hstate_t y_state) {};
249 AUTOMATON_TYPES(output_t);
251 typedef std::pair<typename lhs_t::hstate_t, typename rhs_t::hstate_t>
253 typedef std::list<htransition_t> delta_ret_t;
254 typedef std::map<pair_hstate_t, hstate_t> visited_t;
255 typedef typename series_set_elt_t::support_t support_t;
259 add_state_to_process (output_t& output,
263 const hstate_t& new_state,
264 const pair_hstate_t& new_pair)
266 m[new_state] = new_pair;
267 visited_[new_pair] = new_state;
268 to_process_.push(new_pair);
270 # define if_(Cond, ThenClause, ElseClause) \
271 misc::static_if_simple<Cond, ThenClause, ElseClause>::t
272 # define eq_(Type1, Type2) \
273 misc::static_eq<Type1, Type2>::value
274 # define DECLARE_GEOMETRY(Type) \
275 typedef geometry<typename Type::hstate_t, typename Type::htransition_t, typename Type::geometry_coords_t> geometry_ ## Type ;
277 DECLARE_GEOMETRY(output_t)
278 DECLARE_GEOMETRY(lhs_t)
279 DECLARE_GEOMETRY(rhs_t)
281 if_(eq_(typename output_t::geometry_t, geometry_output_t) and \
282 eq_(typename rhs_t::geometry_t, geometry_rhs_t) and \
283 eq_(typename lhs_t::geometry_t, geometry_lhs_t), \
285 ::setcoordfrom(output, lhs, rhs,
286 new_state, new_pair.first, new_pair.second);
293 initialize_queue (output_t& output,
298 for_all_const_initial_states(lhs_s, lhs)
299 for_all_const_initial_states(rhs_s, rhs)
301 const pair_hstate_t new_pair(*lhs_s, *rhs_s);
302 const hstate_t new_state = output.add_state();
304 this->add_state_to_process(output, lhs, rhs, m, new_state, new_pair);
309 is_shuffle_not_null (
const lhs_t& lhs,
311 const typename lhs_t::delta_iterator& l,
312 const typename rhs_t::delta_iterator& r,
313 series_set_elt_t& prod_series)
const
315 const series_set_elt_t left_series = lhs.series_of(*l);
316 const series_set_elt_t right_series = rhs.series_of(*r);
318 bool prod_is_not_null =
false;
319 for_all_(support_t, supp, left_series.supp())
321 const monoid_elt_t supp_elt (monoid_, *supp);
322 const semiring_elt_t l = left_series.get(supp_elt);
323 const semiring_elt_t r = right_series.get(supp_elt);
324 const semiring_elt_t p = l * r;
325 if (p != semiring_zero_)
327 prod_series.assoc(*supp, p.value());
328 prod_is_not_null =
true;
331 return (prod_is_not_null);
335 const bool use_geometry_;
340 std::queue<pair_hstate_t> to_process_;
343 const series_set_t& series_;
344 const monoid_t& monoid_;
346 const semiring_elt_t semiring_zero_;
353 template<
typename A,
typename T,
typename U>
355 shuffle (
const Element<A, T>& lhs,
const Element<A, U>& rhs,
356 std::map<
typename T::hstate_t,
357 std::pair<typename T::hstate_t, typename U::hstate_t> >& m,
358 const bool use_geometry)
360 Element<A, T> ret(rhs.structure());
361 Shuffle<A, T, U> do_shuffle(ret.structure(), use_geometry);
362 return do_shuffle (ret, lhs, rhs, m);
365 template<
typename A,
typename T,
typename U>
367 shuffle (
const Element<A, T>& lhs,
const Element<A, U>& rhs,
368 const bool use_geometry)
370 std::map<
typename T::hstate_t,
371 std::pair<typename T::hstate_t, typename U::hstate_t> > m;
372 return shuffle (lhs, rhs, m, use_geometry);
377 #endif // ! VCSN_ALGORITHMS_SHUFFLE_HXX