export isl_space_is_wrapping
[isl.git] / isl_output.c
blob127eae459f828f82103d9c4ef811e0213140b8a5
1 /*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010 INRIA Saclay
4 * Copyright 2012-2013 Ecole Normale Superieure
6 * Use of this software is governed by the MIT license
8 * Written by Sven Verdoolaege, K.U.Leuven, Departement
9 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
10 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
11 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
12 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
15 #include <stdlib.h>
16 #include <string.h>
17 #include <isl_ctx_private.h>
18 #include <isl_map_private.h>
19 #include <isl/set.h>
20 #include <isl_seq.h>
21 #include <isl_polynomial_private.h>
22 #include <isl_printer_private.h>
23 #include <isl_space_private.h>
24 #include <isl_mat_private.h>
25 #include <isl_vec_private.h>
26 #include <isl/union_set.h>
27 #include <isl/union_map.h>
28 #include <isl/constraint.h>
29 #include <isl_local.h>
30 #include <isl_local_space_private.h>
31 #include <isl_aff_private.h>
32 #include <isl_id_private.h>
33 #include <isl_val_private.h>
34 #include <isl_constraint_private.h>
35 #include <isl/ast_build.h>
36 #include <isl_sort.h>
37 #include <isl_output_private.h>
39 #include <bset_to_bmap.c>
40 #include <set_to_map.c>
41 #include <uset_to_umap.c>
43 static const char *s_to[2] = { " -> ", " \\to " };
44 static const char *s_and[2] = { " and ", " \\wedge " };
45 static const char *s_or[2] = { " or ", " \\vee " };
46 static const char *s_le[2] = { "<=", "\\le" };
47 static const char *s_ge[2] = { ">=", "\\ge" };
48 static const char *s_open_set[2] = { "{ ", "\\{\\, " };
49 static const char *s_close_set[2] = { " }", " \\,\\}" };
50 static const char *s_open_list[2] = { "[", "(" };
51 static const char *s_close_list[2] = { "]", ")" };
52 static const char *s_such_that[2] = { " : ", " \\mid " };
53 static const char *s_open_exists[2] = { "exists (", "\\exists \\, " };
54 static const char *s_close_exists[2] = { ")", "" };
55 static const char *s_div_prefix[2] = { "e", "\\alpha_" };
56 static const char *s_mod[2] = { "mod", "\\bmod" };
57 static const char *s_param_prefix[2] = { "p", "p_" };
58 static const char *s_input_prefix[2] = { "i", "i_" };
59 static const char *s_output_prefix[2] = { "o", "o_" };
61 static __isl_give isl_printer *print_constraint_polylib(
62 struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p)
64 int i;
65 isl_size n_in = isl_basic_map_dim(bmap, isl_dim_in);
66 isl_size n_out = isl_basic_map_dim(bmap, isl_dim_out);
67 isl_size nparam = isl_basic_map_dim(bmap, isl_dim_param);
68 isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n];
70 if (n_in < 0 || n_out < 0 || nparam < 0)
71 return isl_printer_free(p);
73 p = isl_printer_start_line(p);
74 p = isl_printer_print_int(p, ineq);
75 for (i = 0; i < n_out; ++i) {
76 p = isl_printer_print_str(p, " ");
77 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]);
79 for (i = 0; i < n_in; ++i) {
80 p = isl_printer_print_str(p, " ");
81 p = isl_printer_print_isl_int(p, c[1+nparam+i]);
83 for (i = 0; i < bmap->n_div; ++i) {
84 p = isl_printer_print_str(p, " ");
85 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]);
87 for (i = 0; i < nparam; ++i) {
88 p = isl_printer_print_str(p, " ");
89 p = isl_printer_print_isl_int(p, c[1+i]);
91 p = isl_printer_print_str(p, " ");
92 p = isl_printer_print_isl_int(p, c[0]);
93 p = isl_printer_end_line(p);
94 return p;
97 static __isl_give isl_printer *print_constraints_polylib(
98 struct isl_basic_map *bmap, __isl_take isl_printer *p)
100 int i;
102 p = isl_printer_set_isl_int_width(p, 5);
104 for (i = 0; i < bmap->n_eq; ++i)
105 p = print_constraint_polylib(bmap, 0, i, p);
106 for (i = 0; i < bmap->n_ineq; ++i)
107 p = print_constraint_polylib(bmap, 1, i, p);
109 return p;
112 static __isl_give isl_printer *bset_print_constraints_polylib(
113 struct isl_basic_set *bset, __isl_take isl_printer *p)
115 return print_constraints_polylib(bset_to_bmap(bset), p);
118 static __isl_give isl_printer *isl_basic_map_print_polylib(
119 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int ext)
121 isl_size total;
123 total = isl_basic_map_dim(bmap, isl_dim_all);
124 if (total < 0)
125 return isl_printer_free(p);
126 p = isl_printer_start_line(p);
127 p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq);
128 p = isl_printer_print_str(p, " ");
129 p = isl_printer_print_int(p, 1 + total + 1);
130 if (ext) {
131 isl_size n_in = isl_basic_map_dim(bmap, isl_dim_in);
132 isl_size n_out = isl_basic_map_dim(bmap, isl_dim_out);
133 isl_size n_div = isl_basic_map_dim(bmap, isl_dim_div);
134 isl_size nparam = isl_basic_map_dim(bmap, isl_dim_param);
136 if (n_in < 0 || n_out < 0 || n_div < 0 || nparam < 0)
137 return isl_printer_free(p);
139 p = isl_printer_print_str(p, " ");
140 p = isl_printer_print_int(p, n_out);
141 p = isl_printer_print_str(p, " ");
142 p = isl_printer_print_int(p, n_in);
143 p = isl_printer_print_str(p, " ");
144 p = isl_printer_print_int(p, n_div);
145 p = isl_printer_print_str(p, " ");
146 p = isl_printer_print_int(p, nparam);
148 p = isl_printer_end_line(p);
149 return print_constraints_polylib(bmap, p);
152 static __isl_give isl_printer *isl_basic_set_print_polylib(
153 __isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int ext)
155 return isl_basic_map_print_polylib(bset_to_bmap(bset), p, ext);
158 static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map,
159 __isl_take isl_printer *p, int ext)
161 int i;
163 p = isl_printer_start_line(p);
164 p = isl_printer_print_int(p, map->n);
165 p = isl_printer_end_line(p);
166 for (i = 0; i < map->n; ++i) {
167 p = isl_printer_start_line(p);
168 p = isl_printer_end_line(p);
169 p = isl_basic_map_print_polylib(map->p[i], p, ext);
171 return p;
174 static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set,
175 __isl_take isl_printer *p, int ext)
177 return isl_map_print_polylib(set_to_map(set), p, ext);
180 static isl_size count_same_name(__isl_keep isl_space *space,
181 enum isl_dim_type type, unsigned pos, const char *name)
183 enum isl_dim_type t;
184 int p;
185 isl_size s;
186 int count = 0;
188 for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) {
189 s = t == type ? pos : isl_space_dim(space, t);
190 if (s < 0)
191 return isl_size_error;
192 for (p = 0; p < s; ++p) {
193 const char *n = isl_space_get_dim_name(space, t, p);
194 if (n && !strcmp(n, name))
195 count++;
198 return count;
201 /* Print the name of the variable of type "type" and position "pos"
202 * in "space" to "p".
204 static __isl_give isl_printer *print_name(__isl_keep isl_space *space,
205 __isl_take isl_printer *p, enum isl_dim_type type, unsigned pos,
206 int latex)
208 const char *name;
209 char buffer[20];
210 isl_size primes;
212 name = type == isl_dim_div ? NULL
213 : isl_space_get_dim_name(space, type, pos);
215 if (!name) {
216 const char *prefix;
217 if (type == isl_dim_param)
218 prefix = s_param_prefix[latex];
219 else if (type == isl_dim_div)
220 prefix = s_div_prefix[latex];
221 else if (isl_space_is_set(space) || type == isl_dim_in)
222 prefix = s_input_prefix[latex];
223 else
224 prefix = s_output_prefix[latex];
225 snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);
226 name = buffer;
228 primes = count_same_name(space, name == buffer ? isl_dim_div : type,
229 pos, name);
230 if (primes < 0)
231 return isl_printer_free(p);
232 p = isl_printer_print_str(p, name);
233 while (primes-- > 0)
234 p = isl_printer_print_str(p, "'");
235 return p;
238 static isl_stat pos2type(__isl_keep isl_space *space,
239 enum isl_dim_type *type, unsigned *pos)
241 isl_size n_in = isl_space_dim(space, isl_dim_in);
242 isl_size n_out = isl_space_dim(space, isl_dim_out);
243 isl_size nparam = isl_space_dim(space, isl_dim_param);
245 if (n_in < 0 || n_out < 0 || nparam < 0)
246 return isl_stat_error;
248 if (*pos < 1 + nparam) {
249 *type = isl_dim_param;
250 *pos -= 1;
251 } else if (*pos < 1 + nparam + n_in) {
252 *type = isl_dim_in;
253 *pos -= 1 + nparam;
254 } else if (*pos < 1 + nparam + n_in + n_out) {
255 *type = isl_dim_out;
256 *pos -= 1 + nparam + n_in;
257 } else {
258 *type = isl_dim_div;
259 *pos -= 1 + nparam + n_in + n_out;
262 return isl_stat_ok;
265 /* Can the div expression of the integer division at position "row" of "div"
266 * be printed?
267 * In particular, are the div expressions available and does the selected
268 * variable have a known explicit representation?
269 * Furthermore, the Omega format does not allow any div expressions
270 * to be printed.
272 static isl_bool can_print_div_expr(__isl_keep isl_printer *p,
273 __isl_keep isl_mat *div, int pos)
275 if (p->output_format == ISL_FORMAT_OMEGA)
276 return isl_bool_false;
277 if (!div)
278 return isl_bool_false;
279 return isl_bool_not(isl_local_div_is_marked_unknown(div, pos));
282 static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
283 __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p);
285 static __isl_give isl_printer *print_term(__isl_keep isl_space *space,
286 __isl_keep isl_mat *div,
287 isl_int c, unsigned pos, __isl_take isl_printer *p, int latex)
289 enum isl_dim_type type;
290 int print_div_def;
292 if (!p || !space)
293 return isl_printer_free(p);
295 if (pos == 0)
296 return isl_printer_print_isl_int(p, c);
298 if (pos2type(space, &type, &pos) < 0)
299 return isl_printer_free(p);
300 print_div_def = type == isl_dim_div && can_print_div_expr(p, div, pos);
302 if (isl_int_is_one(c))
304 else if (isl_int_is_negone(c))
305 p = isl_printer_print_str(p, "-");
306 else {
307 p = isl_printer_print_isl_int(p, c);
308 if (p->output_format == ISL_FORMAT_C || print_div_def)
309 p = isl_printer_print_str(p, "*");
311 if (print_div_def)
312 p = print_div(space, div, pos, p);
313 else
314 p = print_name(space, p, type, pos, latex);
315 return p;
318 static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *dim,
319 __isl_keep isl_mat *div,
320 __isl_take isl_printer *p, isl_int *c, int len)
322 int i;
323 int first;
325 for (i = 0, first = 1; i < len; ++i) {
326 int flip = 0;
327 if (isl_int_is_zero(c[i]))
328 continue;
329 if (!first) {
330 if (isl_int_is_neg(c[i])) {
331 flip = 1;
332 isl_int_neg(c[i], c[i]);
333 p = isl_printer_print_str(p, " - ");
334 } else
335 p = isl_printer_print_str(p, " + ");
337 first = 0;
338 p = print_term(dim, div, c[i], i, p, 0);
339 if (flip)
340 isl_int_neg(c[i], c[i]);
342 if (first)
343 p = isl_printer_print_str(p, "0");
344 return p;
347 /* Print an affine expression "c"
348 * to "p", with the variable names taken from "space" and
349 * the integer division definitions taken from "div".
351 static __isl_give isl_printer *print_affine(__isl_take isl_printer *p,
352 __isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c)
354 isl_size n_div, total;
355 unsigned len;
357 total = isl_space_dim(space, isl_dim_all);
358 n_div = isl_mat_rows(div);
359 if (total < 0 || n_div < 0)
360 return isl_printer_free(p);
361 len = 1 + total + n_div;
362 return print_affine_of_len(space, div, p, c, len);
365 /* offset is the offset of local_space inside data->type of data->space.
367 static __isl_give isl_printer *print_nested_var_list(__isl_take isl_printer *p,
368 __isl_keep isl_space *local_space, enum isl_dim_type local_type,
369 struct isl_print_space_data *data, int offset)
371 int i;
372 isl_size dim;
374 if (data->space != local_space && local_type == isl_dim_out)
375 offset += local_space->n_in;
377 dim = isl_space_dim(local_space, local_type);
378 if (dim < 0)
379 return isl_printer_free(p);
380 for (i = 0; i < dim; ++i) {
381 if (i)
382 p = isl_printer_print_str(p, ", ");
383 if (data->print_dim)
384 p = data->print_dim(p, data, offset + i);
385 else
386 p = print_name(data->space, p, data->type, offset + i,
387 data->latex);
389 return p;
392 static __isl_give isl_printer *print_var_list(__isl_take isl_printer *p,
393 __isl_keep isl_space *space, enum isl_dim_type type)
395 struct isl_print_space_data data = { .space = space, .type = type };
397 return print_nested_var_list(p, space, type, &data, 0);
400 static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
401 __isl_keep isl_space *local_dim,
402 struct isl_print_space_data *data, int offset);
404 static __isl_give isl_printer *print_nested_tuple(__isl_take isl_printer *p,
405 __isl_keep isl_space *local_space, enum isl_dim_type local_type,
406 struct isl_print_space_data *data, int offset)
408 const char *name = NULL;
409 isl_size n = isl_space_dim(local_space, local_type);
411 if (n < 0)
412 return isl_printer_free(p);
413 if ((local_type == isl_dim_in || local_type == isl_dim_out)) {
414 name = isl_space_get_tuple_name(local_space, local_type);
415 if (name) {
416 if (data->latex)
417 p = isl_printer_print_str(p, "\\mathrm{");
418 p = isl_printer_print_str(p, name);
419 if (data->latex)
420 p = isl_printer_print_str(p, "}");
423 if (!data->latex || n != 1 || name)
424 p = isl_printer_print_str(p, s_open_list[data->latex]);
425 if ((local_type == isl_dim_in || local_type == isl_dim_out) &&
426 local_space->nested[local_type - isl_dim_in]) {
427 if (data->space != local_space && local_type == isl_dim_out)
428 offset += local_space->n_in;
429 p = print_nested_map_dim(p,
430 local_space->nested[local_type - isl_dim_in],
431 data, offset);
432 } else
433 p = print_nested_var_list(p, local_space, local_type, data,
434 offset);
435 if (!data->latex || n != 1 || name)
436 p = isl_printer_print_str(p, s_close_list[data->latex]);
437 return p;
440 static __isl_give isl_printer *print_tuple(__isl_keep isl_space *dim,
441 __isl_take isl_printer *p, enum isl_dim_type type,
442 struct isl_print_space_data *data)
444 data->space = dim;
445 data->type = type;
446 return print_nested_tuple(p, dim, type, data, 0);
449 static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
450 __isl_keep isl_space *local_dim,
451 struct isl_print_space_data *data, int offset)
453 p = print_nested_tuple(p, local_dim, isl_dim_in, data, offset);
454 p = isl_printer_print_str(p, s_to[data->latex]);
455 p = print_nested_tuple(p, local_dim, isl_dim_out, data, offset);
457 return p;
460 __isl_give isl_printer *isl_print_space(__isl_keep isl_space *space,
461 __isl_take isl_printer *p, int rational,
462 struct isl_print_space_data *data)
464 if (rational && !data->latex)
465 p = isl_printer_print_str(p, "rat: ");
466 if (isl_space_is_params(space))
468 else if (isl_space_is_set(space))
469 p = print_tuple(space, p, isl_dim_set, data);
470 else {
471 p = print_tuple(space, p, isl_dim_in, data);
472 p = isl_printer_print_str(p, s_to[data->latex]);
473 p = print_tuple(space, p, isl_dim_out, data);
476 return p;
479 static __isl_give isl_printer *print_omega_parameters(
480 __isl_keep isl_space *space, __isl_take isl_printer *p)
482 isl_size nparam = isl_space_dim(space, isl_dim_param);
484 if (nparam < 0)
485 return isl_printer_free(p);
486 if (nparam == 0)
487 return p;
489 p = isl_printer_start_line(p);
490 p = isl_printer_print_str(p, "symbolic ");
491 p = print_var_list(p, space, isl_dim_param);
492 p = isl_printer_print_str(p, ";");
493 p = isl_printer_end_line(p);
494 return p;
497 /* Does the inequality constraint following "i" in "bmap"
498 * have an opposite value for the same last coefficient?
499 * "last" is the position of the last coefficient of inequality "i".
500 * If the next constraint is a div constraint, then it is ignored
501 * since div constraints are not printed.
503 static isl_bool next_is_opposite(__isl_keep isl_basic_map *bmap, int i,
504 int last)
506 int r;
507 isl_size total = isl_basic_map_dim(bmap, isl_dim_all);
508 unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
510 if (total < 0)
511 return isl_bool_error;
512 if (i + 1 >= bmap->n_ineq)
513 return isl_bool_false;
514 if (isl_seq_last_non_zero(bmap->ineq[i + 1], 1 + total) != last)
515 return isl_bool_false;
516 if (last >= o_div) {
517 isl_bool is_div;
518 is_div = isl_basic_map_is_div_constraint(bmap,
519 bmap->ineq[i + 1], last - o_div);
520 if (is_div < 0)
521 return isl_bool_error;
522 if (is_div)
523 return isl_bool_false;
525 r = isl_int_abs_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]) &&
526 !isl_int_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]);
527 return isl_bool_ok(r);
530 /* Return a string representation of the operator used when
531 * printing a constraint where the LHS is greater than or equal to the LHS
532 * (sign > 0) or smaller than or equal to the LHS (sign < 0).
533 * If "strict" is set, then return the strict version of the comparison
534 * operator.
536 static const char *constraint_op(int sign, int strict, int latex)
538 if (strict)
539 return sign < 0 ? "<" : ">";
540 if (sign < 0)
541 return s_le[latex];
542 else
543 return s_ge[latex];
546 /* Print one side of a constraint "c" to "p", with
547 * the variable names taken from "space" and the integer division definitions
548 * taken from "div".
549 * "last" is the position of the last non-zero coefficient.
550 * Let c' be the result of zeroing out this coefficient, then
551 * the partial constraint
553 * c' op
555 * is printed.
557 static __isl_give isl_printer *print_half_constraint(__isl_take isl_printer *p,
558 __isl_keep isl_space *space, __isl_keep isl_mat *div,
559 isl_int *c, int last, const char *op, int latex)
561 isl_int_set_si(c[last], 0);
562 p = print_affine(p, space, div, c);
564 p = isl_printer_print_str(p, " ");
565 p = isl_printer_print_str(p, op);
566 p = isl_printer_print_str(p, " ");
568 return p;
571 /* Print a constraint "c" to "p", with the variable names
572 * taken from "space" and the integer division definitions taken from "div".
573 * "last" is the position of the last non-zero coefficient, which is
574 * moreover assumed to be negative.
575 * Let c' be the result of zeroing out this coefficient, then
576 * the constraint is printed in the form
578 * -c[last] op c'
580 static __isl_give isl_printer *print_constraint(__isl_take isl_printer *p,
581 __isl_keep isl_space *space, __isl_keep isl_mat *div,
582 isl_int *c, int last, const char *op, int latex)
584 isl_int_abs(c[last], c[last]);
586 p = print_term(space, div, c[last], last, p, latex);
588 p = isl_printer_print_str(p, " ");
589 p = isl_printer_print_str(p, op);
590 p = isl_printer_print_str(p, " ");
592 isl_int_set_si(c[last], 0);
593 p = print_affine(p, space, div, c);
595 return p;
598 /* Given an integer division
600 * floor(f/m)
602 * at position "pos" in "div", print the corresponding modulo expression
604 * (f) mod m
606 * to "p". The variable names are taken from "space", while any
607 * nested integer division definitions are taken from "div".
609 static __isl_give isl_printer *print_mod(__isl_take isl_printer *p,
610 __isl_keep isl_space *space, __isl_keep isl_mat *div, int pos,
611 int latex)
613 if (!p || !div)
614 return isl_printer_free(p);
616 p = isl_printer_print_str(p, "(");
617 p = print_affine_of_len(space, div, p,
618 div->row[pos] + 1, div->n_col - 1);
619 p = isl_printer_print_str(p, ") ");
620 p = isl_printer_print_str(p, s_mod[latex]);
621 p = isl_printer_print_str(p, " ");
622 p = isl_printer_print_isl_int(p, div->row[pos][0]);
623 return p;
626 /* Can the equality constraints "c" be printed as a modulo constraint?
627 * In particular, is of the form
629 * f - a m floor(g/m) = 0,
631 * with c = -a m the coefficient at position "pos"?
632 * Return the position of the corresponding integer division if so.
633 * Return the number of integer divisions if not.
634 * Return -1 on error.
636 * Modulo constraints are currently not printed in C format.
637 * Other than that, "pos" needs to correspond to an integer division
638 * with explicit representation and "c" needs to be a multiple
639 * of the denominator of the integer division.
641 static isl_size print_as_modulo_pos(__isl_keep isl_printer *p,
642 __isl_keep isl_space *space, __isl_keep isl_mat *div, unsigned pos,
643 isl_int c)
645 isl_bool can_print;
646 isl_size n_div;
647 enum isl_dim_type type;
649 n_div = isl_mat_rows(div);
650 if (!p || !space || n_div < 0)
651 return isl_size_error;
652 if (p->output_format == ISL_FORMAT_C)
653 return n_div;
654 if (pos2type(space, &type, &pos) < 0)
655 return -1;
656 if (type != isl_dim_div)
657 return n_div;
658 can_print = can_print_div_expr(p, div, pos);
659 if (can_print < 0)
660 return isl_size_error;
661 if (!can_print)
662 return n_div;
663 if (!isl_int_is_divisible_by(c, div->row[pos][0]))
664 return n_div;
665 return pos;
668 /* Print equality constraint "c" to "p" as a modulo constraint,
669 * with the variable names taken from "space" and
670 * the integer division definitions taken from "div".
671 * "last" is the position of the last non-zero coefficient, which is
672 * moreover assumed to be negative and a multiple of the denominator
673 * of the corresponding integer division. "div_pos" is the corresponding
674 * position in the sequence of integer divisions.
676 * The equality is of the form
678 * f - a m floor(g/m) = 0.
680 * Print it as
682 * a (g mod m) = -f + a g
684 static __isl_give isl_printer *print_eq_mod_constraint(
685 __isl_take isl_printer *p, __isl_keep isl_space *space,
686 __isl_keep isl_mat *div, unsigned div_pos,
687 isl_int *c, int last, int latex)
689 isl_ctx *ctx;
690 int multiple;
692 ctx = isl_printer_get_ctx(p);
693 isl_int_divexact(c[last], c[last], div->row[div_pos][0]);
694 isl_int_abs(c[last], c[last]);
695 multiple = !isl_int_is_one(c[last]);
696 if (multiple) {
697 p = isl_printer_print_isl_int(p, c[last]);
698 p = isl_printer_print_str(p, "*(");
700 p = print_mod(p, space, div, div_pos, latex);
701 if (multiple)
702 p = isl_printer_print_str(p, ")");
703 p = isl_printer_print_str(p, " = ");
704 isl_seq_combine(c, ctx->negone, c,
705 c[last], div->row[div_pos] + 1, last);
706 isl_int_set_si(c[last], 0);
707 p = print_affine(p, space, div, c);
708 return p;
711 /* Print equality constraint "c" to "p", with the variable names
712 * taken from "space" and the integer division definitions taken from "div".
713 * "last" is the position of the last non-zero coefficient, which is
714 * moreover assumed to be negative.
716 * If possible, print the equality constraint as a modulo constraint.
718 static __isl_give isl_printer *print_eq_constraint(__isl_take isl_printer *p,
719 __isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c,
720 int last, int latex)
722 isl_size n_div;
723 isl_size div_pos;
725 n_div = isl_mat_rows(div);
726 div_pos = print_as_modulo_pos(p, space, div, last, c[last]);
727 if (n_div < 0 || div_pos < 0)
728 return isl_printer_free(p);
729 if (div_pos < n_div)
730 return print_eq_mod_constraint(p, space, div, div_pos,
731 c, last, latex);
732 return print_constraint(p, space, div, c, last, "=", latex);
735 /* Print the constraints of "bmap" to "p".
736 * The names of the variables are taken from "space" and
737 * the integer division definitions are taken from "div".
738 * Div constraints are only printed in "dump" mode.
739 * The constraints are sorted prior to printing (except in "dump" mode).
741 * If x is the last variable with a non-zero coefficient,
742 * then a lower bound
744 * f - a x >= 0
746 * is printed as
748 * a x <= f
750 * while an upper bound
752 * f + a x >= 0
754 * is printed as
756 * a x >= -f
758 * If the next constraint has an opposite sign for the same last coefficient,
759 * then it is printed as
761 * f >= a x
763 * or
765 * -f <= a x
767 * instead. In fact, the "a x" part is not printed explicitly, but
768 * reused from the next constraint, which is therefore treated as
769 * a first constraint in the conjunction.
771 * If the constant term of "f" is -1, then "f" is replaced by "f + 1" and
772 * the comparison operator is replaced by the strict variant.
773 * Essentially, ">= 1" is replaced by "> 0".
775 static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
776 __isl_keep isl_space *space, __isl_keep isl_mat *div,
777 __isl_take isl_printer *p, int latex)
779 int i;
780 isl_vec *c = NULL;
781 int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
782 isl_size total = isl_basic_map_dim(bmap, isl_dim_all);
783 unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
784 int first = 1;
785 int dump;
787 if (total < 0 || !p)
788 return isl_printer_free(p);
789 bmap = isl_basic_map_copy(bmap);
790 dump = p->dump;
791 if (!dump)
792 bmap = isl_basic_map_sort_constraints(bmap);
793 if (!bmap)
794 goto error;
796 c = isl_vec_alloc(bmap->ctx, 1 + total);
797 if (!c)
798 goto error;
800 for (i = bmap->n_eq - 1; i >= 0; --i) {
801 int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total);
802 if (l < 0) {
803 if (i != bmap->n_eq - 1)
804 p = isl_printer_print_str(p, s_and[latex]);
805 p = isl_printer_print_str(p, "0 = 0");
806 continue;
808 if (!first)
809 p = isl_printer_print_str(p, s_and[latex]);
810 if (isl_int_is_neg(bmap->eq[i][l]))
811 isl_seq_cpy(c->el, bmap->eq[i], 1 + total);
812 else
813 isl_seq_neg(c->el, bmap->eq[i], 1 + total);
814 p = print_eq_constraint(p, space, div, c->el, l, latex);
815 first = 0;
817 for (i = 0; i < bmap->n_ineq; ++i) {
818 isl_bool combine;
819 int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);
820 int strict;
821 int s;
822 const char *op;
823 if (l < 0)
824 continue;
825 if (!dump && l >= o_div &&
826 can_print_div_expr(p, div, l - o_div)) {
827 isl_bool is_div;
828 is_div = isl_basic_map_is_div_constraint(bmap,
829 bmap->ineq[i], l - o_div);
830 if (is_div < 0)
831 goto error;
832 if (is_div)
833 continue;
835 if (!first)
836 p = isl_printer_print_str(p, s_and[latex]);
837 s = isl_int_sgn(bmap->ineq[i][l]);
838 strict = !rational && isl_int_is_negone(bmap->ineq[i][0]);
839 if (s < 0)
840 isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);
841 else
842 isl_seq_neg(c->el, bmap->ineq[i], 1 + total);
843 if (strict)
844 isl_int_set_si(c->el[0], 0);
845 combine = dump ? isl_bool_false : next_is_opposite(bmap, i, l);
846 if (combine < 0)
847 goto error;
848 if (combine) {
849 op = constraint_op(-s, strict, latex);
850 p = print_half_constraint(p, space, div, c->el, l,
851 op, latex);
852 first = 1;
853 } else {
854 op = constraint_op(s, strict, latex);
855 p = print_constraint(p, space, div, c->el, l,
856 op, latex);
857 first = 0;
861 isl_basic_map_free(bmap);
862 isl_vec_free(c);
864 return p;
865 error:
866 isl_basic_map_free(bmap);
867 isl_vec_free(c);
868 isl_printer_free(p);
869 return NULL;
872 static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
873 __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p)
875 int c;
877 if (!p || !div)
878 return isl_printer_free(p);
880 c = p->output_format == ISL_FORMAT_C;
881 p = isl_printer_print_str(p, c ? "floord(" : "floor((");
882 p = print_affine_of_len(dim, div, p,
883 div->row[pos] + 1, div->n_col - 1);
884 p = isl_printer_print_str(p, c ? ", " : ")/");
885 p = isl_printer_print_isl_int(p, div->row[pos][0]);
886 p = isl_printer_print_str(p, ")");
887 return p;
890 /* Print a comma separated list of div names, except those that have
891 * a definition that can be printed.
892 * If "print_defined_divs" is set, then those div names are printed
893 * as well, along with their definitions.
895 static __isl_give isl_printer *print_div_list(__isl_take isl_printer *p,
896 __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex,
897 int print_defined_divs)
899 int i;
900 int first = 1;
901 isl_size n_div;
903 n_div = isl_mat_rows(div);
904 if (!p || !space || n_div < 0)
905 return isl_printer_free(p);
907 for (i = 0; i < n_div; ++i) {
908 if (!print_defined_divs && can_print_div_expr(p, div, i))
909 continue;
910 if (!first)
911 p = isl_printer_print_str(p, ", ");
912 p = print_name(space, p, isl_dim_div, i, latex);
913 first = 0;
914 if (!can_print_div_expr(p, div, i))
915 continue;
916 p = isl_printer_print_str(p, " = ");
917 p = print_div(space, div, i, p);
920 return p;
923 /* Does printing an object with local variables described by "div"
924 * require an "exists" clause?
925 * That is, are there any local variables without an explicit representation?
926 * An exists clause is also needed in "dump" mode because
927 * explicit div representations are not printed inline in that case.
929 static isl_bool need_exists(__isl_keep isl_printer *p, __isl_keep isl_mat *div)
931 int i;
932 isl_size n;
934 n = isl_mat_rows(div);
935 if (!p || n < 0)
936 return isl_bool_error;
937 if (n == 0)
938 return isl_bool_false;
939 if (p->dump)
940 return isl_bool_true;
941 for (i = 0; i < n; ++i)
942 if (!can_print_div_expr(p, div, i))
943 return isl_bool_true;
944 return isl_bool_false;
947 /* Print the start of an exists clause, i.e.,
949 * (exists variables:
951 * In dump mode, local variables with an explicit definition are printed
952 * as well because they will not be printed inline.
954 static __isl_give isl_printer *open_exists(__isl_take isl_printer *p,
955 __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex)
957 int dump;
959 if (!p)
960 return NULL;
962 dump = p->dump;
963 p = isl_printer_print_str(p, s_open_exists[latex]);
964 p = print_div_list(p, space, div, latex, dump);
965 p = isl_printer_print_str(p, ": ");
967 return p;
970 /* Remove the explicit representations of all local variables in "div".
972 static __isl_give isl_mat *mark_all_unknown(__isl_take isl_mat *div)
974 int i;
975 isl_size n_div;
977 n_div = isl_mat_rows(div);
978 if (n_div < 0)
979 return isl_mat_free(div);
981 for (i = 0; i < n_div; ++i)
982 div = isl_mat_set_element_si(div, i, 0, 0);
983 return div;
986 /* Print the constraints of "bmap" to "p".
987 * The names of the variables are taken from "space".
988 * "latex" is set if the constraints should be printed in LaTeX format.
989 * Do not print inline explicit div representations in "dump" mode.
991 static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
992 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
994 int dump;
995 isl_mat *div;
996 isl_bool exists;
998 if (!p)
999 return NULL;
1000 dump = p->dump;
1001 div = isl_basic_map_get_divs(bmap);
1002 exists = need_exists(p, div);
1003 if (exists >= 0 && exists)
1004 p = open_exists(p, space, div, latex);
1006 if (dump)
1007 div = mark_all_unknown(div);
1008 p = print_constraints(bmap, space, div, p, latex);
1009 isl_mat_free(div);
1011 if (exists >= 0 && exists)
1012 p = isl_printer_print_str(p, s_close_exists[latex]);
1013 return p;
1016 /* Print a colon followed by the constraints of "bmap"
1017 * to "p", provided there are any constraints.
1018 * The names of the variables are taken from "space".
1019 * "latex" is set if the constraints should be printed in LaTeX format.
1021 static __isl_give isl_printer *print_optional_disjunct(
1022 __isl_keep isl_basic_map *bmap, __isl_keep isl_space *space,
1023 __isl_take isl_printer *p, int latex)
1025 if (isl_basic_map_plain_is_universe(bmap))
1026 return p;
1028 p = isl_printer_print_str(p, ": ");
1029 p = print_disjunct(bmap, space, p, latex);
1031 return p;
1034 static __isl_give isl_printer *basic_map_print_omega(
1035 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
1037 p = isl_printer_print_str(p, "{ [");
1038 p = print_var_list(p, bmap->dim, isl_dim_in);
1039 p = isl_printer_print_str(p, "] -> [");
1040 p = print_var_list(p, bmap->dim, isl_dim_out);
1041 p = isl_printer_print_str(p, "] ");
1042 p = print_optional_disjunct(bmap, bmap->dim, p, 0);
1043 p = isl_printer_print_str(p, " }");
1044 return p;
1047 static __isl_give isl_printer *basic_set_print_omega(
1048 __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
1050 p = isl_printer_print_str(p, "{ [");
1051 p = print_var_list(p, bset->dim, isl_dim_set);
1052 p = isl_printer_print_str(p, "] ");
1053 p = print_optional_disjunct(bset, bset->dim, p, 0);
1054 p = isl_printer_print_str(p, " }");
1055 return p;
1058 static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map,
1059 __isl_take isl_printer *p)
1061 int i;
1063 for (i = 0; i < map->n; ++i) {
1064 if (i)
1065 p = isl_printer_print_str(p, " union ");
1066 p = basic_map_print_omega(map->p[i], p);
1068 return p;
1071 static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set,
1072 __isl_take isl_printer *p)
1074 int i;
1076 for (i = 0; i < set->n; ++i) {
1077 if (i)
1078 p = isl_printer_print_str(p, " union ");
1079 p = basic_set_print_omega(set->p[i], p);
1081 return p;
1084 /* Print the list of parameters in "space", followed by an arrow, to "p",
1085 * if there are any parameters.
1087 static __isl_give isl_printer *print_param_tuple(__isl_take isl_printer *p,
1088 __isl_keep isl_space *space, struct isl_print_space_data *data)
1090 isl_size nparam;
1092 nparam = isl_space_dim(space, isl_dim_param);
1093 if (!p || nparam < 0)
1094 return isl_printer_free(p);
1095 if (nparam == 0)
1096 return p;
1098 p = print_tuple(space, p, isl_dim_param, data);
1099 p = isl_printer_print_str(p, s_to[data->latex]);
1101 return p;
1104 static __isl_give isl_printer *isl_basic_map_print_isl(
1105 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p,
1106 int latex)
1108 struct isl_print_space_data data = { .latex = latex };
1109 int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
1111 p = print_param_tuple(p, bmap->dim, &data);
1112 p = isl_printer_print_str(p, "{ ");
1113 p = isl_print_space(bmap->dim, p, rational, &data);
1114 p = isl_printer_print_str(p, " : ");
1115 p = print_disjunct(bmap, bmap->dim, p, latex);
1116 p = isl_printer_print_str(p, " }");
1117 return p;
1120 /* Print the disjuncts of a map (or set) "map" to "p".
1121 * The names of the variables are taken from "space".
1122 * "latex" is set if the constraints should be printed in LaTeX format.
1124 static __isl_give isl_printer *print_disjuncts_core(__isl_keep isl_map *map,
1125 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
1127 int i;
1129 if (map->n == 0)
1130 p = isl_printer_print_str(p, "false");
1131 for (i = 0; i < map->n; ++i) {
1132 if (i)
1133 p = isl_printer_print_str(p, s_or[latex]);
1134 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
1135 p = isl_printer_print_str(p, "(");
1136 p = print_disjunct(map->p[i], space, p, latex);
1137 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
1138 p = isl_printer_print_str(p, ")");
1140 return p;
1143 /* Print the disjuncts of a map (or set) "map" to "p".
1144 * The names of the variables are taken from "space".
1145 * "hull" describes constraints shared by all disjuncts of "map".
1146 * "latex" is set if the constraints should be printed in LaTeX format.
1148 * Print the disjuncts as a conjunction of "hull" and
1149 * the result of removing the constraints of "hull" from "map".
1150 * If this result turns out to be the universe, then simply print "hull".
1152 static __isl_give isl_printer *print_disjuncts_in_hull(__isl_keep isl_map *map,
1153 __isl_keep isl_space *space, __isl_take isl_basic_map *hull,
1154 __isl_take isl_printer *p, int latex)
1156 isl_bool is_universe;
1158 p = print_disjunct(hull, space, p, latex);
1159 map = isl_map_plain_gist_basic_map(isl_map_copy(map), hull);
1160 is_universe = isl_map_plain_is_universe(map);
1161 if (is_universe < 0)
1162 goto error;
1163 if (!is_universe) {
1164 p = isl_printer_print_str(p, s_and[latex]);
1165 p = isl_printer_print_str(p, "(");
1166 p = print_disjuncts_core(map, space, p, latex);
1167 p = isl_printer_print_str(p, ")");
1169 isl_map_free(map);
1171 return p;
1172 error:
1173 isl_map_free(map);
1174 isl_printer_free(p);
1175 return NULL;
1178 /* Print the disjuncts of a map (or set) "map" to "p".
1179 * The names of the variables are taken from "space".
1180 * "latex" is set if the constraints should be printed in LaTeX format.
1182 * If there are at least two disjuncts and "dump" mode is not turned out,
1183 * check for any shared constraints among all disjuncts.
1184 * If there are any, then print them separately in print_disjuncts_in_hull.
1186 static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
1187 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
1189 if (isl_map_plain_is_universe(map))
1190 return p;
1192 p = isl_printer_print_str(p, s_such_that[latex]);
1193 if (!p)
1194 return NULL;
1196 if (!p->dump && map->n >= 2) {
1197 isl_basic_map *hull;
1198 isl_bool is_universe;
1200 hull = isl_map_plain_unshifted_simple_hull(isl_map_copy(map));
1201 is_universe = isl_basic_map_plain_is_universe(hull);
1202 if (is_universe < 0)
1203 p = isl_printer_free(p);
1204 else if (!is_universe)
1205 return print_disjuncts_in_hull(map, space, hull,
1206 p, latex);
1207 isl_basic_map_free(hull);
1210 return print_disjuncts_core(map, space, p, latex);
1213 /* Print the disjuncts of a map (or set).
1214 * The names of the variables are taken from "space".
1215 * "latex" is set if the constraints should be printed in LaTeX format.
1217 * If the map turns out to be a universal parameter domain, then
1218 * we need to print the colon. Otherwise, the output looks identical
1219 * to the empty set.
1221 static __isl_give isl_printer *print_disjuncts_map(__isl_keep isl_map *map,
1222 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
1224 if (isl_map_plain_is_universe(map) && isl_space_is_params(map->dim))
1225 return isl_printer_print_str(p, s_such_that[latex]);
1226 else
1227 return print_disjuncts(map, space, p, latex);
1230 /* Print the disjuncts of a set.
1231 * The names of the variables are taken from "space".
1232 * "latex" is set if the constraints should be printed in LaTeX format.
1234 static __isl_give isl_printer *print_disjuncts_set(__isl_keep isl_set *set,
1235 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
1237 return print_disjuncts_map(set_to_map(set), space, p, latex);
1240 struct isl_aff_split {
1241 isl_basic_map *aff;
1242 isl_map *map;
1245 static void free_split(__isl_take struct isl_aff_split *split, int n)
1247 int i;
1249 if (!split)
1250 return;
1252 for (i = 0; i < n; ++i) {
1253 isl_basic_map_free(split[i].aff);
1254 isl_map_free(split[i].map);
1257 free(split);
1260 static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap)
1262 int i, j;
1263 isl_size nparam, n_in, n_out, total;
1265 bmap = isl_basic_map_cow(bmap);
1266 if (!bmap)
1267 return NULL;
1268 bmap = isl_basic_map_free_inequality(bmap, bmap->n_ineq);
1270 nparam = isl_basic_map_dim(bmap, isl_dim_param);
1271 n_in = isl_basic_map_dim(bmap, isl_dim_in);
1272 n_out = isl_basic_map_dim(bmap, isl_dim_out);
1273 total = isl_basic_map_dim(bmap, isl_dim_all);
1274 if (n_in < 0 || n_out < 0 || nparam < 0 || total < 0)
1275 return isl_basic_map_free(bmap);
1277 for (i = bmap->n_eq - 1; i >= 0; --i) {
1278 j = isl_seq_last_non_zero(bmap->eq[i] + 1, total);
1279 if (j >= nparam && j < nparam + n_in + n_out &&
1280 (isl_int_is_one(bmap->eq[i][1 + j]) ||
1281 isl_int_is_negone(bmap->eq[i][1 + j])))
1282 continue;
1283 if (isl_basic_map_drop_equality(bmap, i) < 0)
1284 goto error;
1287 bmap = isl_basic_map_finalize(bmap);
1289 return bmap;
1290 error:
1291 isl_basic_map_free(bmap);
1292 return NULL;
1295 static int aff_split_cmp(const void *p1, const void *p2, void *user)
1297 const struct isl_aff_split *s1, *s2;
1298 s1 = (const struct isl_aff_split *) p1;
1299 s2 = (const struct isl_aff_split *) p2;
1301 return isl_basic_map_plain_cmp(s1->aff, s2->aff);
1304 static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap,
1305 __isl_keep isl_basic_map *aff)
1307 int i, j;
1308 isl_size v_div;
1310 v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
1311 if (v_div < 0 || !aff)
1312 goto error;
1314 for (i = bmap->n_eq - 1; i >= 0; --i) {
1315 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + v_div,
1316 bmap->n_div) != -1)
1317 continue;
1318 for (j = 0; j < aff->n_eq; ++j) {
1319 if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + v_div) &&
1320 !isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + v_div))
1321 continue;
1322 if (isl_basic_map_drop_equality(bmap, i) < 0)
1323 goto error;
1324 break;
1328 return bmap;
1329 error:
1330 isl_basic_map_free(bmap);
1331 return NULL;
1334 static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map)
1336 int i, n;
1337 struct isl_aff_split *split;
1338 isl_ctx *ctx;
1340 ctx = isl_map_get_ctx(map);
1341 split = isl_calloc_array(ctx, struct isl_aff_split, map->n);
1342 if (!split)
1343 return NULL;
1345 for (i = 0; i < map->n; ++i) {
1346 isl_basic_map *bmap;
1347 split[i].aff = get_aff(isl_basic_map_copy(map->p[i]));
1348 bmap = isl_basic_map_copy(map->p[i]);
1349 bmap = isl_basic_map_cow(bmap);
1350 bmap = drop_aff(bmap, split[i].aff);
1351 split[i].map = isl_map_from_basic_map(bmap);
1352 if (!split[i].aff || !split[i].map)
1353 goto error;
1356 if (isl_sort(split, map->n, sizeof(struct isl_aff_split),
1357 &aff_split_cmp, NULL) < 0)
1358 goto error;
1360 n = map->n;
1361 for (i = n - 1; i >= 1; --i) {
1362 if (!isl_basic_map_plain_is_equal(split[i - 1].aff,
1363 split[i].aff))
1364 continue;
1365 isl_basic_map_free(split[i].aff);
1366 split[i - 1].map = isl_map_union(split[i - 1].map,
1367 split[i].map);
1368 if (i != n - 1)
1369 split[i] = split[n - 1];
1370 split[n - 1].aff = NULL;
1371 split[n - 1].map = NULL;
1372 --n;
1375 return split;
1376 error:
1377 free_split(split, map->n);
1378 return NULL;
1381 static int defining_equality(__isl_keep isl_basic_map *eq,
1382 __isl_keep isl_space *dim, enum isl_dim_type type, int pos)
1384 int i;
1385 isl_size total;
1387 total = isl_basic_map_dim(eq, isl_dim_all);
1388 if (total < 0)
1389 return -1;
1391 pos += isl_space_offset(dim, type);
1393 for (i = 0; i < eq->n_eq; ++i) {
1394 if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos)
1395 continue;
1396 if (isl_int_is_one(eq->eq[i][1 + pos]))
1397 isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total);
1398 return i;
1401 return -1;
1404 /* Print dimension "pos" of data->space to "p".
1406 * data->user is assumed to be an isl_basic_map keeping track of equalities.
1408 * If the current dimension is defined by these equalities, then print
1409 * the corresponding expression, assigned to the name of the dimension
1410 * if there is any. Otherwise, print the name of the dimension.
1412 static __isl_give isl_printer *print_dim_eq(__isl_take isl_printer *p,
1413 struct isl_print_space_data *data, unsigned pos)
1415 isl_basic_map *eq = data->user;
1416 int j;
1418 j = defining_equality(eq, data->space, data->type, pos);
1419 if (j >= 0) {
1420 if (isl_space_has_dim_name(data->space, data->type, pos)) {
1421 p = print_name(data->space, p, data->type, pos,
1422 data->latex);
1423 p = isl_printer_print_str(p, " = ");
1425 pos += 1 + isl_space_offset(data->space, data->type);
1426 p = print_affine_of_len(data->space, NULL, p, eq->eq[j], pos);
1427 } else {
1428 p = print_name(data->space, p, data->type, pos, data->latex);
1431 return p;
1434 static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p,
1435 struct isl_aff_split *split, int n, __isl_keep isl_space *space)
1437 struct isl_print_space_data data = { 0 };
1438 int i;
1439 int rational;
1441 data.print_dim = &print_dim_eq;
1442 for (i = 0; i < n; ++i) {
1443 if (!split[i].map)
1444 break;
1445 rational = split[i].map->n > 0 &&
1446 ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL);
1447 if (i)
1448 p = isl_printer_print_str(p, "; ");
1449 data.user = split[i].aff;
1450 p = isl_print_space(space, p, rational, &data);
1451 p = print_disjuncts_map(split[i].map, space, p, 0);
1454 return p;
1457 static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map,
1458 __isl_take isl_printer *p)
1460 struct isl_print_space_data data = { 0 };
1461 struct isl_aff_split *split = NULL;
1462 int rational;
1464 if (!p || !map)
1465 return isl_printer_free(p);
1466 if (!p->dump && map->n > 0)
1467 split = split_aff(map);
1468 if (split) {
1469 p = print_split_map(p, split, map->n, map->dim);
1470 } else {
1471 rational = map->n > 0 &&
1472 ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL);
1473 p = isl_print_space(map->dim, p, rational, &data);
1474 p = print_disjuncts_map(map, map->dim, p, 0);
1476 free_split(split, map->n);
1477 return p;
1480 static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,
1481 __isl_take isl_printer *p)
1483 struct isl_print_space_data data = { 0 };
1485 p = print_param_tuple(p, map->dim, &data);
1486 p = isl_printer_print_str(p, s_open_set[0]);
1487 p = isl_map_print_isl_body(map, p);
1488 p = isl_printer_print_str(p, s_close_set[0]);
1489 return p;
1492 static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map,
1493 __isl_take isl_printer *p, __isl_keep isl_basic_map *aff)
1495 struct isl_print_space_data data = { 0 };
1497 data.latex = 1;
1498 p = print_param_tuple(p, map->dim, &data);
1499 p = isl_printer_print_str(p, s_open_set[1]);
1500 data.print_dim = &print_dim_eq;
1501 data.user = aff;
1502 p = isl_print_space(map->dim, p, 0, &data);
1503 p = print_disjuncts_map(map, map->dim, p, 1);
1504 p = isl_printer_print_str(p, s_close_set[1]);
1506 return p;
1509 static __isl_give isl_printer *isl_map_print_latex(__isl_keep isl_map *map,
1510 __isl_take isl_printer *p)
1512 int i;
1513 struct isl_aff_split *split = NULL;
1515 if (map->n > 0)
1516 split = split_aff(map);
1518 if (!split)
1519 return print_latex_map(map, p, NULL);
1521 for (i = 0; i < map->n; ++i) {
1522 if (!split[i].map)
1523 break;
1524 if (i)
1525 p = isl_printer_print_str(p, " \\cup ");
1526 p = print_latex_map(split[i].map, p, split[i].aff);
1529 free_split(split, map->n);
1530 return p;
1533 __isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p,
1534 __isl_keep isl_basic_map *bmap)
1536 if (!p || !bmap)
1537 goto error;
1538 if (p->output_format == ISL_FORMAT_ISL)
1539 return isl_basic_map_print_isl(bmap, p, 0);
1540 else if (p->output_format == ISL_FORMAT_OMEGA)
1541 return basic_map_print_omega(bmap, p);
1542 isl_assert(bmap->ctx, 0, goto error);
1543 error:
1544 isl_printer_free(p);
1545 return NULL;
1548 __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,
1549 __isl_keep isl_basic_set *bset)
1551 if (!p || !bset)
1552 goto error;
1554 if (p->output_format == ISL_FORMAT_ISL)
1555 return isl_basic_map_print_isl(bset, p, 0);
1556 else if (p->output_format == ISL_FORMAT_POLYLIB)
1557 return isl_basic_set_print_polylib(bset, p, 0);
1558 else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1559 return isl_basic_set_print_polylib(bset, p, 1);
1560 else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)
1561 return bset_print_constraints_polylib(bset, p);
1562 else if (p->output_format == ISL_FORMAT_OMEGA)
1563 return basic_set_print_omega(bset, p);
1564 isl_assert(p->ctx, 0, goto error);
1565 error:
1566 isl_printer_free(p);
1567 return NULL;
1570 __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,
1571 __isl_keep isl_set *set)
1573 if (!p || !set)
1574 goto error;
1575 if (p->output_format == ISL_FORMAT_ISL)
1576 return isl_map_print_isl(set_to_map(set), p);
1577 else if (p->output_format == ISL_FORMAT_POLYLIB)
1578 return isl_set_print_polylib(set, p, 0);
1579 else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1580 return isl_set_print_polylib(set, p, 1);
1581 else if (p->output_format == ISL_FORMAT_OMEGA)
1582 return isl_set_print_omega(set, p);
1583 else if (p->output_format == ISL_FORMAT_LATEX)
1584 return isl_map_print_latex(set_to_map(set), p);
1585 isl_assert(set->ctx, 0, goto error);
1586 error:
1587 isl_printer_free(p);
1588 return NULL;
1591 __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
1592 __isl_keep isl_map *map)
1594 if (!p || !map)
1595 goto error;
1597 if (p->output_format == ISL_FORMAT_ISL)
1598 return isl_map_print_isl(map, p);
1599 else if (p->output_format == ISL_FORMAT_POLYLIB)
1600 return isl_map_print_polylib(map, p, 0);
1601 else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1602 return isl_map_print_polylib(map, p, 1);
1603 else if (p->output_format == ISL_FORMAT_OMEGA)
1604 return isl_map_print_omega(map, p);
1605 else if (p->output_format == ISL_FORMAT_LATEX)
1606 return isl_map_print_latex(map, p);
1607 isl_assert(map->ctx, 0, goto error);
1608 error:
1609 isl_printer_free(p);
1610 return NULL;
1613 struct isl_union_print_data {
1614 isl_printer *p;
1615 int first;
1618 static isl_stat print_map_body(__isl_take isl_map *map, void *user)
1620 struct isl_union_print_data *data;
1621 data = (struct isl_union_print_data *)user;
1623 if (!data->first)
1624 data->p = isl_printer_print_str(data->p, "; ");
1625 data->first = 0;
1627 data->p = isl_map_print_isl_body(map, data->p);
1628 isl_map_free(map);
1630 return isl_stat_ok;
1633 /* Print the body of "umap" (everything except the parameter declarations)
1634 * to "p" in isl format.
1636 static __isl_give isl_printer *isl_printer_print_union_map_isl_body(
1637 __isl_take isl_printer *p, __isl_keep isl_union_map *umap)
1639 struct isl_union_print_data data;
1641 p = isl_printer_print_str(p, s_open_set[0]);
1642 data.p = p;
1643 data.first = 1;
1644 isl_union_map_foreach_map(umap, &print_map_body, &data);
1645 p = data.p;
1646 p = isl_printer_print_str(p, s_close_set[0]);
1647 return p;
1650 /* Print the body of "uset" (everything except the parameter declarations)
1651 * to "p" in isl format.
1653 static __isl_give isl_printer *isl_printer_print_union_set_isl_body(
1654 __isl_take isl_printer *p, __isl_keep isl_union_set *uset)
1656 return isl_printer_print_union_map_isl_body(p, uset_to_umap(uset));
1659 /* Print the isl_union_map "umap" to "p" in isl format.
1661 static __isl_give isl_printer *isl_union_map_print_isl(
1662 __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
1664 struct isl_print_space_data space_data = { 0 };
1665 isl_space *space;
1667 space = isl_union_map_get_space(umap);
1668 p = print_param_tuple(p, space, &space_data);
1669 isl_space_free(space);
1671 p = isl_printer_print_union_map_isl_body(p, umap);
1673 return p;
1676 static isl_stat print_latex_map_body(__isl_take isl_map *map, void *user)
1678 struct isl_union_print_data *data;
1679 data = (struct isl_union_print_data *)user;
1681 if (!data->first)
1682 data->p = isl_printer_print_str(data->p, " \\cup ");
1683 data->first = 0;
1685 data->p = isl_map_print_latex(map, data->p);
1686 isl_map_free(map);
1688 return isl_stat_ok;
1691 static __isl_give isl_printer *isl_union_map_print_latex(
1692 __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
1694 struct isl_union_print_data data = { p, 1 };
1695 isl_union_map_foreach_map(umap, &print_latex_map_body, &data);
1696 p = data.p;
1697 return p;
1700 __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p,
1701 __isl_keep isl_union_map *umap)
1703 if (!p || !umap)
1704 goto error;
1706 if (p->output_format == ISL_FORMAT_ISL)
1707 return isl_union_map_print_isl(umap, p);
1708 if (p->output_format == ISL_FORMAT_LATEX)
1709 return isl_union_map_print_latex(umap, p);
1711 isl_die(p->ctx, isl_error_invalid,
1712 "invalid output format for isl_union_map", goto error);
1713 error:
1714 isl_printer_free(p);
1715 return NULL;
1718 __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
1719 __isl_keep isl_union_set *uset)
1721 if (!p || !uset)
1722 goto error;
1724 if (p->output_format == ISL_FORMAT_ISL)
1725 return isl_union_map_print_isl(uset_to_umap(uset), p);
1726 if (p->output_format == ISL_FORMAT_LATEX)
1727 return isl_union_map_print_latex(uset_to_umap(uset), p);
1729 isl_die(p->ctx, isl_error_invalid,
1730 "invalid output format for isl_union_set", goto error);
1731 error:
1732 isl_printer_free(p);
1733 return NULL;
1736 static isl_size poly_rec_n_non_zero(__isl_keep isl_poly_rec *rec)
1738 int i;
1739 int n;
1741 if (!rec)
1742 return isl_size_error;
1744 for (i = 0, n = 0; i < rec->n; ++i) {
1745 isl_bool is_zero = isl_poly_is_zero(rec->p[i]);
1747 if (is_zero < 0)
1748 return isl_size_error;
1749 if (!is_zero)
1750 ++n;
1753 return n;
1756 static __isl_give isl_printer *poly_print_cst(__isl_keep isl_poly *poly,
1757 __isl_take isl_printer *p, int first)
1759 isl_poly_cst *cst;
1760 int neg;
1762 cst = isl_poly_as_cst(poly);
1763 if (!cst)
1764 goto error;
1765 neg = !first && isl_int_is_neg(cst->n);
1766 if (!first)
1767 p = isl_printer_print_str(p, neg ? " - " : " + ");
1768 if (neg)
1769 isl_int_neg(cst->n, cst->n);
1770 if (isl_int_is_zero(cst->d)) {
1771 int sgn = isl_int_sgn(cst->n);
1772 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
1773 sgn == 0 ? "NaN" : "infty");
1774 } else
1775 p = isl_printer_print_isl_int(p, cst->n);
1776 if (neg)
1777 isl_int_neg(cst->n, cst->n);
1778 if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) {
1779 p = isl_printer_print_str(p, "/");
1780 p = isl_printer_print_isl_int(p, cst->d);
1782 return p;
1783 error:
1784 isl_printer_free(p);
1785 return NULL;
1788 static __isl_give isl_printer *print_base(__isl_take isl_printer *p,
1789 __isl_keep isl_space *space, __isl_keep isl_mat *div, int var)
1791 isl_size total;
1793 total = isl_space_dim(space, isl_dim_all);
1794 if (total < 0)
1795 return isl_printer_free(p);
1796 if (var < total)
1797 p = print_term(space, NULL, space->ctx->one, 1 + var, p, 0);
1798 else
1799 p = print_div(space, div, var - total, p);
1800 return p;
1803 static __isl_give isl_printer *print_pow(__isl_take isl_printer *p,
1804 __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var, int exp)
1806 p = print_base(p, dim, div, var);
1807 if (exp == 1)
1808 return p;
1809 if (p->output_format == ISL_FORMAT_C) {
1810 int i;
1811 for (i = 1; i < exp; ++i) {
1812 p = isl_printer_print_str(p, "*");
1813 p = print_base(p, dim, div, var);
1815 } else {
1816 p = isl_printer_print_str(p, "^");
1817 p = isl_printer_print_int(p, exp);
1819 return p;
1822 /* Print the polynomial "poly" defined over the domain space "space" and
1823 * local variables defined by "div" to "p".
1825 static __isl_give isl_printer *poly_print(__isl_keep isl_poly *poly,
1826 __isl_keep isl_space *space, __isl_keep isl_mat *div,
1827 __isl_take isl_printer *p)
1829 int i, first, print_parens;
1830 isl_size n;
1831 isl_bool is_cst;
1832 isl_poly_rec *rec;
1834 is_cst = isl_poly_is_cst(poly);
1835 if (!p || is_cst < 0 || !space || !div)
1836 goto error;
1838 if (is_cst)
1839 return poly_print_cst(poly, p, 1);
1841 rec = isl_poly_as_rec(poly);
1842 n = poly_rec_n_non_zero(rec);
1843 if (n < 0)
1844 return isl_printer_free(p);
1845 print_parens = n > 1;
1846 if (print_parens)
1847 p = isl_printer_print_str(p, "(");
1848 for (i = 0, first = 1; i < rec->n; ++i) {
1849 isl_bool is_zero = isl_poly_is_zero(rec->p[i]);
1850 isl_bool is_one = isl_poly_is_one(rec->p[i]);
1851 isl_bool is_negone = isl_poly_is_negone(rec->p[i]);
1852 isl_bool is_cst = isl_poly_is_cst(rec->p[i]);
1854 if (is_zero < 0 || is_one < 0 || is_negone < 0)
1855 return isl_printer_free(p);
1856 if (is_zero)
1857 continue;
1858 if (is_negone) {
1859 if (!i)
1860 p = isl_printer_print_str(p, "-1");
1861 else if (first)
1862 p = isl_printer_print_str(p, "-");
1863 else
1864 p = isl_printer_print_str(p, " - ");
1865 } else if (is_cst && !is_one)
1866 p = poly_print_cst(rec->p[i], p, first);
1867 else {
1868 if (!first)
1869 p = isl_printer_print_str(p, " + ");
1870 if (i == 0 || !is_one)
1871 p = poly_print(rec->p[i], space, div, p);
1873 first = 0;
1874 if (i == 0)
1875 continue;
1876 if (!is_one && !is_negone)
1877 p = isl_printer_print_str(p, " * ");
1878 p = print_pow(p, space, div, rec->poly.var, i);
1880 if (print_parens)
1881 p = isl_printer_print_str(p, ")");
1882 return p;
1883 error:
1884 isl_printer_free(p);
1885 return NULL;
1888 static __isl_give isl_printer *print_qpolynomial(__isl_take isl_printer *p,
1889 __isl_keep isl_qpolynomial *qp)
1891 if (!p || !qp)
1892 goto error;
1893 p = poly_print(qp->poly, qp->dim, qp->div, p);
1894 return p;
1895 error:
1896 isl_printer_free(p);
1897 return NULL;
1900 static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p,
1901 __isl_keep isl_qpolynomial *qp)
1903 struct isl_print_space_data data = { 0 };
1905 if (!p || !qp)
1906 goto error;
1908 p = print_param_tuple(p, qp->dim, &data);
1909 p = isl_printer_print_str(p, "{ ");
1910 if (!isl_space_is_params(qp->dim)) {
1911 p = isl_print_space(qp->dim, p, 0, &data);
1912 p = isl_printer_print_str(p, " -> ");
1914 p = print_qpolynomial(p, qp);
1915 p = isl_printer_print_str(p, " }");
1916 return p;
1917 error:
1918 isl_printer_free(p);
1919 return NULL;
1922 /* Print the quasi-polynomial "qp" to "p" in C format, with the variable names
1923 * taken from the domain space "space".
1925 static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p,
1926 __isl_keep isl_space *space, __isl_keep isl_qpolynomial *qp)
1928 isl_bool is_one;
1929 isl_val *den;
1931 den = isl_qpolynomial_get_den(qp);
1932 qp = isl_qpolynomial_copy(qp);
1933 qp = isl_qpolynomial_scale_val(qp, isl_val_copy(den));
1934 is_one = isl_val_is_one(den);
1935 if (is_one < 0)
1936 p = isl_printer_free(p);
1937 if (!is_one)
1938 p = isl_printer_print_str(p, "(");
1939 if (qp)
1940 p = poly_print(qp->poly, space, qp->div, p);
1941 else
1942 p = isl_printer_free(p);
1943 if (!is_one) {
1944 p = isl_printer_print_str(p, ")/");
1945 p = isl_printer_print_val(p, den);
1947 isl_qpolynomial_free(qp);
1948 isl_val_free(den);
1949 return p;
1952 __isl_give isl_printer *isl_printer_print_qpolynomial(
1953 __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp)
1955 if (!p || !qp)
1956 goto error;
1958 if (p->output_format == ISL_FORMAT_ISL)
1959 return print_qpolynomial_isl(p, qp);
1960 else if (p->output_format == ISL_FORMAT_C)
1961 return print_qpolynomial_c(p, qp->dim, qp);
1962 else
1963 isl_die(qp->dim->ctx, isl_error_unsupported,
1964 "output format not supported for isl_qpolynomials",
1965 goto error);
1966 error:
1967 isl_printer_free(p);
1968 return NULL;
1971 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
1972 unsigned output_format)
1974 isl_printer *p;
1976 if (!qp)
1977 return;
1979 isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1980 p = isl_printer_to_file(qp->dim->ctx, out);
1981 p = isl_printer_print_qpolynomial(p, qp);
1982 isl_printer_free(p);
1985 static __isl_give isl_printer *qpolynomial_fold_print(
1986 __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
1988 int i;
1990 if (fold->type == isl_fold_min)
1991 p = isl_printer_print_str(p, "min");
1992 else if (fold->type == isl_fold_max)
1993 p = isl_printer_print_str(p, "max");
1994 p = isl_printer_print_str(p, "(");
1995 for (i = 0; i < fold->n; ++i) {
1996 if (i)
1997 p = isl_printer_print_str(p, ", ");
1998 p = print_qpolynomial(p, fold->qp[i]);
2000 p = isl_printer_print_str(p, ")");
2001 return p;
2004 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
2005 FILE *out, unsigned output_format)
2007 isl_printer *p;
2009 if (!fold)
2010 return;
2012 isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);
2014 p = isl_printer_to_file(fold->dim->ctx, out);
2015 p = isl_printer_print_qpolynomial_fold(p, fold);
2017 isl_printer_free(p);
2020 static __isl_give isl_printer *isl_pwqp_print_isl_body(
2021 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
2023 struct isl_print_space_data data = { 0 };
2024 int i = 0;
2026 for (i = 0; i < pwqp->n; ++i) {
2027 isl_space *space;
2029 if (i)
2030 p = isl_printer_print_str(p, "; ");
2031 space = isl_qpolynomial_get_domain_space(pwqp->p[i].qp);
2032 if (!isl_space_is_params(space)) {
2033 p = isl_print_space(space, p, 0, &data);
2034 p = isl_printer_print_str(p, " -> ");
2036 p = print_qpolynomial(p, pwqp->p[i].qp);
2037 p = print_disjuncts(set_to_map(pwqp->p[i].set), space, p, 0);
2038 isl_space_free(space);
2041 return p;
2044 static __isl_give isl_printer *print_pw_qpolynomial_isl(
2045 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
2047 struct isl_print_space_data data = { 0 };
2049 if (!p || !pwqp)
2050 goto error;
2052 p = print_param_tuple(p, pwqp->dim, &data);
2053 p = isl_printer_print_str(p, "{ ");
2054 if (pwqp->n == 0) {
2055 if (!isl_space_is_set(pwqp->dim)) {
2056 p = print_tuple(pwqp->dim, p, isl_dim_in, &data);
2057 p = isl_printer_print_str(p, " -> ");
2059 p = isl_printer_print_str(p, "0");
2061 p = isl_pwqp_print_isl_body(p, pwqp);
2062 p = isl_printer_print_str(p, " }");
2063 return p;
2064 error:
2065 isl_printer_free(p);
2066 return NULL;
2069 void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
2070 unsigned output_format)
2072 isl_printer *p;
2074 if (!pwqp)
2075 return;
2077 p = isl_printer_to_file(pwqp->dim->ctx, out);
2078 p = isl_printer_set_output_format(p, output_format);
2079 p = isl_printer_print_pw_qpolynomial(p, pwqp);
2081 isl_printer_free(p);
2084 static __isl_give isl_printer *isl_pwf_print_isl_body(
2085 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
2087 struct isl_print_space_data data = { 0 };
2088 int i = 0;
2090 for (i = 0; i < pwf->n; ++i) {
2091 isl_space *space;
2093 if (i)
2094 p = isl_printer_print_str(p, "; ");
2095 space = isl_qpolynomial_fold_get_domain_space(pwf->p[i].fold);
2096 if (!isl_space_is_params(space)) {
2097 p = isl_print_space(space, p, 0, &data);
2098 p = isl_printer_print_str(p, " -> ");
2100 p = qpolynomial_fold_print(pwf->p[i].fold, p);
2101 p = print_disjuncts(set_to_map(pwf->p[i].set), space, p, 0);
2102 isl_space_free(space);
2105 return p;
2108 static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(
2109 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
2111 struct isl_print_space_data data = { 0 };
2113 p = print_param_tuple(p, pwf->dim, &data);
2114 p = isl_printer_print_str(p, "{ ");
2115 if (pwf->n == 0) {
2116 if (!isl_space_is_set(pwf->dim)) {
2117 p = print_tuple(pwf->dim, p, isl_dim_in, &data);
2118 p = isl_printer_print_str(p, " -> ");
2120 p = isl_printer_print_str(p, "0");
2122 p = isl_pwf_print_isl_body(p, pwf);
2123 p = isl_printer_print_str(p, " }");
2124 return p;
2127 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2128 __isl_keep isl_local_space *ls, isl_int *c);
2130 /* We skip the constraint if it is implied by the div expression.
2132 * *first indicates whether this is the first constraint in the conjunction and
2133 * is updated if the constraint is actually printed.
2135 static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,
2136 __isl_keep isl_local_space *ls, isl_int *c, const char *op, int *first)
2138 unsigned o_div;
2139 isl_size n_div;
2140 int div;
2142 o_div = isl_local_space_offset(ls, isl_dim_div);
2143 n_div = isl_local_space_dim(ls, isl_dim_div);
2144 if (n_div < 0)
2145 return isl_printer_free(p);
2146 div = isl_seq_last_non_zero(c + o_div, n_div);
2147 if (div >= 0) {
2148 isl_bool is_div = isl_local_space_is_div_constraint(ls, c, div);
2149 if (is_div < 0)
2150 return isl_printer_free(p);
2151 if (is_div)
2152 return p;
2155 if (!*first)
2156 p = isl_printer_print_str(p, " && ");
2158 p = print_ls_affine_c(p, ls, c);
2159 p = isl_printer_print_str(p, " ");
2160 p = isl_printer_print_str(p, op);
2161 p = isl_printer_print_str(p, " 0");
2163 *first = 0;
2165 return p;
2168 static __isl_give isl_printer *print_ls_partial_affine_c(
2169 __isl_take isl_printer *p, __isl_keep isl_local_space *ls,
2170 isl_int *c, unsigned len);
2172 static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,
2173 __isl_keep isl_space *space, __isl_keep isl_basic_set *bset)
2175 int i, j;
2176 int first = 1;
2177 isl_size n_div = isl_basic_set_dim(bset, isl_dim_div);
2178 isl_size total = isl_basic_set_dim(bset, isl_dim_all);
2179 isl_mat *div;
2180 isl_local_space *ls;
2182 if (n_div < 0 || total < 0)
2183 return isl_printer_free(p);
2185 total -= n_div;
2186 div = isl_basic_set_get_divs(bset);
2187 ls = isl_local_space_alloc_div(isl_space_copy(space), div);
2188 for (i = 0; i < bset->n_eq; ++i) {
2189 j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div);
2190 if (j < 0)
2191 p = print_constraint_c(p, ls,
2192 bset->eq[i], "==", &first);
2193 else {
2194 if (i)
2195 p = isl_printer_print_str(p, " && ");
2196 p = isl_printer_print_str(p, "(");
2197 p = print_ls_partial_affine_c(p, ls, bset->eq[i],
2198 1 + total + j);
2199 p = isl_printer_print_str(p, ") % ");
2200 p = isl_printer_print_isl_int(p,
2201 bset->eq[i][1 + total + j]);
2202 p = isl_printer_print_str(p, " == 0");
2203 first = 0;
2206 for (i = 0; i < bset->n_ineq; ++i)
2207 p = print_constraint_c(p, ls, bset->ineq[i], ">=", &first);
2208 isl_local_space_free(ls);
2209 return p;
2212 static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,
2213 __isl_keep isl_space *space, __isl_keep isl_set *set)
2215 int i;
2217 if (!set)
2218 return isl_printer_free(p);
2220 if (set->n == 0)
2221 p = isl_printer_print_str(p, "0");
2223 for (i = 0; i < set->n; ++i) {
2224 if (i)
2225 p = isl_printer_print_str(p, " || ");
2226 if (set->n > 1)
2227 p = isl_printer_print_str(p, "(");
2228 p = print_basic_set_c(p, space, set->p[i]);
2229 if (set->n > 1)
2230 p = isl_printer_print_str(p, ")");
2232 return p;
2235 /* Print the piecewise quasi-polynomial "pwqp" to "p" in C format.
2237 static __isl_give isl_printer *print_pw_qpolynomial_c(
2238 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
2240 int i;
2241 isl_space *space;
2243 space = isl_pw_qpolynomial_get_domain_space(pwqp);
2244 if (pwqp->n == 1 && isl_set_plain_is_universe(pwqp->p[0].set)) {
2245 p = print_qpolynomial_c(p, space, pwqp->p[0].qp);
2246 isl_space_free(space);
2247 return p;
2250 for (i = 0; i < pwqp->n; ++i) {
2251 p = isl_printer_print_str(p, "(");
2252 p = print_set_c(p, space, pwqp->p[i].set);
2253 p = isl_printer_print_str(p, ") ? (");
2254 p = print_qpolynomial_c(p, space, pwqp->p[i].qp);
2255 p = isl_printer_print_str(p, ") : ");
2258 isl_space_free(space);
2259 p = isl_printer_print_str(p, "0");
2260 return p;
2263 __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
2264 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
2266 if (!p || !pwqp)
2267 goto error;
2269 if (p->output_format == ISL_FORMAT_ISL)
2270 return print_pw_qpolynomial_isl(p, pwqp);
2271 else if (p->output_format == ISL_FORMAT_C)
2272 return print_pw_qpolynomial_c(p, pwqp);
2273 isl_assert(p->ctx, 0, goto error);
2274 error:
2275 isl_printer_free(p);
2276 return NULL;
2279 static isl_stat print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user)
2281 struct isl_union_print_data *data;
2282 data = (struct isl_union_print_data *)user;
2284 if (!data->first)
2285 data->p = isl_printer_print_str(data->p, "; ");
2286 data->first = 0;
2288 data->p = isl_pwqp_print_isl_body(data->p, pwqp);
2289 isl_pw_qpolynomial_free(pwqp);
2291 return isl_stat_ok;
2294 static __isl_give isl_printer *print_union_pw_qpolynomial_isl(
2295 __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
2297 struct isl_union_print_data data;
2298 struct isl_print_space_data space_data = { 0 };
2299 isl_space *space;
2301 space = isl_union_pw_qpolynomial_get_space(upwqp);
2302 p = print_param_tuple(p, space, &space_data);
2303 isl_space_free(space);
2304 p = isl_printer_print_str(p, "{ ");
2305 data.p = p;
2306 data.first = 1;
2307 isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body,
2308 &data);
2309 p = data.p;
2310 p = isl_printer_print_str(p, " }");
2311 return p;
2314 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial(
2315 __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
2317 if (!p || !upwqp)
2318 goto error;
2320 if (p->output_format == ISL_FORMAT_ISL)
2321 return print_union_pw_qpolynomial_isl(p, upwqp);
2322 isl_die(p->ctx, isl_error_invalid,
2323 "invalid output format for isl_union_pw_qpolynomial",
2324 goto error);
2325 error:
2326 isl_printer_free(p);
2327 return NULL;
2330 /* Print the quasi-polynomial reduction "fold" to "p" in C format,
2331 * with the variable names taken from the domain space "space".
2333 static __isl_give isl_printer *print_qpolynomial_fold_c(
2334 __isl_take isl_printer *p, __isl_keep isl_space *space,
2335 __isl_keep isl_qpolynomial_fold *fold)
2337 int i;
2339 for (i = 0; i < fold->n - 1; ++i)
2340 if (fold->type == isl_fold_min)
2341 p = isl_printer_print_str(p, "min(");
2342 else if (fold->type == isl_fold_max)
2343 p = isl_printer_print_str(p, "max(");
2345 for (i = 0; i < fold->n; ++i) {
2346 if (i)
2347 p = isl_printer_print_str(p, ", ");
2348 p = print_qpolynomial_c(p, space, fold->qp[i]);
2349 if (i)
2350 p = isl_printer_print_str(p, ")");
2352 return p;
2355 __isl_give isl_printer *isl_printer_print_qpolynomial_fold(
2356 __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
2358 if (!p || !fold)
2359 goto error;
2360 if (p->output_format == ISL_FORMAT_ISL)
2361 return qpolynomial_fold_print(fold, p);
2362 else if (p->output_format == ISL_FORMAT_C)
2363 return print_qpolynomial_fold_c(p, fold->dim, fold);
2364 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2365 goto error);
2366 error:
2367 isl_printer_free(p);
2368 return NULL;
2371 /* Print the piecewise quasi-polynomial reduction "pwf" to "p" in C format.
2373 static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
2374 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
2376 int i;
2377 isl_space *space;
2379 space = isl_pw_qpolynomial_fold_get_domain_space(pwf);
2380 if (pwf->n == 1 && isl_set_plain_is_universe(pwf->p[0].set)) {
2381 p = print_qpolynomial_fold_c(p, space, pwf->p[0].fold);
2382 isl_space_free(space);
2383 return p;
2386 for (i = 0; i < pwf->n; ++i) {
2387 p = isl_printer_print_str(p, "(");
2388 p = print_set_c(p, space, pwf->p[i].set);
2389 p = isl_printer_print_str(p, ") ? (");
2390 p = print_qpolynomial_fold_c(p, space, pwf->p[i].fold);
2391 p = isl_printer_print_str(p, ") : ");
2394 isl_space_free(space);
2395 p = isl_printer_print_str(p, "0");
2396 return p;
2399 __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
2400 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
2402 if (!p || !pwf)
2403 goto error;
2405 if (p->output_format == ISL_FORMAT_ISL)
2406 return print_pw_qpolynomial_fold_isl(p, pwf);
2407 else if (p->output_format == ISL_FORMAT_C)
2408 return print_pw_qpolynomial_fold_c(p, pwf);
2409 isl_assert(p->ctx, 0, goto error);
2410 error:
2411 isl_printer_free(p);
2412 return NULL;
2415 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
2416 FILE *out, unsigned output_format)
2418 isl_printer *p;
2420 if (!pwf)
2421 return;
2423 p = isl_printer_to_file(pwf->dim->ctx, out);
2424 p = isl_printer_set_output_format(p, output_format);
2425 p = isl_printer_print_pw_qpolynomial_fold(p, pwf);
2427 isl_printer_free(p);
2430 static isl_stat print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf,
2431 void *user)
2433 struct isl_union_print_data *data;
2434 data = (struct isl_union_print_data *)user;
2436 if (!data->first)
2437 data->p = isl_printer_print_str(data->p, "; ");
2438 data->first = 0;
2440 data->p = isl_pwf_print_isl_body(data->p, pwf);
2441 isl_pw_qpolynomial_fold_free(pwf);
2443 return isl_stat_ok;
2446 static __isl_give isl_printer *print_union_pw_qpolynomial_fold_isl(
2447 __isl_take isl_printer *p,
2448 __isl_keep isl_union_pw_qpolynomial_fold *upwf)
2450 struct isl_union_print_data data;
2451 struct isl_print_space_data space_data = { 0 };
2452 isl_space *space;
2454 space = isl_union_pw_qpolynomial_fold_get_space(upwf);
2455 p = print_param_tuple(p, space, &space_data);
2456 isl_space_free(space);
2457 p = isl_printer_print_str(p, "{ ");
2458 data.p = p;
2459 data.first = 1;
2460 isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf,
2461 &print_pwf_body, &data);
2462 p = data.p;
2463 p = isl_printer_print_str(p, " }");
2464 return p;
2467 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold(
2468 __isl_take isl_printer *p,
2469 __isl_keep isl_union_pw_qpolynomial_fold *upwf)
2471 if (!p || !upwf)
2472 goto error;
2474 if (p->output_format == ISL_FORMAT_ISL)
2475 return print_union_pw_qpolynomial_fold_isl(p, upwf);
2476 isl_die(p->ctx, isl_error_invalid,
2477 "invalid output format for isl_union_pw_qpolynomial_fold",
2478 goto error);
2479 error:
2480 isl_printer_free(p);
2481 return NULL;
2484 /* Print the isl_constraint "c" to "p".
2486 __isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p,
2487 __isl_keep isl_constraint *c)
2489 struct isl_print_space_data data = { 0 };
2490 isl_local_space *ls;
2491 isl_space *space;
2492 isl_bool exists;
2494 if (!p || !c)
2495 goto error;
2497 ls = isl_constraint_get_local_space(c);
2498 if (!ls)
2499 return isl_printer_free(p);
2500 space = isl_local_space_get_space(ls);
2501 p = print_param_tuple(p, space, &data);
2502 p = isl_printer_print_str(p, "{ ");
2503 p = isl_print_space(space, p, 0, &data);
2504 p = isl_printer_print_str(p, " : ");
2505 exists = need_exists(p, ls->div);
2506 if (exists < 0)
2507 p = isl_printer_free(p);
2508 if (exists >= 0 && exists)
2509 p = open_exists(p, space, ls->div, 0);
2510 p = print_affine_of_len(space, ls->div, p, c->v->el, c->v->size);
2511 if (isl_constraint_is_equality(c))
2512 p = isl_printer_print_str(p, " = 0");
2513 else
2514 p = isl_printer_print_str(p, " >= 0");
2515 if (exists >= 0 && exists)
2516 p = isl_printer_print_str(p, s_close_exists[0]);
2517 p = isl_printer_print_str(p, " }");
2518 isl_space_free(space);
2519 isl_local_space_free(ls);
2521 return p;
2522 error:
2523 isl_printer_free(p);
2524 return NULL;
2527 static __isl_give isl_printer *isl_printer_print_space_isl(
2528 __isl_take isl_printer *p, __isl_keep isl_space *space)
2530 struct isl_print_space_data data = { 0 };
2532 if (!space)
2533 goto error;
2535 p = print_param_tuple(p, space, &data);
2537 p = isl_printer_print_str(p, "{ ");
2538 if (isl_space_is_params(space))
2539 p = isl_printer_print_str(p, s_such_that[0]);
2540 else
2541 p = isl_print_space(space, p, 0, &data);
2542 p = isl_printer_print_str(p, " }");
2544 return p;
2545 error:
2546 isl_printer_free(p);
2547 return NULL;
2550 __isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p,
2551 __isl_keep isl_space *space)
2553 if (!p || !space)
2554 return isl_printer_free(p);
2555 if (p->output_format == ISL_FORMAT_ISL)
2556 return isl_printer_print_space_isl(p, space);
2557 else if (p->output_format == ISL_FORMAT_OMEGA)
2558 return print_omega_parameters(space, p);
2560 isl_die(isl_space_get_ctx(space), isl_error_unsupported,
2561 "output format not supported for space",
2562 return isl_printer_free(p));
2565 __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p,
2566 __isl_keep isl_local_space *ls)
2568 struct isl_print_space_data data = { 0 };
2569 isl_size n_div;
2571 n_div = isl_local_space_dim(ls, isl_dim_div);
2572 if (n_div < 0)
2573 goto error;
2575 p = print_param_tuple(p, ls->dim, &data);
2576 p = isl_printer_print_str(p, "{ ");
2577 p = isl_print_space(ls->dim, p, 0, &data);
2578 if (n_div > 0) {
2579 p = isl_printer_print_str(p, " : ");
2580 p = isl_printer_print_str(p, s_open_exists[0]);
2581 p = print_div_list(p, ls->dim, ls->div, 0, 1);
2582 p = isl_printer_print_str(p, s_close_exists[0]);
2583 } else if (isl_space_is_params(ls->dim))
2584 p = isl_printer_print_str(p, s_such_that[0]);
2585 p = isl_printer_print_str(p, " }");
2586 return p;
2587 error:
2588 isl_printer_free(p);
2589 return NULL;
2592 /* Print the (potentially rational) affine expression "aff" to "p",
2593 * with the variable names taken from "space".
2595 static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p,
2596 __isl_keep isl_space *space, __isl_keep isl_aff *aff)
2598 isl_size total;
2600 if (isl_aff_is_nan(aff))
2601 return isl_printer_print_str(p, "NaN");
2603 total = isl_local_space_dim(aff->ls, isl_dim_all);
2604 if (total < 0)
2605 return isl_printer_free(p);
2606 p = isl_printer_print_str(p, "(");
2607 p = print_affine_of_len(space, aff->ls->div, p,
2608 aff->v->el + 1, 1 + total);
2609 if (isl_int_is_one(aff->v->el[0]))
2610 p = isl_printer_print_str(p, ")");
2611 else {
2612 p = isl_printer_print_str(p, ")/");
2613 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2616 return p;
2619 static __isl_give isl_printer *print_aff(__isl_take isl_printer *p,
2620 __isl_keep isl_aff *aff)
2622 struct isl_print_space_data data = { 0 };
2624 if (isl_space_is_params(aff->ls->dim))
2626 else {
2627 p = print_tuple(aff->ls->dim, p, isl_dim_set, &data);
2628 p = isl_printer_print_str(p, " -> ");
2630 p = isl_printer_print_str(p, "[");
2631 p = print_aff_body(p, aff->ls->dim, aff);
2632 p = isl_printer_print_str(p, "]");
2634 return p;
2637 static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p,
2638 __isl_keep isl_aff *aff)
2640 struct isl_print_space_data data = { 0 };
2642 if (!aff)
2643 goto error;
2645 p = print_param_tuple(p, aff->ls->dim, &data);
2646 p = isl_printer_print_str(p, "{ ");
2647 p = print_aff(p, aff);
2648 p = isl_printer_print_str(p, " }");
2649 return p;
2650 error:
2651 isl_printer_free(p);
2652 return NULL;
2655 /* Print the body of an isl_pw_aff, i.e., a semicolon delimited
2656 * sequence of affine expressions, each followed by constraints.
2658 static __isl_give isl_printer *print_pw_aff_body(
2659 __isl_take isl_printer *p, __isl_keep isl_pw_aff *pa)
2661 int i;
2663 if (!pa)
2664 return isl_printer_free(p);
2666 for (i = 0; i < pa->n; ++i) {
2667 isl_space *space;
2669 if (i)
2670 p = isl_printer_print_str(p, "; ");
2671 p = print_aff(p, pa->p[i].aff);
2672 space = isl_aff_get_domain_space(pa->p[i].aff);
2673 p = print_disjuncts(set_to_map(pa->p[i].set), space, p, 0);
2674 isl_space_free(space);
2677 return p;
2680 static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p,
2681 __isl_keep isl_pw_aff *pwaff)
2683 struct isl_print_space_data data = { 0 };
2685 if (!pwaff)
2686 goto error;
2688 p = print_param_tuple(p, pwaff->dim, &data);
2689 p = isl_printer_print_str(p, "{ ");
2690 p = print_pw_aff_body(p, pwaff);
2691 p = isl_printer_print_str(p, " }");
2692 return p;
2693 error:
2694 isl_printer_free(p);
2695 return NULL;
2698 static __isl_give isl_printer *print_ls_name_c(__isl_take isl_printer *p,
2699 __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos)
2701 if (type == isl_dim_div) {
2702 p = isl_printer_print_str(p, "floord(");
2703 p = print_ls_affine_c(p, ls, ls->div->row[pos] + 1);
2704 p = isl_printer_print_str(p, ", ");
2705 p = isl_printer_print_isl_int(p, ls->div->row[pos][0]);
2706 p = isl_printer_print_str(p, ")");
2707 } else {
2708 const char *name;
2710 name = isl_space_get_dim_name(ls->dim, type, pos);
2711 if (!name)
2712 name = "UNNAMED";
2713 p = isl_printer_print_str(p, name);
2715 return p;
2718 static __isl_give isl_printer *print_ls_term_c(__isl_take isl_printer *p,
2719 __isl_keep isl_local_space *ls, isl_int c, unsigned pos)
2721 enum isl_dim_type type;
2723 if (!p || !ls)
2724 return isl_printer_free(p);
2726 if (pos == 0)
2727 return isl_printer_print_isl_int(p, c);
2729 if (isl_int_is_one(c))
2731 else if (isl_int_is_negone(c))
2732 p = isl_printer_print_str(p, "-");
2733 else {
2734 p = isl_printer_print_isl_int(p, c);
2735 p = isl_printer_print_str(p, "*");
2737 if (pos2type(ls->dim, &type, &pos) < 0)
2738 return isl_printer_free(p);
2739 p = print_ls_name_c(p, ls, type, pos);
2740 return p;
2743 static __isl_give isl_printer *print_ls_partial_affine_c(
2744 __isl_take isl_printer *p, __isl_keep isl_local_space *ls,
2745 isl_int *c, unsigned len)
2747 int i;
2748 int first;
2750 for (i = 0, first = 1; i < len; ++i) {
2751 int flip = 0;
2752 if (isl_int_is_zero(c[i]))
2753 continue;
2754 if (!first) {
2755 if (isl_int_is_neg(c[i])) {
2756 flip = 1;
2757 isl_int_neg(c[i], c[i]);
2758 p = isl_printer_print_str(p, " - ");
2759 } else
2760 p = isl_printer_print_str(p, " + ");
2762 first = 0;
2763 p = print_ls_term_c(p, ls, c[i], i);
2764 if (flip)
2765 isl_int_neg(c[i], c[i]);
2767 if (first)
2768 p = isl_printer_print_str(p, "0");
2769 return p;
2772 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2773 __isl_keep isl_local_space *ls, isl_int *c)
2775 isl_size total = isl_local_space_dim(ls, isl_dim_all);
2777 if (total < 0)
2778 return isl_printer_free(p);
2779 return print_ls_partial_affine_c(p, ls, c, 1 + total);
2782 static __isl_give isl_printer *print_aff_c(__isl_take isl_printer *p,
2783 __isl_keep isl_aff *aff)
2785 isl_size total;
2787 total = isl_local_space_dim(aff->ls, isl_dim_all);
2788 if (total < 0)
2789 return isl_printer_free(p);
2790 if (!isl_int_is_one(aff->v->el[0]))
2791 p = isl_printer_print_str(p, "(");
2792 p = print_ls_partial_affine_c(p, aff->ls, aff->v->el + 1, 1 + total);
2793 if (!isl_int_is_one(aff->v->el[0])) {
2794 p = isl_printer_print_str(p, ")/");
2795 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2797 return p;
2800 /* In the C format, we cannot express that "pwaff" may be undefined
2801 * on parts of the domain space. We therefore assume that the expression
2802 * will only be evaluated on its definition domain and compute the gist
2803 * of each cell with respect to this domain.
2805 static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p,
2806 __isl_keep isl_pw_aff *pwaff)
2808 isl_set *domain;
2809 isl_ast_build *build;
2810 isl_ast_expr *expr;
2812 if (pwaff->n < 1)
2813 isl_die(p->ctx, isl_error_unsupported,
2814 "cannot print empty isl_pw_aff in C format",
2815 return isl_printer_free(p));
2817 domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff));
2818 build = isl_ast_build_from_context(domain);
2819 expr = isl_ast_build_expr_from_pw_aff(build, isl_pw_aff_copy(pwaff));
2820 p = isl_printer_print_ast_expr(p, expr);
2821 isl_ast_expr_free(expr);
2822 isl_ast_build_free(build);
2824 return p;
2827 __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p,
2828 __isl_keep isl_aff *aff)
2830 if (!p || !aff)
2831 goto error;
2833 if (p->output_format == ISL_FORMAT_ISL)
2834 return print_aff_isl(p, aff);
2835 else if (p->output_format == ISL_FORMAT_C)
2836 return print_aff_c(p, aff);
2837 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2838 goto error);
2839 error:
2840 isl_printer_free(p);
2841 return NULL;
2844 __isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p,
2845 __isl_keep isl_pw_aff *pwaff)
2847 if (!p || !pwaff)
2848 goto error;
2850 if (p->output_format == ISL_FORMAT_ISL)
2851 return print_pw_aff_isl(p, pwaff);
2852 else if (p->output_format == ISL_FORMAT_C)
2853 return print_pw_aff_c(p, pwaff);
2854 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2855 goto error);
2856 error:
2857 isl_printer_free(p);
2858 return NULL;
2861 /* Print "pa" in a sequence of isl_pw_affs delimited by semicolons.
2862 * Each isl_pw_aff itself is also printed as semicolon delimited
2863 * sequence of pieces.
2864 * If data->first = 1, then this is the first in the sequence.
2865 * Update data->first to tell the next element that it is not the first.
2867 static isl_stat print_pw_aff_body_wrap(__isl_take isl_pw_aff *pa,
2868 void *user)
2870 struct isl_union_print_data *data;
2871 data = (struct isl_union_print_data *) user;
2873 if (!data->first)
2874 data->p = isl_printer_print_str(data->p, "; ");
2875 data->first = 0;
2877 data->p = print_pw_aff_body(data->p, pa);
2878 isl_pw_aff_free(pa);
2880 return data->p ? isl_stat_ok : isl_stat_error;
2883 /* Print the body of an isl_union_pw_aff, i.e., a semicolon delimited
2884 * sequence of affine expressions, each followed by constraints,
2885 * with the sequence enclosed in braces.
2887 static __isl_give isl_printer *print_union_pw_aff_body(
2888 __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
2890 struct isl_union_print_data data = { p, 1 };
2892 p = isl_printer_print_str(p, s_open_set[0]);
2893 data.p = p;
2894 if (isl_union_pw_aff_foreach_pw_aff(upa,
2895 &print_pw_aff_body_wrap, &data) < 0)
2896 data.p = isl_printer_free(p);
2897 p = data.p;
2898 p = isl_printer_print_str(p, s_close_set[0]);
2900 return p;
2903 /* Print the isl_union_pw_aff "upa" to "p" in isl format.
2905 * The individual isl_pw_affs are delimited by a semicolon.
2907 static __isl_give isl_printer *print_union_pw_aff_isl(
2908 __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
2910 struct isl_print_space_data data = { 0 };
2911 isl_space *space;
2913 space = isl_union_pw_aff_get_space(upa);
2914 p = print_param_tuple(p, space, &data);
2915 isl_space_free(space);
2916 p = print_union_pw_aff_body(p, upa);
2917 return p;
2920 /* Print the isl_union_pw_aff "upa" to "p".
2922 * We currently only support an isl format.
2924 __isl_give isl_printer *isl_printer_print_union_pw_aff(
2925 __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
2927 if (!p || !upa)
2928 return isl_printer_free(p);
2930 if (p->output_format == ISL_FORMAT_ISL)
2931 return print_union_pw_aff_isl(p, upa);
2932 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
2933 "unsupported output format", return isl_printer_free(p));
2936 /* Print dimension "pos" of data->space to "p".
2938 * data->user is assumed to be an isl_multi_aff.
2940 * If the current dimension is an output dimension, then print
2941 * the corresponding expression. Otherwise, print the name of the dimension.
2942 * Make sure to use the domain space for printing names as
2943 * that is the space that will be used for printing constraints (if any).
2945 static __isl_give isl_printer *print_dim_ma(__isl_take isl_printer *p,
2946 struct isl_print_space_data *data, unsigned pos)
2948 isl_multi_aff *ma = data->user;
2949 isl_space *space;
2951 space = isl_multi_aff_get_domain_space(ma);
2952 if (data->type == isl_dim_out) {
2953 p = print_aff_body(p, space, ma->u.p[pos]);
2954 } else {
2955 enum isl_dim_type type = data->type;
2957 if (type == isl_dim_in)
2958 type = isl_dim_set;
2959 p = print_name(space, p, type, pos, data->latex);
2961 isl_space_free(space);
2963 return p;
2966 static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p,
2967 __isl_keep isl_multi_aff *maff)
2969 struct isl_print_space_data data = { 0 };
2971 data.print_dim = &print_dim_ma;
2972 data.user = maff;
2973 return isl_print_space(maff->space, p, 0, &data);
2976 static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p,
2977 __isl_keep isl_multi_aff *maff)
2979 struct isl_print_space_data data = { 0 };
2981 if (!maff)
2982 goto error;
2984 p = print_param_tuple(p, maff->space, &data);
2985 p = isl_printer_print_str(p, "{ ");
2986 p = print_multi_aff(p, maff);
2987 p = isl_printer_print_str(p, " }");
2988 return p;
2989 error:
2990 isl_printer_free(p);
2991 return NULL;
2994 __isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p,
2995 __isl_keep isl_multi_aff *maff)
2997 if (!p || !maff)
2998 goto error;
3000 if (p->output_format == ISL_FORMAT_ISL)
3001 return print_multi_aff_isl(p, maff);
3002 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
3003 goto error);
3004 error:
3005 isl_printer_free(p);
3006 return NULL;
3009 static __isl_give isl_printer *print_pw_multi_aff_body(
3010 __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
3012 int i;
3014 if (!pma)
3015 goto error;
3017 for (i = 0; i < pma->n; ++i) {
3018 isl_space *space;
3020 if (i)
3021 p = isl_printer_print_str(p, "; ");
3022 p = print_multi_aff(p, pma->p[i].maff);
3023 space = isl_multi_aff_get_domain_space(pma->p[i].maff);
3024 p = print_disjuncts(set_to_map(pma->p[i].set), space, p, 0);
3025 isl_space_free(space);
3027 return p;
3028 error:
3029 isl_printer_free(p);
3030 return NULL;
3033 static __isl_give isl_printer *print_pw_multi_aff_isl(__isl_take isl_printer *p,
3034 __isl_keep isl_pw_multi_aff *pma)
3036 struct isl_print_space_data data = { 0 };
3038 if (!pma)
3039 goto error;
3041 p = print_param_tuple(p, pma->dim, &data);
3042 p = isl_printer_print_str(p, "{ ");
3043 p = print_pw_multi_aff_body(p, pma);
3044 p = isl_printer_print_str(p, " }");
3045 return p;
3046 error:
3047 isl_printer_free(p);
3048 return NULL;
3051 /* Print the unnamed, single-dimensional piecewise multi affine expression "pma"
3052 * to "p".
3054 static __isl_give isl_printer *print_unnamed_pw_multi_aff_c(
3055 __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
3057 int i;
3058 isl_space *space;
3060 space = isl_pw_multi_aff_get_domain_space(pma);
3061 for (i = 0; i < pma->n - 1; ++i) {
3062 p = isl_printer_print_str(p, "(");
3063 p = print_set_c(p, space, pma->p[i].set);
3064 p = isl_printer_print_str(p, ") ? (");
3065 p = print_aff_c(p, pma->p[i].maff->u.p[0]);
3066 p = isl_printer_print_str(p, ") : ");
3068 isl_space_free(space);
3070 return print_aff_c(p, pma->p[pma->n - 1].maff->u.p[0]);
3073 static __isl_give isl_printer *print_pw_multi_aff_c(__isl_take isl_printer *p,
3074 __isl_keep isl_pw_multi_aff *pma)
3076 isl_size n;
3077 const char *name;
3079 if (!pma)
3080 goto error;
3081 if (pma->n < 1)
3082 isl_die(p->ctx, isl_error_unsupported,
3083 "cannot print empty isl_pw_multi_aff in C format",
3084 goto error);
3085 n = isl_pw_multi_aff_dim(pma, isl_dim_out);
3086 if (n < 0)
3087 return isl_printer_free(p);
3088 name = isl_pw_multi_aff_get_tuple_name(pma, isl_dim_out);
3089 if (!name && n == 1)
3090 return print_unnamed_pw_multi_aff_c(p, pma);
3091 if (!name)
3092 isl_die(p->ctx, isl_error_unsupported,
3093 "cannot print unnamed isl_pw_multi_aff in C format",
3094 goto error);
3096 p = isl_printer_print_str(p, name);
3097 if (n != 0)
3098 isl_die(p->ctx, isl_error_unsupported,
3099 "not supported yet", goto error);
3101 return p;
3102 error:
3103 isl_printer_free(p);
3104 return NULL;
3107 __isl_give isl_printer *isl_printer_print_pw_multi_aff(
3108 __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
3110 if (!p || !pma)
3111 goto error;
3113 if (p->output_format == ISL_FORMAT_ISL)
3114 return print_pw_multi_aff_isl(p, pma);
3115 if (p->output_format == ISL_FORMAT_C)
3116 return print_pw_multi_aff_c(p, pma);
3117 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
3118 goto error);
3119 error:
3120 isl_printer_free(p);
3121 return NULL;
3124 static isl_stat print_pw_multi_aff_body_wrap(__isl_take isl_pw_multi_aff *pma,
3125 void *user)
3127 struct isl_union_print_data *data;
3128 data = (struct isl_union_print_data *) user;
3130 if (!data->first)
3131 data->p = isl_printer_print_str(data->p, "; ");
3132 data->first = 0;
3134 data->p = print_pw_multi_aff_body(data->p, pma);
3135 isl_pw_multi_aff_free(pma);
3137 return isl_stat_ok;
3140 static __isl_give isl_printer *print_union_pw_multi_aff_isl(
3141 __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
3143 struct isl_union_print_data data;
3144 struct isl_print_space_data space_data = { 0 };
3145 isl_space *space;
3147 space = isl_union_pw_multi_aff_get_space(upma);
3148 p = print_param_tuple(p, space, &space_data);
3149 isl_space_free(space);
3150 p = isl_printer_print_str(p, s_open_set[0]);
3151 data.p = p;
3152 data.first = 1;
3153 isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
3154 &print_pw_multi_aff_body_wrap, &data);
3155 p = data.p;
3156 p = isl_printer_print_str(p, s_close_set[0]);
3157 return p;
3160 __isl_give isl_printer *isl_printer_print_union_pw_multi_aff(
3161 __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
3163 if (!p || !upma)
3164 goto error;
3166 if (p->output_format == ISL_FORMAT_ISL)
3167 return print_union_pw_multi_aff_isl(p, upma);
3168 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
3169 goto error);
3170 error:
3171 isl_printer_free(p);
3172 return NULL;
3175 /* Print dimension "pos" of data->space to "p".
3177 * data->user is assumed to be an isl_multi_pw_aff.
3179 * If the current dimension is an output dimension, then print
3180 * the corresponding piecewise affine expression.
3181 * Otherwise, print the name of the dimension.
3182 * Make sure to use the same space in both cases.
3183 * In particular, use the domain space for printing names as
3184 * that is the space that is used for printing constraints.
3186 static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p,
3187 struct isl_print_space_data *data, unsigned pos)
3189 int i;
3190 int need_parens;
3191 isl_space *space;
3192 isl_multi_pw_aff *mpa = data->user;
3193 isl_pw_aff *pa;
3195 if (data->type != isl_dim_out) {
3196 enum isl_dim_type type = data->type;
3198 if (type == isl_dim_in)
3199 type = isl_dim_set;
3200 space = isl_multi_pw_aff_get_domain_space(mpa);
3201 p = print_name(space, p, type, pos, data->latex);
3202 isl_space_free(space);
3203 return p;
3206 pa = mpa->u.p[pos];
3207 if (pa->n == 0)
3208 return isl_printer_print_str(p, "(0 : false)");
3210 need_parens = pa->n != 1 || !isl_set_plain_is_universe(pa->p[0].set);
3211 if (need_parens)
3212 p = isl_printer_print_str(p, "(");
3213 space = isl_multi_pw_aff_get_domain_space(mpa);
3214 for (i = 0; i < pa->n; ++i) {
3216 if (i)
3217 p = isl_printer_print_str(p, "; ");
3218 p = print_aff_body(p, space, pa->p[i].aff);
3219 p = print_disjuncts(pa->p[i].set, space, p, 0);
3221 isl_space_free(space);
3222 if (need_parens)
3223 p = isl_printer_print_str(p, ")");
3225 return p;
3228 /* Print "mpa" to "p" in isl format.
3230 * If "mpa" is zero-dimensional and has a non-trivial explicit domain,
3231 * then it is printed after the tuple of affine expressions.
3233 static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p,
3234 __isl_keep isl_multi_pw_aff *mpa)
3236 struct isl_print_space_data data = { 0 };
3237 isl_bool has_domain;
3239 if (!mpa)
3240 return isl_printer_free(p);
3242 p = print_param_tuple(p, mpa->space, &data);
3243 p = isl_printer_print_str(p, "{ ");
3244 data.print_dim = &print_dim_mpa;
3245 data.user = mpa;
3246 p = isl_print_space(mpa->space, p, 0, &data);
3247 has_domain = isl_multi_pw_aff_has_non_trivial_domain(mpa);
3248 if (has_domain < 0)
3249 return isl_printer_free(p);
3250 if (has_domain) {
3251 isl_space *space;
3253 space = isl_space_domain(isl_space_copy(mpa->space));
3254 p = print_disjuncts_set(mpa->u.dom, space, p, 0);
3255 isl_space_free(space);
3257 p = isl_printer_print_str(p, " }");
3258 return p;
3261 __isl_give isl_printer *isl_printer_print_multi_pw_aff(
3262 __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa)
3264 if (!p || !mpa)
3265 return isl_printer_free(p);
3267 if (p->output_format == ISL_FORMAT_ISL)
3268 return print_multi_pw_aff_isl(p, mpa);
3269 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
3270 return isl_printer_free(p));
3273 /* Print dimension "pos" of data->space to "p".
3275 * data->user is assumed to be an isl_multi_val.
3277 * If the current dimension is an output dimension, then print
3278 * the corresponding value. Otherwise, print the name of the dimension.
3280 static __isl_give isl_printer *print_dim_mv(__isl_take isl_printer *p,
3281 struct isl_print_space_data *data, unsigned pos)
3283 isl_multi_val *mv = data->user;
3285 if (data->type == isl_dim_out)
3286 return isl_printer_print_val(p, mv->u.p[pos]);
3287 else
3288 return print_name(data->space, p, data->type, pos, data->latex);
3291 /* Print the isl_multi_val "mv" to "p" in isl format.
3293 static __isl_give isl_printer *print_multi_val_isl(__isl_take isl_printer *p,
3294 __isl_keep isl_multi_val *mv)
3296 struct isl_print_space_data data = { 0 };
3298 if (!mv)
3299 return isl_printer_free(p);
3301 p = print_param_tuple(p, mv->space, &data);
3302 p = isl_printer_print_str(p, "{ ");
3303 data.print_dim = &print_dim_mv;
3304 data.user = mv;
3305 p = isl_print_space(mv->space, p, 0, &data);
3306 p = isl_printer_print_str(p, " }");
3307 return p;
3310 /* Print the isl_multi_val "mv" to "p".
3312 * Currently only supported in isl format.
3314 __isl_give isl_printer *isl_printer_print_multi_val(
3315 __isl_take isl_printer *p, __isl_keep isl_multi_val *mv)
3317 if (!p || !mv)
3318 return isl_printer_free(p);
3320 if (p->output_format == ISL_FORMAT_ISL)
3321 return print_multi_val_isl(p, mv);
3322 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
3323 return isl_printer_free(p));
3326 /* Print dimension "pos" of data->space to "p".
3328 * data->user is assumed to be an isl_multi_id.
3330 * If the current dimension is an output dimension, then print
3331 * the corresponding identifier. Otherwise, print the name of the dimension.
3333 static __isl_give isl_printer *print_dim_mi(__isl_take isl_printer *p,
3334 struct isl_print_space_data *data, unsigned pos)
3336 isl_multi_id *mi = data->user;
3338 if (data->type == isl_dim_out)
3339 return isl_printer_print_id(p, mi->u.p[pos]);
3340 else
3341 return print_name(data->space, p, data->type, pos, data->latex);
3344 /* Print the isl_multi_id "mi" to "p" in isl format.
3346 static __isl_give isl_printer *print_multi_id_isl(__isl_take isl_printer *p,
3347 __isl_keep isl_multi_id *mi)
3349 isl_space *space;
3350 struct isl_print_space_data data = { 0 };
3352 space = isl_multi_id_peek_space(mi);
3353 p = print_param_tuple(p, space, &data);
3354 p = isl_printer_print_str(p, "{ ");
3355 data.print_dim = &print_dim_mi;
3356 data.user = mi;
3357 p = isl_print_space(space, p, 0, &data);
3358 p = isl_printer_print_str(p, " }");
3359 return p;
3362 /* Print the isl_multi_id "mi" to "p".
3364 * Currently only supported in isl format.
3366 __isl_give isl_printer *isl_printer_print_multi_id(
3367 __isl_take isl_printer *p, __isl_keep isl_multi_id *mi)
3369 if (!p || !mi)
3370 return isl_printer_free(p);
3372 if (p->output_format == ISL_FORMAT_ISL)
3373 return print_multi_id_isl(p, mi);
3374 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
3375 "unsupported output format", return isl_printer_free(p));
3378 /* Print dimension "pos" of data->space to "p".
3380 * data->user is assumed to be an isl_multi_union_pw_aff.
3382 * The current dimension is necessarily a set dimension, so
3383 * we print the corresponding isl_union_pw_aff, including
3384 * the braces.
3386 static __isl_give isl_printer *print_union_pw_aff_dim(__isl_take isl_printer *p,
3387 struct isl_print_space_data *data, unsigned pos)
3389 isl_multi_union_pw_aff *mupa = data->user;
3390 isl_union_pw_aff *upa;
3392 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, pos);
3393 p = print_union_pw_aff_body(p, upa);
3394 isl_union_pw_aff_free(upa);
3396 return p;
3399 /* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.
3401 * If "mupa" is zero-dimensional and has a non-trivial explicit domain,
3402 * then it is printed after the tuple of affine expressions.
3403 * In order to clarify that this domain belongs to the expression,
3404 * the tuple along with the domain are placed inside parentheses.
3405 * If "mupa" has any parameters, then the opening parenthesis
3406 * appears after the parameter declarations.
3408 static __isl_give isl_printer *print_multi_union_pw_aff_isl(
3409 __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)
3411 struct isl_print_space_data data = { 0 };
3412 isl_bool has_domain;
3413 isl_space *space;
3415 if (!mupa)
3416 return isl_printer_free(p);
3417 has_domain = isl_multi_union_pw_aff_has_non_trivial_domain(mupa);
3418 if (has_domain < 0)
3419 return isl_printer_free(p);
3421 space = isl_multi_union_pw_aff_get_space(mupa);
3422 p = print_param_tuple(p, space, &data);
3424 if (has_domain)
3425 p = isl_printer_print_str(p, "(");
3427 data.print_dim = &print_union_pw_aff_dim;
3428 data.user = mupa;
3430 p = isl_print_space(space, p, 0, &data);
3431 isl_space_free(space);
3433 if (has_domain) {
3434 p = isl_printer_print_str(p, " : ");
3435 p = isl_printer_print_union_set_isl_body(p, mupa->u.dom);
3436 p = isl_printer_print_str(p, ")");
3439 return p;
3442 /* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.
3444 * We currently only support an isl format.
3446 __isl_give isl_printer *isl_printer_print_multi_union_pw_aff(
3447 __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)
3449 if (!p || !mupa)
3450 return isl_printer_free(p);
3452 if (p->output_format == ISL_FORMAT_ISL)
3453 return print_multi_union_pw_aff_isl(p, mupa);
3454 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
3455 "unsupported output format", return isl_printer_free(p));