/*
 * Copyright 2011      Sven Verdoolaege
 * Copyright 2012-2014 Ecole Normale Superieure
 *
 * Use of this software is governed by the MIT license
 *
 * Written by Sven Verdoolaege,
 * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
 */

#include <isl/id.h>
#include <isl_space_private.h>
#include <isl/set.h>
#include <isl_reordering.h>

#include <isl_multi_macro.h>

#define MULTI_NAME(BASE) "isl_multi_" #BASE

isl_ctx *FN(MULTI(BASE),get_ctx)(__isl_keep MULTI(BASE) *multi)
{
	return multi ? isl_space_get_ctx(multi->space) : NULL;
}

/* Return the space of "multi".
 */
__isl_keep isl_space *FN(MULTI(BASE),peek_space)(__isl_keep MULTI(BASE) *multi)
{
	return multi ? multi->space : NULL;
}

__isl_give isl_space *FN(MULTI(BASE),get_space)(__isl_keep MULTI(BASE) *multi)
{
	return isl_space_copy(FN(MULTI(BASE),peek_space)(multi));
}

__isl_give isl_space *FN(MULTI(BASE),get_domain_space)(
	__isl_keep MULTI(BASE) *multi)
{
	return multi ? isl_space_domain(isl_space_copy(multi->space)) : NULL;
}

/* Allocate a multi expression living in "space".
 *
 * If the number of base expressions is zero, then make sure
 * there is enough room in the structure for the explicit domain,
 * in case the type supports such an explicit domain.
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),alloc)(__isl_take isl_space *space)
{
	isl_ctx *ctx;
	isl_size n;
	MULTI(BASE) *multi;

	n = isl_space_dim(space, isl_dim_out);
	if (n < 0)
		goto error;

	ctx = isl_space_get_ctx(space);
	if (n > 0)
		multi = isl_calloc(ctx, MULTI(BASE),
			 sizeof(MULTI(BASE)) + (n - 1) * sizeof(struct EL *));
	else
		multi = isl_calloc(ctx, MULTI(BASE), sizeof(MULTI(BASE)));
	if (!multi)
		goto error;

	multi->space = space;
	multi->n = n;
	multi->ref = 1;
	if (FN(MULTI(BASE),has_explicit_domain)(multi))
		multi = FN(MULTI(BASE),init_explicit_domain)(multi);
	return multi;
error:
	isl_space_free(space);
	return NULL;
}

__isl_give MULTI(BASE) *FN(MULTI(BASE),dup)(__isl_keep MULTI(BASE) *multi)
{
	int i;
	MULTI(BASE) *dup;

	if (!multi)
		return NULL;

	dup = FN(MULTI(BASE),alloc)(isl_space_copy(multi->space));
	if (!dup)
		return NULL;

	for (i = 0; i < multi->n; ++i)
		dup = FN(FN(MULTI(BASE),set),BASE)(dup, i,
						    FN(EL,copy)(multi->u.p[i]));
	if (FN(MULTI(BASE),has_explicit_domain)(multi))
		dup = FN(MULTI(BASE),copy_explicit_domain)(dup, multi);

	return dup;
}

__isl_give MULTI(BASE) *FN(MULTI(BASE),cow)(__isl_take MULTI(BASE) *multi)
{
	if (!multi)
		return NULL;

	if (multi->ref == 1)
		return multi;

	multi->ref--;
	return FN(MULTI(BASE),dup)(multi);
}

__isl_give MULTI(BASE) *FN(MULTI(BASE),copy)(__isl_keep MULTI(BASE) *multi)
{
	if (!multi)
		return NULL;

	multi->ref++;
	return multi;
}

__isl_null MULTI(BASE) *FN(MULTI(BASE),free)(__isl_take MULTI(BASE) *multi)
{
	int i;

	if (!multi)
		return NULL;

	if (--multi->ref > 0)
		return NULL;

	isl_space_free(multi->space);
	for (i = 0; i < multi->n; ++i)
		FN(EL,free)(multi->u.p[i]);
	if (FN(MULTI(BASE),has_explicit_domain)(multi))
		FN(MULTI(BASE),free_explicit_domain)(multi);
	free(multi);

	return NULL;
}

isl_size FN(MULTI(BASE),dim)(__isl_keep MULTI(BASE) *multi,
	enum isl_dim_type type)
{
	return isl_space_dim(FN(MULTI(BASE),peek_space)(multi), type);
}

/* Return the number of base expressions in "multi".
 */
