You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Encode acyclic with integer clocks instead of a transitive closure - #108
When the .cat memory model compiles into an SMT problem, acyclic r turns into the axiomatic definition of r⁺ (i.e. r ⊆ r⁺ and r⁺ ; r⁺ ⊆ r⁺) and the irreflexivity check for r⁺. I think z3 doesn't solve it very efficiently. In particular, when the 3 quantifiers of r⁺ ; r⁺ ⊆ r⁺ (i.e. ∀a,b,c. r⁺ a b -> r⁺ b c -> r⁺ a c) are eliminated, N^3 instances are generated.
Instead, one can define a function clock : Event -> Int with the axiom r e1 e2 ⇒ clock(e1) < clock(e2). It exists if and only if r is acyclic. There are only two quantifiers to eliminate, so N^2 instances are generated, and after that, I think z3 might deal better with integers.
I ran some tests through the web interface, online and locally. The tests (see below, in the "details") are MP through N locations. Even for N = 8, the upstream web interface takes a minute to finish.
In aarch64.cat, I also changed irreflexive ob as external to acyclic obs | dob | aob | bob as external, as now acyclic doesn't require calculating the full transitive closure. Even on its own, this change in .cat file speeds up the tests quite a bit, but N = 24 still times out.
With the clock encoding, it finishes in seconds.
Perhaps we could run proper benchmarks, but this encoding seems semantically sound and does improve performance. I used Claude to run some benchmarks through the command line, on MPn-N (MP with N data locations, 2N+3 events): one worker thread, --check-sat-using "(par-or smt (then dt2bv simplify solve-eqs qe bv))", z3 capped at 120 s. z3 time per test:
test
upstream
cat change only
this PR
MPn-4
0.7 s
0.7 s
0.6 s
MPn-8
2.0 s
2.5 s
0.9 s
MPn-16
> 120 s
7.6 s
1.7 s
MPn-24
> 120 s
> 120 s
3.1 s
"Cat change only" is the upstream binary with just the aarch64.cat edit. The 48 tests in web/client/dist/aarch64 give the same verdicts as before and take about the same time.
Looks great. I wonder if there would be any advantage to using a bitvector clock function with bvult/bvslt, since the number of events is finite? It would keep the entire problem in the bitvector theory, but maybe that doesn't matter much here.
I tried it with bitvectors, it's slower.
It seems like an integer clock encoding is somehow more natural for z3 than bitvectors in this case. I think it's able to figure out, when working in linear integer arithmetic, that it's actually looking for cycles.
Slower than integer clocks, or slower than the naive encoding of transitive closure?
Both. I tried __clock : Event -> (_ BitVec 16) with bvult for < on the same tests:
test
closure
Int clocks
bv clocks
MPn-4
1.0 s
0.2 s
1.1 s
MPn-8
2.4 s
0.4 s
4.3 s
MPn-16
>120 s
1.1 s
64.7 s
MPn-24
>120 s
2.4 s
>120 s
My interpretation is that with the bitvector clock, after bit-blasting, SAT has to re-discover transitivity, while for the integer arithmetic solver it's native.
NB: without rewriting irreflexive R⁺ -> acyclic R in the .cat files, the int clocks are sometimes slower than the naive encoding; I think it's a penalty for mixing z3 theories.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When the .cat memory model compiles into an SMT problem,
acyclic rturns into the axiomatic definition ofr⁺(i.e.r ⊆ r⁺andr⁺ ; r⁺ ⊆ r⁺) and the irreflexivity check forr⁺. I think z3 doesn't solve it very efficiently. In particular, when the3quantifiers ofr⁺ ; r⁺ ⊆ r⁺(i.e.∀a,b,c. r⁺ a b -> r⁺ b c -> r⁺ a c) are eliminated,N^3instances are generated.Instead, one can define a function
clock : Event -> Intwith the axiomr e1 e2 ⇒ clock(e1) < clock(e2). It exists if and only ifris acyclic. There are only two quantifiers to eliminate, soN^2instances are generated, and after that, I thinkz3might deal better with integers.I ran some tests through the web interface, online and locally. The tests (see below, in the "details") are MP through N locations. Even for N = 8, the upstream web interface takes a minute to finish.
In
aarch64.cat, I also changedirreflexive ob as externaltoacyclic obs | dob | aob | bob as external, as now acyclic doesn't require calculating the full transitive closure. Even on its own, this change in .cat file speeds up the tests quite a bit, but N = 24 still times out.With the clock encoding, it finishes in seconds.
Perhaps we could run proper benchmarks, but this encoding seems semantically sound and does improve performance. I used Claude to run some benchmarks through the command line, on MPn-N (MP with N data locations, 2N+3 events): one worker thread,
--check-sat-using "(par-or smt (then dt2bv simplify solve-eqs qe bv))", z3 capped at 120 s. z3 time per test:"Cat change only" is the upstream binary with just the
aarch64.catedit. The 48 tests inweb/client/dist/aarch64give the same verdicts as before and take about the same time.Details
N = 4
N = 24