Zulip Chat Archive
Stream: mathlib4
Topic: feature request: field_simp in Nat
Asei Inoue (Mar 06 2024 at 13:47):
import Mathlib.Tactic
example (n m : Nat) : n * m = ((n + m) ^ 2 - n ^ 2 - m ^ 2 ) / 2 := by
-- `field_simp` fails.
-- Why doesn't `field_simp` use `Nat.div_eq_of_eq_mul_right` here?
try field_simp
symm
apply Nat.div_eq_of_eq_mul_right
. norm_num
rw [show (n + m) ^ 2 = n ^ 2 + 2 * n * m + m ^ 2 from by ring]
calc n ^ 2 + 2 * n * m + m ^ 2 - n ^ 2 - m ^ 2
_ = (n ^ 2 - n ^ 2) + 2 * n * m + (m ^ 2 - m ^ 2) := by simp [add_assoc]
_ = 0 + 2 * n * m + 0 := by congr 2 <;> simp_arith
_ = 2 * (n * m) := by simp [mul_assoc]
example (n m : Rat) : n * m = ((n + m) ^ 2 - n ^ 2 - m ^ 2 ) / 2 := by
-- `field_simp` works! :)
field_simp
ring
Johan Commelin (Mar 06 2024 at 13:48):
Because Rat
is a field and Nat
is not.
Asei Inoue (Mar 06 2024 at 13:49):
My point is that it would be useful if field_simp
could also can be used in Nat
.
Johan Commelin (Mar 06 2024 at 13:50):
It is out of scope. Division on Nat is pretty pathological
Eric Wieser (Mar 06 2024 at 13:51):
As is subtraction
Ruben Van de Velde (Mar 06 2024 at 13:52):
You can rify
or qify
first, but you'll need to show that you're not in a pathological case for that to work
Asei Inoue (Mar 06 2024 at 13:54):
I know it's not field_simp
's job to do this.
Just having a tactic to try Nat.div_eq_of_eq_mul_right
and Nat.div_eq_of_eq_mul_left
would be useful for me.
It would be nice to have a tactic that hits the commonly performed operation of 'erasing the denominator'.
Asei Inoue (Mar 06 2024 at 13:56):
@Ruben Van de Velde
You can rify or qify first, but you'll need to show that you're not in a pathological case for that to work
Thank you ... But I didn't know how to do it. I would like to see an example code.
Bolton Bailey (Mar 06 2024 at 14:33):
Well, I think the issue with trying to use qify
here is that you will run into the non-obviousness of the fact that ((n + m) ^ 2 - n ^ 2 - m ^ 2 )
is evenly divisible by 2.
Kim Morrison (Mar 07 2024 at 00:52):
omega
is not very good at dealing with polynomials, but
import Mathlib.Tactic
example (n m : Nat) : n * m = ((n + m) ^ 2 - n ^ 2 - m ^ 2 ) / 2 := by
ring_nf
generalize n * m = nm
omega
does work.
Kim Morrison (Mar 07 2024 at 00:54):
Actually, the need for generalize
there seems to be a straight up omega
bug. I'll investigate.
Kim Morrison (Mar 07 2024 at 01:00):
Ah, I see, omega
has no way of knowing:
import Mathlib.Tactic
example (n m : Nat) : n * m = ((n + m) ^ 2 - n ^ 2 - m ^ 2) / 2 := by
ring_nf
have : 0 ≤ (n : Int) * (m : Int) := sorry
omega -- works
Kim Morrison (Mar 07 2024 at 01:01):
(This is essentially the difference between linarith
and nlinarith
.)
Kim Morrison (Mar 07 2024 at 01:03):
I think this is far enough afield that I am not going to pursue it now. We had talked about adding an extensible mechanism for telling omega
new facts about atoms, but have decided not to implement that immediately.
If someone is keen to push on this I'm happy to explain what would be required.
Kevin Buzzard (Mar 07 2024 at 07:16):
Asei Inoue said:
It would be nice to have a tactic that hits the commonly performed operation of 'erasing the denominator'.
I would say that natural division is not at all common and was arguably a code smell. a = b / c
is sometimes what you want but far more common is the strictly stronger statement a * c = b
which is what people would usually use rather than division.
Last updated: May 02 2025 at 03:31 UTC