Vcsn  2.8
Be Rational
implicit-path.hh
Go to the documentation of this file.
1 #pragma once
2 
4 #include <vcsn/core/automaton.hh>
5 #include <vcsn/ctx/traits.hh>
6 #include <vcsn/misc/algorithm.hh>
7 
8 namespace vcsn
9 {
10  namespace detail
11  {
20  template <Automaton Aut>
22  {
23  using automaton_t = Aut;
28 
29  public:
30  static constexpr int null_parent_path = -1;
31 
32  implicit_path(const automaton_t& aut, transition_t sidetrack,
33  int parent_path, weight_t weight)
34  : aut_{aut}
35  , sidetrack_{sidetrack}
36  , parent_path_{parent_path}
37  , weight_{weight}
38  {}
39 
48  path_t
49  explicit_path(const std::vector<path_t>& ksp,
51  state_t src)
52  {
53  auto res = path_t(aut_);
54 
55  if (parent_path_ != null_parent_path)
56  {
57  auto& explicit_pref_path = ksp[parent_path_];
58  const auto& path = explicit_pref_path.get_path();
59 
60  // The index of the last transition of the path before the
61  // sidetrack. Using the last occurence of the sidetrack is necessary
62  // to avoid computing the same path each time in the case of loops.
63  // If the sidetrack appears twice and we rebuild our path after the
64  // first one then we lost the previous path.
65  auto i = std::find_if(path.rbegin(), path.rend(), [&] (auto curr) {
66  return aut_->dst_of(curr) == aut_->src_of(sidetrack_);
67  });
68  assert(i != path.rend());
69  // Make it forward iterator, but one iteration further (in
70  // the forward direction).
71  auto last = i.base();
72  for (auto i = path.begin(); i != last; ++i)
73  res.emplace_back(aut_->weight_of(*i), *i);
74  res.emplace_back(aut_->weight_of(sidetrack_), sidetrack_);
75  }
76 
77  auto s = parent_path_ == null_parent_path
78  ? src : aut_->dst_of(sidetrack_);
79 
80  const auto& ws = *aut_->weightset();
81  while (s != tree.get_root())
82  {
83  auto next = tree.get_parent_of(s);
84  if (s == aut_->null_state() || next == aut_->null_state())
85  return path_t(aut_);
86  auto weight = ws.rdivide(tree[s].get_weight(),
87  tree[next].get_weight());
88  auto t = find_transition(s, next);
89  assert(t != aut_->null_transition());
90  res.emplace_back(weight, t);
91  s = next;
92  }
93 
94  return res;
95  }
96 
100  {
101  // GCC 5 and 6 do not capture as const references
102  // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66735). So
103  // instead of `[&aut = *aut_, &ws = *aut_->weightset()]`
104  // we capture this.
105  return min_forward(detail::outin(aut_, src, dst),
106  [this] (auto t1, auto t2)
107  {
108  return aut_->weightset()->less
109  (aut_->weight_of(t1),
110  aut_->weight_of(t2));
111  });
112  }
113 
114  bool operator<(const implicit_path& other) const
115  {
116  return aut_->weightset()->less(weight_, other.weight_);
117  }
118 
119  const weight_t& get_weight() const
120  {
121  return weight_;
122  }
123 
125  {
126  return sidetrack_;
127  }
128 
129  private:
136  };
137  }
138 }
transition_t find_transition(state_t src, state_t dst) const
Find the lightest transition from src to dst.
typename detail::transition_t_of_impl< base_t< ValueSet > >::type transition_t_of
Definition: traits.hh:65
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
Definition: traits.hh:64
path_t explicit_path(const std::vector< path_t > &ksp, shortest_path_tree< automaton_t > &tree, state_t src)
Create the explicit representation of the implicit path.
Implicit Path representation.
transition_t get_sidetrack() const
Container::value_type min_forward(const Container &container, Comp comp)
Same as *std::max_element, but works with an input iterator, not just a forward iterator.
Definition: algorithm.hh:179
const weight_t & get_weight() const
const automaton_t & aut_
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.
Definition: automaton.hh:189
Explicit path representation.
Definition: path.hh:16
Definition: a-star.hh:8
int parent_path_
Parent path indexes in the results array.
static constexpr int null_parent_path
weight_t_of< automaton_t > weight_t
state_t get_parent_of(state_t s) const
path< automaton_t > path_t
transition_t_of< automaton_t > transition_t
typename detail::weight_t_of_impl< base_t< ValueSet > >::type weight_t_of
Definition: traits.hh:66
implicit_path(const automaton_t &aut, transition_t sidetrack, int parent_path, weight_t weight)
state_t_of< automaton_t > state_t
value_impl< detail::weight_tag > weight
Definition: fwd.hh:34
return res
Definition: multiply.hh:399
const path_t & get_path() const
Definition: path.hh:82
bool operator<(const implicit_path &other) const