Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
derived-term.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_DERIVED_TERM_HH
2 # define VCSN_ALGOS_DERIVED_TERM_HH
3 
5 # include <vcsn/algos/derivation.hh>
7 # include <vcsn/algos/split.hh>
10 # include <vcsn/ctx/fwd.hh>
11 # include <vcsn/dyn/automaton.hh>
12 # include <vcsn/dyn/polynomial.hh>
13 # include <vcsn/dyn/ratexp.hh>
14 # include <vcsn/misc/raise.hh>
16 
17 namespace vcsn
18 {
19  /*-----------------------.
20  | derived_term(ratexp). |
21  `-----------------------*/
22 
23  namespace detail
24  {
53  template <typename RatExpSet>
55  {
56  using ratexpset_t = RatExpSet;
57  using ratexp_t = typename ratexpset_t::value_t;
58 
61 
64 
68 
69  derived_termer(const ratexpset_t& rs, bool breaking = false)
70  : rs_(rs)
71  , breaking_(breaking)
72  , res_{make_shared_ptr<automaton_t>(rs_.context())}
73  {}
74 
77  {
78  init_(ratexp);
79 
80  // The alphabet.
81  const auto& ls = rs_.labelset()->genset();
82  while (!res_->todo_.empty())
83  {
84  ratexp_t src = res_->todo_.top();
85  state_t s = res_->state(src);
86  res_->todo_.pop();
87  res_->set_final(s, constant_term(rs_, src));
88  for (auto l : ls)
89  for (const auto& m: derivation(rs_, src, l, breaking_))
90  res_->new_transition(s, m.first, l, m.second);
91  }
92  return res_;
93  }
94 
97  {
98  init_(ratexp);
99 
101  while (!res_->todo_.empty())
102  {
103  ratexp_t src = res_->todo_.top();
104  auto s = res_->state(src);
105  res_->todo_.pop();
106  auto expansion = expand(src);
107  res_->set_final(s, expansion.constant);
108  for (const auto& p: expansion.polynomials)
109  if (breaking_)
110  for (const auto& m1: p.second)
111  for (const auto& m2: split(rs_, m1.first))
112  res_->new_transition(s, m2.first, p.first,
113  ws_.mul(m1.second, m2.second));
114  else
115  for (const auto& m: p.second)
116  res_->new_transition(s, m.first, p.first, m.second);
117  }
118  return res_;
119  }
120 
121  private:
122  void init_(const ratexp_t& ratexp)
123  {
124  if (breaking_)
125  for (const auto& p: split(rs_, ratexp))
126  res_->set_initial(p.first, p.second);
127  else
128  res_->set_initial(ratexp, ws_.one());
129  }
130 
134  weightset_t ws_ = *rs_.weightset();
136  bool breaking_ = false;
139  };
140  }
141 
143  template <typename RatExpSet>
144  inline
146  derived_term_derivation(const RatExpSet& rs,
147  const typename RatExpSet::value_t& r,
148  bool breaking = false)
149  {
150  detail::derived_termer<RatExpSet> dt{rs, breaking};
151  return dt.via_derivation(r);
152  }
153 
155  template <typename RatExpSet>
156  inline
157  ratexp_automaton<mutable_automaton<typename RatExpSet::context_t>>
158  derived_term_expansion(const RatExpSet& rs,
159  const typename RatExpSet::value_t& r,
160  bool breaking = false)
161  {
162  detail::derived_termer<RatExpSet> dt{rs, breaking};
163  return dt.via_expansion(r);
164  }
165 
166  namespace dyn
167  {
168  namespace detail
169  {
171  template <typename RatExpSet, typename String>
172  inline
173  typename std::enable_if<RatExpSet::context_t::labelset_t::is_free(),
174  automaton>::type
175  derived_term(const ratexp& exp, const std::string& algo)
176  {
177  const auto& e = exp->as<RatExpSet>();
178  const auto& rs = e.ratexpset();
179  const auto& r = e.ratexp();
180  auto res
181  = algo == "derivation"
183  : algo == "breaking_derivation"
185  : algo == "auto" || algo == "expansion"
187  : algo == "breaking_expansion"
188  ? ::vcsn::derived_term_expansion(rs, r, true)
189  : nullptr;
190  require(!!res, "derived_term: invalid algorithm: " + algo);
191  return make_automaton(res);
192  }
193 
195  template <typename RatExpSet, typename String>
196  inline
197  typename std::enable_if<!RatExpSet::context_t::labelset_t::is_free(),
198  automaton>::type
199  derived_term(const ratexp& exp, const std::string& algo)
200  {
201  const auto& e = exp->as<RatExpSet>();
202  const auto& rs = e.ratexpset();
203  const auto& r = e.ratexp();
204  auto res
205  = algo == "auto" || algo == "expansion"
207  : algo == "breaking_expansion"
208  ? ::vcsn::derived_term_expansion(rs, r, true)
209  : nullptr;
210  require(!!res, "derived_term: invalid algorithm: " + algo);
211  return make_automaton(res);
212  }
213 
215  (const ratexp& e, const std::string& algo) -> automaton);
216  }
217  }
218 
219 } // vcsn::
220 
221 #endif // !VCSN_ALGOS_DERIVED_TERM_HH
weightset_t ws_
Its weightset.
Linear combination of labels: map labels to weights.
Definition: fwd.hh:32
ratexpset_t rs_
The ratexp's set.
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
automaton_t res_
The resulting automaton.
bool breaking_
Whether to break the polynomials.
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:77
RatExpSet::value_t expand(const RatExpSet &rs, const typename RatExpSet::value_t &e)
Expanding a typed ratexp shared_ptr.
Definition: expand.hh:152
std::shared_ptr< detail::ratexp_base > ratexp
Definition: fwd.hh:64
std::shared_ptr< const node< Context >> ratexp
Definition: fwd.hh:156
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:32
#define REGISTER_DECLARE(Name, Signature)
Definition: fwd.hh:104
std::shared_ptr< const detail::expansion_base > expansion
Definition: expansion.hh:74
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
Definition: traits.hh:38
derived_termer(const ratexpset_t &rs, bool breaking=false)
Definition: derived-term.hh:69
state_t_of< automaton_t > state_t
Definition: derived-term.hh:63
typename polynomialset_t::value_t polynomial_t
Definition: derived-term.hh:67
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:36
automaton_t via_derivation(const ratexp_t &ratexp)
Compute the derived-term automaton via derivation.
Definition: derived-term.hh:76
Compute the derived-term automaton from an expression.
Definition: derived-term.hh:54
context_t_of< ratexpset_t > context_t
Definition: derived-term.hh:59
automaton_t via_expansion(const ratexp_t &ratexp)
Compute the derived-term automaton via expansion.
Definition: derived-term.hh:96
weight_t_of< RatExpSet > constant_term(const RatExpSet &rs, const typename RatExpSet::value_t &e)
std::map< label_t, weight_t, vcsn::less< labelset_t >> value_t
std::enable_if<!RatExpSet::context_t::labelset_t::is_free(), automaton >::type derived_term(const ratexp &exp, const std::string &algo)
Bridge.
void init_(const ratexp_t &ratexp)
rat::ratexp_polynomial_t< RatExpSet > derivation(const RatExpSet &rs, const typename RatExpSet::value_t &e, label_t_of< RatExpSet > a, bool breaking=false)
Derive a ratexp wrt to a letter.
Definition: derivation.hh:201
std::shared_ptr< detail::ratexp_automaton_impl< Aut >> ratexp_automaton
A ratexp automaton as a shared pointer.
Definition: fwd.hh:51
rat::ratexp_polynomial_t< RatExpSet > split(const RatExpSet &rs, const typename RatExpSet::value_t &e)
Split a ratexp.
Definition: split.hh:257
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
weightset_t_of< context_t > weightset_t
Definition: derived-term.hh:60
ratexp_automaton< mutable_automaton< typename RatExpSet::context_t > > derived_term_derivation(const RatExpSet &rs, const typename RatExpSet::value_t &r, bool breaking=false)
The derived-term automaton, computed by derivation.
ratexp_automaton< mutable_automaton< context_t >> automaton_t
Definition: derived-term.hh:62
typename ratexpset_t::value_t ratexp_t
Definition: derived-term.hh:57
ratexp_automaton< mutable_automaton< typename RatExpSet::context_t > > derived_term_expansion(const RatExpSet &rs, const typename RatExpSet::value_t &r, bool breaking=false)
The derived-term automaton, computed by expansion.
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:39