PIPS
sc_unaires.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sc_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 sur les systemes de contraintes sc
26  *
27  * Yi-Qing YANG, 20/05/92
28  */
29 
30 #ifdef HAVE_CONFIG_H
31  #include "config.h"
32 #endif
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <stdlib.h>
37 #include "linear_assert.h"
38 
39 #include "boolean.h"
40 #include "arithmetique.h"
41 #include "linear_assert.h"
42 #include "vecteur.h"
43 #include "contrainte.h"
44 #include "sc.h"
45 
46 /* Psysteme sc_elim_var(Psysteme sc, Variable v)`
47  * This function eliminate all the contraints containing the variable v
48  */
50 {
51  Pcontrainte pr = NULL, eq;
52 
53  if (sc == NULL) return sc;
54  else {
55  eq = sc->egalites;
56  while (eq != NULL) {
57  if (vect_coeff(v,eq->vecteur) != 0) {
58  if (pr == NULL) {
59  sc->egalites = eq = eq->succ;
60  }
61  else {
62  pr->succ = eq = eq->succ;
63  }
64  }
65  else {
66  pr = eq;
67  eq = eq->succ;
68  }
69  }
70 
71  eq = sc->inegalites;
72  pr = NULL;
73  while (eq != NULL) {
74  if (vect_coeff(v,eq->vecteur) != 0) {
75  if (pr == NULL) {
76  sc->inegalites = eq = eq->succ;
77  }
78  else {
79  pr->succ = eq = eq->succ;
80  }
81  }
82  else {
83  pr = eq;
84  eq = eq->succ;
85  }
86  }
87 
88  sc->nb_eq = nb_elems_list(sc->egalites);
89  sc->nb_ineq = nb_elems_list(sc->inegalites);
90  return sc;
91  }
92 }
93 
94 /* void sc_chg_var(Psysteme s, Variable v_old, Variable v_new)
95  * this function replace the variable v_old in the system s by the
96  * variable v_new.
97  */
98 void sc_chg_var(Psysteme s, Variable v_old, Variable v_new)
99 {
100  Pcontrainte pc;
101  if (s != NULL){
102  for (pc = s->egalites; pc != NULL; pc = pc->succ) {
103  vect_chg_var(&(pc->vecteur), v_old, v_new);
104  }
105 
106  for (pc = s->inegalites; pc != NULL; pc = pc->succ) {
107  vect_chg_var(&(pc->vecteur), v_old, v_new);
108  }
109  }
110 }
111 
112 /* the name is self explanatory, I guess. FC 24/11/94
113  * the vectors of the system are sorted.
114  * see man qsort about the compare functions.
115  */
116 void sc_vect_sort(Psysteme s, int (*compare)(Pvecteur *, Pvecteur *))
117 {
118  if (s==NULL || sc_empty_p(s) || sc_rn_p(s))
119  return;
120 
121  contrainte_vect_sort(sc_egalites(s), compare);
122  contrainte_vect_sort(sc_inegalites(s), compare);
123 }
124 
125 /* SORT a Psysteme according to sort_base and compare (given to qsort).
126  * Each constraint is first sorted according to the compare function.
127  * Then list of constraints are sorted.
128  *
129  * The only expected property
130  * is that two calls to this function with the same system (whatever its
131  * order) and same sort_base that covers all variables and same compare
132  * function should give the same result.
133  *
134  * The function is quite peculiar and the order is relevant for some
135  * code generation issues...
136  */
137 void sc_sort(
138  Psysteme sc,
139  Pbase sort_base,
140  int (*compare)(Pvecteur*, Pvecteur*))
141 {
142  sc_vect_sort(sc, compare);
143  sc->inegalites =
144  contrainte_sort(sc->inegalites, sc->base, sort_base, true, true);
145  sc->egalites =
146  contrainte_sort(sc->egalites, sc->base, sort_base, true, true);
147 }
148 
150 {
151  bool decided_p = false;
152  int positive_terms = 0;
153  int negative_terms = 0;
154  Pvecteur coord = VECTEUR_UNDEFINED;
155 
156  for(coord = v; !VECTEUR_NUL_P(coord); coord = coord->succ) {
157  if(vecteur_var(coord)!= TCST)
158  (value_pos_p(vecteur_val(coord))) ?
159  positive_terms++ : negative_terms++;
160  }
161  /* constant vectors are considered decided */
162  decided_p = ((positive_terms!=negative_terms) ||
163  (positive_terms==0 && negative_terms==0));
164 
165  return decided_p;
166 }
167 
168 /* Try to guess the print out order for an equality already
169  lexicographically sorted */
171  int (*compare)(Pvecteur *, Pvecteur *))
172 {
173  Pvecteur v_neg = VECTEUR_NUL;
176 
177  for(cc = v; !VECTEUR_NUL_P(cc); cc = succ) {
178  succ = vecteur_succ(cc); /* before cc might be freed */
179  if(vecteur_val(cc) < 0 || vecteur_var(cc)==TCST) {
180  vect_add_elem(&v_neg, vecteur_var(cc), vecteur_val(cc));
181  vect_erase_var(&v, vecteur_var(cc));
182  }
183  }
184 
185  vect_sort_in_place(&v, compare);
186  vect_sort_in_place(&v_neg, compare);
187 
188  /* append v_neg to v */
189  for(cc=v; !VECTEUR_NUL_P(cc); cc = vecteur_succ(cc)) {
190  if(VECTEUR_NUL_P(vecteur_succ(cc))) {
191  vecteur_succ(cc) = v_neg;
192  break; /* do not follow v_neg for ever */
193  }
194  }
195 
196  return v;
197 }
198 
199 /* Minimize first the lexico-graphic weight of each constraint according to
200  * the comparison function "compare", and then sort the list of equalities
201  * and inequalities by increasing lexico-graphic weight.
202  *
203  * Francois Irigoin
204  */
205 void
207  Psysteme sc,
208  int (*compare)(Pvecteur*, Pvecteur*))
209 {
211 
212  if (sc==NULL || sc_empty_p(sc) || sc_rn_p(sc))
213  return;
214 
215  /* sort the system basis */
216  vect_sort_in_place(&(sc->base), compare);
217 
218  /* sort each constraint */
219  contrainte_vect_sort(sc_egalites(sc), compare);
220  contrainte_vect_sort(sc_inegalites(sc), compare);
221 
222  /* minimize equations: when equations are printed out, terms are moved
223  to eliminate negative coefficients and the inner lexicographic
224  order is broken. Furthermore, an equation can be multiplied by -1
225  and stay the same but be printed out differently. */
226  for(c = sc_egalites(sc); !CONTRAINTE_UNDEFINED_P(c); c = contrainte_succ(c))
227  {
229 
231  int cmp = 0;
232  Pvecteur v1 = vect_dup(v);
234 
235  v1 = vect_printout_order(v1, compare);
236  v2 = vect_printout_order(v2, compare);
237  cmp = vect_lexicographic_compare(v1, v2, compare);
238  if(cmp>0) {
239  contrainte_vecteur(c) =
241  vect_rm(v1);
242  vect_rm(v2);
243  }
244  else if(cmp<0) {
245  vect_rm(v1);
246  vect_rm(v2);
247  }
248  else {
249  /* we are in trouble: v1 and v2 are different but not
250  comparable because the compare function is not strong
251  enough */
252  /* This may occur if the same local names are used for two
253  different variables that can be live simultaneously. For
254  instance, "predict!predict_mb:pict_struct" and
255  "TOP-LEVEL:pict_struct" which are or seem to be both int
256  variables in mpeg2enc. We could take a default action here
257  or force the user to improve his/her comparison function
258  where more information is available. */
259  assert(false);
260  }
261  }
262  }
263 
264  /* sort equalities and inequalities */
265  sc->egalites = equations_lexicographic_sort(sc->egalites, compare);
267 }
268 
269 /* remove constraints with large coefs,
270  * possibly to avoid overflows and to keep systems as simple as possible
271  * @param sc system to consider, which may be modified
272  * @param val maximum coef allowed, >=0, 0 meant to do nothing
273  * @param equalities whether to process equalities
274  * @param inequalities whether to process inequalities
275  * @return whether the system was changed
276  */
278  bool equalities, bool inequalities)
279 {
280  bool changed = false;
281 
282  // nothing to do in some simple cases
283  if (sc==NULL || sc_empty_p(sc) || sc_rn_p(sc))
284  return changed;
285 
286  if (equalities && sc->egalites) {
287  int nb = sc->nb_eq;
289  sc->nb_eq = nb_elems_list(sc->egalites);
290  changed |= nb!=sc->nb_eq;
291  }
292 
293  if (inequalities && sc->inegalites) {
294  int nb = sc->nb_ineq;
296  sc->nb_ineq = nb_elems_list(sc->inegalites);
297  changed |= nb!=sc->nb_ineq;
298  }
299 
300  return changed;
301 }
302 
303 /* That is all
304  */
#define value_pos_p(val)
#define VALUE_MONE
int Value
#define CONTRAINTE_UNDEFINED_P(c)
#define contrainte_succ(c)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_remove_large_coef(Pcontrainte, Value)
Definition: listes.c:179
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
Pcontrainte inequalities_lexicographic_sort(Pcontrainte, int(*)(Pvecteur *, Pvecteur *))
Definition: unaires.c:449
Pcontrainte equations_lexicographic_sort(Pcontrainte, int(*)(Pvecteur *, Pvecteur *))
Definition: unaires.c:438
void contrainte_vect_sort(Pcontrainte, int(*)(Pvecteur *, Pvecteur *))
#define assert(ex)
Definition: newgen_assert.h:41
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
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
Pcontrainte contrainte_sort(Pcontrainte c, Pbase base, Pbase sort_base, bool inner_first, bool complex_first)
Pvecteur vect_printout_order(Pvecteur v, int(*compare)(Pvecteur *, Pvecteur *))
Try to guess the print out order for an equality already lexicographically sorted.
Definition: sc_unaires.c:170
bool sc_remove_large_coef(Psysteme sc, Value val, bool equalities, bool inequalities)
remove constraints with large coefs, possibly to avoid overflows and to keep systems as simple as pos...
Definition: sc_unaires.c:277
static bool vect_printout_order_decided_p(Pvecteur v)
Definition: sc_unaires.c:149
Psysteme sc_elim_var(Psysteme sc, Variable v)
package sur les systemes de contraintes sc
Definition: sc_unaires.c:49
void sc_chg_var(Psysteme s, Variable v_old, Variable v_new)
void sc_chg_var(Psysteme s, Variable v_old, Variable v_new) this function replace the variable v_old ...
Definition: sc_unaires.c:98
void sc_vect_sort(Psysteme s, int(*compare)(Pvecteur *, Pvecteur *))
the name is self explanatory, I guess.
Definition: sc_unaires.c:116
void sc_lexicographic_sort(Psysteme sc, int(*compare)(Pvecteur *, Pvecteur *))
Minimize first the lexico-graphic weight of each constraint according to the comparison function "com...
Definition: sc_unaires.c:206
void sc_sort(Psysteme sc, Pbase sort_base, int(*compare)(Pvecteur *, Pvecteur *))
SORT a Psysteme according to sort_base and compare (given to qsort).
Definition: sc_unaires.c:137
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
Pcontrainte inegalites
Definition: sc-local.h:71
Pcontrainte egalites
Definition: sc-local.h:70
Pbase base
Definition: sc-local.h:75
int nb_ineq
Definition: sc-local.h:73
int nb_eq
Definition: sc-local.h:72
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 VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define VECTEUR_UNDEFINED
#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
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_erase_var(Pvecteur *ppv, Variable v)
void vect_erase_var(Pvecteur * ppv, Variable v): projection du vecteur *ppv selon la direction v (i....
Definition: unaires.c:106
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
void vect_chg_var(Pvecteur *ppv, Variable v_old, Variable v_new)
void vect_chg_var(Pvecteur *ppv, Variable v_old, Variable v_new) replace the variable v_old by v_new
Definition: unaires.c:168