17 #ifndef VCSN_ALGORITHMS_INFILTRATION_HXX
18 # define VCSN_ALGORITHMS_INFILTRATION_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 Infiltration (
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(
"infiltration");
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);
95 for (
typename rhs_t::delta_iterator r(rhs.value(), rhs_s);
99 series_set_elt_t prod_series(series_);
101 if (is_product_not_null(lhs, rhs, l, r, prod_series))
103 const pair_hstate_t new_pair(lhs.dst_of(*l), rhs.dst_of(*r));
104 typename visited_t::const_iterator found = visited_.find(new_pair);
107 if (found == visited_.end())
109 dst = output.add_state();
111 this->add_state_to_process(output, lhs, rhs, m, dst, new_pair);
115 output.add_series_transition(current_state, dst, prod_series);
118 for (
typename lhs_t::delta_iterator l(lhs.value(), lhs_s);
122 const pair_hstate_t new_pair(lhs.dst_of(*l), rhs_s);
123 typename visited_t::const_iterator found = visited_.find(new_pair);
126 if (found == visited_.end())
128 dst = output.add_state();
130 this->add_state_to_process(output, lhs, rhs, m, dst, new_pair);
134 output.add_series_transition(current_state, dst, lhs.series_of(*l));
136 for (
typename rhs_t::delta_iterator r(rhs.value(), rhs_s);
140 const pair_hstate_t new_pair(lhs_s, rhs.dst_of(*r));
141 typename visited_t::const_iterator found = visited_.find(new_pair);
144 if (found == visited_.end())
146 dst = output.add_state();
148 this->add_state_to_process(output, lhs, rhs, m, dst, new_pair);
152 output.add_series_transition(current_state, dst, rhs.series_of(*r));
156 merge_transitions(output);
162 void merge_transitions(output_t& a)
164 typedef std::map<hstate_t, series_set_elt_t> map_t;
169 for (delta_iterator e(a.value(), *s); ! e.done(); e.next())
171 hstate_t target = a.dst_of(*e);
172 transitions.push_back(*e);
173 typename map_t::iterator it = map.find(target);
175 map.insert(std::pair<hstate_t, series_set_elt_t>(target,
178 it->second += a.series_of(*e);
180 for_all_(std::list<htransition_t>, e, transitions)
181 a.del_transition(*e);
182 for_all_(map_t, it, map)
183 if(it->second != a.series().zero_)
184 a.add_series_transition(*s, it->first, it->second);
192 template <
typename Output,
typename Lhs,
typename Rhs>
194 setcoordfrom (Output& a,
197 const typename Output::hstate_t state,
198 const typename Lhs::hstate_t x_state,
199 const typename Rhs::hstate_t y_state)
201 typename std::map<
typename Lhs::hstate_t,
202 typename Lhs::geometry_t::coords_t>::const_iterator iter;
203 typename std::map<
typename Rhs::hstate_t,
204 typename Rhs::geometry_t::coords_t>::const_iterator iter2;
207 iter = lhs.geometry().states().find(x_state);
208 if (iter != lhs.geometry().states().end())
209 x = iter->second.first;
211 iter2 = rhs.geometry().states().find(y_state);
212 if (iter2 != rhs.geometry().states().end())
213 y = iter2->second.second;
215 a.geometry().states()[state] = std::make_pair(x, y);
224 std::map<hstate_t,bool> visited;
225 std::stack<hstate_t> stack;
227 for_all_const_states(i, a)
234 for_all_const_initial_states(i, a)
238 while (!stack.empty())
240 hstate_t i = stack.top();
247 a.geometry()[i] = std::make_pair(x, x);
250 for (delta_iterator j(a.value(), i);
253 stack.push(a.dst_of(*j));
262 template <
typename Output,
typename Lhs,
typename Rhs>
264 setcoordfrom (Output& a,
267 const typename Output::hstate_t state,
268 const typename Lhs::hstate_t x_state,
269 const typename Rhs::hstate_t y_state) {};
273 AUTOMATON_TYPES(output_t);
275 typedef std::pair<typename lhs_t::hstate_t, typename rhs_t::hstate_t>
277 typedef std::list<htransition_t> delta_ret_t;
278 typedef std::map<pair_hstate_t, hstate_t> visited_t;
279 typedef typename series_set_elt_t::support_t support_t;
283 add_state_to_process (output_t& output,
287 const hstate_t& new_state,
288 const pair_hstate_t& new_pair)
290 m[new_state] = new_pair;
291 visited_[new_pair] = new_state;
292 to_process_.push(new_pair);
294 # define if_(Cond, ThenClause, ElseClause) \
295 misc::static_if_simple<Cond, ThenClause, ElseClause>::t
296 # define eq_(Type1, Type2) \
297 misc::static_eq<Type1, Type2>::value
298 # define DECLARE_GEOMETRY(Type) \
299 typedef geometry<typename Type::hstate_t, typename Type::htransition_t, typename Type::geometry_coords_t> geometry_ ## Type ;
301 DECLARE_GEOMETRY(output_t)
302 DECLARE_GEOMETRY(lhs_t)
303 DECLARE_GEOMETRY(rhs_t)
305 if_(eq_(typename output_t::geometry_t, geometry_output_t) and \
306 eq_(typename rhs_t::geometry_t, geometry_rhs_t) and \
307 eq_(typename lhs_t::geometry_t, geometry_lhs_t), \
309 ::setcoordfrom(output, lhs, rhs,
310 new_state, new_pair.first, new_pair.second);
317 initialize_queue (output_t& output,
322 for_all_const_initial_states(lhs_s, lhs)
323 for_all_const_initial_states(rhs_s, rhs)
325 const pair_hstate_t new_pair(*lhs_s, *rhs_s);
326 const hstate_t new_state = output.add_state();
328 this->add_state_to_process(output, lhs, rhs, m, new_state, new_pair);
333 is_product_not_null (
const lhs_t& lhs,
335 const typename lhs_t::delta_iterator& l,
336 const typename rhs_t::delta_iterator& r,
337 series_set_elt_t& prod_series)
const
339 const series_set_elt_t left_series = lhs.series_of(*l);
340 const series_set_elt_t right_series = rhs.series_of(*r);
342 bool prod_is_not_null =
false;
343 for_all_(support_t, supp, left_series.supp())
345 const monoid_elt_t supp_elt (monoid_, *supp);
346 const semiring_elt_t l = left_series.get(supp_elt);
347 const semiring_elt_t r = right_series.get(supp_elt);
348 const semiring_elt_t p = l * r;
349 if (p != semiring_zero_)
351 prod_series.assoc(*supp, p.value());
352 prod_is_not_null =
true;
355 return (prod_is_not_null);
359 const bool use_geometry_;
364 std::queue<pair_hstate_t> to_process_;
367 const series_set_t& series_;
368 const monoid_t& monoid_;
370 const semiring_elt_t semiring_zero_;
377 template<
typename A,
typename T,
typename U>
379 infiltration (
const Element<A, T>& lhs,
const Element<A, U>& rhs,
380 std::map<
typename T::hstate_t,
381 std::pair<typename T::hstate_t, typename U::hstate_t> >& m,
382 const bool use_geometry)
384 Element<A, T> ret(rhs.structure());
385 Infiltration<A, T, U> do_infiltration(ret.structure(), use_geometry);
386 return do_infiltration (ret, lhs, rhs, m);
389 template<
typename A,
typename T,
typename U>
391 infiltration (
const Element<A, T>& lhs,
const Element<A, U>& rhs,
392 const bool use_geometry)
394 std::map<
typename T::hstate_t,
395 std::pair<typename T::hstate_t, typename U::hstate_t> > m;
396 return infiltration (lhs, rhs, m, use_geometry);
401 #endif // ! VCSN_ALGORITHMS_INFILTRATION_HXX