PPL  1.2
Grid_Generator_System.cc
Go to the documentation of this file.
1 /* Grid_Generator_System class implementation (non-inline functions).
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"
27 #include "Scalar_Products_defs.hh"
29 #include "Variables_Set_defs.hh"
30 #include "assertions.hh"
31 #include <iostream>
32 
33 namespace PPL = Parma_Polyhedra_Library;
34 
35 void
37  const dimension_type gs_num_rows = gs.num_rows();
38 
39  if (space_dimension() < gs.space_dimension()) {
41  }
42  else {
44  }
45 
46  for (dimension_type i = 0; i < gs_num_rows; ++i) {
47  sys.insert(gs.sys.rows[i], Recycle_Input());
48  }
49 
50  gs.clear();
51 
53 }
54 
55 void
57  Grid_Generator tmp(g, representation());
58  insert(tmp, Recycle_Input());
59 }
60 
61 void
64  // There is no need to add the origin as a parameter,
65  // as it will be immediately flagged as redundant.
66  // However, we still have to adjust space dimension.
67  if (space_dimension() < g.space_dimension()) {
68  set_space_dimension(g.space_dimension());
69  }
70  return;
71  }
72 
73  sys.insert(g, Recycle_Input());
74 
75  PPL_ASSERT(OK());
76 }
77 
78 void
81  const Linear_Expression& expr,
82  Coefficient_traits::const_reference denominator) {
83  // This is mostly a copy of Generator_System::affine_image.
84 
85  Grid_Generator_System& x = *this;
86  PPL_ASSERT(v.space_dimension() <= x.sys.space_dimension());
87  PPL_ASSERT(expr.space_dimension() <= x.sys.space_dimension());
88  PPL_ASSERT(denominator > 0);
89 
90  const dimension_type num_rows = x.num_rows();
91 
92  // Compute the numerator of the affine transformation and assign it
93  // to the column of `*this' indexed by `v'.
94  PPL_DIRTY_TEMP_COEFFICIENT(numerator);
95 
96  for (dimension_type i = num_rows; i-- > 0; ) {
97  Grid_Generator& row = sys.rows[i];
98  Scalar_Products::assign(numerator, expr, row.expr);
99  if (denominator != 1) {
100  // Since we want integer elements in the matrix,
101  // we multiply by `denominator' all the columns of `*this'
102  // having an index different from `v'.
103  // Note that this operation also modifies the coefficient of v, but
104  // it will be overwritten by the set_coefficient() below.
105  row.expr *= denominator;
106  }
107  row.expr.set_coefficient(v, numerator);
108  // Check that the row is stll OK after fiddling with its internal data.
109  PPL_ASSERT(row.OK());
110  }
111 
112  PPL_ASSERT(sys.OK());
113 
114  // If the mapping is not invertible we may have transformed valid
115  // lines and rays into the origin of the space.
116  const bool not_invertible = (v.space_dimension() >= expr.space_dimension()
117  || expr.coefficient(v) == 0);
118  if (not_invertible) {
120  }
121 }
122 
124 
125 void
126 PPL::Grid_Generator_System::ascii_dump(std::ostream& s) const {
127  sys.ascii_dump(s);
128 }
129 
130 bool
132  if (!sys.ascii_load(s)) {
133  return false;
134  }
135 
136  PPL_ASSERT(OK());
137  return true;
138 }
139 
142 
143 void
145  PPL_ASSERT(zero_dim_univ_p == 0);
146  zero_dim_univ_p
148 }
149 
150 void
152  PPL_ASSERT(zero_dim_univ_p != 0);
153  delete zero_dim_univ_p;
154  zero_dim_univ_p = 0;
155 }
156 
157 bool
159  if (sys.topology() == NOT_NECESSARILY_CLOSED) {
160 #ifndef NDEBUG
161  std::cerr << "Grid_Generator_System is NOT_NECESSARILY_CLOSED"
162  << std::endl;
163 #endif
164  return false;
165  }
166 
167  if (sys.is_sorted()) {
168 #ifndef NDEBUG
169  std::cerr << "Grid_Generator_System is marked as sorted."
170  << std::endl;
171 #endif
172  return false;
173  }
174 
175  return sys.OK();
176 }
177 
179 std::ostream&
181  const Grid_Generator_System& gs) {
183  const Grid_Generator_System::const_iterator gs_end = gs.end();
184  if (i == gs_end) {
185  return s << "false";
186  }
187  while (true) {
188  s << *i;
189  ++i;
190  if (i == gs_end) {
191  return s;
192  }
193  s << ", ";
194  }
195 }
196 
197 void
200  dimension_type col = sys.space_dimension();
201 
202  set_space_dimension(space_dimension() + dims);
203 
204  // Add the new rows and set their diagonal element.
205  for (dimension_type i = 0; i < dims; ++i) {
206  Grid_Generator tmp(space_dimension(), Grid_Generator::LINE_OR_EQUALITY,
207  NECESSARILY_CLOSED, representation());
208  tmp.expr += Variable(col);
209  PPL_ASSERT(tmp.OK());
210  ++col;
211  sys.insert(tmp, Recycle_Input());
212  }
213 }
214 
215 void
218  sys.remove_space_dimensions(vars);
219 }
220 
221 void
224  sys.shift_space_dimensions(v, n);
225 }
226 
227 void
229 ::set_space_dimension(const dimension_type new_dimension) {
230  sys.set_space_dimension(new_dimension);
231  PPL_ASSERT(OK());
232 }
233 
234 void
236  // The origin of the vector space cannot be a valid line/parameter.
237  // NOTE: the following swaps will mix grid generators without even trying
238  // to preserve sortedness: as a matter of fact, it will almost always
239  // be the case that the input generator system is NOT sorted.
240 
241  // Note that the num_rows() value is *not* constant because remove_row()
242  // decreases it.
243  for (dimension_type i = 0; i < num_rows(); ) {
244  const Grid_Generator& g = (*this)[i];
246  sys.remove_row(i, false);
247  }
248  else {
249  ++i;
250  }
251  }
252 }
253 
254 bool
256  const Grid_Generator_System& ggs = *this;
257  for (dimension_type i = num_rows(); i-- > 0; ) {
258  if (!ggs[i].is_line_or_parameter()) {
259  return true;
260  }
261  }
262  return false;
263 }
264 
267  // We are sure that this method is applied only to a matrix
268  // that does not contain pending rows.
269  PPL_ASSERT(sys.num_pending_rows() == 0);
270  const Grid_Generator_System& ggs = *this;
271  dimension_type n = 0;
272  // If the Linear_System happens to be sorted, take advantage of the fact
273  // that lines are at the top of the system.
274  if (sys.is_sorted()) {
275  const dimension_type nrows = num_rows();
276  for (dimension_type i = 0; i < nrows && ggs[i].is_line(); ++i) {
277  ++n;
278  }
279  }
280  else {
281  for (dimension_type i = num_rows(); i-- > 0 ; ) {
282  if (ggs[i].is_line()) {
283  ++n;
284  }
285  }
286  }
287  return n;
288 }
289 
292  // We are sure that this method is applied only to a matrix
293  // that does not contain pending rows.
294  PPL_ASSERT(sys.num_pending_rows() == 0);
295  const Grid_Generator_System& ggs = *this;
296  dimension_type n = 0;
297  // If the Linear_System happens to be sorted, take advantage of the fact
298  // that rays and points are at the bottom of the system and
299  // rays have the inhomogeneous term equal to zero.
300  if (sys.is_sorted()) {
301  for (dimension_type i = num_rows();
302  i != 0 && ggs[--i].is_parameter_or_point(); ) {
303  if (ggs[i].is_line_or_parameter()) {
304  ++n;
305  }
306  }
307  }
308  else {
309  for (dimension_type i = num_rows(); i-- > 0 ; ) {
310  if (ggs[i].is_parameter()) {
311  ++n;
312  }
313  }
314  }
315  return n;
316 }
static const Grid_Generator_System * zero_dim_univ_p
Holds (between class initialization and finalization) a pointer to the singleton system containing on...
bool ascii_load(std::istream &s)
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this ...
size_t dimension_type
An unsigned integral type for representing space dimensions.
An std::set of variables' indexes.
const_iterator end() const
Returns the past-the-end const_iterator.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
Enable_If< Is_Native_Or_Checked< T >::value, void >::type ascii_dump(std::ostream &s, const T &t)
void clear()
Removes all the generators from the generator system and sets its space dimension to 0...
std::ostream & operator<<(std::ostream &s, const Ask_Tell< D > &x)
bool has_points() const
Returns true if and only if *this contains one or more points.
static const Grid_Generator & zero_dim_point()
Returns the origin of the zero-dimensional space .
dimension_type num_lines() const
Returns the number of lines in the system.
The standard C++ namespace.
const_iterator begin() const
Returns the const_iterator pointing to the first generator, if this is not empty; otherwise...
void add_universe_rows_and_columns(dimension_type dims)
Adds dims rows and dims columns of zeroes to the matrix, initializing the added rows as in the univer...
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void set_coefficient(Variable v, Coefficient_traits::const_reference n)
Sets the coefficient of v in *this to n.
void set_space_dimension(dimension_type space_dim)
Resizes the system to the specified space dimension.
Coefficient_traits::const_reference coefficient(Variable v) const
Returns the coefficient of v in *this.
A dimension of the vector space.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
bool OK() const
Checks if all the invariants are satisfied.
bool is_line_or_parameter() const
Returns true if and only if *this is a line or a parameter.
void affine_image(Variable v, const Linear_Expression &expr, Coefficient_traits::const_reference denominator)
Assigns to a given variable an affine expression.
void unset_pending_rows()
Sets the index to indicate that the system has no pending rows.
void remove_space_dimensions(const Variables_Set &vars)
Removes all the specified dimensions from the generator system.
#define PPL_OUTPUT_DEFINITIONS(class_name)
void remove_invalid_lines_and_parameters()
Removes all the invalid lines and parameters.
The entire library is confined to this namespace.
Definition: version.hh:61
bool all_homogeneous_terms_are_zero() const
Returns true if and only if all the homogeneous terms of *this are .
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
void shift_space_dimensions(Variable v, dimension_type n)
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
static void assign(Coefficient &z, const Linear_Expression &x, const Linear_Expression &y)
Computes the scalar product of x and y and assigns it to z.
static void initialize()
Initializes the class.
dimension_type num_parameters() const
Returns the number of parameters in the system.
bool is_parameter() const
Returns true if and only if *this is a parameter.
bool OK() const
Checks if all the invariants are satisfied.
void insert(const Grid_Generator &g)
Inserts into *this a copy of the generator g, increasing the number of space dimensions if needed...
A grid line, parameter or grid point.