l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem LiftRelAux.ret_left (R : α → β → Prop) (C : Computation α → Computation β → Prop) (a cb) :
    LiftRelAux R C (Sum.inl a) (destruct cb) ↔ ∃ b, b ∈ cb ∧ R a b := by
  apply cb.recOn (fun b => _) fun cb => _
  · intro b
    exact
      ⟨fun h => ⟨_, ret_mem _, h⟩, fun ⟨b', mb, h⟩ => by rw [mem_unique (ret_mem _) mb]; exact h⟩
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
a : α
cb : Computation β
⊢ ∀ (cb : Computation β), LiftRelAux R C (Sum.inl a) (destruct (think cb)) ↔ ∃ b, b ∈ think cb ∧ R a b

Next tactic:
intro
@[simp]
theorem LiftRelAux.ret_left (R : α → β → Prop) (C : Computation α → Computation β → Prop) (a cb) :
    LiftRelAux R C (Sum.inl a) (destruct cb) ↔ ∃ b, b ∈ cb ∧ R a b := by
  apply cb.recOn (fun b => _) fun cb => _
  · intro b
    exact
      ⟨fun h => ⟨_, ret_mem _, h⟩, fun ⟨b', mb, h⟩ => by rw [mem_unique (ret_mem _) mb]; exact h⟩
  · intro
    

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
a : α
cb cb✝ : Computation β
⊢ LiftRelAux R C (Sum.inl a) (destruct (think cb✝)) ↔ ∃ b, b ∈ think cb✝ ∧ R a b

Next tactic:
rw [destruct_think]
@[simp]
theorem LiftRelAux.ret_left (R : α → β → Prop) (C : Computation α → Computation β → Prop) (a cb) :
    LiftRelAux R C (Sum.inl a) (destruct cb) ↔ ∃ b, b ∈ cb ∧ R a b := by
  apply cb.recOn (fun b => _) fun cb => _
  · intro b
    exact
      ⟨fun h => ⟨_, ret_mem _, h⟩, fun ⟨b', mb, h⟩ => by rw [mem_unique (ret_mem _) mb]; exact h⟩
  · intro
    rw [destruct_think]
    

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
a : α
cb cb✝ : Computation β
⊢ LiftRelAux R C (Sum.inl a) (Sum.inr cb✝) ↔ ∃ b, b ∈ think cb✝ ∧ R a b

Next tactic:
exact ⟨fun ⟨b, h, r⟩ => ⟨b, think_mem h, r⟩, fun ⟨b, h, r⟩ => ⟨b, of_think_mem h, r⟩⟩
theorem LiftRelAux.swap (R : α → β → Prop) (C) (a b) :
    LiftRelAux (swap R) (swap C) b a = LiftRelAux R C a b := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
a : α ⊕ Computation α
b : β ⊕ Computation β
⊢ LiftRelAux (Function.swap R) (Function.swap C) b a = LiftRelAux R C a b

Next tactic:
cases' a with a ca
theorem LiftRelAux.swap (R : α → β → Prop) (C) (a b) :
    LiftRelAux (swap R) (swap C) b a = LiftRelAux R C a b := by
  cases' a with a ca <;> 

Proof state:
case inl
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
b : β ⊕ Computation β
a : α
⊢ LiftRelAux (Function.swap R) (Function.swap C) b (Sum.inl a) = LiftRelAux R C (Sum.inl a) b

Next tactic:
cases' b with b cb
theorem LiftRelAux.swap (R : α → β → Prop) (C) (a b) :
    LiftRelAux (swap R) (swap C) b a = LiftRelAux R C a b := by
  cases' a with a ca <;> 

Proof state:
case inr
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
b : β ⊕ Computation β
ca : Computation α
⊢ LiftRelAux (Function.swap R) (Function.swap C) b (Sum.inr ca) = LiftRelAux R C (Sum.inr ca) b

