l3lab/ntp-mathlib huggingface dataset:
open scoped Classical in
/-- The basis on `ι →₀ M` with basis vectors `λ ⟨i, x⟩, single i (b i x)`. -/
protected def basis {φ : ι → Type*} (b : ∀ i, Basis (φ i) R M) : Basis (Σi, φ i) R (ι →₀ M) :=
  Basis.ofRepr
    { toFun := fun g =>
        { toFun := fun ix => (b ix.1).repr (g ix.1) ix.2
          support := g.support.sigma fun i => ((b i).repr (g i)).support
          mem_support_toFun := fun ix => by
            simp only [Finset.mem_sigma, mem_support_iff, and_iff_right_iff_imp, Ne.def]
            intro b hg
            simp [hg] at b }
      invFun := fun g =>
        { toFun := fun i =>
            (b i).repr.symm (g.comapDomain _ (Set.injOn_of_injective sigma_mk_injective _))
          support := g.support.image Sigma.fst
          mem_support_toFun := fun i => by
            rw [Ne.def, ← (b i).repr.injective.eq_iff, (b i).repr.apply_symm_apply, FunLike.ext_iff]
            

Proof state:
R : Type u_1
M : Type u_2
ι : Type u_3
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
φ : ι → Type u_4
b : (i : ι) → Basis (φ i) R M
g : (i : ι) × φ i →₀ R
i : ι
⊢ i ∈ Finset.image Sigma.fst g.support ↔
    ¬∀ (x : φ i), (comapDomain (Sigma.mk i) g (_ : InjOn (Sigma.mk i) (Sigma.mk i ⁻¹' ↑g.support))) x = ((b i).repr 0) x

Next tactic:
simp only [exists_prop, LinearEquiv.map_zero, comapDomain_apply, zero_apply,
              exists_and_right, mem_support_iff, exists_eq_right, Sigma.exists, Finset.mem_image,
              not_forall]
@[simp]
theorem coe_basis {φ : ι → Type*} (b : ∀ i, Basis (φ i) R M) :
    ⇑(Finsupp.basis b) = fun ix : Σi, φ i => single ix.1 (b ix.1 ix.2) :=
  funext fun ⟨i, x⟩ =>
    Basis.apply_eq_iff.mpr <| by
      

Proof state:
R : Type u_1
M : Type u_2
ι : Type u_3
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
φ : ι → Type u_4
b : (i : ι) → Basis (φ i) R M
x✝ : (i : ι) × φ i
i : ι
x : φ i
⊢ ((Finsupp.basis b).repr
      fun₀ | { fst := i, snd := x }.fst => (b { fst := i, snd := x }.fst) { fst := i, snd := x }.snd) =
    fun₀ | { fst := i, snd := x } => 1

Next tactic:
classical
      ext ⟨j, y⟩
      by_cases h : i = j
      · cases h
        simp only [basis_repr, single_eq_same, Basis.repr_self,
          Finsupp.single_apply_left sigma_mk_injective]
      · have : Sigma.mk i x ≠ Sigma.mk j y := fun h' => h <| congrArg (fun s => s.fst) h'
        -- Porting note: previously `this` not needed
        simp only [basis_repr, single_apply, h, this, false_and_iff, if_false, LinearEquiv.map_zero,
        zero_apply]
@[simp]
theorem coe_basis {φ : ι → Type*} (b : ∀ i, Basis (φ i) R M) :
    ⇑(Finsupp.basis b) = fun ix : Σi, φ i => single ix.1 (b ix.1 ix.2) :=
  funext fun ⟨i, x⟩ =>
    Basis.apply_eq_iff.mpr <| by
      classical
      

Proof state:
R : Type u_1
M : Type u_2
ι : Type u_3
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
φ : ι → Type u_4
b : (i : ι) → Basis (φ i) R M
x✝ : (i : ι) × φ i
i : ι
x : φ i
⊢ ((Finsupp.basis b).repr
      fun₀ | { fst := i, snd := x }.fst => (b { fst := i, snd := x }.fst) { fst := i, snd := x }.snd) =
    fun₀ | { fst := i, snd := x } => 1

Next tactic:
ext ⟨j, y⟩
@[simp]
theorem coe_basis {φ : ι → Type*} (b : ∀ i, Basis (φ i) R M) :
    ⇑(Finsupp.basis b) = fun ix : Σi, φ i => single ix.1 (b ix.1 ix.2) :=
  funext fun ⟨i, x⟩ =>
    Basis.apply_eq_iff.mpr <| by
      classical
      ext ⟨j, y⟩
      

Proof state:
case h.mk
R : Type u_1
M : Type u_2
ι : Type u_3
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
φ : ι → Type u_4
b : (i : ι) → Basis (φ i) R M
x✝ : (i : ι) × φ i
i : ι
x : φ i
j : ι
y : φ j
⊢ ((Finsupp.basis b).repr
        fun₀ | { fst := i, snd := x }.fst => (b { fst := i, snd := x }.fst) { fst := i, snd := x }.snd)
      { fst := j, snd := y } =
    (fun₀ | { fst := i, snd := x } => 1) { fst := j, snd := y }

Next tactic:
by_cases h : i = j
@[simp]
theorem coe_basis {φ : ι → Type*} (b : ∀ i, Basis (φ i) R M) :
    ⇑(Finsupp.basis b) = fun ix : Σi, φ i => single ix.1 (b ix.1 ix.2) :=
  funext fun ⟨i, x⟩ =>
    Basis.apply_eq_iff.mpr <| by
      classical
      ext ⟨j, y⟩
      by_cases h : i = j
      · 

Proof state:
case pos
R : Type u_1
M : Type u_2
ι : Type u_3
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
φ : ι → Type u_4
b : (i : ι) → Basis (φ i) R M
x✝ : (i : ι) × φ i
i : ι
x : φ i
j : ι
y : φ j
h : i = j
⊢ ((Finsupp.basis b).repr
        fun₀ | { fst := i, snd := x }.fst => (b { fst := i, snd := x }.fst) { fst := i, snd := x }.snd)
      { fst := j, snd := y } =
    (fun₀ | { fst := i, snd := x } => 1) { fst := j, snd := y }

Next tactic:
cases h
@[simp]
theorem coe_basis {φ : ι → Type*} (b : ∀ i, Basis (φ i) R M) :
    ⇑(Finsupp.basis b) = fun ix : Σi, φ i => single ix.1 (b ix.1 ix.2) :=
  funext fun ⟨i, x⟩ =>
    Basis.apply_eq_iff.mpr <| by
      classical
      ext ⟨j, y⟩
      by_cases h : i = j
      · cases h
        

Proof state:
case pos.refl
R : Type u_1
M : Type u_2
ι : Type u_3
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
φ : ι → Type u_4
b : (i : ι) → Basis (φ i) R M
x✝ : (i : ι) × φ i
i : ι
x y : φ i
⊢ ((Finsupp.basis b).repr
        fun₀ | { fst := i, snd := x }.fst => (b { fst := i, snd := x }.fst) { fst := i, snd := x }.snd)
      { fst := i, snd := y } =
    (fun₀ | { fst := i, snd := x } => 1) { fst := i, snd := y }

Next tactic:
simp only [basis_repr, single_eq_same, Basis.repr_self,
          Finsupp.single_apply_left sigma_mk_injective]
@[simp]
theorem coe_basis {φ : ι → Type*} (b : ∀ i, Basis (φ i) R M) :
    ⇑(Finsupp.basis b) = fun ix : Σi, φ i => single ix.1 (b ix.1 ix.2) :=
  funext fun ⟨i, x⟩ =>
    Basis.apply_eq_iff.mpr <| by
      classical
      ext ⟨j, y⟩
      by_cases h : i = j
      · cases h
        simp only [basis_repr, single_eq_same, Basis.repr_self,
          Finsupp.single_apply_left sigma_mk_injective]
      · 

Proof state:
case neg
R : Type u_1
M : Type u_2
ι : Type u_3
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
φ : ι → Type u_4
b : (i : ι) → Basis (φ i) R M
x✝ : (i : ι) × φ i
i : ι
x : φ i
j : ι
y : φ j
h : ¬i = j
⊢ ((Finsupp.basis b).repr
        fun₀ | { fst := i, snd := x }.fst => (b { fst := i, snd := x }.fst) { fst := i, snd := x }.snd)
      { fst := j, snd := y } =
    (fun₀ | { fst := i, snd := x } => 1) { fst := j, snd := y }

Next tactic:
have : Sigma.mk i x ≠ Sigma.mk j y := fun h' => h <| congrArg (fun s => s.fst) h'
@[simp]
theorem coe_basis {φ : ι → Type*} (b : ∀ i, Basis (φ i) R M) :
    ⇑(Finsupp.basis b) = fun ix : Σi, φ i => single ix.1 (b ix.1 ix.2) :=
  funext fun ⟨i, x⟩ =>
    Basis.apply_eq_iff.mpr <| by
      classical
      ext ⟨j, y⟩
      by_cases h : i = j
      · cases h
        simp only [basis_repr, single_eq_same, Basis.repr_self,
          Finsupp.single_apply_left sigma_mk_injective]
      · have : Sigma.mk i x ≠ Sigma.mk j y := fun h' => h <| congrArg (fun s => s.fst) h'
        -- Porting note: previously `this` not needed
        

Proof state:
case neg
R : Type u_1
M : Type u_2
ι : Type u_3
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
φ : ι → Type u_4
b : (i : ι) → Basis (φ i) R M
x✝ : (i : ι) × φ i
i : ι
x : φ i
j : ι
y : φ j
h : ¬i = j
this : { fst := i, snd := x } ≠ { fst := j, snd := y }
⊢ ((Finsupp.basis b).repr
        fun₀ | { fst := i, snd := x }.fst => (b { fst := i, snd := x }.fst) { fst := i, snd := x }.snd)
      { fst := j, snd := y } =
    (fun₀ | { fst := i, snd := x } => 1) { fst := j, snd := y }

Next tactic:
simp only [basis_repr, single_apply, h, this, false_and_iff, if_false, LinearEquiv.map_zero,
        zero_apply]
theorem _root_.Finset.sum_single_ite (a : R) (i : n) :
    (Finset.univ.sum fun x : n => Finsupp.single x (ite (i = x) a 0)) = Finsupp.single i a := by
  

Proof state:
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
a : R
i : n
⊢ (Finset.sum Finset.univ fun x => fun₀ | x => if i = x then a else 0) = fun₀ | i => a

Next tactic:
rw [Finset.sum_congr_set {i} (fun x : n => Finsupp.single x (ite (i = x) a 0)) fun _ =>
      Finsupp.single i a]
theorem _root_.Finset.sum_single_ite (a : R) (i : n) :
    (Finset.univ.sum fun x : n => Finsupp.single x (ite (i = x) a 0)) = Finsupp.single i a := by
  rw [Finset.sum_congr_set {i} (fun x : n => Finsupp.single x (ite (i = x) a 0)) fun _ =>
      Finsupp.single i a]
  · 

Proof state:
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
a : R
i : n
⊢ (Finset.sum Finset.univ fun x => fun₀ | i => a) = fun₀ | i => a

Next tactic:
simp
theorem _root_.Finset.sum_single_ite (a : R) (i : n) :
    (Finset.univ.sum fun x : n => Finsupp.single x (ite (i = x) a 0)) = Finsupp.single i a := by
  rw [Finset.sum_congr_set {i} (fun x : n => Finsupp.single x (ite (i = x) a 0)) fun _ =>
      Finsupp.single i a]
  · simp
  · 

Proof state:
case w
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
a : R
i : n
⊢ ∀ x ∈ {i}, (fun₀ | x => if i = x then a else 0) = fun₀ | i => a

Next tactic:
intro x hx
theorem _root_.Finset.sum_single_ite (a : R) (i : n) :
    (Finset.univ.sum fun x : n => Finsupp.single x (ite (i = x) a 0)) = Finsupp.single i a := by
  rw [Finset.sum_congr_set {i} (fun x : n => Finsupp.single x (ite (i = x) a 0)) fun _ =>
      Finsupp.single i a]
  · simp
  · intro x hx
    

Proof state:
case w
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
a : R
i x : n
hx : x ∈ {i}
⊢ (fun₀ | x => if i = x then a else 0) = fun₀ | i => a

Next tactic:
rw [Set.mem_singleton_iff] at hx
theorem _root_.Finset.sum_single_ite (a : R) (i : n) :
    (Finset.univ.sum fun x : n => Finsupp.single x (ite (i = x) a 0)) = Finsupp.single i a := by
  rw [Finset.sum_congr_set {i} (fun x : n => Finsupp.single x (ite (i = x) a 0)) fun _ =>
      Finsupp.single i a]
  · simp
  · intro x hx
    rw [Set.mem_singleton_iff] at hx
    

Proof state:
case w
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
a : R
i x : n
hx : x = i
⊢ (fun₀ | x => if i = x then a else 0) = fun₀ | i => a

Next tactic:
simp [hx]
theorem _root_.Finset.sum_single_ite (a : R) (i : n) :
    (Finset.univ.sum fun x : n => Finsupp.single x (ite (i = x) a 0)) = Finsupp.single i a := by
  rw [Finset.sum_congr_set {i} (fun x : n => Finsupp.single x (ite (i = x) a 0)) fun _ =>
      Finsupp.single i a]
  · simp
  · intro x hx
    rw [Set.mem_singleton_iff] at hx
    simp [hx]
  

Proof state:
case w'
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
a : R
i : n
⊢ ∀ x ∉ {i}, (fun₀ | x => if i = x then a else 0) = 0

Next tactic:
intro x hx
theorem _root_.Finset.sum_single_ite (a : R) (i : n) :
    (Finset.univ.sum fun x : n => Finsupp.single x (ite (i = x) a 0)) = Finsupp.single i a := by
  rw [Finset.sum_congr_set {i} (fun x : n => Finsupp.single x (ite (i = x) a 0)) fun _ =>
      Finsupp.single i a]
  · simp
  · intro x hx
    rw [Set.mem_singleton_iff] at hx
    simp [hx]
  intro x hx
  

Proof state:
case w'
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
a : R
i x : n
hx : x ∉ {i}
⊢ (fun₀ | x => if i = x then a else 0) = 0

Next tactic:
have hx' : ¬i = x := by
    refine' ne_comm.mp _
    rwa [mem_singleton_iff] at hx
theorem _root_.Finset.sum_single_ite (a : R) (i : n) :
    (Finset.univ.sum fun x : n => Finsupp.single x (ite (i = x) a 0)) = Finsupp.single i a := by
  rw [Finset.sum_congr_set {i} (fun x : n => Finsupp.single x (ite (i = x) a 0)) fun _ =>
      Finsupp.single i a]
  · simp
  · intro x hx
    rw [Set.mem_singleton_iff] at hx
    simp [hx]
  intro x hx
  have hx' : ¬i = x := by
    

Proof state:
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
a : R
i x : n
hx : x ∉ {i}
⊢ ¬i = x

Next tactic:
refine' ne_comm.mp _
theorem _root_.Finset.sum_single_ite (a : R) (i : n) :
    (Finset.univ.sum fun x : n => Finsupp.single x (ite (i = x) a 0)) = Finsupp.single i a := by
  rw [Finset.sum_congr_set {i} (fun x : n => Finsupp.single x (ite (i = x) a 0)) fun _ =>
      Finsupp.single i a]
  · simp
  · intro x hx
    rw [Set.mem_singleton_iff] at hx
    simp [hx]
  intro x hx
  have hx' : ¬i = x := by
    refine' ne_comm.mp _
    

Proof state:
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
a : R
i x : n
hx : x ∉ {i}
⊢ x ≠ i

Next tactic:
rwa [mem_singleton_iff] at hx
theorem _root_.Finset.sum_single_ite (a : R) (i : n) :
    (Finset.univ.sum fun x : n => Finsupp.single x (ite (i = x) a 0)) = Finsupp.single i a := by
  rw [Finset.sum_congr_set {i} (fun x : n => Finsupp.single x (ite (i = x) a 0)) fun _ =>
      Finsupp.single i a]
  · simp
  · intro x hx
    rw [Set.mem_singleton_iff] at hx
    simp [hx]
  intro x hx
  have hx' : ¬i = x := by
    refine' ne_comm.mp _
    rwa [mem_singleton_iff] at hx
  

Proof state:
case w'
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
a : R
i x : n
hx : x ∉ {i}
hx' : ¬i = x
⊢ (fun₀ | x => if i = x then a else 0) = 0

Next tactic:
simp [hx']
theorem equivFun_symm_stdBasis (b : Basis n R M) (i : n) :
    b.equivFun.symm (LinearMap.stdBasis R (fun _ => R) i 1) = b i := by
  

Proof state:
R : Type u_1
M : Type u_2
n : Type u_3
inst✝⁴ : DecidableEq n
inst✝³ : Fintype n
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
b : Basis n R M
i : n
⊢ (LinearEquiv.symm (equivFun b)) ((stdBasis R (fun x => R) i) 1) = b i

Next tactic:
simp
protected instance mul : Mul (PushoutI φ) := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
⊢ Mul (PushoutI φ)

Next tactic:
delta PushoutI
protected instance mul : Mul (PushoutI φ) := by
  delta PushoutI; 

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
⊢ Mul (Con.Quotient (con φ))

Next tactic:
infer_instance
protected instance one : One (PushoutI φ) := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
⊢ One (PushoutI φ)

Next tactic:
delta PushoutI
protected instance one : One (PushoutI φ) := by
  delta PushoutI; 

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
⊢ One (Con.Quotient (con φ))

Next tactic:
infer_instance
theorem of_comp_eq_base (i : ι) : (of i).comp (φ i) = (base φ) := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
i : ι
⊢ MonoidHom.comp (of i) (φ i) = base φ

Next tactic:
ext x
theorem of_comp_eq_base (i : ι) : (of i).comp (φ i) = (base φ) := by
  ext x
  

Proof state:
case h
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
i : ι
x : H
⊢ (MonoidHom.comp (of i) (φ i)) x = (base φ) x

Next tactic:
apply (Con.eq _).2
theorem of_comp_eq_base (i : ι) : (of i).comp (φ i) = (base φ) := by
  ext x
  apply (Con.eq _).2
  

Proof state:
case h
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
i : ι
x : H
⊢ (con φ) ((MonoidHom.comp inl CoprodI.of) ((φ i) x)) (inr x)

Next tactic:
refine ConGen.Rel.of _ _ ?_
theorem of_comp_eq_base (i : ι) : (of i).comp (φ i) = (base φ) := by
  ext x
  apply (Con.eq _).2
  refine ConGen.Rel.of _ _ ?_
  

Proof state:
case h
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
i : ι
x : H
⊢ ∃ i_1 x', (MonoidHom.comp inl CoprodI.of) ((φ i) x) = inl (CoprodI.of ((φ i_1) x')) ∧ inr x = inr x'

Next tactic:
simp only [MonoidHom.comp_apply, Set.mem_iUnion, Set.mem_range]
theorem of_comp_eq_base (i : ι) : (of i).comp (φ i) = (base φ) := by
  ext x
  apply (Con.eq _).2
  refine ConGen.Rel.of _ _ ?_
  simp only [MonoidHom.comp_apply, Set.mem_iUnion, Set.mem_range]
  

Proof state:
case h
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
i : ι
x : H
⊢ ∃ i_1 x', inl (CoprodI.of ((φ i) x)) = inl (CoprodI.of ((φ i_1) x')) ∧ inr x = inr x'

Next tactic:
exact ⟨_, _, rfl, rfl⟩
variable (φ) in
theorem of_apply_eq_base (i : ι) (x : H) : of i (φ i x) = base φ x := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
i : ι
x : H
⊢ (of i) ((φ i) x) = (base φ) x

Next tactic:
rw [← MonoidHom.comp_apply, of_comp_eq_base]
/-- Define a homomorphism out of the pushout of monoids be defining it on each object in the
diagram -/
def lift (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k) :
    PushoutI φ →* K :=
  Con.lift _ (Coprod.lift (CoprodI.lift f) k) <| by
    

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
f : (i : ι) → G i →* K
k : H →* K
hf : ∀ (i : ι), MonoidHom.comp (f i) (φ i) = k
⊢ con φ ≤ Con.ker (Coprod.lift (CoprodI.lift f) k)

Next tactic:
apply Con.conGen_le <| fun x y => ?_
/-- Define a homomorphism out of the pushout of monoids be defining it on each object in the
diagram -/
def lift (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k) :
    PushoutI φ →* K :=
  Con.lift _ (Coprod.lift (CoprodI.lift f) k) <| by
    apply Con.conGen_le <| fun x y => ?_
    

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
f : (i : ι) → G i →* K
k : H →* K
hf : ∀ (i : ι), MonoidHom.comp (f i) (φ i) = k
x y : (CoprodI fun i => (fun i => G i) i) ∗ H
⊢ (∃ i x', x = inl (CoprodI.of ((φ i) x')) ∧ y = inr x') → (Con.ker (Coprod.lift (CoprodI.lift f) k)) x y

Next tactic:
rintro ⟨i, x', rfl, rfl⟩
/-- Define a homomorphism out of the pushout of monoids be defining it on each object in the
diagram -/
def lift (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k) :
    PushoutI φ →* K :=
  Con.lift _ (Coprod.lift (CoprodI.lift f) k) <| by
    apply Con.conGen_le <| fun x y => ?_
    rintro ⟨i, x', rfl, rfl⟩
    

Proof state:
case intro.intro.intro
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
f : (i : ι) → G i →* K
k : H →* K
hf : ∀ (i : ι), MonoidHom.comp (f i) (φ i) = k
i : ι
x' : H
⊢ (Con.ker (Coprod.lift (CoprodI.lift f) k)) (inl (CoprodI.of ((φ i) x'))) (inr x')

Next tactic:
simp only [FunLike.ext_iff, MonoidHom.coe_comp, comp_apply] at hf
/-- Define a homomorphism out of the pushout of monoids be defining it on each object in the
diagram -/
def lift (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k) :
    PushoutI φ →* K :=
  Con.lift _ (Coprod.lift (CoprodI.lift f) k) <| by
    apply Con.conGen_le <| fun x y => ?_
    rintro ⟨i, x', rfl, rfl⟩
    simp only [FunLike.ext_iff, MonoidHom.coe_comp, comp_apply] at hf
    

Proof state:
case intro.intro.intro
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
f : (i : ι) → G i →* K
k : H →* K
i : ι
x' : H
hf : ∀ (i : ι) (x : H), (f i) ((φ i) x) = k x
⊢ (Con.ker (Coprod.lift (CoprodI.lift f) k)) (inl (CoprodI.of ((φ i) x'))) (inr x')

Next tactic:
simp [hf]
@[simp]
theorem lift_of (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k)
    {i : ι} (g : G i) : (lift f k hf) (of i g : PushoutI φ) = f i g := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
f : (i : ι) → G i →* K
k : H →* K
hf : ∀ (i : ι), MonoidHom.comp (f i) (φ i) = k
i : ι
g : G i
⊢ (lift f k hf) ((of i) g) = (f i) g

Next tactic:
delta PushoutI lift of
@[simp]
theorem lift_of (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k)
    {i : ι} (g : G i) : (lift f k hf) (of i g : PushoutI φ) = f i g := by
  delta PushoutI lift of
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
f : (i : ι) → G i →* K
k : H →* K
hf : ∀ (i : ι), MonoidHom.comp (f i) (φ i) = k
i : ι
g : G i
⊢ (Con.lift (con fun i => φ i) (Coprod.lift (CoprodI.lift f) k)
        (_ :
          (conGen fun x y => ∃ i x', x = inl (CoprodI.of ((φ i) x')) ∧ y = inr x') ≤
            Con.ker (Coprod.lift (CoprodI.lift f) k)))
      ((MonoidHom.comp (Con.mk' (con φ)) (MonoidHom.comp inl CoprodI.of)) g) =
    (f i) g

Next tactic:
simp only [MonoidHom.coe_comp, Con.coe_mk', comp_apply, Con.lift_coe,
    lift_apply_inl, CoprodI.lift_of]
@[simp]
theorem lift_base (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k)
    (g : H) : (lift f k hf) (base φ g : PushoutI φ) = k g := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
f : (i : ι) → G i →* K
k : H →* K
hf : ∀ (i : ι), MonoidHom.comp (f i) (φ i) = k
g : H
⊢ (lift f k hf) ((base φ) g) = k g

Next tactic:
delta PushoutI lift base
@[simp]
theorem lift_base (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k)
    (g : H) : (lift f k hf) (base φ g : PushoutI φ) = k g := by
  delta PushoutI lift base
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
f : (i : ι) → G i →* K
k : H →* K
hf : ∀ (i : ι), MonoidHom.comp (f i) (φ i) = k
g : H
⊢ (Con.lift (con fun i => φ i) (Coprod.lift (CoprodI.lift f) k)
        (_ :
          (conGen fun x y => ∃ i x', x = inl (CoprodI.of ((φ i) x')) ∧ y = inr x') ≤
            Con.ker (Coprod.lift (CoprodI.lift f) k)))
      ((MonoidHom.comp (Con.mk' (con φ)) inr) g) =
    k g

Next tactic:
simp only [MonoidHom.coe_comp, Con.coe_mk', comp_apply, Con.lift_coe, lift_apply_inr]
@[ext high]
theorem hom_ext_nonempty [hn : Nonempty ι]
    {f g : PushoutI φ →* K}
    (h : ∀ i, f.comp (of i : G i →* _) = g.comp (of i : G i →* _)) : f = g :=
  hom_ext h <| by
    

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
hn : Nonempty ι
f g : PushoutI φ →* K
h : ∀ (i : ι), MonoidHom.comp f (of i) = MonoidHom.comp g (of i)
⊢ MonoidHom.comp f (base φ) = MonoidHom.comp g (base φ)

Next tactic:
cases hn with
    | intro i =>
      ext
      rw [← of_comp_eq_base i, ← MonoidHom.comp_assoc, h, MonoidHom.comp_assoc]
@[ext high]
theorem hom_ext_nonempty [hn : Nonempty ι]
    {f g : PushoutI φ →* K}
    (h : ∀ i, f.comp (of i : G i →* _) = g.comp (of i : G i →* _)) : f = g :=
  hom_ext h <| by
    cases hn with
    

Proof state:
case intro
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
f g : PushoutI φ →* K
h : ∀ (i : ι), MonoidHom.comp f (of i) = MonoidHom.comp g (of i)
i : ι
⊢ MonoidHom.comp f (base φ) = MonoidHom.comp g (base φ)

Next tactic:
| intro i =>
      ext
      rw [← of_comp_eq_base i, ← MonoidHom.comp_assoc, h, MonoidHom.comp_assoc]