l3lab/ntp-mathlib huggingface dataset:
theorem Ideal.minimalPrimes_eq_subsingleton (hI : I.IsPrimary) : I.minimalPrimes = {I.radical} := by
  ext J
  constructor
  · 

Proof state:
case h.mp
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J✝ : Ideal R
hI : IsPrimary I
J : Ideal R
⊢ J ∈ Ideal.minimalPrimes I → J ∈ {radical I}

Next tactic:
exact fun H =>
      let e := H.1.1.radical_le_iff.mpr H.1.2
      (H.2 ⟨Ideal.isPrime_radical hI, Ideal.le_radical⟩ e).antisymm e
theorem Ideal.minimalPrimes_eq_subsingleton (hI : I.IsPrimary) : I.minimalPrimes = {I.radical} := by
  ext J
  constructor
  · exact fun H =>
      let e := H.1.1.radical_le_iff.mpr H.1.2
      (H.2 ⟨Ideal.isPrime_radical hI, Ideal.le_radical⟩ e).antisymm e
  · 

Proof state:
case h.mpr
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J✝ : Ideal R
hI : IsPrimary I
J : Ideal R
⊢ J ∈ {radical I} → J ∈ Ideal.minimalPrimes I

Next tactic:
rintro (rfl : J = I.radical)
theorem Ideal.minimalPrimes_eq_subsingleton (hI : I.IsPrimary) : I.minimalPrimes = {I.radical} := by
  ext J
  constructor
  · exact fun H =>
      let e := H.1.1.radical_le_iff.mpr H.1.2
      (H.2 ⟨Ideal.isPrime_radical hI, Ideal.le_radical⟩ e).antisymm e
  · rintro (rfl : J = I.radical)
    

Proof state:
case h.mpr
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J : Ideal R
hI : IsPrimary I
⊢ radical I ∈ Ideal.minimalPrimes I

Next tactic:
exact ⟨⟨Ideal.isPrime_radical hI, Ideal.le_radical⟩, fun _ H _ => H.1.radical_le_iff.mpr H.2⟩
theorem Ideal.minimalPrimes_eq_subsingleton_self [I.IsPrime] : I.minimalPrimes = {I} := by
  

Proof state:
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime I
⊢ Ideal.minimalPrimes I = {I}

Next tactic:
ext J
theorem Ideal.minimalPrimes_eq_subsingleton_self [I.IsPrime] : I.minimalPrimes = {I} := by
  ext J
  

Proof state:
case h
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J✝ : Ideal R
inst✝ : IsPrime I
J : Ideal R
⊢ J ∈ Ideal.minimalPrimes I ↔ J ∈ {I}

Next tactic:
constructor
theorem Ideal.minimalPrimes_eq_subsingleton_self [I.IsPrime] : I.minimalPrimes = {I} := by
  ext J
  constructor
  · 

Proof state:
case h.mp
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J✝ : Ideal R
inst✝ : IsPrime I
J : Ideal R
⊢ J ∈ Ideal.minimalPrimes I → J ∈ {I}

Next tactic:
exact fun H => (H.2 ⟨inferInstance, rfl.le⟩ H.1.2).antisymm H.1.2
theorem Ideal.minimalPrimes_eq_subsingleton_self [I.IsPrime] : I.minimalPrimes = {I} := by
  ext J
  constructor
  · exact fun H => (H.2 ⟨inferInstance, rfl.le⟩ H.1.2).antisymm H.1.2
  · 

Proof state:
case h.mpr
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J✝ : Ideal R
inst✝ : IsPrime I
J : Ideal R
⊢ J ∈ {I} → J ∈ Ideal.minimalPrimes I

Next tactic:
rintro (rfl : J = I)
theorem Ideal.minimalPrimes_eq_subsingleton_self [I.IsPrime] : I.minimalPrimes = {I} := by
  ext J
  constructor
  · exact fun H => (H.2 ⟨inferInstance, rfl.le⟩ H.1.2).antisymm H.1.2
  · rintro (rfl : J = I)
    

Proof state:
case h.mpr
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
J✝ J : Ideal R
inst✝ : IsPrime J
⊢ J ∈ Ideal.minimalPrimes J

