3 #include <boost/heap/fibonacci_heap.hpp>
26 template <Automaton Aut>
98 template <Automaton Aut>
156 res = rat::make_info<expset_t>(
aut_->weight_of(t)).atom;
158 res = rat::size<expset_t>(
aut_->weight_of(t));
185 size_t size_loop = 0;
206 p.
size_ = (size_in * (outs - 1)
207 + size_out * (ins - 1)
208 + size_loop * (ins * outs - 1));
226 template <Automaton Aut,
typename Profiler>
243 for (
auto s:
aut_->states())
250 if (s ==
aut_->null_state())
253 auto p =
todo_.top();
258 require(
aut_->has_state(s),
"not a valid state: ", s);
265 while (!
todo_.empty())
267 auto p =
todo_.top();
271 std::cerr <<
"Remove: " << p <<
'\n';
281 std::cerr <<
"update heap: (";
285 if (s !=
aut_->pre() && s !=
aut_->post())
292 std::cerr <<
") => ";
301 const char* sep =
"";
302 for (
auto i =
todo_.ordered_begin(), end =
todo_.ordered_end();
305 std::cerr << sep << *i;
311 template <typename Kind = typename context_t_of<automaton_t>::kind_t>
313 -> std::enable_if_t<std::is_same<Kind, labels_are_one>::value,
319 const auto& ls = *
aut_->labelset();
322 const auto& ws = *
aut_->weightset();
325 auto loop = ws.zero();
331 loop = ws.add(loop,
aut_->weight_of(t));
332 aut_->del_transition(t);
334 loop = ws.star(loop);
341 auto src =
aut_->src_of(
in);
343 auto t =
aut_->add_transition
369 template <
typename Kind>
371 -> std::enable_if_t<std::is_same<Kind, labels_are_expressions>::value,
377 const auto&
rs = *
aut_->labelset();
380 auto loop =
rs.zero();
384 rs.lweight(
aut_->weight_of(t),
aut_->label_of(t)));
385 aut_->del_transition(t);
387 loop =
rs.star(loop);
394 auto src =
aut_->src_of(
in);
396 auto t =
aut_->add_transition
416 using heap_t = boost::heap::fibonacci_heap<profile_t>;
419 std::vector<typename heap_t::handle_type>
handles_;
424 template <Automaton Aut,
typename Profiler>
434 template <Automaton Aut>
447 template <Automaton Aut>
455 auto res = make_fresh_automaton<Aut>(aut);
458 if (s != aut->null_state())
460 require(aut->has_state(s),
"not a valid state: ", s);
461 s = copy.state_map().at(s);
476 template <Automaton Aut,
typename Int>
480 const auto& a = aut->
as<Aut>();
482 auto s = 0 <= state ? state_t(state + 2) : a->null_state();
495 typename ExpSet = expressionset<context_t_of<Aut>>>
496 typename ExpSet::value_t
503 return a->get_initial_weight(a->post());
505 catch (
const std::runtime_error& e)
507 raise(e,
" while making expression");
520 typename ExpSet = expressionset<context_t_of<Aut>>>
521 typename ExpSet::value_t
526 auto a =
lift(aut, ids);
532 raise(
"next_state: invalid algorithm: best");
536 auto profiler = delgado_t(a);
537 return to_expression<decltype(a), delgado_t, ExpSet>(a, profiler);
542 auto profiler = delgado_t(a,
true);
543 return to_expression<decltype(a), delgado_t, ExpSet>(a, profiler);
548 auto profiler = naive_t(a);
549 return to_expression<decltype(a), naive_t, ExpSet>(a, profiler);
556 typename ExpSet = expressionset<context_t_of<Aut>>>
557 typename ExpSet::value_t
563 typename ExpSet::value_t
best;
564 auto best_size = std::numeric_limits<size_t>::max();
569 auto r = to_expression_heuristic<Aut, ExpSet>(aut,
ids, a);
570 auto s = rat::size<ExpSet>(
r);
581 return to_expression_heuristic<Aut, ExpSet>(aut,
ids, algo);
586 typename ExpSet = expressionset<context_t_of<Aut>>>
587 typename ExpSet::value_t
589 const std::string& algo)
602 return to_expression<Aut, ExpSet>(a,
ids, map[algo]);
614 template <Automaton Aut,
typename Identities,
typename String>
617 const std::string& algo)
619 const auto& a = aut->
as<Aut>();
622 auto rs = expressionset_t{a->context(), ids};
638 template <
typename Context,
typename Identities,
typename Label>
643 const auto& c = ctx->
as<Context>();
644 const auto& l = lbl->
as<Label>();
646 return {
rs, rs.atom(l.value())};
658 template <
typename ExpSet>
661 std::false_type, std::true_type)
662 ->
typename ExpSet::value_t
664 raise(
"letter_class: not implemented (is_expressionset)");
667 template <
typename ExpSet>
670 std::false_type, std::false_type)
671 ->
typename ExpSet::value_t
673 auto ls = *
rs.labelset();
675 using labelset_t = decltype(ls);
676 using letter_t =
typename labelset_t::letter_t;
678 auto ccs = std::set<std::pair<letter_t, letter_t>>{};
679 for (
const auto& cc: chars)
681 std::istringstream i1{cc.first};
682 std::istringstream i2{cc.second};
683 letter_t l1 = ls.get_letter(i1,
false);
684 letter_t l2 = ls.get_letter(i2,
false);
687 return rs.letter_class(ccs, accept);
690 template <
typename ExpSet>
693 std::true_type, std::false_type)
694 ->
typename ExpSet::value_t
709 template <
typename ExpressionSet>
710 typename ExpressionSet::value_t
715 using is_one_t = std::is_same<labelset_t, vcsn::oneset>;
718 is_one_t{}, is_expset_t{});
726 template <
typename Context,
typename Identities,
727 typename Letters,
typename Bool>
732 const auto& c = ctx->
as<Context>();
state_profile make_state_profile(state_t state)
detail::lifted_automaton_t< Aut, Tapes... > lift(const Aut &a, vcsn::rat::identities ids={})
Lift some tapes of the transducer.
to_expression_heuristic_t
ExpSet::value_t to_expression_heuristic(const Aut &aut, vcsn::rat::identities ids, to_expression_heuristic_t algo)
std::unordered_set< state_t > neighbors_
naive_profiler(const automaton_t &aut)
state_eliminator< Aut, Profiler > make_state_eliminator(Aut &a, Profiler &profiler)
#define BUILTIN_UNREACHABLE()
std::remove_cv_t< Aut > automaton_t
delgado_profiler(const automaton_t &aut, bool count_labels=false)
Build a generator of Delgado-Morais state profiles.
std::vector< typename heap_t::handle_type > handles_
Map: state -> heap-handle.
The state profile is the product of the number of (strictly) incoming transitions with the number of ...
std::vector< typename Cont::value_type > make_vector(const Cont &cont)
The content of cont as a vector.
Compute a state profile for state-elimination based on connectivity.
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
state_t_of< automaton_t > state_t
transition_t_of< automaton_t > transition_t
void show_heap_() const
Show the heap, for debugging.
size_t size_of_transition(transition_t t)
The "weight" of a transition.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
size_t states_size(const Aut &aut)
The largest state number, plus one.
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
size_t size_
Number of strictly incoming transitions, times the number of strictly outgoing transitions.
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
std::vector< size_t > transition_cache_
automaton eliminate_state(const automaton &aut, int state)
Bridge.
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
size_t transitions_size(const Aut &aut)
The largest transition number, plus one.
auto & as()
Downcast to the exact type.
void update(state_profile &p)
The "weight" of a state, as defined by Delgado-Morais.
auto outin(const Aut &aut, state_t_of< Aut > s, state_t_of< Aut > d)
Indexes of visible transitions from state s to state d.
profiler_t & profiler_
The profiler we work with. Corresponding to a specific heuristic.
transition_t_of< automaton_t > transition_t
auto letter_class_impl(const ExpSet &, const letter_class_t &, bool, std::false_type, std::true_type) -> typename ExpSet::value_t
auto eliminate_state(const Aut &aut, state_t_of< Aut > s=Aut::element_type::null_state()) -> fresh_automaton_t_of< Aut >
A copy of automaton res without the state s.
expression to_expression(const automaton &aut, identities ids={}, const std::string &algo="auto")
An expression denoting the language of aut.
bool operator<(const state_profile &rhs) const
state_profile(state_t state)
bool operator<(const state_profile &rhs) const
void operator()()
Eliminate all the states, in the order specified by next_state.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
expression to_expression_class(const context &ctx, identities ids, const letter_class_t &letters, bool accept)
Bridge (to_expression).
void invalidate_cache(transition_t t)
Updating transitions' size in the cache during the profiler's construction would be clearer but appea...
Template-less root for contexts.
auto copy(const AutIn &input, KeepState keep_state, KeepTrans keep_trans) -> decltype(keep_state(input->null_state()), keep_trans(input->null_transition()), make_fresh_automaton< AutIn, AutOut >(input))
A copy of input keeping only its states that are accepted by keep_state, and transitions accepted by ...
state_t_of< automaton_t > state_t
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
Given an automaton type, the type of its copies.
friend std::ostream & operator<<(std::ostream &o, const state_profile &p)
An expressionset can implement several different sets of identities on expressions.
state_t_of< automaton_t > state_t
friend std::ostream & operator<<(std::ostream &o, const state_profile &p)
auto eliminate_state_(state_t s) -> std::enable_if_t< std::is_same< Kind, labels_are_one >::value, void >
Eliminate state s in the case of labels are one.
auto all_in(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions entering state s.
automaton_t aut_
The automaton we work on.
auto letter_class_impl(const ExpSet &rs, const letter_class_t &, bool, std::true_type, std::false_type) -> typename ExpSet::value_t
expression to_expression_label(const context &ctx, identities ids, const label &lbl)
Bridge (to_expression).
state_eliminator(automaton_t &aut, profiler_t &profiler)
Prepare for state-elimination.
detail::copier< AutIn, AutOut > make_copier(const AutIn &in, AutOut &out, bool safe=true)
Build an automaton copier.
Aut & eliminate_state_here(Aut &res, state_t_of< Aut > s=Aut::element_type::null_state())
In place removal of state s from automaton res.
expression to_expression(const automaton &aut, identities ids, const std::string &algo)
Bridge.
auto make_expressionset(const context< LabelSet, WeightSet > &ctx, rat::identities ids={}) -> expressionset< context< LabelSet, WeightSet >>
Shorthand to expressionset constructor.
Compute a state profile for state-elimination based on the Delgado-Morais heuristic.
auto eliminate_state_impl_(state_t s) -> std::enable_if_t< std::is_same< Kind, labels_are_expressions >::value, void >
Eliminate state s in the case of labels are expressions.
std::set< std::pair< std::string, std::string >> letter_class_t
A set of letter ranges.
void invalidate_cache(transition_t)
auto & as()
Extract wrapped typed value.
typename profiler_t::state_profile profile_t
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
state_profile make_state_profile(state_t state)
auto & as()
Extract wrapped typed automaton.
Eliminate states in an automaton.
A mapping from strings to Values.
static identities ids(const driver &d)
Get the identities of the driver.
void update(state_profile &p)
std::integral_constant< bool, B > bool_constant
ExpressionSet::value_t to_expression(const ExpressionSet &rs, const letter_class_t &letters, bool accept=true)
An expression matching one letter in a letter class.
Provide a variadic mul on top of a binary mul(), and one().
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
void operator()(state_t s)
Eliminate state s.
value_impl< detail::expression_tag > expression
ExpSet::value_t to_expression(Aut &a, Profiler &profiler)
weightset_mixin< detail::r_impl > r
boost::heap::fibonacci_heap< profile_t > heap_t
Max-heap to decide the order of state-elimination.
state_profile(state_t state)