PIPS
sc_io.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sc_io.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 <stdio.h>
32 #include <stddef.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <sys/types.h>
37 #include <dirent.h>
38 #include <sys/stat.h>
39 
40 #include "linear_assert.h"
41 #include "boolean.h"
42 #include "arithmetique.h"
43 #include "vecteur.h"
44 #include "contrainte.h"
45 #include "sc.h"
46 
47  /* Psysteme construit par sc_gram.y */
48 extern Psysteme ps_yacc;
49 
50  /* detection des erreurs de syntaxe par sc_gram.y */
51 extern bool syst_syntax_error;
52 
53  /* fichier lu par sc_lex.l */
54 extern FILE * syst_in;
55 
56 /* Psysteme * sc_read(char * nomfic): construit un systeme d'inegalites
57  * lineaires a partir d'une representation externe standard; les variables
58  * utilisees dans le systeme doivent etre declarees dans la premiere ligne;
59  * les inegalites sont separees par des virgules et regroupees entre
60  * accolades; les egalites sont converties en paires d'inegalites
61  *
62  * Exemple:
63  * VAR x, y, z
64  * { x <= 1,
65  * y == 2, x + 2 z > y }
66  *
67  * Noter l'absence de signe "multiplier" entre les coefficients numeriques
68  * et les noms de variables
69  *
70  * Cette fonction relit un fichier cree par la fonction sc_fprint()
71  *
72  * Ancien nom: fscsys_uf
73  */
74 Psysteme * sc_read(char * nomfic)
75 {
76  if ((syst_in = fopen(nomfic, "r")) == NULL) {
77  (void) fprintf(stderr,
78  "Ouverture du fichier %s impossible\n",nomfic);
79  exit(4);
80  }
81  sc_init_lex();
82  syst_parse();
83  return &ps_yacc;
84 }
85 
86 /* bool sc_fscan(FILE * f, Psysteme * ps): construit un systeme d'inegalites
87  * et d'egalites lineaires a partir d'une representation externe standard;
88  *
89  * Le systeme s est alloue et son ancienne valeur est perdue. Cette fonction
90  * devrait donc etre appelee avec la precondition s==NULL. La variable s
91  * n'est pas retournee pour respecter la syntaxe habituelle de scanf et
92  * pour pouvoir retourner un code.
93  *
94  * Si la syntaxe du fichier f est correct, la valeur true est retournee;
95  * false sinon.
96  *
97  * les variables utilisees dans le systeme doivent etre declarees dans
98  * la premiere ligne precedees du mot-cle VAR et separees par des
99  * virgules
100  *
101  * les inegalites et les egalites sont melangees entre elles, mais separees
102  * par des virgules et regroupees entre accolades; les inegalites sont
103  * toutes mises sous la forme :
104  *
105  * sum a x <= b
106  * i i i
107  *
108  * ou b est le terme constant; noter que le terme constant est conserve
109  * a droite du comparateur et la partie lineaire a gauche
110  *
111  * Exemple:
112  * VAR x, y, z
113  * { x <= 1,
114  * y == 2, x + 2 z > y }
115  *
116  * Noter l'absence de signe "multiplier" entre les coefficients numeriques
117  * et les noms de variables
118  *
119  * Cette fonction peut relire un fichier cree par la fonction sc_fprint()
120  */
121 bool sc_fscan(FILE * f, Psysteme * ps)
122 {
123  syst_in = f;
124  sc_init_lex();
125  syst_restart(f);
126  syst_parse();
128  *ps = ps_yacc;
129  return !syst_syntax_error;
130 }
131 
132 /* void sc_dump(Psysteme sc): dump to stderr
133  *
134  * Ancien nom: sc_fprint() (modifie a cause d'un conflit avec une autre
135  * fonction sc_fprint d'un profil different)
136  *
137  * using variable_debug_name(); lost of original variables' names
138  * now compatible with sc_fscan()
139  * Better use sc_default_name(Psysteme)
140  * DN(5/8/2002)
141  */
143 {
144  if(!SC_UNDEFINED_P(sc)) {
145 
146  (void) fprintf(stderr,"#DIMENSION: (%d) ",sc->dimension);
147  (void) fprintf(stderr,"INEGALITES (%d) ",sc_nbre_inegalites(sc));
148  (void) fprintf(stderr,"EGALITES (%d) ",sc_nbre_egalites(sc));
149  //(void) fprintf(stderr,"BASE (%p) ", sc->base);
150  //(void) fprintf(stderr,"LISTE INEGALITES (%p) ", sc->inegalites);
151  //(void) fprintf(stderr,"LISTE EGALITES (%p) ", sc->egalites);
152  (void) fprintf(stderr,"\nVAR ");
153  base_fprint(stderr,sc->base, variable_debug_name);
154  (void) fprintf(stderr," {\n");
157  (void) fprintf(stderr," }\n");
158  }
159  else
160  (void) fprintf(stderr, "SC_RN or SC_EMPTY or SC_UNDEFINED\n");
161 }
162 
163 /* void sc_default_dump(Psysteme sc): dump to stderr
164  *
165  * sc_default_dump is now compatible with sc_fscan
166  * using default_variable_to_string (stored by LINEAR. see sc_debug.c)
167  * may fail in very few cases, because of variable names.
168  * DN(5/8/2002)
169  */
171 {
172  if(!SC_UNDEFINED_P(sc)) {
173  (void) fprintf(stderr,"#DIMENSION: %d ",sc->dimension);
174  (void) fprintf(stderr,"INEGALITES (%d) ",sc_nbre_inegalites(sc));
175  (void) fprintf(stderr,"EGALITES (%d) ",sc_nbre_egalites(sc));
176  (void) fprintf(stderr,"\nVAR ");
178  (void) fprintf(stderr," {\n");
181  (void) fprintf(stderr," }\n");
182  }
183  else
184  (void) fprintf(stderr, "SC_RN ou SC_EMPTY ou SC_UNDEFINED\n");
185 }
186 
187 
188 
189 /* void sc_print()
190  *
191  * Obsolete. Better use sc_default_dump()
192  *
193  */
195 {
196  sc_fprint(stderr, ps, nom_var);
197 }
198 
199 /* void sc_fprint(FILE * f, Psysteme ps, char * (*nom_var)()):
200  * cette fonction imprime dans le fichier pointe par 'fp' la representation
201  * externe d'un systeme lineaire en nombres entiers, compatible avec la
202  * fonction de lecture sc_fscan()
203  *
204  * nom_var est un pointeur vers la fonction permettant d'obtenir le
205  * nom d'une variable (i.e. d'un des vecteurs de base)
206  *
207  * FI:
208  * - le test ne devrait pas etre fait sur NULL;
209  * - il faudrait toujours faire quelque chose, ne serait-ce qu'imprimer
210  * un systeme nul sous la forme {}; et trouver quelque chose pour
211  * les systemes infaisables;
212  * - pourquoi n'utilise-t-on pas inegalites_fprint (et egalites_fprint)
213  * pour ne pas reproduire un boucle inutile? Sont-elles compatibles avec
214  * la routine de lecture d'un systeme?
215  *
216  * DN: better use sc_fprint_for_sc_fscan()
217  * - can add the information like #dimension, nb_eq, nb_ineq or label in the beginning
218  * - been implemented as sc_fprint_for_sc_fscan(), without infeasibility issue.
219  */
220 void sc_fprint(FILE * fp,
221  Psysteme ps,
223 {
224  register Pbase b;
225  Pcontrainte peq;
226 
227  if (ps != NULL) {
228  int count = 0;
229  if (ps->dimension >=1) {
230  (void)fprintf(fp,"VAR %s",(*nom_var)(vecteur_var(ps->base)));
231 
232  for (b=ps->base->succ; !VECTEUR_NUL_P(b); b = b->succ)
233  (void)fprintf(fp,", %s",(*nom_var)(vecteur_var(b)));
234  }
235  (void) fprintf(fp," \n { \n");
236 
237  for (peq = ps->inegalites, count=0; peq!=NULL; peq=peq->succ, count++)
238  inegalite_fprint(fp,peq,nom_var);
239 
240  assert(count==ps->nb_ineq);
241 
242  for (peq = ps->egalites, count=0; peq!=NULL; peq=peq->succ, count++)
243  egalite_fprint(fp,peq,nom_var);
244 
245  assert(count==ps->nb_eq);
246 
247  (void) fprintf(fp," } \n");
248  }
249  else
250  (void) fprintf(fp,"(nil)\n");
251 }
252 
253 /* void sc_fprint_for_sc_fscan(FILE *f, Psysteme sc, char * (*nom_var)(Variable))
254  *
255  * compatible with sc_fscan. Replaced sc_default_dump_to_file (not really in use)
256  *
257  * should use default_variable_to_string
258  *
259  */
260 void sc_fprint_for_sc_fscan(FILE * f, Psysteme sc, char * (*nom_var)(Variable))
261 {
262  if(!SC_UNDEFINED_P(sc)) {
263  (void) fprintf(f,"#DIMENSION (%d) ",sc->dimension);
264  (void) fprintf(f,"INEGALITES (%d) ",sc_nbre_inegalites(sc));
265  (void) fprintf(f,"EGALITES (%d) ",sc_nbre_egalites(sc));
266  (void) fprintf(f,"\nVAR ");
267  base_fprint(f,sc->base, nom_var);
268  (void) fprintf(f," {\n ");
271  (void) fprintf(f," }\n");
272  }
273  else {
274  (void) fprintf(f, "SC_RN ou SC_EMPTY ou SC_UNDEFINED\n");
275  }
276 }
277 
278 /* void sc_default_dump_to_files(Psysteme sc, sc_nb,directory_name):
279  *
280  * Suitable for filtering purposes
281  * Print the system of constraints into several output files in a directory with names given
282  * Each file is 100% compatible with sc_fscan
283  * print with name of variables from default_variable_to_string
284  * overwrite if files exist
285  * DN(10/2/2003)
286  *
287  */
288 void sc_default_dump_to_files(sc, sc_nb,directory_name)
289 Psysteme sc;
290 int sc_nb;
291 char *directory_name;
292 {
293  FILE * f;
294  char fn[512], *filename;
295  int d;
296 
297  filename = "_sc.out";
298  if (directory_name==NULL)
299  directory_name = "SC_OUT_DEFAULT";
300  d = chdir(directory_name);
301  if (d) {
302  mkdir(directory_name,S_IRWXU);
303  d = chdir(directory_name);
304  }
305  assert(d == 0);
306 
307  snprintf(fn,sizeof(fn),"%d%s",sc_nb,filename);
308 
309  if ((f = fopen(fn,"w")) != NULL) {
310  if(!SC_UNDEFINED_P(sc)) {
311  (void) fprintf(f,"#DIMENSION (%d) ",sc->dimension);
312  (void) fprintf(f,"INEGALITES (%d) ",sc_nbre_inegalites(sc));
313  (void) fprintf(f,"EGALITES (%d) ",sc_nbre_egalites(sc));
314  (void) fprintf(f,"\nVAR ");
315 
317  (void) fprintf(f," {\n ");
320  (void) fprintf(f," }\n");
321  }
322  else {
323  (void) fprintf(f, "SC_RN ou SC_EMPTY ou SC_UNDEFINED\n");
324  }
325  fclose(f);
326  } else {
327  fprintf(stderr,"Ouverture du fichier %s impossible\n",fn);
328  }
329  if (chdir("..")) // just to avoid a gcc warning
330  fprintf(stderr, "chdir(\"..\") failed\n");
331 }
static int count
Definition: SDG.c:519
void inegalites_fprint(FILE *, Pcontrainte, char *(*)(Variable))
void egalite_fprint(FILE *, Pcontrainte, char *(*)(Variable))
void inegalite_fprint(FILE *, Pcontrainte, char *(*)(Variable))
void egalites_fprint(FILE *, Pcontrainte, char *(*)(Variable))
void base_fprint(FILE *f, Pbase b, get_variable_name_t variable_name)
void base_fprint(FILE * f, Pbase b, char * (*variable_name)()): impression d'une base sur le fichier ...
Definition: io.c:342
char *(* variable_debug_name)(Variable)
Debug support: pointer to the function used by debug print outs.
Definition: variable.c:114
#define exit(code)
Definition: misc-local.h:54
#define assert(ex)
Definition: newgen_assert.h:41
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
void sc_init_lex(void)
char * default_variable_to_string(Variable v)
Definition: sc_debug.c:245
int syst_parse(void)
void sc_fprint(FILE *fp, Psysteme ps, get_variable_name_t nom_var)
void sc_fprint(FILE * f, Psysteme ps, char * (*nom_var)()): cette fonction imprime dans le fichier po...
Definition: sc_io.c:220
void sc_print(Psysteme ps, get_variable_name_t nom_var)
void sc_print()
Definition: sc_io.c:194
void sc_default_dump_to_files(Psysteme sc, int sc_nb, char *directory_name)
void sc_default_dump_to_files(Psysteme sc, sc_nb,directory_name):
Definition: sc_io.c:288
Psysteme * sc_read(char *nomfic)
Psysteme * sc_read(char * nomfic): construit un systeme d'inegalites lineaires a partir d'une represe...
Definition: sc_io.c:74
void sc_fprint_for_sc_fscan(FILE *f, Psysteme sc, char *(*nom_var)(Variable))
void sc_fprint_for_sc_fscan(FILE *f, Psysteme sc, char * (*nom_var)(Variable))
Definition: sc_io.c:260
bool syst_syntax_error
detection des erreurs de syntaxe par sc_gram.y
Definition: sc_gram.c:93
FILE * syst_in
fichier lu par sc_lex.l
bool sc_fscan(FILE *f, Psysteme *ps)
bool sc_fscan(FILE * f, Psysteme * ps): construit un systeme d'inegalites et d'egalites lineaires a p...
Definition: sc_io.c:121
void sc_dump(Psysteme sc)
void sc_dump(Psysteme sc): dump to stderr
Definition: sc_io.c:142
void sc_default_dump(Psysteme sc)
void sc_default_dump(Psysteme sc): dump to stderr
Definition: sc_io.c:170
Psysteme ps_yacc
package sc
Definition: sc_gram.c:95
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * nom_var[100]
Definition: sc_read.c:89
Psysteme sc_reversal(Psysteme sc)
Psysteme sc_reversal(Psysteme sc)
Definition: sc_read.c:208
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
#define vecteur_var(v)
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62
#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