Next tactic:
refine' ⟨⟨inferInstance, rfl.le⟩, fun _ h _ => h.2⟩
@[to_additive]
theorem map_mul_map_eq_map_mul_map [FreimanHomClass F A β 2] (f : F) (ha : a ∈ A) (hb : b ∈ A)
    (hc : c ∈ A) (hd : d ∈ A) (h : a * b = c * d) : f a * f b = f c * f d := by
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁶ : FunLike F α fun x => β
inst✝⁵ : CommMonoid α
inst✝⁴ : CommMonoid β
inst✝³ : CommMonoid γ
inst✝² : CommMonoid δ
inst✝¹ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
inst✝ : FreimanHomClass F A β 2
f : F
ha : a ∈ A
hb : b ∈ A
hc : c ∈ A
hd : d ∈ A
h : a * b = c * d
⊢ f a * f b = f c * f d

Next tactic:
simp_rw [← prod_pair] at h ⊢
@[to_additive]
theorem map_mul_map_eq_map_mul_map [FreimanHomClass F A β 2] (f : F) (ha : a ∈ A) (hb : b ∈ A)
    (hc : c ∈ A) (hd : d ∈ A) (h : a * b = c * d) : f a * f b = f c * f d := by
  simp_rw [← prod_pair] at h ⊢
  

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁶ : FunLike F α fun x => β
inst✝⁵ : CommMonoid α
inst✝⁴ : CommMonoid β
inst✝³ : CommMonoid γ
inst✝² : CommMonoid δ
inst✝¹ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
inst✝ : FreimanHomClass F A β 2
f : F
ha : a ∈ A
hb : b ∈ A
hc : c ∈ A
hd : d ∈ A
h : prod {a, b} = prod {c, d}
⊢ prod {f a, f b} = prod {f c, f d}

Next tactic:
refine' map_prod_eq_map_prod f _ _ (card_pair _ _) (card_pair _ _) h
@[to_additive]
theorem map_mul_map_eq_map_mul_map [FreimanHomClass F A β 2] (f : F) (ha : a ∈ A) (hb : b ∈ A)
    (hc : c ∈ A) (hd : d ∈ A) (h : a * b = c * d) : f a * f b = f c * f d := by
  simp_rw [← prod_pair] at h ⊢
  refine' map_prod_eq_map_prod f _ _ (card_pair _ _) (card_pair _ _) h <;> 

Proof state:
case refine'_1
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁶ : FunLike F α fun x => β
inst✝⁵ : CommMonoid α
inst✝⁴ : CommMonoid β
inst✝³ : CommMonoid γ
inst✝² : CommMonoid δ
inst✝¹ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
inst✝ : FreimanHomClass F A β 2
f : F
ha : a ∈ A
hb : b ∈ A
hc : c ∈ A
hd : d ∈ A
h : prod {a, b} = prod {c, d}
⊢ ∀ ⦃x : α⦄, x ∈ {a, b} → x ∈ A

Next tactic:
simp [ha, hb, hc, hd]
@[to_additive]
theorem map_mul_map_eq_map_mul_map [FreimanHomClass F A β 2] (f : F) (ha : a ∈ A) (hb : b ∈ A)
    (hc : c ∈ A) (hd : d ∈ A) (h : a * b = c * d) : f a * f b = f c * f d := by
  simp_rw [← prod_pair] at h ⊢
  refine' map_prod_eq_map_prod f _ _ (card_pair _ _) (card_pair _ _) h <;> 

Proof state:
case refine'_2
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁶ : FunLike F α fun x => β
inst✝⁵ : CommMonoid α
inst✝⁴ : CommMonoid β
inst✝³ : CommMonoid γ
inst✝² : CommMonoid δ
inst✝¹ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
inst✝ : FreimanHomClass F A β 2
f : F
ha : a ∈ A
hb : b ∈ A
hc : c ∈ A
hd : d ∈ A
h : prod {a, b} = prod {c, d}
⊢ ∀ ⦃x : α⦄, x ∈ {c, d} → x ∈ A

Next tactic:
simp [ha, hb, hc, hd]
@[to_additive]
instance funLike : FunLike (A →*[n] β) α fun _ => β where
  coe := toFun
  coe_injective' f g h := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f g : A →*[n] β
