ai-free / backend /riscv64 /RV /Run.lean
SNAPKITTYWEST's picture
October 2026 main drop: sync from GitHub at 8d0f04c
9ad95e5 verified
Raw History Blame Contribute Delete
5.8 kB
import RV.Lower
/-!
# RV.Run
Run relations for the RISC-V model (`RSteps`, `RExec`), code placement (`RAt`), and the lemma
locating each IR instruction's lowered code inside `lowerProg`.
-/
namespace WordDialect
namespace RV
inductive RSteps (code : List (Instr Nat)) : M β†’ M β†’ Prop where
| refl {m : M} : RSteps code m m
| cons {m m1 m2 : M} : step code m = .next m1 β†’ RSteps code m1 m2 β†’ RSteps code m m2
theorem RSteps.single {code : List (Instr Nat)} {m m1 : M} (h : step code m = .next m1) :
RSteps code m m1 := .cons h .refl
theorem RSteps.trans {code : List (Instr Nat)} {m m1 m2 : M}
(h₁ : RSteps code m m1) (hβ‚‚ : RSteps code m1 m2) : RSteps code m m2 := by
induction h₁ with
| refl => exact hβ‚‚
| cons hs _ ih => exact .cons hs (ih hβ‚‚)
/-- Running to a final outcome. -/
inductive RExec (code : List (Instr Nat)) : M β†’ Out β†’ Prop where
| halt {m m' : M} : step code m = .halted m' β†’ RExec code m (.halted m')
| trap {m : M} {t : Trap} : step code m = .trapped t β†’ RExec code m (.trapped t)
| ovf {m : M} : step code m = .overflow β†’ RExec code m .overflow
| next {m m1 : M} {o : Out} : step code m = .next m1 β†’ RExec code m1 o β†’ RExec code m o
theorem RExec.of_steps {code : List (Instr Nat)} {m m1 : M} {o : Out}
(hs : RSteps code m m1) (he : RExec code m1 o) : RExec code m o := by
induction hs with
| refl => exact he
| cons h _ ih => exact .next h (ih he)
/-- `seg` occurs in `code` starting at index `pc`. -/
def RAt : List (Instr Nat) β†’ Nat β†’ List (Instr Nat) β†’ Prop
| _, _, [] => True
| code, pc, i :: is => code[pc]? = some i ∧ RAt code (pc + 1) is
theorem rat_append {code : List (Instr Nat)} {pc : Nat} {c₁ cβ‚‚ : List (Instr Nat)} :
RAt code pc (c₁ ++ cβ‚‚) ↔ RAt code pc c₁ ∧ RAt code (pc + c₁.length) cβ‚‚ := by
induction c₁ generalizing pc with
| nil => simp [RAt]
| cons i is ih =>
simp only [List.cons_append, RAt, ih, List.length_cons]
constructor
· rintro ⟨h, h1, h2⟩; refine ⟨⟨h, h1⟩, ?_⟩
have e : pc + 1 + is.length = pc + (is.length + 1) := by omega
rw [← e]; exact h2
· rintro ⟨⟨h, h1⟩, h2⟩; refine ⟨h, h1, ?_⟩
have e : pc + 1 + is.length = pc + (is.length + 1) := by omega
rw [e]; exact h2
theorem fetch_cast {code : List (Instr Nat)} {i : Instr Nat} {a b : Nat}
(h : code[a]? = some i) (hab : a = b) : code[b]? = some i := hab β–Έ h
theorem rstep_of_fetch {code : List (Instr Nat)} {m : M} {i : Instr Nat}
(h : code[m.pc]? = some i) : step code m = exec i m := by
simp [step, h]
/-- Prefix sums: `offs` of a cons. -/
theorem offs_cons (i : WordDialect.Instr 64) (is : Prog 64) (k : Nat) :
offs (i :: is) (k + 1) = isize i + offs is k := by
simp [offs, List.take_succ_cons]
theorem offs_zero (p : Prog 64) : offs p 0 = 0 := by simp [offs]
theorem rat_embed (pre seg post : List (Instr Nat)) : RAt (pre ++ seg ++ post) pre.length seg := by
induction seg generalizing pre with
| nil => simp [RAt]
| cons i is ih =>
refine ⟨by simp, ?_⟩
have := ih (pre ++ [i])
simpa [List.append_assoc] using this
/-- Where the lowered code of IR instruction `k` sits: at index `pre.length + offs ps k`. -/
theorem lowerGo_at (L : Layout) (off : Nat β†’ Nat) :
βˆ€ (ps : Prog 64) (pre : List (Instr Nat)) (k : Nat) (i : WordDialect.Instr 64),
ps[k]? = some i β†’
RAt (pre ++ lowerGo L off pre.length ps) (pre.length + offs ps k)
(lowerInstr L (pre.length + offs ps k) off i) := by
intro ps
induction ps with
| nil => intro pre k i h; simp at h
| cons j js ih =>
intro pre k i h
cases k with
| zero =>
simp at h; subst h
simp only [offs_zero, Nat.add_zero, lowerGo]
have := rat_embed pre (lowerInstr L pre.length off j) (lowerGo L off (pre.length + isize j) js)
simpa [List.append_assoc] using this
| succ k =>
simp only [List.getElem?_cons_succ] at h
have := ih (pre ++ lowerInstr L pre.length off j) k i h
have hl : (pre ++ lowerInstr L pre.length off j).length = pre.length + isize j := by
simp [lowerInstr_length]
rw [hl] at this
simp only [lowerGo, offs_cons]
have e : pre.length + (isize j + offs js k) = pre.length + isize j + offs js k := by omega
rw [e]
simpa [List.append_assoc] using this
theorem lowerProg_at (L : Layout) (p : Prog 64) (k : Nat) (i : WordDialect.Instr 64)
(h : p[k]? = some i) :
RAt (lowerProg L p) (offs p k) (lowerInstr L (offs p k) (offs p) i) := by
have := lowerGo_at L (offs p) p [] k i h
simpa [lowerProg] using this
/-- The final stub (bad-pc trap) sits at `offs p p.length`. -/
theorem lowerGo_stub (L : Layout) (off : Nat β†’ Nat) :
βˆ€ (ps : Prog 64) (pre : List (Instr Nat)),
RAt (pre ++ lowerGo L off pre.length ps) (pre.length + offs ps ps.length) [.exitTrap .badPc] := by
intro ps
induction ps with
| nil =>
intro pre
simp only [lowerGo, List.length_nil, offs, List.take_nil, List.map_nil, List.sum_nil,
Nat.add_zero]
have := rat_embed pre [.exitTrap .badPc] []
simpa using this
| cons j js ih =>
intro pre
have := ih (pre ++ lowerInstr L pre.length off j)
have hl : (pre ++ lowerInstr L pre.length off j).length = pre.length + isize j := by
simp [lowerInstr_length]
rw [hl] at this
simp only [lowerGo, List.length_cons, offs_cons]
have e : pre.length + (isize j + offs js js.length) = pre.length + isize j + offs js js.length := by omega
rw [e]
simpa [List.append_assoc] using this
theorem lowerProg_stub (L : Layout) (p : Prog 64) :
RAt (lowerProg L p) (offs p p.length) [.exitTrap .badPc] := by
have := lowerGo_stub L (offs p) p []
simpa [lowerProg] using this
end RV
end WordDialect