Zulip Chat Archive
Stream: new members
Topic: changing gt to gte for integers
rzeta0 (Sep 10 2024 at 23:48):
I have a hypothesis about an integer a
a : ℤ
hb : a > 2
I'd like to turn this into
a : ℤ
hb : a ≥ 3
based on the idea that the successor to 2 is 3.
How can I do this?
(I've searched Moogle with no success, using search terms including gte of gt, succ, integer)
Yakov Pechersky (Sep 11 2024 at 00:21):
Does replace hb : a ≥ 3 := by omega
work?
lyphyser (Sep 11 2024 at 00:28):
The best way to solve issues like this is to ask Lean about it:
def foo (a: ℤ) (hb: a > 2): a ≥ 3 := by
apply?
or rw? instead of apply? if it's about a rewrite
In this case, "exact hb" is the answer, since a < b is defined as (a + 1) <= b and thus b > a is defined as b >= (a + 1)
rzeta0 (Sep 11 2024 at 10:59):
Thanks for the replies.
I'm a beginner and at this point in the course (Heather Macbeth's) we aren't expected to use advanced tactics like omega
or asking lean via ?
I think we are expected to search for simpler lemmas like le_or_gt
.
The exercise is simple to express:
example {m : ℤ} (h : ∃ a, 2 * a = m) : m ≠ 5 := by
And the hint is to use a proof by cases, which suggests splitting a
into something like a <= 2
and a >2
. The first case I can do, the second seems to require me to transition from a>2
to a>=3
by virtue of a
being an integer.
rzeta0 (Sep 11 2024 at 11:20):
I'm currently searching moogle for "gt equals gte successor" and Order.lt_succ_iff_eq_or_lt
looks related but the wrong way around, there doesn't appear to be a gt
version.
Damiano Testa (Sep 11 2024 at 11:22):
You should treat x > y
as an illusion and imagine that it is y < x
: Lean will play along.
Daniel Weber (Sep 11 2024 at 11:24):
Maybe there's docs#Nat.add_one_le_of_lt ?
Violeta Hernández (Sep 11 2024 at 11:40):
fyi to talk about successors of natural numbers, just use a + 1
rzeta0 (Sep 11 2024 at 11:40):
Daniel Weber said:
Maybe there's docs#Nat.add_one_le_of_lt ?
unknown tactic
?
I think MacBeth's course environment might be lean3? such a shame as this looks ideal.
Violeta Hernández (Sep 11 2024 at 11:40):
Order.succ
is intended for more general circumstances, and Nat.succ
is sort of an implementation detail
Violeta Hernández (Sep 11 2024 at 11:41):
rzeta0 said:
unknown tactic
?
You must have forgotten to write down the exact
or apply
tactic
rzeta0 (Sep 11 2024 at 12:26):
Here is my code thus far.
I'm trying to create a hypothesis hb2 ; >= 3
from hb : a > 2
using add_one_le_of_lt
but it is giving an unknown tactic error.
example {m : ℤ} (h : ∃ a, 2 * a = m) : m ≠ 5 := by
obtain ⟨a, h2⟩ := h
have h3 := le_or_gt a 2
obtain ha | hb := h3
· have g1 :=
calc
m = 2 * a := by rw [h2]
_ ≤ 2 * 2 := by rel [ha]
_ < 5 := by numbers
apply ne_of_lt
apply g1
· have hb2 : a ≥ 3 := by add_one_le_of_lt -- -- < ERROR unknown tactic
have g2 :=
calc
m = 2 * a := by rw [h2]
_ ≥ 2 * 3 := by rel [hb2]
_ > 5 := by numbers
apply g2
numbers
is like norm_num
Ruben Van de Velde (Sep 11 2024 at 12:27):
It appears to be the case that you are missing imports
Ruben Van de Velde (Sep 11 2024 at 12:27):
And Violeta's answer is correct
Daniel Weber (Sep 11 2024 at 12:39):
You can use have hb2 : a ≥ 3 := Int.add_one_le_of_lt hb
rzeta0 (Sep 11 2024 at 12:58):
Ruben Van de Velde said:
It appears to be the case that you are missing imports
adding a import Mathlib.Init.Data.Nat.Basic
or a import Mathlib.Init.Data.Int.Basic
to the existing boilerplate imports doesn't seem to solve it.
I've also changed the code to hb2 : a ≥ 3 := Int.add_one_le_of_lt hb
, adding the hb
at the end.
rzeta0 (Sep 11 2024 at 13:04):
Here is my code again in plain vanilla lean and not the Heather Macbeth special environment with custom and disabled tactics:
import Mathlib.Tactic -- <-- so far has imported everything I needed
example {m : ℤ} (h : ∃ a, 2 * a = m) : m ≠ 5 := by
obtain ⟨a, h2⟩ := h
have h3 := le_or_gt a 2
obtain ha | hb := h3
· have g1 :=
calc
m = 2 * a := by rw [h2]
_ ≤ 2 * 2 := by rel [ha]
_ < 5 := by norm_num
apply ne_of_lt
apply g1
· have hb2 : a ≥ 3 := by add_one_le_of_lt hb -- <-- unknown tactic error, same with Int.add_one_le_of_lt
have g2 :=
calc
m = 2 * a := by rw [h2]
_ ≥ 2 * 3 := by rel [hb2]
_ > 5 := by norm_num
apply g2
Derek Rhodes (Sep 11 2024 at 13:07):
rzeta0 said:
I think MacBeth's course environment might be lean3? such a shame as this looks ideal.
Hi, I hope I'm not intruding, and as a side note, "The Mechanics of Proof" does use Lean4, however there are some tactics that are programmatically excluded to ensure people learn how to use the less powerful ones.
Derek Rhodes (Sep 11 2024 at 13:09):
oh, nevermind! didn't see the new post.
rzeta0 (Sep 11 2024 at 13:12):
Derek - thanks for the info on Mechanics of Proof.
Launching the code in the online web "live.lean" environment also shows the unknown tactic error.
Derek Rhodes (Sep 11 2024 at 13:18):
@rzeta0, I just tried out your code on my machine, and found that using apply
worked:
have hb2 : a ≥ 3 := by apply Int.add_one_le_of_lt hb
Derek Rhodes (Sep 11 2024 at 13:22):
add_one_le_of_lt
is a theorem, which, if is an equality or an iff, then they can also be rw
rewritten, but not used as a tactic, that is by itself in tactic mode.
another way to do it is with term mode like:
have hb2 : a ≥ 3 := Int.add_one_le_of_lt hb
rzeta0 (Sep 11 2024 at 13:34):
Thanks Derek - the use of apply
worked. I am a beginner so still learning the syntax but I think I do understand the different between applying a lemma and justifying via a tactic .. i think.
Can I ask why the code doesn't work if I leave out the Int
at the beggining of Int.add_one_le_of_lt
?
rzeta0 (Sep 11 2024 at 13:35):
Overall I think Macbeth has a simpler solution in mind as my resulting code seems far too big for this early chapter in her course. Am I missing a mathematical idea?
Derek Rhodes (Sep 11 2024 at 16:02):
import Std.Data.Int.Basic
(edited) will bring the identifiers contained in the Int
package into scope. For some reason Int
itself is in scope, not sure why.
As for apply
, at first it seemed backwards to me because I was used to apply
from lisp. Here are two contrived examples, the first is how apply
seems to consume the last term of a chain of applications. The second example shows how hypothesis can be applied like functions the way programmers are used to seeing it:
example (a b c : ℕ) (ha: a = 1) (hb: b = 2) (hc: b < c): a < c := by
have h : a < b → a < c := by sorry
-- goal ⊢ a < c
apply h -- (works backwards through the implication)
-- goal ⊢ a < b
addarith [ha, hb]
example (a b c : ℕ) (ha: a = 1) (hb: b = 2) (hc: b < c): a < c := by
have h : a < b → a < c := by sorry
have h2 : a < b := by addarith [ha, hb]
-- (how programmers usually think about function application)
have h3 := h h2 -- <====
--
exact h3
Derek Rhodes (Sep 11 2024 at 17:30):
oops, I should have said that it is necessary to open Int
before using add_one_le_of_lt hb
without the Int.
prefix
and that the import should be import Std.Data.Int.Basic
instead.
Kyle Miller (Sep 11 2024 at 17:45):
@Derek Rhodes "Apply" is as in "by applying theorem foo, we see it suffices to show..." in a written proof.
apply h
is more-or-less the same as refine h ?_ ?_ ... ?_
with the correct number of ?_
s. It's applying the theorem in the function application sense too, just with as-yet-unknown arguments.
Derek Rhodes (Sep 11 2024 at 17:48):
Thanks for the insight Kyle, now I have a reason to take a deeper look into refine
.
Kyle Miller (Sep 11 2024 at 17:49):
refine
is exact
except it allows placeholders that create new goals.
Derek Rhodes (Sep 11 2024 at 17:49):
ok cool, good to know
Mario Carneiro (Sep 12 2024 at 10:42):
I'm pretty sure that @Heather Macbeth prefers to use more tactic-based proofs, so probably the proof here is linarith
or addarith
or similar, rather than referring explicitly to the lemma Int.add_one_le_of_lt
by name
rzeta0 (Sep 12 2024 at 14:30):
Mario Carneiro said:
I'm pretty sure that Heather Macbeth prefers to use more tactic-based proofs, so probably the proof here is
linarith
oraddarith
or similar, rather than referring explicitly to the lemmaInt.add_one_le_of_lt
by name
I'd welcome ideas here. I spent quite a few hours trying to find a maths proof that was translatable into the small set of tactics we've covered but I couldn't see it.
Heather Macbeth (Sep 12 2024 at 14:41):
I think Example 2.3.2 has the lemma you want:
have h3 := le_or_succ_le a 2
produces
h3 : a ≤ 2 ∨ 3 ≤ a
rzeta0 (Sep 12 2024 at 14:47):
Thanks Heather Macbeth - I'll give that a go.
I'm working my way through the course doing every single exercise - doing the last two from the Existence chapter now.
Thank you for creating this course. :smiley:
rzeta0 (Sep 12 2024 at 14:49):
yep - that works beautifully:
example {m : ℤ} (h : ∃ a, 2 * a = m) : m ≠ 5 := by
obtain ⟨a, h2⟩ := h
-- have h3 := le_or_gt a 2
have h3 := le_or_succ_le a 2
obtain ha | hb := h3
· have g1 :=
calc
m = 2 * a := by rw [h2]
_ ≤ 2 * 2 := by rel [ha]
_ < 5 := by numbers
apply ne_of_lt
apply g1
· have g2 :=
calc
m = 2 * a := by rw [h2]
_ ≥ 2 * 3 := by rel [hb]
_ > 5 := by numbers
apply ne_of_gt
apply g2
Last updated: May 02 2025 at 03:31 UTC