/***********************************************************************************
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 .
**************************************************************************************************/
#include "FindUndef.h"
#include "Solver.h"
#include "VarReplacer.h"
#include
FindUndef::FindUndef(Solver& _solver) :
solver(_solver)
, isPotentialSum(0)
{
}
void FindUndef::fillPotential()
{
int trail = solver.decisionLevel()-1;
while(trail > 0) {
assert(trail < (int)solver.trail_lim.size());
uint at = solver.trail_lim[trail];
assert(at > 0);
Var v = solver.trail[at].var();
if (solver.assigns[v] != l_Undef) {
isPotential[v] = true;
isPotentialSum++;
}
trail--;
}
for (XorClause** it = solver.xorclauses.getData(), **end = it + solver.xorclauses.size(); it != end; it++) {
XorClause& c = **it;
for (Lit *l = c.getData(), *end = l + c.size(); l != end; l++) {
if (isPotential[l->var()]) {
isPotential[l->var()] = false;
isPotentialSum--;
}
assert(!solver.value(*l).isUndef());
}
}
vector replacingVars = solver.varReplacer->getReplacingVars();
for (Var *it = &replacingVars[0], *end = it + replacingVars.size(); it != end; it++) {
if (isPotential[*it]) {
isPotential[*it] = false;
isPotentialSum--;
}
}
}
void FindUndef::unboundIsPotentials()
{
for (uint i = 0; i < isPotential.size(); i++)
if (isPotential[i])
solver.assigns[i] = l_Undef;
}
void FindUndef::moveBinToNormal()
{
binPosition = solver.clauses.size();
for (uint i = 0; i != solver.binaryClauses.size(); i++)
solver.clauses.push(solver.binaryClauses[i]);
solver.binaryClauses.clear();
}
void FindUndef::moveBinFromNormal()
{
for (uint i = binPosition; i != solver.clauses.size(); i++)
solver.binaryClauses.push(solver.clauses[i]);
solver.clauses.shrink(solver.clauses.size() - binPosition);
}
const uint FindUndef::unRoll()
{
if (solver.decisionLevel() == 0) return 0;
moveBinToNormal();
dontLookAtClause.resize(solver.clauses.size(), false);
isPotential.resize(solver.nVars(), false);
fillPotential();
satisfies.resize(solver.nVars(), 0);
while(!updateTables()) {
assert(isPotentialSum > 0);
uint32_t maximum = 0;
Var v = var_Undef;
for (uint i = 0; i < isPotential.size(); i++) {
if (isPotential[i] && satisfies[i] >= maximum) {
maximum = satisfies[i];
v = i;
}
}
assert(v != var_Undef);
isPotential[v] = false;
isPotentialSum--;
std::fill(satisfies.begin(), satisfies.end(), 0);
}
unboundIsPotentials();
moveBinFromNormal();
return isPotentialSum;
}
bool FindUndef::updateTables()
{
bool allSat = true;
uint i = 0;
for (Clause** it = solver.clauses.getData(), **end = it + solver.clauses.size(); it != end; it++, i++) {
if (dontLookAtClause[i])
continue;
Clause& c = **it;
bool definitelyOK = false;
Var v = var_Undef;
uint numTrue = 0;
for (Lit *l = c.getData(), *end = l + c.size(); l != end; l++) {
if (solver.value(*l) == l_True) {
if (!isPotential[l->var()]) {
dontLookAtClause[i] = true;
definitelyOK = true;
break;
} else {
numTrue ++;
v = l->var();
}
}
}
if (definitelyOK)
continue;
if (numTrue == 1) {
assert(v != var_Undef);
isPotential[v] = false;
isPotentialSum--;
dontLookAtClause[i] = true;
continue;
}
//numTrue > 1
allSat = false;
for (Lit *l = c.getData(), *end = l + c.size(); l != end; l++) {
if (solver.value(*l) == l_True)
satisfies[l->var()]++;
}
}
return allSat;
}