Classical.Sequent: the two-sided sequent calculus for CLL
- every rule now carries a right-hand context Δ as well;
- each connective still has left and right rules, and the rules come in mirror-image pairs. The right rule of a connective looks like the left rule of its De Morgan dual;
- multiplicative rules split both sides: Γ₁ ++ Γ₂ ⊢ Δ₁ ++ Δ₂;
- negation just moves a formula across the turnstile (negL, negR).
Reserved Notation "Γ ⊢[ c ] Δ" (at level 80, c at level 0, no associativity, format "Γ ⊢[ c ] Δ").
The rules
------- ax Γ₁ ⊢ A,Δ₁ A,Γ₂ ⊢ Δ₂ Γ ⊢ Δ Γ ≡ₚ Γ' Δ ≡ₚ Δ'
A ⊢ A ----------------------- cut ------------------------- ex
Γ₁,Γ₂ ⊢ Δ₁,Δ₂ Γ' ⊢ Δ'
Γ ⊢ A,Δ A,Γ ⊢ Δ
----------- ^⊥L ------------ ^⊥R (negation: move across ⊢)
A^⊥,Γ ⊢ Δ Γ ⊢ A^⊥,Δ
Γ ⊢ Δ Γ ⊢ Δ
---------- 𝟙L ------ 𝟙R ------ ⊥L ------------ ⊥R
𝟙,Γ ⊢ Δ ⊢ 𝟙 ⊥ ⊢ Γ ⊢ ⊥,Δ
A,B,Γ ⊢ Δ Γ₁ ⊢ A,Δ₁ Γ₂ ⊢ B,Δ₂
----------- ⊗L ------------------------- ⊗R
A⊗B,Γ ⊢ Δ Γ₁,Γ₂ ⊢ A⊗B,Δ₁,Δ₂
A,Γ₁ ⊢ Δ₁ B,Γ₂ ⊢ Δ₂ Γ ⊢ A,B,Δ
------------------------ ⅋L ------------ ⅋R
A⅋B,Γ₁,Γ₂ ⊢ Δ₁,Δ₂ Γ ⊢ A⅋B,Δ
A,Γ ⊢ Δ B,Γ ⊢ Δ Γ ⊢ A,Δ Γ ⊢ B,Δ
----------- &L₁ ----------- &L₂ ------------------- &R ----------- ⊤R
A&B,Γ ⊢ Δ A&B,Γ ⊢ Δ Γ ⊢ A&B,Δ Γ ⊢ ⊤,Δ
A,Γ ⊢ Δ B,Γ ⊢ Δ Γ ⊢ A,Δ Γ ⊢ B,Δ
------------------ ⊕L ----------- ⊕R₁ ----------- ⊕R₂ ----------- 𝟘L
A⊕B,Γ ⊢ Δ Γ ⊢ A⊕B,Δ Γ ⊢ A⊕B,Δ 𝟘,Γ ⊢ Δ
A,Γ ⊢ Δ Γ ⊢ Δ !A,!A,Γ ⊢ Δ ‼Σ ⊢ A,⁇Π
--------- !D --------- !W ------------ !C ------------ !R
!A,Γ ⊢ Δ !A,Γ ⊢ Δ !A,Γ ⊢ Δ ‼Σ ⊢ !A,⁇Π
Γ ⊢ A,Δ Γ ⊢ Δ Γ ⊢ ?A,?A,Δ A,‼Σ ⊢ ⁇Π
--------- ?D --------- ?W ------------ ?C ------------ ?L
Γ ⊢ ?A,Δ Γ ⊢ ?A,Δ Γ ⊢ ?A,Δ ?A,‼Σ ⊢ ⁇Π
Inductive cll (c : bool) : list cformula -> list cformula -> Prop := (* identity and cut *) | ax A : [A] ⊢[c] [A] | cut Γ₁ Γ₂ Δ₁ Δ₂ A : c = true -> Γ₁ ⊢[c] A :: Δ₁ -> A :: Γ₂ ⊢[c] Δ₂ -> Γ₁ ++ Γ₂ ⊢[c] Δ₁ ++ Δ₂ | ex Γ Γ' Δ Δ' : Γ ≡ₚ Γ' -> Δ ≡ₚ Δ' -> Γ ⊢[c] Δ -> Γ' ⊢[c] Δ' (* negation *) | negL Γ Δ A : Γ ⊢[c] A :: Δ -> A^⊥ :: Γ ⊢[c] Δ | negR Γ Δ A : A :: Γ ⊢[c] Δ -> Γ ⊢[c] A^⊥ :: Δ (* multiplicatives *) | oneL Γ Δ : Γ ⊢[c] Δ -> 𝟙 :: Γ ⊢[c] Δ | oneR : [] ⊢[c] [𝟙] | botL : [⊥] ⊢[c] [] | botR Γ Δ : Γ ⊢[c] Δ -> Γ ⊢[c] ⊥ :: Δ | tensorL Γ Δ A B : A :: B :: Γ ⊢[c] Δ -> A ⊗ B :: Γ ⊢[c] Δ | tensorR Γ₁ Γ₂ Δ₁ Δ₂ A B : Γ₁ ⊢[c] A :: Δ₁ -> Γ₂ ⊢[c] B :: Δ₂ -> Γ₁ ++ Γ₂ ⊢[c] A ⊗ B :: Δ₁ ++ Δ₂ | parL Γ₁ Γ₂ Δ₁ Δ₂ A B : A :: Γ₁ ⊢[c] Δ₁ -> B :: Γ₂ ⊢[c] Δ₂ -> A ⅋ B :: Γ₁ ++ Γ₂ ⊢[c] Δ₁ ++ Δ₂ | parR Γ Δ A B : Γ ⊢[c] A :: B :: Δ -> Γ ⊢[c] A ⅋ B :: Δ (* additives *) | withL1 Γ Δ A B : A :: Γ ⊢[c] Δ -> A & B :: Γ ⊢[c] Δ | withL2 Γ Δ A B : B :: Γ ⊢[c] Δ -> A & B :: Γ ⊢[c] Δ | withR Γ Δ A B : Γ ⊢[c] A :: Δ -> Γ ⊢[c] B :: Δ -> Γ ⊢[c] A & B :: Δ | topR Γ Δ : Γ ⊢[c] ⊤ :: Δ | plusL Γ Δ A B : A :: Γ ⊢[c] Δ -> B :: Γ ⊢[c] Δ -> A ⊕ B :: Γ ⊢[c] Δ | plusR1 Γ Δ A B : Γ ⊢[c] A :: Δ -> Γ ⊢[c] A ⊕ B :: Δ | plusR2 Γ Δ A B : Γ ⊢[c] B :: Δ -> Γ ⊢[c] A ⊕ B :: Δ | zeroL Γ Δ : 𝟘 :: Γ ⊢[c] Δ (* exponentials *) | bangD Γ Δ A : A :: Γ ⊢[c] Δ -> !A :: Γ ⊢[c] Δ | bangW Γ Δ A : Γ ⊢[c] Δ -> !A :: Γ ⊢[c] Δ | bangC Γ Δ A : !A :: !A :: Γ ⊢[c] Δ -> !A :: Γ ⊢[c] Δ | bangR Σ Π A : ‼Σ ⊢[c] A :: ⁇Π -> ‼Σ ⊢[c] !A :: ⁇Π | whyD Γ Δ A : Γ ⊢[c] A :: Δ -> Γ ⊢[c] ? A :: Δ | whyW Γ Δ A : Γ ⊢[c] Δ -> Γ ⊢[c] ? A :: Δ | whyC Γ Δ A : Γ ⊢[c] ? A :: ? A :: Δ -> Γ ⊢[c] ? A :: Δ | whyL Σ Π A : A :: ‼Σ ⊢[c] ⁇Π -> ? A :: ‼Σ ⊢[c] ⁇Π where "Γ ⊢[ c ] Δ" := (cll c Γ Δ) : cll_scope. Notation "Γ ⊢ Δ" := (cll true Γ Δ) (at level 80, no associativity) : cll_scope. Notation "Γ ⊢cf Δ" := (cll false Γ Δ) (at level 80, no associativity) : cll_scope.
Every cut-free proof is a proof.
c: bool
Γ, Δ: list cformulaΓ ⊢cf Δ → Γ ⊢[c] Δ(* The cut case is refuted by [false = true]. Every other rule is re-applied: [constructor] backtracks over the rules until [auto] closes the premises (so [withL1]/[withL2] etc. are told apart). It never picks [cut] or [ex], whose cut formula or source contexts do not occur in the conclusion; [ex] is handled by [eapply]. *) induction 1; try discriminate; solve [constructor; auto | eapply ex; eauto]. Qed.c: bool
Γ, Δ: list cformulaΓ ⊢cf Δ → Γ ⊢[c] Δ
Exchange, conveniently
c: bool
Γ, Γ', Δ, Δ': list cformulaΓ ⊢[c] Δ → Γ ≡ₚ Γ' → Δ ≡ₚ Δ' → Γ' ⊢[c] Δ'intros; eapply ex; eauto. Qed. Ltac ex_to G D := apply (ex' (Γ := G) (Δ := D)); [| solve_Permutation | solve_Permutation].c: bool
Γ, Γ', Δ, Δ': list cformulaΓ ⊢[c] Δ → Γ ≡ₚ Γ' → Δ ≡ₚ Δ' → Γ' ⊢[c] Δ'
Structural rules for ‼Σ and ⁇Π
c: bool
Σ, Γ, Δ: list cformulaΓ ⊢[c] Δ → ‼Σ ++ Γ ⊢[c] Δinduction Σ; simpl; auto using bangW. Qed.c: bool
Σ, Γ, Δ: list cformulaΓ ⊢[c] Δ → ‼Σ ++ Γ ⊢[c] Δc: bool
Π, Γ, Δ: list cformulaΓ ⊢[c] Δ → Γ ⊢[c] ⁇Π ++ Δinduction Π; simpl; auto using whyW. Qed.c: bool
Π, Γ, Δ: list cformulaΓ ⊢[c] Δ → Γ ⊢[c] ⁇Π ++ Δ
For contraction, the induction step contracts the two copies of the
head !A with bangC, parks the survivors in Γ, and uses the
induction hypothesis on the rest of Σ.
c: bool
Σ, Γ, Δ: list cformula‼Σ ++ ‼Σ ++ Γ ⊢[c] Δ → ‼Σ ++ Γ ⊢[c] Δc: bool
Σ, Γ, Δ: list cformula‼Σ ++ ‼Σ ++ Γ ⊢[c] Δ → ‼Σ ++ Γ ⊢[c] Δc: bool
Σ, Δ: list cformula∀ Γ : list cformula, ‼Σ ++ ‼Σ ++ Γ ⊢[c] Δ → ‼Σ ++ Γ ⊢[c] Δc: bool
A: cformula
Σ, Δ: list cformula
IH: ∀ Γ : list cformula, ‼Σ ++ ‼Σ ++ Γ ⊢[c] Δ → ‼Σ ++ Γ ⊢[c] Δ
Γ: list cformula
H: !A :: ‼Σ ++ !A :: ‼Σ ++ Γ ⊢[c] Δ!A :: ‼Σ ++ Γ ⊢[c] Δc: bool
A: cformula
Σ, Δ: list cformula
IH: ∀ Γ : list cformula, ‼Σ ++ ‼Σ ++ Γ ⊢[c] Δ → ‼Σ ++ Γ ⊢[c] Δ
Γ: list cformula
H: !A :: ‼Σ ++ !A :: ‼Σ ++ Γ ⊢[c] Δ!A :: !A :: ‼Σ ++ Γ ⊢[c] Δc: bool
A: cformula
Σ, Δ: list cformula
IH: ∀ Γ : list cformula, ‼Σ ++ ‼Σ ++ Γ ⊢[c] Δ → ‼Σ ++ Γ ⊢[c] Δ
Γ: list cformula
H: !A :: ‼Σ ++ !A :: ‼Σ ++ Γ ⊢[c] Δ‼Σ ++ !A :: !A :: Γ ⊢[c] Δc: bool
A: cformula
Σ, Δ: list cformula
IH: ∀ Γ : list cformula, ‼Σ ++ ‼Σ ++ Γ ⊢[c] Δ → ‼Σ ++ Γ ⊢[c] Δ
Γ: list cformula
H: !A :: ‼Σ ++ !A :: ‼Σ ++ Γ ⊢[c] Δ‼Σ ++ ‼Σ ++ !A :: !A :: Γ ⊢[c] Δexact H. Qed.c: bool
A: cformula
Σ, Δ: list cformula
IH: ∀ Γ : list cformula, ‼Σ ++ ‼Σ ++ Γ ⊢[c] Δ → ‼Σ ++ Γ ⊢[c] Δ
Γ: list cformula
H: !A :: ‼Σ ++ !A :: ‼Σ ++ Γ ⊢[c] Δ!A :: ‼Σ ++ !A :: ‼Σ ++ Γ ⊢[c] Δc: bool
Π, Γ, Δ: list cformulaΓ ⊢[c] ⁇Π ++ ⁇Π ++ Δ → Γ ⊢[c] ⁇Π ++ Δc: bool
Π, Γ, Δ: list cformulaΓ ⊢[c] ⁇Π ++ ⁇Π ++ Δ → Γ ⊢[c] ⁇Π ++ Δc: bool
Π, Γ: list cformula∀ Δ : list cformula, Γ ⊢[c] ⁇Π ++ ⁇Π ++ Δ → Γ ⊢[c] ⁇Π ++ Δc: bool
A: cformula
Π, Γ: list cformula
IH: ∀ Δ : list cformula, Γ ⊢[c] ⁇Π ++ ⁇Π ++ Δ → Γ ⊢[c] ⁇Π ++ Δ
Δ: list cformula
H: Γ ⊢[c] ? A :: ⁇Π ++ ? A :: ⁇Π ++ ΔΓ ⊢[c] ? A :: ⁇Π ++ Δc: bool
A: cformula
Π, Γ: list cformula
IH: ∀ Δ : list cformula, Γ ⊢[c] ⁇Π ++ ⁇Π ++ Δ → Γ ⊢[c] ⁇Π ++ Δ
Δ: list cformula
H: Γ ⊢[c] ? A :: ⁇Π ++ ? A :: ⁇Π ++ ΔΓ ⊢[c] ? A :: ? A :: ⁇Π ++ Δc: bool
A: cformula
Π, Γ: list cformula
IH: ∀ Δ : list cformula, Γ ⊢[c] ⁇Π ++ ⁇Π ++ Δ → Γ ⊢[c] ⁇Π ++ Δ
Δ: list cformula
H: Γ ⊢[c] ? A :: ⁇Π ++ ? A :: ⁇Π ++ ΔΓ ⊢[c] ⁇Π ++ ? A :: ? A :: Δc: bool
A: cformula
Π, Γ: list cformula
IH: ∀ Δ : list cformula, Γ ⊢[c] ⁇Π ++ ⁇Π ++ Δ → Γ ⊢[c] ⁇Π ++ Δ
Δ: list cformula
H: Γ ⊢[c] ? A :: ⁇Π ++ ? A :: ⁇Π ++ ΔΓ ⊢[c] ⁇Π ++ ⁇Π ++ ? A :: ? A :: Δexact H. Qed.c: bool
A: cformula
Π, Γ: list cformula
IH: ∀ Δ : list cformula, Γ ⊢[c] ⁇Π ++ ⁇Π ++ Δ → Γ ⊢[c] ⁇Π ++ Δ
Δ: list cformula
H: Γ ⊢[c] ? A :: ⁇Π ++ ? A :: ⁇Π ++ ΔΓ ⊢[c] ? A :: ⁇Π ++ ? A :: ⁇Π ++ Δ
c: bool
Γ, Δ: list cformula
A, B: cformulaA :: Γ ⊢[c] B :: Δ → Γ ⊢[c] A ⊸ B :: Δc: bool
Γ, Δ: list cformula
A, B: cformulaA :: Γ ⊢[c] B :: Δ → Γ ⊢[c] A ⊸ B :: Δapply parR, negR, H. Qed.c: bool
Γ, Δ: list cformula
A, B: cformula
H: A :: Γ ⊢[c] B :: ΔΓ ⊢[c] A ⊸ B :: Δc: bool
Γ₁, Γ₂, Δ₁, Δ₂: list cformula
A, B: cformulaΓ₁ ⊢[c] A :: Δ₁ → B :: Γ₂ ⊢[c] Δ₂ → A ⊸ B :: Γ₁ ++ Γ₂ ⊢[c] Δ₁ ++ Δ₂c: bool
Γ₁, Γ₂, Δ₁, Δ₂: list cformula
A, B: cformulaΓ₁ ⊢[c] A :: Δ₁ → B :: Γ₂ ⊢[c] Δ₂ → A ⊸ B :: Γ₁ ++ Γ₂ ⊢[c] Δ₁ ++ Δ₂apply parL; [apply negL |]; assumption. Qed.c: bool
Γ₁, Γ₂, Δ₁, Δ₂: list cformula
A, B: cformula
H1: Γ₁ ⊢[c] A :: Δ₁
H2: B :: Γ₂ ⊢[c] Δ₂A ⊸ B :: Γ₁ ++ Γ₂ ⊢[c] Δ₁ ++ Δ₂
Examples
Section Examples. Variables A B C : cformula.
Excluded middle, in its multiplicative form. Its additive form
A ⊕ A^⊥ is not provable.
A, B, C: cformula[] ⊢cf [A ⅋ A^⊥]A, B, C: cformula[] ⊢cf [A ⅋ A^⊥]A, B, C: cformula[] ⊢cf [A; A^⊥]apply negR, ax. Qed.A, B, C: cformula[] ⊢cf [A^⊥; A]
Negation is involutive.
A, B, C: cformula[(A^⊥)^⊥] ⊢cf [A]apply negL, negR, ax. Qed.A, B, C: cformula[(A^⊥)^⊥] ⊢cf [A]A, B, C: cformula[A] ⊢cf [(A^⊥)^⊥]apply negR, negL, ax. Qed.A, B, C: cformula[A] ⊢cf [(A^⊥)^⊥]
⅋ splits the conclusions: an A ⅋ B gives an A and a B on the
right, side by side.
A, B, C: cformula[A ⅋ B] ⊢cf [A; B]apply (parL _ [] [] [A] [B]); apply ax. Qed.A, B, C: cformula[A ⅋ B] ⊢cf [A; B]
De Morgan for the multiplicatives.
A, B, C: cformula[(A ⊗ B)^⊥] ⊢cf [A ⊸ B^⊥]A, B, C: cformula[(A ⊗ B)^⊥] ⊢cf [A ⊸ B^⊥]A, B, C: cformula[] ⊢cf [A; A^⊥]A, B, C: cformula[] ⊢cf [B; B^⊥]A, B, C: cformula[] ⊢cf [A; A^⊥]apply negR, ax.A, B, C: cformula[] ⊢cf [A^⊥; A]A, B, C: cformula[] ⊢cf [B; B^⊥]apply negR, ax. Qed.A, B, C: cformula[] ⊢cf [B^⊥; B]A, B, C: cformula[A ⊸ B^⊥] ⊢cf [(A ⊗ B)^⊥]A, B, C: cformula[A ⊸ B^⊥] ⊢cf [(A ⊗ B)^⊥]A, B, C: cformula[A; B; A ⊸ B^⊥] ⊢cf []apply (parL _ [A] [B] [] []); apply negL, ax. Qed.A, B, C: cformula[A ⊸ B^⊥; A; B] ⊢cf []
De Morgan for the exponentials: ! and ? are dual. Promotion
(bangR, whyL) also needs its contexts named: here Σ and Π
hold at most one formula.
A, B, C: cformula[(!A)^⊥] ⊢cf [? A^⊥]A, B, C: cformula[(!A)^⊥] ⊢cf [? A^⊥]A, B, C: cformula‼[] ⊢cf A :: ⁇[A^⊥]apply whyD, negR, ax. Qed.A, B, C: cformula[] ⊢cf [? A^⊥; A]A, B, C: cformula[? A^⊥] ⊢cf [(!A)^⊥]A, B, C: cformula[? A^⊥] ⊢cf [(!A)^⊥]A, B, C: cformula[!A; ? A^⊥] ⊢cf []apply (whyL _ [A] []), negL, bangD, ax. Qed.A, B, C: cformula[? A^⊥; !A] ⊢cf []
The intuitionistic examples still work, through the derived ⊸
rules.
A, B, C: cformula[A ⊗ B ⊸ C] ⊢cf [A ⊸ B ⊸ C]A, B, C: cformula[A ⊗ B ⊸ C] ⊢cf [A ⊸ B ⊸ C]A, B, C: cformula[B; A; A ⊗ B ⊸ C] ⊢cf [C]A, B, C: cformula[A ⊗ B ⊸ C; A; B] ⊢cf [C]apply (tensorR _ [A] [B] [] []); apply ax. Qed.A, B, C: cformula[A; B] ⊢cf [A ⊗ B]
!A can be duplicated.
A, B, C: cformula[!A] ⊢cf [!A ⊗ !A]apply bangC, (tensorR _ [!A] [!A] [] []); apply ax. Qed.A, B, C: cformula[!A] ⊢cf [!A ⊗ !A]
A use of cut. Classical/CutElim.v shows the cut could be
avoided.
A, B, C: cformula[A ⊸ B; B ⊸ C; A] ⊢ [C]A, B, C: cformula[A ⊸ B; B ⊸ C; A] ⊢ [C]A, B, C: cformula[A ⊸ B; A; B ⊸ C] ⊢ [C]A, B, C: cformula[A ⊸ B; A] ⊢ [B]A, B, C: cformula[B; B ⊸ C] ⊢ [C]apply (lolliL _ [A] [] [] [B]); apply ax.A, B, C: cformula[A ⊸ B; A] ⊢ [B]A, B, C: cformula[B; B ⊸ C] ⊢ [C]apply (lolliL _ [B] [] [] [C]); apply ax. Qed. End Examples.A, B, C: cformula[B ⊸ C; B] ⊢ [C]