rename isl_basic_set_add to isl_basic_set_add_dims
[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 *isl_basic_map_print_omega(
570         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
571 {
572         p = print_omega_parameters(bmap->dim, p);
573
574         p = isl_printer_start_line(p);
575         p = basic_map_print_omega(bmap, p);
576         p = isl_printer_end_line(p);
577         return p;
578 }
579
580 static __isl_give isl_printer *basic_set_print_omega(
581         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
582 {
583         p = isl_printer_print_str(p, "{ [");
584         p = print_var_list(bset->dim, p, isl_dim_set, 0, NULL, NULL);
585         p = isl_printer_print_str(p, "] ");
586         p = print_omega_constraints((isl_basic_map *)bset, p);
587         p = isl_printer_print_str(p, " }");
588         return p;
589 }
590
591 static __isl_give isl_printer *isl_basic_set_print_omega(
592         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
593 {
594         p = print_omega_parameters(bset->dim, p);
595
596         p = isl_printer_start_line(p);
597         p = basic_set_print_omega(bset, p);
598         p = isl_printer_end_line(p);
599         return p;
600 }
601
602 static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map,
603         __isl_take isl_printer *p)
604 {
605         int i;
606
607         p = print_omega_parameters(map->dim, p);
608
609         p = isl_printer_start_line(p);
610         for (i = 0; i < map->n; ++i) {
611                 if (i)
612                         p = isl_printer_print_str(p, " union ");
613                 p = basic_map_print_omega(map->p[i], p);
614         }
615         p = isl_printer_end_line(p);
616         return p;
617 }
618
619 static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set,
620         __isl_take isl_printer *p)
621 {
622         int i;
623
624         p = print_omega_parameters(set->dim, p);
625
626         p = isl_printer_start_line(p);
627         for (i = 0; i < set->n; ++i) {
628                 if (i)
629                         p = isl_printer_print_str(p, " union ");
630                 p = basic_set_print_omega(set->p[i], p);
631         }
632         p = isl_printer_end_line(p);
633         return p;
634 }
635
636 static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
637         __isl_keep isl_space *dim, __isl_take isl_printer *p, int latex)
638 {
639         if (bmap->n_div > 0) {
640                 int i;
641                 p = isl_printer_print_str(p, s_open_exists[latex]);
642                 for (i = 0; i < bmap->n_div; ++i) {
643                         if (i)
644                                 p = isl_printer_print_str(p, ", ");
645                         p = print_name(dim, p, isl_dim_div, i, latex);
646                         if (latex || isl_int_is_zero(bmap->div[i][0]))
647                                 continue;
648                         p = isl_printer_print_str(p, " = [(");
649                         p = print_affine(bmap, dim, p, bmap->div[i] + 1);
650                         p = isl_printer_print_str(p, ")/");
651                         p = isl_printer_print_isl_int(p, bmap->div[i][0]);
652                         p = isl_printer_print_str(p, "]");
653                 }
654                 p = isl_printer_print_str(p, ": ");
655         }
656
657         p = print_constraints(bmap, dim, p, latex);
658
659         if (bmap->n_div > 0)
660                 p = isl_printer_print_str(p, s_close_exists[latex]);
661         return p;
662 }
663
664 static __isl_give isl_printer *isl_basic_map_print_isl(
665         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p,
666         int latex)
667 {
668         int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
669         if (isl_basic_map_dim(bmap, isl_dim_param) > 0) {
670                 p = print_tuple(bmap->dim, p, isl_dim_param, latex, NULL, NULL);
671                 p = isl_printer_print_str(p, " -> ");
672         }
673         p = isl_printer_print_str(p, "{ ");
674         p = print_space(bmap->dim, p, latex, rational, NULL, NULL);
675         p = isl_printer_print_str(p, " : ");
676         p = print_disjunct(bmap, bmap->dim, p, latex);
677         p = isl_printer_print_str(p, " }");
678         return p;
679 }
680
681 static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
682         __isl_take isl_printer *p, int latex)
683 {
684         int i;
685
686         if (isl_map_plain_is_universe(map))
687                 return p;
688
689         p = isl_printer_print_str(p, s_such_that[latex]);
690         if (map->n == 0)
691                 p = isl_printer_print_str(p, "1 = 0");
692         for (i = 0; i < map->n; ++i) {
693                 if (i)
694                         p = isl_printer_print_str(p, s_or[latex]);
695                 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
696                         p = isl_printer_print_str(p, "(");
697                 p = print_disjunct(map->p[i], map->dim, p, latex);
698                 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
699                         p = isl_printer_print_str(p, ")");
700         }
701         return p;
702 }
703
704 /* Print the disjuncts of a map (or set).
705  * If the map turns out to be a universal parameter domain, then
706  * we need to print the colon.  Otherwise, the output looks identical
707  * to the empty set.
708  */
709 static __isl_give isl_printer *print_disjuncts_map(__isl_keep isl_map *map,
710         __isl_take isl_printer *p, int latex)
711 {
712         if (isl_map_plain_is_universe(map) && isl_space_is_params(map->dim))
713                 return isl_printer_print_str(p, s_such_that[latex]);
714         else
715                 return print_disjuncts(map, p, latex);
716 }
717
718 struct isl_aff_split {
719         isl_basic_map *aff;
720         isl_map *map;
721 };
722
723 static void free_split(__isl_take struct isl_aff_split *split, int n)
724 {
725         int i;
726
727         if (!split)
728                 return;
729
730         for (i = 0; i < n; ++i) {
731                 isl_basic_map_free(split[i].aff);
732                 isl_map_free(split[i].map);
733         }
734
735         free(split);
736 }
737
738 static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap)
739 {
740         int i, j;
741         unsigned nparam, n_in, n_out, total;
742
743         bmap = isl_basic_map_cow(bmap);
744         if (!bmap)
745                 return NULL;
746         if (isl_basic_map_free_inequality(bmap, bmap->n_ineq) < 0)
747                 goto error;
748
749         nparam = isl_basic_map_dim(bmap, isl_dim_param);
750         n_in = isl_basic_map_dim(bmap, isl_dim_in);
751         n_out = isl_basic_map_dim(bmap, isl_dim_out);
752         total = isl_basic_map_dim(bmap, isl_dim_all);
753         for (i = bmap->n_eq - 1; i >= 0; --i) {
754                 j = isl_seq_last_non_zero(bmap->eq[i] + 1, total);
755                 if (j >= nparam && j < nparam + n_in + n_out &&
756                     (isl_int_is_one(bmap->eq[i][1 + j]) ||
757                      isl_int_is_negone(bmap->eq[i][1 + j])))
758                         continue;
759                 if (isl_basic_map_drop_equality(bmap, i) < 0)
760                         goto error;
761         }
762
763         bmap = isl_basic_map_finalize(bmap);
764
765         return bmap;
766 error:
767         isl_basic_map_free(bmap);
768         return NULL;
769 }
770
771 static int aff_split_cmp(const void *p1, const void *p2)
772 {
773         const struct isl_aff_split *s1, *s2;
774         s1 = (const struct isl_aff_split *) p1;
775         s2 = (const struct isl_aff_split *) p2;
776
777         return isl_basic_map_plain_cmp(s1->aff, s2->aff);
778 }
779
780 static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap,
781         __isl_keep isl_basic_map *aff)
782 {
783         int i, j;
784         unsigned total;
785
786         if (!bmap || !aff)
787                 goto error;
788
789         total = isl_space_dim(bmap->dim, isl_dim_all);
790
791         for (i = bmap->n_eq - 1; i >= 0; --i) {
792                 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + total,
793                                             bmap->n_div) != -1)
794                         continue;
795                 for (j = 0; j < aff->n_eq; ++j) {
796                         if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + total) &&
797                             !isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + total))
798                                 continue;
799                         if (isl_basic_map_drop_equality(bmap, i) < 0)
800                                 goto error;
801                         break;
802                 }
803         }
804
805         return bmap;
806 error:
807         isl_basic_map_free(bmap);
808         return NULL;
809 }
810
811 static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map)
812 {
813         int i, n;
814         struct isl_aff_split *split;
815         isl_ctx *ctx;
816
817         ctx = isl_map_get_ctx(map);
818         split = isl_calloc_array(ctx, struct isl_aff_split, map->n);
819         if (!split)
820                 return NULL;
821
822         for (i = 0; i < map->n; ++i) {
823                 isl_basic_map *bmap;
824                 split[i].aff = get_aff(isl_basic_map_copy(map->p[i]));
825                 bmap = isl_basic_map_copy(map->p[i]);
826                 bmap = isl_basic_map_cow(bmap);
827                 bmap = drop_aff(bmap, split[i].aff);
828                 split[i].map = isl_map_from_basic_map(bmap);
829                 if (!split[i].aff || !split[i].map)
830                         goto error;
831         }
832
833         qsort(split, map->n, sizeof(struct isl_aff_split), &aff_split_cmp);
834
835         n = map->n;
836         for (i = n - 1; i >= 1; --i) {
837                 if (!isl_basic_map_plain_is_equal(split[i - 1].aff,
838                                                  split[i].aff))
839                         continue;
840                 isl_basic_map_free(split[i].aff);
841                 split[i - 1].map = isl_map_union(split[i - 1].map,
842                                                  split[i].map);
843                 if (i != n - 1)
844                         split[i] = split[n - 1];
845                 split[n - 1].aff = NULL;
846                 split[n - 1].map = NULL;
847                 --n;
848         }
849
850         return split;
851 error:
852         free_split(split, map->n);
853         return NULL;
854 }
855
856 static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p,
857         struct isl_aff_split *split, int n)
858 {
859         int i;
860         int rational;
861
862         for (i = 0; i < n; ++i) {
863                 isl_space *dim;
864
865                 if (!split[i].map)
866                         break;
867                 dim = split[i].map->dim;
868                 rational = split[i].map->n > 0 &&
869                     ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL);
870                 if (i)
871                         p = isl_printer_print_str(p, "; ");
872                 p = print_space(dim, p, 0, rational, split[i].aff, NULL);
873                 p = print_disjuncts_map(split[i].map, p, 0);
874         }
875
876         return p;
877 }
878
879 static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map,
880         __isl_take isl_printer *p)
881 {
882         struct isl_aff_split *split = NULL;
883         int rational;
884
885         if (map->n > 0)
886                 split = split_aff(map);
887         if (split) {
888                 p = print_split_map(p, split, map->n);
889         } else {
890                 rational = map->n > 0 &&
891                     ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL);
892                 p = print_space(map->dim, p, 0, rational, NULL, NULL);
893                 p = print_disjuncts_map(map, p, 0);
894         }
895         free_split(split, map->n);
896         return p;
897 }
898
899 static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,
900         __isl_take isl_printer *p)
901 {
902         if (isl_map_dim(map, isl_dim_param) > 0) {
903                 p = print_tuple(map->dim, p, isl_dim_param, 0, NULL, NULL);
904                 p = isl_printer_print_str(p, s_to[0]);
905         }
906         p = isl_printer_print_str(p, s_open_set[0]);
907         p = isl_map_print_isl_body(map, p);
908         p = isl_printer_print_str(p, s_close_set[0]);
909         return p;
910 }
911
912 static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map,
913         __isl_take isl_printer *p, __isl_keep isl_basic_map *aff)
914 {
915         if (isl_map_dim(map, isl_dim_param) > 0) {
916                 p = print_tuple(map->dim, p, isl_dim_param, 1, NULL, NULL);
917                 p = isl_printer_print_str(p, s_to[1]);
918         }
919         p = isl_printer_print_str(p, s_open_set[1]);
920         p = print_space(map->dim, p, 1, 0, aff, NULL);
921         p = print_disjuncts_map(map, p, 1);
922         p = isl_printer_print_str(p, s_close_set[1]);
923
924         return p;
925 }
926
927 static __isl_give isl_printer *isl_map_print_latex(__isl_keep isl_map *map,
928         __isl_take isl_printer *p)
929 {
930         int i;
931         struct isl_aff_split *split = NULL;
932
933         if (map->n > 0)
934                 split = split_aff(map);
935
936         if (!split)
937                 return print_latex_map(map, p, NULL);
938
939         for (i = 0; i < map->n; ++i) {
940                 if (!split[i].map)
941                         break;
942                 if (i)
943                         p = isl_printer_print_str(p, " \\cup ");
944                 p = print_latex_map(split[i].map, p, split[i].aff);
945         }
946
947         free_split(split, map->n);
948         return p;
949 }
950
951 __isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p,
952         __isl_keep isl_basic_map *bmap)
953 {
954         if (!p || !bmap)
955                 goto error;
956         if (p->output_format == ISL_FORMAT_ISL)
957                 return isl_basic_map_print_isl(bmap, p, 0);
958         else if (p->output_format == ISL_FORMAT_OMEGA)
959                 return isl_basic_map_print_omega(bmap, p);
960         isl_assert(bmap->ctx, 0, goto error);
961 error:
962         isl_printer_free(p);
963         return NULL;
964 }
965
966 void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent,
967         const char *prefix, const char *suffix, unsigned output_format)
968 {
969         isl_printer *printer;
970
971         if (!bmap)
972                 return;
973
974         printer = isl_printer_to_file(bmap->ctx, out);
975         printer = isl_printer_set_indent(printer, indent);
976         printer = isl_printer_set_prefix(printer, prefix);
977         printer = isl_printer_set_suffix(printer, suffix);
978         printer = isl_printer_set_output_format(printer, output_format);
979         isl_printer_print_basic_map(printer, bmap);
980
981         isl_printer_free(printer);
982 }
983
984 __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,
985         __isl_keep isl_basic_set *bset)
986 {
987         if (!p || !bset)
988                 goto error;
989
990         if (p->output_format == ISL_FORMAT_ISL)
991                 return isl_basic_map_print_isl(bset, p, 0);
992         else if (p->output_format == ISL_FORMAT_POLYLIB)
993                 return isl_basic_set_print_polylib(bset, p, 0);
994         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
995                 return isl_basic_set_print_polylib(bset, p, 1);
996         else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)
997                 return bset_print_constraints_polylib(bset, p);
998         else if (p->output_format == ISL_FORMAT_OMEGA)
999                 return isl_basic_set_print_omega(bset, p);
1000         isl_assert(p->ctx, 0, goto error);
1001 error:
1002         isl_printer_free(p);
1003         return NULL;
1004 }
1005
1006 void isl_basic_set_print(struct isl_basic_set *bset, FILE *out, int indent,
1007         const char *prefix, const char *suffix, unsigned output_format)
1008 {
1009         isl_printer *printer;
1010
1011         if (!bset)
1012                 return;
1013
1014         printer = isl_printer_to_file(bset->ctx, out);
1015         printer = isl_printer_set_indent(printer, indent);
1016         printer = isl_printer_set_prefix(printer, prefix);
1017         printer = isl_printer_set_suffix(printer, suffix);
1018         printer = isl_printer_set_output_format(printer, output_format);
1019         isl_printer_print_basic_set(printer, bset);
1020
1021         isl_printer_free(printer);
1022 }
1023
1024 __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,
1025         __isl_keep isl_set *set)
1026 {
1027         if (!p || !set)
1028                 goto error;
1029         if (p->output_format == ISL_FORMAT_ISL)
1030                 return isl_map_print_isl((isl_map *)set, p);
1031         else if (p->output_format == ISL_FORMAT_POLYLIB)
1032                 return isl_set_print_polylib(set, p, 0);
1033         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1034                 return isl_set_print_polylib(set, p, 1);
1035         else if (p->output_format == ISL_FORMAT_OMEGA)
1036                 return isl_set_print_omega(set, p);
1037         else if (p->output_format == ISL_FORMAT_LATEX)
1038                 return isl_map_print_latex((isl_map *)set, p);
1039         isl_assert(set->ctx, 0, goto error);
1040 error:
1041         isl_printer_free(p);
1042         return NULL;
1043 }
1044
1045 void isl_set_print(struct isl_set *set, FILE *out, int indent,
1046         unsigned output_format)
1047 {
1048         isl_printer *printer;
1049
1050         if (!set)
1051                 return;
1052
1053         printer = isl_printer_to_file(set->ctx, out);
1054         printer = isl_printer_set_indent(printer, indent);
1055         printer = isl_printer_set_output_format(printer, output_format);
1056         printer = isl_printer_print_set(printer, set);
1057
1058         isl_printer_free(printer);
1059 }
1060
1061 __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
1062         __isl_keep isl_map *map)
1063 {
1064         if (!p || !map)
1065                 goto error;
1066
1067         if (p->output_format == ISL_FORMAT_ISL)
1068                 return isl_map_print_isl(map, p);
1069         else if (p->output_format == ISL_FORMAT_POLYLIB)
1070                 return isl_map_print_polylib(map, p, 0);
1071         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1072                 return isl_map_print_polylib(map, p, 1);
1073         else if (p->output_format == ISL_FORMAT_OMEGA)
1074                 return isl_map_print_omega(map, p);
1075         else if (p->output_format == ISL_FORMAT_LATEX)
1076                 return isl_map_print_latex(map, p);
1077         isl_assert(map->ctx, 0, goto error);
1078 error:
1079         isl_printer_free(p);
1080         return NULL;
1081 }
1082
1083 struct isl_union_print_data {
1084         isl_printer *p;
1085         int first;
1086 };
1087
1088 static int print_map_body(__isl_take isl_map *map, void *user)
1089 {
1090         struct isl_union_print_data *data;
1091         data = (struct isl_union_print_data *)user;
1092
1093         if (!data->first)
1094                 data->p = isl_printer_print_str(data->p, "; ");
1095         data->first = 0;
1096
1097         data->p = isl_map_print_isl_body(map, data->p);
1098         isl_map_free(map);
1099
1100         return 0;
1101 }
1102
1103 static __isl_give isl_printer *isl_union_map_print_isl(
1104         __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
1105 {
1106         struct isl_union_print_data data = { p, 1 };
1107         isl_space *dim;
1108         dim = isl_union_map_get_space(umap);
1109         if (isl_space_dim(dim, isl_dim_param) > 0) {
1110                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1111                 p = isl_printer_print_str(p, s_to[0]);
1112         }
1113         isl_space_free(dim);
1114         p = isl_printer_print_str(p, s_open_set[0]);
1115         isl_union_map_foreach_map(umap, &print_map_body, &data);
1116         p = data.p;
1117         p = isl_printer_print_str(p, s_close_set[0]);
1118         return p;
1119 }
1120
1121 static int print_latex_map_body(__isl_take isl_map *map, void *user)
1122 {
1123         struct isl_union_print_data *data;
1124         data = (struct isl_union_print_data *)user;
1125
1126         if (!data->first)
1127                 data->p = isl_printer_print_str(data->p, " \\cup ");
1128         data->first = 0;
1129
1130         data->p = isl_map_print_latex(map, data->p);
1131         isl_map_free(map);
1132
1133         return 0;
1134 }
1135
1136 static __isl_give isl_printer *isl_union_map_print_latex(
1137         __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
1138 {
1139         struct isl_union_print_data data = { p, 1 };
1140         isl_union_map_foreach_map(umap, &print_latex_map_body, &data);
1141         p = data.p;
1142         return p;
1143 }
1144
1145 __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p,
1146         __isl_keep isl_union_map *umap)
1147 {
1148         if (!p || !umap)
1149                 goto error;
1150
1151         if (p->output_format == ISL_FORMAT_ISL)
1152                 return isl_union_map_print_isl(umap, p);
1153         if (p->output_format == ISL_FORMAT_LATEX)
1154                 return isl_union_map_print_latex(umap, p);
1155
1156         isl_die(p->ctx, isl_error_invalid,
1157                 "invalid output format for isl_union_map", goto error);
1158 error:
1159         isl_printer_free(p);
1160         return NULL;
1161 }
1162
1163 __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
1164         __isl_keep isl_union_set *uset)
1165 {
1166         if (!p || !uset)
1167                 goto error;
1168
1169         if (p->output_format == ISL_FORMAT_ISL)
1170                 return isl_union_map_print_isl((isl_union_map *)uset, p);
1171         if (p->output_format == ISL_FORMAT_LATEX)
1172                 return isl_union_map_print_latex((isl_union_map *)uset, p);
1173
1174         isl_die(p->ctx, isl_error_invalid,
1175                 "invalid output format for isl_union_set", goto error);
1176 error:
1177         isl_printer_free(p);
1178         return NULL;
1179 }
1180
1181 void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent,
1182         unsigned output_format)
1183 {
1184         isl_printer *printer;
1185
1186         if (!map)
1187                 return;
1188
1189         printer = isl_printer_to_file(map->ctx, out);
1190         printer = isl_printer_set_indent(printer, indent);
1191         printer = isl_printer_set_output_format(printer, output_format);
1192         printer = isl_printer_print_map(printer, map);
1193
1194         isl_printer_free(printer);
1195 }
1196
1197 static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec)
1198 {
1199         int i;
1200         int n;
1201
1202         for (i = 0, n = 0; i < rec->n; ++i)
1203                 if (!isl_upoly_is_zero(rec->p[i]))
1204                         ++n;
1205
1206         return n;
1207 }
1208
1209 static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
1210         __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p)
1211 {
1212         int c = p->output_format == ISL_FORMAT_C;
1213         p = isl_printer_print_str(p, c ? "floord(" : "[(");
1214         p = print_affine_of_len(dim, div, p,
1215                                 div->row[pos] + 1, div->n_col - 1);
1216         p = isl_printer_print_str(p, c ? ", " : ")/");
1217         p = isl_printer_print_isl_int(p, div->row[pos][0]);
1218         p = isl_printer_print_str(p, c ? ")" : "]");
1219         return p;
1220 }
1221
1222 static __isl_give isl_printer *upoly_print_cst(__isl_keep struct isl_upoly *up,
1223         __isl_take isl_printer *p, int first)
1224 {
1225         struct isl_upoly_cst *cst;
1226         int neg;
1227
1228         cst = isl_upoly_as_cst(up);
1229         if (!cst)
1230                 goto error;
1231         neg = !first && isl_int_is_neg(cst->n);
1232         if (!first)
1233                 p = isl_printer_print_str(p, neg ? " - " :  " + ");
1234         if (neg)
1235                 isl_int_neg(cst->n, cst->n);
1236         if (isl_int_is_zero(cst->d)) {
1237                 int sgn = isl_int_sgn(cst->n);
1238                 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
1239                                             sgn == 0 ? "NaN" : "infty");
1240         } else
1241                 p = isl_printer_print_isl_int(p, cst->n);
1242         if (neg)
1243                 isl_int_neg(cst->n, cst->n);
1244         if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) {
1245                 p = isl_printer_print_str(p, "/");
1246                 p = isl_printer_print_isl_int(p, cst->d);
1247         }
1248         return p;
1249 error:
1250         isl_printer_free(p);
1251         return NULL;
1252 }
1253
1254 static __isl_give isl_printer *print_base(__isl_take isl_printer *p,
1255         __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var)
1256 {
1257         unsigned total;
1258
1259         total = isl_space_dim(dim, isl_dim_all);
1260         if (var < total)
1261                 p = print_term(dim, NULL, dim->ctx->one, 1 + var, p, 0);
1262         else
1263                 p = print_div(dim, div, var - total, p);
1264         return p;
1265 }
1266
1267 static __isl_give isl_printer *print_pow(__isl_take isl_printer *p,
1268         __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var, int exp)
1269 {
1270         p = print_base(p, dim, div, var);
1271         if (exp == 1)
1272                 return p;
1273         if (p->output_format == ISL_FORMAT_C) {
1274                 int i;
1275                 for (i = 1; i < exp; ++i) {
1276                         p = isl_printer_print_str(p, "*");
1277                         p = print_base(p, dim, div, var);
1278                 }
1279         } else {
1280                 p = isl_printer_print_str(p, "^");
1281                 p = isl_printer_print_int(p, exp);
1282         }
1283         return p;
1284 }
1285
1286 static __isl_give isl_printer *upoly_print(__isl_keep struct isl_upoly *up,
1287         __isl_keep isl_space *dim, __isl_keep isl_mat *div,
1288         __isl_take isl_printer *p, int outer)
1289 {
1290         int i, n, first, print_parens;
1291         struct isl_upoly_rec *rec;
1292
1293         if (!p || !up || !dim || !div)
1294                 goto error;
1295
1296         if (isl_upoly_is_cst(up))
1297                 return upoly_print_cst(up, p, 1);
1298
1299         rec = isl_upoly_as_rec(up);
1300         if (!rec)
1301                 goto error;
1302         n = upoly_rec_n_non_zero(rec);
1303         print_parens = n > 1 ||
1304                     (outer && rec->up.var >= isl_space_dim(dim, isl_dim_all));
1305         if (print_parens)
1306                 p = isl_printer_print_str(p, "(");
1307         for (i = 0, first = 1; i < rec->n; ++i) {
1308                 if (isl_upoly_is_zero(rec->p[i]))
1309                         continue;
1310                 if (isl_upoly_is_negone(rec->p[i])) {
1311                         if (!i)
1312                                 p = isl_printer_print_str(p, "-1");
1313                         else if (first)
1314                                 p = isl_printer_print_str(p, "-");
1315                         else
1316                                 p = isl_printer_print_str(p, " - ");
1317                 } else if (isl_upoly_is_cst(rec->p[i]) &&
1318                                 !isl_upoly_is_one(rec->p[i]))
1319                         p = upoly_print_cst(rec->p[i], p, first);
1320                 else {
1321                         if (!first)
1322                                 p = isl_printer_print_str(p, " + ");
1323                         if (i == 0 || !isl_upoly_is_one(rec->p[i]))
1324                                 p = upoly_print(rec->p[i], dim, div, p, 0);
1325                 }
1326                 first = 0;
1327                 if (i == 0)
1328                         continue;
1329                 if (!isl_upoly_is_one(rec->p[i]) &&
1330                     !isl_upoly_is_negone(rec->p[i]))
1331                         p = isl_printer_print_str(p, " * ");
1332                 p = print_pow(p, dim, div, rec->up.var, i);
1333         }
1334         if (print_parens)
1335                 p = isl_printer_print_str(p, ")");
1336         return p;
1337 error:
1338         isl_printer_free(p);
1339         return NULL;
1340 }
1341
1342 static __isl_give isl_printer *print_qpolynomial(__isl_take isl_printer *p,
1343         __isl_keep isl_qpolynomial *qp)
1344 {
1345         if (!p || !qp)
1346                 goto error;
1347         p = upoly_print(qp->upoly, qp->dim, qp->div, p, 1);
1348         return p;
1349 error:
1350         isl_printer_free(p);
1351         return NULL;
1352 }
1353
1354 static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p,
1355         __isl_keep isl_qpolynomial *qp)
1356 {
1357         if (!p || !qp)
1358                 goto error;
1359
1360         if (isl_space_dim(qp->dim, isl_dim_param) > 0) {
1361                 p = print_tuple(qp->dim, p, isl_dim_param, 0, NULL, NULL);
1362                 p = isl_printer_print_str(p, " -> ");
1363         }
1364         p = isl_printer_print_str(p, "{ ");
1365         if (!isl_space_is_params(qp->dim)) {
1366                 p = print_space(qp->dim, p, 0, 0, NULL, NULL);
1367                 p = isl_printer_print_str(p, " -> ");
1368         }
1369         p = print_qpolynomial(p, qp);
1370         p = isl_printer_print_str(p, " }");
1371         return p;
1372 error:
1373         isl_printer_free(p);
1374         return NULL;
1375 }
1376
1377 static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p,
1378         __isl_keep isl_space *dim, __isl_keep isl_qpolynomial *qp)
1379 {
1380         isl_int den;
1381
1382         isl_int_init(den);
1383         isl_qpolynomial_get_den(qp, &den);
1384         if (!isl_int_is_one(den)) {
1385                 isl_qpolynomial *f;
1386                 p = isl_printer_print_str(p, "(");
1387                 qp = isl_qpolynomial_copy(qp);
1388                 f = isl_qpolynomial_rat_cst_on_domain(isl_space_copy(qp->dim),
1389                                                 den, qp->dim->ctx->one);
1390                 qp = isl_qpolynomial_mul(qp, f);
1391         }
1392         if (qp)
1393                 p = upoly_print(qp->upoly, dim, qp->div, p, 0);
1394         if (!isl_int_is_one(den)) {
1395                 p = isl_printer_print_str(p, ")/");
1396                 p = isl_printer_print_isl_int(p, den);
1397                 isl_qpolynomial_free(qp);
1398         }
1399         isl_int_clear(den);
1400         return p;
1401 }
1402
1403 __isl_give isl_printer *isl_printer_print_qpolynomial(
1404         __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp)
1405 {
1406         if (!p || !qp)
1407                 goto error;
1408
1409         if (p->output_format == ISL_FORMAT_ISL)
1410                 return print_qpolynomial_isl(p, qp);
1411         else if (p->output_format == ISL_FORMAT_C)
1412                 return print_qpolynomial_c(p, qp->dim, qp);
1413         else
1414                 isl_die(qp->dim->ctx, isl_error_unsupported,
1415                         "output format not supported for isl_qpolynomials",
1416                         goto error);
1417 error:
1418         isl_printer_free(p);
1419         return NULL;
1420 }
1421
1422 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
1423         unsigned output_format)
1424 {
1425         isl_printer *p;
1426
1427         if  (!qp)
1428                 return;
1429
1430         isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1431         p = isl_printer_to_file(qp->dim->ctx, out);
1432         p = isl_printer_print_qpolynomial(p, qp);
1433         isl_printer_free(p);
1434 }
1435
1436 static __isl_give isl_printer *qpolynomial_fold_print(
1437         __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
1438 {
1439         int i;
1440
1441         if (fold->type == isl_fold_min)
1442                 p = isl_printer_print_str(p, "min");
1443         else if (fold->type == isl_fold_max)
1444                 p = isl_printer_print_str(p, "max");
1445         p = isl_printer_print_str(p, "(");
1446         for (i = 0; i < fold->n; ++i) {
1447                 if (i)
1448                         p = isl_printer_print_str(p, ", ");
1449                 p = print_qpolynomial(p, fold->qp[i]);
1450         }
1451         p = isl_printer_print_str(p, ")");
1452         return p;
1453 }
1454
1455 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
1456         FILE *out, unsigned output_format)
1457 {
1458         isl_printer *p;
1459
1460         if (!fold)
1461                 return;
1462
1463         isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1464
1465         p = isl_printer_to_file(fold->dim->ctx, out);
1466         p = isl_printer_print_qpolynomial_fold(p, fold);
1467
1468         isl_printer_free(p);
1469 }
1470
1471 static __isl_give isl_printer *isl_pwqp_print_isl_body(
1472         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1473 {
1474         int i = 0;
1475
1476         for (i = 0; i < pwqp->n; ++i) {
1477                 if (i)
1478                         p = isl_printer_print_str(p, "; ");
1479                 if (!isl_space_is_params(pwqp->p[i].set->dim)) {
1480                         p = print_space(pwqp->p[i].set->dim, p, 0, 0, NULL, NULL);
1481                         p = isl_printer_print_str(p, " -> ");
1482                 }
1483                 p = print_qpolynomial(p, pwqp->p[i].qp);
1484                 p = print_disjuncts((isl_map *)pwqp->p[i].set, p, 0);
1485         }
1486
1487         return p;
1488 }
1489
1490 static __isl_give isl_printer *print_pw_qpolynomial_isl(
1491         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1492 {
1493         if (!p || !pwqp)
1494                 goto error;
1495
1496         if (isl_space_dim(pwqp->dim, isl_dim_param) > 0) {
1497                 p = print_tuple(pwqp->dim, p, isl_dim_param, 0, NULL, NULL);
1498                 p = isl_printer_print_str(p, " -> ");
1499         }
1500         p = isl_printer_print_str(p, "{ ");
1501         if (pwqp->n == 0) {
1502                 if (!isl_space_is_set(pwqp->dim)) {
1503                         p = print_tuple(pwqp->dim, p, isl_dim_in, 0, NULL, NULL);
1504                         p = isl_printer_print_str(p, " -> ");
1505                 }
1506                 p = isl_printer_print_str(p, "0");
1507         }
1508         p = isl_pwqp_print_isl_body(p, pwqp);
1509         p = isl_printer_print_str(p, " }");
1510         return p;
1511 error:
1512         isl_printer_free(p);
1513         return NULL;
1514 }
1515
1516 void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
1517         unsigned output_format)
1518 {
1519         isl_printer *p;
1520
1521         if (!pwqp)
1522                 return;
1523
1524         p = isl_printer_to_file(pwqp->dim->ctx, out);
1525         p = isl_printer_set_output_format(p, output_format);
1526         p = isl_printer_print_pw_qpolynomial(p, pwqp);
1527
1528         isl_printer_free(p);
1529 }
1530
1531 static __isl_give isl_printer *isl_pwf_print_isl_body(
1532         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1533 {
1534         int i = 0;
1535
1536         for (i = 0; i < pwf->n; ++i) {
1537                 if (i)
1538                         p = isl_printer_print_str(p, "; ");
1539                 if (!isl_space_is_params(pwf->p[i].set->dim)) {
1540                         p = print_space(pwf->p[i].set->dim, p, 0, 0, NULL, NULL);
1541                         p = isl_printer_print_str(p, " -> ");
1542                 }
1543                 p = qpolynomial_fold_print(pwf->p[i].fold, p);
1544                 p = print_disjuncts((isl_map *)pwf->p[i].set, p, 0);
1545         }
1546
1547         return p;
1548 }
1549
1550 static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(
1551         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1552 {
1553         if (isl_space_dim(pwf->dim, isl_dim_param) > 0) {
1554                 p = print_tuple(pwf->dim, p, isl_dim_param, 0, NULL, NULL);
1555                 p = isl_printer_print_str(p, " -> ");
1556         }
1557         p = isl_printer_print_str(p, "{ ");
1558         if (pwf->n == 0) {
1559                 if (!isl_space_is_set(pwf->dim)) {
1560                         p = print_tuple(pwf->dim, p, isl_dim_in, 0, NULL, NULL);
1561                         p = isl_printer_print_str(p, " -> ");
1562                 }
1563                 p = isl_printer_print_str(p, "0");
1564         }
1565         p = isl_pwf_print_isl_body(p, pwf);
1566         p = isl_printer_print_str(p, " }");
1567         return p;
1568 }
1569
1570 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1571         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c);
1572
1573 static __isl_give isl_printer *print_name_c(__isl_take isl_printer *p,
1574         __isl_keep isl_space *dim,
1575         __isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos)
1576 {
1577         if (type == isl_dim_div) {
1578                 p = isl_printer_print_str(p, "floord(");
1579                 p = print_affine_c(p, dim, bset, bset->div[pos] + 1);
1580                 p = isl_printer_print_str(p, ", ");
1581                 p = isl_printer_print_isl_int(p, bset->div[pos][0]);
1582                 p = isl_printer_print_str(p, ")");
1583         } else {
1584                 const char *name;
1585
1586                 name = isl_space_get_dim_name(dim, type, pos);
1587                 if (!name)
1588                         name = "UNNAMED";
1589                 p = isl_printer_print_str(p, name);
1590         }
1591         return p;
1592 }
1593
1594 static __isl_give isl_printer *print_term_c(__isl_take isl_printer *p,
1595         __isl_keep isl_space *dim,
1596         __isl_keep isl_basic_set *bset, isl_int c, unsigned pos)
1597 {
1598         enum isl_dim_type type;
1599
1600         if (pos == 0)
1601                 return isl_printer_print_isl_int(p, c);
1602
1603         if (isl_int_is_one(c))
1604                 ;
1605         else if (isl_int_is_negone(c))
1606                 p = isl_printer_print_str(p, "-");
1607         else {
1608                 p = isl_printer_print_isl_int(p, c);
1609                 p = isl_printer_print_str(p, "*");
1610         }
1611         type = pos2type(dim, &pos);
1612         p = print_name_c(p, dim, bset, type, pos);
1613         return p;
1614 }
1615
1616 static __isl_give isl_printer *print_partial_affine_c(__isl_take isl_printer *p,
1617         __isl_keep isl_space *dim,
1618         __isl_keep isl_basic_set *bset, isl_int *c, unsigned len)
1619 {
1620         int i;
1621         int first;
1622
1623         for (i = 0, first = 1; i < len; ++i) {
1624                 int flip = 0;
1625                 if (isl_int_is_zero(c[i]))
1626                         continue;
1627                 if (!first) {
1628                         if (isl_int_is_neg(c[i])) {
1629                                 flip = 1;
1630                                 isl_int_neg(c[i], c[i]);
1631                                 p = isl_printer_print_str(p, " - ");
1632                         } else 
1633                                 p = isl_printer_print_str(p, " + ");
1634                 }
1635                 first = 0;
1636                 p = print_term_c(p, dim, bset, c[i], i);
1637                 if (flip)
1638                         isl_int_neg(c[i], c[i]);
1639         }
1640         if (first)
1641                 p = isl_printer_print_str(p, "0");
1642         return p;
1643 }
1644
1645 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1646         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c)
1647 {
1648         unsigned len = 1 + isl_basic_set_total_dim(bset);
1649         return print_partial_affine_c(p, dim, bset, c, len);
1650 }
1651
1652 /* We skip the constraint if it is implied by the div expression.
1653  */
1654 static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,
1655         __isl_keep isl_space *dim,
1656         __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int first)
1657 {
1658         unsigned o_div;
1659         unsigned n_div;
1660         int div;
1661
1662         o_div = isl_basic_set_offset(bset, isl_dim_div);
1663         n_div = isl_basic_set_dim(bset, isl_dim_div);
1664         div = isl_seq_last_non_zero(c + o_div, n_div);
1665         if (div >= 0 && isl_basic_set_is_div_constraint(bset, c, div))
1666                 return p;
1667
1668         if (!first)
1669                 p = isl_printer_print_str(p, " && ");
1670
1671         p = print_affine_c(p, dim, bset, c);
1672         p = isl_printer_print_str(p, " ");
1673         p = isl_printer_print_str(p, op);
1674         p = isl_printer_print_str(p, " 0");
1675         return p;
1676 }
1677
1678 static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,
1679         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset)
1680 {
1681         int i, j;
1682         unsigned n_div = isl_basic_set_dim(bset, isl_dim_div);
1683         unsigned total = isl_basic_set_total_dim(bset) - n_div;
1684
1685         for (i = 0; i < bset->n_eq; ++i) {
1686                 j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div);
1687                 if (j < 0)
1688                         p = print_constraint_c(p, dim, bset,
1689                                                 bset->eq[i], "==", !i);
1690                 else {
1691                         if (i)
1692                                 p = isl_printer_print_str(p, " && ");
1693                         p = isl_printer_print_str(p, "(");
1694                         p = print_partial_affine_c(p, dim, bset, bset->eq[i],
1695                                                    1 + total + j);
1696                         p = isl_printer_print_str(p, ") % ");
1697                         p = isl_printer_print_isl_int(p,
1698                                                 bset->eq[i][1 + total + j]);
1699                         p = isl_printer_print_str(p, " == 0");
1700                 }
1701         }
1702         for (i = 0; i < bset->n_ineq; ++i)
1703                 p = print_constraint_c(p, dim, bset, bset->ineq[i], ">=",
1704                                         !bset->n_eq && !i);
1705         return p;
1706 }
1707
1708 static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,
1709         __isl_keep isl_space *dim, __isl_keep isl_set *set)
1710 {
1711         int i;
1712
1713         if (set->n == 0)
1714                 p = isl_printer_print_str(p, "0");
1715
1716         for (i = 0; i < set->n; ++i) {
1717                 if (i)
1718                         p = isl_printer_print_str(p, " || ");
1719                 if (set->n > 1)
1720                         p = isl_printer_print_str(p, "(");
1721                 p = print_basic_set_c(p, dim, set->p[i]);
1722                 if (set->n > 1)
1723                         p = isl_printer_print_str(p, ")");
1724         }
1725         return p;
1726 }
1727
1728 static __isl_give isl_printer *print_pw_qpolynomial_c(
1729         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1730 {
1731         int i;
1732
1733         if (pwqp->n == 1 && isl_set_plain_is_universe(pwqp->p[0].set))
1734                 return print_qpolynomial_c(p, pwqp->dim, pwqp->p[0].qp);
1735
1736         for (i = 0; i < pwqp->n; ++i) {
1737                 p = isl_printer_print_str(p, "(");
1738                 p = print_set_c(p, pwqp->dim, pwqp->p[i].set);
1739                 p = isl_printer_print_str(p, ") ? (");
1740                 p = print_qpolynomial_c(p, pwqp->dim, pwqp->p[i].qp);
1741                 p = isl_printer_print_str(p, ") : ");
1742         }
1743
1744         p = isl_printer_print_str(p, "0");
1745         return p;
1746 }
1747
1748 __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
1749         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1750 {
1751         if (!p || !pwqp)
1752                 goto error;
1753
1754         if (p->output_format == ISL_FORMAT_ISL)
1755                 return print_pw_qpolynomial_isl(p, pwqp);
1756         else if (p->output_format == ISL_FORMAT_C)
1757                 return print_pw_qpolynomial_c(p, pwqp);
1758         isl_assert(p->ctx, 0, goto error);
1759 error:
1760         isl_printer_free(p);
1761         return NULL;
1762 }
1763
1764 static int print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user)
1765 {
1766         struct isl_union_print_data *data;
1767         data = (struct isl_union_print_data *)user;
1768
1769         if (!data->first)
1770                 data->p = isl_printer_print_str(data->p, "; ");
1771         data->first = 0;
1772
1773         data->p = isl_pwqp_print_isl_body(data->p, pwqp);
1774         isl_pw_qpolynomial_free(pwqp);
1775
1776         return 0;
1777 }
1778
1779 static __isl_give isl_printer *print_union_pw_qpolynomial_isl(
1780         __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
1781 {
1782         struct isl_union_print_data data = { p, 1 };
1783         isl_space *dim;
1784         dim = isl_union_pw_qpolynomial_get_space(upwqp);
1785         if (isl_space_dim(dim, isl_dim_param) > 0) {
1786                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1787                 p = isl_printer_print_str(p, " -> ");
1788         }
1789         isl_space_free(dim);
1790         p = isl_printer_print_str(p, "{ ");
1791         isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body,
1792                                                         &data);
1793         p = data.p;
1794         p = isl_printer_print_str(p, " }");
1795         return p;
1796 }
1797
1798 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial(
1799         __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
1800 {
1801         if (!p || !upwqp)
1802                 goto error;
1803
1804         if (p->output_format == ISL_FORMAT_ISL)
1805                 return print_union_pw_qpolynomial_isl(p, upwqp);
1806         isl_die(p->ctx, isl_error_invalid,
1807                 "invalid output format for isl_union_pw_qpolynomial",
1808                 goto error);
1809 error:
1810         isl_printer_free(p);
1811         return NULL;
1812 }
1813
1814 static __isl_give isl_printer *print_qpolynomial_fold_c(
1815         __isl_take isl_printer *p, __isl_keep isl_space *dim,
1816         __isl_keep isl_qpolynomial_fold *fold)
1817 {
1818         int i;
1819
1820         for (i = 0; i < fold->n - 1; ++i)
1821                 if (fold->type == isl_fold_min)
1822                         p = isl_printer_print_str(p, "min(");
1823                 else if (fold->type == isl_fold_max)
1824                         p = isl_printer_print_str(p, "max(");
1825
1826         for (i = 0; i < fold->n; ++i) {
1827                 if (i)
1828                         p = isl_printer_print_str(p, ", ");
1829                 p = print_qpolynomial_c(p, dim, fold->qp[i]);
1830                 if (i)
1831                         p = isl_printer_print_str(p, ")");
1832         }
1833         return p;
1834 }
1835
1836 __isl_give isl_printer *isl_printer_print_qpolynomial_fold(
1837         __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
1838 {
1839         if  (!p || !fold)
1840                 goto error;
1841         if (p->output_format == ISL_FORMAT_ISL)
1842                 return qpolynomial_fold_print(fold, p);
1843         else if (p->output_format == ISL_FORMAT_C)
1844                 return print_qpolynomial_fold_c(p, fold->dim, fold);
1845         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
1846                 goto error);
1847 error:
1848         isl_printer_free(p);
1849         return NULL;
1850 }
1851
1852 static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
1853         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1854 {
1855         int i;
1856
1857         if (pwf->n == 1 && isl_set_plain_is_universe(pwf->p[0].set))
1858                 return print_qpolynomial_fold_c(p, pwf->dim, pwf->p[0].fold);
1859
1860         for (i = 0; i < pwf->n; ++i) {
1861                 p = isl_printer_print_str(p, "(");
1862                 p = print_set_c(p, pwf->dim, pwf->p[i].set);
1863                 p = isl_printer_print_str(p, ") ? (");
1864                 p = print_qpolynomial_fold_c(p, pwf->dim, pwf->p[i].fold);
1865                 p = isl_printer_print_str(p, ") : ");
1866         }
1867
1868         p = isl_printer_print_str(p, "0");
1869         return p;
1870 }
1871
1872 __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
1873         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1874 {
1875         if (!p || !pwf)
1876                 goto error;
1877
1878         if (p->output_format == ISL_FORMAT_ISL)
1879                 return print_pw_qpolynomial_fold_isl(p, pwf);
1880         else if (p->output_format == ISL_FORMAT_C)
1881                 return print_pw_qpolynomial_fold_c(p, pwf);
1882         isl_assert(p->ctx, 0, goto error);
1883 error:
1884         isl_printer_free(p);
1885         return NULL;
1886 }
1887
1888 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
1889         FILE *out, unsigned output_format)
1890 {
1891         isl_printer *p;
1892
1893         if (!pwf)
1894                 return;
1895
1896         p = isl_printer_to_file(pwf->dim->ctx, out);
1897         p = isl_printer_set_output_format(p, output_format);
1898         p = isl_printer_print_pw_qpolynomial_fold(p, pwf);
1899
1900         isl_printer_free(p);
1901 }
1902
1903 static int print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf, void *user)
1904 {
1905         struct isl_union_print_data *data;
1906         data = (struct isl_union_print_data *)user;
1907
1908         if (!data->first)
1909                 data->p = isl_printer_print_str(data->p, "; ");
1910         data->first = 0;
1911
1912         data->p = isl_pwf_print_isl_body(data->p, pwf);
1913         isl_pw_qpolynomial_fold_free(pwf);
1914
1915         return 0;
1916 }
1917
1918 static __isl_give isl_printer *print_union_pw_qpolynomial_fold_isl(
1919         __isl_take isl_printer *p,
1920         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
1921 {
1922         struct isl_union_print_data data = { p, 1 };
1923         isl_space *dim;
1924         dim = isl_union_pw_qpolynomial_fold_get_space(upwf);
1925         if (isl_space_dim(dim, isl_dim_param) > 0) {
1926                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1927                 p = isl_printer_print_str(p, " -> ");
1928         }
1929         isl_space_free(dim);
1930         p = isl_printer_print_str(p, "{ ");
1931         isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf,
1932                                                         &print_pwf_body, &data);
1933         p = data.p;
1934         p = isl_printer_print_str(p, " }");
1935         return p;
1936 }
1937
1938 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold(
1939         __isl_take isl_printer *p,
1940         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
1941 {
1942         if (!p || !upwf)
1943                 goto error;
1944
1945         if (p->output_format == ISL_FORMAT_ISL)
1946                 return print_union_pw_qpolynomial_fold_isl(p, upwf);
1947         isl_die(p->ctx, isl_error_invalid,
1948                 "invalid output format for isl_union_pw_qpolynomial_fold",
1949                 goto error);
1950 error:
1951         isl_printer_free(p);
1952         return NULL;
1953 }
1954
1955 __isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p,
1956         __isl_keep isl_constraint *c)
1957 {
1958         isl_basic_map *bmap;
1959
1960         if (!p || !c)
1961                 goto error;
1962
1963         bmap = isl_basic_map_from_constraint(isl_constraint_copy(c));
1964         p = isl_printer_print_basic_map(p, bmap);
1965         isl_basic_map_free(bmap);
1966         return p;
1967 error:
1968         isl_printer_free(p);
1969         return NULL;
1970 }
1971
1972 __isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p,
1973         __isl_keep isl_space *dim)
1974 {
1975         if (!dim)
1976                 goto error;
1977
1978         if (isl_space_dim(dim, isl_dim_param) > 0) {
1979                 p = print_tuple(dim, p, isl_dim_param, 0, NULL, NULL);
1980                 p = isl_printer_print_str(p, " -> ");
1981         }
1982
1983         p = isl_printer_print_str(p, "{ ");
1984         if (isl_space_is_params(dim))
1985                 p = isl_printer_print_str(p, s_such_that[0]);
1986         else
1987                 p = print_space(dim, p, 0, 0, NULL, NULL);
1988         p = isl_printer_print_str(p, " }");
1989
1990         return p;
1991 error:
1992         isl_printer_free(p);
1993         return NULL;
1994 }
1995
1996 __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p,
1997         __isl_keep isl_local_space *ls)
1998 {
1999         unsigned total;
2000         unsigned n_div;
2001
2002         if (!ls)
2003                 goto error;
2004
2005         total = isl_local_space_dim(ls, isl_dim_all);
2006         if (isl_local_space_dim(ls, isl_dim_param) > 0) {
2007                 p = print_tuple(ls->dim, p, isl_dim_param, 0, NULL, NULL);
2008                 p = isl_printer_print_str(p, " -> ");
2009         }
2010         p = isl_printer_print_str(p, "{ ");
2011         p = print_space(ls->dim, p, 0, 0, NULL, NULL);
2012         n_div = isl_local_space_dim(ls, isl_dim_div);
2013         if (n_div > 0) {
2014                 int i;
2015                 p = isl_printer_print_str(p, " : ");
2016                 p = isl_printer_print_str(p, s_open_exists[0]);
2017                 for (i = 0; i < n_div; ++i) {
2018                         if (i)
2019                                 p = isl_printer_print_str(p, ", ");
2020                         p = print_name(ls->dim, p, isl_dim_div, i, 0);
2021                         if (isl_int_is_zero(ls->div->row[i][0]))
2022                                 continue;
2023                         p = isl_printer_print_str(p, " = [(");
2024                         p = print_affine_of_len(ls->dim, ls->div, p,
2025                                             ls->div->row[i] + 1, 1 + total);
2026                         p = isl_printer_print_str(p, ")/");
2027                         p = isl_printer_print_isl_int(p, ls->div->row[i][0]);
2028                         p = isl_printer_print_str(p, "]");
2029                 }
2030         } else if (isl_space_is_params(ls->dim))
2031                 p = isl_printer_print_str(p, s_such_that[0]);
2032         p = isl_printer_print_str(p, " }");
2033         return p;
2034 error:
2035         isl_printer_free(p);
2036         return NULL;
2037 }
2038
2039 static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p,
2040         __isl_keep isl_aff *aff)
2041 {
2042         unsigned total;
2043
2044         total = isl_local_space_dim(aff->ls, isl_dim_all);
2045         p = isl_printer_print_str(p, "(");
2046         p = print_affine_of_len(aff->ls->dim, aff->ls->div, p,
2047                                 aff->v->el + 1, 1 + total);
2048         if (isl_int_is_one(aff->v->el[0]))
2049                 p = isl_printer_print_str(p, ")");
2050         else {
2051                 p = isl_printer_print_str(p, ")/");
2052                 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2053         }
2054
2055         return p;
2056 }
2057
2058 static __isl_give isl_printer *print_aff(__isl_take isl_printer *p,
2059         __isl_keep isl_aff *aff)
2060 {
2061         if (isl_space_is_params(aff->ls->dim))
2062                 ;
2063         else {
2064                 p = print_tuple(aff->ls->dim, p, isl_dim_set, 0, NULL, NULL);
2065                 p = isl_printer_print_str(p, " -> ");
2066         }
2067         p = isl_printer_print_str(p, "[");
2068         p = print_aff_body(p, aff);
2069         p = isl_printer_print_str(p, "]");
2070
2071         return p;
2072 }
2073
2074 static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p,
2075         __isl_keep isl_aff *aff)
2076 {
2077         if (!aff)
2078                 goto error;
2079
2080         if (isl_local_space_dim(aff->ls, isl_dim_param) > 0) {
2081                 p = print_tuple(aff->ls->dim, p, isl_dim_param, 0, NULL, NULL);
2082                 p = isl_printer_print_str(p, " -> ");
2083         }
2084         p = isl_printer_print_str(p, "{ ");
2085         p = print_aff(p, aff);
2086         p = isl_printer_print_str(p, " }");
2087         return p;
2088 error:
2089         isl_printer_free(p);
2090         return NULL;
2091 }
2092
2093 static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p,
2094         __isl_keep isl_pw_aff *pwaff)
2095 {
2096         int i;
2097
2098         if (!pwaff)
2099                 goto error;
2100
2101         if (isl_space_dim(pwaff->dim, isl_dim_param) > 0) {
2102                 p = print_tuple(pwaff->dim, p, isl_dim_param, 0, NULL, NULL);
2103                 p = isl_printer_print_str(p, " -> ");
2104         }
2105         p = isl_printer_print_str(p, "{ ");
2106         for (i = 0; i < pwaff->n; ++i) {
2107                 if (i)
2108                         p = isl_printer_print_str(p, "; ");
2109                 p = print_aff(p, pwaff->p[i].aff);
2110                 p = print_disjuncts((isl_map *)pwaff->p[i].set, p, 0);
2111         }
2112         p = isl_printer_print_str(p, " }");
2113         return p;
2114 error:
2115         isl_printer_free(p);
2116         return NULL;
2117 }
2118
2119 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2120         __isl_keep isl_local_space *ls, isl_int *c);
2121
2122 static __isl_give isl_printer *print_ls_name_c(__isl_take isl_printer *p,
2123         __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos)
2124 {
2125         if (type == isl_dim_div) {
2126                 p = isl_printer_print_str(p, "floord(");
2127                 p = print_ls_affine_c(p, ls, ls->div->row[pos] + 1);
2128                 p = isl_printer_print_str(p, ", ");
2129                 p = isl_printer_print_isl_int(p, ls->div->row[pos][0]);
2130                 p = isl_printer_print_str(p, ")");
2131         } else {
2132                 const char *name;
2133
2134                 name = isl_space_get_dim_name(ls->dim, type, pos);
2135                 if (!name)
2136                         name = "UNNAMED";
2137                 p = isl_printer_print_str(p, name);
2138         }
2139         return p;
2140 }
2141
2142 static __isl_give isl_printer *print_ls_term_c(__isl_take isl_printer *p,
2143         __isl_keep isl_local_space *ls, isl_int c, unsigned pos)
2144 {
2145         enum isl_dim_type type;
2146
2147         if (pos == 0)
2148                 return isl_printer_print_isl_int(p, c);
2149
2150         if (isl_int_is_one(c))
2151                 ;
2152         else if (isl_int_is_negone(c))
2153                 p = isl_printer_print_str(p, "-");
2154         else {
2155                 p = isl_printer_print_isl_int(p, c);
2156                 p = isl_printer_print_str(p, "*");
2157         }
2158         type = pos2type(ls->dim, &pos);
2159         p = print_ls_name_c(p, ls, type, pos);
2160         return p;
2161 }
2162
2163 static __isl_give isl_printer *print_ls_partial_affine_c(
2164         __isl_take isl_printer *p, __isl_keep isl_local_space *ls,
2165         isl_int *c, unsigned len)
2166 {
2167         int i;
2168         int first;
2169
2170         for (i = 0, first = 1; i < len; ++i) {
2171                 int flip = 0;
2172                 if (isl_int_is_zero(c[i]))
2173                         continue;
2174                 if (!first) {
2175                         if (isl_int_is_neg(c[i])) {
2176                                 flip = 1;
2177                                 isl_int_neg(c[i], c[i]);
2178                                 p = isl_printer_print_str(p, " - ");
2179                         } else 
2180                                 p = isl_printer_print_str(p, " + ");
2181                 }
2182                 first = 0;
2183                 p = print_ls_term_c(p, ls, c[i], i);
2184                 if (flip)
2185                         isl_int_neg(c[i], c[i]);
2186         }
2187         if (first)
2188                 p = isl_printer_print_str(p, "0");
2189         return p;
2190 }
2191
2192 static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
2193         __isl_keep isl_local_space *ls, isl_int *c)
2194 {
2195         unsigned len = 1 + isl_local_space_dim(ls, isl_dim_all);
2196         return print_ls_partial_affine_c(p, ls, c, len);
2197 }
2198
2199 static __isl_give isl_printer *print_aff_c(__isl_take isl_printer *p,
2200         __isl_keep isl_aff *aff)
2201 {
2202         unsigned total;
2203
2204         total = isl_local_space_dim(aff->ls, isl_dim_all);
2205         if (!isl_int_is_one(aff->v->el[0]))
2206                 p = isl_printer_print_str(p, "(");
2207         p = print_ls_partial_affine_c(p, aff->ls, aff->v->el + 1, 1 + total);
2208         if (!isl_int_is_one(aff->v->el[0])) {
2209                 p = isl_printer_print_str(p, ")/");
2210                 p = isl_printer_print_isl_int(p, aff->v->el[0]);
2211         }
2212         return p;
2213 }
2214
2215 /* Print the affine expression "aff" in C format to "p".
2216  * The dimension names are taken from "space"
2217  * "set" represents the domain of the affine expression.
2218  */
2219 static __isl_give isl_printer *print_aff_on_domain_c(__isl_take isl_printer *p,
2220         __isl_keep isl_space *space, __isl_keep isl_aff *aff,
2221         __isl_keep isl_set *set)
2222 {
2223         isl_set *u;
2224         isl_ast_build *build;
2225         isl_ast_expr *expr;
2226
2227         u = isl_set_universe(isl_space_copy(space));
2228         build = isl_ast_build_from_context(u);
2229         build = isl_ast_build_restrict(build, isl_set_copy(set));
2230         expr = isl_ast_expr_from_aff(isl_aff_copy(aff), build);
2231         p = isl_printer_print_ast_expr(p, expr);
2232         isl_ast_expr_free(expr);
2233         isl_ast_build_free(build);
2234
2235         return p;
2236 }
2237
2238 /* In the C format, we cannot express that "pwaff" may be undefined
2239  * on parts of the domain space.  We therefore assume that the expression
2240  * will only be evaluated on its definition domain and compute the gist
2241  * of each cell with respect to this domain.
2242  */
2243 static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p,
2244         __isl_keep isl_pw_aff *pwaff)
2245 {
2246         int i;
2247         isl_set *domain;
2248         isl_space *space;
2249
2250         if (pwaff->n < 1)
2251                 isl_die(p->ctx, isl_error_unsupported,
2252                         "cannot print empty isl_pw_aff in C format", goto error);
2253         space = isl_pw_aff_get_domain_space(pwaff);
2254         if (!space)
2255                 goto error;
2256
2257         domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff));
2258
2259         for (i = 0; i < pwaff->n - 1; ++i) {
2260                 isl_set *set_i;
2261
2262                 p = isl_printer_print_str(p, "(");
2263
2264                 set_i = isl_set_copy(pwaff->p[i].set);
2265                 set_i = isl_set_gist(set_i, isl_set_copy(domain));
2266                 p = print_set_c(p, space, set_i);
2267                 isl_set_free(set_i);
2268
2269                 p = isl_printer_print_str(p, ") ? (");
2270                 p = print_aff_on_domain_c(p, space,
2271                                         pwaff->p[i].aff, pwaff->p[i].set);
2272                 p = isl_printer_print_str(p, ") : ");
2273         }
2274
2275         isl_set_free(domain);
2276
2277         p = print_aff_on_domain_c(p, space, pwaff->p[pwaff->n - 1].aff,
2278                                         pwaff->p[pwaff->n - 1].set);
2279         isl_space_free(space);
2280         return p;
2281 error:
2282         isl_printer_free(p);
2283         return NULL;
2284 }
2285
2286 __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p,
2287         __isl_keep isl_aff *aff)
2288 {
2289         if (!p || !aff)
2290                 goto error;
2291
2292         if (p->output_format == ISL_FORMAT_ISL)
2293                 return print_aff_isl(p, aff);
2294         else if (p->output_format == ISL_FORMAT_C)
2295                 return print_aff_c(p, aff);
2296         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2297                 goto error);
2298 error:
2299         isl_printer_free(p);
2300         return NULL;
2301 }
2302
2303 __isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p,
2304         __isl_keep isl_pw_aff *pwaff)
2305 {
2306         if (!p || !pwaff)
2307                 goto error;
2308
2309         if (p->output_format == ISL_FORMAT_ISL)
2310                 return print_pw_aff_isl(p, pwaff);
2311         else if (p->output_format == ISL_FORMAT_C)
2312                 return print_pw_aff_c(p, pwaff);
2313         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2314                 goto error);
2315 error:
2316         isl_printer_free(p);
2317         return NULL;
2318 }
2319
2320 static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p,
2321         __isl_keep isl_multi_aff *maff)
2322 {
2323         return print_space(maff->space, p, 0, 0, NULL, maff);
2324 }
2325
2326 static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p,
2327         __isl_keep isl_multi_aff *maff)
2328 {
2329         if (!maff)
2330                 goto error;
2331
2332         if (isl_space_dim(maff->space, isl_dim_param) > 0) {
2333                 p = print_tuple(maff->space, p, isl_dim_param, 0, NULL, NULL);
2334                 p = isl_printer_print_str(p, " -> ");
2335         }
2336         p = isl_printer_print_str(p, "{ ");
2337         p = print_multi_aff(p, maff);
2338         p = isl_printer_print_str(p, " }");
2339         return p;
2340 error:
2341         isl_printer_free(p);
2342         return NULL;
2343 }
2344
2345 __isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p,
2346         __isl_keep isl_multi_aff *maff)
2347 {
2348         if (!p || !maff)
2349                 goto error;
2350
2351         if (p->output_format == ISL_FORMAT_ISL)
2352                 return print_multi_aff_isl(p, maff);
2353         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2354                 goto error);
2355 error:
2356         isl_printer_free(p);
2357         return NULL;
2358 }
2359
2360 static __isl_give isl_printer *print_pw_multi_aff_body(
2361         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2362 {
2363         int i;
2364
2365         if (!pma)
2366                 goto error;
2367
2368         for (i = 0; i < pma->n; ++i) {
2369                 if (i)
2370                         p = isl_printer_print_str(p, "; ");
2371                 p = print_multi_aff(p, pma->p[i].maff);
2372                 p = print_disjuncts((isl_map *)pma->p[i].set, p, 0);
2373         }
2374         return p;
2375 error:
2376         isl_printer_free(p);
2377         return NULL;
2378 }
2379
2380 static __isl_give isl_printer *print_pw_multi_aff_isl(__isl_take isl_printer *p,
2381         __isl_keep isl_pw_multi_aff *pma)
2382 {
2383         if (!pma)
2384                 goto error;
2385
2386         if (isl_space_dim(pma->dim, isl_dim_param) > 0) {
2387                 p = print_tuple(pma->dim, p, isl_dim_param, 0, NULL, NULL);
2388                 p = isl_printer_print_str(p, " -> ");
2389         }
2390         p = isl_printer_print_str(p, "{ ");
2391         p = print_pw_multi_aff_body(p, pma);
2392         p = isl_printer_print_str(p, " }");
2393         return p;
2394 error:
2395         isl_printer_free(p);
2396         return NULL;
2397 }
2398
2399 static __isl_give isl_printer *print_unnamed_pw_multi_aff_c(
2400         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2401 {
2402         int i;
2403
2404         for (i = 0; i < pma->n - 1; ++i) {
2405                 p = isl_printer_print_str(p, "(");
2406                 p = print_set_c(p, pma->dim, pma->p[i].set);
2407                 p = isl_printer_print_str(p, ") ? (");
2408                 p = print_aff_c(p, pma->p[i].maff->p[0]);
2409                 p = isl_printer_print_str(p, ") : ");
2410         }
2411
2412         return print_aff_c(p, pma->p[pma->n - 1].maff->p[0]);
2413 }
2414
2415 static __isl_give isl_printer *print_pw_multi_aff_c(__isl_take isl_printer *p,
2416         __isl_keep isl_pw_multi_aff *pma)
2417 {
2418         int n;
2419         const char *name;
2420
2421         if (!pma)
2422                 goto error;
2423         if (pma->n < 1)
2424                 isl_die(p->ctx, isl_error_unsupported,
2425                         "cannot print empty isl_pw_multi_aff in C format",
2426                         goto error);
2427         name = isl_pw_multi_aff_get_tuple_name(pma, isl_dim_out);
2428         if (!name && isl_pw_multi_aff_dim(pma, isl_dim_out) == 1)
2429                 return print_unnamed_pw_multi_aff_c(p, pma);
2430         if (!name)
2431                 isl_die(p->ctx, isl_error_unsupported,
2432                         "cannot print unnamed isl_pw_multi_aff in C format",
2433                         goto error);
2434
2435         p = isl_printer_print_str(p, name);
2436         n = isl_pw_multi_aff_dim(pma, isl_dim_out);
2437         if (n != 0)
2438                 isl_die(p->ctx, isl_error_unsupported,
2439                         "not supported yet", goto error);
2440
2441         return p;
2442 error:
2443         isl_printer_free(p);
2444         return NULL;
2445 }
2446
2447 __isl_give isl_printer *isl_printer_print_pw_multi_aff(
2448         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
2449 {
2450         if (!p || !pma)
2451                 goto error;
2452
2453         if (p->output_format == ISL_FORMAT_ISL)
2454                 return print_pw_multi_aff_isl(p, pma);
2455         if (p->output_format == ISL_FORMAT_C)
2456                 return print_pw_multi_aff_c(p, pma);
2457         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2458                 goto error);
2459 error:
2460         isl_printer_free(p);
2461         return NULL;
2462 }
2463
2464 static int print_pw_multi_aff_body_wrap(__isl_take isl_pw_multi_aff *pma,
2465         void *user)
2466 {
2467         struct isl_union_print_data *data;
2468         data = (struct isl_union_print_data *) user;
2469
2470         if (!data->first)
2471                 data->p = isl_printer_print_str(data->p, "; ");
2472         data->first = 0;
2473
2474         data->p = print_pw_multi_aff_body(data->p, pma);
2475         isl_pw_multi_aff_free(pma);
2476
2477         return 0;
2478 }
2479
2480 static __isl_give isl_printer *print_union_pw_multi_aff_isl(
2481         __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
2482 {
2483         struct isl_union_print_data data = { p, 1 };
2484         isl_space *space;
2485
2486         space = isl_union_pw_multi_aff_get_space(upma);
2487         if (isl_space_dim(space, isl_dim_param) > 0) {
2488                 p = print_tuple(space, p, isl_dim_param, 0, NULL, NULL);
2489                 p = isl_printer_print_str(p, s_to[0]);
2490         }
2491         isl_space_free(space);
2492         p = isl_printer_print_str(p, s_open_set[0]);
2493         isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
2494                                         &print_pw_multi_aff_body_wrap, &data);
2495         p = data.p;
2496         p = isl_printer_print_str(p, s_close_set[0]);
2497         return p;
2498 }
2499
2500 __isl_give isl_printer *isl_printer_print_union_pw_multi_aff(
2501         __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
2502 {
2503         if (!p || !upma)
2504                 goto error;
2505
2506         if (p->output_format == ISL_FORMAT_ISL)
2507                 return print_union_pw_multi_aff_isl(p, upma);
2508         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2509                 goto error);
2510 error:
2511         isl_printer_free(p);
2512         return NULL;
2513 }
2514
2515 static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p,
2516         __isl_keep isl_multi_pw_aff *mpa)
2517 {
2518         int i;
2519
2520         if (!mpa)
2521                 return isl_printer_free(p);
2522
2523         p = isl_printer_print_str(p, "(");
2524         for (i = 0; i < mpa->n; ++i) {
2525                 if (i)
2526                         p = isl_printer_print_str(p, ",");
2527                 p = isl_printer_print_pw_aff(p, mpa->p[i]);
2528         }
2529         p = isl_printer_print_str(p, ")");
2530         return p;
2531 }
2532
2533 __isl_give isl_printer *isl_printer_print_multi_pw_aff(
2534         __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa)
2535 {
2536         if (!p || !mpa)
2537                 return isl_printer_free(p);
2538
2539         if (p->output_format == ISL_FORMAT_ISL)
2540                 return print_multi_pw_aff_isl(p, mpa);
2541         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
2542                 return isl_printer_free(p));
2543 }