Theorem: CategoryTheory.Abelian.Pseudoelement.pseudo_exact_of_exact
File: Mathlib/CategoryTheory/Abelian/Pseudoelements.lean

tactic: rw [← comp_apply, h.w]
state_before: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
a : Pseudoelement P
⊢ pseudoApply g (pseudoApply f a) = 0
state_after: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
a : Pseudoelement P
⊢ pseudoApply 0 a = 0

tactic: exact zero_apply _ _
state_before: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
a : Pseudoelement P
⊢ pseudoApply 0 a = 0
state_after: no goals

tactic: have hb' : b.hom ≫ g = 0 := (pseudoZero_iff _).1 hb
state_before: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
⊢ ∃ a, pseudoApply f a = ⟦b⟧
state_after: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
⊢ ∃ a, pseudoApply f a = ⟦b⟧

tactic: obtain ⟨c, hc⟩ := KernelFork.IsLimit.lift' (isLimitImage f g h) _ hb'
state_before: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
⊢ ∃ a, pseudoApply f a = ⟦b⟧
state_after: case mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ ∃ a, pseudoApply f a = ⟦b⟧

tactic: use (pullback.fst : pullback (Abelian.factorThruImage f) c ⟶ P)
state_before: case mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ ∃ a, pseudoApply f a = ⟦b⟧
state_after: case h
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ pseudoApply f (Quot.mk (PseudoEqual P) (Over.mk pullback.fst)) = ⟦b⟧

tactic: apply Quotient.sound
state_before: case h
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ pseudoApply f (Quot.mk (PseudoEqual P) (Over.mk pullback.fst)) = ⟦b⟧
state_after: case h.a
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ (fun g => app f g) (Over.mk pullback.fst) ≈ b

tactic: refine ⟨pullback (Abelian.factorThruImage f) c, 𝟙 _,
        pullback.snd, inferInstance, inferInstance, ?_⟩
state_before: case h.a
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ (fun g => app f g) (Over.mk pullback.fst) ≈ b
state_after: case h.a
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ 𝟙 (pullback (Abelian.factorThruImage f) c) ≫ ((fun g => app f g) (Over.mk pullback.fst)).hom = pullback.snd ≫ b.hom

tactic: calc
  𝟙 (pullback (Abelian.factorThruImage f) c) ≫ pullback.fst ≫ f = pullback.fst ≫ f :=
    Category.id_comp _
  _ = pullback.fst ≫ Abelian.factorThruImage f ≫ kernel.ι (cokernel.π f) := by
    rw [Abelian.image.fac]
  _ = (pullback.snd ≫ c) ≫ kernel.ι (cokernel.π f) := by
    rw [← Category.assoc, pullback.condition]
  _ = pullback.snd ≫ b.hom := by
    rw [Category.assoc]
    congr
state_before: case h.a
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ 𝟙 (pullback (Abelian.factorThruImage f) c) ≫ ((fun g => app f g) (Over.mk pullback.fst)).hom = pullback.snd ≫ b.hom
state_after: no goals

tactic: rw [Abelian.image.fac]
state_before: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ pullback.fst ≫ f = pullback.fst ≫ Abelian.factorThruImage f ≫ kernel.ι (cokernel.π f)
state_after: no goals

tactic: rw [← Category.assoc, pullback.condition]
state_before: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ pullback.fst ≫ Abelian.factorThruImage f ≫ kernel.ι (cokernel.π f) = (pullback.snd ≫ c) ≫ kernel.ι (cokernel.π f)
state_after: no goals

tactic: rw [Category.assoc]
state_before: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ (pullback.snd ≫ c) ≫ kernel.ι (cokernel.π f) = pullback.snd ≫ b.hom
state_after: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ pullback.snd ≫ c ≫ kernel.ι (cokernel.π f) = pullback.snd ≫ b.hom

tactic: congr
state_before: C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : Abelian C
P Q R : C
f : P ⟶ Q
g : Q ⟶ R
h : Exact f g
b' : Pseudoelement Q
b : Over Q
hb : pseudoApply g ⟦b⟧ = 0
hb' : b.hom ≫ g = 0
c : (𝟭 C).obj b.left ⟶ (KernelFork.ofι (image.ι f) ⋯).pt
hc : c ≫ Fork.ι (KernelFork.ofι (image.ι f) ⋯) = b.hom
⊢ pullback.snd ≫ c ≫ kernel.ι (cokernel.π f) = pullback.snd ≫ b.hom
state_after: no goals