crosslang/golang-lean/GolangLean/Core/Determinism.lean
Maximus Gorog fd3d42ae33 Add 'golang-lean/' from commit 'f5f17019224c6a6c319387214ceb8e29d09251c6'
git-subtree-dir: golang-lean
git-subtree-mainline: 6487c7046f
git-subtree-split: f5f1701922
2026-05-12 02:59:14 -06:00

107 lines
3.1 KiB
Text

import GolangLean.Core.Semantics
namespace GolangLean.Core
/-! # Determinism of TGC big-step.
`BigStep h env e v₁ h₁ → BigStep h env e v₂ h₂ → v₁ = v₂ ∧ h₁ = h₂`
By induction on the first derivation, with case analysis on the second.
For each pair of constructors, either the term-shape forces them to agree
(so we apply the IHs to the sub-derivations) or, in the `ifte` case where
two rules share a term shape, an IH on the condition gives a contradictory
boolean. -/
theorem BigStep.deterministic
{h : Heap} {env : Env} {e : Term} {v₁ v₂ : Value} {h₁ h₂ : Heap}
(D₁ : BigStep h env e v₁ h₁) (D₂ : BigStep h env e v₂ h₂) :
v₁ = v₂ ∧ h₁ = h₂ := by
induction D₁ generalizing v₂ h₂ with
| unitR =>
cases D₂; exact ⟨rfl, rfl⟩
| intLitR n =>
cases D₂; exact ⟨rfl, rfl⟩
| boolLitR b =>
cases D₂; exact ⟨rfl, rfl⟩
| varR hLook =>
cases D₂ with
| varR hLook' =>
have heq := hLook.symm.trans hLook'
exact ⟨Option.some.inj heq, rfl⟩
| lamR x body =>
cases D₂; exact ⟨rfl, rfl⟩
| appR _ _ _ ih1 ih2 ihb =>
cases D₂ with
| appR D1' D2' Db' =>
have ⟨hClos, hH1⟩ := ih1 D1'
injection hClos with hx hbody henv
subst hx; subst hbody; subst henv; subst hH1
have ⟨hArg, hH2⟩ := ih2 D2'
subst hArg; subst hH2
exact ihb Db'
| letInR _ _ ih1 ih2 =>
cases D₂ with
| letInR D1' D2' =>
have ⟨hv1, hH1⟩ := ih1 D1'
subst hv1; subst hH1
exact ih2 D2'
| ifTR _ _ ihc iht =>
cases D₂ with
| ifTR Dc' Dt' =>
have ⟨_, hH1⟩ := ihc Dc'
subst hH1
exact iht Dt'
| ifFR Dc' _ =>
have ⟨hb, _⟩ := ihc Dc'
injection hb with hb_eq
exact Bool.noConfusion hb_eq
| ifFR _ _ ihc ihf =>
cases D₂ with
| ifTR Dc' _ =>
have ⟨hb, _⟩ := ihc Dc'
injection hb with hb_eq
exact Bool.noConfusion hb_eq
| ifFR Dc' Df' =>
have ⟨_, hH1⟩ := ihc Dc'
subst hH1
exact ihf Df'
| binopR _ _ Hop ih1 ih2 =>
cases D₂ with
| binopR D1' D2' Hop' =>
have ⟨hv1, hH1⟩ := ih1 D1'
subst hv1; subst hH1
have ⟨hv2, hH2⟩ := ih2 D2'
subst hv2; subst hH2
have heq := Hop.symm.trans Hop'
exact ⟨Option.some.inj heq, rfl⟩
| refMkR _ ih =>
cases D₂ with
| refMkR D' =>
have ⟨hv, hH⟩ := ih D'
subst hv; subst hH
exact ⟨rfl, rfl⟩
| derefR _ Hget ih =>
cases D₂ with
| derefR D' Hget' =>
have ⟨hloc, hH⟩ := ih D'
injection hloc with hloceq
subst hloceq; subst hH
have heq := Hget.symm.trans Hget'
exact ⟨Option.some.inj heq, rfl⟩
| assignR _ _ _ ih1 ih2 =>
cases D₂ with
| assignR D1' D2' _ =>
have ⟨hloc, hH1⟩ := ih1 D1'
injection hloc with hloceq
subst hloceq; subst hH1
have ⟨hv, hH2⟩ := ih2 D2'
subst hv; subst hH2
exact ⟨rfl, rfl⟩
| seqR _ _ ih1 ih2 =>
cases D₂ with
| seqR D1' D2' =>
have ⟨_, hH1⟩ := ih1 D1'
subst hH1
exact ih2 D2'
end GolangLean.Core