Vcsn  2.1
Be Rational
trie.hh
Go to the documentation of this file.
1 #pragma once
2 
5 #include <vcsn/labelset/labelset.hh> // detail::letterized_context
7 #include <vcsn/misc/algorithm.hh> // front
8 #include <vcsn/misc/direction.hh>
10 
11 #include <vcsn/dyn/automaton.hh>
12 #include <vcsn/dyn/context.hh>
13 #include <vcsn/dyn/polynomial.hh>
14 
15 namespace vcsn
16 {
17 
18  /*--------------------.
19  | trie(polynomial). |
20  `--------------------*/
21  namespace detail
22  {
29  template <typename Context, direction Dir>
31  {
32  public:
33  using context_t = Context;
37  using work_automaton_t
48  using monomial_t = typename polynomialset_t::monomial_t;
49 
52  {}
53 
57  void add(const word_t& l, const weight_t& w)
58  {
59  add_(l, w);
60  }
61 
63  void add(const monomial_t& m)
64  {
65  add(label_of(m), weight_of(m));
66  }
67 
69  void add(const polynomial_t& p)
70  {
71  for (const auto& m: p)
72  add(m);
73  }
74 
76  template <direction D = Dir>
77  auto result()
79  {
80  return res_;
81  }
82 
84  template <direction D = Dir>
85  auto result()
87  {
88  return transpose(res_);
89  }
90 
91  private:
97  void add_(const word_t& lbl, const weight_t& wgt)
98  {
99  const auto& ls = *ctx_.labelset();
100  state_t s = res_->pre();
101  s = next_(s, ls.special());
102  for (auto l: ls.letters_of_padded(Dir == direction::forward
103  ? lbl
104  : ls.transpose(lbl),
105  padding_))
106  s = next_(s, l);
107  // The final transition, where we add the weight.
108  res_->add_transition(s, res_->post(), ls.special(), wgt);
109  }
110 
114  {
115  auto ts = res_->out(s, l);
116  assert(ts.size() == 0 || ts.size() == 1);
117  if (ts.empty())
118  {
119  auto d = res_->new_state();
120  res_->new_transition(s, d, l);
121  return d;
122  }
123  else
124  return res_->dst_of(front(ts));
125  }
126 
130  const context_t& ctx_ = res_->context();
134  };
135 
137  template <direction Dir, typename PolynomialSet>
139  make_trie_builder(const PolynomialSet& ps)
140  {
142  auto ctx = make_free_context(ps.context());
143  return {ctx};
144  }
145  }
146 
152  template <typename PolynomialSet>
153  mutable_automaton<detail::free_context<context_t_of<PolynomialSet>>>
154  trie(const PolynomialSet& ps, const typename PolynomialSet::value_t& p)
155  {
156  auto t = detail::make_trie_builder<direction::forward>(ps);
157  t.add(p);
158  return t.result();
159  }
160 
166  template <typename PolynomialSet>
167  mutable_automaton<detail::free_context<context_t_of<PolynomialSet>>>
168  cotrie(const PolynomialSet& ps, const typename PolynomialSet::value_t& p)
169  {
170  auto t = detail::make_trie_builder<direction::backward>(ps);
171  t.add(p);
172  return t.result();
173  }
174 
175  namespace dyn
176  {
177  namespace detail
178  {
180  template <typename PolynomialSet>
181  automaton
182  trie(const polynomial& poly)
183  {
184  const auto& p = poly->as<PolynomialSet>();
185  return make_automaton(trie(p.polynomialset(), p.polynomial()));
186  }
187 
189  template <typename PolynomialSet>
190  automaton
191  cotrie(const polynomial& poly)
192  {
193  const auto& p = poly->as<PolynomialSet>();
194  return make_automaton(cotrie(p.polynomialset(), p.polynomial()));
195  }
196  }
197  }
198 
199  /*--------------.
200  | trie(file). |
201  `--------------*/
202 
208  template <typename PolynomialSet>
209  mutable_automaton<detail::free_context<context_t_of<PolynomialSet>>>
210  trie(const PolynomialSet& ps, std::istream& is)
211  {
212  auto t = detail::make_trie_builder<direction::forward>(ps);
213  while (auto m = ps.conv_monomial(is))
214  t.add(m.get());
215  return t.result();
216  }
217 
223  template <typename PolynomialSet>
224  mutable_automaton<detail::free_context<context_t_of<PolynomialSet>>>
225  cotrie(const PolynomialSet& ps, std::istream& is)
226  {
227  auto t = detail::make_trie_builder<direction::backward>(ps);
228  while (auto m = ps.conv_monomial(is))
229  t.add(m.get());
230  return t.result();
231  }
232 
233  namespace dyn
234  {
235  namespace detail
236  {
238  template <typename Context, typename Istream>
239  automaton
240  trie_stream(const context& ctx, std::istream& is)
241  {
242  const auto& c = ctx->as<Context>();
243  auto ps = make_word_polynomialset(c);
244  return make_automaton(trie(ps, is));
245  }
246 
248  template <typename Context, typename Istream>
249  automaton
250  cotrie_stream(const context& ctx, std::istream& is)
251  {
252  const auto& c = ctx->as<Context>();
253  auto ps = make_word_polynomialset(c);
254  return make_automaton(cotrie(ps, is));
255  }
256  }
257  }
258 } // vcsn::
automaton trie(const polynomial &poly)
Bridge.
Definition: trie.hh:182
work_automaton_t res_
The automaton being built.
Definition: trie.hh:128
Container::value_type front(const Container &container)
The first member of this Container.
Definition: algorithm.hh:57
Build a trie automaton (prefix-tree-like automaton).
Definition: trie.hh:30
state_t_of< automaton_t > state_t
Definition: trie.hh:45
std::shared_ptr< const detail::context_base > context
A dyn::context.
Definition: fwd.hh:41
auto label_of(const welement< Label, Weight > &m) -> decltype(m.label())
Definition: wet.hh:125
weight_t_of< context_t > weight_t
Definition: trie.hh:44
void add(const word_t &l, const weight_t &w)
Add a monomial.
Definition: trie.hh:57
std::istringstream is
The input stream: the specification to translate.
Definition: translate.cc:372
typename polynomialset_t::value_t polynomial_t
Definition: trie.hh:47
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:48
auto result() -> enable_if_t< D==direction::forward, automaton_t >
Get the result for the forward trie.
Definition: trie.hh:77
typename std::enable_if< Cond, T >::type enable_if_t
Definition: type_traits.hh:16
void add(const monomial_t &m)
Add a monomial.
Definition: trie.hh:63
typename polynomialset_t::monomial_t monomial_t
Definition: trie.hh:48
typename labelset_t_of< base_t< ValueSet >>::letter_t letter_t_of
Definition: traits.hh:61
auto result() -> enable_if_t< D==direction::backward, automaton_t >
Get the result for a backward trie.
Definition: trie.hh:85
SharedPtr make_shared_ptr(Args &&...args)
Same as std::make_shared, but parameterized by the shared_ptr type, not the (pointed to) element_type...
Definition: memory.hh:14
Aut transpose(const transpose_automaton< Aut > &aut)
Definition: transpose.hh:235
automaton cotrie(const polynomial &poly)
Bridge.
Definition: trie.hh:191
automaton cotrie_stream(const context &ctx, std::istream &is)
Bridge (cotrie).
Definition: trie.hh:250
typename labelset_t_of< base_t< ValueSet >>::word_t word_t_of
Definition: traits.hh:65
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:75
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:80
letter_t_of< context_t > letter_t
Definition: trie.hh:42
automaton trie_stream(const context &ctx, std::istream &is)
Bridge (trie).
Definition: trie.hh:240
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
std::shared_ptr< detail::transpose_automaton_impl< Aut >> transpose_automaton
An automaton wrapper that presents the transposed automaton.
Definition: fwd.hh:100
auto make_word_polynomialset(const Ctx &ctx) -> word_polynomialset_t< Ctx >
The polynomialset of words of a labelset (not necessarily on words itself).
trie_builder(const context_t &c)
Definition: trie.hh:50
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:47
auto weight_of(const welement< Label, Weight > &m) -> decltype(m.weight())
Definition: wet.hh:132
mutable_automaton< detail::free_context< context_t_of< PolynomialSet > > > trie(const PolynomialSet &ps, const typename PolynomialSet::value_t &p)
Make a trie-like mutable_automaton for a finite series given as a polynomial.
Definition: trie.hh:154
free_context< context< LabelSet, WeightSet > > make_free_context(const context< LabelSet, WeightSet > &c)
The free context for c.
Definition: labelset.hh:237
std::shared_ptr< const detail::polynomial_base > polynomial
Definition: fwd.hh:68
Looking downstream.
conditional_t< Dir==direction::forward, automaton_t, transpose_automaton< automaton_t >> work_automaton_t
The type of the automaton we work on.
Definition: trie.hh:40
labelset_t_of< context_t > labelset_t
Definition: trie.hh:41
state_t next_(state_t s, letter_t l)
Follow a transition, possibly creating it.
Definition: trie.hh:113
word_t_of< context_t > word_t
Definition: trie.hh:43
mutable_automaton< detail::free_context< context_t_of< PolynomialSet > > > cotrie(const PolynomialSet &ps, const typename PolynomialSet::value_t &p)
Make a cotrie-like mutable_automaton for a finite series given as a polynomial.
Definition: trie.hh:168
trie_builder< free_context< context_t_of< PolynomialSet > >, Dir > make_trie_builder(const PolynomialSet &ps)
Instantiate a trie-builder for this type of polynomialset.
Definition: trie.hh:139
const context_t & ctx_
The context of the automaton: letterized.
Definition: trie.hh:130
void add_(const word_t &lbl, const weight_t &wgt)
Add a monomial.
Definition: trie.hh:97
letterized_t< labelset_t >::value_t padding_
Padding, in case it is needed.
Definition: trie.hh:133
constant< type_t::one, Context > one
Definition: fwd.hh:111
typename letterized_traits< LabelSet >::labelset_t letterized_t
Definition: labelset.hh:94
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:24
mutable_automaton< context_t > automaton_t
The type of the result.
Definition: trie.hh:35
typename std::conditional< B, T, U >::type conditional_t
Definition: type_traits.hh:13
void add(const polynomial_t &p)
Add a polynomial.
Definition: trie.hh:69
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:50