Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Switch to using bv_decide to decide memory goals instead of bv_omega #197

Draft
wants to merge 69 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
878735e
feat: bitvector constant folding simprocs
bollu Sep 26, 2024
16301d4
chore: delete bv_omega', reuse bv_omega
bollu Sep 26, 2024
6719e45
chore: BitVec.le_def already has bv_toNat tag
bollu Sep 26, 2024
50ee21b
Apply suggestions from code review
bollu Sep 26, 2024
22cbb4c
chore: reword docstring
bollu Sep 26, 2024
2380071
chore: move files around to have tests in tests/
bollu Sep 26, 2024
2c6b28d
chore: add more docstring
bollu Sep 26, 2024
1bef14e
chore: cleanup
bollu Sep 26, 2024
0ac3b69
chore: try to get 'simp only [bv_toNat] at *' working
bollu Sep 26, 2024
3eab45f
chore: directly invoke simp instead of using `evalTactic`. Next step:…
bollu Sep 26, 2024
d5dbe2b
Merge remote-tracking branch 'origin/main' into replace-simp-mem-eval…
bollu Sep 26, 2024
b818e0c
chore: cleanup
bollu Sep 26, 2024
954d0d7
chore: inline omega, and don't use so we can return the model back
bollu Sep 26, 2024
f22c0f6
chore: cleanup code around omega
bollu Sep 26, 2024
4d0181a
chore: don't enable tracing in memory aliasing tests.
bollu Sep 26, 2024
8c7edfc
Merge branch 'address-normalization-simproc' into simp-mem-v2
bollu Sep 26, 2024
d3bbd3c
chore: don't call simproc
bollu Sep 26, 2024
e67134d
chore: add failed experiment with address normalization timing out
bollu Sep 26, 2024
3db1ded
chore: nuke all old theory, and rewrite things in terms of bitvectors
bollu Sep 26, 2024
7924c21
chore: see that mem_decide_bv works well when we don't have arithmeti…
bollu Sep 26, 2024
83d0e6d
chore: fine-tune tactic a bit
bollu Sep 26, 2024
f2cc13c
bv_decide fails mysteriously?? when used as evalTactic?? what is goin…
bollu Sep 26, 2024
5822a39
I'm going crazy x(
bollu Sep 26, 2024
1672dff
chore: indeed bv_decide is confused.
bollu Sep 26, 2024
920a1c6
chore: hunt down inconsistency.
bollu Sep 26, 2024
f0ede47
chore: create abstraction to bridge bitvec/nat
bollu Sep 26, 2024
67c25c8
chore: get memory aliasing file working
bollu Sep 26, 2024
610147d
chore: show how bitvector theory can fail us, and what the remedy is …
bollu Sep 26, 2024
92d0290
chore: rewrite to use bitvectors.
bollu Sep 26, 2024
4532ae2
chore: make progress on memcpy proof, it's actually... usable? it doe…
bollu Sep 26, 2024
e4285fe
feat: yep yep this is massively more usable
bollu Sep 26, 2024
fbe42a5
chore: add missing assumption
bollu Sep 26, 2024
66bb359
chore: kill a 'sorry'
bollu Sep 26, 2024
b398471
chore: try to simplify proof state to see what's going wrong
bollu Sep 27, 2024
73b3fb4
chore: use proof 2
bollu Sep 27, 2024
3c96aa5
chore: get memcpy proof through
bollu Sep 27, 2024
6d59e51
chore: shrink
bollu Sep 27, 2024
6d734d3
chore: simplify proof of memcpy further
bollu Sep 27, 2024
1987f9a
chore: move axiom into precondition
bollu Sep 27, 2024
5a9846b
chore: delete axiom that was used in place of a hypothesis
bollu Sep 27, 2024
8b37715
chore: add notes in the other files
bollu Sep 27, 2024
9e41f03
chore: time bv_decide, 11 seconds
bollu Sep 27, 2024
1014266
chore: fixup simp_mem some more
bollu Sep 27, 2024
31a63df
chore: checkpoint
bollu Sep 27, 2024
436765c
chore: be careful with withMainContext
bollu Sep 27, 2024
c027175
chore: checkpoint state
bollu Sep 27, 2024
b2ce27d
chore: give up on calling bv_decide and simp programatically, too muc…
bollu Sep 27, 2024
dfb0309
chore: document totally bonkers popcount failure
bollu Sep 27, 2024
2a81df4
chore: update memcpy proof
bollu Sep 27, 2024
dcc5a95
chore: start adding linters and related constructs
bollu Sep 28, 2024
fea3c6e
chore: add linting to help spot weird BV expressions
bollu Sep 28, 2024
966473d
chore: show what's needed for popcount
bollu Sep 28, 2024
057237e
chore: get SHA512Prelude working
bollu Sep 28, 2024
301a4cd
chore: bump up toolchain 29/9/2024
bollu Sep 30, 2024
1a996fc
bugfixes in pairing with @shilgoel, @alexkeizer
bollu Oct 1, 2024
bbf03e7
chore: regenerate LRAT proofs
bollu Oct 1, 2024
8eecc1e
chore: add or_self, was somehow lost?
bollu Oct 1, 2024
747f9cd
chore: fixup paths
bollu Oct 1, 2024
988ca19
chore: update SHA512_block_armv8_rules
bollu Oct 1, 2024
65b4bb5
chore: fixup proof
bollu Oct 1, 2024
f70432b
chore: update popcount32
bollu Oct 1, 2024
b092887
chre: fixup MemCpyVCG
bollu Oct 1, 2024
24546b6
chore: CSE changed
bollu Oct 1, 2024
c6c15a0
Merge branch 'toolchain-bump-29-9-2024' into simp-mem-v2
bollu Oct 1, 2024
1c9b15c
chore: clenup AddLoop
bollu Oct 1, 2024
c5c7379
chore: Henrik's fix worked
bollu Oct 1, 2024
6deed7e
chore: merge conflict resolved
bollu Oct 1, 2024
421619e
chore: write alternative for read/write_bytes called read/write_bytes…
bollu Oct 3, 2024
e8995e4
chore: explore changing read_mem_bytes and write_mem_bytes to read_me…
bollu Oct 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 8 additions & 40 deletions Arm/BitVec.lean
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ namespace BitVec

