#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <cloog/isl/cloog.h>
#include <isl/list.h>
#include <isl/constraint.h>
#include <isl/ilp.h>
#include <isl/aff.h>

#ifdef OSL_SUPPORT
#include <osl/macros.h>
#include <osl/relation.h>
#endif

CloogDomain *cloog_domain_from_isl_set(struct isl_set *set)
{
	if (isl_set_is_params(set))
		set = isl_set_from_params(set);
	set = isl_set_detect_equalities(set);
	set = isl_set_compute_divs(set);
	return (CloogDomain *)set;
}

__isl_give isl_set *isl_set_from_cloog_domain(CloogDomain *domain)
{
	return (isl_set *)domain;
}

CloogScattering *cloog_scattering_from_isl_map(struct isl_map *map)
{
	return (CloogScattering *)map;
}

__isl_give isl_map *isl_map_from_cloog_scattering(CloogScattering *scattering)
{
	return (isl_map *)scattering;
}


/**
 * Returns true if each scattering dimension is defined in terms
 * of the original iterators.
 */
int cloog_scattering_fully_specified(CloogScattering *scattering,
				      CloogDomain *domain)
{
	isl_map *map = isl_map_from_cloog_scattering(scattering);
	return isl_map_is_single_valued(map);
}


CloogConstraintSet *cloog_domain_constraints(CloogDomain *domain)
{
	isl_basic_set *bset;
	isl_set *set = isl_set_from_cloog_domain(domain);
	assert(isl_set_n_basic_set(set) == 1);
	bset = isl_set_copy_basic_set(set);
	return cloog_constraint_set_from_isl_basic_set(bset);
}


void cloog_domain_print_constraints(FILE *foo, CloogDomain *domain,
					int print_number)
{
	isl_basic_set *bset;
	isl_set *set = isl_set_from_cloog_domain(domain);

	if (print_number)
		isl_set_print(set, foo, 0, ISL_FORMAT_EXT_POLYLIB);
	else {
		assert(isl_set_n_basic_set(set) == 1);
		bset = isl_set_copy_basic_set(set);
		isl_basic_set_print(bset, foo,
					0, NULL, NULL, ISL_FORMAT_POLYLIB);
		isl_basic_set_free(bset);
	}
}


void cloog_scattering_print_constraints(FILE *foo, CloogScattering *scattering)
{
	isl_map *map = isl_map_from_cloog_scattering(scattering);
	isl_map_print(map, foo, 0, ISL_FORMAT_EXT_POLYLIB);
}


void cloog_domain_free(CloogDomain * domain)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	isl_set_free(set);
}


void cloog_scattering_free(CloogScattering *scatt)
{
	isl_map *map = isl_map_from_cloog_scattering(scatt);
	isl_map_free(map);
}


CloogDomain * cloog_domain_copy(CloogDomain * domain)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	return cloog_domain_from_isl_set(isl_set_copy(set));
}


/**
 * cloog_domain_convex function:
 * Computes the convex hull of domain.
 */ 
CloogDomain *cloog_domain_convex(CloogDomain *domain)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	set = isl_set_from_basic_set(isl_set_convex_hull(isl_set_copy(set)));
	return cloog_domain_from_isl_set(set);
}


/**
 * cloog_domain_simple_convex:
 * Given a list (union) of polyhedra, this function returns a "simple"
 * convex hull of this union.  In particular, the constraints of the
 * the returned polyhedron consist of (parametric) lower and upper
 * bounds on individual variables and constraints that appear in the
 * original polyhedra.
 */
CloogDomain *cloog_domain_simple_convex(CloogDomain *domain)
{
	struct isl_basic_set *hull;
	isl_set *set = isl_set_from_cloog_domain(domain);

	if (cloog_domain_isconvex(domain))
		return cloog_domain_copy(domain);

	hull = isl_set_bounded_simple_hull(isl_set_copy(set));
	return cloog_domain_from_isl_set(isl_set_from_basic_set(hull));
}


/**
 * cloog_domain_simplify function:
 * Given two polyhedral domains (dom1) and (dom2),
 * this function finds the largest domain set (or the smallest list
 * of non-redundant constraints), that when intersected with polyhedral
 * domain (dom2) equals (dom1)intersect(dom2). The output is a new CloogDomain
 * structure with a polyhedral domain with the "redundant" constraints removed.
 * NB: the second domain is required not to be a union.
 */ 
CloogDomain *cloog_domain_simplify(CloogDomain *dom1, CloogDomain *dom2)
{
	isl_set *set1 = isl_set_from_cloog_domain(dom1);
	isl_set *set2 = isl_set_from_cloog_domain(dom2);
	set1 = isl_set_gist(isl_set_copy(set1), isl_set_copy(set2));
	return cloog_domain_from_isl_set(set1);
}


/**
 * cloog_domain_union function:
 * This function returns a new polyhedral domain which is the union of
 * two polyhedral domains (dom1) U (dom2).
 * Frees dom1 and dom2;
 */
CloogDomain *cloog_domain_union(CloogDomain *dom1, CloogDomain *dom2)
{
	isl_set *set1 = isl_set_from_cloog_domain(dom1);
	isl_set *set2 = isl_set_from_cloog_domain(dom2);
	set1 = isl_set_union(set1, set2);
	return cloog_domain_from_isl_set(set1);
}



/**
 * cloog_domain_intersection function:
 * This function returns a new polyhedral domain which is the intersection of
 * two polyhedral domains (dom1) \cap (dom2).
 */ 
CloogDomain *cloog_domain_intersection(CloogDomain *dom1, CloogDomain *dom2)
{
	isl_set *set1 = isl_set_from_cloog_domain(dom1);
	isl_set *set2 = isl_set_from_cloog_domain(dom2);
	set1 = isl_set_intersect(isl_set_copy(set1), isl_set_copy(set2));
	return cloog_domain_from_isl_set(set1);
}


/**
 * cloog_domain_difference function:
 * Returns the set difference domain \ minus.
 */ 
CloogDomain *cloog_domain_difference(CloogDomain *domain, CloogDomain *minus)
{
	isl_set *set1 = isl_set_from_cloog_domain(domain);
	isl_set *set2 = isl_set_from_cloog_domain(minus);
	set1 = isl_set_subtract(isl_set_copy(set1), isl_set_copy(set2));
	return cloog_domain_from_isl_set(set1);
}


/**
 * cloog_domain_sort function:
 * This function topologically sorts (nb_doms) domains. Here (doms) is an
 * array of pointers to CloogDomains, (nb_doms) is the number of domains,
 * (level) is the level to consider for partial ordering (nb_par) is the
 * parameter space dimension, (permut) if not NULL, is an array of (nb_doms)
 * integers that contains a permutation specification after call in order to
 * apply the topological sorting. 
 */
