PIPS
sc_normalize.c File Reference
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "linear_assert.h"
#include <limits.h>
#include "boolean.h"
#include "arithmetique.h"
#include "vecteur.h"
#include "contrainte.h"
#include "sc.h"
+ Include dependency graph for sc_normalize.c:

Go to the source code of this file.

Macros

#define MAX_NUMBER_OF_CONSTRAINTS   (x_max-x_min)
 
#define if_debug_sc_strong_normalize_2   if(false)
 
#define if_debug_sc_strong_normalize_and_check_feasibility2   if(false)
 

Functions

static void negate_value_interval (Value *pmin, Value *pmax)
 package sc More...
 
static void swap_values (Value *p1, Value *p2)
 
static void swap_value_intervals (Value *px_min, Value *px_max, Value *py_min, Value *py_max)
 
static void update_lower_or_upper_bound (Pvecteur *bound_p, Pvecteur *bound_base_p, Variable var, Value nb, bool lower_p)
 Bounding box (not really a box most of the time) More...
 
static bool update_lower_and_upper_bounds (Pvecteur *ubound_p, Pvecteur *ubound_base_p, Pvecteur *lbound_p, Pvecteur *lbound_base_p, Variable var, Value nb)
 Updates upper and lower bounds, (ubound_p, ubound_base_p) and (lbound_p, lbound_base_p), with equations var==nb. More...
 
static void simplify_constraint_with_bounding_box (Pcontrainte eq, Pbase cb, Pvecteur l, bool is_inequality_p __attribute__((unused)))
 Use constants imposed by the bounding box to eliminate constant terms from constraint eq. More...
 
static Pvecteur compute_x_and_y_bounds (Pvecteur v, Pvecteur l, Pvecteur lb, Pvecteur u, Pvecteur ub, Variable *px, Variable *py, Value *px_min, Value *px_max, int *pcb)
 v is supposed to be the equation of a line in a 2-D space. More...
 
static bool eligible_for_coefficient_reduction_with_bounding_box_p (Pvecteur v, Pvecteur l, Pvecteur lb, Pvecteur u, Pvecteur ub)
 Is it possible to reduce the magnitude of at least one constraint coefficient because it is larger than the intervals defined by the bounding box for the other variable? More...
 
static bool small_slope_and_first_quadrant_p (Pvecteur v)
 Check that the coefficients on the first and second variables, x and y, define a increasing line. More...
 
static Pvecteur new_constraint_for_coefficient_reduction_with_bounding_box (Pvecteur v, int *pcb, Variable x, Variable y, Value *px_min, Value *px_max, Value *py_min, Value *py_max)
 Compute a normalized version of the constraint v and the corresponding change of basis. More...
 
static Pvecteur vect_make_line (Variable x, Variable y, Value x0, Value y0, Value x1, Value y1)
 FI: Could be moved in vecteur library... More...
 
static bool find_first_integer_point_in_between (Value x0, Value y0, Pvecteur up_c, Pvecteur low_c, Variable xv, Variable yv, Value dx, Value dy, Value xf, Value yf __attribute__((unused)), Value *pfx, Value *pfy)
 Find the first significant integer point (*pfx, *pfy) starting from (x0,y0) moving by (dx,dy) steps towards (xf,yf) that is between the constraint up_c and low_c such that *pfx!=xf and pfx!=x0. More...
 
static bool find_integer_point_to_the_right (Value x0, Value y0, Pvecteur up, Pvecteur low, Variable x, Variable y, Value xf, Value yf, Value *pfx, Value *pfy)
 
static bool find_integer_point_to_the_left (Value x0, Value y0, Pvecteur up, Pvecteur low, Variable x, Variable y, Value xf, Value yf, Value *pfx, Value *pfy)
 
static Value eval_2D_vecteur (Pvecteur v, Variable x, Variable y, Value xv, Value yv)
 FI: a bit too specific for vecteur library? More...
 
static Pcontrainte build_convex_constraints_from_vertices (Variable x, Variable y, int ni, int eni, Value ilmpx[ni+2], Value ilmpy[ni+2])
 Use the first eni+2 points in ilmpx and ilmpy to build at most eni+1 convex constraints, all upper bounds for y. More...
 
Pcontrainte find_intermediate_constraints_recursively (Pvecteur v, Variable x, Variable y, Value lmpx, Value lmpy, Value rmpx, Value rmpy)
 Find a set ineq of 2-D constraints equivalent to 2-D constraint v==ax+by+c over the interval [lmpx,rmpx]. More...
 
Pcontrainte find_intermediate_constraints (Pvecteur v, Variable x, Variable y, Value lmpx, Value lmpy, Value rmpx, Value rmpy)
 Find a set ineq of 2-D constraints equivalent to 2-D constraint v==ax+by+c over the interval [lmpx,rmpx]. More...
 
static Pcontrainte small_positive_slope_reduce_coefficients_with_bounding_box (Pvecteur v, Variable x, Value x_min, Value x_max, Variable y, Value y_min __attribute__((unused)), Value y_max __attribute__((unused)))
 Replace 2-D constraint v by a set of constraints when possible because variable x is bounded by [x_min,x_max]. More...
 
static void update_coefficient_signs_in_vector (Pvecteur v, int cb, Variable x, Variable y)
 Perform a reverse change of base to go back into the source code frame. More...
 
static void update_coefficient_signs_in_constraints (Pcontrainte eq, int cb, Variable x, Variable y, Value *x_min, Value *x_max, Value *y_min, Value *y_max)
 Perform the inverse change of basis and update the intervals for later checks. More...
 
static void check_coefficient_reduction (Pvecteur v, Pcontrainte ineq, Variable x, Variable y, Value x_min, Value x_max)
 debug function: check that all 2-D constraints c in ineq are equivalent to contraint v on interval [x_min,x_max]. More...
 
static Pcontrainte reduce_coefficients_with_bounding_box (Pvecteur v, Pvecteur l, Pvecteur lb, Pvecteur u, Pvecteur ub)
 If at least one of the coefficients of constraint v == ax+by<=c are greater that the intervals of the bounding box, reduce them to be at most the the size of the intervals. More...
 
static Psysteme add_bounding_box_constraints (Psysteme ps, Pbase cb, Pbase lb, Pbase ub, Pvecteur l, Pvecteur u)
 Add the constraints defined by cb, lb and ub in Psysteme ps. More...
 
Psysteme sc_bounded_normalization (Psysteme ps)
 Eliminate trivially redundant integer constraint using a O(n x d^2) algorithm, where n is the number of constraints and d the dimension. More...
 
Psysteme sc_normalize (Psysteme ps)
 Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires en nombres entiers ps, en place. More...
 
Psysteme sc_normalize2 (volatile Psysteme ps)
 Psysteme sc_normalize2(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires en nombres entiers ps, en place. More...
 
Psysteme sc_add_normalize_eq (Psysteme ps, Pcontrainte eq)
 
Psysteme sc_add_normalize_ineq (Psysteme ps, Pcontrainte ineq)
 
Psysteme sc_safe_normalize (Psysteme ps)
 Psysteme sc_safe_normalize(Psysteme ps) output : ps, normalized. More...
 
static Psysteme sc_rational_feasibility (Psysteme sc)
 
Psysteme sc_strong_normalize (Psysteme ps)
 Psysteme sc_strong_normalize(Psysteme ps) More...
 
Psysteme sc_strong_normalize3 (Psysteme ps)
 
Psysteme sc_strong_normalize_and_check_feasibility (volatile Psysteme ps, Psysteme(*check_feasibility)(Psysteme))
 
Psysteme sc_strong_normalize2 (volatile Psysteme ps)
 Psysteme sc_strong_normalize2(Psysteme ps) More...
 
Psysteme sc_strong_normalize4 (Psysteme ps, char *(*variable_name)(Variable))
 Psysteme sc_strong_normalize4(Psysteme ps, char * (*variable_name)(Variable)) More...
 
Psysteme sc_strong_normalize5 (Psysteme ps, char *(*variable_name)(Variable))
 
Psysteme sc_strong_normalize_and_check_feasibility2 (volatile Psysteme ps, Psysteme(*check_feasibility)(Psysteme), char *(*variable_name)(Variable), int level)
 Psysteme sc_strong_normalize_and_check_feasibility2 (Psysteme ps, Psysteme (*check_feasibility)(Psysteme), char * (*variable_name)(Variable), int level) More...
 
void sc_gcd_normalize (Psysteme ps)
 sc_gcd_normalize(ps) More...
 

Macro Definition Documentation

◆ if_debug_sc_strong_normalize_2

#define if_debug_sc_strong_normalize_2   if(false)

◆ if_debug_sc_strong_normalize_and_check_feasibility2

#define if_debug_sc_strong_normalize_and_check_feasibility2   if(false)

◆ MAX_NUMBER_OF_CONSTRAINTS

#define MAX_NUMBER_OF_CONSTRAINTS   (x_max-x_min)

Function Documentation

◆ add_bounding_box_constraints()

static Psysteme add_bounding_box_constraints ( Psysteme  ps,
Pbase  cb,
Pbase  lb,
Pbase  ub,
Pvecteur  l,
Pvecteur  u 
)
static

Add the constraints defined by cb, lb and ub in Psysteme ps.

This is necessary when all constraints redundant wrt the bounding box are removed, for instance to detect simple equalities (x<=2 && x>=2) and to remove redundant constraints (x<=2 && x<=2).

add the equalities

Add the upper bounds

Add the lower bounds

Definition at line 1627 of file sc_normalize.c.

1629 {
1630  Pvecteur cv;
1633 
1634  /* add the equalities */
1635  for(cv=cb; !VECTEUR_UNDEFINED_P(cv); cv = vecteur_succ(cv)) {
1636  Variable x = vecteur_var(cv);
1637  Value b = vect_coeff(x, l); // u might be used as well
1638  Pcontrainte c = contrainte_make_1D(VALUE_ONE, x, b, true);
1639  contrainte_succ(c) = eq;
1640  eq = c;
1641  }
1642 
1643  /* Add the upper bounds */
1644  for(cv=ub; !VECTEUR_UNDEFINED_P(cv); cv = vecteur_succ(cv)) {
1645  Variable x = vecteur_var(cv);
1646  if(!base_contains_variable_p(cb,x)) {
1647  Value b = vect_coeff(x, u);
1648  Pcontrainte c = contrainte_make_1D(VALUE_ONE, x, b, true);
1649  contrainte_succ(c) = ineq;
1650  ineq = c;
1651  }
1652  }
1653 
1654  /* Add the lower bounds */
1655  for(cv=lb; !VECTEUR_UNDEFINED_P(cv); cv = vecteur_succ(cv)) {
1656  Variable x = vecteur_var(cv);
1657  if(!base_contains_variable_p(cb,x)) {
1658  Value b = vect_coeff(x, l);
1659  Pcontrainte c = contrainte_make_1D(VALUE_ONE, x, b, false);
1660  contrainte_succ(c) = ineq;
1661  ineq = c;
1662  }
1663  }
1664 
1665  sc_add_egalites(ps, eq);
1666  sc_add_inegalites(ps, ineq);
1667  assert(sc_consistent_p(ps));
1668  return ps;
1669 }
int Value
#define VALUE_ONE
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
#define contrainte_succ(c)
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_make_1D(Value a, Variable x, Value b, bool less_p)
Generate a constraint a x <= b or a x >= b, according to less_p, or ax==b, regardless of less_p.
Definition: alloc.c:86
#define assert(ex)
Definition: newgen_assert.h:41
bool sc_consistent_p(Psysteme sc)
bool sc_consistent_p(Psysteme sc): check that sc is well defined, that the numbers of equalities and ...
Definition: sc.c:282
void sc_add_inegalites(Psysteme p, Pcontrainte i)
Definition: sc_alloc.c:432
void sc_add_egalites(Psysteme p, Pcontrainte i)
Definition: sc_alloc.c:415
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
static char * x
Definition: split_file.c:159
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
#define vecteur_var(v)
#define vecteur_succ(v)
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define VECTEUR_UNDEFINED_P(v)
Value vect_coeff(Variable var, Pvecteur vect)
Variable vect_coeff(Variable var, Pvecteur vect): coefficient de coordonnee var du vecteur vect —> So...
Definition: unaires.c:228

References assert, base_contains_variable_p(), contrainte_make_1D(), contrainte_succ, CONTRAINTE_UNDEFINED, eq, sc_add_egalites(), sc_add_inegalites(), sc_consistent_p(), VALUE_ONE, vect_coeff(), vecteur_succ, VECTEUR_UNDEFINED_P, vecteur_var, and x.

Referenced by sc_bounded_normalization().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ build_convex_constraints_from_vertices()

static Pcontrainte build_convex_constraints_from_vertices ( Variable  x,
Variable  y,
int  ni,
int  eni,
Value  ilmpx[ni+2],
Value  ilmpy[ni+2] 
)
static

Use the first eni+2 points in ilmpx and ilmpy to build at most eni+1 convex constraints, all upper bounds for y.

As we build a partial convex hull, there should always be a solution.

The value in ilmpx are assumed to be striclty increasing. The value in ilmpy are increasing. To be convex, the slopes of the successive constraints must be decreasing.

build a constraint between left and right

Check that all points meet the constraint

We could skip the left and right points...

There is always at least one constraint.

All points have been used

The constraints are chained backwards with respect to the vectices

Definition at line 916 of file sc_normalize.c.

919 {
920  int nli = eni; // number of left intermediate points
921  int left = 0; // index of the first point
922  int right = 1;
923  int rightmost = eni+1; // index of the last point
924  assert(eni>=0);
925  assert(ni>=eni);
927  int count = 0;
928  int i;
929 
930  ifscdebug(1) {
931  fprintf(stderr, "%s: input arrays with %d effective points\n", __FUNCTION__, eni);
932  for(i=0;i<eni+2;i++)
933  fprintf(stderr, "(%lld, %lld)%s", ilmpx[i], ilmpy[i], i==eni+1? "":", ");
934  fprintf(stderr, "\n");
935  }
936 
937  while(nli>=0) {
938  /* build a constraint between left and right */
939  Pvecteur nv = vect_make_line(x, y, ilmpx[left], ilmpy[left],
940  ilmpx[right], ilmpy[right]);
941  nv = vect_multiply(nv, VALUE_MONE);
942  /* Check that all points meet the constraint */
943  bool failed_p = false;
944  for(i=0; i<eni+2 && !failed_p; i++) {
945  /* We could skip the left and right points... */
946  failed_p = value_pos_p(eval_2D_vecteur(nv, x, y, ilmpx[i], ilmpy[i]));
947  }
948  if(failed_p) {
949  ifscdebug(1)
950  fprintf(stderr, "%s: point %d =(%lld, %lld) is skipped (left=%d is unchanged).\n",
951  __FUNCTION__, right, ilmpx[right], ilmpy[right], left);
952  vect_rm(nv);
953  right++;
954  }
955  else {
956  ifscdebug(1)
957  fprintf(stderr, "%s: points %d =(%lld, %lld) and %d =(%lld, %lld) "
958  "are used as vertices to define a new constraint.\n",
959  __FUNCTION__, left, ilmpx[left], ilmpy[left],
960  right, ilmpx[right], ilmpy[right]);
961  left = right;
962  right++;
963  Pcontrainte nc = contrainte_make(nv);
964  contrainte_succ(nc) = ineq;
965  ineq = nc;
966  count++;
967  }
968  nli--;
969  }
970  /* There is always at least one constraint. */
972  /* All points have been used*/
973  assert(right-1==rightmost);
974  /* The constraints are chained backwards with respect to the vectices */
975  ifscdebug(1) {
976  fprintf(stderr, "%s: %d constraints obtained:\n", __FUNCTION__, count);
977  inegalites_dump(ineq);
978  }
979  return ineq;
980 }
static int count
Definition: SDG.c:519
#define value_pos_p(val)
#define VALUE_MONE
#define CONTRAINTE_UNDEFINED_P(c)
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
void inegalites_dump(Pcontrainte)
Definition: io.c:220
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
static Value eval_2D_vecteur(Pvecteur v, Variable x, Variable y, Value xv, Value yv)
FI: a bit too specific for vecteur library?
Definition: sc_normalize.c:894
static Pvecteur vect_make_line(Variable x, Variable y, Value x0, Value y0, Value x1, Value y1)
FI: Could be moved in vecteur library...
Definition: sc_normalize.c:671
Pvecteur vect_multiply(Pvecteur v, Value x)
Pvecteur vect_multiply(Pvecteur v, Value x): multiplication du vecteur v par le scalaire x,...
Definition: scalaires.c:123
else
Definition: set.c:239
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78

References assert, contrainte_make(), contrainte_succ, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, count, eval_2D_vecteur(), fprintf(), inegalites_dump(), VALUE_MONE, value_pos_p, vect_make_line(), vect_multiply(), vect_rm(), and x.

Referenced by find_intermediate_constraints_recursively().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_coefficient_reduction()

static void check_coefficient_reduction ( Pvecteur  v,
Pcontrainte  ineq,
Variable  x,
Variable  y,
Value  x_min,
Value  x_max 
)
static

debug function: check that all 2-D constraints c in ineq are equivalent to contraint v on interval [x_min,x_max].

It is assumed that ineq contains 1, 2 or three constraints.

FI: if the constraint list were properly built, there would be no NULL vector in the list...

FI: linked_regions02; I do not understand whu a NULL constraint is present in ineq...

Scan the x interval

compute bound for y according to v

Definition at line 1466 of file sc_normalize.c.

1469 {
1470  Value a_v = vect_coeff(x,v);
1471  Value b_v = vect_coeff(y,v);
1472  Value c_v = vect_coeff(TCST,v);
1473  bool upper_p = value_pos_p(b_v);
1474  assert(a_v!=0 && b_v!=0);
1475 
1476  // FI: a tighter bound could be found with min(delta_x-1, delta_y-1);
1477 #define MAX_NUMBER_OF_CONSTRAINTS (x_max-x_min)
1481 
1482  Value i;
1483  int n=0; // number of constraints in ineq
1484  Pcontrainte cc;
1485 
1486  for(cc=ineq;
1488  cc = contrainte_succ(cc)) {
1489  Pvecteur cv = contrainte_vecteur(cc);
1490  /* FI: if the constraint list were properly built, there would be
1491  no NULL vector in the list... */
1492  if(!VECTEUR_NUL_P(cv)) {
1493  a[n] = vect_coeff(x, cv);
1494  b[n] = vect_coeff(y, cv);
1495  c[n] = vect_coeff(TCST, cv);
1496  if(upper_p) {
1497  assert(value_posz_p(b[n]));
1498  }
1499  else {
1500  assert(value_negz_p(b[n]));
1501  }
1502  // We could also assert a[n]<=a_v and b[n]<=b_v
1503  n++;
1504  }
1505  }
1506 
1507  /* FI: linked_regions02; I do not understand whu a NULL constraint
1508  is present in ineq... */
1510  assert(n>0);
1511  assert(value_gt(x_min, VALUE_MIN));
1512  assert(value_gt(VALUE_MAX, x_max));
1513  assert(value_ge(x_max,x_min));
1514 
1515  /* Scan the x interval */
1516  for(i=x_min;value_le(i,x_max); i++) {
1517  /* compute bound for y according to v */
1518  Value y_v = upper_p? value_pdiv(-a_v*i-c_v, b_v) :
1519  value_pdiv(a_v*i+c_v-b_v-1, -b_v);
1520  Value y_ineq = upper_p? VALUE_MAX:VALUE_MIN;
1521  int j;
1522  for(j=0;j<n;j++) {
1523  Value y_j = upper_p? value_pdiv(-a[j]*i-c[j], b[j]) :
1524  value_pdiv(a[j]*i+c[j]-b[j]-1, -b[j]);
1525  if(upper_p)
1526  // Decrease the upper bound
1527  y_ineq = (y_ineq>y_j)? y_j : y_ineq;
1528  else
1529  // Increase the lower bound
1530  y_ineq = (y_ineq<y_j)? y_j : y_ineq;
1531  }
1532  if(y_ineq!=y_v) {
1533  fprintf(stderr,
1534  "Discrepancy at x=%lld: initial bound=%lld, new bound=%lld\n",
1535  (long long int) i,
1536  (long long int) y_v, (long long int) y_ineq);
1537  fprintf(stderr, "Initial constraint: ");
1538  vect_dump(v);
1539  fprintf(stderr, "\nNew constraints: ");
1540  inegalites_dump(ineq);
1541  abort();
1542  }
1543  }
1544 }
#define value_gt(v1, v2)
#define value_pdiv(v1, v2)
#define value_le(v1, v2)
#define value_negz_p(val)
#define VALUE_MIN
#define VALUE_MAX
#define value_ge(v1, v2)
#define value_posz_p(val)
#define CONTRAINTE_NULLE_P(c)
contrainte nulle (non contrainte 0 == 0 ou 0 <= 0)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
void vect_dump(Pvecteur v)
void vect_dump(Pvecteur v): print sparse vector v on stderr.
Definition: io.c:304
#define abort()
Definition: misc-local.h:53
#define MAX_NUMBER_OF_CONSTRAINTS
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define VECTEUR_NUL_P(v)

References abort, assert, CONTRAINTE_NULLE_P, contrainte_succ, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, fprintf(), inegalites_dump(), MAX_NUMBER_OF_CONSTRAINTS, TCST, value_ge, value_gt, value_le, VALUE_MAX, VALUE_MIN, value_negz_p, value_pdiv, value_pos_p, value_posz_p, vect_coeff(), vect_dump(), VECTEUR_NUL_P, and x.

Referenced by reduce_coefficients_with_bounding_box().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compute_x_and_y_bounds()

static Pvecteur compute_x_and_y_bounds ( Pvecteur  v,
Pvecteur  l,
Pvecteur  lb,
Pvecteur  u,
Pvecteur  ub,
Variable px,
Variable py,
Value px_min,
Value px_max,
int pcb 
)
static

v is supposed to be the equation of a line in a 2-D space.

l, lb, u and ub define a bounding box for variables in v. Retrieve, when possible, two variables x and y, such that the coefficients for y in v is greater than the interval for x in the bounding box.

Also, make sure that a, the coefficient for x is negative and that b, the coefficient for y is positive. If it is not true, change the frame accordingly and indicate it in *pcb for later conversions.

The bounds are assumed initialized to VALUE_MIN and VALUE_MAX.

If both v1 and v2 are eligible as x, chose arbitrarily v1. This is usually bad design because non determnistic, but I do not have a sorting function available here... A vect_sort() should be performed before calling this function. An intermediate option would be to chose the maximum of a_i/delta_i.

Is v1 eligible as x?

is v2 eligible as x?

We assume here that at least one of the two variables is eligible because it was tested earlier.

For debugging: init_variable_debug_name(entity_local_name)

Let's forget about the slope in ]0,1[, let's try positive slopes

For debugging: init_variable_debug_name(entity_local_name)

Definition at line 327 of file sc_normalize.c.

334 {
335  Pvecteur vc;
336  Value delta_1 = VALUE_MAX, delta_2 = VALUE_MAX;
337  Variable v_1 = NULL, v_2 = NULL;
338  Value a_1 = VALUE_ZERO, a_2 = VALUE_ZERO;
339  Value
340  v_1_min = VALUE_NAN, v_1_max = VALUE_NAN,
341  v_2_min = VALUE_NAN, v_2_max = VALUE_NAN;
342  Value a = VALUE_ZERO, b = VALUE_ZERO, c = VALUE_ZERO;
343  Value delta_x = VALUE_MAX;
344  Pvecteur nv = VECTEUR_NUL;
345 
346  // Retrieve the coefficients, the variables and their intervals
347  for(vc=v; !VECTEUR_UNDEFINED_P(vc); vc=vecteur_succ(vc)) {
348  Variable var = vecteur_var(vc);
349  if(var!=TCST) {
350  if(v_1==NULL) {
351  v_1 = var;
352  a_1 = vecteur_val(vc);
353  if(!value_zero_p(vect_coeff(var,lb))
354  && !value_zero_p(vect_coeff(var,ub))) {
355  v_1_min = vect_coeff(var, l);
356  v_1_max = vect_coeff(var, u);
357  delta_1 = value_minus(v_1_max, v_1_min);
358  }
359  }
360  else {
361  v_2 = var;
362  a_2 = vecteur_val(vc);
363  if(!value_zero_p(vect_coeff(var,lb))
364  && !value_zero_p(vect_coeff(var,ub))) {
365  v_2_min = vect_coeff(var, l);
366  v_2_max = vect_coeff(var, u);
367  delta_2 = value_minus(v_2_max, v_2_min);
368  }
369  }
370  }
371  else {
372  c = vecteur_val(vc);
373  }
374  }
375 
376  /* If both v1 and v2 are eligible as x, chose arbitrarily v1. This
377  is usually bad design because non determnistic, but I do not have
378  a sorting function available here... A vect_sort() should be
379  performed before calling this function. An intermediate option
380  would be to chose the maximum of a_i/delta_i. */
381  /* Is v1 eligible as x? */
382  if(value_gt(value_abs(a_2), delta_1)) {
383  *px = v_1;
384  *py = v_2;
385  *px_min = v_1_min;
386  *px_max = v_1_max;
387  a = a_1;
388  b = a_2;
389  delta_x = delta_1;
390  }
391  else
392  /* is v2 eligible as x? */
393  if(value_gt(value_abs(a_1), delta_2)) {
394  *px = v_2;
395  *py = v_1;
396  *px_min = v_2_min;
397  *px_max = v_2_max;
398  a = a_2;
399  b = a_1;
400  delta_x = delta_2;
401  }
402  else {
403  /* We assume here that at least one of the two variables is
404  eligible because it was tested earlier. */
405  assert(false);
406  }
407 
408  ifscdebug(1) {
409  assert(value_gt(value_abs(b), delta_x));
411  assert(value_pos_p(delta_x));
412  /* For debugging: init_variable_debug_name(entity_local_name) */
413  fprintf(stderr, "Selected constraint: %lld %s + %lld %s + %lld\n",
414  (long long int) a, variable_debug_name(*px),
415  (long long int) b, variable_debug_name(*py),
416  (long long int) c);
417  }
418 
419  if(value_pos_p(a)) {
420  a = value_uminus(a);
421  negate_value_interval(px_min, px_max);
422  *pcb |= 4;
423  }
424  if(value_neg_p(b)) {
425  b = value_uminus(b);
426  *pcb |= 2;
427  }
428  if(false && value_gt(value_abs(a),value_abs(b))) {
429  /* Let's forget about the slope in ]0,1[, let's try positive slopes */
430  ;
431  }
432 
433  ifscdebug(1) {
434  /* For debugging: init_variable_debug_name(entity_local_name) */
435  fprintf(stderr,
436  "Constraint after change of frame: %lld %s + %lld %s + %lld\n",
437  (long long int) a, variable_debug_name(*px),
438  (long long int) b, variable_debug_name(*py),
439  (long long int) c);
440  fprintf(stderr, "Change of frame: %d\n", *pcb);
441  }
442 
443  nv = vect_make(nv, *px, a, *py, b, NULL, NULL, NULL);
444  vect_add_elem(&nv, TCST, c);
445  vect_normalize(nv);
446 
447  ifscdebug(1) {
448  fprintf(stderr, "New constraint nv: ");
449  vect_dump(nv);
450  }
451 
452  return nv;
453 }
#define VALUE_ZERO
#define value_minus(v1, v2)
#define value_notzero_p(val)
#define value_uminus(val)
unary operators on values
#define value_zero_p(val)
#define value_abs(val)
#define VALUE_NAN
#define value_neg_p(val)
char *(* variable_debug_name)(Variable)
Debug support: pointer to the function used by debug print outs.
Definition: variable.c:114
static void negate_value_interval(Value *pmin, Value *pmax)
package sc
Definition: sc_normalize.c:50
#define vecteur_val(v)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
Pvecteur vect_make(Pvecteur v, Variable var, Value val,...)
Pvecteur vect_make(v, [var, val,]* 0, val) Pvecteur v; // may be NULL, use assigne anyway Variable va...
Definition: alloc.c:165
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72
void vect_normalize(Pvecteur v)
void vect_normalize(Pvecteur v): division de tous les coefficients de v par leur pgcd; "normalisation...
Definition: unaires.c:59

References assert, fprintf(), negate_value_interval(), TCST, value_abs, value_gt, VALUE_MAX, value_minus, VALUE_NAN, value_neg_p, value_notzero_p, value_pos_p, value_uminus, VALUE_ZERO, value_zero_p, variable_debug_name, vect_add_elem(), vect_coeff(), vect_dump(), vect_make(), vect_normalize(), VECTEUR_NUL, vecteur_succ, VECTEUR_UNDEFINED_P, vecteur_val, and vecteur_var.

Referenced by reduce_coefficients_with_bounding_box().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eligible_for_coefficient_reduction_with_bounding_box_p()

static bool eligible_for_coefficient_reduction_with_bounding_box_p ( Pvecteur  v,
Pvecteur  l,
Pvecteur  lb,
Pvecteur  u,
Pvecteur  ub 
)
static

Is it possible to reduce the magnitude of at least one constraint coefficient because it is larger than the intervals defined by the bounding box for the other variable?

Note: the modularity wastes computations. It would be nice to benefit from a, b, dx and dy.

v is a 2-D constraint

The two variables are bounded by a non-degenerated rectangle...

At least one variable is bounded by an interval: sufficient condition

The bounding box is not degenerated. If it is the case, the constraint should have been simplified in a much easier way.

make sure that at least one coefficient can be reduced

Definition at line 462 of file sc_normalize.c.

467 {
468  bool eligible_p = true;
469  bool bounded_p = false;
470  Value dx = VALUE_MAX; // width of bounding box
471  Value dy = VALUE_MAX; // height of bounding box
472  Value a = VALUE_ZERO;
473  Value b = VALUE_ZERO;
474  Variable x = VARIABLE_UNDEFINED; // Dangerous, same as TCST...
475 
476  /* v is a 2-D constraint */
477  eligible_p = (vect_size(v)==2 && value_zero_p(vect_coeff(TCST, v)))
478  || (vect_size(v)==3 && value_notzero_p(vect_coeff(TCST, v)));
479 
480  /* The two variables are bounded by a non-degenerated rectangle... */
481  /* At least one variable is bounded by an interval: sufficient condition */
482  if(eligible_p) {
483  Pvecteur vc;
484  for(vc=v; !VECTEUR_UNDEFINED_P(vc) && eligible_p; vc=vecteur_succ(vc)) {
485  Variable var = vecteur_var(vc);
486  bool var_bounded_p = false;
487  if(var!=TCST) {
488  if(value_pos_p(vect_coeff(var, lb)) && value_pos_p(vect_coeff(var, ub))) {
489  bounded_p = true;
490  var_bounded_p = true;
491  }
492  if(VARIABLE_UNDEFINED_P(x)) {
493  dx = var_bounded_p?
494  value_minus(vect_coeff(var,u),vect_coeff(var,l))
495  : VALUE_MAX;
496  a = value_abs(vect_coeff(var, vc));
497  x = var;
498  }
499  else {
500  dy = var_bounded_p?
501  value_minus(vect_coeff(var,u),vect_coeff(var,l))
502  : VALUE_MAX;
503  b = value_abs(vect_coeff(var, vc));
504  }
505  }
506  }
507 
508  /* The bounding box is not degenerated. If it is the case, the
509  constraint should have been simplified in a much easier
510  way. */
511  eligible_p = bounded_p && value_pos_p(dx) && value_pos_p(dy);
512  if(eligible_p)
513  /* make sure that at least one coefficient can be reduced */
514  eligible_p = value_gt(a,dy) || value_gt(b,dx);
515  }
516 
517  return eligible_p;
518 }
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define VARIABLE_UNDEFINED_P(v)
Definition: vecteur-local.h:65
#define VARIABLE_UNDEFINED
Definition: vecteur-local.h:64

References TCST, value_abs, value_gt, VALUE_MAX, value_minus, value_notzero_p, value_pos_p, VALUE_ZERO, value_zero_p, VARIABLE_UNDEFINED, VARIABLE_UNDEFINED_P, vect_coeff(), vect_size(), vecteur_succ, VECTEUR_UNDEFINED_P, vecteur_var, and x.

Referenced by reduce_coefficients_with_bounding_box(), and sc_bounded_normalization().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eval_2D_vecteur()

static Value eval_2D_vecteur ( Pvecteur  v,
Variable  x,
Variable  y,
Value  xv,
Value  yv 
)
static

FI: a bit too specific for vecteur library?

FI: overflow control should be added

Definition at line 894 of file sc_normalize.c.

895 {
896  Value k = VALUE_ZERO;
897  Value a = vect_coeff(x, v);
898  Value b = vect_coeff(y, v);
899  Value c = vect_coeff(TCST, v);
900 
901  /* FI: overflow control should be added */
902  k = a*xv + b*yv + c;
903  return k;
904 }

References TCST, VALUE_ZERO, vect_coeff(), and x.

Referenced by build_convex_constraints_from_vertices().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ find_first_integer_point_in_between()

static bool find_first_integer_point_in_between ( Value  x0,
Value  y0,
Pvecteur  up_c,
Pvecteur  low_c,
Variable  xv,
Variable  yv,
Value  dx,
Value  dy,
Value  xf,
Value yf   __attribute__(unused),
Value pfx,
Value pfy 
)
static

Find the first significant integer point (*pfx, *pfy) starting from (x0,y0) moving by (dx,dy) steps towards (xf,yf) that is between the constraint up_c and low_c such that *pfx!=xf and pfx!=x0.

Let x be *pfx and y be *pfy. Between the constraints means up_c(x,y)<=0 and low_c(x,y)>0.

The two constraints up_c and low_c have a positive slope with respect to variables xv and yv over interval [x0,xf] or [xf,x0].

Value yf is only useful for debugging.

It would be possible to find the intermediate points faster using intersections with the constraints instead of using an incremental step-by-step approach.

This is an auxiliary function for coefficient reduction.

Retrieve coefficients of the two constraints

FI: I am tired of using value macros

The two constraints have positive slopes, but not necessarily in the ]0,1[ interval

&& b_up>-a_up

&& b_low>-a_low

Constraint up is higher than constraint low on interval [x0,xf]

There are other points to explore

The intermediate point si strictly over the lower constraint and meet the upper constraint. It is not the initial nor the final point.

Are there more integer points along this direction? If yes, find the last one.

let ndx = x-x0, ndy = y - y0

let x = x0 + th ndx and y = y0 + th ndy (x and y are new variables)

what is the largest integer value for th such that up<=0?

a_up x0 + a_up th ndx + b_up y0 + b_up th ndy + c_up <= 0

th <= (-a_up x0 - b_up y0 - c_up)/(a_up ndx + b_up ndy)

if a_up dx + b_up dy >=0. Else

th >= (a_up x0 + b_up y0 + c_up)/(-a_up ndx - b_up ndy)

then you should find the last one in the [x0,xf] interval...

if ndx > 0, x0+k ndx<=xf else x0+ k ndx >= xf, x0-xf>=-k ndx

The constraint on th is d th + n <=0

lower bound for th: any th positive is good

d>0, upper bound for th

This should occur for slope07, 08 and 09

Make sure that (x,y) meets all the constraints

return the final resut

Definition at line 705 of file sc_normalize.c.

713 {
714  /* Retrieve coefficients of the two constraints */
715  Value a_up = vect_coeff(xv, up_c);
716  Value a_low = vect_coeff(xv, low_c);
717  Value b_up = vect_coeff(yv, up_c);
718  Value b_low = vect_coeff(yv, low_c);
719  Value c_up = vect_coeff(TCST, up_c);
720  Value c_low = vect_coeff(TCST, low_c);
721  /* FI: I am tired of using value macros */
722  Value up_0 = a_up * x0 + b_up * y0 + c_up;
723  Value low_0 = a_low * x0 + b_low * y0 + c_low;
724  Value up = up_0;
725  Value low = low_0;
726  Value x = x0, y = y0;
727  bool found = false; // (up <= 0 && low >=0); the first point is not
728  // relevant as intermediate point
729 
730  /* The two constraints have positive slopes, but not necessarily in
731  the ]0,1[ interval */
732  assert(a_up<0 && b_up>0 /* && b_up>-a_up */ );
733  assert(a_low<0 && b_low>0 /* && b_low>-a_low */ );
734 
735  /* Constraint up is higher than constraint low on interval [x0,xf] */
736  assert(!(up>0&&low<0));
737 
738  if(x0!=xf) {
739  /* There are other points to explore */
740  assert(dx!=0);
741  assert((xf>x0 && dx>0) || (xf<x0 && dx<0));
742 
743  while(!found && x!=xf) {
744  if(up>=0) {
745  if(dx>0) {
746  x += dx;
747  up += a_up*dx;
748  low += a_low*dx;
749  }
750  else {
751  y += dy;
752  up += b_up*dy;
753  low += b_low*dy;
754  }
755  }
756  if(low<=0 ) {
757  if(dx>0) {
758  y += dy;
759  up += b_up*dy;
760  low += b_low*dy;
761  }
762  else {
763  x += dx;
764  up += a_up*dx;
765  low += a_low*dx;
766  }
767  }
768  /* The intermediate point si strictly over the lower constraint
769  and meet the upper constraint. It is not the initial nor the
770  final point. */
771  found = (up <= 0 && low >0) && x!=x0 && x!=xf;
772  assert(!(up>0&&low<0) || x==x0 || x==xf);
773  }
774  }
775 
776  if(found) {
777  if(y-y0==0) { // slope12.c: this procedure may skip useful
778  //intermediate points, e.g. when the slope oscillates between 1/50 and
779  // 1/49...; it might be OK when the slope is down to 0...
780  /* Are there more integer points along this direction? If yes,
781  * find the last one.
782  *
783  * let ndx = x-x0, ndy = y - y0
784  *
785  * let x = x0 + th ndx and y = y0 + th ndy (x and y are new variables)
786  *
787  * what is the largest integer value for th such that up<=0?
788  *
789  * a_up x0 + a_up th ndx + b_up y0 + b_up th ndy + c_up <= 0
790  *
791  * th <= (-a_up x0 - b_up y0 - c_up)/(a_up ndx + b_up ndy)
792  *
793  * if a_up dx + b_up dy >=0. Else
794  *
795  * th >= (a_up x0 + b_up y0 + c_up)/(-a_up ndx - b_up ndy)
796  */
797  Value ndx = x - x0;
798  Value ndy = y - y0;
799  Value n = a_up*x0+b_up*y0+c_up;
800  Value d = a_up*ndx+b_up*ndy;
801  // The test might be useless, depending on pdiv's behavior
802  Value th = d>0? value_pdiv(value_uminus(n),d)
803  :value_pdiv(n-d-1,value_uminus(d));
804  // th==0 is always solution since (x0,y0) is solution
805  // d>0 implies an upper bound, and d<0 a lower bound
806  assert((d>0 && th>=0) || (d<0 && th<=0));
807 
808  /* then you should find the last one in the [x0,xf] interval...
809  *
810  * if ndx > 0, x0+k ndx<=xf else x0+ k ndx >= xf, x0-xf>=-k ndx
811  */
812  Value k = ndx>0? value_pdiv(xf-x0,ndx) : value_pdiv(x0-xf,-ndx);
813  assert(k>=0);
814 
815  /* The constraint on th is d th + n <=0 */
816  if(d<0) {
817  /* lower bound for th: any th positive is good */
818  assert(th<=0);
819  x = x0+k*ndx;
820  y = y0+k*ndy;
821  found = x!=xf; // Useful intermediate integer point?
822  }
823  else { /* d>0, upper bound for th */
824  /* This should occur for slope07, 08 and 09 */
825  assert(th>=0);
826  Value lambda = value_min(k,th);
827  x = x0+lambda*ndx;
828  y = y0+lambda*ndy;
829  found = x!=xf; // Useful intermediate integer point?
830  }
831  }
832  /* Make sure that (x,y) meets all the constraints */
833  if(found) {
834  assert(a_up*x+b_up*y+c_up<=0);
835  assert(a_low*x+b_low*y+c_low>=0);
836  assert(x!=x0); // y may be equal to y0
837  assert(x!=xf); // y may be equal to yf
838  }
839 
840  /* return the final resut */
841  *pfx = x;
842  *pfy = y;
843  }
844 
845  ifscdebug(1) {
846  if(found) {
847  fprintf(stderr, "Intermediate point: (%lld, %lld) for "
848  "[(%lld,%lld),(%lld,%lld)] "
849  "with saturations low %lld and up %lld\n",
850  x, y, x0, y0, xf, yf,
851  (a_low*x+b_low*y+c_low)/b_low,
852  (a_up*x+b_up*y+c_up)/b_up);
853  fprintf(stderr, "for constraints low and up:\n");
854  vect_dump(low_c);
855  vect_dump(up_c);
856  }
857  else {
858  fprintf(stderr, "No intermediate point found\n");
859  }
860  }
861 
862  return found;
863 }
#define value_min(v1, v2)

References assert, fprintf(), TCST, value_min, value_pdiv, value_uminus, vect_coeff(), vect_dump(), and x.

Referenced by find_integer_point_to_the_left(), and find_integer_point_to_the_right().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ find_integer_point_to_the_left()

static bool find_integer_point_to_the_left ( Value  x0,
Value  y0,
Pvecteur  up,
Pvecteur  low,
Variable  x,
Variable  y,
Value  xf,
Value  yf,
Value pfx,
Value pfy 
)
static

Definition at line 879 of file sc_normalize.c.

886 {
887  assert(value_le(xf,x0));
888  return find_first_integer_point_in_between(x0, y0, up, low, x, y,
890  xf, yf, pfx, pfy);
891 }
static bool find_first_integer_point_in_between(Value x0, Value y0, Pvecteur up_c, Pvecteur low_c, Variable xv, Variable yv, Value dx, Value dy, Value xf, Value yf __attribute__((unused)), Value *pfx, Value *pfy)
Find the first significant integer point (*pfx, *pfy) starting from (x0,y0) moving by (dx,...
Definition: sc_normalize.c:705

References assert, find_first_integer_point_in_between(), value_le, VALUE_MONE, and x.

Referenced by find_intermediate_constraints().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ find_integer_point_to_the_right()

static bool find_integer_point_to_the_right ( Value  x0,
Value  y0,
Pvecteur  up,
Pvecteur  low,
Variable  x,
Variable  y,
Value  xf,
Value  yf,
Value pfx,
Value pfy 
)
static

Definition at line 865 of file sc_normalize.c.

872 {
873  assert(value_ge(xf,x0));
874  return find_first_integer_point_in_between(x0, y0, up, low, x, y,
876  xf, yf, pfx, pfy);
877 }

References assert, find_first_integer_point_in_between(), value_ge, VALUE_ONE, and x.

Referenced by find_intermediate_constraints(), and find_intermediate_constraints_recursively().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ find_intermediate_constraints()

Pcontrainte find_intermediate_constraints ( Pvecteur  v,
Variable  x,
Variable  y,
Value  lmpx,
Value  lmpy,
Value  rmpx,
Value  rmpy 
)

Find a set ineq of 2-D constraints equivalent to 2-D constraint v==ax+by+c over the interval [lmpx,rmpx].

The slope of the constraints is assumed positive. The values lmpy and rmpy could be computed from v and lmpx and rmpx but are passed down to simplify debugging. The coefficients of the new constraints are smaller than the coefficient of v, assuming that abs(b) is greater than rmpx-lmpx.

This function was based on the wrong assumption that at most three constraints were sufficient to replace exactly v. This is proved wrong by slope15.c.

This function is now obsolete: it was based on the wrong assumption that three constraints at most would be necessary to replace one rational constraint. We ended up with a case requiring four constraints in linked_regions02 and we have no proof that the number of integer vertices, and hence the number of constraints is bounded by a smaller bound than min(dx,dy+1).

Look for intermediate points

A lower upper bound

Start with the initial point in order to be able to compute the slope of the new constraint later

Two constraints

assert convexity

Three constraints at most: be careful about the convexity, the slopes must be decreasing...

We still might have some integer points between (ilmpx,ilmpy) and (rmlpx,rlmpy)...

The first intermediate point, (ilmpx,ilmpy), cannot be used

FI: I assume it never happens... by definition of an intermediate point

We must have slope2<slope3

FI: I assume it never happens... by definition of an intermediate point.

One constraint generated by (lmpx,lmpy) and (rmpx,rmpy)

Definition at line 1091 of file sc_normalize.c.

1094 {
1095  Pcontrainte ineq;
1096 
1097  /* Look for intermediate points */
1098  Value ilmpx, ilmpy, irmpx, irmpy;
1099  /* A lower upper bound */
1100  Pvecteur nv = vect_make_line(x, y, lmpx, lmpy, rmpx, rmpy);
1101  nv = vect_multiply(nv, VALUE_MONE);
1102 
1103  /* Start with the initial point in order to be able to compute
1104  the slope of the new constraint later */
1105  bool rfound = find_integer_point_to_the_right(lmpx,
1106  lmpy,
1107  v,
1108  nv,
1109  x, y,
1110  rmpx, rmpy,
1111  &ilmpx, &ilmpy);
1112  bool lfound = find_integer_point_to_the_left(rmpx,
1113  rmpy,
1114  v,
1115  nv,
1116  x, y,
1117  lmpx, lmpy,
1118  &irmpx, &irmpy);
1119  assert(rfound==lfound);
1120  if(rfound) {
1121  if(ilmpx==irmpx) {
1122  /* Two constraints */
1123  double slope1 = ((double)(ilmpy-lmpy))/((double)(ilmpx-lmpx));
1124  double slope3 = ((double)(rmpy-irmpy))/((double)(rmpx-irmpx));
1125  Pvecteur fv = vect_make_line(x, y, lmpx,lmpy,ilmpx,ilmpy);
1126  fv = vect_multiply(fv, VALUE_MONE);
1127  Pvecteur lv = vect_make_line(x, y, irmpx,irmpy,rmpx,rmpy);
1128  lv = vect_multiply(lv, VALUE_MONE);
1129  ineq = contraintes_make(fv,lv, VECTEUR_NUL);
1130  /* assert convexity */
1131  assert(slope1>slope3);
1132  }
1133  else {
1134  /* Three constraints at most: be careful about the convexity, the
1135  slopes must be decreasing... */
1136  double slope1 = ((double)(ilmpy-lmpy))/((double)(ilmpx-lmpx));
1137  double slope2 = ((double)(irmpy-ilmpy))/((double)(irmpx-ilmpx));
1138  double slope3 = ((double)(rmpy-irmpy))/((double)(rmpx-irmpx));
1139  if(slope1>slope2 && slope2>slope3) {
1140  /* We still might have some integer points between
1141  (ilmpx,ilmpy) and (rmlpx,rlmpy)... */
1142  Pvecteur fv = vect_make_line(x, y, lmpx,lmpy,ilmpx,ilmpy);
1143  fv = vect_multiply(fv, VALUE_MONE);
1144  Pvecteur mv = vect_make_line(x, y, ilmpx,ilmpy,irmpx,irmpy);
1145  mv = vect_multiply(mv, VALUE_MONE);
1146  Pvecteur lv = vect_make_line(x, y, irmpx,irmpy,rmpx,rmpy);
1147  lv = vect_multiply(lv, VALUE_MONE);
1148  ineq = contraintes_make(fv, mv, lv, VECTEUR_NUL);
1149  }
1150  else if(slope2>slope1) {
1151  /* The first intermediate point, (ilmpx,ilmpy), cannot be used */
1152  double slope12 = ((double)(irmpy-lmpy))/((double)(irmpx-lmpx));
1153  if(slope12>slope3) {
1154  Pvecteur fv = vect_make_line(x, y, lmpx,lmpy,irmpx,irmpy);
1155  fv = vect_multiply(fv, VALUE_MONE);
1156  Pvecteur lv = vect_make_line(x, y, irmpx,irmpy,rmpx,rmpy);
1157  lv = vect_multiply(lv, VALUE_MONE);
1158  ineq = contraintes_make(fv, lv, VECTEUR_NUL);
1159  }
1160  else {
1161  /* FI: I assume it never happens... by definition of an
1162  intermediate point */
1163  fprintf(stderr, "not implemented.\n");
1164  abort();
1165  }
1166  }
1167  else {
1168  /* We must have slope2<slope3*/
1169  double slope23 = ((double)(rmpy-ilmpy))/((double)(rmpx-ilmpx));
1170  if(slope1>slope23) {
1171  Pvecteur fv = vect_make_line(x, y, lmpx,lmpy,ilmpx,ilmpy);
1172  fv = vect_multiply(fv, VALUE_MONE);
1173  Pvecteur lv = vect_make_line(x, y, ilmpx,ilmpy,rmpx,rmpy);
1174  lv = vect_multiply(lv, VALUE_MONE);
1175  ineq = contraintes_make(fv, lv, VECTEUR_NUL);
1176  }
1177  else {
1178  /* FI: I assume it never happens... by definition of an
1179  intermediate point. */
1180  fprintf(stderr, "not implemented.\n");
1181  abort();
1182  }
1183  }
1184  }
1185  }
1186  else {
1187  /* One constraint generated by (lmpx,lmpy) and (rmpx,rmpy) */
1188  Pvecteur uv = vect_make_line(x, y, lmpx,lmpy,rmpx,rmpy);
1189  uv = vect_multiply(uv, VALUE_MONE);
1190  ineq = contrainte_make(uv);
1191  }
1192  return ineq;
1193 }
Pcontrainte contraintes_make(Pvecteur pv,...)
Convert a list of vectors into a list of constraints.
Definition: alloc.c:99
static bool find_integer_point_to_the_left(Value x0, Value y0, Pvecteur up, Pvecteur low, Variable x, Variable y, Value xf, Value yf, Value *pfx, Value *pfy)
Definition: sc_normalize.c:879
static bool find_integer_point_to_the_right(Value x0, Value y0, Pvecteur up, Pvecteur low, Variable x, Variable y, Value xf, Value yf, Value *pfx, Value *pfy)
Definition: sc_normalize.c:865

References abort, assert, contrainte_make(), contraintes_make(), find_integer_point_to_the_left(), find_integer_point_to_the_right(), fprintf(), VALUE_MONE, vect_make_line(), vect_multiply(), VECTEUR_NUL, and x.

+ Here is the call graph for this function:

◆ find_intermediate_constraints_recursively()

Pcontrainte find_intermediate_constraints_recursively ( Pvecteur  v,
Variable  x,
Variable  y,
Value  lmpx,
Value  lmpy,
Value  rmpx,
Value  rmpy 
)

Find a set ineq of 2-D constraints equivalent to 2-D constraint v==ax+by+c over the interval [lmpx,rmpx].

The slope of the constraint v is assumed positive. The values lmpy and rmpy could be computed from v and lmpx and rmpx but are passed down to simplify debugging. The coefficients of the new constraints are smaller than the coefficient of v, assuming that abs(b) is greater than rmpx-lmpx.

The function looks for intermediate points and build the constraints fromm this set of points, making sure to skip some intermediate points if the constraint they generate do not respect convexity.

No interesting intermediate point exists if lmpx and rmpx or lmpy and rmpy are too close. No values would be available for their coordinates.

maximal number of intermediate points

Look for at most for ni intermediate points, but reserve space to add the initial point and (perhaps) the final point.

The first element is the left most point

Effective number of intermediate points

The control structure of this piece of code could be improved by initializing ilmpx[0] and ilmpy[0] right away and by using a while(more_to_find_p) to avoid code replication.

A lower upper bound for v

add the final point to the arrays ilmpx and ilmpy

Process the intermediate points

One constraint generated by (lmpx,lmpy) and (rmpx,rmpy)

Definition at line 995 of file sc_normalize.c.

999 {
1000  Pcontrainte ineq;
1001  /* No interesting intermediate point exists if lmpx and rmpx or lmpy
1002  and rmpy are too close. No values would be available for their
1003  coordinates. */
1004  Value delta_x = rmpx-lmpx-1; // cardinal of ]lmpx,rmpx[
1005  Value delta_y = rmpy-lmpy; // cardinal of ]lmpy,rmpy], y may not
1006  //vary between the last two points
1007  assert(delta_x>=0);
1008  assert(delta_y>=0);
1009  /* maximal number of intermediate points */
1010  int ni = (int) value_min(delta_x, delta_y);
1011  /* Look for at most for ni intermediate points, but reserve space to
1012  add the initial point and (perhaps) the final point. */
1013  Value ilmpx[ni+2], ilmpy[ni+2];
1014  /* The first element is the left most point */
1015  ilmpx[0] = lmpx;
1016  ilmpy[0] = lmpy;
1017  /* Effective number of intermediate points */
1018  int eni = 0;
1019  bool more_to_find_p = ni>0;
1020 
1021  /* The control structure of this piece of code could be improved by
1022  initializing ilmpx[0] and ilmpy[0] right away and by using a
1023  while(more_to_find_p) to avoid code replication. */
1024 
1025  while(more_to_find_p) {
1026  /* A lower upper bound for v */
1027  Pvecteur nv = vect_make_line(x, y, ilmpx[eni], ilmpy[eni], rmpx, rmpy);
1028  nv = vect_multiply(nv, VALUE_MONE);
1029 
1030  bool rfound = find_integer_point_to_the_right(ilmpx[eni],
1031  ilmpy[eni],
1032  v,
1033  nv,
1034  x, y,
1035  rmpx, rmpy,
1036  &ilmpx[eni+1], &ilmpy[eni+1]);
1037  if(rfound) {
1038  eni++;
1039  Value nlmpx = ilmpx[eni];
1040  Value nlmpy = ilmpy[eni];
1041  Value ndelta_x = rmpx-nlmpx-1;
1042  Value ndelta_y = rmpy-nlmpy; // the constraint may be horizontal
1043  assert(ndelta_x>=0);
1044  assert(ndelta_y>=0);
1045  int nni = (int) value_min(ndelta_x, ndelta_y);
1046  assert(nni<=ni);
1047  more_to_find_p = nni>0;
1048  }
1049  else
1050  more_to_find_p = false;
1051  }
1052 
1053  if(eni>0) {
1054  /* add the final point to the arrays ilmpx and ilmpy */
1055  ilmpx[eni+1] = rmpx;
1056  ilmpy[eni+1] = rmpy;
1057  /* Process the intermediate points */
1058  ineq = build_convex_constraints_from_vertices(x, y, ni, eni,
1059  ilmpx, ilmpy);
1060  }
1061 
1062  if(ni==0||eni==0) {
1063  /* One constraint generated by (lmpx,lmpy) and (rmpx,rmpy) */
1064  Pvecteur uv = vect_make_line(x, y, lmpx,lmpy,rmpx,rmpy);
1065  uv = vect_multiply(uv, VALUE_MONE);
1066  ineq = contrainte_make(uv);
1067  }
1068 
1069  return ineq;
1070 }
void const char const char const int
static Pcontrainte build_convex_constraints_from_vertices(Variable x, Variable y, int ni, int eni, Value ilmpx[ni+2], Value ilmpy[ni+2])
Use the first eni+2 points in ilmpx and ilmpy to build at most eni+1 convex constraints,...
Definition: sc_normalize.c:916

References assert, build_convex_constraints_from_vertices(), contrainte_make(), find_integer_point_to_the_right(), int, value_min, VALUE_MONE, vect_make_line(), vect_multiply(), and x.

Referenced by small_positive_slope_reduce_coefficients_with_bounding_box().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ negate_value_interval()

static void negate_value_interval ( Value pmin,
Value pmax 
)
static

package sc

Normalization, which include some redundacy elimination include <values.h> Two candidates for arithmetique/value.c, which does not exist, or for value/value.c, which does not exist either.

Definition at line 50 of file sc_normalize.c.

51 {
52  Value t = value_uminus(*pmin);
53  *pmin = value_uminus(*pmax);
54  *pmax = t;
55 }

References value_uminus.

Referenced by compute_x_and_y_bounds(), new_constraint_for_coefficient_reduction_with_bounding_box(), and update_coefficient_signs_in_constraints().

+ Here is the caller graph for this function:

◆ new_constraint_for_coefficient_reduction_with_bounding_box()

static Pvecteur new_constraint_for_coefficient_reduction_with_bounding_box ( Pvecteur  v,
int pcb,
Variable  x,
Variable  y,
Value px_min,
Value px_max,
Value py_min,
Value py_max 
)
static

Compute a normalized version of the constraint v and the corresponding change of basis.

The change of basis is encoded by an integer belonging to the interval [0,7]. Bit 2 is used to encode a change of sign for x, bit 1, a change of sign for y and bit 0 a permutation between x and y.

No new variable x' and y' are introduced. The new constraint is still expressed as a constraint on x and y.

The bounds on x and y must be adapted into bound on x' and y'.

substitute x by x'=-x

FI: could cause an overflow

FI: could cause an overflow

Build a_prime x + b_prime y <= -c

x and y must be exchanged: -b_prime x - a_prime y <= -c

Make sure that nv is properly built...

Definition at line 572 of file sc_normalize.c.

580 {
581  Value a = VALUE_ZERO;
582  Value b = VALUE_ZERO;
583  Value c = VALUE_ZERO;
584  Value a_prime = VALUE_ZERO;
585  Value b_prime = VALUE_ZERO;
586  Pvecteur vc;
587  Pvecteur nv = VECTEUR_NUL; // new constraint
588 
589  ifscdebug(1) {
590  fprintf(stderr, "%s:\n", __FUNCTION__);
591  fprintf(stderr, "Constraint before change of basis:");
592  vect_dump(v);
593  fprintf(stderr, "Initial interval x_min=%lld, x_max=%lld\n",
594  *px_min, *px_max);
595  }
596 
597  for(vc=v; !VECTEUR_UNDEFINED_P(vc); vc=vecteur_succ(vc)) {
598  Variable var = vecteur_var(vc);
599  if(var!=TCST) {
600  if(var==x) {
601  a = vect_coeff(var, vc);
602  }
603  else {
604  b = vect_coeff(var, vc);
605  assert(y == vecteur_var(vc));
606  }
607  }
608  else
609  c = vect_coeff(var, vc);
610  }
611 
612  if(value_pos_p(a)) {
613  /* substitute x by x'=-x */
614  *pcb = 4;
615  /* FI: could cause an overflow */
616  value_assign(a_prime, value_uminus(a));
617  negate_value_interval(px_min, px_max);
618  }
619  else {
620  *pcb = 0;
621  value_assign(a_prime, a);
622  }
623  if(value_neg_p(b)) {
624  *pcb |= 2;
625  /* FI: could cause an overflow */
626  value_assign(b_prime, value_uminus(b));
627  negate_value_interval(py_min, py_max);
628  }
629  else {
630  // *pcb |= 0; i.e. unchanged
631  value_assign(b_prime, b);
632  }
633  if(value_gt(b_prime, value_uminus(a_prime))) {
634  /* Build a_prime x + b_prime y <= -c */
635  vect_add_elem(&nv, y, b_prime);
636  vect_add_elem(&nv, x, a_prime);
637  vect_add_elem(&nv, TCST, c);
638  }
639  else {
640  /* x and y must be exchanged: -b_prime x - a_prime y <= -c */
641  *pcb |= 1;
642  vect_add_elem(&nv, y, value_uminus(a_prime));
643  vect_add_elem(&nv, x, value_uminus(b_prime));
644  vect_add_elem(&nv, TCST, c);
645  swap_value_intervals(px_min, px_max, py_min, py_max);
646  }
647 
648  ifscdebug(1) {
649  /* Make sure that nv is properly built... */
650  fprintf(stderr, "%s:\n", __FUNCTION__);
651  fprintf(stderr, "Constraint after change of basis:");
652  vect_dump(nv);
653  fprintf(stderr, "Final interval x_min=%lld, x_max=%lld\n", *px_min, *px_max);
654  fprintf(stderr, "Chosen variables x=%s, y=%s\n", variable_debug_name(x),
656  fprintf(stderr, "Change of basis: %d\n", *pcb);
657 
659  }
660 
661  return nv;
662 }
#define value_assign(ref, val)
assigments
static bool small_slope_and_first_quadrant_p(Pvecteur v)
Check that the coefficients on the first and second variables, x and y, define a increasing line.
Definition: sc_normalize.c:531
static void swap_value_intervals(Value *px_min, Value *px_max, Value *py_min, Value *py_max)
Definition: sc_normalize.c:64

References assert, fprintf(), negate_value_interval(), small_slope_and_first_quadrant_p(), swap_value_intervals(), TCST, value_assign, value_gt, value_neg_p, value_pos_p, value_uminus, VALUE_ZERO, variable_debug_name, vect_add_elem(), vect_coeff(), vect_dump(), VECTEUR_NUL, vecteur_succ, VECTEUR_UNDEFINED_P, vecteur_var, and x.

Referenced by reduce_coefficients_with_bounding_box().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reduce_coefficients_with_bounding_box()

static Pcontrainte reduce_coefficients_with_bounding_box ( Pvecteur  v,
Pvecteur  l,
Pvecteur  lb,
Pvecteur  u,
Pvecteur  ub 
)
static

If at least one of the coefficients of constraint v == ax+by<=c are greater that the intervals of the bounding box, reduce them to be at most the the size of the intervals.

This is similar to a Gomory cut, but we apply the procedure to 2-D constraints only.

Three steps:

0. Check eligibility: 2-D constraint and either |a|>y_max-y_min or |b|>x_max-x_min. Assume or ensure that gcd(a,b)=1. This step must be performed by the caller.

  1. Perform a change of basis M to obtain (x,y)^t = M(x',y')^t and (a',b') = (a,b)M with b'>-a'>0
  2. Simplify constraint a'x'+b'y'<=c. The corresponding line is in the first quadrant and its slope is strictly less than 1 and greater than 0. Up to three new constraints may be generated.
  3. Apply M^-1 to the new contraints on (x',y') in order to obtain constraints on x and y, and return the constraint list.

Beware of overflows if you compute the widths of these intervals...

Perform the reverse change of basis cb on constraints in constraint list ineq

Definition at line 1569 of file sc_normalize.c.

1574 {
1576  Pvecteur nv = VECTEUR_NUL; // normalized constraint
1577  int cb = 0; // memorize the change of basis
1578  /* Beware of overflows if you compute the widths of these intervals... */
1579  Value x_min=VALUE_MIN, x_max=VALUE_MAX, y_min=VALUE_MIN, y_max=VALUE_MAX;
1580  Variable x, y;
1581 
1582  ifscdebug(1) {
1584 
1585  fprintf(stderr, "Initial constraint:\n");
1586  vect_fprint(stderr, v, variable_debug_name);
1587  }
1588 
1589  nv = compute_x_and_y_bounds(v, l, lb, u, ub, &x, &y, &x_min, &x_max, &cb);
1590 
1591  ifscdebug(1) {
1592  fprintf(stderr, "Bounds for the first variable %s: ", variable_debug_name(x));
1593  fprintf(stderr, "x_min=%lld, x_max=%lld\n", (long long int) x_min, (long long int) x_max);
1594  }
1595 
1596  if(false)
1598  &x, &y,
1599  &x_min, &x_max,
1600  &y_min, &y_max);
1601 
1602  ineq =
1604  x, x_min, x_max,
1605  y, y_min, y_max);
1606 
1607  /* Perform the reverse change of basis cb on constraints in
1608  constraint list ineq */
1609  if(cb!=0) {
1611  &x_min, &x_max, &y_min, &y_max);
1612  }
1613 
1614  if(!CONTRAINTE_UNDEFINED_P(ineq))
1615  check_coefficient_reduction(v, ineq, x, y, x_min, x_max);
1616 
1617  return ineq;
1618 }
void vect_fprint(FILE *f, Pvecteur v, get_variable_name_t variable_name)
void vect_fprint(FILE * f, Pvecteur v, char * (*variable_name)()): impression d'un vecteur creux v su...
Definition: io.c:124
static Pvecteur compute_x_and_y_bounds(Pvecteur v, Pvecteur l, Pvecteur lb, Pvecteur u, Pvecteur ub, Variable *px, Variable *py, Value *px_min, Value *px_max, int *pcb)
v is supposed to be the equation of a line in a 2-D space.
Definition: sc_normalize.c:327
static bool eligible_for_coefficient_reduction_with_bounding_box_p(Pvecteur v, Pvecteur l, Pvecteur lb, Pvecteur u, Pvecteur ub)
Is it possible to reduce the magnitude of at least one constraint coefficient because it is larger th...
Definition: sc_normalize.c:462
static void check_coefficient_reduction(Pvecteur v, Pcontrainte ineq, Variable x, Variable y, Value x_min, Value x_max)
debug function: check that all 2-D constraints c in ineq are equivalent to contraint v on interval [x...
static Pvecteur new_constraint_for_coefficient_reduction_with_bounding_box(Pvecteur v, int *pcb, Variable x, Variable y, Value *px_min, Value *px_max, Value *py_min, Value *py_max)
Compute a normalized version of the constraint v and the corresponding change of basis.
Definition: sc_normalize.c:572
static Pcontrainte small_positive_slope_reduce_coefficients_with_bounding_box(Pvecteur v, Variable x, Value x_min, Value x_max, Variable y, Value y_min __attribute__((unused)), Value y_max __attribute__((unused)))
Replace 2-D constraint v by a set of constraints when possible because variable x is bounded by [x_mi...
static void update_coefficient_signs_in_constraints(Pcontrainte eq, int cb, Variable x, Variable y, Value *x_min, Value *x_max, Value *y_min, Value *y_max)
Perform the inverse change of basis and update the intervals for later checks.

References assert, check_coefficient_reduction(), compute_x_and_y_bounds(), CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, eligible_for_coefficient_reduction_with_bounding_box_p(), fprintf(), new_constraint_for_coefficient_reduction_with_bounding_box(), small_positive_slope_reduce_coefficients_with_bounding_box(), update_coefficient_signs_in_constraints(), VALUE_MAX, VALUE_MIN, variable_debug_name, vect_fprint(), VECTEUR_NUL, and x.

Referenced by sc_bounded_normalization().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_add_normalize_eq()

Psysteme sc_add_normalize_eq ( Psysteme  ps,
Pcontrainte  eq 
)

Definition at line 2407 of file sc_normalize.c.

2410 {
2411  Pcontrainte c;
2412 
2413  if (!eq->vecteur) return(ps);
2414 
2416  if (egalite_normalize(eq))
2417  {
2418  c = ps->egalites,
2419  ps->egalites = eq,
2420  eq->succ = c;
2421  ps->nb_eq++;
2422 
2424  {
2425  sc_rm(ps);
2426  return(NULL);
2427  }
2428 
2429  sc_rm_empty_constraints(ps, true);
2430  }
2431 
2432  return(ps);
2433 }
bool egalite_normalize(Pcontrainte)
bool egalite_normalize(Pcontrainte eg): reduction d'une equation diophantienne par le pgcd de ses coe...
Definition: normalize.c:136
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
void sc_rm_empty_constraints(Psysteme ps, bool process_equalities)
package sc: elimination de redondance simple
Definition: sc_elim_eq.c:56
bool sc_elim_simple_redund_with_eq(Psysteme ps, Pcontrainte eg)
package sc
Pvecteur vecteur
struct Scontrainte * succ
Pcontrainte egalites
Definition: sc-local.h:70
int nb_eq
Definition: sc-local.h:72

References egalite_normalize(), eq, sc_elim_simple_redund_with_eq(), sc_rm(), sc_rm_empty_constraints(), Scontrainte::succ, vect_normalize(), and Scontrainte::vecteur.

+ Here is the call graph for this function:

◆ sc_add_normalize_ineq()

Psysteme sc_add_normalize_ineq ( Psysteme  ps,
Pcontrainte  ineq 
)

Definition at line 2435 of file sc_normalize.c.

2438 {
2439  Pcontrainte c;
2440 
2441  if (!ineq->vecteur) return(ps);
2442 
2443  vect_normalize(ineq->vecteur);
2444  if (inegalite_normalize(ineq))
2445  {
2446  c = ps->inegalites,
2447  ps->inegalites = ineq,
2448  ineq->succ = c;
2449  ps->nb_ineq++;
2450 
2451  if (!sc_elim_simple_redund_with_ineq(ps, ineq))
2452  {
2453  sc_rm(ps);
2454  return(NULL);
2455  }
2456 
2457  sc_rm_empty_constraints(ps, false);
2458  }
2459 
2460  return(ps);
2461 }
bool inegalite_normalize(Pcontrainte)
bool inegalite_normalize(Pcontrainte ineg): normalisation d'une inegalite a variables entieres; voir ...
Definition: normalize.c:156
bool sc_elim_simple_redund_with_ineq(Psysteme ps, Pcontrainte ineg)
bool sc_elim_simple_redund_with_ineq(Psysteme ps, Pcontrainte ineg): elimination des contraintes redo...
Pcontrainte inegalites
Definition: sc-local.h:71
int nb_ineq
Definition: sc-local.h:73

References inegalite_normalize(), sc_elim_simple_redund_with_ineq(), sc_rm(), sc_rm_empty_constraints(), Scontrainte::succ, vect_normalize(), and Scontrainte::vecteur.

+ Here is the call graph for this function:

◆ sc_bounded_normalization()

Psysteme sc_bounded_normalization ( Psysteme  ps)

Eliminate trivially redundant integer constraint using a O(n x d^2) algorithm, where n is the number of constraints and d the dimension.

And possibly detect an non feasible constraint system ps. Also, reduce the coefficients of 2-D constraints when possible.

This function must not be used to decide emptyness when checking redundancy with Fourier-Motzkin because this may increase the initial rational convex polyhedron. No integer point is added, but rational points may be added, which may lead to an accuracy loss when a convex hull is performed.

Principle: If two constant vectors, l et u, such that l<=x<=u, where x is the vector representing all variables, then the bound b of any constraint a.x<=b can be compared to a.k where k_i=u_i if a_i is positive, and k_i=l_i elsewhere. The constraint can be eliminated if a.k<=b.

It is not necessary to have upper and lower bounds for all components of x to compute the redundancy condition. It is sufficient to meet the condition:

\forall i s.t. a_i>0 \exists u_i and \forall i s.t. a_i<0 \exists b_i

The complexity is O(n x d) where n is the number of constraints and d the dimension, vs O(n^2 x d^2) for some other normalization functions.

With l and u available, we also use c, the vector containing constant variables. The variables are substituted by their constant values in equations and inequalities.

The normalization is not rational. It assumes that only integer points are relevant. For instance, 2x<=3 is reduced to x<=1. It would be possible to use the same function in rational, but the divisions should be removed, the bounding box would require six vectors, with two new vectors used to keep the variable coefficients, here 2, and the comparisons should be replaced by rational comparisons. Quite a lot of changes, although the general structure would stay the same.

This function was developped to cope successfully with Semantics/type03. The projection performed in transformer_intra_to_inter() explodes without this function.

Note that the upper and lower bounds, u and l, are stored in Pvecteur in an unusual way. The coefficients are used to store the constants.

Note also that constant terms are stored in the lhs in linear, but they are computed here as rhs. In other words, x - 2 <=0 is the internal storage, but the upper bound is 2 as in x<=2.

Note that the simple inequalities used to compute the bounding box cannot be eliminated. Hence, their exact copies are also preserved. Another redundancy test is necessary to get rid of them. They could be eliminated when computing the bounding box if the function updating the bounds returned the information. Note that non feasability cannot be checked because the opposite bound vectors are not passed. If they were, then no simple return code would do. THIS HAS BEEN CHANGED.

The same is true for equations. But the function updating the bounds cannot return directly two pieces of information: the constraint system is empty or the constraint is redundant.

It would be easier to simplify all constraints and then to add the bounding box constraints. Constraints must be normalized initially to avoid destroying useful constraints. For instance, 2i<=99 generates i<=49 whicg proves 21<=99 striclty redundant. THIS HAS BEEN PARTIALLY CHANGED.

Software engineering remarks

This function could be renamed sc_bounded_redundancy_elimination() and be placed into one of the two files, sc_elim_redund.c or sc_elim_simple_redund.c. It just happened that redundancy elimination uses normalization and gdb led me to sc_normalization() when I tried to debug Semantics/type03.c.

This function could be split into three functions, one to compute the bounding box, one to simplify a constraint system according to a bounding box and the third one calling those two, and the coefficient reduction function, which also uses the bounding box.

This split could be useful when projecting a system because the initial bounding box remains valid all along the projection, no matter that happens to the initial constraint. However, the bounding box might be improved with the projections... Since the bounding box computation is fast enough, the function was not split and the transformer (see Linear/C3 Library) projection uses it at each stage. Note that the bouding box may also disappear via overflows and redundancy detection. See for instance the disparition of declaration constraints in convex array regions when the corresponding option is set to true.

Compute the trivial upper and lower bounds for the systeme basis. Since we cannot distinguish between "exist" and "0", we need two extra basis to know if the bound exists or not

can be an equation or an inequality

First look for bounds in equalities, although they may have been exploited otherwise

FI: I do not trust the modulo operator

FI: value_div() instead of value_pdiv(); reason?

ps is empty with two contradictory equations supposedly trapped earlier

Secondly look for bounds in inequalities

This normalization is necessary in case a division is involved, or a useful constraint may be removed. For instance 2*i<=99 generates i<=49 which make 2*i<=99 strictly redundant.

The variable is bounded by zero

upper bound

lower bound

FI: I not too sure how div and pdiv operate nor on what I need here... This explains why the divisions are replicated after the test on the sign of the coefficient.

upper bound

lower bound

Check that the bounding box is not empty because a lower bound is strictly greater than the corresponding upper bound. This could be checked above each time a new bound is defined or redefined. Also, build the constant base, cb

The upper and lower bounds should be printed here for debug

Impression par intervalle, avec verification l<=u quand l et u sont tous les deux disponibles

lower>upper

Simplify equalities using cb and l

Check inequalities for redundancy with respect to ub and lb, if ub and lb contain a minum of information. Also simplify constraints using cb when possible.

new lower bound: useful to check feasiblity

new upper bound

old bound

a lower bound cannot be estimated

the bounding box does not contain enough information to check redundancy with the upper bound

Try to compute the bounds nub and nlb implied by the bounding box

I assume the constraint to be consistent with only one coefficient per dimension

move the bound to the right hand side of the inequality

an upper bound of var is needed

the value macro should be used

c<0 : a lower bound is needed for var

If the new bound nub is tighter, nub <= ob, ob-nub >= 0

Do not destroy the constraints defining the bounding box

The constraint eq is redundant

Preserve this constraint

The new estimated lower bound must be less than the upper bound of the constraint, or the system is empty.

the estimated lower bound, nlb, must be less or equal to the effective upper bound ob: nlb <= ob, 0<=ob-nlb

if ob==nlb, an equation has been detected but it is hard to exploit here

to have a nice breakpoint location

Try to reduce coefficients of 2-D constraints when one variable belongs to an interval.

Remove constraint v

Add the new constraints to the new constraint list, ncl

add the new constraint list to the system

Free all elements of the bounding box

Definition at line 1767 of file sc_normalize.c.

1768 {
1769  /* Compute the trivial upper and lower bounds for the systeme
1770  basis. Since we cannot distinguish between "exist" and "0", we
1771  need two extra basis to know if the bound exists or not */
1772  //Pbase b = sc_base(ps);
1773  Pvecteur u = VECTEUR_NUL;
1774  Pvecteur l = VECTEUR_NUL;
1775  Pbase ub = BASE_NULLE;
1776  Pbase lb = BASE_NULLE;
1777  Pvecteur cb = VECTEUR_NUL;
1778  Pcontrainte eq = CONTRAINTE_UNDEFINED; /* can be an equation or an inequality */
1779  bool empty_p = false;
1780 
1781  assert(sc_consistent_p(ps));
1782 
1783  /* First look for bounds in equalities, although they may have been
1784  exploited otherwise */
1785  for(eq = sc_egalites(ps); !CONTRAINTE_UNDEFINED_P(eq) && !empty_p;
1786  eq = contrainte_succ(eq)) {
1787  empty_p = !egalite_normalize(eq);
1789  int n = vect_size(v);
1790  Value k;
1791  if(n==1) {
1792  Variable var = vecteur_var(v);
1793  update_lower_and_upper_bounds(&u, &ub, &l, &lb, var, VALUE_ZERO);
1794  }
1795  else if(n==2 && (k=vect_coeff(TCST,v))!=0) {
1796  Variable var = vecteur_var(v);
1797  Value c = vecteur_val(v);
1798 
1799  if(var==TCST) {
1800  Pvecteur vn = vecteur_succ(v);
1801  var = vecteur_var(vn);
1802  c = vecteur_val(vn);
1803  }
1804 
1805  /* FI: I do not trust the modulo operator */
1806  if(c<0) {
1807  c = -c;
1808  k = -k;
1809  }
1810 
1811  Value r = modulo(k,c);
1812  if(r==0) {
1813  /* FI: value_div() instead of value_pdiv(); reason? */
1814  Value b_var = -value_div(k,c);
1815  empty_p = update_lower_and_upper_bounds(&u, &ub, &l, &lb, var, b_var);
1816  }
1817  else {
1818  /* ps is empty with two contradictory equations supposedly trapped earlier */
1819  empty_p = true;;
1820  }
1821  }
1822  }
1823 
1824  if(!empty_p) {
1825  /* Secondly look for bounds in inequalities */
1826  for(eq=sc_inegalites(ps); !CONTRAINTE_UNDEFINED_P(eq)&& !empty_p;
1827  eq = contrainte_succ(eq)) {
1828  /* This normalization is necessary in case a division is
1829  involved, or a useful constraint may be removed. For instance
1830  2*i<=99 generates i<=49 which make 2*i<=99 strictly
1831  redundant. */
1832  empty_p = !inegalite_normalize(eq);
1834  int n = vect_size(v);
1835  Value k = VALUE_ZERO;
1836  if(n==1) {
1837  Variable var = vecteur_var(v);
1838  if(var!=TCST) {
1839  /* The variable is bounded by zero */
1840  Value c = vecteur_val(v);
1841  if(value_pos_p(c)) /* upper bound */
1843  else /* lower bound */
1845  }
1846  }
1847  else if(n==2 && (k=vect_coeff(TCST,v))!=0) {
1848  Variable var = vecteur_var(v);
1849  Value c = vecteur_val(v);
1850  if(var==TCST) {
1851  Pvecteur vn = vecteur_succ(v);
1852  var = vecteur_var(vn);
1853  c = vecteur_val(vn);
1854  }
1855  /* FI: I not too sure how div and pdiv operate nor on what I
1856  need here... This explains why the divisions are replicated
1857  after the test on the sign of the coefficient. */
1858  if(value_pos_p(c)) { /* upper bound */
1859  Value b_var = value_pdiv(-k,c);
1860  update_lower_or_upper_bound(&u, &ub, var, b_var, !value_pos_p(c));
1861  }
1862  else { /* lower bound */
1863  Value b_var = value_pdiv(k-c-1,-c);
1864  update_lower_or_upper_bound(&l, &lb, var, b_var, !value_pos_p(c));
1865  }
1866  }
1867  }
1868 
1869  /* Check that the bounding box is not empty because a lower bound
1870  is strictly greater than the corresponding upper bound. This
1871  could be checked above each time a new bound is defined or
1872  redefined. Also, build the constant base, cb */
1873  Pvecteur vc;
1874  for(vc=ub; !VECTEUR_UNDEFINED_P(vc) && !empty_p; vc=vecteur_succ(vc)) {
1875  Variable var = vecteur_var(vc);
1876  Value upper = vect_coeff(var, u);
1877  if(value_notzero_p(vect_coeff(var, lb))) {
1878  Value lower = vect_coeff(var, l);
1879  if(lower>upper)
1880  empty_p = true;
1881  else if(lower==upper) {
1882  vect_add_elem(&cb, var, VALUE_ONE);
1883  }
1884  }
1885  }
1886 
1887  /* The upper and lower bounds should be printed here for debug */
1888  ifscdebug(1) {
1889  if(!VECTEUR_NUL_P(ub) || !VECTEUR_NUL_P(lb)) {
1890  if(empty_p) {
1891  fprintf(stderr, "sc_bounded_normalization: empty bounding box\n");
1892  }
1893  else {
1894  fprintf(stderr, "sc_bounded_normalization: "
1895  "base for upper bound and upper bound:\n");
1896  vect_dump(ub);
1897  vect_dump(u);
1898  fprintf(stderr, "sc_bounded_normalization: "
1899  "base for lower bound and lower bound:\n");
1900  vect_dump(lb);
1901  vect_dump(l);
1902  fprintf(stderr, "sc_bounded_normalization: constraints found:\n");
1903  /* Impression par intervalle, avec verification l<=u quand l et u
1904  sont tous les deux disponibles */
1905  Pvecteur vc;
1906  for(vc=ub; !VECTEUR_UNDEFINED_P(vc); vc=vecteur_succ(vc)) {
1907  Variable var = vecteur_var(vc);
1908  Value upper = vect_coeff(var, u);
1909  if(vect_coeff(var, lb)!=0) {
1910  Value lower = vect_coeff(var, l);
1911  if(lower<upper)
1912  fprintf(stderr, "%d <= %s <= %d\n", (int) lower,
1913  variable_debug_name(var),
1914  (int) upper);
1915  else if(lower==upper)
1916  fprintf(stderr, "%s == %d\n", variable_debug_name(var),
1917  (int) upper);
1918  else /* lower>upper */
1919  abort(); // should have been filtered above
1920  }
1921  else {
1922  fprintf(stderr, "%s <= %d\n", variable_debug_name(var),
1923  (int) upper);
1924  }
1925  }
1926  for(vc=lb; !VECTEUR_UNDEFINED_P(vc); vc=vecteur_succ(vc)) {
1927  Variable var = vecteur_var(vc);
1928  Value lower = vect_coeff(var, l);
1929  if(vect_coeff(var, ub)==0) {
1930  fprintf(stderr, "%d <= %s \n", (int) lower,
1931  variable_debug_name(var));
1932  }
1933  }
1934  }
1935  }
1936  }
1937 
1938  if(!empty_p) {
1939  /* Simplify equalities using cb and l */
1940  if(base_dimension(cb) >=1) {
1941  for(eq=sc_egalites(ps); !CONTRAINTE_UNDEFINED_P(eq);
1942  eq = contrainte_succ(eq))
1944  }
1945 
1946  /* Check inequalities for redundancy with respect to ub and lb,
1947  if ub and lb contain a minum of information. Also simplify
1948  constraints using cb when possible. */
1949  if(base_dimension(ub)+base_dimension(lb) >=1) {
1950  for(eq=sc_inegalites(ps);
1951  !CONTRAINTE_UNDEFINED_P(eq) && !empty_p; eq = contrainte_succ(eq)) {
1952 
1954 
1956  int n = vect_size(v);
1957  Pvecteur vc;
1958  Value nlb = VALUE_ZERO; /* new lower bound: useful to check feasiblity */
1959  Value nub = VALUE_ZERO; /* new upper bound */
1960  Value ob = VALUE_ZERO; /* old bound */
1961  bool lb_failed_p = false; /* a lower bound cannot be estimated */
1962  bool ub_failed_p = false; /* the bounding box does not contain
1963  enough information to check
1964  redundancy with the upper bound */
1965 
1966  /* Try to compute the bounds nub and nlb implied by the bounding box */
1967  for(vc=v; !VECTEUR_NUL_P(vc) && !(ub_failed_p&&lb_failed_p);
1968  vc = vecteur_succ(vc)) {
1969  Variable var = vecteur_var(vc);
1970  Value c = vecteur_val(vc);
1971  if(var==TCST) { /* I assume the constraint to be consistent
1972  with only one coefficient per dimension */
1973  value_assign(ob, value_uminus(c)); /* move the bound to the
1974  right hand side of the
1975  inequality */
1976  }
1977  else {
1978  if(value_pos_p(c)) { /* an upper bound of var is needed */
1979  if(vect_coeff(var, ub)!=0) { /* the value macro should be used */
1980  Value ub_var = vect_coeff(var, u);
1981  value_addto(nub, value_mult(c, ub_var));
1982  }
1983  else {
1984  ub_failed_p = true;
1985  }
1986  if(vect_coeff(var, lb)!=0) {
1987  Value lb_var = vect_coeff(var, l);
1988  value_addto(nlb, value_mult(c, lb_var));
1989  //fprintf(stderr, "c=%lld, lb_var=%lld, nlb=%d\n", c, lb_var, nlb);
1990  }
1991  else {
1992  lb_failed_p = true;
1993  }
1994  }
1995  else { /* c<0 : a lower bound is needed for var*/
1996  if(vect_coeff(var, lb)!=0) {
1997  Value lb_var = vect_coeff(var, l);
1998  value_addto(nub, value_mult(c, lb_var));
1999  }
2000  else {
2001  ub_failed_p = true;
2002  }
2003  if(vect_coeff(var, ub)!=0) {
2004  Value ub_var = vect_coeff(var, u);
2005  value_addto(nlb, value_mult(c, ub_var));
2006  //fprintf(stderr, "c=%lld, ub_var=%lld, nlb=%d\n", c, ub_var, nlb);
2007  }
2008  else {
2009  lb_failed_p = true;
2010  }
2011  }
2012  }
2013  }
2014 
2015  /* If the new bound nub is tighter, nub <= ob, ob-nub >= 0 */
2016  if(!ub_failed_p) {
2017  /* Do not destroy the constraints defining the bounding box */
2018  bool posz_p = value_posz_p(value_minus(ob,nub));
2019  bool pos_p = value_pos_p(value_minus(ob,nub));
2020  if( posz_p
2021  || (n>2 && posz_p)
2022  || (n==2 && value_zero_p(vect_coeff(TCST, v)) && posz_p)
2023  || (n==2 && value_notzero_p(vect_coeff(TCST, v)) && pos_p)
2024  || (n==1 && value_zero_p(vect_coeff(TCST, v)) && pos_p)) {
2025  /* The constraint eq is redundant */
2026  ifscdebug(1) {
2027  fprintf(stderr, "Redundant constraint:\n");
2028  vect_dump(v);
2029  }
2031  }
2032  else { /* Preserve this constraint */
2033  ;
2034  }
2035  }
2036 
2037  /* The new estimated lower bound must be less than the upper
2038  bound of the constraint, or the system is empty.*/
2039  if(!lb_failed_p) { /* the estimated lower bound, nlb, must
2040  be less or equal to the effective
2041  upper bound ob: nlb <= ob, 0<=ob-nlb */
2042  /* if ob==nlb, an equation has been detected but it is
2043  hard to exploit here */
2044  bool pos_p = value_posz_p(value_minus(ob,nlb));
2045  if(!pos_p) /* to have a nice breakpoint location */
2046  empty_p = true;
2047  }
2048  }
2049  }
2050  }
2051  }
2052 
2053  /* Try to reduce coefficients of 2-D constraints when one variable
2054  belongs to an interval. */
2055  if(!empty_p) {
2057  for(eq=sc_inegalites(ps);
2058  !CONTRAINTE_UNDEFINED_P(eq) && !empty_p; eq = contrainte_succ(eq)) {
2059  (void) contrainte_normalize(eq, false);
2062  Pcontrainte nc = reduce_coefficients_with_bounding_box(v, l, lb, u, ub);
2063  if(!CONTRAINTE_UNDEFINED_P(nc)) {
2064  ifscdebug(1) {
2065  fprintf(stderr, "New constraints:\n");
2066  inegalites_dump(nc);
2067  }
2068  /* Remove constraint v */
2070  /* Add the new constraints to the new constraint list, ncl */
2071  ncl = contrainte_append(ncl, nc);
2072  }
2073  else {
2074  empty_p = true;
2075  }
2076  }
2077  }
2078  /* add the new constraint list to the system */
2080  assert(sc_consistent_p(ps));
2081  sc_add_inegalites(ps, ncl);
2082  assert(sc_consistent_p(ps));
2083  }
2084 
2085  if(empty_p) {
2086  Psysteme ns = sc_empty(sc_base(ps));
2087  sc_base(ps) = BASE_NULLE;
2088  sc_rm(ps);
2089  ps = ns;
2090  }
2091  else if(base_dimension(cb)>=1 || base_dimension(lb)>=1 || base_dimension(ub)>=1) {
2092  sc_elim_empty_constraints(ps, true);
2093  sc_elim_empty_constraints(ps, false);
2094  ps = add_bounding_box_constraints(ps, cb, lb, ub, l, u);
2095  }
2096 
2097  /* Free all elements of the bounding box */
2098  vect_rm(l), vect_rm(lb), vect_rm(u), vect_rm(ub);
2099  vect_rm(cb);
2100 
2101  assert(sc_consistent_p(ps));
2102  return ps;
2103 }
#define modulo(a, b)
#define value_addto(ref, val)
#define value_mult(v, w)
whether the default is protected or not this define makes no sense any more...
#define value_div(v1, v2)
Pcontrainte contrainte_append(Pcontrainte c1, Pcontrainte c2)
Pcontrainte contrainte_append(c1, c2) Pcontrainte c1, c2;.
Definition: binaires.c:267
void eq_set_vect_nul(Pcontrainte)
void_eq_set_vect_nul(Pcontrainte c): transformation d'une contrainte en une contrainte triviale 0 == ...
Definition: unaires.c:84
bool cyclic_constraint_list_p(Pcontrainte)
Check if list l contains a cycle.
Definition: listes.c:141
bool contrainte_normalize(Pcontrainte, bool)
normalize.c
Definition: normalize.c:56
Psysteme sc_empty(Pbase b)
Psysteme sc_empty(Pbase b): build a Psysteme with one unfeasible constraint to define the empty subsp...
Definition: sc_alloc.c:319
void sc_elim_empty_constraints(Psysteme ps, bool process_equalities)
void sc_elim_empty_constraints(Psysteme ps, bool process_equalities): elimination des "fausses" contr...
static Pcontrainte reduce_coefficients_with_bounding_box(Pvecteur v, Pvecteur l, Pvecteur lb, Pvecteur u, Pvecteur ub)
If at least one of the coefficients of constraint v == ax+by<=c are greater that the intervals of the...
static void update_lower_or_upper_bound(Pvecteur *bound_p, Pvecteur *bound_base_p, Variable var, Value nb, bool lower_p)
Bounding box (not really a box most of the time)
Definition: sc_normalize.c:122
static Psysteme add_bounding_box_constraints(Psysteme ps, Pbase cb, Pbase lb, Pbase ub, Pvecteur l, Pvecteur u)
Add the constraints defined by cb, lb and ub in Psysteme ps.
static void simplify_constraint_with_bounding_box(Pcontrainte eq, Pbase cb, Pvecteur l, bool is_inequality_p __attribute__((unused)))
Use constants imposed by the bounding box to eliminate constant terms from constraint eq.
Definition: sc_normalize.c:251
static bool update_lower_and_upper_bounds(Pvecteur *ubound_p, Pvecteur *ubound_base_p, Pvecteur *lbound_p, Pvecteur *lbound_base_p, Variable var, Value nb)
Updates upper and lower bounds, (ubound_p, ubound_base_p) and (lbound_p, lbound_base_p),...
Definition: sc_normalize.c:169
#define base_dimension(b)
#define BASE_NULLE
MACROS SUR LES BASES.

References abort, add_bounding_box_constraints(), assert, base_dimension, BASE_NULLE, contrainte_append(), contrainte_normalize(), contrainte_succ, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, cyclic_constraint_list_p(), egalite_normalize(), eligible_for_coefficient_reduction_with_bounding_box_p(), eq, eq_set_vect_nul(), fprintf(), inegalite_normalize(), inegalites_dump(), modulo, reduce_coefficients_with_bounding_box(), sc_add_inegalites(), sc_consistent_p(), sc_elim_empty_constraints(), sc_empty(), sc_rm(), simplify_constraint_with_bounding_box(), TCST, update_lower_and_upper_bounds(), update_lower_or_upper_bound(), value_addto, value_assign, value_div, value_minus, value_mult, value_notzero_p, VALUE_ONE, value_pdiv, value_pos_p, value_posz_p, value_uminus, VALUE_ZERO, value_zero_p, variable_debug_name, vect_add_elem(), vect_coeff(), vect_dump(), vect_rm(), vect_size(), VECTEUR_NUL, VECTEUR_NUL_P, vecteur_succ, VECTEUR_UNDEFINED_P, vecteur_val, and vecteur_var.

Referenced by sc_normalize(), transformer_normalize(), and transformer_projection_with_redundancy_elimination_and_check().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_gcd_normalize()

void sc_gcd_normalize ( Psysteme  ps)

sc_gcd_normalize(ps)

Normalization by gcd's of equalities and inequalities

Normalization by gcd's

Definition at line 3337 of file sc_normalize.c.

3338 {
3339  Pcontrainte eq1,ineq1;
3340 
3341  if (!SC_UNDEFINED_P(ps)) {
3342 
3343  /* Normalization by gcd's */
3344 
3345  for (eq1 = ps->egalites; eq1 != NULL; eq1 = eq1->succ) {
3346  vect_normalize(eq1->vecteur);
3347  }
3348 
3349  for (ineq1 = ps->inegalites; ineq1 != NULL;ineq1 = ineq1->succ) {
3350  (void) contrainte_normalize(ineq1, false);
3351  }
3352  }
3353 }

References contrainte_normalize(), Ssysteme::egalites, Ssysteme::inegalites, Scontrainte::succ, vect_normalize(), and Scontrainte::vecteur.

Referenced by internal_sc_feasibility(), and sc_fourier_motzkin_feasibility_ofl_ctrl().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_normalize()

Psysteme sc_normalize ( Psysteme  ps)

Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires en nombres entiers ps, en place.

Normalisation de chaque contrainte, i.e. division par le pgcd des coefficients (cf. ?!? )

Verification de la non redondance de chaque contrainte avec les autres:

Pour les egalites, on elimine une equation si on a un systeme d'egalites de la forme :

a1/ Ax - b == 0, ou b1/ Ax - b == 0, Ax - b == 0, b - Ax == 0,

ou c1/ 0 == 0

Pour les inegalites, on elimine une inequation si on a un systeme de contraintes de la forme :

a2/ Ax - b <= c, ou b2/ 0 <= const (avec const >=0) Ax - b <= c

ou c2/ Ax == b, Ax <= c avec b <= c,

ou d2/ Ax <= b, Ax <= c avec c >= b ou b >= c

Il manque une elimination de redondance particuliere pour traiter les booleens. Si on a deux vecteurs constants, l et u, tels que l<=x<=u, alors la borne b de n'importe quelle contrainte a.x<=b peut etre comparee a a.k ou k_i=u_i si a_i est positif et k_i=l_i sinon. La contrainte a peut etre eliminee si a.k <= b. Si des composantes de x n'aparaissent dans aucune contrainte, on ne dispose en consequence pas de bornes, mais ca n'a aucune importance. On veut donc avoir une condition pour chaque contrainte: forall i s.t. a.i!=0 \exists l_i and b_i s.t. l_i<=x_i<=b_i. Voir sc_bounded_normalization().

sc_normalize retourne NULL quand la normalisation a montre que le systeme etait non faisable

BC: now returns sc_empty when not feasible to avoid unecessary copy_base in caller.

FI: should check the input for sc_empty_p()

I do not want to disturb every pass of Linear/C3 Library that uses directly or indirectly sc_normalize. Since sc_bounded_normalization() has been developped specifically for transformer_projection(), it is called directly from the function implementing transformer_projection(). But it is not sufficient for type03.

FI: this takes (a lot of) time but I do not know why: O(n^2)?

normalisation de chaque equation

FI: piece of code that will appear in many places... How can we call it: empty_sc()? sc_make_empty()? sc_to_empty()?

Definition at line 2152 of file sc_normalize.c.

2153 {
2154  Pcontrainte eq;
2155  bool is_sc_fais = true;
2156 
2157  /* I do not want to disturb every pass of Linear/C3 Library that uses directly
2158  * or indirectly sc_normalize. Since sc_bounded_normalization()
2159  * has been developped specifically for transformer_projection(),
2160  * it is called directly from the function implementing
2161  * transformer_projection(). But it is not sufficient for type03.
2162  */
2163  static int francois=1;
2164  if(francois==1 && ps && !sc_empty_p(ps) && !sc_rn_p(ps))
2165  ps = sc_bounded_normalization(ps);
2166 
2167  /* FI: this takes (a lot of) time but I do not know why: O(n^2)? */
2168  ps = sc_safe_kill_db_eg(ps);
2169 
2170  if (ps && !sc_empty_p(ps) && !sc_rn_p(ps)) {
2171  for (eq = ps->egalites;
2172  (eq != NULL) && is_sc_fais;
2173  eq=eq->succ) {
2174  /* normalisation de chaque equation */
2175  if (eq->vecteur) {
2177  if ((is_sc_fais = egalite_normalize(eq))== true)
2178  is_sc_fais = sc_elim_simple_redund_with_eq(ps,eq);
2179  }
2180  }
2181  for (eq = ps->inegalites;
2182  (eq!=NULL) && is_sc_fais;
2183  eq=eq->succ) {
2184  if (eq->vecteur) {
2186  if ((is_sc_fais = inegalite_normalize(eq))== true)
2187  is_sc_fais = sc_elim_simple_redund_with_ineq(ps,eq);
2188  }
2189  }
2190 
2191  ps = sc_safe_kill_db_eg(ps);
2192  if (!sc_empty_p(ps))
2193  {
2194  sc_elim_empty_constraints(ps, true);
2195  sc_elim_empty_constraints(ps, false);
2196  }
2197  }
2198 
2199  if (!is_sc_fais)
2200  {
2201  /* FI: piece of code that will appear in many places... How
2202  * can we call it: empty_sc()? sc_make_empty()? sc_to_empty()?
2203  */
2204  Psysteme new_ps = sc_empty(sc_base(ps));
2205  sc_base(ps) = BASE_UNDEFINED;
2206  sc_rm(ps);
2207  ps = new_ps;
2208  }
2209  return(ps);
2210 }
bool sc_rn_p(Psysteme sc)
bool sc_rn_p(Psysteme sc): check if the set associated to sc is the whole space, rn
Definition: sc_alloc.c:369
bool sc_empty_p(Psysteme sc)
bool sc_empty_p(Psysteme sc): check if the set associated to sc is the constant sc_empty or not.
Definition: sc_alloc.c:350
Psysteme sc_safe_kill_db_eg(Psysteme ps)
same as above, but returns an empty system if the system is not feasible
Definition: sc_elim_eq.c:191
Psysteme sc_bounded_normalization(Psysteme ps)
Eliminate trivially redundant integer constraint using a O(n x d^2) algorithm, where n is the number ...
#define BASE_UNDEFINED

References BASE_UNDEFINED, egalite_normalize(), Ssysteme::egalites, eq, inegalite_normalize(), Ssysteme::inegalites, sc_bounded_normalization(), sc_elim_empty_constraints(), sc_elim_simple_redund_with_eq(), sc_elim_simple_redund_with_ineq(), sc_empty(), sc_empty_p(), sc_rm(), sc_rn_p(), sc_safe_kill_db_eg(), Scontrainte::succ, vect_normalize(), and Scontrainte::vecteur.

Referenced by broadcast_of_dataflow(), build_list_of_min(), build_sc_nredund_2pass_ofl_ctrl(), build_third_comb(), cutting_conditions(), dataflows_on_reference(), dependence_cone_positive(), find_implicit_equation(), include_trans_on_LC_in_ref(), main(), make_scanning_over_tiles(), movement_computation(), new_system_with_only_live_variable(), nullify_factors(), pa_intersect_system(), parallel_tiling(), plc_elim_var_with_eg(), plint(), prepare_reindexing(), sc_build_triang_elim_redund(), sc_faisabilite_optim(), sc_fm_project_variables(), sc_minmax_of_variable(), sc_minmax_of_variable2(), sc_minmax_of_variable_optim(), sc_of_constrs(), sc_projection_concat_proj_on_variables(), sc_projection_optim_along_vecteur_ofl(), sc_resol_smith(), sc_safe_normalize(), sc_strong_normalize2(), sc_strong_normalize4(), sc_strong_normalize_and_check_feasibility(), sc_strong_normalize_and_check_feasibility2(), sc_supress_parallel_redund_constraints(), sc_supress_same_constraints(), sc_triang_elim_redund(), separate_variables(), separate_variables_2(), set_dimensions_of_local_variable_family(), smith_int(), sys_int_redond(), syst_smith(), TestDependence(), tiling_transformation(), and valuer().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_normalize2()

Psysteme sc_normalize2 ( volatile Psysteme  ps)

Psysteme sc_normalize2(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires en nombres entiers ps, en place.

Normalisation de chaque contrainte, i.e. division par le pgcd des coefficients (cf. ?!? )

Propagation des constantes definies par les equations dans les inequations. E.g. N==1.

Selection des variables de rang inferieur quand il y a ambiguite: N==M. M is used wherever possible.

Selection des variables eliminables exactement. E.g. N==4M. N is substituted by 4M wherever possible. Ceci permet de raffiner les constantes dans les inegalites.

Les equations de trois variables ou plus ne sont pas utilisees pour ne pas rendre les inegalites trop complexes.

Verification de la non redondance de chaque contrainte avec les autres.

Les contraintes sont normalisees par leurs PGCDs. Les constantes sont propagees dans les inegalites. Les paires de variables equivalentes sont propagees dans les inegalites en utilisant la variable de moindre rang dans la base.

Pour les egalites, on elimine une equation si on a un systeme d'egalites de la forme :

a1/ Ax - b == 0, ou b1/ Ax - b == 0,
Ax - b == 0, b - Ax == 0,

ou c1/ 0 == 0

Si on finit avec b==0, la non-faisabilite est detectee.

Pour les inegalites, on elimine une inequation si on a un systeme de contraintes de la forme :

a2/ Ax - b <= c, ou b2/ 0 <= const (avec const >=0) Ax - b <= c

ou c2/ Ax == b,
Ax <= c avec b <= c,

ou d2/ Ax <= b, Ax <= c avec c >= b ou b >= c

Les doubles inegalites syntaxiquement equivalentes a une egalite sont detectees: Ax <= b, Ax >= b

Si deux inegalites sont incompatibles, la non-faisabilite est detectee: b <= Ax <= c et c < b.

sc_normalize retourne NULL/SC_EMPTY quand la normalisation a montre que le systeme etait non faisable.

Une grande partie du travail est effectue dans sc_elim_db_constraints()

FI: a revoir de pres; devrait retourner SC_EMPTY en cas de non faisabilite

Eliminate variables linked by a two-term equation. Preserve integer information or choose variable with minimal rank in basis b if some ambiguity exists.

Then, after normalization, a1 and a2 must be one

An overflow is unlikely... but it should be handled here I guess rather than be subcontracted?

The substitution of the variable defined by "eq" by its value leads to an overflow in one some unknown constraint of "ps". It might be better to trap the overflow at a lower level, when you know which constraint fails because the constraint could be removed altogether.

Propagate constant definitions, only once although a triangular system might require n steps is the equations are in the worse order

An overflow is unlikely... but it should be handled here I guess rather than be subcontracted.

The substitution of the variable defined by "eq" by its value leads to an overflow in one some unknown constraint of "ps". It might be better to trap the overflow at a lower level, when you know which constraint fails because the constraint could be removed altogether.

Definition at line 2274 of file sc_normalize.c.

2276 {
2277  volatile Pcontrainte eq;
2278 
2279  ps = sc_elim_double_constraints(ps);
2280  sc_elim_empty_constraints(ps, true);
2281  sc_elim_empty_constraints(ps, false);
2282 
2283  if (!SC_UNDEFINED_P(ps)) {
2284  Pbase b = sc_base(ps);
2285 
2286  /* Eliminate variables linked by a two-term equation. Preserve integer
2287  information or choose variable with minimal rank in basis b if some
2288  ambiguity exists. */
2289  volatile Psysteme ps_backup = sc_copy(ps);
2290  bool failure_p = false;
2291  for (eq = ps->egalites; (!SC_UNDEFINED_P(ps) && eq != NULL); eq=eq->succ) {
2293  if(((vect_size(veq)==2) && (vect_coeff(TCST,veq)==VALUE_ZERO))
2294  || ((vect_size(veq)==3) && (vect_coeff(TCST,veq)!=VALUE_ZERO))) {
2295  Pbase bveq = make_base_from_vect(veq);
2296  Variable v1 = vecteur_var(bveq);
2297  Variable v2 = vecteur_var(vecteur_succ(bveq));
2298  volatile Variable v = VARIABLE_UNDEFINED;
2299  Value a1 = value_abs(vect_coeff(v1, veq));
2300  Value a2 = value_abs(vect_coeff(v2, veq));
2301 
2302  if(a1==a2) {
2303  /* Then, after normalization, a1 and a2 must be one */
2304  if(rank_of_variable(b, v1) < rank_of_variable(b, v2)) {
2305  v = v2;
2306  }
2307  else {
2308  v = v1;
2309  }
2310  }
2311  else if(value_one_p(a1)) {
2312  v = v1;
2313  }
2314  else if(value_one_p(a2)) {
2315  v = v2;
2316  }
2317  if(VARIABLE_DEFINED_P(v)) {
2318  /* An overflow is unlikely... but it should be handled here
2319  I guess rather than be subcontracted? */
2321  {
2322  /* The substitution of the variable defined by "eq" by its
2323  value leads to an overflow in one some unknown
2324  constraint of "ps". It might be better to trap the
2325  overflow at a lower level, when you know which
2326  constraint fails because the constraint could be
2327  removed altogether. */
2328  sc_rm(ps); /* */
2329  ps = ps_backup;
2330  failure_p = true;
2331  break;
2332  }
2333  TRY
2334  {
2335  sc_simple_variable_substitution_with_eq_ofl_ctrl(ps, eq, v, OFL_CTRL);
2336  }
2338  }
2339  }
2340  }
2341  if(!failure_p) {
2342  sc_rm(ps_backup);
2343  }
2344  }
2345 
2346  if (!SC_UNDEFINED_P(ps)) {
2347  /* Propagate constant definitions, only once although a triangular
2348  system might require n steps is the equations are in the worse order */
2349  volatile Psysteme ps_backup = sc_copy(ps);
2350  bool failure_p = false;
2351  for (eq = ps->egalites; (!SC_UNDEFINED_P(ps) && eq != NULL); eq=eq->succ) {
2353  if(((vect_size(veq)==1) && (vect_coeff(TCST,veq)==VALUE_ZERO))
2354  || ((vect_size(veq)==2) && (vect_coeff(TCST,veq)!=VALUE_ZERO))) {
2355  volatile Variable v = term_cst(veq)?
2356  vecteur_var(vecteur_succ(veq)) : vecteur_var(veq);
2357  Value a = term_cst(veq)? vecteur_val(vecteur_succ(veq)) : vecteur_val(veq);
2358 
2359  if(value_one_p(a) || value_mone_p(a) || vect_coeff(TCST,veq)==VALUE_ZERO
2360  || value_mod(vect_coeff(TCST,veq), a)==VALUE_ZERO) {
2361  /* An overflow is unlikely... but it should be handled here
2362  I guess rather than be subcontracted. */
2364  {
2365  /* The substitution of the variable defined by "eq" by its
2366  value leads to an overflow in one some unknown
2367  constraint of "ps". It might be better to trap the
2368  overflow at a lower level, when you know which
2369  constraint fails because the constraint could be
2370  removed altogether. */
2371  sc_rm(ps); /* */
2372  ps = ps_backup;
2373  failure_p = true;
2374  break;
2375  }
2376  TRY
2377  {
2378  sc_simple_variable_substitution_with_eq_ofl_ctrl(ps, eq, v, OFL_CTRL);
2379  }
2381  }
2382  else {
2383  sc_rm(ps);
2384  ps = SC_UNDEFINED;
2385  }
2386  }
2387  }
2388  if(!failure_p) {
2389  sc_rm(ps_backup);
2390  }
2391 
2392  ps = sc_elim_double_constraints(ps);
2393  sc_elim_empty_constraints(ps, true);
2394  sc_elim_empty_constraints(ps, false);
2395  }
2396 
2397  return(ps);
2398 }
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
#define value_mone_p(val)
#define value_one_p(val)
#define value_mod(v1, v2)
Pbase make_base_from_vect(Pvecteur pv)
Definition: base.c:109
int rank_of_variable(Pbase base, Variable var)
this function returns the rank of the variable var in the base 0 encodes TCST, but I do not know why,...
Definition: base.c:497
Psysteme sc_copy(Psysteme ps)
Psysteme sc_copy(Psysteme ps): duplication d'un systeme (allocation et copie complete des champs sans...
Definition: sc_alloc.c:230
Psysteme sc_elim_double_constraints(Psysteme ps)
Psysteme sc_elim_double_constraints(Psysteme ps): elimination des egalites et des inegalites identiqu...
#define VARIABLE_DEFINED_P(v)
Definition: vecteur-local.h:66
#define term_cst(varval)
#define OFL_CTRL
I do thing that overflows are managed in a very poor manner.

References CATCH, contrainte_vecteur, Ssysteme::egalites, eq, make_base_from_vect(), OFL_CTRL, overflow_error, rank_of_variable(), sc_copy(), sc_elim_double_constraints(), sc_elim_empty_constraints(), sc_rm(), Scontrainte::succ, TCST, term_cst, TRY, UNCATCH, value_abs, value_mod, value_mone_p, value_one_p, VALUE_ZERO, VARIABLE_DEFINED_P, VARIABLE_UNDEFINED, vect_coeff(), vect_size(), vecteur_succ, vecteur_val, and vecteur_var.

Referenced by effects_to_dma(), transformer_combine(), and transformer_normalize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_rational_feasibility()

static Psysteme sc_rational_feasibility ( Psysteme  sc)
static

Definition at line 2476 of file sc_normalize.c.

2477 {
2478 
2479  if(!sc_rational_feasibility_ofl_ctrl((sc), OFL_CTRL,true)) {
2480  sc_rm(sc);
2481  sc = SC_EMPTY;
2482  }
2483  return sc;
2484 }
bool sc_rational_feasibility_ofl_ctrl(Psysteme sc, int ofl_ctrl, bool ofl_res)

References OFL_CTRL, sc_rational_feasibility_ofl_ctrl(), and sc_rm().

Referenced by sc_strong_normalize3(), and sc_strong_normalize5().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_safe_normalize()

Psysteme sc_safe_normalize ( Psysteme  ps)

Psysteme sc_safe_normalize(Psysteme ps) output : ps, normalized.

modifies : ps. comment : when ps is not feasible, returns sc_empty.

Definition at line 2468 of file sc_normalize.c.

2470 {
2471 
2472  ps = sc_normalize(ps);
2473  return(ps);
2474 }
Psysteme sc_normalize(Psysteme ps)
Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires ...

References sc_normalize().

Referenced by array_must_fully_written_by_regions_p(), precondition_intra_to_inter(), transformer_projection(), and transformer_temporary_value_projection().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_strong_normalize()

Psysteme sc_strong_normalize ( Psysteme  ps)

Psysteme sc_strong_normalize(Psysteme ps)

Apply sc_normalize first. Then solve the equations in a copy of ps and propagate in equations and inequations.

Flag as redundant equations 0 == 0 and inequalities 0 <= k with k a positive integer constant when they appear.

Flag the system as non feasible if any equation 0 == k or any inequality 0 <= -k with k a strictly positive constant appears.

Then, we'll have to deal with remaining inequalities...

Argument ps is not modified by side-effect but it is freed for backward compatability. SC_EMPTY is returned for backward compatability.

The code is difficult to understand because a sparse representation is used. proj_ps is initially an exact copy of ps, with the same constraints in the same order. The one-to-one relationship between constraints must be maintained when proj_ps is modified. This makes it impossible to use most routines available in Linear.

Note: this is a redundancy elimination algorithm a bit too strong for sc_normalize.c...

Definition at line 2512 of file sc_normalize.c.

2513 {
2514  Psysteme new_ps =
2516  (ps, (Psysteme (*)(Psysteme)) NULL);
2517 
2518  return new_ps;
2519 }
Psysteme sc_strong_normalize_and_check_feasibility(volatile Psysteme ps, Psysteme(*check_feasibility)(Psysteme))

References sc_strong_normalize_and_check_feasibility().

Referenced by transformer_normalize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_strong_normalize2()

Psysteme sc_strong_normalize2 ( volatile Psysteme  ps)

Psysteme sc_strong_normalize2(Psysteme ps)

Apply sc_normalize first. Then solve the equations in ps and propagate substitutions in equations and inequations.

Flag as redundant equations 0 == 0 and inequalities 0 <= k with k a positive integer constant when they appear.

Flag the system as non feasible if any equation 0 == k or any inequality 0 <= -k with k a strictly positive constant appears.

Then, we'll have to deal with remaining inequalities...

Argument ps is modified by side-effect. SC_EMPTY is returned for backward compatability if ps is not feasible.

Note: this is a redundancy elimination algorithm a bit too strong for sc_normalize.c... but it's not strong enough to qualify as a normalization procedure.

Automatic variables read in a CATCH block need to be declared volatile as specified by the documentation

CA

Solve the equalities

eq might suffer in the substitution...

eq is redundant

keep eq

use eq to eliminate a variable

Let's use a variable with coefficient 1 if possible

A softer substitution is used

eq itself is going to be modified in ps. use a copy!

The system is not feasible. Stop

Check the inequalities

copy projected inequalities left in ps

sc_base(ps) = BASE_UNDEFINED;

Definition at line 2825 of file sc_normalize.c.

2826 {
2827 
2828 #define if_debug_sc_strong_normalize_2 if(false)
2829 
2830  Psysteme new_ps = sc_make(NULL, NULL);
2831  bool feasible_p = true;
2832 
2833  /* Automatic variables read in a CATCH block need to be declared volatile as
2834  * specified by the documentation*/
2835  Psysteme volatile ps_backup = sc_copy(ps);
2836 
2838  {
2839  /* CA */
2840  fprintf(stderr,"overflow error in normalization\n");
2841  new_ps=ps_backup;
2842  }
2843  TRY
2844  {
2846  fprintf(stderr, "[sc_strong_normalize2]: Begin\n");
2847  }
2848 
2849  if(!SC_UNDEFINED_P(ps)) {
2850  if(!SC_EMPTY_P(ps = sc_normalize(ps))) {
2855 
2857  fprintf(stderr,
2858  "[sc_strong_normalize2]: After call to sc_normalize\n");
2859  fprintf(stderr, "[sc_strong_normalize2]: Input system %p\n",
2860  ps);
2861  sc_default_dump(ps);
2862  }
2863 
2864  /* Solve the equalities */
2865  for(eq = sc_egalites(ps);
2867  eq = next_eq) {
2868 
2869  /* eq might suffer in the substitution... */
2870  next_eq = contrainte_succ(eq);
2871 
2872  if(egalite_normalize(eq)) {
2873  if(CONTRAINTE_NULLE_P(eq)) {
2874  /* eq is redundant */
2875  ;
2876  }
2877  else {
2879  Variable v = TCST;
2880  Pvecteur pv;
2881 
2882  /* keep eq */
2884  sc_add_egalite(new_ps, new_eq);
2885 
2886  /* use eq to eliminate a variable */
2887 
2888  /* Let's use a variable with coefficient 1 if
2889  * possible
2890  */
2891  for( pv = contrainte_vecteur(eq);
2892  !VECTEUR_NUL_P(pv);
2893  pv = vecteur_succ(pv)) {
2894  if(!term_cst(pv)) {
2895  v = vecteur_var(pv);
2896  if(value_one_p(vecteur_val(pv))) {
2897  break;
2898  }
2899  }
2900  }
2901  assert(v!=TCST);
2902 
2903  /* A softer substitution is used
2904  */
2905  /*
2906  if(sc_empty_p(ps =
2907  sc_variable_substitution_with_eq_ofl_ctrl
2908  (ps, eq, v, OFL_CTRL))) {
2909  feasible_p = false;
2910  break;
2911  }
2912  else {
2913  ;
2914  }
2915  */
2916 
2917  /* eq itself is going to be modified in ps.
2918  * use a copy!
2919  */
2920  def = contrainte_copy(eq);
2921  ps =
2922  sc_simple_variable_substitution_with_eq_ofl_ctrl
2923  (ps, def, v, NO_OFL_CTRL);
2924  contrainte_rm(def);
2925  /*
2926  int contrainte_subst_ofl_ctrl(v,def,c,eq_p, ofl_ctrl)
2927  */
2928  }
2929  }
2930  else {
2931  /* The system is not feasible. Stop */
2932  feasible_p = false;
2933  break;
2934  }
2935 
2937  fprintf(stderr,
2938  "Print the two systems at each elimination step:\n");
2939  fprintf(stderr, "[sc_strong_normalize2]: Input system %p\n",
2940  ps);
2941  sc_default_dump(ps);
2942  fprintf(stderr, "[sc_strong_normalize2]: New system %p\n",
2943  new_ps);
2944  sc_default_dump(new_ps);
2945  }
2946 
2947  }
2948  assert(!feasible_p ||
2950 
2951  /* Check the inequalities */
2952  feasible_p = !SC_EMPTY_P(ps = sc_normalize(ps));
2953 
2955  fprintf(stderr,
2956  "Print the three systems after inequality normalization:\n");
2957  fprintf(stderr, "[sc_strong_normalize2]: Input system %p\n",
2958  ps);
2959  sc_default_dump(ps);
2960  fprintf(stderr, "[sc_strong_normalize2]: New system %p\n",
2961  new_ps);
2962  sc_default_dump(new_ps);
2963  }
2964  }
2965  else {
2967  fprintf(stderr,
2968  "[sc_strong_normalize2]:"
2969  " Non-feasibility detected by first call to sc_normalize\n");
2970  }
2971  feasible_p = false;
2972  }
2973  }
2974  else {
2976  fprintf(stderr,
2977  "[sc_strong_normalize2]: Empty system as input\n");
2978  }
2979  feasible_p = false;
2980  }
2981 
2982  if(!feasible_p) {
2983  sc_rm(new_ps);
2984  new_ps = SC_EMPTY;
2985  }
2986  else {
2987  base_rm(sc_base(new_ps));
2988  sc_base(new_ps) = base_copy(sc_base(ps));
2989  sc_dimension(new_ps) = sc_dimension(ps);
2990  /* copy projected inequalities left in ps */
2991  new_ps = sc_safe_append(new_ps, ps);
2992  /* sc_base(ps) = BASE_UNDEFINED; */
2993  assert(sc_weak_consistent_p(new_ps));
2994  }
2995 
2996  sc_rm(ps);
2997  sc_rm(ps_backup);
2999  fprintf(stderr,
3000  "[sc_strong_normalize2]: Final value of new system %p:\n",
3001  new_ps);
3002  sc_default_dump(new_ps);
3003  fprintf(stderr, "[sc_strong_normalize2]: End\n");
3004  }
3006  }
3007  return new_ps;
3008 }
#define contrainte_rm(c)
the standard xxx_rm does not return a value
Pcontrainte contrainte_copy(Pcontrainte c_in)
Have a look at contrainte_dup and contraintes_dup which reverse the order of the list This copy versi...
Definition: alloc.c:254
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg)
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg): allocation et initialisation d'un systeme d'equ...
Definition: sc.c:78
bool sc_weak_consistent_p(Psysteme sc)
check that sc is well defined, that the numbers of equalities and inequalities are consistent with th...
Definition: sc.c:362
void sc_add_egalite(Psysteme p, Pcontrainte e)
void sc_add_egalite(Psysteme p, Pcontrainte e): macro ajoutant une egalite e a un systeme p; la base ...
Definition: sc_alloc.c:389
Psysteme sc_safe_append(Psysteme s1, Psysteme s2)
Psysteme sc_safe_append(Psysteme s1, Psysteme s2) input : output : calcul de l'intersection des polye...
void sc_default_dump(Psysteme sc)
void sc_default_dump(Psysteme sc): dump to stderr
Definition: sc_io.c:170
#define if_debug_sc_strong_normalize_2
static string new_eq()
Definition: splitc.c:543
#define NO_OFL_CTRL
#define base_rm(b)
Pbase base_copy(Pbase b)
Direct duplication.
Definition: alloc.c:300

References assert, base_copy(), base_rm, CATCH, contrainte_copy(), CONTRAINTE_NULLE_P, contrainte_rm, contrainte_succ, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, egalite_normalize(), eq, fprintf(), if_debug_sc_strong_normalize_2, new_eq(), NO_OFL_CTRL, overflow_error, sc_add_egalite(), sc_copy(), sc_default_dump(), sc_make(), sc_normalize(), sc_rm(), sc_safe_append(), sc_weak_consistent_p(), TCST, term_cst, TRY, UNCATCH, value_one_p, VECTEUR_NUL_P, vecteur_succ, vecteur_val, and vecteur_var.

Referenced by expression_less_than_in_context(), and transformer_normalize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_strong_normalize3()

Psysteme sc_strong_normalize3 ( Psysteme  ps)

Definition at line 2521 of file sc_normalize.c.

2522 {
2523  /*
2524  Psysteme new_ps =
2525  sc_strong_normalize_and_check_feasibility
2526  (ps, sc_elim_redund);
2527  */
2528  Psysteme new_ps =
2531 
2532  return new_ps;
2533 }
static Psysteme sc_rational_feasibility(Psysteme sc)

References sc_rational_feasibility(), and sc_strong_normalize_and_check_feasibility().

Referenced by transformer_normalize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_strong_normalize4()

