Coverage Report

Created: 2017-10-03 07:32

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