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

refactor: cleanup popcount proof #168

Merged
merged 23 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8bc9ed8
fix: remove use of `let (foo, bar) := _`, as it causes odd behaviour
alexkeizer Sep 18, 2024
91d399b
extend `sym_aggregate` to include memory effect hyps
alexkeizer Sep 18, 2024
378d3de
mark `AddWithCarry` simplification rules as `bitvec_rules`
alexkeizer Sep 18, 2024
412e185
cleanup popcount proof
alexkeizer Sep 18, 2024
ef4b8c4
chore: cleanup proofs in add_loop
bollu Sep 19, 2024
4c8ace5
chore: make build green
bollu Sep 19, 2024
982f2aa
Merge remote-tracking branch 'origin/main' into cleanup-popcount
bollu Sep 19, 2024
2c9cc1d
make proof prettier
bollu Sep 19, 2024
83903cc
chore: rebase
bollu Sep 23, 2024
f4be53f
chore: undo change
bollu Sep 23, 2024
d78683f
chore: update author list
bollu Sep 23, 2024
3ef52d3
chore: allow a crazy number of maxHeartbeats
bollu Sep 23, 2024
86b1065
chore: try to set maxRecDepth to zero to allow SHA512Prelude to compi…
bollu Sep 23, 2024
12228e3
fix: set maxRecDepth properly
alexkeizer Sep 24, 2024
2231110
fix loop proof
alexkeizer Sep 24, 2024
01ebdfd
chore: cleanup popcount32
bollu Sep 24, 2024
ee8682e
Merge remote-tracking branch 'origin/main' into cleanup-popcount
bollu Sep 24, 2024
0d80e1c
Merge branch 'main' into cleanup-popcount
shigoel Sep 25, 2024
31a3f0b
chore: comment why we need maxRecDepth
bollu Sep 25, 2024
f2f383f
Merge remote-tracking branch 'origin/cleanup-popcount' into cleanup-p…
bollu Sep 25, 2024
7dd34ae
chore: cleanup popcount32
bollu Sep 25, 2024
2d5a84b
chore: figure out precise linter that was slow
bollu Sep 25, 2024
8f7799d
Merge branch 'main' into cleanup-popcount
shigoel Sep 25, 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
4 changes: 3 additions & 1 deletion Arm/Insts/Common.lean
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def AddWithCarry (x : BitVec n) (y : BitVec n) (carry_in : BitVec 1) :
(result, (make_pstate N Z C V))

