29 template <Automaton Aut, wet_kind_t Kind,
bool Lazy = false>
34 "determinize: requires free labelset");
64 return aut_->origins();
70 :
super_t{make_polystate_automaton<automaton_t, kind, Lazy>(a)}
75 aut_->input_->src_of(t),
76 aut_->input_->weight_of(t));
81 static auto res =
symbol{
"determinized_automaton<"
84 +
", " + (Lazy ?
"true" :
"false")
91 o <<
"determinized_automaton<";
92 aut_->input_->print_set(o, fmt);
101 while (!
aut_->todo_.empty())
104 const auto& ss =
aut_->state_name(
aut_->todo_.front());
114 if (Lazy &&
aut_->is_lazy(s))
116 return aut_->all_out(s);
129 template <wet_kind_t K = kind>
131 -> std::enable_if_t<K == wet_kind_t::bitset>
134 "determinize: boolean: requires B or F2 weights");
136 aut_->set_lazy(src,
false);
139 = std::map<label_t, state_name_t, vcsn::less<labelset_t>>;
140 auto dests = dests_t{};
141 for (
const auto& p : ss)
150 for (
auto t :
out(
aut_->input_, s))
152 auto l =
aut_->input_->label_of(t);
153 auto dst =
aut_->input_->dst_of(t);
154 if (j.find(l) == j.end())
155 j.emplace(l,
aut_->zero());
156 aut_->ns_.new_weight(j[l], dst,
aut_->ws_.one());
161 for (
const auto& p : i->second)
163 auto j = dests.find(p.first);
164 if (j == dests.end())
165 dests[p.first] = p.second;
167 aut_->ns_.add_here(j->second, p.second);
172 for (
auto& d : dests)
174 if (!
aut_->ns_.is_zero(d.second))
179 if (!
aut_->ws_.is_zero(w))
184 template <wet_kind_t K = kind>
186 -> std::enable_if_t<K != wet_kind_t::bitset>
189 aut_->set_lazy(src,
false);
192 = std::map<label_t, state_name_t, vcsn::less<labelset_t>>;
193 auto dests = dests_t{};
194 for (
const auto& p : ss)
198 for (
auto t :
out(
aut_->input_, s))
200 auto l =
aut_->input_->label_of(t);
201 auto dst =
aut_->input_->dst_of(t);
202 auto w =
aut_->ws_.mul(
v,
aut_->input_->weight_of(t));
207 dests.emplace(l,
aut_->zero());
208 aut_->ns_.add_here(dests[l], dst, w);
213 for (
auto& d : dests)
215 if (!
aut_->ns_.is_zero(d.second))
223 if (!
aut_->ws_.is_zero(w))
240 template <Automaton Aut, wet_kind_t Kind,
bool Lazy = false>
242 = std::shared_ptr<detail::determinized_automaton_impl<Aut, Kind, Lazy>>;
244 template <Automaton Aut,
typename Tag,
bool Lazy = false>
248 constexpr
auto kind =
249 std::is_same<Tag, boolean_tag>::value
251 : detail::wet_kind<labelset_t_of<Aut>, weightset_t_of<Aut>>();
252 auto res = make_shared_ptr<determinized_automaton<Aut, kind, Lazy>>(a);
262 template <Automaton Aut>
264 = std::conditional_t<std::is_same<weight_t_of<Aut>,
bool>::value,
270 template <Automaton Aut,
bool Lazy = false>
274 return determinize(a, detail::determinization_tag<Aut>{}, lazy);
288 template <Automaton Aut,
typename Type =
void>
290 = std::enable_if_t<std::is_same<weight_t_of<Aut>,
bool>::value, Type>;
293 template <Automaton Aut,
typename Type =
void>
295 = std::enable_if_t<!std::is_same<weight_t_of<Aut>,
bool>::value, Type>;
298 template <Automaton Aut,
typename Tag,
bool Lazy = false>
306 template <Automaton Aut,
typename String>
307 enable_if_boolean_t<Aut, automaton>
312 "determinization algorithm",
314 {
"auto", determinize_tag_<Aut, auto_tag>},
315 {
"boolean", determinize_tag_<Aut, boolean_tag>},
316 {
"weighted", determinize_tag_<Aut, weighted_tag>},
317 {
"lazy",
"lazy,auto"},
318 {
"lazy,auto",
"lazy,weighted"},
319 {
"lazy,weighted", determinize_tag_<Aut, weighted_tag, true>},
322 return map[algo](aut->as<Aut>());
326 template <Automaton Aut,
typename String>
327 enable_if_not_boolean_t<Aut, automaton>
332 "determinization algorithm",
334 {
"auto", determinize_tag_<Aut, auto_tag>},
335 {
"weighted", determinize_tag_<Aut, weighted_tag>},
336 {
"lazy",
"lazy,auto"},
337 {
"lazy,auto",
"lazy,weighted"},
338 {
"lazy,weighted", determinize_tag_<Aut, weighted_tag, true>},
341 if (algo ==
"boolean")
342 raise(
"determinize: cannot apply Boolean"
343 " determinization to weighted automata");
344 return map[algo](aut->as<Aut>());
348 template <Automaton Aut,
typename String>
352 return determinize_<Aut, String>(aut, algo);
362 template <Automaton Aut,
typename Tag = auto_tag>
378 template <Automaton Aut,
typename Tag>
385 template <Automaton Aut,
typename String>
386 enable_if_boolean_t<Aut, automaton>
391 "codeterminization algorithm",
393 {
"auto", codeterminize_tag_<Aut, auto_tag>},
394 {
"boolean", codeterminize_tag_<Aut, boolean_tag>},
395 {
"weighted", codeterminize_tag_<Aut, weighted_tag>},
398 return map[algo](aut->as<Aut>());
402 template <Automaton Aut,
typename String>
403 enable_if_not_boolean_t<Aut, automaton>
408 "codeterminization algorithm",
410 {
"auto", codeterminize_tag_<Aut, auto_tag>},
411 {
"weighted", codeterminize_tag_<Aut, weighted_tag>},
414 if (algo ==
"boolean")
415 raise(
"codeterminize: cannot apply Boolean"
416 " determinization to weighted automata");
417 return map[algo](aut->as<Aut>());
421 template <Automaton Aut,
typename String>
425 return codeterminize_<Aut, String>(aut, algo);
void complete_(state_t s) const
Complete a state: find its outgoing transitions.
std::integral_constant< bool, B > bool_constant
auto map(const std::tuple< Ts... > &ts, Fun f) -> decltype(map_tuple_(f, ts, make_index_sequence< sizeof...(Ts)>()))
Map a function on a tuple, return tuple of the results.
auto all_out(state_t s) const -> decltype(all_out(aut_, s))
All the outgoing transitions.
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
auto codeterminize(const Aut &aut, Tag tag={})
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
auto weight_of(Args &&...args) const -> decltype(aut_-> weight_of(std::forward< Args >(args)...))
labelset_t_of< automaton_t > labelset_t
typename super_t::element_type::state_name_t state_name_t
The state name: set of (input) states.
std::string to_string(direction d)
Conversion to string.
std::shared_ptr< detail::determinized_automaton_impl< Aut, Kind, Lazy >> determinized_automaton
A determinized automaton as a shared pointer.
weightset_t_of< automaton_t > weightset_t
std::enable_if_t<!std::is_same< weight_t_of< Aut >, bool >::value, Type > enable_if_not_boolean_t
Enable if Aut is not over Booleans.
automaton_t aut_
The wrapped automaton, possibly const.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
An input/output format for valuesets.
std::ostream & print_set(std::ostream &o, format fmt={}) const
std::map< state_t, label_map_t > successors_t
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Aut transpose(const transpose_automaton< Aut > &aut)
static constexpr wet_kind_t kind
The subset construction automaton from another.
auto determinize(const Aut &a, Tag={}, bool_constant< Lazy >={})
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
state_name_t finals_
Set of final states in the input automaton.
A mapping from strings to Values.
Tag to request the most appropriate version of an algorithm.
std::enable_if_t< std::is_same< weight_t_of< Aut >, bool >::value, Type > enable_if_boolean_t
Enable if Aut is over Booleans.
label_t_of< automaton_t > label_t
weight_t_of< automaton_t > weight_t
Request the unordered_map implementation.
enable_if_not_boolean_t< Aut, automaton > determinize_(const automaton &aut, const std::string &algo)
Weighted Bridge.
auto complete_(state_t src, const state_name_t &ss) -> std::enable_if_t< K==wet_kind_t::bitset >
Compute the outgoing transitions of this state.
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
std::unordered_map< label_t, state_name_t, vcsn::hash< labelset_t >, vcsn::equal_to< labelset_t >> label_map_t
successors[SOURCE-STATE][LABEL] = DEST-STATESET.
void operator()()
Determinize the automaton.
Aggregate an automaton, and forward calls to it.
enable_if_not_boolean_t< Aut, automaton > codeterminize_(const automaton &aut, const std::string &algo)
Weighted Bridge.
std::shared_ptr< detail::automaton_base > automaton
std::conditional_t< std::is_same< weight_t_of< Aut >, bool >::value, boolean_tag, weighted_tag > determinization_tag
The best tag depending on the type of Aut.
auto new_transition(Args &&...args) -> decltype(aut_-> new_transition(std::forward< Args >(args)...))
context_t_of< automaton_t > context_t
Labels and weights.
wet_kind_t
Different implementations of wets.
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
automaton determinize_tag_(const Aut &aut)
auto set_final(Args &&...args) -> decltype(aut_-> set_ final(std
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
ATTRIBUTE_PURE bool has(const boost::container::flat_set< Key, Compare, Allocator > &s, const Key &e)
Whether e is member of s.
auto complete_(state_t src, const state_name_t &ss) -> std::enable_if_t< K!=wet_kind_t::bitset >
Compute the outgoing transitions of this state.
Request the bitset implementation (bool weights).
auto final_transitions(const Aut &aut) -> decltype(aut->all_in(aut->post()))
Indexes of transitions from (visible) final states.
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
state_t_of< automaton_t > state_t
automaton codeterminize_tag_(const Aut &aut)
Request for the weighted version of an algorithm.
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
auto label_of(Args &&...args) const -> decltype(aut_-> label_of(std::forward< Args >(args)...))
determinized_automaton_impl(const automaton_t &a)
Build the determinizer.