open BitVec

@[deprecated setWidth_setWidth_of_le (since := "2024-09-18")]
abbrev truncate_truncate_of_le := @setWidth_setWidth_of_le

-- Adding some useful simp lemmas to `bitvec_rules`: we do not include
-- `bv_toNat` lemmas here.
-- See Init.Data.BitVec.Lemmas.
Expand Down Expand Up @@ -161,6 +164,8 @@ attribute [bitvec_rules] BitVec.ofBool_false
attribute [bitvec_rules] BitVec.ofNat_eq_ofNat
attribute [bitvec_rules] BitVec.zero_eq
attribute [bitvec_rules] BitVec.truncate_eq_zeroExtend
attribute [bitvec_rules] BitVec.or_self
attribute [minimal_theory] BitVec.zero_or

attribute [bitvec_rules] BitVec.add_sub_cancel
attribute [bitvec_rules] BitVec.sub_add_cancel
Expand Down Expand Up @@ -213,7 +218,7 @@ attribute [bitvec_rules] BitVec.reduceULT
attribute [bitvec_rules] BitVec.reduceULE
attribute [bitvec_rules] BitVec.reduceSLT
attribute [bitvec_rules] BitVec.reduceSLE
attribute [bitvec_rules] BitVec.reduceZeroExtend'
attribute [bitvec_rules] BitVec.reduceSetWidth'
attribute [bitvec_rules] BitVec.reduceShiftLeftZeroExtend
attribute [bitvec_rules] BitVec.reduceExtracLsb'
attribute [bitvec_rules] BitVec.reduceReplicate
Expand Down Expand Up @@ -245,6 +250,7 @@ attribute [bitvec_rules] Nat.reduceLTLE
attribute [bitvec_rules] Nat.reduceLeDiff
attribute [bitvec_rules] Nat.reduceSubDiff
attribute [bitvec_rules] BitVec.toNat_ofNat
attribute [bitvec_rules] BitVec.natCast_eq_ofNat

-- Some Fin lemmas useful for bitvector reasoning:
attribute [bitvec_rules] Fin.eta
Expand Down Expand Up @@ -456,9 +462,6 @@ theorem toNat_ofNat_lt {n w₁ : Nat} (hn : n < 2^w₁) :

---------------------------- Comparison Lemmas -----------------------

@[simp] protected theorem not_lt {n : Nat} {a b : BitVec n} : ¬ a < b ↔ b ≤ a := by
exact Fin.not_lt ..

