PIPS
pnome-io.c
Go to the documentation of this file.
1 /*
2 
3  $Id: pnome-io.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 /******************************************************************** pnome-io.c
26  *
27  * POLYNOMIAL INPUT/OUTPUT FUNCTIONS
28  *
29  */
30 #ifdef HAVE_CONFIG_H
31  #include "config.h"
32 #endif
33 
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <stdint.h>
38 
39 #include "linear_assert.h"
40 #include <ctype.h>
41 
42 #include "boolean.h"
43 #include "arithmetique.h"
44 #include "vecteur.h"
45 #include "polynome.h"
46 
47 
48 /* void float_to_frac(float x, char** ps)
49  * PRIVATE
50  * returns the simplest representation of floating-point number x
51  * tries to make an integer, then a small fraction, then a floating-point,
52  * then a floating-point with exponent.
53  */
54 void float_to_frac(x, ps)
55 char **ps;
56 float x;
57 {
58  int i;
59  float fprecision = (float) intpower(10.0, -PNOME_FLOAT_N_DECIMALES);
60 
61  if (((x <= fprecision) && (x >= -fprecision)) ||
63  /* if too little or too big print it with an exponent */
64  sprintf(*ps, "%.*E", PNOME_FLOAT_N_DECIMALES, x);
65  else {
66  /* default printing: as a float */
67  sprintf(*ps, "%.*f", PNOME_FLOAT_N_DECIMALES, x);
68  for (i=1; i<PNOME_FLOAT_TO_FRAC_LEVEL; i++)
69  if ((((x*i) - ((int) (x*i+0.5))) < (fprecision)) &&
70  (((x*i) - ((int) (x*i+0.5))) > (-fprecision))) {
71  /* if x is close enough up to a little fraction */
72  if ((((int) (x*i+0.5)) < PNOME_FLOAT_TO_FRAC_LEVEL) || (i==1)) {
73  /*print it as a fraction */
74  if (i==1)
75  sprintf(*ps, "%d", (int) (x*i+0.5));
76  else
77  sprintf(*ps, "%d/%d", (int) (x*i+0.5), i);
78  }
79  break;
80  }
81  }
82 }
83 
84 /* void monome_fprint(FILE* fd, Pmonome pm, Pbase pb, bool plus_sign, char* (*variable_name)())
85  * PRIVATE
86  * Outputs to file fd an ASCII form of monomial pm, naming variables
87  * with the "variable-name" function, ordering them with the basis pb.
88  * the "+" sign is printed if plus_sign == true.
89  */
90 void monome_fprint(fd, pm, pb, plus_sign, variable_name)
91 FILE *fd;
92 Pmonome pm;
93 Pbase pb;
94 bool plus_sign;
95 char * (*variable_name)(Variable);
96 {
97  char *s = monome_sprint(pm, pb, plus_sign, variable_name);
98 
99  fprintf(fd, "%s", s);
100  free(s);
101 }
102 
103 /* char *monome_sprint(Pmonome pm, Pbase pb, bool plus_sign, char* (*variable_name)())
104  * PRIVATE
105  * Outputs a string representing monomial pm, naming variables
106  * with the "variable-name" function, ordering them with the basis pb.
107  * the "+" sign is printed if plus_sign == true.
108  */
109 char *monome_sprint(pm, pb, plus_sign, variable_name)
110 Pmonome pm;
111 Pbase pb;
112 bool plus_sign;
113 char * (*variable_name)(Variable);
114 {
115  float x;
116  char t[99];
117  char *r, *s;
118  char *u;
119 
120  u = (char *) malloc(99);
121  r = t;
122 
123  if (MONOME_UNDEFINED_P(pm))
124  sprintf(r, "%s", MONOME_UNDEFINED_SYMBOL);
125  else {
126  x = monome_coeff(pm);
127  if (x==0)
128  sprintf(r, "%s", MONOME_NUL_SYMBOL);
129  else {
130  if (x<0) {
131  *(r++) = '-';
132  if (plus_sign)
133  *(r++) = ' ';
134  x = - x;
135  }
136  else if (plus_sign) {
137  *(r++) = '+';
138  *(r++) = ' ';
139  }
140 
141  float_to_frac(x, &u);
142 
143  if (vect_coeff(TCST, monome_term(pm)) == 0) {
144  if (x != 1) {
145  sprintf(r, "%s%s", u, MONOME_COEFF_MULTIPLY_SYMBOL);
146  r = strchr(r, '\0');
147  }
150  strcpy(r, s);
151  free(s);
152  }
153  else
154  sprintf(r, "%s", u);
155  }
156  }
157  free(u);
158  return (char*) strdup((char *) t);
159 }
160 
161 /* void polynome_fprint(FILE* fd, Ppolynome pp,
162  * char* (*variable_name)(),
163  * bool (*is_inferior_var)())
164  * Outputs to file fd an ASCII form of polynomial pp, using
165  * the user-provided function variable_name(Variable var) to associate
166  * the "Variable" pointers with the variable names.
167  * is_inferior_var(Variable var1, Variable var2) is also given by the user:
168  * it must return true if var1 must be printed before var2 in monomials.
169  *
170  * For the moment, monomials are not sorted.
171  * No "\n" is printed after the polynomial.
172  */
174 FILE *fd;
175 Ppolynome pp;
176 char * (*variable_name)(Variable);
178 {
180 
181  fprintf(fd, "%s", s);
182  free(s);
183 }
184 
185 /* char *polynome_sprint(Ppolynome pp,
186  * char* (*variable_name)(),
187  * bool (*is_inferior_var)())
188  * Outputs to file fd an ASCII form of polynomial pp, using
189  * the user-provided function variable_name(Variable var) to associate
190  * the "Variable" pointers with the variable names.
191  * is_inferior_var(Variable var1, Variable var2) is also given by the user:
192  * it must return true if var1 must be printed before var2 in monomials.
193  *
194  * For the moment, monomials are not sorted.
195  * No "\n" is printed after the polynomial.
196  */
198 Ppolynome pp;
199 char * (*variable_name)(Variable);
201 {
202 #define POLYNOME_BUFFER_SIZE 20480
203  static char t[POLYNOME_BUFFER_SIZE];
204  char *r, *s;
205 
206  r = t;
207 
208  if (POLYNOME_UNDEFINED_P(pp))
209  sprintf(r, "%s", POLYNOME_UNDEFINED_SYMBOL);
210  else if (POLYNOME_NUL_P(pp))
211  sprintf(r, "%s", POLYNOME_NUL_SYMBOL);
212  else {
214  bool print_plus_sign = false;
215 
216  /* The following line is added by L.Zhou Mar. 26, 91 */
217  pp = polynome_sort(&pp, is_inferior_var);
218 
219  while (!POLYNOME_NUL_P(pp)) {
220  s = monome_sprint(polynome_monome(pp), pb,
221  print_plus_sign, variable_name);
222  strcpy(r, s);
223  r = strchr(r, '\0');
224  pp = polynome_succ(pp);
225  print_plus_sign = true;
226  if (!POLYNOME_NUL_P(pp)) *(r++) = ' ';
227  free(s);
228  }
229  }
230  assert( strlen(t) < POLYNOME_BUFFER_SIZE);
231  return (char*) strdup((char *) t);
232 }
233 
234 
235 /* char *default_variable_name(Variable var)
236  * returns for variable var the name "Vxxxx" where xxxx are
237  * four letters computed from (int) var.
238 
239  * I guess that many variables can have the same name since the naming is
240  * done modulo 26^4 ? RK. To be fixed...
241  */
243 Variable var;
244 {
245  char *s = (char *) malloc(6);
246  int i = (intptr_t) var;
247 
248  if (var != TCST) {
249  sprintf(s, "V%c%c%c%c",
250  (char) 93 + (i % 26),
251  (char) 93 + ((i / 26) % 26),
252  (char) 93 + ((i / 26 / 26) % 26),
253  (char) 93 + ((i / 26 / 26 / 26) % 26));
254  }
255  else
256  sprintf(s, "TCST");
257  return(s);
258 }
259 
260 
261 /* bool default_is_inferior_var(Variable var1, Variable var2)
262  * return true if var1 is before var2, lexicographically,
263  * according to the "default_variable_name" naming.
264  */
265 int default_is_inferior_var(var1, var2)
266 Variable var1, var2;
267 {
268  return strcmp(default_variable_name(var1),
269  default_variable_name(var2));
270 }
271 
272 /* bool default_is_inferior_varval(Pvecteur varval1, Pvecteur varval2)
273  * return true if var1 is before var2, lexicographically,
274  * according to the "default_variable_name" naming.
275  */
277 {
278  return strcmp(default_variable_name(vecteur_var(varval1)),
280 }
281 
282 /* bool default_is_inferior_pvarval(Pvecteur * pvarval1, Pvecteur * pvarval2)
283  * return true if var1 is before var2, lexicographically,
284  * according to the "default_variable_name" naming.
285  */
286 int default_is_inferior_pvarval(Pvecteur * pvarval1, Pvecteur * pvarval2)
287 {
288  return strcmp(default_variable_name(vecteur_var(* pvarval1)),
289  default_variable_name(vecteur_var(* pvarval2)));
290 }
291 
292 static void remove_blanks(ps)
293 char **ps;
294 {
295  char *s = *ps,
296  *t = *ps;
297 
298  do {
299  while (isspace(**ps))
300  (*ps)++;
301  *t++ = *(*ps)++;
302  } while (**ps != '\0');
303  *t++ = '\0';
304  *ps = s;
305 }
306 
307 static float parse_coeff(ps)
308 char **ps;
309 {
310  float coeff = 0;
311 
312  if (isdigit(**ps) || (**ps == '.') || (**ps == '+') || (**ps == '-')) {
313  sscanf(*ps, "%f", &coeff);
314  if ((coeff == 0) && (**ps == '+'))
315  coeff = 1;
316  if ((coeff == 0) && (**ps == '-'))
317  coeff = -1;
318  }
319  else
320  coeff = 1;
321 
322  if ((**ps == '-') || (**ps == '+'))
323  (*ps)++;
324  while (isdigit(**ps) || (**ps == '.') || (**ps == '*'))
325  (*ps)++;
326 
327  if (**ps == '/') { /* handle fractionnal coefficients */
328  float denom;
329  (*ps)++;
330  denom = parse_coeff(ps);
331  coeff /= denom;
332  }
333 
334  return(coeff);
335 }
336 
337 static char *parse_var_name(ps)
338 char **ps;
339 {
340  char *name, *n;
341 
342  name = (char *) malloc(MAX_NAME_LENGTH);
343  n = name;
344 
345  if (isalpha(**ps)) /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
346  do { *n++ = *((*ps)++); }
347  while (isalnum(**ps) || (**ps == ':')); /* THE ':' STANDS FOR MODULE_SEP_STRING OF Linear/C3 Library */
348  /* TO BE ABLE TO HANDLE VARIABLES SUCH AS P:I */
349  *n = '\0';
350 
351  return(name);
352 }
353 
354 /* Ppolynome polynome_sscanf(char *sp, (*name_to_variable)())
355  * converts into polynomial structure the expression passed
356  * in ASCII form in string sp. (for debug only)
357  * pas vraiment quick mais bien dirty
358  */
360 char *sp;
362 {
363  Ppolynome pp = POLYNOME_NUL;
364  Pmonome curpm;
365  bool constructing_monome = false;
366  float coeff = 0.;
367  char *varname;
368  Value power;
369  char *s;
370 
371  s = (char*) strdup(sp);
372  remove_blanks(&s);
373 
374  while (*s != '\0')
375  {
376  /*fprintf(stderr, "\ns='%s'\n", s);*/
377  power = VALUE_ONE;
378  if (!constructing_monome) { coeff = parse_coeff(&s);
379  }
380  varname = parse_var_name(&s);
381  if (strlen(varname)!=0) {
382  if (*s == '^') {
383  s++;
384  power = float_to_value(parse_coeff(&s));
385  }
386  else
387  while ((*s == '.') || (*s == '*')) s++;
388  }
389  else varname = (char*) strdup("TCST");
390 
391  if (constructing_monome) {
392  vect_add_elem(&(monome_term(curpm)),
393  name_to_variable(varname),
394  power);
395  }
396  else {
397  curpm = make_monome(coeff, name_to_variable(varname), power);
398  constructing_monome = true;
399  }
400  /*fprintf(stderr, "au milieu: s='%s'\n", s);*/
401 
402  if ((*s == '+') || (*s == '-'))
403  {
404  polynome_monome_add(&pp, curpm);
405  monome_rm(&curpm);
406  constructing_monome = false;
407  }
408  }
409  if (!MONOME_NUL_P(curpm)) {
410  polynome_monome_add(&pp, curpm);
411  monome_rm(&curpm);
412  }
413 
414  return (pp);
415 }
void const char const char const int
#define float_to_value(f)
int Value
#define VALUE_ONE
Variable name_to_variable(char *)
Definition: polynome_ri.c:172
bool is_inferior_var(Variable, Variable)
Definition: polynome_ri.c:118
void * malloc(YYSIZE_T)
void free(void *)
char * vect_sprint_as_monome(Pvecteur v, Pbase b, get_variable_name_t variable_name, char *mult_symbol)
char *vect_sprint_as_monome(Pvecteur v, Pbase b, char * (*variable_name)(), char *mult_symbol): Retou...
Definition: io.c:217
#define assert(ex)
Definition: newgen_assert.h:41
Pmonome make_monome(float coeff, Variable var, Value expo)
Pmonome make_monome(float coeff, Variable var, Value expo) PRIVATE allocates space for,...
Definition: pnome-alloc.c:81
void monome_rm(Pmonome *ppm)
void monome_rm(Pmonome* ppm) PRIVATE frees space occupied by monomial *ppm returns *ppm pointing to M...
Definition: pnome-alloc.c:154
void polynome_monome_add(Ppolynome *ppp, Pmonome pm)
void polynome_monome_add(Ppolynome* ppp, Pmonome pm) PRIVATE Add monomial pm to polynomial *ppp,...
Definition: pnome-bin.c:50
void monome_fprint(FILE *fd, Pmonome pm, Pbase pb, bool plus_sign, char *(*variable_name)(Variable))
void monome_fprint(FILE* fd, Pmonome pm, Pbase pb, bool plus_sign, char* (*variable_name)()) PRIVATE ...
Definition: pnome-io.c:90
int default_is_inferior_pvarval(Pvecteur *pvarval1, Pvecteur *pvarval2)
bool default_is_inferior_pvarval(Pvecteur * pvarval1, Pvecteur * pvarval2) return true if var1 is bef...
Definition: pnome-io.c:286
static void remove_blanks(char **ps)
Definition: pnome-io.c:292
static float parse_coeff(char **ps)
Definition: pnome-io.c:307
char * monome_sprint(Pmonome pm, Pbase pb, bool plus_sign, char *(*variable_name)(Variable))
char monome_sprint(Pmonome pm, Pbase pb, bool plus_sign, char (*variable_name)()) PRIVATE Outputs a s...
Definition: pnome-io.c:109
void polynome_fprint(FILE *fd, Ppolynome pp, char *(*variable_name)(Variable), int *is_inferior_var)
void polynome_fprint(FILE* fd, Ppolynome pp, char* (*variable_name)(), bool (*is_inferior_var)()) Out...
Definition: pnome-io.c:173
int default_is_inferior_varval(Pvecteur varval1, Pvecteur varval2)
bool default_is_inferior_varval(Pvecteur varval1, Pvecteur varval2) return true if var1 is before var...
Definition: pnome-io.c:276
static char * parse_var_name(char **ps)
Definition: pnome-io.c:337
Ppolynome polynome_sscanf(char *sp, Variable(*name_to_variable)(Variable))
Ppolynome polynome_sscanf(char *sp, (*name_to_variable)()) converts into polynomial structure the exp...
Definition: pnome-io.c:359
#define POLYNOME_BUFFER_SIZE
int default_is_inferior_var(Variable var1, Variable var2)
bool default_is_inferior_var(Variable var1, Variable var2) return true if var1 is before var2,...
Definition: pnome-io.c:265
char * default_variable_name(Variable var)
char *default_variable_name(Variable var) returns for variable var the name "Vxxxx" where xxxx are fo...
Definition: pnome-io.c:242
char * polynome_sprint(Ppolynome pp, char *(*variable_name)(Variable), int *is_inferior_var)
char polynome_sprint(Ppolynome pp, char (*variable_name)(), bool (*is_inferior_var)()) Outputs to fil...
Definition: pnome-io.c:197
void float_to_frac(float x, char **ps)
void float_to_frac(float x, char** ps) PRIVATE returns the simplest representation of floating-point ...
Definition: pnome-io.c:54
double intpower(double d, int n)
double intpower(double d, int n) returns d^n for all integers n
Pbase polynome_used_var(Ppolynome pp, int *is_inferior_var)
Pbase polynome_used_var(Ppolynome pp, bool *is_inferior_var()) PRIVATE Returns, in a Pbase,...
Definition: pnome-reduc.c:204
Ppolynome polynome_sort(Ppolynome *ppp, int *is_inferior_var)
Ppolynome polynome_sort((Ppolynome *) ppp, bool (*is_inferior_var)()) Sorts the polynomial *ppp: mono...
#define POLYNOME_NUL
#define MAX_NAME_LENGTH
#define POLYNOME_UNDEFINED_SYMBOL
#define PNOME_FLOAT_TO_EXP_LEVEL
#define MONOME_UNDEFINED_SYMBOL
#define PNOME_FLOAT_TO_FRAC_LEVEL
#define MONOME_NUL_SYMBOL
#define POLYNOME_UNDEFINED_P(pp)
#define monome_term(pm)
#define MONOME_UNDEFINED_P(pm)
#define polynome_monome(pp)
#define monome_coeff(pm)
Macros definitions.
#define POLYNOME_NUL_P(pp)
#define POLYNOME_NUL_SYMBOL
#define MONOME_VAR_MULTIPLY_SYMBOL
#define MONOME_NUL_P(pm)
#define polynome_succ(pp)
#define PNOME_FLOAT_N_DECIMALES
#define MONOME_COEFF_MULTIPLY_SYMBOL
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
char * variable_name(Variable v)
polynome_ri.c
Definition: polynome_ri.c:73
static char * x
Definition: split_file.c:159
#define intptr_t
Definition: stdint.in.h:294
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
struct Svecteur * Pbase
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
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
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