1 /*
2  * This file is part of the Yices SMT Solver.
3  * Copyright (C) 2017 SRI International.
4  *
5  * Yices is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Yices is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Yices.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /*
20  * NEORATIONAL NUMBERS
21  */
22 
23 #ifndef __RATIONALS_H
24 #define __RATIONALS_H
25 
26 #include <assert.h>
27 #include <stdio.h>
28 #include <stdint.h>
29 #include <stdbool.h>
30 #include <gmp.h>
31 
32 #include "terms/mpq_aux.h"
33 #include "utils/memalloc.h"
34 
35 
36 /*
37  * INTERNAL REPRESENTATION
38  */
39 
40 /*
41  * A neorational is a union of size 64 bits.
42  *
43  * if the least bit is 1 it represents a
44  * pointer to a gmp number.
45  *
46  * if the least bit is zero it is a struct consisting of a 32 bit
47  * signed numerator, and a 31 bit unsigned denominator.
48  */
49 typedef struct {
50 #ifdef WORDS_BIGENDIAN
51   int32_t  num;
52   uint32_t den;
53 #else
54   uint32_t den;
55   int32_t  num;
56 #endif
57 } rat32_t;
58 
59 typedef struct {
60   intptr_t gmp;
61 } ratgmp_t;
62 
63 
64 typedef union rational { rat32_t s; ratgmp_t p; } rational_t;   //s for struct; p for pointer
65 
66 #define IS_RAT32  0x0
67 #define IS_RATGMP 0x1
68 /* the test for unicity in the denominator occurs frequently. the denominator is one if it is 2 :-) */
69 #define ONE_DEN   0x2
70 
71 
72 /*
73  * Initialization: allocate and initialize
74  * global variables.
75  */
76 extern void init_rationals(void);
77 
78 
79 /*
80  * Cleanup: free memory
81  */
82 extern void cleanup_rationals(void);
83 
84 
85 /*
86  * Set r to 0/1, Must be called before any operation on r.
87  */
q_init(rational_t * r)88 static inline void q_init(rational_t *r) {
89   r->s.num = 0;
90   r->s.den = ONE_DEN;
91 }
92 
93 
94 /*
95  * Tests and conversions to/from gmp and rat32
96  *
97  * NOTE: the type mpq_ptr is defined in gmp.h. It's a pointer
98  * to the internal structure representing a gmp number.
99  */
is_rat32(const rational_t * r)100 static inline bool is_rat32(const rational_t *r) {
101   return (r->p.gmp & IS_RATGMP) != IS_RATGMP;
102 }
103 
is_ratgmp(const rational_t * r)104 static inline bool is_ratgmp(const rational_t *r) {
105   return (r->p.gmp & IS_RATGMP) == IS_RATGMP;
106 }
107 
get_gmp(const rational_t * r)108 static inline mpq_ptr get_gmp(const rational_t *r) {
109   assert(is_ratgmp(r));
110   return (mpq_ptr) (r->p.gmp ^ IS_RATGMP);
111 }
112 
get_num(const rational_t * r)113 static inline int32_t get_num(const rational_t *r) {
114   assert(is_rat32(r));
115   return r->s.num;
116 }
117 
get_den(const rational_t * r)118 static inline uint32_t get_den(const rational_t *r) {
119   assert(is_rat32(r));
120   return r->s.den >> 1;
121 }
122 
set_ratgmp(rational_t * r,mpq_ptr gmp)123 static inline void set_ratgmp(rational_t *r, mpq_ptr gmp){
124   r->p.gmp = ((intptr_t) gmp) | IS_RATGMP;
125 }
126 
127 /*
128  * Free mpq number attached to r if any, then set r to 0/1.
129  * Must be called before r is deleted to prevent memory leaks.
130  */
131 extern void q_clear(rational_t *r);
132 
133 /*
134  * If r is represented as a gmp rational, convert it
135  * to a pair of integers if possible.
136  * If it's possible the gmp number is freed.
137  */
138 extern void q_normalize(rational_t *r);
139 
140 
141 /*
142  * ASSIGNMENT
143  */
144 
145 /*
146  * Assign +1 or -1 to r
147  */
q_set_one(rational_t * r)148 static inline void q_set_one(rational_t *r) {
149   q_clear(r);
150   r->s.num = 1;
151 }
152 
q_set_minus_one(rational_t * r)153 static inline void q_set_minus_one(rational_t *r) {
154   q_clear(r);
155   r->s.num = -1;
156 }
157 
158 /*
159  * Assignment operations: all set the value of the first argument (r or r1).
160  * - in q_set_int32 and q_set_int64, num/den is normalized first
161  *   (common factors are removed) and den must be non-zero
162  * - in q_set_mpq, q must be canonicalized first
163  *   (a copy of q is made)
164  * - q_set copies r2 into r1 (if r2 is a gmp number,
165  *   then a new gmp number is allocated with the same value
166  *   and assigned to r1)
167  * - q_set_neg assigns the opposite of r2 to r1
168  * - q_set_abs assigns the absolute value of r2 to r1
169  */
170 extern void q_set_int32(rational_t *r, int32_t num, uint32_t den);
171 extern void q_set_int64(rational_t *r, int64_t num, uint64_t den);
172 extern void q_set32(rational_t *r, int32_t num);
173 extern void q_set64(rational_t *r, int64_t num);
174 
175 extern void q_set_mpq(rational_t *r, const mpq_t q);
176 extern void q_set_mpz(rational_t *r, const mpz_t z);
177 extern void q_set(rational_t *r1, const rational_t *r2);
178 extern void q_set_neg(rational_t *r1, const rational_t *r2);
179 extern void q_set_abs(rational_t *r1, const rational_t *r2);
180 
181 /*
182  * Copy r2 into r1: share the gmp index if r2
183  * is a gmp number. Then clear r2.
184  * This can be used without calling q_init(r1).
185  */
q_copy_and_clear(rational_t * r1,rational_t * r2)186 static inline void q_copy_and_clear(rational_t *r1, rational_t *r2) {
187   *r1 = *r2;
188   r2->s.num = 0;
189   r2->s.den = ONE_DEN;
190 }
191 
192 /*
193  * Swap values of r1 and r2
194  */
q_swap(rational_t * r1,rational_t * r2)195 static inline void q_swap(rational_t *r1, rational_t *r2) {
196   rational_t aux;
197 
198   aux = *r1;
199   *r1 = *r2;
200   *r2 = aux;
201 }
202 
203 /*
204  * Copy the numerator or denominator of r2 into r1
205  */
206 extern void q_get_num(rational_t *r1, const rational_t *r2);
207 extern void q_get_den(rational_t *r1, const rational_t *r2);
208 
209 /*
210  * String parsing:
211  * - set_from_string uses the GMP format with base 10:
212  *       <optional_sign> <numerator>/<denominator>
213  *       <optional_sign> <number>
214  *
215  * - set_from_string_base uses the GMP format with base b
216  *
217  * - set_from_float_string uses a floating point format:
218  *   <optional sign> <integer part> . <fractional part>
219  *   <optional sign> <integer part> <exp> <optional sign> <integer>
220  *   <optional sign> <integer part> . <fractional part> <exp> <optional sign> <integer>
221  *
222  * where <optional sign> is + or - or nothing
223  *       <exp> is either 'e' or 'E'
224  *
225  * The functions return -1 if the format is wrong and leave r unchanged.
226  * The functions q_set_from_string and q_set_from_string_base return -2
227  * if the denominator is 0.
228  * Otherwise, the functions return 0 and the parsed value is stored in r.
229  */
230 extern int q_set_from_string(rational_t *r, const char *s);
231 extern int q_set_from_string_base(rational_t *r, const char *s, int32_t b);
232 extern int q_set_from_float_string(rational_t *r, const char *s);
233 
234 /*
235  * ARITHMETIC: ALL OPERATIONS MODIFY THE FIRST ARGUMENT
236  */
237 
238 /*
239  * Arithmetic operations:
240  * - all operate on the first argument:
241  *    q_add: add r2 to r1
242  *    q_sub: subtract r2 from r1
243  *    q_mul: set r1 to r1 * r2
244  *    q_div: set r1 to r1/r2 (r2 must be nonzero)
245  *    q_neg: negate r
246  *    q_inv: invert r (r must be nonzero)
247  *    q_addmul: add r2 * r3 to r1
248  *    q_submul: subtract r2 * r3 from r1
249  *    q_addone: add 1 to r1
250  *    q_subone: subtract 1 from r1
251  * - lcm/gcd operations (r1 and r2 must be integers)
252  *    q_lcm: store lcm(r1, r2) into r1
253  *    q_gcd: store gcd(r1, r2) into r1 (r1 and r2 must not be zero)
254  * - floor and ceiling are also in-place operations:
255  *    q_floor: store largest integer <= r into r
256  *    q_ceil: store smaller integer >= r into r
257  */
258 extern void q_add(rational_t *r1, const rational_t *r2);
259 extern void q_sub(rational_t *r1, const rational_t *r2);
260 extern void q_mul(rational_t *r1, const rational_t *r2);
261 extern void q_div(rational_t *r1, const rational_t *r2);
262 extern void q_neg(rational_t *r);
263 extern void q_inv(rational_t *r);
264 
265 extern void q_addmul(rational_t *r1, const rational_t *r2, const rational_t *r3);
266 extern void q_submul(rational_t *r1, const rational_t *r2, const rational_t *r3);
267 extern void q_add_one(rational_t *r1);
268 extern void q_sub_one(rational_t *r1);
269 
270 extern void q_lcm(rational_t *r1, const rational_t *r2);
271 extern void q_gcd(rational_t *r1, const rational_t *r2);
272 
273 extern void q_floor(rational_t *r);
274 extern void q_ceil(rational_t *r);
275 
276 
277 
278 /*
279  * Exponentiation:
280  * - q_mulexp(r1, r2, n): multiply r1 by r2^n
281  */
282 extern void q_mulexp(rational_t *r1, const rational_t *r2, uint32_t n);
283 
284 
285 /*
286  * Integer division and remainder
287  * - r1 and r2 must both be integer
288  * - r2 must be positive.
289  * - side effect: r2 is normalized
290  *
291  * q_integer_div(r1, r2) stores the quotient of r1 divided by r2 into r1
292  * q_integer_rem(r1, r2) stores the remainder into r1
293  *
294  * This implements the usual definition of division (unlike C).
295  * If r = remainder and q = quotient then we have
296  *    0 <= r < r2 and  r1 = q * r2 + r
297  */
298 extern void q_integer_div(rational_t *r1, rational_t *r2);
299 extern void q_integer_rem(rational_t *r1, rational_t *r2);
300 
301 
302 /*
303  * Generalized LCM: compute the smallest non-negative rational q
304  * such that q/r1 is an integer and q/r2 is an integer.
305  * - r1 and r2 can be arbitrary rationals.
306  * - the result is stored in r1
307  */
308 extern void q_generalized_lcm(rational_t *r1, rational_t *r2);
309 
310 /*
311  * Generalized GCD: compute the largest positive rational q
312  * such that r1/q and r2/q are both integer.
313  * - the result is stored in r2
314  */
315 extern void q_generalized_gcd(rational_t *r1, rational_t *r2);
316 
317 
318 
319 /*
320  * SMT2 Versions of division and mod
321  *
322  * Intended semantics for div and mod:
323  * - if y > 0 then div(x, y) is floor(x/y)
324  * - if y < 0 then div(x, y) is ceil(x/y)
325  * - 0 <= mod(x, y) < y
326  * - x = y * div(x, y) + mod(x, y)
327  * These operations are defined for any x and non-zero y.
328  * The terms x and y are not required to be integers.
329  *
330  * - q_smt2_div(q, x, y) stores (div x y) in q
331  * - q_smt2_mod(q, x, y) stores (mod x y) in q
332  *
333  * For both functions, y must not be zero.
334  */
335 extern void q_smt2_div(rational_t *q, const rational_t *x, const rational_t *y);
336 extern void q_smt2_mod(rational_t *q, const rational_t *x, const rational_t *y);
337 
338 
339 /*
340  * TESTS: DO NOT MODIFY THE ARGUMENT(S)
341  */
342 
343 /*
344  * Sign of r: q_sgn(r) = 0 if r = 0
345  *            q_sgn(r) = +1 if r > 0
346  *            q_sgn(r) = -1 if r < 0
347  */
q_sgn(const rational_t * r)348 static inline int q_sgn(const rational_t *r) {
349   if (is_ratgmp(r)) {
350     return mpq_sgn(get_gmp(r));
351   } else {
352     return (r->s.num < 0 ? -1 : (r->s.num > 0));
353   }
354 }
355 
356 
357 /*
358  * Compare r1 and r2:
359  * - returns a negative number if r1 < r2
360  * - returns 0 if r1 = r2
361  * - returns a positive number if r1 > r2
362  */
363 extern int q_cmp(const rational_t *r1, const rational_t *r2);
364 
365 
366 /*
367  * Compare r1 and num/den
368  * - den must be nonzero
369  * - returns a negative number if r1 < num/den
370  * - returns 0 if r1 = num/den
371  * - returns a positive number if r1 > num/den
372  */
373 extern int q_cmp_int32(const rational_t *r1, int32_t num, uint32_t den);
374 extern int q_cmp_int64(const rational_t *r1, int64_t num, uint64_t den);
375 
376 
377 /*
378  * Variants of q_cmp:
379  * - q_le(r1, r2) is nonzero iff r1 <= r2
380  * - q_lt(r1, r2) is nonzero iff r1 < r2
381  * - q_gt(r1, r2) is nonzero iff r1 > r2
382  * - q_ge(r1, r2) is nonzero iff r1 >= r2
383  * - q_eq(r1, r2) is nonzero iff r1 = r2
384  * - q_neq(r1, r2) is nonzero iff r1 != r2
385  */
q_le(const rational_t * r1,const rational_t * r2)386 static inline bool q_le(const rational_t *r1, const rational_t *r2) {
387   return q_cmp(r1, r2) <= 0;
388 }
389 
q_lt(const rational_t * r1,const rational_t * r2)390 static inline bool q_lt(const rational_t *r1, const rational_t *r2) {
391   return q_cmp(r1, r2) < 0;
392 }
393 
q_ge(const rational_t * r1,const rational_t * r2)394 static inline bool q_ge(const rational_t *r1, const rational_t *r2) {
395   return q_cmp(r1, r2) >= 0;
396 }
397 
q_gt(const rational_t * r1,const rational_t * r2)398 static inline bool q_gt(const rational_t *r1, const rational_t *r2) {
399   return q_cmp(r1, r2) > 0;
400 }
401 
q_eq(const rational_t * r1,const rational_t * r2)402 static inline bool q_eq(const rational_t *r1, const rational_t *r2) {
403   return q_cmp(r1, r2) == 0;
404 }
405 
q_neq(const rational_t * r1,const rational_t * r2)406 static inline bool q_neq(const rational_t *r1, const rational_t *r2) {
407   return q_cmp(r1, r2) != 0;
408 }
409 
410 
411 /*
412  * Check whether r1 and r2 are opposite (i.e., r1 + r2 = 0)
413  */
414 extern bool q_opposite(const rational_t *r1, const rational_t *r2);
415 
416 
417 /*
418  * Tests on rational r
419  */
q_is_zero(const rational_t * r)420 static inline bool q_is_zero(const rational_t *r) {
421   return is_ratgmp(r) ? mpq_is_zero(get_gmp(r)) : r->s.num == 0;
422 }
423 
q_is_nonzero(const rational_t * r)424 static inline bool q_is_nonzero(const rational_t *r) {
425   return is_ratgmp(r) ? mpq_is_nonzero(get_gmp(r)) : r->s.num != 0;
426 }
427 
q_is_one(const rational_t * r)428 static inline bool q_is_one(const rational_t *r) {
429   return (r->s.den == ONE_DEN && r->s.num == 1) ||
430     (is_ratgmp(r) && mpq_is_one(get_gmp(r)));
431 }
432 
q_is_minus_one(const rational_t * r)433 static inline bool q_is_minus_one(const rational_t *r) {
434   return (r->s.den == ONE_DEN && r->s.num == -1) ||
435     (is_ratgmp(r) && mpq_is_minus_one(get_gmp(r)));
436 }
437 
q_is_pos(const rational_t * r)438 static inline bool q_is_pos(const rational_t *r) {
439   return (is_rat32(r) ?  r->s.num > 0 : mpq_is_pos(get_gmp(r)));
440 }
441 
q_is_nonneg(const rational_t * r)442 static inline bool q_is_nonneg(const rational_t *r) {
443   return (is_rat32(r) ?  r->s.num >= 0 : mpq_is_nonneg(get_gmp(r)));
444 }
445 
q_is_neg(const rational_t * r)446 static inline bool q_is_neg(const rational_t *r) {
447   return (is_rat32(r) ?  r->s.num < 0 : mpq_is_neg(get_gmp(r)));
448 }
449 
q_is_nonpos(const rational_t * r)450 static inline bool q_is_nonpos(const rational_t *r) {
451   return (is_rat32(r) ?  r->s.num <= 0 : mpq_is_nonpos(get_gmp(r)));
452 }
453 
q_is_integer(const rational_t * r)454 static inline bool q_is_integer(const rational_t *r) {
455   return (is_rat32(r) && r->s.den == ONE_DEN) || (is_ratgmp(r) && mpq_is_integer(get_gmp(r)));
456 }
457 
458 
459 
460 /*
461  * DIVISIBILITY TESTS
462  */
463 
464 /*
465  * Check whether r1 divides r2: both must be integers
466  * - r1 must be non-zero
467  * - side effect: r1 is normalized
468  */
469 extern bool q_integer_divides(rational_t *r1, const rational_t *r2);
470 
471 
472 /*
473  * General divisibility check: return true iff r2/r1 is an integer
474  * - r1 must be non-zero
475  */
476 extern bool q_divides(const rational_t *r1, const rational_t *r2);
477 
478 
479 /*
480  * SMT2 version:
481  * - if t1 is non-zero, return true iff (r2/r1) is an integer
482  * - if t1 is zero, return true iff r2 is zero
483  */
484 extern bool q_smt2_divides(const rational_t *r1, const rational_t *r2);
485 
486 
487 
488 
489 /*
490  * CONVERSIONS TO INTEGERS
491  */
492 
493 /*
494  * Check whether r is a small integer (use with care: this
495  * ignores the case where r is a small integer that happens
496  * to be represented as a gmp rational).
497  * Call q_normalize(r) first if there's a doubt.
498  */
q_is_smallint(rational_t * r)499 static inline bool q_is_smallint(rational_t *r) {
500   return r->s.den == ONE_DEN;
501 }
502 
503 /*
504  * Convert r to an integer, provided q_is_smallint(r) is true
505  */
q_get_smallint(rational_t * r)506 static inline int32_t q_get_smallint(rational_t *r) {
507   return get_num(r);
508 }
509 
510 
511 /*
512  * Conversions: all functions attempt to convert r into an integer or
513  * a pair of integers (num/den). If the conversion is not possible
514  * the functions return false. Otherwise, the result is true and the
515  * value is returned in v or num/den.
516  */
517 extern bool q_get32(rational_t *r, int32_t *v);
518 extern bool q_get64(rational_t *r, int64_t *v);
519 extern bool q_get_int32(rational_t *r, int32_t *num, uint32_t *den);
520 extern bool q_get_int64(rational_t *r, int64_t *num, uint64_t *den);
521 
522 
523 /*
524  * Similar to the conversion functions above but just check
525  * whether the conversions are possible.
526  */
527 extern bool q_is_int32(rational_t *r);   // r is a/1 where a is int32
528 extern bool q_is_int64(rational_t *r);   // r is a/1 where a is int64
529 extern bool q_fits_int32(rational_t *r); // r is a/b where a is int32, b is uint32
530 extern bool q_fits_int64(rational_t *r); // r is a/b where a is int64, b is uint64
531 
532 
533 
534 /*
535  * Size estimate
536  * - this returns approximately the number of bits to represent r's numerator
537  * - this may not be exact (typically rounded up to a multiple of 32)
538  * - also if r is really really big, this function may return
539  *   UINT32_MAX (not very likely!)
540  */
541 extern uint32_t q_size(rational_t *r);
542 
543 
544 /*
545  * CONVERSION TO GMP OBJECTS
546  */
547 
548 /*
549  * Store r into the GMP integer z.
550  * - return false if r is not a integer, true otherwise
551  */
552 extern bool q_get_mpz(rational_t *r, mpz_t z);
553 
554 
555 /*
556  * Store r into q
557  */
558 extern void q_get_mpq(rational_t *r, mpq_t q);
559 
560 
561 /*
562  * Convert to a floating point number
563  */
564 extern double q_get_double(rational_t *r);
565 
566 
567 
568 /*
569  * PRINT
570  */
571 
572 /*
573  * Print r on stream f.
574  * q_print_abs prints the absolute value
575  */
576 extern void q_print(FILE *f, const rational_t *r);
577 extern void q_print_abs(FILE *f, const rational_t *r);
578 
579 
580 /*
581  * HASH FUNCTION
582  */
583 
584 /*
585  * Hash functions: return a hash of numerator or denominator.
586  * - hash_numerator(r) = numerator MOD bigprime
587  * - hash_denominator(r) = denominator MOD bigprime
588  * where bigprime is the largest prime number smaller than 2^32.
589  */
590 extern uint32_t q_hash_numerator(const rational_t *r);
591 extern uint32_t q_hash_denominator(const rational_t *r);
592 extern void q_hash_decompose(const rational_t *r, uint32_t *h_num, uint32_t *h_den);
593 
594 
595 
596 
597 /*
598  * RATIONAL ARRAYS
599  */
600 
601 #define MAX_RATIONAL_ARRAY_SIZE (UINT32_MAX/sizeof(rational_t))
602 
603 /*
604  * Create and initialize an array of n rationals.
605  */
606 extern rational_t *new_rational_array(uint32_t n);
607 
608 /*
609  * Delete an array created by the previous function
610  * - n must be the size of a
611  */
612 extern void free_rational_array(rational_t *a, uint32_t n);
613 
614 
615 
616 
617 
618 #endif /* __RATIONALS_H */
619