mirror of https://github.com/YosysHQ/yosys.git
Added support for Minisat::SimpSolver + ezSAT frezze() API
This commit is contained in:
parent
b76528d8a5
commit
dab1612f81
|
@ -72,6 +72,7 @@ struct SatGen
|
||||||
} else {
|
} else {
|
||||||
std::string name = pf + stringf(c.wire->width == 1 ? "%s" : "%s [%d]", RTLIL::id2cstr(c.wire->name), c.offset);
|
std::string name = pf + stringf(c.wire->width == 1 ? "%s" : "%s [%d]", RTLIL::id2cstr(c.wire->name), c.offset);
|
||||||
vec.push_back(ez->literal(name));
|
vec.push_back(ez->literal(name));
|
||||||
|
ez->freeze(vec.back());
|
||||||
}
|
}
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,19 @@ void ezMiniSAT::clear()
|
||||||
}
|
}
|
||||||
foundContradiction = false;
|
foundContradiction = false;
|
||||||
minisatVars.clear();
|
minisatVars.clear();
|
||||||
|
#if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL
|
||||||
|
cnfFrozenVars.clear();
|
||||||
|
#endif
|
||||||
ezSAT::clear();
|
ezSAT::clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL
|
||||||
|
void ezMiniSAT::freeze(int id)
|
||||||
|
{
|
||||||
|
cnfFrozenVars.insert(bind(id));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ezMiniSAT *ezMiniSAT::alarmHandlerThis = NULL;
|
ezMiniSAT *ezMiniSAT::alarmHandlerThis = NULL;
|
||||||
clock_t ezMiniSAT::alarmHandlerTimeout = 0;
|
clock_t ezMiniSAT::alarmHandlerTimeout = 0;
|
||||||
|
|
||||||
|
@ -92,7 +102,7 @@ contradiction:
|
||||||
modelIdx.push_back(bind(id));
|
modelIdx.push_back(bind(id));
|
||||||
|
|
||||||
if (minisatSolver == NULL) {
|
if (minisatSolver == NULL) {
|
||||||
minisatSolver = new EZMINISAT_SOLVER;
|
minisatSolver = new Solver;
|
||||||
minisatSolver->verbosity = EZMINISAT_VERBOSITY;
|
minisatSolver->verbosity = EZMINISAT_VERBOSITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,13 +116,27 @@ contradiction:
|
||||||
while (int(minisatVars.size()) < numCnfVariables())
|
while (int(minisatVars.size()) < numCnfVariables())
|
||||||
minisatVars.push_back(minisatSolver->newVar());
|
minisatVars.push_back(minisatSolver->newVar());
|
||||||
|
|
||||||
|
#if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL
|
||||||
|
for (auto idx : cnfFrozenVars)
|
||||||
|
minisatSolver->setFrozen(minisatVars.at(idx > 0 ? idx-1 : -idx-1), true);
|
||||||
|
cnfFrozenVars.clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
for (auto &clause : cnf) {
|
for (auto &clause : cnf) {
|
||||||
Minisat::vec<Minisat::Lit> ps;
|
Minisat::vec<Minisat::Lit> ps;
|
||||||
for (auto idx : clause)
|
for (auto idx : clause) {
|
||||||
if (idx > 0)
|
if (idx > 0)
|
||||||
ps.push(Minisat::mkLit(minisatVars.at(idx-1)));
|
ps.push(Minisat::mkLit(minisatVars.at(idx-1)));
|
||||||
else
|
else
|
||||||
ps.push(Minisat::mkLit(minisatVars.at(-idx-1), true));
|
ps.push(Minisat::mkLit(minisatVars.at(-idx-1), true));
|
||||||
|
#if EZMINISAT_SIMPSOLVER
|
||||||
|
if (minisatSolver->isEliminated(minisatVars.at(idx > 0 ? idx-1 : -idx-1))) {
|
||||||
|
fprintf(stderr, "Assert in %s:%d failed! Missing call to ezsat->freeze(): %s (lit=%d)\n",
|
||||||
|
__FILE__, __LINE__, cnfLiteralInfo(idx).c_str(), idx);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
if (!minisatSolver->addClause(ps))
|
if (!minisatSolver->addClause(ps))
|
||||||
goto contradiction;
|
goto contradiction;
|
||||||
}
|
}
|
||||||
|
@ -122,11 +146,18 @@ contradiction:
|
||||||
|
|
||||||
Minisat::vec<Minisat::Lit> assumps;
|
Minisat::vec<Minisat::Lit> assumps;
|
||||||
|
|
||||||
for (auto idx : extraClauses)
|
for (auto idx : extraClauses) {
|
||||||
if (idx > 0)
|
if (idx > 0)
|
||||||
assumps.push(Minisat::mkLit(minisatVars.at(idx-1)));
|
assumps.push(Minisat::mkLit(minisatVars.at(idx-1)));
|
||||||
else
|
else
|
||||||
assumps.push(Minisat::mkLit(minisatVars.at(-idx-1), true));
|
assumps.push(Minisat::mkLit(minisatVars.at(-idx-1), true));
|
||||||
|
#if EZMINISAT_SIMPSOLVER
|
||||||
|
if (minisatSolver->isEliminated(minisatVars.at(idx > 0 ? idx-1 : -idx-1))) {
|
||||||
|
fprintf(stderr, "Assert in %s:%d failed! Missing call to ezsat->freeze(): %s\n", __FILE__, __LINE__, cnfLiteralInfo(idx).c_str());
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
sighandler_t old_alarm_sighandler = NULL;
|
sighandler_t old_alarm_sighandler = NULL;
|
||||||
int old_alarm_timeout = 0;
|
int old_alarm_timeout = 0;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#ifndef EZMINISAT_H
|
#ifndef EZMINISAT_H
|
||||||
#define EZMINISAT_H
|
#define EZMINISAT_H
|
||||||
|
|
||||||
#define EZMINISAT_SOLVER Minisat::Solver
|
#define EZMINISAT_SIMPSOLVER 0
|
||||||
#define EZMINISAT_VERBOSITY 0
|
#define EZMINISAT_VERBOSITY 0
|
||||||
#define EZMINISAT_INCREMENTAL 1
|
#define EZMINISAT_INCREMENTAL 1
|
||||||
|
|
||||||
|
@ -38,10 +38,19 @@ namespace Minisat {
|
||||||
class ezMiniSAT : public ezSAT
|
class ezMiniSAT : public ezSAT
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
EZMINISAT_SOLVER *minisatSolver;
|
#if EZMINISAT_SIMPSOLVER
|
||||||
|
typedef Minisat::SimpSolver Solver;
|
||||||
|
#else
|
||||||
|
typedef Minisat::Solver Solver;
|
||||||
|
#endif
|
||||||
|
Solver *minisatSolver;
|
||||||
std::vector<int> minisatVars;
|
std::vector<int> minisatVars;
|
||||||
bool foundContradiction;
|
bool foundContradiction;
|
||||||
|
|
||||||
|
#if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL
|
||||||
|
std::set<int> cnfFrozenVars;
|
||||||
|
#endif
|
||||||
|
|
||||||
static ezMiniSAT *alarmHandlerThis;
|
static ezMiniSAT *alarmHandlerThis;
|
||||||
static clock_t alarmHandlerTimeout;
|
static clock_t alarmHandlerTimeout;
|
||||||
static void alarmHandler(int);
|
static void alarmHandler(int);
|
||||||
|
@ -50,6 +59,9 @@ public:
|
||||||
ezMiniSAT();
|
ezMiniSAT();
|
||||||
virtual ~ezMiniSAT();
|
virtual ~ezMiniSAT();
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
#if EZMINISAT_SIMPSOLVER && EZMINISAT_INCREMENTAL
|
||||||
|
virtual void freeze(int id);
|
||||||
|
#endif
|
||||||
virtual bool solver(const std::vector<int> &modelExpressions, std::vector<bool> &modelValues, const std::vector<int> &assumptions);
|
virtual bool solver(const std::vector<int> &modelExpressions, std::vector<bool> &modelValues, const std::vector<int> &assumptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,18 +29,18 @@ const int ezSAT::FALSE = 2;
|
||||||
|
|
||||||
ezSAT::ezSAT()
|
ezSAT::ezSAT()
|
||||||
{
|
{
|
||||||
literal("TRUE");
|
|
||||||
literal("FALSE");
|
|
||||||
|
|
||||||
assert(literal("TRUE") == TRUE);
|
|
||||||
assert(literal("FALSE") == FALSE);
|
|
||||||
|
|
||||||
cnfConsumed = false;
|
cnfConsumed = false;
|
||||||
cnfVariableCount = 0;
|
cnfVariableCount = 0;
|
||||||
cnfClausesCount = 0;
|
cnfClausesCount = 0;
|
||||||
|
|
||||||
solverTimeout = 0;
|
solverTimeout = 0;
|
||||||
solverTimoutStatus = false;
|
solverTimoutStatus = false;
|
||||||
|
|
||||||
|
freeze(literal("TRUE"));
|
||||||
|
freeze(literal("FALSE"));
|
||||||
|
|
||||||
|
assert(literal("TRUE") == TRUE);
|
||||||
|
assert(literal("FALSE") == FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ezSAT::~ezSAT()
|
ezSAT::~ezSAT()
|
||||||
|
@ -345,6 +345,10 @@ void ezSAT::clear()
|
||||||
cnfAssumptions.clear();
|
cnfAssumptions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ezSAT::freeze(int)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void ezSAT::assume(int id)
|
void ezSAT::assume(int id)
|
||||||
{
|
{
|
||||||
cnfAssumptions.insert(id);
|
cnfAssumptions.insert(id);
|
||||||
|
@ -462,6 +466,23 @@ int ezSAT::bound(int id) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ezSAT::cnfLiteralInfo(int idx) const
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < cnfLiteralVariables.size(); i++) {
|
||||||
|
if (cnfLiteralVariables[i] == idx)
|
||||||
|
return to_string(i+1);
|
||||||
|
if (cnfLiteralVariables[i] == -idx)
|
||||||
|
return "NOT " + to_string(i+1);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < cnfExpressionVariables.size(); i++) {
|
||||||
|
if (cnfExpressionVariables[i] == idx)
|
||||||
|
return to_string(-i-1);
|
||||||
|
if (cnfExpressionVariables[i] == -idx)
|
||||||
|
return "NOT " + to_string(-i-1);
|
||||||
|
}
|
||||||
|
return "<unnamed>";
|
||||||
|
}
|
||||||
|
|
||||||
int ezSAT::bind(int id)
|
int ezSAT::bind(int id)
|
||||||
{
|
{
|
||||||
if (id >= 0) {
|
if (id >= 0) {
|
||||||
|
|
|
@ -141,6 +141,7 @@ public:
|
||||||
// manage CNF (usually only accessed by SAT solvers)
|
// manage CNF (usually only accessed by SAT solvers)
|
||||||
|
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
virtual void freeze(int id);
|
||||||
void assume(int id);
|
void assume(int id);
|
||||||
int bind(int id);
|
int bind(int id);
|
||||||
|
|
||||||
|
@ -154,6 +155,8 @@ public:
|
||||||
void consumeCnf();
|
void consumeCnf();
|
||||||
void consumeCnf(std::vector<std::vector<int>> &cnf);
|
void consumeCnf(std::vector<std::vector<int>> &cnf);
|
||||||
|
|
||||||
|
std::string cnfLiteralInfo(int idx) const;
|
||||||
|
|
||||||
// simple helpers for build expressions easily
|
// simple helpers for build expressions easily
|
||||||
|
|
||||||
struct _V {
|
struct _V {
|
||||||
|
|
Loading…
Reference in New Issue