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