PPL  1.2
Grid_simplify.cc
Go to the documentation of this file.
1 /* Grid class implementation: simplify().
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 "assertions.hh"
26 #include "Grid_defs.hh"
27 
28 namespace Parma_Polyhedra_Library {
29 
30 void
32  dimension_type column) {
33  Coefficient_traits::const_reference pivot_column = pivot.expr.get(column);
34  Coefficient_traits::const_reference row_column = row.expr.get(column);
35  PPL_ASSERT(pivot_column != 0);
36  PPL_ASSERT(row_column != 0);
37 
38  PPL_DIRTY_TEMP_COEFFICIENT(reduced_row_col);
39  // Use reduced_row_col temporarily to hold the gcd.
40  gcd_assign(reduced_row_col, pivot_column, row_column);
41  // Store the reduced ratio between pivot[column] and row[column].
42  PPL_DIRTY_TEMP_COEFFICIENT(reduced_pivot_col);
43  exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col);
44  exact_div_assign(reduced_row_col, row_column, reduced_row_col);
45  // Multiply row, then subtract from it a multiple of pivot such that
46  // the result in row[column] is zero.
47  neg_assign(reduced_row_col);
48  // pivot.space_dimension() is the index for the parameter divisor so we
49  // start reducing the line at index pivot.space_dimension() - 2.
50  row.expr.linear_combine(pivot.expr,
51  reduced_pivot_col, reduced_row_col,
52  column, pivot.expr.space_dimension());
53  PPL_ASSERT(row.OK());
54  PPL_ASSERT(row.expr.get(column) == 0);
55 }
56 
57 void
59  const Congruence& pivot,
60  const dimension_type column) {
61  // Assume two equalities.
62  PPL_ASSERT(row.modulus() == 0 && pivot.modulus() == 0);
63 
64  Coefficient_traits::const_reference pivot_column = pivot.expr.get(column);
65  Coefficient_traits::const_reference row_column = row.expr.get(column);
66  PPL_ASSERT(pivot_column != 0);
67  PPL_ASSERT(row_column != 0);
68 
69  PPL_DIRTY_TEMP_COEFFICIENT(reduced_row_col);
70  // Use reduced_row_col temporarily to hold the gcd.
71  gcd_assign(reduced_row_col, pivot_column, row_column);
72  // Store the reduced ratio between pivot[column] and row[column].
73  PPL_DIRTY_TEMP_COEFFICIENT(reduced_pivot_col);
74  exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col);
75  exact_div_assign(reduced_row_col, row_column, reduced_row_col);
76  // Multiply row, then subtract from it a multiple of pivot such that
77  // the result in row[column] is zero.
78  neg_assign(reduced_row_col);
79  row.expr.linear_combine(pivot.expr,
80  reduced_pivot_col, reduced_row_col,
81  0, column + 1);
82  PPL_ASSERT(row.OK());
83  PPL_ASSERT(row.expr.get(column) == 0);
84 }
85 
86 template <typename R>
87 void
88 Grid::reduce_pc_with_pc(R& row, R& pivot,
89  const dimension_type column,
90  const dimension_type start,
91  const dimension_type end) {
92  PPL_ASSERT(start <= end);
93  PPL_ASSERT(start <= column);
94  PPL_ASSERT(column < end);
95 
96  Linear_Expression& row_e = row.expr;
97  Linear_Expression& pivot_e = pivot.expr;
98 
99  Coefficient_traits::const_reference pivot_column = pivot_e.get(column);
100  Coefficient_traits::const_reference row_column = row_e.get(column);
101  PPL_ASSERT(pivot_column != 0);
102  PPL_ASSERT(row_column != 0);
103 
106  PPL_DIRTY_TEMP_COEFFICIENT(reduced_row_col);
108  gcdext_assign(gcd, s, t, pivot_column, row_column);
109  PPL_ASSERT(pivot_e.get(column) * s + row_e.get(column) * t == gcd);
110 
111  // Store the reduced ratio between pivot[column] and row[column].
112  PPL_DIRTY_TEMP_COEFFICIENT(reduced_pivot_col);
113  exact_div_assign(reduced_pivot_col, pivot_column, gcd);
114  exact_div_assign(reduced_row_col, row_column, gcd);
115 
116  // Multiply row, then subtract from it a multiple of pivot such that
117  // the result in row[column] is zero. Afterward, multiply pivot,
118  // then add to it a (possibly negative) multiple of row such that
119  // the result in pivot[column] is the smallest possible positive
120  // integer.
121  const Linear_Expression old_pivot_e = pivot_e;
122  pivot_e.linear_combine_lax(row_e, s, t, start, end);
123  PPL_ASSERT(pivot_e.get(column) == gcd);
124  row_e.linear_combine(old_pivot_e, reduced_pivot_col, -reduced_row_col, start, end);
125  PPL_ASSERT(row_e.get(column) == 0);
126 }
127 
128 void
130  const Grid_Generator& pivot,
131  const dimension_type column,
133  const dimension_type total_num_columns) {
134  // Very similar to reduce_congruence_with_equality below. Any
135  // change here may be needed there too.
136 
137  Coefficient_traits::const_reference pivot_column = pivot.expr.get(column);
138  Coefficient_traits::const_reference row_column = row.expr.get(column);
139  PPL_ASSERT(pivot_column != 0);
140  PPL_ASSERT(row_column != 0);
141 
142  // Subtract one to allow for the parameter divisor column
143  const dimension_type num_columns = total_num_columns - 1;
144 
145  // If the elements at column in row and pivot are the same, then
146  // just subtract pivot from row.
147  if (row_column == pivot_column) {
148  row.expr.linear_combine(pivot.expr, 1, -1, 0, num_columns);
149  return;
150  }
151 
152  PPL_DIRTY_TEMP_COEFFICIENT(reduced_row_col);
153  // Use reduced_row_col temporarily to hold the gcd.
154  gcd_assign(reduced_row_col, pivot_column, row_column);
155  // Store the reduced ratio between pivot[column] and row[column].
156  PPL_DIRTY_TEMP_COEFFICIENT(reduced_pivot_col);
157  exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col);
158  exact_div_assign(reduced_row_col, row_column, reduced_row_col);
159 
160 
161  // Since we are reducing the system to "strong minimal form",
162  // ensure that the multiplier is positive, so that the preceding
163  // diagonals (including the divisor) remain positive. It's safe to
164  // swap the signs as row[column] will still come out 0.
165  if (reduced_pivot_col < 0) {
166  neg_assign(reduced_pivot_col);
167  neg_assign(reduced_row_col);
168  }
169 
170  // Multiply row such that a multiple of pivot can be subtracted from
171  // it below to render row[column] zero. This requires multiplying
172  // all other parameters to match.
173  for (dimension_type index = rows.size(); index-- > 0; ) {
174  Grid_Generator& gen = rows[index];
175  if (gen.is_parameter_or_point()) {
176  // Do not scale the last coefficient.
177  gen.expr.mul_assign(reduced_pivot_col, 0, num_columns);
178  }
179  }
180 
181  // Subtract from row a multiple of pivot such that the result in
182  // row[column] is zero.
183  row.expr.linear_combine(pivot.expr,
184  Coefficient_one(), -reduced_row_col,
185  column, num_columns);
186  PPL_ASSERT(row.expr.get(column) == 0);
187 }
188 
189 void
191  const Congruence& pivot,
192  const dimension_type column,
194  // Very similar to reduce_parameter_with_line above. Any change
195  // here may be needed there too.
196  PPL_ASSERT(row.modulus() > 0 && pivot.modulus() == 0);
197 
198  Coefficient_traits::const_reference pivot_column = pivot.expr.get(column);
199  Coefficient_traits::const_reference row_column = row.expr.get(column);
200 
201  // If the elements at `column' in row and pivot are the same, then
202  // just subtract `pivot' from `row'.
203  if (row_column == pivot_column) {
204  row.expr -= pivot.expr;
205  return;
206  }
207 
208  PPL_DIRTY_TEMP_COEFFICIENT(reduced_row_col);
209  // Use reduced_row_col temporarily to hold the gcd.
210  gcd_assign(reduced_row_col, pivot_column, row_column);
211  PPL_DIRTY_TEMP_COEFFICIENT(reduced_pivot_col);
212  exact_div_assign(reduced_pivot_col, pivot_column, reduced_row_col);
213  exact_div_assign(reduced_row_col, row_column, reduced_row_col);
214  // Ensure that `reduced_pivot_col' is positive, so that the modulus
215  // remains positive when multiplying the proper congruences below.
216  // It's safe to swap the signs as row[column] will still come out 0.
217  if (reduced_pivot_col < 0) {
218  neg_assign(reduced_pivot_col);
219  neg_assign(reduced_row_col);
220  }
221  // Multiply `row', including the modulus, by reduced_pivot_col. To
222  // keep all the moduli the same this requires multiplying all the
223  // other proper congruences in the same way.
224  for (dimension_type index = sys.size(); index-- > 0; ) {
225  Congruence& cg = sys[index];
226  if (cg.is_proper_congruence()) {
227  cg.scale(reduced_pivot_col);
228  }
229  }
230  // Subtract from row a multiple of pivot such that the result in
231  // row[column] is zero.
232  sub_mul_assign(row.expr, reduced_row_col, pivot.expr);
233  PPL_ASSERT(row.expr.get(column) == 0);
234 }
235 
236 #ifndef NDEBUG
237 template <typename M, typename R>
238 bool
240  dimension_type last, dimension_type row_size) {
241  while (first <= last) {
242  const R& row = system[first++];
243  if (!row.expr.all_zeroes(0, row_size)) {
244  return false;
245  }
246  }
247  return true;
248 }
249 #endif
250 
251 void
253  PPL_ASSERT(!ggs.has_no_rows());
254  // Changes here may also be required in the congruence version below.
255 
256  // Subtract one to allow for the parameter divisor column
257  const dimension_type num_columns = ggs.space_dimension() + 1;
258 
259  if (dim_kinds.size() != num_columns) {
260  dim_kinds.resize(num_columns);
261  }
262 
263  const dimension_type num_rows = ggs.num_rows();
264 
265  // For each dimension `dim' move or construct a row into position
266  // `pivot_index' such that the row has zero in all elements
267  // following column `dim' and a value other than zero in column
268  // `dim'.
269  dimension_type pivot_index = 0;
270  for (dimension_type dim = 0; dim < num_columns; ++dim) {
271  // Consider the pivot and following rows.
272  dimension_type row_index = pivot_index;
273 
274  // Move down over rows which have zero in column `dim'.
275  while (row_index < num_rows
276  && ggs.sys.rows[row_index].expr.get(dim) == 0) {
277  ++row_index;
278  }
279 
280  if (row_index == num_rows) {
281  // Element in column `dim' is zero in all rows from the pivot.
282  dim_kinds[dim] = GEN_VIRTUAL;
283  }
284  else {
285  if (row_index != pivot_index) {
286  using std::swap;
287  swap(ggs.sys.rows[row_index], ggs.sys.rows[pivot_index]);
288  }
289  Grid_Generator& pivot = ggs.sys.rows[pivot_index];
290  bool pivot_is_line = pivot.is_line();
291 
292  // Change the matrix so that the value at `dim' in every row
293  // following `pivot_index' is 0, leaving an equivalent grid.
294  while (row_index < num_rows - 1) {
295  ++row_index;
296  Grid_Generator& row = ggs.sys.rows[row_index];
297 
298  if (row.expr.get(dim) == 0) {
299  continue;
300  }
301 
302  if (row.is_line()) {
303  if (pivot_is_line) {
304  reduce_line_with_line(row, pivot, dim);
305  }
306  else {
307  PPL_ASSERT(pivot.is_parameter_or_point());
308  using std::swap;
309  swap(row, pivot);
310  pivot_is_line = true;
311  reduce_parameter_with_line(row, pivot, dim, ggs.sys.rows,
312  num_columns + 1);
313  }
314  }
315  else {
316  PPL_ASSERT(row.is_parameter_or_point());
317  if (pivot_is_line) {
318  reduce_parameter_with_line(row, pivot, dim, ggs.sys.rows,
319  num_columns + 1);
320  }
321  else {
322  PPL_ASSERT(pivot.is_parameter_or_point());
323  reduce_pc_with_pc(row, pivot, dim, dim, num_columns);
324  }
325  }
326  }
327 
328  if (pivot_is_line) {
329  dim_kinds[dim] = LINE;
330  }
331  else {
332  PPL_ASSERT(pivot.is_parameter_or_point());
333  dim_kinds[dim] = PARAMETER;
334  }
335 
336  // Since we are reducing the system to "strong minimal form",
337  // ensure that a positive value follows the leading zeros.
338  if (pivot.expr.get(dim) < 0) {
339  pivot.expr.negate(dim, num_columns);
340  }
341 
342  // Factor this row out of the preceding rows.
343  reduce_reduced<Grid_Generator_System>
344  (ggs.sys.rows, dim, pivot_index, dim, num_columns - 1, dim_kinds);
345 
346  ++pivot_index;
347  }
348  }
349 
350  // Clip any zero rows from the end of the matrix.
351  if (num_rows > pivot_index) {
352 #ifndef NDEBUG
353  const bool ret = rows_are_zero<Grid_Generator_System, Grid_Generator>
354  (ggs,
355  // index of first
356  pivot_index,
357  // index of last
358  ggs.num_rows() - 1,
359  // row size
360  ggs.space_dimension() + 1);
361  PPL_ASSERT(ret == true);
362 #endif
363  ggs.sys.rows.resize(pivot_index);
364  }
365 
366  // Ensure that the parameter divisors are the same as the system
367  // divisor.
368  const Coefficient& system_divisor = ggs.sys.rows[0].expr.inhomogeneous_term();
369  for (dimension_type i = ggs.sys.rows.size() - 1,
370  dim = num_columns - 1; dim > 0; --dim) {
371  switch (dim_kinds[dim]) {
372  case PARAMETER:
373  ggs.sys.rows[i].set_divisor(system_divisor);
374  // Intentionally fall through.
375  case LINE:
376  PPL_ASSERT(ggs.sys.rows[i].OK());
377  --i;
378  break;
379  case GEN_VIRTUAL:
380  break;
381  }
382  }
383 
384  ggs.unset_pending_rows();
385  PPL_ASSERT(ggs.sys.OK());
386 }
387 
388 bool
390  PPL_ASSERT(cgs.space_dimension() != 0);
391  // Changes here may also be required in the generator version above.
392 
393  // TODO: Consider normalizing the moduli only when congruences are
394  // added to con_sys.
395  cgs.normalize_moduli();
396 
397  // NOTE: add one for the inhomogeneous term (but not the modulus).
398  const dimension_type num_columns = cgs.space_dimension() + 1;
399 
400  if (dim_kinds.size() != num_columns) {
401  dim_kinds.resize(num_columns);
402  }
403 
404  const dimension_type num_rows = cgs.num_rows();
405 
406  // For each dimension `dim' move or construct a row into position
407  // `pivot_index' such that the row has a value of zero in all
408  // elements preceding column `dim' and some other value in column
409  // `dim'.
410  dimension_type pivot_index = 0;
411  for (dimension_type dim = num_columns; dim-- > 0; ) {
412  // Consider the pivot and following rows.
413  dimension_type row_index = pivot_index;
414 
415  // Move down over rows which have zero in column `dim'.
416  while (row_index < num_rows && cgs.rows[row_index].expr.get(dim) == 0) {
417  ++row_index;
418  }
419 
420  if (row_index == num_rows) {
421  // Element in column `dim' is zero in all rows from the pivot,
422  // or `cgs' is empty of rows.
423  dim_kinds[dim] = CON_VIRTUAL;
424  }
425  else {
426  // Here row_index != num_rows.
427  if (row_index != pivot_index) {
428  using std::swap;
429  swap(cgs.rows[row_index], cgs.rows[pivot_index]);
430  }
431 
432  Congruence& pivot = cgs.rows[pivot_index];
433  bool pivot_is_equality = pivot.is_equality();
434 
435  // Change the matrix so that the value at `dim' in every row
436  // following `pivot_index' is 0, leaving an equivalent grid.
437  while (row_index < num_rows - 1) {
438  ++row_index;
439  Congruence& row = cgs.rows[row_index];
440  if (row.expr.get(dim) == 0) {
441  continue;
442  }
443 
444  if (row.is_equality()) {
445  if (pivot_is_equality) {
446  reduce_equality_with_equality(row, pivot, dim);
447  }
448  else {
449  PPL_ASSERT(pivot.is_proper_congruence());
450  using std::swap;
451  swap(row, pivot);
452  pivot_is_equality = true;
453  reduce_congruence_with_equality(row, pivot, dim, cgs.rows);
454  }
455  }
456  else {
457  PPL_ASSERT(row.is_proper_congruence());
458  if (pivot_is_equality) {
459  reduce_congruence_with_equality(row, pivot, dim, cgs.rows);
460  }
461  else {
462  PPL_ASSERT(pivot.is_proper_congruence());
463  reduce_pc_with_pc(row, pivot, dim, 0, dim + 1);
464  }
465  }
466  }
467 
468  if (pivot_is_equality) {
469  dim_kinds[dim] = EQUALITY;
470  }
471  else {
472  PPL_ASSERT(pivot.is_proper_congruence());
473  dim_kinds[dim] = PROPER_CONGRUENCE;
474  }
475 
476  // Since we are reducing the system to "strong minimal form",
477  // ensure that a positive value follows the leading zeros.
478  if (pivot.expr.get(dim) < 0) {
479  pivot.expr.negate(0, dim + 1);
480  }
481 
482  // Factor this row out of the preceding ones.
483  reduce_reduced<Congruence_System>
484  (cgs.rows, dim, pivot_index, 0, dim, dim_kinds, false);
485 
486  PPL_ASSERT(cgs.OK());
487 
488  ++pivot_index;
489  }
490  }
491 
492  if (pivot_index > 0) {
493  // If the last row is false then make it the equality 1 = 0, and
494  // make it the only row.
495 
496 #ifndef NDEBUG
497  {
498  const bool ret = rows_are_zero<Congruence_System, Congruence>
499  (cgs,
500  // index of first
501  pivot_index,
502  // index of last
503  num_rows - 1,
504  // row size
505  num_columns);
506  PPL_ASSERT(ret == true);
507  }
508 #endif
509 
510  cgs.remove_trailing_rows(num_rows - pivot_index);
511  Congruence& last_row = cgs.rows.back();
512 
513  switch (dim_kinds[0]) {
514 
515  case PROPER_CONGRUENCE:
516  if (last_row.inhomogeneous_term() % last_row.modulus() == 0) {
517  break;
518  }
519  // The last row is a false proper congruence.
520  last_row.set_modulus(Coefficient_zero());
521  dim_kinds[0] = EQUALITY;
522  // Intentionally fall through.
523 
524  case EQUALITY:
525  // The last row is a false equality, as all the coefficient terms
526  // are zero while the inhomogeneous term (as a result of the
527  // reduced form) is some other value.
529  dim_kinds.resize(1);
530  using std::swap;
531  swap(cgs.rows[0], last_row);
532  cgs.remove_trailing_rows(cgs.num_rows() - 1);
533  PPL_ASSERT(cgs.OK());
534  return true;
535 
536  default:
537  break;
538  }
539  }
540  else {
541  // Either `cgs' is empty (it defines the universe) or every column
542  // before the modulus column contains only zeroes.
543 
544  if (num_rows > 0) {
545 #ifndef NDEBUG
546  const bool ret = rows_are_zero<Congruence_System, Congruence>
547  (cgs,
548  // index of first
549  0,
550  // index of last
551  num_rows - 1,
552  // row size
553  num_columns);
554  PPL_ASSERT(ret == true);
555 #endif
556  // Ensure that a single row will remain for the integrality congruence.
557  cgs.remove_trailing_rows(num_rows - 1);
558  }
559 
560  // Set up the integrality congruence.
561  dim_kinds[0] = PROPER_CONGRUENCE;
562  if (num_rows == 0) {
563  Congruence cg;
567  cgs.insert_verbatim(cg, Recycle_Input());
568 
569  PPL_ASSERT(cgs.OK());
570  return false;
571  }
572 
573  PPL_ASSERT(cgs.num_rows() == 1);
574  cgs.rows.back().set_modulus(Coefficient_one());
575  }
576 
577  // Ensure that the last row is the integrality congruence.
578  if (dim_kinds[0] == CON_VIRTUAL) {
579  // The last row is virtual, append the integrality congruence.
580  dim_kinds[0] = PROPER_CONGRUENCE;
581  Congruence new_last_row;
582  new_last_row.set_space_dimension(cgs.space_dimension());
583  new_last_row.set_modulus(Coefficient_one());
584  // Try use an existing modulus.
586  while (row_index-- > 0) {
587  const Congruence& row = cgs[row_index];
588  if (row.modulus() > 0) {
589  new_last_row.set_modulus(row.modulus());
590  break;
591  }
592  }
593  new_last_row.expr.set_inhomogeneous_term(new_last_row.modulus());
594  cgs.insert_verbatim(new_last_row, Recycle_Input());
595  }
596  else {
597  cgs.rows.back().expr.set_inhomogeneous_term(cgs.rows.back().modulus());
598  }
599 
600  // Since we are reducing the system to "strong minimal form",
601  // factor the modified integrality congruence out of the other rows;
602  reduce_reduced<Congruence_System>
603  (cgs.rows, 0, cgs.num_rows() - 1, 0, 0, dim_kinds, false);
604 
605  PPL_ASSERT(cgs.OK());
606  return false;
607 }
608 
609 } // namespace Parma_Polyhedra_Library
bool is_parameter_or_point() const
Returns true if and only if *this row represents a parameter or a point.
static void reduce_pc_with_pc(R &row, R &pivot, dimension_type column, dimension_type start, dimension_type end)
Reduces row using pivot.
Coefficient_traits::const_reference modulus() const
Returns a const reference to the modulus of *this.
void swap(CO_Tree &x, CO_Tree &y)
size_t dimension_type
An unsigned integral type for representing space dimensions.
bool is_line() const
Returns true if and only if *this is a line.
Coefficient_traits::const_reference get(dimension_type i) const
Returns the i-th coefficient.
#define PPL_DIRTY_TEMP_COEFFICIENT(id)
Declare a local variable named id, of type Coefficient, and containing an unknown initial value...
void insert_verbatim(Congruence &cg, Recycle_Input)
Inserts in *this the congruence cg, stealing its contents and increasing the number of space dimensio...
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void set_inhomogeneous_term(Coefficient_traits::const_reference n)
Sets the inhomogeneous term of *this to n.
Coefficient_traits::const_reference inhomogeneous_term() const
Returns the inhomogeneous term of *this.
void exact_div_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
static bool simplify(Congruence_System &cgs, Dimension_Kinds &dim_kinds)
Converts cgs to upper triangular (i.e. minimized) form.
void normalize_moduli()
Adjusts all expressions to have the same moduli.
bool is_proper_congruence() const
Returns true if the modulus is greater than zero.
void negate(dimension_type first, dimension_type last)
Negates the elements from index first (included) to index last (excluded).
bool OK() const
Checks if all the invariants are satisfied.
Definition: Congruence.cc:252
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void set_modulus(Coefficient_traits::const_reference m)
bool is_equality() const
Returns true if *this is an equality.
std::vector< Dimension_Kind > Dimension_Kinds
Definition: Grid_defs.hh:1994
void gcdext_assign(GMP_Integer &x, GMP_Integer &s, GMP_Integer &t, const GMP_Integer &y, const GMP_Integer &z)
dimension_type row_index
Definition: PIP_Tree.cc:615
bool OK() const
Checks if all the invariants are satisfied.
void swap(Grid &x, Grid &y)
Swaps x with y.
PPL_COEFFICIENT_TYPE Coefficient
An alias for easily naming the type of PPL coefficients.
void linear_combine_lax(const Linear_Expression &y, Coefficient_traits::const_reference c1, Coefficient_traits::const_reference c2)
void unset_pending_rows()
Sets the index to indicate that the system has no pending rows.
void neg_assign(GMP_Integer &x)
Coefficient_traits::const_reference Coefficient_zero()
Returns a const reference to a Coefficient with value 0.
The entire library is confined to this namespace.
Definition: version.hh:61
dimension_type num_rows() const
Returns the number of rows in the system.
static bool rows_are_zero(M &system, dimension_type first, dimension_type last, dimension_type row_size)
Checks that trailing rows contain only zero terms.
dimension_type num_rows() const
Returns the number of rows (generators) in the system.
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
void gcd_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
static void reduce_equality_with_equality(Congruence &row, const Congruence &pivot, dimension_type column)
Reduces the equality row using the equality pivot.
void sub_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
static void reduce_congruence_with_equality(Congruence &row, const Congruence &pivot, dimension_type column, Swapping_Vector< Congruence > &sys)
Reduce row using pivot.
void mul_assign(Coefficient_traits::const_reference n, dimension_type start, dimension_type end)
Equivalent to (*this)[i] *= n, for each i in [start, end).
void linear_combine(const Linear_Expression &y, Variable v)
static void reduce_parameter_with_line(Grid_Generator &row, const Grid_Generator &pivot, dimension_type column, Swapping_Vector< Grid_Generator > &sys, dimension_type num_columns)
Reduce row using pivot.
Coefficient_traits::const_reference Coefficient_one()
Returns a const reference to a Coefficient with value 1.
void scale(Coefficient_traits::const_reference factor)
Multiplies all the coefficients, including the modulus, by factor .
Definition: Congruence.cc:103
void set_space_dimension(dimension_type n)
bool OK() const
Checks if all the invariants are satisfied.
A grid line, parameter or grid point.
static void reduce_line_with_line(Grid_Generator &row, Grid_Generator &pivot, dimension_type column)
Reduces the line row using the line pivot.