isl_size FN(MULTI(BASE),size)(__isl_keep MULTI(BASE) *multi)
{
	return multi ? multi->n : isl_size_error;
}

#undef TYPE
#define TYPE	MULTI(BASE)
static
#include "check_type_range_templ.c"

/* Return a copy of the base expression at position "pos" in "multi".
 */
__isl_give EL *FN(MULTI(BASE),get_at)(__isl_keep MULTI(BASE) *multi, int pos)
{
	isl_ctx *ctx;

	if (FN(MULTI(BASE),check_range)(multi, isl_dim_out, pos, 1) < 0)
		return NULL;
	ctx = FN(MULTI(BASE),get_ctx)(multi);
	return FN(EL,copy)(multi->u.p[pos]);
}

/* This is an alternative name for the function above.
 */
__isl_give EL *FN(FN(MULTI(BASE),get),BASE)(__isl_keep MULTI(BASE) *multi,
	int pos)
{
	return FN(MULTI(BASE),get_at)(multi, pos);
}

/* Set the element at position "pos" of "multi" to "el",
 * where the position may be empty if "multi" has only a single reference.
 */
static __isl_give MULTI(BASE) *FN(MULTI(BASE),restore)(
	__isl_take MULTI(BASE) *multi, int pos, __isl_take EL *el)
{
	multi = FN(MULTI(BASE),cow)(multi);
	if (!multi || !el)
		goto error;

	if (FN(MULTI(BASE),check_range)(multi, isl_dim_out, pos, 1) < 0)
		goto error;

	FN(EL,free)(multi->u.p[pos]);
	multi->u.p[pos] = el;

	return multi;
error:
	FN(MULTI(BASE),free)(multi);
	FN(EL,free)(el);
	return NULL;
}

/* Set the element at position "pos" of "multi" to "el",
 * where the position may be empty if "multi" has only a single reference.
 * However, the space of "multi" is available and is checked
 * for compatibility with "el".
 */
static __isl_give MULTI(BASE) *FN(MULTI(BASE),restore_check_space)(
	__isl_take MULTI(BASE) *multi, int pos, __isl_take EL *el)
{
	isl_space *space;

	space = FN(MULTI(BASE),peek_space)(multi);
	if (FN(EL,check_match_domain_space)(el, space) < 0)
		multi = FN(MULTI(BASE),free)(multi);
	return FN(MULTI(BASE),restore)(multi, pos, el);
}

/* Replace the base expression at position "pos" in "multi" with "el".
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),set_at)(
	__isl_take MULTI(BASE) *multi, int pos, __isl_take EL *el)
{
	isl_space *multi_space = NULL;
	isl_space *el_space = NULL;
	isl_bool match;

	multi_space = FN(MULTI(BASE),get_space)(multi);
	match = FN(EL,matching_params)(el, multi_space);
	if (match < 0)
		goto error;
	if (!match) {
		multi = FN(MULTI(BASE),align_params)(multi,
						    FN(EL,get_space)(el));
		isl_space_free(multi_space);
		multi_space = FN(MULTI(BASE),get_space)(multi);
		el = FN(EL,align_params)(el, isl_space_copy(multi_space));
	}

	multi = FN(MULTI(BASE),restore_check_space)(multi, pos, el);

	isl_space_free(multi_space);
	isl_space_free(el_space);

	return multi;
error:
	FN(MULTI(BASE),free)(multi);
	FN(EL,free)(el);
	isl_space_free(multi_space);
	isl_space_free(el_space);
	return NULL;
}

/* This is an alternative name for the function above.
 */
__isl_give MULTI(BASE) *FN(FN(MULTI(BASE),set),BASE)(
	__isl_take MULTI(BASE) *multi, int pos, __isl_take EL *el)
{
	return FN(MULTI(BASE),set_at)(multi, pos, el);
}

/* Return the base expressions of "multi" as a list.
 */
