l3lab/ntp-mathlib huggingface dataset:
open UniqueMul in
@[to_additive] instance {ι} (G : ι → Type*) [∀ i, Mul (G i)] [∀ i, UniqueProds (G i)] :
    UniqueProds (∀ i, G i) where
  uniqueMul_of_nonempty {A} := by
    classical
    let _ := isWellFounded_ssubset (α := ∀ i, G i) -- why need this?
    apply IsWellFounded.induction (· ⊂ ·) A; intro A ihA B hA
    apply IsWellFounded.induction (· ⊂ ·) B; intro B ihB hB
    by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
    · exact of_card_le_one hA hB hc.1 hc.2
    simp_rw [not_and_or, not_le] at hc
    obtain ⟨i, hc⟩ := exists_or.mpr (hc.imp exists_of_one_lt_card_pi exists_of_one_lt_card_pi)
    obtain ⟨ai, hA, bi, hB, hi⟩ := uniqueMul_of_nonempty (hA.image (· i)) (hB.image (· i))
    rw [mem_image, ← filter_nonempty_iff] at hA hB
    let A' := A.filter (· i = ai); let B' := B.filter (· i = bi)
    obtain ⟨a0, ha0, b0, hb0, hu⟩ : ∃ a0 ∈ A', ∃ b0 ∈ B', UniqueMul A' B' a0 b0
    · 

Proof state:
G✝ : Type u
H : Type v
inst✝³ : Mul G✝
inst✝² : Mul H
ι : Type ?u.379291
G : ι → Type u_1
inst✝¹ : (i : ι) → Mul (G i)
inst✝ : ∀ (i : ι), UniqueProds (G i)
A✝ : Finset ((i : ι) → G i)
x✝ : IsWellFounded (Finset ((i : ι) → G i)) fun x x_1 => x ⊂ x_1 := isWellFounded_ssubset
A : Finset ((i : ι) → G i)
ihA :
  ∀ y ⊂ A,
    ∀ {B : Finset ((i : ι) → G i)}, Finset.Nonempty y → Finset.Nonempty B → ∃ a0 ∈ y, ∃ b0 ∈ B, UniqueMul y B a0 b0
B✝ : Finset ((i : ι) → G i)
hA✝ : Finset.Nonempty A
B : Finset ((i : ι) → G i)
ihB : ∀ y ⊂ B, Finset.Nonempty y → ∃ a0 ∈ A, ∃ b0 ∈ y, UniqueMul A y a0 b0
hB✝ : Finset.Nonempty B
hc✝ : 1 < card A ∨ 1 < card B
i : ι
hc :
  (1 < card (image (fun x => x i) A) ∧ ∀ (ai : G i), filter (fun x => x i = ai) A ⊂ A) ∨
    1 < card (image (fun x => x i) B) ∧ ∀ (ai : G i), filter (fun x => x i = ai) B ⊂ B
ai : G i
hA : Finset.Nonempty (filter (fun a => a i = ai) A)
bi : G i
hB : Finset.Nonempty (filter (fun a => a i = bi) B)
hi : UniqueMul (image (fun x => x i) A) (image (fun x => x i) B) ai bi
A' : Finset ((i : ι) → G i) := filter (fun x => x i = ai) A
B' : Finset ((i : ι) → G i) := filter (fun x => x i = bi) B
⊢ ∃ a0 ∈ A', ∃ b0 ∈ B', UniqueMul A' B' a0 b0

Next tactic:
rcases hc with hc | hc
open UniqueMul in
@[to_additive] instance {ι} (G : ι → Type*) [∀ i, Mul (G i)] [∀ i, UniqueProds (G i)] :
    UniqueProds (∀ i, G i) where
  uniqueMul_of_nonempty {A} := by
    classical
    let _ := isWellFounded_ssubset (α := ∀ i, G i) -- why need this?
    apply IsWellFounded.induction (· ⊂ ·) A; intro A ihA B hA
    apply IsWellFounded.induction (· ⊂ ·) B; intro B ihB hB
    by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
    · exact of_card_le_one hA hB hc.1 hc.2
    simp_rw [not_and_or, not_le] at hc
    obtain ⟨i, hc⟩ := exists_or.mpr (hc.imp exists_of_one_lt_card_pi exists_of_one_lt_card_pi)
    obtain ⟨ai, hA, bi, hB, hi⟩ := uniqueMul_of_nonempty (hA.image (· i)) (hB.image (· i))
    rw [mem_image, ← filter_nonempty_iff] at hA hB
    let A' := A.filter (· i = ai); let B' := B.filter (· i = bi)
    obtain ⟨a0, ha0, b0, hb0, hu⟩ : ∃ a0 ∈ A', ∃ b0 ∈ B', UniqueMul A' B' a0 b0
    · rcases hc with hc | hc; · 

