Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
thompson.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_THOMPSON_HH
2 # define VCSN_ALGOS_THOMPSON_HH
3 
5 # include <vcsn/core/rat/visitor.hh>
6 # include <vcsn/ctx/fwd.hh>
7 # include <vcsn/ctx/traits.hh>
8 # include <vcsn/dyn/automaton.hh>
9 # include <vcsn/dyn/ratexp.hh>
10 # include <vcsn/labelset/labelset.hh> // make_nullableset_context
11 # include <vcsn/misc/raise.hh>
12 
13 namespace vcsn
14 {
15  namespace rat
16  {
21  template <typename Aut,
22  typename RatExpSet>
24  : public RatExpSet::const_visitor
25  {
26  public:
27  using automaton_t = Aut;
28  using ratexpset_t = RatExpSet;
33 
34  using super_t = typename ratexpset_t::const_visitor;
35 
36  static_assert(labelset_t_of<Aut>::has_one(),
37  "thompson: requires nullable labels");
38 
39  constexpr static const char* me() { return "thompson"; }
40 
42  thompson_visitor(const context_t& ctx, const ratexpset_t& rs)
43  : rs_(rs)
45  {}
46 
48  : thompson_visitor(rs.context(), rs)
49  {}
50 
52  operator()(const typename ratexpset_t::value_t& v)
53  {
54  v->accept(*this);
55  res_->set_initial(initial_);
56  res_->set_final(final_);
57  return std::move(res_);
58  }
59 
60  private:
66 
68  {
69  initial_ = res_->new_state();
70  final_ = res_->new_state();
71  }
72 
74  {
75  initial_ = res_->new_state();
76  final_ = res_->new_state();
77  res_->new_transition(initial_, final_, epsilon_);
78  }
79 
81  {
82  initial_ = res_->new_state();
83  final_ = res_->new_state();
84  // The automaton and the expression might have different
85  // labelsets.
86  res_->new_transition(initial_, final_,
87  res_->labelset()->conv(*rs_.labelset(),
88  e.value()));
89  }
90 
92  {
93  state_t initial = res_->new_state();
94  state_t final = res_->new_state();
95  for (auto c: e)
96  {
97  c->accept(*this);
98  res_->new_transition(initial, initial_, epsilon_);
99  res_->new_transition(final_, final, epsilon_);
100  }
101  initial_ = initial;
102  final_ = final;
103  }
104 
106  {
107  e.head()->accept(*this);
108  state_t initial = initial_;
109 
110  // Then the remainder.
111  for (auto c: e.tail())
112  {
113  state_t final = final_;
114  c->accept(*this);
115  res_->new_transition(final, initial_, epsilon_);
116  }
117  initial_ = initial;
118  }
119 
121  {
122  e.sub()->accept(*this);
123  state_t initial = res_->new_state();
124  state_t final = res_->new_state();
125  res_->new_transition(initial, initial_, epsilon_);
126  res_->new_transition(final_, final, epsilon_);
127  res_->new_transition(final_, initial_, epsilon_);
128  res_->new_transition(initial, final, epsilon_);
129  initial_ = initial;
130  final_ = final;
131  }
132 
134  {
135  e.sub()->accept(*this);
136 
137  const weight_t& w = e.weight();
138  for (auto t: res_->out(initial_))
139  res_->set_weight(t, ws_.mul(w, res_->weight_of(t)));
140  }
141 
143  {
144  e.sub()->accept(*this);
145 
146  const weight_t& w = e.weight();
147  for (auto t: res_->in(final_))
148  res_->set_weight(t, ws_.mul(res_->weight_of(t), w));
149  }
150 
151  private:
152  const ratexpset_t& rs_;
153  const weightset_t& ws_ = *rs_.weightset();
156  const label_t epsilon_ = res_->labelset()->one();
157  state_t initial_ = automaton_t::element_type::null_state();
158  state_t final_ = automaton_t::element_type::null_state();
159  };
160 
161  } // rat::
162 
167  template <typename Aut,
168  typename RatExpSet>
169  Aut
171  const RatExpSet& rs, const typename RatExpSet::value_t& r)
172  {
174  return thompson(r);
175  }
176 
181  template <typename Aut,
182  typename RatExpSet>
183  Aut
184  thompson(const RatExpSet& rs, const typename RatExpSet::value_t& r)
185  {
187  return thompson(r);
188  }
189 
190  namespace dyn
191  {
192  namespace detail
193  {
194  /*---------------------.
195  | dyn::thompson(exp). |
196  `---------------------*/
197 
199  template <typename RatExpSet>
200  automaton
201  thompson(const ratexp& exp)
202  {
203  // FIXME: So far, there is a single implementation of ratexps,
204  // but we should actually be parameterized by its type too.
205  using ratexpset_t = RatExpSet;
206  const auto& e = exp->as<ratexpset_t>();
207  auto ctx
208  = vcsn::detail::make_nullableset_context(e.ratexpset().context());
209  using ctx_t = decltype(ctx);
210  using automaton_t = mutable_automaton<ctx_t>;
211  return make_automaton(::vcsn::thompson<automaton_t>(ctx,
212  e.ratexpset(),
213  e.ratexp()));
214  }
215 
217  (const ratexp& e) -> automaton);
218  }
219  }
220 
221 } // vcsn::
222 
223 #endif // !VCSN_ALGOS_THOMPSON_HH
weightset_t_of< ratexpset_t > weightset_t
Definition: thompson.hh:30
An inner node with multiple children.
Definition: fwd.hh:123
#define VCSN_RAT_UNSUPPORTED(Type)
Definition: visitor.hh:54
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
typename ratexpset_t::const_visitor super_t
Definition: thompson.hh:34
Aut thompson(const context_t_of< Aut > &ctx, const RatExpSet &rs, const typename RatExpSet::value_t &r)
Build a Thompson automaton from a ratexp.
Definition: thompson.hh:170
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
const weightset_t & ws_
Definition: thompson.hh:153
context_t_of< automaton_t > context_t
Definition: thompson.hh:29
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:77
static constexpr const char * me()
Definition: thompson.hh:39
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:25
std::shared_ptr< detail::ratexp_base > ratexp
Definition: fwd.hh:64
nullableset_context_t< context< LabelSet, WeightSet > > make_nullableset_context(const context< LabelSet, WeightSet > &ctx)
The nullableset context of a context.
Definition: labelset.hh:48
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:32
thompson_visitor(const context_t &ctx, const ratexpset_t &rs)
Build an automaton of context ctx.
Definition: thompson.hh:42
Build a Thompson automaton from a ratexp.
Definition: thompson.hh:23
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:33
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:38
weight_t_of< ratexpset_t > weight_t
Definition: thompson.hh:31
thompson_visitor(const ratexpset_t &rs)
Definition: thompson.hh:47
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:36
An inner node implementing a weight.
Definition: fwd.hh:145
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:37
automaton_t operator()(const typename ratexpset_t::value_t &v)
Definition: thompson.hh:52
label_t_of< automaton_t > label_t
Definition: thompson.hh:155
state_t_of< automaton_t > state_t
Definition: thompson.hh:32
const ratexpset_t & rs_
Definition: thompson.hh:152
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
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:15
automaton thompson(const ratexp &exp)
Bridge.
Definition: thompson.hh:201