
    /*+-----------------------------------------------------------------**
     **                       OpenScop Library                          **
     **-----------------------------------------------------------------**
     **                           relation.c                            **
     **-----------------------------------------------------------------**
     **                   First version: 30/04/2008                     **
     **-----------------------------------------------------------------**

 
 *****************************************************************************
 * OpenScop: Structures and formats for polyhedral tools to talk together    *
 *****************************************************************************
 *    ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__,                *
 *    /   / /  //  //  //  // /   / /  //  //   / /  // /  /|,_,             *
 *   /   / /  //  //  //  // /   / /  //  //   / /  // /  / / /\             *
 *  |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/  \            *
 *  | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\  \ /\           *
 *  | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\          *
 *  | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \  \         *
 *  | P |n| l | = | s | t |=| = |d| = | = | = | |   |=| o | | \# \  \        *
 *  | H | | y |   | e | o | | = |l|   |   | = | |   | | G | |  \  \  \       *
 *  | I | |   |   | e |   | |   | |   |   |   | |   | |   | |   \  \  \      *
 *  | T | |   |   |   |   | |   | |   |   |   | |   | |   | |    \  \  \     *
 *  | E | |   |   |   |   | |   | |   |   |   | |   | |   | |     \  \  \    *
 *  | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | /      \* \  \   *
 *  | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/        \  \ /   *
 *  '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---'          '--'    *
 *                                                                           *
 * Copyright (C) 2008 University Paris-Sud 11 and INRIA                      *
 *                                                                           *
 * (3-clause BSD license)                                                    *
 * Redistribution and use in source  and binary forms, with or without       *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 * 3. The name of the author may not be used to endorse or promote products  *
 *    derived from this software without specific prior written permission.  *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR      *
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,          *
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  *
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     *
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       *
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  *
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         *
 *                                                                           *
 * OpenScop Library, a library to manipulate OpenScop formats and data       *
 * structures. Written by:                                                   *
 * Cedric Bastoul     <Cedric.Bastoul@u-psud.fr> and                         *
 * Louis-Noel Pouchet <Louis-Noel.pouchet@inria.fr>                          *
 *                                                                           *
 *****************************************************************************/


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include <osl/macros.h>
#include <osl/int.h>
#include <osl/util.h>
#include <osl/vector.h>
#include <osl/strings.h>
#include <osl/names.h>
#include <osl/relation.h>


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


/**
 * osl_relation_sprint_type function:
 * this function prints the textual type of an osl_relation_t structure into
 * a string, according to the OpenScop specification, and returns that string.
 * \param[in] relation The relation whose type has to be printed.
 * \return A string containing the relation type.
 */
static
char * osl_relation_sprint_type(osl_relation_p relation) {
  char * string = NULL;
  
  OSL_malloc(string, char *, OSL_MAX_STRING * sizeof(char));
  string[0] = '\0';

  if (relation != NULL) {
    switch (relation->type) {
      case OSL_UNDEFINED: {
        snprintf(string, OSL_MAX_STRING, OSL_STRING_UNDEFINED);
        break;
      }
      case OSL_TYPE_CONTEXT: {
        snprintf(string, OSL_MAX_STRING, OSL_STRING_CONTEXT);
        break;
      }
      case OSL_TYPE_DOMAIN: {
        snprintf(string, OSL_MAX_STRING, OSL_STRING_DOMAIN);
        break;
      }
      case OSL_TYPE_SCATTERING: {
        snprintf(string, OSL_MAX_STRING, OSL_STRING_SCATTERING);
        break;
      }
      case OSL_TYPE_READ: {
        snprintf(string, OSL_MAX_STRING, OSL_STRING_READ);
        break;
      }
      case OSL_TYPE_WRITE: {
        snprintf(string, OSL_MAX_STRING, OSL_STRING_WRITE);
        break;
      }
      case OSL_TYPE_MAY_WRITE: {
        snprintf(string, OSL_MAX_STRING, OSL_STRING_MAY_WRITE);
        break;
      }
      default: {
        OSL_warning("unknown relation type, "
                    "replaced with "OSL_STRING_UNDEFINED);
        snprintf(string, OSL_MAX_STRING, OSL_STRING_UNDEFINED);
      }
    }
  }

  return string;
}


/**
 * osl_relation_print_type function:
 * this function displays the textual type of an osl_relation_t structure into
 * a file (file, possibly stdout), according to the OpenScop specification.
 * \param[in] file     File where informations are printed.
 * \param[in] relation The relation whose type has to be printed.
 */
static
void osl_relation_print_type(FILE * file, osl_relation_p relation) {
  char * string = osl_relation_sprint_type(relation);
  fprintf(file, "%s", string);
  free(string);
}


/**
 * osl_relation_idump function:
 * this function displays a osl_relation_t structure (*relation) into a
 * file (file, possibly stdout) in a way that trends to be understandable.
 * It includes an indentation level (level) in order to work with others
 * idump functions.
 * \param[in] file     File where informations are printed.
 * \param[in] relation The relation whose information has to be printed.
 * \param[in] level    Number of spaces before printing, for each line.
 */
void osl_relation_idump(FILE * file, osl_relation_p relation, int level) {
  int i, j, first = 1;

  // Go to the right level.
  for (j = 0; j < level; j++)
    fprintf(file, "|\t");

  if (relation != NULL) {
    fprintf(file, "+-- osl_relation_t (");
    osl_relation_print_type(file, relation);
    fprintf(file, ", ");
    osl_int_dump_precision(file, relation->precision);
    fprintf(file, ")\n");
  }
  else {
    fprintf(file, "+-- NULL relation\n");
  }

  while (relation != NULL) {
    if (! first) {
      // Go to the right level.
      for (j = 0; j < level; j++)
        fprintf(file, "|\t");
      fprintf(file, "|   osl_relation_t (");
      osl_relation_print_type(file, relation);
      fprintf(file, ", ");
      osl_int_dump_precision(file, relation->precision);
      fprintf(file, ")\n");
    }
    else
      first = 0;

    // A blank line
    for(j = 0; j <= level; j++)
      fprintf(file, "|\t");
    fprintf(file, "%d %d %d %d %d %d\n",
            relation->nb_rows,        relation->nb_columns,
            relation->nb_output_dims, relation->nb_input_dims,
            relation->nb_local_dims,  relation->nb_parameters);

    // Display the relation.
    for (i = 0; i < relation->nb_rows; i++) {
      for (j = 0; j <= level; j++)
        fprintf(file, "|\t");

      fprintf(file, "[ ");

      for (j = 0; j < relation->nb_columns; j++) {
        osl_int_print(file, relation->precision, relation->m[i], j);
        fprintf(file, " ");
      }

      fprintf(file, "]\n");
    }

    relation = relation->next;

    // Next line.
    if (relation != NULL) {
      for (j = 0; j <= level; j++)
        fprintf(file, "|\t");
      fprintf(file, "|\n");
      for (j = 0; j <= level; j++)
        fprintf(file, "|\t");
      fprintf(file, "V\n");
    }
  }

  // The last line.
  for (j = 0; j <= level; j++)
    fprintf(file, "|\t");
  fprintf(file, "\n");
}


/**
 * osl_relation_dump function:
 * this function prints the content of a osl_relation_t structure
 * (*relation) into a file (file, possibly stdout).
 * \param[in] file     File where informations are printed.
 * \param[in] relation The relation whose information have to be printed.
 */
void osl_relation_dump(FILE * file, osl_relation_p relation) {
  osl_relation_idump(file, relation, 0);
}


/**
 * osl_relation_expression_element function:
 * this function returns a string containing the printing of a value (e.g.,
 * an iterator with its coefficient or a constant).
 * \param[in]     val       Address of the coefficient or constant value.
 * \param[in]     precision The precision of the value.
 * \param[in,out] first     Pointer to a boolean set to 1 if the current value
 *                          is the first of an expresion, 0 otherwise (maybe
 *                          updated).
 * \param[in]     cst       A boolean set to 1 if the value is a constant,
 *                          0 otherwise.
 * \param[in]     name      String containing the name of the element.
 * \return A string that contains the printing of a value.
 */