void cloog_domain_sort(CloogDomain **doms, unsigned nb_doms, unsigned level,
			int *permut)
{
	int i, j, k, cmp;
	struct isl_ctx *ctx;
	unsigned char **follows;
	isl_set *set_i, *set_j;
	isl_basic_set *bset_i, *bset_j;

	if (!nb_doms)
		return;
	set_i = isl_set_from_cloog_domain(doms[0]);
	ctx = isl_set_get_ctx(set_i);
	for (i = 0; i < nb_doms; i++) {
		set_i = isl_set_from_cloog_domain(doms[i]);
		assert(isl_set_n_basic_set(set_i) == 1);
	}

	follows = isl_alloc_array(ctx, unsigned char *, nb_doms);
	assert(follows);
	for (i = 0; i < nb_doms; ++i) {
		follows[i] = isl_alloc_array(ctx, unsigned char, nb_doms);
		assert(follows[i]);
		for (j = 0; j < nb_doms; ++j)
			follows[i][j] = 0;
	}

	for (i = 1; i < nb_doms; ++i) {
		for (j = 0; j < i; ++j) {
			if (follows[i][j] || follows[j][i])
				continue;
			set_i = isl_set_from_cloog_domain(doms[i]);
			set_j = isl_set_from_cloog_domain(doms[j]);
			bset_i = isl_set_copy_basic_set(set_i);
			bset_j = isl_set_copy_basic_set(set_j);
			cmp = isl_basic_set_compare_at(bset_i, bset_j, level-1);
			isl_basic_set_free(bset_i);
			isl_basic_set_free(bset_j);
			if (!cmp)
				continue;
			if (cmp > 0) {
				follows[i][j] = 1;
				for (k = 0; k < i; ++k)
					follows[i][k] |= follows[j][k];
			} else {
				follows[j][i] = 1;
				for (k = 0; k < i; ++k)
					follows[k][i] |= follows[k][j];
			}
		}
	}

	for (i = 0, j = 0; i < nb_doms; j = (j + 1) % nb_doms) {
		for (k = 0; k < nb_doms; ++k)
			if (follows[j][k])
				break;
		if (k < nb_doms)
			continue;
		for (k = 0; k < nb_doms; ++k)
			follows[k][j] = 0;
		follows[j][j] = 1;
		permut[i] = 1 + j;
		++i;
	}

	for (i = 0; i < nb_doms; ++i)
		free(follows[i]);
	free(follows);
}


/**
 * Check whether there is or may be any value of dom1 at the given level
 * that is greater than or equal to a value of dom2 at the same level.
 *
 * Return
 *	 1 is there is or may be a greater-than pair.
 *	 0 if there is no greater-than pair, but there may be an equal-to pair
 *	-1 if there is definitely no such pair
 */
int cloog_domain_follows(CloogDomain *dom1, CloogDomain *dom2, unsigned level)
{
	isl_set *set1 = isl_set_from_cloog_domain(dom1);
	isl_set *set2 = isl_set_from_cloog_domain(dom2);
	int follows;

	follows = isl_set_follows_at(set1, set2, level - 1);
	assert(follows >= -1);

	return follows;
}


/**
 * cloog_domain_empty function:
 * Returns an empty domain of the same dimensions as template.
 */
CloogDomain *cloog_domain_empty(CloogDomain *template)
{
	isl_set *set = isl_set_from_cloog_domain(template);
	return cloog_domain_from_isl_set(isl_set_empty_like(set));
}


/**
 * Return 1 if the specified dimension has both an upper and a lower bound.
 */
int cloog_domain_is_bounded(CloogDomain *dom, unsigned level)
{
	isl_set *set = isl_set_from_cloog_domain(dom);
	return isl_set_dim_is_bounded(set, isl_dim_set, level - 1);
}


/******************************************************************************
 *                          Structure display function                        *
 ******************************************************************************/


/**
 * cloog_domain_print_structure :
 * this function is a more human-friendly way to display the CloogDomain data
 * structure, it only shows the constraint system and includes an indentation
 * level (level) in order to work with others print_structure functions.
 */
void cloog_domain_print_structure(FILE *file, CloogDomain *domain, int level,
				  const char *name)
{
	int i ;
	isl_set *set = isl_set_from_cloog_domain(domain);

	/* Go to the right level. */
	for (i = 0; i < level; i++)
		fprintf(file, "|\t");
  
	if (!set) {
		fprintf(file, "+-- Null CloogDomain\n");
		return;
	}
	fprintf(file, "+-- %s\n", name);
	for (i = 0; i < level+1; ++i)
		fprintf(file, "|\t");

	isl_set_print(set, file, 0, ISL_FORMAT_ISL);

	fprintf(file, "\n");
}


/******************************************************************************
 *                         Memory deallocation function                       *
 ******************************************************************************/


void cloog_domain_list_free(CloogDomainList *list)
{
	CloogDomainList *next;

	for ( ; list; list = next) {
		next = list->next;
		cloog_domain_free(list->domain);
		free(list);
	}
}


/**
 * cloog_scattering_list_free function:
 * This function frees the allocated memory for a CloogScatteringList structure.
 */
void cloog_scattering_list_free(CloogScatteringList *list)
{
	while (list != NULL) {
		CloogScatteringList *temp = list->next;
		isl_map *map = isl_map_from_cloog_scattering(list->scatt);
		isl_map_free(map);
		free(list);
		list = temp;
	}
}


/******************************************************************************
 *                               Reading function                             *
 ******************************************************************************/


/**
 * cloog_domain_read_context function:
 * Read parameter domain.
 */
CloogDomain *cloog_domain_read_context(CloogState *state, FILE *input)
{
	struct isl_ctx *ctx = state->backend->ctx;
	isl_set *set;

	set = isl_set_read_from_file(ctx, input);
	set = isl_set_move_dims(set, isl_dim_param, 0,
				isl_dim_set, 0, isl_set_dim(set, isl_dim_set));

	return cloog_domain_from_isl_set(set);
}


/**
 * cloog_domain_from_context
 * Reinterpret context by turning parameters into variables.
 */
CloogDomain *cloog_domain_from_context(CloogDomain *context)
{
	isl_set *set = isl_set_from_cloog_domain(context);

	set = isl_set_move_dims(set, isl_dim_set, 0,
			    isl_dim_param, 0, isl_set_dim(set, isl_dim_param));

	return cloog_domain_from_isl_set(set);
}


/**
 * cloog_domain_union_read function:
 * This function reads a union of polyhedra into a file (input) and
 * returns a pointer to a CloogDomain containing the read information. 
 */
CloogDomain *cloog_domain_union_read(CloogState *state,
					FILE *input, int nb_parameters)
{
	struct isl_ctx *ctx = state->backend->ctx;
	struct isl_set *set;

	set = isl_set_read_from_file(ctx, input);
	if (isl_set_dim(set, isl_dim_param) != nb_parameters) {
		int dim = isl_set_dim(set, isl_dim_set);
		set = isl_set_move_dims(set, isl_dim_param, 0,
			    isl_dim_set, dim - nb_parameters, nb_parameters);
	}
	return cloog_domain_from_isl_set(set);
}


/**
 * cloog_domain_read_scattering function:
 * This function reads in a scattering function from the file input.
 *
 * We try to read the scattering relation as a map, but if it is
 * specified in the original PolyLib format, then isl_map_read_from_file
 * will treat the input as a set return a map with zero input dimensions.
 * In this case, we need to decompose the set into a map from
 * scattering dimensions to domain dimensions and then invert the
 * resulting map.
 */
CloogScattering *cloog_domain_read_scattering(CloogDomain *domain, FILE *input)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	isl_ctx *ctx = isl_set_get_ctx(set);
	struct isl_map *scat;
	unsigned nparam;
	unsigned dim;
	unsigned n_scat;

	dim = isl_set_dim(set, isl_dim_set);
	nparam = isl_set_dim(set, isl_dim_param);
	scat = isl_map_read_from_file(ctx, input);
	if (isl_map_dim(scat, isl_dim_param) != nparam) {
		int n_out = isl_map_dim(scat, isl_dim_out);
		scat = isl_map_move_dims(scat, isl_dim_param, 0,
					isl_dim_out, n_out - nparam, nparam);
	}
	if (isl_map_dim(scat, isl_dim_in) != dim) {
		n_scat = isl_map_dim(scat, isl_dim_out) - dim;
		scat = isl_map_move_dims(scat, isl_dim_in, 0,
					isl_dim_out, n_scat, dim);
	}
	return cloog_scattering_from_isl_map(scat);
}

/******************************************************************************
 *                      CloogMatrix Reading function                          *
 ******************************************************************************/

