isl_printer_print_basic_map: plug memory leak on error path
[platform/upstream/isl.git] / isl_output.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  * Copyright 2010      INRIA Saclay
4  *
5  * Use of this software is governed by the GNU LGPLv2.1 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/set.h>
16 #include <isl/seq.h>
17 #include <isl_polynomial_private.h>
18 #include <isl_printer_private.h>
19 #include <isl_dim_private.h>
20 #include <isl_map_private.h>
21 #include <isl_mat_private.h>
22 #include <isl/union_map.h>
23
24 static const char *s_to[2] = { " -> ", " \\to " };
25 static const char *s_and[2] = { " and ", " \\wedge " };
26 static const char *s_or[2] = { " or ", " \\vee " };
27 static const char *s_le[2] = { "<=", "\\le" };
28 static const char *s_ge[2] = { ">=", "\\ge" };
29 static const char *s_open_set[2] = { "{ ", "\\{\\, " };
30 static const char *s_close_set[2] = { " }", " \\,\\}" };
31 static const char *s_open_list[2] = { "[", "(" };
32 static const char *s_close_list[2] = { "]", ")" };
33 static const char *s_such_that[2] = { " : ", " \\mid " };
34 static const char *s_open_exists[2] = { "exists (", "\\exists \\, " };
35 static const char *s_close_exists[2] = { ")", "" };
36 static const char *s_div_prefix[2] = { "e", "\\alpha_" };
37 static const char *s_param_prefix[2] = { "p", "p_" };
38 static const char *s_input_prefix[2] = { "i", "i_" };
39 static const char *s_output_prefix[2] = { "o", "o_" };
40
41 static __isl_give isl_printer *print_constraint_polylib(
42         struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p)
43 {
44         int i;
45         unsigned n_in = isl_basic_map_dim(bmap, isl_dim_in);
46         unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
47         unsigned nparam = isl_basic_map_dim(bmap, isl_dim_param);
48         isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n];
49
50         p = isl_printer_start_line(p);
51         p = isl_printer_print_int(p, ineq);
52         for (i = 0; i < n_out; ++i) {
53                 p = isl_printer_print_str(p, " ");
54                 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]);
55         }
56         for (i = 0; i < n_in; ++i) {
57                 p = isl_printer_print_str(p, " ");
58                 p = isl_printer_print_isl_int(p, c[1+nparam+i]);
59         }
60         for (i = 0; i < bmap->n_div; ++i) {
61                 p = isl_printer_print_str(p, " ");
62                 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]);
63         }
64         for (i = 0; i < nparam; ++i) {
65                 p = isl_printer_print_str(p, " ");
66                 p = isl_printer_print_isl_int(p, c[1+i]);
67         }
68         p = isl_printer_print_str(p, " ");
69         p = isl_printer_print_isl_int(p, c[0]);
70         p = isl_printer_end_line(p);
71         return p;
72 }
73
74 static __isl_give isl_printer *print_constraints_polylib(
75         struct isl_basic_map *bmap, __isl_take isl_printer *p)
76 {
77         int i;
78
79         p = isl_printer_set_isl_int_width(p, 5);
80
81         for (i = 0; i < bmap->n_eq; ++i)
82                 p = print_constraint_polylib(bmap, 0, i, p);
83         for (i = 0; i < bmap->n_ineq; ++i)
84                 p = print_constraint_polylib(bmap, 1, i, p);
85
86         return p;
87 }
88
89 static __isl_give isl_printer *bset_print_constraints_polylib(
90         struct isl_basic_set *bset, __isl_take isl_printer *p)
91 {
92         return print_constraints_polylib((struct isl_basic_map *)bset, p);
93 }
94
95 static __isl_give isl_printer *isl_basic_map_print_polylib(
96         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int ext)
97 {
98         unsigned total = isl_basic_map_total_dim(bmap);
99         p = isl_printer_start_line(p);
100         p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq);
101         p = isl_printer_print_str(p, " ");
102         p = isl_printer_print_int(p, 1 + total + 1);
103         if (ext) {
104                 p = isl_printer_print_str(p, " ");
105                 p = isl_printer_print_int(p,
106                                     isl_basic_map_dim(bmap, isl_dim_out));
107                 p = isl_printer_print_str(p, " ");
108                 p = isl_printer_print_int(p,
109                                     isl_basic_map_dim(bmap, isl_dim_in));
110                 p = isl_printer_print_str(p, " ");
111                 p = isl_printer_print_int(p,
112                                     isl_basic_map_dim(bmap, isl_dim_div));
113                 p = isl_printer_print_str(p, " ");
114                 p = isl_printer_print_int(p,
115                                     isl_basic_map_dim(bmap, isl_dim_param));
116         }
117         p = isl_printer_end_line(p);
118         return print_constraints_polylib(bmap, p);
119 }
120
121 static __isl_give isl_printer *isl_basic_set_print_polylib(
122         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int ext)
123 {
124         return isl_basic_map_print_polylib((struct isl_basic_map *)bset, p, ext);
125 }
126
127 static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map,
128         __isl_take isl_printer *p, int ext)
129 {
130         int i;
131
132         p = isl_printer_start_line(p);
133         p = isl_printer_print_int(p, map->n);
134         p = isl_printer_end_line(p);
135         for (i = 0; i < map->n; ++i) {
136                 p = isl_printer_start_line(p);
137                 p = isl_printer_end_line(p);
138                 p = isl_basic_map_print_polylib(map->p[i], p, ext);
139         }
140         return p;
141 }
142
143 static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set,
144         __isl_take isl_printer *p, int ext)
145 {
146         return isl_map_print_polylib((struct isl_map *)set, p, ext);
147 }
148
149 static int count_same_name(__isl_keep isl_dim *dim,
150         enum isl_dim_type type, unsigned pos, const char *name)
151 {
152         enum isl_dim_type t;
153         unsigned p, s;
154         int count = 0;
155
156         for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) {
157                 s = t == type ? pos : isl_dim_size(dim, t);
158                 for (p = 0; p < s; ++p) {
159                         const char *n = isl_dim_get_name(dim, t, p);
160                         if (n && !strcmp(n, name))
161                                 count++;
162                 }
163         }
164         return count;
165 }
166
167 static __isl_give isl_printer *print_name(__isl_keep isl_dim *dim,
168         __isl_take isl_printer *p, enum isl_dim_type type, unsigned pos,
169         int set, int latex)
170 {
171         const char *name;
172         char buffer[20];
173         int primes;
174
175         name = type == isl_dim_div ? NULL : isl_dim_get_name(dim, type, pos);
176
177         if (!name) {
178                 const char *prefix;
179                 if (type == isl_dim_param)
180                         prefix = s_param_prefix[latex];
181                 else if (type == isl_dim_div)
182                         prefix = s_div_prefix[latex];
183                 else if (set || type == isl_dim_in)
184                         prefix = s_input_prefix[latex];
185                 else
186                         prefix = s_output_prefix[latex];
187                 snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);
188                 name = buffer;
189         }
190         primes = count_same_name(dim, name == buffer ? isl_dim_div : type,
191                                  pos, name);
192         p = isl_printer_print_str(p, name);
193         while (primes-- > 0)
194                 p = isl_printer_print_str(p, "'");
195         return p;
196 }
197
198 static enum isl_dim_type pos2type(__isl_keep isl_dim *dim, unsigned *pos)
199 {
200         enum isl_dim_type type;
201         unsigned n_in = isl_dim_size(dim, isl_dim_in);
202         unsigned n_out = isl_dim_size(dim, isl_dim_out);
203         unsigned nparam = isl_dim_size(dim, isl_dim_param);
204
205         if (*pos < 1 + nparam) {
206                 type = isl_dim_param;
207                 *pos -= 1;
208         } else if (*pos < 1 + nparam + n_in) {
209                 type = isl_dim_in;
210                 *pos -= 1 + nparam;
211         } else if (*pos < 1 + nparam + n_in + n_out) {
212                 type = isl_dim_out;
213                 *pos -= 1 + nparam + n_in;
214         } else {
215                 type = isl_dim_div;
216                 *pos -= 1 + nparam + n_in + n_out;
217         }
218
219         return type;
220 }
221
222 static __isl_give isl_printer *print_div(__isl_keep isl_dim *dim,
223         __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p);
224
225 static __isl_give isl_printer *print_term(__isl_keep isl_dim *dim,
226         __isl_keep isl_mat *div,
227         isl_int c, unsigned pos, __isl_take isl_printer *p, int set, int latex)
228 {
229         enum isl_dim_type type;
230         int print_div_def;
231
232         if (pos == 0)
233                 return isl_printer_print_isl_int(p, c);
234
235         type = pos2type(dim, &pos);
236         print_div_def = type == isl_dim_div && div &&
237                         !isl_int_is_zero(div->row[pos][0]);
238
239         if (isl_int_is_one(c))
240                 ;
241         else if (isl_int_is_negone(c))
242                 p = isl_printer_print_str(p, "-");
243         else {
244                 p = isl_printer_print_isl_int(p, c);
245                 if (p->output_format == ISL_FORMAT_C || print_div_def)
246                         p = isl_printer_print_str(p, "*");
247         }
248         if (print_div_def)
249                 p = print_div(dim, div, pos, p);
250         else
251                 p = print_name(dim, p, type, pos, set, latex);
252         return p;
253 }
254
255 static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_dim *dim,
256         __isl_keep isl_mat *div,
257         __isl_take isl_printer *p, isl_int *c, int len, int set)
258 {
259         int i;
260         int first;
261
262         for (i = 0, first = 1; i < len; ++i) {
263                 int flip = 0;
264                 if (isl_int_is_zero(c[i]))
265                         continue;
266                 if (!first) {
267                         if (isl_int_is_neg(c[i])) {
268                                 flip = 1;
269                                 isl_int_neg(c[i], c[i]);
270                                 p = isl_printer_print_str(p, " - ");
271                         } else 
272                                 p = isl_printer_print_str(p, " + ");
273                 }
274                 first = 0;
275                 p = print_term(dim, div, c[i], i, p, set, 0);
276                 if (flip)
277                         isl_int_neg(c[i], c[i]);
278         }
279         if (first)
280                 p = isl_printer_print_str(p, "0");
281         return p;
282 }
283
284 static __isl_give isl_printer *print_affine(__isl_keep isl_basic_map *bmap,
285         __isl_keep isl_dim *dim, __isl_take isl_printer *p, isl_int *c, int set)
286 {
287         unsigned len = 1 + isl_basic_map_total_dim(bmap);
288         return print_affine_of_len(dim, NULL, p, c, len, set);
289 }
290
291 static int defining_equality(__isl_keep isl_basic_map *eq,
292         __isl_keep isl_dim *dim, enum isl_dim_type type, int pos)
293 {
294         int i;
295         unsigned total;
296
297         if (!eq)
298                 return -1;
299
300         pos += isl_dim_offset(dim, type);
301         total = isl_basic_map_total_dim(eq);
302
303         for (i = 0; i < eq->n_eq; ++i) {
304                 if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos)
305                         continue;
306                 if (isl_int_is_one(eq->eq[i][1 + pos]))
307                         isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total);
308                 return i;
309         }
310
311         return -1;
312 }
313
314 /* offset is the offset of local_dim inside global_type of global_dim.
315  */
316 static __isl_give isl_printer *print_nested_var_list(__isl_take isl_printer *p,
317         __isl_keep isl_dim *global_dim, enum isl_dim_type global_type,
318         __isl_keep isl_dim *local_dim, enum isl_dim_type local_type,
319         int set, int latex, __isl_keep isl_basic_map *eq, int offset)
320 {
321         int i, j;
322
323         if (global_dim != local_dim && local_type == isl_dim_out)
324                 offset += local_dim->n_in;
325
326         for (i = 0; i < isl_dim_size(local_dim, local_type); ++i) {
327                 if (i)
328                         p = isl_printer_print_str(p, ", ");
329                 j = defining_equality(eq, global_dim, global_type, offset + i);
330                 if (j >= 0) {
331                         int pos = 1 + isl_dim_offset(global_dim, global_type)
332                                     + offset + i;
333                         p = print_affine_of_len(eq->dim, NULL,
334                                                 p, eq->eq[j], pos, set);
335                 } else {
336                         p = print_name(global_dim, p, global_type, offset + i,
337                                         set, latex);
338                 }
339         }
340         return p;
341 }
342
343 static __isl_give isl_printer *print_var_list(__isl_keep isl_dim *dim,
344         __isl_take isl_printer *p, enum isl_dim_type type,
345         int set, int latex, __isl_keep isl_basic_map *eq)
346 {
347         return print_nested_var_list(p, dim, type, dim, type, set, latex, eq, 0);
348 }
349
350 static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
351         __isl_keep isl_dim *global_dim, enum isl_dim_type global_type,
352         __isl_keep isl_dim *local_dim,
353          int set, int latex, __isl_keep isl_basic_map *eq, int offset);
354
355 static __isl_give isl_printer *print_nested_tuple(__isl_take isl_printer *p,
356         __isl_keep isl_dim *global_dim, enum isl_dim_type global_type,
357         __isl_keep isl_dim *local_dim, enum isl_dim_type local_type,
358         int set, int latex, __isl_keep isl_basic_map *eq, int offset)
359 {
360         const char *name = NULL;
361         unsigned n = isl_dim_size(local_dim, local_type);
362         if ((local_type == isl_dim_in || local_type == isl_dim_out)) {
363                 name = isl_dim_get_tuple_name(local_dim, local_type);
364                 if (name) {
365                         if (latex)
366                                 p = isl_printer_print_str(p, "\\mathrm{");
367                         p = isl_printer_print_str(p, name);
368                         if (latex)
369                                 p = isl_printer_print_str(p, "}");
370                 }
371         }
372         if (!latex || n != 1 || name)
373                 p = isl_printer_print_str(p, s_open_list[latex]);
374         if ((local_type == isl_dim_in || local_type == isl_dim_out) &&
375             local_dim->nested[local_type - isl_dim_in]) {
376                 if (global_dim != local_dim && local_type == isl_dim_out)
377                         offset += local_dim->n_in;
378                 p = print_nested_map_dim(p, global_dim, global_type,
379                                 local_dim->nested[local_type - isl_dim_in],
380                                 set, latex, eq, offset);
381         } else
382                 p = print_nested_var_list(p, global_dim, global_type,
383                                  local_dim, local_type, set, latex, eq, offset);
384         if (!latex || n != 1 || name)
385                 p = isl_printer_print_str(p, s_close_list[latex]);
386         return p;
387 }
388
389 static __isl_give isl_printer *print_tuple(__isl_keep isl_dim *dim,
390         __isl_take isl_printer *p, enum isl_dim_type type,
391         int set, int latex, __isl_keep isl_basic_map *eq)
392 {
393         return print_nested_tuple(p, dim, type, dim, type, set, latex, eq, 0);
394 }
395
396 static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
397         __isl_keep isl_dim *global_dim, enum isl_dim_type global_type,
398         __isl_keep isl_dim *local_dim,
399          int set, int latex, __isl_keep isl_basic_map *eq, int offset)
400 {
401         p = print_nested_tuple(p, global_dim, global_type,
402                         local_dim, isl_dim_in, set, latex, eq, offset);
403         p = isl_printer_print_str(p, s_to[latex]);
404         p = print_nested_tuple(p, global_dim, global_type,
405                         local_dim, isl_dim_out, set, latex, eq, offset);
406
407         return p;
408 }
409
410 static __isl_give isl_printer *print_dim(__isl_keep isl_dim *dim,
411         __isl_take isl_printer *p, int set, int latex,
412         __isl_keep isl_basic_map *eq)
413 {
414         if (set)
415                 p = print_tuple(dim, p, isl_dim_set, 1, latex, eq);
416         else {
417                 p = print_tuple(dim, p, isl_dim_in, 0, latex, eq);
418                 p = isl_printer_print_str(p, s_to[latex]);
419                 p = print_tuple(dim, p, isl_dim_out, 0, latex, eq);
420         }
421
422         return p;
423 }
424
425 static __isl_give isl_printer *print_omega_parameters(__isl_keep isl_dim *dim,
426         __isl_take isl_printer *p)
427 {
428         if (isl_dim_size(dim, isl_dim_param) == 0)
429                 return p;
430
431         p = isl_printer_start_line(p);
432         p = isl_printer_print_str(p, "symbolic ");
433         p = print_var_list(dim, p, isl_dim_param, 0, 0, NULL);
434         p = isl_printer_print_str(p, ";");
435         p = isl_printer_end_line(p);
436         return p;
437 }
438
439 static __isl_give isl_printer *print_constraint(struct isl_basic_map *bmap,
440         __isl_keep isl_dim *dim, __isl_take isl_printer *p,
441         isl_int *c, int last, const char *op, int first_constraint, int set,
442         int latex)
443 {
444         if (!first_constraint)
445                 p = isl_printer_print_str(p, s_and[latex]);
446
447         isl_int_abs(c[last], c[last]);
448
449         p = print_term(dim, NULL, c[last], last, p, set, latex);
450
451         p = isl_printer_print_str(p, " ");
452         p = isl_printer_print_str(p, op);
453         p = isl_printer_print_str(p, " ");
454
455         isl_int_set_si(c[last], 0);
456         p = print_affine(bmap, dim, p, c, set);
457
458         return p;
459 }
460
461 static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
462         __isl_keep isl_dim *dim, __isl_take isl_printer *p, int set, int latex)
463 {
464         int i;
465         struct isl_vec *c;
466         unsigned total = isl_basic_map_total_dim(bmap);
467
468         c = isl_vec_alloc(bmap->ctx, 1 + total);
469         if (!c)
470                 goto error;
471
472         for (i = bmap->n_eq - 1; i >= 0; --i) {
473                 int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total);
474                 isl_assert(bmap->ctx, l >= 0, goto error);
475                 if (isl_int_is_neg(bmap->eq[i][l]))
476                         isl_seq_cpy(c->el, bmap->eq[i], 1 + total);
477                 else
478                         isl_seq_neg(c->el, bmap->eq[i], 1 + total);
479                 p = print_constraint(bmap, dim, p, c->el, l,
480                                     "=", i == bmap->n_eq - 1, set, latex);
481         }
482         for (i = 0; i < bmap->n_ineq; ++i) {
483                 int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);
484                 int s;
485                 const char *op;
486                 if (l < 0)
487                         continue;
488                 s = isl_int_sgn(bmap->ineq[i][l]);
489                 if (s < 0)
490                         isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);
491                 else
492                         isl_seq_neg(c->el, bmap->ineq[i], 1 + total);
493                 op = s < 0 ? s_le[latex] : s_ge[latex];
494                 p = print_constraint(bmap, dim, p, c->el, l,
495                                         op, !bmap->n_eq && !i, set, latex);
496         }
497
498         isl_vec_free(c);
499
500         return p;
501 error:
502         isl_vec_free(c);
503         isl_printer_free(p);
504         return NULL;
505 }
506
507 static __isl_give isl_printer *print_omega_constraints(
508         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int set)
509 {
510         if (bmap->n_eq + bmap->n_ineq == 0)
511                 return p;
512
513         p = isl_printer_print_str(p, ": ");
514         if (bmap->n_div > 0) {
515                 int i;
516                 p = isl_printer_print_str(p, "exists (");
517                 for (i = 0; i < bmap->n_div; ++i) {
518                         if (i)
519                                 p = isl_printer_print_str(p, ", ");
520                         p = print_name(bmap->dim, p, isl_dim_div, i, 0, 0);
521                 }
522                 p = isl_printer_print_str(p, ": ");
523         }
524         p = print_constraints(bmap, bmap->dim, p, set, 0);
525         if (bmap->n_div > 0)
526                 p = isl_printer_print_str(p, ")");
527         return p;
528 }
529
530 static __isl_give isl_printer *basic_map_print_omega(
531         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
532 {
533         p = isl_printer_print_str(p, "{ [");
534         p = print_var_list(bmap->dim, p, isl_dim_in, 0, 0, NULL);
535         p = isl_printer_print_str(p, "] -> [");
536         p = print_var_list(bmap->dim, p, isl_dim_out, 0, 0, NULL);
537         p = isl_printer_print_str(p, "] ");
538         p = print_omega_constraints(bmap, p, 0);
539         p = isl_printer_print_str(p, " }");
540         return p;
541 }
542
543 static __isl_give isl_printer *isl_basic_map_print_omega(
544         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
545 {
546         p = print_omega_parameters(bmap->dim, p);
547
548         p = isl_printer_start_line(p);
549         p = basic_map_print_omega(bmap, p);
550         p = isl_printer_end_line(p);
551         return p;
552 }
553
554 static __isl_give isl_printer *basic_set_print_omega(
555         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
556 {
557         p = isl_printer_print_str(p, "{ [");
558         p = print_var_list(bset->dim, p, isl_dim_set, 1, 0, NULL);
559         p = isl_printer_print_str(p, "] ");
560         p = print_omega_constraints((isl_basic_map *)bset, p, 1);
561         p = isl_printer_print_str(p, " }");
562         return p;
563 }
564
565 static __isl_give isl_printer *isl_basic_set_print_omega(
566         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
567 {
568         p = print_omega_parameters(bset->dim, p);
569
570         p = isl_printer_start_line(p);
571         p = basic_set_print_omega(bset, p);
572         p = isl_printer_end_line(p);
573         return p;
574 }
575
576 static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map,
577         __isl_take isl_printer *p)
578 {
579         int i;
580
581         p = print_omega_parameters(map->dim, p);
582
583         p = isl_printer_start_line(p);
584         for (i = 0; i < map->n; ++i) {
585                 if (i)
586                         p = isl_printer_print_str(p, " union ");
587                 p = basic_map_print_omega(map->p[i], p);
588         }
589         p = isl_printer_end_line(p);
590         return p;
591 }
592
593 static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set,
594         __isl_take isl_printer *p)
595 {
596         int i;
597
598         p = print_omega_parameters(set->dim, p);
599
600         p = isl_printer_start_line(p);
601         for (i = 0; i < set->n; ++i) {
602                 if (i)
603                         p = isl_printer_print_str(p, " union ");
604                 p = basic_set_print_omega(set->p[i], p);
605         }
606         p = isl_printer_end_line(p);
607         return p;
608 }
609
610 static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
611         __isl_keep isl_dim *dim, __isl_take isl_printer *p, int set, int latex)
612 {
613         if (bmap->n_div > 0) {
614                 int i;
615                 p = isl_printer_print_str(p, s_open_exists[latex]);
616                 for (i = 0; i < bmap->n_div; ++i) {
617                         if (i)
618                                 p = isl_printer_print_str(p, ", ");
619                         p = print_name(dim, p, isl_dim_div, i, 0, latex);
620                         if (latex || isl_int_is_zero(bmap->div[i][0]))
621                                 continue;
622                         p = isl_printer_print_str(p, " = [(");
623                         p = print_affine(bmap, dim, p, bmap->div[i] + 1, set);
624                         p = isl_printer_print_str(p, ")/");
625                         p = isl_printer_print_isl_int(p, bmap->div[i][0]);
626                         p = isl_printer_print_str(p, "]");
627                 }
628                 p = isl_printer_print_str(p, ": ");
629         }
630
631         p = print_constraints(bmap, dim, p, set, latex);
632
633         if (bmap->n_div > 0)
634                 p = isl_printer_print_str(p, s_close_exists[latex]);
635         return p;
636 }
637
638 static __isl_give isl_printer *isl_basic_map_print_isl(
639         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int latex)
640 {
641         int i;
642
643         p = isl_printer_start_line(p);
644         if (isl_basic_map_dim(bmap, isl_dim_param) > 0) {
645                 p = print_tuple(bmap->dim, p, isl_dim_param, 0, latex, NULL);
646                 p = isl_printer_print_str(p, " -> ");
647         }
648         p = isl_printer_print_str(p, "{ ");
649         p = print_dim(bmap->dim, p, 0, latex, NULL);
650         p = isl_printer_print_str(p, " : ");
651         p = print_disjunct(bmap, bmap->dim, p, 0, latex);
652         p = isl_printer_print_str(p, " }");
653         p = isl_printer_end_line(p);
654         return p;
655 }
656
657 static __isl_give isl_printer *isl_basic_set_print_isl(
658         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int latex)
659 {
660         int i;
661
662         p = isl_printer_start_line(p);
663         if (isl_basic_set_dim(bset, isl_dim_param) > 0) {
664                 p = print_tuple(bset->dim, p, isl_dim_param, 0, latex, NULL);
665                 p = isl_printer_print_str(p, " -> ");
666         }
667         p = isl_printer_print_str(p, "{ ");
668         p = print_dim(bset->dim, p, 1, latex, NULL);
669         p = isl_printer_print_str(p, " : ");
670         p = print_disjunct((isl_basic_map *)bset, bset->dim, p, 1, latex);
671         p = isl_printer_print_str(p, " }");
672         p = isl_printer_end_line(p);
673         return p;
674 }
675
676 static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
677         __isl_take isl_printer *p, int set, int latex)
678 {
679         int i;
680
681         if (isl_map_fast_is_universe(map))
682                 return p;
683
684         p = isl_printer_print_str(p, s_such_that[latex]);
685         if (map->n == 0)
686                 p = isl_printer_print_str(p, "1 = 0");
687         for (i = 0; i < map->n; ++i) {
688                 if (i)
689                         p = isl_printer_print_str(p, s_or[latex]);
690                 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
691                         p = isl_printer_print_str(p, "(");
692                 p = print_disjunct(map->p[i], map->dim, p, set, latex);
693                 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
694                         p = isl_printer_print_str(p, ")");
695         }
696         return p;
697 }
698
699 struct isl_aff_split {
700         isl_basic_map *aff;
701         isl_map *map;
702 };
703
704 static void free_split(__isl_take struct isl_aff_split *split, int n)
705 {
706         int i;
707
708         if (!split)
709                 return;
710
711         for (i = 0; i < n; ++i) {
712                 isl_basic_map_free(split[i].aff);
713                 isl_map_free(split[i].map);
714         }
715
716         free(split);
717 }
718
719 static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap)
720 {
721         int i, j;
722         unsigned nparam, n_in, n_out, total;
723
724         bmap = isl_basic_map_cow(bmap);
725         if (!bmap)
726                 return NULL;
727         if (isl_basic_map_free_inequality(bmap, bmap->n_ineq) < 0)
728                 goto error;
729
730         nparam = isl_basic_map_dim(bmap, isl_dim_param);
731         n_in = isl_basic_map_dim(bmap, isl_dim_in);
732         n_out = isl_basic_map_dim(bmap, isl_dim_out);
733         total = isl_basic_map_dim(bmap, isl_dim_all);
734         for (i = bmap->n_eq - 1; i >= 0; --i) {
735                 j = isl_seq_last_non_zero(bmap->eq[i] + 1, total);
736                 if (j >= nparam && j < nparam + n_in + n_out &&
737                     (isl_int_is_one(bmap->eq[i][1 + j]) ||
738                      isl_int_is_negone(bmap->eq[i][1 + j])))
739                         continue;
740                 if (isl_basic_map_drop_equality(bmap, i) < 0)
741                         goto error;
742         }
743
744         bmap = isl_basic_map_finalize(bmap);
745
746         return bmap;
747 error:
748         isl_basic_map_free(bmap);
749         return NULL;
750 }
751
752 static int aff_split_cmp(const void *p1, const void *p2)
753 {
754         const struct isl_aff_split *s1, *s2;
755         s1 = (const struct isl_aff_split *) p1;
756         s2 = (const struct isl_aff_split *) p2;
757
758         return isl_basic_map_fast_cmp(s1->aff, s2->aff);
759 }
760
761 static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap,
762         __isl_keep isl_basic_map *aff)
763 {
764         int i, j;
765         unsigned total;
766
767         if (!bmap || !aff)
768                 goto error;
769
770         total = isl_dim_total(bmap->dim);
771
772         for (i = bmap->n_eq - 1; i >= 0; --i) {
773                 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + total,
774                                             bmap->n_div) != -1)
775                         continue;
776                 for (j = 0; j < aff->n_eq; ++j) {
777                         if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + total) &&
778                             !isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + total))
779                                 continue;
780                         if (isl_basic_map_drop_equality(bmap, i) < 0)
781                                 goto error;
782                         break;
783                 }
784         }
785
786         return bmap;
787 error:
788         isl_basic_map_free(bmap);
789         return NULL;
790 }
791
792 static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map)
793 {
794         int i, n;
795         struct isl_aff_split *split;
796
797         split = isl_calloc_array(map->isl, struct isl_aff_split, map->n);
798         if (!split)
799                 return NULL;
800         
801         for (i = 0; i < map->n; ++i) {
802                 isl_basic_map *bmap;
803                 split[i].aff = get_aff(isl_basic_map_copy(map->p[i]));
804                 bmap = isl_basic_map_copy(map->p[i]);
805                 bmap = isl_basic_map_cow(bmap);
806                 bmap = drop_aff(bmap, split[i].aff);
807                 split[i].map = isl_map_from_basic_map(bmap);
808                 if (!split[i].aff || !split[i].map)
809                         goto error;
810         }
811
812         qsort(split, map->n, sizeof(struct isl_aff_split), &aff_split_cmp);
813
814         n = map->n;
815         for (i = n - 1; i >= 1; --i) {
816                 if (!isl_basic_map_fast_is_equal(split[i - 1].aff,
817                                                  split[i].aff))
818                         continue;
819                 isl_basic_map_free(split[i].aff);
820                 split[i - 1].map = isl_map_union(split[i - 1].map,
821                                                  split[i].map);
822                 if (i != n - 1)
823                         split[i] = split[n - 1];
824                 split[n - 1].aff = NULL;
825                 split[n - 1].map = NULL;
826                 --n;
827         }
828
829         return split;
830 error:
831         free_split(split, map->n);
832         return NULL;
833 }
834
835 static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p,
836         struct isl_aff_split *split, int n, int set)
837 {
838         int i;
839
840         for (i = 0; i < n; ++i) {
841                 isl_dim *dim;
842
843                 if (!split[i].map)
844                         break;
845                 dim = split[i].map->dim;
846                 if (i)
847                         p = isl_printer_print_str(p, "; ");
848                 p = print_dim(dim, p, set, 0, split[i].aff);
849                 p = print_disjuncts(split[i].map, p, set, 0);
850         }
851
852         return p;
853 }
854
855 static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map,
856         __isl_take isl_printer *p, int set)
857 {
858         struct isl_aff_split *split = NULL;
859
860         if (map->n > 0)
861                 split = split_aff(map);
862         if (split) {
863                 p = print_split_map(p, split, map->n, set);
864         } else {
865                 p = print_dim(map->dim, p, set, 0, NULL);
866                 p = print_disjuncts(map, p, set, 0);
867         }
868         free_split(split, map->n);
869         return p;
870 }
871
872 static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,
873         __isl_take isl_printer *p, int set)
874 {
875         if (isl_map_dim(map, isl_dim_param) > 0) {
876                 p = print_tuple(map->dim, p, isl_dim_param, set, 0, NULL);
877                 p = isl_printer_print_str(p, s_to[0]);
878         }
879         p = isl_printer_print_str(p, s_open_set[0]);
880         p = isl_map_print_isl_body(map, p, set);
881         p = isl_printer_print_str(p, s_close_set[0]);
882         return p;
883 }
884
885 static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map,
886         __isl_take isl_printer *p, __isl_keep isl_basic_map *aff, int set)
887 {
888         if (isl_map_dim(map, isl_dim_param) > 0) {
889                 p = print_tuple(map->dim, p, isl_dim_param, set, 1, NULL);
890                 p = isl_printer_print_str(p, s_to[1]);
891         }
892         p = isl_printer_print_str(p, s_open_set[1]);
893         p = print_dim(map->dim, p, set, 1, aff);
894         p = print_disjuncts(map, p, set, 1);
895         p = isl_printer_print_str(p, s_close_set[1]);
896
897         return p;
898 }
899
900 static __isl_give isl_printer *isl_map_print_latex(__isl_keep isl_map *map,
901         __isl_take isl_printer *p, int set)
902 {
903         int i;
904         struct isl_aff_split *split = NULL;
905
906         if (map->n > 0)
907                 split = split_aff(map);
908
909         if (!split)
910                 return print_latex_map(map, p, NULL, set);
911
912         for (i = 0; i < map->n; ++i) {
913                 if (!split[i].map)
914                         break;
915                 if (i)
916                         p = isl_printer_print_str(p, " \\cup ");
917                 p = print_latex_map(split[i].map, p, split[i].aff, set);
918         }
919
920         free_split(split, map->n);
921         return p;
922 }
923
924 __isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p,
925         __isl_keep isl_basic_map *bmap)
926 {
927         if (!p || !bmap)
928                 goto error;
929         if (p->output_format == ISL_FORMAT_ISL)
930                 return isl_basic_map_print_isl(bmap, p, 0);
931         else if (p->output_format == ISL_FORMAT_OMEGA)
932                 return isl_basic_map_print_omega(bmap, p);
933         isl_assert(bmap->ctx, 0, goto error);
934 error:
935         isl_printer_free(p);
936         return NULL;
937 }
938
939 void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent,
940         const char *prefix, const char *suffix, unsigned output_format)
941 {
942         isl_printer *printer;
943
944         if (!bmap)
945                 return;
946
947         printer = isl_printer_to_file(bmap->ctx, out);
948         printer = isl_printer_set_indent(printer, indent);
949         printer = isl_printer_set_prefix(printer, prefix);
950         printer = isl_printer_set_suffix(printer, suffix);
951         printer = isl_printer_set_output_format(printer, output_format);
952         isl_printer_print_basic_map(printer, bmap);
953
954         isl_printer_free(printer);
955 }
956
957 __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,
958         __isl_keep isl_basic_set *bset)
959 {
960         if (!p || !bset)
961                 goto error;
962
963         if (p->output_format == ISL_FORMAT_ISL)
964                 return isl_basic_set_print_isl(bset, p, 0);
965         else if (p->output_format == ISL_FORMAT_POLYLIB)
966                 return isl_basic_set_print_polylib(bset, p, 0);
967         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
968                 return isl_basic_set_print_polylib(bset, p, 1);
969         else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)
970                 return bset_print_constraints_polylib(bset, p);
971         else if (p->output_format == ISL_FORMAT_OMEGA)
972                 return isl_basic_set_print_omega(bset, p);
973         isl_assert(p->ctx, 0, goto error);
974 error:
975         isl_printer_free(p);
976         return NULL;
977 }
978
979 void isl_basic_set_print(struct isl_basic_set *bset, FILE *out, int indent,
980         const char *prefix, const char *suffix, unsigned output_format)
981 {
982         isl_printer *printer;
983
984         if (!bset)
985                 return;
986
987         printer = isl_printer_to_file(bset->ctx, out);
988         printer = isl_printer_set_indent(printer, indent);
989         printer = isl_printer_set_prefix(printer, prefix);
990         printer = isl_printer_set_suffix(printer, suffix);
991         printer = isl_printer_set_output_format(printer, output_format);
992         isl_printer_print_basic_set(printer, bset);
993
994         isl_printer_free(printer);
995 }
996
997 __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,
998         __isl_keep isl_set *set)
999 {
1000         if (!p || !set)
1001                 goto error;
1002         if (p->output_format == ISL_FORMAT_ISL)
1003                 return isl_map_print_isl((isl_map *)set, p, 1);
1004         else if (p->output_format == ISL_FORMAT_POLYLIB)
1005                 return isl_set_print_polylib(set, p, 0);
1006         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1007                 return isl_set_print_polylib(set, p, 1);
1008         else if (p->output_format == ISL_FORMAT_OMEGA)
1009                 return isl_set_print_omega(set, p);
1010         else if (p->output_format == ISL_FORMAT_LATEX)
1011                 return isl_map_print_latex((isl_map *)set, p, 1);
1012         isl_assert(set->ctx, 0, goto error);
1013 error:
1014         isl_printer_free(p);
1015         return NULL;
1016 }
1017
1018 void isl_set_print(struct isl_set *set, FILE *out, int indent,
1019         unsigned output_format)
1020 {
1021         isl_printer *printer;
1022
1023         if (!set)
1024                 return;
1025
1026         printer = isl_printer_to_file(set->ctx, out);
1027         printer = isl_printer_set_indent(printer, indent);
1028         printer = isl_printer_set_output_format(printer, output_format);
1029         printer = isl_printer_print_set(printer, set);
1030
1031         isl_printer_free(printer);
1032 }
1033
1034 __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
1035         __isl_keep isl_map *map)
1036 {
1037         if (!p || !map)
1038                 goto error;
1039
1040         if (p->output_format == ISL_FORMAT_ISL)
1041                 return isl_map_print_isl(map, p, 0);
1042         else if (p->output_format == ISL_FORMAT_POLYLIB)
1043                 return isl_map_print_polylib(map, p, 0);
1044         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1045                 return isl_map_print_polylib(map, p, 1);
1046         else if (p->output_format == ISL_FORMAT_OMEGA)
1047                 return isl_map_print_omega(map, p);
1048         else if (p->output_format == ISL_FORMAT_LATEX)
1049                 return isl_map_print_latex(map, p, 0);
1050         isl_assert(map->ctx, 0, goto error);
1051 error:
1052         isl_printer_free(p);
1053         return NULL;
1054 }
1055
1056 struct isl_union_print_data {
1057         isl_printer *p;
1058         int set;
1059         int first;
1060 };
1061
1062 static int print_map_body(__isl_take isl_map *map, void *user)
1063 {
1064         struct isl_union_print_data *data;
1065         data = (struct isl_union_print_data *)user;
1066
1067         if (!data->first)
1068                 data->p = isl_printer_print_str(data->p, "; ");
1069         data->first = 0;
1070
1071         data->p = isl_map_print_isl_body(map, data->p, data->set);
1072         isl_map_free(map);
1073
1074         return 0;
1075 }
1076
1077 static __isl_give isl_printer *isl_union_map_print_isl(
1078         __isl_keep isl_union_map *umap, __isl_take isl_printer *p, int set)
1079 {
1080         struct isl_union_print_data data = { p, set, 1 };
1081         isl_dim *dim;
1082         dim = isl_union_map_get_dim(umap);
1083         if (isl_dim_size(dim, isl_dim_param) > 0) {
1084                 p = print_tuple(dim, p, isl_dim_param, set, 0, NULL);
1085                 p = isl_printer_print_str(p, s_to[0]);
1086         }
1087         isl_dim_free(dim);
1088         p = isl_printer_print_str(p, s_open_set[0]);
1089         isl_union_map_foreach_map(umap, &print_map_body, &data);
1090         p = data.p;
1091         p = isl_printer_print_str(p, s_close_set[0]);
1092         return p;
1093 }
1094
1095 static int print_latex_map_body(__isl_take isl_map *map, void *user)
1096 {
1097         struct isl_union_print_data *data;
1098         data = (struct isl_union_print_data *)user;
1099
1100         if (!data->first)
1101                 data->p = isl_printer_print_str(data->p, " \\cup ");
1102         data->first = 0;
1103
1104         data->p = isl_map_print_latex(map, data->p, data->set);
1105         isl_map_free(map);
1106
1107         return 0;
1108 }
1109
1110 static __isl_give isl_printer *isl_union_map_print_latex(
1111         __isl_keep isl_union_map *umap, __isl_take isl_printer *p, int set)
1112 {
1113         struct isl_union_print_data data = { p, set, 1 };
1114         isl_union_map_foreach_map(umap, &print_latex_map_body, &data);
1115         p = data.p;
1116         return p;
1117 }
1118
1119 __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p,
1120         __isl_keep isl_union_map *umap)
1121 {
1122         if (!p || !umap)
1123                 goto error;
1124
1125         if (p->output_format == ISL_FORMAT_ISL)
1126                 return isl_union_map_print_isl(umap, p, 0);
1127         if (p->output_format == ISL_FORMAT_LATEX)
1128                 return isl_union_map_print_latex(umap, p, 0);
1129
1130         isl_die(p->ctx, isl_error_invalid,
1131                 "invalid output format for isl_union_map", goto error);
1132 error:
1133         isl_printer_free(p);
1134         return NULL;
1135 }
1136
1137 __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
1138         __isl_keep isl_union_set *uset)
1139 {
1140         if (!p || !uset)
1141                 goto error;
1142
1143         if (p->output_format == ISL_FORMAT_ISL)
1144                 return isl_union_map_print_isl((isl_union_map *)uset, p, 1);
1145         if (p->output_format == ISL_FORMAT_LATEX)
1146                 return isl_union_map_print_latex((isl_union_map *)uset, p, 1);
1147
1148         isl_die(p->ctx, isl_error_invalid,
1149                 "invalid output format for isl_union_set", goto error);
1150 error:
1151         isl_printer_free(p);
1152         return NULL;
1153 }
1154
1155 void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent,
1156         unsigned output_format)
1157 {
1158         isl_printer *printer;
1159
1160         if (!map)
1161                 return;
1162
1163         printer = isl_printer_to_file(map->ctx, out);
1164         printer = isl_printer_set_indent(printer, indent);
1165         printer = isl_printer_set_output_format(printer, output_format);
1166         printer = isl_printer_print_map(printer, map);
1167
1168         isl_printer_free(printer);
1169 }
1170
1171 void isl_union_map_dump(__isl_keep isl_union_map *umap)
1172 {
1173         isl_printer *printer;
1174
1175         if (!umap)
1176                 return;
1177
1178         printer = isl_printer_to_file(isl_union_map_get_ctx(umap), stderr);
1179         printer = isl_printer_print_union_map(printer, umap);
1180         printer = isl_printer_end_line(printer);
1181
1182         isl_printer_free(printer);
1183 }
1184
1185 void isl_union_set_dump(__isl_keep isl_union_set *uset)
1186 {
1187         isl_printer *printer;
1188
1189         if (!uset)
1190                 return;
1191
1192         printer = isl_printer_to_file(isl_union_set_get_ctx(uset), stderr);
1193         printer = isl_printer_print_union_set(printer, uset);
1194         printer = isl_printer_end_line(printer);
1195
1196         isl_printer_free(printer);
1197 }
1198
1199 void isl_union_pw_qpolynomial_dump(__isl_keep isl_union_pw_qpolynomial *upwqp)
1200 {
1201         isl_printer *printer;
1202
1203         if (!upwqp)
1204                 return;
1205
1206         printer = isl_printer_to_file(isl_union_pw_qpolynomial_get_ctx(upwqp),
1207                                         stderr);
1208         printer = isl_printer_print_union_pw_qpolynomial(printer, upwqp);
1209         printer = isl_printer_end_line(printer);
1210
1211         isl_printer_free(printer);
1212 }
1213
1214 void isl_union_pw_qpolynomial_fold_dump(
1215         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
1216 {
1217         isl_printer *printer;
1218
1219         if (!upwf)
1220                 return;
1221
1222         printer = isl_printer_to_file(
1223                         isl_union_pw_qpolynomial_fold_get_ctx(upwf), stderr);
1224         printer = isl_printer_print_union_pw_qpolynomial_fold(printer, upwf);
1225         printer = isl_printer_end_line(printer);
1226
1227         isl_printer_free(printer);
1228 }
1229
1230 static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec)
1231 {
1232         int i;
1233         int n;
1234
1235         for (i = 0, n = 0; i < rec->n; ++i)
1236                 if (!isl_upoly_is_zero(rec->p[i]))
1237                         ++n;
1238
1239         return n;
1240 }
1241
1242 static __isl_give isl_printer *print_div(__isl_keep isl_dim *dim,
1243         __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p)
1244 {
1245         int c = p->output_format == ISL_FORMAT_C;
1246         p = isl_printer_print_str(p, c ? "floord(" : "[(");
1247         p = print_affine_of_len(dim, div, p,
1248                                 div->row[pos] + 1, div->n_col - 1, 1);
1249         p = isl_printer_print_str(p, c ? ", " : ")/");
1250         p = isl_printer_print_isl_int(p, div->row[pos][0]);
1251         p = isl_printer_print_str(p, c ? ")" : "]");
1252         return p;
1253 }
1254
1255 static __isl_give isl_printer *upoly_print_cst(__isl_keep struct isl_upoly *up,
1256         __isl_take isl_printer *p, int first)
1257 {
1258         struct isl_upoly_cst *cst;
1259         int neg;
1260
1261         cst = isl_upoly_as_cst(up);
1262         if (!cst)
1263                 goto error;
1264         neg = !first && isl_int_is_neg(cst->n);
1265         if (!first)
1266                 p = isl_printer_print_str(p, neg ? " - " :  " + ");
1267         if (neg)
1268                 isl_int_neg(cst->n, cst->n);
1269         if (isl_int_is_zero(cst->d)) {
1270                 int sgn = isl_int_sgn(cst->n);
1271                 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
1272                                             sgn == 0 ? "NaN" : "infty");
1273         } else
1274                 p = isl_printer_print_isl_int(p, cst->n);
1275         if (neg)
1276                 isl_int_neg(cst->n, cst->n);
1277         if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) {
1278                 p = isl_printer_print_str(p, "/");
1279                 p = isl_printer_print_isl_int(p, cst->d);
1280         }
1281         return p;
1282 error:
1283         isl_printer_free(p);
1284         return NULL;
1285 }
1286
1287 static __isl_give isl_printer *print_base(__isl_take isl_printer *p,
1288         __isl_keep isl_dim *dim, __isl_keep isl_mat *div, int var)
1289 {
1290         unsigned total;
1291
1292         total = isl_dim_total(dim);
1293         if (var < total)
1294                 p = print_term(dim, NULL, dim->ctx->one, 1 + var, p, 1, 0);
1295         else
1296                 p = print_div(dim, div, var - total, p);
1297         return p;
1298 }
1299
1300 static __isl_give isl_printer *print_pow(__isl_take isl_printer *p,
1301         __isl_keep isl_dim *dim, __isl_keep isl_mat *div, int var, int exp)
1302 {
1303         p = print_base(p, dim, div, var);
1304         if (exp == 1)
1305                 return p;
1306         if (p->output_format == ISL_FORMAT_C) {
1307                 int i;
1308                 for (i = 1; i < exp; ++i) {
1309                         p = isl_printer_print_str(p, "*");
1310                         p = print_base(p, dim, div, var);
1311                 }
1312         } else {
1313                 p = isl_printer_print_str(p, "^");
1314                 p = isl_printer_print_int(p, exp);
1315         }
1316         return p;
1317 }
1318
1319 static __isl_give isl_printer *upoly_print(__isl_keep struct isl_upoly *up,
1320         __isl_keep isl_dim *dim, __isl_keep isl_mat *div,
1321         __isl_take isl_printer *p, int outer)
1322 {
1323         int i, n, first, print_parens;
1324         struct isl_upoly_rec *rec;
1325
1326         if (!p || !up || !dim || !div)
1327                 goto error;
1328
1329         if (isl_upoly_is_cst(up))
1330                 return upoly_print_cst(up, p, 1);
1331
1332         rec = isl_upoly_as_rec(up);
1333         if (!rec)
1334                 goto error;
1335         n = upoly_rec_n_non_zero(rec);
1336         print_parens = n > 1 || (outer && rec->up.var >= isl_dim_total(dim));
1337         if (print_parens)
1338                 p = isl_printer_print_str(p, "(");
1339         for (i = 0, first = 1; i < rec->n; ++i) {
1340                 if (isl_upoly_is_zero(rec->p[i]))
1341                         continue;
1342                 if (isl_upoly_is_negone(rec->p[i])) {
1343                         if (!i)
1344                                 p = isl_printer_print_str(p, "-1");
1345                         else if (first)
1346                                 p = isl_printer_print_str(p, "-");
1347                         else
1348                                 p = isl_printer_print_str(p, " - ");
1349                 } else if (isl_upoly_is_cst(rec->p[i]) &&
1350                                 !isl_upoly_is_one(rec->p[i]))
1351                         p = upoly_print_cst(rec->p[i], p, first);
1352                 else {
1353                         if (!first)
1354                                 p = isl_printer_print_str(p, " + ");
1355                         if (i == 0 || !isl_upoly_is_one(rec->p[i]))
1356                                 p = upoly_print(rec->p[i], dim, div, p, 0);
1357                 }
1358                 first = 0;
1359                 if (i == 0)
1360                         continue;
1361                 if (!isl_upoly_is_one(rec->p[i]) &&
1362                     !isl_upoly_is_negone(rec->p[i]))
1363                         p = isl_printer_print_str(p, " * ");
1364                 p = print_pow(p, dim, div, rec->up.var, i);
1365         }
1366         if (print_parens)
1367                 p = isl_printer_print_str(p, ")");
1368         return p;
1369 error:
1370         isl_printer_free(p);
1371         return NULL;
1372 }
1373
1374 __isl_give isl_printer *isl_printer_print_qpolynomial(__isl_take isl_printer *p,
1375         __isl_keep isl_qpolynomial *qp)
1376 {
1377         if (!p || !qp)
1378                 goto error;
1379         p = upoly_print(qp->upoly, qp->dim, qp->div, p, 1);
1380         return p;
1381 error:
1382         isl_printer_free(p);
1383         return NULL;
1384 }
1385
1386 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
1387         unsigned output_format)
1388 {
1389         isl_printer *p;
1390
1391         if  (!qp)
1392                 return;
1393
1394         isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1395         p = isl_printer_to_file(qp->dim->ctx, out);
1396         p = isl_printer_print_qpolynomial(p, qp);
1397         isl_printer_free(p);
1398 }
1399
1400 static __isl_give isl_printer *qpolynomial_fold_print(
1401         __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
1402 {
1403         int i;
1404
1405         if (fold->type == isl_fold_min)
1406                 p = isl_printer_print_str(p, "min");
1407         else if (fold->type == isl_fold_max)
1408                 p = isl_printer_print_str(p, "max");
1409         p = isl_printer_print_str(p, "(");
1410         for (i = 0; i < fold->n; ++i) {
1411                 if (i)
1412                         p = isl_printer_print_str(p, ", ");
1413                 p = isl_printer_print_qpolynomial(p, fold->qp[i]);
1414         }
1415         p = isl_printer_print_str(p, ")");
1416         return p;
1417 }
1418
1419 __isl_give isl_printer *isl_printer_print_qpolynomial_fold(
1420         __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
1421 {
1422         if  (!p || !fold)
1423                 goto error;
1424         p = qpolynomial_fold_print(fold, p);
1425         return p;
1426 error:
1427         isl_printer_free(p);
1428         return NULL;
1429 }
1430
1431 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
1432         FILE *out, unsigned output_format)
1433 {
1434         isl_printer *p;
1435
1436         if (!fold)
1437                 return;
1438
1439         isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);
1440
1441         p = isl_printer_to_file(fold->dim->ctx, out);
1442         p = isl_printer_print_qpolynomial_fold(p, fold);
1443
1444         isl_printer_free(p);
1445 }
1446
1447 static __isl_give isl_printer *isl_pwqp_print_isl_body(
1448         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1449 {
1450         int i = 0;
1451
1452         for (i = 0; i < pwqp->n; ++i) {
1453                 if (i)
1454                         p = isl_printer_print_str(p, "; ");
1455                 if (isl_dim_size(pwqp->dim, isl_dim_set) > 0 ||
1456                     isl_dim_is_named_or_nested(pwqp->dim, isl_dim_set)) {
1457                         p = print_dim(pwqp->p[i].set->dim, p, 1, 0, NULL);
1458                         p = isl_printer_print_str(p, " -> ");
1459                 }
1460                 p = isl_printer_print_qpolynomial(p, pwqp->p[i].qp);
1461                 p = print_disjuncts((isl_map *)pwqp->p[i].set, p, 1, 0);
1462         }
1463
1464         return p;
1465 }
1466
1467 static __isl_give isl_printer *print_pw_qpolynomial_isl(
1468         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1469 {
1470         if (!p || !pwqp)
1471                 goto error;
1472
1473         if (isl_dim_size(pwqp->dim, isl_dim_param) > 0) {
1474                 p = print_tuple(pwqp->dim, p, isl_dim_param, 0, 0, NULL);
1475                 p = isl_printer_print_str(p, " -> ");
1476         }
1477         p = isl_printer_print_str(p, "{ ");
1478         if (pwqp->n == 0) {
1479                 if (isl_dim_size(pwqp->dim, isl_dim_set) > 0 ||
1480                     isl_dim_is_named_or_nested(pwqp->dim, isl_dim_set)) {
1481                         p = print_dim(pwqp->dim, p, 1, 0, NULL);
1482                         p = isl_printer_print_str(p, " -> ");
1483                 }
1484                 p = isl_printer_print_str(p, "0");
1485         }
1486         p = isl_pwqp_print_isl_body(p, pwqp);
1487         p = isl_printer_print_str(p, " }");
1488         return p;
1489 error:
1490         isl_printer_free(p);
1491         return NULL;
1492 }
1493
1494 void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
1495         unsigned output_format)
1496 {
1497         isl_printer *p;
1498
1499         if (!pwqp)
1500                 return;
1501
1502         p = isl_printer_to_file(pwqp->dim->ctx, out);
1503         p = isl_printer_set_output_format(p, output_format);
1504         p = isl_printer_print_pw_qpolynomial(p, pwqp);
1505
1506         isl_printer_free(p);
1507 }
1508
1509 static __isl_give isl_printer *isl_pwf_print_isl_body(
1510         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1511 {
1512         int i = 0;
1513
1514         for (i = 0; i < pwf->n; ++i) {
1515                 if (i)
1516                         p = isl_printer_print_str(p, "; ");
1517                 if (isl_dim_size(pwf->dim, isl_dim_set) > 0 ||
1518                     isl_dim_is_named_or_nested(pwf->dim, isl_dim_set)) {
1519                         p = print_dim(pwf->p[i].set->dim, p, 1, 0, NULL);
1520                         p = isl_printer_print_str(p, " -> ");
1521                 }
1522                 p = qpolynomial_fold_print(pwf->p[i].fold, p);
1523                 p = print_disjuncts((isl_map *)pwf->p[i].set, p, 1, 0);
1524         }
1525
1526         return p;
1527 }
1528
1529 static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(
1530         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1531 {
1532         if (isl_dim_size(pwf->dim, isl_dim_param) > 0) {
1533                 p = print_tuple(pwf->dim, p, isl_dim_param, 0, 0, NULL);
1534                 p = isl_printer_print_str(p, " -> ");
1535         }
1536         p = isl_printer_print_str(p, "{ ");
1537         if (pwf->n == 0) {
1538                 if (isl_dim_size(pwf->dim, isl_dim_set) > 0 ||
1539                     isl_dim_is_named_or_nested(pwf->dim, isl_dim_set)) {
1540                         p = print_dim(pwf->dim, p, 1, 0, NULL);
1541                         p = isl_printer_print_str(p, " -> ");
1542                 }
1543                 p = isl_printer_print_str(p, "0");
1544         }
1545         p = isl_pwf_print_isl_body(p, pwf);
1546         p = isl_printer_print_str(p, " }");
1547         return p;
1548 }
1549
1550 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1551         __isl_keep isl_dim *dim, __isl_keep isl_basic_set *bset, isl_int *c);
1552
1553 static __isl_give isl_printer *print_name_c(__isl_take isl_printer *p,
1554         __isl_keep isl_dim *dim,
1555         __isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos)
1556 {
1557         if (type == isl_dim_div) {
1558                 p = isl_printer_print_str(p, "floord(");
1559                 p = print_affine_c(p, dim, bset, bset->div[pos] + 1);
1560                 p = isl_printer_print_str(p, ", ");
1561                 p = isl_printer_print_isl_int(p, bset->div[pos][0]);
1562                 p = isl_printer_print_str(p, ")");
1563         } else {
1564                 const char *name;
1565
1566                 name = isl_dim_get_name(dim, type, pos);
1567                 if (!name)
1568                         name = "UNNAMED";
1569                 p = isl_printer_print_str(p, name);
1570         }
1571         return p;
1572 }
1573
1574 static __isl_give isl_printer *print_term_c(__isl_take isl_printer *p,
1575         __isl_keep isl_dim *dim,
1576         __isl_keep isl_basic_set *bset, isl_int c, unsigned pos)
1577 {
1578         enum isl_dim_type type;
1579         unsigned nparam = isl_basic_set_dim(bset, isl_dim_param);
1580
1581         if (pos == 0)
1582                 return isl_printer_print_isl_int(p, c);
1583
1584         if (isl_int_is_one(c))
1585                 ;
1586         else if (isl_int_is_negone(c))
1587                 p = isl_printer_print_str(p, "-");
1588         else {
1589                 p = isl_printer_print_isl_int(p, c);
1590                 p = isl_printer_print_str(p, "*");
1591         }
1592         type = pos2type(dim, &pos);
1593         p = print_name_c(p, dim, bset, type, pos);
1594         return p;
1595 }
1596
1597 static __isl_give isl_printer *print_partial_affine_c(__isl_take isl_printer *p,
1598         __isl_keep isl_dim *dim,
1599         __isl_keep isl_basic_set *bset, isl_int *c, unsigned len)
1600 {
1601         int i;
1602         int first;
1603
1604         for (i = 0, first = 1; i < len; ++i) {
1605                 int flip = 0;
1606                 if (isl_int_is_zero(c[i]))
1607                         continue;
1608                 if (!first) {
1609                         if (isl_int_is_neg(c[i])) {
1610                                 flip = 1;
1611                                 isl_int_neg(c[i], c[i]);
1612                                 p = isl_printer_print_str(p, " - ");
1613                         } else 
1614                                 p = isl_printer_print_str(p, " + ");
1615                 }
1616                 first = 0;
1617                 p = print_term_c(p, dim, bset, c[i], i);
1618                 if (flip)
1619                         isl_int_neg(c[i], c[i]);
1620         }
1621         if (first)
1622                 p = isl_printer_print_str(p, "0");
1623         return p;
1624 }
1625
1626 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1627         __isl_keep isl_dim *dim, __isl_keep isl_basic_set *bset, isl_int *c)
1628 {
1629         unsigned len = 1 + isl_basic_set_total_dim(bset);
1630         return print_partial_affine_c(p, dim, bset, c, len);
1631 }
1632
1633 static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,
1634         __isl_keep isl_dim *dim,
1635         __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int first)
1636 {
1637         if (!first)
1638                 p = isl_printer_print_str(p, " && ");
1639
1640         p = print_affine_c(p, dim, bset, c);
1641         p = isl_printer_print_str(p, " ");
1642         p = isl_printer_print_str(p, op);
1643         p = isl_printer_print_str(p, " 0");
1644         return p;
1645 }
1646
1647 static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,
1648         __isl_keep isl_dim *dim, __isl_keep isl_basic_set *bset)
1649 {
1650         int i, j;
1651         unsigned n_div = isl_basic_set_dim(bset, isl_dim_div);
1652         unsigned total = isl_basic_set_total_dim(bset) - n_div;
1653
1654         for (i = 0; i < bset->n_eq; ++i) {
1655                 j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div);
1656                 if (j < 0)
1657                         p = print_constraint_c(p, dim, bset,
1658                                                 bset->eq[i], "==", !i);
1659                 else {
1660                         if (i)
1661                                 p = isl_printer_print_str(p, " && ");
1662                         p = isl_printer_print_str(p, "(");
1663                         p = print_partial_affine_c(p, dim, bset, bset->eq[i],
1664                                                    1 + total + j);
1665                         p = isl_printer_print_str(p, ") % ");
1666                         p = isl_printer_print_isl_int(p,
1667                                                 bset->eq[i][1 + total + j]);
1668                         p = isl_printer_print_str(p, " == 0");
1669                 }
1670         }
1671         for (i = 0; i < bset->n_ineq; ++i)
1672                 p = print_constraint_c(p, dim, bset, bset->ineq[i], ">=",
1673                                         !bset->n_eq && !i);
1674         return p;
1675 }
1676
1677 static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,
1678         __isl_keep isl_dim *dim, __isl_keep isl_set *set)
1679 {
1680         int i;
1681
1682         if (set->n == 0)
1683                 p = isl_printer_print_str(p, "0");
1684
1685         for (i = 0; i < set->n; ++i) {
1686                 if (i)
1687                         p = isl_printer_print_str(p, " || ");
1688                 if (set->n > 1)
1689                         p = isl_printer_print_str(p, "(");
1690                 p = print_basic_set_c(p, dim, set->p[i]);
1691                 if (set->n > 1)
1692                         p = isl_printer_print_str(p, ")");
1693         }
1694         return p;
1695 }
1696
1697 static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p,
1698         __isl_keep isl_dim *dim, __isl_keep isl_qpolynomial *qp)
1699 {
1700         isl_int den;
1701
1702         isl_int_init(den);
1703         isl_qpolynomial_get_den(qp, &den);
1704         if (!isl_int_is_one(den)) {
1705                 isl_qpolynomial *f;
1706                 p = isl_printer_print_str(p, "(");
1707                 qp = isl_qpolynomial_copy(qp);
1708                 f = isl_qpolynomial_rat_cst(isl_dim_copy(qp->dim),
1709                                                 den, qp->dim->ctx->one);
1710                 qp = isl_qpolynomial_mul(qp, f);
1711         }
1712         if (qp)
1713                 p = upoly_print(qp->upoly, dim, qp->div, p, 0);
1714         if (!isl_int_is_one(den)) {
1715                 p = isl_printer_print_str(p, ")/");
1716                 p = isl_printer_print_isl_int(p, den);
1717                 isl_qpolynomial_free(qp);
1718         }
1719         isl_int_clear(den);
1720         return p;
1721 }
1722
1723 static __isl_give isl_printer *print_pw_qpolynomial_c(
1724         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1725 {
1726         int i;
1727
1728         if (pwqp->n == 1 && isl_set_fast_is_universe(pwqp->p[0].set))
1729                 return print_qpolynomial_c(p, pwqp->dim, pwqp->p[0].qp);
1730
1731         for (i = 0; i < pwqp->n; ++i) {
1732                 p = isl_printer_print_str(p, "(");
1733                 p = print_set_c(p, pwqp->dim, pwqp->p[i].set);
1734                 p = isl_printer_print_str(p, ") ? (");
1735                 p = print_qpolynomial_c(p, pwqp->dim, pwqp->p[i].qp);
1736                 p = isl_printer_print_str(p, ") : ");
1737         }
1738
1739         p = isl_printer_print_str(p, "0");
1740         return p;
1741 }
1742
1743 __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
1744         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1745 {
1746         if (!p || !pwqp)
1747                 goto error;
1748
1749         if (p->output_format == ISL_FORMAT_ISL)
1750                 return print_pw_qpolynomial_isl(p, pwqp);
1751         else if (p->output_format == ISL_FORMAT_C)
1752                 return print_pw_qpolynomial_c(p, pwqp);
1753         isl_assert(p->ctx, 0, goto error);
1754 error:
1755         isl_printer_free(p);
1756         return NULL;
1757 }
1758
1759 static int print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user)
1760 {
1761         struct isl_union_print_data *data;
1762         data = (struct isl_union_print_data *)user;
1763
1764         if (!data->first)
1765                 data->p = isl_printer_print_str(data->p, "; ");
1766         data->first = 0;
1767
1768         data->p = isl_pwqp_print_isl_body(data->p, pwqp);
1769         isl_pw_qpolynomial_free(pwqp);
1770
1771         return 0;
1772 }
1773
1774 static __isl_give isl_printer *print_union_pw_qpolynomial_isl(
1775         __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
1776 {
1777         struct isl_union_print_data data = { p, 1, 1 };
1778         isl_dim *dim;
1779         dim = isl_union_pw_qpolynomial_get_dim(upwqp);
1780         if (isl_dim_size(dim, isl_dim_param) > 0) {
1781                 p = print_tuple(dim, p, isl_dim_param, 1, 0, NULL);
1782                 p = isl_printer_print_str(p, " -> ");
1783         }
1784         isl_dim_free(dim);
1785         p = isl_printer_print_str(p, "{ ");
1786         isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body,
1787                                                         &data);
1788         p = data.p;
1789         p = isl_printer_print_str(p, " }");
1790         return p;
1791 }
1792
1793 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial(
1794         __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
1795 {
1796         if (!p || !upwqp)
1797                 goto error;
1798
1799         if (p->output_format == ISL_FORMAT_ISL)
1800                 return print_union_pw_qpolynomial_isl(p, upwqp);
1801         isl_die(p->ctx, isl_error_invalid,
1802                 "invalid output format for isl_union_pw_qpolynomial",
1803                 goto error);
1804 error:
1805         isl_printer_free(p);
1806         return NULL;
1807 }
1808
1809 static __isl_give isl_printer *print_qpolynomial_fold_c(
1810         __isl_take isl_printer *p, __isl_keep isl_dim *dim,
1811         __isl_keep isl_qpolynomial_fold *fold)
1812 {
1813         int i;
1814
1815         for (i = 0; i < fold->n - 1; ++i)
1816                 if (fold->type == isl_fold_min)
1817                         p = isl_printer_print_str(p, "min(");
1818                 else if (fold->type == isl_fold_max)
1819                         p = isl_printer_print_str(p, "max(");
1820
1821         for (i = 0; i < fold->n; ++i) {
1822                 if (i)
1823                         p = isl_printer_print_str(p, ", ");
1824                 p = print_qpolynomial_c(p, dim, fold->qp[i]);
1825                 if (i)
1826                         p = isl_printer_print_str(p, ")");
1827         }
1828         return p;
1829 }
1830
1831 static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
1832         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1833 {
1834         int i;
1835
1836         if (pwf->n == 1 && isl_set_fast_is_universe(pwf->p[0].set))
1837                 return print_qpolynomial_fold_c(p, pwf->dim, pwf->p[0].fold);
1838
1839         for (i = 0; i < pwf->n; ++i) {
1840                 p = isl_printer_print_str(p, "(");
1841                 p = print_set_c(p, pwf->dim, pwf->p[i].set);
1842                 p = isl_printer_print_str(p, ") ? (");
1843                 p = print_qpolynomial_fold_c(p, pwf->dim, pwf->p[i].fold);
1844                 p = isl_printer_print_str(p, ") : ");
1845         }
1846
1847         p = isl_printer_print_str(p, "0");
1848         return p;
1849 }
1850
1851 __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
1852         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1853 {
1854         if (!p || !pwf)
1855                 goto error;
1856
1857         if (p->output_format == ISL_FORMAT_ISL)
1858                 return print_pw_qpolynomial_fold_isl(p, pwf);
1859         else if (p->output_format == ISL_FORMAT_C)
1860                 return print_pw_qpolynomial_fold_c(p, pwf);
1861         isl_assert(p->ctx, 0, goto error);
1862 error:
1863         isl_printer_free(p);
1864         return NULL;
1865 }
1866
1867 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
1868         FILE *out, unsigned output_format)
1869 {
1870         isl_printer *p;
1871
1872         if (!pwf)
1873                 return;
1874
1875         p = isl_printer_to_file(pwf->dim->ctx, out);
1876         p = isl_printer_set_output_format(p, output_format);
1877         p = isl_printer_print_pw_qpolynomial_fold(p, pwf);
1878
1879         isl_printer_free(p);
1880 }
1881
1882 static int print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf, void *user)
1883 {
1884         struct isl_union_print_data *data;
1885         data = (struct isl_union_print_data *)user;
1886
1887         if (!data->first)
1888                 data->p = isl_printer_print_str(data->p, "; ");
1889         data->first = 0;
1890
1891         data->p = isl_pwf_print_isl_body(data->p, pwf);
1892         isl_pw_qpolynomial_fold_free(pwf);
1893
1894         return 0;
1895 }
1896
1897 static __isl_give isl_printer *print_union_pw_qpolynomial_fold_isl(
1898         __isl_take isl_printer *p,
1899         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
1900 {
1901         struct isl_union_print_data data = { p, 1, 1 };
1902         isl_dim *dim;
1903         dim = isl_union_pw_qpolynomial_fold_get_dim(upwf);
1904         if (isl_dim_size(dim, isl_dim_param) > 0) {
1905                 p = print_tuple(dim, p, isl_dim_param, 1, 0, NULL);
1906                 p = isl_printer_print_str(p, " -> ");
1907         }
1908         isl_dim_free(dim);
1909         p = isl_printer_print_str(p, "{ ");
1910         isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf,
1911                                                         &print_pwf_body, &data);
1912         p = data.p;
1913         p = isl_printer_print_str(p, " }");
1914         return p;
1915 }
1916
1917 __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold(
1918         __isl_take isl_printer *p,
1919         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
1920 {
1921         if (!p || !upwf)
1922                 goto error;
1923
1924         if (p->output_format == ISL_FORMAT_ISL)
1925                 return print_union_pw_qpolynomial_fold_isl(p, upwf);
1926         isl_die(p->ctx, isl_error_invalid,
1927                 "invalid output format for isl_union_pw_qpolynomial_fold",
1928                 goto error);
1929 error:
1930         isl_printer_free(p);
1931         return NULL;
1932 }