/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program 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 3 of the License, or
(at your option) any later version.
This program 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, see .
**************************************************************************************************/
#ifndef PACKEDROW_H
#define PACKEDROW_H
//#define DEBUG_ROW
#include
#ifdef _MSC_VER
#include
#else
#include
#endif //_MSC_VER
#include "SolverTypes.h"
#include "Vec.h"
#include
#include
#include
#include
#ifndef uint
#define uint unsigned int
#endif
using std::vector;
class PackedMatrix;
class PackedRow
{
public:
bool operator ==(const PackedRow& b) const;
bool operator !=(const PackedRow& b) const;
PackedRow& operator=(const PackedRow& b)
{
#ifdef DEBUG_ROW
assert(size > 0);
assert(b.size > 0);
assert(size == b.size);
#endif
memcpy(mp-1, b.mp-1, size+1);
return *this;
}
PackedRow& operator^=(const PackedRow& b)
{
#ifdef DEBUG_ROW
assert(size > 0);
assert(b.size > 0);
assert(b.size == size);
#endif
for (uint32_t i = 0; i != size; i++) {
*(mp + i) ^= *(b.mp + i);
}
is_true_internal ^= b.is_true_internal;
return *this;
}
void xorBoth(const PackedRow& b)
{
#ifdef DEBUG_ROW
assert(size > 0);
assert(b.size > 0);
assert(b.size == size);
#endif
for (uint32_t i = 0; i != 2*size+1; i++) {
*(mp + i) ^= *(b.mp + i);
}
is_true_internal ^= b.is_true_internal;
}
uint32_t popcnt() const;
uint32_t popcnt(uint32_t from) const;
bool popcnt_is_one() const
{
char popcount = 0;
for (uint32_t i = 0; i != size; i++) {
uint64_t tmp = mp[i];
while(tmp) {
popcount += tmp & 1;
tmp >>= 1;
}
}
return popcount == 1;
}
bool popcnt_is_one(uint32_t from) const
{
from++;
uint64_t tmp = mp[from/64];
tmp >>= from%64;
if (tmp) return false;
for (uint32_t i = from/64+1; i != size; i++)
if (mp[i]) return false;
return true;
}
inline const uint64_t& is_true() const
{
return is_true_internal;
}
inline const bool isZero() const
{
for (uint32_t i = 0; i != size; i++) {
if (mp[i]) return false;
}
return true;
}
inline void setZero()
{
memset(mp, 0, sizeof(uint64_t)*size);
}
inline void clearBit(const uint32_t i)
{
mp[i/64] &= ~((uint64_t)1 << (i%64));
}
inline void invert_is_true(const bool b = true)
{
is_true_internal ^= (uint64_t)b;
}
inline void setBit(const uint32_t i)
{
mp[i/64] |= ((uint64_t)1 << (i%64));
}
void swapBoth(PackedRow b)
{
#ifdef DEBUG_ROW
assert(size > 0);
assert(b.size > 0);
assert(b.size == size);
#endif
uint64_t * __restrict mp1 = mp-1;
uint64_t * __restrict mp2 = b.mp-1;
uint32_t i = 2*(size+1);
while(i != 0) {
std::swap(*mp1, *mp2);
mp1++;
mp2++;
i--;
}
}
inline const bool operator[](const uint32_t& i) const
{
#ifdef DEBUG_ROW
assert(size*64 > i);
#endif
return (mp[i/64] >> (i%64)) & 1;
}
template
void set(const T& v, const vector& var_to_col, const uint32_t matrix_size)
{
assert(size == (matrix_size/64) + ((bool)(matrix_size % 64)));
//mp = new uint64_t[size];
setZero();
for (uint32_t i = 0; i != v.size(); i++) {
const uint32_t toset_var = var_to_col[v[i].var()];
assert(toset_var != std::numeric_limits::max());
setBit(toset_var);
}
is_true_internal = !v.xor_clause_inverted();
}
void fill(vec& tmp_clause, const vec& assigns, const vector& col_to_var_original) const;
inline unsigned long int scan(const unsigned long int var) const
{
#ifdef DEBUG_ROW
assert(size > 0);
#endif
for(uint32_t i = var; i != size*64; i++)
if (this->operator[](i)) return i;
return std::numeric_limits::max();
}
friend std::ostream& operator << (std::ostream& os, const PackedRow& m);
private:
friend class PackedMatrix;
PackedRow(const uint32_t _size, uint64_t* const _mp) :
mp(_mp+1)
, is_true_internal(*_mp)
, size(_size)
{}
uint64_t* __restrict const mp;
uint64_t& is_true_internal;
const uint32_t size;
};
std::ostream& operator << (std::ostream& os, const PackedRow& m);
#endif //PACKEDROW_H