Vcsn  2.8
Be Rational
star-normal-form.hh
Go to the documentation of this file.
1 #pragma once
2 
5 #include <vcsn/ctx/fwd.hh>
6 #include <vcsn/dyn/value.hh>
7 #include <vcsn/misc/algorithm.hh> // any_of
8 #include <vcsn/misc/raise.hh>
9 #include <vcsn/weightset/b.hh>
10 
11 namespace vcsn
12 {
13 
14  namespace rat
15  {
16 
17  /*--------------------------------.
18  | star_normal_form(expression). |
19  `--------------------------------*/
20 
27  template <typename ExpSet>
29  : public ExpSet::const_visitor
30  {
31  public:
32  using expressionset_t = ExpSet;
33  using expression_t = typename expressionset_t::value_t;
36  static_assert(std::is_same<weightset_t, b>::value,
37  "star_normal_form: requires Boolean weights");
38 
39  using weight_t = typename weightset_t::value_t;
40 
41  using super_t = typename ExpSet::const_visitor;
42 
44  constexpr static const char* me() { return "star_normal_form"; }
45 
47  enum operation_t { dot, box };
48 
50  : rs_(rs)
51  {}
52 
55  {
56  operation_ = dot;
57  return rec_(v);
58  }
59  private:
62  {
63  v->accept(*this);
64  return res_;
65  }
66 
68  {
69  res_ = rs_.zero();
70  }
71 
73  {
74  res_ = operation_ == box ? rs_.zero() : rs_.one();
75  }
76 
78  {
79  res_ = rs_.atom(v.value());
80  }
81 
83  {
84  res_ = rs_.name(rec_(v.sub()), v.name_get());
85  }
86 
87  // Plain traversal for sums.
89  {
90  v.head()->accept(*this);
92  for (auto c: v.tail())
93  res = rs_.add(res, rec_(c));
94  res_ = std::move(res);
95  }
96 
106  using tuple_t = typename super_t::tuple_t;
107  void visit(const tuple_t&, std::true_type) override
108  {
109  raise(me(), ": tuple is not supported");
110  }
111 
113  {
114  if (operation_ == box)
115  box_of(v);
116  else
117  dot_of(v);
118  }
119 
121  void box_of(const mul_t& v)
122  {
123  using detail::any_of;
124  if (any_of(v,
125  [this](const expression_t& n)
126  {
127  return ws_.is_zero(constant_term(rs_, n));
128  }))
129  {
130  // Some factor has a null constant-term.
131  operation_ = dot;
132  dot_of(v);
133  operation_ = box;
134  }
135  else
136  {
137  // All the factors have a non null constant-term.
138  expression_t res = rec_(v.head());
139  for (auto c: v.tail())
140  res = rs_.add(res, rec_(c));
141  res_ = std::move(res);
142  }
143  }
144 
146  void dot_of(const mul_t& v)
147  {
148  expression_t res = rec_(v.head());
149  for (auto c: v.tail())
150  res = rs_.mul(res, rec_(c));
151  res_ = std::move(res);
152  }
153 
155  {
156  if (operation_ == dot)
157  {
158  operation_ = box;
159  res_ = rs_.lweight(ws_.star(constant_term(rs_, v.sub())),
160  rs_.star(rec_(v.sub())));
161  operation_ = dot;
162  }
163  else
164  rec_(v.sub());
165  }
166 
167  private:
170  weightset_t ws_ = *rs_.weightset();
175  };
176 
177  } // rat::
178 
180  template <typename ExpSet>
181  typename ExpSet::value_t
182  star_normal_form(const ExpSet& rs, const typename ExpSet::value_t& e)
183  {
185  return snf(e);
186  }
187 
188  namespace dyn
189  {
190  namespace detail
191  {
193  template <typename ExpSet>
194  expression
196  {
197  const auto& e = exp->as<ExpSet>();
198  return {e.valueset(), ::vcsn::star_normal_form(e.valueset(),
199  e.value())};
200  }
201  }
202  }
203 
204 } // vcsn::
std::shared_ptr< const node< Context > > expression
Definition: fwd.hh:195
typename detail::weightset_t_of_impl< base_t< ValueSet > >::type weightset_t_of
Definition: traits.hh:67
void visit(const tuple_t &, std::true_type) override
bool any_of(const Range &r, Predicate p)
Definition: algorithm.hh:16
void dot_of(const mul_t &v)
Handling of a product by the dot operator.
An inner node with multiple children.
Definition: expression.hh:119
typename weightset_t::value_t weight_t
expression_t rec_(const expression_t &v)
Easy recursion.
operation_t
The type of the operator.
weightset_t ws_
Shorthand to the weightset.
An inner node to name the subexpression.
Definition: expression.hh:290
typename detail::context_t_of_impl< base_t< ValueSet > >::type context_t_of
Definition: traits.hh:61
star_normal_form_visitor(const expressionset_t &rs)
expression_t operator()(const expression_t &v)
typename expressionset_t::value_t expression_t
Definition: a-star.hh:8
expression star_normal_form(const expression &exp)
Bridge.
operation_t operation_
The current operation.
void box_of(const mul_t &v)
Handling of a product by the box operator.
An inner node implementing a weight.
Definition: expression.hh:256
typename super_t::tuple_t tuple_t
context_t_of< expressionset_t > context_t
return v
Definition: multiply.hh:362
value_impl< detail::expression_tag > expression
Definition: fwd.hh:31
weight_t_of< ExpSet > constant_term(const ExpSet &rs, const typename ExpSet::value_t &e)
The constant term of e.
ExpSet::value_t star_normal_form(const ExpSet &rs, const typename ExpSet::value_t &e)
Star-normal form of an expression.
typename ExpSet::const_visitor super_t
#define VCSN_RAT_UNSUPPORTED(Type)
Definition: visitor.hh:75
weightset_t_of< context_t > weightset_t
static constexpr const char * me()
Name of this algorithm, for error messages.
STL namespace.
return res
Definition: multiply.hh:399