25 template <Automaton Aut>
97 template <Automaton Aut>
111 , count_labels_{count_labels}
150 auto&
res = transition_cache_[t];
155 res = rat::make_info<expset_t>(
aut_->weight_of(t)).atom;
157 res = rat::size<expset_t>(
aut_->weight_of(t));
168 if (transition_cache_.size() <= t)
169 transition_cache_.resize(t + 1, 0);
170 transition_cache_[t] = 0;
184 size_t size_loop = 0;
187 size_loop += size_of_transition(t);
191 size_in += size_of_transition(t);
202 size_out += size_of_transition(t);
205 p.
size_ = (size_in * (outs - 1)
206 + size_out * (ins - 1)
207 + size_loop * (ins * outs - 1));
225 template <Automaton Aut,
typename Profiler>
239 , profiler_(profiler)
242 for (
auto s:
aut_->states())
243 handles_[s] = todo_.emplace(profiler_.make_state_profile(s));
249 if (s ==
aut_->null_state())
251 require(!todo_.empty(),
"no state left to remove");
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 <<
'\n';
272 eliminate_state_(p.state_);
280 std::cerr <<
"update heap: (";
283 for (
auto s: neighbors_)
284 if (s !=
aut_->pre() && s !=
aut_->post())
286 auto& h = handles_[s];
287 profiler_.update(*h);
291 std::cerr <<
") => ";
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
349 profiler_.invalidate_cache(t);
350 neighbors_.emplace(src);
351 neighbors_.emplace(dst);
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.lweight(
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
397 rs.mul(rs.lweight(
aut_->weight_of(
in),
aut_->label_of(
in)),
400 profiler_.invalidate_cache(t);
401 neighbors_.emplace(src);
402 neighbors_.emplace(dst);
418 std::vector<typename heap_t::handle_type>
handles_;
423 template <Automaton Aut,
typename Profiler>
427 return {a, 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();
495 typename ExpSet::value_t
502 return a->get_initial_weight(a->post());
504 catch (
const std::runtime_error& e)
506 raise(e,
" while making expression");
520 typename ExpSet::value_t
525 auto a =
lift(aut, ids);
531 raise(
"next_state: invalid algorithm: best");
535 auto profiler = delgado_t(a);
536 return to_expression<decltype(a), delgado_t, ExpSet>(a, profiler);
541 auto profiler = delgado_t(a,
true);
542 return to_expression<decltype(a), delgado_t, ExpSet>(a, profiler);
547 auto profiler = naive_t(a);
548 return to_expression<decltype(a), naive_t, ExpSet>(a, profiler);
556 typename ExpSet::value_t
562 typename ExpSet::value_t
best;
563 auto best_size = std::numeric_limits<size_t>::max();
568 auto r = to_expression_heuristic<Aut, ExpSet>(aut,
ids, a);
569 auto s = rat::size<ExpSet>(
r);
580 return to_expression_heuristic<Aut, ExpSet>(aut,
ids, algo);
586 typename ExpSet::value_t
588 const std::string& algo)
601 return to_expression<Aut, ExpSet>(a,
ids,
map[algo]);
613 template <Automaton Aut,
typename Identities,
typename String>
616 const std::string& algo)
618 const auto& a = aut->as<Aut>();
621 auto rs = expressionset_t{a->context(), ids};
637 template <
typename Context,
typename Identities,
typename Label>
642 const auto& c = ctx->as<Context>();
643 const auto& l = lbl->as<Label>();
645 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)");
668 template <
typename ExpSet>
671 std::true_type, std::false_type)
672 ->
typename ExpSet::value_t
678 template <
typename ExpSet>
681 std::false_type, std::false_type)
682 ->
typename ExpSet::value_t
684 auto ls = *rs.labelset();
686 using labelset_t = decltype(ls);
687 using letter_t =
typename labelset_t::letter_t;
689 auto ccs = std::set<std::pair<letter_t, letter_t>>{};
690 for (
const auto& cc: chars)
692 std::istringstream i1{cc.first};
693 std::istringstream i2{cc.second};
694 letter_t l1 = ls.get_letter(i1,
false);
695 letter_t l2 = ls.get_letter(i2,
false);
698 return rs.letter_class(ccs, accept);
711 template <
typename ExpressionSet>
712 typename ExpressionSet::value_t
717 using is_one_t = std::is_same<labelset_t, vcsn::oneset>;
720 is_one_t{}, is_expset_t{});
728 template <
typename Context,
typename Identities,
729 typename Letters,
typename Bool>
734 const auto& c = ctx->as<Context>();
std::unordered_set< state_t > neighbors_
std::vector< typename heap_t::handle_type > handles_
Map: state -> heap-handle.
weightset_mixin< detail::r_impl > r
std::shared_ptr< const node< Context > > expression
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
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::vector< size_t > transition_cache_
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)
typename detail::transition_t_of_impl< base_t< ValueSet > >::type transition_t_of
profiler_t & profiler_
The profiler we work with. Corresponding to a specific heuristic.
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
size_t states_size(const Aut &aut)
The largest state number, plus one.
void invalidate_cache(transition_t t)
Updating transitions' size in the cache during the profiler's construction would be clearer but appea...
state_profile make_state_profile(state_t state)
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.
std::vector< typename Cont::value_type > make_vector(const Cont &cont)
The content of cont as a vector.
state_t_of< automaton_t > state_t
state_profile(state_t state)
void update(state_profile &p)
The "weight" of a state, as defined by Delgado-Morais.
naive_profiler(const automaton_t &aut)
void operator()()
Eliminate all the states, in the order specified by next_state.
state_t_of< automaton_t > state_t
size_t size_of_transition(transition_t t)
The "weight" of a transition.
typename profiler_t::state_profile profile_t
friend std::ostream & operator<<(std::ostream &o, const state_profile &p)
auto all_in(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions entering state s.
transition_t_of< automaton_t > transition_t
state_eliminator< Aut, Profiler > make_state_eliminator(Aut &a, Profiler &profiler)
bool operator<(const state_profile &rhs) const
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
An expressionset can implement several different sets of identities on expressions.
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
Provide a variadic mul on top of a binary mul(), and one().
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
Case where labelset is an expressionset.
detail::lifted_automaton_t< Aut, Tapes... > lift(const Aut &a, vcsn::rat::identities ids={})
Lift some tapes of the transducer.
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.
std::integral_constant< bool, B > bool_constant
Eliminate states in an automaton.
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.
The state profile is the product of the number of (strictly) incoming transitions with the number of ...
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 ...
expression to_expression_class(const context &ctx, identities ids, const letter_class_t &letters, bool accept)
Bridge (to_expression).
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
void update(state_profile &p)
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
delgado_profiler(const automaton_t &aut, bool count_labels=false)
Build a generator of Delgado-Morais state profiles.
automaton_t aut_
The automaton we work on.
expression to_expression_label(const context &ctx, identities ids, const label &lbl)
Bridge (to_expression).
std::set< std::pair< std::string, std::string > > letter_class_t
A set of letter ranges.
detail::copier< AutIn, AutOut > make_copier(const AutIn &in, AutOut &out, bool safe=true)
Build an automaton copier.
state_t_of< automaton_t > state_t
state_profile(state_t state)
ExpSet::value_t to_expression(Aut &a, Profiler &profiler)
auto make_expressionset(const context< LabelSet, WeightSet > &ctx, rat::identities ids={}) -> expressionset< context< LabelSet, WeightSet >>
Shorthand to expressionset constructor.
vcsn::min_fibonacci_heap< profile_t > heap_t
Max-heap to decide the order of state-elimination.
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.
void show_heap_() const
Show the heap, for debugging.
size_t size_
Number of strictly incoming transitions, times the number of strictly outgoing transitions.
boost::heap::fibonacci_heap< Elt, detail::comparator_t< Elt > > min_fibonacci_heap
value_impl< detail::label_tag > label
bool operator<(const state_profile &rhs) const
to_expression_heuristic_t
A mapping from strings to Values.
Compute a state profile for state-elimination based on connectivity.
void invalidate_cache(transition_t)
state_eliminator(automaton_t &aut, profiler_t &profiler)
Prepare for state-elimination.
size_t transitions_size(const Aut &aut)
The largest transition number, plus one.
static identities ids(const driver &d)
Get the identities of the driver.
::vcsn::rat::identities identities
Sets of identities on expressions.
state_profile make_state_profile(state_t state)
ExpSet::value_t to_expression_heuristic(const Aut &aut, vcsn::rat::identities ids, to_expression_heuristic_t algo)
void require(Bool b, Args &&... args)
If b is not verified, raise an error with args as message.
Compute a state profile for state-elimination based on the Delgado-Morais heuristic.
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
Given an automaton type, the type of its copies.
#define BUILTIN_UNREACHABLE()
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 out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.