Proof state:
case inl
G✝ : Type u
H : Type v
inst✝³ : Mul G✝
inst✝² : Mul H
ι : Type ?u.379291
G : ι → Type u_1
inst✝¹ : (i : ι) → Mul (G i)
inst✝ : ∀ (i : ι), UniqueProds (G i)
A✝ : Finset ((i : ι) → G i)
x✝ : IsWellFounded (Finset ((i : ι) → G i)) fun x x_1 => x ⊂ x_1 := isWellFounded_ssubset
A : Finset ((i : ι) → G i)
ihA :
  ∀ y ⊂ A,
    ∀ {B : Finset ((i : ι) → G i)}, Finset.Nonempty y → Finset.Nonempty B → ∃ a0 ∈ y, ∃ b0 ∈ B, UniqueMul y B a0 b0
B✝ : Finset ((i : ι) → G i)
hA✝ : Finset.Nonempty A
B : Finset ((i : ι) → G i)
ihB : ∀ y ⊂ B, Finset.Nonempty y → ∃ a0 ∈ A, ∃ b0 ∈ y, UniqueMul A y a0 b0
hB✝ : Finset.Nonempty B
hc✝ : 1 < card A ∨ 1 < card B
i : ι
ai : G i
hA : Finset.Nonempty (filter (fun a => a i = ai) A)
bi : G i
hB : Finset.Nonempty (filter (fun a => a i = bi) B)
hi : UniqueMul (image (fun x => x i) A) (image (fun x => x i) B) ai bi
A' : Finset ((i : ι) → G i) := filter (fun x => x i = ai) A
B' : Finset ((i : ι) → G i) := filter (fun x => x i = bi) B
hc : 1 < card (image (fun x => x i) A) ∧ ∀ (ai : G i), filter (fun x => x i = ai) A ⊂ A
⊢ ∃ a0 ∈ A', ∃ b0 ∈ B', UniqueMul A' B' a0 b0

Next tactic:
exact ihA A' (hc.2 ai) hA hB
open UniqueMul in
@[to_additive] instance {ι} (G : ι → Type*) [∀ i, Mul (G i)] [∀ i, UniqueProds (G i)] :
    UniqueProds (∀ i, G i) where
  uniqueMul_of_nonempty {A} := by
    classical
    let _ := isWellFounded_ssubset (α := ∀ i, G i) -- why need this?
    apply IsWellFounded.induction (· ⊂ ·) A; intro A ihA B hA
    apply IsWellFounded.induction (· ⊂ ·) B; intro B ihB hB
    by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
    · exact of_card_le_one hA hB hc.1 hc.2
    simp_rw [not_and_or, not_le] at hc
    obtain ⟨i, hc⟩ := exists_or.mpr (hc.imp exists_of_one_lt_card_pi exists_of_one_lt_card_pi)
    obtain ⟨ai, hA, bi, hB, hi⟩ := uniqueMul_of_nonempty (hA.image (· i)) (hB.image (· i))
    rw [mem_image, ← filter_nonempty_iff] at hA hB
    let A' := A.filter (· i = ai); let B' := B.filter (· i = bi)
    obtain ⟨a0, ha0, b0, hb0, hu⟩ : ∃ a0 ∈ A', ∃ b0 ∈ B', UniqueMul A' B' a0 b0
    · rcases hc with hc | hc; · exact ihA A' (hc.2 ai) hA hB
      

Proof state:
case inr
G✝ : Type u
H : Type v
inst✝³ : Mul G✝
inst✝² : Mul H
ι : Type ?u.379291
G : ι → Type u_1
inst✝¹ : (i : ι) → Mul (G i)
inst✝ : ∀ (i : ι), UniqueProds (G i)
A✝ : Finset ((i : ι) → G i)
x✝ : IsWellFounded (Finset ((i : ι) → G i)) fun x x_1 => x ⊂ x_1 := isWellFounded_ssubset
A : Finset ((i : ι) → G i)
ihA :
  ∀ y ⊂ A,
    ∀ {B : Finset ((i : ι) → G i)}, Finset.Nonempty y → Finset.Nonempty B → ∃ a0 ∈ y, ∃ b0 ∈ B, UniqueMul y B a0 b0
