Coverage Report

Created: 2017-11-21 16:49

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/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] : bmap->eq[n];
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_out; ++i) {
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_in; ++i) {
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_div; ++i) {
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 < nparam; ++i) {
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_eq; ++i)
97
0
    p = print_constraint_polylib(bmap, 0, i, p);
98
0
  for (i = 0; i < bmap->n_ineq; ++i)
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 (ext) {
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->n; ++i) {
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
12.0k
{
167
12.0k
  enum isl_dim_type t;
168
12.0k
  unsigned p, s;
169
12.0k
  int count = 0;
170
12.0k
171
32.6k
  for (t = isl_dim_param; t <= type && 
t <= isl_dim_out24.7k
;
++t20.5k
) {
172
20.5k
    s = t == type ? 
pos7.90k
:
isl_space_dim(dim, t)12.6k
;
173
162k
    for (p = 0; p < s; 
++p142k
) {
174
142k
      const char *n = isl_space_get_dim_name(dim, t, p);
175
142k
      if (n && 
!strcmp(n, name)127k
)
176
0
        count++;
177
142k
    }
178
20.5k
  }
179
12.0k
  return count;
180
12.0k
}
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
12.0k
{
189
12.0k
  const char *name;
190
12.0k
  char buffer[20];
191
12.0k
  int primes;
192
12.0k
193
12.0k
  name = type == isl_dim_div ? NULL
194
12.0k
           : 
isl_space_get_dim_name(space, type, pos)12.0k
;
195
12.0k
196
12.0k
  if (!name) {
197
4.15k
    const char *prefix;
198
4.15k
    if (type == isl_dim_param)
199
0
      prefix = s_param_prefix[latex];
200
4.15k
    else if (type == isl_dim_div)
201
12
      prefix = s_div_prefix[latex];
202
4.14k
    else if (isl_space_is_set(space) || 
type == isl_dim_in3.39k
)
203
3.99k
      prefix = s_input_prefix[latex];
204
146
    else
205
146
      prefix = s_output_prefix[latex];
206
4.15k
    snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos);
207
4.15k
    name = buffer;
208
4.15k
  }
209
12.0k
  primes = count_same_name(space, name == buffer ? 
isl_dim_div4.15k
:
type7.90k
,
210
12.0k
         pos, name);
211
12.0k
  p = isl_printer_print_str(p, name);
212
12.0k
  while (primes-- > 0)
213
12.0k
    
p = isl_printer_print_str(p, "'")0
;
214
12.0k
  return p;
215
12.0k
}
216
217
static enum isl_dim_type pos2type(__isl_keep isl_space *dim, unsigned *pos)
218
3.90k
{
219
3.90k
  enum isl_dim_type type;
220
3.90k
  unsigned n_in = isl_space_dim(dim, isl_dim_in);
221
3.90k
  unsigned n_out = isl_space_dim(dim, isl_dim_out);
222
3.90k
  unsigned nparam = isl_space_dim(dim, isl_dim_param);
223
3.90k
224
3.90k
  if (*pos < 1 + nparam) {
225
1.92k
    type = isl_dim_param;
226
1.92k
    *pos -= 1;
227
1.97k
  } else if (*pos < 1 + nparam + n_in) {
228
1.46k
    type = isl_dim_in;
229
1.46k
    *pos -= 1 + nparam;
230
1.46k
  } else 
if (516
*pos < 1 + nparam + n_in + n_out516
) {
231
475
    type = isl_dim_out;
232
475
    *pos -= 1 + nparam + n_in;
233
475
  } else {
234
41
    type = isl_dim_div;
235
41
    *pos -= 1 + nparam + n_in + n_out;
236
41
  }
237
3.90k
238
3.90k
  return type;
239
3.90k
}
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
100
{
251
100
  if (p->output_format == ISL_FORMAT_OMEGA)
252
100
    
return isl_bool_false0
;
253
100
  if (!div)
254
0
    return isl_bool_false;
255
100
  return !isl_int_is_zero(div->row[pos][0]);
256
100
}
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
5.83k
{
265
5.83k
  enum isl_dim_type type;
266
5.83k
  int print_div_def;
267
5.83k
268
5.83k
  if (pos == 0)
269
1.93k
    return isl_printer_print_isl_int(p, c);
270
3.90k
271
3.90k
  type = pos2type(space, &pos);
272
3.90k
  print_div_def = type == isl_dim_div && 
can_print_div_expr(p, div, pos)41
;
273
3.90k
274
3.90k
  if (isl_int_is_one(c))
275
3.90k
    
;3.51k
276
394
  else if (isl_int_is_negone(c))
277
394
    
p = isl_printer_print_str(p, "-")156
;
278
238
  else {
279
238
    p = isl_printer_print_isl_int(p, c);
280
238
    if (p->output_format == ISL_FORMAT_C || print_div_def)
281
31
      p = isl_printer_print_str(p, "*");
282
394
  }
283
3.90k
  if (print_div_def)
284
31
    p = print_div(space, div, pos, p);
285
3.87k
  else
286
3.87k
    p = print_name(space, p, type, pos, latex);
287
5.83k
  return p;
288
5.83k
}
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
4.84k
{
294
4.84k
  int i;
295
4.84k
  int first;
296
4.84k
297
48.9k
  for (i = 0, first = 1; i < len; 
++i44.0k
) {
298
44.0k
    int flip = 0;
299
44.0k
    if (isl_int_is_zero(c[i]))
300
44.0k
      
continue40.0k
;
301
4.04k
    if (!first) {
302
483
      if (isl_int_is_neg(c[i])) {
303
147
        flip = 1;
304
147
        isl_int_neg(c[i], c[i]);
305
147
        p = isl_printer_print_str(p, " - ");
306
147
      } else 
307
336
        p = isl_printer_print_str(p, " + ");
308
483
    }
309
4.04k
    first = 0;
310
4.04k
    p = print_term(dim, div, c[i], i, p, 0);
311
4.04k
    if (flip)
312
4.04k
      
isl_int_neg147
(c[i], c[i]);
313
44.0k
  }
314
4.84k
  if (first)
315
1.28k
    p = isl_printer_print_str(p, "0");
316
4.84k
  return p;
317
4.84k
}
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
2.56k
{
327
2.56k
  unsigned len = 1 + isl_basic_map_total_dim(bmap);
328
2.56k
  return print_affine_of_len(space, div, p, c, len);
329
2.56k
}
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
4.85k
{
337
4.85k
  int i;
338
4.85k
339
4.85k
  if (data->space != local_dim && 
local_type == isl_dim_out12
)
340
6
    offset += local_dim->n_in;
341
4.85k
342
15.1k
  for (i = 0; i < isl_space_dim(local_dim, local_type); 
++i10.3k
) {
343
10.3k
    if (i)
344
6.01k
      p = isl_printer_print_str(p, ", ");
345
10.3k
    if (data->print_dim)
346
4.55k
      p = data->print_dim(p, data, offset + i);
347
5.77k
    else
348
5.77k
      p = print_name(data->space, p, data->type, offset + i,
349
5.77k
          data->latex);
350
10.3k
  }
351
4.85k
  return p;
352
4.85k
}
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
4.86k
{
370
4.86k
  const char *name = NULL;
371
4.86k
  unsigned n = isl_space_dim(local_dim, local_type);
372
4.86k
  if ((local_type == isl_dim_in || 
local_type == isl_dim_out3.43k
)) {
373
3.42k
    name = isl_space_get_tuple_name(local_dim, local_type);
374
3.42k
    if (name) {
375
2.94k
      if (data->latex)
376
0
        p = isl_printer_print_str(p, "\\mathrm{");
377
2.94k
      p = isl_printer_print_str(p, name);
378
2.94k
      if (data->latex)
379
0
        p = isl_printer_print_str(p, "}");
380
2.94k
    }
381
3.42k
  }
382
4.86k
  if (!data->latex || 
n != 10
||
name0
)
383
4.86k
    p = isl_printer_print_str(p, s_open_list[data->latex]);
384
4.86k
  if ((local_type == isl_dim_in || 
local_type == isl_dim_out3.43k
) &&
385
4.86k
      
local_dim->nested[local_type - isl_dim_in]3.42k
) {
386
6
    if (data->space != local_dim && 
local_type == isl_dim_out0
)
387
0
      offset += local_dim->n_in;
388
6
    p = print_nested_map_dim(p,
389
6
        local_dim->nested[local_type - isl_dim_in],
390
6
        data, offset);
391
6
  } else
392
4.85k
    p = print_nested_var_list(p, local_dim, local_type, data,
393
4.85k
            offset);
394
4.86k
  if (!data->latex || 
n != 10
||
name0
)
395
4.86k
    p = isl_printer_print_str(p, s_close_list[data->latex]);
396
4.86k
  return p;
397
4.86k
}
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
4.85k
{
403
4.85k
  data->space = dim;
404
4.85k
  data->type = type;
405
4.85k
  return print_nested_tuple(p, dim, type, data, 0);
406
4.85k
}
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
6
{
412
6
  p = print_nested_tuple(p, local_dim, isl_dim_in, data, offset);
413
6
  p = isl_printer_print_str(p, s_to[data->latex]);
414
6
  p = print_nested_tuple(p, local_dim, isl_dim_out, data, offset);
415
6
416
6
  return p;
417
6
}
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
2.58k
{
423
2.58k
  if (rational && 
!data->latex0
)
424
0
    p = isl_printer_print_str(p, "rat: ");
425
2.58k
  if (isl_space_is_params(space))
426
698
    ;
427
1.88k
  else if (isl_space_is_set(space))
428
467
    p = print_tuple(space, p, isl_dim_set, data);
429
1.42k
  else {
430
1.42k
    p = print_tuple(space, p, isl_dim_in, data);
431
1.42k
    p = isl_printer_print_str(p, s_to[data->latex]);
432
1.42k
    p = print_tuple(space, p, isl_dim_out, data);
433
1.42k
  }
434
2.58k
435
2.58k
  return p;
436
2.58k
}
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
2.47k
{
460
2.47k
  unsigned total = isl_basic_map_total_dim(bmap);
461
2.47k
  unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
462
2.47k
463
2.47k
  if (i + 1 >= bmap->n_ineq)
464
1.04k
    return 0;
465
1.43k
  if (isl_seq_last_non_zero(bmap->ineq[i + 1], 1 + total) != last)
466
548
    return 0;
467
882
  if (last >= o_div) {
468
9
    isl_bool is_div;
469
9
    is_div = isl_basic_map_is_div_constraint(bmap,
470
9
              bmap->ineq[i + 1], last - o_div);
471
9
    if (is_div < 0)
472
0
      return -1;
473
9
    if (is_div)
474
3
      return 0;
475
879
  }
476
879
  return isl_int_abs_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]) &&