/-- When the carry bit is `0`, `AddWithCarry x y 0 = x + y` -/
@[bitvec_rules]
theorem fst_AddWithCarry_eq_add (x : BitVec n) (y : BitVec n) :
(AddWithCarry x y 0#1).fst = x + y := by
simp [AddWithCarry, zeroExtend_eq, zeroExtend_zero, zeroExtend_zero]
Expand All @@ -67,6 +68,7 @@ theorem fst_AddWithCarry_eq_add (x : BitVec n) (y : BitVec n) :
rw [Nat.mod_eq_of_lt this]

/-- When the carry bit is `1`, `AddWithCarry x y 1 = x - ~~~y` -/
@[bitvec_rules]
theorem fst_AddWithCarry_eq_sub_neg (x : BitVec n) (y : BitVec n) :
(AddWithCarry x y 1#1).fst = x - ~~~y := by
simp [AddWithCarry, zeroExtend_eq, zeroExtend_zero, zeroExtend_zero]
Expand Down Expand Up @@ -551,7 +553,7 @@ def rev_elems (n esize : Nat) (x : BitVec n) (h₀ : esize ∣ n) (h₁ : 0 < es
BitVec.cast h3 (element ++ rest_ans)
termination_by n

example : rev_elems 4 4 0xA#4 (by decide) (by decide) = 0xA#4 := by
example : rev_elems 4 4 0xA#4 (by decide) (by decide) = 0xA#4 := by
native_decide
example : rev_elems 8 4 0xAB#8 (by decide) (by decide) = 0xBA#8 := by native_decide
example : rev_elems 8 4 (rev_elems 8 4 0xAB#8 (by decide) (by decide))
Expand Down
12 changes: 7 additions & 5 deletions Arm/Insts/DPI/Add_sub_imm.lean
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,21 @@ def exec_add_sub_imm (inst : Add_sub_imm_cls) (s : ArmState) : ArmState :=
else
imm <<< 12
let operand1 := read_gpr datasize inst.Rn s
let (carry_in, operand2)
let carryInAndOperand2
:= if sub_op then
(1#1, ~~~imm)
else
(0#1, imm)
let carry := carryInAndOperand2.fst
let operand2 := carryInAndOperand2.snd
let operand2 := BitVec.zeroExtend datasize operand2
let (result, pstate) := AddWithCarry operand1 operand2 carry_in
let resultAndPState := AddWithCarry operand1 operand2 carry
-- State Updates
let s' := write_pc ((read_pc s) + 4#64) s
let s' := if setflags then write_pstate pstate s' else s'
let s' := if setflags then write_pstate resultAndPState.snd s' else s'
let s' := if inst.Rd = 31#5 ∧ ¬ setflags
then write_gpr datasize inst.Rd result s'
else write_gpr_zr datasize inst.Rd result s'
then write_gpr datasize inst.Rd resultAndPState.fst s'
else write_gpr_zr datasize inst.Rd resultAndPState.fst s'
s'

----------------------------------------------------------------------
Expand Down
35 changes: 9 additions & 26 deletions Proofs/Popcount32.lean
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ def popcount32_program : Program :=
(0x400618#64 , 0x910043ff#32), -- add sp, sp, #0x10
(0x40061c#64 , 0xd65f03c0#32)] -- ret


#genStepEqTheorems popcount32_program

theorem popcount32_sym_meets_spec (s0 s_final : ArmState)
Expand All @@ -91,34 +90,18 @@ theorem popcount32_sym_meets_spec (s0 s_final : ArmState)
-- Final Steps
-- Split all the Ands in the conclusion.
repeat' apply And.intro
· simp only [popcount32_spec,
fst_AddWithCarry_eq_add,
fst_AddWithCarry_eq_sub_neg]
simp only [popcount32_spec_rec]
· simp only [popcount32_spec, popcount32_spec_rec]
bv_decide
· sym_aggregate
· -- (TODO @alex) Let's do away with
-- ∀ (n : Nat) (addr : BitVec 64), read_mem_bytes n addr s₁ = read_mem_bytes n addr s₂
-- in favor of
-- s₁.mem = s₂.mem
-- as Sid said.
simp only [←Memory.mem_eq_iff_read_mem_bytes_eq] at *
· intro n addr h_separate
simp only [memory_rules] at *
intro n addr h_separate

-- (TODO @alex/@bollu) Can we hope to make this shorter after the marriage
-- of `sym_n` and `simp_mem`?
simp (config := {ground := true}) only
[fst_AddWithCarry_eq_add, fst_AddWithCarry_eq_sub_neg]
simp only [*, bitvec_rules]
simp_mem
sym_aggregate

simp (config := {ground := true}) only
[fst_AddWithCarry_eq_add, fst_AddWithCarry_eq_sub_neg]
simp only [*, bitvec_rules]
simp_mem
rfl
repeat (simp_mem; sym_aggregate)
· apply Aligned_BitVecSub_64_4 -- TODO(@bollu): match goal.
· assumption
· decide
· apply Aligned_BitVecAdd_64_4
· assumption
· decide


-------------------------------------------------------------------------------
Expand Down
14 changes: 12 additions & 2 deletions Tactics/Aggregate.lean
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,18 @@ elab "sym_aggregate" simpConfig?:(config)? loc?:(location)? : tactic => withMain
let lctx ← getLCtx
-- We keep `expectedRead`/`expectedAlign` as monadic values,
-- so that we get new metavariables for each localdecl we check
let expectedRead := do
let expectedRead : MetaM Expr := do
let fld ← mkFreshExprMVar (mkConst ``StateField)
let state ← mkFreshExprMVar mkArmState
let rhs ← mkFreshExprMVar none
mkEq (mkApp2 (mkConst ``r) fld state) rhs
let expectedAlign := do
let expectedReadMem : MetaM Expr := do
let n ← mkFreshExprMVar (mkConst ``Nat)
let addr ← mkFreshExprMVar (mkApp (mkConst ``BitVec) (toExpr 64))
let mem ← mkFreshExprMVar (mkConst ``Memory)
let rhs ← mkFreshExprMVar none
mkEq (mkApp3 (mkConst ``Memory.read_bytes) n addr mem) rhs
let expectedAlign : MetaM Expr := do
let state ← mkFreshExprMVar mkArmState
return mkApp (mkConst ``CheckSPAlignment) state

Expand All @@ -84,12 +90,16 @@ elab "sym_aggregate" simpConfig?:(config)? loc?:(location)? : tactic => withMain
trace[Tactic.sym] "checking {decl.toExpr} with type {type}"
let expectedRead ← expectedRead
let expectedAlign ← expectedAlign
let expectedReadMem ← expectedReadMem
if ← isDefEq type expectedRead then
trace[Tactic.sym] "{Lean.checkEmoji} match for {expectedRead}"
return axHyps.push decl
else if ← isDefEq type expectedAlign then
trace[Tactic.sym] "{Lean.checkEmoji} match for {expectedAlign}"
return axHyps.push decl
else if ← isDefEq type expectedReadMem then
trace[Tactic.sym] "{Lean.checkEmoji} match for {expectedReadMem}"
return axHyps.push decl
else
trace[Tactic.sym] "{Lean.crossEmoji} no match"
return axHyps
Expand Down
Loading