Files
agda-spa/lean/Spa/Analysis/Reaching/Paths.lean

55 lines
2.4 KiB
Lean4

import Spa.Analysis.Reaching
import Spa.Language.TraceProperties
namespace Spa
namespace ReachingAnalysis
/-- The most recent assignment occurs in the history being searched. -/
lemma LastAssign.mem {prog : Program} {x : String} {run : Run prog} {d : prog.State}
(h : LastAssign prog x run d) : d ∈ run := by
induction h <;> aesop
/-- Appending older history cannot displace an already-found assignment. -/
lemma LastAssign.append {prog : Program} {x : String} {new : Run prog} {d : prog.State}
(h : LastAssign prog x new d) (old : Run prog) :
LastAssign prog x (new ++ old) d := by
induction h with
| here s rhs rest hc => exact .here s rhs _ hc
| there s rest hn h ih => exact .there s _ hn ih
/-- A history containing a write to `x` has a most recent assignment to `x`. -/
lemma lastAssign_of_write {prog : Program} {x : String} {run : Run prog}
(hw : ∃ d ∈ run, ∃ rhs, prog.code d = some (.assign x rhs)) :
∃ d, LastAssign prog x run d := by
induction run with
| nil => simp at hw
| cons d rest ih =>
by_cases hx : ∃ rhs, prog.code d = some (.assign x rhs)
· obtain ⟨rhs, hc⟩ := hx
exact ⟨d, .here d rhs rest hc⟩
· have hw' : ∃ j ∈ rest, ∃ rhs, prog.code j = some (.assign x rhs) := by
obtain ⟨j, hm, rhs, hc⟩ := hw
rcases List.mem_cons.mp hm with rfl | hm
· exact False.elim (hx ⟨rhs, hc⟩)
· exact ⟨j, hm, rhs, hc⟩
obtain ⟨j, hj⟩ := ih hw'
exact ⟨j, .there d rest (by simpa using hx) hj⟩
/-- Outside reaching definitions rule out any write in a confined intervening
path. No equality of static sites is used to infer equality of events. -/
lemma Path.preserves_of_lastAssign_outside {prog : Program}
{a b c : Configuration prog.cfg} (pre : Path prog.cfg a b) (seg : Path prog.cfg b c)
{x : String} (sites : Set prog.State)
(hin : ∀ d ∈ seg.steps, d ∈ sites)
(hout : ∀ d, LastAssign prog x (runOfPath prog (pre.append seg)) d → d ∉ sites) :
∀ v, Env.Mem (x, v) b.2 ↔ Env.Mem (x, v) c.2 := by
apply seg.preserves_unwritten
intro d hm rhs hc
obtain ⟨j, hl⟩ := lastAssign_of_write ⟨d, List.mem_reverse.mpr hm, rhs, hc⟩
apply hout j
· simpa [runOfPath, List.reverse_append] using hl.append (runOfPath prog pre)
· exact hin j (List.mem_reverse.mp hl.mem)
end ReachingAnalysis
end Spa