1/*
2 * Copyright 2011      INRIA Saclay
3 * Copyright 2011      Sven Verdoolaege
4 * Copyright 2012-2014 Ecole Normale Superieure
5 * Copyright 2014      INRIA Rocquencourt
6 * Copyright 2016      Sven Verdoolaege
7 * Copyright 2018,2020 Cerebras Systems
8 * Copyright 2021      Sven Verdoolaege
9 * Copyright 2022      Cerebras Systems
10 *
11 * Use of this software is governed by the MIT license
12 *
13 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
14 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
15 * 91893 Orsay, France
16 * and Ecole Normale Superieure, 45 rue d���Ulm, 75230 Paris, France
17 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
18 * B.P. 105 - 78153 Le Chesnay, France
19 * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
20 * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA
21 */
22
23#include <isl_ctx_private.h>
24#include <isl_map_private.h>
25#include <isl_union_map_private.h>
26#include <isl_aff_private.h>
27#include <isl_space_private.h>
28#include <isl_local_space_private.h>
29#include <isl_vec_private.h>
30#include <isl_mat_private.h>
31#include <isl_id_private.h>
32#include <isl/constraint.h>
33#include <isl_seq.h>
34#include <isl/set.h>
35#include <isl_val_private.h>
36#include <isl_point_private.h>
37#include <isl_config.h>
38
39#undef EL_BASE
40#define EL_BASE aff
41
42#include <isl_list_templ.c>
43#include <isl_list_read_templ.c>
44
45#undef EL_BASE
46#define EL_BASE pw_aff
47
48#include <isl_list_templ.c>
49#include <isl_list_read_templ.c>
50
51#undef EL_BASE
52#define EL_BASE pw_multi_aff
53
54#include <isl_list_templ.c>
55#include <isl_list_read_templ.c>
56
57#undef EL_BASE
58#define EL_BASE union_pw_aff
59
60#include <isl_list_templ.c>
61#include <isl_list_read_templ.c>
62
63#undef EL_BASE
64#define EL_BASE union_pw_multi_aff
65
66#include <isl_list_templ.c>
67
68/* Construct an isl_aff from the given domain local space "ls" and
69 * coefficients "v", where the local space is known to be valid
70 * for an affine expression.
71 */
72static __isl_give isl_aff *isl_aff_alloc_vec_validated(
73	__isl_take isl_local_space *ls, __isl_take isl_vec *v)
74{
75	isl_aff *aff;
76
77	if (!ls || !v)
78		goto error;
79
80	aff = isl_calloc_type(v->ctx, struct isl_aff);
81	if (!aff)
82		goto error;
83
84	aff->ref = 1;
85	aff->ls = ls;
86	aff->v = v;
87
88	return aff;
89error:
90	isl_local_space_free(ls);
91	isl_vec_free(v);
92	return NULL;
93}
94
95/* Construct an isl_aff from the given domain local space "ls" and
96 * coefficients "v".
97 *
98 * First check that "ls" is a valid domain local space
99 * for an affine expression.
100 */
101__isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls,
102	__isl_take isl_vec *v)
103{
104	isl_ctx *ctx;
105
106	if (!ls)
107		return NULL;
108
109	ctx = isl_local_space_get_ctx(ls);
110	if (!isl_local_space_divs_known(ls))
111		isl_die(ctx, isl_error_invalid, "local space has unknown divs",
112			goto error);
113	if (!isl_local_space_is_set(ls))
114		isl_die(ctx, isl_error_invalid,
115			"domain of affine expression should be a set",
116			goto error);
117	return isl_aff_alloc_vec_validated(ls, v);
118error:
119	isl_local_space_free(ls);
120	isl_vec_free(v);
121	return NULL;
122}
123
124__isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls)
125{
126	isl_ctx *ctx;
127	isl_vec *v;
128	isl_size total;
129
130	if (!ls)
131		return NULL;
132
133	ctx = isl_local_space_get_ctx(ls);
134
135	total = isl_local_space_dim(ls, isl_dim_all);
136	if (total < 0)
137		goto error;
138	v = isl_vec_alloc(ctx, 1 + 1 + total);
139	return isl_aff_alloc_vec(ls, v);
140error:
141	isl_local_space_free(ls);
142	return NULL;
143}
144
145__isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff)
146{
147	if (!aff)
148		return NULL;
149
150	aff->ref++;
151	return aff;
152}
153
154__isl_give isl_aff *isl_aff_dup(__isl_keep isl_aff *aff)
155{
156	if (!aff)
157		return NULL;
158
159	return isl_aff_alloc_vec_validated(isl_local_space_copy(aff->ls),
160					    isl_vec_copy(aff->v));
161}
162
163__isl_give isl_aff *isl_aff_cow(__isl_take isl_aff *aff)
164{
165	if (!aff)
166		return NULL;
167
168	if (aff->ref == 1)
169		return aff;
170	aff->ref--;
171	return isl_aff_dup(aff);
172}
173
174/* Return a copy of the rational affine expression of "aff".
175 */
176static __isl_give isl_vec *isl_aff_get_rat_aff(__isl_keep isl_aff *aff)
177{
178	if (!aff)
179		return NULL;
180	return isl_vec_copy(aff->v);
181}
182
183/* Return the rational affine expression of "aff".
184 * This may be either a copy or the expression itself
185 * if there is only one reference to "aff".
186 * This allows the expression to be modified inplace
187 * if both the "aff" and its expression have only a single reference.
188 * The caller is not allowed to modify "aff" between this call and
189 * a subsequent call to isl_aff_restore_rat_aff.
190 * The only exception is that isl_aff_free can be called instead.
191 */
192static __isl_give isl_vec *isl_aff_take_rat_aff(__isl_keep isl_aff *aff)
193{
194	isl_vec *v;
195
196	if (!aff)
197		return NULL;
198	if (aff->ref != 1)
199		return isl_aff_get_rat_aff(aff);
200	v = aff->v;
201	aff->v = NULL;
202	return v;
203}
204
205/* Set the rational affine expression of "aff" to "v",
206 * where the rational affine expression of "aff" may be missing
207 * due to a preceding call to isl_aff_take_rat_aff.
208 * However, in this case, "aff" only has a single reference and
209 * then the call to isl_aff_cow has no effect.
210 */
211static __isl_give isl_aff *isl_aff_restore_rat_aff(__isl_keep isl_aff *aff,
212	__isl_take isl_vec *v)
213{
214	if (!aff || !v)
215		goto error;
216
217	if (aff->v == v) {
218		isl_vec_free(v);
219		return aff;
220	}
221
222	aff = isl_aff_cow(aff);
223	if (!aff)
224		goto error;
225	isl_vec_free(aff->v);
226	aff->v = v;
227
228	return aff;
229error:
230	isl_aff_free(aff);
231	isl_vec_free(v);
232	return NULL;
233}
234
235__isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls)
236{
237	isl_aff *aff;
238
239	aff = isl_aff_alloc(ls);
240	if (!aff)
241		return NULL;
242
243	isl_int_set_si(aff->v->el[0], 1);
244	isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
245
246	return aff;
247}
248
249/* Return an affine expression that is equal to zero on domain space "space".
250 */
251__isl_give isl_aff *isl_aff_zero_on_domain_space(__isl_take isl_space *space)
252{
253	return isl_aff_zero_on_domain(isl_local_space_from_space(space));
254}
255
256/* This function performs the same operation as isl_aff_zero_on_domain_space,
257 * but is considered as a function on an isl_space when exported.
258 */
259__isl_give isl_aff *isl_space_zero_aff_on_domain(__isl_take isl_space *space)
260{
261	return isl_aff_zero_on_domain_space(space);
262}
263
264/* Return a piecewise affine expression defined on the specified domain
265 * that is equal to zero.
266 */
267__isl_give isl_pw_aff *isl_pw_aff_zero_on_domain(__isl_take isl_local_space *ls)
268{
269	return isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls));
270}
271
272/* Change "aff" into a NaN.
273 *
274 * Note that this function gets called from isl_aff_nan_on_domain,
275 * so "aff" may not have been initialized yet.
276 */
277static __isl_give isl_aff *isl_aff_set_nan(__isl_take isl_aff *aff)
278{
279	isl_vec *v;
280
281	v = isl_aff_take_rat_aff(aff);
282	v = isl_vec_clr(v);
283	aff = isl_aff_restore_rat_aff(aff, v);
284
285	return aff;
286}
287
288/* Return an affine expression defined on the specified domain
289 * that represents NaN.
290 */
291__isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls)
292{
293	isl_aff *aff;
294
295	aff = isl_aff_alloc(ls);
296	return isl_aff_set_nan(aff);
297}
298
299/* Return an affine expression defined on the specified domain space
300 * that represents NaN.
301 */
302__isl_give isl_aff *isl_aff_nan_on_domain_space(__isl_take isl_space *space)
303{
304	return isl_aff_nan_on_domain(isl_local_space_from_space(space));
305}
306
307/* Return a piecewise affine expression defined on the specified domain space
308 * that represents NaN.
309 */
310__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain_space(
311	__isl_take isl_space *space)
312{
313	return isl_pw_aff_from_aff(isl_aff_nan_on_domain_space(space));
314}
315
316/* Return a piecewise affine expression defined on the specified domain
317 * that represents NaN.
318 */
319__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls)
320{
321	return isl_pw_aff_from_aff(isl_aff_nan_on_domain(ls));
322}
323
324/* Return an affine expression that is equal to "val" on
325 * domain local space "ls".
326 *
327 * Note that the encoding for the special value NaN
328 * is the same in isl_val and isl_aff, so this does not need
329 * to be treated in any special way.
330 */
331__isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls,
332	__isl_take isl_val *val)
333{
334	isl_aff *aff;
335
336	if (!ls || !val)
337		goto error;
338	if (!isl_val_is_rat(val) && !isl_val_is_nan(val))
339		isl_die(isl_val_get_ctx(val), isl_error_invalid,
340			"expecting rational value or NaN", goto error);
341
342	aff = isl_aff_alloc(isl_local_space_copy(ls));
343	if (!aff)
344		goto error;
345
346	isl_seq_clr(aff->v->el + 2, aff->v->size - 2);
347	isl_int_set(aff->v->el[1], val->n);
348	isl_int_set(aff->v->el[0], val->d);
349
350	isl_local_space_free(ls);
351	isl_val_free(val);
352	return aff;
353error:
354	isl_local_space_free(ls);
355	isl_val_free(val);
356	return NULL;
357}
358
359/* Return an affine expression that is equal to "val" on domain space "space".
360 */
361__isl_give isl_aff *isl_aff_val_on_domain_space(__isl_take isl_space *space,
362	__isl_take isl_val *val)
363{
364	return isl_aff_val_on_domain(isl_local_space_from_space(space), val);
365}
366
367/* Return an affine expression that is equal to the specified dimension
368 * in "ls".
369 */
370__isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls,
371	enum isl_dim_type type, unsigned pos)
372{
373	isl_space *space;
374	isl_aff *aff;
375
376	if (!ls)
377		return NULL;
378
379	space = isl_local_space_get_space(ls);
380	if (!space)
381		goto error;
382	if (isl_space_is_map(space))
383		isl_die(isl_space_get_ctx(space), isl_error_invalid,
384			"expecting (parameter) set space", goto error);
385	if (isl_local_space_check_range(ls, type, pos, 1) < 0)
386		goto error;
387
388	isl_space_free(space);
389	aff = isl_aff_alloc(ls);
390	if (!aff)
391		return NULL;
392
393	pos += isl_local_space_offset(aff->ls, type);
394
395	isl_int_set_si(aff->v->el[0], 1);
396	isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
397	isl_int_set_si(aff->v->el[1 + pos], 1);
398
399	return aff;
400error:
401	isl_local_space_free(ls);
402	isl_space_free(space);
403	return NULL;
404}
405
406/* Return a piecewise affine expression that is equal to
407 * the specified dimension in "ls".
408 */
409__isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls,
410	enum isl_dim_type type, unsigned pos)
411{
412	return isl_pw_aff_from_aff(isl_aff_var_on_domain(ls, type, pos));
413}
414
415/* Return an affine expression that is equal to the parameter
416 * in the domain space "space" with identifier "id".
417 */
418__isl_give isl_aff *isl_aff_param_on_domain_space_id(
419	__isl_take isl_space *space, __isl_take isl_id *id)
420{
421	int pos;
422	isl_local_space *ls;
423
424	if (!space || !id)
425		goto error;
426	pos = isl_space_find_dim_by_id(space, isl_dim_param, id);
427	if (pos < 0)
428		isl_die(isl_space_get_ctx(space), isl_error_invalid,
429			"parameter not found in space", goto error);
430	isl_id_free(id);
431	ls = isl_local_space_from_space(space);
432	return isl_aff_var_on_domain(ls, isl_dim_param, pos);
433error:
434	isl_space_free(space);
435	isl_id_free(id);
436	return NULL;
437}
438
439/* This function performs the same operation as
440 * isl_aff_param_on_domain_space_id,
441 * but is considered as a function on an isl_space when exported.
442 */
443__isl_give isl_aff *isl_space_param_aff_on_domain_id(
444	__isl_take isl_space *space, __isl_take isl_id *id)
445{
446	return isl_aff_param_on_domain_space_id(space, id);
447}
448
449__isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff)
450{
451	if (!aff)
452		return NULL;
453
454	if (--aff->ref > 0)
455		return NULL;
456
457	isl_local_space_free(aff->ls);
458	isl_vec_free(aff->v);
459
460	free(aff);
461
462	return NULL;
463}
464
465isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff)
466{
467	return aff ? isl_local_space_get_ctx(aff->ls) : NULL;
468}
469
470/* Return a hash value that digests "aff".
471 */
472uint32_t isl_aff_get_hash(__isl_keep isl_aff *aff)
473{
474	uint32_t hash, ls_hash, v_hash;
475
476	if (!aff)
477		return 0;
478
479	hash = isl_hash_init();
480	ls_hash = isl_local_space_get_hash(aff->ls);
481	isl_hash_hash(hash, ls_hash);
482	v_hash = isl_vec_get_hash(aff->v);
483	isl_hash_hash(hash, v_hash);
484
485	return hash;
486}
487
488/* Return the domain local space of "aff".
489 */
490static __isl_keep isl_local_space *isl_aff_peek_domain_local_space(
491	__isl_keep isl_aff *aff)
492{
493	return aff ? aff->ls : NULL;
494}
495
496/* Return the number of variables of the given type in the domain of "aff".
497 */
498isl_size isl_aff_domain_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
499{
500	isl_local_space *ls;
501
502	ls = isl_aff_peek_domain_local_space(aff);
503	return isl_local_space_dim(ls, type);
504}
505
506/* Externally, an isl_aff has a map space, but internally, the
507 * ls field corresponds to the domain of that space.
508 */
509isl_size isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
510{
511	if (!aff)
512		return isl_size_error;
513	if (type == isl_dim_out)
514		return 1;
515	if (type == isl_dim_in)
516		type = isl_dim_set;
517	return isl_aff_domain_dim(aff, type);
518}
519
520/* Return the offset of the first coefficient of type "type" in
521 * the domain of "aff".
522 */
523isl_size isl_aff_domain_offset(__isl_keep isl_aff *aff, enum isl_dim_type type)
524{
525	isl_local_space *ls;
526
527	ls = isl_aff_peek_domain_local_space(aff);
528	return isl_local_space_offset(ls, type);
529}
530
531/* Return the position of the dimension of the given type and name
532 * in "aff".
533 * Return -1 if no such dimension can be found.
534 */
535int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, enum isl_dim_type type,
536	const char *name)
537{
538	if (!aff)
539		return -1;
540	if (type == isl_dim_out)
541		return -1;
542	if (type == isl_dim_in)
543		type = isl_dim_set;
544	return isl_local_space_find_dim_by_name(aff->ls, type, name);
545}
546
547/* Return the domain space of "aff".
548 */
549static __isl_keep isl_space *isl_aff_peek_domain_space(__isl_keep isl_aff *aff)
550{
551	return aff ? isl_local_space_peek_space(aff->ls) : NULL;
552}
553
554__isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff)
555{
556	return isl_space_copy(isl_aff_peek_domain_space(aff));
557}
558
559__isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff)
560{
561	isl_space *space;
562	if (!aff)
563		return NULL;
564	space = isl_local_space_get_space(aff->ls);
565	space = isl_space_from_domain(space);
566	space = isl_space_add_dims(space, isl_dim_out, 1);
567	return space;
568}
569
570/* Return a copy of the domain space of "aff".
571 */
572__isl_give isl_local_space *isl_aff_get_domain_local_space(
573	__isl_keep isl_aff *aff)
574{
575	return isl_local_space_copy(isl_aff_peek_domain_local_space(aff));
576}
577
578__isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff)
579{
580	isl_local_space *ls;
581	if (!aff)
582		return NULL;
583	ls = isl_local_space_copy(aff->ls);
584	ls = isl_local_space_from_domain(ls);
585	ls = isl_local_space_add_dims(ls, isl_dim_out, 1);
586	return ls;
587}
588
589/* Return the local space of the domain of "aff".
590 * This may be either a copy or the local space itself
591 * if there is only one reference to "aff".
592 * This allows the local space to be modified inplace
593 * if both the expression and its local space have only a single reference.
594 * The caller is not allowed to modify "aff" between this call and
595 * a subsequent call to isl_aff_restore_domain_local_space.
596 * The only exception is that isl_aff_free can be called instead.
597 */
598__isl_give isl_local_space *isl_aff_take_domain_local_space(
599	__isl_keep isl_aff *aff)
600{
601	isl_local_space *ls;
602
603	if (!aff)
604		return NULL;
605	if (aff->ref != 1)
606		return isl_aff_get_domain_local_space(aff);
607	ls = aff->ls;
608	aff->ls = NULL;
609	return ls;
610}
611
612/* Set the local space of the domain of "aff" to "ls",
613 * where the local space of "aff" may be missing
614 * due to a preceding call to isl_aff_take_domain_local_space.
615 * However, in this case, "aff" only has a single reference and
616 * then the call to isl_aff_cow has no effect.
617 */
618__isl_give isl_aff *isl_aff_restore_domain_local_space(
619	__isl_keep isl_aff *aff, __isl_take isl_local_space *ls)
620{
621	if (!aff || !ls)
622		goto error;
623
624	if (aff->ls == ls) {
625		isl_local_space_free(ls);
626		return aff;
627	}
628
629	aff = isl_aff_cow(aff);
630	if (!aff)
631		goto error;
632	isl_local_space_free(aff->ls);
633	aff->ls = ls;
634
635	return aff;
636error:
637	isl_aff_free(aff);
638	isl_local_space_free(ls);
639	return NULL;
640}
641
642/* Externally, an isl_aff has a map space, but internally, the
643 * ls field corresponds to the domain of that space.
644 */
645const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff,
646	enum isl_dim_type type, unsigned pos)
647{
648	if (!aff)
649		return NULL;
650	if (type == isl_dim_out)
651		return NULL;
652	if (type == isl_dim_in)
653		type = isl_dim_set;
654	return isl_local_space_get_dim_name(aff->ls, type, pos);
655}
656
657__isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff,
658	__isl_take isl_space *space)
659{
660	aff = isl_aff_cow(aff);
661	if (!aff || !space)
662		goto error;
663
664	aff->ls = isl_local_space_reset_space(aff->ls, space);
665	if (!aff->ls)
666		return isl_aff_free(aff);
667
668	return aff;
669error:
670	isl_aff_free(aff);
671	isl_space_free(space);
672	return NULL;
673}
674
675/* Reset the space of "aff".  This function is called from isl_pw_templ.c
676 * and doesn't know if the space of an element object is represented
677 * directly or through its domain.  It therefore passes along both.
678 */
679__isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff,
680	__isl_take isl_space *space, __isl_take isl_space *domain)
681{
682	isl_space_free(space);
683	return isl_aff_reset_domain_space(aff, domain);
684}
685
686/* Reorder the dimensions of the domain of "aff" according
687 * to the given reordering.
688 */
689__isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff,
690	__isl_take isl_reordering *r)
691{
692	aff = isl_aff_cow(aff);
693	if (!aff)
694		goto error;
695
696	r = isl_reordering_extend(r, aff->ls->div->n_row);
697	aff->v = isl_vec_reorder(aff->v, 2, isl_reordering_copy(r));
698	aff->ls = isl_local_space_realign(aff->ls, r);
699
700	if (!aff->v || !aff->ls)
701		return isl_aff_free(aff);
702
703	return aff;
704error:
705	isl_aff_free(aff);
706	isl_reordering_free(r);
707	return NULL;
708}
709
710__isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff,
711	__isl_take isl_space *model)
712{
713	isl_space *domain_space;
714	isl_bool equal_params;
715
716	domain_space = isl_aff_peek_domain_space(aff);
717	equal_params = isl_space_has_equal_params(domain_space, model);
718	if (equal_params < 0)
719		goto error;
720	if (!equal_params) {
721		isl_reordering *exp;
722
723		exp = isl_parameter_alignment_reordering(domain_space, model);
724		aff = isl_aff_realign_domain(aff, exp);
725	}
726
727	isl_space_free(model);
728	return aff;
729error:
730	isl_space_free(model);
731	isl_aff_free(aff);
732	return NULL;
733}
734
735#undef TYPE
736#define TYPE isl_aff
737#include "isl_unbind_params_templ.c"
738
739/* Is "aff" obviously equal to zero?
740 *
741 * If the denominator is zero, then "aff" is not equal to zero.
742 */
743isl_bool isl_aff_plain_is_zero(__isl_keep isl_aff *aff)
744{
745	int pos;
746
747	if (!aff)
748		return isl_bool_error;
749
750	if (isl_int_is_zero(aff->v->el[0]))
751		return isl_bool_false;
752	pos = isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1);
753	return isl_bool_ok(pos < 0);
754}
755
756/* Does "aff" represent NaN?
757 */
758isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff)
759{
760	if (!aff)
761		return isl_bool_error;
762
763	return isl_bool_ok(isl_seq_first_non_zero(aff->v->el, 2) < 0);
764}
765
766/* Are "aff1" and "aff2" obviously equal?
767 *
768 * NaN is not equal to anything, not even to another NaN.
769 */
770isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1,
771	__isl_keep isl_aff *aff2)
772{
773	isl_bool equal;
774
775	if (!aff1 || !aff2)
776		return isl_bool_error;
777
778	if (isl_aff_is_nan(aff1) || isl_aff_is_nan(aff2))
779		return isl_bool_false;
780
781	equal = isl_local_space_is_equal(aff1->ls, aff2->ls);
782	if (equal < 0 || !equal)
783		return equal;
784
785	return isl_vec_is_equal(aff1->v, aff2->v);
786}
787
788/* Return the common denominator of "aff" in "v".
789 *
790 * We cannot return anything meaningful in case of a NaN.
791 */
792isl_stat isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v)
793{
794	if (!aff)
795		return isl_stat_error;
796	if (isl_aff_is_nan(aff))
797		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
798			"cannot get denominator of NaN", return isl_stat_error);
799	isl_int_set(*v, aff->v->el[0]);
800	return isl_stat_ok;
801}
802
803/* Return the common denominator of "aff".
804 */
805__isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff)
806{
807	isl_ctx *ctx;
808
809	if (!aff)
810		return NULL;
811
812	ctx = isl_aff_get_ctx(aff);
813	if (isl_aff_is_nan(aff))
814		return isl_val_nan(ctx);
815	return isl_val_int_from_isl_int(ctx, aff->v->el[0]);
816}
817
818/* Return the constant term of "aff".
819 */
820__isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff)
821{
822	isl_ctx *ctx;
823	isl_val *v;
824
825	if (!aff)
826		return NULL;
827
828	ctx = isl_aff_get_ctx(aff);
829	if (isl_aff_is_nan(aff))
830		return isl_val_nan(ctx);
831	v = isl_val_rat_from_isl_int(ctx, aff->v->el[1], aff->v->el[0]);
832	return isl_val_normalize(v);
833}
834
835/* Return the coefficient of the variable of type "type" at position "pos"
836 * of "aff".
837 */
838__isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff,
839	enum isl_dim_type type, int pos)
840{
841	isl_ctx *ctx;
842	isl_val *v;
843
844	if (!aff)
845		return NULL;
846
847	ctx = isl_aff_get_ctx(aff);
848	if (type == isl_dim_out)
849		isl_die(ctx, isl_error_invalid,
850			"output/set dimension does not have a coefficient",
851			return NULL);
852	if (type == isl_dim_in)
853		type = isl_dim_set;
854
855	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
856		return NULL;
857
858	if (isl_aff_is_nan(aff))
859		return isl_val_nan(ctx);
860	pos += isl_local_space_offset(aff->ls, type);
861	v = isl_val_rat_from_isl_int(ctx, aff->v->el[1 + pos], aff->v->el[0]);
862	return isl_val_normalize(v);
863}
864
865/* Return the sign of the coefficient of the variable of type "type"
866 * at position "pos" of "aff".
867 */
868int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type,
869	int pos)
870{
871	isl_ctx *ctx;
872
873	if (!aff)
874		return 0;
875
876	ctx = isl_aff_get_ctx(aff);
877	if (type == isl_dim_out)
878		isl_die(ctx, isl_error_invalid,
879			"output/set dimension does not have a coefficient",
880			return 0);
881	if (type == isl_dim_in)
882		type = isl_dim_set;
883
884	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
885		return 0;
886
887	pos += isl_local_space_offset(aff->ls, type);
888	return isl_int_sgn(aff->v->el[1 + pos]);
889}
890
891/* Replace the numerator of the constant term of "aff" by "v".
892 *
893 * A NaN is unaffected by this operation.
894 */
895__isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v)
896{
897	if (!aff)
898		return NULL;
899	if (isl_aff_is_nan(aff))
900		return aff;
901	aff = isl_aff_cow(aff);
902	if (!aff)
903		return NULL;
904
905	aff->v = isl_vec_cow(aff->v);
906	if (!aff->v)
907		return isl_aff_free(aff);
908
909	isl_int_set(aff->v->el[1], v);
910
911	return aff;
912}
913
914/* Replace the constant term of "aff" by "v".
915 *
916 * A NaN is unaffected by this operation.
917 */
918__isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff,
919	__isl_take isl_val *v)
920{
921	if (!aff || !v)
922		goto error;
923
924	if (isl_aff_is_nan(aff)) {
925		isl_val_free(v);
926		return aff;
927	}
928
929	if (!isl_val_is_rat(v))
930		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
931			"expecting rational value", goto error);
932
933	if (isl_int_eq(aff->v->el[1], v->n) &&
934	    isl_int_eq(aff->v->el[0], v->d)) {
935		isl_val_free(v);
936		return aff;
937	}
938
939	aff = isl_aff_cow(aff);
940	if (!aff)
941		goto error;
942	aff->v = isl_vec_cow(aff->v);
943	if (!aff->v)
944		goto error;
945
946	if (isl_int_eq(aff->v->el[0], v->d)) {
947		isl_int_set(aff->v->el[1], v->n);
948	} else if (isl_int_is_one(v->d)) {
949		isl_int_mul(aff->v->el[1], aff->v->el[0], v->n);
950	} else {
951		isl_seq_scale(aff->v->el + 1,
952				aff->v->el + 1, v->d, aff->v->size - 1);
953		isl_int_mul(aff->v->el[1], aff->v->el[0], v->n);
954		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
955		aff->v = isl_vec_normalize(aff->v);
956		if (!aff->v)
957			goto error;
958	}
959
960	isl_val_free(v);
961	return aff;
962error:
963	isl_aff_free(aff);
964	isl_val_free(v);
965	return NULL;
966}
967
968/* Add "v" to the constant term of "aff".
969 *
970 * A NaN is unaffected by this operation.
971 */
972__isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v)
973{
974	if (isl_int_is_zero(v))
975		return aff;
976
977	if (!aff)
978		return NULL;
979	if (isl_aff_is_nan(aff))
980		return aff;
981	aff = isl_aff_cow(aff);
982	if (!aff)
983		return NULL;
984
985	aff->v = isl_vec_cow(aff->v);
986	if (!aff->v)
987		return isl_aff_free(aff);
988
989	isl_int_addmul(aff->v->el[1], aff->v->el[0], v);
990
991	return aff;
992}
993
994/* Add "v" to the constant term of "aff",
995 * in case "aff" is a rational expression.
996 */
997static __isl_give isl_aff *isl_aff_add_rat_constant_val(__isl_take isl_aff *aff,
998	__isl_take isl_val *v)
999{
1000	aff = isl_aff_cow(aff);
1001	if (!aff)
1002		goto error;
1003
1004	aff->v = isl_vec_cow(aff->v);
1005	if (!aff->v)
1006		goto error;
1007
1008	if (isl_int_is_one(v->d)) {
1009		isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n);
1010	} else if (isl_int_eq(aff->v->el[0], v->d)) {
1011		isl_int_add(aff->v->el[1], aff->v->el[1], v->n);
1012		aff->v = isl_vec_normalize(aff->v);
1013		if (!aff->v)
1014			goto error;
1015	} else {
1016		isl_seq_scale(aff->v->el + 1,
1017				aff->v->el + 1, v->d, aff->v->size - 1);
1018		isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n);
1019		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
1020		aff->v = isl_vec_normalize(aff->v);
1021		if (!aff->v)
1022			goto error;
1023	}
1024
1025	isl_val_free(v);
1026	return aff;
1027error:
1028	isl_aff_free(aff);
1029	isl_val_free(v);
1030	return NULL;
1031}
1032
1033/* Return the first argument and free the second.
1034 */
1035static __isl_give isl_aff *pick_free(__isl_take isl_aff *aff,
1036	__isl_take isl_val *v)
1037{
1038	isl_val_free(v);
1039	return aff;
1040}
1041
1042/* Replace the first argument by NaN and free the second argument.
1043 */
1044static __isl_give isl_aff *set_nan_free_val(__isl_take isl_aff *aff,
1045	__isl_take isl_val *v)
1046{
1047	isl_val_free(v);
1048	return isl_aff_set_nan(aff);
1049}
1050
1051/* Add "v" to the constant term of "aff".
1052 *
1053 * A NaN is unaffected by this operation.
1054 * Conversely, adding a NaN turns "aff" into a NaN.
1055 */
1056__isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff,
1057	__isl_take isl_val *v)
1058{
1059	isl_bool is_nan, is_zero, is_rat;
1060
1061	is_nan = isl_aff_is_nan(aff);
1062	is_zero = isl_val_is_zero(v);
1063	if (is_nan < 0 || is_zero < 0)
1064		goto error;
1065	if (is_nan || is_zero)
1066		return pick_free(aff, v);
1067
1068	is_nan = isl_val_is_nan(v);
1069	is_rat = isl_val_is_rat(v);
1070	if (is_nan < 0 || is_rat < 0)
1071		goto error;
1072	if (is_nan)
1073		return set_nan_free_val(aff, v);
1074	if (!is_rat)
1075		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
1076			"expecting rational value or NaN", goto error);
1077
1078	return isl_aff_add_rat_constant_val(aff, v);
1079error:
1080	isl_aff_free(aff);
1081	isl_val_free(v);
1082	return NULL;
1083}
1084
1085__isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v)
1086{
1087	isl_int t;
1088
1089	isl_int_init(t);
1090	isl_int_set_si(t, v);
1091	aff = isl_aff_add_constant(aff, t);
1092	isl_int_clear(t);
1093
1094	return aff;
1095}
1096
1097/* Add "v" to the numerator of the constant term of "aff".
1098 *
1099 * A NaN is unaffected by this operation.
1100 */
1101__isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, isl_int v)
1102{
1103	if (isl_int_is_zero(v))
1104		return aff;
1105
1106	if (!aff)
1107		return NULL;
1108	if (isl_aff_is_nan(aff))
1109		return aff;
1110	aff = isl_aff_cow(aff);
1111	if (!aff)
1112		return NULL;
1113
1114	aff->v = isl_vec_cow(aff->v);
1115	if (!aff->v)
1116		return isl_aff_free(aff);
1117
1118	isl_int_add(aff->v->el[1], aff->v->el[1], v);
1119
1120	return aff;
1121}
1122
1123/* Add "v" to the numerator of the constant term of "aff".
1124 *
1125 * A NaN is unaffected by this operation.
1126 */
1127__isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v)
1128{
1129	isl_int t;
1130
1131	if (v == 0)
1132		return aff;
1133
1134	isl_int_init(t);
1135	isl_int_set_si(t, v);
1136	aff = isl_aff_add_constant_num(aff, t);
1137	isl_int_clear(t);
1138
1139	return aff;
1140}
1141
1142/* Replace the numerator of the constant term of "aff" by "v".
1143 *
1144 * A NaN is unaffected by this operation.
1145 */
1146__isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v)
1147{
1148	if (!aff)
1149		return NULL;
1150	if (isl_aff_is_nan(aff))
1151		return aff;
1152	aff = isl_aff_cow(aff);
1153	if (!aff)
1154		return NULL;
1155
1156	aff->v = isl_vec_cow(aff->v);
1157	if (!aff->v)
1158		return isl_aff_free(aff);
1159
1160	isl_int_set_si(aff->v->el[1], v);
1161
1162	return aff;
1163}
1164
1165/* Replace the numerator of the coefficient of the variable of type "type"
1166 * at position "pos" of "aff" by "v".
1167 *
1168 * A NaN is unaffected by this operation.
1169 */
1170__isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff,
1171	enum isl_dim_type type, int pos, isl_int v)
1172{
1173	if (!aff)
1174		return NULL;
1175
1176	if (type == isl_dim_out)
1177		isl_die(aff->v->ctx, isl_error_invalid,
1178			"output/set dimension does not have a coefficient",
1179			return isl_aff_free(aff));
1180	if (type == isl_dim_in)
1181		type = isl_dim_set;
1182
1183	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
1184		return isl_aff_free(aff);
1185
1186	if (isl_aff_is_nan(aff))
1187		return aff;
1188	aff = isl_aff_cow(aff);
1189	if (!aff)
1190		return NULL;
1191
1192	aff->v = isl_vec_cow(aff->v);
1193	if (!aff->v)
1194		return isl_aff_free(aff);
1195
1196	pos += isl_local_space_offset(aff->ls, type);
1197	isl_int_set(aff->v->el[1 + pos], v);
1198
1199	return aff;
1200}
1201
1202/* Replace the numerator of the coefficient of the variable of type "type"
1203 * at position "pos" of "aff" by "v".
1204 *
1205 * A NaN is unaffected by this operation.
1206 */
1207__isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff,
1208	enum isl_dim_type type, int pos, int v)
1209{
1210	if (!aff)
1211		return NULL;
1212
1213	if (type == isl_dim_out)
1214		isl_die(aff->v->ctx, isl_error_invalid,
1215			"output/set dimension does not have a coefficient",
1216			return isl_aff_free(aff));
1217	if (type == isl_dim_in)
1218		type = isl_dim_set;
1219
1220	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
1221		return isl_aff_free(aff);
1222
1223	if (isl_aff_is_nan(aff))
1224		return aff;
1225	pos += isl_local_space_offset(aff->ls, type);
1226	if (isl_int_cmp_si(aff->v->el[1 + pos], v) == 0)
1227		return aff;
1228
1229	aff = isl_aff_cow(aff);
1230	if (!aff)
1231		return NULL;
1232
1233	aff->v = isl_vec_cow(aff->v);
1234	if (!aff->v)
1235		return isl_aff_free(aff);
1236
1237	isl_int_set_si(aff->v->el[1 + pos], v);
1238
1239	return aff;
1240}
1241
1242/* Replace the coefficient of the variable of type "type" at position "pos"
1243 * of "aff" by "v".
1244 *
1245 * A NaN is unaffected by this operation.
1246 */
1247__isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff,
1248	enum isl_dim_type type, int pos, __isl_take isl_val *v)
1249{
1250	if (!aff || !v)
1251		goto error;
1252
1253	if (type == isl_dim_out)
1254		isl_die(aff->v->ctx, isl_error_invalid,
1255			"output/set dimension does not have a coefficient",
1256			goto error);
1257	if (type == isl_dim_in)
1258		type = isl_dim_set;
1259
1260	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
1261		return isl_aff_free(aff);
1262
1263	if (isl_aff_is_nan(aff)) {
1264		isl_val_free(v);
1265		return aff;
1266	}
1267	if (!isl_val_is_rat(v))
1268		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
1269			"expecting rational value", goto error);
1270
1271	pos += isl_local_space_offset(aff->ls, type);
1272	if (isl_int_eq(aff->v->el[1 + pos], v->n) &&
1273	    isl_int_eq(aff->v->el[0], v->d)) {
1274		isl_val_free(v);
1275		return aff;
1276	}
1277
1278	aff = isl_aff_cow(aff);
1279	if (!aff)
1280		goto error;
1281	aff->v = isl_vec_cow(aff->v);
1282	if (!aff->v)
1283		goto error;
1284
1285	if (isl_int_eq(aff->v->el[0], v->d)) {
1286		isl_int_set(aff->v->el[1 + pos], v->n);
1287	} else if (isl_int_is_one(v->d)) {
1288		isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n);
1289	} else {
1290		isl_seq_scale(aff->v->el + 1,
1291				aff->v->el + 1, v->d, aff->v->size - 1);
1292		isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n);
1293		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
1294		aff->v = isl_vec_normalize(aff->v);
1295		if (!aff->v)
1296			goto error;
1297	}
1298
1299	isl_val_free(v);
1300	return aff;
1301error:
1302	isl_aff_free(aff);
1303	isl_val_free(v);
1304	return NULL;
1305}
1306
1307/* Add "v" to the coefficient of the variable of type "type"
1308 * at position "pos" of "aff".
1309 *
1310 * A NaN is unaffected by this operation.
1311 */
1312__isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff,
1313	enum isl_dim_type type, int pos, isl_int v)
1314{
1315	if (!aff)
1316		return NULL;
1317
1318	if (type == isl_dim_out)
1319		isl_die(aff->v->ctx, isl_error_invalid,
1320			"output/set dimension does not have a coefficient",
1321			return isl_aff_free(aff));
1322	if (type == isl_dim_in)
1323		type = isl_dim_set;
1324
1325	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
1326		return isl_aff_free(aff);
1327
1328	if (isl_aff_is_nan(aff))
1329		return aff;
1330	aff = isl_aff_cow(aff);
1331	if (!aff)
1332		return NULL;
1333
1334	aff->v = isl_vec_cow(aff->v);
1335	if (!aff->v)
1336		return isl_aff_free(aff);
1337
1338	pos += isl_local_space_offset(aff->ls, type);
1339	isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v);
1340
1341	return aff;
1342}
1343
1344/* Add "v" to the coefficient of the variable of type "type"
1345 * at position "pos" of "aff".
1346 *
1347 * A NaN is unaffected by this operation.
1348 */
1349__isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff,
1350	enum isl_dim_type type, int pos, __isl_take isl_val *v)
1351{
1352	if (!aff || !v)
1353		goto error;
1354
1355	if (isl_val_is_zero(v)) {
1356		isl_val_free(v);
1357		return aff;
1358	}
1359
1360	if (type == isl_dim_out)
1361		isl_die(aff->v->ctx, isl_error_invalid,
1362			"output/set dimension does not have a coefficient",
1363			goto error);
1364	if (type == isl_dim_in)
1365		type = isl_dim_set;
1366
1367	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
1368		goto error;
1369
1370	if (isl_aff_is_nan(aff)) {
1371		isl_val_free(v);
1372		return aff;
1373	}
1374	if (!isl_val_is_rat(v))
1375		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
1376			"expecting rational value", goto error);
1377
1378	aff = isl_aff_cow(aff);
1379	if (!aff)
1380		goto error;
1381
1382	aff->v = isl_vec_cow(aff->v);
1383	if (!aff->v)
1384		goto error;
1385
1386	pos += isl_local_space_offset(aff->ls, type);
1387	if (isl_int_is_one(v->d)) {
1388		isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n);
1389	} else if (isl_int_eq(aff->v->el[0], v->d)) {
1390		isl_int_add(aff->v->el[1 + pos], aff->v->el[1 + pos], v->n);
1391		aff->v = isl_vec_normalize(aff->v);
1392		if (!aff->v)
1393			goto error;
1394	} else {
1395		isl_seq_scale(aff->v->el + 1,
1396				aff->v->el + 1, v->d, aff->v->size - 1);
1397		isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n);
1398		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
1399		aff->v = isl_vec_normalize(aff->v);
1400		if (!aff->v)
1401			goto error;
1402	}
1403
1404	isl_val_free(v);
1405	return aff;
1406error:
1407	isl_aff_free(aff);
1408	isl_val_free(v);
1409	return NULL;
1410}
1411
1412__isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff,
1413	enum isl_dim_type type, int pos, int v)
1414{
1415	isl_int t;
1416
1417	isl_int_init(t);
1418	isl_int_set_si(t, v);
1419	aff = isl_aff_add_coefficient(aff, type, pos, t);
1420	isl_int_clear(t);
1421
1422	return aff;
1423}
1424
1425__isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos)
1426{
1427	if (!aff)
1428		return NULL;
1429
1430	return isl_local_space_get_div(aff->ls, pos);
1431}
1432
1433/* Return the negation of "aff".
1434 *
1435 * As a special case, -NaN = NaN.
1436 */
1437__isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff)
1438{
1439	if (!aff)
1440		return NULL;
1441	if (isl_aff_is_nan(aff))
1442		return aff;
1443	aff = isl_aff_cow(aff);
1444	if (!aff)
1445		return NULL;
1446	aff->v = isl_vec_cow(aff->v);
1447	if (!aff->v)
1448		return isl_aff_free(aff);
1449
1450	isl_seq_neg(aff->v->el + 1, aff->v->el + 1, aff->v->size - 1);
1451
1452	return aff;
1453}
1454
1455/* Remove divs from the local space that do not appear in the affine
1456 * expression.
1457 * We currently only remove divs at the end.
1458 * Some intermediate divs may also not appear directly in the affine
1459 * expression, but we would also need to check that no other divs are
1460 * defined in terms of them.
1461 */
1462__isl_give isl_aff *isl_aff_remove_unused_divs(__isl_take isl_aff *aff)
1463{
1464	int pos;
1465	isl_size off;
1466	isl_size n;
1467
1468	n = isl_aff_domain_dim(aff, isl_dim_div);
1469	off = isl_aff_domain_offset(aff, isl_dim_div);
1470	if (n < 0 || off < 0)
1471		return isl_aff_free(aff);
1472
1473	pos = isl_seq_last_non_zero(aff->v->el + 1 + off, n) + 1;
1474	if (pos == n)
1475		return aff;
1476
1477	aff = isl_aff_cow(aff);
1478	if (!aff)
1479		return NULL;
1480
1481	aff->ls = isl_local_space_drop_dims(aff->ls, isl_dim_div, pos, n - pos);
1482	aff->v = isl_vec_drop_els(aff->v, 1 + off + pos, n - pos);
1483	if (!aff->ls || !aff->v)
1484		return isl_aff_free(aff);
1485
1486	return aff;
1487}
1488
1489/* Look for any divs in the aff->ls with a denominator equal to one
1490 * and plug them into the affine expression and any subsequent divs
1491 * that may reference the div.
1492 */
1493static __isl_give isl_aff *plug_in_integral_divs(__isl_take isl_aff *aff)
1494{
1495	int i;
1496	isl_size n;
1497	int len;
1498	isl_int v;
1499	isl_vec *vec;
1500	isl_local_space *ls;
1501	isl_size off;
1502
1503	n = isl_aff_domain_dim(aff, isl_dim_div);
1504	off = isl_aff_domain_offset(aff, isl_dim_div);
1505	if (n < 0 || off < 0)
1506		return isl_aff_free(aff);
1507	len = aff->v->size;
1508	for (i = 0; i < n; ++i) {
1509		if (!isl_int_is_one(aff->ls->div->row[i][0]))
1510			continue;
1511		ls = isl_local_space_copy(aff->ls);
1512		ls = isl_local_space_substitute_seq(ls, isl_dim_div, i,
1513				aff->ls->div->row[i], len, i + 1, n - (i + 1));
1514		vec = isl_vec_copy(aff->v);
1515		vec = isl_vec_cow(vec);
1516		if (!ls || !vec)
1517			goto error;
1518
1519		isl_int_init(v);
1520
1521		isl_seq_substitute(vec->el, off + i, aff->ls->div->row[i],
1522					len, len, v);
1523
1524		isl_int_clear(v);
1525
1526		isl_vec_free(aff->v);
1527		aff->v = vec;
1528		isl_local_space_free(aff->ls);
1529		aff->ls = ls;
1530	}
1531
1532	return aff;
1533error:
1534	isl_vec_free(vec);
1535	isl_local_space_free(ls);
1536	return isl_aff_free(aff);
1537}
1538
1539/* Look for any divs j that appear with a unit coefficient inside
1540 * the definitions of other divs i and plug them into the definitions
1541 * of the divs i.
1542 *
1543 * In particular, an expression of the form
1544 *
1545 *	floor((f(..) + floor(g(..)/n))/m)
1546 *
1547 * is simplified to
1548 *
1549 *	floor((n * f(..) + g(..))/(n * m))
1550 *
1551 * This simplification is correct because we can move the expression
1552 * f(..) into the inner floor in the original expression to obtain
1553 *
1554 *	floor(floor((n * f(..) + g(..))/n)/m)
1555 *
1556 * from which we can derive the simplified expression.
1557 */
1558static __isl_give isl_aff *plug_in_unit_divs(__isl_take isl_aff *aff)
1559{
1560	int i, j;
1561	isl_size n;
1562	isl_size off;
1563
1564	n = isl_aff_domain_dim(aff, isl_dim_div);
1565	off = isl_aff_domain_offset(aff, isl_dim_div);
1566	if (n < 0 || off < 0)
1567		return isl_aff_free(aff);
1568	for (i = 1; i < n; ++i) {
1569		for (j = 0; j < i; ++j) {
1570			if (!isl_int_is_one(aff->ls->div->row[i][1 + off + j]))
1571				continue;
1572			aff->ls = isl_local_space_substitute_seq(aff->ls,
1573				isl_dim_div, j, aff->ls->div->row[j],
1574				aff->v->size, i, 1);
1575			if (!aff->ls)
1576				return isl_aff_free(aff);
1577		}
1578	}
1579
1580	return aff;
1581}
1582
1583/* Swap divs "a" and "b" in "aff", which is assumed to be non-NULL.
1584 *
1585 * Even though this function is only called on isl_affs with a single
1586 * reference, we are careful to only change aff->v and aff->ls together.
1587 */
1588static __isl_give isl_aff *swap_div(__isl_take isl_aff *aff, int a, int b)
1589{
1590	isl_size off = isl_aff_domain_offset(aff, isl_dim_div);
1591	isl_local_space *ls;
1592	isl_vec *v;
1593
1594	if (off < 0)
1595		return isl_aff_free(aff);
1596
1597	ls = isl_local_space_copy(aff->ls);
1598	ls = isl_local_space_swap_div(ls, a, b);
1599	v = isl_vec_copy(aff->v);
1600	v = isl_vec_cow(v);
1601	if (!ls || !v)
1602		goto error;
1603
1604	isl_int_swap(v->el[1 + off + a], v->el[1 + off + b]);
1605	isl_vec_free(aff->v);
1606	aff->v = v;
1607	isl_local_space_free(aff->ls);
1608	aff->ls = ls;
1609
1610	return aff;
1611error:
1612	isl_vec_free(v);
1613	isl_local_space_free(ls);
1614	return isl_aff_free(aff);
1615}
1616
1617/* Merge divs "a" and "b" in "aff", which is assumed to be non-NULL.
1618 *
1619 * We currently do not actually remove div "b", but simply add its
1620 * coefficient to that of "a" and then zero it out.
1621 */
1622static __isl_give isl_aff *merge_divs(__isl_take isl_aff *aff, int a, int b)
1623{
1624	isl_size off = isl_aff_domain_offset(aff, isl_dim_div);
1625
1626	if (off < 0)
1627		return isl_aff_free(aff);
1628
1629	if (isl_int_is_zero(aff->v->el[1 + off + b]))
1630		return aff;
1631
1632	aff->v = isl_vec_cow(aff->v);
1633	if (!aff->v)
1634		return isl_aff_free(aff);
1635
1636	isl_int_add(aff->v->el[1 + off + a],
1637		    aff->v->el[1 + off + a], aff->v->el[1 + off + b]);
1638	isl_int_set_si(aff->v->el[1 + off + b], 0);
1639
1640	return aff;
1641}
1642
1643/* Sort the divs in the local space of "aff" according to
1644 * the comparison function "cmp_row" in isl_local_space.c,
1645 * combining the coefficients of identical divs.
1646 *
1647 * Reordering divs does not change the semantics of "aff",
1648 * so there is no need to call isl_aff_cow.
1649 * Moreover, this function is currently only called on isl_affs
1650 * with a single reference.
1651 */
1652static __isl_give isl_aff *sort_divs(__isl_take isl_aff *aff)
1653{
1654	isl_size n;
1655	int i, j;
1656
1657	n = isl_aff_dim(aff, isl_dim_div);
1658	if (n < 0)
1659		return isl_aff_free(aff);
1660	for (i = 1; i < n; ++i) {
1661		for (j = i - 1; j >= 0; --j) {
1662			int cmp = isl_mat_cmp_div(aff->ls->div, j, j + 1);
1663			if (cmp < 0)
1664				break;
1665			if (cmp == 0)
1666				aff = merge_divs(aff, j, j + 1);
1667			else
1668				aff = swap_div(aff, j, j + 1);
1669			if (!aff)
1670				return NULL;
1671		}
1672	}
1673
1674	return aff;
1675}
1676
1677/* Normalize the representation of "aff".
1678 *
1679 * This function should only be called on "new" isl_affs, i.e.,
1680 * with only a single reference.  We therefore do not need to
1681 * worry about affecting other instances.
1682 */
1683__isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff)
1684{
1685	if (!aff)
1686		return NULL;
1687	aff->v = isl_vec_normalize(aff->v);
1688	if (!aff->v)
1689		return isl_aff_free(aff);
1690	aff = plug_in_integral_divs(aff);
1691	aff = plug_in_unit_divs(aff);
1692	aff = sort_divs(aff);
1693	aff = isl_aff_remove_unused_divs(aff);
1694	return aff;
1695}
1696
1697/* Given f, return floor(f).
1698 * If f is an integer expression, then just return f.
1699 * If f is a constant, then return the constant floor(f).
1700 * Otherwise, if f = g/m, write g = q m + r,
1701 * create a new div d = [r/m] and return the expression q + d.
1702 * The coefficients in r are taken to lie between -m/2 and m/2.
1703 *
1704 * reduce_div_coefficients performs the same normalization.
1705 *
1706 * As a special case, floor(NaN) = NaN.
1707 */
1708__isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff)
1709{
1710	int i;
1711	int size;
1712	isl_ctx *ctx;
1713	isl_vec *div;
1714
1715	if (!aff)
1716		return NULL;
1717
1718	if (isl_aff_is_nan(aff))
1719		return aff;
1720	if (isl_int_is_one(aff->v->el[0]))
1721		return aff;
1722
1723	aff = isl_aff_cow(aff);
1724	if (!aff)
1725		return NULL;
1726
1727	aff->v = isl_vec_cow(aff->v);
1728	if (!aff->v)
1729		return isl_aff_free(aff);
1730
1731	if (isl_aff_is_cst(aff)) {
1732		isl_int_fdiv_q(aff->v->el[1], aff->v->el[1], aff->v->el[0]);
1733		isl_int_set_si(aff->v->el[0], 1);
1734		return aff;
1735	}
1736
1737	div = isl_vec_copy(aff->v);
1738	div = isl_vec_cow(div);
1739	if (!div)
1740		return isl_aff_free(aff);
1741
1742	ctx = isl_aff_get_ctx(aff);
1743	isl_int_fdiv_q(aff->v->el[0], aff->v->el[0], ctx->two);
1744	for (i = 1; i < aff->v->size; ++i) {
1745		isl_int_fdiv_r(div->el[i], div->el[i], div->el[0]);
1746		isl_int_fdiv_q(aff->v->el[i], aff->v->el[i], div->el[0]);
1747		if (isl_int_gt(div->el[i], aff->v->el[0])) {
1748			isl_int_sub(div->el[i], div->el[i], div->el[0]);
1749			isl_int_add_ui(aff->v->el[i], aff->v->el[i], 1);
1750		}
1751	}
1752
1753	aff->ls = isl_local_space_add_div(aff->ls, div);
1754	if (!aff->ls)
1755		return isl_aff_free(aff);
1756
1757	size = aff->v->size;
1758	aff->v = isl_vec_extend(aff->v, size + 1);
1759	if (!aff->v)
1760		return isl_aff_free(aff);
1761	isl_int_set_si(aff->v->el[0], 1);
1762	isl_int_set_si(aff->v->el[size], 1);
1763
1764	aff = isl_aff_normalize(aff);
1765
1766	return aff;
1767}
1768
1769/* Compute
1770 *
1771 *	aff mod m = aff - m * floor(aff/m)
1772 *
1773 * with m an integer value.
1774 */
1775__isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff,
1776	__isl_take isl_val *m)
1777{
1778	isl_aff *res;
1779
1780	if (!aff || !m)
1781		goto error;
1782
1783	if (!isl_val_is_int(m))
1784		isl_die(isl_val_get_ctx(m), isl_error_invalid,
1785			"expecting integer modulo", goto error);
1786
1787	res = isl_aff_copy(aff);
1788	aff = isl_aff_scale_down_val(aff, isl_val_copy(m));
1789	aff = isl_aff_floor(aff);
1790	aff = isl_aff_scale_val(aff, m);
1791	res = isl_aff_sub(res, aff);
1792
1793	return res;
1794error:
1795	isl_aff_free(aff);
1796	isl_val_free(m);
1797	return NULL;
1798}
1799
1800/* Compute
1801 *
1802 *	pwaff mod m = pwaff - m * floor(pwaff/m)
1803 */
1804__isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m)
1805{
1806	isl_pw_aff *res;
1807
1808	res = isl_pw_aff_copy(pwaff);
1809	pwaff = isl_pw_aff_scale_down(pwaff, m);
1810	pwaff = isl_pw_aff_floor(pwaff);
1811	pwaff = isl_pw_aff_scale(pwaff, m);
1812	res = isl_pw_aff_sub(res, pwaff);
1813
1814	return res;
1815}
1816
1817/* Compute
1818 *
1819 *	pa mod m = pa - m * floor(pa/m)
1820 *
1821 * with m an integer value.
1822 */
1823__isl_give isl_pw_aff *isl_pw_aff_mod_val(__isl_take isl_pw_aff *pa,
1824	__isl_take isl_val *m)
1825{
1826	if (!pa || !m)
1827		goto error;
1828	if (!isl_val_is_int(m))
1829		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
1830			"expecting integer modulo", goto error);
1831	pa = isl_pw_aff_mod(pa, m->n);
1832	isl_val_free(m);
1833	return pa;
1834error:
1835	isl_pw_aff_free(pa);
1836	isl_val_free(m);
1837	return NULL;
1838}
1839
1840/* Given f, return ceil(f).
1841 * If f is an integer expression, then just return f.
1842 * Otherwise, let f be the expression
1843 *
1844 *	e/m
1845 *
1846 * then return
1847 *
1848 *	floor((e + m - 1)/m)
1849 *
1850 * As a special case, ceil(NaN) = NaN.
1851 */
1852__isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
1853{
1854	if (!aff)
1855		return NULL;
1856
1857	if (isl_aff_is_nan(aff))
1858		return aff;
1859	if (isl_int_is_one(aff->v->el[0]))
1860		return aff;
1861
1862	aff = isl_aff_cow(aff);
1863	if (!aff)
1864		return NULL;
1865	aff->v = isl_vec_cow(aff->v);
1866	if (!aff->v)
1867		return isl_aff_free(aff);
1868
1869	isl_int_add(aff->v->el[1], aff->v->el[1], aff->v->el[0]);
1870	isl_int_sub_ui(aff->v->el[1], aff->v->el[1], 1);
1871	aff = isl_aff_floor(aff);
1872
1873	return aff;
1874}
1875
1876/* Apply the expansion computed by isl_merge_divs.
1877 * The expansion itself is given by "exp" while the resulting
1878 * list of divs is given by "div".
1879 */
1880__isl_give isl_aff *isl_aff_expand_divs(__isl_take isl_aff *aff,
1881	__isl_take isl_mat *div, int *exp)
1882{
1883	isl_size old_n_div;
1884	isl_size new_n_div;
1885	isl_size offset;
1886
1887	aff = isl_aff_cow(aff);
1888
1889	offset = isl_aff_domain_offset(aff, isl_dim_div);
1890	old_n_div = isl_aff_domain_dim(aff, isl_dim_div);
1891	new_n_div = isl_mat_rows(div);
1892	if (offset < 0 || old_n_div < 0 || new_n_div < 0)
1893		goto error;
1894
1895	aff->v = isl_vec_expand(aff->v, 1 + offset, old_n_div, exp, new_n_div);
1896	aff->ls = isl_local_space_replace_divs(aff->ls, div);
1897	if (!aff->v || !aff->ls)
1898		return isl_aff_free(aff);
1899	return aff;
1900error:
1901	isl_aff_free(aff);
1902	isl_mat_free(div);
1903	return NULL;
1904}
1905
1906/* Add two affine expressions that live in the same local space.
1907 */
1908static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1,
1909	__isl_take isl_aff *aff2)
1910{
1911	isl_int gcd, f;
1912
1913	aff1 = isl_aff_cow(aff1);
1914	if (!aff1 || !aff2)
1915		goto error;
1916
1917	aff1->v = isl_vec_cow(aff1->v);
1918	if (!aff1->v)
1919		goto error;
1920
1921	isl_int_init(gcd);
1922	isl_int_init(f);
1923	isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0]);
1924	isl_int_divexact(f, aff2->v->el[0], gcd);
1925	isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1);
1926	isl_int_divexact(f, aff1->v->el[0], gcd);
1927	isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1);
1928	isl_int_divexact(f, aff2->v->el[0], gcd);
1929	isl_int_mul(aff1->v->el[0], aff1->v->el[0], f);
1930	isl_int_clear(f);
1931	isl_int_clear(gcd);
1932
1933	isl_aff_free(aff2);
1934	aff1 = isl_aff_normalize(aff1);
1935	return aff1;
1936error:
1937	isl_aff_free(aff1);
1938	isl_aff_free(aff2);
1939	return NULL;
1940}
1941
1942/* Replace one of the arguments by a NaN and free the other one.
1943 */
1944static __isl_give isl_aff *set_nan_free(__isl_take isl_aff *aff1,
1945	__isl_take isl_aff *aff2)
1946{
1947	isl_aff_free(aff2);
1948	return isl_aff_set_nan(aff1);
1949}
1950
1951/* Return the sum of "aff1" and "aff2".
1952 *
1953 * If either of the two is NaN, then the result is NaN.
1954 */
1955__isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
1956	__isl_take isl_aff *aff2)
1957{
1958	isl_ctx *ctx;
1959	int *exp1 = NULL;
1960	int *exp2 = NULL;
1961	isl_mat *div;
1962	isl_size n_div1, n_div2;
1963
1964	if (!aff1 || !aff2)
1965		goto error;
1966
1967	ctx = isl_aff_get_ctx(aff1);
1968	if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim))
1969		isl_die(ctx, isl_error_invalid,
1970			"spaces don't match", goto error);
1971
1972	if (isl_aff_is_nan(aff1)) {
1973		isl_aff_free(aff2);
1974		return aff1;
1975	}
1976	if (isl_aff_is_nan(aff2)) {
1977		isl_aff_free(aff1);
1978		return aff2;
1979	}
1980
1981	n_div1 = isl_aff_dim(aff1, isl_dim_div);
1982	n_div2 = isl_aff_dim(aff2, isl_dim_div);
1983	if (n_div1 < 0 || n_div2 < 0)
1984		goto error;
1985	if (n_div1 == 0 && n_div2 == 0)
1986		return add_expanded(aff1, aff2);
1987
1988	exp1 = isl_alloc_array(ctx, int, n_div1);
1989	exp2 = isl_alloc_array(ctx, int, n_div2);
1990	if ((n_div1 && !exp1) || (n_div2 && !exp2))
1991		goto error;
1992
1993	div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2);
1994	aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1);
1995	aff2 = isl_aff_expand_divs(aff2, div, exp2);
1996	free(exp1);
1997	free(exp2);
1998
1999	return add_expanded(aff1, aff2);
2000error:
2001	free(exp1);
2002	free(exp2);
2003	isl_aff_free(aff1);
2004	isl_aff_free(aff2);
2005	return NULL;
2006}
2007
2008__isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1,
2009	__isl_take isl_aff *aff2)
2010{
2011	return isl_aff_add(aff1, isl_aff_neg(aff2));
2012}
2013
2014/* Return the result of scaling "aff" by a factor of "f".
2015 *
2016 * As a special case, f * NaN = NaN.
2017 */
2018__isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f)
2019{
2020	isl_int gcd;
2021
2022	if (!aff)
2023		return NULL;
2024	if (isl_aff_is_nan(aff))
2025		return aff;
2026
2027	if (isl_int_is_one(f))
2028		return aff;
2029
2030	aff = isl_aff_cow(aff);
2031	if (!aff)
2032		return NULL;
2033	aff->v = isl_vec_cow(aff->v);
2034	if (!aff->v)
2035		return isl_aff_free(aff);
2036
2037	if (isl_int_is_pos(f) && isl_int_is_divisible_by(aff->v->el[0], f)) {
2038		isl_int_divexact(aff->v->el[0], aff->v->el[0], f);
2039		return aff;
2040	}
2041
2042	isl_int_init(gcd);
2043	isl_int_gcd(gcd, aff->v->el[0], f);
2044	isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd);
2045	isl_int_divexact(gcd, f, gcd);
2046	isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
2047	isl_int_clear(gcd);
2048
2049	return aff;
2050}
2051
2052/* Multiple "aff" by "v".
2053 */
2054__isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff,
2055	__isl_take isl_val *v)
2056{
2057	if (!aff || !v)
2058		goto error;
2059
2060	if (isl_val_is_one(v)) {
2061		isl_val_free(v);
2062		return aff;
2063	}
2064
2065	if (!isl_val_is_rat(v))
2066		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
2067			"expecting rational factor", goto error);
2068
2069	aff = isl_aff_scale(aff, v->n);
2070	aff = isl_aff_scale_down(aff, v->d);
2071
2072	isl_val_free(v);
2073	return aff;
2074error:
2075	isl_aff_free(aff);
2076	isl_val_free(v);
2077	return NULL;
2078}
2079
2080/* Return the result of scaling "aff" down by a factor of "f".
2081 *
2082 * As a special case, NaN/f = NaN.
2083 */
2084__isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f)
2085{
2086	isl_int gcd;
2087
2088	if (!aff)
2089		return NULL;
2090	if (isl_aff_is_nan(aff))
2091		return aff;
2092
2093	if (isl_int_is_one(f))
2094		return aff;
2095
2096	aff = isl_aff_cow(aff);
2097	if (!aff)
2098		return NULL;
2099
2100	if (isl_int_is_zero(f))
2101		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
2102			"cannot scale down by zero", return isl_aff_free(aff));
2103
2104	aff->v = isl_vec_cow(aff->v);
2105	if (!aff->v)
2106		return isl_aff_free(aff);
2107
2108	isl_int_init(gcd);
2109	isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd);
2110	isl_int_gcd(gcd, gcd, f);
2111	isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
2112	isl_int_divexact(gcd, f, gcd);
2113	isl_int_mul(aff->v->el[0], aff->v->el[0], gcd);
2114	isl_int_clear(gcd);
2115
2116	return aff;
2117}
2118
2119/* Divide "aff" by "v".
2120 */
2121__isl_give isl_aff *isl_aff_scale_down_val(__isl_take isl_aff *aff,
2122	__isl_take isl_val *v)
2123{
2124	if (!aff || !v)
2125		goto error;
2126
2127	if (isl_val_is_one(v)) {
2128		isl_val_free(v);
2129		return aff;
2130	}
2131
2132	if (!isl_val_is_rat(v))
2133		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
2134			"expecting rational factor", goto error);
2135	if (!isl_val_is_pos(v))
2136		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
2137			"factor needs to be positive", goto error);
2138
2139	aff = isl_aff_scale(aff, v->d);
2140	aff = isl_aff_scale_down(aff, v->n);
2141
2142	isl_val_free(v);
2143	return aff;
2144error:
2145	isl_aff_free(aff);
2146	isl_val_free(v);
2147	return NULL;
2148}
2149
2150__isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f)
2151{
2152	isl_int v;
2153
2154	if (f == 1)
2155		return aff;
2156
2157	isl_int_init(v);
2158	isl_int_set_ui(v, f);
2159	aff = isl_aff_scale_down(aff, v);
2160	isl_int_clear(v);
2161
2162	return aff;
2163}
2164
2165__isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff,
2166	enum isl_dim_type type, unsigned pos, const char *s)
2167{
2168	aff = isl_aff_cow(aff);
2169	if (!aff)
2170		return NULL;
2171	if (type == isl_dim_out)
2172		isl_die(aff->v->ctx, isl_error_invalid,
2173			"cannot set name of output/set dimension",
2174			return isl_aff_free(aff));
2175	if (type == isl_dim_in)
2176		type = isl_dim_set;
2177	aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s);
2178	if (!aff->ls)
2179		return isl_aff_free(aff);
2180
2181	return aff;
2182}
2183
2184__isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff,
2185	enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
2186{
2187	aff = isl_aff_cow(aff);
2188	if (!aff)
2189		goto error;
2190	if (type == isl_dim_out)
2191		isl_die(aff->v->ctx, isl_error_invalid,
2192			"cannot set name of output/set dimension",
2193			goto error);
2194	if (type == isl_dim_in)
2195		type = isl_dim_set;
2196	aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id);
2197	if (!aff->ls)
2198		return isl_aff_free(aff);
2199
2200	return aff;
2201error:
2202	isl_id_free(id);
2203	isl_aff_free(aff);
2204	return NULL;
2205}
2206
2207/* Replace the identifier of the input tuple of "aff" by "id".
2208 * type is currently required to be equal to isl_dim_in
2209 */
2210__isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff,
2211	enum isl_dim_type type, __isl_take isl_id *id)
2212{
2213	aff = isl_aff_cow(aff);
2214	if (!aff)
2215		goto error;
2216	if (type != isl_dim_in)
2217		isl_die(aff->v->ctx, isl_error_invalid,
2218			"cannot only set id of input tuple", goto error);
2219	aff->ls = isl_local_space_set_tuple_id(aff->ls, isl_dim_set, id);
2220	if (!aff->ls)
2221		return isl_aff_free(aff);
2222
2223	return aff;
2224error:
2225	isl_id_free(id);
2226	isl_aff_free(aff);
2227	return NULL;
2228}
2229
2230/* Exploit the equalities in "eq" to simplify the affine expression
2231 * and the expressions of the integer divisions in the local space.
2232 * The integer divisions in this local space are assumed to appear
2233 * as regular dimensions in "eq".
2234 */
2235static __isl_give isl_aff *isl_aff_substitute_equalities_lifted(
2236	__isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
2237{
2238	int i, j;
2239	unsigned o_div;
2240	unsigned n_div;
2241
2242	if (!eq)
2243		goto error;
2244	if (eq->n_eq == 0) {
2245		isl_basic_set_free(eq);
2246		return aff;
2247	}
2248
2249	aff = isl_aff_cow(aff);
2250	if (!aff)
2251		goto error;
2252
2253	aff->ls = isl_local_space_substitute_equalities(aff->ls,
2254							isl_basic_set_copy(eq));
2255	aff->v = isl_vec_cow(aff->v);
2256	if (!aff->ls || !aff->v)
2257		goto error;
2258
2259	o_div = isl_basic_set_offset(eq, isl_dim_div);
2260	n_div = eq->n_div;
2261	for (i = 0; i < eq->n_eq; ++i) {
2262		j = isl_seq_last_non_zero(eq->eq[i], o_div + n_div);
2263		if (j < 0 || j == 0 || j >= o_div)
2264			continue;
2265
2266		isl_seq_elim(aff->v->el + 1, eq->eq[i], j, o_div,
2267				&aff->v->el[0]);
2268	}
2269
2270	isl_basic_set_free(eq);
2271	aff = isl_aff_normalize(aff);
2272	return aff;
2273error:
2274	isl_basic_set_free(eq);
2275	isl_aff_free(aff);
2276	return NULL;
2277}
2278
2279/* Exploit the equalities in "eq" to simplify the affine expression
2280 * and the expressions of the integer divisions in the local space.
2281 */
2282__isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff,
2283	__isl_take isl_basic_set *eq)
2284{
2285	isl_size n_div;
2286
2287	n_div = isl_aff_domain_dim(aff, isl_dim_div);
2288	if (n_div < 0)
2289		goto error;
2290	if (n_div > 0)
2291		eq = isl_basic_set_add_dims(eq, isl_dim_set, n_div);
2292	return isl_aff_substitute_equalities_lifted(aff, eq);
2293error:
2294	isl_basic_set_free(eq);
2295	isl_aff_free(aff);
2296	return NULL;
2297}
2298
2299/* Look for equalities among the variables shared by context and aff
2300 * and the integer divisions of aff, if any.
2301 * The equalities are then used to eliminate coefficients and/or integer
2302 * divisions from aff.
2303 */
2304__isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff,
2305	__isl_take isl_set *context)
2306{
2307	isl_local_space *ls;
2308	isl_basic_set *hull;
2309
2310	ls = isl_aff_get_domain_local_space(aff);
2311	context = isl_local_space_lift_set(ls, context);
2312
2313	hull = isl_set_affine_hull(context);
2314	return isl_aff_substitute_equalities_lifted(aff, hull);
2315}
2316
2317__isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff,
2318	__isl_take isl_set *context)
2319{
2320	isl_set *dom_context = isl_set_universe(isl_aff_get_domain_space(aff));
2321	dom_context = isl_set_intersect_params(dom_context, context);
2322	return isl_aff_gist(aff, dom_context);
2323}
2324
2325/* Return a basic set containing those elements in the space
2326 * of aff where it is positive.  "rational" should not be set.
2327 *
2328 * If "aff" is NaN, then it is not positive.
2329 */
2330static __isl_give isl_basic_set *aff_pos_basic_set(__isl_take isl_aff *aff,
2331	int rational, void *user)
2332{
2333	isl_constraint *ineq;
2334	isl_basic_set *bset;
2335	isl_val *c;
2336
2337	if (!aff)
2338		return NULL;
2339	if (isl_aff_is_nan(aff)) {
2340		isl_space *space = isl_aff_get_domain_space(aff);
2341		isl_aff_free(aff);
2342		return isl_basic_set_empty(space);
2343	}
2344	if (rational)
2345		isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,
2346			"rational sets not supported", goto error);
2347
2348	ineq = isl_inequality_from_aff(aff);
2349	c = isl_constraint_get_constant_val(ineq);
2350	c = isl_val_sub_ui(c, 1);
2351	ineq = isl_constraint_set_constant_val(ineq, c);
2352
2353	bset = isl_basic_set_from_constraint(ineq);
2354	bset = isl_basic_set_simplify(bset);
2355	return bset;
2356error:
2357	isl_aff_free(aff);
2358	return NULL;
2359}
2360
2361/* Return a basic set containing those elements in the space
2362 * of aff where it is non-negative.
2363 * If "rational" is set, then return a rational basic set.
2364 *
2365 * If "aff" is NaN, then it is not non-negative (it's not negative either).
2366 */
2367static __isl_give isl_basic_set *aff_nonneg_basic_set(
2368	__isl_take isl_aff *aff, int rational, void *user)
2369{
2370	isl_constraint *ineq;
2371	isl_basic_set *bset;
2372
2373	if (!aff)
2374		return NULL;
2375	if (isl_aff_is_nan(aff)) {
2376		isl_space *space = isl_aff_get_domain_space(aff);
2377		isl_aff_free(aff);
2378		return isl_basic_set_empty(space);
2379	}
2380
2381	ineq = isl_inequality_from_aff(aff);
2382
2383	bset = isl_basic_set_from_constraint(ineq);
2384	if (rational)
2385		bset = isl_basic_set_set_rational(bset);
2386	bset = isl_basic_set_simplify(bset);
2387	return bset;
2388}
2389
2390/* Return a basic set containing those elements in the space
2391 * of aff where it is non-negative.
2392 */
2393__isl_give isl_basic_set *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff)
2394{
2395	return aff_nonneg_basic_set(aff, 0, NULL);
2396}
2397
2398/* Return a basic set containing those elements in the domain space
2399 * of "aff" where it is positive.
2400 */
2401__isl_give isl_basic_set *isl_aff_pos_basic_set(__isl_take isl_aff *aff)
2402{
2403	aff = isl_aff_add_constant_num_si(aff, -1);
2404	return isl_aff_nonneg_basic_set(aff);
2405}
2406
2407/* Return a basic set containing those elements in the domain space
2408 * of aff where it is negative.
2409 */
2410__isl_give isl_basic_set *isl_aff_neg_basic_set(__isl_take isl_aff *aff)
2411{
2412	aff = isl_aff_neg(aff);
2413	return isl_aff_pos_basic_set(aff);
2414}
2415
2416/* Return a basic set containing those elements in the space
2417 * of aff where it is zero.
2418 * If "rational" is set, then return a rational basic set.
2419 *
2420 * If "aff" is NaN, then it is not zero.
2421 */
2422static __isl_give isl_basic_set *aff_zero_basic_set(__isl_take isl_aff *aff,
2423	int rational, void *user)
2424{
2425	isl_constraint *ineq;
2426	isl_basic_set *bset;
2427
2428	if (!aff)
2429		return NULL;
2430	if (isl_aff_is_nan(aff)) {
2431		isl_space *space = isl_aff_get_domain_space(aff);
2432		isl_aff_free(aff);
2433		return isl_basic_set_empty(space);
2434	}
2435
2436	ineq = isl_equality_from_aff(aff);
2437
2438	bset = isl_basic_set_from_constraint(ineq);
2439	if (rational)
2440		bset = isl_basic_set_set_rational(bset);
2441	bset = isl_basic_set_simplify(bset);
2442	return bset;
2443}
2444
2445/* Return a basic set containing those elements in the space
2446 * of aff where it is zero.
2447 */
2448__isl_give isl_basic_set *isl_aff_zero_basic_set(__isl_take isl_aff *aff)
2449{
2450	return aff_zero_basic_set(aff, 0, NULL);
2451}
2452
2453/* Return a basic set containing those elements in the shared space
2454 * of aff1 and aff2 where aff1 is greater than or equal to aff2.
2455 */
2456__isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
2457	__isl_take isl_aff *aff2)
2458{
2459	aff1 = isl_aff_sub(aff1, aff2);
2460
2461	return isl_aff_nonneg_basic_set(aff1);
2462}
2463
2464/* Return a basic set containing those elements in the shared domain space
2465 * of "aff1" and "aff2" where "aff1" is greater than "aff2".
2466 */
2467__isl_give isl_basic_set *isl_aff_gt_basic_set(__isl_take isl_aff *aff1,
2468	__isl_take isl_aff *aff2)
2469{
2470	aff1 = isl_aff_sub(aff1, aff2);
2471
2472	return isl_aff_pos_basic_set(aff1);
2473}
2474
2475/* Return a set containing those elements in the shared space
2476 * of aff1 and aff2 where aff1 is greater than or equal to aff2.
2477 */
2478__isl_give isl_set *isl_aff_ge_set(__isl_take isl_aff *aff1,
2479	__isl_take isl_aff *aff2)
2480{
2481	return isl_set_from_basic_set(isl_aff_ge_basic_set(aff1, aff2));
2482}
2483
2484/* Return a set containing those elements in the shared domain space
2485 * of aff1 and aff2 where aff1 is greater than aff2.
2486 *
2487 * If either of the two inputs is NaN, then the result is empty,
2488 * as comparisons with NaN always return false.
2489 */
2490__isl_give isl_set *isl_aff_gt_set(__isl_take isl_aff *aff1,
2491	__isl_take isl_aff *aff2)
2492{
2493	return isl_set_from_basic_set(isl_aff_gt_basic_set(aff1, aff2));
2494}
2495
2496/* Return a basic set containing those elements in the shared space
2497 * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
2498 */
2499__isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
2500	__isl_take isl_aff *aff2)
2501{
2502	return isl_aff_ge_basic_set(aff2, aff1);
2503}
2504
2505/* Return a basic set containing those elements in the shared domain space
2506 * of "aff1" and "aff2" where "aff1" is smaller than "aff2".
2507 */
2508__isl_give isl_basic_set *isl_aff_lt_basic_set(__isl_take isl_aff *aff1,
2509	__isl_take isl_aff *aff2)
2510{
2511	return isl_aff_gt_basic_set(aff2, aff1);
2512}
2513
2514/* Return a set containing those elements in the shared space
2515 * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
2516 */
2517__isl_give isl_set *isl_aff_le_set(__isl_take isl_aff *aff1,
2518	__isl_take isl_aff *aff2)
2519{
2520	return isl_aff_ge_set(aff2, aff1);
2521}
2522
2523/* Return a set containing those elements in the shared domain space
2524 * of "aff1" and "aff2" where "aff1" is smaller than "aff2".
2525 */
2526__isl_give isl_set *isl_aff_lt_set(__isl_take isl_aff *aff1,
2527	__isl_take isl_aff *aff2)
2528{
2529	return isl_set_from_basic_set(isl_aff_lt_basic_set(aff1, aff2));
2530}
2531
2532/* Return a basic set containing those elements in the shared space
2533 * of aff1 and aff2 where aff1 and aff2 are equal.
2534 */
2535__isl_give isl_basic_set *isl_aff_eq_basic_set(__isl_take isl_aff *aff1,
2536	__isl_take isl_aff *aff2)
2537{
2538	aff1 = isl_aff_sub(aff1, aff2);
2539
2540	return isl_aff_zero_basic_set(aff1);
2541}
2542
2543/* Return a set containing those elements in the shared space
2544 * of aff1 and aff2 where aff1 and aff2 are equal.
2545 */
2546__isl_give isl_set *isl_aff_eq_set(__isl_take isl_aff *aff1,
2547	__isl_take isl_aff *aff2)
2548{
2549	return isl_set_from_basic_set(isl_aff_eq_basic_set(aff1, aff2));
2550}
2551
2552/* Return a set containing those elements in the shared domain space
2553 * of aff1 and aff2 where aff1 and aff2 are not equal.
2554 *
2555 * If either of the two inputs is NaN, then the result is empty,
2556 * as comparisons with NaN always return false.
2557 */
2558__isl_give isl_set *isl_aff_ne_set(__isl_take isl_aff *aff1,
2559	__isl_take isl_aff *aff2)
2560{
2561	isl_set *set_lt, *set_gt;
2562
2563	set_lt = isl_aff_lt_set(isl_aff_copy(aff1),
2564				isl_aff_copy(aff2));
2565	set_gt = isl_aff_gt_set(aff1, aff2);
2566	return isl_set_union_disjoint(set_lt, set_gt);
2567}
2568
2569__isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_set *dom,
2570	__isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
2571{
2572	aff1 = isl_aff_add(aff1, aff2);
2573	aff1 = isl_aff_gist(aff1, isl_set_copy(dom));
2574	return aff1;
2575}
2576
2577isl_bool isl_aff_is_empty(__isl_keep isl_aff *aff)
2578{
2579	if (!aff)
2580		return isl_bool_error;
2581
2582	return isl_bool_false;
2583}
2584
2585#undef TYPE
2586#define TYPE	isl_aff
2587static
2588#include "check_type_range_templ.c"
2589
2590/* Check whether the given affine expression has non-zero coefficient
2591 * for any dimension in the given range or if any of these dimensions
2592 * appear with non-zero coefficients in any of the integer divisions
2593 * involved in the affine expression.
2594 */
2595isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff,
2596	enum isl_dim_type type, unsigned first, unsigned n)
2597{
2598	int i;
2599	int *active = NULL;
2600	isl_bool involves = isl_bool_false;
2601
2602	if (!aff)
2603		return isl_bool_error;
2604	if (n == 0)
2605		return isl_bool_false;
2606	if (isl_aff_check_range(aff, type, first, n) < 0)
2607		return isl_bool_error;
2608
2609	active = isl_local_space_get_active(aff->ls, aff->v->el + 2);
2610	if (!active)
2611		goto error;
2612
2613	first += isl_local_space_offset(aff->ls, type) - 1;
2614	for (i = 0; i < n; ++i)
2615		if (active[first + i]) {
2616			involves = isl_bool_true;
2617			break;
2618		}
2619
2620	free(active);
2621
2622	return involves;
2623error:
2624	free(active);
2625	return isl_bool_error;
2626}
2627
2628/* Does "aff" involve any local variables, i.e., integer divisions?
2629 */
2630isl_bool isl_aff_involves_locals(__isl_keep isl_aff *aff)
2631{
2632	isl_size n;
2633
2634	n = isl_aff_dim(aff, isl_dim_div);
2635	if (n < 0)
2636		return isl_bool_error;
2637	return isl_bool_ok(n > 0);
2638}
2639
2640__isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff,
2641	enum isl_dim_type type, unsigned first, unsigned n)
2642{
2643	if (!aff)
2644		return NULL;
2645	if (type == isl_dim_out)
2646		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
2647			"cannot drop output/set dimension",
2648			return isl_aff_free(aff));
2649	if (type == isl_dim_in)
2650		type = isl_dim_set;
2651	if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
2652		return aff;
2653
2654	if (isl_local_space_check_range(aff->ls, type, first, n) < 0)
2655		return isl_aff_free(aff);
2656
2657	aff = isl_aff_cow(aff);
2658	if (!aff)
2659		return NULL;
2660
2661	aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n);
2662	if (!aff->ls)
2663		return isl_aff_free(aff);
2664
2665	first += 1 + isl_local_space_offset(aff->ls, type);
2666	aff->v = isl_vec_drop_els(aff->v, first, n);
2667	if (!aff->v)
2668		return isl_aff_free(aff);
2669
2670	return aff;
2671}
2672
2673/* Is the domain of "aff" a product?
2674 */
2675static isl_bool isl_aff_domain_is_product(__isl_keep isl_aff *aff)
2676{
2677	return isl_space_is_product(isl_aff_peek_domain_space(aff));
2678}
2679
2680#undef TYPE
2681#define TYPE	isl_aff
2682#include <isl_domain_factor_templ.c>
2683
2684/* Project the domain of the affine expression onto its parameter space.
2685 * The affine expression may not involve any of the domain dimensions.
2686 */
2687__isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
2688{
2689	isl_space *space;
2690	isl_size n;
2691
2692	n = isl_aff_dim(aff, isl_dim_in);
2693	if (n < 0)
2694		return isl_aff_free(aff);
2695	aff = isl_aff_drop_domain(aff, 0, n);
2696	space = isl_aff_get_domain_space(aff);
2697	space = isl_space_params(space);
2698	aff = isl_aff_reset_domain_space(aff, space);
2699	return aff;
2700}
2701
2702/* Convert an affine expression defined over a parameter domain
2703 * into one that is defined over a zero-dimensional set.
2704 */
2705__isl_give isl_aff *isl_aff_from_range(__isl_take isl_aff *aff)
2706{
2707	isl_local_space *ls;
2708
2709	ls = isl_aff_take_domain_local_space(aff);
2710	ls = isl_local_space_set_from_params(ls);
2711	aff = isl_aff_restore_domain_local_space(aff, ls);
2712
2713	return aff;
2714}
2715
2716__isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
2717	enum isl_dim_type type, unsigned first, unsigned n)
2718{
2719	if (!aff)
2720		return NULL;
2721	if (type == isl_dim_out)
2722		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
2723			"cannot insert output/set dimensions",
2724			return isl_aff_free(aff));
2725	if (type == isl_dim_in)
2726		type = isl_dim_set;
2727	if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
2728		return aff;
2729
2730	if (isl_local_space_check_range(aff->ls, type, first, 0) < 0)
2731		return isl_aff_free(aff);
2732
2733	aff = isl_aff_cow(aff);
2734	if (!aff)
2735		return NULL;
2736
2737	aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n);
2738	if (!aff->ls)
2739		return isl_aff_free(aff);
2740
2741	first += 1 + isl_local_space_offset(aff->ls, type);
2742	aff->v = isl_vec_insert_zero_els(aff->v, first, n);
2743	if (!aff->v)
2744		return isl_aff_free(aff);
2745
2746	return aff;
2747}
2748
2749__isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff,
2750	enum isl_dim_type type, unsigned n)
2751{
2752	isl_size pos;
2753
2754	pos = isl_aff_dim(aff, type);
2755	if (pos < 0)
2756		return isl_aff_free(aff);
2757
2758	return isl_aff_insert_dims(aff, type, pos, n);
2759}
2760
2761/* Move the "n" dimensions of "src_type" starting at "src_pos" of "aff"
2762 * to dimensions of "dst_type" at "dst_pos".
2763 *
2764 * We only support moving input dimensions to parameters and vice versa.
2765 */
2766__isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff,
2767	enum isl_dim_type dst_type, unsigned dst_pos,
2768	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2769{
2770	unsigned g_dst_pos;
2771	unsigned g_src_pos;
2772	isl_size src_off, dst_off;
2773
2774	if (!aff)
2775		return NULL;
2776	if (n == 0 &&
2777	    !isl_local_space_is_named_or_nested(aff->ls, src_type) &&
2778	    !isl_local_space_is_named_or_nested(aff->ls, dst_type))
2779		return aff;
2780
2781	if (dst_type == isl_dim_out || src_type == isl_dim_out)
2782		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
2783			"cannot move output/set dimension",
2784			return isl_aff_free(aff));
2785	if (dst_type == isl_dim_div || src_type == isl_dim_div)
2786		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
2787			"cannot move divs", return isl_aff_free(aff));
2788	if (dst_type == isl_dim_in)
2789		dst_type = isl_dim_set;
2790	if (src_type == isl_dim_in)
2791		src_type = isl_dim_set;
2792
2793	if (isl_local_space_check_range(aff->ls, src_type, src_pos, n) < 0)
2794		return isl_aff_free(aff);
2795	if (dst_type == src_type)
2796		isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,
2797			"moving dims within the same type not supported",
2798			return isl_aff_free(aff));
2799
2800	aff = isl_aff_cow(aff);
2801	src_off = isl_aff_domain_offset(aff, src_type);
2802	dst_off = isl_aff_domain_offset(aff, dst_type);
2803	if (src_off < 0 || dst_off < 0)
2804		return isl_aff_free(aff);
2805
2806	g_src_pos = 1 + src_off + src_pos;
2807	g_dst_pos = 1 + dst_off + dst_pos;
2808	if (dst_type > src_type)
2809		g_dst_pos -= n;
2810
2811	aff->v = isl_vec_move_els(aff->v, g_dst_pos, g_src_pos, n);
2812	aff->ls = isl_local_space_move_dims(aff->ls, dst_type, dst_pos,
2813						src_type, src_pos, n);
2814	if (!aff->v || !aff->ls)
2815		return isl_aff_free(aff);
2816
2817	aff = sort_divs(aff);
2818
2819	return aff;
2820}
2821
2822/* Given an affine function on a domain (A -> B),
2823 * interchange A and B in the wrapped domain
2824 * to obtain a function on the domain (B -> A).
2825 *
2826 * Since this may change the position of some variables,
2827 * it may also change the normalized order of the local variables.
2828 * Restore this order.  Since sort_divs assumes the input
2829 * has a single reference, an explicit isl_aff_cow is required.
2830 */
2831__isl_give isl_aff *isl_aff_domain_reverse(__isl_take isl_aff *aff)
2832{
2833	isl_space *space;
2834	isl_local_space *ls;
2835	isl_vec *v;
2836	isl_size n_in, n_out;
2837	unsigned offset;
2838
2839	space = isl_aff_peek_domain_space(aff);
2840	offset = isl_space_offset(space, isl_dim_set);
2841	n_in = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_in);
2842	n_out = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_out);
2843	if (offset < 0 || n_in < 0 || n_out < 0)
2844		return isl_aff_free(aff);
2845
2846	v = isl_aff_take_rat_aff(aff);
2847	v = isl_vec_move_els(v, 1 + 1 + offset, 1 + 1 + offset + n_in, n_out);
2848	aff = isl_aff_restore_rat_aff(aff, v);
2849
2850	ls = isl_aff_take_domain_local_space(aff);
2851	ls = isl_local_space_wrapped_reverse(ls);
2852	aff = isl_aff_restore_domain_local_space(aff, ls);
2853
2854	aff = isl_aff_cow(aff);
2855	aff = sort_divs(aff);
2856
2857	return aff;
2858}
2859
2860/* Return a zero isl_aff in the given space.
2861 *
2862 * This is a helper function for isl_pw_*_as_* that ensures a uniform
2863 * interface over all piecewise types.
2864 */
2865static __isl_give isl_aff *isl_aff_zero_in_space(__isl_take isl_space *space)
2866{
2867	isl_local_space *ls;
2868
2869	ls = isl_local_space_from_space(isl_space_domain(space));
2870	return isl_aff_zero_on_domain(ls);
2871}
2872
2873#define isl_aff_involves_nan isl_aff_is_nan
2874
2875#undef PW
2876#define PW isl_pw_aff
2877#undef BASE
2878#define BASE aff
2879#undef EL_IS_ZERO
2880#define EL_IS_ZERO is_empty
2881#undef ZERO
2882#define ZERO empty
2883#undef IS_ZERO
2884#define IS_ZERO is_empty
2885#undef FIELD
2886#define FIELD aff
2887#undef DEFAULT_IS_ZERO
2888#define DEFAULT_IS_ZERO 0
2889
2890#include <isl_pw_templ.c>
2891#include <isl_pw_un_op_templ.c>
2892#include <isl_pw_add_constant_val_templ.c>
2893#include <isl_pw_add_disjoint_templ.c>
2894#include <isl_pw_bind_domain_templ.c>
2895#include <isl_pw_domain_reverse_templ.c>
2896#include <isl_pw_eval.c>
2897#include <isl_pw_hash.c>
2898#include <isl_pw_fix_templ.c>
2899#include <isl_pw_from_range_templ.c>
2900#include <isl_pw_insert_dims_templ.c>
2901#include <isl_pw_insert_domain_templ.c>
2902#include <isl_pw_move_dims_templ.c>
2903#include <isl_pw_neg_templ.c>
2904#include <isl_pw_pullback_templ.c>
2905#include <isl_pw_scale_templ.c>
2906#include <isl_pw_sub_templ.c>
2907#include <isl_pw_union_opt.c>
2908
2909#undef BASE
2910#define BASE pw_aff
2911
2912#include <isl_union_single.c>
2913#include <isl_union_neg.c>
2914#include <isl_union_sub_templ.c>
2915
2916#undef BASE
2917#define BASE aff
2918
2919#include <isl_union_pw_templ.c>
2920
2921/* Compute a piecewise quasi-affine expression with a domain that
2922 * is the union of those of pwaff1 and pwaff2 and such that on each
2923 * cell, the quasi-affine expression is the maximum of those of pwaff1
2924 * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
2925 * cell, then the associated expression is the defined one.
2926 */
2927__isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
2928	__isl_take isl_pw_aff *pwaff2)
2929{
2930	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
2931	return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_ge_set);
2932}
2933
2934/* Compute a piecewise quasi-affine expression with a domain that
2935 * is the union of those of pwaff1 and pwaff2 and such that on each
2936 * cell, the quasi-affine expression is the minimum of those of pwaff1
2937 * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
2938 * cell, then the associated expression is the defined one.
2939 */
2940__isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
2941	__isl_take isl_pw_aff *pwaff2)
2942{
2943	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
2944	return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_le_set);
2945}
2946
2947__isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
2948	__isl_take isl_pw_aff *pwaff2, int max)
2949{
2950	if (max)
2951		return isl_pw_aff_union_max(pwaff1, pwaff2);
2952	else
2953		return isl_pw_aff_union_min(pwaff1, pwaff2);
2954}
2955
2956/* Is the domain of "pa" a product?
2957 */
2958static isl_bool isl_pw_aff_domain_is_product(__isl_keep isl_pw_aff *pa)
2959{
2960	return isl_space_domain_is_wrapping(isl_pw_aff_peek_space(pa));
2961}
2962
2963#undef TYPE
2964#define TYPE	isl_pw_aff
2965#include <isl_domain_factor_templ.c>
2966
2967/* Return a set containing those elements in the domain
2968 * of "pwaff" where it satisfies "fn" (if complement is 0) or
2969 * does not satisfy "fn" (if complement is 1).
2970 *
2971 * The pieces with a NaN never belong to the result since
2972 * NaN does not satisfy any property.
2973 */
2974static __isl_give isl_set *pw_aff_locus(__isl_take isl_pw_aff *pwaff,
2975	__isl_give isl_basic_set *(*fn)(__isl_take isl_aff *aff, int rational,
2976		void *user),
2977	int complement, void *user)
2978{
2979	int i;
2980	isl_set *set;
2981
2982	if (!pwaff)
2983		return NULL;
2984
2985	set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
2986
2987	for (i = 0; i < pwaff->n; ++i) {
2988		isl_basic_set *bset;
2989		isl_set *set_i, *locus;
2990		isl_bool rational;
2991
2992		if (isl_aff_is_nan(pwaff->p[i].aff))
2993			continue;
2994
2995		rational = isl_set_has_rational(pwaff->p[i].set);
2996		bset = fn(isl_aff_copy(pwaff->p[i].aff), rational, user);
2997		locus = isl_set_from_basic_set(bset);
2998		set_i = isl_set_copy(pwaff->p[i].set);
2999		if (complement)
3000			set_i = isl_set_subtract(set_i, locus);
3001		else
3002			set_i = isl_set_intersect(set_i, locus);
3003		set = isl_set_union_disjoint(set, set_i);
3004	}
3005
3006	isl_pw_aff_free(pwaff);
3007
3008	return set;
3009}
3010
3011/* Return a set containing those elements in the domain
3012 * of "pa" where it is positive.
3013 */
3014__isl_give isl_set *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa)
3015{
3016	return pw_aff_locus(pa, &aff_pos_basic_set, 0, NULL);
3017}
3018
3019/* Return a set containing those elements in the domain
3020 * of pwaff where it is non-negative.
3021 */
3022__isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff)
3023{
3024	return pw_aff_locus(pwaff, &aff_nonneg_basic_set, 0, NULL);
3025}
3026
3027/* Return a set containing those elements in the domain
3028 * of pwaff where it is zero.
3029 */
3030__isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff)
3031{
3032	return pw_aff_locus(pwaff, &aff_zero_basic_set, 0, NULL);
3033}
3034
3035/* Return a set containing those elements in the domain
3036 * of pwaff where it is not zero.
3037 */
3038__isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff)
3039{
3040	return pw_aff_locus(pwaff, &aff_zero_basic_set, 1, NULL);
3041}
3042
3043/* Bind the affine function "aff" to the parameter "id",
3044 * returning the elements in the domain where the affine expression
3045 * is equal to the parameter.
3046 */
3047__isl_give isl_basic_set *isl_aff_bind_id(__isl_take isl_aff *aff,
3048	__isl_take isl_id *id)
3049{
3050	isl_space *space;
3051	isl_aff *aff_id;
3052
3053	space = isl_aff_get_domain_space(aff);
3054	space = isl_space_add_param_id(space, isl_id_copy(id));
3055
3056	aff = isl_aff_align_params(aff, isl_space_copy(space));
3057	aff_id = isl_aff_param_on_domain_space_id(space, id);
3058
3059	return isl_aff_eq_basic_set(aff, aff_id);
3060}
3061
3062/* Wrapper around isl_aff_bind_id for use as pw_aff_locus callback.
3063 * "rational" should not be set.
3064 */
3065static __isl_give isl_basic_set *aff_bind_id(__isl_take isl_aff *aff,
3066	int rational, void *user)
3067{
3068	isl_id *id = user;
3069
3070	if (!aff)
3071		return NULL;
3072	if (rational)
3073		isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,
3074			"rational binding not supported", goto error);
3075	return isl_aff_bind_id(aff, isl_id_copy(id));
3076error:
3077	isl_aff_free(aff);
3078	return NULL;
3079}
3080
3081/* Bind the piecewise affine function "pa" to the parameter "id",
3082 * returning the elements in the domain where the expression
3083 * is equal to the parameter.
3084 */
3085__isl_give isl_set *isl_pw_aff_bind_id(__isl_take isl_pw_aff *pa,
3086	__isl_take isl_id *id)
3087{
3088	isl_set *bound;
3089
3090	bound = pw_aff_locus(pa, &aff_bind_id, 0, id);
3091	isl_id_free(id);
3092
3093	return bound;
3094}
3095
3096/* Return a set containing those elements in the shared domain
3097 * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2.
3098 *
3099 * We compute the difference on the shared domain and then construct
3100 * the set of values where this difference is non-negative.
3101 * If strict is set, we first subtract 1 from the difference.
3102 * If equal is set, we only return the elements where pwaff1 and pwaff2
3103 * are equal.
3104 */
3105static __isl_give isl_set *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1,
3106	__isl_take isl_pw_aff *pwaff2, int strict, int equal)
3107{
3108	isl_set *set1, *set2;
3109
3110	set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1));
3111	set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2));
3112	set1 = isl_set_intersect(set1, set2);
3113	pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1));
3114	pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1));
3115	pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2));
3116
3117	if (strict) {
3118		isl_space *space = isl_set_get_space(set1);
3119		isl_aff *aff;
3120		aff = isl_aff_zero_on_domain(isl_local_space_from_space(space));
3121		aff = isl_aff_add_constant_si(aff, -1);
3122		pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff));
3123	} else
3124		isl_set_free(set1);
3125
3126	if (equal)
3127		return isl_pw_aff_zero_set(pwaff1);
3128	return isl_pw_aff_nonneg_set(pwaff1);
3129}
3130
3131/* Return a set containing those elements in the shared domain
3132 * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2.
3133 */
3134__isl_give isl_set *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
3135	__isl_take isl_pw_aff *pwaff2)
3136{
3137	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
3138	return pw_aff_gte_set(pwaff1, pwaff2, 0, 1);
3139}
3140
3141/* Return a set containing those elements in the shared domain
3142 * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
3143 */
3144__isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
3145	__isl_take isl_pw_aff *pwaff2)
3146{
3147	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
3148	return pw_aff_gte_set(pwaff1, pwaff2, 0, 0);
3149}
3150
3151/* Return a set containing those elements in the shared domain
3152 * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2.
3153 */
3154__isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
3155	__isl_take isl_pw_aff *pwaff2)
3156{
3157	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
3158	return pw_aff_gte_set(pwaff1, pwaff2, 1, 0);
3159}
3160
3161__isl_give isl_set *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1,
3162	__isl_take isl_pw_aff *pwaff2)
3163{
3164	return isl_pw_aff_ge_set(pwaff2, pwaff1);
3165}
3166
3167__isl_give isl_set *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1,
3168	__isl_take isl_pw_aff *pwaff2)
3169{
3170	return isl_pw_aff_gt_set(pwaff2, pwaff1);
3171}
3172
3173/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3174 * where the function values are ordered in the same way as "order",
3175 * which returns a set in the shared domain of its two arguments.
3176 *
3177 * Let "pa1" and "pa2" be defined on domains A and B respectively.
3178 * We first pull back the two functions such that they are defined on
3179 * the domain [A -> B].  Then we apply "order", resulting in a set
3180 * in the space [A -> B].  Finally, we unwrap this set to obtain
3181 * a map in the space A -> B.
3182 */
3183static __isl_give isl_map *isl_pw_aff_order_map(
3184	__isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2,
3185	__isl_give isl_set *(*order)(__isl_take isl_pw_aff *pa1,
3186		__isl_take isl_pw_aff *pa2))
3187{
3188	isl_space *space1, *space2;
3189	isl_multi_aff *ma;
3190	isl_set *set;
3191
3192	isl_pw_aff_align_params_bin(&pa1, &pa2);
3193	space1 = isl_space_domain(isl_pw_aff_get_space(pa1));
3194	space2 = isl_space_domain(isl_pw_aff_get_space(pa2));
3195	space1 = isl_space_map_from_domain_and_range(space1, space2);
3196	ma = isl_multi_aff_domain_map(isl_space_copy(space1));
3197	pa1 = isl_pw_aff_pullback_multi_aff(pa1, ma);
3198	ma = isl_multi_aff_range_map(space1);
3199	pa2 = isl_pw_aff_pullback_multi_aff(pa2, ma);
3200	set = order(pa1, pa2);
3201
3202	return isl_set_unwrap(set);
3203}
3204
3205/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3206 * where the function values are equal.
3207 */
3208__isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1,
3209	__isl_take isl_pw_aff *pa2)
3210{
3211	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_eq_set);
3212}
3213
3214/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3215 * where the function value of "pa1" is less than or equal to
3216 * the function value of "pa2".
3217 */
3218__isl_give isl_map *isl_pw_aff_le_map(__isl_take isl_pw_aff *pa1,
3219	__isl_take isl_pw_aff *pa2)
3220{
3221	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_le_set);
3222}
3223
3224/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3225 * where the function value of "pa1" is less than the function value of "pa2".
3226 */
3227__isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1,
3228	__isl_take isl_pw_aff *pa2)
3229{
3230	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_lt_set);
3231}
3232
3233/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3234 * where the function value of "pa1" is greater than or equal to
3235 * the function value of "pa2".
3236 */
3237__isl_give isl_map *isl_pw_aff_ge_map(__isl_take isl_pw_aff *pa1,
3238	__isl_take isl_pw_aff *pa2)
3239{
3240	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_ge_set);
3241}
3242
3243/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3244 * where the function value of "pa1" is greater than the function value
3245 * of "pa2".
3246 */
3247__isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1,
3248	__isl_take isl_pw_aff *pa2)
3249{
3250	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_gt_set);
3251}
3252
3253/* Return a set containing those elements in the shared domain
3254 * of the elements of list1 and list2 where each element in list1
3255 * has the relation specified by "fn" with each element in list2.
3256 */
3257static __isl_give isl_set *pw_aff_list_set(__isl_take isl_pw_aff_list *list1,
3258	__isl_take isl_pw_aff_list *list2,
3259	__isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
3260				    __isl_take isl_pw_aff *pwaff2))
3261{
3262	int i, j;
3263	isl_ctx *ctx;
3264	isl_set *set;
3265
3266	if (!list1 || !list2)
3267		goto error;
3268
3269	ctx = isl_pw_aff_list_get_ctx(list1);
3270	if (list1->n < 1 || list2->n < 1)
3271		isl_die(ctx, isl_error_invalid,
3272			"list should contain at least one element", goto error);
3273
3274	set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0]));
3275	for (i = 0; i < list1->n; ++i)
3276		for (j = 0; j < list2->n; ++j) {
3277			isl_set *set_ij;
3278
3279			set_ij = fn(isl_pw_aff_copy(list1->p[i]),
3280				    isl_pw_aff_copy(list2->p[j]));
3281			set = isl_set_intersect(set, set_ij);
3282		}
3283
3284	isl_pw_aff_list_free(list1);
3285	isl_pw_aff_list_free(list2);
3286	return set;
3287error:
3288	isl_pw_aff_list_free(list1);
3289	isl_pw_aff_list_free(list2);
3290	return NULL;
3291}
3292
3293/* Return a set containing those elements in the shared domain
3294 * of the elements of list1 and list2 where each element in list1
3295 * is equal to each element in list2.
3296 */
3297__isl_give isl_set *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1,
3298	__isl_take isl_pw_aff_list *list2)
3299{
3300	return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set);
3301}
3302
3303__isl_give isl_set *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1,
3304	__isl_take isl_pw_aff_list *list2)
3305{
3306	return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set);
3307}
3308
3309/* Return a set containing those elements in the shared domain
3310 * of the elements of list1 and list2 where each element in list1
3311 * is less than or equal to each element in list2.
3312 */
3313__isl_give isl_set *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1,
3314	__isl_take isl_pw_aff_list *list2)
3315{
3316	return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set);
3317}
3318
3319__isl_give isl_set *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1,
3320	__isl_take isl_pw_aff_list *list2)
3321{
3322	return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set);
3323}
3324
3325__isl_give isl_set *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1,
3326	__isl_take isl_pw_aff_list *list2)
3327{
3328	return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set);
3329}
3330
3331__isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
3332	__isl_take isl_pw_aff_list *list2)
3333{
3334	return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set);
3335}
3336
3337
3338/* Return a set containing those elements in the shared domain
3339 * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2.
3340 */
3341__isl_give isl_set *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
3342	__isl_take isl_pw_aff *pwaff2)
3343{
3344	isl_set *set_lt, *set_gt;
3345
3346	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
3347	set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1),
3348				   isl_pw_aff_copy(pwaff2));
3349	set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2);
3350	return isl_set_union_disjoint(set_lt, set_gt);
3351}
3352
3353__isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
3354	isl_int v)
3355{
3356	int i;
3357
3358	if (isl_int_is_one(v))
3359		return pwaff;
3360	if (!isl_int_is_pos(v))
3361		isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
3362			"factor needs to be positive",
3363			return isl_pw_aff_free(pwaff));
3364	pwaff = isl_pw_aff_cow(pwaff);
3365	if (!pwaff)
3366		return NULL;
3367	if (pwaff->n == 0)
3368		return pwaff;
3369
3370	for (i = 0; i < pwaff->n; ++i) {
3371		pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v);
3372		if (!pwaff->p[i].aff)
3373			return isl_pw_aff_free(pwaff);
3374	}
3375
3376	return pwaff;
3377}
3378
3379__isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff)
3380{
3381	struct isl_pw_aff_un_op_control control = { .fn_base = &isl_aff_floor };
3382	return isl_pw_aff_un_op(pwaff, &control);
3383}
3384
3385__isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff)
3386{
3387	struct isl_pw_aff_un_op_control control = { .fn_base = &isl_aff_ceil };
3388	return isl_pw_aff_un_op(pwaff, &control);
3389}
3390
3391/* Assuming that "cond1" and "cond2" are disjoint,
3392 * return an affine expression that is equal to pwaff1 on cond1
3393 * and to pwaff2 on cond2.
3394 */
3395static __isl_give isl_pw_aff *isl_pw_aff_select(
3396	__isl_take isl_set *cond1, __isl_take isl_pw_aff *pwaff1,
3397	__isl_take isl_set *cond2, __isl_take isl_pw_aff *pwaff2)
3398{
3399	pwaff1 = isl_pw_aff_intersect_domain(pwaff1, cond1);
3400	pwaff2 = isl_pw_aff_intersect_domain(pwaff2, cond2);
3401
3402	return isl_pw_aff_add_disjoint(pwaff1, pwaff2);
3403}
3404
3405/* Return an affine expression that is equal to pwaff_true for elements
3406 * where "cond" is non-zero and to pwaff_false for elements where "cond"
3407 * is zero.
3408 * That is, return cond ? pwaff_true : pwaff_false;
3409 *
3410 * If "cond" involves and NaN, then we conservatively return a NaN
3411 * on its entire domain.  In principle, we could consider the pieces
3412 * where it is NaN separately from those where it is not.
3413 *
3414 * If "pwaff_true" and "pwaff_false" are obviously equal to each other,
3415 * then only use the domain of "cond" to restrict the domain.
3416 */
3417__isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond,
3418	__isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
3419{
3420	isl_set *cond_true, *cond_false;
3421	isl_bool equal;
3422
3423	if (!cond)
3424		goto error;
3425	if (isl_pw_aff_involves_nan(cond)) {
3426		isl_space *space = isl_pw_aff_get_domain_space(cond);
3427		isl_local_space *ls = isl_local_space_from_space(space);
3428		isl_pw_aff_free(cond);
3429		isl_pw_aff_free(pwaff_true);
3430		isl_pw_aff_free(pwaff_false);
3431		return isl_pw_aff_nan_on_domain(ls);
3432	}
3433
3434	pwaff_true = isl_pw_aff_align_params(pwaff_true,
3435					    isl_pw_aff_get_space(pwaff_false));
3436	pwaff_false = isl_pw_aff_align_params(pwaff_false,
3437					    isl_pw_aff_get_space(pwaff_true));
3438	equal = isl_pw_aff_plain_is_equal(pwaff_true, pwaff_false);
3439	if (equal < 0)
3440		goto error;
3441	if (equal) {
3442		isl_set *dom;
3443
3444		dom = isl_set_coalesce(isl_pw_aff_domain(cond));
3445		isl_pw_aff_free(pwaff_false);
3446		return isl_pw_aff_intersect_domain(pwaff_true, dom);
3447	}
3448
3449	cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond));
3450	cond_false = isl_pw_aff_zero_set(cond);
3451	return isl_pw_aff_select(cond_true, pwaff_true,
3452				 cond_false, pwaff_false);
3453error:
3454	isl_pw_aff_free(cond);
3455	isl_pw_aff_free(pwaff_true);
3456	isl_pw_aff_free(pwaff_false);
3457	return NULL;
3458}
3459
3460isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff)
3461{
3462	int pos;
3463
3464	if (!aff)
3465		return isl_bool_error;
3466
3467	pos = isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2);
3468	return isl_bool_ok(pos == -1);
3469}
3470
3471/* Check whether pwaff is a piecewise constant.
3472 */
3473isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff)
3474{
3475	int i;
3476
3477	if (!pwaff)
3478		return isl_bool_error;
3479
3480	for (i = 0; i < pwaff->n; ++i) {
3481		isl_bool is_cst = isl_aff_is_cst(pwaff->p[i].aff);
3482		if (is_cst < 0 || !is_cst)
3483			return is_cst;
3484	}
3485
3486	return isl_bool_true;
3487}
3488
3489/* Return the product of "aff1" and "aff2".
3490 *
3491 * If either of the two is NaN, then the result is NaN.
3492 *
3493 * Otherwise, at least one of "aff1" or "aff2" needs to be a constant.
3494 */
3495__isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
3496	__isl_take isl_aff *aff2)
3497{
3498	if (!aff1 || !aff2)
3499		goto error;
3500
3501	if (isl_aff_is_nan(aff1)) {
3502		isl_aff_free(aff2);
3503		return aff1;
3504	}
3505	if (isl_aff_is_nan(aff2)) {
3506		isl_aff_free(aff1);
3507		return aff2;
3508	}
3509
3510	if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
3511		return isl_aff_mul(aff2, aff1);
3512
3513	if (!isl_aff_is_cst(aff2))
3514		isl_die(isl_aff_get_ctx(aff1), isl_error_invalid,
3515			"at least one affine expression should be constant",
3516			goto error);
3517
3518	aff1 = isl_aff_cow(aff1);
3519	if (!aff1 || !aff2)
3520		goto error;
3521
3522	aff1 = isl_aff_scale(aff1, aff2->v->el[1]);
3523	aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]);
3524
3525	isl_aff_free(aff2);
3526	return aff1;
3527error:
3528	isl_aff_free(aff1);
3529	isl_aff_free(aff2);
3530	return NULL;
3531}
3532
3533/* Divide "aff1" by "aff2", assuming "aff2" is a constant.
3534 *
3535 * If either of the two is NaN, then the result is NaN.
3536 * A division by zero also results in NaN.
3537 */
3538__isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1,
3539	__isl_take isl_aff *aff2)
3540{
3541	isl_bool is_cst, is_zero;
3542	int neg;
3543
3544	if (!aff1 || !aff2)
3545		goto error;
3546
3547	if (isl_aff_is_nan(aff1)) {
3548		isl_aff_free(aff2);
3549		return aff1;
3550	}
3551	if (isl_aff_is_nan(aff2)) {
3552		isl_aff_free(aff1);
3553		return aff2;
3554	}
3555
3556	is_cst = isl_aff_is_cst(aff2);
3557	if (is_cst < 0)
3558		goto error;
3559	if (!is_cst)
3560		isl_die(isl_aff_get_ctx(aff2), isl_error_invalid,
3561			"second argument should be a constant", goto error);
3562	is_zero = isl_aff_plain_is_zero(aff2);
3563	if (is_zero < 0)
3564		goto error;
3565	if (is_zero)
3566		return set_nan_free(aff1, aff2);
3567
3568	neg = isl_int_is_neg(aff2->v->el[1]);
3569	if (neg) {
3570		isl_int_neg(aff2->v->el[0], aff2->v->el[0]);
3571		isl_int_neg(aff2->v->el[1], aff2->v->el[1]);
3572	}
3573
3574	aff1 = isl_aff_scale(aff1, aff2->v->el[0]);
3575	aff1 = isl_aff_scale_down(aff1, aff2->v->el[1]);
3576
3577	if (neg) {
3578		isl_int_neg(aff2->v->el[0], aff2->v->el[0]);
3579		isl_int_neg(aff2->v->el[1], aff2->v->el[1]);
3580	}
3581
3582	isl_aff_free(aff2);
3583	return aff1;
3584error:
3585	isl_aff_free(aff1);
3586	isl_aff_free(aff2);
3587	return NULL;
3588}
3589
3590__isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1,
3591	__isl_take isl_pw_aff *pwaff2)
3592{
3593	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
3594	return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add);
3595}
3596
3597__isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
3598	__isl_take isl_pw_aff *pwaff2)
3599{
3600	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
3601	return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul);
3602}
3603
3604/* Divide "pa1" by "pa2", assuming "pa2" is a piecewise constant.
3605 */
3606__isl_give isl_pw_aff *isl_pw_aff_div(__isl_take isl_pw_aff *pa1,
3607	__isl_take isl_pw_aff *pa2)
3608{
3609	int is_cst;
3610
3611	is_cst = isl_pw_aff_is_cst(pa2);
3612	if (is_cst < 0)
3613		goto error;
3614	if (!is_cst)
3615		isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
3616			"second argument should be a piecewise constant",
3617			goto error);
3618	isl_pw_aff_align_params_bin(&pa1, &pa2);
3619	return isl_pw_aff_on_shared_domain(pa1, pa2, &isl_aff_div);
3620error:
3621	isl_pw_aff_free(pa1);
3622	isl_pw_aff_free(pa2);
3623	return NULL;
3624}
3625
3626/* Compute the quotient of the integer division of "pa1" by "pa2"
3627 * with rounding towards zero.
3628 * "pa2" is assumed to be a piecewise constant.
3629 *
3630 * In particular, return
3631 *
3632 *	pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2)
3633 *
3634 */
3635__isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1,
3636	__isl_take isl_pw_aff *pa2)
3637{
3638	int is_cst;
3639	isl_set *cond;
3640	isl_pw_aff *f, *c;
3641
3642	is_cst = isl_pw_aff_is_cst(pa2);
3643	if (is_cst < 0)
3644		goto error;
3645	if (!is_cst)
3646		isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
3647			"second argument should be a piecewise constant",
3648			goto error);
3649
3650	pa1 = isl_pw_aff_div(pa1, pa2);
3651
3652	cond = isl_pw_aff_nonneg_set(isl_pw_aff_copy(pa1));
3653	f = isl_pw_aff_floor(isl_pw_aff_copy(pa1));
3654	c = isl_pw_aff_ceil(pa1);
3655	return isl_pw_aff_cond(isl_set_indicator_function(cond), f, c);
3656error:
3657	isl_pw_aff_free(pa1);
3658	isl_pw_aff_free(pa2);
3659	return NULL;
3660}
3661
3662/* Compute the remainder of the integer division of "pa1" by "pa2"
3663 * with rounding towards zero.
3664 * "pa2" is assumed to be a piecewise constant.
3665 *
3666 * In particular, return
3667 *
3668 *	pa1 - pa2 * (pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2))
3669 *
3670 */
3671__isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1,
3672	__isl_take isl_pw_aff *pa2)
3673{
3674	int is_cst;
3675	isl_pw_aff *res;
3676
3677	is_cst = isl_pw_aff_is_cst(pa2);
3678	if (is_cst < 0)
3679		goto error;
3680	if (!is_cst)
3681		isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
3682			"second argument should be a piecewise constant",
3683			goto error);
3684	res = isl_pw_aff_tdiv_q(isl_pw_aff_copy(pa1), isl_pw_aff_copy(pa2));
3685	res = isl_pw_aff_mul(pa2, res);
3686	res = isl_pw_aff_sub(pa1, res);
3687	return res;
3688error:
3689	isl_pw_aff_free(pa1);
3690	isl_pw_aff_free(pa2);
3691	return NULL;
3692}
3693
3694/* Does either of "pa1" or "pa2" involve any NaN?
3695 */
3696static isl_bool either_involves_nan(__isl_keep isl_pw_aff *pa1,
3697	__isl_keep isl_pw_aff *pa2)
3698{
3699	isl_bool has_nan;
3700
3701	has_nan = isl_pw_aff_involves_nan(pa1);
3702	if (has_nan < 0 || has_nan)
3703		return has_nan;
3704	return isl_pw_aff_involves_nan(pa2);
3705}
3706
3707/* Return a piecewise affine expression defined on the specified domain
3708 * that represents NaN.
3709 */
3710static __isl_give isl_pw_aff *nan_on_domain_set(__isl_take isl_set *dom)
3711{
3712	isl_local_space *ls;
3713	isl_pw_aff *pa;
3714
3715	ls = isl_local_space_from_space(isl_set_get_space(dom));
3716	pa = isl_pw_aff_nan_on_domain(ls);
3717	pa = isl_pw_aff_intersect_domain(pa, dom);
3718
3719	return pa;
3720}
3721
3722/* Replace "pa1" and "pa2" (at least one of which involves a NaN)
3723 * by a NaN on their shared domain.
3724 *
3725 * In principle, the result could be refined to only being NaN
3726 * on the parts of this domain where at least one of "pa1" or "pa2" is NaN.
3727 */
3728static __isl_give isl_pw_aff *replace_by_nan(__isl_take isl_pw_aff *pa1,
3729	__isl_take isl_pw_aff *pa2)
3730{
3731	isl_set *dom;
3732
3733	dom = isl_set_intersect(isl_pw_aff_domain(pa1), isl_pw_aff_domain(pa2));
3734	return nan_on_domain_set(dom);
3735}
3736
3737static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
3738	__isl_take isl_pw_aff *pwaff2)
3739{
3740	isl_set *le;
3741	isl_set *dom;
3742
3743	dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
3744				isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
3745	le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1),
3746				isl_pw_aff_copy(pwaff2));
3747	dom = isl_set_subtract(dom, isl_set_copy(le));
3748	return isl_pw_aff_select(le, pwaff1, dom, pwaff2);
3749}
3750
3751static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1,
3752	__isl_take isl_pw_aff *pwaff2)
3753{
3754	isl_set *ge;
3755	isl_set *dom;
3756
3757	dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
3758				isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
3759	ge = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1),
3760				isl_pw_aff_copy(pwaff2));
3761	dom = isl_set_subtract(dom, isl_set_copy(ge));
3762	return isl_pw_aff_select(ge, pwaff1, dom, pwaff2);
3763}
3764
3765/* Return an expression for the minimum (if "max" is not set) or
3766 * the maximum (if "max" is set) of "pa1" and "pa2".
3767 * If either expression involves any NaN, then return a NaN
3768 * on the shared domain as result.
3769 */
3770static __isl_give isl_pw_aff *pw_aff_min_max(__isl_take isl_pw_aff *pa1,
3771	__isl_take isl_pw_aff *pa2, int max)
3772{
3773	isl_bool has_nan;
3774
3775	has_nan = either_involves_nan(pa1, pa2);
3776	if (has_nan < 0)
3777		pa1 = isl_pw_aff_free(pa1);
3778	else if (has_nan)
3779		return replace_by_nan(pa1, pa2);
3780
3781	isl_pw_aff_align_params_bin(&pa1, &pa2);
3782	if (max)
3783		return pw_aff_max(pa1, pa2);
3784	else
3785		return pw_aff_min(pa1, pa2);
3786}
3787
3788/* Return an expression for the minimum of "pwaff1" and "pwaff2".
3789 */
3790__isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1,
3791	__isl_take isl_pw_aff *pwaff2)
3792{
3793	return pw_aff_min_max(pwaff1, pwaff2, 0);
3794}
3795
3796/* Return an expression for the maximum of "pwaff1" and "pwaff2".
3797 */
3798__isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1,
3799	__isl_take isl_pw_aff *pwaff2)
3800{
3801	return pw_aff_min_max(pwaff1, pwaff2, 1);
3802}
3803
3804/* Does "pa" not involve any NaN?
3805 */
3806static isl_bool pw_aff_no_nan(__isl_keep isl_pw_aff *pa, void *user)
3807{
3808	return isl_bool_not(isl_pw_aff_involves_nan(pa));
3809}
3810
3811/* Does any element of "list" involve any NaN?
3812 *
3813 * That is, is it not the case that every element does not involve any NaN?
3814 */
3815static isl_bool isl_pw_aff_list_involves_nan(__isl_keep isl_pw_aff_list *list)
3816{
3817	return isl_bool_not(isl_pw_aff_list_every(list, &pw_aff_no_nan, NULL));
3818}
3819
3820/* Replace "list" (consisting of "n" elements, of which
3821 * at least one element involves a NaN)
3822 * by a NaN on the shared domain of the elements.
3823 *
3824 * In principle, the result could be refined to only being NaN
3825 * on the parts of this domain where at least one of the elements is NaN.
3826 */
3827static __isl_give isl_pw_aff *replace_list_by_nan(
3828	__isl_take isl_pw_aff_list *list, int n)
3829{
3830	int i;
3831	isl_set *dom;
3832
3833	dom = isl_pw_aff_domain(isl_pw_aff_list_get_at(list, 0));
3834	for (i = 1; i < n; ++i) {
3835		isl_set *dom_i;
3836
3837		dom_i = isl_pw_aff_domain(isl_pw_aff_list_get_at(list, i));
3838		dom = isl_set_intersect(dom, dom_i);
3839	}
3840
3841	isl_pw_aff_list_free(list);
3842	return nan_on_domain_set(dom);
3843}
3844
3845/* Return the set where the element at "pos1" of "list" is less than or
3846 * equal to the element at "pos2".
3847 * Equality is only allowed if "pos1" is smaller than "pos2".
3848 */
3849static __isl_give isl_set *less(__isl_keep isl_pw_aff_list *list,
3850	int pos1, int pos2)
3851{
3852	isl_pw_aff *pa1, *pa2;
3853
3854	pa1 = isl_pw_aff_list_get_at(list, pos1);
3855	pa2 = isl_pw_aff_list_get_at(list, pos2);
3856
3857	if (pos1 < pos2)
3858		return isl_pw_aff_le_set(pa1, pa2);
3859	else
3860		return isl_pw_aff_lt_set(pa1, pa2);
3861}
3862
3863/* Return an isl_pw_aff that maps each element in the intersection of the
3864 * domains of the piecewise affine expressions in "list"
3865 * to the maximal (if "max" is set) or minimal (if "max" is not set)
3866 * expression in "list" at that element.
3867 * If any expression involves any NaN, then return a NaN
3868 * on the shared domain as result.
3869 *
3870 * If "list" has n elements, then the result consists of n pieces,
3871 * where, in the case of a minimum, each piece has as value expression
3872 * the value expression of one of the elements and as domain
3873 * the set of elements where that value expression
3874 * is less than (or equal) to the other value expressions.
3875 * In the case of a maximum, the condition is
3876 * that all the other value expressions are less than (or equal)
3877 * to the given value expression.
3878 *
3879 * In order to produce disjoint pieces, a pair of elements
3880 * in the original domain is only allowed to be equal to each other
3881 * on exactly one of the two pieces corresponding to the two elements.
3882 * The position in the list is used to break ties.
3883 * In particular, in the case of a minimum,
3884 * in the piece corresponding to a given element,
3885 * this element is allowed to be equal to any later element in the list,
3886 * but not to any earlier element in the list.
3887 */
3888static __isl_give isl_pw_aff *isl_pw_aff_list_opt(
3889	__isl_take isl_pw_aff_list *list, int max)
3890{
3891	int i, j;
3892	isl_bool has_nan;
3893	isl_size n;
3894	isl_space *space;
3895	isl_pw_aff *pa, *res;
3896
3897	n = isl_pw_aff_list_size(list);
3898	if (n < 0)
3899		goto error;
3900	if (n < 1)
3901		isl_die(isl_pw_aff_list_get_ctx(list), isl_error_invalid,
3902			"list should contain at least one element", goto error);
3903
3904	has_nan = isl_pw_aff_list_involves_nan(list);
3905	if (has_nan < 0)
3906		goto error;
3907	if (has_nan)
3908		return replace_list_by_nan(list, n);
3909
3910	pa = isl_pw_aff_list_get_at(list, 0);
3911	space = isl_pw_aff_get_space(pa);
3912	isl_pw_aff_free(pa);
3913	res = isl_pw_aff_empty(space);
3914
3915	for (i = 0; i < n; ++i) {
3916		pa = isl_pw_aff_list_get_at(list, i);
3917		for (j = 0; j < n; ++j) {
3918			isl_set *dom;
3919
3920			if (j == i)
3921				continue;
3922			if (max)
3923				dom = less(list, j, i);
3924			else
3925				dom = less(list, i, j);
3926
3927			pa = isl_pw_aff_intersect_domain(pa, dom);
3928		}
3929		res =  isl_pw_aff_add_disjoint(res, pa);
3930	}
3931
3932	isl_pw_aff_list_free(list);
3933	return res;
3934error:
3935	isl_pw_aff_list_free(list);
3936	return NULL;
3937}
3938
3939/* Return an isl_pw_aff that maps each element in the intersection of the
3940 * domains of the elements of list to the minimal corresponding affine
3941 * expression.
3942 */
3943__isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list)
3944{
3945	return isl_pw_aff_list_opt(list, 0);
3946}
3947
3948/* Return an isl_pw_aff that maps each element in the intersection of the
3949 * domains of the elements of list to the maximal corresponding affine
3950 * expression.
3951 */
3952__isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list)
3953{
3954	return isl_pw_aff_list_opt(list, 1);
3955}
3956
3957/* Mark the domains of "pwaff" as rational.
3958 */
3959__isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff)
3960{
3961	int i;
3962
3963	pwaff = isl_pw_aff_cow(pwaff);
3964	if (!pwaff)
3965		return NULL;
3966	if (pwaff->n == 0)
3967		return pwaff;
3968
3969	for (i = 0; i < pwaff->n; ++i) {
3970		pwaff->p[i].set = isl_set_set_rational(pwaff->p[i].set);
3971		if (!pwaff->p[i].set)
3972			return isl_pw_aff_free(pwaff);
3973	}
3974
3975	return pwaff;
3976}
3977
3978/* Mark the domains of the elements of "list" as rational.
3979 */
3980__isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational(
3981	__isl_take isl_pw_aff_list *list)
3982{
3983	int i, n;
3984
3985	if (!list)
3986		return NULL;
3987	if (list->n == 0)
3988		return list;
3989
3990	n = list->n;
3991	for (i = 0; i < n; ++i) {
3992		isl_pw_aff *pa;
3993
3994		pa = isl_pw_aff_list_get_pw_aff(list, i);
3995		pa = isl_pw_aff_set_rational(pa);
3996		list = isl_pw_aff_list_set_pw_aff(list, i, pa);
3997	}
3998
3999	return list;
4000}
4001
4002/* Do the parameters of "aff" match those of "space"?
4003 */
4004isl_bool isl_aff_matching_params(__isl_keep isl_aff *aff,
4005	__isl_keep isl_space *space)
4006{
4007	isl_space *aff_space;
4008	isl_bool match;
4009
4010	if (!aff || !space)
4011		return isl_bool_error;
4012
4013	aff_space = isl_aff_get_domain_space(aff);
4014
4015	match = isl_space_has_equal_params(space, aff_space);
4016
4017	isl_space_free(aff_space);
4018	return match;
4019}
4020
4021/* Check that the domain space of "aff" matches "space".
4022 */
4023isl_stat isl_aff_check_match_domain_space(__isl_keep isl_aff *aff,
4024	__isl_keep isl_space *space)
4025{
4026	isl_space *aff_space;
4027	isl_bool match;
4028
4029	if (!aff || !space)
4030		return isl_stat_error;
4031
4032	aff_space = isl_aff_get_domain_space(aff);
4033
4034	match = isl_space_has_equal_params(space, aff_space);
4035	if (match < 0)
4036		goto error;
4037	if (!match)
4038		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
4039			"parameters don't match", goto error);
4040	match = isl_space_tuple_is_equal(space, isl_dim_in,
4041					aff_space, isl_dim_set);
4042	if (match < 0)
4043		goto error;
4044	if (!match)
4045		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
4046			"domains don't match", goto error);
4047	isl_space_free(aff_space);
4048	return isl_stat_ok;
4049error:
4050	isl_space_free(aff_space);
4051	return isl_stat_error;
4052}
4053
4054/* Return the shared (universe) domain of the elements of "ma".
4055 *
4056 * Since an isl_multi_aff (and an isl_aff) is always total,
4057 * the domain is always the universe set in its domain space.
4058 * This is a helper function for use in the generic isl_multi_*_bind.
4059 */
4060static __isl_give isl_basic_set *isl_multi_aff_domain(
4061	__isl_take isl_multi_aff *ma)
4062{
4063	isl_space *space;
4064
4065	space = isl_multi_aff_get_space(ma);
4066	isl_multi_aff_free(ma);
4067
4068	return isl_basic_set_universe(isl_space_domain(space));
4069}
4070
4071#undef BASE
4072#define BASE aff
4073
4074#include <isl_multi_no_explicit_domain.c>
4075#include <isl_multi_templ.c>
4076#include <isl_multi_un_op_templ.c>
4077#include <isl_multi_bin_val_templ.c>
4078#include <isl_multi_add_constant_templ.c>
4079#include <isl_multi_align_set.c>
4080#include <isl_multi_arith_templ.c>
4081#include <isl_multi_bind_domain_templ.c>
4082#include <isl_multi_cmp.c>
4083#include <isl_multi_dim_id_templ.c>
4084#include <isl_multi_dims.c>
4085#include <isl_multi_domain_reverse_templ.c>
4086#include <isl_multi_floor.c>
4087#include <isl_multi_from_base_templ.c>
4088#include <isl_multi_identity_templ.c>
4089#include <isl_multi_insert_domain_templ.c>
4090#include <isl_multi_locals_templ.c>
4091#include <isl_multi_move_dims_templ.c>
4092#include <isl_multi_nan_templ.c>
4093#include <isl_multi_product_templ.c>
4094#include <isl_multi_splice_templ.c>
4095#include <isl_multi_tuple_id_templ.c>
4096#include <isl_multi_unbind_params_templ.c>
4097#include <isl_multi_zero_templ.c>
4098
4099#undef DOMBASE
4100#define DOMBASE set
4101#include <isl_multi_check_domain_templ.c>
4102#include <isl_multi_apply_set_no_explicit_domain_templ.c>
4103#include <isl_multi_gist.c>
4104
4105#undef DOMBASE
4106#define DOMBASE basic_set
4107#include <isl_multi_bind_templ.c>
4108
4109/* Construct an isl_multi_aff living in "space" that corresponds
4110 * to the affine transformation matrix "mat".
4111 */
4112__isl_give isl_multi_aff *isl_multi_aff_from_aff_mat(
4113	__isl_take isl_space *space, __isl_take isl_mat *mat)
4114{
4115	isl_ctx *ctx;
4116	isl_local_space *ls = NULL;
4117	isl_multi_aff *ma = NULL;
4118	isl_size n_row, n_col, n_out, total;
4119	int i;
4120
4121	if (!space || !mat)
4122		goto error;
4123
4124	ctx = isl_mat_get_ctx(mat);
4125
4126	n_row = isl_mat_rows(mat);
4127	n_col = isl_mat_cols(mat);
4128	n_out = isl_space_dim(space, isl_dim_out);
4129	total = isl_space_dim(space, isl_dim_all);
4130	if (n_row < 0 || n_col < 0 || n_out < 0 || total < 0)
4131		goto error;
4132	if (n_row < 1)
4133		isl_die(ctx, isl_error_invalid,
4134			"insufficient number of rows", goto error);
4135	if (n_col < 1)
4136		isl_die(ctx, isl_error_invalid,
4137			"insufficient number of columns", goto error);
4138	if (1 + n_out != n_row || 2 + total != n_row + n_col)
4139		isl_die(ctx, isl_error_invalid,
4140			"dimension mismatch", goto error);
4141
4142	ma = isl_multi_aff_zero(isl_space_copy(space));
4143	space = isl_space_domain(space);
4144	ls = isl_local_space_from_space(isl_space_copy(space));
4145
4146	for (i = 0; i < n_row - 1; ++i) {
4147		isl_vec *v;
4148		isl_aff *aff;
4149
4150		v = isl_vec_alloc(ctx, 1 + n_col);
4151		if (!v)
4152			goto error;
4153		isl_int_set(v->el[0], mat->row[0][0]);
4154		isl_seq_cpy(v->el + 1, mat->row[1 + i], n_col);
4155		v = isl_vec_normalize(v);
4156		aff = isl_aff_alloc_vec_validated(isl_local_space_copy(ls), v);
4157		ma = isl_multi_aff_set_aff(ma, i, aff);
4158	}
4159
4160	isl_space_free(space);
4161	isl_local_space_free(ls);
4162	isl_mat_free(mat);
4163	return ma;
4164error:
4165	isl_space_free(space);
4166	isl_local_space_free(ls);
4167	isl_mat_free(mat);
4168	isl_multi_aff_free(ma);
4169	return NULL;
4170}
4171
4172/* Return the constant terms of the affine expressions of "ma".
4173 */
4174__isl_give isl_multi_val *isl_multi_aff_get_constant_multi_val(
4175	__isl_keep isl_multi_aff *ma)
4176{
4177	int i;
4178	isl_size n;
4179	isl_space *space;
4180	isl_multi_val *mv;
4181
4182	n = isl_multi_aff_size(ma);
4183	if (n < 0)
4184		return NULL;
4185	space = isl_space_range(isl_multi_aff_get_space(ma));
4186	space = isl_space_drop_all_params(space);
4187	mv = isl_multi_val_zero(space);
4188
4189	for (i = 0; i < n; ++i) {
4190		isl_aff *aff;
4191		isl_val *val;
4192
4193		aff = isl_multi_aff_get_at(ma, i);
4194		val = isl_aff_get_constant_val(aff);
4195		isl_aff_free(aff);
4196		mv = isl_multi_val_set_at(mv, i, val);
4197	}
4198
4199	return mv;
4200}
4201
4202/* Remove any internal structure of the domain of "ma".
4203 * If there is any such internal structure in the input,
4204 * then the name of the corresponding space is also removed.
4205 */
4206__isl_give isl_multi_aff *isl_multi_aff_flatten_domain(
4207	__isl_take isl_multi_aff *ma)
4208{
4209	isl_space *space;
4210
4211	if (!ma)
4212		return NULL;
4213
4214	if (!ma->space->nested[0])
4215		return ma;
4216
4217	space = isl_multi_aff_get_space(ma);
4218	space = isl_space_flatten_domain(space);
4219	ma = isl_multi_aff_reset_space(ma, space);
4220
4221	return ma;
4222}
4223
4224/* Given a map space, return an isl_multi_aff that maps a wrapped copy
4225 * of the space to its domain.
4226 */
4227__isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space)
4228{
4229	int i;
4230	isl_size n_in;
4231	isl_local_space *ls;
4232	isl_multi_aff *ma;
4233
4234	if (!space)
4235		return NULL;
4236	if (!isl_space_is_map(space))
4237		isl_die(isl_space_get_ctx(space), isl_error_invalid,
4238			"not a map space", goto error);
4239
4240	n_in = isl_space_dim(space, isl_dim_in);
4241	if (n_in < 0)
4242		goto error;
4243	space = isl_space_domain_map(space);
4244
4245	ma = isl_multi_aff_alloc(isl_space_copy(space));
4246	if (n_in == 0) {
4247		isl_space_free(space);
4248		return ma;
4249	}
4250
4251	space = isl_space_domain(space);
4252	ls = isl_local_space_from_space(space);
4253	for (i = 0; i < n_in; ++i) {
4254		isl_aff *aff;
4255
4256		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
4257						isl_dim_set, i);
4258		ma = isl_multi_aff_set_aff(ma, i, aff);
4259	}
4260	isl_local_space_free(ls);
4261	return ma;
4262error:
4263	isl_space_free(space);
4264	return NULL;
4265}
4266
4267/* This function performs the same operation as isl_multi_aff_domain_map,
4268 * but is considered as a function on an isl_space when exported.
4269 */
4270__isl_give isl_multi_aff *isl_space_domain_map_multi_aff(
4271	__isl_take isl_space *space)
4272{
4273	return isl_multi_aff_domain_map(space);
4274}
4275
4276/* Given a map space, return an isl_multi_aff that maps a wrapped copy
4277 * of the space to its range.
4278 */
4279__isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space)
4280{
4281	int i;
4282	isl_size n_in, n_out;
4283	isl_local_space *ls;
4284	isl_multi_aff *ma;
4285
4286	if (!space)
4287		return NULL;
4288	if (!isl_space_is_map(space))
4289		isl_die(isl_space_get_ctx(space), isl_error_invalid,
4290			"not a map space", goto error);
4291
4292	n_in = isl_space_dim(space, isl_dim_in);
4293	n_out = isl_space_dim(space, isl_dim_out);
4294	if (n_in < 0 || n_out < 0)
4295		goto error;
4296	space = isl_space_range_map(space);
4297
4298	ma = isl_multi_aff_alloc(isl_space_copy(space));
4299	if (n_out == 0) {
4300		isl_space_free(space);
4301		return ma;
4302	}
4303
4304	space = isl_space_domain(space);
4305	ls = isl_local_space_from_space(space);
4306	for (i = 0; i < n_out; ++i) {
4307		isl_aff *aff;
4308
4309		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
4310						isl_dim_set, n_in + i);
4311		ma = isl_multi_aff_set_aff(ma, i, aff);
4312	}
4313	isl_local_space_free(ls);
4314	return ma;
4315error:
4316	isl_space_free(space);
4317	return NULL;
4318}
4319
4320/* This function performs the same operation as isl_multi_aff_range_map,
4321 * but is considered as a function on an isl_space when exported.
4322 */
4323__isl_give isl_multi_aff *isl_space_range_map_multi_aff(
4324	__isl_take isl_space *space)
4325{
4326	return isl_multi_aff_range_map(space);
4327}
4328
4329/* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy
4330 * of the space to its domain.
4331 */
4332__isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_map(
4333	__isl_take isl_space *space)
4334{
4335	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_domain_map(space));
4336}
4337
4338/* This function performs the same operation as isl_pw_multi_aff_domain_map,
4339 * but is considered as a function on an isl_space when exported.
4340 */
4341__isl_give isl_pw_multi_aff *isl_space_domain_map_pw_multi_aff(
4342	__isl_take isl_space *space)
4343{
4344	return isl_pw_multi_aff_domain_map(space);
4345}
4346
4347/* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy
4348 * of the space to its range.
4349 */
4350__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map(
4351	__isl_take isl_space *space)
4352{
4353	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_range_map(space));
4354}
4355
4356/* This function performs the same operation as isl_pw_multi_aff_range_map,
4357 * but is considered as a function on an isl_space when exported.
4358 */
4359__isl_give isl_pw_multi_aff *isl_space_range_map_pw_multi_aff(
4360	__isl_take isl_space *space)
4361{
4362	return isl_pw_multi_aff_range_map(space);
4363}
4364
4365/* Given the space of a set and a range of set dimensions,
4366 * construct an isl_multi_aff that projects out those dimensions.
4367 */
4368__isl_give isl_multi_aff *isl_multi_aff_project_out_map(
4369	__isl_take isl_space *space, enum isl_dim_type type,
4370	unsigned first, unsigned n)
4371{
4372	int i;
4373	isl_size dim;
4374	isl_local_space *ls;
4375	isl_multi_aff *ma;
4376
4377	if (!space)
4378		return NULL;
4379	if (!isl_space_is_set(space))
4380		isl_die(isl_space_get_ctx(space), isl_error_unsupported,
4381			"expecting set space", goto error);
4382	if (type != isl_dim_set)
4383		isl_die(isl_space_get_ctx(space), isl_error_invalid,
4384			"only set dimensions can be projected out", goto error);
4385	if (isl_space_check_range(space, type, first, n) < 0)
4386		goto error;
4387
4388	dim = isl_space_dim(space, isl_dim_set);
4389	if (dim < 0)
4390		goto error;
4391
4392	space = isl_space_from_domain(space);
4393	space = isl_space_add_dims(space, isl_dim_out, dim - n);
4394
4395	if (dim == n)
4396		return isl_multi_aff_alloc(space);
4397
4398	ma = isl_multi_aff_alloc(isl_space_copy(space));
4399	space = isl_space_domain(space);
4400	ls = isl_local_space_from_space(space);
4401
4402	for (i = 0; i < first; ++i) {
4403		isl_aff *aff;
4404
4405		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
4406						isl_dim_set, i);
4407		ma = isl_multi_aff_set_aff(ma, i, aff);
4408	}
4409
4410	for (i = 0; i < dim - (first + n); ++i) {
4411		isl_aff *aff;
4412
4413		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
4414						isl_dim_set, first + n + i);
4415		ma = isl_multi_aff_set_aff(ma, first + i, aff);
4416	}
4417
4418	isl_local_space_free(ls);
4419	return ma;
4420error:
4421	isl_space_free(space);
4422	return NULL;
4423}
4424
4425/* Given the space of a set and a range of set dimensions,
4426 * construct an isl_pw_multi_aff that projects out those dimensions.
4427 */
4428__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map(
4429	__isl_take isl_space *space, enum isl_dim_type type,
4430	unsigned first, unsigned n)
4431{
4432	isl_multi_aff *ma;
4433
4434	ma = isl_multi_aff_project_out_map(space, type, first, n);
4435	return isl_pw_multi_aff_from_multi_aff(ma);
4436}
4437
4438/* This function performs the same operation as isl_pw_multi_aff_from_multi_aff,
4439 * but is considered as a function on an isl_multi_aff when exported.
4440 */
4441__isl_give isl_pw_multi_aff *isl_multi_aff_to_pw_multi_aff(
4442	__isl_take isl_multi_aff *ma)
4443{
4444	return isl_pw_multi_aff_from_multi_aff(ma);
4445}
4446
4447/* Create a piecewise multi-affine expression in the given space that maps each
4448 * input dimension to the corresponding output dimension.
4449 */
4450__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
4451	__isl_take isl_space *space)
4452{
4453	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space));
4454}
4455
4456/* Create a piecewise multi expression that maps elements in the given space
4457 * to themselves.
4458 */
4459__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity_on_domain_space(
4460	__isl_take isl_space *space)
4461{
4462	isl_multi_aff *ma;
4463
4464	ma = isl_multi_aff_identity_on_domain_space(space);
4465	return isl_pw_multi_aff_from_multi_aff(ma);
4466}
4467
4468/* This function performs the same operation as
4469 * isl_pw_multi_aff_identity_on_domain_space,
4470 * but is considered as a function on an isl_space when exported.
4471 */
4472__isl_give isl_pw_multi_aff *isl_space_identity_pw_multi_aff_on_domain(
4473	__isl_take isl_space *space)
4474{
4475	return isl_pw_multi_aff_identity_on_domain_space(space);
4476}
4477
4478/* Exploit the equalities in "eq" to simplify the affine expressions.
4479 */
4480static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
4481	__isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq)
4482{
4483	isl_size n;
4484	int i;
4485
4486	n = isl_multi_aff_size(maff);
4487	if (n < 0 || !eq)
4488		goto error;
4489
4490	for (i = 0; i < n; ++i) {
4491		isl_aff *aff;
4492
4493		aff = isl_multi_aff_take_at(maff, i);
4494		aff = isl_aff_substitute_equalities(aff,
4495						    isl_basic_set_copy(eq));
4496		maff = isl_multi_aff_restore_at(maff, i, aff);
4497	}
4498
4499	isl_basic_set_free(eq);
4500	return maff;
4501error:
4502	isl_basic_set_free(eq);
4503	isl_multi_aff_free(maff);
4504	return NULL;
4505}
4506
4507__isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
4508	isl_int f)
4509{
4510	isl_size n;
4511	int i;
4512
4513	n = isl_multi_aff_size(maff);
4514	if (n < 0)
4515		return isl_multi_aff_free(maff);
4516
4517	for (i = 0; i < n; ++i) {
4518		isl_aff *aff;
4519
4520		aff = isl_multi_aff_take_at(maff, i);
4521		aff = isl_aff_scale(aff, f);
4522		maff = isl_multi_aff_restore_at(maff, i, aff);
4523	}
4524
4525	return maff;
4526}
4527
4528__isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_set *dom,
4529	__isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
4530{
4531	maff1 = isl_multi_aff_add(maff1, maff2);
4532	maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom));
4533	return maff1;
4534}
4535
4536isl_bool isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff)
4537{
4538	if (!maff)
4539		return isl_bool_error;
4540
4541	return isl_bool_false;
4542}
4543
4544/* Return the set of domain elements where "ma1" is lexicographically
4545 * smaller than or equal to "ma2".
4546 */
4547__isl_give isl_set *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1,
4548	__isl_take isl_multi_aff *ma2)
4549{
4550	return isl_multi_aff_lex_ge_set(ma2, ma1);
4551}
4552
4553/* Return the set of domain elements where "ma1" is lexicographically
4554 * smaller than "ma2".
4555 */
4556__isl_give isl_set *isl_multi_aff_lex_lt_set(__isl_take isl_multi_aff *ma1,
4557	__isl_take isl_multi_aff *ma2)
4558{
4559	return isl_multi_aff_lex_gt_set(ma2, ma1);
4560}
4561
4562/* Return the set of domain elements where "ma1" is lexicographically
4563 * greater than to "ma2".  If "equal" is set, then include the domain
4564 * elements where they are equal.
4565 * Do this for the case where there are no entries.
4566 * In this case, "ma1" cannot be greater than "ma2",
4567 * but it is (greater than or) equal to "ma2".
4568 */
4569static __isl_give isl_set *isl_multi_aff_lex_gte_set_0d(
4570	__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2, int equal)
4571{
4572	isl_space *space;
4573
4574	space = isl_multi_aff_get_domain_space(ma1);
4575
4576	isl_multi_aff_free(ma1);
4577	isl_multi_aff_free(ma2);
4578
4579	if (equal)
4580		return isl_set_universe(space);
4581	else
4582		return isl_set_empty(space);
4583}
4584
4585/* Return the set where entry "i" of "ma1" and "ma2"
4586 * satisfy the relation prescribed by "cmp".
4587 */
4588static __isl_give isl_set *isl_multi_aff_order_at(__isl_keep isl_multi_aff *ma1,
4589	__isl_keep isl_multi_aff *ma2, int i,
4590	__isl_give isl_set *(*cmp)(__isl_take isl_aff *aff1,
4591		__isl_take isl_aff *aff2))
4592{
4593	isl_aff *aff1, *aff2;
4594
4595	aff1 = isl_multi_aff_get_at(ma1, i);
4596	aff2 = isl_multi_aff_get_at(ma2, i);
4597	return cmp(aff1, aff2);
4598}
4599
4600/* Return the set of domain elements where "ma1" is lexicographically
4601 * greater than to "ma2".  If "equal" is set, then include the domain
4602 * elements where they are equal.
4603 *
4604 * In particular, for all but the final entry,
4605 * include the set of elements where this entry is strictly greater in "ma1"
4606 * and all previous entries are equal.
4607 * The final entry is also allowed to be equal in the two functions
4608 * if "equal" is set.
4609 *
4610 * The case where there are no entries is handled separately.
4611 */
4612static __isl_give isl_set *isl_multi_aff_lex_gte_set(
4613	__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2, int equal)
4614{
4615	int i;
4616	isl_size n;
4617	isl_space *space;
4618	isl_set *res;
4619	isl_set *equal_set;
4620	isl_set *gte;
4621
4622	if (isl_multi_aff_check_equal_space(ma1, ma2) < 0)
4623		goto error;
4624	n = isl_multi_aff_size(ma1);
4625	if (n < 0)
4626		goto error;
4627	if (n == 0)
4628		return isl_multi_aff_lex_gte_set_0d(ma1, ma2, equal);
4629
4630	space = isl_multi_aff_get_domain_space(ma1);
4631	res = isl_set_empty(isl_space_copy(space));
4632	equal_set = isl_set_universe(space);
4633
4634	for (i = 0; i + 1 < n; ++i) {
4635		isl_bool empty;
4636		isl_set *gt, *eq;
4637
4638		gt = isl_multi_aff_order_at(ma1, ma2, i, &isl_aff_gt_set);
4639		gt = isl_set_intersect(gt, isl_set_copy(equal_set));
4640		res = isl_set_union(res, gt);
4641		eq = isl_multi_aff_order_at(ma1, ma2, i, &isl_aff_eq_set);
4642		equal_set = isl_set_intersect(equal_set, eq);
4643
4644		empty = isl_set_is_empty(equal_set);
4645		if (empty >= 0 && empty)
4646			break;
4647	}
4648
4649	if (equal)
4650		gte = isl_multi_aff_order_at(ma1, ma2, n - 1, &isl_aff_ge_set);
4651	else
4652		gte = isl_multi_aff_order_at(ma1, ma2, n - 1, &isl_aff_gt_set);
4653	isl_multi_aff_free(ma1);
4654	isl_multi_aff_free(ma2);
4655
4656	gte = isl_set_intersect(gte, equal_set);
4657	return isl_set_union(res, gte);
4658error:
4659	isl_multi_aff_free(ma1);
4660	isl_multi_aff_free(ma2);
4661	return NULL;
4662}
4663
4664/* Return the set of domain elements where "ma1" is lexicographically
4665 * greater than or equal to "ma2".
4666 */
4667__isl_give isl_set *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1,
4668	__isl_take isl_multi_aff *ma2)
4669{
4670	return isl_multi_aff_lex_gte_set(ma1, ma2, 1);
4671}
4672
4673/* Return the set of domain elements where "ma1" is lexicographically
4674 * greater than "ma2".
4675 */
4676__isl_give isl_set *isl_multi_aff_lex_gt_set(__isl_take isl_multi_aff *ma1,
4677	__isl_take isl_multi_aff *ma2)
4678{
4679	return isl_multi_aff_lex_gte_set(ma1, ma2, 0);
4680}
4681
4682#define isl_multi_aff_zero_in_space	isl_multi_aff_zero
4683
4684#undef PW
4685#define PW isl_pw_multi_aff
4686#undef BASE
4687#define BASE multi_aff
4688#undef EL_IS_ZERO
4689#define EL_IS_ZERO is_empty
4690#undef ZERO
4691#define ZERO empty
4692#undef IS_ZERO
4693#define IS_ZERO is_empty
4694#undef FIELD
4695#define FIELD maff
4696#undef DEFAULT_IS_ZERO
4697#define DEFAULT_IS_ZERO 0
4698
4699#include <isl_pw_templ.c>
4700#include <isl_pw_un_op_templ.c>
4701#include <isl_pw_add_constant_multi_val_templ.c>
4702#include <isl_pw_add_constant_val_templ.c>
4703#include <isl_pw_add_disjoint_templ.c>
4704#include <isl_pw_bind_domain_templ.c>
4705#include <isl_pw_domain_reverse_templ.c>
4706#include <isl_pw_fix_templ.c>
4707#include <isl_pw_from_range_templ.c>
4708#include <isl_pw_insert_dims_templ.c>
4709#include <isl_pw_insert_domain_templ.c>
4710#include <isl_pw_locals_templ.c>
4711#include <isl_pw_move_dims_templ.c>
4712#include <isl_pw_neg_templ.c>
4713#include <isl_pw_pullback_templ.c>
4714#include <isl_pw_range_tuple_id_templ.c>
4715#include <isl_pw_union_opt.c>
4716
4717#undef BASE
4718#define BASE pw_multi_aff
4719
4720#include <isl_union_multi.c>
4721#include "isl_union_locals_templ.c"
4722#include <isl_union_neg.c>
4723#include <isl_union_sub_templ.c>
4724
4725#undef BASE
4726#define BASE multi_aff
4727
4728#include <isl_union_pw_templ.c>
4729
4730/* Generic function for extracting a factor from a product "pma".
4731 * "check_space" checks that the space is that of the right kind of product.
4732 * "space_factor" extracts the factor from the space.
4733 * "multi_aff_factor" extracts the factor from the constituent functions.
4734 */
4735static __isl_give isl_pw_multi_aff *pw_multi_aff_factor(
4736	__isl_take isl_pw_multi_aff *pma,
4737	isl_stat (*check_space)(__isl_keep isl_pw_multi_aff *pma),
4738	__isl_give isl_space *(*space_factor)(__isl_take isl_space *space),
4739	__isl_give isl_multi_aff *(*multi_aff_factor)(
4740		__isl_take isl_multi_aff *ma))
4741{
4742	int i;
4743	isl_space *space;
4744
4745	if (check_space(pma) < 0)
4746		return isl_pw_multi_aff_free(pma);
4747
4748	space = isl_pw_multi_aff_take_space(pma);
4749	space = space_factor(space);
4750
4751	for (i = 0; pma && i < pma->n; ++i) {
4752		isl_multi_aff *ma;
4753
4754		ma = isl_pw_multi_aff_take_base_at(pma, i);
4755		ma = multi_aff_factor(ma);
4756		pma = isl_pw_multi_aff_restore_base_at(pma, i, ma);
4757	}
4758
4759	pma = isl_pw_multi_aff_restore_space(pma, space);
4760
4761	return pma;
4762}
4763
4764/* Is the range of "pma" a wrapped relation?
4765 */
4766static isl_bool isl_pw_multi_aff_range_is_wrapping(
4767	__isl_keep isl_pw_multi_aff *pma)
4768{
4769	return isl_space_range_is_wrapping(isl_pw_multi_aff_peek_space(pma));
4770}
4771
4772/* Check that the range of "pma" is a product.
4773 */
4774static isl_stat pw_multi_aff_check_range_product(
4775	__isl_keep isl_pw_multi_aff *pma)
4776{
4777	isl_bool wraps;
4778
4779	wraps = isl_pw_multi_aff_range_is_wrapping(pma);
4780	if (wraps < 0)
4781		return isl_stat_error;
4782	if (!wraps)
4783		isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
4784			"range is not a product", return isl_stat_error);
4785	return isl_stat_ok;
4786}
4787
4788/* Given a function A -> [B -> C], extract the function A -> B.
4789 */
4790__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_factor_domain(
4791	__isl_take isl_pw_multi_aff *pma)
4792{
4793	return pw_multi_aff_factor(pma, &pw_multi_aff_check_range_product,
4794				&isl_space_range_factor_domain,
4795				&isl_multi_aff_range_factor_domain);
4796}
4797
4798/* Given a function A -> [B -> C], extract the function A -> C.
4799 */
4800__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_factor_range(
4801	__isl_take isl_pw_multi_aff *pma)
4802{
4803	return pw_multi_aff_factor(pma, &pw_multi_aff_check_range_product,
4804				&isl_space_range_factor_range,
4805				&isl_multi_aff_range_factor_range);
4806}
4807
4808/* Given two piecewise multi affine expressions, return a piecewise
4809 * multi-affine expression defined on the union of the definition domains
4810 * of the inputs that is equal to the lexicographic maximum of the two
4811 * inputs on each cell.  If only one of the two inputs is defined on
4812 * a given cell, then it is considered to be the maximum.
4813 */
4814__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax(
4815	__isl_take isl_pw_multi_aff *pma1,
4816	__isl_take isl_pw_multi_aff *pma2)
4817{
4818	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
4819	return isl_pw_multi_aff_union_opt_cmp(pma1, pma2,
4820					    &isl_multi_aff_lex_ge_set);
4821}
4822
4823/* Given two piecewise multi affine expressions, return a piecewise
4824 * multi-affine expression defined on the union of the definition domains
4825 * of the inputs that is equal to the lexicographic minimum of the two
4826 * inputs on each cell.  If only one of the two inputs is defined on
4827 * a given cell, then it is considered to be the minimum.
4828 */
4829__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin(
4830	__isl_take isl_pw_multi_aff *pma1,
4831	__isl_take isl_pw_multi_aff *pma2)
4832{
4833	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
4834	return isl_pw_multi_aff_union_opt_cmp(pma1, pma2,
4835					    &isl_multi_aff_lex_le_set);
4836}
4837
4838__isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
4839	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4840{
4841	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
4842	return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
4843						&isl_multi_aff_add);
4844}
4845
4846/* Subtract "pma2" from "pma1" and return the result.
4847 */
4848__isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub(
4849	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4850{
4851	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
4852	return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
4853						&isl_multi_aff_sub);
4854}
4855
4856/* Given two piecewise multi-affine expressions A -> B and C -> D,
4857 * construct a piecewise multi-affine expression [A -> C] -> [B -> D].
4858 */
4859__isl_give isl_pw_multi_aff *isl_pw_multi_aff_product(
4860	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4861{
4862	int i, j, n;
4863	isl_space *space;
4864	isl_pw_multi_aff *res;
4865
4866	if (isl_pw_multi_aff_align_params_bin(&pma1, &pma2) < 0)
4867		goto error;
4868
4869	n = pma1->n * pma2->n;
4870	space = isl_space_product(isl_space_copy(pma1->dim),
4871				  isl_space_copy(pma2->dim));
4872	res = isl_pw_multi_aff_alloc_size(space, n);
4873
4874	for (i = 0; i < pma1->n; ++i) {
4875		for (j = 0; j < pma2->n; ++j) {
4876			isl_set *domain;
4877			isl_multi_aff *ma;
4878
4879			domain = isl_set_product(isl_set_copy(pma1->p[i].set),
4880						 isl_set_copy(pma2->p[j].set));
4881			ma = isl_multi_aff_product(
4882					isl_multi_aff_copy(pma1->p[i].maff),
4883					isl_multi_aff_copy(pma2->p[j].maff));
4884			res = isl_pw_multi_aff_add_piece(res, domain, ma);
4885		}
4886	}
4887
4888	isl_pw_multi_aff_free(pma1);
4889	isl_pw_multi_aff_free(pma2);
4890	return res;
4891error:
4892	isl_pw_multi_aff_free(pma1);
4893	isl_pw_multi_aff_free(pma2);
4894	return NULL;
4895}
4896
4897/* Subtract the initial "n" elements in "ma" with coefficients in "c" and
4898 * denominator "denom".
4899 * "denom" is allowed to be negative, in which case the actual denominator
4900 * is -denom and the expressions are added instead.
4901 */
4902static __isl_give isl_aff *subtract_initial(__isl_take isl_aff *aff,
4903	__isl_keep isl_multi_aff *ma, int n, isl_int *c, isl_int denom)
4904{
4905	int i, first;
4906	int sign;
4907	isl_int d;
4908
4909	first = isl_seq_first_non_zero(c, n);
4910	if (first == -1)
4911		return aff;
4912
4913	sign = isl_int_sgn(denom);
4914	isl_int_init(d);
4915	isl_int_abs(d, denom);
4916	for (i = first; i < n; ++i) {
4917		isl_aff *aff_i;
4918
4919		if (isl_int_is_zero(c[i]))
4920			continue;
4921		aff_i = isl_multi_aff_get_aff(ma, i);
4922		aff_i = isl_aff_scale(aff_i, c[i]);
4923		aff_i = isl_aff_scale_down(aff_i, d);
4924		if (sign >= 0)
4925			aff = isl_aff_sub(aff, aff_i);
4926		else
4927			aff = isl_aff_add(aff, aff_i);
4928	}
4929	isl_int_clear(d);
4930
4931	return aff;
4932}
4933
4934/* Extract an affine expression that expresses the output dimension "pos"
4935 * of "bmap" in terms of the parameters and input dimensions from
4936 * equality "eq".
4937 * Note that this expression may involve integer divisions defined
4938 * in terms of parameters and input dimensions.
4939 * The equality may also involve references to earlier (but not later)
4940 * output dimensions.  These are replaced by the corresponding elements
4941 * in "ma".
4942 *
4943 * If the equality is of the form
4944 *
4945 *	f(i) + h(j) + a x + g(i) = 0,
4946 *
4947 * with f(i) a linear combinations of the parameters and input dimensions,
4948 * g(i) a linear combination of integer divisions defined in terms of the same
4949 * and h(j) a linear combinations of earlier output dimensions,
4950 * then the affine expression is
4951 *
4952 *	(-f(i) - g(i))/a - h(j)/a
4953 *
4954 * If the equality is of the form
4955 *
4956 *	f(i) + h(j) - a x + g(i) = 0,
4957 *
4958 * then the affine expression is
4959 *
4960 *	(f(i) + g(i))/a - h(j)/(-a)
4961 *
4962 *
4963 * If "div" refers to an integer division (i.e., it is smaller than
4964 * the number of integer divisions), then the equality constraint
4965 * does involve an integer division (the one at position "div") that
4966 * is defined in terms of output dimensions.  However, this integer
4967 * division can be eliminated by exploiting a pair of constraints
4968 * x >= l and x <= l + n, with n smaller than the coefficient of "div"
4969 * in the equality constraint.  "ineq" refers to inequality x >= l, i.e.,
4970 * -l + x >= 0.
4971 * In particular, let
4972 *
4973 *	x = e(i) + m floor(...)
4974 *
4975 * with e(i) the expression derived above and floor(...) the integer
4976 * division involving output dimensions.
4977 * From
4978 *
4979 *	l <= x <= l + n,
4980 *
4981 * we have
4982 *
4983 *	0 <= x - l <= n
4984 *
4985 * This means
4986 *
4987 *	e(i) + m floor(...) - l = (e(i) + m floor(...) - l) mod m
4988 *	                        = (e(i) - l) mod m
4989 *
4990 * Therefore,
4991 *
4992 *	x - l = (e(i) - l) mod m
4993 *
4994 * or
4995 *
4996 *	x = ((e(i) - l) mod m) + l
4997 *
4998 * The variable "shift" below contains the expression -l, which may
4999 * also involve a linear combination of earlier output dimensions.
5000 */
5001static __isl_give isl_aff *extract_aff_from_equality(
5002	__isl_keep isl_basic_map *bmap, int pos, int eq, int div, int ineq,
5003	__isl_keep isl_multi_aff *ma)
5004{
5005	unsigned o_out;
5006	isl_size n_div, n_out;
5007	isl_ctx *ctx;
5008	isl_local_space *ls;
5009	isl_aff *aff, *shift;
5010	isl_val *mod;
5011
5012	ctx = isl_basic_map_get_ctx(bmap);
5013	ls = isl_basic_map_get_local_space(bmap);
5014	ls = isl_local_space_domain(ls);
5015	aff = isl_aff_alloc(isl_local_space_copy(ls));
5016	if (!aff)
5017		goto error;
5018	o_out = isl_basic_map_offset(bmap, isl_dim_out);
5019	n_out = isl_basic_map_dim(bmap, isl_dim_out);
5020	n_div = isl_basic_map_dim(bmap, isl_dim_div);
5021	if (n_out < 0 || n_div < 0)
5022		goto error;
5023	if (isl_int_is_neg(bmap->eq[eq][o_out + pos])) {
5024		isl_seq_cpy(aff->v->el + 1, bmap->eq[eq], o_out);
5025		isl_seq_cpy(aff->v->el + 1 + o_out,
5026			    bmap->eq[eq] + o_out + n_out, n_div);
5027	} else {
5028		isl_seq_neg(aff->v->el + 1, bmap->eq[eq], o_out);
5029		isl_seq_neg(aff->v->el + 1 + o_out,
5030			    bmap->eq[eq] + o_out + n_out, n_div);
5031	}
5032	if (div < n_div)
5033		isl_int_set_si(aff->v->el[1 + o_out + div], 0);
5034	isl_int_abs(aff->v->el[0], bmap->eq[eq][o_out + pos]);
5035	aff = subtract_initial(aff, ma, pos, bmap->eq[eq] + o_out,
5036			    bmap->eq[eq][o_out + pos]);
5037	if (div < n_div) {
5038		shift = isl_aff_alloc(isl_local_space_copy(ls));
5039		if (!shift)
5040			goto error;
5041		isl_seq_cpy(shift->v->el + 1, bmap->ineq[ineq], o_out);
5042		isl_seq_cpy(shift->v->el + 1 + o_out,
5043			    bmap->ineq[ineq] + o_out + n_out, n_div);
5044		isl_int_set_si(shift->v->el[0], 1);
5045		shift = subtract_initial(shift, ma, pos,
5046					bmap->ineq[ineq] + o_out, ctx->negone);
5047		aff = isl_aff_add(aff, isl_aff_copy(shift));
5048		mod = isl_val_int_from_isl_int(ctx,
5049					    bmap->eq[eq][o_out + n_out + div]);
5050		mod = isl_val_abs(mod);
5051		aff = isl_aff_mod_val(aff, mod);
5052		aff = isl_aff_sub(aff, shift);
5053	}
5054
5055	isl_local_space_free(ls);
5056	return aff;
5057error:
5058	isl_local_space_free(ls);
5059	isl_aff_free(aff);
5060	return NULL;
5061}
5062
5063/* Given a basic map with output dimensions defined
5064 * in terms of the parameters input dimensions and earlier
5065 * output dimensions using an equality (and possibly a pair on inequalities),
5066 * extract an isl_aff that expresses output dimension "pos" in terms
5067 * of the parameters and input dimensions.
5068 * Note that this expression may involve integer divisions defined
5069 * in terms of parameters and input dimensions.
5070 * "ma" contains the expressions corresponding to earlier output dimensions.
5071 *
5072 * This function shares some similarities with
5073 * isl_basic_map_has_defining_equality and isl_constraint_get_bound.
5074 */
5075static __isl_give isl_aff *extract_isl_aff_from_basic_map(
5076	__isl_keep isl_basic_map *bmap, int pos, __isl_keep isl_multi_aff *ma)
5077{
5078	int eq, div, ineq;
5079	isl_aff *aff;
5080
5081	if (!bmap)
5082		return NULL;
5083	eq = isl_basic_map_output_defining_equality(bmap, pos, &div, &ineq);
5084	if (eq >= bmap->n_eq)
5085		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
5086			"unable to find suitable equality", return NULL);
5087	aff = extract_aff_from_equality(bmap, pos, eq, div, ineq, ma);
5088
5089	aff = isl_aff_remove_unused_divs(aff);
5090	return aff;
5091}
5092
5093/* Given a basic map where each output dimension is defined
5094 * in terms of the parameters and input dimensions using an equality,
5095 * extract an isl_multi_aff that expresses the output dimensions in terms
5096 * of the parameters and input dimensions.
5097 */
5098static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map(
5099	__isl_take isl_basic_map *bmap)
5100{
5101	int i;
5102	isl_size n_out;
5103	isl_multi_aff *ma;
5104
5105	if (!bmap)
5106		return NULL;
5107
5108	ma = isl_multi_aff_alloc(isl_basic_map_get_space(bmap));
5109	n_out = isl_basic_map_dim(bmap, isl_dim_out);
5110	if (n_out < 0)
5111		ma = isl_multi_aff_free(ma);
5112
5113	for (i = 0; i < n_out; ++i) {
5114		isl_aff *aff;
5115
5116		aff = extract_isl_aff_from_basic_map(bmap, i, ma);
5117		ma = isl_multi_aff_set_aff(ma, i, aff);
5118	}
5119
5120	isl_basic_map_free(bmap);
5121
5122	return ma;
5123}
5124
5125/* Given a basic set where each set dimension is defined
5126 * in terms of the parameters using an equality,
5127 * extract an isl_multi_aff that expresses the set dimensions in terms
5128 * of the parameters.
5129 */
5130__isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities(
5131	__isl_take isl_basic_set *bset)
5132{
5133	return extract_isl_multi_aff_from_basic_map(bset);
5134}
5135
5136/* Create an isl_pw_multi_aff that is equivalent to
5137 * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain).
5138 * The given basic map is such that each output dimension is defined
5139 * in terms of the parameters and input dimensions using an equality.
5140 *
5141 * Since some applications expect the result of isl_pw_multi_aff_from_map
5142 * to only contain integer affine expressions, we compute the floor
5143 * of the expression before returning.
5144 *
5145 * Remove all constraints involving local variables without
5146 * an explicit representation (resulting in the removal of those
5147 * local variables) prior to the actual extraction to ensure
5148 * that the local spaces in which the resulting affine expressions
5149 * are created do not contain any unknown local variables.
5150 * Removing such constraints is safe because constraints involving
5151 * unknown local variables are not used to determine whether
5152 * a basic map is obviously single-valued.
5153 */
5154static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map(
5155	__isl_take isl_set *domain, __isl_take isl_basic_map *bmap)
5156{
5157	isl_multi_aff *ma;
5158
5159	bmap = isl_basic_map_drop_constraints_involving_unknown_divs(bmap);
5160	ma = extract_isl_multi_aff_from_basic_map(bmap);
5161	ma = isl_multi_aff_floor(ma);
5162	return isl_pw_multi_aff_alloc(domain, ma);
5163}
5164
5165/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
5166 * This obviously only works if the input "map" is single-valued.
5167 * If so, we compute the lexicographic minimum of the image in the form
5168 * of an isl_pw_multi_aff.  Since the image is unique, it is equal
5169 * to its lexicographic minimum.
5170 * If the input is not single-valued, we produce an error.
5171 */
5172static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_base(
5173	__isl_take isl_map *map)
5174{
5175	int i;
5176	int sv;
5177	isl_pw_multi_aff *pma;
5178
5179	sv = isl_map_is_single_valued(map);
5180	if (sv < 0)
5181		goto error;
5182	if (!sv)
5183		isl_die(isl_map_get_ctx(map), isl_error_invalid,
5184			"map is not single-valued", goto error);
5185	map = isl_map_make_disjoint(map);
5186	if (!map)
5187		return NULL;
5188
5189	pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
5190
5191	for (i = 0; i < map->n; ++i) {
5192		isl_pw_multi_aff *pma_i;
5193		isl_basic_map *bmap;
5194		bmap = isl_basic_map_copy(map->p[i]);
5195		pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
5196		pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
5197	}
5198
5199	isl_map_free(map);
5200	return pma;
5201error:
5202	isl_map_free(map);
5203	return NULL;
5204}
5205
5206/* Construct an isl_aff from the given domain local space "ls" and
5207 * coefficients "v", where the local space may involve
5208 * local variables without a known expression, as long as these
5209 * do not have a non-zero coefficient in "v".
5210 * These need to be pruned away first since an isl_aff cannot
5211 * reference any local variables without a known expression.
5212 * For simplicity, remove all local variables that have a zero coefficient and
5213 * that are not used in other local variables with a non-zero coefficient.
5214 */
5215static __isl_give isl_aff *isl_aff_alloc_vec_prune(
5216	__isl_take isl_local_space *ls, __isl_take isl_vec *v)
5217{
5218	int i;
5219	isl_size n_div, v_div;
5220
5221	n_div = isl_local_space_dim(ls, isl_dim_div);
5222	v_div = isl_local_space_var_offset(ls, isl_dim_div);
5223	if (n_div < 0 || v_div < 0 || !v)
5224		goto error;
5225	for (i = n_div - 1; i >= 0; --i) {
5226		isl_bool involves;
5227
5228		if (!isl_int_is_zero(v->el[1 + 1 + v_div + i]))
5229			continue;
5230		involves = isl_local_space_involves_dims(ls, isl_dim_div, i, 1);
5231		if (involves < 0)
5232			goto error;
5233		if (involves)
5234			continue;
5235		ls = isl_local_space_drop_dims(ls, isl_dim_div, i, 1);
5236		v = isl_vec_drop_els(v, 1 + 1 + v_div + i, 1);
5237		if (!v)
5238			goto error;
5239	}
5240
5241	return isl_aff_alloc_vec(ls, v);
5242error:
5243	isl_local_space_free(ls);
5244	isl_vec_free(v);
5245	return NULL;
5246}
5247
5248/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
5249 * taking into account that the output dimension at position "d"
5250 * can be represented as
5251 *
5252 *	x = floor((e(...) + c1) / m)
5253 *
5254 * given that constraint "i" is of the form
5255 *
5256 *	e(...) + c1 - m x >= 0
5257 *
5258 * with e(...) an expression that does not involve any other output dimensions.
5259 *
5260 *
5261 * Let "map" be of the form
5262 *
5263 *	A -> B
5264 *
5265 * We construct a mapping
5266 *
5267 *	A -> [A -> x = floor(...)]
5268 *
5269 * apply that to the map, obtaining
5270 *
5271 *	[A -> x = floor(...)] -> B
5272 *
5273 * and equate dimension "d" to x.
5274 * We then compute a isl_pw_multi_aff representation of the resulting map
5275 * and plug in the mapping above.
5276 *
5277 * The constraint "i" is guaranteed by the caller not to involve
5278 * any local variables without a known expression, but such local variables
5279 * may appear in other constraints.  They therefore need to be removed
5280 * during the construction of the affine expression.
5281 */
5282static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_div(
5283	__isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i)
5284{
5285	isl_space *space = NULL;
5286	isl_local_space *ls;
5287	isl_multi_aff *ma;
5288	isl_aff *aff;
5289	isl_vec *v;
5290	isl_map *insert;
5291	isl_size n_in;
5292	isl_pw_multi_aff *pma;
5293	isl_bool is_set;
5294
5295	is_set = isl_map_is_set(map);
5296	if (is_set < 0)
5297		goto error;
5298
5299	space = isl_space_domain(isl_map_get_space(map));
5300	n_in = isl_space_dim(space, isl_dim_set);
5301	if (n_in < 0)
5302		goto error;
5303
5304	ls = isl_basic_map_get_local_space(hull);
5305	if (!is_set)
5306		ls = isl_local_space_wrap(ls);
5307	v = isl_basic_map_inequality_extract_output_upper_bound(hull, i, d);
5308	isl_basic_map_free(hull);
5309
5310	aff = isl_aff_alloc_vec_prune(ls, v);
5311	aff = isl_aff_floor(aff);
5312	if (is_set) {
5313		aff = isl_aff_project_domain_on_params(aff);
5314		isl_space_free(space);
5315		ma = isl_multi_aff_from_aff(aff);
5316	} else {
5317		aff = isl_aff_domain_factor_domain(aff);
5318		ma = isl_multi_aff_identity(isl_space_map_from_set(space));
5319		ma = isl_multi_aff_range_product(ma,
5320						isl_multi_aff_from_aff(aff));
5321	}
5322
5323	insert = isl_map_from_multi_aff_internal(isl_multi_aff_copy(ma));
5324	map = isl_map_apply_domain(map, insert);
5325	map = isl_map_equate(map, isl_dim_in, n_in, isl_dim_out, d);
5326	pma = isl_pw_multi_aff_from_map(map);
5327	pma = isl_pw_multi_aff_pullback_multi_aff(pma, ma);
5328
5329	return pma;
5330error:
5331	isl_space_free(space);
5332	isl_map_free(map);
5333	isl_basic_map_free(hull);
5334	return NULL;
5335}
5336
5337/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
5338 *
5339 * As a special case, we first check if there is any pair of constraints,
5340 * shared by all the basic maps in "map" that force a given dimension
5341 * to be equal to the floor of some affine combination of the input dimensions.
5342 *
5343 * In particular, if we can find two constraints
5344 *
5345 *	e(...) + c1 - m x >= 0		i.e.,		m x <= e(...) + c1
5346 *
5347 * and
5348 *
5349 *	-e(...) + c2 + m x >= 0		i.e.,		m x >= e(...) - c2
5350 *
5351 * where m > 1 and e only depends on parameters and input dimensions,
5352 * and such that
5353 *
5354 *	c1 + c2 < m			i.e.,		-c2 >= c1 - (m - 1)
5355 *
5356 * then we know that we can take
5357 *
5358 *	x = floor((e(...) + c1) / m)
5359 *
5360 * without having to perform any computation.
5361 *
5362 * Note that we know that
5363 *
5364 *	c1 + c2 >= 1
5365 *
5366 * If c1 + c2 were 0, then we would have detected an equality during
5367 * simplification.  If c1 + c2 were negative, then we would have detected
5368 * a contradiction.
5369 */
5370static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_div(
5371	__isl_take isl_map *map)
5372{
5373	int d;
5374	isl_size dim;
5375	isl_size i;
5376	isl_size n_ineq;
5377	isl_basic_map *hull;
5378
5379	hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
5380	dim = isl_map_dim(map, isl_dim_out);
5381	n_ineq = isl_basic_map_n_inequality(hull);
5382	if (dim < 0 || n_ineq < 0)
5383		goto error;
5384
5385	dim = isl_map_dim(map, isl_dim_out);
5386	for (d = 0; d < dim; ++d) {
5387		i = isl_basic_map_find_output_upper_div_constraint(hull, d);
5388		if (i < 0)
5389			goto error;
5390		if (i >= n_ineq)
5391			continue;
5392		return pw_multi_aff_from_map_div(map, hull, d, i);
5393	}
5394	isl_basic_map_free(hull);
5395	return pw_multi_aff_from_map_base(map);
5396error:
5397	isl_map_free(map);
5398	isl_basic_map_free(hull);
5399	return NULL;
5400}
5401
5402/* Given an affine expression
5403 *
5404 *	[A -> B] -> f(A,B)
5405 *
5406 * construct an isl_multi_aff
5407 *
5408 *	[A -> B] -> B'
5409 *
5410 * such that dimension "d" in B' is set to "aff" and the remaining
5411 * dimensions are set equal to the corresponding dimensions in B.
5412 * "n_in" is the dimension of the space A.
5413 * "n_out" is the dimension of the space B.
5414 *
5415 * If "is_set" is set, then the affine expression is of the form
5416 *
5417 *	[B] -> f(B)
5418 *
5419 * and we construct an isl_multi_aff
5420 *
5421 *	B -> B'
5422 */
5423static __isl_give isl_multi_aff *range_map(__isl_take isl_aff *aff, int d,
5424	unsigned n_in, unsigned n_out, int is_set)
5425{
5426	int i;
5427	isl_multi_aff *ma;
5428	isl_space *space, *space2;
5429	isl_local_space *ls;
5430
5431	space = isl_aff_get_domain_space(aff);
5432	ls = isl_local_space_from_space(isl_space_copy(space));
5433	space2 = isl_space_copy(space);
5434	if (!is_set)
5435		space2 = isl_space_range(isl_space_unwrap(space2));
5436	space = isl_space_map_from_domain_and_range(space, space2);
5437	ma = isl_multi_aff_alloc(space);
5438	ma = isl_multi_aff_set_aff(ma, d, aff);
5439
5440	for (i = 0; i < n_out; ++i) {
5441		if (i == d)
5442			continue;
5443		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
5444						isl_dim_set, n_in + i);
5445		ma = isl_multi_aff_set_aff(ma, i, aff);
5446	}
5447
5448	isl_local_space_free(ls);
5449
5450	return ma;
5451}
5452
5453/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
5454 * taking into account that the dimension at position "d" can be written as
5455 *
5456 *	x = m a + f(..)						(1)
5457 *
5458 * where m is equal to "gcd".
5459 * "i" is the index of the equality in "hull" that defines f(..).
5460 * In particular, the equality is of the form
5461 *
5462 *	f(..) - x + m g(existentials) = 0
5463 *
5464 * or
5465 *
5466 *	-f(..) + x + m g(existentials) = 0
5467 *
5468 * We basically plug (1) into "map", resulting in a map with "a"
5469 * in the range instead of "x".  The corresponding isl_pw_multi_aff
5470 * defining "a" is then plugged back into (1) to obtain a definition for "x".
5471 *
5472 * Specifically, given the input map
5473 *
5474 *	A -> B
5475 *
5476 * We first wrap it into a set
5477 *
5478 *	[A -> B]
5479 *
5480 * and define (1) on top of the corresponding space, resulting in "aff".
5481 * We use this to create an isl_multi_aff that maps the output position "d"
5482 * from "a" to "x", leaving all other (intput and output) dimensions unchanged.
5483 * We plug this into the wrapped map, unwrap the result and compute the
5484 * corresponding isl_pw_multi_aff.
5485 * The result is an expression
5486 *
5487 *	A -> T(A)
5488 *
5489 * We adjust that to
5490 *
5491 *	A -> [A -> T(A)]
5492 *
5493 * so that we can plug that into "aff", after extending the latter to
5494 * a mapping
5495 *
5496 *	[A -> B] -> B'
5497 *
5498 *
5499 * If "map" is actually a set, then there is no "A" space, meaning
5500 * that we do not need to perform any wrapping, and that the result
5501 * of the recursive call is of the form
5502 *
5503 *	[T]
5504 *
5505 * which is plugged into a mapping of the form
5506 *
5507 *	B -> B'
5508 */
5509static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride(
5510	__isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i,
5511	isl_int gcd)
5512{
5513	isl_set *set;
5514	isl_space *space;
5515	isl_local_space *ls;
5516	isl_aff *aff;
5517	isl_multi_aff *ma;
5518	isl_pw_multi_aff *pma, *id;
5519	isl_size n_in;
5520	unsigned o_out;
5521	isl_size n_out;
5522	isl_bool is_set;
5523
5524	is_set = isl_map_is_set(map);
5525	if (is_set < 0)
5526		goto error;
5527
5528	n_in = isl_basic_map_dim(hull, isl_dim_in);
5529	n_out = isl_basic_map_dim(hull, isl_dim_out);
5530	if (n_in < 0 || n_out < 0)
5531		goto error;
5532	o_out = isl_basic_map_offset(hull, isl_dim_out);
5533
5534	if (is_set)
5535		set = map;
5536	else
5537		set = isl_map_wrap(map);
5538	space = isl_space_map_from_set(isl_set_get_space(set));
5539	ma = isl_multi_aff_identity(space);
5540	ls = isl_local_space_from_space(isl_set_get_space(set));
5541	aff = isl_aff_alloc(ls);
5542	if (aff) {
5543		isl_int_set_si(aff->v->el[0], 1);
5544		if (isl_int_is_one(hull->eq[i][o_out + d]))
5545			isl_seq_neg(aff->v->el + 1, hull->eq[i],
5546				    aff->v->size - 1);
5547		else
5548			isl_seq_cpy(aff->v->el + 1, hull->eq[i],
5549				    aff->v->size - 1);
5550		isl_int_set(aff->v->el[1 + o_out + d], gcd);
5551	}
5552	ma = isl_multi_aff_set_aff(ma, n_in + d, isl_aff_copy(aff));
5553	set = isl_set_preimage_multi_aff(set, ma);
5554
5555	ma = range_map(aff, d, n_in, n_out, is_set);
5556
5557	if (is_set)
5558		map = set;
5559	else
5560		map = isl_set_unwrap(set);
5561	pma = isl_pw_multi_aff_from_map(map);
5562
5563	if (!is_set) {
5564		space = isl_pw_multi_aff_get_domain_space(pma);
5565		space = isl_space_map_from_set(space);
5566		id = isl_pw_multi_aff_identity(space);
5567		pma = isl_pw_multi_aff_range_product(id, pma);
5568	}
5569	id = isl_pw_multi_aff_from_multi_aff(ma);
5570	pma = isl_pw_multi_aff_pullback_pw_multi_aff(id, pma);
5571
5572	isl_basic_map_free(hull);
5573	return pma;
5574error:
5575	isl_map_free(map);
5576	isl_basic_map_free(hull);
5577	return NULL;
5578}
5579
5580/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
5581 * "hull" contains the equalities valid for "map".
5582 *
5583 * Check if any of the output dimensions is "strided".
5584 * That is, we check if it can be written as
5585 *
5586 *	x = m a + f(..)
5587 *
5588 * with m greater than 1, a some combination of existentially quantified
5589 * variables and f an expression in the parameters and input dimensions.
5590 * If so, we remove the stride in pw_multi_aff_from_map_stride.
5591 *
5592 * Otherwise, we continue with pw_multi_aff_from_map_check_div for a further
5593 * special case.
5594 */
5595static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_strides(
5596	__isl_take isl_map *map, __isl_take isl_basic_map *hull)
5597{
5598	int i, j;
5599	isl_size n_out;
5600	unsigned o_out;
5601	isl_size n_div;
5602	unsigned o_div;
5603	isl_int gcd;
5604
5605	n_div = isl_basic_map_dim(hull, isl_dim_div);
5606	n_out = isl_basic_map_dim(hull, isl_dim_out);
5607	if (n_div < 0 || n_out < 0)
5608		goto error;
5609
5610	if (n_div == 0) {
5611		isl_basic_map_free(hull);
5612		return pw_multi_aff_from_map_check_div(map);
5613	}
5614
5615	isl_int_init(gcd);
5616
5617	o_div = isl_basic_map_offset(hull, isl_dim_div);
5618	o_out = isl_basic_map_offset(hull, isl_dim_out);
5619
5620	for (i = 0; i < n_out; ++i) {
5621		for (j = 0; j < hull->n_eq; ++j) {
5622			isl_int *eq = hull->eq[j];
5623			isl_pw_multi_aff *res;
5624
5625			if (!isl_int_is_one(eq[o_out + i]) &&
5626			    !isl_int_is_negone(eq[o_out + i]))
5627				continue;
5628			if (isl_seq_first_non_zero(eq + o_out, i) != -1)
5629				continue;
5630			if (isl_seq_first_non_zero(eq + o_out + i + 1,
5631						    n_out - (i + 1)) != -1)
5632				continue;
5633			isl_seq_gcd(eq + o_div, n_div, &gcd);
5634			if (isl_int_is_zero(gcd))
5635				continue;
5636			if (isl_int_is_one(gcd))
5637				continue;
5638
5639			res = pw_multi_aff_from_map_stride(map, hull,
5640								i, j, gcd);
5641			isl_int_clear(gcd);
5642			return res;
5643		}
5644	}
5645
5646	isl_int_clear(gcd);
5647	isl_basic_map_free(hull);
5648	return pw_multi_aff_from_map_check_div(map);
5649error:
5650	isl_map_free(map);
5651	isl_basic_map_free(hull);
5652	return NULL;
5653}
5654
5655/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
5656 *
5657 * As a special case, we first check if all output dimensions are uniquely
5658 * defined in terms of the parameters and input dimensions over the entire
5659 * domain.  If so, we extract the desired isl_pw_multi_aff directly
5660 * from the affine hull of "map" and its domain.
5661 *
5662 * Otherwise, continue with pw_multi_aff_from_map_check_strides for more
5663 * special cases.
5664 */
5665__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
5666{
5667	isl_bool sv;
5668	isl_size n;
5669	isl_basic_map *hull;
5670
5671	n = isl_map_n_basic_map(map);
5672	if (n < 0)
5673		goto error;
5674
5675	if (n == 1) {
5676		hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
5677		hull = isl_basic_map_plain_affine_hull(hull);
5678		sv = isl_basic_map_plain_is_single_valued(hull);
5679		if (sv >= 0 && sv)
5680			return plain_pw_multi_aff_from_map(isl_map_domain(map),
5681							    hull);
5682		isl_basic_map_free(hull);
5683	}
5684	map = isl_map_detect_equalities(map);
5685	hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
5686	sv = isl_basic_map_plain_is_single_valued(hull);
5687	if (sv >= 0 && sv)
5688		return plain_pw_multi_aff_from_map(isl_map_domain(map), hull);
5689	if (sv >= 0)
5690		return pw_multi_aff_from_map_check_strides(map, hull);
5691	isl_basic_map_free(hull);
5692error:
5693	isl_map_free(map);
5694	return NULL;
5695}
5696
5697/* This function performs the same operation as isl_pw_multi_aff_from_map,
5698 * but is considered as a function on an isl_map when exported.
5699 */
5700__isl_give isl_pw_multi_aff *isl_map_as_pw_multi_aff(__isl_take isl_map *map)
5701{
5702	return isl_pw_multi_aff_from_map(map);
5703}
5704
5705__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set)
5706{
5707	return isl_pw_multi_aff_from_map(set);
5708}
5709
5710/* This function performs the same operation as isl_pw_multi_aff_from_set,
5711 * but is considered as a function on an isl_set when exported.
5712 */
5713__isl_give isl_pw_multi_aff *isl_set_as_pw_multi_aff(__isl_take isl_set *set)
5714{
5715	return isl_pw_multi_aff_from_set(set);
5716}
5717
5718/* Convert "map" into an isl_pw_multi_aff (if possible) and
5719 * add it to *user.
5720 */
5721static isl_stat pw_multi_aff_from_map(__isl_take isl_map *map, void *user)
5722{
5723	isl_union_pw_multi_aff **upma = user;
5724	isl_pw_multi_aff *pma;
5725
5726	pma = isl_pw_multi_aff_from_map(map);
5727	*upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
5728
5729	return *upma ? isl_stat_ok : isl_stat_error;
5730}
5731
5732/* Create an isl_union_pw_multi_aff with the given isl_aff on a universe
5733 * domain.
5734 */
5735__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff(
5736	__isl_take isl_aff *aff)
5737{
5738	isl_multi_aff *ma;
5739	isl_pw_multi_aff *pma;
5740
5741	ma = isl_multi_aff_from_aff(aff);
5742	pma = isl_pw_multi_aff_from_multi_aff(ma);
5743	return isl_union_pw_multi_aff_from_pw_multi_aff(pma);
5744}
5745
5746/* Try and create an isl_union_pw_multi_aff that is equivalent
5747 * to the given isl_union_map.
5748 * The isl_union_map is required to be single-valued in each space.
5749 * Otherwise, an error is produced.
5750 */
5751__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map(
5752	__isl_take isl_union_map *umap)
5753{
5754	isl_space *space;
5755	isl_union_pw_multi_aff *upma;
5756
5757	space = isl_union_map_get_space(umap);
5758	upma = isl_union_pw_multi_aff_empty(space);
5759	if (isl_union_map_foreach_map(umap, &pw_multi_aff_from_map, &upma) < 0)
5760		upma = isl_union_pw_multi_aff_free(upma);
5761	isl_union_map_free(umap);
5762
5763	return upma;
5764}
5765
5766/* This function performs the same operation as
5767 * isl_union_pw_multi_aff_from_union_map,
5768 * but is considered as a function on an isl_union_map when exported.
5769 */
5770__isl_give isl_union_pw_multi_aff *isl_union_map_as_union_pw_multi_aff(
5771	__isl_take isl_union_map *umap)
5772{
5773	return isl_union_pw_multi_aff_from_union_map(umap);
5774}
5775
5776/* Try and create an isl_union_pw_multi_aff that is equivalent
5777 * to the given isl_union_set.
5778 * The isl_union_set is required to be a singleton in each space.
5779 * Otherwise, an error is produced.
5780 */
5781__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set(
5782	__isl_take isl_union_set *uset)
5783{
5784	return isl_union_pw_multi_aff_from_union_map(uset);
5785}
5786
5787/* Return the piecewise affine expression "set ? 1 : 0".
5788 */
5789__isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_set *set)
5790{
5791	isl_pw_aff *pa;
5792	isl_space *space = isl_set_get_space(set);
5793	isl_local_space *ls = isl_local_space_from_space(space);
5794	isl_aff *zero = isl_aff_zero_on_domain(isl_local_space_copy(ls));
5795	isl_aff *one = isl_aff_zero_on_domain(ls);
5796
5797	one = isl_aff_add_constant_si(one, 1);
5798	pa = isl_pw_aff_alloc(isl_set_copy(set), one);
5799	set = isl_set_complement(set);
5800	pa = isl_pw_aff_add_disjoint(pa, isl_pw_aff_alloc(set, zero));
5801
5802	return pa;
5803}
5804
5805/* Plug in "subs" for dimension "type", "pos" of "aff".
5806 *
5807 * Let i be the dimension to replace and let "subs" be of the form
5808 *
5809 *	f/d
5810 *
5811 * and "aff" of the form
5812 *
5813 *	(a i + g)/m
5814 *
5815 * The result is
5816 *
5817 *	(a f + d g')/(m d)
5818 *
5819 * where g' is the result of plugging in "subs" in each of the integer
5820 * divisions in g.
5821 */
5822__isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
5823	enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
5824{
5825	isl_ctx *ctx;
5826	isl_int v;
5827	isl_size n_div;
5828
5829	aff = isl_aff_cow(aff);
5830	if (!aff || !subs)
5831		return isl_aff_free(aff);
5832
5833	ctx = isl_aff_get_ctx(aff);
5834	if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
5835		isl_die(ctx, isl_error_invalid,
5836			"spaces don't match", return isl_aff_free(aff));
5837	n_div = isl_aff_domain_dim(subs, isl_dim_div);
5838	if (n_div < 0)
5839		return isl_aff_free(aff);
5840	if (n_div != 0)
5841		isl_die(ctx, isl_error_unsupported,
5842			"cannot handle divs yet", return isl_aff_free(aff));
5843
5844	aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
5845	if (!aff->ls)
5846		return isl_aff_free(aff);
5847
5848	aff->v = isl_vec_cow(aff->v);
5849	if (!aff->v)
5850		return isl_aff_free(aff);
5851
5852	pos += isl_local_space_offset(aff->ls, type);
5853
5854	isl_int_init(v);
5855	isl_seq_substitute(aff->v->el, pos, subs->v->el,
5856			    aff->v->size, subs->v->size, v);
5857	isl_int_clear(v);
5858
5859	return aff;
5860}
5861
5862/* Plug in "subs" for dimension "type", "pos" in each of the affine
5863 * expressions in "maff".
5864 */
5865__isl_give isl_multi_aff *isl_multi_aff_substitute(
5866	__isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
5867	__isl_keep isl_aff *subs)
5868{
5869	isl_size n;
5870	int i;
5871
5872	n = isl_multi_aff_size(maff);
5873	if (n < 0 || !subs)
5874		return isl_multi_aff_free(maff);
5875
5876	if (type == isl_dim_in)
5877		type = isl_dim_set;
5878
5879	for (i = 0; i < n; ++i) {
5880		isl_aff *aff;
5881
5882		aff = isl_multi_aff_take_at(maff, i);
5883		aff = isl_aff_substitute(aff, type, pos, subs);
5884		maff = isl_multi_aff_restore_at(maff, i, aff);
5885	}
5886
5887	return maff;
5888}
5889
5890/* Plug in "subs" for input dimension "pos" of "pma".
5891 *
5892 * pma is of the form
5893 *
5894 *	A_i(v) -> M_i(v)
5895 *
5896 * while subs is of the form
5897 *
5898 *	v' = B_j(v) -> S_j
5899 *
5900 * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
5901 * has a contribution in the result, in particular
5902 *
5903 *	C_ij(S_j) -> M_i(S_j)
5904 *
5905 * Note that plugging in S_j in C_ij may also result in an empty set
5906 * and this contribution should simply be discarded.
5907 */
5908__isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
5909	__isl_take isl_pw_multi_aff *pma, unsigned pos,
5910	__isl_keep isl_pw_aff *subs)
5911{
5912	int i, j, n;
5913	isl_pw_multi_aff *res;
5914
5915	if (!pma || !subs)
5916		return isl_pw_multi_aff_free(pma);
5917
5918	n = pma->n * subs->n;
5919	res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
5920
5921	for (i = 0; i < pma->n; ++i) {
5922		for (j = 0; j < subs->n; ++j) {
5923			isl_set *common;
5924			isl_multi_aff *res_ij;
5925			int empty;
5926
5927			common = isl_set_intersect(
5928					isl_set_copy(pma->p[i].set),
5929					isl_set_copy(subs->p[j].set));
5930			common = isl_set_substitute(common,
5931					pos, subs->p[j].aff);
5932			empty = isl_set_plain_is_empty(common);
5933			if (empty < 0 || empty) {
5934				isl_set_free(common);
5935				if (empty < 0)
5936					goto error;
5937				continue;
5938			}
5939
5940			res_ij = isl_multi_aff_substitute(
5941					isl_multi_aff_copy(pma->p[i].maff),
5942					isl_dim_in, pos, subs->p[j].aff);
5943
5944			res = isl_pw_multi_aff_add_piece(res, common, res_ij);
5945		}
5946	}
5947
5948	isl_pw_multi_aff_free(pma);
5949	return res;
5950error:
5951	isl_pw_multi_aff_free(pma);
5952	isl_pw_multi_aff_free(res);
5953	return NULL;
5954}
5955
5956/* Compute the preimage of a range of dimensions in the affine expression "src"
5957 * under "ma" and put the result in "dst".  The number of dimensions in "src"
5958 * that precede the range is given by "n_before".  The number of dimensions
5959 * in the range is given by the number of output dimensions of "ma".
5960 * The number of dimensions that follow the range is given by "n_after".
5961 * If "has_denom" is set (to one),
5962 * then "src" and "dst" have an extra initial denominator.
5963 * "n_div_ma" is the number of existentials in "ma"
5964 * "n_div_bset" is the number of existentials in "src"
5965 * The resulting "dst" (which is assumed to have been allocated by
5966 * the caller) contains coefficients for both sets of existentials,
5967 * first those in "ma" and then those in "src".
5968 * f, c1, c2 and g are temporary objects that have been initialized
5969 * by the caller.
5970 *
5971 * Let src represent the expression
5972 *
5973 *	(a(p) + f_u u + b v + f_w w + c(divs))/d
5974 *
5975 * and let ma represent the expressions
5976 *
5977 *	v_i = (r_i(p) + s_i(y) + t_i(divs'))/m_i
5978 *
5979 * We start out with the following expression for dst:
5980 *
5981 *	(a(p) + f_u u + 0 y + f_w w + 0 divs' + c(divs) + f \sum_i b_i v_i)/d
5982 *
5983 * with the multiplication factor f initially equal to 1
5984 * and f \sum_i b_i v_i kept separately.
5985 * For each x_i that we substitute, we multiply the numerator
5986 * (and denominator) of dst by c_1 = m_i and add the numerator
5987 * of the x_i expression multiplied by c_2 = f b_i,
5988 * after removing the common factors of c_1 and c_2.
5989 * The multiplication factor f also needs to be multiplied by c_1
5990 * for the next x_j, j > i.
5991 */
5992isl_stat isl_seq_preimage(isl_int *dst, isl_int *src,
5993	__isl_keep isl_multi_aff *ma, int n_before, int n_after,
5994	int n_div_ma, int n_div_bmap,
5995	isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom)
5996{
5997	int i;
5998	isl_size n_param, n_in, n_out;
5999	int o_dst, o_src;
6000
6001	n_param = isl_multi_aff_dim(ma, isl_dim_param);
6002	n_in = isl_multi_aff_dim(ma, isl_dim_in);
6003	n_out = isl_multi_aff_dim(ma, isl_dim_out);
6004	if (n_param < 0 || n_in < 0 || n_out < 0)
6005		return isl_stat_error;
6006
6007	isl_seq_cpy(dst, src, has_denom + 1 + n_param + n_before);
6008	o_dst = o_src = has_denom + 1 + n_param + n_before;
6009	isl_seq_clr(dst + o_dst, n_in);
6010	o_dst += n_in;
6011	o_src += n_out;
6012	isl_seq_cpy(dst + o_dst, src + o_src, n_after);
6013	o_dst += n_after;
6014	o_src += n_after;
6015	isl_seq_clr(dst + o_dst, n_div_ma);
6016	o_dst += n_div_ma;
6017	isl_seq_cpy(dst + o_dst, src + o_src, n_div_bmap);
6018
6019	isl_int_set_si(f, 1);
6020
6021	for (i = 0; i < n_out; ++i) {
6022		int offset = has_denom + 1 + n_param + n_before + i;
6023
6024		if (isl_int_is_zero(src[offset]))
6025			continue;
6026		isl_int_set(c1, ma->u.p[i]->v->el[0]);
6027		isl_int_mul(c2, f, src[offset]);
6028		isl_int_gcd(g, c1, c2);
6029		isl_int_divexact(c1, c1, g);
6030		isl_int_divexact(c2, c2, g);
6031
6032		isl_int_mul(f, f, c1);
6033		o_dst = has_denom;
6034		o_src = 1;
6035		isl_seq_combine(dst + o_dst, c1, dst + o_dst,
6036				c2, ma->u.p[i]->v->el + o_src, 1 + n_param);
6037		o_dst += 1 + n_param;
6038		o_src += 1 + n_param;
6039		isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_before);
6040		o_dst += n_before;
6041		isl_seq_combine(dst + o_dst, c1, dst + o_dst,
6042				c2, ma->u.p[i]->v->el + o_src, n_in);
6043		o_dst += n_in;
6044		o_src += n_in;
6045		isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_after);
6046		o_dst += n_after;
6047		isl_seq_combine(dst + o_dst, c1, dst + o_dst,
6048				c2, ma->u.p[i]->v->el + o_src, n_div_ma);
6049		o_dst += n_div_ma;
6050		o_src += n_div_ma;
6051		isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_div_bmap);
6052		if (has_denom)
6053			isl_int_mul(dst[0], dst[0], c1);
6054	}
6055
6056	return isl_stat_ok;
6057}
6058
6059/* Compute the pullback of "aff" by the function represented by "ma".
6060 * In other words, plug in "ma" in "aff".  The result is an affine expression
6061 * defined over the domain space of "ma".
6062 *
6063 * If "aff" is represented by
6064 *
6065 *	(a(p) + b x + c(divs))/d
6066 *
6067 * and ma is represented by
6068 *
6069 *	x = D(p) + F(y) + G(divs')
6070 *
6071 * then the result is
6072 *
6073 *	(a(p) + b D(p) + b F(y) + b G(divs') + c(divs))/d
6074 *
6075 * The divs in the local space of the input are similarly adjusted
6076 * through a call to isl_local_space_preimage_multi_aff.
6077 */
6078__isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff,
6079	__isl_take isl_multi_aff *ma)
6080{
6081	isl_aff *res = NULL;
6082	isl_local_space *ls;
6083	isl_size n_div_aff, n_div_ma;
6084	isl_int f, c1, c2, g;
6085
6086	ma = isl_multi_aff_align_divs(ma);
6087	if (!aff || !ma)
6088		goto error;
6089
6090	n_div_aff = isl_aff_dim(aff, isl_dim_div);
6091	n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0;
6092	if (n_div_aff < 0 || n_div_ma < 0)
6093		goto error;
6094
6095	ls = isl_aff_get_domain_local_space(aff);
6096	ls = isl_local_space_preimage_multi_aff(ls, isl_multi_aff_copy(ma));
6097	res = isl_aff_alloc(ls);
6098	if (!res)
6099		goto error;
6100
6101	isl_int_init(f);
6102	isl_int_init(c1);
6103	isl_int_init(c2);
6104	isl_int_init(g);
6105
6106	if (isl_seq_preimage(res->v->el, aff->v->el, ma, 0, 0,
6107			    n_div_ma, n_div_aff, f, c1, c2, g, 1) < 0)
6108		res = isl_aff_free(res);
6109
6110	isl_int_clear(f);
6111	isl_int_clear(c1);
6112	isl_int_clear(c2);
6113	isl_int_clear(g);
6114
6115	isl_aff_free(aff);
6116	isl_multi_aff_free(ma);
6117	res = isl_aff_normalize(res);
6118	return res;
6119error:
6120	isl_aff_free(aff);
6121	isl_multi_aff_free(ma);
6122	isl_aff_free(res);
6123	return NULL;
6124}
6125
6126/* Compute the pullback of "aff1" by the function represented by "aff2".
6127 * In other words, plug in "aff2" in "aff1".  The result is an affine expression
6128 * defined over the domain space of "aff1".
6129 *
6130 * The domain of "aff1" should match the range of "aff2", which means
6131 * that it should be single-dimensional.
6132 */
6133__isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1,
6134	__isl_take isl_aff *aff2)
6135{
6136	isl_multi_aff *ma;
6137
6138	ma = isl_multi_aff_from_aff(aff2);
6139	return isl_aff_pullback_multi_aff(aff1, ma);
6140}
6141
6142/* Compute the pullback of "ma1" by the function represented by "ma2".
6143 * In other words, plug in "ma2" in "ma1".
6144 */
6145__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
6146	__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
6147{
6148	int i;
6149	isl_size n;
6150	isl_space *space = NULL;
6151
6152	isl_multi_aff_align_params_bin(&ma1, &ma2);
6153	ma2 = isl_multi_aff_align_divs(ma2);
6154	n = isl_multi_aff_size(ma1);
6155	if (n < 0 || !ma2)
6156		goto error;
6157
6158	space = isl_space_join(isl_multi_aff_get_space(ma2),
6159				isl_multi_aff_get_space(ma1));
6160
6161	for (i = 0; i < n; ++i) {
6162		isl_aff *aff;
6163
6164		aff = isl_multi_aff_take_at(ma1, i);
6165		aff = isl_aff_pullback_multi_aff(aff, isl_multi_aff_copy(ma2));
6166		ma1 = isl_multi_aff_restore_at(ma1, i, aff);
6167	}
6168
6169	ma1 = isl_multi_aff_reset_space(ma1, space);
6170	isl_multi_aff_free(ma2);
6171	return ma1;
6172error:
6173	isl_space_free(space);
6174	isl_multi_aff_free(ma2);
6175	isl_multi_aff_free(ma1);
6176	return NULL;
6177}
6178
6179/* Extend the local space of "dst" to include the divs
6180 * in the local space of "src".
6181 *
6182 * If "src" does not have any divs or if the local spaces of "dst" and
6183 * "src" are the same, then no extension is required.
6184 */
6185__isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
6186	__isl_keep isl_aff *src)
6187{
6188	isl_ctx *ctx;
6189	isl_size src_n_div, dst_n_div;
6190	int *exp1 = NULL;
6191	int *exp2 = NULL;
6192	isl_bool equal;
6193	isl_mat *div;
6194
6195	if (!src || !dst)
6196		return isl_aff_free(dst);
6197
6198	ctx = isl_aff_get_ctx(src);
6199	equal = isl_local_space_has_equal_space(src->ls, dst->ls);
6200	if (equal < 0)
6201		return isl_aff_free(dst);
6202	if (!equal)
6203		isl_die(ctx, isl_error_invalid,
6204			"spaces don't match", goto error);
6205
6206	src_n_div = isl_aff_domain_dim(src, isl_dim_div);
6207	dst_n_div = isl_aff_domain_dim(dst, isl_dim_div);
6208	if (src_n_div == 0)
6209		return dst;
6210	equal = isl_local_space_is_equal(src->ls, dst->ls);
6211	if (equal < 0 || src_n_div < 0 || dst_n_div < 0)
6212		return isl_aff_free(dst);
6213	if (equal)
6214		return dst;
6215
6216	exp1 = isl_alloc_array(ctx, int, src_n_div);
6217	exp2 = isl_alloc_array(ctx, int, dst_n_div);
6218	if (!exp1 || (dst_n_div && !exp2))
6219		goto error;
6220
6221	div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
6222	dst = isl_aff_expand_divs(dst, div, exp2);
6223	free(exp1);
6224	free(exp2);
6225
6226	return dst;
6227error:
6228	free(exp1);
6229	free(exp2);
6230	return isl_aff_free(dst);
6231}
6232
6233/* Adjust the local spaces of the affine expressions in "maff"
6234 * such that they all have the save divs.
6235 */
6236__isl_give isl_multi_aff *isl_multi_aff_align_divs(
6237	__isl_take isl_multi_aff *maff)
6238{
6239	isl_aff *aff_0;
6240	isl_size n;
6241	int i;
6242
6243	n = isl_multi_aff_size(maff);
6244	if (n < 0)
6245		return isl_multi_aff_free(maff);
6246	if (n <= 1)
6247		return maff;
6248
6249	aff_0 = isl_multi_aff_take_at(maff, 0);
6250	for (i = 1; i < n; ++i) {
6251		isl_aff *aff_i;
6252
6253		aff_i = isl_multi_aff_peek_at(maff, i);
6254		aff_0 = isl_aff_align_divs(aff_0, aff_i);
6255	}
6256	maff = isl_multi_aff_restore_at(maff, 0, aff_0);
6257
6258	aff_0 = isl_multi_aff_peek_at(maff, 0);
6259	for (i = 1; i < n; ++i) {
6260		isl_aff *aff_i;
6261
6262		aff_i = isl_multi_aff_take_at(maff, i);
6263		aff_i = isl_aff_align_divs(aff_i, aff_0);
6264		maff = isl_multi_aff_restore_at(maff, i, aff_i);
6265	}
6266
6267	return maff;
6268}
6269
6270__isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
6271{
6272	aff = isl_aff_cow(aff);
6273	if (!aff)
6274		return NULL;
6275
6276	aff->ls = isl_local_space_lift(aff->ls);
6277	if (!aff->ls)
6278		return isl_aff_free(aff);
6279
6280	return aff;
6281}
6282
6283/* Lift "maff" to a space with extra dimensions such that the result
6284 * has no more existentially quantified variables.
6285 * If "ls" is not NULL, then *ls is assigned the local space that lies
6286 * at the basis of the lifting applied to "maff".
6287 */
6288__isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
6289	__isl_give isl_local_space **ls)
6290{
6291	int i;
6292	isl_space *space;
6293	isl_aff *aff;
6294	isl_size n, n_div;
6295
6296	if (ls)
6297		*ls = NULL;
6298
6299	n = isl_multi_aff_size(maff);
6300	if (n < 0)
6301		return isl_multi_aff_free(maff);
6302
6303	if (n == 0) {
6304		if (ls) {
6305			isl_space *space = isl_multi_aff_get_domain_space(maff);
6306			*ls = isl_local_space_from_space(space);
6307			if (!*ls)
6308				return isl_multi_aff_free(maff);
6309		}
6310		return maff;
6311	}
6312
6313	maff = isl_multi_aff_align_divs(maff);
6314
6315	aff = isl_multi_aff_peek_at(maff, 0);
6316	n_div = isl_aff_dim(aff, isl_dim_div);
6317	if (n_div < 0)
6318		return isl_multi_aff_free(maff);
6319	space = isl_multi_aff_get_space(maff);
6320	space = isl_space_lift(isl_space_domain(space), n_div);
6321	space = isl_space_extend_domain_with_range(space,
6322						isl_multi_aff_get_space(maff));
6323	maff = isl_multi_aff_restore_space(maff, space);
6324
6325	if (ls) {
6326		aff = isl_multi_aff_peek_at(maff, 0);
6327		*ls = isl_aff_get_domain_local_space(aff);
6328		if (!*ls)
6329			return isl_multi_aff_free(maff);
6330	}
6331
6332	for (i = 0; i < n; ++i) {
6333		aff = isl_multi_aff_take_at(maff, i);
6334		aff = isl_aff_lift(aff);
6335		maff = isl_multi_aff_restore_at(maff, i, aff);
6336	}
6337
6338	return maff;
6339}
6340
6341#undef TYPE
6342#define TYPE	isl_pw_multi_aff
6343static
6344#include "check_type_range_templ.c"
6345
6346/* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
6347 */
6348__isl_give isl_pw_aff *isl_pw_multi_aff_get_at(
6349	__isl_keep isl_pw_multi_aff *pma, int pos)
6350{
6351	int i;
6352	isl_size n_out;
6353	isl_space *space;
6354	isl_pw_aff *pa;
6355
6356	if (isl_pw_multi_aff_check_range(pma, isl_dim_out, pos, 1) < 0)
6357		return NULL;
6358
6359	n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
6360	if (n_out < 0)
6361		return NULL;
6362
6363	space = isl_pw_multi_aff_get_space(pma);
6364	space = isl_space_drop_dims(space, isl_dim_out,
6365				    pos + 1, n_out - pos - 1);
6366	space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
6367
6368	pa = isl_pw_aff_alloc_size(space, pma->n);
6369	for (i = 0; i < pma->n; ++i) {
6370		isl_aff *aff;
6371		aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
6372		pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
6373	}
6374
6375	return pa;
6376}
6377
6378/* This is an alternative name for the function above.
6379 */
6380__isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
6381	__isl_keep isl_pw_multi_aff *pma, int pos)
6382{
6383	return isl_pw_multi_aff_get_at(pma, pos);
6384}
6385
6386/* Return an isl_pw_multi_aff with the given "set" as domain and
6387 * an unnamed zero-dimensional range.
6388 */
6389__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain(
6390	__isl_take isl_set *set)
6391{
6392	isl_multi_aff *ma;
6393	isl_space *space;
6394
6395	space = isl_set_get_space(set);
6396	space = isl_space_from_domain(space);
6397	ma = isl_multi_aff_zero(space);
6398	return isl_pw_multi_aff_alloc(set, ma);
6399}
6400
6401/* Add an isl_pw_multi_aff with the given "set" as domain and
6402 * an unnamed zero-dimensional range to *user.
6403 */
6404static isl_stat add_pw_multi_aff_from_domain(__isl_take isl_set *set,
6405	void *user)
6406{
6407	isl_union_pw_multi_aff **upma = user;
6408	isl_pw_multi_aff *pma;
6409
6410	pma = isl_pw_multi_aff_from_domain(set);
6411	*upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
6412
6413	return isl_stat_ok;
6414}
6415
6416/* Return an isl_union_pw_multi_aff with the given "uset" as domain and
6417 * an unnamed zero-dimensional range.
6418 */
6419__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain(
6420	__isl_take isl_union_set *uset)
6421{
6422	isl_space *space;
6423	isl_union_pw_multi_aff *upma;
6424
6425	if (!uset)
6426		return NULL;
6427
6428	space = isl_union_set_get_space(uset);
6429	upma = isl_union_pw_multi_aff_empty(space);
6430
6431	if (isl_union_set_foreach_set(uset,
6432				    &add_pw_multi_aff_from_domain, &upma) < 0)
6433		goto error;
6434
6435	isl_union_set_free(uset);
6436	return upma;
6437error:
6438	isl_union_set_free(uset);
6439	isl_union_pw_multi_aff_free(upma);
6440	return NULL;
6441}
6442
6443/* Local data for bin_entry and the callback "fn".
6444 */
6445struct isl_union_pw_multi_aff_bin_data {
6446	isl_union_pw_multi_aff *upma2;
6447	isl_union_pw_multi_aff *res;
6448	isl_pw_multi_aff *pma;
6449	isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user);
6450};
6451
6452/* Given an isl_pw_multi_aff from upma1, store it in data->pma
6453 * and call data->fn for each isl_pw_multi_aff in data->upma2.
6454 */
6455static isl_stat bin_entry(__isl_take isl_pw_multi_aff *pma, void *user)
6456{
6457	struct isl_union_pw_multi_aff_bin_data *data = user;
6458	isl_stat r;
6459
6460	data->pma = pma;
6461	r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma2,
6462				   data->fn, data);
6463	isl_pw_multi_aff_free(pma);
6464
6465	return r;
6466}
6467
6468/* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2".
6469 * The isl_pw_multi_aff from upma1 is stored in data->pma (where data is
6470 * passed as user field) and the isl_pw_multi_aff from upma2 is available
6471 * as *entry.  The callback should adjust data->res if desired.
6472 */
6473static __isl_give isl_union_pw_multi_aff *bin_op(
6474	__isl_take isl_union_pw_multi_aff *upma1,
6475	__isl_take isl_union_pw_multi_aff *upma2,
6476	isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user))
6477{
6478	isl_space *space;
6479	struct isl_union_pw_multi_aff_bin_data data = { NULL, NULL, NULL, fn };
6480
6481	space = isl_union_pw_multi_aff_get_space(upma2);
6482	upma1 = isl_union_pw_multi_aff_align_params(upma1, space);
6483	space = isl_union_pw_multi_aff_get_space(upma1);
6484	upma2 = isl_union_pw_multi_aff_align_params(upma2, space);
6485
6486	if (!upma1 || !upma2)
6487		goto error;
6488
6489	data.upma2 = upma2;
6490	data.res = isl_union_pw_multi_aff_alloc_same_size(upma1);
6491	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma1,
6492				   &bin_entry, &data) < 0)
6493		goto error;
6494
6495	isl_union_pw_multi_aff_free(upma1);
6496	isl_union_pw_multi_aff_free(upma2);
6497	return data.res;
6498error:
6499	isl_union_pw_multi_aff_free(upma1);
6500	isl_union_pw_multi_aff_free(upma2);
6501	isl_union_pw_multi_aff_free(data.res);
6502	return NULL;
6503}
6504
6505/* Given two isl_pw_multi_affs A -> B and C -> D,
6506 * construct an isl_pw_multi_aff (A * C) -> [B -> D].
6507 */
6508__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product(
6509	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
6510{
6511	isl_space *space;
6512
6513	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
6514	space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
6515					isl_pw_multi_aff_get_space(pma2));
6516	return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
6517					    &isl_multi_aff_range_product);
6518}
6519
6520/* Given two isl_pw_multi_affs A -> B and C -> D,
6521 * construct an isl_pw_multi_aff (A * C) -> (B, D).
6522 */
6523__isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product(
6524	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
6525{
6526	isl_space *space;
6527
6528	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
6529	space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
6530					isl_pw_multi_aff_get_space(pma2));
6531	space = isl_space_flatten_range(space);
6532	return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
6533					    &isl_multi_aff_flat_range_product);
6534}
6535
6536/* If data->pma and "pma2" have the same domain space, then use "range_product"
6537 * to compute some form of range product and add the result to data->res.
6538 */
6539static isl_stat gen_range_product_entry(__isl_take isl_pw_multi_aff *pma2,
6540	__isl_give isl_pw_multi_aff *(*range_product)(
6541		__isl_take isl_pw_multi_aff *pma1,
6542		__isl_take isl_pw_multi_aff *pma2),
6543	void *user)
6544{
6545	struct isl_union_pw_multi_aff_bin_data *data = user;
6546	isl_bool match;
6547	isl_space *space1, *space2;
6548
6549	space1 = isl_pw_multi_aff_peek_space(data->pma);
6550	space2 = isl_pw_multi_aff_peek_space(pma2);
6551	match = isl_space_tuple_is_equal(space1, isl_dim_in,
6552					space2, isl_dim_in);
6553	if (match < 0 || !match) {
6554		isl_pw_multi_aff_free(pma2);
6555		return match < 0 ? isl_stat_error : isl_stat_ok;
6556	}
6557
6558	pma2 = range_product(isl_pw_multi_aff_copy(data->pma), pma2);
6559
6560	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
6561
6562	return isl_stat_ok;
6563}
6564
6565/* If data->pma and "pma2" have the same domain space, then compute
6566 * their flat range product and add the result to data->res.
6567 */
6568static isl_stat flat_range_product_entry(__isl_take isl_pw_multi_aff *pma2,
6569	void *user)
6570{
6571	return gen_range_product_entry(pma2,
6572				&isl_pw_multi_aff_flat_range_product, user);
6573}
6574
6575/* Given two isl_union_pw_multi_affs A -> B and C -> D,
6576 * construct an isl_union_pw_multi_aff (A * C) -> (B, D).
6577 */
6578__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product(
6579	__isl_take isl_union_pw_multi_aff *upma1,
6580	__isl_take isl_union_pw_multi_aff *upma2)
6581{
6582	return bin_op(upma1, upma2, &flat_range_product_entry);
6583}
6584
6585/* If data->pma and "pma2" have the same domain space, then compute
6586 * their range product and add the result to data->res.
6587 */
6588static isl_stat range_product_entry(__isl_take isl_pw_multi_aff *pma2,
6589	void *user)
6590{
6591	return gen_range_product_entry(pma2,
6592				&isl_pw_multi_aff_range_product, user);
6593}
6594
6595/* Given two isl_union_pw_multi_affs A -> B and C -> D,
6596 * construct an isl_union_pw_multi_aff (A * C) -> [B -> D].
6597 */
6598__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_product(
6599	__isl_take isl_union_pw_multi_aff *upma1,
6600	__isl_take isl_union_pw_multi_aff *upma2)
6601{
6602	return bin_op(upma1, upma2, &range_product_entry);
6603}
6604
6605/* Replace the affine expressions at position "pos" in "pma" by "pa".
6606 * The parameters are assumed to have been aligned.
6607 *
6608 * The implementation essentially performs an isl_pw_*_on_shared_domain,
6609 * except that it works on two different isl_pw_* types.
6610 */
6611static __isl_give isl_pw_multi_aff *pw_multi_aff_set_pw_aff(
6612	__isl_take isl_pw_multi_aff *pma, unsigned pos,
6613	__isl_take isl_pw_aff *pa)
6614{
6615	int i, j, n;
6616	isl_pw_multi_aff *res = NULL;
6617
6618	if (!pma || !pa)
6619		goto error;
6620
6621	if (!isl_space_tuple_is_equal(pma->dim, isl_dim_in,
6622					pa->dim, isl_dim_in))
6623		isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
6624			"domains don't match", goto error);
6625	if (isl_pw_multi_aff_check_range(pma, isl_dim_out, pos, 1) < 0)
6626		goto error;
6627
6628	n = pma->n * pa->n;
6629	res = isl_pw_multi_aff_alloc_size(isl_pw_multi_aff_get_space(pma), n);
6630
6631	for (i = 0; i < pma->n; ++i) {
6632		for (j = 0; j < pa->n; ++j) {
6633			isl_set *common;
6634			isl_multi_aff *res_ij;
6635			int empty;
6636
6637			common = isl_set_intersect(isl_set_copy(pma->p[i].set),
6638						   isl_set_copy(pa->p[j].set));
6639			empty = isl_set_plain_is_empty(common);
6640			if (empty < 0 || empty) {
6641				isl_set_free(common);
6642				if (empty < 0)
6643					goto error;
6644				continue;
6645			}
6646
6647			res_ij = isl_multi_aff_set_aff(
6648					isl_multi_aff_copy(pma->p[i].maff), pos,
6649					isl_aff_copy(pa->p[j].aff));
6650			res_ij = isl_multi_aff_gist(res_ij,
6651					isl_set_copy(common));
6652
6653			res = isl_pw_multi_aff_add_piece(res, common, res_ij);
6654		}
6655	}
6656
6657	isl_pw_multi_aff_free(pma);
6658	isl_pw_aff_free(pa);
6659	return res;
6660error:
6661	isl_pw_multi_aff_free(pma);
6662	isl_pw_aff_free(pa);
6663	return isl_pw_multi_aff_free(res);
6664}
6665
6666/* Replace the affine expressions at position "pos" in "pma" by "pa".
6667 */
6668__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff(
6669	__isl_take isl_pw_multi_aff *pma, unsigned pos,
6670	__isl_take isl_pw_aff *pa)
6671{
6672	isl_bool equal_params;
6673
6674	if (!pma || !pa)
6675		goto error;
6676	equal_params = isl_space_has_equal_params(pma->dim, pa->dim);
6677	if (equal_params < 0)
6678		goto error;
6679	if (equal_params)
6680		return pw_multi_aff_set_pw_aff(pma, pos, pa);
6681	if (isl_pw_multi_aff_check_named_params(pma) < 0 ||
6682	    isl_pw_aff_check_named_params(pa) < 0)
6683		goto error;
6684	pma = isl_pw_multi_aff_align_params(pma, isl_pw_aff_get_space(pa));
6685	pa = isl_pw_aff_align_params(pa, isl_pw_multi_aff_get_space(pma));
6686	return pw_multi_aff_set_pw_aff(pma, pos, pa);
6687error:
6688	isl_pw_multi_aff_free(pma);
6689	isl_pw_aff_free(pa);
6690	return NULL;
6691}
6692
6693/* Do the parameters of "pa" match those of "space"?
6694 */
6695isl_bool isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa,
6696	__isl_keep isl_space *space)
6697{
6698	isl_space *pa_space;
6699	isl_bool match;
6700
6701	if (!pa || !space)
6702		return isl_bool_error;
6703
6704	pa_space = isl_pw_aff_get_space(pa);
6705
6706	match = isl_space_has_equal_params(space, pa_space);
6707
6708	isl_space_free(pa_space);
6709	return match;
6710}
6711
6712/* Check that the domain space of "pa" matches "space".
6713 */
6714isl_stat isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa,
6715	__isl_keep isl_space *space)
6716{
6717	isl_space *pa_space;
6718	isl_bool match;
6719
6720	if (!pa || !space)
6721		return isl_stat_error;
6722
6723	pa_space = isl_pw_aff_get_space(pa);
6724
6725	match = isl_space_has_equal_params(space, pa_space);
6726	if (match < 0)
6727		goto error;
6728	if (!match)
6729		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
6730			"parameters don't match", goto error);
6731	match = isl_space_tuple_is_equal(space, isl_dim_in,
6732					pa_space, isl_dim_in);
6733	if (match < 0)
6734		goto error;
6735	if (!match)
6736		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
6737			"domains don't match", goto error);
6738	isl_space_free(pa_space);
6739	return isl_stat_ok;
6740error:
6741	isl_space_free(pa_space);
6742	return isl_stat_error;
6743}
6744
6745#undef BASE
6746#define BASE pw_aff
6747#undef DOMBASE
6748#define DOMBASE set
6749
6750#include <isl_multi_explicit_domain.c>
6751#include <isl_multi_pw_aff_explicit_domain.c>
6752#include <isl_multi_templ.c>
6753#include <isl_multi_un_op_templ.c>
6754#include <isl_multi_bin_val_templ.c>
6755#include <isl_multi_add_constant_templ.c>
6756#include <isl_multi_align_set.c>
6757#include <isl_multi_apply_set_explicit_domain_templ.c>
6758#include <isl_multi_arith_templ.c>
6759#include <isl_multi_bind_templ.c>
6760#include <isl_multi_bind_domain_templ.c>
6761#include <isl_multi_coalesce.c>
6762#include <isl_multi_domain_templ.c>
6763#include <isl_multi_domain_reverse_templ.c>
6764#include <isl_multi_dim_id_templ.c>
6765#include <isl_multi_dims.c>
6766#include <isl_multi_from_base_templ.c>
6767#include <isl_multi_check_domain_templ.c>
6768#include <isl_multi_gist.c>
6769#include <isl_multi_hash.c>
6770#include <isl_multi_identity_templ.c>
6771#include <isl_multi_insert_domain_templ.c>
6772#include <isl_multi_intersect.c>
6773#include <isl_multi_min_max_templ.c>
6774#include <isl_multi_move_dims_templ.c>
6775#include <isl_multi_nan_templ.c>
6776#include <isl_multi_param_templ.c>
6777#include <isl_multi_product_templ.c>
6778#include <isl_multi_splice_templ.c>
6779#include <isl_multi_tuple_id_templ.c>
6780#include <isl_multi_union_add_templ.c>
6781#include <isl_multi_zero_templ.c>
6782#include <isl_multi_unbind_params_templ.c>
6783
6784/* Is every element of "mpa" defined over a single universe domain?
6785 */
6786isl_bool isl_multi_pw_aff_isa_multi_aff(__isl_keep isl_multi_pw_aff *mpa)
6787{
6788	return isl_multi_pw_aff_every(mpa, &isl_pw_aff_isa_aff);
6789}
6790
6791/* Given that every element of "mpa" is defined over a single universe domain,
6792 * return the corresponding base expressions.
6793 */
6794__isl_give isl_multi_aff *isl_multi_pw_aff_as_multi_aff(
6795	__isl_take isl_multi_pw_aff *mpa)
6796{
6797	int i;
6798	isl_size n;
6799	isl_multi_aff *ma;
6800
6801	n = isl_multi_pw_aff_size(mpa);
6802	if (n < 0)
6803		mpa = isl_multi_pw_aff_free(mpa);
6804	ma = isl_multi_aff_alloc(isl_multi_pw_aff_get_space(mpa));
6805	for (i = 0; i < n; ++i) {
6806		isl_aff *aff;
6807
6808		aff = isl_pw_aff_as_aff(isl_multi_pw_aff_get_at(mpa, i));
6809		ma = isl_multi_aff_set_aff(ma, i, aff);
6810	}
6811	isl_multi_pw_aff_free(mpa);
6812	return ma;
6813}
6814
6815/* If "mpa" has an explicit domain, then intersect the domain of "map"
6816 * with this explicit domain.
6817 */
6818__isl_give isl_map *isl_map_intersect_multi_pw_aff_explicit_domain(
6819	__isl_take isl_map *map, __isl_keep isl_multi_pw_aff *mpa)
6820{
6821	isl_set *dom;
6822
6823	if (!isl_multi_pw_aff_has_explicit_domain(mpa))
6824		return map;
6825
6826	dom = isl_multi_pw_aff_domain(isl_multi_pw_aff_copy(mpa));
6827	map = isl_map_intersect_domain(map, dom);
6828
6829	return map;
6830}
6831
6832/* Are all elements of "mpa" piecewise constants?
6833 */
6834isl_bool isl_multi_pw_aff_is_cst(__isl_keep isl_multi_pw_aff *mpa)
6835{
6836	return isl_multi_pw_aff_every(mpa, &isl_pw_aff_is_cst);
6837}
6838
6839/* Does "mpa" have a non-trivial explicit domain?
6840 *
6841 * The explicit domain, if present, is trivial if it represents
6842 * an (obviously) universe set.
6843 */
6844isl_bool isl_multi_pw_aff_has_non_trivial_domain(
6845	__isl_keep isl_multi_pw_aff *mpa)
6846{
6847	if (!mpa)
6848		return isl_bool_error;
6849	if (!isl_multi_pw_aff_has_explicit_domain(mpa))
6850		return isl_bool_false;
6851	return isl_bool_not(isl_set_plain_is_universe(mpa->u.dom));
6852}
6853
6854#undef BASE
6855#define BASE	set
6856
6857#include "isl_opt_mpa_templ.c"
6858
6859/* Compute the minima of the set dimensions as a function of the
6860 * parameters, but independently of the other set dimensions.
6861 */
6862__isl_give isl_multi_pw_aff *isl_set_min_multi_pw_aff(__isl_take isl_set *set)
6863{
6864	return set_opt_mpa(set, &isl_set_dim_min);
6865}
6866
6867/* Compute the maxima of the set dimensions as a function of the
6868 * parameters, but independently of the other set dimensions.
6869 */
6870__isl_give isl_multi_pw_aff *isl_set_max_multi_pw_aff(__isl_take isl_set *set)
6871{
6872	return set_opt_mpa(set, &isl_set_dim_max);
6873}
6874
6875#undef BASE
6876#define BASE	map
6877
6878#include "isl_opt_mpa_templ.c"
6879
6880/* Compute the minima of the output dimensions as a function of the
6881 * parameters and input dimensions, but independently of
6882 * the other output dimensions.
6883 */
6884__isl_give isl_multi_pw_aff *isl_map_min_multi_pw_aff(__isl_take isl_map *map)
6885{
6886	return map_opt_mpa(map, &isl_map_dim_min);
6887}
6888
6889/* Compute the maxima of the output dimensions as a function of the
6890 * parameters and input dimensions, but independently of
6891 * the other output dimensions.
6892 */
6893__isl_give isl_multi_pw_aff *isl_map_max_multi_pw_aff(__isl_take isl_map *map)
6894{
6895	return map_opt_mpa(map, &isl_map_dim_max);
6896}
6897
6898#undef TYPE
6899#define TYPE	isl_pw_multi_aff
6900#include "isl_type_check_match_range_multi_val.c"
6901
6902/* Apply "fn" to the base expressions of "pma" and "mv".
6903 */
6904static __isl_give isl_pw_multi_aff *isl_pw_multi_aff_op_multi_val(
6905	__isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv,
6906	__isl_give isl_multi_aff *(*fn)(__isl_take isl_multi_aff *ma,
6907		__isl_take isl_multi_val *mv))
6908{
6909	int i;
6910	isl_size n;
6911
6912	if (isl_pw_multi_aff_check_match_range_multi_val(pma, mv) < 0)
6913		goto error;
6914
6915	n = isl_pw_multi_aff_n_piece(pma);
6916	if (n < 0)
6917		goto error;
6918
6919	for (i = 0; i < n; ++i) {
6920		isl_multi_aff *ma;
6921
6922		ma = isl_pw_multi_aff_take_base_at(pma, i);
6923		ma = fn(ma, isl_multi_val_copy(mv));
6924		pma = isl_pw_multi_aff_restore_base_at(pma, i, ma);
6925	}
6926
6927	isl_multi_val_free(mv);
6928	return pma;
6929error:
6930	isl_multi_val_free(mv);
6931	isl_pw_multi_aff_free(pma);
6932	return NULL;
6933}
6934
6935/* Scale the elements of "pma" by the corresponding elements of "mv".
6936 */
6937__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_multi_val(
6938	__isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv)
6939{
6940	return isl_pw_multi_aff_op_multi_val(pma, mv,
6941					&isl_multi_aff_scale_multi_val);
6942}
6943
6944/* Scale the elements of "pma" down by the corresponding elements of "mv".
6945 */
6946__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_down_multi_val(
6947	__isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv)
6948{
6949	return isl_pw_multi_aff_op_multi_val(pma, mv,
6950					&isl_multi_aff_scale_down_multi_val);
6951}
6952
6953/* This function is called for each entry of an isl_union_pw_multi_aff.
6954 * If the space of the entry matches that of data->mv,
6955 * then apply isl_pw_multi_aff_scale_multi_val and return the result.
6956 * Otherwise, return an empty isl_pw_multi_aff.
6957 */
6958static __isl_give isl_pw_multi_aff *union_pw_multi_aff_scale_multi_val_entry(
6959	__isl_take isl_pw_multi_aff *pma, void *user)
6960{
6961	isl_bool equal;
6962	isl_multi_val *mv = user;
6963
6964	equal = isl_pw_multi_aff_match_range_multi_val(pma, mv);
6965	if (equal < 0)
6966		return isl_pw_multi_aff_free(pma);
6967	if (!equal) {
6968		isl_space *space = isl_pw_multi_aff_get_space(pma);
6969		isl_pw_multi_aff_free(pma);
6970		return isl_pw_multi_aff_empty(space);
6971	}
6972
6973	return isl_pw_multi_aff_scale_multi_val(pma, isl_multi_val_copy(mv));
6974}
6975
6976/* Scale the elements of "upma" by the corresponding elements of "mv",
6977 * for those entries that match the space of "mv".
6978 */
6979__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_multi_val(
6980	__isl_take isl_union_pw_multi_aff *upma, __isl_take isl_multi_val *mv)
6981{
6982	struct isl_union_pw_multi_aff_transform_control control = {
6983		.fn = &union_pw_multi_aff_scale_multi_val_entry,
6984		.fn_user = mv,
6985	};
6986
6987	upma = isl_union_pw_multi_aff_align_params(upma,
6988						isl_multi_val_get_space(mv));
6989	mv = isl_multi_val_align_params(mv,
6990					isl_union_pw_multi_aff_get_space(upma));
6991	if (!upma || !mv)
6992		goto error;
6993
6994	return isl_union_pw_multi_aff_transform(upma, &control);
6995
6996	isl_multi_val_free(mv);
6997	return upma;
6998error:
6999	isl_multi_val_free(mv);
7000	isl_union_pw_multi_aff_free(upma);
7001	return NULL;
7002}
7003
7004/* Construct and return a piecewise multi affine expression
7005 * in the given space with value zero in each of the output dimensions and
7006 * a universe domain.
7007 */
7008__isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space)
7009{
7010	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_zero(space));
7011}
7012
7013/* Construct and return a piecewise multi affine expression
7014 * that is equal to the given piecewise affine expression.
7015 */
7016__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff(
7017	__isl_take isl_pw_aff *pa)
7018{
7019	int i;
7020	isl_space *space;
7021	isl_pw_multi_aff *pma;
7022
7023	if (!pa)
7024		return NULL;
7025
7026	space = isl_pw_aff_get_space(pa);
7027	pma = isl_pw_multi_aff_alloc_size(space, pa->n);
7028
7029	for (i = 0; i < pa->n; ++i) {
7030		isl_set *set;
7031		isl_multi_aff *ma;
7032
7033		set = isl_set_copy(pa->p[i].set);
7034		ma = isl_multi_aff_from_aff(isl_aff_copy(pa->p[i].aff));
7035		pma = isl_pw_multi_aff_add_piece(pma, set, ma);
7036	}
7037
7038	isl_pw_aff_free(pa);
7039	return pma;
7040}
7041
7042/* Construct and return a piecewise multi affine expression
7043 * that is equal to the given multi piecewise affine expression
7044 * on the shared domain of the piecewise affine expressions,
7045 * in the special case of a 0D multi piecewise affine expression.
7046 *
7047 * Create a piecewise multi affine expression with the explicit domain of
7048 * the 0D multi piecewise affine expression as domain.
7049 */
7050static __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff_0D(
7051	__isl_take isl_multi_pw_aff *mpa)
7052{
7053	isl_space *space;
7054	isl_set *dom;
7055	isl_multi_aff *ma;
7056
7057	space = isl_multi_pw_aff_get_space(mpa);
7058	dom = isl_multi_pw_aff_get_explicit_domain(mpa);
7059	isl_multi_pw_aff_free(mpa);
7060
7061	ma = isl_multi_aff_zero(space);
7062	return isl_pw_multi_aff_alloc(dom, ma);
7063}
7064
7065/* Construct and return a piecewise multi affine expression
7066 * that is equal to the given multi piecewise affine expression
7067 * on the shared domain of the piecewise affine expressions.
7068 */
7069__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff(
7070	__isl_take isl_multi_pw_aff *mpa)
7071{
7072	int i;
7073	isl_space *space;
7074	isl_pw_aff *pa;
7075	isl_pw_multi_aff *pma;
7076
7077	if (!mpa)
7078		return NULL;
7079
7080	if (mpa->n == 0)
7081		return isl_pw_multi_aff_from_multi_pw_aff_0D(mpa);
7082
7083	space = isl_multi_pw_aff_get_space(mpa);
7084	pa = isl_multi_pw_aff_get_pw_aff(mpa, 0);
7085	pma = isl_pw_multi_aff_from_pw_aff(pa);
7086
7087	for (i = 1; i < mpa->n; ++i) {
7088		isl_pw_multi_aff *pma_i;
7089
7090		pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
7091		pma_i = isl_pw_multi_aff_from_pw_aff(pa);
7092		pma = isl_pw_multi_aff_range_product(pma, pma_i);
7093	}
7094
7095	pma = isl_pw_multi_aff_reset_space(pma, space);
7096
7097	isl_multi_pw_aff_free(mpa);
7098	return pma;
7099}
7100
7101/* Convenience function that constructs an isl_multi_pw_aff
7102 * directly from an isl_aff.
7103 */
7104__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_aff(__isl_take isl_aff *aff)
7105{
7106	return isl_multi_pw_aff_from_pw_aff(isl_pw_aff_from_aff(aff));
7107}
7108
7109/* Construct and return a multi piecewise affine expression
7110 * that is equal to the given multi affine expression.
7111 */
7112__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff(
7113	__isl_take isl_multi_aff *ma)
7114{
7115	int i;
7116	isl_size n;
7117	isl_multi_pw_aff *mpa;
7118
7119	n = isl_multi_aff_dim(ma, isl_dim_out);
7120	if (n < 0)
7121		ma = isl_multi_aff_free(ma);
7122	if (!ma)
7123		return NULL;
7124
7125	mpa = isl_multi_pw_aff_alloc(isl_multi_aff_get_space(ma));
7126
7127	for (i = 0; i < n; ++i) {
7128		isl_pw_aff *pa;
7129
7130		pa = isl_pw_aff_from_aff(isl_multi_aff_get_aff(ma, i));
7131		mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
7132	}
7133
7134	isl_multi_aff_free(ma);
7135	return mpa;
7136}
7137
7138/* This function performs the same operation as isl_multi_pw_aff_from_multi_aff,
7139 * but is considered as a function on an isl_multi_aff when exported.
7140 */
7141__isl_give isl_multi_pw_aff *isl_multi_aff_to_multi_pw_aff(
7142	__isl_take isl_multi_aff *ma)
7143{
7144	return isl_multi_pw_aff_from_multi_aff(ma);
7145}
7146
7147/* Construct and return a multi piecewise affine expression
7148 * that is equal to the given piecewise multi affine expression.
7149 *
7150 * If the resulting multi piecewise affine expression has
7151 * an explicit domain, then assign it the domain of the input.
7152 * In other cases, the domain is stored in the individual elements.
7153 */
7154__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff(
7155	__isl_take isl_pw_multi_aff *pma)
7156{
7157	int i;
7158	isl_size n;
7159	isl_space *space;
7160	isl_multi_pw_aff *mpa;
7161
7162	n = isl_pw_multi_aff_dim(pma, isl_dim_out);
7163	if (n < 0)
7164		pma = isl_pw_multi_aff_free(pma);
7165	space = isl_pw_multi_aff_get_space(pma);
7166	mpa = isl_multi_pw_aff_alloc(space);
7167
7168	for (i = 0; i < n; ++i) {
7169		isl_pw_aff *pa;
7170
7171		pa = isl_pw_multi_aff_get_pw_aff(pma, i);
7172		mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
7173	}
7174	if (isl_multi_pw_aff_has_explicit_domain(mpa)) {
7175		isl_set *dom;
7176
7177		dom = isl_pw_multi_aff_domain(isl_pw_multi_aff_copy(pma));
7178		mpa = isl_multi_pw_aff_intersect_domain(mpa, dom);
7179	}
7180
7181	isl_pw_multi_aff_free(pma);
7182	return mpa;
7183}
7184
7185/* This function performs the same operation as
7186 * isl_multi_pw_aff_from_pw_multi_aff,
7187 * but is considered as a function on an isl_pw_multi_aff when exported.
7188 */
7189__isl_give isl_multi_pw_aff *isl_pw_multi_aff_to_multi_pw_aff(
7190	__isl_take isl_pw_multi_aff *pma)
7191{
7192	return isl_multi_pw_aff_from_pw_multi_aff(pma);
7193}
7194
7195/* Do "pa1" and "pa2" represent the same function?
7196 *
7197 * We first check if they are obviously equal.
7198 * If not, we convert them to maps and check if those are equal.
7199 *
7200 * If "pa1" or "pa2" contain any NaNs, then they are considered
7201 * not to be the same.  A NaN is not equal to anything, not even
7202 * to another NaN.
7203 */
7204isl_bool isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1,
7205	__isl_keep isl_pw_aff *pa2)
7206{
7207	isl_bool equal;
7208	isl_bool has_nan;
7209	isl_map *map1, *map2;
7210
7211	if (!pa1 || !pa2)
7212		return isl_bool_error;
7213
7214	equal = isl_pw_aff_plain_is_equal(pa1, pa2);
7215	if (equal < 0 || equal)
7216		return equal;
7217	has_nan = either_involves_nan(pa1, pa2);
7218	if (has_nan < 0)
7219		return isl_bool_error;
7220	if (has_nan)
7221		return isl_bool_false;
7222
7223	map1 = isl_map_from_pw_aff_internal(isl_pw_aff_copy(pa1));
7224	map2 = isl_map_from_pw_aff_internal(isl_pw_aff_copy(pa2));
7225	equal = isl_map_is_equal(map1, map2);
7226	isl_map_free(map1);
7227	isl_map_free(map2);
7228
7229	return equal;
7230}
7231
7232/* Do "mpa1" and "mpa2" represent the same function?
7233 *
7234 * Note that we cannot convert the entire isl_multi_pw_aff
7235 * to a map because the domains of the piecewise affine expressions
7236 * may not be the same.
7237 */
7238isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1,
7239	__isl_keep isl_multi_pw_aff *mpa2)
7240{
7241	int i;
7242	isl_bool equal, equal_params;
7243
7244	if (!mpa1 || !mpa2)
7245		return isl_bool_error;
7246
7247	equal_params = isl_space_has_equal_params(mpa1->space, mpa2->space);
7248	if (equal_params < 0)
7249		return isl_bool_error;
7250	if (!equal_params) {
7251		if (!isl_space_has_named_params(mpa1->space))
7252			return isl_bool_false;
7253		if (!isl_space_has_named_params(mpa2->space))
7254			return isl_bool_false;
7255		mpa1 = isl_multi_pw_aff_copy(mpa1);
7256		mpa2 = isl_multi_pw_aff_copy(mpa2);
7257		mpa1 = isl_multi_pw_aff_align_params(mpa1,
7258					    isl_multi_pw_aff_get_space(mpa2));
7259		mpa2 = isl_multi_pw_aff_align_params(mpa2,
7260					    isl_multi_pw_aff_get_space(mpa1));
7261		equal = isl_multi_pw_aff_is_equal(mpa1, mpa2);
7262		isl_multi_pw_aff_free(mpa1);
7263		isl_multi_pw_aff_free(mpa2);
7264		return equal;
7265	}
7266
7267	equal = isl_space_is_equal(mpa1->space, mpa2->space);
7268	if (equal < 0 || !equal)
7269		return equal;
7270
7271	for (i = 0; i < mpa1->n; ++i) {
7272		equal = isl_pw_aff_is_equal(mpa1->u.p[i], mpa2->u.p[i]);
7273		if (equal < 0 || !equal)
7274			return equal;
7275	}
7276
7277	return isl_bool_true;
7278}
7279
7280/* Do "pma1" and "pma2" represent the same function?
7281 *
7282 * First check if they are obviously equal.
7283 * If not, then convert them to maps and check if those are equal.
7284 *
7285 * If "pa1" or "pa2" contain any NaNs, then they are considered
7286 * not to be the same.  A NaN is not equal to anything, not even
7287 * to another NaN.
7288 */
7289isl_bool isl_pw_multi_aff_is_equal(__isl_keep isl_pw_multi_aff *pma1,
7290	__isl_keep isl_pw_multi_aff *pma2)
7291{
7292	isl_bool equal;
7293	isl_bool has_nan;
7294	isl_map *map1, *map2;
7295
7296	if (!pma1 || !pma2)
7297		return isl_bool_error;
7298
7299	equal = isl_pw_multi_aff_plain_is_equal(pma1, pma2);
7300	if (equal < 0 || equal)
7301		return equal;
7302	has_nan = isl_pw_multi_aff_involves_nan(pma1);
7303	if (has_nan >= 0 && !has_nan)
7304		has_nan = isl_pw_multi_aff_involves_nan(pma2);
7305	if (has_nan < 0 || has_nan)
7306		return isl_bool_not(has_nan);
7307
7308	map1 = isl_map_from_pw_multi_aff_internal(isl_pw_multi_aff_copy(pma1));
7309	map2 = isl_map_from_pw_multi_aff_internal(isl_pw_multi_aff_copy(pma2));
7310	equal = isl_map_is_equal(map1, map2);
7311	isl_map_free(map1);
7312	isl_map_free(map2);
7313
7314	return equal;
7315}
7316
7317#undef BASE
7318#define BASE	multi_aff
7319
7320#include "isl_multi_pw_aff_pullback_templ.c"
7321
7322#undef BASE
7323#define BASE	pw_multi_aff
7324
7325#include "isl_multi_pw_aff_pullback_templ.c"
7326
7327/* Apply "aff" to "mpa".  The range of "mpa" needs to be compatible
7328 * with the domain of "aff".  The domain of the result is the same
7329 * as that of "mpa".
7330 * "mpa" and "aff" are assumed to have been aligned.
7331 *
7332 * We first extract the parametric constant from "aff", defined
7333 * over the correct domain.
7334 * Then we add the appropriate combinations of the members of "mpa".
7335 * Finally, we add the integer divisions through recursive calls.
7336 */
7337static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff_aligned(
7338	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
7339{
7340	int i;
7341	isl_size n_in, n_div, n_mpa_in;
7342	isl_space *space;
7343	isl_val *v;
7344	isl_pw_aff *pa;
7345	isl_aff *tmp;
7346
7347	n_in = isl_aff_dim(aff, isl_dim_in);
7348	n_div = isl_aff_dim(aff, isl_dim_div);
7349	n_mpa_in = isl_multi_pw_aff_dim(mpa, isl_dim_in);
7350	if (n_in < 0 || n_div < 0 || n_mpa_in < 0)
7351		goto error;
7352
7353	space = isl_space_domain(isl_multi_pw_aff_get_space(mpa));
7354	tmp = isl_aff_copy(aff);
7355	tmp = isl_aff_drop_dims(tmp, isl_dim_div, 0, n_div);
7356	tmp = isl_aff_drop_dims(tmp, isl_dim_in, 0, n_in);
7357	tmp = isl_aff_add_dims(tmp, isl_dim_in, n_mpa_in);
7358	tmp = isl_aff_reset_domain_space(tmp, space);
7359	pa = isl_pw_aff_from_aff(tmp);
7360
7361	for (i = 0; i < n_in; ++i) {
7362		isl_pw_aff *pa_i;
7363
7364		if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
7365			continue;
7366		v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
7367		pa_i = isl_multi_pw_aff_get_pw_aff(mpa, i);
7368		pa_i = isl_pw_aff_scale_val(pa_i, v);
7369		pa = isl_pw_aff_add(pa, pa_i);
7370	}
7371
7372	for (i = 0; i < n_div; ++i) {
7373		isl_aff *div;
7374		isl_pw_aff *pa_i;
7375
7376		if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
7377			continue;
7378		div = isl_aff_get_div(aff, i);
7379		pa_i = isl_multi_pw_aff_apply_aff_aligned(
7380					    isl_multi_pw_aff_copy(mpa), div);
7381		pa_i = isl_pw_aff_floor(pa_i);
7382		v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
7383		pa_i = isl_pw_aff_scale_val(pa_i, v);
7384		pa = isl_pw_aff_add(pa, pa_i);
7385	}
7386
7387	isl_multi_pw_aff_free(mpa);
7388	isl_aff_free(aff);
7389
7390	return pa;
7391error:
7392	isl_multi_pw_aff_free(mpa);
7393	isl_aff_free(aff);
7394	return NULL;
7395}
7396
7397/* Apply "aff" to "mpa".  The range of "mpa" needs to be compatible
7398 * with the domain of "aff".  The domain of the result is the same
7399 * as that of "mpa".
7400 */
7401__isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff(
7402	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
7403{
7404	isl_bool equal_params;
7405
7406	if (!aff || !mpa)
7407		goto error;
7408	equal_params = isl_space_has_equal_params(aff->ls->dim, mpa->space);
7409	if (equal_params < 0)
7410		goto error;
7411	if (equal_params)
7412		return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
7413
7414	aff = isl_aff_align_params(aff, isl_multi_pw_aff_get_space(mpa));
7415	mpa = isl_multi_pw_aff_align_params(mpa, isl_aff_get_space(aff));
7416
7417	return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
7418error:
7419	isl_aff_free(aff);
7420	isl_multi_pw_aff_free(mpa);
7421	return NULL;
7422}
7423
7424/* Apply "pa" to "mpa".  The range of "mpa" needs to be compatible
7425 * with the domain of "pa".  The domain of the result is the same
7426 * as that of "mpa".
7427 * "mpa" and "pa" are assumed to have been aligned.
7428 *
7429 * We consider each piece in turn.  Note that the domains of the
7430 * pieces are assumed to be disjoint and they remain disjoint
7431 * after taking the preimage (over the same function).
7432 */
7433static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff_aligned(
7434	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
7435{
7436	isl_space *space;
7437	isl_pw_aff *res;
7438	int i;
7439
7440	if (!mpa || !pa)
7441		goto error;
7442
7443	space = isl_space_join(isl_multi_pw_aff_get_space(mpa),
7444				isl_pw_aff_get_space(pa));
7445	res = isl_pw_aff_empty(space);
7446
7447	for (i = 0; i < pa->n; ++i) {
7448		isl_pw_aff *pa_i;
7449		isl_set *domain;
7450
7451		pa_i = isl_multi_pw_aff_apply_aff_aligned(
7452					isl_multi_pw_aff_copy(mpa),
7453					isl_aff_copy(pa->p[i].aff));
7454		domain = isl_set_copy(pa->p[i].set);
7455		domain = isl_set_preimage_multi_pw_aff(domain,
7456					isl_multi_pw_aff_copy(mpa));
7457		pa_i = isl_pw_aff_intersect_domain(pa_i, domain);
7458		res = isl_pw_aff_add_disjoint(res, pa_i);
7459	}
7460
7461	isl_pw_aff_free(pa);
7462	isl_multi_pw_aff_free(mpa);
7463	return res;
7464error:
7465	isl_pw_aff_free(pa);
7466	isl_multi_pw_aff_free(mpa);
7467	return NULL;
7468}
7469
7470/* Apply "pa" to "mpa".  The range of "mpa" needs to be compatible
7471 * with the domain of "pa".  The domain of the result is the same
7472 * as that of "mpa".
7473 */
7474__isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff(
7475	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
7476{
7477	isl_bool equal_params;
7478
7479	if (!pa || !mpa)
7480		goto error;
7481	equal_params = isl_space_has_equal_params(pa->dim, mpa->space);
7482	if (equal_params < 0)
7483		goto error;
7484	if (equal_params)
7485		return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
7486
7487	pa = isl_pw_aff_align_params(pa, isl_multi_pw_aff_get_space(mpa));
7488	mpa = isl_multi_pw_aff_align_params(mpa, isl_pw_aff_get_space(pa));
7489
7490	return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
7491error:
7492	isl_pw_aff_free(pa);
7493	isl_multi_pw_aff_free(mpa);
7494	return NULL;
7495}
7496
7497/* Compute the pullback of "pa" by the function represented by "mpa".
7498 * In other words, plug in "mpa" in "pa".
7499 *
7500 * The pullback is computed by applying "pa" to "mpa".
7501 */
7502__isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff(
7503	__isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa)
7504{
7505	return isl_multi_pw_aff_apply_pw_aff(mpa, pa);
7506}
7507
7508#undef BASE
7509#define BASE	multi_pw_aff
7510
7511#include "isl_multi_pw_aff_pullback_templ.c"
7512
7513/* Align the parameters of "mpa1" and "mpa2", check that the ranges
7514 * of "mpa1" and "mpa2" live in the same space, construct map space
7515 * between the domain spaces of "mpa1" and "mpa2" and call "order"
7516 * with this map space as extract argument.
7517 */
7518static __isl_give isl_map *isl_multi_pw_aff_order_map(
7519	__isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2,
7520	__isl_give isl_map *(*order)(__isl_keep isl_multi_pw_aff *mpa1,
7521		__isl_keep isl_multi_pw_aff *mpa2, __isl_take isl_space *space))
7522{
7523	int match;
7524	isl_space *space1, *space2;
7525	isl_map *res;
7526
7527	mpa1 = isl_multi_pw_aff_align_params(mpa1,
7528					    isl_multi_pw_aff_get_space(mpa2));
7529	mpa2 = isl_multi_pw_aff_align_params(mpa2,
7530					    isl_multi_pw_aff_get_space(mpa1));
7531	if (!mpa1 || !mpa2)
7532		goto error;
7533	match = isl_space_tuple_is_equal(mpa1->space, isl_dim_out,
7534					mpa2->space, isl_dim_out);
7535	if (match < 0)
7536		goto error;
7537	if (!match)
7538		isl_die(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid,
7539			"range spaces don't match", goto error);
7540	space1 = isl_space_domain(isl_multi_pw_aff_get_space(mpa1));
7541	space2 = isl_space_domain(isl_multi_pw_aff_get_space(mpa2));
7542	space1 = isl_space_map_from_domain_and_range(space1, space2);
7543
7544	res = order(mpa1, mpa2, space1);
7545	isl_multi_pw_aff_free(mpa1);
7546	isl_multi_pw_aff_free(mpa2);
7547	return res;
7548error:
7549	isl_multi_pw_aff_free(mpa1);
7550	isl_multi_pw_aff_free(mpa2);
7551	return NULL;
7552}
7553
7554/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
7555 * where the function values are equal.  "space" is the space of the result.
7556 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
7557 *
7558 * "mpa1" and "mpa2" are equal when each of the pairs of elements
7559 * in the sequences are equal.
7560 */
7561static __isl_give isl_map *isl_multi_pw_aff_eq_map_on_space(
7562	__isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
7563	__isl_take isl_space *space)
7564{
7565	int i;
7566	isl_size n;
7567	isl_map *res;
7568
7569	n = isl_multi_pw_aff_dim(mpa1, isl_dim_out);
7570	if (n < 0)
7571		space = isl_space_free(space);
7572	res = isl_map_universe(space);
7573
7574	for (i = 0; i < n; ++i) {
7575		isl_pw_aff *pa1, *pa2;
7576		isl_map *map;
7577
7578		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
7579		pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
7580		map = isl_pw_aff_eq_map(pa1, pa2);
7581		res = isl_map_intersect(res, map);
7582	}
7583
7584	return res;
7585}
7586
7587/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
7588 * where the function values are equal.
7589 */
7590__isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1,
7591	__isl_take isl_multi_pw_aff *mpa2)
7592{
7593	return isl_multi_pw_aff_order_map(mpa1, mpa2,
7594					    &isl_multi_pw_aff_eq_map_on_space);
7595}
7596
7597/* Intersect "map" with the result of applying "order"
7598 * on two copies of "mpa".
7599 */
7600static __isl_give isl_map *isl_map_order_at_multi_pw_aff(
7601	__isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa,
7602	__isl_give isl_map *(*order)(__isl_take isl_multi_pw_aff *mpa1,
7603		__isl_take isl_multi_pw_aff *mpa2))
7604{
7605	return isl_map_intersect(map, order(mpa, isl_multi_pw_aff_copy(mpa)));
7606}
7607
7608/* Return the subset of "map" where the domain and the range
7609 * have equal "mpa" values.
7610 */
7611__isl_give isl_map *isl_map_eq_at_multi_pw_aff(__isl_take isl_map *map,
7612	__isl_take isl_multi_pw_aff *mpa)
7613{
7614	return isl_map_order_at_multi_pw_aff(map, mpa,
7615						&isl_multi_pw_aff_eq_map);
7616}
7617
7618/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
7619 * where the function values of "mpa1" lexicographically satisfies
7620 * "strict_base"/"base" compared to that of "mpa2".
7621 * "space" is the space of the result.
7622 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
7623 *
7624 * "mpa1" lexicographically satisfies "strict_base"/"base" compared to "mpa2"
7625 * if, for some i, the i-th element of "mpa1" satisfies "strict_base"/"base"
7626 * when compared to the i-th element of "mpa2" while all previous elements are
7627 * pairwise equal.
7628 * In particular, if i corresponds to the final elements
7629 * then they need to satisfy "base", while "strict_base" needs to be satisfied
7630 * for other values of i.
7631 * If "base" is a strict order, then "base" and "strict_base" are the same.
7632 */
7633static __isl_give isl_map *isl_multi_pw_aff_lex_map_on_space(
7634	__isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
7635	__isl_give isl_map *(*strict_base)(__isl_take isl_pw_aff *pa1,
7636		__isl_take isl_pw_aff *pa2),
7637	__isl_give isl_map *(*base)(__isl_take isl_pw_aff *pa1,
7638		__isl_take isl_pw_aff *pa2),
7639	__isl_take isl_space *space)
7640{
7641	int i;
7642	isl_size n;
7643	isl_map *res, *rest;
7644
7645	n = isl_multi_pw_aff_dim(mpa1, isl_dim_out);
7646	if (n < 0)
7647		space = isl_space_free(space);
7648	res = isl_map_empty(isl_space_copy(space));
7649	rest = isl_map_universe(space);
7650
7651	for (i = 0; i < n; ++i) {
7652		int last;
7653		isl_pw_aff *pa1, *pa2;
7654		isl_map *map;
7655
7656		last = i == n - 1;
7657
7658		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
7659		pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
7660		map = last ? base(pa1, pa2) : strict_base(pa1, pa2);
7661		map = isl_map_intersect(map, isl_map_copy(rest));
7662		res = isl_map_union(res, map);
7663
7664		if (last)
7665			continue;
7666
7667		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
7668		pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
7669		map = isl_pw_aff_eq_map(pa1, pa2);
7670		rest = isl_map_intersect(rest, map);
7671	}
7672
7673	isl_map_free(rest);
7674	return res;
7675}
7676
7677#undef ORDER
7678#define ORDER		le
7679#undef STRICT_ORDER
7680#define STRICT_ORDER	lt
7681#include "isl_aff_lex_templ.c"
7682
7683#undef ORDER
7684#define ORDER		lt
7685#undef STRICT_ORDER
7686#define STRICT_ORDER	lt
7687#include "isl_aff_lex_templ.c"
7688
7689#undef ORDER
7690#define ORDER		ge
7691#undef STRICT_ORDER
7692#define STRICT_ORDER	gt
7693#include "isl_aff_lex_templ.c"
7694
7695#undef ORDER
7696#define ORDER		gt
7697#undef STRICT_ORDER
7698#define STRICT_ORDER	gt
7699#include "isl_aff_lex_templ.c"
7700
7701/* Compare two isl_affs.
7702 *
7703 * Return -1 if "aff1" is "smaller" than "aff2", 1 if "aff1" is "greater"
7704 * than "aff2" and 0 if they are equal.
7705 *
7706 * The order is fairly arbitrary.  We do consider expressions that only involve
7707 * earlier dimensions as "smaller".
7708 */
7709int isl_aff_plain_cmp(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
7710{
7711	int cmp;
7712	int last1, last2;
7713
7714	if (aff1 == aff2)
7715		return 0;
7716
7717	if (!aff1)
7718		return -1;
7719	if (!aff2)
7720		return 1;
7721
7722	cmp = isl_local_space_cmp(aff1->ls, aff2->ls);
7723	if (cmp != 0)
7724		return cmp;
7725
7726	last1 = isl_seq_last_non_zero(aff1->v->el + 1, aff1->v->size - 1);
7727	last2 = isl_seq_last_non_zero(aff2->v->el + 1, aff1->v->size - 1);
7728	if (last1 != last2)
7729		return last1 - last2;
7730
7731	return isl_seq_cmp(aff1->v->el, aff2->v->el, aff1->v->size);
7732}
7733
7734/* Compare two isl_pw_affs.
7735 *
7736 * Return -1 if "pa1" is "smaller" than "pa2", 1 if "pa1" is "greater"
7737 * than "pa2" and 0 if they are equal.
7738 *
7739 * The order is fairly arbitrary.  We do consider expressions that only involve
7740 * earlier dimensions as "smaller".
7741 */
7742int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1,
7743	__isl_keep isl_pw_aff *pa2)
7744{
7745	int i;
7746	int cmp;
7747
7748	if (pa1 == pa2)
7749		return 0;
7750
7751	if (!pa1)
7752		return -1;
7753	if (!pa2)
7754		return 1;
7755
7756	cmp = isl_space_cmp(pa1->dim, pa2->dim);
7757	if (cmp != 0)
7758		return cmp;
7759
7760	if (pa1->n != pa2->n)
7761		return pa1->n - pa2->n;
7762
7763	for (i = 0; i < pa1->n; ++i) {
7764		cmp = isl_set_plain_cmp(pa1->p[i].set, pa2->p[i].set);
7765		if (cmp != 0)
7766			return cmp;
7767		cmp = isl_aff_plain_cmp(pa1->p[i].aff, pa2->p[i].aff);
7768		if (cmp != 0)
7769			return cmp;
7770	}
7771
7772	return 0;
7773}
7774
7775/* Return a piecewise affine expression that is equal to "v" on "domain".
7776 */
7777__isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_set *domain,
7778	__isl_take isl_val *v)
7779{
7780	isl_space *space;
7781	isl_local_space *ls;
7782	isl_aff *aff;
7783
7784	space = isl_set_get_space(domain);
7785	ls = isl_local_space_from_space(space);
7786	aff = isl_aff_val_on_domain(ls, v);
7787
7788	return isl_pw_aff_alloc(domain, aff);
7789}
7790
7791/* This function performs the same operation as isl_pw_aff_val_on_domain,
7792 * but is considered as a function on an isl_set when exported.
7793 */
7794__isl_give isl_pw_aff *isl_set_pw_aff_on_domain_val(__isl_take isl_set *domain,
7795	__isl_take isl_val *v)
7796{
7797	return isl_pw_aff_val_on_domain(domain, v);
7798}
7799
7800/* Return a piecewise affine expression that is equal to the parameter
7801 * with identifier "id" on "domain".
7802 */
7803__isl_give isl_pw_aff *isl_pw_aff_param_on_domain_id(
7804	__isl_take isl_set *domain, __isl_take isl_id *id)
7805{
7806	isl_space *space;
7807	isl_aff *aff;
7808
7809	space = isl_set_get_space(domain);
7810	space = isl_space_add_param_id(space, isl_id_copy(id));
7811	domain = isl_set_align_params(domain, isl_space_copy(space));
7812	aff = isl_aff_param_on_domain_space_id(space, id);
7813
7814	return isl_pw_aff_alloc(domain, aff);
7815}
7816
7817/* This function performs the same operation as
7818 * isl_pw_aff_param_on_domain_id,
7819 * but is considered as a function on an isl_set when exported.
7820 */
7821__isl_give isl_pw_aff *isl_set_param_pw_aff_on_domain_id(
7822	__isl_take isl_set *domain, __isl_take isl_id *id)
7823{
7824	return isl_pw_aff_param_on_domain_id(domain, id);
7825}
7826
7827/* Return a multi affine expression that is equal to "mv" on domain
7828 * space "space".
7829 */
7830__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_domain_space(
7831	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
7832{
7833	int i;
7834	isl_size n;
7835	isl_space *space2;
7836	isl_local_space *ls;
7837	isl_multi_aff *ma;
7838
7839	n = isl_multi_val_dim(mv, isl_dim_set);
7840	if (!space || n < 0)
7841		goto error;
7842
7843	space2 = isl_multi_val_get_space(mv);
7844	space2 = isl_space_align_params(space2, isl_space_copy(space));
7845	space = isl_space_align_params(space, isl_space_copy(space2));
7846	space = isl_space_map_from_domain_and_range(space, space2);
7847	ma = isl_multi_aff_alloc(isl_space_copy(space));
7848	ls = isl_local_space_from_space(isl_space_domain(space));
7849	for (i = 0; i < n; ++i) {
7850		isl_val *v;
7851		isl_aff *aff;
7852
7853		v = isl_multi_val_get_val(mv, i);
7854		aff = isl_aff_val_on_domain(isl_local_space_copy(ls), v);
7855		ma = isl_multi_aff_set_aff(ma, i, aff);
7856	}
7857	isl_local_space_free(ls);
7858
7859	isl_multi_val_free(mv);
7860	return ma;
7861error:
7862	isl_space_free(space);
7863	isl_multi_val_free(mv);
7864	return NULL;
7865}
7866
7867/* This is an alternative name for the function above.
7868 */
7869__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space(
7870	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
7871{
7872	return isl_multi_aff_multi_val_on_domain_space(space, mv);
7873}
7874
7875/* This function performs the same operation as
7876 * isl_multi_aff_multi_val_on_domain_space,
7877 * but is considered as a function on an isl_space when exported.
7878 */
7879__isl_give isl_multi_aff *isl_space_multi_aff_on_domain_multi_val(
7880	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
7881{
7882	return isl_multi_aff_multi_val_on_domain_space(space, mv);
7883}
7884
7885/* Return a piecewise multi-affine expression
7886 * that is equal to "mv" on "domain".
7887 */
7888__isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain(
7889	__isl_take isl_set *domain, __isl_take isl_multi_val *mv)
7890{
7891	isl_space *space;
7892	isl_multi_aff *ma;
7893
7894	space = isl_set_get_space(domain);
7895	ma = isl_multi_aff_multi_val_on_space(space, mv);
7896
7897	return isl_pw_multi_aff_alloc(domain, ma);
7898}
7899
7900/* This function performs the same operation as
7901 * isl_pw_multi_aff_multi_val_on_domain,
7902 * but is considered as a function on an isl_set when exported.
7903 */
7904__isl_give isl_pw_multi_aff *isl_set_pw_multi_aff_on_domain_multi_val(
7905	__isl_take isl_set *domain, __isl_take isl_multi_val *mv)
7906{
7907	return isl_pw_multi_aff_multi_val_on_domain(domain, mv);
7908}
7909
7910/* Internal data structure for isl_union_pw_multi_aff_multi_val_on_domain.
7911 * mv is the value that should be attained on each domain set
7912 * res collects the results
7913 */
7914struct isl_union_pw_multi_aff_multi_val_on_domain_data {
7915	isl_multi_val *mv;
7916	isl_union_pw_multi_aff *res;
7917};
7918
7919/* Create an isl_pw_multi_aff equal to data->mv on "domain"
7920 * and add it to data->res.
7921 */
7922static isl_stat pw_multi_aff_multi_val_on_domain(__isl_take isl_set *domain,
7923	void *user)
7924{
7925	struct isl_union_pw_multi_aff_multi_val_on_domain_data *data = user;
7926	isl_pw_multi_aff *pma;
7927	isl_multi_val *mv;
7928
7929	mv = isl_multi_val_copy(data->mv);
7930	pma = isl_pw_multi_aff_multi_val_on_domain(domain, mv);
7931	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
7932
7933	return data->res ? isl_stat_ok : isl_stat_error;
7934}
7935
7936/* Return a union piecewise multi-affine expression
7937 * that is equal to "mv" on "domain".
7938 */
7939__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_multi_val_on_domain(
7940	__isl_take isl_union_set *domain, __isl_take isl_multi_val *mv)
7941{
7942	struct isl_union_pw_multi_aff_multi_val_on_domain_data data;
7943	isl_space *space;
7944
7945	space = isl_union_set_get_space(domain);
7946	data.res = isl_union_pw_multi_aff_empty(space);
7947	data.mv = mv;
7948	if (isl_union_set_foreach_set(domain,
7949			&pw_multi_aff_multi_val_on_domain, &data) < 0)
7950		data.res = isl_union_pw_multi_aff_free(data.res);
7951	isl_union_set_free(domain);
7952	isl_multi_val_free(mv);
7953	return data.res;
7954}
7955
7956/* Compute the pullback of data->pma by the function represented by "pma2",
7957 * provided the spaces match, and add the results to data->res.
7958 */
7959static isl_stat pullback_entry(__isl_take isl_pw_multi_aff *pma2, void *user)
7960{
7961	struct isl_union_pw_multi_aff_bin_data *data = user;
7962
7963	if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in,
7964				 pma2->dim, isl_dim_out)) {
7965		isl_pw_multi_aff_free(pma2);
7966		return isl_stat_ok;
7967	}
7968
7969	pma2 = isl_pw_multi_aff_pullback_pw_multi_aff(
7970					isl_pw_multi_aff_copy(data->pma), pma2);
7971
7972	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
7973	if (!data->res)
7974		return isl_stat_error;
7975
7976	return isl_stat_ok;
7977}
7978
7979/* Compute the pullback of "upma1" by the function represented by "upma2".
7980 */
7981__isl_give isl_union_pw_multi_aff *
7982isl_union_pw_multi_aff_pullback_union_pw_multi_aff(
7983	__isl_take isl_union_pw_multi_aff *upma1,
7984	__isl_take isl_union_pw_multi_aff *upma2)
7985{
7986	return bin_op(upma1, upma2, &pullback_entry);
7987}
7988
7989/* Apply "upma2" to "upma1".
7990 *
7991 * That is, compute the pullback of "upma2" by "upma1".
7992 */
7993__isl_give isl_union_pw_multi_aff *
7994isl_union_pw_multi_aff_apply_union_pw_multi_aff(
7995	__isl_take isl_union_pw_multi_aff *upma1,
7996	__isl_take isl_union_pw_multi_aff *upma2)
7997{
7998	return isl_union_pw_multi_aff_pullback_union_pw_multi_aff(upma2, upma1);
7999}
8000
8001#undef BASE
8002#define BASE pw_multi_aff
8003static
8004#include "isl_copy_tuple_id_templ.c"
8005
8006/* Given a function "pma1" of the form A[B -> C] -> D and
8007 * a function "pma2" of the form E -> B,
8008 * replace the domain of the wrapped relation inside the domain of "pma1"
8009 * by the preimage with respect to "pma2".
8010 * In other words, plug in "pma2" in this nested domain.
8011 * The result is of the form A[E -> C] -> D.
8012 *
8013 * In particular, extend E -> B to A[E -> C] -> A[B -> C] and
8014 * plug that into "pma1".
8015 */
8016__isl_give isl_pw_multi_aff *
8017isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(
8018	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
8019{
8020	isl_space *pma1_space, *pma2_space;
8021	isl_space *space;
8022	isl_pw_multi_aff *id;
8023
8024	pma1_space = isl_pw_multi_aff_peek_space(pma1);
8025	pma2_space = isl_pw_multi_aff_peek_space(pma2);
8026
8027	if (isl_space_check_domain_is_wrapping(pma1_space) < 0)
8028		goto error;
8029	if (isl_space_check_wrapped_tuple_is_equal(pma1_space,
8030			isl_dim_in, isl_dim_in, pma2_space, isl_dim_out) < 0)
8031		goto error;
8032
8033	space = isl_space_domain(isl_space_copy(pma1_space));
8034	space = isl_space_range(isl_space_unwrap(space));
8035	id = isl_pw_multi_aff_identity_on_domain_space(space);
8036	pma2 = isl_pw_multi_aff_product(pma2, id);
8037
8038	pma2 = isl_pw_multi_aff_copy_tuple_id(pma2, isl_dim_in,
8039						pma1_space, isl_dim_in);
8040	pma2 = isl_pw_multi_aff_copy_tuple_id(pma2, isl_dim_out,
8041						pma1_space, isl_dim_in);
8042
8043	return isl_pw_multi_aff_pullback_pw_multi_aff(pma1, pma2);
8044error:
8045	isl_pw_multi_aff_free(pma1);
8046	isl_pw_multi_aff_free(pma2);
8047	return NULL;
8048}
8049
8050/* If data->pma and "pma2" are such that
8051 * data->pma is of the form A[B -> C] -> D and
8052 * "pma2" is of the form E -> B,
8053 * then replace the domain of the wrapped relation
8054 * inside the domain of data->pma by the preimage with respect to "pma2" and
8055 * add the result to data->res.
8056 */
8057static isl_stat preimage_domain_wrapped_domain_entry(
8058	__isl_take isl_pw_multi_aff *pma2, void *user)
8059{
8060	struct isl_union_pw_multi_aff_bin_data *data = user;
8061	isl_space *pma1_space, *pma2_space;
8062	isl_bool match;
8063
8064	pma1_space = isl_pw_multi_aff_peek_space(data->pma);
8065	pma2_space = isl_pw_multi_aff_peek_space(pma2);
8066
8067	match = isl_space_domain_is_wrapping(pma1_space);
8068	if (match >= 0 && match)
8069		match = isl_space_wrapped_tuple_is_equal(pma1_space, isl_dim_in,
8070					isl_dim_in, pma2_space, isl_dim_out);
8071	if (match < 0 || !match) {
8072		isl_pw_multi_aff_free(pma2);
8073		return match < 0 ? isl_stat_error : isl_stat_ok;
8074	}
8075
8076	pma2 = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(
8077		isl_pw_multi_aff_copy(data->pma), pma2);
8078
8079	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
8080
8081	return isl_stat_non_null(data->res);
8082}
8083
8084/* For each pair of functions A[B -> C] -> D in "upma1" and
8085 * E -> B in "upma2",
8086 * replace the domain of the wrapped relation inside the domain of the first
8087 * by the preimage with respect to the second and collect the results.
8088 * In other words, plug in the second function in this nested domain.
8089 * The results are of the form A[E -> C] -> D.
8090 */
8091__isl_give isl_union_pw_multi_aff *
8092isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(
8093	__isl_take isl_union_pw_multi_aff *upma1,
8094	__isl_take isl_union_pw_multi_aff *upma2)
8095{
8096	return bin_op(upma1, upma2, &preimage_domain_wrapped_domain_entry);
8097}
8098
8099/* Check that the domain space of "upa" matches "space".
8100 *
8101 * This function is called from isl_multi_union_pw_aff_set_union_pw_aff and
8102 * can in principle never fail since the space "space" is that
8103 * of the isl_multi_union_pw_aff and is a set space such that
8104 * there is no domain space to match.
8105 *
8106 * We check the parameters and double-check that "space" is
8107 * indeed that of a set.
8108 */
8109static isl_stat isl_union_pw_aff_check_match_domain_space(
8110	__isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space)
8111{
8112	isl_space *upa_space;
8113	isl_bool match;
8114
8115	if (!upa || !space)
8116		return isl_stat_error;
8117
8118	match = isl_space_is_set(space);
8119	if (match < 0)
8120		return isl_stat_error;
8121	if (!match)
8122		isl_die(isl_space_get_ctx(space), isl_error_invalid,
8123			"expecting set space", return isl_stat_error);
8124
8125	upa_space = isl_union_pw_aff_get_space(upa);
8126	match = isl_space_has_equal_params(space, upa_space);
8127	if (match < 0)
8128		goto error;
8129	if (!match)
8130		isl_die(isl_space_get_ctx(space), isl_error_invalid,
8131			"parameters don't match", goto error);
8132
8133	isl_space_free(upa_space);
8134	return isl_stat_ok;
8135error:
8136	isl_space_free(upa_space);
8137	return isl_stat_error;
8138}
8139
8140/* Do the parameters of "upa" match those of "space"?
8141 */
8142static isl_bool isl_union_pw_aff_matching_params(
8143	__isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space)
8144{
8145	isl_space *upa_space;
8146	isl_bool match;
8147
8148	if (!upa || !space)
8149		return isl_bool_error;
8150
8151	upa_space = isl_union_pw_aff_get_space(upa);
8152
8153	match = isl_space_has_equal_params(space, upa_space);
8154
8155	isl_space_free(upa_space);
8156	return match;
8157}
8158
8159/* Internal data structure for isl_union_pw_aff_reset_domain_space.
8160 * space represents the new parameters.
8161 * res collects the results.
8162 */
8163struct isl_union_pw_aff_reset_params_data {
8164	isl_space *space;
8165	isl_union_pw_aff *res;
8166};
8167
8168/* Replace the parameters of "pa" by data->space and
8169 * add the result to data->res.
8170 */
8171static isl_stat reset_params(__isl_take isl_pw_aff *pa, void *user)
8172{
8173	struct isl_union_pw_aff_reset_params_data *data = user;
8174	isl_space *space;
8175
8176	space = isl_pw_aff_get_space(pa);
8177	space = isl_space_replace_params(space, data->space);
8178	pa = isl_pw_aff_reset_space(pa, space);
8179	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
8180
8181	return data->res ? isl_stat_ok : isl_stat_error;
8182}
8183
8184/* Replace the domain space of "upa" by "space".
8185 * Since a union expression does not have a (single) domain space,
8186 * "space" is necessarily a parameter space.
8187 *
8188 * Since the order and the names of the parameters determine
8189 * the hash value, we need to create a new hash table.
8190 */
8191static __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_domain_space(
8192	__isl_take isl_union_pw_aff *upa, __isl_take isl_space *space)
8193{
8194	struct isl_union_pw_aff_reset_params_data data = { space };
8195	isl_bool match;
8196
8197	match = isl_union_pw_aff_matching_params(upa, space);
8198	if (match < 0)
8199		upa = isl_union_pw_aff_free(upa);
8200	else if (match) {
8201		isl_space_free(space);
8202		return upa;
8203	}
8204
8205	data.res = isl_union_pw_aff_empty(isl_space_copy(space));
8206	if (isl_union_pw_aff_foreach_pw_aff(upa, &reset_params, &data) < 0)
8207		data.res = isl_union_pw_aff_free(data.res);
8208
8209	isl_union_pw_aff_free(upa);
8210	isl_space_free(space);
8211	return data.res;
8212}
8213
8214/* Return the floor of "pa".
8215 */
8216static __isl_give isl_pw_aff *floor_entry(__isl_take isl_pw_aff *pa, void *user)
8217{
8218	return isl_pw_aff_floor(pa);
8219}
8220
8221/* Given f, return floor(f).
8222 */
8223__isl_give isl_union_pw_aff *isl_union_pw_aff_floor(
8224	__isl_take isl_union_pw_aff *upa)
8225{
8226	return isl_union_pw_aff_transform_inplace(upa, &floor_entry, NULL);
8227}
8228
8229/* Compute
8230 *
8231 *	upa mod m = upa - m * floor(upa/m)
8232 *
8233 * with m an integer value.
8234 */
8235__isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val(
8236	__isl_take isl_union_pw_aff *upa, __isl_take isl_val *m)
8237{
8238	isl_union_pw_aff *res;
8239
8240	if (!upa || !m)
8241		goto error;
8242
8243	if (!isl_val_is_int(m))
8244		isl_die(isl_val_get_ctx(m), isl_error_invalid,
8245			"expecting integer modulo", goto error);
8246	if (!isl_val_is_pos(m))
8247		isl_die(isl_val_get_ctx(m), isl_error_invalid,
8248			"expecting positive modulo", goto error);
8249
8250	res = isl_union_pw_aff_copy(upa);
8251	upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(m));
8252	upa = isl_union_pw_aff_floor(upa);
8253	upa = isl_union_pw_aff_scale_val(upa, m);
8254	res = isl_union_pw_aff_sub(res, upa);
8255
8256	return res;
8257error:
8258	isl_val_free(m);
8259	isl_union_pw_aff_free(upa);
8260	return NULL;
8261}
8262
8263/* Internal data structure for isl_union_pw_multi_aff_get_union_pw_aff.
8264 * pos is the output position that needs to be extracted.
8265 * res collects the results.
8266 */
8267struct isl_union_pw_multi_aff_get_union_pw_aff_data {
8268	int pos;
8269	isl_union_pw_aff *res;
8270};
8271
8272/* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma"
8273 * (assuming it has such a dimension) and add it to data->res.
8274 */
8275static isl_stat get_union_pw_aff(__isl_take isl_pw_multi_aff *pma, void *user)
8276{
8277	struct isl_union_pw_multi_aff_get_union_pw_aff_data *data = user;
8278	isl_size n_out;
8279	isl_pw_aff *pa;
8280
8281	n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
8282	if (n_out < 0)
8283		return isl_stat_error;
8284	if (data->pos >= n_out) {
8285		isl_pw_multi_aff_free(pma);
8286		return isl_stat_ok;
8287	}
8288
8289	pa = isl_pw_multi_aff_get_pw_aff(pma, data->pos);
8290	isl_pw_multi_aff_free(pma);
8291
8292	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
8293
8294	return data->res ? isl_stat_ok : isl_stat_error;
8295}
8296
8297/* Extract an isl_union_pw_aff corresponding to
8298 * output dimension "pos" of "upma".
8299 */
8300__isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff(
8301	__isl_keep isl_union_pw_multi_aff *upma, int pos)
8302{
8303	struct isl_union_pw_multi_aff_get_union_pw_aff_data data;
8304	isl_space *space;
8305
8306	if (!upma)
8307		return NULL;
8308
8309	if (pos < 0)
8310		isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid,
8311			"cannot extract at negative position", return NULL);
8312
8313	space = isl_union_pw_multi_aff_get_space(upma);
8314	data.res = isl_union_pw_aff_empty(space);
8315	data.pos = pos;
8316	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
8317						&get_union_pw_aff, &data) < 0)
8318		data.res = isl_union_pw_aff_free(data.res);
8319
8320	return data.res;
8321}
8322
8323/* Return a union piecewise affine expression
8324 * that is equal to "aff" on "domain".
8325 */
8326__isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain(
8327	__isl_take isl_union_set *domain, __isl_take isl_aff *aff)
8328{
8329	isl_pw_aff *pa;
8330
8331	pa = isl_pw_aff_from_aff(aff);
8332	return isl_union_pw_aff_pw_aff_on_domain(domain, pa);
8333}
8334
8335/* Return a union piecewise affine expression
8336 * that is equal to the parameter identified by "id" on "domain".
8337 *
8338 * Make sure the parameter appears in the space passed to
8339 * isl_aff_param_on_domain_space_id.
8340 */
8341__isl_give isl_union_pw_aff *isl_union_pw_aff_param_on_domain_id(
8342	__isl_take isl_union_set *domain, __isl_take isl_id *id)
8343{
8344	isl_space *space;
8345	isl_aff *aff;
8346
8347	space = isl_union_set_get_space(domain);
8348	space = isl_space_add_param_id(space, isl_id_copy(id));
8349	aff = isl_aff_param_on_domain_space_id(space, id);
8350	return isl_union_pw_aff_aff_on_domain(domain, aff);
8351}
8352
8353/* Internal data structure for isl_union_pw_aff_pw_aff_on_domain.
8354 * "pa" is the piecewise symbolic value that the resulting isl_union_pw_aff
8355 * needs to attain.
8356 * "res" collects the results.
8357 */
8358struct isl_union_pw_aff_pw_aff_on_domain_data {
8359	isl_pw_aff *pa;
8360	isl_union_pw_aff *res;
8361};
8362
8363/* Construct a piecewise affine expression that is equal to data->pa
8364 * on "domain" and add the result to data->res.
8365 */
8366static isl_stat pw_aff_on_domain(__isl_take isl_set *domain, void *user)
8367{
8368	struct isl_union_pw_aff_pw_aff_on_domain_data *data = user;
8369	isl_pw_aff *pa;
8370	isl_size dim;
8371
8372	pa = isl_pw_aff_copy(data->pa);
8373	dim = isl_set_dim(domain, isl_dim_set);
8374	if (dim < 0)
8375		pa = isl_pw_aff_free(pa);
8376	pa = isl_pw_aff_from_range(pa);
8377	pa = isl_pw_aff_add_dims(pa, isl_dim_in, dim);
8378	pa = isl_pw_aff_reset_domain_space(pa, isl_set_get_space(domain));
8379	pa = isl_pw_aff_intersect_domain(pa, domain);
8380	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
8381
8382	return data->res ? isl_stat_ok : isl_stat_error;
8383}
8384
8385/* Return a union piecewise affine expression
8386 * that is equal to "pa" on "domain", assuming "domain" and "pa"
8387 * have been aligned.
8388 *
8389 * Construct an isl_pw_aff on each of the sets in "domain" and
8390 * collect the results.
8391 */
8392static __isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain_aligned(
8393	__isl_take isl_union_set *domain, __isl_take isl_pw_aff *pa)
8394{
8395	struct isl_union_pw_aff_pw_aff_on_domain_data data;
8396	isl_space *space;
8397
8398	space = isl_union_set_get_space(domain);
8399	data.res = isl_union_pw_aff_empty(space);
8400	data.pa = pa;
8401	if (isl_union_set_foreach_set(domain, &pw_aff_on_domain, &data) < 0)
8402		data.res = isl_union_pw_aff_free(data.res);
8403	isl_union_set_free(domain);
8404	isl_pw_aff_free(pa);
8405	return data.res;
8406}
8407
8408/* Return a union piecewise affine expression
8409 * that is equal to "pa" on "domain".
8410 *
8411 * Check that "pa" is a parametric expression,
8412 * align the parameters if needed and call
8413 * isl_union_pw_aff_pw_aff_on_domain_aligned.
8414 */
8415__isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain(
8416	__isl_take isl_union_set *domain, __isl_take isl_pw_aff *pa)
8417{
8418	isl_bool is_set;
8419	isl_bool equal_params;
8420	isl_space *domain_space, *pa_space;
8421
8422	pa_space = isl_pw_aff_peek_space(pa);
8423	is_set = isl_space_is_set(pa_space);
8424	if (is_set < 0)
8425		goto error;
8426	if (!is_set)
8427		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
8428			"expecting parametric expression", goto error);
8429
8430	domain_space = isl_union_set_get_space(domain);
8431	pa_space = isl_pw_aff_get_space(pa);
8432	equal_params = isl_space_has_equal_params(domain_space, pa_space);
8433	if (equal_params >= 0 && !equal_params) {
8434		isl_space *space;
8435
8436		space = isl_space_align_params(domain_space, pa_space);
8437		pa = isl_pw_aff_align_params(pa, isl_space_copy(space));
8438		domain = isl_union_set_align_params(domain, space);
8439	} else {
8440		isl_space_free(domain_space);
8441		isl_space_free(pa_space);
8442	}
8443
8444	if (equal_params < 0)
8445		goto error;
8446	return isl_union_pw_aff_pw_aff_on_domain_aligned(domain, pa);
8447error:
8448	isl_union_set_free(domain);
8449	isl_pw_aff_free(pa);
8450	return NULL;
8451}
8452
8453/* Internal data structure for isl_union_pw_aff_val_on_domain.
8454 * "v" is the value that the resulting isl_union_pw_aff needs to attain.
8455 * "res" collects the results.
8456 */
8457struct isl_union_pw_aff_val_on_domain_data {
8458	isl_val *v;
8459	isl_union_pw_aff *res;
8460};
8461
8462/* Construct a piecewise affine expression that is equal to data->v
8463 * on "domain" and add the result to data->res.
8464 */
8465static isl_stat pw_aff_val_on_domain(__isl_take isl_set *domain, void *user)
8466{
8467	struct isl_union_pw_aff_val_on_domain_data *data = user;
8468	isl_pw_aff *pa;
8469	isl_val *v;
8470
8471	v = isl_val_copy(data->v);
8472	pa = isl_pw_aff_val_on_domain(domain, v);
8473	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
8474
8475	return data->res ? isl_stat_ok : isl_stat_error;
8476}
8477
8478/* Return a union piecewise affine expression
8479 * that is equal to "v" on "domain".
8480 *
8481 * Construct an isl_pw_aff on each of the sets in "domain" and
8482 * collect the results.
8483 */
8484__isl_give isl_union_pw_aff *isl_union_pw_aff_val_on_domain(
8485	__isl_take isl_union_set *domain, __isl_take isl_val *v)
8486{
8487	struct isl_union_pw_aff_val_on_domain_data data;
8488	isl_space *space;
8489
8490	space = isl_union_set_get_space(domain);
8491	data.res = isl_union_pw_aff_empty(space);
8492	data.v = v;
8493	if (isl_union_set_foreach_set(domain, &pw_aff_val_on_domain, &data) < 0)
8494		data.res = isl_union_pw_aff_free(data.res);
8495	isl_union_set_free(domain);
8496	isl_val_free(v);
8497	return data.res;
8498}
8499
8500/* Construct a piecewise multi affine expression
8501 * that is equal to "pa" and add it to upma.
8502 */
8503static isl_stat pw_multi_aff_from_pw_aff_entry(__isl_take isl_pw_aff *pa,
8504	void *user)
8505{
8506	isl_union_pw_multi_aff **upma = user;
8507	isl_pw_multi_aff *pma;
8508
8509	pma = isl_pw_multi_aff_from_pw_aff(pa);
8510	*upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
8511
8512	return *upma ? isl_stat_ok : isl_stat_error;
8513}
8514
8515/* Construct and return a union piecewise multi affine expression
8516 * that is equal to the given union piecewise affine expression.
8517 */
8518__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff(
8519	__isl_take isl_union_pw_aff *upa)
8520{
8521	isl_space *space;
8522	isl_union_pw_multi_aff *upma;
8523
8524	if (!upa)
8525		return NULL;
8526
8527	space = isl_union_pw_aff_get_space(upa);
8528	upma = isl_union_pw_multi_aff_empty(space);
8529
8530	if (isl_union_pw_aff_foreach_pw_aff(upa,
8531				&pw_multi_aff_from_pw_aff_entry, &upma) < 0)
8532		upma = isl_union_pw_multi_aff_free(upma);
8533
8534	isl_union_pw_aff_free(upa);
8535	return upma;
8536}
8537
8538/* Compute the set of elements in the domain of "pa" where it is zero and
8539 * add this set to "uset".
8540 */
8541static isl_stat zero_union_set(__isl_take isl_pw_aff *pa, void *user)
8542{
8543	isl_union_set **uset = (isl_union_set **)user;
8544
8545	*uset = isl_union_set_add_set(*uset, isl_pw_aff_zero_set(pa));
8546
8547	return *uset ? isl_stat_ok : isl_stat_error;
8548}
8549
8550/* Return a union set containing those elements in the domain
8551 * of "upa" where it is zero.
8552 */
8553__isl_give isl_union_set *isl_union_pw_aff_zero_union_set(
8554	__isl_take isl_union_pw_aff *upa)
8555{
8556	isl_union_set *zero;
8557
8558	zero = isl_union_set_empty(isl_union_pw_aff_get_space(upa));
8559	if (isl_union_pw_aff_foreach_pw_aff(upa, &zero_union_set, &zero) < 0)
8560		zero = isl_union_set_free(zero);
8561
8562	isl_union_pw_aff_free(upa);
8563	return zero;
8564}
8565
8566/* Internal data structure for isl_union_pw_aff_bind_id,
8567 * storing the parameter that needs to be bound and
8568 * the accumulated results.
8569 */
8570struct isl_bind_id_data {
8571	isl_id *id;
8572	isl_union_set *bound;
8573};
8574
8575/* Bind the piecewise affine function "pa" to the parameter data->id,
8576 * adding the resulting elements in the domain where the expression
8577 * is equal to the parameter to data->bound.
8578 */
8579static isl_stat bind_id(__isl_take isl_pw_aff *pa, void *user)
8580{
8581	struct isl_bind_id_data *data = user;
8582	isl_set *bound;
8583
8584	bound = isl_pw_aff_bind_id(pa, isl_id_copy(data->id));
8585	data->bound = isl_union_set_add_set(data->bound, bound);
8586
8587	return data->bound ? isl_stat_ok : isl_stat_error;
8588}
8589
8590/* Bind the union piecewise affine function "upa" to the parameter "id",
8591 * returning the elements in the domain where the expression
8592 * is equal to the parameter.
8593 */
8594__isl_give isl_union_set *isl_union_pw_aff_bind_id(
8595	__isl_take isl_union_pw_aff *upa, __isl_take isl_id *id)
8596{
8597	struct isl_bind_id_data data = { id };
8598
8599	data.bound = isl_union_set_empty(isl_union_pw_aff_get_space(upa));
8600	if (isl_union_pw_aff_foreach_pw_aff(upa, &bind_id, &data) < 0)
8601		data.bound = isl_union_set_free(data.bound);
8602
8603	isl_union_pw_aff_free(upa);
8604	isl_id_free(id);
8605	return data.bound;
8606}
8607
8608/* Internal data structure for isl_union_pw_aff_pullback_union_pw_multi_aff.
8609 * upma is the function that is plugged in.
8610 * pa is the current part of the function in which upma is plugged in.
8611 * res collects the results.
8612 */
8613struct isl_union_pw_aff_pullback_upma_data {
8614	isl_union_pw_multi_aff *upma;
8615	isl_pw_aff *pa;
8616	isl_union_pw_aff *res;
8617};
8618
8619/* Check if "pma" can be plugged into data->pa.
8620 * If so, perform the pullback and add the result to data->res.
8621 */
8622static isl_stat pa_pb_pma(__isl_take isl_pw_multi_aff *pma, void *user)
8623{
8624	struct isl_union_pw_aff_pullback_upma_data *data = user;
8625	isl_pw_aff *pa;
8626
8627	if (!isl_space_tuple_is_equal(data->pa->dim, isl_dim_in,
8628				 pma->dim, isl_dim_out)) {
8629		isl_pw_multi_aff_free(pma);
8630		return isl_stat_ok;
8631	}
8632
8633	pa = isl_pw_aff_copy(data->pa);
8634	pa = isl_pw_aff_pullback_pw_multi_aff(pa, pma);
8635
8636	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
8637
8638	return data->res ? isl_stat_ok : isl_stat_error;
8639}
8640
8641/* Check if any of the elements of data->upma can be plugged into pa,
8642 * add if so add the result to data->res.
8643 */
8644static isl_stat upa_pb_upma(__isl_take isl_pw_aff *pa, void *user)
8645{
8646	struct isl_union_pw_aff_pullback_upma_data *data = user;
8647	isl_stat r;
8648
8649	data->pa = pa;
8650	r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma,
8651				   &pa_pb_pma, data);
8652	isl_pw_aff_free(pa);
8653
8654	return r;
8655}
8656
8657/* Compute the pullback of "upa" by the function represented by "upma".
8658 * In other words, plug in "upma" in "upa".  The result contains
8659 * expressions defined over the domain space of "upma".
8660 *
8661 * Run over all pairs of elements in "upa" and "upma", perform
8662 * the pullback when appropriate and collect the results.
8663 * If the hash value were based on the domain space rather than
8664 * the function space, then we could run through all elements
8665 * of "upma" and directly pick out the corresponding element of "upa".
8666 */
8667__isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff(
8668	__isl_take isl_union_pw_aff *upa,
8669	__isl_take isl_union_pw_multi_aff *upma)
8670{
8671	struct isl_union_pw_aff_pullback_upma_data data = { NULL, NULL };
8672	isl_space *space;
8673
8674	space = isl_union_pw_multi_aff_get_space(upma);
8675	upa = isl_union_pw_aff_align_params(upa, space);
8676	space = isl_union_pw_aff_get_space(upa);
8677	upma = isl_union_pw_multi_aff_align_params(upma, space);
8678
8679	if (!upa || !upma)
8680		goto error;
8681
8682	data.upma = upma;
8683	data.res = isl_union_pw_aff_alloc_same_size(upa);
8684	if (isl_union_pw_aff_foreach_pw_aff(upa, &upa_pb_upma, &data) < 0)
8685		data.res = isl_union_pw_aff_free(data.res);
8686
8687	isl_union_pw_aff_free(upa);
8688	isl_union_pw_multi_aff_free(upma);
8689	return data.res;
8690error:
8691	isl_union_pw_aff_free(upa);
8692	isl_union_pw_multi_aff_free(upma);
8693	return NULL;
8694}
8695
8696#undef BASE
8697#define BASE union_pw_aff
8698#undef DOMBASE
8699#define DOMBASE union_set
8700
8701#include <isl_multi_explicit_domain.c>
8702#include <isl_multi_union_pw_aff_explicit_domain.c>
8703#include <isl_multi_templ.c>
8704#include <isl_multi_un_op_templ.c>
8705#include <isl_multi_bin_val_templ.c>
8706#include <isl_multi_align_set.c>
8707#include <isl_multi_align_union_set.c>
8708#include <isl_multi_apply_set_explicit_domain_templ.c>
8709#include <isl_multi_apply_union_set_explicit_domain_templ.c>
8710#include <isl_multi_arith_templ.c>
8711#include <isl_multi_bind_templ.c>
8712#include <isl_multi_coalesce.c>
8713#include <isl_multi_dim_id_templ.c>
8714#include <isl_multi_floor.c>
8715#include <isl_multi_from_base_templ.c>
8716#include <isl_multi_check_domain_templ.c>
8717#include <isl_multi_gist.c>
8718#include <isl_multi_intersect.c>
8719#include <isl_multi_nan_templ.c>
8720#include <isl_multi_tuple_id_templ.c>
8721#include <isl_multi_union_add_templ.c>
8722#include <isl_multi_zero_space_templ.c>
8723
8724/* Does "mupa" have a non-trivial explicit domain?
8725 *
8726 * The explicit domain, if present, is trivial if it represents
8727 * an (obviously) universe parameter set.
8728 */
8729isl_bool isl_multi_union_pw_aff_has_non_trivial_domain(
8730	__isl_keep isl_multi_union_pw_aff *mupa)
8731{
8732	isl_bool is_params, trivial;
8733	isl_set *set;
8734
8735	if (!mupa)
8736		return isl_bool_error;
8737	if (!isl_multi_union_pw_aff_has_explicit_domain(mupa))
8738		return isl_bool_false;
8739	is_params = isl_union_set_is_params(mupa->u.dom);
8740	if (is_params < 0 || !is_params)
8741		return isl_bool_not(is_params);
8742	set = isl_set_from_union_set(isl_union_set_copy(mupa->u.dom));
8743	trivial = isl_set_plain_is_universe(set);
8744	isl_set_free(set);
8745	return isl_bool_not(trivial);
8746}
8747
8748/* Construct a multiple union piecewise affine expression
8749 * in the given space with value zero in each of the output dimensions.
8750 *
8751 * Since there is no canonical zero value for
8752 * a union piecewise affine expression, we can only construct
8753 * a zero-dimensional "zero" value.
8754 */
8755__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_zero(
8756	__isl_take isl_space *space)
8757{
8758	isl_bool params;
8759	isl_size dim;
8760
8761	if (!space)
8762		return NULL;
8763
8764	params = isl_space_is_params(space);
8765	if (params < 0)
8766		goto error;
8767	if (params)
8768		isl_die(isl_space_get_ctx(space), isl_error_invalid,
8769			"expecting proper set space", goto error);
8770	if (!isl_space_is_set(space))
8771		isl_die(isl_space_get_ctx(space), isl_error_invalid,
8772			"expecting set space", goto error);
8773	dim = isl_space_dim(space, isl_dim_out);
8774	if (dim < 0)
8775		goto error;
8776	if (dim != 0)
8777		isl_die(isl_space_get_ctx(space), isl_error_invalid,
8778			"expecting 0D space", goto error);
8779
8780	return isl_multi_union_pw_aff_alloc(space);
8781error:
8782	isl_space_free(space);
8783	return NULL;
8784}
8785
8786/* Construct and return a multi union piecewise affine expression
8787 * that is equal to the given multi affine expression.
8788 */
8789__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff(
8790	__isl_take isl_multi_aff *ma)
8791{
8792	isl_multi_pw_aff *mpa;
8793
8794	mpa = isl_multi_pw_aff_from_multi_aff(ma);
8795	return isl_multi_union_pw_aff_from_multi_pw_aff(mpa);
8796}
8797
8798/* This function performs the same operation as
8799 * isl_multi_union_pw_aff_from_multi_aff, but is considered as a function on an
8800 * isl_multi_aff when exported.
8801 */
8802__isl_give isl_multi_union_pw_aff *isl_multi_aff_to_multi_union_pw_aff(
8803        __isl_take isl_multi_aff *ma)
8804{
8805        return isl_multi_union_pw_aff_from_multi_aff(ma);
8806}
8807
8808/* Construct and return a multi union piecewise affine expression
8809 * that is equal to the given multi piecewise affine expression.
8810 *
8811 * If the resulting multi union piecewise affine expression has
8812 * an explicit domain, then assign it the domain of the input.
8813 * In other cases, the domain is stored in the individual elements.
8814 */
8815__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff(
8816	__isl_take isl_multi_pw_aff *mpa)
8817{
8818	int i;
8819	isl_size n;
8820	isl_space *space;
8821	isl_multi_union_pw_aff *mupa;
8822
8823	n = isl_multi_pw_aff_dim(mpa, isl_dim_out);
8824	if (n < 0)
8825		mpa = isl_multi_pw_aff_free(mpa);
8826	if (!mpa)
8827		return NULL;
8828
8829	space = isl_multi_pw_aff_get_space(mpa);
8830	space = isl_space_range(space);
8831	mupa = isl_multi_union_pw_aff_alloc(space);
8832
8833	for (i = 0; i < n; ++i) {
8834		isl_pw_aff *pa;
8835		isl_union_pw_aff *upa;
8836
8837		pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
8838		upa = isl_union_pw_aff_from_pw_aff(pa);
8839		mupa = isl_multi_union_pw_aff_restore_check_space(mupa, i, upa);
8840	}
8841	if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) {
8842		isl_union_set *dom;
8843		isl_multi_pw_aff *copy;
8844
8845		copy = isl_multi_pw_aff_copy(mpa);
8846		dom = isl_union_set_from_set(isl_multi_pw_aff_domain(copy));
8847		mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom);
8848	}
8849
8850	isl_multi_pw_aff_free(mpa);
8851
8852	return mupa;
8853}
8854
8855/* Extract the range space of "pma" and assign it to *space.
8856 * If *space has already been set (through a previous call to this function),
8857 * then check that the range space is the same.
8858 */
8859static isl_stat extract_space(__isl_take isl_pw_multi_aff *pma, void *user)
8860{
8861	isl_space **space = user;
8862	isl_space *pma_space;
8863	isl_bool equal;
8864
8865	pma_space = isl_space_range(isl_pw_multi_aff_get_space(pma));
8866	isl_pw_multi_aff_free(pma);
8867
8868	if (!pma_space)
8869		return isl_stat_error;
8870	if (!*space) {
8871		*space = pma_space;
8872		return isl_stat_ok;
8873	}
8874
8875	equal = isl_space_is_equal(pma_space, *space);
8876	isl_space_free(pma_space);
8877
8878	if (equal < 0)
8879		return isl_stat_error;
8880	if (!equal)
8881		isl_die(isl_space_get_ctx(*space), isl_error_invalid,
8882			"range spaces not the same", return isl_stat_error);
8883	return isl_stat_ok;
8884}
8885
8886/* Construct and return a multi union piecewise affine expression
8887 * that is equal to the given union piecewise multi affine expression.
8888 *
8889 * In order to be able to perform the conversion, the input
8890 * needs to be non-empty and may only involve a single range space.
8891 *
8892 * If the resulting multi union piecewise affine expression has
8893 * an explicit domain, then assign it the domain of the input.
8894 * In other cases, the domain is stored in the individual elements.
8895 */
8896__isl_give isl_multi_union_pw_aff *
8897isl_multi_union_pw_aff_from_union_pw_multi_aff(
8898	__isl_take isl_union_pw_multi_aff *upma)
8899{
8900	isl_space *space = NULL;
8901	isl_multi_union_pw_aff *mupa;
8902	int i;
8903	isl_size n;
8904
8905	n = isl_union_pw_multi_aff_n_pw_multi_aff(upma);
8906	if (n < 0)
8907		goto error;
8908	if (n == 0)
8909		isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid,
8910			"cannot extract range space from empty input",
8911			goto error);
8912	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, &extract_space,
8913							&space) < 0)
8914		goto error;
8915
8916	if (!space)
8917		goto error;
8918
8919	n = isl_space_dim(space, isl_dim_set);
8920	if (n < 0)
8921		space = isl_space_free(space);
8922	mupa = isl_multi_union_pw_aff_alloc(space);
8923
8924	for (i = 0; i < n; ++i) {
8925		isl_union_pw_aff *upa;
8926
8927		upa = isl_union_pw_multi_aff_get_union_pw_aff(upma, i);
8928		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
8929	}
8930	if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) {
8931		isl_union_set *dom;
8932		isl_union_pw_multi_aff *copy;
8933
8934		copy = isl_union_pw_multi_aff_copy(upma);
8935		dom = isl_union_pw_multi_aff_domain(copy);
8936		mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom);
8937	}
8938
8939	isl_union_pw_multi_aff_free(upma);
8940	return mupa;
8941error:
8942	isl_space_free(space);
8943	isl_union_pw_multi_aff_free(upma);
8944	return NULL;
8945}
8946
8947/* This function performs the same operation as
8948 * isl_multi_union_pw_aff_from_union_pw_multi_aff,
8949 * but is considered as a function on an isl_union_pw_multi_aff when exported.
8950 */
8951__isl_give isl_multi_union_pw_aff *
8952isl_union_pw_multi_aff_as_multi_union_pw_aff(
8953	__isl_take isl_union_pw_multi_aff *upma)
8954{
8955	return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma);
8956}
8957
8958/* Try and create an isl_multi_union_pw_aff that is equivalent
8959 * to the given isl_union_map.
8960 * The isl_union_map is required to be single-valued in each space.
8961 * Moreover, it cannot be empty and all range spaces need to be the same.
8962 * Otherwise, an error is produced.
8963 */
8964__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map(
8965	__isl_take isl_union_map *umap)
8966{
8967	isl_union_pw_multi_aff *upma;
8968
8969	upma = isl_union_pw_multi_aff_from_union_map(umap);
8970	return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma);
8971}
8972
8973/* This function performs the same operation as
8974 * isl_multi_union_pw_aff_from_union_map,
8975 * but is considered as a function on an isl_union_map when exported.
8976 */
8977__isl_give isl_multi_union_pw_aff *isl_union_map_as_multi_union_pw_aff(
8978	__isl_take isl_union_map *umap)
8979{
8980	return isl_multi_union_pw_aff_from_union_map(umap);
8981}
8982
8983/* Return a multiple union piecewise affine expression
8984 * that is equal to "mv" on "domain", assuming "domain" and "mv"
8985 * have been aligned.
8986 *
8987 * If the resulting multi union piecewise affine expression has
8988 * an explicit domain, then assign it the input domain.
8989 * In other cases, the domain is stored in the individual elements.
8990 */
8991static __isl_give isl_multi_union_pw_aff *
8992isl_multi_union_pw_aff_multi_val_on_domain_aligned(
8993	__isl_take isl_union_set *domain, __isl_take isl_multi_val *mv)
8994{
8995	int i;
8996	isl_size n;
8997	isl_space *space;
8998	isl_multi_union_pw_aff *mupa;
8999
9000	n = isl_multi_val_dim(mv, isl_dim_set);
9001	if (!domain || n < 0)
9002		goto error;
9003
9004	space = isl_multi_val_get_space(mv);
9005	mupa = isl_multi_union_pw_aff_alloc(space);
9006	for (i = 0; i < n; ++i) {
9007		isl_val *v;
9008		isl_union_pw_aff *upa;
9009
9010		v = isl_multi_val_get_val(mv, i);
9011		upa = isl_union_pw_aff_val_on_domain(isl_union_set_copy(domain),
9012							v);
9013		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
9014	}
9015	if (isl_multi_union_pw_aff_has_explicit_domain(mupa))
9016		mupa = isl_multi_union_pw_aff_intersect_domain(mupa,
9017						    isl_union_set_copy(domain));
9018
9019	isl_union_set_free(domain);
9020	isl_multi_val_free(mv);
9021	return mupa;
9022error:
9023	isl_union_set_free(domain);
9024	isl_multi_val_free(mv);
9025	return NULL;
9026}
9027
9028/* Return a multiple union piecewise affine expression
9029 * that is equal to "mv" on "domain".
9030 */
9031__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_val_on_domain(
9032	__isl_take isl_union_set *domain, __isl_take isl_multi_val *mv)
9033{
9034	isl_bool equal_params;
9035
9036	if (!domain || !mv)
9037		goto error;
9038	equal_params = isl_space_has_equal_params(domain->dim, mv->space);
9039	if (equal_params < 0)
9040		goto error;
9041	if (equal_params)
9042		return isl_multi_union_pw_aff_multi_val_on_domain_aligned(
9043								    domain, mv);
9044	domain = isl_union_set_align_params(domain,
9045						isl_multi_val_get_space(mv));
9046	mv = isl_multi_val_align_params(mv, isl_union_set_get_space(domain));
9047	return isl_multi_union_pw_aff_multi_val_on_domain_aligned(domain, mv);
9048error:
9049	isl_union_set_free(domain);
9050	isl_multi_val_free(mv);
9051	return NULL;
9052}
9053
9054/* Return a multiple union piecewise affine expression
9055 * that is equal to "ma" on "domain".
9056 */
9057__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_aff_on_domain(
9058	__isl_take isl_union_set *domain, __isl_take isl_multi_aff *ma)
9059{
9060	isl_pw_multi_aff *pma;
9061
9062	pma = isl_pw_multi_aff_from_multi_aff(ma);
9063	return isl_multi_union_pw_aff_pw_multi_aff_on_domain(domain, pma);
9064}
9065
9066/* Return a multiple union piecewise affine expression
9067 * that is equal to "pma" on "domain", assuming "domain" and "pma"
9068 * have been aligned.
9069 *
9070 * If the resulting multi union piecewise affine expression has
9071 * an explicit domain, then assign it the input domain.
9072 * In other cases, the domain is stored in the individual elements.
9073 */
9074static __isl_give isl_multi_union_pw_aff *
9075isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(
9076	__isl_take isl_union_set *domain, __isl_take isl_pw_multi_aff *pma)
9077{
9078	int i;
9079	isl_size n;
9080	isl_space *space;
9081	isl_multi_union_pw_aff *mupa;
9082
9083	n = isl_pw_multi_aff_dim(pma, isl_dim_set);
9084	if (!domain || n < 0)
9085		goto error;
9086	space = isl_pw_multi_aff_get_space(pma);
9087	mupa = isl_multi_union_pw_aff_alloc(space);
9088	for (i = 0; i < n; ++i) {
9089		isl_pw_aff *pa;
9090		isl_union_pw_aff *upa;
9091
9092		pa = isl_pw_multi_aff_get_pw_aff(pma, i);
9093		upa = isl_union_pw_aff_pw_aff_on_domain(
9094					    isl_union_set_copy(domain), pa);
9095		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
9096	}
9097	if (isl_multi_union_pw_aff_has_explicit_domain(mupa))
9098		mupa = isl_multi_union_pw_aff_intersect_domain(mupa,
9099						    isl_union_set_copy(domain));
9100
9101	isl_union_set_free(domain);
9102	isl_pw_multi_aff_free(pma);
9103	return mupa;
9104error:
9105	isl_union_set_free(domain);
9106	isl_pw_multi_aff_free(pma);
9107	return NULL;
9108}
9109
9110/* Return a multiple union piecewise affine expression
9111 * that is equal to "pma" on "domain".
9112 */
9113__isl_give isl_multi_union_pw_aff *
9114isl_multi_union_pw_aff_pw_multi_aff_on_domain(__isl_take isl_union_set *domain,
9115	__isl_take isl_pw_multi_aff *pma)
9116{
9117	isl_bool equal_params;
9118	isl_space *space;
9119
9120	space = isl_pw_multi_aff_peek_space(pma);
9121	equal_params = isl_union_set_space_has_equal_params(domain, space);
9122	if (equal_params < 0)
9123		goto error;
9124	if (equal_params)
9125		return isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(
9126								domain, pma);
9127	domain = isl_union_set_align_params(domain,
9128					    isl_pw_multi_aff_get_space(pma));
9129	pma = isl_pw_multi_aff_align_params(pma,
9130					    isl_union_set_get_space(domain));
9131	return isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(domain,
9132									pma);
9133error:
9134	isl_union_set_free(domain);
9135	isl_pw_multi_aff_free(pma);
9136	return NULL;
9137}
9138
9139/* Return a union set containing those elements in the domains
9140 * of the elements of "mupa" where they are all zero.
9141 *
9142 * If there are no elements, then simply return the entire domain.
9143 */
9144__isl_give isl_union_set *isl_multi_union_pw_aff_zero_union_set(
9145	__isl_take isl_multi_union_pw_aff *mupa)
9146{
9147	int i;
9148	isl_size n;
9149	isl_union_pw_aff *upa;
9150	isl_union_set *zero;
9151
9152	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
9153	if (n < 0)
9154		mupa = isl_multi_union_pw_aff_free(mupa);
9155	if (!mupa)
9156		return NULL;
9157
9158	if (n == 0)
9159		return isl_multi_union_pw_aff_domain(mupa);
9160
9161	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
9162	zero = isl_union_pw_aff_zero_union_set(upa);
9163
9164	for (i = 1; i < n; ++i) {
9165		isl_union_set *zero_i;
9166
9167		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
9168		zero_i = isl_union_pw_aff_zero_union_set(upa);
9169
9170		zero = isl_union_set_intersect(zero, zero_i);
9171	}
9172
9173	isl_multi_union_pw_aff_free(mupa);
9174	return zero;
9175}
9176
9177/* Construct a union map mapping the shared domain
9178 * of the union piecewise affine expressions to the range of "mupa"
9179 * in the special case of a 0D multi union piecewise affine expression.
9180 *
9181 * Construct a map between the explicit domain of "mupa" and
9182 * the range space.
9183 * Note that this assumes that the domain consists of explicit elements.
9184 */
9185static __isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff_0D(
9186	__isl_take isl_multi_union_pw_aff *mupa)
9187{
9188	isl_bool is_params;
9189	isl_space *space;
9190	isl_union_set *dom, *ran;
9191
9192	space = isl_multi_union_pw_aff_get_space(mupa);
9193	dom = isl_multi_union_pw_aff_domain(mupa);
9194	ran = isl_union_set_from_set(isl_set_universe(space));
9195
9196	is_params = isl_union_set_is_params(dom);
9197	if (is_params < 0)
9198		dom = isl_union_set_free(dom);
9199	else if (is_params)
9200		isl_die(isl_union_set_get_ctx(dom), isl_error_invalid,
9201			"cannot create union map from expression without "
9202			"explicit domain elements",
9203			dom = isl_union_set_free(dom));
9204
9205	return isl_union_map_from_domain_and_range(dom, ran);
9206}
9207
9208/* Construct a union map mapping the shared domain
9209 * of the union piecewise affine expressions to the range of "mupa"
9210 * with each dimension in the range equated to the
9211 * corresponding union piecewise affine expression.
9212 *
9213 * If the input is zero-dimensional, then construct a mapping
9214 * from its explicit domain.
9215 */
9216__isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff(
9217	__isl_take isl_multi_union_pw_aff *mupa)
9218{
9219	int i;
9220	isl_size n;
9221	isl_space *space;
9222	isl_union_map *umap;
9223	isl_union_pw_aff *upa;
9224
9225	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
9226	if (n < 0)
9227		mupa = isl_multi_union_pw_aff_free(mupa);
9228	if (!mupa)
9229		return NULL;
9230
9231	if (n == 0)
9232		return isl_union_map_from_multi_union_pw_aff_0D(mupa);
9233
9234	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
9235	umap = isl_union_map_from_union_pw_aff(upa);
9236
9237	for (i = 1; i < n; ++i) {
9238		isl_union_map *umap_i;
9239
9240		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
9241		umap_i = isl_union_map_from_union_pw_aff(upa);
9242		umap = isl_union_map_flat_range_product(umap, umap_i);
9243	}
9244
9245	space = isl_multi_union_pw_aff_get_space(mupa);
9246	umap = isl_union_map_reset_range_space(umap, space);
9247
9248	isl_multi_union_pw_aff_free(mupa);
9249	return umap;
9250}
9251
9252/* Internal data structure for isl_union_pw_multi_aff_reset_range_space.
9253 * "range" is the space from which to set the range space.
9254 * "res" collects the results.
9255 */
9256struct isl_union_pw_multi_aff_reset_range_space_data {
9257	isl_space *range;
9258	isl_union_pw_multi_aff *res;
9259};
9260
9261/* Replace the range space of "pma" by the range space of data->range and
9262 * add the result to data->res.
9263 */
9264static isl_stat reset_range_space(__isl_take isl_pw_multi_aff *pma, void *user)
9265{
9266	struct isl_union_pw_multi_aff_reset_range_space_data *data = user;
9267	isl_space *space;
9268
9269	space = isl_pw_multi_aff_get_space(pma);
9270	space = isl_space_domain(space);
9271	space = isl_space_extend_domain_with_range(space,
9272						isl_space_copy(data->range));
9273	pma = isl_pw_multi_aff_reset_space(pma, space);
9274	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
9275
9276	return data->res ? isl_stat_ok : isl_stat_error;
9277}
9278
9279/* Replace the range space of all the piecewise affine expressions in "upma" by
9280 * the range space of "space".
9281 *
9282 * This assumes that all these expressions have the same output dimension.
9283 *
9284 * Since the spaces of the expressions change, so do their hash values.
9285 * We therefore need to create a new isl_union_pw_multi_aff.
9286 * Note that the hash value is currently computed based on the entire
9287 * space even though there can only be a single expression with a given
9288 * domain space.
9289 */
9290static __isl_give isl_union_pw_multi_aff *
9291isl_union_pw_multi_aff_reset_range_space(
9292	__isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *space)
9293{
9294	struct isl_union_pw_multi_aff_reset_range_space_data data = { space };
9295	isl_space *space_upma;
9296
9297	space_upma = isl_union_pw_multi_aff_get_space(upma);
9298	data.res = isl_union_pw_multi_aff_empty(space_upma);
9299	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
9300					&reset_range_space, &data) < 0)
9301		data.res = isl_union_pw_multi_aff_free(data.res);
9302
9303	isl_space_free(space);
9304	isl_union_pw_multi_aff_free(upma);
9305	return data.res;
9306}
9307
9308/* Construct and return a union piecewise multi affine expression
9309 * that is equal to the given multi union piecewise affine expression,
9310 * in the special case of a 0D multi union piecewise affine expression.
9311 *
9312 * Construct a union piecewise multi affine expression
9313 * on top of the explicit domain of the input.
9314 */
9315__isl_give isl_union_pw_multi_aff *
9316isl_union_pw_multi_aff_from_multi_union_pw_aff_0D(
9317	__isl_take isl_multi_union_pw_aff *mupa)
9318{
9319	isl_space *space;
9320	isl_multi_val *mv;
9321	isl_union_set *domain;
9322
9323	space = isl_multi_union_pw_aff_get_space(mupa);
9324	mv = isl_multi_val_zero(space);
9325	domain = isl_multi_union_pw_aff_domain(mupa);
9326	return isl_union_pw_multi_aff_multi_val_on_domain(domain, mv);
9327}
9328
9329/* Construct and return a union piecewise multi affine expression
9330 * that is equal to the given multi union piecewise affine expression.
9331 *
9332 * If the input is zero-dimensional, then
9333 * construct a union piecewise multi affine expression
9334 * on top of the explicit domain of the input.
9335 */
9336__isl_give isl_union_pw_multi_aff *
9337isl_union_pw_multi_aff_from_multi_union_pw_aff(
9338	__isl_take isl_multi_union_pw_aff *mupa)
9339{
9340	int i;
9341	isl_size n;
9342	isl_space *space;
9343	isl_union_pw_multi_aff *upma;
9344	isl_union_pw_aff *upa;
9345
9346	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
9347	if (n < 0)
9348		mupa = isl_multi_union_pw_aff_free(mupa);
9349	if (!mupa)
9350		return NULL;
9351
9352	if (n == 0)
9353		return isl_union_pw_multi_aff_from_multi_union_pw_aff_0D(mupa);
9354
9355	space = isl_multi_union_pw_aff_get_space(mupa);
9356	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
9357	upma = isl_union_pw_multi_aff_from_union_pw_aff(upa);
9358
9359	for (i = 1; i < n; ++i) {
9360		isl_union_pw_multi_aff *upma_i;
9361
9362		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
9363		upma_i = isl_union_pw_multi_aff_from_union_pw_aff(upa);
9364		upma = isl_union_pw_multi_aff_flat_range_product(upma, upma_i);
9365	}
9366
9367	upma = isl_union_pw_multi_aff_reset_range_space(upma, space);
9368
9369	isl_multi_union_pw_aff_free(mupa);
9370	return upma;
9371}
9372
9373/* Intersect the range of "mupa" with "range",
9374 * in the special case where "mupa" is 0D.
9375 *
9376 * Intersect the domain of "mupa" with the constraints on the parameters
9377 * of "range".
9378 */
9379static __isl_give isl_multi_union_pw_aff *mupa_intersect_range_0D(
9380	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *range)
9381{
9382	range = isl_set_params(range);
9383	mupa = isl_multi_union_pw_aff_intersect_params(mupa, range);
9384	return mupa;
9385}
9386
9387/* Intersect the range of "mupa" with "range".
9388 * That is, keep only those domain elements that have a function value
9389 * in "range".
9390 */
9391__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range(
9392	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *range)
9393{
9394	isl_union_pw_multi_aff *upma;
9395	isl_union_set *domain;
9396	isl_space *space;
9397	isl_size n;
9398	int match;
9399
9400	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
9401	if (n < 0 || !range)
9402		goto error;
9403
9404	space = isl_set_get_space(range);
9405	match = isl_space_tuple_is_equal(mupa->space, isl_dim_set,
9406					space, isl_dim_set);
9407	isl_space_free(space);
9408	if (match < 0)
9409		goto error;
9410	if (!match)
9411		isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid,
9412			"space don't match", goto error);
9413	if (n == 0)
9414		return mupa_intersect_range_0D(mupa, range);
9415
9416	upma = isl_union_pw_multi_aff_from_multi_union_pw_aff(
9417					isl_multi_union_pw_aff_copy(mupa));
9418	domain = isl_union_set_from_set(range);
9419	domain = isl_union_set_preimage_union_pw_multi_aff(domain, upma);
9420	mupa = isl_multi_union_pw_aff_intersect_domain(mupa, domain);
9421
9422	return mupa;
9423error:
9424	isl_multi_union_pw_aff_free(mupa);
9425	isl_set_free(range);
9426	return NULL;
9427}
9428
9429/* Return the shared domain of the elements of "mupa",
9430 * in the special case where "mupa" is zero-dimensional.
9431 *
9432 * Return the explicit domain of "mupa".
9433 * Note that this domain may be a parameter set, either
9434 * because "mupa" is meant to live in a set space or
9435 * because no explicit domain has been set.
9436 */
9437__isl_give isl_union_set *isl_multi_union_pw_aff_domain_0D(
9438	__isl_take isl_multi_union_pw_aff *mupa)
9439{
9440	isl_union_set *dom;
9441
9442	dom = isl_multi_union_pw_aff_get_explicit_domain(mupa);
9443	isl_multi_union_pw_aff_free(mupa);
9444
9445	return dom;
9446}
9447
9448/* Return the shared domain of the elements of "mupa".
9449 *
9450 * If "mupa" is zero-dimensional, then return its explicit domain.
9451 */
9452__isl_give isl_union_set *isl_multi_union_pw_aff_domain(
9453	__isl_take isl_multi_union_pw_aff *mupa)
9454{
9455	int i;
9456	isl_size n;
9457	isl_union_pw_aff *upa;
9458	isl_union_set *dom;
9459
9460	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
9461	if (n < 0)
9462		mupa = isl_multi_union_pw_aff_free(mupa);
9463	if (!mupa)
9464		return NULL;
9465
9466	if (n == 0)
9467		return isl_multi_union_pw_aff_domain_0D(mupa);
9468
9469	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
9470	dom = isl_union_pw_aff_domain(upa);
9471	for (i = 1; i < n; ++i) {
9472		isl_union_set *dom_i;
9473
9474		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
9475		dom_i = isl_union_pw_aff_domain(upa);
9476		dom = isl_union_set_intersect(dom, dom_i);
9477	}
9478
9479	isl_multi_union_pw_aff_free(mupa);
9480	return dom;
9481}
9482
9483/* Apply "aff" to "mupa".  The space of "mupa" is equal to the domain of "aff".
9484 * In particular, the spaces have been aligned.
9485 * The result is defined over the shared domain of the elements of "mupa"
9486 *
9487 * We first extract the parametric constant part of "aff" and
9488 * define that over the shared domain.
9489 * Then we iterate over all input dimensions of "aff" and add the corresponding
9490 * multiples of the elements of "mupa".
9491 * Finally, we consider the integer divisions, calling the function
9492 * recursively to obtain an isl_union_pw_aff corresponding to the
9493 * integer division argument.
9494 */
9495static __isl_give isl_union_pw_aff *multi_union_pw_aff_apply_aff(
9496	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff)
9497{
9498	int i;
9499	isl_size n_in, n_div;
9500	isl_union_pw_aff *upa;
9501	isl_union_set *uset;
9502	isl_val *v;
9503	isl_aff *cst;
9504
9505	n_in = isl_aff_dim(aff, isl_dim_in);
9506	n_div = isl_aff_dim(aff, isl_dim_div);
9507	if (n_in < 0 || n_div < 0)
9508		goto error;
9509
9510	uset = isl_multi_union_pw_aff_domain(isl_multi_union_pw_aff_copy(mupa));
9511	cst = isl_aff_copy(aff);
9512	cst = isl_aff_drop_dims(cst, isl_dim_div, 0, n_div);
9513	cst = isl_aff_drop_dims(cst, isl_dim_in, 0, n_in);
9514	cst = isl_aff_project_domain_on_params(cst);
9515	upa = isl_union_pw_aff_aff_on_domain(uset, cst);
9516
9517	for (i = 0; i < n_in; ++i) {
9518		isl_union_pw_aff *upa_i;
9519
9520		if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
9521			continue;
9522		v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
9523		upa_i = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
9524		upa_i = isl_union_pw_aff_scale_val(upa_i, v);
9525		upa = isl_union_pw_aff_add(upa, upa_i);
9526	}
9527
9528	for (i = 0; i < n_div; ++i) {
9529		isl_aff *div;
9530		isl_union_pw_aff *upa_i;
9531
9532		if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
9533			continue;
9534		div = isl_aff_get_div(aff, i);
9535		upa_i = multi_union_pw_aff_apply_aff(
9536					isl_multi_union_pw_aff_copy(mupa), div);
9537		upa_i = isl_union_pw_aff_floor(upa_i);
9538		v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
9539		upa_i = isl_union_pw_aff_scale_val(upa_i, v);
9540		upa = isl_union_pw_aff_add(upa, upa_i);
9541	}
9542
9543	isl_multi_union_pw_aff_free(mupa);
9544	isl_aff_free(aff);
9545
9546	return upa;
9547error:
9548	isl_multi_union_pw_aff_free(mupa);
9549	isl_aff_free(aff);
9550	return NULL;
9551}
9552
9553/* Apply "aff" to "mupa".  The space of "mupa" needs to be compatible
9554 * with the domain of "aff".
9555 * Furthermore, the dimension of this space needs to be greater than zero.
9556 * The result is defined over the shared domain of the elements of "mupa"
9557 *
9558 * We perform these checks and then hand over control to
9559 * multi_union_pw_aff_apply_aff.
9560 */
9561__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff(
9562	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff)
9563{
9564	isl_size dim;
9565	isl_space *space1, *space2;
9566	isl_bool equal;
9567
9568	mupa = isl_multi_union_pw_aff_align_params(mupa,
9569						isl_aff_get_space(aff));
9570	aff = isl_aff_align_params(aff, isl_multi_union_pw_aff_get_space(mupa));
9571	if (!mupa || !aff)
9572		goto error;
9573
9574	space1 = isl_multi_union_pw_aff_get_space(mupa);
9575	space2 = isl_aff_get_domain_space(aff);
9576	equal = isl_space_is_equal(space1, space2);
9577	isl_space_free(space1);
9578	isl_space_free(space2);
9579	if (equal < 0)
9580		goto error;
9581	if (!equal)
9582		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
9583			"spaces don't match", goto error);
9584	dim = isl_aff_dim(aff, isl_dim_in);
9585	if (dim < 0)
9586		goto error;
9587	if (dim == 0)
9588		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
9589			"cannot determine domains", goto error);
9590
9591	return multi_union_pw_aff_apply_aff(mupa, aff);
9592error:
9593	isl_multi_union_pw_aff_free(mupa);
9594	isl_aff_free(aff);
9595	return NULL;
9596}
9597
9598/* Apply "ma" to "mupa", in the special case where "mupa" is 0D.
9599 * The space of "mupa" is known to be compatible with the domain of "ma".
9600 *
9601 * Construct an isl_multi_union_pw_aff that is equal to "ma"
9602 * on the domain of "mupa".
9603 */
9604static __isl_give isl_multi_union_pw_aff *mupa_apply_multi_aff_0D(
9605	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma)
9606{
9607	isl_union_set *dom;
9608
9609	dom = isl_multi_union_pw_aff_domain(mupa);
9610	ma = isl_multi_aff_project_domain_on_params(ma);
9611
9612	return isl_multi_union_pw_aff_multi_aff_on_domain(dom, ma);
9613}
9614
9615/* Apply "ma" to "mupa".  The space of "mupa" needs to be compatible
9616 * with the domain of "ma".
9617 * The result is defined over the shared domain of the elements of "mupa"
9618 */
9619__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff(
9620	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma)
9621{
9622	isl_space *space1, *space2;
9623	isl_multi_union_pw_aff *res;
9624	isl_bool equal;
9625	int i;
9626	isl_size n_in, n_out;
9627
9628	mupa = isl_multi_union_pw_aff_align_params(mupa,
9629						isl_multi_aff_get_space(ma));
9630	ma = isl_multi_aff_align_params(ma,
9631					isl_multi_union_pw_aff_get_space(mupa));
9632	n_in = isl_multi_aff_dim(ma, isl_dim_in);
9633	n_out = isl_multi_aff_dim(ma, isl_dim_out);
9634	if (!mupa || n_in < 0 || n_out < 0)
9635		goto error;
9636
9637	space1 = isl_multi_union_pw_aff_get_space(mupa);
9638	space2 = isl_multi_aff_get_domain_space(ma);
9639	equal = isl_space_is_equal(space1, space2);
9640	isl_space_free(space1);
9641	isl_space_free(space2);
9642	if (equal < 0)
9643		goto error;
9644	if (!equal)
9645		isl_die(isl_multi_aff_get_ctx(ma), isl_error_invalid,
9646			"spaces don't match", goto error);
9647	if (n_in == 0)
9648		return mupa_apply_multi_aff_0D(mupa, ma);
9649
9650	space1 = isl_space_range(isl_multi_aff_get_space(ma));
9651	res = isl_multi_union_pw_aff_alloc(space1);
9652
9653	for (i = 0; i < n_out; ++i) {
9654		isl_aff *aff;
9655		isl_union_pw_aff *upa;
9656
9657		aff = isl_multi_aff_get_aff(ma, i);
9658		upa = multi_union_pw_aff_apply_aff(
9659					isl_multi_union_pw_aff_copy(mupa), aff);
9660		res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa);
9661	}
9662
9663	isl_multi_aff_free(ma);
9664	isl_multi_union_pw_aff_free(mupa);
9665	return res;
9666error:
9667	isl_multi_union_pw_aff_free(mupa);
9668	isl_multi_aff_free(ma);
9669	return NULL;
9670}
9671
9672/* Apply "pa" to "mupa", in the special case where "mupa" is 0D.
9673 * The space of "mupa" is known to be compatible with the domain of "pa".
9674 *
9675 * Construct an isl_multi_union_pw_aff that is equal to "pa"
9676 * on the domain of "mupa".
9677 */
9678static __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff_0D(
9679	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa)
9680{
9681	isl_union_set *dom;
9682
9683	dom = isl_multi_union_pw_aff_domain(mupa);
9684	pa = isl_pw_aff_project_domain_on_params(pa);
9685
9686	return isl_union_pw_aff_pw_aff_on_domain(dom, pa);
9687}
9688
9689/* Apply "pa" to "mupa".  The space of "mupa" needs to be compatible
9690 * with the domain of "pa".
9691 * Furthermore, the dimension of this space needs to be greater than zero.
9692 * The result is defined over the shared domain of the elements of "mupa"
9693 */
9694__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff(
9695	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa)
9696{
9697	int i;
9698	isl_bool equal;
9699	isl_size n_in;
9700	isl_space *space, *space2;
9701	isl_union_pw_aff *upa;
9702
9703	mupa = isl_multi_union_pw_aff_align_params(mupa,
9704						isl_pw_aff_get_space(pa));
9705	pa = isl_pw_aff_align_params(pa,
9706				    isl_multi_union_pw_aff_get_space(mupa));
9707	if (!mupa || !pa)
9708		goto error;
9709
9710	space = isl_multi_union_pw_aff_get_space(mupa);
9711	space2 = isl_pw_aff_get_domain_space(pa);
9712	equal = isl_space_is_equal(space, space2);
9713	isl_space_free(space);
9714	isl_space_free(space2);
9715	if (equal < 0)
9716		goto error;
9717	if (!equal)
9718		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
9719			"spaces don't match", goto error);
9720	n_in = isl_pw_aff_dim(pa, isl_dim_in);
9721	if (n_in < 0)
9722		goto error;
9723	if (n_in == 0)
9724		return isl_multi_union_pw_aff_apply_pw_aff_0D(mupa, pa);
9725
9726	space = isl_space_params(isl_multi_union_pw_aff_get_space(mupa));
9727	upa = isl_union_pw_aff_empty(space);
9728
9729	for (i = 0; i < pa->n; ++i) {
9730		isl_aff *aff;
9731		isl_set *domain;
9732		isl_multi_union_pw_aff *mupa_i;
9733		isl_union_pw_aff *upa_i;
9734
9735		mupa_i = isl_multi_union_pw_aff_copy(mupa);
9736		domain = isl_set_copy(pa->p[i].set);
9737		mupa_i = isl_multi_union_pw_aff_intersect_range(mupa_i, domain);
9738		aff = isl_aff_copy(pa->p[i].aff);
9739		upa_i = multi_union_pw_aff_apply_aff(mupa_i, aff);
9740		upa = isl_union_pw_aff_union_add(upa, upa_i);
9741	}
9742
9743	isl_multi_union_pw_aff_free(mupa);
9744	isl_pw_aff_free(pa);
9745	return upa;
9746error:
9747	isl_multi_union_pw_aff_free(mupa);
9748	isl_pw_aff_free(pa);
9749	return NULL;
9750}
9751
9752/* Apply "pma" to "mupa", in the special case where "mupa" is 0D.
9753 * The space of "mupa" is known to be compatible with the domain of "pma".
9754 *
9755 * Construct an isl_multi_union_pw_aff that is equal to "pma"
9756 * on the domain of "mupa".
9757 */
9758static __isl_give isl_multi_union_pw_aff *mupa_apply_pw_multi_aff_0D(
9759	__isl_take isl_multi_union_pw_aff *mupa,
9760	__isl_take isl_pw_multi_aff *pma)
9761{
9762	isl_union_set *dom;
9763
9764	dom = isl_multi_union_pw_aff_domain(mupa);
9765	pma = isl_pw_multi_aff_project_domain_on_params(pma);
9766
9767	return isl_multi_union_pw_aff_pw_multi_aff_on_domain(dom, pma);
9768}
9769
9770/* Apply "pma" to "mupa".  The space of "mupa" needs to be compatible
9771 * with the domain of "pma".
9772 * The result is defined over the shared domain of the elements of "mupa"
9773 */
9774__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff(
9775	__isl_take isl_multi_union_pw_aff *mupa,
9776	__isl_take isl_pw_multi_aff *pma)
9777{
9778	isl_space *space1, *space2;
9779	isl_multi_union_pw_aff *res;
9780	isl_bool equal;
9781	int i;
9782	isl_size n_in, n_out;
9783
9784	mupa = isl_multi_union_pw_aff_align_params(mupa,
9785					isl_pw_multi_aff_get_space(pma));
9786	pma = isl_pw_multi_aff_align_params(pma,
9787					isl_multi_union_pw_aff_get_space(mupa));
9788	if (!mupa || !pma)
9789		goto error;
9790
9791	space1 = isl_multi_union_pw_aff_get_space(mupa);
9792	space2 = isl_pw_multi_aff_get_domain_space(pma);
9793	equal = isl_space_is_equal(space1, space2);
9794	isl_space_free(space1);
9795	isl_space_free(space2);
9796	if (equal < 0)
9797		goto error;
9798	if (!equal)
9799		isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
9800			"spaces don't match", goto error);
9801	n_in = isl_pw_multi_aff_dim(pma, isl_dim_in);
9802	n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
9803	if (n_in < 0 || n_out < 0)
9804		goto error;
9805	if (n_in == 0)
9806		return mupa_apply_pw_multi_aff_0D(mupa, pma);
9807
9808	space1 = isl_space_range(isl_pw_multi_aff_get_space(pma));
9809	res = isl_multi_union_pw_aff_alloc(space1);
9810
9811	for (i = 0; i < n_out; ++i) {
9812		isl_pw_aff *pa;
9813		isl_union_pw_aff *upa;
9814
9815		pa = isl_pw_multi_aff_get_pw_aff(pma, i);
9816		upa = isl_multi_union_pw_aff_apply_pw_aff(
9817					isl_multi_union_pw_aff_copy(mupa), pa);
9818		res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa);
9819	}
9820
9821	isl_pw_multi_aff_free(pma);
9822	isl_multi_union_pw_aff_free(mupa);
9823	return res;
9824error:
9825	isl_multi_union_pw_aff_free(mupa);
9826	isl_pw_multi_aff_free(pma);
9827	return NULL;
9828}
9829
9830/* Replace the explicit domain of "mupa" by its preimage under "upma".
9831 * If the explicit domain only keeps track of constraints on the parameters,
9832 * then only update those constraints.
9833 */
9834static __isl_give isl_multi_union_pw_aff *preimage_explicit_domain(
9835	__isl_take isl_multi_union_pw_aff *mupa,
9836	__isl_keep isl_union_pw_multi_aff *upma)
9837{
9838	isl_bool is_params;
9839
9840	if (isl_multi_union_pw_aff_check_has_explicit_domain(mupa) < 0)
9841		return isl_multi_union_pw_aff_free(mupa);
9842
9843	mupa = isl_multi_union_pw_aff_cow(mupa);
9844	if (!mupa)
9845		return NULL;
9846
9847	is_params = isl_union_set_is_params(mupa->u.dom);
9848	if (is_params < 0)
9849		return isl_multi_union_pw_aff_free(mupa);
9850
9851	upma = isl_union_pw_multi_aff_copy(upma);
9852	if (is_params)
9853		mupa->u.dom = isl_union_set_intersect_params(mupa->u.dom,
9854		    isl_union_set_params(isl_union_pw_multi_aff_domain(upma)));
9855	else
9856		mupa->u.dom = isl_union_set_preimage_union_pw_multi_aff(
9857							    mupa->u.dom, upma);
9858	if (!mupa->u.dom)
9859		return isl_multi_union_pw_aff_free(mupa);
9860	return mupa;
9861}
9862
9863/* Compute the pullback of "mupa" by the function represented by "upma".
9864 * In other words, plug in "upma" in "mupa".  The result contains
9865 * expressions defined over the domain space of "upma".
9866 *
9867 * Run over all elements of "mupa" and plug in "upma" in each of them.
9868 *
9869 * If "mupa" has an explicit domain, then it is this domain
9870 * that needs to undergo a pullback instead, i.e., a preimage.
9871 */
9872__isl_give isl_multi_union_pw_aff *
9873isl_multi_union_pw_aff_pullback_union_pw_multi_aff(
9874	__isl_take isl_multi_union_pw_aff *mupa,
9875	__isl_take isl_union_pw_multi_aff *upma)
9876{
9877	int i;
9878	isl_size n;
9879
9880	mupa = isl_multi_union_pw_aff_align_params(mupa,
9881				    isl_union_pw_multi_aff_get_space(upma));
9882	upma = isl_union_pw_multi_aff_align_params(upma,
9883				    isl_multi_union_pw_aff_get_space(mupa));
9884	mupa = isl_multi_union_pw_aff_cow(mupa);
9885	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
9886	if (n < 0 || !upma)
9887		goto error;
9888
9889	for (i = 0; i < n; ++i) {
9890		isl_union_pw_aff *upa;
9891
9892		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
9893		upa = isl_union_pw_aff_pullback_union_pw_multi_aff(upa,
9894					    isl_union_pw_multi_aff_copy(upma));
9895		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
9896	}
9897
9898	if (isl_multi_union_pw_aff_has_explicit_domain(mupa))
9899		mupa = preimage_explicit_domain(mupa, upma);
9900
9901	isl_union_pw_multi_aff_free(upma);
9902	return mupa;
9903error:
9904	isl_multi_union_pw_aff_free(mupa);
9905	isl_union_pw_multi_aff_free(upma);
9906	return NULL;
9907}
9908
9909/* Extract the sequence of elements in "mupa" with domain space "space"
9910 * (ignoring parameters).
9911 *
9912 * For the elements of "mupa" that are not defined on the specified space,
9913 * the corresponding element in the result is empty.
9914 */
9915__isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff(
9916	__isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space)
9917{
9918	int i;
9919	isl_size n;
9920	isl_space *space_mpa;
9921	isl_multi_pw_aff *mpa;
9922
9923	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
9924	if (n < 0 || !space)
9925		goto error;
9926
9927	space_mpa = isl_multi_union_pw_aff_get_space(mupa);
9928	space = isl_space_replace_params(space, space_mpa);
9929	space_mpa = isl_space_map_from_domain_and_range(isl_space_copy(space),
9930							space_mpa);
9931	mpa = isl_multi_pw_aff_alloc(space_mpa);
9932
9933	space = isl_space_from_domain(space);
9934	space = isl_space_add_dims(space, isl_dim_out, 1);
9935	for (i = 0; i < n; ++i) {
9936		isl_union_pw_aff *upa;
9937		isl_pw_aff *pa;
9938
9939		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
9940		pa = isl_union_pw_aff_extract_pw_aff(upa,
9941							isl_space_copy(space));
9942		mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
9943		isl_union_pw_aff_free(upa);
9944	}
9945
9946	isl_space_free(space);
9947	return mpa;
9948error:
9949	isl_space_free(space);
9950	return NULL;
9951}
9952
9953/* Data structure that specifies how isl_union_pw_multi_aff_un_op
9954 * should modify the base expressions in the input.
9955 *
9956 * If "filter" is not NULL, then only the base expressions that satisfy "filter"
9957 * are taken into account.
9958 * "fn" is applied to each entry in the input.
9959 */
9960struct isl_union_pw_multi_aff_un_op_control {
9961	isl_bool (*filter)(__isl_keep isl_pw_multi_aff *part);
9962	__isl_give isl_pw_multi_aff *(*fn)(__isl_take isl_pw_multi_aff *pma);
9963};
9964
9965/* Wrapper for isl_union_pw_multi_aff_un_op filter functions (which do not take
9966 * a second argument) for use as an isl_union_pw_multi_aff_transform
9967 * filter function (which does take a second argument).
9968 * Simply call control->filter without the second argument.
9969 */
9970static isl_bool isl_union_pw_multi_aff_un_op_filter_drop_user(
9971	__isl_take isl_pw_multi_aff *pma, void *user)
9972{
9973	struct isl_union_pw_multi_aff_un_op_control *control = user;
9974
9975	return control->filter(pma);
9976}
9977
9978/* Wrapper for isl_union_pw_multi_aff_un_op base functions (which do not take
9979 * a second argument) for use as an isl_union_pw_multi_aff_transform
9980 * base function (which does take a second argument).
9981 * Simply call control->fn without the second argument.
9982 */
9983static __isl_give isl_pw_multi_aff *isl_union_pw_multi_aff_un_op_drop_user(
9984	__isl_take isl_pw_multi_aff *pma, void *user)
9985{
9986	struct isl_union_pw_multi_aff_un_op_control *control = user;
9987
9988	return control->fn(pma);
9989}
9990
9991/* Construct an isl_union_pw_multi_aff that is obtained by
9992 * modifying "upma" according to "control".
9993 *
9994 * isl_union_pw_multi_aff_transform performs essentially
9995 * the same operation, but takes a filter and a callback function
9996 * of a different form (with an extra argument).
9997 * Call isl_union_pw_multi_aff_transform with wrappers
9998 * that remove this extra argument.
9999 */
10000static __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_un_op(
10001	__isl_take isl_union_pw_multi_aff *upma,
10002	struct isl_union_pw_multi_aff_un_op_control *control)
10003{
10004	struct isl_union_pw_multi_aff_transform_control t_control = {
10005		.filter = &isl_union_pw_multi_aff_un_op_filter_drop_user,
10006		.filter_user = control,
10007		.fn = &isl_union_pw_multi_aff_un_op_drop_user,
10008		.fn_user = control,
10009	};
10010
10011	return isl_union_pw_multi_aff_transform(upma, &t_control);
10012}
10013
10014/* For each function in "upma" of the form A -> [B -> C],
10015 * extract the function A -> B and collect the results.
10016 */
10017__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_factor_domain(
10018	__isl_take isl_union_pw_multi_aff *upma)
10019{
10020	struct isl_union_pw_multi_aff_un_op_control control = {
10021		.filter = &isl_pw_multi_aff_range_is_wrapping,
10022		.fn = &isl_pw_multi_aff_range_factor_domain,
10023	};
10024	return isl_union_pw_multi_aff_un_op(upma, &control);
10025}
10026
10027/* For each function in "upma" of the form A -> [B -> C],
10028 * extract the function A -> C and collect the results.
10029 */
10030__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_factor_range(
10031	__isl_take isl_union_pw_multi_aff *upma)
10032{
10033	struct isl_union_pw_multi_aff_un_op_control control = {
10034		.filter = &isl_pw_multi_aff_range_is_wrapping,
10035		.fn = &isl_pw_multi_aff_range_factor_range,
10036	};
10037	return isl_union_pw_multi_aff_un_op(upma, &control);
10038}
10039
10040/* Evaluate the affine function "aff" in the void point "pnt".
10041 * In particular, return the value NaN.
10042 */
10043static __isl_give isl_val *eval_void(__isl_take isl_aff *aff,
10044	__isl_take isl_point *pnt)
10045{
10046	isl_ctx *ctx;
10047
10048	ctx = isl_point_get_ctx(pnt);
10049	isl_aff_free(aff);
10050	isl_point_free(pnt);
10051	return isl_val_nan(ctx);
10052}
10053
10054/* Evaluate the affine expression "aff"
10055 * in the coordinates (with denominator) "pnt".
10056 */
10057static __isl_give isl_val *eval(__isl_keep isl_vec *aff,
10058	__isl_keep isl_vec *pnt)
10059{
10060	isl_int n, d;
10061	isl_ctx *ctx;
10062	isl_val *v;
10063
10064	if (!aff || !pnt)
10065		return NULL;
10066
10067	ctx = isl_vec_get_ctx(aff);
10068	isl_int_init(n);
10069	isl_int_init(d);
10070	isl_seq_inner_product(aff->el + 1, pnt->el, pnt->size, &n);
10071	isl_int_mul(d, aff->el[0], pnt->el[0]);
10072	v = isl_val_rat_from_isl_int(ctx, n, d);
10073	v = isl_val_normalize(v);
10074	isl_int_clear(n);
10075	isl_int_clear(d);
10076
10077	return v;
10078}
10079
10080/* Check that the domain space of "aff" is equal to "space".
10081 */
10082static isl_stat isl_aff_check_has_domain_space(__isl_keep isl_aff *aff,
10083	__isl_keep isl_space *space)
10084{
10085	isl_bool ok;
10086
10087	ok = isl_space_is_equal(isl_aff_peek_domain_space(aff), space);
10088	if (ok < 0)
10089		return isl_stat_error;
10090	if (!ok)
10091		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
10092			"incompatible spaces", return isl_stat_error);
10093	return isl_stat_ok;
10094}
10095
10096/* Evaluate the affine function "aff" in "pnt".
10097 */
10098__isl_give isl_val *isl_aff_eval(__isl_take isl_aff *aff,
10099	__isl_take isl_point *pnt)
10100{
10101	isl_bool is_void;
10102	isl_val *v;
10103	isl_local_space *ls;
10104
10105	if (isl_aff_check_has_domain_space(aff, isl_point_peek_space(pnt)) < 0)
10106		goto error;
10107	is_void = isl_point_is_void(pnt);
10108	if (is_void < 0)
10109		goto error;
10110	if (is_void)
10111		return eval_void(aff, pnt);
10112
10113	ls = isl_aff_get_domain_local_space(aff);
10114	pnt = isl_local_space_lift_point(ls, pnt);
10115
10116	v = eval(aff->v, isl_point_peek_vec(pnt));
10117
10118	isl_aff_free(aff);
10119	isl_point_free(pnt);
10120
10121	return v;
10122error:
10123	isl_aff_free(aff);
10124	isl_point_free(pnt);
10125	return NULL;
10126}
10127