PPL  1.2
Affine_Space.cc
Go to the documentation of this file.
1 /* Affine_Space class implementation.
2  Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3  Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #include "ppl-config.h"
25 #include "Affine_Space_defs.hh"
26 #include <iostream>
27 
28 namespace PPL = Parma_Polyhedra_Library;
29 
31  dimension_type space_dim = gs.space_dimension();
32  // First find a point or closure point and convert it to a
33  // grid point and add to the (initially empty) set of grid generators.
34  Grid_Generator_System ggs(space_dim);
35  Linear_Expression point_expr;
36  PPL_DIRTY_TEMP_COEFFICIENT(point_divisor);
38  gs_end = gs.end(); g != gs_end; ++g) {
39  if (g->is_ray()) {
40  throw std::invalid_argument("Affine_Space::Affine_Space(gs):\n"
41  "gs contains rays.");
42  }
43  else if (g->is_point() || g->is_closure_point()) {
44  point_expr = Linear_Expression(*g);
45  ggs.insert(grid_point(point_expr, g->divisor()));
46  goto non_empty;
47  }
48  }
49  // No (closure) point was found.
50  Grid(EMPTY).m_swap(gr);
51  return;
52 
53  non_empty:
54  // Add a grid line for each line. If the generator is a (closure)
55  // point, the grid line must have the direction given by a line
56  // that joins the grid point already inserted and the new point.
58  PPL_DIRTY_TEMP_COEFFICIENT(g_divisor);
60  gs_end = gs.end(); g != gs_end; ++g) {
61  if (g->is_point() || g->is_closure_point()) {
62  Linear_Expression e = point_expr;
63  e.linear_combine(g->expression(), g->divisor(), -point_divisor,
64  1, space_dim + 1);
66  ggs.insert(grid_line(e));
67  }
68  }
69  else {
70  ggs.insert(grid_line(Linear_Expression(*g)));
71  }
72  }
73  Grid(ggs).m_swap(gr);
74  PPL_ASSERT(OK());
75 }
76 
77 
80  gr = y.gr;
81  return *this;
82 }
83 
86  return gr.affine_dimension();
87 }
88 
91  return gr.congruences();
92 }
93 
96  return gr.minimized_congruences();
97 }
98 
101  // FIXME: implement by filtering the grid generators.
102  abort();
103 }
104 
107  // FIXME: implement by filtering the grid generators.
108  abort();
109 }
110 
113  return gr.relation_with(cg);
114 }
115 
118  return gr.relation_with(g);
119 }
120 
123  return gr.relation_with(c);
124 }
125 
126 bool
128  return gr.is_empty();
129 }
130 
131 bool
133  return gr.is_universe();
134 }
135 
136 bool
138  return gr.is_bounded();
139 }
140 
141 bool
143  return gr.is_discrete();
144 }
145 
146 bool
148  return true;
149 }
150 
151 bool
153  return gr.contains_integer_point();
154 }
155 
156 bool
158  return gr.constrains(var);
159 }
160 
161 bool
162 PPL::Affine_Space::OK(bool check_not_empty) const {
163  return gr.OK(check_not_empty);
164 }
165 
166 void
168  gr.add_constraints(cs);
169 }
170 
171 void
173  // FIXME: do we want this method?
174  abort();
175 }
176 
177 void
179  // FIXME: do we want this method?
180  abort();
181 }
182 
183 void
185  // FIXME: do we want this method?
186  abort();
187 }
188 
189 void
191  // FIXME: do we want this method?
192  abort();
193 }
194 
195 void
197  gr.refine_with_constraint(c);
198 }
199 
200 void
202  gr.refine_with_constraints(cs);
203 }
204 
205 void
207  gr.unconstrain(var);
208 }
209 
210 void
212  gr.unconstrain(vars);
213 }
214 
215 void
217  gr.intersection_assign(y.gr);
218 }
219 
220 void
222  // FIXME: horrible kludge to filter congruences away.
223  gr.upper_bound_assign(y.gr);
224  Affine_Space a(gr.constraints());
225  m_swap(a);
226 }
227 
228 bool
230  return gr.upper_bound_assign_if_exact(y.gr);
231 }
232 
233 void
235  gr.difference_assign(y.gr);
236 }
237 
238 bool
240  return gr.simplify_using_context_assign(y.gr);
241 }
242 
243 void
245  const Linear_Expression& expr,
246  Coefficient_traits::const_reference
247  denominator) {
248  gr.affine_image(var, expr, denominator);
249 }
250 
251 void
254  const Linear_Expression& expr,
255  Coefficient_traits::const_reference denominator) {
256  gr.affine_preimage(var, expr, denominator);
257 }
258 
259 void
262  const Relation_Symbol relsym,
263  const Linear_Expression& expr,
264  Coefficient_traits::const_reference denominator) {
265  gr.generalized_affine_image(var, relsym, expr, denominator);
266 }
267 
268 void
271  const Relation_Symbol relsym,
272  const Linear_Expression& expr,
273  Coefficient_traits::const_reference denominator) {
274  gr.generalized_affine_preimage(var, relsym, expr, denominator);
275 }
276 
277 void
280  const Relation_Symbol relsym,
281  const Linear_Expression& rhs) {
282  gr.generalized_affine_image(lhs, relsym, rhs);
283 }
284 
285 void
288  const Relation_Symbol relsym,
289  const Linear_Expression& rhs) {
290  gr.generalized_affine_preimage(lhs, relsym, rhs);
291 }
292 
293 void
296  const Linear_Expression& lb_expr,
297  const Linear_Expression& ub_expr,
298  Coefficient_traits::const_reference denominator) {
299  gr.bounded_affine_image(var, lb_expr, ub_expr, denominator);
300 }
301 
302 
303 void
306  const Linear_Expression& lb_expr,
307  const Linear_Expression& ub_expr,
308  Coefficient_traits::const_reference denominator) {
309  gr.bounded_affine_preimage(var, lb_expr, ub_expr, denominator);
310 }
311 
312 void
314  gr.time_elapse_assign(y.gr);
315 }
316 
318 bool
320  return x.gr == y.gr;
321 }
322 
323 bool
325  return gr.contains(y.gr);
326 }
327 
328 bool
330  return gr.is_disjoint_from(y.gr);
331 }
332 
333 void
334 PPL::Affine_Space::ascii_dump(std::ostream& s) const {
335  gr.ascii_dump(s);
336 }
337 
339 
340 bool
341 PPL::Affine_Space::ascii_load(std::istream& s) {
342  return gr.ascii_load(s);
343 }
344 
347  return gr.external_memory_in_bytes();
348 }
349 
350 void
352  gr.add_space_dimensions_and_embed(m);
353 }
354 
355 void
357  gr.add_space_dimensions_and_project(m);
358 }
359 
360 void
362  gr.concatenate_assign(y.gr);
363 }
364 
365 void
367  gr.remove_space_dimensions(vars);
368 }
369 
370 void
372  new_dimension) {
373  gr.remove_higher_space_dimensions(new_dimension);
374 }
375 
376 void
378  gr.expand_space_dimension(var, m);
379 }
380 
381 void
383  Variable var) {
384  gr.fold_space_dimensions(to_be_folded, var);
385 }
386 
387 void
389  Affine_Space& x = *this;
390 
391  // Dimension-compatibility check.
392  if (x.space_dimension() != y.space_dimension())
393  throw_dimension_incompatible("widening_assign(y)", "y", y);
394 
395  // Assume `y' is contained in or equal to `x'.
396  PPL_EXPECT_HEAVY(copy_contains(x, y));
397 }
398 
399 void
401  const Constraint_System&,
402  unsigned*) {
403  Affine_Space& x = *this;
404 
405  // Dimension-compatibility check.
406  if (x.space_dimension() != y.space_dimension()) {
407  throw_dimension_incompatible("widening_assign(y)", "y", y);
408  }
409 
410  // Assume `y' is contained in or equal to `x'.
411  PPL_EXPECT_HEAVY(copy_contains(x, y));
412 }
413 
415 std::ostream&
416 PPL::IO_Operators::operator<<(std::ostream& s, const Affine_Space& gr) {
417  s << gr;
418  return s;
419 }
420 
421 void
424  const char* other_name,
425  dimension_type other_dim) const {
426  std::ostringstream s;
427  s << "PPL::Affine_Space::" << method << ":\n"
428  << "this->space_dimension() == " << space_dimension() << ", "
429  << other_name << ".space_dimension() == " << other_dim << ".";
430  throw std::invalid_argument(s.str());
431 }
432 
433 void
436  const char* as_name,
437  const Affine_Space& as) const {
438  throw_dimension_incompatible(method, as_name, as.space_dimension());
439 }
void unconstrain(Variable var)
Computes the cylindrification of *this with respect to space dimension var, assigning the result to *...
The empty element, i.e., the empty set.
void add_constraints(const Constraint_System &cs)
Adds to *this congruences equivalent to the constraints in cs.
void add_recycled_generators(Generator_System &gs)
Adds the generators in gs to the system of generators of this.
void generalized_affine_preimage(Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the preimage of *this with respect to the generalized affine relation ...
A linear equality or inequality.
bool OK(bool check_not_empty=false) const
Checks if all the invariants are satisfied.
Generator_System minimized_generators() const
Returns a minimized system of generators defining *this.
bool upper_bound_assign_if_exact(const Affine_Space &y)
If the upper bound of *this and y is exact it is assigned to this and true is returned, otherwise false is returned.
void refine_with_constraint(const Constraint &c)
Uses a copy of the constraint c to refine *this.
size_t dimension_type
An unsigned integral type for representing space dimensions.
void add_recycled_congruences(Congruence_System &cgs)
Adds the congruences in cgs to *this.
An std::set of variables' indexes.
A line, ray, point or closure point.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
bool is_discrete() const
Returns true if and only if *this is discrete.
std::ostream & operator<<(std::ostream &s, const Ask_Tell< D > &x)
bool contains(const Affine_Space &y) const
Returns true if and only if *this contains y.
The standard C++ namespace.
bool is_topologically_closed() const
Returns true if and only if *this is a topologically closed subset of the vector space.
bool is_universe() const
Returns true if and only if *this is a universe affine space.
bool is_bounded() const
Returns true if and only if *this is bounded.
Poly_Con_Relation relation_with(const Congruence &cg) const
Returns the relations holding between *this and cg.
const Congruence_System & minimized_congruences() const
Returns the system of equality congruences satisfied by *this, with no redundant congruences and havi...
Definition: Affine_Space.cc:95
void affine_preimage(Variable var, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the affine preimage of *this under the function mapping variable var to the affine e...
void difference_assign(const Affine_Space &y)
Assigns to *this the poly-difference of *this and y.
A dimension of the vector space.
void concatenate_assign(const Affine_Space &y)
Assigns to *this the concatenation of *this and y, taken in this order.
void throw_dimension_incompatible(const char *method, const char *other_name, dimension_type other_dim) const
void intersection_assign(const Affine_Space &y)
Assigns to *this the intersection of *this and y.
Relation_Symbol
Relation symbols.
bool is_empty() const
Returns true if and only if *this is an empty affine space.
void fold_space_dimensions(const Variables_Set &to_be_folded, Variable var)
Folds the space dimensions in to_be_folded into var.
bool contains_integer_point() const
Returns true if and only if *this contains at least one integer point.
Grid gr
The rational grid implementing *this.
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type ascii_load(std::istream &s, T &t)
void bounded_affine_preimage(Variable var, const Linear_Expression &lb_expr, const Linear_Expression &ub_expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the preimage of *this with respect to the bounded affine relation ...
void add_space_dimensions_and_embed(dimension_type m)
Adds m new space dimensions and embeds the old affine space in the new vector space.
bool all_homogeneous_terms_are_zero() const
Returns true if and only if all the homogeneous terms of *this are .
bool simplify_using_context_assign(const Affine_Space &y)
Assigns to *this a meet-preserving simplification of *this with respect to y. If false is returned...
memory_size_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
void upper_bound_assign(const Affine_Space &y)
Assigns to *this the least upper bound of *this and y.
void generalized_affine_image(Variable var, Relation_Symbol relsym, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the image of *this with respect to the generalized affine relation ...
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
dimension_type affine_dimension() const
Returns , if *this is empty; otherwise, returns affine dimension of *this.
Definition: Affine_Space.cc:85
Affine_Space(dimension_type num_dimensions=0, Degenerate_Element kind=UNIVERSE)
Builds an affine space having the specified properties.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void limited_extrapolation_assign(const Affine_Space &y, const Constraint_System &cs, unsigned *tp=NULL)
Does nothing, as the domain of affine spaces has finite height.
#define PPL_OUTPUT_DEFINITIONS(class_name)
The entire library is confined to this namespace.
Definition: version.hh:61
bool is_disjoint_from(const Affine_Space &y) const
Returns true if and only if *this and y are disjoint.
Affine_Space & operator=(const Affine_Space &y)
The assignment operator. (*this and y can be dimension-incompatible.)
Definition: Affine_Space.cc:79
bool constrains(Variable var) const
Returns true if and only if var is constrained in *this.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
const_iterator end() const
Returns the past-the-end const_iterator.
const_iterator begin() const
Returns the const_iterator pointing to the first generator, if *this is not empty; otherwise...
void widening_assign(const Affine_Space &y, unsigned *tp=NULL)
Does nothing, as the domain of affine spaces has finite height.
void bounded_affine_image(Variable var, const Linear_Expression &lb_expr, const Linear_Expression &ub_expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the image of *this with respect to the bounded affine relation . ...
void time_elapse_assign(const Affine_Space &y)
Assigns to *this the result of computing the time-elapse between *this and y.
void remove_higher_space_dimensions(dimension_type new_dimension)
Removes the higher dimensions of the vector space so that the resulting space will have dimension new...
void add_generator(const Generator &g)
Adds a copy of affine space generator g to the system of generators of *this.
void remove_space_dimensions(const Variables_Set &vars)
Removes all the specified dimensions from the vector space.
bool operator==(const Box< ITV > &x, const Box< ITV > &y)
size_t memory_size_type
An unsigned integral type for representing memory size in bytes.
void affine_image(Variable var, const Linear_Expression &expr, Coefficient_traits::const_reference denominator=Coefficient_one())
Assigns to *this the affine image of *this under the function mapping variable var to the affine expr...
void refine_with_constraints(const Constraint_System &cs)
Uses a copy of the constraints in cs to refine *this.
void expand_space_dimension(Variable var, dimension_type m)
Creates m copies of the space dimension corresponding to var.
Coefficient c
Definition: PIP_Tree.cc:64
void linear_combine(const Linear_Expression &y, Variable v)
void add_space_dimensions_and_project(dimension_type m)
Adds m new space dimensions to the affine space and does not embed it in the new vector space...
void add_generators(const Generator_System &gs)
Adds a copy of the generators in gs to the system of generators of *this.
void m_swap(Grid &y)
Swaps *this with grid y. (*this and y can be dimension-incompatible.)
Generator_System generators() const
Returns a system of generators defining *this.
const Congruence_System & congruences() const
Returns the system of equality congruences satisfied by *this.
Definition: Affine_Space.cc:90
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
The relation between a polyhedron and a generator.
The relation between a polyhedron and a constraint.