h : f.toFun = g.toFun
⊢ f = g

Next tactic:
cases f
@[to_additive]
instance funLike : FunLike (A →*[n] β) α fun _ => β where
  coe := toFun
  coe_injective' f g h := by cases f; 

Proof state:
case mk
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
g : A →*[n] β
toFun✝ : α → β
map_prod_eq_map_prod'✝ :
  ∀ {s t : Multiset α},
    (∀ ⦃x : α⦄, x ∈ s → x ∈ A) →
      (∀ ⦃x : α⦄, x ∈ t → x ∈ A) → card s = n → card t = n → prod s = prod t → prod (map toFun✝ s) = prod (map toFun✝ t)
h : { toFun := toFun✝, map_prod_eq_map_prod' := map_prod_eq_map_prod'✝ }.toFun = g.toFun
⊢ { toFun := toFun✝, map_prod_eq_map_prod' := map_prod_eq_map_prod'✝ } = g

Next tactic:
cases g
@[to_additive]
instance funLike : FunLike (A →*[n] β) α fun _ => β where
  coe := toFun
  coe_injective' f g h := by cases f; cases g; 

Proof state:
case mk.mk
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
toFun✝¹ : α → β
map_prod_eq_map_prod'✝¹ :
  ∀ {s t : Multiset α},
    (∀ ⦃x : α⦄, x ∈ s → x ∈ A) →
      (∀ ⦃x : α⦄, x ∈ t → x ∈ A) →
        card s = n → card t = n → prod s = prod t → prod (map toFun✝¹ s) = prod (map toFun✝¹ t)
toFun✝ : α → β
map_prod_eq_map_prod'✝ :
  ∀ {s t : Multiset α},
    (∀ ⦃x : α⦄, x ∈ s → x ∈ A) →
      (∀ ⦃x : α⦄, x ∈ t → x ∈ A) → card s = n → card t = n → prod s = prod t → prod (map toFun✝ s) = prod (map toFun✝ t)
h :
  { toFun := toFun✝¹, map_prod_eq_map_prod' := map_prod_eq_map_prod'✝¹ }.toFun =
    { toFun := toFun✝, map_prod_eq_map_prod' := map_prod_eq_map_prod'✝ }.toFun
⊢ { toFun := toFun✝¹, map_prod_eq_map_prod' := map_prod_eq_map_prod'✝¹ } =
    { toFun := toFun✝, map_prod_eq_map_prod' := map_prod_eq_map_prod'✝ }

Next tactic:
congr
/-- The identity map from a commutative monoid to itself. -/
@[to_additive (attr := simps) "The identity map from an additive commutative monoid to itself."]
protected def id (A : Set α) (n : ℕ) : A →*[n] α where
  toFun x := x
  map_prod_eq_map_prod' _ _ _ _ h := by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A✝ : Set α
B : Set β
C : Set γ
n✝ : ℕ
a b c d : α
A : Set α
n : ℕ
s✝ t✝ : Multiset α
x✝³ : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
x✝² : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
x✝¹ : card s✝ = n
x✝ : card t✝ = n
h : prod s✝ = prod t✝
⊢ prod (map (fun x => x) s✝) = prod (map (fun x => x) t✝)

Next tactic:
rw [map_id', map_id', h]
/-- Composition of Freiman homomorphisms as a Freiman homomorphism. -/
@[to_additive "Composition of additive Freiman homomorphisms as an additive Freiman homomorphism."]
protected def comp (f : B →*[n] γ) (g : A →*[n] β) (hAB : A.MapsTo g B) : A →*[n] γ where
  toFun := f ∘ g
  map_prod_eq_map_prod' hsA htA hs ht h := by
    

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f : B →*[n] γ
g : A →*[n] β
hAB : Set.MapsTo (⇑g) A B
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ prod (map (⇑f ∘ ⇑g) s✝) = prod (map (⇑f ∘ ⇑g) t✝)