/**
 * isl_constraint_read_from_matrix:
 * Convert a single line of a matrix to a isl_constraint.
 * Returns a pointer to the constraint if successful; NULL otherwise.
 */
static struct isl_constraint *isl_constraint_read_from_matrix(
	struct isl_space *dim, cloog_int_t *row)
{
	struct isl_constraint *constraint;
	int j;
	int nvariables = isl_space_dim(dim, isl_dim_set);
	int nparam = isl_space_dim(dim, isl_dim_param);
	isl_local_space *ls = isl_local_space_from_space(dim);

	if (cloog_int_is_zero(row[0]))
		constraint = isl_equality_alloc(ls);
	else
		constraint = isl_inequality_alloc(ls);

	for (j = 0; j < nvariables; ++j)
		isl_constraint_set_coefficient(constraint, isl_dim_out, j,
					       row[1 + j]);

	for (j = 0; j < nparam; ++j)
		isl_constraint_set_coefficient(constraint, isl_dim_param, j,
					       row[1 + nvariables + j]);

	isl_constraint_set_constant(constraint, row[1 + nvariables + nparam]);

	return constraint;
}

/**
 * isl_basic_set_read_from_matrix:
 * Convert matrix to basic_set. The matrix contains nparam parameter columns.
 * Returns a pointer to the basic_set if successful; NULL otherwise.
 */
static struct isl_basic_set *isl_basic_set_read_from_matrix(struct isl_ctx *ctx,
	CloogMatrix* matrix, int nparam)
{
	struct isl_space *dim;
	struct isl_basic_set *bset;
	int i;
	unsigned nrows, ncolumns;

	nrows = matrix->NbRows;
	ncolumns = matrix->NbColumns;
	int nvariables = ncolumns - 2 - nparam;

	dim = isl_space_set_alloc(ctx, nparam, nvariables);

	bset = isl_basic_set_universe(isl_space_copy(dim));

	for (i = 0; i < nrows; ++i) {
		cloog_int_t *row = matrix->p[i];
		struct isl_constraint *constraint =
			isl_constraint_read_from_matrix(isl_space_copy(dim), row);
		bset = isl_basic_set_add_constraint(bset, constraint);
	}

	isl_space_free(dim);

	return bset;
}

/**
 * cloog_domain_from_cloog_matrix:
 * Create a CloogDomain containing the constraints described in matrix.
 * nparam is the number of parameters contained in the domain.
 * Returns a pointer to the CloogDomain if successful; NULL otherwise.
 */
CloogDomain *cloog_domain_from_cloog_matrix(CloogState *state,
	CloogMatrix *matrix, int nparam)
{
	struct isl_ctx *ctx = state->backend->ctx;
	struct isl_basic_set *bset;

	bset = isl_basic_set_read_from_matrix(ctx, matrix, nparam);

	return cloog_domain_from_isl_set(isl_set_from_basic_set(bset));
}

/**
 * cloog_scattering_from_cloog_matrix:
 * Create a CloogScattering containing the constraints described in matrix.
 * nparam is the number of parameters contained in the domain.
 * Returns a pointer to the CloogScattering if successful; NULL otherwise.
 */
CloogScattering *cloog_scattering_from_cloog_matrix(CloogState *state,
	CloogMatrix *matrix, int nb_scat, int nb_par)
{
	struct isl_ctx *ctx = state->backend->ctx;
	struct isl_basic_set *bset;
	struct isl_basic_map *scat;
	struct isl_space *dims;
	unsigned dim;

	bset = isl_basic_set_read_from_matrix(ctx, matrix, nb_par);
	dim = isl_basic_set_n_dim(bset) - nb_scat;
	dims = isl_space_alloc(ctx, nb_par, nb_scat, dim);

	scat = isl_basic_map_from_basic_set(bset, dims);
	scat = isl_basic_map_reverse(scat);
	return cloog_scattering_from_isl_map(isl_map_from_basic_map(scat));
}


/******************************************************************************
 *                            Processing functions                            *
 ******************************************************************************/


#ifdef OSL_SUPPORT
/**
 * Converts an openscop relation to a CLooG domain.
 * \param[in,out] state    CLooG state.
 * \param[in]     relation OpenScop relation to convert.
 * \return A new CloogDomain corresponding to the input OpenScop relation.
 */
CloogDomain *cloog_domain_from_osl_relation(CloogState *state,
                                            osl_relation_p relation) {
  char *str;
  struct isl_ctx *ctx = state->backend->ctx;
  isl_set *set;
  CloogDomain *domain = NULL;

  if (relation != NULL) {
    if (relation->precision != OSL_PRECISION_MP)
      cloog_die("Non-GMP precision is not supported yet.\n");

    str = osl_relation_spprint_polylib(relation, NULL);
    set = isl_set_read_from_str(ctx, str);
    free(str);

    domain = cloog_domain_from_isl_set(set);
  }

  return domain;
}


/**
 * Converts an openscop scattering relation to a CLooG scattering.
 * \param[in,out] state    CLooG state.
 * \param[in]     relation OpenScop relation to convert.
 * \return A new CloogScattering corresponding to the input OpenScop relation.
 */
CloogScattering *cloog_scattering_from_osl_relation(CloogState *state,
                                                    osl_relation_p relation) {
  char *str;
  struct isl_ctx *ctx = state->backend->ctx;
  isl_map *map;
  CloogScattering *scattering = NULL;

  if (relation != NULL) {
    if (relation->precision != OSL_PRECISION_MP)
      cloog_die("Non-GMP precision is not supported yet.\n");

    if (relation->type != OSL_TYPE_SCATTERING)
      cloog_die("Cannot convert a non-scattering relation to a scattering.\n");

    str = osl_relation_spprint_polylib(relation, NULL);
    map = isl_map_read_from_str(ctx, str);
    free(str);

    scattering = cloog_scattering_from_isl_map(map);
  }

  return scattering;
}
#endif

/**
 * cloog_domain_isempty function:
 */ 
int cloog_domain_isempty(CloogDomain *domain)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	return isl_set_is_empty(set);
}


/**
 * cloog_domain_universe function:
 * This function returns the complete dim-dimensional space.
 */
CloogDomain *cloog_domain_universe(CloogState *state, unsigned dim)
{
	struct isl_space *dims;
	struct isl_basic_set *bset;

	dims = isl_space_set_alloc(state->backend->ctx, 0, dim);
	bset = isl_basic_set_universe(dims);
	return cloog_domain_from_isl_set(isl_set_from_basic_set(bset));
}


/**
 * cloog_domain_project function:
 * This function returns the projection of
 * (domain) on the (level) first dimensions (i.e. outer loops).
 */ 
CloogDomain *cloog_domain_project(CloogDomain *domain, int level)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	set = isl_set_remove_dims(isl_set_copy(set), isl_dim_set,
					level, isl_set_n_dim(set) - level);
	set = isl_set_compute_divs(set);
	if (level > 0)
		set = isl_set_remove_divs_involving_dims(set,
						isl_dim_set, level - 1, 1);
	return cloog_domain_from_isl_set(set);
}


/**
 * cloog_domain_extend function:
 * This function returns the (domain) given as input with (dim)
 * dimensions and (nb_par) parameters.
 * This function does not free (domain), and returns a new CloogDomain.
 */ 
CloogDomain *cloog_domain_extend(CloogDomain *domain, int dim)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	int n = isl_set_dim(set, isl_dim_set);
	set = isl_set_add_dims(isl_set_copy(set), isl_dim_set, dim - n);
	return cloog_domain_from_isl_set(set);
}


/**
 * cloog_domain_never_integral function:
 * For us, an equality like 3*i -4 = 0 is always false since 4%3 != 0.
 * There is no need to check for such constraints explicitly for the isl
 * backend.
 */
