-- Mathlib/GroupTheory/PushoutI.lean
theorem induction_on {motive : PushoutI φ → Prop}
    (x : PushoutI φ)
    (of : ∀ (i : ι) (g : G i), motive (of i g))
    (base : ∀ h, motive (base φ h))
    (mul : ∀ x y, motive x → motive y → motive (x * y)) : motive x

Proof state:
case H.inl.h_one
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
⊢ motive ↑(inl 1)

Tactic:
simpa using base 1

Result:
no goals

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
x : (con φ).Quotient
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
⊢ motive x

Tactic:
induction x using Con.induction_on with
| H x =>
  induction x using Coprod.induction_on with
  | inl g =>
    induction g using CoprodI.induction_on with
    | h_of i g => exact of i g
    | h_mul x y ihx ihy =>
      rw [map_mul]
      exact mul _ _ ihx ihy
    | h_one => simpa using base 1
  | inr h => exact base h
  | mul x y ihx ihy => exact mul _ _ ihx ihy

Result:
no goals

Proof state:
case H.inl.h_mul
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
x y : CoprodI G
ihx : motive ↑(inl x)
ihy : motive ↑(inl y)
⊢ motive ↑(inl (x * y))

Tactic:
rw [map_mul]

Result:
case H.inl.h_mul
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
x y : CoprodI G
ihx : motive ↑(inl x)
ihy : motive ↑(inl y)
⊢ motive ↑(inl x * inl y)

Proof state:
case H.inl
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
g : CoprodI G
⊢ motive ↑(inl g)

Tactic:
induction g using CoprodI.induction_on with
| h_of i g => exact of i g
| h_mul x y ihx ihy =>
  rw [map_mul]
  exact mul _ _ ihx ihy
| h_one => simpa using base 1

Result:
no goals

Proof state:
case H
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
x : CoprodI G ∗ H
⊢ motive ↑x

Tactic:
induction x using Coprod.induction_on with
| inl g =>
  induction g using CoprodI.induction_on with
  | h_of i g => exact of i g
  | h_mul x y ihx ihy =>
    rw [map_mul]
    exact mul _ _ ihx ihy
  | h_one => simpa using base 1
| inr h => exact base h
| mul x y ihx ihy => exact mul _ _ ihx ihy

Result:
no goals

Proof state:
case H.mul
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
x y : CoprodI G ∗ H
ihx : motive ↑x
ihy : motive ↑y
⊢ motive ↑(x * y)

Tactic:
exact mul _ _ ihx ihy

Result:
no goals

Proof state:
case H.inl.h_mul
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
x y : CoprodI G
ihx : motive ↑(inl x)
ihy : motive ↑(inl y)
⊢ motive ↑(inl x * inl y)

Tactic:
exact mul _ _ ihx ihy

Result:
no goals

Proof state:
case H.inr
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
h : H
⊢ motive ↑(inr h)

Tactic:
exact base h

Result:
no goals

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : PushoutI φ → Prop
x : PushoutI φ
of : ∀ (i : ι) (g : G i), motive ((Monoid.PushoutI.of i) g)
base : ∀ (h : H), motive ((Monoid.PushoutI.base φ) h)
mul : ∀ (x y : PushoutI φ), motive x → motive y → motive (x * y)
⊢ motive x

Tactic:
delta PushoutI PushoutI.of PushoutI.base at *

Result:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
x : (con φ).Quotient
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
⊢ motive x

Proof state:
case H.inl.h_of
ι : Type u_1
G : ι → Type u_2
H : Type u_3
inst✝¹ : (i : ι) → Monoid (G i)
inst✝ : Monoid H
φ : (i : ι) → H →* G i
motive : (con φ).Quotient → Prop
of : ∀ (i : ι) (g : G i), motive (((con φ).mk'.comp (inl.comp CoprodI.of)) g)
base : ∀ (h : H), motive (((con φ).mk'.comp inr) h)
mul : ∀ (x y : (con φ).Quotient), motive x → motive y → motive (x * y)
i : ι
g : G i
⊢ motive ↑(inl (CoprodI.of g))

Tactic:
exact of i g

Result:
no goals