PIPS
binaires.c
Go to the documentation of this file.
1 /*
2 
3  $Id: binaires.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 binaires */
26 
27 #ifdef HAVE_CONFIG_H
28  #include "config.h"
29 #endif
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include "linear_assert.h"
34 
35 #include "boolean.h"
36 #include "arithmetique.h"
37 #include "vecteur.h"
38 #include "contrainte.h"
39 
40 int contrainte_subst_ofl(v,def,c,eq_p)
41 Variable v;
42 Pcontrainte def,c;
43 bool eq_p;
44 {
45  return( contrainte_subst_ofl_ctrl(v,def,c,eq_p, FWD_OFL_CTRL));
46 }
47 
48 int contrainte_subst(v,def,c,eq_p)
49 Variable v;
50 Pcontrainte def,c;
51 bool eq_p;
52 {
53  return( contrainte_subst_ofl_ctrl(v,def,c,eq_p, NO_OFL_CTRL));
54 
55 }
56 
58 {
61  return e;
62 }
63 
64 
65 Pcontrainte inegalite_comb(posit,negat,v)
66 Pcontrainte posit, negat;
67 Variable v;
68 {
69  return( inegalite_comb_ofl_ctrl(posit,negat,v, NO_OFL_CTRL));
70 }
71 
73 Pcontrainte posit, negat;
74 Variable v;
75 {
76  return( inegalite_comb_ofl_ctrl(posit,negat,v, FWD_OFL_CTRL));
77 
78 }
79 
80 
81 /* int contrainte_subst_ofl_ctrl(Variable v, Pcontrainte def, Pcontrainte c
82  * Boolean eq_p, int ofl_ctrl):
83  * elimination d'une variable v entre une equation def et une contrainte,
84  * egalite ou inegalite, c. La contrainte c est modifiee en substituant
85  * v par sa valeur impliquee par def.
86  *
87  * La contrainte c est interpretee comme une inegalite et la valeur retournee
88  * vaut:
89  * -1 si la contrainte c est trivialement verifiee et peut etre eliminee
90  * 0 si la contrainte c est trivialement impossible
91  * 1 sinon (tout va bien)
92  * Si la contrainte c passee en argument etait trivialement impossible
93  * ou trivialement verifiee, aucune subsitution n'a lieu et la valeur 1
94  * est retournee.
95  *
96  * La substitution d'une variable dans une inegalite peut aussi introduire
97  * une non-faisabilite testable par calcul de PGCD, mais cela n'est pas
98  * fait puisqu'on ne sait pas si c est une egalite ou une inegalite. Le
99  * traitement du terme constant n'est pas decidable.
100  *
101  * Note: il faudrait separer le probleme de la combinaison lineaire
102  * a coefficients positifs de celui de la faisabilite et de la trivialite
103  *
104  * Le controle de l'overflow est effectue et traite par le retour
105  * du contexte correspondant au dernier CATCH(overflow_error) effectue.
106  */
107 int contrainte_subst_ofl_ctrl(v,def,c,eq_p, ofl_ctrl)
108 Variable v;
109 Pcontrainte def,c;
110 bool eq_p;
111 int ofl_ctrl;
112 {
113  Pvecteur save_c;
114 
115  /* cv_def = coeff de v dans def */
116  Value cv_def = vect_coeff(v,def->vecteur);
117  /* cv_c = coeff de v dans c */
118  Value cv_c = vect_coeff(v,c->vecteur);
119 
120  /* il faut que cv_def soit non nul pour que la variable v puisse etre
121  eliminee */
122  assert(value_notzero_p(cv_def));
123 
124  /* il n'y a rien a faire si la variable v n'apparait pas dans la
125  contrainte c */
126  /* substitution inutile: variable v absente */
127  if (value_zero_p(cv_c)) return 1;
128 
129  /* on garde trace de la valeur de c avant substitution pour pouvoir
130  la desallouer apres le calcul de la nouvelle */
131  save_c = c->vecteur;
132  /* on ne fait pas de distinction entre egalites et inegalites, mais
133  on prend soin de toujours multiplier la contrainte, inegalite
134  potentielle, par un coefficient positif */
135  if (value_neg_p(cv_def)) {
137  c->vecteur,cv_c,
138  def->vecteur,
139  ofl_ctrl);
140  }
141  else {
142  c->vecteur = vect_cl2_ofl_ctrl(cv_def,c->vecteur,
143  value_uminus(cv_c),
144  def->vecteur, ofl_ctrl);
145  }
146  vect_rm(save_c);
147 
148  /* reste malikien: cette partie ne peut pas etre faite sans savoir
149  si on est en train de traiter une egalite ou une inegalite */
150  if(contrainte_constante_p(c)) {
151  if(contrainte_verifiee(c,eq_p))
152  /* => eliminer cette c inutile */
153  return(-1);
154  else
155  /* => systeme non faisable */
156  return(false);
157  }
158  return(true);
159 }
160 
161 /* Pcontrainte inegalite_comb_ofl_ctrl(Pcontrainte posit, Pcontrainte negat,
162  * Variable v, int ofl_ctrl):
163  * combinaison lineaire positive des deux inegalites posit et negat
164  * eliminant la variable v.
165  *
166  * Une nouvelle contrainte est allouee et renvoyee.
167  *
168  * Si le coefficient de v dans negat egale -1 ou si le coefficient de
169  * v dans posit egale 1, la nouvelle contrainte est equivalente en
170  * nombres entiers avec posit et negat.
171  *
172  * Modifications:
173  * - use gcd to reduce the combination coefficients in hope to reduce
174  * integer overflow risk (Francois Irigoin, 17 December 1991)
175  *
176  * Le controle de l'overflow est effectue et traite par le retour
177  * du contexte correspondant au dernier CATCH(overflow_error) effectue.
178  */
179 Pcontrainte inegalite_comb_ofl_ctrl(posit,negat,v, ofl_ctrl)
180 Pcontrainte posit, negat;
181 Variable v;
182 int ofl_ctrl;
183 {
184  Value cv_p, cv_n, d;
185  Pcontrainte ineg;
186 
187  cv_p = vect_coeff(v,posit->vecteur);
188  cv_n = vect_coeff(v,negat->vecteur);
189 
190  assert(value_pos_p(cv_p) && value_neg_p(cv_n));
191 
192  d = pgcd(cv_p, value_uminus(cv_n));
193  if(value_notone_p(d)) {
194  cv_p = value_div(cv_p,d); /* pdiv ??? */
195  cv_n = value_div(cv_n,d);
196  }
197 
198  ineg = contrainte_new();
199 
200  ineg->vecteur = vect_cl2_ofl_ctrl(cv_p,negat->vecteur,
201  value_uminus(cv_n),
202  posit->vecteur, ofl_ctrl);
203  return(ineg);
204 }
205 
206 
207 
208 /* Value eq_diff_const(Pcontrainte c1, Pcontrainte c2):
209  * calcul de la difference des deux termes constants des deux
210  * equations c1 et c2
211  *
212  * Notes:
213  * - cette routine fait l'hypothese que CONTRAINTE_UNDEFINED=>CONTRAINTE_NULLE
214  *
215  * Modifications:
216  * - renvoie d'une valeur non nulle meme si une des contraintes est nulles
217  */
219 Pcontrainte c1,c2;
220 {
221  if(c1!=NULL)
222  if(c2!=NULL) {
223  Value b1 = vect_coeff(TCST,c1->vecteur),
224  b2 = vect_coeff(TCST,c2->vecteur);
225  return value_minus(b1,b2);
226  }
227  else
228  return vect_coeff(TCST,c1->vecteur);
229  else
230  if(c2!=NULL)
231  return value_uminus(vect_coeff(TCST,c2->vecteur));
232  else
233  return VALUE_ZERO;
234 }
235 
236 /* Value eq_sum_const(Pcontrainte c1, Pcontrainte c2):
237  * calcul de la somme des deux termes constants des deux
238  * contraintes c1 et c2
239  *
240  * Notes:
241  * - cette routine fait l'hypothese que CONTRAINTE_UNDEFINED=>CONTRAINTE_NULLE
242  */
244 Pcontrainte c1,c2;
245 {
246  if(c1!=NULL)
247  if(c2!=NULL) {
248  Value b1 = vect_coeff(TCST,c1->vecteur),
249  b2 = vect_coeff(TCST,c2->vecteur);
250  return value_plus(b1, b2);
251  }
252  else
253  return vect_coeff(TCST,c1->vecteur);
254  else
255  if(c2!=NULL)
256  return vect_coeff(TCST,c2->vecteur);
257  else
258  return VALUE_ZERO;
259 }
260 
261 /* Pcontrainte contrainte_append(c1, c2)
262  * Pcontrainte c1, c2;
263  *
264  * append directly c2 to c1. Neither c1 nor c2 are relevant
265  * when the result is returned.
266  */
268 Pcontrainte c1, c2;
269 {
270  Pcontrainte c;
271 
272  if (c1==NULL) return(c2);
273  if (c2==NULL) return(c1);
274  for (c=c1; c->succ!=NULL; c=c->succ);
275  c->succ=c2;
276  return(c1);
277 }
278 
279 /* common (simply equal) contraints are extracted,
280  * whether equalities or inequalities.
281  * returns the common extracted constaints.
282  * WARNING: *pc1 and *pc2 are modified.
283  */
286 {
287  Pcontrainte c = CONTRAINTE_UNDEFINED, c1, c2, c1p, c2p, nc1, nc2;
288 
289  for (c1 = *pc1,
290  c1p = CONTRAINTE_UNDEFINED,
291  nc1 = c1? c1->succ: CONTRAINTE_UNDEFINED;
292  c1;
293  c1p = (c1==nc1)? c1p: c1,
294  c1 = nc1,
295  nc1 = c1? c1->succ: CONTRAINTE_UNDEFINED)
296  {
297  for (c2 = *pc2,
298  c2p = CONTRAINTE_UNDEFINED,
299  nc2 = c2? c2->succ: CONTRAINTE_UNDEFINED;
300  c2;
301  c2p = (c2==nc2)? c2p: c2,
302  c2 = nc2,
303  nc2 = c2? c2->succ: CONTRAINTE_UNDEFINED)
304  {
305  if ((eq && egalite_equal(c1, c2)) || (!eq && contrainte_equal(c1, c2)))
306  {
307  /* common! */
308  Pcontrainte sc1 = c1->succ, sc2 = c2->succ;
309 
310  c1->succ = c, c = c1; /* link to result. */
311  c2->succ = NULL, contrainte_free(c2); /* clean */
312 
313  if (c1p) c1p->succ = sc1; else *pc1 = sc1;
314  if (c2p) c2p->succ = sc2; else *pc2 = sc2;
315 
316  /* get to next. */
317  c1 = nc1;
318  c2 = nc2 = CONTRAINTE_UNDEFINED;
319  }
320  }
321  }
322 
323  return c;
324 }
#define value_pos_p(val)
#define VALUE_ZERO
#define value_minus(v1, v2)
#define pgcd(a, b)
Pour la recherche de performance, selection d'une implementation particuliere des fonctions.
#define value_notzero_p(val)
#define value_uminus(val)
unary operators on values
#define value_notone_p(val)
#define value_zero_p(val)
int Value
#define value_plus(v1, v2)
binary operators on values
#define value_neg_p(val)
#define value_div(v1, v2)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_free(Pcontrainte c)
Pcontrainte contrainte_free(Pcontrainte c): liberation de l'espace memoire alloue a la contrainte c a...
Definition: alloc.c:184
Pcontrainte contrainte_new(void)
package contrainte - allocations et desallocations
Definition: alloc.c:47
int contrainte_subst(Variable v, Pcontrainte def, Pcontrainte c, bool eq_p)
Definition: binaires.c:48
Pcontrainte inegalite_comb_ofl(Pcontrainte posit, Pcontrainte negat, Variable v)
Definition: binaires.c:72
Value eq_diff_const(Pcontrainte c1, Pcontrainte c2)
Value eq_diff_const(Pcontrainte c1, Pcontrainte c2): calcul de la difference des deux termes constant...
Definition: binaires.c:218
int contrainte_subst_ofl_ctrl(Variable v, Pcontrainte def, Pcontrainte c, bool eq_p, int ofl_ctrl)
int contrainte_subst_ofl_ctrl(Variable v, Pcontrainte def, Pcontrainte c Boolean eq_p,...
Definition: binaires.c:107
Pcontrainte inegalite_comb_ofl_ctrl(Pcontrainte posit, Pcontrainte negat, Variable v, int ofl_ctrl)
Pcontrainte inegalite_comb_ofl_ctrl(Pcontrainte posit, Pcontrainte negat, Variable v,...
Definition: binaires.c:179
Value eq_sum_const(Pcontrainte c1, Pcontrainte c2)
Value eq_sum_const(Pcontrainte c1, Pcontrainte c2): calcul de la somme des deux termes constants des ...
Definition: binaires.c:243
Pcontrainte contrainte_substitute_dimension(Pcontrainte e, Variable i, Pvecteur v)
Definition: binaires.c:57
int contrainte_subst_ofl(Variable v, Pcontrainte def, Pcontrainte c, bool eq_p)
package contrainte - operations binaires
Definition: binaires.c:40
Pcontrainte extract_common_constraints(Pcontrainte *pc1, Pcontrainte *pc2, bool eq)
common (simply equal) contraints are extracted, whether equalities or inequalities.
Definition: binaires.c:285
Pcontrainte contrainte_append(Pcontrainte c1, Pcontrainte c2)
Pcontrainte contrainte_append(c1, c2) Pcontrainte c1, c2;.
Definition: binaires.c:267
Pcontrainte inegalite_comb(Pcontrainte posit, Pcontrainte negat, Variable v)
Definition: binaires.c:65
bool contrainte_equal(Pcontrainte, Pcontrainte)
bool contrainte_equal(Pcontrainte c1, Pcontrainte c2): test d'egalite des contraintes c1 et c2; elles...
Definition: predicats.c:128
bool egalite_equal(Pcontrainte, Pcontrainte)
bool egalite_equal(Pcontrainte eg1, Pcontrainte eg2): teste l'equivalence de deux egalites; leurs coe...
Definition: predicats.c:98
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
#define assert(ex)
Definition: newgen_assert.h:41
Value b2
Definition: sc_gram.c:105
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
Pvecteur vecteur
struct Scontrainte * succ
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define NO_OFL_CTRL
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 FWD_OFL_CTRL
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_cl2_ofl_ctrl(Value x1, Pvecteur v1, Value x2, Pvecteur v2, int ofl_ctrl)
Pvecteur vect_cl2_ofl(Value x1, Pvecteur v1, Value x2, Pvecteur v2): allocation d'un vecteur v dont l...
Definition: binaires.c:204
Pvecteur vect_substitute_dimension(Pvecteur v, Variable i, Pvecteur s)
Pvecteur vect_substitute_dimension(Pvecteur v, Variable i, Pvecteur s)
Definition: binaires.c:99
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