PIPS
sc.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sc.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  * Malik Imadache, Corinne Ancourt, Neil Butler, Francois Irigoin
28  *
29  */
30 
31 #ifdef HAVE_CONFIG_H
32  #include "config.h"
33 #endif
34 
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include "linear_assert.h"
38 
39 #include "arithmetique.h"
40 #include "boolean.h"
41 #include "vecteur.h"
42 #include "contrainte.h"
43 #include "sc.h"
44 
45 #define MALLOC(s,t,f) malloc(s)
46 
47 /* norm_syst(Psysteme): division des contraintes, egalites ou inegalites,
48  * par le PGCD des coefficients de chaque contrainte;
49  *
50  * la faisabilite ou la non-faisabilite n'est pas testee: le terme
51  * constant ne devrait pas etre pris en compte dans norm_eq().
52  */
53 void norm_syst(sc)
54 Psysteme sc;
55 {
57 
58  for (eq=sc->egalites;eq!=NULL;eq=eq->succ)
59  norm_eq(eq);
60  for (eq=sc->inegalites;eq!=NULL;eq=eq->succ)
61  norm_eq(eq);
62 }
63 
64 /* Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg):
65  * allocation et initialisation d'un systeme d'equations et inequations
66  * lineaires a partir de deux listes de contraintes, une liste
67  * d'egalites et une liste d'inegalites
68  *
69  * ATTENTION: les deux listes leg et lineq ne sont pas dupliquees; un appel
70  * a cette fonction peut donc creer du sharing entre structures de donnees
71  *
72  * Ancien nom: mk_syst()
73  *
74  * Modifications:
75  * - ajout de l'initialisation de base et de dimension par un appel
76  * a sc_creer_base()
77  */
78 Psysteme sc_make(leg,lineg)
79 Pcontrainte leg;
80 Pcontrainte lineg;
81 {
82  Psysteme s;
83 
84  s = (Psysteme ) MALLOC(sizeof(Ssysteme),SYSTEME,"sc_make");
85  s->egalites = leg;
86  s->inegalites = lineg;
87  s->nb_eq = nb_elems_list(leg);
88  s->nb_ineq = nb_elems_list(lineg);
90  sc_creer_base(s);
91  return(s);
92 }
93 
94 /* Psysteme sc_translate(Psysteme s, Pbase b, char * (*variable_name)()):
95  * reecriture du systeme s dans la base b basee sur les noms des vecteurs
96  * de base; tous les vecteurs de base utilises dans s doivent avoir un
97  * vecteur de base de meme nom dans b
98  */
100 Psysteme s;
101 Pbase b;
102 char * (*variable_name)();
103 {
104  Pcontrainte e;
105  Pcontrainte i;
106 
107  if(!SC_UNDEFINED_P(s)) {
108 
109  /* translate all equations */
110  for(e=s->egalites; !CONTRAINTE_UNDEFINED_P(e); e = e->succ)
111  (void) contrainte_translate(e, b, variable_name);
112 
113  /* translate all inequalities */
114  for(i=s->inegalites; !CONTRAINTE_UNDEFINED_P(i); i = i->succ)
115  (void) contrainte_translate(i, b, variable_name);
116 
117  /* update basis in s; its dimension should not change */
118  s->base = vect_translate(s->base, b, variable_name);
119  }
120  return s;
121 }
122 
123 /* Psysteme sc_substitute_dimension(Psysteme s, Variable i, Pvecteur v):
124  * The ith dimension of all constraints c is updated:
125  *
126  * c = c + c_i v
127  *
128  * Vector v is untouched
129  */
131 {
132  Pcontrainte e;
133  Pcontrainte c;
134 
135  if(!SC_UNDEFINED_P(s)) {
136  //vect_add_elem(&v, i, VALUE_MONE);
137  /* translate all equations */
138  for(e=s->egalites; !CONTRAINTE_UNDEFINED_P(e); e = e->succ)
139  (void) contrainte_substitute_dimension(e, i, v);
140 
141  /* translate all inequalities */
142  for(c=s->inegalites; !CONTRAINTE_UNDEFINED_P(c); c = c->succ)
143  (void) contrainte_substitute_dimension(c, i, v);
144 
145  /* update basis in s */
146  vect_rm(s->base);
147  s->base = (Pbase) NULL;
148  sc_creer_base(s);
149  }
150  return s;
151 }
152 
153 /* Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new):
154  * reecriture du systeme s remplacant toutes les occurences de la coordonnees
155  * v_old par des occurences de v_new
156  */
157 Psysteme sc_variable_rename(s, v_old, v_new)
158 Psysteme s;
159 Variable v_old;
160 Variable v_new;
161 {
162  Pcontrainte e, i;
163 
164  /* v_new MUST NOT already be in the base. */
165  assert(vect_coeff(v_new, s->base)==VALUE_ZERO);
166 
167  if(!SC_UNDEFINED_P(s))
168  {
169  /* rename all equations */
170  for(e=s->egalites; !CONTRAINTE_UNDEFINED_P(e); e = e->succ)
171  (void) contrainte_variable_rename(e, v_old, v_new);
172 
173  /* rename all inequalities */
174  for(i=s->inegalites; !CONTRAINTE_UNDEFINED_P(i); i = i->succ)
175  (void) contrainte_variable_rename(i, v_old, v_new);
176 
177  /* update basis in s; its dimension should not change */
178  s->base = vect_variable_rename(s->base, v_old, v_new);
179  }
180 
181  return s;
182 }
183 
184 /* Psysteme sc_rename_variables(s, renamed_p, new_variable)
185  * Psysteme s;
186  * bool (*renamed_p)(Variable);
187  * Variable (*new_variable)(Variable);
188  *
189  * what: driven renaming of variables in s.
190  * how: scans, decides and replaces.
191  * input: Psysteme s, plus the decision and replacement functions
192  * output: s is returned.
193  * side effects:
194  * - the system is modified in place.
195  * bugs or features:
196  * - was written by FC...
197  */
199 Psysteme s;
200 bool (*renamed_p)(/*Variable*/);
201 Variable (*new_variable)(/*Variable*/);
202 {
203  Pcontrainte c;
204 
205  if(SC_UNDEFINED_P(s)) return(s);
206 
207  for(c=sc_egalites(s); c!=NULL; c=c->succ)
209  renamed_p, new_variable);
210 
211  for(c=sc_inegalites(s); c!=NULL; c=c->succ)
213  renamed_p, new_variable);
214 
215  (void) vect_rename_variables(sc_base(s), renamed_p, new_variable);
216 
217  return(s);
218 }
219 
220 /* Psysteme sc_variables_rename(Psysteme s, Pvecteur pv_old, Pvecteur pv_new):
221  * reecriture du systeme s remplacant toutes les occurences des coordonnees
222  * de pv_old par des occurences de pv_new
223  */
225  Pvecteur pv_old,
226  Pvecteur pv_new,
228 {
229  Pvecteur pv;
230  for (pv = pv_old; !VECTEUR_UNDEFINED_P(pv); pv = pv->succ) {
231  Variable var_new = base_find_variable_name(pv_new, vecteur_var(pv),
232  variable_name);
233  if (!VARIABLE_UNDEFINED_P(var_new))
234  s = sc_variable_rename(s,pv->var,var_new);
235  }
236  return s;
237 }
238 
240 Psysteme sc;
241 Variable v;
242 {
243  sc_base(sc) = base_remove_variable(sc_base(sc),v);
244  sc_dimension(sc) --;
245 }
246 
247 
249 Psysteme sc;
250 Variable var;
251 {
252 
253  Pbase b1 = sc->base;
254 
255  if (!VECTEUR_NUL_P(b1)) {
256  for(; !VECTEUR_NUL_P(b1) && !variable_equal(vecteur_var(b1), var);
257  b1 = b1->succ);
258  if (VECTEUR_NUL_P(b1)) {
259  for (b1 = sc->base; !VECTEUR_NUL_P(b1->succ); b1=b1->succ);
260  b1->succ = vect_new(var, VALUE_ONE);
261  sc_dimension(sc)++;
262  }
263  }
264  else {
265  sc->base = vect_new(var, VALUE_ONE);
266  sc_dimension(sc)++; }
267 }
268 
269 /* bool sc_consistent_p(Psysteme sc): check that sc is well defined, that the
270  * numbers of equalities and inequalities are consistent with the lists of
271  * equalities and inequalities, and that every variable in the constraints is
272  * in the base
273  *
274  * Francois Irigoin, 7 July 1993
275  *
276  * Note:
277  * - it also checks that every variable in the basis is used with a non-zero
278  * coefficient in at least one constraint (although there is no reason for that)
279  * - there is no explicit check of TCST in the basis; TCST should *not* be in the
280  * basis
281  */
283 {
284  bool consistent;
285  bool flawed = false;
286 
287  consistent = !SC_UNDEFINED_P(sc);
288 
289  if(consistent) {
290  if(sc->nb_eq != safe_nb_elems_list(sc_egalites(sc), sc->nb_eq)) {
291  fprintf(stderr, "Inconsistent number of equalities\n");
292  flawed = true;
293  }
294  if(sc->nb_ineq != safe_nb_elems_list(sc_inegalites(sc), sc->nb_ineq)) {
295  fprintf(stderr, "Inconsistent number of inequalities\n");
296  flawed = true;
297  }
298  if(sc_dimension(sc) != base_dimension(sc_base(sc))) {
299  fprintf(stderr, "Inconsistent dimension\n");
300  flawed = true;
301  }
302  if(!base_normalized_p(sc_base(sc))) {
303  fprintf(stderr, "Inconsistent base\n");
304  flawed = true;
305  }
306  }
307  consistent = consistent && !flawed;
308 
309  if(consistent) {
311  Pbase diagonale = BASE_UNDEFINED;
313  Pbase diff = BASE_UNDEFINED;
314 
315  for(eq = sc->egalites; eq!= NULL; eq=eq->succ) {
316  for (pv = eq->vecteur;pv!= NULL;pv=pv->succ)
317  if (pv->var != TCST)
318  vect_chg_coeff(&diagonale,pv->var, VALUE_ONE);
319  }
320  for(eq = sc->inegalites; eq!= NULL; eq=eq->succ) {
321  for (pv = eq->vecteur;pv!= NULL;pv=pv->succ)
322  if (pv->var != TCST)
323  vect_chg_coeff(&diagonale,pv->var, VALUE_ONE);
324  }
325  diff = base_difference(diagonale, sc_base(sc));
326  consistent = BASE_NULLE_P(diff);
327  if(!consistent) {
328  fprintf(stderr, "The base does not cover all the constraints\n");
329  fprintf(stderr, "Current base\n");
330  vect_dump(sc_base(sc));
331  fprintf(stderr, "Necessary base\n");
332  vect_dump(diagonale);
333  fprintf(stderr, "Base difference\n");
334  vect_dump(diff);
335  }
336  }
337 
338  /* This assert is too bad ! I remove it.
339  *
340  * Alexis Platonoff, 31 january 1995 */
341  /* assert(consistent); */
342 
343  return consistent;
344 }
345 
346 /* check that sc is well defined, that the numbers of equalities and
347  * inequalities are consistent with the lists of equalities and
348  * inequalities, that the dimension is consistent with the basis, that the
349  * basis itself is consistent (all coefficients must be 1), and that every
350  * variable in the constraints is in the basis.
351  *
352  * Each component in the basis should only appear once thanks to the
353  * specifications of Pvecteur (this is not checked).
354  *
355  * Francois Irigoin, 13 November 1995
356  *
357  * Note:
358  * - there is no explicit check of TCST in the basis;
359  * TCST should *not* be in the basis for some use of Psystemes,
360  * like transformers in Linear/C3 Library.
361  * */
363 {
364  bool weak_consistent;
365 
366  weak_consistent = !SC_UNDEFINED_P(sc);
367 
368  if(weak_consistent) {
369  /* The test is broken down into three lines to increase the
370  information available when Valgrind detects a memory access
371  error. */
372  int neq = nb_elems_list(sc_egalites(sc));
373  int nineq = nb_elems_list(sc_inegalites(sc));
374  int dim = base_dimension(sc_base(sc));
375 
376  weak_consistent = (sc->nb_eq == neq);
377  weak_consistent = weak_consistent
378  && (sc->nb_ineq == nineq);
379  weak_consistent = weak_consistent
380  && (sc_dimension(sc) == dim);
381  }
382 
383  if(weak_consistent && sc_dimension(sc) != 0) {
384  Pbase b = sc_base(sc);
385  weak_consistent = base_normalized_p(b);
386  }
387 
388  if(weak_consistent) {
389  Pcontrainte eq;
390  Pvecteur pv;
391  Pbase diagonale = BASE_NULLE;
392 
393  for(eq = sc->egalites; eq!= NULL; eq=eq->succ) {
394  for (pv = eq->vecteur;pv!= NULL;pv=pv->succ)
395  if (pv->var != TCST)
396  vect_chg_coeff(&diagonale,pv->var, VALUE_ONE);
397  }
398  for(eq = sc->inegalites; eq!= NULL; eq=eq->succ) {
399  for (pv = eq->vecteur;pv!= NULL;pv=pv->succ)
400  if (pv->var != TCST)
401  vect_chg_coeff(&diagonale,pv->var, VALUE_ONE);
402  }
403  weak_consistent = base_included_p(diagonale, sc_base(sc));
404  base_rm(diagonale);
405  }
406 
407  /* assert(weak_consistent); */
408 
409  return weak_consistent;
410 }
411 /*
412  * builds two systems from one according to base b:
413  * the system of constraints that contain some b variables,
414  * and the system of those that do not.
415  * s and b are not touched.
416  */
417 void
419  Psysteme s,
420  Pbase b,
421  Psysteme *pwith,
422  Psysteme *pwithout)
423 {
424  Pcontrainte i_with, e_with, i_without, e_without;
425 
426  Pcontrainte_separate_on_vars(sc_inegalites(s), b, &i_with, &i_without);
427  Pcontrainte_separate_on_vars(sc_egalites(s), b, &e_with, &e_without);
428 
429  *pwith = sc_make(e_with, i_with),
430  *pwithout = sc_make(e_without, i_without);
431 }
#define VALUE_ZERO
#define VALUE_ONE
Pbase base_difference(Pbase b1, Pbase b2)
Pbase base_difference(Pbase b1, Pbase b2): allocate b; b = b1 - b2 – with the set meaning return b;.
Definition: base.c:621
Pbase base_remove_variable(Pbase b, Variable v)
Pbase base_remove_variable(b, v): remove basis vector relative to v from b; abort if v is not in b;.
Definition: base.c:122
Variable base_find_variable_name(Pbase b, Variable v, char *(*variable_name)(Variable))
Variable base_find_variable_name(Pbase b, Variable v, char * (*variable_name)()): returns the variabl...
Definition: base.c:170
Pvecteur vect_translate(Pvecteur v, Pbase b, char *(*variable_name)(Variable))
Pvecteur vect_translate(Pvecteur v, Pbase b, char * (*variable_name)()): modify vector v so that its ...
Definition: base.c:313
Pvecteur vect_rename_variables(Pvecteur v, bool(*renamed_p)(Variable), Variable(*new_variable)(Variable))
Pvecteur vect_rename_variables(v, renamed_p, new_variable) Pvecteur v; bool (*renamed_p)(Variable); V...
Definition: base.c:281
Pvecteur vect_variable_rename(Pvecteur v, Variable v_old, Variable v_new)
Pvecteur vect_variable_rename(Pvecteur v, Variable v_old, Variable v_new): rename the potential coord...
Definition: base.c:366
bool base_included_p(Pbase b1, Pbase b2)
Pbase base_included_p(Pbase b1, Pbase b2): include_p = b1 is included in b2 – with the set meaning re...
Definition: base.c:640
bool base_normalized_p(Pbase b)
Definition: base.c:604
#define CONTRAINTE_UNDEFINED_P(c)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_substitute_dimension(Pcontrainte e, Variable i, Pvecteur v)
Definition: binaires.c:57
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 norm_eq(Pcontrainte)
unaires.c
Definition: unaires.c:44
int safe_nb_elems_list(Pcontrainte, int)
Compute the number of elements in the list if it is less than n.
Definition: listes.c:162
Pcontrainte contrainte_variable_rename(Pcontrainte, Variable, Variable)
Pcontrainte contrainte_variable_rename(Pcontrainte c, Variable v_old, Variable v_new): rename the pot...
Definition: unaires.c:115
void Pcontrainte_separate_on_vars(Pcontrainte, Pbase, Pcontrainte *, Pcontrainte *)
void Pcontrainte_separate_on_vars(initial, vars, pwith, pwithout) Pcontrainte initial; Pbase vars; Pc...
Definition: unaires.c:140
Pcontrainte contrainte_translate(Pcontrainte, Pbase, char *(*)(void))
static entity new_variable
entity to be replaced, the primary?
Definition: dynamic.c:860
void vect_dump(Pvecteur v)
void vect_dump(Pvecteur v): print sparse vector v on stderr.
Definition: io.c:304
bool variable_equal(Variable v1, Variable v2)
package vecteur - routines sur les variables
Definition: variable.c:62
#define MALLOC(s, t, f)
package matrice
Definition: smith.c:42
#define assert(ex)
Definition: newgen_assert.h:41
int bool
we cannot use an enum or stdbool because we need to be compatible with newgen, thus boolean need to h...
Definition: newgen_types.h:78
struct Ssysteme * Psysteme
#define SYSTEME
package sc sur les Systemes de Contraintes lineaires.
Definition: sc-local.h:47
void sc_base_add_variable(Psysteme sc, Variable var)
Definition: sc.c:248
void sc_base_remove_variable(Psysteme sc, Variable v)
Definition: sc.c:239
void norm_syst(Psysteme sc)
norm_syst(Psysteme): division des contraintes, egalites ou inegalites, par le PGCD des coefficients d...
Definition: sc.c:53
bool sc_consistent_p(Psysteme sc)
bool sc_consistent_p(Psysteme sc): check that sc is well defined, that the numbers of equalities and ...
Definition: sc.c:282
Psysteme sc_rename_variables(Psysteme s, bool(*renamed_p)(), Variable(*new_variable)())
Psysteme sc_rename_variables(s, renamed_p, new_variable) Psysteme s; bool (*renamed_p)(Variable); Var...
Definition: sc.c:198
Psysteme sc_translate(Psysteme s, Pbase b, char *(*variable_name)())
Psysteme sc_translate(Psysteme s, Pbase b, char * (*variable_name)()): reecriture du systeme s dans l...
Definition: sc.c:99
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
void sc_separate_on_vars(Psysteme s, Pbase b, Psysteme *pwith, Psysteme *pwithout)
Definition: sc.c:418
Psysteme sc_variables_rename(Psysteme s, Pvecteur pv_old, Pvecteur pv_new, get_variable_name_t variable_name)
Psysteme sc_variables_rename(Psysteme s, Pvecteur pv_old, Pvecteur pv_new): reecriture du systeme s r...
Definition: sc.c:224
Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new)
Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new): reecriture du systeme s remp...
Definition: sc.c:157
bool sc_weak_consistent_p(Psysteme sc)
check that sc is well defined, that the numbers of equalities and inequalities are consistent with th...
Definition: sc.c:362
Psysteme sc_substitute_dimension(Psysteme s, Variable i, Pvecteur v)
Psysteme sc_substitute_dimension(Psysteme s, Variable i, Pvecteur v): The ith dimension of all constr...
Definition: sc.c:130
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
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
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * variable_name(Variable v)
polynome_ri.c
Definition: polynome_ri.c:73
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
Variable var
Definition: vecteur-local.h:90
struct Svecteur * succ
Definition: vecteur-local.h:92
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
struct Svecteur * Pbase
#define VECTEUR_UNDEFINED
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62
#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 VARIABLE_UNDEFINED_P(v)
Definition: vecteur-local.h:65
#define BASE_UNDEFINED
#define base_dimension(b)
#define BASE_NULLE
MACROS SUR LES BASES.
#define BASE_NULLE_P(b)
#define VECTEUR_UNDEFINED_P(v)
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
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
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val)
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val): mise de la coordonnee var du vecteur *pp...
Definition: unaires.c:143