Zulip Chat Archive
Stream: general
Topic: The Mechanics of Proof, Exercise 2.1.9.3
Full name or 名前 (Feb 07 2024 at 10:33):
Hello!
I'm following "The Mechanics of Proof" book and am stuck at Exercise 2.1.9.3.
I came up with the following solution:
example (x y : ℚ) (h : x * y = 1) (h2 : x ≥ 1) : y ≤ 1 := by
have h3 : x * y > 0 := by addarith [h]
cancel x at h3
calc
y = y / 1 := by ring
_ = y / (x * y) := by rw [h]
_ = 1 / x := by ring
_ ≤ 1 / 1 := by rel [h2]
_ ≤ 1 := by numbers
Yet it fails on _ = 1 / x := by ring
step:
▶ 1 goal
x y : ℚ
h : x * y = 1
h2 : x ≥ 1
h3 : 0 < y
⊢ y / (x * y) = 1 / x
▶ 95:27-95:31: error:
ring failed, ring expressions not equal
x y : ℚ
h : x * y = 1
h2 : x ≥ 1
h3 : 0 < y
⊢ y * y⁻¹ * x⁻¹ = x⁻¹
Is there any other tactic than ring
which could allow me to cancel a positive variable divided by itself?
P.S. I'm using Lean v4.2.0 and Mathlib4 v4.2.0 (according to lake-manifest.json
).
Full name or 名前 (Feb 07 2024 at 10:34):
cc @Heather Macbeth
Ruben Van de Velde (Feb 07 2024 at 10:37):
Maybe field_simp
?
Kevin Buzzard (Feb 07 2024 at 10:39):
Division and inverses are not axioms of a ring, so one should not expect ring
to know things like for nonzero .
Full name or 名前 (Feb 07 2024 at 10:51):
Neither do this work:
example (x y : ℚ) (h : x * y = 1) (h2 : x ≥ 1) : y ≤ 1 := by
have h3 : x * y > 0 := by addarith [h]
cancel x at h3
have h4 :=
calc
x * y = 1 := by rw[h]
_ = 1 * 1 := by numbers
_ ≤ 1 * x := by rel [h2]
cancel x at h4 -- application type mismatch nonneg_of_mul_nonneg_left ...
application type mismatch
nonneg_of_mul_nonneg_left h4
argument
h4
has type
x * y ≤ 1 * x : Prop
but is expected to have type
0 ≤ ?m.113395 * x : Prop
Ruben Van de Velde (Feb 07 2024 at 10:54):
You've got x
on the left and then on the right
Full name or 名前 (Feb 07 2024 at 10:57):
Yeah, but how can I cancel them out? :thinking:
Ruben Van de Velde (Feb 07 2024 at 11:02):
I mean, you have rather than
Full name or 名前 (Feb 07 2024 at 11:04):
Interesting... Now it compiles, but I get this error:
(deterministic) timeout at 'whnf', maximum number of heartbeats (200000) has been reached (use 'set_option maxHeartbeats <num>' to set the limit)
Full name or 名前 (Feb 07 2024 at 11:04):
The code is:
example (x y : ℚ) (h : x * y = 1) (h2 : x ≥ 1) : y ≤ 1 := by -- (deterministic) timeout ...
have h3 : x * y > 0 := by addarith [h]
cancel x at h3
have h4 :=
calc
x * y = 1 := by rw[h]
_ = 1 * 1 := by numbers
_ ≤ x * 1 := by rel [h2]
cancel x at h4
Heather Macbeth (Feb 08 2024 at 05:05):
Strangely enough a colleague reported this exact example to me yesterday, as well. I think it's a reducibility setting -- but I also think the best fix will be a complete reimplementation (to mathlib standards of robustness) of this tactic, at which point I will also PR it to mathlib. Some previous discussion:
https://leanprover.zulipchat.com/#narrow/stream/113489-new-members/topic/.E2.9C.94.20The.20mechanics.20of.20proof.3A.20cancel.20tactic.20on.20a.5E2.20.3F/near/401470618
Heather Macbeth (Feb 08 2024 at 05:06):
In the short term: try the following endgame, which doesn't involve your last cancel
step:
Last updated: May 02 2025 at 03:31 UTC