isl_tab_pip.c: set free callback before any other fields
[isl.git] / isl_output.c
bloba5fb45990c7adcc7fdcea405d7c055222742d5a5
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_map.h>
27 #include <isl/constraint.h>
28 #include <isl_local_space_private.h>
29 #include <isl_aff_private.h>
30 #include <isl_val_private.h>
31 #include <isl_constraint_private.h>
32 #include <isl/ast_build.h>
33 #include <isl_sort.h>
34 #include <isl_output_private.h>
36 #include <bset_to_bmap.c>
37 #include <set_to_map.c>
39 static const char *s_to[2] = { " -> ", " \\to " };
40 static const char *s_and[2] = { " and ", " \\wedge " };
41 static const char *s_or[2] = { " or ", " \\vee " };
42 static const char *s_le[2] = { "<=", "\\le" };
43 static const char *s_ge[2] = { ">=", "\\ge" };
44 static const char *s_open_set[2] = { "{ ", "\\{\\, " };
45 static const char *s_close_set[2] = { " }", " \\,\\}" };
46 static const char *s_open_list[2] = { "[", "(" };
47 static const char *s_close_list[2] = { "]", ")" };
48 static const char *s_such_that[2] = { " : ", " \\mid " };
49 static const char *s_open_exists[2] = { "exists (", "\\exists \\, " };
50 static const char *s_close_exists[2] = { ")", "" };
51 static const char *s_div_prefix[2] = { "e", "\\alpha_" };
52 static const char *s_param_prefix[2] = { "p", "p_" };
53 static const char *s_input_prefix[2] = { "i", "i_" };
54 static const char *s_output_prefix[2] = { "o", "o_" };
56 static __isl_give isl_printer *print_constraint_polylib(
57 struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p)
59 int i;
60 unsigned n_in = isl_basic_map_dim(bmap, isl_dim_in);
61 unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
62 unsigned nparam = isl_basic_map_dim(bmap, isl_dim_param);
63 isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n];
65 p = isl_printer_start_line(p);
66 p = isl_printer_print_int(p, ineq);
67 for (i = 0; i < n_out; ++i) {
68 p = isl_printer_print_str(p, " ");
69 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]);
71 for (i = 0; i < n_in; ++i) {
72 p = isl_printer_print_str(p, " ");
73 p = isl_printer_print_isl_int(p, c[1+nparam+i]);
75 for (i = 0; i < bmap->n_div; ++i) {
76 p = isl_printer_print_str(p, " ");
77 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]);
79 for (i = 0; i < nparam; ++i) {
80 p = isl_printer_print_str(p, " ");
81 p = isl_printer_print_isl_int(p, c[1+i]);
83 p = isl_printer_print_str(p, " ");
84 p = isl_printer_print_isl_int(p, c[0]);
85 p = isl_printer_end_line(p);
86 return p;
89 static __isl_give isl_printer *print_constraints_polylib(
90 struct isl_basic_map *bmap, __isl_take isl_printer *p)
92 int i;
94 p = isl_printer_set_isl_int_width(p, 5);
96 for (i = 0; i < bmap->n_eq; ++i)
97 p = print_constraint_polylib(bmap, 0, i, p);
98 for (i = 0; i < bmap->n_ineq; ++i)
99 p = print_constraint_polylib(bmap, 1, i, p);
101 return p;
104 static __isl_give isl_printer *bset_print_constraints_polylib(
105 struct isl_basic_set *bset, __isl_take isl_printer *p)
107 return print_constraints_polylib(bset_to_bmap(bset), p);
110 static __isl_give isl_printer *isl_basic_map_print_polylib(
111 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int ext)
113 unsigned total = isl_basic_map_total_dim(bmap);
114 p = isl_printer_start_line(p);
115 p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq);
116 p = isl_printer_print_str(p, " ");
117 p = isl_printer_print_int(p, 1 + total + 1);
118 if (ext) {
119 p = isl_printer_print_str(p, " ");
120 p = isl_printer_print_int(p,
121 isl_basic_map_dim(bmap, isl_dim_out));
122 p = isl_printer_print_str(p, " ");
123 p = isl_printer_print_int(p,
124 isl_basic_map_dim(bmap, isl_dim_in));
125 p = isl_printer_print_str(p, " ");
126 p = isl_printer_print_int(p,
127 isl_basic_map_dim(bmap, isl_dim_div));
128 p = isl_printer_print_str(p, " ");
129 p = isl_printer_print_int(p,
130 isl_basic_map_dim(bmap, isl_dim_param));
132 p = isl_printer_end_line(p);
133 return print_constraints_polylib(bmap, p);
136 static __isl_give isl_printer *isl_basic_set_print_polylib(
137 __isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int ext)
139 return isl_basic_map_print_polylib(bset_to_bmap(bset), p, ext);
142 static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map,
143 __isl_take isl_printer *p, int ext)
145 int i;
147 p = isl_printer_start_line(p);
148 p = isl_printer_print_int(p, map->n);
149 p = isl_printer_end_line(p);
150 for (i = 0; i < map->n; ++i) {
151 p = isl_printer_start_line(p);
152 p = isl_printer_end_line(p);
153 p = isl_basic_map_print_polylib(map->p[i], p, ext);
155 return p;
158 static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set,
159 __isl_take isl_printer *p, int ext)
161 return isl_map_print_polylib(set_to_map(set), p, ext);
164 static int count_same_name(__isl_keep isl_space *dim,
165 enum isl_dim_type type, unsigned pos, const char *name)
167 enum isl_dim_type t;
168 unsigned p, s;
169 int count = 0;
171 for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) {
172 s = t == type ? pos : isl_space_dim(dim, t);
173 for (p = 0; p < s; ++p) {
174 const char *n = isl_space_get_dim_name(dim, t, p);
175 if (n && !strcmp(n, name))
176 count++;
179 return count;
182 /* Print the name of the variable of type "type" and position "pos"
183 * in "space" to "p".
185 static __isl_give isl_printer *print_name(__isl_keep isl_space *space,
186 __isl_take isl_printer *p, enum isl_dim_type type, unsigned pos,
187 int latex)
189 const char *name;
190 char buffer[20];
191 int primes;
193 name = type == isl_dim_div ? NULL
194 : isl_space_get_dim_name(space, type, pos);
196 if (!name) {
197 const char *prefix;
198 if (type == isl_dim_param)
199 prefix = s_param_prefix[latex];
200 else if (type == isl_dim_div)
201 prefix = s_div_prefix[latex];
202 else if (isl_space_is_set(space) || type == isl_dim_in)
203 prefix = s_input_prefix[latex];
204 else
205 prefix = s_output_prefix[latex];
206 snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);
207 name = buffer;
209 primes = count_same_name(space, name == buffer ? isl_dim_div : type,
210 pos, name);
211 p = isl_printer_print_str(p, name);
212 while (primes-- > 0)
213 p = isl_printer_print_str(p, "'");
214 return p;
217 static enum isl_dim_type pos2type(__isl_keep isl_space *dim, unsigned *pos)
219 enum isl_dim_type type;
220 unsigned n_in = isl_space_dim(dim, isl_dim_in);
221 unsigned n_out = isl_space_dim(dim, isl_dim_out);
222 unsigned nparam = isl_space_dim(dim, isl_dim_param);
224 if (*pos < 1 + nparam) {
225 type = isl_dim_param;
226 *pos -= 1;
227 } else if (*pos < 1 + nparam + n_in) {
228 type = isl_dim_in;
229 *pos -= 1 + nparam;
230 } else if (*pos < 1 + nparam + n_in + n_out) {
231 type = isl_dim_out;
232 *pos -= 1 + nparam + n_in;
233 } else {
234 type = isl_dim_div;
235 *pos -= 1 + nparam + n_in + n_out;
238 return type;
241 /* Can the div expression of the integer division at position "row" of "div"
242 * be printed?
243 * In particular, are the div expressions available and does the selected
244 * variable have a known explicit representation?
245 * Furthermore, the Omega format does not allow any div expressions
246 * to be printed.
248 static isl_bool can_print_div_expr(__isl_keep isl_printer *p,
249 __isl_keep isl_mat *div, int pos)
251 if (p->output_format == ISL_FORMAT_OMEGA)
252 return isl_bool_false;
253 if (!div)
254 return isl_bool_false;
255 return !isl_int_is_zero(div->row[pos][0]);
258 static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
259 __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p);
261 static __isl_give isl_printer *print_term(__isl_keep isl_space *space,
262 __isl_keep isl_mat *div,
263 isl_int c, unsigned pos, __isl_take isl_printer *p, int latex)
265 enum isl_dim_type type;
266 int print_div_def;
268 if (pos == 0)
269 return isl_printer_print_isl_int(p, c);
271 type = pos2type(space, &pos);
272 print_div_def = type == isl_dim_div && can_print_div_expr(p, div, pos);
274 if (isl_int_is_one(c))
276 else if (isl_int_is_negone(c))
277 p = isl_printer_print_str(p, "-");
278 else {
279 p = isl_printer_print_isl_int(p, c);
280 if (p->output_format == ISL_FORMAT_C || print_div_def)
281 p = isl_printer_print_str(p, "*");
283 if (print_div_def)
284 p = print_div(space, div, pos, p);
285 else
286 p = print_name(space, p, type, pos, latex);
287 return p;
290 static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *dim,
291 __isl_keep isl_mat *div,
292 __isl_take isl_printer *p, isl_int *c, int len)
294 int i;
295 int first;
297 for (i = 0, first = 1; i < len; ++i) {
298 int flip = 0;
299 if (isl_int_is_zero(c[i]))
300 continue;
301 if (!first) {
302 if (isl_int_is_neg(c[i])) {
303 flip = 1;
304 isl_int_neg(c[i], c[i]);
305 p = isl_printer_print_str(p, " - ");
306 } else
307 p = isl_printer_print_str(p, " + ");
309 first = 0;
310 p = print_term(dim, div, c[i], i, p, 0);
311 if (flip)
312 isl_int_neg(c[i], c[i]);
314 if (first)
315 p = isl_printer_print_str(p, "0");
316 return p;
319 /* Print an affine expression "c" corresponding to a constraint in "bmap"
320 * to "p", with the variable names taken from "space" and
321 * the integer division definitions taken from "div".
323 static __isl_give isl_printer *print_affine(__isl_keep isl_basic_map *bmap,
324 __isl_keep isl_space *space, __isl_keep isl_mat *div,
325 __isl_take isl_printer *p, isl_int *c)
327 unsigned len = 1 + isl_basic_map_total_dim(bmap);
328 return print_affine_of_len(space, div, p, c, len);
331 /* offset is the offset of local_dim inside data->type of data->space.
333 static __isl_give isl_printer *print_nested_var_list(__isl_take isl_printer *p,
334 __isl_keep isl_space *local_dim, enum isl_dim_type local_type,
335 struct isl_print_space_data *data, int offset)
337 int i;
339 if (data->space != local_dim && local_type == isl_dim_out)
340 offset += local_dim->n_in;
342 for (i = 0; i < isl_space_dim(local_dim, local_type); ++i) {
343 if (i)
344 p = isl_printer_print_str(p, ", ");
345 if (data->print_dim)
346 p = data->print_dim(p, data, offset + i);
347 else
348 p = print_name(data->space, p, data->type, offset + i,
349 data->latex);
351 return p;
354 static __isl_give isl_printer *print_var_list(__isl_take isl_printer *p,
355 __isl_keep isl_space *space, enum isl_dim_type type)
357 struct isl_print_space_data data = { .space = space, .type = type };
359 return print_nested_var_list(p, space, type, &data, 0);
362 static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
363 __isl_keep isl_space *local_dim,
364 struct isl_print_space_data *data, int offset);
366 static __isl_give isl_printer *print_nested_tuple(__isl_take isl_printer *p,
367 __isl_keep isl_space *local_dim, enum isl_dim_type local_type,
368 struct isl_print_space_data *data, int offset)
370 const char *name = NULL;
371 unsigned n = isl_space_dim(local_dim, local_type);
372 if ((local_type == isl_dim_in || local_type == isl_dim_out)) {
373 name = isl_space_get_tuple_name(local_dim, local_type);
374 if (name) {
375 if (data->latex)
376 p = isl_printer_print_str(p, "\\mathrm{");
377 p = isl_printer_print_str(p, name);
378 if (data->latex)
379 p = isl_printer_print_str(p, "}");
382 if (!data->latex || n != 1 || name)
383 p = isl_printer_print_str(p, s_open_list[data->latex]);
384 if ((local_type == isl_dim_in || local_type == isl_dim_out) &&
385 local_dim->nested[local_type - isl_dim_in]) {
386 if (data->space != local_dim && local_type == isl_dim_out)
387 offset += local_dim->n_in;
388 p = print_nested_map_dim(p,
389 local_dim->nested[local_type - isl_dim_in],
390 data, offset);
391 } else
392 p = print_nested_var_list(p, local_dim, local_type, data,
393 offset);
394 if (!data->latex || n != 1 || name)
395 p = isl_printer_print_str(p, s_close_list[data->latex]);
396 return p;
399 static __isl_give isl_printer *print_tuple(__isl_keep isl_space *dim,
400 __isl_take isl_printer *p, enum isl_dim_type type,
401 struct isl_print_space_data *data)
403 data->space = dim;
404 data->type = type;
405 return print_nested_tuple(p, dim, type, data, 0);
408 static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
409 __isl_keep isl_space *local_dim,
410 struct isl_print_space_data *data, int offset)
412 p = print_nested_tuple(p, local_dim, isl_dim_in, data, offset);
413 p = isl_printer_print_str(p, s_to[data->latex]);
414 p = print_nested_tuple(p, local_dim, isl_dim_out, data, offset);
416 return p;
419 __isl_give isl_printer *isl_print_space(__isl_keep isl_space *space,
420 __isl_take isl_printer *p, int rational,
421 struct isl_print_space_data *data)
423 if (rational && !data->latex)
424 p = isl_printer_print_str(p, "rat: ");
425 if (isl_space_is_params(space))
427 else if (isl_space_is_set(space))
428 p = print_tuple(space, p, isl_dim_set, data);
429 else {
430 p = print_tuple(space, p, isl_dim_in, data);
431 p = isl_printer_print_str(p, s_to[data->latex]);
432 p = print_tuple(space, p, isl_dim_out, data);
435 return p;
438 static __isl_give isl_printer *print_omega_parameters(__isl_keep isl_space *dim,
439 __isl_take isl_printer *p)
441 if (isl_space_dim(dim, isl_dim_param) == 0)
442 return p;
444 p = isl_printer_start_line(p);
445 p = isl_printer_print_str(p, "symbolic ");
446 p = print_var_list(p, dim, isl_dim_param);
447 p = isl_printer_print_str(p, ";");
448 p = isl_printer_end_line(p);
449 return p;
452 /* Does the inequality constraint following "i" in "bmap"
453 * have an opposite value for the same last coefficient?
454 * "last" is the position of the last coefficient of inequality "i".
455 * If the next constraint is a div constraint, then it is ignored
456 * since div constraints are not printed.
458 static int next_is_opposite(__isl_keep isl_basic_map *bmap, int i, int last)
460 unsigned total = isl_basic_map_total_dim(bmap);
461 unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
463 if (i + 1 >= bmap->n_ineq)
464 return 0;
465 if (isl_seq_last_non_zero(bmap->ineq[i + 1], 1 + total) != last)
466 return 0;
467 if (last >= o_div &&
468 isl_basic_map_is_div_constraint(bmap, bmap->ineq[i + 1],
469 last - o_div))
470 return 0;
471 return isl_int_abs_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]) &&
472 !isl_int_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]);
475 /* Return a string representation of the operator used when
476 * printing a constraint where the LHS is greater than or equal to the LHS
477 * (sign > 0) or smaller than or equal to the LHS (sign < 0).
478 * If "strict" is set, then return the strict version of the comparison
479 * operator.
481 static const char *constraint_op(int sign, int strict, int latex)
483 if (strict)
484 return sign < 0 ? "<" : ">";
485 if (sign < 0)
486 return s_le[latex];
487 else
488 return s_ge[latex];
491 /* Print one side of a constraint "c" from "bmap" to "p", with
492 * the variable names taken from "space" and the integer division definitions
493 * taken from "div".
494 * "last" is the position of the last non-zero coefficient.
495 * Let c' be the result of zeroing out this coefficient, then
496 * the partial constraint
498 * c' op
500 * is printed.
501 * "first_constraint" is set if this is the first constraint
502 * in the conjunction.
504 static __isl_give isl_printer *print_half_constraint(struct isl_basic_map *bmap,
505 __isl_keep isl_space *space, __isl_keep isl_mat *div,
506 __isl_take isl_printer *p, isl_int *c, int last, const char *op,
507 int first_constraint, int latex)
509 if (!first_constraint)
510 p = isl_printer_print_str(p, s_and[latex]);
512 isl_int_set_si(c[last], 0);
513 p = print_affine(bmap, space, div, p, c);
515 p = isl_printer_print_str(p, " ");
516 p = isl_printer_print_str(p, op);
517 p = isl_printer_print_str(p, " ");
519 return p;
522 /* Print a constraint "c" from "bmap" to "p", with the variable names
523 * taken from "space" and the integer division definitions taken from "div".
524 * "last" is the position of the last non-zero coefficient, which is
525 * moreover assumed to be negative.
526 * Let c' be the result of zeroing out this coefficient, then
527 * the constraint is printed in the form
529 * -c[last] op c'
531 * "first_constraint" is set if this is the first constraint
532 * in the conjunction.
534 static __isl_give isl_printer *print_constraint(struct isl_basic_map *bmap,
535 __isl_keep isl_space *space, __isl_keep isl_mat *div,
536 __isl_take isl_printer *p,
537 isl_int *c, int last, const char *op, int first_constraint, int latex)
539 if (!first_constraint)
540 p = isl_printer_print_str(p, s_and[latex]);
542 isl_int_abs(c[last], c[last]);
544 p = print_term(space, div, c[last], last, p, latex);
546 p = isl_printer_print_str(p, " ");
547 p = isl_printer_print_str(p, op);
548 p = isl_printer_print_str(p, " ");
550 isl_int_set_si(c[last], 0);
551 p = print_affine(bmap, space, div, p, c);
553 return p;
556 /* Print the constraints of "bmap" to "p".
557 * The names of the variables are taken from "space" and
558 * the integer division definitions are taken from "div".
559 * Div constraints are only printed in "dump" mode.
560 * The constraints are sorted prior to printing (except in "dump" mode).
562 * If x is the last variable with a non-zero coefficient,
563 * then a lower bound
565 * f - a x >= 0
567 * is printed as
569 * a x <= f
571 * while an upper bound
573 * f + a x >= 0
575 * is printed as
577 * a x >= -f
579 * If the next constraint has an opposite sign for the same last coefficient,
580 * then it is printed as
582 * f >= a x
584 * or
586 * -f <= a x
588 * instead. In fact, the "a x" part is not printed explicitly, but
589 * reused from the next constraint, which is therefore treated as
590 * a first constraint in the conjunction.
592 * If the constant term of "f" is -1, then "f" is replaced by "f + 1" and
593 * the comparison operator is replaced by the strict variant.
594 * Essentially, ">= 1" is replaced by "> 0".
596 static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
597 __isl_keep isl_space *space, __isl_keep isl_mat *div,
598 __isl_take isl_printer *p, int latex)
600 int i;
601 isl_vec *c = NULL;
602 int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
603 unsigned total = isl_basic_map_total_dim(bmap);
604 unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
605 int first = 1;
606 int dump;
608 if (!p)
609 return NULL;
610 bmap = isl_basic_map_copy(bmap);
611 dump = p->dump;
612 if (!dump)
613 bmap = isl_basic_map_sort_constraints(bmap);
614 if (!bmap)
615 goto error;
617 c = isl_vec_alloc(bmap->ctx, 1 + total);
618 if (!c)
619 goto error;
621 for (i = bmap->n_eq - 1; i >= 0; --i) {
622 int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total);
623 if (l < 0) {
624 if (i != bmap->n_eq - 1)
625 p = isl_printer_print_str(p, s_and[latex]);
626 p = isl_printer_print_str(p, "0 = 0");
627 continue;
629 if (isl_int_is_neg(bmap->eq[i][l]))
630 isl_seq_cpy(c->el, bmap->eq[i], 1 + total);
631 else
632 isl_seq_neg(c->el, bmap->eq[i], 1 + total);
633 p = print_constraint(bmap, space, div, p, c->el, l,
634 "=", first, latex);
635 first = 0;
637 for (i = 0; i < bmap->n_ineq; ++i) {
638 int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);
639 int strict;
640 int s;
641 const char *op;
642 if (l < 0)
643 continue;
644 if (!dump && l >= o_div &&
645 can_print_div_expr(p, div, l - o_div) &&
646 isl_basic_map_is_div_constraint(bmap, bmap->ineq[i],
647 l - o_div))
648 continue;
649 s = isl_int_sgn(bmap->ineq[i][l]);
650 strict = !rational && isl_int_is_negone(bmap->ineq[i][0]);
651 if (s < 0)
652 isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);
653 else
654 isl_seq_neg(c->el, bmap->ineq[i], 1 + total);
655 if (strict)
656 isl_int_set_si(c->el[0], 0);
657 if (!dump && next_is_opposite(bmap, i, l)) {
658 op = constraint_op(-s, strict, latex);
659 p = print_half_constraint(bmap, space, div, p, c->el, l,
660 op, first, latex);
661 first = 1;
662 } else {
663 op = constraint_op(s, strict, latex);
664 p = print_constraint(bmap, space, div, p, c->el, l,
665 op, first, latex);
666 first = 0;
670 isl_basic_map_free(bmap);
671 isl_vec_free(c);
673 return p;
674 error:
675 isl_basic_map_free(bmap);
676 isl_vec_free(c);
677 isl_printer_free(p);
678 return NULL;
681 static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
682 __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p)
684 int c;
686 if (!p || !div)
687 return isl_printer_free(p);
689 c = p->output_format == ISL_FORMAT_C;
690 p = isl_printer_print_str(p, c ? "floord(" : "floor((");
691 p = print_affine_of_len(dim, div, p,
692 div->row[pos] + 1, div->n_col - 1);
693 p = isl_printer_print_str(p, c ? ", " : ")/");
694 p = isl_printer_print_isl_int(p, div->row[pos][0]);
695 p = isl_printer_print_str(p, ")");
696 return p;
699 /* Print a comma separated list of div names, except those that have
700 * a definition that can be printed.
701 * If "print_defined_divs" is set, then those div names are printed
702 * as well, along with their definitions.
704 static __isl_give isl_printer *print_div_list(__isl_take isl_printer *p,
705 __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex,
706 int print_defined_divs)
708 int i;
709 int first = 1;
710 unsigned n_div;
712 if (!p || !space || !div)
713 return isl_printer_free(p);
715 n_div = isl_mat_rows(div);
717 for (i = 0; i < n_div; ++i) {
718 if (!print_defined_divs && can_print_div_expr(p, div, i))
719 continue;
720 if (!first)
721 p = isl_printer_print_str(p, ", ");
722 p = print_name(space, p, isl_dim_div, i, latex);
723 first = 0;
724 if (!can_print_div_expr(p, div, i))
725 continue;
726 p = isl_printer_print_str(p, " = ");
727 p = print_div(space, div, i, p);
730 return p;
733 /* Does printing an object with local variables described by "div"
734 * require an "exists" clause?
735 * That is, are there any local variables without an explicit representation?
736 * An exists clause is also needed in "dump" mode because
737 * explicit div representations are not printed inline in that case.
739 static isl_bool need_exists(__isl_keep isl_printer *p, __isl_keep isl_mat *div)
741 int i, n;
743 if (!p || !div)
744 return isl_bool_error;
745 n = isl_mat_rows(div);
746 if (n == 0)
747 return isl_bool_false;
748 if (p->dump)
749 return isl_bool_true;
750 for (i = 0; i < n; ++i)
751 if (!can_print_div_expr(p, div, i))
752 return isl_bool_true;
753 return isl_bool_false;
756 /* Print the start of an exists clause, i.e.,
758 * (exists variables:
760 * In dump mode, local variables with an explicit definition are printed
761 * as well because they will not be printed inline.
763 static __isl_give isl_printer *open_exists(__isl_take isl_printer *p,
764 __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex)
766 int dump;
768 if (!p)
769 return NULL;
771 dump = p->dump;
772 p = isl_printer_print_str(p, s_open_exists[latex]);
773 p = print_div_list(p, space, div, latex, dump);
774 p = isl_printer_print_str(p, ": ");
776 return p;
779 /* Print the constraints of "bmap" to "p".
780 * The names of the variables are taken from "space".
781 * "latex" is set if the constraints should be printed in LaTeX format.
782 * Do not print inline explicit div representations in "dump" mode.
784 static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
785 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
787 int dump;
788 isl_mat *div;
789 isl_bool exists;
791 if (!p)
792 return NULL;
793 dump = p->dump;
794 div = isl_basic_map_get_divs(bmap);
795 exists = need_exists(p, div);
796 if (exists >= 0 && exists)
797 p = open_exists(p, space, div, latex);
799 if (dump)
800 div = isl_mat_free(div);
801 p = print_constraints(bmap, space, div, p, latex);
802 isl_mat_free(div);
804 if (exists >= 0 && exists)
805 p = isl_printer_print_str(p, s_close_exists[latex]);
806 return p;
809 /* Print a colon followed by the constraints of "bmap"
810 * to "p", provided there are any constraints.
811 * The names of the variables are taken from "space".
812 * "latex" is set if the constraints should be printed in LaTeX format.
814 static __isl_give isl_printer *print_optional_disjunct(
815 __isl_keep isl_basic_map *bmap, __isl_keep isl_space *space,
816 __isl_take isl_printer *p, int latex)
818 if (isl_basic_map_plain_is_universe(bmap))
819 return p;
821 p = isl_printer_print_str(p, ": ");
822 p = print_disjunct(bmap, space, p, latex);
824 return p;
827 static __isl_give isl_printer *basic_map_print_omega(
828 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
830 p = isl_printer_print_str(p, "{ [");
831 p = print_var_list(p, bmap->dim, isl_dim_in);
832 p = isl_printer_print_str(p, "] -> [");
833 p = print_var_list(p, bmap->dim, isl_dim_out);
834 p = isl_printer_print_str(p, "] ");
835 p = print_optional_disjunct(bmap, bmap->dim, p, 0);
836 p = isl_printer_print_str(p, " }");
837 return p;
840 static __isl_give isl_printer *basic_set_print_omega(
841 __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
843 p = isl_printer_print_str(p, "{ [");
844 p = print_var_list(p, bset->dim, isl_dim_set);
845 p = isl_printer_print_str(p, "] ");
846 p = print_optional_disjunct(bset, bset->dim, p, 0);
847 p = isl_printer_print_str(p, " }");
848 return p;
851 static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map,
852 __isl_take isl_printer *p)
854 int i;
856 for (i = 0; i < map->n; ++i) {
857 if (i)
858 p = isl_printer_print_str(p, " union ");
859 p = basic_map_print_omega(map->p[i], p);
861 return p;
864 static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set,
865 __isl_take isl_printer *p)
867 int i;
869 for (i = 0; i < set->n; ++i) {
870 if (i)
871 p = isl_printer_print_str(p, " union ");
872 p = basic_set_print_omega(set->p[i], p);
874 return p;
877 /* Print the list of parameters in "space", followed by an arrow, to "p",
878 * if there are any parameters.
880 static __isl_give isl_printer *print_param_tuple(__isl_take isl_printer *p,
881 __isl_keep isl_space *space, struct isl_print_space_data *data)
883 if (!p || !space)
884 return isl_printer_free(p);
885 if (isl_space_dim(space, isl_dim_param) == 0)
886 return p;
888 p = print_tuple(space, p, isl_dim_param, data);
889 p = isl_printer_print_str(p, s_to[data->latex]);
891 return p;
894 static __isl_give isl_printer *isl_basic_map_print_isl(
895 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p,
896 int latex)
898 struct isl_print_space_data data = { .latex = latex };
899 int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
901 p = print_param_tuple(p, bmap->dim, &data);
902 p = isl_printer_print_str(p, "{ ");
903 p = isl_print_space(bmap->dim, p, rational, &data);
904 p = isl_printer_print_str(p, " : ");
905 p = print_disjunct(bmap, bmap->dim, p, latex);
906 p = isl_printer_print_str(p, " }");
907 return p;
910 /* Print the disjuncts of a map (or set) "map" to "p".
911 * The names of the variables are taken from "space".
912 * "latex" is set if the constraints should be printed in LaTeX format.
914 static __isl_give isl_printer *print_disjuncts_core(__isl_keep isl_map *map,
915 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
917 int i;
919 if (map->n == 0)
920 p = isl_printer_print_str(p, "1 = 0");
921 for (i = 0; i < map->n; ++i) {
922 if (i)
923 p = isl_printer_print_str(p, s_or[latex]);
924 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
925 p = isl_printer_print_str(p, "(");
926 p = print_disjunct(map->p[i], space, p, latex);
927 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
928 p = isl_printer_print_str(p, ")");
930 return p;
933 /* Print the disjuncts of a map (or set) "map" to "p".
934 * The names of the variables are taken from "space".
935 * "hull" describes constraints shared by all disjuncts of "map".
936 * "latex" is set if the constraints should be printed in LaTeX format.
938 * Print the disjuncts as a conjunction of "hull" and
939 * the result of removing the constraints of "hull" from "map".
940 * If this result turns out to be the universe, then simply print "hull".
942 static __isl_give isl_printer *print_disjuncts_in_hull(__isl_keep isl_map *map,
943 __isl_keep isl_space *space, __isl_take isl_basic_map *hull,
944 __isl_take isl_printer *p, int latex)
946 isl_bool is_universe;
948 p = print_disjunct(hull, space, p, latex);
949 map = isl_map_plain_gist_basic_map(isl_map_copy(map), hull);
950 is_universe = isl_map_plain_is_universe(map);
951 if (is_universe < 0)
952 goto error;
953 if (!is_universe) {
954 p = isl_printer_print_str(p, s_and[latex]);
955 p = isl_printer_print_str(p, "(");
956 p = print_disjuncts_core(map, space, p, latex);
957 p = isl_printer_print_str(p, ")");
959 isl_map_free(map);
961 return p;
962 error:
963 isl_map_free(map);
964 isl_printer_free(p);
965 return NULL;
968 /* Print the disjuncts of a map (or set) "map" to "p".
969 * The names of the variables are taken from "space".
970 * "latex" is set if the constraints should be printed in LaTeX format.
972 * If there are at least two disjuncts and "dump" mode is not turned out,
973 * check for any shared constraints among all disjuncts.
974 * If there are any, then print them separately in print_disjuncts_in_hull.
976 static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
977 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
979 if (isl_map_plain_is_universe(map))
980 return p;
982 p = isl_printer_print_str(p, s_such_that[latex]);
983 if (!p)
984 return NULL;
986 if (!p->dump && map->n >= 2) {
987 isl_basic_map *hull;
988 isl_bool is_universe;
990 hull = isl_map_plain_unshifted_simple_hull(isl_map_copy(map));
991 is_universe = isl_basic_map_plain_is_universe(hull);
992 if (is_universe < 0)
993 p = isl_printer_free(p);
994 else if (!is_universe)
995 return print_disjuncts_in_hull(map, space, hull,
996 p, latex);
997 isl_basic_map_free(hull);
1000 return print_disjuncts_core(map, space, p, latex);
1003 /* Print the disjuncts of a map (or set).
1004 * The names of the variables are taken from "space".
1005 * "latex" is set if the constraints should be printed in LaTeX format.
1007 * If the map turns out to be a universal parameter domain, then
1008 * we need to print the colon. Otherwise, the output looks identical
1009 * to the empty set.
1011 static __isl_give isl_printer *print_disjuncts_map(__isl_keep isl_map *map,
1012 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
1014 if (isl_map_plain_is_universe(map) && isl_space_is_params(map->dim))
1015 return isl_printer_print_str(p, s_such_that[latex]);
1016 else
1017 return print_disjuncts(map, space, p, latex);
1020 struct isl_aff_split {
1021 isl_basic_map *aff;
1022 isl_map *map;
1025 static void free_split(__isl_take struct isl_aff_split *split, int n)
1027 int i;
1029 if (!split)
1030 return;
1032 for (i = 0; i < n; ++i) {
1033 isl_basic_map_free(split[i].aff);
1034 isl_map_free(split[i].map);
1037 free(split);
1040 static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap)
1042 int i, j;
1043 unsigned nparam, n_in, n_out, total;
1045 bmap = isl_basic_map_cow(bmap);
1046 if (!bmap)
1047 return NULL;
1048 if (isl_basic_map_free_inequality(bmap, bmap->n_ineq) < 0)
1049 goto error;
1051 nparam = isl_basic_map_dim(bmap, isl_dim_param);
1052 n_in = isl_basic_map_dim(bmap, isl_dim_in);
1053 n_out = isl_basic_map_dim(bmap, isl_dim_out);
1054 total = isl_basic_map_dim(bmap, isl_dim_all);
1055 for (i = bmap->n_eq - 1; i >= 0; --i) {
1056 j = isl_seq_last_non_zero(bmap->eq[i] + 1, total);
1057 if (j >= nparam && j < nparam + n_in + n_out &&
1058 (isl_int_is_one(bmap->eq[i][1 + j]) ||
1059 isl_int_is_negone(bmap->eq[i][1 + j])))
1060 continue;
1061 if (isl_basic_map_drop_equality(bmap, i) < 0)
1062 goto error;
1065 bmap = isl_basic_map_finalize(bmap);
1067 return bmap;
1068 error:
1069 isl_basic_map_free(bmap);
1070 return NULL;
1073 static int aff_split_cmp(const void *p1, const void *p2, void *user)
1075 const struct isl_aff_split *s1, *s2;
1076 s1 = (const struct isl_aff_split *) p1;
1077 s2 = (const struct isl_aff_split *) p2;
1079 return isl_basic_map_plain_cmp(s1->aff, s2->aff);
1082 static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap,
1083 __isl_keep isl_basic_map *aff)
1085 int i, j;
1086 unsigned total;
1088 if (!bmap || !aff)
1089 goto error;
1091 total = isl_space_dim(bmap->dim, isl_dim_all);
1093 for (i = bmap->n_eq - 1; i >= 0; --i) {
1094 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + total,
1095 bmap->n_div) != -1)
1096 continue;
1097 for (j = 0; j < aff->n_eq; ++j) {
1098 if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + total) &&
1099 !isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + total))
1100 continue;
1101 if (isl_basic_map_drop_equality(bmap, i) < 0)
1102 goto error;
1103 break;
1107 return bmap;
1108 error:
1109 isl_basic_map_free(bmap);
1110 return NULL;
1113 static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map)
1115 int i, n;
1116 struct isl_aff_split *split;
1117 isl_ctx *ctx;
1119 ctx = isl_map_get_ctx(map);
1120 split = isl_calloc_array(ctx, struct isl_aff_split, map->n);
1121 if (!split)
1122 return NULL;
1124 for (i = 0; i < map->n; ++i) {
1125 isl_basic_map *bmap;
1126 split[i].aff = get_aff(isl_basic_map_copy(map->p[i]));
1127 bmap = isl_basic_map_copy(map->p[i]);
1128 bmap = isl_basic_map_cow(bmap);
1129 bmap = drop_aff(bmap, split[i].aff);
1130 split[i].map = isl_map_from_basic_map(bmap);
1131 if (!split[i].aff || !split[i].map)
1132 goto error;
1135 if (isl_sort(split, map->n, sizeof(struct isl_aff_split),
1136 &aff_split_cmp, NULL) < 0)
1137 goto error;
1139 n = map->n;
1140 for (i = n - 1; i >= 1; --i) {
1141 if (!isl_basic_map_plain_is_equal(split[i - 1].aff,
1142 split[i].aff))
1143 continue;
1144 isl_basic_map_free(split[i].aff);
1145 split[i - 1].map = isl_map_union(split[i - 1].map,
1146 split[i].map);
1147 if (i != n - 1)
1148 split[i] = split[n - 1];
1149 split[n - 1].aff = NULL;
1150 split[n - 1].map = NULL;
1151 --n;
1154 return split;
1155 error:
1156 free_split(split, map->n);
1157 return NULL;
1160 static int defining_equality(__isl_keep isl_basic_map *eq,
1161 __isl_keep isl_space *dim, enum isl_dim_type type, int pos)
1163 int i;
1164 unsigned total;
1166 if (!eq)
1167 return -1;
1169 pos += isl_space_offset(dim, type);
1170 total = isl_basic_map_total_dim(eq);
1172 for (i = 0; i < eq->n_eq; ++i) {
1173 if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos)
1174 continue;
1175 if (isl_int_is_one(eq->eq[i][1 + pos]))
1176 isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total);
1177 return i;
1180 return -1;
1183 /* Print dimension "pos" of data->space to "p".
1185 * data->user is assumed to be an isl_basic_map keeping track of equalities.
1187 * If the current dimension is defined by these equalities, then print
1188 * the corresponding expression, assigned to the name of the dimension
1189 * if there is any. Otherwise, print the name of the dimension.
1191 static __isl_give isl_printer *print_dim_eq(__isl_take isl_printer *p,
1192 struct isl_print_space_data *data, unsigned pos)
1194 isl_basic_map *eq = data->user;
1195 int j;
1197 j = defining_equality(eq, data->space, data->type, pos);
1198 if (j >= 0) {
1199 if (isl_space_has_dim_name(data->space, data->type, pos)) {
1200 p = print_name(data->space, p, data->type, pos,
1201 data->latex);
1202 p = isl_printer_print_str(p, " = ");
1204 pos += 1 + isl_space_offset(data->space, data->type);
1205 p = print_affine_of_len(data->space, NULL, p, eq->eq[j], pos);
1206 } else {
1207 p = print_name(data->space, p, data->type, pos, data->latex);
1210 return p;
1213 static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p,
1214 struct isl_aff_split *split, int n, __isl_keep isl_space *space)
1216 struct isl_print_space_data data = { 0 };
1217 int i;
1218 int rational;
1220 data.print_dim = &print_dim_eq;
1221 for (i = 0; i < n; ++i) {
1222 if (!split[i].map)
1223 break;
1224 rational = split[i].map->n > 0 &&
1225 ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL);
1226 if (i)
1227 p = isl_printer_print_str(p, "; ");
1228 data.user = split[i].aff;
1229 p = isl_print_space(space, p, rational, &data);
1230 p = print_disjuncts_map(split[i].map, space, p, 0);
1233 return p;
1236 static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map,
1237 __isl_take isl_printer *p)
1239 struct isl_print_space_data data = { 0 };
1240 struct isl_aff_split *split = NULL;
1241 int rational;
1243 if (!p || !map)
1244 return isl_printer_free(p);
1245 if (!p->dump && map->n > 0)
1246 split = split_aff(map);
1247 if (split) {
1248 p = print_split_map(p, split, map->n, map->dim);
1249 } else {
1250 rational = map->n > 0 &&
1251 ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL);
1252 p = isl_print_space(map->dim, p, rational, &data);
1253 p = print_disjuncts_map(map, map->dim, p, 0);
1255 free_split(split, map->n);
1256 return p;
1259 static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,
1260 __isl_take isl_printer *p)
1262 struct isl_print_space_data data = { 0 };
1264 p = print_param_tuple(p, map->dim, &data);
1265 p = isl_printer_print_str(p, s_open_set[0]);
1266 p = isl_map_print_isl_body(map, p);
1267 p = isl_printer_print_str(p, s_close_set[0]);
1268 return p;
1271 static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map,
1272 __isl_take isl_printer *p, __isl_keep isl_basic_map *aff)
1274 struct isl_print_space_data data = { 0 };
1276 data.latex = 1;
1277 p = print_param_tuple(p, map->dim, &data);
1278 p = isl_printer_print_str(p, s_open_set[1]);
1279 data.print_dim = &print_dim_eq;
1280 data.user = aff;
1281 p = isl_print_space(map->dim, p, 0, &data);
1282 p = print_disjuncts_map(map, map->dim, p, 1);
1283 p = isl_printer_print_str(p, s_close_set[1]);
1285 return p;
1288 static __isl_give isl_printer *isl_map_print_latex(__isl_keep isl_map *map,
1289 __isl_take isl_printer *p)
1291 int i;
1292 struct isl_aff_split *split = NULL;
1294 if (map->n > 0)
1295 split = split_aff(map);
1297 if (!split)
1298 return print_latex_map(map, p, NULL);
1300 for (i = 0; i < map->n; ++i) {
1301 if (!split[i].map)
1302 break;
1303 if (i)
1304 p = isl_printer_print_str(p, " \\cup ");
1305 p = print_latex_map(split[i].map, p, split[i].aff);
1308 free_split(split, map->n);
1309 return p;
1312 __isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p,
1313 __isl_keep isl_basic_map *bmap)
1315 if (!p || !bmap)
1316 goto error;
1317 if (p->output_format == ISL_FORMAT_ISL)
1318 return isl_basic_map_print_isl(bmap, p, 0);
1319 else if (p->output_format == ISL_FORMAT_OMEGA)
1320 return basic_map_print_omega(bmap, p);
1321 isl_assert(bmap->ctx, 0, goto error);
1322 error:
1323 isl_printer_free(p);
1324 return NULL;
1327 __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,
1328 __isl_keep isl_basic_set *bset)
1330 if (!p || !bset)
1331 goto error;
1333 if (p->output_format == ISL_FORMAT_ISL)
1334 return isl_basic_map_print_isl(bset, p, 0);
1335 else if (p->output_format == ISL_FORMAT_POLYLIB)
1336 return isl_basic_set_print_polylib(bset, p, 0);
1337 else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1338 return isl_basic_set_print_polylib(bset, p, 1);
1339 else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)
1340 return bset_print_constraints_polylib(bset, p);
1341 else if (p->output_format == ISL_FORMAT_OMEGA)
1342 return basic_set_print_omega(bset, p);
1343 isl_assert(p->ctx, 0, goto error);
1344 error:
1345 isl_printer_free(p);
1346 return NULL;
1349 __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,
1350 __isl_keep isl_set *set)
1352 if (!p || !set)
1353 goto error;
1354 if (p->output_format == ISL_FORMAT_ISL)
1355 return isl_map_print_isl(set_to_map(set), p);
1356 else if (p->output_format == ISL_FORMAT_POLYLIB)
1357 return isl_set_print_polylib(set, p, 0);
1358 else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1359 return isl_set_print_polylib(set, p, 1);
1360 else if (p->output_format == ISL_FORMAT_OMEGA)
1361 return isl_set_print_omega(set, p);
1362 else if (p->output_format == ISL_FORMAT_LATEX)
1363 return isl_map_print_latex(set_to_map(set), p);
1364 isl_assert(set->ctx, 0, goto error);
1365 error:
1366 isl_printer_free(p);
1367 return NULL;
1370 __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
1371 __isl_keep isl_map *map)
1373 if (!p || !map)
1374 goto error;
1376 if (p->output_format == ISL_FORMAT_ISL)
1377 return isl_map_print_isl(map, p);
1378 else if (p->output_format == ISL_FORMAT_POLYLIB)
1379 return isl_map_print_polylib(map, p, 0);
1380 else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1381 return isl_map_print_polylib(map, p, 1);
1382 else if (p->output_format == ISL_FORMAT_OMEGA)
1383 return isl_map_print_omega(map, p);
1384 else if (p->output_format == ISL_FORMAT_LATEX)
1385 return isl_map_print_latex(map, p);
1386 isl_assert(map->ctx, 0, goto error);
1387 error:
1388 isl_printer_free(p);
1389 return NULL;
1392 struct isl_union_print_data {
1393 isl_printer *p;
1394 int first;
1397 static isl_stat print_map_body(__isl_take isl_map *map, void *user)
1399 struct isl_union_print_data *data;
1400 data = (struct isl_union_print_data *)user;
1402 if (!data->first)
1403 data->p = isl_printer_print_str(data->p, "; ");
1404 data->first = 0;
1406 data->p = isl_map_print_isl_body(map, data->p);
1407 isl_map_free(map);
1409 return isl_stat_ok;
1412 static __isl_give isl_printer *isl_union_map_print_isl(
1413 __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
1415 struct isl_union_print_data data;
1416 struct isl_print_space_data space_data = { 0 };
1417 isl_space *space;
1419 space = isl_union_map_get_space(umap);
1420 p = print_param_tuple(p, space, &space_data);
1421 isl_space_free(space);
1422 p = isl_printer_print_str(p, s_open_set[0]);
1423 data.p = p;
1424 data.first = 1;
1425 isl_union_map_foreach_map(umap, &print_map_body, &data);
1426 p = data.p;
1427 p = isl_printer_print_str(p, s_close_set[0]);
1428 return p;
1431 static isl_stat print_latex_map_body(__isl_take isl_map *map, void *user)
1433 struct isl_union_print_data *data;
1434 data = (struct isl_union_print_data *)user;
1436 if (!data->first)
1437 data->p = isl_printer_print_str(data->p, " \\cup ");
1438 data->first = 0;
1440 data->p = isl_map_print_latex(map, data->p);
1441 isl_map_free(map);
1443 return isl_stat_ok;
1446 static __isl_give isl_printer *isl_union_map_print_latex(
1447 __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
1449 struct isl_union_print_data data = { p, 1 };
1450 isl_union_map_foreach_map(umap, &print_latex_map_body, &data);
1451 p = data.p;
1452 return p;
1455 __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p,
1456 __isl_keep isl_union_map *umap)
1458 if (!p || !umap)
1459 goto error;
1461 if (p->output_format == ISL_FORMAT_ISL)
1462 return isl_union_map_print_isl(umap, p);
1463 if (p->output_format == ISL_FORMAT_LATEX)
1464 return isl_union_map_print_latex(umap, p);
1466 isl_die(p->ctx, isl_error_invalid,
1467 "invalid output format for isl_union_map", goto error);
1468 error:
1469 isl_printer_free(p);
1470 return NULL;
1473 __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
1474 __isl_keep isl_union_set *uset)
1476 if (!p || !uset)
1477 goto error;
1479 if (p->output_format == ISL_FORMAT_ISL)
1480 return isl_union_map_print_isl((isl_union_map *)uset, p);
1481 if (p->output_format == ISL_FORMAT_LATEX)
1482 return isl_union_map_print_latex((isl_union_map *)uset, p);
1484 isl_die(p->ctx, isl_error_invalid,
1485 "invalid output format for isl_union_set", goto error);
1486 error:
1487 isl_printer_free(p);
1488 return NULL;
1491 static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec)
1493 int i;
1494 int n;
1496 for (i = 0, n = 0; i < rec->n; ++i)
1497 if (!isl_upoly_is_zero(rec->p[i]))
1498 ++n;
1500 return n;
1503 static __isl_give isl_printer *upoly_print_cst(__isl_keep struct isl_upoly *up,
1504 __isl_take isl_printer *p, int first)
1506 struct isl_upoly_cst *cst;
1507 int neg;
1509 cst = isl_upoly_as_cst(up);
1510 if (!cst)
1511 goto error;
1512 neg = !first && isl_int_is_neg(cst->n);
1513 if (!first)
1514 p = isl_printer_print_str(p, neg ? " - " : " + ");
1515 if (neg)
1516 isl_int_neg(cst->n, cst->n);
1517 if (isl_int_is_zero(cst->d)) {
1518 int sgn = isl_int_sgn(cst->n);
1519 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
1520 sgn == 0 ? "NaN" : "infty");
1521 } else
1522 p = isl_printer_print_isl_int(p, cst->n);
1523 if (neg)
1524 isl_int_neg(cst->n, cst->n);
1525 if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) {
1526 p = isl_printer_print_str(p, "/");
1527 p = isl_printer_print_isl_int(p, cst->d);
1529 return p;
1530 error:
1531 isl_printer_free(p);
1532 return NULL;
1535 static __isl_give isl_printer *print_base(__isl_take isl_printer *p,
1536 __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var)
1538 unsigned total;
1540 total = isl_space_dim(dim, isl_dim_all);
1541 if (var < total)
1542 p = print_term(dim, NULL, dim->ctx->one, 1 + var, p, 0);
1543 else
1544 p = print_div(dim, div, var - total, p);
1545 return p;
1548 static __isl_give isl_printer *print_pow(__isl_take isl_printer *p,
1549 __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var, int exp)
1551 p = print_base(p, dim, div, var);
1552 if (exp == 1)
1553 return p;
1554 if (p->output_format == ISL_FORMAT_C) {
1555 int i;
1556 for (i = 1; i < exp; ++i) {
1557 p = isl_printer_print_str(p, "*");
1558 p = print_base(p, dim, div, var);
1560 } else {
1561 p = isl_printer_print_str(p, "^");
1562 p = isl_printer_print_int(p, exp);
1564 return p;
1567 static __isl_give isl_printer *upoly_print(__isl_keep struct isl_upoly *up,
1568 __isl_keep isl_space *dim, __isl_keep isl_mat *div,
1569 __isl_take isl_printer *p, int outer)
1571 int i, n, first, print_parens;
1572 struct isl_upoly_rec *rec;
1574 if (!p || !up || !dim || !div)
1575 goto error;
1577 if (isl_upoly_is_cst(up))
1578 return upoly_print_cst(up, p, 1);
1580 rec = isl_upoly_as_rec(up);
1581 if (!rec)
1582 goto error;
1583 n = upoly_rec_n_non_zero(rec);
1584 print_parens = n > 1 ||
1585 (outer && rec->up.var >= isl_space_dim(dim, isl_dim_all));
1586 if (print_parens)
1587 p = isl_printer_print_str(p, "(");
1588 for (i = 0, first = 1; i < rec->n; ++i) {
1589 if (isl_upoly_is_zero(rec->p[i]))
1590 continue;
1591 if (isl_upoly_is_negone(rec->p[i])) {
1592 if (!i)
1593 p = isl_printer_print_str(p, "-1");
1594 else if (first)
1595 p = isl_printer_print_str(p, "-");
1596 else
1597 p = isl_printer_print_str(p, " - ");
1598 } else if (isl_upoly_is_cst(rec->p[i]) &&
1599 !isl_upoly_is_one(rec->p[i]))
1600 p = upoly_print_cst(rec->p[i], p, first);
1601 else {
1602 if (!first)
1603 p = isl_printer_print_str(p, " + ");
1604 if (i == 0 || !isl_upoly_is_one(rec->p[i]))
1605 p = upoly_print(rec->p[i], dim, div, p, 0);
1607 first = 0;
1608 if (i == 0)
1609 continue;
1610 if (!isl_upoly_is_one(rec->p[i]) &&
1611 !isl_upoly_is_negone(rec->p[i]))
1612 p = isl_printer_print_str(p, " * ");
1613 p = print_pow(p, dim, div, rec->up.var, i);
1615 if (print_parens)
1616 p = isl_printer_print_str(p, ")");
1617 return p;
1618 error:
1619 isl_printer_free(p);
1620 return NULL;
1623 static __isl_give isl_printer *print_qpolynomial(__isl_take isl_printer *p,
1624 __isl_keep isl_qpolynomial *qp)
1626 if (!p || !qp)
1627 goto error;
1628 p = upoly_print(qp->upoly, qp->dim, qp->div, p, 1);
1629 return p;
1630 error:
1631 isl_printer_free(p);
1632 return NULL;
1635 static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p,
1636 __isl_keep isl_qpolynomial *qp)
1638 struct isl_print_space_data data = { 0 };
1640 if (!p || !qp)
1641 goto error;
1643 p = print_param_tuple(p, qp->dim, &data);
1644 p = isl_printer_print_str(p, "{ ");
1645 if (!isl_space_is_params(qp->dim)) {
1646 p = isl_print_space(qp->dim, p, 0, &data);
1647 p = isl_printer_print_str(p, " -> ");
1649 p = print_qpolynomial(p, qp);
1650 p = isl_printer_print_str(p, " }");
1651 return p;
1652 error:
1653 isl_printer_free(p);
1654 return NULL;
1657 static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p,
1658 __isl_keep isl_space *dim, __isl_keep isl_qpolynomial *qp)
1660 isl_int den;
1662 isl_int_init(den);
1663 isl_qpolynomial_get_den(qp, &den);
1664 if (!isl_int_is_one(den)) {
1665 isl_qpolynomial *f;
1666 p = isl_printer_print_str(p, "(");
1667 qp = isl_qpolynomial_copy(qp);
1668 f = isl_qpolynomial_rat_cst_on_domain(isl_space_copy(qp->dim),
1669 den, qp->dim->ctx->one);
1670 qp = isl_qpolynomial_mul(qp, f);
1672 if (qp)
1673 p = upoly_print(qp->upoly, dim, qp->div, p, 0);
1674 else
1675 p = isl_printer_free(p);
1676 if (!isl_int_is_one(den)) {
1677 p = isl_printer_print_str(p, ")/");
1678 p = isl_printer_print_isl_int(p, den);
1679 isl_qpolynomial_free(qp);
1681 isl_int_clear(den);
1682 return p;
1685 __isl_give isl_printer *isl_printer_print_qpolynomial(
1686 __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp)
1688 if (!p || !qp)
1689 goto error;
1691 if (p->output_format == ISL_FORMAT_ISL)
1692 return print_qpolynomial_isl(p, qp);
1693 else if (p->output_format == ISL_FORMAT_C)
1694 return print_qpolynomial_c(p, qp->dim, qp);
1695 else
1696 isl_die(qp->dim->ctx, isl_error_unsupported,
1697 "output format not supported for isl_qpolynomials",
1698 goto error);
1699 error:
1700 isl_printer_free(p);
1701 return NULL;
1704 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
1705 unsigned output_format)
1707 isl_printer *p;
1709 if (!qp)
1710 return;
1712 isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1713 p = isl_printer_to_file(qp->dim->ctx, out);
1714 p = isl_printer_print_qpolynomial(p, qp);
1715 isl_printer_free(p);
1718 static __isl_give isl_printer *qpolynomial_fold_print(
1719 __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
1721 int i;
1723 if (fold->type == isl_fold_min)
1724 p = isl_printer_print_str(p, "min");
1725 else if (fold->type == isl_fold_max)
1726 p = isl_printer_print_str(p, "max");
1727 p = isl_printer_print_str(p, "(");
1728 for (i = 0; i < fold->n; ++i) {
1729 if (i)
1730 p = isl_printer_print_str(p, ", ");
1731 p = print_qpolynomial(p, fold->qp[i]);
1733 p = isl_printer_print_str(p, ")");
1734 return p;
1737 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
1738 FILE *out, unsigned output_format)
1740 isl_printer *p;
1742 if (!fold)
1743 return;
1745 isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1747 p = isl_printer_to_file(fold->dim->ctx, out);
1748 p = isl_printer_print_qpolynomial_fold(p, fold);
1750 isl_printer_free(p);
1753 static __isl_give isl_printer *isl_pwqp_print_isl_body(
1754 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1756 struct isl_print_space_data data = { 0 };
1757 int i = 0;
1759 for (i = 0; i < pwqp->n; ++i) {
1760 isl_space *space;
1762 if (i)
1763 p = isl_printer_print_str(p, "; ");
1764 space = isl_qpolynomial_get_domain_space(pwqp->p[i].qp);
1765 if (!isl_space_is_params(space)) {
1766 p = isl_print_space(space, p, 0, &data);
1767 p = isl_printer_print_str(p, " -> ");
1769 p = print_qpolynomial(p, pwqp->p[i].qp);
1770 p = print_disjuncts(set_to_map(pwqp->p[i].set), space, p, 0);
1771 isl_space_free(space);
1774 return p;
1777 static __isl_give isl_printer *print_pw_qpolynomial_isl(
1778 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1780 struct isl_print_space_data data = { 0 };
1782 if (!p || !pwqp)
1783 goto error;
1785 p = print_param_tuple(p, pwqp->dim, &data);
1786 p = isl_printer_print_str(p, "{ ");
1787 if (pwqp->n == 0) {
1788 if (!isl_space_is_set(pwqp->dim)) {
1789 p = print_tuple(pwqp->dim, p, isl_dim_in, &data);
1790 p = isl_printer_print_str(p, " -> ");
1792 p = isl_printer_print_str(p, "0");
1794 p = isl_pwqp_print_isl_body(p, pwqp);
1795 p = isl_printer_print_str(p, " }");
1796 return p;
1797 error:
1798 isl_printer_free(p);
1799 return NULL;
1802 void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
1803 unsigned output_format)
1805 isl_printer *p;
1807 if (!pwqp)
1808 return;
1810 p = isl_printer_to_file(pwqp->dim->ctx, out);
1811 p = isl_printer_set_output_format(p, output_format);
1812 p = isl_printer_print_pw_qpolynomial(p, pwqp);
1814 isl_printer_free(p);
1817 static __isl_give isl_printer *isl_pwf_print_isl_body(
1818 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1820 struct isl_print_space_data data = { 0 };
1821 int i = 0;
1823 for (i = 0; i < pwf->n; ++i) {
1824 isl_space *space;
1826 if (i)
1827 p = isl_printer_print_str(p, "; ");
1828 space = isl_qpolynomial_fold_get_domain_space(pwf->p[i].fold);
1829 if (!isl_space_is_params(space)) {
1830 p = isl_print_space(space, p, 0, &data);
1831 p = isl_printer_print_str(p, " -> ");
1833 p = qpolynomial_fold_print(pwf->p[i].fold, p);
1834 p = print_disjuncts(set_to_map(pwf->p[i].set), space, p, 0);
1835 isl_space_free(space);
1838 return p;
1841 static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(
1842 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1844 struct isl_print_space_data data = { 0 };
1846 p = print_param_tuple(p, pwf->dim, &data);
1847 p = isl_printer_print_str(p, "{ ");
1848 if (pwf->n == 0) {
1849 if (!isl_space_is_set(pwf->dim)) {
1850 p = print_tuple(pwf->dim, p, isl_dim_in, &data);
1851 p = isl_printer_print_str(p, " -> ");
1853 p = isl_printer_print_str(p, "0");
1855 p = isl_pwf_print_isl_body(p, pwf);
1856 p = isl_printer_print_str(p, " }");
1857 return p;
1860 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1861 __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c);
1863 static __isl_give isl_printer *print_name_c(__isl_take isl_printer *p,
1864 __isl_keep isl_space *dim,
1865 __isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos)
1867 if (type == isl_dim_div) {
1868 p = isl_printer_print_str(p, "floord(");
1869 p = print_affine_c(p, dim, bset, bset->div[pos] + 1);
1870 p = isl_printer_print_str(p, ", ");
1871 p = isl_printer_print_isl_int(p, bset->div[pos][0]);
1872 p = isl_printer_print_str(p, ")");
1873 } else {
1874 const char *name;
1876 name = isl_space_get_dim_name(dim, type, pos);
1877 if (!name)
1878 name = "UNNAMED";
1879 p = isl_printer_print_str(p, name);
1881 return p;
1884 static __isl_give isl_printer *print_term_c(__isl_take isl_printer *p,
1885 __isl_keep isl_space *dim,
1886 __isl_keep isl_basic_set *bset, isl_int c, unsigned pos)
1888 enum isl_dim_type type;
1890 if (pos == 0)
1891 return isl_printer_print_isl_int(p, c);
1893 if (isl_int_is_one(c))
1895 else if (isl_int_is_negone(c))
1896 p = isl_printer_print_str(p, "-");
1897 else {
1898 p = isl_printer_print_isl_int(p, c);
1899 p = isl_printer_print_str(p, "*");
1901 type = pos2type(dim, &pos);
1902 p = print_name_c(p, dim, bset, type, pos);
1903 return p;
1906 static __isl_give isl_printer *print_partial_affine_c(__isl_take isl_printer *p,
1907 __isl_keep isl_space *dim,
1908 __isl_keep isl_basic_set *bset, isl_int *c, unsigned len)
1910 int i;
1911 int first;
1913 for (i = 0, first = 1; i < len; ++i) {
1914 int flip = 0;
1915 if (isl_int_is_zero(c[i]))
1916 continue;
1917 if (!first) {
1918 if (isl_int_is_neg(c[i])) {
1919 flip = 1;
1920 isl_int_neg(c[i], c[i]);
1921 p = isl_printer_print_str(p, " - ");
1922 } else
1923 p = isl_printer_print_str(p, " + ");
1925 first = 0;
1926 p = print_term_c(p, dim, bset, c[i], i);
1927 if (flip)
1928 isl_int_neg(c[i], c[i]);
1930 if (first)
1931 p = isl_printer_print_str(p, "0");
1932 return p;
1935 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1936 __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c)
1938 unsigned len = 1 + isl_basic_set_total_dim(bset);
1939 return print_partial_affine_c(p, dim, bset, c, len);
1942 /* We skip the constraint if it is implied by the div expression.
1944 * *first indicates whether this is the first constraint in the conjunction and
1945 * is updated if the constraint is actually printed.
1947 static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,
1948 __isl_keep isl_space *dim,
1949 __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int *first)
1951 unsigned o_div;
1952 unsigned n_div;
1953 int div;
1955 o_div = isl_basic_set_offset(bset, isl_dim_div);
1956 n_div = isl_basic_set_dim(bset, isl_dim_div);
1957 div = isl_seq_last_non_zero(c + o_div, n_div);
1958 if (div >= 0 && isl_basic_set_is_div_constraint(bset, c, div))
1959 return p;
1961 if (!*first)
1962 p = isl_printer_print_str(p, " && ");
1964 p = print_affine_c(p, dim, bset, c);
1965 p = isl_printer_print_str(p, " ");
1966 p = isl_printer_print_str(p, op);
1967 p = isl_printer_print_str(p, " 0");
1969 *first = 0;
1971 return p;
1974 static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,
1975 __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset)
1977 int i, j;
1978 int first = 1;
1979 unsigned n_div = isl_basic_set_dim(bset, isl_dim_div);
1980 unsigned total = isl_basic_set_total_dim(bset) - n_div;
1982 for (i = 0; i < bset->n_eq; ++i) {
1983 j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div);
1984 if (j < 0)
1985 p = print_constraint_c(p, dim, bset,
1986 bset->eq[i], "==", &first);
1987 else {
1988 if (i)
1989 p = isl_printer_print_str(p, " && ");
1990 p = isl_printer_print_str(p, "(");
1991 p = print_partial_affine_c(p, dim, bset, bset->eq[i],
1992 1 + total + j);
1993 p = isl_printer_print_str(p, ") % ");
1994 p = isl_printer_print_isl_int(p,
1995 bset->eq[i][1 + total + j]);
1996 p = isl_printer_print_str(p, " == 0");
1997 first = 0;
2000 for (i = 0; i < bset->n_ineq; ++i)
2001 p = print_constraint_c(p, dim, bset, bset->ineq[i], ">=",
2002 &first);
2003 return p;
2006 static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,
2007 __isl_keep isl_space *dim, __isl_keep isl_set *set)
2009 int i;
2011 if (!set)
2012 return isl_printer_free(p);
2014 if (set->n == 0)
2015 p = isl_printer_print_str(p, "0");
2017 for (i = 0; i < set->n; ++i) {
2018 if (i)
2019 p = isl_printer_print_str(p, " || ");
2020 if (set->n > 1)
2021 p = isl_printer_print_str(p, "(");
2022 p = print_basic_set_c(p, dim, set->p[i]);
2023 if (set->n > 1)
2024 p = isl_printer_print_str(p, ")");
2026 return p;
2029 static __isl_give isl_printer *print_pw_qpolynomial_c(
2030 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
2032 int i;
2034 if (pwqp->n == 1 && isl_set_plain_is_universe(pwqp->p[0].set))
2035 return print_qpolynomial_c(p, pwqp->dim, pwqp->p[0].qp);
2037 for (i = 0; i < pwqp->n; ++i) {
2038 p = isl_printer_print_str(p, "(");
2039 p = print_set_c(p, pwqp->dim, pwqp->p[i].set);
2040 p = isl_printer_print_str(p, ") ? (");
2041 p = print_qpolynomial_c(p, pwqp->dim, pwqp->p[i].qp);
2042 p = isl_printer_print_str(p, ") : ");
2045 p = isl_printer_print_str(p, "0");
2046 return p;
2049 __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
2050 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
2052 if (!p || !pwqp)
2053 goto error;
2055 if (p->output_format == ISL_FORMAT_ISL)
2056 return print_pw_qpolynomial_isl(p, pwqp);
2057 else if (p->output_format == ISL_FORMAT_C)
2058 return print_pw_qpolynomial_c(p, pwqp);
2059 isl_assert(p->ctx, 0, goto error);
2060 error:
2061 isl_printer_free(p);
2062 return NULL;
2065 static isl_stat print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user)
2067 struct isl_union_print_data *data;
2068 data = (struct isl_union_print_data *)user;
2070 if (!data->first)
2071 data->p = isl_printer_print_str(data->p, "; ");
2072 data->first = 0;
2074 data->p = isl_pwqp_print_isl_body(data->p, pwqp);
2075 isl_pw_qpolynomial_free(pwqp);
2077 return isl_stat_ok;
2080 static __isl_give isl_printer *print_union_pw_qpolynomial_isl(
2081 __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
2083 struct isl_union_print_data data;
2084 struct isl_print_space_data space_data = { 0 };
2085 isl_space *space;
2087 space = isl_union_pw_qpolynomial_get_space(upwqp);
2088 p = print_param_tuple(p, space, &space_data);
2089 isl_space_free(space);
2090 p = isl_printer_print_str(p, "{ ");
2091 data.p = p;
2092 data.first = 1;
2093 isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body,
2094 &data);
2095 p = data.p;
2096 p = isl_printer_print_str(p, " }");
2097 return p;
2100 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial(
2101 __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
2103 if (!p || !upwqp)
2104 goto error;
2106 if (p->output_format == ISL_FORMAT_ISL)
2107 return print_union_pw_qpolynomial_isl(p, upwqp);
2108 isl_die(p->ctx, isl_error_invalid,
2109 "invalid output format for isl_union_pw_qpolynomial",
2110 goto error);
2111 error:
2112 isl_printer_free(p);
2113 return NULL;
2116 static __isl_give isl_printer *print_qpolynomial_fold_c(
2117 __isl_take isl_printer *p, __isl_keep isl_space *dim,
2118 __isl_keep isl_qpolynomial_fold *fold)
2120 int i;
2122 for (i = 0; i < fold->n - 1; ++i)
2123 if (fold->type == isl_fold_min)
2124 p = isl_printer_print_str(p, "min(");
2125 else if (fold->type == isl_fold_max)
2126 p = isl_printer_print_str(p, "max(");
2128 for (i = 0; i < fold->n; ++i) {
2129 if (i)
2130 p = isl_printer_print_str(p, ", ");
2131 p = print_qpolynomial_c(p, dim, fold->qp[i]);
2132 if (i)
2133 p = isl_printer_print_str(p, ")");
2135 return p;
2138 __isl_give isl_printer *isl_printer_print_qpolynomial_fold(
2139 __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
2141 if (!p || !fold)
2142 goto error;
2143 if (p->output_format == ISL_FORMAT_ISL)
2144 return qpolynomial_fold_print(fold, p);
2145 else if (p->output_format == ISL_FORMAT_C)
2146 return print_qpolynomial_fold_c(p, fold->dim, fold);
2147 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2148 goto error);
2149 error:
2150 isl_printer_free(p);
2151 return NULL;
2154 static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
2155 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
2157 int i;
2159 if (pwf->n == 1 && isl_set_plain_is_universe(pwf->p[0].set))
2160 return print_qpolynomial_fold_c(p, pwf->dim, pwf->p[0].fold);
2162 for (i = 0; i < pwf->n; ++i) {
2163 p = isl_printer_print_str(p, "(");
2164 p = print_set_c(p, pwf->dim, pwf->p[i].set);
2165 p = isl_printer_print_str(p, ") ? (");
2166 p = print_qpolynomial_fold_c(p, pwf->dim, pwf->p[i].fold);
2167 p = isl_printer_print_str(p, ") : ");
2170 p = isl_printer_print_str(p, "0");
2171 return p;
2174 __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
2175 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
2177 if (!p || !pwf)
2178 goto error;
2180 if (p->output_format == ISL_FORMAT_ISL)
2181 return print_pw_qpolynomial_fold_isl(p, pwf);
2182 else if (p->output_format == ISL_FORMAT_C)
2183 return print_pw_qpolynomial_fold_c(p, pwf);
2184 isl_assert(p->ctx, 0, goto error);
2185 error:
2186 isl_printer_free(p);
2187 return NULL;
2190 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
2191 FILE *out, unsigned output_format)
2193 isl_printer *p;
2195 if (!pwf)
2196 return;
2198 p = isl_printer_to_file(pwf->dim->ctx, out);
2199 p = isl_printer_set_output_format(p, output_format);
2200 p = isl_printer_print_pw_qpolynomial_fold(p, pwf);
2202 isl_printer_free(p);
2205 static isl_stat print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf,
2206 void *user)
2208 struct isl_union_print_data *data;
2209 data = (struct isl_union_print_data *)user;
2211 if (!data->first)
2212 data->p = isl_printer_print_str(data->p, "; ");
2213 data->first = 0;
2215 data->p = isl_pwf_print_isl_body(data->p, pwf);
2216 isl_pw_qpolynomial_fold_free(pwf);
2218 return isl_stat_ok;
2221 static __isl_give isl_printer *print_union_pw_qpolynomial_fold_isl(
2222 __isl_take isl_printer *p,
2223 __isl_keep isl_union_pw_qpolynomial_fold *upwf)
2225 struct isl_union_print_data data;
2226 struct isl_print_space_data space_data = { 0 };
2227 isl_space *space;
2229 space = isl_union_pw_qpolynomial_fold_get_space(upwf);
2230 p = print_param_tuple(p, space, &space_data);
2231 isl_space_free(space);
2232 p = isl_printer_print_str(p, "{ ");
2233 data.p = p;
2234 data.first = 1;
2235 isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf,
2236 &print_pwf_body, &data);
2237 p = data.p;
2238 p = isl_printer_print_str(p, " }");
2239 return p;
2242 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold(
2243 __isl_take isl_printer *p,
2244 __isl_keep isl_union_pw_qpolynomial_fold *upwf)
2246 if (!p || !upwf)
2247 goto error;
2249 if (p->output_format == ISL_FORMAT_ISL)
2250 return print_union_pw_qpolynomial_fold_isl(p, upwf);
2251 isl_die(p->ctx, isl_error_invalid,
2252 "invalid output format for isl_union_pw_qpolynomial_fold",
2253 goto error);
2254 error:
2255 isl_printer_free(p);
2256 return NULL;
2259 /* Print the isl_constraint "c" to "p".
2261 __isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p,
2262 __isl_keep isl_constraint *c)
2264 struct isl_print_space_data data = { 0 };
2265 isl_local_space *ls;
2266 isl_space *space;
2267 isl_bool exists;
2269 if (!p || !c)
2270 goto error;
2272 ls = isl_constraint_get_local_space(c);
2273 if (!ls)
2274 return isl_printer_free(p);
2275 space = isl_local_space_get_space(ls);
2276 p = print_param_tuple(p, space, &data);
2277 p = isl_printer_print_str(p, "{ ");
2278 p = isl_print_space(space, p, 0, &data);
2279 p = isl_printer_print_str(p, " : ");
2280 exists = need_exists(p, ls->div);
2281 if (exists < 0)
2282 p = isl_printer_free(p);
2283 if (exists >= 0 && exists)
2284 p = open_exists(p, space, ls->div, 0);
2285 p = print_affine_of_len(space, ls->div, p, c->v->el, c->v->size);
2286 if (isl_constraint_is_equality(c))
2287 p = isl_printer_print_str(p, " = 0");
2288 else
2289 p = isl_printer_print_str(p, " >= 0");
2290 if (exists >= 0 && exists)
2291 p = isl_printer_print_str(p, s_close_exists[0]);
2292 p = isl_printer_print_str(p, " }");
2293 isl_space_free(space);
2294 isl_local_space_free(ls);
2296 return p;
2297 error:
2298 isl_printer_free(p);
2299 return NULL;
2302 static __isl_give isl_printer *isl_printer_print_space_isl(
2303 __isl_take isl_printer *p, __isl_keep isl_space *space)
2305 struct isl_print_space_data data = { 0 };
2307 if (!space)
2308 goto error;
2310 p = print_param_tuple(p, space, &data);
2312 p = isl_printer_print_str(p, "{ ");
2313 if (isl_space_is_params(space))
2314 p = isl_printer_print_str(p, s_such_that[0]);
2315 else
2316 p = isl_print_space(space, p, 0, &data);
2317 p = isl_printer_print_str(p, " }");
2319 return p;
2320 error:
2321 isl_printer_free(p);
2322 return NULL;
2325 __isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p,
2326 __isl_keep isl_space *space)
2328 if (!p || !space)
2329 return isl_printer_free(p);
2330 if (p->output_format == ISL_FORMAT_ISL)
2331 return isl_printer_print_space_isl(p, space);
2332 else if (p->output_format == ISL_FORMAT_OMEGA)
2333 return print_omega_parameters(space, p);
2335 isl_die(isl_space_get_ctx(space), isl_error_unsupported,
2336 "output format not supported for space",
2337 return isl_printer_free(p));
2340 __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p,
2341 __isl_keep isl_local_space *ls)
2343 struct isl_print_space_data data = { 0 };
2344 unsigned n_div;
2346 if (!ls)
2347 goto error;
2349 p = print_param_tuple(p, ls->dim, &data);
2350 p = isl_printer_print_str(p, "{ ");
2351 p = isl_print_space(ls->dim, p, 0, &data);
2352 n_div = isl_local_space_dim(ls, isl_dim_div);
2353 if (n_div > 0) {
2354 p = isl_printer_print_str(p, " : ");
2355 p = isl_printer_print_str(p, s_open_exists[0]);
2356 p = print_div_list(p, ls->dim, ls->div, 0, 1);
2357 p = isl_printer_print_str(p, s_close_exists[0]);
2358 } else if (isl_space_is_params(ls->dim))
2359 p = isl_printer_print_str(p, s_such_that[0]);
2360 p = isl_printer_print_str(p, " }");
2361 return p;
2362 error:
2363 isl_printer_free(p);
2364 return NULL;
2367 static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p,
2368 __isl_keep isl_aff *aff)
2370 unsigned total;
2372 if (isl_aff_is_nan(aff))
2373 return isl_printer_print_str(p, "NaN");
2375 total = isl_local_space_dim(aff->ls, isl_dim_all);
2376 p = isl_printer_print_str(p, "(");
2377 p = print_affine_of_len(aff->ls->dim, aff->ls->div, p,
2378 aff->v->el + 1, 1 + total);
2379 if (isl_int_is_one(aff->v->el[0]))
2380 p = isl_printer_print_str(p, ")");
2381 else {
2382 p = isl_printer_print_str(p, ")/");
2383 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2386 return p;
2389 static __isl_give isl_printer *print_aff(__isl_take isl_printer *p,
2390 __isl_keep isl_aff *aff)
2392 struct isl_print_space_data data = { 0 };
2394 if (isl_space_is_params(aff->ls->dim))
2396 else {
2397 p = print_tuple(aff->ls->dim, p, isl_dim_set, &data);
2398 p = isl_printer_print_str(p, " -> ");
2400 p = isl_printer_print_str(p, "[");
2401 p = print_aff_body(p, aff);
2402 p = isl_printer_print_str(p, "]");
2404 return p;
2407 static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p,
2408 __isl_keep isl_aff *aff)
2410 struct isl_print_space_data data = { 0 };
2412 if (!aff)
2413 goto error;
2415 p = print_param_tuple(p, aff->ls->dim, &data);
2416 p = isl_printer_print_str(p, "{ ");
2417 p = print_aff(p, aff);
2418 p = isl_printer_print_str(p, " }");
2419 return p;
2420 error:
2421 isl_printer_free(p);
2422 return NULL;
2425 /* Print the body of an isl_pw_aff, i.e., a semicolon delimited
2426 * sequence of affine expressions, each followed by constraints.
2428 static __isl_give isl_printer *print_pw_aff_body(
2429 __isl_take isl_printer *p, __isl_keep isl_pw_aff *pa)
2431 int i;
2433 if (!pa)
2434 return isl_printer_free(p);
2436 for (i = 0; i < pa->n; ++i) {
2437 isl_space *space;
2439 if (i)
2440 p = isl_printer_print_str(p, "; ");
2441 p = print_aff(p, pa->p[i].aff);
2442 space = isl_aff_get_domain_space(pa->p[i].aff);
2443 p = print_disjuncts(set_to_map(pa->p[i].set), space, p, 0);
2444 isl_space_free(space);
2447 return p;
2450 static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p,
2451 __isl_keep isl_pw_aff *pwaff)
2453 struct isl_print_space_data data = { 0 };
2455 if (!pwaff)
2456 goto error;
2458 p = print_param_tuple(p, pwaff->dim, &data);
2459 p = isl_printer_print_str(p, "{ ");
2460 p = print_pw_aff_body(p, pwaff);
2461 p = isl_printer_print_str(p, " }");
2462 return p;
2463 error:
2464 isl_printer_free(p);
2465 return NULL;
2468 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2469 __isl_keep isl_local_space *ls, isl_int *c);
2471 static __isl_give isl_printer *print_ls_name_c(__isl_take isl_printer *p,
2472 __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos)
2474 if (type == isl_dim_div) {
2475 p = isl_printer_print_str(p, "floord(");
2476 p = print_ls_affine_c(p, ls, ls->div->row[pos] + 1);
2477 p = isl_printer_print_str(p, ", ");
2478 p = isl_printer_print_isl_int(p, ls->div->row[pos][0]);
2479 p = isl_printer_print_str(p, ")");
2480 } else {
2481 const char *name;
2483 name = isl_space_get_dim_name(ls->dim, type, pos);
2484 if (!name)
2485 name = "UNNAMED";
2486 p = isl_printer_print_str(p, name);
2488 return p;
2491 static __isl_give isl_printer *print_ls_term_c(__isl_take isl_printer *p,
2492 __isl_keep isl_local_space *ls, isl_int c, unsigned pos)
2494 enum isl_dim_type type;
2496 if (pos == 0)
2497 return isl_printer_print_isl_int(p, c);
2499 if (isl_int_is_one(c))
2501 else if (isl_int_is_negone(c))
2502 p = isl_printer_print_str(p, "-");
2503 else {
2504 p = isl_printer_print_isl_int(p, c);
2505 p = isl_printer_print_str(p, "*");
2507 type = pos2type(ls->dim, &pos);
2508 p = print_ls_name_c(p, ls, type, pos);
2509 return p;
2512 static __isl_give isl_printer *print_ls_partial_affine_c(
2513 __isl_take isl_printer *p, __isl_keep isl_local_space *ls,
2514 isl_int *c, unsigned len)
2516 int i;
2517 int first;
2519 for (i = 0, first = 1; i < len; ++i) {
2520 int flip = 0;
2521 if (isl_int_is_zero(c[i]))
2522 continue;
2523 if (!first) {
2524 if (isl_int_is_neg(c[i])) {
2525 flip = 1;
2526 isl_int_neg(c[i], c[i]);
2527 p = isl_printer_print_str(p, " - ");
2528 } else
2529 p = isl_printer_print_str(p, " + ");
2531 first = 0;
2532 p = print_ls_term_c(p, ls, c[i], i);
2533 if (flip)
2534 isl_int_neg(c[i], c[i]);
2536 if (first)
2537 p = isl_printer_print_str(p, "0");
2538 return p;
2541 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2542 __isl_keep isl_local_space *ls, isl_int *c)
2544 unsigned len = 1 + isl_local_space_dim(ls, isl_dim_all);
2545 return print_ls_partial_affine_c(p, ls, c, len);
2548 static __isl_give isl_printer *print_aff_c(__isl_take isl_printer *p,
2549 __isl_keep isl_aff *aff)
2551 unsigned total;
2553 total = isl_local_space_dim(aff->ls, isl_dim_all);
2554 if (!isl_int_is_one(aff->v->el[0]))
2555 p = isl_printer_print_str(p, "(");
2556 p = print_ls_partial_affine_c(p, aff->ls, aff->v->el + 1, 1 + total);
2557 if (!isl_int_is_one(aff->v->el[0])) {
2558 p = isl_printer_print_str(p, ")/");
2559 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2561 return p;
2564 /* In the C format, we cannot express that "pwaff" may be undefined
2565 * on parts of the domain space. We therefore assume that the expression
2566 * will only be evaluated on its definition domain and compute the gist
2567 * of each cell with respect to this domain.
2569 static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p,
2570 __isl_keep isl_pw_aff *pwaff)
2572 isl_set *domain;
2573 isl_ast_build *build;
2574 isl_ast_expr *expr;
2576 if (pwaff->n < 1)
2577 isl_die(p->ctx, isl_error_unsupported,
2578 "cannot print empty isl_pw_aff in C format",
2579 return isl_printer_free(p));
2581 domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff));
2582 build = isl_ast_build_from_context(domain);
2583 expr = isl_ast_build_expr_from_pw_aff(build, isl_pw_aff_copy(pwaff));
2584 p = isl_printer_print_ast_expr(p, expr);
2585 isl_ast_expr_free(expr);
2586 isl_ast_build_free(build);
2588 return p;
2591 __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p,
2592 __isl_keep isl_aff *aff)
2594 if (!p || !aff)
2595 goto error;
2597 if (p->output_format == ISL_FORMAT_ISL)
2598 return print_aff_isl(p, aff);
2599 else if (p->output_format == ISL_FORMAT_C)
2600 return print_aff_c(p, aff);
2601 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2602 goto error);
2603 error:
2604 isl_printer_free(p);
2605 return NULL;
2608 __isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p,
2609 __isl_keep isl_pw_aff *pwaff)
2611 if (!p || !pwaff)
2612 goto error;
2614 if (p->output_format == ISL_FORMAT_ISL)
2615 return print_pw_aff_isl(p, pwaff);
2616 else if (p->output_format == ISL_FORMAT_C)
2617 return print_pw_aff_c(p, pwaff);
2618 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2619 goto error);
2620 error:
2621 isl_printer_free(p);
2622 return NULL;
2625 /* Print "pa" in a sequence of isl_pw_affs delimited by semicolons.
2626 * Each isl_pw_aff itself is also printed as semicolon delimited
2627 * sequence of pieces.
2628 * If data->first = 1, then this is the first in the sequence.
2629 * Update data->first to tell the next element that it is not the first.
2631 static isl_stat print_pw_aff_body_wrap(__isl_take isl_pw_aff *pa,
2632 void *user)
2634 struct isl_union_print_data *data;
2635 data = (struct isl_union_print_data *) user;
2637 if (!data->first)
2638 data->p = isl_printer_print_str(data->p, "; ");
2639 data->first = 0;
2641 data->p = print_pw_aff_body(data->p, pa);
2642 isl_pw_aff_free(pa);
2644 return data->p ? isl_stat_ok : isl_stat_error;
2647 /* Print the body of an isl_union_pw_aff, i.e., a semicolon delimited
2648 * sequence of affine expressions, each followed by constraints,
2649 * with the sequence enclosed in braces.
2651 static __isl_give isl_printer *print_union_pw_aff_body(
2652 __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
2654 struct isl_union_print_data data = { p, 1 };
2656 p = isl_printer_print_str(p, s_open_set[0]);
2657 data.p = p;
2658 if (isl_union_pw_aff_foreach_pw_aff(upa,
2659 &print_pw_aff_body_wrap, &data) < 0)
2660 data.p = isl_printer_free(p);
2661 p = data.p;
2662 p = isl_printer_print_str(p, s_close_set[0]);
2664 return p;
2667 /* Print the isl_union_pw_aff "upa" to "p" in isl format.
2669 * The individual isl_pw_affs are delimited by a semicolon.
2671 static __isl_give isl_printer *print_union_pw_aff_isl(
2672 __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
2674 struct isl_print_space_data data = { 0 };
2675 isl_space *space;
2677 space = isl_union_pw_aff_get_space(upa);
2678 p = print_param_tuple(p, space, &data);
2679 isl_space_free(space);
2680 p = print_union_pw_aff_body(p, upa);
2681 return p;
2684 /* Print the isl_union_pw_aff "upa" to "p".
2686 * We currently only support an isl format.
2688 __isl_give isl_printer *isl_printer_print_union_pw_aff(
2689 __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
2691 if (!p || !upa)
2692 return isl_printer_free(p);
2694 if (p->output_format == ISL_FORMAT_ISL)
2695 return print_union_pw_aff_isl(p, upa);
2696 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
2697 "unsupported output format", return isl_printer_free(p));
2700 /* Print dimension "pos" of data->space to "p".
2702 * data->user is assumed to be an isl_multi_aff.
2704 * If the current dimension is an output dimension, then print
2705 * the corresponding expression. Otherwise, print the name of the dimension.
2707 static __isl_give isl_printer *print_dim_ma(__isl_take isl_printer *p,
2708 struct isl_print_space_data *data, unsigned pos)
2710 isl_multi_aff *ma = data->user;
2712 if (data->type == isl_dim_out)
2713 p = print_aff_body(p, ma->p[pos]);
2714 else
2715 p = print_name(data->space, p, data->type, pos, data->latex);
2717 return p;
2720 static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p,
2721 __isl_keep isl_multi_aff *maff)
2723 struct isl_print_space_data data = { 0 };
2725 data.print_dim = &print_dim_ma;
2726 data.user = maff;
2727 return isl_print_space(maff->space, p, 0, &data);
2730 static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p,
2731 __isl_keep isl_multi_aff *maff)
2733 struct isl_print_space_data data = { 0 };
2735 if (!maff)
2736 goto error;
2738 p = print_param_tuple(p, maff->space, &data);
2739 p = isl_printer_print_str(p, "{ ");
2740 p = print_multi_aff(p, maff);
2741 p = isl_printer_print_str(p, " }");
2742 return p;
2743 error:
2744 isl_printer_free(p);
2745 return NULL;
2748 __isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p,
2749 __isl_keep isl_multi_aff *maff)
2751 if (!p || !maff)
2752 goto error;
2754 if (p->output_format == ISL_FORMAT_ISL)
2755 return print_multi_aff_isl(p, maff);
2756 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2757 goto error);
2758 error:
2759 isl_printer_free(p);
2760 return NULL;
2763 static __isl_give isl_printer *print_pw_multi_aff_body(
2764 __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2766 int i;
2768 if (!pma)
2769 goto error;
2771 for (i = 0; i < pma->n; ++i) {
2772 isl_space *space;
2774 if (i)
2775 p = isl_printer_print_str(p, "; ");
2776 p = print_multi_aff(p, pma->p[i].maff);
2777 space = isl_multi_aff_get_domain_space(pma->p[i].maff);
2778 p = print_disjuncts(set_to_map(pma->p[i].set), space, p, 0);
2779 isl_space_free(space);
2781 return p;
2782 error:
2783 isl_printer_free(p);
2784 return NULL;
2787 static __isl_give isl_printer *print_pw_multi_aff_isl(__isl_take isl_printer *p,
2788 __isl_keep isl_pw_multi_aff *pma)
2790 struct isl_print_space_data data = { 0 };
2792 if (!pma)
2793 goto error;
2795 p = print_param_tuple(p, pma->dim, &data);
2796 p = isl_printer_print_str(p, "{ ");
2797 p = print_pw_multi_aff_body(p, pma);
2798 p = isl_printer_print_str(p, " }");
2799 return p;
2800 error:
2801 isl_printer_free(p);
2802 return NULL;
2805 static __isl_give isl_printer *print_unnamed_pw_multi_aff_c(
2806 __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2808 int i;
2810 for (i = 0; i < pma->n - 1; ++i) {
2811 p = isl_printer_print_str(p, "(");
2812 p = print_set_c(p, pma->dim, pma->p[i].set);
2813 p = isl_printer_print_str(p, ") ? (");
2814 p = print_aff_c(p, pma->p[i].maff->p[0]);
2815 p = isl_printer_print_str(p, ") : ");
2818 return print_aff_c(p, pma->p[pma->n - 1].maff->p[0]);
2821 static __isl_give isl_printer *print_pw_multi_aff_c(__isl_take isl_printer *p,
2822 __isl_keep isl_pw_multi_aff *pma)
2824 int n;
2825 const char *name;
2827 if (!pma)
2828 goto error;
2829 if (pma->n < 1)
2830 isl_die(p->ctx, isl_error_unsupported,
2831 "cannot print empty isl_pw_multi_aff in C format",
2832 goto error);
2833 name = isl_pw_multi_aff_get_tuple_name(pma, isl_dim_out);
2834 if (!name && isl_pw_multi_aff_dim(pma, isl_dim_out) == 1)
2835 return print_unnamed_pw_multi_aff_c(p, pma);
2836 if (!name)
2837 isl_die(p->ctx, isl_error_unsupported,
2838 "cannot print unnamed isl_pw_multi_aff in C format",
2839 goto error);
2841 p = isl_printer_print_str(p, name);
2842 n = isl_pw_multi_aff_dim(pma, isl_dim_out);
2843 if (n != 0)
2844 isl_die(p->ctx, isl_error_unsupported,
2845 "not supported yet", goto error);
2847 return p;
2848 error:
2849 isl_printer_free(p);
2850 return NULL;
2853 __isl_give isl_printer *isl_printer_print_pw_multi_aff(
2854 __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2856 if (!p || !pma)
2857 goto error;
2859 if (p->output_format == ISL_FORMAT_ISL)
2860 return print_pw_multi_aff_isl(p, pma);
2861 if (p->output_format == ISL_FORMAT_C)
2862 return print_pw_multi_aff_c(p, pma);
2863 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2864 goto error);
2865 error:
2866 isl_printer_free(p);
2867 return NULL;
2870 static isl_stat print_pw_multi_aff_body_wrap(__isl_take isl_pw_multi_aff *pma,
2871 void *user)
2873 struct isl_union_print_data *data;
2874 data = (struct isl_union_print_data *) user;
2876 if (!data->first)
2877 data->p = isl_printer_print_str(data->p, "; ");
2878 data->first = 0;
2880 data->p = print_pw_multi_aff_body(data->p, pma);
2881 isl_pw_multi_aff_free(pma);
2883 return isl_stat_ok;
2886 static __isl_give isl_printer *print_union_pw_multi_aff_isl(
2887 __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
2889 struct isl_union_print_data data;
2890 struct isl_print_space_data space_data = { 0 };
2891 isl_space *space;
2893 space = isl_union_pw_multi_aff_get_space(upma);
2894 p = print_param_tuple(p, space, &space_data);
2895 isl_space_free(space);
2896 p = isl_printer_print_str(p, s_open_set[0]);
2897 data.p = p;
2898 data.first = 1;
2899 isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
2900 &print_pw_multi_aff_body_wrap, &data);
2901 p = data.p;
2902 p = isl_printer_print_str(p, s_close_set[0]);
2903 return p;
2906 __isl_give isl_printer *isl_printer_print_union_pw_multi_aff(
2907 __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
2909 if (!p || !upma)
2910 goto error;
2912 if (p->output_format == ISL_FORMAT_ISL)
2913 return print_union_pw_multi_aff_isl(p, upma);
2914 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2915 goto error);
2916 error:
2917 isl_printer_free(p);
2918 return NULL;
2921 /* Print dimension "pos" of data->space to "p".
2923 * data->user is assumed to be an isl_multi_pw_aff.
2925 * If the current dimension is an output dimension, then print
2926 * the corresponding piecewise affine expression.
2927 * Otherwise, print the name of the dimension.
2929 static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p,
2930 struct isl_print_space_data *data, unsigned pos)
2932 int i;
2933 int need_parens;
2934 isl_multi_pw_aff *mpa = data->user;
2935 isl_pw_aff *pa;
2937 if (data->type != isl_dim_out)
2938 return print_name(data->space, p, data->type, pos, data->latex);
2940 pa = mpa->p[pos];
2941 if (pa->n == 0)
2942 return isl_printer_print_str(p, "(0 : 1 = 0)");
2944 need_parens = pa->n != 1 || !isl_set_plain_is_universe(pa->p[0].set);
2945 if (need_parens)
2946 p = isl_printer_print_str(p, "(");
2947 for (i = 0; i < pa->n; ++i) {
2948 isl_space *space;
2950 if (i)
2951 p = isl_printer_print_str(p, "; ");
2952 p = print_aff_body(p, pa->p[i].aff);
2953 space = isl_aff_get_domain_space(pa->p[i].aff);
2954 p = print_disjuncts(pa->p[i].set, space, p, 0);
2955 isl_space_free(space);
2957 if (need_parens)
2958 p = isl_printer_print_str(p, ")");
2960 return p;
2963 /* Print "mpa" to "p" in isl format.
2965 static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p,
2966 __isl_keep isl_multi_pw_aff *mpa)
2968 struct isl_print_space_data data = { 0 };
2970 if (!mpa)
2971 return isl_printer_free(p);
2973 p = print_param_tuple(p, mpa->space, &data);
2974 p = isl_printer_print_str(p, "{ ");
2975 data.print_dim = &print_dim_mpa;
2976 data.user = mpa;
2977 p = isl_print_space(mpa->space, p, 0, &data);
2978 p = isl_printer_print_str(p, " }");
2979 return p;
2982 __isl_give isl_printer *isl_printer_print_multi_pw_aff(
2983 __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa)
2985 if (!p || !mpa)
2986 return isl_printer_free(p);
2988 if (p->output_format == ISL_FORMAT_ISL)
2989 return print_multi_pw_aff_isl(p, mpa);
2990 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2991 return isl_printer_free(p));
2994 /* Print dimension "pos" of data->space to "p".
2996 * data->user is assumed to be an isl_multi_val.
2998 * If the current dimension is an output dimension, then print
2999 * the corresponding value. Otherwise, print the name of the dimension.
3001 static __isl_give isl_printer *print_dim_mv(__isl_take isl_printer *p,
3002 struct isl_print_space_data *data, unsigned pos)
3004 isl_multi_val *mv = data->user;
3006 if (data->type == isl_dim_out)
3007 return isl_printer_print_val(p, mv->p[pos]);
3008 else
3009 return print_name(data->space, p, data->type, pos, data->latex);
3012 /* Print the isl_multi_val "mv" to "p" in isl format.
3014 static __isl_give isl_printer *print_multi_val_isl(__isl_take isl_printer *p,
3015 __isl_keep isl_multi_val *mv)
3017 struct isl_print_space_data data = { 0 };
3019 if (!mv)
3020 return isl_printer_free(p);
3022 p = print_param_tuple(p, mv->space, &data);
3023 p = isl_printer_print_str(p, "{ ");
3024 data.print_dim = &print_dim_mv;
3025 data.user = mv;
3026 p = isl_print_space(mv->space, p, 0, &data);
3027 p = isl_printer_print_str(p, " }");
3028 return p;
3031 /* Print the isl_multi_val "mv" to "p".
3033 * Currently only supported in isl format.
3035 __isl_give isl_printer *isl_printer_print_multi_val(
3036 __isl_take isl_printer *p, __isl_keep isl_multi_val *mv)
3038 if (!p || !mv)
3039 return isl_printer_free(p);
3041 if (p->output_format == ISL_FORMAT_ISL)
3042 return print_multi_val_isl(p, mv);
3043 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
3044 return isl_printer_free(p));
3047 /* Print dimension "pos" of data->space to "p".
3049 * data->user is assumed to be an isl_multi_union_pw_aff.
3051 * The current dimension is necessarily a set dimension, so
3052 * we print the corresponding isl_union_pw_aff, including
3053 * the braces.
3055 static __isl_give isl_printer *print_union_pw_aff_dim(__isl_take isl_printer *p,
3056 struct isl_print_space_data *data, unsigned pos)
3058 isl_multi_union_pw_aff *mupa = data->user;
3059 isl_union_pw_aff *upa;
3061 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, pos);
3062 p = print_union_pw_aff_body(p, upa);
3063 isl_union_pw_aff_free(upa);
3065 return p;
3068 /* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.
3070 static __isl_give isl_printer *print_multi_union_pw_aff_isl(
3071 __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)
3073 struct isl_print_space_data data = { 0 };
3074 isl_space *space;
3076 space = isl_multi_union_pw_aff_get_space(mupa);
3077 p = print_param_tuple(p, space, &data);
3079 data.print_dim = &print_union_pw_aff_dim;
3080 data.user = mupa;
3082 p = isl_print_space(space, p, 0, &data);
3083 isl_space_free(space);
3085 return p;
3088 /* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.
3090 * We currently only support an isl format.
3092 __isl_give isl_printer *isl_printer_print_multi_union_pw_aff(
3093 __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)
3095 if (!p || !mupa)
3096 return isl_printer_free(p);
3098 if (p->output_format == ISL_FORMAT_ISL)
3099 return print_multi_union_pw_aff_isl(p, mupa);
3100 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
3101 "unsupported output format", return isl_printer_free(p));