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