__isl_give LIST(EL) *FN(MULTI(BASE),get_list)(
	__isl_keep MULTI(BASE) *multi)
{
	isl_size n;
	int i;
	LIST(EL) *list;

	n = FN(MULTI(BASE),size)(multi);
	if (n < 0)
		return NULL;
	list = FN(LIST(EL),alloc)(FN(MULTI(BASE),get_ctx(multi)), n);
	for (i = 0; i < n; ++i) {
		EL *el = FN(MULTI(BASE),get_at)(multi, i);
		list = FN(LIST(EL),add)(list, el);
	}

	return list;
}

/* Reset the space of "multi".  This function is called from isl_pw_templ.c
 * and doesn't know if the space of an element object is represented
 * directly or through its domain.  It therefore passes along both,
 * which we pass along to the element function since we don't know how
 * that is represented either.
 *
 * If "multi" has an explicit domain, then the caller is expected
 * to make sure that any modification that would change the dimensions
 * of the explicit domain has bee applied before this function is called.
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_space_and_domain)(
	__isl_take MULTI(BASE) *multi, __isl_take isl_space *space,
	__isl_take isl_space *domain)
{
	int i;

	multi = FN(MULTI(BASE),cow)(multi);
	if (!multi || !space || !domain)
		goto error;

	for (i = 0; i < multi->n; ++i) {
		multi->u.p[i] = FN(EL,reset_domain_space)(multi->u.p[i],
				 isl_space_copy(domain));
		if (!multi->u.p[i])
			goto error;
	}
	if (FN(MULTI(BASE),has_explicit_domain)(multi)) {
		multi = FN(MULTI(BASE),reset_explicit_domain_space)(multi,
							isl_space_copy(domain));
		if (!multi)
			goto error;
	}
	isl_space_free(domain);
	isl_space_free(multi->space);
	multi->space = space;

	return multi;
error:
	isl_space_free(domain);
	isl_space_free(space);
	FN(MULTI(BASE),free)(multi);
	return NULL;
}

__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_domain_space)(
	__isl_take MULTI(BASE) *multi, __isl_take isl_space *domain)
{
	isl_space *space;

	space = isl_space_extend_domain_with_range(isl_space_copy(domain),
						isl_space_copy(multi->space));
	return FN(MULTI(BASE),reset_space_and_domain)(multi, space, domain);
}

__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_space)(
	__isl_take MULTI(BASE) *multi, __isl_take isl_space *space)
{
	isl_space *domain;

	domain = isl_space_domain(isl_space_copy(space));
	return FN(MULTI(BASE),reset_space_and_domain)(multi, space, domain);
}

/* Reset the user pointer on all identifiers of parameters and tuples
 * of the space of "multi".
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_user)(
	__isl_take MULTI(BASE) *multi)
{
	isl_space *space;

	space = FN(MULTI(BASE),get_space)(multi);
	space = isl_space_reset_user(space);

	return FN(MULTI(BASE),reset_space)(multi, space);
}

__isl_give MULTI(BASE) *FN(MULTI(BASE),realign_domain)(
	__isl_take MULTI(BASE) *multi, __isl_take isl_reordering *exp)
{
	int i;
	isl_space *space;

	multi = FN(MULTI(BASE),cow)(multi);
	if (!multi || !exp)
		goto error;

	for (i = 0; i < multi->n; ++i) {
		multi->u.p[i] = FN(EL,realign_domain)(multi->u.p[i],
						isl_reordering_copy(exp));
		if (!multi->u.p[i])
			goto error;
	}

	space = isl_reordering_get_space(exp);
	multi = FN(MULTI(BASE),reset_domain_space)(multi, space);

	isl_reordering_free(exp);
	return multi;
error:
	isl_reordering_free(exp);
	FN(MULTI(BASE),free)(multi);
	return NULL;
}

/* Align the parameters of "multi" to those of "model".
 *
 * If "multi" has an explicit domain, then align the parameters
 * of the domain first.
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),align_params)(
	__isl_take MULTI(BASE) *multi, __isl_take isl_space *model)
{
	isl_ctx *ctx;
	isl_bool equal_params;
	isl_reordering *exp;

	if (!multi || !model)
		goto error;

	equal_params = isl_space_has_equal_params(multi->space, model);
	if (equal_params < 0)
		goto error;
	if (equal_params) {
		isl_space_free(model);
		return multi;
	}

	ctx = isl_space_get_ctx(model);
	if (!isl_space_has_named_params(model))
		isl_die(ctx, isl_error_invalid,
			"model has unnamed parameters", goto error);
	if (!isl_space_has_named_params(multi->space))
		isl_die(ctx, isl_error_invalid,
			"input has unnamed parameters", goto error);

	if (FN(MULTI(BASE),has_explicit_domain)(multi)) {
		multi = FN(MULTI(BASE),align_explicit_domain_params)(multi,
							isl_space_copy(model));
		if (!multi)
			goto error;
	}
	exp = isl_parameter_alignment_reordering(multi->space, model);
	exp = isl_reordering_extend_space(exp,
				    FN(MULTI(BASE),get_domain_space)(multi));
	multi = FN(MULTI(BASE),realign_domain)(multi, exp);

	isl_space_free(model);
	return multi;
error:
	isl_space_free(model);
	FN(MULTI(BASE),free)(multi);
	return NULL;
}

/* Create a multi expression in the given space with the elements of "list"
 * as base expressions.
 *
 * Since isl_multi_*_restore_* assumes that the element and
 * the multi expression have matching spaces, the alignment
 * (if any) needs to be performed beforehand.
 */
