Zulip Chat Archive
Stream: lean4
Topic: why Std.range has field step_pos?
Asei Inoue (Apr 06 2025 at 03:55):
this code does not work.
def eratosthenesAux (n : Nat) : Array Bool := Id.run do
let mut isPrime := Array.replicate (n + 1) true
isPrime := isPrime.set! 0 false
isPrime := isPrime.set! 1 false
for p in [2 : n + 1] do
if not isPrime[p]! then
continue
if p ^ 2 > n then
break
/- expected type must not contain free variables
0 < p
Use the '+revert' option to automatically cleanup and revert free variables.Lean 4
p : Nat -/
for q in [p * p : n : p] do
isPrime := isPrime.set! q false
return isPrime
this is because Std.range
has step_pos
field.
structure Range where
start : Nat := 0
stop : Nat
step : Nat := 1
step_pos : 0 < step
I think we need a special notation that does not give a proof for step_pos to make the notation [start : end : step]
more convenient to use.
Mario Carneiro (Apr 06 2025 at 03:57):
you need a proof that p
is positive or else the for loop won't terminate
Asei Inoue (Apr 06 2025 at 03:58):
I want a syntax for Std.range that does not require a proof to be given.
Mario Carneiro (Apr 06 2025 at 03:58):
what would it do?
Mario Carneiro (Apr 06 2025 at 03:59):
the syntax doesn't require a fourth argument
Mario Carneiro (Apr 06 2025 at 03:59):
as you can see, you only wrote 3 things
Mario Carneiro (Apr 06 2025 at 04:00):
you are getting an error because the automatic proof method failed, because you don't have things in the context to help lean prove that p
is positive
Mario Carneiro (Apr 06 2025 at 04:01):
p
comes from another range earlier; so I think if you do for _h : p in [2 : n + 1] do
then omega will be able to prove the later side condition
Asei Inoue (Apr 06 2025 at 04:01):
Is it appropriate to fill in the proof part with decide
? Wouldn't a stronger tactic be better, and wouldn't decide
only accept concrete numbers?
syntax:max "[" withoutPosition(":" term) "]" : term
syntax:max "[" withoutPosition(term ":" term) "]" : term
syntax:max "[" withoutPosition(":" term ":" term) "]" : term
syntax:max "[" withoutPosition(term ":" term ":" term) "]" : term
macro_rules
| `([ : $stop]) => `({ stop := $stop, step_pos := Nat.zero_lt_one : Range })
| `([ $start : $stop ]) => `({ start := $start, stop := $stop, step_pos := Nat.zero_lt_one : Range })
| `([ $start : $stop : $step ]) => `({ start := $start, stop := $stop, step := $step, step_pos := by decide : Range })
| `([ : $stop : $step ]) => `({ stop := $stop, step := $step, step_pos := by decide : Range })
Asei Inoue (Apr 06 2025 at 04:02):
p
comes from another range earlier; so I think if you dofor _h : p in [2 : n + 1] do
then omega will be able to prove the later side condition
I don't think omega can be used because decide fills up automatically.
Mario Carneiro (Apr 06 2025 at 04:03):
you're right, I was hoping it would use get_elem_tactic
or similar
Mario Carneiro (Apr 06 2025 at 04:04):
it seems there is no alternative to just writing the range constructor manually :(
Asei Inoue (Apr 06 2025 at 04:06):
I think this should be an issue on Lean 4.
Asei Inoue (Apr 06 2025 at 04:12):
@Mario Carneiro done!
https://github.com/leanprover/lean4/issues/7833
Last updated: May 02 2025 at 03:31 UTC