int cloog_domain_never_integral(CloogDomain * domain)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	return isl_set_is_empty(set);
}


/**
 * Check whether the loop at "level" is executed at most once.
 * We construct a map that maps all remaining variables to this iterator
 * and check whether this map is single valued.
 *
 * Alternatively, we could have mapped the domain through a mapping
 * [p] -> { [..., i] -> [..., i'] : i' > i }
 * and then taken the intersection of the original domain and the transformed
 * domain.  If this intersection is empty, then the corresponding
 * loop is executed at most once.
 */
int cloog_domain_is_otl(CloogDomain *domain, int level)
{
	int otl;
	isl_set *set = isl_set_from_cloog_domain(domain);
	isl_map *map;

	map = isl_map_from_domain(isl_set_copy(set));
	map = isl_map_move_dims(map, isl_dim_out, 0, isl_dim_in, level - 1, 1);
	otl = isl_map_is_single_valued(map);
	isl_map_free(map);

	return otl;
}


/**
 * cloog_domain_stride function:
 * This function finds the stride imposed to unknown with the column number
 * 'strided_level' in order to be integral. For instance, if we have a
 * constraint like -i - 2j + 2k = 0, and we consider k, then k can be integral
 * only if (i + 2j)%2 = 0. Then only if i%2 = 0. Then k imposes a stride 2 to
 * the unknown i. The function returns the imposed stride in a parameter field.
 * - domain is the set of constraint we have to consider,
 * - strided_level is the column number of the unknown for which a stride have
 *   to be found,
 * - looking_level is the column number of the unknown that impose a stride to
 *   the first unknown.
 * - stride is the stride that is returned back as a function parameter. 
 * - offset is the value of the constant c if the condition is of the shape
 *   (i + c)%s = 0, s being the stride.
 */
void cloog_domain_stride(CloogDomain *domain, int strided_level,
	cloog_int_t *stride, cloog_int_t *offset)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	isl_set_dim_residue_class(set, strided_level - 1, stride, offset);
	if (!isl_int_is_zero(*offset))
		isl_int_sub(*offset, *stride, *offset);
	return;
}


struct cloog_can_stride {
	int level;
	int can_stride;
};

static int constraint_can_stride(__isl_take isl_constraint *c, void *user)
{
	struct cloog_can_stride *ccs = (struct cloog_can_stride *)user;
	int i;
	isl_int v;
	unsigned n_div;

	if (isl_constraint_is_equality(c)) {
		isl_constraint_free(c);
		return 0;
	}

	isl_int_init(v);
	isl_constraint_get_coefficient(c, isl_dim_set, ccs->level - 1, &v);
	if (isl_int_is_pos(v)) {
		n_div = isl_constraint_dim(c, isl_dim_div);
		for (i = 0; i < n_div; ++i) {
			isl_constraint_get_coefficient(c, isl_dim_div, i, &v);
			if (!isl_int_is_zero(v))
				break;
		}
		if (i < n_div)
			ccs->can_stride = 0;
	}
	isl_int_clear(v);
	isl_constraint_free(c);

	return 0;
}

static int basic_set_can_stride(__isl_take isl_basic_set *bset, void *user)
{
	struct cloog_can_stride *ccs = (struct cloog_can_stride *)user;
	int r;

	r = isl_basic_set_foreach_constraint(bset, constraint_can_stride, ccs);
	isl_basic_set_free(bset);
	return r;
}


/**
 * Return 1 if CLooG is allowed to perform stride detection on level "level"
 * and 0 otherwise.
 * Currently, stride detection is only allowed when none of the lower
 * bound constraints involve any existentially quantified variables.
 * The reason is that the current isl interface does not make it
 * easy to construct an integer division that depends on other integer
 * divisions.
 * By not allowing existentially quantified variables in the constraints,
 * we can ignore them in cloog_domain_stride_lower_bound.
 */
int cloog_domain_can_stride(CloogDomain *domain, int level)
{
	struct cloog_can_stride ccs = { level, 1 };
	isl_set *set = isl_set_from_cloog_domain(domain);
	int r;
	r = isl_set_foreach_basic_set(set, basic_set_can_stride, &ccs);
	assert(r == 0);
	return ccs.can_stride;
}


struct cloog_stride_lower {
	int level;
	CloogStride *stride;
	isl_set *set;
	isl_basic_set *bounds;
};

/* If the given constraint is a lower bound on csl->level, then add
 * a lower bound to csl->bounds that makes sure that the remainder
 * of the smallest value on division by csl->stride is equal to csl->offset.
 *
 * In particular, the given lower bound is of the form
 *
 *	a i + f >= 0
 *
 * where f may depend on the parameters and other iterators.
 * The stride is s and the offset is d.
 * The lower bound -f/a may not satisfy the above condition.  In fact,
 * it may not even be integral.  We want to round this value of i up
 * to the nearest value that satisfies the condition and add the corresponding
 * lower bound constraint.  This nearest value is obtained by rounding
 * i - d up to the nearest multiple of s.
 * That is, we first subtract d
 *
 *	i' = -f/a - d
 *
 * then we round up to the nearest multiple of s
 *
 *	i'' = s * ceil(i'/s)
 *
 * and finally, we add d again
 *
 *	i''' = i'' + d
 *
 * and impose the constraint i >= i'''.
 *
 * We find
 *
 *	i'' = s * ceil((-f - a * d)/(a * s)) = - s * floor((f + a * d)/(a * s))
 *
 *	i >= - s * floor((f + a * d)/(a * s)) + d
 *
 * or
 *	i + s * floor((f + a * d)/(a * s)) - d >= 0
 */
static int constraint_stride_lower(__isl_take isl_constraint *c, void *user)
{
	struct cloog_stride_lower *csl = (struct cloog_stride_lower *)user;
	isl_int v;
	isl_constraint *bound;
	isl_aff *b;

	if (isl_constraint_is_equality(c)) {
		isl_constraint_free(c);
		return 0;
	}

	isl_int_init(v);
	isl_constraint_get_coefficient(c, isl_dim_set, csl->level - 1, &v);
	if (!isl_int_is_pos(v)) {
		isl_int_clear(v);
		isl_constraint_free(c);

		return 0;
	}

	b = isl_constraint_get_bound(c, isl_dim_set, csl->level - 1);

	b = isl_aff_neg(b);
	b = isl_aff_add_constant(b, csl->stride->offset);
	b = isl_aff_scale_down(b, csl->stride->stride);
	b = isl_aff_floor(b);
	b = isl_aff_scale(b, csl->stride->stride);
	isl_int_neg(v, csl->stride->offset);
	b = isl_aff_add_constant(b, v);
	b = isl_aff_add_coefficient_si(b, isl_dim_in, csl->level - 1, 1);

	bound = isl_inequality_from_aff(b);

	csl->bounds = isl_basic_set_add_constraint(csl->bounds, bound);

	isl_int_clear(v);
	isl_constraint_free(c);

	return 0;
}

/* This functions performs essentially the same operation as
 * constraint_stride_lower, the only difference being that the offset d
 * is not a constant, but an affine expression in terms of the parameters
 * and earlier variables.  In particular the affine expression is equal
 * to the coefficients of stride->constraint multiplied by stride->factor.
 * As in constraint_stride_lower, we add an extra bound
 *
 *	i + s * floor((f + a * d)/(a * s)) - d >= 0
 *
 * for each lower bound
 *
 *	a i + f >= 0
 *
 * where d is not the aforementioned affine expression.
 */
static int constraint_stride_lower_c(__isl_take isl_constraint *c, void *user)
{
	struct cloog_stride_lower *csl = (struct cloog_stride_lower *)user;
	isl_int v;
	isl_constraint *bound;
	isl_constraint *csl_c;
	isl_aff *d, *b;

	if (isl_constraint_is_equality(c)) {
		isl_constraint_free(c);
		return 0;
	}

	isl_int_init(v);
	isl_constraint_get_coefficient(c, isl_dim_set, csl->level - 1, &v);
	if (!isl_int_is_pos(v)) {
		isl_int_clear(v);
		isl_constraint_free(c);

		return 0;
	}

	csl_c = cloog_constraint_to_isl(csl->stride->constraint);

	d = isl_constraint_get_aff(csl_c);
	d = isl_aff_drop_dims(d, isl_dim_div, 0, isl_aff_dim(d, isl_dim_div));
	d = isl_aff_set_coefficient_si(d, isl_dim_in, csl->level - 1, 0);
	d = isl_aff_scale(d, csl->stride->factor);

	b = isl_constraint_get_bound(c, isl_dim_set, csl->level - 1);

	b = isl_aff_neg(b);
	b = isl_aff_add(b, isl_aff_copy(d));
	b = isl_aff_scale_down(b, csl->stride->stride);
	b = isl_aff_floor(b);
	b = isl_aff_scale(b, csl->stride->stride);
	b = isl_aff_sub(b, d);
	b = isl_aff_add_coefficient_si(b, isl_dim_in, csl->level - 1, 1);

	bound = isl_inequality_from_aff(b);

	csl->bounds = isl_basic_set_add_constraint(csl->bounds, bound);

	isl_int_clear(v);
	isl_constraint_free(c);

	return 0;
}

static int basic_set_stride_lower(__isl_take isl_basic_set *bset, void *user)
{
	struct cloog_stride_lower *csl = (struct cloog_stride_lower *)user;
	int r;

	csl->bounds = isl_basic_set_universe_like(bset);
	if (csl->stride->constraint)
		r = isl_basic_set_foreach_constraint(bset,
					&constraint_stride_lower_c, csl);
	else
		r = isl_basic_set_foreach_constraint(bset,
					&constraint_stride_lower, csl);
	bset = isl_basic_set_intersect(bset, csl->bounds);
	csl->set = isl_set_union(csl->set, isl_set_from_basic_set(bset));

	return r;
}

/**
 * Update the lower bounds at level "level" to the given stride information.
 * That is, make sure that the remainder on division by "stride"
 * is equal to "offset".
 */
CloogDomain *cloog_domain_stride_lower_bound(CloogDomain *domain, int level,
	CloogStride *stride)
{
	struct cloog_stride_lower csl;
	isl_set *set = isl_set_from_cloog_domain(domain);
	int r;

	csl.stride = stride;
	csl.level = level;
	csl.set = isl_set_empty_like(set);

	r = isl_set_foreach_basic_set(set, basic_set_stride_lower, &csl);
	assert(r == 0);

	cloog_domain_free(domain);
	return cloog_domain_from_isl_set(csl.set);
}


/* Add stride constraint, if any, to domain.
 */
CloogDomain *cloog_domain_add_stride_constraint(CloogDomain *domain,
	CloogStride *stride)
{
	isl_constraint *c;
	isl_set *set;

	if (!stride || !stride->constraint)
		return domain;

	set = isl_set_from_cloog_domain(domain);
	c = isl_constraint_copy(cloog_constraint_to_isl(stride->constraint));

	set = isl_set_add_constraint(set, c);

	return cloog_domain_from_isl_set(set);
}


/**
 * cloog_domain_lazy_equal function:
 * This function returns 1 if the domains given as input are the same, 0 if it
 * is unable to decide.
 */
int cloog_domain_lazy_equal(CloogDomain *d1, CloogDomain *d2)
{
	isl_set *set1 = isl_set_from_cloog_domain(d1);
	isl_set *set2 = isl_set_from_cloog_domain(d2);
	return isl_set_fast_is_equal(set1, set2);
}

struct cloog_bound_split {
	isl_set *set;
	int level;
	int lower;
	int upper;
};

static int constraint_bound_split(__isl_take isl_constraint *c, void *user)
{
	struct cloog_bound_split *cbs = (struct cloog_bound_split *)user;
	isl_int v;
	int i;
	int handle = 0;

	isl_int_init(v);
	isl_constraint_get_coefficient(c, isl_dim_set, cbs->level - 1, &v);
	if (!cbs->lower && isl_int_is_pos(v))
		cbs->lower = handle = 1;
	else if (!cbs->upper && isl_int_is_neg(v))
		cbs->upper = handle = 1;
	if (handle) {
		for (i = 0; i < isl_set_dim(cbs->set, isl_dim_param); ++i) {
			isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
			if (isl_int_is_zero(v))
				continue;
			cbs->set = isl_set_split_dims(cbs->set,
							isl_dim_param, i, 1);
		}
	}
	isl_int_clear(v);
	isl_constraint_free(c);

	return (cbs->lower && cbs->upper) ? -1 : 0;
}

static int basic_set_bound_split(__isl_take isl_basic_set *bset, void *user)
{
	struct cloog_bound_split *cbs = (struct cloog_bound_split *)user;
	int r;

	cbs->lower = 0;
	cbs->upper = 0;
	r = isl_basic_set_foreach_constraint(bset, constraint_bound_split, cbs);
	isl_basic_set_free(bset);
	return ((!cbs->lower || !cbs->upper) && r < 0) ? -1 : 0;
}

/**
 * Return a union of sets S_i such that the convex hull of "dom",
 * when intersected with one the sets S_i, will have an upper and
 * lower bound for the dimension at "level" (provided "dom" itself
 * has such bounds for the dimensions).
 *
 * We currently take a very simple approach.  For each of the basic
 * sets in "dom" we pick a lower and an upper bound and split the
 * range of any parameter involved in these two bounds in a
 * nonnegative and a negative part.  This ensures that the symbolic
 * constant in these two constraints are themselves bounded and
 * so there will be at least one upper and one lower bound
 * in the convex hull.
 */
CloogDomain *cloog_domain_bound_splitter(CloogDomain *dom, int level)
{
	struct cloog_bound_split cbs;
	isl_set *set = isl_set_from_cloog_domain(dom);
	int r;
	cbs.level = level;
	cbs.set = isl_set_universe_like(set);
	r = isl_set_foreach_basic_set(set, basic_set_bound_split, &cbs);
	assert(r == 0);
	return cloog_domain_from_isl_set(cbs.set);
}


/* Check whether the union of scattering functions over all domains
 * is obviously injective.
 */
static int injective_scattering(CloogScatteringList *list)
{
	isl_map *map;
	isl_union_map *umap;
	int injective;
	int i = 0;
	char name[30];

	if (!list)
		return 1;
	
	map = isl_map_copy(isl_map_from_cloog_scattering(list->scatt));
	snprintf(name, sizeof(name), "S%d", i);
	map = isl_map_set_tuple_name(map, isl_dim_in, name);
	umap = isl_union_map_from_map(map);

	for (list = list->next, ++i; list; list = list->next, ++i) {
		map = isl_map_copy(isl_map_from_cloog_scattering(list->scatt));
		snprintf(name, sizeof(name), "S%d", i);
		map = isl_map_set_tuple_name(map, isl_dim_in, name);
		umap = isl_union_map_add_map(umap, map);
	}

	injective = isl_union_map_plain_is_injective(umap);

	isl_union_map_free(umap);

	return injective;
}


/**
 * cloog_scattering_lazy_block function:
 * This function returns 1 if the two scattering functions s1 and s2 given
 * as input are the same (except possibly for the final dimension, where we
 * allow a difference of 1), assuming that the domains on which this
 * scatterings are applied are the same.
 * In fact this function answers the question "can I
 * safely consider the two domains as only one with two statements (a block) ?".
 * A difference of 1 in the final dimension is only allowed if the
 * entire scattering function is injective.
 * - s1 and s2 are the two domains to check for blocking,
 * - scattering is the linked list of all domains,
 * - scattdims is the total number of scattering dimentions.
 */
int cloog_scattering_lazy_block(CloogScattering *s1, CloogScattering *s2,
			    CloogScatteringList *scattering, int scattdims)
{
	int i;
	struct isl_space *dim;
	struct isl_map *rel;
	struct isl_set *delta;
	isl_map *map1 = isl_map_from_cloog_scattering(s1);
	isl_map *map2 = isl_map_from_cloog_scattering(s2);
	int fixed, block;
	isl_int cst;
	unsigned n_scat;

	n_scat = isl_map_dim(map1, isl_dim_out);
	if (n_scat != isl_map_dim(map2, isl_dim_out))
		return 0;

	dim = isl_map_get_space(map1);
	dim = isl_space_map_from_set(isl_space_domain(dim));
	rel = isl_map_identity(dim);
	rel = isl_map_apply_domain(rel, isl_map_copy(map1));
	rel = isl_map_apply_range(rel, isl_map_copy(map2));
	delta = isl_map_deltas(rel);
	isl_int_init(cst);
	for (i = 0; i < n_scat; ++i) {
		fixed = isl_set_fast_dim_is_fixed(delta, i, &cst);
		if (fixed != 1)
			break;
		if (isl_int_is_zero(cst))
			continue;
		if (i + 1 < n_scat)
			break;
		if (!isl_int_is_one(cst))
			break;
		if (!injective_scattering(scattering))
			break;
	}
	block = i >= n_scat;
	isl_int_clear(cst);
	isl_set_free(delta);
	return block;
}


/**
 * cloog_domain_lazy_disjoint function:
 * This function returns 1 if the domains given as input are disjoint, 0 if it
 * is unable to decide.
 */
int cloog_domain_lazy_disjoint(CloogDomain *d1, CloogDomain *d2)
{
	isl_set *set1 = isl_set_from_cloog_domain(d1);
	isl_set *set2 = isl_set_from_cloog_domain(d2);
	return isl_set_fast_is_disjoint(set1, set2);
} 
 
 
/**
 * cloog_scattering_list_lazy_same function:
 * This function returns 1 if two domains in the list are the same, 0 if it
 * is unable to decide.
 */
int cloog_scattering_list_lazy_same(CloogScatteringList *list)
{
	CloogScatteringList *one, *other;
	isl_map *one_map, *other_map;

	for (one = list; one; one = one->next) {
		one_map = isl_map_from_cloog_scattering(one->scatt);
		for (other = one->next; other; other = other->next) {
			other_map = isl_map_from_cloog_scattering(other->scatt);
			if (isl_map_fast_is_equal(one_map, other_map))
				return 1;
		}
	}
	return 0;
}

int cloog_domain_dimension(CloogDomain * domain)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	return isl_set_dim(set, isl_dim_set);
}

int cloog_domain_parameter_dimension(CloogDomain *domain)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	return isl_set_dim(set, isl_dim_param);
}

int cloog_scattering_dimension(CloogScattering *scatt, CloogDomain *domain)
{
	isl_map *map = isl_map_from_cloog_scattering(scatt);
	return isl_map_dim(map, isl_dim_out);
}

int cloog_domain_isconvex(CloogDomain * domain)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	return isl_set_n_basic_set(set) <= 1;
}


/**
 * cloog_domain_cut_first function:
 * This function splits off and returns the first convex set in the
 * union "domain".  The remainder of the union is returned in rest.
 * The original "domain" itself is destroyed and may not be used
 * after a call to this function.
 */
CloogDomain *cloog_domain_cut_first(CloogDomain *domain, CloogDomain **rest)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	struct isl_basic_set *first;

	first = isl_set_copy_basic_set(set);
	set = isl_set_drop_basic_set(set, first);
	*rest = cloog_domain_from_isl_set(set);

	return cloog_domain_from_isl_set(isl_set_from_basic_set(first));
}


/**
 * Given a union domain, try to find a simpler representation
 * using fewer sets in the union.
 * The original "domain" itself is destroyed and may not be used
 * after a call to this function.
 */
CloogDomain *cloog_domain_simplify_union(CloogDomain *domain)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	return cloog_domain_from_isl_set(isl_set_coalesce(set));
}


/**
 * cloog_scattering_lazy_isscalar function:
 * this function returns 1 if the scattering dimension 'dimension' in the
 * scattering 'scatt' is constant.
 * If value is not NULL, then it is set to the constant value of dimension.
 */
int cloog_scattering_lazy_isscalar(CloogScattering *scatt, int dimension,
					cloog_int_t *value)
{
	isl_map *map = isl_map_from_cloog_scattering(scatt);
	return isl_map_fast_is_fixed(map, isl_dim_out, dimension, value);
}


/**
 * cloog_domain_lazy_isconstant function:
 * this function returns 1 if the dimension 'dimension' in the
 * domain 'domain' is constant.
 * If value is not NULL, then it is set to the constant value of dimension.
 */
int cloog_domain_lazy_isconstant(CloogDomain *domain, int dimension,
	cloog_int_t *value)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	return isl_set_fast_dim_is_fixed(set, dimension, value);
}


/**
 * cloog_scattering_erase_dimension function:
 * this function returns a CloogDomain structure builds from 'domain' where
 * we removed the dimension 'dimension' and every constraint involving this
 * dimension.
 */
CloogScattering *cloog_scattering_erase_dimension(CloogScattering *scattering,
						int dimension)
{
	isl_map *map = isl_map_from_cloog_scattering(scattering);
	map = isl_map_remove_dims(isl_map_copy(map), isl_dim_out, dimension, 1);
	return cloog_scattering_from_isl_map(map);
}

/**
 * cloog_domain_cube:
 * Construct and return a dim-dimensional cube, with values ranging
 * between min and max in each dimension.
 */
CloogDomain *cloog_domain_cube(CloogState *state,
				int dim, cloog_int_t min, cloog_int_t max)
{
	int i;
	struct isl_basic_set *cube;
	struct isl_basic_set *interval;
	struct isl_basic_set_list *list;

	if (dim == 0)
		return cloog_domain_universe(state, dim);

	interval = isl_basic_set_interval(state->backend->ctx, min, max);
	list = isl_basic_set_list_alloc(state->backend->ctx, dim);
	for (i = 0; i < dim; ++i)
		list = isl_basic_set_list_add(list, isl_basic_set_copy(interval));
	isl_basic_set_free(interval);
	cube = isl_basic_set_list_product(list);
	return cloog_domain_from_isl_set(isl_set_from_basic_set(cube));
}


/**
 * cloog_domain_scatter function:
 * This function add the scattering (scheduling) informations to a domain.
 */
CloogDomain *cloog_domain_scatter(CloogDomain *domain, CloogScattering *scatt)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	isl_map *map = isl_map_from_cloog_scattering(scatt);

	map = isl_map_reverse(isl_map_copy(map));
	map = isl_map_intersect_range(map, set);
	set = isl_set_flatten(isl_map_wrap(map));
	return cloog_domain_from_isl_set(set);
}

static int add_domain_from_map(__isl_take isl_map *map, void *user)
{
	isl_space *dim;
	const char *name;
	CloogDomain *domain;
	CloogScattering *scat;
	CloogUnionDomain **ud = (CloogUnionDomain **)user;

	dim = isl_map_get_space(map);
	name = isl_space_get_tuple_name(dim, isl_dim_in);
	domain = cloog_domain_from_isl_set(isl_map_domain(isl_map_copy(map)));
	scat = cloog_scattering_from_isl_map(map);
	*ud = cloog_union_domain_add_domain(*ud, name, domain, scat, NULL);
	isl_space_free(dim);

	return 0;
}