Next tactic:
rw [← map_map, ← map_map]
/-- Composition of Freiman homomorphisms as a Freiman homomorphism. -/
@[to_additive "Composition of additive Freiman homomorphisms as an additive Freiman homomorphism."]
protected def comp (f : B →*[n] γ) (g : A →*[n] β) (hAB : A.MapsTo g B) : A →*[n] γ where
  toFun := f ∘ g
  map_prod_eq_map_prod' hsA htA hs ht h := by
    rw [← map_map, ← map_map]
    

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f : B →*[n] γ
g : A →*[n] β
hAB : Set.MapsTo (⇑g) A B
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ prod (map (⇑f) (map (⇑g) s✝)) = prod (map (⇑f) (map (⇑g) t✝))

Next tactic:
apply map_prod_eq_map_prod f _ _ ((card_map _ _).trans hs)
/-- Composition of Freiman homomorphisms as a Freiman homomorphism. -/
@[to_additive "Composition of additive Freiman homomorphisms as an additive Freiman homomorphism."]
protected def comp (f : B →*[n] γ) (g : A →*[n] β) (hAB : A.MapsTo g B) : A →*[n] γ where
  toFun := f ∘ g
  map_prod_eq_map_prod' hsA htA hs ht h := by
    rw [← map_map, ← map_map]
    apply map_prod_eq_map_prod f _ _ ((card_map _ _).trans hs)
    · 

Proof state:
case ht
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f : B →*[n] γ
g : A →*[n] β
hAB : Set.MapsTo (⇑g) A B
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ card (map (⇑g) t✝) = n

Next tactic:
rwa [card_map]
/-- Composition of Freiman homomorphisms as a Freiman homomorphism. -/
@[to_additive "Composition of additive Freiman homomorphisms as an additive Freiman homomorphism."]
protected def comp (f : B →*[n] γ) (g : A →*[n] β) (hAB : A.MapsTo g B) : A →*[n] γ where
  toFun := f ∘ g
  map_prod_eq_map_prod' hsA htA hs ht h := by
    rw [← map_map, ← map_map]
    apply map_prod_eq_map_prod f _ _ ((card_map _ _).trans hs)
    · rwa [card_map]
    · 

Proof state:
case h
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f : B →*[n] γ
g : A →*[n] β
hAB : Set.MapsTo (⇑g) A B
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ prod (map (⇑g) s✝) = prod (map (⇑g) t✝)

Next tactic:
apply (map_prod_eq_map_prod g hsA htA hs ht h)
/-- Composition of Freiman homomorphisms as a Freiman homomorphism. -/
@[to_additive "Composition of additive Freiman homomorphisms as an additive Freiman homomorphism."]
protected def comp (f : B →*[n] γ) (g : A →*[n] β) (hAB : A.MapsTo g B) : A →*[n] γ where
  toFun := f ∘ g
  map_prod_eq_map_prod' hsA htA hs ht h := by
    rw [← map_map, ← map_map]
    apply map_prod_eq_map_prod f _ _ ((card_map _ _).trans hs)
    · rwa [card_map]
    · apply (map_prod_eq_map_prod g hsA htA hs ht h)
    · 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f : B →*[n] γ
g : A →*[n] β
hAB : Set.MapsTo (⇑g) A B
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ ∀ ⦃x : β⦄, x ∈ map (⇑g) s✝ → x ∈ B

Next tactic:
simpa using fun a h => hAB (hsA h)
/-- Composition of Freiman homomorphisms as a Freiman homomorphism. -/
@[to_additive "Composition of additive Freiman homomorphisms as an additive Freiman homomorphism."]
protected def comp (f : B →*[n] γ) (g : A →*[n] β) (hAB : A.MapsTo g B) : A →*[n] γ where
  toFun := f ∘ g
  map_prod_eq_map_prod' hsA htA hs ht h := by
    rw [← map_map, ← map_map]
    apply map_prod_eq_map_prod f _ _ ((card_map _ _).trans hs)
    · rwa [card_map]
    · apply (map_prod_eq_map_prod g hsA htA hs ht h)
    · simpa using fun a h => hAB (hsA h)
    · 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f : B →*[n] γ
g : A →*[n] β
hAB : Set.MapsTo (⇑g) A B
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ ∀ ⦃x : β⦄, x ∈ map (⇑g) t✝ → x ∈ B

