@@ -639,7 +639,7 @@ section Size
639639This is the implementation of the default instance `IteratorSize.defaultImplementation`.
640640-/
641641@[always_inline, inline]
642- def IterM.DefaultConsumers.size {α : Type w} {m : Type w → Type w'} [Monad m] {β : Type w}
642+ def IterM.DefaultConsumers.count {α : Type w} {m : Type w → Type w'} [Monad m] {β : Type w}
643643 [Iterator α m β] [IteratorLoop α m m] [Finite α m] (it : IterM (α := α) m β) :
644644 m (ULift Nat) :=
645645 it.fold (init := .up 0 ) fun acc _ => .up (acc.down + 1 )
@@ -648,70 +648,89 @@ def IterM.DefaultConsumers.size {α : Type w} {m : Type w → Type w'} [Monad m]
648648This is the implementation of the default instance `IteratorSizePartial.defaultImplementation`.
649649-/
650650@[always_inline, inline]
651- def IterM.DefaultConsumers.sizePartial {α : Type w} {m : Type w → Type w'} [Monad m] {β : Type w}
651+ def IterM.DefaultConsumers.countPartial {α : Type w} {m : Type w → Type w'} [Monad m] {β : Type w}
652652 [Iterator α m β] [IteratorLoopPartial α m m] (it : IterM (α := α) m β) :
653653 m (ULift Nat) :=
654654 it.allowNontermination.fold (init := .up 0 ) fun acc _ => .up (acc.down + 1 )
655655
656+ /--
657+ Steps through the whole iterator, counting the number of outputs emitted.
658+
659+ **Performance** :
660+
661+ linear in the number of steps taken by the iterator
662+ -/
663+ @[always_inline, inline]
664+ def IterM.count {α : Type } {m : Type → Type w'} {β : Type } [Iterator α m β] [IteratorLoop α m m]
665+ [Monad m] [Finite α m] (it : IterM (α := α) m β) : m Nat :=
666+ ULift.down <$> IterM.DefaultConsumers.count it
667+
668+ /--
669+ Steps through the whole iterator, counting the number of outputs emitted.
670+
671+ **Performance** :
672+
673+ linear in the number of steps taken by the iterator
674+ -/
675+ @[always_inline, inline]
676+ def IterM.Partial.count {α : Type } {m : Type → Type w'} {β : Type } [Iterator α m β]
677+ [IteratorLoopPartial α m m] [Monad m] (it : IterM.Partial (α := α) m β)
678+ [IteratorSizePartial α m] : m Nat :=
679+ ULift.down <$> IterM.DefaultConsumers.countPartial it.it
680+
681+ set_option pp.universes true
656682/--
657683This is the default implementation of the `IteratorSize` class.
658684It simply iterates using `IteratorLoop` and counts the elements.
659685For certain iterators, more efficient implementations are possible and should be used instead.
660686-/
661687@[always_inline, inline]
662- def IteratorSize.defaultImplementation {α β : Type w} {m : Type w → Type w'} [Monad m]
688+ def IteratorSize.defaultImplementation {α β : Type w} [Monad m]
663689 [Iterator α m β] [Finite α m] [IteratorLoop α m m] :
664690 IteratorSize α m where
665- size := IterM.DefaultConsumers.size
666-
691+ size := IterM.DefaultConsumers.count
667692
668693/--
669694This is the default implementation of the `IteratorSizePartial` class.
670695It simply iterates using `IteratorLoopPartial` and counts the elements.
671696For certain iterators, more efficient implementations are possible and should be used instead.
672697-/
673698@[always_inline, inline]
674- instance IteratorSizePartial.defaultImplementation {α β : Type w} {m : Type w → Type w'} [Monad m]
699+ instance IteratorSizePartial.defaultImplementation {α β : Type w} [Monad m]
675700 [Iterator α m β] [IteratorLoopPartial α m m] :
676701 IteratorSizePartial α m where
677- size := IterM.DefaultConsumers.sizePartial
702+ size := IterM.DefaultConsumers.countPartial
678703
679704/--
680- Computes how many elements the iterator returns. In monadic situations, it is unclear which effects
681- are caused by calling `size`, and if the monad is nondeterministic, it is also unclear what the
682- returned value should be. The reference implementation, `IteratorSize.defaultImplementation`,
683- simply iterates over the whole iterator monadically, counting the number of emitted values.
684- An `IteratorSize` instance is considered lawful if it is equal to the reference implementation.
705+ Computes how many elements the iterator returns. In contrast to `count`, this function might take
706+ shortcuts instead of actually stepping through the whole iterator.
685707
686708**Performance** :
687709
688- Default performance is linear in the number of steps taken by the iterator.
710+ Depends on the concrete type of the iterator. The default implementation, which is identical to
711+ `count`, is linear, but it is sometimes possible to provide an O(1) implementation.
689712-/
690713@[always_inline, inline]
691- def IterM.size {α : Type } {m : Type → Type w'} { β : Type } [Iterator α m β] [Monad m ]
692- (it : IterM (α := α) m β) [IteratorSize α m ] : m Nat :=
693- ULift.down <$> IteratorSize.size it
714+ def IterM.size {α : Type } {β : Type } [Iterator α Id β ]
715+ (it : IterM (α := α) Id β) [IteratorSize α Id ] : Nat :=
716+ ( IteratorSize.size it).run.down
694717
695718/--
696- Computes how many elements the iterator emits.
697-
698- With monadic iterators (`IterM`), it is unclear which effects
699- are caused by calling `size`, and if the monad is nondeterministic, it is also unclear what the
700- returned value should be. The reference implementation, `IteratorSize.defaultImplementation`,
701- simply iterates over the whole iterator monadically, counting the number of emitted values.
702- An `IteratorSize` instance is considered lawful if it is equal to the reference implementation.
719+ Computes how many elements the iterator returns. In contrast to `count`, this function might take
720+ shortcuts instead of actually stepping through the whole iterator.
703721
704722This is the partial version of `size`. It does not require a proof of finiteness and might loop
705723forever. It is not possible to verify the behavior in Lean because it uses `partial`.
706724
707725**Performance** :
708726
709- Default performance is linear in the number of steps taken by the iterator.
727+ Depends on the concrete type of the iterator. The default implementation, which is identical to
728+ `count`, is linear, but it is sometimes possible to provide an O(1) implementation.
710729-/
711730@[always_inline, inline]
712- def IterM.Partial.size {α : Type } {m : Type → Type w'} { β : Type } [Iterator α m β] [Monad m ]
713- (it : IterM.Partial (α := α) m β) [IteratorSizePartial α m ] : m Nat :=
714- ULift.down <$> IteratorSizePartial.size it.it
731+ def IterM.Partial.size {α : Type } {β : Type } [Iterator α Id β ]
732+ (it : IterM.Partial (α := α) Id β) [IteratorSizePartial α Id ] : Nat :=
733+ ( IteratorSizePartial.size it.it).run.down
715734
716735end Size
717736
0 commit comments