isl_basic_set_opt: avoid invalid access on error path
[platform/upstream/isl.git] / isl_output.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  * Copyright 2010      INRIA Saclay
4  *
5  * Use of this software is governed by the MIT license
6  *
7  * Written by Sven Verdoolaege, K.U.Leuven, Departement
8  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
10  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France 
11  */
12
13 #include <stdlib.h>
14 #include <string.h>
15 #include <isl_ctx_private.h>
16 #include <isl_map_private.h>
17 #include <isl/set.h>
18 #include <isl/seq.h>
19 #include <isl_polynomial_private.h>
20 #include <isl_printer_private.h>
21 #include <isl_space_private.h>
22 #include <isl_mat_private.h>
23 #include <isl/union_map.h>
24 #include <isl/constraint.h>
25 #include <isl_local_space_private.h>
26 #include <isl_aff_private.h>
27 #include <isl_ast_build_expr.h>
28
29 static const char *s_to[2] = { " -> ", " \\to " };
30 static const char *s_and[2] = { " and ", " \\wedge " };
31 static const char *s_or[2] = { " or ", " \\vee " };
32 static const char *s_le[2] = { "<=", "\\le" };
33 static const char *s_ge[2] = { ">=", "\\ge" };
34 static const char *s_open_set[2] = { "{ ", "\\{\\, " };
35 static const char *s_close_set[2] = { " }", " \\,\\}" };
36 static const char *s_open_list[2] = { "[", "(" };
37 static const char *s_close_list[2] = { "]", ")" };
38 static const char *s_such_that[2] = { " : ", " \\mid " };
39 static const char *s_open_exists[2] = { "exists (", "\\exists \\, " };
40 static const char *s_close_exists[2] = { ")", "" };
41 static const char *s_div_prefix[2] = { "e", "\\alpha_" };
42 static const char *s_param_prefix[2] = { "p", "p_" };
43 static const char *s_input_prefix[2] = { "i", "i_" };
44 static const char *s_output_prefix[2] = { "o", "o_" };
45
46 static __isl_give isl_printer *print_constraint_polylib(
47         struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p)
48 {
49         int i;
50         unsigned n_in = isl_basic_map_dim(bmap, isl_dim_in);
51         unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
52         unsigned nparam = isl_basic_map_dim(bmap, isl_dim_param);
53         isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n];
54
55         p = isl_printer_start_line(p);
56         p = isl_printer_print_int(p, ineq);
57         for (i = 0; i < n_out; ++i) {
58                 p = isl_printer_print_str(p, " ");
59                 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]);
60         }
61         for (i = 0; i < n_in; ++i) {
62                 p = isl_printer_print_str(p, " ");
63                 p = isl_printer_print_isl_int(p, c[1+nparam+i]);
64         }
65         for (i = 0; i < bmap->n_div; ++i) {
66                 p = isl_printer_print_str(p, " ");
67                 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]);
68         }
69         for (i = 0; i < nparam; ++i) {
70                 p = isl_printer_print_str(p, " ");
71                 p = isl_printer_print_isl_int(p, c[1+i]);
72         }
73         p = isl_printer_print_str(p, " ");
74         p = isl_printer_print_isl_int(p, c[0]);
75         p = isl_printer_end_line(p);
76         return p;
77 }
78
79 static __isl_give isl_printer *print_constraints_polylib(
80         struct isl_basic_map *bmap, __isl_take isl_printer *p)
81 {
82         int i;
83
84         p = isl_printer_set_isl_int_width(p, 5);
85
86         for (i = 0; i < bmap->n_eq; ++i)
87                 p = print_constraint_polylib(bmap, 0, i, p);
88         for (i = 0; i < bmap->n_ineq; ++i)
89                 p = print_constraint_polylib(bmap, 1, i, p);
90
91         return p;
92 }
93
94 static __isl_give isl_printer *bset_print_constraints_polylib(
95         struct isl_basic_set *bset, __isl_take isl_printer *p)
96 {
97         return print_constraints_polylib((struct isl_basic_map *)bset, p);
98 }
99
100 static __isl_give isl_printer *isl_basic_map_print_polylib(
101         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int ext)
102 {
103         unsigned total = isl_basic_map_total_dim(bmap);
104         p = isl_printer_start_line(p);
105         p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq);
106         p = isl_printer_print_str(p, " ");
107         p = isl_printer_print_int(p, 1 + total + 1);
108         if (ext) {
109                 p = isl_printer_print_str(p, " ");
110                 p = isl_printer_print_int(p,
111                                     isl_basic_map_dim(bmap, isl_dim_out));
112                 p = isl_printer_print_str(p, " ");
113                 p = isl_printer_print_int(p,
114                                     isl_basic_map_dim(bmap, isl_dim_in));
115                 p = isl_printer_print_str(p, " ");
116                 p = isl_printer_print_int(p,
117                                     isl_basic_map_dim(bmap, isl_dim_div));
118                 p = isl_printer_print_str(p, " ");
119                 p = isl_printer_print_int(p,
120                                     isl_basic_map_dim(bmap, isl_dim_param));
121         }
122         p = isl_printer_end_line(p);
123         return print_constraints_polylib(bmap, p);
124 }
125
126 static __isl_give isl_printer *isl_basic_set_print_polylib(
127         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int ext)
128 {
129         return isl_basic_map_print_polylib((struct isl_basic_map *)bset, p, ext);
130 }
131
132 static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map,
133         __isl_take isl_printer *p, int ext)
134 {
135         int i;
136
137         p = isl_printer_start_line(p);
138         p = isl_printer_print_int(p, map->n);
139         p = isl_printer_end_line(p);
140         for (i = 0; i < map->n; ++i) {
141                 p = isl_printer_start_line(p);
142                 p = isl_printer_end_line(p);
143                 p = isl_basic_map_print_polylib(map->p[i], p, ext);
144         }
145         return p;
146 }
147
148 static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set,
149         __isl_take isl_printer *p, int ext)
150 {
151         return isl_map_print_polylib((struct isl_map *)set, p, ext);
152 }
153
154 static int count_same_name(__isl_keep isl_space *dim,
155         enum isl_dim_type type, unsigned pos, const char *name)
156 {
157         enum isl_dim_type t;
158         unsigned p, s;
159         int count = 0;
160
161         for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) {
162                 s = t == type ? pos : isl_space_dim(dim, t);
163                 for (p = 0; p < s; ++p) {
164                         const char *n = isl_space_get_dim_name(dim, t, p);
165                         if (n && !strcmp(n, name))
166                                 count++;
167                 }
168         }
169         return count;
170 }
171
172 static __isl_give isl_printer *print_name(__isl_keep isl_space *dim,
173         __isl_take isl_printer *p, enum isl_dim_type type, unsigned pos,
174         int latex)
175 {
176         const char *name;
177         char buffer[20];
178         int primes;
179
180         name = type == isl_dim_div ? NULL : isl_space_get_dim_name(dim, type, pos);
181
182         if (!name) {
183                 const char *prefix;
184                 if (type == isl_dim_param)
185                         prefix = s_param_prefix[latex];
186                 else if (type == isl_dim_div)
187                         prefix = s_div_prefix[latex];
188                 else if (isl_space_is_set(dim) || type == isl_dim_in)
189                         prefix = s_input_prefix[latex];
190                 else
191                         prefix = s_output_prefix[latex];
192                 snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);
193                 name = buffer;
194         }
195         primes = count_same_name(dim, name == buffer ? isl_dim_div : type,
196                                  pos, name);
197         p = isl_printer_print_str(p, name);
198         while (primes-- > 0)
199                 p = isl_printer_print_str(p, "'");
200         return p;
201 }
202
203 static enum isl_dim_type pos2type(__isl_keep isl_space *dim, unsigned *pos)
204 {
205         enum isl_dim_type type;
206         unsigned n_in = isl_space_dim(dim, isl_dim_in);
207         unsigned n_out = isl_space_dim(dim, isl_dim_out);
208         unsigned nparam = isl_space_dim(dim, isl_dim_param);
209
210         if (*pos < 1 + nparam) {
211                 type = isl_dim_param;
212                 *pos -= 1;
213         } else if (*pos < 1 + nparam + n_in) {
214                 type = isl_dim_in;
215                 *pos -= 1 + nparam;
216         } else if (*pos < 1 + nparam + n_in + n_out) {
217                 type = isl_dim_out;
218                 *pos -= 1 + nparam + n_in;
219         } else {
220                 type = isl_dim_div;
221                 *pos -= 1 + nparam + n_in + n_out;
222         }
223
224         return type;
225 }
226
227 static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
228         __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p);
229
230 static __isl_give isl_printer *print_term(__isl_keep isl_space *dim,
231         __isl_keep isl_mat *div,
232         isl_int c, unsigned pos, __isl_take isl_printer *p, int latex)
233 {
234         enum isl_dim_type type;
235         int print_div_def;
236
237         if (pos == 0)
238                 return isl_printer_print_isl_int(p, c);
239
240         type = pos2type(dim, &pos);
241         print_div_def = type == isl_dim_div && div &&
242                         !isl_int_is_zero(div->row[pos][0]);
243
244         if (isl_int_is_one(c))
245                 ;
246         else if (isl_int_is_negone(c))
247                 p = isl_printer_print_str(p, "-");
248         else {
249                 p = isl_printer_print_isl_int(p, c);
250                 if (p->output_format == ISL_FORMAT_C || print_div_def)
251                         p = isl_printer_print_str(p, "*");
252         }
253         if (print_div_def)
254                 p = print_div(dim, div, pos, p);
255         else
256                 p = print_name(dim, p, type, pos, latex);
257         return p;
258 }
259
260 static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *dim,
261         __isl_keep isl_mat *div,
262         __isl_take isl_printer *p, isl_int *c, int len)
263 {
264         int i;
265         int first;
266
267         for (i = 0, first = 1; i < len; ++i) {
268                 int flip = 0;
269                 if (isl_int_is_zero(c[i]))
270                         continue;
271                 if (!first) {
272                         if (isl_int_is_neg(c[i])) {
273                                 flip = 1;
274                                 isl_int_neg(c[i], c[i]);
275                                 p = isl_printer_print_str(p, " - ");
276                         } else 
277                                 p = isl_printer_print_str(p, " + ");
278                 }
279                 first = 0;
280                 p = print_term(dim, div, c[i], i, p, 0);
281                 if (flip)
282                         isl_int_neg(c[i], c[i]);
283         }
284         if (first)
285                 p = isl_printer_print_str(p, "0");
286         return p;
287 }
288
289 static __isl_give isl_printer *print_affine(__isl_keep isl_basic_map *bmap,
290         __isl_keep isl_space *dim, __isl_take isl_printer *p, isl_int *c)
291 {
292         unsigned len = 1 + isl_basic_map_total_dim(bmap);
293         return print_affine_of_len(dim, NULL, p, c, len);
294 }
295
296 static int defining_equality(__isl_keep isl_basic_map *eq,
297         __isl_keep isl_space *dim, enum isl_dim_type type, int pos)
298 {
299         int i;
300         unsigned total;
301
302         if (!eq)
303                 return -1;
304
305         pos += isl_space_offset(dim, type);
306         total = isl_basic_map_total_dim(eq);
307
308         for (i = 0; i < eq->n_eq; ++i) {
309                 if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos)
310                         continue;
311                 if (isl_int_is_one(eq->eq[i][1 + pos]))
312                         isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total);
313                 return i;
314         }
315
316         return -1;
317 }
318
319 static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p,
320         __isl_keep isl_aff *aff);
321
322 /* offset is the offset of local_dim inside global_type of global_dim.
323  */
324 static __isl_give isl_printer *print_nested_var_list(__isl_take isl_printer *p,
325         __isl_keep isl_space *global_dim, enum isl_dim_type global_type,
326         __isl_keep isl_space *local_dim, enum isl_dim_type local_type,
327         int latex, __isl_keep isl_basic_map *eq,
328         __isl_keep isl_multi_aff *maff, int offset)
329 {
330         int i, j;
331
332         if (global_dim != local_dim && local_type == isl_dim_out)
333                 offset += local_dim->n_in;
334
335         for (i = 0; i < isl_space_dim(local_dim, local_type); ++i) {
336                 if (i)
337                         p = isl_printer_print_str(p, ", ");
338                 if (maff && global_type == isl_dim_out) {
339                         p = print_aff_body(p, maff->p[offset + i]);
340                         continue;
341                 }
342                 j = defining_equality(eq, global_dim, global_type, offset + i);
343                 if (j >= 0) {
344                         int pos = 1 + isl_space_offset(global_dim, global_type)
345                                     + offset + i;
346                         p = print_affine_of_len(eq->dim, NULL,
347                                                 p, eq->eq[j], pos);
348                 } else {
349                         p = print_name(global_dim, p, global_type, offset + i,
350                                         latex);
351                 }
352         }
353         return p;
354 }
355
356 static __isl_give isl_printer *print_var_list(__isl_keep isl_space *dim,
357         __isl_take isl_printer *p, enum isl_dim_type type,
358         int latex, __isl_keep isl_basic_map *eq, __isl_keep isl_multi_aff *maff)
359 {
360         return print_nested_var_list(p, dim, type, dim, type, latex,
361                                         eq, maff, 0);
362 }
363
364 static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
365         __isl_keep isl_space *global_dim, enum isl_dim_type global_type,
366         __isl_keep isl_space *local_dim,
367         int latex, __isl_keep isl_basic_map *eq,
368         __isl_keep isl_multi_aff *maff, int offset);
369
370 static __isl_give isl_printer *print_nested_tuple(__isl_take isl_printer *p,
371         __isl_keep isl_space *global_dim, enum isl_dim_type global_type,
372         __isl_keep isl_space *local_dim, enum isl_dim_type local_type,
373         int latex, __isl_keep isl_basic_map *eq,
374         __isl_keep isl_multi_aff *maff, int offset)
375 {
376         const char *name = NULL;
377         unsigned n = isl_space_dim(local_dim, local_type);
378         if ((local_type == isl_dim_in || local_type == isl_dim_out)) {
379                 name = isl_space_get_tuple_name(local_dim, local_type);
380                 if (name) {
381                         if (latex)
382                                 p = isl_printer_print_str(p, "\\mathrm{");
383                         p = isl_printer_print_str(p, name);
384                         if (latex)
385                                 p = isl_printer_print_str(p, "}");
386                 }
387         }
388         if (!latex || n != 1 || name)
389                 p = isl_printer_print_str(p, s_open_list[latex]);
390         if ((local_type == isl_dim_in || local_type == isl_dim_out) &&
391             local_dim->nested[local_type - isl_dim_in]) {
392                 if (global_dim != local_dim && local_type == isl_dim_out)
393                         offset += local_dim->n_in;
394                 p = print_nested_map_dim(p, global_dim, global_type,
395                                 local_dim->nested[local_type - isl_dim_in],
396                                 latex, eq, maff, offset);
397         } else
398                 p = print_nested_var_list(p, global_dim, global_type,
399                                           local_dim, local_type, latex,
400                                           eq, maff, offset);
401         if (!latex || n != 1 || name)
402                 p = isl_printer_print_str(p, s_close_list[latex]);
403         return p;
404 }
405
406 static __isl_give isl_printer *print_tuple(__isl_keep isl_space *dim,
407         __isl_take isl_printer *p, enum isl_dim_type type,
408         int latex, __isl_keep isl_basic_map *eq, __isl_keep isl_multi_aff *maff)
409 {
410         return print_nested_tuple(p, dim, type, dim, type, latex, eq, maff, 0);
411 }
412
413 static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
414         __isl_keep isl_space *global_dim, enum isl_dim_type global_type,
415         __isl_keep isl_space *local_dim,
416         int latex, __isl_keep isl_basic_map *eq,
417         __isl_keep isl_multi_aff *maff, int offset)
418 {
419         p = print_nested_tuple(p, global_dim, global_type,
420                         local_dim, isl_dim_in, latex, eq, maff, offset);
421         p = isl_printer_print_str(p, s_to[latex]);
422         p = print_nested_tuple(p, global_dim, global_type,
423                         local_dim, isl_dim_out, latex, eq, maff, offset);
424
425         return p;
426 }
427
428 static __isl_give isl_printer *print_space(__isl_keep isl_space *dim,
429         __isl_take isl_printer *p, int latex, int rational,
430         __isl_keep isl_basic_map *eq, __isl_keep isl_multi_aff *maff)
431 {
432         if (rational && !latex)
433                 p = isl_printer_print_str(p, "rat: ");
434         if (isl_space_is_params(dim))
435                 ;
436         else if (isl_space_is_set(dim))
437                 p = print_tuple(dim, p, isl_dim_set, latex, eq, maff);
438         else {
439                 p = print_tuple(dim, p, isl_dim_in, latex, eq, maff);
440                 p = isl_printer_print_str(p, s_to[latex]);
441                 p = print_tuple(dim, p, isl_dim_out, latex, eq, maff);
442         }
443
444         return p;
445 }
446
447 static __isl_give isl_printer *print_omega_parameters(__isl_keep isl_space *dim,
448         __isl_take isl_printer *p)
449 {
450         if (isl_space_dim(dim, isl_dim_param) == 0)
451                 return p;
452
453         p = isl_printer_start_line(p);
454         p = isl_printer_print_str(p, "symbolic ");
455         p = print_var_list(dim, p, isl_dim_param, 0, NULL, NULL);
456         p = isl_printer_print_str(p, ";");
457         p = isl_printer_end_line(p);
458         return p;
459 }
460
461 static __isl_give isl_printer *print_constraint(struct isl_basic_map *bmap,
462         __isl_keep isl_space *dim, __isl_take isl_printer *p,
463         isl_int *c, int last, const char *op, int first_constraint, int latex)
464 {
465         if (!first_constraint)
466                 p = isl_printer_print_str(p, s_and[latex]);
467
468         isl_int_abs(c[last], c[last]);
469
470         p = print_term(dim, NULL, c[last], last, p, latex);
471
472         p = isl_printer_print_str(p, " ");
473         p = isl_printer_print_str(p, op);
474         p = isl_printer_print_str(p, " ");
475
476         isl_int_set_si(c[last], 0);
477         p = print_affine(bmap, dim, p, c);
478
479         return p;
480 }
481
482 static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
483         __isl_keep isl_space *dim, __isl_take isl_printer *p, int latex)
484 {
485         int i;
486         struct isl_vec *c;
487         unsigned total = isl_basic_map_total_dim(bmap);
488
489         c = isl_vec_alloc(bmap->ctx, 1 + total);
490         if (!c)
491                 goto error;
492
493         for (i = bmap->n_eq - 1; i >= 0; --i) {
494                 int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total);
495                 if (l < 0) {
496                         if (i != bmap->n_eq - 1)
497                                 p = isl_printer_print_str(p, s_and[latex]);
498                         p = isl_printer_print_str(p, "0 = 0");
499                         continue;
500                 }
501                 if (isl_int_is_neg(bmap->eq[i][l]))
502                         isl_seq_cpy(c->el, bmap->eq[i], 1 + total);
503                 else
504                         isl_seq_neg(c->el, bmap->eq[i], 1 + total);
505                 p = print_constraint(bmap, dim, p, c->el, l,
506                                     "=", i == bmap->n_eq - 1, latex);
507         }
508         for (i = 0; i < bmap->n_ineq; ++i) {
509                 int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);
510                 int s;
511                 const char *op;
512                 if (l < 0)
513                         continue;
514                 s = isl_int_sgn(bmap->ineq[i][l]);
515                 if (s < 0)
516                         isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);
517                 else
518                         isl_seq_neg(c->el, bmap->ineq[i], 1 + total);
519                 op = s < 0 ? s_le[latex] : s_ge[latex];
520                 p = print_constraint(bmap, dim, p, c->el, l,
521                                         op, !bmap->n_eq && !i, latex);
522         }
523
524         isl_vec_free(c);
525
526         return p;
527 error:
528         isl_vec_free(c);
529         isl_printer_free(p);
530         return NULL;
531 }
532
533 static __isl_give isl_printer *print_omega_constraints(
534         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
535 {
536         if (bmap->n_eq + bmap->n_ineq == 0)
537                 return p;
538
539         p = isl_printer_print_str(p, ": ");
540         if (bmap->n_div > 0) {
541                 int i;
542                 p = isl_printer_print_str(p, "exists (");
543                 for (i = 0; i < bmap->n_div; ++i) {
544                         if (i)
545                                 p = isl_printer_print_str(p, ", ");
546                         p = print_name(bmap->dim, p, isl_dim_div, i, 0);
547                 }
548                 p = isl_printer_print_str(p, ": ");
549         }
550         p = print_constraints(bmap, bmap->dim, p, 0);
551         if (bmap->n_div > 0)
552                 p = isl_printer_print_str(p, ")");
553         return p;
554 }
555
556 static __isl_give isl_printer *basic_map_print_omega(
557         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
558 {
559         p = isl_printer_print_str(p, "{ [");
560         p = print_var_list(bmap->dim, p, isl_dim_in, 0, NULL, NULL);
561         p = isl_printer_print_str(p, "] -> [");
562         p = print_var_list(bmap->dim, p, isl_dim_out, 0, NULL, NULL);
563         p = isl_printer_print_str(p, "] ");
564         p = print_omega_constraints(bmap, p);
565         p = isl_printer_print_str(p, " }");
566         return p;
567 }
568
569 static __isl_give isl_printer *basic_set_print_omega(
570         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
571 {
572         p = isl_printer_print_str(p, "{ [");
573         p = print_var_list(bset->dim, p, isl_dim_set, 0, NULL, NULL);
574         p = isl_printer_print_str(p, "] ");
575         p = print_omega_constraints((isl_basic_map *)bset, p);
576         p = isl_printer_print_str(p, " }");
577         return p;
578 }
579
580 static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map,
581         __isl_take isl_printer *p)
582 {
583         int i;
584
585         for (i = 0; i < map->n; ++i) {
586                 if (i)
587                         p = isl_printer_print_str(p, " union ");
588                 p = basic_map_print_omega(map->p[i], p);
589         }
590         return p;
591 }
592
593 static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set,
594         __isl_take isl_printer *p)
595 {
596         int i;
597
598         for (i = 0; i < set->n; ++i) {
599                 if (i)
600                         p = isl_printer_print_str(p, " union ");
601                 p = basic_set_print_omega(set->p[i], p);
602         }
603         return p;
604 }
605
606 static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
607         __isl_keep isl_space *dim, __isl_take isl_printer *p, int latex)
608 {
609         if (bmap->n_div > 0) {
610                 int i;
611                 p = isl_printer_print_str(p, s_open_exists[latex]);
612                 for (i = 0; i < bmap->n_div; ++i) {
613                         if (i)
614                                 p = isl_printer_print_str(p, ", ");
615                         p = print_name(dim, p, isl_dim_div, i, latex);
616                         if (latex || isl_int_is_zero(bmap->div[i][0]))
617                                 continue;
618                         p = isl_printer_print_str(p, " = [(");
619                         p = print_affine(bmap, dim, p, bmap->div[i] + 1);
620                         p = isl_printer_print_str(p, ")/");
621                         p = isl_printer_print_isl_int(p, bmap->div[i][0]);
622                         p = isl_printer_print_str(p, "]");
623                 }
624                 p = isl_printer_print_str(p, ": ");
625         }
626
627         p = print_constraints(bmap, dim, p, latex);
628
629         if (bmap->n_div > 0)
630                 p = isl_printer_print_str(p, s_close_exists[latex]);
631         return p;
632 }
633
634 static __isl_give isl_printer *isl_basic_map_print_isl(
635         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p,
636         int latex)
637 {
638         int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
639         if (isl_basic_map_dim(bmap, isl_dim_param) > 0) {
640                 p = print_tuple(bmap->dim, p, isl_dim_param, latex, NULL, NULL);
641                 p = isl_printer_print_str(p, " -> ");
642         }
643         p = isl_printer_print_str(p, "{ ");
644         p = print_space(bmap->dim, p, latex, rational, NULL, NULL);
645         p = isl_printer_print_str(p, " : ");
646         p = print_disjunct(bmap, bmap->dim, p, latex);
647         p = isl_printer_print_str(p, " }");
648         return p;
649 }
650
651 static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
652         __isl_take isl_printer *p, int latex)
653 {
654         int i;
655
656         if (isl_map_plain_is_universe(map))
657                 return p;
658
659         p = isl_printer_print_str(p, s_such_that[latex]);
660         if (map->n == 0)
661                 p = isl_printer_print_str(p, "1 = 0");
662         for (i = 0; i < map->n; ++i) {
663                 if (i)
664                         p = isl_printer_print_str(p, s_or[latex]);
665                 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
666                         p = isl_printer_print_str(p, "(");
667                 p = print_disjunct(map->p[i], map->dim, p, latex);
668                 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
669                         p = isl_printer_print_str(p, ")");
670         }
671         return p;
672 }
673
674 /* Print the disjuncts of a map (or set).
675  * If the map turns out to be a universal parameter domain, then
676  * we need to print the colon.  Otherwise, the output looks identical
677  * to the empty set.
678  */
679 static __isl_give isl_printer *print_disjuncts_map(__isl_keep isl_map *map,
680         __isl_take isl_printer *p, int latex)
681 {
682         if (isl_map_plain_is_universe(map) && isl_space_is_params(map->dim))
683                 return isl_printer_print_str(p, s_such_that[latex]);
684         else
685                 return print_disjuncts(map, p, latex);
686 }
687
688 struct isl_aff_split {
689         isl_basic_map *aff;
690         isl_map *map;
691 };
692
693 static void free_split(__isl_take struct isl_aff_split *split, int n)
694 {
695         int i;
696
697         if (!split)
698                 return;
699
700         for (i = 0; i < n; ++i) {
701                 isl_basic_map_free(split[i].aff);
702                 isl_map_free(split[i].map);
703         }
704
705         free(split);
706 }
707
708 static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap)
709 {
710         int i, j;
711         unsigned nparam, n_in, n_out, total;
712
713         bmap = isl_basic_map_cow(bmap);
714         if (!bmap)
715                 return NULL;
716         if (isl_basic_map_free_inequality(bmap, bmap->n_ineq) < 0)
717                 goto error;
718
719         nparam = isl_basic_map_dim(bmap, isl_dim_param);
720         n_in = isl_basic_map_dim(bmap, isl_dim_in);
721         n_out = isl_basic_map_dim(bmap, isl_dim_out);
722         total = isl_basic_map_dim(bmap, isl_dim_all);
723         for (i = bmap->n_eq - 1; i >= 0; --i) {
724                 j = isl_seq_last_non_zero(bmap->eq[i] + 1, total);
725                 if (j >= nparam && j < nparam + n_in + n_out &&
726                     (isl_int_is_one(bmap->eq[i][1 + j]) ||
727                      isl_int_is_negone(bmap->eq[i][1 + j])))
728                         continue;
729                 if (isl_basic_map_drop_equality(bmap, i) < 0)
730                         goto error;
731         }
732
733         bmap = isl_basic_map_finalize(bmap);
734
735         return bmap;
736 error:
737         isl_basic_map_free(bmap);
738         return NULL;
739 }
740
741 static int aff_split_cmp(const void *p1, const void *p2)
742 {
743         const struct isl_aff_split *s1, *s2;
744         s1 = (const struct isl_aff_split *) p1;
745         s2 = (const struct isl_aff_split *) p2;
746
747         return isl_basic_map_plain_cmp(s1->aff, s2->aff);
748 }
749
750 static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap,
751         __isl_keep isl_basic_map *aff)
752 {
753         int i, j;
754         unsigned total;
755
756         if (!bmap || !aff)
757                 goto error;
758
759         total = isl_space_dim(bmap->dim, isl_dim_all);
760
761         for (i = bmap->n_eq - 1; i >= 0; --i) {
762                 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + total,
763                                             bmap->n_div) != -1)
764                         continue;
765                 for (j = 0; j < aff->n_eq; ++j) {
766                         if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + total) &&
767                             !isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + total))
768                                 continue;
769                         if (isl_basic_map_drop_equality(bmap, i) < 0)
770                                 goto error;
771                         break;
772                 }
773         }
774
775         return bmap;
776 error:
777         isl_basic_map_free(bmap);
778         return NULL;
779 }
780
781 static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map)
782 {
783         int i, n;
784         struct isl_aff_split *split;
785         isl_ctx *ctx;
786
787         ctx = isl_map_get_ctx(map);
788         split = isl_calloc_array(ctx, struct isl_aff_split, map->n);
789         if (!split)
790                 return NULL;
791
792         for (i = 0; i < map->n; ++i) {
793                 isl_basic_map *bmap;
794                 split[i].aff = get_aff(isl_basic_map_copy(map->p[i]));
795                 bmap = isl_basic_map_copy(map->p[i]);
796                 bmap = isl_basic_map_cow(bmap);
797                 bmap = drop_aff(bmap, split[i].aff);
798                 split[i].map = isl_map_from_basic_map(bmap);
799                 if (!split[i].aff || !split[i].map)
800                         goto error;
801         }
802
803         qsort(split, map->n, sizeof(struct isl_aff_split), &aff_split_cmp);
804
805         n = map->n;
806         for (i = n - 1; i >= 1; --i) {
807                 if (!isl_basic_map_plain_is_equal(split[i - 1].aff,
808                                                  split[i].aff))
809                         continue;
810                 isl_basic_map_free(split[i].aff);
811                 split[i - 1].map = isl_map_union(split[i - 1].map,
812                                                  split[i].map);
813                 if (i != n - 1)
814                         split[i] = split[n - 1];
815                 split[n - 1].aff = NULL;
816                 split[n - 1].map = NULL;
817                 --n;
818         }
819
820         return split;
821 error:
822         free_split(split, map->n);
823         return NULL;
824 }
825
826 static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p,
827         struct isl_aff_split *split, int n)
828 {
829         int i;
830         int rational;
831
832         for (i = 0; i < n; ++i) {
833                 isl_space *dim;
834
835                 if (!split[i].map)
836                         break;
837                 dim = split[i].map->dim;
838                 rational = split[i].map->n > 0 &&
839                     ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL);
840                 if (i)
841                         p = isl_printer_print_str(p, "; ");
842                 p = print_space(dim, p, 0, rational, split[i].aff, NULL);
843                 p = print_disjuncts_map(split[i].map, p, 0);
844         }
845
846         return p;
847 }
848
849 static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map,
850         __isl_take isl_printer *p)
851 {
852         struct isl_aff_split *split = NULL;
853         int rational;
854
855         if (map->n > 0)
856                 split = split_aff(map);
857         if (split) {
858                 p = print_split_map(p, split, map->n);
859         } else {
860                 rational = map->n > 0 &&
861                     ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL);
862                 p = print_space(map->dim, p, 0, rational, NULL, NULL);
863                 p = print_disjuncts_map(map, p, 0);
864         }
865         free_split(split, map->n);
866         return p;
867 }
868
869 static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,
870         __isl_take isl_printer *p)
871 {
872         if (isl_map_dim(map, isl_dim_param) > 0) {
873                 p = print_tuple(map->dim, p, isl_dim_param, 0, NULL, NULL);
874                 p = isl_printer_print_str(p, s_to[0]);
875         }
876         p = isl_printer_print_str(p, s_open_set[0]);
877         p = isl_map_print_isl_body(map, p);
878         p = isl_printer_print_str(p, s_close_set[0]);
879         return p;
880 }
881
882 static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map,
883         __isl_take isl_printer *p, __isl_keep isl_basic_map *aff)
884 {
885         if (isl_map_dim(map, isl_dim_param) > 0) {
886                 p = print_tuple(map->dim, p, isl_dim_param, 1, NULL, NULL);
887                 p = isl_printer_print_str(p, s_to[1]);
888         }
889         p = isl_printer_print_str(p, s_open_set[1]);
890         p = print_space(map->dim, p, 1, 0, aff, NULL);
891         p = print_disjuncts_map(map, p, 1);
892         p = isl_printer_print_str(p, s_close_set[1]);
893
894         return p;
895 }
896
897 static __isl_give isl_printer *isl_map_print_latex(__isl_keep isl_map *map,
898         __isl_take isl_printer *p)
899 {
900         int i;
901         struct isl_aff_split *split = NULL;
902
903         if (map->n > 0)
904                 split = split_aff(map);
905
906         if (!split)
907                 return print_latex_map(map, p, NULL);
908
909         for (i = 0; i < map->n; ++i) {
910                 if (!split[i].map)
911                         break;
912                 if (i)
913                         p = isl_printer_print_str(p, " \\cup ");
914                 p = print_latex_map(split[i].map, p, split[i].aff);
915         }
916
917         free_split(split, map->n);
918         return p;
919 }
920
921 __isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p,
922         __isl_keep isl_basic_map *bmap)
923 {
924         if (!p || !bmap)
925                 goto error;
926         if (p->output_format == ISL_FORMAT_ISL)
927                 return isl_basic_map_print_isl(bmap, p, 0);
928         else if (p->output_format == ISL_FORMAT_OMEGA)
929                 return basic_map_print_omega(bmap, p);
930         isl_assert(bmap->ctx, 0, goto error);
931 error:
932         isl_printer_free(p);
933         return NULL;
934 }
935
936 void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent,
937         const char *prefix, const char *suffix, unsigned output_format)
938 {
939         isl_printer *printer;
940
941         if (!bmap)
942                 return;
943
944         printer = isl_printer_to_file(bmap->ctx, out);
945         printer = isl_printer_set_indent(printer, indent);
946         printer = isl_printer_set_prefix(printer, prefix);
947         printer = isl_printer_set_suffix(printer, suffix);
948         printer = isl_printer_set_output_format(printer, output_format);
949         isl_printer_print_basic_map(printer, bmap);
950
951         isl_printer_free(printer);
952 }
953
954 __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,
955         __isl_keep isl_basic_set *bset)
956 {
957         if (!p || !bset)
958                 goto error;
959
960         if (p->output_format == ISL_FORMAT_ISL)
961                 return isl_basic_map_print_isl(bset, p, 0);
962         else if (p->output_format == ISL_FORMAT_POLYLIB)
963                 return isl_basic_set_print_polylib(bset, p, 0);
964         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
965                 return isl_basic_set_print_polylib(bset, p, 1);
966         else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)
967                 return bset_print_constraints_polylib(bset, p);
968         else if (p->output_format == ISL_FORMAT_OMEGA)
969                 return basic_set_print_omega(bset, p);
970         isl_assert(p->ctx, 0, goto error);
971 error:
972         isl_printer_free(p);
973         return NULL;
974 }
975
976 void isl_basic_set_print(struct isl_basic_set *bset, FILE *out, int indent,
977         const char *prefix, const char *suffix, unsigned output_format)
978 {
979         isl_printer *printer;
980
981         if (!bset)
982                 return;
983
984         printer = isl_printer_to_file(bset->ctx, out);
985         printer = isl_printer_set_indent(printer, indent);
986         printer = isl_printer_set_prefix(printer, prefix);
987         printer = isl_printer_set_suffix(printer, suffix);
988         printer = isl_printer_set_output_format(printer, output_format);
989         isl_printer_print_basic_set(printer, bset);
990
991         isl_printer_free(printer);
992 }
993
994 __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,
995         __isl_keep isl_set *set)
996 {
997         if (!p || !set)
998                 goto error;
999         if (p->output_format == ISL_FORMAT_ISL)
1000                 return isl_map_print_isl((isl_map *)set, p);
1001         else if (p->output_format == ISL_FORMAT_POLYLIB)
1002                 return isl_set_print_polylib(set, p, 0);
1003         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1004                 return isl_set_print_polylib(set, p, 1);
1005         else if (p->output_format == ISL_FORMAT_OMEGA)
1006                 return isl_set_print_omega(set, p);
1007         else if (p->output_format == ISL_FORMAT_LATEX)
1008                 return isl_map_print_latex((isl_map *)set, p);
1009         isl_assert(set->ctx, 0, goto error);
1010 error:
1011         isl_printer_free(p);
1012         return NULL;
1013 }
1014
1015 void isl_set_print(struct isl_set *set, FILE *out, int indent,
1016         unsigned output_format)
1017 {
1018         isl_printer *printer;
1019
1020         if (!set)
1021                 return;
1022
1023         printer = isl_printer_to_file(set->ctx, out);
1024         printer = isl_printer_set_indent(printer, indent);
1025         printer = isl_printer_set_output_format(printer, output_format);
1026         printer = isl_printer_print_set(printer, set);
1027
1028         isl_printer_free(printer);
1029 }
1030
1031 __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
1032         __isl_keep isl_map *map)
1033 {
1034         if (!p || !map)
1035                 goto error;
1036
1037         if (p->output_format == ISL_FORMAT_ISL)
1038                 return isl_map_print_isl(map, p);
1039         else if (p->output_format == ISL_FORMAT_POLYLIB)
1040                 return isl_map_print_polylib(map, p, 0);
1041         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1042                 return isl_map_print_polylib(map, p, 1);
1043         else if (p->output_format == ISL_FORMAT_OMEGA)
1044                 return isl_map_print_omega(map, p);
1045         else if (p->output_format == ISL_FORMAT_LATEX)
1046                 return isl_map_print_latex(map, p);
1047         isl_assert(map->ctx, 0, goto error);
1048 error:
1049         isl_printer_free(p);
1050         return NULL;
1051 }
1052
1053 struct isl_union_print_data {
1054         isl_printer *p;
1055         int first;
1056 };
1057
1058 static int print_map_body(__isl_take isl_map *map, void *user)
1059 {
1060         struct isl_union_print_data *data;
1061         data = (struct isl_union_print_data *)user;
1062
1063         if (!data->first)
1064                 data->p = isl_printer_print_str(data->p, "; ");
1065         data->first = 0;
1066
1067         data->p = isl_map_print_isl_body(map, data->p);
1068         isl_map_free(map);
1069
1070         return 0;
1071 }
1072
1073 static __isl_give isl_printer *isl_union_map_print_isl(
1074         __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
1075 {
1076         struct isl_union_print_data data = { p, 1 };
1077         isl_space *dim;
1078         dim = isl_union_map_get_space(umap);
1079         if (isl_space_dim(dim, isl_dim_param) > 0) {
1080                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1081                 p = isl_printer_print_str(p, s_to[0]);
1082         }
1083         isl_space_free(dim);
1084         p = isl_printer_print_str(p, s_open_set[0]);
1085         isl_union_map_foreach_map(umap, &print_map_body, &data);
1086         p = data.p;
1087         p = isl_printer_print_str(p, s_close_set[0]);
1088         return p;
1089 }
1090
1091 static int print_latex_map_body(__isl_take isl_map *map, void *user)
1092 {
1093         struct isl_union_print_data *data;
1094         data = (struct isl_union_print_data *)user;
1095
1096         if (!data->first)
1097                 data->p = isl_printer_print_str(data->p, " \\cup ");
1098         data->first = 0;
1099
1100         data->p = isl_map_print_latex(map, data->p);
1101         isl_map_free(map);
1102
1103         return 0;
1104 }
1105
1106 static __isl_give isl_printer *isl_union_map_print_latex(
1107         __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
1108 {
1109         struct isl_union_print_data data = { p, 1 };
1110         isl_union_map_foreach_map(umap, &print_latex_map_body, &data);
1111         p = data.p;
1112         return p;
1113 }
1114
1115 __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p,
1116         __isl_keep isl_union_map *umap)
1117 {
1118         if (!p || !umap)
1119                 goto error;
1120
1121         if (p->output_format == ISL_FORMAT_ISL)
1122                 return isl_union_map_print_isl(umap, p);
1123         if (p->output_format == ISL_FORMAT_LATEX)
1124                 return isl_union_map_print_latex(umap, p);
1125
1126         isl_die(p->ctx, isl_error_invalid,
1127                 "invalid output format for isl_union_map", goto error);
1128 error:
1129         isl_printer_free(p);
1130         return NULL;
1131 }
1132
1133 __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
1134         __isl_keep isl_union_set *uset)
1135 {
1136         if (!p || !uset)
1137                 goto error;
1138
1139         if (p->output_format == ISL_FORMAT_ISL)
1140                 return isl_union_map_print_isl((isl_union_map *)uset, p);
1141         if (p->output_format == ISL_FORMAT_LATEX)
1142                 return isl_union_map_print_latex((isl_union_map *)uset, p);
1143
1144         isl_die(p->ctx, isl_error_invalid,
1145                 "invalid output format for isl_union_set", goto error);
1146 error:
1147         isl_printer_free(p);
1148         return NULL;
1149 }
1150
1151 void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent,
1152         unsigned output_format)
1153 {
1154         isl_printer *printer;
1155
1156         if (!map)
1157                 return;
1158
1159         printer = isl_printer_to_file(map->ctx, out);
1160         printer = isl_printer_set_indent(printer, indent);
1161         printer = isl_printer_set_output_format(printer, output_format);
1162         printer = isl_printer_print_map(printer, map);
1163
1164         isl_printer_free(printer);
1165 }
1166
1167 static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec)
1168 {
1169         int i;
1170         int n;
1171
1172         for (i = 0, n = 0; i < rec->n; ++i)
1173                 if (!isl_upoly_is_zero(rec->p[i]))
1174                         ++n;
1175
1176         return n;
1177 }
1178
1179 static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
1180         __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p)
1181 {
1182         int c = p->output_format == ISL_FORMAT_C;
1183         p = isl_printer_print_str(p, c ? "floord(" : "[(");
1184         p = print_affine_of_len(dim, div, p,
1185                                 div->row[pos] + 1, div->n_col - 1);
1186         p = isl_printer_print_str(p, c ? ", " : ")/");
1187         p = isl_printer_print_isl_int(p, div->row[pos][0]);
1188         p = isl_printer_print_str(p, c ? ")" : "]");
1189         return p;
1190 }
1191
1192 static __isl_give isl_printer *upoly_print_cst(__isl_keep struct isl_upoly *up,
1193         __isl_take isl_printer *p, int first)
1194 {
1195         struct isl_upoly_cst *cst;
1196         int neg;
1197
1198         cst = isl_upoly_as_cst(up);
1199         if (!cst)
1200                 goto error;
1201         neg = !first && isl_int_is_neg(cst->n);
1202         if (!first)
1203                 p = isl_printer_print_str(p, neg ? " - " :  " + ");
1204         if (neg)
1205                 isl_int_neg(cst->n, cst->n);
1206         if (isl_int_is_zero(cst->d)) {
1207                 int sgn = isl_int_sgn(cst->n);
1208                 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
1209                                             sgn == 0 ? "NaN" : "infty");
1210         } else
1211                 p = isl_printer_print_isl_int(p, cst->n);
1212         if (neg)
1213                 isl_int_neg(cst->n, cst->n);
1214         if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) {
1215                 p = isl_printer_print_str(p, "/");
1216                 p = isl_printer_print_isl_int(p, cst->d);
1217         }
1218         return p;
1219 error:
1220         isl_printer_free(p);
1221         return NULL;
1222 }
1223
1224 static __isl_give isl_printer *print_base(__isl_take isl_printer *p,
1225         __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var)
1226 {
1227         unsigned total;
1228
1229         total = isl_space_dim(dim, isl_dim_all);
1230         if (var < total)
1231                 p = print_term(dim, NULL, dim->ctx->one, 1 + var, p, 0);
1232         else
1233                 p = print_div(dim, div, var - total, p);
1234         return p;
1235 }
1236
1237 static __isl_give isl_printer *print_pow(__isl_take isl_printer *p,
1238         __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var, int exp)
1239 {
1240         p = print_base(p, dim, div, var);
1241         if (exp == 1)
1242                 return p;
1243         if (p->output_format == ISL_FORMAT_C) {
1244                 int i;
1245                 for (i = 1; i < exp; ++i) {
1246                         p = isl_printer_print_str(p, "*");
1247                         p = print_base(p, dim, div, var);
1248                 }
1249         } else {
1250                 p = isl_printer_print_str(p, "^");
1251                 p = isl_printer_print_int(p, exp);
1252         }
1253         return p;
1254 }
1255
1256 static __isl_give isl_printer *upoly_print(__isl_keep struct isl_upoly *up,
1257         __isl_keep isl_space *dim, __isl_keep isl_mat *div,
1258         __isl_take isl_printer *p, int outer)
1259 {
1260         int i, n, first, print_parens;
1261         struct isl_upoly_rec *rec;
1262
1263         if (!p || !up || !dim || !div)
1264                 goto error;
1265
1266         if (isl_upoly_is_cst(up))
1267                 return upoly_print_cst(up, p, 1);
1268
1269         rec = isl_upoly_as_rec(up);
1270         if (!rec)
1271                 goto error;
1272         n = upoly_rec_n_non_zero(rec);
1273         print_parens = n > 1 ||
1274                     (outer && rec->up.var >= isl_space_dim(dim, isl_dim_all));
1275         if (print_parens)
1276                 p = isl_printer_print_str(p, "(");
1277         for (i = 0, first = 1; i < rec->n; ++i) {
1278                 if (isl_upoly_is_zero(rec->p[i]))
1279                         continue;
1280                 if (isl_upoly_is_negone(rec->p[i])) {
1281                         if (!i)
1282                                 p = isl_printer_print_str(p, "-1");
1283                         else if (first)
1284                                 p = isl_printer_print_str(p, "-");
1285                         else
1286                                 p = isl_printer_print_str(p, " - ");
1287                 } else if (isl_upoly_is_cst(rec->p[i]) &&
1288                                 !isl_upoly_is_one(rec->p[i]))
1289                         p = upoly_print_cst(rec->p[i], p, first);
1290                 else {
1291                         if (!first)
1292                                 p = isl_printer_print_str(p, " + ");
1293                         if (i == 0 || !isl_upoly_is_one(rec->p[i]))
1294                                 p = upoly_print(rec->p[i], dim, div, p, 0);
1295                 }
1296                 first = 0;
1297                 if (i == 0)
1298                         continue;
1299                 if (!isl_upoly_is_one(rec->p[i]) &&
1300                     !isl_upoly_is_negone(rec->p[i]))
1301                         p = isl_printer_print_str(p, " * ");
1302                 p = print_pow(p, dim, div, rec->up.var, i);
1303         }
1304         if (print_parens)
1305                 p = isl_printer_print_str(p, ")");
1306         return p;
1307 error:
1308         isl_printer_free(p);
1309         return NULL;
1310 }
1311
1312 static __isl_give isl_printer *print_qpolynomial(__isl_take isl_printer *p,
1313         __isl_keep isl_qpolynomial *qp)
1314 {
1315         if (!p || !qp)
1316                 goto error;
1317         p = upoly_print(qp->upoly, qp->dim, qp->div, p, 1);
1318         return p;
1319 error:
1320         isl_printer_free(p);
1321         return NULL;
1322 }
1323
1324 static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p,
1325         __isl_keep isl_qpolynomial *qp)
1326 {
1327         if (!p || !qp)
1328                 goto error;
1329
1330         if (isl_space_dim(qp->dim, isl_dim_param) > 0) {
1331                 p = print_tuple(qp->dim, p, isl_dim_param, 0, NULL, NULL);
1332                 p = isl_printer_print_str(p, " -> ");
1333         }
1334         p = isl_printer_print_str(p, "{ ");
1335         if (!isl_space_is_params(qp->dim)) {
1336                 p = print_space(qp->dim, p, 0, 0, NULL, NULL);
1337                 p = isl_printer_print_str(p, " -> ");
1338         }
1339         p = print_qpolynomial(p, qp);
1340         p = isl_printer_print_str(p, " }");
1341         return p;
1342 error:
1343         isl_printer_free(p);
1344         return NULL;
1345 }
1346
1347 static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p,
1348         __isl_keep isl_space *dim, __isl_keep isl_qpolynomial *qp)
1349 {
1350         isl_int den;
1351
1352         isl_int_init(den);
1353         isl_qpolynomial_get_den(qp, &den);
1354         if (!isl_int_is_one(den)) {
1355                 isl_qpolynomial *f;
1356                 p = isl_printer_print_str(p, "(");
1357                 qp = isl_qpolynomial_copy(qp);
1358                 f = isl_qpolynomial_rat_cst_on_domain(isl_space_copy(qp->dim),
1359                                                 den, qp->dim->ctx->one);
1360                 qp = isl_qpolynomial_mul(qp, f);
1361         }
1362         if (qp)
1363                 p = upoly_print(qp->upoly, dim, qp->div, p, 0);
1364         if (!isl_int_is_one(den)) {
1365                 p = isl_printer_print_str(p, ")/");
1366                 p = isl_printer_print_isl_int(p, den);
1367                 isl_qpolynomial_free(qp);
1368         }
1369         isl_int_clear(den);
1370         return p;
1371 }
1372
1373 __isl_give isl_printer *isl_printer_print_qpolynomial(
1374         __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp)
1375 {
1376         if (!p || !qp)
1377                 goto error;
1378
1379         if (p->output_format == ISL_FORMAT_ISL)
1380                 return print_qpolynomial_isl(p, qp);
1381         else if (p->output_format == ISL_FORMAT_C)
1382                 return print_qpolynomial_c(p, qp->dim, qp);
1383         else
1384                 isl_die(qp->dim->ctx, isl_error_unsupported,
1385                         "output format not supported for isl_qpolynomials",
1386                         goto error);
1387 error:
1388         isl_printer_free(p);
1389         return NULL;
1390 }
1391
1392 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
1393         unsigned output_format)
1394 {
1395         isl_printer *p;
1396
1397         if  (!qp)
1398                 return;
1399
1400         isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1401         p = isl_printer_to_file(qp->dim->ctx, out);
1402         p = isl_printer_print_qpolynomial(p, qp);
1403         isl_printer_free(p);
1404 }
1405
1406 static __isl_give isl_printer *qpolynomial_fold_print(
1407         __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
1408 {
1409         int i;
1410
1411         if (fold->type == isl_fold_min)
1412                 p = isl_printer_print_str(p, "min");
1413         else if (fold->type == isl_fold_max)
1414                 p = isl_printer_print_str(p, "max");
1415         p = isl_printer_print_str(p, "(");
1416         for (i = 0; i < fold->n; ++i) {
1417                 if (i)
1418                         p = isl_printer_print_str(p, ", ");
1419                 p = print_qpolynomial(p, fold->qp[i]);
1420         }
1421         p = isl_printer_print_str(p, ")");
1422         return p;
1423 }
1424
1425 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
1426         FILE *out, unsigned output_format)
1427 {
1428         isl_printer *p;
1429
1430         if (!fold)
1431                 return;
1432
1433         isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1434
1435         p = isl_printer_to_file(fold->dim->ctx, out);
1436         p = isl_printer_print_qpolynomial_fold(p, fold);
1437
1438         isl_printer_free(p);
1439 }
1440
1441 static __isl_give isl_printer *isl_pwqp_print_isl_body(
1442         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1443 {
1444         int i = 0;
1445
1446         for (i = 0; i < pwqp->n; ++i) {
1447                 if (i)
1448                         p = isl_printer_print_str(p, "; ");
1449                 if (!isl_space_is_params(pwqp->p[i].set->dim)) {
1450                         p = print_space(pwqp->p[i].set->dim, p, 0, 0, NULL, NULL);
1451                         p = isl_printer_print_str(p, " -> ");
1452                 }
1453                 p = print_qpolynomial(p, pwqp->p[i].qp);
1454                 p = print_disjuncts((isl_map *)pwqp->p[i].set, p, 0);
1455         }
1456
1457         return p;
1458 }
1459
1460 static __isl_give isl_printer *print_pw_qpolynomial_isl(
1461         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1462 {
1463         if (!p || !pwqp)
1464                 goto error;
1465
1466         if (isl_space_dim(pwqp->dim, isl_dim_param) > 0) {
1467                 p = print_tuple(pwqp->dim, p, isl_dim_param, 0, NULL, NULL);
1468                 p = isl_printer_print_str(p, " -> ");
1469         }
1470         p = isl_printer_print_str(p, "{ ");
1471         if (pwqp->n == 0) {
1472                 if (!isl_space_is_set(pwqp->dim)) {
1473                         p = print_tuple(pwqp->dim, p, isl_dim_in, 0, NULL, NULL);
1474                         p = isl_printer_print_str(p, " -> ");
1475                 }
1476                 p = isl_printer_print_str(p, "0");
1477         }
1478         p = isl_pwqp_print_isl_body(p, pwqp);
1479         p = isl_printer_print_str(p, " }");
1480         return p;
1481 error:
1482         isl_printer_free(p);
1483         return NULL;
1484 }
1485
1486 void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
1487         unsigned output_format)
1488 {
1489         isl_printer *p;
1490
1491         if (!pwqp)
1492                 return;
1493
1494         p = isl_printer_to_file(pwqp->dim->ctx, out);
1495         p = isl_printer_set_output_format(p, output_format);
1496         p = isl_printer_print_pw_qpolynomial(p, pwqp);
1497
1498         isl_printer_free(p);
1499 }
1500
1501 static __isl_give isl_printer *isl_pwf_print_isl_body(
1502         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1503 {
1504         int i = 0;
1505
1506         for (i = 0; i < pwf->n; ++i) {
1507                 if (i)
1508                         p = isl_printer_print_str(p, "; ");
1509                 if (!isl_space_is_params(pwf->p[i].set->dim)) {
1510                         p = print_space(pwf->p[i].set->dim, p, 0, 0, NULL, NULL);
1511                         p = isl_printer_print_str(p, " -> ");
1512                 }
1513                 p = qpolynomial_fold_print(pwf->p[i].fold, p);
1514                 p = print_disjuncts((isl_map *)pwf->p[i].set, p, 0);
1515         }
1516
1517         return p;
1518 }
1519
1520 static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(
1521         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1522 {
1523         if (isl_space_dim(pwf->dim, isl_dim_param) > 0) {
1524                 p = print_tuple(pwf->dim, p, isl_dim_param, 0, NULL, NULL);
1525                 p = isl_printer_print_str(p, " -> ");
1526         }
1527         p = isl_printer_print_str(p, "{ ");
1528         if (pwf->n == 0) {
1529                 if (!isl_space_is_set(pwf->dim)) {
1530                         p = print_tuple(pwf->dim, p, isl_dim_in, 0, NULL, NULL);
1531                         p = isl_printer_print_str(p, " -> ");
1532                 }
1533                 p = isl_printer_print_str(p, "0");
1534         }
1535         p = isl_pwf_print_isl_body(p, pwf);
1536         p = isl_printer_print_str(p, " }");
1537         return p;
1538 }
1539
1540 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1541         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c);
1542
1543 static __isl_give isl_printer *print_name_c(__isl_take isl_printer *p,
1544         __isl_keep isl_space *dim,
1545         __isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos)
1546 {
1547         if (type == isl_dim_div) {
1548                 p = isl_printer_print_str(p, "floord(");
1549                 p = print_affine_c(p, dim, bset, bset->div[pos] + 1);
1550                 p = isl_printer_print_str(p, ", ");
1551                 p = isl_printer_print_isl_int(p, bset->div[pos][0]);
1552                 p = isl_printer_print_str(p, ")");
1553         } else {
1554                 const char *name;
1555
1556                 name = isl_space_get_dim_name(dim, type, pos);
1557                 if (!name)
1558                         name = "UNNAMED";
1559                 p = isl_printer_print_str(p, name);
1560         }
1561         return p;
1562 }
1563
1564 static __isl_give isl_printer *print_term_c(__isl_take isl_printer *p,
1565         __isl_keep isl_space *dim,
1566         __isl_keep isl_basic_set *bset, isl_int c, unsigned pos)
1567 {
1568         enum isl_dim_type type;
1569
1570         if (pos == 0)
1571                 return isl_printer_print_isl_int(p, c);
1572
1573         if (isl_int_is_one(c))
1574                 ;
1575         else if (isl_int_is_negone(c))
1576                 p = isl_printer_print_str(p, "-");
1577         else {
1578                 p = isl_printer_print_isl_int(p, c);
1579                 p = isl_printer_print_str(p, "*");
1580         }
1581         type = pos2type(dim, &pos);
1582         p = print_name_c(p, dim, bset, type, pos);
1583         return p;
1584 }
1585
1586 static __isl_give isl_printer *print_partial_affine_c(__isl_take isl_printer *p,
1587         __isl_keep isl_space *dim,
1588         __isl_keep isl_basic_set *bset, isl_int *c, unsigned len)
1589 {
1590         int i;
1591         int first;
1592
1593         for (i = 0, first = 1; i < len; ++i) {
1594                 int flip = 0;
1595                 if (isl_int_is_zero(c[i]))
1596                         continue;
1597                 if (!first) {
1598                         if (isl_int_is_neg(c[i])) {
1599                                 flip = 1;
1600                                 isl_int_neg(c[i], c[i]);
1601                                 p = isl_printer_print_str(p, " - ");
1602                         } else 
1603                                 p = isl_printer_print_str(p, " + ");
1604                 }
1605                 first = 0;
1606                 p = print_term_c(p, dim, bset, c[i], i);
1607                 if (flip)
1608                         isl_int_neg(c[i], c[i]);
1609         }
1610         if (first)
1611                 p = isl_printer_print_str(p, "0");
1612         return p;
1613 }
1614
1615 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1616         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c)
1617 {
1618         unsigned len = 1 + isl_basic_set_total_dim(bset);
1619         return print_partial_affine_c(p, dim, bset, c, len);
1620 }
1621
1622 /* We skip the constraint if it is implied by the div expression.
1623  */
1624 static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,
1625         __isl_keep isl_space *dim,
1626         __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int first)
1627 {
1628         unsigned o_div;
1629         unsigned n_div;
1630         int div;
1631
1632         o_div = isl_basic_set_offset(bset, isl_dim_div);
1633         n_div = isl_basic_set_dim(bset, isl_dim_div);
1634         div = isl_seq_last_non_zero(c + o_div, n_div);
1635         if (div >= 0 && isl_basic_set_is_div_constraint(bset, c, div))
1636                 return p;
1637
1638         if (!first)
1639                 p = isl_printer_print_str(p, " && ");
1640
1641         p = print_affine_c(p, dim, bset, c);
1642         p = isl_printer_print_str(p, " ");
1643         p = isl_printer_print_str(p, op);
1644         p = isl_printer_print_str(p, " 0");
1645         return p;
1646 }
1647
1648 static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,
1649         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset)
1650 {
1651         int i, j;
1652         unsigned n_div = isl_basic_set_dim(bset, isl_dim_div);
1653         unsigned total = isl_basic_set_total_dim(bset) - n_div;
1654
1655         for (i = 0; i < bset->n_eq; ++i) {
1656                 j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div);
1657                 if (j < 0)
1658                         p = print_constraint_c(p, dim, bset,
1659                                                 bset->eq[i], "==", !i);
1660                 else {
1661                         if (i)
1662                                 p = isl_printer_print_str(p, " && ");
1663                         p = isl_printer_print_str(p, "(");
1664                         p = print_partial_affine_c(p, dim, bset, bset->eq[i],
1665                                                    1 + total + j);
1666                         p = isl_printer_print_str(p, ") % ");
1667                         p = isl_printer_print_isl_int(p,
1668                                                 bset->eq[i][1 + total + j]);
1669                         p = isl_printer_print_str(p, " == 0");
1670                 }
1671         }
1672         for (i = 0; i < bset->n_ineq; ++i)
1673                 p = print_constraint_c(p, dim, bset, bset->ineq[i], ">=",
1674                                         !bset->n_eq && !i);
1675         return p;
1676 }
1677
1678 static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,
1679         __isl_keep isl_space *dim, __isl_keep isl_set *set)
1680 {
1681         int i;
1682
1683         if (!set)
1684                 return isl_printer_free(p);
1685
1686         if (set->n == 0)
1687                 p = isl_printer_print_str(p, "0");
1688
1689         for (i = 0; i < set->n; ++i) {
1690                 if (i)
1691                         p = isl_printer_print_str(p, " || ");
1692                 if (set->n > 1)
1693                         p = isl_printer_print_str(p, "(");
1694                 p = print_basic_set_c(p, dim, set->p[i]);
1695                 if (set->n > 1)
1696                         p = isl_printer_print_str(p, ")");
1697         }
1698         return p;
1699 }
1700
1701 static __isl_give isl_printer *print_pw_qpolynomial_c(
1702         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1703 {
1704         int i;
1705
1706         if (pwqp->n == 1 && isl_set_plain_is_universe(pwqp->p[0].set))
1707                 return print_qpolynomial_c(p, pwqp->dim, pwqp->p[0].qp);
1708
1709         for (i = 0; i < pwqp->n; ++i) {
1710                 p = isl_printer_print_str(p, "(");
1711                 p = print_set_c(p, pwqp->dim, pwqp->p[i].set);
1712                 p = isl_printer_print_str(p, ") ? (");
1713                 p = print_qpolynomial_c(p, pwqp->dim, pwqp->p[i].qp);
1714                 p = isl_printer_print_str(p, ") : ");
1715         }
1716
1717         p = isl_printer_print_str(p, "0");
1718         return p;
1719 }
1720
1721 __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
1722         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1723 {
1724         if (!p || !pwqp)
1725                 goto error;
1726
1727         if (p->output_format == ISL_FORMAT_ISL)
1728                 return print_pw_qpolynomial_isl(p, pwqp);
1729         else if (p->output_format == ISL_FORMAT_C)
1730                 return print_pw_qpolynomial_c(p, pwqp);
1731         isl_assert(p->ctx, 0, goto error);
1732 error:
1733         isl_printer_free(p);
1734         return NULL;
1735 }
1736
1737 static int print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user)
1738 {
1739         struct isl_union_print_data *data;
1740         data = (struct isl_union_print_data *)user;
1741
1742         if (!data->first)
1743                 data->p = isl_printer_print_str(data->p, "; ");
1744         data->first = 0;
1745
1746         data->p = isl_pwqp_print_isl_body(data->p, pwqp);
1747         isl_pw_qpolynomial_free(pwqp);
1748
1749         return 0;
1750 }
1751
1752 static __isl_give isl_printer *print_union_pw_qpolynomial_isl(
1753         __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
1754 {
1755         struct isl_union_print_data data = { p, 1 };
1756         isl_space *dim;
1757         dim = isl_union_pw_qpolynomial_get_space(upwqp);
1758         if (isl_space_dim(dim, isl_dim_param) > 0) {
1759                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1760                 p = isl_printer_print_str(p, " -> ");
1761         }
1762         isl_space_free(dim);
1763         p = isl_printer_print_str(p, "{ ");
1764         isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body,
1765                                                         &data);
1766         p = data.p;
1767         p = isl_printer_print_str(p, " }");
1768         return p;
1769 }
1770
1771 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial(
1772         __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
1773 {
1774         if (!p || !upwqp)
1775                 goto error;
1776
1777         if (p->output_format == ISL_FORMAT_ISL)
1778                 return print_union_pw_qpolynomial_isl(p, upwqp);
1779         isl_die(p->ctx, isl_error_invalid,
1780                 "invalid output format for isl_union_pw_qpolynomial",
1781                 goto error);
1782 error:
1783         isl_printer_free(p);
1784         return NULL;
1785 }
1786
1787 static __isl_give isl_printer *print_qpolynomial_fold_c(
1788         __isl_take isl_printer *p, __isl_keep isl_space *dim,
1789         __isl_keep isl_qpolynomial_fold *fold)
1790 {
1791         int i;
1792
1793         for (i = 0; i < fold->n - 1; ++i)
1794                 if (fold->type == isl_fold_min)
1795                         p = isl_printer_print_str(p, "min(");
1796                 else if (fold->type == isl_fold_max)
1797                         p = isl_printer_print_str(p, "max(");
1798
1799         for (i = 0; i < fold->n; ++i) {
1800                 if (i)
1801                         p = isl_printer_print_str(p, ", ");
1802                 p = print_qpolynomial_c(p, dim, fold->qp[i]);
1803                 if (i)
1804                         p = isl_printer_print_str(p, ")");
1805         }
1806         return p;
1807 }
1808
1809 __isl_give isl_printer *isl_printer_print_qpolynomial_fold(
1810         __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
1811 {
1812         if  (!p || !fold)
1813                 goto error;
1814         if (p->output_format == ISL_FORMAT_ISL)
1815                 return qpolynomial_fold_print(fold, p);
1816         else if (p->output_format == ISL_FORMAT_C)
1817                 return print_qpolynomial_fold_c(p, fold->dim, fold);
1818         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
1819                 goto error);
1820 error:
1821         isl_printer_free(p);
1822         return NULL;
1823 }
1824
1825 static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
1826         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1827 {
1828         int i;
1829
1830         if (pwf->n == 1 && isl_set_plain_is_universe(pwf->p[0].set))
1831                 return print_qpolynomial_fold_c(p, pwf->dim, pwf->p[0].fold);
1832
1833         for (i = 0; i < pwf->n; ++i) {
1834                 p = isl_printer_print_str(p, "(");
1835                 p = print_set_c(p, pwf->dim, pwf->p[i].set);
1836                 p = isl_printer_print_str(p, ") ? (");
1837                 p = print_qpolynomial_fold_c(p, pwf->dim, pwf->p[i].fold);
1838                 p = isl_printer_print_str(p, ") : ");
1839         }
1840
1841         p = isl_printer_print_str(p, "0");
1842         return p;
1843 }
1844
1845 __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
1846         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1847 {
1848         if (!p || !pwf)
1849                 goto error;
1850
1851         if (p->output_format == ISL_FORMAT_ISL)
1852                 return print_pw_qpolynomial_fold_isl(p, pwf);
1853         else if (p->output_format == ISL_FORMAT_C)
1854                 return print_pw_qpolynomial_fold_c(p, pwf);
1855         isl_assert(p->ctx, 0, goto error);
1856 error:
1857         isl_printer_free(p);
1858         return NULL;
1859 }
1860
1861 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
1862         FILE *out, unsigned output_format)
1863 {
1864         isl_printer *p;
1865
1866         if (!pwf)
1867                 return;
1868
1869         p = isl_printer_to_file(pwf->dim->ctx, out);
1870         p = isl_printer_set_output_format(p, output_format);
1871         p = isl_printer_print_pw_qpolynomial_fold(p, pwf);
1872
1873         isl_printer_free(p);
1874 }
1875
1876 static int print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf, void *user)
1877 {
1878         struct isl_union_print_data *data;
1879         data = (struct isl_union_print_data *)user;
1880
1881         if (!data->first)
1882                 data->p = isl_printer_print_str(data->p, "; ");
1883         data->first = 0;
1884
1885         data->p = isl_pwf_print_isl_body(data->p, pwf);
1886         isl_pw_qpolynomial_fold_free(pwf);
1887
1888         return 0;
1889 }
1890
1891 static __isl_give isl_printer *print_union_pw_qpolynomial_fold_isl(
1892         __isl_take isl_printer *p,
1893         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
1894 {
1895         struct isl_union_print_data data = { p, 1 };
1896         isl_space *dim;
1897         dim = isl_union_pw_qpolynomial_fold_get_space(upwf);
1898         if (isl_space_dim(dim, isl_dim_param) > 0) {
1899                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1900                 p = isl_printer_print_str(p, " -> ");
1901         }
1902         isl_space_free(dim);
1903         p = isl_printer_print_str(p, "{ ");
1904         isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf,
1905                                                         &print_pwf_body, &data);
1906         p = data.p;
1907         p = isl_printer_print_str(p, " }");
1908         return p;
1909 }
1910
1911 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold(
1912         __isl_take isl_printer *p,
1913         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
1914 {
1915         if (!p || !upwf)
1916                 goto error;
1917
1918         if (p->output_format == ISL_FORMAT_ISL)
1919                 return print_union_pw_qpolynomial_fold_isl(p, upwf);
1920         isl_die(p->ctx, isl_error_invalid,
1921                 "invalid output format for isl_union_pw_qpolynomial_fold",
1922                 goto error);
1923 error:
1924         isl_printer_free(p);
1925         return NULL;
1926 }
1927
1928 __isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p,
1929         __isl_keep isl_constraint *c)
1930 {
1931         isl_basic_map *bmap;
1932
1933         if (!p || !c)
1934                 goto error;
1935
1936         bmap = isl_basic_map_from_constraint(isl_constraint_copy(c));
1937         p = isl_printer_print_basic_map(p, bmap);
1938         isl_basic_map_free(bmap);
1939         return p;
1940 error:
1941         isl_printer_free(p);
1942         return NULL;
1943 }
1944
1945 static __isl_give isl_printer *isl_printer_print_space_isl(
1946         __isl_take isl_printer *p, __isl_keep isl_space *dim)
1947 {
1948         if (!dim)
1949                 goto error;
1950
1951         if (isl_space_dim(dim, isl_dim_param) > 0) {
1952                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1953                 p = isl_printer_print_str(p, " -> ");
1954         }
1955
1956         p = isl_printer_print_str(p, "{ ");
1957         if (isl_space_is_params(dim))
1958                 p = isl_printer_print_str(p, s_such_that[0]);
1959         else
1960                 p = print_space(dim, p, 0, 0, NULL, NULL);
1961         p = isl_printer_print_str(p, " }");
1962
1963         return p;
1964 error:
1965         isl_printer_free(p);
1966         return NULL;
1967 }
1968
1969 __isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p,
1970         __isl_keep isl_space *space)
1971 {
1972         if (!p || !space)
1973                 return isl_printer_free(p);
1974         if (p->output_format == ISL_FORMAT_ISL)
1975                 return isl_printer_print_space_isl(p, space);
1976         else if (p->output_format == ISL_FORMAT_OMEGA)
1977                 return print_omega_parameters(space, p);
1978
1979         isl_die(isl_space_get_ctx(space), isl_error_unsupported,
1980                 "output format not supported for space",
1981                 return isl_printer_free(p));
1982 }
1983
1984 __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p,
1985         __isl_keep isl_local_space *ls)
1986 {
1987         unsigned total;
1988         unsigned n_div;
1989
1990         if (!ls)
1991                 goto error;
1992
1993         total = isl_local_space_dim(ls, isl_dim_all);
1994         if (isl_local_space_dim(ls, isl_dim_param) > 0) {
1995                 p = print_tuple(ls->dim, p, isl_dim_param, 0, NULL, NULL);
1996                 p = isl_printer_print_str(p, " -> ");
1997         }
1998         p = isl_printer_print_str(p, "{ ");
1999         p = print_space(ls->dim, p, 0, 0, NULL, NULL);
2000         n_div = isl_local_space_dim(ls, isl_dim_div);
2001         if (n_div > 0) {
2002                 int i;
2003                 p = isl_printer_print_str(p, " : ");
2004                 p = isl_printer_print_str(p, s_open_exists[0]);
2005                 for (i = 0; i < n_div; ++i) {
2006                         if (i)
2007                                 p = isl_printer_print_str(p, ", ");
2008                         p = print_name(ls->dim, p, isl_dim_div, i, 0);
2009                         if (isl_int_is_zero(ls->div->row[i][0]))
2010                                 continue;
2011                         p = isl_printer_print_str(p, " = [(");
2012                         p = print_affine_of_len(ls->dim, ls->div, p,
2013                                             ls->div->row[i] + 1, 1 + total);
2014                         p = isl_printer_print_str(p, ")/");
2015                         p = isl_printer_print_isl_int(p, ls->div->row[i][0]);
2016                         p = isl_printer_print_str(p, "]");
2017                 }
2018         } else if (isl_space_is_params(ls->dim))
2019                 p = isl_printer_print_str(p, s_such_that[0]);
2020         p = isl_printer_print_str(p, " }");
2021         return p;
2022 error:
2023         isl_printer_free(p);
2024         return NULL;
2025 }
2026
2027 static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p,
2028         __isl_keep isl_aff *aff)
2029 {
2030         unsigned total;
2031
2032         total = isl_local_space_dim(aff->ls, isl_dim_all);
2033         p = isl_printer_print_str(p, "(");
2034         p = print_affine_of_len(aff->ls->dim, aff->ls->div, p,
2035                                 aff->v->el + 1, 1 + total);
2036         if (isl_int_is_one(aff->v->el[0]))
2037                 p = isl_printer_print_str(p, ")");
2038         else {
2039                 p = isl_printer_print_str(p, ")/");
2040                 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2041         }
2042
2043         return p;
2044 }
2045
2046 static __isl_give isl_printer *print_aff(__isl_take isl_printer *p,
2047         __isl_keep isl_aff *aff)
2048 {
2049         if (isl_space_is_params(aff->ls->dim))
2050                 ;
2051         else {
2052                 p = print_tuple(aff->ls->dim, p, isl_dim_set, 0, NULL, NULL);
2053                 p = isl_printer_print_str(p, " -> ");
2054         }
2055         p = isl_printer_print_str(p, "[");
2056         p = print_aff_body(p, aff);
2057         p = isl_printer_print_str(p, "]");
2058
2059         return p;
2060 }
2061
2062 static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p,
2063         __isl_keep isl_aff *aff)
2064 {
2065         if (!aff)
2066                 goto error;
2067
2068         if (isl_local_space_dim(aff->ls, isl_dim_param) > 0) {
2069                 p = print_tuple(aff->ls->dim, p, isl_dim_param, 0, NULL, NULL);
2070                 p = isl_printer_print_str(p, " -> ");
2071         }
2072         p = isl_printer_print_str(p, "{ ");
2073         p = print_aff(p, aff);
2074         p = isl_printer_print_str(p, " }");
2075         return p;
2076 error:
2077         isl_printer_free(p);
2078         return NULL;
2079 }
2080
2081 static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p,
2082         __isl_keep isl_pw_aff *pwaff)
2083 {
2084         int i;
2085
2086         if (!pwaff)
2087                 goto error;
2088
2089         if (isl_space_dim(pwaff->dim, isl_dim_param) > 0) {
2090                 p = print_tuple(pwaff->dim, p, isl_dim_param, 0, NULL, NULL);
2091                 p = isl_printer_print_str(p, " -> ");
2092         }
2093         p = isl_printer_print_str(p, "{ ");
2094         for (i = 0; i < pwaff->n; ++i) {
2095                 if (i)
2096                         p = isl_printer_print_str(p, "; ");
2097                 p = print_aff(p, pwaff->p[i].aff);
2098                 p = print_disjuncts((isl_map *)pwaff->p[i].set, p, 0);
2099         }
2100         p = isl_printer_print_str(p, " }");
2101         return p;
2102 error:
2103         isl_printer_free(p);
2104         return NULL;
2105 }
2106
2107 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2108         __isl_keep isl_local_space *ls, isl_int *c);
2109
2110 static __isl_give isl_printer *print_ls_name_c(__isl_take isl_printer *p,
2111         __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos)
2112 {
2113         if (type == isl_dim_div) {
2114                 p = isl_printer_print_str(p, "floord(");
2115                 p = print_ls_affine_c(p, ls, ls->div->row[pos] + 1);
2116                 p = isl_printer_print_str(p, ", ");
2117                 p = isl_printer_print_isl_int(p, ls->div->row[pos][0]);
2118                 p = isl_printer_print_str(p, ")");
2119         } else {
2120                 const char *name;
2121
2122                 name = isl_space_get_dim_name(ls->dim, type, pos);
2123                 if (!name)
2124                         name = "UNNAMED";
2125                 p = isl_printer_print_str(p, name);
2126         }
2127         return p;
2128 }
2129
2130 static __isl_give isl_printer *print_ls_term_c(__isl_take isl_printer *p,
2131         __isl_keep isl_local_space *ls, isl_int c, unsigned pos)
2132 {
2133         enum isl_dim_type type;
2134
2135         if (pos == 0)
2136                 return isl_printer_print_isl_int(p, c);
2137
2138         if (isl_int_is_one(c))
2139                 ;
2140         else if (isl_int_is_negone(c))
2141                 p = isl_printer_print_str(p, "-");
2142         else {
2143                 p = isl_printer_print_isl_int(p, c);
2144                 p = isl_printer_print_str(p, "*");
2145         }
2146         type = pos2type(ls->dim, &pos);
2147         p = print_ls_name_c(p, ls, type, pos);
2148         return p;
2149 }
2150
2151 static __isl_give isl_printer *print_ls_partial_affine_c(
2152         __isl_take isl_printer *p, __isl_keep isl_local_space *ls,
2153         isl_int *c, unsigned len)
2154 {
2155         int i;
2156         int first;
2157
2158         for (i = 0, first = 1; i < len; ++i) {
2159                 int flip = 0;
2160                 if (isl_int_is_zero(c[i]))
2161                         continue;
2162                 if (!first) {
2163                         if (isl_int_is_neg(c[i])) {
2164                                 flip = 1;
2165                                 isl_int_neg(c[i], c[i]);
2166                                 p = isl_printer_print_str(p, " - ");
2167                         } else 
2168                                 p = isl_printer_print_str(p, " + ");
2169                 }
2170                 first = 0;
2171                 p = print_ls_term_c(p, ls, c[i], i);
2172                 if (flip)
2173                         isl_int_neg(c[i], c[i]);
2174         }
2175         if (first)
2176                 p = isl_printer_print_str(p, "0");
2177         return p;
2178 }
2179
2180 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2181         __isl_keep isl_local_space *ls, isl_int *c)
2182 {
2183         unsigned len = 1 + isl_local_space_dim(ls, isl_dim_all);
2184         return print_ls_partial_affine_c(p, ls, c, len);
2185 }
2186
2187 static __isl_give isl_printer *print_aff_c(__isl_take isl_printer *p,
2188         __isl_keep isl_aff *aff)
2189 {
2190         unsigned total;
2191
2192         total = isl_local_space_dim(aff->ls, isl_dim_all);
2193         if (!isl_int_is_one(aff->v->el[0]))
2194                 p = isl_printer_print_str(p, "(");
2195         p = print_ls_partial_affine_c(p, aff->ls, aff->v->el + 1, 1 + total);
2196         if (!isl_int_is_one(aff->v->el[0])) {
2197                 p = isl_printer_print_str(p, ")/");
2198                 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2199         }
2200         return p;
2201 }
2202
2203 /* Print the affine expression "aff" in C format to "p".
2204  * The dimension names are taken from "space"
2205  * "set" represents the domain of the affine expression.
2206  */
2207 static __isl_give isl_printer *print_aff_on_domain_c(__isl_take isl_printer *p,
2208         __isl_keep isl_space *space, __isl_keep isl_aff *aff,
2209         __isl_keep isl_set *set)
2210 {
2211         isl_set *u;
2212         isl_ast_build *build;
2213         isl_ast_expr *expr;
2214
2215         u = isl_set_universe(isl_space_copy(space));
2216         build = isl_ast_build_from_context(u);
2217         build = isl_ast_build_restrict(build, isl_set_copy(set));
2218         expr = isl_ast_expr_from_aff(isl_aff_copy(aff), build);
2219         p = isl_printer_print_ast_expr(p, expr);
2220         isl_ast_expr_free(expr);
2221         isl_ast_build_free(build);
2222
2223         return p;
2224 }
2225
2226 /* In the C format, we cannot express that "pwaff" may be undefined
2227  * on parts of the domain space.  We therefore assume that the expression
2228  * will only be evaluated on its definition domain and compute the gist
2229  * of each cell with respect to this domain.
2230  */
2231 static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p,
2232         __isl_keep isl_pw_aff *pwaff)
2233 {
2234         int i;
2235         isl_set *domain;
2236         isl_space *space;
2237
2238         if (pwaff->n < 1)
2239                 isl_die(p->ctx, isl_error_unsupported,
2240                         "cannot print empty isl_pw_aff in C format", goto error);
2241         space = isl_pw_aff_get_domain_space(pwaff);
2242         if (!space)
2243                 goto error;
2244
2245         domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff));
2246
2247         for (i = 0; i < pwaff->n - 1; ++i) {
2248                 isl_set *set_i;
2249
2250                 p = isl_printer_print_str(p, "(");
2251
2252                 set_i = isl_set_copy(pwaff->p[i].set);
2253                 set_i = isl_set_gist(set_i, isl_set_copy(domain));
2254                 p = print_set_c(p, space, set_i);
2255                 isl_set_free(set_i);
2256
2257                 p = isl_printer_print_str(p, ") ? (");
2258                 p = print_aff_on_domain_c(p, space,
2259                                         pwaff->p[i].aff, pwaff->p[i].set);
2260                 p = isl_printer_print_str(p, ") : ");
2261         }
2262
2263         isl_set_free(domain);
2264
2265         p = print_aff_on_domain_c(p, space, pwaff->p[pwaff->n - 1].aff,
2266                                         pwaff->p[pwaff->n - 1].set);
2267         isl_space_free(space);
2268         return p;
2269 error:
2270         isl_printer_free(p);
2271         return NULL;
2272 }
2273
2274 __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p,
2275         __isl_keep isl_aff *aff)
2276 {
2277         if (!p || !aff)
2278                 goto error;
2279
2280         if (p->output_format == ISL_FORMAT_ISL)
2281                 return print_aff_isl(p, aff);
2282         else if (p->output_format == ISL_FORMAT_C)
2283                 return print_aff_c(p, aff);
2284         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2285                 goto error);
2286 error:
2287         isl_printer_free(p);
2288         return NULL;
2289 }
2290
2291 __isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p,
2292         __isl_keep isl_pw_aff *pwaff)
2293 {
2294         if (!p || !pwaff)
2295                 goto error;
2296
2297         if (p->output_format == ISL_FORMAT_ISL)
2298                 return print_pw_aff_isl(p, pwaff);
2299         else if (p->output_format == ISL_FORMAT_C)
2300                 return print_pw_aff_c(p, pwaff);
2301         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2302                 goto error);
2303 error:
2304         isl_printer_free(p);
2305         return NULL;
2306 }
2307
2308 static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p,
2309         __isl_keep isl_multi_aff *maff)
2310 {
2311         return print_space(maff->space, p, 0, 0, NULL, maff);
2312 }
2313
2314 static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p,
2315         __isl_keep isl_multi_aff *maff)
2316 {
2317         if (!maff)
2318                 goto error;
2319
2320         if (isl_space_dim(maff->space, isl_dim_param) > 0) {
2321                 p = print_tuple(maff->space, p, isl_dim_param, 0, NULL, NULL);
2322                 p = isl_printer_print_str(p, " -> ");
2323         }
2324         p = isl_printer_print_str(p, "{ ");
2325         p = print_multi_aff(p, maff);
2326         p = isl_printer_print_str(p, " }");
2327         return p;
2328 error:
2329         isl_printer_free(p);
2330         return NULL;
2331 }
2332
2333 __isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p,
2334         __isl_keep isl_multi_aff *maff)
2335 {
2336         if (!p || !maff)
2337                 goto error;
2338
2339         if (p->output_format == ISL_FORMAT_ISL)
2340                 return print_multi_aff_isl(p, maff);
2341         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2342                 goto error);
2343 error:
2344         isl_printer_free(p);
2345         return NULL;
2346 }
2347
2348 static __isl_give isl_printer *print_pw_multi_aff_body(
2349         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2350 {
2351         int i;
2352
2353         if (!pma)
2354                 goto error;
2355
2356         for (i = 0; i < pma->n; ++i) {
2357                 if (i)
2358                         p = isl_printer_print_str(p, "; ");
2359                 p = print_multi_aff(p, pma->p[i].maff);
2360                 p = print_disjuncts((isl_map *)pma->p[i].set, p, 0);
2361         }
2362         return p;
2363 error:
2364         isl_printer_free(p);
2365         return NULL;
2366 }
2367
2368 static __isl_give isl_printer *print_pw_multi_aff_isl(__isl_take isl_printer *p,
2369         __isl_keep isl_pw_multi_aff *pma)
2370 {
2371         if (!pma)
2372                 goto error;
2373
2374         if (isl_space_dim(pma->dim, isl_dim_param) > 0) {
2375                 p = print_tuple(pma->dim, p, isl_dim_param, 0, NULL, NULL);
2376                 p = isl_printer_print_str(p, " -> ");
2377         }
2378         p = isl_printer_print_str(p, "{ ");
2379         p = print_pw_multi_aff_body(p, pma);
2380         p = isl_printer_print_str(p, " }");
2381         return p;
2382 error:
2383         isl_printer_free(p);
2384         return NULL;
2385 }
2386
2387 static __isl_give isl_printer *print_unnamed_pw_multi_aff_c(
2388         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2389 {
2390         int i;
2391
2392         for (i = 0; i < pma->n - 1; ++i) {
2393                 p = isl_printer_print_str(p, "(");
2394                 p = print_set_c(p, pma->dim, pma->p[i].set);
2395                 p = isl_printer_print_str(p, ") ? (");
2396                 p = print_aff_c(p, pma->p[i].maff->p[0]);
2397                 p = isl_printer_print_str(p, ") : ");
2398         }
2399
2400         return print_aff_c(p, pma->p[pma->n - 1].maff->p[0]);
2401 }
2402
2403 static __isl_give isl_printer *print_pw_multi_aff_c(__isl_take isl_printer *p,
2404         __isl_keep isl_pw_multi_aff *pma)
2405 {
2406         int n;
2407         const char *name;
2408
2409         if (!pma)
2410                 goto error;
2411         if (pma->n < 1)
2412                 isl_die(p->ctx, isl_error_unsupported,
2413                         "cannot print empty isl_pw_multi_aff in C format",
2414                         goto error);
2415         name = isl_pw_multi_aff_get_tuple_name(pma, isl_dim_out);
2416         if (!name && isl_pw_multi_aff_dim(pma, isl_dim_out) == 1)
2417                 return print_unnamed_pw_multi_aff_c(p, pma);
2418         if (!name)
2419                 isl_die(p->ctx, isl_error_unsupported,
2420                         "cannot print unnamed isl_pw_multi_aff in C format",
2421                         goto error);
2422
2423         p = isl_printer_print_str(p, name);
2424         n = isl_pw_multi_aff_dim(pma, isl_dim_out);
2425         if (n != 0)
2426                 isl_die(p->ctx, isl_error_unsupported,
2427                         "not supported yet", goto error);
2428
2429         return p;
2430 error:
2431         isl_printer_free(p);
2432         return NULL;
2433 }
2434
2435 __isl_give isl_printer *isl_printer_print_pw_multi_aff(
2436         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2437 {
2438         if (!p || !pma)
2439                 goto error;
2440
2441         if (p->output_format == ISL_FORMAT_ISL)
2442                 return print_pw_multi_aff_isl(p, pma);
2443         if (p->output_format == ISL_FORMAT_C)
2444                 return print_pw_multi_aff_c(p, pma);
2445         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2446                 goto error);
2447 error:
2448         isl_printer_free(p);
2449         return NULL;
2450 }
2451
2452 static int print_pw_multi_aff_body_wrap(__isl_take isl_pw_multi_aff *pma,
2453         void *user)
2454 {
2455         struct isl_union_print_data *data;
2456         data = (struct isl_union_print_data *) user;
2457
2458         if (!data->first)
2459                 data->p = isl_printer_print_str(data->p, "; ");
2460         data->first = 0;
2461
2462         data->p = print_pw_multi_aff_body(data->p, pma);
2463         isl_pw_multi_aff_free(pma);
2464
2465         return 0;
2466 }
2467
2468 static __isl_give isl_printer *print_union_pw_multi_aff_isl(
2469         __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
2470 {
2471         struct isl_union_print_data data = { p, 1 };
2472         isl_space *space;
2473
2474         space = isl_union_pw_multi_aff_get_space(upma);
2475         if (isl_space_dim(space, isl_dim_param) > 0) {
2476                 p = print_tuple(space, p, isl_dim_param, 0, NULL, NULL);
2477                 p = isl_printer_print_str(p, s_to[0]);
2478         }
2479         isl_space_free(space);
2480         p = isl_printer_print_str(p, s_open_set[0]);
2481         isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
2482                                         &print_pw_multi_aff_body_wrap, &data);
2483         p = data.p;
2484         p = isl_printer_print_str(p, s_close_set[0]);
2485         return p;
2486 }
2487
2488 __isl_give isl_printer *isl_printer_print_union_pw_multi_aff(
2489         __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
2490 {
2491         if (!p || !upma)
2492                 goto error;
2493
2494         if (p->output_format == ISL_FORMAT_ISL)
2495                 return print_union_pw_multi_aff_isl(p, upma);
2496         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2497                 goto error);
2498 error:
2499         isl_printer_free(p);
2500         return NULL;
2501 }
2502
2503 static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p,
2504         __isl_keep isl_multi_pw_aff *mpa)
2505 {
2506         int i;
2507
2508         if (!mpa)
2509                 return isl_printer_free(p);
2510
2511         p = isl_printer_print_str(p, "(");
2512         for (i = 0; i < mpa->n; ++i) {
2513                 if (i)
2514                         p = isl_printer_print_str(p, ",");
2515                 p = isl_printer_print_pw_aff(p, mpa->p[i]);
2516         }
2517         p = isl_printer_print_str(p, ")");
2518         return p;
2519 }
2520
2521 __isl_give isl_printer *isl_printer_print_multi_pw_aff(
2522         __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa)
2523 {
2524         if (!p || !mpa)
2525                 return isl_printer_free(p);
2526
2527         if (p->output_format == ISL_FORMAT_ISL)
2528                 return print_multi_pw_aff_isl(p, mpa);
2529         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2530                 return isl_printer_free(p));
2531 }