5 #include <unordered_map> 6 #include <unordered_set> 12 #include <vcsn/algos/fwd.hh> 30 bool has_one = labelset_t_of<Aut>::has_one()>
31 class epsilon_remover_separate
35 using weight_t =
typename weightset_t::value_t;
58 ,
ws_(*aut->weightset())
67 auto proper_ctx = aut->context();
72 aut_dirty_ = make_shared_ptr<aut_dirty_t>(dirty_ctx);
73 aut_proper_ = make_shared_ptr<aut_proper_t>(proper_ctx);
80 pcopier([](state_t) {
return true; },
81 [&aut](transition_t t) {
82 return !aut->labelset()->is_one(aut->label_of(t));
85 dcopier([&aut](state_t s) {
86 return (!
in(aut, s, aut->labelset()->one()).empty()
87 || !
out(aut, s, aut->labelset()->one()).empty());
89 [&aut](transition_t t) {
90 return aut->labelset()->is_one(aut->label_of(t));
94 const auto& dorigins = dcopier.state_map();
95 const auto& porigins = pcopier.state_map();
96 for (
const auto& dp : dorigins)
98 const auto pp = porigins.find(dp.first);
99 assert(pp != porigins.end());
100 d2p_[dp.second] = pp->second;
101 p2d_[pp->second] = dp.second;
112 auto dirty_s =
p2d_[proper_s];
120 p->update(in_dirty, in_proper + in_dirty,
121 out_dirty, out_proper + out_dirty);
134 auto proper_s =
d2p_[s];
144 const char* sep =
"";
145 for (
auto i =
todo_.ordered_begin(), end =
todo_.ordered_end();
148 std::cerr << sep << *i;
159 std::cerr <<
"update heap (" << s <<
" : ";
164 todo_.update(i->second);
167 std::cerr <<
") => ";
204 using state_weight_t = std::pair<state_dirty_t, weight_t>;
205 auto closure = std::vector<state_weight_t>{};
217 star =
ws_.star(weight);
219 closure.emplace_back(src, weight);
247 for (
auto pair: closure)
249 auto src =
pair.first;
262 for (
auto pair: closure)
264 auto src =
pair.first;
289 std::cerr <<
" -" << removed <<
"+" << added
290 <<
" (-" << removed_ <<
"+" << added_ <<
")";
340 auto neighbors = std::unordered_set<state_proper_t>{};
341 while (!
todo_.empty())
345 std::cerr <<
"Before: ";
349 auto p =
todo_.top();
352 std::cerr <<
"Remove: " << p;
355 auto dirty_s =
p2d_[proper_s];
372 neighbors.emplace(
d2p_[n]);
375 neighbors.emplace(
d2p_[n]);
381 for (
auto n: neighbors)
383 for (
auto n: neighbors)
386 std::cerr <<
" #tr: " 393 std::cerr <<
"After: ";
407 std::cerr <<
"Total transitions -" << removed_
408 <<
"+" << added_ <<
'\n';
439 std::unordered_map<state_proper_t, typename heap_t::handle_type>
handles_;
445 std::vector<state_proper_t>
d2p_;
447 std::vector<state_dirty_t>
p2d_;
452 template <Automaton Aut>
std::shared_ptr< detail::mutable_automaton_impl< Context > > mutable_automaton
void remover_on(state_proper_t proper_s)
Wrapper around remover_on() which does a lookup of the dirty state.
void remover_on(state_proper_t proper_s, state_dirty_t dirty_s)
For each state (s), for each incoming epsilon-transitions (t), if (t) is a loop, the star of its weig...
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
bool prune_
Whether to prune states that become inaccessible.
epsilon_remover_separate(const automaton_t &aut, bool prune=true)
Get ready to eliminate spontaneous transitions.
aut_dirty_t aut_dirty_
The sponteanous part.
typename detail::transition_t_of_impl< base_t< ValueSet > >::type transition_t_of
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.
labelset_t_of< automaton_t > labelset_t
state_t_of< aut_dirty_t > state_dirty_t
std::vector< state_proper_t > d2p_
dirty states -> proper states.
profile_t * profile_(state_proper_t s) const
The profile of state s, or nullptr if it is not to be processed.
std::vector< typename Cont::value_type > make_vector(const Cont &cont)
The content of cont as a vector.
This class contains the core of the proper algorithm.
void build_heap_()
Build the profiles and the heap for states with incoming spontaneous transitions. ...
fresh_automaton_t_of< automaton_t > aut_proper_t
vcsn::min_fibonacci_heap< profile_t > heap_t
Min-heap to decide the order of state-elimination.
auto all_in(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions entering state s.
aut_proper_t get_proper()
Return the proper part. Needed by lazy algorithm.
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
const weightset_t & ws_
Shorthand to the weightset.
pair_automaton< Aut > pair(const Aut &aut, bool keep_initials=false)
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 ...
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
std::ostream & dot(const Aut &aut, std::ostream &out=std::cout, format fmt={}, bool mathjax=false)
Print an automaton in Graphviz's Dot format.
aut_proper_t operator()()
Remove all the states with incoming spontaneous transitions.
std::remove_cv_t< Aut > automaton_t
void update_profile_(state_proper_t proper_s)
Update the profile of s.
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
epsilon_remover_separate(const automaton_t &aut, bool)
mutable_automaton< dirty_ctx_t > aut_dirty_t
Spontaneous automaton.
void update_heap_(state_proper_t s)
Update the heap for s.
typename detail::label_t_of_impl< base_t< ValueSet > >::type label_t_of
This is used by some epsilon removal algorithms.
aut_proper_t operator()()
detail::copier< AutIn, AutOut > make_copier(const AutIn &in, AutOut &out, bool safe=true)
Build an automaton copier.
std::unordered_map< state_proper_t, typename heap_t::handle_type > handles_
Map: state -> heap-handle.
fresh_automaton_t_of< Aut, proper_ctx_t > aut_proper_t
Proper automaton.
void show_heap_() const
Show the heap, for debugging.
label_t_of< aut_proper_t > label_proper_t
weightset_t_of< automaton_t > weightset_t
boost::heap::fibonacci_heap< Elt, detail::comparator_t< Elt > > min_fibonacci_heap
value_impl< detail::label_tag > label
aut_proper_t get_proper()
typename weightset_t::value_t weight_t
int debug_
Debug level. The higher, the more details are reported.
std::vector< state_dirty_t > p2d_
proper states -> dirty states.
static int debug_level()
Debug level set in the user's environment.
auto transitions(const Aut &aut) -> decltype(all_transitions(aut, is_special_t< Aut >
All the transition indexes between visible states.
std::remove_cv_t< Aut > automaton_t
auto make_proper_context(const context< LabelSet, WeightSet > &ctx) -> proper_context< context< LabelSet, WeightSet >>
From a context, its non-nullable context.
bool state_has_spontaneous_in(state_proper_t proper_s) const
Whether the given state has incoming spontaneous transitions.
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
Given an automaton type, the type of its copies.
value_impl< detail::weight_tag > weight
state_t_of< aut_proper_t > state_proper_t
aut_proper_t aut_proper_
The proper part.
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.