@@ -19,16 +19,6 @@ namespace Std
19
19
20
20
namespace Iterators
21
21
22
- /--
23
- `BaseIter` is the common data structure underlying `Iter` and `IterM`. API users should never
24
- use `BaseIter` directly, only `Iter` and `IterM`.
25
- -/
26
- structure BaseIter {α : Type w} (m : Type w → Type w') (β : Type w) : Type w where
27
- /--
28
- Internal implementation detail of the iterator.
29
- -/
30
- internalState : α
31
-
32
22
/--
33
23
An iterator that sequentially emits values of type `β` in the monad `m`. It may be finite
34
24
or infinite.
@@ -68,7 +58,9 @@ def x := [1, 2, 3].iterM IO
68
58
def x := ([1, 2, 3].iterM IO : IterM IO Nat)
69
59
```
70
60
-/
71
- def IterM {α : Type w} (m : Type w → Type w') (β : Type w) := BaseIter (α := α) m β
61
+ structure IterM {α : Type w} (m : Type w → Type w') (β : Type w) where
62
+ /-- Internal implementation detail of the iterator. -/
63
+ internalState : α
72
64
73
65
/--
74
66
An iterator that sequentially emits values of type `β`. It may be finite
@@ -109,29 +101,41 @@ def x := [1, 2, 3].iter
109
101
def x := ([1, 2, 3].iter : Iter Nat)
110
102
```
111
103
-/
112
- def Iter {α : Type w} (β : Type w) := BaseIter (α := α) Id β
104
+ structure Iter {α : Type w} (β : Type w) where
105
+ /-- Internal implementation detail of the iterator. -/
106
+ internalState : α
113
107
114
108
/--
115
109
Converts a pure iterator (`Iter β`) into a monadic iterator (`IterM Id β`) in the
116
110
identity monad `Id`.
117
111
-/
118
112
def Iter.toIterM {α : Type w} {β : Type w} (it : Iter (α := α) β) : IterM (α := α) Id β :=
119
- it
113
+ ⟨it.internalState⟩
120
114
121
115
/--
122
116
Converts a monadic iterator (`IterM Id β`) over `Id` into a pure iterator (`Iter β`).
123
117
-/
124
- def IterM.toPureIter {α : Type w} {β : Type w} (it : IterM (α := α) Id β) : Iter (α := α) β :=
125
- it
118
+ def IterM.toIter {α : Type w} {β : Type w} (it : IterM (α := α) Id β) : Iter (α := α) β :=
119
+ ⟨it.internalState⟩
120
+
121
+ @[simp]
122
+ theorem Iter.toIter_toIterM {α : Type w} {β : Type w} (it : Iter (α := α) β) :
123
+ it.toIterM.toIter = it :=
124
+ rfl
126
125
127
126
@[simp]
128
- theorem Iter.toPureIter_toIterM {α : Type w} {β : Type w} (it : Iter (α := α) β) :
129
- it.toIterM.toPureIter = it :=
127
+ theorem Iter.toIter_comp_toIterM {α : Type w} {β : Type w} :
128
+ IterM.toIter ∘ Iter.toIterM (α := α) (β := β) = id :=
130
129
rfl
131
130
132
131
@[simp]
133
- theorem Iter.toIterM_toPureIter {α : Type w} {β : Type w} (it : IterM (α := α) Id β) :
134
- it.toPureIter.toIterM = it :=
132
+ theorem Iter.toIterM_toIter {α : Type w} {β : Type w} (it : IterM (α := α) Id β) :
133
+ it.toIter.toIterM = it :=
134
+ rfl
135
+
136
+ @[simp]
137
+ theorem Iter.toIterM_comp_toIter {α : Type w} {β : Type w} :
138
+ Iter.toIterM ∘ IterM.toIter (α := α) (β := β) = id :=
135
139
rfl
136
140
137
141
section IterStep
@@ -169,6 +173,27 @@ def IterStep.successor : IterStep α β → Option α
169
173
| .skip it => some it
170
174
| .done => none
171
175
176
+ /--
177
+ If present, applies `f` to the iterator of an `IterStep` and replaces the iterator
178
+ with the result of the application of `f`.
179
+ -/
180
+ @[always_inline, inline]
181
+ def IterStep.mapIterator {α' : Type u'} (f : α → α') : IterStep α β → IterStep α' β
182
+ | .yield it out => .yield (f it) out
183
+ | .skip it => .skip (f it)
184
+ | .done => .done
185
+
186
+ @[simp]
187
+ theorem IterStep.mapIterator_mapIterator {α' : Type u'} {α'' : Type u''}
188
+ {f : α → α'} {g : α' → α''} {step : IterStep α β} :
189
+ (step.mapIterator f).mapIterator g = step.mapIterator (g ∘ f) := by
190
+ cases step <;> rfl
191
+
192
+ @[simp]
193
+ theorem IterStep.mapIterator_id {step : IterStep α β} :
194
+ step.mapIterator id = step := by
195
+ cases step <;> rfl
196
+
172
197
/--
173
198
A variant of `IterStep` that bundles the step together with a proof that it is "plausible".
174
199
The plausibility predicate will later be chosen to assert that a state is a plausible successor
@@ -203,6 +228,20 @@ def PlausibleIterStep.done {IsPlausibleStep : IterStep α β → Prop}
203
228
(h : IsPlausibleStep .done) : PlausibleIterStep IsPlausibleStep :=
204
229
⟨.done, h⟩
205
230
231
+ /--
232
+ A more convenient `cases` eliminator for `PlausibleIterStep`.
233
+ -/
234
+ @[elab_as_elim, cases_eliminator]
235
+ abbrev PlausibleIterStep.casesOn {IsPlausibleStep : IterStep α β → Prop }
236
+ {motive : PlausibleIterStep IsPlausibleStep → Sort x} (s : PlausibleIterStep IsPlausibleStep)
237
+ (yield : ∀ it' out h, motive ⟨.yield it' out, h⟩)
238
+ (skip : ∀ it' h, motive ⟨.skip it', h⟩)
239
+ (done : ∀ h, motive ⟨.done, h⟩) : motive s :=
240
+ match s with
241
+ | .yield it' out h => yield it' out h
242
+ | .skip it' h => skip it' h
243
+ | .done h => done h
244
+
206
245
end IterStep
207
246
208
247
/--
@@ -296,7 +335,7 @@ is up to the `Iterator` instance but it should be strong enough to allow termina
296
335
-/
297
336
def Iter.IsPlausibleStep {α : Type w} {β : Type w} [Iterator α Id β]
298
337
(it : Iter (α := α) β) (step : IterStep (Iter (α := α) β) β) : Prop :=
299
- it.toIterM.IsPlausibleStep step
338
+ it.toIterM.IsPlausibleStep ( step.mapIterator Iter.toIterM)
300
339
301
340
/--
302
341
The type of the step object returned by `Iter.step`, containing an `IterStep`
@@ -305,6 +344,37 @@ and a proof that this is a plausible step for the given iterator.
305
344
def Iter.Step {α : Type w} {β : Type w} [Iterator α Id β] (it : Iter (α := α) β) :=
306
345
PlausibleIterStep (Iter.IsPlausibleStep it)
307
346
347
+ /--
348
+ Converts an `Iter.Step` into an `IterM.Step`.
349
+ -/
350
+ @[always_inline, inline]
351
+ def Iter.Step.toMonadic {α : Type w} {β : Type w} [Iterator α Id β] {it : Iter (α := α) β}
352
+ (step : it.Step) : it.toIterM.Step :=
353
+ ⟨step.val.mapIterator Iter.toIterM, step.property⟩
354
+
355
+ /--
356
+ Converts an `IterM.Step` into an `Iter.Step`.
357
+ -/
358
+ @[always_inline, inline]
359
+ def IterM.Step.toPure {α : Type w} {β : Type w} [Iterator α Id β] {it : IterM (α := α) Id β}
360
+ (step : it.Step) : it.toIter.Step :=
361
+ ⟨step.val.mapIterator IterM.toIter, (by simp [Iter.IsPlausibleStep, step.property])⟩
362
+
363
+ @[simp]
364
+ theorem IterM.Step.toPure_yield {α β : Type w} [Iterator α Id β] {it : IterM (α := α) Id β}
365
+ {it' out h} : IterM.Step.toPure (⟨.yield it' out, h⟩ : it.Step) = .yield it'.toIter out h :=
366
+ rfl
367
+
368
+ @[simp]
369
+ theorem IterM.Step.toPure_skip {α β : Type w} [Iterator α Id β] {it : IterM (α := α) Id β}
370
+ {it' h} : IterM.Step.toPure (⟨.skip it', h⟩ : it.Step) = .skip it'.toIter h :=
371
+ rfl
372
+
373
+ @[simp]
374
+ theorem IterM.Step.toPure_done {α β : Type w} [Iterator α Id β] {it : IterM (α := α) Id β}
375
+ {h} : IterM.Step.toPure (⟨.done, h⟩ : it.Step) = .done h :=
376
+ rfl
377
+
308
378
/--
309
379
Asserts that a certain output value could plausibly be emitted by the given iterator in its next
310
380
step.
@@ -319,15 +389,15 @@ given iterator `it`.
319
389
-/
320
390
def Iter.IsPlausibleSuccessorOf {α : Type w} {β : Type w} [Iterator α Id β]
321
391
(it' it : Iter (α := α) β) : Prop :=
322
- it'.toIterM.IsPlausibleSuccessorOf it
392
+ it'.toIterM.IsPlausibleSuccessorOf it.toIterM
323
393
324
394
/--
325
395
Asserts that a certain iterator `it'` could plausibly be the directly succeeding iterator of another
326
396
given iterator `it` while no value is emitted (see `IterStep.skip`).
327
397
-/
328
398
def Iter.IsPlausibleSkipSuccessorOf {α : Type w} {β : Type w} [Iterator α Id β]
329
399
(it' it : Iter (α := α) β) : Prop :=
330
- it'.toIterM.IsPlausibleSkipSuccessorOf it
400
+ it'.toIterM.IsPlausibleSkipSuccessorOf it.toIterM
331
401
332
402
/--
333
403
Makes a single step with the given iterator `it`, potentially emitting a value and providing a
@@ -336,7 +406,7 @@ the termination measures `it.finitelyManySteps` and `it.finitelyManySkips`.
336
406
-/
337
407
@[always_inline, inline]
338
408
def Iter.step {α β : Type w} [Iterator α Id β] (it : Iter (α := α) β) : it.Step :=
339
- it.toIterM.step
409
+ it.toIterM.step.run.toPure
340
410
341
411
end Pure
342
412
@@ -415,14 +485,14 @@ with `IterM.finitelyManySteps`.
415
485
theorem Iter.TerminationMeasures.Finite.rel_of_yield
416
486
{α : Type w} {β : Type w} [Iterator α Id β]
417
487
{it it' : Iter (α := α) β} {out : β} (h : it.IsPlausibleStep (.yield it' out)) :
418
- IterM.TerminationMeasures.Finite.Rel ⟨it'⟩ ⟨it⟩ :=
488
+ IterM.TerminationMeasures.Finite.Rel ⟨it'.toIterM ⟩ ⟨it.toIterM ⟩ :=
419
489
IterM.TerminationMeasures.Finite.rel_of_yield h
420
490
421
491
@[inherit_doc Iter.TerminationMeasures.Finite.rel_of_yield]
422
492
theorem Iter.TerminationMeasures.Finite.rel_of_skip
423
493
{α : Type w} {β : Type w} [Iterator α Id β]
424
494
{it it' : Iter (α := α) β} (h : it.IsPlausibleStep (.skip it')) :
425
- IterM.TerminationMeasures.Finite.Rel ⟨it'⟩ ⟨it⟩ :=
495
+ IterM.TerminationMeasures.Finite.Rel ⟨it'.toIterM ⟩ ⟨it.toIterM ⟩ :=
426
496
IterM.TerminationMeasures.Finite.rel_of_skip h
427
497
428
498
macro_rules | `(tactic| decreasing_trivial) => `(tactic|
0 commit comments