1/*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010      INRIA Saclay
4 * Copyright 2012-2014 Ecole Normale Superieure
5 * Copyright 2014      INRIA Rocquencourt
6 * Copyright 2016      INRIA Paris
7 * Copyright 2016      Sven Verdoolaege
8 * Copyright 2018-2019 Cerebras Systems
9 * Copyright 2022      Cerebras Systems
10 *
11 * Use of this software is governed by the MIT license
12 *
13 * Written by Sven Verdoolaege, K.U.Leuven, Departement
14 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
15 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
16 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
17 * and Ecole Normale Superieure, 45 rue d���Ulm, 75230 Paris, France
18 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
19 * B.P. 105 - 78153 Le Chesnay, France
20 * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12,
21 * CS 42112, 75589 Paris Cedex 12, France
22 * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
23 */
24
25#include <string.h>
26#include <isl_ctx_private.h>
27#include <isl_map_private.h>
28#include <isl_blk.h>
29#include <isl_id_private.h>
30#include <isl/constraint.h>
31#include "isl_space_private.h"
32#include "isl_equalities.h"
33#include <isl_lp_private.h>
34#include <isl_seq.h>
35#include <isl/set.h>
36#include <isl/map.h>
37#include <isl_reordering.h>
38#include "isl_sample.h"
39#include <isl_sort.h>
40#include "isl_tab.h"
41#include <isl/vec.h>
42#include <isl_mat_private.h>
43#include <isl_vec_private.h>
44#include <isl_dim_map.h>
45#include <isl_local_space_private.h>
46#include <isl_aff_private.h>
47#include <isl_options_private.h>
48#include <isl_morph.h>
49#include <isl_val_private.h>
50#include <isl_printer_private.h>
51
52#include <bset_to_bmap.c>
53#include <bset_from_bmap.c>
54#include <set_to_map.c>
55#include <set_from_map.c>
56
57/* Treat "bset" as a basic map.
58 * Internally, isl_basic_set is defined to isl_basic_map, so in practice,
59 * this function performs a redundant cast.
60 */
61static __isl_keep const isl_basic_map *const_bset_to_bmap(
62	__isl_keep const isl_basic_set *bset)
63{
64	return (const isl_basic_map *) bset;
65}
66
67#undef TYPE
68#define TYPE	isl_basic_map
69#include "has_single_reference_templ.c"
70
71static unsigned pos(__isl_keep isl_space *space, enum isl_dim_type type)
72{
73	switch (type) {
74	case isl_dim_param:	return 1;
75	case isl_dim_in:	return 1 + space->nparam;
76	case isl_dim_out:	return 1 + space->nparam + space->n_in;
77	default:		return 0;
78	}
79}
80
81isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap,
82				enum isl_dim_type type)
83{
84	if (!bmap)
85		return isl_size_error;
86	switch (type) {
87	case isl_dim_cst:	return 1;
88	case isl_dim_param:
89	case isl_dim_in:
90	case isl_dim_out:	return isl_space_dim(bmap->dim, type);
91	case isl_dim_div:	return bmap->n_div;
92	case isl_dim_all:	return isl_basic_map_total_dim(bmap);
93	default:		return 0;
94	}
95}
96
97/* Return the space of "map".
98 */
99__isl_keep isl_space *isl_map_peek_space(__isl_keep const isl_map *map)
100{
101	return map ? map->dim : NULL;
102}
103
104/* Return the space of "set".
105 */
106__isl_keep isl_space *isl_set_peek_space(__isl_keep isl_set *set)
107{
108	return isl_map_peek_space(set_to_map(set));
109}
110
111isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type)
112{
113	return isl_space_dim(isl_map_peek_space(map), type);
114}
115
116/* Return the dimensionality of the domain (tuple) of the map.
117 */
118isl_size isl_map_domain_tuple_dim(__isl_keep isl_map *map)
119{
120	return isl_map_dim(map, isl_dim_in);
121}
122
123/* Return the dimensionality of the range (tuple) of the map.
124 */
125isl_size isl_map_range_tuple_dim(__isl_keep isl_map *map)
126{
127	return isl_map_dim(map, isl_dim_out);
128}
129
130isl_size isl_set_dim(__isl_keep isl_set *set, enum isl_dim_type type)
131{
132	return isl_map_dim(set_to_map(set), type);
133}
134
135/* Return the dimensionality of the (tuple of the) set.
136 */
137isl_size isl_set_tuple_dim(__isl_keep isl_set *set)
138{
139	return isl_set_dim(set, isl_dim_set);
140}
141
142/* Return the position of the variables of the given type
143 * within the sequence of variables of "bmap".
144 */
145isl_size isl_basic_map_var_offset(__isl_keep isl_basic_map *bmap,
146	enum isl_dim_type type)
147{
148	isl_space *space;
149
150	space = isl_basic_map_peek_space(bmap);
151
152	switch (type) {
153	case isl_dim_param:
154	case isl_dim_in:
155	case isl_dim_out:	return isl_space_offset(space, type);
156	case isl_dim_div:	return isl_space_dim(space, isl_dim_all);
157	case isl_dim_cst:
158	default:
159		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
160			"invalid dimension type", return isl_size_error);
161	}
162}
163
164/* Return the position of the variables of the given type
165 * within the sequence of variables of "bset".
166 */
167isl_size isl_basic_set_var_offset(__isl_keep isl_basic_set *bset,
168	enum isl_dim_type type)
169{
170	return isl_basic_map_var_offset(bset_to_bmap(bset), type);
171}
172
173/* Return the position of the coefficients of the variables of the given type
174 * within the sequence of coefficients of "bmap".
175 */
176unsigned isl_basic_map_offset(__isl_keep isl_basic_map *bmap,
177	enum isl_dim_type type)
178{
179	switch (type) {
180	case isl_dim_cst:	return 0;
181	case isl_dim_param:
182	case isl_dim_in:
183	case isl_dim_out:
184	case isl_dim_div:	return 1 + isl_basic_map_var_offset(bmap, type);
185	default:		return 0;
186	}
187}
188
189unsigned isl_basic_set_offset(__isl_keep isl_basic_set *bset,
190					enum isl_dim_type type)
191{
192	return isl_basic_map_offset(bset, type);
193}
194
195static unsigned map_offset(__isl_keep isl_map *map, enum isl_dim_type type)
196{
197	return pos(map->dim, type);
198}
199
200isl_size isl_basic_set_dim(__isl_keep isl_basic_set *bset,
201				enum isl_dim_type type)
202{
203	return isl_basic_map_dim(bset, type);
204}
205
206isl_size isl_basic_set_n_dim(__isl_keep isl_basic_set *bset)
207{
208	return isl_basic_set_dim(bset, isl_dim_set);
209}
210
211isl_size isl_basic_set_n_param(__isl_keep isl_basic_set *bset)
212{
213	return isl_basic_set_dim(bset, isl_dim_param);
214}
215
216isl_size isl_basic_set_total_dim(__isl_keep const isl_basic_set *bset)
217{
218	return isl_basic_map_total_dim(const_bset_to_bmap(bset));
219}
220
221isl_size isl_set_n_dim(__isl_keep isl_set *set)
222{
223	return isl_set_dim(set, isl_dim_set);
224}
225
226isl_size isl_set_n_param(__isl_keep isl_set *set)
227{
228	return isl_set_dim(set, isl_dim_param);
229}
230
231isl_size isl_basic_map_total_dim(__isl_keep const isl_basic_map *bmap)
232{
233	isl_size dim;
234
235	if (!bmap)
236		return isl_size_error;
237	dim = isl_space_dim(bmap->dim, isl_dim_all);
238	if (dim < 0)
239		return isl_size_error;
240	return dim + bmap->n_div;
241}
242
243/* Return the number of equality constraints in the description of "bmap".
244 * Return isl_size_error on error.
245 */
246isl_size isl_basic_map_n_equality(__isl_keep isl_basic_map *bmap)
247{
248	if (!bmap)
249		return isl_size_error;
250	return bmap->n_eq;
251}
252
253/* Return the number of equality constraints in the description of "bset".
254 * Return isl_size_error on error.
255 */
256isl_size isl_basic_set_n_equality(__isl_keep isl_basic_set *bset)
257{
258	return isl_basic_map_n_equality(bset_to_bmap(bset));
259}
260
261/* Return the number of inequality constraints in the description of "bmap".
262 * Return isl_size_error on error.
263 */
264isl_size isl_basic_map_n_inequality(__isl_keep isl_basic_map *bmap)
265{
266	if (!bmap)
267		return isl_size_error;
268	return bmap->n_ineq;
269}
270
271/* Return the number of inequality constraints in the description of "bset".
272 * Return isl_size_error on error.
273 */
274isl_size isl_basic_set_n_inequality(__isl_keep isl_basic_set *bset)
275{
276	return isl_basic_map_n_inequality(bset_to_bmap(bset));
277}
278
279/* Do "bmap1" and "bmap2" have the same parameters?
280 */
281static isl_bool isl_basic_map_has_equal_params(__isl_keep isl_basic_map *bmap1,
282	__isl_keep isl_basic_map *bmap2)
283{
284	isl_space *space1, *space2;
285
286	space1 = isl_basic_map_peek_space(bmap1);
287	space2 = isl_basic_map_peek_space(bmap2);
288	return isl_space_has_equal_params(space1, space2);
289}
290
291/* Do "map1" and "map2" have the same parameters?
292 */
293isl_bool isl_map_has_equal_params(__isl_keep isl_map *map1,
294	__isl_keep isl_map *map2)
295{
296	isl_space *space1, *space2;
297
298	space1 = isl_map_peek_space(map1);
299	space2 = isl_map_peek_space(map2);
300	return isl_space_has_equal_params(space1, space2);
301}
302
303/* Do "map" and "set" have the same parameters?
304 */
305static isl_bool isl_map_set_has_equal_params(__isl_keep isl_map *map,
306	__isl_keep isl_set *set)
307{
308	return isl_map_has_equal_params(map, set_to_map(set));
309}
310
311/* Is the tuple of type "type" of "bmap" the same as the single tuple of "bset"?
312 */
313static isl_bool isl_basic_map_set_tuple_is_equal(__isl_keep isl_basic_map *bmap,
314	enum isl_dim_type type, __isl_keep isl_basic_set *bset)
315{
316	isl_space *bmap_space, *bset_space;
317
318	bmap_space = isl_basic_map_peek_space(bmap);
319	bset_space = isl_basic_set_peek_space(bset);
320	return isl_space_tuple_is_equal(bmap_space, type,
321					bset_space, isl_dim_set);
322}
323
324/* Is the tuple of type "type" of "map" the same as the single tuple of "set"?
325 */
326static isl_bool isl_map_set_tuple_is_equal(__isl_keep isl_map *map,
327	enum isl_dim_type type, __isl_keep isl_set *set)
328{
329	return isl_map_tuple_is_equal(map, type, set_to_map(set), isl_dim_set);
330}
331
332isl_bool isl_map_compatible_domain(__isl_keep isl_map *map,
333	__isl_keep isl_set *set)
334{
335	isl_bool m;
336	if (!map || !set)
337		return isl_bool_error;
338	m = isl_map_has_equal_params(map, set_to_map(set));
339	if (m < 0 || !m)
340		return m;
341	return isl_map_set_tuple_is_equal(map, isl_dim_in, set);
342}
343
344isl_bool isl_basic_map_compatible_domain(__isl_keep isl_basic_map *bmap,
345	__isl_keep isl_basic_set *bset)
346{
347	isl_bool m;
348	if (!bmap || !bset)
349		return isl_bool_error;
350	m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
351	if (m < 0 || !m)
352		return m;
353	return isl_basic_map_set_tuple_is_equal(bmap, isl_dim_in, bset);
354}
355
356isl_bool isl_map_compatible_range(__isl_keep isl_map *map,
357	__isl_keep isl_set *set)
358{
359	isl_bool m;
360	if (!map || !set)
361		return isl_bool_error;
362	m = isl_map_has_equal_params(map, set_to_map(set));
363	if (m < 0 || !m)
364		return m;
365	return isl_map_set_tuple_is_equal(map, isl_dim_out, set);
366}
367
368isl_bool isl_basic_map_compatible_range(__isl_keep isl_basic_map *bmap,
369	__isl_keep isl_basic_set *bset)
370{
371	isl_bool m;
372	if (!bmap || !bset)
373		return isl_bool_error;
374	m = isl_basic_map_has_equal_params(bmap, bset_to_bmap(bset));
375	if (m < 0 || !m)
376		return m;
377	return isl_basic_map_set_tuple_is_equal(bmap, isl_dim_out, bset);
378}
379
380isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap)
381{
382	return bmap ? bmap->ctx : NULL;
383}
384
385isl_ctx *isl_basic_set_get_ctx(__isl_keep isl_basic_set *bset)
386{
387	return bset ? bset->ctx : NULL;
388}
389
390isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map)
391{
392	return map ? map->ctx : NULL;
393}
394
395isl_ctx *isl_set_get_ctx(__isl_keep isl_set *set)
396{
397	return set ? set->ctx : NULL;
398}
399
400/* Return the space of "bmap".
401 */
402__isl_keep isl_space *isl_basic_map_peek_space(
403	__isl_keep const isl_basic_map *bmap)
404{
405	return bmap ? bmap->dim : NULL;
406}
407
408/* Return the space of "bset".
409 */
410__isl_keep isl_space *isl_basic_set_peek_space(__isl_keep isl_basic_set *bset)
411{
412	return isl_basic_map_peek_space(bset_to_bmap(bset));
413}
414
415__isl_give isl_space *isl_basic_map_get_space(__isl_keep isl_basic_map *bmap)
416{
417	return isl_space_copy(isl_basic_map_peek_space(bmap));
418}
419
420__isl_give isl_space *isl_basic_set_get_space(__isl_keep isl_basic_set *bset)
421{
422	return isl_basic_map_get_space(bset_to_bmap(bset));
423}
424
425/* Return the space of "bmap".
426 * This may be either a copy or the space itself
427 * if there is only one reference to "bmap".
428 * This allows the space to be modified inplace
429 * if both the basic map and its space have only a single reference.
430 * The caller is not allowed to modify "bmap" between this call and
431 * a subsequent call to isl_basic_map_restore_space.
432 * The only exception is that isl_basic_map_free can be called instead.
433 */
434static __isl_give isl_space *isl_basic_map_take_space(
435	__isl_keep isl_basic_map *bmap)
436{
437	isl_space *space;
438
439	if (!bmap)
440		return NULL;
441	if (bmap->ref != 1)
442		return isl_basic_map_get_space(bmap);
443	space = bmap->dim;
444	bmap->dim = NULL;
445	return space;
446}
447
448/* Set the space of "bmap" to "space", where the space of "bmap" may be missing
449 * due to a preceding call to isl_basic_map_take_space.
450 * However, in this case, "bmap" only has a single reference and
451 * then the call to isl_basic_map_cow has no effect.
452 */
453static __isl_give isl_basic_map *isl_basic_map_restore_space(
454	__isl_take isl_basic_map *bmap, __isl_take isl_space *space)
455{
456	if (!bmap || !space)
457		goto error;
458
459	if (bmap->dim == space) {
460		isl_space_free(space);
461		return bmap;
462	}
463
464	bmap = isl_basic_map_cow(bmap);
465	if (!bmap)
466		goto error;
467	isl_space_free(bmap->dim);
468	bmap->dim = space;
469
470	return bmap;
471error:
472	isl_basic_map_free(bmap);
473	isl_space_free(space);
474	return NULL;
475}
476
477/* Extract the divs in "bmap" as a matrix.
478 */
479__isl_give isl_mat *isl_basic_map_get_divs(__isl_keep isl_basic_map *bmap)
480{
481	int i;
482	isl_ctx *ctx;
483	isl_mat *div;
484	isl_size v_div;
485	unsigned cols;
486
487	v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
488	if (v_div < 0)
489		return NULL;
490
491	ctx = isl_basic_map_get_ctx(bmap);
492	cols = 1 + 1 + v_div + bmap->n_div;
493	div = isl_mat_alloc(ctx, bmap->n_div, cols);
494	if (!div)
495		return NULL;
496
497	for (i = 0; i < bmap->n_div; ++i)
498		isl_seq_cpy(div->row[i], bmap->div[i], cols);
499
500	return div;
501}
502
503/* Extract the divs in "bset" as a matrix.
504 */
505__isl_give isl_mat *isl_basic_set_get_divs(__isl_keep isl_basic_set *bset)
506{
507	return isl_basic_map_get_divs(bset);
508}
509
510__isl_give isl_local_space *isl_basic_map_get_local_space(
511	__isl_keep isl_basic_map *bmap)
512{
513	isl_mat *div;
514
515	if (!bmap)
516		return NULL;
517
518	div = isl_basic_map_get_divs(bmap);
519	return isl_local_space_alloc_div(isl_space_copy(bmap->dim), div);
520}
521
522__isl_give isl_local_space *isl_basic_set_get_local_space(
523	__isl_keep isl_basic_set *bset)
524{
525	return isl_basic_map_get_local_space(bset);
526}
527
528/* For each known div d = floor(f/m), add the constraints
529 *
530 *		f - m d >= 0
531 *		-(f-(m-1)) + m d >= 0
532 *
533 * Do not finalize the result.
534 */
535static __isl_give isl_basic_map *add_known_div_constraints(
536	__isl_take isl_basic_map *bmap)
537{
538	int i;
539	isl_size n_div;
540
541	n_div = isl_basic_map_dim(bmap, isl_dim_div);
542	if (n_div < 0)
543		return isl_basic_map_free(bmap);
544	if (n_div == 0)
545		return bmap;
546	bmap = isl_basic_map_cow(bmap);
547	bmap = isl_basic_map_extend_constraints(bmap, 0, 2 * n_div);
548	if (!bmap)
549		return NULL;
550	for (i = 0; i < n_div; ++i) {
551		if (isl_int_is_zero(bmap->div[i][0]))
552			continue;
553		bmap = isl_basic_map_add_div_constraints(bmap, i);
554	}
555
556	return bmap;
557}
558
559__isl_give isl_basic_map *isl_basic_map_from_local_space(
560	__isl_take isl_local_space *ls)
561{
562	int i;
563	isl_size n_div;
564	isl_basic_map *bmap;
565
566	n_div = isl_local_space_dim(ls, isl_dim_div);
567	if (n_div < 0)
568		ls = isl_local_space_free(ls);
569	if (!ls)
570		return NULL;
571
572	bmap = isl_basic_map_alloc_space(isl_local_space_get_space(ls),
573					n_div, 0, 2 * n_div);
574
575	for (i = 0; i < n_div; ++i)
576		if (isl_basic_map_alloc_div(bmap) < 0)
577			goto error;
578
579	for (i = 0; i < n_div; ++i)
580		isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
581	bmap = add_known_div_constraints(bmap);
582
583	isl_local_space_free(ls);
584	return bmap;
585error:
586	isl_local_space_free(ls);
587	isl_basic_map_free(bmap);
588	return NULL;
589}
590
591__isl_give isl_basic_set *isl_basic_set_from_local_space(
592	__isl_take isl_local_space *ls)
593{
594	return isl_basic_map_from_local_space(ls);
595}
596
597__isl_give isl_space *isl_map_get_space(__isl_keep isl_map *map)
598{
599	return isl_space_copy(isl_map_peek_space(map));
600}
601
602__isl_give isl_space *isl_set_get_space(__isl_keep isl_set *set)
603{
604	if (!set)
605		return NULL;
606	return isl_space_copy(set->dim);
607}
608
609/* Return the space of "map".
610 * This may be either a copy or the space itself
611 * if there is only one reference to "map".
612 * This allows the space to be modified inplace
613 * if both the map and its space have only a single reference.
614 * The caller is not allowed to modify "map" between this call and
615 * a subsequent call to isl_map_restore_space.
616 * The only exception is that isl_map_free can be called instead.
617 */
618static __isl_give isl_space *isl_map_take_space(__isl_keep isl_map *map)
619{
620	isl_space *space;
621
622	if (!map)
623		return NULL;
624	if (map->ref != 1)
625		return isl_map_get_space(map);
626	space = map->dim;
627	map->dim = NULL;
628	return space;
629}
630
631/* Set the space of "map" to "space", where the space of "map" may be missing
632 * due to a preceding call to isl_map_take_space.
633 * However, in this case, "map" only has a single reference and
634 * then the call to isl_map_cow has no effect.
635 */
636static __isl_give isl_map *isl_map_restore_space(__isl_take isl_map *map,
637	__isl_take isl_space *space)
638{
639	if (!map || !space)
640		goto error;
641
642	if (map->dim == space) {
643		isl_space_free(space);
644		return map;
645	}
646
647	map = isl_map_cow(map);
648	if (!map)
649		goto error;
650	isl_space_free(map->dim);
651	map->dim = space;
652
653	return map;
654error:
655	isl_map_free(map);
656	isl_space_free(space);
657	return NULL;
658}
659
660__isl_give isl_basic_map *isl_basic_map_set_tuple_name(
661	__isl_take isl_basic_map *bmap, enum isl_dim_type type, const char *s)
662{
663	isl_space *space;
664
665	space = isl_basic_map_take_space(bmap);
666	space = isl_space_set_tuple_name(space, type, s);
667	bmap = isl_basic_map_restore_space(bmap, space);
668	bmap = isl_basic_map_finalize(bmap);
669	return bmap;
670}
671
672__isl_give isl_basic_set *isl_basic_set_set_tuple_name(
673	__isl_take isl_basic_set *bset, const char *s)
674{
675	return isl_basic_map_set_tuple_name(bset, isl_dim_set, s);
676}
677
678const char *isl_basic_map_get_tuple_name(__isl_keep isl_basic_map *bmap,
679	enum isl_dim_type type)
680{
681	return bmap ? isl_space_get_tuple_name(bmap->dim, type) : NULL;
682}
683
684__isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map,
685	enum isl_dim_type type, const char *s)
686{
687	int i;
688	isl_space *space;
689
690	map = isl_map_cow(map);
691	if (!map)
692		return NULL;
693
694	for (i = 0; i < map->n; ++i) {
695		map->p[i] = isl_basic_map_set_tuple_name(map->p[i], type, s);
696		if (!map->p[i])
697			goto error;
698	}
699
700	space = isl_map_take_space(map);
701	space = isl_space_set_tuple_name(space, type, s);
702	map = isl_map_restore_space(map, space);
703
704	return map;
705error:
706	isl_map_free(map);
707	return NULL;
708}
709
710/* Replace the identifier of the tuple of type "type" by "id".
711 */
712__isl_give isl_basic_map *isl_basic_map_set_tuple_id(
713	__isl_take isl_basic_map *bmap,
714	enum isl_dim_type type, __isl_take isl_id *id)
715{
716	isl_space *space;
717
718	space = isl_basic_map_take_space(bmap);
719	space = isl_space_set_tuple_id(space, type, id);
720	bmap = isl_basic_map_restore_space(bmap, space);
721	bmap = isl_basic_map_finalize(bmap);
722	return bmap;
723}
724
725/* Replace the identifier of the tuple by "id".
726 */
727__isl_give isl_basic_set *isl_basic_set_set_tuple_id(
728	__isl_take isl_basic_set *bset, __isl_take isl_id *id)
729{
730	return isl_basic_map_set_tuple_id(bset, isl_dim_set, id);
731}
732
733/* Does the input or output tuple have a name?
734 */
735isl_bool isl_map_has_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type)
736{
737	return map ? isl_space_has_tuple_name(map->dim, type) : isl_bool_error;
738}
739
740const char *isl_map_get_tuple_name(__isl_keep isl_map *map,
741	enum isl_dim_type type)
742{
743	return map ? isl_space_get_tuple_name(map->dim, type) : NULL;
744}
745
746__isl_give isl_set *isl_set_set_tuple_name(__isl_take isl_set *set,
747	const char *s)
748{
749	return set_from_map(isl_map_set_tuple_name(set_to_map(set),
750						isl_dim_set, s));
751}
752
753__isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map,
754	enum isl_dim_type type, __isl_take isl_id *id)
755{
756	isl_space *space;
757
758	space = isl_map_take_space(map);
759	space = isl_space_set_tuple_id(space, type, id);
760	map = isl_map_restore_space(map, space);
761
762	return isl_map_reset_space(map, isl_map_get_space(map));
763}
764
765/* Replace the identifier of the domain tuple of "map" by "id".
766 */
767__isl_give isl_map *isl_map_set_domain_tuple_id(__isl_take isl_map *map,
768	__isl_take isl_id *id)
769{
770	return isl_map_set_tuple_id(map, isl_dim_in, id);
771}
772
773/* Replace the identifier of the range tuple of "map" by "id".
774 */
775__isl_give isl_map *isl_map_set_range_tuple_id(__isl_take isl_map *map,
776	__isl_take isl_id *id)
777{
778	return isl_map_set_tuple_id(map, isl_dim_out, id);
779}
780
781__isl_give isl_set *isl_set_set_tuple_id(__isl_take isl_set *set,
782	__isl_take isl_id *id)
783{
784	return isl_map_set_tuple_id(set, isl_dim_set, id);
785}
786
787__isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map,
788	enum isl_dim_type type)
789{
790	isl_space *space;
791
792	space = isl_map_take_space(map);
793	space = isl_space_reset_tuple_id(space, type);
794	map = isl_map_restore_space(map, space);
795
796	return isl_map_reset_space(map, isl_map_get_space(map));
797}
798
799__isl_give isl_set *isl_set_reset_tuple_id(__isl_take isl_set *set)
800{
801	return isl_map_reset_tuple_id(set, isl_dim_set);
802}
803
804isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type)
805{
806	return map ? isl_space_has_tuple_id(map->dim, type) : isl_bool_error;
807}
808
809/* Does the domain tuple of "map" have an identifier?
810 */
811isl_bool isl_map_has_domain_tuple_id(__isl_keep isl_map *map)
812{
813	return isl_map_has_tuple_id(map, isl_dim_in);
814}
815
816/* Does the range tuple of "map" have an identifier?
817 */
818isl_bool isl_map_has_range_tuple_id(__isl_keep isl_map *map)
819{
820	return isl_map_has_tuple_id(map, isl_dim_out);
821}
822
823__isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map,
824	enum isl_dim_type type)
825{
826	return map ? isl_space_get_tuple_id(map->dim, type) : NULL;
827}
828
829/* Return the identifier of the domain tuple of "map", assuming it has one.
830 */
831__isl_give isl_id *isl_map_get_domain_tuple_id(__isl_keep isl_map *map)
832{
833	return isl_map_get_tuple_id(map, isl_dim_in);
834}
835
836/* Return the identifier of the range tuple of "map", assuming it has one.
837 */
838__isl_give isl_id *isl_map_get_range_tuple_id(__isl_keep isl_map *map)
839{
840	return isl_map_get_tuple_id(map, isl_dim_out);
841}
842
843isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set)
844{
845	return isl_map_has_tuple_id(set, isl_dim_set);
846}
847
848__isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_set *set)
849{
850	return isl_map_get_tuple_id(set, isl_dim_set);
851}
852
853/* Does the set tuple have a name?
854 */
855isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set)
856{
857	if (!set)
858		return isl_bool_error;
859	return isl_space_has_tuple_name(set->dim, isl_dim_set);
860}
861
862
863const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_set *bset)
864{
865	return bset ? isl_space_get_tuple_name(bset->dim, isl_dim_set) : NULL;
866}
867
868const char *isl_set_get_tuple_name(__isl_keep isl_set *set)
869{
870	return set ? isl_space_get_tuple_name(set->dim, isl_dim_set) : NULL;
871}
872
873const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap,
874	enum isl_dim_type type, unsigned pos)
875{
876	return bmap ? isl_space_get_dim_name(bmap->dim, type, pos) : NULL;
877}
878
879const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_set *bset,
880	enum isl_dim_type type, unsigned pos)
881{
882	return bset ? isl_space_get_dim_name(bset->dim, type, pos) : NULL;
883}
884
885/* Does the given dimension have a name?
886 */
887isl_bool isl_map_has_dim_name(__isl_keep isl_map *map,
888	enum isl_dim_type type, unsigned pos)
889{
890	if (!map)
891		return isl_bool_error;
892	return isl_space_has_dim_name(map->dim, type, pos);
893}
894
895const char *isl_map_get_dim_name(__isl_keep isl_map *map,
896	enum isl_dim_type type, unsigned pos)
897{
898	return map ? isl_space_get_dim_name(map->dim, type, pos) : NULL;
899}
900
901const char *isl_set_get_dim_name(__isl_keep isl_set *set,
902	enum isl_dim_type type, unsigned pos)
903{
904	return set ? isl_space_get_dim_name(set->dim, type, pos) : NULL;
905}
906
907/* Does the given dimension have a name?
908 */
909isl_bool isl_set_has_dim_name(__isl_keep isl_set *set,
910	enum isl_dim_type type, unsigned pos)
911{
912	if (!set)
913		return isl_bool_error;
914	return isl_space_has_dim_name(set->dim, type, pos);
915}
916
917__isl_give isl_basic_map *isl_basic_map_set_dim_name(
918	__isl_take isl_basic_map *bmap,
919	enum isl_dim_type type, unsigned pos, const char *s)
920{
921	isl_space *space;
922
923	space = isl_basic_map_take_space(bmap);
924	space = isl_space_set_dim_name(space, type, pos, s);
925	bmap = isl_basic_map_restore_space(bmap, space);
926	return isl_basic_map_finalize(bmap);
927}
928
929__isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map,
930	enum isl_dim_type type, unsigned pos, const char *s)
931{
932	int i;
933	isl_space *space;
934
935	map = isl_map_cow(map);
936	if (!map)
937		return NULL;
938
939	for (i = 0; i < map->n; ++i) {
940		map->p[i] = isl_basic_map_set_dim_name(map->p[i], type, pos, s);
941		if (!map->p[i])
942			goto error;
943	}
944
945	space = isl_map_take_space(map);
946	space = isl_space_set_dim_name(space, type, pos, s);
947	map = isl_map_restore_space(map, space);
948
949	return map;
950error:
951	isl_map_free(map);
952	return NULL;
953}
954
955__isl_give isl_basic_set *isl_basic_set_set_dim_name(
956	__isl_take isl_basic_set *bset,
957	enum isl_dim_type type, unsigned pos, const char *s)
958{
959	return bset_from_bmap(isl_basic_map_set_dim_name(bset_to_bmap(bset),
960							type, pos, s));
961}
962
963__isl_give isl_set *isl_set_set_dim_name(__isl_take isl_set *set,
964	enum isl_dim_type type, unsigned pos, const char *s)
965{
966	return set_from_map(isl_map_set_dim_name(set_to_map(set),
967							type, pos, s));
968}
969
970isl_bool isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap,
971	enum isl_dim_type type, unsigned pos)
972{
973	if (!bmap)
974		return isl_bool_error;
975	return isl_space_has_dim_id(bmap->dim, type, pos);
976}
977
978__isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_set *bset,
979	enum isl_dim_type type, unsigned pos)
980{
981	return bset ? isl_space_get_dim_id(bset->dim, type, pos) : NULL;
982}
983
984isl_bool isl_map_has_dim_id(__isl_keep isl_map *map,
985	enum isl_dim_type type, unsigned pos)
986{
987	return map ? isl_space_has_dim_id(map->dim, type, pos) : isl_bool_error;
988}
989
990__isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map,
991	enum isl_dim_type type, unsigned pos)
992{
993	return map ? isl_space_get_dim_id(map->dim, type, pos) : NULL;
994}
995
996isl_bool isl_set_has_dim_id(__isl_keep isl_set *set,
997	enum isl_dim_type type, unsigned pos)
998{
999	return isl_map_has_dim_id(set, type, pos);
1000}
1001
1002__isl_give isl_id *isl_set_get_dim_id(__isl_keep isl_set *set,
1003	enum isl_dim_type type, unsigned pos)
1004{
1005	return isl_map_get_dim_id(set, type, pos);
1006}
1007
1008__isl_give isl_map *isl_map_set_dim_id(__isl_take isl_map *map,
1009	enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
1010{
1011	isl_space *space;
1012
1013	space = isl_map_take_space(map);
1014	space = isl_space_set_dim_id(space, type, pos, id);
1015	map = isl_map_restore_space(map, space);
1016
1017	return isl_map_reset_space(map, isl_map_get_space(map));
1018}
1019
1020__isl_give isl_set *isl_set_set_dim_id(__isl_take isl_set *set,
1021	enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
1022{
1023	return isl_map_set_dim_id(set, type, pos, id);
1024}
1025
1026int isl_map_find_dim_by_id(__isl_keep isl_map *map, enum isl_dim_type type,
1027	__isl_keep isl_id *id)
1028{
1029	if (!map)
1030		return -1;
1031	return isl_space_find_dim_by_id(map->dim, type, id);
1032}
1033
1034int isl_set_find_dim_by_id(__isl_keep isl_set *set, enum isl_dim_type type,
1035	__isl_keep isl_id *id)
1036{
1037	return isl_map_find_dim_by_id(set, type, id);
1038}
1039
1040/* Return the position of the dimension of the given type and name
1041 * in "bmap".
1042 * Return -1 if no such dimension can be found.
1043 */
1044int isl_basic_map_find_dim_by_name(__isl_keep isl_basic_map *bmap,
1045	enum isl_dim_type type, const char *name)
1046{
1047	if (!bmap)
1048		return -1;
1049	return isl_space_find_dim_by_name(bmap->dim, type, name);
1050}
1051
1052int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type,
1053	const char *name)
1054{
1055	if (!map)
1056		return -1;
1057	return isl_space_find_dim_by_name(map->dim, type, name);
1058}
1059
1060int isl_set_find_dim_by_name(__isl_keep isl_set *set, enum isl_dim_type type,
1061	const char *name)
1062{
1063	return isl_map_find_dim_by_name(set, type, name);
1064}
1065
1066/* Check whether equality i of bset is a pure stride constraint
1067 * on a single dimension, i.e., of the form
1068 *
1069 *	v = k e
1070 *
1071 * with k a constant and e an existentially quantified variable.
1072 */
1073isl_bool isl_basic_set_eq_is_stride(__isl_keep isl_basic_set *bset, int i)
1074{
1075	isl_size nparam;
1076	isl_size d;
1077	isl_size n_div;
1078	int pos1;
1079	int pos2;
1080
1081	nparam = isl_basic_set_dim(bset, isl_dim_param);
1082	d = isl_basic_set_dim(bset, isl_dim_set);
1083	n_div = isl_basic_set_dim(bset, isl_dim_div);
1084	if (nparam < 0 || d < 0 || n_div < 0)
1085		return isl_bool_error;
1086
1087	if (!isl_int_is_zero(bset->eq[i][0]))
1088		return isl_bool_false;
1089
1090	if (isl_seq_first_non_zero(bset->eq[i] + 1, nparam) != -1)
1091		return isl_bool_false;
1092	pos1 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam, d);
1093	if (pos1 == -1)
1094		return isl_bool_false;
1095	if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + pos1 + 1,
1096					d - pos1 - 1) != -1)
1097		return isl_bool_false;
1098
1099	pos2 = isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d, n_div);
1100	if (pos2 == -1)
1101		return isl_bool_false;
1102	if (isl_seq_first_non_zero(bset->eq[i] + 1 + nparam + d  + pos2 + 1,
1103				   n_div - pos2 - 1) != -1)
1104		return isl_bool_false;
1105	if (!isl_int_is_one(bset->eq[i][1 + nparam + pos1]) &&
1106	    !isl_int_is_negone(bset->eq[i][1 + nparam + pos1]))
1107		return isl_bool_false;
1108
1109	return isl_bool_true;
1110}
1111
1112/* Reset the user pointer on all identifiers of parameters and tuples
1113 * of the space of "map".
1114 */
1115__isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map)
1116{
1117	isl_space *space;
1118
1119	space = isl_map_get_space(map);
1120	space = isl_space_reset_user(space);
1121	map = isl_map_reset_space(map, space);
1122
1123	return map;
1124}
1125
1126/* Reset the user pointer on all identifiers of parameters and tuples
1127 * of the space of "set".
1128 */
1129__isl_give isl_set *isl_set_reset_user(__isl_take isl_set *set)
1130{
1131	return isl_map_reset_user(set);
1132}
1133
1134isl_bool isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap)
1135{
1136	if (!bmap)
1137		return isl_bool_error;
1138	return ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL);
1139}
1140
1141/* Has "map" been marked as a rational map?
1142 * In particular, have all basic maps in "map" been marked this way?
1143 * An empty map is not considered to be rational.
1144 * Maps where only some of the basic maps are marked rational
1145 * are not allowed.
1146 */
1147isl_bool isl_map_is_rational(__isl_keep isl_map *map)
1148{
1149	int i;
1150	isl_bool rational;
1151
1152	if (!map)
1153		return isl_bool_error;
1154	if (map->n == 0)
1155		return isl_bool_false;
1156	rational = isl_basic_map_is_rational(map->p[0]);
1157	if (rational < 0)
1158		return rational;
1159	for (i = 1; i < map->n; ++i) {
1160		isl_bool rational_i;
1161
1162		rational_i = isl_basic_map_is_rational(map->p[i]);
1163		if (rational_i < 0)
1164			return rational_i;
1165		if (rational != rational_i)
1166			isl_die(isl_map_get_ctx(map), isl_error_unsupported,
1167				"mixed rational and integer basic maps "
1168				"not supported", return isl_bool_error);
1169	}
1170
1171	return rational;
1172}
1173
1174/* Has "set" been marked as a rational set?
1175 * In particular, have all basic set in "set" been marked this way?
1176 * An empty set is not considered to be rational.
1177 * Sets where only some of the basic sets are marked rational
1178 * are not allowed.
1179 */
1180isl_bool isl_set_is_rational(__isl_keep isl_set *set)
1181{
1182	return isl_map_is_rational(set);
1183}
1184
1185int isl_basic_set_is_rational(__isl_keep isl_basic_set *bset)
1186{
1187	return isl_basic_map_is_rational(bset);
1188}
1189
1190/* Does "bmap" contain any rational points?
1191 *
1192 * If "bmap" has an equality for each dimension, equating the dimension
1193 * to an integer constant, then it has no rational points, even if it
1194 * is marked as rational.
1195 */
1196isl_bool isl_basic_map_has_rational(__isl_keep isl_basic_map *bmap)
1197{
1198	isl_bool has_rational = isl_bool_true;
1199	isl_size total;
1200
1201	if (!bmap)
1202		return isl_bool_error;
1203	if (isl_basic_map_plain_is_empty(bmap))
1204		return isl_bool_false;
1205	if (!isl_basic_map_is_rational(bmap))
1206		return isl_bool_false;
1207	bmap = isl_basic_map_copy(bmap);
1208	bmap = isl_basic_map_implicit_equalities(bmap);
1209	total = isl_basic_map_dim(bmap, isl_dim_all);
1210	if (total < 0)
1211		return isl_bool_error;
1212	if (bmap->n_eq == total) {
1213		int i, j;
1214		for (i = 0; i < bmap->n_eq; ++i) {
1215			j = isl_seq_first_non_zero(bmap->eq[i] + 1, total);
1216			if (j < 0)
1217				break;
1218			if (!isl_int_is_one(bmap->eq[i][1 + j]) &&
1219			    !isl_int_is_negone(bmap->eq[i][1 + j]))
1220				break;
1221			j = isl_seq_first_non_zero(bmap->eq[i] + 1 + j + 1,
1222						    total - j - 1);
1223			if (j >= 0)
1224				break;
1225		}
1226		if (i == bmap->n_eq)
1227			has_rational = isl_bool_false;
1228	}
1229	isl_basic_map_free(bmap);
1230
1231	return has_rational;
1232}
1233
1234/* Does "map" contain any rational points?
1235 */
1236isl_bool isl_map_has_rational(__isl_keep isl_map *map)
1237{
1238	int i;
1239	isl_bool has_rational;
1240
1241	if (!map)
1242		return isl_bool_error;
1243	for (i = 0; i < map->n; ++i) {
1244		has_rational = isl_basic_map_has_rational(map->p[i]);
1245		if (has_rational < 0 || has_rational)
1246			return has_rational;
1247	}
1248	return isl_bool_false;
1249}
1250
1251/* Does "set" contain any rational points?
1252 */
1253isl_bool isl_set_has_rational(__isl_keep isl_set *set)
1254{
1255	return isl_map_has_rational(set);
1256}
1257
1258/* Is this basic set a parameter domain?
1259 */
1260isl_bool isl_basic_set_is_params(__isl_keep isl_basic_set *bset)
1261{
1262	if (!bset)
1263		return isl_bool_error;
1264	return isl_space_is_params(bset->dim);
1265}
1266
1267/* Is this set a parameter domain?
1268 */
1269isl_bool isl_set_is_params(__isl_keep isl_set *set)
1270{
1271	if (!set)
1272		return isl_bool_error;
1273	return isl_space_is_params(set->dim);
1274}
1275
1276/* Is this map actually a parameter domain?
1277 * Users should never call this function.  Outside of isl,
1278 * a map can never be a parameter domain.
1279 */
1280isl_bool isl_map_is_params(__isl_keep isl_map *map)
1281{
1282	if (!map)
1283		return isl_bool_error;
1284	return isl_space_is_params(map->dim);
1285}
1286
1287static __isl_give isl_basic_map *basic_map_init(isl_ctx *ctx,
1288	__isl_take isl_basic_map *bmap, unsigned extra,
1289	unsigned n_eq, unsigned n_ineq)
1290{
1291	int i;
1292	isl_space *space = isl_basic_map_peek_space(bmap);
1293	isl_size n_var = isl_space_dim(space, isl_dim_all);
1294	size_t row_size = 1 + n_var + extra;
1295
1296	bmap->ctx = ctx;
1297	isl_ctx_ref(ctx);
1298
1299	if (n_var < 0)
1300		return isl_basic_map_free(bmap);
1301
1302	bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size);
1303	if (isl_blk_is_error(bmap->block))
1304		goto error;
1305
1306	bmap->ineq = isl_alloc_array(ctx, isl_int *, n_ineq + n_eq);
1307	if ((n_ineq + n_eq) && !bmap->ineq)
1308		goto error;
1309
1310	if (extra == 0) {
1311		bmap->block2 = isl_blk_empty();
1312		bmap->div = NULL;
1313	} else {
1314		bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
1315		if (isl_blk_is_error(bmap->block2))
1316			goto error;
1317
1318		bmap->div = isl_alloc_array(ctx, isl_int *, extra);
1319		if (!bmap->div)
1320			goto error;
1321	}
1322
1323	for (i = 0; i < n_ineq + n_eq; ++i)
1324		bmap->ineq[i] = bmap->block.data + i * row_size;
1325
1326	for (i = 0; i < extra; ++i)
1327		bmap->div[i] = bmap->block2.data + i * (1 + row_size);
1328
1329	bmap->ref = 1;
1330	bmap->flags = 0;
1331	bmap->c_size = n_eq + n_ineq;
1332	bmap->eq = bmap->ineq + n_ineq;
1333	bmap->extra = extra;
1334	bmap->n_eq = 0;
1335	bmap->n_ineq = 0;
1336	bmap->n_div = 0;
1337	bmap->sample = NULL;
1338
1339	return bmap;
1340error:
1341	isl_basic_map_free(bmap);
1342	return NULL;
1343}
1344
1345__isl_give isl_basic_set *isl_basic_set_alloc(isl_ctx *ctx,
1346		unsigned nparam, unsigned dim, unsigned extra,
1347		unsigned n_eq, unsigned n_ineq)
1348{
1349	struct isl_basic_map *bmap;
1350	isl_space *space;
1351
1352	space = isl_space_set_alloc(ctx, nparam, dim);
1353	if (!space)
1354		return NULL;
1355
1356	bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
1357	return bset_from_bmap(bmap);
1358}
1359
1360__isl_give isl_basic_set *isl_basic_set_alloc_space(__isl_take isl_space *space,
1361		unsigned extra, unsigned n_eq, unsigned n_ineq)
1362{
1363	struct isl_basic_map *bmap;
1364	if (!space)
1365		return NULL;
1366	isl_assert(space->ctx, space->n_in == 0, goto error);
1367	bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
1368	return bset_from_bmap(bmap);
1369error:
1370	isl_space_free(space);
1371	return NULL;
1372}
1373
1374__isl_give isl_basic_map *isl_basic_map_alloc_space(__isl_take isl_space *space,
1375		unsigned extra, unsigned n_eq, unsigned n_ineq)
1376{
1377	struct isl_basic_map *bmap;
1378
1379	if (!space)
1380		return NULL;
1381	bmap = isl_calloc_type(space->ctx, struct isl_basic_map);
1382	if (!bmap)
1383		goto error;
1384	bmap->dim = space;
1385
1386	return basic_map_init(space->ctx, bmap, extra, n_eq, n_ineq);
1387error:
1388	isl_space_free(space);
1389	return NULL;
1390}
1391
1392__isl_give isl_basic_map *isl_basic_map_alloc(isl_ctx *ctx,
1393		unsigned nparam, unsigned in, unsigned out, unsigned extra,
1394		unsigned n_eq, unsigned n_ineq)
1395{
1396	struct isl_basic_map *bmap;
1397	isl_space *space;
1398
1399	space = isl_space_alloc(ctx, nparam, in, out);
1400	if (!space)
1401		return NULL;
1402
1403	bmap = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
1404	return bmap;
1405}
1406
1407static __isl_give isl_basic_map *dup_constraints(__isl_take isl_basic_map *dst,
1408	__isl_keep isl_basic_map *src)
1409{
1410	int i;
1411	isl_size total = isl_basic_map_dim(src, isl_dim_all);
1412
1413	if (!dst || total < 0)
1414		return isl_basic_map_free(dst);
1415
1416	for (i = 0; i < src->n_eq; ++i) {
1417		int j = isl_basic_map_alloc_equality(dst);
1418		if (j < 0)
1419			return isl_basic_map_free(dst);
1420		isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
1421	}
1422
1423	for (i = 0; i < src->n_ineq; ++i) {
1424		int j = isl_basic_map_alloc_inequality(dst);
1425		if (j < 0)
1426			return isl_basic_map_free(dst);
1427		isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
1428	}
1429
1430	for (i = 0; i < src->n_div; ++i) {
1431		int j = isl_basic_map_alloc_div(dst);
1432		if (j < 0)
1433			return isl_basic_map_free(dst);
1434		isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
1435	}
1436	ISL_F_SET(dst, ISL_BASIC_SET_FINAL);
1437	return dst;
1438}
1439
1440__isl_give isl_basic_map *isl_basic_map_dup(__isl_keep isl_basic_map *bmap)
1441{
1442	struct isl_basic_map *dup;
1443
1444	if (!bmap)
1445		return NULL;
1446	dup = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
1447			bmap->n_div, bmap->n_eq, bmap->n_ineq);
1448	dup = dup_constraints(dup, bmap);
1449	if (!dup)
1450		return NULL;
1451	dup->flags = bmap->flags;
1452	dup->sample = isl_vec_copy(bmap->sample);
1453	return dup;
1454}
1455
1456__isl_give isl_basic_set *isl_basic_set_dup(__isl_keep isl_basic_set *bset)
1457{
1458	struct isl_basic_map *dup;
1459
1460	dup = isl_basic_map_dup(bset_to_bmap(bset));
1461	return bset_from_bmap(dup);
1462}
1463
1464__isl_give isl_basic_set *isl_basic_set_copy(__isl_keep isl_basic_set *bset)
1465{
1466	return bset_from_bmap(isl_basic_map_copy(bset_to_bmap(bset)));
1467}
1468
1469__isl_give isl_set *isl_set_copy(__isl_keep isl_set *set)
1470{
1471	if (!set)
1472		return NULL;
1473
1474	set->ref++;
1475	return set;
1476}
1477
1478__isl_give isl_basic_map *isl_basic_map_copy(__isl_keep isl_basic_map *bmap)
1479{
1480	if (!bmap)
1481		return NULL;
1482
1483	if (ISL_F_ISSET(bmap, ISL_BASIC_SET_FINAL)) {
1484		bmap->ref++;
1485		return bmap;
1486	}
1487	bmap = isl_basic_map_dup(bmap);
1488	if (bmap)
1489		ISL_F_SET(bmap, ISL_BASIC_SET_FINAL);
1490	return bmap;
1491}
1492
1493__isl_give isl_map *isl_map_copy(__isl_keep isl_map *map)
1494{
1495	if (!map)
1496		return NULL;
1497
1498	map->ref++;
1499	return map;
1500}
1501
1502__isl_null isl_basic_map *isl_basic_map_free(__isl_take isl_basic_map *bmap)
1503{
1504	if (!bmap)
1505		return NULL;
1506
1507	if (--bmap->ref > 0)
1508		return NULL;
1509
1510	isl_ctx_deref(bmap->ctx);
1511	free(bmap->div);
1512	isl_blk_free(bmap->ctx, bmap->block2);
1513	free(bmap->ineq);
1514	isl_blk_free(bmap->ctx, bmap->block);
1515	isl_vec_free(bmap->sample);
1516	isl_space_free(bmap->dim);
1517	free(bmap);
1518
1519	return NULL;
1520}
1521
1522__isl_null isl_basic_set *isl_basic_set_free(__isl_take isl_basic_set *bset)
1523{
1524	return isl_basic_map_free(bset_to_bmap(bset));
1525}
1526
1527static int room_for_con(__isl_keep isl_basic_map *bmap, unsigned n)
1528{
1529	return bmap->n_eq + bmap->n_ineq + n <= bmap->c_size;
1530}
1531
1532/* Check that "bset" does not involve any parameters.
1533 */
1534isl_stat isl_basic_set_check_no_params(__isl_keep isl_basic_set *bset)
1535{
1536	isl_size nparam;
1537
1538	nparam = isl_basic_set_dim(bset, isl_dim_param);
1539	if (nparam < 0)
1540		return isl_stat_error;
1541	if (nparam != 0)
1542		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
1543			"basic set should not have any parameters",
1544			return isl_stat_error);
1545	return isl_stat_ok;
1546}
1547
1548/* Check that "bset" does not involve any local variables.
1549 */
1550isl_stat isl_basic_set_check_no_locals(__isl_keep isl_basic_set *bset)
1551{
1552	isl_size n_div;
1553
1554	n_div = isl_basic_set_dim(bset, isl_dim_div);
1555	if (n_div < 0)
1556		return isl_stat_error;
1557	if (n_div != 0)
1558		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
1559			"basic set should not have any local variables",
1560			return isl_stat_error);
1561	return isl_stat_ok;
1562}
1563
1564#undef TYPE
1565#define TYPE isl_map
1566
1567#include "isl_check_named_params_templ.c"
1568
1569#undef TYPE
1570#define TYPE isl_basic_map
1571
1572static
1573#include "isl_check_named_params_templ.c"
1574
1575/* Check that "bmap1" and "bmap2" have the same parameters,
1576 * reporting an error if they do not.
1577 */
1578static isl_stat isl_basic_map_check_equal_params(
1579	__isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
1580{
1581	isl_bool match;
1582
1583	match = isl_basic_map_has_equal_params(bmap1, bmap2);
1584	if (match < 0)
1585		return isl_stat_error;
1586	if (!match)
1587		isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
1588			"parameters don't match", return isl_stat_error);
1589	return isl_stat_ok;
1590}
1591
1592#undef TYPE
1593#define TYPE	isl_map
1594
1595#include "isl_align_params_bin_templ.c"
1596
1597#undef SUFFIX
1598#define SUFFIX	set
1599#undef ARG1
1600#define ARG1	isl_map
1601#undef ARG2
1602#define ARG2	isl_set
1603
1604#include "isl_align_params_templ.c"
1605
1606isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1,
1607	__isl_keep isl_map *map2,
1608	isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2))
1609{
1610	isl_bool r;
1611
1612	if (!map1 || !map2)
1613		return isl_bool_error;
1614	if (isl_map_has_equal_params(map1, map2))
1615		return fn(map1, map2);
1616	if (isl_map_check_named_params(map1) < 0)
1617		return isl_bool_error;
1618	if (isl_map_check_named_params(map2) < 0)
1619		return isl_bool_error;
1620	map1 = isl_map_copy(map1);
1621	map2 = isl_map_copy(map2);
1622	map1 = isl_map_align_params(map1, isl_map_get_space(map2));
1623	map2 = isl_map_align_params(map2, isl_map_get_space(map1));
1624	r = fn(map1, map2);
1625	isl_map_free(map1);
1626	isl_map_free(map2);
1627	return r;
1628}
1629
1630int isl_basic_map_alloc_equality(__isl_keep isl_basic_map *bmap)
1631{
1632	isl_size total;
1633	struct isl_ctx *ctx;
1634
1635	total = isl_basic_map_dim(bmap, isl_dim_all);
1636	if (total < 0)
1637		return -1;
1638	ctx = bmap->ctx;
1639	isl_assert(ctx, room_for_con(bmap, 1), return -1);
1640	isl_assert(ctx, (bmap->eq - bmap->ineq) + bmap->n_eq <= bmap->c_size,
1641			return -1);
1642	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
1643	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
1644	ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
1645	ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
1646	if ((bmap->eq - bmap->ineq) + bmap->n_eq == bmap->c_size) {
1647		isl_int *t;
1648		int j = isl_basic_map_alloc_inequality(bmap);
1649		if (j < 0)
1650			return -1;
1651		t = bmap->ineq[j];
1652		bmap->ineq[j] = bmap->ineq[bmap->n_ineq - 1];
1653		bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
1654		bmap->eq[-1] = t;
1655		bmap->n_eq++;
1656		bmap->n_ineq--;
1657		bmap->eq--;
1658		return 0;
1659	}
1660	isl_seq_clr(bmap->eq[bmap->n_eq] + 1 + total,
1661		      bmap->extra - bmap->n_div);
1662	return bmap->n_eq++;
1663}
1664
1665int isl_basic_set_alloc_equality(__isl_keep isl_basic_set *bset)
1666{
1667	return isl_basic_map_alloc_equality(bset_to_bmap(bset));
1668}
1669
1670__isl_give isl_basic_map *isl_basic_map_free_equality(
1671	__isl_take isl_basic_map *bmap, unsigned n)
1672{
1673	if (!bmap)
1674		return NULL;
1675	if (n > bmap->n_eq)
1676		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
1677			"invalid number of equalities",
1678			isl_basic_map_free(bmap));
1679	bmap->n_eq -= n;
1680	return bmap;
1681}
1682
1683__isl_give isl_basic_set *isl_basic_set_free_equality(
1684	__isl_take isl_basic_set *bset, unsigned n)
1685{
1686	return bset_from_bmap(isl_basic_map_free_equality(bset_to_bmap(bset),
1687							    n));
1688}
1689
1690/* Drop the equality constraint at position "pos",
1691 * preserving the order of the other equality constraints.
1692 */
1693int isl_basic_map_drop_equality(__isl_keep isl_basic_map *bmap, unsigned pos)
1694{
1695	isl_int *t;
1696	int r;
1697
1698	if (!bmap)
1699		return -1;
1700	isl_assert(bmap->ctx, pos < bmap->n_eq, return -1);
1701
1702	t = bmap->eq[pos];
1703	bmap->n_eq--;
1704	for (r = pos; r < bmap->n_eq; ++r)
1705		bmap->eq[r] = bmap->eq[r + 1];
1706	bmap->eq[bmap->n_eq] = t;
1707
1708	return 0;
1709}
1710
1711/* Turn inequality "pos" of "bmap" into an equality.
1712 *
1713 * In particular, we move the inequality in front of the equalities
1714 * and move the last inequality in the position of the moved inequality.
1715 * Note that isl_tab_make_equalities_explicit depends on this particular
1716 * change in the ordering of the constraints.
1717 */
1718void isl_basic_map_inequality_to_equality(
1719		__isl_keep isl_basic_map *bmap, unsigned pos)
1720{
1721	isl_int *t;
1722
1723	t = bmap->ineq[pos];
1724	bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
1725	bmap->ineq[bmap->n_ineq - 1] = bmap->eq[-1];
1726	bmap->eq[-1] = t;
1727	bmap->n_eq++;
1728	bmap->n_ineq--;
1729	bmap->eq--;
1730	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
1731	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
1732	ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
1733	ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
1734}
1735
1736static int room_for_ineq(__isl_keep isl_basic_map *bmap, unsigned n)
1737{
1738	return bmap->n_ineq + n <= bmap->eq - bmap->ineq;
1739}
1740
1741int isl_basic_map_alloc_inequality(__isl_keep isl_basic_map *bmap)
1742{
1743	isl_size total;
1744	struct isl_ctx *ctx;
1745
1746	total = isl_basic_map_dim(bmap, isl_dim_all);
1747	if (total < 0)
1748		return -1;
1749	ctx = bmap->ctx;
1750	isl_assert(ctx, room_for_ineq(bmap, 1), return -1);
1751	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
1752	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
1753	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
1754	ISL_F_CLR(bmap, ISL_BASIC_MAP_ALL_EQUALITIES);
1755	isl_seq_clr(bmap->ineq[bmap->n_ineq] + 1 + total,
1756		      bmap->extra - bmap->n_div);
1757	return bmap->n_ineq++;
1758}
1759
1760int isl_basic_set_alloc_inequality(__isl_keep isl_basic_set *bset)
1761{
1762	return isl_basic_map_alloc_inequality(bset_to_bmap(bset));
1763}
1764
1765__isl_give isl_basic_map *isl_basic_map_free_inequality(
1766	__isl_take isl_basic_map *bmap, unsigned n)
1767{
1768	if (!bmap)
1769		return NULL;
1770	if (n > bmap->n_ineq)
1771		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
1772			"invalid number of inequalities",
1773			return isl_basic_map_free(bmap));
1774	bmap->n_ineq -= n;
1775	return bmap;
1776}
1777
1778__isl_give isl_basic_set *isl_basic_set_free_inequality(
1779	__isl_take isl_basic_set *bset, unsigned n)
1780{
1781	return bset_from_bmap(isl_basic_map_free_inequality(bset_to_bmap(bset),
1782							    n));
1783}
1784
1785int isl_basic_map_drop_inequality(__isl_keep isl_basic_map *bmap, unsigned pos)
1786{
1787	isl_int *t;
1788	if (!bmap)
1789		return -1;
1790	isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
1791
1792	if (pos != bmap->n_ineq - 1) {
1793		t = bmap->ineq[pos];
1794		bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
1795		bmap->ineq[bmap->n_ineq - 1] = t;
1796		ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
1797	}
1798	bmap->n_ineq--;
1799	return 0;
1800}
1801
1802int isl_basic_set_drop_inequality(__isl_keep isl_basic_set *bset, unsigned pos)
1803{
1804	return isl_basic_map_drop_inequality(bset_to_bmap(bset), pos);
1805}
1806
1807__isl_give isl_basic_map *isl_basic_map_add_eq(__isl_take isl_basic_map *bmap,
1808	isl_int *eq)
1809{
1810	isl_bool empty;
1811	isl_size total;
1812	int k;
1813
1814	empty = isl_basic_map_plain_is_empty(bmap);
1815	if (empty < 0)
1816		return isl_basic_map_free(bmap);
1817	if (empty)
1818		return bmap;
1819
1820	bmap = isl_basic_map_cow(bmap);
1821	bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
1822	total = isl_basic_map_dim(bmap, isl_dim_all);
1823	if (total < 0)
1824		return isl_basic_map_free(bmap);
1825	k = isl_basic_map_alloc_equality(bmap);
1826	if (k < 0)
1827		goto error;
1828	isl_seq_cpy(bmap->eq[k], eq, 1 + total);
1829	return bmap;
1830error:
1831	isl_basic_map_free(bmap);
1832	return NULL;
1833}
1834
1835__isl_give isl_basic_set *isl_basic_set_add_eq(__isl_take isl_basic_set *bset,
1836	isl_int *eq)
1837{
1838	return bset_from_bmap(isl_basic_map_add_eq(bset_to_bmap(bset), eq));
1839}
1840
1841__isl_give isl_basic_map *isl_basic_map_add_ineq(__isl_take isl_basic_map *bmap,
1842	isl_int *ineq)
1843{
1844	isl_size total;
1845	int k;
1846
1847	bmap = isl_basic_map_cow(bmap);
1848	bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
1849	total = isl_basic_map_dim(bmap, isl_dim_all);
1850	if (total < 0)
1851		return isl_basic_map_free(bmap);
1852	k = isl_basic_map_alloc_inequality(bmap);
1853	if (k < 0)
1854		goto error;
1855	isl_seq_cpy(bmap->ineq[k], ineq, 1 + total);
1856	return bmap;
1857error:
1858	isl_basic_map_free(bmap);
1859	return NULL;
1860}
1861
1862__isl_give isl_basic_set *isl_basic_set_add_ineq(__isl_take isl_basic_set *bset,
1863	isl_int *ineq)
1864{
1865	return bset_from_bmap(isl_basic_map_add_ineq(bset_to_bmap(bset), ineq));
1866}
1867
1868int isl_basic_map_alloc_div(__isl_keep isl_basic_map *bmap)
1869{
1870	isl_size total;
1871
1872	total = isl_basic_map_dim(bmap, isl_dim_all);
1873	if (total < 0)
1874		return -1;
1875	isl_assert(bmap->ctx, bmap->n_div < bmap->extra, return -1);
1876	isl_seq_clr(bmap->div[bmap->n_div] + 1 + 1 + total,
1877		      bmap->extra - bmap->n_div);
1878	ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
1879	return bmap->n_div++;
1880}
1881
1882int isl_basic_set_alloc_div(__isl_keep isl_basic_set *bset)
1883{
1884	return isl_basic_map_alloc_div(bset_to_bmap(bset));
1885}
1886
1887#undef TYPE
1888#define TYPE	isl_basic_map
1889#include "check_type_range_templ.c"
1890
1891/* Check that there are "n" dimensions of type "type" starting at "first"
1892 * in "bset".
1893 */
1894isl_stat isl_basic_set_check_range(__isl_keep isl_basic_set *bset,
1895	enum isl_dim_type type, unsigned first, unsigned n)
1896{
1897	return isl_basic_map_check_range(bset_to_bmap(bset),
1898					type, first, n);
1899}
1900
1901/* Insert an extra integer division, prescribed by "div", to "bmap"
1902 * at (integer division) position "pos".
1903 *
1904 * The integer division is first added at the end and then moved
1905 * into the right position.
1906 */
1907__isl_give isl_basic_map *isl_basic_map_insert_div(
1908	__isl_take isl_basic_map *bmap, int pos, __isl_keep isl_vec *div)
1909{
1910	int i, k;
1911	isl_size total;
1912
1913	bmap = isl_basic_map_cow(bmap);
1914	total = isl_basic_map_dim(bmap, isl_dim_all);
1915	if (total < 0 || !div)
1916		return isl_basic_map_free(bmap);
1917
1918	if (div->size != 1 + 1 + total)
1919		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
1920			"unexpected size", return isl_basic_map_free(bmap));
1921	if (isl_basic_map_check_range(bmap, isl_dim_div, pos, 0) < 0)
1922		return isl_basic_map_free(bmap);
1923
1924	bmap = isl_basic_map_extend(bmap, 1, 0, 2);
1925	k = isl_basic_map_alloc_div(bmap);
1926	if (k < 0)
1927		return isl_basic_map_free(bmap);
1928	isl_seq_cpy(bmap->div[k], div->el, div->size);
1929	isl_int_set_si(bmap->div[k][div->size], 0);
1930
1931	for (i = k; i > pos; --i)
1932		bmap = isl_basic_map_swap_div(bmap, i, i - 1);
1933
1934	return bmap;
1935}
1936
1937isl_stat isl_basic_map_free_div(__isl_keep isl_basic_map *bmap, unsigned n)
1938{
1939	if (!bmap)
1940		return isl_stat_error;
1941	isl_assert(bmap->ctx, n <= bmap->n_div, return isl_stat_error);
1942	bmap->n_div -= n;
1943	return isl_stat_ok;
1944}
1945
1946static __isl_give isl_basic_map *add_constraints(
1947	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2,
1948	unsigned i_pos, unsigned o_pos)
1949{
1950	isl_size total, n_param, n_in, n_out, n_div;
1951	unsigned o_in, o_out;
1952	isl_ctx *ctx;
1953	isl_space *space;
1954	struct isl_dim_map *dim_map;
1955
1956	space = isl_basic_map_peek_space(bmap2);
1957	if (!bmap1 || !space)
1958		goto error;
1959
1960	total = isl_basic_map_dim(bmap1, isl_dim_all);
1961	n_param = isl_basic_map_dim(bmap2, isl_dim_param);
1962	n_in = isl_basic_map_dim(bmap2, isl_dim_in);
1963	o_in = isl_basic_map_offset(bmap1, isl_dim_in) - 1 + i_pos;
1964	n_out = isl_basic_map_dim(bmap2, isl_dim_out);
1965	o_out = isl_basic_map_offset(bmap1, isl_dim_out) - 1 + o_pos;
1966	n_div = isl_basic_map_dim(bmap2, isl_dim_div);
1967	if (total < 0 || n_param < 0 || n_in < 0 || n_out < 0 || n_div < 0)
1968		goto error;
1969	ctx = isl_basic_map_get_ctx(bmap1);
1970	dim_map = isl_dim_map_alloc(ctx, total + n_div);
1971	isl_dim_map_dim_range(dim_map, space, isl_dim_param, 0, n_param, 0);
1972	isl_dim_map_dim_range(dim_map, space, isl_dim_in, 0, n_in, o_in);
1973	isl_dim_map_dim_range(dim_map, space, isl_dim_out, 0, n_out, o_out);
1974	isl_dim_map_div(dim_map, bmap2, total);
1975
1976	return isl_basic_map_add_constraints_dim_map(bmap1, bmap2, dim_map);
1977error:
1978	isl_basic_map_free(bmap1);
1979	isl_basic_map_free(bmap2);
1980	return NULL;
1981}
1982
1983__isl_give isl_basic_map *isl_basic_map_extend(__isl_take isl_basic_map *base,
1984	unsigned extra, unsigned n_eq, unsigned n_ineq)
1985{
1986	isl_space *space;
1987	struct isl_basic_map *ext;
1988	unsigned flags;
1989	int dims_ok;
1990
1991	if (!base)
1992		goto error;
1993
1994	dims_ok = base->extra >= base->n_div + extra;
1995
1996	if (dims_ok && room_for_con(base, n_eq + n_ineq) &&
1997		       room_for_ineq(base, n_ineq))
1998		return base;
1999
2000	extra += base->extra;
2001	n_eq += base->n_eq;
2002	n_ineq += base->n_ineq;
2003
2004	space = isl_basic_map_get_space(base);
2005	ext = isl_basic_map_alloc_space(space, extra, n_eq, n_ineq);
2006	if (!ext)
2007		goto error;
2008
2009	if (dims_ok)
2010		ext->sample = isl_vec_copy(base->sample);
2011	flags = base->flags;
2012	ext = add_constraints(ext, base, 0, 0);
2013	if (ext) {
2014		ext->flags = flags;
2015		ISL_F_CLR(ext, ISL_BASIC_SET_FINAL);
2016	}
2017
2018	return ext;
2019
2020error:
2021	isl_basic_map_free(base);
2022	return NULL;
2023}
2024
2025__isl_give isl_basic_set *isl_basic_set_extend(__isl_take isl_basic_set *base,
2026	unsigned extra, unsigned n_eq, unsigned n_ineq)
2027{
2028	return bset_from_bmap(isl_basic_map_extend(bset_to_bmap(base),
2029						    extra, n_eq, n_ineq));
2030}
2031
2032__isl_give isl_basic_map *isl_basic_map_extend_constraints(
2033	__isl_take isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
2034{
2035	return isl_basic_map_extend(base, 0, n_eq, n_ineq);
2036}
2037
2038__isl_give isl_basic_set *isl_basic_set_extend_constraints(
2039	__isl_take isl_basic_set *base, unsigned n_eq, unsigned n_ineq)
2040{
2041	isl_basic_map *bmap = bset_to_bmap(base);
2042	bmap = isl_basic_map_extend_constraints(bmap, n_eq, n_ineq);
2043	return bset_from_bmap(bmap);
2044}
2045
2046__isl_give isl_basic_set *isl_basic_set_cow(__isl_take isl_basic_set *bset)
2047{
2048	return bset_from_bmap(isl_basic_map_cow(bset_to_bmap(bset)));
2049}
2050
2051__isl_give isl_basic_map *isl_basic_map_cow(__isl_take isl_basic_map *bmap)
2052{
2053	if (!bmap)
2054		return NULL;
2055
2056	if (bmap->ref > 1) {
2057		bmap->ref--;
2058		bmap = isl_basic_map_dup(bmap);
2059	}
2060	if (bmap) {
2061		ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL);
2062		ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS);
2063	}
2064	return bmap;
2065}
2066
2067/* Clear all cached information in "map", either because it is about
2068 * to be modified or because it is being freed.
2069 * Always return the same pointer that is passed in.
2070 * This is needed for the use in isl_map_free.
2071 */
2072static __isl_give isl_map *clear_caches(__isl_take isl_map *map)
2073{
2074	isl_basic_map_free(map->cached_simple_hull[0]);
2075	isl_basic_map_free(map->cached_simple_hull[1]);
2076	map->cached_simple_hull[0] = NULL;
2077	map->cached_simple_hull[1] = NULL;
2078	return map;
2079}
2080
2081__isl_give isl_set *isl_set_cow(__isl_take isl_set *set)
2082{
2083	return isl_map_cow(set);
2084}
2085
2086/* Return an isl_map that is equal to "map" and that has only
2087 * a single reference.
2088 *
2089 * If the original input already has only one reference, then
2090 * simply return it, but clear all cached information, since
2091 * it may be rendered invalid by the operations that will be
2092 * performed on the result.
2093 *
2094 * Otherwise, create a duplicate (without any cached information).
2095 */
2096__isl_give isl_map *isl_map_cow(__isl_take isl_map *map)
2097{
2098	if (!map)
2099		return NULL;
2100
2101	if (map->ref == 1)
2102		return clear_caches(map);
2103	map->ref--;
2104	return isl_map_dup(map);
2105}
2106
2107static void swap_vars(struct isl_blk blk, isl_int *a,
2108			unsigned a_len, unsigned b_len)
2109{
2110	isl_seq_cpy(blk.data, a+a_len, b_len);
2111	isl_seq_cpy(blk.data+b_len, a, a_len);
2112	isl_seq_cpy(a, blk.data, b_len+a_len);
2113}
2114
2115static __isl_give isl_basic_map *isl_basic_map_swap_vars(
2116	__isl_take isl_basic_map *bmap, unsigned pos, unsigned n1, unsigned n2)
2117{
2118	int i;
2119	struct isl_blk blk;
2120
2121	if (isl_basic_map_check_range(bmap, isl_dim_all, pos - 1, n1 + n2) < 0)
2122		goto error;
2123
2124	if (n1 == 0 || n2 == 0)
2125		return bmap;
2126
2127	bmap = isl_basic_map_cow(bmap);
2128	if (!bmap)
2129		return NULL;
2130
2131	blk = isl_blk_alloc(bmap->ctx, n1 + n2);
2132	if (isl_blk_is_error(blk))
2133		goto error;
2134
2135	for (i = 0; i < bmap->n_eq; ++i)
2136		swap_vars(blk,
2137			  bmap->eq[i] + pos, n1, n2);
2138
2139	for (i = 0; i < bmap->n_ineq; ++i)
2140		swap_vars(blk,
2141			  bmap->ineq[i] + pos, n1, n2);
2142
2143	for (i = 0; i < bmap->n_div; ++i)
2144		swap_vars(blk,
2145			  bmap->div[i]+1 + pos, n1, n2);
2146
2147	isl_blk_free(bmap->ctx, blk);
2148
2149	ISL_F_CLR(bmap, ISL_BASIC_SET_SORTED);
2150	bmap = isl_basic_map_gauss(bmap, NULL);
2151	return isl_basic_map_finalize(bmap);
2152error:
2153	isl_basic_map_free(bmap);
2154	return NULL;
2155}
2156
2157/* The given basic map has turned out to be empty.
2158 * Explicitly mark it as such and change the representation
2159 * to a canonical representation of the empty basic map.
2160 * Since the basic map has conflicting constraints,
2161 * it must have at least one constraint, except perhaps
2162 * if it was already explicitly marked as being empty.
2163 * Do nothing in the latter case, i.e., if it has been marked empty and
2164 * has no constraints.
2165 */
2166__isl_give isl_basic_map *isl_basic_map_set_to_empty(
2167	__isl_take isl_basic_map *bmap)
2168{
2169	int i = 0;
2170	isl_bool empty;
2171	isl_size n;
2172	isl_size total;
2173
2174	n = isl_basic_map_n_constraint(bmap);
2175	empty = isl_basic_map_plain_is_empty(bmap);
2176	if (n < 0 || empty < 0)
2177		return isl_basic_map_free(bmap);
2178	if (n == 0 && empty)
2179		return bmap;
2180	total = isl_basic_map_dim(bmap, isl_dim_all);
2181	if (total < 0)
2182		return isl_basic_map_free(bmap);
2183	if (isl_basic_map_free_div(bmap, bmap->n_div) < 0)
2184		return isl_basic_map_free(bmap);
2185	bmap = isl_basic_map_free_inequality(bmap, bmap->n_ineq);
2186	if (!bmap)
2187		return NULL;
2188	if (bmap->n_eq > 0) {
2189		bmap = isl_basic_map_free_equality(bmap, bmap->n_eq - 1);
2190		if (!bmap)
2191			return NULL;
2192	} else {
2193		i = isl_basic_map_alloc_equality(bmap);
2194		if (i < 0)
2195			goto error;
2196	}
2197	isl_int_set_si(bmap->eq[i][0], 1);
2198	isl_seq_clr(bmap->eq[i]+1, total);
2199	ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
2200	isl_vec_free(bmap->sample);
2201	bmap->sample = NULL;
2202	return isl_basic_map_finalize(bmap);
2203error:
2204	isl_basic_map_free(bmap);
2205	return NULL;
2206}
2207
2208__isl_give isl_basic_set *isl_basic_set_set_to_empty(
2209	__isl_take isl_basic_set *bset)
2210{
2211	return bset_from_bmap(isl_basic_map_set_to_empty(bset_to_bmap(bset)));
2212}
2213
2214__isl_give isl_basic_map *isl_basic_map_set_rational(
2215	__isl_take isl_basic_map *bmap)
2216{
2217	if (!bmap)
2218		return NULL;
2219
2220	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
2221		return bmap;
2222
2223	bmap = isl_basic_map_cow(bmap);
2224	if (!bmap)
2225		return NULL;
2226
2227	ISL_F_SET(bmap, ISL_BASIC_MAP_RATIONAL);
2228
2229	return isl_basic_map_finalize(bmap);
2230}
2231
2232__isl_give isl_basic_set *isl_basic_set_set_rational(
2233	__isl_take isl_basic_set *bset)
2234{
2235	return isl_basic_map_set_rational(bset);
2236}
2237
2238__isl_give isl_basic_set *isl_basic_set_set_integral(
2239	__isl_take isl_basic_set *bset)
2240{
2241	if (!bset)
2242		return NULL;
2243
2244	if (!ISL_F_ISSET(bset, ISL_BASIC_MAP_RATIONAL))
2245		return bset;
2246
2247	bset = isl_basic_set_cow(bset);
2248	if (!bset)
2249		return NULL;
2250
2251	ISL_F_CLR(bset, ISL_BASIC_MAP_RATIONAL);
2252
2253	return isl_basic_set_finalize(bset);
2254}
2255
2256__isl_give isl_map *isl_map_set_rational(__isl_take isl_map *map)
2257{
2258	int i;
2259
2260	map = isl_map_cow(map);
2261	if (!map)
2262		return NULL;
2263	for (i = 0; i < map->n; ++i) {
2264		map->p[i] = isl_basic_map_set_rational(map->p[i]);
2265		if (!map->p[i])
2266			goto error;
2267	}
2268	return map;
2269error:
2270	isl_map_free(map);
2271	return NULL;
2272}
2273
2274__isl_give isl_set *isl_set_set_rational(__isl_take isl_set *set)
2275{
2276	return isl_map_set_rational(set);
2277}
2278
2279/* Swap divs "a" and "b" in "bmap" (without modifying any of the constraints
2280 * of "bmap").
2281 */
2282static void swap_div(__isl_keep isl_basic_map *bmap, int a, int b)
2283{
2284	isl_int *t = bmap->div[a];
2285	bmap->div[a] = bmap->div[b];
2286	bmap->div[b] = t;
2287}
2288
2289/* Swap divs "a" and "b" in "bmap" and adjust the constraints and
2290 * div definitions accordingly.
2291 */
2292__isl_give isl_basic_map *isl_basic_map_swap_div(__isl_take isl_basic_map *bmap,
2293	int a, int b)
2294{
2295	int i;
2296	isl_size off;
2297
2298	off = isl_basic_map_var_offset(bmap, isl_dim_div);
2299	if (off < 0)
2300		return isl_basic_map_free(bmap);
2301
2302	swap_div(bmap, a, b);
2303
2304	for (i = 0; i < bmap->n_eq; ++i)
2305		isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b]);
2306
2307	for (i = 0; i < bmap->n_ineq; ++i)
2308		isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b]);
2309
2310	for (i = 0; i < bmap->n_div; ++i)
2311		isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b]);
2312	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
2313
2314	return bmap;
2315}
2316
2317static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem)
2318{
2319	isl_seq_cpy(c, c + n, rem);
2320	isl_seq_clr(c + rem, n);
2321}
2322
2323/* Drop n dimensions starting at first.
2324 *
2325 * In principle, this frees up some extra variables as the number
2326 * of columns remains constant, but we would have to extend
2327 * the div array too as the number of rows in this array is assumed
2328 * to be equal to extra.
2329 */
2330__isl_give isl_basic_set *isl_basic_set_drop_dims(
2331	__isl_take isl_basic_set *bset, unsigned first, unsigned n)
2332{
2333	return isl_basic_map_drop(bset_to_bmap(bset), isl_dim_set, first, n);
2334}
2335
2336/* Move "n" divs starting at "first" to the end of the list of divs.
2337 */
2338static __isl_give isl_basic_map *move_divs_last(__isl_take isl_basic_map *bmap,
2339	unsigned first, unsigned n)
2340{
2341	isl_int **div;
2342	int i;
2343
2344	if (first + n == bmap->n_div)
2345		return bmap;
2346
2347	div = isl_alloc_array(bmap->ctx, isl_int *, n);
2348	if (!div)
2349		goto error;
2350	for (i = 0; i < n; ++i)
2351		div[i] = bmap->div[first + i];
2352	for (i = 0; i < bmap->n_div - first - n; ++i)
2353		bmap->div[first + i] = bmap->div[first + n + i];
2354	for (i = 0; i < n; ++i)
2355		bmap->div[bmap->n_div - n + i] = div[i];
2356	free(div);
2357	return bmap;
2358error:
2359	isl_basic_map_free(bmap);
2360	return NULL;
2361}
2362
2363#undef TYPE
2364#define TYPE	isl_map
2365static
2366#include "check_type_range_templ.c"
2367
2368/* Check that there are "n" dimensions of type "type" starting at "first"
2369 * in "set".
2370 */
2371isl_stat isl_set_check_range(__isl_keep isl_set *set,
2372	enum isl_dim_type type, unsigned first, unsigned n)
2373{
2374	return isl_map_check_range(set_to_map(set), type, first, n);
2375}
2376
2377/* Drop "n" dimensions of type "type" starting at "first".
2378 * Perform the core computation, without cowing or
2379 * simplifying and finalizing the result.
2380 *
2381 * In principle, this frees up some extra variables as the number
2382 * of columns remains constant, but we would have to extend
2383 * the div array too as the number of rows in this array is assumed
2384 * to be equal to extra.
2385 */
2386__isl_give isl_basic_map *isl_basic_map_drop_core(
2387	__isl_take isl_basic_map *bmap, enum isl_dim_type type,
2388	unsigned first, unsigned n)
2389{
2390	int i;
2391	unsigned offset;
2392	unsigned left;
2393	isl_size total;
2394
2395	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2396		return isl_basic_map_free(bmap);
2397
2398	total = isl_basic_map_dim(bmap, isl_dim_all);
2399	if (total < 0)
2400		return isl_basic_map_free(bmap);
2401
2402	offset = isl_basic_map_offset(bmap, type) + first;
2403	left = total - (offset - 1) - n;
2404	for (i = 0; i < bmap->n_eq; ++i)
2405		constraint_drop_vars(bmap->eq[i]+offset, n, left);
2406
2407	for (i = 0; i < bmap->n_ineq; ++i)
2408		constraint_drop_vars(bmap->ineq[i]+offset, n, left);
2409
2410	for (i = 0; i < bmap->n_div; ++i)
2411		constraint_drop_vars(bmap->div[i]+1+offset, n, left);
2412
2413	if (type == isl_dim_div) {
2414		bmap = move_divs_last(bmap, first, n);
2415		if (!bmap)
2416			return NULL;
2417		if (isl_basic_map_free_div(bmap, n) < 0)
2418			return isl_basic_map_free(bmap);
2419	} else
2420		bmap->dim = isl_space_drop_dims(bmap->dim, type, first, n);
2421	if (!bmap->dim)
2422		return isl_basic_map_free(bmap);
2423
2424	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
2425	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
2426	return bmap;
2427}
2428
2429/* Drop "n" dimensions of type "type" starting at "first".
2430 *
2431 * In principle, this frees up some extra variables as the number
2432 * of columns remains constant, but we would have to extend
2433 * the div array too as the number of rows in this array is assumed
2434 * to be equal to extra.
2435 */
2436__isl_give isl_basic_map *isl_basic_map_drop(__isl_take isl_basic_map *bmap,
2437	enum isl_dim_type type, unsigned first, unsigned n)
2438{
2439	if (!bmap)
2440		return NULL;
2441	if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
2442		return bmap;
2443
2444	bmap = isl_basic_map_cow(bmap);
2445	if (!bmap)
2446		return NULL;
2447
2448	bmap = isl_basic_map_drop_core(bmap, type, first, n);
2449
2450	bmap = isl_basic_map_simplify(bmap);
2451	return isl_basic_map_finalize(bmap);
2452}
2453
2454__isl_give isl_basic_set *isl_basic_set_drop(__isl_take isl_basic_set *bset,
2455	enum isl_dim_type type, unsigned first, unsigned n)
2456{
2457	return bset_from_bmap(isl_basic_map_drop(bset_to_bmap(bset),
2458							type, first, n));
2459}
2460
2461/* No longer consider "map" to be normalized.
2462 */
2463static __isl_give isl_map *isl_map_unmark_normalized(__isl_take isl_map *map)
2464{
2465	if (!map)
2466		return NULL;
2467	ISL_F_CLR(map, ISL_MAP_NORMALIZED);
2468	return map;
2469}
2470
2471__isl_give isl_map *isl_map_drop(__isl_take isl_map *map,
2472	enum isl_dim_type type, unsigned first, unsigned n)
2473{
2474	int i;
2475	isl_space *space;
2476
2477	if (isl_map_check_range(map, type, first, n) < 0)
2478		return isl_map_free(map);
2479
2480	if (n == 0 && !isl_space_is_named_or_nested(map->dim, type))
2481		return map;
2482	map = isl_map_cow(map);
2483	if (!map)
2484		goto error;
2485
2486	for (i = 0; i < map->n; ++i) {
2487		map->p[i] = isl_basic_map_drop(map->p[i], type, first, n);
2488		if (!map->p[i])
2489			goto error;
2490	}
2491	map = isl_map_unmark_normalized(map);
2492
2493	space = isl_map_take_space(map);
2494	space = isl_space_drop_dims(space, type, first, n);
2495	map = isl_map_restore_space(map, space);
2496
2497	return map;
2498error:
2499	isl_map_free(map);
2500	return NULL;
2501}
2502
2503__isl_give isl_set *isl_set_drop(__isl_take isl_set *set,
2504	enum isl_dim_type type, unsigned first, unsigned n)
2505{
2506	return set_from_map(isl_map_drop(set_to_map(set), type, first, n));
2507}
2508
2509/* Drop the integer division at position "div", which is assumed
2510 * not to appear in any of the constraints or
2511 * in any of the other integer divisions.
2512 *
2513 * Since the integer division is redundant, there is no need to cow.
2514 */
2515__isl_give isl_basic_map *isl_basic_map_drop_div(
2516	__isl_take isl_basic_map *bmap, unsigned div)
2517{
2518	return isl_basic_map_drop_core(bmap, isl_dim_div, div, 1);
2519}
2520
2521/* Eliminate the specified n dimensions starting at first from the
2522 * constraints, without removing the dimensions from the space.
2523 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2524 */
2525__isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
2526	enum isl_dim_type type, unsigned first, unsigned n)
2527{
2528	int i;
2529
2530	if (n == 0)
2531		return map;
2532
2533	if (isl_map_check_range(map, type, first, n) < 0)
2534		return isl_map_free(map);
2535
2536	map = isl_map_cow(map);
2537	if (!map)
2538		return NULL;
2539
2540	for (i = 0; i < map->n; ++i) {
2541		map->p[i] = isl_basic_map_eliminate(map->p[i], type, first, n);
2542		if (!map->p[i])
2543			goto error;
2544	}
2545	return map;
2546error:
2547	isl_map_free(map);
2548	return NULL;
2549}
2550
2551/* Eliminate the specified n dimensions starting at first from the
2552 * constraints, without removing the dimensions from the space.
2553 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2554 */
2555__isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set,
2556	enum isl_dim_type type, unsigned first, unsigned n)
2557{
2558	return set_from_map(isl_map_eliminate(set_to_map(set), type, first, n));
2559}
2560
2561/* Eliminate the specified n dimensions starting at first from the
2562 * constraints, without removing the dimensions from the space.
2563 * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
2564 */
2565__isl_give isl_set *isl_set_eliminate_dims(__isl_take isl_set *set,
2566	unsigned first, unsigned n)
2567{
2568	return isl_set_eliminate(set, isl_dim_set, first, n);
2569}
2570
2571__isl_give isl_basic_map *isl_basic_map_remove_divs(
2572	__isl_take isl_basic_map *bmap)
2573{
2574	isl_size v_div;
2575
2576	v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
2577	if (v_div < 0)
2578		return isl_basic_map_free(bmap);
2579	bmap = isl_basic_map_eliminate_vars(bmap, v_div, bmap->n_div);
2580	if (!bmap)
2581		return NULL;
2582	bmap->n_div = 0;
2583	return isl_basic_map_finalize(bmap);
2584}
2585
2586__isl_give isl_basic_set *isl_basic_set_remove_divs(
2587	__isl_take isl_basic_set *bset)
2588{
2589	return bset_from_bmap(isl_basic_map_remove_divs(bset_to_bmap(bset)));
2590}
2591
2592__isl_give isl_map *isl_map_remove_divs(__isl_take isl_map *map)
2593{
2594	int i;
2595
2596	if (!map)
2597		return NULL;
2598	if (map->n == 0)
2599		return map;
2600
2601	map = isl_map_cow(map);
2602	if (!map)
2603		return NULL;
2604
2605	for (i = 0; i < map->n; ++i) {
2606		map->p[i] = isl_basic_map_remove_divs(map->p[i]);
2607		if (!map->p[i])
2608			goto error;
2609	}
2610	return map;
2611error:
2612	isl_map_free(map);
2613	return NULL;
2614}
2615
2616__isl_give isl_set *isl_set_remove_divs(__isl_take isl_set *set)
2617{
2618	return isl_map_remove_divs(set);
2619}
2620
2621__isl_give isl_basic_map *isl_basic_map_remove_dims(
2622	__isl_take isl_basic_map *bmap, enum isl_dim_type type,
2623	unsigned first, unsigned n)
2624{
2625	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2626		return isl_basic_map_free(bmap);
2627	if (n == 0 && !isl_space_is_named_or_nested(bmap->dim, type))
2628		return bmap;
2629	bmap = isl_basic_map_eliminate_vars(bmap,
2630			isl_basic_map_offset(bmap, type) - 1 + first, n);
2631	if (!bmap)
2632		return bmap;
2633	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY) && type == isl_dim_div)
2634		return bmap;
2635	bmap = isl_basic_map_drop(bmap, type, first, n);
2636	return bmap;
2637}
2638
2639/* Return true if the definition of the given div (recursively) involves
2640 * any of the given variables.
2641 */
2642static isl_bool div_involves_vars(__isl_keep isl_basic_map *bmap, int div,
2643	unsigned first, unsigned n)
2644{
2645	int i;
2646	unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
2647
2648	if (isl_int_is_zero(bmap->div[div][0]))
2649		return isl_bool_false;
2650	if (isl_seq_first_non_zero(bmap->div[div] + 1 + 1 + first, n) >= 0)
2651		return isl_bool_true;
2652
2653	for (i = bmap->n_div - 1; i >= 0; --i) {
2654		isl_bool involves;
2655
2656		if (isl_int_is_zero(bmap->div[div][1 + div_offset + i]))
2657			continue;
2658		involves = div_involves_vars(bmap, i, first, n);
2659		if (involves < 0 || involves)
2660			return involves;
2661	}
2662
2663	return isl_bool_false;
2664}
2665
2666/* Try and add a lower and/or upper bound on "div" to "bmap"
2667 * based on inequality "i".
2668 * "total" is the total number of variables (excluding the divs).
2669 * "v" is a temporary object that can be used during the calculations.
2670 * If "lb" is set, then a lower bound should be constructed.
2671 * If "ub" is set, then an upper bound should be constructed.
2672 *
2673 * The calling function has already checked that the inequality does not
2674 * reference "div", but we still need to check that the inequality is
2675 * of the right form.  We'll consider the case where we want to construct
2676 * a lower bound.  The construction of upper bounds is similar.
2677 *
2678 * Let "div" be of the form
2679 *
2680 *	q = floor((a + f(x))/d)
2681 *
2682 * We essentially check if constraint "i" is of the form
2683 *
2684 *	b + f(x) >= 0
2685 *
2686 * so that we can use it to derive a lower bound on "div".
2687 * However, we allow a slightly more general form
2688 *
2689 *	b + g(x) >= 0
2690 *
2691 * with the condition that the coefficients of g(x) - f(x) are all
2692 * divisible by d.
2693 * Rewriting this constraint as
2694 *
2695 *	0 >= -b - g(x)
2696 *
2697 * adding a + f(x) to both sides and dividing by d, we obtain
2698 *
2699 *	(a + f(x))/d >= (a-b)/d + (f(x)-g(x))/d
2700 *
2701 * Taking the floor on both sides, we obtain
2702 *
2703 *	q >= floor((a-b)/d) + (f(x)-g(x))/d
2704 *
2705 * or
2706 *
2707 *	(g(x)-f(x))/d + ceil((b-a)/d) + q >= 0
2708 *
2709 * In the case of an upper bound, we construct the constraint
2710 *
2711 *	(g(x)+f(x))/d + floor((b+a)/d) - q >= 0
2712 *
2713 */
2714static __isl_give isl_basic_map *insert_bounds_on_div_from_ineq(
2715	__isl_take isl_basic_map *bmap, int div, int i,
2716	unsigned total, isl_int v, int lb, int ub)
2717{
2718	int j;
2719
2720	for (j = 0; (lb || ub) && j < total + bmap->n_div; ++j) {
2721		if (lb) {
2722			isl_int_sub(v, bmap->ineq[i][1 + j],
2723					bmap->div[div][1 + 1 + j]);
2724			lb = isl_int_is_divisible_by(v, bmap->div[div][0]);
2725		}
2726		if (ub) {
2727			isl_int_add(v, bmap->ineq[i][1 + j],
2728					bmap->div[div][1 + 1 + j]);
2729			ub = isl_int_is_divisible_by(v, bmap->div[div][0]);
2730		}
2731	}
2732	if (!lb && !ub)
2733		return bmap;
2734
2735	bmap = isl_basic_map_cow(bmap);
2736	bmap = isl_basic_map_extend_constraints(bmap, 0, lb + ub);
2737	if (lb) {
2738		int k = isl_basic_map_alloc_inequality(bmap);
2739		if (k < 0)
2740			goto error;
2741		for (j = 0; j < 1 + total + bmap->n_div; ++j) {
2742			isl_int_sub(bmap->ineq[k][j], bmap->ineq[i][j],
2743					bmap->div[div][1 + j]);
2744			isl_int_cdiv_q(bmap->ineq[k][j],
2745					bmap->ineq[k][j], bmap->div[div][0]);
2746		}
2747		isl_int_set_si(bmap->ineq[k][1 + total + div], 1);
2748	}
2749	if (ub) {
2750		int k = isl_basic_map_alloc_inequality(bmap);
2751		if (k < 0)
2752			goto error;
2753		for (j = 0; j < 1 + total + bmap->n_div; ++j) {
2754			isl_int_add(bmap->ineq[k][j], bmap->ineq[i][j],
2755					bmap->div[div][1 + j]);
2756			isl_int_fdiv_q(bmap->ineq[k][j],
2757					bmap->ineq[k][j], bmap->div[div][0]);
2758		}
2759		isl_int_set_si(bmap->ineq[k][1 + total + div], -1);
2760	}
2761
2762	return bmap;
2763error:
2764	isl_basic_map_free(bmap);
2765	return NULL;
2766}
2767
2768/* This function is called right before "div" is eliminated from "bmap"
2769 * using Fourier-Motzkin.
2770 * Look through the constraints of "bmap" for constraints on the argument
2771 * of the integer division and use them to construct constraints on the
2772 * integer division itself.  These constraints can then be combined
2773 * during the Fourier-Motzkin elimination.
2774 * Note that it is only useful to introduce lower bounds on "div"
2775 * if "bmap" already contains upper bounds on "div" as the newly
2776 * introduce lower bounds can then be combined with the pre-existing
2777 * upper bounds.  Similarly for upper bounds.
2778 * We therefore first check if "bmap" contains any lower and/or upper bounds
2779 * on "div".
2780 *
2781 * It is interesting to note that the introduction of these constraints
2782 * can indeed lead to more accurate results, even when compared to
2783 * deriving constraints on the argument of "div" from constraints on "div".
2784 * Consider, for example, the set
2785 *
2786 *	{ [i,j,k] : 3 + i + 2j >= 0 and 2 * [(i+2j)/4] <= k }
2787 *
2788 * The second constraint can be rewritten as
2789 *
2790 *	2 * [(-i-2j+3)/4] + k >= 0
2791 *
2792 * from which we can derive
2793 *
2794 *	-i - 2j + 3 >= -2k
2795 *
2796 * or
2797 *
2798 *	i + 2j <= 3 + 2k
2799 *
2800 * Combined with the first constraint, we obtain
2801 *
2802 *	-3 <= 3 + 2k	or	k >= -3
2803 *
2804 * If, on the other hand we derive a constraint on [(i+2j)/4] from
2805 * the first constraint, we obtain
2806 *
2807 *	[(i + 2j)/4] >= [-3/4] = -1
2808 *
2809 * Combining this constraint with the second constraint, we obtain
2810 *
2811 *	k >= -2
2812 */
2813static __isl_give isl_basic_map *insert_bounds_on_div(
2814	__isl_take isl_basic_map *bmap, int div)
2815{
2816	int i;
2817	int check_lb, check_ub;
2818	isl_int v;
2819	isl_size v_div;
2820
2821	if (!bmap)
2822		return NULL;
2823
2824	if (isl_int_is_zero(bmap->div[div][0]))
2825		return bmap;
2826
2827	v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
2828	if (v_div < 0)
2829		return isl_basic_map_free(bmap);
2830
2831	check_lb = 0;
2832	check_ub = 0;
2833	for (i = 0; (!check_lb || !check_ub) && i < bmap->n_ineq; ++i) {
2834		int s = isl_int_sgn(bmap->ineq[i][1 + v_div + div]);
2835		if (s > 0)
2836			check_ub = 1;
2837		if (s < 0)
2838			check_lb = 1;
2839	}
2840
2841	if (!check_lb && !check_ub)
2842		return bmap;
2843
2844	isl_int_init(v);
2845
2846	for (i = 0; bmap && i < bmap->n_ineq; ++i) {
2847		if (!isl_int_is_zero(bmap->ineq[i][1 + v_div + div]))
2848			continue;
2849
2850		bmap = insert_bounds_on_div_from_ineq(bmap, div, i, v_div, v,
2851							check_lb, check_ub);
2852	}
2853
2854	isl_int_clear(v);
2855
2856	return bmap;
2857}
2858
2859/* Remove all divs (recursively) involving any of the given dimensions
2860 * in their definitions.
2861 */
2862__isl_give isl_basic_map *isl_basic_map_remove_divs_involving_dims(
2863	__isl_take isl_basic_map *bmap,
2864	enum isl_dim_type type, unsigned first, unsigned n)
2865{
2866	int i;
2867	isl_size off;
2868
2869	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2870		return isl_basic_map_free(bmap);
2871	off = isl_basic_map_var_offset(bmap, type);
2872	if (off < 0)
2873		return isl_basic_map_free(bmap);
2874	first += off;
2875
2876	for (i = bmap->n_div - 1; i >= 0; --i) {
2877		isl_bool involves;
2878
2879		involves = div_involves_vars(bmap, i, first, n);
2880		if (involves < 0)
2881			return isl_basic_map_free(bmap);
2882		if (!involves)
2883			continue;
2884		bmap = insert_bounds_on_div(bmap, i);
2885		bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
2886		if (!bmap)
2887			return NULL;
2888		i = bmap->n_div;
2889	}
2890
2891	return bmap;
2892}
2893
2894__isl_give isl_basic_set *isl_basic_set_remove_divs_involving_dims(
2895	__isl_take isl_basic_set *bset,
2896	enum isl_dim_type type, unsigned first, unsigned n)
2897{
2898	return isl_basic_map_remove_divs_involving_dims(bset, type, first, n);
2899}
2900
2901__isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map,
2902	enum isl_dim_type type, unsigned first, unsigned n)
2903{
2904	int i;
2905
2906	if (!map)
2907		return NULL;
2908	if (map->n == 0)
2909		return map;
2910
2911	map = isl_map_cow(map);
2912	if (!map)
2913		return NULL;
2914
2915	for (i = 0; i < map->n; ++i) {
2916		map->p[i] = isl_basic_map_remove_divs_involving_dims(map->p[i],
2917								type, first, n);
2918		if (!map->p[i])
2919			goto error;
2920	}
2921	return map;
2922error:
2923	isl_map_free(map);
2924	return NULL;
2925}
2926
2927__isl_give isl_set *isl_set_remove_divs_involving_dims(__isl_take isl_set *set,
2928	enum isl_dim_type type, unsigned first, unsigned n)
2929{
2930	return set_from_map(isl_map_remove_divs_involving_dims(set_to_map(set),
2931							      type, first, n));
2932}
2933
2934/* Does the description of "bmap" depend on the specified dimensions?
2935 * We also check whether the dimensions appear in any of the div definitions.
2936 * In principle there is no need for this check.  If the dimensions appear
2937 * in a div definition, they also appear in the defining constraints of that
2938 * div.
2939 */
2940isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap,
2941	enum isl_dim_type type, unsigned first, unsigned n)
2942{
2943	int i;
2944
2945	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
2946		return isl_bool_error;
2947
2948	first += isl_basic_map_offset(bmap, type);
2949	for (i = 0; i < bmap->n_eq; ++i)
2950		if (isl_seq_first_non_zero(bmap->eq[i] + first, n) >= 0)
2951			return isl_bool_true;
2952	for (i = 0; i < bmap->n_ineq; ++i)
2953		if (isl_seq_first_non_zero(bmap->ineq[i] + first, n) >= 0)
2954			return isl_bool_true;
2955	for (i = 0; i < bmap->n_div; ++i) {
2956		if (isl_int_is_zero(bmap->div[i][0]))
2957			continue;
2958		if (isl_seq_first_non_zero(bmap->div[i] + 1 + first, n) >= 0)
2959			return isl_bool_true;
2960	}
2961
2962	return isl_bool_false;
2963}
2964
2965isl_bool isl_map_involves_dims(__isl_keep isl_map *map,
2966	enum isl_dim_type type, unsigned first, unsigned n)
2967{
2968	int i;
2969
2970	if (isl_map_check_range(map, type, first, n) < 0)
2971		return isl_bool_error;
2972
2973	for (i = 0; i < map->n; ++i) {
2974		isl_bool involves = isl_basic_map_involves_dims(map->p[i],
2975							    type, first, n);
2976		if (involves < 0 || involves)
2977			return involves;
2978	}
2979
2980	return isl_bool_false;
2981}
2982
2983isl_bool isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset,
2984	enum isl_dim_type type, unsigned first, unsigned n)
2985{
2986	return isl_basic_map_involves_dims(bset, type, first, n);
2987}
2988
2989isl_bool isl_set_involves_dims(__isl_keep isl_set *set,
2990	enum isl_dim_type type, unsigned first, unsigned n)
2991{
2992	return isl_map_involves_dims(set, type, first, n);
2993}
2994
2995/* Does "bset" involve any local variables, i.e., integer divisions?
2996 */
2997static isl_bool isl_basic_set_involves_locals(__isl_keep isl_basic_set *bset)
2998{
2999	isl_size n;
3000
3001	n = isl_basic_set_dim(bset, isl_dim_div);
3002	if (n < 0)
3003		return isl_bool_error;
3004	return isl_bool_ok(n > 0);
3005}
3006
3007/* isl_set_every_basic_set callback that checks whether "bset"
3008 * is free of local variables.
3009 */
3010static isl_bool basic_set_no_locals(__isl_keep isl_basic_set *bset, void *user)
3011{
3012	return isl_bool_not(isl_basic_set_involves_locals(bset));
3013}
3014
3015/* Does "set" involve any local variables, i.e., integer divisions?
3016 */
3017isl_bool isl_set_involves_locals(__isl_keep isl_set *set)
3018{
3019	isl_bool no_locals;
3020
3021	no_locals = isl_set_every_basic_set(set, &basic_set_no_locals, NULL);
3022	return isl_bool_not(no_locals);
3023}
3024
3025/* Drop all constraints in bmap that involve any of the dimensions
3026 * first to first+n-1.
3027 * This function only performs the actual removal of constraints.
3028 *
3029 * This function should not call finalize since it is used by
3030 * remove_redundant_divs, which in turn is called by isl_basic_map_finalize.
3031 */
3032__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving(
3033	__isl_take isl_basic_map *bmap, unsigned first, unsigned n)
3034{
3035	int i;
3036
3037	if (n == 0)
3038		return bmap;
3039
3040	bmap = isl_basic_map_cow(bmap);
3041
3042	if (!bmap)
3043		return NULL;
3044
3045	for (i = bmap->n_eq - 1; i >= 0; --i) {
3046		if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) == -1)
3047			continue;
3048		if (isl_basic_map_drop_equality(bmap, i) < 0)
3049			return isl_basic_map_free(bmap);
3050	}
3051
3052	for (i = bmap->n_ineq - 1; i >= 0; --i) {
3053		if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) == -1)
3054			continue;
3055		if (isl_basic_map_drop_inequality(bmap, i) < 0)
3056			return isl_basic_map_free(bmap);
3057	}
3058
3059	return bmap;
3060}
3061
3062/* Drop all constraints in bset that involve any of the dimensions
3063 * first to first+n-1.
3064 * This function only performs the actual removal of constraints.
3065 */
3066__isl_give isl_basic_set *isl_basic_set_drop_constraints_involving(
3067	__isl_take isl_basic_set *bset, unsigned first, unsigned n)
3068{
3069	return isl_basic_map_drop_constraints_involving(bset, first, n);
3070}
3071
3072/* Drop all constraints in bmap that do not involve any of the dimensions
3073 * first to first + n - 1 of the given type.
3074 */
3075__isl_give isl_basic_map *isl_basic_map_drop_constraints_not_involving_dims(
3076	__isl_take isl_basic_map *bmap,
3077	enum isl_dim_type type, unsigned first, unsigned n)
3078{
3079	int i;
3080
3081	if (n == 0) {
3082		isl_space *space = isl_basic_map_get_space(bmap);
3083		isl_basic_map_free(bmap);
3084		return isl_basic_map_universe(space);
3085	}
3086	bmap = isl_basic_map_cow(bmap);
3087	if (!bmap)
3088		return NULL;
3089
3090	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
3091		return isl_basic_map_free(bmap);
3092
3093	first += isl_basic_map_offset(bmap, type) - 1;
3094
3095	for (i = bmap->n_eq - 1; i >= 0; --i) {
3096		if (isl_seq_first_non_zero(bmap->eq[i] + 1 + first, n) != -1)
3097			continue;
3098		if (isl_basic_map_drop_equality(bmap, i) < 0)
3099			return isl_basic_map_free(bmap);
3100	}
3101
3102	for (i = bmap->n_ineq - 1; i >= 0; --i) {
3103		if (isl_seq_first_non_zero(bmap->ineq[i] + 1 + first, n) != -1)
3104			continue;
3105		if (isl_basic_map_drop_inequality(bmap, i) < 0)
3106			return isl_basic_map_free(bmap);
3107	}
3108
3109	bmap = isl_basic_map_add_known_div_constraints(bmap);
3110	return bmap;
3111}
3112
3113/* Drop all constraints in bset that do not involve any of the dimensions
3114 * first to first + n - 1 of the given type.
3115 */
3116__isl_give isl_basic_set *isl_basic_set_drop_constraints_not_involving_dims(
3117	__isl_take isl_basic_set *bset,
3118	enum isl_dim_type type, unsigned first, unsigned n)
3119{
3120	return isl_basic_map_drop_constraints_not_involving_dims(bset,
3121							    type, first, n);
3122}
3123
3124/* Drop all constraints in bmap that involve any of the dimensions
3125 * first to first + n - 1 of the given type.
3126 */
3127__isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_dims(
3128	__isl_take isl_basic_map *bmap,
3129	enum isl_dim_type type, unsigned first, unsigned n)
3130{
3131	if (!bmap)
3132		return NULL;
3133	if (n == 0)
3134		return bmap;
3135
3136	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
3137		return isl_basic_map_free(bmap);
3138
3139	bmap = isl_basic_map_remove_divs_involving_dims(bmap, type, first, n);
3140	first += isl_basic_map_offset(bmap, type) - 1;
3141	bmap = isl_basic_map_drop_constraints_involving(bmap, first, n);
3142	bmap = isl_basic_map_add_known_div_constraints(bmap);
3143	return bmap;
3144}
3145
3146/* Drop all constraints in bset that involve any of the dimensions
3147 * first to first + n - 1 of the given type.
3148 */
3149__isl_give isl_basic_set *isl_basic_set_drop_constraints_involving_dims(
3150	__isl_take isl_basic_set *bset,
3151	enum isl_dim_type type, unsigned first, unsigned n)
3152{
3153	return isl_basic_map_drop_constraints_involving_dims(bset,
3154							    type, first, n);
3155}
3156
3157/* Drop constraints from "map" by applying "drop" to each basic map.
3158 */
3159static __isl_give isl_map *drop_constraints(__isl_take isl_map *map,
3160	enum isl_dim_type type, unsigned first, unsigned n,
3161	__isl_give isl_basic_map *(*drop)(__isl_take isl_basic_map *bmap,
3162		enum isl_dim_type type, unsigned first, unsigned n))
3163{
3164	int i;
3165
3166	if (isl_map_check_range(map, type, first, n) < 0)
3167		return isl_map_free(map);
3168
3169	map = isl_map_cow(map);
3170	if (!map)
3171		return NULL;
3172
3173	for (i = 0; i < map->n; ++i) {
3174		map->p[i] = drop(map->p[i], type, first, n);
3175		if (!map->p[i])
3176			return isl_map_free(map);
3177	}
3178
3179	if (map->n > 1)
3180		ISL_F_CLR(map, ISL_MAP_DISJOINT);
3181
3182	return map;
3183}
3184
3185/* Drop all constraints in map that involve any of the dimensions
3186 * first to first + n - 1 of the given type.
3187 */
3188__isl_give isl_map *isl_map_drop_constraints_involving_dims(
3189	__isl_take isl_map *map,
3190	enum isl_dim_type type, unsigned first, unsigned n)
3191{
3192	if (n == 0)
3193		return map;
3194	return drop_constraints(map, type, first, n,
3195				&isl_basic_map_drop_constraints_involving_dims);
3196}
3197
3198/* Drop all constraints in "map" that do not involve any of the dimensions
3199 * first to first + n - 1 of the given type.
3200 */
3201__isl_give isl_map *isl_map_drop_constraints_not_involving_dims(
3202	__isl_take isl_map *map,
3203	enum isl_dim_type type, unsigned first, unsigned n)
3204{
3205	if (n == 0) {
3206		isl_space *space = isl_map_get_space(map);
3207		isl_map_free(map);
3208		return isl_map_universe(space);
3209	}
3210	return drop_constraints(map, type, first, n,
3211			    &isl_basic_map_drop_constraints_not_involving_dims);
3212}
3213
3214/* Drop all constraints in set that involve any of the dimensions
3215 * first to first + n - 1 of the given type.
3216 */
3217__isl_give isl_set *isl_set_drop_constraints_involving_dims(
3218	__isl_take isl_set *set,
3219	enum isl_dim_type type, unsigned first, unsigned n)
3220{
3221	return isl_map_drop_constraints_involving_dims(set, type, first, n);
3222}
3223
3224/* Drop all constraints in "set" that do not involve any of the dimensions
3225 * first to first + n - 1 of the given type.
3226 */
3227__isl_give isl_set *isl_set_drop_constraints_not_involving_dims(
3228	__isl_take isl_set *set,
3229	enum isl_dim_type type, unsigned first, unsigned n)
3230{
3231	return isl_map_drop_constraints_not_involving_dims(set, type, first, n);
3232}
3233
3234/* Does local variable "div" of "bmap" have a complete explicit representation?
3235 * Having a complete explicit representation requires not only
3236 * an explicit representation, but also that all local variables
3237 * that appear in this explicit representation in turn have
3238 * a complete explicit representation.
3239 */
3240isl_bool isl_basic_map_div_is_known(__isl_keep isl_basic_map *bmap, int div)
3241{
3242	int i;
3243	unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
3244	isl_bool marked;
3245
3246	marked = isl_basic_map_div_is_marked_unknown(bmap, div);
3247	if (marked < 0 || marked)
3248		return isl_bool_not(marked);
3249
3250	for (i = bmap->n_div - 1; i >= 0; --i) {
3251		isl_bool known;
3252
3253		if (isl_int_is_zero(bmap->div[div][1 + div_offset + i]))
3254			continue;
3255		known = isl_basic_map_div_is_known(bmap, i);
3256		if (known < 0 || !known)
3257			return known;
3258	}
3259
3260	return isl_bool_true;
3261}
3262
3263/* Remove all divs that are unknown or defined in terms of unknown divs.
3264 */
3265__isl_give isl_basic_map *isl_basic_map_remove_unknown_divs(
3266	__isl_take isl_basic_map *bmap)
3267{
3268	int i;
3269
3270	if (!bmap)
3271		return NULL;
3272
3273	for (i = bmap->n_div - 1; i >= 0; --i) {
3274		if (isl_basic_map_div_is_known(bmap, i))
3275			continue;
3276		bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
3277		if (!bmap)
3278			return NULL;
3279		i = bmap->n_div;
3280	}
3281
3282	return bmap;
3283}
3284
3285/* Remove all divs that are unknown or defined in terms of unknown divs.
3286 */
3287__isl_give isl_basic_set *isl_basic_set_remove_unknown_divs(
3288	__isl_take isl_basic_set *bset)
3289{
3290	return isl_basic_map_remove_unknown_divs(bset);
3291}
3292
3293__isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map)
3294{
3295	int i;
3296
3297	if (!map)
3298		return NULL;
3299	if (map->n == 0)
3300		return map;
3301
3302	map = isl_map_cow(map);
3303	if (!map)
3304		return NULL;
3305
3306	for (i = 0; i < map->n; ++i) {
3307		map->p[i] = isl_basic_map_remove_unknown_divs(map->p[i]);
3308		if (!map->p[i])
3309			goto error;
3310	}
3311	return map;
3312error:
3313	isl_map_free(map);
3314	return NULL;
3315}
3316
3317__isl_give isl_set *isl_set_remove_unknown_divs(__isl_take isl_set *set)
3318{
3319	return set_from_map(isl_map_remove_unknown_divs(set_to_map(set)));
3320}
3321
3322__isl_give isl_basic_set *isl_basic_set_remove_dims(
3323	__isl_take isl_basic_set *bset,
3324	enum isl_dim_type type, unsigned first, unsigned n)
3325{
3326	isl_basic_map *bmap = bset_to_bmap(bset);
3327	bmap = isl_basic_map_remove_dims(bmap, type, first, n);
3328	return bset_from_bmap(bmap);
3329}
3330
3331__isl_give isl_map *isl_map_remove_dims(__isl_take isl_map *map,
3332	enum isl_dim_type type, unsigned first, unsigned n)
3333{
3334	int i;
3335
3336	if (n == 0)
3337		return map;
3338
3339	map = isl_map_cow(map);
3340	if (isl_map_check_range(map, type, first, n) < 0)
3341		return isl_map_free(map);
3342
3343	for (i = 0; i < map->n; ++i) {
3344		map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
3345			isl_basic_map_offset(map->p[i], type) - 1 + first, n);
3346		if (!map->p[i])
3347			goto error;
3348	}
3349	map = isl_map_drop(map, type, first, n);
3350	return map;
3351error:
3352	isl_map_free(map);
3353	return NULL;
3354}
3355
3356__isl_give isl_set *isl_set_remove_dims(__isl_take isl_set *bset,
3357	enum isl_dim_type type, unsigned first, unsigned n)
3358{
3359	return set_from_map(isl_map_remove_dims(set_to_map(bset),
3360						type, first, n));
3361}
3362
3363/* Project out n inputs starting at first using Fourier-Motzkin */
3364__isl_give isl_map *isl_map_remove_inputs(__isl_take isl_map *map,
3365	unsigned first, unsigned n)
3366{
3367	return isl_map_remove_dims(map, isl_dim_in, first, n);
3368}
3369
3370void isl_basic_set_print_internal(__isl_keep isl_basic_set *bset,
3371	FILE *out, int indent)
3372{
3373	isl_printer *p;
3374
3375	if (!bset) {
3376		fprintf(out, "null basic set\n");
3377		return;
3378	}
3379
3380	fprintf(out, "%*s", indent, "");
3381	fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
3382			bset->ref, bset->dim->nparam, bset->dim->n_out,
3383			bset->extra, bset->flags);
3384
3385	p = isl_printer_to_file(isl_basic_set_get_ctx(bset), out);
3386	p = isl_printer_set_dump(p, 1);
3387	p = isl_printer_set_indent(p, indent);
3388	p = isl_printer_start_line(p);
3389	p = isl_printer_print_basic_set(p, bset);
3390	p = isl_printer_end_line(p);
3391	isl_printer_free(p);
3392}
3393
3394void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap,
3395	FILE *out, int indent)
3396{
3397	isl_printer *p;
3398
3399	if (!bmap) {
3400		fprintf(out, "null basic map\n");
3401		return;
3402	}
3403
3404	fprintf(out, "%*s", indent, "");
3405	fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
3406			"flags: %x, n_name: %d\n",
3407		bmap->ref,
3408		bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,
3409		bmap->extra, bmap->flags, bmap->dim->n_id);
3410
3411	p = isl_printer_to_file(isl_basic_map_get_ctx(bmap), out);
3412	p = isl_printer_set_dump(p, 1);
3413	p = isl_printer_set_indent(p, indent);
3414	p = isl_printer_start_line(p);
3415	p = isl_printer_print_basic_map(p, bmap);
3416	p = isl_printer_end_line(p);
3417	isl_printer_free(p);
3418}
3419
3420__isl_give isl_basic_map *isl_inequality_negate(__isl_take isl_basic_map *bmap,
3421	unsigned pos)
3422{
3423	isl_size total;
3424
3425	total = isl_basic_map_dim(bmap, isl_dim_all);
3426	if (total < 0)
3427		return isl_basic_map_free(bmap);
3428	if (pos >= bmap->n_ineq)
3429		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
3430			"invalid position", return isl_basic_map_free(bmap));
3431	isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
3432	isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1);
3433	ISL_F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
3434	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
3435	return bmap;
3436}
3437
3438__isl_give isl_set *isl_set_alloc_space(__isl_take isl_space *space, int n,
3439	unsigned flags)
3440{
3441	if (isl_space_check_is_set(space) < 0)
3442		goto error;
3443	return isl_map_alloc_space(space, n, flags);
3444error:
3445	isl_space_free(space);
3446	return NULL;
3447}
3448
3449/* Make sure "map" has room for at least "n" more basic maps.
3450 */
3451__isl_give isl_map *isl_map_grow(__isl_take isl_map *map, int n)
3452{
3453	int i;
3454	struct isl_map *grown = NULL;
3455
3456	if (!map)
3457		return NULL;
3458	isl_assert(map->ctx, n >= 0, goto error);
3459	if (map->n + n <= map->size)
3460		return map;
3461	grown = isl_map_alloc_space(isl_map_get_space(map), map->n + n, map->flags);
3462	if (!grown)
3463		goto error;
3464	for (i = 0; i < map->n; ++i) {
3465		grown->p[i] = isl_basic_map_copy(map->p[i]);
3466		if (!grown->p[i])
3467			goto error;
3468		grown->n++;
3469	}
3470	isl_map_free(map);
3471	return grown;
3472error:
3473	isl_map_free(grown);
3474	isl_map_free(map);
3475	return NULL;
3476}
3477
3478/* Make sure "set" has room for at least "n" more basic sets.
3479 */
3480__isl_give isl_set *isl_set_grow(__isl_take isl_set *set, int n)
3481{
3482	return set_from_map(isl_map_grow(set_to_map(set), n));
3483}
3484
3485__isl_give isl_set *isl_set_from_basic_set(__isl_take isl_basic_set *bset)
3486{
3487	return isl_map_from_basic_map(bset);
3488}
3489
3490/* This function performs the same operation as isl_set_from_basic_set,
3491 * but is considered as a function on an isl_basic_set when exported.
3492 */
3493__isl_give isl_set *isl_basic_set_to_set(__isl_take isl_basic_set *bset)
3494{
3495	return isl_set_from_basic_set(bset);
3496}
3497
3498__isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap)
3499{
3500	struct isl_map *map;
3501
3502	if (!bmap)
3503		return NULL;
3504
3505	map = isl_map_alloc_space(isl_space_copy(bmap->dim), 1, ISL_MAP_DISJOINT);
3506	return isl_map_add_basic_map(map, bmap);
3507}
3508
3509__isl_give isl_set *isl_set_add_basic_set(__isl_take isl_set *set,
3510						__isl_take isl_basic_set *bset)
3511{
3512	return set_from_map(isl_map_add_basic_map(set_to_map(set),
3513						bset_to_bmap(bset)));
3514}
3515
3516__isl_null isl_set *isl_set_free(__isl_take isl_set *set)
3517{
3518	return isl_map_free(set);
3519}
3520
3521void isl_set_print_internal(__isl_keep isl_set *set, FILE *out, int indent)
3522{
3523	int i;
3524
3525	if (!set) {
3526		fprintf(out, "null set\n");
3527		return;
3528	}
3529
3530	fprintf(out, "%*s", indent, "");
3531	fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
3532			set->ref, set->n, set->dim->nparam, set->dim->n_out,
3533			set->flags);
3534	for (i = 0; i < set->n; ++i) {
3535		fprintf(out, "%*s", indent, "");
3536		fprintf(out, "basic set %d:\n", i);
3537		isl_basic_set_print_internal(set->p[i], out, indent+4);
3538	}
3539}
3540
3541void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent)
3542{
3543	int i;
3544
3545	if (!map) {
3546		fprintf(out, "null map\n");
3547		return;
3548	}
3549
3550	fprintf(out, "%*s", indent, "");
3551	fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
3552		     "flags: %x, n_name: %d\n",
3553			map->ref, map->n, map->dim->nparam, map->dim->n_in,
3554			map->dim->n_out, map->flags, map->dim->n_id);
3555	for (i = 0; i < map->n; ++i) {
3556		fprintf(out, "%*s", indent, "");
3557		fprintf(out, "basic map %d:\n", i);
3558		isl_basic_map_print_internal(map->p[i], out, indent+4);
3559	}
3560}
3561
3562/* Check that the space of "bset" is the same as that of the domain of "bmap".
3563 */
3564static isl_stat isl_basic_map_check_compatible_domain(
3565	__isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *bset)
3566{
3567	isl_bool ok;
3568
3569	ok = isl_basic_map_compatible_domain(bmap, bset);
3570	if (ok < 0)
3571		return isl_stat_error;
3572	if (!ok)
3573		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
3574			"incompatible spaces", return isl_stat_error);
3575
3576	return isl_stat_ok;
3577}
3578
3579__isl_give isl_basic_map *isl_basic_map_intersect_domain(
3580	__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *bset)
3581{
3582	struct isl_basic_map *bmap_domain;
3583	isl_size dim;
3584
3585	if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
3586		goto error;
3587
3588	dim = isl_basic_set_dim(bset, isl_dim_set);
3589	if (dim < 0)
3590		goto error;
3591	if (dim != 0 &&
3592	    isl_basic_map_check_compatible_domain(bmap, bset) < 0)
3593		goto error;
3594
3595	bmap = isl_basic_map_cow(bmap);
3596	if (!bmap)
3597		goto error;
3598	bmap = isl_basic_map_extend(bmap,
3599			bset->n_div, bset->n_eq, bset->n_ineq);
3600	bmap_domain = isl_basic_map_from_domain(bset);
3601	bmap = add_constraints(bmap, bmap_domain, 0, 0);
3602
3603	bmap = isl_basic_map_simplify(bmap);
3604	return isl_basic_map_finalize(bmap);
3605error:
3606	isl_basic_map_free(bmap);
3607	isl_basic_set_free(bset);
3608	return NULL;
3609}
3610
3611/* Check that the space of "bset" is the same as that of the range of "bmap".
3612 */
3613static isl_stat isl_basic_map_check_compatible_range(
3614	__isl_keep isl_basic_map *bmap, __isl_keep isl_basic_set *bset)
3615{
3616	isl_bool ok;
3617
3618	ok = isl_basic_map_compatible_range(bmap, bset);
3619	if (ok < 0)
3620		return isl_stat_error;
3621	if (!ok)
3622		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
3623			"incompatible spaces", return isl_stat_error);
3624
3625	return isl_stat_ok;
3626}
3627
3628__isl_give isl_basic_map *isl_basic_map_intersect_range(
3629	__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *bset)
3630{
3631	struct isl_basic_map *bmap_range;
3632	isl_size dim;
3633
3634	if (isl_basic_map_check_equal_params(bmap, bset_to_bmap(bset)) < 0)
3635		goto error;
3636
3637	dim = isl_basic_set_dim(bset, isl_dim_set);
3638	if (dim < 0)
3639		goto error;
3640	if (dim != 0 && isl_basic_map_check_compatible_range(bmap, bset) < 0)
3641		goto error;
3642
3643	if (isl_basic_set_plain_is_universe(bset)) {
3644		isl_basic_set_free(bset);
3645		return bmap;
3646	}
3647
3648	bmap = isl_basic_map_cow(bmap);
3649	if (!bmap)
3650		goto error;
3651	bmap = isl_basic_map_extend(bmap,
3652			bset->n_div, bset->n_eq, bset->n_ineq);
3653	bmap_range = bset_to_bmap(bset);
3654	bmap = add_constraints(bmap, bmap_range, 0, 0);
3655
3656	bmap = isl_basic_map_simplify(bmap);
3657	return isl_basic_map_finalize(bmap);
3658error:
3659	isl_basic_map_free(bmap);
3660	isl_basic_set_free(bset);
3661	return NULL;
3662}
3663
3664isl_bool isl_basic_map_contains(__isl_keep isl_basic_map *bmap,
3665	__isl_keep isl_vec *vec)
3666{
3667	int i;
3668	isl_size total;
3669	isl_int s;
3670
3671	total = isl_basic_map_dim(bmap, isl_dim_all);
3672	if (total < 0 || !vec)
3673		return isl_bool_error;
3674
3675	if (1 + total != vec->size)
3676		return isl_bool_false;
3677
3678	isl_int_init(s);
3679
3680	for (i = 0; i < bmap->n_eq; ++i) {
3681		isl_seq_inner_product(vec->el, bmap->eq[i], 1 + total, &s);
3682		if (!isl_int_is_zero(s)) {
3683			isl_int_clear(s);
3684			return isl_bool_false;
3685		}
3686	}
3687
3688	for (i = 0; i < bmap->n_ineq; ++i) {
3689		isl_seq_inner_product(vec->el, bmap->ineq[i], 1 + total, &s);
3690		if (isl_int_is_neg(s)) {
3691			isl_int_clear(s);
3692			return isl_bool_false;
3693		}
3694	}
3695
3696	isl_int_clear(s);
3697
3698	return isl_bool_true;
3699}
3700
3701isl_bool isl_basic_set_contains(__isl_keep isl_basic_set *bset,
3702	__isl_keep isl_vec *vec)
3703{
3704	return isl_basic_map_contains(bset_to_bmap(bset), vec);
3705}
3706
3707__isl_give isl_basic_map *isl_basic_map_intersect(
3708	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
3709{
3710	struct isl_vec *sample = NULL;
3711	isl_space *space1, *space2;
3712	isl_size dim1, dim2, nparam1, nparam2;
3713
3714	if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
3715		goto error;
3716	space1 = isl_basic_map_peek_space(bmap1);
3717	space2 = isl_basic_map_peek_space(bmap2);
3718	dim1 = isl_space_dim(space1, isl_dim_all);
3719	dim2 = isl_space_dim(space2, isl_dim_all);
3720	nparam1 = isl_space_dim(space1, isl_dim_param);
3721	nparam2 = isl_space_dim(space2, isl_dim_param);
3722	if (dim1 < 0 || dim2 < 0 || nparam1 < 0 || nparam2 < 0)
3723		goto error;
3724	if (dim1 == nparam1 && dim2 != nparam2)
3725		return isl_basic_map_intersect(bmap2, bmap1);
3726
3727	if (dim2 != nparam2 &&
3728	    isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
3729		goto error;
3730
3731	if (isl_basic_map_plain_is_empty(bmap1)) {
3732		isl_basic_map_free(bmap2);
3733		return bmap1;
3734	}
3735	if (isl_basic_map_plain_is_empty(bmap2)) {
3736		isl_basic_map_free(bmap1);
3737		return bmap2;
3738	}
3739
3740	if (bmap1->sample &&
3741	    isl_basic_map_contains(bmap1, bmap1->sample) > 0 &&
3742	    isl_basic_map_contains(bmap2, bmap1->sample) > 0)
3743		sample = isl_vec_copy(bmap1->sample);
3744	else if (bmap2->sample &&
3745	    isl_basic_map_contains(bmap1, bmap2->sample) > 0 &&
3746	    isl_basic_map_contains(bmap2, bmap2->sample) > 0)
3747		sample = isl_vec_copy(bmap2->sample);
3748
3749	bmap1 = isl_basic_map_cow(bmap1);
3750	if (!bmap1)
3751		goto error;
3752	bmap1 = isl_basic_map_extend(bmap1,
3753			bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
3754	bmap1 = add_constraints(bmap1, bmap2, 0, 0);
3755
3756	if (!bmap1)
3757		isl_vec_free(sample);
3758	else if (sample) {
3759		isl_vec_free(bmap1->sample);
3760		bmap1->sample = sample;
3761	}
3762
3763	bmap1 = isl_basic_map_simplify(bmap1);
3764	return isl_basic_map_finalize(bmap1);
3765error:
3766	if (sample)
3767		isl_vec_free(sample);
3768	isl_basic_map_free(bmap1);
3769	isl_basic_map_free(bmap2);
3770	return NULL;
3771}
3772
3773__isl_give isl_basic_set *isl_basic_set_intersect(
3774	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
3775{
3776	return bset_from_bmap(isl_basic_map_intersect(bset_to_bmap(bset1),
3777							bset_to_bmap(bset2)));
3778}
3779
3780__isl_give isl_basic_set *isl_basic_set_intersect_params(
3781	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
3782{
3783	return isl_basic_set_intersect(bset1, bset2);
3784}
3785
3786/* Does "map" consist of a single disjunct, without any local variables?
3787 */
3788static isl_bool is_convex_no_locals(__isl_keep isl_map *map)
3789{
3790	isl_size n_div;
3791
3792	if (!map)
3793		return isl_bool_error;
3794	if (map->n != 1)
3795		return isl_bool_false;
3796	n_div = isl_basic_map_dim(map->p[0], isl_dim_div);
3797	if (n_div < 0)
3798		return isl_bool_error;
3799	if (n_div != 0)
3800		return isl_bool_false;
3801	return isl_bool_true;
3802}
3803
3804/* Check that "map" consists of a single disjunct, without any local variables.
3805 */
3806static isl_stat check_convex_no_locals(__isl_keep isl_map *map)
3807{
3808	isl_bool ok;
3809
3810	ok = is_convex_no_locals(map);
3811	if (ok < 0)
3812		return isl_stat_error;
3813	if (ok)
3814		return isl_stat_ok;
3815
3816	isl_die(isl_map_get_ctx(map), isl_error_internal,
3817		"unexpectedly not convex or involving local variables",
3818		return isl_stat_error);
3819}
3820
3821/* Special case of isl_map_intersect, where both map1 and map2
3822 * are convex, without any divs and such that either map1 or map2
3823 * contains a single constraint.  This constraint is then simply
3824 * added to the other map.
3825 */
3826static __isl_give isl_map *map_intersect_add_constraint(
3827	__isl_take isl_map *map1, __isl_take isl_map *map2)
3828{
3829	if (check_convex_no_locals(map1) < 0 ||
3830	    check_convex_no_locals(map2) < 0)
3831		goto error;
3832
3833	if (map2->p[0]->n_eq + map2->p[0]->n_ineq != 1)
3834		return isl_map_intersect(map2, map1);
3835
3836	map1 = isl_map_cow(map1);
3837	if (!map1)
3838		goto error;
3839	if (isl_map_plain_is_empty(map1)) {
3840		isl_map_free(map2);
3841		return map1;
3842	}
3843	if (map2->p[0]->n_eq == 1)
3844		map1->p[0] = isl_basic_map_add_eq(map1->p[0], map2->p[0]->eq[0]);
3845	else
3846		map1->p[0] = isl_basic_map_add_ineq(map1->p[0],
3847							map2->p[0]->ineq[0]);
3848
3849	map1->p[0] = isl_basic_map_simplify(map1->p[0]);
3850	map1->p[0] = isl_basic_map_finalize(map1->p[0]);
3851	if (!map1->p[0])
3852		goto error;
3853
3854	if (isl_basic_map_plain_is_empty(map1->p[0])) {
3855		isl_basic_map_free(map1->p[0]);
3856		map1->n = 0;
3857	}
3858
3859	isl_map_free(map2);
3860
3861	map1 = isl_map_unmark_normalized(map1);
3862	return map1;
3863error:
3864	isl_map_free(map1);
3865	isl_map_free(map2);
3866	return NULL;
3867}
3868
3869/* map2 may be either a parameter domain or a map living in the same
3870 * space as map1.
3871 */
3872static __isl_give isl_map *map_intersect_internal(__isl_take isl_map *map1,
3873	__isl_take isl_map *map2)
3874{
3875	unsigned flags = 0;
3876	isl_bool equal;
3877	isl_map *result;
3878	int i, j;
3879	isl_size dim2, nparam2;
3880
3881	if (!map1 || !map2)
3882		goto error;
3883
3884	if ((isl_map_plain_is_empty(map1) ||
3885	     isl_map_plain_is_universe(map2)) &&
3886	    isl_space_is_equal(map1->dim, map2->dim)) {
3887		isl_map_free(map2);
3888		return map1;
3889	}
3890	if ((isl_map_plain_is_empty(map2) ||
3891	     isl_map_plain_is_universe(map1)) &&
3892	    isl_space_is_equal(map1->dim, map2->dim)) {
3893		isl_map_free(map1);
3894		return map2;
3895	}
3896
3897	if (is_convex_no_locals(map1) == isl_bool_true &&
3898	    is_convex_no_locals(map2) == isl_bool_true &&
3899	    isl_space_is_equal(map1->dim, map2->dim) &&
3900	    (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 ||
3901	     map2->p[0]->n_eq + map2->p[0]->n_ineq == 1))
3902		return map_intersect_add_constraint(map1, map2);
3903
3904	equal = isl_map_plain_is_equal(map1, map2);
3905	if (equal < 0)
3906		goto error;
3907	if (equal) {
3908		isl_map_free(map2);
3909		return map1;
3910	}
3911
3912	dim2 = isl_map_dim(map2, isl_dim_all);
3913	nparam2 = isl_map_dim(map2, isl_dim_param);
3914	if (dim2 < 0 || nparam2 < 0)
3915		goto error;
3916	if (dim2 != nparam2)
3917		isl_assert(map1->ctx,
3918			    isl_space_is_equal(map1->dim, map2->dim), goto error);
3919
3920	if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
3921	    ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
3922		ISL_FL_SET(flags, ISL_MAP_DISJOINT);
3923
3924	result = isl_map_alloc_space(isl_space_copy(map1->dim),
3925				map1->n * map2->n, flags);
3926	if (!result)
3927		goto error;
3928	for (i = 0; i < map1->n; ++i)
3929		for (j = 0; j < map2->n; ++j) {
3930			struct isl_basic_map *part;
3931			part = isl_basic_map_intersect(
3932				    isl_basic_map_copy(map1->p[i]),
3933				    isl_basic_map_copy(map2->p[j]));
3934			if (isl_basic_map_is_empty(part) < 0)
3935				part = isl_basic_map_free(part);
3936			result = isl_map_add_basic_map(result, part);
3937			if (!result)
3938				goto error;
3939		}
3940	isl_map_free(map1);
3941	isl_map_free(map2);
3942	return result;
3943error:
3944	isl_map_free(map1);
3945	isl_map_free(map2);
3946	return NULL;
3947}
3948
3949static __isl_give isl_map *map_intersect(__isl_take isl_map *map1,
3950	__isl_take isl_map *map2)
3951{
3952	if (isl_map_check_equal_space(map1, map2) < 0)
3953		goto error;
3954	return map_intersect_internal(map1, map2);
3955error:
3956	isl_map_free(map1);
3957	isl_map_free(map2);
3958	return NULL;
3959}
3960
3961__isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1,
3962	__isl_take isl_map *map2)
3963{
3964	isl_map_align_params_bin(&map1, &map2);
3965	return map_intersect(map1, map2);
3966}
3967
3968__isl_give isl_set *isl_set_intersect(__isl_take isl_set *set1,
3969	__isl_take isl_set *set2)
3970{
3971	return set_from_map(isl_map_intersect(set_to_map(set1),
3972					      set_to_map(set2)));
3973}
3974
3975/* map_intersect_internal accepts intersections
3976 * with parameter domains, so we can just call that function.
3977 */
3978__isl_give isl_map *isl_map_intersect_params(__isl_take isl_map *map,
3979	__isl_take isl_set *params)
3980{
3981	isl_map_align_params_set(&map, &params);
3982	return map_intersect_internal(map, params);
3983}
3984
3985__isl_give isl_set *isl_set_intersect_params(__isl_take isl_set *set,
3986		__isl_take isl_set *params)
3987{
3988	return isl_map_intersect_params(set, params);
3989}
3990
3991__isl_give isl_basic_map *isl_basic_map_reverse(__isl_take isl_basic_map *bmap)
3992{
3993	isl_space *space;
3994	unsigned pos;
3995	isl_size n1, n2;
3996
3997	if (!bmap)
3998		return NULL;
3999	bmap = isl_basic_map_cow(bmap);
4000	if (!bmap)
4001		return NULL;
4002	space = isl_space_reverse(isl_space_copy(bmap->dim));
4003	pos = isl_basic_map_offset(bmap, isl_dim_in);
4004	n1 = isl_basic_map_dim(bmap, isl_dim_in);
4005	n2 = isl_basic_map_dim(bmap, isl_dim_out);
4006	if (n1 < 0 || n2 < 0)
4007		bmap = isl_basic_map_free(bmap);
4008	bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
4009	return isl_basic_map_reset_space(bmap, space);
4010}
4011
4012/* Given a basic map where the tuple of type "type" is a wrapped map,
4013 * swap domain and range of that wrapped map.
4014 */
4015static __isl_give isl_basic_map *isl_basic_map_reverse_wrapped(
4016	__isl_take isl_basic_map *bmap, enum isl_dim_type type)
4017{
4018	isl_space *space;
4019	isl_size offset, n1, n2;
4020
4021	space = isl_basic_map_peek_space(bmap);
4022	offset = isl_basic_map_var_offset(bmap, type);
4023	n1 = isl_space_wrapped_dim(space, type, isl_dim_in);
4024	n2 = isl_space_wrapped_dim(space, type, isl_dim_out);
4025	if (offset < 0 || n1 < 0 || n2 < 0)
4026		return isl_basic_map_free(bmap);
4027
4028	bmap = isl_basic_map_swap_vars(bmap, 1 + offset, n1, n2);
4029
4030	space = isl_basic_map_take_space(bmap);
4031	space = isl_space_reverse_wrapped(space, type);
4032	bmap = isl_basic_map_restore_space(bmap, space);
4033
4034	return bmap;
4035}
4036
4037/* Given a basic map (A -> B) -> C, return the corresponding basic map
4038 * (B -> A) -> C.
4039 */
4040static __isl_give isl_basic_map *isl_basic_map_domain_reverse(
4041	__isl_take isl_basic_map *bmap)
4042{
4043	isl_space *space;
4044
4045	space = isl_basic_map_peek_space(bmap);
4046	if (isl_space_check_domain_is_wrapping(space) < 0)
4047		return isl_basic_map_free(bmap);
4048	bmap = isl_basic_map_reverse_wrapped(bmap, isl_dim_in);
4049
4050	return bmap;
4051}
4052
4053/* Given a basic map A -> (B -> C), return the corresponding basic map
4054 * A -> (C -> B).
4055 */
4056static __isl_give isl_basic_map *isl_basic_map_range_reverse(
4057	__isl_take isl_basic_map *bmap)
4058{
4059	isl_space *space;
4060
4061	space = isl_basic_map_peek_space(bmap);
4062	if (isl_space_check_range_is_wrapping(space) < 0)
4063		return isl_basic_map_free(bmap);
4064	bmap = isl_basic_map_reverse_wrapped(bmap, isl_dim_out);
4065
4066	return bmap;
4067}
4068
4069/* Given a basic map that is actually a basic set (A -> B),
4070 * return the corresponding basic set (B -> A) as a basic map.
4071 */
4072static __isl_give isl_basic_map *isl_basic_map_set_reverse(
4073	__isl_take isl_basic_map *bmap)
4074{
4075	isl_space *space;
4076
4077	space = isl_basic_map_peek_space(bmap);
4078	if (isl_space_check_is_wrapping(space) < 0)
4079		return isl_basic_map_free(bmap);
4080	bmap = isl_basic_map_reverse_wrapped(bmap, isl_dim_set);
4081
4082	return bmap;
4083}
4084
4085static __isl_give isl_basic_map *basic_map_space_reset(
4086	__isl_take isl_basic_map *bmap, enum isl_dim_type type)
4087{
4088	isl_space *space;
4089
4090	if (!bmap)
4091		return NULL;
4092	if (!isl_space_is_named_or_nested(bmap->dim, type))
4093		return bmap;
4094
4095	space = isl_basic_map_get_space(bmap);
4096	space = isl_space_reset(space, type);
4097	bmap = isl_basic_map_reset_space(bmap, space);
4098	return bmap;
4099}
4100
4101__isl_give isl_basic_map *isl_basic_map_insert_dims(
4102	__isl_take isl_basic_map *bmap, enum isl_dim_type type,
4103	unsigned pos, unsigned n)
4104{
4105	isl_bool rational, is_empty;
4106	isl_space *res_space;
4107	struct isl_basic_map *res;
4108	struct isl_dim_map *dim_map;
4109	isl_size total;
4110	unsigned off;
4111	enum isl_dim_type t;
4112
4113	if (n == 0)
4114		return basic_map_space_reset(bmap, type);
4115
4116	is_empty = isl_basic_map_plain_is_empty(bmap);
4117	total = isl_basic_map_dim(bmap, isl_dim_all);
4118	if (is_empty < 0 || total < 0)
4119		return isl_basic_map_free(bmap);
4120	res_space = isl_space_insert_dims(isl_basic_map_get_space(bmap),
4121					type, pos, n);
4122	if (!res_space)
4123		return isl_basic_map_free(bmap);
4124	if (is_empty) {
4125		isl_basic_map_free(bmap);
4126		return isl_basic_map_empty(res_space);
4127	}
4128
4129	dim_map = isl_dim_map_alloc(bmap->ctx, total + n);
4130	off = 0;
4131	for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4132		isl_size dim;
4133
4134		if (t != type) {
4135			isl_dim_map_dim(dim_map, bmap->dim, t, off);
4136		} else {
4137			isl_size size = isl_basic_map_dim(bmap, t);
4138			if (size < 0)
4139				dim_map = isl_dim_map_free(dim_map);
4140			isl_dim_map_dim_range(dim_map, bmap->dim, t,
4141						0, pos, off);
4142			isl_dim_map_dim_range(dim_map, bmap->dim, t,
4143						pos, size - pos, off + pos + n);
4144		}
4145		dim = isl_space_dim(res_space, t);
4146		if (dim < 0)
4147			dim_map = isl_dim_map_free(dim_map);
4148		off += dim;
4149	}
4150	isl_dim_map_div(dim_map, bmap, off);
4151
4152	res = isl_basic_map_alloc_space(res_space,
4153			bmap->n_div, bmap->n_eq, bmap->n_ineq);
4154	rational = isl_basic_map_is_rational(bmap);
4155	if (rational < 0)
4156		res = isl_basic_map_free(res);
4157	if (rational)
4158		res = isl_basic_map_set_rational(res);
4159	res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4160	return isl_basic_map_finalize(res);
4161}
4162
4163__isl_give isl_basic_set *isl_basic_set_insert_dims(
4164	__isl_take isl_basic_set *bset,
4165	enum isl_dim_type type, unsigned pos, unsigned n)
4166{
4167	return isl_basic_map_insert_dims(bset, type, pos, n);
4168}
4169
4170__isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap,
4171		enum isl_dim_type type, unsigned n)
4172{
4173	isl_size dim;
4174
4175	dim = isl_basic_map_dim(bmap, type);
4176	if (dim < 0)
4177		return isl_basic_map_free(bmap);
4178	return isl_basic_map_insert_dims(bmap, type, dim, n);
4179}
4180
4181__isl_give isl_basic_set *isl_basic_set_add_dims(__isl_take isl_basic_set *bset,
4182		enum isl_dim_type type, unsigned n)
4183{
4184	if (!bset)
4185		return NULL;
4186	isl_assert(bset->ctx, type != isl_dim_in, goto error);
4187	return isl_basic_map_add_dims(bset, type, n);
4188error:
4189	isl_basic_set_free(bset);
4190	return NULL;
4191}
4192
4193static __isl_give isl_map *map_space_reset(__isl_take isl_map *map,
4194	enum isl_dim_type type)
4195{
4196	isl_space *space;
4197
4198	if (!map || !isl_space_is_named_or_nested(map->dim, type))
4199		return map;
4200
4201	space = isl_map_get_space(map);
4202	space = isl_space_reset(space, type);
4203	map = isl_map_reset_space(map, space);
4204	return map;
4205}
4206
4207__isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map,
4208		enum isl_dim_type type, unsigned pos, unsigned n)
4209{
4210	int i;
4211	isl_space *space;
4212
4213	if (n == 0)
4214		return map_space_reset(map, type);
4215
4216	map = isl_map_cow(map);
4217	if (!map)
4218		return NULL;
4219
4220	for (i = 0; i < map->n; ++i) {
4221		map->p[i] = isl_basic_map_insert_dims(map->p[i], type, pos, n);
4222		if (!map->p[i])
4223			goto error;
4224	}
4225
4226	space = isl_map_take_space(map);
4227	space = isl_space_insert_dims(space, type, pos, n);
4228	map = isl_map_restore_space(map, space);
4229
4230	return map;
4231error:
4232	isl_map_free(map);
4233	return NULL;
4234}
4235
4236__isl_give isl_set *isl_set_insert_dims(__isl_take isl_set *set,
4237		enum isl_dim_type type, unsigned pos, unsigned n)
4238{
4239	return isl_map_insert_dims(set, type, pos, n);
4240}
4241
4242__isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map,
4243		enum isl_dim_type type, unsigned n)
4244{
4245	isl_size dim;
4246
4247	dim = isl_map_dim(map, type);
4248	if (dim < 0)
4249		return isl_map_free(map);
4250	return isl_map_insert_dims(map, type, dim, n);
4251}
4252
4253__isl_give isl_set *isl_set_add_dims(__isl_take isl_set *set,
4254		enum isl_dim_type type, unsigned n)
4255{
4256	if (!set)
4257		return NULL;
4258	isl_assert(set->ctx, type != isl_dim_in, goto error);
4259	return set_from_map(isl_map_add_dims(set_to_map(set), type, n));
4260error:
4261	isl_set_free(set);
4262	return NULL;
4263}
4264
4265__isl_give isl_basic_map *isl_basic_map_move_dims(
4266	__isl_take isl_basic_map *bmap,
4267	enum isl_dim_type dst_type, unsigned dst_pos,
4268	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4269{
4270	isl_space *space;
4271	struct isl_dim_map *dim_map;
4272	struct isl_basic_map *res;
4273	enum isl_dim_type t;
4274	isl_size total;
4275	unsigned off;
4276
4277	if (!bmap)
4278		return NULL;
4279	if (n == 0) {
4280		bmap = isl_basic_map_reset(bmap, src_type);
4281		bmap = isl_basic_map_reset(bmap, dst_type);
4282		return bmap;
4283	}
4284
4285	if (isl_basic_map_check_range(bmap, src_type, src_pos, n) < 0)
4286		return isl_basic_map_free(bmap);
4287
4288	if (dst_type == src_type && dst_pos == src_pos)
4289		return bmap;
4290
4291	isl_assert(bmap->ctx, dst_type != src_type, goto error);
4292
4293	if (pos(bmap->dim, dst_type) + dst_pos ==
4294	    pos(bmap->dim, src_type) + src_pos +
4295					    ((src_type < dst_type) ? n : 0)) {
4296		space = isl_basic_map_take_space(bmap);
4297		space = isl_space_move_dims(space, dst_type, dst_pos,
4298						src_type, src_pos, n);
4299		bmap = isl_basic_map_restore_space(bmap, space);
4300		bmap = isl_basic_map_finalize(bmap);
4301
4302		return bmap;
4303	}
4304
4305	total = isl_basic_map_dim(bmap, isl_dim_all);
4306	if (total < 0)
4307		return isl_basic_map_free(bmap);
4308	dim_map = isl_dim_map_alloc(bmap->ctx, total);
4309
4310	off = 0;
4311	space = isl_basic_map_peek_space(bmap);
4312	for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4313		isl_size size = isl_space_dim(space, t);
4314		if (size < 0)
4315			dim_map = isl_dim_map_free(dim_map);
4316		if (t == dst_type) {
4317			isl_dim_map_dim_range(dim_map, space, t,
4318					    0, dst_pos, off);
4319			off += dst_pos;
4320			isl_dim_map_dim_range(dim_map, space, src_type,
4321					    src_pos, n, off);
4322			off += n;
4323			isl_dim_map_dim_range(dim_map, space, t,
4324					    dst_pos, size - dst_pos, off);
4325			off += size - dst_pos;
4326		} else if (t == src_type) {
4327			isl_dim_map_dim_range(dim_map, space, t,
4328					    0, src_pos, off);
4329			off += src_pos;
4330			isl_dim_map_dim_range(dim_map, space, t,
4331					src_pos + n, size - src_pos - n, off);
4332			off += size - src_pos - n;
4333		} else {
4334			isl_dim_map_dim(dim_map, space, t, off);
4335			off += size;
4336		}
4337	}
4338	isl_dim_map_div(dim_map, bmap, off);
4339
4340	res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
4341			bmap->n_div, bmap->n_eq, bmap->n_ineq);
4342	bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4343	space = isl_basic_map_take_space(bmap);
4344	space = isl_space_move_dims(space, dst_type, dst_pos,
4345					src_type, src_pos, n);
4346	bmap = isl_basic_map_restore_space(bmap, space);
4347	if (!bmap)
4348		goto error;
4349
4350	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
4351	bmap = isl_basic_map_gauss(bmap, NULL);
4352	bmap = isl_basic_map_finalize(bmap);
4353
4354	return bmap;
4355error:
4356	isl_basic_map_free(bmap);
4357	return NULL;
4358}
4359
4360__isl_give isl_basic_set *isl_basic_set_move_dims(__isl_take isl_basic_set *bset,
4361	enum isl_dim_type dst_type, unsigned dst_pos,
4362	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4363{
4364	isl_basic_map *bmap = bset_to_bmap(bset);
4365	bmap = isl_basic_map_move_dims(bmap, dst_type, dst_pos,
4366					src_type, src_pos, n);
4367	return bset_from_bmap(bmap);
4368}
4369
4370__isl_give isl_set *isl_set_move_dims(__isl_take isl_set *set,
4371	enum isl_dim_type dst_type, unsigned dst_pos,
4372	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4373{
4374	if (!set)
4375		return NULL;
4376	isl_assert(set->ctx, dst_type != isl_dim_in, goto error);
4377	return set_from_map(isl_map_move_dims(set_to_map(set),
4378				    dst_type, dst_pos, src_type, src_pos, n));
4379error:
4380	isl_set_free(set);
4381	return NULL;
4382}
4383
4384__isl_give isl_map *isl_map_move_dims(__isl_take isl_map *map,
4385	enum isl_dim_type dst_type, unsigned dst_pos,
4386	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
4387{
4388	int i;
4389	isl_space *space;
4390
4391	if (n == 0) {
4392		map = isl_map_reset(map, src_type);
4393		map = isl_map_reset(map, dst_type);
4394		return map;
4395	}
4396
4397	if (isl_map_check_range(map, src_type, src_pos, n))
4398		return isl_map_free(map);
4399
4400	if (dst_type == src_type && dst_pos == src_pos)
4401		return map;
4402
4403	isl_assert(map->ctx, dst_type != src_type, goto error);
4404
4405	map = isl_map_cow(map);
4406	if (!map)
4407		return NULL;
4408
4409	for (i = 0; i < map->n; ++i) {
4410		map->p[i] = isl_basic_map_move_dims(map->p[i],
4411						dst_type, dst_pos,
4412						src_type, src_pos, n);
4413		if (!map->p[i])
4414			goto error;
4415	}
4416
4417	space = isl_map_take_space(map);
4418	space = isl_space_move_dims(space, dst_type, dst_pos,
4419					    src_type, src_pos, n);
4420	map = isl_map_restore_space(map, space);
4421
4422	return map;
4423error:
4424	isl_map_free(map);
4425	return NULL;
4426}
4427
4428/* Move the specified dimensions to the last columns right before
4429 * the divs.  Don't change the dimension specification of bmap.
4430 * That's the responsibility of the caller.
4431 */
4432static __isl_give isl_basic_map *move_last(__isl_take isl_basic_map *bmap,
4433	enum isl_dim_type type, unsigned first, unsigned n)
4434{
4435	isl_space *space;
4436	struct isl_dim_map *dim_map;
4437	struct isl_basic_map *res;
4438	enum isl_dim_type t;
4439	isl_size total;
4440	unsigned off;
4441
4442	if (!bmap)
4443		return NULL;
4444	if (isl_basic_map_offset(bmap, type) + first + n ==
4445				isl_basic_map_offset(bmap, isl_dim_div))
4446		return bmap;
4447
4448	total = isl_basic_map_dim(bmap, isl_dim_all);
4449	if (total < 0)
4450		return isl_basic_map_free(bmap);
4451	dim_map = isl_dim_map_alloc(bmap->ctx, total);
4452
4453	off = 0;
4454	space = isl_basic_map_peek_space(bmap);
4455	for (t = isl_dim_param; t <= isl_dim_out; ++t) {
4456		isl_size size = isl_space_dim(space, t);
4457		if (size < 0)
4458			dim_map = isl_dim_map_free(dim_map);
4459		if (t == type) {
4460			isl_dim_map_dim_range(dim_map, space, t,
4461					    0, first, off);
4462			off += first;
4463			isl_dim_map_dim_range(dim_map, space, t,
4464					    first, n, total - bmap->n_div - n);
4465			isl_dim_map_dim_range(dim_map, space, t,
4466					    first + n, size - (first + n), off);
4467			off += size - (first + n);
4468		} else {
4469			isl_dim_map_dim(dim_map, space, t, off);
4470			off += size;
4471		}
4472	}
4473	isl_dim_map_div(dim_map, bmap, off + n);
4474
4475	res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
4476			bmap->n_div, bmap->n_eq, bmap->n_ineq);
4477	res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
4478	return res;
4479}
4480
4481/* Insert "n" rows in the divs of "bmap".
4482 *
4483 * The number of columns is not changed, which means that the last
4484 * dimensions of "bmap" are being reintepreted as the new divs.
4485 * The space of "bmap" is not adjusted, however, which means
4486 * that "bmap" is left in an inconsistent state.  Removing "n" dimensions
4487 * from the space of "bmap" is the responsibility of the caller.
4488 */
4489static __isl_give isl_basic_map *insert_div_rows(__isl_take isl_basic_map *bmap,
4490	int n)
4491{
4492	int i;
4493	size_t row_size;
4494	isl_int **new_div;
4495	isl_int *old;
4496
4497	bmap = isl_basic_map_cow(bmap);
4498	if (!bmap)
4499		return NULL;
4500
4501	row_size = isl_basic_map_offset(bmap, isl_dim_div) + bmap->extra;
4502	old = bmap->block2.data;
4503	bmap->block2 = isl_blk_extend(bmap->ctx, bmap->block2,
4504					(bmap->extra + n) * (1 + row_size));
4505	if (!bmap->block2.data)
4506		return isl_basic_map_free(bmap);
4507	new_div = isl_alloc_array(bmap->ctx, isl_int *, bmap->extra + n);
4508	if (!new_div)
4509		return isl_basic_map_free(bmap);
4510	for (i = 0; i < n; ++i) {
4511		new_div[i] = bmap->block2.data +
4512				(bmap->extra + i) * (1 + row_size);
4513		isl_seq_clr(new_div[i], 1 + row_size);
4514	}
4515	for (i = 0; i < bmap->extra; ++i)
4516		new_div[n + i] = bmap->block2.data + (bmap->div[i] - old);
4517	free(bmap->div);
4518	bmap->div = new_div;
4519	bmap->n_div += n;
4520	bmap->extra += n;
4521
4522	return bmap;
4523}
4524
4525/* Drop constraints from "bmap" that only involve the variables
4526 * of "type" in the range [first, first + n] that are not related
4527 * to any of the variables outside that interval.
4528 * These constraints cannot influence the values for the variables
4529 * outside the interval, except in case they cause "bmap" to be empty.
4530 * Only drop the constraints if "bmap" is known to be non-empty.
4531 */
4532static __isl_give isl_basic_map *drop_irrelevant_constraints(
4533	__isl_take isl_basic_map *bmap, enum isl_dim_type type,
4534	unsigned first, unsigned n)
4535{
4536	int i;
4537	int *groups;
4538	isl_size dim, n_div;
4539	isl_bool non_empty;
4540
4541	non_empty = isl_basic_map_plain_is_non_empty(bmap);
4542	if (non_empty < 0)
4543		return isl_basic_map_free(bmap);
4544	if (!non_empty)
4545		return bmap;
4546
4547	dim = isl_basic_map_dim(bmap, isl_dim_all);
4548	n_div = isl_basic_map_dim(bmap, isl_dim_div);
4549	if (dim < 0 || n_div < 0)
4550		return isl_basic_map_free(bmap);
4551	groups = isl_calloc_array(isl_basic_map_get_ctx(bmap), int, dim);
4552	if (!groups)
4553		return isl_basic_map_free(bmap);
4554	first += isl_basic_map_offset(bmap, type) - 1;
4555	for (i = 0; i < first; ++i)
4556		groups[i] = -1;
4557	for (i = first + n; i < dim - n_div; ++i)
4558		groups[i] = -1;
4559
4560	bmap = isl_basic_map_drop_unrelated_constraints(bmap, groups);
4561
4562	return bmap;
4563}
4564
4565/* Turn the n dimensions of type type, starting at first
4566 * into existentially quantified variables.
4567 *
4568 * If a subset of the projected out variables are unrelated
4569 * to any of the variables that remain, then the constraints
4570 * involving this subset are simply dropped first.
4571 */
4572__isl_give isl_basic_map *isl_basic_map_project_out(
4573		__isl_take isl_basic_map *bmap,
4574		enum isl_dim_type type, unsigned first, unsigned n)
4575{
4576	isl_bool empty;
4577	isl_space *space;
4578
4579	if (n == 0)
4580		return basic_map_space_reset(bmap, type);
4581	if (type == isl_dim_div)
4582		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
4583			"cannot project out existentially quantified variables",
4584			return isl_basic_map_free(bmap));
4585
4586	empty = isl_basic_map_plain_is_empty(bmap);
4587	if (empty < 0)
4588		return isl_basic_map_free(bmap);
4589	if (empty)
4590		bmap = isl_basic_map_set_to_empty(bmap);
4591
4592	bmap = drop_irrelevant_constraints(bmap, type, first, n);
4593	if (!bmap)
4594		return NULL;
4595
4596	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
4597		return isl_basic_map_remove_dims(bmap, type, first, n);
4598
4599	if (isl_basic_map_check_range(bmap, type, first, n) < 0)
4600		return isl_basic_map_free(bmap);
4601
4602	bmap = move_last(bmap, type, first, n);
4603	bmap = isl_basic_map_cow(bmap);
4604	bmap = insert_div_rows(bmap, n);
4605
4606	space = isl_basic_map_take_space(bmap);
4607	space = isl_space_drop_dims(space, type, first, n);
4608	bmap = isl_basic_map_restore_space(bmap, space);
4609	bmap = isl_basic_map_simplify(bmap);
4610	bmap = isl_basic_map_drop_redundant_divs(bmap);
4611	return isl_basic_map_finalize(bmap);
4612}
4613
4614/* Turn the n dimensions of type type, starting at first
4615 * into existentially quantified variables.
4616 */
4617__isl_give isl_basic_set *isl_basic_set_project_out(
4618	__isl_take isl_basic_set *bset, enum isl_dim_type type,
4619	unsigned first, unsigned n)
4620{
4621	return bset_from_bmap(isl_basic_map_project_out(bset_to_bmap(bset),
4622							type, first, n));
4623}
4624
4625/* Turn the n dimensions of type type, starting at first
4626 * into existentially quantified variables.
4627 */
4628__isl_give isl_map *isl_map_project_out(__isl_take isl_map *map,
4629		enum isl_dim_type type, unsigned first, unsigned n)
4630{
4631	int i;
4632	isl_space *space;
4633
4634	if (n == 0)
4635		return map_space_reset(map, type);
4636
4637	if (isl_map_check_range(map, type, first, n) < 0)
4638		return isl_map_free(map);
4639
4640	map = isl_map_cow(map);
4641	if (!map)
4642		return NULL;
4643
4644	for (i = 0; i < map->n; ++i) {
4645		map->p[i] = isl_basic_map_project_out(map->p[i], type, first, n);
4646		if (!map->p[i])
4647			goto error;
4648	}
4649
4650	if (map->n > 1)
4651		ISL_F_CLR(map, ISL_MAP_DISJOINT);
4652	map = isl_map_unmark_normalized(map);
4653
4654	space = isl_map_take_space(map);
4655	space = isl_space_drop_dims(space, type, first, n);
4656	map = isl_map_restore_space(map, space);
4657
4658	return map;
4659error:
4660	isl_map_free(map);
4661	return NULL;
4662}
4663
4664#undef TYPE
4665#define TYPE	isl_map
4666#include "isl_project_out_all_params_templ.c"
4667#include "isl_project_out_param_templ.c"
4668
4669/* Turn all the dimensions of type "type", except the "n" starting at "first"
4670 * into existentially quantified variables.
4671 */
4672__isl_give isl_map *isl_map_project_onto(__isl_take isl_map *map,
4673	enum isl_dim_type type, unsigned first, unsigned n)
4674{
4675	isl_size dim;
4676
4677	dim = isl_map_dim(map, type);
4678	if (isl_map_check_range(map, type, first, n) < 0 || dim < 0)
4679		return isl_map_free(map);
4680	map = isl_map_project_out(map, type, first + n, dim - (first + n));
4681	map = isl_map_project_out(map, type, 0, first);
4682	return map;
4683}
4684
4685/* Turn the n dimensions of type type, starting at first
4686 * into existentially quantified variables.
4687 */
4688__isl_give isl_set *isl_set_project_out(__isl_take isl_set *set,
4689		enum isl_dim_type type, unsigned first, unsigned n)
4690{
4691	return set_from_map(isl_map_project_out(set_to_map(set),
4692						type, first, n));
4693}
4694
4695/* If "set" involves a parameter with identifier "id",
4696 * then turn it into an existentially quantified variable.
4697 */
4698__isl_give isl_set *isl_set_project_out_param_id(__isl_take isl_set *set,
4699	__isl_take isl_id *id)
4700{
4701	return set_from_map(isl_map_project_out_param_id(set_to_map(set), id));
4702}
4703
4704/* If "set" involves any of the parameters with identifiers in "list",
4705 * then turn them into existentially quantified variables.
4706 */
4707__isl_give isl_set *isl_set_project_out_param_id_list(__isl_take isl_set *set,
4708	__isl_take isl_id_list *list)
4709{
4710	isl_map *map;
4711
4712	map = set_to_map(set);
4713	map = isl_map_project_out_param_id_list(map, list);
4714	return set_from_map(map);
4715}
4716
4717/* Project out all parameters from "set" by existentially quantifying
4718 * over them.
4719 */
4720__isl_give isl_set *isl_set_project_out_all_params(__isl_take isl_set *set)
4721{
4722	return set_from_map(isl_map_project_out_all_params(set_to_map(set)));
4723}
4724
4725/* Return a map that projects the elements in "set" onto their
4726 * "n" set dimensions starting at "first".
4727 * "type" should be equal to isl_dim_set.
4728 */
4729__isl_give isl_map *isl_set_project_onto_map(__isl_take isl_set *set,
4730	enum isl_dim_type type, unsigned first, unsigned n)
4731{
4732	int i;
4733	isl_map *map;
4734
4735	if (type != isl_dim_set)
4736		isl_die(isl_set_get_ctx(set), isl_error_invalid,
4737			"only set dimensions can be projected out", goto error);
4738	if (isl_set_check_range(set, type, first, n) < 0)
4739		return isl_set_free(set);
4740
4741	map = isl_map_from_domain(set);
4742	map = isl_map_add_dims(map, isl_dim_out, n);
4743	for (i = 0; i < n; ++i)
4744		map = isl_map_equate(map, isl_dim_in, first + i,
4745					isl_dim_out, i);
4746	return map;
4747error:
4748	isl_set_free(set);
4749	return NULL;
4750}
4751
4752static __isl_give isl_basic_map *add_divs(__isl_take isl_basic_map *bmap,
4753	unsigned n)
4754{
4755	int i, j;
4756	isl_size total;
4757
4758	total = isl_basic_map_dim(bmap, isl_dim_all);
4759	if (total < 0)
4760		return isl_basic_map_free(bmap);
4761	for (i = 0; i < n; ++i) {
4762		j = isl_basic_map_alloc_div(bmap);
4763		if (j < 0)
4764			goto error;
4765		isl_seq_clr(bmap->div[j], 1 + 1 + total);
4766	}
4767	return bmap;
4768error:
4769	isl_basic_map_free(bmap);
4770	return NULL;
4771}
4772
4773/* Does "bmap2" apply to the range of "bmap1" (ignoring parameters)?
4774 */
4775isl_bool isl_basic_map_applies_range(__isl_keep isl_basic_map *bmap1,
4776	__isl_keep isl_basic_map *bmap2)
4777{
4778	isl_space *space1, *space2;
4779
4780	space1 = isl_basic_map_peek_space(bmap1);
4781	space2 = isl_basic_map_peek_space(bmap2);
4782	return isl_space_tuple_is_equal(space1, isl_dim_out,
4783					space2, isl_dim_in);
4784}
4785
4786/* Check that "bmap2" applies to the range of "bmap1" (ignoring parameters).
4787 */
4788static isl_stat isl_basic_map_check_applies_range(
4789	__isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
4790{
4791	isl_bool equal;
4792
4793	equal = isl_basic_map_applies_range(bmap1, bmap2);
4794	if (equal < 0)
4795		return isl_stat_error;
4796	if (!equal)
4797		isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
4798			"spaces don't match", return isl_stat_error);
4799	return isl_stat_ok;
4800}
4801
4802__isl_give isl_basic_map *isl_basic_map_apply_range(
4803	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
4804{
4805	isl_space *space_result = NULL;
4806	struct isl_basic_map *bmap;
4807	isl_size n_in, n_out, n, nparam;
4808	unsigned total, pos;
4809	struct isl_dim_map *dim_map1, *dim_map2;
4810
4811	if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
4812		goto error;
4813	if (isl_basic_map_check_applies_range(bmap1, bmap2) < 0)
4814		goto error;
4815
4816	n_in = isl_basic_map_dim(bmap1, isl_dim_in);
4817	n_out = isl_basic_map_dim(bmap2, isl_dim_out);
4818	n = isl_basic_map_dim(bmap1, isl_dim_out);
4819	nparam = isl_basic_map_dim(bmap1, isl_dim_param);
4820	if (n_in < 0 || n_out < 0 || n < 0 || nparam < 0)
4821		goto error;
4822
4823	space_result = isl_space_join(isl_basic_map_get_space(bmap1),
4824				  isl_basic_map_get_space(bmap2));
4825
4826	total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
4827	dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4828	dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
4829	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
4830	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
4831	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4832	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
4833	isl_dim_map_div(dim_map1, bmap1, pos += n_out);
4834	isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4835	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
4836	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
4837
4838	bmap = isl_basic_map_alloc_space(space_result,
4839			bmap1->n_div + bmap2->n_div + n,
4840			bmap1->n_eq + bmap2->n_eq,
4841			bmap1->n_ineq + bmap2->n_ineq);
4842	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
4843	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
4844	bmap = add_divs(bmap, n);
4845	bmap = isl_basic_map_simplify(bmap);
4846	bmap = isl_basic_map_drop_redundant_divs(bmap);
4847	return isl_basic_map_finalize(bmap);
4848error:
4849	isl_basic_map_free(bmap1);
4850	isl_basic_map_free(bmap2);
4851	return NULL;
4852}
4853
4854__isl_give isl_basic_set *isl_basic_set_apply(__isl_take isl_basic_set *bset,
4855	__isl_take isl_basic_map *bmap)
4856{
4857	if (isl_basic_map_check_compatible_domain(bmap, bset) < 0)
4858		goto error;
4859
4860	return bset_from_bmap(isl_basic_map_apply_range(bset_to_bmap(bset),
4861							bmap));
4862error:
4863	isl_basic_set_free(bset);
4864	isl_basic_map_free(bmap);
4865	return NULL;
4866}
4867
4868__isl_give isl_basic_map *isl_basic_map_apply_domain(
4869	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
4870{
4871	if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
4872		goto error;
4873	if (!isl_space_tuple_is_equal(bmap1->dim, isl_dim_in,
4874					bmap2->dim, isl_dim_in))
4875		isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
4876			"spaces don't match", goto error);
4877
4878	bmap1 = isl_basic_map_reverse(bmap1);
4879	bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
4880	return isl_basic_map_reverse(bmap1);
4881error:
4882	isl_basic_map_free(bmap1);
4883	isl_basic_map_free(bmap2);
4884	return NULL;
4885}
4886
4887/* Given two basic maps A -> f(A) and B -> g(B), construct a basic map
4888 * A \cap B -> f(A) + f(B)
4889 */
4890__isl_give isl_basic_map *isl_basic_map_sum(__isl_take isl_basic_map *bmap1,
4891	__isl_take isl_basic_map *bmap2)
4892{
4893	isl_size n_in, n_out, nparam;
4894	unsigned total, pos;
4895	struct isl_basic_map *bmap = NULL;
4896	struct isl_dim_map *dim_map1, *dim_map2;
4897	int i;
4898
4899	if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
4900		goto error;
4901
4902	nparam = isl_basic_map_dim(bmap1, isl_dim_param);
4903	n_in = isl_basic_map_dim(bmap1, isl_dim_in);
4904	n_out = isl_basic_map_dim(bmap1, isl_dim_out);
4905	if (nparam < 0 || n_in < 0 || n_out < 0)
4906		goto error;
4907
4908	total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + 2 * n_out;
4909	dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
4910	dim_map2 = isl_dim_map_alloc(bmap2->ctx, total);
4911	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
4912	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos);
4913	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
4914	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
4915	isl_dim_map_div(dim_map1, bmap1, pos += n_in + n_out);
4916	isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
4917	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
4918	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_out);
4919
4920	bmap = isl_basic_map_alloc_space(isl_space_copy(bmap1->dim),
4921			bmap1->n_div + bmap2->n_div + 2 * n_out,
4922			bmap1->n_eq + bmap2->n_eq + n_out,
4923			bmap1->n_ineq + bmap2->n_ineq);
4924	for (i = 0; i < n_out; ++i) {
4925		int j = isl_basic_map_alloc_equality(bmap);
4926		if (j < 0)
4927			goto error;
4928		isl_seq_clr(bmap->eq[j], 1+total);
4929		isl_int_set_si(bmap->eq[j][1+nparam+n_in+i], -1);
4930		isl_int_set_si(bmap->eq[j][1+pos+i], 1);
4931		isl_int_set_si(bmap->eq[j][1+pos-n_out+i], 1);
4932	}
4933	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
4934	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
4935	bmap = add_divs(bmap, 2 * n_out);
4936
4937	bmap = isl_basic_map_simplify(bmap);
4938	return isl_basic_map_finalize(bmap);
4939error:
4940	isl_basic_map_free(bmap);
4941	isl_basic_map_free(bmap1);
4942	isl_basic_map_free(bmap2);
4943	return NULL;
4944}
4945
4946/* Given two maps A -> f(A) and B -> g(B), construct a map
4947 * A \cap B -> f(A) + f(B)
4948 */
4949__isl_give isl_map *isl_map_sum(__isl_take isl_map *map1,
4950	__isl_take isl_map *map2)
4951{
4952	struct isl_map *result;
4953	int i, j;
4954
4955	if (isl_map_check_equal_space(map1, map2) < 0)
4956		goto error;
4957
4958	result = isl_map_alloc_space(isl_space_copy(map1->dim),
4959				map1->n * map2->n, 0);
4960	if (!result)
4961		goto error;
4962	for (i = 0; i < map1->n; ++i)
4963		for (j = 0; j < map2->n; ++j) {
4964			struct isl_basic_map *part;
4965			part = isl_basic_map_sum(
4966				    isl_basic_map_copy(map1->p[i]),
4967				    isl_basic_map_copy(map2->p[j]));
4968			if (isl_basic_map_is_empty(part))
4969				isl_basic_map_free(part);
4970			else
4971				result = isl_map_add_basic_map(result, part);
4972			if (!result)
4973				goto error;
4974		}
4975	isl_map_free(map1);
4976	isl_map_free(map2);
4977	return result;
4978error:
4979	isl_map_free(map1);
4980	isl_map_free(map2);
4981	return NULL;
4982}
4983
4984__isl_give isl_set *isl_set_sum(__isl_take isl_set *set1,
4985	__isl_take isl_set *set2)
4986{
4987	return set_from_map(isl_map_sum(set_to_map(set1), set_to_map(set2)));
4988}
4989
4990/* Given a basic map A -> f(A), construct A -> -f(A).
4991 */
4992__isl_give isl_basic_map *isl_basic_map_neg(__isl_take isl_basic_map *bmap)
4993{
4994	int i, j;
4995	unsigned off;
4996	isl_size n;
4997
4998	bmap = isl_basic_map_cow(bmap);
4999	n = isl_basic_map_dim(bmap, isl_dim_out);
5000	if (n < 0)
5001		return isl_basic_map_free(bmap);
5002
5003	off = isl_basic_map_offset(bmap, isl_dim_out);
5004	for (i = 0; i < bmap->n_eq; ++i)
5005		for (j = 0; j < n; ++j)
5006			isl_int_neg(bmap->eq[i][off+j], bmap->eq[i][off+j]);
5007	for (i = 0; i < bmap->n_ineq; ++i)
5008		for (j = 0; j < n; ++j)
5009			isl_int_neg(bmap->ineq[i][off+j], bmap->ineq[i][off+j]);
5010	for (i = 0; i < bmap->n_div; ++i)
5011		for (j = 0; j < n; ++j)
5012			isl_int_neg(bmap->div[i][1+off+j], bmap->div[i][1+off+j]);
5013	bmap = isl_basic_map_gauss(bmap, NULL);
5014	return isl_basic_map_finalize(bmap);
5015}
5016
5017__isl_give isl_basic_set *isl_basic_set_neg(__isl_take isl_basic_set *bset)
5018{
5019	return isl_basic_map_neg(bset);
5020}
5021
5022/* Given a map A -> f(A), construct A -> -f(A).
5023 */
5024__isl_give isl_map *isl_map_neg(__isl_take isl_map *map)
5025{
5026	int i;
5027
5028	map = isl_map_cow(map);
5029	if (!map)
5030		return NULL;
5031
5032	for (i = 0; i < map->n; ++i) {
5033		map->p[i] = isl_basic_map_neg(map->p[i]);
5034		if (!map->p[i])
5035			goto error;
5036	}
5037
5038	return map;
5039error:
5040	isl_map_free(map);
5041	return NULL;
5042}
5043
5044__isl_give isl_set *isl_set_neg(__isl_take isl_set *set)
5045{
5046	return set_from_map(isl_map_neg(set_to_map(set)));
5047}
5048
5049/* Given a basic map A -> f(A) and an integer d, construct a basic map
5050 * A -> floor(f(A)/d).
5051 */
5052__isl_give isl_basic_map *isl_basic_map_floordiv(__isl_take isl_basic_map *bmap,
5053		isl_int d)
5054{
5055	isl_size n_in, n_out, nparam;
5056	unsigned total, pos;
5057	struct isl_basic_map *result = NULL;
5058	struct isl_dim_map *dim_map;
5059	int i;
5060
5061	nparam = isl_basic_map_dim(bmap, isl_dim_param);
5062	n_in = isl_basic_map_dim(bmap, isl_dim_in);
5063	n_out = isl_basic_map_dim(bmap, isl_dim_out);
5064	if (nparam < 0 || n_in < 0 || n_out < 0)
5065		return isl_basic_map_free(bmap);
5066
5067	total = nparam + n_in + n_out + bmap->n_div + n_out;
5068	dim_map = isl_dim_map_alloc(bmap->ctx, total);
5069	isl_dim_map_dim(dim_map, bmap->dim, isl_dim_param, pos = 0);
5070	isl_dim_map_dim(dim_map, bmap->dim, isl_dim_in, pos += nparam);
5071	isl_dim_map_div(dim_map, bmap, pos += n_in + n_out);
5072	isl_dim_map_dim(dim_map, bmap->dim, isl_dim_out, pos += bmap->n_div);
5073
5074	result = isl_basic_map_alloc_space(isl_space_copy(bmap->dim),
5075			bmap->n_div + n_out,
5076			bmap->n_eq, bmap->n_ineq + 2 * n_out);
5077	result = isl_basic_map_add_constraints_dim_map(result, bmap, dim_map);
5078	result = add_divs(result, n_out);
5079	for (i = 0; i < n_out; ++i) {
5080		int j;
5081		j = isl_basic_map_alloc_inequality(result);
5082		if (j < 0)
5083			goto error;
5084		isl_seq_clr(result->ineq[j], 1+total);
5085		isl_int_neg(result->ineq[j][1+nparam+n_in+i], d);
5086		isl_int_set_si(result->ineq[j][1+pos+i], 1);
5087		j = isl_basic_map_alloc_inequality(result);
5088		if (j < 0)
5089			goto error;
5090		isl_seq_clr(result->ineq[j], 1+total);
5091		isl_int_set(result->ineq[j][1+nparam+n_in+i], d);
5092		isl_int_set_si(result->ineq[j][1+pos+i], -1);
5093		isl_int_sub_ui(result->ineq[j][0], d, 1);
5094	}
5095
5096	result = isl_basic_map_simplify(result);
5097	return isl_basic_map_finalize(result);
5098error:
5099	isl_basic_map_free(result);
5100	return NULL;
5101}
5102
5103/* Given a map A -> f(A) and an integer d, construct a map
5104 * A -> floor(f(A)/d).
5105 */
5106__isl_give isl_map *isl_map_floordiv(__isl_take isl_map *map, isl_int d)
5107{
5108	int i;
5109
5110	map = isl_map_cow(map);
5111	if (!map)
5112		return NULL;
5113
5114	ISL_F_CLR(map, ISL_MAP_DISJOINT);
5115	for (i = 0; i < map->n; ++i) {
5116		map->p[i] = isl_basic_map_floordiv(map->p[i], d);
5117		if (!map->p[i])
5118			goto error;
5119	}
5120	map = isl_map_unmark_normalized(map);
5121
5122	return map;
5123error:
5124	isl_map_free(map);
5125	return NULL;
5126}
5127
5128/* Given a map A -> f(A) and an integer d, construct a map
5129 * A -> floor(f(A)/d).
5130 */
5131__isl_give isl_map *isl_map_floordiv_val(__isl_take isl_map *map,
5132	__isl_take isl_val *d)
5133{
5134	if (!map || !d)
5135		goto error;
5136	if (!isl_val_is_int(d))
5137		isl_die(isl_val_get_ctx(d), isl_error_invalid,
5138			"expecting integer denominator", goto error);
5139	map = isl_map_floordiv(map, d->n);
5140	isl_val_free(d);
5141	return map;
5142error:
5143	isl_map_free(map);
5144	isl_val_free(d);
5145	return NULL;
5146}
5147
5148static __isl_give isl_basic_map *var_equal(__isl_take isl_basic_map *bmap,
5149	unsigned pos)
5150{
5151	int i;
5152	isl_size nparam;
5153	isl_size n_in;
5154	isl_size total;
5155
5156	total = isl_basic_map_dim(bmap, isl_dim_all);
5157	nparam = isl_basic_map_dim(bmap, isl_dim_param);
5158	n_in = isl_basic_map_dim(bmap, isl_dim_in);
5159	if (total < 0 || nparam < 0 || n_in < 0)
5160		return isl_basic_map_free(bmap);
5161	i = isl_basic_map_alloc_equality(bmap);
5162	if (i < 0)
5163		goto error;
5164	isl_seq_clr(bmap->eq[i], 1 + total);
5165	isl_int_set_si(bmap->eq[i][1+nparam+pos], -1);
5166	isl_int_set_si(bmap->eq[i][1+nparam+n_in+pos], 1);
5167	return isl_basic_map_finalize(bmap);
5168error:
5169	isl_basic_map_free(bmap);
5170	return NULL;
5171}
5172
5173/* Add a constraint to "bmap" expressing i_pos < o_pos
5174 */
5175static __isl_give isl_basic_map *var_less(__isl_take isl_basic_map *bmap,
5176	unsigned pos)
5177{
5178	int i;
5179	isl_size nparam;
5180	isl_size n_in;
5181	isl_size total;
5182
5183	total = isl_basic_map_dim(bmap, isl_dim_all);
5184	nparam = isl_basic_map_dim(bmap, isl_dim_param);
5185	n_in = isl_basic_map_dim(bmap, isl_dim_in);
5186	if (total < 0 || nparam < 0 || n_in < 0)
5187		return isl_basic_map_free(bmap);
5188	i = isl_basic_map_alloc_inequality(bmap);
5189	if (i < 0)
5190		goto error;
5191	isl_seq_clr(bmap->ineq[i], 1 + total);
5192	isl_int_set_si(bmap->ineq[i][0], -1);
5193	isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
5194	isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
5195	return isl_basic_map_finalize(bmap);
5196error:
5197	isl_basic_map_free(bmap);
5198	return NULL;
5199}
5200
5201/* Add a constraint to "bmap" expressing i_pos <= o_pos
5202 */
5203static __isl_give isl_basic_map *var_less_or_equal(
5204	__isl_take isl_basic_map *bmap, unsigned pos)
5205{
5206	int i;
5207	isl_size nparam;
5208	isl_size n_in;
5209	isl_size total;
5210
5211	total = isl_basic_map_dim(bmap, isl_dim_all);
5212	nparam = isl_basic_map_dim(bmap, isl_dim_param);
5213	n_in = isl_basic_map_dim(bmap, isl_dim_in);
5214	if (total < 0 || nparam < 0 || n_in < 0)
5215		return isl_basic_map_free(bmap);
5216	i = isl_basic_map_alloc_inequality(bmap);
5217	if (i < 0)
5218		goto error;
5219	isl_seq_clr(bmap->ineq[i], 1 + total);
5220	isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
5221	isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
5222	return isl_basic_map_finalize(bmap);
5223error:
5224	isl_basic_map_free(bmap);
5225	return NULL;
5226}
5227
5228/* Add a constraint to "bmap" expressing i_pos > o_pos
5229 */
5230static __isl_give isl_basic_map *var_more(__isl_take isl_basic_map *bmap,
5231	unsigned pos)
5232{
5233	int i;
5234	isl_size nparam;
5235	isl_size n_in;
5236	isl_size total;
5237
5238	total = isl_basic_map_dim(bmap, isl_dim_all);
5239	nparam = isl_basic_map_dim(bmap, isl_dim_param);
5240	n_in = isl_basic_map_dim(bmap, isl_dim_in);
5241	if (total < 0 || nparam < 0 || n_in < 0)
5242		return isl_basic_map_free(bmap);
5243	i = isl_basic_map_alloc_inequality(bmap);
5244	if (i < 0)
5245		goto error;
5246	isl_seq_clr(bmap->ineq[i], 1 + total);
5247	isl_int_set_si(bmap->ineq[i][0], -1);
5248	isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
5249	isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
5250	return isl_basic_map_finalize(bmap);
5251error:
5252	isl_basic_map_free(bmap);
5253	return NULL;
5254}
5255
5256/* Add a constraint to "bmap" expressing i_pos >= o_pos
5257 */
5258static __isl_give isl_basic_map *var_more_or_equal(
5259	__isl_take isl_basic_map *bmap, unsigned pos)
5260{
5261	int i;
5262	isl_size nparam;
5263	isl_size n_in;
5264	isl_size total;
5265
5266	total = isl_basic_map_dim(bmap, isl_dim_all);
5267	nparam = isl_basic_map_dim(bmap, isl_dim_param);
5268	n_in = isl_basic_map_dim(bmap, isl_dim_in);
5269	if (total < 0 || nparam < 0 || n_in < 0)
5270		return isl_basic_map_free(bmap);
5271	i = isl_basic_map_alloc_inequality(bmap);
5272	if (i < 0)
5273		goto error;
5274	isl_seq_clr(bmap->ineq[i], 1 + total);
5275	isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
5276	isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
5277	return isl_basic_map_finalize(bmap);
5278error:
5279	isl_basic_map_free(bmap);
5280	return NULL;
5281}
5282
5283__isl_give isl_basic_map *isl_basic_map_equal(
5284	__isl_take isl_space *space, unsigned n_equal)
5285{
5286	int i;
5287	struct isl_basic_map *bmap;
5288	bmap = isl_basic_map_alloc_space(space, 0, n_equal, 0);
5289	if (!bmap)
5290		return NULL;
5291	for (i = 0; i < n_equal && bmap; ++i)
5292		bmap = var_equal(bmap, i);
5293	return isl_basic_map_finalize(bmap);
5294}
5295
5296/* Return a relation on of dimension "space" expressing i_[0..pos] << o_[0..pos]
5297 */
5298__isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *space,
5299	unsigned pos)
5300{
5301	int i;
5302	struct isl_basic_map *bmap;
5303	bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5304	if (!bmap)
5305		return NULL;
5306	for (i = 0; i < pos && bmap; ++i)
5307		bmap = var_equal(bmap, i);
5308	if (bmap)
5309		bmap = var_less(bmap, pos);
5310	return isl_basic_map_finalize(bmap);
5311}
5312
5313/* Return a relation on "space" expressing i_[0..pos] <<= o_[0..pos]
5314 */
5315__isl_give isl_basic_map *isl_basic_map_less_or_equal_at(
5316	__isl_take isl_space *space, unsigned pos)
5317{
5318	int i;
5319	isl_basic_map *bmap;
5320
5321	bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5322	for (i = 0; i < pos; ++i)
5323		bmap = var_equal(bmap, i);
5324	bmap = var_less_or_equal(bmap, pos);
5325	return isl_basic_map_finalize(bmap);
5326}
5327
5328/* Return a relation on "space" expressing i_pos > o_pos
5329 */
5330__isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *space,
5331	unsigned pos)
5332{
5333	int i;
5334	struct isl_basic_map *bmap;
5335	bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5336	if (!bmap)
5337		return NULL;
5338	for (i = 0; i < pos && bmap; ++i)
5339		bmap = var_equal(bmap, i);
5340	if (bmap)
5341		bmap = var_more(bmap, pos);
5342	return isl_basic_map_finalize(bmap);
5343}
5344
5345/* Return a relation on "space" expressing i_[0..pos] >>= o_[0..pos]
5346 */
5347__isl_give isl_basic_map *isl_basic_map_more_or_equal_at(
5348	__isl_take isl_space *space, unsigned pos)
5349{
5350	int i;
5351	isl_basic_map *bmap;
5352
5353	bmap = isl_basic_map_alloc_space(space, 0, pos, 1);
5354	for (i = 0; i < pos; ++i)
5355		bmap = var_equal(bmap, i);
5356	bmap = var_more_or_equal(bmap, pos);
5357	return isl_basic_map_finalize(bmap);
5358}
5359
5360static __isl_give isl_map *map_lex_lte_first(__isl_take isl_space *space,
5361	unsigned n, int equal)
5362{
5363	struct isl_map *map;
5364	int i;
5365
5366	if (n == 0 && equal)
5367		return isl_map_universe(space);
5368
5369	map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT);
5370
5371	for (i = 0; i + 1 < n; ++i)
5372		map = isl_map_add_basic_map(map,
5373				  isl_basic_map_less_at(isl_space_copy(space), i));
5374	if (n > 0) {
5375		if (equal)
5376			map = isl_map_add_basic_map(map,
5377			      isl_basic_map_less_or_equal_at(space, n - 1));
5378		else
5379			map = isl_map_add_basic_map(map,
5380			      isl_basic_map_less_at(space, n - 1));
5381	} else
5382		isl_space_free(space);
5383
5384	return map;
5385}
5386
5387static __isl_give isl_map *map_lex_lte(__isl_take isl_space *space, int equal)
5388{
5389	if (!space)
5390		return NULL;
5391	return map_lex_lte_first(space, space->n_out, equal);
5392}
5393
5394__isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *space,
5395	unsigned n)
5396{
5397	return map_lex_lte_first(space, n, 0);
5398}
5399
5400__isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *space,
5401	unsigned n)
5402{
5403	return map_lex_lte_first(space, n, 1);
5404}
5405
5406__isl_give isl_map *isl_map_lex_lt(__isl_take isl_space *set_space)
5407{
5408	return map_lex_lte(isl_space_map_from_set(set_space), 0);
5409}
5410
5411__isl_give isl_map *isl_map_lex_le(__isl_take isl_space *set_space)
5412{
5413	return map_lex_lte(isl_space_map_from_set(set_space), 1);
5414}
5415
5416static __isl_give isl_map *map_lex_gte_first(__isl_take isl_space *space,
5417	unsigned n, int equal)
5418{
5419	struct isl_map *map;
5420	int i;
5421
5422	if (n == 0 && equal)
5423		return isl_map_universe(space);
5424
5425	map = isl_map_alloc_space(isl_space_copy(space), n, ISL_MAP_DISJOINT);
5426
5427	for (i = 0; i + 1 < n; ++i)
5428		map = isl_map_add_basic_map(map,
5429				  isl_basic_map_more_at(isl_space_copy(space), i));
5430	if (n > 0) {
5431		if (equal)
5432			map = isl_map_add_basic_map(map,
5433			      isl_basic_map_more_or_equal_at(space, n - 1));
5434		else
5435			map = isl_map_add_basic_map(map,
5436			      isl_basic_map_more_at(space, n - 1));
5437	} else
5438		isl_space_free(space);
5439
5440	return map;
5441}
5442
5443static __isl_give isl_map *map_lex_gte(__isl_take isl_space *space, int equal)
5444{
5445	if (!space)
5446		return NULL;
5447	return map_lex_gte_first(space, space->n_out, equal);
5448}
5449
5450__isl_give isl_map *isl_map_lex_gt_first(__isl_take isl_space *space,
5451	unsigned n)
5452{
5453	return map_lex_gte_first(space, n, 0);
5454}
5455
5456__isl_give isl_map *isl_map_lex_ge_first(__isl_take isl_space *space,
5457	unsigned n)
5458{
5459	return map_lex_gte_first(space, n, 1);
5460}
5461
5462__isl_give isl_map *isl_map_lex_gt(__isl_take isl_space *set_space)
5463{
5464	return map_lex_gte(isl_space_map_from_set(set_space), 0);
5465}
5466
5467__isl_give isl_map *isl_map_lex_ge(__isl_take isl_space *set_space)
5468{
5469	return map_lex_gte(isl_space_map_from_set(set_space), 1);
5470}
5471
5472__isl_give isl_map *isl_set_lex_le_set(__isl_take isl_set *set1,
5473	__isl_take isl_set *set2)
5474{
5475	isl_map *map;
5476	map = isl_map_lex_le(isl_set_get_space(set1));
5477	map = isl_map_intersect_domain(map, set1);
5478	map = isl_map_intersect_range(map, set2);
5479	return map;
5480}
5481
5482__isl_give isl_map *isl_set_lex_lt_set(__isl_take isl_set *set1,
5483	__isl_take isl_set *set2)
5484{
5485	isl_map *map;
5486	map = isl_map_lex_lt(isl_set_get_space(set1));
5487	map = isl_map_intersect_domain(map, set1);
5488	map = isl_map_intersect_range(map, set2);
5489	return map;
5490}
5491
5492__isl_give isl_map *isl_set_lex_ge_set(__isl_take isl_set *set1,
5493	__isl_take isl_set *set2)
5494{
5495	isl_map *map;
5496	map = isl_map_lex_ge(isl_set_get_space(set1));
5497	map = isl_map_intersect_domain(map, set1);
5498	map = isl_map_intersect_range(map, set2);
5499	return map;
5500}
5501
5502__isl_give isl_map *isl_set_lex_gt_set(__isl_take isl_set *set1,
5503	__isl_take isl_set *set2)
5504{
5505	isl_map *map;
5506	map = isl_map_lex_gt(isl_set_get_space(set1));
5507	map = isl_map_intersect_domain(map, set1);
5508	map = isl_map_intersect_range(map, set2);
5509	return map;
5510}
5511
5512__isl_give isl_map *isl_map_lex_le_map(__isl_take isl_map *map1,
5513	__isl_take isl_map *map2)
5514{
5515	isl_map *map;
5516	map = isl_map_lex_le(isl_space_range(isl_map_get_space(map1)));
5517	map = isl_map_apply_domain(map, isl_map_reverse(map1));
5518	map = isl_map_apply_range(map, isl_map_reverse(map2));
5519	return map;
5520}
5521
5522__isl_give isl_map *isl_map_lex_lt_map(__isl_take isl_map *map1,
5523	__isl_take isl_map *map2)
5524{
5525	isl_map *map;
5526	map = isl_map_lex_lt(isl_space_range(isl_map_get_space(map1)));
5527	map = isl_map_apply_domain(map, isl_map_reverse(map1));
5528	map = isl_map_apply_range(map, isl_map_reverse(map2));
5529	return map;
5530}
5531
5532__isl_give isl_map *isl_map_lex_ge_map(__isl_take isl_map *map1,
5533	__isl_take isl_map *map2)
5534{
5535	isl_map *map;
5536	map = isl_map_lex_ge(isl_space_range(isl_map_get_space(map1)));
5537	map = isl_map_apply_domain(map, isl_map_reverse(map1));
5538	map = isl_map_apply_range(map, isl_map_reverse(map2));
5539	return map;
5540}
5541
5542__isl_give isl_map *isl_map_lex_gt_map(__isl_take isl_map *map1,
5543	__isl_take isl_map *map2)
5544{
5545	isl_map *map;
5546	map = isl_map_lex_gt(isl_space_range(isl_map_get_space(map1)));
5547	map = isl_map_apply_domain(map, isl_map_reverse(map1));
5548	map = isl_map_apply_range(map, isl_map_reverse(map2));
5549	return map;
5550}
5551
5552/* For the div d = floor(f/m) at position "div", add the constraint
5553 *
5554 *		f - m d >= 0
5555 */
5556static __isl_give isl_basic_map *add_upper_div_constraint(
5557	__isl_take isl_basic_map *bmap, unsigned div)
5558{
5559	int i;
5560	isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
5561	isl_size n_div;
5562	unsigned pos;
5563
5564	n_div = isl_basic_map_dim(bmap, isl_dim_div);
5565	if (v_div < 0 || n_div < 0)
5566		return isl_basic_map_free(bmap);
5567	pos = v_div + div;
5568	i = isl_basic_map_alloc_inequality(bmap);
5569	if (i < 0)
5570		return isl_basic_map_free(bmap);
5571	isl_seq_cpy(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
5572	isl_int_neg(bmap->ineq[i][1 + pos], bmap->div[div][0]);
5573
5574	return bmap;
5575}
5576
5577/* For the div d = floor(f/m) at position "div", add the constraint
5578 *
5579 *		-(f-(m-1)) + m d >= 0
5580 */
5581static __isl_give isl_basic_map *add_lower_div_constraint(
5582	__isl_take isl_basic_map *bmap, unsigned div)
5583{
5584	int i;
5585	isl_size v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
5586	isl_size n_div;
5587	unsigned pos;
5588
5589	n_div = isl_basic_map_dim(bmap, isl_dim_div);
5590	if (v_div < 0 || n_div < 0)
5591		return isl_basic_map_free(bmap);
5592	pos = v_div + div;
5593	i = isl_basic_map_alloc_inequality(bmap);
5594	if (i < 0)
5595		return isl_basic_map_free(bmap);
5596	isl_seq_neg(bmap->ineq[i], bmap->div[div] + 1, 1 + v_div + n_div);
5597	isl_int_set(bmap->ineq[i][1 + pos], bmap->div[div][0]);
5598	isl_int_add(bmap->ineq[i][0], bmap->ineq[i][0], bmap->ineq[i][1 + pos]);
5599	isl_int_sub_ui(bmap->ineq[i][0], bmap->ineq[i][0], 1);
5600
5601	return bmap;
5602}
5603
5604/* For the div d = floor(f/m) at position "pos", add the constraints
5605 *
5606 *		f - m d >= 0
5607 *		-(f-(m-1)) + m d >= 0
5608 *
5609 * Note that the second constraint is the negation of
5610 *
5611 *		f - m d >= m
5612 */
5613__isl_give isl_basic_map *isl_basic_map_add_div_constraints(
5614	__isl_take isl_basic_map *bmap, unsigned pos)
5615{
5616	bmap = add_upper_div_constraint(bmap, pos);
5617	bmap = add_lower_div_constraint(bmap, pos);
5618	return bmap;
5619}
5620
5621/* For each known div d = floor(f/m), add the constraints
5622 *
5623 *		f - m d >= 0
5624 *		-(f-(m-1)) + m d >= 0
5625 *
5626 * Remove duplicate constraints in case of some these div constraints
5627 * already appear in "bmap".
5628 */
5629__isl_give isl_basic_map *isl_basic_map_add_known_div_constraints(
5630	__isl_take isl_basic_map *bmap)
5631{
5632	isl_size n_div;
5633
5634	n_div = isl_basic_map_dim(bmap, isl_dim_div);
5635	if (n_div < 0)
5636		return isl_basic_map_free(bmap);
5637	if (n_div == 0)
5638		return bmap;
5639
5640	bmap = add_known_div_constraints(bmap);
5641	bmap = isl_basic_map_remove_duplicate_constraints(bmap, NULL, 0);
5642	bmap = isl_basic_map_finalize(bmap);
5643	return bmap;
5644}
5645
5646/* Add the div constraint of sign "sign" for div "div" of "bmap".
5647 *
5648 * In particular, if this div is of the form d = floor(f/m),
5649 * then add the constraint
5650 *
5651 *		f - m d >= 0
5652 *
5653 * if sign < 0 or the constraint
5654 *
5655 *		-(f-(m-1)) + m d >= 0
5656 *
5657 * if sign > 0.
5658 */
5659__isl_give isl_basic_map *isl_basic_map_add_div_constraint(
5660	__isl_take isl_basic_map *bmap, unsigned div, int sign)
5661{
5662	if (sign < 0)
5663		return add_upper_div_constraint(bmap, div);
5664	else
5665		return add_lower_div_constraint(bmap, div);
5666}
5667
5668__isl_give isl_basic_set *isl_basic_map_underlying_set(
5669	__isl_take isl_basic_map *bmap)
5670{
5671	isl_space *space;
5672
5673	if (!bmap)
5674		goto error;
5675	if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
5676	    bmap->n_div == 0 &&
5677	    !isl_space_is_named_or_nested(bmap->dim, isl_dim_in) &&
5678	    !isl_space_is_named_or_nested(bmap->dim, isl_dim_out))
5679		return bset_from_bmap(bmap);
5680	bmap = isl_basic_map_cow(bmap);
5681	if (!bmap)
5682		return NULL;
5683	space = isl_basic_map_take_space(bmap);
5684	space = isl_space_underlying(space, bmap->n_div);
5685	bmap = isl_basic_map_restore_space(bmap, space);
5686	if (!bmap)
5687		return NULL;
5688	bmap->extra -= bmap->n_div;
5689	bmap->n_div = 0;
5690	bmap = isl_basic_map_finalize(bmap);
5691	return bset_from_bmap(bmap);
5692error:
5693	isl_basic_map_free(bmap);
5694	return NULL;
5695}
5696
5697__isl_give isl_basic_set *isl_basic_set_underlying_set(
5698		__isl_take isl_basic_set *bset)
5699{
5700	return isl_basic_map_underlying_set(bset_to_bmap(bset));
5701}
5702
5703/* Replace each element in "list" by the result of applying
5704 * isl_basic_map_underlying_set to the element.
5705 */
5706__isl_give isl_basic_set_list *isl_basic_map_list_underlying_set(
5707	__isl_take isl_basic_map_list *list)
5708{
5709	int i;
5710	isl_size n;
5711
5712	n = isl_basic_map_list_n_basic_map(list);
5713	if (n < 0)
5714		goto error;
5715
5716	for (i = 0; i < n; ++i) {
5717		isl_basic_map *bmap;
5718		isl_basic_set *bset;
5719
5720		bmap = isl_basic_map_list_get_basic_map(list, i);
5721		bset = isl_basic_set_underlying_set(bmap);
5722		list = isl_basic_set_list_set_basic_set(list, i, bset);
5723	}
5724
5725	return list;
5726error:
5727	isl_basic_map_list_free(list);
5728	return NULL;
5729}
5730
5731__isl_give isl_basic_map *isl_basic_map_overlying_set(
5732	__isl_take isl_basic_set *bset, __isl_take isl_basic_map *like)
5733{
5734	struct isl_basic_map *bmap;
5735	struct isl_ctx *ctx;
5736	isl_size dim, bmap_total;
5737	unsigned total;
5738	int i;
5739
5740	if (!bset || !like)
5741		goto error;
5742	ctx = bset->ctx;
5743	if (isl_basic_set_check_no_params(bset) < 0 ||
5744	    isl_basic_set_check_no_locals(bset) < 0)
5745		goto error;
5746	dim = isl_basic_set_dim(bset, isl_dim_set);
5747	bmap_total = isl_basic_map_dim(like, isl_dim_all);
5748	if (dim < 0 || bmap_total < 0)
5749		goto error;
5750	isl_assert(ctx, dim == bmap_total, goto error);
5751	if (like->n_div == 0) {
5752		isl_space *space = isl_basic_map_get_space(like);
5753		isl_basic_map_free(like);
5754		return isl_basic_map_reset_space(bset, space);
5755	}
5756	bset = isl_basic_set_cow(bset);
5757	if (!bset)
5758		goto error;
5759	total = dim + bset->extra;
5760	bmap = bset_to_bmap(bset);
5761	isl_space_free(isl_basic_map_take_space(bmap));
5762	bmap = isl_basic_map_restore_space(bmap, isl_basic_map_get_space(like));
5763	if (!bmap)
5764		goto error;
5765	bmap->n_div = like->n_div;
5766	bmap->extra += like->n_div;
5767	if (bmap->extra) {
5768		unsigned ltotal;
5769		isl_int **div;
5770		ltotal = total - bmap->extra + like->extra;
5771		if (ltotal > total)
5772			ltotal = total;
5773		bmap->block2 = isl_blk_extend(ctx, bmap->block2,
5774					bmap->extra * (1 + 1 + total));
5775		if (isl_blk_is_error(bmap->block2))
5776			goto error;
5777		div = isl_realloc_array(ctx, bmap->div, isl_int *, bmap->extra);
5778		if (!div)
5779			goto error;
5780		bmap->div = div;
5781		for (i = 0; i < bmap->extra; ++i)
5782			bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
5783		for (i = 0; i < like->n_div; ++i) {
5784			isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
5785			isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
5786		}
5787		bmap = isl_basic_map_add_known_div_constraints(bmap);
5788	}
5789	isl_basic_map_free(like);
5790	bmap = isl_basic_map_simplify(bmap);
5791	bmap = isl_basic_map_finalize(bmap);
5792	return bmap;
5793error:
5794	isl_basic_map_free(like);
5795	isl_basic_set_free(bset);
5796	return NULL;
5797}
5798
5799__isl_give isl_basic_set *isl_basic_set_from_underlying_set(
5800	__isl_take isl_basic_set *bset, __isl_take isl_basic_set *like)
5801{
5802	return bset_from_bmap(isl_basic_map_overlying_set(bset,
5803							bset_to_bmap(like)));
5804}
5805
5806__isl_give isl_set *isl_map_underlying_set(__isl_take isl_map *map)
5807{
5808	int i;
5809
5810	map = isl_map_cow(map);
5811	if (!map)
5812		return NULL;
5813	map->dim = isl_space_cow(map->dim);
5814	if (!map->dim)
5815		goto error;
5816
5817	for (i = 1; i < map->n; ++i)
5818		isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,
5819				goto error);
5820	for (i = 0; i < map->n; ++i) {
5821		map->p[i] = bset_to_bmap(
5822				isl_basic_map_underlying_set(map->p[i]));
5823		if (!map->p[i])
5824			goto error;
5825	}
5826	if (map->n == 0)
5827		map->dim = isl_space_underlying(map->dim, 0);
5828	else {
5829		isl_space_free(map->dim);
5830		map->dim = isl_space_copy(map->p[0]->dim);
5831	}
5832	if (!map->dim)
5833		goto error;
5834	return set_from_map(map);
5835error:
5836	isl_map_free(map);
5837	return NULL;
5838}
5839
5840/* Replace the space of "bmap" by "space".
5841 *
5842 * If the space of "bmap" is identical to "space" (including the identifiers
5843 * of the input and output dimensions), then simply return the original input.
5844 */
5845__isl_give isl_basic_map *isl_basic_map_reset_space(
5846	__isl_take isl_basic_map *bmap, __isl_take isl_space *space)
5847{
5848	isl_bool equal;
5849	isl_space *bmap_space;
5850
5851	bmap_space = isl_basic_map_peek_space(bmap);
5852	equal = isl_space_is_equal(bmap_space, space);
5853	if (equal >= 0 && equal)
5854		equal = isl_space_has_equal_ids(bmap_space, space);
5855	if (equal < 0)
5856		goto error;
5857	if (equal) {
5858		isl_space_free(space);
5859		return bmap;
5860	}
5861	isl_space_free(isl_basic_map_take_space(bmap));
5862	bmap = isl_basic_map_restore_space(bmap, space);
5863
5864	bmap = isl_basic_map_finalize(bmap);
5865
5866	return bmap;
5867error:
5868	isl_basic_map_free(bmap);
5869	isl_space_free(space);
5870	return NULL;
5871}
5872
5873__isl_give isl_basic_set *isl_basic_set_reset_space(
5874	__isl_take isl_basic_set *bset, __isl_take isl_space *space)
5875{
5876	return bset_from_bmap(isl_basic_map_reset_space(bset_to_bmap(bset),
5877							space));
5878}
5879
5880/* Check that the total dimensions of "map" and "space" are the same.
5881 */
5882static isl_stat check_map_space_equal_total_dim(__isl_keep isl_map *map,
5883	__isl_keep isl_space *space)
5884{
5885	isl_size dim1, dim2;
5886
5887	dim1 = isl_map_dim(map, isl_dim_all);
5888	dim2 = isl_space_dim(space, isl_dim_all);
5889	if (dim1 < 0 || dim2 < 0)
5890		return isl_stat_error;
5891	if (dim1 == dim2)
5892		return isl_stat_ok;
5893	isl_die(isl_map_get_ctx(map), isl_error_invalid,
5894		"total dimensions do not match", return isl_stat_error);
5895}
5896
5897__isl_give isl_map *isl_map_reset_space(__isl_take isl_map *map,
5898	__isl_take isl_space *space)
5899{
5900	int i;
5901
5902	map = isl_map_cow(map);
5903	if (!map || !space)
5904		goto error;
5905
5906	for (i = 0; i < map->n; ++i) {
5907		map->p[i] = isl_basic_map_reset_space(map->p[i],
5908						    isl_space_copy(space));
5909		if (!map->p[i])
5910			goto error;
5911	}
5912	isl_space_free(isl_map_take_space(map));
5913	map = isl_map_restore_space(map, space);
5914
5915	return map;
5916error:
5917	isl_map_free(map);
5918	isl_space_free(space);
5919	return NULL;
5920}
5921
5922/* Replace the space of "map" by "space", without modifying
5923 * the dimension of "map".
5924 *
5925 * If the space of "map" is identical to "space" (including the identifiers
5926 * of the input and output dimensions), then simply return the original input.
5927 */
5928__isl_give isl_map *isl_map_reset_equal_dim_space(__isl_take isl_map *map,
5929	__isl_take isl_space *space)
5930{
5931	isl_bool equal;
5932	isl_space *map_space;
5933
5934	map_space = isl_map_peek_space(map);
5935	equal = isl_space_is_equal(map_space, space);
5936	if (equal >= 0 && equal)
5937		equal = isl_space_has_equal_ids(map_space, space);
5938	if (equal < 0)
5939		goto error;
5940	if (equal) {
5941		isl_space_free(space);
5942		return map;
5943	}
5944	if (check_map_space_equal_total_dim(map, space) < 0)
5945		goto error;
5946	return isl_map_reset_space(map, space);
5947error:
5948	isl_map_free(map);
5949	isl_space_free(space);
5950	return NULL;
5951}
5952
5953__isl_give isl_set *isl_set_reset_space(__isl_take isl_set *set,
5954	__isl_take isl_space *space)
5955{
5956	return set_from_map(isl_map_reset_space(set_to_map(set), space));
5957}
5958
5959/* Compute the parameter domain of the given basic set.
5960 */
5961__isl_give isl_basic_set *isl_basic_set_params(__isl_take isl_basic_set *bset)
5962{
5963	isl_bool is_params;
5964	isl_space *space;
5965	isl_size n;
5966
5967	is_params = isl_basic_set_is_params(bset);
5968	if (is_params < 0)
5969		return isl_basic_set_free(bset);
5970	if (is_params)
5971		return bset;
5972
5973	n = isl_basic_set_dim(bset, isl_dim_set);
5974	if (n < 0)
5975		return isl_basic_set_free(bset);
5976	bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
5977	space = isl_basic_set_get_space(bset);
5978	space = isl_space_params(space);
5979	bset = isl_basic_set_reset_space(bset, space);
5980	return bset;
5981}
5982
5983/* Construct a zero-dimensional basic set with the given parameter domain.
5984 */
5985__isl_give isl_basic_set *isl_basic_set_from_params(
5986	__isl_take isl_basic_set *bset)
5987{
5988	isl_space *space;
5989	space = isl_basic_set_get_space(bset);
5990	space = isl_space_set_from_params(space);
5991	bset = isl_basic_set_reset_space(bset, space);
5992	return bset;
5993}
5994
5995/* Compute the parameter domain of the given set.
5996 */
5997__isl_give isl_set *isl_set_params(__isl_take isl_set *set)
5998{
5999	return isl_map_params(set_to_map(set));
6000}
6001
6002/* Construct a zero-dimensional set with the given parameter domain.
6003 */
6004__isl_give isl_set *isl_set_from_params(__isl_take isl_set *set)
6005{
6006	isl_space *space;
6007	space = isl_set_get_space(set);
6008	space = isl_space_set_from_params(space);
6009	set = isl_set_reset_space(set, space);
6010	return set;
6011}
6012
6013/* Compute the parameter domain of the given map.
6014 */
6015__isl_give isl_set *isl_map_params(__isl_take isl_map *map)
6016{
6017	isl_space *space;
6018	isl_size n_in, n_out;
6019
6020	n_in = isl_map_dim(map, isl_dim_in);
6021	n_out = isl_map_dim(map, isl_dim_out);
6022	if (n_in < 0 || n_out < 0)
6023		return isl_map_free(map);
6024	map = isl_map_project_out(map, isl_dim_in, 0, n_in);
6025	map = isl_map_project_out(map, isl_dim_out, 0, n_out);
6026	space = isl_map_get_space(map);
6027	space = isl_space_params(space);
6028	map = isl_map_reset_space(map, space);
6029	return map;
6030}
6031
6032__isl_give isl_basic_set *isl_basic_map_domain(__isl_take isl_basic_map *bmap)
6033{
6034	isl_space *space;
6035	isl_size n_out;
6036
6037	n_out = isl_basic_map_dim(bmap, isl_dim_out);
6038	if (n_out < 0)
6039		return isl_basic_map_free(bmap);
6040	space = isl_space_domain(isl_basic_map_get_space(bmap));
6041
6042	bmap = isl_basic_map_project_out(bmap, isl_dim_out, 0, n_out);
6043
6044	return isl_basic_map_reset_space(bmap, space);
6045}
6046
6047isl_bool isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap)
6048{
6049	if (!bmap)
6050		return isl_bool_error;
6051	return isl_space_may_be_set(bmap->dim);
6052}
6053
6054/* Is this basic map actually a set?
6055 * Users should never call this function.  Outside of isl,
6056 * the type should indicate whether something is a set or a map.
6057 */
6058isl_bool isl_basic_map_is_set(__isl_keep isl_basic_map *bmap)
6059{
6060	if (!bmap)
6061		return isl_bool_error;
6062	return isl_space_is_set(bmap->dim);
6063}
6064
6065__isl_give isl_basic_set *isl_basic_map_range(__isl_take isl_basic_map *bmap)
6066{
6067	isl_bool is_set;
6068
6069	is_set = isl_basic_map_is_set(bmap);
6070	if (is_set < 0)
6071		goto error;
6072	if (is_set)
6073		return bmap;
6074	return isl_basic_map_domain(isl_basic_map_reverse(bmap));
6075error:
6076	isl_basic_map_free(bmap);
6077	return NULL;
6078}
6079
6080__isl_give isl_basic_map *isl_basic_map_domain_map(
6081	__isl_take isl_basic_map *bmap)
6082{
6083	int i;
6084	isl_space *space;
6085	isl_basic_map *domain;
6086	isl_size nparam, n_in, n_out;
6087
6088	nparam = isl_basic_map_dim(bmap, isl_dim_param);
6089	n_in = isl_basic_map_dim(bmap, isl_dim_in);
6090	n_out = isl_basic_map_dim(bmap, isl_dim_out);
6091	if (nparam < 0 || n_in < 0 || n_out < 0)
6092		return isl_basic_map_free(bmap);
6093
6094	space = isl_basic_map_get_space(bmap);
6095	space = isl_space_from_range(isl_space_domain(space));
6096	domain = isl_basic_map_universe(space);
6097
6098	bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
6099	bmap = isl_basic_map_apply_range(bmap, domain);
6100	bmap = isl_basic_map_extend_constraints(bmap, n_in, 0);
6101
6102	for (i = 0; i < n_in; ++i)
6103		bmap = isl_basic_map_equate(bmap, isl_dim_in, i,
6104						    isl_dim_out, i);
6105
6106	bmap = isl_basic_map_gauss(bmap, NULL);
6107	return isl_basic_map_finalize(bmap);
6108}
6109
6110__isl_give isl_basic_map *isl_basic_map_range_map(
6111	__isl_take isl_basic_map *bmap)
6112{
6113	int i;
6114	isl_space *space;
6115	isl_basic_map *range;
6116	isl_size nparam, n_in, n_out;
6117
6118	nparam = isl_basic_map_dim(bmap, isl_dim_param);
6119	n_in = isl_basic_map_dim(bmap, isl_dim_in);
6120	n_out = isl_basic_map_dim(bmap, isl_dim_out);
6121	if (nparam < 0 || n_in < 0 || n_out < 0)
6122		return isl_basic_map_free(bmap);
6123
6124	space = isl_basic_map_get_space(bmap);
6125	space = isl_space_from_range(isl_space_range(space));
6126	range = isl_basic_map_universe(space);
6127
6128	bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
6129	bmap = isl_basic_map_apply_range(bmap, range);
6130	bmap = isl_basic_map_extend_constraints(bmap, n_out, 0);
6131
6132	for (i = 0; i < n_out; ++i)
6133		bmap = isl_basic_map_equate(bmap, isl_dim_in, n_in + i,
6134						    isl_dim_out, i);
6135
6136	bmap = isl_basic_map_gauss(bmap, NULL);
6137	return isl_basic_map_finalize(bmap);
6138}
6139
6140int isl_map_may_be_set(__isl_keep isl_map *map)
6141{
6142	if (!map)
6143		return -1;
6144	return isl_space_may_be_set(map->dim);
6145}
6146
6147/* Is this map actually a set?
6148 * Users should never call this function.  Outside of isl,
6149 * the type should indicate whether something is a set or a map.
6150 */
6151isl_bool isl_map_is_set(__isl_keep isl_map *map)
6152{
6153	if (!map)
6154		return isl_bool_error;
6155	return isl_space_is_set(map->dim);
6156}
6157
6158__isl_give isl_set *isl_map_range(__isl_take isl_map *map)
6159{
6160	isl_space *space;
6161	isl_size n_in;
6162
6163	n_in = isl_map_dim(map, isl_dim_in);
6164	if (n_in < 0)
6165		return set_from_map(isl_map_free(map));
6166	space = isl_space_range(isl_map_get_space(map));
6167
6168	map = isl_map_project_out(map, isl_dim_in, 0, n_in);
6169
6170	return set_from_map(isl_map_reset_space(map, space));
6171}
6172
6173/* Transform "map" by applying "fn_space" to its space and "fn_bmap"
6174 * to each of its basic maps.
6175 */
6176static __isl_give isl_map *isl_map_transform(__isl_take isl_map *map,
6177	__isl_give isl_space *(*fn_space)(__isl_take isl_space *space),
6178	__isl_give isl_basic_map *(*fn_bmap)(__isl_take isl_basic_map *bmap))
6179{
6180	int i;
6181	isl_space *space;
6182
6183	map = isl_map_cow(map);
6184	if (!map)
6185		return NULL;
6186
6187	for (i = 0; i < map->n; ++i) {
6188		map->p[i] = fn_bmap(map->p[i]);
6189		if (!map->p[i])
6190			return isl_map_free(map);
6191	}
6192	map = isl_map_unmark_normalized(map);
6193
6194	space = isl_map_take_space(map);
6195	space = fn_space(space);
6196	map = isl_map_restore_space(map, space);
6197
6198	return map;
6199}
6200
6201__isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map)
6202{
6203	return isl_map_transform(map, &isl_space_domain_map,
6204					&isl_basic_map_domain_map);
6205}
6206
6207__isl_give isl_map *isl_map_range_map(__isl_take isl_map *map)
6208{
6209	return isl_map_transform(map, &isl_space_range_map,
6210					&isl_basic_map_range_map);
6211}
6212
6213/* Given a wrapped map of the form A[B -> C],
6214 * return the map A[B -> C] -> B.
6215 */
6216__isl_give isl_map *isl_set_wrapped_domain_map(__isl_take isl_set *set)
6217{
6218	isl_id *id;
6219	isl_map *map;
6220
6221	if (!set)
6222		return NULL;
6223	if (!isl_set_has_tuple_id(set))
6224		return isl_map_domain_map(isl_set_unwrap(set));
6225
6226	id = isl_set_get_tuple_id(set);
6227	map = isl_map_domain_map(isl_set_unwrap(set));
6228	map = isl_map_set_tuple_id(map, isl_dim_in, id);
6229
6230	return map;
6231}
6232
6233__isl_give isl_basic_map *isl_basic_map_from_domain(
6234	__isl_take isl_basic_set *bset)
6235{
6236	return isl_basic_map_reverse(isl_basic_map_from_range(bset));
6237}
6238
6239__isl_give isl_basic_map *isl_basic_map_from_range(
6240	__isl_take isl_basic_set *bset)
6241{
6242	isl_space *space;
6243	space = isl_basic_set_get_space(bset);
6244	space = isl_space_from_range(space);
6245	bset = isl_basic_set_reset_space(bset, space);
6246	return bset_to_bmap(bset);
6247}
6248
6249/* Create a relation with the given set as range.
6250 * The domain of the created relation is a zero-dimensional
6251 * flat anonymous space.
6252 */
6253__isl_give isl_map *isl_map_from_range(__isl_take isl_set *set)
6254{
6255	isl_space *space;
6256	space = isl_set_get_space(set);
6257	space = isl_space_from_range(space);
6258	set = isl_set_reset_space(set, space);
6259	return set_to_map(set);
6260}
6261
6262/* Create a relation with the given set as domain.
6263 * The range of the created relation is a zero-dimensional
6264 * flat anonymous space.
6265 */
6266__isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set)
6267{
6268	return isl_map_reverse(isl_map_from_range(set));
6269}
6270
6271__isl_give isl_basic_map *isl_basic_map_from_domain_and_range(
6272	__isl_take isl_basic_set *domain, __isl_take isl_basic_set *range)
6273{
6274	return isl_basic_map_apply_range(isl_basic_map_reverse(domain), range);
6275}
6276
6277__isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain,
6278	__isl_take isl_set *range)
6279{
6280	return isl_map_apply_range(isl_map_reverse(domain), range);
6281}
6282
6283/* Return a newly allocated isl_map with given space and flags and
6284 * room for "n" basic maps.
6285 * Make sure that all cached information is cleared.
6286 */
6287__isl_give isl_map *isl_map_alloc_space(__isl_take isl_space *space, int n,
6288	unsigned flags)
6289{
6290	struct isl_map *map;
6291
6292	if (!space)
6293		return NULL;
6294	if (n < 0)
6295		isl_die(space->ctx, isl_error_internal,
6296			"negative number of basic maps", goto error);
6297	map = isl_calloc(space->ctx, struct isl_map,
6298			sizeof(struct isl_map) +
6299			(n - 1) * sizeof(struct isl_basic_map *));
6300	if (!map)
6301		goto error;
6302
6303	map->ctx = space->ctx;
6304	isl_ctx_ref(map->ctx);
6305	map->ref = 1;
6306	map->size = n;
6307	map->n = 0;
6308	map->dim = space;
6309	map->flags = flags;
6310	return map;
6311error:
6312	isl_space_free(space);
6313	return NULL;
6314}
6315
6316__isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *space)
6317{
6318	struct isl_basic_map *bmap;
6319	bmap = isl_basic_map_alloc_space(space, 0, 1, 0);
6320	bmap = isl_basic_map_set_to_empty(bmap);
6321	return bmap;
6322}
6323
6324__isl_give isl_basic_set *isl_basic_set_empty(__isl_take isl_space *space)
6325{
6326	struct isl_basic_set *bset;
6327	bset = isl_basic_set_alloc_space(space, 0, 1, 0);
6328	bset = isl_basic_set_set_to_empty(bset);
6329	return bset;
6330}
6331
6332__isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *space)
6333{
6334	struct isl_basic_map *bmap;
6335	bmap = isl_basic_map_alloc_space(space, 0, 0, 0);
6336	bmap = isl_basic_map_finalize(bmap);
6337	return bmap;
6338}
6339
6340__isl_give isl_basic_set *isl_basic_set_universe(__isl_take isl_space *space)
6341{
6342	struct isl_basic_set *bset;
6343	bset = isl_basic_set_alloc_space(space, 0, 0, 0);
6344	bset = isl_basic_set_finalize(bset);
6345	return bset;
6346}
6347
6348__isl_give isl_basic_map *isl_basic_map_nat_universe(
6349	__isl_take isl_space *space)
6350{
6351	int i;
6352	isl_size total = isl_space_dim(space, isl_dim_all);
6353	isl_basic_map *bmap;
6354
6355	if (total < 0)
6356		space = isl_space_free(space);
6357	bmap = isl_basic_map_alloc_space(space, 0, 0, total);
6358	for (i = 0; i < total; ++i) {
6359		int k = isl_basic_map_alloc_inequality(bmap);
6360		if (k < 0)
6361			goto error;
6362		isl_seq_clr(bmap->ineq[k], 1 + total);
6363		isl_int_set_si(bmap->ineq[k][1 + i], 1);
6364	}
6365	return bmap;
6366error:
6367	isl_basic_map_free(bmap);
6368	return NULL;
6369}
6370
6371__isl_give isl_basic_set *isl_basic_set_nat_universe(
6372	__isl_take isl_space *space)
6373{
6374	return isl_basic_map_nat_universe(space);
6375}
6376
6377__isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *space)
6378{
6379	return isl_map_from_basic_map(isl_basic_map_nat_universe(space));
6380}
6381
6382__isl_give isl_set *isl_set_nat_universe(__isl_take isl_space *space)
6383{
6384	return isl_map_nat_universe(space);
6385}
6386
6387__isl_give isl_map *isl_map_empty(__isl_take isl_space *space)
6388{
6389	return isl_map_alloc_space(space, 0, ISL_MAP_DISJOINT);
6390}
6391
6392__isl_give isl_set *isl_set_empty(__isl_take isl_space *space)
6393{
6394	return isl_set_alloc_space(space, 0, ISL_MAP_DISJOINT);
6395}
6396
6397__isl_give isl_map *isl_map_universe(__isl_take isl_space *space)
6398{
6399	struct isl_map *map;
6400	if (!space)
6401		return NULL;
6402	map = isl_map_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT);
6403	map = isl_map_add_basic_map(map, isl_basic_map_universe(space));
6404	return map;
6405}
6406
6407/* This function performs the same operation as isl_map_universe,
6408 * but is considered as a function on an isl_space when exported.
6409 */
6410__isl_give isl_map *isl_space_universe_map(__isl_take isl_space *space)
6411{
6412	return isl_map_universe(space);
6413}
6414
6415__isl_give isl_set *isl_set_universe(__isl_take isl_space *space)
6416{
6417	struct isl_set *set;
6418	if (!space)
6419		return NULL;
6420	set = isl_set_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT);
6421	set = isl_set_add_basic_set(set, isl_basic_set_universe(space));
6422	return set;
6423}
6424
6425/* This function performs the same operation as isl_set_universe,
6426 * but is considered as a function on an isl_space when exported.
6427 */
6428__isl_give isl_set *isl_space_universe_set(__isl_take isl_space *space)
6429{
6430	return isl_set_universe(space);
6431}
6432
6433__isl_give isl_map *isl_map_dup(__isl_keep isl_map *map)
6434{
6435	int i;
6436	struct isl_map *dup;
6437
6438	if (!map)
6439		return NULL;
6440	dup = isl_map_alloc_space(isl_space_copy(map->dim), map->n, map->flags);
6441	for (i = 0; i < map->n; ++i)
6442		dup = isl_map_add_basic_map(dup, isl_basic_map_copy(map->p[i]));
6443	return dup;
6444}
6445
6446__isl_give isl_map *isl_map_add_basic_map(__isl_take isl_map *map,
6447						__isl_take isl_basic_map *bmap)
6448{
6449	if (!bmap || !map)
6450		goto error;
6451	if (isl_basic_map_plain_is_empty(bmap)) {
6452		isl_basic_map_free(bmap);
6453		return map;
6454	}
6455	if (isl_map_basic_map_check_equal_space(map, bmap) < 0)
6456		goto error;
6457	isl_assert(map->ctx, map->n < map->size, goto error);
6458	map->p[map->n] = bmap;
6459	map->n++;
6460	map = isl_map_unmark_normalized(map);
6461	return map;
6462error:
6463	if (map)
6464		isl_map_free(map);
6465	if (bmap)
6466		isl_basic_map_free(bmap);
6467	return NULL;
6468}
6469
6470__isl_null isl_map *isl_map_free(__isl_take isl_map *map)
6471{
6472	int i;
6473
6474	if (!map)
6475		return NULL;
6476
6477	if (--map->ref > 0)
6478		return NULL;
6479
6480	clear_caches(map);
6481	isl_ctx_deref(map->ctx);
6482	for (i = 0; i < map->n; ++i)
6483		isl_basic_map_free(map->p[i]);
6484	isl_space_free(map->dim);
6485	free(map);
6486
6487	return NULL;
6488}
6489
6490static __isl_give isl_basic_map *isl_basic_map_fix_pos_si(
6491	__isl_take isl_basic_map *bmap, unsigned pos, int value)
6492{
6493	int j;
6494	isl_size total;
6495
6496	total = isl_basic_map_dim(bmap, isl_dim_all);
6497	if (total < 0)
6498		return isl_basic_map_free(bmap);
6499
6500	bmap = isl_basic_map_cow(bmap);
6501	bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
6502	j = isl_basic_map_alloc_equality(bmap);
6503	if (j < 0)
6504		goto error;
6505	isl_seq_clr(bmap->eq[j] + 1, total);
6506	isl_int_set_si(bmap->eq[j][pos], -1);
6507	isl_int_set_si(bmap->eq[j][0], value);
6508	bmap = isl_basic_map_simplify(bmap);
6509	return isl_basic_map_finalize(bmap);
6510error:
6511	isl_basic_map_free(bmap);
6512	return NULL;
6513}
6514
6515static __isl_give isl_basic_map *isl_basic_map_fix_pos(
6516	__isl_take isl_basic_map *bmap, unsigned pos, isl_int value)
6517{
6518	int j;
6519	isl_size total;
6520
6521	total = isl_basic_map_dim(bmap, isl_dim_all);
6522	if (total < 0)
6523		return isl_basic_map_free(bmap);
6524
6525	bmap = isl_basic_map_cow(bmap);
6526	bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
6527	j = isl_basic_map_alloc_equality(bmap);
6528	if (j < 0)
6529		goto error;
6530	isl_seq_clr(bmap->eq[j] + 1, total);
6531	isl_int_set_si(bmap->eq[j][pos], -1);
6532	isl_int_set(bmap->eq[j][0], value);
6533	bmap = isl_basic_map_simplify(bmap);
6534	return isl_basic_map_finalize(bmap);
6535error:
6536	isl_basic_map_free(bmap);
6537	return NULL;
6538}
6539
6540__isl_give isl_basic_map *isl_basic_map_fix_si(__isl_take isl_basic_map *bmap,
6541		enum isl_dim_type type, unsigned pos, int value)
6542{
6543	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6544		return isl_basic_map_free(bmap);
6545	return isl_basic_map_fix_pos_si(bmap,
6546		isl_basic_map_offset(bmap, type) + pos, value);
6547}
6548
6549__isl_give isl_basic_map *isl_basic_map_fix(__isl_take isl_basic_map *bmap,
6550		enum isl_dim_type type, unsigned pos, isl_int value)
6551{
6552	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6553		return isl_basic_map_free(bmap);
6554	return isl_basic_map_fix_pos(bmap,
6555		isl_basic_map_offset(bmap, type) + pos, value);
6556}
6557
6558/* Fix the value of the variable at position "pos" of type "type" of "bmap"
6559 * to be equal to "v".
6560 */
6561__isl_give isl_basic_map *isl_basic_map_fix_val(__isl_take isl_basic_map *bmap,
6562	enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6563{
6564	if (!bmap || !v)
6565		goto error;
6566	if (!isl_val_is_int(v))
6567		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
6568			"expecting integer value", goto error);
6569	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6570		goto error;
6571	pos += isl_basic_map_offset(bmap, type);
6572	bmap = isl_basic_map_fix_pos(bmap, pos, v->n);
6573	isl_val_free(v);
6574	return bmap;
6575error:
6576	isl_basic_map_free(bmap);
6577	isl_val_free(v);
6578	return NULL;
6579}
6580
6581/* Fix the value of the variable at position "pos" of type "type" of "bset"
6582 * to be equal to "v".
6583 */
6584__isl_give isl_basic_set *isl_basic_set_fix_val(__isl_take isl_basic_set *bset,
6585	enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6586{
6587	return isl_basic_map_fix_val(bset, type, pos, v);
6588}
6589
6590__isl_give isl_basic_set *isl_basic_set_fix_si(__isl_take isl_basic_set *bset,
6591		enum isl_dim_type type, unsigned pos, int value)
6592{
6593	return bset_from_bmap(isl_basic_map_fix_si(bset_to_bmap(bset),
6594						    type, pos, value));
6595}
6596
6597__isl_give isl_basic_set *isl_basic_set_fix(__isl_take isl_basic_set *bset,
6598		enum isl_dim_type type, unsigned pos, isl_int value)
6599{
6600	return bset_from_bmap(isl_basic_map_fix(bset_to_bmap(bset),
6601						    type, pos, value));
6602}
6603
6604/* Remove the basic map at position "i" from "map" if this basic map
6605 * is (obviously) empty.
6606 */
6607static __isl_give isl_map *remove_if_empty(__isl_take isl_map *map, int i)
6608{
6609	isl_bool empty;
6610
6611	if (!map)
6612		return NULL;
6613
6614	empty = isl_basic_map_plain_is_empty(map->p[i]);
6615	if (empty < 0)
6616		return isl_map_free(map);
6617	if (!empty)
6618		return map;
6619
6620	isl_basic_map_free(map->p[i]);
6621	map->n--;
6622	if (i != map->n) {
6623		map->p[i] = map->p[map->n];
6624		map = isl_map_unmark_normalized(map);
6625
6626	}
6627
6628	return map;
6629}
6630
6631/* Perform "fn" on each basic map of "map", where we may not be holding
6632 * the only reference to "map".
6633 * In particular, "fn" should be a semantics preserving operation
6634 * that we want to apply to all copies of "map".  We therefore need
6635 * to be careful not to modify "map" in a way that breaks "map"
6636 * in case anything goes wrong.
6637 */
6638__isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map,
6639	__isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap))
6640{
6641	struct isl_basic_map *bmap;
6642	int i;
6643
6644	if (!map)
6645		return NULL;
6646
6647	for (i = map->n - 1; i >= 0; --i) {
6648		bmap = isl_basic_map_copy(map->p[i]);
6649		bmap = fn(bmap);
6650		if (!bmap)
6651			goto error;
6652		isl_basic_map_free(map->p[i]);
6653		map->p[i] = bmap;
6654		map = remove_if_empty(map, i);
6655		if (!map)
6656			return NULL;
6657	}
6658
6659	return map;
6660error:
6661	isl_map_free(map);
6662	return NULL;
6663}
6664
6665__isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map,
6666		enum isl_dim_type type, unsigned pos, int value)
6667{
6668	int i;
6669
6670	map = isl_map_cow(map);
6671	if (isl_map_check_range(map, type, pos, 1) < 0)
6672		return isl_map_free(map);
6673	for (i = map->n - 1; i >= 0; --i) {
6674		map->p[i] = isl_basic_map_fix_si(map->p[i], type, pos, value);
6675		map = remove_if_empty(map, i);
6676		if (!map)
6677			return NULL;
6678	}
6679	map = isl_map_unmark_normalized(map);
6680	return map;
6681}
6682
6683__isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set,
6684		enum isl_dim_type type, unsigned pos, int value)
6685{
6686	return set_from_map(isl_map_fix_si(set_to_map(set), type, pos, value));
6687}
6688
6689__isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
6690		enum isl_dim_type type, unsigned pos, isl_int value)
6691{
6692	int i;
6693
6694	map = isl_map_cow(map);
6695	if (isl_map_check_range(map, type, pos, 1) < 0)
6696		return isl_map_free(map);
6697	for (i = 0; i < map->n; ++i) {
6698		map->p[i] = isl_basic_map_fix(map->p[i], type, pos, value);
6699		if (!map->p[i])
6700			goto error;
6701	}
6702	map = isl_map_unmark_normalized(map);
6703	return map;
6704error:
6705	isl_map_free(map);
6706	return NULL;
6707}
6708
6709__isl_give isl_set *isl_set_fix(__isl_take isl_set *set,
6710		enum isl_dim_type type, unsigned pos, isl_int value)
6711{
6712	return set_from_map(isl_map_fix(set_to_map(set), type, pos, value));
6713}
6714
6715/* Fix the value of the variable at position "pos" of type "type" of "map"
6716 * to be equal to "v".
6717 */
6718__isl_give isl_map *isl_map_fix_val(__isl_take isl_map *map,
6719	enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6720{
6721	int i;
6722
6723	map = isl_map_cow(map);
6724	if (!map || !v)
6725		goto error;
6726
6727	if (!isl_val_is_int(v))
6728		isl_die(isl_map_get_ctx(map), isl_error_invalid,
6729			"expecting integer value", goto error);
6730	if (isl_map_check_range(map, type, pos, 1) < 0)
6731		goto error;
6732	for (i = map->n - 1; i >= 0; --i) {
6733		map->p[i] = isl_basic_map_fix_val(map->p[i], type, pos,
6734							isl_val_copy(v));
6735		map = remove_if_empty(map, i);
6736		if (!map)
6737			goto error;
6738	}
6739	map = isl_map_unmark_normalized(map);
6740	isl_val_free(v);
6741	return map;
6742error:
6743	isl_map_free(map);
6744	isl_val_free(v);
6745	return NULL;
6746}
6747
6748/* Fix the value of the variable at position "pos" of type "type" of "set"
6749 * to be equal to "v".
6750 */
6751__isl_give isl_set *isl_set_fix_val(__isl_take isl_set *set,
6752	enum isl_dim_type type, unsigned pos, __isl_take isl_val *v)
6753{
6754	return isl_map_fix_val(set, type, pos, v);
6755}
6756
6757__isl_give isl_map *isl_map_fix_input_si(__isl_take isl_map *map,
6758		unsigned input, int value)
6759{
6760	return isl_map_fix_si(map, isl_dim_in, input, value);
6761}
6762
6763__isl_give isl_set *isl_set_fix_dim_si(__isl_take isl_set *set, unsigned dim,
6764	int value)
6765{
6766	return set_from_map(isl_map_fix_si(set_to_map(set),
6767						isl_dim_set, dim, value));
6768}
6769
6770static __isl_give isl_basic_map *basic_map_bound_si(
6771	__isl_take isl_basic_map *bmap,
6772	enum isl_dim_type type, unsigned pos, int value, int upper)
6773{
6774	int j;
6775	isl_size total;
6776
6777	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6778		return isl_basic_map_free(bmap);
6779	total = isl_basic_map_dim(bmap, isl_dim_all);
6780	if (total < 0)
6781		return isl_basic_map_free(bmap);
6782	pos += isl_basic_map_offset(bmap, type);
6783	bmap = isl_basic_map_cow(bmap);
6784	bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
6785	j = isl_basic_map_alloc_inequality(bmap);
6786	if (j < 0)
6787		goto error;
6788	isl_seq_clr(bmap->ineq[j], 1 + total);
6789	if (upper) {
6790		isl_int_set_si(bmap->ineq[j][pos], -1);
6791		isl_int_set_si(bmap->ineq[j][0], value);
6792	} else {
6793		isl_int_set_si(bmap->ineq[j][pos], 1);
6794		isl_int_set_si(bmap->ineq[j][0], -value);
6795	}
6796	bmap = isl_basic_map_simplify(bmap);
6797	return isl_basic_map_finalize(bmap);
6798error:
6799	isl_basic_map_free(bmap);
6800	return NULL;
6801}
6802
6803__isl_give isl_basic_map *isl_basic_map_lower_bound_si(
6804	__isl_take isl_basic_map *bmap,
6805	enum isl_dim_type type, unsigned pos, int value)
6806{
6807	return basic_map_bound_si(bmap, type, pos, value, 0);
6808}
6809
6810/* Constrain the values of the given dimension to be no greater than "value".
6811 */
6812__isl_give isl_basic_map *isl_basic_map_upper_bound_si(
6813	__isl_take isl_basic_map *bmap,
6814	enum isl_dim_type type, unsigned pos, int value)
6815{
6816	return basic_map_bound_si(bmap, type, pos, value, 1);
6817}
6818
6819static __isl_give isl_map *map_bound_si(__isl_take isl_map *map,
6820	enum isl_dim_type type, unsigned pos, int value, int upper)
6821{
6822	int i;
6823
6824	map = isl_map_cow(map);
6825	if (isl_map_check_range(map, type, pos, 1) < 0)
6826		return isl_map_free(map);
6827	for (i = 0; i < map->n; ++i) {
6828		map->p[i] = basic_map_bound_si(map->p[i],
6829						 type, pos, value, upper);
6830		if (!map->p[i])
6831			goto error;
6832	}
6833	map = isl_map_unmark_normalized(map);
6834	return map;
6835error:
6836	isl_map_free(map);
6837	return NULL;
6838}
6839
6840__isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
6841	enum isl_dim_type type, unsigned pos, int value)
6842{
6843	return map_bound_si(map, type, pos, value, 0);
6844}
6845
6846__isl_give isl_map *isl_map_upper_bound_si(__isl_take isl_map *map,
6847	enum isl_dim_type type, unsigned pos, int value)
6848{
6849	return map_bound_si(map, type, pos, value, 1);
6850}
6851
6852__isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set,
6853		enum isl_dim_type type, unsigned pos, int value)
6854{
6855	return set_from_map(isl_map_lower_bound_si(set_to_map(set),
6856							type, pos, value));
6857}
6858
6859__isl_give isl_set *isl_set_upper_bound_si(__isl_take isl_set *set,
6860	enum isl_dim_type type, unsigned pos, int value)
6861{
6862	return isl_map_upper_bound_si(set, type, pos, value);
6863}
6864
6865/* Bound the given variable of "bmap" from below (or above is "upper"
6866 * is set) to "value".
6867 */
6868static __isl_give isl_basic_map *basic_map_bound(
6869	__isl_take isl_basic_map *bmap,
6870	enum isl_dim_type type, unsigned pos, isl_int value, int upper)
6871{
6872	int j;
6873	isl_size total;
6874
6875	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
6876		return isl_basic_map_free(bmap);
6877	total = isl_basic_map_dim(bmap, isl_dim_all);
6878	if (total < 0)
6879		return isl_basic_map_free(bmap);
6880	pos += isl_basic_map_offset(bmap, type);
6881	bmap = isl_basic_map_cow(bmap);
6882	bmap = isl_basic_map_extend_constraints(bmap, 0, 1);
6883	j = isl_basic_map_alloc_inequality(bmap);
6884	if (j < 0)
6885		goto error;
6886	isl_seq_clr(bmap->ineq[j], 1 + total);
6887	if (upper) {
6888		isl_int_set_si(bmap->ineq[j][pos], -1);
6889		isl_int_set(bmap->ineq[j][0], value);
6890	} else {
6891		isl_int_set_si(bmap->ineq[j][pos], 1);
6892		isl_int_neg(bmap->ineq[j][0], value);
6893	}
6894	bmap = isl_basic_map_simplify(bmap);
6895	return isl_basic_map_finalize(bmap);
6896error:
6897	isl_basic_map_free(bmap);
6898	return NULL;
6899}
6900
6901/* Bound the given variable of "map" from below (or above is "upper"
6902 * is set) to "value".
6903 */
6904static __isl_give isl_map *map_bound(__isl_take isl_map *map,
6905	enum isl_dim_type type, unsigned pos, isl_int value, int upper)
6906{
6907	int i;
6908
6909	map = isl_map_cow(map);
6910	if (isl_map_check_range(map, type, pos, 1) < 0)
6911		return isl_map_free(map);
6912	for (i = map->n - 1; i >= 0; --i) {
6913		map->p[i] = basic_map_bound(map->p[i], type, pos, value, upper);
6914		map = remove_if_empty(map, i);
6915		if (!map)
6916			return NULL;
6917	}
6918	map = isl_map_unmark_normalized(map);
6919	return map;
6920}
6921
6922__isl_give isl_map *isl_map_lower_bound(__isl_take isl_map *map,
6923	enum isl_dim_type type, unsigned pos, isl_int value)
6924{
6925	return map_bound(map, type, pos, value, 0);
6926}
6927
6928__isl_give isl_map *isl_map_upper_bound(__isl_take isl_map *map,
6929	enum isl_dim_type type, unsigned pos, isl_int value)
6930{
6931	return map_bound(map, type, pos, value, 1);
6932}
6933
6934__isl_give isl_set *isl_set_lower_bound(__isl_take isl_set *set,
6935	enum isl_dim_type type, unsigned pos, isl_int value)
6936{
6937	return isl_map_lower_bound(set, type, pos, value);
6938}
6939
6940__isl_give isl_set *isl_set_upper_bound(__isl_take isl_set *set,
6941	enum isl_dim_type type, unsigned pos, isl_int value)
6942{
6943	return isl_map_upper_bound(set, type, pos, value);
6944}
6945
6946/* Force the values of the variable at position "pos" of type "type" of "map"
6947 * to be no smaller than "value".
6948 */
6949__isl_give isl_map *isl_map_lower_bound_val(__isl_take isl_map *map,
6950	enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6951{
6952	if (!value)
6953		goto error;
6954	if (!isl_val_is_int(value))
6955		isl_die(isl_map_get_ctx(map), isl_error_invalid,
6956			"expecting integer value", goto error);
6957	map = isl_map_lower_bound(map, type, pos, value->n);
6958	isl_val_free(value);
6959	return map;
6960error:
6961	isl_val_free(value);
6962	isl_map_free(map);
6963	return NULL;
6964}
6965
6966/* Force the values of the variable at position "pos" of type "type" of "set"
6967 * to be no smaller than "value".
6968 */
6969__isl_give isl_set *isl_set_lower_bound_val(__isl_take isl_set *set,
6970	enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6971{
6972	isl_map *map;
6973
6974	map = set_to_map(set);
6975	return set_from_map(isl_map_lower_bound_val(map, type, pos, value));
6976}
6977
6978/* Force the values of the variable at position "pos" of type "type" of "map"
6979 * to be no greater than "value".
6980 */
6981__isl_give isl_map *isl_map_upper_bound_val(__isl_take isl_map *map,
6982	enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
6983{
6984	if (!value)
6985		goto error;
6986	if (!isl_val_is_int(value))
6987		isl_die(isl_map_get_ctx(map), isl_error_invalid,
6988			"expecting integer value", goto error);
6989	map = isl_map_upper_bound(map, type, pos, value->n);
6990	isl_val_free(value);
6991	return map;
6992error:
6993	isl_val_free(value);
6994	isl_map_free(map);
6995	return NULL;
6996}
6997
6998/* Force the values of the variable at position "pos" of type "type" of "set"
6999 * to be no greater than "value".
7000 */
7001__isl_give isl_set *isl_set_upper_bound_val(__isl_take isl_set *set,
7002	enum isl_dim_type type, unsigned pos, __isl_take isl_val *value)
7003{
7004	isl_map *map;
7005
7006	map = set_to_map(set);
7007	return set_from_map(isl_map_upper_bound_val(map, type, pos, value));
7008}
7009
7010/* If "mv" has an explicit domain, then intersect the domain of "map"
7011 * with this explicit domain.
7012 *
7013 * An isl_multi_val object never has an explicit domain,
7014 * so simply return "map".
7015 */
7016static __isl_give isl_map *isl_map_intersect_multi_val_explicit_domain(
7017	__isl_take isl_map *map, __isl_keep isl_multi_val *mv)
7018{
7019	return map;
7020}
7021
7022#undef BASE
7023#define BASE	val
7024#include "isl_map_bound_templ.c"
7025
7026/* Apply "map_bound" to "set" with the corresponding value in "bound"
7027 * for each set dimension, by treating the set as a map.
7028 */
7029static __isl_give isl_set *set_bound_multi_val(__isl_take isl_set *set,
7030	__isl_take isl_multi_val *bound,
7031	__isl_give isl_map *map_bound(__isl_take isl_map *map,
7032		unsigned pos, __isl_take isl_val *value))
7033{
7034	isl_map *map;
7035
7036	map = set_to_map(set);
7037	return set_from_map(map_bound_multi_val(map, bound, map_bound));
7038}
7039
7040#undef BASE
7041#define BASE	pw_aff
7042#include "isl_map_bound_templ.c"
7043
7044/* Apply "map_bound" to "set" with the corresponding value in "bound"
7045 * for each set dimension, by converting the set and the bound
7046 * to objects living in a map space.
7047 */
7048static __isl_give isl_set *set_bound_multi_pw_aff(__isl_take isl_set *set,
7049	__isl_take isl_multi_pw_aff *bound,
7050	__isl_give isl_map *set_bound(__isl_take isl_map *map,
7051		unsigned pos, __isl_take TYPE *value))
7052{
7053	isl_map *map;
7054
7055	map = isl_map_from_range(set);
7056	bound = isl_multi_pw_aff_from_range(bound);
7057	map = map_bound_multi_pw_aff(map, bound, set_bound);
7058	return isl_map_range(map);
7059}
7060
7061/* Wrapper around isl_map_lower_bound_val for use in map_bound_multi_val,
7062 * setting a bound on the given output dimension.
7063 */
7064static __isl_give isl_map *map_lower_bound_val(__isl_take isl_map *map,
7065	unsigned pos, __isl_take isl_val *v)
7066{
7067	return isl_map_lower_bound_val(map, isl_dim_out, pos, v);
7068}
7069
7070/* Force the values of the set dimensions of "set"
7071 * to be no smaller than the corresponding values in "lower".
7072 */
7073__isl_give isl_set *isl_set_lower_bound_multi_val(__isl_take isl_set *set,
7074	__isl_take isl_multi_val *lower)
7075{
7076	return set_bound_multi_val(set, lower, &map_lower_bound_val);
7077}
7078
7079/* Wrapper around isl_map_upper_bound_val for use in map_bound_multi_val,
7080 * setting a bound on the given output dimension.
7081 */
7082static __isl_give isl_map *map_upper_bound_val(__isl_take isl_map *map,
7083	unsigned pos, __isl_take isl_val *v)
7084{
7085	return isl_map_upper_bound_val(map, isl_dim_out, pos, v);
7086}
7087
7088/* Force the values of the set dimensions of "set"
7089 * to be no greater than the corresponding values in "upper".
7090 */
7091__isl_give isl_set *isl_set_upper_bound_multi_val(__isl_take isl_set *set,
7092	__isl_take isl_multi_val *upper)
7093{
7094	return set_bound_multi_val(set, upper, &map_upper_bound_val);
7095}
7096
7097/* Force the symbolic constant expression "bound"
7098 * to satisfy the relation "order" with respect to
7099 * the output variable at position "pos" of "map".
7100 *
7101 * Create an affine expression representing the output variable
7102 * in terms of the range and
7103 * compare it using "order" to "bound" (defined on the domain).
7104 * The result is a relation between elements in domain and range that
7105 * can be intersected with "map".
7106 */
7107static __isl_give isl_map *map_bound_pw_aff(__isl_take isl_map *map,
7108	unsigned pos, __isl_take isl_pw_aff *bound,
7109	__isl_give isl_map *(*order)(__isl_take isl_pw_aff *pa1,
7110		__isl_take isl_pw_aff *pa2))
7111{
7112	isl_space *space;
7113	isl_local_space *ls;
7114	isl_pw_aff *var;
7115
7116	space = isl_space_range(isl_map_get_space(map));
7117	ls = isl_local_space_from_space(space);
7118	var = isl_pw_aff_var_on_domain(ls, isl_dim_set, pos);
7119	map = isl_map_intersect(map, order(bound, var));
7120	return map;
7121}
7122
7123/* Force the values of the output variable at position "pos" of "map"
7124 * to be no smaller than the symbolic constant expression "lower".
7125 */
7126static __isl_give isl_map *map_lower_bound_pw_aff(__isl_take isl_map *map,
7127	unsigned pos, __isl_take isl_pw_aff *lower)
7128{
7129	return map_bound_pw_aff(map, pos, lower, &isl_pw_aff_le_map);
7130}
7131
7132/* Force the values of the output variable at position "pos" of "map"
7133 * to be no greater than the symbolic constant expression "upper".
7134 */
7135static __isl_give isl_map *map_upper_bound_pw_aff(__isl_take isl_map *map,
7136	unsigned pos, __isl_take isl_pw_aff *upper)
7137{
7138	return map_bound_pw_aff(map, pos, upper, &isl_pw_aff_ge_map);
7139}
7140
7141/* Force the values of the set dimensions of "set"
7142 * to be no smaller than the corresponding constant symbolic expressions
7143 * in "lower".
7144 */
7145__isl_give isl_set *isl_set_lower_bound_multi_pw_aff(__isl_take isl_set *set,
7146	__isl_take isl_multi_pw_aff *lower)
7147{
7148	return set_bound_multi_pw_aff(set, lower, &map_lower_bound_pw_aff);
7149}
7150
7151/* Force the values of the set dimensions of "set"
7152 * to be no greater than the corresponding constant symbolic expressions
7153 * in "upper".
7154 */
7155__isl_give isl_set *isl_set_upper_bound_multi_pw_aff(__isl_take isl_set *set,
7156	__isl_take isl_multi_pw_aff *upper)
7157{
7158	return set_bound_multi_pw_aff(set, upper, &map_upper_bound_pw_aff);
7159}
7160
7161/* Force the values of the output dimensions of "map"
7162 * to be no smaller than the corresponding constant symbolic expressions
7163 * in "lower".
7164 */
7165__isl_give isl_map *isl_map_lower_bound_multi_pw_aff(__isl_take isl_map *map,
7166	__isl_take isl_multi_pw_aff *lower)
7167{
7168	return map_bound_multi_pw_aff(map, lower, &map_lower_bound_pw_aff);
7169}
7170
7171/* Force the values of the output dimensions of "map"
7172 * to be no greater than the corresponding constant symbolic expressions
7173 * in "upper".
7174 */
7175__isl_give isl_map *isl_map_upper_bound_multi_pw_aff(__isl_take isl_map *map,
7176	__isl_take isl_multi_pw_aff *upper)
7177{
7178	return map_bound_multi_pw_aff(map, upper, &map_upper_bound_pw_aff);
7179}
7180
7181/* Bound the given variable of "bset" from below (or above is "upper"
7182 * is set) to "value".
7183 */
7184static __isl_give isl_basic_set *isl_basic_set_bound(
7185	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
7186	isl_int value, int upper)
7187{
7188	return bset_from_bmap(basic_map_bound(bset_to_bmap(bset),
7189						type, pos, value, upper));
7190}
7191
7192/* Bound the given variable of "bset" from below (or above is "upper"
7193 * is set) to "value".
7194 */
7195static __isl_give isl_basic_set *isl_basic_set_bound_val(
7196	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
7197	__isl_take isl_val *value, int upper)
7198{
7199	if (!value)
7200		goto error;
7201	if (!isl_val_is_int(value))
7202		isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
7203			"expecting integer value", goto error);
7204	bset = isl_basic_set_bound(bset, type, pos, value->n, upper);
7205	isl_val_free(value);
7206	return bset;
7207error:
7208	isl_val_free(value);
7209	isl_basic_set_free(bset);
7210	return NULL;
7211}
7212
7213/* Bound the given variable of "bset" from below to "value".
7214 */
7215__isl_give isl_basic_set *isl_basic_set_lower_bound_val(
7216	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
7217	__isl_take isl_val *value)
7218{
7219	return isl_basic_set_bound_val(bset, type, pos, value, 0);
7220}
7221
7222/* Bound the given variable of "bset" from above to "value".
7223 */
7224__isl_give isl_basic_set *isl_basic_set_upper_bound_val(
7225	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned pos,
7226	__isl_take isl_val *value)
7227{
7228	return isl_basic_set_bound_val(bset, type, pos, value, 1);
7229}
7230
7231__isl_give isl_map *isl_map_reverse(__isl_take isl_map *map)
7232{
7233	return isl_map_transform(map, &isl_space_reverse,
7234					&isl_basic_map_reverse);
7235}
7236
7237/* Given a map (A -> B) -> C, return the corresponding map (B -> A) -> C.
7238 */
7239__isl_give isl_map *isl_map_domain_reverse(__isl_take isl_map *map)
7240{
7241	return isl_map_transform(map, &isl_space_domain_reverse,
7242					&isl_basic_map_domain_reverse);
7243}
7244
7245/* Given a map A -> (B -> C), return the corresponding map A -> (C -> B).
7246 */
7247__isl_give isl_map *isl_map_range_reverse(__isl_take isl_map *map)
7248{
7249	return isl_map_transform(map, &isl_space_range_reverse,
7250					&isl_basic_map_range_reverse);
7251}
7252
7253/* Given a set (A -> B), return the corresponding set (B -> A).
7254 */
7255__isl_give isl_set *isl_set_wrapped_reverse(__isl_take isl_set *set)
7256{
7257	isl_map *map = set_to_map(set);
7258
7259	map = isl_map_transform(map, &isl_space_wrapped_reverse,
7260					&isl_basic_map_set_reverse);
7261	return set_from_map(map);
7262}
7263
7264#undef TYPE
7265#define TYPE	isl_pw_multi_aff
7266#undef SUFFIX
7267#define SUFFIX	_pw_multi_aff
7268#undef EMPTY
7269#define EMPTY	isl_pw_multi_aff_empty
7270#undef ADD
7271#define ADD	isl_pw_multi_aff_union_add
7272#include "isl_map_lexopt_templ.c"
7273
7274/* Given a map "map", compute the lexicographically minimal
7275 * (or maximal) image element for each domain element in dom,
7276 * in the form of an isl_pw_multi_aff.
7277 * If "empty" is not NULL, then set *empty to those elements in dom that
7278 * do not have an image element.
7279 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
7280 * should be computed over the domain of "map".  "empty" is also NULL
7281 * in this case.
7282 *
7283 * We first compute the lexicographically minimal or maximal element
7284 * in the first basic map.  This results in a partial solution "res"
7285 * and a subset "todo" of dom that still need to be handled.
7286 * We then consider each of the remaining maps in "map" and successively
7287 * update both "res" and "todo".
7288 * If "empty" is NULL, then the todo sets are not needed and therefore
7289 * also not computed.
7290 */
7291static __isl_give isl_pw_multi_aff *isl_map_partial_lexopt_aligned_pw_multi_aff(
7292	__isl_take isl_map *map, __isl_take isl_set *dom,
7293	__isl_give isl_set **empty, unsigned flags)
7294{
7295	int i;
7296	int full;
7297	isl_pw_multi_aff *res;
7298	isl_set *todo;
7299
7300	full = ISL_FL_ISSET(flags, ISL_OPT_FULL);
7301	if (!map || (!full && !dom))
7302		goto error;
7303
7304	if (isl_map_plain_is_empty(map)) {
7305		if (empty)
7306			*empty = dom;
7307		else
7308			isl_set_free(dom);
7309		return isl_pw_multi_aff_from_map(map);
7310	}
7311
7312	res = basic_map_partial_lexopt_pw_multi_aff(
7313					    isl_basic_map_copy(map->p[0]),
7314					    isl_set_copy(dom), empty, flags);
7315
7316	if (empty)
7317		todo = *empty;
7318	for (i = 1; i < map->n; ++i) {
7319		isl_pw_multi_aff *res_i;
7320
7321		res_i = basic_map_partial_lexopt_pw_multi_aff(
7322					    isl_basic_map_copy(map->p[i]),
7323					    isl_set_copy(dom), empty, flags);
7324
7325		if (ISL_FL_ISSET(flags, ISL_OPT_MAX))
7326			res = isl_pw_multi_aff_union_lexmax(res, res_i);
7327		else
7328			res = isl_pw_multi_aff_union_lexmin(res, res_i);
7329
7330		if (empty)
7331			todo = isl_set_intersect(todo, *empty);
7332	}
7333
7334	isl_set_free(dom);
7335	isl_map_free(map);
7336
7337	if (empty)
7338		*empty = todo;
7339
7340	return res;
7341error:
7342	if (empty)
7343		*empty = NULL;
7344	isl_set_free(dom);
7345	isl_map_free(map);
7346	return NULL;
7347}
7348
7349#undef TYPE
7350#define TYPE	isl_map
7351#undef SUFFIX
7352#define SUFFIX
7353#undef EMPTY
7354#define EMPTY	isl_map_empty
7355#undef ADD
7356#define ADD	isl_map_union_disjoint
7357#include "isl_map_lexopt_templ.c"
7358
7359/* Given a map "map", compute the lexicographically minimal
7360 * (or maximal) image element for each domain element in "dom",
7361 * in the form of an isl_map.
7362 * If "empty" is not NULL, then set *empty to those elements in "dom" that
7363 * do not have an image element.
7364 * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
7365 * should be computed over the domain of "map".  "empty" is also NULL
7366 * in this case.
7367 *
7368 * If the input consists of more than one disjunct, then first
7369 * compute the desired result in the form of an isl_pw_multi_aff and
7370 * then convert that into an isl_map.
7371 *
7372 * This function used to have an explicit implementation in terms
7373 * of isl_maps, but it would continually intersect the domains of
7374 * partial results with the complement of the domain of the next
7375 * partial solution, potentially leading to an explosion in the number
7376 * of disjuncts if there are several disjuncts in the input.
7377 * An even earlier implementation of this function would look for
7378 * better results in the domain of the partial result and for extra
7379 * results in the complement of this domain, which would lead to
7380 * even more splintering.
7381 */
7382static __isl_give isl_map *isl_map_partial_lexopt_aligned(
7383	__isl_take isl_map *map, __isl_take isl_set *dom,
7384	__isl_give isl_set **empty, unsigned flags)
7385{
7386	int full;
7387	struct isl_map *res;
7388	isl_pw_multi_aff *pma;
7389
7390	full = ISL_FL_ISSET(flags, ISL_OPT_FULL);
7391	if (!map || (!full && !dom))
7392		goto error;
7393
7394	if (isl_map_plain_is_empty(map)) {
7395		if (empty)
7396			*empty = dom;
7397		else
7398			isl_set_free(dom);
7399		return map;
7400	}
7401
7402	if (map->n == 1) {
7403		res = basic_map_partial_lexopt(isl_basic_map_copy(map->p[0]),
7404						dom, empty, flags);
7405		isl_map_free(map);
7406		return res;
7407	}
7408
7409	pma = isl_map_partial_lexopt_aligned_pw_multi_aff(map, dom, empty,
7410							flags);
7411	return isl_map_from_pw_multi_aff_internal(pma);
7412error:
7413	if (empty)
7414		*empty = NULL;
7415	isl_set_free(dom);
7416	isl_map_free(map);
7417	return NULL;
7418}
7419
7420__isl_give isl_map *isl_map_partial_lexmax(
7421		__isl_take isl_map *map, __isl_take isl_set *dom,
7422		__isl_give isl_set **empty)
7423{
7424	return isl_map_partial_lexopt(map, dom, empty, ISL_OPT_MAX);
7425}
7426
7427__isl_give isl_map *isl_map_partial_lexmin(
7428		__isl_take isl_map *map, __isl_take isl_set *dom,
7429		__isl_give isl_set **empty)
7430{
7431	return isl_map_partial_lexopt(map, dom, empty, 0);
7432}
7433
7434__isl_give isl_set *isl_set_partial_lexmin(
7435		__isl_take isl_set *set, __isl_take isl_set *dom,
7436		__isl_give isl_set **empty)
7437{
7438	return set_from_map(isl_map_partial_lexmin(set_to_map(set),
7439						    dom, empty));
7440}
7441
7442__isl_give isl_set *isl_set_partial_lexmax(
7443		__isl_take isl_set *set, __isl_take isl_set *dom,
7444		__isl_give isl_set **empty)
7445{
7446	return set_from_map(isl_map_partial_lexmax(set_to_map(set),
7447						    dom, empty));
7448}
7449
7450/* Compute the lexicographic minimum (or maximum if "flags" includes
7451 * ISL_OPT_MAX) of "bset" over its parametric domain.
7452 */
7453__isl_give isl_set *isl_basic_set_lexopt(__isl_take isl_basic_set *bset,
7454	unsigned flags)
7455{
7456	return isl_basic_map_lexopt(bset, flags);
7457}
7458
7459__isl_give isl_map *isl_basic_map_lexmax(__isl_take isl_basic_map *bmap)
7460{
7461	return isl_basic_map_lexopt(bmap, ISL_OPT_MAX);
7462}
7463
7464__isl_give isl_set *isl_basic_set_lexmin(__isl_take isl_basic_set *bset)
7465{
7466	return set_from_map(isl_basic_map_lexmin(bset_to_bmap(bset)));
7467}
7468
7469__isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset)
7470{
7471	return set_from_map(isl_basic_map_lexmax(bset_to_bmap(bset)));
7472}
7473
7474/* Compute the lexicographic minimum of "bset" over its parametric domain
7475 * for the purpose of quantifier elimination.
7476 * That is, find an explicit representation for all the existentially
7477 * quantified variables in "bset" by computing their lexicographic
7478 * minimum.
7479 */
7480static __isl_give isl_set *isl_basic_set_lexmin_compute_divs(
7481	__isl_take isl_basic_set *bset)
7482{
7483	return isl_basic_set_lexopt(bset, ISL_OPT_QE);
7484}
7485
7486/* Given a basic map with one output dimension, compute the minimum or
7487 * maximum of that dimension as an isl_pw_aff.
7488 *
7489 * Compute the optimum as a lexicographic optimum over the single
7490 * output dimension and extract the single isl_pw_aff from the result.
7491 */
7492static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap,
7493	int max)
7494{
7495	isl_pw_multi_aff *pma;
7496	isl_pw_aff *pwaff;
7497
7498	bmap = isl_basic_map_copy(bmap);
7499	pma = isl_basic_map_lexopt_pw_multi_aff(bmap, max ? ISL_OPT_MAX : 0);
7500	pwaff = isl_pw_multi_aff_get_pw_aff(pma, 0);
7501	isl_pw_multi_aff_free(pma);
7502
7503	return pwaff;
7504}
7505
7506/* Compute the minimum or maximum of the given output dimension
7507 * as a function of the parameters and the input dimensions,
7508 * but independently of the other output dimensions.
7509 *
7510 * We first project out the other output dimension and then compute
7511 * the "lexicographic" maximum in each basic map, combining the results
7512 * using isl_pw_aff_union_max.
7513 */
7514static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos,
7515	int max)
7516{
7517	int i;
7518	isl_pw_aff *pwaff;
7519	isl_size n_out;
7520
7521	n_out = isl_map_dim(map, isl_dim_out);
7522	if (n_out < 0)
7523		map = isl_map_free(map);
7524	map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1));
7525	map = isl_map_project_out(map, isl_dim_out, 0, pos);
7526	if (!map)
7527		return NULL;
7528
7529	if (map->n == 0) {
7530		isl_space *space = isl_map_get_space(map);
7531		isl_map_free(map);
7532		return isl_pw_aff_empty(space);
7533	}
7534
7535	pwaff = basic_map_dim_opt(map->p[0], max);
7536	for (i = 1; i < map->n; ++i) {
7537		isl_pw_aff *pwaff_i;
7538
7539		pwaff_i = basic_map_dim_opt(map->p[i], max);
7540		pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max);
7541	}
7542
7543	isl_map_free(map);
7544
7545	return pwaff;
7546}
7547
7548/* Compute the minimum of the given output dimension as a function of the
7549 * parameters and input dimensions, but independently of
7550 * the other output dimensions.
7551 */
7552__isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos)
7553{
7554	return map_dim_opt(map, pos, 0);
7555}
7556
7557/* Compute the maximum of the given output dimension as a function of the
7558 * parameters and input dimensions, but independently of
7559 * the other output dimensions.
7560 */
7561__isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos)
7562{
7563	return map_dim_opt(map, pos, 1);
7564}
7565
7566/* Compute the minimum or maximum of the given set dimension
7567 * as a function of the parameters,
7568 * but independently of the other set dimensions.
7569 */
7570static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_set *set, int pos,
7571	int max)
7572{
7573	return map_dim_opt(set, pos, max);
7574}
7575
7576/* Compute the maximum of the given set dimension as a function of the
7577 * parameters, but independently of the other set dimensions.
7578 */
7579__isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_set *set, int pos)
7580{
7581	return set_dim_opt(set, pos, 1);
7582}
7583
7584/* Compute the minimum of the given set dimension as a function of the
7585 * parameters, but independently of the other set dimensions.
7586 */
7587__isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_set *set, int pos)
7588{
7589	return set_dim_opt(set, pos, 0);
7590}
7591
7592/* Apply a preimage specified by "mat" on the parameters of "bset".
7593 * bset is assumed to have only parameters and divs.
7594 */
7595static __isl_give isl_basic_set *basic_set_parameter_preimage(
7596	__isl_take isl_basic_set *bset, __isl_take isl_mat *mat)
7597{
7598	isl_size nparam;
7599
7600	nparam = isl_basic_set_dim(bset, isl_dim_param);
7601	if (nparam < 0 || !mat)
7602		goto error;
7603
7604	bset->dim = isl_space_cow(bset->dim);
7605	if (!bset->dim)
7606		goto error;
7607
7608	isl_assert(bset->ctx, mat->n_row == 1 + nparam, goto error);
7609
7610	bset->dim->nparam = 0;
7611	bset->dim->n_out = nparam;
7612	bset = isl_basic_set_preimage(bset, mat);
7613	if (bset) {
7614		bset->dim->nparam = bset->dim->n_out;
7615		bset->dim->n_out = 0;
7616	}
7617	return bset;
7618error:
7619	isl_mat_free(mat);
7620	isl_basic_set_free(bset);
7621	return NULL;
7622}
7623
7624/* Apply a preimage specified by "mat" on the parameters of "set".
7625 * set is assumed to have only parameters and divs.
7626 */
7627static __isl_give isl_set *set_parameter_preimage(__isl_take isl_set *set,
7628	__isl_take isl_mat *mat)
7629{
7630	isl_space *space;
7631	isl_size nparam;
7632
7633	nparam = isl_set_dim(set, isl_dim_param);
7634	if (nparam < 0 || !mat)
7635		goto error;
7636
7637	if (mat->n_row != 1 + nparam)
7638		isl_die(isl_set_get_ctx(set), isl_error_internal,
7639			"unexpected number of rows", goto error);
7640
7641	space = isl_set_get_space(set);
7642	space = isl_space_move_dims(space, isl_dim_set, 0,
7643				    isl_dim_param, 0, nparam);
7644	set = isl_set_reset_space(set, space);
7645	set = isl_set_preimage(set, mat);
7646	nparam = isl_set_dim(set, isl_dim_out);
7647	if (nparam < 0)
7648		set = isl_set_free(set);
7649	space = isl_set_get_space(set);
7650	space = isl_space_move_dims(space, isl_dim_param, 0,
7651				    isl_dim_out, 0, nparam);
7652	set = isl_set_reset_space(set, space);
7653	return set;
7654error:
7655	isl_mat_free(mat);
7656	isl_set_free(set);
7657	return NULL;
7658}
7659
7660/* Intersect the basic set "bset" with the affine space specified by the
7661 * equalities in "eq".
7662 */
7663static __isl_give isl_basic_set *basic_set_append_equalities(
7664	__isl_take isl_basic_set *bset, __isl_take isl_mat *eq)
7665{
7666	int i, k;
7667	unsigned len;
7668
7669	if (!bset || !eq)
7670		goto error;
7671
7672	bset = isl_basic_set_extend(bset, 0, eq->n_row, 0);
7673	if (!bset)
7674		goto error;
7675
7676	len = isl_basic_set_offset(bset, isl_dim_div) + bset->extra;
7677	for (i = 0; i < eq->n_row; ++i) {
7678		k = isl_basic_set_alloc_equality(bset);
7679		if (k < 0)
7680			goto error;
7681		isl_seq_cpy(bset->eq[k], eq->row[i], eq->n_col);
7682		isl_seq_clr(bset->eq[k] + eq->n_col, len - eq->n_col);
7683	}
7684	isl_mat_free(eq);
7685
7686	bset = isl_basic_set_gauss(bset, NULL);
7687	bset = isl_basic_set_finalize(bset);
7688
7689	return bset;
7690error:
7691	isl_mat_free(eq);
7692	isl_basic_set_free(bset);
7693	return NULL;
7694}
7695
7696/* Intersect the set "set" with the affine space specified by the
7697 * equalities in "eq".
7698 */
7699static __isl_give isl_set *set_append_equalities(__isl_take isl_set *set,
7700	__isl_take isl_mat *eq)
7701{
7702	int i;
7703
7704	if (!set || !eq)
7705		goto error;
7706
7707	for (i = 0; i < set->n; ++i) {
7708		set->p[i] = basic_set_append_equalities(set->p[i],
7709					isl_mat_copy(eq));
7710		if (!set->p[i])
7711			goto error;
7712	}
7713	isl_mat_free(eq);
7714	return set;
7715error:
7716	isl_mat_free(eq);
7717	isl_set_free(set);
7718	return NULL;
7719}
7720
7721/* Given a basic set "bset" that only involves parameters and existentially
7722 * quantified variables, return the index of the first equality
7723 * that only involves parameters.  If there is no such equality then
7724 * return bset->n_eq.
7725 *
7726 * This function assumes that isl_basic_set_gauss has been called on "bset".
7727 */
7728static int first_parameter_equality(__isl_keep isl_basic_set *bset)
7729{
7730	int i, j;
7731	isl_size nparam, n_div;
7732
7733	nparam = isl_basic_set_dim(bset, isl_dim_param);
7734	n_div = isl_basic_set_dim(bset, isl_dim_div);
7735	if (nparam < 0 || n_div < 0)
7736		return -1;
7737
7738	for (i = 0, j = n_div - 1; i < bset->n_eq && j >= 0; --j) {
7739		if (!isl_int_is_zero(bset->eq[i][1 + nparam + j]))
7740			++i;
7741	}
7742
7743	return i;
7744}
7745
7746/* Compute an explicit representation for the existentially quantified
7747 * variables in "bset" by computing the "minimal value" of the set
7748 * variables.  Since there are no set variables, the computation of
7749 * the minimal value essentially computes an explicit representation
7750 * of the non-empty part(s) of "bset".
7751 *
7752 * The input only involves parameters and existentially quantified variables.
7753 * All equalities among parameters have been removed.
7754 *
7755 * Since the existentially quantified variables in the result are in general
7756 * going to be different from those in the input, we first replace
7757 * them by the minimal number of variables based on their equalities.
7758 * This should simplify the parametric integer programming.
7759 */
7760static __isl_give isl_set *base_compute_divs(__isl_take isl_basic_set *bset)
7761{
7762	isl_morph *morph1, *morph2;
7763	isl_set *set;
7764	isl_size n;
7765
7766	if (!bset)
7767		return NULL;
7768	if (bset->n_eq == 0)
7769		return isl_basic_set_lexmin_compute_divs(bset);
7770
7771	morph1 = isl_basic_set_parameter_compression(bset);
7772	bset = isl_morph_basic_set(isl_morph_copy(morph1), bset);
7773	bset = isl_basic_set_lift(bset);
7774	morph2 = isl_basic_set_variable_compression(bset, isl_dim_set);
7775	bset = isl_morph_basic_set(morph2, bset);
7776	n = isl_basic_set_dim(bset, isl_dim_set);
7777	if (n < 0)
7778		bset = isl_basic_set_free(bset);
7779	bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n);
7780
7781	set = isl_basic_set_lexmin_compute_divs(bset);
7782
7783	set = isl_morph_set(isl_morph_inverse(morph1), set);
7784
7785	return set;
7786}
7787
7788/* Project the given basic set onto its parameter domain, possibly introducing
7789 * new, explicit, existential variables in the constraints.
7790 * The input has parameters and (possibly implicit) existential variables.
7791 * The output has the same parameters, but only
7792 * explicit existentially quantified variables.
7793 *
7794 * The actual projection is performed by pip, but pip doesn't seem
7795 * to like equalities very much, so we first remove the equalities
7796 * among the parameters by performing a variable compression on
7797 * the parameters.  Afterward, an inverse transformation is performed
7798 * and the equalities among the parameters are inserted back in.
7799 *
7800 * The variable compression on the parameters may uncover additional
7801 * equalities that were only implicit before.  We therefore check
7802 * if there are any new parameter equalities in the result and
7803 * if so recurse.  The removal of parameter equalities is required
7804 * for the parameter compression performed by base_compute_divs.
7805 */
7806static __isl_give isl_set *parameter_compute_divs(
7807	__isl_take isl_basic_set *bset)
7808{
7809	int i;
7810	struct isl_mat *eq;
7811	struct isl_mat *T, *T2;
7812	struct isl_set *set;
7813	isl_size nparam;
7814
7815	bset = isl_basic_set_cow(bset);
7816	if (!bset)
7817		return NULL;
7818
7819	if (bset->n_eq == 0)
7820		return base_compute_divs(bset);
7821
7822	bset = isl_basic_set_gauss(bset, NULL);
7823	if (!bset)
7824		return NULL;
7825	if (isl_basic_set_plain_is_empty(bset))
7826		return isl_set_from_basic_set(bset);
7827
7828	i = first_parameter_equality(bset);
7829	if (i == bset->n_eq)
7830		return base_compute_divs(bset);
7831
7832	nparam = isl_basic_set_dim(bset, isl_dim_param);
7833	if (nparam < 0)
7834		return isl_set_from_basic_set(isl_basic_set_free(bset));
7835	eq = isl_mat_sub_alloc6(bset->ctx, bset->eq, i, bset->n_eq - i,
7836		0, 1 + nparam);
7837	eq = isl_mat_cow(eq);
7838	T = isl_mat_variable_compression(isl_mat_copy(eq), &T2);
7839	if (T && T->n_col == 0) {
7840		isl_mat_free(T);
7841		isl_mat_free(T2);
7842		isl_mat_free(eq);
7843		bset = isl_basic_set_set_to_empty(bset);
7844		return isl_set_from_basic_set(bset);
7845	}
7846	bset = basic_set_parameter_preimage(bset, T);
7847
7848	i = first_parameter_equality(bset);
7849	if (!bset)
7850		set = NULL;
7851	else if (i == bset->n_eq)
7852		set = base_compute_divs(bset);
7853	else
7854		set = parameter_compute_divs(bset);
7855	set = set_parameter_preimage(set, T2);
7856	set = set_append_equalities(set, eq);
7857	return set;
7858}
7859
7860/* Insert the divs from "ls" before those of "bmap".
7861 *
7862 * The number of columns is not changed, which means that the last
7863 * dimensions of "bmap" are being reintepreted as the divs from "ls".
7864 * The caller is responsible for removing the same number of dimensions
7865 * from the space of "bmap".
7866 */
7867static __isl_give isl_basic_map *insert_divs_from_local_space(
7868	__isl_take isl_basic_map *bmap, __isl_keep isl_local_space *ls)
7869{
7870	int i;
7871	isl_size n_div;
7872	int old_n_div;
7873
7874	n_div = isl_local_space_dim(ls, isl_dim_div);
7875	if (n_div < 0)
7876		return isl_basic_map_free(bmap);
7877	if (n_div == 0)
7878		return bmap;
7879
7880	old_n_div = bmap->n_div;
7881	bmap = insert_div_rows(bmap, n_div);
7882	if (!bmap)
7883		return NULL;
7884
7885	for (i = 0; i < n_div; ++i) {
7886		isl_seq_cpy(bmap->div[i], ls->div->row[i], ls->div->n_col);
7887		isl_seq_clr(bmap->div[i] + ls->div->n_col, old_n_div);
7888	}
7889
7890	return bmap;
7891}
7892
7893/* Replace the space of "bmap" by the space and divs of "ls".
7894 *
7895 * If "ls" has any divs, then we simplify the result since we may
7896 * have discovered some additional equalities that could simplify
7897 * the div expressions.
7898 */
7899static __isl_give isl_basic_map *basic_replace_space_by_local_space(
7900	__isl_take isl_basic_map *bmap, __isl_take isl_local_space *ls)
7901{
7902	isl_size n_div;
7903
7904	bmap = isl_basic_map_cow(bmap);
7905	n_div = isl_local_space_dim(ls, isl_dim_div);
7906	if (!bmap || n_div < 0)
7907		goto error;
7908
7909	bmap = insert_divs_from_local_space(bmap, ls);
7910	if (!bmap)
7911		goto error;
7912
7913	isl_space_free(bmap->dim);
7914	bmap->dim = isl_local_space_get_space(ls);
7915	if (!bmap->dim)
7916		goto error;
7917
7918	isl_local_space_free(ls);
7919	if (n_div > 0)
7920		bmap = isl_basic_map_simplify(bmap);
7921	bmap = isl_basic_map_finalize(bmap);
7922	return bmap;
7923error:
7924	isl_basic_map_free(bmap);
7925	isl_local_space_free(ls);
7926	return NULL;
7927}
7928
7929/* Replace the space of "map" by the space and divs of "ls".
7930 */
7931static __isl_give isl_map *replace_space_by_local_space(__isl_take isl_map *map,
7932	__isl_take isl_local_space *ls)
7933{
7934	int i;
7935
7936	map = isl_map_cow(map);
7937	if (!map || !ls)
7938		goto error;
7939
7940	for (i = 0; i < map->n; ++i) {
7941		map->p[i] = basic_replace_space_by_local_space(map->p[i],
7942						    isl_local_space_copy(ls));
7943		if (!map->p[i])
7944			goto error;
7945	}
7946	isl_space_free(isl_map_take_space(map));
7947	map = isl_map_restore_space(map, isl_local_space_get_space(ls));
7948
7949	isl_local_space_free(ls);
7950	return map;
7951error:
7952	isl_local_space_free(ls);
7953	isl_map_free(map);
7954	return NULL;
7955}
7956
7957/* Compute an explicit representation for the existentially
7958 * quantified variables for which do not know any explicit representation yet.
7959 *
7960 * We first sort the existentially quantified variables so that the
7961 * existentially quantified variables for which we already have an explicit
7962 * representation are placed before those for which we do not.
7963 * The input dimensions, the output dimensions and the existentially
7964 * quantified variables for which we already have an explicit
7965 * representation are then turned into parameters.
7966 * compute_divs returns a map with the same parameters and
7967 * no input or output dimensions and the dimension specification
7968 * is reset to that of the input, including the existentially quantified
7969 * variables for which we already had an explicit representation.
7970 */
7971static __isl_give isl_map *compute_divs(__isl_take isl_basic_map *bmap)
7972{
7973	struct isl_basic_set *bset;
7974	struct isl_set *set;
7975	struct isl_map *map;
7976	isl_space *space;
7977	isl_local_space *ls;
7978	isl_size nparam;
7979	isl_size n_in;
7980	isl_size n_out;
7981	int n_known;
7982	int i;
7983
7984	bmap = isl_basic_map_sort_divs(bmap);
7985	bmap = isl_basic_map_cow(bmap);
7986	if (!bmap)
7987		return NULL;
7988
7989	n_known = isl_basic_map_first_unknown_div(bmap);
7990	nparam = isl_basic_map_dim(bmap, isl_dim_param);
7991	n_in = isl_basic_map_dim(bmap, isl_dim_in);
7992	n_out = isl_basic_map_dim(bmap, isl_dim_out);
7993	if (n_known < 0 || nparam < 0 || n_in < 0 || n_out < 0)
7994		return isl_map_from_basic_map(isl_basic_map_free(bmap));
7995
7996	space = isl_space_set_alloc(bmap->ctx,
7997				    nparam + n_in + n_out + n_known, 0);
7998	if (!space)
7999		goto error;
8000
8001	ls = isl_basic_map_get_local_space(bmap);
8002	ls = isl_local_space_drop_dims(ls, isl_dim_div,
8003					n_known, bmap->n_div - n_known);
8004	if (n_known > 0) {
8005		for (i = n_known; i < bmap->n_div; ++i)
8006			swap_div(bmap, i - n_known, i);
8007		bmap->n_div -= n_known;
8008		bmap->extra -= n_known;
8009	}
8010	bmap = isl_basic_map_reset_space(bmap, space);
8011	bset = bset_from_bmap(bmap);
8012
8013	set = parameter_compute_divs(bset);
8014	map = set_to_map(set);
8015	map = replace_space_by_local_space(map, ls);
8016
8017	return map;
8018error:
8019	isl_basic_map_free(bmap);
8020	return NULL;
8021}
8022
8023/* Remove the explicit representation of local variable "div",
8024 * if there is any.
8025 */
8026__isl_give isl_basic_map *isl_basic_map_mark_div_unknown(
8027	__isl_take isl_basic_map *bmap, int div)
8028{
8029	isl_bool unknown;
8030
8031	unknown = isl_basic_map_div_is_marked_unknown(bmap, div);
8032	if (unknown < 0)
8033		return isl_basic_map_free(bmap);
8034	if (unknown)
8035		return bmap;
8036
8037	bmap = isl_basic_map_cow(bmap);
8038	if (!bmap)
8039		return NULL;
8040	isl_int_set_si(bmap->div[div][0], 0);
8041	return bmap;
8042}
8043
8044/* Is local variable "div" of "bmap" marked as not having an explicit
8045 * representation?
8046 * Note that even if "div" is not marked in this way and therefore
8047 * has an explicit representation, this representation may still
8048 * depend (indirectly) on other local variables that do not
8049 * have an explicit representation.
8050 */
8051isl_bool isl_basic_map_div_is_marked_unknown(__isl_keep isl_basic_map *bmap,
8052	int div)
8053{
8054	if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
8055		return isl_bool_error;
8056	return isl_int_is_zero(bmap->div[div][0]);
8057}
8058
8059/* Return the position of the first local variable that does not
8060 * have an explicit representation.
8061 * Return the total number of local variables if they all have
8062 * an explicit representation.
8063 * Return -1 on error.
8064 */
8065int isl_basic_map_first_unknown_div(__isl_keep isl_basic_map *bmap)
8066{
8067	int i;
8068
8069	if (!bmap)
8070		return -1;
8071
8072	for (i = 0; i < bmap->n_div; ++i) {
8073		if (!isl_basic_map_div_is_known(bmap, i))
8074			return i;
8075	}
8076	return bmap->n_div;
8077}
8078
8079/* Return the position of the first local variable that does not
8080 * have an explicit representation.
8081 * Return the total number of local variables if they all have
8082 * an explicit representation.
8083 * Return -1 on error.
8084 */
8085int isl_basic_set_first_unknown_div(__isl_keep isl_basic_set *bset)
8086{
8087	return isl_basic_map_first_unknown_div(bset);
8088}
8089
8090/* Does "bmap" have an explicit representation for all local variables?
8091 */
8092isl_bool isl_basic_map_divs_known(__isl_keep isl_basic_map *bmap)
8093{
8094	int first;
8095	isl_size n;
8096
8097	n = isl_basic_map_dim(bmap, isl_dim_div);
8098	first = isl_basic_map_first_unknown_div(bmap);
8099	if (n < 0 || first < 0)
8100		return isl_bool_error;
8101	return first == n;
8102}
8103
8104/* Do all basic maps in "map" have an explicit representation
8105 * for all local variables?
8106 */
8107isl_bool isl_map_divs_known(__isl_keep isl_map *map)
8108{
8109	int i;
8110
8111	if (!map)
8112		return isl_bool_error;
8113
8114	for (i = 0; i < map->n; ++i) {
8115		int known = isl_basic_map_divs_known(map->p[i]);
8116		if (known <= 0)
8117			return known;
8118	}
8119
8120	return isl_bool_true;
8121}
8122
8123/* If bmap contains any unknown divs, then compute explicit
8124 * expressions for them.  However, this computation may be
8125 * quite expensive, so first try to remove divs that aren't
8126 * strictly needed.
8127 */
8128__isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap)
8129{
8130	int known;
8131	struct isl_map *map;
8132
8133	known = isl_basic_map_divs_known(bmap);
8134	if (known < 0)
8135		goto error;
8136	if (known)
8137		return isl_map_from_basic_map(bmap);
8138
8139	bmap = isl_basic_map_drop_redundant_divs(bmap);
8140
8141	known = isl_basic_map_divs_known(bmap);
8142	if (known < 0)
8143		goto error;
8144	if (known)
8145		return isl_map_from_basic_map(bmap);
8146
8147	map = compute_divs(bmap);
8148	return map;
8149error:
8150	isl_basic_map_free(bmap);
8151	return NULL;
8152}
8153
8154__isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map)
8155{
8156	int i;
8157	int known;
8158	struct isl_map *res;
8159
8160	if (!map)
8161		return NULL;
8162	if (map->n == 0)
8163		return map;
8164
8165	known = isl_map_divs_known(map);
8166	if (known < 0) {
8167		isl_map_free(map);
8168		return NULL;
8169	}
8170	if (known)
8171		return map;
8172
8173	res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
8174	for (i = 1 ; i < map->n; ++i) {
8175		struct isl_map *r2;
8176		r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
8177		if (ISL_F_ISSET(map, ISL_MAP_DISJOINT))
8178			res = isl_map_union_disjoint(res, r2);
8179		else
8180			res = isl_map_union(res, r2);
8181	}
8182	isl_map_free(map);
8183
8184	return res;
8185}
8186
8187__isl_give isl_set *isl_basic_set_compute_divs(__isl_take isl_basic_set *bset)
8188{
8189	return set_from_map(isl_basic_map_compute_divs(bset_to_bmap(bset)));
8190}
8191
8192__isl_give isl_set *isl_set_compute_divs(__isl_take isl_set *set)
8193{
8194	return set_from_map(isl_map_compute_divs(set_to_map(set)));
8195}
8196
8197__isl_give isl_set *isl_map_domain(__isl_take isl_map *map)
8198{
8199	isl_space *space;
8200	isl_size n_out;
8201
8202	n_out = isl_map_dim(map, isl_dim_out);
8203	if (n_out < 0)
8204		return set_from_map(isl_map_free(map));
8205	space = isl_space_domain(isl_map_get_space(map));
8206
8207	map = isl_map_project_out(map, isl_dim_out, 0, n_out);
8208
8209	return set_from_map(isl_map_reset_space(map, space));
8210}
8211
8212/* Return the union of "map1" and "map2", where we assume for now that
8213 * "map1" and "map2" are disjoint.  Note that the basic maps inside
8214 * "map1" or "map2" may not be disjoint from each other.
8215 * Also note that this function is also called from isl_map_union,
8216 * which takes care of handling the situation where "map1" and "map2"
8217 * may not be disjoint.
8218 *
8219 * If one of the inputs is empty, we can simply return the other input.
8220 * Similarly, if one of the inputs is universal, then it is equal to the union.
8221 */
8222static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
8223	__isl_take isl_map *map2)
8224{
8225	int i;
8226	unsigned flags = 0;
8227	struct isl_map *map = NULL;
8228	int is_universe;
8229
8230	if (isl_map_check_equal_space(map1, map2) < 0)
8231		goto error;
8232
8233	if (map1->n == 0) {
8234		isl_map_free(map1);
8235		return map2;
8236	}
8237	if (map2->n == 0) {
8238		isl_map_free(map2);
8239		return map1;
8240	}
8241
8242	is_universe = isl_map_plain_is_universe(map1);
8243	if (is_universe < 0)
8244		goto error;
8245	if (is_universe) {
8246		isl_map_free(map2);
8247		return map1;
8248	}
8249
8250	is_universe = isl_map_plain_is_universe(map2);
8251	if (is_universe < 0)
8252		goto error;
8253	if (is_universe) {
8254		isl_map_free(map1);
8255		return map2;
8256	}
8257
8258	if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
8259	    ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
8260		ISL_FL_SET(flags, ISL_MAP_DISJOINT);
8261
8262	map = isl_map_alloc_space(isl_space_copy(map1->dim),
8263				map1->n + map2->n, flags);
8264	if (!map)
8265		goto error;
8266	for (i = 0; i < map1->n; ++i) {
8267		map = isl_map_add_basic_map(map,
8268				  isl_basic_map_copy(map1->p[i]));
8269		if (!map)
8270			goto error;
8271	}
8272	for (i = 0; i < map2->n; ++i) {
8273		map = isl_map_add_basic_map(map,
8274				  isl_basic_map_copy(map2->p[i]));
8275		if (!map)
8276			goto error;
8277	}
8278	isl_map_free(map1);
8279	isl_map_free(map2);
8280	return map;
8281error:
8282	isl_map_free(map);
8283	isl_map_free(map1);
8284	isl_map_free(map2);
8285	return NULL;
8286}
8287
8288/* Return the union of "map1" and "map2", where "map1" and "map2" are
8289 * guaranteed to be disjoint by the caller.
8290 *
8291 * Note that this functions is called from within isl_map_make_disjoint,
8292 * so we have to be careful not to touch the constraints of the inputs
8293 * in any way.
8294 */
8295__isl_give isl_map *isl_map_union_disjoint(__isl_take isl_map *map1,
8296	__isl_take isl_map *map2)
8297{
8298	isl_map_align_params_bin(&map1, &map2);
8299	return map_union_disjoint(map1, map2);
8300}
8301
8302/* Return the union of "map1" and "map2", where "map1" and "map2" may
8303 * not be disjoint.
8304 *
8305 * We currently simply call map_union_disjoint, the internal operation
8306 * of which does not really depend on the inputs being disjoint.
8307 * If the result contains more than one basic map, then we clear
8308 * the disjoint flag since the result may contain basic maps from
8309 * both inputs and these are not guaranteed to be disjoint.
8310 *
8311 * As a special case, if "map1" and "map2" are obviously equal,
8312 * then we simply return "map1".
8313 */
8314__isl_give isl_map *isl_map_union(__isl_take isl_map *map1,
8315	__isl_take isl_map *map2)
8316{
8317	int equal;
8318
8319	if (isl_map_align_params_bin(&map1, &map2) < 0)
8320		goto error;
8321
8322	equal = isl_map_plain_is_equal(map1, map2);
8323	if (equal < 0)
8324		goto error;
8325	if (equal) {
8326		isl_map_free(map2);
8327		return map1;
8328	}
8329
8330	map1 = map_union_disjoint(map1, map2);
8331	if (!map1)
8332		return NULL;
8333	if (map1->n > 1)
8334		ISL_F_CLR(map1, ISL_MAP_DISJOINT);
8335	return map1;
8336error:
8337	isl_map_free(map1);
8338	isl_map_free(map2);
8339	return NULL;
8340}
8341
8342__isl_give isl_set *isl_set_union_disjoint(
8343	__isl_take isl_set *set1, __isl_take isl_set *set2)
8344{
8345	return set_from_map(isl_map_union_disjoint(set_to_map(set1),
8346						    set_to_map(set2)));
8347}
8348
8349__isl_give isl_set *isl_set_union(__isl_take isl_set *set1,
8350	__isl_take isl_set *set2)
8351{
8352	return set_from_map(isl_map_union(set_to_map(set1), set_to_map(set2)));
8353}
8354
8355/* Apply "fn" to pairs of elements from "map" and "set" and collect
8356 * the results in a map living in "space".
8357 *
8358 * "map" and "set" are assumed to be compatible and non-NULL.
8359 */
8360static __isl_give isl_map *map_intersect_set(__isl_take isl_map *map,
8361	__isl_take isl_space *space, __isl_take isl_set *set,
8362	__isl_give isl_basic_map *fn(__isl_take isl_basic_map *bmap,
8363		__isl_take isl_basic_set *bset))
8364{
8365	unsigned flags = 0;
8366	struct isl_map *result;
8367	int i, j;
8368
8369	if (isl_set_plain_is_universe(set)) {
8370		isl_set_free(set);
8371		return isl_map_reset_equal_dim_space(map, space);
8372	}
8373
8374	if (ISL_F_ISSET(map, ISL_MAP_DISJOINT) &&
8375	    ISL_F_ISSET(set, ISL_MAP_DISJOINT))
8376		ISL_FL_SET(flags, ISL_MAP_DISJOINT);
8377
8378	result = isl_map_alloc_space(space, map->n * set->n, flags);
8379	for (i = 0; result && i < map->n; ++i)
8380		for (j = 0; j < set->n; ++j) {
8381			result = isl_map_add_basic_map(result,
8382					fn(isl_basic_map_copy(map->p[i]),
8383					    isl_basic_set_copy(set->p[j])));
8384			if (!result)
8385				break;
8386		}
8387
8388	isl_map_free(map);
8389	isl_set_free(set);
8390	return result;
8391}
8392
8393__isl_give isl_map *isl_map_intersect_range(__isl_take isl_map *map,
8394	__isl_take isl_set *set)
8395{
8396	isl_bool ok;
8397	isl_space *space;
8398
8399	isl_map_align_params_set(&map, &set);
8400	ok = isl_map_compatible_range(map, set);
8401	if (ok < 0)
8402		goto error;
8403	if (!ok)
8404		isl_die(set->ctx, isl_error_invalid,
8405			"incompatible spaces", goto error);
8406
8407	space = isl_map_get_space(map);
8408	return map_intersect_set(map, space, set,
8409				&isl_basic_map_intersect_range);
8410error:
8411	isl_map_free(map);
8412	isl_set_free(set);
8413	return NULL;
8414}
8415
8416/* Intersect the domain of "map" with "set".
8417 *
8418 * If the domain dimensions of "map" do not have any identifiers,
8419 * then copy them over from "set".
8420 */
8421__isl_give isl_map *isl_map_intersect_domain(__isl_take isl_map *map,
8422	__isl_take isl_set *set)
8423{
8424	isl_bool ok;
8425	isl_space *space;
8426
8427	isl_map_align_params_set(&map, &set);
8428	ok = isl_map_compatible_domain(map, set);
8429	if (ok < 0)
8430		goto error;
8431	if (!ok)
8432		isl_die(set->ctx, isl_error_invalid,
8433			"incompatible spaces", goto error);
8434
8435	space = isl_map_get_space(map);
8436	space = isl_space_copy_ids_if_unset(space, isl_dim_in,
8437					isl_set_peek_space(set), isl_dim_set);
8438	return map_intersect_set(map, space, set,
8439				&isl_basic_map_intersect_domain);
8440error:
8441	isl_map_free(map);
8442	isl_set_free(set);
8443	return NULL;
8444}
8445
8446#undef BASE
8447#define BASE map
8448static
8449#include "isl_copy_tuple_id_templ.c"
8450
8451/* Data structure that specifies how isl_map_intersect_factor
8452 * should operate.
8453 *
8454 * "preserve_type" is the tuple where the factor differs from
8455 * the input map and of which the identifiers needs
8456 * to be preserved explicitly.
8457 * "other_factor" is used to extract the space of the other factor
8458 * from the space of the product ("map").
8459 * "product" is used to combine the given factor and a universe map
8460 * in the space returned by "other_factor" to produce a map
8461 * that lives in the same space as the input map.
8462 */
8463struct isl_intersect_factor_control {
8464	enum isl_dim_type preserve_type;
8465	__isl_give isl_space *(*other_factor)(__isl_take isl_space *space);
8466	__isl_give isl_map *(*product)(__isl_take isl_map *factor,
8467		__isl_take isl_map *other);
8468};
8469
8470/* Given a map "map" in some product space and a map "factor"
8471 * living in some factor space, return the intersection.
8472 *
8473 * After aligning the parameters,
8474 * the map "factor" is first extended to a map living in the same space
8475 * as "map" and then a regular intersection is computed.
8476 *
8477 * Note that the extension is computed as a product, which is anonymous
8478 * by default.  If "map" has an identifier on the corresponding tuple,
8479 * then this identifier needs to be set on the product
8480 * before the intersection is computed.
8481 */
8482static __isl_give isl_map *isl_map_intersect_factor(
8483	__isl_take isl_map *map, __isl_take isl_map *factor,
8484	struct isl_intersect_factor_control *control)
8485{
8486	isl_bool equal;
8487	isl_space *space;
8488	isl_map *other, *product;
8489
8490	equal = isl_map_has_equal_params(map, factor);
8491	if (equal < 0)
8492		goto error;
8493	if (!equal) {
8494		map = isl_map_align_params(map, isl_map_get_space(factor));
8495		factor = isl_map_align_params(factor, isl_map_get_space(map));
8496	}
8497
8498	space = isl_map_get_space(map);
8499	other = isl_map_universe(control->other_factor(space));
8500	product = control->product(factor, other);
8501
8502	space = isl_map_peek_space(map);
8503	product = isl_map_copy_tuple_id(product, control->preserve_type,
8504					space, control->preserve_type);
8505	return map_intersect(map, product);
8506error:
8507	isl_map_free(map);
8508	isl_map_free(factor);
8509	return NULL;
8510}
8511
8512/* Return the domain product of "map2" and "map1".
8513 */
8514static __isl_give isl_map *isl_map_reverse_domain_product(
8515	__isl_take isl_map *map1, __isl_take isl_map *map2)
8516{
8517	return isl_map_domain_product(map2, map1);
8518}
8519
8520/* Return the range product of "map2" and "map1".
8521 */
8522static __isl_give isl_map *isl_map_reverse_range_product(
8523	__isl_take isl_map *map1, __isl_take isl_map *map2)
8524{
8525	return isl_map_range_product(map2, map1);
8526}
8527
8528/* Given a map "map" in a space [A -> B] -> C and a map "factor"
8529 * in the space A -> C, return the intersection.
8530 */
8531__isl_give isl_map *isl_map_intersect_domain_factor_domain(
8532	__isl_take isl_map *map, __isl_take isl_map *factor)
8533{
8534	struct isl_intersect_factor_control control = {
8535		.preserve_type = isl_dim_in,
8536		.other_factor = isl_space_domain_factor_range,
8537		.product = isl_map_domain_product,
8538	};
8539
8540	return isl_map_intersect_factor(map, factor, &control);
8541}
8542
8543/* Given a map "map" in a space [A -> B] -> C and a map "factor"
8544 * in the space B -> C, return the intersection.
8545 */
8546__isl_give isl_map *isl_map_intersect_domain_factor_range(
8547	__isl_take isl_map *map, __isl_take isl_map *factor)
8548{
8549	struct isl_intersect_factor_control control = {
8550		.preserve_type = isl_dim_in,
8551		.other_factor = isl_space_domain_factor_domain,
8552		.product = isl_map_reverse_domain_product,
8553	};
8554
8555	return isl_map_intersect_factor(map, factor, &control);
8556}
8557
8558/* Given a map "map" in a space A -> [B -> C] and a map "factor"
8559 * in the space A -> B, return the intersection.
8560 */
8561__isl_give isl_map *isl_map_intersect_range_factor_domain(
8562	__isl_take isl_map *map, __isl_take isl_map *factor)
8563{
8564	struct isl_intersect_factor_control control = {
8565		.preserve_type = isl_dim_out,
8566		.other_factor = isl_space_range_factor_range,
8567		.product = isl_map_range_product,
8568	};
8569
8570	return isl_map_intersect_factor(map, factor, &control);
8571}
8572
8573/* Given a map "map" in a space A -> [B -> C] and a map "factor"
8574 * in the space A -> C, return the intersection.
8575 */
8576__isl_give isl_map *isl_map_intersect_range_factor_range(
8577	__isl_take isl_map *map, __isl_take isl_map *factor)
8578{
8579	struct isl_intersect_factor_control control = {
8580		.preserve_type = isl_dim_out,
8581		.other_factor = isl_space_range_factor_domain,
8582		.product = isl_map_reverse_range_product,
8583	};
8584
8585	return isl_map_intersect_factor(map, factor, &control);
8586}
8587
8588/* Given a set "set" in a space [A -> B] and a set "domain"
8589 * in the space A, return the intersection.
8590 *
8591 * The set "domain" is first extended to a set living in the space
8592 * [A -> B] and then a regular intersection is computed.
8593 */
8594__isl_give isl_set *isl_set_intersect_factor_domain(__isl_take isl_set *set,
8595	__isl_take isl_set *domain)
8596{
8597	struct isl_intersect_factor_control control = {
8598		.preserve_type = isl_dim_set,
8599		.other_factor = isl_space_factor_range,
8600		.product = isl_map_range_product,
8601	};
8602
8603	return set_from_map(isl_map_intersect_factor(set_to_map(set),
8604						set_to_map(domain), &control));
8605}
8606
8607/* Given a set "set" in a space [A -> B] and a set "range"
8608 * in the space B, return the intersection.
8609 *
8610 * The set "range" is first extended to a set living in the space
8611 * [A -> B] and then a regular intersection is computed.
8612 */
8613__isl_give isl_set *isl_set_intersect_factor_range(__isl_take isl_set *set,
8614	__isl_take isl_set *range)
8615{
8616	struct isl_intersect_factor_control control = {
8617		.preserve_type = isl_dim_set,
8618		.other_factor = isl_space_factor_domain,
8619		.product = isl_map_reverse_range_product,
8620	};
8621
8622	return set_from_map(isl_map_intersect_factor(set_to_map(set),
8623						set_to_map(range), &control));
8624}
8625
8626#undef BASE
8627#define BASE set
8628static
8629#include "isl_copy_tuple_id_templ.c"
8630
8631/* Given a map "map" in a space [A -> B] -> C and a set "domain"
8632 * in the space A, return the intersection.
8633 *
8634 * The set "domain" is extended to a set living in the space [A -> B] and
8635 * the domain of "map" is intersected with this set.
8636 *
8637 * If "map" has an identifier on the domain tuple,
8638 * then this identifier needs to be set on this product
8639 * before the intersection is computed.
8640 */
8641__isl_give isl_map *isl_map_intersect_domain_wrapped_domain(
8642	__isl_take isl_map *map, __isl_take isl_set *domain)
8643{
8644	isl_space *space;
8645	isl_set *factor;
8646
8647	isl_map_align_params_set(&map, &domain);
8648	space = isl_map_get_space(map);
8649	space = isl_space_domain_wrapped_range(space);
8650	factor = isl_set_universe(space);
8651	domain = isl_set_product(domain, factor);
8652	space = isl_map_peek_space(map);
8653	domain = isl_set_copy_tuple_id(domain, isl_dim_set, space, isl_dim_in);
8654	return isl_map_intersect_domain(map, domain);
8655}
8656
8657/* Given a map "map" in a space A -> [B -> C] and a set "domain"
8658 * in the space B, return the intersection.
8659 *
8660 * The set "domain" is extended to a set living in the space [B -> C] and
8661 * the range of "map" is intersected with this set.
8662 *
8663 * If "map" has an identifier on the range tuple,
8664 * then this identifier needs to be set on this product
8665 * before the intersection is computed.
8666 */
8667__isl_give isl_map *isl_map_intersect_range_wrapped_domain(
8668	__isl_take isl_map *map, __isl_take isl_set *domain)
8669{
8670	isl_space *space;
8671	isl_set *factor;
8672
8673	isl_map_align_params_set(&map, &domain);
8674	space = isl_map_get_space(map);
8675	space = isl_space_range_wrapped_range(space);
8676	factor = isl_set_universe(space);
8677	domain = isl_set_product(domain, factor);
8678	space = isl_map_peek_space(map);
8679	domain = isl_set_copy_tuple_id(domain, isl_dim_set, space, isl_dim_out);
8680	return isl_map_intersect_range(map, domain);
8681}
8682
8683__isl_give isl_map *isl_map_apply_domain(__isl_take isl_map *map1,
8684	__isl_take isl_map *map2)
8685{
8686	if (isl_map_align_params_bin(&map1, &map2) < 0)
8687		goto error;
8688	map1 = isl_map_reverse(map1);
8689	map1 = isl_map_apply_range(map1, map2);
8690	return isl_map_reverse(map1);
8691error:
8692	isl_map_free(map1);
8693	isl_map_free(map2);
8694	return NULL;
8695}
8696
8697__isl_give isl_map *isl_map_apply_range(__isl_take isl_map *map1,
8698	__isl_take isl_map *map2)
8699{
8700	isl_space *space;
8701	struct isl_map *result;
8702	int i, j;
8703
8704	if (isl_map_align_params_bin(&map1, &map2) < 0)
8705		goto error;
8706
8707	space = isl_space_join(isl_space_copy(map1->dim),
8708				  isl_space_copy(map2->dim));
8709
8710	result = isl_map_alloc_space(space, map1->n * map2->n, 0);
8711	if (!result)
8712		goto error;
8713	for (i = 0; i < map1->n; ++i)
8714		for (j = 0; j < map2->n; ++j) {
8715			result = isl_map_add_basic_map(result,
8716			    isl_basic_map_apply_range(
8717				isl_basic_map_copy(map1->p[i]),
8718				isl_basic_map_copy(map2->p[j])));
8719			if (!result)
8720				goto error;
8721		}
8722	isl_map_free(map1);
8723	isl_map_free(map2);
8724	if (result && result->n <= 1)
8725		ISL_F_SET(result, ISL_MAP_DISJOINT);
8726	return result;
8727error:
8728	isl_map_free(map1);
8729	isl_map_free(map2);
8730	return NULL;
8731}
8732
8733/* Is "bmap" a transformation, i.e.,
8734 * does it relate elements from the same space.
8735 */
8736isl_bool isl_basic_map_is_transformation(__isl_keep isl_basic_map *bmap)
8737{
8738	isl_space *space;
8739
8740	space = isl_basic_map_peek_space(bmap);
8741	return isl_space_tuple_is_equal(space, isl_dim_in, space, isl_dim_out);
8742}
8743
8744/* Check that "bmap" is a transformation, i.e.,
8745 * that it relates elements from the same space.
8746 */
8747static isl_stat isl_basic_map_check_transformation(
8748	__isl_keep isl_basic_map *bmap)
8749{
8750	isl_bool equal;
8751
8752	equal = isl_basic_map_is_transformation(bmap);
8753	if (equal < 0)
8754		return isl_stat_error;
8755	if (!equal)
8756		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
8757			"domain and range don't match", return isl_stat_error);
8758	return isl_stat_ok;
8759}
8760
8761/*
8762 * returns range - domain
8763 */
8764__isl_give isl_basic_set *isl_basic_map_deltas(__isl_take isl_basic_map *bmap)
8765{
8766	isl_space *target_space;
8767	struct isl_basic_set *bset;
8768	isl_size dim;
8769	isl_size nparam;
8770	isl_size total;
8771	int i;
8772
8773	if (isl_basic_map_check_transformation(bmap) < 0)
8774		return isl_basic_map_free(bmap);
8775	dim = isl_basic_map_dim(bmap, isl_dim_in);
8776	nparam = isl_basic_map_dim(bmap, isl_dim_param);
8777	if (dim < 0 || nparam < 0)
8778		goto error;
8779	target_space = isl_space_domain(isl_basic_map_get_space(bmap));
8780	bmap = isl_basic_map_from_range(isl_basic_map_wrap(bmap));
8781	bmap = isl_basic_map_add_dims(bmap, isl_dim_in, dim);
8782	total = isl_basic_map_dim(bmap, isl_dim_all);
8783	if (total < 0)
8784		bmap = isl_basic_map_free(bmap);
8785	bmap = isl_basic_map_extend_constraints(bmap, dim, 0);
8786	for (i = 0; i < dim; ++i) {
8787		int j = isl_basic_map_alloc_equality(bmap);
8788		if (j < 0) {
8789			bmap = isl_basic_map_free(bmap);
8790			break;
8791		}
8792		isl_seq_clr(bmap->eq[j], 1 + total);
8793		isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
8794		isl_int_set_si(bmap->eq[j][1+nparam+dim+i], 1);
8795		isl_int_set_si(bmap->eq[j][1+nparam+2*dim+i], -1);
8796	}
8797	bset = isl_basic_map_domain(bmap);
8798	bset = isl_basic_set_reset_space(bset, target_space);
8799	return bset;
8800error:
8801	isl_basic_map_free(bmap);
8802	return NULL;
8803}
8804
8805/* Is the tuple of type "type1" of "map" the same as
8806 * the tuple of type "type2" of "space"?
8807 */
8808isl_bool isl_map_space_tuple_is_equal(__isl_keep isl_map *map,
8809	enum isl_dim_type type1, __isl_keep isl_space *space,
8810	enum isl_dim_type type2)
8811{
8812	isl_space *map_space;
8813
8814	map_space = isl_map_peek_space(map);
8815	return isl_space_tuple_is_equal(map_space, type1, space, type2);
8816}
8817
8818/* Is the tuple of type "type1" of "map1" the same as
8819 * the tuple of type "type2" of "map2"?
8820 */
8821isl_bool isl_map_tuple_is_equal(__isl_keep isl_map *map1,
8822	enum isl_dim_type type1, __isl_keep isl_map *map2,
8823	enum isl_dim_type type2)
8824{
8825	isl_space *space1, *space2;
8826
8827	space1 = isl_map_peek_space(map1);
8828	space2 = isl_map_peek_space(map2);
8829	return isl_space_tuple_is_equal(space1, type1, space2, type2);
8830}
8831
8832/* Is the space of "obj" equal to "space", ignoring parameters?
8833 */
8834isl_bool isl_map_has_space_tuples(__isl_keep isl_map *map,
8835	__isl_keep isl_space *space)
8836{
8837	isl_space *map_space;
8838
8839	map_space = isl_map_peek_space(map);
8840	return isl_space_has_equal_tuples(map_space, space);
8841}
8842
8843/* Check that "map" is a transformation, i.e.,
8844 * that it relates elements from the same space.
8845 */
8846isl_stat isl_map_check_transformation(__isl_keep isl_map *map)
8847{
8848	isl_bool equal;
8849
8850	equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out);
8851	if (equal < 0)
8852		return isl_stat_error;
8853	if (!equal)
8854		isl_die(isl_map_get_ctx(map), isl_error_invalid,
8855			"domain and range don't match", return isl_stat_error);
8856	return isl_stat_ok;
8857}
8858
8859/*
8860 * returns range - domain
8861 */
8862__isl_give isl_set *isl_map_deltas(__isl_take isl_map *map)
8863{
8864	int i;
8865	isl_space *space;
8866	struct isl_set *result;
8867
8868	if (isl_map_check_transformation(map) < 0)
8869		goto error;
8870	space = isl_map_get_space(map);
8871	space = isl_space_domain(space);
8872	result = isl_set_alloc_space(space, map->n, 0);
8873	if (!result)
8874		goto error;
8875	for (i = 0; i < map->n; ++i)
8876		result = isl_set_add_basic_set(result,
8877			  isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
8878	isl_map_free(map);
8879	return result;
8880error:
8881	isl_map_free(map);
8882	return NULL;
8883}
8884
8885/*
8886 * returns [domain -> range] -> range - domain
8887 */
8888__isl_give isl_basic_map *isl_basic_map_deltas_map(
8889	__isl_take isl_basic_map *bmap)
8890{
8891	int i, k;
8892	isl_space *space;
8893	isl_basic_map *domain;
8894	isl_size nparam, n;
8895	isl_size total;
8896
8897	if (isl_basic_map_check_transformation(bmap) < 0)
8898		return isl_basic_map_free(bmap);
8899
8900	nparam = isl_basic_map_dim(bmap, isl_dim_param);
8901	n = isl_basic_map_dim(bmap, isl_dim_in);
8902	if (nparam < 0 || n < 0)
8903		return isl_basic_map_free(bmap);
8904
8905	space = isl_basic_map_get_space(bmap);
8906	space = isl_space_from_range(isl_space_domain(space));
8907	domain = isl_basic_map_universe(space);
8908
8909	bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
8910	bmap = isl_basic_map_apply_range(bmap, domain);
8911	bmap = isl_basic_map_extend_constraints(bmap, n, 0);
8912
8913	total = isl_basic_map_dim(bmap, isl_dim_all);
8914	if (total < 0)
8915		return isl_basic_map_free(bmap);
8916
8917	for (i = 0; i < n; ++i) {
8918		k = isl_basic_map_alloc_equality(bmap);
8919		if (k < 0)
8920			goto error;
8921		isl_seq_clr(bmap->eq[k], 1 + total);
8922		isl_int_set_si(bmap->eq[k][1 + nparam + i], 1);
8923		isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1);
8924		isl_int_set_si(bmap->eq[k][1 + nparam + n + n + i], 1);
8925	}
8926
8927	bmap = isl_basic_map_gauss(bmap, NULL);
8928	return isl_basic_map_finalize(bmap);
8929error:
8930	isl_basic_map_free(bmap);
8931	return NULL;
8932}
8933
8934/*
8935 * returns [domain -> range] -> range - domain
8936 */
8937__isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map)
8938{
8939	if (isl_map_check_transformation(map) < 0)
8940		return isl_map_free(map);
8941
8942	return isl_map_transform(map, &isl_space_range_map,
8943					&isl_basic_map_deltas_map);
8944}
8945
8946/* Return pairs of elements { x -> y } such that y - x is in "deltas".
8947 */
8948__isl_give isl_map *isl_set_translation(__isl_take isl_set *deltas)
8949{
8950	isl_space *space;
8951	isl_map *map;
8952
8953	space = isl_space_map_from_set(isl_set_get_space(deltas));
8954	map = isl_map_deltas_map(isl_map_universe(space));
8955	map = isl_map_intersect_range(map, deltas);
8956
8957	return isl_set_unwrap(isl_map_domain(map));
8958}
8959
8960__isl_give isl_basic_map *isl_basic_map_identity(__isl_take isl_space *space)
8961{
8962	isl_size n_in, n_out;
8963
8964	n_in = isl_space_dim(space, isl_dim_in);
8965	n_out = isl_space_dim(space, isl_dim_out);
8966	if (n_in < 0 || n_out < 0)
8967		goto error;
8968	if (n_in != n_out)
8969		isl_die(space->ctx, isl_error_invalid,
8970			"number of input and output dimensions needs to be "
8971			"the same", goto error);
8972	return isl_basic_map_equal(space, n_in);
8973error:
8974	isl_space_free(space);
8975	return NULL;
8976}
8977
8978__isl_give isl_map *isl_map_identity(__isl_take isl_space *space)
8979{
8980	return isl_map_from_basic_map(isl_basic_map_identity(space));
8981}
8982
8983__isl_give isl_map *isl_set_identity(__isl_take isl_set *set)
8984{
8985	isl_space *space = isl_set_get_space(set);
8986	isl_map *id;
8987	id = isl_map_identity(isl_space_map_from_set(space));
8988	return isl_map_intersect_range(id, set);
8989}
8990
8991/* Construct a basic set with all set dimensions having only non-negative
8992 * values.
8993 */
8994__isl_give isl_basic_set *isl_basic_set_positive_orthant(
8995	__isl_take isl_space *space)
8996{
8997	int i;
8998	isl_size nparam;
8999	isl_size dim;
9000	isl_size total;
9001	struct isl_basic_set *bset;
9002
9003	nparam = isl_space_dim(space, isl_dim_param);
9004	dim = isl_space_dim(space, isl_dim_set);
9005	total = isl_space_dim(space, isl_dim_all);
9006	if (nparam < 0 || dim < 0 || total < 0)
9007		space = isl_space_free(space);
9008	bset = isl_basic_set_alloc_space(space, 0, 0, dim);
9009	if (!bset)
9010		return NULL;
9011	for (i = 0; i < dim; ++i) {
9012		int k = isl_basic_set_alloc_inequality(bset);
9013		if (k < 0)
9014			goto error;
9015		isl_seq_clr(bset->ineq[k], 1 + total);
9016		isl_int_set_si(bset->ineq[k][1 + nparam + i], 1);
9017	}
9018	return bset;
9019error:
9020	isl_basic_set_free(bset);
9021	return NULL;
9022}
9023
9024/* Construct the half-space x_pos >= 0.
9025 */
9026static __isl_give isl_basic_set *nonneg_halfspace(__isl_take isl_space *space,
9027	int pos)
9028{
9029	int k;
9030	isl_size total;
9031	isl_basic_set *nonneg;
9032
9033	total = isl_space_dim(space, isl_dim_all);
9034	if (total < 0)
9035		space = isl_space_free(space);
9036	nonneg = isl_basic_set_alloc_space(space, 0, 0, 1);
9037	k = isl_basic_set_alloc_inequality(nonneg);
9038	if (k < 0)
9039		goto error;
9040	isl_seq_clr(nonneg->ineq[k], 1 + total);
9041	isl_int_set_si(nonneg->ineq[k][pos], 1);
9042
9043	return isl_basic_set_finalize(nonneg);
9044error:
9045	isl_basic_set_free(nonneg);
9046	return NULL;
9047}
9048
9049/* Construct the half-space x_pos <= -1.
9050 */
9051static __isl_give isl_basic_set *neg_halfspace(__isl_take isl_space *space,
9052	int pos)
9053{
9054	int k;
9055	isl_size total;
9056	isl_basic_set *neg;
9057
9058	total = isl_space_dim(space, isl_dim_all);
9059	if (total < 0)
9060		space = isl_space_free(space);
9061	neg = isl_basic_set_alloc_space(space, 0, 0, 1);
9062	k = isl_basic_set_alloc_inequality(neg);
9063	if (k < 0)
9064		goto error;
9065	isl_seq_clr(neg->ineq[k], 1 + total);
9066	isl_int_set_si(neg->ineq[k][0], -1);
9067	isl_int_set_si(neg->ineq[k][pos], -1);
9068
9069	return isl_basic_set_finalize(neg);
9070error:
9071	isl_basic_set_free(neg);
9072	return NULL;
9073}
9074
9075__isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set,
9076	enum isl_dim_type type, unsigned first, unsigned n)
9077{
9078	int i;
9079	unsigned offset;
9080	isl_basic_set *nonneg;
9081	isl_basic_set *neg;
9082
9083	if (n == 0)
9084		return set;
9085
9086	if (isl_set_check_range(set, type, first, n) < 0)
9087		return isl_set_free(set);
9088
9089	offset = pos(set->dim, type);
9090	for (i = 0; i < n; ++i) {
9091		nonneg = nonneg_halfspace(isl_set_get_space(set),
9092					  offset + first + i);
9093		neg = neg_halfspace(isl_set_get_space(set), offset + first + i);
9094
9095		set = isl_set_intersect(set, isl_basic_set_union(nonneg, neg));
9096	}
9097
9098	return set;
9099}
9100
9101static isl_stat foreach_orthant(__isl_take isl_set *set, int *signs, int first,
9102	int len,
9103	isl_stat (*fn)(__isl_take isl_set *orthant, int *signs, void *user),
9104	void *user)
9105{
9106	isl_set *half;
9107
9108	if (!set)
9109		return isl_stat_error;
9110	if (isl_set_plain_is_empty(set)) {
9111		isl_set_free(set);
9112		return isl_stat_ok;
9113	}
9114	if (first == len)
9115		return fn(set, signs, user);
9116
9117	signs[first] = 1;
9118	half = isl_set_from_basic_set(nonneg_halfspace(isl_set_get_space(set),
9119							1 + first));
9120	half = isl_set_intersect(half, isl_set_copy(set));
9121	if (foreach_orthant(half, signs, first + 1, len, fn, user) < 0)
9122		goto error;
9123
9124	signs[first] = -1;
9125	half = isl_set_from_basic_set(neg_halfspace(isl_set_get_space(set),
9126							1 + first));
9127	half = isl_set_intersect(half, set);
9128	return foreach_orthant(half, signs, first + 1, len, fn, user);
9129error:
9130	isl_set_free(set);
9131	return isl_stat_error;
9132}
9133
9134/* Call "fn" on the intersections of "set" with each of the orthants
9135 * (except for obviously empty intersections).  The orthant is identified
9136 * by the signs array, with each entry having value 1 or -1 according
9137 * to the sign of the corresponding variable.
9138 */
9139isl_stat isl_set_foreach_orthant(__isl_keep isl_set *set,
9140	isl_stat (*fn)(__isl_take isl_set *orthant, int *signs, void *user),
9141	void *user)
9142{
9143	isl_size nparam;
9144	isl_size nvar;
9145	int *signs;
9146	isl_stat r;
9147
9148	if (!set)
9149		return isl_stat_error;
9150	if (isl_set_plain_is_empty(set))
9151		return isl_stat_ok;
9152
9153	nparam = isl_set_dim(set, isl_dim_param);
9154	nvar = isl_set_dim(set, isl_dim_set);
9155	if (nparam < 0 || nvar < 0)
9156		return isl_stat_error;
9157
9158	signs = isl_alloc_array(set->ctx, int, nparam + nvar);
9159
9160	r = foreach_orthant(isl_set_copy(set), signs, 0, nparam + nvar,
9161			    fn, user);
9162
9163	free(signs);
9164
9165	return r;
9166}
9167
9168isl_bool isl_set_is_equal(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
9169{
9170	return isl_map_is_equal(set_to_map(set1), set_to_map(set2));
9171}
9172
9173isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1,
9174	__isl_keep isl_basic_map *bmap2)
9175{
9176	isl_bool is_subset;
9177	struct isl_map *map1;
9178	struct isl_map *map2;
9179
9180	if (!bmap1 || !bmap2)
9181		return isl_bool_error;
9182
9183	map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
9184	map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
9185
9186	is_subset = isl_map_is_subset(map1, map2);
9187
9188	isl_map_free(map1);
9189	isl_map_free(map2);
9190
9191	return is_subset;
9192}
9193
9194isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1,
9195	__isl_keep isl_basic_set *bset2)
9196{
9197	return isl_basic_map_is_subset(bset1, bset2);
9198}
9199
9200isl_bool isl_basic_map_is_equal(__isl_keep isl_basic_map *bmap1,
9201	__isl_keep isl_basic_map *bmap2)
9202{
9203	isl_bool is_subset;
9204
9205	if (!bmap1 || !bmap2)
9206		return isl_bool_error;
9207	is_subset = isl_basic_map_is_subset(bmap1, bmap2);
9208	if (is_subset != isl_bool_true)
9209		return is_subset;
9210	is_subset = isl_basic_map_is_subset(bmap2, bmap1);
9211	return is_subset;
9212}
9213
9214isl_bool isl_basic_set_is_equal(__isl_keep isl_basic_set *bset1,
9215	__isl_keep isl_basic_set *bset2)
9216{
9217	return isl_basic_map_is_equal(
9218		bset_to_bmap(bset1), bset_to_bmap(bset2));
9219}
9220
9221isl_bool isl_map_is_empty(__isl_keep isl_map *map)
9222{
9223	int i;
9224	int is_empty;
9225
9226	if (!map)
9227		return isl_bool_error;
9228	for (i = 0; i < map->n; ++i) {
9229		is_empty = isl_basic_map_is_empty(map->p[i]);
9230		if (is_empty < 0)
9231			return isl_bool_error;
9232		if (!is_empty)
9233			return isl_bool_false;
9234	}
9235	return isl_bool_true;
9236}
9237
9238isl_bool isl_map_plain_is_empty(__isl_keep isl_map *map)
9239{
9240	return map ? map->n == 0 : isl_bool_error;
9241}
9242
9243isl_bool isl_set_plain_is_empty(__isl_keep isl_set *set)
9244{
9245	return set ? set->n == 0 : isl_bool_error;
9246}
9247
9248isl_bool isl_set_is_empty(__isl_keep isl_set *set)
9249{
9250	return isl_map_is_empty(set_to_map(set));
9251}
9252
9253#undef TYPE
9254#define TYPE	isl_basic_map
9255
9256static
9257#include "isl_type_has_equal_space_bin_templ.c"
9258#include "isl_type_check_equal_space_templ.c"
9259
9260/* Check that "bset1" and "bset2" live in the same space,
9261 * reporting an error if they do not.
9262 */
9263isl_stat isl_basic_set_check_equal_space(__isl_keep isl_basic_set *bset1,
9264	__isl_keep isl_basic_set *bset2)
9265{
9266	return isl_basic_map_check_equal_space(bset_to_bmap(bset1),
9267						bset_to_bmap(bset1));
9268}
9269
9270#undef TYPE
9271#define TYPE	isl_map
9272
9273#include "isl_type_has_equal_space_bin_templ.c"
9274#include "isl_type_check_equal_space_templ.c"
9275#include "isl_type_has_space_templ.c"
9276
9277isl_bool isl_set_has_equal_space(__isl_keep isl_set *set1,
9278	__isl_keep isl_set *set2)
9279{
9280	return isl_map_has_equal_space(set_to_map(set1), set_to_map(set2));
9281}
9282
9283#undef TYPE1
9284#define TYPE1		isl_map
9285#undef TYPE2
9286#define TYPE2		isl_basic_map
9287#undef TYPE_PAIR
9288#define TYPE_PAIR	isl_map_basic_map
9289
9290static
9291#include "isl_type_has_equal_space_templ.c"
9292#include "isl_type_check_equal_space_templ.c"
9293
9294/* Check that "set" and "bset" live in the same space,
9295 * reporting an error if they do not.
9296 */
9297isl_stat isl_set_basic_set_check_equal_space(__isl_keep isl_set *set,
9298	__isl_keep isl_basic_set *bset)
9299{
9300	return isl_map_basic_map_check_equal_space(set_to_map(set),
9301						    bset_to_bmap(bset));
9302}
9303
9304static isl_bool map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
9305{
9306	isl_bool is_subset;
9307
9308	if (!map1 || !map2)
9309		return isl_bool_error;
9310	is_subset = isl_map_is_subset(map1, map2);
9311	if (is_subset != isl_bool_true)
9312		return is_subset;
9313	is_subset = isl_map_is_subset(map2, map1);
9314	return is_subset;
9315}
9316
9317/* Is "map1" equal to "map2"?
9318 *
9319 * First check if they are obviously equal.
9320 * If not, then perform a more detailed analysis.
9321 */
9322isl_bool isl_map_is_equal(__isl_keep isl_map *map1, __isl_keep isl_map *map2)
9323{
9324	isl_bool equal;
9325
9326	equal = isl_map_plain_is_equal(map1, map2);
9327	if (equal < 0 || equal)
9328		return equal;
9329	return isl_map_align_params_map_map_and_test(map1, map2, &map_is_equal);
9330}
9331
9332isl_bool isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1,
9333	__isl_keep isl_basic_map *bmap2)
9334{
9335	isl_bool is_subset;
9336
9337	if (!bmap1 || !bmap2)
9338		return isl_bool_error;
9339	is_subset = isl_basic_map_is_subset(bmap1, bmap2);
9340	if (is_subset != isl_bool_true)
9341		return is_subset;
9342	is_subset = isl_basic_map_is_subset(bmap2, bmap1);
9343	return isl_bool_not(is_subset);
9344}
9345
9346isl_bool isl_map_is_strict_subset(__isl_keep isl_map *map1,
9347	__isl_keep isl_map *map2)
9348{
9349	isl_bool is_subset;
9350
9351	if (!map1 || !map2)
9352		return isl_bool_error;
9353	is_subset = isl_map_is_subset(map1, map2);
9354	if (is_subset != isl_bool_true)
9355		return is_subset;
9356	is_subset = isl_map_is_subset(map2, map1);
9357	return isl_bool_not(is_subset);
9358}
9359
9360isl_bool isl_set_is_strict_subset(__isl_keep isl_set *set1,
9361	__isl_keep isl_set *set2)
9362{
9363	return isl_map_is_strict_subset(set_to_map(set1), set_to_map(set2));
9364}
9365
9366/* Is "bmap" obviously equal to the universe with the same space?
9367 *
9368 * That is, does it not have any constraints?
9369 */
9370isl_bool isl_basic_map_plain_is_universe(__isl_keep isl_basic_map *bmap)
9371{
9372	if (!bmap)
9373		return isl_bool_error;
9374	return bmap->n_eq == 0 && bmap->n_ineq == 0;
9375}
9376
9377/* Is "bset" obviously equal to the universe with the same space?
9378 */
9379isl_bool isl_basic_set_plain_is_universe(__isl_keep isl_basic_set *bset)
9380{
9381	return isl_basic_map_plain_is_universe(bset);
9382}
9383
9384/* If "c" does not involve any existentially quantified variables,
9385 * then set *univ to false and abort
9386 */
9387static isl_stat involves_divs(__isl_take isl_constraint *c, void *user)
9388{
9389	isl_bool *univ = user;
9390	isl_size n;
9391
9392	n = isl_constraint_dim(c, isl_dim_div);
9393	if (n < 0)
9394		c = isl_constraint_free(c);
9395	*univ = isl_constraint_involves_dims(c, isl_dim_div, 0, n);
9396	isl_constraint_free(c);
9397	if (*univ < 0 || !*univ)
9398		return isl_stat_error;
9399	return isl_stat_ok;
9400}
9401
9402/* Is "bmap" equal to the universe with the same space?
9403 *
9404 * First check if it is obviously equal to the universe.
9405 * If not and if there are any constraints not involving
9406 * existentially quantified variables, then it is certainly
9407 * not equal to the universe.
9408 * Otherwise, check if the universe is a subset of "bmap".
9409 */
9410isl_bool isl_basic_map_is_universe(__isl_keep isl_basic_map *bmap)
9411{
9412	isl_size n_div;
9413	isl_bool univ;
9414	isl_basic_map *test;
9415
9416	univ = isl_basic_map_plain_is_universe(bmap);
9417	if (univ < 0 || univ)
9418		return univ;
9419	n_div = isl_basic_map_dim(bmap, isl_dim_div);
9420	if (n_div < 0)
9421		return isl_bool_error;
9422	if (n_div == 0)
9423		return isl_bool_false;
9424	univ = isl_bool_true;
9425	if (isl_basic_map_foreach_constraint(bmap, &involves_divs, &univ) < 0 &&
9426	    univ)
9427		return isl_bool_error;
9428	if (univ < 0 || !univ)
9429		return univ;
9430	test = isl_basic_map_universe(isl_basic_map_get_space(bmap));
9431	univ = isl_basic_map_is_subset(test, bmap);
9432	isl_basic_map_free(test);
9433	return univ;
9434}
9435
9436/* Is "bset" equal to the universe with the same space?
9437 */
9438isl_bool isl_basic_set_is_universe(__isl_keep isl_basic_set *bset)
9439{
9440	return isl_basic_map_is_universe(bset);
9441}
9442
9443isl_bool isl_map_plain_is_universe(__isl_keep isl_map *map)
9444{
9445	int i;
9446
9447	if (!map)
9448		return isl_bool_error;
9449
9450	for (i = 0; i < map->n; ++i) {
9451		isl_bool r = isl_basic_map_plain_is_universe(map->p[i]);
9452		if (r < 0 || r)
9453			return r;
9454	}
9455
9456	return isl_bool_false;
9457}
9458
9459isl_bool isl_set_plain_is_universe(__isl_keep isl_set *set)
9460{
9461	return isl_map_plain_is_universe(set_to_map(set));
9462}
9463
9464isl_bool isl_basic_map_is_empty(__isl_keep isl_basic_map *bmap)
9465{
9466	struct isl_basic_set *bset = NULL;
9467	struct isl_vec *sample = NULL;
9468	isl_bool empty, non_empty;
9469
9470	if (!bmap)
9471		return isl_bool_error;
9472
9473	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
9474		return isl_bool_true;
9475
9476	if (isl_basic_map_plain_is_universe(bmap))
9477		return isl_bool_false;
9478
9479	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
9480		struct isl_basic_map *copy = isl_basic_map_copy(bmap);
9481		copy = isl_basic_map_remove_redundancies(copy);
9482		empty = isl_basic_map_plain_is_empty(copy);
9483		isl_basic_map_free(copy);
9484		return empty;
9485	}
9486
9487	non_empty = isl_basic_map_plain_is_non_empty(bmap);
9488	if (non_empty < 0)
9489		return isl_bool_error;
9490	if (non_empty)
9491		return isl_bool_false;
9492	isl_vec_free(bmap->sample);
9493	bmap->sample = NULL;
9494	bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
9495	if (!bset)
9496		return isl_bool_error;
9497	sample = isl_basic_set_sample_vec(bset);
9498	if (!sample)
9499		return isl_bool_error;
9500	empty = sample->size == 0;
9501	isl_vec_free(bmap->sample);
9502	bmap->sample = sample;
9503	if (empty)
9504		ISL_F_SET(bmap, ISL_BASIC_MAP_EMPTY);
9505
9506	return empty;
9507}
9508
9509isl_bool isl_basic_map_plain_is_empty(__isl_keep isl_basic_map *bmap)
9510{
9511	if (!bmap)
9512		return isl_bool_error;
9513	return ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY);
9514}
9515
9516isl_bool isl_basic_set_plain_is_empty(__isl_keep isl_basic_set *bset)
9517{
9518	if (!bset)
9519		return isl_bool_error;
9520	return ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY);
9521}
9522
9523/* Is "bmap" known to be non-empty?
9524 *
9525 * That is, is the cached sample still valid?
9526 */
9527isl_bool isl_basic_map_plain_is_non_empty(__isl_keep isl_basic_map *bmap)
9528{
9529	isl_size total;
9530
9531	if (!bmap)
9532		return isl_bool_error;
9533	if (!bmap->sample)
9534		return isl_bool_false;
9535	total = isl_basic_map_dim(bmap, isl_dim_all);
9536	if (total < 0)
9537		return isl_bool_error;
9538	if (bmap->sample->size != 1 + total)
9539		return isl_bool_false;
9540	return isl_basic_map_contains(bmap, bmap->sample);
9541}
9542
9543isl_bool isl_basic_set_is_empty(__isl_keep isl_basic_set *bset)
9544{
9545	return isl_basic_map_is_empty(bset_to_bmap(bset));
9546}
9547
9548__isl_give isl_map *isl_basic_map_union(__isl_take isl_basic_map *bmap1,
9549	__isl_take isl_basic_map *bmap2)
9550{
9551	struct isl_map *map;
9552
9553	if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
9554		goto error;
9555
9556	map = isl_map_alloc_space(isl_space_copy(bmap1->dim), 2, 0);
9557	if (!map)
9558		goto error;
9559	map = isl_map_add_basic_map(map, bmap1);
9560	map = isl_map_add_basic_map(map, bmap2);
9561	return map;
9562error:
9563	isl_basic_map_free(bmap1);
9564	isl_basic_map_free(bmap2);
9565	return NULL;
9566}
9567
9568__isl_give isl_set *isl_basic_set_union(__isl_take isl_basic_set *bset1,
9569	__isl_take isl_basic_set *bset2)
9570{
9571	return set_from_map(isl_basic_map_union(bset_to_bmap(bset1),
9572						bset_to_bmap(bset2)));
9573}
9574
9575/* Order divs such that any div only depends on previous divs */
9576__isl_give isl_basic_map *isl_basic_map_order_divs(
9577	__isl_take isl_basic_map *bmap)
9578{
9579	int i;
9580	isl_size off;
9581
9582	off = isl_basic_map_var_offset(bmap, isl_dim_div);
9583	if (off < 0)
9584		return isl_basic_map_free(bmap);
9585
9586	for (i = 0; i < bmap->n_div; ++i) {
9587		int pos;
9588		if (isl_int_is_zero(bmap->div[i][0]))
9589			continue;
9590		pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
9591							    bmap->n_div-i);
9592		if (pos == -1)
9593			continue;
9594		if (pos == 0)
9595			isl_die(isl_basic_map_get_ctx(bmap), isl_error_internal,
9596				"integer division depends on itself",
9597				return isl_basic_map_free(bmap));
9598		bmap = isl_basic_map_swap_div(bmap, i, i + pos);
9599		if (!bmap)
9600			return NULL;
9601		--i;
9602	}
9603	return bmap;
9604}
9605
9606__isl_give isl_map *isl_map_order_divs(__isl_take isl_map *map)
9607{
9608	int i;
9609
9610	if (!map)
9611		return 0;
9612
9613	for (i = 0; i < map->n; ++i) {
9614		map->p[i] = isl_basic_map_order_divs(map->p[i]);
9615		if (!map->p[i])
9616			goto error;
9617	}
9618
9619	return map;
9620error:
9621	isl_map_free(map);
9622	return NULL;
9623}
9624
9625/* Sort the local variables of "bset".
9626 */
9627__isl_give isl_basic_set *isl_basic_set_sort_divs(
9628	__isl_take isl_basic_set *bset)
9629{
9630	return bset_from_bmap(isl_basic_map_sort_divs(bset_to_bmap(bset)));
9631}
9632
9633/* Apply the expansion computed by isl_merge_divs.
9634 * The expansion itself is given by "exp" while the resulting
9635 * list of divs is given by "div".
9636 *
9637 * Move the integer divisions of "bmap" into the right position
9638 * according to "exp" and then introduce the additional integer
9639 * divisions, adding div constraints.
9640 * The moving should be done first to avoid moving coefficients
9641 * in the definitions of the extra integer divisions.
9642 */
9643__isl_give isl_basic_map *isl_basic_map_expand_divs(
9644	__isl_take isl_basic_map *bmap, __isl_take isl_mat *div, int *exp)
9645{
9646	int i, j;
9647	int n_div;
9648
9649	bmap = isl_basic_map_cow(bmap);
9650	if (!bmap || !div)
9651		goto error;
9652
9653	if (div->n_row < bmap->n_div)
9654		isl_die(isl_mat_get_ctx(div), isl_error_invalid,
9655			"not an expansion", goto error);
9656
9657	n_div = bmap->n_div;
9658	bmap = isl_basic_map_extend(bmap, div->n_row - n_div, 0,
9659					    2 * (div->n_row - n_div));
9660
9661	for (i = n_div; i < div->n_row; ++i)
9662		if (isl_basic_map_alloc_div(bmap) < 0)
9663			goto error;
9664
9665	for (j = n_div - 1; j >= 0; --j) {
9666		if (exp[j] == j)
9667			break;
9668		bmap = isl_basic_map_swap_div(bmap, j, exp[j]);
9669		if (!bmap)
9670			goto error;
9671	}
9672	j = 0;
9673	for (i = 0; i < div->n_row; ++i) {
9674		if (j < n_div && exp[j] == i) {
9675			j++;
9676		} else {
9677			isl_seq_cpy(bmap->div[i], div->row[i], div->n_col);
9678			if (isl_basic_map_div_is_marked_unknown(bmap, i))
9679				continue;
9680			bmap = isl_basic_map_add_div_constraints(bmap, i);
9681			if (!bmap)
9682				goto error;
9683		}
9684	}
9685
9686	isl_mat_free(div);
9687	return bmap;
9688error:
9689	isl_basic_map_free(bmap);
9690	isl_mat_free(div);
9691	return NULL;
9692}
9693
9694/* Apply the expansion computed by isl_merge_divs.
9695 * The expansion itself is given by "exp" while the resulting
9696 * list of divs is given by "div".
9697 */
9698__isl_give isl_basic_set *isl_basic_set_expand_divs(
9699	__isl_take isl_basic_set *bset, __isl_take isl_mat *div, int *exp)
9700{
9701	return isl_basic_map_expand_divs(bset, div, exp);
9702}
9703
9704/* Look for a div in dst that corresponds to the div "div" in src.
9705 * The divs before "div" in src and dst are assumed to be the same.
9706 *
9707 * Return the position of the corresponding div in dst
9708 * if there is one.  Otherwise, return a position beyond the integer divisions.
9709 * Return -1 on error.
9710 */
9711static int find_div(__isl_keep isl_basic_map *dst,
9712	__isl_keep isl_basic_map *src, unsigned div)
9713{
9714	int i;
9715	isl_size n_div;
9716	isl_size v_div;
9717
9718	v_div = isl_basic_map_var_offset(src, isl_dim_div);
9719	n_div = isl_basic_map_dim(dst, isl_dim_div);
9720	if (n_div < 0 || v_div < 0)
9721		return -1;
9722	isl_assert(dst->ctx, div <= n_div, return -1);
9723	for (i = div; i < n_div; ++i)
9724		if (isl_seq_eq(dst->div[i], src->div[div], 1+1+v_div+div) &&
9725		    isl_seq_first_non_zero(dst->div[i] + 1 + 1 + v_div + div,
9726						n_div - div) == -1)
9727			return i;
9728	return n_div;
9729}
9730
9731/* Align the divs of "dst" to those of "src", adding divs from "src"
9732 * if needed.  That is, make sure that the first src->n_div divs
9733 * of the result are equal to those of src.
9734 * The integer division of "src" are assumed to be ordered.
9735 *
9736 * The integer divisions are swapped into the right position
9737 * (possibly after adding them first).  This may result
9738 * in the remaining integer divisions appearing in the wrong order,
9739 * i.e., with some integer division appearing before
9740 * some other integer division on which it depends.
9741 * The integer divisions therefore need to be ordered.
9742 * This will not affect the integer divisions aligned to those of "src",
9743 * since "src" is assumed to have ordered integer divisions.
9744 *
9745 * The result is not finalized as by design it will have redundant
9746 * divs if any divs from "src" were copied.
9747 */
9748__isl_give isl_basic_map *isl_basic_map_align_divs(
9749	__isl_take isl_basic_map *dst, __isl_keep isl_basic_map *src)
9750{
9751	int i;
9752	isl_bool known;
9753	int extended;
9754	isl_size v_div;
9755	isl_size dst_n_div;
9756
9757	if (!dst || !src)
9758		return isl_basic_map_free(dst);
9759
9760	if (src->n_div == 0)
9761		return dst;
9762
9763	known = isl_basic_map_divs_known(src);
9764	if (known < 0)
9765		return isl_basic_map_free(dst);
9766	if (!known)
9767		isl_die(isl_basic_map_get_ctx(src), isl_error_invalid,
9768			"some src divs are unknown",
9769			return isl_basic_map_free(dst));
9770
9771	v_div = isl_basic_map_var_offset(src, isl_dim_div);
9772	if (v_div < 0)
9773		return isl_basic_map_free(dst);
9774
9775	extended = 0;
9776	dst_n_div = isl_basic_map_dim(dst, isl_dim_div);
9777	if (dst_n_div < 0)
9778		dst = isl_basic_map_free(dst);
9779	for (i = 0; i < src->n_div; ++i) {
9780		int j = find_div(dst, src, i);
9781		if (j < 0)
9782			dst = isl_basic_map_free(dst);
9783		if (j == dst_n_div) {
9784			if (!extended) {
9785				int extra = src->n_div - i;
9786				dst = isl_basic_map_cow(dst);
9787				if (!dst)
9788					return isl_basic_map_free(dst);
9789				dst = isl_basic_map_extend(dst,
9790						extra, 0, 2 * extra);
9791				extended = 1;
9792			}
9793			j = isl_basic_map_alloc_div(dst);
9794			if (j < 0)
9795				return isl_basic_map_free(dst);
9796			isl_seq_cpy(dst->div[j], src->div[i], 1+1+v_div+i);
9797			isl_seq_clr(dst->div[j]+1+1+v_div+i, dst->n_div - i);
9798			dst_n_div++;
9799			dst = isl_basic_map_add_div_constraints(dst, j);
9800			if (!dst)
9801				return isl_basic_map_free(dst);
9802		}
9803		if (j != i)
9804			dst = isl_basic_map_swap_div(dst, i, j);
9805		if (!dst)
9806			return isl_basic_map_free(dst);
9807	}
9808	return isl_basic_map_order_divs(dst);
9809}
9810
9811__isl_give isl_map *isl_map_align_divs_internal(__isl_take isl_map *map)
9812{
9813	int i;
9814
9815	if (!map)
9816		return NULL;
9817	if (map->n == 0)
9818		return map;
9819	map = isl_map_compute_divs(map);
9820	map = isl_map_order_divs(map);
9821	map = isl_map_cow(map);
9822	if (!map)
9823		return NULL;
9824
9825	for (i = 1; i < map->n; ++i)
9826		map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
9827	for (i = 1; i < map->n; ++i) {
9828		map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
9829		if (!map->p[i])
9830			return isl_map_free(map);
9831	}
9832
9833	map = isl_map_unmark_normalized(map);
9834	return map;
9835}
9836
9837__isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map)
9838{
9839	return isl_map_align_divs_internal(map);
9840}
9841
9842__isl_give isl_set *isl_set_align_divs(__isl_take isl_set *set)
9843{
9844	return set_from_map(isl_map_align_divs_internal(set_to_map(set)));
9845}
9846
9847/* Align the divs of the basic maps in "map" to those
9848 * of the basic maps in "list", as well as to the other basic maps in "map".
9849 * The elements in "list" are assumed to have known divs.
9850 */
9851__isl_give isl_map *isl_map_align_divs_to_basic_map_list(
9852	__isl_take isl_map *map, __isl_keep isl_basic_map_list *list)
9853{
9854	int i;
9855	isl_size n;
9856
9857	n = isl_basic_map_list_n_basic_map(list);
9858	map = isl_map_compute_divs(map);
9859	map = isl_map_cow(map);
9860	if (!map || n < 0)
9861		return isl_map_free(map);
9862	if (map->n == 0)
9863		return map;
9864
9865	for (i = 0; i < n; ++i) {
9866		isl_basic_map *bmap;
9867
9868		bmap = isl_basic_map_list_get_basic_map(list, i);
9869		bmap = isl_basic_map_order_divs(bmap);
9870		map->p[0] = isl_basic_map_align_divs(map->p[0], bmap);
9871		isl_basic_map_free(bmap);
9872	}
9873	if (!map->p[0])
9874		return isl_map_free(map);
9875
9876	return isl_map_align_divs_internal(map);
9877}
9878
9879/* Align the divs of each element of "list" to those of "bmap".
9880 * Both "bmap" and the elements of "list" are assumed to have known divs.
9881 */
9882__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map(
9883	__isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap)
9884{
9885	int i;
9886	isl_size n;
9887
9888	n = isl_basic_map_list_n_basic_map(list);
9889	if (n < 0 || !bmap)
9890		return isl_basic_map_list_free(list);
9891
9892	for (i = 0; i < n; ++i) {
9893		isl_basic_map *bmap_i;
9894
9895		bmap_i = isl_basic_map_list_get_basic_map(list, i);
9896		bmap_i = isl_basic_map_align_divs(bmap_i, bmap);
9897		list = isl_basic_map_list_set_basic_map(list, i, bmap_i);
9898	}
9899
9900	return list;
9901}
9902
9903__isl_give isl_set *isl_set_apply( __isl_take isl_set *set,
9904	__isl_take isl_map *map)
9905{
9906	isl_bool ok;
9907
9908	isl_map_align_params_set(&map, &set);
9909	ok = isl_map_compatible_domain(map, set);
9910	if (ok < 0)
9911		goto error;
9912	if (!ok)
9913		isl_die(isl_set_get_ctx(set), isl_error_invalid,
9914			"incompatible spaces", goto error);
9915	map = isl_map_intersect_domain(map, set);
9916	set = isl_map_range(map);
9917	return set;
9918error:
9919	isl_set_free(set);
9920	isl_map_free(map);
9921	return NULL;
9922}
9923
9924/* There is no need to cow as removing empty parts doesn't change
9925 * the meaning of the set.
9926 */
9927__isl_give isl_map *isl_map_remove_empty_parts(__isl_take isl_map *map)
9928{
9929	int i;
9930
9931	if (!map)
9932		return NULL;
9933
9934	for (i = map->n - 1; i >= 0; --i)
9935		map = remove_if_empty(map, i);
9936
9937	return map;
9938}
9939
9940__isl_give isl_set *isl_set_remove_empty_parts(__isl_take isl_set *set)
9941{
9942	return set_from_map(isl_map_remove_empty_parts(set_to_map(set)));
9943}
9944
9945/* Create a binary relation that maps the shared initial "pos" dimensions
9946 * of "bset1" and "bset2" to the remaining dimensions of "bset1" and "bset2".
9947 */
9948static __isl_give isl_basic_map *join_initial(__isl_keep isl_basic_set *bset1,
9949	__isl_keep isl_basic_set *bset2, int pos)
9950{
9951	isl_basic_map *bmap1;
9952	isl_basic_map *bmap2;
9953
9954	bmap1 = isl_basic_map_from_range(isl_basic_set_copy(bset1));
9955	bmap2 = isl_basic_map_from_range(isl_basic_set_copy(bset2));
9956	bmap1 = isl_basic_map_move_dims(bmap1, isl_dim_in, 0,
9957					isl_dim_out, 0, pos);
9958	bmap2 = isl_basic_map_move_dims(bmap2, isl_dim_in, 0,
9959					isl_dim_out, 0, pos);
9960	return isl_basic_map_range_product(bmap1, bmap2);
9961}
9962
9963/* Given two basic sets bset1 and bset2, compute the maximal difference
9964 * between the values of dimension pos in bset1 and those in bset2
9965 * for any common value of the parameters and dimensions preceding pos.
9966 */
9967static enum isl_lp_result basic_set_maximal_difference_at(
9968	__isl_keep isl_basic_set *bset1, __isl_keep isl_basic_set *bset2,
9969	int pos, isl_int *opt)
9970{
9971	isl_basic_map *bmap1;
9972	struct isl_ctx *ctx;
9973	struct isl_vec *obj;
9974	isl_size total;
9975	isl_size nparam;
9976	isl_size dim1;
9977	enum isl_lp_result res;
9978
9979	nparam = isl_basic_set_dim(bset1, isl_dim_param);
9980	dim1 = isl_basic_set_dim(bset1, isl_dim_set);
9981	if (nparam < 0 || dim1 < 0 || !bset2)
9982		return isl_lp_error;
9983
9984	bmap1 = join_initial(bset1, bset2, pos);
9985	total = isl_basic_map_dim(bmap1, isl_dim_all);
9986	if (total < 0)
9987		return isl_lp_error;
9988
9989	ctx = bmap1->ctx;
9990	obj = isl_vec_alloc(ctx, 1 + total);
9991	if (!obj)
9992		goto error;
9993	isl_seq_clr(obj->block.data, 1 + total);
9994	isl_int_set_si(obj->block.data[1+nparam+pos], 1);
9995	isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1);
9996	res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
9997					opt, NULL, NULL);
9998	isl_basic_map_free(bmap1);
9999	isl_vec_free(obj);
10000	return res;
10001error:
10002	isl_basic_map_free(bmap1);
10003	return isl_lp_error;
10004}
10005
10006/* Given two _disjoint_ basic sets bset1 and bset2, check whether
10007 * for any common value of the parameters and dimensions preceding pos
10008 * in both basic sets, the values of dimension pos in bset1 are
10009 * smaller or larger than those in bset2.
10010 *
10011 * Returns
10012 *	 1 if bset1 follows bset2
10013 *	-1 if bset1 precedes bset2
10014 *	 0 if bset1 and bset2 are incomparable
10015 *	-2 if some error occurred.
10016 */
10017int isl_basic_set_compare_at(__isl_keep isl_basic_set *bset1,
10018	__isl_keep isl_basic_set *bset2, int pos)
10019{
10020	isl_int opt;
10021	enum isl_lp_result res;
10022	int cmp;
10023
10024	isl_int_init(opt);
10025
10026	res = basic_set_maximal_difference_at(bset1, bset2, pos, &opt);
10027
10028	if (res == isl_lp_empty)
10029		cmp = 0;
10030	else if ((res == isl_lp_ok && isl_int_is_pos(opt)) ||
10031		  res == isl_lp_unbounded)
10032		cmp = 1;
10033	else if (res == isl_lp_ok && isl_int_is_neg(opt))
10034		cmp = -1;
10035	else
10036		cmp = -2;
10037
10038	isl_int_clear(opt);
10039	return cmp;
10040}
10041
10042/* Given two basic sets bset1 and bset2, check whether
10043 * for any common value of the parameters and dimensions preceding pos
10044 * there is a value of dimension pos in bset1 that is larger
10045 * than a value of the same dimension in bset2.
10046 *
10047 * Return
10048 *	 1 if there exists such a pair
10049 *	 0 if there is no such pair, but there is a pair of equal values
10050 *	-1 otherwise
10051 *	-2 if some error occurred.
10052 */
10053int isl_basic_set_follows_at(__isl_keep isl_basic_set *bset1,
10054	__isl_keep isl_basic_set *bset2, int pos)
10055{
10056	isl_bool empty;
10057	isl_basic_map *bmap;
10058	isl_size dim1;
10059
10060	dim1 = isl_basic_set_dim(bset1, isl_dim_set);
10061	if (dim1 < 0)
10062		return -2;
10063	bmap = join_initial(bset1, bset2, pos);
10064	bmap = isl_basic_map_order_ge(bmap, isl_dim_out, 0,
10065					    isl_dim_out, dim1 - pos);
10066	empty = isl_basic_map_is_empty(bmap);
10067	if (empty < 0)
10068		goto error;
10069	if (empty) {
10070		isl_basic_map_free(bmap);
10071		return -1;
10072	}
10073	bmap = isl_basic_map_order_gt(bmap, isl_dim_out, 0,
10074					    isl_dim_out, dim1 - pos);
10075	empty = isl_basic_map_is_empty(bmap);
10076	if (empty < 0)
10077		goto error;
10078	isl_basic_map_free(bmap);
10079	if (empty)
10080		return 0;
10081	return 1;
10082error:
10083	isl_basic_map_free(bmap);
10084	return -2;
10085}
10086
10087/* Given two sets set1 and set2, check whether
10088 * for any common value of the parameters and dimensions preceding pos
10089 * there is a value of dimension pos in set1 that is larger
10090 * than a value of the same dimension in set2.
10091 *
10092 * Return
10093 *	 1 if there exists such a pair
10094 *	 0 if there is no such pair, but there is a pair of equal values
10095 *	-1 otherwise
10096 *	-2 if some error occurred.
10097 */
10098int isl_set_follows_at(__isl_keep isl_set *set1,
10099	__isl_keep isl_set *set2, int pos)
10100{
10101	int i, j;
10102	int follows = -1;
10103
10104	if (!set1 || !set2)
10105		return -2;
10106
10107	for (i = 0; i < set1->n; ++i)
10108		for (j = 0; j < set2->n; ++j) {
10109			int f;
10110			f = isl_basic_set_follows_at(set1->p[i], set2->p[j], pos);
10111			if (f == 1 || f == -2)
10112				return f;
10113			if (f > follows)
10114				follows = f;
10115		}
10116
10117	return follows;
10118}
10119
10120static isl_bool isl_basic_map_plain_has_fixed_var(
10121	__isl_keep isl_basic_map *bmap, unsigned pos, isl_int *val)
10122{
10123	int i;
10124	int d;
10125	isl_size total;
10126
10127	total = isl_basic_map_dim(bmap, isl_dim_all);
10128	if (total < 0)
10129		return isl_bool_error;
10130	for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
10131		for (; d+1 > pos; --d)
10132			if (!isl_int_is_zero(bmap->eq[i][1+d]))
10133				break;
10134		if (d != pos)
10135			continue;
10136		if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
10137			return isl_bool_false;
10138		if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
10139			return isl_bool_false;
10140		if (!isl_int_is_one(bmap->eq[i][1+d]))
10141			return isl_bool_false;
10142		if (val)
10143			isl_int_neg(*val, bmap->eq[i][0]);
10144		return isl_bool_true;
10145	}
10146	return isl_bool_false;
10147}
10148
10149static isl_bool isl_map_plain_has_fixed_var(__isl_keep isl_map *map,
10150	unsigned pos, isl_int *val)
10151{
10152	int i;
10153	isl_int v;
10154	isl_int tmp;
10155	isl_bool fixed;
10156
10157	if (!map)
10158		return isl_bool_error;
10159	if (map->n == 0)
10160		return isl_bool_false;
10161	if (map->n == 1)
10162		return isl_basic_map_plain_has_fixed_var(map->p[0], pos, val);
10163	isl_int_init(v);
10164	isl_int_init(tmp);
10165	fixed = isl_basic_map_plain_has_fixed_var(map->p[0], pos, &v);
10166	for (i = 1; fixed == isl_bool_true && i < map->n; ++i) {
10167		fixed = isl_basic_map_plain_has_fixed_var(map->p[i], pos, &tmp);
10168		if (fixed == isl_bool_true && isl_int_ne(tmp, v))
10169			fixed = isl_bool_false;
10170	}
10171	if (val)
10172		isl_int_set(*val, v);
10173	isl_int_clear(tmp);
10174	isl_int_clear(v);
10175	return fixed;
10176}
10177
10178static isl_bool isl_basic_set_plain_has_fixed_var(
10179	__isl_keep isl_basic_set *bset, unsigned pos, isl_int *val)
10180{
10181	return isl_basic_map_plain_has_fixed_var(bset_to_bmap(bset),
10182						pos, val);
10183}
10184
10185isl_bool isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
10186	enum isl_dim_type type, unsigned pos, isl_int *val)
10187{
10188	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
10189		return isl_bool_error;
10190	return isl_basic_map_plain_has_fixed_var(bmap,
10191		isl_basic_map_offset(bmap, type) - 1 + pos, val);
10192}
10193
10194/* If "bmap" obviously lies on a hyperplane where the given dimension
10195 * has a fixed value, then return that value.
10196 * Otherwise return NaN.
10197 */
10198__isl_give isl_val *isl_basic_map_plain_get_val_if_fixed(
10199	__isl_keep isl_basic_map *bmap,
10200	enum isl_dim_type type, unsigned pos)
10201{
10202	isl_ctx *ctx;
10203	isl_val *v;
10204	isl_bool fixed;
10205
10206	if (!bmap)
10207		return NULL;
10208	ctx = isl_basic_map_get_ctx(bmap);
10209	v = isl_val_alloc(ctx);
10210	if (!v)
10211		return NULL;
10212	fixed = isl_basic_map_plain_is_fixed(bmap, type, pos, &v->n);
10213	if (fixed < 0)
10214		return isl_val_free(v);
10215	if (fixed) {
10216		isl_int_set_si(v->d, 1);
10217		return v;
10218	}
10219	isl_val_free(v);
10220	return isl_val_nan(ctx);
10221}
10222
10223isl_bool isl_map_plain_is_fixed(__isl_keep isl_map *map,
10224	enum isl_dim_type type, unsigned pos, isl_int *val)
10225{
10226	if (isl_map_check_range(map, type, pos, 1) < 0)
10227		return isl_bool_error;
10228	return isl_map_plain_has_fixed_var(map,
10229		map_offset(map, type) - 1 + pos, val);
10230}
10231
10232/* If "map" obviously lies on a hyperplane where the given dimension
10233 * has a fixed value, then return that value.
10234 * Otherwise return NaN.
10235 */
10236__isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map,
10237	enum isl_dim_type type, unsigned pos)
10238{
10239	isl_ctx *ctx;
10240	isl_val *v;
10241	isl_bool fixed;
10242
10243	if (!map)
10244		return NULL;
10245	ctx = isl_map_get_ctx(map);
10246	v = isl_val_alloc(ctx);
10247	if (!v)
10248		return NULL;
10249	fixed = isl_map_plain_is_fixed(map, type, pos, &v->n);
10250	if (fixed < 0)
10251		return isl_val_free(v);
10252	if (fixed) {
10253		isl_int_set_si(v->d, 1);
10254		return v;
10255	}
10256	isl_val_free(v);
10257	return isl_val_nan(ctx);
10258}
10259
10260/* If "set" obviously lies on a hyperplane where the given dimension
10261 * has a fixed value, then return that value.
10262 * Otherwise return NaN.
10263 */
10264__isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_set *set,
10265	enum isl_dim_type type, unsigned pos)
10266{
10267	return isl_map_plain_get_val_if_fixed(set, type, pos);
10268}
10269
10270/* Return a sequence of values in the same space as "set"
10271 * that are equal to the corresponding set dimensions of "set"
10272 * for those set dimensions that obviously lie on a hyperplane
10273 * where the dimension has a fixed value.
10274 * The other elements are set to NaN.
10275 */
10276__isl_give isl_multi_val *isl_set_get_plain_multi_val_if_fixed(
10277	__isl_keep isl_set *set)
10278{
10279	int i;
10280	isl_size n;
10281	isl_space *space;
10282	isl_multi_val *mv;
10283
10284	space = isl_space_drop_all_params(isl_set_get_space(set));
10285	mv = isl_multi_val_alloc(space);
10286	n = isl_multi_val_size(mv);
10287	if (n < 0)
10288		return isl_multi_val_free(mv);
10289
10290	for (i = 0; i < n; ++i) {
10291		isl_val *v;
10292
10293		v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, i);
10294		mv = isl_multi_val_set_val(mv, i, v);
10295	}
10296
10297	return mv;
10298}
10299
10300/* Check if dimension dim has fixed value and if so and if val is not NULL,
10301 * then return this fixed value in *val.
10302 */
10303isl_bool isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset,
10304	unsigned dim, isl_int *val)
10305{
10306	isl_size nparam;
10307
10308	nparam = isl_basic_set_dim(bset, isl_dim_param);
10309	if (nparam < 0)
10310		return isl_bool_error;
10311	return isl_basic_set_plain_has_fixed_var(bset, nparam + dim, val);
10312}
10313
10314/* Return -1 if the constraint "c1" should be sorted before "c2"
10315 * and 1 if it should be sorted after "c2".
10316 * Return 0 if the two constraints are the same (up to the constant term).
10317 *
10318 * In particular, if a constraint involves later variables than another
10319 * then it is sorted after this other constraint.
10320 * uset_gist depends on constraints without existentially quantified
10321 * variables sorting first.
10322 *
10323 * For constraints that have the same latest variable, those
10324 * with the same coefficient for this latest variable (first in absolute value
10325 * and then in actual value) are grouped together.
10326 * This is useful for detecting pairs of constraints that can
10327 * be chained in their printed representation.
10328 *
10329 * Finally, within a group, constraints are sorted according to
10330 * their coefficients (excluding the constant term).
10331 */
10332static int sort_constraint_cmp(const void *p1, const void *p2, void *arg)
10333{
10334	isl_int **c1 = (isl_int **) p1;
10335	isl_int **c2 = (isl_int **) p2;
10336	int l1, l2;
10337	unsigned size = *(unsigned *) arg;
10338	int cmp;
10339
10340	l1 = isl_seq_last_non_zero(*c1 + 1, size);
10341	l2 = isl_seq_last_non_zero(*c2 + 1, size);
10342
10343	if (l1 != l2)
10344		return l1 - l2;
10345
10346	cmp = isl_int_abs_cmp((*c1)[1 + l1], (*c2)[1 + l1]);
10347	if (cmp != 0)
10348		return cmp;
10349	cmp = isl_int_cmp((*c1)[1 + l1], (*c2)[1 + l1]);
10350	if (cmp != 0)
10351		return -cmp;
10352
10353	return isl_seq_cmp(*c1 + 1, *c2 + 1, size);
10354}
10355
10356/* Return -1 if the constraint "c1" of "bmap" is sorted before "c2"
10357 * by isl_basic_map_sort_constraints, 1 if it is sorted after "c2"
10358 * and 0 if the two constraints are the same (up to the constant term).
10359 */
10360int isl_basic_map_constraint_cmp(__isl_keep isl_basic_map *bmap,
10361	isl_int *c1, isl_int *c2)
10362{
10363	isl_size total;
10364	unsigned size;
10365
10366	total = isl_basic_map_dim(bmap, isl_dim_all);
10367	if (total < 0)
10368		return -2;
10369	size = total;
10370	return sort_constraint_cmp(&c1, &c2, &size);
10371}
10372
10373__isl_give isl_basic_map *isl_basic_map_sort_constraints(
10374	__isl_take isl_basic_map *bmap)
10375{
10376	isl_size total;
10377	unsigned size;
10378
10379	if (!bmap)
10380		return NULL;
10381	if (bmap->n_ineq == 0)
10382		return bmap;
10383	if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_SORTED))
10384		return bmap;
10385	total = isl_basic_map_dim(bmap, isl_dim_all);
10386	if (total < 0)
10387		return isl_basic_map_free(bmap);
10388	size = total;
10389	if (isl_sort(bmap->ineq, bmap->n_ineq, sizeof(isl_int *),
10390		    &sort_constraint_cmp, &size) < 0)
10391		return isl_basic_map_free(bmap);
10392	ISL_F_SET(bmap, ISL_BASIC_MAP_SORTED);
10393	return bmap;
10394}
10395
10396__isl_give isl_basic_set *isl_basic_set_sort_constraints(
10397	__isl_take isl_basic_set *bset)
10398{
10399	isl_basic_map *bmap = bset_to_bmap(bset);
10400	return bset_from_bmap(isl_basic_map_sort_constraints(bmap));
10401}
10402
10403__isl_give isl_basic_map *isl_basic_map_normalize(
10404	__isl_take isl_basic_map *bmap)
10405{
10406	bmap = isl_basic_map_remove_redundancies(bmap);
10407	bmap = isl_basic_map_sort_constraints(bmap);
10408	return bmap;
10409}
10410int isl_basic_map_plain_cmp(__isl_keep isl_basic_map *bmap1,
10411	__isl_keep isl_basic_map *bmap2)
10412{
10413	int i, cmp;
10414	isl_size total;
10415	isl_space *space1, *space2;
10416
10417	if (!bmap1 || !bmap2)
10418		return -1;
10419
10420	if (bmap1 == bmap2)
10421		return 0;
10422	space1 = isl_basic_map_peek_space(bmap1);
10423	space2 = isl_basic_map_peek_space(bmap2);
10424	cmp = isl_space_cmp(space1, space2);
10425	if (cmp)
10426		return cmp;
10427	if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) !=
10428	    ISL_F_ISSET(bmap2, ISL_BASIC_MAP_RATIONAL))
10429		return ISL_F_ISSET(bmap1, ISL_BASIC_MAP_RATIONAL) ? -1 : 1;
10430	if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) &&
10431	    ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
10432		return 0;
10433	if (ISL_F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY))
10434		return 1;
10435	if (ISL_F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
10436		return -1;
10437	if (bmap1->n_eq != bmap2->n_eq)
10438		return bmap1->n_eq - bmap2->n_eq;
10439	if (bmap1->n_ineq != bmap2->n_ineq)
10440		return bmap1->n_ineq - bmap2->n_ineq;
10441	if (bmap1->n_div != bmap2->n_div)
10442		return bmap1->n_div - bmap2->n_div;
10443	total = isl_basic_map_dim(bmap1, isl_dim_all);
10444	if (total < 0)
10445		return -1;
10446	for (i = 0; i < bmap1->n_eq; ++i) {
10447		cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
10448		if (cmp)
10449			return cmp;
10450	}
10451	for (i = 0; i < bmap1->n_ineq; ++i) {
10452		cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
10453		if (cmp)
10454			return cmp;
10455	}
10456	for (i = 0; i < bmap1->n_div; ++i) {
10457		isl_bool unknown1, unknown2;
10458
10459		unknown1 = isl_basic_map_div_is_marked_unknown(bmap1, i);
10460		unknown2 = isl_basic_map_div_is_marked_unknown(bmap2, i);
10461		if (unknown1 < 0 || unknown2 < 0)
10462			return -1;
10463		if (unknown1 && unknown2)
10464			continue;
10465		if (unknown1)
10466			return 1;
10467		if (unknown2)
10468			return -1;
10469		cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
10470		if (cmp)
10471			return cmp;
10472	}
10473	return 0;
10474}
10475
10476int isl_basic_set_plain_cmp(__isl_keep isl_basic_set *bset1,
10477	__isl_keep isl_basic_set *bset2)
10478{
10479	return isl_basic_map_plain_cmp(bset1, bset2);
10480}
10481
10482int isl_set_plain_cmp(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
10483{
10484	int i, cmp;
10485
10486	if (set1 == set2)
10487		return 0;
10488	if (set1->n != set2->n)
10489		return set1->n - set2->n;
10490
10491	for (i = 0; i < set1->n; ++i) {
10492		cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]);
10493		if (cmp)
10494			return cmp;
10495	}
10496
10497	return 0;
10498}
10499
10500isl_bool isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1,
10501	__isl_keep isl_basic_map *bmap2)
10502{
10503	if (!bmap1 || !bmap2)
10504		return isl_bool_error;
10505	return isl_basic_map_plain_cmp(bmap1, bmap2) == 0;
10506}
10507
10508isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1,
10509	__isl_keep isl_basic_set *bset2)
10510{
10511	return isl_basic_map_plain_is_equal(bset_to_bmap(bset1),
10512					    bset_to_bmap(bset2));
10513}
10514
10515static int qsort_bmap_cmp(const void *p1, const void *p2)
10516{
10517	isl_basic_map *bmap1 = *(isl_basic_map **) p1;
10518	isl_basic_map *bmap2 = *(isl_basic_map **) p2;
10519
10520	return isl_basic_map_plain_cmp(bmap1, bmap2);
10521}
10522
10523/* Sort the basic maps of "map" and remove duplicate basic maps.
10524 *
10525 * While removing basic maps, we make sure that the basic maps remain
10526 * sorted because isl_map_normalize expects the basic maps of the result
10527 * to be sorted.
10528 */
10529static __isl_give isl_map *sort_and_remove_duplicates(__isl_take isl_map *map)
10530{
10531	int i, j;
10532
10533	map = isl_map_remove_empty_parts(map);
10534	if (!map)
10535		return NULL;
10536	qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
10537	for (i = map->n - 1; i >= 1; --i) {
10538		if (!isl_basic_map_plain_is_equal(map->p[i - 1], map->p[i]))
10539			continue;
10540		isl_basic_map_free(map->p[i-1]);
10541		for (j = i; j < map->n; ++j)
10542			map->p[j - 1] = map->p[j];
10543		map->n--;
10544	}
10545
10546	return map;
10547}
10548
10549/* Remove obvious duplicates among the basic maps of "map".
10550 *
10551 * Unlike isl_map_normalize, this function does not remove redundant
10552 * constraints and only removes duplicates that have exactly the same
10553 * constraints in the input.  It does sort the constraints and
10554 * the basic maps to ease the detection of duplicates.
10555 *
10556 * If "map" has already been normalized or if the basic maps are
10557 * disjoint, then there can be no duplicates.
10558 */
10559__isl_give isl_map *isl_map_remove_obvious_duplicates(__isl_take isl_map *map)
10560{
10561	int i;
10562	isl_basic_map *bmap;
10563
10564	if (!map)
10565		return NULL;
10566	if (map->n <= 1)
10567		return map;
10568	if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED | ISL_MAP_DISJOINT))
10569		return map;
10570	for (i = 0; i < map->n; ++i) {
10571		bmap = isl_basic_map_copy(map->p[i]);
10572		bmap = isl_basic_map_sort_constraints(bmap);
10573		if (!bmap)
10574			return isl_map_free(map);
10575		isl_basic_map_free(map->p[i]);
10576		map->p[i] = bmap;
10577	}
10578
10579	map = sort_and_remove_duplicates(map);
10580	return map;
10581}
10582
10583/* We normalize in place, but if anything goes wrong we need
10584 * to return NULL, so we need to make sure we don't change the
10585 * meaning of any possible other copies of map.
10586 */
10587__isl_give isl_map *isl_map_normalize(__isl_take isl_map *map)
10588{
10589	int i;
10590	struct isl_basic_map *bmap;
10591
10592	if (!map)
10593		return NULL;
10594	if (ISL_F_ISSET(map, ISL_MAP_NORMALIZED))
10595		return map;
10596	for (i = 0; i < map->n; ++i) {
10597		bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
10598		if (!bmap)
10599			goto error;
10600		isl_basic_map_free(map->p[i]);
10601		map->p[i] = bmap;
10602	}
10603
10604	map = sort_and_remove_duplicates(map);
10605	if (map)
10606		ISL_F_SET(map, ISL_MAP_NORMALIZED);
10607	return map;
10608error:
10609	isl_map_free(map);
10610	return NULL;
10611}
10612
10613__isl_give isl_set *isl_set_normalize(__isl_take isl_set *set)
10614{
10615	return set_from_map(isl_map_normalize(set_to_map(set)));
10616}
10617
10618isl_bool isl_map_plain_is_equal(__isl_keep isl_map *map1,
10619	__isl_keep isl_map *map2)
10620{
10621	int i;
10622	isl_bool equal;
10623
10624	if (!map1 || !map2)
10625		return isl_bool_error;
10626
10627	if (map1 == map2)
10628		return isl_bool_true;
10629	equal = isl_map_has_equal_space(map1, map2);
10630	if (equal < 0 || !equal)
10631		return equal;
10632
10633	map1 = isl_map_copy(map1);
10634	map2 = isl_map_copy(map2);
10635	map1 = isl_map_normalize(map1);
10636	map2 = isl_map_normalize(map2);
10637	if (!map1 || !map2)
10638		goto error;
10639	equal = map1->n == map2->n;
10640	for (i = 0; equal && i < map1->n; ++i) {
10641		equal = isl_basic_map_plain_is_equal(map1->p[i], map2->p[i]);
10642		if (equal < 0)
10643			goto error;
10644	}
10645	isl_map_free(map1);
10646	isl_map_free(map2);
10647	return equal;
10648error:
10649	isl_map_free(map1);
10650	isl_map_free(map2);
10651	return isl_bool_error;
10652}
10653
10654isl_bool isl_set_plain_is_equal(__isl_keep isl_set *set1,
10655	__isl_keep isl_set *set2)
10656{
10657	return isl_map_plain_is_equal(set_to_map(set1), set_to_map(set2));
10658}
10659
10660/* Return the basic maps in "map" as a list.
10661 */
10662__isl_give isl_basic_map_list *isl_map_get_basic_map_list(
10663	__isl_keep isl_map *map)
10664{
10665	int i;
10666	isl_ctx *ctx;
10667	isl_basic_map_list *list;
10668
10669	if (!map)
10670		return NULL;
10671	ctx = isl_map_get_ctx(map);
10672	list = isl_basic_map_list_alloc(ctx, map->n);
10673
10674	for (i = 0; i < map->n; ++i) {
10675		isl_basic_map *bmap;
10676
10677		bmap = isl_basic_map_copy(map->p[i]);
10678		list = isl_basic_map_list_add(list, bmap);
10679	}
10680
10681	return list;
10682}
10683
10684/* Return the intersection of the elements in the non-empty list "list".
10685 * All elements are assumed to live in the same space.
10686 */
10687__isl_give isl_basic_map *isl_basic_map_list_intersect(
10688	__isl_take isl_basic_map_list *list)
10689{
10690	int i;
10691	isl_size n;
10692	isl_basic_map *bmap;
10693
10694	n = isl_basic_map_list_n_basic_map(list);
10695	if (n < 0)
10696		goto error;
10697	if (n < 1)
10698		isl_die(isl_basic_map_list_get_ctx(list), isl_error_invalid,
10699			"expecting non-empty list", goto error);
10700
10701	bmap = isl_basic_map_list_get_basic_map(list, 0);
10702	for (i = 1; i < n; ++i) {
10703		isl_basic_map *bmap_i;
10704
10705		bmap_i = isl_basic_map_list_get_basic_map(list, i);
10706		bmap = isl_basic_map_intersect(bmap, bmap_i);
10707	}
10708
10709	isl_basic_map_list_free(list);
10710	return bmap;
10711error:
10712	isl_basic_map_list_free(list);
10713	return NULL;
10714}
10715
10716/* Return the intersection of the elements in the non-empty list "list".
10717 * All elements are assumed to live in the same space.
10718 */
10719__isl_give isl_basic_set *isl_basic_set_list_intersect(
10720	__isl_take isl_basic_set_list *list)
10721{
10722	return isl_basic_map_list_intersect(list);
10723}
10724
10725/* Return the union of the elements of "list".
10726 * The list is required to have at least one element.
10727 */
10728__isl_give isl_set *isl_basic_set_list_union(
10729	__isl_take isl_basic_set_list *list)
10730{
10731	int i;
10732	isl_size n;
10733	isl_space *space;
10734	isl_basic_set *bset;
10735	isl_set *set;
10736
10737	n = isl_basic_set_list_n_basic_set(list);
10738	if (n < 0)
10739		goto error;
10740	if (n < 1)
10741		isl_die(isl_basic_set_list_get_ctx(list), isl_error_invalid,
10742			"expecting non-empty list", goto error);
10743
10744	bset = isl_basic_set_list_get_basic_set(list, 0);
10745	space = isl_basic_set_get_space(bset);
10746	isl_basic_set_free(bset);
10747
10748	set = isl_set_alloc_space(space, n, 0);
10749	for (i = 0; i < n; ++i) {
10750		bset = isl_basic_set_list_get_basic_set(list, i);
10751		set = isl_set_add_basic_set(set, bset);
10752	}
10753
10754	isl_basic_set_list_free(list);
10755	return set;
10756error:
10757	isl_basic_set_list_free(list);
10758	return NULL;
10759}
10760
10761/* Return the union of the elements in the non-empty list "list".
10762 * All elements are assumed to live in the same space.
10763 */
10764__isl_give isl_set *isl_set_list_union(__isl_take isl_set_list *list)
10765{
10766	int i;
10767	isl_size n;
10768	isl_set *set;
10769
10770	n = isl_set_list_n_set(list);
10771	if (n < 0)
10772		goto error;
10773	if (n < 1)
10774		isl_die(isl_set_list_get_ctx(list), isl_error_invalid,
10775			"expecting non-empty list", goto error);
10776
10777	set = isl_set_list_get_set(list, 0);
10778	for (i = 1; i < n; ++i) {
10779		isl_set *set_i;
10780
10781		set_i = isl_set_list_get_set(list, i);
10782		set = isl_set_union(set, set_i);
10783	}
10784
10785	isl_set_list_free(list);
10786	return set;
10787error:
10788	isl_set_list_free(list);
10789	return NULL;
10790}
10791
10792__isl_give isl_basic_map *isl_basic_map_product(
10793	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10794{
10795	isl_space *space_result = NULL;
10796	struct isl_basic_map *bmap;
10797	unsigned in1, in2, out1, out2, nparam, total, pos;
10798	struct isl_dim_map *dim_map1, *dim_map2;
10799
10800	if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
10801		goto error;
10802	space_result = isl_space_product(isl_space_copy(bmap1->dim),
10803						   isl_space_copy(bmap2->dim));
10804
10805	in1 = isl_basic_map_dim(bmap1, isl_dim_in);
10806	in2 = isl_basic_map_dim(bmap2, isl_dim_in);
10807	out1 = isl_basic_map_dim(bmap1, isl_dim_out);
10808	out2 = isl_basic_map_dim(bmap2, isl_dim_out);
10809	nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10810
10811	total = nparam + in1 + in2 + out1 + out2 + bmap1->n_div + bmap2->n_div;
10812	dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10813	dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10814	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10815	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10816	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10817	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
10818	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
10819	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
10820	isl_dim_map_div(dim_map1, bmap1, pos += out2);
10821	isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10822
10823	bmap = isl_basic_map_alloc_space(space_result,
10824			bmap1->n_div + bmap2->n_div,
10825			bmap1->n_eq + bmap2->n_eq,
10826			bmap1->n_ineq + bmap2->n_ineq);
10827	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10828	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10829	bmap = isl_basic_map_simplify(bmap);
10830	return isl_basic_map_finalize(bmap);
10831error:
10832	isl_basic_map_free(bmap1);
10833	isl_basic_map_free(bmap2);
10834	return NULL;
10835}
10836
10837__isl_give isl_basic_map *isl_basic_map_flat_product(
10838	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10839{
10840	isl_basic_map *prod;
10841
10842	prod = isl_basic_map_product(bmap1, bmap2);
10843	prod = isl_basic_map_flatten(prod);
10844	return prod;
10845}
10846
10847__isl_give isl_basic_set *isl_basic_set_flat_product(
10848	__isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
10849{
10850	return isl_basic_map_flat_range_product(bset1, bset2);
10851}
10852
10853__isl_give isl_basic_map *isl_basic_map_domain_product(
10854	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10855{
10856	isl_space *space1, *space2;
10857	isl_space *space_result = NULL;
10858	isl_basic_map *bmap;
10859	isl_size in1, in2, out, nparam;
10860	unsigned total, pos;
10861	struct isl_dim_map *dim_map1, *dim_map2;
10862
10863	in1 = isl_basic_map_dim(bmap1, isl_dim_in);
10864	in2 = isl_basic_map_dim(bmap2, isl_dim_in);
10865	out = isl_basic_map_dim(bmap1, isl_dim_out);
10866	nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10867	if (in1 < 0 || in2 < 0 || out < 0 || nparam < 0)
10868		goto error;
10869
10870	space1 = isl_basic_map_get_space(bmap1);
10871	space2 = isl_basic_map_get_space(bmap2);
10872	space_result = isl_space_domain_product(space1, space2);
10873
10874	total = nparam + in1 + in2 + out + bmap1->n_div + bmap2->n_div;
10875	dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10876	dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10877	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10878	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10879	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10880	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos += in1);
10881	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in2);
10882	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos);
10883	isl_dim_map_div(dim_map1, bmap1, pos += out);
10884	isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10885
10886	bmap = isl_basic_map_alloc_space(space_result,
10887			bmap1->n_div + bmap2->n_div,
10888			bmap1->n_eq + bmap2->n_eq,
10889			bmap1->n_ineq + bmap2->n_ineq);
10890	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10891	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10892	bmap = isl_basic_map_simplify(bmap);
10893	return isl_basic_map_finalize(bmap);
10894error:
10895	isl_basic_map_free(bmap1);
10896	isl_basic_map_free(bmap2);
10897	return NULL;
10898}
10899
10900__isl_give isl_basic_map *isl_basic_map_range_product(
10901	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10902{
10903	isl_bool rational;
10904	isl_space *space_result = NULL;
10905	isl_basic_map *bmap;
10906	isl_size in, out1, out2, nparam;
10907	unsigned total, pos;
10908	struct isl_dim_map *dim_map1, *dim_map2;
10909
10910	rational = isl_basic_map_is_rational(bmap1);
10911	if (rational >= 0 && rational)
10912		rational = isl_basic_map_is_rational(bmap2);
10913	in = isl_basic_map_dim(bmap1, isl_dim_in);
10914	out1 = isl_basic_map_dim(bmap1, isl_dim_out);
10915	out2 = isl_basic_map_dim(bmap2, isl_dim_out);
10916	nparam = isl_basic_map_dim(bmap1, isl_dim_param);
10917	if (in < 0 || out1 < 0 || out2 < 0 || nparam < 0 || rational < 0)
10918		goto error;
10919
10920	if (isl_basic_map_check_equal_params(bmap1, bmap2) < 0)
10921		goto error;
10922
10923	space_result = isl_space_range_product(isl_space_copy(bmap1->dim),
10924					   isl_space_copy(bmap2->dim));
10925
10926	total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
10927	dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
10928	dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
10929	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
10930	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
10931	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
10932	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
10933	isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
10934	isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
10935	isl_dim_map_div(dim_map1, bmap1, pos += out2);
10936	isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
10937
10938	bmap = isl_basic_map_alloc_space(space_result,
10939			bmap1->n_div + bmap2->n_div,
10940			bmap1->n_eq + bmap2->n_eq,
10941			bmap1->n_ineq + bmap2->n_ineq);
10942	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap1, dim_map1);
10943	bmap = isl_basic_map_add_constraints_dim_map(bmap, bmap2, dim_map2);
10944	if (rational)
10945		bmap = isl_basic_map_set_rational(bmap);
10946	bmap = isl_basic_map_simplify(bmap);
10947	return isl_basic_map_finalize(bmap);
10948error:
10949	isl_basic_map_free(bmap1);
10950	isl_basic_map_free(bmap2);
10951	return NULL;
10952}
10953
10954__isl_give isl_basic_map *isl_basic_map_flat_range_product(
10955	__isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
10956{
10957	isl_basic_map *prod;
10958
10959	prod = isl_basic_map_range_product(bmap1, bmap2);
10960	prod = isl_basic_map_flatten_range(prod);
10961	return prod;
10962}
10963
10964/* Apply "basic_map_product" to each pair of basic maps in "map1" and "map2"
10965 * and collect the results.
10966 * The result live in the space obtained by calling "space_product"
10967 * on the spaces of "map1" and "map2".
10968 * If "remove_duplicates" is set then the result may contain duplicates
10969 * (even if the inputs do not) and so we try and remove the obvious
10970 * duplicates.
10971 */
10972static __isl_give isl_map *map_product(__isl_take isl_map *map1,
10973	__isl_take isl_map *map2,
10974	__isl_give isl_space *(*space_product)(__isl_take isl_space *left,
10975					   __isl_take isl_space *right),
10976	__isl_give isl_basic_map *(*basic_map_product)(
10977		__isl_take isl_basic_map *left,
10978		__isl_take isl_basic_map *right),
10979	int remove_duplicates)
10980{
10981	unsigned flags = 0;
10982	struct isl_map *result;
10983	int i, j;
10984	isl_bool m;
10985
10986	m = isl_map_has_equal_params(map1, map2);
10987	if (m < 0)
10988		goto error;
10989	if (!m)
10990		isl_die(isl_map_get_ctx(map1), isl_error_invalid,
10991			"parameters don't match", goto error);
10992
10993	if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
10994	    ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
10995		ISL_FL_SET(flags, ISL_MAP_DISJOINT);
10996
10997	result = isl_map_alloc_space(space_product(isl_space_copy(map1->dim),
10998					       isl_space_copy(map2->dim)),
10999				map1->n * map2->n, flags);
11000	if (!result)
11001		goto error;
11002	for (i = 0; i < map1->n; ++i)
11003		for (j = 0; j < map2->n; ++j) {
11004			struct isl_basic_map *part;
11005			part = basic_map_product(isl_basic_map_copy(map1->p[i]),
11006						 isl_basic_map_copy(map2->p[j]));
11007			if (isl_basic_map_is_empty(part))
11008				isl_basic_map_free(part);
11009			else
11010				result = isl_map_add_basic_map(result, part);
11011			if (!result)
11012				goto error;
11013		}
11014	if (remove_duplicates)
11015		result = isl_map_remove_obvious_duplicates(result);
11016	isl_map_free(map1);
11017	isl_map_free(map2);
11018	return result;
11019error:
11020	isl_map_free(map1);
11021	isl_map_free(map2);
11022	return NULL;
11023}
11024
11025/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
11026 */
11027__isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
11028	__isl_take isl_map *map2)
11029{
11030	isl_map_align_params_bin(&map1, &map2);
11031	return map_product(map1, map2, &isl_space_product,
11032			&isl_basic_map_product, 0);
11033}
11034
11035/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
11036 */
11037__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
11038	__isl_take isl_map *map2)
11039{
11040	isl_map *prod;
11041
11042	prod = isl_map_product(map1, map2);
11043	prod = isl_map_flatten(prod);
11044	return prod;
11045}
11046
11047/* Given two set A and B, construct its Cartesian product A x B.
11048 */
11049__isl_give isl_set *isl_set_product(__isl_take isl_set *set1,
11050	__isl_take isl_set *set2)
11051{
11052	return isl_map_range_product(set1, set2);
11053}
11054
11055__isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
11056	__isl_take isl_set *set2)
11057{
11058	return isl_map_flat_range_product(set1, set2);
11059}
11060
11061/* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
11062 */
11063__isl_give isl_map *isl_map_domain_product(__isl_take isl_map *map1,
11064	__isl_take isl_map *map2)
11065{
11066	isl_map_align_params_bin(&map1, &map2);
11067	return map_product(map1, map2, &isl_space_domain_product,
11068				&isl_basic_map_domain_product, 1);
11069}
11070
11071/* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
11072 */
11073__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
11074	__isl_take isl_map *map2)
11075{
11076	isl_map_align_params_bin(&map1, &map2);
11077	return map_product(map1, map2, &isl_space_range_product,
11078				&isl_basic_map_range_product, 1);
11079}
11080
11081/* Given a map of the form [A -> B] -> [C -> D], return the map A -> C.
11082 */
11083__isl_give isl_map *isl_map_factor_domain(__isl_take isl_map *map)
11084{
11085	isl_space *space;
11086	isl_size total1, keep1, total2, keep2;
11087
11088	total1 = isl_map_dim(map, isl_dim_in);
11089	total2 = isl_map_dim(map, isl_dim_out);
11090	if (total1 < 0 || total2 < 0)
11091		return isl_map_free(map);
11092	if (!isl_space_domain_is_wrapping(map->dim) ||
11093	    !isl_space_range_is_wrapping(map->dim))
11094		isl_die(isl_map_get_ctx(map), isl_error_invalid,
11095			"not a product", return isl_map_free(map));
11096
11097	space = isl_map_get_space(map);
11098	space = isl_space_factor_domain(space);
11099	keep1 = isl_space_dim(space, isl_dim_in);
11100	keep2 = isl_space_dim(space, isl_dim_out);
11101	if (keep1 < 0 || keep2 < 0)
11102		map = isl_map_free(map);
11103	map = isl_map_project_out(map, isl_dim_in, keep1, total1 - keep1);
11104	map = isl_map_project_out(map, isl_dim_out, keep2, total2 - keep2);
11105	map = isl_map_reset_space(map, space);
11106
11107	return map;
11108}
11109
11110/* Given a map of the form [A -> B] -> [C -> D], return the map B -> D.
11111 */
11112__isl_give isl_map *isl_map_factor_range(__isl_take isl_map *map)
11113{
11114	isl_space *space;
11115	isl_size total1, keep1, total2, keep2;
11116
11117	total1 = isl_map_dim(map, isl_dim_in);
11118	total2 = isl_map_dim(map, isl_dim_out);
11119	if (total1 < 0 || total2 < 0)
11120		return isl_map_free(map);
11121	if (!isl_space_domain_is_wrapping(map->dim) ||
11122	    !isl_space_range_is_wrapping(map->dim))
11123		isl_die(isl_map_get_ctx(map), isl_error_invalid,
11124			"not a product", return isl_map_free(map));
11125
11126	space = isl_map_get_space(map);
11127	space = isl_space_factor_range(space);
11128	keep1 = isl_space_dim(space, isl_dim_in);
11129	keep2 = isl_space_dim(space, isl_dim_out);
11130	if (keep1 < 0 || keep2 < 0)
11131		map = isl_map_free(map);
11132	map = isl_map_project_out(map, isl_dim_in, 0, total1 - keep1);
11133	map = isl_map_project_out(map, isl_dim_out, 0, total2 - keep2);
11134	map = isl_map_reset_space(map, space);
11135
11136	return map;
11137}
11138
11139/* Given a map of the form [A -> B] -> C, return the map A -> C.
11140 */
11141__isl_give isl_map *isl_map_domain_factor_domain(__isl_take isl_map *map)
11142{
11143	isl_space *space;
11144	isl_size total, keep;
11145
11146	total = isl_map_dim(map, isl_dim_in);
11147	if (total < 0)
11148		return isl_map_free(map);
11149	if (!isl_space_domain_is_wrapping(map->dim))
11150		isl_die(isl_map_get_ctx(map), isl_error_invalid,
11151			"domain is not a product", return isl_map_free(map));
11152
11153	space = isl_map_get_space(map);
11154	space = isl_space_domain_factor_domain(space);
11155	keep = isl_space_dim(space, isl_dim_in);
11156	if (keep < 0)
11157		map = isl_map_free(map);
11158	map = isl_map_project_out(map, isl_dim_in, keep, total - keep);
11159	map = isl_map_reset_space(map, space);
11160
11161	return map;
11162}
11163
11164/* Given a map of the form [A -> B] -> C, return the map B -> C.
11165 */
11166__isl_give isl_map *isl_map_domain_factor_range(__isl_take isl_map *map)
11167{
11168	isl_space *space;
11169	isl_size total, keep;
11170
11171	total = isl_map_dim(map, isl_dim_in);
11172	if (total < 0)
11173		return isl_map_free(map);
11174	if (!isl_space_domain_is_wrapping(map->dim))
11175		isl_die(isl_map_get_ctx(map), isl_error_invalid,
11176			"domain is not a product", return isl_map_free(map));
11177
11178	space = isl_map_get_space(map);
11179	space = isl_space_domain_factor_range(space);
11180	keep = isl_space_dim(space, isl_dim_in);
11181	if (keep < 0)
11182		map = isl_map_free(map);
11183	map = isl_map_project_out(map, isl_dim_in, 0, total - keep);
11184	map = isl_map_reset_space(map, space);
11185
11186	return map;
11187}
11188
11189/* Given a map A -> [B -> C], extract the map A -> B.
11190 */
11191__isl_give isl_map *isl_map_range_factor_domain(__isl_take isl_map *map)
11192{
11193	isl_space *space;
11194	isl_size total, keep;
11195
11196	total = isl_map_dim(map, isl_dim_out);
11197	if (total < 0)
11198		return isl_map_free(map);
11199	if (!isl_space_range_is_wrapping(map->dim))
11200		isl_die(isl_map_get_ctx(map), isl_error_invalid,
11201			"range is not a product", return isl_map_free(map));
11202
11203	space = isl_map_get_space(map);
11204	space = isl_space_range_factor_domain(space);
11205	keep = isl_space_dim(space, isl_dim_out);
11206	if (keep < 0)
11207		map = isl_map_free(map);
11208	map = isl_map_project_out(map, isl_dim_out, keep, total - keep);
11209	map = isl_map_reset_space(map, space);
11210
11211	return map;
11212}
11213
11214/* Given a map A -> [B -> C], extract the map A -> C.
11215 */
11216__isl_give isl_map *isl_map_range_factor_range(__isl_take isl_map *map)
11217{
11218	isl_space *space;
11219	isl_size total, keep;
11220
11221	total = isl_map_dim(map, isl_dim_out);
11222	if (total < 0)
11223		return isl_map_free(map);
11224	if (!isl_space_range_is_wrapping(map->dim))
11225		isl_die(isl_map_get_ctx(map), isl_error_invalid,
11226			"range is not a product", return isl_map_free(map));
11227
11228	space = isl_map_get_space(map);
11229	space = isl_space_range_factor_range(space);
11230	keep = isl_space_dim(space, isl_dim_out);
11231	if (keep < 0)
11232		map = isl_map_free(map);
11233	map = isl_map_project_out(map, isl_dim_out, 0, total - keep);
11234	map = isl_map_reset_space(map, space);
11235
11236	return map;
11237}
11238
11239/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D)
11240 */
11241__isl_give isl_map *isl_map_flat_domain_product(__isl_take isl_map *map1,
11242	__isl_take isl_map *map2)
11243{
11244	isl_map *prod;
11245
11246	prod = isl_map_domain_product(map1, map2);
11247	prod = isl_map_flatten_domain(prod);
11248	return prod;
11249}
11250
11251/* Given two maps A -> B and C -> D, construct a map (A * C) -> (B, D)
11252 */
11253__isl_give isl_map *isl_map_flat_range_product(__isl_take isl_map *map1,
11254	__isl_take isl_map *map2)
11255{
11256	isl_map *prod;
11257
11258	prod = isl_map_range_product(map1, map2);
11259	prod = isl_map_flatten_range(prod);
11260	return prod;
11261}
11262
11263uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
11264{
11265	int i;
11266	uint32_t hash = isl_hash_init();
11267	isl_size total;
11268
11269	if (!bmap)
11270		return 0;
11271	bmap = isl_basic_map_copy(bmap);
11272	bmap = isl_basic_map_normalize(bmap);
11273	total = isl_basic_map_dim(bmap, isl_dim_all);
11274	if (total < 0)
11275		return 0;
11276	isl_hash_byte(hash, bmap->n_eq & 0xFF);
11277	for (i = 0; i < bmap->n_eq; ++i) {
11278		uint32_t c_hash;
11279		c_hash = isl_seq_get_hash(bmap->eq[i], 1 + total);
11280		isl_hash_hash(hash, c_hash);
11281	}
11282	isl_hash_byte(hash, bmap->n_ineq & 0xFF);
11283	for (i = 0; i < bmap->n_ineq; ++i) {
11284		uint32_t c_hash;
11285		c_hash = isl_seq_get_hash(bmap->ineq[i], 1 + total);
11286		isl_hash_hash(hash, c_hash);
11287	}
11288	isl_hash_byte(hash, bmap->n_div & 0xFF);
11289	for (i = 0; i < bmap->n_div; ++i) {
11290		uint32_t c_hash;
11291		if (isl_int_is_zero(bmap->div[i][0]))
11292			continue;
11293		isl_hash_byte(hash, i & 0xFF);
11294		c_hash = isl_seq_get_hash(bmap->div[i], 1 + 1 + total);
11295		isl_hash_hash(hash, c_hash);
11296	}
11297	isl_basic_map_free(bmap);
11298	return hash;
11299}
11300
11301uint32_t isl_basic_set_get_hash(__isl_keep isl_basic_set *bset)
11302{
11303	return isl_basic_map_get_hash(bset_to_bmap(bset));
11304}
11305
11306uint32_t isl_map_get_hash(__isl_keep isl_map *map)
11307{
11308	int i;
11309	uint32_t hash;
11310
11311	if (!map)
11312		return 0;
11313	map = isl_map_copy(map);
11314	map = isl_map_normalize(map);
11315	if (!map)
11316		return 0;
11317
11318	hash = isl_hash_init();
11319	for (i = 0; i < map->n; ++i) {
11320		uint32_t bmap_hash;
11321		bmap_hash = isl_basic_map_get_hash(map->p[i]);
11322		isl_hash_hash(hash, bmap_hash);
11323	}
11324
11325	isl_map_free(map);
11326
11327	return hash;
11328}
11329
11330uint32_t isl_set_get_hash(__isl_keep isl_set *set)
11331{
11332	return isl_map_get_hash(set_to_map(set));
11333}
11334
11335/* Return the number of basic maps in the (current) representation of "map".
11336 */
11337isl_size isl_map_n_basic_map(__isl_keep isl_map *map)
11338{
11339	return map ? map->n : isl_size_error;
11340}
11341
11342isl_size isl_set_n_basic_set(__isl_keep isl_set *set)
11343{
11344	return set ? set->n : isl_size_error;
11345}
11346
11347isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map,
11348	isl_stat (*fn)(__isl_take isl_basic_map *bmap, void *user), void *user)
11349{
11350	int i;
11351
11352	if (!map)
11353		return isl_stat_error;
11354
11355	for (i = 0; i < map->n; ++i)
11356		if (fn(isl_basic_map_copy(map->p[i]), user) < 0)
11357			return isl_stat_error;
11358
11359	return isl_stat_ok;
11360}
11361
11362isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set,
11363	isl_stat (*fn)(__isl_take isl_basic_set *bset, void *user), void *user)
11364{
11365	int i;
11366
11367	if (!set)
11368		return isl_stat_error;
11369
11370	for (i = 0; i < set->n; ++i)
11371		if (fn(isl_basic_set_copy(set->p[i]), user) < 0)
11372			return isl_stat_error;
11373
11374	return isl_stat_ok;
11375}
11376
11377/* Does "test" succeed on every basic set in "set"?
11378 */
11379isl_bool isl_set_every_basic_set(__isl_keep isl_set *set,
11380	isl_bool (*test)(__isl_keep isl_basic_set *bset, void *user),
11381	void *user)
11382{
11383	int i;
11384
11385	if (!set)
11386		return isl_bool_error;
11387
11388	for (i = 0; i < set->n; ++i) {
11389		isl_bool r;
11390
11391		r = test(set->p[i], user);
11392		if (r < 0 || !r)
11393			return r;
11394	}
11395
11396	return isl_bool_true;
11397}
11398
11399/* Return a list of basic sets, the union of which is equal to "set".
11400 */
11401__isl_give isl_basic_set_list *isl_set_get_basic_set_list(
11402	__isl_keep isl_set *set)
11403{
11404	int i;
11405	isl_basic_set_list *list;
11406
11407	if (!set)
11408		return NULL;
11409
11410	list = isl_basic_set_list_alloc(isl_set_get_ctx(set), set->n);
11411	for (i = 0; i < set->n; ++i) {
11412		isl_basic_set *bset;
11413
11414		bset = isl_basic_set_copy(set->p[i]);
11415		list = isl_basic_set_list_add(list, bset);
11416	}
11417
11418	return list;
11419}
11420
11421__isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset)
11422{
11423	isl_space *space;
11424
11425	if (!bset)
11426		return NULL;
11427
11428	bset = isl_basic_set_cow(bset);
11429	if (!bset)
11430		return NULL;
11431
11432	space = isl_basic_set_get_space(bset);
11433	space = isl_space_lift(space, bset->n_div);
11434	if (!space)
11435		goto error;
11436	isl_space_free(bset->dim);
11437	bset->dim = space;
11438	bset->extra -= bset->n_div;
11439	bset->n_div = 0;
11440
11441	bset = isl_basic_set_finalize(bset);
11442
11443	return bset;
11444error:
11445	isl_basic_set_free(bset);
11446	return NULL;
11447}
11448
11449__isl_give isl_set *isl_set_lift(__isl_take isl_set *set)
11450{
11451	int i;
11452	isl_space *space;
11453	unsigned n_div;
11454
11455	set = set_from_map(isl_map_align_divs_internal(set_to_map(set)));
11456
11457	if (!set)
11458		return NULL;
11459
11460	set = isl_set_cow(set);
11461	if (!set)
11462		return NULL;
11463
11464	n_div = set->p[0]->n_div;
11465	space = isl_set_get_space(set);
11466	space = isl_space_lift(space, n_div);
11467	if (!space)
11468		goto error;
11469	isl_space_free(set->dim);
11470	set->dim = space;
11471
11472	for (i = 0; i < set->n; ++i) {
11473		set->p[i] = isl_basic_set_lift(set->p[i]);
11474		if (!set->p[i])
11475			goto error;
11476	}
11477
11478	return set;
11479error:
11480	isl_set_free(set);
11481	return NULL;
11482}
11483
11484int isl_basic_set_size(__isl_keep isl_basic_set *bset)
11485{
11486	isl_size dim;
11487	int size = 0;
11488
11489	dim = isl_basic_set_dim(bset, isl_dim_all);
11490	if (dim < 0)
11491		return -1;
11492	size += bset->n_eq * (1 + dim);
11493	size += bset->n_ineq * (1 + dim);
11494	size += bset->n_div * (2 + dim);
11495
11496	return size;
11497}
11498
11499int isl_set_size(__isl_keep isl_set *set)
11500{
11501	int i;
11502	int size = 0;
11503
11504	if (!set)
11505		return -1;
11506
11507	for (i = 0; i < set->n; ++i)
11508		size += isl_basic_set_size(set->p[i]);
11509
11510	return size;
11511}
11512
11513/* Check if there is any lower bound (if lower == 0) and/or upper
11514 * bound (if upper == 0) on the specified dim.
11515 */
11516static isl_bool basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
11517	enum isl_dim_type type, unsigned pos, int lower, int upper)
11518{
11519	int i;
11520
11521	if (isl_basic_map_check_range(bmap, type, pos, 1) < 0)
11522		return isl_bool_error;
11523
11524	pos += isl_basic_map_offset(bmap, type);
11525
11526	for (i = 0; i < bmap->n_div; ++i) {
11527		if (isl_int_is_zero(bmap->div[i][0]))
11528			continue;
11529		if (!isl_int_is_zero(bmap->div[i][1 + pos]))
11530			return isl_bool_true;
11531	}
11532
11533	for (i = 0; i < bmap->n_eq; ++i)
11534		if (!isl_int_is_zero(bmap->eq[i][pos]))
11535			return isl_bool_true;
11536
11537	for (i = 0; i < bmap->n_ineq; ++i) {
11538		int sgn = isl_int_sgn(bmap->ineq[i][pos]);
11539		if (sgn > 0)
11540			lower = 1;
11541		if (sgn < 0)
11542			upper = 1;
11543	}
11544
11545	return lower && upper;
11546}
11547
11548isl_bool isl_basic_map_dim_is_bounded(__isl_keep isl_basic_map *bmap,
11549	enum isl_dim_type type, unsigned pos)
11550{
11551	return basic_map_dim_is_bounded(bmap, type, pos, 0, 0);
11552}
11553
11554isl_bool isl_basic_map_dim_has_lower_bound(__isl_keep isl_basic_map *bmap,
11555	enum isl_dim_type type, unsigned pos)
11556{
11557	return basic_map_dim_is_bounded(bmap, type, pos, 0, 1);
11558}
11559
11560isl_bool isl_basic_map_dim_has_upper_bound(__isl_keep isl_basic_map *bmap,
11561	enum isl_dim_type type, unsigned pos)
11562{
11563	return basic_map_dim_is_bounded(bmap, type, pos, 1, 0);
11564}
11565
11566isl_bool isl_map_dim_is_bounded(__isl_keep isl_map *map,
11567	enum isl_dim_type type, unsigned pos)
11568{
11569	int i;
11570
11571	if (!map)
11572		return isl_bool_error;
11573
11574	for (i = 0; i < map->n; ++i) {
11575		isl_bool bounded;
11576		bounded = isl_basic_map_dim_is_bounded(map->p[i], type, pos);
11577		if (bounded < 0 || !bounded)
11578			return bounded;
11579	}
11580
11581	return isl_bool_true;
11582}
11583
11584/* Return true if the specified dim is involved in both an upper bound
11585 * and a lower bound.
11586 */
11587isl_bool isl_set_dim_is_bounded(__isl_keep isl_set *set,
11588	enum isl_dim_type type, unsigned pos)
11589{
11590	return isl_map_dim_is_bounded(set_to_map(set), type, pos);
11591}
11592
11593/* Does "map" have a bound (according to "fn") for any of its basic maps?
11594 */
11595static isl_bool has_any_bound(__isl_keep isl_map *map,
11596	enum isl_dim_type type, unsigned pos,
11597	isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
11598		  enum isl_dim_type type, unsigned pos))
11599{
11600	int i;
11601
11602	if (!map)
11603		return isl_bool_error;
11604
11605	for (i = 0; i < map->n; ++i) {
11606		isl_bool bounded;
11607		bounded = fn(map->p[i], type, pos);
11608		if (bounded < 0 || bounded)
11609			return bounded;
11610	}
11611
11612	return isl_bool_false;
11613}
11614
11615/* Return 1 if the specified dim is involved in any lower bound.
11616 */
11617isl_bool isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set,
11618	enum isl_dim_type type, unsigned pos)
11619{
11620	return has_any_bound(set, type, pos,
11621				&isl_basic_map_dim_has_lower_bound);
11622}
11623
11624/* Return 1 if the specified dim is involved in any upper bound.
11625 */
11626isl_bool isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set,
11627	enum isl_dim_type type, unsigned pos)
11628{
11629	return has_any_bound(set, type, pos,
11630				&isl_basic_map_dim_has_upper_bound);
11631}
11632
11633/* Does "map" have a bound (according to "fn") for all of its basic maps?
11634 */
11635static isl_bool has_bound(__isl_keep isl_map *map,
11636	enum isl_dim_type type, unsigned pos,
11637	isl_bool (*fn)(__isl_keep isl_basic_map *bmap,
11638		  enum isl_dim_type type, unsigned pos))
11639{
11640	int i;
11641
11642	if (!map)
11643		return isl_bool_error;
11644
11645	for (i = 0; i < map->n; ++i) {
11646		isl_bool bounded;
11647		bounded = fn(map->p[i], type, pos);
11648		if (bounded < 0 || !bounded)
11649			return bounded;
11650	}
11651
11652	return isl_bool_true;
11653}
11654
11655/* Return 1 if the specified dim has a lower bound (in each of its basic sets).
11656 */
11657isl_bool isl_set_dim_has_lower_bound(__isl_keep isl_set *set,
11658	enum isl_dim_type type, unsigned pos)
11659{
11660	return has_bound(set, type, pos, &isl_basic_map_dim_has_lower_bound);
11661}
11662
11663/* Return 1 if the specified dim has an upper bound (in each of its basic sets).
11664 */
11665isl_bool isl_set_dim_has_upper_bound(__isl_keep isl_set *set,
11666	enum isl_dim_type type, unsigned pos)
11667{
11668	return has_bound(set, type, pos, &isl_basic_map_dim_has_upper_bound);
11669}
11670
11671/* For each of the "n" variables starting at "first", determine
11672 * the sign of the variable and put the results in the first "n"
11673 * elements of the array "signs".
11674 * Sign
11675 *	1 means that the variable is non-negative
11676 *	-1 means that the variable is non-positive
11677 *	0 means the variable attains both positive and negative values.
11678 */
11679isl_stat isl_basic_set_vars_get_sign(__isl_keep isl_basic_set *bset,
11680	unsigned first, unsigned n, int *signs)
11681{
11682	isl_vec *bound = NULL;
11683	struct isl_tab *tab = NULL;
11684	struct isl_tab_undo *snap;
11685	int i;
11686	isl_size total;
11687
11688	total = isl_basic_set_dim(bset, isl_dim_all);
11689	if (total < 0 || !signs)
11690		return isl_stat_error;
11691
11692	bound = isl_vec_alloc(bset->ctx, 1 + total);
11693	tab = isl_tab_from_basic_set(bset, 0);
11694	if (!bound || !tab)
11695		goto error;
11696
11697	isl_seq_clr(bound->el, bound->size);
11698	isl_int_set_si(bound->el[0], -1);
11699
11700	snap = isl_tab_snap(tab);
11701	for (i = 0; i < n; ++i) {
11702		int empty;
11703
11704		isl_int_set_si(bound->el[1 + first + i], -1);
11705		if (isl_tab_add_ineq(tab, bound->el) < 0)
11706			goto error;
11707		empty = tab->empty;
11708		isl_int_set_si(bound->el[1 + first + i], 0);
11709		if (isl_tab_rollback(tab, snap) < 0)
11710			goto error;
11711
11712		if (empty) {
11713			signs[i] = 1;
11714			continue;
11715		}
11716
11717		isl_int_set_si(bound->el[1 + first + i], 1);
11718		if (isl_tab_add_ineq(tab, bound->el) < 0)
11719			goto error;
11720		empty = tab->empty;
11721		isl_int_set_si(bound->el[1 + first + i], 0);
11722		if (isl_tab_rollback(tab, snap) < 0)
11723			goto error;
11724
11725		signs[i] = empty ? -1 : 0;
11726	}
11727
11728	isl_tab_free(tab);
11729	isl_vec_free(bound);
11730	return isl_stat_ok;
11731error:
11732	isl_tab_free(tab);
11733	isl_vec_free(bound);
11734	return isl_stat_error;
11735}
11736
11737isl_stat isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset,
11738	enum isl_dim_type type, unsigned first, unsigned n, int *signs)
11739{
11740	if (!bset || !signs)
11741		return isl_stat_error;
11742	if (isl_basic_set_check_range(bset, type, first, n) < 0)
11743		return isl_stat_error;
11744
11745	first += pos(bset->dim, type) - 1;
11746	return isl_basic_set_vars_get_sign(bset, first, n, signs);
11747}
11748
11749/* Is it possible for the integer division "div" to depend (possibly
11750 * indirectly) on any output dimensions?
11751 *
11752 * If the div is undefined, then we conservatively assume that it
11753 * may depend on them.
11754 * Otherwise, we check if it actually depends on them or on any integer
11755 * divisions that may depend on them.
11756 */
11757static isl_bool div_may_involve_output(__isl_keep isl_basic_map *bmap, int div)
11758{
11759	int i;
11760	isl_size n_out, n_div;
11761	unsigned o_out, o_div;
11762
11763	if (isl_int_is_zero(bmap->div[div][0]))
11764		return isl_bool_true;
11765
11766	n_out = isl_basic_map_dim(bmap, isl_dim_out);
11767	if (n_out < 0)
11768		return isl_bool_error;
11769	o_out = isl_basic_map_offset(bmap, isl_dim_out);
11770
11771	if (isl_seq_first_non_zero(bmap->div[div] + 1 + o_out, n_out) != -1)
11772		return isl_bool_true;
11773
11774	n_div = isl_basic_map_dim(bmap, isl_dim_div);
11775	if (n_div < 0)
11776		return isl_bool_error;
11777	o_div = isl_basic_map_offset(bmap, isl_dim_div);
11778
11779	for (i = 0; i < n_div; ++i) {
11780		isl_bool may_involve;
11781
11782		if (isl_int_is_zero(bmap->div[div][1 + o_div + i]))
11783			continue;
11784		may_involve = div_may_involve_output(bmap, i);
11785		if (may_involve < 0 || may_involve)
11786			return may_involve;
11787	}
11788
11789	return isl_bool_false;
11790}
11791
11792/* Return the first integer division of "bmap" in the range
11793 * [first, first + n[ that may depend on any output dimensions and
11794 * that has a non-zero coefficient in "c" (where the first coefficient
11795 * in "c" corresponds to integer division "first").
11796 */
11797static int first_div_may_involve_output(__isl_keep isl_basic_map *bmap,
11798	isl_int *c, int first, int n)
11799{
11800	int k;
11801
11802	if (!bmap)
11803		return -1;
11804
11805	for (k = first; k < first + n; ++k) {
11806		isl_bool may_involve;
11807
11808		if (isl_int_is_zero(c[k]))
11809			continue;
11810		may_involve = div_may_involve_output(bmap, k);
11811		if (may_involve < 0)
11812			return -1;
11813		if (may_involve)
11814			return k;
11815	}
11816
11817	return first + n;
11818}
11819
11820/* Look for a pair of inequality constraints in "bmap" of the form
11821 *
11822 *	-l + i >= 0		or		i >= l
11823 * and
11824 *	n + l - i >= 0		or		i <= l + n
11825 *
11826 * with n < "m" and i the output dimension at position "pos".
11827 * (Note that n >= 0 as otherwise the two constraints would conflict.)
11828 * Furthermore, "l" is only allowed to involve parameters, input dimensions
11829 * and earlier output dimensions, as well as integer divisions that do
11830 * not involve any of the output dimensions.
11831 *
11832 * Return the index of the first inequality constraint or bmap->n_ineq
11833 * if no such pair can be found.
11834 */
11835static int find_modulo_constraint_pair(__isl_keep isl_basic_map *bmap,
11836	int pos, isl_int m)
11837{
11838	int i, j;
11839	isl_ctx *ctx;
11840	isl_size total;
11841	isl_size n_div, n_out;
11842	unsigned o_div, o_out;
11843	int less;
11844
11845	total = isl_basic_map_dim(bmap, isl_dim_all);
11846	n_out = isl_basic_map_dim(bmap, isl_dim_out);
11847	n_div = isl_basic_map_dim(bmap, isl_dim_div);
11848	if (total < 0 || n_out < 0 || n_div < 0)
11849		return -1;
11850
11851	ctx = isl_basic_map_get_ctx(bmap);
11852	o_out = isl_basic_map_offset(bmap, isl_dim_out);
11853	o_div = isl_basic_map_offset(bmap, isl_dim_div);
11854	for (i = 0; i < bmap->n_ineq; ++i) {
11855		if (!isl_int_abs_eq(bmap->ineq[i][o_out + pos], ctx->one))
11856			continue;
11857		if (isl_seq_first_non_zero(bmap->ineq[i] + o_out + pos + 1,
11858					n_out - (pos + 1)) != -1)
11859			continue;
11860		if (first_div_may_involve_output(bmap, bmap->ineq[i] + o_div,
11861						0, n_div) < n_div)
11862			continue;
11863		for (j = i + 1; j < bmap->n_ineq; ++j) {
11864			if (!isl_int_abs_eq(bmap->ineq[j][o_out + pos],
11865					    ctx->one))
11866				continue;
11867			if (!isl_seq_is_neg(bmap->ineq[i] + 1,
11868					    bmap->ineq[j] + 1, total))
11869				continue;
11870			break;
11871		}
11872		if (j >= bmap->n_ineq)
11873			continue;
11874		isl_int_add(bmap->ineq[i][0],
11875			    bmap->ineq[i][0], bmap->ineq[j][0]);
11876		less = isl_int_abs_lt(bmap->ineq[i][0], m);
11877		isl_int_sub(bmap->ineq[i][0],
11878			    bmap->ineq[i][0], bmap->ineq[j][0]);
11879		if (!less)
11880			continue;
11881		if (isl_int_is_one(bmap->ineq[i][o_out + pos]))
11882			return i;
11883		else
11884			return j;
11885	}
11886
11887	return bmap->n_ineq;
11888}
11889
11890/* Return the index of the equality of "bmap" that defines
11891 * the output dimension "pos" in terms of earlier dimensions.
11892 * The equality may also involve integer divisions, as long
11893 * as those integer divisions are defined in terms of
11894 * parameters or input dimensions.
11895 * In this case, *div is set to the number of integer divisions and
11896 * *ineq is set to the number of inequality constraints (provided
11897 * div and ineq are not NULL).
11898 *
11899 * The equality may also involve a single integer division involving
11900 * the output dimensions (typically only output dimension "pos") as
11901 * long as the coefficient of output dimension "pos" is 1 or -1 and
11902 * there is a pair of constraints i >= l and i <= l + n, with i referring
11903 * to output dimension "pos", l an expression involving only earlier
11904 * dimensions and n smaller than the coefficient of the integer division
11905 * in the equality.  In this case, the output dimension can be defined
11906 * in terms of a modulo expression that does not involve the integer division.
11907 * *div is then set to this single integer division and
11908 * *ineq is set to the index of constraint i >= l.
11909 *
11910 * Return bmap->n_eq if there is no such equality.
11911 * Return -1 on error.
11912 */
11913int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap,
11914	int pos, int *div, int *ineq)
11915{
11916	int j, k, l;
11917	isl_size n_div, n_out;
11918	unsigned o_div, o_out;
11919
11920	n_out = isl_basic_map_dim(bmap, isl_dim_out);
11921	n_div = isl_basic_map_dim(bmap, isl_dim_div);
11922	if (n_out < 0 || n_div < 0)
11923		return -1;
11924
11925	o_out = isl_basic_map_offset(bmap, isl_dim_out);
11926	o_div = isl_basic_map_offset(bmap, isl_dim_div);
11927
11928	if (ineq)
11929		*ineq = bmap->n_ineq;
11930	if (div)
11931		*div = n_div;
11932	for (j = 0; j < bmap->n_eq; ++j) {
11933		if (isl_int_is_zero(bmap->eq[j][o_out + pos]))
11934			continue;
11935		if (isl_seq_first_non_zero(bmap->eq[j] + o_out + pos + 1,
11936					n_out - (pos + 1)) != -1)
11937			continue;
11938		k = first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
11939						0, n_div);
11940		if (k >= n_div)
11941			return j;
11942		if (!isl_int_is_one(bmap->eq[j][o_out + pos]) &&
11943		    !isl_int_is_negone(bmap->eq[j][o_out + pos]))
11944			continue;
11945		if (first_div_may_involve_output(bmap, bmap->eq[j] + o_div,
11946						k + 1, n_div - (k+1)) < n_div)
11947			continue;
11948		l = find_modulo_constraint_pair(bmap, pos,
11949						bmap->eq[j][o_div + k]);
11950		if (l < 0)
11951			return -1;
11952		if (l >= bmap->n_ineq)
11953			continue;
11954		if (div)
11955			*div = k;
11956		if (ineq)
11957			*ineq = l;
11958		return j;
11959	}
11960
11961	return bmap->n_eq;
11962}
11963
11964/* Check if the given basic map is obviously single-valued.
11965 * In particular, for each output dimension, check that there is
11966 * an equality that defines the output dimension in terms of
11967 * earlier dimensions.
11968 */
11969isl_bool isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
11970{
11971	int i;
11972	isl_size n_out;
11973
11974	n_out = isl_basic_map_dim(bmap, isl_dim_out);
11975	if (n_out < 0)
11976		return isl_bool_error;
11977
11978	for (i = 0; i < n_out; ++i) {
11979		int eq;
11980
11981		eq = isl_basic_map_output_defining_equality(bmap, i,
11982							    NULL, NULL);
11983		if (eq < 0)
11984			return isl_bool_error;
11985		if (eq >= bmap->n_eq)
11986			return isl_bool_false;
11987	}
11988
11989	return isl_bool_true;
11990}
11991
11992/* Check if the given basic map is single-valued.
11993 * We simply compute
11994 *
11995 *	M \circ M^-1
11996 *
11997 * and check if the result is a subset of the identity mapping.
11998 */
11999isl_bool isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap)
12000{
12001	isl_space *space;
12002	isl_basic_map *test;
12003	isl_basic_map *id;
12004	isl_bool sv;
12005
12006	sv = isl_basic_map_plain_is_single_valued(bmap);
12007	if (sv < 0 || sv)
12008		return sv;
12009
12010	test = isl_basic_map_reverse(isl_basic_map_copy(bmap));
12011	test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap));
12012
12013	space = isl_basic_map_get_space(bmap);
12014	space = isl_space_map_from_set(isl_space_range(space));
12015	id = isl_basic_map_identity(space);
12016
12017	sv = isl_basic_map_is_subset(test, id);
12018
12019	isl_basic_map_free(test);
12020	isl_basic_map_free(id);
12021
12022	return sv;
12023}
12024
12025/* Check if the given map is obviously single-valued.
12026 */
12027isl_bool isl_map_plain_is_single_valued(__isl_keep isl_map *map)
12028{
12029	if (!map)
12030		return isl_bool_error;
12031	if (map->n == 0)
12032		return isl_bool_true;
12033	if (map->n >= 2)
12034		return isl_bool_false;
12035
12036	return isl_basic_map_plain_is_single_valued(map->p[0]);
12037}
12038
12039/* Check if the given map is single-valued.
12040 * We simply compute
12041 *
12042 *	M \circ M^-1
12043 *
12044 * and check if the result is a subset of the identity mapping.
12045 */
12046isl_bool isl_map_is_single_valued(__isl_keep isl_map *map)
12047{
12048	isl_space *space;
12049	isl_map *test;
12050	isl_map *id;
12051	isl_bool sv;
12052
12053	sv = isl_map_plain_is_single_valued(map);
12054	if (sv < 0 || sv)
12055		return sv;
12056
12057	test = isl_map_reverse(isl_map_copy(map));
12058	test = isl_map_apply_range(test, isl_map_copy(map));
12059
12060	space = isl_space_map_from_set(isl_space_range(isl_map_get_space(map)));
12061	id = isl_map_identity(space);
12062
12063	sv = isl_map_is_subset(test, id);
12064
12065	isl_map_free(test);
12066	isl_map_free(id);
12067
12068	return sv;
12069}
12070
12071isl_bool isl_map_is_injective(__isl_keep isl_map *map)
12072{
12073	isl_bool in;
12074
12075	map = isl_map_copy(map);
12076	map = isl_map_reverse(map);
12077	in = isl_map_is_single_valued(map);
12078	isl_map_free(map);
12079
12080	return in;
12081}
12082
12083/* Check if the given map is obviously injective.
12084 */
12085isl_bool isl_map_plain_is_injective(__isl_keep isl_map *map)
12086{
12087	isl_bool in;
12088
12089	map = isl_map_copy(map);
12090	map = isl_map_reverse(map);
12091	in = isl_map_plain_is_single_valued(map);
12092	isl_map_free(map);
12093
12094	return in;
12095}
12096
12097isl_bool isl_map_is_bijective(__isl_keep isl_map *map)
12098{
12099	isl_bool sv;
12100
12101	sv = isl_map_is_single_valued(map);
12102	if (sv < 0 || !sv)
12103		return sv;
12104
12105	return isl_map_is_injective(map);
12106}
12107
12108isl_bool isl_set_is_singleton(__isl_keep isl_set *set)
12109{
12110	return isl_map_is_single_valued(set_to_map(set));
12111}
12112
12113/* Does "map" only map elements to themselves?
12114 *
12115 * If the domain and range spaces are different, then "map"
12116 * is considered not to be an identity relation, even if it is empty.
12117 * Otherwise, construct the maximal identity relation and
12118 * check whether "map" is a subset of this relation.
12119 */
12120isl_bool isl_map_is_identity(__isl_keep isl_map *map)
12121{
12122	isl_map *id;
12123	isl_bool equal, is_identity;
12124
12125	equal = isl_map_tuple_is_equal(map, isl_dim_in, map, isl_dim_out);
12126	if (equal < 0 || !equal)
12127		return equal;
12128
12129	id = isl_map_identity(isl_map_get_space(map));
12130	is_identity = isl_map_is_subset(map, id);
12131	isl_map_free(id);
12132
12133	return is_identity;
12134}
12135
12136int isl_map_is_translation(__isl_keep isl_map *map)
12137{
12138	int ok;
12139	isl_set *delta;
12140
12141	delta = isl_map_deltas(isl_map_copy(map));
12142	ok = isl_set_is_singleton(delta);
12143	isl_set_free(delta);
12144
12145	return ok;
12146}
12147
12148static int unique(isl_int *p, unsigned pos, unsigned len)
12149{
12150	if (isl_seq_first_non_zero(p, pos) != -1)
12151		return 0;
12152	if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1)
12153		return 0;
12154	return 1;
12155}
12156
12157isl_bool isl_basic_set_is_box(__isl_keep isl_basic_set *bset)
12158{
12159	int i, j;
12160	isl_size nvar, ovar, n_div;
12161
12162	n_div = isl_basic_set_dim(bset, isl_dim_div);
12163	if (n_div < 0)
12164		return isl_bool_error;
12165	if (n_div != 0)
12166		return isl_bool_false;
12167
12168	nvar = isl_basic_set_dim(bset, isl_dim_set);
12169	ovar = isl_space_offset(bset->dim, isl_dim_set);
12170	if (nvar < 0 || ovar < 0)
12171		return isl_bool_error;
12172	for (j = 0; j < nvar; ++j) {
12173		int lower = 0, upper = 0;
12174		for (i = 0; i < bset->n_eq; ++i) {
12175			if (isl_int_is_zero(bset->eq[i][1 + ovar + j]))
12176				continue;
12177			if (!unique(bset->eq[i] + 1 + ovar, j, nvar))
12178				return isl_bool_false;
12179			break;
12180		}
12181		if (i < bset->n_eq)
12182			continue;
12183		for (i = 0; i < bset->n_ineq; ++i) {
12184			if (isl_int_is_zero(bset->ineq[i][1 + ovar + j]))
12185				continue;
12186			if (!unique(bset->ineq[i] + 1 + ovar, j, nvar))
12187				return isl_bool_false;
12188			if (isl_int_is_pos(bset->ineq[i][1 + ovar + j]))
12189				lower = 1;
12190			else
12191				upper = 1;
12192		}
12193		if (!lower || !upper)
12194			return isl_bool_false;
12195	}
12196
12197	return isl_bool_true;
12198}
12199
12200isl_bool isl_set_is_box(__isl_keep isl_set *set)
12201{
12202	if (!set)
12203		return isl_bool_error;
12204	if (set->n != 1)
12205		return isl_bool_false;
12206
12207	return isl_basic_set_is_box(set->p[0]);
12208}
12209
12210isl_bool isl_basic_set_is_wrapping(__isl_keep isl_basic_set *bset)
12211{
12212	if (!bset)
12213		return isl_bool_error;
12214
12215	return isl_space_is_wrapping(bset->dim);
12216}
12217
12218isl_bool isl_set_is_wrapping(__isl_keep isl_set *set)
12219{
12220	if (!set)
12221		return isl_bool_error;
12222
12223	return isl_space_is_wrapping(set->dim);
12224}
12225
12226/* Modify the space of "map" through a call to "change".
12227 * If "can_change" is set (not NULL), then first call it to check
12228 * if the modification is allowed, printing the error message "cannot_change"
12229 * if it is not.
12230 */
12231static __isl_give isl_map *isl_map_change_space(__isl_take isl_map *map,
12232	isl_bool (*can_change)(__isl_keep isl_map *map),
12233	const char *cannot_change,
12234	__isl_give isl_space *(*change)(__isl_take isl_space *space))
12235{
12236	isl_bool ok;
12237	isl_space *space;
12238
12239	if (!map)
12240		return NULL;
12241
12242	ok = can_change ? can_change(map) : isl_bool_true;
12243	if (ok < 0)
12244		return isl_map_free(map);
12245	if (!ok)
12246		isl_die(isl_map_get_ctx(map), isl_error_invalid, cannot_change,
12247			return isl_map_free(map));
12248
12249	space = change(isl_map_get_space(map));
12250	map = isl_map_reset_space(map, space);
12251
12252	return map;
12253}
12254
12255/* Is the domain of "map" a wrapped relation?
12256 */
12257isl_bool isl_map_domain_is_wrapping(__isl_keep isl_map *map)
12258{
12259	if (!map)
12260		return isl_bool_error;
12261
12262	return isl_space_domain_is_wrapping(map->dim);
12263}
12264
12265/* Does "map" have a wrapped relation in both domain and range?
12266 */
12267isl_bool isl_map_is_product(__isl_keep isl_map *map)
12268{
12269	return isl_space_is_product(isl_map_peek_space(map));
12270}
12271
12272/* Is the range of "map" a wrapped relation?
12273 */
12274isl_bool isl_map_range_is_wrapping(__isl_keep isl_map *map)
12275{
12276	if (!map)
12277		return isl_bool_error;
12278
12279	return isl_space_range_is_wrapping(map->dim);
12280}
12281
12282__isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
12283{
12284	isl_space *space;
12285
12286	space = isl_basic_map_take_space(bmap);
12287	space = isl_space_wrap(space);
12288	bmap = isl_basic_map_restore_space(bmap, space);
12289
12290	bmap = isl_basic_map_finalize(bmap);
12291
12292	return bset_from_bmap(bmap);
12293}
12294
12295/* Given a map A -> B, return the set (A -> B).
12296 */
12297__isl_give isl_set *isl_map_wrap(__isl_take isl_map *map)
12298{
12299	return isl_map_change_space(map, NULL, NULL, &isl_space_wrap);
12300}
12301
12302__isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset)
12303{
12304	bset = isl_basic_set_cow(bset);
12305	if (!bset)
12306		return NULL;
12307
12308	bset->dim = isl_space_unwrap(bset->dim);
12309	if (!bset->dim)
12310		goto error;
12311
12312	bset = isl_basic_set_finalize(bset);
12313
12314	return bset_to_bmap(bset);
12315error:
12316	isl_basic_set_free(bset);
12317	return NULL;
12318}
12319
12320/* Given a set (A -> B), return the map A -> B.
12321 * Error out if "set" is not of the form (A -> B).
12322 */
12323__isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set)
12324{
12325	return isl_map_change_space(set, &isl_set_is_wrapping,
12326				    "not a wrapping set", &isl_space_unwrap);
12327}
12328
12329__isl_give isl_basic_map *isl_basic_map_reset(__isl_take isl_basic_map *bmap,
12330	enum isl_dim_type type)
12331{
12332	isl_space *space;
12333
12334	space = isl_basic_map_take_space(bmap);
12335	space = isl_space_reset(space, type);
12336	bmap = isl_basic_map_restore_space(bmap, space);
12337
12338	bmap = isl_basic_map_mark_final(bmap);
12339
12340	return bmap;
12341}
12342
12343__isl_give isl_map *isl_map_reset(__isl_take isl_map *map,
12344	enum isl_dim_type type)
12345{
12346	int i;
12347	isl_space *space;
12348
12349	if (!map)
12350		return NULL;
12351
12352	if (!isl_space_is_named_or_nested(map->dim, type))
12353		return map;
12354
12355	map = isl_map_cow(map);
12356	if (!map)
12357		return NULL;
12358
12359	for (i = 0; i < map->n; ++i) {
12360		map->p[i] = isl_basic_map_reset(map->p[i], type);
12361		if (!map->p[i])
12362			goto error;
12363	}
12364
12365	space = isl_map_take_space(map);
12366	space = isl_space_reset(space, type);
12367	map = isl_map_restore_space(map, space);
12368
12369	return map;
12370error:
12371	isl_map_free(map);
12372	return NULL;
12373}
12374
12375__isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
12376{
12377	isl_space *space;
12378
12379	space = isl_basic_map_take_space(bmap);
12380	space = isl_space_flatten(space);
12381	bmap = isl_basic_map_restore_space(bmap, space);
12382
12383	bmap = isl_basic_map_mark_final(bmap);
12384
12385	return bmap;
12386}
12387
12388__isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset)
12389{
12390	return bset_from_bmap(isl_basic_map_flatten(bset_to_bmap(bset)));
12391}
12392
12393__isl_give isl_basic_map *isl_basic_map_flatten_domain(
12394	__isl_take isl_basic_map *bmap)
12395{
12396	isl_space *space;
12397
12398	space = isl_basic_map_take_space(bmap);
12399	space = isl_space_flatten_domain(space);
12400	bmap = isl_basic_map_restore_space(bmap, space);
12401
12402	bmap = isl_basic_map_mark_final(bmap);
12403
12404	return bmap;
12405}
12406
12407__isl_give isl_basic_map *isl_basic_map_flatten_range(
12408	__isl_take isl_basic_map *bmap)
12409{
12410	isl_space *space;
12411
12412	space = isl_basic_map_take_space(bmap);
12413	space = isl_space_flatten_range(space);
12414	bmap = isl_basic_map_restore_space(bmap, space);
12415
12416	bmap = isl_basic_map_mark_final(bmap);
12417
12418	return bmap;
12419}
12420
12421/* Remove any internal structure from the spaces of domain and range of "map".
12422 */
12423__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
12424{
12425	if (!map)
12426		return NULL;
12427
12428	if (!map->dim->nested[0] && !map->dim->nested[1])
12429		return map;
12430
12431	return isl_map_change_space(map, NULL, NULL, &isl_space_flatten);
12432}
12433
12434__isl_give isl_set *isl_set_flatten(__isl_take isl_set *set)
12435{
12436	return set_from_map(isl_map_flatten(set_to_map(set)));
12437}
12438
12439__isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set)
12440{
12441	isl_space *space, *flat_space;
12442	isl_map *map;
12443
12444	space = isl_set_get_space(set);
12445	flat_space = isl_space_flatten(isl_space_copy(space));
12446	map = isl_map_identity(isl_space_join(isl_space_reverse(space),
12447						flat_space));
12448	map = isl_map_intersect_domain(map, set);
12449
12450	return map;
12451}
12452
12453/* Remove any internal structure from the space of the domain of "map".
12454 */
12455__isl_give isl_map *isl_map_flatten_domain(__isl_take isl_map *map)
12456{
12457	if (!map)
12458		return NULL;
12459
12460	if (!map->dim->nested[0])
12461		return map;
12462
12463	return isl_map_change_space(map, NULL, NULL, &isl_space_flatten_domain);
12464}
12465
12466/* Remove any internal structure from the space of the range of "map".
12467 */
12468__isl_give isl_map *isl_map_flatten_range(__isl_take isl_map *map)
12469{
12470	if (!map)
12471		return NULL;
12472
12473	if (!map->dim->nested[1])
12474		return map;
12475
12476	return isl_map_change_space(map, NULL, NULL, &isl_space_flatten_range);
12477}
12478
12479/* Reorder the dimensions of "bmap" according to the given dim_map
12480 * and set the dimension specification to "space" and
12481 * perform Gaussian elimination on the result.
12482 */
12483__isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap,
12484	__isl_take isl_space *space, __isl_take struct isl_dim_map *dim_map)
12485{
12486	isl_basic_map *res;
12487	unsigned flags;
12488	isl_size n_div;
12489
12490	n_div = isl_basic_map_dim(bmap, isl_dim_div);
12491	if (n_div < 0 || !space || !dim_map)
12492		goto error;
12493
12494	flags = bmap->flags;
12495	ISL_FL_CLR(flags, ISL_BASIC_MAP_FINAL);
12496	ISL_FL_CLR(flags, ISL_BASIC_MAP_SORTED);
12497	ISL_FL_CLR(flags, ISL_BASIC_MAP_NORMALIZED_DIVS);
12498	res = isl_basic_map_alloc_space(space, n_div, bmap->n_eq, bmap->n_ineq);
12499	res = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
12500	if (res)
12501		res->flags = flags;
12502	res = isl_basic_map_gauss(res, NULL);
12503	res = isl_basic_map_finalize(res);
12504	return res;
12505error:
12506	isl_dim_map_free(dim_map);
12507	isl_basic_map_free(bmap);
12508	isl_space_free(space);
12509	return NULL;
12510}
12511
12512/* Reorder the dimensions of "map" according to given reordering.
12513 */
12514__isl_give isl_map *isl_map_realign(__isl_take isl_map *map,
12515	__isl_take isl_reordering *r)
12516{
12517	int i;
12518	struct isl_dim_map *dim_map;
12519
12520	map = isl_map_cow(map);
12521	dim_map = isl_dim_map_from_reordering(r);
12522	if (!map || !r || !dim_map)
12523		goto error;
12524
12525	for (i = 0; i < map->n; ++i) {
12526		struct isl_dim_map *dim_map_i;
12527		isl_space *space;
12528
12529		dim_map_i = isl_dim_map_extend(dim_map, map->p[i]);
12530
12531		space = isl_reordering_get_space(r);
12532		map->p[i] = isl_basic_map_realign(map->p[i], space, dim_map_i);
12533
12534		if (!map->p[i])
12535			goto error;
12536	}
12537
12538	map = isl_map_reset_space(map, isl_reordering_get_space(r));
12539	map = isl_map_unmark_normalized(map);
12540
12541	isl_reordering_free(r);
12542	isl_dim_map_free(dim_map);
12543	return map;
12544error:
12545	isl_dim_map_free(dim_map);
12546	isl_map_free(map);
12547	isl_reordering_free(r);
12548	return NULL;
12549}
12550
12551__isl_give isl_set *isl_set_realign(__isl_take isl_set *set,
12552	__isl_take isl_reordering *r)
12553{
12554	return set_from_map(isl_map_realign(set_to_map(set), r));
12555}
12556
12557__isl_give isl_map *isl_map_align_params(__isl_take isl_map *map,
12558	__isl_take isl_space *model)
12559{
12560	isl_ctx *ctx;
12561	isl_bool aligned;
12562
12563	if (!map || !model)
12564		goto error;
12565
12566	ctx = isl_space_get_ctx(model);
12567	if (!isl_space_has_named_params(model))
12568		isl_die(ctx, isl_error_invalid,
12569			"model has unnamed parameters", goto error);
12570	if (isl_map_check_named_params(map) < 0)
12571		goto error;
12572	aligned = isl_map_space_has_equal_params(map, model);
12573	if (aligned < 0)
12574		goto error;
12575	if (!aligned) {
12576		isl_space *space;
12577		isl_reordering *exp;
12578
12579		space = isl_map_peek_space(map);
12580		exp = isl_parameter_alignment_reordering(space, model);
12581		map = isl_map_realign(map, exp);
12582	}
12583
12584	isl_space_free(model);
12585	return map;
12586error:
12587	isl_space_free(model);
12588	isl_map_free(map);
12589	return NULL;
12590}
12591
12592__isl_give isl_set *isl_set_align_params(__isl_take isl_set *set,
12593	__isl_take isl_space *model)
12594{
12595	return isl_map_align_params(set, model);
12596}
12597
12598/* Align the parameters of "bmap" to those of "model", introducing
12599 * additional parameters if needed.
12600 */
12601__isl_give isl_basic_map *isl_basic_map_align_params(
12602	__isl_take isl_basic_map *bmap, __isl_take isl_space *model)
12603{
12604	isl_ctx *ctx;
12605	isl_bool equal_params;
12606	isl_space *bmap_space;
12607
12608	if (!bmap || !model)
12609		goto error;
12610
12611	ctx = isl_space_get_ctx(model);
12612	if (!isl_space_has_named_params(model))
12613		isl_die(ctx, isl_error_invalid,
12614			"model has unnamed parameters", goto error);
12615	if (isl_basic_map_check_named_params(bmap) < 0)
12616		goto error;
12617	bmap_space = isl_basic_map_peek_space(bmap);
12618	equal_params = isl_space_has_equal_params(bmap_space, model);
12619	if (equal_params < 0)
12620		goto error;
12621	if (!equal_params) {
12622		isl_reordering *exp;
12623		struct isl_dim_map *dim_map;
12624
12625		exp = isl_parameter_alignment_reordering(bmap_space, model);
12626		dim_map = isl_dim_map_from_reordering(exp);
12627		bmap = isl_basic_map_realign(bmap,
12628				    isl_reordering_get_space(exp),
12629				    isl_dim_map_extend(dim_map, bmap));
12630		isl_reordering_free(exp);
12631		isl_dim_map_free(dim_map);
12632	}
12633
12634	isl_space_free(model);
12635	return bmap;
12636error:
12637	isl_space_free(model);
12638	isl_basic_map_free(bmap);
12639	return NULL;
12640}
12641
12642/* Do "bset" and "space" have the same parameters?
12643 */
12644isl_bool isl_basic_set_space_has_equal_params(__isl_keep isl_basic_set *bset,
12645	__isl_keep isl_space *space)
12646{
12647	isl_space *bset_space;
12648
12649	bset_space = isl_basic_set_peek_space(bset);
12650	return isl_space_has_equal_params(bset_space, space);
12651}
12652
12653/* Do "map" and "space" have the same parameters?
12654 */
12655isl_bool isl_map_space_has_equal_params(__isl_keep isl_map *map,
12656	__isl_keep isl_space *space)
12657{
12658	isl_space *map_space;
12659
12660	map_space = isl_map_peek_space(map);
12661	return isl_space_has_equal_params(map_space, space);
12662}
12663
12664/* Do "set" and "space" have the same parameters?
12665 */
12666isl_bool isl_set_space_has_equal_params(__isl_keep isl_set *set,
12667	__isl_keep isl_space *space)
12668{
12669	return isl_map_space_has_equal_params(set_to_map(set), space);
12670}
12671
12672/* Align the parameters of "bset" to those of "model", introducing
12673 * additional parameters if needed.
12674 */
12675__isl_give isl_basic_set *isl_basic_set_align_params(
12676	__isl_take isl_basic_set *bset, __isl_take isl_space *model)
12677{
12678	return isl_basic_map_align_params(bset, model);
12679}
12680
12681#undef TYPE
12682#define TYPE	isl_map
12683#define isl_map_drop_dims	isl_map_drop
12684#include "isl_drop_unused_params_templ.c"
12685
12686/* Drop all parameters not referenced by "set".
12687 */
12688__isl_give isl_set *isl_set_drop_unused_params(
12689	__isl_take isl_set *set)
12690{
12691	return set_from_map(isl_map_drop_unused_params(set_to_map(set)));
12692}
12693
12694#undef TYPE
12695#define TYPE	isl_basic_map
12696#define isl_basic_map_drop_dims	isl_basic_map_drop
12697#include "isl_drop_unused_params_templ.c"
12698
12699/* Drop all parameters not referenced by "bset".
12700 */
12701__isl_give isl_basic_set *isl_basic_set_drop_unused_params(
12702	__isl_take isl_basic_set *bset)
12703{
12704	return bset_from_bmap(isl_basic_map_drop_unused_params(
12705							bset_to_bmap(bset)));
12706}
12707
12708/* Given a tuple of identifiers "tuple" in a space that corresponds
12709 * to that of "set", if any of those identifiers appear as parameters
12710 * in "set", then equate those parameters with the corresponding
12711 * set dimensions and project out the parameters.
12712 * The result therefore has no such parameters.
12713 */
12714static __isl_give isl_set *equate_params(__isl_take isl_set *set,
12715	__isl_keep isl_multi_id *tuple)
12716{
12717	int i;
12718	isl_size n;
12719	isl_space *set_space, *tuple_space;
12720
12721	set_space = isl_set_peek_space(set);
12722	tuple_space = isl_multi_id_peek_space(tuple);
12723	if (isl_space_check_equal_tuples(tuple_space, set_space) < 0)
12724		return isl_set_free(set);
12725	n = isl_multi_id_size(tuple);
12726	if (n < 0)
12727		return isl_set_free(set);
12728	for (i = 0; i < n; ++i) {
12729		isl_id *id;
12730		int pos;
12731
12732		id = isl_multi_id_get_at(tuple, i);
12733		if (!id)
12734			return isl_set_free(set);
12735		pos = isl_set_find_dim_by_id(set, isl_dim_param, id);
12736		isl_id_free(id);
12737		if (pos < 0)
12738			continue;
12739		set = isl_set_equate(set, isl_dim_param, pos, isl_dim_set, i);
12740		set = isl_set_project_out(set, isl_dim_param, pos, 1);
12741	}
12742	return set;
12743}
12744
12745/* Bind the set dimensions of "set" to parameters with identifiers
12746 * specified by "tuple", living in the same space as "set".
12747 *
12748 * If no parameters with these identifiers appear in "set" already,
12749 * then the set dimensions are simply reinterpreted as parameters.
12750 * Otherwise, the parameters are first equated to the corresponding
12751 * set dimensions.
12752 */
12753__isl_give isl_set *isl_set_bind(__isl_take isl_set *set,
12754	__isl_take isl_multi_id *tuple)
12755{
12756	isl_space *space;
12757
12758	set = equate_params(set, tuple);
12759	space = isl_set_get_space(set);
12760	space = isl_space_bind_set(space, tuple);
12761	isl_multi_id_free(tuple);
12762	set = isl_set_reset_space(set, space);
12763
12764	return set;
12765}
12766
12767/* Given a tuple of identifiers "tuple" in a space that corresponds
12768 * to the domain of "map", if any of those identifiers appear as parameters
12769 * in "map", then equate those parameters with the corresponding
12770 * input dimensions and project out the parameters.
12771 * The result therefore has no such parameters.
12772 */
12773static __isl_give isl_map *map_equate_params(__isl_take isl_map *map,
12774	__isl_keep isl_multi_id *tuple)
12775{
12776	int i;
12777	isl_size n;
12778	isl_space *map_space, *tuple_space;
12779
12780	map_space = isl_map_peek_space(map);
12781	tuple_space = isl_multi_id_peek_space(tuple);
12782	if (isl_space_check_domain_tuples(tuple_space, map_space) < 0)
12783		return isl_map_free(map);
12784	n = isl_multi_id_size(tuple);
12785	if (n < 0)
12786		return isl_map_free(map);
12787	for (i = 0; i < n; ++i) {
12788		isl_id *id;
12789		int pos;
12790
12791		id = isl_multi_id_get_at(tuple, i);
12792		if (!id)
12793			return isl_map_free(map);
12794		pos = isl_map_find_dim_by_id(map, isl_dim_param, id);
12795		isl_id_free(id);
12796		if (pos < 0)
12797			continue;
12798		map = isl_map_equate(map, isl_dim_param, pos, isl_dim_in, i);
12799		map = isl_map_project_out(map, isl_dim_param, pos, 1);
12800	}
12801	return map;
12802}
12803
12804/* Bind the input dimensions of "map" to parameters with identifiers
12805 * specified by "tuple", living in the domain space of "map".
12806 *
12807 * If no parameters with these identifiers appear in "map" already,
12808 * then the input dimensions are simply reinterpreted as parameters.
12809 * Otherwise, the parameters are first equated to the corresponding
12810 * input dimensions.
12811 */
12812__isl_give isl_set *isl_map_bind_domain(__isl_take isl_map *map,
12813	__isl_take isl_multi_id *tuple)
12814{
12815	isl_space *space;
12816	isl_set *set;
12817
12818	map = map_equate_params(map, tuple);
12819	space = isl_map_get_space(map);
12820	space = isl_space_bind_map_domain(space, tuple);
12821	isl_multi_id_free(tuple);
12822	set = set_from_map(isl_map_reset_space(map, space));
12823
12824	return set;
12825}
12826
12827/* Bind the output dimensions of "map" to parameters with identifiers
12828 * specified by "tuple", living in the range space of "map".
12829 *
12830 * Since binding is more easily implemented on the domain,
12831 * bind the input dimensions of the inverse of "map".
12832 */
12833__isl_give isl_set *isl_map_bind_range(__isl_take isl_map *map,
12834	__isl_take isl_multi_id *tuple)
12835{
12836	return isl_map_bind_domain(isl_map_reverse(map), tuple);
12837}
12838
12839/* Insert a domain corresponding to "tuple"
12840 * into the nullary or unary relation "set".
12841 * The result has an extra initial tuple and is therefore
12842 * either a unary or binary relation.
12843 * Any parameters with identifiers in "tuple" are reinterpreted
12844 * as the corresponding domain dimensions.
12845 */
12846static __isl_give isl_map *unbind_params_insert_domain(
12847	__isl_take isl_set *set, __isl_take isl_multi_id *tuple)
12848{
12849	isl_space *space;
12850	isl_reordering *r;
12851
12852	space = isl_set_peek_space(set);
12853	r = isl_reordering_unbind_params_insert_domain(space, tuple);
12854	isl_multi_id_free(tuple);
12855
12856	return isl_map_realign(set_to_map(set), r);
12857}
12858
12859/* Construct a set with "tuple" as domain from the parameter domain "set".
12860 * Any parameters with identifiers in "tuple" are reinterpreted
12861 * as the corresponding set dimensions.
12862 */
12863__isl_give isl_set *isl_set_unbind_params(__isl_take isl_set *set,
12864	__isl_take isl_multi_id *tuple)
12865{
12866	isl_bool is_params;
12867
12868	is_params = isl_set_is_params(set);
12869	if (is_params < 0)
12870		set = isl_set_free(set);
12871	else if (!is_params)
12872		isl_die(isl_set_get_ctx(set), isl_error_invalid,
12873			"expecting parameter domain", set = isl_set_free(set));
12874	return set_from_map(unbind_params_insert_domain(set, tuple));
12875}
12876
12877/* Check that "set" is a proper set, i.e., that it is not a parameter domain.
12878 */
12879static isl_stat isl_set_check_is_set(__isl_keep isl_set *set)
12880{
12881	isl_bool is_params;
12882
12883	is_params = isl_set_is_params(set);
12884	if (is_params < 0)
12885		return isl_stat_error;
12886	else if (is_params)
12887		isl_die(isl_set_get_ctx(set), isl_error_invalid,
12888			"expecting proper set", return isl_stat_error);
12889
12890	return isl_stat_ok;
12891}
12892
12893/* Construct a map with "domain" as domain and "set" as range.
12894 * Any parameters with identifiers in "domain" are reinterpreted
12895 * as the corresponding domain dimensions.
12896 */
12897__isl_give isl_map *isl_set_unbind_params_insert_domain(
12898	__isl_take isl_set *set, __isl_take isl_multi_id *domain)
12899{
12900	if (isl_set_check_is_set(set) < 0)
12901		set = isl_set_free(set);
12902	return unbind_params_insert_domain(set, domain);
12903}
12904
12905/* Construct a map with "domain" as domain and "set" as range.
12906 */
12907__isl_give isl_map *isl_set_insert_domain(__isl_take isl_set *set,
12908	__isl_take isl_space *domain)
12909{
12910	isl_size dim;
12911	isl_space *space;
12912	isl_map *map;
12913
12914	if (isl_set_check_is_set(set) < 0 || isl_space_check_is_set(domain) < 0)
12915		domain = isl_space_free(domain);
12916	dim = isl_space_dim(domain, isl_dim_set);
12917	if (dim < 0)
12918		domain = isl_space_free(domain);
12919	space = isl_set_get_space(set);
12920	domain = isl_space_replace_params(domain, space);
12921	space = isl_space_map_from_domain_and_range(domain, space);
12922
12923	map = isl_map_from_range(set);
12924	map = isl_map_add_dims(map, isl_dim_in, dim);
12925	map = isl_map_reset_space(map, space);
12926
12927	return map;
12928}
12929
12930__isl_give isl_mat *isl_basic_map_equalities_matrix(
12931		__isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
12932		enum isl_dim_type c2, enum isl_dim_type c3,
12933		enum isl_dim_type c4, enum isl_dim_type c5)
12934{
12935	enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12936	struct isl_mat *mat;
12937	int i, j, k;
12938	int pos;
12939	isl_size total;
12940
12941	total = isl_basic_map_dim(bmap, isl_dim_all);
12942	if (total < 0)
12943		return NULL;
12944	mat = isl_mat_alloc(bmap->ctx, bmap->n_eq, total + 1);
12945	if (!mat)
12946		return NULL;
12947	for (i = 0; i < bmap->n_eq; ++i)
12948		for (j = 0, pos = 0; j < 5; ++j) {
12949			int off = isl_basic_map_offset(bmap, c[j]);
12950			isl_size dim = isl_basic_map_dim(bmap, c[j]);
12951			if (dim < 0)
12952				return isl_mat_free(mat);
12953			for (k = 0; k < dim; ++k) {
12954				isl_int_set(mat->row[i][pos],
12955					    bmap->eq[i][off + k]);
12956				++pos;
12957			}
12958		}
12959
12960	return mat;
12961}
12962
12963__isl_give isl_mat *isl_basic_map_inequalities_matrix(
12964		__isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
12965		enum isl_dim_type c2, enum isl_dim_type c3,
12966		enum isl_dim_type c4, enum isl_dim_type c5)
12967{
12968	enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
12969	struct isl_mat *mat;
12970	int i, j, k;
12971	int pos;
12972	isl_size total;
12973
12974	total = isl_basic_map_dim(bmap, isl_dim_all);
12975	if (total < 0)
12976		return NULL;
12977	mat = isl_mat_alloc(bmap->ctx, bmap->n_ineq, total + 1);
12978	if (!mat)
12979		return NULL;
12980	for (i = 0; i < bmap->n_ineq; ++i)
12981		for (j = 0, pos = 0; j < 5; ++j) {
12982			int off = isl_basic_map_offset(bmap, c[j]);
12983			isl_size dim = isl_basic_map_dim(bmap, c[j]);
12984			if (dim < 0)
12985				return isl_mat_free(mat);
12986			for (k = 0; k < dim; ++k) {
12987				isl_int_set(mat->row[i][pos],
12988					    bmap->ineq[i][off + k]);
12989				++pos;
12990			}
12991		}
12992
12993	return mat;
12994}
12995
12996__isl_give isl_basic_map *isl_basic_map_from_constraint_matrices(
12997	__isl_take isl_space *space,
12998	__isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
12999	enum isl_dim_type c2, enum isl_dim_type c3,
13000	enum isl_dim_type c4, enum isl_dim_type c5)
13001{
13002	enum isl_dim_type c[5] = { c1, c2, c3, c4, c5 };
13003	isl_basic_map *bmap = NULL;
13004	isl_size dim;
13005	unsigned total;
13006	unsigned extra;
13007	int i, j, k, l;
13008	int pos;
13009
13010	dim = isl_space_dim(space, isl_dim_all);
13011	if (dim < 0 || !eq || !ineq)
13012		goto error;
13013
13014	if (eq->n_col != ineq->n_col)
13015		isl_die(space->ctx, isl_error_invalid,
13016			"equalities and inequalities matrices should have "
13017			"same number of columns", goto error);
13018
13019	total = 1 + dim;
13020
13021	if (eq->n_col < total)
13022		isl_die(space->ctx, isl_error_invalid,
13023			"number of columns too small", goto error);
13024
13025	extra = eq->n_col - total;
13026
13027	bmap = isl_basic_map_alloc_space(isl_space_copy(space), extra,
13028				       eq->n_row, ineq->n_row);
13029	if (!bmap)
13030		goto error;
13031	for (i = 0; i < extra; ++i) {
13032		k = isl_basic_map_alloc_div(bmap);
13033		if (k < 0)
13034			goto error;
13035		isl_int_set_si(bmap->div[k][0], 0);
13036	}
13037	for (i = 0; i < eq->n_row; ++i) {
13038		l = isl_basic_map_alloc_equality(bmap);
13039		if (l < 0)
13040			goto error;
13041		for (j = 0, pos = 0; j < 5; ++j) {
13042			int off = isl_basic_map_offset(bmap, c[j]);
13043			isl_size dim = isl_basic_map_dim(bmap, c[j]);
13044			if (dim < 0)
13045				goto error;
13046			for (k = 0; k < dim; ++k) {
13047				isl_int_set(bmap->eq[l][off + k],
13048					    eq->row[i][pos]);
13049				++pos;
13050			}
13051		}
13052	}
13053	for (i = 0; i < ineq->n_row; ++i) {
13054		l = isl_basic_map_alloc_inequality(bmap);
13055		if (l < 0)
13056			goto error;
13057		for (j = 0, pos = 0; j < 5; ++j) {
13058			int off = isl_basic_map_offset(bmap, c[j]);
13059			isl_size dim = isl_basic_map_dim(bmap, c[j]);
13060			if (dim < 0)
13061				goto error;
13062			for (k = 0; k < dim; ++k) {
13063				isl_int_set(bmap->ineq[l][off + k],
13064					    ineq->row[i][pos]);
13065				++pos;
13066			}
13067		}
13068	}
13069
13070	isl_space_free(space);
13071	isl_mat_free(eq);
13072	isl_mat_free(ineq);
13073
13074	bmap = isl_basic_map_simplify(bmap);
13075	return isl_basic_map_finalize(bmap);
13076error:
13077	isl_space_free(space);
13078	isl_mat_free(eq);
13079	isl_mat_free(ineq);
13080	isl_basic_map_free(bmap);
13081	return NULL;
13082}
13083
13084__isl_give isl_mat *isl_basic_set_equalities_matrix(
13085	__isl_keep isl_basic_set *bset, enum isl_dim_type c1,
13086	enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
13087{
13088	return isl_basic_map_equalities_matrix(bset_to_bmap(bset),
13089						c1, c2, c3, c4, isl_dim_in);
13090}
13091
13092__isl_give isl_mat *isl_basic_set_inequalities_matrix(
13093	__isl_keep isl_basic_set *bset, enum isl_dim_type c1,
13094	enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
13095{
13096	return isl_basic_map_inequalities_matrix(bset_to_bmap(bset),
13097						 c1, c2, c3, c4, isl_dim_in);
13098}
13099
13100__isl_give isl_basic_set *isl_basic_set_from_constraint_matrices(
13101	__isl_take isl_space *space,
13102	__isl_take isl_mat *eq, __isl_take isl_mat *ineq, enum isl_dim_type c1,
13103	enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4)
13104{
13105	isl_basic_map *bmap;
13106	bmap = isl_basic_map_from_constraint_matrices(space, eq, ineq,
13107						   c1, c2, c3, c4, isl_dim_in);
13108	return bset_from_bmap(bmap);
13109}
13110
13111isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap)
13112{
13113	if (!bmap)
13114		return isl_bool_error;
13115
13116	return isl_space_can_zip(bmap->dim);
13117}
13118
13119isl_bool isl_map_can_zip(__isl_keep isl_map *map)
13120{
13121	if (!map)
13122		return isl_bool_error;
13123
13124	return isl_space_can_zip(map->dim);
13125}
13126
13127/* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map
13128 * (A -> C) -> (B -> D).
13129 */
13130__isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
13131{
13132	unsigned pos;
13133	isl_size n_in;
13134	isl_size n1;
13135	isl_size n2;
13136
13137	if (!bmap)
13138		return NULL;
13139
13140	if (!isl_basic_map_can_zip(bmap))
13141		isl_die(bmap->ctx, isl_error_invalid,
13142			"basic map cannot be zipped", goto error);
13143	n_in = isl_space_dim(bmap->dim->nested[0], isl_dim_in);
13144	n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
13145	n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
13146	if (n_in < 0 || n1 < 0 || n2 < 0)
13147		return isl_basic_map_free(bmap);
13148	pos = isl_basic_map_offset(bmap, isl_dim_in) + n_in;
13149	bmap = isl_basic_map_cow(bmap);
13150	bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
13151	if (!bmap)
13152		return NULL;
13153	bmap->dim = isl_space_zip(bmap->dim);
13154	if (!bmap->dim)
13155		goto error;
13156	bmap = isl_basic_map_mark_final(bmap);
13157	return bmap;
13158error:
13159	isl_basic_map_free(bmap);
13160	return NULL;
13161}
13162
13163/* Given a map (A -> B) -> (C -> D), return the corresponding map
13164 * (A -> C) -> (B -> D).
13165 */
13166__isl_give isl_map *isl_map_zip(__isl_take isl_map *map)
13167{
13168	if (!map)
13169		return NULL;
13170
13171	if (!isl_map_can_zip(map))
13172		isl_die(map->ctx, isl_error_invalid, "map cannot be zipped",
13173			goto error);
13174
13175	return isl_map_transform(map, &isl_space_zip, &isl_basic_map_zip);
13176error:
13177	isl_map_free(map);
13178	return NULL;
13179}
13180
13181/* Can we apply isl_basic_map_curry to "bmap"?
13182 * That is, does it have a nested relation in its domain?
13183 */
13184isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap)
13185{
13186	if (!bmap)
13187		return isl_bool_error;
13188
13189	return isl_space_can_curry(bmap->dim);
13190}
13191
13192/* Can we apply isl_map_curry to "map"?
13193 * That is, does it have a nested relation in its domain?
13194 */
13195isl_bool isl_map_can_curry(__isl_keep isl_map *map)
13196{
13197	if (!map)
13198		return isl_bool_error;
13199
13200	return isl_space_can_curry(map->dim);
13201}
13202
13203/* Given a basic map (A -> B) -> C, return the corresponding basic map
13204 * A -> (B -> C).
13205 */
13206__isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
13207{
13208
13209	if (!bmap)
13210		return NULL;
13211
13212	if (!isl_basic_map_can_curry(bmap))
13213		isl_die(bmap->ctx, isl_error_invalid,
13214			"basic map cannot be curried", goto error);
13215	bmap = isl_basic_map_cow(bmap);
13216	if (!bmap)
13217		return NULL;
13218	bmap->dim = isl_space_curry(bmap->dim);
13219	if (!bmap->dim)
13220		goto error;
13221	bmap = isl_basic_map_mark_final(bmap);
13222	return bmap;
13223error:
13224	isl_basic_map_free(bmap);
13225	return NULL;
13226}
13227
13228/* Given a map (A -> B) -> C, return the corresponding map
13229 * A -> (B -> C).
13230 */
13231__isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
13232{
13233	return isl_map_change_space(map, &isl_map_can_curry,
13234				    "map cannot be curried", &isl_space_curry);
13235}
13236
13237/* Can isl_map_range_curry be applied to "map"?
13238 * That is, does it have a nested relation in its range,
13239 * the domain of which is itself a nested relation?
13240 */
13241isl_bool isl_map_can_range_curry(__isl_keep isl_map *map)
13242{
13243	if (!map)
13244		return isl_bool_error;
13245
13246	return isl_space_can_range_curry(map->dim);
13247}
13248
13249/* Given a map A -> ((B -> C) -> D), return the corresponding map
13250 * A -> (B -> (C -> D)).
13251 */
13252__isl_give isl_map *isl_map_range_curry(__isl_take isl_map *map)
13253{
13254	return isl_map_change_space(map, &isl_map_can_range_curry,
13255				    "map range cannot be curried",
13256				    &isl_space_range_curry);
13257}
13258
13259/* Can we apply isl_basic_map_uncurry to "bmap"?
13260 * That is, does it have a nested relation in its domain?
13261 */
13262isl_bool isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap)
13263{
13264	if (!bmap)
13265		return isl_bool_error;
13266
13267	return isl_space_can_uncurry(bmap->dim);
13268}
13269
13270/* Can we apply isl_map_uncurry to "map"?
13271 * That is, does it have a nested relation in its domain?
13272 */
13273isl_bool isl_map_can_uncurry(__isl_keep isl_map *map)
13274{
13275	if (!map)
13276		return isl_bool_error;
13277
13278	return isl_space_can_uncurry(map->dim);
13279}
13280
13281/* Given a basic map A -> (B -> C), return the corresponding basic map
13282 * (A -> B) -> C.
13283 */
13284__isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
13285{
13286
13287	if (!bmap)
13288		return NULL;
13289
13290	if (!isl_basic_map_can_uncurry(bmap))
13291		isl_die(bmap->ctx, isl_error_invalid,
13292			"basic map cannot be uncurried",
13293			return isl_basic_map_free(bmap));
13294	bmap = isl_basic_map_cow(bmap);
13295	if (!bmap)
13296		return NULL;
13297	bmap->dim = isl_space_uncurry(bmap->dim);
13298	if (!bmap->dim)
13299		return isl_basic_map_free(bmap);
13300	bmap = isl_basic_map_mark_final(bmap);
13301	return bmap;
13302}
13303
13304/* Given a map A -> (B -> C), return the corresponding map
13305 * (A -> B) -> C.
13306 */
13307__isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map)
13308{
13309	return isl_map_change_space(map, &isl_map_can_uncurry,
13310				"map cannot be uncurried", &isl_space_uncurry);
13311}
13312
13313__isl_give isl_set *isl_set_equate(__isl_take isl_set *set,
13314	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13315{
13316	return isl_map_equate(set, type1, pos1, type2, pos2);
13317}
13318
13319/* Construct a basic map where the given dimensions are equal to each other.
13320 */
13321static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
13322	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13323{
13324	isl_basic_map *bmap = NULL;
13325	int i;
13326	isl_size total;
13327
13328	total = isl_space_dim(space, isl_dim_all);
13329	if (total < 0 ||
13330	    isl_space_check_range(space, type1, pos1, 1) < 0 ||
13331	    isl_space_check_range(space, type2, pos2, 1) < 0)
13332		goto error;
13333
13334	if (type1 == type2 && pos1 == pos2)
13335		return isl_basic_map_universe(space);
13336
13337	bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
13338	i = isl_basic_map_alloc_equality(bmap);
13339	if (i < 0)
13340		goto error;
13341	isl_seq_clr(bmap->eq[i], 1 + total);
13342	pos1 += isl_basic_map_offset(bmap, type1);
13343	pos2 += isl_basic_map_offset(bmap, type2);
13344	isl_int_set_si(bmap->eq[i][pos1], -1);
13345	isl_int_set_si(bmap->eq[i][pos2], 1);
13346	bmap = isl_basic_map_finalize(bmap);
13347	isl_space_free(space);
13348	return bmap;
13349error:
13350	isl_space_free(space);
13351	isl_basic_map_free(bmap);
13352	return NULL;
13353}
13354
13355/* Add a constraint imposing that the given two dimensions are equal.
13356 */
13357__isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap,
13358	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13359{
13360	isl_basic_map *eq;
13361
13362	eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
13363
13364	bmap = isl_basic_map_intersect(bmap, eq);
13365
13366	return bmap;
13367}
13368
13369/* Add a constraint imposing that the given two dimensions are equal.
13370 */
13371__isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
13372	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13373{
13374	isl_basic_map *bmap;
13375
13376	bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2);
13377
13378	map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13379
13380	return map;
13381}
13382
13383/* Add a constraint imposing that the given two dimensions have opposite values.
13384 */
13385__isl_give isl_map *isl_map_oppose(__isl_take isl_map *map,
13386	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13387{
13388	isl_basic_map *bmap = NULL;
13389	int i;
13390	isl_size total;
13391
13392	if (isl_map_check_range(map, type1, pos1, 1) < 0)
13393		return isl_map_free(map);
13394	if (isl_map_check_range(map, type2, pos2, 1) < 0)
13395		return isl_map_free(map);
13396
13397	total = isl_map_dim(map, isl_dim_all);
13398	if (total < 0)
13399		return isl_map_free(map);
13400	bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
13401	i = isl_basic_map_alloc_equality(bmap);
13402	if (i < 0)
13403		goto error;
13404	isl_seq_clr(bmap->eq[i], 1 + total);
13405	pos1 += isl_basic_map_offset(bmap, type1);
13406	pos2 += isl_basic_map_offset(bmap, type2);
13407	isl_int_set_si(bmap->eq[i][pos1], 1);
13408	isl_int_set_si(bmap->eq[i][pos2], 1);
13409	bmap = isl_basic_map_finalize(bmap);
13410
13411	map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13412
13413	return map;
13414error:
13415	isl_basic_map_free(bmap);
13416	isl_map_free(map);
13417	return NULL;
13418}
13419
13420/* Construct a constraint imposing that the value of the first dimension is
13421 * greater than or equal to that of the second.
13422 */
13423static __isl_give isl_constraint *constraint_order_ge(
13424	__isl_take isl_space *space, enum isl_dim_type type1, int pos1,
13425	enum isl_dim_type type2, int pos2)
13426{
13427	isl_constraint *c;
13428
13429	if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
13430	    isl_space_check_range(space, type2, pos2, 1) < 0)
13431		space = isl_space_free(space);
13432	if (!space)
13433		return NULL;
13434
13435	c = isl_constraint_alloc_inequality(isl_local_space_from_space(space));
13436
13437	if (type1 == type2 && pos1 == pos2)
13438		return c;
13439
13440	c = isl_constraint_set_coefficient_si(c, type1, pos1, 1);
13441	c = isl_constraint_set_coefficient_si(c, type2, pos2, -1);
13442
13443	return c;
13444}
13445
13446/* Add a constraint imposing that the value of the first dimension is
13447 * greater than or equal to that of the second.
13448 */
13449__isl_give isl_basic_map *isl_basic_map_order_ge(__isl_take isl_basic_map *bmap,
13450	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13451{
13452	isl_constraint *c;
13453	isl_space *space;
13454
13455	if (type1 == type2 && pos1 == pos2)
13456		return bmap;
13457	space = isl_basic_map_get_space(bmap);
13458	c = constraint_order_ge(space, type1, pos1, type2, pos2);
13459	bmap = isl_basic_map_add_constraint(bmap, c);
13460
13461	return bmap;
13462}
13463
13464/* Add a constraint imposing that the value of the first dimension is
13465 * greater than or equal to that of the second.
13466 */
13467__isl_give isl_map *isl_map_order_ge(__isl_take isl_map *map,
13468	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13469{
13470	isl_constraint *c;
13471	isl_space *space;
13472
13473	if (type1 == type2 && pos1 == pos2)
13474		return map;
13475	space = isl_map_get_space(map);
13476	c = constraint_order_ge(space, type1, pos1, type2, pos2);
13477	map = isl_map_add_constraint(map, c);
13478
13479	return map;
13480}
13481
13482/* Add a constraint imposing that the value of the first dimension is
13483 * less than or equal to that of the second.
13484 */
13485__isl_give isl_map *isl_map_order_le(__isl_take isl_map *map,
13486	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13487{
13488	return isl_map_order_ge(map, type2, pos2, type1, pos1);
13489}
13490
13491/* Construct a basic map where the value of the first dimension is
13492 * greater than that of the second.
13493 */
13494static __isl_give isl_basic_map *greator(__isl_take isl_space *space,
13495	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13496{
13497	isl_basic_map *bmap = NULL;
13498	int i;
13499	isl_size total;
13500
13501	if (isl_space_check_range(space, type1, pos1, 1) < 0 ||
13502	    isl_space_check_range(space, type2, pos2, 1) < 0)
13503		goto error;
13504
13505	if (type1 == type2 && pos1 == pos2)
13506		return isl_basic_map_empty(space);
13507
13508	bmap = isl_basic_map_alloc_space(space, 0, 0, 1);
13509	total = isl_basic_map_dim(bmap, isl_dim_all);
13510	i = isl_basic_map_alloc_inequality(bmap);
13511	if (total < 0 || i < 0)
13512		return isl_basic_map_free(bmap);
13513	isl_seq_clr(bmap->ineq[i], 1 + total);
13514	pos1 += isl_basic_map_offset(bmap, type1);
13515	pos2 += isl_basic_map_offset(bmap, type2);
13516	isl_int_set_si(bmap->ineq[i][pos1], 1);
13517	isl_int_set_si(bmap->ineq[i][pos2], -1);
13518	isl_int_set_si(bmap->ineq[i][0], -1);
13519	bmap = isl_basic_map_finalize(bmap);
13520
13521	return bmap;
13522error:
13523	isl_space_free(space);
13524	isl_basic_map_free(bmap);
13525	return NULL;
13526}
13527
13528/* Add a constraint imposing that the value of the first dimension is
13529 * greater than that of the second.
13530 */
13531__isl_give isl_basic_map *isl_basic_map_order_gt(__isl_take isl_basic_map *bmap,
13532	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13533{
13534	isl_basic_map *gt;
13535
13536	gt = greator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
13537
13538	bmap = isl_basic_map_intersect(bmap, gt);
13539
13540	return bmap;
13541}
13542
13543/* Add a constraint imposing that the value of the first dimension is
13544 * greater than that of the second.
13545 */
13546__isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map,
13547	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13548{
13549	isl_basic_map *bmap;
13550
13551	bmap = greator(isl_map_get_space(map), type1, pos1, type2, pos2);
13552
13553	map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
13554
13555	return map;
13556}
13557
13558/* Add a constraint imposing that the value of the first dimension is
13559 * smaller than that of the second.
13560 */
13561__isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map,
13562	enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
13563{
13564	return isl_map_order_gt(map, type2, pos2, type1, pos1);
13565}
13566
13567__isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
13568	int pos)
13569{
13570	isl_aff *div;
13571	isl_local_space *ls;
13572
13573	if (!bmap)
13574		return NULL;
13575
13576	if (!isl_basic_map_divs_known(bmap))
13577		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
13578			"some divs are unknown", return NULL);
13579
13580	ls = isl_basic_map_get_local_space(bmap);
13581	div = isl_local_space_get_div(ls, pos);
13582	isl_local_space_free(ls);
13583
13584	return div;
13585}
13586
13587__isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset,
13588	int pos)
13589{
13590	return isl_basic_map_get_div(bset, pos);
13591}
13592
13593/* Plug in "subs" for set dimension "pos" of "set".
13594 */
13595__isl_give isl_set *isl_set_substitute(__isl_take isl_set *set,
13596	unsigned pos, __isl_keep isl_aff *subs)
13597{
13598	isl_multi_aff *ma;
13599
13600	if (set && isl_set_plain_is_empty(set))
13601		return set;
13602
13603	ma = isl_multi_aff_identity_on_domain_space(isl_set_get_space(set));
13604	ma = isl_multi_aff_set_aff(ma, pos, isl_aff_copy(subs));
13605	return isl_set_preimage_multi_aff(set, ma);
13606}
13607
13608/* Check if the range of "ma" is compatible with the domain or range
13609 * (depending on "type") of "bmap".
13610 */
13611static isl_stat check_basic_map_compatible_range_multi_aff(
13612	__isl_keep isl_basic_map *bmap, enum isl_dim_type type,
13613	__isl_keep isl_multi_aff *ma)
13614{
13615	isl_bool m;
13616	isl_space *ma_space;
13617
13618	ma_space = isl_multi_aff_get_space(ma);
13619
13620	m = isl_space_has_equal_params(bmap->dim, ma_space);
13621	if (m < 0)
13622		goto error;
13623	if (!m)
13624		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
13625			"parameters don't match", goto error);
13626	m = isl_space_tuple_is_equal(bmap->dim, type, ma_space, isl_dim_out);
13627	if (m < 0)
13628		goto error;
13629	if (!m)
13630		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
13631			"spaces don't match", goto error);
13632
13633	isl_space_free(ma_space);
13634	return isl_stat_ok;
13635error:
13636	isl_space_free(ma_space);
13637	return isl_stat_error;
13638}
13639
13640/* Copy the divs from "ma" to "bmap", adding zeros for the "n_before"
13641 * coefficients before the transformed range of dimensions,
13642 * the "n_after" coefficients after the transformed range of dimensions
13643 * and the coefficients of the other divs in "bmap".
13644 */
13645static __isl_give isl_basic_map *set_ma_divs(__isl_take isl_basic_map *bmap,
13646	__isl_keep isl_multi_aff *ma, int n_before, int n_after, int n_div)
13647{
13648	int i;
13649	isl_size n_param;
13650	isl_size n_set;
13651	isl_local_space *ls;
13652
13653	if (n_div == 0)
13654		return bmap;
13655
13656	ls = isl_aff_get_domain_local_space(ma->u.p[0]);
13657	n_param = isl_local_space_dim(ls, isl_dim_param);
13658	n_set = isl_local_space_dim(ls, isl_dim_set);
13659	if (n_param < 0 || n_set < 0)
13660		return isl_basic_map_free(bmap);
13661
13662	for (i = 0; i < n_div; ++i) {
13663		int o_bmap = 0, o_ls = 0;
13664
13665		isl_seq_cpy(bmap->div[i], ls->div->row[i], 1 + 1 + n_param);
13666		o_bmap += 1 + 1 + n_param;
13667		o_ls += 1 + 1 + n_param;
13668		isl_seq_clr(bmap->div[i] + o_bmap, n_before);
13669		o_bmap += n_before;
13670		isl_seq_cpy(bmap->div[i] + o_bmap,
13671			    ls->div->row[i] + o_ls, n_set);
13672		o_bmap += n_set;
13673		o_ls += n_set;
13674		isl_seq_clr(bmap->div[i] + o_bmap, n_after);
13675		o_bmap += n_after;
13676		isl_seq_cpy(bmap->div[i] + o_bmap,
13677			    ls->div->row[i] + o_ls, n_div);
13678		o_bmap += n_div;
13679		o_ls += n_div;
13680		isl_seq_clr(bmap->div[i] + o_bmap, bmap->n_div - n_div);
13681		bmap = isl_basic_map_add_div_constraints(bmap, i);
13682		if (!bmap)
13683			goto error;
13684	}
13685
13686	isl_local_space_free(ls);
13687	return bmap;
13688error:
13689	isl_local_space_free(ls);
13690	return isl_basic_map_free(bmap);
13691}
13692
13693/* How many stride constraints does "ma" enforce?
13694 * That is, how many of the affine expressions have a denominator
13695 * different from one?
13696 */
13697static int multi_aff_strides(__isl_keep isl_multi_aff *ma)
13698{
13699	int i;
13700	int strides = 0;
13701
13702	for (i = 0; i < ma->n; ++i)
13703		if (!isl_int_is_one(ma->u.p[i]->v->el[0]))
13704			strides++;
13705
13706	return strides;
13707}
13708
13709/* For each affine expression in ma of the form
13710 *
13711 *	x_i = (f_i y + h_i)/m_i
13712 *
13713 * with m_i different from one, add a constraint to "bmap"
13714 * of the form
13715 *
13716 *	f_i y + h_i = m_i alpha_i
13717 *
13718 * with alpha_i an additional existentially quantified variable.
13719 *
13720 * The input variables of "ma" correspond to a subset of the variables
13721 * of "bmap".  There are "n_before" variables in "bmap" before this
13722 * subset and "n_after" variables after this subset.
13723 * The integer divisions of the affine expressions in "ma" are assumed
13724 * to have been aligned.  There are "n_div_ma" of them and
13725 * they appear first in "bmap", straight after the "n_after" variables.
13726 */
13727static __isl_give isl_basic_map *add_ma_strides(
13728	__isl_take isl_basic_map *bmap, __isl_keep isl_multi_aff *ma,
13729	int n_before, int n_after, int n_div_ma)
13730{
13731	int i, k;
13732	int div;
13733	isl_size total;
13734	isl_size n_param;
13735	isl_size n_in;
13736
13737	total = isl_basic_map_dim(bmap, isl_dim_all);
13738	n_param = isl_multi_aff_dim(ma, isl_dim_param);
13739	n_in = isl_multi_aff_dim(ma, isl_dim_in);
13740	if (total < 0 || n_param < 0 || n_in < 0)
13741		return isl_basic_map_free(bmap);
13742	for (i = 0; i < ma->n; ++i) {
13743		int o_bmap = 0, o_ma = 1;
13744
13745		if (isl_int_is_one(ma->u.p[i]->v->el[0]))
13746			continue;
13747		div = isl_basic_map_alloc_div(bmap);
13748		k = isl_basic_map_alloc_equality(bmap);
13749		if (div < 0 || k < 0)
13750			goto error;
13751		isl_int_set_si(bmap->div[div][0], 0);
13752		isl_seq_cpy(bmap->eq[k] + o_bmap,
13753			    ma->u.p[i]->v->el + o_ma, 1 + n_param);
13754		o_bmap += 1 + n_param;
13755		o_ma += 1 + n_param;
13756		isl_seq_clr(bmap->eq[k] + o_bmap, n_before);
13757		o_bmap += n_before;
13758		isl_seq_cpy(bmap->eq[k] + o_bmap,
13759			    ma->u.p[i]->v->el + o_ma, n_in);
13760		o_bmap += n_in;
13761		o_ma += n_in;
13762		isl_seq_clr(bmap->eq[k] + o_bmap, n_after);
13763		o_bmap += n_after;
13764		isl_seq_cpy(bmap->eq[k] + o_bmap,
13765			    ma->u.p[i]->v->el + o_ma, n_div_ma);
13766		o_bmap += n_div_ma;
13767		o_ma += n_div_ma;
13768		isl_seq_clr(bmap->eq[k] + o_bmap, 1 + total - o_bmap);
13769		isl_int_neg(bmap->eq[k][1 + total], ma->u.p[i]->v->el[0]);
13770		total++;
13771	}
13772
13773	return bmap;
13774error:
13775	isl_basic_map_free(bmap);
13776	return NULL;
13777}
13778
13779/* Replace the domain or range space (depending on "type) of "space" by "set".
13780 */
13781static __isl_give isl_space *isl_space_set(__isl_take isl_space *space,
13782	enum isl_dim_type type, __isl_take isl_space *set)
13783{
13784	if (type == isl_dim_in) {
13785		space = isl_space_range(space);
13786		space = isl_space_map_from_domain_and_range(set, space);
13787	} else {
13788		space = isl_space_domain(space);
13789		space = isl_space_map_from_domain_and_range(space, set);
13790	}
13791
13792	return space;
13793}
13794
13795/* Compute the preimage of the domain or range (depending on "type")
13796 * of "bmap" under the function represented by "ma".
13797 * In other words, plug in "ma" in the domain or range of "bmap".
13798 * The result is a basic map that lives in the same space as "bmap"
13799 * except that the domain or range has been replaced by
13800 * the domain space of "ma".
13801 *
13802 * If bmap is represented by
13803 *
13804 *	A(p) + S u + B x + T v + C(divs) >= 0,
13805 *
13806 * where u and x are input and output dimensions if type == isl_dim_out
13807 * while x and v are input and output dimensions if type == isl_dim_in,
13808 * and ma is represented by
13809 *
13810 *	x = D(p) + F(y) + G(divs')
13811 *
13812 * then the result is
13813 *
13814 *	A(p) + B D(p) + S u + B F(y) + T v + B G(divs') + C(divs) >= 0
13815 *
13816 * The divs in the input set are similarly adjusted.
13817 * In particular
13818 *
13819 *	floor((a_i(p) + s u + b_i x + t v + c_i(divs))/n_i)
13820 *
13821 * becomes
13822 *
13823 *	floor((a_i(p) + b_i D(p) + s u + b_i F(y) + t v +
13824 *		B_i G(divs') + c_i(divs))/n_i)
13825 *
13826 * If bmap is not a rational map and if F(y) involves any denominators
13827 *
13828 *	x_i = (f_i y + h_i)/m_i
13829 *
13830 * then additional constraints are added to ensure that we only
13831 * map back integer points.  That is we enforce
13832 *
13833 *	f_i y + h_i = m_i alpha_i
13834 *
13835 * with alpha_i an additional existentially quantified variable.
13836 *
13837 * We first copy over the divs from "ma".
13838 * Then we add the modified constraints and divs from "bmap".
13839 * Finally, we add the stride constraints, if needed.
13840 */
13841__isl_give isl_basic_map *isl_basic_map_preimage_multi_aff(
13842	__isl_take isl_basic_map *bmap, enum isl_dim_type type,
13843	__isl_take isl_multi_aff *ma)
13844{
13845	int i, k;
13846	isl_space *space;
13847	isl_basic_map *res = NULL;
13848	isl_size n_before, n_after, n_div_bmap, n_div_ma;
13849	isl_int f, c1, c2, g;
13850	isl_bool rational;
13851	int strides;
13852
13853	isl_int_init(f);
13854	isl_int_init(c1);
13855	isl_int_init(c2);
13856	isl_int_init(g);
13857
13858	ma = isl_multi_aff_align_divs(ma);
13859	if (!bmap || !ma)
13860		goto error;
13861	if (check_basic_map_compatible_range_multi_aff(bmap, type, ma) < 0)
13862		goto error;
13863
13864	if (type == isl_dim_in) {
13865		n_before = 0;
13866		n_after = isl_basic_map_dim(bmap, isl_dim_out);
13867	} else {
13868		n_before = isl_basic_map_dim(bmap, isl_dim_in);
13869		n_after = 0;
13870	}
13871	n_div_bmap = isl_basic_map_dim(bmap, isl_dim_div);
13872	n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0;
13873	if (n_before < 0 || n_after < 0 || n_div_bmap < 0 || n_div_ma < 0)
13874		goto error;
13875
13876	space = isl_multi_aff_get_domain_space(ma);
13877	space = isl_space_set(isl_basic_map_get_space(bmap), type, space);
13878	rational = isl_basic_map_is_rational(bmap);
13879	strides = rational ? 0 : multi_aff_strides(ma);
13880	res = isl_basic_map_alloc_space(space, n_div_ma + n_div_bmap + strides,
13881			    bmap->n_eq + strides, bmap->n_ineq + 2 * n_div_ma);
13882	if (rational)
13883		res = isl_basic_map_set_rational(res);
13884
13885	for (i = 0; i < n_div_ma + n_div_bmap; ++i)
13886		if (isl_basic_map_alloc_div(res) < 0)
13887			goto error;
13888
13889	res = set_ma_divs(res, ma, n_before, n_after, n_div_ma);
13890	if (!res)
13891		goto error;
13892
13893	for (i = 0; i < bmap->n_eq; ++i) {
13894		k = isl_basic_map_alloc_equality(res);
13895		if (k < 0)
13896			goto error;
13897		if (isl_seq_preimage(res->eq[k], bmap->eq[i], ma, n_before,
13898				    n_after, n_div_ma, n_div_bmap,
13899				    f, c1, c2, g, 0) < 0)
13900			goto error;
13901	}
13902
13903	for (i = 0; i < bmap->n_ineq; ++i) {
13904		k = isl_basic_map_alloc_inequality(res);
13905		if (k < 0)
13906			goto error;
13907		if (isl_seq_preimage(res->ineq[k], bmap->ineq[i], ma, n_before,
13908				    n_after, n_div_ma, n_div_bmap,
13909				    f, c1, c2, g, 0) < 0)
13910			goto error;
13911	}
13912
13913	for (i = 0; i < bmap->n_div; ++i) {
13914		if (isl_int_is_zero(bmap->div[i][0])) {
13915			isl_int_set_si(res->div[n_div_ma + i][0], 0);
13916			continue;
13917		}
13918		if (isl_seq_preimage(res->div[n_div_ma + i], bmap->div[i], ma,
13919				    n_before, n_after, n_div_ma, n_div_bmap,
13920				    f, c1, c2, g, 1) < 0)
13921			goto error;
13922	}
13923
13924	if (strides)
13925		res = add_ma_strides(res, ma, n_before, n_after, n_div_ma);
13926
13927	isl_int_clear(f);
13928	isl_int_clear(c1);
13929	isl_int_clear(c2);
13930	isl_int_clear(g);
13931	isl_basic_map_free(bmap);
13932	isl_multi_aff_free(ma);
13933	res = isl_basic_map_simplify(res);
13934	return isl_basic_map_finalize(res);
13935error:
13936	isl_int_clear(f);
13937	isl_int_clear(c1);
13938	isl_int_clear(c2);
13939	isl_int_clear(g);
13940	isl_basic_map_free(bmap);
13941	isl_multi_aff_free(ma);
13942	isl_basic_map_free(res);
13943	return NULL;
13944}
13945
13946/* Compute the preimage of "bset" under the function represented by "ma".
13947 * In other words, plug in "ma" in "bset".  The result is a basic set
13948 * that lives in the domain space of "ma".
13949 */
13950__isl_give isl_basic_set *isl_basic_set_preimage_multi_aff(
13951	__isl_take isl_basic_set *bset, __isl_take isl_multi_aff *ma)
13952{
13953	return isl_basic_map_preimage_multi_aff(bset, isl_dim_set, ma);
13954}
13955
13956/* Compute the preimage of the domain of "bmap" under the function
13957 * represented by "ma".
13958 * In other words, plug in "ma" in the domain of "bmap".
13959 * The result is a basic map that lives in the same space as "bmap"
13960 * except that the domain has been replaced by the domain space of "ma".
13961 */
13962__isl_give isl_basic_map *isl_basic_map_preimage_domain_multi_aff(
13963	__isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
13964{
13965	return isl_basic_map_preimage_multi_aff(bmap, isl_dim_in, ma);
13966}
13967
13968/* Compute the preimage of the range of "bmap" under the function
13969 * represented by "ma".
13970 * In other words, plug in "ma" in the range of "bmap".
13971 * The result is a basic map that lives in the same space as "bmap"
13972 * except that the range has been replaced by the domain space of "ma".
13973 */
13974__isl_give isl_basic_map *isl_basic_map_preimage_range_multi_aff(
13975	__isl_take isl_basic_map *bmap, __isl_take isl_multi_aff *ma)
13976{
13977	return isl_basic_map_preimage_multi_aff(bmap, isl_dim_out, ma);
13978}
13979
13980/* Check if the range of "ma" is compatible with the domain or range
13981 * (depending on "type") of "map".
13982 * Return isl_stat_error if anything is wrong.
13983 */
13984static isl_stat check_map_compatible_range_multi_aff(
13985	__isl_keep isl_map *map, enum isl_dim_type type,
13986	__isl_keep isl_multi_aff *ma)
13987{
13988	isl_bool m;
13989	isl_space *ma_space;
13990
13991	ma_space = isl_multi_aff_get_space(ma);
13992	m = isl_map_space_tuple_is_equal(map, type, ma_space, isl_dim_out);
13993	isl_space_free(ma_space);
13994	if (m < 0)
13995		return isl_stat_error;
13996	if (!m)
13997		isl_die(isl_map_get_ctx(map), isl_error_invalid,
13998			"spaces don't match", return isl_stat_error);
13999	return isl_stat_ok;
14000}
14001
14002/* Compute the preimage of the domain or range (depending on "type")
14003 * of "map" under the function represented by "ma".
14004 * In other words, plug in "ma" in the domain or range of "map".
14005 * The result is a map that lives in the same space as "map"
14006 * except that the domain or range has been replaced by
14007 * the domain space of "ma".
14008 *
14009 * The parameters are assumed to have been aligned.
14010 */
14011static __isl_give isl_map *map_preimage_multi_aff(__isl_take isl_map *map,
14012	enum isl_dim_type type, __isl_take isl_multi_aff *ma)
14013{
14014	int i;
14015	isl_space *space;
14016
14017	map = isl_map_cow(map);
14018	ma = isl_multi_aff_align_divs(ma);
14019	if (!map || !ma)
14020		goto error;
14021	if (check_map_compatible_range_multi_aff(map, type, ma) < 0)
14022		goto error;
14023
14024	for (i = 0; i < map->n; ++i) {
14025		map->p[i] = isl_basic_map_preimage_multi_aff(map->p[i], type,
14026							isl_multi_aff_copy(ma));
14027		if (!map->p[i])
14028			goto error;
14029	}
14030
14031	space = isl_multi_aff_get_domain_space(ma);
14032	space = isl_space_set(isl_map_get_space(map), type, space);
14033
14034	isl_space_free(isl_map_take_space(map));
14035	map = isl_map_restore_space(map, space);
14036	if (!map)
14037		goto error;
14038
14039	isl_multi_aff_free(ma);
14040	if (map->n > 1)
14041		ISL_F_CLR(map, ISL_MAP_DISJOINT);
14042	ISL_F_CLR(map, ISL_SET_NORMALIZED);
14043	return map;
14044error:
14045	isl_multi_aff_free(ma);
14046	isl_map_free(map);
14047	return NULL;
14048}
14049
14050/* Compute the preimage of the domain or range (depending on "type")
14051 * of "map" under the function represented by "ma".
14052 * In other words, plug in "ma" in the domain or range of "map".
14053 * The result is a map that lives in the same space as "map"
14054 * except that the domain or range has been replaced by
14055 * the domain space of "ma".
14056 */
14057__isl_give isl_map *isl_map_preimage_multi_aff(__isl_take isl_map *map,
14058	enum isl_dim_type type, __isl_take isl_multi_aff *ma)
14059{
14060	isl_bool aligned;
14061
14062	if (!map || !ma)
14063		goto error;
14064
14065	aligned = isl_map_space_has_equal_params(map, ma->space);
14066	if (aligned < 0)
14067		goto error;
14068	if (aligned)
14069		return map_preimage_multi_aff(map, type, ma);
14070
14071	if (isl_map_check_named_params(map) < 0)
14072		goto error;
14073	if (!isl_space_has_named_params(ma->space))
14074		isl_die(map->ctx, isl_error_invalid,
14075			"unaligned unnamed parameters", goto error);
14076	map = isl_map_align_params(map, isl_multi_aff_get_space(ma));
14077	ma = isl_multi_aff_align_params(ma, isl_map_get_space(map));
14078
14079	return map_preimage_multi_aff(map, type, ma);
14080error:
14081	isl_multi_aff_free(ma);
14082	return isl_map_free(map);
14083}
14084
14085/* Compute the preimage of "set" under the function represented by "ma".
14086 * In other words, plug in "ma" in "set".  The result is a set
14087 * that lives in the domain space of "ma".
14088 */
14089__isl_give isl_set *isl_set_preimage_multi_aff(__isl_take isl_set *set,
14090	__isl_take isl_multi_aff *ma)
14091{
14092	return isl_map_preimage_multi_aff(set, isl_dim_set, ma);
14093}
14094
14095/* Compute the preimage of the domain of "map" under the function
14096 * represented by "ma".
14097 * In other words, plug in "ma" in the domain of "map".
14098 * The result is a map that lives in the same space as "map"
14099 * except that the domain has been replaced by the domain space of "ma".
14100 */
14101__isl_give isl_map *isl_map_preimage_domain_multi_aff(__isl_take isl_map *map,
14102	__isl_take isl_multi_aff *ma)
14103{
14104	return isl_map_preimage_multi_aff(map, isl_dim_in, ma);
14105}
14106
14107/* Compute the preimage of the range of "map" under the function
14108 * represented by "ma".
14109 * In other words, plug in "ma" in the range of "map".
14110 * The result is a map that lives in the same space as "map"
14111 * except that the range has been replaced by the domain space of "ma".
14112 */
14113__isl_give isl_map *isl_map_preimage_range_multi_aff(__isl_take isl_map *map,
14114	__isl_take isl_multi_aff *ma)
14115{
14116	return isl_map_preimage_multi_aff(map, isl_dim_out, ma);
14117}
14118
14119/* Compute the preimage of "map" under the function represented by "pma".
14120 * In other words, plug in "pma" in the domain or range of "map".
14121 * The result is a map that lives in the same space as "map",
14122 * except that the space of type "type" has been replaced by
14123 * the domain space of "pma".
14124 *
14125 * The parameters of "map" and "pma" are assumed to have been aligned.
14126 */
14127static __isl_give isl_map *isl_map_preimage_pw_multi_aff_aligned(
14128	__isl_take isl_map *map, enum isl_dim_type type,
14129	__isl_take isl_pw_multi_aff *pma)
14130{
14131	int i;
14132	isl_map *res;
14133
14134	if (!pma)
14135		goto error;
14136
14137	if (pma->n == 0) {
14138		isl_space *space;
14139
14140		space = isl_pw_multi_aff_get_domain_space(pma);
14141		isl_pw_multi_aff_free(pma);
14142		space = isl_space_set(isl_map_get_space(map), type, space);
14143		isl_map_free(map);
14144		return isl_map_empty(space);
14145	}
14146
14147	res = isl_map_preimage_multi_aff(isl_map_copy(map), type,
14148					isl_multi_aff_copy(pma->p[0].maff));
14149	if (type == isl_dim_in)
14150		res = isl_map_intersect_domain(res,
14151						isl_map_copy(pma->p[0].set));
14152	else
14153		res = isl_map_intersect_range(res,
14154						isl_map_copy(pma->p[0].set));
14155
14156	for (i = 1; i < pma->n; ++i) {
14157		isl_map *res_i;
14158
14159		res_i = isl_map_preimage_multi_aff(isl_map_copy(map), type,
14160					isl_multi_aff_copy(pma->p[i].maff));
14161		if (type == isl_dim_in)
14162			res_i = isl_map_intersect_domain(res_i,
14163						isl_map_copy(pma->p[i].set));
14164		else
14165			res_i = isl_map_intersect_range(res_i,
14166						isl_map_copy(pma->p[i].set));
14167		res = isl_map_union(res, res_i);
14168	}
14169
14170	isl_pw_multi_aff_free(pma);
14171	isl_map_free(map);
14172	return res;
14173error:
14174	isl_pw_multi_aff_free(pma);
14175	isl_map_free(map);
14176	return NULL;
14177}
14178
14179/* Compute the preimage of "map" under the function represented by "pma".
14180 * In other words, plug in "pma" in the domain or range of "map".
14181 * The result is a map that lives in the same space as "map",
14182 * except that the space of type "type" has been replaced by
14183 * the domain space of "pma".
14184 */
14185__isl_give isl_map *isl_map_preimage_pw_multi_aff(__isl_take isl_map *map,
14186	enum isl_dim_type type, __isl_take isl_pw_multi_aff *pma)
14187{
14188	isl_bool aligned;
14189
14190	if (!map || !pma)
14191		goto error;
14192
14193	aligned = isl_map_space_has_equal_params(map, pma->dim);
14194	if (aligned < 0)
14195		goto error;
14196	if (aligned)
14197		return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
14198
14199	if (isl_map_check_named_params(map) < 0)
14200		goto error;
14201	if (isl_pw_multi_aff_check_named_params(pma) < 0)
14202		goto error;
14203	map = isl_map_align_params(map, isl_pw_multi_aff_get_space(pma));
14204	pma = isl_pw_multi_aff_align_params(pma, isl_map_get_space(map));
14205
14206	return isl_map_preimage_pw_multi_aff_aligned(map, type, pma);
14207error:
14208	isl_pw_multi_aff_free(pma);
14209	return isl_map_free(map);
14210}
14211
14212/* Compute the preimage of "set" under the function represented by "pma".
14213 * In other words, plug in "pma" in "set".  The result is a set
14214 * that lives in the domain space of "pma".
14215 */
14216__isl_give isl_set *isl_set_preimage_pw_multi_aff(__isl_take isl_set *set,
14217	__isl_take isl_pw_multi_aff *pma)
14218{
14219	return isl_map_preimage_pw_multi_aff(set, isl_dim_set, pma);
14220}
14221
14222/* Compute the preimage of the domain of "map" under the function
14223 * represented by "pma".
14224 * In other words, plug in "pma" in the domain of "map".
14225 * The result is a map that lives in the same space as "map",
14226 * except that domain space has been replaced by the domain space of "pma".
14227 */
14228__isl_give isl_map *isl_map_preimage_domain_pw_multi_aff(
14229	__isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
14230{
14231	return isl_map_preimage_pw_multi_aff(map, isl_dim_in, pma);
14232}
14233
14234/* Compute the preimage of the range of "map" under the function
14235 * represented by "pma".
14236 * In other words, plug in "pma" in the range of "map".
14237 * The result is a map that lives in the same space as "map",
14238 * except that range space has been replaced by the domain space of "pma".
14239 */
14240__isl_give isl_map *isl_map_preimage_range_pw_multi_aff(
14241	__isl_take isl_map *map, __isl_take isl_pw_multi_aff *pma)
14242{
14243	return isl_map_preimage_pw_multi_aff(map, isl_dim_out, pma);
14244}
14245
14246/* Compute the preimage of "map" under the function represented by "mpa".
14247 * In other words, plug in "mpa" in the domain or range of "map".
14248 * The result is a map that lives in the same space as "map",
14249 * except that the space of type "type" has been replaced by
14250 * the domain space of "mpa".
14251 *
14252 * If the map does not involve any constraints that refer to the
14253 * dimensions of the substituted space, then the only possible
14254 * effect of "mpa" on the map is to map the space to a different space.
14255 * We create a separate isl_multi_aff to effectuate this change
14256 * in order to avoid spurious splitting of the map along the pieces
14257 * of "mpa".
14258 * If "mpa" has a non-trivial explicit domain, however,
14259 * then the full substitution should be performed.
14260 */
14261__isl_give isl_map *isl_map_preimage_multi_pw_aff(__isl_take isl_map *map,
14262	enum isl_dim_type type, __isl_take isl_multi_pw_aff *mpa)
14263{
14264	isl_size n;
14265	isl_bool full;
14266	isl_pw_multi_aff *pma;
14267
14268	n = isl_map_dim(map, type);
14269	if (n < 0 || !mpa)
14270		goto error;
14271
14272	full = isl_map_involves_dims(map, type, 0, n);
14273	if (full >= 0 && !full)
14274		full = isl_multi_pw_aff_has_non_trivial_domain(mpa);
14275	if (full < 0)
14276		goto error;
14277	if (!full) {
14278		isl_space *space;
14279		isl_multi_aff *ma;
14280
14281		space = isl_multi_pw_aff_get_space(mpa);
14282		isl_multi_pw_aff_free(mpa);
14283		ma = isl_multi_aff_zero(space);
14284		return isl_map_preimage_multi_aff(map, type, ma);
14285	}
14286
14287	pma = isl_pw_multi_aff_from_multi_pw_aff(mpa);
14288	return isl_map_preimage_pw_multi_aff(map, type, pma);
14289error:
14290	isl_map_free(map);
14291	isl_multi_pw_aff_free(mpa);
14292	return NULL;
14293}
14294
14295/* Compute the preimage of "map" under the function represented by "mpa".
14296 * In other words, plug in "mpa" in the domain "map".
14297 * The result is a map that lives in the same space as "map",
14298 * except that domain space has been replaced by the domain space of "mpa".
14299 */
14300__isl_give isl_map *isl_map_preimage_domain_multi_pw_aff(
14301	__isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa)
14302{
14303	return isl_map_preimage_multi_pw_aff(map, isl_dim_in, mpa);
14304}
14305
14306/* Compute the preimage of "set" by the function represented by "mpa".
14307 * In other words, plug in "mpa" in "set".
14308 */
14309__isl_give isl_set *isl_set_preimage_multi_pw_aff(__isl_take isl_set *set,
14310	__isl_take isl_multi_pw_aff *mpa)
14311{
14312	return isl_map_preimage_multi_pw_aff(set, isl_dim_set, mpa);
14313}
14314
14315/* Given that inequality "ineq" of "bmap" expresses an upper bound
14316 * on the output dimension "pos" in terms of the parameters,
14317 * the input dimensions and possibly some integer divisions,
14318 * but not any other output dimensions, extract this upper bound
14319 * as a function of all dimensions (with zero coefficients
14320 * for the output dimensions).
14321 *
14322 * That is, the inequality is of the form
14323 *
14324 *	e(...) + c - m x >= 0
14325 *
14326 * where e does not depend on any other output dimensions.
14327 * Return (e(...) + c) / m, with the denominator m in the first position.
14328 */
14329__isl_give isl_vec *isl_basic_map_inequality_extract_output_upper_bound(
14330	__isl_keep isl_basic_map *bmap, int ineq, int pos)
14331{
14332	isl_ctx *ctx;
14333	isl_vec *v;
14334	isl_size v_out, total;
14335
14336	v_out = isl_basic_map_var_offset(bmap, isl_dim_out);
14337	total = isl_basic_map_dim(bmap, isl_dim_all);
14338	if (v_out < 0 || total < 0)
14339		return NULL;
14340	ctx = isl_basic_map_get_ctx(bmap);
14341	v = isl_vec_alloc(ctx, 1 + 1 + total);
14342	if (!v)
14343		return NULL;
14344	isl_int_neg(v->el[0], bmap->ineq[ineq][1 + v_out + pos]);
14345	isl_seq_cpy(v->el + 1, bmap->ineq[ineq], 1 + total);
14346	isl_int_set_si(v->el[1 + 1 + v_out + pos], 0);
14347
14348	return v;
14349}
14350
14351/* Is constraint "c" of "bmap" of the form
14352 *
14353 *	e(...) + c1 - m x >= 0
14354 *
14355 * or
14356 *
14357 *	-e(...) + c2 + m x >= 0
14358 *
14359 * where m > 1 and e does not involve any other output variables?
14360 *
14361 * "v_out" is the offset to the output variables.
14362 * "d" is the position of x among the output variables.
14363 * "v_div" is the offset to the local variables.
14364 * "total" is the total number of variables.
14365 *
14366 * Since the purpose of this function is to use the constraint
14367 * to express the output variable as an integer division,
14368 * do not allow the constraint to involve any local variables
14369 * that do not have an explicit representation.
14370 */
14371static isl_bool is_potential_div_constraint(__isl_keep isl_basic_map *bmap,
14372	isl_int *c, int v_out, int d, int v_div, int total)
14373{
14374	int i = 0;
14375
14376	if (isl_int_is_zero(c[1 + v_out + d]))
14377		return isl_bool_false;
14378	if (isl_int_is_one(c[1 + v_out + d]))
14379		return isl_bool_false;
14380	if (isl_int_is_negone(c[1 + v_out + d]))
14381		return isl_bool_false;
14382	if (isl_seq_first_non_zero(c + 1 + v_out, d) != -1)
14383		return isl_bool_false;
14384	if (isl_seq_first_non_zero(c + 1 + v_out + d + 1,
14385				    v_div - (v_out + d + 1)) != -1)
14386		return isl_bool_false;
14387	for (i = 0; v_div + i < total; ++i) {
14388		isl_bool known, involves;
14389
14390		if (isl_int_is_zero(c[1 + v_div + i]))
14391			continue;
14392		known = isl_basic_map_div_is_known(bmap, i);
14393		if (known < 0 || !known)
14394			return known;
14395		involves = div_involves_vars(bmap, i, v_out, v_div - v_out);
14396		if (involves < 0 || involves)
14397			return isl_bool_not(involves);
14398	}
14399	return isl_bool_true;
14400}
14401
14402/* Look for a pair of constraints
14403 *
14404 *	e(...) + c1 - m x >= 0		i.e.,		m x <= e(...) + c1
14405 *
14406 * and
14407 *
14408 *	-e(...) + c2 + m x >= 0		i.e.,		m x >= e(...) - c2
14409 *
14410 * that express that the output dimension x at position "pos"
14411 * is some integer division of an expression in terms of the parameters,
14412 * input dimensions and integer divisions.
14413 * If such a pair can be found, then return the index
14414 * of the upper bound constraint, m x <= e(...) + c1.
14415 * Otherwise, return an index beyond the number of constraints.
14416 *
14417 * In order for the constraints above to express an integer division,
14418 * m needs to be greater than 1 and such that
14419 *
14420 *	c1 + c2 < m			i.e.,		-c2 >= c1 - (m - 1)
14421 *
14422 * In particular, this ensures that
14423 *
14424 *	x = floor((e(...) + c1) / m)
14425 */
14426isl_size isl_basic_map_find_output_upper_div_constraint(
14427	__isl_keep isl_basic_map *bmap, int pos)
14428{
14429	int i, j;
14430	isl_size n_ineq;
14431	isl_size v_out, v_div;
14432	isl_size total;
14433	isl_int sum;
14434
14435	total = isl_basic_map_dim(bmap, isl_dim_all);
14436	v_out = isl_basic_map_var_offset(bmap, isl_dim_out);
14437	v_div = isl_basic_map_var_offset(bmap, isl_dim_div);
14438	n_ineq = isl_basic_map_n_inequality(bmap);
14439	if (total < 0 || v_out < 0 || v_div < 0 || n_ineq < 0)
14440		return isl_size_error;
14441
14442	isl_int_init(sum);
14443	for (i = 0; i < n_ineq; ++i) {
14444		isl_bool potential;
14445
14446		potential = is_potential_div_constraint(bmap, bmap->ineq[i],
14447						v_out, pos, v_div, total);
14448		if (potential < 0)
14449			goto error;
14450		if (!potential)
14451			continue;
14452		for (j = i + 1; j < n_ineq; ++j) {
14453			if (!isl_seq_is_neg(bmap->ineq[i] + 1,
14454					bmap->ineq[j] + 1, total))
14455				continue;
14456			isl_int_add(sum, bmap->ineq[i][0], bmap->ineq[j][0]);
14457			if (isl_int_abs_lt(sum, bmap->ineq[i][1 + v_out + pos]))
14458				break;
14459		}
14460		if (j < n_ineq)
14461			break;
14462	}
14463	isl_int_clear(sum);
14464
14465	if (i >= n_ineq)
14466		return n_ineq;
14467	if (isl_int_is_pos(bmap->ineq[j][1 + v_out + pos]))
14468		return i;
14469	else
14470		return j;
14471error:
14472	isl_int_clear(sum);
14473	return isl_size_error;
14474}
14475
14476/* Return a copy of the equality constraints of "bset" as a matrix.
14477 */
14478__isl_give isl_mat *isl_basic_set_extract_equalities(
14479	__isl_keep isl_basic_set *bset)
14480{
14481	isl_ctx *ctx;
14482	isl_size total;
14483
14484	total = isl_basic_set_dim(bset, isl_dim_all);
14485	if (total < 0)
14486		return NULL;
14487
14488	ctx = isl_basic_set_get_ctx(bset);
14489	return isl_mat_sub_alloc6(ctx, bset->eq, 0, bset->n_eq, 0, 1 + total);
14490}
14491
14492/* Are the "n" "coefficients" starting at "first" of the integer division
14493 * expressions at position "pos1" in "bmap1" and "pos2" in "bmap2" equal
14494 * to each other?
14495 * The "coefficient" at position 0 is the denominator.
14496 * The "coefficient" at position 1 is the constant term.
14497 */
14498isl_bool isl_basic_map_equal_div_expr_part(__isl_keep isl_basic_map *bmap1,
14499	int pos1, __isl_keep isl_basic_map *bmap2, int pos2,
14500	unsigned first, unsigned n)
14501{
14502	if (isl_basic_map_check_range(bmap1, isl_dim_div, pos1, 1) < 0)
14503		return isl_bool_error;
14504	if (isl_basic_map_check_range(bmap2, isl_dim_div, pos2, 1) < 0)
14505		return isl_bool_error;
14506	return isl_seq_eq(bmap1->div[pos1] + first,
14507			  bmap2->div[pos2] + first, n);
14508}
14509
14510/* Are the integer division expressions at position "pos1" in "bmap1" and
14511 * "pos2" in "bmap2" equal to each other, except that the constant terms
14512 * are different?
14513 */
14514isl_bool isl_basic_map_equal_div_expr_except_constant(
14515	__isl_keep isl_basic_map *bmap1, int pos1,
14516	__isl_keep isl_basic_map *bmap2, int pos2)
14517{
14518	isl_bool equal;
14519	isl_size total, total2;
14520
14521	total = isl_basic_map_dim(bmap1, isl_dim_all);
14522	total2 = isl_basic_map_dim(bmap2, isl_dim_all);
14523	if (total < 0 || total2 < 0)
14524		return isl_bool_error;
14525	if (total != total2)
14526		isl_die(isl_basic_map_get_ctx(bmap1), isl_error_invalid,
14527			"incomparable div expressions", return isl_bool_error);
14528	equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14529						0, 1);
14530	if (equal < 0 || !equal)
14531		return equal;
14532	equal = isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14533						1, 1);
14534	if (equal < 0 || equal)
14535		return isl_bool_not(equal);
14536	return isl_basic_map_equal_div_expr_part(bmap1, pos1, bmap2, pos2,
14537						2, total);
14538}
14539
14540/* Replace the numerator of the constant term of the integer division
14541 * expression at position "div" in "bmap" by "value".
14542 * The caller guarantees that this does not change the meaning
14543 * of the input.
14544 */
14545__isl_give isl_basic_map *isl_basic_map_set_div_expr_constant_num_si_inplace(
14546	__isl_take isl_basic_map *bmap, int div, int value)
14547{
14548	if (isl_basic_map_check_range(bmap, isl_dim_div, div, 1) < 0)
14549		return isl_basic_map_free(bmap);
14550
14551	isl_int_set_si(bmap->div[div][1], value);
14552
14553	return bmap;
14554}
14555
14556/* Is the point "inner" internal to inequality constraint "ineq"
14557 * of "bset"?
14558 * The point is considered to be internal to the inequality constraint,
14559 * if it strictly lies on the positive side of the inequality constraint,
14560 * or if it lies on the constraint and the constraint is lexico-positive.
14561 */
14562static isl_bool is_internal(__isl_keep isl_vec *inner,
14563	__isl_keep isl_basic_set *bset, int ineq)
14564{
14565	isl_ctx *ctx;
14566	int pos;
14567	isl_size total;
14568
14569	if (!inner || !bset)
14570		return isl_bool_error;
14571
14572	ctx = isl_basic_set_get_ctx(bset);
14573	isl_seq_inner_product(inner->el, bset->ineq[ineq], inner->size,
14574				&ctx->normalize_gcd);
14575	if (!isl_int_is_zero(ctx->normalize_gcd))
14576		return isl_int_is_nonneg(ctx->normalize_gcd);
14577
14578	total = isl_basic_set_dim(bset, isl_dim_all);
14579	if (total < 0)
14580		return isl_bool_error;
14581	pos = isl_seq_first_non_zero(bset->ineq[ineq] + 1, total);
14582	return isl_int_is_pos(bset->ineq[ineq][1 + pos]);
14583}
14584
14585/* Tighten the inequality constraints of "bset" that are outward with respect
14586 * to the point "vec".
14587 * That is, tighten the constraints that are not satisfied by "vec".
14588 *
14589 * "vec" is a point internal to some superset S of "bset" that is used
14590 * to make the subsets of S disjoint, by tightening one half of the constraints
14591 * that separate two subsets.  In particular, the constraints of S
14592 * are all satisfied by "vec" and should not be tightened.
14593 * Of the internal constraints, those that have "vec" on the outside
14594 * are tightened.  The shared facet is included in the adjacent subset
14595 * with the opposite constraint.
14596 * For constraints that saturate "vec", this criterion cannot be used
14597 * to determine which of the two sides should be tightened.
14598 * Instead, the sign of the first non-zero coefficient is used
14599 * to make this choice.  Note that this second criterion is never used
14600 * on the constraints of S since "vec" is interior to "S".
14601 */
14602__isl_give isl_basic_set *isl_basic_set_tighten_outward(
14603	__isl_take isl_basic_set *bset, __isl_keep isl_vec *vec)
14604{
14605	int j;
14606
14607	bset = isl_basic_set_cow(bset);
14608	if (!bset)
14609		return NULL;
14610	for (j = 0; j < bset->n_ineq; ++j) {
14611		isl_bool internal;
14612
14613		internal = is_internal(vec, bset, j);
14614		if (internal < 0)
14615			return isl_basic_set_free(bset);
14616		if (internal)
14617			continue;
14618		isl_int_sub_ui(bset->ineq[j][0], bset->ineq[j][0], 1);
14619	}
14620
14621	return bset;
14622}
14623
14624/* Replace the variables x of type "type" starting at "first" in "bmap"
14625 * by x' with x = M x' with M the matrix trans.
14626 * That is, replace the corresponding coefficients c by c M.
14627 *
14628 * The transformation matrix should be a square matrix.
14629 */
14630__isl_give isl_basic_map *isl_basic_map_transform_dims(
14631	__isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first,
14632	__isl_take isl_mat *trans)
14633{
14634	unsigned pos;
14635
14636	bmap = isl_basic_map_cow(bmap);
14637	if (!bmap || !trans)
14638		goto error;
14639
14640	if (trans->n_row != trans->n_col)
14641		isl_die(trans->ctx, isl_error_invalid,
14642			"expecting square transformation matrix", goto error);
14643	if (isl_basic_map_check_range(bmap, type, first, trans->n_row) < 0)
14644		goto error;
14645
14646	pos = isl_basic_map_offset(bmap, type) + first;
14647
14648	if (isl_mat_sub_transform(bmap->eq, bmap->n_eq, pos,
14649			isl_mat_copy(trans)) < 0)
14650		goto error;
14651	if (isl_mat_sub_transform(bmap->ineq, bmap->n_ineq, pos,
14652		      isl_mat_copy(trans)) < 0)
14653		goto error;
14654	if (isl_mat_sub_transform(bmap->div, bmap->n_div, 1 + pos,
14655		      isl_mat_copy(trans)) < 0)
14656		goto error;
14657
14658	ISL_F_CLR(bmap, ISL_BASIC_MAP_SORTED);
14659	ISL_F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED_DIVS);
14660
14661	isl_mat_free(trans);
14662	return bmap;
14663error:
14664	isl_mat_free(trans);
14665	isl_basic_map_free(bmap);
14666	return NULL;
14667}
14668
14669/* Replace the variables x of type "type" starting at "first" in "bset"
14670 * by x' with x = M x' with M the matrix trans.
14671 * That is, replace the corresponding coefficients c by c M.
14672 *
14673 * The transformation matrix should be a square matrix.
14674 */
14675__isl_give isl_basic_set *isl_basic_set_transform_dims(
14676	__isl_take isl_basic_set *bset, enum isl_dim_type type, unsigned first,
14677	__isl_take isl_mat *trans)
14678{
14679	return isl_basic_map_transform_dims(bset, type, first, trans);
14680}
14681