477
879
    
!872
isl_int_eq872
(bmap->ineq[i][last], bmap->ineq[i + 1][last]);
478
2.47k
}
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
2.47k
{
488
2.47k
  if (strict)
489
459
    return sign < 0 ? 
"<"300
:
">"159
;
490
2.01k
  if (sign < 0)
491
1.64k
    return s_le[latex];
492
363
  else
493
363
    return s_ge[latex];
494
2.47k
}
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
765
{
515
765
  if (!first_constraint)
516
339
    p = isl_printer_print_str(p, s_and[latex]);
517
765
518
765
  isl_int_set_si(c[last], 0);
519
765
  p = print_affine(bmap, space, div, p, c);
520
765
521
765
  p = isl_printer_print_str(p, " ");
522
765
  p = isl_printer_print_str(p, op);
523
765
  p = isl_printer_print_str(p, " ");
524
765
525
765
  return p;
526
765
}
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
1.79k
{
545
1.79k
  if (!first_constraint)
546
357
    p = isl_printer_print_str(p, s_and[latex]);
547
1.79k
548
1.79k
  isl_int_abs(c[last], c[last]);
549
1.79k
550
1.79k
  p = print_term(space, div, c[last], last, p, latex);
551
1.79k
552
1.79k
  p = isl_printer_print_str(p, " ");
553
1.79k
  p = isl_printer_print_str(p, op);
554
1.79k
  p = isl_printer_print_str(p, " ");
555
1.79k
556
1.79k
  isl_int_set_si(c[last], 0);
557
1.79k
  p = print_affine(bmap, space, div, p, c);
558
1.79k
559
1.79k
  return p;
560
1.79k
}
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
1.10k
{
606
1.10k
  int i;
607
1.10k
  isl_vec *c = NULL;
608
1.10k
  int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
609
1.10k
  unsigned total = isl_basic_map_total_dim(bmap);
610
1.10k
  unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div);
611
1.10k
  int first = 1;
612
1.10k
  int dump;
613
1.10k
614
1.10k
  if (!p)
615
0
    return NULL;
616
1.10k
  bmap = isl_basic_map_copy(bmap);
617
1.10k
  dump = p->dump;
618
1.10k
  if (!dump)
619
1.10k
    bmap = isl_basic_map_sort_constraints(bmap);
620
1.10k
  if (!bmap)
621
0
    goto error;
622
1.10k
623
1.10k
  c = isl_vec_alloc(bmap->ctx, 1 + total);
624
1.10k
  if (!c)
