/* SatMatrix class implementation (non-inline functions).
Copyright (C) 2001-2004 Roberto Bagnara <bagnara@cs.unipr.it>
This file is part of the Parma Polyhedra Library (PPL).
The PPL is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
The PPL is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
For the most up-to-date information see the Parma Polyhedra Library
site: http://www.cs.unipr.it/ppl/ . */
#include <config.h>
#include "SatMatrix.defs.hh"
#include "globals.hh"
#include <iostream>
#include <algorithm>
#include <string>
namespace PPL = Parma_Polyhedra_Library;
PPL::SatMatrix&
PPL::SatMatrix::operator=(const SatMatrix& y){
rows = y.rows;
row_size = y.row_size;
assert(OK());
return *this;
}
void
PPL::SatMatrix::sort_rows() {
// Sorting without removing duplicates.
std::sort(rows.begin(), rows.end(), RowCompare());
// Moving all the duplicate elements at the end of the vector.
std::vector<SatRow>::iterator first_duplicate
= std::unique(rows.begin(), rows.end());
// Removing duplicates.
rows.erase(first_duplicate, rows.end());
assert(OK());
}
void
PPL::SatMatrix::add_row(const SatRow& row) {
const dimension_type new_rows_size = rows.size() + 1;
if (rows.capacity() < new_rows_size) {
// Reallocation will take place.
std::vector<SatRow> new_rows;
new_rows.reserve(compute_capacity(new_rows_size));
new_rows.insert(new_rows.end(), new_rows_size, SatRow());
// Put the new row in place.
dimension_type i = new_rows_size-1;
new_rows[i] = row;
// Steal the old rows.
while (i-- > 0)
new_rows[i].swap(rows[i]);
// Put the new rows into place.
std::swap(rows, new_rows);
}
else
// Reallocation will NOT take place: append a new empty row.
rows.push_back(row);
assert(OK());
}
void
PPL::SatMatrix::transpose() {
const SatMatrix& x = *this;
const dimension_type nrows = num_rows();
const dimension_type ncols = num_columns();
SatMatrix tmp(ncols, nrows);
for (dimension_type i = nrows; i-- > 0; )
for (int j = x[i].last(); j >= 0; j = x[i].prev(j))
tmp[j].set(i);
swap(tmp);
assert(OK());
}
void
PPL::SatMatrix::transpose_assign(const SatMatrix& y) {
const dimension_type y_nrows = y.num_rows();
const dimension_type y_ncols = y.num_columns();
SatMatrix tmp(y_ncols, y_nrows);
for (dimension_type i = y_nrows; i-- > 0; )
for (int j = y[i].last(); j >= 0; j = y[i].prev(j))
tmp[j].set(i);
swap(tmp);
assert(OK());
}
void
PPL::SatMatrix::resize(dimension_type new_n_rows,
dimension_type new_n_columns) {
assert(OK());
const dimension_type old_num_rows = num_rows();
if (new_n_columns < row_size) {
const dimension_type num_preserved_rows
= std::min(old_num_rows, new_n_rows);
SatMatrix& x = *this;
for (dimension_type i = num_preserved_rows; i-- > 0; )
x[i].clear_from(new_n_columns);
}
row_size = new_n_columns;
if (new_n_rows > old_num_rows) {
if (rows.capacity() < new_n_rows) {
// Reallocation will take place.
std::vector<SatRow> new_rows;
new_rows.reserve(compute_capacity(new_n_rows));
new_rows.insert(new_rows.end(), new_n_rows, SatRow());
// Steal the old rows.
for (dimension_type i = old_num_rows; i-- > 0; )
new_rows[i].swap(rows[i]);
// Put the new vector into place.
std::swap(rows, new_rows);
}
else
// Reallocation will NOT take place.
rows.insert(rows.end(), new_n_rows - old_num_rows, SatRow());
}
else if (new_n_rows < old_num_rows)
// Drop some rows.
rows.erase(rows.begin() + new_n_rows, rows.end());
assert(OK());
}
bool
PPL::SatMatrix::sorted_contains(const SatRow& row) const {
assert(check_sorted());
const SatMatrix& x = *this;
for (dimension_type i = num_rows(); i-- > 0; ) {
const int comp = compare(x[i], row);
if (comp == 0)
return true;
else if (comp < 0)
return false;
}
return false;
}
void
PPL::SatMatrix::ascii_dump(std::ostream& s) const {
using std::endl;
const SatMatrix& x = *this;
const char separator = ' ';
s << num_rows() << separator << 'x' << separator
<< num_columns() << endl;
for (dimension_type i = 0; i < num_rows(); ++i) {
for (dimension_type j = 0; j < num_columns(); ++j)
s << x[i][j] << separator;
s << endl;
}
}
bool
PPL::SatMatrix::ascii_load(std::istream& s) {
SatMatrix& x = *this;
dimension_type nrows;
dimension_type ncols;
std::string str;
if (!(s >> nrows))
return false;
if (!(s >> str))
return false;
if (!(s >> ncols))
return false;
resize(nrows, ncols);
for (dimension_type i = 0; i < num_rows(); ++i)
for (dimension_type j = 0; j < num_columns(); ++j) {
int bit;
if (!(s >> bit))
return false;
if (bit)
x[i].set(j);
else
x[i].clear(j);
}
// Check for well-formedness.
assert(OK());
return true;
}
bool
PPL::SatMatrix::OK() const {
#ifndef NDEBUG
using std::endl;
using std::cerr;
#endif
const SatMatrix& x = *this;
for (dimension_type i = num_rows(); i-- > 1; ) {
const SatRow& row = x[i];
if (!row.OK())
return false;
else if (row.last() >= 0 && unsigned(row.last()) >= row_size) {
#ifndef NDEBUG
cerr << "SatMatrix[" << i << "] is a SatRow with too many bits!"
<< endl
<< "(row_size == " << row_size
<< ", row.last() == " << row.last() << ")"
<< endl;
#endif
return false;
}
}
return true;
}
#ifndef NDEBUG
bool
PPL::SatMatrix::check_sorted() const {
const SatMatrix& x = *this;
for (dimension_type i = num_rows(); i-- > 1; )
if (compare(x[i-1], x[i]) > 0)
return false;
return true;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1