refactor: partially move iterators to Init (#8767)
This PR moves parts of the iterator library from `Std` to `Init`. The reason is that the polymorphic range API must be in `Init` and it depends on the iterators.
This commit is contained in:
parent
f0fdab86bb
commit
86eded35db
62 changed files with 980 additions and 803 deletions
|
|
@ -46,3 +46,4 @@ import Init.Data.NeZero
|
|||
import Init.Data.Function
|
||||
import Init.Data.RArray
|
||||
import Init.Data.Vector
|
||||
import Init.Data.Iterators
|
||||
|
|
|
|||
19
src/Init/Data/Iterators.lean
Normal file
19
src/Init/Data/Iterators.lean
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/-
|
||||
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
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.PostconditionMonad
|
||||
import Init.Data.Iterators.Consumers
|
||||
import Init.Data.Iterators.Lemmas
|
||||
import Init.Data.Iterators.Internal
|
||||
|
||||
/-!
|
||||
# Iterators
|
||||
|
||||
See `Std.Data.Iterators` for an overview over the iterator API.
|
||||
-/
|
||||
|
|
@ -3,6 +3,8 @@ 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
|
||||
import Init.Core
|
||||
import Init.Classical
|
||||
|
|
@ -31,7 +33,7 @@ See `Std.Data.Iterators.Producers` for ways to iterate over common data structur
|
|||
By convention, the monadic iterator associated with an object can be obtained via dot notation.
|
||||
For example, `List.iterM IO` creates an iterator over a list in the monad `IO`.
|
||||
|
||||
See `Std.Data.Iterators.Consumers` for ways to use an iterator. For example, `it.toList` will
|
||||
See `Init.Data.Iterators.Consumers` for ways to use an iterator. For example, `it.toList` will
|
||||
convert a provably finite iterator `it` into a list and `it.allowNontermination.toList` will
|
||||
do so even if finiteness cannot be proved. It is also always possible to manually iterate using
|
||||
`it.step`, relying on the termination measures `it.finitelyManySteps` and `it.finitelyManySkips`.
|
||||
|
|
@ -75,7 +77,7 @@ See `Std.Data.Iterators.Producers` for ways to iterate over common data structur
|
|||
By convention, the monadic iterator associated with an object can be obtained via dot notation.
|
||||
For example, `List.iterM IO` creates an iterator over a list in the monad `IO`.
|
||||
|
||||
See `Std.Data.Iterators.Consumers` for ways to use an iterator. For example, `it.toList` will
|
||||
See `Init.Data.Iterators.Consumers` for ways to use an iterator. For example, `it.toList` will
|
||||
convert a provably finite iterator `it` into a list and `it.allowNontermination.toList` will
|
||||
do so even if finiteness cannot be proved. It is also always possible to manually iterate using
|
||||
`it.step`, relying on the termination measures `it.finitelyManySteps` and `it.finitelyManySkips`.
|
||||
|
|
@ -111,12 +113,14 @@ structure Iter {α : Type w} (β : Type w) where
|
|||
Converts a pure iterator (`Iter β`) into a monadic iterator (`IterM Id β`) in the
|
||||
identity monad `Id`.
|
||||
-/
|
||||
@[expose]
|
||||
def Iter.toIterM {α : Type w} {β : Type w} (it : Iter (α := α) β) : IterM (α := α) Id β :=
|
||||
⟨it.internalState⟩
|
||||
|
||||
/--
|
||||
Converts a monadic iterator (`IterM Id β`) over `Id` into a pure iterator (`Iter β`).
|
||||
-/
|
||||
@[expose]
|
||||
def IterM.toIter {α : Type w} {β : Type w} (it : IterM (α := α) Id β) : Iter (α := α) β :=
|
||||
⟨it.internalState⟩
|
||||
|
||||
|
|
@ -170,6 +174,7 @@ inductive IterStep (α β) where
|
|||
Returns the succeeding iterator stored in an iterator step or `none` if the step is `.done`
|
||||
and the iterator has finished.
|
||||
-/
|
||||
@[expose]
|
||||
def IterStep.successor : IterStep α β → Option α
|
||||
| .yield it _ => some it
|
||||
| .skip it => some it
|
||||
|
|
@ -179,7 +184,7 @@ def IterStep.successor : IterStep α β → Option α
|
|||
If present, applies `f` to the iterator of an `IterStep` and replaces the iterator
|
||||
with the result of the application of `f`.
|
||||
-/
|
||||
@[always_inline, inline]
|
||||
@[always_inline, inline, expose]
|
||||
def IterStep.mapIterator {α' : Type u'} (f : α → α') : IterStep α β → IterStep α' β
|
||||
| .yield it out => .yield (f it) out
|
||||
| .skip it => .skip (f it)
|
||||
|
|
@ -224,12 +229,13 @@ of another state. Having this proof bundled up with the step is important for te
|
|||
|
||||
See `IterM.Step` and `Iter.Step` for the concrete choice of the plausibility predicate.
|
||||
-/
|
||||
@[expose]
|
||||
def PlausibleIterStep (IsPlausibleStep : IterStep α β → Prop) := Subtype IsPlausibleStep
|
||||
|
||||
/--
|
||||
Match pattern for the `yield` case. See also `IterStep.yield`.
|
||||
-/
|
||||
@[match_pattern, simp]
|
||||
@[match_pattern, simp, expose]
|
||||
def PlausibleIterStep.yield {IsPlausibleStep : IterStep α β → Prop}
|
||||
(it' : α) (out : β) (h : IsPlausibleStep (.yield it' out)) :
|
||||
PlausibleIterStep IsPlausibleStep :=
|
||||
|
|
@ -238,7 +244,7 @@ def PlausibleIterStep.yield {IsPlausibleStep : IterStep α β → Prop}
|
|||
/--
|
||||
Match pattern for the `skip` case. See also `IterStep.skip`.
|
||||
-/
|
||||
@[match_pattern, simp]
|
||||
@[match_pattern, simp, expose]
|
||||
def PlausibleIterStep.skip {IsPlausibleStep : IterStep α β → Prop}
|
||||
(it' : α) (h : IsPlausibleStep (.skip it')) : PlausibleIterStep IsPlausibleStep :=
|
||||
⟨.skip it', h⟩
|
||||
|
|
@ -246,7 +252,7 @@ def PlausibleIterStep.skip {IsPlausibleStep : IterStep α β → Prop}
|
|||
/--
|
||||
Match pattern for the `done` case. See also `IterStep.done`.
|
||||
-/
|
||||
@[match_pattern, simp]
|
||||
@[match_pattern, simp, expose]
|
||||
def PlausibleIterStep.done {IsPlausibleStep : IterStep α β → Prop}
|
||||
(h : IsPlausibleStep .done) : PlausibleIterStep IsPlausibleStep :=
|
||||
⟨.done, h⟩
|
||||
|
|
@ -283,7 +289,7 @@ section Monadic
|
|||
/--
|
||||
Converts wraps the state of an iterator into an `IterM` object.
|
||||
-/
|
||||
@[always_inline, inline]
|
||||
@[always_inline, inline, expose]
|
||||
def toIterM {α : Type w} (it : α) (m : Type w → Type w') (β : Type w) :
|
||||
IterM (α := α) m β :=
|
||||
⟨it⟩
|
||||
|
|
@ -302,6 +308,7 @@ theorem internalState_toIterM {α m β} (it : α) :
|
|||
Asserts that certain step is plausibly the successor of a given iterator. What "plausible" means
|
||||
is up to the `Iterator` instance but it should be strong enough to allow termination proofs.
|
||||
-/
|
||||
@[expose]
|
||||
abbrev IterM.IsPlausibleStep {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β] :
|
||||
IterM (α := α) m β → IterStep (IterM (α := α) m β) β → Prop :=
|
||||
Iterator.IsPlausibleStep (α := α) (m := m)
|
||||
|
|
@ -310,6 +317,7 @@ abbrev IterM.IsPlausibleStep {α : Type w} {m : Type w → Type w'} {β : Type w
|
|||
The type of the step object returned by `IterM.step`, containing an `IterStep`
|
||||
and a proof that this is a plausible step for the given iterator.
|
||||
-/
|
||||
@[expose]
|
||||
abbrev IterM.Step {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
|
||||
(it : IterM (α := α) m β) :=
|
||||
PlausibleIterStep it.IsPlausibleStep
|
||||
|
|
@ -318,6 +326,7 @@ abbrev IterM.Step {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator
|
|||
Asserts that a certain output value could plausibly be emitted by the given iterator in its next
|
||||
step.
|
||||
-/
|
||||
@[expose]
|
||||
def IterM.IsPlausibleOutput {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
|
||||
(it : IterM (α := α) m β) (out : β) : Prop :=
|
||||
∃ it', it.IsPlausibleStep (.yield it' out)
|
||||
|
|
@ -326,6 +335,7 @@ def IterM.IsPlausibleOutput {α : Type w} {m : Type w → Type w'} {β : Type w}
|
|||
Asserts that a certain iterator `it'` could plausibly be the directly succeeding iterator of another
|
||||
given iterator `it`.
|
||||
-/
|
||||
@[expose]
|
||||
def IterM.IsPlausibleSuccessorOf {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
|
||||
(it' it : IterM (α := α) m β) : Prop :=
|
||||
∃ step, step.successor = some it' ∧ it.IsPlausibleStep step
|
||||
|
|
@ -334,6 +344,7 @@ def IterM.IsPlausibleSuccessorOf {α : Type w} {m : Type w → Type w'} {β : Ty
|
|||
Asserts that a certain iterator `it'` could plausibly be the directly succeeding iterator of another
|
||||
given iterator `it` while no value is emitted (see `IterStep.skip`).
|
||||
-/
|
||||
@[expose]
|
||||
def IterM.IsPlausibleSkipSuccessorOf {α : Type w} {m : Type w → Type w'} {β : Type w}
|
||||
[Iterator α m β] (it' it : IterM (α := α) m β) : Prop :=
|
||||
it.IsPlausibleStep (.skip it')
|
||||
|
|
@ -356,6 +367,7 @@ section Pure
|
|||
Asserts that certain step is plausibly the successor of a given iterator. What "plausible" means
|
||||
is up to the `Iterator` instance but it should be strong enough to allow termination proofs.
|
||||
-/
|
||||
@[expose]
|
||||
def Iter.IsPlausibleStep {α : Type w} {β : Type w} [Iterator α Id β]
|
||||
(it : Iter (α := α) β) (step : IterStep (Iter (α := α) β) β) : Prop :=
|
||||
it.toIterM.IsPlausibleStep (step.mapIterator Iter.toIterM)
|
||||
|
|
@ -364,6 +376,7 @@ def Iter.IsPlausibleStep {α : Type w} {β : Type w} [Iterator α Id β]
|
|||
The type of the step object returned by `Iter.step`, containing an `IterStep`
|
||||
and a proof that this is a plausible step for the given iterator.
|
||||
-/
|
||||
@[expose]
|
||||
def Iter.Step {α : Type w} {β : Type w} [Iterator α Id β] (it : Iter (α := α) β) :=
|
||||
PlausibleIterStep (Iter.IsPlausibleStep it)
|
||||
|
||||
|
|
@ -378,7 +391,7 @@ def Iter.Step.toMonadic {α : Type w} {β : Type w} [Iterator α Id β] {it : It
|
|||
/--
|
||||
Converts an `IterM.Step` into an `Iter.Step`.
|
||||
-/
|
||||
@[always_inline, inline]
|
||||
@[always_inline, inline, expose]
|
||||
def IterM.Step.toPure {α : Type w} {β : Type w} [Iterator α Id β] {it : IterM (α := α) Id β}
|
||||
(step : it.Step) : it.toIter.Step :=
|
||||
⟨step.val.mapIterator IterM.toIter, (by simp [Iter.IsPlausibleStep, step.property])⟩
|
||||
|
|
@ -402,6 +415,7 @@ theorem IterM.Step.toPure_done {α β : Type w} [Iterator α Id β] {it : IterM
|
|||
Asserts that a certain output value could plausibly be emitted by the given iterator in its next
|
||||
step.
|
||||
-/
|
||||
@[expose]
|
||||
def Iter.IsPlausibleOutput {α : Type w} {β : Type w} [Iterator α Id β]
|
||||
(it : Iter (α := α) β) (out : β) : Prop :=
|
||||
it.toIterM.IsPlausibleOutput out
|
||||
|
|
@ -410,6 +424,7 @@ def Iter.IsPlausibleOutput {α : Type w} {β : Type w} [Iterator α Id β]
|
|||
Asserts that a certain iterator `it'` could plausibly be the directly succeeding iterator of another
|
||||
given iterator `it`.
|
||||
-/
|
||||
@[expose]
|
||||
def Iter.IsPlausibleSuccessorOf {α : Type w} {β : Type w} [Iterator α Id β]
|
||||
(it' it : Iter (α := α) β) : Prop :=
|
||||
it'.toIterM.IsPlausibleSuccessorOf it.toIterM
|
||||
|
|
@ -427,7 +442,7 @@ Makes a single step with the given iterator `it`, potentially emitting a value a
|
|||
succeeding iterator. If this function is used recursively, termination can sometimes be proved with
|
||||
the termination measures `it.finitelyManySteps` and `it.finitelyManySkips`.
|
||||
-/
|
||||
@[always_inline, inline]
|
||||
@[always_inline, inline, expose]
|
||||
def Iter.step {α β : Type w} [Iterator α Id β] (it : Iter (α := α) β) : it.Step :=
|
||||
it.toIterM.step.run.toPure
|
||||
|
||||
|
|
@ -456,6 +471,7 @@ structure IterM.TerminationMeasures.Finite
|
|||
The relation of plausible successors on `IterM.TerminationMeasures.Finite`. It is well-founded
|
||||
if there is a `Finite` instance.
|
||||
-/
|
||||
@[expose]
|
||||
def IterM.TerminationMeasures.Finite.Rel
|
||||
{α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β] :
|
||||
TerminationMeasures.Finite α m → TerminationMeasures.Finite α m → Prop :=
|
||||
|
|
@ -464,12 +480,13 @@ def IterM.TerminationMeasures.Finite.Rel
|
|||
instance {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
|
||||
[Finite α m] : WellFoundedRelation (IterM.TerminationMeasures.Finite α m) where
|
||||
rel := IterM.TerminationMeasures.Finite.Rel
|
||||
wf := (InvImage.wf _ Finite.wf).transGen
|
||||
wf := by exact (InvImage.wf _ Finite.wf).transGen
|
||||
|
||||
/--
|
||||
Termination measure to be used in well-founded recursive functions recursing over a finite iterator
|
||||
(see also `Finite`).
|
||||
-/
|
||||
@[expose]
|
||||
def IterM.finitelyManySteps {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
|
||||
[Finite α m] (it : IterM (α := α) m β) : IterM.TerminationMeasures.Finite α m :=
|
||||
⟨it⟩
|
||||
|
|
@ -494,9 +511,10 @@ theorem IterM.TerminationMeasures.Finite.rel_of_skip
|
|||
macro_rules | `(tactic| decreasing_trivial) => `(tactic|
|
||||
first
|
||||
| exact IterM.TerminationMeasures.Finite.rel_of_yield ‹_›
|
||||
| exact IterM.TerminationMeasures.Finite.rel_of_skip ‹_›)
|
||||
| exact IterM.TerminationMeasures.Finite.rel_of_skip ‹_›
|
||||
| fail)
|
||||
|
||||
@[inherit_doc IterM.finitelyManySteps]
|
||||
@[inherit_doc IterM.finitelyManySteps, expose]
|
||||
def Iter.finitelyManySteps {α : Type w} {β : Type w} [Iterator α Id β] [Finite α Id]
|
||||
(it : Iter (α := α) β) : IterM.TerminationMeasures.Finite α Id :=
|
||||
it.toIterM.finitelyManySteps
|
||||
|
|
@ -521,7 +539,8 @@ theorem Iter.TerminationMeasures.Finite.rel_of_skip
|
|||
macro_rules | `(tactic| decreasing_trivial) => `(tactic|
|
||||
first
|
||||
| exact Iter.TerminationMeasures.Finite.rel_of_yield ‹_›
|
||||
| exact Iter.TerminationMeasures.Finite.rel_of_skip ‹_›)
|
||||
| exact Iter.TerminationMeasures.Finite.rel_of_skip ‹_›
|
||||
| fail)
|
||||
|
||||
theorem IterM.isPlausibleSuccessorOf_of_yield
|
||||
{α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
|
||||
|
|
@ -561,6 +580,7 @@ structure IterM.TerminationMeasures.Productive
|
|||
The relation of plausible successors while skipping on `IterM.TerminationMeasures.Productive`.
|
||||
It is well-founded if there is a `Productive` instance.
|
||||
-/
|
||||
@[expose]
|
||||
def IterM.TerminationMeasures.Productive.Rel
|
||||
{α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β] :
|
||||
TerminationMeasures.Productive α m → TerminationMeasures.Productive α m → Prop :=
|
||||
|
|
@ -569,12 +589,13 @@ def IterM.TerminationMeasures.Productive.Rel
|
|||
instance {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
|
||||
[Productive α m] : WellFoundedRelation (IterM.TerminationMeasures.Productive α m) where
|
||||
rel := IterM.TerminationMeasures.Productive.Rel
|
||||
wf := (InvImage.wf _ Productive.wf).transGen
|
||||
wf := by exact (InvImage.wf _ Productive.wf).transGen
|
||||
|
||||
/--
|
||||
Termination measure to be used in well-founded recursive functions recursing over a productive
|
||||
iterator (see also `Productive`).
|
||||
-/
|
||||
@[expose]
|
||||
def IterM.finitelyManySkips {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
|
||||
[Productive α m] (it : IterM (α := α) m β) : IterM.TerminationMeasures.Productive α m :=
|
||||
⟨it⟩
|
||||
|
|
@ -590,9 +611,11 @@ theorem IterM.TerminationMeasures.Productive.rel_of_skip
|
|||
.single h
|
||||
|
||||
macro_rules | `(tactic| decreasing_trivial) => `(tactic|
|
||||
exact IterM.TerminationMeasures.Productive.rel_of_skip ‹_›)
|
||||
first
|
||||
| exact IterM.TerminationMeasures.Productive.rel_of_skip ‹_›
|
||||
| fail)
|
||||
|
||||
@[inherit_doc IterM.finitelyManySkips]
|
||||
@[inherit_doc IterM.finitelyManySkips, expose]
|
||||
def Iter.finitelyManySkips {α : Type w} {β : Type w} [Iterator α Id β] [Productive α Id]
|
||||
(it : Iter (α := α) β) : IterM.TerminationMeasures.Productive α Id :=
|
||||
it.toIterM.finitelyManySkips
|
||||
|
|
@ -608,7 +631,9 @@ theorem Iter.TerminationMeasures.Productive.rel_of_skip
|
|||
IterM.TerminationMeasures.Productive.rel_of_skip h
|
||||
|
||||
macro_rules | `(tactic| decreasing_trivial) => `(tactic|
|
||||
exact Iter.TerminationMeasures.Productive.rel_of_skip ‹_›)
|
||||
first
|
||||
| exact Iter.TerminationMeasures.Productive.rel_of_skip ‹_›
|
||||
| fail)
|
||||
|
||||
instance [Iterator α m β] [Finite α m] : Productive α m where
|
||||
wf := by
|
||||
13
src/Init/Data/Iterators/Consumers.lean
Normal file
13
src/Init/Data/Iterators/Consumers.lean
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/-
|
||||
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
|
||||
import Init.Data.Iterators.Consumers.Monadic
|
||||
import Init.Data.Iterators.Consumers.Access
|
||||
import Init.Data.Iterators.Consumers.Collect
|
||||
import Init.Data.Iterators.Consumers.Loop
|
||||
import Init.Data.Iterators.Consumers.Partial
|
||||
|
|
@ -3,8 +3,10 @@ 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
|
||||
import Std.Data.Iterators.Consumers.Partial
|
||||
import Init.Data.Iterators.Consumers.Partial
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
@ -3,10 +3,12 @@ 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
|
||||
import Std.Data.Iterators.Basic
|
||||
import Std.Data.Iterators.Consumers.Partial
|
||||
import Std.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Consumers.Partial
|
||||
import Init.Data.Iterators.Consumers.Monadic.Collect
|
||||
|
||||
/-!
|
||||
# Collectors
|
||||
|
|
@ -3,9 +3,11 @@ 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
|
||||
import Std.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Std.Data.Iterators.Consumers.Partial
|
||||
import Init.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Init.Data.Iterators.Consumers.Partial
|
||||
|
||||
/-!
|
||||
# Loop consumers
|
||||
11
src/Init/Data/Iterators/Consumers/Monadic.lean
Normal file
11
src/Init/Data/Iterators/Consumers/Monadic.lean
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/-
|
||||
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
|
||||
import Init.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Init.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Init.Data.Iterators.Consumers.Monadic.Partial
|
||||
|
|
@ -3,9 +3,11 @@ 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
|
||||
import Std.Data.Iterators.Consumers.Monadic.Partial
|
||||
import Std.Data.Internal.LawfulMonadLiftFunction
|
||||
import Init.Data.Iterators.Consumers.Monadic.Partial
|
||||
import Init.Data.Iterators.Internal.LawfulMonadLiftFunction
|
||||
|
||||
/-!
|
||||
# Collectors
|
||||
|
|
@ -3,10 +3,12 @@ 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
|
||||
import Init.RCases
|
||||
import Std.Data.Iterators.Basic
|
||||
import Std.Data.Iterators.Consumers.Monadic.Partial
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Consumers.Monadic.Partial
|
||||
|
||||
/-!
|
||||
# Loop-based consumers
|
||||
|
|
@ -62,8 +64,9 @@ class IteratorLoop (α : Type w) (m : Type w → Type w') {β : Type w} [Iterato
|
|||
forIn : ∀ (_lift : (γ : Type w) → m γ → n γ) (γ : Type w),
|
||||
(plausible_forInStep : β → γ → ForInStep γ → Prop) →
|
||||
IteratorLoop.WellFounded α m plausible_forInStep →
|
||||
IterM (α := α) m β → γ →
|
||||
((b : β) → (c : γ) → n (Subtype (plausible_forInStep b c))) → n γ
|
||||
(it : IterM (α := α) m β) → γ →
|
||||
((b : β) → (c : γ) → n (Subtype (plausible_forInStep b c))) →
|
||||
n γ
|
||||
|
||||
/--
|
||||
`IteratorLoopPartial α m` provides efficient implementations of loop-based consumers for `α`-based
|
||||
|
|
@ -76,7 +79,8 @@ provided by the standard library.
|
|||
class IteratorLoopPartial (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β]
|
||||
(n : Type w → Type w'') where
|
||||
forInPartial : ∀ (_lift : (γ : Type w) → m γ → n γ) {γ : Type w},
|
||||
IterM (α := α) m β → γ → ((b : β) → (c : γ) → n (ForInStep γ)) → n γ
|
||||
(it : IterM (α := α) m β) → γ →
|
||||
((b : β) → (c : γ) → n (ForInStep γ)) → n γ
|
||||
|
||||
end Typeclasses
|
||||
|
||||
|
|
@ -91,7 +95,7 @@ private def IteratorLoop.WFRel.mk {α : Type w} {m : Type w → Type w'} {β : T
|
|||
IteratorLoop.WFRel wf :=
|
||||
(it, c)
|
||||
|
||||
instance {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
|
||||
private instance {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
|
||||
{γ : Type x} {plausible_forInStep : β → γ → ForInStep γ → Prop}
|
||||
(wf : IteratorLoop.WellFounded α m plausible_forInStep) :
|
||||
WellFoundedRelation (IteratorLoop.WFRel wf) where
|
||||
|
|
@ -116,9 +120,13 @@ def IterM.DefaultConsumers.forIn {m : Type w → Type w'} {α : Type w} {β : Ty
|
|||
match ← it.step with
|
||||
| .yield it' out _ =>
|
||||
match ← f out init with
|
||||
| ⟨.yield c, _⟩ => IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' c f
|
||||
| ⟨.yield c, _⟩ =>
|
||||
IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' c
|
||||
(fun out acc => f out acc)
|
||||
| ⟨.done c, _⟩ => return c
|
||||
| .skip it' _ => IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' init f
|
||||
| .skip it' _ =>
|
||||
IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' init
|
||||
(fun out acc => f out acc)
|
||||
| .done _ => return init
|
||||
termination_by IteratorLoop.WFRel.mk wf it init
|
||||
decreasing_by
|
||||
|
|
@ -159,9 +167,13 @@ partial def IterM.DefaultConsumers.forInPartial {m : Type w → Type w'} {α : T
|
|||
match ← it.step with
|
||||
| .yield it' out _ =>
|
||||
match ← f out init with
|
||||
| .yield c => IterM.DefaultConsumers.forInPartial lift _ it' c f
|
||||
| .yield c =>
|
||||
IterM.DefaultConsumers.forInPartial lift _ it' c
|
||||
fun out acc => f out acc
|
||||
| .done c => return c
|
||||
| .skip it' _ => IterM.DefaultConsumers.forInPartial lift _ it' init f
|
||||
| .skip it' _ =>
|
||||
IterM.DefaultConsumers.forInPartial lift _ it' init
|
||||
fun out acc => f out acc
|
||||
| .done _ => return init
|
||||
|
||||
/--
|
||||
|
|
@ -206,12 +218,13 @@ def IteratorLoop.finiteForIn {m : Type w → Type w'} {n : Type w → Type w''}
|
|||
forIn {γ} [Monad n] it init f :=
|
||||
IteratorLoop.forIn (α := α) (m := m) lift γ (fun _ _ _ => True)
|
||||
wellFounded_of_finite
|
||||
it init ((⟨·, .intro⟩) <$> f · ·)
|
||||
it init (fun out acc => (⟨·, .intro⟩) <$> f out acc)
|
||||
|
||||
instance {m : Type w → Type w'} {n : Type w → Type w''}
|
||||
{α : Type w} {β : Type w} [Iterator α m β] [Finite α m] [IteratorLoop α m n]
|
||||
[MonadLiftT m n] :
|
||||
ForIn n (IterM (α := α) m β) β := IteratorLoop.finiteForIn (fun _ => monadLift)
|
||||
ForIn n (IterM (α := α) m β) β :=
|
||||
IteratorLoop.finiteForIn (fun _ => monadLift)
|
||||
|
||||
instance {m : Type w → Type w'} {n : Type w → Type w''}
|
||||
{α : Type w} {β : Type w} [Iterator α m β] [IteratorLoopPartial α m n] [MonadLiftT m n] :
|
||||
|
|
@ -3,8 +3,10 @@ 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
|
||||
import Std.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Basic
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
@ -3,8 +3,10 @@ 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
|
||||
import Std.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Basic
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
10
src/Init/Data/Iterators/Internal.lean
Normal file
10
src/Init/Data/Iterators/Internal.lean
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/-
|
||||
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
|
||||
import Init.Data.Iterators.Internal.LawfulMonadLiftFunction
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
|
|
@ -3,6 +3,8 @@ 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
|
||||
import Init.Control.Basic
|
||||
import Init.Control.Lawful.Basic
|
||||
|
|
@ -3,8 +3,10 @@ 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
|
||||
import Std.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Basic
|
||||
|
||||
/-!
|
||||
This is an internal module used by iterator implementations.
|
||||
|
|
@ -3,5 +3,7 @@ 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
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.Lemmas.Consumers
|
||||
|
|
@ -3,8 +3,10 @@ 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
|
||||
import Std.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Basic
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
11
src/Init/Data/Iterators/Lemmas/Consumers.lean
Normal file
11
src/Init/Data/Iterators/Lemmas/Consumers.lean
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/-
|
||||
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
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Collect
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Loop
|
||||
114
src/Init/Data/Iterators/Lemmas/Consumers/Collect.lean
Normal file
114
src/Init/Data/Iterators/Lemmas/Consumers/Collect.lean
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/-
|
||||
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
|
||||
import Init.Data.Iterators.Lemmas.Basic
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic.Collect
|
||||
import all Init.Data.Iterators.Consumers.Access
|
||||
import all Init.Data.Iterators.Consumers.Collect
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
theorem Iter.toArray_eq_toArray_toIterM {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toArray = it.toIterM.toArray.run :=
|
||||
(rfl)
|
||||
|
||||
theorem Iter.toList_eq_toList_toIterM {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toList = it.toIterM.toList.run :=
|
||||
(rfl)
|
||||
|
||||
theorem Iter.toListRev_eq_toListRev_toIterM {α β} [Iterator α Id β] [Finite α Id]
|
||||
{it : Iter (α := α) β} :
|
||||
it.toListRev = it.toIterM.toListRev.run :=
|
||||
(rfl)
|
||||
|
||||
@[simp]
|
||||
theorem IterM.toList_toIter {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
{it : IterM (α := α) Id β} :
|
||||
it.toIter.toList = it.toList.run :=
|
||||
(rfl)
|
||||
|
||||
@[simp]
|
||||
theorem IterM.toListRev_toIter {α β} [Iterator α Id β] [Finite α Id]
|
||||
{it : IterM (α := α) Id β} :
|
||||
it.toIter.toListRev = it.toListRev.run :=
|
||||
(rfl)
|
||||
|
||||
theorem Iter.toList_toArray {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toArray.toList = it.toList := by
|
||||
simp [toArray_eq_toArray_toIterM, toList_eq_toList_toIterM, ← IterM.toList_toArray]
|
||||
|
||||
theorem Iter.toArray_toList {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toList.toArray = it.toArray := by
|
||||
simp [toArray_eq_toArray_toIterM, toList_eq_toList_toIterM, ← IterM.toArray_toList]
|
||||
|
||||
@[simp]
|
||||
theorem Iter.reverse_toListRev [Iterator α Id β] [Finite α Id]
|
||||
[IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{it : Iter (α := α) β} :
|
||||
it.toListRev.reverse = it.toList := by
|
||||
simp [toListRev_eq_toListRev_toIterM, toList_eq_toList_toIterM, ← IterM.reverse_toListRev]
|
||||
|
||||
theorem Iter.toListRev_eq {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toListRev = it.toList.reverse := by
|
||||
simp [Iter.toListRev_eq_toListRev_toIterM, Iter.toList_eq_toList_toIterM, IterM.toListRev_eq]
|
||||
|
||||
theorem Iter.toArray_eq_match_step {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toArray = match it.step with
|
||||
| .yield it' out _ => #[out] ++ it'.toArray
|
||||
| .skip it' _ => it'.toArray
|
||||
| .done _ => #[] := by
|
||||
simp only [Iter.toArray_eq_toArray_toIterM, Iter.step]
|
||||
rw [IterM.toArray_eq_match_step, Id.run_bind]
|
||||
generalize it.toIterM.step.run = step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp
|
||||
|
||||
theorem Iter.toList_eq_match_step {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toList = match it.step with
|
||||
| .yield it' out _ => out :: it'.toList
|
||||
| .skip it' _ => it'.toList
|
||||
| .done _ => [] := by
|
||||
rw [← Iter.toList_toArray, Iter.toArray_eq_match_step]
|
||||
split <;> simp [Iter.toList_toArray]
|
||||
|
||||
theorem Iter.toListRev_eq_match_step {α β} [Iterator α Id β] [Finite α Id] {it : Iter (α := α) β} :
|
||||
it.toListRev = match it.step with
|
||||
| .yield it' out _ => it'.toListRev ++ [out]
|
||||
| .skip it' _ => it'.toListRev
|
||||
| .done _ => [] := by
|
||||
rw [Iter.toListRev_eq_toListRev_toIterM, IterM.toListRev_eq_match_step, Iter.step, Id.run_bind]
|
||||
generalize it.toIterM.step.run = step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp
|
||||
|
||||
theorem Iter.getElem?_toList_eq_atIdxSlow? {α β}
|
||||
[Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{it : Iter (α := α) β} {k : Nat} :
|
||||
it.toList[k]? = it.atIdxSlow? k := by
|
||||
induction it using Iter.inductSteps generalizing k with | step it ihy ihs =>
|
||||
rw [toList_eq_match_step, atIdxSlow?]
|
||||
obtain ⟨step, h⟩ := it.step
|
||||
cases step
|
||||
· cases k <;> simp [ihy h]
|
||||
· simp [ihs h]
|
||||
· simp
|
||||
|
||||
theorem Iter.toList_eq_of_atIdxSlow?_eq {α₁ α₂ β}
|
||||
[Iterator α₁ Id β] [Finite α₁ Id] [IteratorCollect α₁ Id Id] [LawfulIteratorCollect α₁ Id Id]
|
||||
[Iterator α₂ Id β] [Finite α₂ Id] [IteratorCollect α₂ Id Id] [LawfulIteratorCollect α₂ Id Id]
|
||||
{it₁ : Iter (α := α₁) β} {it₂ : Iter (α := α₂) β}
|
||||
(h : ∀ k, it₁.atIdxSlow? k = it₂.atIdxSlow? k) :
|
||||
it₁.toList = it₂.toList := by
|
||||
ext; simp [getElem?_toList_eq_atIdxSlow?, h]
|
||||
|
||||
end Std.Iterators
|
||||
180
src/Init/Data/Iterators/Lemmas/Consumers/Loop.lean
Normal file
180
src/Init/Data/Iterators/Lemmas/Consumers/Loop.lean
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
/-
|
||||
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
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Collect
|
||||
import all Init.Data.Iterators.Lemmas.Consumers.Monadic.Loop
|
||||
import all Init.Data.Iterators.Consumers.Loop
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
theorem Iter.forIn_eq {α β : Type w} [Iterator α Id β] [Finite α Id]
|
||||
{m : Type w → Type w''} [Monad m] [IteratorLoop α Id m] [hl : LawfulIteratorLoop α Id m]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ}
|
||||
{f : (b : β) → γ → m (ForInStep γ)} :
|
||||
ForIn.forIn it init f =
|
||||
IterM.DefaultConsumers.forIn (fun _ c => pure c.run) γ (fun _ _ _ => True)
|
||||
IteratorLoop.wellFounded_of_finite it.toIterM init
|
||||
(fun out acc => (⟨·, .intro⟩) <$>
|
||||
f out acc) := by
|
||||
cases hl.lawful; rfl
|
||||
|
||||
theorem Iter.forIn_eq_forIn_toIterM {α β : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
|
||||
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ}
|
||||
{f : β → γ → m (ForInStep γ)} :
|
||||
ForIn.forIn it init f =
|
||||
letI : MonadLift Id m := ⟨Std.Internal.idToMonad (α := _)⟩
|
||||
ForIn.forIn it.toIterM init f := by
|
||||
rfl
|
||||
|
||||
theorem Iter.forIn_eq_match_step {α β : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
|
||||
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ}
|
||||
{f : β → γ → m (ForInStep γ)} :
|
||||
ForIn.forIn it init f = (do
|
||||
match it.step with
|
||||
| .yield it' out _ =>
|
||||
match ← f out init with
|
||||
| .yield c => ForIn.forIn it' c f
|
||||
| .done c => return c
|
||||
| .skip it' _ => ForIn.forIn it' init f
|
||||
| .done _ => return init) := by
|
||||
rw [Iter.forIn_eq_forIn_toIterM, @IterM.forIn_eq_match_step, Iter.step]
|
||||
simp only [liftM, monadLift, pure_bind]
|
||||
generalize it.toIterM.step = step
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· apply bind_congr
|
||||
intro forInStep
|
||||
rfl
|
||||
· rfl
|
||||
· rfl
|
||||
|
||||
theorem Iter.forIn_toList {α β : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
|
||||
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
[IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ}
|
||||
{f : β → γ → m (ForInStep γ)} :
|
||||
ForIn.forIn it.toList init f = ForIn.forIn it init f := by
|
||||
rw [List.forIn_eq_foldlM]
|
||||
induction it using Iter.inductSteps generalizing init with case step it ihy ihs =>
|
||||
rw [forIn_eq_match_step, Iter.toList_eq_match_step]
|
||||
simp only [map_eq_pure_bind]
|
||||
generalize it.step = step
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· rename_i it' out h
|
||||
simp only [List.foldlM_cons, bind_pure_comp, map_bind]
|
||||
apply bind_congr
|
||||
intro forInStep
|
||||
cases forInStep
|
||||
· induction it'.toList <;> simp [*]
|
||||
· simp only [ForIn.forIn, forIn', List.forIn'] at ihy
|
||||
simp [ihy h, forIn_eq_forIn_toIterM]
|
||||
· rename_i it' h
|
||||
simp only [bind_pure_comp]
|
||||
rw [ihs h]
|
||||
· simp
|
||||
|
||||
theorem Iter.foldM_eq_forIn {α β γ : Type w} [Iterator α Id β] [Finite α Id] {m : Type w → Type w'}
|
||||
[Monad m] [IteratorLoop α Id m] {f : γ → β → m γ}
|
||||
{init : γ} {it : Iter (α := α) β} :
|
||||
it.foldM (init := init) f = ForIn.forIn it init (fun x acc => ForInStep.yield <$> f acc x) :=
|
||||
(rfl)
|
||||
|
||||
theorem Iter.foldM_eq_foldM_toIterM {α β : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
|
||||
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ} {f : γ → β → m γ} :
|
||||
it.foldM (init := init) f = letI : MonadLift Id m := ⟨pure⟩; it.toIterM.foldM (init := init) f :=
|
||||
(rfl)
|
||||
|
||||
theorem Iter.forIn_yield_eq_foldM {α β γ δ : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m] [IteratorLoop α Id m]
|
||||
[LawfulIteratorLoop α Id m] {f : β → γ → m δ} {g : β → γ → δ → γ} {init : γ}
|
||||
{it : Iter (α := α) β} :
|
||||
ForIn.forIn it init (fun c b => (fun d => .yield (g c b d)) <$> f c b) =
|
||||
it.foldM (fun b c => g c b <$> f c b) init := by
|
||||
simp [Iter.foldM_eq_forIn]
|
||||
|
||||
theorem Iter.foldM_eq_match_step {α β γ : Type w} [Iterator α Id β] [Finite α Id]
|
||||
{m : Type w → Type w'} [Monad m] [LawfulMonad m] [IteratorLoop α Id m]
|
||||
[LawfulIteratorLoop α Id m] {f : γ → β → m γ} {init : γ} {it : Iter (α := α) β} :
|
||||
it.foldM (init := init) f = (do
|
||||
match it.step with
|
||||
| .yield it' out _ => it'.foldM (init := ← f init out) f
|
||||
| .skip it' _ => it'.foldM (init := init) f
|
||||
| .done _ => return init) := by
|
||||
rw [Iter.foldM_eq_forIn, Iter.forIn_eq_match_step]
|
||||
generalize it.step = step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp [foldM_eq_forIn]
|
||||
|
||||
theorem Iter.foldlM_toList {α β γ : Type w} [Iterator α Id β] [Finite α Id] {m : Type w → Type w'}
|
||||
[Monad m] [LawfulMonad m] [IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
[IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{f : γ → β → m γ}
|
||||
{init : γ} {it : Iter (α := α) β} :
|
||||
it.toList.foldlM (init := init) f = it.foldM (init := init) f := by
|
||||
rw [Iter.foldM_eq_forIn, ← Iter.forIn_toList]
|
||||
simp only [List.forIn_yield_eq_foldlM, id_map']
|
||||
|
||||
theorem IterM.forIn_eq_foldM {α β : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
|
||||
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
[IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ}
|
||||
{f : β → γ → m (ForInStep γ)} :
|
||||
forIn it init f = ForInStep.value <$>
|
||||
it.foldM (fun c b => match c with
|
||||
| .yield c => f b c
|
||||
| .done c => pure (.done c)) (ForInStep.yield init) := by
|
||||
simp only [← Iter.forIn_toList, List.forIn_eq_foldlM, ← Iter.foldlM_toList]; rfl
|
||||
|
||||
theorem Iter.fold_eq_forIn {α β γ : Type w} [Iterator α Id β]
|
||||
[Finite α Id] [IteratorLoop α Id Id] {f : γ → β → γ} {init : γ} {it : Iter (α := α) β} :
|
||||
it.fold (init := init) f =
|
||||
(ForIn.forIn (m := Id) it init (fun x acc => pure (ForInStep.yield (f acc x)))).run := by
|
||||
rfl
|
||||
|
||||
theorem Iter.fold_eq_foldM {α β γ : Type w} [Iterator α Id β]
|
||||
[Finite α Id] [IteratorLoop α Id Id] {f : γ → β → γ} {init : γ}
|
||||
{it : Iter (α := α) β} :
|
||||
it.fold (init := init) f = (it.foldM (m := Id) (init := init) (pure <| f · ·)).run := by
|
||||
simp [foldM_eq_forIn, fold_eq_forIn]
|
||||
|
||||
@[simp]
|
||||
theorem Iter.forIn_pure_yield_eq_fold {α β γ : Type w} [Iterator α Id β]
|
||||
[Finite α Id] [IteratorLoop α Id Id]
|
||||
[LawfulIteratorLoop α Id Id] {f : β → γ → γ} {init : γ}
|
||||
{it : Iter (α := α) β} :
|
||||
ForIn.forIn (m := Id) it init (fun c b => pure (.yield (f c b))) =
|
||||
pure (it.fold (fun b c => f c b) init) := by
|
||||
simp only [fold_eq_forIn]
|
||||
rfl
|
||||
|
||||
theorem Iter.fold_eq_match_step {α β γ : Type w} [Iterator α Id β] [Finite α Id]
|
||||
[IteratorLoop α Id Id] [LawfulIteratorLoop α Id Id]
|
||||
{f : γ → β → γ} {init : γ} {it : Iter (α := α) β} :
|
||||
it.fold (init := init) f = (match it.step with
|
||||
| .yield it' out _ => it'.fold (init := f init out) f
|
||||
| .skip it' _ => it'.fold (init := init) f
|
||||
| .done _ => init) := by
|
||||
rw [fold_eq_foldM, foldM_eq_match_step]
|
||||
simp only [fold_eq_foldM]
|
||||
generalize it.step = step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp
|
||||
|
||||
theorem Iter.foldl_toList {α β γ : Type w} [Iterator α Id β] [Finite α Id]
|
||||
[IteratorLoop α Id Id] [LawfulIteratorLoop α Id Id]
|
||||
[IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{f : γ → β → γ} {init : γ} {it : Iter (α := α) β} :
|
||||
it.toList.foldl (init := init) f = it.fold (init := init) f := by
|
||||
rw [fold_eq_foldM, List.foldl_eq_foldlM, ← Iter.foldlM_toList]
|
||||
|
||||
end Std.Iterators
|
||||
|
|
@ -3,7 +3,8 @@ 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
|
||||
import Std.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Std.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Std.Data.Iterators.Consumers.Monadic.Partial
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic.Collect
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic.Loop
|
||||
157
src/Init/Data/Iterators/Lemmas/Consumers/Monadic/Collect.lean
Normal file
157
src/Init/Data/Iterators/Lemmas/Consumers/Monadic/Collect.lean
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/-
|
||||
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
|
||||
import Init.Data.Array.Lemmas
|
||||
import Init.Data.Iterators.Lemmas.Monadic.Basic
|
||||
import all Init.Data.Iterators.Consumers.Monadic.Collect
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
variable {α β γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''}
|
||||
{lift : ⦃δ : Type w⦄ → m δ → n δ} {f : β → n γ} {it : IterM (α := α) m β}
|
||||
|
||||
theorem IterM.DefaultConsumers.toArrayMapped.go.aux₁ [Monad n] [LawfulMonad n] [Iterator α m β]
|
||||
[Finite α m] {b : γ} {bs : Array γ} :
|
||||
IterM.DefaultConsumers.toArrayMapped.go lift f it (#[b] ++ bs) (m := m) =
|
||||
(#[b] ++ ·) <$> IterM.DefaultConsumers.toArrayMapped.go lift f it bs (m := m) := by
|
||||
induction it, bs using IterM.DefaultConsumers.toArrayMapped.go.induct
|
||||
next it bs ih₁ ih₂ =>
|
||||
rw [go, map_eq_pure_bind, go, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
split
|
||||
· simp [ih₁ _ _ ‹_›]
|
||||
· simp [ih₂ _ ‹_›]
|
||||
· simp
|
||||
|
||||
theorem IterM.DefaultConsumers.toArrayMapped.go.aux₂ [Monad n] [LawfulMonad n] [Iterator α m β]
|
||||
[Finite α m] {acc : Array γ} :
|
||||
IterM.DefaultConsumers.toArrayMapped.go lift f it acc (m := m) =
|
||||
(acc ++ ·) <$> IterM.DefaultConsumers.toArrayMapped lift f it (m := m) := by
|
||||
rw [← Array.toArray_toList (xs := acc)]
|
||||
generalize acc.toList = acc
|
||||
induction acc with
|
||||
| nil => simp [toArrayMapped]
|
||||
| cons x xs ih =>
|
||||
rw [List.toArray_cons, IterM.DefaultConsumers.toArrayMapped.go.aux₁, ih]
|
||||
simp only [Functor.map_map, Array.append_assoc]
|
||||
|
||||
theorem IterM.DefaultConsumers.toArrayMapped_eq_match_step [Monad n] [LawfulMonad n]
|
||||
[Iterator α m β] [Finite α m] :
|
||||
IterM.DefaultConsumers.toArrayMapped lift f it (m := m) = letI : MonadLift m n := ⟨lift (δ := _)⟩; (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ =>
|
||||
return #[← f out] ++ (← IterM.DefaultConsumers.toArrayMapped lift f it' (m := m))
|
||||
| .skip it' _ => IterM.DefaultConsumers.toArrayMapped lift f it' (m := m)
|
||||
| .done _ => return #[]) := by
|
||||
rw [IterM.DefaultConsumers.toArrayMapped, IterM.DefaultConsumers.toArrayMapped.go]
|
||||
apply bind_congr
|
||||
intro step
|
||||
split <;> simp [IterM.DefaultConsumers.toArrayMapped.go.aux₂]
|
||||
|
||||
theorem IterM.toArray_eq_match_step [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m] :
|
||||
it.toArray = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ => return #[out] ++ (← it'.toArray)
|
||||
| .skip it' _ => it'.toArray
|
||||
| .done _ => return #[]) := by
|
||||
simp only [IterM.toArray, LawfulIteratorCollect.toArrayMapped_eq]
|
||||
rw [IterM.DefaultConsumers.toArrayMapped_eq_match_step]
|
||||
simp [bind_pure_comp, pure_bind, toArray]
|
||||
|
||||
theorem IterM.toList_toArray [Monad m] [Iterator α m β] [Finite α m] [IteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
Array.toList <$> it.toArray = it.toList := by
|
||||
simp [IterM.toList]
|
||||
|
||||
theorem IterM.toArray_toList [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
[IteratorCollect α m m] {it : IterM (α := α) m β} :
|
||||
List.toArray <$> it.toList = it.toArray := by
|
||||
simp [IterM.toList]
|
||||
|
||||
theorem IterM.toList_eq_match_step [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m] {it : IterM (α := α) m β} :
|
||||
it.toList = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ => return out :: (← it'.toList)
|
||||
| .skip it' _ => it'.toList
|
||||
| .done _ => return []) := by
|
||||
simp [← IterM.toList_toArray]
|
||||
rw [IterM.toArray_eq_match_step, map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
split <;> simp
|
||||
|
||||
theorem IterM.toListRev.go.aux₁ [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
{it : IterM (α := α) m β} {b : β} {bs : List β} :
|
||||
IterM.toListRev.go it (bs ++ [b]) = (· ++ [b]) <$> IterM.toListRev.go it bs:= by
|
||||
induction it, bs using IterM.toListRev.go.induct
|
||||
next it bs ih₁ ih₂ =>
|
||||
rw [go, go, map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
simp only [List.cons_append] at ih₁
|
||||
split <;> simp [*]
|
||||
|
||||
theorem IterM.toListRev.go.aux₂ [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
{it : IterM (α := α) m β} {acc : List β} :
|
||||
IterM.toListRev.go it acc = (· ++ acc) <$> it.toListRev := by
|
||||
rw [← List.reverse_reverse (as := acc)]
|
||||
generalize acc.reverse = acc
|
||||
induction acc with
|
||||
| nil => simp [toListRev]
|
||||
| cons x xs ih => simp [IterM.toListRev.go.aux₁, ih]
|
||||
|
||||
theorem IterM.toListRev_eq_match_step [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.toListRev = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ => return (← it'.toListRev) ++ [out]
|
||||
| .skip it' _ => it'.toListRev
|
||||
| .done _ => return []) := by
|
||||
simp [IterM.toListRev]
|
||||
rw [toListRev.go]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp [IterM.toListRev.go.aux₂]
|
||||
|
||||
theorem IterM.reverse_toListRev [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
List.reverse <$> it.toListRev = it.toList := by
|
||||
apply Eq.symm
|
||||
induction it using IterM.inductSteps
|
||||
rename_i it ihy ihs
|
||||
rw [toListRev_eq_match_step, toList_eq_match_step, map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
split <;> simp (discharger := assumption) [ihy, ihs]
|
||||
|
||||
theorem IterM.toListRev_eq [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.toListRev = List.reverse <$> it.toList := by
|
||||
rw [← IterM.reverse_toListRev]
|
||||
simp
|
||||
|
||||
theorem LawfulIteratorCollect.toArray_eq {α β : Type w} {m : Type w → Type w'}
|
||||
[Monad m] [Iterator α m β] [Finite α m] [IteratorCollect α m m]
|
||||
[hl : LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.toArray = (letI : IteratorCollect α m m := .defaultImplementation; it.toArray) := by
|
||||
simp only [IterM.toArray, toArrayMapped_eq]
|
||||
|
||||
theorem LawfulIteratorCollect.toList_eq {α β : Type w} {m : Type w → Type w'}
|
||||
[Monad m] [Iterator α m β] [Finite α m] [IteratorCollect α m m]
|
||||
[hl : LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.toList = (letI : IteratorCollect α m m := .defaultImplementation; it.toList) := by
|
||||
simp [IterM.toList, toArray_eq]
|
||||
|
||||
end Std.Iterators
|
||||
239
src/Init/Data/Iterators/Lemmas/Consumers/Monadic/Loop.lean
Normal file
239
src/Init/Data/Iterators/Lemmas/Consumers/Monadic/Loop.lean
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/-
|
||||
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
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic.Collect
|
||||
import all Init.Data.Iterators.Consumers.Monadic.Loop
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
theorem IterM.DefaultConsumers.forIn_eq_match_step {α β : Type w} {m : Type w → Type w'}
|
||||
[Iterator α m β]
|
||||
{n : Type w → Type w''} [Monad n]
|
||||
{lift : ∀ γ, m γ → n γ} {γ : Type w}
|
||||
{plausible_forInStep : β → γ → ForInStep γ → Prop}
|
||||
{wf : IteratorLoop.WellFounded α m plausible_forInStep}
|
||||
{it : IterM (α := α) m β} {init : γ}
|
||||
{f : (b : β) → (c : γ) → n (Subtype (plausible_forInStep b c))} :
|
||||
IterM.DefaultConsumers.forIn lift γ plausible_forInStep wf it init f = (do
|
||||
match ← lift _ it.step with
|
||||
| .yield it' out _ =>
|
||||
match ← f out init with
|
||||
| ⟨.yield c, _⟩ =>
|
||||
IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' c
|
||||
fun out acc => f out acc
|
||||
| ⟨.done c, _⟩ => return c
|
||||
| .skip it' _ =>
|
||||
IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' init
|
||||
fun out acc => f out acc
|
||||
| .done _ => return init) := by
|
||||
rw [forIn]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn <;> rfl
|
||||
|
||||
theorem IterM.forIn_eq {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
{n : Type w → Type w''} [Monad n] [IteratorLoop α m n] [hl : LawfulIteratorLoop α m n]
|
||||
[MonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
|
||||
{f : β → γ → n (ForInStep γ)} :
|
||||
ForIn.forIn it init f = IterM.DefaultConsumers.forIn (fun _ => monadLift) γ (fun _ _ _ => True)
|
||||
IteratorLoop.wellFounded_of_finite it init (fun out acc => (⟨·, .intro⟩) <$> f out acc) := by
|
||||
cases hl.lawful; rfl
|
||||
|
||||
theorem IterM.forIn_eq_match_step {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n]
|
||||
[IteratorLoop α m n] [LawfulIteratorLoop α m n]
|
||||
[MonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
|
||||
{f : β → γ → n (ForInStep γ)} :
|
||||
ForIn.forIn it init f = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ =>
|
||||
match ← f out init with
|
||||
| .yield c => ForIn.forIn it' c f
|
||||
| .done c => return c
|
||||
| .skip it' _ => ForIn.forIn it' init f
|
||||
| .done _ => return init) := by
|
||||
rw [IterM.forIn_eq, DefaultConsumers.forIn_eq_match_step]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· simp only [map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro forInStep
|
||||
cases forInStep <;> simp [IterM.forIn_eq]
|
||||
· simp [IterM.forIn_eq]
|
||||
· simp
|
||||
|
||||
theorem IterM.forM_eq_forIn {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n]
|
||||
[IteratorLoop α m n] [LawfulIteratorLoop α m n]
|
||||
[MonadLiftT m n] {it : IterM (α := α) m β}
|
||||
{f : β → n PUnit} :
|
||||
ForM.forM it f = ForIn.forIn it PUnit.unit (fun out _ => do f out; return .yield .unit) :=
|
||||
rfl
|
||||
|
||||
theorem IterM.forM_eq_match_step {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n]
|
||||
[IteratorLoop α m n] [LawfulIteratorLoop α m n]
|
||||
[MonadLiftT m n] {it : IterM (α := α) m β}
|
||||
{f : β → n PUnit} :
|
||||
ForM.forM it f = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ =>
|
||||
f out
|
||||
ForM.forM it' f
|
||||
| .skip it' _ => ForM.forM it' f
|
||||
| .done _ => return) := by
|
||||
rw [forM_eq_forIn, forIn_eq_match_step]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp [forM_eq_forIn]
|
||||
|
||||
theorem IterM.foldM_eq_forIn {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
{n : Type w → Type w''} [Monad n] [IteratorLoop α m n] [MonadLiftT m n] {f : γ → β → n γ}
|
||||
{init : γ} {it : IterM (α := α) m β} :
|
||||
it.foldM (init := init) f = ForIn.forIn it init (fun x acc => ForInStep.yield <$> f acc x) :=
|
||||
(rfl)
|
||||
|
||||
theorem IterM.forIn_yield_eq_foldM {α β γ δ : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n] [IteratorLoop α m n]
|
||||
[LawfulIteratorLoop α m n] [MonadLiftT m n] {f : β → γ → n δ} {g : β → γ → δ → γ} {init : γ}
|
||||
{it : IterM (α := α) m β} :
|
||||
ForIn.forIn it init (fun c b => (fun d => .yield (g c b d)) <$> f c b) =
|
||||
it.foldM (fun b c => g c b <$> f c b) init := by
|
||||
simp [IterM.foldM_eq_forIn]
|
||||
|
||||
theorem IterM.foldM_eq_match_step {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
{n : Type w → Type w''} [Monad n] [LawfulMonad n] [IteratorLoop α m n] [LawfulIteratorLoop α m n]
|
||||
[MonadLiftT m n] {f : γ → β → n γ} {init : γ} {it : IterM (α := α) m β} :
|
||||
it.foldM (init := init) f = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ => it'.foldM (init := ← f init out) f
|
||||
| .skip it' _ => it'.foldM (init := init) f
|
||||
| .done _ => return init) := by
|
||||
rw [IterM.foldM_eq_forIn, IterM.forIn_eq_match_step]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp [foldM_eq_forIn]
|
||||
|
||||
theorem IterM.fold_eq_forIn {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m]
|
||||
[IteratorLoop α m m] {f : γ → β → γ} {init : γ} {it : IterM (α := α) m β} :
|
||||
it.fold (init := init) f =
|
||||
ForIn.forIn (m := m) it init (fun x acc => pure (ForInStep.yield (f acc x))) := by
|
||||
rfl
|
||||
|
||||
theorem IterM.fold_eq_foldM {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m] {f : γ → β → γ} {init : γ}
|
||||
{it : IterM (α := α) m β} :
|
||||
it.fold (init := init) f = it.foldM (init := init) (pure <| f · ·) := by
|
||||
simp [foldM_eq_forIn, fold_eq_forIn]
|
||||
|
||||
@[simp]
|
||||
theorem IterM.forIn_pure_yield_eq_fold {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m]
|
||||
[LawfulIteratorLoop α m m] {f : β → γ → γ} {init : γ}
|
||||
{it : IterM (α := α) m β} :
|
||||
ForIn.forIn it init (fun c b => pure (.yield (f c b))) =
|
||||
it.fold (fun b c => f c b) init := by
|
||||
simp [IterM.fold_eq_forIn]
|
||||
|
||||
theorem IterM.fold_eq_match_step {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
[Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
{f : γ → β → γ} {init : γ} {it : IterM (α := α) m β} :
|
||||
it.fold (init := init) f = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ => it'.fold (init := f init out) f
|
||||
| .skip it' _ => it'.fold (init := init) f
|
||||
| .done _ => return init) := by
|
||||
rw [fold_eq_foldM, foldM_eq_match_step]
|
||||
simp only [fold_eq_foldM]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp
|
||||
|
||||
theorem IterM.toList_eq_fold {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.toList = it.fold (init := []) (fun l out => l ++ [out]) := by
|
||||
suffices h : ∀ l' : List β, (l' ++ ·) <$> it.toList =
|
||||
it.fold (init := l') (fun l out => l ++ [out]) by
|
||||
specialize h []
|
||||
simpa using h
|
||||
induction it using IterM.inductSteps with | step it ihy ihs =>
|
||||
intro l'
|
||||
rw [IterM.toList_eq_match_step, IterM.fold_eq_match_step]
|
||||
simp only [map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· rename_i it' out h
|
||||
specialize ihy h (l' ++ [out])
|
||||
simpa using ihy
|
||||
· rename_i it' h
|
||||
simp [ihs h]
|
||||
· simp
|
||||
|
||||
theorem IterM.drain_eq_fold {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
[Monad m] [IteratorLoop α m m] {it : IterM (α := α) m β} :
|
||||
it.drain = it.fold (init := PUnit.unit) (fun _ _ => .unit) :=
|
||||
(rfl)
|
||||
|
||||
theorem IterM.drain_eq_foldM {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
[Monad m] [LawfulMonad m] [IteratorLoop α m m] {it : IterM (α := α) m β} :
|
||||
it.drain = it.foldM (init := PUnit.unit) (fun _ _ => pure .unit) := by
|
||||
simp [IterM.drain_eq_fold, IterM.fold_eq_foldM]
|
||||
|
||||
theorem IterM.drain_eq_forIn {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
[Monad m] [IteratorLoop α m m] {it : IterM (α := α) m β} :
|
||||
it.drain = ForIn.forIn (m := m) it PUnit.unit (fun _ _ => pure (ForInStep.yield .unit)) := by
|
||||
simp [IterM.drain_eq_fold, IterM.fold_eq_forIn]
|
||||
|
||||
theorem IterM.drain_eq_match_step {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
[Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.drain = (do
|
||||
match ← it.step with
|
||||
| .yield it' _ _ => it'.drain
|
||||
| .skip it' _ => it'.drain
|
||||
| .done _ => return .unit) := by
|
||||
rw [IterM.drain_eq_fold, IterM.fold_eq_match_step]
|
||||
simp [IterM.drain_eq_fold]
|
||||
|
||||
theorem IterM.drain_eq_map_toList {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.drain = (fun _ => .unit) <$> it.toList := by
|
||||
induction it using IterM.inductSteps with | step it ihy ihs =>
|
||||
rw [IterM.drain_eq_match_step, IterM.toList_eq_match_step]
|
||||
simp only [map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· rename_i it' out h
|
||||
simp [ihy h]
|
||||
· rename_i it' h
|
||||
simp [ihs h]
|
||||
· simp
|
||||
|
||||
theorem IterM.drain_eq_map_toListRev {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.drain = (fun _ => .unit) <$> it.toListRev := by
|
||||
simp [IterM.drain_eq_map_toList, IterM.toListRev_eq]
|
||||
|
||||
theorem IterM.drain_eq_map_toArray {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.drain = (fun _ => .unit) <$> it.toList := by
|
||||
simp [IterM.drain_eq_map_toList]
|
||||
|
||||
end Std.Iterators
|
||||
|
|
@ -3,8 +3,10 @@ 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
|
||||
import Std.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Basic
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
@ -3,6 +3,8 @@ 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
|
||||
import Init.Control.Lawful.Basic
|
||||
import Init.Data.Subtype
|
||||
|
|
@ -48,6 +50,7 @@ def PostconditionT.lift {α : Type w} {m : Type w → Type w'} [Functor m] (x :
|
|||
PostconditionT m α :=
|
||||
⟨fun _ => True, (⟨·, .intro⟩) <$> x⟩
|
||||
|
||||
@[always_inline, inline]
|
||||
protected def PostconditionT.pure {m : Type w → Type w'} [Pure m] {α : Type w}
|
||||
(a : α) : PostconditionT m α :=
|
||||
⟨fun y => a = y, pure <| ⟨a, rfl⟩⟩
|
||||
|
|
@ -117,16 +120,20 @@ instance {m : Type w → Type w'} [Monad m] : Monad (PostconditionT m) where
|
|||
pure := PostconditionT.pure
|
||||
bind := PostconditionT.bind
|
||||
|
||||
@[simp]
|
||||
theorem PostconditionT.computation_pure {m : Type w → Type w'} [Monad m] {α : Type w}
|
||||
{x : α} :
|
||||
(pure x : PostconditionT m α).operation = pure ⟨x, rfl⟩ :=
|
||||
theorem PostconditionT.pure_eq_pure {m : Type w → Type w'} [Monad m] {α} {a : α} :
|
||||
pure a = PostconditionT.pure (m := m) a :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem PostconditionT.property_pure {m : Type w → Type w'} [Monad m] {α : Type w}
|
||||
{x : α} :
|
||||
(pure x : PostconditionT m α).Property = (x = ·) :=
|
||||
(pure x : PostconditionT m α).Property = (x = ·) := by
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem PostconditionT.operation_pure {m : Type w → Type w'} [Monad m] {α : Type w}
|
||||
{x : α} :
|
||||
(pure x : PostconditionT m α).operation = pure ⟨x, property_pure (m := m) ▸ rfl⟩ := by
|
||||
rfl
|
||||
|
||||
theorem PostconditionT.ext {m : Type w → Type w'} [Monad m] [LawfulMonad m]
|
||||
|
|
@ -209,12 +216,19 @@ theorem PostconditionT.property_map {m : Type w → Type w'} [Functor m] {α : T
|
|||
@[simp]
|
||||
theorem PostconditionT.operation_map {m : Type w → Type w'} [Functor m] {α : Type w} {β : Type w}
|
||||
{x : PostconditionT m α} {f : α → β} :
|
||||
(x.map f).operation = (fun a => ⟨_, a, rfl⟩) <$> x.operation :=
|
||||
(x.map f).operation =
|
||||
(fun a => ⟨_, (property_map (m := m)).mpr ⟨a.1, rfl, a.2⟩⟩) <$> x.operation := by
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem PostconditionT.operation_lift {m : Type w →Type w'} [Functor m] {α : Type w}
|
||||
{x : m α} : (lift x : PostconditionT m α).operation = (⟨·, True.intro⟩) <$> x :=
|
||||
theorem PostconditionT.property_lift {m : Type w → Type w'} [Functor m] {α : Type w}
|
||||
{x : m α} : (lift x : PostconditionT m α).Property = (fun _ => True) := by
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem PostconditionT.operation_lift {m : Type w → Type w'} [Functor m] {α : Type w}
|
||||
{x : m α} : (lift x : PostconditionT m α).operation =
|
||||
(⟨·, property_lift (m := m) ▸ True.intro⟩) <$> x := by
|
||||
rfl
|
||||
|
||||
end Std.Iterators
|
||||
|
|
@ -4,13 +4,13 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Consumers
|
||||
import Init.Data.Iterators.PostconditionMonad
|
||||
import Init.Data.Iterators.Internal
|
||||
import Std.Data.Iterators.Producers
|
||||
import Std.Data.Iterators.Consumers
|
||||
import Std.Data.Iterators.Combinators
|
||||
import Std.Data.Iterators.Lemmas
|
||||
import Std.Data.Iterators.PostConditionMonad
|
||||
import Std.Data.Iterators.Internal
|
||||
|
||||
/-!
|
||||
# Iterators
|
||||
|
|
@ -79,7 +79,9 @@ that needs to wait for a language feature.
|
|||
A distinction that cuts through the whole module is that between pure and monadic
|
||||
iterators. Each submodule contains a dedicated `Monadic` sub-submodule.
|
||||
|
||||
All of the following module names are prefixed with `Std.Data.Iterators`.
|
||||
Depending on whether functionality is needed in `Init`, modules might exist in `Init` or in `Std`.
|
||||
The following module names can then be found under `Init.Data.Iterators`, `Std.Data.Iterators` or
|
||||
both.
|
||||
|
||||
### Basic iterator API
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Basic
|
||||
import Std.Data.Iterators.Consumers.Collect
|
||||
import Std.Data.Iterators.Consumers.Loop
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Consumers.Collect
|
||||
import Init.Data.Iterators.Consumers.Loop
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
|
||||
/-!
|
||||
This file provides the iterator combinator `IterM.drop`.
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ Authors: Paul Reichert
|
|||
prelude
|
||||
import Init.Data.Nat.Lemmas
|
||||
import Init.RCases
|
||||
import Std.Data.Iterators.Basic
|
||||
import Std.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Std.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Std.Data.Iterators.PostConditionMonad
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Init.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.PostconditionMonad
|
||||
|
||||
/-!
|
||||
# Monadic `dropWhile` iterator combinator
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Basic
|
||||
import Std.Data.Iterators.Consumers.Collect
|
||||
import Std.Data.Iterators.Consumers.Loop
|
||||
import Std.Data.Iterators.PostConditionMonad
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Consumers.Collect
|
||||
import Init.Data.Iterators.Consumers.Loop
|
||||
import Init.Data.Iterators.PostconditionMonad
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
|
||||
/-!
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ Authors: Paul Reichert
|
|||
prelude
|
||||
import Init.Data.Nat.Lemmas
|
||||
import Init.RCases
|
||||
import Std.Data.Iterators.Basic
|
||||
import Std.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Std.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Init.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
|
||||
/-!
|
||||
This module provides the iterator combinator `IterM.take`.
|
||||
|
|
@ -143,15 +143,9 @@ instance Take.instIteratorLoop [Monad m] [Monad n] [Iterator α m β]
|
|||
IteratorLoop (Take α m β) m n :=
|
||||
.defaultImplementation
|
||||
|
||||
instance Take.instIteratorForPartial [Monad m] [Monad n] [Iterator α m β]
|
||||
instance Take.instIteratorLoopPartial [Monad m] [Monad n] [Iterator α m β]
|
||||
[IteratorLoopPartial α m n] [MonadLiftT m n] :
|
||||
IteratorLoopPartial (Take α m β) m n where
|
||||
forInPartial lift {γ} it init f := do
|
||||
Prod.fst <$> IteratorLoopPartial.forInPartial lift it.internalState.inner (γ := γ × Nat)
|
||||
(init, it.internalState.remaining)
|
||||
fun out acc =>
|
||||
match acc.snd with
|
||||
| 0 => pure <| .done acc
|
||||
| n + 1 => (fun | .yield x => .yield ⟨x, n⟩ | .done x => .done ⟨x, n⟩) <$> f out acc.fst
|
||||
IteratorLoopPartial (Take α m β) m n :=
|
||||
.defaultImplementation
|
||||
|
||||
end Std.Iterators
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ Authors: Paul Reichert
|
|||
prelude
|
||||
import Init.Data.Nat.Lemmas
|
||||
import Init.RCases
|
||||
import Std.Data.Iterators.Basic
|
||||
import Std.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Std.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Std.Data.Iterators.PostConditionMonad
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Init.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.PostconditionMonad
|
||||
|
||||
/-!
|
||||
# Monadic `takeWhile` iterator combinator
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Init.Data.Option.Lemmas
|
||||
import Std.Data.Iterators.Basic
|
||||
import Std.Data.Iterators.Consumers.Collect
|
||||
import Std.Data.Iterators.Consumers.Loop
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.Consumers.Collect
|
||||
import Init.Data.Iterators.Consumers.Loop
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
|
||||
/-!
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
/-
|
||||
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Consumers.Monadic
|
||||
import Std.Data.Iterators.Consumers.Access
|
||||
import Std.Data.Iterators.Consumers.Collect
|
||||
import Std.Data.Iterators.Consumers.Loop
|
||||
import Std.Data.Iterators.Consumers.Partial
|
||||
|
|
@ -4,9 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Lemmas.Basic
|
||||
import Init.Data.Iterators.Lemmas.Basic
|
||||
import Std.Data.Iterators.Lemmas.Monadic
|
||||
import Std.Data.Iterators.Lemmas.Consumers
|
||||
import Std.Data.Iterators.Lemmas.Combinators
|
||||
import Std.Data.Iterators.Lemmas.Producers
|
||||
import Std.Data.Iterators.Lemmas.Equivalence
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ prelude
|
|||
import Std.Data.Iterators.Combinators.Drop
|
||||
import Std.Data.Iterators.Lemmas.Combinators.Monadic.Drop
|
||||
import Std.Data.Iterators.Lemmas.Combinators.Take
|
||||
import Std.Data.Iterators.Lemmas.Consumers
|
||||
import Init.Data.Iterators.Lemmas.Consumers
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Authors: Paul Reichert
|
|||
prelude
|
||||
import Std.Data.Iterators.Combinators.DropWhile
|
||||
import Std.Data.Iterators.Lemmas.Combinators.Monadic.DropWhile
|
||||
import Std.Data.Iterators.Lemmas.Consumers
|
||||
import Init.Data.Iterators.Lemmas.Consumers
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Lemmas.Consumers
|
||||
import Init.Data.Iterators.Lemmas.Consumers
|
||||
import Std.Data.Iterators.Lemmas.Combinators.Monadic.FilterMap
|
||||
import Std.Data.Iterators.Combinators.FilterMap
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Combinators.Monadic.Drop
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Combinators.Monadic.DropWhile
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Internal.LawfulMonadLiftFunction
|
||||
import Init.Data.Iterators.Internal.LawfulMonadLiftFunction
|
||||
import Std.Data.Iterators.Combinators.Monadic.FilterMap
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Std.Data.Iterators.Lemmas.Equivalence.StepCongr
|
||||
|
||||
namespace Std.Iterators
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Combinators.Monadic.Take
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Combinators.Monadic.Zip
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Combinators.Take
|
||||
import Std.Data.Iterators.Consumers.Access
|
||||
import Init.Data.Iterators.Consumers.Access
|
||||
import Std.Data.Iterators.Lemmas.Combinators.Monadic.Take
|
||||
import Std.Data.Iterators.Lemmas.Consumers
|
||||
import Init.Data.Iterators.Lemmas.Consumers
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ Authors: Paul Reichert
|
|||
prelude
|
||||
import Std.Data.Iterators.Combinators.Take
|
||||
import Std.Data.Iterators.Combinators.Zip
|
||||
import Std.Data.Iterators.Consumers.Access
|
||||
import Init.Data.Iterators.Consumers.Access
|
||||
import Std.Data.Iterators.Lemmas.Combinators.Monadic.Zip
|
||||
import Std.Data.Iterators.Lemmas.Combinators.Take
|
||||
import Std.Data.Iterators.Lemmas.Consumers
|
||||
import Init.Data.Iterators.Lemmas.Consumers
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
|
|||
|
|
@ -4,113 +4,14 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Consumers.Access
|
||||
import Std.Data.Iterators.Consumers.Collect
|
||||
import Std.Data.Iterators.Lemmas.Basic
|
||||
import Init.Data.Iterators.Consumers.Access
|
||||
import Init.Data.Iterators.Consumers.Collect
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Collect
|
||||
import Init.Data.Iterators.Lemmas.Basic
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic.Collect
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
theorem Iter.toArray_eq_toArray_toIterM {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toArray = it.toIterM.toArray.run :=
|
||||
rfl
|
||||
|
||||
theorem Iter.toList_eq_toList_toIterM {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toList = it.toIterM.toList.run :=
|
||||
rfl
|
||||
|
||||
theorem Iter.toListRev_eq_toListRev_toIterM {α β} [Iterator α Id β] [Finite α Id]
|
||||
{it : Iter (α := α) β} :
|
||||
it.toListRev = it.toIterM.toListRev.run :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem IterM.toList_toIter {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
{it : IterM (α := α) Id β} :
|
||||
it.toIter.toList = it.toList.run :=
|
||||
rfl
|
||||
|
||||
@[simp]
|
||||
theorem IterM.toListRev_toIter {α β} [Iterator α Id β] [Finite α Id]
|
||||
{it : IterM (α := α) Id β} :
|
||||
it.toIter.toListRev = it.toListRev.run :=
|
||||
rfl
|
||||
|
||||
theorem Iter.toList_toArray {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toArray.toList = it.toList := by
|
||||
simp [toArray_eq_toArray_toIterM, toList_eq_toList_toIterM, ← IterM.toList_toArray]
|
||||
|
||||
theorem Iter.toArray_toList {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toList.toArray = it.toArray := by
|
||||
simp [toArray_eq_toArray_toIterM, toList_eq_toList_toIterM, ← IterM.toArray_toList]
|
||||
|
||||
@[simp]
|
||||
theorem Iter.reverse_toListRev [Iterator α Id β] [Finite α Id]
|
||||
[IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{it : Iter (α := α) β} :
|
||||
it.toListRev.reverse = it.toList := by
|
||||
simp [toListRev_eq_toListRev_toIterM, toList_eq_toList_toIterM, ← IterM.reverse_toListRev]
|
||||
|
||||
theorem Iter.toListRev_eq {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toListRev = it.toList.reverse := by
|
||||
simp [Iter.toListRev_eq_toListRev_toIterM, Iter.toList_eq_toList_toIterM, IterM.toListRev_eq]
|
||||
|
||||
theorem Iter.toArray_eq_match_step {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toArray = match it.step with
|
||||
| .yield it' out _ => #[out] ++ it'.toArray
|
||||
| .skip it' _ => it'.toArray
|
||||
| .done _ => #[] := by
|
||||
simp only [Iter.toArray_eq_toArray_toIterM, Iter.step]
|
||||
rw [IterM.toArray_eq_match_step, Id.run_bind]
|
||||
generalize it.toIterM.step.run = step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp
|
||||
|
||||
theorem Iter.toList_eq_match_step {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id]
|
||||
[LawfulIteratorCollect α Id Id] {it : Iter (α := α) β} :
|
||||
it.toList = match it.step with
|
||||
| .yield it' out _ => out :: it'.toList
|
||||
| .skip it' _ => it'.toList
|
||||
| .done _ => [] := by
|
||||
rw [← Iter.toList_toArray, Iter.toArray_eq_match_step]
|
||||
split <;> simp [Iter.toList_toArray]
|
||||
|
||||
theorem Iter.toListRev_eq_match_step {α β} [Iterator α Id β] [Finite α Id] {it : Iter (α := α) β} :
|
||||
it.toListRev = match it.step with
|
||||
| .yield it' out _ => it'.toListRev ++ [out]
|
||||
| .skip it' _ => it'.toListRev
|
||||
| .done _ => [] := by
|
||||
rw [Iter.toListRev_eq_toListRev_toIterM, IterM.toListRev_eq_match_step, Iter.step, Id.run_bind]
|
||||
generalize it.toIterM.step.run = step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp
|
||||
|
||||
theorem Iter.getElem?_toList_eq_atIdxSlow? {α β}
|
||||
[Iterator α Id β] [Finite α Id] [IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{it : Iter (α := α) β} {k : Nat} :
|
||||
it.toList[k]? = it.atIdxSlow? k := by
|
||||
induction it using Iter.inductSteps generalizing k with | step it ihy ihs =>
|
||||
rw [toList_eq_match_step, atIdxSlow?]
|
||||
obtain ⟨step, h⟩ := it.step
|
||||
cases step
|
||||
· cases k <;> simp [ihy h]
|
||||
· simp [ihs h]
|
||||
· simp
|
||||
|
||||
theorem Iter.toList_eq_of_atIdxSlow?_eq {α₁ α₂ β}
|
||||
[Iterator α₁ Id β] [Finite α₁ Id] [IteratorCollect α₁ Id Id] [LawfulIteratorCollect α₁ Id Id]
|
||||
[Iterator α₂ Id β] [Finite α₂ Id] [IteratorCollect α₂ Id Id] [LawfulIteratorCollect α₂ Id Id]
|
||||
{it₁ : Iter (α := α₁) β} {it₂ : Iter (α := α₂) β}
|
||||
(h : ∀ k, it₁.atIdxSlow? k = it₂.atIdxSlow? k) :
|
||||
it₁.toList = it₂.toList := by
|
||||
ext; simp [getElem?_toList_eq_atIdxSlow?, h]
|
||||
|
||||
section Equivalence
|
||||
|
||||
theorem Iter.Equiv.toListRev_eq
|
||||
[Iterator α₁ Id β] [Iterator α₂ Id β] [Finite α₁ Id] [Finite α₂ Id]
|
||||
{ita : Iter (α := α₁) β} {itb : Iter (α := α₂) β} (h : Iter.Equiv ita itb) :
|
||||
|
|
@ -133,6 +34,4 @@ theorem Iter.Equiv.toArray_eq
|
|||
ita.toArray = itb.toArray := by
|
||||
simp only [← Iter.toArray_toList, toList_eq h]
|
||||
|
||||
end Equivalence
|
||||
|
||||
end Std.Iterators
|
||||
|
|
|
|||
|
|
@ -5,179 +5,15 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Init.Data.List.Control
|
||||
import Std.Data.Iterators.Lemmas.Basic
|
||||
import Init.Data.Iterators.Lemmas.Basic
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Loop
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Collect
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic.Loop
|
||||
import Std.Data.Iterators.Consumers.Collect
|
||||
import Std.Data.Iterators.Consumers.Loop
|
||||
import Init.Data.Iterators.Consumers.Collect
|
||||
import Init.Data.Iterators.Consumers.Loop
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
theorem Iter.forIn_eq {α β : Type w} [Iterator α Id β] [Finite α Id]
|
||||
{m : Type w → Type w''} [Monad m] [IteratorLoop α Id m] [hl : LawfulIteratorLoop α Id m]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ}
|
||||
{f : β → γ → m (ForInStep γ)} :
|
||||
ForIn.forIn it init f =
|
||||
IterM.DefaultConsumers.forIn (fun _ c => pure c.run) γ (fun _ _ _ => True)
|
||||
IteratorLoop.wellFounded_of_finite it.toIterM init ((⟨·, .intro⟩) <$> f · ·) := by
|
||||
cases hl.lawful; rfl
|
||||
|
||||
theorem Iter.forIn_eq_forIn_toIterM {α β : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
|
||||
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ}
|
||||
{f : β → γ → m (ForInStep γ)} :
|
||||
ForIn.forIn it init f =
|
||||
letI : MonadLift Id m := ⟨Std.Internal.idToMonad (α := _)⟩
|
||||
ForIn.forIn it.toIterM init f := by
|
||||
rfl
|
||||
|
||||
theorem Iter.forIn_eq_match_step {α β : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
|
||||
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ}
|
||||
{f : β → γ → m (ForInStep γ)} :
|
||||
ForIn.forIn it init f = (do
|
||||
match it.step with
|
||||
| .yield it' out _ =>
|
||||
match ← f out init with
|
||||
| .yield c => ForIn.forIn it' c f
|
||||
| .done c => return c
|
||||
| .skip it' _ => ForIn.forIn it' init f
|
||||
| .done _ => return init) := by
|
||||
rw [Iter.forIn_eq_forIn_toIterM, @IterM.forIn_eq_match_step, Iter.step]
|
||||
simp only [liftM, monadLift, pure_bind]
|
||||
generalize it.toIterM.step = step
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· apply bind_congr
|
||||
intro forInStep
|
||||
rfl
|
||||
· rfl
|
||||
· rfl
|
||||
|
||||
theorem Iter.forIn_toList {α β : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
|
||||
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
[IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ}
|
||||
{f : β → γ → m (ForInStep γ)} :
|
||||
ForIn.forIn it.toList init f = ForIn.forIn it init f := by
|
||||
rw [List.forIn_eq_foldlM]
|
||||
induction it using Iter.inductSteps generalizing init with case step it ihy ihs =>
|
||||
rw [forIn_eq_match_step, Iter.toList_eq_match_step]
|
||||
simp only [map_eq_pure_bind]
|
||||
generalize it.step = step
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· rename_i it' out h
|
||||
simp only [List.foldlM_cons, bind_pure_comp, map_bind]
|
||||
apply bind_congr
|
||||
intro forInStep
|
||||
cases forInStep
|
||||
· induction it'.toList <;> simp [*]
|
||||
· simp only [ForIn.forIn, forIn', List.forIn'] at ihy
|
||||
simp [ihy h, forIn_eq_forIn_toIterM]
|
||||
· rename_i it' h
|
||||
simp only [bind_pure_comp]
|
||||
rw [ihs h]
|
||||
· simp
|
||||
|
||||
theorem Iter.foldM_eq_forIn {α β γ : Type w} [Iterator α Id β] [Finite α Id] {m : Type w → Type w'}
|
||||
[Monad m] [IteratorLoop α Id m] {f : γ → β → m γ}
|
||||
{init : γ} {it : Iter (α := α) β} :
|
||||
it.foldM (init := init) f = ForIn.forIn it init (fun x acc => ForInStep.yield <$> f acc x) :=
|
||||
rfl
|
||||
|
||||
theorem Iter.foldM_eq_foldM_toIterM {α β : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
|
||||
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ} {f : γ → β → m γ} :
|
||||
it.foldM (init := init) f = letI : MonadLift Id m := ⟨pure⟩; it.toIterM.foldM (init := init) f :=
|
||||
rfl
|
||||
|
||||
theorem Iter.forIn_yield_eq_foldM {α β γ δ : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m] [IteratorLoop α Id m]
|
||||
[LawfulIteratorLoop α Id m] {f : β → γ → m δ} {g : β → γ → δ → γ} {init : γ}
|
||||
{it : Iter (α := α) β} :
|
||||
ForIn.forIn it init (fun c b => (fun d => .yield (g c b d)) <$> f c b) =
|
||||
it.foldM (fun b c => g c b <$> f c b) init := by
|
||||
simp [Iter.foldM_eq_forIn]
|
||||
|
||||
theorem Iter.foldM_eq_match_step {α β γ : Type w} [Iterator α Id β] [Finite α Id]
|
||||
{m : Type w → Type w'} [Monad m] [LawfulMonad m] [IteratorLoop α Id m]
|
||||
[LawfulIteratorLoop α Id m] {f : γ → β → m γ} {init : γ} {it : Iter (α := α) β} :
|
||||
it.foldM (init := init) f = (do
|
||||
match it.step with
|
||||
| .yield it' out _ => it'.foldM (init := ← f init out) f
|
||||
| .skip it' _ => it'.foldM (init := init) f
|
||||
| .done _ => return init) := by
|
||||
rw [Iter.foldM_eq_forIn, Iter.forIn_eq_match_step]
|
||||
generalize it.step = step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp [foldM_eq_forIn]
|
||||
|
||||
theorem Iter.foldlM_toList {α β γ : Type w} [Iterator α Id β] [Finite α Id] {m : Type w → Type w'}
|
||||
[Monad m] [LawfulMonad m] [IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
[IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{f : γ → β → m γ}
|
||||
{init : γ} {it : Iter (α := α) β} :
|
||||
it.toList.foldlM (init := init) f = it.foldM (init := init) f := by
|
||||
rw [Iter.foldM_eq_forIn, ← Iter.forIn_toList]
|
||||
simp only [List.forIn_yield_eq_foldlM, id_map']
|
||||
|
||||
theorem IterM.forIn_eq_foldM {α β : Type w} [Iterator α Id β]
|
||||
[Finite α Id] {m : Type w → Type w''} [Monad m] [LawfulMonad m]
|
||||
[IteratorLoop α Id m] [LawfulIteratorLoop α Id m]
|
||||
[IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{γ : Type w} {it : Iter (α := α) β} {init : γ}
|
||||
{f : β → γ → m (ForInStep γ)} :
|
||||
forIn it init f = ForInStep.value <$>
|
||||
it.foldM (fun c b => match c with
|
||||
| .yield c => f b c
|
||||
| .done c => pure (.done c)) (ForInStep.yield init) := by
|
||||
simp only [← Iter.forIn_toList, List.forIn_eq_foldlM, ← Iter.foldlM_toList]; rfl
|
||||
|
||||
theorem Iter.fold_eq_forIn {α β γ : Type w} [Iterator α Id β]
|
||||
[Finite α Id] [IteratorLoop α Id Id] {f : γ → β → γ} {init : γ} {it : Iter (α := α) β} :
|
||||
it.fold (init := init) f =
|
||||
(ForIn.forIn (m := Id) it init (fun x acc => pure (ForInStep.yield (f acc x)))).run := by
|
||||
rfl
|
||||
|
||||
theorem Iter.fold_eq_foldM {α β γ : Type w} [Iterator α Id β]
|
||||
[Finite α Id] [IteratorLoop α Id Id] {f : γ → β → γ} {init : γ}
|
||||
{it : Iter (α := α) β} :
|
||||
it.fold (init := init) f = (it.foldM (m := Id) (init := init) (pure <| f · ·)).run := by
|
||||
simp [foldM_eq_forIn, fold_eq_forIn]
|
||||
|
||||
@[simp]
|
||||
theorem Iter.forIn_pure_yield_eq_fold {α β γ : Type w} [Iterator α Id β]
|
||||
[Finite α Id] [IteratorLoop α Id Id]
|
||||
[LawfulIteratorLoop α Id Id] {f : β → γ → γ} {init : γ}
|
||||
{it : Iter (α := α) β} :
|
||||
ForIn.forIn (m := Id) it init (fun c b => pure (.yield (f c b))) =
|
||||
pure (it.fold (fun b c => f c b) init) := by
|
||||
simp only [fold_eq_forIn]
|
||||
rfl
|
||||
|
||||
theorem Iter.fold_eq_match_step {α β γ : Type w} [Iterator α Id β] [Finite α Id]
|
||||
[IteratorLoop α Id Id] [LawfulIteratorLoop α Id Id]
|
||||
{f : γ → β → γ} {init : γ} {it : Iter (α := α) β} :
|
||||
it.fold (init := init) f = (match it.step with
|
||||
| .yield it' out _ => it'.fold (init := f init out) f
|
||||
| .skip it' _ => it'.fold (init := init) f
|
||||
| .done _ => init) := by
|
||||
rw [fold_eq_foldM, foldM_eq_match_step]
|
||||
simp only [fold_eq_foldM]
|
||||
generalize it.step = step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp
|
||||
|
||||
theorem Iter.foldl_toList {α β γ : Type w} [Iterator α Id β] [Finite α Id]
|
||||
[IteratorLoop α Id Id] [LawfulIteratorLoop α Id Id]
|
||||
[IteratorCollect α Id Id] [LawfulIteratorCollect α Id Id]
|
||||
{f : γ → β → γ} {init : γ} {it : Iter (α := α) β} :
|
||||
it.toList.foldl (init := init) f = it.fold (init := init) f := by
|
||||
rw [fold_eq_foldM, List.foldl_eq_foldlM, ← Iter.foldlM_toList]
|
||||
|
||||
section Equivalence
|
||||
|
||||
theorem Iter.Equiv.forIn_eq {α₁ α₂ β γ : Type w} {m : Type w → Type w'}
|
||||
[Iterator α₁ Id β] [Iterator α₂ Id β] [Finite α₁ Id] [Finite α₂ Id]
|
||||
[Monad m] [LawfulMonad m] [IteratorLoop α₁ Id m] [LawfulIteratorLoop α₁ Id m]
|
||||
|
|
@ -208,6 +44,4 @@ theorem Iter.Equiv.fold_eq {α₁ α₂ β γ : Type w} {m : Type w → Type w'}
|
|||
ita.fold (init := init) f = itb.fold (init := init) f := by
|
||||
simp [Iter.fold_eq_foldM, h.foldM_eq]
|
||||
|
||||
end Equivalence
|
||||
|
||||
end Std.Iterators
|
||||
|
|
|
|||
|
|
@ -5,161 +5,13 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Init.Data.Array.Lemmas
|
||||
import Std.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Std.Data.Iterators.Lemmas.Monadic.Basic
|
||||
import Std.Data.Iterators.Producers
|
||||
import Init.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic.Collect
|
||||
import Init.Data.Iterators.Lemmas.Monadic.Basic
|
||||
import Std.Data.Iterators.Lemmas.Equivalence.StepCongr
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
section Consumers
|
||||
|
||||
variable {α β γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''}
|
||||
{lift : ⦃δ : Type w⦄ → m δ → n δ} {f : β → n γ} {it : IterM (α := α) m β}
|
||||
|
||||
theorem IterM.DefaultConsumers.toArrayMapped.go.aux₁ [Monad n] [LawfulMonad n] [Iterator α m β]
|
||||
[Finite α m] {b : γ} {bs : Array γ} :
|
||||
IterM.DefaultConsumers.toArrayMapped.go lift f it (#[b] ++ bs) (m := m) =
|
||||
(#[b] ++ ·) <$> IterM.DefaultConsumers.toArrayMapped.go lift f it bs (m := m) := by
|
||||
induction it, bs using IterM.DefaultConsumers.toArrayMapped.go.induct
|
||||
next it bs ih₁ ih₂ =>
|
||||
rw [go, map_eq_pure_bind, go, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
split
|
||||
· simp [ih₁ _ _ ‹_›]
|
||||
· simp [ih₂ _ ‹_›]
|
||||
· simp
|
||||
|
||||
theorem IterM.DefaultConsumers.toArrayMapped.go.aux₂ [Monad n] [LawfulMonad n] [Iterator α m β]
|
||||
[Finite α m] {acc : Array γ} :
|
||||
IterM.DefaultConsumers.toArrayMapped.go lift f it acc (m := m) =
|
||||
(acc ++ ·) <$> IterM.DefaultConsumers.toArrayMapped lift f it (m := m) := by
|
||||
rw [← Array.toArray_toList (xs := acc)]
|
||||
generalize acc.toList = acc
|
||||
induction acc with
|
||||
| nil => simp [toArrayMapped]
|
||||
| cons x xs ih =>
|
||||
rw [List.toArray_cons, IterM.DefaultConsumers.toArrayMapped.go.aux₁, ih]
|
||||
simp only [Functor.map_map, Array.append_assoc]
|
||||
|
||||
theorem IterM.DefaultConsumers.toArrayMapped_eq_match_step [Monad n] [LawfulMonad n]
|
||||
[Iterator α m β] [Finite α m] :
|
||||
IterM.DefaultConsumers.toArrayMapped lift f it (m := m) = letI : MonadLift m n := ⟨lift (δ := _)⟩; (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ =>
|
||||
return #[← f out] ++ (← IterM.DefaultConsumers.toArrayMapped lift f it' (m := m))
|
||||
| .skip it' _ => IterM.DefaultConsumers.toArrayMapped lift f it' (m := m)
|
||||
| .done _ => return #[]) := by
|
||||
rw [IterM.DefaultConsumers.toArrayMapped, IterM.DefaultConsumers.toArrayMapped.go]
|
||||
apply bind_congr
|
||||
intro step
|
||||
split <;> simp [IterM.DefaultConsumers.toArrayMapped.go.aux₂]
|
||||
|
||||
theorem IterM.toArray_eq_match_step [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m] :
|
||||
it.toArray = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ => return #[out] ++ (← it'.toArray)
|
||||
| .skip it' _ => it'.toArray
|
||||
| .done _ => return #[]) := by
|
||||
simp only [IterM.toArray, LawfulIteratorCollect.toArrayMapped_eq]
|
||||
rw [IterM.DefaultConsumers.toArrayMapped_eq_match_step]
|
||||
simp [bind_pure_comp, pure_bind, toArray]
|
||||
|
||||
theorem IterM.toList_toArray [Monad m] [Iterator α m β] [Finite α m] [IteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
Array.toList <$> it.toArray = it.toList := by
|
||||
simp [IterM.toList]
|
||||
|
||||
theorem IterM.toArray_toList [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
[IteratorCollect α m m] {it : IterM (α := α) m β} :
|
||||
List.toArray <$> it.toList = it.toArray := by
|
||||
simp [IterM.toList]
|
||||
|
||||
theorem IterM.toList_eq_match_step [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m] {it : IterM (α := α) m β} :
|
||||
it.toList = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ => return out :: (← it'.toList)
|
||||
| .skip it' _ => it'.toList
|
||||
| .done _ => return []) := by
|
||||
simp [← IterM.toList_toArray]
|
||||
rw [IterM.toArray_eq_match_step, map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
split <;> simp
|
||||
|
||||
theorem IterM.toListRev.go.aux₁ [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
{it : IterM (α := α) m β} {b : β} {bs : List β} :
|
||||
IterM.toListRev.go it (bs ++ [b]) = (· ++ [b]) <$> IterM.toListRev.go it bs:= by
|
||||
induction it, bs using IterM.toListRev.go.induct
|
||||
next it bs ih₁ ih₂ =>
|
||||
rw [go, go, map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
simp only [List.cons_append] at ih₁
|
||||
split <;> simp [*]
|
||||
|
||||
theorem IterM.toListRev.go.aux₂ [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
{it : IterM (α := α) m β} {acc : List β} :
|
||||
IterM.toListRev.go it acc = (· ++ acc) <$> it.toListRev := by
|
||||
rw [← List.reverse_reverse (as := acc)]
|
||||
generalize acc.reverse = acc
|
||||
induction acc with
|
||||
| nil => simp [toListRev]
|
||||
| cons x xs ih => simp [IterM.toListRev.go.aux₁, ih]
|
||||
|
||||
theorem IterM.toListRev_eq_match_step [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.toListRev = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ => return (← it'.toListRev) ++ [out]
|
||||
| .skip it' _ => it'.toListRev
|
||||
| .done _ => return []) := by
|
||||
simp [IterM.toListRev]
|
||||
rw [toListRev.go]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp [IterM.toListRev.go.aux₂]
|
||||
|
||||
theorem IterM.reverse_toListRev [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
List.reverse <$> it.toListRev = it.toList := by
|
||||
apply Eq.symm
|
||||
induction it using IterM.inductSteps
|
||||
rename_i it ihy ihs
|
||||
rw [toListRev_eq_match_step, toList_eq_match_step, map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
split <;> simp (discharger := assumption) [ihy, ihs]
|
||||
|
||||
theorem IterM.toListRev_eq [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.toListRev = List.reverse <$> it.toList := by
|
||||
rw [← IterM.reverse_toListRev]
|
||||
simp
|
||||
|
||||
theorem LawfulIteratorCollect.toArray_eq {α β : Type w} {m : Type w → Type w'}
|
||||
[Monad m] [Iterator α m β] [Finite α m] [IteratorCollect α m m]
|
||||
[hl : LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.toArray = (letI : IteratorCollect α m m := .defaultImplementation; it.toArray) := by
|
||||
simp only [IterM.toArray, toArrayMapped_eq]
|
||||
|
||||
theorem LawfulIteratorCollect.toList_eq {α β : Type w} {m : Type w → Type w'}
|
||||
[Monad m] [Iterator α m β] [Finite α m] [IteratorCollect α m m]
|
||||
[hl : LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.toList = (letI : IteratorCollect α m m := .defaultImplementation; it.toList) := by
|
||||
simp [IterM.toList, toArray_eq]
|
||||
|
||||
end Consumers
|
||||
|
||||
section Equivalence
|
||||
|
||||
theorem IterM.Equiv.toListRev_eq [Monad m] [LawfulMonad m]
|
||||
[Iterator α₁ m β] [Iterator α₂ m β] [Finite α₁ m] [Finite α₂ m]
|
||||
{ita : IterM (α := α₁) m β} {itb : IterM (α := α₂) m β} (h : IterM.Equiv ita itb) :
|
||||
|
|
@ -197,6 +49,4 @@ theorem IterM.Equiv.toArray_eq [Monad m] [LawfulMonad m]
|
|||
ita.toArray = itb.toArray := by
|
||||
simp only [← IterM.toArray_toList, toList_eq h]
|
||||
|
||||
end Equivalence
|
||||
|
||||
end Std.Iterators
|
||||
|
|
|
|||
|
|
@ -5,237 +5,15 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Init.Control.Lawful.Basic
|
||||
import Std.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Std.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Std.Data.Iterators.Lemmas.Monadic.Basic
|
||||
import Init.Data.Iterators.Consumers.Monadic.Collect
|
||||
import Init.Data.Iterators.Consumers.Monadic.Loop
|
||||
import Init.Data.Iterators.Lemmas.Monadic.Basic
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic.Loop
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic.Collect
|
||||
import Std.Data.Iterators.Lemmas.Equivalence.StepCongr
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
theorem IterM.DefaultConsumers.forIn_eq_match_step {α β : Type w} {m : Type w → Type w'}
|
||||
[Iterator α m β]
|
||||
{n : Type w → Type w''} [Monad n]
|
||||
{lift : ∀ γ, m γ → n γ} {γ : Type w}
|
||||
{plausible_forInStep : β → γ → ForInStep γ → Prop}
|
||||
{wf : IteratorLoop.WellFounded α m plausible_forInStep}
|
||||
{it : IterM (α := α) m β} {init : γ}
|
||||
{f : (b : β) → (c : γ) → n (Subtype (plausible_forInStep b c))} :
|
||||
IterM.DefaultConsumers.forIn lift γ plausible_forInStep wf it init f = (do
|
||||
match ← lift _ it.step with
|
||||
| .yield it' out _ =>
|
||||
match ← f out init with
|
||||
| ⟨.yield c, _⟩ => IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' c f
|
||||
| ⟨.done c, _⟩ => return c
|
||||
| .skip it' _ => IterM.DefaultConsumers.forIn lift _ plausible_forInStep wf it' init f
|
||||
| .done _ => return init) := by
|
||||
rw [forIn]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn <;> rfl
|
||||
|
||||
theorem IterM.forIn_eq {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
{n : Type w → Type w''} [Monad n] [IteratorLoop α m n] [hl : LawfulIteratorLoop α m n]
|
||||
[MonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
|
||||
{f : β → γ → n (ForInStep γ)} :
|
||||
ForIn.forIn it init f = IterM.DefaultConsumers.forIn (fun _ => monadLift) γ (fun _ _ _ => True)
|
||||
IteratorLoop.wellFounded_of_finite it init ((⟨·, .intro⟩) <$> f · ·) := by
|
||||
cases hl.lawful; rfl
|
||||
|
||||
theorem IterM.forIn_eq_match_step {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n]
|
||||
[IteratorLoop α m n] [LawfulIteratorLoop α m n]
|
||||
[MonadLiftT m n] {γ : Type w} {it : IterM (α := α) m β} {init : γ}
|
||||
{f : β → γ → n (ForInStep γ)} :
|
||||
ForIn.forIn it init f = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ =>
|
||||
match ← f out init with
|
||||
| .yield c => ForIn.forIn it' c f
|
||||
| .done c => return c
|
||||
| .skip it' _ => ForIn.forIn it' init f
|
||||
| .done _ => return init) := by
|
||||
rw [IterM.forIn_eq, DefaultConsumers.forIn_eq_match_step]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· simp only [map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro forInStep
|
||||
cases forInStep <;> simp [IterM.forIn_eq]
|
||||
· simp [IterM.forIn_eq]
|
||||
· simp
|
||||
|
||||
theorem IterM.forM_eq_forIn {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n]
|
||||
[IteratorLoop α m n] [LawfulIteratorLoop α m n]
|
||||
[MonadLiftT m n] {it : IterM (α := α) m β}
|
||||
{f : β → n PUnit} :
|
||||
ForM.forM it f = ForIn.forIn it PUnit.unit (fun out _ => do f out; return .yield .unit) :=
|
||||
rfl
|
||||
|
||||
theorem IterM.forM_eq_match_step {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n]
|
||||
[IteratorLoop α m n] [LawfulIteratorLoop α m n]
|
||||
[MonadLiftT m n] {it : IterM (α := α) m β}
|
||||
{f : β → n PUnit} :
|
||||
ForM.forM it f = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ =>
|
||||
f out
|
||||
ForM.forM it' f
|
||||
| .skip it' _ => ForM.forM it' f
|
||||
| .done _ => return) := by
|
||||
rw [forM_eq_forIn, forIn_eq_match_step]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp [forM_eq_forIn]
|
||||
|
||||
theorem IterM.foldM_eq_forIn {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
{n : Type w → Type w''} [Monad n] [IteratorLoop α m n] [MonadLiftT m n] {f : γ → β → n γ}
|
||||
{init : γ} {it : IterM (α := α) m β} :
|
||||
it.foldM (init := init) f = ForIn.forIn it init (fun x acc => ForInStep.yield <$> f acc x) :=
|
||||
rfl
|
||||
|
||||
theorem IterM.forIn_yield_eq_foldM {α β γ δ : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] {n : Type w → Type w''} [Monad n] [LawfulMonad n] [IteratorLoop α m n]
|
||||
[LawfulIteratorLoop α m n] [MonadLiftT m n] {f : β → γ → n δ} {g : β → γ → δ → γ} {init : γ}
|
||||
{it : IterM (α := α) m β} :
|
||||
ForIn.forIn it init (fun c b => (fun d => .yield (g c b d)) <$> f c b) =
|
||||
it.foldM (fun b c => g c b <$> f c b) init := by
|
||||
simp [IterM.foldM_eq_forIn]
|
||||
|
||||
theorem IterM.foldM_eq_match_step {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
{n : Type w → Type w''} [Monad n] [LawfulMonad n] [IteratorLoop α m n] [LawfulIteratorLoop α m n]
|
||||
[MonadLiftT m n] {f : γ → β → n γ} {init : γ} {it : IterM (α := α) m β} :
|
||||
it.foldM (init := init) f = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ => it'.foldM (init := ← f init out) f
|
||||
| .skip it' _ => it'.foldM (init := init) f
|
||||
| .done _ => return init) := by
|
||||
rw [IterM.foldM_eq_forIn, IterM.forIn_eq_match_step]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp [foldM_eq_forIn]
|
||||
|
||||
theorem IterM.fold_eq_forIn {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m]
|
||||
[IteratorLoop α m m] {f : γ → β → γ} {init : γ} {it : IterM (α := α) m β} :
|
||||
it.fold (init := init) f =
|
||||
ForIn.forIn (m := m) it init (fun x acc => pure (ForInStep.yield (f acc x))) := by
|
||||
rfl
|
||||
|
||||
theorem IterM.fold_eq_foldM {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m] {f : γ → β → γ} {init : γ}
|
||||
{it : IterM (α := α) m β} :
|
||||
it.fold (init := init) f = it.foldM (init := init) (pure <| f · ·) := by
|
||||
simp [foldM_eq_forIn, fold_eq_forIn]
|
||||
|
||||
@[simp]
|
||||
theorem IterM.forIn_pure_yield_eq_fold {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m]
|
||||
[LawfulIteratorLoop α m m] {f : β → γ → γ} {init : γ}
|
||||
{it : IterM (α := α) m β} :
|
||||
ForIn.forIn it init (fun c b => pure (.yield (f c b))) =
|
||||
it.fold (fun b c => f c b) init := by
|
||||
simp [IterM.fold_eq_forIn]
|
||||
|
||||
theorem IterM.fold_eq_match_step {α β γ : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
[Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
{f : γ → β → γ} {init : γ} {it : IterM (α := α) m β} :
|
||||
it.fold (init := init) f = (do
|
||||
match ← it.step with
|
||||
| .yield it' out _ => it'.fold (init := f init out) f
|
||||
| .skip it' _ => it'.fold (init := init) f
|
||||
| .done _ => return init) := by
|
||||
rw [fold_eq_foldM, foldM_eq_match_step]
|
||||
simp only [fold_eq_foldM]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn <;> simp
|
||||
|
||||
theorem IterM.toList_eq_fold {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.toList = it.fold (init := []) (fun l out => l ++ [out]) := by
|
||||
suffices h : ∀ l' : List β, (l' ++ ·) <$> it.toList =
|
||||
it.fold (init := l') (fun l out => l ++ [out]) by
|
||||
specialize h []
|
||||
simpa using h
|
||||
induction it using IterM.inductSteps with | step it ihy ihs =>
|
||||
intro l'
|
||||
rw [IterM.toList_eq_match_step, IterM.fold_eq_match_step]
|
||||
simp only [map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· rename_i it' out h
|
||||
specialize ihy h (l' ++ [out])
|
||||
simpa using ihy
|
||||
· rename_i it' h
|
||||
simp [ihs h]
|
||||
· simp
|
||||
|
||||
theorem IterM.drain_eq_fold {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
[Monad m] [IteratorLoop α m m] {it : IterM (α := α) m β} :
|
||||
it.drain = it.fold (init := PUnit.unit) (fun _ _ => .unit) :=
|
||||
rfl
|
||||
|
||||
theorem IterM.drain_eq_foldM {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
[Monad m] [LawfulMonad m] [IteratorLoop α m m] {it : IterM (α := α) m β} :
|
||||
it.drain = it.foldM (init := PUnit.unit) (fun _ _ => pure .unit) := by
|
||||
simp [IterM.drain_eq_fold, IterM.fold_eq_foldM]
|
||||
|
||||
theorem IterM.drain_eq_forIn {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
[Monad m] [IteratorLoop α m m] {it : IterM (α := α) m β} :
|
||||
it.drain = ForIn.forIn (m := m) it PUnit.unit (fun _ _ => pure (ForInStep.yield .unit)) := by
|
||||
simp [IterM.drain_eq_fold, IterM.fold_eq_forIn]
|
||||
|
||||
theorem IterM.drain_eq_match_step {α β : Type w} {m : Type w → Type w'} [Iterator α m β] [Finite α m]
|
||||
[Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.drain = (do
|
||||
match ← it.step with
|
||||
| .yield it' _ _ => it'.drain
|
||||
| .skip it' _ => it'.drain
|
||||
| .done _ => return .unit) := by
|
||||
rw [IterM.drain_eq_fold, IterM.fold_eq_match_step]
|
||||
simp [IterM.drain_eq_fold]
|
||||
|
||||
theorem IterM.drain_eq_map_toList {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.drain = (fun _ => .unit) <$> it.toList := by
|
||||
induction it using IterM.inductSteps with | step it ihy ihs =>
|
||||
rw [IterM.drain_eq_match_step, IterM.toList_eq_match_step]
|
||||
simp only [map_eq_pure_bind, bind_assoc]
|
||||
apply bind_congr
|
||||
intro step
|
||||
cases step using PlausibleIterStep.casesOn
|
||||
· rename_i it' out h
|
||||
simp [ihy h]
|
||||
· rename_i it' h
|
||||
simp [ihs h]
|
||||
· simp
|
||||
|
||||
theorem IterM.drain_eq_map_toListRev {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.drain = (fun _ => .unit) <$> it.toListRev := by
|
||||
simp [IterM.drain_eq_map_toList, IterM.toListRev_eq]
|
||||
|
||||
theorem IterM.drain_eq_map_toArray {α β : Type w} {m : Type w → Type w'} [Iterator α m β]
|
||||
[Finite α m] [Monad m] [LawfulMonad m] [IteratorLoop α m m] [LawfulIteratorLoop α m m]
|
||||
[IteratorCollect α m m] [LawfulIteratorCollect α m m]
|
||||
{it : IterM (α := α) m β} :
|
||||
it.drain = (fun _ => .unit) <$> it.toList := by
|
||||
simp [IterM.drain_eq_map_toList]
|
||||
|
||||
section Equivalence
|
||||
|
||||
theorem IterM.Equiv.forIn_eq {α₁ α₂ β γ : Type w} {m : Type w → Type w'}
|
||||
{n : Type w → Type w''} [Iterator α₁ m β] [Iterator α₂ m β]
|
||||
[Finite α₁ m] [Finite α₂ m]
|
||||
|
|
@ -296,6 +74,4 @@ theorem IterM.Equiv.drain_eq {α₁ α₂ β : Type w} {m : Type w → Type w'}
|
|||
ita.drain = itb.drain := by
|
||||
simp [IterM.drain_eq_fold, h.fold_eq]
|
||||
|
||||
end Equivalence
|
||||
|
||||
end Std.Iterators
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import Init.Control.Lawful.Basic
|
|||
import Init.Ext
|
||||
import Init.Internal.Order
|
||||
import Init.Core
|
||||
import Std.Data.Iterators.Basic
|
||||
import Std.Data.Iterators.PostConditionMonad
|
||||
import Init.Data.Iterators.Basic
|
||||
import Init.Data.Iterators.PostconditionMonad
|
||||
import Std.Data.Iterators.Lemmas.Equivalence.HetT
|
||||
|
||||
namespace Std.Iterators
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import Init.Control.Lawful.Basic
|
|||
import Init.Data.Subtype
|
||||
import Init.PropLemmas
|
||||
import Init.Classical
|
||||
import Std.Data.Internal.LawfulMonadLiftFunction
|
||||
import Std.Data.Iterators.PostConditionMonad
|
||||
import Init.Data.Iterators.Internal.LawfulMonadLiftFunction
|
||||
import Init.Data.Iterators.PostconditionMonad
|
||||
|
||||
namespace Std.Internal
|
||||
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Lemmas.Monadic.Basic
|
||||
import Init.Data.Iterators.Lemmas.Monadic.Basic
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Collect
|
||||
import Std.Data.Iterators.Producers.Array
|
||||
import Std.Data.Iterators.Producers.List
|
||||
import Std.Data.Iterators.Lemmas.Producers.Monadic.Array
|
||||
|
||||
/-!
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Lemmas.Producers.Monadic.Empty
|
||||
import Std.Data.Iterators.Lemmas.Consumers
|
||||
import Init.Data.Iterators.Lemmas.Consumers
|
||||
import Std.Data.Iterators.Producers.Empty
|
||||
|
||||
namespace Std.Iterators
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Consumers
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Collect
|
||||
import Init.Data.Iterators.Consumers
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Collect
|
||||
import Std.Data.Iterators.Producers.List
|
||||
import Std.Data.Iterators.Lemmas.Producers.Monadic.List
|
||||
|
||||
/-!
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Internal.LawfulMonadLiftFunction
|
||||
import Init.Data.Iterators.Internal.LawfulMonadLiftFunction
|
||||
import Init.Data.Iterators.Consumers
|
||||
import Std.Data.Iterators.Producers.Monadic.Array
|
||||
import Std.Data.Iterators.Consumers
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Std.Data.Iterators.Lemmas.Producers.Monadic.List
|
||||
import Std.Data.Iterators.Lemmas.Equivalence.Basic
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ Authors: Paul Reichert
|
|||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Producers.Monadic.Empty
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic.Loop
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic.Loop
|
||||
|
||||
namespace Std.Iterators
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Init.Data.Iterators.Consumers
|
||||
import Init.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Init.Data.Iterators.Internal.LawfulMonadLiftFunction
|
||||
import Std.Data.Iterators.Producers.Monadic.List
|
||||
import Std.Data.Iterators.Consumers
|
||||
import Std.Data.Iterators.Lemmas.Consumers.Monadic
|
||||
import Std.Data.Internal.LawfulMonadLiftFunction
|
||||
import Std.Data.Iterators.Lemmas.Equivalence.Basic
|
||||
|
||||
/-!
|
||||
# Lemmas about list iterators
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ Authors: Paul Reichert
|
|||
prelude
|
||||
import Init.Data.Option.Lemmas
|
||||
import Std.Data.Iterators.Producers.Repeat
|
||||
import Std.Data.Iterators.Consumers.Access
|
||||
import Std.Data.Iterators.Consumers.Collect
|
||||
import Init.Data.Iterators.Consumers.Access
|
||||
import Init.Data.Iterators.Consumers.Collect
|
||||
import Std.Data.Iterators.Combinators.Take
|
||||
import Std.Data.Iterators.Lemmas.Combinators.Take
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ Authors: Paul Reichert
|
|||
prelude
|
||||
import Init.Data.Nat.Lemmas
|
||||
import Init.RCases
|
||||
import Std.Data.Iterators.Consumers
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.Consumers
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
|
||||
/-!
|
||||
# Array iterator
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Consumers.Collect
|
||||
import Std.Data.Iterators.Consumers.Loop
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.Consumers.Collect
|
||||
import Init.Data.Iterators.Consumers.Loop
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
|
||||
/-!
|
||||
This file provides an empty iterator.
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ Authors: Paul Reichert
|
|||
prelude
|
||||
import Init.Data.Nat.Lemmas
|
||||
import Init.RCases
|
||||
import Std.Data.Iterators.Consumers
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.Consumers
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
|
||||
/-!
|
||||
# List iterator
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
|
|||
Authors: Paul Reichert
|
||||
-/
|
||||
prelude
|
||||
import Std.Data.Iterators.Consumers.Monadic
|
||||
import Std.Data.Iterators.Internal.Termination
|
||||
import Init.Data.Iterators.Consumers.Monadic
|
||||
import Init.Data.Iterators.Internal.Termination
|
||||
|
||||
/-!
|
||||
# Function-unfolding iterator
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue