Makefile.am: add isl_val_private.h to libisl.la sources
[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         else
1365                 p = isl_printer_free(p);
1366         if (!isl_int_is_one(den)) {
1367                 p = isl_printer_print_str(p, ")/");
1368                 p = isl_printer_print_isl_int(p, den);
1369                 isl_qpolynomial_free(qp);
1370         }
1371         isl_int_clear(den);
1372         return p;
1373 }
1374
1375 __isl_give isl_printer *isl_printer_print_qpolynomial(
1376         __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp)
1377 {
1378         if (!p || !qp)
1379                 goto error;
1380
1381         if (p->output_format == ISL_FORMAT_ISL)
1382                 return print_qpolynomial_isl(p, qp);
1383         else if (p->output_format == ISL_FORMAT_C)
1384                 return print_qpolynomial_c(p, qp->dim, qp);
1385         else
1386                 isl_die(qp->dim->ctx, isl_error_unsupported,
1387                         "output format not supported for isl_qpolynomials",
1388                         goto error);
1389 error:
1390         isl_printer_free(p);
1391         return NULL;
1392 }
1393
1394 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
1395         unsigned output_format)
1396 {
1397         isl_printer *p;
1398
1399         if  (!qp)
1400                 return;
1401
1402         isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1403         p = isl_printer_to_file(qp->dim->ctx, out);
1404         p = isl_printer_print_qpolynomial(p, qp);
1405         isl_printer_free(p);
1406 }
1407
1408 static __isl_give isl_printer *qpolynomial_fold_print(
1409         __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
1410 {
1411         int i;
1412
1413         if (fold->type == isl_fold_min)
1414                 p = isl_printer_print_str(p, "min");
1415         else if (fold->type == isl_fold_max)
1416                 p = isl_printer_print_str(p, "max");
1417         p = isl_printer_print_str(p, "(");
1418         for (i = 0; i < fold->n; ++i) {
1419                 if (i)
1420                         p = isl_printer_print_str(p, ", ");
1421                 p = print_qpolynomial(p, fold->qp[i]);
1422         }
1423         p = isl_printer_print_str(p, ")");
1424         return p;
1425 }
1426
1427 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
1428         FILE *out, unsigned output_format)
1429 {
1430         isl_printer *p;
1431
1432         if (!fold)
1433                 return;
1434
1435         isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1436
1437         p = isl_printer_to_file(fold->dim->ctx, out);
1438         p = isl_printer_print_qpolynomial_fold(p, fold);
1439
1440         isl_printer_free(p);
1441 }
1442
1443 static __isl_give isl_printer *isl_pwqp_print_isl_body(
1444         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1445 {
1446         int i = 0;
1447
1448         for (i = 0; i < pwqp->n; ++i) {
1449                 if (i)
1450                         p = isl_printer_print_str(p, "; ");
1451                 if (!isl_space_is_params(pwqp->p[i].set->dim)) {
1452                         p = print_space(pwqp->p[i].set->dim, p, 0, 0, NULL, NULL);
1453                         p = isl_printer_print_str(p, " -> ");
1454                 }
1455                 p = print_qpolynomial(p, pwqp->p[i].qp);
1456                 p = print_disjuncts((isl_map *)pwqp->p[i].set, p, 0);
1457         }
1458
1459         return p;
1460 }
1461
1462 static __isl_give isl_printer *print_pw_qpolynomial_isl(
1463         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1464 {
1465         if (!p || !pwqp)
1466                 goto error;
1467
1468         if (isl_space_dim(pwqp->dim, isl_dim_param) > 0) {
1469                 p = print_tuple(pwqp->dim, p, isl_dim_param, 0, NULL, NULL);
1470                 p = isl_printer_print_str(p, " -> ");
1471         }
1472         p = isl_printer_print_str(p, "{ ");
1473         if (pwqp->n == 0) {
1474                 if (!isl_space_is_set(pwqp->dim)) {
1475                         p = print_tuple(pwqp->dim, p, isl_dim_in, 0, NULL, NULL);
1476                         p = isl_printer_print_str(p, " -> ");
1477                 }
1478                 p = isl_printer_print_str(p, "0");
1479         }
1480         p = isl_pwqp_print_isl_body(p, pwqp);
1481         p = isl_printer_print_str(p, " }");
1482         return p;
1483 error:
1484         isl_printer_free(p);
1485         return NULL;
1486 }
1487
1488 void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
1489         unsigned output_format)
1490 {
1491         isl_printer *p;
1492
1493         if (!pwqp)
1494                 return;
1495
1496         p = isl_printer_to_file(pwqp->dim->ctx, out);
1497         p = isl_printer_set_output_format(p, output_format);
1498         p = isl_printer_print_pw_qpolynomial(p, pwqp);
1499
1500         isl_printer_free(p);
1501 }
1502
1503 static __isl_give isl_printer *isl_pwf_print_isl_body(
1504         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1505 {
1506         int i = 0;
1507
1508         for (i = 0; i < pwf->n; ++i) {
1509                 if (i)
1510                         p = isl_printer_print_str(p, "; ");
1511                 if (!isl_space_is_params(pwf->p[i].set->dim)) {
1512                         p = print_space(pwf->p[i].set->dim, p, 0, 0, NULL, NULL);
1513                         p = isl_printer_print_str(p, " -> ");
1514                 }
1515                 p = qpolynomial_fold_print(pwf->p[i].fold, p);
1516                 p = print_disjuncts((isl_map *)pwf->p[i].set, p, 0);
1517         }
1518
1519         return p;
1520 }
1521
1522 static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(
1523         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1524 {
1525         if (isl_space_dim(pwf->dim, isl_dim_param) > 0) {
1526                 p = print_tuple(pwf->dim, p, isl_dim_param, 0, NULL, NULL);
1527                 p = isl_printer_print_str(p, " -> ");
1528         }
1529         p = isl_printer_print_str(p, "{ ");
1530         if (pwf->n == 0) {
1531                 if (!isl_space_is_set(pwf->dim)) {
1532                         p = print_tuple(pwf->dim, p, isl_dim_in, 0, NULL, NULL);
1533                         p = isl_printer_print_str(p, " -> ");
1534                 }
1535                 p = isl_printer_print_str(p, "0");
1536         }
1537         p = isl_pwf_print_isl_body(p, pwf);
1538         p = isl_printer_print_str(p, " }");
1539         return p;
1540 }
1541
1542 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1543         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c);
1544
1545 static __isl_give isl_printer *print_name_c(__isl_take isl_printer *p,
1546         __isl_keep isl_space *dim,
1547         __isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos)
1548 {
1549         if (type == isl_dim_div) {
1550                 p = isl_printer_print_str(p, "floord(");
1551                 p = print_affine_c(p, dim, bset, bset->div[pos] + 1);
1552                 p = isl_printer_print_str(p, ", ");
1553                 p = isl_printer_print_isl_int(p, bset->div[pos][0]);
1554                 p = isl_printer_print_str(p, ")");
1555         } else {
1556                 const char *name;
1557
1558                 name = isl_space_get_dim_name(dim, type, pos);
1559                 if (!name)
1560                         name = "UNNAMED";
1561                 p = isl_printer_print_str(p, name);
1562         }
1563         return p;
1564 }
1565
1566 static __isl_give isl_printer *print_term_c(__isl_take isl_printer *p,
1567         __isl_keep isl_space *dim,
1568         __isl_keep isl_basic_set *bset, isl_int c, unsigned pos)
1569 {
1570         enum isl_dim_type type;
1571
1572         if (pos == 0)
1573                 return isl_printer_print_isl_int(p, c);
1574
1575         if (isl_int_is_one(c))
1576                 ;
1577         else if (isl_int_is_negone(c))
1578                 p = isl_printer_print_str(p, "-");
1579         else {
1580                 p = isl_printer_print_isl_int(p, c);
1581                 p = isl_printer_print_str(p, "*");
1582         }
1583         type = pos2type(dim, &pos);
1584         p = print_name_c(p, dim, bset, type, pos);
1585         return p;
1586 }
1587
1588 static __isl_give isl_printer *print_partial_affine_c(__isl_take isl_printer *p,
1589         __isl_keep isl_space *dim,
1590         __isl_keep isl_basic_set *bset, isl_int *c, unsigned len)
1591 {
1592         int i;
1593         int first;
1594
1595         for (i = 0, first = 1; i < len; ++i) {
1596                 int flip = 0;
1597                 if (isl_int_is_zero(c[i]))
1598                         continue;
1599                 if (!first) {
1600                         if (isl_int_is_neg(c[i])) {
1601                                 flip = 1;
1602                                 isl_int_neg(c[i], c[i]);
1603                                 p = isl_printer_print_str(p, " - ");
1604                         } else 
1605                                 p = isl_printer_print_str(p, " + ");
1606                 }
1607                 first = 0;
1608                 p = print_term_c(p, dim, bset, c[i], i);
1609                 if (flip)
1610                         isl_int_neg(c[i], c[i]);
1611         }
1612         if (first)
1613                 p = isl_printer_print_str(p, "0");
1614         return p;
1615 }
1616
1617 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1618         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c)
1619 {
1620         unsigned len = 1 + isl_basic_set_total_dim(bset);
1621         return print_partial_affine_c(p, dim, bset, c, len);
1622 }
1623
1624 /* We skip the constraint if it is implied by the div expression.
1625  */
1626 static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,
1627         __isl_keep isl_space *dim,
1628         __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int first)
1629 {
1630         unsigned o_div;
1631         unsigned n_div;
1632         int div;
1633
1634         o_div = isl_basic_set_offset(bset, isl_dim_div);
1635         n_div = isl_basic_set_dim(bset, isl_dim_div);
1636         div = isl_seq_last_non_zero(c + o_div, n_div);
1637         if (div >= 0 && isl_basic_set_is_div_constraint(bset, c, div))
1638                 return p;
1639
1640         if (!first)
1641                 p = isl_printer_print_str(p, " && ");
1642
1643         p = print_affine_c(p, dim, bset, c);
1644         p = isl_printer_print_str(p, " ");
1645         p = isl_printer_print_str(p, op);
1646         p = isl_printer_print_str(p, " 0");
1647         return p;
1648 }
1649
1650 static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,
1651         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset)
1652 {
1653         int i, j;
1654         unsigned n_div = isl_basic_set_dim(bset, isl_dim_div);
1655         unsigned total = isl_basic_set_total_dim(bset) - n_div;
1656
1657         for (i = 0; i < bset->n_eq; ++i) {
1658                 j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div);
1659                 if (j < 0)
1660                         p = print_constraint_c(p, dim, bset,
1661                                                 bset->eq[i], "==", !i);
1662                 else {
1663                         if (i)
1664                                 p = isl_printer_print_str(p, " && ");
1665                         p = isl_printer_print_str(p, "(");
1666                         p = print_partial_affine_c(p, dim, bset, bset->eq[i],
1667                                                    1 + total + j);
1668                         p = isl_printer_print_str(p, ") % ");
1669                         p = isl_printer_print_isl_int(p,
1670                                                 bset->eq[i][1 + total + j]);
1671                         p = isl_printer_print_str(p, " == 0");
1672                 }
1673         }
1674         for (i = 0; i < bset->n_ineq; ++i)
1675                 p = print_constraint_c(p, dim, bset, bset->ineq[i], ">=",
1676                                         !bset->n_eq && !i);
1677         return p;
1678 }
1679
1680 static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,
1681         __isl_keep isl_space *dim, __isl_keep isl_set *set)
1682 {
1683         int i;
1684
1685         if (!set)
1686                 return isl_printer_free(p);
1687
1688         if (set->n == 0)
1689                 p = isl_printer_print_str(p, "0");
1690
1691         for (i = 0; i < set->n; ++i) {
1692                 if (i)
1693                         p = isl_printer_print_str(p, " || ");
1694                 if (set->n > 1)
1695                         p = isl_printer_print_str(p, "(");
1696                 p = print_basic_set_c(p, dim, set->p[i]);
1697                 if (set->n > 1)
1698                         p = isl_printer_print_str(p, ")");
1699         }
1700         return p;
1701 }
1702
1703 static __isl_give isl_printer *print_pw_qpolynomial_c(
1704         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1705 {
1706         int i;
1707
1708         if (pwqp->n == 1 && isl_set_plain_is_universe(pwqp->p[0].set))
1709                 return print_qpolynomial_c(p, pwqp->dim, pwqp->p[0].qp);
1710
1711         for (i = 0; i < pwqp->n; ++i) {
1712                 p = isl_printer_print_str(p, "(");
1713                 p = print_set_c(p, pwqp->dim, pwqp->p[i].set);
1714                 p = isl_printer_print_str(p, ") ? (");
1715                 p = print_qpolynomial_c(p, pwqp->dim, pwqp->p[i].qp);
1716                 p = isl_printer_print_str(p, ") : ");
1717         }
1718
1719         p = isl_printer_print_str(p, "0");
1720         return p;
1721 }
1722
1723 __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
1724         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1725 {
1726         if (!p || !pwqp)
1727                 goto error;
1728
1729         if (p->output_format == ISL_FORMAT_ISL)
1730                 return print_pw_qpolynomial_isl(p, pwqp);
1731         else if (p->output_format == ISL_FORMAT_C)
1732                 return print_pw_qpolynomial_c(p, pwqp);
1733         isl_assert(p->ctx, 0, goto error);
1734 error:
1735         isl_printer_free(p);
1736         return NULL;
1737 }
1738
1739 static int print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user)
1740 {
1741         struct isl_union_print_data *data;
1742         data = (struct isl_union_print_data *)user;
1743
1744         if (!data->first)
1745                 data->p = isl_printer_print_str(data->p, "; ");
1746         data->first = 0;
1747
1748         data->p = isl_pwqp_print_isl_body(data->p, pwqp);
1749         isl_pw_qpolynomial_free(pwqp);
1750
1751         return 0;
1752 }
1753
1754 static __isl_give isl_printer *print_union_pw_qpolynomial_isl(
1755         __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
1756 {
1757         struct isl_union_print_data data = { p, 1 };
1758         isl_space *dim;
1759         dim = isl_union_pw_qpolynomial_get_space(upwqp);
1760         if (isl_space_dim(dim, isl_dim_param) > 0) {
1761                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1762                 p = isl_printer_print_str(p, " -> ");
1763         }
1764         isl_space_free(dim);
1765         p = isl_printer_print_str(p, "{ ");
1766         isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body,
1767                                                         &data);
1768         p = data.p;
1769         p = isl_printer_print_str(p, " }");
1770         return p;
1771 }
1772
1773 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial(
1774         __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
1775 {
1776         if (!p || !upwqp)
1777                 goto error;
1778
1779         if (p->output_format == ISL_FORMAT_ISL)
1780                 return print_union_pw_qpolynomial_isl(p, upwqp);
1781         isl_die(p->ctx, isl_error_invalid,
1782                 "invalid output format for isl_union_pw_qpolynomial",
1783                 goto error);
1784 error:
1785         isl_printer_free(p);
1786         return NULL;
1787 }
1788
1789 static __isl_give isl_printer *print_qpolynomial_fold_c(
1790         __isl_take isl_printer *p, __isl_keep isl_space *dim,
1791         __isl_keep isl_qpolynomial_fold *fold)
1792 {
1793         int i;
1794
1795         for (i = 0; i < fold->n - 1; ++i)
1796                 if (fold->type == isl_fold_min)
1797                         p = isl_printer_print_str(p, "min(");
1798                 else if (fold->type == isl_fold_max)
1799                         p = isl_printer_print_str(p, "max(");
1800
1801         for (i = 0; i < fold->n; ++i) {
1802                 if (i)
1803                         p = isl_printer_print_str(p, ", ");
1804                 p = print_qpolynomial_c(p, dim, fold->qp[i]);
1805                 if (i)
1806                         p = isl_printer_print_str(p, ")");
1807         }
1808         return p;
1809 }
1810
1811 __isl_give isl_printer *isl_printer_print_qpolynomial_fold(
1812         __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
1813 {
1814         if  (!p || !fold)
1815                 goto error;
1816         if (p->output_format == ISL_FORMAT_ISL)
1817                 return qpolynomial_fold_print(fold, p);
1818         else if (p->output_format == ISL_FORMAT_C)
1819                 return print_qpolynomial_fold_c(p, fold->dim, fold);
1820         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
1821                 goto error);
1822 error:
1823         isl_printer_free(p);
1824         return NULL;
1825 }
1826
1827 static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
1828         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1829 {
1830         int i;
1831
1832         if (pwf->n == 1 && isl_set_plain_is_universe(pwf->p[0].set))
1833                 return print_qpolynomial_fold_c(p, pwf->dim, pwf->p[0].fold);
1834
1835         for (i = 0; i < pwf->n; ++i) {
1836                 p = isl_printer_print_str(p, "(");
1837                 p = print_set_c(p, pwf->dim, pwf->p[i].set);
1838                 p = isl_printer_print_str(p, ") ? (");
1839                 p = print_qpolynomial_fold_c(p, pwf->dim, pwf->p[i].fold);
1840                 p = isl_printer_print_str(p, ") : ");
1841         }
1842
1843         p = isl_printer_print_str(p, "0");
1844         return p;
1845 }
1846
1847 __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
1848         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1849 {
1850         if (!p || !pwf)
1851                 goto error;
1852
1853         if (p->output_format == ISL_FORMAT_ISL)
1854                 return print_pw_qpolynomial_fold_isl(p, pwf);
1855         else if (p->output_format == ISL_FORMAT_C)
1856                 return print_pw_qpolynomial_fold_c(p, pwf);
1857         isl_assert(p->ctx, 0, goto error);
1858 error:
1859         isl_printer_free(p);
1860         return NULL;
1861 }
1862
1863 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
1864         FILE *out, unsigned output_format)
1865 {
1866         isl_printer *p;
1867
1868         if (!pwf)
1869                 return;
1870
1871         p = isl_printer_to_file(pwf->dim->ctx, out);
1872         p = isl_printer_set_output_format(p, output_format);
1873         p = isl_printer_print_pw_qpolynomial_fold(p, pwf);
1874
1875         isl_printer_free(p);
1876 }
1877
1878 static int print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf, void *user)
1879 {
1880         struct isl_union_print_data *data;
1881         data = (struct isl_union_print_data *)user;
1882
1883         if (!data->first)
1884                 data->p = isl_printer_print_str(data->p, "; ");
1885         data->first = 0;
1886
1887         data->p = isl_pwf_print_isl_body(data->p, pwf);
1888         isl_pw_qpolynomial_fold_free(pwf);
1889
1890         return 0;
1891 }
1892
1893 static __isl_give isl_printer *print_union_pw_qpolynomial_fold_isl(
1894         __isl_take isl_printer *p,
1895         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
1896 {
1897         struct isl_union_print_data data = { p, 1 };
1898         isl_space *dim;
1899         dim = isl_union_pw_qpolynomial_fold_get_space(upwf);
1900         if (isl_space_dim(dim, isl_dim_param) > 0) {
1901                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1902                 p = isl_printer_print_str(p, " -> ");
1903         }
1904         isl_space_free(dim);
1905         p = isl_printer_print_str(p, "{ ");
1906         isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf,
1907                                                         &print_pwf_body, &data);
1908         p = data.p;
1909         p = isl_printer_print_str(p, " }");
1910         return p;
1911 }
1912
1913 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold(
1914         __isl_take isl_printer *p,
1915         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
1916 {
1917         if (!p || !upwf)
1918                 goto error;
1919
1920         if (p->output_format == ISL_FORMAT_ISL)
1921                 return print_union_pw_qpolynomial_fold_isl(p, upwf);
1922         isl_die(p->ctx, isl_error_invalid,
1923                 "invalid output format for isl_union_pw_qpolynomial_fold",
1924                 goto error);
1925 error:
1926         isl_printer_free(p);
1927         return NULL;
1928 }
1929
1930 __isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p,
1931         __isl_keep isl_constraint *c)
1932 {
1933         isl_basic_map *bmap;
1934
1935         if (!p || !c)
1936                 goto error;
1937
1938         bmap = isl_basic_map_from_constraint(isl_constraint_copy(c));
1939         p = isl_printer_print_basic_map(p, bmap);
1940         isl_basic_map_free(bmap);
1941         return p;
1942 error:
1943         isl_printer_free(p);
1944         return NULL;
1945 }
1946
1947 static __isl_give isl_printer *isl_printer_print_space_isl(
1948         __isl_take isl_printer *p, __isl_keep isl_space *dim)
1949 {
1950         if (!dim)
1951                 goto error;
1952
1953         if (isl_space_dim(dim, isl_dim_param) > 0) {
1954                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1955                 p = isl_printer_print_str(p, " -> ");
1956         }
1957
1958         p = isl_printer_print_str(p, "{ ");
1959         if (isl_space_is_params(dim))
1960                 p = isl_printer_print_str(p, s_such_that[0]);
1961         else
1962                 p = print_space(dim, p, 0, 0, NULL, NULL);
1963         p = isl_printer_print_str(p, " }");
1964
1965         return p;
1966 error:
1967         isl_printer_free(p);
1968         return NULL;
1969 }
1970
1971 __isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p,
1972         __isl_keep isl_space *space)
1973 {
1974         if (!p || !space)
1975                 return isl_printer_free(p);
1976         if (p->output_format == ISL_FORMAT_ISL)
1977                 return isl_printer_print_space_isl(p, space);
1978         else if (p->output_format == ISL_FORMAT_OMEGA)
1979                 return print_omega_parameters(space, p);
1980
1981         isl_die(isl_space_get_ctx(space), isl_error_unsupported,
1982                 "output format not supported for space",
1983                 return isl_printer_free(p));
1984 }
1985
1986 __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p,
1987         __isl_keep isl_local_space *ls)
1988 {
1989         unsigned total;
1990         unsigned n_div;
1991
1992         if (!ls)
1993                 goto error;
1994
1995         total = isl_local_space_dim(ls, isl_dim_all);
1996         if (isl_local_space_dim(ls, isl_dim_param) > 0) {
1997                 p = print_tuple(ls->dim, p, isl_dim_param, 0, NULL, NULL);
1998                 p = isl_printer_print_str(p, " -> ");
1999         }
2000         p = isl_printer_print_str(p, "{ ");
2001         p = print_space(ls->dim, p, 0, 0, NULL, NULL);
2002         n_div = isl_local_space_dim(ls, isl_dim_div);
2003         if (n_div > 0) {
2004                 int i;
2005                 p = isl_printer_print_str(p, " : ");
2006                 p = isl_printer_print_str(p, s_open_exists[0]);
2007                 for (i = 0; i < n_div; ++i) {
2008                         if (i)
2009                                 p = isl_printer_print_str(p, ", ");
2010                         p = print_name(ls->dim, p, isl_dim_div, i, 0);
2011                         if (isl_int_is_zero(ls->div->row[i][0]))
2012                                 continue;
2013                         p = isl_printer_print_str(p, " = [(");
2014                         p = print_affine_of_len(ls->dim, ls->div, p,
2015                                             ls->div->row[i] + 1, 1 + total);
2016                         p = isl_printer_print_str(p, ")/");
2017                         p = isl_printer_print_isl_int(p, ls->div->row[i][0]);
2018                         p = isl_printer_print_str(p, "]");
2019                 }
2020         } else if (isl_space_is_params(ls->dim))
2021                 p = isl_printer_print_str(p, s_such_that[0]);
2022         p = isl_printer_print_str(p, " }");
2023         return p;
2024 error:
2025         isl_printer_free(p);
2026         return NULL;
2027 }
2028
2029 static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p,
2030         __isl_keep isl_aff *aff)
2031 {
2032         unsigned total;
2033
2034         total = isl_local_space_dim(aff->ls, isl_dim_all);
2035         p = isl_printer_print_str(p, "(");
2036         p = print_affine_of_len(aff->ls->dim, aff->ls->div, p,
2037                                 aff->v->el + 1, 1 + total);
2038         if (isl_int_is_one(aff->v->el[0]))
2039                 p = isl_printer_print_str(p, ")");
2040         else {
2041                 p = isl_printer_print_str(p, ")/");
2042                 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2043         }
2044
2045         return p;
2046 }
2047
2048 static __isl_give isl_printer *print_aff(__isl_take isl_printer *p,
2049         __isl_keep isl_aff *aff)
2050 {
2051         if (isl_space_is_params(aff->ls->dim))
2052                 ;
2053         else {
2054                 p = print_tuple(aff->ls->dim, p, isl_dim_set, 0, NULL, NULL);
2055                 p = isl_printer_print_str(p, " -> ");
2056         }
2057         p = isl_printer_print_str(p, "[");
2058         p = print_aff_body(p, aff);
2059         p = isl_printer_print_str(p, "]");
2060
2061         return p;
2062 }
2063
2064 static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p,
2065         __isl_keep isl_aff *aff)
2066 {
2067         if (!aff)
2068                 goto error;
2069
2070         if (isl_local_space_dim(aff->ls, isl_dim_param) > 0) {
2071                 p = print_tuple(aff->ls->dim, p, isl_dim_param, 0, NULL, NULL);
2072                 p = isl_printer_print_str(p, " -> ");
2073         }
2074         p = isl_printer_print_str(p, "{ ");
2075         p = print_aff(p, aff);
2076         p = isl_printer_print_str(p, " }");
2077         return p;
2078 error:
2079         isl_printer_free(p);
2080         return NULL;
2081 }
2082
2083 static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p,
2084         __isl_keep isl_pw_aff *pwaff)
2085 {
2086         int i;
2087
2088         if (!pwaff)
2089                 goto error;
2090
2091         if (isl_space_dim(pwaff->dim, isl_dim_param) > 0) {
2092                 p = print_tuple(pwaff->dim, p, isl_dim_param, 0, NULL, NULL);
2093                 p = isl_printer_print_str(p, " -> ");
2094         }
2095         p = isl_printer_print_str(p, "{ ");
2096         for (i = 0; i < pwaff->n; ++i) {
2097                 if (i)
2098                         p = isl_printer_print_str(p, "; ");
2099                 p = print_aff(p, pwaff->p[i].aff);
2100                 p = print_disjuncts((isl_map *)pwaff->p[i].set, p, 0);
2101         }
2102         p = isl_printer_print_str(p, " }");
2103         return p;
2104 error:
2105         isl_printer_free(p);
2106         return NULL;
2107 }
2108
2109 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2110         __isl_keep isl_local_space *ls, isl_int *c);
2111
2112 static __isl_give isl_printer *print_ls_name_c(__isl_take isl_printer *p,
2113         __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos)
2114 {
2115         if (type == isl_dim_div) {
2116                 p = isl_printer_print_str(p, "floord(");
2117                 p = print_ls_affine_c(p, ls, ls->div->row[pos] + 1);
2118                 p = isl_printer_print_str(p, ", ");
2119                 p = isl_printer_print_isl_int(p, ls->div->row[pos][0]);
2120                 p = isl_printer_print_str(p, ")");
2121         } else {
2122                 const char *name;
2123
2124                 name = isl_space_get_dim_name(ls->dim, type, pos);
2125                 if (!name)
2126                         name = "UNNAMED";
2127                 p = isl_printer_print_str(p, name);
2128         }
2129         return p;
2130 }
2131
2132 static __isl_give isl_printer *print_ls_term_c(__isl_take isl_printer *p,
2133         __isl_keep isl_local_space *ls, isl_int c, unsigned pos)
2134 {
2135         enum isl_dim_type type;
2136
2137         if (pos == 0)
2138                 return isl_printer_print_isl_int(p, c);
2139
2140         if (isl_int_is_one(c))
2141                 ;
2142         else if (isl_int_is_negone(c))
2143                 p = isl_printer_print_str(p, "-");
2144         else {
2145                 p = isl_printer_print_isl_int(p, c);
2146                 p = isl_printer_print_str(p, "*");
2147         }
2148         type = pos2type(ls->dim, &pos);
2149         p = print_ls_name_c(p, ls, type, pos);
2150         return p;
2151 }
2152
2153 static __isl_give isl_printer *print_ls_partial_affine_c(
2154         __isl_take isl_printer *p, __isl_keep isl_local_space *ls,
2155         isl_int *c, unsigned len)
2156 {
2157         int i;
2158         int first;
2159
2160         for (i = 0, first = 1; i < len; ++i) {
2161                 int flip = 0;
2162                 if (isl_int_is_zero(c[i]))
2163                         continue;
2164                 if (!first) {
2165                         if (isl_int_is_neg(c[i])) {
2166                                 flip = 1;
2167                                 isl_int_neg(c[i], c[i]);
2168                                 p = isl_printer_print_str(p, " - ");
2169                         } else 
2170                                 p = isl_printer_print_str(p, " + ");
2171                 }
2172                 first = 0;
2173                 p = print_ls_term_c(p, ls, c[i], i);
2174                 if (flip)
2175                         isl_int_neg(c[i], c[i]);
2176         }
2177         if (first)
2178                 p = isl_printer_print_str(p, "0");
2179         return p;
2180 }
2181
2182 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2183         __isl_keep isl_local_space *ls, isl_int *c)
2184 {
2185         unsigned len = 1 + isl_local_space_dim(ls, isl_dim_all);
2186         return print_ls_partial_affine_c(p, ls, c, len);
2187 }
2188
2189 static __isl_give isl_printer *print_aff_c(__isl_take isl_printer *p,
2190         __isl_keep isl_aff *aff)
2191 {
2192         unsigned total;
2193
2194         total = isl_local_space_dim(aff->ls, isl_dim_all);
2195         if (!isl_int_is_one(aff->v->el[0]))
2196                 p = isl_printer_print_str(p, "(");
2197         p = print_ls_partial_affine_c(p, aff->ls, aff->v->el + 1, 1 + total);
2198         if (!isl_int_is_one(aff->v->el[0])) {
2199                 p = isl_printer_print_str(p, ")/");
2200                 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2201         }
2202         return p;
2203 }
2204
2205 /* Print the affine expression "aff" in C format to "p".
2206  * The dimension names are taken from "space"
2207  * "set" represents the domain of the affine expression.
2208  */
2209 static __isl_give isl_printer *print_aff_on_domain_c(__isl_take isl_printer *p,
2210         __isl_keep isl_space *space, __isl_keep isl_aff *aff,
2211         __isl_keep isl_set *set)
2212 {
2213         isl_set *u;
2214         isl_ast_build *build;
2215         isl_ast_expr *expr;
2216
2217         u = isl_set_universe(isl_space_copy(space));
2218         build = isl_ast_build_from_context(u);
2219         build = isl_ast_build_restrict(build, isl_set_copy(set));
2220         expr = isl_ast_expr_from_aff(isl_aff_copy(aff), build);
2221         p = isl_printer_print_ast_expr(p, expr);
2222         isl_ast_expr_free(expr);
2223         isl_ast_build_free(build);
2224
2225         return p;
2226 }
2227
2228 /* In the C format, we cannot express that "pwaff" may be undefined
2229  * on parts of the domain space.  We therefore assume that the expression
2230  * will only be evaluated on its definition domain and compute the gist
2231  * of each cell with respect to this domain.
2232  */
2233 static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p,
2234         __isl_keep isl_pw_aff *pwaff)
2235 {
2236         int i;
2237         isl_set *domain;
2238         isl_space *space;
2239
2240         if (pwaff->n < 1)
2241                 isl_die(p->ctx, isl_error_unsupported,
2242                         "cannot print empty isl_pw_aff in C format", goto error);
2243         space = isl_pw_aff_get_domain_space(pwaff);
2244         if (!space)
2245                 goto error;
2246
2247         domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff));
2248
2249         for (i = 0; i < pwaff->n - 1; ++i) {
2250                 isl_set *set_i;
2251
2252                 p = isl_printer_print_str(p, "(");
2253
2254                 set_i = isl_set_copy(pwaff->p[i].set);
2255                 set_i = isl_set_gist(set_i, isl_set_copy(domain));
2256                 p = print_set_c(p, space, set_i);
2257                 isl_set_free(set_i);
2258
2259                 p = isl_printer_print_str(p, ") ? (");
2260                 p = print_aff_on_domain_c(p, space,
2261                                         pwaff->p[i].aff, pwaff->p[i].set);
2262                 p = isl_printer_print_str(p, ") : ");
2263         }
2264
2265         isl_set_free(domain);
2266
2267         p = print_aff_on_domain_c(p, space, pwaff->p[pwaff->n - 1].aff,
2268                                         pwaff->p[pwaff->n - 1].set);
2269         isl_space_free(space);
2270         return p;
2271 error:
2272         isl_printer_free(p);
2273         return NULL;
2274 }
2275
2276 __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p,
2277         __isl_keep isl_aff *aff)
2278 {
2279         if (!p || !aff)
2280                 goto error;
2281
2282         if (p->output_format == ISL_FORMAT_ISL)
2283                 return print_aff_isl(p, aff);
2284         else if (p->output_format == ISL_FORMAT_C)
2285                 return print_aff_c(p, aff);
2286         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2287                 goto error);
2288 error:
2289         isl_printer_free(p);
2290         return NULL;
2291 }
2292
2293 __isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p,
2294         __isl_keep isl_pw_aff *pwaff)
2295 {
2296         if (!p || !pwaff)
2297                 goto error;
2298
2299         if (p->output_format == ISL_FORMAT_ISL)
2300                 return print_pw_aff_isl(p, pwaff);
2301         else if (p->output_format == ISL_FORMAT_C)
2302                 return print_pw_aff_c(p, pwaff);
2303         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2304                 goto error);
2305 error:
2306         isl_printer_free(p);
2307         return NULL;
2308 }
2309
2310 static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p,
2311         __isl_keep isl_multi_aff *maff)
2312 {
2313         return print_space(maff->space, p, 0, 0, NULL, maff);
2314 }
2315
2316 static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p,
2317         __isl_keep isl_multi_aff *maff)
2318 {
2319         if (!maff)
2320                 goto error;
2321
2322         if (isl_space_dim(maff->space, isl_dim_param) > 0) {
2323                 p = print_tuple(maff->space, p, isl_dim_param, 0, NULL, NULL);
2324                 p = isl_printer_print_str(p, " -> ");
2325         }
2326         p = isl_printer_print_str(p, "{ ");
2327         p = print_multi_aff(p, maff);
2328         p = isl_printer_print_str(p, " }");
2329         return p;
2330 error:
2331         isl_printer_free(p);
2332         return NULL;
2333 }
2334
2335 __isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p,
2336         __isl_keep isl_multi_aff *maff)
2337 {
2338         if (!p || !maff)
2339                 goto error;
2340
2341         if (p->output_format == ISL_FORMAT_ISL)
2342                 return print_multi_aff_isl(p, maff);
2343         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2344                 goto error);
2345 error:
2346         isl_printer_free(p);
2347         return NULL;
2348 }
2349
2350 static __isl_give isl_printer *print_pw_multi_aff_body(
2351         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2352 {
2353         int i;
2354
2355         if (!pma)
2356                 goto error;
2357
2358         for (i = 0; i < pma->n; ++i) {
2359                 if (i)
2360                         p = isl_printer_print_str(p, "; ");
2361                 p = print_multi_aff(p, pma->p[i].maff);
2362                 p = print_disjuncts((isl_map *)pma->p[i].set, p, 0);
2363         }
2364         return p;
2365 error:
2366         isl_printer_free(p);
2367         return NULL;
2368 }
2369
2370 static __isl_give isl_printer *print_pw_multi_aff_isl(__isl_take isl_printer *p,
2371         __isl_keep isl_pw_multi_aff *pma)
2372 {
2373         if (!pma)
2374                 goto error;
2375
2376         if (isl_space_dim(pma->dim, isl_dim_param) > 0) {
2377                 p = print_tuple(pma->dim, p, isl_dim_param, 0, NULL, NULL);
2378                 p = isl_printer_print_str(p, " -> ");
2379         }
2380         p = isl_printer_print_str(p, "{ ");
2381         p = print_pw_multi_aff_body(p, pma);
2382         p = isl_printer_print_str(p, " }");
2383         return p;
2384 error:
2385         isl_printer_free(p);
2386         return NULL;
2387 }
2388
2389 static __isl_give isl_printer *print_unnamed_pw_multi_aff_c(
2390         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2391 {
2392         int i;
2393
2394         for (i = 0; i < pma->n - 1; ++i) {
2395                 p = isl_printer_print_str(p, "(");
2396                 p = print_set_c(p, pma->dim, pma->p[i].set);
2397                 p = isl_printer_print_str(p, ") ? (");
2398                 p = print_aff_c(p, pma->p[i].maff->p[0]);
2399                 p = isl_printer_print_str(p, ") : ");
2400         }
2401
2402         return print_aff_c(p, pma->p[pma->n - 1].maff->p[0]);
2403 }
2404
2405 static __isl_give isl_printer *print_pw_multi_aff_c(__isl_take isl_printer *p,
2406         __isl_keep isl_pw_multi_aff *pma)
2407 {
2408         int n;
2409         const char *name;
2410
2411         if (!pma)
2412                 goto error;
2413         if (pma->n < 1)
2414                 isl_die(p->ctx, isl_error_unsupported,
2415                         "cannot print empty isl_pw_multi_aff in C format",
2416                         goto error);
2417         name = isl_pw_multi_aff_get_tuple_name(pma, isl_dim_out);
2418         if (!name && isl_pw_multi_aff_dim(pma, isl_dim_out) == 1)
2419                 return print_unnamed_pw_multi_aff_c(p, pma);
2420         if (!name)
2421                 isl_die(p->ctx, isl_error_unsupported,
2422                         "cannot print unnamed isl_pw_multi_aff in C format",
2423                         goto error);
2424
2425         p = isl_printer_print_str(p, name);
2426         n = isl_pw_multi_aff_dim(pma, isl_dim_out);
2427         if (n != 0)
2428                 isl_die(p->ctx, isl_error_unsupported,
2429                         "not supported yet", goto error);
2430
2431         return p;
2432 error:
2433         isl_printer_free(p);
2434         return NULL;
2435 }
2436
2437 __isl_give isl_printer *isl_printer_print_pw_multi_aff(
2438         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2439 {
2440         if (!p || !pma)
2441                 goto error;
2442
2443         if (p->output_format == ISL_FORMAT_ISL)
2444                 return print_pw_multi_aff_isl(p, pma);
2445         if (p->output_format == ISL_FORMAT_C)
2446                 return print_pw_multi_aff_c(p, pma);
2447         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2448                 goto error);
2449 error:
2450         isl_printer_free(p);
2451         return NULL;
2452 }
2453
2454 static int print_pw_multi_aff_body_wrap(__isl_take isl_pw_multi_aff *pma,
2455         void *user)
2456 {
2457         struct isl_union_print_data *data;
2458         data = (struct isl_union_print_data *) user;
2459
2460         if (!data->first)
2461                 data->p = isl_printer_print_str(data->p, "; ");
2462         data->first = 0;
2463
2464         data->p = print_pw_multi_aff_body(data->p, pma);
2465         isl_pw_multi_aff_free(pma);
2466
2467         return 0;
2468 }
2469
2470 static __isl_give isl_printer *print_union_pw_multi_aff_isl(
2471         __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
2472 {
2473         struct isl_union_print_data data = { p, 1 };
2474         isl_space *space;
2475
2476         space = isl_union_pw_multi_aff_get_space(upma);
2477         if (isl_space_dim(space, isl_dim_param) > 0) {
2478                 p = print_tuple(space, p, isl_dim_param, 0, NULL, NULL);
2479                 p = isl_printer_print_str(p, s_to[0]);
2480         }
2481         isl_space_free(space);
2482         p = isl_printer_print_str(p, s_open_set[0]);
2483         isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
2484                                         &print_pw_multi_aff_body_wrap, &data);
2485         p = data.p;
2486         p = isl_printer_print_str(p, s_close_set[0]);
2487         return p;
2488 }
2489
2490 __isl_give isl_printer *isl_printer_print_union_pw_multi_aff(
2491         __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
2492 {
2493         if (!p || !upma)
2494                 goto error;
2495
2496         if (p->output_format == ISL_FORMAT_ISL)
2497                 return print_union_pw_multi_aff_isl(p, upma);
2498         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2499                 goto error);
2500 error:
2501         isl_printer_free(p);
2502         return NULL;
2503 }
2504
2505 static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p,
2506         __isl_keep isl_multi_pw_aff *mpa)
2507 {
2508         int i;
2509
2510         if (!mpa)
2511                 return isl_printer_free(p);
2512
2513         p = isl_printer_print_str(p, "(");
2514         for (i = 0; i < mpa->n; ++i) {
2515                 if (i)
2516                         p = isl_printer_print_str(p, ",");
2517                 p = isl_printer_print_pw_aff(p, mpa->p[i]);
2518         }
2519         p = isl_printer_print_str(p, ")");
2520         return p;
2521 }
2522
2523 __isl_give isl_printer *isl_printer_print_multi_pw_aff(
2524         __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa)
2525 {
2526         if (!p || !mpa)
2527                 return isl_printer_free(p);
2528
2529         if (p->output_format == ISL_FORMAT_ISL)
2530                 return print_multi_pw_aff_isl(p, mpa);
2531         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2532                 return isl_printer_free(p));
2533 }