isl_val_gcdext: revert to open-coded version of isl_int_gcdext
[isl.git] / isl_val.c
blob38b4c9752d201d0a1e87b996da03a9fd776ab1f6
1 /*
2 * Copyright 2013 Ecole Normale Superieure
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege,
7 * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
8 */
10 #include <isl_int.h>
11 #include <isl_ctx_private.h>
12 #include <isl_val_private.h>
14 #undef BASE
15 #define BASE val
17 #include <isl_list_templ.c>
19 /* Allocate an isl_val object with indeterminate value.
21 __isl_give isl_val *isl_val_alloc(isl_ctx *ctx)
23 isl_val *v;
25 v = isl_alloc_type(ctx, struct isl_val);
26 if (!v)
27 return NULL;
29 v->ctx = ctx;
30 isl_ctx_ref(ctx);
31 v->ref = 1;
32 isl_int_init(v->n);
33 isl_int_init(v->d);
35 return v;
38 /* Return a reference to an isl_val representing zero.
40 __isl_give isl_val *isl_val_zero(isl_ctx *ctx)
42 return isl_val_int_from_si(ctx, 0);
45 /* Return a reference to an isl_val representing one.
47 __isl_give isl_val *isl_val_one(isl_ctx *ctx)
49 return isl_val_int_from_si(ctx, 1);
52 /* Return a reference to an isl_val representing negative one.
54 __isl_give isl_val *isl_val_negone(isl_ctx *ctx)
56 return isl_val_int_from_si(ctx, -1);
59 /* Return a reference to an isl_val representing NaN.
61 __isl_give isl_val *isl_val_nan(isl_ctx *ctx)
63 isl_val *v;
65 v = isl_val_alloc(ctx);
66 if (!v)
67 return NULL;
69 isl_int_set_si(v->n, 0);
70 isl_int_set_si(v->d, 0);
72 return v;
75 /* Change "v" into a NaN.
77 __isl_give isl_val *isl_val_set_nan(__isl_take isl_val *v)
79 if (!v)
80 return NULL;
81 if (isl_val_is_nan(v))
82 return v;
83 v = isl_val_cow(v);
84 if (!v)
85 return NULL;
87 isl_int_set_si(v->n, 0);
88 isl_int_set_si(v->d, 0);
90 return v;
93 /* Return a reference to an isl_val representing +infinity.
95 __isl_give isl_val *isl_val_infty(isl_ctx *ctx)
97 isl_val *v;
99 v = isl_val_alloc(ctx);
100 if (!v)
101 return NULL;
103 isl_int_set_si(v->n, 1);
104 isl_int_set_si(v->d, 0);
106 return v;
109 /* Return a reference to an isl_val representing -infinity.
111 __isl_give isl_val *isl_val_neginfty(isl_ctx *ctx)
113 isl_val *v;
115 v = isl_val_alloc(ctx);
116 if (!v)
117 return NULL;
119 isl_int_set_si(v->n, -1);
120 isl_int_set_si(v->d, 0);
122 return v;
125 /* Return a reference to an isl_val representing the integer "i".
127 __isl_give isl_val *isl_val_int_from_si(isl_ctx *ctx, long i)
129 isl_val *v;
131 v = isl_val_alloc(ctx);
132 if (!v)
133 return NULL;
135 isl_int_set_si(v->n, i);
136 isl_int_set_si(v->d, 1);
138 return v;
141 /* Change the value of "v" to be equal to the integer "i".
143 __isl_give isl_val *isl_val_set_si(__isl_take isl_val *v, long i)
145 if (!v)
146 return NULL;
147 if (isl_val_is_int(v) && isl_int_cmp_si(v->n, i) == 0)
148 return v;
149 v = isl_val_cow(v);
150 if (!v)
151 return NULL;
153 isl_int_set_si(v->n, i);
154 isl_int_set_si(v->d, 1);
156 return v;
159 /* Change the value of "v" to be equal to zero.
161 __isl_give isl_val *isl_val_set_zero(__isl_take isl_val *v)
163 return isl_val_set_si(v, 0);
166 /* Return a reference to an isl_val representing the unsigned integer "u".
168 __isl_give isl_val *isl_val_int_from_ui(isl_ctx *ctx, unsigned long u)
170 isl_val *v;
172 v = isl_val_alloc(ctx);
173 if (!v)
174 return NULL;
176 isl_int_set_ui(v->n, u);
177 isl_int_set_si(v->d, 1);
179 return v;
182 /* Return a reference to an isl_val representing the integer "n".
184 __isl_give isl_val *isl_val_int_from_isl_int(isl_ctx *ctx, isl_int n)
186 isl_val *v;
188 v = isl_val_alloc(ctx);
189 if (!v)
190 return NULL;
192 isl_int_set(v->n, n);
193 isl_int_set_si(v->d, 1);
195 return v;
198 /* Return a reference to an isl_val representing the rational value "n"/"d".
199 * Normalizing the isl_val (if needed) is left to the caller.
201 __isl_give isl_val *isl_val_rat_from_isl_int(isl_ctx *ctx,
202 isl_int n, isl_int d)
204 isl_val *v;
206 v = isl_val_alloc(ctx);
207 if (!v)
208 return NULL;
210 isl_int_set(v->n, n);
211 isl_int_set(v->d, d);
213 return v;
216 /* Return a new reference to "v".
218 __isl_give isl_val *isl_val_copy(__isl_keep isl_val *v)
220 if (!v)
221 return NULL;
223 v->ref++;
224 return v;
227 /* Return a fresh copy of "val".
229 __isl_give isl_val *isl_val_dup(__isl_keep isl_val *val)
231 isl_val *dup;
233 if (!val)
234 return NULL;
236 dup = isl_val_alloc(isl_val_get_ctx(val));
237 if (!dup)
238 return NULL;
240 isl_int_set(dup->n, val->n);
241 isl_int_set(dup->d, val->d);
243 return dup;
246 /* Return an isl_val that is equal to "val" and that has only
247 * a single reference.
249 __isl_give isl_val *isl_val_cow(__isl_take isl_val *val)
251 if (!val)
252 return NULL;
254 if (val->ref == 1)
255 return val;
256 val->ref--;
257 return isl_val_dup(val);
260 /* Free "v" and return NULL.
262 __isl_null isl_val *isl_val_free(__isl_take isl_val *v)
264 if (!v)
265 return NULL;
267 if (--v->ref > 0)
268 return NULL;
270 isl_ctx_deref(v->ctx);
271 isl_int_clear(v->n);
272 isl_int_clear(v->d);
273 free(v);
274 return NULL;
277 /* Extract the numerator of a rational value "v" as an integer.
279 * If "v" is not a rational value, then the result is undefined.
281 long isl_val_get_num_si(__isl_keep isl_val *v)
283 if (!v)
284 return 0;
285 if (!isl_val_is_rat(v))
286 isl_die(isl_val_get_ctx(v), isl_error_invalid,
287 "expecting rational value", return 0);
288 if (!isl_int_fits_slong(v->n))
289 isl_die(isl_val_get_ctx(v), isl_error_invalid,
290 "numerator too large", return 0);
291 return isl_int_get_si(v->n);
294 /* Extract the numerator of a rational value "v" as an isl_int.
296 * If "v" is not a rational value, then the result is undefined.
298 int isl_val_get_num_isl_int(__isl_keep isl_val *v, isl_int *n)
300 if (!v)
301 return -1;
302 if (!isl_val_is_rat(v))
303 isl_die(isl_val_get_ctx(v), isl_error_invalid,
304 "expecting rational value", return -1);
305 isl_int_set(*n, v->n);
306 return 0;
309 /* Extract the denominator of a rational value "v" as an integer.
311 * If "v" is not a rational value, then the result is undefined.
313 long isl_val_get_den_si(__isl_keep isl_val *v)
315 if (!v)
316 return 0;
317 if (!isl_val_is_rat(v))
318 isl_die(isl_val_get_ctx(v), isl_error_invalid,
319 "expecting rational value", return 0);
320 if (!isl_int_fits_slong(v->d))
321 isl_die(isl_val_get_ctx(v), isl_error_invalid,
322 "denominator too large", return 0);
323 return isl_int_get_si(v->d);
326 /* Return an approximation of "v" as a double.
328 double isl_val_get_d(__isl_keep isl_val *v)
330 if (!v)
331 return 0;
332 if (!isl_val_is_rat(v))
333 isl_die(isl_val_get_ctx(v), isl_error_invalid,
334 "expecting rational value", return 0);
335 return isl_int_get_d(v->n) / isl_int_get_d(v->d);
338 /* Return the isl_ctx to which "val" belongs.
340 isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val)
342 return val ? val->ctx : NULL;
345 /* Normalize "v".
347 * In particular, make sure that the denominator of a rational value
348 * is positive and the numerator and denominator do not have any
349 * common divisors.
351 * This function should not be called by an external user
352 * since it will only be given normalized values.
354 __isl_give isl_val *isl_val_normalize(__isl_take isl_val *v)
356 isl_ctx *ctx;
358 if (!v)
359 return NULL;
360 if (isl_val_is_int(v))
361 return v;
362 if (!isl_val_is_rat(v))
363 return v;
364 if (isl_int_is_neg(v->d)) {
365 isl_int_neg(v->d, v->d);
366 isl_int_neg(v->n, v->n);
368 ctx = isl_val_get_ctx(v);
369 isl_int_gcd(ctx->normalize_gcd, v->n, v->d);
370 if (isl_int_is_one(ctx->normalize_gcd))
371 return v;
372 isl_int_divexact(v->n, v->n, ctx->normalize_gcd);
373 isl_int_divexact(v->d, v->d, ctx->normalize_gcd);
374 return v;
377 /* Return the opposite of "v".
379 __isl_give isl_val *isl_val_neg(__isl_take isl_val *v)
381 if (!v)
382 return NULL;
383 if (isl_val_is_nan(v))
384 return v;
385 if (isl_val_is_zero(v))
386 return v;
388 v = isl_val_cow(v);
389 if (!v)
390 return NULL;
391 isl_int_neg(v->n, v->n);
393 return v;
396 /* Return the absolute value of "v".
398 __isl_give isl_val *isl_val_abs(__isl_take isl_val *v)
400 if (!v)
401 return NULL;
402 if (isl_val_is_nan(v))
403 return v;
404 if (isl_val_is_nonneg(v))
405 return v;
406 return isl_val_neg(v);
409 /* Return the "floor" (greatest integer part) of "v".
410 * That is, return the result of rounding towards -infinity.
412 __isl_give isl_val *isl_val_floor(__isl_take isl_val *v)
414 if (!v)
415 return NULL;
416 if (isl_val_is_int(v))
417 return v;
418 if (!isl_val_is_rat(v))
419 return v;
421 v = isl_val_cow(v);
422 if (!v)
423 return NULL;
424 isl_int_fdiv_q(v->n, v->n, v->d);
425 isl_int_set_si(v->d, 1);
427 return v;
430 /* Return the "ceiling" of "v".
431 * That is, return the result of rounding towards +infinity.
433 __isl_give isl_val *isl_val_ceil(__isl_take isl_val *v)
435 if (!v)
436 return NULL;
437 if (isl_val_is_int(v))
438 return v;
439 if (!isl_val_is_rat(v))
440 return v;
442 v = isl_val_cow(v);
443 if (!v)
444 return NULL;
445 isl_int_cdiv_q(v->n, v->n, v->d);
446 isl_int_set_si(v->d, 1);
448 return v;
451 /* Truncate "v".
452 * That is, return the result of rounding towards zero.
454 __isl_give isl_val *isl_val_trunc(__isl_take isl_val *v)
456 if (!v)
457 return NULL;
458 if (isl_val_is_int(v))
459 return v;
460 if (!isl_val_is_rat(v))
461 return v;
463 v = isl_val_cow(v);
464 if (!v)
465 return NULL;
466 isl_int_tdiv_q(v->n, v->n, v->d);
467 isl_int_set_si(v->d, 1);
469 return v;
472 /* Return 2^v, where v is an integer (that is not too large).
474 __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v)
476 unsigned long exp;
477 int neg;
479 v = isl_val_cow(v);
480 if (!v)
481 return NULL;
482 if (!isl_val_is_int(v))
483 isl_die(isl_val_get_ctx(v), isl_error_invalid,
484 "can only compute integer powers",
485 return isl_val_free(v));
486 neg = isl_val_is_neg(v);
487 if (neg)
488 isl_int_neg(v->n, v->n);
489 if (!isl_int_fits_ulong(v->n))
490 isl_die(isl_val_get_ctx(v), isl_error_invalid,
491 "exponent too large", return isl_val_free(v));
492 exp = isl_int_get_ui(v->n);
493 if (neg) {
494 isl_int_mul_2exp(v->d, v->d, exp);
495 isl_int_set_si(v->n, 1);
496 } else {
497 isl_int_mul_2exp(v->n, v->d, exp);
500 return v;
503 /* Return the minimum of "v1" and "v2".
505 __isl_give isl_val *isl_val_min(__isl_take isl_val *v1, __isl_take isl_val *v2)
507 if (!v1 || !v2)
508 goto error;
510 if (isl_val_is_nan(v1)) {
511 isl_val_free(v2);
512 return v1;
514 if (isl_val_is_nan(v2)) {
515 isl_val_free(v1);
516 return v2;
518 if (isl_val_le(v1, v2)) {
519 isl_val_free(v2);
520 return v1;
521 } else {
522 isl_val_free(v1);
523 return v2;
525 error:
526 isl_val_free(v1);
527 isl_val_free(v2);
528 return NULL;
531 /* Return the maximum of "v1" and "v2".
533 __isl_give isl_val *isl_val_max(__isl_take isl_val *v1, __isl_take isl_val *v2)
535 if (!v1 || !v2)
536 goto error;
538 if (isl_val_is_nan(v1)) {
539 isl_val_free(v2);
540 return v1;
542 if (isl_val_is_nan(v2)) {
543 isl_val_free(v1);
544 return v2;
546 if (isl_val_ge(v1, v2)) {
547 isl_val_free(v2);
548 return v1;
549 } else {
550 isl_val_free(v1);
551 return v2;
553 error:
554 isl_val_free(v1);
555 isl_val_free(v2);
556 return NULL;
559 /* Return the sum of "v1" and "v2".
561 __isl_give isl_val *isl_val_add(__isl_take isl_val *v1, __isl_take isl_val *v2)
563 if (!v1 || !v2)
564 goto error;
565 if (isl_val_is_nan(v1)) {
566 isl_val_free(v2);
567 return v1;
569 if (isl_val_is_nan(v2)) {
570 isl_val_free(v1);
571 return v2;
573 if ((isl_val_is_infty(v1) && isl_val_is_neginfty(v2)) ||
574 (isl_val_is_neginfty(v1) && isl_val_is_infty(v2))) {
575 isl_val_free(v2);
576 return isl_val_set_nan(v1);
578 if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
579 isl_val_free(v2);
580 return v1;
582 if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
583 isl_val_free(v1);
584 return v2;
586 if (isl_val_is_zero(v1)) {
587 isl_val_free(v1);
588 return v2;
590 if (isl_val_is_zero(v2)) {
591 isl_val_free(v2);
592 return v1;
595 v1 = isl_val_cow(v1);
596 if (!v1)
597 goto error;
598 if (isl_val_is_int(v1) && isl_val_is_int(v2))
599 isl_int_add(v1->n, v1->n, v2->n);
600 else {
601 if (isl_int_eq(v1->d, v2->d))
602 isl_int_add(v1->n, v1->n, v2->n);
603 else {
604 isl_int_mul(v1->n, v1->n, v2->d);
605 isl_int_addmul(v1->n, v2->n, v1->d);
606 isl_int_mul(v1->d, v1->d, v2->d);
608 v1 = isl_val_normalize(v1);
610 isl_val_free(v2);
611 return v1;
612 error:
613 isl_val_free(v1);
614 isl_val_free(v2);
615 return NULL;
618 /* Return the sum of "v1" and "v2".
620 __isl_give isl_val *isl_val_add_ui(__isl_take isl_val *v1, unsigned long v2)
622 if (!v1)
623 return NULL;
624 if (!isl_val_is_rat(v1))
625 return v1;
626 if (v2 == 0)
627 return v1;
628 v1 = isl_val_cow(v1);
629 if (!v1)
630 return NULL;
632 isl_int_addmul_ui(v1->n, v1->d, v2);
634 return v1;
637 /* Subtract "v2" from "v1".
639 __isl_give isl_val *isl_val_sub(__isl_take isl_val *v1, __isl_take isl_val *v2)
641 if (!v1 || !v2)
642 goto error;
643 if (isl_val_is_nan(v1)) {
644 isl_val_free(v2);
645 return v1;
647 if (isl_val_is_nan(v2)) {
648 isl_val_free(v1);
649 return v2;
651 if ((isl_val_is_infty(v1) && isl_val_is_infty(v2)) ||
652 (isl_val_is_neginfty(v1) && isl_val_is_neginfty(v2))) {
653 isl_val_free(v2);
654 return isl_val_set_nan(v1);
656 if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
657 isl_val_free(v2);
658 return v1;
660 if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
661 isl_val_free(v1);
662 return isl_val_neg(v2);
664 if (isl_val_is_zero(v2)) {
665 isl_val_free(v2);
666 return v1;
668 if (isl_val_is_zero(v1)) {
669 isl_val_free(v1);
670 return isl_val_neg(v2);
673 v1 = isl_val_cow(v1);
674 if (!v1)
675 goto error;
676 if (isl_val_is_int(v1) && isl_val_is_int(v2))
677 isl_int_sub(v1->n, v1->n, v2->n);
678 else {
679 if (isl_int_eq(v1->d, v2->d))
680 isl_int_sub(v1->n, v1->n, v2->n);
681 else {
682 isl_int_mul(v1->n, v1->n, v2->d);
683 isl_int_submul(v1->n, v2->n, v1->d);
684 isl_int_mul(v1->d, v1->d, v2->d);
686 v1 = isl_val_normalize(v1);
688 isl_val_free(v2);
689 return v1;
690 error:
691 isl_val_free(v1);
692 isl_val_free(v2);
693 return NULL;
696 /* Subtract "v2" from "v1".
698 __isl_give isl_val *isl_val_sub_ui(__isl_take isl_val *v1, unsigned long v2)
700 if (!v1)
701 return NULL;
702 if (!isl_val_is_rat(v1))
703 return v1;
704 if (v2 == 0)
705 return v1;
706 v1 = isl_val_cow(v1);
707 if (!v1)
708 return NULL;
710 isl_int_submul_ui(v1->n, v1->d, v2);
712 return v1;
715 /* Return the product of "v1" and "v2".
717 __isl_give isl_val *isl_val_mul(__isl_take isl_val *v1, __isl_take isl_val *v2)
719 if (!v1 || !v2)
720 goto error;
721 if (isl_val_is_nan(v1)) {
722 isl_val_free(v2);
723 return v1;
725 if (isl_val_is_nan(v2)) {
726 isl_val_free(v1);
727 return v2;
729 if ((!isl_val_is_rat(v1) && isl_val_is_zero(v2)) ||
730 (isl_val_is_zero(v1) && !isl_val_is_rat(v2))) {
731 isl_val_free(v2);
732 return isl_val_set_nan(v1);
734 if (isl_val_is_zero(v1)) {
735 isl_val_free(v2);
736 return v1;
738 if (isl_val_is_zero(v2)) {
739 isl_val_free(v1);
740 return v2;
742 if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
743 if (isl_val_is_neg(v2))
744 v1 = isl_val_neg(v1);
745 isl_val_free(v2);
746 return v1;
748 if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
749 if (isl_val_is_neg(v1))
750 v2 = isl_val_neg(v2);
751 isl_val_free(v1);
752 return v2;
755 v1 = isl_val_cow(v1);
756 if (!v1)
757 goto error;
758 if (isl_val_is_int(v1) && isl_val_is_int(v2))
759 isl_int_mul(v1->n, v1->n, v2->n);
760 else {
761 isl_int_mul(v1->n, v1->n, v2->n);
762 isl_int_mul(v1->d, v1->d, v2->d);
763 v1 = isl_val_normalize(v1);
765 isl_val_free(v2);
766 return v1;
767 error:
768 isl_val_free(v1);
769 isl_val_free(v2);
770 return NULL;
773 /* Return the product of "v1" and "v2".
775 * This is a private copy of isl_val_mul for use in the generic
776 * isl_multi_*_scale_val instantiated for isl_val.
778 __isl_give isl_val *isl_val_scale_val(__isl_take isl_val *v1,
779 __isl_take isl_val *v2)
781 return isl_val_mul(v1, v2);
784 /* Return the product of "v1" and "v2".
786 __isl_give isl_val *isl_val_mul_ui(__isl_take isl_val *v1, unsigned long v2)
788 if (!v1)
789 return NULL;
790 if (isl_val_is_nan(v1))
791 return v1;
792 if (!isl_val_is_rat(v1)) {
793 if (v2 == 0)
794 v1 = isl_val_set_nan(v1);
795 return v1;
797 if (v2 == 1)
798 return v1;
799 v1 = isl_val_cow(v1);
800 if (!v1)
801 return NULL;
803 isl_int_mul_ui(v1->n, v1->n, v2);
805 return isl_val_normalize(v1);
808 /* Divide "v1" by "v2".
810 __isl_give isl_val *isl_val_div(__isl_take isl_val *v1, __isl_take isl_val *v2)
812 if (!v1 || !v2)
813 goto error;
814 if (isl_val_is_nan(v1)) {
815 isl_val_free(v2);
816 return v1;
818 if (isl_val_is_nan(v2)) {
819 isl_val_free(v1);
820 return v2;
822 if (isl_val_is_zero(v2) ||
823 (!isl_val_is_rat(v1) && !isl_val_is_rat(v2))) {
824 isl_val_free(v2);
825 return isl_val_set_nan(v1);
827 if (isl_val_is_zero(v1)) {
828 isl_val_free(v2);
829 return v1;
831 if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
832 if (isl_val_is_neg(v2))
833 v1 = isl_val_neg(v1);
834 isl_val_free(v2);
835 return v1;
837 if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
838 isl_val_free(v2);
839 return isl_val_set_zero(v1);
842 v1 = isl_val_cow(v1);
843 if (!v1)
844 goto error;
845 if (isl_val_is_int(v2)) {
846 isl_int_mul(v1->d, v1->d, v2->n);
847 v1 = isl_val_normalize(v1);
848 } else {
849 isl_int_mul(v1->d, v1->d, v2->n);
850 isl_int_mul(v1->n, v1->n, v2->d);
851 v1 = isl_val_normalize(v1);
853 isl_val_free(v2);
854 return v1;
855 error:
856 isl_val_free(v1);
857 isl_val_free(v2);
858 return NULL;
861 /* Divide "v1" by "v2".
863 * This is a private copy of isl_val_div for use in the generic
864 * isl_multi_*_scale_down_val instantiated for isl_val.
866 __isl_give isl_val *isl_val_scale_down_val(__isl_take isl_val *v1,
867 __isl_take isl_val *v2)
869 return isl_val_div(v1, v2);
872 /* Given two integer values "v1" and "v2", check if "v1" is divisible by "v2".
874 int isl_val_is_divisible_by(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
876 if (!v1 || !v2)
877 return -1;
879 if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
880 isl_die(isl_val_get_ctx(v1), isl_error_invalid,
881 "expecting two integers", return -1);
883 return isl_int_is_divisible_by(v1->n, v2->n);
886 /* Given two integer values "v1" and "v2", return the residue of "v1"
887 * modulo "v2".
889 __isl_give isl_val *isl_val_mod(__isl_take isl_val *v1, __isl_take isl_val *v2)
891 if (!v1 || !v2)
892 goto error;
893 if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
894 isl_die(isl_val_get_ctx(v1), isl_error_invalid,
895 "expecting two integers", goto error);
896 if (isl_val_is_nonneg(v1) && isl_val_lt(v1, v2)) {
897 isl_val_free(v2);
898 return v1;
900 v1 = isl_val_cow(v1);
901 if (!v1)
902 goto error;
903 isl_int_fdiv_r(v1->n, v1->n, v2->n);
904 isl_val_free(v2);
905 return v1;
906 error:
907 isl_val_free(v1);
908 isl_val_free(v2);
909 return NULL;
912 /* Given two integer values, return their greatest common divisor.
914 __isl_give isl_val *isl_val_gcd(__isl_take isl_val *v1, __isl_take isl_val *v2)
916 if (!v1 || !v2)
917 goto error;
918 if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
919 isl_die(isl_val_get_ctx(v1), isl_error_invalid,
920 "expecting two integers", goto error);
921 if (isl_val_eq(v1, v2)) {
922 isl_val_free(v2);
923 return v1;
925 if (isl_val_is_one(v1)) {
926 isl_val_free(v2);
927 return v1;
929 if (isl_val_is_one(v2)) {
930 isl_val_free(v1);
931 return v2;
933 v1 = isl_val_cow(v1);
934 if (!v1)
935 goto error;
936 isl_int_gcd(v1->n, v1->n, v2->n);
937 isl_val_free(v2);
938 return v1;
939 error:
940 isl_val_free(v1);
941 isl_val_free(v2);
942 return NULL;
945 /* Compute x, y and g such that g = gcd(a,b) and a*x+b*y = g.
947 static void isl_int_gcdext(isl_int g, isl_int x, isl_int y,
948 isl_int a, isl_int b)
950 isl_int d, tmp;
951 isl_int a_copy, b_copy;
953 isl_int_init(a_copy);
954 isl_int_init(b_copy);
955 isl_int_init(d);
956 isl_int_init(tmp);
957 isl_int_set(a_copy, a);
958 isl_int_set(b_copy, b);
959 isl_int_abs(g, a_copy);
960 isl_int_abs(d, b_copy);
961 isl_int_set_si(x, 1);
962 isl_int_set_si(y, 0);
963 while (isl_int_is_pos(d)) {
964 isl_int_fdiv_q(tmp, g, d);
965 isl_int_submul(x, tmp, y);
966 isl_int_submul(g, tmp, d);
967 isl_int_swap(g, d);
968 isl_int_swap(x, y);
970 if (isl_int_is_zero(a_copy))
971 isl_int_set_si(x, 0);
972 else if (isl_int_is_neg(a_copy))
973 isl_int_neg(x, x);
974 if (isl_int_is_zero(b_copy))
975 isl_int_set_si(y, 0);
976 else {
977 isl_int_mul(tmp, a_copy, x);
978 isl_int_sub(tmp, g, tmp);
979 isl_int_divexact(y, tmp, b_copy);
981 isl_int_clear(d);
982 isl_int_clear(tmp);
983 isl_int_clear(a_copy);
984 isl_int_clear(b_copy);
987 /* Given two integer values v1 and v2, return their greatest common divisor g,
988 * as well as two integers x and y such that x * v1 + y * v2 = g.
990 __isl_give isl_val *isl_val_gcdext(__isl_take isl_val *v1,
991 __isl_take isl_val *v2, __isl_give isl_val **x, __isl_give isl_val **y)
993 isl_ctx *ctx;
994 isl_val *a = NULL, *b = NULL;
996 if (!x && !y)
997 return isl_val_gcd(v1, v2);
999 if (!v1 || !v2)
1000 goto error;
1002 ctx = isl_val_get_ctx(v1);
1003 if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
1004 isl_die(ctx, isl_error_invalid,
1005 "expecting two integers", goto error);
1007 v1 = isl_val_cow(v1);
1008 a = isl_val_alloc(ctx);
1009 b = isl_val_alloc(ctx);
1010 if (!v1 || !a || !b)
1011 goto error;
1012 isl_int_gcdext(v1->n, a->n, b->n, v1->n, v2->n);
1013 if (x) {
1014 isl_int_set_si(a->d, 1);
1015 *x = a;
1016 } else
1017 isl_val_free(a);
1018 if (y) {
1019 isl_int_set_si(b->d, 1);
1020 *y = b;
1021 } else
1022 isl_val_free(b);
1023 isl_val_free(v2);
1024 return v1;
1025 error:
1026 isl_val_free(v1);
1027 isl_val_free(v2);
1028 isl_val_free(a);
1029 isl_val_free(b);
1030 if (x)
1031 *x = NULL;
1032 if (y)
1033 *y = NULL;
1034 return NULL;
1037 /* Does "v" represent an integer value?
1039 int isl_val_is_int(__isl_keep isl_val *v)
1041 if (!v)
1042 return -1;
1044 return isl_int_is_one(v->d);
1047 /* Does "v" represent a rational value?
1049 int isl_val_is_rat(__isl_keep isl_val *v)
1051 if (!v)
1052 return -1;
1054 return !isl_int_is_zero(v->d);
1057 /* Does "v" represent NaN?
1059 int isl_val_is_nan(__isl_keep isl_val *v)
1061 if (!v)
1062 return -1;
1064 return isl_int_is_zero(v->n) && isl_int_is_zero(v->d);
1067 /* Does "v" represent +infinity?
1069 int isl_val_is_infty(__isl_keep isl_val *v)
1071 if (!v)
1072 return -1;
1074 return isl_int_is_pos(v->n) && isl_int_is_zero(v->d);
1077 /* Does "v" represent -infinity?
1079 int isl_val_is_neginfty(__isl_keep isl_val *v)
1081 if (!v)
1082 return -1;
1084 return isl_int_is_neg(v->n) && isl_int_is_zero(v->d);
1087 /* Does "v" represent the integer zero?
1089 int isl_val_is_zero(__isl_keep isl_val *v)
1091 if (!v)
1092 return -1;
1094 return isl_int_is_zero(v->n) && !isl_int_is_zero(v->d);
1097 /* Does "v" represent the integer one?
1099 int isl_val_is_one(__isl_keep isl_val *v)
1101 if (!v)
1102 return -1;
1104 return isl_int_eq(v->n, v->d);
1107 /* Does "v" represent the integer negative one?
1109 int isl_val_is_negone(__isl_keep isl_val *v)
1111 if (!v)
1112 return -1;
1114 return isl_int_is_neg(v->n) && isl_int_abs_eq(v->n, v->d);
1117 /* Is "v" (strictly) positive?
1119 int isl_val_is_pos(__isl_keep isl_val *v)
1121 if (!v)
1122 return -1;
1124 return isl_int_is_pos(v->n);
1127 /* Is "v" (strictly) negative?
1129 int isl_val_is_neg(__isl_keep isl_val *v)
1131 if (!v)
1132 return -1;
1134 return isl_int_is_neg(v->n);
1137 /* Is "v" non-negative?
1139 int isl_val_is_nonneg(__isl_keep isl_val *v)
1141 if (!v)
1142 return -1;
1144 if (isl_val_is_nan(v))
1145 return 0;
1147 return isl_int_is_nonneg(v->n);
1150 /* Is "v" non-positive?
1152 int isl_val_is_nonpos(__isl_keep isl_val *v)
1154 if (!v)
1155 return -1;
1157 if (isl_val_is_nan(v))
1158 return 0;
1160 return isl_int_is_nonpos(v->n);
1163 /* Return the sign of "v".
1165 * The sign of NaN is undefined.
1167 int isl_val_sgn(__isl_keep isl_val *v)
1169 if (!v)
1170 return 0;
1171 if (isl_val_is_zero(v))
1172 return 0;
1173 if (isl_val_is_pos(v))
1174 return 1;
1175 return -1;
1178 /* Is "v1" (strictly) less than "v2"?
1180 int isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1182 isl_int t;
1183 int lt;
1185 if (!v1 || !v2)
1186 return -1;
1187 if (isl_val_is_int(v1) && isl_val_is_int(v2))
1188 return isl_int_lt(v1->n, v2->n);
1189 if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
1190 return 0;
1191 if (isl_val_eq(v1, v2))
1192 return 0;
1193 if (isl_val_is_infty(v2))
1194 return 1;
1195 if (isl_val_is_infty(v1))
1196 return 0;
1197 if (isl_val_is_neginfty(v1))
1198 return 1;
1199 if (isl_val_is_neginfty(v2))
1200 return 0;
1202 isl_int_init(t);
1203 isl_int_mul(t, v1->n, v2->d);
1204 isl_int_submul(t, v2->n, v1->d);
1205 lt = isl_int_is_neg(t);
1206 isl_int_clear(t);
1208 return lt;
1211 /* Is "v1" (strictly) greater than "v2"?
1213 int isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1215 return isl_val_lt(v2, v1);
1218 /* Is "v1" less than or equal to "v2"?
1220 int isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1222 isl_int t;
1223 int le;
1225 if (!v1 || !v2)
1226 return -1;
1227 if (isl_val_is_int(v1) && isl_val_is_int(v2))
1228 return isl_int_le(v1->n, v2->n);
1229 if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
1230 return 0;
1231 if (isl_val_eq(v1, v2))
1232 return 1;
1233 if (isl_val_is_infty(v2))
1234 return 1;
1235 if (isl_val_is_infty(v1))
1236 return 0;
1237 if (isl_val_is_neginfty(v1))
1238 return 1;
1239 if (isl_val_is_neginfty(v2))
1240 return 0;
1242 isl_int_init(t);
1243 isl_int_mul(t, v1->n, v2->d);
1244 isl_int_submul(t, v2->n, v1->d);
1245 le = isl_int_is_nonpos(t);
1246 isl_int_clear(t);
1248 return le;
1251 /* Is "v1" greater than or equal to "v2"?
1253 int isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1255 return isl_val_le(v2, v1);
1258 /* How does "v" compare to "i"?
1260 * Return 1 if v is greater, -1 if v is smaller and 0 if v is equal to i.
1262 * If v is NaN (or NULL), then the result is undefined.
1264 int isl_val_cmp_si(__isl_keep isl_val *v, long i)
1266 isl_int t;
1267 int cmp;
1269 if (!v)
1270 return 0;
1271 if (isl_val_is_int(v))
1272 return isl_int_cmp_si(v->n, i);
1273 if (isl_val_is_nan(v))
1274 return 0;
1275 if (isl_val_is_infty(v))
1276 return 1;
1277 if (isl_val_is_neginfty(v))
1278 return -1;
1280 isl_int_init(t);
1281 isl_int_mul_si(t, v->d, i);
1282 isl_int_sub(t, v->n, t);
1283 cmp = isl_int_sgn(t);
1284 isl_int_clear(t);
1286 return cmp;
1289 /* Is "v1" equal to "v2"?
1291 int isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1293 if (!v1 || !v2)
1294 return -1;
1295 if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
1296 return 0;
1298 return isl_int_eq(v1->n, v2->n) && isl_int_eq(v1->d, v2->d);
1301 /* Is "v1" different from "v2"?
1303 int isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
1305 if (!v1 || !v2)
1306 return -1;
1307 if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
1308 return 0;
1310 return isl_int_ne(v1->n, v2->n) || isl_int_ne(v1->d, v2->d);
1313 /* Print a textual representation of "v" onto "p".
1315 __isl_give isl_printer *isl_printer_print_val(__isl_take isl_printer *p,
1316 __isl_keep isl_val *v)
1318 int neg;
1320 if (!p || !v)
1321 return isl_printer_free(p);
1323 neg = isl_int_is_neg(v->n);
1324 if (neg) {
1325 p = isl_printer_print_str(p, "-");
1326 isl_int_neg(v->n, v->n);
1328 if (isl_int_is_zero(v->d)) {
1329 int sgn = isl_int_sgn(v->n);
1330 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
1331 sgn == 0 ? "NaN" : "infty");
1332 } else
1333 p = isl_printer_print_isl_int(p, v->n);
1334 if (neg)
1335 isl_int_neg(v->n, v->n);
1336 if (!isl_int_is_zero(v->d) && !isl_int_is_one(v->d)) {
1337 p = isl_printer_print_str(p, "/");
1338 p = isl_printer_print_isl_int(p, v->d);
1341 return p;
1344 /* Is "val1" (obviously) equal to "val2"?
1346 * This is a private copy of isl_val_eq for use in the generic
1347 * isl_multi_*_plain_is_equal instantiated for isl_val.
1349 int isl_val_plain_is_equal(__isl_keep isl_val *val1, __isl_keep isl_val *val2)
1351 return isl_val_eq(val1, val2);
1354 /* Does "v" have any non-zero coefficients
1355 * for any dimension in the given range?
1357 * This function is only meant to be used in the generic isl_multi_*
1358 * functions which have to deal with base objects that have an associated
1359 * space. Since an isl_val does not have any coefficients, this function
1360 * always return 0.
1362 int isl_val_involves_dims(__isl_keep isl_val *v, enum isl_dim_type type,
1363 unsigned first, unsigned n)
1365 if (!v)
1366 return -1;
1368 return 0;
1371 /* Insert "n" dimensions of type "type" at position "first".
1373 * This function is only meant to be used in the generic isl_multi_*
1374 * functions which have to deal with base objects that have an associated
1375 * space. Since an isl_val does not have an associated space, this function
1376 * does not do anything.
1378 __isl_give isl_val *isl_val_insert_dims(__isl_take isl_val *v,
1379 enum isl_dim_type type, unsigned first, unsigned n)
1381 return v;
1384 /* Drop the the "n" first dimensions of type "type" at position "first".
1386 * This function is only meant to be used in the generic isl_multi_*
1387 * functions which have to deal with base objects that have an associated
1388 * space. Since an isl_val does not have an associated space, this function
1389 * does not do anything.
1391 __isl_give isl_val *isl_val_drop_dims(__isl_take isl_val *v,
1392 enum isl_dim_type type, unsigned first, unsigned n)
1394 return v;
1397 /* Change the name of the dimension of type "type" at position "pos" to "s".
1399 * This function is only meant to be used in the generic isl_multi_*
1400 * functions which have to deal with base objects that have an associated
1401 * space. Since an isl_val does not have an associated space, this function
1402 * does not do anything.
1404 __isl_give isl_val *isl_val_set_dim_name(__isl_take isl_val *v,
1405 enum isl_dim_type type, unsigned pos, const char *s)
1407 return v;
1410 /* Return the space of "v".
1412 * This function is only meant to be used in the generic isl_multi_*
1413 * functions which have to deal with base objects that have an associated
1414 * space. The conditions surrounding the call to this function make sure
1415 * that this function will never actually get called. We return a valid
1416 * space anyway, just in case.
1418 __isl_give isl_space *isl_val_get_space(__isl_keep isl_val *v)
1420 if (!v)
1421 return NULL;
1423 return isl_space_params_alloc(isl_val_get_ctx(v), 0);
1426 /* Reset the domain space of "v" to "space".
1428 * This function is only meant to be used in the generic isl_multi_*
1429 * functions which have to deal with base objects that have an associated
1430 * space. Since an isl_val does not have an associated space, this function
1431 * does not do anything, apart from error handling and cleaning up memory.
1433 __isl_give isl_val *isl_val_reset_domain_space(__isl_take isl_val *v,
1434 __isl_take isl_space *space)
1436 if (!space)
1437 return isl_val_free(v);
1438 isl_space_free(space);
1439 return v;
1442 /* Align the parameters of "v" to those of "space".
1444 * This function is only meant to be used in the generic isl_multi_*
1445 * functions which have to deal with base objects that have an associated
1446 * space. Since an isl_val does not have an associated space, this function
1447 * does not do anything, apart from error handling and cleaning up memory.
1448 * Note that the conditions surrounding the call to this function make sure
1449 * that this function will never actually get called.
1451 __isl_give isl_val *isl_val_align_params(__isl_take isl_val *v,
1452 __isl_take isl_space *space)
1454 if (!space)
1455 return isl_val_free(v);
1456 isl_space_free(space);
1457 return v;
1460 /* Reorder the dimensions of the domain of "v" according
1461 * to the given reordering.
1463 * This function is only meant to be used in the generic isl_multi_*
1464 * functions which have to deal with base objects that have an associated
1465 * space. Since an isl_val does not have an associated space, this function
1466 * does not do anything, apart from error handling and cleaning up memory.
1468 __isl_give isl_val *isl_val_realign_domain(__isl_take isl_val *v,
1469 __isl_take isl_reordering *r)
1471 if (!r)
1472 return isl_val_free(v);
1473 isl_reordering_free(r);
1474 return v;
1477 /* Return an isl_val that is zero on "ls".
1479 * This function is only meant to be used in the generic isl_multi_*
1480 * functions which have to deal with base objects that have an associated
1481 * space. Since an isl_val does not have an associated space, this function
1482 * simply returns a zero isl_val in the same context as "ls".
1484 __isl_give isl_val *isl_val_zero_on_domain(__isl_take isl_local_space *ls)
1486 isl_ctx *ctx;
1488 if (!ls)
1489 return NULL;
1490 ctx = isl_local_space_get_ctx(ls);
1491 isl_local_space_free(ls);
1492 return isl_val_zero(ctx);
1495 /* Do the parameters of "v" match those of "space"?
1497 * This function is only meant to be used in the generic isl_multi_*
1498 * functions which have to deal with base objects that have an associated
1499 * space. Since an isl_val does not have an associated space, this function
1500 * simply returns 1, except if "v" or "space" are NULL.
1502 int isl_val_matching_params(__isl_keep isl_val *v, __isl_keep isl_space *space)
1504 if (!v || !space)
1505 return -1;
1506 return 1;
1509 /* Check that the domain space of "v" matches "space".
1511 * Return 0 on success and -1 on error.
1513 * This function is only meant to be used in the generic isl_multi_*
1514 * functions which have to deal with base objects that have an associated
1515 * space. Since an isl_val does not have an associated space, this function
1516 * simply returns 0, except if "v" or "space" are NULL.
1518 int isl_val_check_match_domain_space(__isl_keep isl_val *v,
1519 __isl_keep isl_space *space)
1521 if (!v || !space)
1522 return -1;
1523 return 0;
1526 #undef BASE
1527 #define BASE val
1529 #define NO_DOMAIN
1530 #define NO_INTERSECT_DOMAIN
1531 #define NO_GIST
1532 #define NO_IDENTITY
1533 #define NO_FROM_BASE
1534 #define NO_MOVE_DIMS
1535 #include <isl_multi_templ.c>
1537 /* Apply "fn" to each of the elements of "mv" with as second argument "v".
1539 static __isl_give isl_multi_val *isl_multi_val_fn_val(
1540 __isl_take isl_multi_val *mv,
1541 __isl_give isl_val *(*fn)(__isl_take isl_val *v1,
1542 __isl_take isl_val *v2),
1543 __isl_take isl_val *v)
1545 int i;
1547 mv = isl_multi_val_cow(mv);
1548 if (!mv || !v)
1549 goto error;
1551 for (i = 0; i < mv->n; ++i) {
1552 mv->p[i] = fn(mv->p[i], isl_val_copy(v));
1553 if (!mv->p[i])
1554 goto error;
1557 isl_val_free(v);
1558 return mv;
1559 error:
1560 isl_val_free(v);
1561 isl_multi_val_free(mv);
1562 return NULL;
1565 /* Add "v" to each of the elements of "mv".
1567 __isl_give isl_multi_val *isl_multi_val_add_val(__isl_take isl_multi_val *mv,
1568 __isl_take isl_val *v)
1570 if (!v)
1571 return isl_multi_val_free(mv);
1572 if (isl_val_is_zero(v)) {
1573 isl_val_free(v);
1574 return mv;
1576 return isl_multi_val_fn_val(mv, &isl_val_add, v);
1579 /* Reduce the elements of "mv" modulo "v".
1581 __isl_give isl_multi_val *isl_multi_val_mod_val(__isl_take isl_multi_val *mv,
1582 __isl_take isl_val *v)
1584 return isl_multi_val_fn_val(mv, &isl_val_mod, v);