Aim | Why |
---|---|
Bit Level Modelling | System level languages allow this granularity of access, and define behaviours at this level. |
Performance | Real programs generate many complex constraints, need to analyse these programs quickly enough to be sueful. |
[[SAT]] solvers could be used to implement this, however most applications generate constraints at a higher level than just boolean formulae (e.g. integers, integer comparison). |
Hence we use [[Satisfiability Modulo Theories]] and [[BitVectors]].
- Each block of memory is represented by an array of 8-bit [[BitVectors]] to allow constraints with bit-level accuracy.
- Operations on [[BitVectors]] include concatenation, extraction, bitwise operations and arithmetic.
- Eagre translation is used to simplify formulas at the theory level (e.g.
$x - x \equiv 0$ ) - Arithmetic can be encoded as a formula representing a circuit (e.g. a ripple-carry adder)
/// Read a value
fn read(a: &Array, i: Index) -> Value;
/// return a new array that is a copy of a, with v at index i
fn write(a: &Array, i: Index, v: Value) -> Array;
$$\begin{matrix*}
read(write(a, v, i), j) \Leftrightarrow ite(i = j, v, read(a, j))
\end{matrix*}$$
The write can be eliminated, instead just check if the
Can replace each syntactically-unique
- Expensive as it expands formulas by
$\cfrac{n(n-1)}{2}$ terms (where$n$ are the syntactically different indexes) to compare all indexes used.
For example: $$\begin{split} & (a[i_1] = e_1) \land (a[i_2] = e_2) \land (a[i_3] = e_3) \land (i_1 + i_2 + i_3 = 6) \ \to \ & (v_1 = e_1) \land (v_2 = e_2) \land (v_3 = e_3) \land (i_1 + i_2 + i_3 = 6) \ \to \ & (i_1 = i_2 \Rightarrow v_1 = v_2) \land (i_1 = i_3 \Rightarrow v_1 = v_3) \land (i_2 = i_3 \Rightarrow v_2 = v_3)\ \end{split}$$
When we cannot eliminate the array, we can [[TODO]]
[[Satisfiability Modulo Theories]] solving is NP-Complete and hence expensive, it is also invoked at every branch.
- [[70024 - Software Reliability/Constraint Solving#Eliminating Arrays|Elimination]] of constraints.
- Caching constraints and the values satisfying them.
- Constraint simplification
- Summarizing loops
Different solvers perform differently on different formulas, so we can invoke multiple and see which is the fastest.
Many conditions only rely on a small number of variables. We only need to include relevant constraints to a branch condition.
Lots of similar constraint sets for branches (e.g. in loops, the same constraints used many times).
b[k] > 0
We can add in constraints on the indices of b
that are in some value range.
b[k] > x
we can turn this into: