klee
AssignmentValidatingSolver.cpp
Go to the documentation of this file.
1//===-- AssignmentValidatingSolver.cpp ------------------------------------===//
2//
3// The KLEE Symbolic Virtual Machine
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
12#include "klee/Solver/Solver.h"
14
15#include <vector>
16
17namespace klee {
18
20private:
22 void dumpAssignmentQuery(const Query &query, const Assignment &assignment);
23
24public:
27
28 bool computeValidity(const Query &, Solver::Validity &result);
29 bool computeTruth(const Query &, bool &isValid);
30 bool computeValue(const Query &, ref<Expr> &result);
31 bool computeInitialValues(const Query &,
32 const std::vector<const Array *> &objects,
33 std::vector<std::vector<unsigned char> > &values,
34 bool &hasSolution);
36 char *getConstraintLog(const Query &);
37 void setCoreSolverTimeout(time::Span timeout);
38};
39
40// TODO: use computeInitialValues for all queries for more stress testing
42 Solver::Validity &result) {
43 return solver->impl->computeValidity(query, result);
44}
46 bool &isValid) {
47 return solver->impl->computeTruth(query, isValid);
48}
50 ref<Expr> &result) {
51 return solver->impl->computeValue(query, result);
52}
53
55 const Query &query, const std::vector<const Array *> &objects,
56 std::vector<std::vector<unsigned char> > &values, bool &hasSolution) {
57 bool success =
58 solver->impl->computeInitialValues(query, objects, values, hasSolution);
59 if (!hasSolution)
60 return success;
61
62 // Use `_allowFreeValues` so that if we are missing an assignment
63 // we can't compute a constant and flag this as a problem.
64 Assignment assignment(objects, values, /*_allowFreeValues=*/true);
65 // Check computed assignment satisfies query
66 for (const auto &constraint : query.constraints) {
67 ref<Expr> constraintEvaluated = assignment.evaluate(constraint);
68 ConstantExpr *CE = dyn_cast<ConstantExpr>(constraintEvaluated);
69 if (CE == NULL) {
70 llvm::errs() << "Constraint did not evalaute to a constant:\n";
71 llvm::errs() << "Constraint:\n" << constraint << "\n";
72 llvm::errs() << "Evaluated Constraint:\n" << constraintEvaluated << "\n";
73 llvm::errs() << "Assignment:\n";
74 assignment.dump();
75 dumpAssignmentQuery(query, assignment);
76 abort();
77 }
78 if (CE->isFalse()) {
79 llvm::errs() << "Constraint evaluated to false when using assignment\n";
80 llvm::errs() << "Constraint:\n" << constraint << "\n";
81 llvm::errs() << "Assignment:\n";
82 assignment.dump();
83 dumpAssignmentQuery(query, assignment);
84 abort();
85 }
86 }
87
88 ref<Expr> queryExprEvaluated = assignment.evaluate(query.expr);
89 ConstantExpr *CE = dyn_cast<ConstantExpr>(queryExprEvaluated);
90 if (CE == NULL) {
91 llvm::errs() << "Query expression did not evalaute to a constant:\n";
92 llvm::errs() << "Expression:\n" << query.expr << "\n";
93 llvm::errs() << "Evaluated expression:\n" << queryExprEvaluated << "\n";
94 llvm::errs() << "Assignment:\n";
95 assignment.dump();
96 dumpAssignmentQuery(query, assignment);
97 abort();
98 }
99 // KLEE queries are validity queries. A counter example to
100 // ∀ x constraints(x) → query(x)
101 // exists therefore
102 // ¬∀ x constraints(x) → query(x)
103 // Which is equivalent to
104 // ∃ x constraints(x) ∧ ¬ query(x)
105 // This means for the assignment we get back query expression should evaluate
106 // to false.
107 if (CE->isTrue()) {
108 llvm::errs()
109 << "Query Expression evaluated to true when using assignment\n";
110 llvm::errs() << "Expression:\n" << query.expr << "\n";
111 llvm::errs() << "Assignment:\n";
112 assignment.dump();
113 dumpAssignmentQuery(query, assignment);
114 abort();
115 }
116
117 return success;
118}
119
121 const Query &query, const Assignment &assignment) {
122 // Create a Query that is augmented with constraints that
123 // enforce the given assignment.
124 auto constraints = assignment.createConstraintsFromAssignment();
125
126 // Add Constraints from `query`
127 for (const auto &constraint : query.constraints)
128 constraints.push_back(constraint);
129
130 Query augmentedQuery(constraints, query.expr);
131
132 // Ask the solver for the log for this query.
133 char *logText = solver->getConstraintLog(augmentedQuery);
134 llvm::errs() << "Query with assignment as constraints:\n" << logText << "\n";
135 free(logText);
136}
137
141}
142
144 return solver->impl->getConstraintLog(query);
145}
146
148 return solver->impl->setCoreSolverTimeout(timeout);
149}
150
152 return new Solver(new AssignmentValidatingSolver(s));
153}
154}
bool computeValidity(const Query &, Solver::Validity &result)
bool computeValue(const Query &, ref< Expr > &result)
bool computeTruth(const Query &, bool &isValid)
SolverRunStatus getOperationStatusCode()
getOperationStatusCode - get the status of the last solver operation
void dumpAssignmentQuery(const Query &query, const Assignment &assignment)
bool computeInitialValues(const Query &, const std::vector< const Array * > &objects, std::vector< std::vector< unsigned char > > &values, bool &hasSolution)
ref< Expr > evaluate(const Array *mo, unsigned index) const
Definition: Assignment.h:69
ConstraintSet createConstraintsFromAssignment() const
Definition: Assignment.cpp:28
bool isTrue() const
isTrue - Is this the true expression.
Definition: Expr.h:1099
bool isFalse() const
isFalse - Is this the false expression.
Definition: Expr.h:1104
void push_back(const ref< Expr > &e)
SolverImpl - Abstract base clase for solver implementations.
Definition: SolverImpl.h:25
virtual void setCoreSolverTimeout(time::Span timeout)
Definition: SolverImpl.h:109
virtual bool computeTruth(const Query &query, bool &isValid)=0
virtual bool computeInitialValues(const Query &query, const std::vector< const Array * > &objects, std::vector< std::vector< unsigned char > > &values, bool &hasSolution)=0
virtual bool computeValue(const Query &query, ref< Expr > &result)=0
virtual char * getConstraintLog(const Query &query)
Definition: SolverImpl.h:104
virtual bool computeValidity(const Query &query, Solver::Validity &result)
Definition: SolverImpl.cpp:17
virtual SolverRunStatus getOperationStatusCode()=0
getOperationStatusCode - get the status of the last solver operation
SolverImpl * impl
Definition: Solver.h:77
virtual char * getConstraintLog(const Query &query)
Definition: Solver.cpp:29
Definition: main.cpp:291
Solver * createAssignmentValidatingSolver(Solver *s)
ref< Expr > expr
Definition: Solver.h:35
const ConstraintSet & constraints
Definition: Solver.h:34