1 Introduction
1.1 Contributions
- We prove our algorithms correct and show how proofs for existing closure algorithms can be simplified, paving the way for mechanised formalisation. (To keep the length of the paper manageable, the proofs are relegated to “Appendix A”. The exception is Lemma 6.1 since the argument is itself a significant conceptual advance, hence is included in the body of the paper.)
- We give detailed proofs for in-place versions of our algorithms (Sect. 7).
- We implement these new algorithms which show significant performance improvements over existing closure algorithms in real-world setting (Sect. 8).
2 Related work
3 Preliminaries
3.1 The octagon domain and its representation
3.2 Definitions of closure
- \(\forall i. {\mathbf {m}}_{i,i} = 0\)
- \(\forall i,j,k. {\mathbf {m}}_{i,j} \le {\mathbf {m}}_{i,k} + {\mathbf {m}}_{k,j}\)
- \(\mathbf {m}\) is closed
- \(\forall i,j .{\mathbf {m}}_{i,j} \le {\mathbf {m}}_{i,\bar{\imath }}/2 + {\mathbf {m}}_{\bar{\jmath },j}/2\)
- \(\mathbf {m}\) is strongly closed
- \(\forall i. {\mathbf {m}}_{i,\bar{\imath }}\;\text {is even}\)
- \(\forall i . {\mathbf {m}}_{i,i} = 0\)
- \(\forall i,j,k. {\mathbf {m}}_{i,k} + {\mathbf {m}}_{k,j} \ge \min ({\mathbf {m}}_{i,j}, {\mathbf {m}}_{i,\bar{\imath }}/2 + {\mathbf {m}}_{\bar{\jmath },j}/2)\)
3.3 High-level overview
4 Incremental closure
4.1 Classical incremental closure
4.2 Improved incremental closure
- \({\mathbf {m}}_{b,a} + d \ge 0\)
- \({\mathbf {m}}_{\bar{a},\bar{b}} + d \ge 0\)
- \({\mathbf {m}}_{\bar{a},a} + d + {\mathbf {m}}_{b,\bar{b}} + d \ge 0\)
- \({\mathbf {m}}_{b,a} + d < 0\) or
- \({\mathbf {m}}_{\bar{a},\bar{b}} + d < 0\) or
- \({\mathbf {m}}_{b,\bar{b}} + d + {\mathbf {m}}_{\bar{a},a} + d < 0\)
4.3 Properties of incremental closure
5 Incremental strong closure
5.1 Classical strong closure
5.2 Properties of strong closure
5.3 Incremental strong closure
6 Incremental tight closure
6.1 Properties of tight closure
7 In-place update
7.1 In-place incremental closure
- \({\mathbf {m'}}_{i,j} \le {\mathbf {m'}}_{i,a} + d + {\mathbf {m'}}_{b,j}\)
- \({\mathbf {m'}}_{i,j} \le {\mathbf {m'}}_{i,\bar{b}} + d + {\mathbf {m'}}_{\bar{a},j}\)
- \({\mathbf {m'}}_{i,j} \le {\mathbf {m'}}_{i,\bar{b}} + d + {\mathbf {m'}}_{\bar{a},a} + d + {\mathbf {m'}}_{b,j}\)
- \({\mathbf {m'}}_{i,j} \le {\mathbf {m'}}_{i,a} + d + {\mathbf {m'}}_{b,\bar{b}} + d + {\mathbf {m'}}_{\bar{a},j}\)
- \(\forall 0 \le \ell < k. \mathbf {m^{k}_{\rho ^{-1}(\ell )}} = \mathbf {m'_{\rho ^{-1}(\ell )}}\)
- \(\forall k \le \ell < 4n^2. \mathbf {m^{k}_{\rho ^{-1}(\ell )}} = \mathbf {m_{\rho ^{-1}(\ell )}}\)
7.2 In-place incremental strong closure
- \(\forall 0 \le \ell < k. \mathbf {m^{k}_{\rho ^{-1}(\ell )}} = \mathbf {m''_{\rho ^{-1}(\ell )}}\)
- \(\forall k \le \ell < 4n^2. \mathbf {m^{k}_{\rho ^{-1}(\ell )}} = \mathbf {m_{\rho ^{-1}(\ell )}}\)
7.3 In-place incremental tight closure
- \(\forall 0 \le \ell < k. \mathbf {m^{k}_{\rho ^{-1}(\ell )}} = \mathbf {m'''_{\rho ^{-1}(\ell )}}\)
- \(\forall k \le \ell < 4n^2. \mathbf {m^{k}_{\rho ^{-1}(\ell )}} = \mathbf {m_{\rho ^{-1}(\ell )}}\)
8 Experimental evaluation
8.1 Apron library
bound_t
, which depending on compile-time options, will select a specific header file containing concrete implementations of operations involving numbers extended to the symbolic values of \(-\,\infty \) and \(+\,\infty \). Every bound_t
object has to be initialised via a call to bound_init
, which in the case of rationals will invoke malloc
and initialise space for the rational number. DBMs are stored taking advantage of the half-matrix nature of octagonal DBMs which follows by the definition of coherence. An array of bound_t
objects is then used to represent the half-matrix, as shown in Fig. 16, subfigure (1). If \(i\ge j\) or \(i=\bar{\jmath }\) then the entry at (i, j) in the DBM is stored at index \(j + \lfloor i^2 / 2\rfloor \) in the array. Otherwise (i, j) is stored at the array element reserved for entry \((\bar{\jmath }, \bar{\imath })\). A DBM of size n requires an array of size \(2n(n+1)\) which gives a significant space reduction over a naive representation of size \(4n^2\).8.2 Compact DBMs
malloc
-like routines. In response, the underlying DBM data structure was refactored to ensure that this undesirable memory management feature did not artificially perturb the experiments. The refactoring is fully described in a separate work [9], but to keep the paper self-contained the main idea is summarised in the following paragraph.8.3 Micro-benchmarks
Name | Benchmark | LOC | Description |
---|---|---|---|
lev | levenstein | 187 | Levenstein string distance library |
sol | solitaire | 334 | Card cipher |
2048 | 2048 | 435 | 2048 game |
kh | khash | 652 | Hash code from klib C library |
taes | Tiny-AES | 813 | Portable AES-128 implementation |
qlz | qlz | 1168 | Fast compression library |
mod | libmodbus | 7685 | Library to interact with Modbus protocol |
mgmp | mini-gmp | 11,787 | Subset of GMP library |
unq | unqlite | 64,795 | Embedded NoSQL DB |
bzip | bzip-single-file | 74,017 | bzip single file for static analysis benchmarking |
8.4 Frama-C benchmarks
Benchmark | Apron | IncClose | DBM IncStrongClose | IncClose | CoDBM IncStrongClose |
---|---|---|---|---|---|
lev | 33.16 | 14.98 | 14.21 | 9.23 | 9.05 |
sol | 49.80 | 49.76 | 49.19 | 26.17 | 26.03 |
2048 | 33.16 | 26.10 | 26.26 | 13.39 | 13.23 |
kh | 1.80 | 1.37 | 1.40 | 1.00 | 1.02 |
taes | 1817.91 | 814.77 | 810.00 | 430.60 | 421.32 |
qlz | 1.08 | 1.21 | 1.18 | 1.08 | 1.20 |
mod | 463.46 | 343.05 | 349.62 | 141.17 | 138.60 |
mgmp | 2.09 | 1.97 | 2.03 | 1.21 | 1.18 |
unq | 1.49 | 1.49 | 1.46 | 1.49 | 1.42 |
bzip | 621.53 | 607.88 | 602.78 | 53.51 | 52.63 |
cumulative | 3025.48 | 1862.58 | 1858.13 | 678.85 | 665.68 |
Benchmark | Apron | IncClose | DBM IncStrongClose | ||
---|---|---|---|---|---|
lev | 2.61 | 2.46 | 2.47 | ||
sol | 12.62 | 12.99 | 13.00 | ||
2048 | 4.48 | 4.48 | 4.44 | ||
kh | 0.60 | 0.60 | 0.58 | ||
taes | 113.26 | 93.26 | 88.47 | ||
qlz | 1.35 | 1.29 | 1.33 | ||
mod | 57.59 | 54.43 | 53.41 | ||
mgmp | 1.00 | 0.99 | 0.96 | ||
unq | 1.44 | 1.46 | 1.45 | ||
bzip | 22.69 | 22.60 | 22.52 | ||
cumulative | 217.64 | 194.56 | 188.63 |
8.5 AbSolute constraint solver benchmarks
Benchmark | Apron | IncClose | IncStrongClose |
---|---|---|---|
boxdifference | 8.72 | 8.42 | 8.39 |
diseq | 18.25 | 18.11 | 18.07 |
diseq2 | 15.62 | 14.80 | 14.75 |
disjunction | 4.30 | 4.17 | 4.15 |
eclipse | 42.39 | 41.91 | 41.14 |
heart | 1014.13 | 947.32 | 944.04 |
lin1 | 12.15 | 11.77 | 11.76 |
nonlin1 | 2.38 | 2.35 | 2.35 |
nonlin2 | 4.05 | 3.92 | 3.97 |
octo_hole | 2.11 | 2.05 | 2.06 |
power | 24.57 | 22.97 | 23.13 |
question | 5.30 | 5.36 | 5.37 |
root | 13.53 | 12.92 | 13.00 |
strict_large | 4.52 | 4.26 | 4.31 |
two_circles | 11.99 | 11.95 | 11.95 |
cumulative | 1192.38 | 1112.28 | 1108.44 |