Psysteme sc_strong_normalize4 ( Psysteme  ps,
char *(*)(Variable variable_name 
)

Psysteme sc_strong_normalize4(Psysteme ps, char * (*variable_name)(Variable))

Definition at line 3013 of file sc_normalize.c.

3014 {
3015  /*
3016  Psysteme new_ps =
3017  sc_strong_normalize_and_check_feasibility2
3018  (ps, sc_normalize, variable_name, VALUE_MAX);
3019  */
3020 
3021  Psysteme new_ps =
3023  (ps, sc_normalize, variable_name, 2);
3024 
3025  return new_ps;
3026 }
Psysteme sc_strong_normalize_and_check_feasibility2(volatile Psysteme ps, Psysteme(*check_feasibility)(Psysteme), char *(*variable_name)(Variable), int level)
Psysteme sc_strong_normalize_and_check_feasibility2 (Psysteme ps, Psysteme (*check_feasibility)(Psyst...
char * variable_name(Variable v)
polynome_ri.c
Definition: polynome_ri.c:73

References sc_normalize(), sc_strong_normalize_and_check_feasibility2(), and variable_name().

Referenced by transformer_empty_p(), and transformer_normalize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_strong_normalize5()

Psysteme sc_strong_normalize5 ( Psysteme  ps,
char *(*)(Variable variable_name 
)

Good, but pretty slow

Definition at line 3028 of file sc_normalize.c.

3029 {
3030  /* Good, but pretty slow */
3031  /*
3032  Psysteme new_ps =
3033  sc_strong_normalize_and_check_feasibility2
3034  (ps, sc_elim_redund, variable_name, 2);
3035  */
3036 
3037  Psysteme new_ps =
3040 
3041  return new_ps;
3042 }

References sc_rational_feasibility(), sc_strong_normalize_and_check_feasibility2(), and variable_name().

Referenced by check_range_wrt_precondition(), transformer_normalize(), and transformer_strongly_empty_p().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_strong_normalize_and_check_feasibility()

Psysteme sc_strong_normalize_and_check_feasibility ( volatile Psysteme  ps,
Psysteme(*)(Psysteme check_feasibility 
)

Automatic variables read in a CATCH block need to be declared volatile as specified by the documentation

CA

We need an exact copy of ps to have equalities and inequalities in the very same order

FI: may have is has been fixed with sc_dup() by now... see comments in sc_copy()

Solve the equalities

proj_eq might suffer in the substitution...

eq is redundant

keep eq

use proj_eq to eliminate a variable

Let's use a variable with coefficient 1 if possible

A softer substitution is needed in order to preserve the relationship between ps and proj_ps

proj_eq itself is going to be modified in proj_ps. use a copy!

The system is not feasible. Stop

Check the inequalities

ineq is redundant

keep ineq

ineq is redundant with another inequality: destroy ineq to avoid the mutual elimination of two identical constraints

The system is not feasible. Stop

Check redundancy between residual inequalities

sc_elim_simple_redund_with_ineq(ps,ineg)

Well, sc_normalize should not be able to do much here!

FI: test added for breakpoint placement

Definition at line 2535 of file sc_normalize.c.

2538 {
2539 
2540  volatile Psysteme new_ps = SC_UNDEFINED;
2541  volatile Psysteme proj_ps = SC_UNDEFINED;
2542  volatile bool feasible_p = true;
2543  /* Automatic variables read in a CATCH block need to be declared volatile as
2544  * specified by the documentation*/
2545  Psysteme volatile ps_backup = sc_copy(ps);
2546  /*
2547  fprintf(stderr, "[sc_strong_normalize]: Begin\n");
2548  */
2549 
2550 
2552  {
2553  /* CA */
2554  fprintf(stderr,"overflow error in normalization\n");
2555  new_ps=ps_backup;
2556  }
2557  TRY
2558  {
2559  if(!SC_UNDEFINED_P(ps)) {
2560  if(!SC_EMPTY_P(ps = sc_normalize(ps))) {
2564  Pcontrainte next_proj_eq = CONTRAINTE_UNDEFINED;
2565  Pcontrainte proj_ineq = CONTRAINTE_UNDEFINED;
2567  Pcontrainte new_ineq = CONTRAINTE_UNDEFINED;
2568 
2569  /*
2570  fprintf(stderr,
2571  "[sc_strong_normalize]: After call to sc_normalize\n");
2572  */
2573 
2574  /* We need an exact copy of ps to have equalities
2575  * and inequalities in the very same order
2576  *
2577  * FI: may have is has been fixed with sc_dup() by
2578  * now... see comments in sc_copy()
2579  */
2580  new_ps = sc_copy(ps);
2581  proj_ps = sc_copy(new_ps);
2582  sc_rm(new_ps);
2583  new_ps = sc_make(NULL, NULL);
2584 
2585  /*
2586  fprintf(stderr, "[sc_strong_normalize]: Input system %x\n",
2587  (unsigned int) ps);
2588  sc_default_dump(ps);
2589  fprintf(stderr, "[sc_strong_normalize]: Copy system %x\n",
2590  (unsigned int) ps);
2591  sc_default_dump(proj_ps);
2592  */
2593 
2594  /* Solve the equalities */
2595  for(proj_eq = sc_egalites(proj_ps),
2596  eq = sc_egalites(ps);
2597  !CONTRAINTE_UNDEFINED_P(proj_eq);
2598  eq = contrainte_succ(eq)) {
2599 
2600  /* proj_eq might suffer in the substitution... */
2601  next_proj_eq = contrainte_succ(proj_eq);
2602 
2603  if(egalite_normalize(proj_eq)) {
2604  if(CONTRAINTE_NULLE_P(proj_eq)) {
2605  /* eq is redundant */
2606  ;
2607  }
2608  else {
2610  /* keep eq */
2611  Variable v = TCST;
2612  Pvecteur pv;
2613 
2615  sc_add_egalite(new_ps, new_eq);
2616  /* use proj_eq to eliminate a variable */
2617 
2618  /* Let's use a variable with coefficient 1 if
2619  * possible
2620  */
2621  for( pv = contrainte_vecteur(proj_eq);
2622  !VECTEUR_NUL_P(pv);
2623  pv = vecteur_succ(pv)) {
2624  if(!term_cst(pv)) {
2625  v = vecteur_var(pv);
2626  if(value_one_p(vecteur_val(pv))) {
2627  break;
2628  }
2629  }
2630  }
2631  assert(v!=TCST);
2632 
2633  /* A softer substitution is needed in order to
2634  * preserve the relationship between ps and proj_ps
2635  */
2636  /*
2637  if(sc_empty_p(proj_ps =
2638  sc_variable_substitution_with_eq_ofl_ctrl
2639  (proj_ps, proj_eq, v, NO_OFL_CTRL))) {
2640  feasible_p = false;
2641  break;
2642  }
2643  else {
2644  ;
2645  }
2646  */
2647 
2648  /* proj_eq itself is going to be modified in proj_ps.
2649  * use a copy!
2650  */
2651  def = contrainte_copy(proj_eq);
2652  proj_ps =
2653  sc_simple_variable_substitution_with_eq_ofl_ctrl
2654  (proj_ps, def, v, NO_OFL_CTRL);
2655  contrainte_rm(def);
2656  /*
2657  int contrainte_subst_ofl_ctrl(v,def,c,eq_p, ofl_ctrl)
2658  */
2659  }
2660  }
2661  else {
2662  /* The system is not feasible. Stop */
2663  feasible_p = false;
2664  break;
2665  }
2666 
2667  /*
2668  fprintf(stderr,
2669  "Print the three systems at each elimination step:\n");
2670  fprintf(stderr, "[sc_strong_normalize]: Input system %x\n",
2671  (unsigned int) ps);
2672  sc_default_dump(ps);
2673  fprintf(stderr, "[sc_strong_normalize]: Copy system %x\n",
2674  (unsigned int) proj_ps);
2675  sc_default_dump(proj_ps);
2676  fprintf(stderr, "[sc_strong_normalize]: New system %x\n",
2677  (unsigned int) new_ps);
2678  sc_default_dump(new_ps);
2679  */
2680 
2681  proj_eq = next_proj_eq;
2682  }
2683  assert(!feasible_p ||
2685 
2686  /* Check the inequalities */
2687  for(proj_ineq = sc_inegalites(proj_ps),
2688  ineq = sc_inegalites(ps);
2689  feasible_p && !CONTRAINTE_UNDEFINED_P(proj_ineq);
2690  proj_ineq = contrainte_succ(proj_ineq),
2691  ineq = contrainte_succ(ineq)) {
2692 
2693  if(inegalite_normalize(proj_ineq)) {
2694  if(contrainte_constante_p(proj_ineq)
2695  && contrainte_verifiee(proj_ineq, false)) {
2696  /* ineq is redundant */
2697  ;
2698  }
2699  else {
2700  int i;
2701  i = sc_check_inequality_redundancy(proj_ineq, proj_ps);
2702  if(i==0) {
2703  /* keep ineq */
2704  new_ineq = contrainte_copy(ineq);
2705  sc_add_inegalite(new_ps, new_ineq);
2706  }
2707  else if(i==1) {
2708  /* ineq is redundant with another inequality:
2709  * destroy ineq to avoid the mutual elimination of
2710  * two identical constraints
2711  */
2712  eq_set_vect_nul(proj_ineq);
2713  }
2714  else if(i==2) {
2715  feasible_p = false;
2716  break;
2717  }
2718  else {
2719  assert(false);
2720  }
2721  }
2722  }
2723  else {
2724  /* The system is not feasible. Stop */
2725  feasible_p = false;
2726  break;
2727  }
2728  }
2729 
2730  /*
2731  fprintf(stderr,
2732  "Print the three systems after inequality normalization:\n");
2733  fprintf(stderr, "[sc_strong_normalize]: Input system %x\n",
2734  (unsigned int) ps);
2735  sc_default_dump(ps);
2736  fprintf(stderr, "[sc_strong_normalize]: Copy system %x\n",
2737  (unsigned int) proj_ps);
2738  sc_default_dump(proj_ps);
2739  fprintf(stderr, "[sc_strong_normalize]: New system %x\n",
2740  (unsigned int) new_ps);
2741  sc_default_dump(new_ps);
2742  */
2743 
2744  /* Check redundancy between residual inequalities */
2745 
2746  /* sc_elim_simple_redund_with_ineq(ps,ineg) */
2747 
2748  /* Well, sc_normalize should not be able to do much here! */
2749  /*
2750  new_ps = sc_normalize(new_ps);
2751  feasible_p = (!SC_EMPTY_P(new_ps));
2752  */
2753  }
2754  else {
2755  /*
2756  fprintf(stderr,
2757  "[sc_strong_normalize]:"
2758  " Non-feasibility detected by sc_normalize\n");
2759  */
2760  feasible_p = false;
2761  }
2762  }
2763  else {
2764  /*
2765  fprintf(stderr,
2766  "[sc_strong_normalize]: Empty system as input\n");
2767  */
2768  feasible_p = false;
2769  }
2770 
2771  if(feasible_p && check_feasibility != (Psysteme (*)(Psysteme)) NULL) {
2772  proj_ps = check_feasibility(proj_ps);
2773  feasible_p = !SC_EMPTY_P(proj_ps);
2774  }
2775 
2776  if(!feasible_p) {
2777  sc_rm(new_ps);
2778  //new_ps = SC_EMPTY; interpreted as R^n by the caller sometimes...
2779  new_ps = sc_empty(BASE_NULLE);
2780  }
2781  else {
2782  sc_base(new_ps) = sc_base(ps);
2783  sc_base(ps) = BASE_UNDEFINED;
2784  sc_dimension(new_ps) = sc_dimension(ps);
2785  /* FI: test added for breakpoint placement*/
2786  if(!sc_weak_consistent_p(new_ps))
2787  assert(sc_weak_consistent_p(new_ps));
2788  }
2789 
2790  sc_rm(proj_ps);
2791  sc_rm(ps);
2792  sc_rm(ps_backup);
2793  /*
2794  fprintf(stderr, "[sc_strong_normalize]: Final value of new system %x:\n",
2795  (unsigned int) new_ps);
2796  sc_default_dump(new_ps);
2797  fprintf(stderr, "[sc_strong_normalize]: End\n");
2798  */
2799 
2801  }
2802  return new_ps;
2803 }
bool contrainte_constante_p(Pcontrainte)
bool contrainte_constante_p(Pcontrainte c): test de contrainte triviale sans variables (ie du type 0<...
Definition: predicats.c:192
bool contrainte_verifiee(Pcontrainte, bool)
bool contrainte_verifiee(Pcontrainte ineg, bool eq_p): test de faisabilite d'inegalite (eq_p == false...
Definition: predicats.c:234
void sc_add_inegalite(Psysteme p, Pcontrainte i)
void sc_add_inegalite(Psysteme p, Pcontrainte i): macro ajoutant une inegalite i a un systeme p; la b...
Definition: sc_alloc.c:406
int sc_check_inequality_redundancy(Pcontrainte ineq, Psysteme ps)
int sc_check_inequality_redundancy(Pcontrainte ineq, Psysteme ps) Check if an inequality ineq,...

References assert, BASE_NULLE, BASE_UNDEFINED, CATCH, contrainte_constante_p(), contrainte_copy(), CONTRAINTE_NULLE_P, contrainte_rm, contrainte_succ, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, contrainte_verifiee(), egalite_normalize(), eq, eq_set_vect_nul(), fprintf(), inegalite_normalize(), new_eq(), NO_OFL_CTRL, overflow_error, sc_add_egalite(), sc_add_inegalite(), sc_check_inequality_redundancy(), sc_copy(), sc_empty(), sc_make(), sc_normalize(), sc_rm(), sc_weak_consistent_p(), TCST, term_cst, TRY, UNCATCH, value_one_p, VECTEUR_NUL_P, vecteur_succ, vecteur_val, and vecteur_var.

Referenced by sc_strong_normalize(), and sc_strong_normalize3().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sc_strong_normalize_and_check_feasibility2()

Psysteme sc_strong_normalize_and_check_feasibility2 ( volatile Psysteme  ps,
Psysteme(*)(Psysteme check_feasibility,
char *(*)(Variable variable_name,
int  level 
)

Psysteme sc_strong_normalize_and_check_feasibility2 (Psysteme ps, Psysteme (*check_feasibility)(Psysteme), char * (*variable_name)(Variable), int level)

Same as sc_strong_normalize2() but equations are used by increasing order of their numbers of variables, and, within one equation, the lexicographic minimal variables is chosen among equivalent variables.

Equations with more than "level" variables are not used for the substitution. Unless level==VALUE_MAX.

Finally, an additional normalization procedure is applied on the substituted system. Another stronger normalization can be chosen to benefit from the system size reduction (e.g. sc_elim_redund). Or a light one to benefit from the inequality simplifications due to equation solving (e.g. sc_normalize).

Automatic variables read in a CATCH block need to be declared volatile as specified by the documentation

CA

Solve the equalities (if any)

Start with equalities with the smallest number of variables and stop when all equalities have been used and or when all equalities left have too many variables.

&& sc_nbre_egalites(ps) != 0

eq might suffer in the substitution...

eq is redundant

Equalities change because of substitutions. Their dimensions may go under the present required dimension, nvar. Hence the non-equality test.

keep eq

use eq to eliminate a variable

Let's use a variable with coefficient 1 if possible. Among such variables, choose the lexicographically minimal one.

v1 = TCST;

because of the !CONTRAINTE_NULLE_P() test

eq itself is going to be modified in ps. use a copy!

too early to use this equation eq

If there any hope to use it in the future? Yes, if its dimension is no more than nvar+1 because one of its variable might be substituted. If more variable are substituted, it's dimension is going to go down and it will be counted later... Well this is not true, it will be lost:-(

to be on the safe side till I find a better idea...

The system is not feasible. Stop

This reaaly generates a lot of about on real life system!

This is a much too much expensive transformation in an innermost loop!

It cannot be used as a convergence test.

feasible_p = (!SC_EMPTY_P(ps = sc_normalize(ps)));

Check the inequalities

copy projected inequalities left in ps

sc_base(ps) = BASE_UNDEFINED;

assert(sc_weak_consistent_p(new_ps));

Definition at line 3064 of file sc_normalize.c.

3069 {
3070 
3071 #define if_debug_sc_strong_normalize_and_check_feasibility2 if(false)
3072 
3073  Psysteme new_ps = sc_make(NULL, NULL);
3074  bool feasible_p = true;
3075  /* Automatic variables read in a CATCH block need to be declared volatile as
3076  * specified by the documentation*/
3077  Psysteme volatile ps_backup = sc_copy(ps);
3078 
3080  {
3081  /* CA */
3082  fprintf(stderr,"overflow error in normalization\n");
3083  new_ps=ps_backup;
3084  }
3085  TRY
3086  {
3088  fprintf(stderr,
3089  "[sc_strong_normalize_and_check_feasibility2]"
3090  " Input system %p\n", ps);
3091  sc_default_dump(ps);
3092  }
3093 
3094  if(SC_UNDEFINED_P(ps)) {
3096  fprintf(stderr,
3097  "[sc_strong_normalize_and_check_feasibility2]"
3098  " Empty system as input\n");
3099  }
3100  feasible_p = false;
3101  }
3102  else if(SC_EMPTY_P(ps = sc_normalize(ps))) {
3104  fprintf(stderr,
3105  "[sc_strong_normalize_and_check_feasibility2]:"
3106  " Non-feasibility detected by first call to sc_normalize\n");
3107  }
3108  feasible_p = false;
3109  }
3110  else {
3115  int nvar;
3116  int neq = sc_nbre_egalites(ps);
3117 
3119  fprintf(stderr,
3120  "[sc_strong_normalize_and_check_feasibility2]"
3121  " Input system after normalization %p\n", ps);
3122  sc_default_dump(ps);
3123  }
3124 
3125 
3126  /*
3127  * Solve the equalities (if any)
3128  *
3129  * Start with equalities with the smallest number of variables
3130  * and stop when all equalities have been used and or when
3131  * all equalities left have too many variables.
3132  */
3133  for(nvar = 1;
3134  feasible_p && neq > 0 && nvar <= level /* && sc_nbre_egalites(ps) != 0 */;
3135  nvar++) {
3136  for(eq = sc_egalites(ps);
3137  feasible_p && !CONTRAINTE_UNDEFINED_P(eq);
3138  eq = next_eq) {
3139 
3140  /* eq might suffer in the substitution... */
3141  next_eq = contrainte_succ(eq);
3142 
3143  if(egalite_normalize(eq)) {
3144  if(CONTRAINTE_NULLE_P(eq)) {
3145  /* eq is redundant */
3146  ;
3147  }
3148  else {
3149  /* Equalities change because of substitutions.
3150  * Their dimensions may go under the present
3151  * required dimension, nvar. Hence the non-equality
3152  * test.
3153  */
3155 
3156  if(d<=nvar) {
3158  Variable v = TCST;
3159  Variable v1 = TCST;
3160  Variable v2 = TCST;
3161  Variable nv = TCST;
3162  Pvecteur pv;
3163 
3164  /* keep eq */
3166  sc_add_egalite(new_ps, new_eq);
3167 
3168  /* use eq to eliminate a variable */
3169 
3170  /* Let's use a variable with coefficient 1 if
3171  * possible. Among such variables,
3172  * choose the lexicographically minimal one.
3173  */
3174  v1 = TCST;
3175  v2 = TCST;
3176  for( pv = contrainte_vecteur(eq);
3177  !VECTEUR_NUL_P(pv);
3178  pv = vecteur_succ(pv)) {
3179  if(!term_cst(pv)) {
3180  nv = vecteur_var(pv);
3181  v2 = (v2==TCST)? nv : v2;
3182  if (value_one_p(vecteur_val(pv))) {
3183  if(v1==TCST) {
3184  v1 = nv;
3185  }
3186  else {
3187  /* v1 = TCST; */
3188  v1 =
3189  (strcmp(variable_name(v1),
3190  variable_name(nv))>=0)
3191  ? nv : v1;
3192  }
3193  }
3194  }
3195  }
3196  v = (v1==TCST)? v2 : v1;
3197  /* because of the !CONTRAINTE_NULLE_P() test */
3198  assert(v!=TCST);
3199 
3200  /* eq itself is going to be modified in ps.
3201  * use a copy!
3202  */
3203  def = contrainte_copy(eq);
3204  ps =
3205  sc_simple_variable_substitution_with_eq_ofl_ctrl
3206  (ps, def, v, NO_OFL_CTRL);
3207  contrainte_rm(def);
3208  }
3209  else {
3210  /* too early to use this equation eq */
3211  /* If there any hope to use it in the future?
3212  * Yes, if its dimension is no more than nvar+1
3213  * because one of its variable might be substituted.
3214  * If more variable are substituted, it's dimension
3215  * is going to go down and it will be counted later...
3216  * Well this is not true, it will be lost:-(
3217  */
3218  if(d<=nvar+1) {
3219  neq++;
3220  }
3221  else {
3222  /* to be on the safe side till I find a better idea... */
3223  neq++;
3224  }
3225  }
3226  }
3227  }
3228  else {
3229  /* The system is not feasible. Stop */
3230  feasible_p = false;
3231  break;
3232  }
3233 
3234  /* This reaaly generates a lot of about on real life system! */
3235  /*
3236  if_debug_sc_strong_normalize_and_check_feasibility2 {
3237  fprintf(stderr,
3238  "Print the two systems at each elimination step:\n");
3239  fprintf(stderr, "[sc_strong_normalize_and_check_feasibility2]: Input system %x\n",
3240  (unsigned int) ps);
3241  sc_default_dump(ps);
3242  fprintf(stderr, "[sc_strong_normalize_and_check_feasibility2]: New system %x\n",
3243  (unsigned int) new_ps);
3244  sc_default_dump(new_ps);
3245  }
3246  */
3247 
3248  /* This is a much too much expensive transformation
3249  * in an innermost loop!
3250  *
3251  * It cannot be used as a convergence test.
3252  */
3253  /* feasible_p = (!SC_EMPTY_P(ps = sc_normalize(ps))); */
3254 
3255  }
3256 
3258  fprintf(stderr,
3259  "Print the two systems at each nvar=%d step:\n", nvar);
3260  fprintf(stderr, "[sc_strong_normalize_and_check_feasibility2]: Input system %p\n",
3261  ps);
3262  sc_default_dump(ps);
3263  fprintf(stderr, "[sc_strong_normalize_and_check_feasibility2]: New system %p\n",
3264  new_ps);
3265  sc_default_dump(new_ps);
3266  }
3267  }
3268  sc_elim_empty_constraints(new_ps,true);
3269  sc_elim_empty_constraints(ps,true);
3270  assert(!feasible_p ||
3272 
3273  /* Check the inequalities */
3274  assert(check_feasibility != (Psysteme (*)(Psysteme)) NULL);
3275 
3276  feasible_p = feasible_p && !SC_EMPTY_P(ps = check_feasibility(ps));
3277 
3279  fprintf(stderr,
3280  "Print the three systems after inequality normalization:\n");
3281  fprintf(stderr, "[sc_strong_normalize_and_check_feasibility2]: Input system %p\n",
3282  ps);
3283  sc_default_dump(ps);
3284  fprintf(stderr, "[sc_strong_normalize_and_check_feasibility2]: New system %p\n",
3285  new_ps);
3286  sc_default_dump(new_ps);
3287  }
3288  }
3289 
3290  if(!feasible_p) {
3291  sc_rm(new_ps);
3292  new_ps = SC_EMPTY;
3293  }
3294  else {
3295  base_rm(sc_base(new_ps));
3296  sc_base(new_ps) = base_copy(sc_base(ps));
3297  sc_dimension(new_ps) = sc_dimension(ps);
3298  /* copy projected inequalities left in ps */
3299  new_ps = sc_safe_append(new_ps, ps);
3300  /* sc_base(ps) = BASE_UNDEFINED; */
3301  if (!sc_weak_consistent_p(new_ps))
3302  {
3303  fprintf(stderr,
3304  "[sc_strong_normalize_and_check_feasibility2]: "
3305  "Input system %p\n", ps);
3306  sc_default_dump(ps);
3307  fprintf(stderr,
3308  "[sc_strong_normalize_and_check_feasibility2]: "
3309  "New system %p\n", new_ps);
3310  sc_default_dump(new_ps);
3311  /* assert(sc_weak_consistent_p(new_ps)); */
3312  assert(false);
3313  }
3314  }
3315 
3316  sc_rm(ps);
3317  sc_rm(ps_backup);
3319  {
3320  fprintf(stderr,
3321  "[sc_strong_normalize_and_check_feasibility2]: Final value of new system %p:\n",
3322  new_ps);
3323  sc_default_dump(new_ps);
3324  fprintf(stderr, "[sc_strong_normalize_and_check_feasibility2]: End\n");
3325  }
3326 
3328  }
3329  return new_ps;
3330 }
int vect_dimension(Pvecteur v)
int vect_dimension(Pvecteur v): calcul du nombre de composantes non nulles et non constantes d'un vec...
Definition: reductions.c:64
#define level
#define if_debug_sc_strong_normalize_and_check_feasibility2

References assert, base_copy(), base_rm, CATCH, contrainte_copy(), CONTRAINTE_NULLE_P, contrainte_rm, contrainte_succ, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, egalite_normalize(), eq, fprintf(), if_debug_sc_strong_normalize_and_check_feasibility2, level, new_eq(), NO_OFL_CTRL, overflow_error, sc_add_egalite(), sc_copy(), sc_default_dump(), sc_elim_empty_constraints(), sc_make(), sc_normalize(), sc_rm(), sc_safe_append(), sc_weak_consistent_p(), TCST, term_cst, TRY, UNCATCH, value_one_p, variable_name(), vect_dimension(), VECTEUR_NUL_P, vecteur_succ, vecteur_val, and vecteur_var.

Referenced by sc_strong_normalize4(), and sc_strong_normalize5().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ simplify_constraint_with_bounding_box()

static void simplify_constraint_with_bounding_box ( Pcontrainte  eq,
Pbase  cb,
Pvecteur  l,
bool is_inequality_p   __attribute__(unused) 
)
static

Use constants imposed by the bounding box to eliminate constant terms from constraint eq.

Unless this is the constraint defining the bounding box? Destroy it any way to remove redundancy and expect the bounding box contraints to be added later.

Constant variables are defined by basis cb and their value are found in l (See description of bounding box above).

Substitute constant variables, computing a delta value to be added to the constant term and setting the variable coefficient to zero; we should have not only lb and ub but also cb, the base for the constant terms

We could check here if var has a constant value and eliminate it from the constraint v... if this did not break the surrounding loop on v... So the update is accumulated into a difference vector dv that is added to v at the end of the loop

We should update here the constant term with delta, the value accumulated with the constant terms

is_inequality_p &&

do not destroy this equation by simplification if it defines a constant...

For debugging: init_variable_debug_name(entity_local_name)

Definition at line 251 of file sc_normalize.c.

255 {
257  Pvecteur vc;
258  Pvecteur dv = VECTEUR_NUL;
259 
260  /* Substitute constant variables, computing a delta value to be
261  added to the constant term and setting the variable coefficient
262  to zero; we should have not only lb and ub but also cb, the base
263  for the constant terms */
264  for(vc=v; !VECTEUR_NUL_P(vc); vc = vecteur_succ(vc)) {
265  Variable var = vecteur_var(vc);
266  Value c = vecteur_val(vc);
267  /* We could check here if var has a constant value and eliminate
268  it from the constraint v... if this did not break the
269  surrounding loop on v... So the update is accumulated into a
270  difference vector dv that is added to v at the end of the
271  loop */
272  if(vect_coeff(var, cb)!=0) {
273  Value delta = value_direct_multiply(c, vect_coeff(var, l));
274  vect_add_elem(&dv, TCST, delta);
275  vect_add_elem(&dv, var, value_uminus(c));
276  }
277  }
278  /* We should update here the constant term with delta, the
279  value accumulated with the constant terms */
280  if(!VECTEUR_NUL_P(dv)) {
281  Pvecteur nv = vect_add(v, dv);
282  bool substitute_p = true;
283  if(false && /*!is_inequality_p &&*/ VECTEUR_NUL_P(nv)) {
284  /* do not destroy this equation by simplification if it defines
285  a constant... */
286  int n = vect_size(v);
287  Value cst = vect_coeff(TCST, v);
288  if((n==1 && value_zero_p(cst)) || (n==2 && value_notzero_p(cst)))
289  substitute_p = false;
290  }
291  if(substitute_p) {
292  ifscdebug(1) {
293  /* For debugging: init_variable_debug_name(entity_local_name) */
294  fprintf(stderr, "Initial constraint v=%p:\n", v);
295  vect_dump(v);
296  fprintf(stderr, "Difference dv=%p:\n", dv);
297  vect_dump(dv);
298  fprintf(stderr, "New constraint nv=%p:\n", nv);
299  vect_dump(nv);
300  }
301  vect_rm(v);
302  vect_rm(dv);
303  v = nv;
304  contrainte_vecteur(eq) = nv;
305  //assert(vect_check(nv));
306  }
307  else {
308  vect_rm(dv);
309  vect_rm(nv);
310  //assert(vect_check(v));
311  }
312  }
313 }
#define value_direct_multiply(v1, v2)
Pvecteur vect_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53

References contrainte_vecteur, eq, fprintf(), TCST, value_direct_multiply, value_notzero_p, value_uminus, value_zero_p, vect_add(), vect_add_elem(), vect_coeff(), vect_dump(), vect_rm(), vect_size(), VECTEUR_NUL, VECTEUR_NUL_P, vecteur_succ, vecteur_val, and vecteur_var.

Referenced by sc_bounded_normalization().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ small_positive_slope_reduce_coefficients_with_bounding_box()

static Pcontrainte small_positive_slope_reduce_coefficients_with_bounding_box ( Pvecteur  v,
Variable  x,
Value  x_min,
Value  x_max,
Variable  y,
Value y_min   __attribute__(unused),
Value y_max   __attribute__(unused) 
)
static

Replace 2-D constraint v by a set of constraints when possible because variable x is bounded by [x_min,x_max].

The set of constraints contains one, two or three new constraints.

The slope of constraint v wrt variable x is in interval ]0,1[. On other words, if v is interpreted as a x + b y + c <=0, a is negative and b is greater than -a. Also b is greater than |low-up|. All these constraints have been checked earlier.

Retrieve coefficients and variables in v = ax+by+c

Compute two integer vertices for x_min and x_max using constraint ax+by+c=0, y = (- c - ax)/b

Reminder: the slope is positive, the function is increasing and y_x_min and y_x_max are upper bounds

x must be bounded, but y bounds are useless; they simply make the resolution more complex

In case, both x and y are bounded we think it useful to take advantage of the interval product

Compute two integer vertices for y_min and y_max using constraint ax+by+c=0, x = (- c - by)/a

The constraint ax+by+c=0 has at most two valid intersections with the bounding box. Because the slope is positive, 0<-a/b<1, the minimum point is obtained with x_min or y_min and the maximum point is obtained with x_max or y_max.

Constraint redundant with the bounding box should have been eliminated earlier with a simpler technique.

The constraint is a redundant tangent

The change of coordinates was meaningful when bounding both x and y

One new horizontal constraint defined by the two vertices lmp and rmp: y<=lmpy; test case slope01.c

Two constraints defined by (lmp,lrmp) and (lrmp, rmp). test case slope02.c

Only one constraint defined by : test case slope03.c

The slope is sufficiently large to find up to three constraints: look for the leftmost and rightmost integer points between (lmpx, lmpy) and (rmpx,rmpy) that meet v and are above nv, the line between (lmpx,lmpy) and (rmpx,rmpy). Let them be (ilmpx, ilmpy) and (irmpx, irmpy).

If ilmpx>irmpx, on constraint is enough, nv, because no intermediate points exist.

If ilmpx=irmpx, two constraints are necessary and they are defined by the two couples of points ((lmpx,lmpy),(ilmpx, ilmpy) and ((irmpx, irmpy), (rmpx, rmpy)).

Else ilmpx<irmpx, three constraints are necessary and they are defined by the segments delimited by the four points, (lmpx, lmpy), (ilmpx, ilmpy), (irmpx, irmpy) and (rmpx,rmpy). Only if no new intermediate point exists between the two intermediate points.

Test case: slope04.c

Default option

Definition at line 1205 of file sc_normalize.c.

1212 {
1213  Value a = VALUE_ZERO;
1214  Value b = VALUE_ZERO;
1215  Value c = VALUE_ZERO;
1216  Value lmpx, lmpy; // left most vertex
1217  Value rmpx, rmpy; // right most vertex
1219 
1220  ifscdebug(1) {
1221  fprintf(stderr, "%s:\n", __FUNCTION__);
1222  fprintf(stderr, "Constraint after change of basis:");
1223  vect_fprint(stderr, v, variable_debug_name);
1224  fprintf(stderr, "Interval for %s: x_min=%lld, x_max=%lld\n",
1225  variable_debug_name(x), x_min, x_max);
1226  }
1227 
1228  /* Retrieve coefficients and variables in v = ax+by+c */
1229  Pvecteur vc;
1230  for(vc=v; !VECTEUR_UNDEFINED_P(vc); vc=vecteur_succ(vc)) {
1231  Variable var = vecteur_var(vc);
1232  if(var!=TCST) {
1233  if(var==x) {
1234  a = vect_coeff(var, vc);
1235  }
1236  else {
1237  b = vect_coeff(var, vc);
1238  }
1239  }
1240  else
1241  c = vect_coeff(var, vc);
1242  }
1243 
1244  /* Compute two integer vertices for x_min and x_max using constraint
1245  ax+by+c=0, y = (- c - ax)/b */
1246  assert(value_ne(x_min, VALUE_MIN) && value_ne(x_max, VALUE_MAX));
1247 
1248  /* Reminder: the slope is positive, the function is increasing and
1249  y_x_min and y_x_max are upper bounds */
1250  Value y_x_min =
1252  Value y_x_max =
1254 
1255  /* x must be bounded, but y bounds are useless; they simply make the
1256  resolution more complex */
1257  /* In case, both x and y are bounded we think it useful to take
1258  advantage of the interval product */
1259  if(false) {
1260  Value x_y_min, x_y_max;
1261  bool found_p, redundant_p;
1262  /* Compute two integer vertices for y_min and y_max using constraint
1263  ax+by+c=0, x = (- c - by)/a */
1264  x_y_min =
1266  x_y_max =
1268 
1269  /* The constraint ax+by+c=0 has at most two valid intersections with
1270  the bounding box. Because the slope is positive, 0<-a/b<1, the
1271  minimum point is obtained with x_min or y_min and the maximum
1272  point is obtained with x_max or y_max.
1273 
1274  Constraint redundant with the bounding box should have been
1275  eliminated earlier with a simpler technique.
1276  */
1277  if(value_ge(y_x_min, y_min) && value_le(y_x_min, y_max)) {
1278  if(value_lt(y_x_min, y_max)) {
1279  // The left most point is (x_min, y_x_min)
1280  lmpx = x_min;
1281  lmpy = y_x_min;
1282  found_p = true;
1283  }
1284  else {
1285  // The constraint is a redundant tangent
1286  redundant_p = true;
1287  }
1288  }
1289  if(!redundant_p && value_ge(x_y_min, x_min) && value_le(x_y_min, x_max)) {
1290  if(value_lt(x_y_min, x_max)) {
1291  // The left most point is (x_y_min, y_min)
1292  lmpx = x_min;
1293  lmpy = y_x_min;
1294  found_p = true;
1295  }
1296  else {
1297  // The constraint is a redundant tangent
1298  redundant_p = true;
1299  }
1300  }
1301  if(!found_p)
1302  redundant_p = true;
1303  assert(!redundant_p);
1304  fprintf(stderr, "lmpx=%d, lmpy=%d\n", (int) lmpx, (int) lmpy);
1305  if(value_ge(y_x_max, y_min) && value_le(y_x_max, y_max)) {
1306  if(value_lt(y_x_max, y_max)) {
1307  // The right most point is (x_max, y_x_max)
1308  rmpx = x_min;
1309  rmpy = y_x_min;
1310  found_p = true;
1311  }
1312  else if(value_lt(y_x_max, y_min)) {
1313  /* The constraint is a redundant tangent */
1314  redundant_p = true;
1315  }
1316  }
1317  if (!redundant_p && !found_p
1318  && value_ge(x_y_max, x_max) && value_le(x_y_max, x_max)) {
1319  if (value_lt(x_y_max, x_max)) {
1320  // The right most point is (x_y_max, y_max)
1321  rmpx = x_min;
1322  rmpy = y_x_min;
1323  found_p = true;
1324  }
1325  else {
1326  // The constraint is a redundant tangent
1327  redundant_p = true;
1328  }
1329  }
1330  if(!found_p)
1331  redundant_p = true;
1332  assert(!redundant_p && found_p);
1333  }
1334 
1335  /* The change of coordinates was meaningful when bounding both x and y */
1336  lmpx = x_min;
1337  lmpy = y_x_min;
1338  rmpx = x_max;
1339  rmpy = y_x_max;
1340  ifscdebug(1) {
1341  fprintf(stderr, "lmpx=%d, lmpy=%d\n", (int) lmpx, (int) lmpy);
1342  fprintf(stderr, "rmpx=%d, rmpy=%d\n", (int) rmpx, (int) rmpy);
1343  }
1344 
1345  if (value_le(value_minus(rmpy,lmpy), VALUE_ZERO)) {
1346  /* One new horizontal constraint defined by the two vertices lmp
1347  and rmp: y<=lmpy; test case slope01.c */
1348  Pvecteur nv = VECTEUR_NUL;
1349  nv = vect_make(nv, y, VALUE_ONE, NULL, NULL, NULL);
1350  vect_add_elem(&nv, TCST, value_uminus(lmpy));
1351  ineq = contrainte_make(nv);
1352  ifscdebug(1) fprintf(stderr, "Case slope01\n");
1353  }
1354  else if (value_le(value_minus(rmpy,lmpy), VALUE_ONE)) {
1355  // There may be one vertex on the left of rmp, lrmp, with a lrmpx
1356  // + b rmpy <= -c, b rmpy + c <= -ax, lrmpx >= (c + b rmpy -a -1)/(-a)
1357  Value lrmpx =
1358  value_pdiv(
1359  value_plus(c, value_plus(value_mult(b, rmpy),
1361  VALUE_MONE))),
1362  value_uminus(a));
1363  if(value_gt(lrmpx, lmpx) && value_lt(lrmpx, rmpx)) {
1364  /* Two constraints defined by (lmp,lrmp) and (lrmp, rmp). test
1365  case slope02.c */
1367  Pvecteur nv1 = vect_make_line(x, y, lmpx, lmpy, lrmpx, rmpy);
1368  nv1 = vect_multiply(nv1, VALUE_MONE);
1369  Pvecteur nv2 = vect_make(nv, y, VALUE_ONE, NULL, NULL, NULL);
1370  vect_add_elem(&nv2, TCST, value_uminus(rmpy));
1371  Pcontrainte ineq1 = contrainte_make(nv1);
1372  Pcontrainte ineq2 = contrainte_make(nv2);
1373  contrainte_succ(ineq1) = ineq2;
1374  ineq = ineq1;
1375  ifscdebug(1) fprintf(stderr, "Case slope02\n");
1376  }
1377  else if(value_eq(lrmpx, rmpx)) {
1378  /* Only one constraint defined by : test case slope03.c */
1379  Pvecteur nv = vect_make_line(x, y, lmpx, lmpy, lrmpx, rmpy);
1380  nv = vect_multiply(nv, VALUE_MONE);
1381  ineq = contrainte_make(nv);
1382  ifscdebug(1) fprintf(stderr, "Case slope03\n");
1383  }
1384  }
1385  else {
1386  /* The slope is sufficiently large to find up to three
1387  constraints: look for the leftmost and rightmost integer points
1388  between (lmpx, lmpy) and (rmpx,rmpy) that meet v and are above
1389  nv, the line between (lmpx,lmpy) and (rmpx,rmpy). Let them be
1390  (ilmpx, ilmpy) and (irmpx, irmpy).
1391 
1392  If ilmpx>irmpx, on constraint is enough, nv, because no
1393  intermediate points exist.
1394 
1395  If ilmpx=irmpx, two constraints are necessary and they are
1396  defined by the two couples of points ((lmpx,lmpy),(ilmpx,
1397  ilmpy) and ((irmpx, irmpy), (rmpx, rmpy)).
1398 
1399  Else ilmpx<irmpx, three constraints are necessary and they are
1400  defined by the segments delimited by the four points, (lmpx,
1401  lmpy), (ilmpx, ilmpy), (irmpx, irmpy) and (rmpx,rmpy). Only if
1402  no new intermediate point exists between the two intermediate
1403  points.
1404 
1405  Test case: slope04.c
1406  */
1407  /* Default option */
1408  if(false) {
1409  Pvecteur nv = vect_copy(v);
1410  ineq = contrainte_make(nv); // equivalent to doing nothing
1411  fprintf(stderr, "Not implemented yet\n");
1412  }
1413  else {
1414  /*
1415  ineq = find_intermediate_constraints(v, x, y,
1416  lmpx, lmpy,
1417  rmpx, rmpy);
1418  */
1420  lmpx, lmpy,
1421  rmpx, rmpy);
1422  }
1423  }
1424  return ineq;
1425 }
#define value_ne(v1, v2)
#define value_eq(v1, v2)
bool operators on values
#define value_plus(v1, v2)
binary operators on values
#define value_lt(v1, v2)
if(!(yy_init))
Definition: genread_lex.c:1029
Pcontrainte find_intermediate_constraints_recursively(Pvecteur v, Variable x, Variable y, Value lmpx, Value lmpy, Value rmpx, Value rmpy)
Find a set ineq of 2-D constraints equivalent to 2-D constraint v==ax+by+c over the interval [lmpx,...
Definition: sc_normalize.c:995
#define VECTEUR_UNDEFINED
Pbase vect_copy(Pvecteur b)
direct duplication.
Definition: alloc.c:240

References assert, contrainte_make(), contrainte_succ, CONTRAINTE_UNDEFINED, find_intermediate_constraints_recursively(), fprintf(), TCST, value_eq, value_ge, value_gt, value_le, value_lt, VALUE_MAX, VALUE_MIN, value_minus, VALUE_MONE, value_mult, value_ne, VALUE_ONE, value_pdiv, value_plus, value_uminus, VALUE_ZERO, variable_debug_name, vect_add_elem(), vect_coeff(), vect_copy(), vect_fprint(), vect_make(), vect_make_line(), vect_multiply(), VECTEUR_NUL, vecteur_succ, VECTEUR_UNDEFINED, VECTEUR_UNDEFINED_P, vecteur_var, and x.

Referenced by reduce_coefficients_with_bounding_box().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ small_slope_and_first_quadrant_p()

static bool small_slope_and_first_quadrant_p ( Pvecteur  v)
static

Check that the coefficients on the first and second variables, x and y, define a increasing line.

With a slope less than one? Used to be a condition, but was lifted.

Internal check used after a change of frame.

Note: dangerous use of term ordering inside a linear sparse vector.

Should work, although inefficiently for large slopes.

Definition at line 531 of file sc_normalize.c.

532 {
533  Value a = VALUE_ZERO;
534  Value b = VALUE_ZERO;
535  Pvecteur vc;
536  bool ok_p = true;
537 
538  ok_p = (vect_size(v)==2 && value_zero_p(vect_coeff(TCST, v)))
539  || (vect_size(v)==3 && value_notzero_p(vect_coeff(TCST, v)));
540 
541  if(ok_p) {
542  for(vc=v; !VECTEUR_UNDEFINED_P(vc); vc=vecteur_succ(vc)) {
543  Variable var = vecteur_var(vc);
544  if(var!=TCST) {
545  if(value_zero_p(a))
546  a = vect_coeff(var, vc);
547  else
548  b = vect_coeff(var, vc);
549  }
550  }
551  }
552 
553  ok_p = value_neg_p(a) && value_pos_p(b) && value_gt(b, value_uminus(a));
554 
555  return ok_p;
556 }

References TCST, value_gt, value_neg_p, value_notzero_p, value_pos_p, value_uminus, VALUE_ZERO, value_zero_p, vect_coeff(), vect_size(), vecteur_succ, VECTEUR_UNDEFINED_P, and vecteur_var.

Referenced by new_constraint_for_coefficient_reduction_with_bounding_box().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ swap_value_intervals()

static void swap_value_intervals ( Value px_min,
Value px_max,
Value py_min,
Value py_max 
)
static

Definition at line 64 of file sc_normalize.c.

66 {
67  swap_values(px_min, py_min);
68  swap_values(px_max, py_max);
69 }
static void swap_values(Value *p1, Value *p2)
Definition: sc_normalize.c:57

References swap_values().

Referenced by new_constraint_for_coefficient_reduction_with_bounding_box().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ swap_values()

static void swap_values ( Value p1,
Value p2 
)
static

Definition at line 57 of file sc_normalize.c.

58 {
59  Value t = *p1;
60  *p1 = *p2;
61  *p2 = t;
62 }

Referenced by swap_value_intervals().

+ Here is the caller graph for this function:

◆ update_coefficient_signs_in_constraints()

static void update_coefficient_signs_in_constraints ( Pcontrainte  eq,
int  cb,
Variable  x,
Variable  y,
Value x_min,
Value x_max,
Value y_min,
Value y_max 
)
static

Perform the inverse change of basis and update the intervals for later checks.

Definition at line 1444 of file sc_normalize.c.

1449 {
1450  Pcontrainte ceq;
1451  for(ceq=eq; !CONTRAINTE_UNDEFINED_P(ceq); ceq = contrainte_succ(ceq)) {
1452  Pvecteur v = contrainte_vecteur(ceq);
1454  }
1455  if(cb&4)
1456  negate_value_interval(x_min,x_max);
1457  if(cb&2)
1458  negate_value_interval(y_min,y_max);
1459 }
static void update_coefficient_signs_in_vector(Pvecteur v, int cb, Variable x, Variable y)
Perform a reverse change of base to go back into the source code frame.

References contrainte_succ, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, eq, negate_value_interval(), update_coefficient_signs_in_vector(), and x.

Referenced by reduce_coefficients_with_bounding_box().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_coefficient_signs_in_vector()

static void update_coefficient_signs_in_vector ( Pvecteur  v,
int  cb,
Variable  x,
Variable  y 
)
static

Perform a reverse change of base to go back into the source code frame.

Definition at line 1429 of file sc_normalize.c.

1431 {
1432  if(cb&4) {
1433  Value a = vect_coeff(x, v);
1434  vect_chg_coeff(&v, x, value_uminus(a));
1435  }
1436  if(cb&2) {
1437  Value b = vect_coeff(y, v);
1438  vect_chg_coeff(&v, y, value_uminus(b));
1439  }
1440 }
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val)
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val): mise de la coordonnee var du vecteur *pp...
Definition: unaires.c:143

References value_uminus, vect_chg_coeff(), vect_coeff(), and x.

Referenced by update_coefficient_signs_in_constraints().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_lower_and_upper_bounds()

static bool update_lower_and_upper_bounds ( Pvecteur ubound_p,
Pvecteur ubound_base_p,
Pvecteur lbound_p,
Pvecteur lbound_base_p,
Variable  var,
Value  nb 
)
static

Updates upper and lower bounds, (ubound_p, ubound_base_p) and (lbound_p, lbound_base_p), with equations var==nb.

Do not test for nb==0. This would increase the code size a lot for a very limited benefit.

This function returns a boolean to signal an empy interval, i.e. a non-feasible system.

Auxiliary function of sc_bounded_normalization() new bound

Some constraint like 0==0, i.e. the NULL vector, or 0==3 an impossible constraint

Update the upper bound

A pre-existing upper bound exists

The new bound nb is stricter and consistent with the preexisting upper bound

ignore the non feasability

but maintain consistency to avoid a later abort

Update the lower bound, almost identical, but for the compatibility check

A lower bound has already been defined

The new bound nb is stricter and consistent with the preexisting lower bound

ps is empty with contradictory equations and inequalities supposedly trapped earlier

ignore the non feasability

but maintain consistency to avoid a later abort

Definition at line 169 of file sc_normalize.c.

175 {
176  bool empty_p = false;
177 
178  if(var==TCST) {
179  /* Some constraint like 0==0, i.e. the NULL vector, or 0==3 an impossible constraint */
180  // abort();
181  if(!value_zero_p(nb))
182  empty_p = true;
183  }
184  else {
185  /* Update the upper bound */
186  if(vect_coeff(var,*ubound_base_p)!=0) {
187  /* A pre-existing upper bound exists */
188  Value ob = vect_coeff(var, *ubound_p);
189  if(value_gt(ob, nb)) {
190  /* The new bound nb is stricter and consistent with the preexisting upper bound */
191  vect_add_elem(ubound_p, var, value_minus(nb,ob));
192  }
193  else if(value_eq(ob,nb))
194  ;
195  else {
196  empty_p = true;
197  //abort();
198  ; /* ignore the non feasability */
199  /* but maintain consistency to avoid a later abort */
200  //vect_add_elem(ubound_p, var, value_minus(nb,ob));
201  }
202  }
203  else {
204  base_add_dimension(ubound_base_p, var);
205  vect_add_elem(ubound_p, var, nb);
206  }
207 
208  /* Update the lower bound, almost identical, but for the
209  compatibility check */
210  if(vect_coeff(var,*lbound_base_p)!=0) {
211  /* A lower bound has already been defined */
212  Value ob = vect_coeff(var, *lbound_p);
213  if(value_lt(ob, nb)) {
214  /* The new bound nb is stricter and consistent with the
215  preexisting lower bound */
216  vect_add_elem(lbound_p, var, value_minus(nb,ob));
217  }
218  else if(value_eq(ob,nb))
219  ;
220  else {
221  empty_p = true;
222  /* ps is empty with contradictory equations and inequalities
223  supposedly trapped earlier */
224  // abort();
225  ; /* ignore the non feasability */
226  /* but maintain consistency to avoid a later abort */
227  //vect_add_elem(lbound_p, var, value_minus(nb,ob));
228  }
229  }
230  else {
231  base_add_dimension(lbound_base_p, var);
232  vect_add_elem(lbound_p, var, nb);
233  }
234  if(!empty_p && vect_coeff(var, *lbound_p)!=vect_coeff(var,*ubound_p))
235  abort();
236  }
237  return empty_p;
238 }
#define base_add_dimension(b, v)

References abort, base_add_dimension, TCST, value_eq, value_gt, value_lt, value_minus, value_zero_p, vect_add_elem(), and vect_coeff().

Referenced by sc_bounded_normalization().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_lower_or_upper_bound()

static void update_lower_or_upper_bound ( Pvecteur bound_p,
Pvecteur bound_base_p,
Variable  var,
Value  nb,
bool  lower_p 
)
static

Bounding box (not really a box most of the time)

The bounding box is made of all 1-D constraints found in a constraint system and is represented by five vectors ub, lb, cb, u and l.

The function sc_bounded_normalization() and the function reduce_coefficients_with_bounding_box() both rely on numerical bounds l and b for vector x, such that l<=x<=b.

However, lower and upper bounds are not always available for all components x_i of x. And 0 is a perfectly valid bound, that is not represented with linear sparse vector representation. Hence, the bound information cannot be carried by only two vectors. Four vectors are used, two basis vectors, lb and ub, used to specifiy if a bound is available, and two vectors l and b to contain the bounds.

Note that l and u are not usual vectors. The constant bounds appear as variable coefficients. For instance, l=2u+3v, together with lb=u+v+w, means that the lower bounds for x_u, x_v and x_w are 2, 3 and 0.

When the lower and upper bounds are known and equal, another base vector, cb, is introduced to flag the constants.

FI: I do not want to introduce a new data structure to represent a bounding box, and I do not like the idea of keeping independently five vectors...

However, I could not think of a simple data structure to store the bounding box as a unique object. With more variables, it would be better to use hash tables to link variables to their lower and upper bound and to their value when they are constant. Hence the use of four sparse vectors as explained above. Auxiliary functions for sc_bounded_normalization(): build the bounding box

Update bound information for variable var. A lower or upper bound_p and bound_base_p must be passer regardless of lower_p. lower_p is only used to know how to tighten the bound if it is already defined. The information to use is:

lower_p? var <= nb : var>=nb

It is not possible to detect an empty system here because information on both bounds is not available simultaneously. lb, l, ub and u should all be passed for the check.

A bound is already known. It must be updated if the new one is better.

previous bound

bigger is better

update bound

The current constraint is redundant

smaller is better

update bound

The current constraint is redundant

No bound is known yet

Parameters
lower_pnew bound

Definition at line 122 of file sc_normalize.c.

127 {
128  if(vect_coeff(var, *bound_base_p)!=0) {
129  /* A bound is already known. It must be updated if the new one is better. */
130  Value pb = vect_coeff(var, *bound_p); /* previous bound */
131  if(lower_p) { /* bigger is better */
132  if(nb>pb) { /* update bound */
133  // vect_chg_coeff() should be used for a simpler update...
134  vect_add_elem(bound_p, var, value_minus(nb,pb));
135  }
136  else {
137  /* The current constraint is redundant */
138  ;
139  }
140  }
141  else { /* smaller is better */
142  if(nb<pb) { /* update bound */
143  vect_add_elem(bound_p, var, value_minus(nb,pb));
144  }
145  else {
146  /* The current constraint is redundant */
147  ;
148  }
149  }
150  }
151  else {
152  /* No bound is known yet */
153  base_add_dimension(bound_base_p, var);
154  vect_add_elem(bound_p, var, nb);
155  }
156 }
static bool(* bound_p)(entity)

References base_add_dimension, bound_p, value_minus, vect_add_elem(), and vect_coeff().

Referenced by sc_bounded_normalization().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ vect_make_line()

static Pvecteur vect_make_line ( Variable  x,
Variable  y,
Value  x0,
Value  y0,
Value  x1,
Value  y1 
)
static

FI: Could be moved in vecteur library...

Compute the equation of the line joining (x0,y0) and (x1,y1)

(x1-x0) y = (y1 -y0) (x - x0) + y0 (x1-x0)

as ax+by+c=0, where a, b and c are prime together.

constant term: -x0 dy + y0 dx

Definition at line 671 of file sc_normalize.c.

673 {
674  Value dx = value_minus(x1,x0);
675  Value dy = value_minus(y1,y0);
676  Value a = dy;
677  Value b = -dx;
678  assert(dx!=0 || dy!=0);
679  /* constant term: -x0 dy + y0 dx */
680  Value c = value_minus(value_mult(y0, dx), value_mult(x0, dy));
681  Pvecteur v = vect_new(x, a);
682  vect_add_elem(&v, y, b);
683  vect_add_elem(&v, TCST, c);
684  vect_normalize(v);
685  return v;
686 }
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110

References assert, TCST, value_minus, value_mult, vect_add_elem(), vect_new(), vect_normalize(), and x.

Referenced by build_convex_constraints_from_vertices(), find_intermediate_constraints(), find_intermediate_constraints_recursively(), and small_positive_slope_reduce_coefficients_with_bounding_box().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: