Vcsn  2.1
Be Rational
epsilon-remover-distance.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <stdexcept>
4 #include <type_traits>
5 #include <utility>
6 #include <vector>
7 
8 #include <vcsn/algos/copy.hh>
9 #include <vcsn/algos/distance.hh>
10 
11 namespace vcsn
12 {
13  namespace detail
14  {
19  template <typename Aut,
20  bool has_one = labelset_t_of<Aut>::has_one()>
22  {
26  using weight_t = typename weightset_t::value_t;
29  using transitions_t = std::vector<transition_t>;
30 
33 
36 
38 
39  public:
40  epsilon_remover_distance(const automaton_t& aut, bool prune = true)
41  : ws_(*aut->weightset())
42  , prune_(prune)
43  , d2p_(aut->all_states().back() + 1, aut->null_state())
44  , p2d_(aut->all_states().back() + 1, aut->null_state())
45  {
46  auto dirty_ctx = dirty_ctx_t{{}, ws_};
47  auto proper_ctx = make_proper_context(aut->context());
48  aut_dirty_ = make_shared_ptr<aut_dirty_t>(dirty_ctx);
49  aut_proper_ = make_shared_ptr<aut_proper_t>(proper_ctx);
50 
51  auto pcopier = make_copier(aut, aut_proper_);
52  auto dcopier = make_copier(aut, aut_dirty_);
53 
54  pcopier([](state_t) { return true; },
55  [&aut](transition_t t) {
56  return !aut->labelset()->is_one(aut->label_of(t));
57  }
58  );
59  dcopier([&aut](state_t s) {
60  return (!aut->in(s, aut->labelset()->one()).empty()
61  || !aut->out(s, aut->labelset()->one()).empty());
62  },
63  [&aut](transition_t t) {
64  return aut->labelset()->is_one(aut->label_of(t));
65  }
66  );
67 
68  const auto& dorigins = dcopier.state_map();
69  const auto& porigins = pcopier.state_map();
70  for (const auto& dp : dorigins)
71  {
72  auto pp = porigins.find(dp.first);
73  assert(pp != porigins.end());
74  d2p_[dp.second] = pp->second;
75  p2d_[pp->second] = dp.second;
76  }
77 
78  de_ = all_distances(aut_dirty_);
79  }
80 
81  public:
82 
84  {
85  for (auto proper_p : aut_proper_->states())
86  {
87  state_t dirty_p = p2d_[proper_p];
88  for (state_t dirty_q = 0; dirty_q < de_[dirty_p].size(); dirty_q++)
89  {
90  weight_t dist_pq = de_[dirty_p][dirty_q];
91  state_t proper_q = d2p_[dirty_q];
92  for (auto t : aut_proper_->all_out(proper_q))
93  {
94  state_t proper_r = aut_proper_->dst_of(t);
95  label_proper_t l = aut_proper_->label_of(t);
96  weight_t w = aut_proper_->weight_of(t);
97  aut_proper_->add_transition(proper_p, proper_r, l,
98  ws_.mul(w, dist_pq));
99  }
100  }
101  }
102  if (prune_)
103  for (auto s : aut_proper_->states())
104  if (aut_proper_->all_in(s).empty())
105  aut_proper_->del_state(s);
106  return aut_proper_;
107  }
108 
109  private:
113 
115  const weightset_t& ws_;
116 
118  bool prune_;
119 
120  std::vector<state_t> d2p_; // dirty states -> proper states
121  std::vector<state_t> p2d_; // proper states -> dirty states
122 
123  std::vector<std::vector<weight_t>> de_;
124  };
125 
126  template <typename Aut>
127  class epsilon_remover_distance<Aut, false>
128  {
131  public:
133  : aut_(aut)
134  {}
135 
137  {
138  return copy(aut_);
139  }
140 
141  private:
143  };
144  }
145 } // namespace vcsn
std::vector< std::vector< weight_t_of< Aut > > > all_distances(const Aut &aut)
Definition: distance.hh:281
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:46
std::vector< std::vector< weight_t > > de_
fresh_automaton_t_of< Aut, proper_ctx_t > aut_proper_t
Container::value_type back(const Container &container)
The last member of this Container.
Definition: algorithm.hh:26
detail::copier< AutIn, AutOut > make_copier(const AutIn &in, AutOut &out)
Build an automaton copier.
Definition: copy.hh:116
std::string type(const automaton &a)
The implementation type of a.
Definition: others.cc:197
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:48
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:51
aut_proper_t aut_proper_
The automata we work on.
mutable_automaton< dirty_ctx_t > aut_dirty_t
bool prune_
Whether to prune states that become inaccessible.
This class contains the core of the proper algorithm.
typename Aut::element_type::template fresh_automaton_t< Context > fresh_automaton_t_of
Definition: traits.hh:57
auto make_proper_context(const context< LabelSet, WeightSet > &ctx) -> proper_context< context< LabelSet, WeightSet >>
From a context, its non-nullable context.
Definition: labelset.hh:218
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.
Definition: copy.hh:254
epsilon_remover_distance(const automaton_t &aut, bool prune=true)
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:47
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:49
typename std::remove_cv< Aut >::type automaton_t
transition_t_of< automaton_t > transition_t
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:24
const weightset_t & ws_
Shorthand to the weightset.