OCamlPro / alt-ergo

OCamlPro public development repository for Alt-Ergo
https://alt-ergo.ocamlpro.com/
Other
132 stars 33 forks source link

Documentation of Arrays_rel #1268

Open Halbaroth opened 1 week ago

Halbaroth commented 1 week ago

While writing this documentation, I read the paper Generalized, Efficient Array Decision Procedures of de Moura and Bjorner.

Before writing this documentation, I believed that we only implement the basic inferences rules, which is exposed in Fig 1 of the paper. These rules are:

  1. (idx) a == store(b, i, v) ===> a[i] = v
  2. (down) a == store(b, i, v), w == a'[j], a ~ a' ===> i = j \/ a[j] = b[j]
  3. (up) a == store(b, i, v), w = b'[j], b ~ b' ===> i = j \/ a[j] = b[j]
  4. (ext) a, b know ===> a = b \/ a[k] <> b[k] (k fresh name)

(I use the double equality symbol == to denote syntactical equality and ~ for the congruence relation.)

In fact, we implement a slightly different version of these rules. The down , up and ext inference rules are implemented by respectively get_of_set, get_and_set and extensionality functions in Arrays_rel module.

The idx axiom is not implemented by a dedicated function. Instead, different instantiations of this axiom are produced by get_of_set, get_and_set and get_from_set:

1a. (idx a) a[i] known, a ~ store(b, j, v) ==> i <> j \/ a[i] = v 1b. (idx b) store(b, i, v), store(a, j, w) known, a ~ b ==> store(a, j, w)[j] = w.

Technically, our implementation does not send directly instantiated axioms to the SAT solver. Consider for instance the axiom down and assume that all its hypotheses are satisfied. We produce the deduction i = j \/ a[j] = b[j] but we do not send it to the SAT solver. Instead, we add the equality i = j in the set env.split in order to split on its negation later. If we split on it or we see i <> j in assume, we send a[j] = b[j] to the SAT solver.

Our implementation suffers from a number of issues:

  1. We produce a lot of redundant axioms (see section A and section B of the paper). For instance, we do not need to propagate a[i] = v if we already know that a'[i'] = v' for with a ~ a', i ~ i' and v ~ v'. The same goes for other axioms.
  2. We store all the relevant terms in huge maps which is not efficient.
  3. We transform literal expressions into literal semantic values.

To be more efficient, our implementation only should follow equivalent classes of read/write terms and relevant indices. When some of these classes merge, we may have to instantiate axioms. This new version could be implemented using a union-find in Arrays_rel itself but as I explained during the last dev meeting, this modification will conflict with our plan for the union-find in UF (using Basile's store).