625
0
    goto error;
626
1.10k
627
1.19k
  
for (i = bmap->n_eq - 1; 1.10k
i >= 0;
--i90
) {
628
90
    int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total);
629
90
    if (l < 0) {
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
90
    if (isl_int_is_neg(bmap->eq[i][l]))
636
90
      
isl_seq_cpy(c->el, bmap->eq[i], 1 + total)0
;
637
90
    else
638
90
      isl_seq_neg(c->el, bmap->eq[i], 1 + total);
639
90
    p = print_constraint(bmap, space, div, p, c->el, l,
640
90
            "=", first, latex);
641
90
    first = 0;
642
90
  }
643
3.57k
  for (i = 0; i < bmap->n_ineq; 
++i2.47k
) {
644
2.47k
    int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total);
645
2.47k
    int strict;
646
2.47k
    int s;
647
2.47k
    const char *op;
648
2.47k
    if (l < 0)
649
0
      continue;
650
2.47k
    if (!dump && l >= o_div &&
651
2.47k
        
can_print_div_expr(p, div, l - o_div)22
) {
652
14
      isl_bool is_div;
653
14
      is_div = isl_basic_map_is_div_constraint(bmap,
654
14
                bmap->ineq[i], l - o_div);
655
14
      if (is_div < 0)
656
0
        goto error;
657
14
      if (is_div)
658
7
        continue;
659
2.47k
    }
660
2.47k
    s = isl_int_sgn(bmap->ineq[i][l]);
661
2.47k
    strict = !rational && isl_int_is_negone(bmap->ineq[i][0]);
662
2.47k
    if (s < 0)
663
1.18k
      isl_seq_cpy(c->el, bmap->ineq[i], 1 + total);
664
1.28k
    else
665
1.28k
      isl_seq_neg(c->el, bmap->ineq[i], 1 + total);
666
2.47k
    if (strict)
667
2.47k
      
isl_int_set_si459
(c->el[0], 0);
668
2.47k
    if (!dump && next_is_opposite(bmap, i, l)) {
669
765
      op = constraint_op(-s, strict, latex);
670
765
      p = print_half_constraint(bmap, space, div, p, c->el, l,
671
765
            op, first, latex);
672
765
      first = 1;
673
1.70k
    } else {
674
1.70k
      op = constraint_op(s, strict, latex);
675
1.70k
      p = print_constraint(bmap, space, div, p, c->el, l,
676
1.70k
            op, first, latex);
677
1.70k
      first = 0;
678
1.70k
    }
679
2.47k
  }
680
1.10k
681
1.10k
  isl_basic_map_free(bmap);
682
1.10k
  isl_vec_free(c);
683
1.10k
684
1.10k
  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
1.10k
}
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
31
{
695
31
  int c;
696
31
697
31
  if (!p || !div)
698
0
    return isl_printer_free(p);
699
31
700
31
  c = p->output_format == ISL_FORMAT_C;
701
31
  p = isl_printer_print_str(p, c ? 
"floord("0
: "floor((");
702
31
  p = print_affine_of_len(dim, div, p,
703
31
        div->row[pos] + 1, div->n_col - 1);
704
31
  p = isl_printer_print_str(p, c ? 
", "0
: ")/");
705
31
  p = isl_printer_print_isl_int(p, div->row[pos][0]);
706
31
  p = isl_printer_print_str(p, ")");
707
31
  return p;
708
31
}
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 || !space || !div)
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_div; 
++i4
) {
729
4
    if (!print_defined_divs && can_print_div_expr(p, div, i))
730
2
      continue;
731
2
    if (!first)
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
1.10k
{
752
1.10k
  int i, n;
753
1.10k
754
1.10k
  if (!p || !div)
755
0
    return isl_bool_error;
756
1.10k
  n = isl_mat_rows(div);
757
1.10k
  if (n == 0)
758
1.07k
    return isl_bool_false;
759
29
  if (p->dump)
760
0
    return isl_bool_true;
761
58
  
for (i = 0; 29
i < n;
++i29
)
762
31
    if (!can_print_div_expr(p, div, i))
763
2
      return isl_bool_true;
764
29
  
return isl_bool_false27
;
765
1.10k
}
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
1.10k
{
798
1.10k
  int dump;
799
1.10k
  isl_mat *div;
800
1.10k
  isl_bool exists;
801
1.10k
802
1.10k
  if (!p)
803
0
    return NULL;
804
1.10k
  dump = p->dump;
805
1.10k
  div = isl_basic_map_get_divs(bmap);
806
1.10k
  exists = need_exists(p, div);
807
1.10k
  if (exists >= 0 && exists)
808
2
    p = open_exists(p, space, div, latex);
809
1.10k
810
1.10k
  if (dump)
811
0
    div = isl_mat_free(div);
812
1.10k
  p = print_constraints(bmap, space, div, p, latex);
813
1.10k
  isl_mat_free(div);
814
1.10k
815
1.10k
  if (exists >= 0 && exists)
816
2
    p = isl_printer_print_str(p, s_close_exists[latex]);
817
1.10k
  return p;
818
1.10k
}
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->n; ++i) {
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->n; ++i) {
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
2.61k
{
894
2.61k
  if (!p || !space)
895
0
    return isl_printer_free(p);
896
2.61k
  if (isl_space_dim(space, isl_dim_param) == 0)
897
1.17k
    return p;
898
1.43k
899
1.43k
  p = print_tuple(space, p, isl_dim_param, data);
900
1.43k
  p = isl_printer_print_str(p, s_to[data->latex]);
901
1.43k
902
1.43k
  return p;
903
1.43k
}
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
997
{
928
997
  int i;
929
997
930
997
  if (map->n == 0)
931
123
    p = isl_printer_print_str(p, "1 = 0");
932
2.05k
  for (i = 0; i < map->n; 
++i1.06k
) {
933
1.06k
    if (i)
934
188
      p = isl_printer_print_str(p, s_or[latex]);
935
1.06k
    if (map->n > 1 && 
map->p[i]->n_eq + map->p[i]->n_ineq > 1328
)
936
78
      p = isl_printer_print_str(p, "(");
937
1.06k
    p = print_disjunct(map->p[i], space, p, latex);
938
1.06k
    if (map->n > 1 && 
map->p[i]->n_eq + map->p[i]->n_ineq > 1328
)
939
78
      p = isl_printer_print_str(p, ")");
940
1.06k
  }
941
997
  return p;
942
997
}
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
38
{
957
38
  isl_bool is_universe;
958
38
959
38
  p = print_disjunct(hull, space, p, latex);
960
38
  map = isl_map_plain_gist_basic_map(isl_map_copy(map), hull);
961
38
  is_universe = isl_map_plain_is_universe(map);
962
38
  if (is_universe < 0)
963
0
    goto error;
964
38
  if (!is_universe) {
965
37
    p = isl_printer_print_str(p, s_and[latex]);
966
37
    p = isl_printer_print_str(p, "(");
967
37
    p = print_disjuncts_core(map, space, p, latex);
968
37
    p = isl_printer_print_str(p, ")");
969
37
  }
970
38
  isl_map_free(map);
971
38
972
38
  return p;
973
0
error:
974
0
  isl_map_free(map);
975
0
  isl_printer_free(p);
976
0
  return NULL;
977
38
}
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
2.45k
{
990
2.45k
  if (isl_map_plain_is_universe(map))
991
1.45k
    return p;
992
998
993
998
  p = isl_printer_print_str(p, s_such_that[latex]);
994
998
  if (!p)
995
0
    return NULL;
996
998
997
998
  if (!p->dump && map->n >= 2) {
998
141
    isl_basic_map *hull;
999
141
    isl_bool is_universe;
1000
141
1001
141
    hull = isl_map_plain_unshifted_simple_hull(isl_map_copy(map));
1002
141
    is_universe = isl_basic_map_plain_is_universe(hull);
1003
141
    if (is_universe < 0)
1004
0
      p = isl_printer_free(p);
1005
141
    else if (!is_universe)
1006
38
      return print_disjuncts_in_hull(map, space, hull,
1007
38
              p, latex);
1008
103
    isl_basic_map_free(hull);
1009
103
  }
1010
998
1011
998
  
return print_disjuncts_core(map, space, p, latex)960
;
1012
2.45k
}
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
2.40k
{
1025
2.40k
  if (isl_map_plain_is_universe(map) && 
isl_space_is_params(map->dim)1.46k
)
1026
237
    return isl_printer_print_str(p, s_such_that[latex]);
1027
2.16k
  else
1028
2.16k
    return print_disjuncts(map, space, p, latex);
1029
2.40k
}
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
2.33k
{
1038
2.33k
  int i;
1039
2.33k
1040
2.33k
  if (!split)
1041
123
    return;
1042
2.21k
1043
4.68k
  
for (i = 0; 2.21k
i < n;
++i2.46k
) {
1044
2.46k
    isl_basic_map_free(split[i].aff);
1045
2.46k
    isl_map_free(split[i].map);
1046
2.46k
  }
1047
2.33k
1048
2.33k
  free(split);
1049
2.33k
}
1050
1051
static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap)
1052
2.46k
{
1053
2.46k
  int i, j;
1054
2.46k
  unsigned nparam, n_in, n_out, total;
1055
2.46k
1056
2.46k
  bmap = isl_basic_map_cow(bmap);
1057
2.46k
  if (!bmap)
1058
0
    return NULL;
1059
2.46k
  if (isl_basic_map_free_inequality(bmap, bmap->n_ineq) < 0)
1060
0
    goto error;
1061
2.46k
1062
2.46k
  nparam = isl_basic_map_dim(bmap, isl_dim_param);
1063
2.46k
  n_in = isl_basic_map_dim(bmap, isl_dim_in);
1064
2.46k
  n_out = isl_basic_map_dim(bmap, isl_dim_out);
1065
2.46k
  total = isl_basic_map_dim(bmap, isl_dim_all);
1066
4.54k
  for (i = bmap->n_eq - 1; i >= 0; 
--i2.07k
) {
1067
2.07k
    j = isl_seq_last_non_zero(bmap->eq[i] + 1, total);
1068
2.07k
    if (j >= nparam && 
j < nparam + n_in + n_out2.01k
&&
1069
2.07k
        
(1.98k
isl_int_is_one1.98k
(bmap->eq[i][1 + j]) ||
1070
1.98k
         
isl_int_is_negone2
(bmap->eq[i][1 + j])))
1071
1.98k
      continue;
1072
86
    if (isl_basic_map_drop_equality(bmap, i) < 0)
1073
0
      goto error;
1074
2.07k
  }
1075
2.46k
1076
2.46k
  bmap = isl_basic_map_finalize(bmap);
1077
2.46k
1078
2.46k
  return bmap;
1079
0
error:
1080
0
  isl_basic_map_free(bmap);
1081
0
  return NULL;
1082
2.46k
}
1083
1084
static int aff_split_cmp(const void *p1, const void *p2, void *user)
1085
326
{
1086
326
  const struct isl_aff_split *s1, *s2;
1087
326
  s1 = (const struct isl_aff_split *) p1;
1088
326
  s2 = (const struct isl_aff_split *) p2;
1089
326
1090
326
  return isl_basic_map_plain_cmp(s1->aff, s2->aff);
1091
326
}
1092
1093
static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap,
1094
  __isl_keep isl_basic_map *aff)
1095
2.46k
{
1096
2.46k
  int i, j;
1097
2.46k
  unsigned total;
1098
2.46k
1099
2.46k
  if (!bmap || !aff)
1100
0
    goto error;
1101
2.46k
1102
2.46k
  total = isl_space_dim(bmap->dim, isl_dim_all);
1103
2.46k
1104
4.54k
  for (i = bmap->n_eq - 1; i >= 0; 
--i2.07k
) {
1105
2.07k
    if (isl_seq_first_non_zero(bmap->eq[i] + 1 + total,
1106
2.07k
              bmap->n_div) != -1)
1107
24
      continue;
1108
3.59k
    
for (j = 0; 2.04k
j < aff->n_eq;
++j1.54k
) {
1109
3.53k
      if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + total) &&
1110
3.53k
          
!isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + total)1.54k
)
1111
1.54k
        continue;
1112
1.98k
      if (isl_basic_map_drop_equality(bmap, i) < 0)
1113
0
        goto error;
1114
1.98k
      break;
1115
1.98k
    }
1116
2.07k
  }
1117
2.46k
1118
2.46k
  return bmap;
1119
0
error:
1120
0
  isl_basic_map_free(bmap);
1121
0
  return NULL;
