PIPS
constraint_to_text.c
Go to the documentation of this file.
1 /*
2 
3  $Id: constraint_to_text.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS 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 General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 
32 #include "linear.h"
33 
34 #include "genC.h"
35 
36 #include "text.h"
37 #include "text-util.h"
38 
39 #include "properties.h"
40 #include "misc.h"
41 #include "ri.h"
42 #include "ri-util.h"
43 
44 /******************************************************************* SYSTEME */
45 
47 {
49 }
50 
51 /******************************************** FOR PRETTYPRINTING CONSTRAINTS */
52 
54 {
56 }
57 
59 {
61 }
62 
63 static string the_operator(bool is_inegalite, bool a_la_fortran)
64 {
65  return is_inegalite? (a_la_fortran? ".LE.": "<="):
66  (a_la_fortran? ".EQ.": "==");
67 }
68 
69 static void
71  string buffer,
72  Value v,
73  string continuation,
74  text t)
75 {
77 }
78 
79 static void
81  string buffer,
82  Value constante,
83  bool is_inegalite,
84  bool a_la_fortran,
85  string continuation,
86  text t)
87 {
88  add_to_current_line(buffer, the_operator(is_inegalite, a_la_fortran),
89  continuation, t);
91 }
92 
93 static void
95  string buffer,
96  Value coeff,
97  Variable var,
98  char * (*variable_name)(Variable),
99  string continuation,
100  text t)
101 {
102  if (value_notone_p(ABS(coeff)) || var==TCST)
105 }
106 
107 static void
109  string buffer,
110  string signe,
111  Value coeff,
112  Variable var,
113  char * (*variable_name)(Variable),
114  string continuation,
115  text t)
116 {
119  continuation, t);
120 }
121 
122 static char *
124  string buffer,
125  string continuation,
126  text txt,
127  Pvecteur v,
128  bool is_inegalite,
129  char * (*variable_name)(Variable),
130  bool a_la_fortran,
131  bool __attribute__ ((unused)) first_line)
132 {
133  short int debut = 1;
134  Value constante = VALUE_ZERO;
135 
136  while (!VECTEUR_NUL_P(v))
137  {
138  Variable var = var_of(v);
139  Value coeff = val_of(v);
140 
141  if (var!=TCST) {
142  string signe;
143 
144  if (value_notzero_p(coeff)) {
145  if (value_pos_p(coeff))
146  signe = "+";
147  else {
148  signe = "-";
149  coeff = value_uminus(coeff);
150  };
151  if (value_pos_p(coeff) && debut)
154  continuation, txt);
155  else
156  signed_operation_to_textline(buffer, signe, coeff,
157  var, variable_name,
158  continuation, txt);
159  debut = 0;
160  }
161  }
162  else
163  /* on admet plusieurs occurences du terme constant!?! */
164  value_addto(constante, coeff);
165 
166  v = v->succ;
167  }
168  constante_to_textline(buffer,value_uminus(constante),is_inegalite,
169  a_la_fortran, continuation, txt);
170  return buffer;
171 }
172 
173 /* FI: does not take into account constant floating point terms
174  *
175  * No easy modification. I give up for the time being. 25 July 2011.
176  */
177 static string
179  string buffer,
180  string continuation,
181  text txt,
182  Pvecteur v,
183  bool is_inegalite,
184  string (*variable_name)(Variable),
185  bool a_la_fortran,
186  bool __attribute__ ((unused)) first_line)
187 {
188  Pvecteur coord;
189  short int debut = true;
190  int positive_terms = 0;
191  int negative_terms = 0;
192  Value const_coeff = 0;
193  bool const_coeff_p = false;
194  string signe;
195 
196  if(!is_inegalite) {
197  for(coord = v; !VECTEUR_NUL_P(coord); coord = coord->succ) {
198  if(vecteur_var(coord)!= TCST
199  && !entity_constant_p((entity)vecteur_var(coord)))
200  (value_pos_p(vecteur_val(coord))) ?
201  positive_terms++ : negative_terms++;
202  }
203 
204  if(negative_terms > positive_terms)
205  vect_chg_sgn(v);
206  }
207 
208  positive_terms = 0;
209  negative_terms = 0;
210 
211  for(coord = v; !VECTEUR_NUL_P(coord); coord = coord->succ) {
212  Value coeff = vecteur_val(coord);
213  Variable var = vecteur_var(coord);
214 
215  if (value_pos_p(coeff)) {
216  positive_terms++;
217  if(!term_cst(coord)|| is_inegalite)
218  {
219  signe = "+";
220  if (debut)
222  continuation, txt);
223  else
225  continuation, txt);
226  debut=false;
227  }
228  else positive_terms--;
229  }
230  }
231 
232  if(positive_terms == 0)
234 
235  add_to_current_line(buffer, the_operator(is_inegalite, a_la_fortran),
236  continuation, txt);
237 
238  debut = true;
239  for(coord = v; !VECTEUR_NUL_P(coord); coord = coord->succ)
240  {
241  Value coeff = vecteur_val(coord);
242  Variable var = var_of(coord);
243 
244  if(term_cst(coord) && !is_inegalite) {
245  /* Save the constant term for future use */
246  const_coeff_p = true;
247  const_coeff = coeff;
248  /* And now, a lie... In fact, rhs_terms++ */
249  negative_terms++;
250  }
251  else if (value_neg_p(coeff))
252  {
253  negative_terms++;
254  signe = "+";
255  if (debut) {
257  (buffer, value_uminus(coeff), var, variable_name,
258  continuation, txt);
259  debut=false;
260  }
261  else
263  (buffer, signe, value_uminus(coeff),var, variable_name,
264  continuation, txt);
265  }
266  }
267 
268  if(negative_terms == 0)
270 
271  else if(const_coeff_p)
272  {
273  pips_assert("const coeff not zero", value_notzero_p(const_coeff));
274  if (!debut && value_neg_p(const_coeff))
277  continuation, txt);
278  }
279 
280  return buffer;
281 }
282 
283 
284 string
286  string aux_line,
287  string continuation,
288  text txt,
289  Pcontrainte c,
290  bool is_inegalite,
291  string (*variable_name)(Variable),
292  bool a_la_fortran,
293  bool first_line)
294 {
295  Pvecteur v;
296  int heuristique = 2;
297 
298  if (!CONTRAINTE_UNDEFINED_P(c))
299  v = contrainte_vecteur(c);
300  else
301  v = VECTEUR_NUL;
302 
303  pips_assert("vector v is okay", vect_check(v));
304 
305  switch(heuristique) {
306  case 1: aux_line = contrainte_to_text_1(aux_line,continuation,txt,
307  v,is_inegalite, variable_name,
308  a_la_fortran, first_line);
309  break;
310  case 2:aux_line = contrainte_to_text_2(aux_line,continuation,txt,v,
311  is_inegalite, variable_name,
312  a_la_fortran, first_line);
313  break;
314  default: contrainte_error("contrainte_sprint", "unknown heuristics\n");
315  }
316 
317  return aux_line;
318 }
319 
320 string
322  string aux_line,
323  string continuation,
324  text txt,
325  Pcontrainte eg,
326  string (*variable_name)(Variable),
327  bool a_la_fortran,
328  bool first_line)
329 {
330  return contrainte_text_format(aux_line,continuation,txt,eg, false,
331  variable_name,a_la_fortran,first_line);
332 }
333 
334 string
336  string aux_line,
337  string continuation,
338  text txt,
339  Pcontrainte ineg,
340  string (*variable_name)(),
341  bool a_la_fortran,
342  bool first_line)
343 {
344  return contrainte_text_format(aux_line,continuation,txt,ineg, true,
345  variable_name,a_la_fortran,first_line);
346 }
347 
348 
349 static void
350 add_separation(string line, string prefix, text txt, bool a_la_fortran)
351 {
352  add_to_current_line(line, a_la_fortran? ".AND.": ", ", prefix, txt);
353 }
354 
355 static bool
357  string line, /* current buffer */
358  string prefix, /* for continuations */
359  text txt, /* formed text */
360  Pcontrainte cs, /* contraintes to be printed */
361  string (*variable_name)(Variable), /* hook for naming a variable */
362  bool invert_put_first, /* whether to invert put_first */
363  bool (*put_first)(Pvecteur), /* whether to put first some constraints */
364  bool some_previous, /* whether a separator is needed */
365  bool is_inegalites, /* egalites or inegalites */
366  bool a_la_fortran /* fortran look? */)
367 {
368  for (; cs; cs=cs->succ)
369  {
370  if (put_first? (invert_put_first ^ put_first(cs->vecteur)): true)
371  {
372  if (some_previous) add_separation(line, prefix, txt, a_la_fortran);
373  else some_previous = true;
374 
375  if (a_la_fortran)
376  add_to_current_line(line, "(", prefix, txt);
377 
378  contrainte_text_format(line, prefix, txt, cs, is_inegalites,
379  variable_name, false, a_la_fortran);
380 
381  if (a_la_fortran)
382  add_to_current_line(line, ")", prefix, txt);
383  }
384  }
385  return some_previous;
386 }
387 
388 /* lower level hook for regions.
389  */
390 void
392  string line,
393  string prefix,
394  text txt,
395  Psysteme ps,
396  string (*variable_name)(Variable),
397  bool (*put_first)(Pvecteur), /* whether to put a constraints ahead */
398  bool a_la_fortran)
399 {
400  bool invert, stop, some_previous = false;
401 
402  if (ps==NULL)
403  {
404  add_to_current_line(line, get_string_property("SYSTEM_NULL"), prefix, txt);
405  return;
406  }
407  else if (SC_UNDEFINED_P(ps))
408  {
409  add_to_current_line(line, get_string_property("SYSTEM_UNDEFINED"),
410  prefix, txt);
411  return;
412  }
413  else if (sc_empty_p(ps))
414  {
415  add_to_current_line(line, get_string_property("SYSTEM_NOT_FEASIBLE"),
416  prefix, txt);
417  return;
418  }
419 
420  /* {
421  */
422  if (!a_la_fortran) add_to_current_line(line, "{", prefix, txt);
423 
424  /* repeat twice: once for first, once for not first.
425  */
426  for(invert = false, stop = false; !stop; )
427  {
428  /* == / .EQ.
429  */
430  some_previous =
431  contraintes_text_format(line, prefix, txt, sc_egalites(ps),
432  variable_name, invert, put_first,
433  some_previous, false, a_la_fortran);
434 
435  /* <= / .LE.
436  */
437  some_previous =
438  contraintes_text_format(line, prefix, txt, sc_inegalites(ps),
439  variable_name, invert, put_first,
440  some_previous, true, a_la_fortran);
441 
442  if (invert || !put_first) stop = true;
443  invert = true;
444  }
445 
446  /* }
447  */
448  if (!a_la_fortran) add_to_current_line(line, "}", prefix, txt);
449 }
450 
451 /* appends ps to line/txt with prefix continuations.
452  */
454  string line,
455  string prefix,
456  text txt,
457  Psysteme ps,
458  string (*variable_name)(Variable),
459  bool a_la_fortran)
460 {
462  (line, prefix, txt, ps, variable_name, NULL, a_la_fortran);
463 }
464 
465 /* appends the list of entity...
466  */
467 void
469  string line,
470  string continuation,
471  text t,
472  list /* of entity */ le,
473  const char* (*var_name)(entity))
474 {
475  if (le)
476  {
477  int j=0, len = gen_length(le);
478  const char ** provi = (const char **) malloc(sizeof(char *) * len);
479  bool some_previous = false;
480 
481  FOREACH(entity, e, le)
482  provi[j++] = entity_undefined_p(e)? "undefined...": var_name(e);
483 
484  qsort(provi, len, sizeof(char**), gen_qsort_string_cmp);
485 
486  for(j=0; j<len; j++)
487  {
488  if (some_previous) add_to_current_line(line, ",", continuation, t);
489  else some_previous = true;
490  add_to_current_line(line, provi[j], continuation, t);
491  }
492 
493  free(provi);
494  }
495 }
496 
497 /* That is all
498  */
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
#define value_pos_p(val)
#define VALUE_ZERO
#define value_notzero_p(val)
#define value_uminus(val)
unary operators on values
#define value_notone_p(val)
int Value
#define ABS(x)
was: #define value_mult(v,w) value_direct_multiply(v,w) #define value_product(v,w) value_direct_produ...
#define value_addto(ref, val)
#define value_neg_p(val)
char * Value_to_string(Value)
Definition: io.c:76
static void signed_operation_to_textline(string buffer, string signe, Value coeff, Variable var, char *(*variable_name)(Variable), string continuation, text t)
static string the_operator(bool is_inegalite, bool a_la_fortran)
static string contrainte_to_text_2(string buffer, string continuation, text txt, Pvecteur v, bool is_inegalite, string(*variable_name)(Variable), bool a_la_fortran, bool __attribute__((unused)) first_line)
FI: does not take into account constant floating point terms.
static void constante_to_textline(string buffer, Value constante, bool is_inegalite, bool a_la_fortran, string continuation, text t)
void inegalite_debug(Pcontrainte c)
string inegalite_text_format(string aux_line, string continuation, text txt, Pcontrainte ineg, string(*variable_name)(), bool a_la_fortran, bool first_line)
void system_sorted_text_format(string line, string prefix, text txt, Psysteme ps, string(*variable_name)(Variable), bool(*put_first)(Pvecteur), bool a_la_fortran)
lower level hook for regions.
string egalite_text_format(string aux_line, string continuation, text txt, Pcontrainte eg, string(*variable_name)(Variable), bool a_la_fortran, bool first_line)
static void unsigned_operation_to_textline(string buffer, Value coeff, Variable var, char *(*variable_name)(Variable), string continuation, text t)
static bool contraintes_text_format(string line, string prefix, text txt, Pcontrainte cs, string(*variable_name)(Variable), bool invert_put_first, bool(*put_first)(Pvecteur), bool some_previous, bool is_inegalites, bool a_la_fortran)
void entity_list_text_format(string line, string continuation, text t, list le, const char *(*var_name)(entity))
appends the list of entity...
void system_text_format(string line, string prefix, text txt, Psysteme ps, string(*variable_name)(Variable), bool a_la_fortran)
appends ps to line/txt with prefix continuations.
void sc_syst_debug(Psysteme s)
constraint_to_text.c
void egalite_debug(Pcontrainte c)
string contrainte_text_format(string aux_line, string continuation, text txt, Pcontrainte c, bool is_inegalite, string(*variable_name)(Variable), bool a_la_fortran, bool first_line)
static char * contrainte_to_text_1(string buffer, string continuation, text txt, Pvecteur v, bool is_inegalite, char *(*variable_name)(Variable), bool a_la_fortran, bool __attribute__((unused)) first_line)
static void add_separation(string line, string prefix, text txt, bool a_la_fortran)
static void add_Value_to_current_line(string buffer, Value v, string continuation, text t)
#define continuation
Definition: prettyprint.c:102
#define CONTRAINTE_UNDEFINED_P(c)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
void egalite_fprint(FILE *, Pcontrainte, char *(*)(Variable))
void contrainte_error(char *, char *,...)
error.c
Definition: error.c:49
void inegalite_fprint(FILE *, Pcontrainte, char *(*)(Variable))
char * get_string_property(const char *)
void * malloc(YYSIZE_T)
void free(void *)
size_t gen_length(const list l)
Definition: list.c:150
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
bool vect_check(Pvecteur cv)
bool vect_check(Pvecteur v): renvoie true si le vecteur v est coherent avec les specifications du pac...
Definition: reductions.c:529
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
int gen_qsort_string_cmp(const void *, const void *)
Callback for sorting string with qsort.
Definition: string.c:332
static const char * prefix
#define entity_constant_p(e)
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
#define entity_undefined_p(x)
Definition: ri.h:2762
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_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
char * variable_name(Variable v)
polynome_ri.c
Definition: polynome_ri.c:73
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
static int line
FLEX_SCANNER.
Definition: scanner.c:852
static string buffer
Definition: string.c:113
Pvecteur vecteur
struct Scontrainte * succ
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
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
void add_to_current_line(string, const char *, string, text)
Definition: util.c:140
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_val(v)
#define vecteur_var(v)
#define val_of(varval)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
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
#define var_of(varval)
#define term_cst(varval)