LCOV - code coverage report
Current view: top level - metalib_isl - isl_val.c (source / functions) Hit Total Coverage
Test: 2018-10-31_point_maint_greina16.lcov Lines: 175 881 19.9 %
Date: 2018-11-01 11:27:00 Functions: 26 89 29.2 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2013      Ecole Normale Superieure
       3             :  *
       4             :  * Use of this software is governed by the MIT license
       5             :  *
       6             :  * Written by Sven Verdoolaege,
       7             :  * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
       8             :  */
       9             : 
      10             : #include <isl_int.h>
      11             : #include <isl_ctx_private.h>
      12             : #include <isl_val_private.h>
      13             : 
      14             : #undef BASE
      15             : #define BASE val
      16             : 
      17             : #include <isl_list_templ.c>
      18             : 
      19             : /* Allocate an isl_val object with indeterminate value.
      20             :  */
      21     1130180 : __isl_give isl_val *isl_val_alloc(isl_ctx *ctx)
      22             : {
      23             :         isl_val *v;
      24             : 
      25     1130180 :         v = isl_alloc_type(ctx, struct isl_val);
      26     1130180 :         if (!v)
      27           0 :                 return NULL;
      28             : 
      29     1130180 :         v->ctx = ctx;
      30     1130180 :         isl_ctx_ref(ctx);
      31     1130180 :         v->ref = 1;
      32     1130180 :         isl_int_init(v->n);
      33     1130180 :         isl_int_init(v->d);
      34             : 
      35     1130180 :         return v;
      36             : }
      37             : 
      38             : /* Return a reference to an isl_val representing zero.
      39             :  */
      40           0 : __isl_give isl_val *isl_val_zero(isl_ctx *ctx)
      41             : {
      42           0 :         return isl_val_int_from_si(ctx, 0);
      43             : }
      44             : 
      45             : /* Return a reference to an isl_val representing one.
      46             :  */
      47           0 : __isl_give isl_val *isl_val_one(isl_ctx *ctx)
      48             : {
      49           0 :         return isl_val_int_from_si(ctx, 1);
      50             : }
      51             : 
      52             : /* Return a reference to an isl_val representing negative one.
      53             :  */
      54           0 : __isl_give isl_val *isl_val_negone(isl_ctx *ctx)
      55             : {
      56           0 :         return isl_val_int_from_si(ctx, -1);
      57             : }
      58             : 
      59             : /* Return a reference to an isl_val representing NaN.
      60             :  */
      61           0 : __isl_give isl_val *isl_val_nan(isl_ctx *ctx)
      62             : {
      63             :         isl_val *v;
      64             : 
      65           0 :         v = isl_val_alloc(ctx);
      66           0 :         if (!v)
      67           0 :                 return NULL;
      68             : 
      69           0 :         isl_int_set_si(v->n, 0);
      70           0 :         isl_int_set_si(v->d, 0);
      71             : 
      72           0 :         return v;
      73             : }
      74             : 
      75             : /* Change "v" into a NaN.
      76             :  */
      77           0 : __isl_give isl_val *isl_val_set_nan(__isl_take isl_val *v)
      78             : {
      79           0 :         if (!v)
      80           0 :                 return NULL;
      81           0 :         if (isl_val_is_nan(v))
      82           0 :                 return v;
      83           0 :         v = isl_val_cow(v);
      84           0 :         if (!v)
      85           0 :                 return NULL;
      86             : 
      87           0 :         isl_int_set_si(v->n, 0);
      88           0 :         isl_int_set_si(v->d, 0);
      89             : 
      90           0 :         return v;
      91             : }
      92             : 
      93             : /* Return a reference to an isl_val representing +infinity.
      94             :  */
      95           0 : __isl_give isl_val *isl_val_infty(isl_ctx *ctx)
      96             : {
      97             :         isl_val *v;
      98             : 
      99           0 :         v = isl_val_alloc(ctx);
     100           0 :         if (!v)
     101           0 :                 return NULL;
     102             : 
     103           0 :         isl_int_set_si(v->n, 1);
     104           0 :         isl_int_set_si(v->d, 0);
     105             : 
     106           0 :         return v;
     107             : }
     108             : 
     109             : /* Return a reference to an isl_val representing -infinity.
     110             :  */
     111           0 : __isl_give isl_val *isl_val_neginfty(isl_ctx *ctx)
     112             : {
     113             :         isl_val *v;
     114             : 
     115           0 :         v = isl_val_alloc(ctx);
     116           0 :         if (!v)
     117           0 :                 return NULL;
     118             : 
     119           0 :         isl_int_set_si(v->n, -1);
     120           0 :         isl_int_set_si(v->d, 0);
     121             : 
     122           0 :         return v;
     123             : }
     124             : 
     125             : /* Return a reference to an isl_val representing the integer "i".
     126             :  */
     127      223800 : __isl_give isl_val *isl_val_int_from_si(isl_ctx *ctx, long i)
     128             : {
     129             :         isl_val *v;
     130             : 
     131      223800 :         v = isl_val_alloc(ctx);
     132      223800 :         if (!v)
     133           0 :                 return NULL;
     134             : 
     135      223800 :         isl_int_set_si(v->n, i);
     136      223800 :         isl_int_set_si(v->d, 1);
     137             : 
     138      223800 :         return v;
     139             : }
     140             : 
     141             : /* Change the value of "v" to be equal to the integer "i".
     142             :  */
     143           0 : __isl_give isl_val *isl_val_set_si(__isl_take isl_val *v, long i)
     144             : {
     145           0 :         if (!v)
     146           0 :                 return NULL;
     147           0 :         if (isl_val_is_int(v) && isl_int_cmp_si(v->n, i) == 0)
     148           0 :                 return v;
     149           0 :         v = isl_val_cow(v);
     150           0 :         if (!v)
     151           0 :                 return NULL;
     152             : 
     153           0 :         isl_int_set_si(v->n, i);
     154           0 :         isl_int_set_si(v->d, 1);
     155             : 
     156           0 :         return v;
     157             : }
     158             : 
     159             : /* Change the value of "v" to be equal to zero.
     160             :  */
     161           0 : __isl_give isl_val *isl_val_set_zero(__isl_take isl_val *v)
     162             : {
     163           0 :         return isl_val_set_si(v, 0);
     164             : }
     165             : 
     166             : /* Return a reference to an isl_val representing the unsigned integer "u".
     167             :  */
     168           0 : __isl_give isl_val *isl_val_int_from_ui(isl_ctx *ctx, unsigned long u)
     169             : {
     170             :         isl_val *v;
     171             : 
     172           0 :         v = isl_val_alloc(ctx);
     173           0 :         if (!v)
     174           0 :                 return NULL;
     175             : 
     176           0 :         isl_int_set_ui(v->n, u);
     177           0 :         isl_int_set_si(v->d, 1);
     178             : 
     179           0 :         return v;
     180             : }
     181             : 
     182             : /* Return a reference to an isl_val representing the integer "n".
     183             :  */
     184           0 : __isl_give isl_val *isl_val_int_from_isl_int(isl_ctx *ctx, isl_int n)
     185             : {
     186             :         isl_val *v;
     187             : 
     188           0 :         v = isl_val_alloc(ctx);
     189           0 :         if (!v)
     190           0 :                 return NULL;
     191             : 
     192           0 :         isl_int_set(v->n, n);
     193           0 :         isl_int_set_si(v->d, 1);
     194             : 
     195           0 :         return v;
     196             : }
     197             : 
     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.
     200             :  */
     201           0 : __isl_give isl_val *isl_val_rat_from_isl_int(isl_ctx *ctx,
     202             :         isl_int n, isl_int d)
     203             : {
     204             :         isl_val *v;
     205             : 
     206           0 :         v = isl_val_alloc(ctx);
     207           0 :         if (!v)
     208           0 :                 return NULL;
     209             : 
     210           0 :         isl_int_set(v->n, n);
     211           0 :         isl_int_set(v->d, d);
     212             : 
     213           0 :         return v;
     214             : }
     215             : 
     216             : /* Return a new reference to "v".
     217             :  */
     218    16033004 : __isl_give isl_val *isl_val_copy(__isl_keep isl_val *v)
     219             : {
     220    16033004 :         if (!v)
     221           0 :                 return NULL;
     222             : 
     223    16033004 :         v->ref++;
     224    16033004 :         return v;
     225             : }
     226             : 
     227             : /* Return a fresh copy of "val".
     228             :  */
     229      906380 : __isl_give isl_val *isl_val_dup(__isl_keep isl_val *val)
     230             : {
     231             :         isl_val *dup;
     232             : 
     233      906380 :         if (!val)
     234           0 :                 return NULL;
     235             : 
     236      906380 :         dup = isl_val_alloc(isl_val_get_ctx(val));
     237      906380 :         if (!dup)
     238           0 :                 return NULL;
     239             : 
     240      906380 :         isl_int_set(dup->n, val->n);
     241      906380 :         isl_int_set(dup->d, val->d);
     242             : 
     243      906380 :         return dup;
     244             : }
     245             : 
     246             : /* Return an isl_val that is equal to "val" and that has only
     247             :  * a single reference.
     248             :  */
     249      906380 : __isl_give isl_val *isl_val_cow(__isl_take isl_val *val)
     250             : {
     251      906380 :         if (!val)
     252           0 :                 return NULL;
     253             : 
     254      906380 :         if (val->ref == 1)
     255           0 :                 return val;
     256      906380 :         val->ref--;
     257      906380 :         return isl_val_dup(val);
     258             : }
     259             : 
     260             : /* Free "v" and return NULL.
     261             :  */
     262    16256804 : __isl_null isl_val *isl_val_free(__isl_take isl_val *v)
     263             : {
     264    16256804 :         if (!v)
     265           0 :                 return NULL;
     266             : 
     267    16256804 :         if (--v->ref > 0)
     268    15126624 :                 return NULL;
     269             : 
     270     1130180 :         isl_ctx_deref(v->ctx);
     271     1130180 :         isl_int_clear(v->n);
     272     1130180 :         isl_int_clear(v->d);
     273     1130180 :         free(v);
     274     1130180 :         return NULL;
     275             : }
     276             : 
     277             : /* Extract the numerator of a rational value "v" as an integer.
     278             :  *
     279             :  * If "v" is not a rational value, then the result is undefined.
     280             :  */
     281           0 : long isl_val_get_num_si(__isl_keep isl_val *v)
     282             : {
     283           0 :         if (!v)
     284           0 :                 return 0;
     285           0 :         if (!isl_val_is_rat(v))
     286           0 :                 isl_die(isl_val_get_ctx(v), isl_error_invalid,
     287             :                         "expecting rational value", return 0);
     288           0 :         if (!isl_int_fits_slong(v->n))
     289           0 :                 isl_die(isl_val_get_ctx(v), isl_error_invalid,
     290             :                         "numerator too large", return 0);
     291           0 :         return isl_int_get_si(v->n);
     292             : }
     293             : 
     294             : /* Extract the numerator of a rational value "v" as an isl_int.
     295             :  *
     296             :  * If "v" is not a rational value, then the result is undefined.
     297             :  */
     298           0 : isl_stat isl_val_get_num_isl_int(__isl_keep isl_val *v, isl_int *n)
     299             : {
     300           0 :         if (!v)
     301           0 :                 return isl_stat_error;
     302           0 :         if (!isl_val_is_rat(v))
     303           0 :                 isl_die(isl_val_get_ctx(v), isl_error_invalid,
     304             :                         "expecting rational value", return isl_stat_error);
     305           0 :         isl_int_set(*n, v->n);
     306           0 :         return isl_stat_ok;
     307             : }
     308             : 
     309             : /* Extract the denominator of a rational value "v" as an integer.
     310             :  *
     311             :  * If "v" is not a rational value, then the result is undefined.
     312             :  */
     313           0 : long isl_val_get_den_si(__isl_keep isl_val *v)
     314             : {
     315           0 :         if (!v)
     316           0 :                 return 0;
     317           0 :         if (!isl_val_is_rat(v))
     318           0 :                 isl_die(isl_val_get_ctx(v), isl_error_invalid,
     319             :                         "expecting rational value", return 0);
     320           0 :         if (!isl_int_fits_slong(v->d))
     321           0 :                 isl_die(isl_val_get_ctx(v), isl_error_invalid,
     322             :                         "denominator too large", return 0);
     323           0 :         return isl_int_get_si(v->d);
     324             : }
     325             : 
     326             : /* Extract the denominator of a rational value "v" as an isl_val.
     327             :  *
     328             :  * If "v" is not a rational value, then the result is undefined.
     329             :  */
     330           0 : __isl_give isl_val *isl_val_get_den_val(__isl_keep isl_val *v)
     331             : {
     332           0 :         if (!v)
     333           0 :                 return NULL;
     334           0 :         if (!isl_val_is_rat(v))
     335           0 :                 isl_die(isl_val_get_ctx(v), isl_error_invalid,
     336             :                         "expecting rational value", return NULL);
     337           0 :         return isl_val_int_from_isl_int(isl_val_get_ctx(v), v->d);
     338             : }
     339             : 
     340             : /* Return an approximation of "v" as a double.
     341             :  */
     342           0 : double isl_val_get_d(__isl_keep isl_val *v)
     343             : {
     344           0 :         if (!v)
     345           0 :                 return 0;
     346           0 :         if (!isl_val_is_rat(v))
     347           0 :                 isl_die(isl_val_get_ctx(v), isl_error_invalid,
     348             :                         "expecting rational value", return 0);
     349           0 :         return isl_int_get_d(v->n) / isl_int_get_d(v->d);
     350             : }
     351             : 
     352             : /* Return the isl_ctx to which "val" belongs.
     353             :  */
     354      906380 : isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val)
     355             : {
     356      906380 :         return val ? val->ctx : NULL;
     357             : }
     358             : 
     359             : /* Return a hash value that digests "val".
     360             :  */
     361           0 : uint32_t isl_val_get_hash(__isl_keep isl_val *val)
     362             : {
     363             :         uint32_t hash;
     364             : 
     365           0 :         if (!val)
     366           0 :                 return 0;
     367             : 
     368           0 :         hash = isl_hash_init();
     369           0 :         hash = isl_int_hash(val->n, hash);
     370           0 :         hash = isl_int_hash(val->d, hash);
     371             : 
     372           0 :         return hash;
     373             : }
     374             : 
     375             : /* Normalize "v".
     376             :  *
     377             :  * In particular, make sure that the denominator of a rational value
     378             :  * is positive and the numerator and denominator do not have any
     379             :  * common divisors.
     380             :  *
     381             :  * This function should not be called by an external user
     382             :  * since it will only be given normalized values.
     383             :  */
     384           0 : __isl_give isl_val *isl_val_normalize(__isl_take isl_val *v)
     385             : {
     386             :         isl_ctx *ctx;
     387             : 
     388           0 :         if (!v)
     389           0 :                 return NULL;
     390           0 :         if (isl_val_is_int(v))
     391           0 :                 return v;
     392           0 :         if (!isl_val_is_rat(v))
     393           0 :                 return v;
     394           0 :         if (isl_int_is_neg(v->d)) {
     395           0 :                 isl_int_neg(v->d, v->d);
     396           0 :                 isl_int_neg(v->n, v->n);
     397             :         }
     398           0 :         ctx = isl_val_get_ctx(v);
     399           0 :         isl_int_gcd(ctx->normalize_gcd, v->n, v->d);
     400           0 :         if (isl_int_is_one(ctx->normalize_gcd))
     401           0 :                 return v;
     402           0 :         isl_int_divexact(v->n, v->n, ctx->normalize_gcd);
     403           0 :         isl_int_divexact(v->d, v->d, ctx->normalize_gcd);
     404           0 :         return v;
     405             : }
     406             : 
     407             : /* Return the opposite of "v".
     408             :  */
     409      399265 : __isl_give isl_val *isl_val_neg(__isl_take isl_val *v)
     410             : {
     411      399265 :         if (!v)
     412           0 :                 return NULL;
     413      399265 :         if (isl_val_is_nan(v))
     414           0 :                 return v;
     415      399265 :         if (isl_val_is_zero(v))
     416       99773 :                 return v;
     417             : 
     418      299492 :         v = isl_val_cow(v);
     419      299492 :         if (!v)
     420           0 :                 return NULL;
     421      299492 :         isl_int_neg(v->n, v->n);
     422             : 
     423      299492 :         return v;
     424             : }
     425             : 
     426             : /* Return the inverse of "v".
     427             :  */
     428           0 : __isl_give isl_val *isl_val_inv(__isl_take isl_val *v)
     429             : {
     430           0 :         if (!v)
     431           0 :                 return NULL;
     432           0 :         if (isl_val_is_nan(v))
     433           0 :                 return v;
     434           0 :         if (isl_val_is_zero(v)) {
     435           0 :                 isl_ctx *ctx = isl_val_get_ctx(v);
     436           0 :                 isl_val_free(v);
     437           0 :                 return isl_val_nan(ctx);
     438             :         }
     439           0 :         if (isl_val_is_infty(v) || isl_val_is_neginfty(v)) {
     440           0 :                 isl_ctx *ctx = isl_val_get_ctx(v);
     441           0 :                 isl_val_free(v);
     442           0 :                 return isl_val_zero(ctx);
     443             :         }
     444             : 
     445           0 :         v = isl_val_cow(v);
     446           0 :         if (!v)
     447           0 :                 return NULL;
     448           0 :         isl_int_swap(v->n, v->d);
     449             : 
     450           0 :         return isl_val_normalize(v);
     451             : }
     452             : 
     453             : /* Return the absolute value of "v".
     454             :  */
     455      328556 : __isl_give isl_val *isl_val_abs(__isl_take isl_val *v)
     456             : {
     457      328556 :         if (!v)
     458           0 :                 return NULL;
     459      328556 :         if (isl_val_is_nan(v))
     460           0 :                 return v;
     461      328556 :         if (isl_val_is_nonneg(v))
     462      277949 :                 return v;
     463       50607 :         return isl_val_neg(v);
     464             : }
     465             : 
     466             : /* Return the "floor" (greatest integer part) of "v".
     467             :  * That is, return the result of rounding towards -infinity.
     468             :  */
     469      327174 : __isl_give isl_val *isl_val_floor(__isl_take isl_val *v)
     470             : {
     471      327174 :         if (!v)
     472           0 :                 return NULL;
     473      327174 :         if (isl_val_is_int(v))
     474      327174 :                 return v;
     475           0 :         if (!isl_val_is_rat(v))
     476           0 :                 return v;
     477             : 
     478           0 :         v = isl_val_cow(v);
     479           0 :         if (!v)
     480           0 :                 return NULL;
     481           0 :         isl_int_fdiv_q(v->n, v->n, v->d);
     482           0 :         isl_int_set_si(v->d, 1);
     483             : 
     484           0 :         return v;
     485             : }
     486             : 
     487             : /* Return the "ceiling" of "v".
     488             :  * That is, return the result of rounding towards +infinity.
     489             :  */
     490      327893 : __isl_give isl_val *isl_val_ceil(__isl_take isl_val *v)
     491             : {
     492      327893 :         if (!v)
     493           0 :                 return NULL;
     494      327893 :         if (isl_val_is_int(v))
     495      327893 :                 return v;
     496           0 :         if (!isl_val_is_rat(v))
     497           0 :                 return v;
     498             : 
     499           0 :         v = isl_val_cow(v);
     500           0 :         if (!v)
     501           0 :                 return NULL;
     502           0 :         isl_int_cdiv_q(v->n, v->n, v->d);
     503           0 :         isl_int_set_si(v->d, 1);
     504             : 
     505           0 :         return v;
     506             : }
     507             : 
     508             : /* Truncate "v".
     509             :  * That is, return the result of rounding towards zero.
     510             :  */
     511      327732 : __isl_give isl_val *isl_val_trunc(__isl_take isl_val *v)
     512             : {
     513      327732 :         if (!v)
     514           0 :                 return NULL;
     515      327732 :         if (isl_val_is_int(v))
     516      327732 :                 return v;
     517           0 :         if (!isl_val_is_rat(v))
     518           0 :                 return v;
     519             : 
     520           0 :         v = isl_val_cow(v);
     521           0 :         if (!v)
     522           0 :                 return NULL;
     523           0 :         isl_int_tdiv_q(v->n, v->n, v->d);
     524           0 :         isl_int_set_si(v->d, 1);
     525             : 
     526           0 :         return v;
     527             : }
     528             : 
     529             : /* Return 2^v, where v is an integer (that is not too large).
     530             :  */
     531           0 : __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v)
     532             : {
     533             :         unsigned long exp;
     534             :         int neg;
     535             : 
     536           0 :         v = isl_val_cow(v);
     537           0 :         if (!v)
     538           0 :                 return NULL;
     539           0 :         if (!isl_val_is_int(v))
     540           0 :                 isl_die(isl_val_get_ctx(v), isl_error_invalid,
     541             :                         "can only compute integer powers",
     542             :                         return isl_val_free(v));
     543           0 :         neg = isl_val_is_neg(v);
     544           0 :         if (neg)
     545           0 :                 isl_int_neg(v->n, v->n);
     546           0 :         if (!isl_int_fits_ulong(v->n))
     547           0 :                 isl_die(isl_val_get_ctx(v), isl_error_invalid,
     548             :                         "exponent too large", return isl_val_free(v));
     549           0 :         exp = isl_int_get_ui(v->n);
     550           0 :         if (neg) {
     551           0 :                 isl_int_mul_2exp(v->d, v->d, exp);
     552           0 :                 isl_int_set_si(v->n, 1);
     553             :         } else {
     554           0 :                 isl_int_mul_2exp(v->n, v->d, exp);
     555             :         }
     556             : 
     557           0 :         return v;
     558             : }
     559             : 
     560             : /* Return the minimum of "v1" and "v2".
     561             :  */
     562      326916 : __isl_give isl_val *isl_val_min(__isl_take isl_val *v1, __isl_take isl_val *v2)
     563             : {
     564      326916 :         if (!v1 || !v2)
     565             :                 goto error;
     566             : 
     567      326916 :         if (isl_val_is_nan(v1)) {
     568           0 :                 isl_val_free(v2);
     569           0 :                 return v1;
     570             :         }
     571      326916 :         if (isl_val_is_nan(v2)) {
     572           0 :                 isl_val_free(v1);
     573           0 :                 return v2;
     574             :         }
     575      326916 :         if (isl_val_le(v1, v2)) {
     576      239858 :                 isl_val_free(v2);
     577      239858 :                 return v1;
     578             :         } else {
     579       87058 :                 isl_val_free(v1);
     580       87058 :                 return v2;
     581             :         }
     582             : error:
     583           0 :         isl_val_free(v1);
     584           0 :         isl_val_free(v2);
     585           0 :         return NULL;
     586             : }
     587             : 
     588             : /* Return the maximum of "v1" and "v2".
     589             :  */
     590      327527 : __isl_give isl_val *isl_val_max(__isl_take isl_val *v1, __isl_take isl_val *v2)
     591             : {
     592      327527 :         if (!v1 || !v2)
     593             :                 goto error;
     594             : 
     595      327527 :         if (isl_val_is_nan(v1)) {
     596           0 :                 isl_val_free(v2);
     597           0 :                 return v1;
     598             :         }
     599      327527 :         if (isl_val_is_nan(v2)) {
     600           0 :                 isl_val_free(v1);
     601           0 :                 return v2;
     602             :         }
     603      327527 :         if (isl_val_ge(v1, v2)) {
     604      243227 :                 isl_val_free(v2);
     605      243227 :                 return v1;
     606             :         } else {
     607       84300 :                 isl_val_free(v1);
     608       84300 :                 return v2;
     609             :         }
     610             : error:
     611           0 :         isl_val_free(v1);
     612           0 :         isl_val_free(v2);
     613           0 :         return NULL;
     614             : }
     615             : 
     616             : /* Return the sum of "v1" and "v2".
     617             :  */
     618      325358 : __isl_give isl_val *isl_val_add(__isl_take isl_val *v1, __isl_take isl_val *v2)
     619             : {
     620      325358 :         if (!v1 || !v2)
     621             :                 goto error;
     622      325358 :         if (isl_val_is_nan(v1)) {
     623           0 :                 isl_val_free(v2);
     624           0 :                 return v1;
     625             :         }
     626      325358 :         if (isl_val_is_nan(v2)) {
     627           0 :                 isl_val_free(v1);
     628           0 :                 return v2;
     629             :         }
     630      650716 :         if ((isl_val_is_infty(v1) && isl_val_is_neginfty(v2)) ||
     631      325358 :             (isl_val_is_neginfty(v1) && isl_val_is_infty(v2))) {
     632           0 :                 isl_val_free(v2);
     633           0 :                 return isl_val_set_nan(v1);
     634             :         }
     635      325358 :         if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
     636           0 :                 isl_val_free(v2);
     637           0 :                 return v1;
     638             :         }
     639      325358 :         if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
     640           0 :                 isl_val_free(v1);
     641           0 :                 return v2;
     642             :         }
     643      325358 :         if (isl_val_is_zero(v1)) {
     644       92137 :                 isl_val_free(v1);
     645       92137 :                 return v2;
     646             :         }
     647      233221 :         if (isl_val_is_zero(v2)) {
     648       31467 :                 isl_val_free(v2);
     649       31467 :                 return v1;
     650             :         }
     651             : 
     652      201754 :         v1 = isl_val_cow(v1);
     653      201754 :         if (!v1)
     654           0 :                 goto error;
     655      201754 :         if (isl_val_is_int(v1) && isl_val_is_int(v2))
     656      201754 :                 isl_int_add(v1->n, v1->n, v2->n);
     657             :         else {
     658           0 :                 if (isl_int_eq(v1->d, v2->d))
     659           0 :                         isl_int_add(v1->n, v1->n, v2->n);
     660             :                 else {
     661           0 :                         isl_int_mul(v1->n, v1->n, v2->d);
     662           0 :                         isl_int_addmul(v1->n, v2->n, v1->d);
     663           0 :                         isl_int_mul(v1->d, v1->d, v2->d);
     664             :                 }
     665           0 :                 v1 = isl_val_normalize(v1);
     666             :         }
     667      201754 :         isl_val_free(v2);
     668      201754 :         return v1;
     669             : error:
     670           0 :         isl_val_free(v1);
     671           0 :         isl_val_free(v2);
     672           0 :         return NULL;
     673             : }
     674             : 
     675             : /* Return the sum of "v1" and "v2".
     676             :  */
     677           0 : __isl_give isl_val *isl_val_add_ui(__isl_take isl_val *v1, unsigned long v2)
     678             : {
     679           0 :         if (!v1)
     680           0 :                 return NULL;
     681           0 :         if (!isl_val_is_rat(v1))
     682           0 :                 return v1;
     683           0 :         if (v2 == 0)
     684           0 :                 return v1;
     685           0 :         v1 = isl_val_cow(v1);
     686           0 :         if (!v1)
     687           0 :                 return NULL;
     688             : 
     689           0 :         isl_int_addmul_ui(v1->n, v1->d, v2);
     690             : 
     691           0 :         return v1;
     692             : }
     693             : 
     694             : /* Subtract "v2" from "v1".
     695             :  */
     696      328037 : __isl_give isl_val *isl_val_sub(__isl_take isl_val *v1, __isl_take isl_val *v2)
     697             : {
     698      328037 :         if (!v1 || !v2)
     699             :                 goto error;
     700      328037 :         if (isl_val_is_nan(v1)) {
     701           0 :                 isl_val_free(v2);
     702           0 :                 return v1;
     703             :         }
     704      328037 :         if (isl_val_is_nan(v2)) {
     705           0 :                 isl_val_free(v1);
     706           0 :                 return v2;
     707             :         }
     708      656074 :         if ((isl_val_is_infty(v1) && isl_val_is_infty(v2)) ||
     709      328037 :             (isl_val_is_neginfty(v1) && isl_val_is_neginfty(v2))) {
     710           0 :                 isl_val_free(v2);
     711           0 :                 return isl_val_set_nan(v1);
     712             :         }
     713      328037 :         if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
     714           0 :                 isl_val_free(v2);
     715           0 :                 return v1;
     716             :         }
     717      328037 :         if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
     718           0 :                 isl_val_free(v1);
     719           0 :                 return isl_val_neg(v2);
     720             :         }
     721      328037 :         if (isl_val_is_zero(v2)) {
     722      101915 :                 isl_val_free(v2);
     723      101915 :                 return v1;
     724             :         }
     725      226122 :         if (isl_val_is_zero(v1)) {
     726       21641 :                 isl_val_free(v1);
     727       21641 :                 return isl_val_neg(v2);
     728             :         }
     729             : 
     730      204481 :         v1 = isl_val_cow(v1);
     731      204481 :         if (!v1)
     732           0 :                 goto error;
     733      204481 :         if (isl_val_is_int(v1) && isl_val_is_int(v2))
     734      204481 :                 isl_int_sub(v1->n, v1->n, v2->n);
     735             :         else {
     736           0 :                 if (isl_int_eq(v1->d, v2->d))
     737           0 :                         isl_int_sub(v1->n, v1->n, v2->n);
     738             :                 else {
     739           0 :                         isl_int_mul(v1->n, v1->n, v2->d);
     740           0 :                         isl_int_submul(v1->n, v2->n, v1->d);
     741           0 :                         isl_int_mul(v1->d, v1->d, v2->d);
     742             :                 }
     743           0 :                 v1 = isl_val_normalize(v1);
     744             :         }
     745      204481 :         isl_val_free(v2);
     746      204481 :         return v1;
     747             : error:
     748           0 :         isl_val_free(v1);
     749           0 :         isl_val_free(v2);
     750           0 :         return NULL;
     751             : }
     752             : 
     753             : /* Subtract "v2" from "v1".
     754             :  */
     755           0 : __isl_give isl_val *isl_val_sub_ui(__isl_take isl_val *v1, unsigned long v2)
     756             : {
     757           0 :         if (!v1)
     758           0 :                 return NULL;
     759           0 :         if (!isl_val_is_rat(v1))
     760           0 :                 return v1;
     761           0 :         if (v2 == 0)
     762           0 :                 return v1;
     763           0 :         v1 = isl_val_cow(v1);
     764           0 :         if (!v1)
     765           0 :                 return NULL;
     766             : 
     767           0 :         isl_int_submul_ui(v1->n, v1->d, v2);
     768             : 
     769           0 :         return v1;
     770             : }
     771             : 
     772             : /* Return the product of "v1" and "v2".
     773             :  */
     774      324168 : __isl_give isl_val *isl_val_mul(__isl_take isl_val *v1, __isl_take isl_val *v2)
     775             : {
     776      324168 :         if (!v1 || !v2)
     777             :                 goto error;
     778      324168 :         if (isl_val_is_nan(v1)) {
     779           0 :                 isl_val_free(v2);
     780           0 :                 return v1;
     781             :         }
     782      324168 :         if (isl_val_is_nan(v2)) {
     783           0 :                 isl_val_free(v1);
     784           0 :                 return v2;
     785             :         }
     786      648336 :         if ((!isl_val_is_rat(v1) && isl_val_is_zero(v2)) ||
     787      416198 :             (isl_val_is_zero(v1) && !isl_val_is_rat(v2))) {
     788           0 :                 isl_val_free(v2);
     789           0 :                 return isl_val_set_nan(v1);
     790             :         }
     791      324168 :         if (isl_val_is_zero(v1)) {
     792       92030 :                 isl_val_free(v2);
     793       92030 :                 return v1;
     794             :         }
     795      232138 :         if (isl_val_is_zero(v2)) {
     796       31485 :                 isl_val_free(v1);
     797       31485 :                 return v2;
     798             :         }
     799      200653 :         if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
     800           0 :                 if (isl_val_is_neg(v2))
     801           0 :                         v1 = isl_val_neg(v1);
     802           0 :                 isl_val_free(v2);
     803           0 :                 return v1;
     804             :         }
     805      200653 :         if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
     806           0 :                 if (isl_val_is_neg(v1))
     807           0 :                         v2 = isl_val_neg(v2);
     808           0 :                 isl_val_free(v1);
     809           0 :                 return v2;
     810             :         }
     811             : 
     812      200653 :         v1 = isl_val_cow(v1);
     813      200653 :         if (!v1)
     814           0 :                 goto error;
     815      200653 :         if (isl_val_is_int(v1) && isl_val_is_int(v2))
     816      200653 :                 isl_int_mul(v1->n, v1->n, v2->n);
     817             :         else {
     818           0 :                 isl_int_mul(v1->n, v1->n, v2->n);
     819           0 :                 isl_int_mul(v1->d, v1->d, v2->d);
     820           0 :                 v1 = isl_val_normalize(v1);
     821             :         }
     822      200653 :         isl_val_free(v2);
     823      200653 :         return v1;
     824             : error:
     825           0 :         isl_val_free(v1);
     826           0 :         isl_val_free(v2);
     827           0 :         return NULL;
     828             : }
     829             : 
     830             : /* Return the product of "v1" and "v2".
     831             :  *
     832             :  * This is a private copy of isl_val_mul for use in the generic
     833             :  * isl_multi_*_scale_val instantiated for isl_val.
     834             :  */
     835           0 : __isl_give isl_val *isl_val_scale_val(__isl_take isl_val *v1,
     836             :         __isl_take isl_val *v2)
     837             : {
     838           0 :         return isl_val_mul(v1, v2);
     839             : }
     840             : 
     841             : /* Return the product of "v1" and "v2".
     842             :  */
     843           0 : __isl_give isl_val *isl_val_mul_ui(__isl_take isl_val *v1, unsigned long v2)
     844             : {
     845           0 :         if (!v1)
     846           0 :                 return NULL;
     847           0 :         if (isl_val_is_nan(v1))
     848           0 :                 return v1;
     849           0 :         if (!isl_val_is_rat(v1)) {
     850           0 :                 if (v2 == 0)
     851           0 :                         v1 = isl_val_set_nan(v1);
     852           0 :                 return v1;
     853             :         }
     854           0 :         if (v2 == 1)
     855           0 :                 return v1;
     856           0 :         v1 = isl_val_cow(v1);
     857           0 :         if (!v1)
     858           0 :                 return NULL;
     859             : 
     860           0 :         isl_int_mul_ui(v1->n, v1->n, v2);
     861             : 
     862           0 :         return isl_val_normalize(v1);
     863             : }
     864             : 
     865             : /* Divide "v1" by "v2".
     866             :  */
     867           0 : __isl_give isl_val *isl_val_div(__isl_take isl_val *v1, __isl_take isl_val *v2)
     868             : {
     869           0 :         if (!v1 || !v2)
     870             :                 goto error;
     871           0 :         if (isl_val_is_nan(v1)) {
     872           0 :                 isl_val_free(v2);
     873           0 :                 return v1;
     874             :         }
     875           0 :         if (isl_val_is_nan(v2)) {
     876           0 :                 isl_val_free(v1);
     877           0 :                 return v2;
     878             :         }
     879           0 :         if (isl_val_is_zero(v2) ||
     880           0 :             (!isl_val_is_rat(v1) && !isl_val_is_rat(v2))) {
     881           0 :                 isl_val_free(v2);
     882           0 :                 return isl_val_set_nan(v1);
     883             :         }
     884           0 :         if (isl_val_is_zero(v1)) {
     885           0 :                 isl_val_free(v2);
     886           0 :                 return v1;
     887             :         }
     888           0 :         if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) {
     889           0 :                 if (isl_val_is_neg(v2))
     890           0 :                         v1 = isl_val_neg(v1);
     891           0 :                 isl_val_free(v2);
     892           0 :                 return v1;
     893             :         }
     894           0 :         if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)) {
     895           0 :                 isl_val_free(v2);
     896           0 :                 return isl_val_set_zero(v1);
     897             :         }
     898             : 
     899           0 :         v1 = isl_val_cow(v1);
     900           0 :         if (!v1)
     901           0 :                 goto error;
     902           0 :         if (isl_val_is_int(v2)) {
     903           0 :                 isl_int_mul(v1->d, v1->d, v2->n);
     904           0 :                 v1 = isl_val_normalize(v1);
     905             :         } else {
     906           0 :                 isl_int_mul(v1->d, v1->d, v2->n);
     907           0 :                 isl_int_mul(v1->n, v1->n, v2->d);
     908           0 :                 v1 = isl_val_normalize(v1);
     909             :         }
     910           0 :         isl_val_free(v2);
     911           0 :         return v1;
     912             : error:
     913           0 :         isl_val_free(v1);
     914           0 :         isl_val_free(v2);
     915           0 :         return NULL;
     916             : }
     917             : 
     918             : /* Divide "v1" by "v2".
     919             :  */
     920           0 : __isl_give isl_val *isl_val_div_ui(__isl_take isl_val *v1, unsigned long v2)
     921             : {
     922           0 :         if (!v1)
     923           0 :                 return NULL;
     924           0 :         if (isl_val_is_nan(v1))
     925           0 :                 return v1;
     926           0 :         if (v2 == 0)
     927           0 :                 return isl_val_set_nan(v1);
     928           0 :         if (v2 == 1)
     929           0 :                 return v1;
     930           0 :         if (isl_val_is_zero(v1))
     931           0 :                 return v1;
     932           0 :         if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1))
     933           0 :                 return v1;
     934           0 :         v1 = isl_val_cow(v1);
     935           0 :         if (!v1)
     936           0 :                 return NULL;
     937             : 
     938           0 :         isl_int_mul_ui(v1->d, v1->d, v2);
     939             : 
     940           0 :         return isl_val_normalize(v1);
     941             : }
     942             : 
     943             : /* Divide "v1" by "v2".
     944             :  *
     945             :  * This is a private copy of isl_val_div for use in the generic
     946             :  * isl_multi_*_scale_down_val instantiated for isl_val.
     947             :  */
     948           0 : __isl_give isl_val *isl_val_scale_down_val(__isl_take isl_val *v1,
     949             :         __isl_take isl_val *v2)
     950             : {
     951           0 :         return isl_val_div(v1, v2);
     952             : }
     953             : 
     954             : /* Given two integer values "v1" and "v2", check if "v1" is divisible by "v2".
     955             :  */
     956           0 : isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
     957             : {
     958           0 :         if (!v1 || !v2)
     959           0 :                 return isl_bool_error;
     960             : 
     961           0 :         if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
     962           0 :                 isl_die(isl_val_get_ctx(v1), isl_error_invalid,
     963             :                         "expecting two integers", return isl_bool_error);
     964             : 
     965           0 :         return isl_int_is_divisible_by(v1->n, v2->n);
     966             : }
     967             : 
     968             : /* Given two integer values "v1" and "v2", return the residue of "v1"
     969             :  * modulo "v2".
     970             :  */
     971           0 : __isl_give isl_val *isl_val_mod(__isl_take isl_val *v1, __isl_take isl_val *v2)
     972             : {
     973           0 :         if (!v1 || !v2)
     974             :                 goto error;
     975           0 :         if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
     976           0 :                 isl_die(isl_val_get_ctx(v1), isl_error_invalid,
     977             :                         "expecting two integers", goto error);
     978           0 :         if (isl_val_is_nonneg(v1) && isl_val_lt(v1, v2)) {
     979           0 :                 isl_val_free(v2);
     980           0 :                 return v1;
     981             :         }
     982           0 :         v1 = isl_val_cow(v1);
     983           0 :         if (!v1)
     984           0 :                 goto error;
     985           0 :         isl_int_fdiv_r(v1->n, v1->n, v2->n);
     986           0 :         isl_val_free(v2);
     987           0 :         return v1;
     988             : error:
     989           0 :         isl_val_free(v1);
     990           0 :         isl_val_free(v2);
     991           0 :         return NULL;
     992             : }
     993             : 
     994             : /* Given two integer values "v1" and "v2", return the residue of "v1"
     995             :  * modulo "v2".
     996             :  *
     997             :  * This is a private copy of isl_val_mod for use in the generic
     998             :  * isl_multi_*_mod_multi_val instantiated for isl_val.
     999             :  */
    1000           0 : __isl_give isl_val *isl_val_mod_val(__isl_take isl_val *v1,
    1001             :         __isl_take isl_val *v2)
    1002             : {
    1003           0 :         return isl_val_mod(v1, v2);
    1004             : }
    1005             : 
    1006             : /* Given two integer values, return their greatest common divisor.
    1007             :  */
    1008           0 : __isl_give isl_val *isl_val_gcd(__isl_take isl_val *v1, __isl_take isl_val *v2)
    1009             : {
    1010           0 :         if (!v1 || !v2)
    1011             :                 goto error;
    1012           0 :         if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
    1013           0 :                 isl_die(isl_val_get_ctx(v1), isl_error_invalid,
    1014             :                         "expecting two integers", goto error);
    1015           0 :         if (isl_val_eq(v1, v2)) {
    1016           0 :                 isl_val_free(v2);
    1017           0 :                 return v1;
    1018             :         }
    1019           0 :         if (isl_val_is_one(v1)) {
    1020           0 :                 isl_val_free(v2);
    1021           0 :                 return v1;
    1022             :         }
    1023           0 :         if (isl_val_is_one(v2)) {
    1024           0 :                 isl_val_free(v1);
    1025           0 :                 return v2;
    1026             :         }
    1027           0 :         v1 = isl_val_cow(v1);
    1028           0 :         if (!v1)
    1029           0 :                 goto error;
    1030           0 :         isl_int_gcd(v1->n, v1->n, v2->n);
    1031           0 :         isl_val_free(v2);
    1032           0 :         return v1;
    1033             : error:
    1034           0 :         isl_val_free(v1);
    1035           0 :         isl_val_free(v2);
    1036           0 :         return NULL;
    1037             : }
    1038             : 
    1039             : /* Compute x, y and g such that g = gcd(a,b) and a*x+b*y = g.
    1040             :  */
    1041           0 : static void isl_int_gcdext(isl_int *g, isl_int *x, isl_int *y,
    1042             :         isl_int a, isl_int b)
    1043             : {
    1044             :         isl_int d, tmp;
    1045             :         isl_int a_copy, b_copy;
    1046             : 
    1047           0 :         isl_int_init(a_copy);
    1048           0 :         isl_int_init(b_copy);
    1049           0 :         isl_int_init(d);
    1050           0 :         isl_int_init(tmp);
    1051           0 :         isl_int_set(a_copy, a);
    1052           0 :         isl_int_set(b_copy, b);
    1053           0 :         isl_int_abs(*g, a_copy);
    1054           0 :         isl_int_abs(d, b_copy);
    1055           0 :         isl_int_set_si(*x, 1);
    1056           0 :         isl_int_set_si(*y, 0);
    1057           0 :         while (isl_int_is_pos(d)) {
    1058           0 :                 isl_int_fdiv_q(tmp, *g, d);
    1059           0 :                 isl_int_submul(*x, tmp, *y);
    1060           0 :                 isl_int_submul(*g, tmp, d);
    1061           0 :                 isl_int_swap(*g, d);
    1062           0 :                 isl_int_swap(*x, *y);
    1063             :         }
    1064           0 :         if (isl_int_is_zero(a_copy))
    1065           0 :                 isl_int_set_si(*x, 0);
    1066           0 :         else if (isl_int_is_neg(a_copy))
    1067           0 :                 isl_int_neg(*x, *x);
    1068           0 :         if (isl_int_is_zero(b_copy))
    1069           0 :                 isl_int_set_si(*y, 0);
    1070             :         else {
    1071           0 :                 isl_int_mul(tmp, a_copy, *x);
    1072           0 :                 isl_int_sub(tmp, *g, tmp);
    1073           0 :                 isl_int_divexact(*y, tmp, b_copy);
    1074             :         }
    1075           0 :         isl_int_clear(d);
    1076           0 :         isl_int_clear(tmp);
    1077           0 :         isl_int_clear(a_copy);
    1078           0 :         isl_int_clear(b_copy);
    1079           0 : }
    1080             : 
    1081             : /* Given two integer values v1 and v2, return their greatest common divisor g,
    1082             :  * as well as two integers x and y such that x * v1 + y * v2 = g.
    1083             :  */
    1084           0 : __isl_give isl_val *isl_val_gcdext(__isl_take isl_val *v1,
    1085             :         __isl_take isl_val *v2, __isl_give isl_val **x, __isl_give isl_val **y)
    1086             : {
    1087             :         isl_ctx *ctx;
    1088           0 :         isl_val *a = NULL, *b = NULL;
    1089             : 
    1090           0 :         if (!x && !y)
    1091           0 :                 return isl_val_gcd(v1, v2);
    1092             : 
    1093           0 :         if (!v1 || !v2)
    1094             :                 goto error;
    1095             : 
    1096           0 :         ctx = isl_val_get_ctx(v1);
    1097           0 :         if (!isl_val_is_int(v1) || !isl_val_is_int(v2))
    1098           0 :                 isl_die(ctx, isl_error_invalid,
    1099             :                         "expecting two integers", goto error);
    1100             : 
    1101           0 :         v1 = isl_val_cow(v1);
    1102           0 :         a = isl_val_alloc(ctx);
    1103           0 :         b = isl_val_alloc(ctx);
    1104           0 :         if (!v1 || !a || !b)
    1105             :                 goto error;
    1106           0 :         isl_int_gcdext(&v1->n, &a->n, &b->n, v1->n, v2->n);
    1107           0 :         if (x) {
    1108           0 :                 isl_int_set_si(a->d, 1);
    1109           0 :                 *x = a;
    1110             :         } else
    1111           0 :                 isl_val_free(a);
    1112           0 :         if (y) {
    1113           0 :                 isl_int_set_si(b->d, 1);
    1114           0 :                 *y = b;
    1115             :         } else
    1116           0 :                 isl_val_free(b);
    1117           0 :         isl_val_free(v2);
    1118           0 :         return v1;
    1119             : error:
    1120           0 :         isl_val_free(v1);
    1121           0 :         isl_val_free(v2);
    1122           0 :         isl_val_free(a);
    1123           0 :         isl_val_free(b);
    1124           0 :         if (x)
    1125           0 :                 *x = NULL;
    1126           0 :         if (y)
    1127           0 :                 *y = NULL;
    1128           0 :         return NULL;
    1129             : }
    1130             : 
    1131             : /* Does "v" represent an integer value?
    1132             :  */
    1133     3505461 : isl_bool isl_val_is_int(__isl_keep isl_val *v)
    1134             : {
    1135     3505461 :         if (!v)
    1136           0 :                 return isl_bool_error;
    1137             : 
    1138     3505461 :         return isl_int_is_one(v->d);
    1139             : }
    1140             : 
    1141             : /* Does "v" represent a rational value?
    1142             :  */
    1143     3470940 : isl_bool isl_val_is_rat(__isl_keep isl_val *v)
    1144             : {
    1145     3470940 :         if (!v)
    1146           0 :                 return isl_bool_error;
    1147             : 
    1148     3470940 :         return !isl_int_is_zero(v->d);
    1149             : }
    1150             : 
    1151             : /* Does "v" represent NaN?
    1152             :  */
    1153     4320389 : isl_bool isl_val_is_nan(__isl_keep isl_val *v)
    1154             : {
    1155     4320389 :         if (!v)
    1156           0 :                 return isl_bool_error;
    1157             : 
    1158     4320389 :         return isl_int_is_zero(v->n) && isl_int_is_zero(v->d);
    1159             : }
    1160             : 
    1161             : /* Does "v" represent +infinity?
    1162             :  */
    1163     2361491 : isl_bool isl_val_is_infty(__isl_keep isl_val *v)
    1164             : {
    1165     2361491 :         if (!v)
    1166           0 :                 return isl_bool_error;
    1167             : 
    1168     2361491 :         return isl_int_is_pos(v->n) && isl_int_is_zero(v->d);
    1169             : }
    1170             : 
    1171             : /* Does "v" represent -infinity?
    1172             :  */
    1173     2361491 : isl_bool isl_val_is_neginfty(__isl_keep isl_val *v)
    1174             : {
    1175     2361491 :         if (!v)
    1176           0 :                 return isl_bool_error;
    1177             : 
    1178     2361491 :         return isl_int_is_neg(v->n) && isl_int_is_zero(v->d);
    1179             : }
    1180             : 
    1181             : /* Does "v" represent the integer zero?
    1182             :  */
    1183     2392477 : isl_bool isl_val_is_zero(__isl_keep isl_val *v)
    1184             : {
    1185     2392477 :         if (!v)
    1186           0 :                 return isl_bool_error;
    1187             : 
    1188     2392477 :         return isl_int_is_zero(v->n) && !isl_int_is_zero(v->d);
    1189             : }
    1190             : 
    1191             : /* Does "v" represent the integer one?
    1192             :  */
    1193           0 : isl_bool isl_val_is_one(__isl_keep isl_val *v)
    1194             : {
    1195           0 :         if (!v)
    1196           0 :                 return isl_bool_error;
    1197             : 
    1198           0 :         if (isl_val_is_nan(v))
    1199           0 :                 return isl_bool_false;
    1200             : 
    1201           0 :         return isl_int_eq(v->n, v->d);
    1202             : }
    1203             : 
    1204             : /* Does "v" represent the integer negative one?
    1205             :  */
    1206           0 : isl_bool isl_val_is_negone(__isl_keep isl_val *v)
    1207             : {
    1208           0 :         if (!v)
    1209           0 :                 return isl_bool_error;
    1210             : 
    1211           0 :         return isl_int_is_neg(v->n) && isl_int_abs_eq(v->n, v->d);
    1212             : }
    1213             : 
    1214             : /* Is "v" (strictly) positive?
    1215             :  */
    1216           0 : isl_bool isl_val_is_pos(__isl_keep isl_val *v)
    1217             : {
    1218           0 :         if (!v)
    1219           0 :                 return isl_bool_error;
    1220             : 
    1221           0 :         return isl_int_is_pos(v->n);
    1222             : }
    1223             : 
    1224             : /* Is "v" (strictly) negative?
    1225             :  */
    1226           0 : isl_bool isl_val_is_neg(__isl_keep isl_val *v)
    1227             : {
    1228           0 :         if (!v)
    1229           0 :                 return isl_bool_error;
    1230             : 
    1231           0 :         return isl_int_is_neg(v->n);
    1232             : }
    1233             : 
    1234             : /* Is "v" non-negative?
    1235             :  */
    1236      328556 : isl_bool isl_val_is_nonneg(__isl_keep isl_val *v)
    1237             : {
    1238      328556 :         if (!v)
    1239           0 :                 return isl_bool_error;
    1240             : 
    1241      328556 :         if (isl_val_is_nan(v))
    1242           0 :                 return isl_bool_false;
    1243             : 
    1244      328556 :         return isl_int_is_nonneg(v->n);
    1245             : }
    1246             : 
    1247             : /* Is "v" non-positive?
    1248             :  */
    1249           0 : isl_bool isl_val_is_nonpos(__isl_keep isl_val *v)
    1250             : {
    1251           0 :         if (!v)
    1252           0 :                 return isl_bool_error;
    1253             : 
    1254           0 :         if (isl_val_is_nan(v))
    1255           0 :                 return isl_bool_false;
    1256             : 
    1257           0 :         return isl_int_is_nonpos(v->n);
    1258             : }
    1259             : 
    1260             : /* Return the sign of "v".
    1261             :  *
    1262             :  * The sign of NaN is undefined.
    1263             :  */
    1264           0 : int isl_val_sgn(__isl_keep isl_val *v)
    1265             : {
    1266           0 :         if (!v)
    1267           0 :                 return 0;
    1268           0 :         if (isl_val_is_zero(v))
    1269           0 :                 return 0;
    1270           0 :         if (isl_val_is_pos(v))
    1271           0 :                 return 1;
    1272           0 :         return -1;
    1273             : }
    1274             : 
    1275             : /* Is "v1" (strictly) less than "v2"?
    1276             :  */
    1277           0 : isl_bool isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
    1278             : {
    1279             :         isl_int t;
    1280             :         isl_bool lt;
    1281             : 
    1282           0 :         if (!v1 || !v2)
    1283           0 :                 return isl_bool_error;
    1284           0 :         if (isl_val_is_int(v1) && isl_val_is_int(v2))
    1285           0 :                 return isl_int_lt(v1->n, v2->n);
    1286           0 :         if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
    1287           0 :                 return isl_bool_false;
    1288           0 :         if (isl_val_eq(v1, v2))
    1289           0 :                 return isl_bool_false;
    1290           0 :         if (isl_val_is_infty(v2))
    1291           0 :                 return isl_bool_true;
    1292           0 :         if (isl_val_is_infty(v1))
    1293           0 :                 return isl_bool_false;
    1294           0 :         if (isl_val_is_neginfty(v1))
    1295           0 :                 return isl_bool_true;
    1296           0 :         if (isl_val_is_neginfty(v2))
    1297           0 :                 return isl_bool_false;
    1298             : 
    1299           0 :         isl_int_init(t);
    1300           0 :         isl_int_mul(t, v1->n, v2->d);
    1301           0 :         isl_int_submul(t, v2->n, v1->d);
    1302           0 :         lt = isl_int_is_neg(t);
    1303           0 :         isl_int_clear(t);
    1304             : 
    1305           0 :         return lt;
    1306             : }
    1307             : 
    1308             : /* Is "v1" (strictly) greater than "v2"?
    1309             :  */
    1310           0 : isl_bool isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
    1311             : {
    1312           0 :         return isl_val_lt(v2, v1);
    1313             : }
    1314             : 
    1315             : /* Is "v" (strictly) greater than "i"?
    1316             :  */
    1317           0 : isl_bool isl_val_gt_si(__isl_keep isl_val *v, long i)
    1318             : {
    1319             :         isl_val *vi;
    1320             :         isl_bool res;
    1321             : 
    1322           0 :         if (!v)
    1323           0 :                 return isl_bool_error;
    1324           0 :         if (isl_val_is_int(v))
    1325           0 :                 return isl_int_cmp_si(v->n, i) > 0;
    1326           0 :         if (isl_val_is_nan(v))
    1327           0 :                 return isl_bool_false;
    1328           0 :         if (isl_val_is_infty(v))
    1329           0 :                 return isl_bool_true;
    1330           0 :         if (isl_val_is_neginfty(v))
    1331           0 :                 return isl_bool_false;
    1332             : 
    1333           0 :         vi = isl_val_int_from_si(isl_val_get_ctx(v), i);
    1334           0 :         res = isl_val_gt(v, vi);
    1335           0 :         isl_val_free(vi);
    1336             : 
    1337           0 :         return res;
    1338             : }
    1339             : 
    1340             : /* Is "v1" less than or equal to "v2"?
    1341             :  */
    1342      654443 : isl_bool isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
    1343             : {
    1344             :         isl_int t;
    1345             :         isl_bool le;
    1346             : 
    1347      654443 :         if (!v1 || !v2)
    1348           0 :                 return isl_bool_error;
    1349      654443 :         if (isl_val_is_int(v1) && isl_val_is_int(v2))
    1350      654443 :                 return isl_int_le(v1->n, v2->n);
    1351           0 :         if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
    1352           0 :                 return isl_bool_false;
    1353           0 :         if (isl_val_eq(v1, v2))
    1354           0 :                 return isl_bool_true;
    1355           0 :         if (isl_val_is_infty(v2))
    1356           0 :                 return isl_bool_true;
    1357           0 :         if (isl_val_is_infty(v1))
    1358           0 :                 return isl_bool_false;
    1359           0 :         if (isl_val_is_neginfty(v1))
    1360           0 :                 return isl_bool_true;
    1361           0 :         if (isl_val_is_neginfty(v2))
    1362           0 :                 return isl_bool_false;
    1363             : 
    1364           0 :         isl_int_init(t);
    1365           0 :         isl_int_mul(t, v1->n, v2->d);
    1366           0 :         isl_int_submul(t, v2->n, v1->d);
    1367           0 :         le = isl_int_is_nonpos(t);
    1368           0 :         isl_int_clear(t);
    1369             : 
    1370           0 :         return le;
    1371             : }
    1372             : 
    1373             : /* Is "v1" greater than or equal to "v2"?
    1374             :  */
    1375      327527 : isl_bool isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
    1376             : {
    1377      327527 :         return isl_val_le(v2, v1);
    1378             : }
    1379             : 
    1380             : /* How does "v" compare to "i"?
    1381             :  *
    1382             :  * Return 1 if v is greater, -1 if v is smaller and 0 if v is equal to i.
    1383             :  *
    1384             :  * If v is NaN (or NULL), then the result is undefined.
    1385             :  */
    1386           0 : int isl_val_cmp_si(__isl_keep isl_val *v, long i)
    1387             : {
    1388             :         isl_int t;
    1389             :         int cmp;
    1390             : 
    1391           0 :         if (!v)
    1392           0 :                 return 0;
    1393           0 :         if (isl_val_is_int(v))
    1394           0 :                 return isl_int_cmp_si(v->n, i);
    1395           0 :         if (isl_val_is_nan(v))
    1396           0 :                 return 0;
    1397           0 :         if (isl_val_is_infty(v))
    1398           0 :                 return 1;
    1399           0 :         if (isl_val_is_neginfty(v))
    1400           0 :                 return -1;
    1401             : 
    1402           0 :         isl_int_init(t);
    1403           0 :         isl_int_mul_si(t, v->d, i);
    1404           0 :         isl_int_sub(t, v->n, t);
    1405           0 :         cmp = isl_int_sgn(t);
    1406           0 :         isl_int_clear(t);
    1407             : 
    1408           0 :         return cmp;
    1409             : }
    1410             : 
    1411             : /* Is "v1" equal to "v2"?
    1412             :  */
    1413           0 : isl_bool isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
    1414             : {
    1415           0 :         if (!v1 || !v2)
    1416           0 :                 return isl_bool_error;
    1417           0 :         if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
    1418           0 :                 return isl_bool_false;
    1419             : 
    1420           0 :         return isl_int_eq(v1->n, v2->n) && isl_int_eq(v1->d, v2->d);
    1421             : }
    1422             : 
    1423             : /* Is "v1" equal to "v2" in absolute value?
    1424             :  */
    1425           0 : isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
    1426             : {
    1427           0 :         if (!v1 || !v2)
    1428           0 :                 return isl_bool_error;
    1429           0 :         if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
    1430           0 :                 return isl_bool_false;
    1431             : 
    1432           0 :         return isl_int_abs_eq(v1->n, v2->n) && isl_int_eq(v1->d, v2->d);
    1433             : }
    1434             : 
    1435             : /* Is "v1" different from "v2"?
    1436             :  */
    1437           0 : isl_bool isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
    1438             : {
    1439           0 :         if (!v1 || !v2)
    1440           0 :                 return isl_bool_error;
    1441           0 :         if (isl_val_is_nan(v1) || isl_val_is_nan(v2))
    1442           0 :                 return isl_bool_false;
    1443             : 
    1444           0 :         return isl_int_ne(v1->n, v2->n) || isl_int_ne(v1->d, v2->d);
    1445             : }
    1446             : 
    1447             : /* Print a textual representation of "v" onto "p".
    1448             :  */
    1449           0 : __isl_give isl_printer *isl_printer_print_val(__isl_take isl_printer *p,
    1450             :         __isl_keep isl_val *v)
    1451             : {
    1452             :         int neg;
    1453             : 
    1454           0 :         if (!p || !v)
    1455           0 :                 return isl_printer_free(p);
    1456             : 
    1457           0 :         neg = isl_int_is_neg(v->n);
    1458           0 :         if (neg) {
    1459           0 :                 p = isl_printer_print_str(p, "-");
    1460           0 :                 isl_int_neg(v->n, v->n);
    1461             :         }
    1462           0 :         if (isl_int_is_zero(v->d)) {
    1463           0 :                 int sgn = isl_int_sgn(v->n);
    1464           0 :                 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
    1465             :                                             sgn == 0 ? "NaN" : "infty");
    1466             :         } else
    1467           0 :                 p = isl_printer_print_isl_int(p, v->n);
    1468           0 :         if (neg)
    1469           0 :                 isl_int_neg(v->n, v->n);
    1470           0 :         if (!isl_int_is_zero(v->d) && !isl_int_is_one(v->d)) {
    1471           0 :                 p = isl_printer_print_str(p, "/");
    1472           0 :                 p = isl_printer_print_isl_int(p, v->d);
    1473             :         }
    1474             : 
    1475           0 :         return p;
    1476             : }
    1477             : 
    1478             : /* Is "val1" (obviously) equal to "val2"?
    1479             :  *
    1480             :  * This is a private copy of isl_val_eq for use in the generic
    1481             :  * isl_multi_*_plain_is_equal instantiated for isl_val.
    1482             :  */
    1483           0 : int isl_val_plain_is_equal(__isl_keep isl_val *val1, __isl_keep isl_val *val2)
    1484             : {
    1485           0 :         return isl_val_eq(val1, val2);
    1486             : }
    1487             : 
    1488             : /* Does "v" have any non-zero coefficients
    1489             :  * for any dimension in the given range?
    1490             :  *
    1491             :  * This function is only meant to be used in the generic isl_multi_*
    1492             :  * functions which have to deal with base objects that have an associated
    1493             :  * space.  Since an isl_val does not have any coefficients, this function
    1494             :  * always returns isl_bool_false.
    1495             :  */
    1496           0 : isl_bool isl_val_involves_dims(__isl_keep isl_val *v, enum isl_dim_type type,
    1497             :         unsigned first, unsigned n)
    1498             : {
    1499           0 :         if (!v)
    1500           0 :                 return isl_bool_error;
    1501             : 
    1502           0 :         return isl_bool_false;
    1503             : }
    1504             : 
    1505             : /* Insert "n" dimensions of type "type" at position "first".
    1506             :  *
    1507             :  * This function is only meant to be used in the generic isl_multi_*
    1508             :  * functions which have to deal with base objects that have an associated
    1509             :  * space.  Since an isl_val does not have an associated space, this function
    1510             :  * does not do anything.
    1511             :  */
    1512           0 : __isl_give isl_val *isl_val_insert_dims(__isl_take isl_val *v,
    1513             :         enum isl_dim_type type, unsigned first, unsigned n)
    1514             : {
    1515           0 :         return v;
    1516             : }
    1517             : 
    1518             : /* Drop the "n" first dimensions of type "type" at position "first".
    1519             :  *
    1520             :  * This function is only meant to be used in the generic isl_multi_*
    1521             :  * functions which have to deal with base objects that have an associated
    1522             :  * space.  Since an isl_val does not have an associated space, this function
    1523             :  * does not do anything.
    1524             :  */
    1525           0 : __isl_give isl_val *isl_val_drop_dims(__isl_take isl_val *v,
    1526             :         enum isl_dim_type type, unsigned first, unsigned n)
    1527             : {
    1528           0 :         return v;
    1529             : }
    1530             : 
    1531             : /* Change the name of the dimension of type "type" at position "pos" to "s".
    1532             :  *
    1533             :  * This function is only meant to be used in the generic isl_multi_*
    1534             :  * functions which have to deal with base objects that have an associated
    1535             :  * space.  Since an isl_val does not have an associated space, this function
    1536             :  * does not do anything.
    1537             :  */
    1538           0 : __isl_give isl_val *isl_val_set_dim_name(__isl_take isl_val *v,
    1539             :         enum isl_dim_type type, unsigned pos, const char *s)
    1540             : {
    1541           0 :         return v;
    1542             : }
    1543             : 
    1544             : /* Return the space of "v".
    1545             :  *
    1546             :  * This function is only meant to be used in the generic isl_multi_*
    1547             :  * functions which have to deal with base objects that have an associated
    1548             :  * space.  The conditions surrounding the call to this function make sure
    1549             :  * that this function will never actually get called.  We return a valid
    1550             :  * space anyway, just in case.
    1551             :  */
    1552           0 : __isl_give isl_space *isl_val_get_space(__isl_keep isl_val *v)
    1553             : {
    1554           0 :         if (!v)
    1555           0 :                 return NULL;
    1556             : 
    1557           0 :         return isl_space_params_alloc(isl_val_get_ctx(v), 0);
    1558             : }
    1559             : 
    1560             : /* Reset the domain space of "v" to "space".
    1561             :  *
    1562             :  * This function is only meant to be used in the generic isl_multi_*
    1563             :  * functions which have to deal with base objects that have an associated
    1564             :  * space.  Since an isl_val does not have an associated space, this function
    1565             :  * does not do anything, apart from error handling and cleaning up memory.
    1566             :  */
    1567           0 : __isl_give isl_val *isl_val_reset_domain_space(__isl_take isl_val *v,
    1568             :         __isl_take isl_space *space)
    1569             : {
    1570           0 :         if (!space)
    1571           0 :                 return isl_val_free(v);
    1572           0 :         isl_space_free(space);
    1573           0 :         return v;
    1574             : }
    1575             : 
    1576             : /* Align the parameters of "v" to those of "space".
    1577             :  *
    1578             :  * This function is only meant to be used in the generic isl_multi_*
    1579             :  * functions which have to deal with base objects that have an associated
    1580             :  * space.  Since an isl_val does not have an associated space, this function
    1581             :  * does not do anything, apart from error handling and cleaning up memory.
    1582             :  * Note that the conditions surrounding the call to this function make sure
    1583             :  * that this function will never actually get called.
    1584             :  */
    1585           0 : __isl_give isl_val *isl_val_align_params(__isl_take isl_val *v,
    1586             :         __isl_take isl_space *space)
    1587             : {
    1588           0 :         if (!space)
    1589           0 :                 return isl_val_free(v);
    1590           0 :         isl_space_free(space);
    1591           0 :         return v;
    1592             : }
    1593             : 
    1594             : /* Reorder the dimensions of the domain of "v" according
    1595             :  * to the given reordering.
    1596             :  *
    1597             :  * This function is only meant to be used in the generic isl_multi_*
    1598             :  * functions which have to deal with base objects that have an associated
    1599             :  * space.  Since an isl_val does not have an associated space, this function
    1600             :  * does not do anything, apart from error handling and cleaning up memory.
    1601             :  */
    1602           0 : __isl_give isl_val *isl_val_realign_domain(__isl_take isl_val *v,
    1603             :         __isl_take isl_reordering *r)
    1604             : {
    1605           0 :         if (!r)
    1606           0 :                 return isl_val_free(v);
    1607           0 :         isl_reordering_free(r);
    1608           0 :         return v;
    1609             : }
    1610             : 
    1611             : /* Return an isl_val that is zero on "ls".
    1612             :  *
    1613             :  * This function is only meant to be used in the generic isl_multi_*
    1614             :  * functions which have to deal with base objects that have an associated
    1615             :  * space.  Since an isl_val does not have an associated space, this function
    1616             :  * simply returns a zero isl_val in the same context as "ls".
    1617             :  */
    1618           0 : __isl_give isl_val *isl_val_zero_on_domain(__isl_take isl_local_space *ls)
    1619             : {
    1620             :         isl_ctx *ctx;
    1621             : 
    1622           0 :         if (!ls)
    1623           0 :                 return NULL;
    1624           0 :         ctx = isl_local_space_get_ctx(ls);
    1625           0 :         isl_local_space_free(ls);
    1626           0 :         return isl_val_zero(ctx);
    1627             : }
    1628             : 
    1629             : /* Do the parameters of "v" match those of "space"?
    1630             :  *
    1631             :  * This function is only meant to be used in the generic isl_multi_*
    1632             :  * functions which have to deal with base objects that have an associated
    1633             :  * space.  Since an isl_val does not have an associated space, this function
    1634             :  * simply returns true, except if "v" or "space" are NULL.
    1635             :  */
    1636           0 : isl_bool isl_val_matching_params(__isl_keep isl_val *v,
    1637             :         __isl_keep isl_space *space)
    1638             : {
    1639           0 :         if (!v || !space)
    1640           0 :                 return isl_bool_error;
    1641           0 :         return isl_bool_true;
    1642             : }
    1643             : 
    1644             : /* Check that the domain space of "v" matches "space".
    1645             :  *
    1646             :  * This function is only meant to be used in the generic isl_multi_*
    1647             :  * functions which have to deal with base objects that have an associated
    1648             :  * space.  Since an isl_val does not have an associated space, this function
    1649             :  * simply returns 0, except if "v" or "space" are NULL.
    1650             :  */
    1651           0 : isl_stat isl_val_check_match_domain_space(__isl_keep isl_val *v,
    1652             :         __isl_keep isl_space *space)
    1653             : {
    1654           0 :         if (!v || !space)
    1655           0 :                 return isl_stat_error;
    1656           0 :         return isl_stat_ok;
    1657             : }
    1658             : 
    1659             : #define isl_val_involves_nan isl_val_is_nan
    1660             : 
    1661             : #undef BASE
    1662             : #define BASE val
    1663             : 
    1664             : #define NO_DOMAIN
    1665             : #define NO_IDENTITY
    1666             : #define NO_FROM_BASE
    1667             : #define NO_MOVE_DIMS
    1668             : #include <isl_multi_no_explicit_domain.c>
    1669             : #include <isl_multi_templ.c>
    1670             : #include <isl_multi_dims.c>
    1671             : 
    1672             : /* Apply "fn" to each of the elements of "mv" with as second argument "v".
    1673             :  */
    1674           0 : static __isl_give isl_multi_val *isl_multi_val_fn_val(
    1675             :         __isl_take isl_multi_val *mv,
    1676             :         __isl_give isl_val *(*fn)(__isl_take isl_val *v1,
    1677             :                                         __isl_take isl_val *v2),
    1678             :         __isl_take isl_val *v)
    1679             : {
    1680             :         int i;
    1681             : 
    1682           0 :         mv = isl_multi_val_cow(mv);
    1683           0 :         if (!mv || !v)
    1684             :                 goto error;
    1685             : 
    1686           0 :         for (i = 0; i < mv->n; ++i) {
    1687           0 :                 mv->u.p[i] = fn(mv->u.p[i], isl_val_copy(v));
    1688           0 :                 if (!mv->u.p[i])
    1689           0 :                         goto error;
    1690             :         }
    1691             : 
    1692           0 :         isl_val_free(v);
    1693           0 :         return mv;
    1694             : error:
    1695           0 :         isl_val_free(v);
    1696           0 :         isl_multi_val_free(mv);
    1697           0 :         return NULL;
    1698             : }
    1699             : 
    1700             : /* Add "v" to each of the elements of "mv".
    1701             :  */
    1702           0 : __isl_give isl_multi_val *isl_multi_val_add_val(__isl_take isl_multi_val *mv,
    1703             :         __isl_take isl_val *v)
    1704             : {
    1705           0 :         if (!v)
    1706           0 :                 return isl_multi_val_free(mv);
    1707           0 :         if (isl_val_is_zero(v)) {
    1708           0 :                 isl_val_free(v);
    1709           0 :                 return mv;
    1710             :         }
    1711           0 :         return isl_multi_val_fn_val(mv, &isl_val_add, v);
    1712             : }
    1713             : 
    1714             : /* Reduce the elements of "mv" modulo "v".
    1715             :  */
    1716           0 : __isl_give isl_multi_val *isl_multi_val_mod_val(__isl_take isl_multi_val *mv,
    1717             :         __isl_take isl_val *v)
    1718             : {
    1719           0 :         return isl_multi_val_fn_val(mv, &isl_val_mod, v);
    1720             : }

Generated by: LCOV version 1.12