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