PIPS
sc_enumerate.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sc_enumerate.c 1526 2012-04-26 08:14:32Z guelton $
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 
25 #ifdef HAVE_CONFIG_H
26  #include "pips_config.h"
27 #endif
28 
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <limits.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 
37 #include "linear.h"
38 
39 /* IRISA/POLYLIB data structures.
40  */
41 #include "polylib/polylib.h"
42 
43 /* maximum number of rays allowed in chernikova... (was 20000)
44  * it does not look a good idea to move the limit up, as it
45  * makes both time and memory consumption to grow a lot.
46  */
47 #define MAX_NB_RAYS (20000)
48 
49 /* Irisa is based on int. We would like to change this to
50  * some other type, say "long long" if desired, as VALUE may
51  * also be changed. It is currently an int. Let us assume
52  * that the future type will be be called "IRINT" (Irisa Int)
53  */
54 /*
55 #define VALUE_TO_IRINT(val) VALUE_TO_INT(val)
56 #define IRINT_TO_VALUE(i) ((Value)i)
57 */
58 
59 #define VALUE_TO_IRINT(val) (val)
60 #define IRINT_TO_VALUE(i) (i)
61 
62 
63 static void my_Matrix_Free(Matrix * volatile * m)
64 {
65  ifscdebug(9)
66  fprintf(stderr, "[my_Matrix_Free] in %p\n", *m);
67 
68  Matrix_Free(*m);
69  *m = NULL;
70 
71  ifscdebug(9)
72  fprintf(stderr, "[my_Matrix_Free] out %p\n", *m);
73 }
74 
75 static void my_Polyhedron_Free(Polyhedron * volatile * p)
76 {
77  ifscdebug(9)
78  fprintf(stderr, "[my_Polyhedron_Free] in %p\n", *p);
79 
80  Polyhedron_Free(*p);
81  *p = NULL;
82 
83  ifscdebug(9)
84  fprintf(stderr, "[my_Polyhedron_Free] out %p\n", *p);
85 }
86 
87 
88 /* Fonctions de conversion traduisant une Pcontrainte en une
89  * ligne de la structure matrix de l'IRISA
90  */
92  Pcontrainte pc,
93  Matrix *mat,
94  int i,
95  Pbase base)
96 {
97  Pvecteur pv;
98  int j;
99  Value v;
100 
101  for (pv=base,j=1; !VECTEUR_NUL_P(pv); pv=pv->succ,j++)
102  {
104  mat->p[i][j] = VALUE_TO_IRINT(v);
105  }
106 
108  mat->p[i][j]= VALUE_TO_IRINT(v);
109 }
110 
111 /* Passage du systeme lineaire sc a une matrice matrix (structure Irisa)
112  * Cette fonction de conversion est utilisee par la fonction
113  * sc_to_sg_chernikova
114  */
115 static void sc_to_matrix(Psysteme sc, Matrix *mat)
116 {
117  int nbrows, i, j;
118  Pcontrainte peq;
119  Pvecteur pv;
120 
121  nbrows = mat->NbRows;
122 
123  // Differentiation equations and inequations
124  for (i=0; i<=sc->nb_eq-1;i++)
125  mat->p[i][0] =0;
126  for (; i<=nbrows-1;i++)
127  mat->p[i][0] =1;
128 
129  // Matrix initialisation
130  for (peq = sc->egalites,i=0;
132  peq=peq->succ, i++)
133  contrainte_to_matrix_ligne(peq,mat,i,sc->base);
134 
135  for (peq =sc->inegalites;
137  peq=peq->succ, i++)
138  contrainte_to_matrix_ligne(peq,mat,i,sc->base);
139 
140  for (pv=sc->base,j=1; !VECTEUR_NUL_P(pv); pv=pv->succ, j++)
141  mat->p[i][j] = 0;
142  mat->p[i][j]=1;
143 }
144 
145 
146 #if 0
147 /* Evaluate that the point defined by the value array N meets the
148  sparse equality defined by v and b. See also contrainte_eval(). */
149 static Value eval_constraint_with_vertex(
150  Pvecteur v,
151  Pbase b,
152  int d,
153  Value * N)
154 {
156  Value k = VALUE_ZERO;
157 
158  // debugging information - any equivalent to ifscdebug() for polyedre?
159  // ifscdebug seems to be used although not in sc
160  static int francois_debug=0;
161  if(francois_debug) {
162  int i;
163  fprintf(stderr, "Constraint:\n");
164  vect_dump(v);
165  fprintf(stderr, "Basis:\n");
166  vect_dump(b);
167  fprintf(stderr, "Vertex:\n");
168  for(i=0;i<d;i++)
169  fprintf(stderr, "N[%d]=%ld, ", i, (long int) N[i]);
170  fprintf(stderr, "\n");
171  }
172 
173  for(cv=v; !VECTEUR_UNDEFINED_P(cv); cv = vecteur_succ(cv)) {
174  Variable var = vecteur_var(cv);
175  Value coeff = vecteur_val(cv);
176  if(var==TCST) {
177  value_addto(k, coeff);
178  }
179  else {
180  int rank = rank_of_variable(b, var);
181  assert(0<rank && rank<d-1);
182  Value val = value_pdiv(N[rank],N[d-1]);
183  value_addto(k, value_direct_multiply(coeff, val));
184  }
185  }
186 
187  return k;
188 }
189 
190 /* Check that the point defined by the value array N meets the
191  sparse equality defined by v and b */
192 static bool vertex_meets_equality_p(Pvecteur v, Pbase b, int d, Value * N)
193 {
194  Value k = eval_constraint_with_vertex(v, b, d, N);
195  bool meets_p = value_zero_p(k);
196  return meets_p;
197 }
198 
199 /* Check that the point defined by the value array N meets the
200  sparse inequality defined by v and b */
201 static bool vertex_meets_inequality_p(Pvecteur v, Pbase b, int d, Value * N)
202 {
203  Value k = eval_constraint_with_vertex(v, b, d, N);
204  bool meets_p = value_negz_p(k);
205  return meets_p;
206 }
207 
208 /* Check that the point defined by the value array N meets the
209  sparse inequality defined by v and b */
210 static bool vertex_strictly_meets_inequality_p
211 (Pvecteur v, Pbase b, int d, Value * N)
212 {
213  Value k = eval_constraint_with_vertex(v, b, d, N);
214  bool meets_p = value_neg_p(k);
215  return meets_p;
216 }
217 #endif
218 
219 #if 0
220 /* Check if the Value vector N is inside the set of integer points defined by sc
221  *
222  * Used to avoid adding redundant vertices.
223  */
224 static bool redundant_vertex_p(Psysteme sc, int d, Value * N, bool strict_p)
225 {
226  bool redundant_p = true;
227  Pbase b = sc_base(sc);
229 
230  assert(base_dimension(b)==d-2);
231 
232  for(eq=sc_egalites(sc);
233  !CONTRAINTE_UNDEFINED_P(eq) && redundant_p;
234  eq = contrainte_succ(eq)) {
236  redundant_p = vertex_meets_equality_p(v, b, d, N);
237  }
238 
239  for(eq=sc_inegalites(sc);
240  !CONTRAINTE_UNDEFINED_P(eq) && redundant_p;
241  eq = contrainte_succ(eq)) {
243  if(strict_p)
244  redundant_p = vertex_strictly_meets_inequality_p(v, b, d, N);
245  else
246  redundant_p = vertex_meets_inequality_p(v, b, d, N);
247  }
248 
249  return redundant_p;
250 }
251 #endif
252 
253 
254 static Variable base_nth(Pbase b,size_t i)
255 {
256  while(i--) {
257  b=vecteur_succ(b);
258  }
259  return vecteur_var(b);
260 }
261 
262 static Ppolynome evalue_to_polynome(evalue *, Pbase );
263 
264 static Ppolynome enode_to_polynome(enode *e, Pbase ordered_base)
265 {
266  int i;
267  if (!e)
268  return POLYNOME_UNDEFINED;
270  switch(e->type) {
271  case evector:
272  for (i=0; i<e->size; i++) {
273  Ppolynome pp = evalue_to_polynome(&e->arr[i],ordered_base);
274  polynome_add(&p,pp);
275  }
276  return p;
277  case polynomial:
278  for (i=e->size-1; i>=0; i--) {
279  Ppolynome pp = evalue_to_polynome(&e->arr[i],ordered_base);
280  pp=polynome_mult(pp,make_polynome(1,base_nth(ordered_base,e->pos-1),i));
281  polynome_add(&p,pp);
282  }
283  return p;
284  default:
285  fprintf(stderr,"cannot represent periodic polynomials in linear\n");
286  return POLYNOME_UNDEFINED;
287  }
288 }
289 
290 static Ppolynome evalue_to_polynome(evalue *e, Pbase ordered_base)
291 {
292  Ppolynome p = NULL;
293  if(value_notzero_p(e->d))
294  p=make_polynome((float)e->x.n/(float)e->d,TCST,0);
295  else
296  p = enode_to_polynome(e->x.p,ordered_base);
297  return p;
298 }
299 
300 /* enumerate the systeme sc using base pb
301  * pb contains the unknow variables
302  * and sc all the constraints
303  * ordered_sc must be order as follows:
304  * elements from ordered_base appear last
305  * variable_names can be provided for debugging purpose (name of bases) or set to NULL
306  */
308  Psysteme ordered_sc, Pbase ordered_base,
309  const char* variable_names[])
310 {
311  // Automatic variables read in a CATCH block need to be declared volatile as
312  // specified by the documentation
313  Polyhedron * volatile A = NULL;
314  Matrix * volatile a = NULL;
315  Polyhedron * volatile C = NULL;
316  Enumeration * volatile ehrhart = NULL;
317 
318  int nbrows = 0;
319  int nbcolumns = 0;
320  if( sc_dimension(ordered_sc) == 0 )
321  return make_polynome(1,TCST,1);
322  else
323  {
325  {
326  if (A) my_Polyhedron_Free(&A);
327  if (a) my_Matrix_Free(&a);
328  if (C) my_Polyhedron_Free(&C);
329  RETHROW();
330  }
331  TRY
332  {
333  assert(!SC_UNDEFINED_P(ordered_sc) && (sc_dimension(ordered_sc) != 0));
334  nbrows = ordered_sc->nb_eq + ordered_sc->nb_ineq+1;
335  nbcolumns = ordered_sc->dimension +2;
336  a = Matrix_Alloc(nbrows, nbcolumns);
337  sc_to_matrix(ordered_sc,a);
338 
339  A = Constraints2Polyhedron(a, MAX_NB_RAYS);
340  my_Matrix_Free(&a);
341 
342  C = Universe_Polyhedron(base_dimension(ordered_base));
343 
344  ehrhart = Polyhedron_Enumerate(A, C, MAX_NB_RAYS, variable_names);
345  // Value vals[2]= {0,0};
346  // Value *val = compute_poly(ehrhart,&vals[0]);
347  // printf("%lld\n",*val);
349  my_Polyhedron_Free(&C);
350  } // end TRY
351 
353  return evalue_to_polynome(&ehrhart->EP,ordered_base);
354  }
355 }
#define CATCH(what)
@ any_exception_error
catch all
#define UNCATCH(what)
#define RETHROW()
#define TRY
#define VALUE_ZERO
#define value_pdiv(v1, v2)
#define value_notzero_p(val)
#define value_uminus(val)
unary operators on values
#define value_negz_p(val)
#define value_direct_multiply(v1, v2)
#define value_zero_p(val)
int Value
#define value_addto(ref, val)
#define value_neg_p(val)
int rank_of_variable(Pbase base, Variable var)
this function returns the rank of the variable var in the base 0 encodes TCST, but I do not know why,...
Definition: base.c:497
bdt base
Current expression.
Definition: bdt_read_paf.c:100
#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
void vect_dump(Pvecteur v)
void vect_dump(Pvecteur v): print sparse vector v on stderr.
Definition: io.c:304
static entity rank
#define assert(ex)
Definition: newgen_assert.h:41
Ppolynome make_polynome(float coeff, Variable var, Value expo)
Ppolynome make_polynome(float coeff, Variable var, Value expo) PRIVATE allocates space for,...
Definition: pnome-alloc.c:100
Ppolynome polynome_mult(Ppolynome pp1, Ppolynome pp2)
Ppolynome polynome_mult(Ppolynome pp1, Ppolynome pp2) returns pp1 * pp2.
Definition: pnome-bin.c:287
void polynome_add(Ppolynome *ppp, Ppolynome pp2)
void polynome_add(Ppolynome* ppp, Ppolynome pp2) (*ppp) = (*ppp) + pp2.
Definition: pnome-bin.c:171
#define POLYNOME_NUL
#define POLYNOME_UNDEFINED
static Variable base_nth(Pbase b, size_t i)
Definition: sc_enumerate.c:254
static void contrainte_to_matrix_ligne(Pcontrainte pc, Matrix *mat, int i, Pbase base)
Fonctions de conversion traduisant une Pcontrainte en une ligne de la structure matrix de l'IRISA.
Definition: sc_enumerate.c:91
static Ppolynome evalue_to_polynome(evalue *, Pbase)
Definition: sc_enumerate.c:290
static void sc_to_matrix(Psysteme sc, Matrix *mat)
Passage du systeme lineaire sc a une matrice matrix (structure Irisa) Cette fonction de conversion es...
Definition: sc_enumerate.c:115
#define MAX_NB_RAYS
IRISA/POLYLIB data structures.
Definition: sc_enumerate.c:47
static Ppolynome enode_to_polynome(enode *e, Pbase ordered_base)
Definition: sc_enumerate.c:264
static void my_Polyhedron_Free(Polyhedron *volatile *p)
Definition: sc_enumerate.c:75
static void my_Matrix_Free(Matrix *volatile *m)
Definition: sc_enumerate.c:63
#define VALUE_TO_IRINT(val)
Irisa is based on int.
Definition: sc_enumerate.c:59
Ppolynome sc_enumerate(Psysteme ordered_sc, Pbase ordered_base, const char *variable_names[])
enumerate the systeme sc using base pb pb contains the unknow variables and sc all the constraints or...
Definition: sc_enumerate.c:307
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 ...
Definition: pip__tab.h:25
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
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_val(v)
#define vecteur_var(v)
#define VECTEUR_UNDEFINED
#define vecteur_succ(v)
#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 base_dimension(b)
#define VECTEUR_UNDEFINED_P(v)
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