Vcsn  2.8
Be Rational
qmp.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <ostream>
4 #include <string>
5 
6 #include <cstddef> // https://gcc.gnu.org/gcc-4.9/porting_to.html
7 #include <gmpxx.h>
8 
9 #include <vcsn/core/join.hh>
10 #include <vcsn/misc/format.hh>
11 #include <vcsn/misc/functional.hh>
12 #include <vcsn/misc/raise.hh>
13 #include <vcsn/misc/star-status.hh>
14 #include <vcsn/misc/stream.hh> // eat
15 #include <vcsn/weightset/b.hh>
16 #include <vcsn/weightset/fwd.hh>
17 #include <vcsn/weightset/q.hh>
18 #include <vcsn/weightset/r.hh>
20 #include <vcsn/weightset/z.hh>
21 
22 namespace vcsn
23 {
24  namespace detail
25  {
26  class qmp_impl
27  {
28  public:
29  using self_t = qmp;
30 
31  static symbol sname()
32  {
33  static auto res = symbol{"qmp"};
34  return res;
35  }
36 
38  static qmp make(std::istream& is)
39  {
40  eat(is, sname());
41  return {};
42  }
43 
44  using value_t = mpq_class;
45 
47  static value_t value(int num, unsigned den)
48  {
49  return value_t{num, den};
50  }
51 
52  static value_t zero()
53  {
54  // Not value_t{0, 1} to avoid the (const char* s, int base)
55  // constructor.
56  return value_t{mpz_class(0), 1};
57  }
58 
59  static value_t one()
60  {
61  return value_t{1, 1};
62  }
63 
64  static value_t
65  min()
66  {
67  auto num = std::numeric_limits<int>::min();
68  return value_t{num, 1};
69  }
70 
71  static value_t
72  max()
73  {
74  auto num = std::numeric_limits<int>::max();
75  return value_t{num, 1};
76  }
77 
78  static value_t add(const value_t& l, const value_t& r)
79  {
80  return l + r;
81  }
82 
83  static value_t sub(const value_t& l, const value_t& r)
84  {
85  return l - r;
86  }
87 
88  static value_t mul(const value_t& l, const value_t& r)
89  {
90  return l * r;
91  }
92 
93  value_t
94  rdivide(const value_t& l, const value_t& r) const
95  {
96  require(!is_zero(r), *this, ":div: division by zero");
97  return l / r;
98  }
99 
100  value_t
101  ldivide(const value_t& l, const value_t& r) const
102  {
103  return rdivide(r, l);
104  }
105 
106  value_t star(const value_t& v) const
107  {
108  if (abs(v.get_num()) < v.get_den())
109  // No need to reduce: numerator and denominators are primes.
110  return {v.get_den(), v.get_den() - v.get_num()};
111  else
112  raise_not_starrable(*this, v);
113  }
114 
115  static bool is_special(const value_t&) // C++11: cannot be constexpr.
116  {
117  return false;
118  }
119 
120  static bool is_zero(const value_t& v)
121  {
122  return v.get_num() == 0;
123  }
124 
125  static bool is_one(const value_t& v)
126  {
127  // All values are normalized.
128  return v.get_num() == 1 && v.get_den() == 1;
129  }
130 
132  static int compare(const value_t& l, const value_t& r)
133  {
134  return cmp(l, r);
135  }
136 
138  static bool equal(const value_t& l, const value_t& r)
139  {
140  return l == r;
141  }
142 
144  static bool less(const value_t& l, const value_t& r)
145  {
146  return l < r;
147  }
148 
149  static constexpr bool is_commutative() { return true; }
150  static constexpr bool has_lightening_weights() { return true; }
151 
152  static constexpr bool show_one() { return false; }
153  static constexpr star_status_t star_status() { return star_status_t::ABSVAL; }
154 
155  static value_t
156  abs(const value_t& v)
157  {
158  return ::abs(v);
159  }
160 
161  static value_t
163  {
164  return v;
165  }
166 
167  static size_t hash(const value_t& v)
168  {
169  // FIXME: be serious...
170  return hash_value(to_string(qmp_impl(), v));
171  }
172 
173  static value_t
174  conv(self_t, const value_t& v)
175  {
176  return v;
177  }
178 
179  static value_t
181  {
182  return {v, 1};
183  }
184 
185  static value_t
187  {
188  return {v, 1};
189  }
190 
191  static value_t
192  conv(std::istream& i, bool = true)
193  {
194  value_t res;
195  i >> res;
196  return res;
197  }
198 
199  static std::ostream&
200  print(const value_t& v, std::ostream& o = std::cout,
201  format fmt = {})
202  {
203  if (fmt == format::latex)
204  {
205  if (v.get_den() == 1)
206  o << v.get_num();
207  else
208  o << "\\frac{" << v.get_num() << "}{" << v.get_den() << '}';
209  }
210  else
211  o << v;
212  return o;
213  }
214 
215  std::ostream&
216  print_set(std::ostream& o, format fmt = {}) const
217  {
218  switch (fmt.kind())
219  {
220  case format::latex:
221  o << "\\mathbb{Q}_{\\text{mp}}";
222  break;
223  case format::sname:
224  o << sname();
225  break;
226  case format::text:
227  o << "Qmp";
228  break;
229  case format::utf8:
230  o << "ℚmp";
231  break;
232  case format::raw:
233  assert(0);
234  break;
235  }
236  return o;
237  }
238  };
239 
241  template <typename RandomGenerator>
242  class random_weight<qmp, RandomGenerator>
243  : public random_weight_base<qmp, RandomGenerator>
244  {
245  public:
247  using value_t = typename super_t::weight_t;
248 
249  using super_t::super_t;
250 
251  private:
253  {
254  auto dis_num =
255  std::uniform_int_distribution<>(super_t::min_.get_num().get_ui(),
256  super_t::max_.get_num().get_ui());
257  auto dis_den =
258  std::uniform_int_distribution<unsigned>
259  (super_t::min_.get_den().get_ui(),
260  super_t::max_.get_num().get_ui());
261  auto num = dis_num(super_t::gen_);
262  auto den = dis_den(super_t::gen_);
263  return super_t::ws_.value(num, den);
264  }
265  };
266 
267 
268  /*-------.
269  | join. |
270  `-------*/
271 
276 
277  // We don't want to force the inclusion of qmp.hh in r.hh, as it
278  // means that qmp.hh become a hard requirement.
280  }
281 }
Print as a parsable type string.
Definition: format.hh:26
static constexpr bool is_commutative()
Definition: qmp.hh:149
static value_t sub(const value_t &l, const value_t &r)
Definition: qmp.hh:83
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54
static value_t value(int num, unsigned den)
Create rational weight from num and den.
Definition: qmp.hh:47
static size_t hash(const value_t &v)
Definition: qmp.hh:167
static bool is_zero(const value_t &v)
Definition: qmp.hh:120
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:147
return exp min
Definition: multiply.hh:362
mpq_class value_t
Definition: qmp.hh:44
static value_t conv(z, z::value_t v)
Definition: qmp.hh:180
value_t ldivide(const value_t &l, const value_t &r) const
Definition: qmp.hh:101
static value_t transpose(const value_t &v)
Definition: qmp.hh:162
static bool equal(const value_t &l, const value_t &r)
Whether l == r.
Definition: qmp.hh:138
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:21
static value_t conv(b, b::value_t v)
Definition: qmp.hh:186
static int compare(const value_t &l, const value_t &r)
Three-way comparison between l and r.
Definition: qmp.hh:132
static constexpr bool show_one()
Definition: qmp.hh:152
static symbol sname()
Definition: qmp.hh:31
std::ostream & print_set(std::ostream &o, format fmt={}) const
Definition: qmp.hh:216
static value_t max()
Definition: qmp.hh:72
valid iff proper succeeds on the "absolute value" of the automaton
Definition: star-status.hh:9
static value_t add(const value_t &l, const value_t &r)
Definition: qmp.hh:78
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
An input/output format for valuesets.
Definition: format.hh:13
Abstract class for random weight generation.
Definition: weightset.hh:118
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
weightset_mixin< detail::qmp_impl > qmp
Definition: fwd.hh:53
value_t star(const value_t &v) const
Definition: qmp.hh:106
static bool less(const value_t &l, const value_t &r)
Whether < r.
Definition: qmp.hh:144
static std::ostream & print(const value_t &v, std::ostream &o=std::cout, format fmt={})
Definition: qmp.hh:200
static value_t mul(const value_t &l, const value_t &r)
Definition: qmp.hh:88
auto hash_value(const T &v) -> decltype(std::hash< T >
Following the naming convention of Boost.
Definition: functional.hh:45
static qmp make(std::istream &is)
Build from the description in is.
Definition: qmp.hh:38
Definition: a-star.hh:8
static constexpr bool has_lightening_weights()
Definition: qmp.hh:150
value_t rdivide(const value_t &l, const value_t &r) const
Definition: qmp.hh:94
static value_t zero()
Definition: qmp.hh:52
static bool is_special(const value_t &)
Definition: qmp.hh:115
star_status_t
Definition: star-status.hh:5
static value_t conv(self_t, const value_t &v)
Definition: qmp.hh:174
static value_t one()
Definition: qmp.hh:59
static bool is_one(const value_t &v)
Definition: qmp.hh:125
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
ATTRIBUTE_NORETURN void raise_not_starrable(const WeightSet &ws, const typename WeightSet::value_t &w)
This value is not starrable.
Definition: weightset.hh:235
static value_t abs(const value_t &v)
Definition: qmp.hh:156
Print as is. For instance, don&#39;t try to escape labels.
Definition: format.hh:24
Print for LaTeX.
Definition: format.hh:22
static value_t min()
Definition: qmp.hh:65
VCSN_JOIN_SIMPLE(b, b)
Generic declaration of the class which is specialized in each weightset.
Definition: weightset.hh:208
void require(Bool b, Args &&... args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:87
static constexpr star_status_t star_status()
Definition: qmp.hh:153
std::string to_string(direction d)
Conversion to string.
Definition: direction.cc:7
static value_t conv(std::istream &i, bool=true)
Definition: qmp.hh:192
return res
Definition: multiply.hh:399