PIPS
predicats.c
Go to the documentation of this file.
1 /*
2 
3  $Id: predicats.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 - tests sur des contraintes
26  */
27 
28 /*LINTLIBRARY*/
29 
30 #ifdef HAVE_CONFIG_H
31  #include "config.h"
32 #endif
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include "linear_assert.h"
37 
38 #include "linear_assert.h"
39 
40 #include "boolean.h"
41 #include "arithmetique.h"
42 #include "vecteur.h"
43 #include "contrainte.h"
44 
45 /* bool eq_smg(Pcontrainte c1, Pcontrainte c2):
46  * comparaison des coefficients de deux contraintes pour savoir si elles ont le
47  * meme membre gauche.
48  *
49  * Note: this works for inequalities. Similar equations may differ
50  * by a factor of -1.
51  */
52 bool eq_smg(c1,c2)
53 Pcontrainte c1,c2;
54 {
55  bool result;
56 
57  if(c1==NULL && c2==NULL)
58  result = true;
59  else if(c1==NULL || c2==NULL)
60  result = false;
61  else
62  result = vect_equal_except(c1->vecteur,c2->vecteur,TCST);
63 
64  return result;
65 }
66 
67 /* bool inequalities_opposite_p(Pcontrainte c1, Pcontrainte c2):
68  * True if the non-constant part of c1 is the opposite of
69  * the non-constant part of c2.
70  */
72 Pcontrainte c1,c2;
73 {
74  bool result;
75 
76  if(c1==NULL && c2==NULL)
77  result = true;
78  else if(c1==NULL || c2==NULL)
79  result = false;
80  else
81  result = vect_opposite_except(c1->vecteur,c2->vecteur,TCST);
82 
83  return result;
84 }
85 
86 /* bool egalite_equal(Pcontrainte eg1, Pcontrainte eg2): teste
87  * l'equivalence de deux egalites; leurs coefficients peuvent etre
88  * tous egaux ou tous opposes; pour obtenir une meilleure equivalence
89  * il faut commencer par reduire leurs coefficients par les PGCD
90  *
91  * Soit eg1, sum a1i xi = b1, et eg2, sum a2i xi = b2.
92  * i i
93  * return a1i == a2i || a1i == -a2i;
94  * i i
95  *
96  * Note: 2x=2 est different de x=1
97  */
98 bool egalite_equal(eg1,eg2)
99 Pcontrainte eg1;
100 Pcontrainte eg2;
101 {
102  bool result;
103 
105  result = true;
106  else if(CONTRAINTE_UNDEFINED_P(eg1) || CONTRAINTE_UNDEFINED_P(eg2))
107  result = false;
108  else
109  result = vect_equal(eg1->vecteur,eg2->vecteur) ||
110  vect_oppos(eg1->vecteur,eg2->vecteur);
111 
112  return(result);
113 }
114 
115 /* bool contrainte_equal(Pcontrainte c1, Pcontrainte c2): test
116  * d'egalite des contraintes c1 et c2; elles sont egales si tous
117  * leurs coefficients et leur termes constants sont egaux; il faut les
118  * avoir normalisees auparavant pour etre sur de leur egalite;
119  *
120  * La contrainte CONTRAINTE_UNDEFINED est assimilee a la contrainte nulle
121  *
122  * Ancien nom: ineg_same()
123  *
124  * Modifications:
125  * - utilisation de CONTRAINTE_UNDEFINED_P() et contrainte_vecteur()
126  * (FI, 08/12/89)
127  */
129 {
130  register bool
131  undef1 = CONTRAINTE_UNDEFINED_P(c1),
132  undef2 = CONTRAINTE_UNDEFINED_P(c2);
133 
134  if (undef1 || undef2)
135  return(undef1 && undef2);
136 
137  return(vect_equal(contrainte_vecteur(c1),
138  contrainte_vecteur(c2)));
139 }
140 
141 /* Les deux contraintes c1 et c2 sont paralleles s'il existe deux
142  * coefficients a1 et a2 tels que a1 c1 + a2 c2 est reduit un terme
143  * constant K.
144  */
146 {
147  bool parallel_p = false;
148  register bool
149  undef1 = CONTRAINTE_UNDEFINED_P(c1),
150  undef2 = CONTRAINTE_UNDEFINED_P(c2);
151 
152  if (undef1 || undef2)
153  parallel_p = (undef1 && undef2);
154  else {
155  /* On cherche une composante quelconque relative a une variable */
156  Pvecteur v1 = contrainte_vecteur(c1);
157  Pvecteur v2 = contrainte_vecteur(c2);
158  if(vect_constant_p(v1))
159  parallel_p = vect_constant_p(v2);
160  else if(vect_constant_p(v2))
161  parallel_p = false;
162  else {
163  Pvecteur v;
164  for(v=v1; !VECTEUR_NUL_P(v); v = vecteur_succ(v)) {
165  if(vecteur_var(v)!=TCST)
166  break;
167  }
168  Variable var = vecteur_var(v);
169  *pa1 = vect_coeff(var, v1);
170  *pa2 = -vect_coeff(var, v2);
171  Pvecteur nv1 = vect_multiply(vect_copy(v1), *pa2);
172  Pvecteur nv2 = vect_multiply(vect_copy(v2), *pa1);
173  Pvecteur nv = vect_add(nv1, nv2);
174  if(vect_size(nv)==0 || (vect_size(nv)==1 && vecteur_var(nv)==TCST))
175  parallel_p = true;
176  vect_rm(nv1), vect_rm(nv2), vect_rm(nv);
177  }
178  }
179  return parallel_p;
180 }
181 
182 /* bool contrainte_constante_p(Pcontrainte c): test de contrainte
183  * triviale sans variables (ie du type 0<= K ou 0<=0 ou 0 == 0 ou 0 == K)
184  *
185  * Les equations non-faisables ne sont pas detectees.
186  *
187  * Modifications:
188  * - utilisation de CONTRAINTE_NULLE_P()
189  * Bugs:
190  * - should assert !CONTRAINTE_UNDEFINED_P(c)
191  */
193 Pcontrainte c;
194 {
195 
196  if (CONTRAINTE_NULLE_P(c))
197  return(true);
198  else {
200  }
201 }
202 
203 /* bool vect_constant_p(Pvecteur v): v contains only a constant term,
204  * may be zero
205  *
206  * Bugs:
207  * - this function should not be in contrainte.dir; it should be moved into
208  * vecteur.dir with TCST...
209  * - should assert !VECTEUR_UNDEFINED_P(v)
210  */
212 Pvecteur v;
213 {
214  return(VECTEUR_NUL_P(v) || (v->var == TCST && v->succ == NULL));
215 }
216 
217 /* bool contrainte_verifiee(Pcontrainte ineg, bool eq_p):
218  * test de faisabilite d'inegalite (eq_p == false) ou d'egalite triviale
219  *
220  * Le test est different pour les egalites.
221  *
222  * Modifications:
223  * - test de l'absence d'un successeur dans vecteur (ajout d'un test
224  * succ == NULL)
225  * - changement de cote du terme constant (FI, 08/12/89)
226  * - ajout d'un assert pour pallier partiellement le bug 1 (FI, 08/12/89)
227  * - utilisation de la macro CONTRAINTE_NULLE_P() (FI, 08/12/89)
228  * Bugs:
229  * - si on passe une inegalite non constante en argument, le resultat
230  * depend du premier terme du vecteur; il faudrait pouvoir retourner
231  * la valeur bottom pour les inegalites non constantes;
232  * - le nom devrait etre inegalite_verifiee()
233  */
234 bool contrainte_verifiee(ineg,eq_p)
235 Pcontrainte ineg;
236 bool eq_p;
237 {
238  Value v;
240 
241  /* l'inegalite 0 <= 0 est representee par un vecteur nul */
242  if (CONTRAINTE_NULLE_P(ineg))
243  return(true);
244 
245  /* l'inegalite 0 <= K est representee par un vecteur a un element */
246  v = val_of(ineg->vecteur);
247 
248  return (!eq_p && value_negz_p(v) && ineg->vecteur->succ==NULL)
249  || ( eq_p && value_zero_p(v) && ineg->vecteur->succ==NULL);
250 }
251 
252 /* bool contrainte_oppos(Pcontrainte ineg1, Pcontrainte ineg2):
253  * indique si 2 inegalites forment une egalite ou si deux egalites sont
254  * equivalentes.
255  *
256  * return(ineg1 == -ineg2);
257  */
258 bool contrainte_oppos(ineg1,ineg2)
259 Pcontrainte ineg1,ineg2;
260 {
261  return(vect_oppos(ineg1->vecteur,ineg2->vecteur));
262 }
263 
264 
265 /* bool constraint_without_vars(c, vars)
266  * Pcontrainte c;
267  * Pbase vars;
268  *
269  * IN: c, vars
270  * OUT: returned boolean
271  *
272  * returns if the current constraint uses none of the variables in vars.
273  *
274  * (c) FC 16/05/94
275  */
277 Pcontrainte c;
278 Pbase vars;
279 {
280  Pbase
281  b = BASE_NULLE;
282 
283  for(b=vars;
284  b!=BASE_NULLE;
285  b=b->succ)
286  if (vect_coeff(var_of(b), c->vecteur)!=(Value) 0) return(false);
287 
288  return(true);
289 }
290 
291 /* bool constraints_without_vars(pc, vars)
292  * Pcontrainte pc;
293  * Pbase vars;
294  *
295  * IN: c, vars
296  * OUT: returned boolean
297  *
298  * returns true if none of the constraints use the variables in vars.
299  */
301 Pcontrainte pc;
302 Pbase vars;
303 {
304  Pcontrainte c;
305 
306  for (c=pc;
307  c!=NULL;
308  c=c->succ)
309  if (!constraint_without_vars(c, vars)) return(false);
310 
311  return(true);
312 }
313 ␌
314 /* Evaluate constraint c according to values in v and return the
315  constant obtained. The constraint may be an equality or an
316  inequality.
317 
318  If c is an equality, the value return must be zero or the point
319  does not belong to the hyperplane defined by c.
320 
321  If c is an inequality, the value returned is negative if v belongs
322  to the half-space defined by c. If it is zero, the point v belongs
323  to the constraint, i.e. is on the boundary of any constraint system
324  containing c, i.e. to the hyperplane defined by c. If the value
325  returned is stricly positive, v does not belong to the half-space
326  defined by c.
327 
328  Note: this function is not a predicate but it is used by the next
329  function, which is a predicate.
330  */
332 {
333  Value k = VALUE_ZERO;
334  Pvecteur cc = VECTEUR_NUL;
335 
336  for(cc=c; !VECTEUR_NUL_P(cc); cc = vecteur_succ(cc)) {
337  Variable var = vecteur_var(cc);
338  Value coef = vecteur_val(cc);
339  if(var==TCST) {
340  value_addto(k, coef);
341  }
342  else {
343  Value val = vect_coeff(var, v);
344  value_addto(k, value_direct_multiply(coef, val));
345  }
346  }
347 
348  return k;
349 }
350 
351 /* Evaluate constraint c according to values in v and return true if
352  the constraint is met. The constraint may be an equality or an
353  inequality depending on is_equality_p */
354 bool contrainte_eval_p(Pvecteur c, Pvecteur v, bool is_equality_p)
355 {
356  Value k = VALUE_ZERO;
357  bool is_met_p = true;
358 
359  k = contrainte_eval(c, v);
360 
361  if(is_equality_p)
362  is_met_p = value_zero_p(k);
363  else
364  is_met_p = value_negz_p(k);
365 
366  return is_met_p;
367 }
368 
370 {
371  return contrainte_eval_p(c, v, true);
372 }
373 
375 {
376  return contrainte_eval_p(c, v, false);
377 }
378 
379 /*
380  * that is all
381  */
#define VALUE_ZERO
#define value_negz_p(val)
#define value_direct_multiply(v1, v2)
#define value_zero_p(val)
int Value
#define value_addto(ref, val)
#define CONTRAINTE_UNDEFINED_P(c)
#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"
bool vect_opposite_except(Pvecteur v1, Pvecteur v2, Variable var)
bool vect_opposite_except(Pvecteur v1, Pvecteur v2, Variable var): test a egalite des projections sel...
Definition: reductions.c:399
bool vect_equal(Pvecteur v1, Pvecteur v2)
bool vect_equal(Pvecteur v1, Pvecteur v2): test a egalite de deux vecteurs
Definition: reductions.c:278
bool vect_oppos(Pvecteur v1, Pvecteur v2)
bool vect_oppos(Pvecteur v1, Pvecteur v2): test de l'opposition de deux vecteurs
Definition: reductions.c:360
bool vect_equal_except(Pvecteur v1, Pvecteur v2, Variable var)
bool vect_equal_except(Pvecteur v1, Pvecteur v2, Variable var): test a egalite des projections selon ...
Definition: reductions.c:319
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define assert(ex)
Definition: newgen_assert.h:41
bool eq_smg(Pcontrainte c1, Pcontrainte c2)
package contrainte - tests sur des contraintes
Definition: predicats.c:52
bool contrainte_parallele(Pcontrainte c1, Pcontrainte c2, Value *pa1, Value *pa2)
Les deux contraintes c1 et c2 sont paralleles s'il existe deux coefficients a1 et a2 tels que a1 c1 +...
Definition: predicats.c:145
bool equality_eval_p(Pvecteur c, Pvecteur v)
Definition: predicats.c:369
bool contrainte_constante_p(Pcontrainte c)
bool contrainte_constante_p(Pcontrainte c): test de contrainte triviale sans variables (ie du type 0<...
Definition: predicats.c:192
bool contrainte_eval_p(Pvecteur c, Pvecteur v, bool is_equality_p)
Evaluate constraint c according to values in v and return true if the constraint is met.
Definition: predicats.c:354
bool constraint_without_vars(Pcontrainte c, Pbase vars)
bool constraint_without_vars(c, vars) Pcontrainte c; Pbase vars;
Definition: predicats.c:276
Value contrainte_eval(Pvecteur c, Pvecteur v)
Evaluate constraint c according to values in v and return the constant obtained.
Definition: predicats.c:331
bool vect_constant_p(Pvecteur v)
bool vect_constant_p(Pvecteur v): v contains only a constant term, may be zero
Definition: predicats.c:211
bool contrainte_verifiee(Pcontrainte ineg, bool eq_p)
bool contrainte_verifiee(Pcontrainte ineg, bool eq_p): test de faisabilite d'inegalite (eq_p == false...
Definition: predicats.c:234
bool contrainte_oppos(Pcontrainte ineg1, Pcontrainte ineg2)
bool contrainte_oppos(Pcontrainte ineg1, Pcontrainte ineg2): indique si 2 inegalites forment une egal...
Definition: predicats.c:258
bool inequalities_opposite_p(Pcontrainte c1, Pcontrainte c2)
bool inequalities_opposite_p(Pcontrainte c1, Pcontrainte c2): True if the non-constant part of c1 is ...
Definition: predicats.c:71
bool contrainte_equal(Pcontrainte c1, Pcontrainte c2)
bool contrainte_equal(Pcontrainte c1, Pcontrainte c2): test d'egalite des contraintes c1 et c2; elles...
Definition: predicats.c:128
bool inequality_eval_p(Pvecteur c, Pvecteur v)
Definition: predicats.c:374
bool egalite_equal(Pcontrainte eg1, Pcontrainte eg2)
bool egalite_equal(Pcontrainte eg1, Pcontrainte eg2): teste l'equivalence de deux egalites; leurs coe...
Definition: predicats.c:98
bool constraints_without_vars(Pcontrainte pc, Pbase vars)
bool constraints_without_vars(pc, vars) Pcontrainte pc; Pbase vars;
Definition: predicats.c:300
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
Pvecteur vecteur
struct Scontrainte * succ
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
struct Svecteur * succ
Definition: vecteur-local.h:92
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_val(v)
#define vecteur_var(v)
#define val_of(varval)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define vecteur_succ(v)
#define VECTEUR_NUL_P(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 var_of(varval)
#define BASE_NULLE
MACROS SUR LES BASES.
Pbase vect_copy(Pvecteur b)
direct duplication.
Definition: alloc.c:240
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53
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