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