PIPS
unaires.c
Go to the documentation of this file.
1 /*
2 
3  $Id: unaires.c 1671 2019-06-26 19:14:11Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of Linear/C3 Library.
8 
9  Linear/C3 Library is free software: you can redistribute it and/or modify it
10  under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  Linear/C3 Library is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with Linear/C3 Library. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25  /* PACKAGE CONTRAINTE - OPERATIONS UNAIRES
26  */
27 
28 #ifdef HAVE_CONFIG_H
29  #include "config.h"
30 #endif
31 
32 #include <stdio.h>
33 #include "linear_assert.h"
34 #include <stdlib.h>
35 
36 #include "boolean.h"
37 #include "arithmetique.h"
38 #include "vecteur.h"
39 #include "contrainte.h"
40 
41 /* norm_eq: normalisation d'une contrainte par le pgcd de TOUS les
42  * coefficients, i.e. y compris le terme constant
43  */
44 void norm_eq(nr)
45 Pcontrainte nr;
46 {
47  vect_normalize(nr->vecteur);
48 }
49 
50 /* void contrainte_chg_sgn(Pcontrainte eq): changement de signe d'une
51  * contrainte, i.e. multiplication par -1. Les equations ne sont pas
52  * modifiees mais les inequations sont transformees.
53  *
54  * Ancien nom: ch_sgn
55  */
57 Pcontrainte c;
58 {
59  vect_chg_sgn(c->vecteur);
60 }
61 
62 
63 /* void contrainte_reverse(Pcontrainte eq): changement de signe d'une
64  * contrainte, i.e. multiplication par -1, et ajout de la constante 1.
65  *
66  */
68 Pcontrainte c;
69 {
71  vect_add_elem(&(c->vecteur), TCST, VALUE_ONE);
72 }
73 
74 /* void_eq_set_vect_nul(Pcontrainte c): transformation d'une contrainte
75  * en une contrainte triviale 0 == 0
76  *
77  * cette fonction est utile lorsque l'on veut eliminer plusieurs
78  * contraintes du systeme sans avoir a le restructurer apres chaque
79  * elimination.
80  *
81  * Pour eliminer toutes ces "fausses" contraintes on utilise a la fin la
82  * fonction "syst_elim_eq" (ou "sc_rm_empty_constraints"...)
83  */
85 Pcontrainte c;
86 {
87  if(!CONTRAINTE_UNDEFINED_P(c)) {
90  }
91 }
92 
93 /* Pcontrainte contrainte_translate(Pcontrainte c, Pbase b,
94  * char * (*variable_name)()):
95  * normalisation des vecteurs de base utilises dans c par rapport
96  * a la base b utilisant les "noms" des vecteurs de base; en sortie
97  * tous les vecteurs de base utilises dans c appartiennent a b;
98  */
100 Pcontrainte c;
101 Pbase b;
102 char * (*variable_name)();
103 {
104  if(!CONTRAINTE_UNDEFINED_P(c))
106  variable_name);
107 
108  return c;
109 }
110 
111 /* Pcontrainte contrainte_variable_rename(Pcontrainte c, Variable v_old,
112  * Variable v_new):
113  * rename the potential coordinate v_old in c as v_new
114  */
116 Pcontrainte c;
117 Variable v_old;
118 Variable v_new;
119 {
120  if(!CONTRAINTE_UNDEFINED_P(c))
122  v_old, v_new);
123 
124  return c;
125 }
126 
127 /* void Pcontrainte_separate_on_vars(initial, vars, pwith, pwithout)
128  * Pcontrainte initial;
129  * Pbase vars;
130  * Pcontrainte *pwith, *pwithout;
131  *
132  * IN: initial, vars
133  * OUT: pwith, pwithout
134  *
135  * builds two Pcontraintes from the one given, using the
136  * constraint_without_vars criterium.
137  *
138  * (c) FC 16/05/94
139  */
140 void Pcontrainte_separate_on_vars(initial, vars, pwith, pwithout)
141 Pcontrainte initial;
142 Pbase vars;
143 Pcontrainte *pwith, *pwithout;
144 {
146  c = (Pcontrainte) NULL,
147  new = CONTRAINTE_UNDEFINED;
148 
149  for(c=initial,
150  *pwith=(Pcontrainte)NULL,
151  *pwithout=(Pcontrainte)NULL;
152  c!=(Pcontrainte) NULL;
153  c=c->succ)
154  if (constraint_without_vars(c, vars))
155  new = contrainte_make(vect_dup(c->vecteur)),
156  new->succ = *pwithout,
157  *pwithout = new;
158  else
159  new = contrainte_make(vect_dup(c->vecteur)),
160  new->succ = *pwith,
161  *pwith = new;
162 }
163 
164 /* void constraints_for_bounds(var, pinit, plower, pupper)
165  * Variable var;
166  * Pcontrainte *pinit, *plower, *pupper;
167  * IN: var, *pinit;
168  * OUT: *pinit, *plower, *pupper;
169  *
170  * separate the constraints involving var for upper and lower bounds
171  * The constraints are removed from the original system.
172  * everything is touched. Should be fast because there is no allocation.
173  *
174  * FC 28/11/94
175  */
176 void constraints_for_bounds(var, pinit, plower, pupper)
177 Variable var;
178 Pcontrainte *pinit, *plower, *pupper;
179 {
180  Value
181  v;
183  c, next,
184  remain = NULL,
185  lower = NULL,
186  upper = NULL;
187 
188  for(c = *pinit, next=(c==NULL ? NULL : c->succ);
189  c!=NULL;
190  c=next, next=(c==NULL ? NULL : c->succ))
191  {
192  v = vect_coeff(var, c->vecteur);
193 
194  if (value_pos_p(v))
195  c->succ = upper, upper = c;
196  else if (value_neg_p(v))
197  c->succ = lower, lower = c;
198  else /* v==0 */
199  c->succ = remain, remain = c;
200  }
201 
202  *pinit = remain,
203  *plower = lower,
204  *pupper = upper;
205 }
206 
207 /* Pcontrainte contrainte_dup_extract(c, var)
208  * Pcontrainte c;
209  * Variable var;
210  *
211  * returns a copy of the constraints of c which contain var.
212  *
213  * FC 27/09/94
214  */
216 Pcontrainte c;
217 Variable var;
218 {
220  result = NULL,
221  pc, ctmp;
222 
223  for (pc=c; pc!=NULL; pc=pc->succ)
224  if ((var==NULL) || vect_coeff(var, pc->vecteur)!=0)
225  ctmp = contrainte_dup(pc),
226  ctmp->succ = result,
227  result = ctmp;
228 
229  return(result);
230 }
231 
232 /* Pcontrainte contrainte_extract(pc, base, var)
233  * Pcontrainte *pc;
234  * Pbase base;
235  * Variable var;
236  *
237  * returns the constraints of *pc of which the higher rank variable from base
238  * is var. These constraints are removed from *pc.
239  *
240  * FC 27/09/94
241  */
243 Pcontrainte *pc;
244 Pbase base;
245 Variable var;
246 {
247  int
248  rank = rank_of_variable(base, var);
250  ctmp = NULL,
251  result = NULL,
252  cprev = NULL,
253  c = *pc;
254 
255  while (c!=NULL)
256  {
257  if (search_higher_rank(c->vecteur, base)==rank)
258  {
259  /*
260  * c must be extracted
261  */
262  ctmp = c->succ,
263  c->succ = result,
264  result = c,
265  c = ctmp;
266 
267  if (cprev==NULL)
268  *pc = ctmp;
269  else
270  cprev->succ=ctmp;
271  }
272  else
273  c=c->succ,
274  cprev=(cprev==NULL) ? *pc : cprev->succ;
275  }
276 
277  return(result);
278 }
279 
280 /* int level_contrainte(Pcontrainte pc, Pbase base_index)
281  * compute the level (rank) of the constraint pc in the nested loops.
282  * base_index is the index basis in the good order
283  * The result corresponds to the rank of the greatest index in the constraint,
284  * and the sign of the result corresponds to the sign of the coefficient of
285  * this index
286  *
287  * For instance:
288  * base_index :I->J->K ,
289  * I - J <=0 ==> level -2
290  * I + J + K <=0 ==> level +3
291  */
292 int level_contrainte(pc, base_index)
293 Pcontrainte pc;
294 Pbase base_index;
295 {
296  Pvecteur pv;
297  Pbase pb;
298  int level = 0;
299  int i;
300  int sign=1;
301  bool trouve = false;
302 
303  for (pv = pc->vecteur;
304  pv!=NULL;
305  pv = pv->succ)
306  {
307  for (i=1, trouve=false, pb=base_index;
308  pb!=NULL && !trouve;
309  i++, pb=pb->succ)
310  if (pv->var == pb->var)
311  {
312  trouve = true;
313  if (i>level)
314  level = i, sign = value_sign(pv->val);
315  }
316  }
317  return(sign*level);
318 }
319 
320 /* it sorts the vectors as expected. FC 24/11/94
321  */
322 void
324 Pcontrainte c;
325 int (*compare)(Pvecteur *, Pvecteur *);
326 {
327  for (; c!=NULL; c=c->succ)
328  vect_sort_in_place(&c->vecteur, compare);
329 }
330 
331 
332 /* Pcontrainte contrainte_var_min_coeff(Pcontrainte contraintes, Variable v,
333  * int *coeff)
334  * input : a list of constraints (euqalities or inequalities),
335  * a variable, and the location of an integer.
336  * output : the constraint in "contraintes" where the coefficient of
337  * "v" is the smallest (but non-zero).
338  * modifies : nothing.
339  * comment : the returned constraint is not removed from the list if
340  * rm_if_not_first_p is false.
341  * if rm_if_not_first_p is true, the returned contraint is
342  * remove only if it is not the first constraint.
343  */
345 contrainte_var_min_coeff(contraintes, v, coeff, rm_if_not_first_p)
346 Pcontrainte contraintes;
347 Variable v;
348 Value *coeff;
349 bool rm_if_not_first_p;
350 {
351  Value sc = VALUE_ZERO, cv = VALUE_ZERO;
352  Pcontrainte result, eq, pred, eq1;
353 
354  if (contraintes == NULL)
355  return(NULL);
356 
357  result = pred = eq1 = NULL;
358 
359  for (eq = contraintes; eq != NULL; eq = eq->succ) {
360  Value c, ca;
361  c = vect_coeff(v, eq->vecteur);
362  ca = value_abs(c);
363  if ((value_lt(ca,cv) && value_pos_p(ca)) ||
364  (value_zero_p(cv) && value_notzero_p(c))) {
365  cv = ca;
366  sc = c;
367  result = eq;
368  pred = eq1;
369  }
370  }
371 
372  if (value_neg_p(sc))
373  contrainte_chg_sgn(result);
374 
375  if (rm_if_not_first_p && pred != NULL) {
376  pred->succ = result->succ;
377  result->succ = NULL;
378  }
379 
380  *coeff = cv;
381  return result;
382 }
383 ␌
384 /*
385  * Constraint sorting for prettyprinting
386  *
387  */
388 
389 /* Required because qsort (and C) do no let us parametrize the
390  * comparison function (no lambda closure).
391  */
392 static int (* lexicographic_compare)(Pvecteur *, Pvecteur *) = NULL;
393 
394 int
396  int (*compare)(Pvecteur*, Pvecteur*))
397 {
398  /* it is assumed that constraints c1 and c2 are already
399  lexicographically sorted */
400  int cmp = 0;
401 
402  cmp = vect_lexicographic_compare(c1->vecteur, c2->vecteur, compare);
403 
404  return cmp;
405 }
406 
407 static int
409 {
410  int cmp = equation_lexicographic_compare(*pc1, *pc2,
412  return cmp;
413 }
414 
415 int
417  int (*compare)(Pvecteur*, Pvecteur*))
418 {
419  /* it is assumed that constraints c1 and c2 are already
420  lexicographically sorted */
421  int cmp = 0;
422 
423  cmp = vect_lexicographic_compare2(c1->vecteur, c2->vecteur, compare);
424 
425  return cmp;
426 }
427 
428 static int
430 {
431  int cmp = inequality_lexicographic_compare(*pc1, *pc2,
433  return cmp;
434 }
435 
436 
439  int (*compare)(Pvecteur*, Pvecteur*))
440 {
442 
443  result = constraints_lexicographic_sort_generic(cl, compare, true);
444 
445  return result;
446 }
447 
450  int (*compare)(Pvecteur*, Pvecteur*))
451 {
453 
454  result = constraints_lexicographic_sort_generic(cl, compare, false);
455 
456  return result;
457 }
458 
459 /* For historical reasons, equal to equations_lexicographic_sort() */
462  int (*compare)(Pvecteur*, Pvecteur*))
463 {
465 
466  result = constraints_lexicographic_sort_generic(cl, compare, true);
467 
468  return result;
469 }
470 
473  int (*compare)(Pvecteur*, Pvecteur*),
474  bool is_equation)
475 {
476  int n = nb_elems_list(cl);
478  Pcontrainte * table = NULL;
479  Pcontrainte * elem = NULL;
480  Pcontrainte ce;
481 
482  if ( n==0 || n==1 )
483  return cl;
484 
485  lexicographic_compare = compare;
486 
487  /* the temporary table is created and initialized
488  */
489  table = (Pcontrainte*) malloc(sizeof(Pcontrainte)*n);
490  assert(table!=NULL);
491 
492  for (ce=cl, elem=table; ce!=CONTRAINTE_UNDEFINED; ce=ce->succ, elem++)
493  *elem=ce;
494 
495  /* sort!
496  */
497  if(is_equation)
498  qsort((char *) table, n, sizeof(Pcontrainte),
499  (int (*)()) internal_equation_compare);
500  else
501  qsort((char *) table, n, sizeof(Pcontrainte),
502  (int (*)()) internal_inequality_compare);
503 
504  /* the vector is regenerated in order
505  */
506  for (elem=table; n>1; elem++, n--)
507  (*elem)->succ=*(elem+1);
508 
509  (*elem)->succ= CONTRAINTE_UNDEFINED;
510 
511  /* clean and return
512  */
513  result = *table;
514  free(table);
515  return result;
516 }
517 
518 /* returns whether a constraint is a simple equality: X == 12
519  * the system is expected to be normalized?
520  */
522 {
523  Pvecteur v = e->vecteur;
524  int size = vect_size(v);
525  switch (size) {
526  case 0: return NULL;
527  case 1: if (v->var) return v->var; else return NULL;
528  case 2:
529  if (v->var && !v->succ->var) return v->var;
530  if (!v->var && v->succ->var) return v->succ->var;
531  }
532  return NULL;
533 }
534 
535 /* that is all
536  */
#define value_pos_p(val)
#define VALUE_ZERO
#define value_sign(v)
trian operators on values
#define value_notzero_p(val)
void const char const char const int
#define value_zero_p(val)
int Value
#define VALUE_ONE
#define value_abs(val)
#define value_lt(v1, v2)
#define value_neg_p(val)
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
Pvecteur vect_translate(Pvecteur v, Pbase b, char *(*variable_name)(Variable))
Pvecteur vect_translate(Pvecteur v, Pbase b, char * (*variable_name)()): modify vector v so that its ...
Definition: base.c:313
Pvecteur vect_variable_rename(Pvecteur v, Variable v_old, Variable v_new)
Pvecteur vect_variable_rename(Pvecteur v, Variable v_old, Variable v_new): rename the potential coord...
Definition: base.c:366
int search_higher_rank(Pvecteur vect, Pbase base)
int search_higher_rank(): this fonction returns the rank of the variable of higher rank in the vecteu...
Definition: base.c:541
bdt base
Current expression.
Definition: bdt_read_paf.c:100
#define CONTRAINTE_UNDEFINED_P(c)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
#define CONTRAINTE_UNDEFINED
struct Scontrainte * Pcontrainte
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
Pcontrainte contrainte_dup(Pcontrainte c_in)
Pcontrainte contrainte_dup(Pcontrainte c_in): allocation d'une contrainte c_out prenant la valeur de ...
Definition: alloc.c:132
void Pcontrainte_separate_on_vars(Pcontrainte initial, Pbase vars, Pcontrainte *pwith, Pcontrainte *pwithout)
void Pcontrainte_separate_on_vars(initial, vars, pwith, pwithout) Pcontrainte initial; Pbase vars; Pc...
Definition: unaires.c:140
void contrainte_reverse(Pcontrainte c)
void contrainte_reverse(Pcontrainte eq): changement de signe d'une contrainte, i.e.
Definition: unaires.c:67
Pcontrainte contrainte_var_min_coeff(Pcontrainte contraintes, Variable v, Value *coeff, bool rm_if_not_first_p)
Pcontrainte contrainte_var_min_coeff(Pcontrainte contraintes, Variable v, int *coeff) input : a list ...
Definition: unaires.c:345
int equation_lexicographic_compare(Pcontrainte c1, Pcontrainte c2, int(*compare)(Pvecteur *, Pvecteur *))
Definition: unaires.c:395
int inequality_lexicographic_compare(Pcontrainte c1, Pcontrainte c2, int(*compare)(Pvecteur *, Pvecteur *))
Definition: unaires.c:416
Pcontrainte equations_lexicographic_sort(Pcontrainte cl, int(*compare)(Pvecteur *, Pvecteur *))
Definition: unaires.c:438
void constraints_for_bounds(Variable var, Pcontrainte *pinit, Pcontrainte *plower, Pcontrainte *pupper)
void constraints_for_bounds(var, pinit, plower, pupper) Variable var; Pcontrainte *pinit,...
Definition: unaires.c:176
void contrainte_vect_sort(Pcontrainte c, int *compare)
it sorts the vectors as expected.
Definition: unaires.c:323
void contrainte_chg_sgn(Pcontrainte c)
void contrainte_chg_sgn(Pcontrainte eq): changement de signe d'une contrainte, i.e.
Definition: unaires.c:56
static int internal_equation_compare(Pcontrainte *pc1, Pcontrainte *pc2)
Definition: unaires.c:408
Pcontrainte contrainte_dup_extract(Pcontrainte c, Variable var)
Pcontrainte contrainte_dup_extract(c, var) Pcontrainte c; Variable var;.
Definition: unaires.c:215
static int internal_inequality_compare(Pcontrainte *pc1, Pcontrainte *pc2)
Definition: unaires.c:429
int level_contrainte(Pcontrainte pc, Pbase base_index)
int level_contrainte(Pcontrainte pc, Pbase base_index) compute the level (rank) of the constraint pc ...
Definition: unaires.c:292
void eq_set_vect_nul(Pcontrainte c)
void_eq_set_vect_nul(Pcontrainte c): transformation d'une contrainte en une contrainte triviale 0 == ...
Definition: unaires.c:84
Pcontrainte constraints_lexicographic_sort_generic(Pcontrainte cl, int(*compare)(Pvecteur *, Pvecteur *), bool is_equation)
Definition: unaires.c:472
Pcontrainte contrainte_variable_rename(Pcontrainte c, Variable v_old, Variable v_new)
Pcontrainte contrainte_variable_rename(Pcontrainte c, Variable v_old, Variable v_new): rename the pot...
Definition: unaires.c:115
static int(* lexicographic_compare)(Pvecteur *, Pvecteur *)
Required because qsort (and C) do no let us parametrize the comparison function (no lambda closure).
Definition: unaires.c:392
Pcontrainte constraints_lexicographic_sort(Pcontrainte cl, int(*compare)(Pvecteur *, Pvecteur *))
For historical reasons, equal to equations_lexicographic_sort()
Definition: unaires.c:461
Pcontrainte contrainte_extract(Pcontrainte *pc, Pbase base, Variable var)
Pcontrainte contrainte_extract(pc, base, var) Pcontrainte *pc; Pbase base; Variable var;.
Definition: unaires.c:242
Pcontrainte inequalities_lexicographic_sort(Pcontrainte cl, int(*compare)(Pvecteur *, Pvecteur *))
Definition: unaires.c:449
Pcontrainte contrainte_translate(Pcontrainte c, Pbase b, char *(*variable_name)())
Pcontrainte contrainte_translate(Pcontrainte c, Pbase b, char * (*variable_name)()): normalisation de...
Definition: unaires.c:99
Variable contrainte_simple_equality(Pcontrainte e)
returns whether a constraint is a simple equality: X == 12 the system is expected to be normalized?
Definition: unaires.c:521
void norm_eq(Pcontrainte nr)
PACKAGE CONTRAINTE - OPERATIONS UNAIRES.
Definition: unaires.c:44
int nb_elems_list(Pcontrainte)
int nb_elems_list(Pcontrainte list): nombre de contraintes se trouvant dans une liste de contraintes
Definition: listes.c:129
bool constraint_without_vars(Pcontrainte, Pbase)
bool constraint_without_vars(c, vars) Pcontrainte c; Pbase vars;
Definition: predicats.c:276
void * malloc(YYSIZE_T)
void free(void *)
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
static entity rank
#define assert(ex)
Definition: newgen_assert.h:41
#define level
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
char * variable_name(Variable v)
polynome_ri.c
Definition: polynome_ri.c:73
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
Pvecteur vecteur
struct Scontrainte * succ
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Value val
Definition: vecteur-local.h:91
Variable var
Definition: vecteur-local.h:90
struct Svecteur * succ
Definition: vecteur-local.h:92
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
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
Pvecteur vect_dup(Pvecteur v_in)
Pvecteur vect_dup(Pvecteur v_in): duplication du vecteur v_in; allocation de et copie dans v_out;.
Definition: alloc.c:51
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
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
int vect_lexicographic_compare(Pvecteur v1, Pvecteur v2, int(*compare)(Pvecteur *, Pvecteur *))
qsort() is not safe if the comparison function is not antisymmetric.
Definition: unaires.c:433
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
void vect_sort_in_place(Pvecteur *pv, int *compare)
void vect_sort_in_place(pv, compare) Pvecteur *pv; int (*compare)(Pvecteur *, Pvecteur *);
Definition: unaires.c:290
int vect_lexicographic_compare2(Pvecteur v1, Pvecteur v2, int(*compare)(Pvecteur *, Pvecteur *))
Version for inequalities.
Definition: unaires.c:449
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