/**
 * Construct a CloogUnionDomain from an isl_union_map representing
 * a global scattering function.  The input is a mapping from different
 * spaces (different tuple names and possibly different dimensions)
 * to a common space.  The iteration domains are set to the domains
 * in each space.  The statement names are set to the names of the
 * spaces.  The parameter names of the result are set to those of
 * the input, but the iterator and scattering dimension names are
 * left unspecified.
 */
CloogUnionDomain *cloog_union_domain_from_isl_union_map(
	__isl_take isl_union_map *umap)
{
	int i;
	int nparam;
	isl_space *dim;
	CloogUnionDomain *ud;

	dim = isl_union_map_get_space(umap);
	nparam = isl_space_dim(dim, isl_dim_param);

	ud = cloog_union_domain_alloc(nparam);

	for (i = 0; i < nparam; ++i) {
		const char *s = isl_space_get_dim_name(dim, isl_dim_param, i);
		ud = cloog_union_domain_set_name(ud, CLOOG_PARAM, i, s);
	}
	isl_space_free(dim);

	if (isl_union_map_foreach_map(umap, &add_domain_from_map, &ud) < 0) {
		isl_union_map_free(umap);
		cloog_union_domain_free(ud);
		assert(0);
	}

	isl_union_map_free(umap);

	return ud;
}

static int count_same_name(__isl_keep isl_space *dim,
	enum isl_dim_type type, unsigned pos, const char *name)
{
	enum isl_dim_type t;
	unsigned p, s;
	int count = 0;
	int len = strlen(name);

	for (t = isl_dim_param; t <= type && t <= isl_dim_out; ++t) {
		s = t == type ? pos : isl_space_dim(dim, t);
		for (p = 0; p < s; ++p) {
			const char *n = isl_space_get_dim_name(dim, t, p);
			if (n && !strncmp(n, name, len))
				count++;
		}
	}
	return count;
}

static CloogUnionDomain *add_domain(__isl_take isl_set *set, CloogUnionDomain *ud)
{
	int i, nvar;
	isl_ctx *ctx;
	isl_space *dim;
	char buffer[20];
	const char *name;
	CloogDomain *domain;

	ctx = isl_set_get_ctx(set);
	dim = isl_set_get_space(set);
	name = isl_space_get_tuple_name(dim, isl_dim_set);
	set = isl_set_flatten(set);
	set = isl_set_set_tuple_name(set, NULL);
	domain = cloog_domain_from_isl_set(set);
	ud = cloog_union_domain_add_domain(ud, name, domain, NULL, NULL);

	nvar = isl_space_dim(dim, isl_dim_set);
	for (i = 0; i < nvar; ++i) {
		char *long_name = NULL;
		int n;

		name = isl_space_get_dim_name(dim, isl_dim_set, i);
		if (!name) {
			snprintf(buffer, sizeof(buffer), "i%d", i);
			name = buffer;
		}
		n = count_same_name(dim, isl_dim_set, i, name);
		if (n) {
			int size = strlen(name) + 10;
			long_name = isl_alloc_array(ctx, char, size);
			if (!long_name)
				cloog_die("memory overflow.\n");
			snprintf(long_name, size, "%s_%d", name, n);
			name = long_name;
		}
		ud = cloog_union_domain_set_name(ud, CLOOG_ITER, i, name);
		free(long_name);
	}
	isl_space_free(dim);

	return ud;
}

/**
 * Construct a CloogUnionDomain from an isl_set.
 * The statement names are set to the names of the
 * spaces.  The parameter and iterator names of the result are set to those of
 * the input, but the scattering dimension names are left unspecified.
 */
CloogUnionDomain *cloog_union_domain_from_isl_set(
	__isl_take isl_set *set)
{
	int i;
	int nparam;
	isl_space *dim;
	CloogUnionDomain *ud;

	dim = isl_set_get_space(set);
	nparam = isl_space_dim(dim, isl_dim_param);

	ud = cloog_union_domain_alloc(nparam);

	for (i = 0; i < nparam; ++i) {
		const char *s = isl_space_get_dim_name(dim, isl_dim_param, i);
		ud = cloog_union_domain_set_name(ud, CLOOG_PARAM, i, s);
	}
	isl_space_free(dim);

	ud = add_domain(set, ud);

	return ud;
}

/* Computes x, y and g such that g = gcd(a,b) and a*x+b*y = g */
static void Euclid(cloog_int_t a, cloog_int_t b,
			cloog_int_t *x, cloog_int_t *y, cloog_int_t *g)
{
	cloog_int_t c, d, e, f, tmp;

	cloog_int_init(c);
	cloog_int_init(d);
	cloog_int_init(e);
	cloog_int_init(f);
	cloog_int_init(tmp);
	cloog_int_abs(c, a);
	cloog_int_abs(d, b);
	cloog_int_set_si(e, 1);
	cloog_int_set_si(f, 0);
	while (cloog_int_is_pos(d)) {
		cloog_int_tdiv_q(tmp, c, d);
		cloog_int_mul(tmp, tmp, f);
		cloog_int_sub(e, e, tmp);
		cloog_int_tdiv_q(tmp, c, d);
		cloog_int_mul(tmp, tmp, d);
		cloog_int_sub(c, c, tmp);
		cloog_int_swap(c, d);
	    cloog_int_swap(e, f);
	}
	cloog_int_set(*g, c);
	if (cloog_int_is_zero(a))
		cloog_int_set_si(*x, 0);
	else if (cloog_int_is_pos(a))
		cloog_int_set(*x, e);
	else cloog_int_neg(*x, e);
	if (cloog_int_is_zero(b))
		cloog_int_set_si(*y, 0);
	else {
		cloog_int_mul(tmp, a, *x);
		cloog_int_sub(tmp, c, tmp);
		cloog_int_divexact(*y, tmp, b);
	}
	cloog_int_clear(c);
	cloog_int_clear(d);
	cloog_int_clear(e);
	cloog_int_clear(f);
	cloog_int_clear(tmp);
}

/* Construct a CloogStride from the given constraint for the given level,
 * if possible.
 * We first compute the gcd of the coefficients of the existentially
 * quantified variables and then remove any common factors it has
 * with the coefficient at the given level.
 * The result is the value of the stride and if it is not one,
 * then it is possible to construct a CloogStride.
 * The constraint leading to the stride is stored in the CloogStride
 * as well a value (factor) such that the product of this value
 * and the coefficient at the given level is equal to -1 modulo the stride.
 */
static CloogStride *construct_stride(isl_constraint *c, int level)
{
	int i, n, sign;
	isl_int v, m, gcd, stride, factor;
	CloogStride *s;

	if (!c)
		return NULL;

	isl_int_init(v);
	isl_int_init(m);
	isl_int_init(gcd);
	isl_int_init(factor);
	isl_int_init(stride);

	isl_constraint_get_coefficient(c, isl_dim_set, level - 1, &v);
	sign = isl_int_sgn(v);
	isl_int_abs(m, v);

	isl_int_set_si(gcd, 0);
	n = isl_constraint_dim(c, isl_dim_div);
	for (i = 0; i < n; ++i) {
		isl_constraint_get_coefficient(c, isl_dim_div, i, &v);
		isl_int_gcd(gcd, gcd, v);
	}

	isl_int_gcd(v, m, gcd);
	isl_int_divexact(stride, gcd, v);

	if (isl_int_is_zero(stride) || isl_int_is_one(stride))
		s = NULL;
	else {
		Euclid(m, stride, &factor, &v, &gcd);
		if (sign > 0)
			isl_int_neg(factor, factor);

		c = isl_constraint_copy(c);
		s = cloog_stride_alloc_from_constraint(stride,
			    cloog_constraint_from_isl_constraint(c), factor);
	}

	isl_int_clear(stride);
	isl_int_clear(factor);
	isl_int_clear(gcd);
	isl_int_clear(m);
	isl_int_clear(v);

	return s;
}

