isl_ast_build_expr.c: ast_expr_from_pw_aff: delay construction of expression
[isl.git] / isl_output.c
bloba0a578779bcf69f6928a46b662f4192b7d15560b
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/ast_build.h>
32 #include <isl_sort.h>
33 #include <isl_output_private.h>
35 static const char *s_to[2] = { " -> ", " \\to " };
36 static const char *s_and[2] = { " and ", " \\wedge " };
37 static const char *s_or[2] = { " or ", " \\vee " };
38 static const char *s_le[2] = { "<=", "\\le" };
39 static const char *s_ge[2] = { ">=", "\\ge" };
40 static const char *s_open_set[2] = { "{ ", "\\{\\, " };
41 static const char *s_close_set[2] = { " }", " \\,\\}" };
42 static const char *s_open_list[2] = { "[", "(" };
43 static const char *s_close_list[2] = { "]", ")" };
44 static const char *s_such_that[2] = { " : ", " \\mid " };
45 static const char *s_open_exists[2] = { "exists (", "\\exists \\, " };
46 static const char *s_close_exists[2] = { ")", "" };
47 static const char *s_div_prefix[2] = { "e", "\\alpha_" };
48 static const char *s_param_prefix[2] = { "p", "p_" };
49 static const char *s_input_prefix[2] = { "i", "i_" };
50 static const char *s_output_prefix[2] = { "o", "o_" };
52 static __isl_give isl_printer *print_constraint_polylib(
53 struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p)
55 int i;
56 unsigned n_in = isl_basic_map_dim(bmap, isl_dim_in);
57 unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
58 unsigned nparam = isl_basic_map_dim(bmap, isl_dim_param);
59 isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n];
61 p = isl_printer_start_line(p);
62 p = isl_printer_print_int(p, ineq);
63 for (i = 0; i < n_out; ++i) {
64 p = isl_printer_print_str(p, " ");
65 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]);
67 for (i = 0; i < n_in; ++i) {
68 p = isl_printer_print_str(p, " ");
69 p = isl_printer_print_isl_int(p, c[1+nparam+i]);
71 for (i = 0; i < bmap->n_div; ++i) {
72 p = isl_printer_print_str(p, " ");
73 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]);
75 for (i = 0; i < nparam; ++i) {
76 p = isl_printer_print_str(p, " ");
77 p = isl_printer_print_isl_int(p, c[1+i]);
79 p = isl_printer_print_str(p, " ");
80 p = isl_printer_print_isl_int(p, c[0]);
81 p = isl_printer_end_line(p);
82 return p;
85 static __isl_give isl_printer *print_constraints_polylib(
86 struct isl_basic_map *bmap, __isl_take isl_printer *p)
88 int i;
90 p = isl_printer_set_isl_int_width(p, 5);
92 for (i = 0; i < bmap->n_eq; ++i)
93 p = print_constraint_polylib(bmap, 0, i, p);
94 for (i = 0; i < bmap->n_ineq; ++i)
95 p = print_constraint_polylib(bmap, 1, i, p);
97 return p;
100 static __isl_give isl_printer *bset_print_constraints_polylib(
101 struct isl_basic_set *bset, __isl_take isl_printer *p)
103 return print_constraints_polylib((struct isl_basic_map *)bset, p);
106 static __isl_give isl_printer *isl_basic_map_print_polylib(
107 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int ext)
109 unsigned total = isl_basic_map_total_dim(bmap);
110 p = isl_printer_start_line(p);
111 p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq);
112 p = isl_printer_print_str(p, " ");
113 p = isl_printer_print_int(p, 1 + total + 1);
114 if (ext) {
115 p = isl_printer_print_str(p, " ");
116 p = isl_printer_print_int(p,
117 isl_basic_map_dim(bmap, isl_dim_out));
118 p = isl_printer_print_str(p, " ");
119 p = isl_printer_print_int(p,
120 isl_basic_map_dim(bmap, isl_dim_in));
121 p = isl_printer_print_str(p, " ");
122 p = isl_printer_print_int(p,
123 isl_basic_map_dim(bmap, isl_dim_div));
124 p = isl_printer_print_str(p, " ");
125 p = isl_printer_print_int(p,
126 isl_basic_map_dim(bmap, isl_dim_param));
128 p = isl_printer_end_line(p);
129 return print_constraints_polylib(bmap, p);
132 static __isl_give isl_printer *isl_basic_set_print_polylib(
133 __isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int ext)
135 return isl_basic_map_print_polylib((struct isl_basic_map *)bset, p, ext);
138 static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map,
139 __isl_take isl_printer *p, int ext)
141 int i;
143 p = isl_printer_start_line(p);
144 p = isl_printer_print_int(p, map->n);
145 p = isl_printer_end_line(p);
146 for (i = 0; i < map->n; ++i) {
147 p = isl_printer_start_line(p);
148 p = isl_printer_end_line(p);
149 p = isl_basic_map_print_polylib(map->p[i], p, ext);
151 return p;
154 static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set,
155 __isl_take isl_printer *p, int ext)
157 return isl_map_print_polylib((struct isl_map *)set, p, ext);
160 static int count_same_name(__isl_keep isl_space *dim,
161 enum isl_dim_type type, unsigned pos, const char *name)
163 enum isl_dim_type t;
164 unsigned p, s;
165 int count = 0;
167 for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) {
168 s = t == type ? pos : isl_space_dim(dim, t);
169 for (p = 0; p < s; ++p) {
170 const char *n = isl_space_get_dim_name(dim, t, p);
171 if (n && !strcmp(n, name))
172 count++;
175 return count;
178 /* Print the name of the variable of type "type" and position "pos"
179 * in "space" to "p".
181 static __isl_give isl_printer *print_name(__isl_keep isl_space *space,
182 __isl_take isl_printer *p, enum isl_dim_type type, unsigned pos,
183 int latex)
185 const char *name;
186 char buffer[20];
187 int primes;
189 name = type == isl_dim_div ? NULL
190 : isl_space_get_dim_name(space, type, pos);
192 if (!name) {
193 const char *prefix;
194 if (type == isl_dim_param)
195 prefix = s_param_prefix[latex];
196 else if (type == isl_dim_div)
197 prefix = s_div_prefix[latex];
198 else if (isl_space_is_set(space) || type == isl_dim_in)
199 prefix = s_input_prefix[latex];
200 else
201 prefix = s_output_prefix[latex];
202 snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);
203 name = buffer;
205 primes = count_same_name(space, name == buffer ? isl_dim_div : type,
206 pos, name);
207 p = isl_printer_print_str(p, name);
208 while (primes-- > 0)
209 p = isl_printer_print_str(p, "'");
210 return p;
213 static enum isl_dim_type pos2type(__isl_keep isl_space *dim, unsigned *pos)
215 enum isl_dim_type type;
216 unsigned n_in = isl_space_dim(dim, isl_dim_in);
217 unsigned n_out = isl_space_dim(dim, isl_dim_out);
218 unsigned nparam = isl_space_dim(dim, isl_dim_param);
220 if (*pos < 1 + nparam) {
221 type = isl_dim_param;
222 *pos -= 1;
223 } else if (*pos < 1 + nparam + n_in) {
224 type = isl_dim_in;
225 *pos -= 1 + nparam;
226 } else if (*pos < 1 + nparam + n_in + n_out) {
227 type = isl_dim_out;
228 *pos -= 1 + nparam + n_in;
229 } else {
230 type = isl_dim_div;
231 *pos -= 1 + nparam + n_in + n_out;
234 return type;
237 /* Can the div expression of the integer division at position "row" of "div"
238 * be printed?
239 * In particular, are the div expressions available and does the selected
240 * variable have a known explicit representation?
241 * Furthermore, the Omega format does not allow and div expressions
242 * to be printed.
244 static isl_bool can_print_div_expr(__isl_keep isl_printer *p,
245 __isl_keep isl_mat *div, int pos)
247 if (p->output_format == ISL_FORMAT_OMEGA)
248 return isl_bool_false;
249 if (!div)
250 return isl_bool_false;
251 return !isl_int_is_zero(div->row[pos][0]);
254 static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
255 __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p);
257 static __isl_give isl_printer *print_term(__isl_keep isl_space *space,
258 __isl_keep isl_mat *div,
259 isl_int c, unsigned pos, __isl_take isl_printer *p, int latex)
261 enum isl_dim_type type;
262 int print_div_def;
264 if (pos == 0)
265 return isl_printer_print_isl_int(p, c);
267 type = pos2type(space, &pos);
268 print_div_def = type == isl_dim_div && can_print_div_expr(p, div, pos);
270 if (isl_int_is_one(c))
272 else if (isl_int_is_negone(c))
273 p = isl_printer_print_str(p, "-");
274 else {
275 p = isl_printer_print_isl_int(p, c);
276 if (p->output_format == ISL_FORMAT_C || print_div_def)
277 p = isl_printer_print_str(p, "*");
279 if (print_div_def)
280 p = print_div(space, div, pos, p);
281 else
282 p = print_name(space, p, type, pos, latex);
283 return p;
286 static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *dim,
287 __isl_keep isl_mat *div,
288 __isl_take isl_printer *p, isl_int *c, int len)
290 int i;
291 int first;
293 for (i = 0, first = 1; i < len; ++i) {
294 int flip = 0;
295 if (isl_int_is_zero(c[i]))
296 continue;
297 if (!first) {
298 if (isl_int_is_neg(c[i])) {
299 flip = 1;
300 isl_int_neg(c[i], c[i]);
301 p = isl_printer_print_str(p, " - ");
302 } else
303 p = isl_printer_print_str(p, " + ");
305 first = 0;
306 p = print_term(dim, div, c[i], i, p, 0);
307 if (flip)
308 isl_int_neg(c[i], c[i]);
310 if (first)
311 p = isl_printer_print_str(p, "0");
312 return p;
315 /* Print an affine expression "c" corresponding to a constraint in "bmap"
316 * to "p", with the variable names taken from "space" and
317 * the integer division definitions taken from "div".
319 static __isl_give isl_printer *print_affine(__isl_keep isl_basic_map *bmap,
320 __isl_keep isl_space *space, __isl_keep isl_mat *div,
321 __isl_take isl_printer *p, isl_int *c)
323 unsigned len = 1 + isl_basic_map_total_dim(bmap);
324 return print_affine_of_len(space, div, p, c, len);
327 /* offset is the offset of local_dim inside data->type of data->space.
329 static __isl_give isl_printer *print_nested_var_list(__isl_take isl_printer *p,
330 __isl_keep isl_space *local_dim, enum isl_dim_type local_type,
331 struct isl_print_space_data *data, int offset)
333 int i;
335 if (data->space != local_dim && local_type == isl_dim_out)
336 offset += local_dim->n_in;
338 for (i = 0; i < isl_space_dim(local_dim, local_type); ++i) {
339 if (i)
340 p = isl_printer_print_str(p, ", ");
341 if (data->print_dim)
342 p = data->print_dim(p, data, offset + i);
343 else
344 p = print_name(data->space, p, data->type, offset + i,
345 data->latex);
347 return p;
350 static __isl_give isl_printer *print_var_list(__isl_take isl_printer *p,
351 __isl_keep isl_space *space, enum isl_dim_type type)
353 struct isl_print_space_data data = { .space = space, .type = type };
355 return print_nested_var_list(p, space, type, &data, 0);
358 static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
359 __isl_keep isl_space *local_dim,
360 struct isl_print_space_data *data, int offset);
362 static __isl_give isl_printer *print_nested_tuple(__isl_take isl_printer *p,
363 __isl_keep isl_space *local_dim, enum isl_dim_type local_type,
364 struct isl_print_space_data *data, int offset)
366 const char *name = NULL;
367 unsigned n = isl_space_dim(local_dim, local_type);
368 if ((local_type == isl_dim_in || local_type == isl_dim_out)) {
369 name = isl_space_get_tuple_name(local_dim, local_type);
370 if (name) {
371 if (data->latex)
372 p = isl_printer_print_str(p, "\\mathrm{");
373 p = isl_printer_print_str(p, name);
374 if (data->latex)
375 p = isl_printer_print_str(p, "}");
378 if (!data->latex || n != 1 || name)
379 p = isl_printer_print_str(p, s_open_list[data->latex]);
380 if ((local_type == isl_dim_in || local_type == isl_dim_out) &&
381 local_dim->nested[local_type - isl_dim_in]) {
382 if (data->space != local_dim && local_type == isl_dim_out)
383 offset += local_dim->n_in;
384 p = print_nested_map_dim(p,
385 local_dim->nested[local_type - isl_dim_in],
386 data, offset);
387 } else
388 p = print_nested_var_list(p, local_dim, local_type, data,
389 offset);
390 if (!data->latex || n != 1 || name)
391 p = isl_printer_print_str(p, s_close_list[data->latex]);
392 return p;
395 static __isl_give isl_printer *print_tuple(__isl_keep isl_space *dim,
396 __isl_take isl_printer *p, enum isl_dim_type type,
397 struct isl_print_space_data *data)
399 data->space = dim;
400 data->type = type;
401 return print_nested_tuple(p, dim, type, data, 0);
404 static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
405 __isl_keep isl_space *local_dim,
406 struct isl_print_space_data *data, int offset)
408 p = print_nested_tuple(p, local_dim, isl_dim_in, data, offset);
409 p = isl_printer_print_str(p, s_to[data->latex]);
410 p = print_nested_tuple(p, local_dim, isl_dim_out, data, offset);
412 return p;
415 __isl_give isl_printer *isl_print_space(__isl_keep isl_space *space,
416 __isl_take isl_printer *p, int rational,
417 struct isl_print_space_data *data)
419 if (rational && !data->latex)
420 p = isl_printer_print_str(p, "rat: ");
421 if (isl_space_is_params(space))
423 else if (isl_space_is_set(space))
424 p = print_tuple(space, p, isl_dim_set, data);
425 else {
426 p = print_tuple(space, p, isl_dim_in, data);
427 p = isl_printer_print_str(p, s_to[data->latex]);
428 p = print_tuple(space, p, isl_dim_out, data);
431 return p;
434 static __isl_give isl_printer *print_omega_parameters(__isl_keep isl_space *dim,
435 __isl_take isl_printer *p)
437 if (isl_space_dim(dim, isl_dim_param) == 0)
438 return p;
440 p = isl_printer_start_line(p);
441 p = isl_printer_print_str(p, "symbolic ");
442 p = print_var_list(p, dim, isl_dim_param);
443 p = isl_printer_print_str(p, ";");
444 p = isl_printer_end_line(p);
445 return p;
448 /* Does the inequality constraint following "i" in "bmap"
449 * have an opposite value for the same last coefficient?
450 * "last" is the position of the last coefficient of inequality "i".
451 * If the next constraint is a div constraint, then it is ignored
452 * since div constraints are not printed.
454 static int next_is_opposite(__isl_keep isl_basic_map *bmap, int i, int last)
456 unsigned total = isl_basic_map_total_dim(bmap);
457 unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
459 if (i + 1 >= bmap->n_ineq)
460 return 0;
461 if (isl_seq_last_non_zero(bmap->ineq[i + 1], 1 + total) != last)
462 return 0;
463 if (last >= o_div &&
464 isl_basic_map_is_div_constraint(bmap, bmap->ineq[i + 1],
465 last - o_div))
466 return 0;
467 return isl_int_abs_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]) &&
468 !isl_int_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]);
471 /* Return a string representation of the operator used when
472 * printing a constraint where the LHS is greater than or equal to the LHS
473 * (sign > 0) or smaller than or equal to the LHS (sign < 0).
474 * If "strict" is set, then return the strict version of the comparison
475 * operator.
477 static const char *constraint_op(int sign, int strict, int latex)
479 if (strict)
480 return sign < 0 ? "<" : ">";
481 if (sign < 0)
482 return s_le[latex];
483 else
484 return s_ge[latex];
487 /* Print one side of a constraint "c" from "bmap" to "p", with
488 * the variable names taken from "space" and the integer division definitions
489 * taken from "div".
490 * "last" is the position of the last non-zero coefficient.
491 * Let c' be the result of zeroing out this coefficient, then
492 * the partial constraint
494 * c' op
496 * is printed.
497 * "first_constraint" is set if this is the first constraint
498 * in the conjunction.
500 static __isl_give isl_printer *print_half_constraint(struct isl_basic_map *bmap,
501 __isl_keep isl_space *space, __isl_keep isl_mat *div,
502 __isl_take isl_printer *p, isl_int *c, int last, const char *op,
503 int first_constraint, int latex)
505 if (!first_constraint)
506 p = isl_printer_print_str(p, s_and[latex]);
508 isl_int_set_si(c[last], 0);
509 p = print_affine(bmap, space, div, p, c);
511 p = isl_printer_print_str(p, " ");
512 p = isl_printer_print_str(p, op);
513 p = isl_printer_print_str(p, " ");
515 return p;
518 /* Print a constraint "c" from "bmap" to "p", with the variable names
519 * taken from "space" and the integer division definitions taken from "div".
520 * "last" is the position of the last non-zero coefficient, which is
521 * moreover assumed to be negative.
522 * Let c' be the result of zeroing out this coefficient, then
523 * the constraint is printed in the form
525 * -c[last] op c'
527 * "first_constraint" is set if this is the first constraint
528 * in the conjunction.
530 static __isl_give isl_printer *print_constraint(struct isl_basic_map *bmap,
531 __isl_keep isl_space *space, __isl_keep isl_mat *div,
532 __isl_take isl_printer *p,
533 isl_int *c, int last, const char *op, int first_constraint, int latex)
535 if (!first_constraint)
536 p = isl_printer_print_str(p, s_and[latex]);
538 isl_int_abs(c[last], c[last]);
540 p = print_term(space, div, c[last], last, p, latex);
542 p = isl_printer_print_str(p, " ");
543 p = isl_printer_print_str(p, op);
544 p = isl_printer_print_str(p, " ");
546 isl_int_set_si(c[last], 0);
547 p = print_affine(bmap, space, div, p, c);
549 return p;
552 /* Print the constraints of "bmap" to "p".
553 * The names of the variables are taken from "space" and
554 * the integer division definitions are taken from "div".
555 * Div constraints are only printed in "dump" mode.
556 * The constraints are sorted prior to printing (except in "dump" mode).
558 * If x is the last variable with a non-zero coefficient,
559 * then a lower bound
561 * f - a x >= 0
563 * is printed as
565 * a x <= f
567 * while an upper bound
569 * f + a x >= 0
571 * is printed as
573 * a x >= -f
575 * If the next constraint has an opposite sign for the same last coefficient,
576 * then it is printed as
578 * f >= a x
580 * or
582 * -f <= a x
584 * instead. In fact, the "a x" part is not printed explicitly, but
585 * reused from the next constraint, which is therefore treated as
586 * a first constraint in the conjunction.
588 * If the constant term of "f" is -1, then "f" is replaced by "f + 1" and
589 * the comparison operator is replaced by the strict variant.
590 * Essentially, ">= 1" is replaced by "> 0".
592 static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
593 __isl_keep isl_space *space, __isl_keep isl_mat *div,
594 __isl_take isl_printer *p, int latex)
596 int i;
597 isl_vec *c = NULL;
598 int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
599 unsigned total = isl_basic_map_total_dim(bmap);
600 unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
601 int first = 1;
603 bmap = isl_basic_map_copy(bmap);
604 if (!p->dump)
605 bmap = isl_basic_map_sort_constraints(bmap);
606 if (!bmap)
607 goto error;
609 c = isl_vec_alloc(bmap->ctx, 1 + total);
610 if (!c)
611 goto error;
613 for (i = bmap->n_eq - 1; i >= 0; --i) {
614 int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total);
615 if (l < 0) {
616 if (i != bmap->n_eq - 1)
617 p = isl_printer_print_str(p, s_and[latex]);
618 p = isl_printer_print_str(p, "0 = 0");
619 continue;
621 if (isl_int_is_neg(bmap->eq[i][l]))
622 isl_seq_cpy(c->el, bmap->eq[i], 1 + total);
623 else
624 isl_seq_neg(c->el, bmap->eq[i], 1 + total);
625 p = print_constraint(bmap, space, div, p, c->el, l,
626 "=", first, latex);
627 first = 0;
629 for (i = 0; i < bmap->n_ineq; ++i) {
630 int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);
631 int strict;
632 int s;
633 const char *op;
634 if (l < 0)
635 continue;
636 if (!p->dump && l >= o_div &&
637 isl_basic_map_is_div_constraint(bmap, bmap->ineq[i],
638 l - o_div))
639 continue;
640 s = isl_int_sgn(bmap->ineq[i][l]);
641 strict = !rational && isl_int_is_negone(bmap->ineq[i][0]);
642 if (s < 0)
643 isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);
644 else
645 isl_seq_neg(c->el, bmap->ineq[i], 1 + total);
646 if (strict)
647 isl_int_set_si(c->el[0], 0);
648 if (!p->dump && next_is_opposite(bmap, i, l)) {
649 op = constraint_op(-s, strict, latex);
650 p = print_half_constraint(bmap, space, div, p, c->el, l,
651 op, first, latex);
652 first = 1;
653 } else {
654 op = constraint_op(s, strict, latex);
655 p = print_constraint(bmap, space, div, p, c->el, l,
656 op, first, latex);
657 first = 0;
661 isl_basic_map_free(bmap);
662 isl_vec_free(c);
664 return p;
665 error:
666 isl_basic_map_free(bmap);
667 isl_vec_free(c);
668 isl_printer_free(p);
669 return NULL;
672 static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
673 __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p)
675 int c;
677 if (!p || !div)
678 return isl_printer_free(p);
680 c = p->output_format == ISL_FORMAT_C;
681 p = isl_printer_print_str(p, c ? "floord(" : "floor((");
682 p = print_affine_of_len(dim, div, p,
683 div->row[pos] + 1, div->n_col - 1);
684 p = isl_printer_print_str(p, c ? ", " : ")/");
685 p = isl_printer_print_isl_int(p, div->row[pos][0]);
686 p = isl_printer_print_str(p, ")");
687 return p;
690 /* Print a comma separated list of div names, except those that have
691 * a definition that can be printed.
692 * If "print_defined_divs" is set, then those div names are printed
693 * as well, along with their definitions.
695 static __isl_give isl_printer *print_div_list(__isl_take isl_printer *p,
696 __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex,
697 int print_defined_divs)
699 int i;
700 int first = 1;
701 unsigned n_div;
703 if (!p || !space || !div)
704 return isl_printer_free(p);
706 n_div = isl_mat_rows(div);
708 for (i = 0; i < n_div; ++i) {
709 if (!print_defined_divs && can_print_div_expr(p, div, i))
710 continue;
711 if (!first)
712 p = isl_printer_print_str(p, ", ");
713 p = print_name(space, p, isl_dim_div, i, latex);
714 first = 0;
715 if (!can_print_div_expr(p, div, i))
716 continue;
717 p = isl_printer_print_str(p, " = ");
718 p = print_div(space, div, i, p);
721 return p;
724 /* Does printing "bmap" require an "exists" clause?
725 * That is, are there any local variables without an explicit representation?
727 static isl_bool need_exists(__isl_keep isl_printer *p,
728 __isl_keep isl_basic_map *bmap, __isl_keep isl_mat *div)
730 int i;
732 if (!p || !bmap)
733 return isl_bool_error;
734 if (bmap->n_div == 0)
735 return isl_bool_false;
736 for (i = 0; i < bmap->n_div; ++i)
737 if (!can_print_div_expr(p, div, i))
738 return isl_bool_true;
739 return isl_bool_false;
742 /* Print the constraints of "bmap" to "p".
743 * The names of the variables are taken from "space".
744 * "latex" is set if the constraints should be printed in LaTeX format.
745 * Do not print inline explicit div representations in "dump" mode.
747 static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
748 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
750 isl_mat *div;
751 isl_bool exists;
753 div = isl_basic_map_get_divs(bmap);
754 if (p->dump)
755 exists = bmap->n_div > 0;
756 else
757 exists = need_exists(p, bmap, div);
758 if (exists >= 0 && exists) {
759 p = isl_printer_print_str(p, s_open_exists[latex]);
760 p = print_div_list(p, space, div, latex, p->dump);
761 p = isl_printer_print_str(p, ": ");
764 if (p->dump)
765 div = isl_mat_free(div);
766 p = print_constraints(bmap, space, div, p, latex);
767 isl_mat_free(div);
769 if (exists >= 0 && exists)
770 p = isl_printer_print_str(p, s_close_exists[latex]);
771 return p;
774 /* Print a colon followed by the constraints of "bmap"
775 * to "p", provided there are any constraints.
776 * The names of the variables are taken from "space".
777 * "latex" is set if the constraints should be printed in LaTeX format.
779 static __isl_give isl_printer *print_optional_disjunct(
780 __isl_keep isl_basic_map *bmap, __isl_keep isl_space *space,
781 __isl_take isl_printer *p, int latex)
783 if (isl_basic_map_is_universe(bmap))
784 return p;
786 p = isl_printer_print_str(p, ": ");
787 p = print_disjunct(bmap, space, p, latex);
789 return p;
792 static __isl_give isl_printer *basic_map_print_omega(
793 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
795 p = isl_printer_print_str(p, "{ [");
796 p = print_var_list(p, bmap->dim, isl_dim_in);
797 p = isl_printer_print_str(p, "] -> [");
798 p = print_var_list(p, bmap->dim, isl_dim_out);
799 p = isl_printer_print_str(p, "] ");
800 p = print_optional_disjunct(bmap, bmap->dim, p, 0);
801 p = isl_printer_print_str(p, " }");
802 return p;
805 static __isl_give isl_printer *basic_set_print_omega(
806 __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
808 p = isl_printer_print_str(p, "{ [");
809 p = print_var_list(p, bset->dim, isl_dim_set);
810 p = isl_printer_print_str(p, "] ");
811 p = print_optional_disjunct(bset, bset->dim, p, 0);
812 p = isl_printer_print_str(p, " }");
813 return p;
816 static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map,
817 __isl_take isl_printer *p)
819 int i;
821 for (i = 0; i < map->n; ++i) {
822 if (i)
823 p = isl_printer_print_str(p, " union ");
824 p = basic_map_print_omega(map->p[i], p);
826 return p;
829 static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set,
830 __isl_take isl_printer *p)
832 int i;
834 for (i = 0; i < set->n; ++i) {
835 if (i)
836 p = isl_printer_print_str(p, " union ");
837 p = basic_set_print_omega(set->p[i], p);
839 return p;
842 static __isl_give isl_printer *isl_basic_map_print_isl(
843 __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p,
844 int latex)
846 struct isl_print_space_data data = { .latex = latex };
847 int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
849 if (isl_basic_map_dim(bmap, isl_dim_param) > 0) {
850 p = print_tuple(bmap->dim, p, isl_dim_param, &data);
851 p = isl_printer_print_str(p, " -> ");
853 p = isl_printer_print_str(p, "{ ");
854 p = isl_print_space(bmap->dim, p, rational, &data);
855 p = isl_printer_print_str(p, " : ");
856 p = print_disjunct(bmap, bmap->dim, p, latex);
857 p = isl_printer_print_str(p, " }");
858 return p;
861 /* Print the disjuncts of a map (or set) "map" to "p".
862 * The names of the variables are taken from "space".
863 * "latex" is set if the constraints should be printed in LaTeX format.
865 static __isl_give isl_printer *print_disjuncts_core(__isl_keep isl_map *map,
866 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
868 int i;
870 if (map->n == 0)
871 p = isl_printer_print_str(p, "1 = 0");
872 for (i = 0; i < map->n; ++i) {
873 if (i)
874 p = isl_printer_print_str(p, s_or[latex]);
875 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
876 p = isl_printer_print_str(p, "(");
877 p = print_disjunct(map->p[i], space, p, latex);
878 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
879 p = isl_printer_print_str(p, ")");
881 return p;
884 /* Print the disjuncts of a map (or set) "map" to "p".
885 * The names of the variables are taken from "space".
886 * "hull" describes constraints shared by all disjuncts of "map".
887 * "latex" is set if the constraints should be printed in LaTeX format.
889 * Print the disjuncts as a conjunction of "hull" and
890 * the result of removing the constraints of "hull" from "map".
891 * If this result turns out to be the universe, then simply print "hull".
893 static __isl_give isl_printer *print_disjuncts_in_hull(__isl_keep isl_map *map,
894 __isl_keep isl_space *space, __isl_take isl_basic_map *hull,
895 __isl_take isl_printer *p, int latex)
897 isl_bool is_universe;
899 p = print_disjunct(hull, space, p, latex);
900 map = isl_map_plain_gist_basic_map(isl_map_copy(map), hull);
901 is_universe = isl_map_plain_is_universe(map);
902 if (is_universe < 0)
903 goto error;
904 if (!is_universe) {
905 p = isl_printer_print_str(p, s_and[latex]);
906 p = isl_printer_print_str(p, "(");
907 p = print_disjuncts_core(map, space, p, latex);
908 p = isl_printer_print_str(p, ")");
910 isl_map_free(map);
912 return p;
913 error:
914 isl_map_free(map);
915 isl_printer_free(p);
916 return NULL;
919 /* Print the disjuncts of a map (or set) "map" to "p".
920 * The names of the variables are taken from "space".
921 * "latex" is set if the constraints should be printed in LaTeX format.
923 * If there are at least two disjuncts and "dump" mode is not turned out,
924 * check for any shared constraints among all disjuncts.
925 * If there are any, then print them separately in print_disjuncts_in_hull.
927 static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
928 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
930 if (isl_map_plain_is_universe(map))
931 return p;
933 p = isl_printer_print_str(p, s_such_that[latex]);
935 if (!p->dump && map->n >= 2) {
936 isl_basic_map *hull;
937 isl_bool is_universe;
939 hull = isl_map_plain_unshifted_simple_hull(isl_map_copy(map));
940 is_universe = isl_basic_map_is_universe(hull);
941 if (is_universe < 0)
942 p = isl_printer_free(p);
943 else if (!is_universe)
944 return print_disjuncts_in_hull(map, space, hull,
945 p, latex);
946 isl_basic_map_free(hull);
949 return print_disjuncts_core(map, space, p, latex);
952 /* Print the disjuncts of a map (or set).
953 * The names of the variables are taken from "space".
954 * "latex" is set if the constraints should be printed in LaTeX format.
956 * If the map turns out to be a universal parameter domain, then
957 * we need to print the colon. Otherwise, the output looks identical
958 * to the empty set.
960 static __isl_give isl_printer *print_disjuncts_map(__isl_keep isl_map *map,
961 __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
963 if (isl_map_plain_is_universe(map) && isl_space_is_params(map->dim))
964 return isl_printer_print_str(p, s_such_that[latex]);
965 else
966 return print_disjuncts(map, space, p, latex);
969 struct isl_aff_split {
970 isl_basic_map *aff;
971 isl_map *map;
974 static void free_split(__isl_take struct isl_aff_split *split, int n)
976 int i;
978 if (!split)
979 return;
981 for (i = 0; i < n; ++i) {
982 isl_basic_map_free(split[i].aff);
983 isl_map_free(split[i].map);
986 free(split);
989 static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap)
991 int i, j;
992 unsigned nparam, n_in, n_out, total;
994 bmap = isl_basic_map_cow(bmap);
995 if (!bmap)
996 return NULL;
997 if (isl_basic_map_free_inequality(bmap, bmap->n_ineq) < 0)
998 goto error;
1000 nparam = isl_basic_map_dim(bmap, isl_dim_param);
1001 n_in = isl_basic_map_dim(bmap, isl_dim_in);
1002 n_out = isl_basic_map_dim(bmap, isl_dim_out);
1003 total = isl_basic_map_dim(bmap, isl_dim_all);
1004 for (i = bmap->n_eq - 1; i >= 0; --i) {
1005 j = isl_seq_last_non_zero(bmap->eq[i] + 1, total);
1006 if (j >= nparam && j < nparam + n_in + n_out &&
1007 (isl_int_is_one(bmap->eq[i][1 + j]) ||
1008 isl_int_is_negone(bmap->eq[i][1 + j])))
1009 continue;
1010 if (isl_basic_map_drop_equality(bmap, i) < 0)
1011 goto error;
1014 bmap = isl_basic_map_finalize(bmap);
1016 return bmap;
1017 error:
1018 isl_basic_map_free(bmap);
1019 return NULL;
1022 static int aff_split_cmp(const void *p1, const void *p2, void *user)
1024 const struct isl_aff_split *s1, *s2;
1025 s1 = (const struct isl_aff_split *) p1;
1026 s2 = (const struct isl_aff_split *) p2;
1028 return isl_basic_map_plain_cmp(s1->aff, s2->aff);
1031 static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap,
1032 __isl_keep isl_basic_map *aff)
1034 int i, j;
1035 unsigned total;
1037 if (!bmap || !aff)
1038 goto error;
1040 total = isl_space_dim(bmap->dim, isl_dim_all);
1042 for (i = bmap->n_eq - 1; i >= 0; --i) {
1043 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + total,
1044 bmap->n_div) != -1)
1045 continue;
1046 for (j = 0; j < aff->n_eq; ++j) {
1047 if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + total) &&
1048 !isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + total))
1049 continue;
1050 if (isl_basic_map_drop_equality(bmap, i) < 0)
1051 goto error;
1052 break;
1056 return bmap;
1057 error:
1058 isl_basic_map_free(bmap);
1059 return NULL;
1062 static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map)
1064 int i, n;
1065 struct isl_aff_split *split;
1066 isl_ctx *ctx;
1068 ctx = isl_map_get_ctx(map);
1069 split = isl_calloc_array(ctx, struct isl_aff_split, map->n);
1070 if (!split)
1071 return NULL;
1073 for (i = 0; i < map->n; ++i) {
1074 isl_basic_map *bmap;
1075 split[i].aff = get_aff(isl_basic_map_copy(map->p[i]));
1076 bmap = isl_basic_map_copy(map->p[i]);
1077 bmap = isl_basic_map_cow(bmap);
1078 bmap = drop_aff(bmap, split[i].aff);
1079 split[i].map = isl_map_from_basic_map(bmap);
1080 if (!split[i].aff || !split[i].map)
1081 goto error;
1084 if (isl_sort(split, map->n, sizeof(struct isl_aff_split),
1085 &aff_split_cmp, NULL) < 0)
1086 goto error;
1088 n = map->n;
1089 for (i = n - 1; i >= 1; --i) {
1090 if (!isl_basic_map_plain_is_equal(split[i - 1].aff,
1091 split[i].aff))
1092 continue;
1093 isl_basic_map_free(split[i].aff);
1094 split[i - 1].map = isl_map_union(split[i - 1].map,
1095 split[i].map);
1096 if (i != n - 1)
1097 split[i] = split[n - 1];
1098 split[n - 1].aff = NULL;
1099 split[n - 1].map = NULL;
1100 --n;
1103 return split;
1104 error:
1105 free_split(split, map->n);
1106 return NULL;
1109 static int defining_equality(__isl_keep isl_basic_map *eq,
1110 __isl_keep isl_space *dim, enum isl_dim_type type, int pos)
1112 int i;
1113 unsigned total;
1115 if (!eq)
1116 return -1;
1118 pos += isl_space_offset(dim, type);
1119 total = isl_basic_map_total_dim(eq);
1121 for (i = 0; i < eq->n_eq; ++i) {
1122 if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos)
1123 continue;
1124 if (isl_int_is_one(eq->eq[i][1 + pos]))
1125 isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total);
1126 return i;
1129 return -1;
1132 /* Print dimension "pos" of data->space to "p".
1134 * data->user is assumed to be an isl_basic_map keeping track of equalities.
1136 * If the current dimension is defined by these equalities, then print
1137 * the corresponding expression. Otherwise, print the name of the dimension.
1139 static __isl_give isl_printer *print_dim_eq(__isl_take isl_printer *p,
1140 struct isl_print_space_data *data, unsigned pos)
1142 isl_basic_map *eq = data->user;
1143 int j;
1145 j = defining_equality(eq, data->space, data->type, pos);
1146 if (j >= 0) {
1147 pos += 1 + isl_space_offset(data->space, data->type);
1148 p = print_affine_of_len(eq->dim, NULL, p, eq->eq[j], pos);
1149 } else {
1150 p = print_name(data->space, p, data->type, pos, data->latex);
1153 return p;
1156 static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p,
1157 struct isl_aff_split *split, int n, __isl_keep isl_space *space)
1159 struct isl_print_space_data data = { 0 };
1160 int i;
1161 int rational;
1163 data.print_dim = &print_dim_eq;
1164 for (i = 0; i < n; ++i) {
1165 if (!split[i].map)
1166 break;
1167 rational = split[i].map->n > 0 &&
1168 ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL);
1169 if (i)
1170 p = isl_printer_print_str(p, "; ");
1171 data.user = split[i].aff;
1172 p = isl_print_space(space, p, rational, &data);
1173 p = print_disjuncts_map(split[i].map, space, p, 0);
1176 return p;
1179 static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map,
1180 __isl_take isl_printer *p)
1182 struct isl_print_space_data data = { 0 };
1183 struct isl_aff_split *split = NULL;
1184 int rational;
1186 if (!p->dump && map->n > 0)
1187 split = split_aff(map);
1188 if (split) {
1189 p = print_split_map(p, split, map->n, map->dim);
1190 } else {
1191 rational = map->n > 0 &&
1192 ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL);
1193 p = isl_print_space(map->dim, p, rational, &data);
1194 p = print_disjuncts_map(map, map->dim, p, 0);
1196 free_split(split, map->n);
1197 return p;
1200 static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,
1201 __isl_take isl_printer *p)
1203 struct isl_print_space_data data = { 0 };
1205 if (isl_map_dim(map, isl_dim_param) > 0) {
1206 p = print_tuple(map->dim, p, isl_dim_param, &data);
1207 p = isl_printer_print_str(p, s_to[0]);
1209 p = isl_printer_print_str(p, s_open_set[0]);
1210 p = isl_map_print_isl_body(map, p);
1211 p = isl_printer_print_str(p, s_close_set[0]);
1212 return p;
1215 static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map,
1216 __isl_take isl_printer *p, __isl_keep isl_basic_map *aff)
1218 struct isl_print_space_data data = { 0 };
1220 data.latex = 1;
1221 if (isl_map_dim(map, isl_dim_param) > 0) {
1222 p = print_tuple(map->dim, p, isl_dim_param, &data);
1223 p = isl_printer_print_str(p, s_to[1]);
1225 p = isl_printer_print_str(p, s_open_set[1]);
1226 data.print_dim = &print_dim_eq;
1227 data.user = aff;
1228 p = isl_print_space(map->dim, p, 0, &data);
1229 p = print_disjuncts_map(map, map->dim, p, 1);
1230 p = isl_printer_print_str(p, s_close_set[1]);
1232 return p;
1235 static __isl_give isl_printer *isl_map_print_latex(__isl_keep isl_map *map,
1236 __isl_take isl_printer *p)
1238 int i;
1239 struct isl_aff_split *split = NULL;
1241 if (map->n > 0)
1242 split = split_aff(map);
1244 if (!split)
1245 return print_latex_map(map, p, NULL);
1247 for (i = 0; i < map->n; ++i) {
1248 if (!split[i].map)
1249 break;
1250 if (i)
1251 p = isl_printer_print_str(p, " \\cup ");
1252 p = print_latex_map(split[i].map, p, split[i].aff);
1255 free_split(split, map->n);
1256 return p;
1259 __isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p,
1260 __isl_keep isl_basic_map *bmap)
1262 if (!p || !bmap)
1263 goto error;
1264 if (p->output_format == ISL_FORMAT_ISL)
1265 return isl_basic_map_print_isl(bmap, p, 0);
1266 else if (p->output_format == ISL_FORMAT_OMEGA)
1267 return basic_map_print_omega(bmap, p);
1268 isl_assert(bmap->ctx, 0, goto error);
1269 error:
1270 isl_printer_free(p);
1271 return NULL;
1274 __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,
1275 __isl_keep isl_basic_set *bset)
1277 if (!p || !bset)
1278 goto error;
1280 if (p->output_format == ISL_FORMAT_ISL)
1281 return isl_basic_map_print_isl(bset, p, 0);
1282 else if (p->output_format == ISL_FORMAT_POLYLIB)
1283 return isl_basic_set_print_polylib(bset, p, 0);
1284 else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1285 return isl_basic_set_print_polylib(bset, p, 1);
1286 else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)
1287 return bset_print_constraints_polylib(bset, p);
1288 else if (p->output_format == ISL_FORMAT_OMEGA)
1289 return basic_set_print_omega(bset, p);
1290 isl_assert(p->ctx, 0, goto error);
1291 error:
1292 isl_printer_free(p);
1293 return NULL;
1296 __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,
1297 __isl_keep isl_set *set)
1299 if (!p || !set)
1300 goto error;
1301 if (p->output_format == ISL_FORMAT_ISL)
1302 return isl_map_print_isl((isl_map *)set, p);
1303 else if (p->output_format == ISL_FORMAT_POLYLIB)
1304 return isl_set_print_polylib(set, p, 0);
1305 else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1306 return isl_set_print_polylib(set, p, 1);
1307 else if (p->output_format == ISL_FORMAT_OMEGA)
1308 return isl_set_print_omega(set, p);
1309 else if (p->output_format == ISL_FORMAT_LATEX)
1310 return isl_map_print_latex((isl_map *)set, p);
1311 isl_assert(set->ctx, 0, goto error);
1312 error:
1313 isl_printer_free(p);
1314 return NULL;
1317 __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
1318 __isl_keep isl_map *map)
1320 if (!p || !map)
1321 goto error;
1323 if (p->output_format == ISL_FORMAT_ISL)
1324 return isl_map_print_isl(map, p);
1325 else if (p->output_format == ISL_FORMAT_POLYLIB)
1326 return isl_map_print_polylib(map, p, 0);
1327 else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1328 return isl_map_print_polylib(map, p, 1);
1329 else if (p->output_format == ISL_FORMAT_OMEGA)
1330 return isl_map_print_omega(map, p);
1331 else if (p->output_format == ISL_FORMAT_LATEX)
1332 return isl_map_print_latex(map, p);
1333 isl_assert(map->ctx, 0, goto error);
1334 error:
1335 isl_printer_free(p);
1336 return NULL;
1339 struct isl_union_print_data {
1340 isl_printer *p;
1341 int first;
1344 static isl_stat print_map_body(__isl_take isl_map *map, void *user)
1346 struct isl_union_print_data *data;
1347 data = (struct isl_union_print_data *)user;
1349 if (!data->first)
1350 data->p = isl_printer_print_str(data->p, "; ");
1351 data->first = 0;
1353 data->p = isl_map_print_isl_body(map, data->p);
1354 isl_map_free(map);
1356 return isl_stat_ok;
1359 static __isl_give isl_printer *isl_union_map_print_isl(
1360 __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
1362 struct isl_union_print_data data;
1363 struct isl_print_space_data space_data = { 0 };
1364 isl_space *dim;
1366 dim = isl_union_map_get_space(umap);
1367 if (isl_space_dim(dim, isl_dim_param) > 0) {
1368 p = print_tuple(dim, p, isl_dim_param, &space_data);
1369 p = isl_printer_print_str(p, s_to[0]);
1371 isl_space_free(dim);
1372 p = isl_printer_print_str(p, s_open_set[0]);
1373 data.p = p;
1374 data.first = 1;
1375 isl_union_map_foreach_map(umap, &print_map_body, &data);
1376 p = data.p;
1377 p = isl_printer_print_str(p, s_close_set[0]);
1378 return p;
1381 static isl_stat print_latex_map_body(__isl_take isl_map *map, void *user)
1383 struct isl_union_print_data *data;
1384 data = (struct isl_union_print_data *)user;
1386 if (!data->first)
1387 data->p = isl_printer_print_str(data->p, " \\cup ");
1388 data->first = 0;
1390 data->p = isl_map_print_latex(map, data->p);
1391 isl_map_free(map);
1393 return isl_stat_ok;
1396 static __isl_give isl_printer *isl_union_map_print_latex(
1397 __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
1399 struct isl_union_print_data data = { p, 1 };
1400 isl_union_map_foreach_map(umap, &print_latex_map_body, &data);
1401 p = data.p;
1402 return p;
1405 __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p,
1406 __isl_keep isl_union_map *umap)
1408 if (!p || !umap)
1409 goto error;
1411 if (p->output_format == ISL_FORMAT_ISL)
1412 return isl_union_map_print_isl(umap, p);
1413 if (p->output_format == ISL_FORMAT_LATEX)
1414 return isl_union_map_print_latex(umap, p);
1416 isl_die(p->ctx, isl_error_invalid,
1417 "invalid output format for isl_union_map", goto error);
1418 error:
1419 isl_printer_free(p);
1420 return NULL;
1423 __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
1424 __isl_keep isl_union_set *uset)
1426 if (!p || !uset)
1427 goto error;
1429 if (p->output_format == ISL_FORMAT_ISL)
1430 return isl_union_map_print_isl((isl_union_map *)uset, p);
1431 if (p->output_format == ISL_FORMAT_LATEX)
1432 return isl_union_map_print_latex((isl_union_map *)uset, p);
1434 isl_die(p->ctx, isl_error_invalid,
1435 "invalid output format for isl_union_set", goto error);
1436 error:
1437 isl_printer_free(p);
1438 return NULL;
1441 static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec)
1443 int i;
1444 int n;
1446 for (i = 0, n = 0; i < rec->n; ++i)
1447 if (!isl_upoly_is_zero(rec->p[i]))
1448 ++n;
1450 return n;
1453 static __isl_give isl_printer *upoly_print_cst(__isl_keep struct isl_upoly *up,
1454 __isl_take isl_printer *p, int first)
1456 struct isl_upoly_cst *cst;
1457 int neg;
1459 cst = isl_upoly_as_cst(up);
1460 if (!cst)
1461 goto error;
1462 neg = !first && isl_int_is_neg(cst->n);
1463 if (!first)
1464 p = isl_printer_print_str(p, neg ? " - " : " + ");
1465 if (neg)
1466 isl_int_neg(cst->n, cst->n);
1467 if (isl_int_is_zero(cst->d)) {
1468 int sgn = isl_int_sgn(cst->n);
1469 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
1470 sgn == 0 ? "NaN" : "infty");
1471 } else
1472 p = isl_printer_print_isl_int(p, cst->n);
1473 if (neg)
1474 isl_int_neg(cst->n, cst->n);
1475 if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) {
1476 p = isl_printer_print_str(p, "/");
1477 p = isl_printer_print_isl_int(p, cst->d);
1479 return p;
1480 error:
1481 isl_printer_free(p);
1482 return NULL;
1485 static __isl_give isl_printer *print_base(__isl_take isl_printer *p,
1486 __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var)
1488 unsigned total;
1490 total = isl_space_dim(dim, isl_dim_all);
1491 if (var < total)
1492 p = print_term(dim, NULL, dim->ctx->one, 1 + var, p, 0);
1493 else
1494 p = print_div(dim, div, var - total, p);
1495 return p;
1498 static __isl_give isl_printer *print_pow(__isl_take isl_printer *p,
1499 __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var, int exp)
1501 p = print_base(p, dim, div, var);
1502 if (exp == 1)
1503 return p;
1504 if (p->output_format == ISL_FORMAT_C) {
1505 int i;
1506 for (i = 1; i < exp; ++i) {
1507 p = isl_printer_print_str(p, "*");
1508 p = print_base(p, dim, div, var);
1510 } else {
1511 p = isl_printer_print_str(p, "^");
1512 p = isl_printer_print_int(p, exp);
1514 return p;
1517 static __isl_give isl_printer *upoly_print(__isl_keep struct isl_upoly *up,
1518 __isl_keep isl_space *dim, __isl_keep isl_mat *div,
1519 __isl_take isl_printer *p, int outer)
1521 int i, n, first, print_parens;
1522 struct isl_upoly_rec *rec;
1524 if (!p || !up || !dim || !div)
1525 goto error;
1527 if (isl_upoly_is_cst(up))
1528 return upoly_print_cst(up, p, 1);
1530 rec = isl_upoly_as_rec(up);
1531 if (!rec)
1532 goto error;
1533 n = upoly_rec_n_non_zero(rec);
1534 print_parens = n > 1 ||
1535 (outer && rec->up.var >= isl_space_dim(dim, isl_dim_all));
1536 if (print_parens)
1537 p = isl_printer_print_str(p, "(");
1538 for (i = 0, first = 1; i < rec->n; ++i) {
1539 if (isl_upoly_is_zero(rec->p[i]))
1540 continue;
1541 if (isl_upoly_is_negone(rec->p[i])) {
1542 if (!i)
1543 p = isl_printer_print_str(p, "-1");
1544 else if (first)
1545 p = isl_printer_print_str(p, "-");
1546 else
1547 p = isl_printer_print_str(p, " - ");
1548 } else if (isl_upoly_is_cst(rec->p[i]) &&
1549 !isl_upoly_is_one(rec->p[i]))
1550 p = upoly_print_cst(rec->p[i], p, first);
1551 else {
1552 if (!first)
1553 p = isl_printer_print_str(p, " + ");
1554 if (i == 0 || !isl_upoly_is_one(rec->p[i]))
1555 p = upoly_print(rec->p[i], dim, div, p, 0);
1557 first = 0;
1558 if (i == 0)
1559 continue;
1560 if (!isl_upoly_is_one(rec->p[i]) &&
1561 !isl_upoly_is_negone(rec->p[i]))
1562 p = isl_printer_print_str(p, " * ");
1563 p = print_pow(p, dim, div, rec->up.var, i);
1565 if (print_parens)
1566 p = isl_printer_print_str(p, ")");
1567 return p;
1568 error:
1569 isl_printer_free(p);
1570 return NULL;
1573 static __isl_give isl_printer *print_qpolynomial(__isl_take isl_printer *p,
1574 __isl_keep isl_qpolynomial *qp)
1576 if (!p || !qp)
1577 goto error;
1578 p = upoly_print(qp->upoly, qp->dim, qp->div, p, 1);
1579 return p;
1580 error:
1581 isl_printer_free(p);
1582 return NULL;
1585 static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p,
1586 __isl_keep isl_qpolynomial *qp)
1588 struct isl_print_space_data data = { 0 };
1590 if (!p || !qp)
1591 goto error;
1593 if (isl_space_dim(qp->dim, isl_dim_param) > 0) {
1594 p = print_tuple(qp->dim, p, isl_dim_param, &data);
1595 p = isl_printer_print_str(p, " -> ");
1597 p = isl_printer_print_str(p, "{ ");
1598 if (!isl_space_is_params(qp->dim)) {
1599 p = isl_print_space(qp->dim, p, 0, &data);
1600 p = isl_printer_print_str(p, " -> ");
1602 p = print_qpolynomial(p, qp);
1603 p = isl_printer_print_str(p, " }");
1604 return p;
1605 error:
1606 isl_printer_free(p);
1607 return NULL;
1610 static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p,
1611 __isl_keep isl_space *dim, __isl_keep isl_qpolynomial *qp)
1613 isl_int den;
1615 isl_int_init(den);
1616 isl_qpolynomial_get_den(qp, &den);
1617 if (!isl_int_is_one(den)) {
1618 isl_qpolynomial *f;
1619 p = isl_printer_print_str(p, "(");
1620 qp = isl_qpolynomial_copy(qp);
1621 f = isl_qpolynomial_rat_cst_on_domain(isl_space_copy(qp->dim),
1622 den, qp->dim->ctx->one);
1623 qp = isl_qpolynomial_mul(qp, f);
1625 if (qp)
1626 p = upoly_print(qp->upoly, dim, qp->div, p, 0);
1627 else
1628 p = isl_printer_free(p);
1629 if (!isl_int_is_one(den)) {
1630 p = isl_printer_print_str(p, ")/");
1631 p = isl_printer_print_isl_int(p, den);
1632 isl_qpolynomial_free(qp);
1634 isl_int_clear(den);
1635 return p;
1638 __isl_give isl_printer *isl_printer_print_qpolynomial(
1639 __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp)
1641 if (!p || !qp)
1642 goto error;
1644 if (p->output_format == ISL_FORMAT_ISL)
1645 return print_qpolynomial_isl(p, qp);
1646 else if (p->output_format == ISL_FORMAT_C)
1647 return print_qpolynomial_c(p, qp->dim, qp);
1648 else
1649 isl_die(qp->dim->ctx, isl_error_unsupported,
1650 "output format not supported for isl_qpolynomials",
1651 goto error);
1652 error:
1653 isl_printer_free(p);
1654 return NULL;
1657 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
1658 unsigned output_format)
1660 isl_printer *p;
1662 if (!qp)
1663 return;
1665 isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1666 p = isl_printer_to_file(qp->dim->ctx, out);
1667 p = isl_printer_print_qpolynomial(p, qp);
1668 isl_printer_free(p);
1671 static __isl_give isl_printer *qpolynomial_fold_print(
1672 __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
1674 int i;
1676 if (fold->type == isl_fold_min)
1677 p = isl_printer_print_str(p, "min");
1678 else if (fold->type == isl_fold_max)
1679 p = isl_printer_print_str(p, "max");
1680 p = isl_printer_print_str(p, "(");
1681 for (i = 0; i < fold->n; ++i) {
1682 if (i)
1683 p = isl_printer_print_str(p, ", ");
1684 p = print_qpolynomial(p, fold->qp[i]);
1686 p = isl_printer_print_str(p, ")");
1687 return p;
1690 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
1691 FILE *out, unsigned output_format)
1693 isl_printer *p;
1695 if (!fold)
1696 return;
1698 isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1700 p = isl_printer_to_file(fold->dim->ctx, out);
1701 p = isl_printer_print_qpolynomial_fold(p, fold);
1703 isl_printer_free(p);
1706 static __isl_give isl_printer *isl_pwqp_print_isl_body(
1707 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1709 struct isl_print_space_data data = { 0 };
1710 int i = 0;
1712 for (i = 0; i < pwqp->n; ++i) {
1713 isl_space *space;
1715 if (i)
1716 p = isl_printer_print_str(p, "; ");
1717 space = isl_qpolynomial_get_domain_space(pwqp->p[i].qp);
1718 if (!isl_space_is_params(space)) {
1719 p = isl_print_space(space, p, 0, &data);
1720 p = isl_printer_print_str(p, " -> ");
1722 p = print_qpolynomial(p, pwqp->p[i].qp);
1723 p = print_disjuncts((isl_map *)pwqp->p[i].set, space, p, 0);
1724 isl_space_free(space);
1727 return p;
1730 static __isl_give isl_printer *print_pw_qpolynomial_isl(
1731 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1733 struct isl_print_space_data data = { 0 };
1735 if (!p || !pwqp)
1736 goto error;
1738 if (isl_space_dim(pwqp->dim, isl_dim_param) > 0) {
1739 p = print_tuple(pwqp->dim, p, isl_dim_param, &data);
1740 p = isl_printer_print_str(p, " -> ");
1742 p = isl_printer_print_str(p, "{ ");
1743 if (pwqp->n == 0) {
1744 if (!isl_space_is_set(pwqp->dim)) {
1745 p = print_tuple(pwqp->dim, p, isl_dim_in, &data);
1746 p = isl_printer_print_str(p, " -> ");
1748 p = isl_printer_print_str(p, "0");
1750 p = isl_pwqp_print_isl_body(p, pwqp);
1751 p = isl_printer_print_str(p, " }");
1752 return p;
1753 error:
1754 isl_printer_free(p);
1755 return NULL;
1758 void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
1759 unsigned output_format)
1761 isl_printer *p;
1763 if (!pwqp)
1764 return;
1766 p = isl_printer_to_file(pwqp->dim->ctx, out);
1767 p = isl_printer_set_output_format(p, output_format);
1768 p = isl_printer_print_pw_qpolynomial(p, pwqp);
1770 isl_printer_free(p);
1773 static __isl_give isl_printer *isl_pwf_print_isl_body(
1774 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1776 struct isl_print_space_data data = { 0 };
1777 int i = 0;
1779 for (i = 0; i < pwf->n; ++i) {
1780 isl_space *space;
1782 if (i)
1783 p = isl_printer_print_str(p, "; ");
1784 space = isl_qpolynomial_fold_get_domain_space(pwf->p[i].fold);
1785 if (!isl_space_is_params(space)) {
1786 p = isl_print_space(space, p, 0, &data);
1787 p = isl_printer_print_str(p, " -> ");
1789 p = qpolynomial_fold_print(pwf->p[i].fold, p);
1790 p = print_disjuncts((isl_map *)pwf->p[i].set, space, p, 0);
1791 isl_space_free(space);
1794 return p;
1797 static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(
1798 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1800 struct isl_print_space_data data = { 0 };
1802 if (isl_space_dim(pwf->dim, isl_dim_param) > 0) {
1803 p = print_tuple(pwf->dim, p, isl_dim_param, &data);
1804 p = isl_printer_print_str(p, " -> ");
1806 p = isl_printer_print_str(p, "{ ");
1807 if (pwf->n == 0) {
1808 if (!isl_space_is_set(pwf->dim)) {
1809 p = print_tuple(pwf->dim, p, isl_dim_in, &data);
1810 p = isl_printer_print_str(p, " -> ");
1812 p = isl_printer_print_str(p, "0");
1814 p = isl_pwf_print_isl_body(p, pwf);
1815 p = isl_printer_print_str(p, " }");
1816 return p;
1819 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1820 __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c);
1822 static __isl_give isl_printer *print_name_c(__isl_take isl_printer *p,
1823 __isl_keep isl_space *dim,
1824 __isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos)
1826 if (type == isl_dim_div) {
1827 p = isl_printer_print_str(p, "floord(");
1828 p = print_affine_c(p, dim, bset, bset->div[pos] + 1);
1829 p = isl_printer_print_str(p, ", ");
1830 p = isl_printer_print_isl_int(p, bset->div[pos][0]);
1831 p = isl_printer_print_str(p, ")");
1832 } else {
1833 const char *name;
1835 name = isl_space_get_dim_name(dim, type, pos);
1836 if (!name)
1837 name = "UNNAMED";
1838 p = isl_printer_print_str(p, name);
1840 return p;
1843 static __isl_give isl_printer *print_term_c(__isl_take isl_printer *p,
1844 __isl_keep isl_space *dim,
1845 __isl_keep isl_basic_set *bset, isl_int c, unsigned pos)
1847 enum isl_dim_type type;
1849 if (pos == 0)
1850 return isl_printer_print_isl_int(p, c);
1852 if (isl_int_is_one(c))
1854 else if (isl_int_is_negone(c))
1855 p = isl_printer_print_str(p, "-");
1856 else {
1857 p = isl_printer_print_isl_int(p, c);
1858 p = isl_printer_print_str(p, "*");
1860 type = pos2type(dim, &pos);
1861 p = print_name_c(p, dim, bset, type, pos);
1862 return p;
1865 static __isl_give isl_printer *print_partial_affine_c(__isl_take isl_printer *p,
1866 __isl_keep isl_space *dim,
1867 __isl_keep isl_basic_set *bset, isl_int *c, unsigned len)
1869 int i;
1870 int first;
1872 for (i = 0, first = 1; i < len; ++i) {
1873 int flip = 0;
1874 if (isl_int_is_zero(c[i]))
1875 continue;
1876 if (!first) {
1877 if (isl_int_is_neg(c[i])) {
1878 flip = 1;
1879 isl_int_neg(c[i], c[i]);
1880 p = isl_printer_print_str(p, " - ");
1881 } else
1882 p = isl_printer_print_str(p, " + ");
1884 first = 0;
1885 p = print_term_c(p, dim, bset, c[i], i);
1886 if (flip)
1887 isl_int_neg(c[i], c[i]);
1889 if (first)
1890 p = isl_printer_print_str(p, "0");
1891 return p;
1894 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1895 __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c)
1897 unsigned len = 1 + isl_basic_set_total_dim(bset);
1898 return print_partial_affine_c(p, dim, bset, c, len);
1901 /* We skip the constraint if it is implied by the div expression.
1903 * *first indicates whether this is the first constraint in the conjunction and
1904 * is updated if the constraint is actually printed.
1906 static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,
1907 __isl_keep isl_space *dim,
1908 __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int *first)
1910 unsigned o_div;
1911 unsigned n_div;
1912 int div;
1914 o_div = isl_basic_set_offset(bset, isl_dim_div);
1915 n_div = isl_basic_set_dim(bset, isl_dim_div);
1916 div = isl_seq_last_non_zero(c + o_div, n_div);
1917 if (div >= 0 && isl_basic_set_is_div_constraint(bset, c, div))
1918 return p;
1920 if (!*first)
1921 p = isl_printer_print_str(p, " && ");
1923 p = print_affine_c(p, dim, bset, c);
1924 p = isl_printer_print_str(p, " ");
1925 p = isl_printer_print_str(p, op);
1926 p = isl_printer_print_str(p, " 0");
1928 *first = 0;
1930 return p;
1933 static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,
1934 __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset)
1936 int i, j;
1937 int first = 1;
1938 unsigned n_div = isl_basic_set_dim(bset, isl_dim_div);
1939 unsigned total = isl_basic_set_total_dim(bset) - n_div;
1941 for (i = 0; i < bset->n_eq; ++i) {
1942 j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div);
1943 if (j < 0)
1944 p = print_constraint_c(p, dim, bset,
1945 bset->eq[i], "==", &first);
1946 else {
1947 if (i)
1948 p = isl_printer_print_str(p, " && ");
1949 p = isl_printer_print_str(p, "(");
1950 p = print_partial_affine_c(p, dim, bset, bset->eq[i],
1951 1 + total + j);
1952 p = isl_printer_print_str(p, ") % ");
1953 p = isl_printer_print_isl_int(p,
1954 bset->eq[i][1 + total + j]);
1955 p = isl_printer_print_str(p, " == 0");
1956 first = 0;
1959 for (i = 0; i < bset->n_ineq; ++i)
1960 p = print_constraint_c(p, dim, bset, bset->ineq[i], ">=",
1961 &first);
1962 return p;
1965 static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,
1966 __isl_keep isl_space *dim, __isl_keep isl_set *set)
1968 int i;
1970 if (!set)
1971 return isl_printer_free(p);
1973 if (set->n == 0)
1974 p = isl_printer_print_str(p, "0");
1976 for (i = 0; i < set->n; ++i) {
1977 if (i)
1978 p = isl_printer_print_str(p, " || ");
1979 if (set->n > 1)
1980 p = isl_printer_print_str(p, "(");
1981 p = print_basic_set_c(p, dim, set->p[i]);
1982 if (set->n > 1)
1983 p = isl_printer_print_str(p, ")");
1985 return p;
1988 static __isl_give isl_printer *print_pw_qpolynomial_c(
1989 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1991 int i;
1993 if (pwqp->n == 1 && isl_set_plain_is_universe(pwqp->p[0].set))
1994 return print_qpolynomial_c(p, pwqp->dim, pwqp->p[0].qp);
1996 for (i = 0; i < pwqp->n; ++i) {
1997 p = isl_printer_print_str(p, "(");
1998 p = print_set_c(p, pwqp->dim, pwqp->p[i].set);
1999 p = isl_printer_print_str(p, ") ? (");
2000 p = print_qpolynomial_c(p, pwqp->dim, pwqp->p[i].qp);
2001 p = isl_printer_print_str(p, ") : ");
2004 p = isl_printer_print_str(p, "0");
2005 return p;
2008 __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
2009 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
2011 if (!p || !pwqp)
2012 goto error;
2014 if (p->output_format == ISL_FORMAT_ISL)
2015 return print_pw_qpolynomial_isl(p, pwqp);
2016 else if (p->output_format == ISL_FORMAT_C)
2017 return print_pw_qpolynomial_c(p, pwqp);
2018 isl_assert(p->ctx, 0, goto error);
2019 error:
2020 isl_printer_free(p);
2021 return NULL;
2024 static isl_stat print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user)
2026 struct isl_union_print_data *data;
2027 data = (struct isl_union_print_data *)user;
2029 if (!data->first)
2030 data->p = isl_printer_print_str(data->p, "; ");
2031 data->first = 0;
2033 data->p = isl_pwqp_print_isl_body(data->p, pwqp);
2034 isl_pw_qpolynomial_free(pwqp);
2036 return isl_stat_ok;
2039 static __isl_give isl_printer *print_union_pw_qpolynomial_isl(
2040 __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
2042 struct isl_union_print_data data;
2043 struct isl_print_space_data space_data = { 0 };
2044 isl_space *dim;
2046 dim = isl_union_pw_qpolynomial_get_space(upwqp);
2047 if (isl_space_dim(dim, isl_dim_param) > 0) {
2048 p = print_tuple(dim, p, isl_dim_param, &space_data);
2049 p = isl_printer_print_str(p, " -> ");
2051 isl_space_free(dim);
2052 p = isl_printer_print_str(p, "{ ");
2053 data.p = p;
2054 data.first = 1;
2055 isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body,
2056 &data);
2057 p = data.p;
2058 p = isl_printer_print_str(p, " }");
2059 return p;
2062 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial(
2063 __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
2065 if (!p || !upwqp)
2066 goto error;
2068 if (p->output_format == ISL_FORMAT_ISL)
2069 return print_union_pw_qpolynomial_isl(p, upwqp);
2070 isl_die(p->ctx, isl_error_invalid,
2071 "invalid output format for isl_union_pw_qpolynomial",
2072 goto error);
2073 error:
2074 isl_printer_free(p);
2075 return NULL;
2078 static __isl_give isl_printer *print_qpolynomial_fold_c(
2079 __isl_take isl_printer *p, __isl_keep isl_space *dim,
2080 __isl_keep isl_qpolynomial_fold *fold)
2082 int i;
2084 for (i = 0; i < fold->n - 1; ++i)
2085 if (fold->type == isl_fold_min)
2086 p = isl_printer_print_str(p, "min(");
2087 else if (fold->type == isl_fold_max)
2088 p = isl_printer_print_str(p, "max(");
2090 for (i = 0; i < fold->n; ++i) {
2091 if (i)
2092 p = isl_printer_print_str(p, ", ");
2093 p = print_qpolynomial_c(p, dim, fold->qp[i]);
2094 if (i)
2095 p = isl_printer_print_str(p, ")");
2097 return p;
2100 __isl_give isl_printer *isl_printer_print_qpolynomial_fold(
2101 __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
2103 if (!p || !fold)
2104 goto error;
2105 if (p->output_format == ISL_FORMAT_ISL)
2106 return qpolynomial_fold_print(fold, p);
2107 else if (p->output_format == ISL_FORMAT_C)
2108 return print_qpolynomial_fold_c(p, fold->dim, fold);
2109 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2110 goto error);
2111 error:
2112 isl_printer_free(p);
2113 return NULL;
2116 static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
2117 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
2119 int i;
2121 if (pwf->n == 1 && isl_set_plain_is_universe(pwf->p[0].set))
2122 return print_qpolynomial_fold_c(p, pwf->dim, pwf->p[0].fold);
2124 for (i = 0; i < pwf->n; ++i) {
2125 p = isl_printer_print_str(p, "(");
2126 p = print_set_c(p, pwf->dim, pwf->p[i].set);
2127 p = isl_printer_print_str(p, ") ? (");
2128 p = print_qpolynomial_fold_c(p, pwf->dim, pwf->p[i].fold);
2129 p = isl_printer_print_str(p, ") : ");
2132 p = isl_printer_print_str(p, "0");
2133 return p;
2136 __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
2137 __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
2139 if (!p || !pwf)
2140 goto error;
2142 if (p->output_format == ISL_FORMAT_ISL)
2143 return print_pw_qpolynomial_fold_isl(p, pwf);
2144 else if (p->output_format == ISL_FORMAT_C)
2145 return print_pw_qpolynomial_fold_c(p, pwf);
2146 isl_assert(p->ctx, 0, goto error);
2147 error:
2148 isl_printer_free(p);
2149 return NULL;
2152 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
2153 FILE *out, unsigned output_format)
2155 isl_printer *p;
2157 if (!pwf)
2158 return;
2160 p = isl_printer_to_file(pwf->dim->ctx, out);
2161 p = isl_printer_set_output_format(p, output_format);
2162 p = isl_printer_print_pw_qpolynomial_fold(p, pwf);
2164 isl_printer_free(p);
2167 static isl_stat print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf,
2168 void *user)
2170 struct isl_union_print_data *data;
2171 data = (struct isl_union_print_data *)user;
2173 if (!data->first)
2174 data->p = isl_printer_print_str(data->p, "; ");
2175 data->first = 0;
2177 data->p = isl_pwf_print_isl_body(data->p, pwf);
2178 isl_pw_qpolynomial_fold_free(pwf);
2180 return isl_stat_ok;
2183 static __isl_give isl_printer *print_union_pw_qpolynomial_fold_isl(
2184 __isl_take isl_printer *p,
2185 __isl_keep isl_union_pw_qpolynomial_fold *upwf)
2187 struct isl_union_print_data data;
2188 struct isl_print_space_data space_data = { 0 };
2189 isl_space *dim;
2191 dim = isl_union_pw_qpolynomial_fold_get_space(upwf);
2192 if (isl_space_dim(dim, isl_dim_param) > 0) {
2193 p = print_tuple(dim, p, isl_dim_param, &space_data);
2194 p = isl_printer_print_str(p, " -> ");
2196 isl_space_free(dim);
2197 p = isl_printer_print_str(p, "{ ");
2198 data.p = p;
2199 data.first = 1;
2200 isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf,
2201 &print_pwf_body, &data);
2202 p = data.p;
2203 p = isl_printer_print_str(p, " }");
2204 return p;
2207 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold(
2208 __isl_take isl_printer *p,
2209 __isl_keep isl_union_pw_qpolynomial_fold *upwf)
2211 if (!p || !upwf)
2212 goto error;
2214 if (p->output_format == ISL_FORMAT_ISL)
2215 return print_union_pw_qpolynomial_fold_isl(p, upwf);
2216 isl_die(p->ctx, isl_error_invalid,
2217 "invalid output format for isl_union_pw_qpolynomial_fold",
2218 goto error);
2219 error:
2220 isl_printer_free(p);
2221 return NULL;
2224 __isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p,
2225 __isl_keep isl_constraint *c)
2227 isl_basic_map *bmap;
2229 if (!p || !c)
2230 goto error;
2232 bmap = isl_basic_map_from_constraint(isl_constraint_copy(c));
2233 p = isl_printer_print_basic_map(p, bmap);
2234 isl_basic_map_free(bmap);
2235 return p;
2236 error:
2237 isl_printer_free(p);
2238 return NULL;
2241 static __isl_give isl_printer *isl_printer_print_space_isl(
2242 __isl_take isl_printer *p, __isl_keep isl_space *space)
2244 struct isl_print_space_data data = { 0 };
2246 if (!space)
2247 goto error;
2249 if (isl_space_dim(space, isl_dim_param) > 0) {
2250 p = print_tuple(space, p, isl_dim_param, &data);
2251 p = isl_printer_print_str(p, " -> ");
2254 p = isl_printer_print_str(p, "{ ");
2255 if (isl_space_is_params(space))
2256 p = isl_printer_print_str(p, s_such_that[0]);
2257 else
2258 p = isl_print_space(space, p, 0, &data);
2259 p = isl_printer_print_str(p, " }");
2261 return p;
2262 error:
2263 isl_printer_free(p);
2264 return NULL;
2267 __isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p,
2268 __isl_keep isl_space *space)
2270 if (!p || !space)
2271 return isl_printer_free(p);
2272 if (p->output_format == ISL_FORMAT_ISL)
2273 return isl_printer_print_space_isl(p, space);
2274 else if (p->output_format == ISL_FORMAT_OMEGA)
2275 return print_omega_parameters(space, p);
2277 isl_die(isl_space_get_ctx(space), isl_error_unsupported,
2278 "output format not supported for space",
2279 return isl_printer_free(p));
2282 __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p,
2283 __isl_keep isl_local_space *ls)
2285 struct isl_print_space_data data = { 0 };
2286 unsigned n_div;
2288 if (!ls)
2289 goto error;
2291 if (isl_local_space_dim(ls, isl_dim_param) > 0) {
2292 p = print_tuple(ls->dim, p, isl_dim_param, &data);
2293 p = isl_printer_print_str(p, " -> ");
2295 p = isl_printer_print_str(p, "{ ");
2296 p = isl_print_space(ls->dim, p, 0, &data);
2297 n_div = isl_local_space_dim(ls, isl_dim_div);
2298 if (n_div > 0) {
2299 p = isl_printer_print_str(p, " : ");
2300 p = isl_printer_print_str(p, s_open_exists[0]);
2301 p = print_div_list(p, ls->dim, ls->div, 0, 1);
2302 p = isl_printer_print_str(p, s_close_exists[0]);
2303 } else if (isl_space_is_params(ls->dim))
2304 p = isl_printer_print_str(p, s_such_that[0]);
2305 p = isl_printer_print_str(p, " }");
2306 return p;
2307 error:
2308 isl_printer_free(p);
2309 return NULL;
2312 static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p,
2313 __isl_keep isl_aff *aff)
2315 unsigned total;
2317 if (isl_aff_is_nan(aff))
2318 return isl_printer_print_str(p, "NaN");
2320 total = isl_local_space_dim(aff->ls, isl_dim_all);
2321 p = isl_printer_print_str(p, "(");
2322 p = print_affine_of_len(aff->ls->dim, aff->ls->div, p,
2323 aff->v->el + 1, 1 + total);
2324 if (isl_int_is_one(aff->v->el[0]))
2325 p = isl_printer_print_str(p, ")");
2326 else {
2327 p = isl_printer_print_str(p, ")/");
2328 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2331 return p;
2334 static __isl_give isl_printer *print_aff(__isl_take isl_printer *p,
2335 __isl_keep isl_aff *aff)
2337 struct isl_print_space_data data = { 0 };
2339 if (isl_space_is_params(aff->ls->dim))
2341 else {
2342 p = print_tuple(aff->ls->dim, p, isl_dim_set, &data);
2343 p = isl_printer_print_str(p, " -> ");
2345 p = isl_printer_print_str(p, "[");
2346 p = print_aff_body(p, aff);
2347 p = isl_printer_print_str(p, "]");
2349 return p;
2352 static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p,
2353 __isl_keep isl_aff *aff)
2355 struct isl_print_space_data data = { 0 };
2357 if (!aff)
2358 goto error;
2360 if (isl_local_space_dim(aff->ls, isl_dim_param) > 0) {
2361 p = print_tuple(aff->ls->dim, p, isl_dim_param, &data);
2362 p = isl_printer_print_str(p, " -> ");
2364 p = isl_printer_print_str(p, "{ ");
2365 p = print_aff(p, aff);
2366 p = isl_printer_print_str(p, " }");
2367 return p;
2368 error:
2369 isl_printer_free(p);
2370 return NULL;
2373 /* Print the body of an isl_pw_aff, i.e., a semicolon delimited
2374 * sequence of affine expressions, each followed by constraints.
2376 static __isl_give isl_printer *print_pw_aff_body(
2377 __isl_take isl_printer *p, __isl_keep isl_pw_aff *pa)
2379 int i;
2381 if (!pa)
2382 return isl_printer_free(p);
2384 for (i = 0; i < pa->n; ++i) {
2385 isl_space *space;
2387 if (i)
2388 p = isl_printer_print_str(p, "; ");
2389 p = print_aff(p, pa->p[i].aff);
2390 space = isl_aff_get_domain_space(pa->p[i].aff);
2391 p = print_disjuncts((isl_map *)pa->p[i].set, space, p, 0);
2392 isl_space_free(space);
2395 return p;
2398 static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p,
2399 __isl_keep isl_pw_aff *pwaff)
2401 struct isl_print_space_data data = { 0 };
2403 if (!pwaff)
2404 goto error;
2406 if (isl_space_dim(pwaff->dim, isl_dim_param) > 0) {
2407 p = print_tuple(pwaff->dim, p, isl_dim_param, &data);
2408 p = isl_printer_print_str(p, " -> ");
2410 p = isl_printer_print_str(p, "{ ");
2411 p = print_pw_aff_body(p, pwaff);
2412 p = isl_printer_print_str(p, " }");
2413 return p;
2414 error:
2415 isl_printer_free(p);
2416 return NULL;
2419 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2420 __isl_keep isl_local_space *ls, isl_int *c);
2422 static __isl_give isl_printer *print_ls_name_c(__isl_take isl_printer *p,
2423 __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos)
2425 if (type == isl_dim_div) {
2426 p = isl_printer_print_str(p, "floord(");
2427 p = print_ls_affine_c(p, ls, ls->div->row[pos] + 1);
2428 p = isl_printer_print_str(p, ", ");
2429 p = isl_printer_print_isl_int(p, ls->div->row[pos][0]);
2430 p = isl_printer_print_str(p, ")");
2431 } else {
2432 const char *name;
2434 name = isl_space_get_dim_name(ls->dim, type, pos);
2435 if (!name)
2436 name = "UNNAMED";
2437 p = isl_printer_print_str(p, name);
2439 return p;
2442 static __isl_give isl_printer *print_ls_term_c(__isl_take isl_printer *p,
2443 __isl_keep isl_local_space *ls, isl_int c, unsigned pos)
2445 enum isl_dim_type type;
2447 if (pos == 0)
2448 return isl_printer_print_isl_int(p, c);
2450 if (isl_int_is_one(c))
2452 else if (isl_int_is_negone(c))
2453 p = isl_printer_print_str(p, "-");
2454 else {
2455 p = isl_printer_print_isl_int(p, c);
2456 p = isl_printer_print_str(p, "*");
2458 type = pos2type(ls->dim, &pos);
2459 p = print_ls_name_c(p, ls, type, pos);
2460 return p;
2463 static __isl_give isl_printer *print_ls_partial_affine_c(
2464 __isl_take isl_printer *p, __isl_keep isl_local_space *ls,
2465 isl_int *c, unsigned len)
2467 int i;
2468 int first;
2470 for (i = 0, first = 1; i < len; ++i) {
2471 int flip = 0;
2472 if (isl_int_is_zero(c[i]))
2473 continue;
2474 if (!first) {
2475 if (isl_int_is_neg(c[i])) {
2476 flip = 1;
2477 isl_int_neg(c[i], c[i]);
2478 p = isl_printer_print_str(p, " - ");
2479 } else
2480 p = isl_printer_print_str(p, " + ");
2482 first = 0;
2483 p = print_ls_term_c(p, ls, c[i], i);
2484 if (flip)
2485 isl_int_neg(c[i], c[i]);
2487 if (first)
2488 p = isl_printer_print_str(p, "0");
2489 return p;
2492 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2493 __isl_keep isl_local_space *ls, isl_int *c)
2495 unsigned len = 1 + isl_local_space_dim(ls, isl_dim_all);
2496 return print_ls_partial_affine_c(p, ls, c, len);
2499 static __isl_give isl_printer *print_aff_c(__isl_take isl_printer *p,
2500 __isl_keep isl_aff *aff)
2502 unsigned total;
2504 total = isl_local_space_dim(aff->ls, isl_dim_all);
2505 if (!isl_int_is_one(aff->v->el[0]))
2506 p = isl_printer_print_str(p, "(");
2507 p = print_ls_partial_affine_c(p, aff->ls, aff->v->el + 1, 1 + total);
2508 if (!isl_int_is_one(aff->v->el[0])) {
2509 p = isl_printer_print_str(p, ")/");
2510 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2512 return p;
2515 /* In the C format, we cannot express that "pwaff" may be undefined
2516 * on parts of the domain space. We therefore assume that the expression
2517 * will only be evaluated on its definition domain and compute the gist
2518 * of each cell with respect to this domain.
2520 static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p,
2521 __isl_keep isl_pw_aff *pwaff)
2523 isl_set *domain;
2524 isl_ast_build *build;
2525 isl_ast_expr *expr;
2527 if (pwaff->n < 1)
2528 isl_die(p->ctx, isl_error_unsupported,
2529 "cannot print empty isl_pw_aff in C format",
2530 return isl_printer_free(p));
2532 domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff));
2533 build = isl_ast_build_from_context(domain);
2534 expr = isl_ast_build_expr_from_pw_aff(build, isl_pw_aff_copy(pwaff));
2535 p = isl_printer_print_ast_expr(p, expr);
2536 isl_ast_expr_free(expr);
2537 isl_ast_build_free(build);
2539 return p;
2542 __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p,
2543 __isl_keep isl_aff *aff)
2545 if (!p || !aff)
2546 goto error;
2548 if (p->output_format == ISL_FORMAT_ISL)
2549 return print_aff_isl(p, aff);
2550 else if (p->output_format == ISL_FORMAT_C)
2551 return print_aff_c(p, aff);
2552 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2553 goto error);
2554 error:
2555 isl_printer_free(p);
2556 return NULL;
2559 __isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p,
2560 __isl_keep isl_pw_aff *pwaff)
2562 if (!p || !pwaff)
2563 goto error;
2565 if (p->output_format == ISL_FORMAT_ISL)
2566 return print_pw_aff_isl(p, pwaff);
2567 else if (p->output_format == ISL_FORMAT_C)
2568 return print_pw_aff_c(p, pwaff);
2569 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2570 goto error);
2571 error:
2572 isl_printer_free(p);
2573 return NULL;
2576 /* Print "pa" in a sequence of isl_pw_affs delimited by semicolons.
2577 * Each isl_pw_aff itself is also printed as semicolon delimited
2578 * sequence of pieces.
2579 * If data->first = 1, then this is the first in the sequence.
2580 * Update data->first to tell the next element that it is not the first.
2582 static isl_stat print_pw_aff_body_wrap(__isl_take isl_pw_aff *pa,
2583 void *user)
2585 struct isl_union_print_data *data;
2586 data = (struct isl_union_print_data *) user;
2588 if (!data->first)
2589 data->p = isl_printer_print_str(data->p, "; ");
2590 data->first = 0;
2592 data->p = print_pw_aff_body(data->p, pa);
2593 isl_pw_aff_free(pa);
2595 return data->p ? isl_stat_ok : isl_stat_error;
2598 /* Print the body of an isl_union_pw_aff, i.e., a semicolon delimited
2599 * sequence of affine expressions, each followed by constraints,
2600 * with the sequence enclosed in braces.
2602 static __isl_give isl_printer *print_union_pw_aff_body(
2603 __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
2605 struct isl_union_print_data data = { p, 1 };
2607 p = isl_printer_print_str(p, s_open_set[0]);
2608 data.p = p;
2609 if (isl_union_pw_aff_foreach_pw_aff(upa,
2610 &print_pw_aff_body_wrap, &data) < 0)
2611 data.p = isl_printer_free(p);
2612 p = data.p;
2613 p = isl_printer_print_str(p, s_close_set[0]);
2615 return p;
2618 /* Print the isl_union_pw_aff "upa" to "p" in isl format.
2620 * The individual isl_pw_affs are delimited by a semicolon.
2622 static __isl_give isl_printer *print_union_pw_aff_isl(
2623 __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
2625 struct isl_print_space_data data = { 0 };
2626 isl_space *space;
2628 space = isl_union_pw_aff_get_space(upa);
2629 if (isl_space_dim(space, isl_dim_param) > 0) {
2630 p = print_tuple(space, p, isl_dim_param, &data);
2631 p = isl_printer_print_str(p, s_to[0]);
2633 isl_space_free(space);
2634 p = print_union_pw_aff_body(p, upa);
2635 return p;
2638 /* Print the isl_union_pw_aff "upa" to "p".
2640 * We currently only support an isl format.
2642 __isl_give isl_printer *isl_printer_print_union_pw_aff(
2643 __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
2645 if (!p || !upa)
2646 return isl_printer_free(p);
2648 if (p->output_format == ISL_FORMAT_ISL)
2649 return print_union_pw_aff_isl(p, upa);
2650 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
2651 "unsupported output format", return isl_printer_free(p));
2654 /* Print dimension "pos" of data->space to "p".
2656 * data->user is assumed to be an isl_multi_aff.
2658 * If the current dimension is an output dimension, then print
2659 * the corresponding expression. Otherwise, print the name of the dimension.
2661 static __isl_give isl_printer *print_dim_ma(__isl_take isl_printer *p,
2662 struct isl_print_space_data *data, unsigned pos)
2664 isl_multi_aff *ma = data->user;
2666 if (data->type == isl_dim_out)
2667 p = print_aff_body(p, ma->p[pos]);
2668 else
2669 p = print_name(data->space, p, data->type, pos, data->latex);
2671 return p;
2674 static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p,
2675 __isl_keep isl_multi_aff *maff)
2677 struct isl_print_space_data data = { 0 };
2679 data.print_dim = &print_dim_ma;
2680 data.user = maff;
2681 return isl_print_space(maff->space, p, 0, &data);
2684 static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p,
2685 __isl_keep isl_multi_aff *maff)
2687 struct isl_print_space_data data = { 0 };
2689 if (!maff)
2690 goto error;
2692 if (isl_space_dim(maff->space, isl_dim_param) > 0) {
2693 p = print_tuple(maff->space, p, isl_dim_param, &data);
2694 p = isl_printer_print_str(p, " -> ");
2696 p = isl_printer_print_str(p, "{ ");
2697 p = print_multi_aff(p, maff);
2698 p = isl_printer_print_str(p, " }");
2699 return p;
2700 error:
2701 isl_printer_free(p);
2702 return NULL;
2705 __isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p,
2706 __isl_keep isl_multi_aff *maff)
2708 if (!p || !maff)
2709 goto error;
2711 if (p->output_format == ISL_FORMAT_ISL)
2712 return print_multi_aff_isl(p, maff);
2713 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2714 goto error);
2715 error:
2716 isl_printer_free(p);
2717 return NULL;
2720 static __isl_give isl_printer *print_pw_multi_aff_body(
2721 __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2723 int i;
2725 if (!pma)
2726 goto error;
2728 for (i = 0; i < pma->n; ++i) {
2729 isl_space *space;
2731 if (i)
2732 p = isl_printer_print_str(p, "; ");
2733 p = print_multi_aff(p, pma->p[i].maff);
2734 space = isl_multi_aff_get_domain_space(pma->p[i].maff);
2735 p = print_disjuncts((isl_map *)pma->p[i].set, space, p, 0);
2736 isl_space_free(space);
2738 return p;
2739 error:
2740 isl_printer_free(p);
2741 return NULL;
2744 static __isl_give isl_printer *print_pw_multi_aff_isl(__isl_take isl_printer *p,
2745 __isl_keep isl_pw_multi_aff *pma)
2747 struct isl_print_space_data data = { 0 };
2749 if (!pma)
2750 goto error;
2752 if (isl_space_dim(pma->dim, isl_dim_param) > 0) {
2753 p = print_tuple(pma->dim, p, isl_dim_param, &data);
2754 p = isl_printer_print_str(p, " -> ");
2756 p = isl_printer_print_str(p, "{ ");
2757 p = print_pw_multi_aff_body(p, pma);
2758 p = isl_printer_print_str(p, " }");
2759 return p;
2760 error:
2761 isl_printer_free(p);
2762 return NULL;
2765 static __isl_give isl_printer *print_unnamed_pw_multi_aff_c(
2766 __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2768 int i;
2770 for (i = 0; i < pma->n - 1; ++i) {
2771 p = isl_printer_print_str(p, "(");
2772 p = print_set_c(p, pma->dim, pma->p[i].set);
2773 p = isl_printer_print_str(p, ") ? (");
2774 p = print_aff_c(p, pma->p[i].maff->p[0]);
2775 p = isl_printer_print_str(p, ") : ");
2778 return print_aff_c(p, pma->p[pma->n - 1].maff->p[0]);
2781 static __isl_give isl_printer *print_pw_multi_aff_c(__isl_take isl_printer *p,
2782 __isl_keep isl_pw_multi_aff *pma)
2784 int n;
2785 const char *name;
2787 if (!pma)
2788 goto error;
2789 if (pma->n < 1)
2790 isl_die(p->ctx, isl_error_unsupported,
2791 "cannot print empty isl_pw_multi_aff in C format",
2792 goto error);
2793 name = isl_pw_multi_aff_get_tuple_name(pma, isl_dim_out);
2794 if (!name && isl_pw_multi_aff_dim(pma, isl_dim_out) == 1)
2795 return print_unnamed_pw_multi_aff_c(p, pma);
2796 if (!name)
2797 isl_die(p->ctx, isl_error_unsupported,
2798 "cannot print unnamed isl_pw_multi_aff in C format",
2799 goto error);
2801 p = isl_printer_print_str(p, name);
2802 n = isl_pw_multi_aff_dim(pma, isl_dim_out);
2803 if (n != 0)
2804 isl_die(p->ctx, isl_error_unsupported,
2805 "not supported yet", goto error);
2807 return p;
2808 error:
2809 isl_printer_free(p);
2810 return NULL;
2813 __isl_give isl_printer *isl_printer_print_pw_multi_aff(
2814 __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2816 if (!p || !pma)
2817 goto error;
2819 if (p->output_format == ISL_FORMAT_ISL)
2820 return print_pw_multi_aff_isl(p, pma);
2821 if (p->output_format == ISL_FORMAT_C)
2822 return print_pw_multi_aff_c(p, pma);
2823 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2824 goto error);
2825 error:
2826 isl_printer_free(p);
2827 return NULL;
2830 static isl_stat print_pw_multi_aff_body_wrap(__isl_take isl_pw_multi_aff *pma,
2831 void *user)
2833 struct isl_union_print_data *data;
2834 data = (struct isl_union_print_data *) user;
2836 if (!data->first)
2837 data->p = isl_printer_print_str(data->p, "; ");
2838 data->first = 0;
2840 data->p = print_pw_multi_aff_body(data->p, pma);
2841 isl_pw_multi_aff_free(pma);
2843 return isl_stat_ok;
2846 static __isl_give isl_printer *print_union_pw_multi_aff_isl(
2847 __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
2849 struct isl_union_print_data data;
2850 struct isl_print_space_data space_data = { 0 };
2851 isl_space *space;
2853 space = isl_union_pw_multi_aff_get_space(upma);
2854 if (isl_space_dim(space, isl_dim_param) > 0) {
2855 p = print_tuple(space, p, isl_dim_param, &space_data);
2856 p = isl_printer_print_str(p, s_to[0]);
2858 isl_space_free(space);
2859 p = isl_printer_print_str(p, s_open_set[0]);
2860 data.p = p;
2861 data.first = 1;
2862 isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
2863 &print_pw_multi_aff_body_wrap, &data);
2864 p = data.p;
2865 p = isl_printer_print_str(p, s_close_set[0]);
2866 return p;
2869 __isl_give isl_printer *isl_printer_print_union_pw_multi_aff(
2870 __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
2872 if (!p || !upma)
2873 goto error;
2875 if (p->output_format == ISL_FORMAT_ISL)
2876 return print_union_pw_multi_aff_isl(p, upma);
2877 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2878 goto error);
2879 error:
2880 isl_printer_free(p);
2881 return NULL;
2884 /* Print dimension "pos" of data->space to "p".
2886 * data->user is assumed to be an isl_multi_pw_aff.
2888 * If the current dimension is an output dimension, then print
2889 * the corresponding piecewise affine expression.
2890 * Otherwise, print the name of the dimension.
2892 static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p,
2893 struct isl_print_space_data *data, unsigned pos)
2895 int i;
2896 int need_parens;
2897 isl_multi_pw_aff *mpa = data->user;
2898 isl_pw_aff *pa;
2900 if (data->type != isl_dim_out)
2901 return print_name(data->space, p, data->type, pos, data->latex);
2903 pa = mpa->p[pos];
2904 if (pa->n == 0)
2905 return isl_printer_print_str(p, "(0 : 1 = 0)");
2907 need_parens = pa->n != 1 || !isl_set_plain_is_universe(pa->p[0].set);
2908 if (need_parens)
2909 p = isl_printer_print_str(p, "(");
2910 for (i = 0; i < pa->n; ++i) {
2911 isl_space *space;
2913 if (i)
2914 p = isl_printer_print_str(p, "; ");
2915 p = print_aff_body(p, pa->p[i].aff);
2916 space = isl_aff_get_domain_space(pa->p[i].aff);
2917 p = print_disjuncts(pa->p[i].set, space, p, 0);
2918 isl_space_free(space);
2920 if (need_parens)
2921 p = isl_printer_print_str(p, ")");
2923 return p;
2926 /* Print "mpa" to "p" in isl format.
2928 static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p,
2929 __isl_keep isl_multi_pw_aff *mpa)
2931 struct isl_print_space_data data = { 0 };
2933 if (!mpa)
2934 return isl_printer_free(p);
2936 if (isl_space_dim(mpa->space, isl_dim_param) > 0) {
2937 p = print_tuple(mpa->space, p, isl_dim_param, &data);
2938 p = isl_printer_print_str(p, " -> ");
2940 p = isl_printer_print_str(p, "{ ");
2941 data.print_dim = &print_dim_mpa;
2942 data.user = mpa;
2943 p = isl_print_space(mpa->space, p, 0, &data);
2944 p = isl_printer_print_str(p, " }");
2945 return p;
2948 __isl_give isl_printer *isl_printer_print_multi_pw_aff(
2949 __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa)
2951 if (!p || !mpa)
2952 return isl_printer_free(p);
2954 if (p->output_format == ISL_FORMAT_ISL)
2955 return print_multi_pw_aff_isl(p, mpa);
2956 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2957 return isl_printer_free(p));
2960 /* Print dimension "pos" of data->space to "p".
2962 * data->user is assumed to be an isl_multi_val.
2964 * If the current dimension is an output dimension, then print
2965 * the corresponding value. Otherwise, print the name of the dimension.
2967 static __isl_give isl_printer *print_dim_mv(__isl_take isl_printer *p,
2968 struct isl_print_space_data *data, unsigned pos)
2970 isl_multi_val *mv = data->user;
2972 if (data->type == isl_dim_out)
2973 return isl_printer_print_val(p, mv->p[pos]);
2974 else
2975 return print_name(data->space, p, data->type, pos, data->latex);
2978 /* Print the isl_multi_val "mv" to "p" in isl format.
2980 static __isl_give isl_printer *print_multi_val_isl(__isl_take isl_printer *p,
2981 __isl_keep isl_multi_val *mv)
2983 struct isl_print_space_data data = { 0 };
2985 if (!mv)
2986 return isl_printer_free(p);
2988 if (isl_space_dim(mv->space, isl_dim_param) > 0) {
2989 p = print_tuple(mv->space, p, isl_dim_param, &data);
2990 p = isl_printer_print_str(p, " -> ");
2992 p = isl_printer_print_str(p, "{ ");
2993 data.print_dim = &print_dim_mv;
2994 data.user = mv;
2995 p = isl_print_space(mv->space, p, 0, &data);
2996 p = isl_printer_print_str(p, " }");
2997 return p;
3000 /* Print the isl_multi_val "mv" to "p".
3002 * Currently only supported in isl format.
3004 __isl_give isl_printer *isl_printer_print_multi_val(
3005 __isl_take isl_printer *p, __isl_keep isl_multi_val *mv)
3007 if (!p || !mv)
3008 return isl_printer_free(p);
3010 if (p->output_format == ISL_FORMAT_ISL)
3011 return print_multi_val_isl(p, mv);
3012 isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
3013 return isl_printer_free(p));
3016 /* Print dimension "pos" of data->space to "p".
3018 * data->user is assumed to be an isl_multi_union_pw_aff.
3020 * The current dimension is necessarily a set dimension, so
3021 * we print the corresponding isl_union_pw_aff, including
3022 * the braces.
3024 static __isl_give isl_printer *print_union_pw_aff_dim(__isl_take isl_printer *p,
3025 struct isl_print_space_data *data, unsigned pos)
3027 isl_multi_union_pw_aff *mupa = data->user;
3028 isl_union_pw_aff *upa;
3030 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, pos);
3031 p = print_union_pw_aff_body(p, upa);
3032 isl_union_pw_aff_free(upa);
3034 return p;
3037 /* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.
3039 static __isl_give isl_printer *print_multi_union_pw_aff_isl(
3040 __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)
3042 struct isl_print_space_data data = { 0 };
3043 isl_space *space;
3045 space = isl_multi_union_pw_aff_get_space(mupa);
3046 if (isl_space_dim(space, isl_dim_param) > 0) {
3047 struct isl_print_space_data space_data = { 0 };
3048 p = print_tuple(space, p, isl_dim_param, &space_data);
3049 p = isl_printer_print_str(p, s_to[0]);
3052 data.print_dim = &print_union_pw_aff_dim;
3053 data.user = mupa;
3055 p = isl_print_space(space, p, 0, &data);
3056 isl_space_free(space);
3058 return p;
3061 /* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.
3063 * We currently only support an isl format.
3065 __isl_give isl_printer *isl_printer_print_multi_union_pw_aff(
3066 __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)
3068 if (!p || !mupa)
3069 return isl_printer_free(p);
3071 if (p->output_format == ISL_FORMAT_ISL)
3072 return print_multi_union_pw_aff_isl(p, mupa);
3073 isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
3074 "unsupported output format", return isl_printer_free(p));