l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem length_ndinsert_of_not_mem {a : α} {s : Multiset α} (h : a ∉ s) :
    card (ndinsert a s) = card s + 1 := by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
h : a ∉ s
⊢ card (ndinsert a s) = card s + 1

Next tactic:
simp [h]
theorem dedup_cons {a : α} {s : Multiset α} : dedup (a ::ₘ s) = ndinsert a (dedup s) := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
⊢ dedup (a ::ₘ s) = ndinsert a (dedup s)

Next tactic:
by_cases h : a ∈ s
theorem dedup_cons {a : α} {s : Multiset α} : dedup (a ::ₘ s) = ndinsert a (dedup s) := by
  by_cases h : a ∈ s <;> 

Proof state:
case pos
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
h : a ∈ s
⊢ dedup (a ::ₘ s) = ndinsert a (dedup s)

Next tactic:
simp [h]
theorem dedup_cons {a : α} {s : Multiset α} : dedup (a ::ₘ s) = ndinsert a (dedup s) := by
  by_cases h : a ∈ s <;> 

Proof state:
case neg
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
h : a ∉ s
⊢ dedup (a ::ₘ s) = ndinsert a (dedup s)

Next tactic:
simp [h]
theorem ndinsert_le {a : α} {s t : Multiset α} : ndinsert a s ≤ t ↔ s ≤ t ∧ a ∈ t :=
  ⟨fun h => ⟨le_trans (le_ndinsert_self _ _) h, mem_of_le h (mem_ndinsert_self _ _)⟩, fun ⟨l, m⟩ =>
    if h : a ∈ s then by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s t : Multiset α
x✝ : s ≤ t ∧ a ∈ t
l : s ≤ t
m : a ∈ t
h : a ∈ s
⊢ ndinsert a s ≤ t

Next tactic:
simp [h, l]
theorem ndinsert_le {a : α} {s t : Multiset α} : ndinsert a s ≤ t ↔ s ≤ t ∧ a ∈ t :=
  ⟨fun h => ⟨le_trans (le_ndinsert_self _ _) h, mem_of_le h (mem_ndinsert_self _ _)⟩, fun ⟨l, m⟩ =>
    if h : a ∈ s then by simp [h, l]
    else by
      

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s t : Multiset α
x✝ : s ≤ t ∧ a ∈ t
l : s ≤ t
m : a ∈ t
h : a ∉ s
⊢ ndinsert a s ≤ t

Next tactic:
rw [ndinsert_of_not_mem h, ← cons_erase m, cons_le_cons_iff, ← le_cons_of_not_mem h,
          cons_erase m]
theorem ndinsert_le {a : α} {s t : Multiset α} : ndinsert a s ≤ t ↔ s ≤ t ∧ a ∈ t :=
  ⟨fun h => ⟨le_trans (le_ndinsert_self _ _) h, mem_of_le h (mem_ndinsert_self _ _)⟩, fun ⟨l, m⟩ =>
    if h : a ∈ s then by simp [h, l]
    else by
      rw [ndinsert_of_not_mem h, ← cons_erase m, cons_le_cons_iff, ← le_cons_of_not_mem h,
          cons_erase m];
        

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s t : Multiset α
x✝ : s ≤ t ∧ a ∈ t
l : s ≤ t
m : a ∈ t
h : a ∉ s
⊢ s ≤ t

Next tactic:
exact l
theorem attach_ndinsert (a : α) (s : Multiset α) :
    (s.ndinsert a).attach =
      ndinsert ⟨a, mem_ndinsert_self a s⟩ (s.attach.map fun p => ⟨p.1, mem_ndinsert_of_mem p.2⟩) :=
  have eq :
    ∀ h : ∀ p : { x // x ∈ s }, p.1 ∈ s,
      (fun p : { x // x ∈ s } => ⟨p.val, h p⟩ : { x // x ∈ s } → { x // x ∈ s }) = id :=
    fun h => funext fun p => Subtype.eq rfl
  have : ∀ (t) (eq : s.ndinsert a = t), t.attach = ndinsert ⟨a, eq ▸ mem_ndinsert_self a s⟩
      (s.attach.map fun p => ⟨p.1, eq ▸ mem_ndinsert_of_mem p.2⟩) := by
    

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
eq : ∀ (h : ∀ (p : { x // x ∈ s }), ↑p ∈ s), (fun p => { val := ↑p, property := (_ : ↑p ∈ s) }) = id
⊢ ∀ (t : Multiset α) (eq : ndinsert a s = t),
    attach t =
      ndinsert { val := a, property := (_ : a ∈ t) } (map (fun p => { val := ↑p, property := (_ : ↑p ∈ t) }) (attach s))

Next tactic:
intro t ht
theorem attach_ndinsert (a : α) (s : Multiset α) :
    (s.ndinsert a).attach =
      ndinsert ⟨a, mem_ndinsert_self a s⟩ (s.attach.map fun p => ⟨p.1, mem_ndinsert_of_mem p.2⟩) :=
  have eq :
    ∀ h : ∀ p : { x // x ∈ s }, p.1 ∈ s,
      (fun p : { x // x ∈ s } => ⟨p.val, h p⟩ : { x // x ∈ s } → { x // x ∈ s }) = id :=
    fun h => funext fun p => Subtype.eq rfl
  have : ∀ (t) (eq : s.ndinsert a = t), t.attach = ndinsert ⟨a, eq ▸ mem_ndinsert_self a s⟩
      (s.attach.map fun p => ⟨p.1, eq ▸ mem_ndinsert_of_mem p.2⟩) := by
    intro t ht
    

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
eq : ∀ (h : ∀ (p : { x // x ∈ s }), ↑p ∈ s), (fun p => { val := ↑p, property := (_ : ↑p ∈ s) }) = id
t : Multiset α
ht : ndinsert a s = t
⊢ attach t =
    ndinsert { val := a, property := (_ : a ∈ t) } (map (fun p => { val := ↑p, property := (_ : ↑p ∈ t) }) (attach s))

Next tactic:
by_cases h : a ∈ s
theorem attach_ndinsert (a : α) (s : Multiset α) :
    (s.ndinsert a).attach =
      ndinsert ⟨a, mem_ndinsert_self a s⟩ (s.attach.map fun p => ⟨p.1, mem_ndinsert_of_mem p.2⟩) :=
  have eq :
    ∀ h : ∀ p : { x // x ∈ s }, p.1 ∈ s,
      (fun p : { x // x ∈ s } => ⟨p.val, h p⟩ : { x // x ∈ s } → { x // x ∈ s }) = id :=
    fun h => funext fun p => Subtype.eq rfl
  have : ∀ (t) (eq : s.ndinsert a = t), t.attach = ndinsert ⟨a, eq ▸ mem_ndinsert_self a s⟩
      (s.attach.map fun p => ⟨p.1, eq ▸ mem_ndinsert_of_mem p.2⟩) := by
    intro t ht
    by_cases h : a ∈ s
    · 

Proof state:
case pos
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
eq : ∀ (h : ∀ (p : { x // x ∈ s }), ↑p ∈ s), (fun p => { val := ↑p, property := (_ : ↑p ∈ s) }) = id
t : Multiset α
ht : ndinsert a s = t
h : a ∈ s
⊢ attach t =
    ndinsert { val := a, property := (_ : a ∈ t) } (map (fun p => { val := ↑p, property := (_ : ↑p ∈ t) }) (attach s))

Next tactic:
rw [ndinsert_of_mem h] at ht
theorem attach_ndinsert (a : α) (s : Multiset α) :
    (s.ndinsert a).attach =
      ndinsert ⟨a, mem_ndinsert_self a s⟩ (s.attach.map fun p => ⟨p.1, mem_ndinsert_of_mem p.2⟩) :=
  have eq :
    ∀ h : ∀ p : { x // x ∈ s }, p.1 ∈ s,
      (fun p : { x // x ∈ s } => ⟨p.val, h p⟩ : { x // x ∈ s } → { x // x ∈ s }) = id :=
    fun h => funext fun p => Subtype.eq rfl
  have : ∀ (t) (eq : s.ndinsert a = t), t.attach = ndinsert ⟨a, eq ▸ mem_ndinsert_self a s⟩
      (s.attach.map fun p => ⟨p.1, eq ▸ mem_ndinsert_of_mem p.2⟩) := by
    intro t ht
    by_cases h : a ∈ s
    · rw [ndinsert_of_mem h] at ht
      

Proof state:
case pos
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
eq : ∀ (h : ∀ (p : { x // x ∈ s }), ↑p ∈ s), (fun p => { val := ↑p, property := (_ : ↑p ∈ s) }) = id
t : Multiset α
ht✝ : ndinsert a s = t
ht : s = t
h : a ∈ s
⊢ attach t =
    ndinsert { val := a, property := (_ : a ∈ t) } (map (fun p => { val := ↑p, property := (_ : ↑p ∈ t) }) (attach s))

Next tactic:
subst ht
theorem attach_ndinsert (a : α) (s : Multiset α) :
    (s.ndinsert a).attach =
      ndinsert ⟨a, mem_ndinsert_self a s⟩ (s.attach.map fun p => ⟨p.1, mem_ndinsert_of_mem p.2⟩) :=
  have eq :
    ∀ h : ∀ p : { x // x ∈ s }, p.1 ∈ s,
      (fun p : { x // x ∈ s } => ⟨p.val, h p⟩ : { x // x ∈ s } → { x // x ∈ s }) = id :=
    fun h => funext fun p => Subtype.eq rfl
  have : ∀ (t) (eq : s.ndinsert a = t), t.attach = ndinsert ⟨a, eq ▸ mem_ndinsert_self a s⟩
      (s.attach.map fun p => ⟨p.1, eq ▸ mem_ndinsert_of_mem p.2⟩) := by
    intro t ht
    by_cases h : a ∈ s
    · rw [ndinsert_of_mem h] at ht
      subst ht
      

Proof state:
case pos
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
eq : ∀ (h : ∀ (p : { x // x ∈ s }), ↑p ∈ s), (fun p => { val := ↑p, property := (_ : ↑p ∈ s) }) = id
h : a ∈ s
ht : ndinsert a s = s
⊢ attach s =
    ndinsert { val := a, property := (_ : a ∈ s) } (map (fun p => { val := ↑p, property := (_ : ↑p ∈ s) }) (attach s))

Next tactic:
rw [eq, map_id, ndinsert_of_mem (mem_attach _ _)]
theorem attach_ndinsert (a : α) (s : Multiset α) :
    (s.ndinsert a).attach =
      ndinsert ⟨a, mem_ndinsert_self a s⟩ (s.attach.map fun p => ⟨p.1, mem_ndinsert_of_mem p.2⟩) :=
  have eq :
    ∀ h : ∀ p : { x // x ∈ s }, p.1 ∈ s,
      (fun p : { x // x ∈ s } => ⟨p.val, h p⟩ : { x // x ∈ s } → { x // x ∈ s }) = id :=
    fun h => funext fun p => Subtype.eq rfl
  have : ∀ (t) (eq : s.ndinsert a = t), t.attach = ndinsert ⟨a, eq ▸ mem_ndinsert_self a s⟩
      (s.attach.map fun p => ⟨p.1, eq ▸ mem_ndinsert_of_mem p.2⟩) := by
    intro t ht
    by_cases h : a ∈ s
    · rw [ndinsert_of_mem h] at ht
      subst ht
      rw [eq, map_id, ndinsert_of_mem (mem_attach _ _)]
    · 

Proof state:
case neg
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
eq : ∀ (h : ∀ (p : { x // x ∈ s }), ↑p ∈ s), (fun p => { val := ↑p, property := (_ : ↑p ∈ s) }) = id
t : Multiset α
ht : ndinsert a s = t
h : a ∉ s
⊢ attach t =
    ndinsert { val := a, property := (_ : a ∈ t) } (map (fun p => { val := ↑p, property := (_ : ↑p ∈ t) }) (attach s))

Next tactic:
rw [ndinsert_of_not_mem h] at ht
theorem attach_ndinsert (a : α) (s : Multiset α) :
    (s.ndinsert a).attach =
      ndinsert ⟨a, mem_ndinsert_self a s⟩ (s.attach.map fun p => ⟨p.1, mem_ndinsert_of_mem p.2⟩) :=
  have eq :
    ∀ h : ∀ p : { x // x ∈ s }, p.1 ∈ s,
      (fun p : { x // x ∈ s } => ⟨p.val, h p⟩ : { x // x ∈ s } → { x // x ∈ s }) = id :=
    fun h => funext fun p => Subtype.eq rfl
  have : ∀ (t) (eq : s.ndinsert a = t), t.attach = ndinsert ⟨a, eq ▸ mem_ndinsert_self a s⟩
      (s.attach.map fun p => ⟨p.1, eq ▸ mem_ndinsert_of_mem p.2⟩) := by
    intro t ht
    by_cases h : a ∈ s
    · rw [ndinsert_of_mem h] at ht
      subst ht
      rw [eq, map_id, ndinsert_of_mem (mem_attach _ _)]
    · rw [ndinsert_of_not_mem h] at ht
      

Proof state:
case neg
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
eq : ∀ (h : ∀ (p : { x // x ∈ s }), ↑p ∈ s), (fun p => { val := ↑p, property := (_ : ↑p ∈ s) }) = id
t : Multiset α
ht✝ : ndinsert a s = t
ht : a ::ₘ s = t
h : a ∉ s
⊢ attach t =
    ndinsert { val := a, property := (_ : a ∈ t) } (map (fun p => { val := ↑p, property := (_ : ↑p ∈ t) }) (attach s))

Next tactic:
subst ht
theorem attach_ndinsert (a : α) (s : Multiset α) :
    (s.ndinsert a).attach =
      ndinsert ⟨a, mem_ndinsert_self a s⟩ (s.attach.map fun p => ⟨p.1, mem_ndinsert_of_mem p.2⟩) :=
  have eq :
    ∀ h : ∀ p : { x // x ∈ s }, p.1 ∈ s,
      (fun p : { x // x ∈ s } => ⟨p.val, h p⟩ : { x // x ∈ s } → { x // x ∈ s }) = id :=
    fun h => funext fun p => Subtype.eq rfl
  have : ∀ (t) (eq : s.ndinsert a = t), t.attach = ndinsert ⟨a, eq ▸ mem_ndinsert_self a s⟩
      (s.attach.map fun p => ⟨p.1, eq ▸ mem_ndinsert_of_mem p.2⟩) := by
    intro t ht
    by_cases h : a ∈ s
    · rw [ndinsert_of_mem h] at ht
      subst ht
      rw [eq, map_id, ndinsert_of_mem (mem_attach _ _)]
    · rw [ndinsert_of_not_mem h] at ht
      subst ht
      

Proof state:
case neg
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s : Multiset α
eq : ∀ (h : ∀ (p : { x // x ∈ s }), ↑p ∈ s), (fun p => { val := ↑p, property := (_ : ↑p ∈ s) }) = id
h : a ∉ s
ht : ndinsert a s = a ::ₘ s
⊢ attach (a ::ₘ s) =
    ndinsert { val := a, property := (_ : a ∈ a ::ₘ s) }
      (map (fun p => { val := ↑p, property := (_ : ↑p ∈ a ::ₘ s) }) (attach s))

Next tactic:
simp [attach_cons, h]
@[simp]
theorem disjoint_ndinsert_left {a : α} {s t : Multiset α} :
    Disjoint (ndinsert a s) t ↔ a ∉ t ∧ Disjoint s t :=
  Iff.trans (by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s t : Multiset α
⊢ Disjoint (ndinsert a s) t ↔ Disjoint (a ::ₘ s) t

Next tactic:
simp [Disjoint]
@[simp]
theorem disjoint_ndinsert_right {a : α} {s t : Multiset α} :
    Disjoint s (ndinsert a t) ↔ a ∉ s ∧ Disjoint s t := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s t : Multiset α
⊢ Disjoint s (ndinsert a t) ↔ a ∉ s ∧ Disjoint s t

Next tactic:
rw [disjoint_comm, disjoint_ndinsert_left]
@[simp]
theorem disjoint_ndinsert_right {a : α} {s t : Multiset α} :
    Disjoint s (ndinsert a t) ↔ a ∉ s ∧ Disjoint s t := by
  rw [disjoint_comm, disjoint_ndinsert_left]; 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s t : Multiset α
⊢ a ∉ s ∧ Disjoint t s ↔ a ∉ s ∧ Disjoint s t

Next tactic:
tauto
theorem ndunion_le {s t u : Multiset α} : ndunion s t ≤ u ↔ s ⊆ u ∧ t ≤ u :=
  Multiset.induction_on s (by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ s t u : Multiset α
⊢ ndunion 0 t ≤ u ↔ 0 ⊆ u ∧ t ≤ u

Next tactic:
simp [zero_ndunion]
theorem ndunion_le {s t u : Multiset α} : ndunion s t ≤ u ↔ s ⊆ u ∧ t ≤ u :=
  Multiset.induction_on s (by simp [zero_ndunion])
    (fun _ _ h =>
      by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ s t u : Multiset α
x✝¹ : α
x✝ : Multiset α
h : ndunion x✝ t ≤ u ↔ x✝ ⊆ u ∧ t ≤ u
⊢ ndunion (x✝¹ ::ₘ x✝) t ≤ u ↔ x✝¹ ::ₘ x✝ ⊆ u ∧ t ≤ u

Next tactic:
simp only [cons_ndunion, mem_ndunion, ndinsert_le, and_comm, cons_subset, and_left_comm, h,
        and_assoc]
@[simp]
theorem cons_ndinter_of_mem {a : α} (s : Multiset α) {t : Multiset α} (h : a ∈ t) :
    ndinter (a ::ₘ s) t = a ::ₘ ndinter s t := by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s t : Multiset α
h : a ∈ t
⊢ ndinter (a ::ₘ s) t = a ::ₘ ndinter s t

Next tactic:
simp [ndinter, h]
@[simp]
theorem ndinter_cons_of_not_mem {a : α} (s : Multiset α) {t : Multiset α} (h : a ∉ t) :
    ndinter (a ::ₘ s) t = ndinter s t := by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ : Multiset α
a : α
s t : Multiset α
h : a ∉ t
⊢ ndinter (a ::ₘ s) t = ndinter s t

Next tactic:
simp [ndinter, h]
@[simp]
theorem mem_ndinter {s t : Multiset α} {a : α} : a ∈ ndinter s t ↔ a ∈ s ∧ a ∈ t := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ s t : Multiset α
a : α
⊢ a ∈ ndinter s t ↔ a ∈ s ∧ a ∈ t

Next tactic:
simp [ndinter, mem_filter]
theorem le_ndinter {s t u : Multiset α} : s ≤ ndinter t u ↔ s ≤ t ∧ s ⊆ u := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ s t u : Multiset α
⊢ s ≤ ndinter t u ↔ s ≤ t ∧ s ⊆ u

Next tactic:
simp [ndinter, le_filter, subset_iff]
theorem ndinter_eq_zero_iff_disjoint {s t : Multiset α} : ndinter s t = 0 ↔ Disjoint s t := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ s t : Multiset α
⊢ ndinter s t = 0 ↔ Disjoint s t

Next tactic:
rw [← subset_zero]
theorem ndinter_eq_zero_iff_disjoint {s t : Multiset α} : ndinter s t = 0 ↔ Disjoint s t := by
  rw [← subset_zero]; 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s✝ s t : Multiset α
⊢ ndinter s t ⊆ 0 ↔ Disjoint s t

Next tactic:
simp [subset_iff, Disjoint]
theorem polar_add (f g : M → R) (x y : M) : polar (f + g) x y = polar f x y + polar g x y := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝¹ : CommRing R
inst✝ : AddCommGroup M
f g : M → R
x y : M
⊢ polar (f + g) x y = polar f x y + polar g x y

Next tactic:
simp only [polar, Pi.add_apply]
theorem polar_add (f g : M → R) (x y : M) : polar (f + g) x y = polar f x y + polar g x y := by
  simp only [polar, Pi.add_apply]
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝¹ : CommRing R
inst✝ : AddCommGroup M
f g : M → R
x y : M
⊢ f (x + y) + g (x + y) - (f x + g x) - (f y + g y) = f (x + y) - f x - f y + (g (x + y) - g x - g y)

Next tactic:
abel
theorem polar_neg (f : M → R) (x y : M) : polar (-f) x y = -polar f x y := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝¹ : CommRing R
inst✝ : AddCommGroup M
f : M → R
x y : M
⊢ polar (-f) x y = -polar f x y

Next tactic:
simp only [polar, Pi.neg_apply, sub_eq_add_neg, neg_add]
theorem polar_smul [Monoid S] [DistribMulAction S R] (f : M → R) (s : S) (x y : M) :
    polar (s • f) x y = s • polar f x y := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝³ : CommRing R
inst✝² : AddCommGroup M
inst✝¹ : Monoid S
inst✝ : DistribMulAction S R
f : M → R
s : S
x y : M
⊢ polar (s • f) x y = s • polar f x y

Next tactic:
simp only [polar, Pi.smul_apply, smul_sub]
theorem polar_comm (f : M → R) (x y : M) : polar f x y = polar f y x := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝¹ : CommRing R
inst✝ : AddCommGroup M
f : M → R
x y : M
⊢ polar f x y = polar f y x

Next tactic:
rw [polar, polar, add_comm, sub_sub, sub_sub, add_comm (f x) (f y)]
/-- Auxiliary lemma to express bilinearity of `QuadraticForm.polar` without subtraction. -/
theorem polar_add_left_iff {f : M → R} {x x' y : M} :
    polar f (x + x') y = polar f x y + polar f x' y ↔
      f (x + x' + y) + (f x + f x' + f y) = f (x + x') + f (x' + y) + f (y + x) := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝¹ : CommRing R
inst✝ : AddCommGroup M
f : M → R
x x' y : M
⊢ polar f (x + x') y = polar f x y + polar f x' y ↔
    f (x + x' + y) + (f x + f x' + f y) = f (x + x') + f (x' + y) + f (y + x)

Next tactic:
simp only [← add_assoc]
/-- Auxiliary lemma to express bilinearity of `QuadraticForm.polar` without subtraction. -/
theorem polar_add_left_iff {f : M → R} {x x' y : M} :
    polar f (x + x') y = polar f x y + polar f x' y ↔
      f (x + x' + y) + (f x + f x' + f y) = f (x + x') + f (x' + y) + f (y + x) := by
  simp only [← add_assoc]
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝¹ : CommRing R
inst✝ : AddCommGroup M
f : M → R
x x' y : M
⊢ polar f (x + x') y = polar f x y + polar f x' y ↔
    f (x + x' + y) + f x + f x' + f y = f (x + x') + f (x' + y) + f (y + x)

Next tactic:
simp only [polar, sub_eq_iff_eq_add, eq_sub_iff_add_eq, sub_add_eq_add_sub, add_sub]
/-- Auxiliary lemma to express bilinearity of `QuadraticForm.polar` without subtraction. -/
theorem polar_add_left_iff {f : M → R} {x x' y : M} :
    polar f (x + x') y = polar f x y + polar f x' y ↔
      f (x + x' + y) + (f x + f x' + f y) = f (x + x') + f (x' + y) + f (y + x) := by
  simp only [← add_assoc]
  simp only [polar, sub_eq_iff_eq_add, eq_sub_iff_add_eq, sub_add_eq_add_sub, add_sub]
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝¹ : CommRing R
inst✝ : AddCommGroup M
f : M → R
x x' y : M
⊢ f (x + x' + y) + f y + f x' + f y + f x = f (x + y) + f (x' + y) + f y + f (x + x') ↔
    f (x + x' + y) + f x + f x' + f y = f (x + x') + f (x' + y) + f (y + x)

Next tactic:
simp only [add_right_comm _ (f y) _, add_right_comm _ (f x') (f x)]
/-- Auxiliary lemma to express bilinearity of `QuadraticForm.polar` without subtraction. -/
theorem polar_add_left_iff {f : M → R} {x x' y : M} :
    polar f (x + x') y = polar f x y + polar f x' y ↔
      f (x + x' + y) + (f x + f x' + f y) = f (x + x') + f (x' + y) + f (y + x) := by
  simp only [← add_assoc]
  simp only [polar, sub_eq_iff_eq_add, eq_sub_iff_add_eq, sub_add_eq_add_sub, add_sub]
  simp only [add_right_comm _ (f y) _, add_right_comm _ (f x') (f x)]
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝¹ : CommRing R
inst✝ : AddCommGroup M
f : M → R
x x' y : M
⊢ f (x + x' + y) + f x + f x' + f y + f y = f (x + y) + f (x' + y) + f (x + x') + f y ↔
    f (x + x' + y) + f x + f x' + f y = f (x + x') + f (x' + y) + f (y + x)

Next tactic:
rw [add_comm y x, add_right_comm _ _ (f (x + y)), add_comm _ (f (x + y)),
    add_right_comm (f (x + y)), add_left_inj]
theorem polar_comp {F : Type*} [CommRing S] [AddMonoidHomClass F R S]
    (f : M → R) (g : F) (x y : M) :
    polar (g ∘ f) x y = g (polar f x y) := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝³ : CommRing R
inst✝² : AddCommGroup M
F : Type u_5
inst✝¹ : CommRing S
inst✝ : AddMonoidHomClass F R S
f : M → R
g : F
x y : M
⊢ polar (⇑g ∘ f) x y = g (polar f x y)

Next tactic:
simp only [polar, Pi.smul_apply, Function.comp_apply, map_sub]
instance funLike : FunLike (QuadraticForm R M) M fun _ => R where
  coe := toFun
  coe_injective' x y h := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
Q Q' x y : QuadraticForm R M
h : x.toFun = y.toFun
⊢ x = y

Next tactic:
cases x
instance funLike : FunLike (QuadraticForm R M) M fun _ => R where
  coe := toFun
  coe_injective' x y h := by cases x; 

Proof state:
case mk
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
Q Q' y : QuadraticForm R M
toFun✝ : M → R
toFun_smul✝ : ∀ (a : R) (x : M), toFun✝ (a • x) = a * a * toFun✝ x
exists_companion'✝ : ∃ B, ∀ (x y : M), toFun✝ (x + y) = toFun✝ x + toFun✝ y + BilinForm.bilin B x y
h : { toFun := toFun✝, toFun_smul := toFun_smul✝, exists_companion' := exists_companion'✝ }.toFun = y.toFun
⊢ { toFun := toFun✝, toFun_smul := toFun_smul✝, exists_companion' := exists_companion'✝ } = y

Next tactic:
cases y
instance funLike : FunLike (QuadraticForm R M) M fun _ => R where
  coe := toFun
  coe_injective' x y h := by cases x; cases y; 

Proof state:
case mk.mk
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
Q Q' : QuadraticForm R M
toFun✝¹ : M → R
toFun_smul✝¹ : ∀ (a : R) (x : M), toFun✝¹ (a • x) = a * a * toFun✝¹ x
exists_companion'✝¹ : ∃ B, ∀ (x y : M), toFun✝¹ (x + y) = toFun✝¹ x + toFun✝¹ y + BilinForm.bilin B x y
toFun✝ : M → R
toFun_smul✝ : ∀ (a : R) (x : M), toFun✝ (a • x) = a * a * toFun✝ x
exists_companion'✝ : ∃ B, ∀ (x y : M), toFun✝ (x + y) = toFun✝ x + toFun✝ y + BilinForm.bilin B x y
h :
  { toFun := toFun✝¹, toFun_smul := toFun_smul✝¹, exists_companion' := exists_companion'✝¹ }.toFun =
    { toFun := toFun✝, toFun_smul := toFun_smul✝, exists_companion' := exists_companion'✝ }.toFun
⊢ { toFun := toFun✝¹, toFun_smul := toFun_smul✝¹, exists_companion' := exists_companion'✝¹ } =
    { toFun := toFun✝, toFun_smul := toFun_smul✝, exists_companion' := exists_companion'✝ }

Next tactic:
congr
theorem map_add_add_add_map (x y z : M) :
    Q (x + y + z) + (Q x + Q y + Q z) = Q (x + y) + Q (y + z) + Q (z + x) := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
Q : QuadraticForm R M
x y z : M
⊢ Q (x + y + z) + (Q x + Q y + Q z) = Q (x + y) + Q (y + z) + Q (z + x)

Next tactic:
obtain ⟨B, h⟩ := Q.exists_companion
theorem map_add_add_add_map (x y z : M) :
    Q (x + y + z) + (Q x + Q y + Q z) = Q (x + y) + Q (y + z) + Q (z + x) := by
  obtain ⟨B, h⟩ := Q.exists_companion
  

Proof state:
case intro
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
Q : QuadraticForm R M
x y z : M
B : BilinForm R M
h : ∀ (x y : M), Q (x + y) = Q x + Q y + BilinForm.bilin B x y
⊢ Q (x + y + z) + (Q x + Q y + Q z) = Q (x + y) + Q (y + z) + Q (z + x)

Next tactic:
rw [add_comm z x]
theorem map_add_add_add_map (x y z : M) :
    Q (x + y + z) + (Q x + Q y + Q z) = Q (x + y) + Q (y + z) + Q (z + x) := by
  obtain ⟨B, h⟩ := Q.exists_companion
  rw [add_comm z x]
  

Proof state:
case intro
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
Q : QuadraticForm R M
x y z : M
B : BilinForm R M
h : ∀ (x y : M), Q (x + y) = Q x + Q y + BilinForm.bilin B x y
⊢ Q (x + y + z) + (Q x + Q y + Q z) = Q (x + y) + Q (y + z) + Q (x + z)

Next tactic:
simp only [h, BilinForm.add_left]
theorem map_add_add_add_map (x y z : M) :
    Q (x + y + z) + (Q x + Q y + Q z) = Q (x + y) + Q (y + z) + Q (z + x) := by
  obtain ⟨B, h⟩ := Q.exists_companion
  rw [add_comm z x]
  simp only [h, BilinForm.add_left]
  

Proof state:
case intro
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
Q : QuadraticForm R M
x y z : M
B : BilinForm R M
h : ∀ (x y : M), Q (x + y) = Q x + Q y + BilinForm.bilin B x y
⊢ Q x + Q y + BilinForm.bilin B x y + Q z + (BilinForm.bilin B x z + BilinForm.bilin B y z) + (Q x + Q y + Q z) =
    Q x + Q y + BilinForm.bilin B x y + (Q y + Q z + BilinForm.bilin B y z) + (Q x + Q z + BilinForm.bilin B x z)

Next tactic:
abel
theorem map_add_self (x : M) : Q (x + x) = 4 * Q x := by
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
Q : QuadraticForm R M
x : M
⊢ Q (x + x) = 4 * Q x

Next tactic:
rw [← one_smul R x, ← add_smul, map_smul]
theorem map_add_self (x : M) : Q (x + x) = 4 * Q x := by
  rw [← one_smul R x, ← add_smul, map_smul]
  

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
M : Type u_4
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
Q : QuadraticForm R M
x : M
⊢ (1 + 1) * (1 + 1) * Q x = 4 * Q (1 • x)

Next tactic:
norm_num