Next tactic:
cases' b with b cb
theorem LiftRelAux.swap (R : α → β → Prop) (C) (a b) :
    LiftRelAux (swap R) (swap C) b a = LiftRelAux R C a b := by
  cases' a with a ca <;> cases' b with b cb <;> 

Proof state:
case inl.inl
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
a : α
b : β
⊢ LiftRelAux (Function.swap R) (Function.swap C) (Sum.inl b) (Sum.inl a) = LiftRelAux R C (Sum.inl a) (Sum.inl b)

Next tactic:
simp only [LiftRelAux]
theorem LiftRelAux.swap (R : α → β → Prop) (C) (a b) :
    LiftRelAux (swap R) (swap C) b a = LiftRelAux R C a b := by
  cases' a with a ca <;> cases' b with b cb <;> 

Proof state:
case inl.inr
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
a : α
cb : Computation β
⊢ LiftRelAux (Function.swap R) (Function.swap C) (Sum.inr cb) (Sum.inl a) = LiftRelAux R C (Sum.inl a) (Sum.inr cb)

Next tactic:
simp only [LiftRelAux]
theorem LiftRelAux.swap (R : α → β → Prop) (C) (a b) :
    LiftRelAux (swap R) (swap C) b a = LiftRelAux R C a b := by
  cases' a with a ca <;> cases' b with b cb <;> 

Proof state:
case inr.inl
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
ca : Computation α
b : β
⊢ LiftRelAux (Function.swap R) (Function.swap C) (Sum.inl b) (Sum.inr ca) = LiftRelAux R C (Sum.inr ca) (Sum.inl b)

Next tactic:
simp only [LiftRelAux]
theorem LiftRelAux.swap (R : α → β → Prop) (C) (a b) :
    LiftRelAux (swap R) (swap C) b a = LiftRelAux R C a b := by
  cases' a with a ca <;> cases' b with b cb <;> 

Proof state:
case inr.inr
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
ca : Computation α
cb : Computation β
⊢ LiftRelAux (Function.swap R) (Function.swap C) (Sum.inr cb) (Sum.inr ca) = LiftRelAux R C (Sum.inr ca) (Sum.inr cb)

Next tactic:
simp only [LiftRelAux]
@[simp]
theorem LiftRelAux.ret_right (R : α → β → Prop) (C : Computation α → Computation β → Prop) (b ca) :
    LiftRelAux R C (destruct ca) (Sum.inl b) ↔ ∃ a, a ∈ ca ∧ R a b := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
b : β
ca : Computation α
⊢ LiftRelAux R C (destruct ca) (Sum.inl b) ↔ ∃ a, a ∈ ca ∧ R a b

Next tactic:
rw [← LiftRelAux.swap, LiftRelAux.ret_left]
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
cb : Computation β
Hc : C ca cb
a : α
ha : a ∈ ca
⊢ LiftRel R ca cb

Next tactic:
revert cb
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
⊢ ∀ (cb : Computation β), C ca cb → LiftRel R ca cb

Next tactic:
refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _)
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> 

Proof state:
case refine'_1
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
⊢ (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) (pure a)

Next tactic:
intro cb Hc
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> 