static
char * osl_relation_expression_element(void * val,
                                       int precision, int * first,
                                       int cst, char * name) {
  char * temp, * body, * sval;
 
  OSL_malloc(temp, char *, OSL_MAX_STRING * sizeof(char));
  OSL_malloc(body, char *, OSL_MAX_STRING * sizeof(char));
  OSL_malloc(sval, char *, OSL_MAX_STRING * sizeof(char));

  body[0] = '\0';
  sval[0] = '\0';

  // statements for the 'normal' processing.
  if (!osl_int_zero(precision, val, 0) && (!cst)) {
    if ((*first) || osl_int_neg(precision, val, 0)) {
      if (osl_int_one(precision, val, 0)) {         // case 1
        sprintf(sval, "%s", name);
      }
      else {
        if (osl_int_mone(precision, val, 0)) {      // case -1
          sprintf(sval, "-%s", name);
        }
	else {                                      // default case
	  osl_int_sprint(sval, precision, val, 0);
	  sprintf(temp, "*%s", name);
	  strcat(sval, temp);
        }
      }
      *first = 0;
    }
    else {
      if (osl_int_one(precision, val, 0)) {
        sprintf(sval, "+%s", name);
      }
      else {
        sprintf(sval, "+");
	osl_int_sprint_txt(temp, precision, val, 0);
	strcat(sval, temp);
	sprintf(temp, "*%s", name);
	strcat(sval, temp);
      }
    }
  }
  else {
    if (cst) {
      if ((osl_int_zero(precision, val, 0) && (*first)) ||
          (osl_int_neg(precision, val, 0)))
        osl_int_sprint_txt(sval, precision, val, 0);
      if (osl_int_pos(precision, val, 0)) {
        if (!(*first)) {
          sprintf(sval, "+");
          osl_int_sprint_txt(temp, precision, val, 0);
	  strcat(sval, temp);
	}
	else {
          osl_int_sprint_txt(sval, precision, val, 0);
        }
      }
    }
  }
  free(temp);
  free(body);

  return(sval);
}


/**
 * osl_relation_strings function:
 * this function creates a NULL-terminated array of strings from an
 * osl_names_t structure in such a way that the ith string is the "name"
 * corresponding to the ith column of the constraint matrix.
 * \param[in] relation The relation for which we need an array of names.
 * \param[in] names    The set of names for each element.
 * \return An array of strings with one string per constraint matrix column.
 */
static
char ** osl_relation_strings(osl_relation_p relation, osl_names_p names) {
  char ** strings;
  char temp[OSL_MAX_STRING];
  int i, offset, array_id;
  
  if ((relation == NULL) || (names == NULL)) {
    OSL_debug("no names or relation to build the name array");
    return NULL;
  }

  OSL_malloc(strings, char **, (relation->nb_columns + 1)*sizeof(char *));
  strings[relation->nb_columns] = NULL;

  // 1. Equality/inequality marker.
  OSL_strdup(strings[0], "e/i");
  offset = 1;

  // 2. Output dimensions.
  if (osl_relation_is_access(relation)) {
    // The first output dimension is the array name.
    array_id  = osl_relation_get_array_id(relation);
    OSL_strdup(strings[offset], names->arrays->string[array_id - 1]);
    // The other ones are the array dimensions [1]...[n]
    for (i = offset + 1; i < relation->nb_output_dims + offset; i++) {
      sprintf(temp, "[%d]", i - 1);
      OSL_strdup(strings[i], temp);
    }
  }
  else
  if (relation->type == OSL_TYPE_SCATTERING) {
    for (i = offset; i < relation->nb_output_dims + offset; i++) {
      OSL_strdup(strings[i], names->scatt_dims->string[i - offset]);
    }
  }
  else {
    for (i = offset; i < relation->nb_output_dims + offset; i++) {
      OSL_strdup(strings[i], names->iterators->string[i - offset]);
    }
  }
  offset += relation->nb_output_dims;

  // 3. Input dimensions.
  for (i = offset; i < relation->nb_input_dims + offset; i++)
    OSL_strdup(strings[i], names->iterators->string[i - offset]);
  offset += relation->nb_input_dims;

  // 4. Local dimensions.
  for (i = offset; i < relation->nb_local_dims + offset; i++)
    OSL_strdup(strings[i], names->local_dims->string[i - offset]);
  offset += relation->nb_local_dims;

  // 5. Parameters.
  for (i = offset; i < relation->nb_parameters + offset; i++)
    OSL_strdup(strings[i], names->parameters->string[i - offset]);
  offset += relation->nb_parameters;

  // 6. Scalar.
  OSL_strdup(strings[offset], "1");

  return strings;
}


/**
 * osl_relation_subexpression function:
 * this function returns a string corresponding to an affine (sub-)expression
 * stored at the "row"^th row of the relation pointed by "relation" between
 * the start and stop columns. Optionnaly it may oppose the whole expression.
 * \param[in] relation A set of linear expressions.
 * \param[in] row     The row corresponding to the expression.
 * \param[in] start   The first column for the expression (inclusive).
 * \param[in] stop    The last column for the expression (inclusive).
 * \param[in] oppose  Boolean set to 1 to negate the expression, 0 otherwise.
 * \param[in] strings Array of textual names of the various elements.
 * \return A string that contains the printing of an affine (sub-)expression.
 */
static
char * osl_relation_subexpression(osl_relation_p relation,
                                  int row, int start, int stop, int oppose,
                                  char ** strings) {
  int i, first = 1, constant;
  char * sval;
  char * sline;
  
  OSL_malloc(sline, char *, OSL_MAX_STRING * sizeof(char));
  sline[0] = '\0';

  // Create the expression. The constant is a special case.
  for (i = start; i <= stop; i++) {
    if (oppose) {
      osl_int_oppose(relation->precision,
                     relation->m[row], i, relation->m[row], i);
    }

    if (i == relation->nb_columns - 1)
      constant = 1;
    else
      constant = 0;

    sval = osl_relation_expression_element(
        osl_int_address(relation->precision, relation->m[row], i),
        relation->precision, &first, constant, strings[i]);
    
    if (oppose) {
      osl_int_oppose(relation->precision,
                     relation->m[row], i, relation->m[row], i);
    }
    strcat(sline, sval);
    free(sval);
  }

  return sline;
}


/**
 * osl_relation_expression function:
 * this function returns a string corresponding to an affine expression
 * stored at the "row"^th row of the relation pointed by "relation".
 * \param[in] relation A set of linear expressions.
 * \param[in] row     The row corresponding to the expression.
 * \param[in] strings Array of textual names of the various elements.
 * \return A string that contains the printing of an affine expression.
 */
char * osl_relation_expression(osl_relation_p relation,
                               int row, char ** strings) {

  return osl_relation_subexpression(relation, row,
                                    1, relation->nb_columns - 1, 0,
                                    strings);
}


/**
 * osl_relation_is_simple_output function:
 * this function returns 1 or -1 if a given constraint row of a relation
 * corresponds to an output, 0 otherwise. We call a simple output an equality
 * constraint where exactly one output coefficient is not 0 and is either
 * 1 (in this case the function returns 1) or -1 (in this case the function
 * returns -1). 
 * \param[in] relation The relation to test for simple output.
 * \param[in] row      The row corresponding to the constraint to test.
 * \return 1 or -1 if the row is a simple output, 0 otherwise.
 */
static
int osl_relation_is_simple_output(osl_relation_p relation, int row) {
  int i;
  int first = 1;
  int sign  = 0;

  if ((relation == NULL) ||
      (relation->m == NULL) ||
      (relation->nb_output_dims == 0))
    return 0;

  if ((row < 0) || (row > relation->nb_rows))
    OSL_error("the specified row does not exist in the relation");

  // The constraint must be an equality.
  if (!osl_int_zero(relation->precision, relation->m[row], 0))
    return 0;

  // Check the output part has one and only one non-zero +1 or -1 coefficient.
  first = 1;
  for (i = 1; i <= relation->nb_output_dims; i++) {
    if (!osl_int_zero(relation->precision, relation->m[row], i)) {
      if (first)
        first = 0;
      else
        return 0;

      if (osl_int_one(relation->precision, relation->m[row], i))
        sign = 1;
      else if (osl_int_mone(relation->precision, relation->m[row], i))
        sign = -1;
      else
        return 0;
    }
  }

  return sign;
}


/**
 * osl_relation_sprint_comment function:
 * this function prints into a string a comment corresponding to a constraint
 * of a relation, according to its type, then it returns this string. This
 * function does not check that printing the comment is possible (i.e., are
 * there enough names ?), hence it is the responsibility of the user to ensure
 * he/she can call this function safely.
 * \param[in] relation The relation for which a comment has to be printed.
 * \param[in] row      The constrain row for which a comment has to be printed.
 * \param[in] strings  Array of textual names of the various elements.
 * \return A string which contains the comment for the row.
 */ 
