Logic.Syntax


namespace Syntax


inductive Tm : Type where
  | var : ℕ → Tm
  | and : TmTmTm
  | or  : TmTmTm
  | imp :  TmTmTm
  | tt  : Tm
  | ff  : Tm


open Tm


scoped infixr:35 " ∧ " => Tm.and

scoped infixr:30 " ∨ " => Tm.or

scoped infixr:25 " ⇒ " => Tm.imp


abbrev Ctxt := List Tm


instance : LE Ctxt := (· <:+ ·)


instance : Preorder Ctxt where
  le := (· <:+ ·)
  le_refl := fun _ => List.suffix_rfl
  le_trans := fun _ _ _ => List.IsSuffix.trans


inductive Pf : (Γ : Ctxt) → TmProp where
  | assume : ∀ {Γ : Ctxt} {P : Tm} , Pf (P :: Γ ) P
  | wk : ∀ {Γ Δ : Ctxt} {P : Tm}, ΓΔPf Γ PPf Δ P
  | and_I : ∀ {Γ : Ctxt} {P Q : Tm}, Pf Γ PPf Γ QPf Γ (PQ)
  | and_E₁ : ∀ {Γ : Ctxt} {P Q : Tm}, Pf Γ (PQ) → Pf Γ P
  | and_E₂ : ∀ {Γ : Ctxt} {P Q : Tm}, Pf Γ (PQ) → Pf Γ Q

  | or_I₁ : ∀ {Γ : Ctxt} {P Q : Tm}, Pf Γ PPf Γ (PQ)
  | or_I₂ : ∀ {Γ : Ctxt} {P Q : Tm}, Pf Γ QPf Γ (PQ)
  | or_E  : ∀ {Γ : Ctxt} {P Q C : Tm}, Pf Γ (PQ) → Pf (P :: Γ) CPf (Q :: Γ) CPf Γ C
  | imp_I :  ∀ {Γ : Ctxt} {P Q : Tm}, Pf (P :: Γ) QPf Γ (PQ)
  | imp_E :  ∀ {Γ : Ctxt} {P Q : Tm}, Pf Γ (PQ) → Pf Γ PPf Γ Q
  | ff_E  : ∀ {Γ : Ctxt}{P : Tm}, Pf Γ ffPf Γ P
  | tt_I :  ∀ {Γ : Ctxt}, Pf Γ tt


def example1 : Pf [] ((var 0var 1) ∧ var 0var 1) := by
Pf [] ((var 0 var 1) var 0 var 1)
apply Pf.imp_I
a
Pf [(var 0 var 1) var 0] (var 1)
apply Pf.imp_E
a.a
Pf [(var 0 var 1) var 0] (?a.P✝ var 1)
a.a
Pf [(var 0 var 1) var 0] ?a.P✝
a.P
Tm
·
a.a
Pf [(var 0 var 1) var 0] (?a.P✝ var 1)
apply Pf.and_E₁
a.a.a
Pf [(var 0 var 1) var 0] ((?a.P✝ var 1) ?a.a.Q✝)
a.a.Q
Tm
apply Pf.assume ·
a.a
Pf [(var 0 var 1) var 0] ?a.P✝
apply Pf.and_E₂
a.a.a
Pf [(var 0 var 1) var 0] (?a.a.P✝ var 0)
a.a.P
Tm
apply Pf.assume



lemma cut {tm₂ : Tm} (tm₁ : Tm)
   (A : Pf Γ tm₁) (B : Pf (tm₁ :: Γ) tm₂) : Pf Γ tm₂ := by
Γ : Ctxt
tm₂ : Tm
tm₁ : Tm
A : Pf Γ tm₁
B : Pf (tm₁ :: Γ) tm₂
Pf Γ tm₂
have B' : Pf Γ (tm₁tm₂) := by
Γ : Ctxt
tm₂ : Tm
tm₁ : Tm
A : Pf Γ tm₁
B : Pf (tm₁ :: Γ) tm₂
Pf Γ tm₂
apply Pf.imp_I
a
Γ : Ctxt
tm₂ : Tm
tm₁ : Tm
A : Pf Γ tm₁
B : Pf (tm₁ :: Γ) tm₂
Pf (tm₁ :: Γ) tm₂
; assumption apply Pf.imp_E B'
Γ : Ctxt
tm₂ : Tm
tm₁ : Tm
A : Pf Γ tm₁
B : Pf (tm₁ :: Γ) tm₂
B' : Pf Γ (tm₁ tm₂)
Pf Γ tm₁
assumption


