l3lab/ntp-mathlib huggingface dataset:
theorem card_sigma : #(Σn, L.Term (Sum α (Fin n))) = max ℵ₀ #(Sum α (Σi, L.Functions i)) := by
  refine' le_antisymm _ _
  · rw [mk_sigma]
    refine' (sum_le_iSup_lift _).trans _
    rw [mk_nat, lift_aleph0, mul_eq_max_of_aleph0_le_left le_rfl, max_le_iff,
      ciSup_le_iff' (bddAbove_range _)]
    · refine' ⟨le_max_left _ _, fun i => card_le.trans _⟩
      refine' max_le (le_max_left _ _) _
      rw [← add_eq_max le_rfl, mk_sum, mk_sum, mk_sum, add_comm (Cardinal.lift #α), lift_add,
        add_assoc, lift_lift, lift_lift, mk_fin, lift_natCast]
      exact add_le_add_right (nat_lt_aleph0 _).le _
    · rw [← one_le_iff_ne_zero]
      refine' _root_.trans _ (le_ciSup (bddAbove_range _) 1)
      rw [one_le_iff_ne_zero, mk_ne_zero_iff]
      exact ⟨var (Sum.inr 0)⟩
  · rw [max_le_iff, ← infinite_iff]
    refine' ⟨Infinite.of_injective (fun i => ⟨i + 1, var (Sum.inr i)⟩) fun i j ij => _, _⟩
    · cases ij
      rfl
    · rw [Cardinal.le_def]
      refine' ⟨⟨Sum.elim (fun i => ⟨0, var (Sum.inl i)⟩)
        fun F => ⟨1, func F.2 fun _ => var (Sum.inr 0)⟩, _⟩⟩
      · rintro (a | a) (b | b) h
        · 

Proof state:
case refine'_2.refine'_2.inl.inl
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
a b : α
h :
  Sum.elim (fun i => { fst := 0, snd := var (Sum.inl i) })
      (fun F => { fst := 1, snd := func F.snd fun x => var (Sum.inr 0) }) (Sum.inl a) =
    Sum.elim (fun i => { fst := 0, snd := var (Sum.inl i) })
      (fun F => { fst := 1, snd := func F.snd fun x => var (Sum.inr 0) }) (Sum.inl b)
⊢ Sum.inl a = Sum.inl b

Next tactic:
simp only [Sum.elim_inl, Sigma.mk.inj_iff, heq_eq_eq, var.injEq, Sum.inl.injEq, true_and]
            at h
theorem card_sigma : #(Σn, L.Term (Sum α (Fin n))) = max ℵ₀ #(Sum α (Σi, L.Functions i)) := by
  refine' le_antisymm _ _
  · rw [mk_sigma]
    refine' (sum_le_iSup_lift _).trans _
    rw [mk_nat, lift_aleph0, mul_eq_max_of_aleph0_le_left le_rfl, max_le_iff,
      ciSup_le_iff' (bddAbove_range _)]
    · refine' ⟨le_max_left _ _, fun i => card_le.trans _⟩
      refine' max_le (le_max_left _ _) _
      rw [← add_eq_max le_rfl, mk_sum, mk_sum, mk_sum, add_comm (Cardinal.lift #α), lift_add,
        add_assoc, lift_lift, lift_lift, mk_fin, lift_natCast]
      exact add_le_add_right (nat_lt_aleph0 _).le _
    · rw [← one_le_iff_ne_zero]
      refine' _root_.trans _ (le_ciSup (bddAbove_range _) 1)
      rw [one_le_iff_ne_zero, mk_ne_zero_iff]
      exact ⟨var (Sum.inr 0)⟩
  · rw [max_le_iff, ← infinite_iff]
    refine' ⟨Infinite.of_injective (fun i => ⟨i + 1, var (Sum.inr i)⟩) fun i j ij => _, _⟩
    · cases ij
      rfl
    · rw [Cardinal.le_def]
      refine' ⟨⟨Sum.elim (fun i => ⟨0, var (Sum.inl i)⟩)
        fun F => ⟨1, func F.2 fun _ => var (Sum.inr 0)⟩, _⟩⟩
      · rintro (a | a) (b | b) h
        · simp only [Sum.elim_inl, Sigma.mk.inj_iff, heq_eq_eq, var.injEq, Sum.inl.injEq, true_and]
            at h
          

Proof state:
case refine'_2.refine'_2.inl.inl
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
a b : α
h : a = b
⊢ Sum.inl a = Sum.inl b

Next tactic:
rw [h]
theorem card_sigma : #(Σn, L.Term (Sum α (Fin n))) = max ℵ₀ #(Sum α (Σi, L.Functions i)) := by
  refine' le_antisymm _ _
  · rw [mk_sigma]
    refine' (sum_le_iSup_lift _).trans _
    rw [mk_nat, lift_aleph0, mul_eq_max_of_aleph0_le_left le_rfl, max_le_iff,
      ciSup_le_iff' (bddAbove_range _)]
    · refine' ⟨le_max_left _ _, fun i => card_le.trans _⟩
      refine' max_le (le_max_left _ _) _
      rw [← add_eq_max le_rfl, mk_sum, mk_sum, mk_sum, add_comm (Cardinal.lift #α), lift_add,
        add_assoc, lift_lift, lift_lift, mk_fin, lift_natCast]
      exact add_le_add_right (nat_lt_aleph0 _).le _
    · rw [← one_le_iff_ne_zero]
      refine' _root_.trans _ (le_ciSup (bddAbove_range _) 1)
      rw [one_le_iff_ne_zero, mk_ne_zero_iff]
      exact ⟨var (Sum.inr 0)⟩
  · rw [max_le_iff, ← infinite_iff]
    refine' ⟨Infinite.of_injective (fun i => ⟨i + 1, var (Sum.inr i)⟩) fun i j ij => _, _⟩
    · cases ij
      rfl
    · rw [Cardinal.le_def]
      refine' ⟨⟨Sum.elim (fun i => ⟨0, var (Sum.inl i)⟩)
        fun F => ⟨1, func F.2 fun _ => var (Sum.inr 0)⟩, _⟩⟩
      · rintro (a | a) (b | b) h
        · simp only [Sum.elim_inl, Sigma.mk.inj_iff, heq_eq_eq, var.injEq, Sum.inl.injEq, true_and]
            at h
          rw [h]
        · 

Proof state:
case refine'_2.refine'_2.inl.inr
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
a : α
b : (i : ℕ) × Functions L i
h :
  Sum.elim (fun i => { fst := 0, snd := var (Sum.inl i) })
      (fun F => { fst := 1, snd := func F.snd fun x => var (Sum.inr 0) }) (Sum.inl a) =
    Sum.elim (fun i => { fst := 0, snd := var (Sum.inl i) })
      (fun F => { fst := 1, snd := func F.snd fun x => var (Sum.inr 0) }) (Sum.inr b)
⊢ Sum.inl a = Sum.inr b

Next tactic:
simp only [Sum.elim_inl, Sum.elim_inr, Sigma.mk.inj_iff, false_and] at h
theorem card_sigma : #(Σn, L.Term (Sum α (Fin n))) = max ℵ₀ #(Sum α (Σi, L.Functions i)) := by
  refine' le_antisymm _ _
  · rw [mk_sigma]
    refine' (sum_le_iSup_lift _).trans _
    rw [mk_nat, lift_aleph0, mul_eq_max_of_aleph0_le_left le_rfl, max_le_iff,
      ciSup_le_iff' (bddAbove_range _)]
    · refine' ⟨le_max_left _ _, fun i => card_le.trans _⟩
      refine' max_le (le_max_left _ _) _
      rw [← add_eq_max le_rfl, mk_sum, mk_sum, mk_sum, add_comm (Cardinal.lift #α), lift_add,
        add_assoc, lift_lift, lift_lift, mk_fin, lift_natCast]
      exact add_le_add_right (nat_lt_aleph0 _).le _
    · rw [← one_le_iff_ne_zero]
      refine' _root_.trans _ (le_ciSup (bddAbove_range _) 1)
      rw [one_le_iff_ne_zero, mk_ne_zero_iff]
      exact ⟨var (Sum.inr 0)⟩
  · rw [max_le_iff, ← infinite_iff]
    refine' ⟨Infinite.of_injective (fun i => ⟨i + 1, var (Sum.inr i)⟩) fun i j ij => _, _⟩
    · cases ij
      rfl
    · rw [Cardinal.le_def]
      refine' ⟨⟨Sum.elim (fun i => ⟨0, var (Sum.inl i)⟩)
        fun F => ⟨1, func F.2 fun _ => var (Sum.inr 0)⟩, _⟩⟩
      · rintro (a | a) (b | b) h
        · simp only [Sum.elim_inl, Sigma.mk.inj_iff, heq_eq_eq, var.injEq, Sum.inl.injEq, true_and]
            at h
          rw [h]
        · simp only [Sum.elim_inl, Sum.elim_inr, Sigma.mk.inj_iff, false_and] at h
        · 

Proof state:
case refine'_2.refine'_2.inr.inl
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
a : (i : ℕ) × Functions L i
b : α
h :
  Sum.elim (fun i => { fst := 0, snd := var (Sum.inl i) })
      (fun F => { fst := 1, snd := func F.snd fun x => var (Sum.inr 0) }) (Sum.inr a) =
    Sum.elim (fun i => { fst := 0, snd := var (Sum.inl i) })
      (fun F => { fst := 1, snd := func F.snd fun x => var (Sum.inr 0) }) (Sum.inl b)
⊢ Sum.inr a = Sum.inl b

Next tactic:
simp only [Sum.elim_inr, Sum.elim_inl, Sigma.mk.inj_iff, false_and] at h
theorem card_sigma : #(Σn, L.Term (Sum α (Fin n))) = max ℵ₀ #(Sum α (Σi, L.Functions i)) := by
  refine' le_antisymm _ _
  · rw [mk_sigma]
    refine' (sum_le_iSup_lift _).trans _
    rw [mk_nat, lift_aleph0, mul_eq_max_of_aleph0_le_left le_rfl, max_le_iff,
      ciSup_le_iff' (bddAbove_range _)]
    · refine' ⟨le_max_left _ _, fun i => card_le.trans _⟩
      refine' max_le (le_max_left _ _) _
      rw [← add_eq_max le_rfl, mk_sum, mk_sum, mk_sum, add_comm (Cardinal.lift #α), lift_add,
        add_assoc, lift_lift, lift_lift, mk_fin, lift_natCast]
      exact add_le_add_right (nat_lt_aleph0 _).le _
    · rw [← one_le_iff_ne_zero]
      refine' _root_.trans _ (le_ciSup (bddAbove_range _) 1)
      rw [one_le_iff_ne_zero, mk_ne_zero_iff]
      exact ⟨var (Sum.inr 0)⟩
  · rw [max_le_iff, ← infinite_iff]
    refine' ⟨Infinite.of_injective (fun i => ⟨i + 1, var (Sum.inr i)⟩) fun i j ij => _, _⟩
    · cases ij
      rfl
    · rw [Cardinal.le_def]
      refine' ⟨⟨Sum.elim (fun i => ⟨0, var (Sum.inl i)⟩)
        fun F => ⟨1, func F.2 fun _ => var (Sum.inr 0)⟩, _⟩⟩
      · rintro (a | a) (b | b) h
        · simp only [Sum.elim_inl, Sigma.mk.inj_iff, heq_eq_eq, var.injEq, Sum.inl.injEq, true_and]
            at h
          rw [h]
        · simp only [Sum.elim_inl, Sum.elim_inr, Sigma.mk.inj_iff, false_and] at h
        · simp only [Sum.elim_inr, Sum.elim_inl, Sigma.mk.inj_iff, false_and] at h
        · 

Proof state:
case refine'_2.refine'_2.inr.inr
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
a b : (i : ℕ) × Functions L i
h :
  Sum.elim (fun i => { fst := 0, snd := var (Sum.inl i) })
      (fun F => { fst := 1, snd := func F.snd fun x => var (Sum.inr 0) }) (Sum.inr a) =
    Sum.elim (fun i => { fst := 0, snd := var (Sum.inl i) })
      (fun F => { fst := 1, snd := func F.snd fun x => var (Sum.inr 0) }) (Sum.inr b)
⊢ Sum.inr a = Sum.inr b

Next tactic:
simp only [Sum.elim_inr, Sigma.mk.inj_iff, heq_eq_eq, func.injEq, true_and] at h
theorem card_sigma : #(Σn, L.Term (Sum α (Fin n))) = max ℵ₀ #(Sum α (Σi, L.Functions i)) := by
  refine' le_antisymm _ _
  · rw [mk_sigma]
    refine' (sum_le_iSup_lift _).trans _
    rw [mk_nat, lift_aleph0, mul_eq_max_of_aleph0_le_left le_rfl, max_le_iff,
      ciSup_le_iff' (bddAbove_range _)]
    · refine' ⟨le_max_left _ _, fun i => card_le.trans _⟩
      refine' max_le (le_max_left _ _) _
      rw [← add_eq_max le_rfl, mk_sum, mk_sum, mk_sum, add_comm (Cardinal.lift #α), lift_add,
        add_assoc, lift_lift, lift_lift, mk_fin, lift_natCast]
      exact add_le_add_right (nat_lt_aleph0 _).le _
    · rw [← one_le_iff_ne_zero]
      refine' _root_.trans _ (le_ciSup (bddAbove_range _) 1)
      rw [one_le_iff_ne_zero, mk_ne_zero_iff]
      exact ⟨var (Sum.inr 0)⟩
  · rw [max_le_iff, ← infinite_iff]
    refine' ⟨Infinite.of_injective (fun i => ⟨i + 1, var (Sum.inr i)⟩) fun i j ij => _, _⟩
    · cases ij
      rfl
    · rw [Cardinal.le_def]
      refine' ⟨⟨Sum.elim (fun i => ⟨0, var (Sum.inl i)⟩)
        fun F => ⟨1, func F.2 fun _ => var (Sum.inr 0)⟩, _⟩⟩
      · rintro (a | a) (b | b) h
        · simp only [Sum.elim_inl, Sigma.mk.inj_iff, heq_eq_eq, var.injEq, Sum.inl.injEq, true_and]
            at h
          rw [h]
        · simp only [Sum.elim_inl, Sum.elim_inr, Sigma.mk.inj_iff, false_and] at h
        · simp only [Sum.elim_inr, Sum.elim_inl, Sigma.mk.inj_iff, false_and] at h
        · simp only [Sum.elim_inr, Sigma.mk.inj_iff, heq_eq_eq, func.injEq, true_and] at h
          

Proof state:
case refine'_2.refine'_2.inr.inr
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
a b : (i : ℕ) × Functions L i
h : a.fst = b.fst ∧ HEq a.snd b.snd ∧ HEq (fun x => var (Sum.inr 0)) fun x => var (Sum.inr 0)
⊢ Sum.inr a = Sum.inr b

Next tactic:
rw [Sigma.ext_iff.2 ⟨h.1, h.2.1⟩]
instance [Encodable α] [Encodable (Σi, L.Functions i)] : Encodable (L.Term α) :=
  Encodable.ofLeftInjection listEncode (fun l => (listDecode l).head?.join) fun t => by
    

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝⁴ : Structure L M
inst✝³ : Structure L N
inst✝² : Structure L P
α : Type u'
β : Type v'
inst✝¹ : Encodable α
inst✝ : Encodable ((i : ℕ) × Functions L i)
t : Term L α
⊢ (fun l => Option.join (head? (listDecode l))) (listEncode t) = some t

Next tactic:
simp only
instance [Encodable α] [Encodable (Σi, L.Functions i)] : Encodable (L.Term α) :=
  Encodable.ofLeftInjection listEncode (fun l => (listDecode l).head?.join) fun t => by
    simp only
    

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝⁴ : Structure L M
inst✝³ : Structure L N
inst✝² : Structure L P
α : Type u'
β : Type v'
inst✝¹ : Encodable α
inst✝ : Encodable ((i : ℕ) × Functions L i)
t : Term L α
⊢ Option.join (head? (listDecode (listEncode t))) = some t

Next tactic:
rw [← bind_singleton listEncode, listDecode_encode_list]
instance [Encodable α] [Encodable (Σi, L.Functions i)] : Encodable (L.Term α) :=
  Encodable.ofLeftInjection listEncode (fun l => (listDecode l).head?.join) fun t => by
    simp only
    rw [← bind_singleton listEncode, listDecode_encode_list]
    

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝⁴ : Structure L M
inst✝³ : Structure L N
inst✝² : Structure L P
α : Type u'
β : Type v'
inst✝¹ : Encodable α
inst✝ : Encodable ((i : ℕ) × Functions L i)
t : Term L α
⊢ Option.join (head? (List.map some [t])) = some t

Next tactic:
simp only [Option.join, head?, List.map, Option.some_bind, id.def]
instance [h1 : Countable α] [h2 : Countable (Σl, L.Functions l)] : Countable (L.Term α) := by
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
h1 : Countable α
h2 : Countable ((l : ℕ) × Functions L l)
⊢ Countable (Term L α)

Next tactic:
refine' mk_le_aleph0_iff.1 (card_le.trans (max_le_iff.2 _))
instance [h1 : Countable α] [h2 : Countable (Σl, L.Functions l)] : Countable (L.Term α) := by
  refine' mk_le_aleph0_iff.1 (card_le.trans (max_le_iff.2 _))
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
h1 : Countable α
h2 : Countable ((l : ℕ) × Functions L l)
⊢ ℵ₀ ≤ ℵ₀ ∧ #(α ⊕ (i : ℕ) × Functions L i) ≤ ℵ₀

Next tactic:
simp only [le_refl, mk_sum, add_le_aleph0, lift_le_aleph0, true_and_iff]
instance [h1 : Countable α] [h2 : Countable (Σl, L.Functions l)] : Countable (L.Term α) := by
  refine' mk_le_aleph0_iff.1 (card_le.trans (max_le_iff.2 _))
  simp only [le_refl, mk_sum, add_le_aleph0, lift_le_aleph0, true_and_iff]
  

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
h1 : Countable α
h2 : Countable ((l : ℕ) × Functions L l)
⊢ #α ≤ ℵ₀ ∧ #((i : ℕ) × Functions L i) ≤ ℵ₀

Next tactic:
exact ⟨Cardinal.mk_le_aleph0, Cardinal.mk_le_aleph0⟩
/-- Applies `imp` to two elements of `(Σ n, L.BoundedFormula α n)`,
or returns `default` if not possible. -/
def sigmaImp : (Σn, L.BoundedFormula α n) → (Σn, L.BoundedFormula α n) → Σn, L.BoundedFormula α n
  | ⟨m, φ⟩, ⟨n, ψ⟩ => if h : m = n then ⟨m, φ.imp (Eq.mp (by 

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
m : ℕ
φ : BoundedFormula L α m
n : ℕ
ψ : BoundedFormula L α n
h : m = n
⊢ BoundedFormula L α n = BoundedFormula L α m

Next tactic:
rw [h]
/-- Decodes a list of symbols as a list of formulas. -/
@[simp]
def listDecode : ∀ l : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)),
    (Σn, L.BoundedFormula α n) ×
    { l' : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)) //
      SizeOf.sizeOf l' ≤ max 1 (SizeOf.sizeOf l) }
  | Sum.inr (Sum.inr (n + 2))::l => ⟨⟨n, falsum⟩, l, le_max_of_le_right le_add_self⟩
  | Sum.inl ⟨n₁, t₁⟩::Sum.inl ⟨n₂, t₂⟩::l =>
    ⟨if h : n₁ = n₂ then ⟨n₁, equal t₁ (Eq.mp (by 

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
n₁ : ℕ
t₁ : Term L (α ⊕ Fin n₁)
n₂ : ℕ
t₂ : Term L (α ⊕ Fin n₂)
l : List ((k : ℕ) × Term L (α ⊕ Fin k) ⊕ (n : ℕ) × Relations L n ⊕ ℕ)
h : n₁ = n₂
⊢ Term L (α ⊕ Fin n₂) = Term L (α ⊕ Fin n₁)

Next tactic:
rw [h]
/-- Decodes a list of symbols as a list of formulas. -/
@[simp]
def listDecode : ∀ l : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)),
    (Σn, L.BoundedFormula α n) ×
    { l' : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)) //
      SizeOf.sizeOf l' ≤ max 1 (SizeOf.sizeOf l) }
  | Sum.inr (Sum.inr (n + 2))::l => ⟨⟨n, falsum⟩, l, le_max_of_le_right le_add_self⟩
  | Sum.inl ⟨n₁, t₁⟩::Sum.inl ⟨n₂, t₂⟩::l =>
    ⟨if h : n₁ = n₂ then ⟨n₁, equal t₁ (Eq.mp (by rw [h]) t₂)⟩ else default, l, by
      

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
n₁ : ℕ
t₁ : Term L (α ⊕ Fin n₁)
n₂ : ℕ
t₂ : Term L (α ⊕ Fin n₂)
l : List ((k : ℕ) × Term L (α ⊕ Fin k) ⊕ (n : ℕ) × Relations L n ⊕ ℕ)
⊢ sizeOf l ≤ max 1 (sizeOf (Sum.inl { fst := n₁, snd := t₁ } :: Sum.inl { fst := n₂, snd := t₂ } :: l))

Next tactic:
simp only [SizeOf.sizeOf, List._sizeOf_1, ← add_assoc]
/-- Decodes a list of symbols as a list of formulas. -/
@[simp]
def listDecode : ∀ l : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)),
    (Σn, L.BoundedFormula α n) ×
    { l' : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)) //
      SizeOf.sizeOf l' ≤ max 1 (SizeOf.sizeOf l) }
  | Sum.inr (Sum.inr (n + 2))::l => ⟨⟨n, falsum⟩, l, le_max_of_le_right le_add_self⟩
  | Sum.inl ⟨n₁, t₁⟩::Sum.inl ⟨n₂, t₂⟩::l =>
    ⟨if h : n₁ = n₂ then ⟨n₁, equal t₁ (Eq.mp (by rw [h]) t₂)⟩ else default, l, by
      simp only [SizeOf.sizeOf, List._sizeOf_1, ← add_assoc]
      

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
n₁ : ℕ
t₁ : Term L (α ⊕ Fin n₁)
n₂ : ℕ
t₂ : Term L (α ⊕ Fin n₂)
l : List ((k : ℕ) × Term L (α ⊕ Fin k) ⊕ (n : ℕ) × Relations L n ⊕ ℕ)
⊢ List.rec 1 (fun head tail tail_ih => 1 + Sum._sizeOf_1 head + tail_ih) l ≤
    max 1
      (1 + Sum._sizeOf_1 (Sum.inl { fst := n₁, snd := t₁ }) + 1 + Sum._sizeOf_1 (Sum.inl { fst := n₂, snd := t₂ }) +
        List.rec 1 (fun head tail tail_ih => 1 + Sum._sizeOf_1 head + tail_ih) l)

Next tactic:
exact le_max_of_le_right le_add_self
/-- Decodes a list of symbols as a list of formulas. -/
@[simp]
def listDecode : ∀ l : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)),
    (Σn, L.BoundedFormula α n) ×
    { l' : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)) //
      SizeOf.sizeOf l' ≤ max 1 (SizeOf.sizeOf l) }
  | Sum.inr (Sum.inr (n + 2))::l => ⟨⟨n, falsum⟩, l, le_max_of_le_right le_add_self⟩
  | Sum.inl ⟨n₁, t₁⟩::Sum.inl ⟨n₂, t₂⟩::l =>
    ⟨if h : n₁ = n₂ then ⟨n₁, equal t₁ (Eq.mp (by rw [h]) t₂)⟩ else default, l, by
      simp only [SizeOf.sizeOf, List._sizeOf_1, ← add_assoc]
      exact le_max_of_le_right le_add_self⟩
  | Sum.inr (Sum.inl ⟨n, R⟩)::Sum.inr (Sum.inr k)::l =>
    ⟨if h : ∀ i : Fin n, ((l.map Sum.getLeft?).get? i).join.isSome then
        if h' : ∀ i, (Option.get _ (h i)).1 = k then
          ⟨k, BoundedFormula.rel R fun i => Eq.mp (by 

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
n : ℕ
R : Relations L n
k : ℕ
l : List ((k : ℕ) × Term L (α ⊕ Fin k) ⊕ (n : ℕ) × Relations L n ⊕ ℕ)
h : ∀ (i : Fin n), Option.isSome (Option.join (get? (List.map Sum.getLeft? l) ↑i)) = true
h' :
  ∀ (i : Fin n),
    (Option.get (Option.join (get? (List.map Sum.getLeft? l) ↑i))
          (_ : Option.isSome (Option.join (get? (List.map Sum.getLeft? l) ↑i)) = true)).fst =
      k
i : Fin n
⊢ Term L
      (α ⊕
        Fin
          (Option.get (Option.join (get? (List.map Sum.getLeft? l) ↑i))
              (_ : Option.isSome (Option.join (get? (List.map Sum.getLeft? l) ↑i)) = true)).fst) =
    Term L (α ⊕ Fin k)

Next tactic:
rw [h' i]
/-- Decodes a list of symbols as a list of formulas. -/
@[simp]
def listDecode : ∀ l : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)),
    (Σn, L.BoundedFormula α n) ×
    { l' : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)) //
      SizeOf.sizeOf l' ≤ max 1 (SizeOf.sizeOf l) }
  | Sum.inr (Sum.inr (n + 2))::l => ⟨⟨n, falsum⟩, l, le_max_of_le_right le_add_self⟩
  | Sum.inl ⟨n₁, t₁⟩::Sum.inl ⟨n₂, t₂⟩::l =>
    ⟨if h : n₁ = n₂ then ⟨n₁, equal t₁ (Eq.mp (by rw [h]) t₂)⟩ else default, l, by
      simp only [SizeOf.sizeOf, List._sizeOf_1, ← add_assoc]
      exact le_max_of_le_right le_add_self⟩
  | Sum.inr (Sum.inl ⟨n, R⟩)::Sum.inr (Sum.inr k)::l =>
    ⟨if h : ∀ i : Fin n, ((l.map Sum.getLeft?).get? i).join.isSome then
        if h' : ∀ i, (Option.get _ (h i)).1 = k then
          ⟨k, BoundedFormula.rel R fun i => Eq.mp (by rw [h' i]) (Option.get _ (h i)).2⟩
        else default
      else default,
      l.drop n, le_max_of_le_right (le_add_left (le_add_left (List.drop_sizeOf_le _ _)))⟩
  | Sum.inr (Sum.inr 0)::l =>
    have : SizeOf.sizeOf
        (↑(listDecode l).2 : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ))) <
        1 + (1 + 1) + SizeOf.sizeOf l := by
      

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
l : List ((k : ℕ) × Term L (α ⊕ Fin k) ⊕ (n : ℕ) × Relations L n ⊕ ℕ)
⊢ sizeOf ↑(listDecode l).2 < 1 + (1 + 1) + sizeOf l

Next tactic:
refine' lt_of_le_of_lt (listDecode l).2.2 (max_lt _ (Nat.lt_add_of_pos_left (by decide)))
/-- Decodes a list of symbols as a list of formulas. -/
@[simp]
def listDecode : ∀ l : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)),
    (Σn, L.BoundedFormula α n) ×
    { l' : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)) //
      SizeOf.sizeOf l' ≤ max 1 (SizeOf.sizeOf l) }
  | Sum.inr (Sum.inr (n + 2))::l => ⟨⟨n, falsum⟩, l, le_max_of_le_right le_add_self⟩
  | Sum.inl ⟨n₁, t₁⟩::Sum.inl ⟨n₂, t₂⟩::l =>
    ⟨if h : n₁ = n₂ then ⟨n₁, equal t₁ (Eq.mp (by rw [h]) t₂)⟩ else default, l, by
      simp only [SizeOf.sizeOf, List._sizeOf_1, ← add_assoc]
      exact le_max_of_le_right le_add_self⟩
  | Sum.inr (Sum.inl ⟨n, R⟩)::Sum.inr (Sum.inr k)::l =>
    ⟨if h : ∀ i : Fin n, ((l.map Sum.getLeft?).get? i).join.isSome then
        if h' : ∀ i, (Option.get _ (h i)).1 = k then
          ⟨k, BoundedFormula.rel R fun i => Eq.mp (by rw [h' i]) (Option.get _ (h i)).2⟩
        else default
      else default,
      l.drop n, le_max_of_le_right (le_add_left (le_add_left (List.drop_sizeOf_le _ _)))⟩
  | Sum.inr (Sum.inr 0)::l =>
    have : SizeOf.sizeOf
        (↑(listDecode l).2 : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ))) <
        1 + (1 + 1) + SizeOf.sizeOf l := by
      refine' lt_of_le_of_lt (listDecode l).2.2 (max_lt _ (Nat.lt_add_of_pos_left (by 

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
l : List ((k : ℕ) × Term L (α ⊕ Fin k) ⊕ (n : ℕ) × Relations L n ⊕ ℕ)
⊢ 0 < 1 + (1 + 1)

Next tactic:
decide
/-- Decodes a list of symbols as a list of formulas. -/
@[simp]
def listDecode : ∀ l : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)),
    (Σn, L.BoundedFormula α n) ×
    { l' : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ)) //
      SizeOf.sizeOf l' ≤ max 1 (SizeOf.sizeOf l) }
  | Sum.inr (Sum.inr (n + 2))::l => ⟨⟨n, falsum⟩, l, le_max_of_le_right le_add_self⟩
  | Sum.inl ⟨n₁, t₁⟩::Sum.inl ⟨n₂, t₂⟩::l =>
    ⟨if h : n₁ = n₂ then ⟨n₁, equal t₁ (Eq.mp (by rw [h]) t₂)⟩ else default, l, by
      simp only [SizeOf.sizeOf, List._sizeOf_1, ← add_assoc]
      exact le_max_of_le_right le_add_self⟩
  | Sum.inr (Sum.inl ⟨n, R⟩)::Sum.inr (Sum.inr k)::l =>
    ⟨if h : ∀ i : Fin n, ((l.map Sum.getLeft?).get? i).join.isSome then
        if h' : ∀ i, (Option.get _ (h i)).1 = k then
          ⟨k, BoundedFormula.rel R fun i => Eq.mp (by rw [h' i]) (Option.get _ (h i)).2⟩
        else default
      else default,
      l.drop n, le_max_of_le_right (le_add_left (le_add_left (List.drop_sizeOf_le _ _)))⟩
  | Sum.inr (Sum.inr 0)::l =>
    have : SizeOf.sizeOf
        (↑(listDecode l).2 : List (Sum (Σk, L.Term (Sum α (Fin k))) (Sum (Σn, L.Relations n) ℕ))) <
        1 + (1 + 1) + SizeOf.sizeOf l := by
      refine' lt_of_le_of_lt (listDecode l).2.2 (max_lt _ (Nat.lt_add_of_pos_left (by decide)))
      

Proof state:
L : Language
M : Type w
N : Type u_1
P : Type u_2
inst✝² : Structure L M
inst✝¹ : Structure L N
inst✝ : Structure L P
α : Type u'
β : Type v'
l : List ((k : ℕ) × Term L (α ⊕ Fin k) ⊕ (n : ℕ) × Relations L n ⊕ ℕ)
⊢ 1 < 1 + (1 + 1) + sizeOf l

Next tactic:
rw [add_assoc, lt_add_iff_pos_right, add_pos_iff]