theorem ge_of_not_lt (x y : BitVec w₁) (h : ¬ (x < y)) : x ≥ y := by
simp_all only [BitVec.le_def, BitVec.lt_def]
omega
Expand Down Expand Up @@ -500,32 +503,12 @@ protected theorem zero_le_sub (x y : BitVec n) :

----------------------------- Logical Lemmas ------------------------

@[bitvec_rules]
protected theorem zero_or (x : BitVec n) : 0#n ||| x = x := by
unfold HOr.hOr instHOrOfOrOp OrOp.or instOrOp BitVec.or
simp only [toNat_ofNat, Nat.zero_mod, Nat.zero_or]
congr

@[bitvec_rules]
protected theorem or_zero (x : BitVec n) : x ||| 0#n = x := by
rw [BitVec.or_comm]
rw [BitVec.zero_or]
done

@[bitvec_rules]
protected theorem or_self (x : BitVec n) :
x ||| x = x := by
refine eq_of_toNat_eq ?_
rw [BitVec.toNat_or]
apply Nat.eq_of_testBit_eq
simp only [Nat.testBit_or, Bool.or_self, implies_true]
done

--------------------- ZeroExtend/Append/Extract Lemmas ----------------

@[bitvec_rules]
theorem zeroExtend_zero_width : (zeroExtend 0 x) = 0#0 := by
unfold zeroExtend
unfold zeroExtend setWidth
split <;> simp [bitvec_zero_is_unique]

-- During symbolic simulation, we often encounter an `if` in the first argument
Expand Down Expand Up @@ -1087,21 +1070,6 @@ theorem BitVec.ofBool_getLsbD (a : BitVec w) (i : Nat) :
intro ⟨0, _⟩
simp

/-- If multiplication does not overflow,
then `(x * y).toNat` equals `x.toNat * y.toNat` -/
theorem toNat_mul_of_lt {w} {x y : BitVec w} (h : x.toNat * y.toNat < 2^w) :
(x * y).toNat = x.toNat * y.toNat := by
rw [BitVec.toNat_mul, Nat.mod_eq_of_lt h]

/-- If subtraction does not overflow,
then `(x - y).toNat` equals `x.toNat - y.toNat` -/
theorem toNat_sub_of_lt {w} {x y : BitVec w} (h : x.toNat < y.toNat) :
(y - x).toNat = y.toNat - x.toNat := by
rw [BitVec.toNat_sub,
show (2^w - x.toNat + y.toNat) = 2^w + (y.toNat - x.toNat) by omega,
Nat.add_mod, Nat.mod_self, Nat.zero_add, Nat.mod_mod,
Nat.mod_eq_of_lt (by omega)]

