lean4-htt/src/Std/Data/Iterators/Lemmas/Producers/Array.lean
Paul Reichert d2c738c4bd
feat: vector iterator (#12363)
This PR introduces iterators for vectors via `Vector.iter` and
`Vector.iterM`, together with the usual lemmas.
2026-02-09 07:45:42 +00:00

117 lines
3.7 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Paul Reichert
-/
module
prelude
public import Std.Data.Iterators.Lemmas.Consumers.Collect
import Std.Data.Iterators.Lemmas.Consumers.Loop
import Init.Data.List.TakeDrop
public import Std.Data.Iterators.Producers.Array
public import Init.Data.Iterators.Producers.List
public import Std.Data.Iterators.Lemmas.Producers.Monadic.Array
@[expose] public section
/-!
# Lemmas about array iterators
This module provides lemmas about the interactions of `Array.iter` with `Iter.step` and various
collectors.
-/
open Std Std.Iterators
variable {β : Type w}
theorem Array.iter_eq_toIter_iterM {array : Array β} :
array.iter = (array.iterM Id).toIter :=
rfl
theorem Array.iter_eq_iterFromIdx {array : Array β} :
array.iter = array.iterFromIdx 0 :=
rfl
theorem Array.iterFromIdx_eq_toIter_iterFromIdxM {array : Array β} {pos : Nat} :
array.iterFromIdx pos = (array.iterFromIdxM Id pos).toIter :=
rfl
theorem Array.step_iterFromIdx {array : Array β} {pos : Nat} :
(array.iterFromIdx pos).step = if h : pos < array.size then
.yield
(array.iterFromIdx (pos + 1))
array[pos]
⟨rfl, rfl, h, rfl⟩
else
.done (Nat.not_lt.mp h) := by
simp only [Array.iterFromIdx_eq_toIter_iterFromIdxM, Iter.step, Iter.toIterM_toIter,
Array.step_iterFromIdxM, Id.run_pure, Shrink.inflate_deflate]
split <;> rfl
theorem Array.step_iter {array : Array β} :
array.iter.step = if h : 0 < array.size then
.yield
(array.iterFromIdx 1)
array[0]
⟨rfl, rfl, h, rfl⟩
else
.done (Nat.not_lt.mp h) := by
simp only [Array.iter_eq_iterFromIdx, Array.step_iterFromIdx]
@[simp, grind =]
theorem Array.toList_iterFromIdx {array : Array β}
{pos : Nat} :
(array.iterFromIdx pos).toList = array.toList.drop pos := by
simp [Iter.toList, Array.iterFromIdx_eq_toIter_iterFromIdxM, Iter.toIterM_toIter,
Array.toList_iterFromIdxM]
@[simp, grind =]
theorem Array.toList_iter {array : Array β} :
array.iter.toList = array.toList := by
simp [Array.iter_eq_iterFromIdx, Array.toList_iterFromIdx]
@[simp, grind =]
theorem Array.toArray_iterFromIdx {array : Array β} {pos : Nat} :
(array.iterFromIdx pos).toArray = array.extract pos := by
simp [iterFromIdx_eq_toIter_iterFromIdxM, Iter.toArray]
@[simp, grind =]
theorem Array.toArray_iter {array : Array β} :
array.iter.toArray = array := by
simp [Array.iter_eq_iterFromIdx]
@[simp, grind =]
theorem Array.toListRev_iterFromIdx {array : Array β} {pos : Nat} :
(array.iterFromIdx pos).toListRev = (array.toList.drop pos).reverse := by
simp [Iter.toListRev_eq, Array.toList_iterFromIdx]
@[simp, grind =]
theorem Array.toListRev_iter {array : Array β} :
array.iter.toListRev = array.toListRev := by
simp [Array.iter_eq_iterFromIdx]
@[simp, grind =]
theorem Array.length_iterFromIdx {array : Array β} {pos : Nat} :
(array.iterFromIdx pos).length = array.size - pos := by
simp [← Iter.length_toList_eq_length]
@[simp, grind =]
theorem Array.length_iter {array : Array β} :
array.iter.length = array.size := by
simp [← Iter.length_toList_eq_length]
section Equivalence
theorem Array.iterFromIdx_equiv_iter_drop_toList {α : Type w} {array : Array α}
{pos : Nat} : (array.iterFromIdx pos).Equiv (array.toList.drop pos).iter := by
apply IterM.Equiv.toIter
exact Array.iterFromIdxM_equiv_iterM_drop_toList
theorem Array.iter_equiv_iter_toList {α : Type w} {array : Array α} :
array.iter.Equiv array.toList.iter := by
rw [Array.iter_eq_iterFromIdx]
simpa using iterFromIdx_equiv_iter_drop_toList
end Equivalence