Vcsn  2.3
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 
45  static value_t zero()
46  {
47  // Not value_t{0, 1} to avoid the (const char* s, int base)
48  // constructor.
49  return value_t{mpz_class(0), 1};
50  }
51 
52  static value_t one()
53  {
54  return value_t{1, 1};
55  }
56 
57  static value_t add(const value_t l, const value_t r)
58  {
59  return l + r;
60  }
61 
62  static value_t sub(const value_t l, const value_t r)
63  {
64  return l - r;
65  }
66 
67  static value_t mul(const value_t l, const value_t r)
68  {
69  return l * r;
70  }
71 
72  value_t
73  rdivide(const value_t l, const value_t r) const
74  {
75  require(!is_zero(r), *this, ":div: division by zero");
76  return l / r;
77  }
78 
79  value_t
80  ldivide(const value_t l, const value_t r) const
81  {
82  return rdivide(r, l);
83  }
84 
85  value_t star(const value_t v) const
86  {
87  if (abs(v.get_num()) < v.get_den())
88  // No need to reduce: numerator and denominators are primes.
89  return {v.get_den(), v.get_den() - v.get_num()};
90  else
91  raise_not_starrable(*this, v);
92  }
93 
94  static bool is_special(const value_t) // C++11: cannot be constexpr.
95  {
96  return false;
97  }
98 
99  static bool is_zero(const value_t v)
100  {
101  return v.get_num() == 0;
102  }
103 
104  static bool is_one(const value_t v)
105  {
106  // All values are normalized.
107  return v.get_num() == 1 && v.get_den() == 1;
108  }
109 
110  static bool equal(const value_t l, const value_t r)
111  {
112  return l == r;
113  }
114 
116  static bool less(value_t l, value_t r)
117  {
118  return l < r;
119  }
120 
121  static constexpr bool is_commutative() { return true; }
122  static constexpr bool has_lightening_weights() { return true; }
123 
124  static constexpr bool show_one() { return false; }
125  static constexpr star_status_t star_status() { return star_status_t::ABSVAL; }
126 
127  static value_t
128  abs(const value_t v)
129  {
130  return ::abs(v);
131  }
132 
133  static value_t
135  {
136  return v;
137  }
138 
139  static size_t hash(value_t v)
140  {
141  // FIXME: be serious...
142  return hash_value(to_string(qmp_impl(), v));
143  }
144 
145  static value_t
147  {
148  return v;
149  }
150 
151  static value_t
153  {
154  return {v, 1};
155  }
156 
157  static value_t
159  {
160  return {v, 1};
161  }
162 
163  static value_t
164  conv(std::istream& i, bool = true)
165  {
166  value_t res;
167  i >> res;
168  return res;
169  }
170 
171  static std::ostream&
172  print(const value_t v, std::ostream& o = std::cout,
173  format fmt = {})
174  {
175  if (fmt == format::latex)
176  {
177  if (v.get_den() == 1)
178  o << v.get_num();
179  else
180  o << "\\frac{" << v.get_num() << "}{" << v.get_den() << '}';
181  }
182  else
183  o << v;
184  return o;
185  }
186 
187  std::ostream&
188  print_set(std::ostream& o, format fmt = {}) const
189  {
190  switch (fmt.kind())
191  {
192  case format::latex:
193  o << "\\mathbb{Q}_{\\text{mp}}";
194  break;
195  case format::sname:
196  o << sname();
197  break;
198  case format::text:
199  o << "Qmp";
200  break;
201  case format::utf8:
202  o << "ℚmp";
203  break;
204  case format::raw:
205  assert(0);
206  break;
207  }
208  return o;
209  }
210  };
211 
212  /*-------.
213  | join. |
214  `-------*/
215 
220  }
221 }
static value_t sub(const value_t l, const value_t r)
Definition: qmp.hh:62
weightset_mixin< detail::q_impl > q
Definition: fwd.hh:52
static value_t add(const value_t l, const value_t r)
Definition: qmp.hh:57
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
static value_t conv(b, b::value_t v)
Definition: qmp.hh:158
static constexpr bool is_commutative()
Definition: qmp.hh:121
star_status_t
Definition: star-status.hh:5
static bool less(value_t l, value_t r)
Whether < r.
Definition: qmp.hh:116
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 value_t one()
Definition: qmp.hh:52
value_t star(const value_t v) const
Definition: qmp.hh:85
static value_t mul(const value_t l, const value_t r)
Definition: qmp.hh:67
Print as a parsable type string.
Definition: format.hh:26
static bool is_zero(const value_t v)
Definition: qmp.hh:99
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:91
static value_t transpose(const value_t v)
Definition: qmp.hh:134
static value_t abs(const value_t v)
Definition: qmp.hh:128
static size_t hash(value_t v)
Definition: qmp.hh:139
return res
Definition: multiply.hh:398
auto hash_value(const T &v) -> decltype(std::hash< T >
Following the naming convention of Boost.
Definition: functional.hh:30
static bool is_special(const value_t)
Definition: qmp.hh:94
static value_t conv(std::istream &i, bool=true)
Definition: qmp.hh:164
VCSN_JOIN_SIMPLE(b, b)
Definition: a-star.hh:8
static value_t conv(self_t, value_t v)
Definition: qmp.hh:146
mpq_class value_t
Definition: qmp.hh:43
An input/output format for valuesets.
Definition: format.hh:13
static value_t zero()
Definition: qmp.hh:45
Print as is. For instance, don't try to escape labels.
Definition: format.hh:24
std::string to_string(direction d)
Conversion to string.
Definition: direction.cc:7
value_t rdivide(const value_t l, const value_t r) const
Definition: qmp.hh:73
static constexpr bool show_one()
Definition: qmp.hh:124
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
static constexpr bool has_lightening_weights()
Definition: qmp.hh:122
std::ostream & print_set(std::ostream &o, format fmt={}) const
Definition: qmp.hh:188
static symbol sname()
Definition: qmp.hh:30
weightset_mixin< detail::qmp_impl > qmp
Definition: fwd.hh:53
weightset_mixin< detail::z_impl > z
Definition: fwd.hh:56
value_t ldivide(const value_t l, const value_t r) const
Definition: qmp.hh:80
static bool equal(const value_t l, const value_t r)
Definition: qmp.hh:110
weightset_mixin< detail::b_impl > b
Definition: fwd.hh:48
Print for LaTeX.
Definition: format.hh:22
static std::ostream & print(const value_t v, std::ostream &o=std::cout, format fmt={})
Definition: qmp.hh:172
static value_t conv(z, z::value_t v)
Definition: qmp.hh:152
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
valid iff proper succeeds on the "absolute value" of the automaton
Definition: star-status.hh:9
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:90
static constexpr star_status_t star_status()
Definition: qmp.hh:125
static bool is_one(const value_t v)
Definition: qmp.hh:104
static qmp make(std::istream &is)
Build from the description in is.
Definition: qmp.hh:37
weightset_mixin< detail::r_impl > r
Definition: fwd.hh:54