24 #ifndef PPL_Linear_System_templates_hh
25 #define PPL_Linear_System_templates_hh 1
39 template <
typename Row>
42 PPL_ASSERT(num_pending_rows() == 0);
46 if (x[i].is_line_or_equality()) {
53 template <
typename Row>
74 while (xi < x_num_rows && yi < y_num_rows) {
75 const int comp =
compare(x[xi], y[yi]);
80 tmp.
back().set_representation(representation());
89 Row copy(y[yi++], space_dimension(), representation());
94 if (xi < x_num_rows) {
95 while (xi < x_num_rows) {
98 tmp.
back().set_representation(representation());
102 while (yi < y_num_rows) {
104 Row copy(y[yi++], space_dimension(), representation());
112 unset_pending_rows();
113 PPL_ASSERT(check_sorted());
117 template <
typename Row>
124 s <<
"topology " << (is_necessarily_closed()
125 ?
"NECESSARILY_CLOSED"
126 :
"NOT_NECESSARILY_CLOSED")
128 << num_rows() <<
" x " << space_dimension() <<
" ";
130 s <<
" " << (sorted ?
"(sorted)" :
"(not_sorted)")
132 <<
"index_first_pending " << first_pending_row()
135 rows[i].ascii_dump(s);
141 template <typename Row>
145 if (!(s >> str) || str !=
"topology") {
155 if (str ==
"NECESSARILY_CLOSED") {
159 if (str !=
"NOT_NECESSARILY_CLOSED") {
172 if (!(s >> str) || str !=
"x") {
175 if (!(s >> space_dims)) {
179 space_dimension_ = space_dims;
185 if (!(s >> str) || (str !=
"(sorted)" && str !=
"(not_sorted)")) {
188 const bool sortedness = (str ==
"(sorted)");
190 if (!(s >> str) || str !=
"index_first_pending") {
199 if (!row.ascii_load(s)) {
204 index_first_pending = index;
212 template <
typename Row>
215 Row tmp(r, representation());
219 template <
typename Row>
226 template <
typename Row>
229 PPL_ASSERT(topology() == r.topology());
231 PPL_ASSERT(num_pending_rows() == 0);
233 const bool was_sorted = is_sorted();
244 sorted = (
compare(rows[nrows-2], rows[nrows-1]) <= 0);
252 unset_pending_rows();
255 template <
typename Row>
264 PPL_ASSERT(r.check_strong_normalized());
267 PPL_ASSERT(r.topology() == topology());
269 r.set_representation(representation());
271 if (space_dimension() < r.space_dimension()) {
272 set_space_dimension_no_ok(r.space_dimension());
275 r.set_space_dimension_no_ok(space_dimension());
278 rows.resize(rows.size() + 1);
279 swap(rows.back(), r);
282 template <
typename Row>
285 Row tmp(r, representation());
289 template <
typename Row>
296 template <
typename Row>
303 template <
typename Row>
321 template <
typename Row>
328 template <
typename Row>
331 PPL_ASSERT(num_pending_rows() == 0);
347 sorted = (
compare(rows[n_rows-1], y[0]) <= 0);
358 unset_pending_rows();
363 template <
typename Row>
379 const bool valid = rows[i].remove_space_dimensions(vars);
385 remove_row_no_ok(i,
false);
392 space_dimension_ -= vars.size();
397 template <
typename Row>
402 PPL_ASSERT(v.
id() <= space_dimension());
404 rows[i].shift_space_dimensions(v, n);
406 space_dimension_ += n;
410 template <
typename Row>
414 sort_rows(0, first_pending_row());
419 template <
typename Row>
423 PPL_ASSERT(first_row <= last_row && last_row <= num_rows());
425 PPL_ASSERT(first_row >= first_pending_row()
426 || last_row <= first_pending_row());
428 const bool sorting_pending = (first_row >= first_pending_row());
438 using namespace Implementation;
440 typedef Indirect_Sort_Compare<Cont, Row_Less_Than> Sort_Compare;
441 typedef Indirect_Swapper<Cont> Swapper;
444 Sort_Compare(rows, first_row),
446 Swapper(rows, first_row));
448 if (num_duplicates > 0) {
449 typedef typename Cont::iterator Iter;
450 typedef typename std::iterator_traits<Iter>::difference_type diff_t;
451 Iter last = rows.begin() +
static_cast<diff_t
>(last_row);
452 Iter first = last - +
static_cast<diff_t
>(num_duplicates);
453 rows.erase(first, last);
456 if (sorting_pending) {
457 PPL_ASSERT(old_num_pending >= num_duplicates);
458 index_first_pending = num_rows() - (old_num_pending - num_duplicates);
461 index_first_pending = num_rows() - old_num_pending;
467 template <
typename Row>
473 rows[i].strong_normalize();
475 sorted = (nrows <= 1);
479 template <
typename Row>
485 rows[i].sign_normalize();
487 sorted = (nrows <= 1);
492 template <
typename Row>
500 if (x_num_rows != y_num_rows) {
519 template <
typename Row>
523 PPL_ASSERT(first_pending_row() == sat.
num_rows());
524 if (first_pending_row() <= 1) {
540 unique_cmp, swapper);
543 = first_pending_row() - num_duplicates;
545 if (num_pending_rows() > 0) {
549 swap(rows[new_first_pending_row + i], rows[n_rows - i]);
554 rows.resize(rows.size() - num_duplicates);
555 index_first_pending = new_first_pending_row;
565 template <
typename Row>
571 PPL_ASSERT(num_pending_rows() == 0);
572 PPL_ASSERT(n_lines_or_equalities == num_lines_or_equalities());
575 PPL_ASSERT((*
this)[i].is_line_or_equality());
581 bool changed =
false;
584 = is_necessarily_closed() ? space_dimension() + 1 : space_dimension() + 2;
592 if ((*
this)[i].expr.get(j) == 0) {
598 swap(rows[i], rows[rank]);
606 if (rows[k].expr.get(
Variable(j - 1)) != 0) {
607 rows[k].linear_combine(rows[rank], j);
625 template <
typename Row>
632 PPL_ASSERT(num_pending_rows() == 0);
633 PPL_ASSERT(n_lines_or_equalities <= num_lines_or_equalities());
636 PPL_ASSERT((*
this)[i].is_line_or_equality());
642 bool still_sorted = is_sorted();
645 std::deque<bool> check_for_sortedness;
647 check_for_sortedness.insert(check_for_sortedness.end(), nrows,
false);
654 Row& row_k = rows[k];
661 Row& row_i = rows[i];
662 if (row_i.expr.get(
Variable(j - 1)) != 0) {
665 row_i.linear_combine(row_k, j);
670 check_for_sortedness[i-1] =
true;
672 check_for_sortedness[i] =
true;
682 const bool have_to_negate = (row_k.expr.get(
Variable(j - 1)) < 0);
683 if (have_to_negate) {
694 Row& row_i = rows[i];
695 if (row_i.expr.get(
Variable(j - 1)) != 0) {
698 row_i.linear_combine(row_k, j);
702 if (i > n_lines_or_equalities) {
703 check_for_sortedness[i-1] =
true;
705 check_for_sortedness[i] =
true;
709 if (have_to_negate) {
714 PPL_ASSERT(row_k.OK());
719 if (check_for_sortedness[i]) {
721 still_sorted = (
compare((*
this)[i], (*
this)[i+1]) <= 0);
726 sorted = still_sorted;
731 template <
typename Row>
735 PPL_ASSERT(num_pending_rows() == 0);
742 if ((*
this)[i].is_line_or_equality()) {
743 if (n_lines_or_equalities < i) {
744 swap(rows[i], rows[n_lines_or_equalities]);
748 ++n_lines_or_equalities;
754 if (rank < n_lines_or_equalities) {
756 n_rays_or_points_or_inequalities = nrows - n_lines_or_equalities;
758 num_swaps = std::min(n_lines_or_equalities - rank,
759 n_rays_or_points_or_inequalities);
761 swap(rows[--nrows], rows[rank + i]);
763 remove_trailing_rows(old_nrows - nrows);
764 if (n_rays_or_points_or_inequalities > num_swaps) {
767 unset_pending_rows();
768 n_lines_or_equalities = rank;
771 back_substitute(n_lines_or_equalities);
776 template <
typename Row>
781 const bool was_sorted = is_sorted();
784 = is_necessarily_closed() ? space_dimension() : space_dimension() + 1;
785 set_space_dimension(space_dimension() + n);
786 rows.resize(rows.size() + n);
789 swap(rows[i], rows[i + n]);
795 if (
Variable(
c).space_dimension() <= space_dimension()) {
800 Row r(le, Row::LINE_OR_EQUALITY, row_topology);
808 r.mark_as_not_necessarily_closed();
817 sorted = (
compare(rows[n-1], rows[n]) <= 0);
822 if (!is_necessarily_closed()) {
824 PPL_ASSERT(old_space_dim != 0);
827 rows[i].expr.swap_space_dimensions(
Variable(old_space_dim - 1),
829 PPL_ASSERT(rows[i].OK());
837 rows[i].expr.swap_space_dimensions(
Variable(old_eps_index),
839 PPL_ASSERT(rows[i].OK());
846 set_index_first_pending_row(index_first_pending + n);
849 template <
typename Row>
852 PPL_ASSERT(num_pending_rows() > 0);
853 PPL_ASSERT(is_sorted());
858 sort_rows(first_pending, num_rows());
869 while (k1 < first_pending && k2 < num_rows) {
879 swap(rows[k2], rows[k2 + num_duplicates]);
891 if (num_duplicates > 0 && k2 < num_rows) {
892 swap(rows[k2], rows[k2 + num_duplicates]);
898 if (num_duplicates > 0) {
900 for (++k2; k2 < num_rows; ++k2) {
901 swap(rows[k2], rows[k2 + num_duplicates]);
904 rows.resize(num_rows);
910 template <
typename Row>
914 if (
compare(rows[i], rows[i-1]) < 0) {
921 template <
typename Row>
930 if (rows[i].representation() != representation()) {
932 cerr <<
"Linear_System has a row with the wrong representation!"
937 if (rows[i].space_dimension() != space_dimension()) {
939 cerr <<
"Linear_System has a row with the wrong number of space dimensions!"
947 if (rows[i].topology() != topology()) {
949 cerr <<
"Linear_System has a row with the wrong topology!"
957 if (first_pending_row() > num_rows()) {
959 cerr <<
"Linear_System has a negative number of pending rows!"
968 if (topology() != rows[i].topology()) {
970 cerr <<
"Topology mismatch between the system "
971 <<
"and one of its rows!"
978 if (sorted && !check_sorted()) {
980 cerr <<
"The system declares itself to be sorted but it is not!"
992 #endif // !defined(PPL_Linear_System_templates_hh)
dimension_type space_dimension() const
Returns the dimension of the smallest vector space enclosing all the variables whose indexes are in t...
Comparison predicate (used when implementing the unique algorithm).
dimension_type max_num_rows()
void swap(CO_Tree &x, CO_Tree &y)
void set_space_dimension(dimension_type n)
Sets the dimension of the vector space enclosing *this to n .
The base class for systems of constraints and generators.
size_t dimension_type
An unsigned integral type for representing space dimensions.
void merge_rows_assign(const Linear_System &y)
Assigns to *this the result of merging its rows with those of y, obtaining a sorted system...
An std::set of variables' indexes.
dimension_type num_rows() const
Returns the number of rows of *this.
void resize(dimension_type new_size)
void sort_pending_and_remove_duplicates()
Sorts the pending rows and eliminates those that also occur in the non-pending part of the system...
Enable_If< Is_Native_Or_Checked< T >::value, void >::type ascii_dump(std::ostream &s, const T &t)
void insert_pending(const Row &r)
Adds a copy of the given row to the pending part of the system, automatically resizing the system or ...
dimension_type num_lines_or_equalities() const
Returns the number of rows in the system that represent either lines or equalities.
void strong_normalize()
Strongly normalizes the system.
The standard C++ namespace.
bool check_sorted() const
Returns true if and only if *this is sorted, without checking for duplicates.
dimension_type first_pending_row() const
Returns the index of the first pending row.
void sort_and_remove_with_sat(Bit_Matrix &sat)
Sorts the system, removing duplicates, keeping the saturation matrix consistent.
void back_substitute(dimension_type n_lines_or_equalities)
Back-substitutes the coefficients to reduce the complexity of the system.
void clear()
Clears the system deallocating all its rows.
Swapping_Vector< Row > rows
The vector that contains the rows.
void insert_pending_no_ok(Row &r, Recycle_Input)
Adds r to the pending part of the system, stealing its contents and automatically resizing the system...
dimension_type id() const
Returns the index of the Cartesian axis associated to the variable.
A dimension of the vector space.
dimension_type compute_capacity(dimension_type requested_size, dimension_type maximum_size)
Speculative allocation function.
#define PPL_OUTPUT_TEMPLATE_DEFINITIONS_ASCII_ONLY(type_symbol, class_prefix)
void add_universe_rows_and_space_dimensions(dimension_type n)
Adds n rows and space dimensions to the system.
dimension_type num_rows() const
bool is_sorted() const
Returns the value of the sortedness flag.
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type ascii_load(std::istream &s, T &t)
int compare(const Linear_Expression &x, const Linear_Expression &y)
void remove_trailing_rows(dimension_type n)
Removes the last n rows.
void simplify()
Applies Gaussian elimination and back-substitution so as to simplify the linear system.
void shift_space_dimensions(Variable v, dimension_type n)
void reserve(dimension_type new_capacity)
void neg_assign(GMP_Integer &x)
void insert(const Row &r)
Adds a copy of r to the system, automatically resizing the system or the row's copy, if needed.
The entire library is confined to this namespace.
void sign_normalize()
Sign-normalizes the system.
int cmp(const GMP_Integer &x, const GMP_Integer &y)
dimension_type gauss(dimension_type n_lines_or_equalities)
Minimizes the subsystem of equations contained in *this.
Sort_Comparer::size_type indirect_sort_and_unique(typename Sort_Comparer::size_type num_elems, Sort_Comparer sort_cmp, Unique_Comparer unique_cmp, Swapper indirect_swap)
dimension_type space_dimension() const
Returns the space dimension of the rows in the system.
void sort_rows()
Sorts the non-pending rows (in growing order) and eliminates duplicated ones.
bool OK() const
Checks if all the invariants are satisfied.
void remove_space_dimensions(const Variables_Set &vars)
Removes all the specified dimensions from the system.
bool operator==(const Linear_System< Row > &x, const Linear_System< Row > &y)
void insert_no_ok(Row &r, Recycle_Input)
Adds r to the system, stealing its contents and automatically resizing the system or the row...
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
dimension_type size() const
dimension_type num_pending_rows() const
Returns the number of rows that are in the pending part of the system.
bool le(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
Topology
Kinds of polyhedra domains.