__isl_give MULTI(BASE) *FN(FN(MULTI(BASE),from),LIST(BASE))(
	__isl_take isl_space *space, __isl_take LIST(EL) *list)
{
	int i;
	isl_size n, dim;
	isl_ctx *ctx;
	MULTI(BASE) *multi;

	dim = isl_space_dim(space, isl_dim_out);
	n = FN(FN(LIST(EL),n),BASE)(list);
	if (dim < 0 || n < 0)
		goto error;

	ctx = isl_space_get_ctx(space);
	if (n != dim)
		isl_die(ctx, isl_error_invalid,
			"invalid number of elements in list", goto error);

	for (i = 0; i < n; ++i) {
		EL *el = FN(LIST(EL),peek)(list, i);
		space = isl_space_align_params(space, FN(EL,get_space)(el));
	}
	multi = FN(MULTI(BASE),alloc)(isl_space_copy(space));
	for (i = 0; i < n; ++i) {
		EL *el = FN(FN(LIST(EL),get),BASE)(list, i);
		el = FN(EL,align_params)(el, isl_space_copy(space));
		multi = FN(MULTI(BASE),restore_check_space)(multi, i, el);
	}

	isl_space_free(space);
	FN(LIST(EL),free)(list);
	return multi;
error:
	isl_space_free(space);
	FN(LIST(EL),free)(list);
	return NULL;
}

/* This function performs the same operation as isl_multi_*_from_*_list,
 * but is considered as a function on an isl_space when exported.
 */
__isl_give MULTI(BASE) *FN(isl_space_multi,BASE)(__isl_take isl_space *space,
	__isl_take LIST(EL) *list)
{
	return FN(FN(MULTI(BASE),from),LIST(BASE))(space, list);
}

__isl_give MULTI(BASE) *FN(MULTI(BASE),drop_dims)(
	__isl_take MULTI(BASE) *multi,
	enum isl_dim_type type, unsigned first, unsigned n)
{
	int i;

	multi = FN(MULTI(BASE),cow)(multi);
	if (FN(MULTI(BASE),check_range)(multi, type, first, n) < 0)
		return FN(MULTI(BASE),free)(multi);

	multi->space = isl_space_drop_dims(multi->space, type, first, n);
	if (!multi->space)
		return FN(MULTI(BASE),free)(multi);

	if (type == isl_dim_out) {
		for (i = 0; i < n; ++i)
			FN(EL,free)(multi->u.p[first + i]);
		for (i = first; i + n < multi->n; ++i)
			multi->u.p[i] = multi->u.p[i + n];
		multi->n -= n;
		if (n > 0 && FN(MULTI(BASE),has_explicit_domain)(multi))
			multi = FN(MULTI(BASE),init_explicit_domain)(multi);

		return multi;
	}

	if (FN(MULTI(BASE),has_explicit_domain)(multi))
		multi = FN(MULTI(BASE),drop_explicit_domain_dims)(multi,
								type, first, n);
	if (!multi)
		return NULL;