static
char * osl_relation_sprint_comment(osl_relation_p relation,
                                   int row, char ** strings) {
  int sign;
  int high_water_mark = OSL_MAX_STRING;
  char * string = NULL;
  char * expression;
  char buffer[OSL_MAX_STRING];

  OSL_malloc(string, char *, high_water_mark * sizeof(char));
  string[0] = '\0';
  
  if ((relation == NULL) || (strings == NULL)) {
    OSL_debug("no relation or names while asked to print a comment");
    return string;
  }
  
  if ((sign = osl_relation_is_simple_output(relation, row))) {
    // First case : output == expression.

    expression = osl_relation_subexpression(relation, row,
                                            1, relation->nb_output_dims,
                                            sign < 0,
                                            strings);
    snprintf(buffer, OSL_MAX_STRING, "   ## %s", expression);
    osl_util_safe_strcat(&string, buffer, &high_water_mark);
    free(expression);
    
    // We don't print the right hand side if it's an array identifier.
    if (!osl_relation_is_access(relation) ||
        osl_int_zero(relation->precision, relation->m[row], 1)) {
      expression = osl_relation_subexpression(relation, row,
                                              relation->nb_output_dims + 1,
                                              relation->nb_columns - 1,
                                              sign > 0,
                                              strings);
      snprintf(buffer, OSL_MAX_STRING, " == %s", expression);
      osl_util_safe_strcat(&string, buffer, &high_water_mark);
      free(expression);
    }
  }
  else {
    // Second case : general case.
    
    expression = osl_relation_expression(relation, row, strings);
    snprintf(buffer, OSL_MAX_STRING, "   ## %s", expression);
    osl_util_safe_strcat(&string, buffer, &high_water_mark);
    free(expression);
    
    if (osl_int_zero(relation->precision, relation->m[row], 0))
      snprintf(buffer, OSL_MAX_STRING, " == 0");
    else
      snprintf(buffer, OSL_MAX_STRING, " >= 0");
    osl_util_safe_strcat(&string, buffer, &high_water_mark);
  }

  return string;
}


/**
 * osl_relation_column_string function:
 * this function returns an OpenScop comment string showing all column
 * names. It is designed to nicely fit a constraint matrix that would be
 * printed just below this line.
 * \param[in] relation The relation related to the comment line to build.
 * \param[in] strings  Array of textual names of the various elements.
 * \return A fancy comment string with all the dimension names.
 */
static
char * osl_relation_column_string(osl_relation_p relation, char ** strings) {
  int i, j;
  int index_output_dims;
  int index_input_dims;
  int index_local_dims;
  int index_parameters;
  int index_scalar;
  int space, length, left, right;
  char * scolumn;
  char temp[OSL_MAX_STRING];

  OSL_malloc(scolumn, char *, OSL_MAX_STRING);
 
  index_output_dims = 1;
  index_input_dims  = index_output_dims + relation->nb_output_dims;
  index_local_dims  = index_input_dims  + relation->nb_input_dims;
  index_parameters  = index_local_dims  + relation->nb_local_dims;
  index_scalar      = index_parameters  + relation->nb_parameters;

  // 1. The comment part.
  sprintf(scolumn, "#");
  for (j = 0; j < (OSL_FMT_LENGTH - 1)/2 - 1; j++)
    strcat(scolumn, " ");

  i = 0;
  while (strings[i] != NULL) {
    space  = OSL_FMT_LENGTH;
    length = (space > strlen(strings[i])) ? strlen(strings[i]) : space;
    right  = (space - length + (OSL_FMT_LENGTH % 2)) / 2;
    left   = space - length - right;

    // 2. Spaces before the name
    for (j = 0; j < left; j++)
      strcat(scolumn, " ");

    // 3. The (abbreviated) name
    for (j = 0; j < length - 1; j++) {
      sprintf(temp, "%c", strings[i][j]);
      strcat(scolumn, temp);
    }
    if (length >= strlen(strings[i]))
      sprintf(temp, "%c", strings[i][j]);
    else 
      sprintf(temp, ".");
    strcat(scolumn, temp);

    // 4. Spaces after the name
    for (j = 0; j < right; j++)
      strcat(scolumn, " ");
    
    i++;
    if ((i == index_output_dims) ||
        (i == index_input_dims)  ||
        (i == index_local_dims)  ||
        (i == index_parameters)  ||
        (i == index_scalar))
      strcat(scolumn, "|");
    else
      strcat(scolumn, " ");
  }
  strcat(scolumn, "\n");

  return scolumn;
}


/**
 * osl_relation_names function:
 * this function generates as set of names for all the dimensions
 * involved in a given relation.
 * \param[in] relation The relation we have to generate names for.
 * \return A set of generated names for the input relation dimensions.
 */
static
osl_names_p osl_relation_names(osl_relation_p relation) {
  int nb_parameters = OSL_UNDEFINED;
  int nb_iterators  = OSL_UNDEFINED;
  int nb_scattdims  = OSL_UNDEFINED;
  int nb_localdims  = OSL_UNDEFINED;
  int array_id      = OSL_UNDEFINED;

  osl_relation_get_attributes(relation, &nb_parameters, &nb_iterators,
                              &nb_scattdims, &nb_localdims, &array_id);
  
  return osl_names_generate("P", nb_parameters,
                            "i", nb_iterators,
                            "c", nb_scattdims,
                            "l", nb_localdims,
                            "A", array_id);
}


/**
 * osl_relation_nb_components function:
 * this function returns the number of component in the union of relations
 * provided as parameter.
 * \param[in] relation The input union of relations.
 * \return The number of components in the input union of relations.
 */
int osl_relation_nb_components(osl_relation_p relation) {
  int nb_components = 0;
  
  while (relation != NULL) {
    nb_components++;
    relation = relation->next;
  }

  return nb_components;
}


/**
 * osl_relation_spprint_polylib function:
 * this function pretty-prints the content of an osl_relation_t structure
 * (*relation) into a string in the extended polylib format, and returns this
 * string. This format is the same as OpenScop's, minus the type.
 * \param[in] relation The relation whose information has to be printed.
 * \param[in] names    The names of the constraint columns for comments.
 * \return A string containing the relation pretty-printing.
 */
char * osl_relation_spprint_polylib(osl_relation_p relation,
                                    osl_names_p names) {
  int i, j;
  int part, nb_parts;
  int generated_names = 0;
  int high_water_mark = OSL_MAX_STRING;
  char * string = NULL;
  char buffer[OSL_MAX_STRING];
  char ** name_array = NULL;
  char * scolumn;
  char * comment;

  if (relation == NULL)
    return strdup("# NULL relation\n");

  OSL_malloc(string, char *, high_water_mark * sizeof(char));
  string[0] = '\0';

  // Generates the names for the comments if necessary.
  if (names == NULL) {
    generated_names = 1;
    names = osl_relation_names(relation);
  }

  nb_parts = osl_relation_nb_components(relation);

  if (nb_parts > 1) {
    snprintf(buffer, OSL_MAX_STRING, "# Union with %d parts\n%d\n",
             nb_parts, nb_parts);
    osl_util_safe_strcat(&string, buffer, &high_water_mark);
  }

  // Print each part of the union.
  for (part = 1; part <= nb_parts; part++) {
    // Prepare the array of strings for comments.
    name_array = osl_relation_strings(relation, names);

    if (nb_parts > 1) {
      snprintf(buffer, OSL_MAX_STRING, "# Union part No.%d\n", part);
      osl_util_safe_strcat(&string, buffer, &high_water_mark);
    }

    snprintf(buffer, OSL_MAX_STRING, "%d %d %d %d %d %d\n",
             relation->nb_rows,        relation->nb_columns,
             relation->nb_output_dims, relation->nb_input_dims,
             relation->nb_local_dims,  relation->nb_parameters);
    osl_util_safe_strcat(&string, buffer, &high_water_mark);

    if (relation->nb_rows > 0) {
      scolumn = osl_relation_column_string(relation, name_array);
      snprintf(buffer, OSL_MAX_STRING, "%s", scolumn);
      osl_util_safe_strcat(&string, buffer, &high_water_mark);
      free(scolumn);
    }

    for (i = 0; i < relation->nb_rows; i++) {
      for (j = 0; j < relation->nb_columns; j++) {
        osl_int_sprint(buffer, relation->precision, relation->m[i], j);
        osl_util_safe_strcat(&string, buffer, &high_water_mark);
        snprintf(buffer, OSL_MAX_STRING, " ");
        osl_util_safe_strcat(&string, buffer, &high_water_mark);
      }

      if (name_array != NULL) {
        comment = osl_relation_sprint_comment(relation, i, name_array);
        osl_util_safe_strcat(&string, comment, &high_water_mark);
        free(comment);
      }
      snprintf(buffer, OSL_MAX_STRING, "\n");
      osl_util_safe_strcat(&string, buffer, &high_water_mark);
    }

    // Free the array of strings.
    if (name_array != NULL) {
      for (i = 0; i < relation->nb_columns; i++)
        free(name_array[i]);
      free(name_array);
    }

    relation = relation->next;
  }
  
  if (generated_names)
    osl_names_free(names);

  return string;
}


/**
 * osl_relation_spprint function:
 * this function pretty-prints the content of an osl_relation_t structure
 * (*relation) into a string in the OpenScop format, and returns this string.
 * \param[in] relation The relation whose information has to be printed.
 * \param[in] names    The names of the constraint columns for comments.
 * \return A string 
 */
char * osl_relation_spprint(osl_relation_p relation, osl_names_p names) {
  int high_water_mark = OSL_MAX_STRING;
  char * string = NULL;
  char * temp;
  char buffer[OSL_MAX_STRING];
  OSL_malloc(string, char *, high_water_mark * sizeof(char));
  string[0] = '\0';

  if (osl_relation_nb_components(relation) > 0) {
    temp = osl_relation_sprint_type(relation);
    osl_util_safe_strcat(&string, temp, &high_water_mark);
    free(temp);
    
    snprintf(buffer, OSL_MAX_STRING, "\n");
    osl_util_safe_strcat(&string, buffer, &high_water_mark);

    temp = osl_relation_spprint_polylib(relation, names);
    osl_util_safe_strcat(&string, temp, &high_water_mark);
    free(temp);
  }

  return string;
}