namespace Pf


theorem of_mem {Γ : Ctxt} {P : Tm} (h : PΓ) : Pf Γ P := by
Γ : Ctxt
P : Tm
h : P Γ
Pf Γ P
induction Γ with | nil =>
nil
P : Tm
h : P []
Pf [] P
cases h | cons Q Γ ih =>
cons
P : Tm
Q : Tm
Γ : List Tm
ih : P ΓPf Γ P
h : P Q :: Γ
Pf (Q :: Γ) P
simp at h
cons
P : Tm
Q : Tm
Γ : List Tm
ih : P ΓPf Γ P
h : P = Q P Γ
Pf (Q :: Γ) P
rcases h with rfl | h
cons.inl
P : Tm
Γ : List Tm
ih : P ΓPf Γ P
Pf (P :: Γ) P
cons.inr
P : Tm
Q : Tm
Γ : List Tm
ih : P ΓPf Γ P
h : P Γ
Pf (Q :: Γ) P
·
cons.inl
P : Tm
Γ : List Tm
ih : P ΓPf Γ P
Pf (P :: Γ) P
exact Pf.assume ·
cons.inr
P : Tm
Q : Tm
Γ : List Tm
ih : P ΓPf Γ P
h : P Γ
Pf (Q :: Γ) P
exact Pf.wk (List.suffix_cons Q Γ) (ih h)


lemma quodlibet (φ t : Tm) : Pf [φTm.ff] (φt) := by
φ : Tm
t : Tm
Pf [φ ff] (φ t)
apply Pf.imp_I
a
φ : Tm
t : Tm
Pf [φ, φ ff] t
apply Pf.ff_E
a.a
φ : Tm
t : Tm
Pf [φ, φ ff] ff
apply Pf.imp_E
a.a.a
φ : Tm
t : Tm
Pf [φ, φ ff] (?a.a.P✝ ff)
a.a.a
φ : Tm
t : Tm
Pf [φ, φ ff] ?a.a.P✝
a.a.P
φ : Tm
t : Tm
Tm
·
a.a.a
φ : Tm
t : Tm
Pf [φ, φ ff] (?a.a.P✝ ff)
have hmem : (φTm.ff) ∈ [φ, φTm.ff] := by
φ : Tm
t : Tm
Pf [φ ff] (φ t)
simp apply of_mem hmem ·
a.a.a
φ : Tm
t : Tm
Pf [φ, φ ff] ?a.a.P✝
exact Pf.assume


