l3lab/ntp-mathlib huggingface dataset:
@[simp] theorem right_mem_perpBisector : p₂ ∈ perpBisector p₁ p₂ ↔ p₁ = p₂ := by
  

Proof state:
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c c₁ c₂ p₁ p₂ : P
⊢ p₂ ∈ perpBisector p₁ p₂ ↔ p₁ = p₂

Next tactic:
simpa [mem_perpBisector_iff_inner_eq_inner] using eq_comm
@[simp] theorem left_mem_perpBisector : p₁ ∈ perpBisector p₁ p₂ ↔ p₁ = p₂ := by
  

Proof state:
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c c₁ c₂ p₁ p₂ : P
⊢ p₁ ∈ perpBisector p₁ p₂ ↔ p₁ = p₂

Next tactic:
rw [perpBisector_comm, right_mem_perpBisector, eq_comm]
@[simp] theorem perpBisector_self (p : P) : perpBisector p p = ⊤ :=
  top_unique <| fun _ ↦ by 

Proof state:
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c c₁ c₂ p₁ p₂ p x✝ : P
⊢ x✝ ∈ ↑⊤ → x✝ ∈ ↑(perpBisector p p)

Next tactic:
simp [mem_perpBisector_iff_inner_eq_inner]
@[simp] theorem perpBisector_eq_top : perpBisector p₁ p₂ = ⊤ ↔ p₁ = p₂ := by
  

Proof state:
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c c₁ c₂ p₁ p₂ : P
⊢ perpBisector p₁ p₂ = ⊤ ↔ p₁ = p₂

Next tactic:
refine ⟨fun h ↦ ?_, fun h ↦ h ▸ perpBisector_self _⟩
@[simp] theorem perpBisector_eq_top : perpBisector p₁ p₂ = ⊤ ↔ p₁ = p₂ := by
  refine ⟨fun h ↦ ?_, fun h ↦ h ▸ perpBisector_self _⟩
  

Proof state:
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c c₁ c₂ p₁ p₂ : P
h : perpBisector p₁ p₂ = ⊤
⊢ p₁ = p₂

Next tactic:
rw [← left_mem_perpBisector, h]
@[simp] theorem perpBisector_eq_top : perpBisector p₁ p₂ = ⊤ ↔ p₁ = p₂ := by
  refine ⟨fun h ↦ ?_, fun h ↦ h ▸ perpBisector_self _⟩
  rw [← left_mem_perpBisector, h]
  

Proof state:
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c c₁ c₂ p₁ p₂ : P
h : perpBisector p₁ p₂ = ⊤
⊢ p₁ ∈ ⊤

Next tactic:
trivial
@[simp] theorem perpBisector_ne_bot : perpBisector p₁ p₂ ≠ ⊥ := by
  

Proof state:
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c c₁ c₂ p₁ p₂ : P
⊢ perpBisector p₁ p₂ ≠ ⊥

Next tactic:
rw [← nonempty_iff_ne_bot]
@[simp] theorem perpBisector_ne_bot : perpBisector p₁ p₂ ≠ ⊥ := by
  rw [← nonempty_iff_ne_bot]; 

Proof state:
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c c₁ c₂ p₁ p₂ : P
⊢ Set.Nonempty ↑(perpBisector p₁ p₂)

Next tactic:
exact perpBisector_nonempty
/-- Suppose that `c₁` is equidistant from `p₁` and `p₂`, and the same applies to `c₂`. Then the
vector between `c₁` and `c₂` is orthogonal to that between `p₁` and `p₂`. (In two dimensions, this
says that the diagonals of a kite are orthogonal.) -/
theorem inner_vsub_vsub_of_dist_eq_of_dist_eq {c₁ c₂ p₁ p₂ : P} (hc₁ : dist p₁ c₁ = dist p₂ c₁)
    (hc₂ : dist p₁ c₂ = dist p₂ c₂) : ⟪c₂ -ᵥ c₁, p₂ -ᵥ p₁⟫ = 0 := by
  

Proof state:
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c₁ c₂ p₁ p₂ : P
hc₁ : dist p₁ c₁ = dist p₂ c₁
hc₂ : dist p₁ c₂ = dist p₂ c₂
⊢ inner (c₂ -ᵥ c₁) (p₂ -ᵥ p₁) = 0

