isl_printer_print_basic_{set,map}: add closing "}"
[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 <string.h>
14 #include <isl_set.h>
15 #include <isl_seq.h>
16 #include <isl_polynomial_private.h>
17 #include <isl_printer_private.h>
18
19 static __isl_give isl_printer *print_constraint_polylib(
20         struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p)
21 {
22         int i;
23         unsigned n_in = isl_basic_map_dim(bmap, isl_dim_in);
24         unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
25         unsigned nparam = isl_basic_map_dim(bmap, isl_dim_param);
26         isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n];
27
28         p = isl_printer_start_line(p);
29         p = isl_printer_print_int(p, ineq);
30         for (i = 0; i < n_out; ++i) {
31                 p = isl_printer_print_str(p, " ");
32                 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]);
33         }
34         for (i = 0; i < n_in; ++i) {
35                 p = isl_printer_print_str(p, " ");
36                 p = isl_printer_print_isl_int(p, c[1+nparam+i]);
37         }
38         for (i = 0; i < bmap->n_div; ++i) {
39                 p = isl_printer_print_str(p, " ");
40                 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]);
41         }
42         for (i = 0; i < nparam; ++i) {
43                 p = isl_printer_print_str(p, " ");
44                 p = isl_printer_print_isl_int(p, c[1+i]);
45         }
46         p = isl_printer_print_str(p, " ");
47         p = isl_printer_print_isl_int(p, c[0]);
48         p = isl_printer_end_line(p);
49         return p;
50 }
51
52 static __isl_give isl_printer *print_constraints_polylib(
53         struct isl_basic_map *bmap, __isl_take isl_printer *p)
54 {
55         int i;
56
57         p = isl_printer_set_isl_int_width(p, 5);
58
59         for (i = 0; i < bmap->n_eq; ++i)
60                 p = print_constraint_polylib(bmap, 0, i, p);
61         for (i = 0; i < bmap->n_ineq; ++i)
62                 p = print_constraint_polylib(bmap, 1, i, p);
63
64         return p;
65 }
66
67 static __isl_give isl_printer *bset_print_constraints_polylib(
68         struct isl_basic_set *bset, __isl_take isl_printer *p)
69 {
70         return print_constraints_polylib((struct isl_basic_map *)bset, p);
71 }
72
73 static __isl_give isl_printer *isl_basic_map_print_polylib(
74         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
75 {
76         unsigned total = isl_basic_map_total_dim(bmap);
77         p = isl_printer_start_line(p);
78         p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq);
79         p = isl_printer_print_str(p, " ");
80         p = isl_printer_print_int(p, 1 + total + 1);
81         p = isl_printer_end_line(p);
82         return print_constraints_polylib(bmap, p);
83 }
84
85 static __isl_give isl_printer *isl_basic_set_print_polylib(
86         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
87 {
88         return isl_basic_map_print_polylib((struct isl_basic_map *)bset, p);
89 }
90
91 static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map,
92         __isl_take isl_printer *p)
93 {
94         int i;
95
96         p = isl_printer_start_line(p);
97         p = isl_printer_print_int(p, map->n);
98         p = isl_printer_end_line(p);
99         for (i = 0; i < map->n; ++i) {
100                 p = isl_printer_start_line(p);
101                 p = isl_printer_end_line(p);
102                 p = isl_basic_map_print_polylib(map->p[i], p);
103         }
104         return p;
105 }
106
107 static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set,
108         __isl_take isl_printer *p)
109 {
110         return isl_map_print_polylib((struct isl_map *)set, p);
111 }
112
113 static int count_same_name(__isl_keep isl_dim *dim,
114         enum isl_dim_type type, unsigned pos, const char *name)
115 {
116         enum isl_dim_type t;
117         unsigned p, s;
118         int count = 0;
119
120         for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) {
121                 s = t == type ? pos : isl_dim_size(dim, t);
122                 for (p = 0; p < s; ++p) {
123                         const char *n = isl_dim_get_name(dim, t, p);
124                         if (n && !strcmp(n, name))
125                                 count++;
126                 }
127         }
128         return count;
129 }
130
131 static __isl_give isl_printer *print_name(__isl_keep isl_dim *dim,
132         __isl_take isl_printer *p, enum isl_dim_type type, unsigned pos, int set)
133 {
134         const char *name;
135         char buffer[20];
136         int primes;
137
138         name = type == isl_dim_div ? NULL : isl_dim_get_name(dim, type, pos);
139
140         if (!name) {
141                 const char *prefix;
142                 if (type == isl_dim_param)
143                         prefix = "p";
144                 else if (type == isl_dim_div)
145                         prefix = "e";
146                 else if (set || type == isl_dim_in)
147                         prefix = "i";
148                 else
149                         prefix = "o";
150                 snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);
151                 name = buffer;
152         }
153         primes = count_same_name(dim, name == buffer ? isl_dim_div : type,
154                                  pos, name);
155         p = isl_printer_print_str(p, name);
156         while (primes-- > 0)
157                 p = isl_printer_print_str(p, "'");
158         return p;
159 }
160
161 static __isl_give isl_printer *print_var_list(__isl_keep isl_dim *dim,
162         __isl_take isl_printer *p, enum isl_dim_type type, int set)
163 {
164         int i;
165
166         for (i = 0; i < isl_dim_size(dim, type); ++i) {
167                 if (i)
168                         p = isl_printer_print_str(p, ", ");
169                 p = print_name(dim, p, type, i, set);
170         }
171         return p;
172 }
173
174 static __isl_give isl_printer *print_tuple(__isl_keep isl_dim *dim,
175         __isl_take isl_printer *p, enum isl_dim_type type, int set)
176 {
177         p = isl_printer_print_str(p, "[");
178         p = print_var_list(dim, p, type, set);
179         p = isl_printer_print_str(p, "]");
180         return p;
181 }
182
183 static __isl_give isl_printer *print_omega_parameters(__isl_keep isl_dim *dim,
184         __isl_take isl_printer *p)
185 {
186         if (isl_dim_size(dim, isl_dim_param) == 0)
187                 return p;
188
189         p = isl_printer_start_line(p);
190         p = isl_printer_print_str(p, "symbolic ");
191         p = print_var_list(dim, p, isl_dim_param, 0);
192         p = isl_printer_print_str(p, ";");
193         p = isl_printer_end_line(p);
194         return p;
195 }
196
197 static enum isl_dim_type pos2type(__isl_keep isl_dim *dim, unsigned *pos)
198 {
199         enum isl_dim_type type;
200         unsigned n_in = isl_dim_size(dim, isl_dim_in);
201         unsigned n_out = isl_dim_size(dim, isl_dim_out);
202         unsigned nparam = isl_dim_size(dim, isl_dim_param);
203
204         if (*pos < 1 + nparam) {
205                 type = isl_dim_param;
206                 *pos -= 1;
207         } else if (*pos < 1 + nparam + n_in) {
208                 type = isl_dim_in;
209                 *pos -= 1 + nparam;
210         } else if (*pos < 1 + nparam + n_in + n_out) {
211                 type = isl_dim_out;
212                 *pos -= 1 + nparam + n_in;
213         } else {
214                 type = isl_dim_div;
215                 *pos -= 1 + nparam + n_in + n_out;
216         }
217
218         return type;
219 }
220
221 static __isl_give isl_printer *print_term(__isl_keep isl_dim *dim,
222                         isl_int c, unsigned pos, __isl_take isl_printer *p, int set)
223 {
224         enum isl_dim_type type;
225
226         if (pos == 0)
227                 return isl_printer_print_isl_int(p, c);
228
229         if (isl_int_is_one(c))
230                 ;
231         else if (isl_int_is_negone(c))
232                 p = isl_printer_print_str(p, "-");
233         else
234                 p = isl_printer_print_isl_int(p, c);
235         type = pos2type(dim, &pos);
236         p = print_name(dim, p, type, pos, set);
237         return p;
238 }
239
240 static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_dim *dim,
241         __isl_take isl_printer *p, isl_int *c, int len, int set)
242 {
243         int i;
244         int first;
245
246         for (i = 0, first = 1; i < len; ++i) {
247                 int flip = 0;
248                 if (isl_int_is_zero(c[i]))
249                         continue;
250                 if (!first) {
251                         if (isl_int_is_neg(c[i])) {
252                                 flip = 1;
253                                 isl_int_neg(c[i], c[i]);
254                                 p = isl_printer_print_str(p, " - ");
255                         } else 
256                                 p = isl_printer_print_str(p, " + ");
257                 }
258                 first = 0;
259                 p = print_term(dim, c[i], i, p, set);
260                 if (flip)
261                         isl_int_neg(c[i], c[i]);
262         }
263         if (first)
264                 p = isl_printer_print_str(p, "0");
265         return p;
266 }
267
268 static __isl_give isl_printer *print_affine(__isl_keep isl_basic_map *bmap,
269         __isl_keep isl_dim *dim, __isl_take isl_printer *p, isl_int *c, int set)
270 {
271         unsigned len = 1 + isl_basic_map_total_dim(bmap);
272         return print_affine_of_len(dim, p, c, len, set);
273 }
274
275 static __isl_give isl_printer *print_constraint(struct isl_basic_map *bmap,
276         __isl_keep isl_dim *dim, __isl_take isl_printer *p,
277         isl_int *c, int last, const char *op, int first_constraint, int set)
278 {
279         if (!first_constraint)
280                 p = isl_printer_print_str(p, " and ");
281
282         isl_int_abs(c[last], c[last]);
283
284         p = print_term(dim, c[last], last, p, set);
285
286         p = isl_printer_print_str(p, " ");
287         p = isl_printer_print_str(p, op);
288         p = isl_printer_print_str(p, " ");
289
290         isl_int_set_si(c[last], 0);
291         p = print_affine(bmap, dim, p, c, set);
292
293         return p;
294 }
295
296 static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
297         __isl_keep isl_dim *dim, __isl_take isl_printer *p, int set)
298 {
299         int i;
300         struct isl_vec *c;
301         unsigned total = isl_basic_map_total_dim(bmap);
302
303         c = isl_vec_alloc(bmap->ctx, 1 + total);
304         if (!c)
305                 goto error;
306
307         for (i = bmap->n_eq - 1; i >= 0; --i) {
308                 int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total);
309                 isl_assert(bmap->ctx, l >= 0, goto error);
310                 if (isl_int_is_neg(bmap->eq[i][l]))
311                         isl_seq_cpy(c->el, bmap->eq[i], 1 + total);
312                 else
313                         isl_seq_neg(c->el, bmap->eq[i], 1 + total);
314                 p = print_constraint(bmap, dim, p, c->el, l,
315                                     "=", i == bmap->n_eq - 1, set);
316         }
317         for (i = 0; i < bmap->n_ineq; ++i) {
318                 int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);
319                 int s;
320                 isl_assert(bmap->ctx, l >= 0, goto error);
321                 s = isl_int_sgn(bmap->ineq[i][l]);
322                 if (s < 0)
323                         isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);
324                 else
325                         isl_seq_neg(c->el, bmap->ineq[i], 1 + total);
326                 p = print_constraint(bmap, dim, p, c->el, l,
327                                     s < 0 ? "<=" : ">=", !bmap->n_eq && !i, set);
328         }
329
330         isl_vec_free(c);
331
332         return p;
333 error:
334         isl_printer_free(p);
335         return NULL;
336 }
337
338 static __isl_give isl_printer *print_omega_constraints(
339         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int set)
340 {
341         if (bmap->n_eq + bmap->n_ineq == 0)
342                 return p;
343
344         p = isl_printer_print_str(p, ": ");
345         if (bmap->n_div > 0) {
346                 int i;
347                 p = isl_printer_print_str(p, "exists (");
348                 for (i = 0; i < bmap->n_div; ++i) {
349                         if (i)
350                                 p = isl_printer_print_str(p, ", ");
351                         p = print_name(bmap->dim, p, isl_dim_div, i, 0);
352                 }
353                 p = isl_printer_print_str(p, ": ");
354         }
355         p = print_constraints(bmap, bmap->dim, p, set);
356         if (bmap->n_div > 0)
357                 p = isl_printer_print_str(p, ")");
358         return p;
359 }
360
361 static __isl_give isl_printer *basic_map_print_omega(
362         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
363 {
364         p = isl_printer_print_str(p, "{ [");
365         p = print_var_list(bmap->dim, p, isl_dim_in, 0);
366         p = isl_printer_print_str(p, "] -> [");
367         p = print_var_list(bmap->dim, p, isl_dim_out, 0);
368         p = isl_printer_print_str(p, "] ");
369         p = print_omega_constraints(bmap, p, 0);
370         p = isl_printer_print_str(p, " }");
371         return p;
372 }
373
374 static __isl_give isl_printer *isl_basic_map_print_omega(
375         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
376 {
377         p = print_omega_parameters(bmap->dim, p);
378
379         p = isl_printer_start_line(p);
380         p = basic_map_print_omega(bmap, p);
381         p = isl_printer_end_line(p);
382         return p;
383 }
384
385 static __isl_give isl_printer *basic_set_print_omega(
386         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
387 {
388         p = isl_printer_print_str(p, "{ [");
389         p = print_var_list(bset->dim, p, isl_dim_set, 1);
390         p = isl_printer_print_str(p, "] ");
391         p = print_omega_constraints((isl_basic_map *)bset, p, 1);
392         p = isl_printer_print_str(p, " }");
393         return p;
394 }
395
396 static __isl_give isl_printer *isl_basic_set_print_omega(
397         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
398 {
399         p = print_omega_parameters(bset->dim, p);
400
401         p = isl_printer_start_line(p);
402         p = basic_set_print_omega(bset, p);
403         p = isl_printer_end_line(p);
404         return p;
405 }
406
407 static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map,
408         __isl_take isl_printer *p)
409 {
410         int i;
411
412         p = print_omega_parameters(map->dim, p);
413
414         p = isl_printer_start_line(p);
415         for (i = 0; i < map->n; ++i) {
416                 if (i)
417                         p = isl_printer_print_str(p, " union ");
418                 p = basic_map_print_omega(map->p[i], p);
419         }
420         p = isl_printer_end_line(p);
421         return p;
422 }
423
424 static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set,
425         __isl_take isl_printer *p)
426 {
427         int i;
428
429         p = print_omega_parameters(set->dim, p);
430
431         p = isl_printer_start_line(p);
432         for (i = 0; i < set->n; ++i) {
433                 if (i)
434                         p = isl_printer_print_str(p, " union ");
435                 p = basic_set_print_omega(set->p[i], p);
436         }
437         p = isl_printer_end_line(p);
438         return p;
439 }
440
441 static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
442         __isl_keep isl_dim *dim, __isl_take isl_printer *p, int set)
443 {
444         if (bmap->n_div > 0) {
445                 int i;
446                 p = isl_printer_print_str(p, "exists (");
447                 for (i = 0; i < bmap->n_div; ++i) {
448                         if (i)
449                                 p = isl_printer_print_str(p, ", ");
450                         p = print_name(dim, p, isl_dim_div, i, 0);
451                         if (isl_int_is_zero(bmap->div[i][0]))
452                                 continue;
453                         p = isl_printer_print_str(p, " = [(");
454                         p = print_affine(bmap, dim, p, bmap->div[i] + 1, set);
455                         p = isl_printer_print_str(p, ")/");
456                         p = isl_printer_print_isl_int(p, bmap->div[i][0]);
457                         p = isl_printer_print_str(p, "]");
458                 }
459                 p = isl_printer_print_str(p, ": ");
460         }
461
462         p = print_constraints(bmap, dim, p, set);
463
464         if (bmap->n_div > 0)
465                 p = isl_printer_print_str(p, ")");
466         return p;
467 }
468
469 static __isl_give isl_printer *isl_basic_map_print_isl(
470         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
471 {
472         int i;
473
474         p = isl_printer_start_line(p);
475         if (isl_basic_map_dim(bmap, isl_dim_param) > 0) {
476                 p = print_tuple(bmap->dim, p, isl_dim_param, 0);
477                 p = isl_printer_print_str(p, " -> ");
478         }
479         p = isl_printer_print_str(p, "{ ");
480         p = print_tuple(bmap->dim, p, isl_dim_in, 0);
481         p = isl_printer_print_str(p, " -> ");
482         p = print_tuple(bmap->dim, p, isl_dim_out, 0);
483         p = isl_printer_print_str(p, " : ");
484         p = print_disjunct(bmap, bmap->dim, p, 0);
485         p = isl_printer_print_str(p, " }");
486         p = isl_printer_end_line(p);
487         return p;
488 }
489
490 static __isl_give isl_printer *isl_basic_set_print_isl(
491         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
492 {
493         int i;
494
495         p = isl_printer_start_line(p);
496         if (isl_basic_set_dim(bset, isl_dim_param) > 0) {
497                 p = print_tuple(bset->dim, p, isl_dim_param, 0);
498                 p = isl_printer_print_str(p, " -> ");
499         }
500         p = isl_printer_print_str(p, "{ ");
501         p = print_tuple(bset->dim, p, isl_dim_set, 1);
502         p = isl_printer_print_str(p, " : ");
503         p = print_disjunct((isl_basic_map *)bset, bset->dim, p, 1);
504         p = isl_printer_print_str(p, " }");
505         p = isl_printer_end_line(p);
506         return p;
507 }
508
509 static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
510         __isl_take isl_printer *p, int set)
511 {
512         int i;
513
514         if (isl_map_fast_is_universe(map))
515                 return p;
516
517         p = isl_printer_print_str(p, " : ");
518         if (map->n == 0)
519                 p = isl_printer_print_str(p, "1 = 0");
520         for (i = 0; i < map->n; ++i) {
521                 if (i)
522                         p = isl_printer_print_str(p, " or ");
523                 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
524                         p = isl_printer_print_str(p, "(");
525                 p = print_disjunct(map->p[i], map->dim, p, set);
526                 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
527                         p = isl_printer_print_str(p, ")");
528         }
529         return p;
530 }
531
532 static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,
533         __isl_take isl_printer *p)
534 {
535         if (isl_map_dim(map, isl_dim_param) > 0) {
536                 p = print_tuple(map->dim, p, isl_dim_param, 0);
537                 p = isl_printer_print_str(p, " -> ");
538         }
539         p = isl_printer_print_str(p, "{ ");
540         p = print_tuple(map->dim, p, isl_dim_in, 0);
541         p = isl_printer_print_str(p, " -> ");
542         p = print_tuple(map->dim, p, isl_dim_out, 0);
543         p = print_disjuncts(map, p, 0);
544         p = isl_printer_print_str(p, " }");
545         return p;
546 }
547
548 static __isl_give isl_printer *isl_set_print_isl(__isl_keep isl_set *set,
549         __isl_take isl_printer *p)
550 {
551         int i;
552
553         if (isl_set_dim(set, isl_dim_param) > 0) {
554                 p = print_tuple(set->dim, p, isl_dim_param, 0);
555                 p = isl_printer_print_str(p, " -> ");
556         }
557         p = isl_printer_print_str(p, "{ ");
558         p = print_tuple(set->dim, p, isl_dim_set, 1);
559         p = print_disjuncts((isl_map *)set, p, 1);
560         p = isl_printer_print_str(p, " }");
561         return p;
562 }
563
564 __isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p,
565         __isl_keep isl_basic_map *bmap)
566 {
567         if (!p || !bmap)
568                 goto error;
569         if (p->output_format == ISL_FORMAT_ISL)
570                 return isl_basic_map_print_isl(bmap, p);
571         else if (p->output_format == ISL_FORMAT_OMEGA)
572                 return isl_basic_map_print_omega(bmap, p);
573         isl_assert(bmap->ctx, 0, goto error);
574 error:
575         isl_printer_free(p);
576         return NULL;
577 }
578
579 void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent,
580         const char *prefix, const char *suffix, unsigned output_format)
581 {
582         isl_printer *printer;
583
584         if (!bmap)
585                 return;
586
587         printer = isl_printer_to_file(bmap->ctx, out);
588         printer = isl_printer_set_indent(printer, indent);
589         printer = isl_printer_set_prefix(printer, prefix);
590         printer = isl_printer_set_suffix(printer, suffix);
591         printer = isl_printer_set_output_format(printer, output_format);
592         isl_printer_print_basic_map(printer, bmap);
593
594         isl_printer_free(printer);
595 }
596
597 __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,
598         __isl_keep isl_basic_set *bset)
599 {
600         if (!p || !bset)
601                 goto error;
602
603         if (p->output_format == ISL_FORMAT_ISL)
604                 return isl_basic_set_print_isl(bset, p);
605         else if (p->output_format == ISL_FORMAT_POLYLIB)
606                 return isl_basic_set_print_polylib(bset, p);
607         else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)
608                 return bset_print_constraints_polylib(bset, p);
609         else if (p->output_format == ISL_FORMAT_OMEGA)
610                 return isl_basic_set_print_omega(bset, p);
611         isl_assert(p->ctx, 0, goto error);
612 error:
613         isl_printer_free(p);
614         return NULL;
615 }
616
617 void isl_basic_set_print(struct isl_basic_set *bset, FILE *out, int indent,
618         const char *prefix, const char *suffix, unsigned output_format)
619 {
620         isl_printer *printer;
621
622         if (!bset)
623                 return;
624
625         printer = isl_printer_to_file(bset->ctx, out);
626         printer = isl_printer_set_indent(printer, indent);
627         printer = isl_printer_set_prefix(printer, prefix);
628         printer = isl_printer_set_suffix(printer, suffix);
629         printer = isl_printer_set_output_format(printer, output_format);
630         isl_printer_print_basic_set(printer, bset);
631
632         isl_printer_free(printer);
633 }
634
635 __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,
636         __isl_keep isl_set *set)
637 {
638         if (!p || !set)
639                 goto error;
640         if (p->output_format == ISL_FORMAT_ISL)
641                 return isl_set_print_isl(set, p);
642         else if (p->output_format == ISL_FORMAT_POLYLIB)
643                 return isl_set_print_polylib(set, p);
644         else if (p->output_format == ISL_FORMAT_OMEGA)
645                 return isl_set_print_omega(set, p);
646         isl_assert(set->ctx, 0, goto error);
647 error:
648         isl_printer_free(p);
649         return NULL;
650 }
651
652 void isl_set_print(struct isl_set *set, FILE *out, int indent,
653         unsigned output_format)
654 {
655         isl_printer *printer;
656
657         if (!set)
658                 return;
659
660         printer = isl_printer_to_file(set->ctx, out);
661         printer = isl_printer_set_indent(printer, indent);
662         printer = isl_printer_set_output_format(printer, output_format);
663         printer = isl_printer_print_set(printer, set);
664
665         isl_printer_free(printer);
666 }
667
668 __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
669         __isl_keep isl_map *map)
670 {
671         if (!p || !map)
672                 goto error;
673
674         if (p->output_format == ISL_FORMAT_ISL)
675                 return isl_map_print_isl(map, p);
676         else if (p->output_format == ISL_FORMAT_POLYLIB)
677                 return isl_map_print_polylib(map, p);
678         else if (p->output_format == ISL_FORMAT_OMEGA)
679                 return isl_map_print_omega(map, p);
680         isl_assert(map->ctx, 0, goto error);
681 error:
682         isl_printer_free(p);
683         return NULL;
684 }
685
686 void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent,
687         unsigned output_format)
688 {
689         isl_printer *printer;
690
691         if (!map)
692                 return;
693
694         printer = isl_printer_to_file(map->ctx, out);
695         printer = isl_printer_set_indent(printer, indent);
696         printer = isl_printer_set_output_format(printer, output_format);
697         printer = isl_printer_print_map(printer, map);
698
699         isl_printer_free(printer);
700 }
701
702 static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec)
703 {
704         int i;
705         int n;
706
707         for (i = 0, n = 0; i < rec->n; ++i)
708                 if (!isl_upoly_is_zero(rec->p[i]))
709                         ++n;
710
711         return n;
712 }
713
714 static __isl_give isl_printer *print_div(__isl_keep isl_dim *dim,
715         __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p)
716 {
717         int c = p->output_format == ISL_FORMAT_C;
718         p = isl_printer_print_str(p, c ? "floord(" : "[(");
719         p = print_affine_of_len(dim, p, div->row[pos] + 1, div->n_col - 1, 1);
720         p = isl_printer_print_str(p, c ? ", " : ")/");
721         p = isl_printer_print_isl_int(p, div->row[pos][0]);
722         p = isl_printer_print_str(p, c ? ")" : "]");
723         return p;
724 }
725
726 static __isl_give isl_printer *upoly_print_cst(__isl_keep struct isl_upoly *up,
727         __isl_take isl_printer *p, int first)
728 {
729         struct isl_upoly_cst *cst;
730         int neg;
731
732         cst = isl_upoly_as_cst(up);
733         if (!cst)
734                 goto error;
735         neg = !first && isl_int_is_neg(cst->n);
736         if (!first)
737                 p = isl_printer_print_str(p, neg ? " - " :  " + ");
738         if (neg)
739                 isl_int_neg(cst->n, cst->n);
740         if (isl_int_is_zero(cst->d)) {
741                 int sgn = isl_int_sgn(cst->n);
742                 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
743                                             sgn == 0 ? "NaN" : "infty");
744         } else
745                 p = isl_printer_print_isl_int(p, cst->n);
746         if (neg)
747                 isl_int_neg(cst->n, cst->n);
748         if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) {
749                 p = isl_printer_print_str(p, "/");
750                 p = isl_printer_print_isl_int(p, cst->d);
751         }
752         return p;
753 error:
754         isl_printer_free(p);
755         return NULL;
756 }
757
758 static __isl_give isl_printer *print_base(__isl_take isl_printer *p,
759         __isl_keep isl_dim *dim, __isl_keep isl_mat *div, int var)
760 {
761         unsigned total;
762
763         total = isl_dim_total(dim);
764         if (var < total)
765                 p = print_term(dim, dim->ctx->one, 1 + var, p, 1);
766         else
767                 p = print_div(dim, div, var - total, p);
768         return p;
769 }
770
771 static __isl_give isl_printer *print_pow(__isl_take isl_printer *p,
772         __isl_keep isl_dim *dim, __isl_keep isl_mat *div, int var, int exp)
773 {
774         p = print_base(p, dim, div, var);
775         if (exp == 1)
776                 return p;
777         if (p->output_format == ISL_FORMAT_C) {
778                 int i;
779                 for (i = 1; i < exp; ++i) {
780                         p = isl_printer_print_str(p, "*");
781                         p = print_base(p, dim, div, var);
782                 }
783         } else {
784                 p = isl_printer_print_str(p, "^");
785                 p = isl_printer_print_int(p, exp);
786         }
787         return p;
788 }
789
790 static __isl_give isl_printer *upoly_print(__isl_keep struct isl_upoly *up,
791         __isl_keep isl_dim *dim, __isl_keep isl_mat *div,
792         __isl_take isl_printer *p)
793 {
794         int i, n, first;
795         struct isl_upoly_rec *rec;
796
797         if (!p || !up || !dim || !div)
798                 goto error;
799
800         if (isl_upoly_is_cst(up))
801                 return upoly_print_cst(up, p, 1);
802
803         rec = isl_upoly_as_rec(up);
804         if (!rec)
805                 goto error;
806         n = upoly_rec_n_non_zero(rec);
807         if (n > 1)
808                 p = isl_printer_print_str(p, "(");
809         for (i = 0, first = 1; i < rec->n; ++i) {
810                 if (isl_upoly_is_zero(rec->p[i]))
811                         continue;
812                 if (isl_upoly_is_negone(rec->p[i])) {
813                         if (!i)
814                                 p = isl_printer_print_str(p, "-1");
815                         else if (first)
816                                 p = isl_printer_print_str(p, "-");
817                         else
818                                 p = isl_printer_print_str(p, " - ");
819                 } else if (isl_upoly_is_cst(rec->p[i]) &&
820                                 !isl_upoly_is_one(rec->p[i]))
821                         p = upoly_print_cst(rec->p[i], p, first);
822                 else {
823                         if (!first)
824                                 p = isl_printer_print_str(p, " + ");
825                         if (i == 0 || !isl_upoly_is_one(rec->p[i]))
826                                 p = upoly_print(rec->p[i], dim, div, p);
827                 }
828                 first = 0;
829                 if (i == 0)
830                         continue;
831                 if (!isl_upoly_is_one(rec->p[i]) &&
832                     !isl_upoly_is_negone(rec->p[i]))
833                         p = isl_printer_print_str(p, " * ");
834                 p = print_pow(p, dim, div, rec->up.var, i);
835         }
836         if (n > 1)
837                 p = isl_printer_print_str(p, ")");
838         return p;
839 error:
840         isl_printer_free(p);
841         return NULL;
842 }
843
844 __isl_give isl_printer *isl_printer_print_qpolynomial(__isl_take isl_printer *p,
845         __isl_keep isl_qpolynomial *qp)
846 {
847         if (!p || !qp)
848                 goto error;
849         p = upoly_print(qp->upoly, qp->dim, qp->div, p);
850         return p;
851 error:
852         isl_printer_free(p);
853         return NULL;
854 }
855
856 void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
857         unsigned output_format)
858 {
859         isl_printer *p;
860
861         if  (!qp)
862                 return;
863
864         isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);
865         p = isl_printer_to_file(qp->dim->ctx, out);
866         p = isl_printer_print_qpolynomial(p, qp);
867         isl_printer_free(p);
868 }
869
870 static __isl_give isl_printer *qpolynomial_fold_print(
871         __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
872 {
873         int i;
874
875         if (fold->type == isl_fold_min)
876                 p = isl_printer_print_str(p, "min");
877         else if (fold->type == isl_fold_max)
878                 p = isl_printer_print_str(p, "max");
879         p = isl_printer_print_str(p, "(");
880         for (i = 0; i < fold->n; ++i) {
881                 if (i)
882                         p = isl_printer_print_str(p, ", ");
883                 p = isl_printer_print_qpolynomial(p, fold->qp[i]);
884         }
885         p = isl_printer_print_str(p, ")");
886         return p;
887 }
888
889 __isl_give isl_printer *isl_printer_print_qpolynomial_fold(
890         __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
891 {
892         if  (!p || !fold)
893                 goto error;
894         p = qpolynomial_fold_print(fold, p);
895         return p;
896 error:
897         isl_printer_free(p);
898         return NULL;
899 }
900
901 void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
902         FILE *out, unsigned output_format)
903 {
904         isl_printer *p;
905
906         if (!fold)
907                 return;
908
909         isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);
910
911         p = isl_printer_to_file(fold->dim->ctx, out);
912         p = isl_printer_print_qpolynomial_fold(p, fold);
913
914         isl_printer_free(p);
915 }
916
917 static __isl_give isl_printer *print_pw_qpolynomial_isl(
918         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
919 {
920         int i = 0;
921
922         if (!p || !pwqp)
923                 goto error;
924
925         if (isl_dim_size(pwqp->dim, isl_dim_param) > 0) {
926                 p = print_tuple(pwqp->dim, p, isl_dim_param, 0);
927                 p = isl_printer_print_str(p, " -> ");
928         }
929         p = isl_printer_print_str(p, "{ ");
930         if (pwqp->n == 0) {
931                 if (isl_dim_size(pwqp->dim, isl_dim_set) > 0) {
932                         p = print_tuple(pwqp->dim, p, isl_dim_set, 1);
933                         p = isl_printer_print_str(p, " -> ");
934                 }
935                 p = isl_printer_print_str(p, "0");
936         }
937         for (i = 0; i < pwqp->n; ++i) {
938                 if (i)
939                         p = isl_printer_print_str(p, "; ");
940                 if (isl_dim_size(pwqp->p[i].set->dim, isl_dim_set) > 0) {
941                         p = print_tuple(pwqp->p[i].set->dim, p, isl_dim_set, 1);
942                         p = isl_printer_print_str(p, " -> ");
943                 }
944                 p = isl_printer_print_qpolynomial(p, pwqp->p[i].qp);
945                 p = print_disjuncts((isl_map *)pwqp->p[i].set, p, 1);
946         }
947         p = isl_printer_print_str(p, " }");
948         return p;
949 error:
950         isl_printer_free(p);
951         return NULL;
952 }
953
954 void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
955         unsigned output_format)
956 {
957         isl_printer *p;
958
959         if (!pwqp)
960                 return;
961
962         p = isl_printer_to_file(pwqp->dim->ctx, out);
963         p = isl_printer_set_output_format(p, output_format);
964         p = isl_printer_print_pw_qpolynomial(p, pwqp);
965
966         isl_printer_free(p);
967 }
968
969 static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(
970         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
971 {
972         int i = 0;
973
974         if (isl_dim_size(pwf->dim, isl_dim_param) > 0) {
975                 p = print_tuple(pwf->dim, p, isl_dim_param, 0);
976                 p = isl_printer_print_str(p, " -> ");
977         }
978         p = isl_printer_print_str(p, "{ ");
979         if (pwf->n == 0) {
980                 if (isl_dim_size(pwf->dim, isl_dim_set) > 0) {
981                         p = print_tuple(pwf->dim, p, isl_dim_set, 0);
982                         p = isl_printer_print_str(p, " -> ");
983                 }
984                 p = isl_printer_print_str(p, "0");
985         }
986         for (i = 0; i < pwf->n; ++i) {
987                 if (i)
988                         p = isl_printer_print_str(p, "; ");
989                 if (isl_dim_size(pwf->p[i].set->dim, isl_dim_set) > 0) {
990                         p = print_tuple(pwf->p[i].set->dim, p, isl_dim_set, 0);
991                         p = isl_printer_print_str(p, " -> ");
992                 }
993                 p = qpolynomial_fold_print(pwf->p[i].fold, p);
994                 p = print_disjuncts((isl_map *)pwf->p[i].set, p, 1);
995         }
996         p = isl_printer_print_str(p, " }");
997         return p;
998 }
999
1000 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1001         __isl_keep isl_basic_set *bset, isl_int *c);
1002
1003 static __isl_give isl_printer *print_name_c(__isl_take isl_printer *p,
1004         __isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos)
1005 {
1006         if (type == isl_dim_div) {
1007                 p = isl_printer_print_str(p, "floord(");
1008                 p = print_affine_c(p, bset, bset->div[pos] + 1);
1009                 p = isl_printer_print_str(p, ", ");
1010                 p = isl_printer_print_isl_int(p, bset->div[pos][0]);
1011                 p = isl_printer_print_str(p, ")");
1012         } else {
1013                 const char *name;
1014
1015                 name = isl_dim_get_name(bset->dim, type, pos);
1016                 if (!name)
1017                         name = "UNNAMED";
1018                 p = isl_printer_print_str(p, name);
1019         }
1020         return p;
1021 }
1022
1023 static __isl_give isl_printer *print_term_c(__isl_take isl_printer *p,
1024         __isl_keep isl_basic_set *bset, isl_int c, unsigned pos)
1025 {
1026         enum isl_dim_type type;
1027         unsigned nparam = isl_basic_set_dim(bset, isl_dim_param);
1028
1029         if (pos == 0)
1030                 return isl_printer_print_isl_int(p, c);
1031
1032         if (isl_int_is_one(c))
1033                 ;
1034         else if (isl_int_is_negone(c))
1035                 p = isl_printer_print_str(p, "-");
1036         else {
1037                 p = isl_printer_print_isl_int(p, c);
1038                 p = isl_printer_print_str(p, "*");
1039         }
1040         type = pos2type(bset->dim, &pos);
1041         p = print_name_c(p, bset, type, pos);
1042         return p;
1043 }
1044
1045 static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
1046         __isl_keep isl_basic_set *bset, isl_int *c)
1047 {
1048         int i;
1049         int first;
1050         unsigned len = 1 + isl_basic_set_total_dim(bset);
1051
1052         for (i = 0, first = 1; i < len; ++i) {
1053                 int flip = 0;
1054                 if (isl_int_is_zero(c[i]))
1055                         continue;
1056                 if (!first) {
1057                         if (isl_int_is_neg(c[i])) {
1058                                 flip = 1;
1059                                 isl_int_neg(c[i], c[i]);
1060                                 p = isl_printer_print_str(p, " - ");
1061                         } else 
1062                                 p = isl_printer_print_str(p, " + ");
1063                 }
1064                 first = 0;
1065                 p = print_term(bset->dim, c[i], i, p, 1);
1066                 if (flip)
1067                         isl_int_neg(c[i], c[i]);
1068         }
1069         if (first)
1070                 p = isl_printer_print_str(p, "0");
1071         return p;
1072 }
1073
1074 static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,
1075         __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int first)
1076 {
1077         if (!first)
1078                 p = isl_printer_print_str(p, " && ");
1079
1080         p = print_affine_c(p, bset, c);
1081         p = isl_printer_print_str(p, " ");
1082         p = isl_printer_print_str(p, op);
1083         p = isl_printer_print_str(p, " 0");
1084         return p;
1085 }
1086
1087 static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,
1088         __isl_keep isl_basic_set *bset)
1089 {
1090         int i;
1091
1092         for (i = 0; i < bset->n_eq; ++i)
1093                 p = print_constraint_c(p, bset, bset->eq[i], "==", !i);
1094         for (i = 0; i < bset->n_ineq; ++i)
1095                 p = print_constraint_c(p, bset, bset->ineq[i], ">=",
1096                                         !bset->n_eq && !i);
1097         return p;
1098 }
1099
1100 static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,
1101         __isl_keep isl_set *set)
1102 {
1103         int i;
1104
1105         if (set->n == 0)
1106                 p = isl_printer_print_str(p, "0");
1107
1108         for (i = 0; i < set->n; ++i) {
1109                 if (i)
1110                         p = isl_printer_print_str(p, " || ");
1111                 if (set->n > 1)
1112                         p = isl_printer_print_str(p, "(");
1113                 p = print_basic_set_c(p, set->p[i]);
1114                 if (set->n > 1)
1115                         p = isl_printer_print_str(p, ")");
1116         }
1117         return p;
1118 }
1119
1120 static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p,
1121         __isl_keep isl_qpolynomial *qp)
1122 {
1123         isl_int den;
1124
1125         isl_int_init(den);
1126         isl_qpolynomial_get_den(qp, &den);
1127         if (!isl_int_is_one(den)) {
1128                 isl_qpolynomial *f;
1129                 p = isl_printer_print_str(p, "(");
1130                 qp = isl_qpolynomial_copy(qp);
1131                 f = isl_qpolynomial_rat_cst(isl_dim_copy(qp->dim),
1132                                                 den, qp->dim->ctx->one);
1133                 qp = isl_qpolynomial_mul(qp, f);
1134         }
1135         if (qp)
1136                 p = upoly_print(qp->upoly, qp->dim, qp->div, p);
1137         if (!isl_int_is_one(den)) {
1138                 p = isl_printer_print_str(p, ")/");
1139                 p = isl_printer_print_isl_int(p, den);
1140                 isl_qpolynomial_free(qp);
1141         }
1142         isl_int_clear(den);
1143         return p;
1144 }
1145
1146 static __isl_give isl_printer *print_pw_qpolynomial_c(
1147         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwpq)
1148 {
1149         int i;
1150
1151         if (pwpq->n == 1 && isl_set_fast_is_universe(pwpq->p[0].set))
1152                 return print_qpolynomial_c(p, pwpq->p[0].qp);
1153
1154         for (i = 0; i < pwpq->n; ++i) {
1155                 p = isl_printer_print_str(p, "(");
1156                 p = print_set_c(p, pwpq->p[i].set);
1157                 p = isl_printer_print_str(p, ") ? (");
1158                 p = print_qpolynomial_c(p, pwpq->p[i].qp);
1159                 p = isl_printer_print_str(p, ") : ");
1160         }
1161
1162         p = isl_printer_print_str(p, "0");
1163         return p;
1164 }
1165
1166 __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
1167         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
1168 {
1169         if (!p || !pwqp)
1170                 goto error;
1171
1172         if (p->output_format == ISL_FORMAT_ISL)
1173                 return print_pw_qpolynomial_isl(p, pwqp);
1174         else if (p->output_format == ISL_FORMAT_C)
1175                 return print_pw_qpolynomial_c(p, pwqp);
1176         isl_assert(p->ctx, 0, goto error);
1177 error:
1178         isl_printer_free(p);
1179         return NULL;
1180 }
1181
1182 static __isl_give isl_printer *print_qpolynomial_fold_c(
1183         __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
1184 {
1185         int i;
1186
1187         for (i = 0; i < fold->n - 1; ++i)
1188                 if (fold->type == isl_fold_min)
1189                         p = isl_printer_print_str(p, "min(");
1190                 else if (fold->type == isl_fold_max)
1191                         p = isl_printer_print_str(p, "max(");
1192
1193         for (i = 0; i < fold->n; ++i) {
1194                 if (i)
1195                         p = isl_printer_print_str(p, ", ");
1196                 p = print_qpolynomial_c(p, fold->qp[i]);
1197                 if (i)
1198                         p = isl_printer_print_str(p, ")");
1199         }
1200         return p;
1201 }
1202
1203 static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
1204         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1205 {
1206         int i;
1207
1208         if (pwf->n == 1 && isl_set_fast_is_universe(pwf->p[0].set))
1209                 return print_qpolynomial_fold_c(p, pwf->p[0].fold);
1210
1211         for (i = 0; i < pwf->n; ++i) {
1212                 p = isl_printer_print_str(p, "(");
1213                 p = print_set_c(p, pwf->p[i].set);
1214                 p = isl_printer_print_str(p, ") ? (");
1215                 p = print_qpolynomial_fold_c(p, pwf->p[i].fold);
1216                 p = isl_printer_print_str(p, ") : ");
1217         }
1218
1219         p = isl_printer_print_str(p, "0");
1220         return p;
1221 }
1222
1223 __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
1224         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
1225 {
1226         if (!p || !pwf)
1227                 goto error;
1228
1229         if (p->output_format == ISL_FORMAT_ISL)
1230                 return print_pw_qpolynomial_fold_isl(p, pwf);
1231         else if (p->output_format == ISL_FORMAT_C)
1232                 return print_pw_qpolynomial_fold_c(p, pwf);
1233         isl_assert(p->ctx, 0, goto error);
1234 error:
1235         isl_printer_free(p);
1236         return NULL;
1237 }
1238
1239 void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
1240         FILE *out, unsigned output_format)
1241 {
1242         isl_printer *p;
1243
1244         if (!pwf)
1245                 return;
1246
1247         p = isl_printer_to_file(pwf->dim->ctx, out);
1248         p = isl_printer_set_output_format(p, output_format);
1249         p = isl_printer_print_pw_qpolynomial_fold(p, pwf);
1250
1251         isl_printer_free(p);
1252 }