isl_sample.c: drop_constraints_involving: avoid NULL pointer dereference
[isl.git] / isl_output.c
blobef7e7580763a8157c3e6e8a0b571dc40b33b310d
1 /*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010 INRIA Saclay
5 * Use of this software is governed by the GNU LGPLv2.1 license
7 * Written by Sven Verdoolaege, K.U.Leuven, Departement
8 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
10 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
13 #include <string.h>
14 #include <isl_set.h>
15 #include <isl_seq.h>
16 #include <isl_polynomial_private.h>
17 #include <isl_printer_private.h>
19 static const char *s_to[2] = { " -> ", " \\to " };
20 static const char *s_and[2] = { " and ", " \\wedge " };
21 static const char *s_or[2] = { " or ", " \\vee " };
22 static const char *s_le[2] = { "<=", "\\le" };
23 static const char *s_ge[2] = { ">=", "\\ge" };
24 static const char *s_open_set[2] = { "{ ", "\\{\\, " };
25 static const char *s_close_set[2] = { " }", " \\,\\}" };
26 static const char *s_open_list[2] = { "[", "(" };
27 static const char *s_close_list[2] = { "]", ")" };
28 static const char *s_such_that[2] = { " : ", " \\mid " };
29 static const char *s_open_exists[2] = { "exists (", "\\exists \\, " };
30 static const char *s_close_exists[2] = { ")", "" };
31 static const char *s_div_prefix[2] = { "e", "\\alpha_" };
32 static const char *s_param_prefix[2] = { "p", "p_" };
33 static const char *s_input_prefix[2] = { "i", "i_" };
34 static const char *s_output_prefix[2] = { "o", "o_" };
36 static __isl_give isl_printer *print_constraint_polylib(
37 struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p)
39 int i;
40 unsigned n_in = isl_basic_map_dim(bmap, isl_dim_in);
41 unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
42 unsigned nparam = isl_basic_map_dim(bmap, isl_dim_param);
43 isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n];
45 p = isl_printer_start_line(p);
46 p = isl_printer_print_int(p, ineq);
47 for (i = 0; i < n_out; ++i) {
48 p = isl_printer_print_str(p, " ");
49 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]);
51 for (i = 0; i < n_in; ++i) {
52 p = isl_printer_print_str(p, " ");
53 p = isl_printer_print_isl_int(p, c[1+nparam+i]);
55 for (i = 0; i < bmap->n_div; ++i) {
56 p = isl_printer_print_str(p, " ");
57 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]);
59 for (i = 0; i < nparam; ++i) {
60 p = isl_printer_print_str(p, " ");
61 p = isl_printer_print_isl_int(p, c[1+i]);
63 p = isl_printer_print_str(p, " ");
64 p = isl_printer_print_isl_int(p, c[0]);
65 p = isl_printer_end_line(p);
66 return p;
69 static __isl_give isl_printer *print_constraints_polylib(
70 struct isl_basic_map *bmap, __isl_take isl_printer *p)
72 int i;
74 p = isl_printer_set_isl_int_width(p, 5);
76 for (i = 0; i < bmap->n_eq; ++i)
77 p = print_constraint_polylib(bmap, 0, i, p);
78 for (i = 0; i < bmap->n_ineq; ++i)
79 p = print_constraint_polylib(bmap, 1, i, p);
81 return p;
84 static __isl_give isl_printer *bset_print_constraints_polylib(
85 struct isl_basic_set *bset, __isl_take isl_printer *p)
87 return print_constraints_polylib((struct isl_basic_map *)bset, p);
90 static __isl_give isl_printer *isl_basic_map_print_polylib(
91 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
93 unsigned total = isl_basic_map_total_dim(bmap);
94 p = isl_printer_start_line(p);
95 p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq);
96 p = isl_printer_print_str(p, " ");
97 p = isl_printer_print_int(p, 1 + total + 1);
98 p = isl_printer_end_line(p);
99 return print_constraints_polylib(bmap, p);
102 static __isl_give isl_printer *isl_basic_set_print_polylib(
103 __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
105 return isl_basic_map_print_polylib((struct isl_basic_map *)bset, p);
108 static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map,
109 __isl_take isl_printer *p)
111 int i;
113 p = isl_printer_start_line(p);
114 p = isl_printer_print_int(p, map->n);
115 p = isl_printer_end_line(p);
116 for (i = 0; i < map->n; ++i) {
117 p = isl_printer_start_line(p);
118 p = isl_printer_end_line(p);
119 p = isl_basic_map_print_polylib(map->p[i], p);
121 return p;
124 static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set,
125 __isl_take isl_printer *p)
127 return isl_map_print_polylib((struct isl_map *)set, p);
130 static int count_same_name(__isl_keep isl_dim *dim,
131 enum isl_dim_type type, unsigned pos, const char *name)
133 enum isl_dim_type t;
134 unsigned p, s;
135 int count = 0;
137 for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) {
138 s = t == type ? pos : isl_dim_size(dim, t);
139 for (p = 0; p < s; ++p) {
140 const char *n = isl_dim_get_name(dim, t, p);
141 if (n && !strcmp(n, name))
142 count++;
145 return count;
148 static __isl_give isl_printer *print_name(__isl_keep isl_dim *dim,
149 __isl_take isl_printer *p, enum isl_dim_type type, unsigned pos,
150 int set, int latex)
152 const char *name;
153 char buffer[20];
154 int primes;
156 name = type == isl_dim_div ? NULL : isl_dim_get_name(dim, type, pos);
158 if (!name) {
159 const char *prefix;
160 if (type == isl_dim_param)
161 prefix = s_param_prefix[latex];
162 else if (type == isl_dim_div)
163 prefix = s_div_prefix[latex];
164 else if (set || type == isl_dim_in)
165 prefix = s_input_prefix[latex];
166 else
167 prefix = s_output_prefix[latex];
168 snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);
169 name = buffer;
171 primes = count_same_name(dim, name == buffer ? isl_dim_div : type,
172 pos, name);
173 p = isl_printer_print_str(p, name);
174 while (primes-- > 0)
175 p = isl_printer_print_str(p, "'");
176 return p;
179 static __isl_give isl_printer *print_var_list(__isl_keep isl_dim *dim,
180 __isl_take isl_printer *p, enum isl_dim_type type, int set, int latex)
182 int i;
184 for (i = 0; i < isl_dim_size(dim, type); ++i) {
185 if (i)
186 p = isl_printer_print_str(p, ", ");
187 p = print_name(dim, p, type, i, set, latex);
189 return p;
192 static __isl_give isl_printer *print_tuple(__isl_keep isl_dim *dim,
193 __isl_take isl_printer *p, enum isl_dim_type type, int set, int latex)
195 unsigned n = isl_dim_size(dim, type);
196 if (!latex || n != 1)
197 p = isl_printer_print_str(p, s_open_list[latex]);
198 p = print_var_list(dim, p, type, set, latex);
199 if (!latex || n != 1)
200 p = isl_printer_print_str(p, s_close_list[latex]);
201 return p;
204 static __isl_give isl_printer *print_omega_parameters(__isl_keep isl_dim *dim,
205 __isl_take isl_printer *p)
207 if (isl_dim_size(dim, isl_dim_param) == 0)
208 return p;
210 p = isl_printer_start_line(p);
211 p = isl_printer_print_str(p, "symbolic ");
212 p = print_var_list(dim, p, isl_dim_param, 0, 0);
213 p = isl_printer_print_str(p, ";");
214 p = isl_printer_end_line(p);
215 return p;
218 static enum isl_dim_type pos2type(__isl_keep isl_dim *dim, unsigned *pos)
220 enum isl_dim_type type;
221 unsigned n_in = isl_dim_size(dim, isl_dim_in);
222 unsigned n_out = isl_dim_size(dim, isl_dim_out);
223 unsigned nparam = isl_dim_size(dim, isl_dim_param);
225 if (*pos < 1 + nparam) {
226 type = isl_dim_param;
227 *pos -= 1;
228 } else if (*pos < 1 + nparam + n_in) {
229 type = isl_dim_in;
230 *pos -= 1 + nparam;
231 } else if (*pos < 1 + nparam + n_in + n_out) {
232 type = isl_dim_out;
233 *pos -= 1 + nparam + n_in;
234 } else {
235 type = isl_dim_div;
236 *pos -= 1 + nparam + n_in + n_out;
239 return type;
242 static __isl_give isl_printer *print_term(__isl_keep isl_dim *dim,
243 isl_int c, unsigned pos, __isl_take isl_printer *p, int set, int latex)
245 enum isl_dim_type type;
247 if (pos == 0)
248 return isl_printer_print_isl_int(p, c);
250 if (isl_int_is_one(c))
252 else if (isl_int_is_negone(c))
253 p = isl_printer_print_str(p, "-");
254 else
255 p = isl_printer_print_isl_int(p, c);
256 type = pos2type(dim, &pos);
257 p = print_name(dim, p, type, pos, set, latex);
258 return p;
261 static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_dim *dim,
262 __isl_take isl_printer *p, isl_int *c, int len, int set)
264 int i;
265 int first;
267 for (i = 0, first = 1; i < len; ++i) {
268 int flip = 0;
269 if (isl_int_is_zero(c[i]))
270 continue;
271 if (!first) {
272 if (isl_int_is_neg(c[i])) {
273 flip = 1;
274 isl_int_neg(c[i], c[i]);
275 p = isl_printer_print_str(p, " - ");
276 } else
277 p = isl_printer_print_str(p, " + ");
279 first = 0;
280 p = print_term(dim, c[i], i, p, set, 0);
281 if (flip)
282 isl_int_neg(c[i], c[i]);
284 if (first)
285 p = isl_printer_print_str(p, "0");
286 return p;
289 static __isl_give isl_printer *print_affine(__isl_keep isl_basic_map *bmap,
290 __isl_keep isl_dim *dim, __isl_take isl_printer *p, isl_int *c, int set)
292 unsigned len = 1 + isl_basic_map_total_dim(bmap);
293 return print_affine_of_len(dim, p, c, len, set);
296 static __isl_give isl_printer *print_constraint(struct isl_basic_map *bmap,
297 __isl_keep isl_dim *dim, __isl_take isl_printer *p,
298 isl_int *c, int last, const char *op, int first_constraint, int set,
299 int latex)
301 if (!first_constraint)
302 p = isl_printer_print_str(p, s_and[latex]);
304 isl_int_abs(c[last], c[last]);
306 p = print_term(dim, c[last], last, p, set, latex);
308 p = isl_printer_print_str(p, " ");
309 p = isl_printer_print_str(p, op);
310 p = isl_printer_print_str(p, " ");
312 isl_int_set_si(c[last], 0);
313 p = print_affine(bmap, dim, p, c, set);
315 return p;
318 static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
319 __isl_keep isl_dim *dim, __isl_take isl_printer *p, int set, int latex)
321 int i;
322 struct isl_vec *c;
323 unsigned total = isl_basic_map_total_dim(bmap);
325 c = isl_vec_alloc(bmap->ctx, 1 + total);
326 if (!c)
327 goto error;
329 for (i = bmap->n_eq - 1; i >= 0; --i) {
330 int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total);
331 isl_assert(bmap->ctx, l >= 0, goto error);
332 if (isl_int_is_neg(bmap->eq[i][l]))
333 isl_seq_cpy(c->el, bmap->eq[i], 1 + total);
334 else
335 isl_seq_neg(c->el, bmap->eq[i], 1 + total);
336 p = print_constraint(bmap, dim, p, c->el, l,
337 "=", i == bmap->n_eq - 1, set, latex);
339 for (i = 0; i < bmap->n_ineq; ++i) {
340 int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);
341 int s;
342 const char *op;
343 if (l < 0)
344 continue;
345 s = isl_int_sgn(bmap->ineq[i][l]);
346 if (s < 0)
347 isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);
348 else
349 isl_seq_neg(c->el, bmap->ineq[i], 1 + total);
350 op = s < 0 ? s_le[latex] : s_ge[latex];
351 p = print_constraint(bmap, dim, p, c->el, l,
352 op, !bmap->n_eq && !i, set, latex);
355 isl_vec_free(c);
357 return p;
358 error:
359 isl_printer_free(p);
360 return NULL;
363 static __isl_give isl_printer *print_omega_constraints(
364 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int set)
366 if (bmap->n_eq + bmap->n_ineq == 0)
367 return p;
369 p = isl_printer_print_str(p, ": ");
370 if (bmap->n_div > 0) {
371 int i;
372 p = isl_printer_print_str(p, "exists (");
373 for (i = 0; i < bmap->n_div; ++i) {
374 if (i)
375 p = isl_printer_print_str(p, ", ");
376 p = print_name(bmap->dim, p, isl_dim_div, i, 0, 0);
378 p = isl_printer_print_str(p, ": ");
380 p = print_constraints(bmap, bmap->dim, p, set, 0);
381 if (bmap->n_div > 0)
382 p = isl_printer_print_str(p, ")");
383 return p;
386 static __isl_give isl_printer *basic_map_print_omega(
387 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
389 p = isl_printer_print_str(p, "{ [");
390 p = print_var_list(bmap->dim, p, isl_dim_in, 0, 0);
391 p = isl_printer_print_str(p, "] -> [");
392 p = print_var_list(bmap->dim, p, isl_dim_out, 0, 0);
393 p = isl_printer_print_str(p, "] ");
394 p = print_omega_constraints(bmap, p, 0);
395 p = isl_printer_print_str(p, " }");
396 return p;
399 static __isl_give isl_printer *isl_basic_map_print_omega(
400 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
402 p = print_omega_parameters(bmap->dim, p);
404 p = isl_printer_start_line(p);
405 p = basic_map_print_omega(bmap, p);
406 p = isl_printer_end_line(p);
407 return p;
410 static __isl_give isl_printer *basic_set_print_omega(
411 __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
413 p = isl_printer_print_str(p, "{ [");
414 p = print_var_list(bset->dim, p, isl_dim_set, 1, 0);
415 p = isl_printer_print_str(p, "] ");
416 p = print_omega_constraints((isl_basic_map *)bset, p, 1);
417 p = isl_printer_print_str(p, " }");
418 return p;
421 static __isl_give isl_printer *isl_basic_set_print_omega(
422 __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
424 p = print_omega_parameters(bset->dim, p);
426 p = isl_printer_start_line(p);
427 p = basic_set_print_omega(bset, p);
428 p = isl_printer_end_line(p);
429 return p;
432 static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map,
433 __isl_take isl_printer *p)
435 int i;
437 p = print_omega_parameters(map->dim, p);
439 p = isl_printer_start_line(p);
440 for (i = 0; i < map->n; ++i) {
441 if (i)
442 p = isl_printer_print_str(p, " union ");
443 p = basic_map_print_omega(map->p[i], p);
445 p = isl_printer_end_line(p);
446 return p;
449 static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set,
450 __isl_take isl_printer *p)
452 int i;
454 p = print_omega_parameters(set->dim, p);
456 p = isl_printer_start_line(p);
457 for (i = 0; i < set->n; ++i) {
458 if (i)
459 p = isl_printer_print_str(p, " union ");
460 p = basic_set_print_omega(set->p[i], p);
462 p = isl_printer_end_line(p);
463 return p;
466 static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
467 __isl_keep isl_dim *dim, __isl_take isl_printer *p, int set, int latex)
469 if (bmap->n_div > 0) {
470 int i;
471 p = isl_printer_print_str(p, s_open_exists[latex]);
472 for (i = 0; i < bmap->n_div; ++i) {
473 if (i)
474 p = isl_printer_print_str(p, ", ");
475 p = print_name(dim, p, isl_dim_div, i, 0, latex);
476 if (latex || isl_int_is_zero(bmap->div[i][0]))
477 continue;
478 p = isl_printer_print_str(p, " = [(");
479 p = print_affine(bmap, dim, p, bmap->div[i] + 1, set);
480 p = isl_printer_print_str(p, ")/");
481 p = isl_printer_print_isl_int(p, bmap->div[i][0]);
482 p = isl_printer_print_str(p, "]");
484 p = isl_printer_print_str(p, ": ");
487 p = print_constraints(bmap, dim, p, set, latex);
489 if (bmap->n_div > 0)
490 p = isl_printer_print_str(p, s_close_exists[latex]);
491 return p;
494 static __isl_give isl_printer *isl_basic_map_print_isl(
495 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int latex)
497 int i;
499 p = isl_printer_start_line(p);
500 if (isl_basic_map_dim(bmap, isl_dim_param) > 0) {
501 p = print_tuple(bmap->dim, p, isl_dim_param, 0, latex);
502 p = isl_printer_print_str(p, " -> ");
504 p = isl_printer_print_str(p, "{ ");
505 p = print_tuple(bmap->dim, p, isl_dim_in, 0, latex);
506 p = isl_printer_print_str(p, " -> ");
507 p = print_tuple(bmap->dim, p, isl_dim_out, 0, latex);
508 p = isl_printer_print_str(p, " : ");
509 p = print_disjunct(bmap, bmap->dim, p, 0, latex);
510 p = isl_printer_print_str(p, " }");
511 p = isl_printer_end_line(p);
512 return p;
515 static __isl_give isl_printer *isl_basic_set_print_isl(
516 __isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int latex)
518 int i;
520 p = isl_printer_start_line(p);
521 if (isl_basic_set_dim(bset, isl_dim_param) > 0) {
522 p = print_tuple(bset->dim, p, isl_dim_param, 0, latex);
523 p = isl_printer_print_str(p, " -> ");
525 p = isl_printer_print_str(p, "{ ");
526 p = print_tuple(bset->dim, p, isl_dim_set, 1, latex);
527 p = isl_printer_print_str(p, " : ");
528 p = print_disjunct((isl_basic_map *)bset, bset->dim, p, 1, latex);
529 p = isl_printer_print_str(p, " }");
530 p = isl_printer_end_line(p);
531 return p;
534 static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
535 __isl_take isl_printer *p, int set, int latex)
537 int i;
539 if (isl_map_fast_is_universe(map))
540 return p;
542 p = isl_printer_print_str(p, s_such_that[latex]);
543 if (map->n == 0)
544 p = isl_printer_print_str(p, "1 = 0");
545 for (i = 0; i < map->n; ++i) {
546 if (i)
547 p = isl_printer_print_str(p, s_or[latex]);
548 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
549 p = isl_printer_print_str(p, "(");
550 p = print_disjunct(map->p[i], map->dim, p, set, latex);
551 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
552 p = isl_printer_print_str(p, ")");
554 return p;
557 static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,
558 __isl_take isl_printer *p, int latex)
560 if (isl_map_dim(map, isl_dim_param) > 0) {
561 p = print_tuple(map->dim, p, isl_dim_param, 0, latex);
562 p = isl_printer_print_str(p, s_to[latex]);
564 p = isl_printer_print_str(p, s_open_set[latex]);
565 p = print_tuple(map->dim, p, isl_dim_in, 0, latex);
566 p = isl_printer_print_str(p, s_to[latex]);
567 p = print_tuple(map->dim, p, isl_dim_out, 0, latex);
568 p = print_disjuncts(map, p, 0, latex);
569 p = isl_printer_print_str(p, s_close_set[latex]);
570 return p;
573 static __isl_give isl_printer *isl_set_print_isl(__isl_keep isl_set *set,
574 __isl_take isl_printer *p, int latex)
576 int i;
578 if (isl_set_dim(set, isl_dim_param) > 0) {
579 p = print_tuple(set->dim, p, isl_dim_param, 0, latex);
580 p = isl_printer_print_str(p, " -> ");
582 p = isl_printer_print_str(p, "{ ");
583 p = print_tuple(set->dim, p, isl_dim_set, 1, latex);
584 p = print_disjuncts((isl_map *)set, p, 1, latex);
585 p = isl_printer_print_str(p, " }");
586 return p;
589 __isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p,
590 __isl_keep isl_basic_map *bmap)
592 if (!p || !bmap)
593 goto error;
594 if (p->output_format == ISL_FORMAT_ISL)
595 return isl_basic_map_print_isl(bmap, p, 0);
596 else if (p->output_format == ISL_FORMAT_OMEGA)
597 return isl_basic_map_print_omega(bmap, p);
598 isl_assert(bmap->ctx, 0, goto error);
599 error:
600 isl_printer_free(p);
601 return NULL;
604 void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent,
605 const char *prefix, const char *suffix, unsigned output_format)
607 isl_printer *printer;
609 if (!bmap)
610 return;
612 printer = isl_printer_to_file(bmap->ctx, out);
613 printer = isl_printer_set_indent(printer, indent);
614 printer = isl_printer_set_prefix(printer, prefix);
615 printer = isl_printer_set_suffix(printer, suffix);
616 printer = isl_printer_set_output_format(printer, output_format);
617 isl_printer_print_basic_map(printer, bmap);
619 isl_printer_free(printer);
622 __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,
623 __isl_keep isl_basic_set *bset)
625 if (!p || !bset)
626 goto error;
628 if (p->output_format == ISL_FORMAT_ISL)
629 return isl_basic_set_print_isl(bset, p, 0);
630 else if (p->output_format == ISL_FORMAT_POLYLIB)
631 return isl_basic_set_print_polylib(bset, p);
632 else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)
633 return bset_print_constraints_polylib(bset, p);
634 else if (p->output_format == ISL_FORMAT_OMEGA)
635 return isl_basic_set_print_omega(bset, p);
636 isl_assert(p->ctx, 0, goto error);
637 error:
638 isl_printer_free(p);
639 return NULL;
642 void isl_basic_set_print(struct isl_basic_set *bset, FILE *out, int indent,
643 const char *prefix, const char *suffix, unsigned output_format)
645 isl_printer *printer;
647 if (!bset)
648 return;
650 printer = isl_printer_to_file(bset->ctx, out);
651 printer = isl_printer_set_indent(printer, indent);
652 printer = isl_printer_set_prefix(printer, prefix);
653 printer = isl_printer_set_suffix(printer, suffix);
654 printer = isl_printer_set_output_format(printer, output_format);
655 isl_printer_print_basic_set(printer, bset);
657 isl_printer_free(printer);
660 __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,
661 __isl_keep isl_set *set)
663 if (!p || !set)
664 goto error;
665 if (p->output_format == ISL_FORMAT_ISL)
666 return isl_set_print_isl(set, p, 0);
667 else if (p->output_format == ISL_FORMAT_POLYLIB)
668 return isl_set_print_polylib(set, p);
669 else if (p->output_format == ISL_FORMAT_OMEGA)
670 return isl_set_print_omega(set, p);
671 isl_assert(set->ctx, 0, goto error);
672 error:
673 isl_printer_free(p);
674 return NULL;
677 void isl_set_print(struct isl_set *set, FILE *out, int indent,
678 unsigned output_format)
680 isl_printer *printer;
682 if (!set)
683 return;
685 printer = isl_printer_to_file(set->ctx, out);
686 printer = isl_printer_set_indent(printer, indent);
687 printer = isl_printer_set_output_format(printer, output_format);
688 printer = isl_printer_print_set(printer, set);
690 isl_printer_free(printer);
693 __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
694 __isl_keep isl_map *map)
696 if (!p || !map)
697 goto error;
699 if (p->output_format == ISL_FORMAT_ISL)
700 return isl_map_print_isl(map, p, 0);
701 else if (p->output_format == ISL_FORMAT_POLYLIB)
702 return isl_map_print_polylib(map, p);
703 else if (p->output_format == ISL_FORMAT_OMEGA)
704 return isl_map_print_omega(map, p);
705 else if (p->output_format == ISL_FORMAT_LATEX)
706 return isl_map_print_isl(map, p, 1);
707 isl_assert(map->ctx, 0, goto error);
708 error:
709 isl_printer_free(p);
710 return NULL;
713 void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent,
714 unsigned output_format)
716 isl_printer *printer;
718 if (!map)
719 return;
721 printer = isl_printer_to_file(map->ctx, out);
722 printer = isl_printer_set_indent(printer, indent);
723 printer = isl_printer_set_output_format(printer, output_format);
724 printer = isl_printer_print_map(printer, map);
726 isl_printer_free(printer);
729 static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec)
731 int i;
732 int n;
734 for (i = 0, n = 0; i < rec->n; ++i)
735 if (!isl_upoly_is_zero(rec->p[i]))
736 ++n;
738 return n;
741 static __isl_give isl_printer *print_div(__isl_keep isl_dim *dim,
742 __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p)
744 int c = p->output_format == ISL_FORMAT_C;
745 p = isl_printer_print_str(p, c ? "floord(" : "[(");
746 p = print_affine_of_len(dim, p, div->row[pos] + 1, div->n_col - 1, 1);
747 p = isl_printer_print_str(p, c ? ", " : ")/");
748 p = isl_printer_print_isl_int(p, div->row[pos][0]);
749 p = isl_printer_print_str(p, c ? ")" : "]");
750 return p;
753 static __isl_give isl_printer *upoly_print_cst(__isl_keep struct isl_upoly *up,
754 __isl_take isl_printer *p, int first)
756 struct isl_upoly_cst *cst;
757 int neg;
759 cst = isl_upoly_as_cst(up);
760 if (!cst)
761 goto error;
762 neg = !first && isl_int_is_neg(cst->n);
763 if (!first)
764 p = isl_printer_print_str(p, neg ? " - " : " + ");
765 if (neg)
766 isl_int_neg(cst->n, cst->n);
767 if (isl_int_is_zero(cst->d)) {
768 int sgn = isl_int_sgn(cst->n);
769 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
770 sgn == 0 ? "NaN" : "infty");
771 } else
772 p = isl_printer_print_isl_int(p, cst->n);
773 if (neg)
774 isl_int_neg(cst->n, cst->n);
775 if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) {
776 p = isl_printer_print_str(p, "/");
777 p = isl_printer_print_isl_int(p, cst->d);
779 return p;
780 error:
781 isl_printer_free(p);
782 return NULL;
785 static __isl_give isl_printer *print_base(__isl_take isl_printer *p,
786 __isl_keep isl_dim *dim, __isl_keep isl_mat *div, int var)
788 unsigned total;
790 total = isl_dim_total(dim);
791 if (var < total)
792 p = print_term(dim, dim->ctx->one, 1 + var, p, 1, 0);
793 else
794 p = print_div(dim, div, var - total, p);
795 return p;
798 static __isl_give isl_printer *print_pow(__isl_take isl_printer *p,
799 __isl_keep isl_dim *dim, __isl_keep isl_mat *div, int var, int exp)
801 p = print_base(p, dim, div, var);
802 if (exp == 1)
803 return p;
804 if (p->output_format == ISL_FORMAT_C) {
805 int i;
806 for (i = 1; i < exp; ++i) {
807 p = isl_printer_print_str(p, "*");
808 p = print_base(p, dim, div, var);
810 } else {
811 p = isl_printer_print_str(p, "^");
812 p = isl_printer_print_int(p, exp);
814 return p;
817 static __isl_give isl_printer *upoly_print(__isl_keep struct isl_upoly *up,
818 __isl_keep isl_dim *dim, __isl_keep isl_mat *div,
819 __isl_take isl_printer *p)
821 int i, n, first;
822 struct isl_upoly_rec *rec;
824 if (!p || !up || !dim || !div)
825 goto error;
827 if (isl_upoly_is_cst(up))
828 return upoly_print_cst(up, p, 1);
830 rec = isl_upoly_as_rec(up);
831 if (!rec)
832 goto error;
833 n = upoly_rec_n_non_zero(rec);
834 if (n > 1)
835 p = isl_printer_print_str(p, "(");
836 for (i = 0, first = 1; i < rec->n; ++i) {
837 if (isl_upoly_is_zero(rec->p[i]))
838 continue;
839 if (isl_upoly_is_negone(rec->p[i])) {
840 if (!i)
841 p = isl_printer_print_str(p, "-1");
842 else if (first)
843 p = isl_printer_print_str(p, "-");
844 else
845 p = isl_printer_print_str(p, " - ");
846 } else if (isl_upoly_is_cst(rec->p[i]) &&
847 !isl_upoly_is_one(rec->p[i]))
848 p = upoly_print_cst(rec->p[i], p, first);
849 else {
850 if (!first)
851 p = isl_printer_print_str(p, " + ");
852 if (i == 0 || !isl_upoly_is_one(rec->p[i]))
853 p = upoly_print(rec->p[i], dim, div, p);
855 first = 0;
856 if (i == 0)
857 continue;
858 if (!isl_upoly_is_one(rec->p[i]) &&
859 !isl_upoly_is_negone(rec->p[i]))
860 p = isl_printer_print_str(p, " * ");
861 p = print_pow(p, dim, div, rec->up.var, i);
863 if (n > 1)
864 p = isl_printer_print_str(p, ")");
865 return p;
866 error:
867 isl_printer_free(p);
868 return NULL;
871 __isl_give isl_printer *isl_printer_print_qpolynomial(__isl_take isl_printer *p,
872 __isl_keep isl_qpolynomial *qp)
874 if (!p || !qp)
875 goto error;
876 p = upoly_print(qp->upoly, qp->dim, qp->div, p);
877 return p;
878 error:
879 isl_printer_free(p);
880 return NULL;
883 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
884 unsigned output_format)
886 isl_printer *p;
888 if (!qp)
889 return;
891 isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);
892 p = isl_printer_to_file(qp->dim->ctx, out);
893 p = isl_printer_print_qpolynomial(p, qp);
894 isl_printer_free(p);
897 static __isl_give isl_printer *qpolynomial_fold_print(
898 __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
900 int i;
902 if (fold->type == isl_fold_min)
903 p = isl_printer_print_str(p, "min");
904 else if (fold->type == isl_fold_max)
905 p = isl_printer_print_str(p, "max");
906 p = isl_printer_print_str(p, "(");
907 for (i = 0; i < fold->n; ++i) {
908 if (i)
909 p = isl_printer_print_str(p, ", ");
910 p = isl_printer_print_qpolynomial(p, fold->qp[i]);
912 p = isl_printer_print_str(p, ")");
913 return p;
916 __isl_give isl_printer *isl_printer_print_qpolynomial_fold(
917 __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
919 if (!p || !fold)
920 goto error;
921 p = qpolynomial_fold_print(fold, p);
922 return p;
923 error:
924 isl_printer_free(p);
925 return NULL;
928 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
929 FILE *out, unsigned output_format)
931 isl_printer *p;
933 if (!fold)
934 return;
936 isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);
938 p = isl_printer_to_file(fold->dim->ctx, out);
939 p = isl_printer_print_qpolynomial_fold(p, fold);
941 isl_printer_free(p);
944 static __isl_give isl_printer *print_pw_qpolynomial_isl(
945 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
947 int i = 0;
949 if (!p || !pwqp)
950 goto error;
952 if (isl_dim_size(pwqp->dim, isl_dim_param) > 0) {
953 p = print_tuple(pwqp->dim, p, isl_dim_param, 0, 0);
954 p = isl_printer_print_str(p, " -> ");
956 p = isl_printer_print_str(p, "{ ");
957 if (pwqp->n == 0) {
958 if (isl_dim_size(pwqp->dim, isl_dim_set) > 0) {
959 p = print_tuple(pwqp->dim, p, isl_dim_set, 1, 0);
960 p = isl_printer_print_str(p, " -> ");
962 p = isl_printer_print_str(p, "0");
964 for (i = 0; i < pwqp->n; ++i) {
965 if (i)
966 p = isl_printer_print_str(p, "; ");
967 if (isl_dim_size(pwqp->p[i].set->dim, isl_dim_set) > 0) {
968 p = print_tuple(pwqp->p[i].set->dim, p, isl_dim_set, 1, 0);
969 p = isl_printer_print_str(p, " -> ");
971 p = isl_printer_print_qpolynomial(p, pwqp->p[i].qp);
972 p = print_disjuncts((isl_map *)pwqp->p[i].set, p, 1, 0);
974 p = isl_printer_print_str(p, " }");
975 return p;
976 error:
977 isl_printer_free(p);
978 return NULL;
981 void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
982 unsigned output_format)
984 isl_printer *p;
986 if (!pwqp)
987 return;
989 p = isl_printer_to_file(pwqp->dim->ctx, out);
990 p = isl_printer_set_output_format(p, output_format);
991 p = isl_printer_print_pw_qpolynomial(p, pwqp);
993 isl_printer_free(p);
996 static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(
997 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
999 int i = 0;
1001 if (isl_dim_size(pwf->dim, isl_dim_param) > 0) {
1002 p = print_tuple(pwf->dim, p, isl_dim_param, 0, 0);
1003 p = isl_printer_print_str(p, " -> ");
1005 p = isl_printer_print_str(p, "{ ");
1006 if (pwf->n == 0) {
1007 if (isl_dim_size(pwf->dim, isl_dim_set) > 0) {
1008 p = print_tuple(pwf->dim, p, isl_dim_set, 0, 0);
1009 p = isl_printer_print_str(p, " -> ");
1011 p = isl_printer_print_str(p, "0");
1013 for (i = 0; i < pwf->n; ++i) {
1014 if (i)
1015 p = isl_printer_print_str(p, "; ");
1016 if (isl_dim_size(pwf->p[i].set->dim, isl_dim_set) > 0) {
1017 p = print_tuple(pwf->p[i].set->dim, p, isl_dim_set, 0, 0);
1018 p = isl_printer_print_str(p, " -> ");
1020 p = qpolynomial_fold_print(pwf->p[i].fold, p);
1021 p = print_disjuncts((isl_map *)pwf->p[i].set, p, 1, 0);
1023 p = isl_printer_print_str(p, " }");
1024 return p;
1027 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1028 __isl_keep isl_basic_set *bset, isl_int *c);
1030 static __isl_give isl_printer *print_name_c(__isl_take isl_printer *p,
1031 __isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos)
1033 if (type == isl_dim_div) {
1034 p = isl_printer_print_str(p, "floord(");
1035 p = print_affine_c(p, bset, bset->div[pos] + 1);
1036 p = isl_printer_print_str(p, ", ");
1037 p = isl_printer_print_isl_int(p, bset->div[pos][0]);
1038 p = isl_printer_print_str(p, ")");
1039 } else {
1040 const char *name;
1042 name = isl_dim_get_name(bset->dim, type, pos);
1043 if (!name)
1044 name = "UNNAMED";
1045 p = isl_printer_print_str(p, name);
1047 return p;
1050 static __isl_give isl_printer *print_term_c(__isl_take isl_printer *p,
1051 __isl_keep isl_basic_set *bset, isl_int c, unsigned pos)
1053 enum isl_dim_type type;
1054 unsigned nparam = isl_basic_set_dim(bset, isl_dim_param);
1056 if (pos == 0)
1057 return isl_printer_print_isl_int(p, c);
1059 if (isl_int_is_one(c))
1061 else if (isl_int_is_negone(c))
1062 p = isl_printer_print_str(p, "-");
1063 else {
1064 p = isl_printer_print_isl_int(p, c);
1065 p = isl_printer_print_str(p, "*");
1067 type = pos2type(bset->dim, &pos);
1068 p = print_name_c(p, bset, type, pos);
1069 return p;
1072 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1073 __isl_keep isl_basic_set *bset, isl_int *c)
1075 int i;
1076 int first;
1077 unsigned len = 1 + isl_basic_set_total_dim(bset);
1079 for (i = 0, first = 1; i < len; ++i) {
1080 int flip = 0;
1081 if (isl_int_is_zero(c[i]))
1082 continue;
1083 if (!first) {
1084 if (isl_int_is_neg(c[i])) {
1085 flip = 1;
1086 isl_int_neg(c[i], c[i]);
1087 p = isl_printer_print_str(p, " - ");
1088 } else
1089 p = isl_printer_print_str(p, " + ");
1091 first = 0;
1092 p = print_term_c(p, bset, c[i], i);
1093 if (flip)
1094 isl_int_neg(c[i], c[i]);
1096 if (first)
1097 p = isl_printer_print_str(p, "0");
1098 return p;
1101 static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,
1102 __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int first)
1104 if (!first)
1105 p = isl_printer_print_str(p, " && ");
1107 p = print_affine_c(p, bset, c);
1108 p = isl_printer_print_str(p, " ");
1109 p = isl_printer_print_str(p, op);
1110 p = isl_printer_print_str(p, " 0");
1111 return p;
1114 static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,
1115 __isl_keep isl_basic_set *bset)
1117 int i;
1119 for (i = 0; i < bset->n_eq; ++i)
1120 p = print_constraint_c(p, bset, bset->eq[i], "==", !i);
1121 for (i = 0; i < bset->n_ineq; ++i)
1122 p = print_constraint_c(p, bset, bset->ineq[i], ">=",
1123 !bset->n_eq && !i);
1124 return p;
1127 static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,
1128 __isl_keep isl_set *set)
1130 int i;
1132 if (set->n == 0)
1133 p = isl_printer_print_str(p, "0");
1135 for (i = 0; i < set->n; ++i) {
1136 if (i)
1137 p = isl_printer_print_str(p, " || ");
1138 if (set->n > 1)
1139 p = isl_printer_print_str(p, "(");
1140 p = print_basic_set_c(p, set->p[i]);
1141 if (set->n > 1)
1142 p = isl_printer_print_str(p, ")");
1144 return p;
1147 static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p,
1148 __isl_keep isl_qpolynomial *qp)
1150 isl_int den;
1152 isl_int_init(den);
1153 isl_qpolynomial_get_den(qp, &den);
1154 if (!isl_int_is_one(den)) {
1155 isl_qpolynomial *f;
1156 p = isl_printer_print_str(p, "(");
1157 qp = isl_qpolynomial_copy(qp);
1158 f = isl_qpolynomial_rat_cst(isl_dim_copy(qp->dim),
1159 den, qp->dim->ctx->one);
1160 qp = isl_qpolynomial_mul(qp, f);
1162 if (qp)
1163 p = upoly_print(qp->upoly, qp->dim, qp->div, p);
1164 if (!isl_int_is_one(den)) {
1165 p = isl_printer_print_str(p, ")/");
1166 p = isl_printer_print_isl_int(p, den);
1167 isl_qpolynomial_free(qp);
1169 isl_int_clear(den);
1170 return p;
1173 static __isl_give isl_printer *print_pw_qpolynomial_c(
1174 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwpq)
1176 int i;
1178 if (pwpq->n == 1 && isl_set_fast_is_universe(pwpq->p[0].set))
1179 return print_qpolynomial_c(p, pwpq->p[0].qp);
1181 for (i = 0; i < pwpq->n; ++i) {
1182 p = isl_printer_print_str(p, "(");
1183 p = print_set_c(p, pwpq->p[i].set);
1184 p = isl_printer_print_str(p, ") ? (");
1185 p = print_qpolynomial_c(p, pwpq->p[i].qp);
1186 p = isl_printer_print_str(p, ") : ");
1189 p = isl_printer_print_str(p, "0");
1190 return p;
1193 __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
1194 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1196 if (!p || !pwqp)
1197 goto error;
1199 if (p->output_format == ISL_FORMAT_ISL)
1200 return print_pw_qpolynomial_isl(p, pwqp);
1201 else if (p->output_format == ISL_FORMAT_C)
1202 return print_pw_qpolynomial_c(p, pwqp);
1203 isl_assert(p->ctx, 0, goto error);
1204 error:
1205 isl_printer_free(p);
1206 return NULL;
1209 static __isl_give isl_printer *print_qpolynomial_fold_c(
1210 __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
1212 int i;
1214 for (i = 0; i < fold->n - 1; ++i)
1215 if (fold->type == isl_fold_min)
1216 p = isl_printer_print_str(p, "min(");
1217 else if (fold->type == isl_fold_max)
1218 p = isl_printer_print_str(p, "max(");
1220 for (i = 0; i < fold->n; ++i) {
1221 if (i)
1222 p = isl_printer_print_str(p, ", ");
1223 p = print_qpolynomial_c(p, fold->qp[i]);
1224 if (i)
1225 p = isl_printer_print_str(p, ")");
1227 return p;
1230 static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
1231 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1233 int i;
1235 if (pwf->n == 1 && isl_set_fast_is_universe(pwf->p[0].set))
1236 return print_qpolynomial_fold_c(p, pwf->p[0].fold);
1238 for (i = 0; i < pwf->n; ++i) {
1239 p = isl_printer_print_str(p, "(");
1240 p = print_set_c(p, pwf->p[i].set);
1241 p = isl_printer_print_str(p, ") ? (");
1242 p = print_qpolynomial_fold_c(p, pwf->p[i].fold);
1243 p = isl_printer_print_str(p, ") : ");
1246 p = isl_printer_print_str(p, "0");
1247 return p;
1250 __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
1251 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1253 if (!p || !pwf)
1254 goto error;
1256 if (p->output_format == ISL_FORMAT_ISL)
1257 return print_pw_qpolynomial_fold_isl(p, pwf);
1258 else if (p->output_format == ISL_FORMAT_C)
1259 return print_pw_qpolynomial_fold_c(p, pwf);
1260 isl_assert(p->ctx, 0, goto error);
1261 error:
1262 isl_printer_free(p);
1263 return NULL;
1266 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
1267 FILE *out, unsigned output_format)
1269 isl_printer *p;
1271 if (!pwf)
1272 return;
1274 p = isl_printer_to_file(pwf->dim->ctx, out);
1275 p = isl_printer_set_output_format(p, output_format);
1276 p = isl_printer_print_pw_qpolynomial_fold(p, pwf);
1278 isl_printer_free(p);