	for (i = 0; i < multi->n; ++i) {
		multi->u.p[i] = FN(EL,drop_dims)(multi->u.p[i], type, first, n);
		if (!multi->u.p[i])
			return FN(MULTI(BASE),free)(multi);
	}

	return multi;
}

#undef TYPE
#define TYPE MULTI(BASE)

#include "isl_check_named_params_templ.c"
static
#include "isl_align_params_bin_templ.c"

/* Given two MULTI(BASE)s A -> B and C -> D,
 * construct a MULTI(BASE) (A * C) -> [B -> D].
 *
 * If "multi1" and/or "multi2" has an explicit domain, then
 * intersect the domain of the result with these explicit domains.
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),range_product)(
	__isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2)
{
	int i;
	isl_size n1, n2;
	EL *el;
	isl_space *space;
	MULTI(BASE) *res;

	FN(MULTI(BASE),align_params_bin)(&multi1, &multi2);
	n1 = FN(MULTI(BASE),size)(multi1);
	n2 = FN(MULTI(BASE),size)(multi2);
	if (n1 < 0 || n2 < 0)
		goto error;

	space = isl_space_range_product(FN(MULTI(BASE),get_space)(multi1),
					FN(MULTI(BASE),get_space)(multi2));
	res = FN(MULTI(BASE),alloc)(space);

	for (i = 0; i < n1; ++i) {
		el = FN(FN(MULTI(BASE),get),BASE)(multi1, i);
		res = FN(FN(MULTI(BASE),set),BASE)(res, i, el);
	}

	for (i = 0; i < n2; ++i) {
		el = FN(FN(MULTI(BASE),get),BASE)(multi2, i);
		res = FN(FN(MULTI(BASE),set),BASE)(res, n1 + i, el);
	}

	if (FN(MULTI(BASE),has_explicit_domain)(multi1))
		res = FN(MULTI(BASE),intersect_explicit_domain)(res, multi1);
	if (FN(MULTI(BASE),has_explicit_domain)(multi2))
		res = FN(MULTI(BASE),intersect_explicit_domain)(res, multi2);

	FN(MULTI(BASE),free)(multi1);
	FN(MULTI(BASE),free)(multi2);
	return res;
error:
	FN(MULTI(BASE),free)(multi1);
	FN(MULTI(BASE),free)(multi2);
	return NULL;
}

/* Is the range of "multi" a wrapped relation?
 */
isl_bool FN(MULTI(BASE),range_is_wrapping)(__isl_keep MULTI(BASE) *multi)
{
	if (!multi)
		return isl_bool_error;
	return isl_space_range_is_wrapping(multi->space);
}