1122
2.46k
}
1123
1124
static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map)
1125
2.21k
{
1126
2.21k
  int i, n;
1127
2.21k
  struct isl_aff_split *split;
1128
2.21k
  isl_ctx *ctx;
1129
2.21k
1130
2.21k
  ctx = isl_map_get_ctx(map);
1131
2.21k
  split = isl_calloc_array(ctx, struct isl_aff_split, map->n);
1132
2.21k
  if (!split)
1133
0
    return NULL;
1134
2.21k
1135
4.68k
  
for (i = 0; 2.21k
i < map->n;
++i2.46k
) {
1136
2.46k
    isl_basic_map *bmap;
1137
2.46k
    split[i].aff = get_aff(isl_basic_map_copy(map->p[i]));
1138
2.46k
    bmap = isl_basic_map_copy(map->p[i]);
1139
2.46k
    bmap = isl_basic_map_cow(bmap);
1140
2.46k
    bmap = drop_aff(bmap, split[i].aff);
1141
2.46k
    split[i].map = isl_map_from_basic_map(bmap);
1142
2.46k
    if (!split[i].aff || !split[i].map)
1143
0
      goto error;
1144
2.46k
  }
1145
2.21k
1146
2.21k
  if (isl_sort(split, map->n, sizeof(struct isl_aff_split),
1147
2.21k
      &aff_split_cmp, NULL) < 0)
1148
0
    goto error;
1149
2.21k
1150
2.21k
  n = map->n;
1151
2.46k
  for (i = n - 1; i >= 1; 
--i254
) {
1152
254
    if (!isl_basic_map_plain_is_equal(split[i - 1].aff,
1153
254
             split[i].aff))
1154
67
      continue;
1155
187
    isl_basic_map_free(split[i].aff);
1156
187
    split[i - 1].map = isl_map_union(split[i - 1].map,
1157
187
             split[i].map);
1158
187
    if (i != n - 1)
1159
10
      split[i] = split[n - 1];
1160
254
    split[n - 1].aff = NULL;
1161
254
    split[n - 1].map = NULL;
1162
254
    --n;
1163
254
  }
1164
2.21k
1165
2.21k
  return split;
1166
0
error:
1167
0
  free_split(split, map->n);
1168
0
  return NULL;
1169
2.21k
}
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
4.33k
{
1174
4.33k
  int i;
1175
4.33k
  unsigned total;
1176
4.33k
1177
4.33k
  if (!eq)
1178
0
    return -1;
1179
4.33k
1180
4.33k
  pos += isl_space_offset(dim, type);
1181
4.33k
  total = isl_basic_map_total_dim(eq);
1182
4.33k
1183
8.86k
  for (i = 0; i < eq->n_eq; 
++i4.53k
) {
1184
6.46k
    if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos)
1185
4.53k
      continue;
1186
1.92k
    if (isl_int_is_one(eq->eq[i][1 + pos]))
1187
1.92k
      isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total);
1188
6.46k
    return i;
1189
6.46k
  }
1190
4.33k
1191
4.33k
  
return -12.40k
;
1192
4.33k
}
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
4.33k
{
1205
4.33k
  isl_basic_map *eq = data->user;
1206
4.33k
  int j;
1207
4.33k
1208
4.33k
  j = defining_equality(eq, data->space, data->type, pos);
1209
4.33k
  if (j >= 0) {
1210
1.92k
    if (isl_space_has_dim_name(data->space, data->type, pos)) {
1211
0
      p = print_name(data->space, p, data->type, pos,
1212
0
          data->latex);
1213
0
      p = isl_printer_print_str(p, " = ");
1214
0
    }
1215
1.92k
    pos += 1 + isl_space_offset(data->space, data->type);
1216
1.92k
    p = print_affine_of_len(data->space, NULL, p, eq->eq[j], pos);
1217
2.40k
  } else {
1218
2.40k
    p = print_name(data->space, p, data->type, pos, data->latex);
1219
2.40k
  }
1220
4.33k
1221
4.33k
  return p;
1222
4.33k
}
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
2.21k
{
1227
2.21k
  struct isl_print_space_data data = { 0 };
1228
2.21k
  int i;
1229
2.21k
  int rational;
1230
2.21k
1231
2.21k
  data.print_dim = &print_dim_eq;
1232
4.49k
  for (i = 0; i < n; 
++i2.28k
) {
1233
2.41k
    if (!split[i].map)
1234
134
      break;
1235
2.28k
    rational = split[i].map->n > 0 &&
1236
2.28k
        ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL);
1237
2.28k
    if (i)
1238
67
      p = isl_printer_print_str(p, "; ");
1239
2.41k
    data.user = split[i].aff;
1240
2.41k
    p = isl_print_space(space, p, rational, &data);
1241
2.41k
    p = print_disjuncts_map(split[i].map, space, p, 0);
1242
2.41k
  }
1243
2.21k
1244
2.21k
  return p;
1245
2.21k
}
1246
1247
static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map,
1248
  __isl_take isl_printer *p)
1249
2.33k
{
1250
2.33k
  struct isl_print_space_data data = { 0 };
1251
2.33k
  struct isl_aff_split *split = NULL;
1252
2.33k
  int rational;
1253
2.33k
1254
2.33k
  if (!p || !map)
1255
0
    return isl_printer_free(p);
1256
2.33k
  if (!p->dump && map->n > 0)
1257
2.21k
    split = split_aff(map);
1258
2.33k
  if (split) {
1259
2.21k
    p = print_split_map(p, split, map->n, map->dim);
1260
2.21k
  } else {
1261
123
    rational = map->n > 0 &&
1262
123
        ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL);
1263
123
    p = isl_print_space(map->dim, p, rational, &data);
1264
123
    p = print_disjuncts_map(map, map->dim, p, 0);
1265
123
  }
1266
2.33k
  free_split(split, map->n);
1267
2.33k
  return p;
1268
2.33k
}
1269
1270
static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map,
1271
  __isl_take isl_printer *p)
1272
2.26k
{
1273
2.26k
  struct isl_print_space_data data = { 0 };
1274
2.26k
1275
2.26k
  p = print_param_tuple(p, map->dim, &data);
1276
2.26k
  p = isl_printer_print_str(p, s_open_set[0]);
1277
2.26k
  p = isl_map_print_isl_body(map, p);
1278
2.26k
  p = isl_printer_print_str(p, s_close_set[0]);
1279
2.26k
  return p;
1280
2.26k
}
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; i < map->n; ++i) {
1312
0
    if (!split[i].map)
1313
0
      break;
1314
0
    if (i)
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 || !bmap)
1327
0
    goto error;
1328
0
  if (p->output_format == ISL_FORMAT_ISL)
1329
0
    return isl_basic_map_print_isl(bmap, p, 0);
1330
0
  else if (p->output_format == ISL_FORMAT_OMEGA)
1331
0
    return basic_map_print_omega(bmap, p);
1332
0
  isl_assert(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 || !bset)
1342
0
    goto error;
1343
0
1344
0
  if (p->output_format == ISL_FORMAT_ISL)
1345
0
    return isl_basic_map_print_isl(bset, p, 0);
1346
0
  else if (p->output_format == ISL_FORMAT_POLYLIB)
1347
0
    return isl_basic_set_print_polylib(bset, p, 0);
1348
0
  else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1349