/**
 * osl_relation_pprint function:
 * this function pretty-prints the content of an osl_relation_t structure
 * (*relation) into a file (file, possibly stdout) in the OpenScop format.
 * \param[in] file     File where informations are printed.
 * \param[in] relation The relation whose information has to be printed.
 * \param[in] names    The names of the constraint columns for comments. 
 */
void osl_relation_pprint(FILE * file, osl_relation_p relation,
                         osl_names_p names) {
  char * string = osl_relation_spprint(relation, names);
  fprintf(file, "%s", string);
  free(string);
}


/**
 * osl_relation_print function:
 * this function prints the content of an osl_relation_t structure
 * (*relation) into a file (file, possibly stdout) in the OpenScop format.
 * \param[in] file     File where informations are printed.
 * \param[in] relation The relation whose information has to be printed.
 */
void osl_relation_print(FILE * file, osl_relation_p relation) {

  osl_relation_pprint(file, relation, NULL);
}


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


/**
 * osl_relation_read_type function:
 * this function reads a textual relation type and returns its integer
 * counterpart.
 * \param[in] file The input stream.
 * \return The relation type.
 */
static
int osl_relation_read_type(FILE * file) {
  int type;
  osl_strings_p strings;
  
  strings = osl_strings_read(file);
  if (osl_strings_size(strings) > 1) {
    OSL_warning("uninterpreted information (after the relation type)");
  }
  if (osl_strings_size(strings) == 0)
    OSL_error("no relation type");
 
  if (!strcmp(strings->string[0], OSL_STRING_UNDEFINED)) {
    type = OSL_UNDEFINED;
    goto return_type;
  }

  if (!strcmp(strings->string[0], OSL_STRING_CONTEXT)) {
    type = OSL_TYPE_CONTEXT; 
    goto return_type;
  }

  if (!strcmp(strings->string[0], OSL_STRING_DOMAIN)) {
    type = OSL_TYPE_DOMAIN; 
    goto return_type;
  }

  if (!strcmp(strings->string[0], OSL_STRING_SCATTERING)) {
    type = OSL_TYPE_SCATTERING; 
    goto return_type;
  }

  if (!strcmp(strings->string[0], OSL_STRING_READ)) {
    type = OSL_TYPE_READ; 
    goto return_type;
  }

  if (!strcmp(strings->string[0], OSL_STRING_WRITE)) {
    type = OSL_TYPE_WRITE; 
    goto return_type;
  }

  if (!strcmp(strings->string[0], OSL_STRING_MAY_WRITE)) {
    type = OSL_TYPE_MAY_WRITE; 
    goto return_type;
  }

  OSL_error("relation type not supported");

return_type:
  osl_strings_free(strings);
  return type;
}


/**
 * osl_relation_pread function ("precision read"):
 * this function reads a relation into a file (foo, posibly stdin) and
 * returns a pointer this relation. The relation is set to the maximum
 * available precision.
 * \param[in] foo       The input stream.
 * \param[in] precision The precision of the relation elements.
 * \return A pointer to the relation structure that has been read.
 */
osl_relation_p osl_relation_pread(FILE * foo, int precision) {
  int i, j, k, n, read = 0;
  int nb_rows, nb_columns;
  int nb_output_dims, nb_input_dims, nb_local_dims, nb_parameters;
  int nb_union_parts = 1;
  int may_read_nb_union_parts = 1;
  int read_attributes = 1;
  int first = 1;
  int type;
  char * c, s[OSL_MAX_STRING], str[OSL_MAX_STRING], *tmp;
  osl_relation_p relation, relation_union = NULL, previous = NULL;

  type = osl_relation_read_type(foo);

  // Read each part of the union (the number of parts may be updated inside)
  for (k = 0; k < nb_union_parts; k++) {
    // Read the number of union parts or the attributes of the union part
    while (read_attributes) {
      read_attributes = 0;

      // Read relation attributes.
      c = osl_util_skip_blank_and_comments(foo, s);
      read = sscanf(c, " %d %d %d %d %d %d", &nb_rows, &nb_columns,
                                             &nb_output_dims, &nb_input_dims,
                                             &nb_local_dims, &nb_parameters);
    
      if (((read != 1) && (read != 6)) ||
          ((read == 1) && (may_read_nb_union_parts != 1)))
        OSL_error("not 1 or 6 integers on the first relation line");

      if (read == 1) {
        // Only one number means a union and is the number of parts.
        nb_union_parts = nb_rows;
        if (nb_union_parts < 1)
          OSL_error("negative nb of union parts");
        
        // Allow to read the properties of the first part of the union.
        read_attributes = 1;
      }

      may_read_nb_union_parts = 0;
    }

    // Allocate the union part and fill its properties.
    relation = osl_relation_pmalloc(precision, nb_rows, nb_columns);
    relation->type           = type;
    relation->nb_output_dims = nb_output_dims;
    relation->nb_input_dims  = nb_input_dims;
    relation->nb_local_dims  = nb_local_dims;
    relation->nb_parameters  = nb_parameters;

    // Read the matrix of constraints.
    for (i = 0; i < relation->nb_rows; i++) {
      c = osl_util_skip_blank_and_comments(foo, s);
      if (c == NULL)
        OSL_error("not enough rows");

      for (j = 0; j < relation->nb_columns; j++) {
        if (c == NULL || *c == '#' || *c == '\n')
          OSL_error("not enough columns");
        if (sscanf(c, "%s%n", str, &n) == 0)
          OSL_error("not enough rows");

        // TODO: remove this tmp (sread updates the pointer).
        tmp = str;
        osl_int_sread(&tmp, precision, relation->m[i], j);
        c += n;
      }
    }
    
    // Build the linked list of union parts.
    if (first == 1) {
      relation_union = relation;
      first = 0;
    }
    else {
      previous->next = relation;
    }

    previous = relation;
    read_attributes = 1;
  }

  return relation_union;
}


/**
 * osl_relation_read function:
 * this function is equivalent to osl_relation_pread() except that
 * the precision corresponds to the precision environment variable or
 * to the highest available precision if it is not defined.
 * \see{osl_relation_pread}
 */
osl_relation_p osl_relation_read(FILE * foo) {
  int precision = osl_util_get_precision();
  return osl_relation_pread(foo, precision);
}


/*+***************************************************************************
 *                    Memory allocation/deallocation function                *
 *****************************************************************************/


/**
 * osl_relation_pmalloc function:
 * (precision malloc) this function allocates the memory space for an
 * osl_relation_t structure and sets its fields with default values.
 * Then it returns a pointer to the allocated space.
 * \param[in] precision  The precision of the constraint matrix.
 * \param[in] nb_rows    The number of row of the relation to allocate.
 * \param[in] nb_columns The number of columns of the relation to allocate.
 * \return A pointer to an empty relation with fields set to default values
 *         and a ready-to-use constraint matrix.
 */
osl_relation_p osl_relation_pmalloc(int precision,
                                    int nb_rows, int nb_columns) {
  osl_relation_p relation;
  void ** p, * q;
  int i, j;

  OSL_malloc(relation, osl_relation_p, sizeof(osl_relation_t));
  relation->type           = OSL_UNDEFINED;
  relation->nb_rows        = nb_rows;
  relation->nb_columns     = nb_columns;
  relation->nb_output_dims = OSL_UNDEFINED;
  relation->nb_input_dims  = OSL_UNDEFINED;
  relation->nb_parameters  = OSL_UNDEFINED;
  relation->nb_local_dims  = OSL_UNDEFINED;
  relation->precision      = precision;
  
  if ((nb_rows == 0) || (nb_columns == 0) ||
      (nb_rows == OSL_UNDEFINED) || (nb_columns == OSL_UNDEFINED)) {
    relation->m = NULL;
  } 
  else {
    OSL_malloc(p, void **, nb_rows * sizeof(void *));
    OSL_malloc(q, void *,
                    nb_rows * nb_columns * osl_int_sizeof(precision));
    relation->m = p;
    for (i = 0; i < nb_rows; i++) {
      relation->m[i] = osl_int_address(precision, q, i * nb_columns);
      for (j = 0; j < nb_columns; j++)
        osl_int_init_set_si(precision, relation->m[i], j, 0);
    }
  }
 
  relation->next = NULL;

  return relation;
}


/**
 * osl_relation_malloc function:
 * this function is equivalent to osl_relation_pmalloc() except that
 * the precision corresponds to the precision environment variable or
 * to the highest available precision if it is not defined.
 * \see{osl_relation_pmalloc}
 */
osl_relation_p osl_relation_malloc(int nb_rows, int nb_columns) {
  int precision = osl_util_get_precision();
  return osl_relation_pmalloc(precision, nb_rows, nb_columns);
}


