1 #ifndef VCSN_ALGOS_DETERMINIZE_HH
2 # define VCSN_ALGOS_DETERMINIZE_HH
7 # include <type_traits>
35 template <
typename Aut>
40 "determinize: boolean: requires free labelset");
42 "determinize: boolean: requires Boolean weights");
72 for (
auto t :
input_->final_transitions())
81 std::string
vname(
bool full =
true)
const
83 return "determinized_automaton<" +
input_->vname(full) +
">";
93 auto i =
map_.find(ss);
94 if (i == std::end(
map_))
112 std::map<label_t, state_name_t, vcsn::less<labelset_t_of<Aut>>> ml;
113 while (!
todo_.empty())
115 auto ss = std::move(
todo_.top());
120 for (
auto s = ss.find_first(); s != ss.npos;
129 for (
auto t :
input_->out(s))
131 auto l =
input_->label_of(t);
132 if (j.find(l) == j.end())
134 j[l].set(
input_->dst_of(t));
139 for (
const auto& p : i->second)
141 auto j = ml.find(p.first);
143 ml[p.first] = p.second;
145 j->second |= p.second;
150 for (
const auto& e : ml)
164 const std::string& fmt =
"text",
165 bool delimit =
false)
const
174 const char* sep =
"";
175 for (
auto s: i->second)
178 input_->print_state_name(s, o, fmt,
true);
195 for (
const auto& p:
map_)
197 std::set<state_t> from;
198 const auto& ss = p.first;
199 for (
auto s = ss.find_first(); s != ss.npos;
202 origins_.emplace(p.second, std::move(from));
209 using map_t = std::unordered_map<state_name_t, state_t>;
221 using stack = std::stack<state_name_t>;
237 template <
typename Aut>
239 = std::shared_ptr<detail::determinized_automaton_impl<Aut>>;
241 template <
typename Aut>
247 auto res = make_shared_ptr<determinized_automaton<Aut>>(a);
253 template <
typename Aut>
271 template <
typename Aut>
276 "determinize: weighted: requires free labelset");
318 return aut_->print_state_name(s, out, format);
350 std::string
vname(
bool full =
true)
const
352 return "detweighted_automaton<" +
input_->vname(full) +
">";
362 while (!
todo_.empty())
364 auto ss = std::move(
todo_.front());
369 for (
const auto& p : ss)
373 for (
auto t :
input_->all_out(s))
375 auto l =
input_->label_of(t);
376 auto dst =
input_->dst_of(t);
377 auto w =
ws_.mul(v,
input_->weight_of(t));
382 dests.emplace(l,
ns_.zero());
384 ns_.add_here(d, dst, w);
388 for (
auto& d : dests)
389 if (!
ns_.is_zero(d.second))
407 const std::string& fmt =
"text")
const
413 ns_.print(i->second, o, fmt,
", ");
424 for (
const auto& p:
map_)
425 origins_.emplace(p.second, p.first);
437 auto i =
map_.find(name);
438 if (i == std::end(
map_))
465 using queue = std::queue<state_name_t>;
471 template <
typename Aut>
473 = std::shared_ptr<detail::detweighted_automaton_impl<Aut>>;
475 template <
typename Aut>
481 auto res = make_shared_ptr<detweighted_automaton<Aut>>(a);
486 template <
typename Aut>
503 template <
typename Aut,
typename Type>
505 =
typename std::enable_if<std::is_same<weightset_t_of<Aut>,
b>::value,
508 template <
typename Aut,
typename Type>
510 =
typename std::enable_if<!std::is_same<weightset_t_of<Aut>,
b>::value,
515 template <
typename Aut,
typename String>
519 const auto& a = aut->as<Aut>();
520 if (algo ==
"auto" || algo ==
"boolean")
522 else if (algo ==
"weighted")
525 raise(
"determinize: invalid algorithm: ",
str_escape(algo));
529 template <
typename Aut,
typename String>
530 if_not_boolean_t<Aut, automaton>
533 const auto& a = aut->as<Aut>();
534 if (algo ==
"boolean")
535 raise(
"determinize: cannot apply Boolean determinization");
536 else if (algo ==
"auto" || algo ==
"weighted")
539 raise(
"determinize: invalid algorithm: ",
str_escape(algo));
558 template <
typename Aut,
typename String>
559 if_boolean_t<Aut, automaton>
562 const auto& a = aut->as<Aut>();
563 if (algo ==
"auto" || algo ==
"boolean")
565 else if (algo ==
"weighted")
568 raise(
"codeterminize: invalid algorithm: ",
str_escape(algo));
572 template <
typename Aut,
typename String>
573 if_not_boolean_t<Aut, automaton>
576 const auto& a = aut->as<Aut>();
577 if (algo ==
"boolean")
578 raise(
"codeterminize: cannot apply Boolean determinization");
579 else if (algo ==
"auto" || algo ==
"weighted")
582 raise(
"codeterminize: invalid algorithm: ",
str_escape(algo));
592 #endif // !VCSN_ALGOS_DETERMINIZE_HH
static std::string sname()
if_boolean_t< Aut, automaton > determinize(const automaton &aut, const std::string &algo)
Boolean Bridge.
Linear combination of labels: map labels to weights.
std::shared_ptr< detail::determinized_automaton_impl< Aut >> determinized_automaton
A determinized automaton as a shared pointer.
std::map< state_t, state_name_t > origins_t
A map from determinized states to sets of original states.
auto codeterminize_weighted(const Aut &aut) -> decltype(transpose(determinize_weighted(transpose(aut))))
std::unordered_map< state_name_t, state_t, vcsn::hash< state_nameset_t >, vcsn::equal_to< state_nameset_t >> map_t
Map from state name to state number.
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
typename state_nameset_t::value_t state_name_t
auto codeterminize(const Aut &a) -> decltype(transpose(determinize(transpose(a))))
static size_t hash(state_t s)
label_t_of< automaton_t > label_t
std::shared_ptr< detail::detweighted_automaton_impl< Aut >> detweighted_automaton
A determinized automaton as a shared pointer.
const origins_t & origins() const
weightset_t ws_
Its weightset.
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.
labelset_t_of< automaton_t > labelset_t
label_t_of< automaton_t > label_t
detweighted_automaton_impl(const automaton_t &a)
Build the weighted determinizer.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
weight_t_of< automaton_t > weight_t
The weighted determinization of weighted automaton.
if_boolean_t< Aut, automaton > codeterminize(const automaton &aut, const std::string &algo)
Boolean Bridge.
size_t state_size_
We use state numbers as indexes, so we need to know the last state number.
typename Aut::element_type::automaton_nocv_t automaton_nocv_t
state_t_of< automaton_t > state_t
Result automaton state type.
state_name_t finals_
Set of final states in the input automaton.
automaton_t input_
Input automaton.
polynomialset< context< stateset, weightset_t >> state_nameset_t
boost::flyweight< std::string, boost::flyweights::no_tracking > symbol
An internalized string.
typename std::enable_if< std::is_same< weightset_t_of< Aut >, b >::value, Type >::type if_boolean_t
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
variadic_mul_mixin< detail::b_impl > b
dynamic_bitset state_name_t
The name: set of (input) states.
std::ostream & str_escape(std::ostream &os, const std::string &str)
Output a string, escaping special characters.
typename Aut::element_type::automaton_nocv_t automaton_nocv_t
std::map< state_t, label_map_t > successors_t
automaton_t input_
Input automaton.
auto new_state(Args &&...args) -> decltype(aut_-> new_state(std::forward< Args >(args)...))
std::size_t hash_value(const T &v)
labelset_t_of< automaton_t > labelset_t
void operator()()
The determinization of weighted automaton with the idea based on Mohri's algorithm.
std::string vname(bool full=true) const
state_t state_(const state_name_t &name)
The state for set of states ss.
Aggregate an automaton, and forward calls to it.
bool state_has_name(state_t s) const
weightset_t_of< automaton_t > weightset_t
std::ostream & print_state_name(state_t ss, std::ostream &o, const std::string &fmt="text") const
The subset construction automaton from another.
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.
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
state_nameset_t ns_
(Nameset) The polynomialset that stores weighted states.
void operator()()
Determinize all accessible states.
std::map< state_t, std::set< state_t >> origins_t
A map from determinized states to sets of original states.
const origins_t & origins() const
auto set_final(Args &&...args) -> decltype(aut_-> set_ final(std
An output state is a list of weighted input states.
static std::string sname()
typename std::enable_if<!std::is_same< weightset_t_of< Aut >, b >::value, Type >::type if_not_boolean_t
static bool equals(state_t l, state_t r)
auto determinize(const Aut &a) -> determinized_automaton< Aut >
stateset(const automaton_t &aut)
state_t state(const state_name_t &ss)
The state for set of states ss.
Provide a variadic mul on top of a binary mul(), and one().
std::unordered_map< state_name_t, state_t > map_t
Set of input states -> output state.
static bool less_than(state_t l, state_t r)
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Aut transpose(const transpose_automaton< Aut > &aut)
auto determinize_weighted(const Aut &a) -> detweighted_automaton< Aut >
std::queue< state_name_t > queue
The sets of (input) states waiting to be processed.
bool state_has_name(state_t s) const
boost::dynamic_bitset<> dynamic_bitset
determinized_automaton_impl(const automaton_t &a)
Build the determinizer.
static constexpr auto pre(Args &&...args) -> decltype(automaton_t::element_type::pre(std::forward< Args >(args)...))
std::ostream & print_state_name(state_t s, std::ostream &o, const std::string &fmt="text", bool delimit=false) const
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
state_t_of< automaton_t > state_t
auto new_transition(Args &&...args) -> decltype(aut_-> new_transition(std::forward< Args >(args)...))
auto print_state(Args &&...args) const -> decltype(aut_-> print_state(std::forward< Args >(args)...))
std::stack< state_name_t > stack
The sets of (input) states waiting to be processed.
variadic_mul_mixin< detail::r_impl > r
bool has(const std::map< Key, Value, Compare, Alloc > &s, const Key &e)
std::ostream & print(state_t s, std::ostream &out, symbol format=symbol{"text"}) const
std::string vname(bool full=true) const
static constexpr auto post(Args &&...args) -> decltype(automaton_t::element_type::post(std::forward< Args >(args)...))
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
auto out(Args &&...args) const -> decltype(aut_-> out(std::forward< Args >(args)...))