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