B✝ : Finset ((i : ι) → G i)
hA✝ : Finset.Nonempty A
B : Finset ((i : ι) → G i)
ihB : ∀ y ⊂ B, Finset.Nonempty y → ∃ a0 ∈ A, ∃ b0 ∈ y, UniqueMul A y a0 b0
hB✝ : Finset.Nonempty B
hc✝ : 1 < card A ∨ 1 < card B
i : ι
ai : G i
hA : Finset.Nonempty (filter (fun a => a i = ai) A)
bi : G i
hB : Finset.Nonempty (filter (fun a => a i = bi) B)
hi : UniqueMul (image (fun x => x i) A) (image (fun x => x i) B) ai bi
A' : Finset ((i : ι) → G i) := filter (fun x => x i = ai) A
B' : Finset ((i : ι) → G i) := filter (fun x => x i = bi) B
hc : 1 < card (image (fun x => x i) B) ∧ ∀ (ai : G i), filter (fun x => x i = ai) B ⊂ B
⊢ ∃ a0 ∈ A', ∃ b0 ∈ B', UniqueMul A' B' a0 b0

Next tactic:
by_cases hA' : A' = A
open UniqueMul in
@[to_additive] instance {ι} (G : ι → Type*) [∀ i, Mul (G i)] [∀ i, UniqueProds (G i)] :
    UniqueProds (∀ i, G i) where
  uniqueMul_of_nonempty {A} := by
    classical
    let _ := isWellFounded_ssubset (α := ∀ i, G i) -- why need this?
    apply IsWellFounded.induction (· ⊂ ·) A; intro A ihA B hA
    apply IsWellFounded.induction (· ⊂ ·) B; intro B ihB hB
    by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
    · exact of_card_le_one hA hB hc.1 hc.2
    simp_rw [not_and_or, not_le] at hc
    obtain ⟨i, hc⟩ := exists_or.mpr (hc.imp exists_of_one_lt_card_pi exists_of_one_lt_card_pi)
    obtain ⟨ai, hA, bi, hB, hi⟩ := uniqueMul_of_nonempty (hA.image (· i)) (hB.image (· i))
    rw [mem_image, ← filter_nonempty_iff] at hA hB
    let A' := A.filter (· i = ai); let B' := B.filter (· i = bi)
    obtain ⟨a0, ha0, b0, hb0, hu⟩ : ∃ a0 ∈ A', ∃ b0 ∈ B', UniqueMul A' B' a0 b0
    · rcases hc with hc | hc; · exact ihA A' (hc.2 ai) hA hB
      by_cases hA' : A' = A; rw [hA']
      exacts [ihB B' (hc.2 bi) hB, ihA A' ((A.filter_subset _).ssubset_of_ne hA') hA hB]
    

Proof state:
case neg.intro.intro.intro.intro.intro.intro.intro.intro.intro
G✝ : Type u
H : Type v
inst✝³ : Mul G✝
inst✝² : Mul H
ι : Type ?u.379291
G : ι → Type u_1
inst✝¹ : (i : ι) → Mul (G i)
inst✝ : ∀ (i : ι), UniqueProds (G i)
A✝ : Finset ((i : ι) → G i)
x✝ : IsWellFounded (Finset ((i : ι) → G i)) fun x x_1 => x ⊂ x_1 := isWellFounded_ssubset
A : Finset ((i : ι) → G i)
ihA :
  ∀ y ⊂ A,
    ∀ {B : Finset ((i : ι) → G i)}, Finset.Nonempty y → Finset.Nonempty B → ∃ a0 ∈ y, ∃ b0 ∈ B, UniqueMul y B a0 b0
B✝ : Finset ((i : ι) → G i)
hA✝ : Finset.Nonempty A
B : Finset ((i : ι) → G i)
ihB : ∀ y ⊂ B, Finset.Nonempty y → ∃ a0 ∈ A, ∃ b0 ∈ y, UniqueMul A y a0 b0
hB✝ : Finset.Nonempty B
hc✝ : 1 < card A ∨ 1 < card B
i : ι
hc :
  (1 < card (image (fun x => x i) A) ∧ ∀ (ai : G i), filter (fun x => x i = ai) A ⊂ A) ∨
    1 < card (image (fun x => x i) B) ∧ ∀ (ai : G i), filter (fun x => x i = ai) B ⊂ B
ai : G i
hA : Finset.Nonempty (filter (fun a => a i = ai) A)
bi : G i
hB : Finset.Nonempty (filter (fun a => a i = bi) B)
hi : UniqueMul (image (fun x => x i) A) (image (fun x => x i) B) ai bi
A' : Finset ((i : ι) → G i) := filter (fun x => x i = ai) A
B' : Finset ((i : ι) → G i) := filter (fun x => x i = bi) B
a0 : (i : ι) → G i
ha0 : a0 ∈ A'
b0 : (i : ι) → G i
hb0 : b0 ∈ B'
hu : UniqueMul A' B' a0 b0
⊢ ∃ a0 ∈ A, ∃ b0 ∈ B, UniqueMul A B a0 b0

Next tactic:
rw [mem_filter] at ha0 hb0
open UniqueMul in
@[to_additive] instance {ι} (G : ι → Type*) [∀ i, Mul (G i)] [∀ i, UniqueProds (G i)] :
    UniqueProds (∀ i, G i) where
  uniqueMul_of_nonempty {A} := by
    classical
    let _ := isWellFounded_ssubset (α := ∀ i, G i) -- why need this?
    apply IsWellFounded.induction (· ⊂ ·) A; intro A ihA B hA
    apply IsWellFounded.induction (· ⊂ ·) B; intro B ihB hB
    by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
    · exact of_card_le_one hA hB hc.1 hc.2
    simp_rw [not_and_or, not_le] at hc
    obtain ⟨i, hc⟩ := exists_or.mpr (hc.imp exists_of_one_lt_card_pi exists_of_one_lt_card_pi)
    obtain ⟨ai, hA, bi, hB, hi⟩ := uniqueMul_of_nonempty (hA.image (· i)) (hB.image (· i))
    rw [mem_image, ← filter_nonempty_iff] at hA hB
    let A' := A.filter (· i = ai); let B' := B.filter (· i = bi)
    obtain ⟨a0, ha0, b0, hb0, hu⟩ : ∃ a0 ∈ A', ∃ b0 ∈ B', UniqueMul A' B' a0 b0
    · rcases hc with hc | hc; · exact ihA A' (hc.2 ai) hA hB
      by_cases hA' : A' = A; rw [hA']
      exacts [ihB B' (hc.2 bi) hB, ihA A' ((A.filter_subset _).ssubset_of_ne hA') hA hB]
    rw [mem_filter] at ha0 hb0
    

Proof state:
case neg.intro.intro.intro.intro.intro.intro.intro.intro.intro
G✝ : Type u
H : Type v
inst✝³ : Mul G✝
inst✝² : Mul H
ι : Type ?u.379291
G : ι → Type u_1
inst✝¹ : (i : ι) → Mul (G i)
inst✝ : ∀ (i : ι), UniqueProds (G i)
A✝ : Finset ((i : ι) → G i)
x✝ : IsWellFounded (Finset ((i : ι) → G i)) fun x x_1 => x ⊂ x_1 := isWellFounded_ssubset
A : Finset ((i : ι) → G i)
ihA :
  ∀ y ⊂ A,
    ∀ {B : Finset ((i : ι) → G i)}, Finset.Nonempty y → Finset.Nonempty B → ∃ a0 ∈ y, ∃ b0 ∈ B, UniqueMul y B a0 b0
B✝ : Finset ((i : ι) → G i)
hA✝ : Finset.Nonempty A
B : Finset ((i : ι) → G i)
ihB : ∀ y ⊂ B, Finset.Nonempty y → ∃ a0 ∈ A, ∃ b0 ∈ y, UniqueMul A y a0 b0
hB✝ : Finset.Nonempty B
hc✝ : 1 < card A ∨ 1 < card B
i : ι
hc :
  (1 < card (image (fun x => x i) A) ∧ ∀ (ai : G i), filter (fun x => x i = ai) A ⊂ A) ∨
    1 < card (image (fun x => x i) B) ∧ ∀ (ai : G i), filter (fun x => x i = ai) B ⊂ B
ai : G i
hA : Finset.Nonempty (filter (fun a => a i = ai) A)
bi : G i
hB : Finset.Nonempty (filter (fun a => a i = bi) B)
hi : UniqueMul (image (fun x => x i) A) (image (fun x => x i) B) ai bi
A' : Finset ((i : ι) → G i) := filter (fun x => x i = ai) A
B' : Finset ((i : ι) → G i) := filter (fun x => x i = bi) B
a0 : (i : ι) → G i
ha0 : a0 ∈ A ∧ a0 i = ai
b0 : (i : ι) → G i
hb0 : b0 ∈ B ∧ b0 i = bi
hu : UniqueMul A' B' a0 b0
⊢ ∃ a0 ∈ A, ∃ b0 ∈ B, UniqueMul A B a0 b0

Next tactic:
exact ⟨a0, ha0.1, b0, hb0.1, of_image_filter (Pi.evalMulHom G i) ha0.2 hb0.2 hi hu⟩
open ULift in
@[to_additive] instance [UniqueProds G] [UniqueProds H] : UniqueProds (G × H) := by
  

Proof state:
G : Type u
H : Type v
inst✝³ : Mul G
inst✝² : Mul H
inst✝¹ : UniqueProds G
inst✝ : UniqueProds H
⊢ UniqueProds (G × H)

Next tactic:
have : ∀ b, UniqueProds (I G H b) := Bool.rec ?_ ?_
open ULift in
@[to_additive] instance [UniqueProds G] [UniqueProds H] : UniqueProds (G × H) := by
  have : ∀ b, UniqueProds (I G H b) := Bool.rec ?_ ?_
  · 

Proof state:
case refine_3
G : Type u
H : Type v
inst✝³ : Mul G
inst✝² : Mul H
inst✝¹ : UniqueProds G
inst✝ : UniqueProds H
⊢ UniqueProds (I G H true)

Next tactic:
exact mulHom_image_of_injective (downMulHom H) down_injective ‹_›
open ULift in
@[to_additive] instance [UniqueProds G] [UniqueProds H] : UniqueProds (G × H) := by
  have : ∀ b, UniqueProds (I G H b) := Bool.rec ?_ ?_
  · exact mulHom_image_of_injective (downMulHom H) down_injective ‹_›
  · 

Proof state:
case refine_1
G : Type u
H : Type v
inst✝³ : Mul G
inst✝² : Mul H
inst✝¹ : UniqueProds G
inst✝ : UniqueProds H
this : ∀ (b : Bool), UniqueProds (I G H b)
⊢ UniqueProds (G × H)

Next tactic:
refine mulHom_image_of_injective (Prod.upMulHom G H) (fun x y he => Prod.ext ?_ ?_)
      (instUniqueProdsForAllInstMul <| I G H)
open ULift in
@[to_additive] instance [UniqueProds G] [UniqueProds H] : UniqueProds (G × H) := by
  have : ∀ b, UniqueProds (I G H b) := Bool.rec ?_ ?_
  · exact mulHom_image_of_injective (downMulHom H) down_injective ‹_›
  · refine mulHom_image_of_injective (Prod.upMulHom G H) (fun x y he => Prod.ext ?_ ?_)
      (instUniqueProdsForAllInstMul <| I G H) <;> 

Proof state:
case refine_1.refine_1
G : Type u
H : Type v
inst✝³ : Mul G
inst✝² : Mul H
inst✝¹ : UniqueProds G
inst✝ : UniqueProds H
this : ∀ (b : Bool), UniqueProds (I G H b)
x y : G × H
he : (Prod.upMulHom G H) x = (Prod.upMulHom G H) y
⊢ x.1 = y.1

Next tactic:
apply up_injective
open ULift in
@[to_additive] instance [UniqueProds G] [UniqueProds H] : UniqueProds (G × H) := by
  have : ∀ b, UniqueProds (I G H b) := Bool.rec ?_ ?_
  · exact mulHom_image_of_injective (downMulHom H) down_injective ‹_›
  · refine mulHom_image_of_injective (Prod.upMulHom G H) (fun x y he => Prod.ext ?_ ?_)
      (instUniqueProdsForAllInstMul <| I G H) <;> 

Proof state:
case refine_1.refine_2
G : Type u
H : Type v
inst✝³ : Mul G
inst✝² : Mul H
inst✝¹ : UniqueProds G
inst✝ : UniqueProds H
this : ∀ (b : Bool), UniqueProds (I G H b)
x y : G × H
he : (Prod.upMulHom G H) x = (Prod.upMulHom G H) y
⊢ x.2 = y.2

Next tactic:
apply up_injective
open ULift in
@[to_additive] instance [UniqueProds G] [UniqueProds H] : UniqueProds (G × H) := by
  have : ∀ b, UniqueProds (I G H b) := Bool.rec ?_ ?_
  · exact mulHom_image_of_injective (downMulHom H) down_injective ‹_›
  · refine mulHom_image_of_injective (Prod.upMulHom G H) (fun x y he => Prod.ext ?_ ?_)
      (instUniqueProdsForAllInstMul <| I G H) <;> apply up_injective
    

Proof state:
case refine_1.refine_1.a
G : Type u
H : Type v
inst✝³ : Mul G
inst✝² : Mul H
inst✝¹ : UniqueProds G
inst✝ : UniqueProds H
this : ∀ (b : Bool), UniqueProds (I G H b)
x y : G × H
he : (Prod.upMulHom G H) x = (Prod.upMulHom G H) y
⊢ { down := x.1 } = { down := y.1 }
case refine_1.refine_2.a
G : Type u
H : Type v
inst✝³ : Mul G
inst✝² : Mul H
inst✝¹ : UniqueProds G
inst✝ : UniqueProds H
this : ∀ (b : Bool), UniqueProds (I G H b)
x y : G × H
he : (Prod.upMulHom G H) x = (Prod.upMulHom G H) y
⊢ { down := x.2 } = { down := y.2 }

Next tactic:
exacts [congr_fun he false, congr_fun he true]
open ULift in
@[to_additive] instance [UniqueProds G] [UniqueProds H] : UniqueProds (G × H) := by
  have : ∀ b, UniqueProds (I G H b) := Bool.rec ?_ ?_
  · exact mulHom_image_of_injective (downMulHom H) down_injective ‹_›
  · refine mulHom_image_of_injective (Prod.upMulHom G H) (fun x y he => Prod.ext ?_ ?_)
      (instUniqueProdsForAllInstMul <| I G H) <;> apply up_injective
    exacts [congr_fun he false, congr_fun he true]
  · 

Proof state:
case refine_2
G : Type u
H : Type v
inst✝³ : Mul G
inst✝² : Mul H
inst✝¹ : UniqueProds G
inst✝ : UniqueProds H
⊢ UniqueProds (I G H false)

Next tactic:
exact mulHom_image_of_injective (downMulHom G) down_injective ‹_›
@[to_additive]
theorem mulHom_image_of_injective (f : H →ₙ* G) (hf : Function.Injective f)
    (uG : TwoUniqueProds G) : TwoUniqueProds H where
  uniqueMul_of_one_lt_card {A B} hc := by
    

Proof state:
G : Type u
H : Type v
inst✝¹ : Mul G
inst✝ : Mul H
f : H →ₙ* G
hf : Function.Injective ⇑f
uG : TwoUniqueProds G
A B : Finset H
hc : 1 < card A * card B
⊢ ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2

Next tactic:
classical
    simp_rw [← card_map ⟨f, hf⟩] at hc
    obtain ⟨⟨a1, b1⟩, h1, ⟨a2, b2⟩, h2, hne, hu1, hu2⟩ := uG.uniqueMul_of_one_lt_card hc
    simp only [mem_product, mem_map] at h1 h2 ⊢
    obtain ⟨⟨a1, ha1, rfl⟩, ⟨b1, hb1, rfl⟩⟩ := h1
    obtain ⟨⟨a2, ha2, rfl⟩, ⟨b2, hb2, rfl⟩⟩ := h2
    refine ⟨(a1, b1), ⟨ha1, hb1⟩, (a2, b2), ⟨ha2, hb2⟩, ?_, ?_, ?_⟩
    · rw [Ne, Prod.ext_iff] at hne ⊢; simp_rw [← hf.eq_iff]; exact hne
    all_goals apply (UniqueMul.mulHom_map_iff ⟨f, hf⟩ f.2).mp
    exacts [hu1, hu2]
@[to_additive]
theorem mulHom_image_of_injective (f : H →ₙ* G) (hf : Function.Injective f)
    (uG : TwoUniqueProds G) : TwoUniqueProds H where
  uniqueMul_of_one_lt_card {A B} hc := by
    classical
    

Proof state:
G : Type u
H : Type v
inst✝¹ : Mul G
inst✝ : Mul H
f : H →ₙ* G
hf : Function.Injective ⇑f
uG : TwoUniqueProds G
A B : Finset H
hc : 1 < card A * card B
⊢ ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2

Next tactic:
simp_rw [← card_map ⟨f, hf⟩] at hc
@[to_additive]
theorem mulHom_image_of_injective (f : H →ₙ* G) (hf : Function.Injective f)
    (uG : TwoUniqueProds G) : TwoUniqueProds H where
  uniqueMul_of_one_lt_card {A B} hc := by
    classical
    simp_rw [← card_map ⟨f, hf⟩] at hc
    

Proof state:
G : Type u
H : Type v
inst✝¹ : Mul G
inst✝ : Mul H
f : H →ₙ* G
hf : Function.Injective ⇑f
uG : TwoUniqueProds G
A B : Finset H
hc : 1 < card (map { toFun := ⇑f, inj' := hf } A) * card (map { toFun := ⇑f, inj' := hf } B)
⊢ ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2

Next tactic:
obtain ⟨⟨a1, b1⟩, h1, ⟨a2, b2⟩, h2, hne, hu1, hu2⟩ := uG.uniqueMul_of_one_lt_card hc
@[to_additive]
theorem mulHom_image_of_injective (f : H →ₙ* G) (hf : Function.Injective f)
    (uG : TwoUniqueProds G) : TwoUniqueProds H where
  uniqueMul_of_one_lt_card {A B} hc := by
    classical
    simp_rw [← card_map ⟨f, hf⟩] at hc
    obtain ⟨⟨a1, b1⟩, h1, ⟨a2, b2⟩, h2, hne, hu1, hu2⟩ := uG.uniqueMul_of_one_lt_card hc
    

Proof state:
case intro.mk.intro.intro.mk.intro.intro.intro
G : Type u
H : Type v
inst✝¹ : Mul G
inst✝ : Mul H
f : H →ₙ* G
hf : Function.Injective ⇑f
uG : TwoUniqueProds G
A B : Finset H
hc : 1 < card (map { toFun := ⇑f, inj' := hf } A) * card (map { toFun := ⇑f, inj' := hf } B)
a1 b1 : G
h1 : (a1, b1) ∈ map { toFun := ⇑f, inj' := hf } A ×ˢ map { toFun := ⇑f, inj' := hf } B
a2 b2 : G
h2 : (a2, b2) ∈ map { toFun := ⇑f, inj' := hf } A ×ˢ map { toFun := ⇑f, inj' := hf } B
hne : (a1, b1) ≠ (a2, b2)
hu1 : UniqueMul (map { toFun := ⇑f, inj' := hf } A) (map { toFun := ⇑f, inj' := hf } B) (a1, b1).1 (a1, b1).2
hu2 : UniqueMul (map { toFun := ⇑f, inj' := hf } A) (map { toFun := ⇑f, inj' := hf } B) (a2, b2).1 (a2, b2).2
⊢ ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2

Next tactic:
simp only [mem_product, mem_map] at h1 h2 ⊢
@[to_additive]
theorem mulHom_image_of_injective (f : H →ₙ* G) (hf : Function.Injective f)
    (uG : TwoUniqueProds G) : TwoUniqueProds H where
  uniqueMul_of_one_lt_card {A B} hc := by
    classical
    simp_rw [← card_map ⟨f, hf⟩] at hc
    obtain ⟨⟨a1, b1⟩, h1, ⟨a2, b2⟩, h2, hne, hu1, hu2⟩ := uG.uniqueMul_of_one_lt_card hc
    simp only [mem_product, mem_map] at h1 h2 ⊢
    

Proof state:
case intro.mk.intro.intro.mk.intro.intro.intro
G : Type u
H : Type v
inst✝¹ : Mul G
inst✝ : Mul H
f : H →ₙ* G
hf : Function.Injective ⇑f
uG : TwoUniqueProds G
A B : Finset H
hc : 1 < card (map { toFun := ⇑f, inj' := hf } A) * card (map { toFun := ⇑f, inj' := hf } B)
a1 b1 a2 b2 : G
hne : (a1, b1) ≠ (a2, b2)
hu1 : UniqueMul (map { toFun := ⇑f, inj' := hf } A) (map { toFun := ⇑f, inj' := hf } B) (a1, b1).1 (a1, b1).2
hu2 : UniqueMul (map { toFun := ⇑f, inj' := hf } A) (map { toFun := ⇑f, inj' := hf } B) (a2, b2).1 (a2, b2).2
h1 : (∃ a ∈ A, { toFun := ⇑f, inj' := hf } a = a1) ∧ ∃ a ∈ B, { toFun := ⇑f, inj' := hf } a = b1
h2 : (∃ a ∈ A, { toFun := ⇑f, inj' := hf } a = a2) ∧ ∃ a ∈ B, { toFun := ⇑f, inj' := hf } a = b2
⊢ ∃ p1,
    (p1.1 ∈ A ∧ p1.2 ∈ B) ∧ ∃ p2, (p2.1 ∈ A ∧ p2.2 ∈ B) ∧ p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2

Next tactic:
obtain ⟨⟨a1, ha1, rfl⟩, ⟨b1, hb1, rfl⟩⟩ := h1
@[to_additive]
theorem mulHom_image_of_injective (f : H →ₙ* G) (hf : Function.Injective f)
    (uG : TwoUniqueProds G) : TwoUniqueProds H where
  uniqueMul_of_one_lt_card {A B} hc := by
    classical
    simp_rw [← card_map ⟨f, hf⟩] at hc
    obtain ⟨⟨a1, b1⟩, h1, ⟨a2, b2⟩, h2, hne, hu1, hu2⟩ := uG.uniqueMul_of_one_lt_card hc
    simp only [mem_product, mem_map] at h1 h2 ⊢
    obtain ⟨⟨a1, ha1, rfl⟩, ⟨b1, hb1, rfl⟩⟩ := h1
    

Proof state:
case intro.mk.intro.intro.mk.intro.intro.intro.intro.intro.intro.intro.intro
G : Type u
H : Type v
inst✝¹ : Mul G
inst✝ : Mul H
f : H →ₙ* G
hf : Function.Injective ⇑f
uG : TwoUniqueProds G
A B : Finset H
hc : 1 < card (map { toFun := ⇑f, inj' := hf } A) * card (map { toFun := ⇑f, inj' := hf } B)
a2 b2 : G
hu2 : UniqueMul (map { toFun := ⇑f, inj' := hf } A) (map { toFun := ⇑f, inj' := hf } B) (a2, b2).1 (a2, b2).2
h2 : (∃ a ∈ A, { toFun := ⇑f, inj' := hf } a = a2) ∧ ∃ a ∈ B, { toFun := ⇑f, inj' := hf } a = b2
a1 : H
ha1 : a1 ∈ A
b1 : H
hb1 : b1 ∈ B
hne : ({ toFun := ⇑f, inj' := hf } a1, { toFun := ⇑f, inj' := hf } b1) ≠ (a2, b2)
hu1 :
  UniqueMul (map { toFun := ⇑f, inj' := hf } A) (map { toFun := ⇑f, inj' := hf } B)
    ({ toFun := ⇑f, inj' := hf } a1, { toFun := ⇑f, inj' := hf } b1).1
    ({ toFun := ⇑f, inj' := hf } a1, { toFun := ⇑f, inj' := hf } b1).2
⊢ ∃ p1,
    (p1.1 ∈ A ∧ p1.2 ∈ B) ∧ ∃ p2, (p2.1 ∈ A ∧ p2.2 ∈ B) ∧ p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2

Next tactic:
obtain ⟨⟨a2, ha2, rfl⟩, ⟨b2, hb2, rfl⟩⟩ := h2
@[to_additive]
theorem mulHom_image_of_injective (f : H →ₙ* G) (hf : Function.Injective f)
    (uG : TwoUniqueProds G) : TwoUniqueProds H where
  uniqueMul_of_one_lt_card {A B} hc := by
    classical
    simp_rw [← card_map ⟨f, hf⟩] at hc
    obtain ⟨⟨a1, b1⟩, h1, ⟨a2, b2⟩, h2, hne, hu1, hu2⟩ := uG.uniqueMul_of_one_lt_card hc
    simp only [mem_product, mem_map] at h1 h2 ⊢
    obtain ⟨⟨a1, ha1, rfl⟩, ⟨b1, hb1, rfl⟩⟩ := h1
    obtain ⟨⟨a2, ha2, rfl⟩, ⟨b2, hb2, rfl⟩⟩ := h2
    

Proof state:
case intro.mk.intro.intro.mk.intro.intro.intro.intro.intro.intro.intro.intro.intro.intro.intro.intro.intro
G : Type u
H : Type v
inst✝¹ : Mul G
inst✝ : Mul H
f : H →ₙ* G
hf : Function.Injective ⇑f
uG : TwoUniqueProds G
A B : Finset H
hc : 1 < card (map { toFun := ⇑f, inj' := hf } A) * card (map { toFun := ⇑f, inj' := hf } B)
a1 : H
ha1 : a1 ∈ A
b1 : H
hb1 : b1 ∈ B
hu1 :
  UniqueMul (map { toFun := ⇑f, inj' := hf } A) (map { toFun := ⇑f, inj' := hf } B)
    ({ toFun := ⇑f, inj' := hf } a1, { toFun := ⇑f, inj' := hf } b1).1
    ({ toFun := ⇑f, inj' := hf } a1, { toFun := ⇑f, inj' := hf } b1).2
a2 : H
ha2 : a2 ∈ A
b2 : H
hb2 : b2 ∈ B
hu2 :
  UniqueMul (map { toFun := ⇑f, inj' := hf } A) (map { toFun := ⇑f, inj' := hf } B)
    ({ toFun := ⇑f, inj' := hf } a2, { toFun := ⇑f, inj' := hf } b2).1
    ({ toFun := ⇑f, inj' := hf } a2, { toFun := ⇑f, inj' := hf } b2).2
hne :
  ({ toFun := ⇑f, inj' := hf } a1, { toFun := ⇑f, inj' := hf } b1) ≠
    ({ toFun := ⇑f, inj' := hf } a2, { toFun := ⇑f, inj' := hf } b2)
⊢ ∃ p1,
    (p1.1 ∈ A ∧ p1.2 ∈ B) ∧ ∃ p2, (p2.1 ∈ A ∧ p2.2 ∈ B) ∧ p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2

Next tactic:
refine ⟨(a1, b1), ⟨ha1, hb1⟩, (a2, b2), ⟨ha2, hb2⟩, ?_, ?_, ?_⟩