PIPS
sc_alloc.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sc_alloc.c 1669 2019-06-26 17:24:57Z 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 */
26 
27 #ifdef HAVE_CONFIG_H
28  #include "config.h"
29 #endif
30 
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdio.h>
34 
35 #include "arithmetique.h"
36 #include "linear_assert.h"
37 #include "boolean.h"
38 #include "vecteur.h"
39 #include "contrainte.h"
40 #include "sc.h"
41 
42 #define MALLOC(s,t,f) malloc(s)
43 
44 /* Psysteme sc_new():
45  * alloue un systeme vide, initialise tous les champs avec des
46  * valeurs nulles, puis retourne ce systeme en resultat.
47  *
48  * Attention, sc_new ne fabrique pas un systeme coherent comportant
49  * une base. Un tel systeme s'obtient par appel a la fonction sc_creer_base,
50  * apres avoir ajoute des equations et des inequations au systeme. La base
51  * n'est pas entretenue lorsque le systeme est modifie.
52  *
53  * Ancien nom: init_systeme()
54  */
56 {
57  Psysteme p = (Psysteme) malloc(sizeof(Ssysteme));
58 
59  assert(p);
60 
61  p->nb_eq = 0;
62  p->nb_ineq = 0;
63  p->dimension = 0;
64 
65  p->egalites = (Pcontrainte) NULL;
66  p->inegalites = (Pcontrainte) NULL;
67  p->base = BASE_NULLE;
68 
69  return p;
70 }
71 
72 /* creation d'une base contenant toutes les variables
73  * apparaissant avec des coefficients non-nuls
74  * dans les egalites ou les inegalites de ps
75  */
77 {
79  Pbase b = BASE_NULLE;
80  Pcontrainte c;
81  Pvecteur v;
82 
83  /* great optimization */
84  if (!ps->egalites && !ps->inegalites)
85  return BASE_NULLE;
86 
88 
89  for (c = ps->egalites; c!=NULL; c=c->succ) {
90  for (v = c->vecteur; v!=VECTEUR_NUL; v=v->succ) {
91  Variable var = var_of(v);
92  if (var!=TCST && !linear_hashtable_isin(seen, var)) {
94  b = vect_chain(b, var, VALUE_ONE);
95  }
96  }
97  }
98 
99  for (c = ps->inegalites; c!=NULL; c=c->succ) {
100  for (v = c->vecteur; v!=VECTEUR_NUL; v=v->succ) {
101  Variable var = var_of(v);
102  if (var!=TCST && !linear_hashtable_isin(seen, var)) {
103  linear_hashtable_put_once(seen, var, var);
104  b = vect_chain(b, var, VALUE_ONE);
105  }
106  }
107  }
108 
110 
111  return b;
112 }
113 
114 /* void sc_creer_base(Psysteme ps): initialisation des parametres dimension
115  * et base d'un systeme lineaire en nombres entiers ps, i.e. de la
116  * base implicite correspondant aux egalites et inegalites du systeme;
117  *
118  * Attention, cette base ne reste pas coherente apres un ajout de nouvelles
119  * egalites ou inegalites (risque d'ajout de nouvelles variables), ni apres
120  * des suppressions (certaines variables de la base risque de n'apparaitre
121  * dans aucune contrainte).
122  *
123  * dimension : nombre de variables du systeme (i.e. differentes de TCST, le
124  * terme constant)
125  *
126  * Modifications:
127  * - passage de num_var a base (FI, 13/12/89)
128  */
130 Psysteme ps;
131 {
132  if (ps) {
133  assert(ps->base == (Pbase) NULL);
134  ps->base = sc_to_minimal_basis(ps);
135  ps->dimension = vect_size(ps->base);
136  }
137 }
138 
139 /* fix system s for coherency of the base and number of things.
140  */
142 {
143  if (s) {
144  s->nb_eq = nb_elems_list(s->egalites);
146  if (s->base) base_rm(s->base), s->base = NULL;
147  sc_creer_base(s);
148  }
149 }
150 
151 /* Variable * sc_base_dup(int nbv, Variable * b):
152  * duplication de la table des variables base, qui contient nbv elements
153  *
154  * Modifications:
155  * - on renvoie un pointeur NULL si le nombre de variables nbv est nul
156  * - changement de num_var en base; cette fonction perd tout interet
157  * et n'est conservee que pour faciliter la mise a jour des modules
158  * de plint (FI, 19/12/89)
159  *
160  * ancien nom: tab_dup
161  */
163 int nbv;
164 Pbase b;
165 {
166  assert(nbv==base_dimension(b));
167 
168  return((Pbase) base_copy(b));
169 }
170 
171 /* Psysteme sc_dup(Psysteme ps): should becomes a link
172  *
173  * Ancien nom (obsolete): cp_sc()
174  *
175  */
177 {
178  return sc_copy(ps);
179  /*
180  Psysteme cp = SC_UNDEFINED;
181 
182  if (!SC_UNDEFINED_P(ps)) {
183  Pcontrainte eq, eq_cp;
184  cp = sc_new();
185 
186  for (eq = ps->egalites; eq != NULL; eq = eq->succ) {
187  eq_cp = contrainte_new();
188  contrainte_vecteur(eq_cp) = vect_dup(contrainte_vecteur(eq));
189  sc_add_egalite(cp, eq_cp);
190  }
191 
192  for(eq=ps->inegalites;eq!=NULL;eq=eq->succ) {
193  eq_cp = contrainte_new();
194  contrainte_vecteur(eq_cp) = vect_dup(contrainte_vecteur(eq));
195  sc_add_inegalite(cp, eq_cp);
196  }
197 
198  if(ps->dimension==0) {
199  assert(VECTEUR_UNDEFINED_P(ps->base));
200  cp->dimension = 0;
201  cp->base = VECTEUR_UNDEFINED;
202  }
203  else {
204  assert(ps->dimension==vect_size(ps->base));
205  cp->dimension = ps->dimension;
206  cp->base = base_dup(ps->base);
207  }
208  }
209 
210  return cp;
211  */
212 }
213 
214 /* Psysteme sc_copy(Psysteme ps): duplication d'un systeme (allocation
215  * et copie complete des champs sans sharing)
216  *
217  * replace sc_dup(ps), which now becomes a link
218  *
219  * Ancien nom (obsolete): cp_sc()
220  *
221  * Modification: L'ordre des egalites, inegalites, la base et des
222  * variables dans le syteme est recopie egalement. (CA,
223  * 28/08/91),(DN,24/6/02)
224  *
225  * We can use contrainte_copy, contraintes_copy here If we test the
226  * size of system here for debugging purposes, il may cost more time
227  * ...
228  *
229  */
231 {
232  Psysteme cp = SC_UNDEFINED;
233  int i,j;
234 
235  if (!SC_UNDEFINED_P(ps)) {
236  Pcontrainte eq, eq_cp;
237  cp = sc_new();
238 
239  for (j=ps->nb_eq;j>0;j--) {
240  for (eq = ps->egalites,i=1;i<j; eq = eq->succ,i++) {/**/}
241  eq_cp = contrainte_new();
243  sc_add_egalite(cp, eq_cp);
244  }
245 
246  for (j=ps->nb_ineq;j>0;j--) {
247  for (eq = ps->inegalites,i=1;i<j; eq = eq->succ,i++) {/**/}
248  eq_cp = contrainte_new();
250  sc_add_inegalite(cp, eq_cp);
251  }
252 
253  if(ps->dimension==0) {
254  cp->dimension = 0;
255  cp->base = VECTEUR_UNDEFINED;
256  }
257  else {
258  cp->dimension = ps->dimension;
259  cp->base = base_copy(ps->base);
260  }
261  }
262 
263  return cp;
264 }
265 /* void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par
266  * le systeme de contraintes ps;
267  *
268  * utilisation standard:
269  * sc_rm(s);
270  * s = NULL;
271  *
272  * comme toujours, les champs pointeurs sont remis a NULL avant la
273  * desallocation pour detecter au plus tot les erreurs dues a
274  * l'allocation dynamique de memoire
275  *
276  */
277 void sc_rm(ps)
278 Psysteme ps;
279 {
280  if (ps != NULL) {
281  if (ps->inegalites != NULL) {
282  contraintes_free(ps->inegalites);
283  ps->inegalites = NULL;
284  }
285 
286  if (ps->egalites != NULL) {
287  contraintes_free(ps->egalites);
288  ps->egalites = NULL;
289  }
290 
291  if (!VECTEUR_NUL_P(ps->base)) {
292  vect_rm(ps->base);
293  ps->base = VECTEUR_UNDEFINED;
294  }
295 
296  free((char *) ps);
297  }
298 }
299 
300 /* This function returns a new empty system which has been initialized
301  * with the same dimension and base than sc.
302  */
304 Psysteme sc;
305 {
306 
307  Psysteme sc1= sc_new();
308  sc1->dimension = sc->dimension;
309  sc1->base = base_copy(sc->base);
310  return(sc1);
311 }
312 
313 /* Psysteme sc_empty(Pbase b): build a Psysteme with one unfeasible
314  * constraint to define the empty subspace in a space R^n, where n is
315  * b's dimension. b is shared by sc.
316  *
317  * The unfeasible constraint is the equations 0 == 1
318  */
320 Pbase b;
321 {
322  Psysteme sc = SC_UNDEFINED;
326 
327  sc_base(sc) = b;
328  sc_dimension(sc) = base_dimension(b);
329 
330  return sc;
331 }
332 
333 /* Psysteme sc_rn(Pbase b): build a Psysteme without constraints to
334  * define R^n, where n is b's dimension. b is shared by sc.
335  */
337 Pbase b;
338 {
339  Psysteme sc = sc_new();
340 
341  sc_base(sc) = b;
342  sc_dimension(sc) = base_dimension(b);
343 
344  return sc;
345 }
346 /* bool sc_empty_p(Psysteme sc): check if the set associated to sc
347  * is the constant sc_empty or not. More expensive tests like
348  * sc_faisabilite() are necessary to handle the general case.
349  */
350 bool sc_empty_p(sc)
351 Psysteme sc;
352 {
353  bool empty = false;
354 
355  assert(!SC_UNDEFINED_P(sc));
356  if(sc_nbre_inegalites(sc)==0 && sc_nbre_egalites(sc)==1) {
357  Pvecteur eq = contrainte_vecteur(sc_egalites(sc));
358 
359  empty = vect_size(eq) == 1 && vecteur_var(eq) == TCST;
360  if(empty)
361  assert(vecteur_val(eq)!=0);
362  }
363  return empty;
364 }
365 
366 /* bool sc_rn_p(Psysteme sc): check if the set associated to sc is
367  the whole space, rn
368  */
369 bool sc_rn_p(sc)
370 Psysteme sc;
371 {
372  assert(!SC_UNDEFINED_P(sc));
373  return sc_nbre_inegalites(sc)==0 && sc_nbre_egalites(sc)==0;
374 }
375 
376 
377 /* void sc_add_egalite(Psysteme p, Pcontrainte e): macro ajoutant une
378  * egalite e a un systeme p; la base n'est pas mise a jour; il faut faire
379  * ensuite un appel a sc_creer_base(); il vaut mieux utiliser sc_make()
380  *
381  * sc_add_eg est (a peu pres) equivalent a sc_add_egalite, mais le
382  * parametre e n'est utilise qu'une fois ce qui permet d'eviter
383  * des surprises en cas de e++ et autres effects de bords a chaque
384  * evaluation de e; sc_add_egalite est donc plus sur que sc_add_eg
385  *
386  * If the system basis should be updated, use sc_constraint_add()
387  * and the two related function in sc_insert.c
388  */
390 {
391  assert(p && e && !e->succ);
392 
393  e->succ = p->egalites;
394  p->egalites = e;
395  p->nb_eq++;
396 }
397 
398 /* void sc_add_inegalite(Psysteme p, Pcontrainte i): macro ajoutant une
399  * inegalite i a un systeme p; la base n'est pas mise a jour; il faut
400  * ensuite faire un appel a sc_creer_base(); il vaut mieux utiliser
401  * sc_make();
402  *
403  * sc_add_ineg est (a peu pres) equivalent a sc_add_inegalite; cf supra
404  * pour l'explication des differences
405  */
407 {
408  assert(p && i && !i->succ);
409 
410  i->succ = p->inegalites;
411  p->inegalites = i;
412  p->nb_ineq++;
413 }
414 
416 {
417  if(CONTRAINTE_UNDEFINED_P(sc_egalites(p))) {
418  sc_egalites(p) = i;
419  }
420  else {
422  for(ineq = sc_egalites(p);
424  ineq = contrainte_succ(ineq)) {
425  }
426  contrainte_succ(ineq) = i;
427  }
428  /* Adjust the number of equalities */
429  sc_nbre_egalites(p) = nb_elems_list(sc_egalites(p));
430 }
431 
433 {
434  if(CONTRAINTE_UNDEFINED_P(sc_inegalites(p))) {
435  sc_inegalites(p) = i;
436  }
437  else {
439  for(ineq = sc_inegalites(p);
441  ineq = contrainte_succ(ineq)) {
442  }
443  contrainte_succ(ineq) = i;
444  }
445  /* Adjust the number of inequalities */
446  sc_nbre_inegalites(p) = nb_elems_list(sc_inegalites(p));
447 }
static hash_table seen
static function to store whether a module has been seen during the recursive generation of the daVinc...
Definition: graph.c:85
#define VALUE_ONE
#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
struct Scontrainte * Pcontrainte
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_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
Pcontrainte contrainte_new(void)
package contrainte - allocations et desallocations
Definition: alloc.c:47
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
void * malloc(YYSIZE_T)
void free(void *)
bool linear_hashtable_isin(linear_hashtable_pt h, void *k)
Definition: hashpointer.c:273
void linear_hashtable_put_once(linear_hashtable_pt h, void *k, void *v)
Definition: hashpointer.c:268
linear_hashtable_pt linear_hashtable_make(void)
constructor.
Definition: hashpointer.c:165
void linear_hashtable_free(linear_hashtable_pt h)
destructor
Definition: hashpointer.c:189
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define assert(ex)
Definition: newgen_assert.h:41
Pvecteur vect_chain(Pvecteur v_in, Variable var, Value coeff)
package vecteur routines internes au package
Definition: private.c:69
struct Ssysteme * Psysteme
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg)
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg): allocation et initialisation d'un systeme d'equ...
Definition: sc.c:78
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
Psysteme sc_empty(Pbase b)
Psysteme sc_empty(Pbase b): build a Psysteme with one unfeasible constraint to define the empty subsp...
Definition: sc_alloc.c:319
Psysteme sc_rn(Pbase b)
Psysteme sc_rn(Pbase b): build a Psysteme without constraints to define R^n, where n is b's dimension...
Definition: sc_alloc.c:336
void sc_creer_base(Psysteme ps)
void sc_creer_base(Psysteme ps): initialisation des parametres dimension et base d'un systeme lineair...
Definition: sc_alloc.c:129
void sc_fix(Psysteme s)
fix system s for coherency of the base and number of things.
Definition: sc_alloc.c:141
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
void sc_add_egalite(Psysteme p, Pcontrainte e)
void sc_add_egalite(Psysteme p, Pcontrainte e): macro ajoutant une egalite e a un systeme p; la base ...
Definition: sc_alloc.c:389
void sc_add_inegalites(Psysteme p, Pcontrainte i)
Definition: sc_alloc.c:432
Pbase sc_to_minimal_basis(Psysteme ps)
creation d'une base contenant toutes les variables apparaissant avec des coefficients non-nuls dans l...
Definition: sc_alloc.c:76
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
Psysteme sc_init_with_sc(Psysteme sc)
This function returns a new empty system which has been initialized with the same dimension and base ...
Definition: sc_alloc.c:303
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
void sc_add_inegalite(Psysteme p, Pcontrainte i)
void sc_add_inegalite(Psysteme p, Pcontrainte i): macro ajoutant une inegalite i a un systeme p; la b...
Definition: sc_alloc.c:406
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
Pbase sc_base_dup(int nbv, Pbase b)
Variable * sc_base_dup(int nbv, Variable * b): duplication de la table des variables base,...
Definition: sc_alloc.c:162
void sc_add_egalites(Psysteme p, Pcontrainte i)
Definition: sc_alloc.c:415
Psysteme sc_copy(Psysteme ps)
Psysteme sc_copy(Psysteme ps): duplication d'un systeme (allocation et copie complete des champs sans...
Definition: sc_alloc.c:230
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
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 dimension
Definition: sc-local.h:74
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
hidden structure to store the hashtable.
Definition: hashpointer.c:66
@ empty
b1 < bj -> h1/hj = empty
Definition: union-local.h:64
#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_NUL_P(v)
#define base_rm(b)
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_dimension(b)
#define BASE_NULLE
MACROS SUR LES BASES.
Pbase vect_copy(Pvecteur b)
direct duplication.
Definition: alloc.c:240
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
Pbase base_copy(Pbase b)
Direct duplication.
Definition: alloc.c:300
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78