Skip to content

Commit

Permalink
[feat, bitwuzla] getConstraintLog implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
S1eGa committed Nov 20, 2023
1 parent f2304ff commit f5859c6
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 4 deletions.
6 changes: 5 additions & 1 deletion include/klee/Expr/Constraints.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ class ConstraintSet {
bool isSymcretized(ref<Expr> expr) const;

void rewriteConcretization(const Assignment &a);
ConstraintSet withExpr(ref<Expr> e) const;
ConstraintSet withExpr(ref<Expr> e) const {
ConstraintSet copy = ConstraintSet(*this);
copy.addConstraint(e, Assignment());
return copy;
}

std::vector<const Array *> gatherArrays() const;
std::vector<const Array *> gatherSymcretizedArrays() const;
Expand Down
4 changes: 4 additions & 0 deletions lib/Solver/BitwuzlaBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ class BitwuzlaBuilder {
// these.
std::vector<Term> sideConstraints;

std::string symbolOf(const Array *array) {
return getInitialArray(array).symbol().value();
}

BitwuzlaBuilder(bool autoClearConstructCache);
~BitwuzlaBuilder();

Expand Down
49 changes: 46 additions & 3 deletions lib/Solver/BitwuzlaSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ struct BitwuzlaSolverEnv {
inc_umap<const Array *, ExprHashSet> usedArrayBytes;
ExprIncSet symbolicObjects;

explicit BitwuzlaSolverEnv(){};
explicit BitwuzlaSolverEnv() = default;
explicit BitwuzlaSolverEnv(const arr_vec &objects);

void pop(size_t popSize);
Expand All @@ -180,7 +180,7 @@ struct BitwuzlaSolverEnv {
const arr_vec *getObjectsForGetModel(ObjectAssignment oa) const;
};

BitwuzlaSolverEnv::BitwuzlaSolverEnv(const std::vector<const Array *> &objects)
BitwuzlaSolverEnv::BitwuzlaSolverEnv(const arr_vec &objects)
: objectsForGetModel(objects) {}

void BitwuzlaSolverEnv::pop(size_t popSize) {
Expand Down Expand Up @@ -314,7 +314,50 @@ BitwuzlaSolverImpl::BitwuzlaSolverImpl()
}

char *BitwuzlaSolverImpl::getConstraintLog(const Query &query) {
return strdup("unimplemented");
std::stringstream outputLog;

// We use a different builder here because we don't want to interfere
// with the solver's builder because it may change the solver builder's
// cache.
// NOTE: The builder does not set `z3LogInteractionFile` to avoid conflicting
// with whatever the solver's builder is set to do.
std::unique_ptr<BitwuzlaBuilder> tempBuilder(new BitwuzlaBuilder(false));
ConstantArrayFinder constant_arrays_in_query;

for (const auto array :
query.constraints.withExpr(query.expr).gatherArrays()) {
outputLog << "(declare-fun " << tempBuilder->symbolOf(array)
<< " () (Array (_ BitVec " << array->getDomain() << ") (_ BitVec "
<< array->getRange() << ")))\n";
}

for (auto const &constraint : query.constraints.cs()) {
outputLog << "(assert " << tempBuilder->construct(constraint).str(10)
<< ")\n";
constant_arrays_in_query.visit(constraint);
}

// KLEE Queries are validity queries i.e.
// ∀ X Constraints(X) → query(X)
// but Z3 works in terms of satisfiability so instead we ask the
// the negation of the equivalent i.e.
// ∃ X Constraints(X) ∧ ¬ query(X)
Term formula = mk_term(Kind::NOT, {tempBuilder->construct(query.expr)});
constant_arrays_in_query.visit(query.expr);

for (auto const &constant_array : constant_arrays_in_query.results) {
for (auto const &arrayIndexValueExpr :
tempBuilder->constant_array_assertions[constant_array]) {
outputLog << "(assert " << arrayIndexValueExpr.str(10) << ")\n";
}
}

outputLog << "(assert " << formula.str(10) << ")\n";
outputLog << "(check-sat)"
<< "\n";

// Client is responsible for freeing the returned C-string
return strdup(outputLog.str().c_str());
}

bool BitwuzlaSolverImpl::computeTruth(const ConstraintQuery &query,
Expand Down

0 comments on commit f5859c6

Please sign in to comment.