Proof state:
case refine'_2
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
⊢ (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) (think ca')

Next tactic:
intro cb Hc
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> 

Proof state:
case refine'_1
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
cb : Computation β
Hc : C (pure a) cb
⊢ LiftRel R (pure a) cb

Next tactic:
have h := H Hc
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> 

Proof state:
case refine'_2
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
⊢ LiftRel R (think ca') cb

Next tactic:
have h := H Hc
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · 

Proof state:
case refine'_1
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
cb : Computation β
Hc : C (pure a) cb
h : LiftRelAux R C (destruct (pure a)) (destruct cb)
⊢ LiftRel R (pure a) cb

Next tactic:
simp only [destruct_pure, LiftRelAux.ret_left] at h
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    

Proof state:
case refine'_1
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
cb : Computation β
Hc : C (pure a) cb
h : ∃ b, b ∈ cb ∧ R a b
⊢ LiftRel R (pure a) cb

Next tactic:
simp [h]
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    simp [h]
  · 

Proof state:
case refine'_2
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
h : LiftRelAux R C (destruct (think ca')) (destruct cb)
⊢ LiftRel R (think ca') cb

Next tactic:
simp only [liftRel_think_left]
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    simp [h]
  · simp only [liftRel_think_left]
    

Proof state:
case refine'_2
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
h : LiftRelAux R C (destruct (think ca')) (destruct cb)
⊢ LiftRel R ca' cb

Next tactic:
revert h
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    simp [h]
  · simp only [liftRel_think_left]
    revert h
    

Proof state:
case refine'_2
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
⊢ LiftRelAux R C (destruct (think ca')) (destruct cb) → LiftRel R ca' cb

Next tactic:
apply cb.recOn (fun b => _) fun cb' => _
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    simp [h]
  · simp only [liftRel_think_left]
    revert h
    apply cb.recOn (fun b => _) fun cb' => _ <;> 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
⊢ ∀ (b : β), LiftRelAux R C (destruct (think ca')) (destruct (pure b)) → LiftRel R ca' (pure b)

Next tactic:
intros _ h
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    simp [h]
  · simp only [liftRel_think_left]
    revert h
    apply cb.recOn (fun b => _) fun cb' => _ <;> 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
⊢ ∀ (cb' : Computation β), LiftRelAux R C (destruct (think ca')) (destruct (think cb')) → LiftRel R ca' (think cb')

Next tactic:
intros _ h
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    simp [h]
  · simp only [liftRel_think_left]
    revert h
    apply cb.recOn (fun b => _) fun cb' => _ <;> intros _ h <;> 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
b✝ : β
h : LiftRelAux R C (destruct (think ca')) (destruct (pure b✝))
⊢ LiftRel R ca' (pure b✝)

Next tactic:
simp at h
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    simp [h]
  · simp only [liftRel_think_left]
    revert h
    apply cb.recOn (fun b => _) fun cb' => _ <;> intros _ h <;> 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
cb'✝ : Computation β
h : LiftRelAux R C (destruct (think ca')) (destruct (think cb'✝))
⊢ LiftRel R ca' (think cb'✝)

Next tactic:
simp at h
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    simp [h]
  · simp only [liftRel_think_left]
    revert h
    apply cb.recOn (fun b => _) fun cb' => _ <;> intros _ h <;> simp at h <;> 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
b✝ : β
h : ∃ a, a ∈ ca' ∧ R a b✝
⊢ LiftRel R ca' (pure b✝)

Next tactic:
simp [h]
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    simp [h]
  · simp only [liftRel_think_left]
    revert h
    apply cb.recOn (fun b => _) fun cb' => _ <;> intros _ h <;> simp at h <;> 

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
cb'✝ : Computation β
h : C ca' cb'✝
⊢ LiftRel R ca' (think cb'✝)

Next tactic:
simp [h]
theorem LiftRelRec.lem {R : α → β → Prop} (C : Computation α → Computation β → Prop)
    (H : ∀ {ca cb}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)) (ca cb) (Hc : C ca cb) (a)
    (ha : a ∈ ca) : LiftRel R ca cb := by
  revert cb
  refine' memRecOn (C := (λ ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb))
    ha _ (fun ca' IH => _) <;> intro cb Hc <;> have h := H Hc
  · simp only [destruct_pure, LiftRelAux.ret_left] at h
    simp [h]
  · simp only [liftRel_think_left]
    revert h
    apply cb.recOn (fun b => _) fun cb' => _ <;> intros _ h <;> simp at h <;> simp [h]
    

Proof state:
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : Computation α → Computation β → Prop
H : ∀ {ca : Computation α} {cb : Computation β}, C ca cb → LiftRelAux R C (destruct ca) (destruct cb)
ca : Computation α
a : α
ha : a ∈ ca
ca' : Computation α
IH : (fun ca => ∀ (cb : Computation β), C ca cb → LiftRel R ca cb) ca'
cb : Computation β
Hc : C (think ca') cb
cb'✝ : Computation β
h : C ca' cb'✝
⊢ LiftRel R ca' cb'✝

Next tactic:
exact IH _ h
theorem ker_pi (f : (i : ι) → M₂ →ₗ[R] φ i) : ker (pi f) = ⨅ i : ι, ker (f i) := by
  

Proof state:
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
ι' : Type x'
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : Module R M₂
inst✝³ : AddCommMonoid M₃
inst✝² : Module R M₃
φ : ι → Type i
inst✝¹ : (i : ι) → AddCommMonoid (φ i)
inst✝ : (i : ι) → Module R (φ i)
f : (i : ι) → M₂ →ₗ[R] φ i
⊢ ker (pi f) = ⨅ i, ker (f i)

Next tactic:
ext c
theorem ker_pi (f : (i : ι) → M₂ →ₗ[R] φ i) : ker (pi f) = ⨅ i : ι, ker (f i) := by
  ext c; 

Proof state:
case h
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
ι' : Type x'
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : Module R M₂
inst✝³ : AddCommMonoid M₃
inst✝² : Module R M₃
φ : ι → Type i
inst✝¹ : (i : ι) → AddCommMonoid (φ i)
inst✝ : (i : ι) → Module R (φ i)
f : (i : ι) → M₂ →ₗ[R] φ i
c : M₂
⊢ c ∈ ker (pi f) ↔ c ∈ ⨅ i, ker (f i)

Next tactic:
simp [funext_iff]
theorem pi_eq_zero (f : (i : ι) → M₂ →ₗ[R] φ i) : pi f = 0 ↔ ∀ i, f i = 0 := by
  

Proof state:
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
ι' : Type x'
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : Module R M₂
inst✝³ : AddCommMonoid M₃
inst✝² : Module R M₃
φ : ι → Type i
inst✝¹ : (i : ι) → AddCommMonoid (φ i)
inst✝ : (i : ι) → Module R (φ i)
f : (i : ι) → M₂ →ₗ[R] φ i
⊢ pi f = 0 ↔ ∀ (i : ι), f i = 0

Next tactic:
simp only [LinearMap.ext_iff, pi_apply, funext_iff]
theorem pi_eq_zero (f : (i : ι) → M₂ →ₗ[R] φ i) : pi f = 0 ↔ ∀ i, f i = 0 := by
  simp only [LinearMap.ext_iff, pi_apply, funext_iff];
    

Proof state:
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
ι' : Type x'
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : Module R M₂
inst✝³ : AddCommMonoid M₃
inst✝² : Module R M₃
φ : ι → Type i
inst✝¹ : (i : ι) → AddCommMonoid (φ i)
inst✝ : (i : ι) → Module R (φ i)
f : (i : ι) → M₂ →ₗ[R] φ i
⊢ (∀ (x : M₂) (a : ι), (f a) x = 0 x a) ↔ ∀ (i : ι) (x : M₂), (f i) x = 0 x

Next tactic:
exact ⟨fun h a b => h b a, fun h a b => h b a⟩
theorem pi_zero : pi (fun i => 0 : (i : ι) → M₂ →ₗ[R] φ i) = 0 := by 

Proof state:
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
ι' : Type x'
inst✝⁶ : Semiring R
inst✝⁵ : AddCommMonoid M₂
inst✝⁴ : Module R M₂
inst✝³ : AddCommMonoid M₃
inst✝² : Module R M₃
φ : ι → Type i
inst✝¹ : (i : ι) → AddCommMonoid (φ i)
inst✝ : (i : ι) → Module R (φ i)
⊢ (pi fun i => 0) = 0

Next tactic:
ext