0
    return isl_basic_set_print_polylib(bset, p, 1);
1350
0
  else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS)
1351
0
    return bset_print_constraints_polylib(bset, p);
1352
0
  else if (p->output_format == ISL_FORMAT_OMEGA)
1353
0
    return basic_set_print_omega(bset, p);
1354
0
  isl_assert(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
973
{
1363
973
  if (!p || !set)
1364
0
    goto error;
1365
973
  if (p->output_format == ISL_FORMAT_ISL)
1366
973
    return isl_map_print_isl(set_to_map(set), p);
1367
0
  else if (p->output_format == ISL_FORMAT_POLYLIB)
1368
0
    return isl_set_print_polylib(set, p, 0);
1369
0
  else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1370
0
    return isl_set_print_polylib(set, p, 1);
1371
0
  else if (p->output_format == ISL_FORMAT_OMEGA)
1372
0
    return isl_set_print_omega(set, p);
1373
0
  else if (p->output_format == ISL_FORMAT_LATEX)
1374
0
    return isl_map_print_latex(set_to_map(set), p);
1375
0
  isl_assert(set->ctx, 0, goto error);
1376
0
error:
1377
0
  isl_printer_free(p);
1378
0
  return NULL;
1379
973
}
1380
1381
__isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
1382
  __isl_keep isl_map *map)
1383
1.29k
{
1384
1.29k
  if (!p || !map)
1385
0
    goto error;
1386
1.29k
1387
1.29k
  if (p->output_format == ISL_FORMAT_ISL)
1388
1.29k
    return isl_map_print_isl(map, p);
1389
0
  else if (p->output_format == ISL_FORMAT_POLYLIB)
1390
0
    return isl_map_print_polylib(map, p, 0);
1391
0
  else if (p->output_format == ISL_FORMAT_EXT_POLYLIB)
1392
0
    return isl_map_print_polylib(map, p, 1);
1393
0
  else if (p->output_format == ISL_FORMAT_OMEGA)
1394
0
    return isl_map_print_omega(map, p);
1395
0
  else if (p->output_format == ISL_FORMAT_LATEX)
1396
0
    return isl_map_print_latex(map, p);
1397
0
  isl_assert(map->ctx, 0, goto error);
1398
0
error:
1399
0
  isl_printer_free(p);
1400
0
  return NULL;
1401
1.29k
}
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
75
{
1410
75
  struct isl_union_print_data *data;
1411
75
  data = (struct isl_union_print_data *)user;
1412
75
1413
75
  if (!data->first)
1414
28
    data->p = isl_printer_print_str(data->p, "; ");
1415
75
  data->first = 0;
1416
75
1417
75
  data->p = isl_map_print_isl_body(map, data->p);
1418
75
  isl_map_free(map);
1419
75
1420
75
  return isl_stat_ok;
1421
75
}
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
94
{
1426
94
  struct isl_union_print_data data;
1427
94
  struct isl_print_space_data space_data = { 0 };
1428
94
  isl_space *space;
1429
94
1430
94
  space = isl_union_map_get_space(umap);
1431
94
  p = print_param_tuple(p, space, &space_data);
1432
94
  isl_space_free(space);
1433
94
  p = isl_printer_print_str(p, s_open_set[0]);
1434
94
  data.p = p;
1435
94
  data.first = 1;
1436
94
  isl_union_map_foreach_map(umap, &print_map_body, &data);
1437
94
  p = data.p;
1438
94
  p = isl_printer_print_str(p, s_close_set[0]);
1439
94
  return p;
1440
94
}
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
94
{
1469
94
  if (!p || !umap)
1470
0
    goto error;
1471
94
1472
94
  if (p->output_format == ISL_FORMAT_ISL)
1473
94
    return isl_union_map_print_isl(umap, p);
1474
0
  if (p->output_format == ISL_FORMAT_LATEX)
1475
0
    return isl_union_map_print_latex(umap, p);
1476
0
1477
0
  isl_die(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
94
}
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 || !uset)
1488
0
    goto error;
1489
0
1490
0
  if (p->output_format == ISL_FORMAT_ISL)
1491
0
    return isl_union_map_print_isl((isl_union_map *)uset, p);
1492
0
  if (p->output_format == ISL_FORMAT_LATEX)
1493
0
    return isl_union_map_print_latex((isl_union_map *)uset, p);
1494
0
1495
0
  isl_die(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->n; ++i)
1508
0
    if (!isl_upoly_is_zero(rec->p[i]))
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 && isl_int_is_neg(cst->n);
1524
0
  if (!first)
1525
0
    p = isl_printer_print_str(p, neg ? " - " :  " + ");
1526
0
  if (neg)
1527
0
    isl_int_neg(cst->n, cst->n);
