LCOV - code coverage report
Current view: top level - metalib_isl - isl_output.c (source / functions) Hit Total Coverage
Test: 2018-10-31_point_maint_greina16.lcov Lines: 243 1719 14.1 %
Date: 2018-11-01 11:27:00 Functions: 26 151 17.2 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2008-2009 Katholieke Universiteit Leuven
       3             :  * Copyright 2010      INRIA Saclay
       4             :  * Copyright 2012-2013 Ecole Normale Superieure
       5             :  *
       6             :  * Use of this software is governed by the MIT license
       7             :  *
       8             :  * Written by Sven Verdoolaege, K.U.Leuven, Departement
       9             :  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
      10             :  * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
      11             :  * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France 
      12             :  * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
      13             :  */
      14             : 
      15             : #include <stdlib.h>
      16             : #include <string.h>
      17             : #include <isl_ctx_private.h>
      18             : #include <isl_map_private.h>
      19             : #include <isl/set.h>
      20             : #include <isl_seq.h>
      21             : #include <isl_polynomial_private.h>
      22             : #include <isl_printer_private.h>
      23             : #include <isl_space_private.h>
      24             : #include <isl_mat_private.h>
      25             : #include <isl_vec_private.h>
      26             : #include <isl/union_set.h>
      27             : #include <isl/union_map.h>
      28             : #include <isl/constraint.h>
      29             : #include <isl_local_space_private.h>
      30             : #include <isl_aff_private.h>
      31             : #include <isl_val_private.h>
      32             : #include <isl_constraint_private.h>
      33             : #include <isl/ast_build.h>
      34             : #include <isl_sort.h>
      35             : #include <isl_output_private.h>
      36             : 
      37             : #include <bset_to_bmap.c>
      38             : #include <set_to_map.c>
      39             : #include <uset_to_umap.c>
      40             : 
      41             : static const char *s_to[2] = { " -> ", " \\to " };
      42             : static const char *s_and[2] = { " and ", " \\wedge " };
      43             : static const char *s_or[2] = { " or ", " \\vee " };
      44             : static const char *s_le[2] = { "<=", "\\le" };
      45             : static const char *s_ge[2] = { ">=", "\\ge" };
      46             : static const char *s_open_set[2] = { "{ ", "\\{\\, " };
      47             : static const char *s_close_set[2] = { " }", " \\,\\}" };
      48             : static const char *s_open_list[2] = { "[", "(" };
      49             : static const char *s_close_list[2] = { "]", ")" };
      50             : static const char *s_such_that[2] = { " : ", " \\mid " };
      51             : static const char *s_open_exists[2] = { "exists (", "\\exists \\, " };
      52             : static const char *s_close_exists[2] = { ")", "" };
      53             : static const char *s_div_prefix[2] = { "e", "\\alpha_" };
      54             : static const char *s_mod[2] = { "mod", "\\bmod" };
      55             : static const char *s_param_prefix[2] = { "p", "p_" };
      56             : static const char *s_input_prefix[2] = { "i", "i_" };
      57             : static const char *s_output_prefix[2] = { "o", "o_" };
      58             : 
      59           0 : static __isl_give isl_printer *print_constraint_polylib(
      60             :         struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p)
      61             : {
      62             :         int i;
      63           0 :         unsigned n_in = isl_basic_map_dim(bmap, isl_dim_in);
      64           0 :         unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out);
      65           0 :         unsigned nparam = isl_basic_map_dim(bmap, isl_dim_param);
      66           0 :         isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n];
      67             : 
      68           0 :         p = isl_printer_start_line(p);
      69           0 :         p = isl_printer_print_int(p, ineq);
      70           0 :         for (i = 0; i < n_out; ++i) {
      71           0 :                 p = isl_printer_print_str(p, " ");
      72           0 :                 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]);
      73             :         }
      74           0 :         for (i = 0; i < n_in; ++i) {
      75           0 :                 p = isl_printer_print_str(p, " ");
      76           0 :                 p = isl_printer_print_isl_int(p, c[1+nparam+i]);
      77             :         }
      78           0 :         for (i = 0; i < bmap->n_div; ++i) {
      79           0 :                 p = isl_printer_print_str(p, " ");
      80           0 :                 p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]);
      81             :         }
      82           0 :         for (i = 0; i < nparam; ++i) {
      83           0 :                 p = isl_printer_print_str(p, " ");
      84           0 :                 p = isl_printer_print_isl_int(p, c[1+i]);
      85             :         }
      86           0 :         p = isl_printer_print_str(p, " ");
      87           0 :         p = isl_printer_print_isl_int(p, c[0]);
      88           0 :         p = isl_printer_end_line(p);
      89           0 :         return p;
      90             : }
      91             : 
      92           0 : static __isl_give isl_printer *print_constraints_polylib(
      93             :         struct isl_basic_map *bmap, __isl_take isl_printer *p)
      94             : {
      95             :         int i;
      96             : 
      97           0 :         p = isl_printer_set_isl_int_width(p, 5);
      98             : 
      99           0 :         for (i = 0; i < bmap->n_eq; ++i)
     100           0 :                 p = print_constraint_polylib(bmap, 0, i, p);
     101           0 :         for (i = 0; i < bmap->n_ineq; ++i)
     102           0 :                 p = print_constraint_polylib(bmap, 1, i, p);
     103             : 
     104           0 :         return p;
     105             : }
     106             : 
     107           0 : static __isl_give isl_printer *bset_print_constraints_polylib(
     108             :         struct isl_basic_set *bset, __isl_take isl_printer *p)
     109             : {
     110           0 :         return print_constraints_polylib(bset_to_bmap(bset), p);
     111             : }
     112             : 
     113           0 : static __isl_give isl_printer *isl_basic_map_print_polylib(
     114             :         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int ext)
     115             : {
     116           0 :         unsigned total = isl_basic_map_total_dim(bmap);
     117           0 :         p = isl_printer_start_line(p);
     118           0 :         p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq);
     119           0 :         p = isl_printer_print_str(p, " ");
     120           0 :         p = isl_printer_print_int(p, 1 + total + 1);
     121           0 :         if (ext) {
     122           0 :                 p = isl_printer_print_str(p, " ");
     123           0 :                 p = isl_printer_print_int(p,
     124           0 :                                     isl_basic_map_dim(bmap, isl_dim_out));
     125           0 :                 p = isl_printer_print_str(p, " ");
     126           0 :                 p = isl_printer_print_int(p,
     127           0 :                                     isl_basic_map_dim(bmap, isl_dim_in));
     128           0 :                 p = isl_printer_print_str(p, " ");
     129           0 :                 p = isl_printer_print_int(p,
     130           0 :                                     isl_basic_map_dim(bmap, isl_dim_div));
     131           0 :                 p = isl_printer_print_str(p, " ");
     132           0 :                 p = isl_printer_print_int(p,
     133           0 :                                     isl_basic_map_dim(bmap, isl_dim_param));
     134             :         }
     135           0 :         p = isl_printer_end_line(p);
     136           0 :         return print_constraints_polylib(bmap, p);
     137             : }
     138             : 
     139           0 : static __isl_give isl_printer *isl_basic_set_print_polylib(
     140             :         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int ext)
     141             : {
     142           0 :         return isl_basic_map_print_polylib(bset_to_bmap(bset), p, ext);
     143             : }
     144             : 
     145           0 : static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map,
     146             :         __isl_take isl_printer *p, int ext)
     147             : {
     148             :         int i;
     149             : 
     150           0 :         p = isl_printer_start_line(p);
     151           0 :         p = isl_printer_print_int(p, map->n);
     152           0 :         p = isl_printer_end_line(p);
     153           0 :         for (i = 0; i < map->n; ++i) {
     154           0 :                 p = isl_printer_start_line(p);
     155           0 :                 p = isl_printer_end_line(p);
     156           0 :                 p = isl_basic_map_print_polylib(map->p[i], p, ext);
     157             :         }
     158           0 :         return p;
     159             : }
     160             : 
     161           0 : static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set,
     162             :         __isl_take isl_printer *p, int ext)
     163             : {
     164           0 :         return isl_map_print_polylib(set_to_map(set), p, ext);
     165             : }
     166             : 
     167    12437055 : static int count_same_name(__isl_keep isl_space *dim,
     168             :         enum isl_dim_type type, unsigned pos, const char *name)
     169             : {
     170             :         enum isl_dim_type t;
     171             :         unsigned p, s;
     172    12437055 :         int count = 0;
     173             : 
     174    49748220 :         for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) {
     175    37311165 :                 s = t == type ? pos : isl_space_dim(dim, t);
     176   114646008 :                 for (p = 0; p < s; ++p) {
     177    77334843 :                         const char *n = isl_space_get_dim_name(dim, t, p);
     178    77334843 :                         if (n && !strcmp(n, name))
     179           0 :                                 count++;
     180             :                 }
     181             :         }
     182    12437055 :         return count;
     183             : }
     184             : 
     185             : /* Print the name of the variable of type "type" and position "pos"
     186             :  * in "space" to "p".
     187             :  */
     188    12437055 : static __isl_give isl_printer *print_name(__isl_keep isl_space *space,
     189             :         __isl_take isl_printer *p, enum isl_dim_type type, unsigned pos,
     190             :         int latex)
     191             : {
     192             :         const char *name;
     193             :         char buffer[20];
     194             :         int primes;
     195             : 
     196    12437055 :         name = type == isl_dim_div ? NULL
     197    12437055 :                                    : isl_space_get_dim_name(space, type, pos);
     198             : 
     199    12437055 :         if (!name) {
     200             :                 const char *prefix;
     201    12437055 :                 if (type == isl_dim_param)
     202           0 :                         prefix = s_param_prefix[latex];
     203    12437055 :                 else if (type == isl_dim_div)
     204           0 :                         prefix = s_div_prefix[latex];
     205    12437055 :                 else if (isl_space_is_set(space) || type == isl_dim_in)
     206    12437055 :                         prefix = s_input_prefix[latex];
     207             :                 else
     208           0 :                         prefix = s_output_prefix[latex];
     209    12437055 :                 snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);
     210    12437055 :                 name = buffer;
     211             :         }
     212    12437055 :         primes = count_same_name(space, name == buffer ? isl_dim_div : type,
     213             :                                  pos, name);
     214    12437055 :         p = isl_printer_print_str(p, name);
     215    24874110 :         while (primes-- > 0)
     216           0 :                 p = isl_printer_print_str(p, "'");
     217    12437055 :         return p;
     218             : }
     219             : 
     220    17215845 : static enum isl_dim_type pos2type(__isl_keep isl_space *dim, unsigned *pos)
     221             : {
     222             :         enum isl_dim_type type;
     223    17215845 :         unsigned n_in = isl_space_dim(dim, isl_dim_in);
     224    17215845 :         unsigned n_out = isl_space_dim(dim, isl_dim_out);
     225    17215845 :         unsigned nparam = isl_space_dim(dim, isl_dim_param);
     226             : 
     227    17215845 :         if (*pos < 1 + nparam) {
     228           0 :                 type = isl_dim_param;
     229           0 :                 *pos -= 1;
     230    17215845 :         } else if (*pos < 1 + nparam + n_in) {
     231           0 :                 type = isl_dim_in;
     232           0 :                 *pos -= 1 + nparam;
     233    17215845 :         } else if (*pos < 1 + nparam + n_in + n_out) {
     234    17215845 :                 type = isl_dim_out;
     235    17215845 :                 *pos -= 1 + nparam + n_in;
     236             :         } else {
     237           0 :                 type = isl_dim_div;
     238           0 :                 *pos -= 1 + nparam + n_in + n_out;
     239             :         }
     240             : 
     241    17215845 :         return type;
     242             : }
     243             : 
     244             : /* Can the div expression of the integer division at position "row" of "div"
     245             :  * be printed?
     246             :  * In particular, are the div expressions available and does the selected
     247             :  * variable have a known explicit representation?
     248             :  * Furthermore, the Omega format does not allow any div expressions
     249             :  * to be printed.
     250             :  */
     251           0 : static isl_bool can_print_div_expr(__isl_keep isl_printer *p,
     252             :         __isl_keep isl_mat *div, int pos)
     253             : {
     254           0 :         if (p->output_format == ISL_FORMAT_OMEGA)
     255           0 :                 return isl_bool_false;
     256           0 :         if (!div)
     257           0 :                 return isl_bool_false;
     258           0 :         return !isl_int_is_zero(div->row[pos][0]);
     259             : }
     260             : 
     261             : static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
     262             :         __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p);
     263             : 
     264    17179731 : static __isl_give isl_printer *print_term(__isl_keep isl_space *space,
     265             :         __isl_keep isl_mat *div,
     266             :         isl_int c, unsigned pos, __isl_take isl_printer *p, int latex)
     267             : {
     268             :         enum isl_dim_type type;
     269             :         int print_div_def;
     270             : 
     271    17179731 :         if (!p || !space)
     272           0 :                 return isl_printer_free(p);
     273             : 
     274    17179731 :         if (pos == 0)
     275     6110748 :                 return isl_printer_print_isl_int(p, c);
     276             : 
     277    11068983 :         type = pos2type(space, &pos);
     278    11068983 :         print_div_def = type == isl_dim_div && can_print_div_expr(p, div, pos);
     279             : 
     280    11068983 :         if (isl_int_is_one(c))
     281             :                 ;
     282     4179603 :         else if (isl_int_is_negone(c))
     283       16838 :                 p = isl_printer_print_str(p, "-");
     284             :         else {
     285     4162765 :                 p = isl_printer_print_isl_int(p, c);
     286     4162765 :                 if (p->output_format == ISL_FORMAT_C || print_div_def)
     287           0 :                         p = isl_printer_print_str(p, "*");
     288             :         }
     289    11068983 :         if (print_div_def)
     290           0 :                 p = print_div(space, div, pos, p);
     291             :         else
     292    11068983 :                 p = print_name(space, p, type, pos, latex);
     293    11068983 :         return p;
     294             : }
     295             : 
     296     7569538 : static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *dim,
     297             :         __isl_keep isl_mat *div,
     298             :         __isl_take isl_printer *p, isl_int *c, int len)
     299             : {
     300             :         int i;
     301             :         int first;
     302             : 
     303    62641098 :         for (i = 0, first = 1; i < len; ++i) {
     304    55071560 :                 int flip = 0;
     305    55071560 :                 if (isl_int_is_zero(c[i]))
     306    45461367 :                         continue;
     307     9610193 :                 if (!first) {
     308     3427293 :                         if (isl_int_is_neg(c[i])) {
     309     1731519 :                                 flip = 1;
     310     1731519 :                                 isl_int_neg(c[i], c[i]);
     311     1731519 :                                 p = isl_printer_print_str(p, " - ");
     312             :                         } else 
     313     1695774 :                                 p = isl_printer_print_str(p, " + ");
     314             :                 }
     315     9610193 :                 first = 0;
     316     9610193 :                 p = print_term(dim, div, c[i], i, p, 0);
     317     9610193 :                 if (flip)
     318     1731519 :                         isl_int_neg(c[i], c[i]);
     319             :         }
     320     7569538 :         if (first)
     321     1386638 :                 p = isl_printer_print_str(p, "0");
     322     7569538 :         return p;
     323             : }
     324             : 
     325             : /* Print an affine expression "c"
     326             :  * to "p", with the variable names taken from "space" and
     327             :  * the integer division definitions taken from "div".
     328             :  */
     329     7569538 : static __isl_give isl_printer *print_affine(__isl_take isl_printer *p,
     330             :         __isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c)
     331             : {
     332             :         unsigned n_div;
     333             :         unsigned len;
     334             : 
     335     7569538 :         if (!space || !div)
     336           0 :                 return isl_printer_free(p);
     337     7569538 :         n_div = isl_mat_rows(div);
     338     7569538 :         len = 1 + isl_space_dim(space, isl_dim_all) + n_div;
     339     7569538 :         return print_affine_of_len(space, div, p, c, len);
     340             : }
     341             : 
     342             : /* offset is the offset of local_dim inside data->type of data->space.
     343             :  */
     344      225906 : static __isl_give isl_printer *print_nested_var_list(__isl_take isl_printer *p,
     345             :         __isl_keep isl_space *local_dim, enum isl_dim_type local_type,
     346             :         struct isl_print_space_data *data, int offset)
     347             : {
     348             :         int i;
     349             : 
     350      225906 :         if (data->space != local_dim && local_type == isl_dim_out)
     351           0 :                 offset += local_dim->n_in;
     352             : 
     353     1593978 :         for (i = 0; i < isl_space_dim(local_dim, local_type); ++i) {
     354     1368072 :                 if (i)
     355     1142166 :                         p = isl_printer_print_str(p, ", ");
     356     1368072 :                 if (data->print_dim)
     357           0 :                         p = data->print_dim(p, data, offset + i);
     358             :                 else
     359     1368072 :                         p = print_name(data->space, p, data->type, offset + i,
     360             :                                         data->latex);
     361             :         }
     362      225906 :         return p;
     363             : }
     364             : 
     365           0 : static __isl_give isl_printer *print_var_list(__isl_take isl_printer *p,
     366             :         __isl_keep isl_space *space, enum isl_dim_type type)
     367             : {
     368           0 :         struct isl_print_space_data data = { .space = space, .type = type };
     369             : 
     370           0 :         return print_nested_var_list(p, space, type, &data, 0);
     371             : }
     372             : 
     373             : static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
     374             :         __isl_keep isl_space *local_dim,
     375             :         struct isl_print_space_data *data, int offset);
     376             : 
     377      225906 : static __isl_give isl_printer *print_nested_tuple(__isl_take isl_printer *p,
     378             :         __isl_keep isl_space *local_dim, enum isl_dim_type local_type,
     379             :         struct isl_print_space_data *data, int offset)
     380             : {
     381      225906 :         const char *name = NULL;
     382      225906 :         unsigned n = isl_space_dim(local_dim, local_type);
     383      225906 :         if ((local_type == isl_dim_in || local_type == isl_dim_out)) {
     384      225906 :                 name = isl_space_get_tuple_name(local_dim, local_type);
     385      225906 :                 if (name) {
     386           0 :                         if (data->latex)
     387           0 :                                 p = isl_printer_print_str(p, "\\mathrm{");
     388           0 :                         p = isl_printer_print_str(p, name);
     389           0 :                         if (data->latex)
     390           0 :                                 p = isl_printer_print_str(p, "}");
     391             :                 }
     392             :         }
     393      225906 :         if (!data->latex || n != 1 || name)
     394      225906 :                 p = isl_printer_print_str(p, s_open_list[data->latex]);
     395      451812 :         if ((local_type == isl_dim_in || local_type == isl_dim_out) &&
     396      225906 :             local_dim->nested[local_type - isl_dim_in]) {
     397           0 :                 if (data->space != local_dim && local_type == isl_dim_out)
     398           0 :                         offset += local_dim->n_in;
     399           0 :                 p = print_nested_map_dim(p,
     400           0 :                                 local_dim->nested[local_type - isl_dim_in],
     401             :                                 data, offset);
     402             :         } else
     403      225906 :                 p = print_nested_var_list(p, local_dim, local_type, data,
     404             :                                           offset);
     405      225906 :         if (!data->latex || n != 1 || name)
     406      225906 :                 p = isl_printer_print_str(p, s_close_list[data->latex]);
     407      225906 :         return p;
     408             : }
     409             : 
     410      225906 : static __isl_give isl_printer *print_tuple(__isl_keep isl_space *dim,
     411             :         __isl_take isl_printer *p, enum isl_dim_type type,
     412             :         struct isl_print_space_data *data)
     413             : {
     414      225906 :         data->space = dim;
     415      225906 :         data->type = type;
     416      225906 :         return print_nested_tuple(p, dim, type, data, 0);
     417             : }
     418             : 
     419           0 : static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p,
     420             :         __isl_keep isl_space *local_dim,
     421             :         struct isl_print_space_data *data, int offset)
     422             : {
     423           0 :         p = print_nested_tuple(p, local_dim, isl_dim_in, data, offset);
     424           0 :         p = isl_printer_print_str(p, s_to[data->latex]);
     425           0 :         p = print_nested_tuple(p, local_dim, isl_dim_out, data, offset);
     426             : 
     427           0 :         return p;
     428             : }
     429             : 
     430      225906 : __isl_give isl_printer *isl_print_space(__isl_keep isl_space *space,
     431             :         __isl_take isl_printer *p, int rational,
     432             :         struct isl_print_space_data *data)
     433             : {
     434      225906 :         if (rational && !data->latex)
     435           0 :                 p = isl_printer_print_str(p, "rat: ");
     436      225906 :         if (isl_space_is_params(space))
     437             :                 ;
     438      225906 :         else if (isl_space_is_set(space))
     439      225906 :                 p = print_tuple(space, p, isl_dim_set, data);
     440             :         else {
     441           0 :                 p = print_tuple(space, p, isl_dim_in, data);
     442           0 :                 p = isl_printer_print_str(p, s_to[data->latex]);
     443           0 :                 p = print_tuple(space, p, isl_dim_out, data);
     444             :         }
     445             : 
     446      225906 :         return p;
     447             : }
     448             : 
     449           0 : static __isl_give isl_printer *print_omega_parameters(__isl_keep isl_space *dim,
     450             :         __isl_take isl_printer *p)
     451             : {
     452           0 :         if (isl_space_dim(dim, isl_dim_param) == 0)
     453           0 :                 return p;
     454             : 
     455           0 :         p = isl_printer_start_line(p);
     456           0 :         p = isl_printer_print_str(p, "symbolic ");
     457           0 :         p = print_var_list(p, dim, isl_dim_param);
     458           0 :         p = isl_printer_print_str(p, ";");
     459           0 :         p = isl_printer_end_line(p);
     460           0 :         return p;
     461             : }
     462             : 
     463             : /* Does the inequality constraint following "i" in "bmap"
     464             :  * have an opposite value for the same last coefficient?
     465             :  * "last" is the position of the last coefficient of inequality "i".
     466             :  * If the next constraint is a div constraint, then it is ignored
     467             :  * since div constraints are not printed.
     468             :  */
     469           0 : static int next_is_opposite(__isl_keep isl_basic_map *bmap, int i, int last)
     470             : {
     471           0 :         unsigned total = isl_basic_map_total_dim(bmap);
     472           0 :         unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
     473             : 
     474           0 :         if (i + 1 >= bmap->n_ineq)
     475           0 :                 return 0;
     476           0 :         if (isl_seq_last_non_zero(bmap->ineq[i + 1], 1 + total) != last)
     477           0 :                 return 0;
     478           0 :         if (last >= o_div) {
     479             :                 isl_bool is_div;
     480           0 :                 is_div = isl_basic_map_is_div_constraint(bmap,
     481           0 :                                             bmap->ineq[i + 1], last - o_div);
     482           0 :                 if (is_div < 0)
     483           0 :                         return -1;
     484           0 :                 if (is_div)
     485           0 :                         return 0;
     486             :         }
     487           0 :         return isl_int_abs_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]) &&
     488           0 :                 !isl_int_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]);
     489             : }
     490             : 
     491             : /* Return a string representation of the operator used when
     492             :  * printing a constraint where the LHS is greater than or equal to the LHS
     493             :  * (sign > 0) or smaller than or equal to the LHS (sign < 0).
     494             :  * If "strict" is set, then return the strict version of the comparison
     495             :  * operator.
     496             :  */
     497     1422676 : static const char *constraint_op(int sign, int strict, int latex)
     498             : {
     499     1422676 :         if (strict)
     500        9501 :                 return sign < 0 ? "<" : ">";
     501     1413175 :         if (sign < 0)
     502      707070 :                 return s_le[latex];
     503             :         else
     504      706105 :                 return s_ge[latex];
     505             : }
     506             : 
     507             : /* Print one side of a constraint "c" to "p", with
     508             :  * the variable names taken from "space" and the integer division definitions
     509             :  * taken from "div".
     510             :  * "last" is the position of the last non-zero coefficient.
     511             :  * Let c' be the result of zeroing out this coefficient, then
     512             :  * the partial constraint
     513             :  *
     514             :  *      c' op
     515             :  *
     516             :  * is printed.
     517             :  */
     518           0 : static __isl_give isl_printer *print_half_constraint(__isl_take isl_printer *p,
     519             :         __isl_keep isl_space *space, __isl_keep isl_mat *div,
     520             :         isl_int *c, int last, const char *op, int latex)
     521             : {
     522           0 :         isl_int_set_si(c[last], 0);
     523           0 :         p = print_affine(p, space, div, c);
     524             : 
     525           0 :         p = isl_printer_print_str(p, " ");
     526           0 :         p = isl_printer_print_str(p, op);
     527           0 :         p = isl_printer_print_str(p, " ");
     528             : 
     529           0 :         return p;
     530             : }
     531             : 
     532             : /* Print a constraint "c" to "p", with the variable names
     533             :  * taken from "space" and the integer division definitions taken from "div".
     534             :  * "last" is the position of the last non-zero coefficient, which is
     535             :  * moreover assumed to be negative.
     536             :  * Let c' be the result of zeroing out this coefficient, then
     537             :  * the constraint is printed in the form
     538             :  *
     539             :  *      -c[last] op c'
     540             :  */
     541     7569538 : static __isl_give isl_printer *print_constraint(__isl_take isl_printer *p,
     542             :         __isl_keep isl_space *space, __isl_keep isl_mat *div,
     543             :         isl_int *c, int last, const char *op, int latex)
     544             : {
     545     7569538 :         isl_int_abs(c[last], c[last]);
     546             : 
     547     7569538 :         p = print_term(space, div, c[last], last, p, latex);
     548             : 
     549     7569538 :         p = isl_printer_print_str(p, " ");
     550     7569538 :         p = isl_printer_print_str(p, op);
     551     7569538 :         p = isl_printer_print_str(p, " ");
     552             : 
     553     7569538 :         isl_int_set_si(c[last], 0);
     554     7569538 :         p = print_affine(p, space, div, c);
     555             : 
     556     7569538 :         return p;
     557             : }
     558             : 
     559             : /* Given an integer division
     560             :  *
     561             :  *      floor(f/m)
     562             :  *
     563             :  * at position "pos" in "div", print the corresponding modulo expression
     564             :  *
     565             :  *      (f) mod m
     566             :  *
     567             :  * to "p".  The variable names are taken from "space", while any
     568             :  * nested integer division definitions are taken from "div".
     569             :  */
     570           0 : static __isl_give isl_printer *print_mod(__isl_take isl_printer *p,
     571             :         __isl_keep isl_space *space, __isl_keep isl_mat *div, int pos,
     572             :         int latex)
     573             : {
     574           0 :         if (!p || !div)
     575           0 :                 return isl_printer_free(p);
     576             : 
     577           0 :         p = isl_printer_print_str(p, "(");
     578           0 :         p = print_affine_of_len(space, div, p,
     579           0 :                                 div->row[pos] + 1, div->n_col - 1);
     580           0 :         p = isl_printer_print_str(p, ") ");
     581           0 :         p = isl_printer_print_str(p, s_mod[latex]);
     582           0 :         p = isl_printer_print_str(p, " ");
     583           0 :         p = isl_printer_print_isl_int(p, div->row[pos][0]);
     584           0 :         return p;
     585             : }
     586             : 
     587             : /* Can the equality constraints "c" be printed as a modulo constraint?
     588             :  * In particular, is of the form
     589             :  *
     590             :  *      f - a m floor(g/m) = 0,
     591             :  *
     592             :  * with c = -a m the coefficient at position "pos"?
     593             :  * Return the position of the corresponding integer division if so.
     594             :  * Return the number of integer divisions if not.
     595             :  * Return -1 on error.
     596             :  *
     597             :  * Modulo constraints are currently not printed in C format.
     598             :  * Other than that, "pos" needs to correspond to an integer division
     599             :  * with explicit representation and "c" needs to be a multiple
     600             :  * of the denominator of the integer division.
     601             :  */
     602     6146862 : static int print_as_modulo_pos(__isl_keep isl_printer *p,
     603             :         __isl_keep isl_space *space, __isl_keep isl_mat *div, unsigned pos,
     604             :         isl_int c)
     605             : {
     606             :         isl_bool can_print;
     607             :         unsigned n_div;
     608             :         enum isl_dim_type type;
     609             : 
     610     6146862 :         if (!p || !space)
     611           0 :                 return -1;
     612     6146862 :         n_div = isl_mat_rows(div);
     613     6146862 :         if (p->output_format == ISL_FORMAT_C)
     614           0 :                 return n_div;
     615     6146862 :         type = pos2type(space, &pos);
     616     6146862 :         if (type != isl_dim_div)
     617     6146862 :                 return n_div;
     618           0 :         can_print = can_print_div_expr(p, div, pos);
     619           0 :         if (can_print < 0)
     620           0 :                 return -1;
     621           0 :         if (!can_print)
     622           0 :                 return n_div;
     623           0 :         if (!isl_int_is_divisible_by(c, div->row[pos][0]))
     624           0 :                 return n_div;
     625           0 :         return pos;
     626             : }
     627             : 
     628             : /* Print equality constraint "c" to "p" as a modulo constraint,
     629             :  * with the variable names taken from "space" and
     630             :  * the integer division definitions taken from "div".
     631             :  * "last" is the position of the last non-zero coefficient, which is
     632             :  * moreover assumed to be negative and a multiple of the denominator
     633             :  * of the corresponding integer division.  "div_pos" is the corresponding
     634             :  * position in the sequence of integer divisions.
     635             :  *
     636             :  * The equality is of the form
     637             :  *
     638             :  *      f - a m floor(g/m) = 0.
     639             :  *
     640             :  * Print it as
     641             :  *
     642             :  *      a (g mod m) = -f + a g
     643             :  */
     644           0 : static __isl_give isl_printer *print_eq_mod_constraint(
     645             :         __isl_take isl_printer *p, __isl_keep isl_space *space,
     646             :         __isl_keep isl_mat *div, unsigned div_pos,
     647             :         isl_int *c, int last, int latex)
     648             : {
     649             :         isl_ctx *ctx;
     650             :         int multiple;
     651             : 
     652           0 :         ctx = isl_printer_get_ctx(p);
     653           0 :         isl_int_divexact(c[last], c[last], div->row[div_pos][0]);
     654           0 :         isl_int_abs(c[last], c[last]);
     655           0 :         multiple = !isl_int_is_one(c[last]);
     656           0 :         if (multiple) {
     657           0 :                 p = isl_printer_print_isl_int(p, c[last]);
     658           0 :                 p = isl_printer_print_str(p, "*(");
     659             :         }
     660           0 :         p = print_mod(p, space, div, div_pos, latex);
     661           0 :         if (multiple)
     662           0 :                 p = isl_printer_print_str(p, ")");
     663           0 :         p = isl_printer_print_str(p, " = ");
     664           0 :         isl_seq_combine(c, ctx->negone, c,
     665           0 :                             c[last], div->row[div_pos] + 1, last);
     666           0 :         isl_int_set_si(c[last], 0);
     667           0 :         p = print_affine(p, space, div, c);
     668           0 :         return p;
     669             : }
     670             : 
     671             : /* Print equality constraint "c" to "p", with the variable names
     672             :  * taken from "space" and the integer division definitions taken from "div".
     673             :  * "last" is the position of the last non-zero coefficient, which is
     674             :  * moreover assumed to be negative.
     675             :  *
     676             :  * If possible, print the equality constraint as a modulo constraint.
     677             :  */
     678     6146862 : static __isl_give isl_printer *print_eq_constraint(__isl_take isl_printer *p,
     679             :         __isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c,
     680             :         int last, int latex)
     681             : {
     682             :         unsigned n_div;
     683             :         int div_pos;
     684             : 
     685     6146862 :         n_div = isl_mat_rows(div);
     686     6146862 :         div_pos = print_as_modulo_pos(p, space, div, last, c[last]);
     687     6146862 :         if (div_pos < 0)
     688           0 :                 return isl_printer_free(p);
     689     6146862 :         if (div_pos < n_div)
     690           0 :                 return print_eq_mod_constraint(p, space, div, div_pos,
     691             :                                                 c, last, latex);
     692     6146862 :         return print_constraint(p, space, div, c, last, "=", latex);
     693             : }
     694             : 
     695             : /* Print the constraints of "bmap" to "p".
     696             :  * The names of the variables are taken from "space" and
     697             :  * the integer division definitions are taken from "div".
     698             :  * Div constraints are only printed in "dump" mode.
     699             :  * The constraints are sorted prior to printing (except in "dump" mode).
     700             :  *
     701             :  * If x is the last variable with a non-zero coefficient,
     702             :  * then a lower bound
     703             :  *
     704             :  *      f - a x >= 0
     705             :  *
     706             :  * is printed as
     707             :  *
     708             :  *      a x <= f
     709             :  *
     710             :  * while an upper bound
     711             :  *
     712             :  *      f + a x >= 0
     713             :  *
     714             :  * is printed as
     715             :  *
     716             :  *      a x >= -f
     717             :  *
     718             :  * If the next constraint has an opposite sign for the same last coefficient,
     719             :  * then it is printed as
     720             :  *
     721             :  *      f >= a x
     722             :  *
     723             :  * or
     724             :  *
     725             :  *      -f <= a x
     726             :  *
     727             :  * instead.  In fact, the "a x" part is not printed explicitly, but
     728             :  * reused from the next constraint, which is therefore treated as
     729             :  * a first constraint in the conjunction.
     730             :  *
     731             :  * If the constant term of "f" is -1, then "f" is replaced by "f + 1" and
     732             :  * the comparison operator is replaced by the strict variant.
     733             :  * Essentially, ">= 1" is replaced by "> 0".
     734             :  */
     735     1117716 : static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
     736             :         __isl_keep isl_space *space, __isl_keep isl_mat *div,
     737             :         __isl_take isl_printer *p, int latex)
     738             : {
     739             :         int i;
     740     1117716 :         isl_vec *c = NULL;
     741     1117716 :         int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
     742     1117716 :         unsigned total = isl_basic_map_total_dim(bmap);
     743     1117716 :         unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
     744     1117716 :         int first = 1;
     745             :         int dump;
     746             : 
     747     1117716 :         if (!p)
     748           0 :                 return NULL;
     749     1117716 :         bmap = isl_basic_map_copy(bmap);
     750     1117716 :         dump = p->dump;
     751     1117716 :         if (!dump)
     752           0 :                 bmap = isl_basic_map_sort_constraints(bmap);
     753     1117716 :         if (!bmap)
     754           0 :                 goto error;
     755             : 
     756     1117716 :         c = isl_vec_alloc(bmap->ctx, 1 + total);
     757     1117716 :         if (!c)
     758           0 :                 goto error;
     759             : 
     760     7264578 :         for (i = bmap->n_eq - 1; i >= 0; --i) {
     761     6146862 :                 int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total);
     762     6146862 :                 if (l < 0) {
     763           0 :                         if (i != bmap->n_eq - 1)
     764           0 :                                 p = isl_printer_print_str(p, s_and[latex]);
     765           0 :                         p = isl_printer_print_str(p, "0 = 0");
     766           0 :                         continue;
     767             :                 }
     768     6146862 :                 if (!first)
     769     5071019 :                         p = isl_printer_print_str(p, s_and[latex]);
     770     6146862 :                 if (isl_int_is_neg(bmap->eq[i][l]))
     771           0 :                         isl_seq_cpy(c->el, bmap->eq[i], 1 + total);
     772             :                 else
     773     6146862 :                         isl_seq_neg(c->el, bmap->eq[i], 1 + total);
     774     6146862 :                 p = print_eq_constraint(p, space, div, c->el, l, latex);
     775     6146862 :                 first = 0;
     776             :         }
     777     2540392 :         for (i = 0; i < bmap->n_ineq; ++i) {
     778     1422676 :                 int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);
     779             :                 int strict;
     780             :                 int s;
     781             :                 const char *op;
     782     1422676 :                 if (l < 0)
     783           0 :                         continue;
     784     1422676 :                 if (!dump && l >= o_div &&
     785           0 :                     can_print_div_expr(p, div, l - o_div)) {
     786             :                         isl_bool is_div;
     787           0 :                         is_div = isl_basic_map_is_div_constraint(bmap,
     788           0 :                                                     bmap->ineq[i], l - o_div);
     789           0 :                         if (is_div < 0)
     790           0 :                                 goto error;
     791           0 :                         if (is_div)
     792           0 :                                 continue;
     793             :                 }
     794     1422676 :                 if (!first)
     795     1380803 :                         p = isl_printer_print_str(p, s_and[latex]);
     796     1422676 :                 s = isl_int_sgn(bmap->ineq[i][l]);
     797     1422676 :                 strict = !rational && isl_int_is_negone(bmap->ineq[i][0]);
     798     1422676 :                 if (s < 0)
     799      708957 :                         isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);
     800             :                 else
     801      713719 :                         isl_seq_neg(c->el, bmap->ineq[i], 1 + total);
     802     1422676 :                 if (strict)
     803        9501 :                         isl_int_set_si(c->el[0], 0);
     804     1422676 :                 if (!dump && next_is_opposite(bmap, i, l)) {
     805           0 :                         op = constraint_op(-s, strict, latex);
     806           0 :                         p = print_half_constraint(p, space, div, c->el, l,
     807             :                                                 op, latex);
     808           0 :                         first = 1;
     809             :                 } else {
     810     1422676 :                         op = constraint_op(s, strict, latex);
     811     1422676 :                         p = print_constraint(p, space, div, c->el, l,
     812             :                                                 op, latex);
     813     1422676 :                         first = 0;
     814             :                 }
     815             :         }
     816             : 
     817     1117716 :         isl_basic_map_free(bmap);
     818     1117716 :         isl_vec_free(c);
     819             : 
     820     1117716 :         return p;
     821             : error:
     822           0 :         isl_basic_map_free(bmap);
     823           0 :         isl_vec_free(c);
     824           0 :         isl_printer_free(p);
     825           0 :         return NULL;
     826             : }
     827             : 
     828           0 : static __isl_give isl_printer *print_div(__isl_keep isl_space *dim,
     829             :         __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p)
     830             : {
     831             :         int c;
     832             : 
     833           0 :         if (!p || !div)
     834           0 :                 return isl_printer_free(p);
     835             : 
     836           0 :         c = p->output_format == ISL_FORMAT_C;
     837           0 :         p = isl_printer_print_str(p, c ? "floord(" : "floor((");
     838           0 :         p = print_affine_of_len(dim, div, p,
     839           0 :                                 div->row[pos] + 1, div->n_col - 1);
     840           0 :         p = isl_printer_print_str(p, c ? ", " : ")/");
     841           0 :         p = isl_printer_print_isl_int(p, div->row[pos][0]);
     842           0 :         p = isl_printer_print_str(p, ")");
     843           0 :         return p;
     844             : }
     845             : 
     846             : /* Print a comma separated list of div names, except those that have
     847             :  * a definition that can be printed.
     848             :  * If "print_defined_divs" is set, then those div names are printed
     849             :  * as well, along with their definitions.
     850             :  */
     851           0 : static __isl_give isl_printer *print_div_list(__isl_take isl_printer *p,
     852             :         __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex,
     853             :         int print_defined_divs)
     854             : {
     855             :         int i;
     856           0 :         int first = 1;
     857             :         unsigned n_div;
     858             : 
     859           0 :         if (!p || !space || !div)
     860           0 :                 return isl_printer_free(p);
     861             : 
     862           0 :         n_div = isl_mat_rows(div);
     863             : 
     864           0 :         for (i = 0; i < n_div; ++i) {
     865           0 :                 if (!print_defined_divs && can_print_div_expr(p, div, i))
     866           0 :                         continue;
     867           0 :                 if (!first)
     868           0 :                         p = isl_printer_print_str(p, ", ");
     869           0 :                 p = print_name(space, p, isl_dim_div, i, latex);
     870           0 :                 first = 0;
     871           0 :                 if (!can_print_div_expr(p, div, i))
     872           0 :                         continue;
     873           0 :                 p = isl_printer_print_str(p, " = ");
     874           0 :                 p = print_div(space, div, i, p);
     875             :         }
     876             : 
     877           0 :         return p;
     878             : }
     879             : 
     880             : /* Does printing an object with local variables described by "div"
     881             :  * require an "exists" clause?
     882             :  * That is, are there any local variables without an explicit representation?
     883             :  * An exists clause is also needed in "dump" mode because
     884             :  * explicit div representations are not printed inline in that case.
     885             :  */
     886     1117716 : static isl_bool need_exists(__isl_keep isl_printer *p, __isl_keep isl_mat *div)
     887             : {
     888             :         int i, n;
     889             : 
     890     1117716 :         if (!p || !div)
     891           0 :                 return isl_bool_error;
     892     1117716 :         n = isl_mat_rows(div);
     893     1117716 :         if (n == 0)
     894     1117716 :                 return isl_bool_false;
     895           0 :         if (p->dump)
     896           0 :                 return isl_bool_true;
     897           0 :         for (i = 0; i < n; ++i)
     898           0 :                 if (!can_print_div_expr(p, div, i))
     899           0 :                         return isl_bool_true;
     900           0 :         return isl_bool_false;
     901             : }
     902             : 
     903             : /* Print the start of an exists clause, i.e.,
     904             :  *
     905             :  *      (exists variables:
     906             :  *
     907             :  * In dump mode, local variables with an explicit definition are printed
     908             :  * as well because they will not be printed inline.
     909             :  */
     910           0 : static __isl_give isl_printer *open_exists(__isl_take isl_printer *p,
     911             :         __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex)
     912             : {
     913             :         int dump;
     914             : 
     915           0 :         if (!p)
     916           0 :                 return NULL;
     917             : 
     918           0 :         dump = p->dump;
     919           0 :         p = isl_printer_print_str(p, s_open_exists[latex]);
     920           0 :         p = print_div_list(p, space, div, latex, dump);
     921           0 :         p = isl_printer_print_str(p, ": ");
     922             : 
     923           0 :         return p;
     924             : }
     925             : 
     926             : /* Remove the explicit representations of all local variables in "div".
     927             :  */
     928     1117716 : static __isl_give isl_mat *mark_all_unknown(__isl_take isl_mat *div)
     929             : {
     930             :         int i, n_div;
     931             : 
     932     1117716 :         if (!div)
     933           0 :                 return NULL;
     934             : 
     935     1117716 :         n_div = isl_mat_rows(div);
     936     1117716 :         for (i = 0; i < n_div; ++i)
     937           0 :                 div = isl_mat_set_element_si(div, i, 0, 0);
     938     1117716 :         return div;
     939             : }
     940             : 
     941             : /* Print the constraints of "bmap" to "p".
     942             :  * The names of the variables are taken from "space".
     943             :  * "latex" is set if the constraints should be printed in LaTeX format.
     944             :  * Do not print inline explicit div representations in "dump" mode.
     945             :  */
     946     1117716 : static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
     947             :         __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
     948             : {
     949             :         int dump;
     950             :         isl_mat *div;
     951             :         isl_bool exists;
     952             : 
     953     1117716 :         if (!p)
     954           0 :                 return NULL;
     955     1117716 :         dump = p->dump;
     956     1117716 :         div = isl_basic_map_get_divs(bmap);
     957     1117716 :         exists = need_exists(p, div);
     958     1117716 :         if (exists >= 0 && exists)
     959           0 :                 p = open_exists(p, space, div, latex);
     960             : 
     961     1117716 :         if (dump)
     962     1117716 :                 div = mark_all_unknown(div);
     963     1117716 :         p = print_constraints(bmap, space, div, p, latex);
     964     1117716 :         isl_mat_free(div);
     965             : 
     966     1117716 :         if (exists >= 0 && exists)
     967           0 :                 p = isl_printer_print_str(p, s_close_exists[latex]);
     968     1117716 :         return p;
     969             : }
     970             : 
     971             : /* Print a colon followed by the constraints of "bmap"
     972             :  * to "p", provided there are any constraints.
     973             :  * The names of the variables are taken from "space".
     974             :  * "latex" is set if the constraints should be printed in LaTeX format.
     975             :  */
     976           0 : static __isl_give isl_printer *print_optional_disjunct(
     977             :         __isl_keep isl_basic_map *bmap, __isl_keep isl_space *space,
     978             :         __isl_take isl_printer *p, int latex)
     979             : {
     980           0 :         if (isl_basic_map_plain_is_universe(bmap))
     981           0 :                 return p;
     982             : 
     983           0 :         p = isl_printer_print_str(p, ": ");
     984           0 :         p = print_disjunct(bmap, space, p, latex);
     985             : 
     986           0 :         return p;
     987             : }
     988             : 
     989           0 : static __isl_give isl_printer *basic_map_print_omega(
     990             :         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p)
     991             : {
     992           0 :         p = isl_printer_print_str(p, "{ [");
     993           0 :         p = print_var_list(p, bmap->dim, isl_dim_in);
     994           0 :         p = isl_printer_print_str(p, "] -> [");
     995           0 :         p = print_var_list(p, bmap->dim, isl_dim_out);
     996           0 :         p = isl_printer_print_str(p, "] ");
     997           0 :         p = print_optional_disjunct(bmap, bmap->dim, p, 0);
     998           0 :         p = isl_printer_print_str(p, " }");
     999           0 :         return p;
    1000             : }
    1001             : 
    1002           0 : static __isl_give isl_printer *basic_set_print_omega(
    1003             :         __isl_keep isl_basic_set *bset, __isl_take isl_printer *p)
    1004             : {
    1005           0 :         p = isl_printer_print_str(p, "{ [");
    1006           0 :         p = print_var_list(p, bset->dim, isl_dim_set);
    1007           0 :         p = isl_printer_print_str(p, "] ");
    1008           0 :         p = print_optional_disjunct(bset, bset->dim, p, 0);
    1009           0 :         p = isl_printer_print_str(p, " }");
    1010           0 :         return p;
    1011             : }
    1012             : 
    1013           0 : static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map,
    1014             :         __isl_take isl_printer *p)
    1015             : {
    1016             :         int i;
    1017             : 
    1018           0 :         for (i = 0; i < map->n; ++i) {
    1019           0 :                 if (i)
    1020           0 :                         p = isl_printer_print_str(p, " union ");
    1021           0 :                 p = basic_map_print_omega(map->p[i], p);
    1022             :         }
    1023           0 :         return p;
    1024             : }
    1025             : 
    1026           0 : static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set,
    1027             :         __isl_take isl_printer *p)
    1028             : {
    1029             :         int i;
    1030             : 
    1031           0 :         for (i = 0; i < set->n; ++i) {
    1032           0 :                 if (i)
    1033           0 :                         p = isl_printer_print_str(p, " union ");
    1034           0 :                 p = basic_set_print_omega(set->p[i], p);
    1035             :         }
    1036           0 :         return p;
    1037             : }
    1038             : 
    1039             : /* Print the list of parameters in "space", followed by an arrow, to "p",
    1040             :  * if there are any parameters.
    1041             :  */
    1042      225906 : static __isl_give isl_printer *print_param_tuple(__isl_take isl_printer *p,
    1043             :         __isl_keep isl_space *space, struct isl_print_space_data *data)
    1044             : {
    1045      225906 :         if (!p || !space)
    1046           0 :                 return isl_printer_free(p);
    1047      225906 :         if (isl_space_dim(space, isl_dim_param) == 0)
    1048      225906 :                 return p;
    1049             : 
    1050           0 :         p = print_tuple(space, p, isl_dim_param, data);
    1051           0 :         p = isl_printer_print_str(p, s_to[data->latex]);
    1052             : 
    1053           0 :         return p;
    1054             : }
    1055             : 
    1056           0 : static __isl_give isl_printer *isl_basic_map_print_isl(
    1057             :         __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p,
    1058             :         int latex)
    1059             : {
    1060           0 :         struct isl_print_space_data data = { .latex = latex };
    1061           0 :         int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
    1062             : 
    1063           0 :         p = print_param_tuple(p, bmap->dim, &data);
    1064           0 :         p = isl_printer_print_str(p, "{ ");
    1065           0 :         p = isl_print_space(bmap->dim, p, rational, &data);
    1066           0 :         p = isl_printer_print_str(p, " : ");
    1067           0 :         p = print_disjunct(bmap, bmap->dim, p, latex);
    1068           0 :         p = isl_printer_print_str(p, " }");
    1069           0 :         return p;
    1070             : }
    1071             : 
    1072             : /* Print the disjuncts of a map (or set) "map" to "p".
    1073             :  * The names of the variables are taken from "space".
    1074             :  * "latex" is set if the constraints should be printed in LaTeX format.
    1075             :  */
    1076      225906 : static __isl_give isl_printer *print_disjuncts_core(__isl_keep isl_map *map,
    1077             :         __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
    1078             : {
    1079             :         int i;
    1080             : 
    1081      225906 :         if (map->n == 0)
    1082           0 :                 p = isl_printer_print_str(p, "false");
    1083     1343622 :         for (i = 0; i < map->n; ++i) {
    1084     1117716 :                 if (i)
    1085      891810 :                         p = isl_printer_print_str(p, s_or[latex]);
    1086     1117716 :                 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
    1087      998316 :                         p = isl_printer_print_str(p, "(");
    1088     1117716 :                 p = print_disjunct(map->p[i], space, p, latex);
    1089     1117716 :                 if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 1)
    1090      998316 :                         p = isl_printer_print_str(p, ")");
    1091             :         }
    1092      225906 :         return p;
    1093             : }
    1094             : 
    1095             : /* Print the disjuncts of a map (or set) "map" to "p".
    1096             :  * The names of the variables are taken from "space".
    1097             :  * "hull" describes constraints shared by all disjuncts of "map".
    1098             :  * "latex" is set if the constraints should be printed in LaTeX format.
    1099             :  *
    1100             :  * Print the disjuncts as a conjunction of "hull" and
    1101             :  * the result of removing the constraints of "hull" from "map".
    1102             :  * If this result turns out to be the universe, then simply print "hull".
    1103             :  */
    1104           0 : static __isl_give isl_printer *print_disjuncts_in_hull(__isl_keep isl_map *map,
    1105             :         __isl_keep isl_space *space, __isl_take isl_basic_map *hull,
    1106             :         __isl_take isl_printer *p, int latex)
    1107             : {
    1108             :         isl_bool is_universe;
    1109             : 
    1110           0 :         p = print_disjunct(hull, space, p, latex);
    1111           0 :         map = isl_map_plain_gist_basic_map(isl_map_copy(map), hull);
    1112           0 :         is_universe = isl_map_plain_is_universe(map);
    1113           0 :         if (is_universe < 0)
    1114           0 :                 goto error;
    1115           0 :         if (!is_universe) {
    1116           0 :                 p = isl_printer_print_str(p, s_and[latex]);
    1117           0 :                 p = isl_printer_print_str(p, "(");
    1118           0 :                 p = print_disjuncts_core(map, space, p, latex);
    1119           0 :                 p = isl_printer_print_str(p, ")");
    1120             :         }
    1121           0 :         isl_map_free(map);
    1122             : 
    1123           0 :         return p;
    1124             : error:
    1125           0 :         isl_map_free(map);
    1126           0 :         isl_printer_free(p);
    1127           0 :         return NULL;
    1128             : }
    1129             : 
    1130             : /* Print the disjuncts of a map (or set) "map" to "p".
    1131             :  * The names of the variables are taken from "space".
    1132             :  * "latex" is set if the constraints should be printed in LaTeX format.
    1133             :  *
    1134             :  * If there are at least two disjuncts and "dump" mode is not turned out,
    1135             :  * check for any shared constraints among all disjuncts.
    1136             :  * If there are any, then print them separately in print_disjuncts_in_hull.
    1137             :  */
    1138      225906 : static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map,
    1139             :         __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
    1140             : {
    1141      225906 :         if (isl_map_plain_is_universe(map))
    1142           0 :                 return p;
    1143             : 
    1144      225906 :         p = isl_printer_print_str(p, s_such_that[latex]);
    1145      225906 :         if (!p)
    1146           0 :                 return NULL;
    1147             : 
    1148      225906 :         if (!p->dump && map->n >= 2) {
    1149             :                 isl_basic_map *hull;
    1150             :                 isl_bool is_universe;
    1151             : 
    1152           0 :                 hull = isl_map_plain_unshifted_simple_hull(isl_map_copy(map));
    1153           0 :                 is_universe = isl_basic_map_plain_is_universe(hull);
    1154           0 :                 if (is_universe < 0)
    1155           0 :                         p = isl_printer_free(p);
    1156           0 :                 else if (!is_universe)
    1157           0 :                         return print_disjuncts_in_hull(map, space, hull,
    1158             :                                                         p, latex);
    1159           0 :                 isl_basic_map_free(hull);
    1160             :         }
    1161             : 
    1162      225906 :         return print_disjuncts_core(map, space, p, latex);
    1163             : }
    1164             : 
    1165             : /* Print the disjuncts of a map (or set).
    1166             :  * The names of the variables are taken from "space".
    1167             :  * "latex" is set if the constraints should be printed in LaTeX format.
    1168             :  *
    1169             :  * If the map turns out to be a universal parameter domain, then
    1170             :  * we need to print the colon.  Otherwise, the output looks identical
    1171             :  * to the empty set.
    1172             :  */
    1173      225906 : static __isl_give isl_printer *print_disjuncts_map(__isl_keep isl_map *map,
    1174             :         __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
    1175             : {
    1176      225906 :         if (isl_map_plain_is_universe(map) && isl_space_is_params(map->dim))
    1177           0 :                 return isl_printer_print_str(p, s_such_that[latex]);
    1178             :         else
    1179      225906 :                 return print_disjuncts(map, space, p, latex);
    1180             : }
    1181             : 
    1182             : /* Print the disjuncts of a set.
    1183             :  * The names of the variables are taken from "space".
    1184             :  * "latex" is set if the constraints should be printed in LaTeX format.
    1185             :  */
    1186           0 : static __isl_give isl_printer *print_disjuncts_set(__isl_keep isl_set *set,
    1187             :         __isl_keep isl_space *space, __isl_take isl_printer *p, int latex)
    1188             : {
    1189           0 :         return print_disjuncts_map(set_to_map(set), space, p, latex);
    1190             : }
    1191             : 
    1192             : struct isl_aff_split {
    1193             :         isl_basic_map *aff;
    1194             :         isl_map *map;
    1195             : };
    1196             : 
    1197      225906 : static void free_split(__isl_take struct isl_aff_split *split, int n)
    1198             : {
    1199             :         int i;
    1200             : 
    1201      225906 :         if (!split)
    1202      225906 :                 return;
    1203             : 
    1204           0 :         for (i = 0; i < n; ++i) {
    1205           0 :                 isl_basic_map_free(split[i].aff);
    1206           0 :                 isl_map_free(split[i].map);
    1207             :         }
    1208             : 
    1209           0 :         free(split);
    1210             : }
    1211             : 
    1212           0 : static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap)
    1213             : {
    1214             :         int i, j;
    1215             :         unsigned nparam, n_in, n_out, total;
    1216             : 
    1217           0 :         bmap = isl_basic_map_cow(bmap);
    1218           0 :         if (!bmap)
    1219           0 :                 return NULL;
    1220           0 :         if (isl_basic_map_free_inequality(bmap, bmap->n_ineq) < 0)
    1221           0 :                 goto error;
    1222             : 
    1223           0 :         nparam = isl_basic_map_dim(bmap, isl_dim_param);
    1224           0 :         n_in = isl_basic_map_dim(bmap, isl_dim_in);
    1225           0 :         n_out = isl_basic_map_dim(bmap, isl_dim_out);
    1226           0 :         total = isl_basic_map_dim(bmap, isl_dim_all);
    1227           0 :         for (i = bmap->n_eq - 1; i >= 0; --i) {
    1228           0 :                 j = isl_seq_last_non_zero(bmap->eq[i] + 1, total);
    1229           0 :                 if (j >= nparam && j < nparam + n_in + n_out &&
    1230           0 :                     (isl_int_is_one(bmap->eq[i][1 + j]) ||
    1231           0 :                      isl_int_is_negone(bmap->eq[i][1 + j])))
    1232           0 :                         continue;
    1233           0 :                 if (isl_basic_map_drop_equality(bmap, i) < 0)
    1234           0 :                         goto error;
    1235             :         }
    1236             : 
    1237           0 :         bmap = isl_basic_map_finalize(bmap);
    1238             : 
    1239           0 :         return bmap;
    1240             : error:
    1241           0 :         isl_basic_map_free(bmap);
    1242           0 :         return NULL;
    1243             : }
    1244             : 
    1245           0 : static int aff_split_cmp(const void *p1, const void *p2, void *user)
    1246             : {
    1247             :         const struct isl_aff_split *s1, *s2;
    1248           0 :         s1 = (const struct isl_aff_split *) p1;
    1249           0 :         s2 = (const struct isl_aff_split *) p2;
    1250             : 
    1251           0 :         return isl_basic_map_plain_cmp(s1->aff, s2->aff);
    1252             : }
    1253             : 
    1254           0 : static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap,
    1255             :         __isl_keep isl_basic_map *aff)
    1256             : {
    1257             :         int i, j;
    1258             :         unsigned total;
    1259             : 
    1260           0 :         if (!bmap || !aff)
    1261             :                 goto error;
    1262             : 
    1263           0 :         total = isl_space_dim(bmap->dim, isl_dim_all);
    1264             : 
    1265           0 :         for (i = bmap->n_eq - 1; i >= 0; --i) {
    1266           0 :                 if (isl_seq_first_non_zero(bmap->eq[i] + 1 + total,
    1267             :                                             bmap->n_div) != -1)
    1268           0 :                         continue;
    1269           0 :                 for (j = 0; j < aff->n_eq; ++j) {
    1270           0 :                         if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + total) &&
    1271           0 :                             !isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + total))
    1272           0 :                                 continue;
    1273           0 :                         if (isl_basic_map_drop_equality(bmap, i) < 0)
    1274           0 :                                 goto error;
    1275           0 :                         break;
    1276             :                 }
    1277             :         }
    1278             : 
    1279           0 :         return bmap;
    1280             : error:
    1281           0 :         isl_basic_map_free(bmap);
    1282           0 :         return NULL;
    1283             : }
    1284             : 
    1285           0 : static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map)
    1286             : {
    1287             :         int i, n;
    1288             :         struct isl_aff_split *split;
    1289             :         isl_ctx *ctx;
    1290             : 
    1291           0 :         ctx = isl_map_get_ctx(map);
    1292           0 :         split = isl_calloc_array(ctx, struct isl_aff_split, map->n);
    1293           0 :         if (!split)
    1294           0 :                 return NULL;
    1295             : 
    1296           0 :         for (i = 0; i < map->n; ++i) {
    1297             :                 isl_basic_map *bmap;
    1298           0 :                 split[i].aff = get_aff(isl_basic_map_copy(map->p[i]));
    1299           0 :                 bmap = isl_basic_map_copy(map->p[i]);
    1300           0 :                 bmap = isl_basic_map_cow(bmap);
    1301           0 :                 bmap = drop_aff(bmap, split[i].aff);
    1302           0 :                 split[i].map = isl_map_from_basic_map(bmap);
    1303           0 :                 if (!split[i].aff || !split[i].map)
    1304             :                         goto error;
    1305             :         }
    1306             : 
    1307           0 :         if (isl_sort(split, map->n, sizeof(struct isl_aff_split),
    1308             :                         &aff_split_cmp, NULL) < 0)
    1309           0 :                 goto error;
    1310             : 
    1311           0 :         n = map->n;
    1312           0 :         for (i = n - 1; i >= 1; --i) {
    1313           0 :                 if (!isl_basic_map_plain_is_equal(split[i - 1].aff,
    1314           0 :                                                  split[i].aff))
    1315           0 :                         continue;
    1316           0 :                 isl_basic_map_free(split[i].aff);
    1317           0 :                 split[i - 1].map = isl_map_union(split[i - 1].map,
    1318           0 :                                                  split[i].map);
    1319           0 :                 if (i != n - 1)
    1320           0 :                         split[i] = split[n - 1];
    1321           0 :                 split[n - 1].aff = NULL;
    1322           0 :                 split[n - 1].map = NULL;
    1323           0 :                 --n;
    1324             :         }
    1325             : 
    1326           0 :         return split;
    1327             : error:
    1328           0 :         free_split(split, map->n);
    1329           0 :         return NULL;
    1330             : }
    1331             : 
    1332           0 : static int defining_equality(__isl_keep isl_basic_map *eq,
    1333             :         __isl_keep isl_space *dim, enum isl_dim_type type, int pos)
    1334             : {
    1335             :         int i;
    1336             :         unsigned total;
    1337             : 
    1338           0 :         if (!eq)
    1339           0 :                 return -1;
    1340             : 
    1341           0 :         pos += isl_space_offset(dim, type);
    1342           0 :         total = isl_basic_map_total_dim(eq);
    1343             : 
    1344           0 :         for (i = 0; i < eq->n_eq; ++i) {
    1345           0 :                 if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos)
    1346           0 :                         continue;
    1347           0 :                 if (isl_int_is_one(eq->eq[i][1 + pos]))
    1348           0 :                         isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total);
    1349           0 :                 return i;
    1350             :         }
    1351             : 
    1352           0 :         return -1;
    1353             : }
    1354             : 
    1355             : /* Print dimension "pos" of data->space to "p".
    1356             :  *
    1357             :  * data->user is assumed to be an isl_basic_map keeping track of equalities.
    1358             :  *
    1359             :  * If the current dimension is defined by these equalities, then print
    1360             :  * the corresponding expression, assigned to the name of the dimension
    1361             :  * if there is any.  Otherwise, print the name of the dimension.
    1362             :  */
    1363           0 : static __isl_give isl_printer *print_dim_eq(__isl_take isl_printer *p,
    1364             :         struct isl_print_space_data *data, unsigned pos)
    1365             : {
    1366           0 :         isl_basic_map *eq = data->user;
    1367             :         int j;
    1368             : 
    1369           0 :         j = defining_equality(eq, data->space, data->type, pos);
    1370           0 :         if (j >= 0) {
    1371           0 :                 if (isl_space_has_dim_name(data->space, data->type, pos)) {
    1372           0 :                         p = print_name(data->space, p, data->type, pos,
    1373             :                                         data->latex);
    1374           0 :                         p = isl_printer_print_str(p, " = ");
    1375             :                 }
    1376           0 :                 pos += 1 + isl_space_offset(data->space, data->type);
    1377           0 :                 p = print_affine_of_len(data->space, NULL, p, eq->eq[j], pos);
    1378             :         } else {
    1379           0 :                 p = print_name(data->space, p, data->type, pos, data->latex);
    1380             :         }
    1381             : 
    1382           0 :         return p;
    1383             : }
    1384             : 
    1385           0 : static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p,
    1386             :         struct isl_aff_split *split, int n, __isl_keep isl_space *space)
    1387             : {
    1388           0 :         struct isl_print_space_data data = { 0 };
    1389             :         int i;
    1390             :         int rational;
    1391             : 
    1392           0 :         data.print_dim = &print_dim_eq;
    1393           0 :         for (i = 0; i < n; ++i) {
    1394           0 :                 if (!split[i].map)
    1395           0 :                         break;
    1396           0 :                 rational = split[i].map->n > 0 &&
    1397           0 :                     ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL);
    1398           0 :                 if (i)
    1399           0 :                         p = isl_printer_print_str(p, "; ");
    1400           0 :                 data.user = split[i].aff;
    1401           0 :                 p = isl_print_space(space, p, rational, &data);
    1402           0 :                 p = print_disjuncts_map(split[i].map, space, p, 0);
    1403             :         }
    1404             : 
    1405           0 :         return p;
    1406             : }
    1407             : 
    1408      225906 : static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map,
    1409             :         __isl_take isl_printer *p)
    1410             : {
    1411      225906 :         struct isl_print_space_data data = { 0 };
    1412      225906 :         struct isl_aff_split *split = NULL;
    1413             :         int rational;
    1414             : 
    1415      225906 :         if (!p || !map)
    1416           0 :                 return isl_printer_free(p);
    1417      225906 :         if (!p->dump && map->n > 0)
    1418           0 :                 split = split_aff(map);
    1419      225906 :         if (split) {
    1420           0 :                 p = print_split_map(p, split, map->n, map->dim);
    1421             :         } else {
    1422      451812 :                 rational = map->n > 0 &&
    1423      225906 :                     ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL);
    1424      225906 :                 p = isl_print_space(map->dim, p, rational, &data);
    1425      225906 :                 p = print_disjuncts_map(map, map->dim, p, 0);
    1426             :         }
    1427      225906 :         free_split(split, map->n);
    1428      225906 :         return p;
    1429             : }
    1430             : 
    1431      225906 : static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,
    1432             :         __isl_take isl_printer *p)
    1433             : {
    1434      225906 :         struct isl_print_space_data data = { 0 };
    1435             : 
    1436      225906 :         p = print_param_tuple(p, map->dim, &data);
    1437      225906 :         p = isl_printer_print_str(p, s_open_set[0]);
    1438      225906 :         p = isl_map_print_isl_body(map, p);
    1439      225906 :         p = isl_printer_print_str(p, s_close_set[0]);
    1440      225906 :         return p;
    1441             : }
    1442             : 
    1443           0 : static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map,
    1444             :         __isl_take isl_printer *p, __isl_keep isl_basic_map *aff)
    1445             : {
    1446           0 :         struct isl_print_space_data data = { 0 };
    1447             : 
    1448           0 :         data.latex = 1;
    1449           0 :         p = print_param_tuple(p, map->dim, &data);
    1450           0 :         p = isl_printer_print_str(p, s_open_set[1]);
    1451           0 :         data.print_dim = &print_dim_eq;
    1452           0 :         data.user = aff;
    1453           0 :         p = isl_print_space(map->dim, p, 0, &data);
    1454           0 :         p = print_disjuncts_map(map, map->dim, p, 1);
    1455           0 :         p = isl_printer_print_str(p, s_close_set[1]);
    1456             : 
    1457           0 :         return p;
    1458             : }
    1459             : 
    1460           0 : static __isl_give isl_printer *isl_map_print_latex(__isl_keep isl_map *map,
    1461             :         __isl_take isl_printer *p)
    1462             : {
    1463             :         int i;
    1464           0 :         struct isl_aff_split *split = NULL;
    1465             : 
    1466           0 :         if (map->n > 0)
    1467           0 :                 split = split_aff(map);
    1468             : 
    1469           0 :         if (!split)
    1470           0 :                 return print_latex_map(map, p, NULL);
    1471             : 
    1472           0 :         for (i = 0; i < map->n; ++i) {
    1473           0 :                 if (!split[i].map)
    1474           0 :                         break;
    1475           0 :                 if (i)
    1476           0 :                         p = isl_printer_print_str(p, " \\cup ");
    1477           0 :                 p = print_latex_map(split[i].map, p, split[i].aff);
    1478             :         }
    1479             : 
    1480           0 :         free_split(split, map->n);
    1481           0 :         return p;
    1482             : }
    1483             : 
    1484           0 : __isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p,
    1485             :         __isl_keep isl_basic_map *bmap)
    1486             : {
    1487           0 :         if (!p || !bmap)
    1488             :                 goto error;
    1489           0 :         if (p->output_format == ISL_FORMAT_ISL)
    1490           0 :                 return isl_basic_map_print_isl(bmap, p, 0);
    1491           0 :         else if (p->output_format == ISL_FORMAT_OMEGA)
    1492           0 :                 return basic_map_print_omega(bmap, p);
    1493           0 :         isl_assert(bmap->ctx, 0, goto error);
    1494             : error:
    1495           0 :         isl_printer_free(p);
    1496           0 :         return NULL;
    1497             : }
    1498             : 
    1499           0 : __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,
    1500             :         __isl_keep isl_basic_set *bset)
    1501             : {
    1502           0 :         if (!p || !bset)
    1503             :                 goto error;
    1504             : 
    1505           0 :         if (p->output_format == ISL_FORMAT_ISL)
    1506           0 :                 return isl_basic_map_print_isl(bset, p, 0);
    1507           0 :         else if (p->output_format == ISL_FORMAT_POLYLIB)
    1508           0 :                 return isl_basic_set_print_polylib(bset, p, 0);
    1509           0 :         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
    1510           0 :                 return isl_basic_set_print_polylib(bset, p, 1);
    1511           0 :         else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)
    1512           0 :                 return bset_print_constraints_polylib(bset, p);
    1513           0 :         else if (p->output_format == ISL_FORMAT_OMEGA)
    1514           0 :                 return basic_set_print_omega(bset, p);
    1515           0 :         isl_assert(p->ctx, 0, goto error);
    1516             : error:
    1517           0 :         isl_printer_free(p);
    1518           0 :         return NULL;
    1519             : }
    1520             : 
    1521      225906 : __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,
    1522             :         __isl_keep isl_set *set)
    1523             : {
    1524      225906 :         if (!p || !set)
    1525             :                 goto error;
    1526      225906 :         if (p->output_format == ISL_FORMAT_ISL)
    1527      225906 :                 return isl_map_print_isl(set_to_map(set), p);
    1528           0 :         else if (p->output_format == ISL_FORMAT_POLYLIB)
    1529           0 :                 return isl_set_print_polylib(set, p, 0);
    1530           0 :         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
    1531           0 :                 return isl_set_print_polylib(set, p, 1);
    1532           0 :         else if (p->output_format == ISL_FORMAT_OMEGA)
    1533           0 :                 return isl_set_print_omega(set, p);
    1534           0 :         else if (p->output_format == ISL_FORMAT_LATEX)
    1535           0 :                 return isl_map_print_latex(set_to_map(set), p);
    1536           0 :         isl_assert(set->ctx, 0, goto error);
    1537             : error:
    1538           0 :         isl_printer_free(p);
    1539           0 :         return NULL;
    1540             : }
    1541             : 
    1542           0 : __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
    1543             :         __isl_keep isl_map *map)
    1544             : {
    1545           0 :         if (!p || !map)
    1546             :                 goto error;
    1547             : 
    1548           0 :         if (p->output_format == ISL_FORMAT_ISL)
    1549           0 :                 return isl_map_print_isl(map, p);
    1550           0 :         else if (p->output_format == ISL_FORMAT_POLYLIB)
    1551           0 :                 return isl_map_print_polylib(map, p, 0);
    1552           0 :         else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
    1553           0 :                 return isl_map_print_polylib(map, p, 1);
    1554           0 :         else if (p->output_format == ISL_FORMAT_OMEGA)
    1555           0 :                 return isl_map_print_omega(map, p);
    1556           0 :         else if (p->output_format == ISL_FORMAT_LATEX)
    1557           0 :                 return isl_map_print_latex(map, p);
    1558           0 :         isl_assert(map->ctx, 0, goto error);
    1559             : error:
    1560           0 :         isl_printer_free(p);
    1561           0 :         return NULL;
    1562             : }
    1563             : 
    1564             : struct isl_union_print_data {
    1565             :         isl_printer *p;
    1566             :         int first;
    1567             : };
    1568             : 
    1569           0 : static isl_stat print_map_body(__isl_take isl_map *map, void *user)
    1570             : {
    1571             :         struct isl_union_print_data *data;
    1572           0 :         data = (struct isl_union_print_data *)user;
    1573             : 
    1574           0 :         if (!data->first)
    1575           0 :                 data->p = isl_printer_print_str(data->p, "; ");
    1576           0 :         data->first = 0;
    1577             : 
    1578           0 :         data->p = isl_map_print_isl_body(map, data->p);
    1579           0 :         isl_map_free(map);
    1580             : 
    1581           0 :         return isl_stat_ok;
    1582             : }
    1583             : 
    1584             : /* Print the body of "umap" (everything except the parameter declarations)
    1585             :  * to "p" in isl format.
    1586             :  */
    1587           0 : static __isl_give isl_printer *isl_printer_print_union_map_isl_body(
    1588             :         __isl_take isl_printer *p, __isl_keep isl_union_map *umap)
    1589             : {
    1590             :         struct isl_union_print_data data;
    1591             : 
    1592           0 :         p = isl_printer_print_str(p, s_open_set[0]);
    1593           0 :         data.p = p;
    1594           0 :         data.first = 1;
    1595           0 :         isl_union_map_foreach_map(umap, &print_map_body, &data);
    1596           0 :         p = data.p;
    1597           0 :         p = isl_printer_print_str(p, s_close_set[0]);
    1598           0 :         return p;
    1599             : }
    1600             : 
    1601             : /* Print the body of "uset" (everything except the parameter declarations)
    1602             :  * to "p" in isl format.
    1603             :  */
    1604           0 : static __isl_give isl_printer *isl_printer_print_union_set_isl_body(
    1605             :         __isl_take isl_printer *p, __isl_keep isl_union_set *uset)
    1606             : {
    1607           0 :         return isl_printer_print_union_map_isl_body(p, uset_to_umap(uset));
    1608             : }
    1609             : 
    1610             : /* Print the isl_union_map "umap" to "p" in isl format.
    1611             :  */
    1612           0 : static __isl_give isl_printer *isl_union_map_print_isl(
    1613             :         __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
    1614             : {
    1615           0 :         struct isl_print_space_data space_data = { 0 };
    1616             :         isl_space *space;
    1617             : 
    1618           0 :         space = isl_union_map_get_space(umap);
    1619           0 :         p = print_param_tuple(p, space, &space_data);
    1620           0 :         isl_space_free(space);
    1621             : 
    1622           0 :         p = isl_printer_print_union_map_isl_body(p, umap);
    1623             : 
    1624           0 :         return p;
    1625             : }
    1626             : 
    1627           0 : static isl_stat print_latex_map_body(__isl_take isl_map *map, void *user)
    1628             : {
    1629             :         struct isl_union_print_data *data;
    1630           0 :         data = (struct isl_union_print_data *)user;
    1631             : 
    1632           0 :         if (!data->first)
    1633           0 :                 data->p = isl_printer_print_str(data->p, " \\cup ");
    1634           0 :         data->first = 0;
    1635             : 
    1636           0 :         data->p = isl_map_print_latex(map, data->p);
    1637           0 :         isl_map_free(map);
    1638             : 
    1639           0 :         return isl_stat_ok;
    1640             : }
    1641             : 
    1642           0 : static __isl_give isl_printer *isl_union_map_print_latex(
    1643             :         __isl_keep isl_union_map *umap, __isl_take isl_printer *p)
    1644             : {
    1645           0 :         struct isl_union_print_data data = { p, 1 };
    1646           0 :         isl_union_map_foreach_map(umap, &print_latex_map_body, &data);
    1647           0 :         p = data.p;
    1648           0 :         return p;
    1649             : }
    1650             : 
    1651           0 : __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p,
    1652             :         __isl_keep isl_union_map *umap)
    1653             : {
    1654           0 :         if (!p || !umap)
    1655             :                 goto error;
    1656             : 
    1657           0 :         if (p->output_format == ISL_FORMAT_ISL)
    1658           0 :                 return isl_union_map_print_isl(umap, p);
    1659           0 :         if (p->output_format == ISL_FORMAT_LATEX)
    1660           0 :                 return isl_union_map_print_latex(umap, p);
    1661             : 
    1662           0 :         isl_die(p->ctx, isl_error_invalid,
    1663             :                 "invalid output format for isl_union_map", goto error);
    1664             : error:
    1665           0 :         isl_printer_free(p);
    1666           0 :         return NULL;
    1667             : }
    1668             : 
    1669           0 : __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
    1670             :         __isl_keep isl_union_set *uset)
    1671             : {
    1672           0 :         if (!p || !uset)
    1673             :                 goto error;
    1674             : 
    1675           0 :         if (p->output_format == ISL_FORMAT_ISL)
    1676           0 :                 return isl_union_map_print_isl(uset_to_umap(uset), p);
    1677           0 :         if (p->output_format == ISL_FORMAT_LATEX)
    1678           0 :                 return isl_union_map_print_latex(uset_to_umap(uset), p);
    1679             : 
    1680           0 :         isl_die(p->ctx, isl_error_invalid,
    1681             :                 "invalid output format for isl_union_set", goto error);
    1682             : error:
    1683           0 :         isl_printer_free(p);
    1684           0 :         return NULL;
    1685             : }
    1686             : 
    1687           0 : static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec)
    1688             : {
    1689             :         int i;
    1690             :         int n;
    1691             : 
    1692           0 :         for (i = 0, n = 0; i < rec->n; ++i)
    1693           0 :                 if (!isl_upoly_is_zero(rec->p[i]))
    1694           0 :                         ++n;
    1695             : 
    1696           0 :         return n;
    1697             : }
    1698             : 
    1699           0 : static __isl_give isl_printer *upoly_print_cst(__isl_keep struct isl_upoly *up,
    1700             :         __isl_take isl_printer *p, int first)
    1701             : {
    1702             :         struct isl_upoly_cst *cst;
    1703             :         int neg;
    1704             : 
    1705           0 :         cst = isl_upoly_as_cst(up);
    1706           0 :         if (!cst)
    1707           0 :                 goto error;
    1708           0 :         neg = !first && isl_int_is_neg(cst->n);
    1709           0 :         if (!first)
    1710           0 :                 p = isl_printer_print_str(p, neg ? " - " :  " + ");
    1711           0 :         if (neg)
    1712           0 :                 isl_int_neg(cst->n, cst->n);
    1713           0 :         if (isl_int_is_zero(cst->d)) {
    1714           0 :                 int sgn = isl_int_sgn(cst->n);
    1715           0 :                 p = isl_printer_print_str(p, sgn < 0 ? "-infty" :
    1716             :                                             sgn == 0 ? "NaN" : "infty");
    1717             :         } else
    1718           0 :                 p = isl_printer_print_isl_int(p, cst->n);
    1719           0 :         if (neg)
    1720           0 :                 isl_int_neg(cst->n, cst->n);
    1721           0 :         if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) {
    1722           0 :                 p = isl_printer_print_str(p, "/");
    1723           0 :                 p = isl_printer_print_isl_int(p, cst->d);
    1724             :         }
    1725           0 :         return p;
    1726             : error:
    1727           0 :         isl_printer_free(p);
    1728           0 :         return NULL;
    1729             : }
    1730             : 
    1731           0 : static __isl_give isl_printer *print_base(__isl_take isl_printer *p,
    1732             :         __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var)
    1733             : {
    1734             :         unsigned total;
    1735             : 
    1736           0 :         total = isl_space_dim(dim, isl_dim_all);
    1737           0 :         if (var < total)
    1738           0 :                 p = print_term(dim, NULL, dim->ctx->one, 1 + var, p, 0);
    1739             :         else
    1740           0 :                 p = print_div(dim, div, var - total, p);
    1741           0 :         return p;
    1742             : }
    1743             : 
    1744           0 : static __isl_give isl_printer *print_pow(__isl_take isl_printer *p,
    1745             :         __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var, int exp)
    1746             : {
    1747           0 :         p = print_base(p, dim, div, var);
    1748           0 :         if (exp == 1)
    1749           0 :                 return p;
    1750           0 :         if (p->output_format == ISL_FORMAT_C) {
    1751             :                 int i;
    1752           0 :                 for (i = 1; i < exp; ++i) {
    1753           0 :                         p = isl_printer_print_str(p, "*");
    1754           0 :                         p = print_base(p, dim, div, var);
    1755             :                 }
    1756             :         } else {
    1757           0 :                 p = isl_printer_print_str(p, "^");
    1758           0 :                 p = isl_printer_print_int(p, exp);
    1759             :         }
    1760           0 :         return p;
    1761             : }
    1762             : 
    1763             : /* Print the polynomial "up" defined over the domain space "space" and
    1764             :  * local variables defined by "div" to "p".
    1765             :  */
    1766           0 : static __isl_give isl_printer *upoly_print(__isl_keep struct isl_upoly *up,
    1767             :         __isl_keep isl_space *space, __isl_keep isl_mat *div,
    1768             :         __isl_take isl_printer *p)
    1769             : {
    1770             :         int i, n, first, print_parens;
    1771             :         struct isl_upoly_rec *rec;
    1772             : 
    1773           0 :         if (!p || !up || !space || !div)
    1774             :                 goto error;
    1775             : 
    1776           0 :         if (isl_upoly_is_cst(up))
    1777           0 :                 return upoly_print_cst(up, p, 1);
    1778             : 
    1779           0 :         rec = isl_upoly_as_rec(up);
    1780           0 :         if (!rec)
    1781           0 :                 goto error;
    1782           0 :         n = upoly_rec_n_non_zero(rec);
    1783           0 :         print_parens = n > 1;
    1784           0 :         if (print_parens)
    1785           0 :                 p = isl_printer_print_str(p, "(");
    1786           0 :         for (i = 0, first = 1; i < rec->n; ++i) {
    1787           0 :                 if (isl_upoly_is_zero(rec->p[i]))
    1788           0 :                         continue;
    1789           0 :                 if (isl_upoly_is_negone(rec->p[i])) {
    1790           0 :                         if (!i)
    1791           0 :                                 p = isl_printer_print_str(p, "-1");
    1792           0 :                         else if (first)
    1793           0 :                                 p = isl_printer_print_str(p, "-");
    1794             :                         else
    1795           0 :                                 p = isl_printer_print_str(p, " - ");
    1796           0 :                 } else if (isl_upoly_is_cst(rec->p[i]) &&
    1797           0 :                                 !isl_upoly_is_one(rec->p[i]))
    1798           0 :                         p = upoly_print_cst(rec->p[i], p, first);
    1799             :                 else {
    1800           0 :                         if (!first)
    1801           0 :                                 p = isl_printer_print_str(p, " + ");
    1802           0 :                         if (i == 0 || !isl_upoly_is_one(rec->p[i]))
    1803           0 :                                 p = upoly_print(rec->p[i], space, div, p);
    1804             :                 }
    1805           0 :                 first = 0;
    1806           0 :                 if (i == 0)
    1807           0 :                         continue;
    1808           0 :                 if (!isl_upoly_is_one(rec->p[i]) &&
    1809           0 :                     !isl_upoly_is_negone(rec->p[i]))
    1810           0 :                         p = isl_printer_print_str(p, " * ");
    1811           0 :                 p = print_pow(p, space, div, rec->up.var, i);
    1812             :         }
    1813           0 :         if (print_parens)
    1814           0 :                 p = isl_printer_print_str(p, ")");
    1815           0 :         return p;
    1816             : error:
    1817           0 :         isl_printer_free(p);
    1818           0 :         return NULL;
    1819             : }
    1820             : 
    1821           0 : static __isl_give isl_printer *print_qpolynomial(__isl_take isl_printer *p,
    1822             :         __isl_keep isl_qpolynomial *qp)
    1823             : {
    1824           0 :         if (!p || !qp)
    1825             :                 goto error;
    1826           0 :         p = upoly_print(qp->upoly, qp->dim, qp->div, p);
    1827           0 :         return p;
    1828             : error:
    1829           0 :         isl_printer_free(p);
    1830           0 :         return NULL;
    1831             : }
    1832             : 
    1833           0 : static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p,
    1834             :         __isl_keep isl_qpolynomial *qp)
    1835             : {
    1836           0 :         struct isl_print_space_data data = { 0 };
    1837             : 
    1838           0 :         if (!p || !qp)
    1839             :                 goto error;
    1840             : 
    1841           0 :         p = print_param_tuple(p, qp->dim, &data);
    1842           0 :         p = isl_printer_print_str(p, "{ ");
    1843           0 :         if (!isl_space_is_params(qp->dim)) {
    1844           0 :                 p = isl_print_space(qp->dim, p, 0, &data);
    1845           0 :                 p = isl_printer_print_str(p, " -> ");
    1846             :         }
    1847           0 :         p = print_qpolynomial(p, qp);
    1848           0 :         p = isl_printer_print_str(p, " }");
    1849           0 :         return p;
    1850             : error:
    1851           0 :         isl_printer_free(p);
    1852           0 :         return NULL;
    1853             : }
    1854             : 
    1855             : /* Print the quasi-polynomial "qp" to "p" in C format, with the variable names
    1856             :  * taken from the domain space "space".
    1857             :  */
    1858           0 : static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p,
    1859             :         __isl_keep isl_space *space, __isl_keep isl_qpolynomial *qp)
    1860             : {
    1861             :         isl_int den;
    1862             : 
    1863           0 :         isl_int_init(den);
    1864           0 :         isl_qpolynomial_get_den(qp, &den);
    1865           0 :         if (!isl_int_is_one(den)) {
    1866             :                 isl_qpolynomial *f;
    1867           0 :                 p = isl_printer_print_str(p, "(");
    1868           0 :                 qp = isl_qpolynomial_copy(qp);
    1869           0 :                 f = isl_qpolynomial_rat_cst_on_domain(isl_space_copy(qp->dim),
    1870           0 :                                                 den, qp->dim->ctx->one);
    1871           0 :                 qp = isl_qpolynomial_mul(qp, f);
    1872             :         }
    1873           0 :         if (qp)
    1874           0 :                 p = upoly_print(qp->upoly, space, qp->div, p);
    1875             :         else
    1876           0 :                 p = isl_printer_free(p);
    1877           0 :         if (!isl_int_is_one(den)) {
    1878           0 :                 p = isl_printer_print_str(p, ")/");
    1879           0 :                 p = isl_printer_print_isl_int(p, den);
    1880           0 :                 isl_qpolynomial_free(qp);
    1881             :         }
    1882           0 :         isl_int_clear(den);
    1883           0 :         return p;
    1884             : }
    1885             : 
    1886           0 : __isl_give isl_printer *isl_printer_print_qpolynomial(
    1887             :         __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp)
    1888             : {
    1889           0 :         if (!p || !qp)
    1890             :                 goto error;
    1891             : 
    1892           0 :         if (p->output_format == ISL_FORMAT_ISL)
    1893           0 :                 return print_qpolynomial_isl(p, qp);
    1894           0 :         else if (p->output_format == ISL_FORMAT_C)
    1895           0 :                 return print_qpolynomial_c(p, qp->dim, qp);
    1896             :         else
    1897           0 :                 isl_die(qp->dim->ctx, isl_error_unsupported,
    1898             :                         "output format not supported for isl_qpolynomials",
    1899             :                         goto error);
    1900             : error:
    1901           0 :         isl_printer_free(p);
    1902           0 :         return NULL;
    1903             : }
    1904             : 
    1905           0 : void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
    1906             :         unsigned output_format)
    1907             : {
    1908             :         isl_printer *p;
    1909             : 
    1910           0 :         if  (!qp)
    1911           0 :                 return;
    1912             : 
    1913           0 :         isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return);
    1914           0 :         p = isl_printer_to_file(qp->dim->ctx, out);
    1915           0 :         p = isl_printer_print_qpolynomial(p, qp);
    1916           0 :         isl_printer_free(p);
    1917             : }
    1918             : 
    1919           0 : static __isl_give isl_printer *qpolynomial_fold_print(
    1920             :         __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p)
    1921             : {
    1922             :         int i;
    1923             : 
    1924           0 :         if (fold->type == isl_fold_min)
    1925           0 :                 p = isl_printer_print_str(p, "min");
    1926           0 :         else if (fold->type == isl_fold_max)
    1927           0 :                 p = isl_printer_print_str(p, "max");
    1928           0 :         p = isl_printer_print_str(p, "(");
    1929           0 :         for (i = 0; i < fold->n; ++i) {
    1930           0 :                 if (i)
    1931           0 :                         p = isl_printer_print_str(p, ", ");
    1932           0 :                 p = print_qpolynomial(p, fold->qp[i]);
    1933             :         }
    1934           0 :         p = isl_printer_print_str(p, ")");
    1935           0 :         return p;
    1936             : }
    1937             : 
    1938           0 : void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
    1939             :         FILE *out, unsigned output_format)
    1940             : {
    1941             :         isl_printer *p;
    1942             : 
    1943           0 :         if (!fold)
    1944           0 :                 return;
    1945             : 
    1946           0 :         isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return);
    1947             : 
    1948           0 :         p = isl_printer_to_file(fold->dim->ctx, out);
    1949           0 :         p = isl_printer_print_qpolynomial_fold(p, fold);
    1950             : 
    1951           0 :         isl_printer_free(p);
    1952             : }
    1953             : 
    1954           0 : static __isl_give isl_printer *isl_pwqp_print_isl_body(
    1955             :         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
    1956             : {
    1957           0 :         struct isl_print_space_data data = { 0 };
    1958           0 :         int i = 0;
    1959             : 
    1960           0 :         for (i = 0; i < pwqp->n; ++i) {
    1961             :                 isl_space *space;
    1962             : 
    1963           0 :                 if (i)
    1964           0 :                         p = isl_printer_print_str(p, "; ");
    1965           0 :                 space = isl_qpolynomial_get_domain_space(pwqp->p[i].qp);
    1966           0 :                 if (!isl_space_is_params(space)) {
    1967           0 :                         p = isl_print_space(space, p, 0, &data);
    1968           0 :                         p = isl_printer_print_str(p, " -> ");
    1969             :                 }
    1970           0 :                 p = print_qpolynomial(p, pwqp->p[i].qp);
    1971           0 :                 p = print_disjuncts(set_to_map(pwqp->p[i].set), space, p, 0);
    1972           0 :                 isl_space_free(space);
    1973             :         }
    1974             : 
    1975           0 :         return p;
    1976             : }
    1977             : 
    1978           0 : static __isl_give isl_printer *print_pw_qpolynomial_isl(
    1979             :         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
    1980             : {
    1981           0 :         struct isl_print_space_data data = { 0 };
    1982             : 
    1983           0 :         if (!p || !pwqp)
    1984             :                 goto error;
    1985             : 
    1986           0 :         p = print_param_tuple(p, pwqp->dim, &data);
    1987           0 :         p = isl_printer_print_str(p, "{ ");
    1988           0 :         if (pwqp->n == 0) {
    1989           0 :                 if (!isl_space_is_set(pwqp->dim)) {
    1990           0 :                         p = print_tuple(pwqp->dim, p, isl_dim_in, &data);
    1991           0 :                         p = isl_printer_print_str(p, " -> ");
    1992             :                 }
    1993           0 :                 p = isl_printer_print_str(p, "0");
    1994             :         }
    1995           0 :         p = isl_pwqp_print_isl_body(p, pwqp);
    1996           0 :         p = isl_printer_print_str(p, " }");
    1997           0 :         return p;
    1998             : error:
    1999           0 :         isl_printer_free(p);
    2000           0 :         return NULL;
    2001             : }
    2002             : 
    2003           0 : void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
    2004             :         unsigned output_format)
    2005             : {
    2006             :         isl_printer *p;
    2007             : 
    2008           0 :         if (!pwqp)
    2009           0 :                 return;
    2010             : 
    2011           0 :         p = isl_printer_to_file(pwqp->dim->ctx, out);
    2012           0 :         p = isl_printer_set_output_format(p, output_format);
    2013           0 :         p = isl_printer_print_pw_qpolynomial(p, pwqp);
    2014             : 
    2015           0 :         isl_printer_free(p);
    2016             : }
    2017             : 
    2018           0 : static __isl_give isl_printer *isl_pwf_print_isl_body(
    2019             :         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
    2020             : {
    2021           0 :         struct isl_print_space_data data = { 0 };
    2022           0 :         int i = 0;
    2023             : 
    2024           0 :         for (i = 0; i < pwf->n; ++i) {
    2025             :                 isl_space *space;
    2026             : 
    2027           0 :                 if (i)
    2028           0 :                         p = isl_printer_print_str(p, "; ");
    2029           0 :                 space = isl_qpolynomial_fold_get_domain_space(pwf->p[i].fold);
    2030           0 :                 if (!isl_space_is_params(space)) {
    2031           0 :                         p = isl_print_space(space, p, 0, &data);
    2032           0 :                         p = isl_printer_print_str(p, " -> ");
    2033             :                 }
    2034           0 :                 p = qpolynomial_fold_print(pwf->p[i].fold, p);
    2035           0 :                 p = print_disjuncts(set_to_map(pwf->p[i].set), space, p, 0);
    2036           0 :                 isl_space_free(space);
    2037             :         }
    2038             : 
    2039           0 :         return p;
    2040             : }
    2041             : 
    2042           0 : static __isl_give isl_printer *print_pw_qpolynomial_fold_isl(
    2043             :         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
    2044             : {
    2045           0 :         struct isl_print_space_data data = { 0 };
    2046             : 
    2047           0 :         p = print_param_tuple(p, pwf->dim, &data);
    2048           0 :         p = isl_printer_print_str(p, "{ ");
    2049           0 :         if (pwf->n == 0) {
    2050           0 :                 if (!isl_space_is_set(pwf->dim)) {
    2051           0 :                         p = print_tuple(pwf->dim, p, isl_dim_in, &data);
    2052           0 :                         p = isl_printer_print_str(p, " -> ");
    2053             :                 }
    2054           0 :                 p = isl_printer_print_str(p, "0");
    2055             :         }
    2056           0 :         p = isl_pwf_print_isl_body(p, pwf);
    2057           0 :         p = isl_printer_print_str(p, " }");
    2058           0 :         return p;
    2059             : }
    2060             : 
    2061             : static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
    2062             :         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c);
    2063             : 
    2064           0 : static __isl_give isl_printer *print_name_c(__isl_take isl_printer *p,
    2065             :         __isl_keep isl_space *dim,
    2066             :         __isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos)
    2067             : {
    2068           0 :         if (type == isl_dim_div) {
    2069           0 :                 p = isl_printer_print_str(p, "floord(");
    2070           0 :                 p = print_affine_c(p, dim, bset, bset->div[pos] + 1);
    2071           0 :                 p = isl_printer_print_str(p, ", ");
    2072           0 :                 p = isl_printer_print_isl_int(p, bset->div[pos][0]);
    2073           0 :                 p = isl_printer_print_str(p, ")");
    2074             :         } else {
    2075             :                 const char *name;
    2076             : 
    2077           0 :                 name = isl_space_get_dim_name(dim, type, pos);
    2078           0 :                 if (!name)
    2079           0 :                         name = "UNNAMED";
    2080           0 :                 p = isl_printer_print_str(p, name);
    2081             :         }
    2082           0 :         return p;
    2083             : }
    2084             : 
    2085           0 : static __isl_give isl_printer *print_term_c(__isl_take isl_printer *p,
    2086             :         __isl_keep isl_space *space,
    2087             :         __isl_keep isl_basic_set *bset, isl_int c, unsigned pos)
    2088             : {
    2089             :         enum isl_dim_type type;
    2090             : 
    2091           0 :         if (!p || !space)
    2092           0 :                 return isl_printer_free(p);
    2093             : 
    2094           0 :         if (pos == 0)
    2095           0 :                 return isl_printer_print_isl_int(p, c);
    2096             : 
    2097           0 :         if (isl_int_is_one(c))
    2098             :                 ;
    2099           0 :         else if (isl_int_is_negone(c))
    2100           0 :                 p = isl_printer_print_str(p, "-");
    2101             :         else {
    2102           0 :                 p = isl_printer_print_isl_int(p, c);
    2103           0 :                 p = isl_printer_print_str(p, "*");
    2104             :         }
    2105           0 :         type = pos2type(space, &pos);
    2106           0 :         p = print_name_c(p, space, bset, type, pos);
    2107           0 :         return p;
    2108             : }
    2109             : 
    2110           0 : static __isl_give isl_printer *print_partial_affine_c(__isl_take isl_printer *p,
    2111             :         __isl_keep isl_space *dim,
    2112             :         __isl_keep isl_basic_set *bset, isl_int *c, unsigned len)
    2113             : {
    2114             :         int i;
    2115             :         int first;
    2116             : 
    2117           0 :         for (i = 0, first = 1; i < len; ++i) {
    2118           0 :                 int flip = 0;
    2119           0 :                 if (isl_int_is_zero(c[i]))
    2120           0 :                         continue;
    2121           0 :                 if (!first) {
    2122           0 :                         if (isl_int_is_neg(c[i])) {
    2123           0 :                                 flip = 1;
    2124           0 :                                 isl_int_neg(c[i], c[i]);
    2125           0 :                                 p = isl_printer_print_str(p, " - ");
    2126             :                         } else 
    2127           0 :                                 p = isl_printer_print_str(p, " + ");
    2128             :                 }
    2129           0 :                 first = 0;
    2130           0 :                 p = print_term_c(p, dim, bset, c[i], i);
    2131           0 :                 if (flip)
    2132           0 :                         isl_int_neg(c[i], c[i]);
    2133             :         }
    2134           0 :         if (first)
    2135           0 :                 p = isl_printer_print_str(p, "0");
    2136           0 :         return p;
    2137             : }
    2138             : 
    2139           0 : static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p,
    2140             :         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c)
    2141             : {
    2142           0 :         unsigned len = 1 + isl_basic_set_total_dim(bset);
    2143           0 :         return print_partial_affine_c(p, dim, bset, c, len);
    2144             : }
    2145             : 
    2146             : /* We skip the constraint if it is implied by the div expression.
    2147             :  *
    2148             :  * *first indicates whether this is the first constraint in the conjunction and
    2149             :  * is updated if the constraint is actually printed.
    2150             :  */
    2151           0 : static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p,
    2152             :         __isl_keep isl_space *dim,
    2153             :         __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int *first)
    2154             : {
    2155             :         unsigned o_div;
    2156             :         unsigned n_div;
    2157             :         int div;
    2158             : 
    2159           0 :         o_div = isl_basic_set_offset(bset, isl_dim_div);
    2160           0 :         n_div = isl_basic_set_dim(bset, isl_dim_div);
    2161           0 :         div = isl_seq_last_non_zero(c + o_div, n_div);
    2162           0 :         if (div >= 0) {
    2163           0 :                 isl_bool is_div = isl_basic_set_is_div_constraint(bset, c, div);
    2164           0 :                 if (is_div < 0)
    2165           0 :                         return isl_printer_free(p);
    2166           0 :                 if (is_div)
    2167           0 :                         return p;
    2168             :         }
    2169             : 
    2170           0 :         if (!*first)
    2171           0 :                 p = isl_printer_print_str(p, " && ");
    2172             : 
    2173           0 :         p = print_affine_c(p, dim, bset, c);
    2174           0 :         p = isl_printer_print_str(p, " ");
    2175           0 :         p = isl_printer_print_str(p, op);
    2176           0 :         p = isl_printer_print_str(p, " 0");
    2177             : 
    2178           0 :         *first = 0;
    2179             : 
    2180           0 :         return p;
    2181             : }
    2182             : 
    2183           0 : static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p,
    2184             :         __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset)
    2185             : {
    2186             :         int i, j;
    2187           0 :         int first = 1;
    2188           0 :         unsigned n_div = isl_basic_set_dim(bset, isl_dim_div);
    2189           0 :         unsigned total = isl_basic_set_total_dim(bset) - n_div;
    2190             : 
    2191           0 :         for (i = 0; i < bset->n_eq; ++i) {
    2192           0 :                 j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div);
    2193           0 :                 if (j < 0)
    2194           0 :                         p = print_constraint_c(p, dim, bset,
    2195           0 :                                                 bset->eq[i], "==", &first);
    2196             :                 else {
    2197           0 :                         if (i)
    2198           0 :                                 p = isl_printer_print_str(p, " && ");
    2199           0 :                         p = isl_printer_print_str(p, "(");
    2200           0 :                         p = print_partial_affine_c(p, dim, bset, bset->eq[i],
    2201           0 :                                                    1 + total + j);
    2202           0 :                         p = isl_printer_print_str(p, ") % ");
    2203           0 :                         p = isl_printer_print_isl_int(p,
    2204           0 :                                                 bset->eq[i][1 + total + j]);
    2205           0 :                         p = isl_printer_print_str(p, " == 0");
    2206           0 :                         first = 0;
    2207             :                 }
    2208             :         }
    2209           0 :         for (i = 0; i < bset->n_ineq; ++i)
    2210           0 :                 p = print_constraint_c(p, dim, bset, bset->ineq[i], ">=",
    2211             :                                         &first);
    2212           0 :         return p;
    2213             : }
    2214             : 
    2215           0 : static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p,
    2216             :         __isl_keep isl_space *dim, __isl_keep isl_set *set)
    2217             : {
    2218             :         int i;
    2219             : 
    2220           0 :         if (!set)
    2221           0 :                 return isl_printer_free(p);
    2222             : 
    2223           0 :         if (set->n == 0)
    2224           0 :                 p = isl_printer_print_str(p, "0");
    2225             : 
    2226           0 :         for (i = 0; i < set->n; ++i) {
    2227           0 :                 if (i)
    2228           0 :                         p = isl_printer_print_str(p, " || ");
    2229           0 :                 if (set->n > 1)
    2230           0 :                         p = isl_printer_print_str(p, "(");
    2231           0 :                 p = print_basic_set_c(p, dim, set->p[i]);
    2232           0 :                 if (set->n > 1)
    2233           0 :                         p = isl_printer_print_str(p, ")");
    2234             :         }
    2235           0 :         return p;
    2236             : }
    2237             : 
    2238             : /* Print the piecewise quasi-polynomial "pwqp" to "p" in C format.
    2239             :  */
    2240           0 : static __isl_give isl_printer *print_pw_qpolynomial_c(
    2241             :         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
    2242             : {
    2243             :         int i;
    2244             :         isl_space *space;
    2245             : 
    2246           0 :         space = isl_pw_qpolynomial_get_domain_space(pwqp);
    2247           0 :         if (pwqp->n == 1 && isl_set_plain_is_universe(pwqp->p[0].set)) {
    2248           0 :                 p = print_qpolynomial_c(p, space, pwqp->p[0].qp);
    2249           0 :                 isl_space_free(space);
    2250           0 :                 return p;
    2251             :         }
    2252             : 
    2253           0 :         for (i = 0; i < pwqp->n; ++i) {
    2254           0 :                 p = isl_printer_print_str(p, "(");
    2255           0 :                 p = print_set_c(p, space, pwqp->p[i].set);
    2256           0 :                 p = isl_printer_print_str(p, ") ? (");
    2257           0 :                 p = print_qpolynomial_c(p, space, pwqp->p[i].qp);
    2258           0 :                 p = isl_printer_print_str(p, ") : ");
    2259             :         }
    2260             : 
    2261           0 :         isl_space_free(space);
    2262           0 :         p = isl_printer_print_str(p, "0");
    2263           0 :         return p;
    2264             : }
    2265             : 
    2266           0 : __isl_give isl_printer *isl_printer_print_pw_qpolynomial(
    2267             :         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp)
    2268             : {
    2269           0 :         if (!p || !pwqp)
    2270             :                 goto error;
    2271             : 
    2272           0 :         if (p->output_format == ISL_FORMAT_ISL)
    2273           0 :                 return print_pw_qpolynomial_isl(p, pwqp);
    2274           0 :         else if (p->output_format == ISL_FORMAT_C)
    2275           0 :                 return print_pw_qpolynomial_c(p, pwqp);
    2276           0 :         isl_assert(p->ctx, 0, goto error);
    2277             : error:
    2278           0 :         isl_printer_free(p);
    2279           0 :         return NULL;
    2280             : }
    2281             : 
    2282           0 : static isl_stat print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user)
    2283             : {
    2284             :         struct isl_union_print_data *data;
    2285           0 :         data = (struct isl_union_print_data *)user;
    2286             : 
    2287           0 :         if (!data->first)
    2288           0 :                 data->p = isl_printer_print_str(data->p, "; ");
    2289           0 :         data->first = 0;
    2290             : 
    2291           0 :         data->p = isl_pwqp_print_isl_body(data->p, pwqp);
    2292           0 :         isl_pw_qpolynomial_free(pwqp);
    2293             : 
    2294           0 :         return isl_stat_ok;
    2295             : }
    2296             : 
    2297           0 : static __isl_give isl_printer *print_union_pw_qpolynomial_isl(
    2298             :         __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
    2299             : {
    2300             :         struct isl_union_print_data data;
    2301           0 :         struct isl_print_space_data space_data = { 0 };
    2302             :         isl_space *space;
    2303             : 
    2304           0 :         space = isl_union_pw_qpolynomial_get_space(upwqp);
    2305           0 :         p = print_param_tuple(p, space, &space_data);
    2306           0 :         isl_space_free(space);
    2307           0 :         p = isl_printer_print_str(p, "{ ");
    2308           0 :         data.p = p;
    2309           0 :         data.first = 1;
    2310           0 :         isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body,
    2311             :                                                         &data);
    2312           0 :         p = data.p;
    2313           0 :         p = isl_printer_print_str(p, " }");
    2314           0 :         return p;
    2315             : }
    2316             : 
    2317           0 : __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial(
    2318             :         __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp)
    2319             : {
    2320           0 :         if (!p || !upwqp)
    2321             :                 goto error;
    2322             : 
    2323           0 :         if (p->output_format == ISL_FORMAT_ISL)
    2324           0 :                 return print_union_pw_qpolynomial_isl(p, upwqp);
    2325           0 :         isl_die(p->ctx, isl_error_invalid,
    2326             :                 "invalid output format for isl_union_pw_qpolynomial",
    2327             :                 goto error);
    2328             : error:
    2329           0 :         isl_printer_free(p);
    2330           0 :         return NULL;
    2331             : }
    2332             : 
    2333             : /* Print the quasi-polynomial reduction "fold" to "p" in C format,
    2334             :  * with the variable names taken from the domain space "space".
    2335             :  */
    2336           0 : static __isl_give isl_printer *print_qpolynomial_fold_c(
    2337             :         __isl_take isl_printer *p, __isl_keep isl_space *space,
    2338             :         __isl_keep isl_qpolynomial_fold *fold)
    2339             : {
    2340             :         int i;
    2341             : 
    2342           0 :         for (i = 0; i < fold->n - 1; ++i)
    2343           0 :                 if (fold->type == isl_fold_min)
    2344           0 :                         p = isl_printer_print_str(p, "min(");
    2345           0 :                 else if (fold->type == isl_fold_max)
    2346           0 :                         p = isl_printer_print_str(p, "max(");
    2347             : 
    2348           0 :         for (i = 0; i < fold->n; ++i) {
    2349           0 :                 if (i)
    2350           0 :                         p = isl_printer_print_str(p, ", ");
    2351           0 :                 p = print_qpolynomial_c(p, space, fold->qp[i]);
    2352           0 :                 if (i)
    2353           0 :                         p = isl_printer_print_str(p, ")");
    2354             :         }
    2355           0 :         return p;
    2356             : }
    2357             : 
    2358           0 : __isl_give isl_printer *isl_printer_print_qpolynomial_fold(
    2359             :         __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
    2360             : {
    2361           0 :         if  (!p || !fold)
    2362             :                 goto error;
    2363           0 :         if (p->output_format == ISL_FORMAT_ISL)
    2364           0 :                 return qpolynomial_fold_print(fold, p);
    2365           0 :         else if (p->output_format == ISL_FORMAT_C)
    2366           0 :                 return print_qpolynomial_fold_c(p, fold->dim, fold);
    2367           0 :         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
    2368             :                 goto error);
    2369             : error:
    2370           0 :         isl_printer_free(p);
    2371           0 :         return NULL;
    2372             : }
    2373             : 
    2374             : /* Print the piecewise quasi-polynomial reduction "pwf" to "p" in C format.
    2375             :  */
    2376           0 : static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
    2377             :         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
    2378             : {
    2379             :         int i;
    2380             :         isl_space *space;
    2381             : 
    2382           0 :         space = isl_pw_qpolynomial_fold_get_domain_space(pwf);
    2383           0 :         if (pwf->n == 1 && isl_set_plain_is_universe(pwf->p[0].set)) {
    2384           0 :                 p = print_qpolynomial_fold_c(p, space, pwf->p[0].fold);
    2385           0 :                 isl_space_free(space);
    2386           0 :                 return p;
    2387             :         }
    2388             : 
    2389           0 :         for (i = 0; i < pwf->n; ++i) {
    2390           0 :                 p = isl_printer_print_str(p, "(");
    2391           0 :                 p = print_set_c(p, space, pwf->p[i].set);
    2392           0 :                 p = isl_printer_print_str(p, ") ? (");
    2393           0 :                 p = print_qpolynomial_fold_c(p, space, pwf->p[i].fold);
    2394           0 :                 p = isl_printer_print_str(p, ") : ");
    2395             :         }
    2396             : 
    2397           0 :         isl_space_free(space);
    2398           0 :         p = isl_printer_print_str(p, "0");
    2399           0 :         return p;
    2400             : }
    2401             : 
    2402           0 : __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold(
    2403             :         __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
    2404             : {
    2405           0 :         if (!p || !pwf)
    2406             :                 goto error;
    2407             : 
    2408           0 :         if (p->output_format == ISL_FORMAT_ISL)
    2409           0 :                 return print_pw_qpolynomial_fold_isl(p, pwf);
    2410           0 :         else if (p->output_format == ISL_FORMAT_C)
    2411           0 :                 return print_pw_qpolynomial_fold_c(p, pwf);
    2412           0 :         isl_assert(p->ctx, 0, goto error);
    2413             : error:
    2414           0 :         isl_printer_free(p);
    2415           0 :         return NULL;
    2416             : }
    2417             : 
    2418           0 : void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
    2419             :         FILE *out, unsigned output_format)
    2420             : {
    2421             :         isl_printer *p;
    2422             : 
    2423           0 :         if (!pwf)
    2424           0 :                 return;
    2425             : 
    2426           0 :         p = isl_printer_to_file(pwf->dim->ctx, out);
    2427           0 :         p = isl_printer_set_output_format(p, output_format);
    2428           0 :         p = isl_printer_print_pw_qpolynomial_fold(p, pwf);
    2429             : 
    2430           0 :         isl_printer_free(p);
    2431             : }
    2432             : 
    2433           0 : static isl_stat print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf,
    2434             :         void *user)
    2435             : {
    2436             :         struct isl_union_print_data *data;
    2437           0 :         data = (struct isl_union_print_data *)user;
    2438             : 
    2439           0 :         if (!data->first)
    2440           0 :                 data->p = isl_printer_print_str(data->p, "; ");
    2441           0 :         data->first = 0;
    2442             : 
    2443           0 :         data->p = isl_pwf_print_isl_body(data->p, pwf);
    2444           0 :         isl_pw_qpolynomial_fold_free(pwf);
    2445             : 
    2446           0 :         return isl_stat_ok;
    2447             : }
    2448             : 
    2449           0 : static __isl_give isl_printer *print_union_pw_qpolynomial_fold_isl(
    2450             :         __isl_take isl_printer *p,
    2451             :         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
    2452             : {
    2453             :         struct isl_union_print_data data;
    2454           0 :         struct isl_print_space_data space_data = { 0 };
    2455             :         isl_space *space;
    2456             : 
    2457           0 :         space = isl_union_pw_qpolynomial_fold_get_space(upwf);
    2458           0 :         p = print_param_tuple(p, space, &space_data);
    2459           0 :         isl_space_free(space);
    2460           0 :         p = isl_printer_print_str(p, "{ ");
    2461           0 :         data.p = p;
    2462           0 :         data.first = 1;
    2463           0 :         isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf,
    2464             :                                                         &print_pwf_body, &data);
    2465           0 :         p = data.p;
    2466           0 :         p = isl_printer_print_str(p, " }");
    2467           0 :         return p;
    2468             : }
    2469             : 
    2470           0 : __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold(
    2471             :         __isl_take isl_printer *p,
    2472             :         __isl_keep isl_union_pw_qpolynomial_fold *upwf)
    2473             : {
    2474           0 :         if (!p || !upwf)
    2475             :                 goto error;
    2476             : 
    2477           0 :         if (p->output_format == ISL_FORMAT_ISL)
    2478           0 :                 return print_union_pw_qpolynomial_fold_isl(p, upwf);
    2479           0 :         isl_die(p->ctx, isl_error_invalid,
    2480             :                 "invalid output format for isl_union_pw_qpolynomial_fold",
    2481             :                 goto error);
    2482             : error:
    2483           0 :         isl_printer_free(p);
    2484           0 :         return NULL;
    2485             : }
    2486             : 
    2487             : /* Print the isl_constraint "c" to "p".
    2488             :  */
    2489           0 : __isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p,
    2490             :         __isl_keep isl_constraint *c)
    2491             : {
    2492           0 :         struct isl_print_space_data data = { 0 };
    2493             :         isl_local_space *ls;
    2494             :         isl_space *space;
    2495             :         isl_bool exists;
    2496             : 
    2497           0 :         if (!p || !c)
    2498             :                 goto error;
    2499             : 
    2500           0 :         ls = isl_constraint_get_local_space(c);
    2501           0 :         if (!ls)
    2502           0 :                 return isl_printer_free(p);
    2503           0 :         space = isl_local_space_get_space(ls);
    2504           0 :         p = print_param_tuple(p, space, &data);
    2505           0 :         p = isl_printer_print_str(p, "{ ");
    2506           0 :         p = isl_print_space(space, p, 0, &data);
    2507           0 :         p = isl_printer_print_str(p, " : ");
    2508           0 :         exists = need_exists(p, ls->div);
    2509           0 :         if (exists < 0)
    2510           0 :                 p = isl_printer_free(p);
    2511           0 :         if (exists >= 0 && exists)
    2512           0 :                 p = open_exists(p, space, ls->div, 0);
    2513           0 :         p = print_affine_of_len(space, ls->div, p, c->v->el, c->v->size);
    2514           0 :         if (isl_constraint_is_equality(c))
    2515           0 :                 p = isl_printer_print_str(p, " = 0");
    2516             :         else
    2517           0 :                 p = isl_printer_print_str(p, " >= 0");
    2518           0 :         if (exists >= 0 && exists)
    2519           0 :                 p = isl_printer_print_str(p, s_close_exists[0]);
    2520           0 :         p = isl_printer_print_str(p, " }");
    2521           0 :         isl_space_free(space);
    2522           0 :         isl_local_space_free(ls);
    2523             : 
    2524           0 :         return p;
    2525             : error:
    2526           0 :         isl_printer_free(p);
    2527           0 :         return NULL;
    2528             : }
    2529             : 
    2530           0 : static __isl_give isl_printer *isl_printer_print_space_isl(
    2531             :         __isl_take isl_printer *p, __isl_keep isl_space *space)
    2532             : {
    2533           0 :         struct isl_print_space_data data = { 0 };
    2534             : 
    2535           0 :         if (!space)
    2536           0 :                 goto error;
    2537             : 
    2538           0 :         p = print_param_tuple(p, space, &data);
    2539             : 
    2540           0 :         p = isl_printer_print_str(p, "{ ");
    2541           0 :         if (isl_space_is_params(space))
    2542           0 :                 p = isl_printer_print_str(p, s_such_that[0]);
    2543             :         else
    2544           0 :                 p = isl_print_space(space, p, 0, &data);
    2545           0 :         p = isl_printer_print_str(p, " }");
    2546             : 
    2547           0 :         return p;
    2548             : error:
    2549           0 :         isl_printer_free(p);
    2550           0 :         return NULL;
    2551             : }
    2552             : 
    2553           0 : __isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p,
    2554             :         __isl_keep isl_space *space)
    2555             : {
    2556           0 :         if (!p || !space)
    2557           0 :                 return isl_printer_free(p);
    2558           0 :         if (p->output_format == ISL_FORMAT_ISL)
    2559           0 :                 return isl_printer_print_space_isl(p, space);
    2560           0 :         else if (p->output_format == ISL_FORMAT_OMEGA)
    2561           0 :                 return print_omega_parameters(space, p);
    2562             : 
    2563           0 :         isl_die(isl_space_get_ctx(space), isl_error_unsupported,
    2564             :                 "output format not supported for space",
    2565             :                 return isl_printer_free(p));
    2566             : }
    2567             : 
    2568           0 : __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p,
    2569             :         __isl_keep isl_local_space *ls)
    2570             : {
    2571           0 :         struct isl_print_space_data data = { 0 };
    2572             :         unsigned n_div;
    2573             : 
    2574           0 :         if (!ls)
    2575           0 :                 goto error;
    2576             : 
    2577           0 :         p = print_param_tuple(p, ls->dim, &data);
    2578           0 :         p = isl_printer_print_str(p, "{ ");
    2579           0 :         p = isl_print_space(ls->dim, p, 0, &data);
    2580           0 :         n_div = isl_local_space_dim(ls, isl_dim_div);
    2581           0 :         if (n_div > 0) {
    2582           0 :                 p = isl_printer_print_str(p, " : ");
    2583           0 :                 p = isl_printer_print_str(p, s_open_exists[0]);
    2584           0 :                 p = print_div_list(p, ls->dim, ls->div, 0, 1);
    2585           0 :                 p = isl_printer_print_str(p, s_close_exists[0]);
    2586           0 :         } else if (isl_space_is_params(ls->dim))
    2587           0 :                 p = isl_printer_print_str(p, s_such_that[0]);
    2588           0 :         p = isl_printer_print_str(p, " }");
    2589           0 :         return p;
    2590             : error:
    2591           0 :         isl_printer_free(p);
    2592           0 :         return NULL;
    2593             : }
    2594             : 
    2595             : /* Print the (potentially rational) affine expression "aff" to "p",
    2596             :  * with the variable names taken from "space".
    2597             :  */
    2598           0 : static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p,
    2599             :         __isl_keep isl_space *space, __isl_keep isl_aff *aff)
    2600             : {
    2601             :         unsigned total;
    2602             : 
    2603           0 :         if (isl_aff_is_nan(aff))
    2604           0 :                 return isl_printer_print_str(p, "NaN");
    2605             : 
    2606           0 :         total = isl_local_space_dim(aff->ls, isl_dim_all);
    2607           0 :         p = isl_printer_print_str(p, "(");
    2608           0 :         p = print_affine_of_len(space, aff->ls->div, p,
    2609           0 :                                 aff->v->el + 1, 1 + total);
    2610           0 :         if (isl_int_is_one(aff->v->el[0]))
    2611           0 :                 p = isl_printer_print_str(p, ")");
    2612             :         else {
    2613           0 :                 p = isl_printer_print_str(p, ")/");
    2614           0 :                 p = isl_printer_print_isl_int(p, aff->v->el[0]);
    2615             :         }
    2616             : 
    2617           0 :         return p;
    2618             : }
    2619             : 
    2620           0 : static __isl_give isl_printer *print_aff(__isl_take isl_printer *p,
    2621             :         __isl_keep isl_aff *aff)
    2622             : {
    2623           0 :         struct isl_print_space_data data = { 0 };
    2624             : 
    2625           0 :         if (isl_space_is_params(aff->ls->dim))
    2626             :                 ;
    2627             :         else {
    2628           0 :                 p = print_tuple(aff->ls->dim, p, isl_dim_set, &data);
    2629           0 :                 p = isl_printer_print_str(p, " -> ");
    2630             :         }
    2631           0 :         p = isl_printer_print_str(p, "[");
    2632           0 :         p = print_aff_body(p, aff->ls->dim, aff);
    2633           0 :         p = isl_printer_print_str(p, "]");
    2634             : 
    2635           0 :         return p;
    2636             : }
    2637             : 
    2638           0 : static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p,
    2639             :         __isl_keep isl_aff *aff)
    2640             : {
    2641           0 :         struct isl_print_space_data data = { 0 };
    2642             : 
    2643           0 :         if (!aff)
    2644           0 :                 goto error;
    2645             : 
    2646           0 :         p = print_param_tuple(p, aff->ls->dim, &data);
    2647           0 :         p = isl_printer_print_str(p, "{ ");
    2648           0 :         p = print_aff(p, aff);
    2649           0 :         p = isl_printer_print_str(p, " }");
    2650           0 :         return p;
    2651             : error:
    2652           0 :         isl_printer_free(p);
    2653           0 :         return NULL;
    2654             : }
    2655             : 
    2656             : /* Print the body of an isl_pw_aff, i.e., a semicolon delimited
    2657             :  * sequence of affine expressions, each followed by constraints.
    2658             :  */
    2659           0 : static __isl_give isl_printer *print_pw_aff_body(
    2660             :         __isl_take isl_printer *p, __isl_keep isl_pw_aff *pa)
    2661             : {
    2662             :         int i;
    2663             : 
    2664           0 :         if (!pa)
    2665           0 :                 return isl_printer_free(p);
    2666             : 
    2667           0 :         for (i = 0; i < pa->n; ++i) {
    2668             :                 isl_space *space;
    2669             : 
    2670           0 :                 if (i)
    2671           0 :                         p = isl_printer_print_str(p, "; ");
    2672           0 :                 p = print_aff(p, pa->p[i].aff);
    2673           0 :                 space = isl_aff_get_domain_space(pa->p[i].aff);
    2674           0 :                 p = print_disjuncts(set_to_map(pa->p[i].set), space, p, 0);
    2675           0 :                 isl_space_free(space);
    2676             :         }
    2677             : 
    2678           0 :         return p;
    2679             : }
    2680             : 
    2681           0 : static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p,
    2682             :         __isl_keep isl_pw_aff *pwaff)
    2683             : {
    2684           0 :         struct isl_print_space_data data = { 0 };
    2685             : 
    2686           0 :         if (!pwaff)
    2687           0 :                 goto error;
    2688             : 
    2689           0 :         p = print_param_tuple(p, pwaff->dim, &data);
    2690           0 :         p = isl_printer_print_str(p, "{ ");
    2691           0 :         p = print_pw_aff_body(p, pwaff);
    2692           0 :         p = isl_printer_print_str(p, " }");
    2693           0 :         return p;
    2694             : error:
    2695           0 :         isl_printer_free(p);
    2696           0 :         return NULL;
    2697             : }
    2698             : 
    2699             : static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
    2700             :         __isl_keep isl_local_space *ls, isl_int *c);
    2701             : 
    2702           0 : static __isl_give isl_printer *print_ls_name_c(__isl_take isl_printer *p,
    2703             :         __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos)
    2704             : {
    2705           0 :         if (type == isl_dim_div) {
    2706           0 :                 p = isl_printer_print_str(p, "floord(");
    2707           0 :                 p = print_ls_affine_c(p, ls, ls->div->row[pos] + 1);
    2708           0 :                 p = isl_printer_print_str(p, ", ");
    2709           0 :                 p = isl_printer_print_isl_int(p, ls->div->row[pos][0]);
    2710           0 :                 p = isl_printer_print_str(p, ")");
    2711             :         } else {
    2712             :                 const char *name;
    2713             : 
    2714           0 :                 name = isl_space_get_dim_name(ls->dim, type, pos);
    2715           0 :                 if (!name)
    2716           0 :                         name = "UNNAMED";
    2717           0 :                 p = isl_printer_print_str(p, name);
    2718             :         }
    2719           0 :         return p;
    2720             : }
    2721             : 
    2722           0 : static __isl_give isl_printer *print_ls_term_c(__isl_take isl_printer *p,
    2723             :         __isl_keep isl_local_space *ls, isl_int c, unsigned pos)
    2724             : {
    2725             :         enum isl_dim_type type;
    2726             : 
    2727           0 :         if (!p || !ls)
    2728           0 :                 return isl_printer_free(p);
    2729             : 
    2730           0 :         if (pos == 0)
    2731           0 :                 return isl_printer_print_isl_int(p, c);
    2732             : 
    2733           0 :         if (isl_int_is_one(c))
    2734             :                 ;
    2735           0 :         else if (isl_int_is_negone(c))
    2736           0 :                 p = isl_printer_print_str(p, "-");
    2737             :         else {
    2738           0 :                 p = isl_printer_print_isl_int(p, c);
    2739           0 :                 p = isl_printer_print_str(p, "*");
    2740             :         }
    2741           0 :         type = pos2type(ls->dim, &pos);
    2742           0 :         p = print_ls_name_c(p, ls, type, pos);
    2743           0 :         return p;
    2744             : }
    2745             : 
    2746           0 : static __isl_give isl_printer *print_ls_partial_affine_c(
    2747             :         __isl_take isl_printer *p, __isl_keep isl_local_space *ls,
    2748             :         isl_int *c, unsigned len)
    2749             : {
    2750             :         int i;
    2751             :         int first;
    2752             : 
    2753           0 :         for (i = 0, first = 1; i < len; ++i) {
    2754           0 :                 int flip = 0;
    2755           0 :                 if (isl_int_is_zero(c[i]))
    2756           0 :                         continue;
    2757           0 :                 if (!first) {
    2758           0 :                         if (isl_int_is_neg(c[i])) {
    2759           0 :                                 flip = 1;
    2760           0 :                                 isl_int_neg(c[i], c[i]);
    2761           0 :                                 p = isl_printer_print_str(p, " - ");
    2762             :                         } else 
    2763           0 :                                 p = isl_printer_print_str(p, " + ");
    2764             :                 }
    2765           0 :                 first = 0;
    2766           0 :                 p = print_ls_term_c(p, ls, c[i], i);
    2767           0 :                 if (flip)
    2768           0 :                         isl_int_neg(c[i], c[i]);
    2769             :         }
    2770           0 :         if (first)
    2771           0 :                 p = isl_printer_print_str(p, "0");
    2772           0 :         return p;
    2773             : }
    2774             : 
    2775           0 : static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p,
    2776             :         __isl_keep isl_local_space *ls, isl_int *c)
    2777             : {
    2778           0 :         unsigned len = 1 + isl_local_space_dim(ls, isl_dim_all);
    2779           0 :         return print_ls_partial_affine_c(p, ls, c, len);
    2780             : }
    2781             : 
    2782           0 : static __isl_give isl_printer *print_aff_c(__isl_take isl_printer *p,
    2783             :         __isl_keep isl_aff *aff)
    2784             : {
    2785             :         unsigned total;
    2786             : 
    2787           0 :         total = isl_local_space_dim(aff->ls, isl_dim_all);
    2788           0 :         if (!isl_int_is_one(aff->v->el[0]))
    2789           0 :                 p = isl_printer_print_str(p, "(");
    2790           0 :         p = print_ls_partial_affine_c(p, aff->ls, aff->v->el + 1, 1 + total);
    2791           0 :         if (!isl_int_is_one(aff->v->el[0])) {
    2792           0 :                 p = isl_printer_print_str(p, ")/");
    2793           0 :                 p = isl_printer_print_isl_int(p, aff->v->el[0]);
    2794             :         }
    2795           0 :         return p;
    2796             : }
    2797             : 
    2798             : /* In the C format, we cannot express that "pwaff" may be undefined
    2799             :  * on parts of the domain space.  We therefore assume that the expression
    2800             :  * will only be evaluated on its definition domain and compute the gist
    2801             :  * of each cell with respect to this domain.
    2802             :  */
    2803           0 : static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p,
    2804             :         __isl_keep isl_pw_aff *pwaff)
    2805             : {
    2806             :         isl_set *domain;
    2807             :         isl_ast_build *build;
    2808             :         isl_ast_expr *expr;
    2809             : 
    2810           0 :         if (pwaff->n < 1)
    2811           0 :                 isl_die(p->ctx, isl_error_unsupported,
    2812             :                         "cannot print empty isl_pw_aff in C format",
    2813             :                         return isl_printer_free(p));
    2814             : 
    2815           0 :         domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff));
    2816           0 :         build = isl_ast_build_from_context(domain);
    2817           0 :         expr = isl_ast_build_expr_from_pw_aff(build, isl_pw_aff_copy(pwaff));
    2818           0 :         p = isl_printer_print_ast_expr(p, expr);
    2819           0 :         isl_ast_expr_free(expr);
    2820           0 :         isl_ast_build_free(build);
    2821             : 
    2822           0 :         return p;
    2823             : }
    2824             : 
    2825           0 : __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p,
    2826             :         __isl_keep isl_aff *aff)
    2827             : {
    2828           0 :         if (!p || !aff)
    2829             :                 goto error;
    2830             : 
    2831           0 :         if (p->output_format == ISL_FORMAT_ISL)
    2832           0 :                 return print_aff_isl(p, aff);
    2833           0 :         else if (p->output_format == ISL_FORMAT_C)
    2834           0 :                 return print_aff_c(p, aff);
    2835           0 :         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
    2836             :                 goto error);
    2837             : error:
    2838           0 :         isl_printer_free(p);
    2839           0 :         return NULL;
    2840             : }
    2841             : 
    2842           0 : __isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p,
    2843             :         __isl_keep isl_pw_aff *pwaff)
    2844             : {
    2845           0 :         if (!p || !pwaff)
    2846             :                 goto error;
    2847             : 
    2848           0 :         if (p->output_format == ISL_FORMAT_ISL)
    2849           0 :                 return print_pw_aff_isl(p, pwaff);
    2850           0 :         else if (p->output_format == ISL_FORMAT_C)
    2851           0 :                 return print_pw_aff_c(p, pwaff);
    2852           0 :         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
    2853             :                 goto error);
    2854             : error:
    2855           0 :         isl_printer_free(p);
    2856           0 :         return NULL;
    2857             : }
    2858             : 
    2859             : /* Print "pa" in a sequence of isl_pw_affs delimited by semicolons.
    2860             :  * Each isl_pw_aff itself is also printed as semicolon delimited
    2861             :  * sequence of pieces.
    2862             :  * If data->first = 1, then this is the first in the sequence.
    2863             :  * Update data->first to tell the next element that it is not the first.
    2864             :  */
    2865           0 : static isl_stat print_pw_aff_body_wrap(__isl_take isl_pw_aff *pa,
    2866             :         void *user)
    2867             : {
    2868             :         struct isl_union_print_data *data;
    2869           0 :         data = (struct isl_union_print_data *) user;
    2870             : 
    2871           0 :         if (!data->first)
    2872           0 :                 data->p = isl_printer_print_str(data->p, "; ");
    2873           0 :         data->first = 0;
    2874             : 
    2875           0 :         data->p = print_pw_aff_body(data->p, pa);
    2876           0 :         isl_pw_aff_free(pa);
    2877             : 
    2878           0 :         return data->p ? isl_stat_ok : isl_stat_error;
    2879             : }
    2880             : 
    2881             : /* Print the body of an isl_union_pw_aff, i.e., a semicolon delimited
    2882             :  * sequence of affine expressions, each followed by constraints,
    2883             :  * with the sequence enclosed in braces.
    2884             :  */
    2885           0 : static __isl_give isl_printer *print_union_pw_aff_body(
    2886             :         __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
    2887             : {
    2888           0 :         struct isl_union_print_data data = { p, 1 };
    2889             : 
    2890           0 :         p = isl_printer_print_str(p, s_open_set[0]);
    2891           0 :         data.p = p;
    2892           0 :         if (isl_union_pw_aff_foreach_pw_aff(upa,
    2893             :                                             &print_pw_aff_body_wrap, &data) < 0)
    2894           0 :                 data.p = isl_printer_free(p);
    2895           0 :         p = data.p;
    2896           0 :         p = isl_printer_print_str(p, s_close_set[0]);
    2897             : 
    2898           0 :         return p;
    2899             : }
    2900             : 
    2901             : /* Print the isl_union_pw_aff "upa" to "p" in isl format.
    2902             :  *
    2903             :  * The individual isl_pw_affs are delimited by a semicolon.
    2904             :  */
    2905           0 : static __isl_give isl_printer *print_union_pw_aff_isl(
    2906             :         __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
    2907             : {
    2908           0 :         struct isl_print_space_data data = { 0 };
    2909             :         isl_space *space;
    2910             : 
    2911           0 :         space = isl_union_pw_aff_get_space(upa);
    2912           0 :         p = print_param_tuple(p, space, &data);
    2913           0 :         isl_space_free(space);
    2914           0 :         p = print_union_pw_aff_body(p, upa);
    2915           0 :         return p;
    2916             : }
    2917             : 
    2918             : /* Print the isl_union_pw_aff "upa" to "p".
    2919             :  *
    2920             :  * We currently only support an isl format.
    2921             :  */
    2922           0 : __isl_give isl_printer *isl_printer_print_union_pw_aff(
    2923             :         __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
    2924             : {
    2925           0 :         if (!p || !upa)
    2926           0 :                 return isl_printer_free(p);
    2927             : 
    2928           0 :         if (p->output_format == ISL_FORMAT_ISL)
    2929           0 :                 return print_union_pw_aff_isl(p, upa);
    2930           0 :         isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
    2931             :                 "unsupported output format", return isl_printer_free(p));
    2932             : }
    2933             : 
    2934             : /* Print dimension "pos" of data->space to "p".
    2935             :  *
    2936             :  * data->user is assumed to be an isl_multi_aff.
    2937             :  *
    2938             :  * If the current dimension is an output dimension, then print
    2939             :  * the corresponding expression.  Otherwise, print the name of the dimension.
    2940             :  * Make sure to use the domain space for printing names as
    2941           0 :  * that is the space that will be used for printing constraints (if any).
    2942             :  */
    2943             : static __isl_give isl_printer *print_dim_ma(__isl_take isl_printer *p,
    2944           0 :         struct isl_print_space_data *data, unsigned pos)
    2945             : {
    2946           0 :         isl_multi_aff *ma = data->user;
    2947             :         isl_space *space;
    2948             : 
    2949           0 :         space = isl_multi_aff_get_domain_space(ma);
    2950           0 :         if (data->type == isl_dim_out) {
    2951           0 :                 p = print_aff_body(p, space, ma->u.p[pos]);
    2952             :         } else {
    2953           0 :                 enum isl_dim_type type = data->type;
    2954             : 
    2955             :                 if (type == isl_dim_in)
    2956           0 :                         type = isl_dim_set;
    2957             :                 p = print_name(space, p, type, pos, data->latex);
    2958             :         }
    2959           0 :         isl_space_free(space);
    2960             : 
    2961             :         return p;
    2962           0 : }
    2963             : 
    2964           0 : static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p,
    2965           0 :         __isl_keep isl_multi_aff *maff)
    2966           0 : {
    2967             :         struct isl_print_space_data data = { 0 };
    2968             : 
    2969           0 :         data.print_dim = &print_dim_ma;
    2970             :         data.user = maff;
    2971             :         return isl_print_space(maff->space, p, 0, &data);
    2972           0 : }
    2973             : 
    2974           0 : static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p,
    2975           0 :         __isl_keep isl_multi_aff *maff)
    2976             : {
    2977           0 :         struct isl_print_space_data data = { 0 };
    2978           0 : 
    2979           0 :         if (!maff)
    2980           0 :                 goto error;
    2981           0 : 
    2982             :         p = print_param_tuple(p, maff->space, &data);
    2983           0 :         p = isl_printer_print_str(p, "{ ");
    2984           0 :         p = print_multi_aff(p, maff);
    2985             :         p = isl_printer_print_str(p, " }");
    2986             :         return p;
    2987           0 : error:
    2988             :         isl_printer_free(p);
    2989             :         return NULL;
    2990           0 : }
    2991             : 
    2992             : __isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p,
    2993           0 :         __isl_keep isl_multi_aff *maff)
    2994           0 : {
    2995           0 :         if (!p || !maff)
    2996             :                 goto error;
    2997             : 
    2998           0 :         if (p->output_format == ISL_FORMAT_ISL)
    2999           0 :                 return print_multi_aff_isl(p, maff);
    3000             :         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
    3001             :                 goto error);
    3002           0 : error:
    3003             :         isl_printer_free(p);
    3004             :         return NULL;
    3005             : }
    3006             : 
    3007           0 : static __isl_give isl_printer *print_pw_multi_aff_body(
    3008           0 :         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
    3009             : {
    3010           0 :         int i;
    3011             : 
    3012             :         if (!pma)
    3013           0 :                 goto error;
    3014           0 : 
    3015           0 :         for (i = 0; i < pma->n; ++i) {
    3016           0 :                 isl_space *space;
    3017           0 : 
    3018           0 :                 if (i)
    3019             :                         p = isl_printer_print_str(p, "; ");
    3020           0 :                 p = print_multi_aff(p, pma->p[i].maff);
    3021             :                 space = isl_multi_aff_get_domain_space(pma->p[i].maff);
    3022           0 :                 p = print_disjuncts(set_to_map(pma->p[i].set), space, p, 0);
    3023           0 :                 isl_space_free(space);
    3024             :         }
    3025             :         return p;
    3026           0 : error:
    3027             :         isl_printer_free(p);
    3028             :         return NULL;
    3029           0 : }
    3030             : 
    3031           0 : static __isl_give isl_printer *print_pw_multi_aff_isl(__isl_take isl_printer *p,
    3032           0 :         __isl_keep isl_pw_multi_aff *pma)
    3033             : {
    3034           0 :         struct isl_print_space_data data = { 0 };
    3035           0 : 
    3036           0 :         if (!pma)
    3037           0 :                 goto error;
    3038           0 : 
    3039             :         p = print_param_tuple(p, pma->dim, &data);
    3040           0 :         p = isl_printer_print_str(p, "{ ");
    3041           0 :         p = print_pw_multi_aff_body(p, pma);
    3042             :         p = isl_printer_print_str(p, " }");
    3043             :         return p;
    3044             : error:
    3045             :         isl_printer_free(p);
    3046             :         return NULL;
    3047           0 : }
    3048             : 
    3049             : /* Print the unnamed, single-dimensional piecewise multi affine expression "pma"
    3050             :  * to "p".
    3051             :  */
    3052             : static __isl_give isl_printer *print_unnamed_pw_multi_aff_c(
    3053           0 :         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
    3054           0 : {
    3055           0 :         int i;
    3056           0 :         isl_space *space;
    3057           0 : 
    3058           0 :         space = isl_pw_multi_aff_get_domain_space(pma);
    3059           0 :         for (i = 0; i < pma->n - 1; ++i) {
    3060             :                 p = isl_printer_print_str(p, "(");
    3061           0 :                 p = print_set_c(p, space, pma->p[i].set);
    3062             :                 p = isl_printer_print_str(p, ") ? (");
    3063           0 :                 p = print_aff_c(p, pma->p[i].maff->u.p[0]);
    3064             :                 p = isl_printer_print_str(p, ") : ");
    3065             :         }
    3066           0 :         isl_space_free(space);
    3067             : 
    3068             :         return print_aff_c(p, pma->p[pma->n - 1].maff->u.p[0]);
    3069             : }
    3070             : 
    3071             : static __isl_give isl_printer *print_pw_multi_aff_c(__isl_take isl_printer *p,
    3072           0 :         __isl_keep isl_pw_multi_aff *pma)
    3073           0 : {
    3074           0 :         int n;
    3075           0 :         const char *name;
    3076             : 
    3077             :         if (!pma)
    3078           0 :                 goto error;
    3079           0 :         if (pma->n < 1)
    3080           0 :                 isl_die(p->ctx, isl_error_unsupported,
    3081           0 :                         "cannot print empty isl_pw_multi_aff in C format",
    3082           0 :                         goto error);
    3083             :         name = isl_pw_multi_aff_get_tuple_name(pma, isl_dim_out);
    3084             :         if (!name && isl_pw_multi_aff_dim(pma, isl_dim_out) == 1)
    3085             :                 return print_unnamed_pw_multi_aff_c(p, pma);
    3086           0 :         if (!name)
    3087           0 :                 isl_die(p->ctx, isl_error_unsupported,
    3088           0 :                         "cannot print unnamed isl_pw_multi_aff in C format",
    3089           0 :                         goto error);
    3090             : 
    3091             :         p = isl_printer_print_str(p, name);
    3092           0 :         n = isl_pw_multi_aff_dim(pma, isl_dim_out);
    3093             :         if (n != 0)
    3094           0 :                 isl_die(p->ctx, isl_error_unsupported,
    3095           0 :                         "not supported yet", goto error);
    3096             : 
    3097             :         return p;
    3098           0 : error:
    3099             :         isl_printer_free(p);
    3100             :         return NULL;
    3101           0 : }
    3102             : 
    3103             : __isl_give isl_printer *isl_printer_print_pw_multi_aff(
    3104           0 :         __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma)
    3105           0 : {
    3106           0 :         if (!p || !pma)
    3107           0 :                 goto error;
    3108           0 : 
    3109             :         if (p->output_format == ISL_FORMAT_ISL)
    3110             :                 return print_pw_multi_aff_isl(p, pma);
    3111           0 :         if (p->output_format == ISL_FORMAT_C)
    3112           0 :                 return print_pw_multi_aff_c(p, pma);
    3113             :         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
    3114             :                 goto error);
    3115           0 : error:
    3116             :         isl_printer_free(p);
    3117             :         return NULL;
    3118             : }
    3119           0 : 
    3120             : static isl_stat print_pw_multi_aff_body_wrap(__isl_take isl_pw_multi_aff *pma,
    3121           0 :         void *user)
    3122           0 : {
    3123           0 :         struct isl_union_print_data *data;
    3124             :         data = (struct isl_union_print_data *) user;
    3125           0 : 
    3126           0 :         if (!data->first)
    3127             :                 data->p = isl_printer_print_str(data->p, "; ");
    3128           0 :         data->first = 0;
    3129             : 
    3130             :         data->p = print_pw_multi_aff_body(data->p, pma);
    3131           0 :         isl_pw_multi_aff_free(pma);
    3132             : 
    3133             :         return isl_stat_ok;
    3134             : }
    3135           0 : 
    3136             : static __isl_give isl_printer *print_union_pw_multi_aff_isl(
    3137             :         __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
    3138           0 : {
    3139           0 :         struct isl_union_print_data data;
    3140           0 :         struct isl_print_space_data space_data = { 0 };
    3141           0 :         isl_space *space;
    3142           0 : 
    3143           0 :         space = isl_union_pw_multi_aff_get_space(upma);
    3144           0 :         p = print_param_tuple(p, space, &space_data);
    3145             :         isl_space_free(space);
    3146           0 :         p = isl_printer_print_str(p, s_open_set[0]);
    3147           0 :         data.p = p;
    3148           0 :         data.first = 1;
    3149             :         isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
    3150             :                                         &print_pw_multi_aff_body_wrap, &data);
    3151           0 :         p = data.p;
    3152             :         p = isl_printer_print_str(p, s_close_set[0]);
    3153             :         return p;
    3154           0 : }
    3155             : 
    3156             : __isl_give isl_printer *isl_printer_print_union_pw_multi_aff(
    3157           0 :         __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma)
    3158           0 : {
    3159           0 :         if (!p || !upma)
    3160             :                 goto error;
    3161             : 
    3162           0 :         if (p->output_format == ISL_FORMAT_ISL)
    3163           0 :                 return print_union_pw_multi_aff_isl(p, upma);
    3164             :         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
    3165             :                 goto error);
    3166             : error:
    3167             :         isl_printer_free(p);
    3168             :         return NULL;
    3169             : }
    3170             : 
    3171             : /* Print dimension "pos" of data->space to "p".
    3172             :  *
    3173             :  * data->user is assumed to be an isl_multi_pw_aff.
    3174           0 :  *
    3175             :  * If the current dimension is an output dimension, then print
    3176             :  * the corresponding piecewise affine expression.
    3177             :  * Otherwise, print the name of the dimension.
    3178             :  * Make sure to use the same space in both cases.
    3179             :  * In particular, use the domain space for printing names as
    3180           0 :  * that is the space that is used for printing constraints.
    3181             :  */
    3182             : static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p,
    3183           0 :         struct isl_print_space_data *data, unsigned pos)
    3184           0 : {
    3185             :         int i;
    3186           0 :         int need_parens;
    3187           0 :         isl_space *space;
    3188           0 :         isl_multi_pw_aff *mpa = data->user;
    3189             :         isl_pw_aff *pa;
    3190           0 : 
    3191           0 :         if (data->type != isl_dim_out) {
    3192           0 :                 enum isl_dim_type type = data->type;
    3193           0 : 
    3194           0 :                 if (type == isl_dim_in)
    3195             :                         type = isl_dim_set;
    3196           0 :                 space = isl_multi_pw_aff_get_domain_space(mpa);
    3197           0 :                 p = print_name(space, p, type, pos, data->latex);
    3198           0 :                 isl_space_free(space);
    3199           0 :                 return p;
    3200             :         }
    3201           0 : 
    3202           0 :         pa = mpa->u.p[pos];
    3203           0 :         if (pa->n == 0)
    3204             :                 return isl_printer_print_str(p, "(0 : false)");
    3205           0 : 
    3206             :         need_parens = pa->n != 1 || !isl_set_plain_is_universe(pa->p[0].set);
    3207             :         if (need_parens)
    3208             :                 p = isl_printer_print_str(p, "(");
    3209             :         space = isl_multi_pw_aff_get_domain_space(mpa);
    3210             :         for (i = 0; i < pa->n; ++i) {
    3211             : 
    3212             :                 if (i)
    3213           0 :                         p = isl_printer_print_str(p, "; ");
    3214             :                 p = print_aff_body(p, space, pa->p[i].aff);
    3215             :                 p = print_disjuncts(pa->p[i].set, space, p, 0);
    3216           0 :         }
    3217             :         isl_space_free(space);
    3218             :         if (need_parens)
    3219           0 :                 p = isl_printer_print_str(p, ")");
    3220           0 : 
    3221             :         return p;
    3222           0 : }
    3223           0 : 
    3224           0 : /* Print "mpa" to "p" in isl format.
    3225           0 :  *
    3226           0 :  * If "mpa" is zero-dimensional and has a non-trivial explicit domain,
    3227           0 :  * then it is printed after the tuple of affine expressions.
    3228           0 :  */
    3229           0 : static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p,
    3230           0 :         __isl_keep isl_multi_pw_aff *mpa)
    3231             : {
    3232             :         struct isl_print_space_data data = { 0 };
    3233           0 :         isl_bool has_domain;
    3234           0 : 
    3235           0 :         if (!mpa)
    3236             :                 return isl_printer_free(p);
    3237           0 : 
    3238           0 :         p = print_param_tuple(p, mpa->space, &data);
    3239             :         p = isl_printer_print_str(p, "{ ");
    3240             :         data.print_dim = &print_dim_mpa;
    3241           0 :         data.user = mpa;
    3242             :         p = isl_print_space(mpa->space, p, 0, &data);
    3243             :         has_domain = isl_multi_pw_aff_has_non_trivial_domain(mpa);
    3244           0 :         if (has_domain < 0)
    3245           0 :                 return isl_printer_free(p);
    3246             :         if (has_domain) {
    3247           0 :                 isl_space *space;
    3248           0 : 
    3249           0 :                 space = isl_space_domain(isl_space_copy(mpa->space));
    3250             :                 p = print_disjuncts_set(mpa->u.dom, space, p, 0);
    3251             :                 isl_space_free(space);
    3252             :         }
    3253             :         p = isl_printer_print_str(p, " }");
    3254             :         return p;
    3255             : }
    3256             : 
    3257             : __isl_give isl_printer *isl_printer_print_multi_pw_aff(
    3258             :         __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa)
    3259             : {
    3260           0 :         if (!p || !mpa)
    3261             :                 return isl_printer_free(p);
    3262             : 
    3263           0 :         if (p->output_format == ISL_FORMAT_ISL)
    3264             :                 return print_multi_pw_aff_isl(p, mpa);
    3265           0 :         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
    3266           0 :                 return isl_printer_free(p));
    3267             : }
    3268           0 : 
    3269             : /* Print dimension "pos" of data->space to "p".
    3270             :  *
    3271             :  * data->user is assumed to be an isl_multi_val.
    3272             :  *
    3273           0 :  * If the current dimension is an output dimension, then print
    3274             :  * the corresponding value.  Otherwise, print the name of the dimension.
    3275             :  */
    3276           0 : static __isl_give isl_printer *print_dim_mv(__isl_take isl_printer *p,
    3277             :         struct isl_print_space_data *data, unsigned pos)
    3278           0 : {
    3279           0 :         isl_multi_val *mv = data->user;
    3280             : 
    3281           0 :         if (data->type == isl_dim_out)
    3282           0 :                 return isl_printer_print_val(p, mv->u.p[pos]);
    3283           0 :         else
    3284           0 :                 return print_name(data->space, p, data->type, pos, data->latex);
    3285           0 : }
    3286           0 : 
    3287           0 : /* Print the isl_multi_val "mv" to "p" in isl format.
    3288             :  */
    3289             : static __isl_give isl_printer *print_multi_val_isl(__isl_take isl_printer *p,
    3290             :         __isl_keep isl_multi_val *mv)
    3291             : {
    3292             :         struct isl_print_space_data data = { 0 };
    3293             : 
    3294           0 :         if (!mv)
    3295             :                 return isl_printer_free(p);
    3296             : 
    3297           0 :         p = print_param_tuple(p, mv->space, &data);
    3298           0 :         p = isl_printer_print_str(p, "{ ");
    3299             :         data.print_dim = &print_dim_mv;
    3300           0 :         data.user = mv;
    3301           0 :         p = isl_print_space(mv->space, p, 0, &data);
    3302           0 :         p = isl_printer_print_str(p, " }");
    3303             :         return p;
    3304             : }
    3305             : 
    3306             : /* Print the isl_multi_val "mv" to "p".
    3307             :  *
    3308             :  * Currently only supported in isl format.
    3309             :  */
    3310             : __isl_give isl_printer *isl_printer_print_multi_val(
    3311             :         __isl_take isl_printer *p, __isl_keep isl_multi_val *mv)
    3312             : {
    3313             :         if (!p || !mv)
    3314           0 :                 return isl_printer_free(p);
    3315             : 
    3316             :         if (p->output_format == ISL_FORMAT_ISL)
    3317           0 :                 return print_multi_val_isl(p, mv);
    3318             :         isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
    3319             :                 return isl_printer_free(p));
    3320           0 : }
    3321           0 : 
    3322           0 : /* Print dimension "pos" of data->space to "p".
    3323             :  *
    3324           0 :  * data->user is assumed to be an isl_multi_union_pw_aff.
    3325             :  *
    3326             :  * The current dimension is necessarily a set dimension, so
    3327             :  * we print the corresponding isl_union_pw_aff, including
    3328             :  * the braces.
    3329             :  */
    3330             : static __isl_give isl_printer *print_union_pw_aff_dim(__isl_take isl_printer *p,
    3331             :         struct isl_print_space_data *data, unsigned pos)
    3332             : {
    3333             :         isl_multi_union_pw_aff *mupa = data->user;
    3334             :         isl_union_pw_aff *upa;
    3335             : 
    3336           0 :         upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, pos);
    3337             :         p = print_union_pw_aff_body(p, upa);
    3338             :         isl_union_pw_aff_free(upa);
    3339           0 : 
    3340             :         return p;
    3341             : }
    3342             : 
    3343           0 : /* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.
    3344           0 :  *
    3345           0 :  * If "mupa" is zero-dimensional and has a non-trivial explicit domain,
    3346           0 :  * then it is printed after the tuple of affine expressions.
    3347           0 :  * In order to clarify that this domain belongs to the expression,
    3348             :  * the tuple along with the domain are placed inside parentheses.
    3349           0 :  * If "mupa" has any parameters, then the opening parenthesis
    3350           0 :  * appears after the parameter declarations.
    3351             :  */
    3352           0 : static __isl_give isl_printer *print_multi_union_pw_aff_isl(
    3353           0 :         __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)
    3354             : {
    3355           0 :         struct isl_print_space_data data = { 0 };
    3356           0 :         isl_bool has_domain;
    3357             :         isl_space *space;
    3358           0 : 
    3359           0 :         if (!mupa)
    3360             :                 return isl_printer_free(p);
    3361           0 :         has_domain = isl_multi_union_pw_aff_has_non_trivial_domain(mupa);
    3362           0 :         if (has_domain < 0)
    3363           0 :                 return isl_printer_free(p);
    3364           0 : 
    3365             :         space = isl_multi_union_pw_aff_get_space(mupa);
    3366             :         p = print_param_tuple(p, space, &data);
    3367           0 : 
    3368             :         if (has_domain)
    3369             :                 p = isl_printer_print_str(p, "(");
    3370             : 
    3371             :         data.print_dim = &print_union_pw_aff_dim;
    3372             :         data.user = mupa;
    3373             : 
    3374           0 :         p = isl_print_space(space, p, 0, &data);
    3375             :         isl_space_free(space);
    3376             : 
    3377           0 :         if (has_domain) {
    3378           0 :                 p = isl_printer_print_str(p, " : ");
    3379             :                 p = isl_printer_print_union_set_isl_body(p, mupa->u.dom);
    3380           0 :                 p = isl_printer_print_str(p, ")");
    3381           0 :         }
    3382           0 : 
    3383             :         return p;
    3384             : }
    3385             : 
    3386             : /* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.
    3387             :  *
    3388             :  * We currently only support an isl format.
    3389             :  */
    3390             : __isl_give isl_printer *isl_printer_print_multi_union_pw_aff(
    3391             :         __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)
    3392             : {
    3393             :         if (!p || !mupa)
    3394             :                 return isl_printer_free(p);
    3395             : 
    3396             :         if (p->output_format == ISL_FORMAT_ISL)
    3397             :                 return print_multi_union_pw_aff_isl(p, mupa);
    3398             :         isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
    3399             :                 "unsupported output format", return isl_printer_free(p));
    3400             : }

Generated by: LCOV version 1.12