Skip to content

Commit b477dc5

Browse files
committed
Add capability to sym_block to specify a list of possibly different block sizes
1 parent dd971b2 commit b477dc5

File tree

3 files changed

+59
-14
lines changed

3 files changed

+59
-14
lines changed

Proofs/SHA512/SHA512BlockSym.lean

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,11 @@ theorem sha512_loop_sym {s0 sf : ArmState}
100100
-- ∧ (r (.SFP 3) sf ++ r (.SFP 2) sf ++ r (.SFP 1) sf ++ r (.SFP 0) sf) = final_hash
101101
:= by
102102
-- Symbolic Simulation
103-
sym_block 485 (block_size := 20) -- ceiling|485/20| blocks
103+
-- sym_block 485 (block_size := 20) -- ceiling|485/20| blocks
104+
sym_block 485 (block_sizes := [20, 20, 20, 20, 20, 20, 20,
105+
20, 20, 20, 20, 20, 20, 20,
106+
20, 20, 20, 20, 20, 20, 20,
107+
20, 20, 20, 5])
104108
-- clear_named [h_s, blocki_]
105109
-- Reasoning
106110
-- subst h_N

Tactics/SymBlock.lean

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -135,28 +135,63 @@ def sym_block1 (blockSize stepsLeft : Nat) : SymM Unit := do
135135
traceHeartbeats
136136

137137
syntax sym_block_size := "(" "block_size" " := " num ")"
138+
syntax sym_block_sizes := "(" "block_sizes" " := " "[" num,* "]" ")"
139+
140+
/--
141+
Get the first `n` elements of the list `xs`, where `acc` is the accumulator.
142+
143+
(FIXME) Implicit assumption: `xs` has at least one assumption.
144+
-/
145+
def first_n (n : Nat) (xs acc : List Nat) : List Nat :=
146+
match n with
147+
| 0 => acc.reverse
148+
| n' + 1 => first_n n' xs.tail (List.headD xs 0 :: acc)
149+
150+
/-- info: 5 -/
151+
#guard_msgs in
152+
#eval (first_n 1 [5, 2, 2, 1] []).foldl Nat.add 0
138153

139154
open Elab.Term (elabTerm) in
140-
elab "sym_block" n:num block_size:(sym_block_size)? s:(sym_at)? : tactic => do
155+
elab "sym_block" n:num
156+
-- block_size:(sym_block_size)?
157+
block_sizes:(sym_block_sizes)?
158+
s:(sym_at)? : tactic => do
141159
traceHeartbeats "initial heartbeats"
142160

143161
let s ← s.mapM fun
144162
| `(sym_at|at $s:ident) => pure s.getId
145163
| _ => Lean.Elab.throwUnsupportedSyntax
146-
let block_size ← block_size.mapM (fun
147-
| `(sym_block_size|(block_size := $val)) => pure val.getNat
148-
| _ => -- If no block size is specified, we step one instruction at a time.
149-
pure 1)
150-
let block_size := block_size.get!
164+
let block_sizes ← block_sizes.mapM (fun
165+
| `(sym_block_sizes|(block_sizes := [$elems,*])) => do
166+
let size_exprs ← elems.getElems.mapM (fun elem => do
167+
let size := elem.getNat
168+
return (mkNatLit size))
169+
let size_terms ← size_exprs.mapM (fun e => do
170+
let some val ← Lean.Meta.getNatValue? e | throwError ""
171+
return val)
172+
dbg_trace s!"size_terms: {size_terms}"
173+
pure size_terms.toList
174+
| _ =>
175+
-- (FIXME)
176+
-- If no block size is specified, we step one instruction at a time.
177+
pure [1])
178+
let block_sizes := block_sizes.get!
179+
trace[Tactic.sym.info] "block_sizes: {block_sizes}"
180+
181+
-- let block_size ← block_size.mapM (fun
182+
-- | `(sym_block_size|(block_size := $val)) => pure val.getNat
183+
-- | _ => -- If no block size is specified, we step one instruction at a time.
184+
-- pure 1)
185+
-- let block_size := block_size.get!
151186

152187
let c ← SymContext.fromMainContext s
153188
-- TODO: Is this `get!` safe?
154-
let total_steps := c.runSteps?.get!
189+
-- let total_steps := c.runSteps?.get!
155190
-- The number of instructions, not blocks, the user asked to simulate.
156191
let sim_steps := n.getNat
157192
-- We compute the number of blocks to be simulated using a ceiling divide.
158193
-- Note that the last block can be < `block_size`.
159-
let num_blocks := (sim_steps + block_size - 1) / block_size
194+
-- let num_blocks := (sim_steps + block_size - 1) / block_size
160195

161196
SymM.run' c <| withMainContext' <| do
162197
-- Check pre-conditions
@@ -166,10 +201,15 @@ elab "sym_block" n:num block_size:(sym_block_size)? s:(sym_at)? : tactic => do
166201

167202
withMainContext' <| do
168203
-- The main loop
169-
for i in List.range num_blocks do
170-
let block_size' := min (sim_steps - (i * block_size)) block_size
171-
let steps_left := (total_steps - (i * block_size) - block_size')
172-
sym_block1 block_size' steps_left
204+
-- for i in List.range num_blocks do
205+
-- let block_size' := min (sim_steps - (i * block_size)) block_size
206+
-- let steps_left := (total_steps - (i * block_size) - block_size')
207+
-- sym_block1 block_size' steps_left
208+
let mut ctr := 0
209+
for bsize in block_sizes do
210+
ctr := ctr + 1
211+
let steps_left := sim_steps - ((first_n ctr block_sizes []).foldl Nat.add 0)
212+
sym_block1 bsize steps_left
173213

174214
traceHeartbeats "symbolic simulation total"
175215
withCurrHeartbeats <|

Tests/Tactics/SymBlock.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,6 @@ theorem test {s0 : ArmState}
9090
(h_err : r StateField.ERR s0 = StateError.None)
9191
(h_run : sf = run 8 s0) :
9292
sf.program = ugh_program := by
93-
sym_block 8 (block_size := 4) -- 2 blocks: size 4 each
93+
-- sym_block 8 (block_size := 4) -- 2 blocks: size 4 each
94+
sym_block 8 (block_sizes := [4, 4])
9495
done

0 commit comments

Comments
 (0)