PIPS
sc_integer_projection.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sc_integer_projection.c 1641 2016-03-02 08:20:19Z 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 SC : sc_integer_projection.c
26  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27  *
28  * Projection of a system of constraints (equalities and inequalities)
29  * along one or several variables. The variables are eliminated only
30  * if the projection is exact, i.e. introduces no integer points
31  * that do not belong to the projection of the initial integer points.
32  *
33  * Arguments of these functions :
34  *
35  * - ofl_ctrl is the way overflow errors are handled
36  * ofl_ctrl == NO_OFL_CTRL
37  * -> overflow errors are not handled
38  * ofl_ctrl == OFL_CTRL
39  * -> overflow errors are handled in the called function
40  * (not often available, check first)
41  * ofl_ctrl == FWD_OFL_CTRL
42  * -> overflow errors must be handled by the calling function
43  *
44  * Authors :
45  *
46  * Remi Triolet, Malik Imadache, Francois Irigoin, Yi-Qing Yang,
47  * Corinne Ancourt
48  *
49  * Last modified : Be'atrice Creusillet, 16/12/94
50  */
51 
52 
53 #ifdef HAVE_CONFIG_H
54  #include "config.h"
55 #endif
56 
57 #include <stdio.h>
58 #include <stdlib.h>
59 
60 #include "boolean.h"
61 #include "arithmetique.h"
62 #include "vecteur.h"
63 #include "contrainte.h"
64 #include "sc.h"
65 
66 
67 #define MALLOC(s,t,f) malloc((unsigned)(s))
68 #define FREE(s,t,f) free((char *)(s))
69 
70 struct prtri_struct {
71  Pcontrainte pos,neg,cnul;
72 };
73 /* This function sorts all the constraints of inegs into three systems.
74  * Each system contains respectively constraints where the coefficient
75  * of the variable v is positive, negative, or null
76 */
77 
78 static void constraint_sort(inegs,v,prtri,nb_pos,nb_neg)
79 Pcontrainte inegs;
80 Variable v;
81 struct prtri_struct *prtri;
82 int *nb_pos,*nb_neg;
83 {
84  Pcontrainte ineg=NULL;
85  Pcontrainte ineg1=NULL;
86  Value c;
87 
88  prtri->pos = NULL;
89  prtri->neg = NULL;
90  prtri->cnul = NULL;
91  if (inegs!=NULL) {
92  for(ineg=inegs,ineg1=ineg->succ;ineg!=NULL;) {
93  c = vect_coeff(v,ineg->vecteur);
94  if (value_pos_p(c)) {
95  ineg->succ = prtri->pos;
96  prtri->pos = ineg;
97  *nb_pos +=1;
98  }
99  else {
100  if (value_neg_p(c)) {
101  ineg->succ = prtri->neg;
102  prtri->neg = ineg;
103  *nb_neg+=1;
104  }
105  else {
106  ineg->succ = prtri->cnul;
107  prtri->cnul = ineg;
108  }
109  }
110  ineg=ineg1;
111  if (ineg1!=NULL) ineg1=ineg1->succ;
112  }
113  }
114 }
115 
116 /* dans sc, elimine la Variable v des inegalites par "projections entieres".
117  * Si la projection "Fourier-Motzkin" d'une variable n'est pas equivalente
118  * a la projection entiere alors des contraintes sur la variable sont
119  * conservees. Ces contraintes sont celles qui rendent la condition
120  * suffisante non satisfaite.
121  */
122 
123 bool
124 sc_integer_fourier_motzkin_variable_elimination(
125  Psysteme sci,
126  Psysteme sc,
127  Variable v)
128 {
129  struct prtri_struct rtri;
130  Pcontrainte posit=NULL;
131  Pcontrainte negat=NULL;
132  Pcontrainte ineg=NULL;
133  Pcontrainte inegs = NULL;
134  Pcontrainte posit1 = NULL;
135  Psysteme scd = SC_UNDEFINED;
136  bool non_equivalent_projections = false;
137  int nb_pos=0;
138  int nb_neg = 0;
139  int i1,dim = sc->nb_ineq;
140  bool *ineg_stay; /* [dim+1] */
141 
142  ineg_stay = (bool*) malloc(sizeof(bool)*(dim+1));
143 
144  for (i1 =1; i1<=dim; ineg_stay[i1]=true, i1++);
145  if (!SC_UNDEFINED_P(sc)) {
146  inegs=sc->inegalites;
147  scd = sc_dup(sc);
148  }
149  else {
150  inegs = NULL;
151  free(ineg_stay);
152  return true;
153  }
154 
155  constraint_sort(inegs,v,&rtri,&nb_pos,&nb_neg);
156 
157 
158  /* pour chaque inegalite ou v a un coeff. positif et chaque
159  inegalite ou v a un coefficient negatif, faire une combinaison */
160 
161  for( posit=rtri.pos; posit!=NULL; ) {
162  bool integer_comb_p = true;
163  non_equivalent_projections = false;
164  for( negat=rtri.neg, i1=1; negat!=NULL; i1++) {
165 
166  ineg = sc_integer_inequalities_combination_ofl_ctrl
167  (sci, posit, negat, v, &integer_comb_p, OFL_CTRL);
168  ineg_stay[i1] = ineg_stay[i1] && integer_comb_p;
169  if(!integer_comb_p) non_equivalent_projections = true;
170 
171 
172  if (contrainte_constante_p(ineg)) {
173  if (contrainte_verifiee(ineg,false)) {
174  vect_rm(ineg->vecteur);
175  /* combinaison => 1 termcst >= 0 */
176  /* inutile de la garder */
177  }
178  else {
179  contraintes_free(rtri.pos);
180  rtri.pos=NULL;
181  contraintes_free(rtri.neg);
182  rtri.neg=NULL;
183  contraintes_free(rtri.cnul);
184  rtri.cnul = NULL;
185  posit = NULL;
186  negat = NULL;
187  return false;
188  /* systeme non faisable */
189  }
190  }
191  else {
192  if(!integer_comb_p) {
193  vect_rm(ineg->vecteur);
194  ineg->vecteur = vect_dup(negat->vecteur);
195  }
196 
197  ineg->succ = rtri.cnul;
198  rtri.cnul = ineg;
199  /* combinaison simple reussie => 1ineg en + */
200  }
201  if (negat) negat = negat->succ;
202  }
203 
204  if (non_equivalent_projections) {
205  posit1 = contrainte_dup(posit);
206  posit1->succ=rtri.cnul;
207  rtri.cnul = posit1;
208  }
209 
210  if (posit) posit = posit->succ;
211 
212  }
213  for( negat=rtri.neg, i1=1; negat!=NULL; negat=negat->succ, i1++) {
214  if (!ineg_stay[i1]) {
215  ineg = contrainte_dup(negat);
216  ineg->succ = rtri.cnul;
217  rtri.cnul = ineg;
218  }
219  }
220  contraintes_free(rtri.pos);
221  contraintes_free(rtri.neg);
222  rtri.pos = NULL;
223  rtri.neg = NULL;
224  /* apres les combinaisons eliminer les elements devenus inutils */
225  sc_rm(scd);
226  (sc->inegalites) = rtri.cnul;
227 
228  free(ineg_stay);
229  return true;
230 }
231 
232 
233 /* Integer projection of variable v in the system sc. The system sci
234  * corresponds to the initial system on which no projection has been made.
235  * Sci is usefull for computing the "suffisant condition".
236  * If the "Fourier-Motzkin" projection is not equivalent to the
237  * "integer projection" then some constraints on the variable v are kept.
238  * Those constraints are those for which the "suffisant condition" is not
239  * satisfied.
240  */
241 
242 /* projection d'un sc sur une var v */
243 Psysteme sc_integer_projection_along_variable(
244  Psysteme sci, // sci est le systeme initial sans les projections
245  volatile Psysteme sc,
246  Variable v)
247 {
248  Pcontrainte eq;
249  Value coeff;
250  if (sc) {
251  // trouver une egalite ou v a un coeff. minimal en valeur absolue
252  if ((eq = contrainte_var_min_coeff(sc->egalites,v,&coeff, false)) != NULL)
253  {
254  if(!egalite_normalize(eq))
255  return SC_EMPTY;
257  sc = sc_elim_var(sc,v);
258  }
259  TRY {
260  sc = sc_variable_substitution_with_eq_ofl_ctrl(sc, eq, v, NO_OFL_CTRL);
262  }
263  }
264  else {
265  // v n'apparait dans aucune egalite, il faut l'eliminer
266  // des inegalites par des combinaisons (fonction combiner)
267 
268  if (!sc_integer_fourier_motzkin_variable_elimination(sci,sc,v) && sc) {
269  sc_rm(sc);
270  return SC_UNDEFINED;
271  }
272  sc->nb_ineq = nb_elems_list(sc->inegalites);
273  }
274  }
275  return sc;
276 }
277 
278 
279 
280 /* this function returns the system resulting of the successive integer
281  * projection of the system sc along all the variables contain in vecteur pv
282  */
283 Psysteme sc_integer_projection_along_variables
284  (Psysteme fsc,
285  Psysteme sc,
286  Pbase index_base,
287  Pvecteur pv,
288  int tab_info[][4],
289  int dim,
290  int n)
291 {
292  Pvecteur pv1;
293 
294  for (pv1 = pv;!VECTEUR_NUL_P(pv1); pv1=pv1->succ)
295  {
296  sc = sc_integer_projection_along_variable(fsc,sc,vecteur_var(pv1));
297  sc = sc_normalize(sc);
298  sc_integer_projection_information(sc,index_base,tab_info,dim,n);
299  sc = build_integer_sc_nredund(sc,index_base,tab_info,dim,dim,n);
300  }
301  return sc;
302 }
303 
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
#define value_pos_p(val)
int Value
#define value_neg_p(val)
Pcontrainte contraintes_free(Pcontrainte pc)
Pcontrainte contraintes_free(Pcontrainte pc): desallocation de toutes les contraintes de la liste pc.
Definition: alloc.c:226
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
Pcontrainte contrainte_var_min_coeff(Pcontrainte, Variable, Value *, bool)
Pcontrainte contrainte_var_min_coeff(Pcontrainte contraintes, Variable v, int *coeff) input : a list ...
Definition: unaires.c:345
bool egalite_normalize(Pcontrainte)
bool egalite_normalize(Pcontrainte eg): reduction d'une equation diophantienne par le pgcd de ses coe...
Definition: normalize.c:136
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 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 * malloc(YYSIZE_T)
void free(void *)
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
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
Psysteme build_integer_sc_nredund(volatile Psysteme ps, Pbase index_base, int tab_info[][4], int loop_level, int dim_h __attribute__((unused)), int n __attribute__((unused)))
Computation of a new system sc from the system ps, where each constraint of the system ps is added to...
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
void sc_integer_projection_information(Psysteme sc, Pbase index_base, int sc_info[][4], int dim_h, int n)
This function gives information about the variables and the constraints of the system.
Psysteme sc_normalize(Psysteme ps)
Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires ...
Psysteme sc_elim_var(Psysteme sc, Variable v)
package sur les systemes de contraintes sc
Definition: sc_unaires.c:49
Pvecteur vecteur
struct Scontrainte * succ
Pcontrainte inegalites
Definition: sc-local.h:71
Pcontrainte egalites
Definition: sc-local.h:70
int nb_ineq
Definition: sc-local.h:73
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 vecteur_var(v)
#define NO_OFL_CTRL
#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 OFL_CTRL
I do thing that overflows are managed in a very poor manner.
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
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