struct cloog_isl_find_stride_data {
	int level;
	CloogStride *stride;
};

/* Check if the given constraint can be used to derive
 * a stride on the iterator identified by data->level.
 * We first check that there are some existentially quantified variables
 * and that the coefficient at data->level is non-zero.
 * Then we call construct_stride for further checks and the actual
 * construction of the CloogStride.
 */
static int find_stride(__isl_take isl_constraint *c, void *user)
{
	struct cloog_isl_find_stride_data *data;
	int n;
	isl_int v;

	data = (struct cloog_isl_find_stride_data *)user;

	if (data->stride) {
		isl_constraint_free(c);
		return 0;
	}

	n = isl_constraint_dim(c, isl_dim_div);
	if (n == 0) {
		isl_constraint_free(c);
		return 0;
	}

	isl_int_init(v);

	isl_constraint_get_coefficient(c, isl_dim_set, data->level - 1, &v);
	if (!isl_int_is_zero(v))
		data->stride = construct_stride(c, data->level);

	isl_int_clear(v);

	isl_constraint_free(c);

	return 0;
}

/* Check if the given list of domains has a common stride on the given level.
 * If so, return a pointer to a CloogStride object.  If not, return NULL.
 *
 * We project out all later variables, take the union and compute
 * the affine hull of the union.  Then we check the (equality)
 * constraints in this affine hull for imposing a stride.
 */
CloogStride *cloog_domain_list_stride(CloogDomainList *list, int level)
{
	struct cloog_isl_find_stride_data data = { level, NULL };
	isl_set *set;
	isl_basic_set *aff;
	int first = level;
	int n;
	int r;

	set = isl_set_from_cloog_domain(list->domain);
	n = isl_set_dim(set, isl_dim_set) - first;
	set = isl_set_project_out(isl_set_copy(set), isl_dim_set, first, n);

	for (list = list->next; list; list = list->next) {
		isl_set *set_i = isl_set_from_cloog_domain(list->domain);
		n = isl_set_dim(set_i, isl_dim_set) - first;
		set_i = isl_set_project_out(isl_set_copy(set_i),
						isl_dim_set, first, n);
		set = isl_set_union(set, set_i);
	}
	aff = isl_set_affine_hull(set);

	r = isl_basic_set_foreach_constraint(aff, &find_stride, &data);
	assert(r == 0);

	isl_basic_set_free(aff);

	return data.stride;
}

struct cloog_can_unroll {
	int can_unroll;
	int level;
	isl_constraint *c;
	isl_set *set;
	isl_int *n;
};


/*
 * Check if the given lower bound can be used for unrolling
 * and, if so, return the unrolling factor/trip count in *v.
 * If the lower bound involves any existentially quantified
 * variables, we currently punt.
 * Otherwise we compute the maximal value of (i - ceil(l) + 1),
 * with l the given lower bound and i the iterator identified by level.
 */
static int is_valid_unrolling_lower_bound(struct cloog_can_unroll *ccu,
	__isl_keep isl_constraint *c, isl_int *v)
{
	unsigned n_div;
	isl_aff *aff;
	enum isl_lp_result res;

	n_div = isl_constraint_dim(c, isl_dim_div);
	if (isl_constraint_involves_dims(c, isl_dim_div, 0, n_div))
		return 0;

	aff = isl_constraint_get_bound(c, isl_dim_set, ccu->level - 1);
	aff = isl_aff_ceil(aff);
	aff = isl_aff_neg(aff);
	aff = isl_aff_add_coefficient_si(aff, isl_dim_in, ccu->level - 1, 1);
	res = isl_set_max(ccu->set, aff, v);
	isl_aff_free(aff);

	if (res == isl_lp_unbounded)
		return 0;

	assert(res == isl_lp_ok);

	cloog_int_add_ui(*v, *v, 1);

	return 1;
}


/* Check if we can unroll based on the given constraint.
 * Only lower bounds can be used.
 * Record it if it turns out to be usable and if we haven't recorded
 * any other constraint already.
 */
static int constraint_can_unroll(__isl_take isl_constraint *c, void *user)
{
	struct cloog_can_unroll *ccu = (struct cloog_can_unroll *)user;
	isl_int v;
	isl_int count;

	isl_int_init(v);
	isl_int_init(count);
	isl_constraint_get_coefficient(c, isl_dim_set, ccu->level - 1, &v);
	if (isl_int_is_pos(v) &&
	    is_valid_unrolling_lower_bound(ccu, c, &count) &&
	    (!ccu->c || isl_int_lt(count, *ccu->n))) {
		isl_constraint_free(ccu->c);
		ccu->c = isl_constraint_copy(c);
		isl_int_set(*ccu->n, count);
	}
	isl_int_clear(count);
	isl_int_clear(v);
	isl_constraint_free(c);

	return 0;
}


/* Check if we can unroll the domain at the current level.
 * If the domain is a union, we cannot.  Otherwise, we check the
 * constraints.
 */
static int basic_set_can_unroll(__isl_take isl_basic_set *bset, void *user)
{
	struct cloog_can_unroll *ccu = (struct cloog_can_unroll *)user;
	int r = 0;

	if (ccu->c || !ccu->can_unroll)
		ccu->can_unroll = 0;
	else {
		bset = isl_basic_set_remove_redundancies(bset);
		r = isl_basic_set_foreach_constraint(bset,
						&constraint_can_unroll, ccu);
	}
	isl_basic_set_free(bset);
	return r;
}


/* Check if we can unroll the given domain at the given level, and
 * if so, return the single lower bound in *lb and an upper bound
 * on the number of iterations in *n.
 * If we cannot unroll, return 0 and set *lb to NULL.
 *
 * We can unroll, if we can identify a lower bound on level
 * such that the number of iterations is bounded by a constant.
 */
int cloog_domain_can_unroll(CloogDomain *domain, int level, cloog_int_t *n,
	CloogConstraint **lb)
{
	isl_set *set = isl_set_from_cloog_domain(domain);
	struct cloog_can_unroll ccu = { 1, level, NULL, set, n };
	int r;

	*lb = NULL;
	r = isl_set_foreach_basic_set(set, &basic_set_can_unroll, &ccu);
	assert(r == 0);
	if (!ccu.c)
		ccu.can_unroll = 0;
	if (!ccu.can_unroll) {
		isl_constraint_free(ccu.c);
		return 0;
	}

	*lb = cloog_constraint_from_isl_constraint(ccu.c);

	return ccu.can_unroll;
}


/* Fix the iterator i at the given level to l + o,
 * where l is prescribed by the constraint lb and o is equal to offset.
 * In particular, if lb is the constraint
 *
 *	a i >= f(j)
 *
 * then l = ceil(f(j)/a).
 */
CloogDomain *cloog_domain_fixed_offset(CloogDomain *domain,
	int level, CloogConstraint *lb, cloog_int_t offset)
{
	isl_aff *aff;
	isl_set *set = isl_set_from_cloog_domain(domain);
	isl_constraint *c;
	isl_constraint *eq;

	c = cloog_constraint_to_isl(lb);
	aff = isl_constraint_get_bound(c, isl_dim_set, level - 1);
	aff = isl_aff_ceil(aff);
	aff = isl_aff_add_coefficient_si(aff, isl_dim_in, level - 1, -1);
	aff = isl_aff_add_constant(aff, offset);
	eq = isl_equality_from_aff(aff);
	set = isl_set_add_constraint(set, eq);

	return cloog_domain_from_isl_set(set);
}
