Relational parametricity for pure System F
TheoremFundamental theorem of relational parametricity for System F#✓fully proved
The fundamental binary relational-parametricity theorem of pure System F.
A syntactic-model adaptation of Reynolds' abstraction theorem (1983, Sections 3 and 8), following Wadler's related-environment formulation (1989, Section 6); see the module's provenance and model qualifications.
theorem fundamental {n m : Nat} {Γ : Ctx n m} {t : Tm n m} {A : Ty n}
(ht : Typing Γ t A) (ρ : Fin n → Rel) (σ τ : Fin m → Model)
(hστ : ∀ i, ((Γ i).interpret ρ).holds (σ i) (τ i)) :
(A.interpret ρ).holds (Tm.close σ t) (Tm.close τ t)
abbrev Ctx (n m : Nat) := Fin m → Ty n
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:92
inductive Tm : Nat → Nat → Type where
| var {n m : Nat} : Fin m → Tm n m
| lam {n m : Nat} : Ty n → Tm n (m + 1) → Tm n m
| app {n m : Nat} : Tm n m → Tm n m → Tm n m
| tabs {n m : Nat} : Tm (n + 1) m → Tm n m
| tapp {n m : Nat} : Tm n m → Ty n → Tm n m
deriving DecidableEq, Repr
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:83
inductive Ty : Nat → Type where
| var {n : Nat} : Fin n → Ty n
| arr {n : Nat} : Ty n → Ty n → Ty n
| all {n : Nat} : Ty (n + 1) → Ty n
deriving DecidableEq, Repr
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:31
inductive Typing : {n m : Nat} → Ctx n m → Tm n m → Ty n → Prop where
| var {n m : Nat} {Γ : Ctx n m} (i : Fin m) :
Typing Γ (.var i) (Γ i)
| lam {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {b : Tm n (m + 1)} :
Typing (Fin.cases A Γ) b B → Typing Γ (.lam A b) (.arr A B)
| app {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {f a : Tm n m} :
Typing Γ f (.arr A B) → Typing Γ a A → Typing Γ (.app f a) B
| tabs {n m : Nat} {Γ : Ctx n m} {b : Tm (n + 1) m} {C : Ty (n + 1)} :
Typing (fun i => (Γ i).rename Fin.succ) b C →
Typing Γ (.tabs b) (.all C)
| tapp {n m : Nat} {Γ : Ctx n m} {f : Tm n m} {A : Ty n}
{C : Ty (n + 1)} :
⋯
CSLibExt/Languages/LambdaCalculus/SystemF/Typing.lean:25
structure Rel where
/-- The actual binary predicate. -/
holds : Model → Model → Prop
/-- Conversion may replace either argument independently. -/
congr : ∀ {f f' g g'}, BetaEq f f' → BetaEq g g' →
(holds f g ↔ holds f' g')
CSLibExt/Languages/LambdaCalculus/SystemF/Relations.lean:26
abbrev Model : Type := {t : Term Nat // t.LcAt 0}
CSLibExt/Languages/LambdaCalculus/SystemF/Model.lean:27
def close {n m : Nat} (σ : Fin m → Model) (t : Tm n m) : Model :=
⟨eraseWith (fun i => (σ i).val) t,
eraseWith_lcAt _ t (fun i => (σ i).property)⟩
CSLibExt/Languages/LambdaCalculus/SystemF/Erasure.lean:140
Uses 15 · Used by 1
TheoremClosed typed System F terms are related to themselves#✓fully proved
Every closed typed term is related to itself under arbitrary relations.
theorem fundamental_closed {n : Nat} {Γ : Ctx n 0} {t : Tm n 0} {A : Ty n}
(ht : Typing Γ t A) (ρ : Fin n → Rel) :
(A.interpret ρ).holds (Tm.eraseModel t) (Tm.eraseModel t)
abbrev Ctx (n m : Nat) := Fin m → Ty n
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:92
inductive Tm : Nat → Nat → Type where
| var {n m : Nat} : Fin m → Tm n m
| lam {n m : Nat} : Ty n → Tm n (m + 1) → Tm n m
| app {n m : Nat} : Tm n m → Tm n m → Tm n m
| tabs {n m : Nat} : Tm (n + 1) m → Tm n m
| tapp {n m : Nat} : Tm n m → Ty n → Tm n m
deriving DecidableEq, Repr
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:83
inductive Ty : Nat → Type where
| var {n : Nat} : Fin n → Ty n
| arr {n : Nat} : Ty n → Ty n → Ty n
| all {n : Nat} : Ty (n + 1) → Ty n
deriving DecidableEq, Repr
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:31
inductive Typing : {n m : Nat} → Ctx n m → Tm n m → Ty n → Prop where
| var {n m : Nat} {Γ : Ctx n m} (i : Fin m) :
Typing Γ (.var i) (Γ i)
| lam {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {b : Tm n (m + 1)} :
Typing (Fin.cases A Γ) b B → Typing Γ (.lam A b) (.arr A B)
| app {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {f a : Tm n m} :
Typing Γ f (.arr A B) → Typing Γ a A → Typing Γ (.app f a) B
| tabs {n m : Nat} {Γ : Ctx n m} {b : Tm (n + 1) m} {C : Ty (n + 1)} :
Typing (fun i => (Γ i).rename Fin.succ) b C →
Typing Γ (.tabs b) (.all C)
| tapp {n m : Nat} {Γ : Ctx n m} {f : Tm n m} {A : Ty n}
{C : Ty (n + 1)} :
⋯
CSLibExt/Languages/LambdaCalculus/SystemF/Typing.lean:25
structure Rel where
/-- The actual binary predicate. -/
holds : Model → Model → Prop
/-- Conversion may replace either argument independently. -/
congr : ∀ {f f' g g'}, BetaEq f f' → BetaEq g g' →
(holds f g ↔ holds f' g')
CSLibExt/Languages/LambdaCalculus/SystemF/Relations.lean:26
def eraseModel {n : Nat} (t : Tm n 0) : Model := close Fin.elim0 t
CSLibExt/Languages/LambdaCalculus/SystemF/Erasure.lean:145
Uses 9 · Used by 3
DefinitionPolymorphic identity type#✓fully proved
The polymorphic identity type, universally quantified at any type depth.
DefinitionPolymorphic identity term#✓fully proved
The pure polymorphic identity term.
def polyId {n m : Nat} : Tm n m := .tabs (.lam (.var 0) (.var 0))
inductive Tm : Nat → Nat → Type where
| var {n m : Nat} : Fin m → Tm n m
| lam {n m : Nat} : Ty n → Tm n (m + 1) → Tm n m
| app {n m : Nat} : Tm n m → Tm n m → Tm n m
| tabs {n m : Nat} : Tm (n + 1) m → Tm n m
| tapp {n m : Nat} : Tm n m → Ty n → Tm n m
deriving DecidableEq, Repr
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:83
Uses 2 · Used by 1
TheoremTyping of the polymorphic identity#✓fully proved
The polymorphic identity is well typed in any existing term context.
theorem polyId_typed {n m : Nat} (Γ : Ctx n m) :
Typing Γ polyId polyIdType
abbrev Ctx (n m : Nat) := Fin m → Ty n
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:92
inductive Typing : {n m : Nat} → Ctx n m → Tm n m → Ty n → Prop where
| var {n m : Nat} {Γ : Ctx n m} (i : Fin m) :
Typing Γ (.var i) (Γ i)
| lam {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {b : Tm n (m + 1)} :
Typing (Fin.cases A Γ) b B → Typing Γ (.lam A b) (.arr A B)
| app {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {f a : Tm n m} :
Typing Γ f (.arr A B) → Typing Γ a A → Typing Γ (.app f a) B
| tabs {n m : Nat} {Γ : Ctx n m} {b : Tm (n + 1) m} {C : Ty (n + 1)} :
Typing (fun i => (Γ i).rename Fin.succ) b C →
Typing Γ (.tabs b) (.all C)
| tapp {n m : Nat} {Γ : Ctx n m} {f : Tm n m} {A : Ty n}
{C : Ty (n + 1)} :
⋯
CSLibExt/Languages/LambdaCalculus/SystemF/Typing.lean:25
def polyId {n m : Nat} : Tm n m := .tabs (.lam (.var 0) (.var 0))
CSLibExt/Languages/LambdaCalculus/SystemF/Parametricity.lean:97
def polyIdType {n : Nat} : Ty n := .all (.arr (.var 0) (.var 0))
CSLibExt/Languages/LambdaCalculus/SystemF/Parametricity.lean:94
TheoremClosed inhabitants of the polymorphic identity type are identities#✓fully proved
Every closed inhabitant acts as identity after every type instantiation.
The conclusion is full-beta conversion in the existing erased term model, for an arbitrary locally closed input. It makes no CBV termination claim. This consumer specializes the free-theorem method of Wadler (1989, Figure 1) to the declared syntactic model; it applies to every typed inhabitant.
theorem polymorphic_identity {t : Tm 0 0}
(ht : Typing Fin.elim0 t polyIdType) (A : Ty 0) (x : Model) :
BetaEq (Model.app (Tm.eraseModel (.tapp t A)) x) x
inductive Tm : Nat → Nat → Type where
| var {n m : Nat} : Fin m → Tm n m
| lam {n m : Nat} : Ty n → Tm n (m + 1) → Tm n m
| app {n m : Nat} : Tm n m → Tm n m → Tm n m
| tabs {n m : Nat} : Tm (n + 1) m → Tm n m
| tapp {n m : Nat} : Tm n m → Ty n → Tm n m
deriving DecidableEq, Repr
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:83
inductive Typing : {n m : Nat} → Ctx n m → Tm n m → Ty n → Prop where
| var {n m : Nat} {Γ : Ctx n m} (i : Fin m) :
Typing Γ (.var i) (Γ i)
| lam {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {b : Tm n (m + 1)} :
Typing (Fin.cases A Γ) b B → Typing Γ (.lam A b) (.arr A B)
| app {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {f a : Tm n m} :
Typing Γ f (.arr A B) → Typing Γ a A → Typing Γ (.app f a) B
| tabs {n m : Nat} {Γ : Ctx n m} {b : Tm (n + 1) m} {C : Ty (n + 1)} :
Typing (fun i => (Γ i).rename Fin.succ) b C →
Typing Γ (.tabs b) (.all C)
| tapp {n m : Nat} {Γ : Ctx n m} {f : Tm n m} {A : Ty n}
{C : Ty (n + 1)} :
⋯
CSLibExt/Languages/LambdaCalculus/SystemF/Typing.lean:25
def polyIdType {n : Nat} : Ty n := .all (.arr (.var 0) (.var 0))
CSLibExt/Languages/LambdaCalculus/SystemF/Parametricity.lean:94
inductive Ty : Nat → Type where
| var {n : Nat} : Fin n → Ty n
| arr {n : Nat} : Ty n → Ty n → Ty n
| all {n : Nat} : Ty (n + 1) → Ty n
deriving DecidableEq, Repr
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:31
abbrev Model : Type := {t : Term Nat // t.LcAt 0}
CSLibExt/Languages/LambdaCalculus/SystemF/Model.lean:27
abbrev BetaEq (f g : Model) : Prop :=
Relation.EqvGen Term.FullBeta f.val g.val
CSLibExt/Languages/LambdaCalculus/SystemF/Model.lean:30
def app (f a : Model) : Model :=
⟨.app f.val a.val, by
simpa only [Term.LcAt, Bool.and_eq_true] using
And.intro f.property a.property⟩
CSLibExt/Languages/LambdaCalculus/SystemF/Model.lean:36
def eraseModel {n : Nat} (t : Tm n 0) : Model := close Fin.elim0 t
CSLibExt/Languages/LambdaCalculus/SystemF/Erasure.lean:145
Uses 13
TheoremPolymorphic identity inhabitants preserve admissible relations#✓fully proved
Type instantiations preserve every admissible binary input relation.
theorem polymorphic_related {t : Tm 0 0}
(ht : Typing Fin.elim0 t polyIdType) (A B : Ty 0) (R : Rel)
{x y : Model} (hxy : R.holds x y) :
R.holds (Model.app (Tm.eraseModel (.tapp t A)) x)
(Model.app (Tm.eraseModel (.tapp t B)) y)
inductive Tm : Nat → Nat → Type where
| var {n m : Nat} : Fin m → Tm n m
| lam {n m : Nat} : Ty n → Tm n (m + 1) → Tm n m
| app {n m : Nat} : Tm n m → Tm n m → Tm n m
| tabs {n m : Nat} : Tm (n + 1) m → Tm n m
| tapp {n m : Nat} : Tm n m → Ty n → Tm n m
deriving DecidableEq, Repr
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:83
inductive Typing : {n m : Nat} → Ctx n m → Tm n m → Ty n → Prop where
| var {n m : Nat} {Γ : Ctx n m} (i : Fin m) :
Typing Γ (.var i) (Γ i)
| lam {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {b : Tm n (m + 1)} :
Typing (Fin.cases A Γ) b B → Typing Γ (.lam A b) (.arr A B)
| app {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {f a : Tm n m} :
Typing Γ f (.arr A B) → Typing Γ a A → Typing Γ (.app f a) B
| tabs {n m : Nat} {Γ : Ctx n m} {b : Tm (n + 1) m} {C : Ty (n + 1)} :
Typing (fun i => (Γ i).rename Fin.succ) b C →
Typing Γ (.tabs b) (.all C)
| tapp {n m : Nat} {Γ : Ctx n m} {f : Tm n m} {A : Ty n}
{C : Ty (n + 1)} :
⋯
CSLibExt/Languages/LambdaCalculus/SystemF/Typing.lean:25
def polyIdType {n : Nat} : Ty n := .all (.arr (.var 0) (.var 0))
CSLibExt/Languages/LambdaCalculus/SystemF/Parametricity.lean:94
inductive Ty : Nat → Type where
| var {n : Nat} : Fin n → Ty n
| arr {n : Nat} : Ty n → Ty n → Ty n
| all {n : Nat} : Ty (n + 1) → Ty n
deriving DecidableEq, Repr
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:31
structure Rel where
/-- The actual binary predicate. -/
holds : Model → Model → Prop
/-- Conversion may replace either argument independently. -/
congr : ∀ {f f' g g'}, BetaEq f f' → BetaEq g g' →
(holds f g ↔ holds f' g')
CSLibExt/Languages/LambdaCalculus/SystemF/Relations.lean:26
abbrev Model : Type := {t : Term Nat // t.LcAt 0}
CSLibExt/Languages/LambdaCalculus/SystemF/Model.lean:27
def app (f a : Model) : Model :=
⟨.app f.val a.val, by
simpa only [Term.LcAt, Bool.and_eq_true] using
And.intro f.property a.property⟩
CSLibExt/Languages/LambdaCalculus/SystemF/Model.lean:36
def eraseModel {n : Nat} (t : Tm n 0) : Model := close Fin.elim0 t
CSLibExt/Languages/LambdaCalculus/SystemF/Erasure.lean:145
Uses 9
TheoremNo closed System F term inhabits \(\forall X, X\)#✓fully proved
The empty relation rules out every closed inhabitant of forall X, X.
theorem forall_var_uninhabited (t : Tm 0 0) :
¬ Typing Fin.elim0 t (.all (.var 0))
inductive Tm : Nat → Nat → Type where
| var {n m : Nat} : Fin m → Tm n m
| lam {n m : Nat} : Ty n → Tm n (m + 1) → Tm n m
| app {n m : Nat} : Tm n m → Tm n m → Tm n m
| tabs {n m : Nat} : Tm (n + 1) m → Tm n m
| tapp {n m : Nat} : Tm n m → Ty n → Tm n m
deriving DecidableEq, Repr
CSLibExt/Languages/LambdaCalculus/SystemF/Syntax.lean:83
inductive Typing : {n m : Nat} → Ctx n m → Tm n m → Ty n → Prop where
| var {n m : Nat} {Γ : Ctx n m} (i : Fin m) :
Typing Γ (.var i) (Γ i)
| lam {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {b : Tm n (m + 1)} :
Typing (Fin.cases A Γ) b B → Typing Γ (.lam A b) (.arr A B)
| app {n m : Nat} {Γ : Ctx n m} {A B : Ty n} {f a : Tm n m} :
Typing Γ f (.arr A B) → Typing Γ a A → Typing Γ (.app f a) B
| tabs {n m : Nat} {Γ : Ctx n m} {b : Tm (n + 1) m} {C : Ty (n + 1)} :
Typing (fun i => (Γ i).rename Fin.succ) b C →
Typing Γ (.tabs b) (.all C)
| tapp {n m : Nat} {Γ : Ctx n m} {f : Tm n m} {A : Ty n}
{C : Ty (n + 1)} :
⋯
CSLibExt/Languages/LambdaCalculus/SystemF/Typing.lean:25
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.