Coverage Report

Created: 2017-03-27 23:01

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