Next tactic:
rw [← Submodule.mem_orthogonal_singleton_iff_inner_left, ← direction_perpBisector]
/-- Suppose that `c₁` is equidistant from `p₁` and `p₂`, and the same applies to `c₂`. Then the
vector between `c₁` and `c₂` is orthogonal to that between `p₁` and `p₂`. (In two dimensions, this
says that the diagonals of a kite are orthogonal.) -/
theorem inner_vsub_vsub_of_dist_eq_of_dist_eq {c₁ c₂ p₁ p₂ : P} (hc₁ : dist p₁ c₁ = dist p₂ c₁)
    (hc₂ : dist p₁ c₂ = dist p₂ c₂) : ⟪c₂ -ᵥ c₁, p₂ -ᵥ p₁⟫ = 0 := by
  rw [← Submodule.mem_orthogonal_singleton_iff_inner_left, ← direction_perpBisector]
  

Proof state:
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c₁ c₂ p₁ p₂ : P
hc₁ : dist p₁ c₁ = dist p₂ c₁
hc₂ : dist p₁ c₂ = dist p₂ c₂
⊢ c₂ -ᵥ c₁ ∈ direction (perpBisector p₁ p₂)

Next tactic:
apply vsub_mem_direction
/-- Suppose that `c₁` is equidistant from `p₁` and `p₂`, and the same applies to `c₂`. Then the
vector between `c₁` and `c₂` is orthogonal to that between `p₁` and `p₂`. (In two dimensions, this
says that the diagonals of a kite are orthogonal.) -/
theorem inner_vsub_vsub_of_dist_eq_of_dist_eq {c₁ c₂ p₁ p₂ : P} (hc₁ : dist p₁ c₁ = dist p₂ c₁)
    (hc₂ : dist p₁ c₂ = dist p₂ c₂) : ⟪c₂ -ᵥ c₁, p₂ -ᵥ p₁⟫ = 0 := by
  rw [← Submodule.mem_orthogonal_singleton_iff_inner_left, ← direction_perpBisector]
  apply vsub_mem_direction <;> 

Proof state:
case hp1
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c₁ c₂ p₁ p₂ : P
hc₁ : dist p₁ c₁ = dist p₂ c₁
hc₂ : dist p₁ c₂ = dist p₂ c₂
⊢ c₂ ∈ perpBisector p₁ p₂

