lean4-htt/tests/bench/bv_decide_mod.lean
Henrik Böving 248864c716
perf: benchmark for modulo on bv_decide (#5653)
This verifies a bit hack from here:
https://en.wikipedia.org/wiki/Lehmer_random_number_generator#Sample_C99_code

I previously ran the SMTLIB equivalent this with Bitwuzla in my crypto
class and got the following numbers:
- 22s with Bitwuzla
- Z3 and CVC5 don't yet terminate after > 2min

Now with`bv_decide` the overall timing is 33.7s, consisting of:
- 5s of checking the LRAT cert
- 5s of trimming the LRAT cert from 800k to 300k proof steps
- remainder actual solving time

So running `bv_decide` like a normal SMT solver without verifying the
result of the SAT solver would yield approximately ~24s.
2024-10-08 18:58:15 +00:00

39 lines
1 KiB
Text

import Std.Tactic.BVDecide
/-
Verify: https://en.wikipedia.org/wiki/Lehmer_random_number_generator#Sample_C99_code
uint32_t lcg_parkmiller(uint32_t *state)
{
return *state = (uint64_t)*state * 48271 % 0x7fffffff;
}
vs
uint32_t lcg_parkmiller(uint32_t *state)
{
uint64_t product = (uint64_t)*state * 48271;
uint32_t x = (product & 0x7fffffff) + (product >> 31);
x = (x & 0x7fffffff) + (x >> 31);
return *state = x;
}
-/
def naive (state : BitVec 32) : BitVec 32 :=
(((state.zeroExtend 64) * 48271) % 0x7fffffff).extractLsb 31 0
def opt (state : BitVec 32) : BitVec 32 :=
let product := (state.zeroExtend 64) * 48271
let x := ((product &&& 0x7fffffff) + (product >>> 31)).extractLsb 31 0
let x := (x &&& 0x7fffffff) + (x >>> 31)
x
--set_option trace.Meta.Tactic.bv true in
--set_option trace.Meta.Tactic.sat true in
--set_option trace.profiler true in
set_option sat.timeout 120 in
theorem lehmer_correct (state : BitVec 32) (h1 : state > 0) (h2 : state < 0x7fffffff) :
naive state = opt state := by
unfold naive opt
bv_decide