klee
Solver.cpp
Go to the documentation of this file.
1//===-- Solver.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
10#include "klee/Solver/Solver.h"
11
14
15using namespace klee;
16
17const char *Solver::validity_to_str(Validity v) {
18 switch (v) {
19 default: return "Unknown";
20 case True: return "True";
21 case False: return "False";
22 }
23}
24
26 delete impl;
27}
28
29char *Solver::getConstraintLog(const Query& query) {
30 return impl->getConstraintLog(query);
31}
32
34 impl->setCoreSolverTimeout(timeout);
35}
36
37bool Solver::evaluate(const Query& query, Validity &result) {
38 assert(query.expr->getWidth() == Expr::Bool && "Invalid expression type!");
39
40 // Maintain invariants implementations expect.
41 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(query.expr)) {
42 result = CE->isTrue() ? True : False;
43 return true;
44 }
45
46 return impl->computeValidity(query, result);
47}
48
49bool Solver::mustBeTrue(const Query& query, bool &result) {
50 assert(query.expr->getWidth() == Expr::Bool && "Invalid expression type!");
51
52 // Maintain invariants implementations expect.
53 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(query.expr)) {
54 result = CE->isTrue() ? true : false;
55 return true;
56 }
57
58 return impl->computeTruth(query, result);
59}
60
61bool Solver::mustBeFalse(const Query& query, bool &result) {
62 return mustBeTrue(query.negateExpr(), result);
63}
64
65bool Solver::mayBeTrue(const Query& query, bool &result) {
66 bool res;
67 if (!mustBeFalse(query, res))
68 return false;
69 result = !res;
70 return true;
71}
72
73bool Solver::mayBeFalse(const Query& query, bool &result) {
74 bool res;
75 if (!mustBeTrue(query, res))
76 return false;
77 result = !res;
78 return true;
79}
80
81bool Solver::getValue(const Query& query, ref<ConstantExpr> &result) {
82 // Maintain invariants implementation expect.
83 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(query.expr)) {
84 result = CE;
85 return true;
86 }
87
88 // FIXME: Push ConstantExpr requirement down.
89 ref<Expr> tmp;
90 if (!impl->computeValue(query, tmp))
91 return false;
92
93 result = cast<ConstantExpr>(tmp);
94 return true;
95}
96
97bool
99 const std::vector<const Array*> &objects,
100 std::vector< std::vector<unsigned char> > &values) {
101 bool hasSolution;
102 bool success =
103 impl->computeInitialValues(query, objects, values, hasSolution);
104 // FIXME: Propogate this out.
105 if (!hasSolution)
106 return false;
107
108 return success;
109}
110
111std::pair< ref<Expr>, ref<Expr> > Solver::getRange(const Query& query) {
112 ref<Expr> e = query.expr;
113 Expr::Width width = e->getWidth();
114 uint64_t min, max;
115
116 if (width==1) {
117 Solver::Validity result;
118 if (!evaluate(query, result))
119 assert(0 && "computeValidity failed");
120 switch (result) {
121 case Solver::True:
122 min = max = 1; break;
123 case Solver::False:
124 min = max = 0; break;
125 default:
126 min = 0, max = 1; break;
127 }
128 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(e)) {
129 min = max = CE->getZExtValue();
130 } else {
131 // binary search for # of useful bits
132 uint64_t lo=0, hi=width, mid, bits=0;
133 while (lo<hi) {
134 mid = lo + (hi - lo)/2;
135 bool res;
136 bool success =
137 mustBeTrue(query.withExpr(
138 EqExpr::create(LShrExpr::create(e,
140 width)),
141 ConstantExpr::create(0, width))),
142 res);
143
144 assert(success && "FIXME: Unhandled solver failure");
145 (void) success;
146
147 if (res) {
148 hi = mid;
149 } else {
150 lo = mid+1;
151 }
152
153 bits = lo;
154 }
155
156 // could binary search for training zeros and offset
157 // min max but unlikely to be very useful
158
159 // check common case
160 bool res = false;
161 bool success =
162 mayBeTrue(query.withExpr(EqExpr::create(e, ConstantExpr::create(0,
163 width))),
164 res);
165
166 assert(success && "FIXME: Unhandled solver failure");
167 (void) success;
168
169 if (res) {
170 min = 0;
171 } else {
172 // binary search for min
173 lo=0, hi=bits64::maxValueOfNBits(bits);
174 while (lo<hi) {
175 mid = lo + (hi - lo)/2;
176 bool res = false;
177 bool success =
178 mayBeTrue(query.withExpr(UleExpr::create(e,
180 width))),
181 res);
182
183 assert(success && "FIXME: Unhandled solver failure");
184 (void) success;
185
186 if (res) {
187 hi = mid;
188 } else {
189 lo = mid+1;
190 }
191 }
192
193 min = lo;
194 }
195
196 // binary search for max
197 lo=min, hi=bits64::maxValueOfNBits(bits);
198 while (lo<hi) {
199 mid = lo + (hi - lo)/2;
200 bool res;
201 bool success =
202 mustBeTrue(query.withExpr(UleExpr::create(e,
204 width))),
205 res);
206
207 assert(success && "FIXME: Unhandled solver failure");
208 (void) success;
209
210 if (res) {
211 hi = mid;
212 } else {
213 lo = mid+1;
214 }
215 }
216
217 max = lo;
218 }
219
220 return std::make_pair(ConstantExpr::create(min, width),
221 ConstantExpr::create(max, width));
222}
223
224void Query::dump() const {
225 llvm::errs() << "Constraints [\n";
226 for (const auto &constraint : constraints)
227 constraint->dump();
228
229 llvm::errs() << "]\n";
230 llvm::errs() << "Query [\n";
231 expr->dump();
232 llvm::errs() << "]\n";
233}
static ref< ConstantExpr > create(uint64_t v, Width w)
Definition: Expr.h:1079
virtual Width getWidth() const =0
unsigned Width
The type of an expression is simply its width, in bits.
Definition: Expr.h:97
static const Width Bool
Definition: Expr.h:100
void dump() const
dump - Print the expression to stderr.
Definition: Expr.cpp:330
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
bool evaluate(const Query &, Validity &result)
Definition: Solver.cpp:37
bool mayBeTrue(const Query &, bool &result)
Definition: Solver.cpp:65
bool mustBeTrue(const Query &, bool &result)
Definition: Solver.cpp:49
bool getValue(const Query &, ref< ConstantExpr > &result)
Definition: Solver.cpp:81
SolverImpl * impl
Definition: Solver.h:77
bool mayBeFalse(const Query &, bool &result)
Definition: Solver.cpp:73
bool getInitialValues(const Query &, const std::vector< const Array * > &objects, std::vector< std::vector< unsigned char > > &result)
Definition: Solver.cpp:98
bool mustBeFalse(const Query &, bool &result)
Definition: Solver.cpp:61
virtual ~Solver()
Definition: Solver.cpp:25
virtual void setCoreSolverTimeout(time::Span timeout)
Definition: Solver.cpp:33
virtual std::pair< ref< Expr >, ref< Expr > > getRange(const Query &)
Definition: Solver.cpp:111
virtual char * getConstraintLog(const Query &query)
Definition: Solver.cpp:29
Definition: Ref.h:82
uint64_t maxValueOfNBits(unsigned N)
Definition: Bits.h:70
Definition: main.cpp:291
ref< Expr > expr
Definition: Solver.h:35
Query withExpr(ref< Expr > _expr) const
withExpr - Return a copy of the query with the given expression.
Definition: Solver.h:42
const ConstraintSet & constraints
Definition: Solver.h:34
void dump() const
Dump query.
Definition: Solver.cpp:224
Query negateExpr() const
negateExpr - Return a copy of the query with the expression negated.
Definition: Solver.h:52