Next tactic:
rwa [mem_perpBisector_iff_dist_eq']
/-- Suppose that `c₁` is equidistant from `p₁` and `p₂`, and the same applies to `c₂`. Then the
vector between `c₁` and `c₂` is orthogonal to that between `p₁` and `p₂`. (In two dimensions, this
says that the diagonals of a kite are orthogonal.) -/
theorem inner_vsub_vsub_of_dist_eq_of_dist_eq {c₁ c₂ p₁ p₂ : P} (hc₁ : dist p₁ c₁ = dist p₂ c₁)
    (hc₂ : dist p₁ c₂ = dist p₂ c₂) : ⟪c₂ -ᵥ c₁, p₂ -ᵥ p₁⟫ = 0 := by
  rw [← Submodule.mem_orthogonal_singleton_iff_inner_left, ← direction_perpBisector]
  apply vsub_mem_direction <;> 

Proof state:
case hp2
V : Type u_2
P : Type u_1
inst✝³ : NormedAddCommGroup V
inst✝² : InnerProductSpace ℝ V
inst✝¹ : MetricSpace P
inst✝ : NormedAddTorsor V P
c₁ c₂ p₁ p₂ : P
hc₁ : dist p₁ c₁ = dist p₂ c₁
hc₂ : dist p₁ c₂ = dist p₂ c₂
⊢ c₁ ∈ perpBisector p₁ p₂

Next tactic:
rwa [mem_perpBisector_iff_dist_eq']
theorem Isometry.preimage_perpBisector {f : P → P'} (h : Isometry f) (p₁ p₂ : P) :
    f ⁻¹' (perpBisector (f p₁) (f p₂)) = perpBisector p₁ p₂ := by
  

Proof state:
V : Type u_4
P : Type u_1
V' : Type u_3
P' : Type u_2
inst✝⁷ : NormedAddCommGroup V
inst✝⁶ : InnerProductSpace ℝ V
inst✝⁵ : MetricSpace P
inst✝⁴ : NormedAddTorsor V P
inst✝³ : NormedAddCommGroup V'
inst✝² : InnerProductSpace ℝ V'
inst✝¹ : MetricSpace P'
inst✝ : NormedAddTorsor V' P'
f : P → P'
h : Isometry f
p₁ p₂ : P
⊢ f ⁻¹' ↑(perpBisector (f p₁) (f p₂)) = ↑(perpBisector p₁ p₂)

Next tactic:
ext x
theorem Isometry.preimage_perpBisector {f : P → P'} (h : Isometry f) (p₁ p₂ : P) :
    f ⁻¹' (perpBisector (f p₁) (f p₂)) = perpBisector p₁ p₂ := by
  ext x; 

Proof state:
case h
V : Type u_4
P : Type u_1
V' : Type u_3
P' : Type u_2
inst✝⁷ : NormedAddCommGroup V
inst✝⁶ : InnerProductSpace ℝ V
inst✝⁵ : MetricSpace P
inst✝⁴ : NormedAddTorsor V P
inst✝³ : NormedAddCommGroup V'
inst✝² : InnerProductSpace ℝ V'
inst✝¹ : MetricSpace P'
inst✝ : NormedAddTorsor V' P'
f : P → P'
h : Isometry f
p₁ p₂ x : P
⊢ x ∈ f ⁻¹' ↑(perpBisector (f p₁) (f p₂)) ↔ x ∈ ↑(perpBisector p₁ p₂)

Next tactic:
simp [mem_perpBisector_iff_dist_eq, h.dist_eq]
/-- If `f i` has a faithful scalar action for a given `i`, then so does `Π i, f i`. This is
not an instance as `i` cannot be inferred. -/
@[to_additive
  "If `f i` has a faithful additive action for a given `i`, then
  so does `Π i, f i`. This is not an instance as `i` cannot be inferred"]
theorem faithfulSMul_at {α : Type*} [∀ i, SMul α <| f i] [∀ i, Nonempty (f i)] (i : I)
    [FaithfulSMul α (f i)] : FaithfulSMul α (∀ i, f i) :=
  ⟨fun h =>
    eq_of_smul_eq_smul fun a : f i => by
      

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i✝ : I
α : Type u_1
inst✝² : (i : I) → SMul α (f i)
inst✝¹ : ∀ (i : I), Nonempty (f i)
i : I
inst✝ : FaithfulSMul α (f i)
m₁✝ m₂✝ : α
h : ∀ (a : (i : I) → f i), m₁✝ • a = m₂✝ • a
a : f i
⊢ m₁✝ • a = m₂✝ • a

Next tactic:
classical
        have :=
          congr_fun (h <| Function.update (fun j => Classical.choice (‹∀ i, Nonempty (f i)› j)) i a)
            i
        simpa using this
/-- If `f i` has a faithful scalar action for a given `i`, then so does `Π i, f i`. This is
not an instance as `i` cannot be inferred. -/
@[to_additive
  "If `f i` has a faithful additive action for a given `i`, then
  so does `Π i, f i`. This is not an instance as `i` cannot be inferred"]
theorem faithfulSMul_at {α : Type*} [∀ i, SMul α <| f i] [∀ i, Nonempty (f i)] (i : I)
    [FaithfulSMul α (f i)] : FaithfulSMul α (∀ i, f i) :=
  ⟨fun h =>
    eq_of_smul_eq_smul fun a : f i => by
      classical
        

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i✝ : I
α : Type u_1
inst✝² : (i : I) → SMul α (f i)
inst✝¹ : ∀ (i : I), Nonempty (f i)
i : I
inst✝ : FaithfulSMul α (f i)
m₁✝ m₂✝ : α
h : ∀ (a : (i : I) → f i), m₁✝ • a = m₂✝ • a
a : f i
⊢ m₁✝ • a = m₂✝ • a

Next tactic:
have :=
          congr_fun (h <| Function.update (fun j => Classical.choice (‹∀ i, Nonempty (f i)› j)) i a)
            i
/-- If `f i` has a faithful scalar action for a given `i`, then so does `Π i, f i`. This is
not an instance as `i` cannot be inferred. -/
@[to_additive
  "If `f i` has a faithful additive action for a given `i`, then
  so does `Π i, f i`. This is not an instance as `i` cannot be inferred"]
theorem faithfulSMul_at {α : Type*} [∀ i, SMul α <| f i] [∀ i, Nonempty (f i)] (i : I)
    [FaithfulSMul α (f i)] : FaithfulSMul α (∀ i, f i) :=
  ⟨fun h =>
    eq_of_smul_eq_smul fun a : f i => by
      classical
        have :=
          congr_fun (h <| Function.update (fun j => Classical.choice (‹∀ i, Nonempty (f i)› j)) i a)
            i
        

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i✝ : I
α : Type u_1
inst✝² : (i : I) → SMul α (f i)
inst✝¹ : ∀ (i : I), Nonempty (f i)
i : I
inst✝ : FaithfulSMul α (f i)
m₁✝ m₂✝ : α
h : ∀ (a : (i : I) → f i), m₁✝ • a = m₂✝ • a
a : f i
this :
  (m₁✝ • Function.update (fun j => Classical.choice (_ : Nonempty (f j))) i a) i =
    (m₂✝ • Function.update (fun j => Classical.choice (_ : Nonempty (f j))) i a) i
⊢ m₁✝ • a = m₂✝ • a

Next tactic:
simpa using this
instance smulZeroClass' {g : I → Type*} {n : ∀ i, Zero <| g i} [∀ i, SMulZeroClass (f i) (g i)] :
  @SMulZeroClass (∀ i, f i) (∀ i : I, g i) (@Pi.instZero I g n) where
  smul_zero := by 

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i : I
g : I → Type u_1
n : (i : I) → Zero (g i)
inst✝ : (i : I) → SMulZeroClass (f i) (g i)
⊢ ∀ (a : (i : I) → f i), a • 0 = 0

Next tactic:
intros
instance smulZeroClass' {g : I → Type*} {n : ∀ i, Zero <| g i} [∀ i, SMulZeroClass (f i) (g i)] :
  @SMulZeroClass (∀ i, f i) (∀ i : I, g i) (@Pi.instZero I g n) where
  smul_zero := by intros; 

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i : I
g : I → Type u_1
n : (i : I) → Zero (g i)
inst✝ : (i : I) → SMulZeroClass (f i) (g i)
a✝ : (i : I) → f i
⊢ a✝ • 0 = 0

Next tactic:
ext x
instance smulZeroClass' {g : I → Type*} {n : ∀ i, Zero <| g i} [∀ i, SMulZeroClass (f i) (g i)] :
  @SMulZeroClass (∀ i, f i) (∀ i : I, g i) (@Pi.instZero I g n) where
  smul_zero := by intros; ext x; 

Proof state:
case h
I : Type u
f : I → Type v
x✝ y : (i : I) → f i
i : I
g : I → Type u_1
n : (i : I) → Zero (g i)
inst✝ : (i : I) → SMulZeroClass (f i) (g i)
a✝ : (i : I) → f i
x : I
⊢ (a✝ • 0) x = OfNat.ofNat 0 x

Next tactic:
exact smul_zero _
instance distribSMul' {g : I → Type*} {n : ∀ i, AddZeroClass <| g i}
  [∀ i, DistribSMul (f i) (g i)] :
  @DistribSMul (∀ i, f i) (∀ i : I, g i) (@Pi.addZeroClass I g n) where
  smul_zero := by 

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i : I
g : I → Type u_1
n : (i : I) → AddZeroClass (g i)
inst✝ : (i : I) → DistribSMul (f i) (g i)
⊢ ∀ (a : (i : I) → f i), a • 0 = 0

Next tactic:
intros
instance distribSMul' {g : I → Type*} {n : ∀ i, AddZeroClass <| g i}
  [∀ i, DistribSMul (f i) (g i)] :
  @DistribSMul (∀ i, f i) (∀ i : I, g i) (@Pi.addZeroClass I g n) where
  smul_zero := by intros; 

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i : I
g : I → Type u_1
n : (i : I) → AddZeroClass (g i)
inst✝ : (i : I) → DistribSMul (f i) (g i)
a✝ : (i : I) → f i
⊢ a✝ • 0 = 0

Next tactic:
ext x
instance distribSMul' {g : I → Type*} {n : ∀ i, AddZeroClass <| g i}
  [∀ i, DistribSMul (f i) (g i)] :
  @DistribSMul (∀ i, f i) (∀ i : I, g i) (@Pi.addZeroClass I g n) where
  smul_zero := by intros; ext x; 

Proof state:
case h
I : Type u
f : I → Type v
x✝ y : (i : I) → f i
i : I
g : I → Type u_1
n : (i : I) → AddZeroClass (g i)
inst✝ : (i : I) → DistribSMul (f i) (g i)
a✝ : (i : I) → f i
x : I
⊢ (a✝ • 0) x = OfNat.ofNat 0 x

Next tactic:
exact smul_zero _
instance distribSMul' {g : I → Type*} {n : ∀ i, AddZeroClass <| g i}
  [∀ i, DistribSMul (f i) (g i)] :
  @DistribSMul (∀ i, f i) (∀ i : I, g i) (@Pi.addZeroClass I g n) where
  smul_zero := by intros; ext x; exact smul_zero _
  smul_add := by 

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i : I
g : I → Type u_1
n : (i : I) → AddZeroClass (g i)
inst✝ : (i : I) → DistribSMul (f i) (g i)
⊢ ∀ (a : (i : I) → f i) (x y : (i : I) → g i), a • (x + y) = a • x + a • y

Next tactic:
intros
instance distribSMul' {g : I → Type*} {n : ∀ i, AddZeroClass <| g i}
  [∀ i, DistribSMul (f i) (g i)] :
  @DistribSMul (∀ i, f i) (∀ i : I, g i) (@Pi.addZeroClass I g n) where
  smul_zero := by intros; ext x; exact smul_zero _
  smul_add := by intros; 

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i : I
g : I → Type u_1
n : (i : I) → AddZeroClass (g i)
inst✝ : (i : I) → DistribSMul (f i) (g i)
a✝ : (i : I) → f i
x✝ y✝ : (i : I) → g i
⊢ a✝ • (x✝ + y✝) = a✝ • x✝ + a✝ • y✝

Next tactic:
ext x
instance distribSMul' {g : I → Type*} {n : ∀ i, AddZeroClass <| g i}
  [∀ i, DistribSMul (f i) (g i)] :
  @DistribSMul (∀ i, f i) (∀ i : I, g i) (@Pi.addZeroClass I g n) where
  smul_zero := by intros; ext x; exact smul_zero _
  smul_add := by intros; ext x; 

Proof state:
case h
I : Type u
f : I → Type v
x✝¹ y : (i : I) → f i
i : I
g : I → Type u_1
n : (i : I) → AddZeroClass (g i)
inst✝ : (i : I) → DistribSMul (f i) (g i)
a✝ : (i : I) → f i
x✝ y✝ : (i : I) → g i
x : I
⊢ (a✝ • (x✝ + y✝)) x = (a✝ • x✝ + a✝ • y✝) x

Next tactic:
exact smul_add _ _ _
instance mulDistribMulAction' {g : I → Type*} {m : ∀ i, Monoid (f i)} {n : ∀ i, Monoid <| g i}
    [∀ i, MulDistribMulAction (f i) (g i)] :
    @MulDistribMulAction (∀ i, f i) (∀ i : I, g i) (@Pi.monoid I f m) (@Pi.monoid I g n) where
  smul_mul := by
    

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i : I
g : I → Type u_1
m : (i : I) → Monoid (f i)
n : (i : I) → Monoid (g i)
inst✝ : (i : I) → MulDistribMulAction (f i) (g i)
⊢ ∀ (r : (i : I) → f i) (x y : (i : I) → g i), r • (x * y) = r • x * r • y

Next tactic:
intros
instance mulDistribMulAction' {g : I → Type*} {m : ∀ i, Monoid (f i)} {n : ∀ i, Monoid <| g i}
    [∀ i, MulDistribMulAction (f i) (g i)] :
    @MulDistribMulAction (∀ i, f i) (∀ i : I, g i) (@Pi.monoid I f m) (@Pi.monoid I g n) where
  smul_mul := by
    intros
    

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i : I
g : I → Type u_1
m : (i : I) → Monoid (f i)
n : (i : I) → Monoid (g i)
inst✝ : (i : I) → MulDistribMulAction (f i) (g i)
r✝ : (i : I) → f i
x✝ y✝ : (i : I) → g i
⊢ r✝ • (x✝ * y✝) = r✝ • x✝ * r✝ • y✝

Next tactic:
ext x
instance mulDistribMulAction' {g : I → Type*} {m : ∀ i, Monoid (f i)} {n : ∀ i, Monoid <| g i}
    [∀ i, MulDistribMulAction (f i) (g i)] :
    @MulDistribMulAction (∀ i, f i) (∀ i : I, g i) (@Pi.monoid I f m) (@Pi.monoid I g n) where
  smul_mul := by
    intros
    ext x
    

Proof state:
case h
I : Type u
f : I → Type v
x✝¹ y : (i : I) → f i
i : I
g : I → Type u_1
m : (i : I) → Monoid (f i)
n : (i : I) → Monoid (g i)
inst✝ : (i : I) → MulDistribMulAction (f i) (g i)
r✝ : (i : I) → f i
x✝ y✝ : (i : I) → g i
x : I
⊢ (r✝ • (x✝ * y✝)) x = (r✝ • x✝ * r✝ • y✝) x

Next tactic:
apply smul_mul'
instance mulDistribMulAction' {g : I → Type*} {m : ∀ i, Monoid (f i)} {n : ∀ i, Monoid <| g i}
    [∀ i, MulDistribMulAction (f i) (g i)] :
    @MulDistribMulAction (∀ i, f i) (∀ i : I, g i) (@Pi.monoid I f m) (@Pi.monoid I g n) where
  smul_mul := by
    intros
    ext x
    apply smul_mul'
  smul_one := by
    

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i : I
g : I → Type u_1
m : (i : I) → Monoid (f i)
n : (i : I) → Monoid (g i)
inst✝ : (i : I) → MulDistribMulAction (f i) (g i)
⊢ ∀ (r : (i : I) → f i), r • 1 = 1

Next tactic:
intros
instance mulDistribMulAction' {g : I → Type*} {m : ∀ i, Monoid (f i)} {n : ∀ i, Monoid <| g i}
    [∀ i, MulDistribMulAction (f i) (g i)] :
    @MulDistribMulAction (∀ i, f i) (∀ i : I, g i) (@Pi.monoid I f m) (@Pi.monoid I g n) where
  smul_mul := by
    intros
    ext x
    apply smul_mul'
  smul_one := by
    intros
    

Proof state:
I : Type u
f : I → Type v
x y : (i : I) → f i
i : I
g : I → Type u_1
m : (i : I) → Monoid (f i)
n : (i : I) → Monoid (g i)
inst✝ : (i : I) → MulDistribMulAction (f i) (g i)
r✝ : (i : I) → f i
⊢ r✝ • 1 = 1

Next tactic:
ext x
instance mulDistribMulAction' {g : I → Type*} {m : ∀ i, Monoid (f i)} {n : ∀ i, Monoid <| g i}
    [∀ i, MulDistribMulAction (f i) (g i)] :
    @MulDistribMulAction (∀ i, f i) (∀ i : I, g i) (@Pi.monoid I f m) (@Pi.monoid I g n) where
  smul_mul := by
    intros
    ext x
    apply smul_mul'
  smul_one := by
    intros
    ext x
    

Proof state:
case h
I : Type u
f : I → Type v
x✝ y : (i : I) → f i
i : I
g : I → Type u_1
m : (i : I) → Monoid (f i)
n : (i : I) → Monoid (g i)
inst✝ : (i : I) → MulDistribMulAction (f i) (g i)
r✝ : (i : I) → f i
x : I
⊢ (r✝ • 1) x = OfNat.ofNat 1 x

Next tactic:
apply smul_one
@[to_additive]
theorem Function.extend_smul {R α β γ : Type*} [SMul R γ] (r : R) (f : α → β) (g : α → γ)
    (e : β → γ) : Function.extend f (r • g) (r • e) = r • Function.extend f g e :=
  funext fun x => by
  -- Porting note: Lean4 is unable to automatically call `Classical.propDecidable`
  

Proof state:
I : Type u
f✝ : I → Type v
x✝ y : (i : I) → f✝ i
i : I
R : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : SMul R γ
r : R
f : α → β
g : α → γ
e : β → γ
x : β
⊢ extend f (r • g) (r • e) x = (r • extend f g e) x

Next tactic:
haveI : Decidable (∃ a : α, f a = x) := Classical.propDecidable _
@[to_additive]
theorem Function.extend_smul {R α β γ : Type*} [SMul R γ] (r : R) (f : α → β) (g : α → γ)
    (e : β → γ) : Function.extend f (r • g) (r • e) = r • Function.extend f g e :=
  funext fun x => by
  -- Porting note: Lean4 is unable to automatically call `Classical.propDecidable`
  haveI : Decidable (∃ a : α, f a = x) := Classical.propDecidable _
  

Proof state:
I : Type u
f✝ : I → Type v
x✝ y : (i : I) → f✝ i
i : I
R : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : SMul R γ
r : R
f : α → β
g : α → γ
e : β → γ
x : β
this : Decidable (∃ a, f a = x)
⊢ extend f (r • g) (r • e) x = (r • extend f g e) x

Next tactic:
rw [extend_def, Pi.smul_apply, Pi.smul_apply, extend_def]
@[to_additive]
theorem Function.extend_smul {R α β γ : Type*} [SMul R γ] (r : R) (f : α → β) (g : α → γ)
    (e : β → γ) : Function.extend f (r • g) (r • e) = r • Function.extend f g e :=
  funext fun x => by
  -- Porting note: Lean4 is unable to automatically call `Classical.propDecidable`
  haveI : Decidable (∃ a : α, f a = x) := Classical.propDecidable _
  rw [extend_def, Pi.smul_apply, Pi.smul_apply, extend_def]
  

Proof state:
I : Type u
f✝ : I → Type v
x✝ y : (i : I) → f✝ i
i : I
R : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : SMul R γ
r : R
f : α → β
g : α → γ
e : β → γ
x : β
this : Decidable (∃ a, f a = x)
⊢ (if h : ∃ a, f a = x then (r • g) (Classical.choose h) else r • e x) =
    r • if h : ∃ a, f a = x then g (Classical.choose h) else e x

Next tactic:
split_ifs
@[to_additive]
theorem Function.extend_smul {R α β γ : Type*} [SMul R γ] (r : R) (f : α → β) (g : α → γ)
    (e : β → γ) : Function.extend f (r • g) (r • e) = r • Function.extend f g e :=
  funext fun x => by
  -- Porting note: Lean4 is unable to automatically call `Classical.propDecidable`
  haveI : Decidable (∃ a : α, f a = x) := Classical.propDecidable _
  rw [extend_def, Pi.smul_apply, Pi.smul_apply, extend_def]
  split_ifs <;>
  

Proof state:
case pos
I : Type u
f✝ : I → Type v
x✝ y : (i : I) → f✝ i
i : I
R : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : SMul R γ
r : R
f : α → β
g : α → γ
e : β → γ
x : β
this : Decidable (∃ a, f a = x)
h✝ : ∃ a, f a = x
⊢ (r • g) (Classical.choose h✝) = r • g (Classical.choose h✝)

Next tactic:
rfl
@[to_additive]
theorem Function.extend_smul {R α β γ : Type*} [SMul R γ] (r : R) (f : α → β) (g : α → γ)
    (e : β → γ) : Function.extend f (r • g) (r • e) = r • Function.extend f g e :=
  funext fun x => by
  -- Porting note: Lean4 is unable to automatically call `Classical.propDecidable`
  haveI : Decidable (∃ a : α, f a = x) := Classical.propDecidable _
  rw [extend_def, Pi.smul_apply, Pi.smul_apply, extend_def]
  split_ifs <;>
  

Proof state:
case neg
I : Type u
f✝ : I → Type v
x✝ y : (i : I) → f✝ i
i : I
R : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝ : SMul R γ
r : R
f : α → β
g : α → γ
e : β → γ
x : β
this : Decidable (∃ a, f a = x)
h✝ : ¬∃ a, f a = x
⊢ r • e x = r • e x

Next tactic:
rfl
@[simp 1100]
theorem op_mem_op {s : Set α} {a : α} : op a ∈ s.op ↔ a ∈ s := by 

Proof state:
α : Type u_1
s : Set α
a : α
⊢ op a ∈ Set.op s ↔ a ∈ s

Next tactic:
rfl
@[simp 1100]
theorem unop_mem_unop {s : Set αᵒᵖ} {a : αᵒᵖ} : unop a ∈ s.unop ↔ a ∈ s := by 

Proof state:
α : Type u_1
s : Set αᵒᵖ
a : αᵒᵖ
⊢ a.unop ∈ Set.unop s ↔ a ∈ s

Next tactic:
rfl
@[simp]
theorem singleton_op (x : α) : ({x} : Set α).op = {op x} := by
  

Proof state:
α : Type u_1
x : α
⊢ Set.op {x} = {op x}

Next tactic:
ext
@[simp]
theorem singleton_op (x : α) : ({x} : Set α).op = {op x} := by
  ext
  

Proof state:
case h
α : Type u_1
x : α
x✝ : αᵒᵖ
⊢ x✝ ∈ Set.op {x} ↔ x✝ ∈ {op x}

Next tactic:
constructor
@[simp]
theorem singleton_op (x : α) : ({x} : Set α).op = {op x} := by
  ext
  constructor
  · 

Proof state:
case h.mp
α : Type u_1
x : α
x✝ : αᵒᵖ
⊢ x✝ ∈ Set.op {x} → x✝ ∈ {op x}

Next tactic:
apply unop_injective
@[simp]
theorem singleton_op (x : α) : ({x} : Set α).op = {op x} := by
  ext
  constructor
  · apply unop_injective
  · 

Proof state:
case h.mpr
α : Type u_1
x : α
x✝ : αᵒᵖ
⊢ x✝ ∈ {op x} → x✝ ∈ Set.op {x}

Next tactic:
apply op_injective
@[simp]
theorem singleton_unop (x : αᵒᵖ) : ({x} : Set αᵒᵖ).unop = {unop x} := by
  

Proof state:
α : Type u_1
x : αᵒᵖ
⊢ Set.unop {x} = {x.unop}

Next tactic:
ext
@[simp]
theorem singleton_unop (x : αᵒᵖ) : ({x} : Set αᵒᵖ).unop = {unop x} := by
  ext
  

Proof state:
case h
α : Type u_1
x : αᵒᵖ
x✝ : α
⊢ x✝ ∈ Set.unop {x} ↔ x✝ ∈ {x.unop}

Next tactic:
constructor
@[simp]
theorem singleton_unop (x : αᵒᵖ) : ({x} : Set αᵒᵖ).unop = {unop x} := by
  ext
  constructor
  · 

Proof state:
case h.mp
α : Type u_1
x : αᵒᵖ
x✝ : α
⊢ x✝ ∈ Set.unop {x} → x✝ ∈ {x.unop}

Next tactic:
apply op_injective
@[simp]
theorem singleton_unop (x : αᵒᵖ) : ({x} : Set αᵒᵖ).unop = {unop x} := by
  ext
  constructor
  · apply op_injective
  · 

Proof state:
case h.mpr
α : Type u_1
x : αᵒᵖ
x✝ : α
⊢ x✝ ∈ {x.unop} → x✝ ∈ Set.unop {x}

Next tactic:
apply unop_injective
@[simp 1100]
theorem singleton_op_unop (x : α) : ({op x} : Set αᵒᵖ).unop = {x} := by
  

Proof state:
α : Type u_1
x : α
⊢ Set.unop {op x} = {x}

Next tactic:
ext
@[simp 1100]
theorem singleton_op_unop (x : α) : ({op x} : Set αᵒᵖ).unop = {x} := by
  ext
  

Proof state:
case h
α : Type u_1
x x✝ : α
⊢ x✝ ∈ Set.unop {op x} ↔ x✝ ∈ {x}

Next tactic:
constructor
@[simp 1100]
theorem singleton_op_unop (x : α) : ({op x} : Set αᵒᵖ).unop = {x} := by
  ext
  constructor
  · 

Proof state:
case h.mp
α : Type u_1
x x✝ : α
⊢ x✝ ∈ Set.unop {op x} → x✝ ∈ {x}

Next tactic:
apply op_injective
@[simp 1100]
theorem singleton_op_unop (x : α) : ({op x} : Set αᵒᵖ).unop = {x} := by
  ext
  constructor
  · apply op_injective
  · 

Proof state:
case h.mpr
α : Type u_1
x x✝ : α
⊢ x✝ ∈ {x} → x✝ ∈ Set.unop {op x}

Next tactic:
apply unop_injective
@[simp 1100]
theorem singleton_unop_op (x : αᵒᵖ) : ({unop x} : Set α).op = {x} := by
  

Proof state:
α : Type u_1
x : αᵒᵖ
⊢ Set.op {x.unop} = {x}

Next tactic:
ext