Next tactic:
simpa using fun a h => hAB (htA h)
@[to_additive]
theorem cancel_right_on {g₁ g₂ : B →*[n] γ} {f : A →*[n] β} (hf : A.SurjOn f B) {hf'} :
    A.EqOn (g₁.comp f hf') (g₂.comp f hf') ↔ B.EqOn g₁ g₂ :=
  by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
g₁ g₂ : B →*[n] γ
f : A →*[n] β
hf : Set.SurjOn (⇑f) A B
hf' : Set.MapsTo (⇑f) A B
⊢ Set.EqOn (⇑(FreimanHom.comp g₁ f hf')) (⇑(FreimanHom.comp g₂ f hf')) A ↔ Set.EqOn (⇑g₁) (⇑g₂) B

Next tactic:
simp [hf.cancel_right hf']
@[to_additive]
theorem cancel_left_on {g : B →*[n] γ} {f₁ f₂ : A →*[n] β} (hg : B.InjOn g) {hf₁ hf₂} :
    A.EqOn (g.comp f₁ hf₁) (g.comp f₂ hf₂) ↔ A.EqOn f₁ f₂ :=
  by 

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
g : B →*[n] γ
f₁ f₂ : A →*[n] β
hg : Set.InjOn (⇑g) B
hf₁ : Set.MapsTo (⇑f₁) A B
hf₂ : Set.MapsTo (⇑f₂) A B
⊢ Set.EqOn (⇑(FreimanHom.comp g f₁ hf₁)) (⇑(FreimanHom.comp g f₂ hf₂)) A ↔ Set.EqOn (⇑f₁) (⇑f₂) A

Next tactic:
simp [hg.cancel_left hf₁ hf₂]
/-- `FreimanHom.const A n b` is the Freiman homomorphism sending everything to `b`. -/
@[to_additive "`AddFreimanHom.const An b` is the Freiman homomorphism sending everything to `b`."]
def const (A : Set α) (n : ℕ) (b : β) : A →*[n] β where
  toFun _ := b
  map_prod_eq_map_prod' _ _ hs ht _ := by
    

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A✝ : Set α
B : Set β
C : Set γ
n✝ : ℕ
a b✝ c d : α
A : Set α
n : ℕ
b : β
s✝ t✝ : Multiset α
x✝² : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
x✝¹ : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
x✝ : prod s✝ = prod t✝
⊢ prod (map (fun x => b) s✝) = prod (map (fun x => b) t✝)

Next tactic:
simp only [map_const', hs, prod_replicate, ht]
/-- `f * g` is the Freiman homomorphism sends `x` to `f x * g x`. -/
@[to_additive "`f + g` is the Freiman homomorphism sending `x` to `f x + g x`."]
instance : Mul (A →*[n] β) :=
  ⟨fun f g =>
    { toFun := fun x => f x * g x
      map_prod_eq_map_prod' := fun hsA htA hs ht h => by
          

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f g : A →*[n] β
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ prod (map (fun x => f x * g x) s✝) = prod (map (fun x => f x * g x) t✝)

Next tactic:
rw [prod_map_mul, prod_map_mul]
/-- `f * g` is the Freiman homomorphism sends `x` to `f x * g x`. -/
@[to_additive "`f + g` is the Freiman homomorphism sending `x` to `f x + g x`."]
instance : Mul (A →*[n] β) :=
  ⟨fun f g =>
    { toFun := fun x => f x * g x
      map_prod_eq_map_prod' := fun hsA htA hs ht h => by
          rw [prod_map_mul, prod_map_mul]
          

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f g : A →*[n] β
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ prod (map (fun x => f x) s✝) * prod (map (fun x => g x) s✝) =
    prod (map (fun x => f x) t✝) * prod (map (fun x => g x) t✝)

Next tactic:
rw [map_prod_eq_map_prod f hsA htA hs ht h]
/-- `f * g` is the Freiman homomorphism sends `x` to `f x * g x`. -/
@[to_additive "`f + g` is the Freiman homomorphism sending `x` to `f x + g x`."]
instance : Mul (A →*[n] β) :=
  ⟨fun f g =>
    { toFun := fun x => f x * g x
      map_prod_eq_map_prod' := fun hsA htA hs ht h => by
          rw [prod_map_mul, prod_map_mul]
          rw [map_prod_eq_map_prod f hsA htA hs ht h]
          

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f g : A →*[n] β
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ prod (map (⇑f) t✝) * prod (map (fun x => g x) s✝) = prod (map (fun x => f x) t✝) * prod (map (fun x => g x) t✝)

Next tactic:
rw [map_prod_eq_map_prod g hsA htA hs ht h]
/-- If `f` is a Freiman homomorphism to a commutative group, then `f⁻¹` is the Freiman homomorphism
sending `x` to `(f x)⁻¹`. -/
@[to_additive
      "If `f` is a Freiman homomorphism to an additive commutative group, then `-f` is the
      Freiman homomorphism sending `x` to `-f x`."]
instance : Inv (A →*[n] G) :=
  ⟨fun f =>
    { toFun := fun x => (f x)⁻¹
      map_prod_eq_map_prod' := fun hsA htA hs ht h => by
        

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f : A →*[n] G
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ prod (map (fun x => (f x)⁻¹) s✝) = prod (map (fun x => (f x)⁻¹) t✝)

Next tactic:
rw [prod_map_inv, prod_map_inv, map_prod_eq_map_prod f hsA htA hs ht h]
/-- If `f` and `g` are Freiman homomorphisms to a commutative group, then `f / g` is the Freiman
homomorphism sending `x` to `f x / g x`. -/
@[to_additive
      "If `f` and `g` are additive Freiman homomorphisms to an additive commutative group,
      then `f - g` is the additive Freiman homomorphism sending `x` to `f x - g x`"]
instance : Div (A →*[n] G) :=
  ⟨fun f g =>
    { toFun := fun x => f x / g x
      map_prod_eq_map_prod' := fun hsA htA hs ht h => by
        

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a b c d : α
f g : A →*[n] G
s✝ t✝ : Multiset α
hsA : ∀ ⦃x : α⦄, x ∈ s✝ → x ∈ A
htA : ∀ ⦃x : α⦄, x ∈ t✝ → x ∈ A
hs : card s✝ = n
ht : card t✝ = n
h : prod s✝ = prod t✝
⊢ prod (map (fun x => f x / g x) s✝) = prod (map (fun x => f x / g x) t✝)

Next tactic:
rw [prod_map_div, prod_map_div, map_prod_eq_map_prod f hsA htA hs ht h,
          map_prod_eq_map_prod g hsA htA hs ht h]
/-- `A →*[n] β` is a `CommMonoid`. -/
@[to_additive "`α →+[n] β` is an `AddCommMonoid`."]
instance commMonoid : CommMonoid (A →*[n] β) where
  mul_assoc a b c := by
    

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a✝ b✝ c✝ d : α
a b c : A →*[n] β
⊢ a * b * c = a * (b * c)

Next tactic:
ext
/-- `A →*[n] β` is a `CommMonoid`. -/
@[to_additive "`α →+[n] β` is an `AddCommMonoid`."]
instance commMonoid : CommMonoid (A →*[n] β) where
  mul_assoc a b c := by
    ext
    

Proof state:
case h
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a✝ b✝ c✝ d : α
a b c : A →*[n] β
x✝ : α
⊢ (a * b * c) x✝ = (a * (b * c)) x✝

Next tactic:
apply mul_assoc
/-- `A →*[n] β` is a `CommMonoid`. -/
@[to_additive "`α →+[n] β` is an `AddCommMonoid`."]
instance commMonoid : CommMonoid (A →*[n] β) where
  mul_assoc a b c := by
    ext
    apply mul_assoc
  one_mul a := by
    

Proof state:
F : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
δ : Type u_5
G : Type u_6
inst✝⁵ : FunLike F α fun x => β
inst✝⁴ : CommMonoid α
inst✝³ : CommMonoid β
inst✝² : CommMonoid γ
inst✝¹ : CommMonoid δ
inst✝ : CommGroup G
A : Set α
B : Set β
C : Set γ
n : ℕ
a✝ b c d : α
a : A →*[n] β
⊢ 1 * a = a

Next tactic:
ext