3 #include <boost/heap/fibonacci_heap.hpp>
25 template <Automaton Aut>
97 template <Automaton Aut>
155 res = rat::make_info<expset_t>(
aut_->weight_of(t)).atom;
157 res = rat::size<expset_t>(
aut_->weight_of(t));
184 size_t size_loop = 0;
205 p.
size_ = (size_in * (outs - 1)
206 + size_out * (ins - 1)
207 + size_loop * (ins * outs - 1));
225 template <Automaton Aut,
typename Profiler>
242 for (
auto s:
aut_->states())
249 if (s ==
aut_->null_state())
252 auto p =
todo_.top();
257 require(
aut_->has_state(s),
"not a valid state: ", s);
264 while (!
todo_.empty())
266 auto p =
todo_.top();
270 std::cerr <<
"Remove: " << p << std::endl;
280 std::cerr <<
"update heap: (";
284 if (s !=
aut_->pre() && s !=
aut_->post())
291 std::cerr <<
") => ";
293 std::cerr << std::endl;
300 const char* sep =
"";
301 for (
auto i =
todo_.ordered_begin(), end =
todo_.ordered_end();
304 std::cerr << sep << *i;
310 template <typename Kind = typename context_t_of<automaton_t>::kind_t>
312 -> std::enable_if_t<std::is_same<Kind, labels_are_one>::value,
318 const auto& ls = *
aut_->labelset();
321 const auto& ws = *
aut_->weightset();
324 auto loop = ws.zero();
330 loop = ws.add(loop,
aut_->weight_of(t));
331 aut_->del_transition(t);
333 loop = ws.star(loop);
340 auto src =
aut_->src_of(
in);
342 auto t =
aut_->add_transition
368 template <
typename Kind>
370 -> std::enable_if_t<std::is_same<Kind, labels_are_expressions>::value,
376 const auto&
rs = *
aut_->labelset();
379 auto loop =
rs.zero();
383 rs.lmul(
aut_->weight_of(t),
aut_->label_of(t)));
384 aut_->del_transition(t);
386 loop =
rs.star(loop);
393 auto src =
aut_->src_of(
in);
395 auto t =
aut_->add_transition
415 using heap_t = boost::heap::fibonacci_heap<profile_t>;
418 std::vector<typename heap_t::handle_type>
handles_;
423 template <Automaton Aut,
typename Profiler>
433 template <Automaton Aut>
446 template <Automaton Aut>
454 auto res = make_fresh_automaton<Aut>(aut);
457 if (s != aut->null_state())
459 require(aut->has_state(s),
"not a valid state: ", s);
460 s = copy.state_map().at(s);
475 template <Automaton Aut,
typename Int>
479 const auto& a = aut->as<Aut>();
481 auto s = 0 <= state ? state_t(state + 2) : a->null_state();
494 typename ExpSet = expressionset<context_t_of<Aut>>>
495 typename ExpSet::value_t
500 return a->get_initial_weight(a->post());
512 typename ExpSet = expressionset<context_t_of<Aut>>>
513 typename ExpSet::value_t
518 auto a =
lift(aut, ids);
524 raise(
"next_state: invalid algorithm: best");
528 auto profiler = delgado_t(a);
529 return to_expression<decltype(a), delgado_t, ExpSet>(a, profiler);
534 auto profiler = delgado_t(a,
true);
535 return to_expression<decltype(a), delgado_t, ExpSet>(a, profiler);
540 auto profiler = naive_t(a);
541 return to_expression<decltype(a), naive_t, ExpSet>(a, profiler);
548 typename ExpSet = expressionset<context_t_of<Aut>>>
549 typename ExpSet::value_t
555 typename ExpSet::value_t
best;
556 auto best_size = std::numeric_limits<size_t>::max();
561 auto r = to_expression_heuristic<Aut, ExpSet>(aut,
ids, a);
562 auto s = rat::size<ExpSet>(
r);
573 return to_expression_heuristic<Aut, ExpSet>(aut,
ids, algo);
578 typename ExpSet = expressionset<context_t_of<Aut>>>
579 typename ExpSet::value_t
581 const std::string& algo)
594 return to_expression<Aut, ExpSet>(a,
ids, map[algo]);
606 template <Automaton Aut,
typename Identities,
typename String>
609 const std::string& algo)
611 const auto& a = aut->as<Aut>();
614 auto rs = expressionset_t{a->context(), ids};
630 template <
typename Context,
typename Identities,
typename Label>
635 const auto& c = ctx->as<Context>();
636 const auto& l = lbl->as<Label>();
650 template <
typename ExpSet>
653 std::false_type, std::true_type)
654 ->
typename ExpSet::value_t
656 raise(
"letter_class: not implemented (is_expressionset)");
659 template <
typename ExpSet>
662 std::false_type, std::false_type)
663 ->
typename ExpSet::value_t
665 auto ls = *
rs.labelset();
667 using labelset_t = decltype(ls);
668 using letter_t =
typename labelset_t::letter_t;
670 auto ccs = std::set<std::pair<letter_t, letter_t>>{};
671 for (
const auto& cc: chars)
673 std::istringstream i1{cc.first};
674 std::istringstream i2{cc.second};
675 letter_t l1 = ls.get_letter(i1,
false);
676 letter_t l2 = ls.get_letter(i2,
false);
679 return rs.letter_class(ccs, accept);
682 template <
typename ExpSet>
685 std::true_type, std::false_type)
686 ->
typename ExpSet::value_t
701 template <
typename ExpressionSet>
702 typename ExpressionSet::value_t
707 using is_one_t = std::is_same<labelset_t, vcsn::oneset>;
710 is_one_t{}, is_expset_t{});
718 template <
typename Context,
typename Identities,
719 typename Letters,
typename Bool>
724 const auto& c = ctx->as<Context>();
std::vector< typename heap_t::handle_type > handles_
Map: state -> heap-handle.
std::integral_constant< bool, B > bool_constant
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
size_t size_of_transition(transition_t t)
The "weight" of a transition.
Container::value_type back(const Container &container)
The last member of this Container.
transition_t_of< automaton_t > transition_t
state_profile(state_t state)
automaton eliminate_state(const automaton &aut, int state)
Bridge.
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
ExpSet::value_t to_expression_heuristic(const Aut &aut, vcsn::rat::identities ids, to_expression_heuristic_t algo)
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
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.
An expressionset can implement several different sets of identities on expressions.
state_eliminator< Aut, Profiler > make_state_eliminator(Aut &a, Profiler &profiler)
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.
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
bool operator<(const state_profile &rhs) const
auto all_in(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions entering state s.
std::set< std::pair< std::string, std::string >> letter_class_t
A set of letter ranges.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
boost::heap::fibonacci_heap< profile_t > heap_t
Max-heap to decide the order of state-elimination.
weightset_mixin< detail::r_impl > r
Provide a variadic mul on top of a binary mul(), and one().
void operator()()
Eliminate all the states, in the order specified by next_state.
state_profile make_state_profile(state_t state)
to_expression_heuristic_t
expression to_expression(const automaton &aut, vcsn::rat::identities ids, const std::string &algo)
Bridge.
void invalidate_cache(transition_t)
state_t_of< automaton_t > state_t
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
#define BUILTIN_UNREACHABLE()
std::shared_ptr< const detail::label_base > label
void show_heap_() const
Show the heap, for debugging.
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
A mapping from strings to Values.
state_profile make_state_profile(state_t state)
friend std::ostream & operator<<(std::ostream &o, const state_profile &p)
naive_profiler(const automaton_t &aut)
std::vector< size_t > transition_cache_
auto letter_class_impl(const ExpSet &, const letter_class_t &, bool, std::false_type, std::true_type) -> typename ExpSet::value_t
ExpSet::value_t to_expression(Aut &a, Profiler &profiler)
std::shared_ptr< const detail::context_base > context
A dyn::context.
std::vector< typename Cont::value_type > make_vector(const Cont &cont)
The content of cont as a vector.
std::unordered_set< state_t > neighbors_
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
Given an automaton type, the type of its copies.
std::shared_ptr< detail::automaton_base > automaton
automaton_t aut_
The automaton we work on.
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
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.
void invalidate_cache(transition_t t)
Updating transitions' size in the cache during the profiler's construction would be clearer but appea...
bool operator<(const state_profile &rhs) const
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.
expression to_expression_class(const context &ctx, rat::identities ids, const letter_class_t &letters, bool accept)
Bridge (to_expression).
void update(state_profile &p)
The "weight" of a state, as defined by Delgado-Morais.
expressionset< Context > make_expressionset(const Context &ctx, rat::identities identities={})
Shorthand to expressionset constructor.
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
The state profile is the product of the number of (strictly) incoming transitions with the number of ...
state_t_of< automaton_t > state_t
Eliminate states in an automaton.
expression to_expression_label(const context &ctx, rat::identities ids, const label &lbl)
Bridge (to_expression).
static dyn::context ctx(const driver &d)
Get the context of the driver.
delgado_profiler(const automaton_t &aut, bool count_labels=false)
Build a generator of Delgado-Morais state profiles.
void update(state_profile &p)
state_t_of< automaton_t > state_t
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.
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.
typename profiler_t::state_profile profile_t
profiler_t & profiler_
The profiler we work with. Corresponding to a specific heuristic.
std::shared_ptr< detail::expression_base > expression
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.
Compute a state profile for state-elimination based on connectivity.
static identities ids(const driver &d)
Get the identities of the driver.
size_t size_
Number of strictly incoming transitions, times the number of strictly outgoing transitions.
auto all_transitions(const Aut &aut)
All the transition indexes between all states (including pre and post).
void operator()(state_t s)
Eliminate state s.
friend std::ostream & operator<<(std::ostream &o, const state_profile &p)
std::remove_cv_t< Aut > automaton_t
size_t size(const ExpSet &rs, const typename ExpSet::value_t &r)
detail::lifted_automaton_t< Aut, Tapes... > lift(const Aut &a, vcsn::rat::identities ids={})
Lift some tapes of the transducer.
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
expression make_expression(const ExpSet &rs, const typename ExpSet::value_t &r)
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_profile(state_t state)
transition_t_of< automaton_t > transition_t