1528
0
  if (isl_int_is_zero(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 ? "NaN" : "infty");
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 (!isl_int_is_zero(cst->d) && !isl_int_is_one(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 (p->output_format == ISL_FORMAT_C) {
1566
0
    int i;
1567
0
    for (i = 1; i < exp; ++i) {
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 || !up || !space || !div)
1589
0
    goto error;
1590
0
1591
0
  if (isl_upoly_is_cst(up))
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->n; ++i) {
1602
0
    if (isl_upoly_is_zero(rec->p[i]))
1603
0
      continue;
1604
0
    if (isl_upoly_is_negone(rec->p[i])) {
1605
0
      if (!i)
1606
0
        p = isl_printer_print_str(p, "-1");
1607
0
      else if (first)
1608
0
        p = isl_printer_print_str(p, "-");
1609
0
      else
1610
0
        p = isl_printer_print_str(p, " - ");
1611
0
    } else if (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 || !isl_upoly_is_one(rec->p[i]))
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 (!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 || !qp)
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 || !qp)
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)) {
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 (!isl_int_is_one(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 (!isl_int_is_one(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 || !qp)
1705
0
    goto error;
1706
0
1707
0
  if (p->output_format == ISL_FORMAT_ISL)
1708
0
    return print_qpolynomial_isl(p, qp);
1709
0
  else if (p->output_format == ISL_FORMAT_C)
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_assert(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 (fold->type == isl_fold_max)
1742
0
    p = isl_printer_print_str(p, "max");
1743
0
  p = isl_printer_print_str(p, "(");
1744
0
  for (i = 0; i < fold->n; ++i) {
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_assert(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->n; ++i) {
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)) {
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 || !pwqp)
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 == 0) {
1804
0
    if (!isl_space_is_set(pwqp->dim)) {
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->n; ++i) {
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)) {
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 == 0) {
1865
0
    if (!isl_space_is_set(pwf->dim)) {
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_div) {
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 (isl_int_is_one(c))
1910
0
    ;
1911
0
  else if (isl_int_is_negone(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 < len; ++i) {
1930
0
    int flip = 0;
1931
0
    if (isl_int_is_zero(c[i]))
1932
0
      continue;
1933
0
    if (!first) {
1934
0
      if (isl_int_is_neg(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 >= 0) {
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 (is_div)
1979
0
      return p;
1980
0
  }
1981
0
1982
0
  if (!*first)
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_eq; ++i) {
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_ineq; ++i)
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 (set->n == 0)
2036
0
    p = isl_printer_print_str(p, "0");
2037
0
2038
0
  for (i = 0; i < set->n; ++i) {
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 && isl_set_plain_is_universe(pwqp->p[0].set)) {
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; i < pwqp->n; ++i) {
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 || !pwqp)
2082
0
    goto error;
2083
0
2084
0
  if (p->output_format == ISL_FORMAT_ISL)
2085
0
    return print_pw_qpolynomial_isl(p, pwqp);
2086
0
  else if (p->output_format == ISL_FORMAT_C)
2087
0
    return print_pw_qpolynomial_c(p, pwqp);
2088
0
  isl_assert(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 || !upwqp)
2133
0
    goto error;
2134
0
2135
0
  if (p->output_format == ISL_FORMAT_ISL)
2136
0
    return print_union_pw_qpolynomial_isl(p, upwqp);
2137
0
  isl_die(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 - 1; ++i)
2155
0
    if (fold->type == isl_fold_min)
2156
0
      p = isl_printer_print_str(p, "min(");
2157
0
    else if (fold->type == isl_fold_max)
2158
0
      p = isl_printer_print_str(p, "max(");
2159
0
2160
0
  for (i = 0; i < fold->n; ++i) {
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 || !fold)
2174
0
    goto error;
2175
0
  if (p->output_format == ISL_FORMAT_ISL)
2176
0
    return qpolynomial_fold_print(fold, p);
2177
0
  else if (p->output_format == ISL_FORMAT_C)
2178
0
    return print_qpolynomial_fold_c(p, fold->dim, fold);
2179
0
  isl_die(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 && isl_set_plain_is_universe(pwf->p[0].set)) {
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; i < pwf->n; ++i) {
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 || !pwf)
2218
0
    goto error;
2219
0
2220
0
  if (p->output_format == ISL_FORMAT_ISL)
2221
0
    return print_pw_qpolynomial_fold_isl(p, pwf);
2222
0
  else if (p->output_format == ISL_FORMAT_C)
2223
0
    return print_pw_qpolynomial_fold_c(p, pwf);
2224
0
  isl_assert(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 || !upwf)
2287
0
    goto error;
2288
0
2289
0
  if (p->output_format == ISL_FORMAT_ISL)
2290
0
    return print_union_pw_qpolynomial_fold_isl(p, upwf);
2291
0
  isl_die(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 || !c)
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 && exists)
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 && exists)
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
1
{
2345
1
  struct isl_print_space_data data = { 0 };
2346
1
2347
1
  if (!space)
2348
0
    goto error;
2349
1
2350
1
  p = print_param_tuple(p, space, &data);
2351
1
2352
1
  p = isl_printer_print_str(p, "{ ");
2353
1
  if (isl_space_is_params(space))
2354
1
    p = isl_printer_print_str(p, s_such_that[0]);
2355
0
  else
2356
0
    p = isl_print_space(space, p, 0, &data);
2357
1
  p = isl_printer_print_str(p, " }");
2358
1
2359
1
  return p;
2360
0
error:
2361
0
  isl_printer_free(p);
2362
0
  return NULL;
2363
1
}
2364
2365
__isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p,
2366
  __isl_keep isl_space *space)
2367
1
{
2368
1
  if (!p || !space)
2369
0
    return isl_printer_free(p);
2370
1
  if (p->output_format == ISL_FORMAT_ISL)
2371
1
    return isl_printer_print_space_isl(p, space);
2372
0
  else if (p->output_format == ISL_FORMAT_OMEGA)
2373
0
    return print_omega_parameters(space, p);
2374
0
2375
0
  isl_die(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 > 0) {
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 (isl_space_is_params(ls->dim))
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
324
{
2410
324
  unsigned total;
2411
324
2412
324
  if (isl_aff_is_nan(aff))
2413
0
    return isl_printer_print_str(p, "NaN");
2414
324
2415
324
  total = isl_local_space_dim(aff->ls, isl_dim_all);
2416
324
  p = isl_printer_print_str(p, "(");
2417
324
  p = print_affine_of_len(aff->ls->dim, aff->ls->div, p,
2418
324
        aff->v->el + 1, 1 + total);
2419
324
  if (isl_int_is_one(aff->v->el[0]))
2420
324
    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
324
2426
324
  return p;
2427
324
}
2428
2429
static __isl_give isl_printer *print_aff(__isl_take isl_printer *p,
2430
  __isl_keep isl_aff *aff)
2431
102
{
2432
102
  struct isl_print_space_data data = { 0 };
2433
102
2434
102
  if (isl_space_is_params(aff->ls->dim))
2435
0
    ;
2436
102
  else {
2437
102
    p = print_tuple(aff->ls->dim, p, isl_dim_set, &data);
2438
102
    p = isl_printer_print_str(p, " -> ");
2439
102
  }
2440
102
  p = isl_printer_print_str(p, "[");
2441
102
  p = print_aff_body(p, aff);
2442
102
  p = isl_printer_print_str(p, "]");
2443
102
2444
102
  return p;
2445
102
}
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
102
{
2471
102
  int i;
2472
102
2473
102
  if (!pa)
2474
0
    return isl_printer_free(p);
2475
102
2476
204
  
for (i = 0; 102
i < pa->n;
++i102
) {
2477
102
    isl_space *space;
2478
102
2479
102
    if (i)
2480
0
      p = isl_printer_print_str(p, "; ");
2481
102
    p = print_aff(p, pa->p[i].aff);
2482
102
    space = isl_aff_get_domain_space(pa->p[i].aff);
2483
102
    p = print_disjuncts(set_to_map(pa->p[i].set), space, p, 0);
2484
102
    isl_space_free(space);
2485
102
  }
2486
102
2487
102
  return p;
2488
102
}
2489
2490
static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p,
2491
  __isl_keep isl_pw_aff *pwaff)
2492
102
{
2493
102
  struct isl_print_space_data data = { 0 };
2494
102
2495
102
  if (!pwaff)
2496
0
    goto error;
2497
102
2498
102
  p = print_param_tuple(p, pwaff->dim, &data);
2499
102
  p = isl_printer_print_str(p, "{ ");
2500
102
  p = print_pw_aff_body(p, pwaff);
2501
102
  p = isl_printer_print_str(p, " }");
2502
102
  return p;
2503
0
error:
2504
0
  isl_printer_free(p);
2505
0
  return NULL;
2506
102
}
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_div) {
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 (isl_int_is_one(c))
2540
0
    ;
2541
0
  else if (isl_int_is_negone(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 < len; ++i) {
2560
0
    int flip = 0;
2561
0
    if (isl_int_is_zero(c[i]))
2562
0
      continue;
2563
0
    if (!first) {
2564
0
      if (isl_int_is_neg(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 (!isl_int_is_one(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 (!isl_int_is_one(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
6
{
2612
6
  isl_set *domain;
2613
6
  isl_ast_build *build;
2614
6
  isl_ast_expr *expr;
2615
6
2616
6
  if (pwaff->n < 1)
2617
6
    
isl_die0
(p->ctx, isl_error_unsupported,
2618
6
      "cannot print empty isl_pw_aff in C format",
2619
6
      return isl_printer_free(p));
2620
6
2621
6
  domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff));
2622
6
  build = isl_ast_build_from_context(domain);
2623
6
  expr = isl_ast_build_expr_from_pw_aff(build, isl_pw_aff_copy(pwaff));
2624
6
  p = isl_printer_print_ast_expr(p, expr);
2625
6
  isl_ast_expr_free(expr);
2626
6
  isl_ast_build_free(build);
2627
6
2628
6
  return p;
2629
6
}
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 || !aff)
2635
0
    goto error;
2636
0
2637
0
  if (p->output_format == ISL_FORMAT_ISL)
2638
0
    return print_aff_isl(p, aff);
2639
0
  else if (p->output_format == ISL_FORMAT_C)
2640
0
    return print_aff_c(p, aff);
2641
0
  isl_die(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
108
{
2651
108
  if (!p || !pwaff)
2652
0
    goto error;
2653
108
2654
108
  if (p->output_format == ISL_FORMAT_ISL)
2655
108
    
return print_pw_aff_isl(p, pwaff)102
;
2656
6
  else if (p->output_format == ISL_FORMAT_C)
2657
6
    return print_pw_aff_c(p, pwaff);
2658
0
  isl_die(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
108
}
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_ok : isl_stat_error;
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 || !upa)
2732
0
    return isl_printer_free(p);
2733
0
2734
0
  if (p->output_format == ISL_FORMAT_ISL)
2735
0
    return print_union_pw_aff_isl(p, upa);
2736
0
  isl_die(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
222
{
2750
222
  isl_multi_aff *ma = data->user;
2751
222
2752
222
  if (data->type == isl_dim_out)
2753
222
    p = print_aff_body(p, ma->p[pos]);
2754
0
  else
2755
0
    p = print_name(data->space, p, data->type, pos, data->latex);
2756
222
2757
222
  return p;
2758
222
}
2759
2760
static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p,
2761
  __isl_keep isl_multi_aff *maff)
2762
182
{
2763
182
  struct isl_print_space_data data = { 0 };
2764
182
2765
182
  data.print_dim = &print_dim_ma;
2766
182
  data.user = maff;
2767
182
  return isl_print_space(maff->space, p, 0, &data);
2768
182
}
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 || !maff)
2792
0
    goto error;
2793
0
2794
0
  if (p->output_format == ISL_FORMAT_ISL)
2795
0
    return print_multi_aff_isl(p, maff);
2796
0
  isl_die(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
154
{
2806
154
  int i;
2807
154
2808
154
  if (!pma)
2809
0
    goto error;
2810
154
2811
336
  
for (i = 0; 154
i < pma->n;
++i182
) {
2812
182
    isl_space *space;
2813
182
2814
182
    if (i)
2815
28
      p = isl_printer_print_str(p, "; ");
2816
182
    p = print_multi_aff(p, pma->p[i].maff);
2817
182
    space = isl_multi_aff_get_domain_space(pma->p[i].maff);
2818
182
    p = print_disjuncts(set_to_map(pma->p[i].set), space, p, 0);
2819
182
    isl_space_free(space);
2820
182
  }
2821
154
  return p;
2822
0
error:
2823
0
  isl_printer_free(p);
2824
0
  return NULL;
2825
154
}
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
154
{
2830
154
  struct isl_print_space_data data = { 0 };
2831
154
2832
154
  if (!pma)
2833
0
    goto error;
2834
154
2835
154
  p = print_param_tuple(p, pma->dim, &data);
2836
154
  p = isl_printer_print_str(p, "{ ");
2837
154
  p = print_pw_multi_aff_body(p, pma);
2838
154
  p = isl_printer_print_str(p, " }");
2839
154
  return p;
2840
0
error:
2841
0
  isl_printer_free(p);
2842
0
  return NULL;
2843
154
}
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 - 1; ++i) {
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 (pma->n < 1)
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 && isl_pw_multi_aff_dim(pma, isl_dim_out) == 1)
2881
0
    return print_unnamed_pw_multi_aff_c(p, pma);
2882
0
  if (!name)
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
154
{
2902
154
  if (!p || !pma)
2903
0
    goto error;
2904
154
2905
154
  if (p->output_format == ISL_FORMAT_ISL)
2906
154
    return print_pw_multi_aff_isl(p, pma);
2907
0
  if (p->output_format == ISL_FORMAT_C)
2908
0
    return print_pw_multi_aff_c(p, pma);
2909
0
  isl_die(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
154
}
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 || !upma)
2956
0
    goto error;
2957
0
2958
0
  if (p->output_format == ISL_FORMAT_ISL)
2959
0
    return print_union_pw_multi_aff_isl(p, upma);
2960
0
  isl_die(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 || !isl_set_plain_is_universe(pa->p[0].set);
2991
0
  if (need_parens)
2992
0
    p = isl_printer_print_str(p, "(");
2993
0
  for (i = 0; i < pa->n; ++i) {
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 || !mpa)
3032
0
    return isl_printer_free(p);
3033
0
3034
0
  if (p->output_format == ISL_FORMAT_ISL)
3035
0
    return print_multi_pw_aff_isl(p, mpa);
3036
0
  isl_die(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 || !mv)
3085
0
    return isl_printer_free(p);
3086
0
3087
0
  if (p->output_format == ISL_FORMAT_ISL)
3088
0
    return print_multi_val_isl(p, mv);
3089
0
  isl_die(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 || !mupa)
3142
0
    return isl_printer_free(p);
3143
0
3144
0
  if (p->output_format == ISL_FORMAT_ISL)
3145
0
    return print_multi_union_pw_aff_isl(p, mupa);
3146
0
  isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
3147
0
    "unsupported output format", return isl_printer_free(p));
3148
0
}