/**
 * osl_relation_free_inside function:
 * this function frees the allocated memory for the inside of a
 * osl_relation_t structure, i.e. only m.
 * \param[in] relation The pointer to the relation we want to free internals.
 */
void osl_relation_free_inside(osl_relation_p relation) {
  int i, nb_elements;
  void * p;

  if (relation == NULL)
    return;

  nb_elements = relation->nb_rows * relation->nb_columns;
  
  if (nb_elements > 0)
    p = relation->m[0];
  
  for (i = 0; i < nb_elements; i++)
    osl_int_clear(relation->precision, p, i);

  if (relation->m != NULL) {
    if (nb_elements > 0)
      free(relation->m[0]);
    free(relation->m);
  }
}


/**
 * osl_relation_free function:
 * this function frees the allocated memory for an osl_relation_t
 * structure.
 * \param[in] relation The pointer to the relation we want to free.
 */
void osl_relation_free(osl_relation_p relation) {
  osl_relation_p tmp;
  
  if (relation == NULL)
    return;

  while (relation != NULL) {
    tmp = relation->next;
    osl_relation_free_inside(relation);
    free(relation);
    relation = tmp;
  }
}


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


/**
 * osl_relation_nclone function:
 * this functions builds and returns a "hard copy" (not a pointer copy) of a
 * osl_relation_t data structure such that the clone is restricted to the
 * "n" first rows of the relation. This applies to all the parts in the case
 * of a relation union.
 * \param[in] relation The pointer to the relation we want to clone.
 * \param[in] n        The number of row of the relation we want to clone (the
 *                     special value -1 means "all the rows").
 * \return A pointer to the clone of the relation union restricted to the
 *         first n rows of constraint matrix for each part of the union.
 */
osl_relation_p osl_relation_nclone(osl_relation_p relation, int n) {
  int i, j;
  int first = 1, all_rows = 0;
  osl_relation_p clone = NULL, node, previous = NULL;

  if (n == -1)
    all_rows = 1;

  while (relation != NULL) {
    if (all_rows)
      n = relation->nb_rows;

    if (n > relation->nb_rows)
      OSL_error("not enough rows to clone in the relation");

    node = osl_relation_pmalloc(relation->precision, n, relation->nb_columns);
    node->type           = relation->type;
    node->nb_output_dims = relation->nb_output_dims;
    node->nb_input_dims  = relation->nb_input_dims;
    node->nb_local_dims  = relation->nb_local_dims;
    node->nb_parameters  = relation->nb_parameters;

    for (i = 0; i < n; i++)
      for (j = 0; j < relation->nb_columns; j++)
        osl_int_assign(relation->precision, node->m[i], j, relation->m[i], j);
  
    if (first) {
      first = 0;
      clone = node;
      previous = node;
    }
    else {
      previous->next = node;
      previous = previous->next;
    }

    relation = relation->next;
  }

  return clone;
}


/**
 * osl_relation_clone function:
 * this function builds and returns a "hard copy" (not a pointer copy) of an
 * osl_relation_t data structure (the full union of relation).
 * \param[in] relation The pointer to the relation we want to clone.
 * \return A pointer to the clone of the union of relations.
 */
osl_relation_p osl_relation_clone(osl_relation_p relation) {
  if (relation == NULL)
    return NULL;

  return osl_relation_nclone(relation, -1);
}


/**
 * osl_relation_replace_vector function:
 * this function replaces the "row"^th row of a relation "relation" with the
 * vector "vector". It directly updates the relation union part pointed
 * by "relation" and this part only.
 * \param[in,out] relation The relation we want to replace a row.
 * \param[in]     vector   The vector that will replace a row of the relation.
 * \param[in]     row      The row of the relation to be replaced.
 */
void osl_relation_replace_vector(osl_relation_p relation,
                                 osl_vector_p vector, int row) {
  int i;

  if ((relation == NULL) || (vector == NULL)     ||
      (relation->precision != vector->precision) ||
      (relation->nb_columns != vector->size)     ||
      (row >= relation->nb_rows) || (row < 0))
    OSL_error("vector cannot replace relation row");

  for (i = 0; i < vector->size; i++)
    osl_int_assign(relation->precision, relation->m[row], i, vector->v, i);
}


/**
 * osl_relation_add_vector function:
 * this function adds (meaning, +) a vector to the "row"^th row of a
 * relation "relation". It directly updates the relation union part pointed
 * by "relation" and this part only.
 * \param[in,out] relation The relation we want to add a vector to a row.
 * \param[in]     vector   The vector that will replace a row of the relation.
 * \param[in]     row      The row of the relation to add the vector.
 */
void osl_relation_add_vector(osl_relation_p relation,
                             osl_vector_p vector, int row) {
  int i;

  if ((relation == NULL) || (vector == NULL)     ||
      (relation->precision != vector->precision) ||
      (relation->nb_columns != vector->size)     ||
      (row >= relation->nb_rows) || (row < 0))
    OSL_error("vector cannot be added to relation");

  if (osl_int_get_si(relation->precision, relation->m[row], 0) == 0)
    osl_int_assign(relation->precision, relation->m[row], 0, vector->v, 0);

  for (i = 1; i < vector->size; i++)
    osl_int_add(relation->precision,
                relation->m[row], i, relation->m[row], i, vector->v, i);
}


/**
 * osl_relation_sub_vector function:
 * this function subtracts the vector "vector" to the "row"^th row of
 * a relation "relation. It directly updates the relation union part pointed
 * by "relation" and this part only.
 * \param[in,out] relation The relation where to subtract a vector to a row.
 * \param[in]     vector   The vector to subtract to a relation row.
 * \param[in]     row      The row of the relation to subtract the vector.
 */
void osl_relation_sub_vector(osl_relation_p relation,
                             osl_vector_p vector, int row) {
  int i;

  if ((relation == NULL) || (vector == NULL)     ||
      (relation->precision != vector->precision) ||
      (relation->nb_columns != vector->size)     ||
      (row >= relation->nb_rows) || (row < 0))
    OSL_error("vector cannot be subtracted to row");

  if (osl_int_get_si(relation->precision, relation->m[row], 0) == 0)
    osl_int_assign(relation->precision, relation->m[row], 0, vector->v, 0);

  for (i = 1; i < vector->size; i++)
    osl_int_sub(relation->precision,
                relation->m[row], i, relation->m[row], i, vector->v, i);
}


/**
 * osl_relation_insert_vector function:
 * this function inserts a new row corresponding to the vector "vector" to
 * the relation "relation" by inserting it at the "row"^th row. It directly
 * updates the relation union part pointed by "relation" and this part only.
 * If "vector" (or "relation") is NULL, the relation is left unmodified.
 * \param[in,out] relation The relation we want to extend.
 * \param[in]     vector   The vector that will be added relation.
 * \param[in]     row      The row where to insert the vector.
 */
void osl_relation_insert_vector(osl_relation_p relation,
                                osl_vector_p vector, int row) {
  osl_relation_p temp;

  temp = osl_relation_from_vector(vector);
  osl_relation_insert_constraints(relation, temp, row);
  osl_relation_free(temp);
}


/**
 * osl_relation_insert_blank_row function:
 * this function inserts a new row filled with zeros o an existing relation
 * union part (it only affects the first union part).
 * \param[in,out] relation The relation to add a row in.
 * \param[in]     row      The row where to insert the blank row.
 */
void osl_relation_insert_blank_row(osl_relation_p relation, int row) {
  osl_vector_p vector;

  if (relation != NULL) {
    vector = osl_vector_pmalloc(relation->precision, relation->nb_columns);
    osl_relation_insert_vector(relation, vector, row);
    osl_vector_free(vector);
  }
}


/**
 * osl_relation_insert_blank_column function:
 * this function inserts a new column filled with zeros to an existing
 * relation union part (it only affects the first union part). WARNING:
 * this function does not update the relation attributes.
 * \param[in,out] relation The relation to add a column in.
 * \param[in]     column   The column where to insert the blank column.
 */
void osl_relation_insert_blank_column(osl_relation_p relation, int column) {

  int i, j;
  osl_relation_p temp;

  if (relation == NULL)
    return;

  if ((column < 0) || (column > relation->nb_columns))
    OSL_error("bad column number");

  // We use a temporary relation just to reuse existing functions. Cleaner.
  temp = osl_relation_pmalloc(relation->precision,
                              relation->nb_rows, relation->nb_columns + 1);

  for (i = 0; i < relation->nb_rows; i++) {
    for (j = 0; j < column; j++)
      osl_int_assign(relation->precision, temp->m[i], j, relation->m[i], j);

    for (j = column; j < relation->nb_columns; j++)
      osl_int_assign(relation->precision, temp->m[i], j+1, relation->m[i], j);
  }

  osl_relation_free_inside(relation);

  // Replace the inside of relation.
  relation->nb_columns = temp->nb_columns;
  relation->m = temp->m;

  // Free the temp "shell".
  free(temp);
}


