4 #include <unordered_map>
6 #include <vcsn/algos/fwd.hh>
22 template <Automaton Aut>
25 template <
typename Dummy>
28 template <
typename... LabelSet>
34 template <std::size_t... I>
40 return labelset_(ls,
index_t{});
43 template <std::size_t... I>
70 template <Automaton Aut>
80 template <Automaton Aut>
112 static auto res =
symbol{
"synchronized_automaton<"
120 o <<
"synchronized_automaton<";
121 super_t::print_set(o, fmt);
126 using smap = std::unordered_map<state_name_t, state_t>;
130 state_t state(const state_name_t& r, bool todo = true)
132 if (r.first == aut_->pre())
134 // Benches show that the map_.emplace technique is slower, and
135 // then that operator[] is faster than emplace.
137 auto i = map_.find(r);
138 if (i == std::end(map_))
140 res = super_t::new_state();
150 using super_t::new_transition;
153 new_transition(const state_name_t& src, const state_name_t& dst,
154 const label_t& l, const weight_t& w)
156 super_t::new_transition(state(src), state(dst), l, w);
159 using super_t::set_final;
161 void set_final(const state_name_t& st, const weight_t& w)
163 super_t::set_final(map_[st], w);
166 bool state_has_name(state_t s) const
168 return has(origins(), s);
172 print_state_name(state_t s, std::ostream& o,
176 auto name = origins().at(s);
177 aut_->print_state_name(name.first, o, fmt, true);
179 this->labelset()->print(name.second, o, fmt.for_labels());
184 using origins_t = std::unordered_map<state_t, state_name_t>;
185 mutable origins_t origins_;
190 if (origins_.empty())
191 for (const auto& p: map_)
192 origins_[p.second] = p.first;
197 std::stack<state_name_t, std::vector<state_name_t>> todo_;
204 template <Automaton Aut>
205 using synchronized_automaton
206 = std::shared_ptr<synchronized_automaton_impl<Aut>>;
208 template <Automaton Aut>
211 static_assert(context_t_of<Aut>::is_lat,
212 "synchronize: automaton labelset must be a tupleset");
215 using automaton_t = Aut;
216 using out_automaton_t = synchronized_automaton<automaton_t>;
217 using state_t = state_t_of<automaton_t>;
218 using labelset_t = labelset_t_of<out_automaton_t>;
219 using weightset_t = weightset_t_of<out_automaton_t>;
220 using label_t = typename labelset_t::value_t;
221 using state_name_t = typename out_automaton_t::element_type::state_name_t;
224 template <std::size_t... I>
225 using seq = vcsn::detail::index_sequence<I...>;
227 static constexpr size_t number_of_tapes = labelset_t_of<Aut>::size();
229 using index_t = detail::make_index_sequence<number_of_tapes>;
231 static constexpr index_t indices = {};
234 using tape_labelset_t = typename labelset_t::template valueset_t<I>;
236 synchronizer(const automaton_t& aut)
237 : in_aut_(aut), out_aut_(make_shared_ptr<out_automaton_t>(aut))
240 out_automaton_t synchronize()
242 while (!out_aut_->todo_.empty())
244 state_name_t st = std::move(out_aut_->todo_.top());
245 out_aut_->todo_.pop();
247 label_t l = st.second;
248 if (in_aut_->is_final(s))
250 if (labelset_t::is_one(l))
251 out_aut_->set_final(st, in_aut_->get_final_weight(s));
254 auto f = state_name_t{s, labelset_t::one()};
255 // Create the state, don't add it
to the todo
list.
256 out_aut_->state(f,
false);
257 out_aut_->new_transition(st, f, l,
258 in_aut_->get_final_weight(s));
263 for (
auto tr :
out(in_aut_, s))
266 out_aut_->labelset()->mul(l,
267 out_aut_->labelset()->conv(*in_aut_->labelset(),
268 in_aut_->label_of(tr)));
270 auto pre_suf = get_prefix(combined);
271 out_aut_->new_transition(st,
272 {in_aut_->dst_of(tr), pre_suf.second},
274 in_aut_->weight_of(tr));
282 std::pair<label_t, label_t>
285 return get_prefix(get_min_length(l), l);
290 std::pair<label_t, label_t>
293 auto ls = out_aut_->labelset();
299 ls->letters_of_padded(l,
317 return get_min_length_(l, indices);
320 template <
size_t... I>
330 template <Automaton Aut>
348 template <Automaton Aut>
361 template <Automaton Aut>
constant< type_t::one, Context > one
auto prefix(const Aut &aut) -> decltype(::vcsn::copy(aut))
static labelset_t labelset_(const in_labelset_t &ls, seq< I... >)
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
An automaton whose states may be qualified by delays and/or prefixes.
A traits to compute the letterized context.
fresh_worded_automaton_t< Aut > fresh_t
Aggregate an automaton, and forward calls to it.
static labelset_t labelset(const in_labelset_t &ls)
An input/output format for valuesets.
std::ostream & print_set(std::ostream &o, format fmt={}) const
Provide a variadic mul on top of a binary mul(), and one().
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
Given an automaton type, the type of its copies.
context_t_of< in_automaton_t > in_context_t
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
state_t_of< super_t > state_t
std::pair< label_t, label_t > get_prefix(size_t length, const label_t &l)
Split the label in prefix/suffix, with the prefix of size length.
labelset_t_of< in_automaton_t > in_labelset_t
auto suffix(const Aut &aut) -> decltype(::vcsn::copy(aut))
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
static symbol sname()
Static name.
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
synchronized_automaton_impl(const automaton_t &aut)
size_t get_min_length(const label_t &l)
out_automaton_t synchronize()
automaton synchronize(const automaton &aut)
Bridge.
labelset_t_of< super_t > labelset_t
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
std::pair< label_t, label_t > get_prefix(const label_t &l)
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
weightset_t_of< in_automaton_t > weightset_t
Weightset of the worded automaton (same as input)
static labelset_t labelset(const in_labelset_t &ls)
Create the worded labelset from the original one.
weight_t_of< super_t > weight_t
mutable_automaton< context_t > automaton_t
Type of the worded automaton.
std::pair< state_t_of< automaton_t >, label_t > state_name_t
State + delay.
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
An exponent, or range of exponents.
typename worded_labelset< in_labelset_t >::labelset_t labelset_t
Labelset of the worded automaton.
size_t get_min_length_(const label_t &l, seq< I... >)
weightset_t_of< super_t > weightset_t
label_t_of< super_t > label_t
auto & as()
Extract wrapped typed automaton.
std::ostream & list(const PolynomialSet &ps, const typename PolynomialSet::value_t &p, std::ostream &o=std::cout)
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
synchronized_automaton< automaton_t > out_automaton_t
fresh_automaton_t_of< typename worded_automaton< Aut >::automaton_t > fresh_worded_automaton_t
law_t< LabelSet > make_wordset(const LabelSet &ls)
The wordset of a labelset.
context_t_of< super_t > context_t
typename labelset_t::template valueset_t< I > tape_labelset_t