Zulip Chat Archive
Stream: mathlib4
Topic: field_simp failure
Junyan Xu (May 25 2024 at 07:42):
The following two examples are similar in form, except that the latter is more complicated, and indeed field_simp
succeeds on the former (when followed by ring
) but fails on the latter. What could be the problem?
import Mathlib.Tactic.FieldSimp
import Mathlib.Tactic.Ring
lemma smulX_add_aux {F} [Field F] {m n m₂ n₂ a s : F}
(hm : m ≠ 0) (hn : n ≠ 0) (ha : a ≠ 0) (hs : s ≠ 0) :
m₂ / m ^ 4 * (n₂ / n ^ 4) / (a * s / (n * m) ^ 2) ^ 2 = n₂ * m₂ / (a * s) ^ 2 := by
field_simp; ring
lemma smulY_add_sub_negY_aux {F} [Field F] {m n m₂ n₂ a s am an : F}
(hm : m ≠ 0) (hn : n ≠ 0) (ha : a ≠ 0) (hs : s ≠ 0) :
(m₂ / m ^ 4 * (an * m / (a * n) ^ 2) - n₂ / n ^ 4 * (am * n / (a * m) ^ 2))
/ (a * s / (n * m) ^ 2)
= (an * m₂ * n - am * n₂ * m) * a / (s * n * m) / a ^ 4 := by
/- `field_simp; ring` produces
⊢ m₂ * an * m ^ 6 * n ^ 7 * a ^ 6 * s * m⁻¹ ^ 6 * n⁻¹ ^ 6 * a⁻¹ ^ 5 * s⁻¹ -
m ^ 7 * n ^ 6 * a ^ 6 * n₂ * am * s * m⁻¹ ^ 6 * n⁻¹ ^ 6 * a⁻¹ ^ 5 * s⁻¹ =
m₂ * an * n * a - m * a * n₂ * am -/
field_simp; rw [div_eq_iff]
· ring
apply_rules [pow_ne_zero, mul_ne_zero]
When working with elliptic curves I find that field_simp is not fast enough and I had to extract lemmas that capture the pattern (it's probably the field being complicated that makes it slow). How could we make it faster so it's more convenient to use?
Junyan Xu (May 28 2024 at 04:35):
cc author @Sébastien Gouëzel and porter @David Renshaw
David Renshaw (May 28 2024 at 11:41):
Increasing the max discharge depth makes it work:
lemma smulY_add_sub_negY_aux {F} [Field F] {m n m₂ n₂ a s am an : F}
(hm : m ≠ 0) (hn : n ≠ 0) (ha : a ≠ 0) (hs : s ≠ 0) :
(m₂ / m ^ 4 * (an * m / (a * n) ^ 2) - n₂ / n ^ 4 * (am * n / (a * m) ^ 2))
/ (a * s / (n * m) ^ 2)
= (an * m₂ * n - am * n₂ * m) * a / (s * n * m) / a ^ 4 := by
field_simp (config := {maxDischargeDepth := 9}); ring
Junyan Xu (May 28 2024 at 14:46):
Thank you! I think this configuration should be in the docstring. Here is another small issue with field_simp
:
import Mathlib.Tactic.FieldSimp
variable {F} [Field F] {x₁ x₂ : F} (hx : x₁ - x₂ ≠ 0)
lemma neg_sub_div_sub : -(x₁ - x₂) / (x₁ - x₂) = -1 := by
field_simp /- successful -/
lemma sub_div_neg_sub : (x₁ - x₂) / -(x₁ - x₂) = -1 := by
field_simp /- goal: (x₁ - x₂) / (x₂ - x₁) = -1 -/
Richard Copley (May 28 2024 at 16:01):
It can do a little more inference if you lift to the group of units:
import Mathlib.Tactic.FieldSimp
variable {F} [Field F] {x₁ x₂ : F} (hx : x₁ - x₂ ≠ 0)
lemma sub_div_neg_sub : (x₁ - x₂) / -(x₁ - x₂) = -1 := by
lift x₁ - x₂ to Fˣ using hx.isUnit with h
field_simp -- successful
Sadly it doesn't do the same with NeZero
instances, so even adding this silly thing doesn't help much:
instance {F} [SubtractionMonoid F] {x y : F} [inst: NeZero (x - y)] : NeZero (y - x) :=
have ⟨hx⟩ := inst
⟨by rwa [← neg_zero, ← neg_sub, neg_inj.ne]⟩
maxDischargeDepth
is passed straight to simp
(after increasing it to at least 7 if necessary). See #11070, #12239, previous discussion.
Junyan Xu (May 28 2024 at 16:26):
Thanks for the pointers!
The issue with sub_div_neg_sub
is field_simp somehow "simplified" -(x₁ - x₂)
to (x₂ - x₁)
so it can no longer use hx
. Switching x₁
and x₂
in hx
makes it work again:
lemma sub_div_neg_sub : (x₁ - x₂) / -(x₁ - x₂) = -1 := by
rw [sub_ne_zero, ne_comm, ← sub_ne_zero] at hx
field_simp -- successful
It also suffices to use set
instead of lift
:
lemma sub_div_neg_sub : (x₁ - x₂) / -(x₁ - x₂) = -1 := by
set x := x₁ - x₂
field_simp
Junyan Xu (May 28 2024 at 17:16):
Consider also the following four examples, whose behaviors hinge upon that docs#neg_sq is a simp lemma but there's no such lemma for the cube:
import Mathlib.Tactic.FieldSimp
import Mathlib.Tactic.Ring
variable {F} [Field F] {x : F}
lemma pow_three_div_neg_pow_three (hx : -x ≠ 0) : x ^ 3 / (-x) ^ 3 = -1 := by
field_simp; ring -- successful
lemma pow_three_div_neg_pow_three' (hx : x ≠ 0) : x ^ 3 / (-x) ^ 3 = -1 := by
field_simp -- simp made no progress
lemma sq_div_neg_sq (hx : -x ≠ 0) : x ^ 2 / (-x) ^ 2 = 1 := by
field_simp -- ⊢ x ^ 2 / x ^ 2 = 1
lemma sq_div_neg_sq' (hx : x ≠ 0) : x ^ 2 / (-x) ^ 2 = 1 := by
field_simp -- successful
Last updated: May 02 2025 at 03:31 UTC