/**
 * osl_relation_from_vector function:
 * this function converts a vector "vector" to a relation with a single row
 * and returns a pointer to that relation.
 * \param[in] vector The vector to convert to a relation.
 * \return A pointer to a relation resulting from the vector conversion.
 */
osl_relation_p osl_relation_from_vector(osl_vector_p vector) {
  osl_relation_p relation;

  if (vector == NULL)
    return NULL;

  relation = osl_relation_pmalloc(vector->precision, 1, vector->size);
  osl_relation_replace_vector(relation, vector, 0);
  return relation;
}


/**
 * osl_relation_replace_constraints function:
 * this function replaces some rows of a relation "r1" with the rows of
 * the relation "r2". It begins at the "row"^th row of "r1". It directly
 * updates the relation union part pointed by "r1" and this part only.
 * \param[in,out] r1  The relation we want to change some rows.
 * \param[in]     r2  The relation containing the new rows.
 * \param[in]     row The first row of the relation r1 to be replaced.
 */
void osl_relation_replace_constraints(osl_relation_p r1,
                                      osl_relation_p r2, int row) {
  int i, j;

  if ((r1 == NULL) || (r2 == NULL)       ||
      (r1->precision != r2->precision)   ||
      (r1->nb_columns != r1->nb_columns) ||
      ((row + r2->nb_rows) > r1->nb_rows) || (row < 0))
    OSL_error("relation rows could not be replaced");

  for (i = 0; i < r2->nb_rows; i++)
    for (j = 0; j < r2->nb_columns; j++)
      osl_int_assign(r1->precision, r1->m[i+row], j, r2->m[i], j);
}


/**
 * osl_relation_insert_constraints function:
 * this function adds new rows corresponding to the relation "r1" to
 * the relation "r2" by inserting it at the "row"^th row. It directly
 * updates the relation union part pointed by "r1" and this part only.
 * If "r2" (or "r1") is NULL, the relation is left unmodified.
 * \param[in,out] r1  The relation we want to extend.
 * \param[in]     r2  The relation to be inserted.
 * \param[in]     row The row where to insert the relation
 */
void osl_relation_insert_constraints(osl_relation_p r1,
                                     osl_relation_p r2, int row) {
  int i, j;
  osl_relation_p temp;

  if ((r1 == NULL) || (r2 == NULL))
    return;

  if ((r1->nb_columns != r2->nb_columns) ||
      (r1->precision != r2->precision)   ||
      (row > r1->nb_rows) || (row < 0))
    OSL_error("constraints cannot be inserted");

  // We use a temporary relation just to reuse existing functions. Cleaner.
  temp = osl_relation_pmalloc(r1->precision,
                              r1->nb_rows + r2->nb_rows, r1->nb_columns);

  for (i = 0; i < row; i++)
    for (j = 0; j < r1->nb_columns; j++)
      osl_int_assign(r1->precision, temp->m[i], j, r1->m[i], j);

  osl_relation_replace_constraints(temp, r2, row);

  for (i = row + r2->nb_rows; i < r2->nb_rows + r1->nb_rows; i++)
    for (j = 0; j < r1->nb_columns; j++)
      osl_int_assign(r1->precision, temp->m[i], j, r1->m[i-r2->nb_rows], j);

  osl_relation_free_inside(r1);

  // Replace the inside of relation.
  r1->nb_rows = temp->nb_rows;
  r1->m = temp->m;

  // Free the temp "shell".
  free(temp);
}


/**
 * osl_relation_insert_columns function:
 * this function inserts new columns to an existing relation union part (it
 * only affects the first union part). The columns are copied out from the
 * matrix of an input relation which must have the convenient number of rows.
 * All columns of the input matrix are copied. WARNING: this function does not 
 * update the relation attributes of the modified matrix.
 * \param[in,out] relation The relation to add columns in.
 * \param[in]     insert   The relation containing the columns to add.
 * \param[in]     column   The column where to insert the new columns.
 */
void osl_relation_insert_columns(osl_relation_p relation,
                                 osl_relation_p insert, int column) {
  int i, j;
  osl_relation_p temp;

  if ((relation == NULL) || (insert == NULL))
    return;

  if ((relation->precision != insert->precision) ||
      (relation->nb_rows   != insert->nb_rows)   ||
      (column < 0) || (column > relation->nb_columns))
    OSL_error("columns cannot be inserted");

  // We use a temporary relation just to reuse existing functions. Cleaner.
  temp = osl_relation_pmalloc(relation->precision, relation->nb_rows,
                              relation->nb_columns + insert->nb_columns);

  for (i = 0; i < relation->nb_rows; i++) {
    for (j = 0; j < column; j++)
      osl_int_assign(relation->precision, temp->m[i], j, relation->m[i], j);

    for (j = column; j < column + insert->nb_columns; j++)
      osl_int_assign(relation->precision,
                     temp->m[i], j, insert->m[i], j - column);

    for (j = column + insert->nb_columns;
         j < insert->nb_columns + relation->nb_columns; j++)
      osl_int_assign(relation->precision,
                     temp->m[i], j, relation->m[i], j - insert->nb_columns);
  }

  osl_relation_free_inside(relation);

  // Replace the inside of relation.
  relation->nb_columns = temp->nb_columns;
  relation->m = temp->m;

  // Free the temp "shell".
  free(temp);
}


/**
 * osl_relation_concat_constraints function:
 * this function builds a new relation from two relations sent as
 * parameters. The new set of constraints is built as the concatenation
 * of the rows of the first elements of the two relation unions r1 and r2.
 * This means, there is no next field in the result.
 * \param[in] r1  The first relation.
 * \param[in] r2  The second relation.
 * \return A pointer to the relation resulting from the concatenation of
 *         the first elements of r1 and r2.
 */
osl_relation_p osl_relation_concat_constraints(
    osl_relation_p r1,
    osl_relation_p r2) {
  osl_relation_p new;

  if (r1 == NULL)
    return osl_relation_clone(r2);

  if (r2 == NULL)
    return osl_relation_clone(r1);

  if (r1->nb_columns != r2->nb_columns)
    OSL_error("incompatible sizes for concatenation");
  
  if (r1->next || r2->next)
    OSL_warning("relation concatenation is done on the first elements "
                     "of union only");

  new = osl_relation_pmalloc(r1->precision,
                             r1->nb_rows + r2->nb_rows, r1->nb_columns);
  osl_relation_replace_constraints(new, r1, 0);
  osl_relation_replace_constraints(new, r2, r1->nb_rows);

  return new;
}


/**
 * osl_relation_equal function:
 * this function returns true if the two relations provided as parameters
 * are the same, false otherwise.
 * \param[in] r1  The first relation.
 * \param[in] r2  The second relation.
 * \return 1 if r1 and r2 are the same (content-wise), 0 otherwise.
 */
int osl_relation_equal(osl_relation_p r1, osl_relation_p r2) {
  int i, j;

  while ((r1 != NULL) && (r2 != NULL)) {
    if (r1 == r2)
      return 1;

    if ((r1->type           != r2->type)           ||
        (r1->precision      != r2->precision)      ||
        (r1->nb_rows        != r2->nb_rows)        ||
        (r1->nb_columns     != r2->nb_columns)     ||
        (r1->nb_output_dims != r2->nb_output_dims) ||
        (r1->nb_input_dims  != r2->nb_input_dims)  ||
        (r1->nb_local_dims  != r2->nb_local_dims)  ||
        (r1->nb_parameters  != r2->nb_parameters))
      return 0;

    for (i = 0; i < r1->nb_rows; ++i)
      for (j = 0; j < r1->nb_columns; ++j)
        if (osl_int_ne(r1->precision, r1->m[i], j, r2->m[i], j))
          return 0;

    r1 = r1->next;
    r2 = r2->next;
  }
  
  if (((r1 == NULL) && (r2 != NULL)) || ((r1 != NULL) && (r2 == NULL)))
    return 0;
  
  return 1;
}


/**
 * osl_relation_check_attribute internal function:
 * This function checks whether an "actual" value is the same as an
 * "expected" value or not. If the expected value is set to
 * OSL_UNDEFINED, this function sets it to the "actual" value
 * and do not report a difference has been detected.
 * It returns 0 if a difference has been detected, 1 otherwise.
 * \param[in,out] expected Pointer to the expected value (the value is
 *                         modified if it was set to OSL_UNDEFINED).
 * \param[in]     actual   Value we want to check.
 * \return 0 if the values are not the same while the expected value was
 *         not OSL_UNDEFINED, 1 otherwise.
 */
static
int osl_relation_check_attribute(int * expected, int actual) {
  if (*expected != OSL_UNDEFINED) { 
    if ((actual != OSL_UNDEFINED) &&
        (actual != *expected)) {
      OSL_warning("unexpected atribute");
      return 0;
    }
  }
  else {
    *expected = actual;
  }

  return 1;
}


