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<";
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>
std::shared_ptr< detail::mutable_automaton_impl< Context > > mutable_automaton
static labelset_t labelset(const in_labelset_t &ls)
synchronized_automaton_impl(const automaton_t &aut)
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
static labelset_t labelset_(const in_labelset_t &ls, seq< I... >)
auto prefix(const Aut &aut) -> decltype(::vcsn::copy(aut))
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
synchronized_automaton< automaton_t > out_automaton_t
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
std::pair< label_t, label_t > get_prefix(const label_t &l)
static symbol sname()
Static name.
weightset_t_of< in_automaton_t > weightset_t
Weightset of the worded automaton (same as input)
size_t get_min_length(const label_t &l)
typename worded_labelset< in_labelset_t >::labelset_t labelset_t
Labelset of the worded automaton.
A traits to compute the letterized context.
state_t_of< super_t > state_t
constant< type_t::one, Context > one
label_t_of< super_t > label_t
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
auto suffix(const Aut &aut) -> decltype(::vcsn::copy(aut))
weight_t_of< super_t > weight_t
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
An input/output format for valuesets.
static labelset_t labelset(const in_labelset_t &ls)
Create the worded labelset from the original one.
Provide a variadic mul on top of a binary mul(), and one().
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.
std::ostream & print_set(std::ostream &o, format fmt={}) const
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
Build the static sequence of size_t [0, N[.
labelset_t_of< super_t > labelset_t
context_t_of< in_automaton_t > in_context_t
out_automaton_t synchronize()
typename detail::label_t_of_impl< base_t< ValueSet > >::type label_t_of
auto & as()
Extract wrapped typed automaton.
labelset_t_of< in_automaton_t > in_labelset_t
fresh_automaton_t_of< typename worded_automaton< Aut >::automaton_t > fresh_worded_automaton_t
mutable_automaton< context_t > automaton_t
Type of the worded automaton.
Aggregate an automaton, and forward calls to it.
context_t_of< super_t > context_t
size_t get_min_length_(const label_t &l, seq< I... >)
typename labelset_t::template valueset_t< I > tape_labelset_t
std::ostream & list(const PolynomialSet &ps, const typename PolynomialSet::value_t &p, std::ostream &o=std::cout)
weightset_t_of< super_t > weightset_t
law_t< LabelSet > make_wordset(const LabelSet &ls)
The wordset of a labelset.
An exponent, or range of exponents.
An automaton whose states may be qualified by delays and/or prefixes.
fresh_worded_automaton_t< Aut > fresh_t
typename detail::weight_t_of_impl< base_t< ValueSet > >::type weight_t_of
std::pair< state_t_of< automaton_t >, label_t > state_name_t
State + delay.
automaton synchronize(const automaton &aut)
Bridge.
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
Given an automaton type, the type of its copies.
synchronizer< Aut >::out_automaton_t synchronize(const Aut &aut)
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.