5 #include <unordered_map>
6 #include <unordered_set>
10 #include <boost/lexical_cast.hpp>
11 #include <boost/heap/fibonacci_heap.hpp>
15 #include <vcsn/algos/fwd.hh>
36 template <
typename Aut,
37 bool has_one = labelset_t_of<Aut>::has_one()>
43 using weight_t =
typename weightset_t::value_t;
58 ,
ws_(*aut->weightset())
66 auto res = make_shared_ptr<aut_proper_t>(proper_ctx);
114 aut_->all_out(s).size());
121 for (
auto s:
aut_->states())
126 auto in =
aut_->in(s).size();
128 auto out =
aut_->all_out(s).size();
130 {s, in_sp, in, out_sp, out});
138 const char* sep =
"";
139 for (
auto i =
todo_.ordered_begin(), end =
todo_.ordered_end();
142 std::cerr << sep << *i;
153 std::cerr <<
"update heap (" << s <<
" : ";
158 todo_.update(i->second);
161 std::cerr <<
") => ";
163 std::cerr << std::endl;
200 using state_weight_t = std::pair<state_t, weight_t>;
201 std::vector<state_weight_t> closure;
202 for (
auto t : transitions)
207 star =
ws_.star(weight);
209 closure.emplace_back(src, weight);
211 aut_->del_transition(t);
228 for (
auto t:
aut_->all_out(s))
234 aut_->set_weight(t, blow);
238 for (
auto pair: closure)
242 aut_->add_transition(src, dst, label, w);
246 unsigned added =
aut_->all_out(s).size() * closure.size();
247 unsigned removed = transitions.size();
252 removed +=
aut_->all_out(s).size();
260 std::cerr <<
" -" << removed <<
"+" << added
261 <<
" (-" << removed_ <<
"+" << added_ <<
")";
287 std::unordered_set<state_t> neighbors;
288 while (!
todo_.empty())
292 std::cerr <<
"Before: ";
294 std::cerr << std::endl;
296 auto p =
todo_.top();
299 std::cerr <<
"Remove: " << p;
304 for (
auto t:
aut_->in(s))
308 neighbors.emplace(n);
310 for (
auto t:
aut_->out(s))
314 neighbors.emplace(n);
320 for (
auto n: neighbors)
322 for (
auto n: neighbors)
325 std::cerr <<
" #tr: "
327 <<
"/" <<
aut_->num_transitions() << std::endl;
330 std::cerr <<
"After: ";
332 std::cerr << std::endl;
335 dot(
aut_, std::cerr) << std::endl;
337 std::cerr << std::endl;
341 std::cerr <<
"Total transitions -" << removed_
342 <<
"+" << added_ << std::endl;
353 for (
auto t :
aut_->transitions())
354 res +=
aut_->labelset()->is_one(
aut_->label_of(t));
369 using heap_t = boost::heap::fibonacci_heap<epsilon_profile<state_t>>;
372 std::unordered_map<state_t, typename heap_t::handle_type>
handles_;
383 template <
typename Aut>
void show_heap_() const
Show the heap, for debugging.
boost::heap::fibonacci_heap< epsilon_profile< state_t >> heap_t
Max-heap to decide the order of state-elimination.
epsilon_remover(automaton_t &aut, bool=true)
std::vector< typename Cont::value_type > make_vector(const Cont &cont)
The content of cont as a vector.
static int debug_level()
Debug level set in the user's environment.
void update_heap_(state_t s)
Update the heap for s.
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
std::shared_ptr< const detail::label_base > label
labelset_t_of< automaton_t > labelset_t
fresh_automaton_t_of< automaton_t, detail::proper_context< context_t_of< automaton_t >>> aut_proper_t
state_t_of< automaton_t > state_t
typename weightset_t::value_t weight_t
std::unordered_map< state_t, typename heap_t::handle_type > handles_
Map: state -> heap-handle.
void in_situ_remover_()
Remove all the states with incoming spontaneous transitions.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
size_t num_spontaneous_transitions_() const
The number of spontaneous transitions in aut_.
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
This is used by some epsilon removal algorithms.
epsilon_profile< state_t > * profile(state_t s)
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
auto make_proper_context(const context< LabelSet, WeightSet > &ctx) -> proper_context< context< LabelSet, WeightSet >>
From a context, its non-nullable context.
AutOut copy(const AutIn &input, KeepState keep_state, KeepTrans keep_trans)
A copy of input keeping only its states that are accepted by keep_state.
bool prune_
Whether to prune states that become inaccessible.
std::shared_ptr< const detail::weight_base > weight
void build_heap_()
Build the profiles and the heap for states with incoming spontaneous transitions. ...
void copy_into(const AutIn &in, AutOut &out, KeepState keep_state, KeepTrans keep_trans)
Copy selected states and transitions of an automaton.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
label_t empty_word_
Shorthand to the empty word.
label_t_of< automaton_t > label_t
int debug_
Debug level. The higher, the more details are reported.
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
transition_t_of< automaton_t > transition_t
const weightset_t & ws_
Shorthand to the weightset.
pair_automaton< Aut > pair(const Aut &aut, bool keep_initials=false)
bool is_proper(const Aut &aut)
Test whether an automaton is proper.
std::ostream & dot(const Aut &aut, std::ostream &out, bool dot2tex=false)
aut_proper_t operator()()
void update_profile_(state_t s)
The core of the (backward) epsilon-removal.
epsilon_remover(automaton_t &aut, bool prune=true)
Get ready to eliminate spontaneous transitions.
automaton_t aut_
The automaton we work on.
fresh_automaton_t_of< automaton_t > aut_proper_t
aut_proper_t operator()()
This class contains the core of the proper algorithm.
weightset_t_of< automaton_t > weightset_t
void in_situ_remover_(state_t s)
For each state (s), for each incoming epsilon-transitions (t), if (t) is a loop, the star of its weig...