55 lines
2.4 KiB
Lean4
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
|