/* Given a function A -> [B -> C], extract the function A -> B.
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),range_factor_domain)(
	__isl_take MULTI(BASE) *multi)
{
	isl_space *space;
	isl_size total, keep;

	total = FN(MULTI(BASE),dim)(multi, isl_dim_out);
	if (total < 0)
		return FN(MULTI(BASE),free)(multi);
	if (!isl_space_range_is_wrapping(multi->space))
		isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid,
			"range is not a product",
			return FN(MULTI(BASE),free)(multi));

	space = FN(MULTI(BASE),get_space)(multi);
	space = isl_space_range_factor_domain(space);
	keep = isl_space_dim(space, isl_dim_out);
	if (keep < 0)
		multi = FN(MULTI(BASE),free)(multi);
	multi = FN(MULTI(BASE),drop_dims)(multi,
					isl_dim_out, keep, total - keep);
	multi = FN(MULTI(BASE),reset_space)(multi, space);

	return multi;
}

/* Given a function A -> [B -> C], extract the function A -> C.
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),range_factor_range)(
	__isl_take MULTI(BASE) *multi)
{
	isl_space *space;
	isl_size total, keep;

	total = FN(MULTI(BASE),dim)(multi, isl_dim_out);
	if (total < 0)
		return FN(MULTI(BASE),free)(multi);
	if (!isl_space_range_is_wrapping(multi->space))
		isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid,
			"range is not a product",
			return FN(MULTI(BASE),free)(multi));

	space = FN(MULTI(BASE),get_space)(multi);
	space = isl_space_range_factor_range(space);
	keep = isl_space_dim(space, isl_dim_out);
	if (keep < 0)
		multi = FN(MULTI(BASE),free)(multi);
	multi = FN(MULTI(BASE),drop_dims)(multi, isl_dim_out, 0, total - keep);
	multi = FN(MULTI(BASE),reset_space)(multi, space);

	return multi;
}

/* Given a function [B -> C], extract the function C.
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),factor_range)(
	__isl_take MULTI(BASE) *multi)
{
	isl_space *space;
	isl_size total, keep;

	total = FN(MULTI(BASE),dim)(multi, isl_dim_set);
	if (total < 0)
		return FN(MULTI(BASE),free)(multi);
	if (!isl_space_is_wrapping(multi->space))
		isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid,
			"not a product", return FN(MULTI(BASE),free)(multi));

	space = FN(MULTI(BASE),get_space)(multi);
	space = isl_space_factor_range(space);
	keep = isl_space_dim(space, isl_dim_set);
	if (keep < 0)
		multi = FN(MULTI(BASE),free)(multi);
	multi = FN(MULTI(BASE),drop_dims)(multi, isl_dim_set, 0, total - keep);
	multi = FN(MULTI(BASE),reset_space)(multi, space);

	return multi;
}

__isl_give MULTI(BASE) *FN(MULTI(BASE),flatten_range)(
	__isl_take MULTI(BASE) *multi)
{
	if (!multi)
		return NULL;

	if (!multi->space->nested[1])
		return multi;

	multi = FN(MULTI(BASE),cow)(multi);
	if (!multi)
		return NULL;

	multi->space = isl_space_flatten_range(multi->space);
	if (!multi->space)
		return FN(MULTI(BASE),free)(multi);

	return multi;
}

/* Given two MULTI(BASE)s A -> B and C -> D,
 * construct a MULTI(BASE) (A * C) -> (B, D).
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),flat_range_product)(
	__isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2)
{
	MULTI(BASE) *multi;

	multi = FN(MULTI(BASE),range_product)(multi1, multi2);
	multi = FN(MULTI(BASE),flatten_range)(multi);
	return multi;
}

/* Given two multi expressions, "multi1"
 *
 *	[A] -> [B1 B2]
 *
 * where B2 starts at position "pos", and "multi2"
 *
 *	[A] -> [D]
 *
 * return the multi expression
 *
 *	[A] -> [B1 D B2]
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),range_splice)(
	__isl_take MULTI(BASE) *multi1, unsigned pos,
	__isl_take MULTI(BASE) *multi2)
{
	MULTI(BASE) *res;
	isl_size dim;

	dim = FN(MULTI(BASE),size)(multi1);
	if (dim < 0 || !multi2)
		goto error;

	if (FN(MULTI(BASE),check_range)(multi1, isl_dim_out, pos, 0) < 0)
		goto error;

	res = FN(MULTI(BASE),copy)(multi1);
	res = FN(MULTI(BASE),drop_dims)(res, isl_dim_out, pos, dim - pos);
	multi1 = FN(MULTI(BASE),drop_dims)(multi1, isl_dim_out, 0, pos);

	res = FN(MULTI(BASE),flat_range_product)(res, multi2);
	res = FN(MULTI(BASE),flat_range_product)(res, multi1);

	return res;
error:
	FN(MULTI(BASE),free)(multi1);
	FN(MULTI(BASE),free)(multi2);
	return NULL;
}

#undef TYPE
#define TYPE	MULTI(BASE)

static
#include "isl_type_has_equal_space_bin_templ.c"
static
#include "isl_type_check_equal_space_templ.c"

/* This function is currently only used from isl_aff.c
 */
static __isl_give MULTI(BASE) *FN(MULTI(BASE),bin_op)(
	__isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2,
	__isl_give EL *(*fn)(__isl_take EL *, __isl_take EL *))
	__attribute__ ((unused));

/* Pairwise perform "fn" to the elements of "multi1" and "multi2" and
 * return the result.
 *
 * If "multi2" has an explicit domain, then
 * intersect the domain of the result with this explicit domain.
 */