/-- `x.toNat * z.toNat ≤ k` if `z ≤ y` and `x.toNat * y.toNat ≤ k` -/
theorem toNat_mul_toNat_le_of_le_of_le {w} (x y z : BitVec w)
(hxy : x.toNat * y.toNat ≤ k)
Expand Down
6 changes: 3 additions & 3 deletions Arm/Cfg/Cfg.lean
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ protected def addToCfg (address : BitVec 64) (program : Program) (cfg : Cfg)
-- is in terms of Fin so that we can take advantage of Fin lemmas. We
-- will map this theorem to BitVecs (using lemmas like
-- BitVec.fin_bitvec_lt) in create'.
private theorem termination_lemma (i j max : Fin n) (h : n > 0)
(h0 : i < max) (h1 : j <= max - i) (h2 : ((Fin.ofNat' 0 h) : Fin n) < j) :
private theorem termination_lemma (i j max : Fin n) (h : NeZero n)
(h0 : i < max) (h1 : j <= max - i) (h2 : ((Fin.ofNat' n 0)) < j) :
(max - (i + j)) < (max - i) := by
-- Our strategy is to convert this proof obligation in terms of Nat,
-- which is made possible by h0 and h1 hypotheses above.
Expand Down Expand Up @@ -270,7 +270,7 @@ private def create' (address : BitVec 64) (max_address : BitVec 64)
else if h₂ : 4#64 <= max_address - address then
have ?term_lemma : (max_address - (address + 4#64)).toNat < (max_address - address).toNat := by
have := termination_lemma address.toFin (4#64).toFin max_address.toFin
(by decide)
(by exact inferInstance)
(by simp_all! only [BitVec.not_lt, BitVec.fin_bitvec_lt, not_false_eq_true, BitVec.lt_of_le_ne, h₁])
(by rw [← BitVec.toFin_sub]; exact h₂)
(by simp_arith)
Expand Down
3 changes: 0 additions & 3 deletions Arm/Insts/Common.lean
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,6 @@ dsimproc [state_simp_rules] reduceInvalidBitMasks (invalid_bit_masks _ _ _ _) :=
imm.expr.isTrue
M)

theorem Nat.lt_one_iff {n : Nat} : n < 1 ↔ n = 0 := by
omega

theorem M_divisible_by_esize_of_valid_bit_masks (immN : BitVec 1) (imms : BitVec 6)
(immediate : Bool) (M : Nat):
¬ invalid_bit_masks immN imms immediate M →
Expand Down
27 changes: 21 additions & 6 deletions Arm/Insts/LDST/Reg_imm.lean
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ instance : ToString Reg_imm_cls where toString a := toString (repr a)
@[state_simp_rules]
def reg_imm_operation (inst_str : String) (op : BitVec 1)
(wback : Bool) (postindex : Bool) (SIMD? : Bool)
(datasize : Nat) (regsize : Option Nat) (Rn : BitVec 5)
(datasize : Nat) (hdatasize : datasize < 2^64) (regsize : Option Nat) (Rn : BitVec 5)
(Rt : BitVec 5) (offset : BitVec 64) (s : ArmState)
(H : 8 ∣ datasize) : ArmState :=
let address := read_gpr 64 Rn s
Expand All @@ -48,7 +48,15 @@ def reg_imm_operation (inst_str : String) (op : BitVec 1)
match op with
| 0#1 => -- STORE
let data := ldst_read SIMD? datasize Rt s
write_mem_bytes (datasize / 8) address (BitVec.cast h.symm data) s
write_mem_bytes' (datasize / 8) address (data.cast (by
simp [bv_toNat]
show _ = (BitVec.udiv _ _).toNat * 8
rw [BitVec.toNat_udiv]
simp
rw [Nat.mod_eq_of_lt (by omega)]
omega
)) s
-- write_mem_bytes (datasize / 8) address (BitVec.cast h.symm data) s
| _ => -- LOAD
let data := read_mem_bytes (datasize / 8) address s
if SIMD? then write_sfp datasize Rt (BitVec.cast h data) s
Expand Down Expand Up @@ -79,12 +87,13 @@ def supported_reg_imm (size : BitVec 2) (opc : BitVec 2) (SIMD? : Bool) : Bool :
| 0b00#2, 0b11#2, true => true -- LDR, 128-bit, SIMD&FP
| _, _, _ => false -- other instructions that are not supported or illegal


@[state_simp_rules]
def exec_reg_imm_common
(inst : Reg_imm_cls) (inst_str : String) (s : ArmState) : ArmState :=
let scale :=
if inst.SIMD? then ((lsb inst.opc 1) ++ inst.size).toNat
else inst.size.toNat
let scale, hscale⟩ : { n : Nat // n ≤ 10} :=
if inst.SIMD? then ((lsb inst.opc 1) ++ inst.size).toNat, by bv_omega⟩
else inst.size.toNat, by bv_omega⟩
-- Only allow supported LDST Reg immediate instructions
if not $ supported_reg_imm inst.size inst.opc inst.SIMD? then
write_err (StateError.Unimplemented "Unsupported instruction {inst_str} encountered!") s
Expand All @@ -100,6 +109,12 @@ def exec_reg_imm_common
| Sum.inl imm12 => (BitVec.zeroExtend 64 imm12) <<< scale
| Sum.inr imm9 => signExtend 64 imm9
let datasize := 8 <<< scale
have : datasize < 2^64 := by
simp [datasize]
rw [Nat.shiftLeft_eq]
have : 2^scale ≤ 2^10 := by apply Nat.pow_le_pow_of_le (by decide) (by omega)
simp at this
omega
let regsize :=
if inst.SIMD? then none
else if inst.size = 0b11#2 then some 64 else some 32
Expand All @@ -108,7 +123,7 @@ def exec_reg_imm_common
-- State Updates
let s' := reg_imm_operation inst_str
(lsb inst.opc 0) inst.wback inst.postindex
inst.SIMD? datasize regsize inst.Rn inst.Rt offset s (H)
inst.SIMD? datasize (by omega) regsize inst.Rn inst.Rt offset s (H)
let s' := write_pc ((read_pc s) + 4#64) s'
s'

Expand Down
Loading
Loading