isl_basic_map_simplify: eliminate known divs that appear with unit coefficient
[platform/upstream/isl.git] / isl_test.c
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  *
4  * Use of this software is governed by the GNU LGPLv2.1 license
5  *
6  * Written by Sven Verdoolaege, K.U.Leuven, Departement
7  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
8  */
9
10 #include <assert.h>
11 #include <stdio.h>
12 #include <limits.h>
13 #include <isl_ctx_private.h>
14 #include <isl_map_private.h>
15 #include <isl_aff_private.h>
16 #include <isl/set.h>
17 #include <isl/flow.h>
18 #include <isl/constraint.h>
19 #include <isl/polynomial.h>
20 #include <isl/union_map.h>
21 #include <isl_factorization.h>
22 #include <isl/schedule.h>
23 #include <isl_options_private.h>
24 #include <isl/vertices.h>
25
26 #define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array))
27
28 static char *srcdir;
29
30 static char *get_filename(isl_ctx *ctx, const char *name, const char *suffix) {
31         char *filename;
32         int length;
33         char *pattern = "%s/test_inputs/%s.%s";
34
35         length = strlen(pattern) - 6 + strlen(srcdir) + strlen(name)
36                 + strlen(suffix) + 1;
37         filename = isl_alloc_array(ctx, char, length);
38
39         if (!filename)
40                 return NULL;
41
42         sprintf(filename, pattern, srcdir, name, suffix);
43
44         return filename;
45 }
46
47 void test_parse_map(isl_ctx *ctx, const char *str)
48 {
49         isl_map *map;
50
51         map = isl_map_read_from_str(ctx, str);
52         assert(map);
53         isl_map_free(map);
54 }
55
56 int test_parse_map_equal(isl_ctx *ctx, const char *str, const char *str2)
57 {
58         isl_map *map, *map2;
59         int equal;
60
61         map = isl_map_read_from_str(ctx, str);
62         map2 = isl_map_read_from_str(ctx, str2);
63         equal = isl_map_is_equal(map, map2);
64         isl_map_free(map);
65         isl_map_free(map2);
66
67         if (equal < 0)
68                 return -1;
69         if (!equal)
70                 isl_die(ctx, isl_error_unknown, "maps not equal",
71                         return -1);
72
73         return 0;
74 }
75
76 void test_parse_pwqp(isl_ctx *ctx, const char *str)
77 {
78         isl_pw_qpolynomial *pwqp;
79
80         pwqp = isl_pw_qpolynomial_read_from_str(ctx, str);
81         assert(pwqp);
82         isl_pw_qpolynomial_free(pwqp);
83 }
84
85 static void test_parse_pwaff(isl_ctx *ctx, const char *str)
86 {
87         isl_pw_aff *pwaff;
88
89         pwaff = isl_pw_aff_read_from_str(ctx, str);
90         assert(pwaff);
91         isl_pw_aff_free(pwaff);
92 }
93
94 int test_parse(struct isl_ctx *ctx)
95 {
96         isl_map *map, *map2;
97         const char *str, *str2;
98
99         str = "{ [i] -> [-i] }";
100         map = isl_map_read_from_str(ctx, str);
101         assert(map);
102         isl_map_free(map);
103
104         str = "{ A[i] -> L[([i/3])] }";
105         map = isl_map_read_from_str(ctx, str);
106         assert(map);
107         isl_map_free(map);
108
109         test_parse_map(ctx, "{[[s] -> A[i]] -> [[s+1] -> A[i]]}");
110         test_parse_map(ctx, "{ [p1, y1, y2] -> [2, y1, y2] : "
111                                 "p1 = 1 && (y1 <= y2 || y2 = 0) }");
112
113         str = "{ [x,y]  : [([x/2]+y)/3] >= 1 }";
114         str2 = "{ [x, y] : 2y >= 6 - x }";
115         if (test_parse_map_equal(ctx, str, str2) < 0)
116                 return -1;
117
118         if (test_parse_map_equal(ctx, "{ [x,y] : x <= min(y, 2*y+3) }",
119                                       "{ [x,y] : x <= y, 2*y + 3 }") < 0)
120                 return -1;
121         str = "{ [x, y] : (y <= x and y >= -3) or (2y <= -3 + x and y <= -4) }";
122         if (test_parse_map_equal(ctx, "{ [x,y] : x >= min(y, 2*y+3) }",
123                                         str) < 0)
124                 return -1;
125
126         str = "{[new,old] -> [new+1-2*[(new+1)/2],old+1-2*[(old+1)/2]]}";
127         map = isl_map_read_from_str(ctx, str);
128         str = "{ [new, old] -> [o0, o1] : "
129                "exists (e0 = [(-1 - new + o0)/2], e1 = [(-1 - old + o1)/2]: "
130                "2e0 = -1 - new + o0 and 2e1 = -1 - old + o1 and o0 >= 0 and "
131                "o0 <= 1 and o1 >= 0 and o1 <= 1) }";
132         map2 = isl_map_read_from_str(ctx, str);
133         assert(isl_map_is_equal(map, map2));
134         isl_map_free(map);
135         isl_map_free(map2);
136
137         str = "{[new,old] -> [new+1-2*[(new+1)/2],old+1-2*[(old+1)/2]]}";
138         map = isl_map_read_from_str(ctx, str);
139         str = "{[new,old] -> [(new+1)%2,(old+1)%2]}";
140         map2 = isl_map_read_from_str(ctx, str);
141         assert(isl_map_is_equal(map, map2));
142         isl_map_free(map);
143         isl_map_free(map2);
144
145         str = "[n] -> { [c1] : c1>=0 and c1<=floord(n-4,3) }";
146         str2 = "[n] -> { [c1] : c1 >= 0 and 3c1 <= -4 + n }";
147         if (test_parse_map_equal(ctx, str, str2) < 0)
148                 return -1;
149
150         str = "{ [i,j] -> [i] : i < j; [i,j] -> [j] : j <= i }";
151         str2 = "{ [i,j] -> [min(i,j)] }";
152         if (test_parse_map_equal(ctx, str, str2) < 0)
153                 return -1;
154
155         str = "{ [i,j] : i != j }";
156         str2 = "{ [i,j] : i < j or i > j }";
157         if (test_parse_map_equal(ctx, str, str2) < 0)
158                 return -1;
159
160         str = "{ [i,j] : (i+1)*2 >= j }";
161         str2 = "{ [i, j] : j <= 2 + 2i }";
162         if (test_parse_map_equal(ctx, str, str2) < 0)
163                 return -1;
164
165         str = "{ [i] -> [i > 0 ? 4 : 5] }";
166         str2 = "{ [i] -> [5] : i <= 0; [i] -> [4] : i >= 1 }";
167         if (test_parse_map_equal(ctx, str, str2) < 0)
168                 return -1;
169
170         str = "[N=2,M] -> { [i=[(M+N)/4]] }";
171         str2 = "[N, M] -> { [i] : N = 2 and 4i <= 2 + M and 4i >= -1 + M }";
172         if (test_parse_map_equal(ctx, str, str2) < 0)
173                 return -1;
174
175         str = "{ [x] : x >= 0 }";
176         str2 = "{ [x] : x-0 >= 0 }";
177         if (test_parse_map_equal(ctx, str, str2) < 0)
178                 return -1;
179
180         str = "{ [i] : ((i > 10)) }";
181         str2 = "{ [i] : i >= 11 }";
182         if (test_parse_map_equal(ctx, str, str2) < 0)
183                 return -1;
184
185         str = "{ [i] -> [0] }";
186         str2 = "{ [i] -> [0 * i] }";
187         if (test_parse_map_equal(ctx, str, str2) < 0)
188                 return -1;
189
190         test_parse_pwqp(ctx, "{ [i] -> i + [ (i + [i/3])/2 ] }");
191         test_parse_map(ctx, "{ S1[i] -> [([i/10]),i%10] : 0 <= i <= 45 }");
192         test_parse_pwaff(ctx, "{ [i] -> [i + 1] : i > 0; [a] -> [a] : a < 0 }");
193         test_parse_pwqp(ctx, "{ [x] -> ([(x)/2] * [(x)/3]) }");
194
195         if (test_parse_map_equal(ctx, "{ [a] -> [b] : (not false) }",
196                                       "{ [a] -> [b] : true }") < 0)
197                 return -1;
198
199         return 0;
200 }
201
202 void test_read(struct isl_ctx *ctx)
203 {
204         char *filename;
205         FILE *input;
206         struct isl_basic_set *bset1, *bset2;
207         const char *str = "{[y]: Exists ( alpha : 2alpha = y)}";
208
209         filename = get_filename(ctx, "set", "omega");
210         assert(filename);
211         input = fopen(filename, "r");
212         assert(input);
213
214         bset1 = isl_basic_set_read_from_file(ctx, input);
215         bset2 = isl_basic_set_read_from_str(ctx, str);
216
217         assert(isl_basic_set_is_equal(bset1, bset2) == 1);
218
219         isl_basic_set_free(bset1);
220         isl_basic_set_free(bset2);
221         free(filename);
222
223         fclose(input);
224 }
225
226 void test_bounded(struct isl_ctx *ctx)
227 {
228         isl_set *set;
229         int bounded;
230
231         set = isl_set_read_from_str(ctx, "[n] -> {[i] : 0 <= i <= n }");
232         bounded = isl_set_is_bounded(set);
233         assert(bounded);
234         isl_set_free(set);
235
236         set = isl_set_read_from_str(ctx, "{[n, i] : 0 <= i <= n }");
237         bounded = isl_set_is_bounded(set);
238         assert(!bounded);
239         isl_set_free(set);
240
241         set = isl_set_read_from_str(ctx, "[n] -> {[i] : i <= n }");
242         bounded = isl_set_is_bounded(set);
243         assert(!bounded);
244         isl_set_free(set);
245 }
246
247 /* Construct the basic set { [i] : 5 <= i <= N } */
248 void test_construction(struct isl_ctx *ctx)
249 {
250         isl_int v;
251         isl_space *dim;
252         isl_local_space *ls;
253         struct isl_basic_set *bset;
254         struct isl_constraint *c;
255
256         isl_int_init(v);
257
258         dim = isl_space_set_alloc(ctx, 1, 1);
259         bset = isl_basic_set_universe(isl_space_copy(dim));
260         ls = isl_local_space_from_space(dim);
261
262         c = isl_inequality_alloc(isl_local_space_copy(ls));
263         isl_int_set_si(v, -1);
264         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
265         isl_int_set_si(v, 1);
266         isl_constraint_set_coefficient(c, isl_dim_param, 0, v);
267         bset = isl_basic_set_add_constraint(bset, c);
268
269         c = isl_inequality_alloc(isl_local_space_copy(ls));
270         isl_int_set_si(v, 1);
271         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
272         isl_int_set_si(v, -5);
273         isl_constraint_set_constant(c, v);
274         bset = isl_basic_set_add_constraint(bset, c);
275
276         isl_local_space_free(ls);
277         isl_basic_set_free(bset);
278
279         isl_int_clear(v);
280 }
281
282 void test_dim(struct isl_ctx *ctx)
283 {
284         const char *str;
285         isl_map *map1, *map2;
286
287         map1 = isl_map_read_from_str(ctx,
288             "[n] -> { [i] -> [j] : exists (a = [i/10] : i - 10a <= n ) }");
289         map1 = isl_map_add_dims(map1, isl_dim_in, 1);
290         map2 = isl_map_read_from_str(ctx,
291             "[n] -> { [i,k] -> [j] : exists (a = [i/10] : i - 10a <= n ) }");
292         assert(isl_map_is_equal(map1, map2));
293         isl_map_free(map2);
294
295         map1 = isl_map_project_out(map1, isl_dim_in, 0, 1);
296         map2 = isl_map_read_from_str(ctx, "[n] -> { [i] -> [j] : n >= 0 }");
297         assert(isl_map_is_equal(map1, map2));
298
299         isl_map_free(map1);
300         isl_map_free(map2);
301
302         str = "[n] -> { [i] -> [] : exists a : 0 <= i <= n and i = 2 a }";
303         map1 = isl_map_read_from_str(ctx, str);
304         str = "{ [i] -> [j] : exists a : 0 <= i <= j and i = 2 a }";
305         map2 = isl_map_read_from_str(ctx, str);
306         map1 = isl_map_move_dims(map1, isl_dim_out, 0, isl_dim_param, 0, 1);
307         assert(isl_map_is_equal(map1, map2));
308
309         isl_map_free(map1);
310         isl_map_free(map2);
311 }
312
313 static int test_div(isl_ctx *ctx)
314 {
315         unsigned n;
316         const char *str;
317         int empty;
318         isl_int v;
319         isl_space *dim;
320         isl_set *set;
321         isl_local_space *ls;
322         struct isl_basic_set *bset;
323         struct isl_constraint *c;
324
325         isl_int_init(v);
326
327         /* test 1 */
328         dim = isl_space_set_alloc(ctx, 0, 3);
329         bset = isl_basic_set_universe(isl_space_copy(dim));
330         ls = isl_local_space_from_space(dim);
331
332         c = isl_equality_alloc(isl_local_space_copy(ls));
333         isl_int_set_si(v, -1);
334         isl_constraint_set_constant(c, v);
335         isl_int_set_si(v, 1);
336         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
337         isl_int_set_si(v, 3);
338         isl_constraint_set_coefficient(c, isl_dim_set, 1, v);
339         bset = isl_basic_set_add_constraint(bset, c);
340
341         c = isl_equality_alloc(isl_local_space_copy(ls));
342         isl_int_set_si(v, 1);
343         isl_constraint_set_constant(c, v);
344         isl_int_set_si(v, -1);
345         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
346         isl_int_set_si(v, 3);
347         isl_constraint_set_coefficient(c, isl_dim_set, 2, v);
348         bset = isl_basic_set_add_constraint(bset, c);
349
350         bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2);
351
352         assert(bset && bset->n_div == 1);
353         isl_local_space_free(ls);
354         isl_basic_set_free(bset);
355
356         /* test 2 */
357         dim = isl_space_set_alloc(ctx, 0, 3);
358         bset = isl_basic_set_universe(isl_space_copy(dim));
359         ls = isl_local_space_from_space(dim);
360
361         c = isl_equality_alloc(isl_local_space_copy(ls));
362         isl_int_set_si(v, 1);
363         isl_constraint_set_constant(c, v);
364         isl_int_set_si(v, -1);
365         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
366         isl_int_set_si(v, 3);
367         isl_constraint_set_coefficient(c, isl_dim_set, 1, v);
368         bset = isl_basic_set_add_constraint(bset, c);
369
370         c = isl_equality_alloc(isl_local_space_copy(ls));
371         isl_int_set_si(v, -1);
372         isl_constraint_set_constant(c, v);
373         isl_int_set_si(v, 1);
374         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
375         isl_int_set_si(v, 3);
376         isl_constraint_set_coefficient(c, isl_dim_set, 2, v);
377         bset = isl_basic_set_add_constraint(bset, c);
378
379         bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2);
380
381         assert(bset && bset->n_div == 1);
382         isl_local_space_free(ls);
383         isl_basic_set_free(bset);
384
385         /* test 3 */
386         dim = isl_space_set_alloc(ctx, 0, 3);
387         bset = isl_basic_set_universe(isl_space_copy(dim));
388         ls = isl_local_space_from_space(dim);
389
390         c = isl_equality_alloc(isl_local_space_copy(ls));
391         isl_int_set_si(v, 1);
392         isl_constraint_set_constant(c, v);
393         isl_int_set_si(v, -1);
394         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
395         isl_int_set_si(v, 3);
396         isl_constraint_set_coefficient(c, isl_dim_set, 1, v);
397         bset = isl_basic_set_add_constraint(bset, c);
398
399         c = isl_equality_alloc(isl_local_space_copy(ls));
400         isl_int_set_si(v, -3);
401         isl_constraint_set_constant(c, v);
402         isl_int_set_si(v, 1);
403         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
404         isl_int_set_si(v, 4);
405         isl_constraint_set_coefficient(c, isl_dim_set, 2, v);
406         bset = isl_basic_set_add_constraint(bset, c);
407
408         bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2);
409
410         assert(bset && bset->n_div == 1);
411         isl_local_space_free(ls);
412         isl_basic_set_free(bset);
413
414         /* test 4 */
415         dim = isl_space_set_alloc(ctx, 0, 3);
416         bset = isl_basic_set_universe(isl_space_copy(dim));
417         ls = isl_local_space_from_space(dim);
418
419         c = isl_equality_alloc(isl_local_space_copy(ls));
420         isl_int_set_si(v, 2);
421         isl_constraint_set_constant(c, v);
422         isl_int_set_si(v, -1);
423         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
424         isl_int_set_si(v, 3);
425         isl_constraint_set_coefficient(c, isl_dim_set, 1, v);
426         bset = isl_basic_set_add_constraint(bset, c);
427
428         c = isl_equality_alloc(isl_local_space_copy(ls));
429         isl_int_set_si(v, -1);
430         isl_constraint_set_constant(c, v);
431         isl_int_set_si(v, 1);
432         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
433         isl_int_set_si(v, 6);
434         isl_constraint_set_coefficient(c, isl_dim_set, 2, v);
435         bset = isl_basic_set_add_constraint(bset, c);
436
437         bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 2);
438
439         assert(isl_basic_set_is_empty(bset));
440         isl_local_space_free(ls);
441         isl_basic_set_free(bset);
442
443         /* test 5 */
444         dim = isl_space_set_alloc(ctx, 0, 3);
445         bset = isl_basic_set_universe(isl_space_copy(dim));
446         ls = isl_local_space_from_space(dim);
447
448         c = isl_equality_alloc(isl_local_space_copy(ls));
449         isl_int_set_si(v, -1);
450         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
451         isl_int_set_si(v, 3);
452         isl_constraint_set_coefficient(c, isl_dim_set, 2, v);
453         bset = isl_basic_set_add_constraint(bset, c);
454
455         c = isl_equality_alloc(isl_local_space_copy(ls));
456         isl_int_set_si(v, 1);
457         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
458         isl_int_set_si(v, -3);
459         isl_constraint_set_coefficient(c, isl_dim_set, 1, v);
460         bset = isl_basic_set_add_constraint(bset, c);
461
462         bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 1);
463
464         assert(bset && bset->n_div == 0);
465         isl_basic_set_free(bset);
466         isl_local_space_free(ls);
467
468         /* test 6 */
469         dim = isl_space_set_alloc(ctx, 0, 3);
470         bset = isl_basic_set_universe(isl_space_copy(dim));
471         ls = isl_local_space_from_space(dim);
472
473         c = isl_equality_alloc(isl_local_space_copy(ls));
474         isl_int_set_si(v, -1);
475         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
476         isl_int_set_si(v, 6);
477         isl_constraint_set_coefficient(c, isl_dim_set, 2, v);
478         bset = isl_basic_set_add_constraint(bset, c);
479
480         c = isl_equality_alloc(isl_local_space_copy(ls));
481         isl_int_set_si(v, 1);
482         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
483         isl_int_set_si(v, -3);
484         isl_constraint_set_coefficient(c, isl_dim_set, 1, v);
485         bset = isl_basic_set_add_constraint(bset, c);
486
487         bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 1);
488
489         assert(bset && bset->n_div == 1);
490         isl_basic_set_free(bset);
491         isl_local_space_free(ls);
492
493         /* test 7 */
494         /* This test is a bit tricky.  We set up an equality
495          *              a + 3b + 3c = 6 e0
496          * Normalization of divs creates _two_ divs
497          *              a = 3 e0
498          *              c - b - e0 = 2 e1
499          * Afterwards e0 is removed again because it has coefficient -1
500          * and we end up with the original equality and div again.
501          * Perhaps we can avoid the introduction of this temporary div.
502          */
503         dim = isl_space_set_alloc(ctx, 0, 4);
504         bset = isl_basic_set_universe(isl_space_copy(dim));
505         ls = isl_local_space_from_space(dim);
506
507         c = isl_equality_alloc(isl_local_space_copy(ls));
508         isl_int_set_si(v, -1);
509         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
510         isl_int_set_si(v, -3);
511         isl_constraint_set_coefficient(c, isl_dim_set, 1, v);
512         isl_int_set_si(v, -3);
513         isl_constraint_set_coefficient(c, isl_dim_set, 2, v);
514         isl_int_set_si(v, 6);
515         isl_constraint_set_coefficient(c, isl_dim_set, 3, v);
516         bset = isl_basic_set_add_constraint(bset, c);
517
518         bset = isl_basic_set_project_out(bset, isl_dim_set, 3, 1);
519
520         /* Test disabled for now */
521         /*
522         assert(bset && bset->n_div == 1);
523         */
524         isl_local_space_free(ls);
525         isl_basic_set_free(bset);
526
527         /* test 8 */
528         dim = isl_space_set_alloc(ctx, 0, 5);
529         bset = isl_basic_set_universe(isl_space_copy(dim));
530         ls = isl_local_space_from_space(dim);
531
532         c = isl_equality_alloc(isl_local_space_copy(ls));
533         isl_int_set_si(v, -1);
534         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
535         isl_int_set_si(v, -3);
536         isl_constraint_set_coefficient(c, isl_dim_set, 1, v);
537         isl_int_set_si(v, -3);
538         isl_constraint_set_coefficient(c, isl_dim_set, 3, v);
539         isl_int_set_si(v, 6);
540         isl_constraint_set_coefficient(c, isl_dim_set, 4, v);
541         bset = isl_basic_set_add_constraint(bset, c);
542
543         c = isl_equality_alloc(isl_local_space_copy(ls));
544         isl_int_set_si(v, -1);
545         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
546         isl_int_set_si(v, 1);
547         isl_constraint_set_coefficient(c, isl_dim_set, 2, v);
548         isl_int_set_si(v, 1);
549         isl_constraint_set_constant(c, v);
550         bset = isl_basic_set_add_constraint(bset, c);
551
552         bset = isl_basic_set_project_out(bset, isl_dim_set, 4, 1);
553
554         /* Test disabled for now */
555         /*
556         assert(bset && bset->n_div == 1);
557         */
558         isl_local_space_free(ls);
559         isl_basic_set_free(bset);
560
561         /* test 9 */
562         dim = isl_space_set_alloc(ctx, 0, 4);
563         bset = isl_basic_set_universe(isl_space_copy(dim));
564         ls = isl_local_space_from_space(dim);
565
566         c = isl_equality_alloc(isl_local_space_copy(ls));
567         isl_int_set_si(v, 1);
568         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
569         isl_int_set_si(v, -1);
570         isl_constraint_set_coefficient(c, isl_dim_set, 1, v);
571         isl_int_set_si(v, -2);
572         isl_constraint_set_coefficient(c, isl_dim_set, 2, v);
573         bset = isl_basic_set_add_constraint(bset, c);
574
575         c = isl_equality_alloc(isl_local_space_copy(ls));
576         isl_int_set_si(v, -1);
577         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
578         isl_int_set_si(v, 3);
579         isl_constraint_set_coefficient(c, isl_dim_set, 3, v);
580         isl_int_set_si(v, 2);
581         isl_constraint_set_constant(c, v);
582         bset = isl_basic_set_add_constraint(bset, c);
583
584         bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 2);
585
586         bset = isl_basic_set_fix_si(bset, isl_dim_set, 0, 2);
587
588         assert(!isl_basic_set_is_empty(bset));
589
590         isl_local_space_free(ls);
591         isl_basic_set_free(bset);
592
593         /* test 10 */
594         dim = isl_space_set_alloc(ctx, 0, 3);
595         bset = isl_basic_set_universe(isl_space_copy(dim));
596         ls = isl_local_space_from_space(dim);
597
598         c = isl_equality_alloc(isl_local_space_copy(ls));
599         isl_int_set_si(v, 1);
600         isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
601         isl_int_set_si(v, -2);
602         isl_constraint_set_coefficient(c, isl_dim_set, 2, v);
603         bset = isl_basic_set_add_constraint(bset, c);
604
605         bset = isl_basic_set_project_out(bset, isl_dim_set, 2, 1);
606
607         bset = isl_basic_set_fix_si(bset, isl_dim_set, 0, 2);
608
609         isl_local_space_free(ls);
610         isl_basic_set_free(bset);
611
612         isl_int_clear(v);
613
614         str = "{ [i] : exists (e0, e1: 3e1 >= 1 + 2e0 and "
615             "8e1 <= -1 + 5i - 5e0 and 2e1 >= 1 + 2i - 5e0) }";
616         set = isl_set_read_from_str(ctx, str);
617         set = isl_set_compute_divs(set);
618         isl_set_free(set);
619         if (!set)
620                 return -1;
621
622         str = "{ [i,j] : 2*[i/2] + 3 * [j/4] <= 10 and 2 i = j }";
623         bset = isl_basic_set_read_from_str(ctx, str);
624         n = isl_basic_set_dim(bset, isl_dim_div);
625         isl_basic_set_free(bset);
626         if (!bset)
627                 return -1;
628         if (n != 0)
629                 isl_die(ctx, isl_error_unknown,
630                         "expecting no existentials", return -1);
631
632         str = "{ [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }";
633         set = isl_set_read_from_str(ctx, str);
634         set = isl_set_remove_divs_involving_dims(set, isl_dim_set, 0, 2);
635         set = isl_set_fix_si(set, isl_dim_set, 2, -3);
636         empty = isl_set_is_empty(set);
637         isl_set_free(set);
638         if (empty < 0)
639                 return -1;
640         if (!empty)
641                 isl_die(ctx, isl_error_unknown,
642                         "result not as accurate as expected", return -1);
643
644         return 0;
645 }
646
647 void test_application_case(struct isl_ctx *ctx, const char *name)
648 {
649         char *filename;
650         FILE *input;
651         struct isl_basic_set *bset1, *bset2;
652         struct isl_basic_map *bmap;
653
654         filename = get_filename(ctx, name, "omega");
655         assert(filename);
656         input = fopen(filename, "r");
657         assert(input);
658
659         bset1 = isl_basic_set_read_from_file(ctx, input);
660         bmap = isl_basic_map_read_from_file(ctx, input);
661
662         bset1 = isl_basic_set_apply(bset1, bmap);
663
664         bset2 = isl_basic_set_read_from_file(ctx, input);
665
666         assert(isl_basic_set_is_equal(bset1, bset2) == 1);
667
668         isl_basic_set_free(bset1);
669         isl_basic_set_free(bset2);
670         free(filename);
671
672         fclose(input);
673 }
674
675 void test_application(struct isl_ctx *ctx)
676 {
677         test_application_case(ctx, "application");
678         test_application_case(ctx, "application2");
679 }
680
681 void test_affine_hull_case(struct isl_ctx *ctx, const char *name)
682 {
683         char *filename;
684         FILE *input;
685         struct isl_basic_set *bset1, *bset2;
686
687         filename = get_filename(ctx, name, "polylib");
688         assert(filename);
689         input = fopen(filename, "r");
690         assert(input);
691
692         bset1 = isl_basic_set_read_from_file(ctx, input);
693         bset2 = isl_basic_set_read_from_file(ctx, input);
694
695         bset1 = isl_basic_set_affine_hull(bset1);
696
697         assert(isl_basic_set_is_equal(bset1, bset2) == 1);
698
699         isl_basic_set_free(bset1);
700         isl_basic_set_free(bset2);
701         free(filename);
702
703         fclose(input);
704 }
705
706 int test_affine_hull(struct isl_ctx *ctx)
707 {
708         const char *str;
709         isl_set *set;
710         isl_basic_set *bset;
711         int n;
712
713         test_affine_hull_case(ctx, "affine2");
714         test_affine_hull_case(ctx, "affine");
715         test_affine_hull_case(ctx, "affine3");
716
717         str = "[m] -> { [i0] : exists (e0, e1: e1 <= 1 + i0 and "
718                         "m >= 3 and 4i0 <= 2 + m and e1 >= i0 and "
719                         "e1 >= 0 and e1 <= 2 and e1 >= 1 + 2e0 and "
720                         "2e1 <= 1 + m + 4e0 and 2e1 >= 2 - m + 4i0 - 4e0) }";
721         set = isl_set_read_from_str(ctx, str);
722         bset = isl_set_affine_hull(set);
723         n = isl_basic_set_dim(bset, isl_dim_div);
724         isl_basic_set_free(bset);
725         if (n != 0)
726                 isl_die(ctx, isl_error_unknown, "not expecting any divs",
727                         return -1);
728
729         return 0;
730 }
731
732 void test_convex_hull_case(struct isl_ctx *ctx, const char *name)
733 {
734         char *filename;
735         FILE *input;
736         struct isl_basic_set *bset1, *bset2;
737         struct isl_set *set;
738
739         filename = get_filename(ctx, name, "polylib");
740         assert(filename);
741         input = fopen(filename, "r");
742         assert(input);
743
744         bset1 = isl_basic_set_read_from_file(ctx, input);
745         bset2 = isl_basic_set_read_from_file(ctx, input);
746
747         set = isl_basic_set_union(bset1, bset2);
748         bset1 = isl_set_convex_hull(set);
749
750         bset2 = isl_basic_set_read_from_file(ctx, input);
751
752         assert(isl_basic_set_is_equal(bset1, bset2) == 1);
753
754         isl_basic_set_free(bset1);
755         isl_basic_set_free(bset2);
756         free(filename);
757
758         fclose(input);
759 }
760
761 void test_convex_hull_algo(struct isl_ctx *ctx, int convex)
762 {
763         const char *str1, *str2;
764         isl_set *set1, *set2;
765         int orig_convex = ctx->opt->convex;
766         ctx->opt->convex = convex;
767
768         test_convex_hull_case(ctx, "convex0");
769         test_convex_hull_case(ctx, "convex1");
770         test_convex_hull_case(ctx, "convex2");
771         test_convex_hull_case(ctx, "convex3");
772         test_convex_hull_case(ctx, "convex4");
773         test_convex_hull_case(ctx, "convex5");
774         test_convex_hull_case(ctx, "convex6");
775         test_convex_hull_case(ctx, "convex7");
776         test_convex_hull_case(ctx, "convex8");
777         test_convex_hull_case(ctx, "convex9");
778         test_convex_hull_case(ctx, "convex10");
779         test_convex_hull_case(ctx, "convex11");
780         test_convex_hull_case(ctx, "convex12");
781         test_convex_hull_case(ctx, "convex13");
782         test_convex_hull_case(ctx, "convex14");
783         test_convex_hull_case(ctx, "convex15");
784
785         str1 = "{ [i0, i1, i2] : (i2 = 1 and i0 = 0 and i1 >= 0) or "
786                "(i0 = 1 and i1 = 0 and i2 = 1) or "
787                "(i0 = 0 and i1 = 0 and i2 = 0) }";
788         str2 = "{ [i0, i1, i2] : i0 >= 0 and i2 >= i0 and i2 <= 1 and i1 >= 0 }";
789         set1 = isl_set_read_from_str(ctx, str1);
790         set2 = isl_set_read_from_str(ctx, str2);
791         set1 = isl_set_from_basic_set(isl_set_convex_hull(set1));
792         assert(isl_set_is_equal(set1, set2));
793         isl_set_free(set1);
794         isl_set_free(set2);
795
796         ctx->opt->convex = orig_convex;
797 }
798
799 void test_convex_hull(struct isl_ctx *ctx)
800 {
801         test_convex_hull_algo(ctx, ISL_CONVEX_HULL_FM);
802         test_convex_hull_algo(ctx, ISL_CONVEX_HULL_WRAP);
803 }
804
805 void test_gist_case(struct isl_ctx *ctx, const char *name)
806 {
807         char *filename;
808         FILE *input;
809         struct isl_basic_set *bset1, *bset2;
810
811         filename = get_filename(ctx, name, "polylib");
812         assert(filename);
813         input = fopen(filename, "r");
814         assert(input);
815
816         bset1 = isl_basic_set_read_from_file(ctx, input);
817         bset2 = isl_basic_set_read_from_file(ctx, input);
818
819         bset1 = isl_basic_set_gist(bset1, bset2);
820
821         bset2 = isl_basic_set_read_from_file(ctx, input);
822
823         assert(isl_basic_set_is_equal(bset1, bset2) == 1);
824
825         isl_basic_set_free(bset1);
826         isl_basic_set_free(bset2);
827         free(filename);
828
829         fclose(input);
830 }
831
832 void test_gist(struct isl_ctx *ctx)
833 {
834         const char *str;
835         isl_basic_set *bset1, *bset2;
836
837         test_gist_case(ctx, "gist1");
838
839         str = "[p0, p2, p3, p5, p6, p10] -> { [] : "
840             "exists (e0 = [(15 + p0 + 15p6 + 15p10)/16], e1 = [(p5)/8], "
841             "e2 = [(p6)/128], e3 = [(8p2 - p5)/128], "
842             "e4 = [(128p3 - p6)/4096]: 8e1 = p5 and 128e2 = p6 and "
843             "128e3 = 8p2 - p5 and 4096e4 = 128p3 - p6 and p2 >= 0 and "
844             "16e0 >= 16 + 16p6 + 15p10 and  p2 <= 15 and p3 >= 0 and "
845             "p3 <= 31 and  p6 >= 128p3 and p5 >= 8p2 and p10 >= 0 and "
846             "16e0 <= 15 + p0 + 15p6 + 15p10 and 16e0 >= p0 + 15p6 + 15p10 and "
847             "p10 <= 15 and p10 <= -1 + p0 - p6) }";
848         bset1 = isl_basic_set_read_from_str(ctx, str);
849         str = "[p0, p2, p3, p5, p6, p10] -> { [] : exists (e0 = [(p5)/8], "
850             "e1 = [(p6)/128], e2 = [(8p2 - p5)/128], "
851             "e3 = [(128p3 - p6)/4096]: 8e0 = p5 and 128e1 = p6 and "
852             "128e2 = 8p2 - p5 and 4096e3 = 128p3 - p6 and p5 >= -7 and "
853             "p2 >= 0 and 8p2 <= -1 + p0 and p2 <= 15 and p3 >= 0 and "
854             "p3 <= 31 and 128p3 <= -1 + p0 and p6 >= -127 and "
855             "p5 <= -1 + p0 and p6 <= -1 + p0 and p6 >= 128p3 and "
856             "p0 >= 1 and p5 >= 8p2 and p10 >= 0 and p10 <= 15 ) }";
857         bset2 = isl_basic_set_read_from_str(ctx, str);
858         bset1 = isl_basic_set_gist(bset1, bset2);
859         assert(bset1 && bset1->n_div == 0);
860         isl_basic_set_free(bset1);
861 }
862
863 int test_coalesce_set(isl_ctx *ctx, const char *str, int check_one)
864 {
865         isl_set *set, *set2;
866         int equal;
867         int one;
868
869         set = isl_set_read_from_str(ctx, str);
870         set = isl_set_coalesce(set);
871         set2 = isl_set_read_from_str(ctx, str);
872         equal = isl_set_is_equal(set, set2);
873         one = set && set->n == 1;
874         isl_set_free(set);
875         isl_set_free(set2);
876
877         if (equal < 0)
878                 return -1;
879         if (!equal)
880                 isl_die(ctx, isl_error_unknown,
881                         "coalesced set not equal to input", return -1);
882         if (check_one && !one)
883                 isl_die(ctx, isl_error_unknown,
884                         "coalesced set should not be a union", return -1);
885
886         return 0;
887 }
888
889 int test_coalesce_unbounded_wrapping(isl_ctx *ctx)
890 {
891         int r = 0;
892         int bounded;
893
894         bounded = isl_options_get_coalesce_bounded_wrapping(ctx);
895         isl_options_set_coalesce_bounded_wrapping(ctx, 0);
896
897         if (test_coalesce_set(ctx,
898                 "{[x,y,z] : y + 2 >= 0 and x - y + 1 >= 0 and "
899                         "-x - y + 1 >= 0 and -3 <= z <= 3;"
900                 "[x,y,z] : -x+z + 20 >= 0 and -x-z + 20 >= 0 and "
901                         "x-z + 20 >= 0 and x+z + 20 >= 0 and "
902                         "-10 <= y <= 0}", 1) < 0)
903                 goto error;
904         if (test_coalesce_set(ctx,
905                 "{[x,y] : 0 <= x,y <= 10; [5,y]: 4 <=y <= 11}", 1) < 0)
906                 goto error;
907         if (test_coalesce_set(ctx,
908                 "{[x,0,0] : -5 <= x <= 5; [0,y,1] : -5 <= y <= 5 }", 1) < 0)
909                 goto error;
910
911         if (0) {
912 error:
913                 r = -1;
914         }
915
916         isl_options_set_coalesce_bounded_wrapping(ctx, bounded);
917
918         return r;
919 }
920
921 int test_coalesce(struct isl_ctx *ctx)
922 {
923         const char *str;
924         struct isl_set *set, *set2;
925         struct isl_map *map, *map2;
926
927         set = isl_set_read_from_str(ctx,
928                 "{[x,y]: x >= 0 & x <= 10 & y >= 0 & y <= 10 or "
929                        "y >= x & x >= 2 & 5 >= y }");
930         set = isl_set_coalesce(set);
931         assert(set && set->n == 1);
932         isl_set_free(set);
933
934         set = isl_set_read_from_str(ctx,
935                 "{[x,y]: y >= 0 & 2x + y <= 30 & y <= 10 & x >= 0 or "
936                        "x + y >= 10 & y <= x & x + y <= 20 & y >= 0}");
937         set = isl_set_coalesce(set);
938         assert(set && set->n == 1);
939         isl_set_free(set);
940
941         set = isl_set_read_from_str(ctx,
942                 "{[x,y]: y >= 0 & 2x + y <= 30 & y <= 10 & x >= 0 or "
943                        "x + y >= 10 & y <= x & x + y <= 19 & y >= 0}");
944         set = isl_set_coalesce(set);
945         assert(set && set->n == 2);
946         isl_set_free(set);
947
948         set = isl_set_read_from_str(ctx,
949                 "{[x,y]: y >= 0 & x <= 5 & y <= x or "
950                        "y >= 0 & x >= 6 & x <= 10 & y <= x}");
951         set = isl_set_coalesce(set);
952         assert(set && set->n == 1);
953         isl_set_free(set);
954
955         set = isl_set_read_from_str(ctx,
956                 "{[x,y]: y >= 0 & x <= 5 & y <= x or "
957                        "y >= 0 & x >= 7 & x <= 10 & y <= x}");
958         set = isl_set_coalesce(set);
959         assert(set && set->n == 2);
960         isl_set_free(set);
961
962         set = isl_set_read_from_str(ctx,
963                 "{[x,y]: y >= 0 & x <= 5 & y <= x or "
964                        "y >= 0 & x >= 6 & x <= 10 & y + 1 <= x}");
965         set = isl_set_coalesce(set);
966         assert(set && set->n == 2);
967         isl_set_free(set);
968
969         set = isl_set_read_from_str(ctx,
970                 "{[x,y]: y >= 0 & x <= 5 & y <= x or "
971                        "y >= 0 & x = 6 & y <= 6}");
972         set = isl_set_coalesce(set);
973         assert(set && set->n == 1);
974         isl_set_free(set);
975
976         set = isl_set_read_from_str(ctx,
977                 "{[x,y]: y >= 0 & x <= 5 & y <= x or "
978                        "y >= 0 & x = 7 & y <= 6}");
979         set = isl_set_coalesce(set);
980         assert(set && set->n == 2);
981         isl_set_free(set);
982
983         set = isl_set_read_from_str(ctx,
984                 "{[x,y]: y >= 0 & x <= 5 & y <= x or "
985                        "y >= 0 & x = 6 & y <= 5}");
986         set = isl_set_coalesce(set);
987         assert(set && set->n == 1);
988         set2 = isl_set_read_from_str(ctx,
989                 "{[x,y]: y >= 0 & x <= 5 & y <= x or "
990                        "y >= 0 & x = 6 & y <= 5}");
991         assert(isl_set_is_equal(set, set2));
992         isl_set_free(set);
993         isl_set_free(set2);
994
995         set = isl_set_read_from_str(ctx,
996                 "{[x,y]: y >= 0 & x <= 5 & y <= x or "
997                        "y >= 0 & x = 6 & y <= 7}");
998         set = isl_set_coalesce(set);
999         assert(set && set->n == 2);
1000         isl_set_free(set);
1001
1002         set = isl_set_read_from_str(ctx,
1003                 "[n] -> { [i] : i = 1 and n >= 2 or 2 <= i and i <= n }");
1004         set = isl_set_coalesce(set);
1005         assert(set && set->n == 1);
1006         set2 = isl_set_read_from_str(ctx,
1007                 "[n] -> { [i] : i = 1 and n >= 2 or 2 <= i and i <= n }");
1008         assert(isl_set_is_equal(set, set2));
1009         isl_set_free(set);
1010         isl_set_free(set2);
1011
1012         set = isl_set_read_from_str(ctx,
1013                 "{[x,y] : x >= 0 and y >= 0 or 0 <= y and y <= 5 and x = -1}");
1014         set = isl_set_coalesce(set);
1015         set2 = isl_set_read_from_str(ctx,
1016                 "{[x,y] : x >= 0 and y >= 0 or 0 <= y and y <= 5 and x = -1}");
1017         assert(isl_set_is_equal(set, set2));
1018         isl_set_free(set);
1019         isl_set_free(set2);
1020
1021         set = isl_set_read_from_str(ctx,
1022                 "[n] -> { [i] : 1 <= i and i <= n - 1 or "
1023                                 "2 <= i and i <= n }");
1024         set = isl_set_coalesce(set);
1025         assert(set && set->n == 1);
1026         set2 = isl_set_read_from_str(ctx,
1027                 "[n] -> { [i] : 1 <= i and i <= n - 1 or "
1028                                 "2 <= i and i <= n }");
1029         assert(isl_set_is_equal(set, set2));
1030         isl_set_free(set);
1031         isl_set_free(set2);
1032
1033         map = isl_map_read_from_str(ctx,
1034                 "[n] -> { [i0] -> [o0] : exists (e0 = [(i0)/4], e1 = [(o0)/4], "
1035                 "e2 = [(n)/2], e3 = [(-2 + i0)/4], e4 = [(-2 + o0)/4], "
1036                 "e5 = [(-2n + i0)/4]: 2e2 = n and 4e3 = -2 + i0 and "
1037                 "4e4 = -2 + o0 and i0 >= 8 + 2n and o0 >= 2 + i0 and "
1038                 "o0 <= 56 + 2n and o0 <= -12 + 4n and i0 <= 57 + 2n and "
1039                 "i0 <= -11 + 4n and o0 >= 6 + 2n and 4e0 <= i0 and "
1040                 "4e0 >= -3 + i0 and 4e1 <= o0 and 4e1 >= -3 + o0 and "
1041                 "4e5 <= -2n + i0 and 4e5 >= -3 - 2n + i0);"
1042                 "[i0] -> [o0] : exists (e0 = [(i0)/4], e1 = [(o0)/4], "
1043                 "e2 = [(n)/2], e3 = [(-2 + i0)/4], e4 = [(-2 + o0)/4], "
1044                 "e5 = [(-2n + i0)/4]: 2e2 = n and 4e3 = -2 + i0 and "
1045                 "4e4 = -2 + o0 and 2e0 >= 3 + n and e0 <= -4 + n and "
1046                 "2e0 <= 27 + n and e1 <= -4 + n and 2e1 <= 27 + n and "
1047                 "2e1 >= 2 + n and e1 >= 1 + e0 and i0 >= 7 + 2n and "
1048                 "i0 <= -11 + 4n and i0 <= 57 + 2n and 4e0 <= -2 + i0 and "
1049                 "4e0 >= -3 + i0 and o0 >= 6 + 2n and o0 <= -11 + 4n and "
1050                 "o0 <= 57 + 2n and 4e1 <= -2 + o0 and 4e1 >= -3 + o0 and "
1051                 "4e5 <= -2n + i0 and 4e5 >= -3 - 2n + i0 ) }");
1052         map = isl_map_coalesce(map);
1053         map2 = isl_map_read_from_str(ctx,
1054                 "[n] -> { [i0] -> [o0] : exists (e0 = [(i0)/4], e1 = [(o0)/4], "
1055                 "e2 = [(n)/2], e3 = [(-2 + i0)/4], e4 = [(-2 + o0)/4], "
1056                 "e5 = [(-2n + i0)/4]: 2e2 = n and 4e3 = -2 + i0 and "
1057                 "4e4 = -2 + o0 and i0 >= 8 + 2n and o0 >= 2 + i0 and "
1058                 "o0 <= 56 + 2n and o0 <= -12 + 4n and i0 <= 57 + 2n and "
1059                 "i0 <= -11 + 4n and o0 >= 6 + 2n and 4e0 <= i0 and "
1060                 "4e0 >= -3 + i0 and 4e1 <= o0 and 4e1 >= -3 + o0 and "
1061                 "4e5 <= -2n + i0 and 4e5 >= -3 - 2n + i0);"
1062                 "[i0] -> [o0] : exists (e0 = [(i0)/4], e1 = [(o0)/4], "
1063                 "e2 = [(n)/2], e3 = [(-2 + i0)/4], e4 = [(-2 + o0)/4], "
1064                 "e5 = [(-2n + i0)/4]: 2e2 = n and 4e3 = -2 + i0 and "
1065                 "4e4 = -2 + o0 and 2e0 >= 3 + n and e0 <= -4 + n and "
1066                 "2e0 <= 27 + n and e1 <= -4 + n and 2e1 <= 27 + n and "
1067                 "2e1 >= 2 + n and e1 >= 1 + e0 and i0 >= 7 + 2n and "
1068                 "i0 <= -11 + 4n and i0 <= 57 + 2n and 4e0 <= -2 + i0 and "
1069                 "4e0 >= -3 + i0 and o0 >= 6 + 2n and o0 <= -11 + 4n and "
1070                 "o0 <= 57 + 2n and 4e1 <= -2 + o0 and 4e1 >= -3 + o0 and "
1071                 "4e5 <= -2n + i0 and 4e5 >= -3 - 2n + i0 ) }");
1072         assert(isl_map_is_equal(map, map2));
1073         isl_map_free(map);
1074         isl_map_free(map2);
1075
1076         str = "[n, m] -> { [] -> [o0, o2, o3] : (o3 = 1 and o0 >= 1 + m and "
1077               "o0 <= n + m and o2 <= m and o0 >= 2 + n and o2 >= 3) or "
1078               "(o0 >= 2 + n and o0 >= 1 + m and o0 <= n + m and n >= 1 and "
1079               "o3 <= -1 + o2 and o3 >= 1 - m + o2 and o3 >= 2 and o3 <= n) }";
1080         map = isl_map_read_from_str(ctx, str);
1081         map = isl_map_coalesce(map);
1082         map2 = isl_map_read_from_str(ctx, str);
1083         assert(isl_map_is_equal(map, map2));
1084         isl_map_free(map);
1085         isl_map_free(map2);
1086
1087         str = "[M, N] -> { [i0, i1, i2, i3, i4, i5, i6] -> "
1088           "[o0, o1, o2, o3, o4, o5, o6] : "
1089           "(o6 <= -4 + 2M - 2N + i0 + i1 - i2 + i6 - o0 - o1 + o2 and "
1090           "o3 <= -2 + i3 and o6 >= 2 + i0 + i3 + i6 - o0 - o3 and "
1091           "o6 >= 2 - M + N + i3 + i4 + i6 - o3 - o4 and o0 <= -1 + i0 and "
1092           "o4 >= 4 - 3M + 3N - i0 - i1 + i2 + 2i3 + i4 + o0 + o1 - o2 - 2o3 "
1093           "and o6 <= -3 + 2M - 2N + i3 + i4 - i5 + i6 - o3 - o4 + o5 and "
1094           "2o6 <= -5 + 5M - 5N + 2i0 + i1 - i2 - i5 + 2i6 - 2o0 - o1 + o2 + o5 "
1095           "and o6 >= 2i0 + i1 + i6 - 2o0 - o1 and "
1096           "3o6 <= -5 + 4M - 4N + 2i0 + i1 - i2 + 2i3 + i4 - i5 + 3i6 "
1097           "- 2o0 - o1 + o2 - 2o3 - o4 + o5) or "
1098           "(N >= 2 and o3 <= -1 + i3 and o0 <= -1 + i0 and "
1099           "o6 >= i3 + i6 - o3 and M >= 0 and "
1100           "2o6 >= 1 + i0 + i3 + 2i6 - o0 - o3 and "
1101           "o6 >= 1 - M + i0 + i6 - o0 and N >= 2M and o6 >= i0 + i6 - o0) }";
1102         map = isl_map_read_from_str(ctx, str);
1103         map = isl_map_coalesce(map);
1104         map2 = isl_map_read_from_str(ctx, str);
1105         assert(isl_map_is_equal(map, map2));
1106         isl_map_free(map);
1107         isl_map_free(map2);
1108
1109         str = "[M, N] -> { [] -> [o0] : (o0 = 0 and M >= 1 and N >= 2) or "
1110                 "(o0 = 0 and M >= 1 and N >= 2M and N >= 2 + M) or "
1111                 "(o0 = 0 and M >= 2 and N >= 3) or "
1112                 "(M = 0 and o0 = 0 and N >= 3) }";
1113         map = isl_map_read_from_str(ctx, str);
1114         map = isl_map_coalesce(map);
1115         map2 = isl_map_read_from_str(ctx, str);
1116         assert(isl_map_is_equal(map, map2));
1117         isl_map_free(map);
1118         isl_map_free(map2);
1119
1120         str = "{ [i0, i1, i2, i3] : (i1 = 10i0 and i0 >= 1 and 10i0 <= 100 and "
1121                 "i3 <= 9 + 10 i2 and i3 >= 1 + 10i2 and i3 >= 0) or "
1122                 "(i1 <= 9 + 10i0 and i1 >= 1 + 10i0 and i2 >= 0 and "
1123                 "i0 >= 0 and i1 <= 100 and i3 <= 9 + 10i2 and i3 >= 1 + 10i2) }";
1124         map = isl_map_read_from_str(ctx, str);
1125         map = isl_map_coalesce(map);
1126         map2 = isl_map_read_from_str(ctx, str);
1127         assert(isl_map_is_equal(map, map2));
1128         isl_map_free(map);
1129         isl_map_free(map2);
1130
1131         test_coalesce_set(ctx,
1132                 "[M] -> { [i1] : (i1 >= 2 and i1 <= M) or "
1133                                 "(i1 = M and M >= 1) }", 0);
1134         test_coalesce_set(ctx,
1135                 "{[x,y] : x,y >= 0; [x,y] : 10 <= x <= 20 and y >= -1 }", 0);
1136         test_coalesce_set(ctx,
1137                 "{ [x, y] : (x >= 1 and y >= 1 and x <= 2 and y <= 2) or "
1138                 "(y = 3 and x = 1) }", 1);
1139         test_coalesce_set(ctx,
1140                 "[M] -> { [i0, i1, i2, i3, i4] : (i1 >= 3 and i4 >= 2 + i2 and "
1141                 "i2 >= 2 and i0 >= 2 and i3 >= 1 + i2 and i0 <= M and "
1142                 "i1 <= M and i3 <= M and i4 <= M) or "
1143                 "(i1 >= 2 and i4 >= 1 + i2 and i2 >= 2 and i0 >= 2 and "
1144                 "i3 >= 1 + i2 and i0 <= M and i1 <= -1 + M and i3 <= M and "
1145                 "i4 <= -1 + M) }", 1);
1146         test_coalesce_set(ctx,
1147                 "{ [x, y] : (x >= 0 and y >= 0 and x <= 10 and y <= 10) or "
1148                 "(x >= 1 and y >= 1 and x <= 11 and y <= 11) }", 1);
1149         if (test_coalesce_unbounded_wrapping(ctx) < 0)
1150                 return -1;
1151         if (test_coalesce_set(ctx, "{[x,0] : x >= 0; [x,1] : x <= 20}", 0) < 0)
1152                 return -1;
1153         if (test_coalesce_set(ctx, "{ [x, 1 - x] : 0 <= x <= 1; [0,0] }", 1) < 0)
1154                 return -1;
1155         if (test_coalesce_set(ctx, "{ [0,0]; [i,i] : 1 <= i <= 10 }", 1) < 0)
1156                 return -1;
1157         if (test_coalesce_set(ctx, "{ [0,0]; [i,j] : 1 <= i,j <= 10 }", 0) < 0)
1158                 return -1;
1159         if (test_coalesce_set(ctx, "{ [0,0]; [i,2i] : 1 <= i <= 10 }", 1) < 0)
1160                 return -1;
1161         if (test_coalesce_set(ctx, "{ [0,0]; [i,2i] : 2 <= i <= 10 }", 0) < 0)
1162                 return -1;
1163         if (test_coalesce_set(ctx, "{ [1,0]; [i,2i] : 1 <= i <= 10 }", 0) < 0)
1164                 return -1;
1165         if (test_coalesce_set(ctx, "{ [0,1]; [i,2i] : 1 <= i <= 10 }", 0) < 0)
1166                 return -1;
1167         if (test_coalesce_set(ctx, "{ [a, b] : exists e : 2e = a and "
1168                     "a >= 0 and (a <= 3 or (b <= 0 and b >= -4 + a)) }", 0) < 0)
1169                 return -1;
1170         if (test_coalesce_set(ctx,
1171                 "{ [i, j, i', j'] : i <= 2 and j <= 2 and "
1172                         "j' >= -1 + 2i + j - 2i' and i' <= -1 + i and "
1173                         "j >= 1 and j' <= i + j - i' and i >= 1; "
1174                 "[1, 1, 1, 1] }", 0) < 0)
1175                 return -1;
1176         if (test_coalesce_set(ctx, "{ [i,j] : exists a,b : i = 2a and j = 3b; "
1177                                      "[i,j] : exists a : j = 3a }", 1) < 0)
1178                 return -1;
1179         return 0;
1180 }
1181
1182 void test_closure(struct isl_ctx *ctx)
1183 {
1184         const char *str;
1185         isl_set *dom;
1186         isl_map *up, *right;
1187         isl_map *map, *map2;
1188         int exact;
1189
1190         /* COCOA example 1 */
1191         map = isl_map_read_from_str(ctx,
1192                 "[n] -> { [i,j] -> [i2,j2] : i2 = i + 1 and j2 = j + 1 and "
1193                         "1 <= i and i < n and 1 <= j and j < n or "
1194                         "i2 = i + 1 and j2 = j - 1 and "
1195                         "1 <= i and i < n and 2 <= j and j <= n }");
1196         map = isl_map_power(map, &exact);
1197         assert(exact);
1198         isl_map_free(map);
1199
1200         /* COCOA example 1 */
1201         map = isl_map_read_from_str(ctx,
1202                 "[n] -> { [i,j] -> [i2,j2] : i2 = i + 1 and j2 = j + 1 and "
1203                         "1 <= i and i < n and 1 <= j and j < n or "
1204                         "i2 = i + 1 and j2 = j - 1 and "
1205                         "1 <= i and i < n and 2 <= j and j <= n }");
1206         map = isl_map_transitive_closure(map, &exact);
1207         assert(exact);
1208         map2 = isl_map_read_from_str(ctx,
1209                 "[n] -> { [i,j] -> [i2,j2] : exists (k1,k2,k : "
1210                         "1 <= i and i < n and 1 <= j and j <= n and "
1211                         "2 <= i2 and i2 <= n and 1 <= j2 and j2 <= n and "
1212                         "i2 = i + k1 + k2 and j2 = j + k1 - k2 and "
1213                         "k1 >= 0 and k2 >= 0 and k1 + k2 = k and k >= 1 )}");
1214         assert(isl_map_is_equal(map, map2));
1215         isl_map_free(map2);
1216         isl_map_free(map);
1217
1218         map = isl_map_read_from_str(ctx,
1219                 "[n] -> { [x] -> [y] : y = x + 1 and 0 <= x and x <= n and "
1220                                      " 0 <= y and y <= n }");
1221         map = isl_map_transitive_closure(map, &exact);
1222         map2 = isl_map_read_from_str(ctx,
1223                 "[n] -> { [x] -> [y] : y > x and 0 <= x and x <= n and "
1224                                      " 0 <= y and y <= n }");
1225         assert(isl_map_is_equal(map, map2));
1226         isl_map_free(map2);
1227         isl_map_free(map);
1228
1229         /* COCOA example 2 */
1230         map = isl_map_read_from_str(ctx,
1231                 "[n] -> { [i,j] -> [i2,j2] : i2 = i + 2 and j2 = j + 2 and "
1232                         "1 <= i and i < n - 1 and 1 <= j and j < n - 1 or "
1233                         "i2 = i + 2 and j2 = j - 2 and "
1234                         "1 <= i and i < n - 1 and 3 <= j and j <= n }");
1235         map = isl_map_transitive_closure(map, &exact);
1236         assert(exact);
1237         map2 = isl_map_read_from_str(ctx,
1238                 "[n] -> { [i,j] -> [i2,j2] : exists (k1,k2,k : "
1239                         "1 <= i and i < n - 1 and 1 <= j and j <= n and "
1240                         "3 <= i2 and i2 <= n and 1 <= j2 and j2 <= n and "
1241                         "i2 = i + 2 k1 + 2 k2 and j2 = j + 2 k1 - 2 k2 and "
1242                         "k1 >= 0 and k2 >= 0 and k1 + k2 = k and k >= 1) }");
1243         assert(isl_map_is_equal(map, map2));
1244         isl_map_free(map);
1245         isl_map_free(map2);
1246
1247         /* COCOA Fig.2 left */
1248         map = isl_map_read_from_str(ctx,
1249                 "[n] -> { [i,j] -> [i2,j2] : i2 = i + 2 and j2 = j and "
1250                         "i <= 2 j - 3 and i <= n - 2 and j <= 2 i - 1 and "
1251                         "j <= n or "
1252                         "i2 = i and j2 = j + 2 and i <= 2 j - 1 and i <= n and "
1253                         "j <= 2 i - 3 and j <= n - 2 or "
1254                         "i2 = i + 1 and j2 = j + 1 and i <= 2 j - 1 and "
1255                         "i <= n - 1 and j <= 2 i - 1 and j <= n - 1 }");
1256         map = isl_map_transitive_closure(map, &exact);
1257         assert(exact);
1258         isl_map_free(map);
1259
1260         /* COCOA Fig.2 right */
1261         map = isl_map_read_from_str(ctx,
1262                 "[n] -> { [i,j] -> [i2,j2] : i2 = i + 3 and j2 = j and "
1263                         "i <= 2 j - 4 and i <= n - 3 and j <= 2 i - 1 and "
1264                         "j <= n or "
1265                         "i2 = i and j2 = j + 3 and i <= 2 j - 1 and i <= n and "
1266                         "j <= 2 i - 4 and j <= n - 3 or "
1267                         "i2 = i + 1 and j2 = j + 1 and i <= 2 j - 1 and "
1268                         "i <= n - 1 and j <= 2 i - 1 and j <= n - 1 }");
1269         map = isl_map_power(map, &exact);
1270         assert(exact);
1271         isl_map_free(map);
1272
1273         /* COCOA Fig.2 right */
1274         map = isl_map_read_from_str(ctx,
1275                 "[n] -> { [i,j] -> [i2,j2] : i2 = i + 3 and j2 = j and "
1276                         "i <= 2 j - 4 and i <= n - 3 and j <= 2 i - 1 and "
1277                         "j <= n or "
1278                         "i2 = i and j2 = j + 3 and i <= 2 j - 1 and i <= n and "
1279                         "j <= 2 i - 4 and j <= n - 3 or "
1280                         "i2 = i + 1 and j2 = j + 1 and i <= 2 j - 1 and "
1281                         "i <= n - 1 and j <= 2 i - 1 and j <= n - 1 }");
1282         map = isl_map_transitive_closure(map, &exact);
1283         assert(exact);
1284         map2 = isl_map_read_from_str(ctx,
1285                 "[n] -> { [i,j] -> [i2,j2] : exists (k1,k2,k3,k : "
1286                         "i <= 2 j - 1 and i <= n and j <= 2 i - 1 and "
1287                         "j <= n and 3 + i + 2 j <= 3 n and "
1288                         "3 + 2 i + j <= 3n and i2 <= 2 j2 -1 and i2 <= n and "
1289                         "i2 <= 3 j2 - 4 and j2 <= 2 i2 -1 and j2 <= n and "
1290                         "13 + 4 j2 <= 11 i2 and i2 = i + 3 k1 + k3 and "
1291                         "j2 = j + 3 k2 + k3 and k1 >= 0 and k2 >= 0 and "
1292                         "k3 >= 0 and k1 + k2 + k3 = k and k > 0) }");
1293         assert(isl_map_is_equal(map, map2));
1294         isl_map_free(map2);
1295         isl_map_free(map);
1296
1297         /* COCOA Fig.1 right */
1298         dom = isl_set_read_from_str(ctx,
1299                 "{ [x,y] : x >= 0 and -2 x + 3 y >= 0 and x <= 3 and "
1300                         "2 x - 3 y + 3 >= 0 }");
1301         right = isl_map_read_from_str(ctx,
1302                 "{ [x,y] -> [x2,y2] : x2 = x + 1 and y2 = y }");
1303         up = isl_map_read_from_str(ctx,
1304                 "{ [x,y] -> [x2,y2] : x2 = x and y2 = y + 1 }");
1305         right = isl_map_intersect_domain(right, isl_set_copy(dom));
1306         right = isl_map_intersect_range(right, isl_set_copy(dom));
1307         up = isl_map_intersect_domain(up, isl_set_copy(dom));
1308         up = isl_map_intersect_range(up, dom);
1309         map = isl_map_union(up, right);
1310         map = isl_map_transitive_closure(map, &exact);
1311         assert(exact);
1312         map2 = isl_map_read_from_str(ctx,
1313                 "{ [0,0] -> [0,1]; [0,0] -> [1,1]; [0,1] -> [1,1]; "
1314                 "  [2,2] -> [3,2]; [2,2] -> [3,3]; [3,2] -> [3,3] }");
1315         assert(isl_map_is_equal(map, map2));
1316         isl_map_free(map2);
1317         isl_map_free(map);
1318
1319         /* COCOA Theorem 1 counter example */
1320         map = isl_map_read_from_str(ctx,
1321                 "{ [i,j] -> [i2,j2] : i = 0 and 0 <= j and j <= 1 and "
1322                         "i2 = 1 and j2 = j or "
1323                         "i = 0 and j = 0 and i2 = 0 and j2 = 1 }");
1324         map = isl_map_transitive_closure(map, &exact);
1325         assert(exact);
1326         isl_map_free(map);
1327
1328         map = isl_map_read_from_str(ctx,
1329                 "[m,n] -> { [i,j] -> [i2,j2] : i2 = i and j2 = j + 2 and "
1330                         "1 <= i,i2 <= n and 1 <= j,j2 <= m or "
1331                         "i2 = i + 1 and 3 <= j2 - j <= 4 and "
1332                         "1 <= i,i2 <= n and 1 <= j,j2 <= m }");
1333         map = isl_map_transitive_closure(map, &exact);
1334         assert(exact);
1335         isl_map_free(map);
1336
1337         /* Kelly et al 1996, fig 12 */
1338         map = isl_map_read_from_str(ctx,
1339                 "[n] -> { [i,j] -> [i2,j2] : i2 = i and j2 = j + 1 and "
1340                         "1 <= i,j,j+1 <= n or "
1341                         "j = n and j2 = 1 and i2 = i + 1 and "
1342                         "1 <= i,i+1 <= n }");
1343         map = isl_map_transitive_closure(map, &exact);
1344         assert(exact);
1345         map2 = isl_map_read_from_str(ctx,
1346                 "[n] -> { [i,j] -> [i2,j2] : 1 <= j < j2 <= n and "
1347                         "1 <= i <= n and i = i2 or "
1348                         "1 <= i < i2 <= n and 1 <= j <= n and "
1349                         "1 <= j2 <= n }");
1350         assert(isl_map_is_equal(map, map2));
1351         isl_map_free(map2);
1352         isl_map_free(map);
1353
1354         /* Omega's closure4 */
1355         map = isl_map_read_from_str(ctx,
1356                 "[m,n] -> { [x,y] -> [x2,y2] : x2 = x and y2 = y + 1 and "
1357                         "1 <= x,y <= 10 or "
1358                         "x2 = x + 1 and y2 = y and "
1359                         "1 <= x <= 20 && 5 <= y <= 15 }");
1360         map = isl_map_transitive_closure(map, &exact);
1361         assert(exact);
1362         isl_map_free(map);
1363
1364         map = isl_map_read_from_str(ctx,
1365                 "[n] -> { [x] -> [y]: 1 <= n <= y - x <= 10 }");
1366         map = isl_map_transitive_closure(map, &exact);
1367         assert(!exact);
1368         map2 = isl_map_read_from_str(ctx,
1369                 "[n] -> { [x] -> [y] : 1 <= n <= 10 and y >= n + x }");
1370         assert(isl_map_is_equal(map, map2));
1371         isl_map_free(map);
1372         isl_map_free(map2);
1373
1374         str = "[n, m] -> { [i0, i1, i2, i3] -> [o0, o1, o2, o3] : "
1375             "i3 = 1 and o0 = i0 and o1 = -1 + i1 and o2 = -1 + i2 and "
1376             "o3 = -2 + i2 and i1 <= -1 + i0 and i1 >= 1 - m + i0 and "
1377             "i1 >= 2 and i1 <= n and i2 >= 3 and i2 <= 1 + n and i2 <= m }";
1378         map = isl_map_read_from_str(ctx, str);
1379         map = isl_map_transitive_closure(map, &exact);
1380         assert(exact);
1381         map2 = isl_map_read_from_str(ctx, str);
1382         assert(isl_map_is_equal(map, map2));
1383         isl_map_free(map);
1384         isl_map_free(map2);
1385
1386         str = "{[0] -> [1]; [2] -> [3]}";
1387         map = isl_map_read_from_str(ctx, str);
1388         map = isl_map_transitive_closure(map, &exact);
1389         assert(exact);
1390         map2 = isl_map_read_from_str(ctx, str);
1391         assert(isl_map_is_equal(map, map2));
1392         isl_map_free(map);
1393         isl_map_free(map2);
1394
1395         str = "[n] -> { [[i0, i1, 1, 0, i0] -> [i5, 1]] -> "
1396             "[[i0, -1 + i1, 2, 0, i0] -> [-1 + i5, 2]] : "
1397             "exists (e0 = [(3 - n)/3]: i5 >= 2 and i1 >= 2 and "
1398             "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and "
1399             "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n); "
1400             "[[i0, i1, 2, 0, i0] -> [i5, 1]] -> "
1401             "[[i0, i1, 1, 0, i0] -> [-1 + i5, 2]] : "
1402             "exists (e0 = [(3 - n)/3]: i5 >= 2 and i1 >= 1 and "
1403             "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and "
1404             "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n); "
1405             "[[i0, i1, 1, 0, i0] -> [i5, 2]] -> "
1406             "[[i0, -1 + i1, 2, 0, i0] -> [i5, 1]] : "
1407             "exists (e0 = [(3 - n)/3]: i1 >= 2 and i5 >= 1 and "
1408             "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and "
1409             "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n); "
1410             "[[i0, i1, 2, 0, i0] -> [i5, 2]] -> "
1411             "[[i0, i1, 1, 0, i0] -> [i5, 1]] : "
1412             "exists (e0 = [(3 - n)/3]: i5 >= 1 and i1 >= 1 and "
1413             "3i0 <= -1 + n and i1 <= -1 + n and i5 <= -1 + n and "
1414             "3e0 >= 1 - n and 3e0 <= 2 - n and 3i0 >= -2 + n) }";
1415         map = isl_map_read_from_str(ctx, str);
1416         map = isl_map_transitive_closure(map, NULL);
1417         assert(map);
1418         isl_map_free(map);
1419 }
1420
1421 void test_lex(struct isl_ctx *ctx)
1422 {
1423         isl_space *dim;
1424         isl_map *map;
1425
1426         dim = isl_space_set_alloc(ctx, 0, 0);
1427         map = isl_map_lex_le(dim);
1428         assert(!isl_map_is_empty(map));
1429         isl_map_free(map);
1430 }
1431
1432 void test_lexmin(struct isl_ctx *ctx)
1433 {
1434         const char *str;
1435         isl_basic_map *bmap;
1436         isl_map *map, *map2;
1437         isl_set *set;
1438         isl_set *set2;
1439         isl_pw_multi_aff *pma;
1440
1441         str = "[p0, p1] -> { [] -> [] : "
1442             "exists (e0 = [(2p1)/3], e1, e2, e3 = [(3 - p1 + 3e0)/3], "
1443             "e4 = [(p1)/3], e5 = [(p1 + 3e4)/3]: "
1444             "3e0 >= -2 + 2p1 and 3e0 >= p1 and 3e3 >= 1 - p1 + 3e0 and "
1445             "3e0 <= 2p1 and 3e3 >= -2 + p1 and 3e3 <= -1 + p1 and p1 >= 3 and "
1446             "3e5 >= -2 + 2p1 and 3e5 >= p1 and 3e5 <= -1 + p1 + 3e4 and "
1447             "3e4 <= p1 and 3e4 >= -2 + p1 and e3 <= -1 + e0 and "
1448             "3e4 >= 6 - p1 + 3e1 and 3e1 >= p1 and 3e5 >= -2 + p1 + 3e4 and "
1449             "2e4 >= 3 - p1 + 2e1 and e4 <= e1 and 3e3 <= 2 - p1 + 3e0 and "
1450             "e5 >= 1 + e1 and 3e4 >= 6 - 2p1 + 3e1 and "
1451             "p0 >= 2 and p1 >= p0 and 3e2 >= p1 and 3e4 >= 6 - p1 + 3e2 and "
1452             "e2 <= e1 and e3 >= 1 and e4 <= e2) }";
1453         map = isl_map_read_from_str(ctx, str);
1454         map = isl_map_lexmin(map);
1455         isl_map_free(map);
1456
1457         str = "[C] -> { [obj,a,b,c] : obj <= 38 a + 7 b + 10 c and "
1458             "a + b <= 1 and c <= 10 b and c <= C and a,b,c,C >= 0 }";
1459         set = isl_set_read_from_str(ctx, str);
1460         set = isl_set_lexmax(set);
1461         str = "[C] -> { [obj,a,b,c] : C = 8 }";
1462         set2 = isl_set_read_from_str(ctx, str);
1463         set = isl_set_intersect(set, set2);
1464         assert(!isl_set_is_empty(set));
1465         isl_set_free(set);
1466
1467         str = "{ [x] -> [y] : x <= y <= 10; [x] -> [5] : -8 <= x <= 8 }";
1468         map = isl_map_read_from_str(ctx, str);
1469         map = isl_map_lexmin(map);
1470         str = "{ [x] -> [5] : 6 <= x <= 8; "
1471                 "[x] -> [x] : x <= 5 or (9 <= x <= 10) }";
1472         map2 = isl_map_read_from_str(ctx, str);
1473         assert(isl_map_is_equal(map, map2));
1474         isl_map_free(map);
1475         isl_map_free(map2);
1476
1477         str = "{ [x] -> [y] : 4y = x or 4y = -1 + x or 4y = -2 + x }";
1478         map = isl_map_read_from_str(ctx, str);
1479         map2 = isl_map_copy(map);
1480         map = isl_map_lexmin(map);
1481         assert(isl_map_is_equal(map, map2));
1482         isl_map_free(map);
1483         isl_map_free(map2);
1484
1485         str = "{ [x] -> [y] : x = 4y; [x] -> [y] : x = 2y }";
1486         map = isl_map_read_from_str(ctx, str);
1487         map = isl_map_lexmin(map);
1488         str = "{ [x] -> [y] : (4y = x and x >= 0) or "
1489                 "(exists (e0 = [(x)/4], e1 = [(-2 + x)/4]: 2y = x and "
1490                 "4e1 = -2 + x and 4e0 <= -1 + x and 4e0 >= -3 + x)) or "
1491                 "(exists (e0 = [(x)/4]: 2y = x and 4e0 = x and x <= -4)) }";
1492         map2 = isl_map_read_from_str(ctx, str);
1493         assert(isl_map_is_equal(map, map2));
1494         isl_map_free(map);
1495         isl_map_free(map2);
1496
1497         str = "{ [i] -> [i', j] : j = i - 8i' and i' >= 0 and i' <= 7 and "
1498                                 " 8i' <= i and 8i' >= -7 + i }";
1499         bmap = isl_basic_map_read_from_str(ctx, str);
1500         pma = isl_basic_map_lexmin_pw_multi_aff(isl_basic_map_copy(bmap));
1501         map2 = isl_map_from_pw_multi_aff(pma);
1502         map = isl_map_from_basic_map(bmap);
1503         assert(isl_map_is_equal(map, map2));
1504         isl_map_free(map);
1505         isl_map_free(map2);
1506
1507         str = "{ T[a] -> S[b, c] : a = 4b-2c and c >= b }";
1508         map = isl_map_read_from_str(ctx, str);
1509         map = isl_map_lexmin(map);
1510         str = "{ T[a] -> S[b, c] : 2b = a and 2c = a }";
1511         map2 = isl_map_read_from_str(ctx, str);
1512         assert(isl_map_is_equal(map, map2));
1513         isl_map_free(map);
1514         isl_map_free(map2);
1515 }
1516
1517 struct must_may {
1518         isl_map *must;
1519         isl_map *may;
1520 };
1521
1522 static int collect_must_may(__isl_take isl_map *dep, int must,
1523         void *dep_user, void *user)
1524 {
1525         struct must_may *mm = (struct must_may *)user;
1526
1527         if (must)
1528                 mm->must = isl_map_union(mm->must, dep);
1529         else
1530                 mm->may = isl_map_union(mm->may, dep);
1531
1532         return 0;
1533 }
1534
1535 static int common_space(void *first, void *second)
1536 {
1537         int depth = *(int *)first;
1538         return 2 * depth;
1539 }
1540
1541 static int map_is_equal(__isl_keep isl_map *map, const char *str)
1542 {
1543         isl_map *map2;
1544         int equal;
1545
1546         if (!map)
1547                 return -1;
1548
1549         map2 = isl_map_read_from_str(map->ctx, str);
1550         equal = isl_map_is_equal(map, map2);
1551         isl_map_free(map2);
1552
1553         return equal;
1554 }
1555
1556 static int map_check_equal(__isl_keep isl_map *map, const char *str)
1557 {
1558         int equal;
1559
1560         equal = map_is_equal(map, str);
1561         if (equal < 0)
1562                 return -1;
1563         if (!equal)
1564                 isl_die(isl_map_get_ctx(map), isl_error_unknown,
1565                         "result not as expected", return -1);
1566         return 0;
1567 }
1568
1569 void test_dep(struct isl_ctx *ctx)
1570 {
1571         const char *str;
1572         isl_space *dim;
1573         isl_map *map;
1574         isl_access_info *ai;
1575         isl_flow *flow;
1576         int depth;
1577         struct must_may mm;
1578
1579         depth = 3;
1580
1581         str = "{ [2,i,0] -> [i] : 0 <= i <= 10 }";
1582         map = isl_map_read_from_str(ctx, str);
1583         ai = isl_access_info_alloc(map, &depth, &common_space, 2);
1584
1585         str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }";
1586         map = isl_map_read_from_str(ctx, str);
1587         ai = isl_access_info_add_source(ai, map, 1, &depth);
1588
1589         str = "{ [1,i,0] -> [5] : 0 <= i <= 10 }";
1590         map = isl_map_read_from_str(ctx, str);
1591         ai = isl_access_info_add_source(ai, map, 1, &depth);
1592
1593         flow = isl_access_info_compute_flow(ai);
1594         dim = isl_space_alloc(ctx, 0, 3, 3);
1595         mm.must = isl_map_empty(isl_space_copy(dim));
1596         mm.may = isl_map_empty(dim);
1597
1598         isl_flow_foreach(flow, collect_must_may, &mm);
1599
1600         str = "{ [0,i,0] -> [2,i,0] : (0 <= i <= 4) or (6 <= i <= 10); "
1601               "  [1,10,0] -> [2,5,0] }";
1602         assert(map_is_equal(mm.must, str));
1603         str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }";
1604         assert(map_is_equal(mm.may, str));
1605
1606         isl_map_free(mm.must);
1607         isl_map_free(mm.may);
1608         isl_flow_free(flow);
1609
1610
1611         str = "{ [2,i,0] -> [i] : 0 <= i <= 10 }";
1612         map = isl_map_read_from_str(ctx, str);
1613         ai = isl_access_info_alloc(map, &depth, &common_space, 2);
1614
1615         str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }";
1616         map = isl_map_read_from_str(ctx, str);
1617         ai = isl_access_info_add_source(ai, map, 1, &depth);
1618
1619         str = "{ [1,i,0] -> [5] : 0 <= i <= 10 }";
1620         map = isl_map_read_from_str(ctx, str);
1621         ai = isl_access_info_add_source(ai, map, 0, &depth);
1622
1623         flow = isl_access_info_compute_flow(ai);
1624         dim = isl_space_alloc(ctx, 0, 3, 3);
1625         mm.must = isl_map_empty(isl_space_copy(dim));
1626         mm.may = isl_map_empty(dim);
1627
1628         isl_flow_foreach(flow, collect_must_may, &mm);
1629
1630         str = "{ [0,i,0] -> [2,i,0] : (0 <= i <= 4) or (6 <= i <= 10) }";
1631         assert(map_is_equal(mm.must, str));
1632         str = "{ [0,5,0] -> [2,5,0]; [1,i,0] -> [2,5,0] : 0 <= i <= 10 }";
1633         assert(map_is_equal(mm.may, str));
1634
1635         isl_map_free(mm.must);
1636         isl_map_free(mm.may);
1637         isl_flow_free(flow);
1638
1639
1640         str = "{ [2,i,0] -> [i] : 0 <= i <= 10 }";
1641         map = isl_map_read_from_str(ctx, str);
1642         ai = isl_access_info_alloc(map, &depth, &common_space, 2);
1643
1644         str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }";
1645         map = isl_map_read_from_str(ctx, str);
1646         ai = isl_access_info_add_source(ai, map, 0, &depth);
1647
1648         str = "{ [1,i,0] -> [5] : 0 <= i <= 10 }";
1649         map = isl_map_read_from_str(ctx, str);
1650         ai = isl_access_info_add_source(ai, map, 0, &depth);
1651
1652         flow = isl_access_info_compute_flow(ai);
1653         dim = isl_space_alloc(ctx, 0, 3, 3);
1654         mm.must = isl_map_empty(isl_space_copy(dim));
1655         mm.may = isl_map_empty(dim);
1656
1657         isl_flow_foreach(flow, collect_must_may, &mm);
1658
1659         str = "{ [0,i,0] -> [2,i,0] : 0 <= i <= 10; "
1660               "  [1,i,0] -> [2,5,0] : 0 <= i <= 10 }";
1661         assert(map_is_equal(mm.may, str));
1662         str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }";
1663         assert(map_is_equal(mm.must, str));
1664
1665         isl_map_free(mm.must);
1666         isl_map_free(mm.may);
1667         isl_flow_free(flow);
1668
1669
1670         str = "{ [0,i,2] -> [i] : 0 <= i <= 10 }";
1671         map = isl_map_read_from_str(ctx, str);
1672         ai = isl_access_info_alloc(map, &depth, &common_space, 2);
1673
1674         str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }";
1675         map = isl_map_read_from_str(ctx, str);
1676         ai = isl_access_info_add_source(ai, map, 0, &depth);
1677
1678         str = "{ [0,i,1] -> [5] : 0 <= i <= 10 }";
1679         map = isl_map_read_from_str(ctx, str);
1680         ai = isl_access_info_add_source(ai, map, 0, &depth);
1681
1682         flow = isl_access_info_compute_flow(ai);
1683         dim = isl_space_alloc(ctx, 0, 3, 3);
1684         mm.must = isl_map_empty(isl_space_copy(dim));
1685         mm.may = isl_map_empty(dim);
1686
1687         isl_flow_foreach(flow, collect_must_may, &mm);
1688
1689         str = "{ [0,i,0] -> [0,i,2] : 0 <= i <= 10; "
1690               "  [0,i,1] -> [0,5,2] : 0 <= i <= 5 }";
1691         assert(map_is_equal(mm.may, str));
1692         str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }";
1693         assert(map_is_equal(mm.must, str));
1694
1695         isl_map_free(mm.must);
1696         isl_map_free(mm.may);
1697         isl_flow_free(flow);
1698
1699
1700         str = "{ [0,i,1] -> [i] : 0 <= i <= 10 }";
1701         map = isl_map_read_from_str(ctx, str);
1702         ai = isl_access_info_alloc(map, &depth, &common_space, 2);
1703
1704         str = "{ [0,i,0] -> [i] : 0 <= i <= 10 }";
1705         map = isl_map_read_from_str(ctx, str);
1706         ai = isl_access_info_add_source(ai, map, 0, &depth);
1707
1708         str = "{ [0,i,2] -> [5] : 0 <= i <= 10 }";
1709         map = isl_map_read_from_str(ctx, str);
1710         ai = isl_access_info_add_source(ai, map, 0, &depth);
1711
1712         flow = isl_access_info_compute_flow(ai);
1713         dim = isl_space_alloc(ctx, 0, 3, 3);
1714         mm.must = isl_map_empty(isl_space_copy(dim));
1715         mm.may = isl_map_empty(dim);
1716
1717         isl_flow_foreach(flow, collect_must_may, &mm);
1718
1719         str = "{ [0,i,0] -> [0,i,1] : 0 <= i <= 10; "
1720               "  [0,i,2] -> [0,5,1] : 0 <= i <= 4 }";
1721         assert(map_is_equal(mm.may, str));
1722         str = "{ [i,j,k] -> [l,m,n] : 1 = 0 }";
1723         assert(map_is_equal(mm.must, str));
1724
1725         isl_map_free(mm.must);
1726         isl_map_free(mm.may);
1727         isl_flow_free(flow);
1728
1729
1730         depth = 5;
1731
1732         str = "{ [1,i,0,0,0] -> [i,j] : 0 <= i <= 10 and 0 <= j <= 10 }";
1733         map = isl_map_read_from_str(ctx, str);
1734         ai = isl_access_info_alloc(map, &depth, &common_space, 1);
1735
1736         str = "{ [0,i,0,j,0] -> [i,j] : 0 <= i <= 10 and 0 <= j <= 10 }";
1737         map = isl_map_read_from_str(ctx, str);
1738         ai = isl_access_info_add_source(ai, map, 1, &depth);
1739
1740         flow = isl_access_info_compute_flow(ai);
1741         dim = isl_space_alloc(ctx, 0, 5, 5);
1742         mm.must = isl_map_empty(isl_space_copy(dim));
1743         mm.may = isl_map_empty(dim);
1744
1745         isl_flow_foreach(flow, collect_must_may, &mm);
1746
1747         str = "{ [0,i,0,j,0] -> [1,i,0,0,0] : 0 <= i,j <= 10 }";
1748         assert(map_is_equal(mm.must, str));
1749         str = "{ [0,0,0,0,0] -> [0,0,0,0,0] : 1 = 0 }";
1750         assert(map_is_equal(mm.may, str));
1751
1752         isl_map_free(mm.must);
1753         isl_map_free(mm.may);
1754         isl_flow_free(flow);
1755 }
1756
1757 int test_sv(isl_ctx *ctx)
1758 {
1759         const char *str;
1760         isl_map *map;
1761         isl_union_map *umap;
1762         int sv;
1763
1764         str = "[N] -> { [i] -> [f] : 0 <= i <= N and 0 <= i - 10 f <= 9 }";
1765         map = isl_map_read_from_str(ctx, str);
1766         sv = isl_map_is_single_valued(map);
1767         isl_map_free(map);
1768         if (sv < 0)
1769                 return -1;
1770         if (!sv)
1771                 isl_die(ctx, isl_error_internal,
1772                         "map not detected as single valued", return -1);
1773
1774         str = "[N] -> { [i] -> [f] : 0 <= i <= N and 0 <= i - 10 f <= 10 }";
1775         map = isl_map_read_from_str(ctx, str);
1776         sv = isl_map_is_single_valued(map);
1777         isl_map_free(map);
1778         if (sv < 0)
1779                 return -1;
1780         if (sv)
1781                 isl_die(ctx, isl_error_internal,
1782                         "map detected as single valued", return -1);
1783
1784         str = "{ S1[i] -> [i] : 0 <= i <= 9; S2[i] -> [i] : 0 <= i <= 9 }";
1785         umap = isl_union_map_read_from_str(ctx, str);
1786         sv = isl_union_map_is_single_valued(umap);
1787         isl_union_map_free(umap);
1788         if (sv < 0)
1789                 return -1;
1790         if (!sv)
1791                 isl_die(ctx, isl_error_internal,
1792                         "map not detected as single valued", return -1);
1793
1794         str = "{ [i] -> S1[i] : 0 <= i <= 9; [i] -> S2[i] : 0 <= i <= 9 }";
1795         umap = isl_union_map_read_from_str(ctx, str);
1796         sv = isl_union_map_is_single_valued(umap);
1797         isl_union_map_free(umap);
1798         if (sv < 0)
1799                 return -1;
1800         if (sv)
1801                 isl_die(ctx, isl_error_internal,
1802                         "map detected as single valued", return -1);
1803
1804         return 0;
1805 }
1806
1807 void test_bijective_case(struct isl_ctx *ctx, const char *str, int bijective)
1808 {
1809         isl_map *map;
1810
1811         map = isl_map_read_from_str(ctx, str);
1812         if (bijective)
1813                 assert(isl_map_is_bijective(map));
1814         else
1815                 assert(!isl_map_is_bijective(map));
1816         isl_map_free(map);
1817 }
1818
1819 void test_bijective(struct isl_ctx *ctx)
1820 {
1821         test_bijective_case(ctx, "[N,M]->{[i,j] -> [i]}", 0);
1822         test_bijective_case(ctx, "[N,M]->{[i,j] -> [i] : j=i}", 1);
1823         test_bijective_case(ctx, "[N,M]->{[i,j] -> [i] : j=0}", 1);
1824         test_bijective_case(ctx, "[N,M]->{[i,j] -> [i] : j=N}", 1);
1825         test_bijective_case(ctx, "[N,M]->{[i,j] -> [j,i]}", 1);
1826         test_bijective_case(ctx, "[N,M]->{[i,j] -> [i+j]}", 0);
1827         test_bijective_case(ctx, "[N,M]->{[i,j] -> []}", 0);
1828         test_bijective_case(ctx, "[N,M]->{[i,j] -> [i,j,N]}", 1);
1829         test_bijective_case(ctx, "[N,M]->{[i,j] -> [2i]}", 0);
1830         test_bijective_case(ctx, "[N,M]->{[i,j] -> [i,i]}", 0);
1831         test_bijective_case(ctx, "[N,M]->{[i,j] -> [2i,i]}", 0);
1832         test_bijective_case(ctx, "[N,M]->{[i,j] -> [2i,j]}", 1);
1833         test_bijective_case(ctx, "[N,M]->{[i,j] -> [x,y] : 2x=i & y =j}", 1);
1834 }
1835
1836 void test_pwqp(struct isl_ctx *ctx)
1837 {
1838         const char *str;
1839         isl_set *set;
1840         isl_pw_qpolynomial *pwqp1, *pwqp2;
1841
1842         str = "{ [i,j,k] -> 1 + 9 * [i/5] + 7 * [j/11] + 4 * [k/13] }";
1843         pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str);
1844
1845         pwqp1 = isl_pw_qpolynomial_move_dims(pwqp1, isl_dim_param, 0,
1846                                                 isl_dim_in, 1, 1);
1847
1848         str = "[j] -> { [i,k] -> 1 + 9 * [i/5] + 7 * [j/11] + 4 * [k/13] }";
1849         pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str);
1850
1851         pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2);
1852
1853         assert(isl_pw_qpolynomial_is_zero(pwqp1));
1854
1855         isl_pw_qpolynomial_free(pwqp1);
1856
1857         str = "{ [i] -> i }";
1858         pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str);
1859         str = "{ [k] : exists a : k = 2a }";
1860         set = isl_set_read_from_str(ctx, str);
1861         pwqp1 = isl_pw_qpolynomial_gist(pwqp1, set);
1862         str = "{ [i] -> i }";
1863         pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str);
1864
1865         pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2);
1866
1867         assert(isl_pw_qpolynomial_is_zero(pwqp1));
1868
1869         isl_pw_qpolynomial_free(pwqp1);
1870
1871         str = "{ [i] -> i + [ (i + [i/3])/2 ] }";
1872         pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str);
1873         str = "{ [10] }";
1874         set = isl_set_read_from_str(ctx, str);
1875         pwqp1 = isl_pw_qpolynomial_gist(pwqp1, set);
1876         str = "{ [i] -> 16 }";
1877         pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str);
1878
1879         pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2);
1880
1881         assert(isl_pw_qpolynomial_is_zero(pwqp1));
1882
1883         isl_pw_qpolynomial_free(pwqp1);
1884
1885         str = "{ [i] -> ([(i)/2]) }";
1886         pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str);
1887         str = "{ [k] : exists a : k = 2a+1 }";
1888         set = isl_set_read_from_str(ctx, str);
1889         pwqp1 = isl_pw_qpolynomial_gist(pwqp1, set);
1890         str = "{ [i] -> -1/2 + 1/2 * i }";
1891         pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str);
1892
1893         pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2);
1894
1895         assert(isl_pw_qpolynomial_is_zero(pwqp1));
1896
1897         isl_pw_qpolynomial_free(pwqp1);
1898
1899         str = "{ [i] -> ([([i/2] + [i/2])/5]) }";
1900         pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str);
1901         str = "{ [i] -> ([(2 * [i/2])/5]) }";
1902         pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str);
1903
1904         pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2);
1905
1906         assert(isl_pw_qpolynomial_is_zero(pwqp1));
1907
1908         isl_pw_qpolynomial_free(pwqp1);
1909
1910         str = "{ [x] -> ([x/2] + [(x+1)/2]) }";
1911         pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str);
1912         str = "{ [x] -> x }";
1913         pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str);
1914
1915         pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2);
1916
1917         assert(isl_pw_qpolynomial_is_zero(pwqp1));
1918
1919         isl_pw_qpolynomial_free(pwqp1);
1920
1921         str = "{ [i] -> ([i/2]) : i >= 0; [i] -> ([i/3]) : i < 0 }";
1922         pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str);
1923         pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str);
1924         pwqp1 = isl_pw_qpolynomial_coalesce(pwqp1);
1925         pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2);
1926         assert(isl_pw_qpolynomial_is_zero(pwqp1));
1927         isl_pw_qpolynomial_free(pwqp1);
1928 }
1929
1930 void test_split_periods(isl_ctx *ctx)
1931 {
1932         const char *str;
1933         isl_pw_qpolynomial *pwqp;
1934
1935         str = "{ [U,V] -> 1/3 * U + 2/3 * V - [(U + 2V)/3] + [U/2] : "
1936                 "U + 2V + 3 >= 0 and - U -2V  >= 0 and - U + 10 >= 0 and "
1937                 "U  >= 0; [U,V] -> U^2 : U >= 100 }";
1938         pwqp = isl_pw_qpolynomial_read_from_str(ctx, str);
1939
1940         pwqp = isl_pw_qpolynomial_split_periods(pwqp, 2);
1941         assert(pwqp);
1942
1943         isl_pw_qpolynomial_free(pwqp);
1944 }
1945
1946 void test_union(isl_ctx *ctx)
1947 {
1948         const char *str;
1949         isl_union_set *uset1, *uset2;
1950         isl_union_map *umap1, *umap2;
1951
1952         str = "{ [i] : 0 <= i <= 1 }";
1953         uset1 = isl_union_set_read_from_str(ctx, str);
1954         str = "{ [1] -> [0] }";
1955         umap1 = isl_union_map_read_from_str(ctx, str);
1956
1957         umap2 = isl_union_set_lex_gt_union_set(isl_union_set_copy(uset1), uset1);
1958         assert(isl_union_map_is_equal(umap1, umap2));
1959
1960         isl_union_map_free(umap1);
1961         isl_union_map_free(umap2);
1962
1963         str = "{ A[i] -> B[i]; B[i] -> C[i]; A[0] -> C[1] }";
1964         umap1 = isl_union_map_read_from_str(ctx, str);
1965         str = "{ A[i]; B[i] }";
1966         uset1 = isl_union_set_read_from_str(ctx, str);
1967
1968         uset2 = isl_union_map_domain(umap1);
1969
1970         assert(isl_union_set_is_equal(uset1, uset2));
1971
1972         isl_union_set_free(uset1);
1973         isl_union_set_free(uset2);
1974 }
1975
1976 void test_bound(isl_ctx *ctx)
1977 {
1978         const char *str;
1979         isl_pw_qpolynomial *pwqp;
1980         isl_pw_qpolynomial_fold *pwf;
1981
1982         str = "{ [[a, b, c, d] -> [e]] -> 0 }";
1983         pwqp = isl_pw_qpolynomial_read_from_str(ctx, str);
1984         pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL);
1985         assert(isl_pw_qpolynomial_fold_dim(pwf, isl_dim_in) == 4);
1986         isl_pw_qpolynomial_fold_free(pwf);
1987
1988         str = "{ [[x]->[x]] -> 1 : exists a : x = 2 a }";
1989         pwqp = isl_pw_qpolynomial_read_from_str(ctx, str);
1990         pwf = isl_pw_qpolynomial_bound(pwqp, isl_fold_max, NULL);
1991         assert(isl_pw_qpolynomial_fold_dim(pwf, isl_dim_in) == 1);
1992         isl_pw_qpolynomial_fold_free(pwf);
1993 }
1994
1995 void test_lift(isl_ctx *ctx)
1996 {
1997         const char *str;
1998         isl_basic_map *bmap;
1999         isl_basic_set *bset;
2000
2001         str = "{ [i0] : exists e0 : i0 = 4e0 }";
2002         bset = isl_basic_set_read_from_str(ctx, str);
2003         bset = isl_basic_set_lift(bset);
2004         bmap = isl_basic_map_from_range(bset);
2005         bset = isl_basic_map_domain(bmap);
2006         isl_basic_set_free(bset);
2007 }
2008
2009 void test_subset(isl_ctx *ctx)
2010 {
2011         const char *str;
2012         isl_set *set1, *set2;
2013
2014         str = "{ [112, 0] }";
2015         set1 = isl_set_read_from_str(ctx, str);
2016         str = "{ [i0, i1] : exists (e0 = [(i0 - i1)/16], e1: "
2017                 "16e0 <= i0 - i1 and 16e0 >= -15 + i0 - i1 and "
2018                 "16e1 <= i1 and 16e0 >= -i1 and 16e1 >= -i0 + i1) }";
2019         set2 = isl_set_read_from_str(ctx, str);
2020         assert(isl_set_is_subset(set1, set2));
2021         isl_set_free(set1);
2022         isl_set_free(set2);
2023 }
2024
2025 int test_factorize(isl_ctx *ctx)
2026 {
2027         const char *str;
2028         isl_basic_set *bset;
2029         isl_factorizer *f;
2030
2031         str = "{ [i0, i1, i2, i3, i4, i5, i6, i7] : 3i5 <= 2 - 2i0 and "
2032             "i0 >= -2 and i6 >= 1 + i3 and i7 >= 0 and 3i5 >= -2i0 and "
2033             "2i4 <= i2 and i6 >= 1 + 2i0 + 3i1 and i4 <= -1 and "
2034             "i6 >= 1 + 2i0 + 3i5 and i6 <= 2 + 2i0 + 3i5 and "
2035             "3i5 <= 2 - 2i0 - i2 + 3i4 and i6 <= 2 + 2i0 + 3i1 and "
2036             "i0 <= -1 and i7 <= i2 + i3 - 3i4 - i6 and "
2037             "3i5 >= -2i0 - i2 + 3i4 }";
2038         bset = isl_basic_set_read_from_str(ctx, str);
2039         f = isl_basic_set_factorizer(bset);
2040         isl_basic_set_free(bset);
2041         isl_factorizer_free(f);
2042         if (!f)
2043                 isl_die(ctx, isl_error_unknown,
2044                         "failed to construct factorizer", return -1);
2045
2046         str = "{ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12] : "
2047             "i12 <= 2 + i0 - i11 and 2i8 >= -i4 and i11 >= i1 and "
2048             "3i5 <= -i2 and 2i11 >= -i4 - 2i7 and i11 <= 3 + i0 + 3i9 and "
2049             "i11 <= -i4 - 2i7 and i12 >= -i10 and i2 >= -2 and "
2050             "i11 >= i1 + 3i10 and i11 >= 1 + i0 + 3i9 and "
2051             "i11 <= 1 - i4 - 2i8 and 6i6 <= 6 - i2 and 3i6 >= 1 - i2 and "
2052             "i11 <= 2 + i1 and i12 <= i4 + i11 and i12 >= i0 - i11 and "
2053             "3i5 >= -2 - i2 and i12 >= -1 + i4 + i11 and 3i3 <= 3 - i2 and "
2054             "9i6 <= 11 - i2 + 6i5 and 3i3 >= 1 - i2 and "
2055             "9i6 <= 5 - i2 + 6i3 and i12 <= -1 and i2 <= 0 }";
2056         bset = isl_basic_set_read_from_str(ctx, str);
2057         f = isl_basic_set_factorizer(bset);
2058         isl_basic_set_free(bset);
2059         isl_factorizer_free(f);
2060         if (!f)
2061                 isl_die(ctx, isl_error_unknown,
2062                         "failed to construct factorizer", return -1);
2063
2064         return 0;
2065 }
2066
2067 static int check_injective(__isl_take isl_map *map, void *user)
2068 {
2069         int *injective = user;
2070
2071         *injective = isl_map_is_injective(map);
2072         isl_map_free(map);
2073
2074         if (*injective < 0 || !*injective)
2075                 return -1;
2076
2077         return 0;
2078 }
2079
2080 int test_one_schedule(isl_ctx *ctx, const char *d, const char *w,
2081         const char *r, const char *s, int tilable, int parallel)
2082 {
2083         int i;
2084         isl_union_set *D;
2085         isl_union_map *W, *R, *S;
2086         isl_union_map *empty;
2087         isl_union_map *dep_raw, *dep_war, *dep_waw, *dep;
2088         isl_union_map *validity, *proximity;
2089         isl_union_map *schedule;
2090         isl_union_map *test;
2091         isl_union_set *delta;
2092         isl_union_set *domain;
2093         isl_set *delta_set;
2094         isl_set *slice;
2095         isl_set *origin;
2096         isl_schedule *sched;
2097         int is_nonneg, is_parallel, is_tilable, is_injection, is_complete;
2098
2099         D = isl_union_set_read_from_str(ctx, d);
2100         W = isl_union_map_read_from_str(ctx, w);
2101         R = isl_union_map_read_from_str(ctx, r);
2102         S = isl_union_map_read_from_str(ctx, s);
2103
2104         W = isl_union_map_intersect_domain(W, isl_union_set_copy(D));
2105         R = isl_union_map_intersect_domain(R, isl_union_set_copy(D));
2106
2107         empty = isl_union_map_empty(isl_union_map_get_space(S));
2108         isl_union_map_compute_flow(isl_union_map_copy(R),
2109                                    isl_union_map_copy(W), empty,
2110                                    isl_union_map_copy(S),
2111                                    &dep_raw, NULL, NULL, NULL);
2112         isl_union_map_compute_flow(isl_union_map_copy(W),
2113                                    isl_union_map_copy(W),
2114                                    isl_union_map_copy(R),
2115                                    isl_union_map_copy(S),
2116                                    &dep_waw, &dep_war, NULL, NULL);
2117
2118         dep = isl_union_map_union(dep_waw, dep_war);
2119         dep = isl_union_map_union(dep, dep_raw);
2120         validity = isl_union_map_copy(dep);
2121         proximity = isl_union_map_copy(dep);
2122
2123         sched = isl_union_set_compute_schedule(isl_union_set_copy(D),
2124                                                validity, proximity);
2125         schedule = isl_schedule_get_map(sched);
2126         isl_schedule_free(sched);
2127         isl_union_map_free(W);
2128         isl_union_map_free(R);
2129         isl_union_map_free(S);
2130
2131         is_injection = 1;
2132         isl_union_map_foreach_map(schedule, &check_injective, &is_injection);
2133
2134         domain = isl_union_map_domain(isl_union_map_copy(schedule));
2135         is_complete = isl_union_set_is_subset(D, domain);
2136         isl_union_set_free(D);
2137         isl_union_set_free(domain);
2138
2139         test = isl_union_map_reverse(isl_union_map_copy(schedule));
2140         test = isl_union_map_apply_range(test, dep);
2141         test = isl_union_map_apply_range(test, schedule);
2142
2143         delta = isl_union_map_deltas(test);
2144         if (isl_union_set_n_set(delta) == 0) {
2145                 is_tilable = 1;
2146                 is_parallel = 1;
2147                 is_nonneg = 1;
2148                 isl_union_set_free(delta);
2149         } else {
2150                 delta_set = isl_set_from_union_set(delta);
2151
2152                 slice = isl_set_universe(isl_set_get_space(delta_set));
2153                 for (i = 0; i < tilable; ++i)
2154                         slice = isl_set_lower_bound_si(slice, isl_dim_set, i, 0);
2155                 is_tilable = isl_set_is_subset(delta_set, slice);
2156                 isl_set_free(slice);
2157
2158                 slice = isl_set_universe(isl_set_get_space(delta_set));
2159                 for (i = 0; i < parallel; ++i)
2160                         slice = isl_set_fix_si(slice, isl_dim_set, i, 0);
2161                 is_parallel = isl_set_is_subset(delta_set, slice);
2162                 isl_set_free(slice);
2163
2164                 origin = isl_set_universe(isl_set_get_space(delta_set));
2165                 for (i = 0; i < isl_set_dim(origin, isl_dim_set); ++i)
2166                         origin = isl_set_fix_si(origin, isl_dim_set, i, 0);
2167
2168                 delta_set = isl_set_union(delta_set, isl_set_copy(origin));
2169                 delta_set = isl_set_lexmin(delta_set);
2170
2171                 is_nonneg = isl_set_is_equal(delta_set, origin);
2172
2173                 isl_set_free(origin);
2174                 isl_set_free(delta_set);
2175         }
2176
2177         if (is_nonneg < 0 || is_parallel < 0 || is_tilable < 0 ||
2178             is_injection < 0 || is_complete < 0)
2179                 return -1;
2180         if (!is_complete)
2181                 isl_die(ctx, isl_error_unknown,
2182                         "generated schedule incomplete", return -1);
2183         if (!is_injection)
2184                 isl_die(ctx, isl_error_unknown,
2185                         "generated schedule not injective on each statement",
2186                         return -1);
2187         if (!is_nonneg)
2188                 isl_die(ctx, isl_error_unknown,
2189                         "negative dependences in generated schedule",
2190                         return -1);
2191         if (!is_tilable)
2192                 isl_die(ctx, isl_error_unknown,
2193                         "generated schedule not as tilable as expected",
2194                         return -1);
2195         if (!is_parallel)
2196                 isl_die(ctx, isl_error_unknown,
2197                         "generated schedule not as parallel as expected",
2198                         return -1);
2199
2200         return 0;
2201 }
2202
2203 int test_special_schedule(isl_ctx *ctx, const char *domain,
2204         const char *validity, const char *proximity, const char *expected_sched)
2205 {
2206         isl_union_set *dom;
2207         isl_union_map *dep;
2208         isl_union_map *prox;
2209         isl_union_map *sched1, *sched2;
2210         isl_schedule *schedule;
2211         int equal;
2212
2213         dom = isl_union_set_read_from_str(ctx, domain);
2214         dep = isl_union_map_read_from_str(ctx, validity);
2215         prox = isl_union_map_read_from_str(ctx, proximity);
2216         schedule = isl_union_set_compute_schedule(dom, dep, prox);
2217         sched1 = isl_schedule_get_map(schedule);
2218         isl_schedule_free(schedule);
2219
2220         sched2 = isl_union_map_read_from_str(ctx, expected_sched);
2221
2222         equal = isl_union_map_is_equal(sched1, sched2);
2223         isl_union_map_free(sched1);
2224         isl_union_map_free(sched2);
2225
2226         if (equal < 0)
2227                 return -1;
2228         if (!equal)
2229                 isl_die(ctx, isl_error_unknown, "unexpected schedule",
2230                         return -1);
2231
2232         return 0;
2233 }
2234
2235 int test_schedule(isl_ctx *ctx)
2236 {
2237         const char *D, *W, *R, *V, *P, *S;
2238
2239         /* Jacobi */
2240         D = "[T,N] -> { S1[t,i] : 1 <= t <= T and 2 <= i <= N - 1 }";
2241         W = "{ S1[t,i] -> a[t,i] }";
2242         R = "{ S1[t,i] -> a[t-1,i]; S1[t,i] -> a[t-1,i-1]; "
2243                 "S1[t,i] -> a[t-1,i+1] }";
2244         S = "{ S1[t,i] -> [t,i] }";
2245         if (test_one_schedule(ctx, D, W, R, S, 2, 0) < 0)
2246                 return -1;
2247
2248         /* Fig. 5 of CC2008 */
2249         D = "[N] -> { S_0[i, j] : i >= 0 and i <= -1 + N and j >= 2 and "
2250                                 "j <= -1 + N }";
2251         W = "[N] -> { S_0[i, j] -> a[i, j] : i >= 0 and i <= -1 + N and "
2252                                 "j >= 2 and j <= -1 + N }";
2253         R = "[N] -> { S_0[i, j] -> a[j, i] : i >= 0 and i <= -1 + N and "
2254                                 "j >= 2 and j <= -1 + N; "
2255                     "S_0[i, j] -> a[i, -1 + j] : i >= 0 and i <= -1 + N and "
2256                                 "j >= 2 and j <= -1 + N }";
2257         S = "[N] -> { S_0[i, j] -> [0, i, 0, j, 0] }";
2258         if (test_one_schedule(ctx, D, W, R, S, 2, 0) < 0)
2259                 return -1;
2260
2261         D = "{ S1[i] : 0 <= i <= 10; S2[i] : 0 <= i <= 9 }";
2262         W = "{ S1[i] -> a[i] }";
2263         R = "{ S2[i] -> a[i+1] }";
2264         S = "{ S1[i] -> [0,i]; S2[i] -> [1,i] }";
2265         if (test_one_schedule(ctx, D, W, R, S, 1, 1) < 0)
2266                 return -1;
2267
2268         D = "{ S1[i] : 0 <= i < 10; S2[i] : 0 <= i < 10 }";
2269         W = "{ S1[i] -> a[i] }";
2270         R = "{ S2[i] -> a[9-i] }";
2271         S = "{ S1[i] -> [0,i]; S2[i] -> [1,i] }";
2272         if (test_one_schedule(ctx, D, W, R, S, 1, 1) < 0)
2273                 return -1;
2274
2275         D = "[N] -> { S1[i] : 0 <= i < N; S2[i] : 0 <= i < N }";
2276         W = "{ S1[i] -> a[i] }";
2277         R = "[N] -> { S2[i] -> a[N-1-i] }";
2278         S = "{ S1[i] -> [0,i]; S2[i] -> [1,i] }";
2279         if (test_one_schedule(ctx, D, W, R, S, 1, 1) < 0)
2280                 return -1;
2281         
2282         D = "{ S1[i] : 0 < i < 10; S2[i] : 0 <= i < 10 }";
2283         W = "{ S1[i] -> a[i]; S2[i] -> b[i] }";
2284         R = "{ S2[i] -> a[i]; S1[i] -> b[i-1] }";
2285         S = "{ S1[i] -> [i,0]; S2[i] -> [i,1] }";
2286         if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0)
2287                 return -1;
2288
2289         D = "[N] -> { S1[i] : 1 <= i <= N; S2[i,j] : 1 <= i,j <= N }";
2290         W = "{ S1[i] -> a[0,i]; S2[i,j] -> a[i,j] }";
2291         R = "{ S2[i,j] -> a[i-1,j] }";
2292         S = "{ S1[i] -> [0,i,0]; S2[i,j] -> [1,i,j] }";
2293         if (test_one_schedule(ctx, D, W, R, S, 2, 1) < 0)
2294                 return -1;
2295
2296         D = "[N] -> { S1[i] : 1 <= i <= N; S2[i,j] : 1 <= i,j <= N }";
2297         W = "{ S1[i] -> a[i,0]; S2[i,j] -> a[i,j] }";
2298         R = "{ S2[i,j] -> a[i,j-1] }";
2299         S = "{ S1[i] -> [0,i,0]; S2[i,j] -> [1,i,j] }";
2300         if (test_one_schedule(ctx, D, W, R, S, 2, 1) < 0)
2301                 return -1;
2302
2303         D = "[N] -> { S_0[]; S_1[i] : i >= 0 and i <= -1 + N; S_2[] }";
2304         W = "[N] -> { S_0[] -> a[0]; S_2[] -> b[0]; "
2305                     "S_1[i] -> a[1 + i] : i >= 0 and i <= -1 + N }";
2306         R = "[N] -> { S_2[] -> a[N]; S_1[i] -> a[i] : i >= 0 and i <= -1 + N }";
2307         S = "[N] -> { S_1[i] -> [1, i, 0]; S_2[] -> [2, 0, 1]; "
2308                     "S_0[] -> [0, 0, 0] }";
2309         if (test_one_schedule(ctx, D, W, R, S, 1, 0) < 0)
2310                 return -1;
2311         ctx->opt->schedule_parametric = 0;
2312         if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0)
2313                 return -1;
2314         ctx->opt->schedule_parametric = 1;
2315
2316         D = "[N] -> { S1[i] : 1 <= i <= N; S2[i] : 1 <= i <= N; "
2317                     "S3[i,j] : 1 <= i,j <= N; S4[i] : 1 <= i <= N }";
2318         W = "{ S1[i] -> a[i,0]; S2[i] -> a[0,i]; S3[i,j] -> a[i,j] }";
2319         R = "[N] -> { S3[i,j] -> a[i-1,j]; S3[i,j] -> a[i,j-1]; "
2320                     "S4[i] -> a[i,N] }";
2321         S = "{ S1[i] -> [0,i,0]; S2[i] -> [1,i,0]; S3[i,j] -> [2,i,j]; "
2322                 "S4[i] -> [4,i,0] }";
2323         if (test_one_schedule(ctx, D, W, R, S, 2, 0) < 0)
2324                 return -1;
2325
2326         D = "[N] -> { S_0[i, j] : i >= 1 and i <= N and j >= 1 and j <= N }";
2327         W = "[N] -> { S_0[i, j] -> s[0] : i >= 1 and i <= N and j >= 1 and "
2328                                         "j <= N }";
2329         R = "[N] -> { S_0[i, j] -> s[0] : i >= 1 and i <= N and j >= 1 and "
2330                                         "j <= N; "
2331                     "S_0[i, j] -> a[i, j] : i >= 1 and i <= N and j >= 1 and "
2332                                         "j <= N }";
2333         S = "[N] -> { S_0[i, j] -> [0, i, 0, j, 0] }";
2334         if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0)
2335                 return -1;
2336
2337         D = "[N] -> { S_0[t] : t >= 0 and t <= -1 + N; "
2338                     " S_2[t] : t >= 0 and t <= -1 + N; "
2339                     " S_1[t, i] : t >= 0 and t <= -1 + N and i >= 0 and "
2340                                 "i <= -1 + N }";
2341         W = "[N] -> { S_0[t] -> a[t, 0] : t >= 0 and t <= -1 + N; "
2342                     " S_2[t] -> b[t] : t >= 0 and t <= -1 + N; "
2343                     " S_1[t, i] -> a[t, 1 + i] : t >= 0 and t <= -1 + N and "
2344                                                 "i >= 0 and i <= -1 + N }";
2345         R = "[N] -> { S_1[t, i] -> a[t, i] : t >= 0 and t <= -1 + N and "
2346                                             "i >= 0 and i <= -1 + N; "
2347                     " S_2[t] -> a[t, N] : t >= 0 and t <= -1 + N }";
2348         S = "[N] -> { S_2[t] -> [0, t, 2]; S_1[t, i] -> [0, t, 1, i, 0]; "
2349                     " S_0[t] -> [0, t, 0] }";
2350
2351         if (test_one_schedule(ctx, D, W, R, S, 2, 1) < 0)
2352                 return -1;
2353         ctx->opt->schedule_parametric = 0;
2354         if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0)
2355                 return -1;
2356         ctx->opt->schedule_parametric = 1;
2357
2358         D = "[N] -> { S1[i,j] : 0 <= i,j < N; S2[i,j] : 0 <= i,j < N }";
2359         S = "{ S1[i,j] -> [0,i,j]; S2[i,j] -> [1,i,j] }";
2360         if (test_one_schedule(ctx, D, "{}", "{}", S, 2, 2) < 0)
2361                 return -1;
2362
2363         D = "[M, N] -> { S_1[i] : i >= 0 and i <= -1 + M; "
2364             "S_0[i, j] : i >= 0 and i <= -1 + M and j >= 0 and j <= -1 + N }";
2365         W = "[M, N] -> { S_0[i, j] -> a[j] : i >= 0 and i <= -1 + M and "
2366                                             "j >= 0 and j <= -1 + N; "
2367                         "S_1[i] -> b[0] : i >= 0 and i <= -1 + M }";
2368         R = "[M, N] -> { S_0[i, j] -> a[0] : i >= 0 and i <= -1 + M and "
2369                                             "j >= 0 and j <= -1 + N; "
2370                         "S_1[i] -> b[0] : i >= 0 and i <= -1 + M }";
2371         S = "[M, N] -> { S_1[i] -> [1, i, 0]; S_0[i, j] -> [0, i, 0, j, 0] }";
2372         if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0)
2373                 return -1;
2374
2375         D = "{ S_0[i] : i >= 0 }";
2376         W = "{ S_0[i] -> a[i] : i >= 0 }";
2377         R = "{ S_0[i] -> a[0] : i >= 0 }";
2378         S = "{ S_0[i] -> [0, i, 0] }";
2379         if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0)
2380                 return -1;
2381
2382         D = "{ S_0[i] : i >= 0; S_1[i] : i >= 0 }";
2383         W = "{ S_0[i] -> a[i] : i >= 0; S_1[i] -> b[i] : i >= 0 }";
2384         R = "{ S_0[i] -> b[0] : i >= 0; S_1[i] -> a[i] : i >= 0 }";
2385         S = "{ S_1[i] -> [0, i, 1]; S_0[i] -> [0, i, 0] }";
2386         if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0)
2387                 return -1;
2388
2389         D = "[n] -> { S_0[j, k] : j <= -1 + n and j >= 0 and "
2390                                 "k <= -1 + n and k >= 0 }";
2391         W = "[n] -> { S_0[j, k] -> B[j] : j <= -1 + n and j >= 0 and "                                                  "k <= -1 + n and k >= 0 }";
2392         R = "[n] -> { S_0[j, k] -> B[j] : j <= -1 + n and j >= 0 and "
2393                                         "k <= -1 + n and k >= 0; "
2394                     "S_0[j, k] -> B[k] : j <= -1 + n and j >= 0 and "
2395                                         "k <= -1 + n and k >= 0; "
2396                     "S_0[j, k] -> A[k] : j <= -1 + n and j >= 0 and "
2397                                         "k <= -1 + n and k >= 0 }";
2398         S = "[n] -> { S_0[j, k] -> [2, j, k] }";
2399         ctx->opt->schedule_outer_zero_distance = 1;
2400         if (test_one_schedule(ctx, D, W, R, S, 0, 0) < 0)
2401                 return -1;
2402         ctx->opt->schedule_outer_zero_distance = 0;
2403
2404         D = "{Stmt_for_body24[i0, i1, i2, i3]:"
2405                 "i0 >= 0 and i0 <= 1 and i1 >= 0 and i1 <= 6 and i2 >= 2 and "
2406                 "i2 <= 6 - i1 and i3 >= 0 and i3 <= -1 + i2;"
2407              "Stmt_for_body24[i0, i1, 1, 0]:"
2408                 "i0 >= 0 and i0 <= 1 and i1 >= 0 and i1 <= 5;"
2409              "Stmt_for_body7[i0, i1, i2]:"
2410                 "i0 >= 0 and i0 <= 1 and i1 >= 0 and i1 <= 7 and i2 >= 0 and "
2411                 "i2 <= 7 }";
2412
2413         V = "{Stmt_for_body24[0, i1, i2, i3] -> "
2414                 "Stmt_for_body24[1, i1, i2, i3]:"
2415                 "i3 >= 0 and i3 <= -1 + i2 and i1 >= 0 and i2 <= 6 - i1 and "
2416                 "i2 >= 1;"
2417              "Stmt_for_body24[0, i1, i2, i3] -> "
2418                 "Stmt_for_body7[1, 1 + i1 + i3, 1 + i1 + i2]:"
2419                 "i3 <= -1 + i2 and i2 <= 6 - i1 and i2 >= 1 and i1 >= 0 and "
2420                 "i3 >= 0;"
2421               "Stmt_for_body24[0, i1, i2, i3] ->"
2422                 "Stmt_for_body7[1, i1, 1 + i1 + i3]:"
2423                 "i3 >= 0 and i2 <= 6 - i1 and i1 >= 0 and i3 <= -1 + i2;"
2424               "Stmt_for_body7[0, i1, i2] -> Stmt_for_body7[1, i1, i2]:"
2425                 "(i2 >= 1 + i1 and i2 <= 6 and i1 >= 0 and i1 <= 4) or "
2426                 "(i2 >= 3 and i2 <= 7 and i1 >= 1 and i2 >= 1 + i1) or "
2427                 "(i2 >= 0 and i2 <= i1 and i2 >= -7 + i1 and i1 <= 7);"
2428               "Stmt_for_body7[0, i1, 1 + i1] -> Stmt_for_body7[1, i1, 1 + i1]:"
2429                 "i1 <= 6 and i1 >= 0;"
2430               "Stmt_for_body7[0, 0, 7] -> Stmt_for_body7[1, 0, 7];"
2431               "Stmt_for_body7[i0, i1, i2] -> "
2432                 "Stmt_for_body24[i0, o1, -1 + i2 - o1, -1 + i1 - o1]:"
2433                 "i0 >= 0 and i0 <= 1 and o1 >= 0 and i2 >= 1 + i1 and "
2434                 "o1 <= -2 + i2 and i2 <= 7 and o1 <= -1 + i1;"
2435               "Stmt_for_body7[i0, i1, i2] -> "
2436                 "Stmt_for_body24[i0, i1, o2, -1 - i1 + i2]:"
2437                 "i0 >= 0 and i0 <= 1 and i1 >= 0 and o2 >= -i1 + i2 and "
2438                 "o2 >= 1 and o2 <= 6 - i1 and i2 >= 1 + i1 }";
2439         P = V;
2440         S = "{ Stmt_for_body24[i0, i1, i2, i3] -> "
2441                 "[i0, 5i0 + i1, 6i0 + i1 + i2, 1 + 6i0 + i1 + i2 + i3, 1];"
2442             "Stmt_for_body7[i0, i1, i2] -> [0, 5i0, 6i0 + i1, 6i0 + i2, 0] }";
2443
2444         if (test_special_schedule(ctx, D, V, P, S) < 0)
2445                 return -1;
2446
2447         D = "{ S_0[i, j] : i >= 1 and i <= 10 and j >= 1 and j <= 8 }";
2448         V = "{ S_0[i, j] -> S_0[i, 1 + j] : i >= 1 and i <= 10 and "
2449                                            "j >= 1 and j <= 7;"
2450                 "S_0[i, j] -> S_0[1 + i, j] : i >= 1 and i <= 9 and "
2451                                              "j >= 1 and j <= 8 }";
2452         P = "{ }";
2453         S = "{ S_0[i, j] -> [i + j, j] }";
2454         ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER;
2455         if (test_special_schedule(ctx, D, V, P, S) < 0)
2456                 return -1;
2457         ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL;
2458
2459         /* Fig. 1 from Feautrier's "Some Efficient Solutions..." pt. 2, 1992 */
2460         D = "[N] -> { S_0[i, j] : i >= 0 and i <= -1 + N and "
2461                                  "j >= 0 and j <= -1 + i }";
2462         V = "[N] -> { S_0[i, j] -> S_0[i, 1 + j] : j <= -2 + i and "
2463                                         "i <= -1 + N and j >= 0;"
2464                      "S_0[i, -1 + i] -> S_0[1 + i, 0] : i >= 1 and "
2465                                         "i <= -2 + N }";
2466         P = "{ }";
2467         S = "{ S_0[i, j] -> [i, j] }";
2468         ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER;
2469         if (test_special_schedule(ctx, D, V, P, S) < 0)
2470                 return -1;
2471         ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL;
2472
2473         /* Test both algorithms on a case with only proximity dependences. */
2474         D = "{ S[i,j] : 0 <= i <= 10 }";
2475         V = "{ }";
2476         P = "{ S[i,j] -> S[i+1,j] : 0 <= i,j <= 10 }";
2477         S = "{ S[i, j] -> [j, i] }";
2478         ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_FEAUTRIER;
2479         if (test_special_schedule(ctx, D, V, P, S) < 0)
2480                 return -1;
2481         ctx->opt->schedule_algorithm = ISL_SCHEDULE_ALGORITHM_ISL;
2482         return test_special_schedule(ctx, D, V, P, S);
2483 }
2484
2485 int test_plain_injective(isl_ctx *ctx, const char *str, int injective)
2486 {
2487         isl_union_map *umap;
2488         int test;
2489
2490         umap = isl_union_map_read_from_str(ctx, str);
2491         test = isl_union_map_plain_is_injective(umap);
2492         isl_union_map_free(umap);
2493         if (test < 0)
2494                 return -1;
2495         if (test == injective)
2496                 return 0;
2497         if (injective)
2498                 isl_die(ctx, isl_error_unknown,
2499                         "map not detected as injective", return -1);
2500         else
2501                 isl_die(ctx, isl_error_unknown,
2502                         "map detected as injective", return -1);
2503 }
2504
2505 int test_injective(isl_ctx *ctx)
2506 {
2507         const char *str;
2508
2509         if (test_plain_injective(ctx, "{S[i,j] -> A[0]; T[i,j] -> B[1]}", 0))
2510                 return -1;
2511         if (test_plain_injective(ctx, "{S[] -> A[0]; T[] -> B[0]}", 1))
2512                 return -1;
2513         if (test_plain_injective(ctx, "{S[] -> A[0]; T[] -> A[1]}", 1))
2514                 return -1;
2515         if (test_plain_injective(ctx, "{S[] -> A[0]; T[] -> A[0]}", 0))
2516                 return -1;
2517         if (test_plain_injective(ctx, "{S[i] -> A[i,0]; T[i] -> A[i,1]}", 1))
2518                 return -1;
2519         if (test_plain_injective(ctx, "{S[i] -> A[i]; T[i] -> A[i]}", 0))
2520                 return -1;
2521         if (test_plain_injective(ctx, "{S[] -> A[0,0]; T[] -> A[0,1]}", 1))
2522                 return -1;
2523         if (test_plain_injective(ctx, "{S[] -> A[0,0]; T[] -> A[1,0]}", 1))
2524                 return -1;
2525
2526         str = "{S[] -> A[0,0]; T[] -> A[0,1]; U[] -> A[1,0]}";
2527         if (test_plain_injective(ctx, str, 1))
2528                 return -1;
2529         str = "{S[] -> A[0,0]; T[] -> A[0,1]; U[] -> A[0,0]}";
2530         if (test_plain_injective(ctx, str, 0))
2531                 return -1;
2532
2533         return 0;
2534 }
2535
2536 static int aff_plain_is_equal(__isl_keep isl_aff *aff, const char *str)
2537 {
2538         isl_aff *aff2;
2539         int equal;
2540
2541         if (!aff)
2542                 return -1;
2543
2544         aff2 = isl_aff_read_from_str(isl_aff_get_ctx(aff), str);
2545         equal = isl_aff_plain_is_equal(aff, aff2);
2546         isl_aff_free(aff2);
2547
2548         return equal;
2549 }
2550
2551 static int aff_check_plain_equal(__isl_keep isl_aff *aff, const char *str)
2552 {
2553         int equal;
2554
2555         equal = aff_plain_is_equal(aff, str);
2556         if (equal < 0)
2557                 return -1;
2558         if (!equal)
2559                 isl_die(isl_aff_get_ctx(aff), isl_error_unknown,
2560                         "result not as expected", return -1);
2561         return 0;
2562 }
2563
2564 int test_aff(isl_ctx *ctx)
2565 {
2566         const char *str;
2567         isl_set *set;
2568         isl_space *space;
2569         isl_local_space *ls;
2570         isl_aff *aff;
2571         int zero, equal;
2572
2573         space = isl_space_set_alloc(ctx, 0, 1);
2574         ls = isl_local_space_from_space(space);
2575         aff = isl_aff_zero_on_domain(ls);
2576
2577         aff = isl_aff_add_coefficient_si(aff, isl_dim_in, 0, 1);
2578         aff = isl_aff_scale_down_ui(aff, 3);
2579         aff = isl_aff_floor(aff);
2580         aff = isl_aff_add_coefficient_si(aff, isl_dim_in, 0, 1);
2581         aff = isl_aff_scale_down_ui(aff, 2);
2582         aff = isl_aff_floor(aff);
2583         aff = isl_aff_add_coefficient_si(aff, isl_dim_in, 0, 1);
2584
2585         str = "{ [10] }";
2586         set = isl_set_read_from_str(ctx, str);
2587         aff = isl_aff_gist(aff, set);
2588
2589         aff = isl_aff_add_constant_si(aff, -16);
2590         zero = isl_aff_plain_is_zero(aff);
2591         isl_aff_free(aff);
2592
2593         if (zero < 0)
2594                 return -1;
2595         if (!zero)
2596                 isl_die(ctx, isl_error_unknown, "unexpected result", return -1);
2597
2598         aff = isl_aff_read_from_str(ctx, "{ [-1] }");
2599         aff = isl_aff_scale_down_ui(aff, 64);
2600         aff = isl_aff_floor(aff);
2601         equal = aff_check_plain_equal(aff, "{ [-1] }");
2602         isl_aff_free(aff);
2603         if (equal < 0)
2604                 return -1;
2605
2606         return 0;
2607 }
2608
2609 int test_dim_max(isl_ctx *ctx)
2610 {
2611         int equal;
2612         const char *str;
2613         isl_set *set1, *set2;
2614         isl_set *set;
2615         isl_map *map;
2616         isl_pw_aff *pwaff;
2617
2618         str = "[N] -> { [i] : 0 <= i <= min(N,10) }";
2619         set = isl_set_read_from_str(ctx, str);
2620         pwaff = isl_set_dim_max(set, 0);
2621         set1 = isl_set_from_pw_aff(pwaff);
2622         str = "[N] -> { [10] : N >= 10; [N] : N <= 9 and N >= 0 }";
2623         set2 = isl_set_read_from_str(ctx, str);
2624         equal = isl_set_is_equal(set1, set2);
2625         isl_set_free(set1);
2626         isl_set_free(set2);
2627         if (equal < 0)
2628                 return -1;
2629         if (!equal)
2630                 isl_die(ctx, isl_error_unknown, "unexpected result", return -1);
2631
2632         str = "[N] -> { [i] : 0 <= i <= max(2N,N+6) }";
2633         set = isl_set_read_from_str(ctx, str);
2634         pwaff = isl_set_dim_max(set, 0);
2635         set1 = isl_set_from_pw_aff(pwaff);
2636         str = "[N] -> { [6 + N] : -6 <= N <= 5; [2N] : N >= 6 }";
2637         set2 = isl_set_read_from_str(ctx, str);
2638         equal = isl_set_is_equal(set1, set2);
2639         isl_set_free(set1);
2640         isl_set_free(set2);
2641         if (equal < 0)
2642                 return -1;
2643         if (!equal)
2644                 isl_die(ctx, isl_error_unknown, "unexpected result", return -1);
2645
2646         str = "[N] -> { [i] : 0 <= i <= 2N or 0 <= i <= N+6 }";
2647         set = isl_set_read_from_str(ctx, str);
2648         pwaff = isl_set_dim_max(set, 0);
2649         set1 = isl_set_from_pw_aff(pwaff);
2650         str = "[N] -> { [6 + N] : -6 <= N <= 5; [2N] : N >= 6 }";
2651         set2 = isl_set_read_from_str(ctx, str);
2652         equal = isl_set_is_equal(set1, set2);
2653         isl_set_free(set1);
2654         isl_set_free(set2);
2655         if (equal < 0)
2656                 return -1;
2657         if (!equal)
2658                 isl_die(ctx, isl_error_unknown, "unexpected result", return -1);
2659
2660         str = "[N,M] -> { [i,j] -> [([i/16]), i%16, ([j/16]), j%16] : "
2661                         "0 <= i < N and 0 <= j < M }";
2662         map = isl_map_read_from_str(ctx, str);
2663         set = isl_map_range(map);
2664
2665         pwaff = isl_set_dim_max(isl_set_copy(set), 0);
2666         set1 = isl_set_from_pw_aff(pwaff);
2667         str = "[N,M] -> { [([(N-1)/16])] : M,N > 0 }";
2668         set2 = isl_set_read_from_str(ctx, str);
2669         equal = isl_set_is_equal(set1, set2);
2670         isl_set_free(set1);
2671         isl_set_free(set2);
2672
2673         pwaff = isl_set_dim_max(isl_set_copy(set), 3);
2674         set1 = isl_set_from_pw_aff(pwaff);
2675         str = "[N,M] -> { [t] : t = min(M-1,15) and M,N > 0 }";
2676         set2 = isl_set_read_from_str(ctx, str);
2677         if (equal >= 0 && equal)
2678                 equal = isl_set_is_equal(set1, set2);
2679         isl_set_free(set1);
2680         isl_set_free(set2);
2681
2682         isl_set_free(set);
2683
2684         if (equal < 0)
2685                 return -1;
2686         if (!equal)
2687                 isl_die(ctx, isl_error_unknown, "unexpected result", return -1);
2688
2689         return 0;
2690 }
2691
2692 int test_product(isl_ctx *ctx)
2693 {
2694         const char *str;
2695         isl_set *set;
2696         isl_union_set *uset1, *uset2;
2697         int ok;
2698
2699         str = "{ A[i] }";
2700         set = isl_set_read_from_str(ctx, str);
2701         set = isl_set_product(set, isl_set_copy(set));
2702         ok = isl_set_is_wrapping(set);
2703         isl_set_free(set);
2704         if (ok < 0)
2705                 return -1;
2706         if (!ok)
2707                 isl_die(ctx, isl_error_unknown, "unexpected result", return -1);
2708
2709         str = "{ [] }";
2710         uset1 = isl_union_set_read_from_str(ctx, str);
2711         uset1 = isl_union_set_product(uset1, isl_union_set_copy(uset1));
2712         str = "{ [[] -> []] }";
2713         uset2 = isl_union_set_read_from_str(ctx, str);
2714         ok = isl_union_set_is_equal(uset1, uset2);
2715         isl_union_set_free(uset1);
2716         isl_union_set_free(uset2);
2717         if (ok < 0)
2718                 return -1;
2719         if (!ok)
2720                 isl_die(ctx, isl_error_unknown, "unexpected result", return -1);
2721
2722         return 0;
2723 }
2724
2725 int test_equal(isl_ctx *ctx)
2726 {
2727         const char *str;
2728         isl_set *set, *set2;
2729         int equal;
2730
2731         str = "{ S_6[i] }";
2732         set = isl_set_read_from_str(ctx, str);
2733         str = "{ S_7[i] }";
2734         set2 = isl_set_read_from_str(ctx, str);
2735         equal = isl_set_is_equal(set, set2);
2736         isl_set_free(set);
2737         isl_set_free(set2);
2738         if (equal < 0)
2739                 return -1;
2740         if (equal)
2741                 isl_die(ctx, isl_error_unknown, "unexpected result", return -1);
2742
2743         return 0;
2744 }
2745
2746 static int test_plain_fixed(isl_ctx *ctx, __isl_take isl_map *map,
2747         enum isl_dim_type type, unsigned pos, int fixed)
2748 {
2749         int test;
2750
2751         test = isl_map_plain_is_fixed(map, type, pos, NULL);
2752         isl_map_free(map);
2753         if (test < 0)
2754                 return -1;
2755         if (test == fixed)
2756                 return 0;
2757         if (fixed)
2758                 isl_die(ctx, isl_error_unknown,
2759                         "map not detected as fixed", return -1);
2760         else
2761                 isl_die(ctx, isl_error_unknown,
2762                         "map detected as fixed", return -1);
2763 }
2764
2765 int test_fixed(isl_ctx *ctx)
2766 {
2767         const char *str;
2768         isl_map *map;
2769
2770         str = "{ [i] -> [i] }";
2771         map = isl_map_read_from_str(ctx, str);
2772         if (test_plain_fixed(ctx, map, isl_dim_out, 0, 0))
2773                 return -1;
2774         str = "{ [i] -> [1] }";
2775         map = isl_map_read_from_str(ctx, str);
2776         if (test_plain_fixed(ctx, map, isl_dim_out, 0, 1))
2777                 return -1;
2778         str = "{ S_1[p1] -> [o0] : o0 = -2 and p1 >= 1 and p1 <= 7 }";
2779         map = isl_map_read_from_str(ctx, str);
2780         if (test_plain_fixed(ctx, map, isl_dim_out, 0, 1))
2781                 return -1;
2782         map = isl_map_read_from_str(ctx, str);
2783         map = isl_map_neg(map);
2784         if (test_plain_fixed(ctx, map, isl_dim_out, 0, 1))
2785                 return -1;
2786
2787         return 0;
2788 }
2789
2790 int test_vertices(isl_ctx *ctx)
2791 {
2792         const char *str;
2793         isl_basic_set *bset;
2794         isl_vertices *vertices;
2795
2796         str = "{ A[t, i] : t = 12 and i >= 4 and i <= 12 }";
2797         bset = isl_basic_set_read_from_str(ctx, str);
2798         vertices = isl_basic_set_compute_vertices(bset);
2799         isl_basic_set_free(bset);
2800         isl_vertices_free(vertices);
2801         if (!vertices)
2802                 return -1;
2803
2804         str = "{ A[t, i] : t = 14 and i = 1 }";
2805         bset = isl_basic_set_read_from_str(ctx, str);
2806         vertices = isl_basic_set_compute_vertices(bset);
2807         isl_basic_set_free(bset);
2808         isl_vertices_free(vertices);
2809         if (!vertices)
2810                 return -1;
2811
2812         return 0;
2813 }
2814
2815 int test_union_pw(isl_ctx *ctx)
2816 {
2817         int equal;
2818         const char *str;
2819         isl_union_set *uset;
2820         isl_union_pw_qpolynomial *upwqp1, *upwqp2;
2821
2822         str = "{ [x] -> x^2 }";
2823         upwqp1 = isl_union_pw_qpolynomial_read_from_str(ctx, str);
2824         upwqp2 = isl_union_pw_qpolynomial_copy(upwqp1);
2825         uset = isl_union_pw_qpolynomial_domain(upwqp1);
2826         upwqp1 = isl_union_pw_qpolynomial_copy(upwqp2);
2827         upwqp1 = isl_union_pw_qpolynomial_intersect_domain(upwqp1, uset);
2828         equal = isl_union_pw_qpolynomial_plain_is_equal(upwqp1, upwqp2);
2829         isl_union_pw_qpolynomial_free(upwqp1);
2830         isl_union_pw_qpolynomial_free(upwqp2);
2831         if (equal < 0)
2832                 return -1;
2833         if (!equal)
2834                 isl_die(ctx, isl_error_unknown, "unexpected result", return -1);
2835
2836         return 0;
2837 }
2838
2839 int test_output(isl_ctx *ctx)
2840 {
2841         char *s;
2842         const char *str;
2843         isl_pw_aff *pa;
2844         isl_printer *p;
2845         int equal;
2846
2847         str = "[x] -> { [1] : x % 4 <= 2; [2] : x = 3 }";
2848         pa = isl_pw_aff_read_from_str(ctx, str);
2849
2850         p = isl_printer_to_str(ctx);
2851         p = isl_printer_set_output_format(p, ISL_FORMAT_C);
2852         p = isl_printer_print_pw_aff(p, pa);
2853         s = isl_printer_get_str(p);
2854         isl_printer_free(p);
2855         isl_pw_aff_free(pa);
2856         equal = !strcmp(s, "(2 - x + 4*floord(x, 4) >= 0) ? (1) : 2");
2857         free(s);
2858         if (equal < 0)
2859                 return -1;
2860         if (!equal)
2861                 isl_die(ctx, isl_error_unknown, "unexpected result", return -1);
2862
2863         return 0;
2864 }
2865
2866 int test_sample(isl_ctx *ctx)
2867 {
2868         const char *str;
2869         isl_basic_set *bset1, *bset2;
2870         int empty, subset;
2871
2872         str = "{ [a, b, c, d, e, f, g, h, i, j, k] : "
2873             "3i >= 1073741823b - c - 1073741823e + f and c >= 0 and "
2874             "3i >= -1 + 3221225466b + c + d - 3221225466e - f and "
2875             "2e >= a - b and 3e <= 2a and 3k <= -a and f <= -1 + a and "
2876             "3i <= 4 - a + 4b + 2c - e - 2f and 3k <= -a + c - f and "
2877             "3h >= -2 + a and 3g >= -3 - a and 3k >= -2 - a and "
2878             "3i >= -2 - a - 2c + 3e + 2f and 3h <= a + c - f and "
2879             "3h >= a + 2147483646b + 2c - 2147483646e - 2f and "
2880             "3g <= -1 - a and 3i <= 1 + c + d - f and a <= 1073741823 and "
2881             "f >= 1 - a + 1073741822b + c + d - 1073741822e and "
2882             "3i >= 1 + 2b - 2c + e + 2f + 3g and "
2883             "1073741822f <= 1073741822 - a + 1073741821b + 1073741822c +"
2884                 "d - 1073741821e and "
2885             "3j <= 3 - a + 3b and 3g <= -2 - 2b + c + d - e - f and "
2886             "3j >= 1 - a + b + 2e and "
2887             "3f >= -3 + a + 3221225462b + 3c + d - 3221225465e and "
2888             "3i <= 4 - a + 4b - e and "
2889             "f <= 1073741822 + 1073741822b - 1073741822e and 3h <= a and "
2890             "f >= 0 and 2e <= 4 - a + 5b - d and 2e <= a - b + d and "
2891             "c <= -1 + a and 3i >= -2 - a + 3e and "
2892             "1073741822e <= 1073741823 - a + 1073741822b + c and "
2893             "3g >= -4 + 3221225464b + 3c + d - 3221225467e - 3f and "
2894             "3i >= -1 + 3221225466b + 3c + d - 3221225466e - 3f and "
2895             "1073741823e >= 1 + 1073741823b - d and "
2896             "3i >= 1073741823b + c - 1073741823e - f and "
2897             "3i >= 1 + 2b + e + 3g }";
2898         bset1 = isl_basic_set_read_from_str(ctx, str);
2899         bset2 = isl_basic_set_sample(isl_basic_set_copy(bset1));
2900         empty = isl_basic_set_is_empty(bset2);
2901         subset = isl_basic_set_is_subset(bset2, bset1);
2902         isl_basic_set_free(bset1);
2903         isl_basic_set_free(bset2);
2904         if (empty)
2905                 isl_die(ctx, isl_error_unknown, "point not found", return -1);
2906         if (!subset)
2907                 isl_die(ctx, isl_error_unknown, "bad point found", return -1);
2908
2909         return 0;
2910 }
2911
2912 int test_fixed_power(isl_ctx *ctx)
2913 {
2914         const char *str;
2915         isl_map *map;
2916         isl_int exp;
2917         int equal;
2918
2919         isl_int_init(exp);
2920         str = "{ [i] -> [i + 1] }";
2921         map = isl_map_read_from_str(ctx, str);
2922         isl_int_set_si(exp, 23);
2923         map = isl_map_fixed_power(map, exp);
2924         equal = map_check_equal(map, "{ [i] -> [i + 23] }");
2925         isl_int_clear(exp);
2926         isl_map_free(map);
2927         if (equal < 0)
2928                 return -1;
2929
2930         return 0;
2931 }
2932
2933 int test_slice(isl_ctx *ctx)
2934 {
2935         const char *str;
2936         isl_map *map;
2937         int equal;
2938
2939         str = "{ [i] -> [j] }";
2940         map = isl_map_read_from_str(ctx, str);
2941         map = isl_map_equate(map, isl_dim_in, 0, isl_dim_out, 0);
2942         equal = map_check_equal(map, "{ [i] -> [i] }");
2943         isl_map_free(map);
2944         if (equal < 0)
2945                 return -1;
2946
2947         str = "{ [i] -> [j] }";
2948         map = isl_map_read_from_str(ctx, str);
2949         map = isl_map_equate(map, isl_dim_in, 0, isl_dim_in, 0);
2950         equal = map_check_equal(map, "{ [i] -> [j] }");
2951         isl_map_free(map);
2952         if (equal < 0)
2953                 return -1;
2954
2955         str = "{ [i] -> [j] }";
2956         map = isl_map_read_from_str(ctx, str);
2957         map = isl_map_oppose(map, isl_dim_in, 0, isl_dim_out, 0);
2958         equal = map_check_equal(map, "{ [i] -> [-i] }");
2959         isl_map_free(map);
2960         if (equal < 0)
2961                 return -1;
2962
2963         str = "{ [i] -> [j] }";
2964         map = isl_map_read_from_str(ctx, str);
2965         map = isl_map_oppose(map, isl_dim_in, 0, isl_dim_in, 0);
2966         equal = map_check_equal(map, "{ [0] -> [j] }");
2967         isl_map_free(map);
2968         if (equal < 0)
2969                 return -1;
2970
2971         str = "{ [i] -> [j] }";
2972         map = isl_map_read_from_str(ctx, str);
2973         map = isl_map_order_gt(map, isl_dim_in, 0, isl_dim_out, 0);
2974         equal = map_check_equal(map, "{ [i] -> [j] : i > j }");
2975         isl_map_free(map);
2976         if (equal < 0)
2977                 return -1;
2978
2979         str = "{ [i] -> [j] }";
2980         map = isl_map_read_from_str(ctx, str);
2981         map = isl_map_order_gt(map, isl_dim_in, 0, isl_dim_in, 0);
2982         equal = map_check_equal(map, "{ [i] -> [j] : false }");
2983         isl_map_free(map);
2984         if (equal < 0)
2985                 return -1;
2986
2987         return 0;
2988 }
2989
2990 int test_eliminate(isl_ctx *ctx)
2991 {
2992         const char *str;
2993         isl_map *map;
2994         int equal;
2995
2996         str = "{ [i] -> [j] : i = 2j }";
2997         map = isl_map_read_from_str(ctx, str);
2998         map = isl_map_eliminate(map, isl_dim_out, 0, 1);
2999         equal = map_check_equal(map, "{ [i] -> [j] : exists a : i = 2a }");
3000         isl_map_free(map);
3001         if (equal < 0)
3002                 return -1;
3003
3004         return 0;
3005 }
3006
3007 int test_align_parameters(isl_ctx *ctx)
3008 {
3009         const char *str;
3010         isl_space *space;
3011         isl_multi_aff *ma1, *ma2;
3012         int equal;
3013
3014         str = "{ A[B[] -> C[]] -> D[E[] -> F[]] }";
3015         ma1 = isl_multi_aff_read_from_str(ctx, str);
3016
3017         space = isl_space_params_alloc(ctx, 1);
3018         space = isl_space_set_dim_name(space, isl_dim_param, 0, "N");
3019         ma1 = isl_multi_aff_align_params(ma1, space);
3020
3021         str = "[N] -> { A[B[] -> C[]] -> D[E[] -> F[]] }";
3022         ma2 = isl_multi_aff_read_from_str(ctx, str);
3023
3024         equal = isl_multi_aff_plain_is_equal(ma1, ma2);
3025
3026         isl_multi_aff_free(ma1);
3027         isl_multi_aff_free(ma2);
3028
3029         if (equal < 0)
3030                 return -1;
3031         if (!equal)
3032                 isl_die(ctx, isl_error_unknown,
3033                         "result not as expected", return -1);
3034
3035         return 0;
3036 }
3037
3038 struct {
3039         const char *name;
3040         int (*fn)(isl_ctx *ctx);
3041 } tests [] = {
3042         { "align parameters", &test_align_parameters },
3043         { "eliminate", &test_eliminate },
3044         { "div", &test_div },
3045         { "slice", &test_slice },
3046         { "fixed power", &test_fixed_power },
3047         { "sample", &test_sample },
3048         { "output", &test_output },
3049         { "vertices", &test_vertices },
3050         { "fixed", &test_fixed },
3051         { "equal", &test_equal },
3052         { "product", &test_product },
3053         { "dim_max", &test_dim_max },
3054         { "affine", &test_aff },
3055         { "injective", &test_injective },
3056         { "schedule", &test_schedule },
3057         { "union_pw", &test_union_pw },
3058         { "parse", &test_parse },
3059         { "single-valued", &test_sv },
3060         { "affine hull", &test_affine_hull },
3061         { "coalesce", &test_coalesce },
3062         { "factorize", &test_factorize },
3063 };
3064
3065 int main()
3066 {
3067         int i;
3068         struct isl_ctx *ctx;
3069
3070         srcdir = getenv("srcdir");
3071         assert(srcdir);
3072
3073         ctx = isl_ctx_alloc();
3074         for (i = 0; i < ARRAY_SIZE(tests); ++i) {
3075                 printf("%s\n", tests[i].name);
3076                 if (tests[i].fn(ctx) < 0)
3077                         goto error;
3078         }
3079         test_subset(ctx);
3080         test_lift(ctx);
3081         test_bound(ctx);
3082         test_union(ctx);
3083         test_split_periods(ctx);
3084         test_pwqp(ctx);
3085         test_lex(ctx);
3086         test_bijective(ctx);
3087         test_dep(ctx);
3088         test_read(ctx);
3089         test_bounded(ctx);
3090         test_construction(ctx);
3091         test_dim(ctx);
3092         test_application(ctx);
3093         test_convex_hull(ctx);
3094         test_gist(ctx);
3095         test_closure(ctx);
3096         test_lexmin(ctx);
3097         isl_ctx_free(ctx);
3098         return 0;
3099 error:
3100         isl_ctx_free(ctx);
3101         return -1;
3102 }