static __isl_give MULTI(BASE) *FN(MULTI(BASE),bin_op)(
	__isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2,
	__isl_give EL *(*fn)(__isl_take EL *, __isl_take EL *))
{
	int i;

	FN(MULTI(BASE),align_params_bin)(&multi1, &multi2);
	multi1 = FN(MULTI(BASE),cow)(multi1);
	if (FN(MULTI(BASE),check_equal_space)(multi1, multi2) < 0)
		goto error;

	for (i = 0; i < multi1->n; ++i) {
		multi1->u.p[i] = fn(multi1->u.p[i],
						FN(EL,copy)(multi2->u.p[i]));
		if (!multi1->u.p[i])
			goto error;
	}

	if (FN(MULTI(BASE),has_explicit_domain)(multi2))
		multi1 = FN(MULTI(BASE),intersect_explicit_domain)(multi1,
								    multi2);

	FN(MULTI(BASE),free)(multi2);
	return multi1;
error:
	FN(MULTI(BASE),free)(multi1);
	FN(MULTI(BASE),free)(multi2);
	return NULL;
}

/* Only used on some multi-expressions.
 */
static isl_bool FN(MULTI(BASE),any)(__isl_keep MULTI(BASE) *multi,
	isl_bool (*test)(__isl_keep EL *)) __attribute__ ((unused));

/* Does "test" succeed on any base expression of "multi"?
 */
static isl_bool FN(MULTI(BASE),any)(__isl_keep MULTI(BASE) *multi,
	isl_bool (*test)(__isl_keep EL *))
{
	isl_size n;
	int i;

	n = FN(MULTI(BASE),size)(multi);
	if (n < 0)
		return isl_bool_error;

	for (i = 0; i < n; ++i) {
		isl_bool any = test(multi->u.p[i]);
		if (any < 0 || any)
			return any;
	}

	return isl_bool_false;
}

/* Only used on some multi-expressions.
 */
static isl_bool FN(MULTI(BASE),every)(__isl_keep MULTI(BASE) *multi,
	isl_bool (*test)(__isl_keep EL *)) __attribute__ ((unused));

/* Does "test" succeed on every base expression of "multi"?
 */
static isl_bool FN(MULTI(BASE),every)(__isl_keep MULTI(BASE) *multi,
	isl_bool (*test)(__isl_keep EL *))
{
	isl_size n;
	int i;

	n = FN(MULTI(BASE),size)(multi);
	if (n < 0)
		return isl_bool_error;

	for (i = 0; i < n; ++i) {
		isl_bool every = test(multi->u.p[i]);
		if (every < 0 || !every)
			return every;
	}

	return isl_bool_true;
}

/* Convert a multiple expression defined over a parameter domain
 * into one that is defined over a zero-dimensional set.
 */
__isl_give MULTI(BASE) *FN(MULTI(BASE),from_range)(
	__isl_take MULTI(BASE) *multi)
{
	isl_space *space;

	if (!multi)
		return NULL;
	if (!isl_space_is_set(multi->space))
		isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid,
			"not living in a set space",
			return FN(MULTI(BASE),free)(multi));

	space = FN(MULTI(BASE),get_space)(multi);
	space = isl_space_from_range(space);
	multi = FN(MULTI(BASE),reset_space)(multi, space);

	return multi;
}

/* Are "multi1" and "multi2" obviously equal?
 */
isl_bool FN(MULTI(BASE),plain_is_equal)(__isl_keep MULTI(BASE) *multi1,
	__isl_keep MULTI(BASE) *multi2)
{
	int i;
	isl_bool equal;

	if (!multi1 || !multi2)
		return isl_bool_error;
	if (multi1->n != multi2->n)
		return isl_bool_false;
	equal = isl_space_is_equal(multi1->space, multi2->space);
	if (equal < 0 || !equal)
		return equal;

	for (i = 0; i < multi1->n; ++i) {
		equal = FN(EL,plain_is_equal)(multi1->u.p[i], multi2->u.p[i]);
		if (equal < 0 || !equal)
			return equal;
	}

	if (FN(MULTI(BASE),has_explicit_domain)(multi1) ||
	    FN(MULTI(BASE),has_explicit_domain)(multi2)) {
		equal = FN(MULTI(BASE),equal_explicit_domain)(multi1, multi2);
		if (equal < 0 || !equal)
			return equal;
	}

	return isl_bool_true;
}
