PIPS
convex_hull.c
Go to the documentation of this file.
1 /*
2 
3  $Id: convex_hull.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  * transformer package - convex hull computation
29  *
30  * Francois Irigoin, 21 April 1990
31  */
32 
33 #include <stdio.h>
34 
35 #include "genC.h"
36 #include "linear.h"
37 
38 #include "ri.h"
39 #include "ri-util.h"
40 
41 #include "misc.h"
42 
43 #include "boolean.h"
44 #include "vecteur.h"
45 #include "contrainte.h"
46 #include "sc.h"
47 #include "ray_dte.h"
48 #include "sommet.h"
49 #include "sg.h"
50 #include "polyedre.h"
51 
52 /* temporarily, for ifdebug */
53 #include "transformer.h"
54 
55 /* This function used to have side effects on arguments t1 and t2 */
57 (transformer t1, transformer t2, Psysteme (*method)(Psysteme, Psysteme))
58 {
60 
61 
62  pips_debug(6,"begin\n");
63  ifdebug(6) {
64  pips_debug(6, "convex hull t1 (%p):\n", t1);
65  dump_transformer(t1) ;
66  }
67  ifdebug(6) {
68  pips_debug(6, "convex hull t2 (%p):\n", t2);
69  dump_transformer(t2) ;
70  }
71 
72  /* If one of the transformers is empty, you do not want to union
73  * the arguments
74  */
75  if(transformer_empty_p(t1)) {
76  t = transformer_dup(t2);
77  }
78  else if(transformer_empty_p(t2)) {
79  t = transformer_dup(t1);
80  }
81  else {
84  Psysteme r;
85  Pbase b1;
86  Pbase b2;
87  Pbase b1_min = sc_to_minimal_basis(r1);
88  Pbase b2_min = sc_to_minimal_basis(r2);
89  Pbase b;
90  /* Pbase b_min; */ /* Could be used if useless dimensions are not
91  detected at lower level(s) */
92  int eq_count1 = 0;
93  int eq_count2 = 0;
94  int ineq_count1 = 0;
95  int ineq_count2 = 0;
96 
101 
102  /* add implicit equality constraints in r1 and r2 */
103  /* These equalities should only be added if the variable explicitly
104  appears in at least one constraint in the other constraint
105  system. Mathematical proof?. */
108  entity a_new = entity_to_new_value(a);
109  if(base_contains_variable_p(b1_min, (Variable) a_new)) {
110  entity a_old = entity_to_old_value(a);
111  Pvecteur eq = vect_new((Variable) a_new, -1);
112  vect_chg_coeff(&eq, (Variable) a_old, 1);
114  eq_count2++;
116  /* add implicit constraints for bool variables */
117  Pvecteur ineq1 = vect_new((Variable) a_new, VALUE_ONE);
118  Pvecteur ineq2 = vect_new((Variable) a_new, VALUE_MONE);
119 
120  vect_add_elem(&ineq1, TCST, VALUE_MONE);
121  r2 = sc_inequality_add(r2, contrainte_make(ineq1));
122  r2 = sc_inequality_add(r2, contrainte_make(ineq2));
123  ineq_count2++;
124  }
125  }
126  }
127  }
128  base_rm(b1_min);
131  entity a_new = entity_to_new_value(a);
132  if(base_contains_variable_p(b2_min, (Variable) a_new)) {
133  entity a_old = entity_to_old_value(a);
134  Pvecteur eq = vect_new((Variable) a_new, -1);
135  vect_chg_coeff(&eq, (Variable) a_old, 1);
137  eq_count1++;
139  /* add implicit constraints for bool variables */
140  Pvecteur ineq1 = vect_new((Variable) a_new, VALUE_ONE);
141  Pvecteur ineq2 = vect_new((Variable) a_new, VALUE_MONE);
142 
143  vect_add_elem(&ineq1, TCST, VALUE_MONE);
144  r1 = sc_inequality_add(r1, contrainte_make(ineq1));
145  r1 = sc_inequality_add(r1, contrainte_make(ineq2));
146  ineq_count1++;
147  }
148  }
149  }
150  }
151  base_rm(b2_min);
152 
153  pips_debug(6,"Number of equations added to t1: %d, to t2: %d\n"
154  "Number of inequalities added to t1: %d, to t2: %d\n",
155  eq_count1, eq_count2, ineq_count1, ineq_count2);
156 
157  /* update bases using their "union"; convex hull has to be computed
158  relatively to ONE space */
159  b1 = r1->base;
160  b2 = r2->base;
161  b = base_union(b1, b2);
162  base_rm(b1);
163  base_rm(b2);
164  /* b is duplicated because it may be later freed by (*method)()
165  * FI->CA: To be changed when (*method)() is cleaned up
166  */
167  sc_base(r1) = base_dup(b);
168  /* please, no sharing between Psysteme's */
169  sc_base(r2) = base_dup(b);
170  sc_dimension(r1) = base_dimension(b);
171  sc_dimension(r2) = sc_dimension(r1);
172 
173  /* meet operation (with no side-effect on arguments r1 and r2) */
174  r = (* method)(r1, r2);
175 
176  /* There is no way to distinguish between SC_RN and SC_EMPY since
177  both are defined as NULL */
178  if(SC_EMPTY_P(r)) {
179  /* FI: this could be eliminated if SC_EMPTY was really usable; 27/5/93 */
180  /* and replaced by a SC_UNDEFINED_P() and pips_error() */
181  r = sc_empty(BASE_NULLE);
182  }
183  else {
184  base_rm(b);
185  b = BASE_NULLE;
186  }
187 
188  sc_rm(r1);
189  sc_rm(r2);
190 
191  if(sc_empty_p(r)) {
192  /* To eliminate the arguments in case r is really empty */
193  t = empty_transformer(t);
194  }
195  else
197 
198  }
199 
200  ifdebug(6) {
201  pips_debug(6, "convex hull, t (%p):\n", t);
202  dump_transformer(t) ;
203  }
204 
205  pips_debug(6, "end\n");
206 
207  return t;
208 }
209 
210 /* transformer transformer_convex_hull(t1, t2): compute convex hull for t1
211  * and t2; t1 and t2 are slightly modified to give them the same basis; else
212  * convex hull means nothing; some of the work is duplicated in sc_enveloppe;
213  * however their "relation" fields are preserved; the whole thing is pretty
214  * badly designed; shame on Francois! FI, 24 August 1990
215  */
217 {
218  /* return transformer_convex_hulls(t1, t2, sc_enveloppe); */
219  /* return transformer_convex_hulls(t1, t2, sc_enveloppe_chernikova); */
220  /* return transformer_convex_hulls(t1, t2, sc_common_projection_convex_hull);
221  */
222 /* t1 = transformer_normalize(t1, 4); */
223 /* t2 = transformer_normalize(t2, 4); */
224  t1 = transformer_normalize(t1, 2);
225  t2 = transformer_normalize(t2, 2);
227 }
228 
229 /* I removed this because I do not want to port the polyedre library
230  * to use "Value". If you want this function, do the port! FC 07/96
231  */
232 /*
233 transformer transformer_fast_convex_hull(t1, t2)
234 transformer t1;
235 transformer t2;
236 {
237  return transformer_convex_hulls(t1, t2, sc_fast_convex_hull);
238 }
239 */
240 
241 /*
242 transformer transformer_chernikova_convex_hull(t1, t2)
243 transformer t1;
244 transformer t2;
245 {
246  return transformer_convex_hulls(t1, t2, sc_enveloppe_chernikova);
247 }
248 */
cons * arguments_union(cons *a1, cons *a2)
cons * arguments_union(cons * a1, cons * a2): returns a = union(a1, a2) where a1 and a2 are lists of ...
Definition: arguments.c:116
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
#define VALUE_MONE
#define VALUE_ONE
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
Pbase base_union(Pbase b1, Pbase b2)
Pbase base_union(Pbase b1, Pbase b2): compute a new basis containing all elements of b1 and all eleme...
Definition: base.c:428
transformer transformer_dup(transformer t_in)
transformer package - basic routines
Definition: basic.c:49
transformer empty_transformer(transformer t)
Do not allocate an empty transformer, but transform an allocated transformer into an empty_transforme...
Definition: basic.c:144
transformer transformer_identity()
Allocate an identity transformer.
Definition: basic.c:110
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
#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
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define dump_transformer(t)
Definition: print.c:355
Psysteme cute_convex_union(Psysteme s1, Psysteme s2)
debug messages before calling the version in polyedre.
Definition: convex_hull.c:41
#define transformer_undefined
Definition: ri.h:2847
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define type_variable(x)
Definition: ri.h:2949
#define transformer_relation(x)
Definition: ri.h:2873
#define transformer_arguments(x)
Definition: ri.h:2871
#define entity_type(x)
Definition: ri.h:2792
#define predicate_system(x)
Definition: ri.h:2069
#define variable_basic(x)
Definition: ri.h:3120
#define basic_logical_p(x)
Definition: ri.h:620
Psysteme sc_empty(Pbase b)
Psysteme sc_empty(Pbase b): build a Psysteme with one unfeasible constraint to define the empty subsp...
Definition: sc_alloc.c:319
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
Pbase sc_to_minimal_basis(Psysteme ps)
creation d'une base contenant toutes les variables apparaissant avec des coefficients non-nuls dans l...
Definition: sc_alloc.c:76
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
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
Value b2
Definition: sc_gram.c:105
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
Psysteme sc_inequality_add(Psysteme sc, Pcontrainte c)
Definition: sc_insert_eq.c:108
Psysteme sc_equation_add(Psysteme sc, Pcontrainte c)
The basis of the constraint system is updated.
Definition: sc_insert_eq.c:101
#define ifdebug(n)
Definition: sg.c:47
Pbase base
Definition: sc-local.h:75
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
static transformer transformer_convex_hulls(transformer t1, transformer t2, Psysteme(*method)(Psysteme, Psysteme))
temporarily, for ifdebug
Definition: convex_hull.c:57
transformer transformer_convex_hull(transformer t1, transformer t2)
transformer transformer_convex_hull(t1, t2): compute convex hull for t1 and t2; t1 and t2 are slightl...
Definition: convex_hull.c:216
transformer transformer_normalize(transformer t, int level)
Eliminate (some) rational or integer redundancy.
Definition: transformer.c:932
bool transformer_empty_p(transformer t)
If true is returned, the transformer certainly is empty.
Definition: transformer.c:2455
entity entity_to_new_value(entity)
Definition: value.c:859
entity entity_to_old_value(entity)
Definition: value.c:869
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#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 base_dimension(b)
#define BASE_NULLE
MACROS SUR LES BASES.
Pbase base_dup(Pbase b)
Pbase base_dup(Pbase b) Note: this function changes the value of the pointer.
Definition: alloc.c:268
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_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
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