Skip to content

feat: reverse iterators for Array and Vector - #15327

Open
Bubbler-4 wants to merge 4 commits into
leanprover:masterfrom
Bubbler-4:bubbler-array-reviter
Open

Bubbler-4 wants to merge 4 commits into
leanprover:masterfrom
Bubbler-4:bubbler-array-reviter

Conversation

@Bubbler-4

Copy link
Copy Markdown

This PR adds reverse iterators for Array and Vector.

This change was split out of #15233 into a separate PR, as per the comments there.

@Bubbler-4
Bubbler-4 requested a review from datokrat as a code owner September 25, 2026 11:54
@github-actions github-actions Bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Sep 25, 2026

@datokrat datokrat left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for helping us out with the iterator API!

I noticed that the verification API for the reverse iterators is still missing (under Std/Data/Iterators/Lemmas/Producers/Monadic/Array.lean etc.). It would be very helpful to have the verification API already in this PR. Besides the benefit of proving that the iterator does what it should, I believe that writing it would have caught some of the things I remarked, e.g. the missing Finite and IteratorLoop instance

· cases h'
· cases h

instance ArrayRevIterator.instFinite [Pure m] : Finite (ArrayIterator α) m := by

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: Should be ArrayRevIterator. toList, as in your tests, works, but you wouldn't be able to use it in proofs without the Finite instance. There's the same type in instIteratorLoop below.

Comment on lines +153 to +157
@[always_inline, inline, match_pattern]
def _root_.Array.iterRevFromIdxM {α : Type w} (array : Array α) (m : Type w → Type w') (pos : Nat)
[Pure m] :
IterM (α := ArrayRevIterator α) m α :=
⟨{ array := array, pos := (pos + 1).min array.size, upper_bound := Nat.min_le_right _ _ }⟩

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something that will bite us in the lemmas (iterRevFromIdxM is the natural thing to induct over):
For non-empty arrays, iterRevFromIdxM cannot represent the exhausted state pos := 0.

I also don't think that the match_pattern will work here because of min; this is also something that would become apparent when writing the lemmas.

I think we could address both issues by instead providing an iterator iterRevFromRevIdxM, where the last element of the iterator gets position 0. Then the exhausted state becomes representable and we can get rid of the min. What do you think? Alternatively, we could provide both iterRevFromRevIdxM, the more well-behaved one, and iterRevFromIdxM, the more intuitive one.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iterRevFromRevIdxM sounds like a good idea indeed. It should also help with formalizing the equivalence with the forward iterator too. That said, how would I actually write down the statement that "iterRevFromRevIdxM is equivalent to iterFromIdxM on the reversed array"?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would already be great to show that applying toList to both yields the same result. The more general, but also more difficult, theorem would be to show that these iterators are equivalent. Although it would be great to have such a lemma, I think the toList-based lemma would be sufficient for now (except, of course, if you are willing to prove the general equivalence, that would be great).

@Bubbler-4
Bubbler-4 force-pushed the bubbler-array-reviter branch from 205259a to 72eb75d Compare November 14, 2026 12:12
@Bubbler-4
Bubbler-4 force-pushed the bubbler-array-reviter branch from 72eb75d to 3dbaf7e Compare November 14, 2026 12:18

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants