This PR introduces iterators for vectors via `Vector.iter` and `Vector.iterM`, together with the usual lemmas.
117 lines
3.7 KiB
Text
117 lines
3.7 KiB
Text
/-
|
||
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
|