l3lab/ntp-mathlib huggingface dataset:
/-- `Unique_Mul` is preserved under multiplicative maps that are injective.

See `UniqueMul.mulHom_map_iff` for a version with swapped bundling. -/
@[to_additive
      "`UniqueAdd` is preserved under additive maps that are injective.

See `UniqueAdd.addHom_map_iff` for a version with swapped bundling."]
theorem mulHom_image_iff [DecidableEq H] (f : G →ₙ* H) (hf : Function.Injective f) :
    UniqueMul (A.image f) (B.image f) (f a0) (f b0) ↔ UniqueMul A B a0 b0 := by
  simp_rw [UniqueMul, Finset.mem_image]
  refine ⟨fun h a b ha hb ab ↦ ?_, fun h _ _ ↦ ?_⟩
  · 

Proof state:
case refine_1
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A B : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
hf : Function.Injective ⇑f
h : ∀ ⦃a b : H⦄, (∃ a_1 ∈ A, f a_1 = a) → (∃ a ∈ B, f a = b) → a * b = f a0 * f b0 → a = f a0 ∧ b = f b0
a b : G
ha : a ∈ A
hb : b ∈ B
ab : a * b = a0 * b0
⊢ a = a0 ∧ b = b0

Next tactic:
rw [← hf.eq_iff, map_mul, map_mul] at ab
/-- `Unique_Mul` is preserved under multiplicative maps that are injective.

See `UniqueMul.mulHom_map_iff` for a version with swapped bundling. -/
@[to_additive
      "`UniqueAdd` is preserved under additive maps that are injective.

See `UniqueAdd.addHom_map_iff` for a version with swapped bundling."]
theorem mulHom_image_iff [DecidableEq H] (f : G →ₙ* H) (hf : Function.Injective f) :
    UniqueMul (A.image f) (B.image f) (f a0) (f b0) ↔ UniqueMul A B a0 b0 := by
  simp_rw [UniqueMul, Finset.mem_image]
  refine ⟨fun h a b ha hb ab ↦ ?_, fun h _ _ ↦ ?_⟩
  · rw [← hf.eq_iff, map_mul, map_mul] at ab
    

Proof state:
case refine_1
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A B : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
hf : Function.Injective ⇑f
h : ∀ ⦃a b : H⦄, (∃ a_1 ∈ A, f a_1 = a) → (∃ a ∈ B, f a = b) → a * b = f a0 * f b0 → a = f a0 ∧ b = f b0
a b : G
ha : a ∈ A
hb : b ∈ B
ab : f a * f b = f a0 * f b0
⊢ a = a0 ∧ b = b0

Next tactic:
have := h ⟨a, ha, rfl⟩ ⟨b, hb, rfl⟩ ab
/-- `Unique_Mul` is preserved under multiplicative maps that are injective.

See `UniqueMul.mulHom_map_iff` for a version with swapped bundling. -/
@[to_additive
      "`UniqueAdd` is preserved under additive maps that are injective.

See `UniqueAdd.addHom_map_iff` for a version with swapped bundling."]
theorem mulHom_image_iff [DecidableEq H] (f : G →ₙ* H) (hf : Function.Injective f) :
    UniqueMul (A.image f) (B.image f) (f a0) (f b0) ↔ UniqueMul A B a0 b0 := by
  simp_rw [UniqueMul, Finset.mem_image]
  refine ⟨fun h a b ha hb ab ↦ ?_, fun h _ _ ↦ ?_⟩
  · rw [← hf.eq_iff, map_mul, map_mul] at ab
    have := h ⟨a, ha, rfl⟩ ⟨b, hb, rfl⟩ ab
    

Proof state:
case refine_1
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A B : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
hf : Function.Injective ⇑f
h : ∀ ⦃a b : H⦄, (∃ a_1 ∈ A, f a_1 = a) → (∃ a ∈ B, f a = b) → a * b = f a0 * f b0 → a = f a0 ∧ b = f b0
a b : G
ha : a ∈ A
hb : b ∈ B
ab : f a * f b = f a0 * f b0
this : f a = f a0 ∧ f b = f b0
⊢ a = a0 ∧ b = b0

Next tactic:
exact ⟨hf this.1, hf this.2⟩
/-- `Unique_Mul` is preserved under multiplicative maps that are injective.

See `UniqueMul.mulHom_map_iff` for a version with swapped bundling. -/
@[to_additive
      "`UniqueAdd` is preserved under additive maps that are injective.

See `UniqueAdd.addHom_map_iff` for a version with swapped bundling."]
theorem mulHom_image_iff [DecidableEq H] (f : G →ₙ* H) (hf : Function.Injective f) :
    UniqueMul (A.image f) (B.image f) (f a0) (f b0) ↔ UniqueMul A B a0 b0 := by
  simp_rw [UniqueMul, Finset.mem_image]
  refine ⟨fun h a b ha hb ab ↦ ?_, fun h _ _ ↦ ?_⟩
  · rw [← hf.eq_iff, map_mul, map_mul] at ab
    have := h ⟨a, ha, rfl⟩ ⟨b, hb, rfl⟩ ab
    exact ⟨hf this.1, hf this.2⟩
  · 

Proof state:
case refine_2
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A B : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
hf : Function.Injective ⇑f
h : ∀ ⦃a b : G⦄, a ∈ A → b ∈ B → a * b = a0 * b0 → a = a0 ∧ b = b0
x✝¹ x✝ : H
⊢ (∃ a ∈ A, f a = x✝¹) → (∃ a ∈ B, f a = x✝) → x✝¹ * x✝ = f a0 * f b0 → x✝¹ = f a0 ∧ x✝ = f b0

Next tactic:
rintro ⟨a, aA, rfl⟩ ⟨b, bB, rfl⟩ ab
/-- `Unique_Mul` is preserved under multiplicative maps that are injective.

See `UniqueMul.mulHom_map_iff` for a version with swapped bundling. -/
@[to_additive
      "`UniqueAdd` is preserved under additive maps that are injective.

See `UniqueAdd.addHom_map_iff` for a version with swapped bundling."]
theorem mulHom_image_iff [DecidableEq H] (f : G →ₙ* H) (hf : Function.Injective f) :
    UniqueMul (A.image f) (B.image f) (f a0) (f b0) ↔ UniqueMul A B a0 b0 := by
  simp_rw [UniqueMul, Finset.mem_image]
  refine ⟨fun h a b ha hb ab ↦ ?_, fun h _ _ ↦ ?_⟩
  · rw [← hf.eq_iff, map_mul, map_mul] at ab
    have := h ⟨a, ha, rfl⟩ ⟨b, hb, rfl⟩ ab
    exact ⟨hf this.1, hf this.2⟩
  · rintro ⟨a, aA, rfl⟩ ⟨b, bB, rfl⟩ ab
    

Proof state:
case refine_2.intro.intro.intro.intro
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A B : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
hf : Function.Injective ⇑f
h : ∀ ⦃a b : G⦄, a ∈ A → b ∈ B → a * b = a0 * b0 → a = a0 ∧ b = b0
a : G
aA : a ∈ A
b : G
bB : b ∈ B
ab : f a * f b = f a0 * f b0
⊢ f a = f a0 ∧ f b = f b0

Next tactic:
simp only [← map_mul, hf.eq_iff] at ab ⊢
/-- `Unique_Mul` is preserved under multiplicative maps that are injective.

See `UniqueMul.mulHom_map_iff` for a version with swapped bundling. -/
@[to_additive
      "`UniqueAdd` is preserved under additive maps that are injective.

See `UniqueAdd.addHom_map_iff` for a version with swapped bundling."]
theorem mulHom_image_iff [DecidableEq H] (f : G →ₙ* H) (hf : Function.Injective f) :
    UniqueMul (A.image f) (B.image f) (f a0) (f b0) ↔ UniqueMul A B a0 b0 := by
  simp_rw [UniqueMul, Finset.mem_image]
  refine ⟨fun h a b ha hb ab ↦ ?_, fun h _ _ ↦ ?_⟩
  · rw [← hf.eq_iff, map_mul, map_mul] at ab
    have := h ⟨a, ha, rfl⟩ ⟨b, hb, rfl⟩ ab
    exact ⟨hf this.1, hf this.2⟩
  · rintro ⟨a, aA, rfl⟩ ⟨b, bB, rfl⟩ ab
    simp only [← map_mul, hf.eq_iff] at ab ⊢
    

Proof state:
case refine_2.intro.intro.intro.intro
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A B : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
hf : Function.Injective ⇑f
h : ∀ ⦃a b : G⦄, a ∈ A → b ∈ B → a * b = a0 * b0 → a = a0 ∧ b = b0
a : G
aA : a ∈ A
b : G
bB : b ∈ B
ab : a * b = a0 * b0
⊢ a = a0 ∧ b = b0

Next tactic:
exact h aA bB ab
/-- `UniqueMul` is preserved under embeddings that are multiplicative.

See `UniqueMul.mulHom_image_iff` for a version with swapped bundling. -/
@[to_additive
      "`UniqueAdd` is preserved under embeddings that are additive.

See `UniqueAdd.addHom_image_iff` for a version with swapped bundling."]
theorem mulHom_map_iff (f : G ↪ H) (mul : ∀ x y, f (x * y) = f x * f y) :
    UniqueMul (A.map f) (B.map f) (f a0) (f b0) ↔ UniqueMul A B a0 b0 := by
  

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : Mul G
inst✝ : Mul H
A B : Finset G
a0 b0 : G
f : G ↪ H
mul : ∀ (x y : G), f (x * y) = f x * f y
⊢ UniqueMul (Finset.map f A) (Finset.map f B) (f a0) (f b0) ↔ UniqueMul A B a0 b0

Next tactic:
classical simp_rw [← mulHom_image_iff ⟨f, mul⟩ f.2, Finset.map_eq_image]; rfl
/-- `UniqueMul` is preserved under embeddings that are multiplicative.

See `UniqueMul.mulHom_image_iff` for a version with swapped bundling. -/
@[to_additive
      "`UniqueAdd` is preserved under embeddings that are additive.

See `UniqueAdd.addHom_image_iff` for a version with swapped bundling."]
theorem mulHom_map_iff (f : G ↪ H) (mul : ∀ x y, f (x * y) = f x * f y) :
    UniqueMul (A.map f) (B.map f) (f a0) (f b0) ↔ UniqueMul A B a0 b0 := by
  classical 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : Mul G
inst✝ : Mul H
A B : Finset G
a0 b0 : G
f : G ↪ H
mul : ∀ (x y : G), f (x * y) = f x * f y
⊢ UniqueMul (Finset.map f A) (Finset.map f B) (f a0) (f b0) ↔ UniqueMul A B a0 b0

Next tactic:
simp_rw [← mulHom_image_iff ⟨f, mul⟩ f.2, Finset.map_eq_image]
/-- `UniqueMul` is preserved under embeddings that are multiplicative.

See `UniqueMul.mulHom_image_iff` for a version with swapped bundling. -/
@[to_additive
      "`UniqueAdd` is preserved under embeddings that are additive.

See `UniqueAdd.addHom_image_iff` for a version with swapped bundling."]
theorem mulHom_map_iff (f : G ↪ H) (mul : ∀ x y, f (x * y) = f x * f y) :
    UniqueMul (A.map f) (B.map f) (f a0) (f b0) ↔ UniqueMul A B a0 b0 := by
  classical simp_rw [← mulHom_image_iff ⟨f, mul⟩ f.2, Finset.map_eq_image]; 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : Mul G
inst✝ : Mul H
A B : Finset G
a0 b0 : G
f : G ↪ H
mul : ∀ (x y : G), f (x * y) = f x * f y
⊢ UniqueMul (Finset.image (⇑f) A) (Finset.image (⇑f) B) (f a0) (f b0) ↔
    UniqueMul (Finset.image (⇑{ toFun := ⇑f, map_mul' := mul }) A) (Finset.image (⇑{ toFun := ⇑f, map_mul' := mul }) B)
      ({ toFun := ⇑f, map_mul' := mul } a0) ({ toFun := ⇑f, map_mul' := mul } b0)

Next tactic:
rfl
@[to_additive]
theorem of_mulOpposite
    (h : UniqueMul (B.map ⟨_, op_injective⟩) (A.map ⟨_, op_injective⟩) (op b0) (op a0)) :
    UniqueMul A B a0 b0 := fun a b aA bB ab ↦ by
  

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : Mul G
inst✝ : Mul H
A B : Finset G
a0 b0 : G
h :
  UniqueMul (map { toFun := op, inj' := (_ : Function.Injective op) } B)
    (map { toFun := op, inj' := (_ : Function.Injective op) } A) (op b0) (op a0)
a b : G
aA : a ∈ A
bB : b ∈ B
ab : a * b = a0 * b0
⊢ a = a0 ∧ b = b0

Next tactic:
simpa [and_comm] using h (mem_map_of_mem _ bB) (mem_map_of_mem _ aA) (congr_arg op ab)
@[to_additive]
theorem to_mulOpposite (h : UniqueMul A B a0 b0) :
    UniqueMul (B.map ⟨_, op_injective⟩) (A.map ⟨_, op_injective⟩) (op b0) (op a0) :=
  of_mulOpposite (by 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : Mul G
inst✝ : Mul H
A B : Finset G
a0 b0 : G
h : UniqueMul A B a0 b0
⊢ UniqueMul
    (map { toFun := op, inj' := (_ : Function.Injective op) }
      (map { toFun := op, inj' := (_ : Function.Injective op) } A))
    (map { toFun := op, inj' := (_ : Function.Injective op) }
      (map { toFun := op, inj' := (_ : Function.Injective op) } B))
    (op (op a0)) (op (op b0))

Next tactic:
simp_rw [map_map]
@[to_additive]
theorem to_mulOpposite (h : UniqueMul A B a0 b0) :
    UniqueMul (B.map ⟨_, op_injective⟩) (A.map ⟨_, op_injective⟩) (op b0) (op a0) :=
  of_mulOpposite (by simp_rw [map_map]; 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : Mul G
inst✝ : Mul H
A B : Finset G
a0 b0 : G
h : UniqueMul A B a0 b0
⊢ UniqueMul
    (map
      (Function.Embedding.trans { toFun := op, inj' := (_ : Function.Injective op) }
        { toFun := op, inj' := (_ : Function.Injective op) })
      A)
    (map
      (Function.Embedding.trans { toFun := op, inj' := (_ : Function.Injective op) }
        { toFun := op, inj' := (_ : Function.Injective op) })
      B)
    (op (op a0)) (op (op b0))

Next tactic:
exact (mulHom_map_iff _ fun _ _ ↦ by rfl).mpr h
@[to_additive]
theorem to_mulOpposite (h : UniqueMul A B a0 b0) :
    UniqueMul (B.map ⟨_, op_injective⟩) (A.map ⟨_, op_injective⟩) (op b0) (op a0) :=
  of_mulOpposite (by simp_rw [map_map]; exact (mulHom_map_iff _ fun _ _ ↦ by 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : Mul G
inst✝ : Mul H
A B : Finset G
a0 b0 : G
h : UniqueMul A B a0 b0
x✝¹ x✝ : G
⊢ (Function.Embedding.trans { toFun := op, inj' := (_ : Function.Injective op) }
        { toFun := op, inj' := (_ : Function.Injective op) })
      (x✝¹ * x✝) =
    (Function.Embedding.trans { toFun := op, inj' := (_ : Function.Injective op) }
          { toFun := op, inj' := (_ : Function.Injective op) })
        x✝¹ *
      (Function.Embedding.trans { toFun := op, inj' := (_ : Function.Injective op) }
          { toFun := op, inj' := (_ : Function.Injective op) })
        x✝

Next tactic:
rfl
open Finset in
@[to_additive]
theorem of_image_filter [DecidableEq H]
    (f : G →ₙ* H) {A B : Finset G} {aG bG : G} {aH bH : H} (hae : f aG = aH) (hbe : f bG = bH)
    (huH : UniqueMul (A.image f) (B.image f) aH bH)
    (huG : UniqueMul (A.filter (f · = aH)) (B.filter (f · = bH)) aG bG) :
    UniqueMul A B aG bG := fun a b ha hb he ↦ by
  

Proof state:
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A✝ B✝ : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
A B : Finset G
aG bG : G
aH bH : H
hae : f aG = aH
hbe : f bG = bH
huH : UniqueMul (image (⇑f) A) (image (⇑f) B) aH bH
huG : UniqueMul (filter (fun x => f x = aH) A) (filter (fun x => f x = bH) B) aG bG
a b : G
ha : a ∈ A
hb : b ∈ B
he : a * b = aG * bG
⊢ a = aG ∧ b = bG

Next tactic:
specialize huH (mem_image_of_mem _ ha) (mem_image_of_mem _ hb)
open Finset in
@[to_additive]
theorem of_image_filter [DecidableEq H]
    (f : G →ₙ* H) {A B : Finset G} {aG bG : G} {aH bH : H} (hae : f aG = aH) (hbe : f bG = bH)
    (huH : UniqueMul (A.image f) (B.image f) aH bH)
    (huG : UniqueMul (A.filter (f · = aH)) (B.filter (f · = bH)) aG bG) :
    UniqueMul A B aG bG := fun a b ha hb he ↦ by
  specialize huH (mem_image_of_mem _ ha) (mem_image_of_mem _ hb)
  

Proof state:
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A✝ B✝ : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
A B : Finset G
aG bG : G
aH bH : H
hae : f aG = aH
hbe : f bG = bH
huG : UniqueMul (filter (fun x => f x = aH) A) (filter (fun x => f x = bH) B) aG bG
a b : G
ha : a ∈ A
hb : b ∈ B
he : a * b = aG * bG
huH : f a * f b = aH * bH → f a = aH ∧ f b = bH
⊢ a = aG ∧ b = bG

Next tactic:
rw [← map_mul, he, map_mul, hae, hbe] at huH
open Finset in
@[to_additive]
theorem of_image_filter [DecidableEq H]
    (f : G →ₙ* H) {A B : Finset G} {aG bG : G} {aH bH : H} (hae : f aG = aH) (hbe : f bG = bH)
    (huH : UniqueMul (A.image f) (B.image f) aH bH)
    (huG : UniqueMul (A.filter (f · = aH)) (B.filter (f · = bH)) aG bG) :
    UniqueMul A B aG bG := fun a b ha hb he ↦ by
  specialize huH (mem_image_of_mem _ ha) (mem_image_of_mem _ hb)
  rw [← map_mul, he, map_mul, hae, hbe] at huH
  

Proof state:
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A✝ B✝ : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
A B : Finset G
aG bG : G
aH bH : H
hae : f aG = aH
hbe : f bG = bH
huG : UniqueMul (filter (fun x => f x = aH) A) (filter (fun x => f x = bH) B) aG bG
a b : G
ha : a ∈ A
hb : b ∈ B
he : a * b = aG * bG
huH : aH * bH = aH * bH → f a = aH ∧ f b = bH
⊢ a = aG ∧ b = bG

Next tactic:
refine huG ?_ ?_ he
open Finset in
@[to_additive]
theorem of_image_filter [DecidableEq H]
    (f : G →ₙ* H) {A B : Finset G} {aG bG : G} {aH bH : H} (hae : f aG = aH) (hbe : f bG = bH)
    (huH : UniqueMul (A.image f) (B.image f) aH bH)
    (huG : UniqueMul (A.filter (f · = aH)) (B.filter (f · = bH)) aG bG) :
    UniqueMul A B aG bG := fun a b ha hb he ↦ by
  specialize huH (mem_image_of_mem _ ha) (mem_image_of_mem _ hb)
  rw [← map_mul, he, map_mul, hae, hbe] at huH
  refine huG ?_ ?_ he <;> 

Proof state:
case refine_1
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A✝ B✝ : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
A B : Finset G
aG bG : G
aH bH : H
hae : f aG = aH
hbe : f bG = bH
huG : UniqueMul (filter (fun x => f x = aH) A) (filter (fun x => f x = bH) B) aG bG
a b : G
ha : a ∈ A
hb : b ∈ B
he : a * b = aG * bG
huH : aH * bH = aH * bH → f a = aH ∧ f b = bH
⊢ a ∈ filter (fun x => f x = aH) A

Next tactic:
rw [mem_filter]
open Finset in
@[to_additive]
theorem of_image_filter [DecidableEq H]
    (f : G →ₙ* H) {A B : Finset G} {aG bG : G} {aH bH : H} (hae : f aG = aH) (hbe : f bG = bH)
    (huH : UniqueMul (A.image f) (B.image f) aH bH)
    (huG : UniqueMul (A.filter (f · = aH)) (B.filter (f · = bH)) aG bG) :
    UniqueMul A B aG bG := fun a b ha hb he ↦ by
  specialize huH (mem_image_of_mem _ ha) (mem_image_of_mem _ hb)
  rw [← map_mul, he, map_mul, hae, hbe] at huH
  refine huG ?_ ?_ he <;> 

Proof state:
case refine_2
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A✝ B✝ : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
A B : Finset G
aG bG : G
aH bH : H
hae : f aG = aH
hbe : f bG = bH
huG : UniqueMul (filter (fun x => f x = aH) A) (filter (fun x => f x = bH) B) aG bG
a b : G
ha : a ∈ A
hb : b ∈ B
he : a * b = aG * bG
huH : aH * bH = aH * bH → f a = aH ∧ f b = bH
⊢ b ∈ filter (fun x => f x = bH) B

Next tactic:
rw [mem_filter]
open Finset in
@[to_additive]
theorem of_image_filter [DecidableEq H]
    (f : G →ₙ* H) {A B : Finset G} {aG bG : G} {aH bH : H} (hae : f aG = aH) (hbe : f bG = bH)
    (huH : UniqueMul (A.image f) (B.image f) aH bH)
    (huG : UniqueMul (A.filter (f · = aH)) (B.filter (f · = bH)) aG bG) :
    UniqueMul A B aG bG := fun a b ha hb he ↦ by
  specialize huH (mem_image_of_mem _ ha) (mem_image_of_mem _ hb)
  rw [← map_mul, he, map_mul, hae, hbe] at huH
  refine huG ?_ ?_ he <;> rw [mem_filter]
  

Proof state:
case refine_1
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A✝ B✝ : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
A B : Finset G
aG bG : G
aH bH : H
hae : f aG = aH
hbe : f bG = bH
huG : UniqueMul (filter (fun x => f x = aH) A) (filter (fun x => f x = bH) B) aG bG
a b : G
ha : a ∈ A
hb : b ∈ B
he : a * b = aG * bG
huH : aH * bH = aH * bH → f a = aH ∧ f b = bH
⊢ a ∈ A ∧ f a = aH
case refine_2
G : Type u_1
H : Type u_2
inst✝² : Mul G
inst✝¹ : Mul H
A✝ B✝ : Finset G
a0 b0 : G
inst✝ : DecidableEq H
f : G →ₙ* H
A B : Finset G
aG bG : G
aH bH : H
hae : f aG = aH
hbe : f bG = bH
huG : UniqueMul (filter (fun x => f x = aH) A) (filter (fun x => f x = bH) B) aG bG
a b : G
ha : a ∈ A
hb : b ∈ B
he : a * b = aG * bG
huH : aH * bH = aH * bH → f a = aH ∧ f b = bH
⊢ b ∈ B ∧ f b = bH

Next tactic:
exacts [⟨ha, (huH rfl).1⟩, ⟨hb, (huH rfl).2⟩]
@[to_additive]
lemma uniqueMul_of_twoUniqueMul {G} [Mul G] {A B : Finset G} (h : 1 < A.card * B.card →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2)
    (hA : A.Nonempty) (hB : B.Nonempty) : ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b := by
  

Proof state:
G : Type u_1
inst✝ : Mul G
A B : Finset G
h :
  1 < Finset.card A * Finset.card B →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2
hA : Finset.Nonempty A
hB : Finset.Nonempty B
⊢ ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b

Next tactic:
by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
@[to_additive]
lemma uniqueMul_of_twoUniqueMul {G} [Mul G] {A B : Finset G} (h : 1 < A.card * B.card →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2)
    (hA : A.Nonempty) (hB : B.Nonempty) : ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b := by
  by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
  · 

Proof state:
case pos
G : Type u_1
inst✝ : Mul G
A B : Finset G
h :
  1 < Finset.card A * Finset.card B →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2
hA : Finset.Nonempty A
hB : Finset.Nonempty B
hc : Finset.card A ≤ 1 ∧ Finset.card B ≤ 1
⊢ ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b

Next tactic:
exact UniqueMul.of_card_le_one hA hB hc.1 hc.2
@[to_additive]
lemma uniqueMul_of_twoUniqueMul {G} [Mul G] {A B : Finset G} (h : 1 < A.card * B.card →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2)
    (hA : A.Nonempty) (hB : B.Nonempty) : ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b := by
  by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
  · exact UniqueMul.of_card_le_one hA hB hc.1 hc.2
  

Proof state:
case neg
G : Type u_1
inst✝ : Mul G
A B : Finset G
h :
  1 < Finset.card A * Finset.card B →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2
hA : Finset.Nonempty A
hB : Finset.Nonempty B
hc : ¬(Finset.card A ≤ 1 ∧ Finset.card B ≤ 1)
⊢ ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b

Next tactic:
simp_rw [not_and_or, not_le] at hc
@[to_additive]
lemma uniqueMul_of_twoUniqueMul {G} [Mul G] {A B : Finset G} (h : 1 < A.card * B.card →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2)
    (hA : A.Nonempty) (hB : B.Nonempty) : ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b := by
  by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
  · exact UniqueMul.of_card_le_one hA hB hc.1 hc.2
  simp_rw [not_and_or, not_le] at hc
  

Proof state:
case neg
G : Type u_1
inst✝ : Mul G
A B : Finset G
h :
  1 < Finset.card A * Finset.card B →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2
hA : Finset.Nonempty A
hB : Finset.Nonempty B
hc : 1 < Finset.card A ∨ 1 < Finset.card B
⊢ ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b

Next tactic:
rw [← Finset.card_pos] at hA hB
@[to_additive]
lemma uniqueMul_of_twoUniqueMul {G} [Mul G] {A B : Finset G} (h : 1 < A.card * B.card →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2)
    (hA : A.Nonempty) (hB : B.Nonempty) : ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b := by
  by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
  · exact UniqueMul.of_card_le_one hA hB hc.1 hc.2
  simp_rw [not_and_or, not_le] at hc
  rw [← Finset.card_pos] at hA hB
  

Proof state:
case neg
G : Type u_1
inst✝ : Mul G
A B : Finset G
h :
  1 < Finset.card A * Finset.card B →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2
hA : 0 < Finset.card A
hB : 0 < Finset.card B
hc : 1 < Finset.card A ∨ 1 < Finset.card B
⊢ ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b

Next tactic:
obtain ⟨p, hp, _, _, _, hu, _⟩ := h (Nat.one_lt_mul_iff.mpr ⟨hA, hB, hc⟩)
@[to_additive]
lemma uniqueMul_of_twoUniqueMul {G} [Mul G] {A B : Finset G} (h : 1 < A.card * B.card →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2)
    (hA : A.Nonempty) (hB : B.Nonempty) : ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b := by
  by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
  · exact UniqueMul.of_card_le_one hA hB hc.1 hc.2
  simp_rw [not_and_or, not_le] at hc
  rw [← Finset.card_pos] at hA hB
  obtain ⟨p, hp, _, _, _, hu, _⟩ := h (Nat.one_lt_mul_iff.mpr ⟨hA, hB, hc⟩)
  

Proof state:
case neg.intro.intro.intro.intro.intro.intro
G : Type u_1
inst✝ : Mul G
A B : Finset G
h :
  1 < Finset.card A * Finset.card B →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2
hA : 0 < Finset.card A
hB : 0 < Finset.card B
hc : 1 < Finset.card A ∨ 1 < Finset.card B
p : G × G
hp : p ∈ A ×ˢ B
w✝ : G × G
left✝¹ : w✝ ∈ A ×ˢ B
left✝ : p ≠ w✝
hu : UniqueMul A B p.1 p.2
right✝ : UniqueMul A B w✝.1 w✝.2
⊢ ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b

Next tactic:
rw [Finset.mem_product] at hp
@[to_additive]
lemma uniqueMul_of_twoUniqueMul {G} [Mul G] {A B : Finset G} (h : 1 < A.card * B.card →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2)
    (hA : A.Nonempty) (hB : B.Nonempty) : ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b := by
  by_cases hc : A.card ≤ 1 ∧ B.card ≤ 1
  · exact UniqueMul.of_card_le_one hA hB hc.1 hc.2
  simp_rw [not_and_or, not_le] at hc
  rw [← Finset.card_pos] at hA hB
  obtain ⟨p, hp, _, _, _, hu, _⟩ := h (Nat.one_lt_mul_iff.mpr ⟨hA, hB, hc⟩)
  rw [Finset.mem_product] at hp
  

Proof state:
case neg.intro.intro.intro.intro.intro.intro
G : Type u_1
inst✝ : Mul G
A B : Finset G
h :
  1 < Finset.card A * Finset.card B →
    ∃ p1 ∈ A ×ˢ B, ∃ p2 ∈ A ×ˢ B, p1 ≠ p2 ∧ UniqueMul A B p1.1 p1.2 ∧ UniqueMul A B p2.1 p2.2
hA : 0 < Finset.card A
hB : 0 < Finset.card B
hc : 1 < Finset.card A ∨ 1 < Finset.card B
p : G × G
hp : p.1 ∈ A ∧ p.2 ∈ B
w✝ : G × G
left✝¹ : w✝ ∈ A ×ˢ B
left✝ : p ≠ w✝
hu : UniqueMul A B p.1 p.2
right✝ : UniqueMul A B w✝.1 w✝.2
⊢ ∃ a ∈ A, ∃ b ∈ B, UniqueMul A B a b

Next tactic:
exact ⟨p.1, hp.1, p.2, hp.2, hu⟩
@[to_additive] private def Prod.upMulHom : G × H →ₙ* ∀ b, I G H b :=
  ⟨fun x ↦ Bool.rec ⟨x.1⟩ ⟨x.2⟩, fun x y ↦ by 

Proof state:
G : Type u
H : Type v
inst✝¹ : Mul G
inst✝ : Mul H
x y : G × H
⊢ (fun x t => Bool.rec { down := x.1 } { down := x.2 } t) (x * y) =
    (fun x t => Bool.rec { down := x.1 } { down := x.2 } t) x *
      (fun x t => Bool.rec { down := x.1 } { down := x.2 } t) y

Next tactic:
ext (_|_)
@[to_additive] private def Prod.upMulHom : G × H →ₙ* ∀ b, I G H b :=
  ⟨fun x ↦ Bool.rec ⟨x.1⟩ ⟨x.2⟩, fun x y ↦ by ext (_|_) <;> 

Proof state:
case h.false.h
G : Type u
H : Type v
inst✝¹ : Mul G
inst✝ : Mul H
x y : G × H
⊢ ((fun x t => Bool.rec { down := x.1 } { down := x.2 } t) (x * y) false).down =
    (((fun x t => Bool.rec { down := x.1 } { down := x.2 } t) x *
          (fun x t => Bool.rec { down := x.1 } { down := x.2 } t) y)
        false).down

Next tactic:
rfl