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 : }
|