Vcsn  2.2
Be Rational
thompson.hh
Go to the documentation of this file.
1 #pragma once
2 
5 #include <vcsn/ctx/fwd.hh>
6 #include <vcsn/ctx/traits.hh>
7 #include <vcsn/dyn/automaton.hh>
8 #include <vcsn/dyn/expression.hh>
9 #include <vcsn/labelset/labelset.hh> // make_nullableset_context
10 #include <vcsn/misc/raise.hh>
11 
12 namespace vcsn
13 {
14  namespace rat
15  {
20  template <Automaton Aut,
21  typename ExpSet>
23  : public ExpSet::const_visitor
24  {
25  public:
26  using automaton_t = Aut;
27  using expressionset_t = ExpSet;
32 
33  using super_t = typename expressionset_t::const_visitor;
34 
35  static_assert(labelset_t_of<Aut>::has_one(),
36  "thompson: requires nullable labels");
37 
39  constexpr static const char* me() { return "thompson"; }
40 
43  : rs_(rs)
45  {}
46 
48  : thompson_visitor(rs.context(), rs)
49  {}
50 
52  operator()(const typename expressionset_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:
67  using tuple_t = typename super_t::tuple_t;
68  virtual void visit(const tuple_t&, std::true_type) override
69  {
70  raise(me(), ": tuple is not supported");
71  }
72 
74  {
75  initial_ = res_->new_state();
76  final_ = res_->new_state();
77  }
78 
80  {
81  initial_ = res_->new_state();
82  final_ = res_->new_state();
83  res_->new_transition(initial_, final_, epsilon_);
84  }
85 
87  {
88  initial_ = res_->new_state();
89  final_ = res_->new_state();
90  // The automaton and the expression might have different
91  // labelsets.
92  res_->new_transition(initial_, final_,
93  res_->labelset()->conv(*rs_.labelset(),
94  e.value()));
95  }
96 
98  {
99  state_t initial = res_->new_state();
100  state_t final = res_->new_state();
101  for (auto c: e)
102  {
103  c->accept(*this);
104  res_->new_transition(initial, initial_, epsilon_);
105  res_->new_transition(final_, final, epsilon_);
106  }
107  initial_ = initial;
108  final_ = final;
109  }
110 
112  {
113  e.head()->accept(*this);
114  state_t initial = initial_;
115 
116  // Then the remainder.
117  for (auto c: e.tail())
118  {
119  state_t final = final_;
120  c->accept(*this);
121  res_->new_transition(final, initial_, epsilon_);
122  }
123  initial_ = initial;
124  }
125 
127  {
128  e.sub()->accept(*this);
129  state_t initial = res_->new_state();
130  state_t final = res_->new_state();
131  res_->new_transition(initial, initial_, epsilon_);
132  res_->new_transition(final_, final, epsilon_);
133  res_->new_transition(final_, initial_, epsilon_);
134  res_->new_transition(initial, final, epsilon_);
135  initial_ = initial;
136  final_ = final;
137  }
138 
140  {
141  e.sub()->accept(*this);
142 
143  const weight_t& w = e.weight();
144  for (auto t: out(res_, initial_))
145  res_->set_weight(t, ws_.mul(w, res_->weight_of(t)));
146  }
147 
149  {
150  e.sub()->accept(*this);
151 
152  const weight_t& w = e.weight();
153  for (auto t: in(res_, final_))
154  res_->set_weight(t, ws_.mul(res_->weight_of(t), w));
155  }
156 
157  private:
159  const weightset_t& ws_ = *rs_.weightset();
162  const label_t epsilon_ = res_->labelset()->one();
163  state_t initial_ = automaton_t::element_type::null_state();
164  state_t final_ = automaton_t::element_type::null_state();
165  };
166 
167  } // rat::
168 
173  template <Automaton Aut, typename ExpSet>
174  inline
175  Aut
177  const ExpSet& rs, const typename ExpSet::value_t& r)
178  {
180  return thompson(r);
181  }
182 
187  template <Automaton Aut, typename ExpSet>
188  inline
189  Aut
190  thompson(const ExpSet& rs, const typename ExpSet::value_t& r)
191  {
193  return thompson(r);
194  }
195 
196  namespace dyn
197  {
198  namespace detail
199  {
200  /*---------------------.
201  | dyn::thompson(exp). |
202  `---------------------*/
203 
205  template <typename ExpSet>
206  inline
207  automaton
208  thompson(const expression& exp)
209  {
210  // FIXME: So far, there is a single implementation of expressions,
211  // but we should actually be parameterized by its type too.
212  using expressionset_t = ExpSet;
213  const auto& e = exp->as<expressionset_t>();
214  auto ctx
215  = vcsn::detail::make_nullableset_context(e.expressionset().context());
216  using ctx_t = decltype(ctx);
217  using automaton_t = mutable_automaton<ctx_t>;
218  return make_automaton(::vcsn::thompson<automaton_t>(ctx,
219  e.expressionset(),
220  e.expression()));
221  }
222  }
223  }
224 
225 } // vcsn::
#define VCSN_RAT_UNSUPPORTED(Type)
Definition: visitor.hh:68
const weightset_t & ws_
Definition: thompson.hh:159
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:75
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:59
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
Definition: fwd.hh:25
Definition: a-star.hh:8
STL namespace.
weightset_t_of< expressionset_t > weightset_t
Definition: thompson.hh:29
thompson_visitor(const context_t &ctx, const expressionset_t &rs)
Build an automaton of context ctx.
Definition: thompson.hh:42
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:55
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
weight_t_of< expressionset_t > weight_t
Definition: thompson.hh:30
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
An inner node with multiple children.
Definition: expression.hh:118
state_t_of< automaton_t > state_t
Definition: thompson.hh:31
Aut thompson(const context_t_of< Aut > &ctx, const ExpSet &rs, const typename ExpSet::value_t &r)
Build a Thompson automaton from an expression.
Definition: thompson.hh:176
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:58
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:56
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
Definition: automaton.hh:56
nullableset_context_t< context< LabelSet, WeightSet > > make_nullableset_context(const context< LabelSet, WeightSet > &ctx)
The nullableset context of a context.
Definition: labelset.hh:174
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
auto rs
Definition: lift.hh:151
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: thompson.hh:39
context_t_of< automaton_t > context_t
Definition: thompson.hh:28
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:53
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:54
typename super_t::tuple_t tuple_t
Definition: thompson.hh:67
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:82
An inner node implementing a weight.
Definition: expression.hh:264
Build a Thompson automaton from an expression.
Definition: thompson.hh:22
std::shared_ptr< detail::expression_base > expression
Definition: expression.hh:92
virtual void visit(const tuple_t &, std::true_type) override
Definition: thompson.hh:68
const expressionset_t & rs_
Definition: thompson.hh:158
typename expressionset_t::const_visitor super_t
Definition: thompson.hh:33
label_t_of< automaton_t > label_t
Definition: thompson.hh:161
#define Automaton
Definition: automaton.hh:24
thompson_visitor(const expressionset_t &rs)
Definition: thompson.hh:47
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
Definition: automaton.hh:105
automaton_t operator()(const typename expressionset_t::value_t &v)
Definition: thompson.hh:52
automaton thompson(const expression &exp)
Bridge.
Definition: thompson.hh:208