14#include "llvm/ADT/ArrayRef.h"
15#include "llvm/ADT/SmallVector.h"
16#include "llvm/Support/SMTAPI.h"
27class Z3SATSolver :
public IncrementalSATSolver {
29 Z3SATSolver() : solver(
llvm::CreateZ3Solver()) {}
31 ~Z3SATSolver()
override { clearSolveScope(); }
33 void add(
int lit)
override {
36 addClauseInternal(clauseBuf);
41 const int absLit = std::abs(
lit);
42 if (absLit > maxVariable)
45 clauseBuf.push_back(
lit);
48 void assume(
int lit)
override {
52 assumptions.push_back(
lit);
55 Result
solve()
override {
58 solveScopeActive =
true;
59 for (
int lit : assumptions)
60 solver->addConstraint(literalToExpr(
lit));
62 auto result = solver->check();
64 return lastResult = kUNKNOWN;
65 return lastResult = (*result ? kSAT : kUNSAT);
68 int val(
int v)
const override {
69 if (lastResult != kSAT || v <= 0 || v > maxVariable)
71 llvm::APSInt value(llvm::APInt(1, 0),
true);
75 if (!solver->getInterpretation(variables[v - 1], value))
82 void reserveVars(
int maxVar)
override {
83 if (maxVar <= maxVariable)
85 while (
static_cast<int>(variables.size()) < maxVar)
91 void clearSolveScope() {
92 if (!solveScopeActive)
95 solveScopeActive =
false;
96 lastResult = kUNKNOWN;
100 int varIndex =
static_cast<int>(variables.size()) + 1;
101 std::string name =
"v" + std::to_string(varIndex);
102 variables.push_back(solver->mkSymbol(name.c_str(), solver->getBoolSort()));
106 llvm::SMTExprRef literalToExpr(
int lit) {
107 int absLit = std::abs(
lit);
110 auto *variable = variables[absLit - 1];
111 return lit > 0 ? variable : solver->mkNot(variable);
114 void addClauseInternal(llvm::ArrayRef<int> lits) {
116 solver->addConstraint(solver->mkBoolean(
false));
120 llvm::SMTExprRef clause =
nullptr;
121 for (
int lit : lits) {
124 auto *expr = literalToExpr(
lit);
125 clause = clause ? solver->mkOr(clause, expr) : expr;
129 solver->addConstraint(solver->mkBoolean(
false));
133 solver->addConstraint(clause);
136 llvm::SMTSolverRef solver;
137 llvm::SmallVector<llvm::SMTExprRef> variables;
138 llvm::SmallVector<int> assumptions, clauseBuf;
140 Result lastResult = kUNKNOWN;
141 bool solveScopeActive =
false;
149 return std::make_unique<Z3SATSolver>();
static void solve(Term *lhs, Term *rhs)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
std::unique_ptr< IncrementalSATSolver > createZ3SATSolver()
Construct a Z3-backed incremental IPASIR-style SAT solver.