Types.CurryHoward: programs are proofs
Γ ⨾ Δ ⊢ e ∶ A ──translation──▶ ‼Γ ++ somes Δ ⊢ A
- types are formulas: A ⊸ B, A ⊗ B, !A, … are read the same way on both sides;
- programs are proofs: a term e of type A records a derivation of A, one rule per term former;
- evaluation is cut elimination: a redex such as (ƛ e) · v is an introduction rule immediately consumed by the matching elimination, which in the sequent calculus is a cut between a right rule and a left rule. Contracting the redex (⟶) corresponds to the step of Gentzen's cut elimination that removes that cut. This file does not formalize the step-by-step match. What it does use is the end result: by Intuitionistic/CutElim.v every proof has a cut-free form. On the program side, LinearTypes.preservation says that each step keeps the type, so each step gives a proof of the same sequent;
- linearity is the absence of contraction and weakening: a linear variable used twice would need contraction, and one never used would need weakening. Only !-types, whose variables live in the unrestricted context Γ, may be copied and dropped, exactly as bangC and bangW allow only !-formulas to be.
Reading the contexts
The translation, rule by rule
typing rule sequent proof
ƛ e ⊸R
e1 · e2 cut e1 against ⊸L (with e2 and ax)
⟨⟩ 𝟙R, after dropping ‼Γ
let𝟙 e1 in e2 cut e1 against 𝟙L
⟪e1, e2⟫ ⊗R, after duplicating ‼Γ
let⊗ e1 in e2 cut e1 against ⊗L
⟨e1, e2⟩ &R
π₁ e, π₂ e cut e against &L₁, &L₂ (with ax)
ι₁ e, ι₂ e ⊕R₁, ⊕R₂
case cut e against ⊕L
⟨⊤⟩ ⊤R
abort e cut e against 𝟘L
!e !R (the linear context is empty)
let! e1 in e2 cut e1 against e2, which uses !A as a hypothesis
lv n ax, after dropping ‼Γ
uv n !D and ax, after dropping the rest of ‼Γ
Consequences
From LinearLogic.Intuitionistic Require Import CutElim.
Available linear variables
Definition somes (Δ : list (option iformula)) : list iformula := omap id Δ.A: iformula
Δ: list (option iformula)somes (Some A :: Δ) = A :: somes Δdone. Qed.A: iformula
Δ: list (option iformula)somes (Some A :: Δ) = A :: somes ΔΔ: list (option iformula)somes (None :: Δ) = somes Δdone. Qed.Δ: list (option iformula)somes (None :: Δ) = somes Δ
An empty linear context has no hypotheses.
Δ: list (option iformula)lempty Δ → somes Δ = []induction 1 as [| o Δ -> _ IH]; [done | by rewrite somes_None]. Qed.Δ: list (option iformula)lempty Δ → somes Δ = []
The context of a linear variable is a single hypothesis.
n: nat
A: iformula
Δ: list (option iformula)lone n A Δ → somes Δ = [A]n: nat
A: iformula
Δ: list (option iformula)lone n A Δ → somes Δ = [A]A: iformula
Δ: list (option iformula)
HΔ: lempty Δsomes (Some A :: Δ) = [A]n: nat
A: iformula
Δ: list (option iformula)
IH: somes Δ = [A]somes (None :: Δ) = [A]by rewrite somes_Some, somes_lempty.A: iformula
Δ: list (option iformula)
HΔ: lempty Δsomes (Some A :: Δ) = [A]by rewrite somes_None. Qed.n: nat
A: iformula
Δ: list (option iformula)
IH: somes Δ = [A]somes (None :: Δ) = [A]
A split of the linear context is a split of the hypotheses, up to
order.
Δ, Δ1, Δ2: list (option iformula)Δ ≔ Δ1 ⋈ Δ2 → somes Δ ≡ₚ somes Δ1 ++ somes Δ2Δ, Δ1, Δ2: list (option iformula)Δ ≔ Δ1 ⋈ Δ2 → somes Δ ≡ₚ somes Δ1 ++ somes Δ2inversion Ho; subst; rewrite ?somes_Some, ?somes_None, IH; solve_Permutation. Qed.o1, o2, o: option iformula
Δ1, Δ2, Δ: list (option iformula)
Ho: mrg o1 o2 o
IH: somes Δ ≡ₚ somes Δ1 ++ somes Δ2somes (o :: Δ) ≡ₚ somes (o1 :: Δ1) ++ somes (o2 :: Δ2)
A context split, on the sequent side: both premises receive ‼Γ,
and contract_bangs merges the two copies.
Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
C: iformulaΔ ≔ Δ1 ⋈ Δ2 → (‼Γ ++ somes Δ1) ++ ‼Γ ++ somes Δ2 ⊢ C → ‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
C: iformulaΔ ≔ Δ1 ⋈ Δ2 → (‼Γ ++ somes Δ1) ++ ‼Γ ++ somes Δ2 ⊢ C → ‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
C: iformula
Hm: Δ ≔ Δ1 ⋈ Δ2
H: (‼Γ ++ somes Δ1) ++ ‼Γ ++ somes Δ2 ⊢ C‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
C: iformula
Hm: Δ ≔ Δ1 ⋈ Δ2
H: (‼Γ ++ somes Δ1) ++ ‼Γ ++ somes Δ2 ⊢ C‼Γ ++ ‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
C: iformula
Hm: Δ ≔ Δ1 ⋈ Δ2
H: (‼Γ ++ somes Δ1) ++ ‼Γ ++ somes Δ2 ⊢ C(‼Γ ++ somes Δ1) ++ ‼Γ ++ somes Δ2 ≡ₚ ‼Γ ++ ‼Γ ++ somes Δsolve_Permutation. Qed.Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
C: iformula
Hm: Δ ≔ Δ1 ⋈ Δ2
H: (‼Γ ++ somes Δ1) ++ ‼Γ ++ somes Δ2 ⊢ C(‼Γ ++ somes Δ1) ++ ‼Γ ++ somes Δ2 ≡ₚ ‼Γ ++ ‼Γ ++ somes Δ1 ++ somes Δ2
The shape of every elimination: cut the eliminated term A against
a proof that uses A as a hypothesis.
Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
A, C: iformulaΔ ≔ Δ1 ⋈ Δ2 → ‼Γ ++ somes Δ1 ⊢ A → A :: ‼Γ ++ somes Δ2 ⊢ C → ‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
A, C: iformulaΔ ≔ Δ1 ⋈ Δ2 → ‼Γ ++ somes Δ1 ⊢ A → A :: ‼Γ ++ somes Δ2 ⊢ C → ‼Γ ++ somes Δ ⊢ Capply (join _ _ _ _ _ Hm), (cut _ _ _ A); done. Qed.Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
A, C: iformula
Hm: Δ ≔ Δ1 ⋈ Δ2
H1: ‼Γ ++ somes Δ1 ⊢ A
H2: A :: ‼Γ ++ somes Δ2 ⊢ C‼Γ ++ somes Δ ⊢ C
A cut whose second premise uses nothing but the cut formula.
Γ: list iformula
A, C: iformulaΓ ⊢ A → [A] ⊢ C → Γ ⊢ CΓ: list iformula
A, C: iformulaΓ ⊢ A → [A] ⊢ C → Γ ⊢ CΓ: list iformula
A, C: iformula
H1: Γ ⊢ A
H2: [A] ⊢ CΓ ⊢ Cby apply (cut _ _ _ A). Qed.Γ: list iformula
A, C: iformula
H1: Γ ⊢ A
H2: [A] ⊢ CΓ ++ [] ⊢ C
An unrestricted variable: take its !A out of ‼Γ, drop the rest
with bangW, and open it with bangD.
Γ: list iformula
n: nat
A: iformulaΓ !! n = Some A → ‼Γ ⊢ AΓ: list iformula
n: nat
A: iformulaΓ !! n = Some A → ‼Γ ⊢ AΓ: list iformula
n: nat
A: iformula
Hn: Γ !! n = Some A‼Γ ⊢ An: nat
A: iformula
Γ1, Γ2: list iformula‼(Γ1 ++ A :: Γ2) ⊢ An: nat
A: iformula
Γ1, Γ2: list iformula‼Γ1 ++ ‼(A :: Γ2) ⊢ An: nat
A: iformula
Γ1, Γ2: list iformula‼Γ1 ++ !A :: ‼Γ2 ⊢ An: nat
A: iformula
Γ1, Γ2: list iformula(‼Γ1 ++ ‼Γ2) ++ [!A] ⊢ Aapply weaken_bangs, bangD, ax. Qed.n: nat
A: iformula
Γ1, Γ2: list iformula‼(Γ1 ++ Γ2) ++ [!A] ⊢ A
Γ: list iformula
Δ: list (option iformula)
e: tm
A: iformulaΓ ⨾ Δ ⊢ e ∶ A → ‼Γ ++ somes Δ ⊢ AΓ: list iformula
Δ: list (option iformula)
e: tm
A: iformulaΓ ⨾ Δ ⊢ e ∶ A → ‼Γ ++ somes Δ ⊢ AΓ: list iformula
Δ: list (option iformula)
n: nat
A: iformula
H: lone n A Δ‼Γ ++ somes Δ ⊢ AΓ: list iformula
Δ: list (option iformula)
n: nat
A: iformula
H: Γ !! n = Some A
H0: lempty Δ‼Γ ++ somes Δ ⊢ AΓ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Some A :: Δ ⊢ e ∶ B
IHtyped: ‼Γ ++ somes (Some A :: Δ) ⊢ B‼Γ ++ somes Δ ⊢ A ⊸ BΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A ⊸ B
H1: Γ ⨾ Δ2 ⊢ e2 ∶ A
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊸ B
IHtyped2: ‼Γ ++ somes Δ2 ⊢ A‼Γ ++ somes Δ ⊢ BΓ: list iformula
Δ: list (option iformula)
H: lempty Δ‼Γ ++ somes Δ ⊢ 𝟙Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ 𝟙
H1: Γ ⨾ Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ 𝟙
IHtyped2: ‼Γ ++ somes Δ2 ⊢ C‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A
H1: Γ ⨾ Δ2 ⊢ e2 ∶ B
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A
IHtyped2: ‼Γ ++ somes Δ2 ⊢ B‼Γ ++ somes Δ ⊢ A ⊗ BΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A ⊗ B
H1: Γ ⨾ Some B :: Some A :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊗ B
IHtyped2: ‼Γ ++ somes (Some B :: Some A :: Δ2) ⊢ C‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ: list (option iformula)
e1, e2: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e1 ∶ A
H0: Γ ⨾ Δ ⊢ e2 ∶ B
IHtyped1: ‼Γ ++ somes Δ ⊢ A
IHtyped2: ‼Γ ++ somes Δ ⊢ B‼Γ ++ somes Δ ⊢ A & BΓ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e ∶ A & B
IHtyped: ‼Γ ++ somes Δ ⊢ A & B‼Γ ++ somes Δ ⊢ AΓ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e ∶ A & B
IHtyped: ‼Γ ++ somes Δ ⊢ A & B‼Γ ++ somes Δ ⊢ BΓ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e ∶ A
IHtyped: ‼Γ ++ somes Δ ⊢ A‼Γ ++ somes Δ ⊢ A ⊕ BΓ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e ∶ B
IHtyped: ‼Γ ++ somes Δ ⊢ B‼Γ ++ somes Δ ⊢ A ⊕ BΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e, e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ A ⊕ B
H1: Γ ⨾ Some A :: Δ2 ⊢ e1 ∶ C
H2: Γ ⨾ Some B :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊕ B
IHtyped2: ‼Γ ++ somes (Some A :: Δ2) ⊢ C
IHtyped3: ‼Γ ++ somes (Some B :: Δ2) ⊢ C‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ: list (option iformula)‼Γ ++ somes Δ ⊢ ⊤Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e: tm
C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ 𝟘
IHtyped: ‼Γ ++ somes Δ1 ⊢ 𝟘‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ: list (option iformula)
e: tm
A: iformula
H: lempty Δ
H0: Γ ⨾ Δ ⊢ e ∶ A
IHtyped: ‼Γ ++ somes Δ ⊢ A‼Γ ++ somes Δ ⊢ !AΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ !A
H1: A :: Γ ⨾ Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ !A
IHtyped2: ‼(A :: Γ) ++ somes Δ2 ⊢ C‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ: list (option iformula)
n: nat
A: iformula
H: lone n A Δ‼Γ ++ somes Δ ⊢ Aapply weaken_bangs, ax.Γ: list iformula
Δ: list (option iformula)
n: nat
A: iformula
H: lone n A Δ‼Γ ++ [A] ⊢ AΓ: list iformula
Δ: list (option iformula)
n: nat
A: iformula
H: Γ !! n = Some A
H0: lempty Δ‼Γ ++ somes Δ ⊢ Aby eapply uvar_proof.Γ: list iformula
Δ: list (option iformula)
n: nat
A: iformula
H: Γ !! n = Some A
H0: lempty Δ‼Γ ⊢ AΓ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Some A :: Δ ⊢ e ∶ B
IHtyped: ‼Γ ++ somes (Some A :: Δ) ⊢ B‼Γ ++ somes Δ ⊢ A ⊸ BΓ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Some A :: Δ ⊢ e ∶ B
IHtyped: ‼Γ ++ somes (Some A :: Δ) ⊢ BA :: ‼Γ ++ somes Δ ⊢ Bdone.Γ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Some A :: Δ ⊢ e ∶ B
IHtyped: ‼Γ ++ somes (Some A :: Δ) ⊢ B‼Γ ++ A :: somes Δ ⊢ BΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A ⊸ B
H1: Γ ⨾ Δ2 ⊢ e2 ∶ A
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊸ B
IHtyped2: ‼Γ ++ somes Δ2 ⊢ A‼Γ ++ somes Δ ⊢ BΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A ⊸ B
H1: Γ ⨾ Δ2 ⊢ e2 ∶ A
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊸ B
IHtyped2: ‼Γ ++ somes Δ2 ⊢ AA ⊸ B :: ‼Γ ++ somes Δ2 ⊢ Bapply lolliL; [done | apply ax].Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A ⊸ B
H1: Γ ⨾ Δ2 ⊢ e2 ∶ A
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊸ B
IHtyped2: ‼Γ ++ somes Δ2 ⊢ AA ⊸ B :: (‼Γ ++ somes Δ2) ++ [] ⊢ BΓ: list iformula
Δ: list (option iformula)
H: lempty Δ‼Γ ++ somes Δ ⊢ 𝟙apply weaken_bangs, oneR.Γ: list iformula
Δ: list (option iformula)
H: lempty Δ‼Γ ++ [] ⊢ 𝟙Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ 𝟙
H1: Γ ⨾ Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ 𝟙
IHtyped2: ‼Γ ++ somes Δ2 ⊢ C‼Γ ++ somes Δ ⊢ Cby apply oneL.Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ 𝟙
H1: Γ ⨾ Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ 𝟙
IHtyped2: ‼Γ ++ somes Δ2 ⊢ C𝟙 :: ‼Γ ++ somes Δ2 ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A
H1: Γ ⨾ Δ2 ⊢ e2 ∶ B
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A
IHtyped2: ‼Γ ++ somes Δ2 ⊢ B‼Γ ++ somes Δ ⊢ A ⊗ Bby apply tensorR.Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A
H1: Γ ⨾ Δ2 ⊢ e2 ∶ B
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A
IHtyped2: ‼Γ ++ somes Δ2 ⊢ B(‼Γ ++ somes Δ1) ++ ‼Γ ++ somes Δ2 ⊢ A ⊗ BΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A ⊗ B
H1: Γ ⨾ Some B :: Some A :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊗ B
IHtyped2: ‼Γ ++ somes (Some B :: Some A :: Δ2) ⊢ C‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A ⊗ B
H1: Γ ⨾ Some B :: Some A :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊗ B
IHtyped2: ‼Γ ++ somes (Some B :: Some A :: Δ2) ⊢ CA ⊗ B :: ‼Γ ++ somes Δ2 ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A ⊗ B
H1: Γ ⨾ Some B :: Some A :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊗ B
IHtyped2: ‼Γ ++ somes (Some B :: Some A :: Δ2) ⊢ CA :: B :: ‼Γ ++ somes Δ2 ⊢ Cdone.Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ A ⊗ B
H1: Γ ⨾ Some B :: Some A :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊗ B
IHtyped2: ‼Γ ++ somes (Some B :: Some A :: Δ2) ⊢ C‼Γ ++ B :: A :: somes Δ2 ⊢ Cby apply withR.Γ: list iformula
Δ: list (option iformula)
e1, e2: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e1 ∶ A
H0: Γ ⨾ Δ ⊢ e2 ∶ B
IHtyped1: ‼Γ ++ somes Δ ⊢ A
IHtyped2: ‼Γ ++ somes Δ ⊢ B‼Γ ++ somes Δ ⊢ A & BΓ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e ∶ A & B
IHtyped: ‼Γ ++ somes Δ ⊢ A & B‼Γ ++ somes Δ ⊢ Aapply withL1, ax.Γ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e ∶ A & B
IHtyped: ‼Γ ++ somes Δ ⊢ A & B[A & B] ⊢ AΓ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e ∶ A & B
IHtyped: ‼Γ ++ somes Δ ⊢ A & B‼Γ ++ somes Δ ⊢ Bapply withL2, ax.Γ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e ∶ A & B
IHtyped: ‼Γ ++ somes Δ ⊢ A & B[A & B] ⊢ Bby apply plusR1.Γ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e ∶ A
IHtyped: ‼Γ ++ somes Δ ⊢ A‼Γ ++ somes Δ ⊢ A ⊕ Bby apply plusR2.Γ: list iformula
Δ: list (option iformula)
e: tm
A, B: iformula
H: Γ ⨾ Δ ⊢ e ∶ B
IHtyped: ‼Γ ++ somes Δ ⊢ B‼Γ ++ somes Δ ⊢ A ⊕ BΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e, e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ A ⊕ B
H1: Γ ⨾ Some A :: Δ2 ⊢ e1 ∶ C
H2: Γ ⨾ Some B :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊕ B
IHtyped2: ‼Γ ++ somes (Some A :: Δ2) ⊢ C
IHtyped3: ‼Γ ++ somes (Some B :: Δ2) ⊢ C‼Γ ++ somes Δ ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e, e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ A ⊕ B
H1: Γ ⨾ Some A :: Δ2 ⊢ e1 ∶ C
H2: Γ ⨾ Some B :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊕ B
IHtyped2: ‼Γ ++ somes (Some A :: Δ2) ⊢ C
IHtyped3: ‼Γ ++ somes (Some B :: Δ2) ⊢ CA ⊕ B :: ‼Γ ++ somes Δ2 ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e, e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ A ⊕ B
H1: Γ ⨾ Some A :: Δ2 ⊢ e1 ∶ C
H2: Γ ⨾ Some B :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊕ B
IHtyped2: ‼Γ ++ somes (Some A :: Δ2) ⊢ C
IHtyped3: ‼Γ ++ somes (Some B :: Δ2) ⊢ CA :: ‼Γ ++ somes Δ2 ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e, e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ A ⊕ B
H1: Γ ⨾ Some A :: Δ2 ⊢ e1 ∶ C
H2: Γ ⨾ Some B :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊕ B
IHtyped2: ‼Γ ++ somes (Some A :: Δ2) ⊢ C
IHtyped3: ‼Γ ++ somes (Some B :: Δ2) ⊢ CB :: ‼Γ ++ somes Δ2 ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e, e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ A ⊕ B
H1: Γ ⨾ Some A :: Δ2 ⊢ e1 ∶ C
H2: Γ ⨾ Some B :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊕ B
IHtyped2: ‼Γ ++ somes (Some A :: Δ2) ⊢ C
IHtyped3: ‼Γ ++ somes (Some B :: Δ2) ⊢ CA :: ‼Γ ++ somes Δ2 ⊢ Cdone.Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e, e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ A ⊕ B
H1: Γ ⨾ Some A :: Δ2 ⊢ e1 ∶ C
H2: Γ ⨾ Some B :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊕ B
IHtyped2: ‼Γ ++ somes (Some A :: Δ2) ⊢ C
IHtyped3: ‼Γ ++ somes (Some B :: Δ2) ⊢ C‼Γ ++ A :: somes Δ2 ⊢ CΓ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e, e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ A ⊕ B
H1: Γ ⨾ Some A :: Δ2 ⊢ e1 ∶ C
H2: Γ ⨾ Some B :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊕ B
IHtyped2: ‼Γ ++ somes (Some A :: Δ2) ⊢ C
IHtyped3: ‼Γ ++ somes (Some B :: Δ2) ⊢ CB :: ‼Γ ++ somes Δ2 ⊢ Cdone.Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e, e1, e2: tm
A, B, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ A ⊕ B
H1: Γ ⨾ Some A :: Δ2 ⊢ e1 ∶ C
H2: Γ ⨾ Some B :: Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ A ⊕ B
IHtyped2: ‼Γ ++ somes (Some A :: Δ2) ⊢ C
IHtyped3: ‼Γ ++ somes (Some B :: Δ2) ⊢ C‼Γ ++ B :: somes Δ2 ⊢ Capply topR.Γ: list iformula
Δ: list (option iformula)‼Γ ++ somes Δ ⊢ ⊤Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e: tm
C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ 𝟘
IHtyped: ‼Γ ++ somes Δ1 ⊢ 𝟘‼Γ ++ somes Δ ⊢ Capply zeroL.Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e: tm
C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e ∶ 𝟘
IHtyped: ‼Γ ++ somes Δ1 ⊢ 𝟘𝟘 :: ‼Γ ++ somes Δ2 ⊢ CΓ: list iformula
Δ: list (option iformula)
e: tm
A: iformula
H: lempty Δ
H0: Γ ⨾ Δ ⊢ e ∶ A
IHtyped: ‼Γ ++ somes Δ ⊢ A‼Γ ++ somes Δ ⊢ !Aby apply bangR.Γ: list iformula
Δ: list (option iformula)
e: tm
A: iformula
H: lempty Δ
H0: Γ ⨾ Δ ⊢ e ∶ A
IHtyped: ‼Γ ⊢ A‼Γ ⊢ !Aeapply cut_join; done. Qed.Γ: list iformula
Δ, Δ1, Δ2: list (option iformula)
e1, e2: tm
A, C: iformula
H: Δ ≔ Δ1 ⋈ Δ2
H0: Γ ⨾ Δ1 ⊢ e1 ∶ !A
H1: A :: Γ ⨾ Δ2 ⊢ e2 ∶ C
IHtyped1: ‼Γ ++ somes Δ1 ⊢ !A
IHtyped2: ‼(A :: Γ) ++ somes Δ2 ⊢ C‼Γ ++ somes Δ ⊢ C
Consequences for closed programs
e: tm
A: iformula[] ⨾ [] ⊢ e ∶ A → [] ⊢ Aapply curry_howard. Qed.e: tm
A: iformula[] ⨾ [] ⊢ e ∶ A → [] ⊢ A
By cut elimination (Intuitionistic/CutElim.v) that proof can be
taken cut-free. A cut-free proof of a sequent with no hypotheses
ends, up to exchange, in a right rule, just as a closed value is an
introduction form.
e: tm
A: iformula[] ⨾ [] ⊢ e ∶ A → [] ⊢cf Ae: tm
A: iformula[] ⨾ [] ⊢ e ∶ A → [] ⊢cf Aby apply cut_elimination, (closed_proof e). Qed.e: tm
A: iformula
He: [] ⨾ [] ⊢ e ∶ A[] ⊢cf A
For instance swap yields a cut-free proof that ⊗ commutes.
[] ⊢cf $0 ⊗ $1 ⊸ $1 ⊗ $0apply (closed_proof_cf swap), swap_typed. Qed.[] ⊢cf $0 ⊗ $1 ⊸ $1 ⊗ $0
Read contrapositively, the translation turns unprovability into the
nonexistence of programs. Intuitionistic/Phase.v refutes the
following sequents in a phase model, so no program has these types.
No closed program duplicates its argument. LinearTypes.no_copy
rules out one particular term, ƛ ⟪lv 0, lv 0⟫; this rules out all
of them.
e: tm¬ ([] ⨾ [] ⊢ e ∶ $0 ⊸ $0 ⊗ $0)e: tm¬ ([] ⨾ [] ⊢ e ∶ $0 ⊸ $0 ⊗ $0)by apply no_duplicator, (closed_proof e). Qed.e: tm
He: [] ⨾ [] ⊢ e ∶ $0 ⊸ $0 ⊗ $0False
No closed program discards part of its argument.
e: tm¬ ([] ⨾ [] ⊢ e ∶ $0 ⊗ $1 ⊸ $0)e: tm¬ ([] ⨾ [] ⊢ e ∶ $0 ⊗ $1 ⊸ $0)by apply no_eraser, (closed_proof e). Qed.e: tm
He: [] ⨾ [] ⊢ e ∶ $0 ⊗ $1 ⊸ $0False
No closed program has the empty type: the language is consistent as
a logic.
e: tm¬ ([] ⨾ [] ⊢ e ∶ 𝟘)e: tm¬ ([] ⨾ [] ⊢ e ∶ 𝟘)by apply consistency, (closed_proof e). Qed.e: tm
He: [] ⨾ [] ⊢ e ∶ 𝟘False
Under !, duplication is allowed: LinearTypes.dup has the type
that no_duplicating_program rules out for an atom. The phase model
agrees: !$0 ⊸ !$0 ⊗ !$0 is provable, by bangC.
∃ e : tm, [] ⨾ [] ⊢ e ∶ !$0 ⊸ !$0 ⊗ !$0∃ e : tm, [] ⨾ [] ⊢ e ∶ !$0 ⊸ !$0 ⊗ !$0apply dup_typed. Qed.[] ⨾ [] ⊢ dup ∶ !$0 ⊸ !$0 ⊗ !$0