/**
 * osl_relation_check_nb_columns internal function:
 * This function checks that the number of columns of a relation
 * corresponds to some expected properties (setting an expected property to
 * OSL_UNDEFINED makes this function unable to detect a problem).
 * It returns 0 if the number of columns seems incorrect or 1 if no problem
 * has been detected.
 * \param[in] relation  The relation we want to check the number of columns.
 * \param[in] expected_nb_output_dims Expected number of output dimensions.
 * \param[in] expected_nb_input_dims  Expected number of input dimensions.
 * \param[in] expected_nb_parameters  Expected number of parameters.
 * \return 0 if the number of columns seems incorrect, 1 otherwise.
 */
static
int osl_relation_check_nb_columns(osl_relation_p relation,
                                  int expected_nb_output_dims,
                                  int expected_nb_input_dims,
                                  int expected_nb_parameters) {
  int expected_nb_local_dims, expected_nb_columns;
  
  if ((expected_nb_output_dims != OSL_UNDEFINED) &&
      (expected_nb_input_dims  != OSL_UNDEFINED) &&
      (expected_nb_parameters  != OSL_UNDEFINED)) {
    
    if (relation->nb_local_dims == OSL_UNDEFINED)
      expected_nb_local_dims = 0;
    else
      expected_nb_local_dims = relation->nb_local_dims;

    expected_nb_columns = expected_nb_output_dims +
                          expected_nb_input_dims  +
                          expected_nb_local_dims  +
                          expected_nb_parameters  +
                          2;
    
    if (expected_nb_columns != relation->nb_columns) {
      OSL_warning("unexpected number of columns");
      return 0;
    }
  }

  return 1;
}


/**
 * osl_relation_integrity_check function:
 * this function checks that a relation is "well formed" according to some
 * expected properties (setting an expected value to OSL_UNDEFINED means
 * that we do not expect a specific value) and what the relation is supposed
 * to represent. It returns 0 if the check failed or 1 if no problem has been
 * detected.
 * \param[in] relation      The relation we want to check.
 * \param[in] expected_type Semantics about this relation (domain, access...).
 * \param[in] expected_nb_output_dims Expected number of output dimensions.
 * \param[in] expected_nb_input_dims  Expected number of input dimensions.
 * \param[in] expected_nb_parameters  Expected number of parameters.
 * \return 0 if the integrity check fails, 1 otherwise.
 */
int osl_relation_integrity_check(osl_relation_p relation,
                                 int expected_type,
                                 int expected_nb_output_dims,
                                 int expected_nb_input_dims,
                                 int expected_nb_parameters) {
  int i;

  // Check the NULL case.
  if (relation == NULL) {
    if ((expected_nb_output_dims != OSL_UNDEFINED) ||
        (expected_nb_input_dims  != OSL_UNDEFINED) ||
        (expected_nb_parameters  != OSL_UNDEFINED)) {
      OSL_debug("NULL relation with some expected attibutes");
      //return 0;
    }

    return 1;
  }

  // Check the type.
  if (((expected_type != OSL_TYPE_ACCESS) &&
       (expected_type != relation->type)) ||
      ((expected_type == OSL_TYPE_ACCESS) &&
       (!osl_relation_is_access(relation)))) {
    OSL_warning("wrong type");
    osl_relation_dump(stderr, relation);
    return 0;
  }

  // Check that relations have no undefined atributes.
  if ((relation->nb_output_dims == OSL_UNDEFINED) ||
      (relation->nb_input_dims  == OSL_UNDEFINED) ||
      (relation->nb_local_dims  == OSL_UNDEFINED) ||
      (relation->nb_parameters  == OSL_UNDEFINED)) {
    OSL_warning("all attributes should be defined");
    osl_relation_dump(stderr, relation);
    return 0;
  }

  // Check that a context has actually 0 output dimensions.
  if ((relation->type == OSL_TYPE_CONTEXT) &&
      (relation->nb_output_dims != 0)) {
    OSL_warning("context without 0 as number of output dimensions");
    osl_relation_dump(stderr, relation);
    return 0;
  }

  // Check that a domain or a context has actually 0 input dimensions.
  if (((relation->type == OSL_TYPE_DOMAIN) ||
       (relation->type == OSL_TYPE_CONTEXT)) &&
      (relation->nb_input_dims != 0)) {
    OSL_warning("domain or context without 0 input dimensions");
    osl_relation_dump(stderr, relation);
    return 0;
  }

  // Check properties according to expected values (and if expected values
  // are undefined, define them with the first relation part properties).
  if (!osl_relation_check_attribute(&expected_nb_output_dims,
                                    relation->nb_output_dims) ||
      !osl_relation_check_attribute(&expected_nb_input_dims,
                                    relation->nb_input_dims)  ||
      !osl_relation_check_attribute(&expected_nb_parameters,
                                    relation->nb_parameters)) {
    osl_relation_dump(stderr, relation);
    return 0;
  }

  while (relation != NULL) {

    // Attributes (except the number of local dimensions) should be the same
    // in all parts of the union.
    if ((expected_nb_output_dims != relation->nb_output_dims) ||
        (expected_nb_input_dims  != relation->nb_input_dims)  ||
        (expected_nb_parameters  != relation->nb_parameters)) {
      OSL_warning("inconsistent attributes");
      osl_relation_dump(stderr, relation);
      return 0;
    }
   
    // Check whether the number of columns is OK or not.
    if (!osl_relation_check_nb_columns(relation,
                                       expected_nb_output_dims,
                                       expected_nb_input_dims,
                                       expected_nb_parameters)) {
      osl_relation_dump(stderr, relation);
      return 0;
    }

    // Check the first column. The first column of a relation part should be
    // made of 0 or 1 only.
    if ((relation->nb_rows > 0) && (relation->nb_columns > 0)) {
      for (i = 0; i < relation->nb_rows; i++) {
        if (!osl_int_zero(relation->precision, relation->m[i], 0) &&
            !osl_int_one(relation->precision, relation->m[i], 0)) {
          OSL_warning("first column of a relation is not "
                           "strictly made of 0 or 1");
          osl_relation_dump(stderr, relation);
          return 0;
        }
      }
    }

    // Array accesses must provide the array identifier.
    if ((osl_relation_is_access(relation)) &&
        (osl_relation_get_array_id(relation) == OSL_UNDEFINED)) {
      osl_relation_dump(stderr, relation);
      return 0;
    }

    relation = relation->next;
  }

  return 1;
}


/**
 * osl_relation_union function:
 * this function builds a new relation from two relations provided
 * as parameters. The new relation is built as an union of the
 * two relations: the list of constraint sets are linked together.
 * \param[in] r1 The first relation.
 * \param[in] r2 The second relation.
 * \return A new relation corresponding to the union of r1 and r2.
 */
osl_relation_p osl_relation_union(osl_relation_p r1,
                                  osl_relation_p r2) {
  osl_relation_p copy1, copy2, tmp;
  
  if ((r1 == NULL) && (r2 == NULL))
    return NULL;
  
  copy1 = osl_relation_clone(r1);
  copy2 = osl_relation_clone(r2);

  if ((r1 != NULL) && (r2 == NULL))
    return copy1;
    
  if ((r1 == NULL) && (r2 != NULL))
    return copy2;

  tmp = copy1;
  while (tmp->next != NULL)
    tmp = tmp->next;

  tmp->next = copy2;
  return copy1;
}


/**
 * osl_relation_set_attributes function:
 * this functions sets the attributes of a relation provided as a
 * parameter. It updates the relation directly.
 * \param[in,out] relation The relation to set the attributes.
 * \param[in]     nb_output_dims Number of output dimensions.
 * \param[in]     nb_input_dims  Number of input dimensions.
 * \param[in]     nb_local_dims  Number of local dimensions.
 * \param[in]     nb_parameters  Number of parameters.
 */
void osl_relation_set_attributes(osl_relation_p relation,
                                 int nb_output_dims, int nb_input_dims,
                                 int nb_local_dims,  int nb_parameters) {
  if (relation != NULL) {
    relation->nb_output_dims = nb_output_dims;
    relation->nb_input_dims  = nb_input_dims;
    relation->nb_local_dims  = nb_local_dims;
    relation->nb_parameters  = nb_parameters;
  }
}


/** 
 * osl_relation_set_type function:
 * this function sets the type of each relation union part in the relation
 * to the one provided as parameter.
 * \param relation The relation to set the type.
 * \param type     The type.
 */
void osl_relation_set_type(osl_relation_p relation, int type) {

  while (relation != NULL) {
    relation->type = type;
    relation = relation->next;
  }
}


/**
 * osl_relation_get_array_id function:
 * this function returns the array identifier in a relation with access type
 * It returns OSL_UNDEFINED if it is not able to find it (in particular
 * if there are irregularities in the relation).
 * \param[in] relation The relation where to find an array identifier.
 * \return The array identifier in the relation or OSL_UNDEFINED.
 */
