Vcsn  2.8
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/value.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;
28  using expression_t = typename expressionset_t::value_t;
33 
34  using super_t = typename expressionset_t::const_visitor;
35 
36  static_assert(labelset_t_of<Aut>::has_one(),
37  "thompson: requires nullable labels");
38 
40  constexpr static const char* me() { return "thompson"; }
41 
44  : rs_(rs)
46  {}
47 
49  : thompson_visitor(rs.context(), rs)
50  {}
51 
54  {
55  try
56  {
57  v->accept(*this);
58  res_->set_initial(initial_);
59  res_->set_final(final_);
60  return std::move(res_);
61  }
62  catch (const std::runtime_error& e)
63  {
64  raise(e,
65  " while computing thompson automaton of: ",
66  to_string(rs_, v));
67  }
68  }
69 
70  private:
78  using tuple_t = typename super_t::tuple_t;
79  void visit(const tuple_t&, std::true_type) override
80  {
81  raise(me(), ": tuple is not supported");
82  }
83 
85  {
86  initial_ = res_->new_state();
87  final_ = res_->new_state();
88  }
89 
91  {
92  initial_ = res_->new_state();
93  final_ = res_->new_state();
94  res_->new_transition(initial_, final_, epsilon_);
95  }
96 
98  {
99  super_t::visit(e);
100  }
101 
103  {
104  initial_ = res_->new_state();
105  final_ = res_->new_state();
106  // The automaton and the expression might have different
107  // labelsets.
108  res_->new_transition(initial_, final_,
109  res_->labelset()->conv(*rs_.labelset(),
110  e.value()));
111  }
112 
114  {
115  state_t initial = res_->new_state();
116  state_t final = res_->new_state();
117  for (const auto& c: e)
118  {
119  c->accept(*this);
120  res_->new_transition(initial, initial_, epsilon_);
121  res_->new_transition(final_, final, epsilon_);
122  }
123  initial_ = initial;
124  final_ = final;
125  }
126 
128  {
129  e.head()->accept(*this);
130  state_t initial = initial_;
131 
132  // Then the remainder.
133  for (const auto& c: e.tail())
134  {
135  state_t final = final_;
136  c->accept(*this);
137  res_->new_transition(final, initial_, epsilon_);
138  }
139  initial_ = initial;
140  }
141 
143  {
144  e.sub()->accept(*this);
145  state_t initial = res_->new_state();
146  state_t final = res_->new_state();
147  res_->new_transition(initial, initial_, epsilon_);
148  res_->new_transition(final_, final, epsilon_);
149  res_->new_transition(final_, initial_, epsilon_);
150  res_->new_transition(initial, final, epsilon_);
151  initial_ = initial;
152  final_ = final;
153  }
154 
156  {
157  e.sub()->accept(*this);
158 
159  const weight_t& w = e.weight();
160  for (auto t: out(res_, initial_))
161  res_->set_weight(t, ws_.mul(w, res_->weight_of(t)));
162  }
163 
165  {
166  e.sub()->accept(*this);
167 
168  const weight_t& w = e.weight();
169  for (auto t: in(res_, final_))
170  res_->set_weight(t, ws_.mul(res_->weight_of(t), w));
171  }
172 
173  private:
175  const weightset_t& ws_ = *rs_.weightset();
178  const label_t epsilon_ = res_->labelset()->one();
179  state_t initial_ = automaton_t::element_type::null_state();
180  state_t final_ = automaton_t::element_type::null_state();
181  };
182  } // rat::
183 
188  template <Automaton Aut, typename ExpSet>
189  Aut
191  const ExpSet& rs, const typename ExpSet::value_t& r)
192  {
193  auto thm = rat::thompson_visitor<Aut, ExpSet>{ctx, rs};
194  return thm(r);
195  }
196 
201  template <Automaton Aut, typename ExpSet>
202  Aut
203  thompson(const ExpSet& rs, const typename ExpSet::value_t& r)
204  {
205  auto thm = rat::thompson_visitor<Aut, ExpSet>{rs};
206  return thm(r);
207  }
208 
209  namespace dyn
210  {
211  namespace detail
212  {
213  /*---------------------.
214  | dyn::thompson(exp). |
215  `---------------------*/
216 
218  template <typename ExpSet>
219  automaton
220  thompson(const expression& exp)
221  {
222  // FIXME: So far, there is a single implementation of expressions,
223  // but we should actually be parameterized by its type too.
224  using expressionset_t = ExpSet;
225  const auto& e = exp->as<expressionset_t>();
226  auto ctx
227  = vcsn::detail::make_nullableset_context(e.valueset().context());
228  using ctx_t = decltype(ctx);
230  return ::vcsn::thompson<automaton_t>(ctx, e.valueset(), e.value());
231  }
232  }
233  }
234 
235 } // vcsn::
std::shared_ptr< detail::mutable_automaton_impl< Context > > mutable_automaton
Definition: fwd.hh:25
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:190
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
Definition: traits.hh:67
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: thompson.hh:40
typename expressionset_t::const_visitor super_t
Definition: thompson.hh:34
typename detail::state_t_of_impl< base_t< ValueSet > >::type state_t_of
Definition: traits.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:164
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:13
An inner node with multiple children.
Definition: expression.hh:119
weightset_t_of< expressionset_t > weightset_t
Definition: thompson.hh:30
context_t_of< automaton_t > context_t
Definition: thompson.hh:29
label_t_of< automaton_t > label_t
Definition: thompson.hh:177
An inner node to name the subexpression.
Definition: expression.hh:290
weight_t_of< expressionset_t > weight_t
Definition: thompson.hh:31
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
Definition: traits.hh:61
typename expressionset_t::value_t expression_t
Definition: thompson.hh:28
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
typename super_t::tuple_t tuple_t
Definition: thompson.hh:78
void visit(const tuple_t &, std::true_type) override
Definition: thompson.hh:79
typename detail::labelset_t_of_impl< base_t< ValueSet > >::type labelset_t_of
Definition: traits.hh:63
Definition: a-star.hh:8
auto in(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions arriving to state s.
Definition: automaton.hh:135
typename detail::label_t_of_impl< base_t< ValueSet > >::type label_t_of
Definition: traits.hh:62
state_t_of< automaton_t > state_t
Definition: thompson.hh:32
std::string to_string(identities i)
Wrapper around operator<<.
Definition: identities.cc:38
An inner node implementing a weight.
Definition: expression.hh:256
Build a Thompson automaton from an expression.
Definition: thompson.hh:22
automaton_t operator()(const expression_t &v)
The Thompson automaton of v.
Definition: thompson.hh:53
return v
Definition: multiply.hh:362
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:84
const weightset_t & ws_
Definition: thompson.hh:175
thompson_visitor(const expressionset_t &rs)
Definition: thompson.hh:48
value_impl< detail::expression_tag > expression
Definition: fwd.hh:31
#define Automaton
Definition: automaton.hh:23
#define VCSN_RAT_UNSUPPORTED(Type)
Definition: visitor.hh:75
typename detail::weight_t_of_impl< base_t< ValueSet > >::type weight_t_of
Definition: traits.hh:66
STL namespace.
thompson_visitor(const context_t &ctx, const expressionset_t &rs)
Build an automaton of context ctx.
Definition: thompson.hh:43
const expressionset_t & rs_
Definition: thompson.hh:174
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
Definition: automaton.hh:86