lemma or_cases_to (φ ψ A : Tm) : Pf [φψ, φA, ψA] A := by
φ : Tm
ψ : Tm
A : Tm
Pf [φ ψ, φ A, ψ A] A
apply Pf.or_E
a
φ : Tm
ψ : Tm
A : Tm
Pf [φ ψ, φ A, ψ A] (?P ?Q)
a
φ : Tm
ψ : Tm
A : Tm
Pf [?P, φ ψ, φ A, ψ A] A
a
φ : Tm
ψ : Tm
A : Tm
Pf [?Q, φ ψ, φ A, ψ A] A
P
φ : Tm
ψ : Tm
A : Tm
Tm
Q
φ : Tm
ψ : Tm
A : Tm
Tm
·
a
φ : Tm
ψ : Tm
A : Tm
Pf [φ ψ, φ A, ψ A] (?P ?Q)
have hmem : (φψ) ∈ [φψ, φA, ψA] := by
φ : Tm
ψ : Tm
A : Tm
Pf [φ ψ, φ A, ψ A] A
simp exact Pf.of_mem hmem ·
a
φ : Tm
ψ : Tm
A : Tm
Pf [?P, φ ψ, φ A, ψ A] A
apply Pf.imp_E
a.a
φ : Tm
ψ : Tm
A : Tm
Pf [φ, φ ψ, φ A, ψ A] (?a.P✝ A)
a.a
φ : Tm
ψ : Tm
A : Tm
Pf [φ, φ ψ, φ A, ψ A] ?a.P✝
a.P
φ : Tm
ψ : Tm
A : Tm
Tm
·
a.a
φ : Tm
ψ : Tm
A : Tm
Pf [φ, φ ψ, φ A, ψ A] (?a.P✝ A)
have hmem : (φA) ∈ [φ, φψ, φA, ψA] := by
φ : Tm
ψ : Tm
A : Tm
Pf [φ ψ, φ A, ψ A] A
simp exact Pf.of_mem hmem ·
a.a
φ : Tm
ψ : Tm
A : Tm
Pf [φ, φ ψ, φ A, ψ A] ?a.P✝
exact Pf.assume ·
a
φ : Tm
ψ : Tm
A : Tm
Pf [?Q, φ ψ, φ A, ψ A] A
apply Pf.imp_E
a.a
φ : Tm
ψ : Tm
A : Tm
Pf [ψ, φ ψ, φ A, ψ A] (?a.P✝ A)
a.a
φ : Tm
ψ : Tm
A : Tm
Pf [ψ, φ ψ, φ A, ψ A] ?a.P✝
a.P
φ : Tm
ψ : Tm
A : Tm
Tm
·
a.a
φ : Tm
ψ : Tm
A : Tm
Pf [ψ, φ ψ, φ A, ψ A] (?a.P✝ A)
have hmem : (ψA) ∈ [ψ, φψ, φA, ψA] := by
φ : Tm
ψ : Tm
A : Tm
Pf [φ ψ, φ A, ψ A] A
simp exact Pf.of_mem hmem ·
a.a
φ : Tm
ψ : Tm
A : Tm
Pf [ψ, φ ψ, φ A, ψ A] ?a.P✝
exact Pf.assume


theorem multicut {Δ : Ctxt} {P : Tm} (h : Pf Δ P) :
    ∀ {Γ : Ctxt}, (∀ QΔ, Pf Γ Q) → Pf Γ P := by