int osl_relation_get_array_id(osl_relation_p relation) {
  int i;
  int first = 1;
  int array_id = OSL_UNDEFINED;
  int reference_array_id = OSL_UNDEFINED;
  int nb_array_id;
  int row_id = 0;
  int precision;

  if (relation == NULL)
    return OSL_UNDEFINED;
  
  if (!osl_relation_is_access(relation)) {
    OSL_warning("asked for an array id of non-array relation");
    return OSL_UNDEFINED;
  }
  
  while (relation != NULL) {
    precision = relation->precision;

    // There should be room to store the array identifier.
    if ((relation->nb_rows < 1) ||
        (relation->nb_columns < 3)) {
      OSL_warning("no array identifier in an access function");
      return OSL_UNDEFINED;
    }

    // Array identifiers are m[i][#columns -1] / m[i][1], with i the only row
    // where m[i][1] is not 0.
    // - check there is exactly one row such that m[i][1] is not 0,
    // - check the whole ith row if full of 0 except m[i][1] and the id,
    // - check that (m[i][#columns -1] % m[i][1]) == 0,
    // - check that (-m[i][#columns -1] / m[i][1]) > 0.
    nb_array_id = 0;
    for (i = 0; i < relation->nb_rows; i++) {
      if (!osl_int_zero(precision, relation->m[i], 1)) {
        nb_array_id ++;
        row_id = i;
      }
    }
    if (nb_array_id == 0) {
      OSL_warning("no array identifier in an access function");
      return OSL_UNDEFINED;
    }
    if (nb_array_id > 1) {
      OSL_warning("several array identifiers in one access function");
      return OSL_UNDEFINED;
    }
    for (i = 0; i < relation->nb_columns - 1; i++) {
      if ((i != 1) && !osl_int_zero(precision, relation->m[row_id], i)) {
        OSL_warning("non integer array identifier");
        return OSL_UNDEFINED;
      }
    }
    if (!osl_int_divisible(precision,
                           relation->m[row_id], relation->nb_columns - 1,
                           relation->m[row_id], 1)) {
      OSL_warning("rational array identifier");
      return OSL_UNDEFINED;
    }
    array_id = -osl_int_get_si(precision,
                               relation->m[row_id],
                               relation->nb_columns - 1);
    array_id /= osl_int_get_si(precision, relation->m[row_id], 1);
    if (array_id <= 0) {
      OSL_warning("negative or 0 identifier in access function");
      return OSL_UNDEFINED;
    }

    // Unions of accesses are allowed, but they should refer at the same array.
    if (first) {
      reference_array_id = array_id;
      first = 0;
    }
    else {
      if (reference_array_id != array_id) {
        OSL_warning("inconsistency of array identifiers in an "
                    "union of access relations");
        return OSL_UNDEFINED;
      }
    }
    
    relation = relation->next;
  }

  return array_id;
}


/**
 * osl_relation_is_access function:
 * this function returns 1 if the relation corresponds to an access relation,
 * whatever its precise type (read, write etc.), 0 otherwise.
 * \param relation The relation to check wheter it is an access relation or not.
 * \return 1 if the relation is an access relation, 0 otherwise.
 */
int osl_relation_is_access(osl_relation_p relation) {

  if (relation == NULL)
    return 0;
  
  if ((relation->type == OSL_TYPE_ACCESS)    ||
      (relation->type == OSL_TYPE_READ)      ||
      (relation->type == OSL_TYPE_WRITE)     ||
      (relation->type == OSL_TYPE_MAY_WRITE))
    return 1;

  return 0;
}


/**
 * osl_relation_get_attributes function:
 * this function returns, through its parameters, the maximum values of the
 * relation attributes (nb_iterators, nb_parameters etc), depending on its
 * type. HOWEVER, it updates the parameter value iff the attribute is greater
 * than the input parameter value. Hence it may be used to get the
 * attributes as well as to find the maximum attributes for several relations.
 * The array identifier 0 is used when there is no array identifier (AND this
 * is OK), OSL_UNDEFINED is used to report it is impossible to provide the
 * property while it should. This function is not intended for checking, the
 * input relation should be correct.
 * \param[in]     relation      The relation to extract attribute values.
 * \param[in,out] nb_parameters Number of parameter attribute.
 * \param[in,out] nb_iterators  Number of iterators attribute.
 * \param[in,out] nb_scattdims  Number of scattering dimensions attribute.
 * \param[in,out] nb_localdims  Number of local dimensions attribute.
 * \param[in,out] array_id      Maximum array identifier attribute.
 */
void osl_relation_get_attributes(osl_relation_p relation,
                                 int * nb_parameters,
                                 int * nb_iterators,
                                 int * nb_scattdims,
                                 int * nb_localdims,
                                 int * array_id) {
  int type;
  int local_nb_parameters = OSL_UNDEFINED;
  int local_nb_iterators  = OSL_UNDEFINED;
  int local_nb_scattdims  = OSL_UNDEFINED;
  int local_nb_localdims  = OSL_UNDEFINED;
  int local_array_id      = OSL_UNDEFINED;

  while (relation != NULL) {
    if (osl_relation_is_access(relation))
      type = OSL_TYPE_ACCESS;
    else
      type = relation->type;

    // There is some redundancy but I believe the code is cleaner this way.
    switch (type) {
      case OSL_TYPE_CONTEXT:
        local_nb_parameters = relation->nb_parameters;
        local_nb_iterators  = 0;
        local_nb_scattdims  = 0;
        local_nb_localdims  = relation->nb_local_dims;
        local_array_id      = 0;
        break;

      case OSL_TYPE_DOMAIN:
        local_nb_parameters = relation->nb_parameters;
        local_nb_iterators  = relation->nb_output_dims;
        local_nb_scattdims  = 0;
        local_nb_localdims  = relation->nb_local_dims;
        local_array_id      = 0;
        break;

      case OSL_TYPE_SCATTERING:
        local_nb_parameters = relation->nb_parameters;
        local_nb_iterators  = relation->nb_input_dims;
        local_nb_scattdims  = relation->nb_output_dims;
        local_nb_localdims  = relation->nb_local_dims;
        local_array_id      = 0;
        break;

      case OSL_TYPE_ACCESS:
        local_nb_parameters = relation->nb_parameters;
        local_nb_iterators  = relation->nb_input_dims;
        local_nb_scattdims  = 0;
        local_nb_localdims  = relation->nb_local_dims;
        local_array_id      = osl_relation_get_array_id(relation);
        break;
    }

    // Update.
    *nb_parameters = OSL_max(*nb_parameters, local_nb_parameters);
    *nb_iterators  = OSL_max(*nb_iterators,  local_nb_iterators);
    *nb_scattdims  = OSL_max(*nb_scattdims,  local_nb_scattdims);
    *nb_localdims  = OSL_max(*nb_localdims,  local_nb_localdims);
    *array_id      = OSL_max(*array_id,      local_array_id);
    relation = relation->next;
  }
}


/**
 * osl_relation_extend_output function:
 * this function extends the number of output dimensions of a given relation. It
 * returns a copy of the input relation with a number of output dimensions
 * extended to "dim" for all its union components. The new output dimensions
 * are simply set equal to 0. The extended number of dimensions must be higher
 * than or equal to the original one (an error will be raised otherwise).
 * \param[in] relation The input relation to extend.
 * \param[in] dim      The number of output dimension to reach.
 * \return A new relation: "relation" extended to "dim" output dims.
 */
osl_relation_p osl_relation_extend_output(osl_relation_p relation, int dim) {
  int i, j;
  int first = 1;
  int offset;
  osl_relation_p extended = NULL, node, previous = NULL;

  while (relation != NULL) {
    if (relation->nb_output_dims > dim)
      OSL_error("Number of output dims is greater than required extension");
    offset = dim - relation->nb_output_dims;
    
    node = osl_relation_pmalloc(relation->precision,
                                relation->nb_rows + offset,
                                relation->nb_columns + offset);
    
    node->type           = relation->type;
    node->nb_output_dims = OSL_max(relation->nb_output_dims, dim);
    node->nb_input_dims  = relation->nb_input_dims;
    node->nb_local_dims  = relation->nb_local_dims;
    node->nb_parameters  = relation->nb_parameters;

    // Copy of the original relation with some 0 columns for the new dimensions
    // Note that we use the fact that the matrix is initialized with zeros.
    for (i = 0; i < relation->nb_rows; i++) {
      for (j = 0; j <= relation->nb_output_dims; j++)
        osl_int_assign(relation->precision, node->m[i], j, relation->m[i], j);

      for (j = relation->nb_output_dims + offset + 1;
           j < relation->nb_columns + offset; j++)
        osl_int_assign(relation->precision,
                       node->m[i], j, relation->m[i], j - offset);
    }

    // New rows dedicated to the new dimensions
    for (i = relation->nb_rows; i < relation->nb_rows + offset; i++) {
      for (j = 0; j < relation->nb_columns + offset; j++) {
        if ((i - relation->nb_rows) == (j - relation->nb_output_dims - 1))
          osl_int_set_si(relation->precision, node->m[i], j, -1);
      }
    }

    if (first) {
      first = 0;
      extended = node;
      previous = node;
    }
    else {
      previous->next = node;
      previous = previous->next;
    }

    relation = relation->next;
  }
  
  return extended;
}

