This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/bee/cryptominisat-2.5.1/Solver/ClauseCleaner.cpp
Vitor Santos Costa 16015bd8e6 bee
2019-04-22 12:15:21 +01:00

417 lines
12 KiB
C++
Executable File

/***********************************************************************************
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 <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "ClauseCleaner.h"
#include "VarReplacer.h"
#ifdef _MSC_VER
#define __builtin_prefetch(a,b,c)
#endif //_MSC_VER
//#define DEBUG_CLEAN
//#define VERBOSE_DEBUG
ClauseCleaner::ClauseCleaner(Solver& _solver) :
solver(_solver)
{
for (uint i = 0; i < 6; i++) {
lastNumUnitarySat[i] = solver.get_unitary_learnts_num();
lastNumUnitaryClean[i] = solver.get_unitary_learnts_num();
}
}
void ClauseCleaner::removeSatisfied(vec<XorClause*>& cs, ClauseSetType type, const uint limit)
{
#ifdef DEBUG_CLEAN
assert(solver.decisionLevel() == 0);
#endif
if (lastNumUnitarySat[type] + limit >= solver.get_unitary_learnts_num())
return;
uint32_t i,j;
for (i = j = 0; i < cs.size(); i++) {
if (satisfied(*cs[i]))
solver.removeClause(*cs[i]);
else
cs[j++] = cs[i];
}
cs.shrink(i - j);
lastNumUnitarySat[type] = solver.get_unitary_learnts_num();
}
void ClauseCleaner::removeSatisfied(vec<Clause*>& cs, ClauseSetType type, const uint limit)
{
#ifdef DEBUG_CLEAN
assert(solver.decisionLevel() == 0);
#endif
if (lastNumUnitarySat[type] + limit >= solver.get_unitary_learnts_num())
return;
Clause **i,**j, **end;
for (i = j = cs.getData(), end = i + cs.size(); i != end; i++) {
if (i+1 != end)
__builtin_prefetch(*(i+1), 0, 0);
if (satisfied(**i))
solver.removeClause(**i);
else
*j++ = *i;
}
cs.shrink(i - j);
lastNumUnitarySat[type] = solver.get_unitary_learnts_num();
}
void ClauseCleaner::cleanClauses(vec<Clause*>& cs, ClauseSetType type, const uint limit)
{
assert(solver.decisionLevel() == 0);
assert(solver.qhead == solver.trail.size());
if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
return;
#ifdef VERBOSE_DEBUG
std::cout << "Cleaning " << (type==binaryClauses ? "binaryClauses" : "normal clauses" ) << std::endl;
#endif //VERBOSE_DEBUG
Clause **s, **ss, **end;
for (s = ss = cs.getData(), end = s + cs.size(); s != end;) {
if (s+1 != end)
__builtin_prefetch(*(s+1), 1, 0);
if (cleanClause(*s)) {
clauseFree(*s);
s++;
} else if (type != ClauseCleaner::binaryClauses && (*s)->size() == 2) {
solver.binaryClauses.push(*s);
solver.becameBinary++;
s++;
} else {
*ss++ = *s++;
}
}
cs.shrink(s-ss);
lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
#ifdef VERBOSE_DEBUG
cout << "cleanClauses(Clause) useful ?? Removed: " << s-ss << endl;
#endif
}
inline const bool ClauseCleaner::cleanClause(Clause*& cc)
{
Clause& c = *cc;
Lit origLit1 = c[0];
Lit origLit2 = c[1];
uint32_t origSize = c.size();
Lit *i, *j, *end;
for (i = j = c.getData(), end = i + c.size(); i != end; i++) {
lbool val = solver.value(*i);
if (val == l_Undef) {
*j++ = *i;
continue;
}
if (val == l_True) {
solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
return true;
}
}
c.shrink(i-j);
if (i != j) {
c.setStrenghtened();
if (c.size() == 2) {
solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
Clause *c2 = Clause_new(c);
clauseFree(&c);
cc = c2;
solver.attachClause(*c2);
/*} else if (c.size() == 3) {
solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
Clause *c2 = Clause_new(c);
clauseFree(&c);
cc = c2;
solver.attachClause(*c2);*/
} else {
if (c.learnt())
solver.learnts_literals -= i-j;
else
solver.clauses_literals -= i-j;
}
}
return false;
}
void ClauseCleaner::cleanClauses(vec<XorClause*>& cs, ClauseSetType type, const uint limit)
{
assert(solver.decisionLevel() == 0);
assert(solver.qhead == solver.trail.size());
if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
return;
XorClause **s, **ss, **end;
for (s = ss = cs.getData(), end = s + cs.size(); s != end; s++) {
if (s+1 != end)
__builtin_prefetch(*(s+1), 1, 0);
#ifdef DEBUG_ATTACH
assert(find(solver.xorwatches[(**s)[0].var()], *s));
assert(find(solver.xorwatches[(**s)[1].var()], *s));
if (solver.assigns[(**s)[0].var()]!=l_Undef || solver.assigns[(**s)[1].var()]!=l_Undef) {
satisfied(**s);
}
#endif //DEBUG_ATTACH
if (cleanClause(**s)) {
solver.freeLater.push(*s);
(*s)->setRemoved();
} else {
#ifdef DEBUG_ATTACH
assert(find(solver.xorwatches[(**s)[0].var()], *s));
assert(find(solver.xorwatches[(**s)[1].var()], *s));
#endif //DEBUG_ATTACH
*ss++ = *s;
}
}
cs.shrink(s-ss);
lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
#ifdef VERBOSE_DEBUG
cout << "cleanClauses(XorClause) useful: ?? Removed: " << s-ss << endl;
#endif
}
inline const bool ClauseCleaner::cleanClause(XorClause& c)
{
Lit *i, *j, *end;
Var origVar1 = c[0].var();
Var origVar2 = c[1].var();
uint32_t origSize = c.size();
for (i = j = c.getData(), end = i + c.size(); i != end; i++) {
const lbool& val = solver.assigns[i->var()];
if (val.isUndef()) {
*j = *i;
j++;
} else c.invert(val.getBool());
}
c.shrink(i-j);
assert(c.size() != 1);
switch (c.size()) {
case 0: {
solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
return true;
}
case 2: {
c[0] = c[0].unsign();
c[1] = c[1].unsign();
solver.varReplacer->replace(c, c.xor_clause_inverted(), c.getGroup());
solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
return true;
}
default: {
if (i-j > 0) {
c.setStrenghtened();
solver.clauses_literals -= i-j;
}
return false;
}
}
assert(false);
return false;
}
void ClauseCleaner::cleanClausesBewareNULL(vec<ClauseSimp>& cs, ClauseCleaner::ClauseSetType type, Subsumer& subs, const uint limit)
{
assert(solver.decisionLevel() == 0);
assert(solver.qhead == solver.trail.size());
if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
return;
ClauseSimp *s, *end;
for (s = cs.getData(), end = s + cs.size(); s != end; s++) {
if (s+1 != end)
__builtin_prefetch((s+1)->clause, 1, 0);
if (s->clause == NULL)
continue;
if (cleanClauseBewareNULL(*s, subs)) {
continue;
} else if (s->clause->size() == 2)
solver.becameBinary++;
}
lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
}
inline const bool ClauseCleaner::cleanClauseBewareNULL(ClauseSimp cc, Subsumer& subs)
{
Clause& c = *cc.clause;
vec<Lit> origClause(c.size());
memcpy(origClause.getData(), c.getData(), sizeof(Lit)*c.size());
Lit *i, *j, *end;
for (i = j = c.getData(), end = i + c.size(); i != end; i++) {
lbool val = solver.value(*i);
if (val == l_Undef) {
*j++ = *i;
continue;
}
if (val == l_True) {
subs.unlinkModifiedClause(origClause, cc);
clauseFree(cc.clause);
return true;
}
}
if (i != j) {
c.setStrenghtened();
if (origClause.size() > 2 && origClause.size()-(i-j) == 2) {
subs.unlinkModifiedClause(origClause, cc);
subs.clauses[cc.index] = cc;
c.shrink(i-j);
solver.attachClause(c);
subs.linkInAlreadyClause(cc);
} else {
c.shrink(i-j);
subs.unlinkModifiedClauseNoDetachNoNULL(origClause, cc);
subs.linkInAlreadyClause(cc);
if (c.learnt())
solver.learnts_literals -= i-j;
else
solver.clauses_literals -= i-j;
}
c.calcAbstraction();
subs.updateClause(cc);
}
return false;
}
void ClauseCleaner::cleanXorClausesBewareNULL(vec<XorClauseSimp>& cs, ClauseCleaner::ClauseSetType type, XorSubsumer& subs, const uint limit)
{
assert(solver.decisionLevel() == 0);
assert(solver.qhead == solver.trail.size());
if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
return;
XorClauseSimp *s, *end;
for (s = cs.getData(), end = s + cs.size(); s != end; s++) {
if (s+1 != end)
__builtin_prefetch((s+1)->clause, 1, 0);
if (s->clause == NULL)
continue;
cleanXorClauseBewareNULL(*s, subs);
}
lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
}
inline const bool ClauseCleaner::cleanXorClauseBewareNULL(XorClauseSimp cc, XorSubsumer& subs)
{
XorClause& c = *cc.clause;
vec<Lit> origClause(c.size());
memcpy(origClause.getData(), c.getData(), sizeof(Lit)*c.size());
Lit *i, *j, *end;
for (i = j = c.getData(), end = i + c.size(); i != end; i++) {
const lbool& val = solver.assigns[i->var()];
if (val.isUndef()) {
*j = *i;
j++;
} else c.invert(val.getBool());
}
c.shrink(i-j);
switch(c.size()) {
case 0: {
subs.unlinkModifiedClause(origClause, cc);
clauseFree(cc.clause);
return true;
}
case 2: {
vec<Lit> ps(2);
ps[0] = c[0].unsign();
ps[1] = c[1].unsign();
solver.varReplacer->replace(ps, c.xor_clause_inverted(), c.getGroup());
subs.unlinkModifiedClause(origClause, cc);
clauseFree(cc.clause);
return true;
}
default:
if (i-j > 0) {
subs.unlinkModifiedClauseNoDetachNoNULL(origClause, cc);
subs.linkInAlreadyClause(cc);
c.calcXorAbstraction();
}
}
return false;
}
bool ClauseCleaner::satisfied(const Clause& c) const
{
for (uint i = 0; i != c.size(); i++)
if (solver.value(c[i]) == l_True)
return true;
return false;
}
bool ClauseCleaner::satisfied(const XorClause& c) const
{
bool final = c.xor_clause_inverted();
for (uint k = 0; k != c.size(); k++ ) {
const lbool& val = solver.assigns[c[k].var()];
if (val.isUndef()) return false;
final ^= val.getBool();
}
return final;
}
void ClauseCleaner::moveBinClausesToBinClauses()
{
assert(solver.decisionLevel() == 0);
assert(solver.qhead == solver.trail.size());
vec<Clause*>& cs = solver.clauses;
Clause **s, **ss, **end;
for (s = ss = cs.getData(), end = s + cs.size(); s != end; s++) {
if (s+1 != end)
__builtin_prefetch(*(s+1), 1, 0);
if ((**s).size() == 2) {
(**s).setUnsorted();
solver.binaryClauses.push(*s);
} else
*ss++ = *s;
}
cs.shrink(s-ss);
}