@@ -88,52 +88,6 @@ class IteratorLoopPartial (α : Type w) (m : Type w → Type w') {β : Type w} [
8888 (it : IterM (α := α) m β) → γ →
8989 ((b : β) → it.IsPlausibleIndirectOutput b → (c : γ) → n (ForInStep γ)) → n γ
9090
91- /--
92- `IteratorSize α m` provides an implementation of the `IterM.size` function.
93-
94- This class is experimental and users of the iterator API should not explicitly depend on it.
95- They can, however, assume that consumers that require an instance will work for all iterators
96- provided by the standard library.
97- -/
98- class IteratorSize (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β] where
99- size : IterM (α := α) m β → Nat
100-
101- /--
102- `IteratorSizePartial α m` provides an implementation of the `IterM.Partial.size` function that
103- can be used as `it.allowTermination.size`.
104-
105- This class is experimental and users of the iterator API should not explicitly depend on it.
106- They can, however, assume that consumers that require an instance will work for all iterators
107- provided by the standard library.
108- -/
109- class IteratorSizePartial (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β] where
110- size : IterM (α := α) m β → Nat
111-
112- /--
113- `LawfulIteratorSize α m` ensures that the `size` function of an iterator is well-behaved.
114- More concretely, it ensures that the successor's size is one less in case of an
115- `IterStep.yield` result and equal in the case of an `IterStep.skip` result. The iterator may only
116- finish immediately if its size is zero. All of these properties are expressed using the
117- `IterM.IsPlausibleStep` predicate.
118-
119- This class is experimental and users of the iterator API should not explicitly depend on it.
120- -/
121- class LawfulIteratorSize (α : Type w) {β : Type w} [Iterator α m β] [IteratorSize α m]
122- [Monad m] where
123- ex {it : IterM (α := α) m β} :
124- ∃ s : m (Shrink ({ s : IterStep (IterM (α := α) m β) β // match s with
125- | .yield it' _ => IteratorSize.size it = IteratorSize.size it' + 1
126- | .skip it' => IteratorSize.size it = IteratorSize.size it'
127- | .done => IteratorSize.size it = 0 })),
128- (Shrink.deflate <| Subtype.val <| Shrink.inflate ·) <$> s =
129- (Shrink.deflate <| Subtype.val <| Shrink.inflate ·) <$> it.step
130- -- size_eq_of_yield {it it' : IterM (α := α) m β} {out} :
131- -- it.IsPlausibleStep (.yield it' out) → IteratorSize.size it = IteratorSize.size it' + 1
132- -- size_eq_of_skip {it it' : IterM (α := α) m β} :
133- -- it.IsPlausibleStep (.skip it') → IteratorSize.size it = IteratorSize.size it'
134- -- size_eq_of_done {it : IterM (α := α) m β} :
135- -- it.IsPlausibleStep .done → IteratorSize.size it = 0
136-
13791end Typeclasses
13892
13993/-- Internal implementation detail of the iterator library. -/
@@ -340,7 +294,7 @@ instance {m : Type w → Type w'} {n : Type w → Type w''}
340294 forM it f := forIn it PUnit.unit (fun out _ => do f out; return .yield .unit)
341295
342296instance {m : Type w → Type w'} {n : Type w → Type w''}
343- {α : Type w} {β : Type w} [Iterator α m β] [Finite α m] [ IteratorLoopPartial α m n]
297+ {α : Type w} {β : Type w} [Iterator α m β] [IteratorLoopPartial α m n]
344298 [MonadLiftT m n] :
345299 ForM n (IterM.Partial (α := α) m β) β where
346300 forM it f := forIn it PUnit.unit (fun out _ => do f out; return .yield .unit)
@@ -658,14 +612,14 @@ def IterM.Partial.find? {α β : Type w} {m : Type w → Type w'} [Monad m] [Ite
658612 m (Option β) :=
659613 it.findM? (pure <| .up <| f ·)
660614
661- section Size
615+ section Count
662616
663617/--
664618This is the implementation of the default instance `IteratorSize.defaultImplementation`.
665619-/
666620@[always_inline, inline]
667621def IterM.DefaultConsumers.count {α : Type w} {m : Type w → Type w'} [Monad m] {β : Type w}
668- [Iterator α m β] [IteratorLoop α m m ] [Finite α m] (it : IterM (α := α) m β) :
622+ [Iterator α m β] [Finite α m] [IteratorLoop α m m] (it : IterM (α := α) m β) :
669623 m (ULift Nat) :=
670624 it.fold (init := .up 0 ) fun acc _ => .up (acc.down + 1 )
671625
@@ -686,9 +640,10 @@ Steps through the whole iterator, counting the number of outputs emitted.
686640linear in the number of steps taken by the iterator
687641-/
688642@[always_inline, inline]
689- def IterM.count {α : Type } {m : Type → Type w'} {β : Type } [Iterator α m β] [IteratorLoop α m m]
690- [Monad m] [Finite α m] (it : IterM (α := α) m β) : m Nat :=
691- ULift.down <$> IterM.DefaultConsumers.count it
643+ def IterM.count {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β] [Finite α m]
644+ [IteratorLoop α m m]
645+ [Monad m] (it : IterM (α := α) m β) : m (ULift Nat) :=
646+ IterM.DefaultConsumers.count it
692647
693648/--
694649Steps through the whole iterator, counting the number of outputs emitted.
@@ -698,73 +653,10 @@ Steps through the whole iterator, counting the number of outputs emitted.
698653linear in the number of steps taken by the iterator
699654-/
700655@[always_inline, inline]
701- def IterM.Partial.count {α : Type } {m : Type → Type w'} {β : Type } [Iterator α m β]
702- [IteratorLoopPartial α m m] [Monad m] (it : IterM.Partial (α := α) m β)
703- [IteratorSizePartial α m] : m Nat :=
704- ULift.down <$> IterM.DefaultConsumers.countPartial it.it
705-
706- set_option pp.universes true
707- /--
708- This is the default implementation of the `IteratorSize` class.
709- It simply iterates using `IteratorLoop` and counts the elements.
710- For certain iterators, more efficient implementations are possible and should be used instead.
711- -/
712- @[always_inline, inline]
713- def IteratorSize.defaultImplementation {α β : Type w}
714- [Iterator α Id β] [Finite α Id] [IteratorLoop α Id Id] :
715- IteratorSize α Id where
716- size it := IterM.DefaultConsumers.count it |>.run.down
717-
718- /--
719- This is the default implementation of the `IteratorSizePartial` class.
720- It simply iterates using `IteratorLoopPartial` and counts the elements.
721- For certain iterators, more efficient implementations are possible and should be used instead.
722- -/
723- @[always_inline, inline]
724- instance IteratorSizePartial.defaultImplementation {α β : Type w}
725- [Iterator α Id β] [IteratorLoopPartial α Id Id] :
726- IteratorSizePartial α Id where
727- size it := IterM.DefaultConsumers.countPartial it |>.run.down
728-
729- /--
730- Computes how many elements the iterator returns. In contrast to `count`, this function might take
731- shortcuts instead of actually stepping through the whole iterator and it has no monadic side effects.
732-
733- This operation is not available for all iterators. If you get an error that `IteratorSize` cannot
734- be synthesized, consider using `count` instead. It is always available and steps through the whole
735- iterator to compute its size.
736-
737- **Performance** :
738-
739- Depends on the concrete type of the iterator. The default implementation, which is identical to
740- `count`, is linear, but it is sometimes possible to provide an O(1) implementation.
741- -/
742- @[always_inline, inline]
743- def IterM.size {α : Type w} {β : Type w} [Iterator α m β] [IteratorSize α m]
744- (it : IterM (α := α) m β) : Nat :=
745- IteratorSize.size it
746-
747- /--
748- Computes how many elements the iterator returns. In contrast to `count`, this function might take
749- shortcuts instead of actually stepping through the whole iterator.
750-
751- This operation is not available for all iterators. If you get an error that `IteratorSizePartial`
752- cannot be synthesized, consider using `count` instead. It is always available and steps through the
753- whole iterator to compute its size.
754-
755- This is the partial version of `size`. It does not require a proof of finiteness and might loop
756- forever. It is not possible to verify the behavior in Lean because it uses `partial`.
757-
758- **Performance** :
759-
760- Depends on the concrete type of the iterator. The default implementation, which is identical to
761- `count`, is linear, but it is sometimes possible to provide an O(1) implementation.
762- -/
763- @[always_inline, inline]
764- def IterM.Partial.size {α : Type w} {β : Type w} [Iterator α m β]
765- (it : IterM.Partial (α := α) m β) [IteratorSizePartial α m] : Nat :=
766- IteratorSizePartial.size it.it
656+ def IterM.Partial.count {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
657+ [IteratorLoopPartial α m m] [Monad m] (it : IterM.Partial (α := α) m β) : m (ULift Nat) :=
658+ IterM.DefaultConsumers.countPartial it.it
767659
768- end Size
660+ end Count
769661
770662end Std.Iterators
0 commit comments