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