Δ : Ctxt
P : Tm
h : Pf Δ P
∀ {Γ : Ctxt}, (∀ QΔ, Pf Γ Q) → Pf Γ P
induction h with | assume =>
assume
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ P✝
intro Γ
assume
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Γ : Ctxt
: QP✝ :: Γ✝, Pf Γ Q
Pf Γ P✝
exact _ (by
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Γ : Ctxt
: QP✝ :: Γ✝, Pf Γ Q
P✝ P✝ :: Γ✝
simp) | wk hP ih =>
wk
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
Δ✝ : Ctxt
P✝ : Tm
: Γ✝ Δ✝
hP : Pf Γ✝ P✝
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
∀ {Γ : Ctxt}, (∀ QΔ✝, Pf Γ Q) → Pf Γ P✝
intro Γ
wk
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
Δ✝ : Ctxt
P✝ : Tm
: Γ✝ Δ✝
hP : Pf Γ✝ P✝
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
Γ : Ctxt
: QΔ✝, Pf Γ Q
Pf Γ P✝
apply ih
wk.a
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
Δ✝ : Ctxt
P✝ : Tm
: Γ✝ Δ✝
hP : Pf Γ✝ P✝
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
Γ : Ctxt
: QΔ✝, Pf Γ Q
QΓ✝, Pf Γ Q
intro Q hQ
wk.a
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
Δ✝ : Ctxt
P✝ : Tm
: Γ✝ Δ✝
hP : Pf Γ✝ P✝
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
Γ : Ctxt
: QΔ✝, Pf Γ Q
Q : Tm
hQ : Q Γ✝
Pf Γ Q
exact Q (.sublist.subset hQ) | and_I hP hQ ihP ihQ =>
and_I
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hP : Pf Γ✝ P✝
hQ : Pf Γ✝ Q✝
ihP : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
ihQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ Q✝
∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
intro Γ
and_I
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hP : Pf Γ✝ P✝
hQ : Pf Γ✝ Q✝
ihP : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
ihQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ Q✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
Pf Γ (P✝ Q✝)
exact Pf.and_I (ihP ) (ihQ ) | and_E₁ hPQ ih =>
and_E₁
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
intro Γ
and_E₁
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
Γ : Ctxt
: QΓ✝, Pf Γ Q
Pf Γ P✝
exact Pf.and_E₁ (ih ) | and_E₂ hPQ ih =>
and_E₂
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ Q✝
intro Γ
and_E₂
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
Γ : Ctxt
: QΓ✝, Pf Γ Q
Pf Γ Q✝
exact Pf.and_E₂ (ih ) | or_I₁ hP ih =>
or_I₁
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hP : Pf Γ✝ P✝
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
intro Γ
or_I₁
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hP : Pf Γ✝ P✝
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
Pf Γ (P✝ Q✝)
exact Pf.or_I₁ (ih ) | or_I₂ hQ ih =>
or_I₂
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hQ : Pf Γ✝ Q✝
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ Q✝
∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
intro Γ
or_I₂
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hQ : Pf Γ✝ Q✝
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ Q✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
Pf Γ (P✝ Q✝)
exact Pf.or_I₂ (ih ) | or_E hPQ hPC hQC ihPQ ihPC ihQC =>
or_E
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
C✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hPC : Pf (P✝ :: Γ✝) C✝
hQC : Pf (Q✝ :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ C✝
intro Γ
or_E
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
C✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hPC : Pf (P✝ :: Γ✝) C✝
hQC : Pf (Q✝ :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
Pf Γ C✝
exact Pf.or_E (ihPQ ) (ihPC (Γ := _ :: Γ) (fun R hR => by
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
C✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hPC : Pf (P✝ :: Γ✝) C✝
hQC : Pf (Q✝ :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R P✝ :: Γ✝
Pf (P✝ :: Γ) R
simp at hR
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
C✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hPC : Pf (P✝ :: Γ✝) C✝
hQC : Pf (Q✝ :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R = P✝ R Γ✝
Pf (P✝ :: Γ) R
rcases hR with rfl | hR
inl
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
Q✝ : Tm
C✝ : Tm
hQC : Pf (Q✝ :: Γ✝) C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hPQ : Pf Γ✝ (R Q✝)
hPC : Pf (R :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (R Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QR :: Γ✝, Pf Γ Q) → Pf Γ C✝
Pf (R :: Γ) R
inr
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
C✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hPC : Pf (P✝ :: Γ✝) C✝
hQC : Pf (Q✝ :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R Γ✝
Pf (P✝ :: Γ) R
·
inl
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
Q✝ : Tm
C✝ : Tm
hQC : Pf (Q✝ :: Γ✝) C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hPQ : Pf Γ✝ (R Q✝)
hPC : Pf (R :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (R Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QR :: Γ✝, Pf Γ Q) → Pf Γ C✝
Pf (R :: Γ) R
exact Pf.assume ·
inr
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
C✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hPC : Pf (P✝ :: Γ✝) C✝
hQC : Pf (Q✝ :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R Γ✝
Pf (P✝ :: Γ) R
exact Pf.wk (List.suffix_cons _ Γ) ( R hR))) (ihQC (Γ := _ :: Γ) (fun R hR => by
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
C✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hPC : Pf (P✝ :: Γ✝) C✝
hQC : Pf (Q✝ :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R Q✝ :: Γ✝
Pf (Q✝ :: Γ) R
simp at hR
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
C✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hPC : Pf (P✝ :: Γ✝) C✝
hQC : Pf (Q✝ :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R = Q✝ R Γ✝
Pf (Q✝ :: Γ) R
rcases hR with rfl | hR
inl
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
C✝ : Tm
hPC : Pf (P✝ :: Γ✝) C✝
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hPQ : Pf Γ✝ (P✝ R)
hQC : Pf (R :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ R)
ihQC : ∀ {Γ : Ctxt}, (∀ QR :: Γ✝, Pf Γ Q) → Pf Γ C✝
Pf (R :: Γ) R
inr
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
C✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hPC : Pf (P✝ :: Γ✝) C✝
hQC : Pf (Q✝ :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R Γ✝
Pf (Q✝ :: Γ) R
·
inl
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
C✝ : Tm
hPC : Pf (P✝ :: Γ✝) C✝
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hPQ : Pf Γ✝ (P✝ R)
hQC : Pf (R :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ R)
ihQC : ∀ {Γ : Ctxt}, (∀ QR :: Γ✝, Pf Γ Q) → Pf Γ C✝
Pf (R :: Γ) R
exact Pf.assume ·
inr
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
C✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hPC : Pf (P✝ :: Γ✝) C✝
hQC : Pf (Q✝ :: Γ✝) C✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihPC : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
ihQC : ∀ {Γ : Ctxt}, (∀ QQ✝ :: Γ✝, Pf Γ Q) → Pf Γ C✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R Γ✝
Pf (Q✝ :: Γ) R
exact Pf.wk (List.suffix_cons _ Γ) ( R hR))) | imp_I hPQ ih =>
imp_I
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf (P✝ :: Γ✝) Q✝
ih : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ Q✝
∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
intro Γ
imp_I
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf (P✝ :: Γ✝) Q✝
ih : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ Q✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
Pf Γ (P✝ Q✝)
exact Pf.imp_I (ih (Γ := _ :: Γ) (fun R hR => by
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf (P✝ :: Γ✝) Q✝
ih : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ Q✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R P✝ :: Γ✝
Pf (P✝ :: Γ) R
simp at hR
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf (P✝ :: Γ✝) Q✝
ih : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ Q✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R = P✝ R Γ✝
Pf (P✝ :: Γ) R
rcases hR with rfl | hR
inl
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
Q✝ : Tm
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hPQ : Pf (R :: Γ✝) Q✝
ih : ∀ {Γ : Ctxt}, (∀ QR :: Γ✝, Pf Γ Q) → Pf Γ Q✝
Pf (R :: Γ) R
inr
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf (P✝ :: Γ✝) Q✝
ih : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ Q✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R Γ✝
Pf (P✝ :: Γ) R
·
inl
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
Q✝ : Tm
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hPQ : Pf (R :: Γ✝) Q✝
ih : ∀ {Γ : Ctxt}, (∀ QR :: Γ✝, Pf Γ Q) → Pf Γ Q✝
Pf (R :: Γ) R
exact Pf.assume ·
inr
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf (P✝ :: Γ✝) Q✝
ih : ∀ {Γ : Ctxt}, (∀ QP✝ :: Γ✝, Pf Γ Q) → Pf Γ Q✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
R : Tm
hR : R Γ✝
Pf (P✝ :: Γ) R
exact Pf.wk (List.suffix_cons _ Γ) ( R hR))) | imp_E hPQ hP ihPQ ihP =>
imp_E
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hP : Pf Γ✝ P✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihP : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ Q✝
intro Γ
imp_E
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
Q✝ : Tm
hPQ : Pf Γ✝ (P✝ Q✝)
hP : Pf Γ✝ P✝
ihPQ : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ (P✝ Q✝)
ihP : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
Γ : Ctxt
: QΓ✝, Pf Γ Q
Pf Γ Q✝
exact Pf.imp_E (ihPQ ) (ihP ) | ff_E hff ih =>
ff_E
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
hff : Pf Γ✝ ff
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ ff
∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ P✝
intro Γ
ff_E
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
P✝ : Tm
hff : Pf Γ✝ ff
ih : ∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ ff
Γ : Ctxt
: QΓ✝, Pf Γ Q
Pf Γ P✝
exact Pf.ff_E (ih ) | tt_I =>
tt_I
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
∀ {Γ : Ctxt}, (∀ QΓ✝, Pf Γ Q) → Pf Γ tt
intro Γ
tt_I
Δ : Ctxt
P : Tm
Γ✝ : Ctxt
Γ : Ctxt
: QΓ✝, Pf Γ Q
Pf Γ tt
exact Pf.tt_I


theorem monotone_mem (Γ Δ : Ctxt) {P : Tm} (hmem : ∀ QΓ, QΔ) :
    Pf Γ PPf Δ P := by
Γ : Ctxt
Δ : Ctxt
P : Tm
hmem : QΓ, Q Δ
Pf Γ PPf Δ P
intro hP
Γ : Ctxt
Δ : Ctxt
P : Tm
hmem : QΓ, Q Δ
hP : Pf Γ P
Pf Δ P
exact hP.multicut (fun Q hQ => of_mem (hmem Q hQ))


end Pf


end Syntax