Skip to content

Commit 73cbf72

Browse files
committed
address remarks
1 parent 3c41364 commit 73cbf72

File tree

7 files changed

+89
-78
lines changed

7 files changed

+89
-78
lines changed

src/Std/Data/Iterators/Basic.lean

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -115,27 +115,27 @@ def Iter.toIterM {α : Type w} {β : Type w} (it : Iter (α := α) β) : IterM (
115115
/--
116116
Converts a monadic iterator (`IterM Id β`) over `Id` into a pure iterator (`Iter β`).
117117
-/
118-
def IterM.toPureIter {α : Type w} {β : Type w} (it : IterM (α := α) Id β) : Iter (α := α) β :=
118+
def IterM.toIter {α : Type w} {β : Type w} (it : IterM (α := α) Id β) : Iter (α := α) β :=
119119
⟨it.internalState⟩
120120

121121
@[simp]
122-
theorem Iter.toPureIter_toIterM {α : Type w} {β : Type w} (it : Iter (α := α) β) :
123-
it.toIterM.toPureIter = it :=
122+
theorem Iter.toIter_toIterM {α : Type w} {β : Type w} (it : Iter (α := α) β) :
123+
it.toIterM.toIter = it :=
124124
rfl
125125

126126
@[simp]
127-
theorem Iter.toPureIter_comp_toIterM {α : Type w} {β : Type w} :
128-
IterM.toPureIter ∘ Iter.toIterM (α := α) (β := β) = id :=
127+
theorem Iter.toIter_comp_toIterM {α : Type w} {β : Type w} :
128+
IterM.toIter ∘ Iter.toIterM (α := α) (β := β) = id :=
129129
rfl
130130

131131
@[simp]
132-
theorem Iter.toIterM_toPureIter {α : Type w} {β : Type w} (it : IterM (α := α) Id β) :
133-
it.toPureIter.toIterM = it :=
132+
theorem Iter.toIterM_toIter {α : Type w} {β : Type w} (it : IterM (α := α) Id β) :
133+
it.toIter.toIterM = it :=
134134
rfl
135135

136136
@[simp]
137-
theorem Iter.toIterM_comp_toPureIter {α : Type w} {β : Type w} :
138-
Iter.toIterM ∘ IterM.toPureIter (α := α) (β := β) = id :=
137+
theorem Iter.toIterM_comp_toIter {α : Type w} {β : Type w} :
138+
Iter.toIterM ∘ IterM.toIter (α := α) (β := β) = id :=
139139
rfl
140140

141141
section IterStep
@@ -184,8 +184,8 @@ def IterStep.mapIterator {α' : Type u'} (f : α → α') : IterStep α β → I
184184
| .done => .done
185185

186186
@[simp]
187-
theorem IterStep.mapIterator_mapIterator {α' : Type u'} {f : α → α'} {g : α' → α}
188-
{step : IterStep α β} :
187+
theorem IterStep.mapIterator_mapIterator {α' : Type u'} {α'' : Type u''}
188+
{f : α → α'} {g : α' → α''} {step : IterStep α β} :
189189
(step.mapIterator f).mapIterator g = step.mapIterator (g ∘ f) := by
190190
cases step <;> rfl
191191

@@ -229,35 +229,18 @@ def PlausibleIterStep.done {IsPlausibleStep : IterStep α β → Prop}
229229
⟨.done, h⟩
230230

231231
/--
232-
An inductive type that makes it easier to apply the `cases` tactic to a
233-
`PlausibleIterStep`. See `PlausibleIterStep.casesHelper` for more information.
232+
A more convenient `cases` eliminator for `PlausibleIterStep`.
234233
-/
235-
inductive PlausibleIterStep.CasesHelper {IsPlausibleStep : IterStep α β → Prop} :
236-
PlausibleIterStep IsPlausibleStep → Type _ where
237-
| yield (it' out h) : CasesHelper ⟨.yield it' out, h⟩
238-
| skip (it' h) : CasesHelper ⟨.skip it', h⟩
239-
| done (h) : CasesHelper ⟨.done, h⟩
240-
241-
/--
242-
Because `PlausibleIterStep` is a subtype of `IterStep`, it is tedious to use
243-
the `cases` tactic:
244-
245-
```lean
246-
obtain ⟨step, h⟩ := step
247-
cases step
248-
```
249-
250-
Using `casesHelper`, the case distinction can be done more ergonomically.
251-
252-
```lean
253-
cases step.casesHelper
254-
```
255-
-/
256-
def PlausibleIterStep.casesHelper {IsPlausibleStep : IterStep α β → Prop} :
257-
(step : PlausibleIterStep IsPlausibleStep) → PlausibleIterStep.CasesHelper step
258-
| .yield it' out h => .yield it' out h
259-
| .skip it' h => .skip it' h
260-
| .done h => .done h
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
261244

262245
end IterStep
263246

@@ -374,17 +357,17 @@ Converts an `IterM.Step` into an `Iter.Step`.
374357
-/
375358
@[always_inline, inline]
376359
def IterM.Step.toPure {α : Type w} {β : Type w} [Iterator α Id β] {it : IterM (α := α) Id β}
377-
(step : it.Step) : it.toPureIter.Step :=
378-
⟨step.val.mapIterator IterM.toPureIter, (by simp [Iter.IsPlausibleStep, step.property])⟩
360+
(step : it.Step) : it.toIter.Step :=
361+
⟨step.val.mapIterator IterM.toIter, (by simp [Iter.IsPlausibleStep, step.property])⟩
379362

380363
@[simp]
381364
theorem IterM.Step.toPure_yield {α β : Type w} [Iterator α Id β] {it : IterM (α := α) Id β}
382-
{it' out h} : IterM.Step.toPure (⟨.yield it' out, h⟩ : it.Step) = .yield it'.toPureIter out h :=
365+
{it' out h} : IterM.Step.toPure (⟨.yield it' out, h⟩ : it.Step) = .yield it'.toIter out h :=
383366
rfl
384367

385368
@[simp]
386369
theorem IterM.Step.toPure_skip {α β : Type w} [Iterator α Id β] {it : IterM (α := α) Id β}
387-
{it' h} : IterM.Step.toPure (⟨.skip it', h⟩ : it.Step) = .skip it'.toPureIter h :=
370+
{it' h} : IterM.Step.toPure (⟨.skip it', h⟩ : it.Step) = .skip it'.toIter h :=
388371
rfl
389372

390373
@[simp]

src/Std/Data/Iterators/Consumers/Access.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ before emitting `n` values.
1515
1616
This function requires a `Productive` instance proving that the iterator will always emit a value
1717
after a finite number of skips. If the iterator is not productive or such an instance is not
18-
available, consider using `it.allowNontermination.toArray` instead of `it.toArray`. However, it is
18+
available, consider using `it.allowNontermination.seekIdx?` instead of `it.seekIdx?`. However, it is
1919
not possible to formally verify the behavior of the partial variant.
2020
-/
2121
@[specialize]

src/Std/Data/Iterators/Lemmas/Basic.lean

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,32 @@ iterator `it` to an element of `motive it` by defining `f it` in terms of the va
1414
the plausible successors of `it'.
1515
-/
1616
@[specialize]
17-
def Iter.induct {α β} [Iterator α Id β] [Finite α Id]
17+
def Iter.inductSteps {α β} [Iterator α Id β] [Finite α Id]
1818
(motive : Iter (α := α) β → Sort x)
1919
(step : (it : Iter (α := α) β) →
2020
(ih_yield : ∀ {it' : Iter (α := α) β} {out : β},
2121
it.IsPlausibleStep (.yield it' out) → motive it') →
22-
(ih_skip : ∀ {it' : Iter (α := α) β}, it.IsPlausibleStep (.skip it') → motive it' ) →
22+
(ih_skip : ∀ {it' : Iter (α := α) β}, it.IsPlausibleStep (.skip it') → motive it') →
2323
motive it)
2424
(it : Iter (α := α) β) : motive it :=
2525
step it
26-
(fun {it' _} _ => Iter.induct motive step it')
27-
(fun {it'} _ => Iter.induct motive step it')
26+
(fun {it' _} _ => inductSteps motive step it')
27+
(fun {it'} _ => inductSteps motive step it')
2828
termination_by it.finitelyManySteps
2929

30+
/--
31+
Induction principle for productive iterators: One can define a function `f` that maps every
32+
iterator `it` to an element of `motive it` by defining `f it` in terms of the values of `f` on
33+
the plausible skip successors of `it'.
34+
-/
35+
@[specialize]
36+
def Iter.inductSkips {α β} [Iterator α Id β] [Productive α Id]
37+
(motive : Iter (α := α) β → Sort x)
38+
(step : (it : Iter (α := α) β) →
39+
(ih_skip : ∀ {it' : Iter (α := α) β}, it.IsPlausibleStep (.skip it') → motive it') →
40+
motive it)
41+
(it : Iter (α := α) β) : motive it :=
42+
step it (fun {it'} _ => inductSkips motive step it')
43+
termination_by it.finitelyManySkips
44+
3045
end Std.Iterators

src/Std/Data/Iterators/Lemmas/Consumers/Collect.lean

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ theorem Iter.toListRev_eq_toListRev_toIterM {α β} [Iterator α Id β] [Finite
2727
rfl
2828

2929
@[simp]
30-
theorem IterM.toList_toPureIter {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
30+
theorem IterM.toList_toIter {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
3131
{it : IterM (α := α) Id β} :
32-
it.toPureIter.toList = it.toList :=
32+
it.toIter.toList = it.toList :=
3333
rfl
3434

3535
@[simp]
36-
theorem IterM.toListRev_toPureIter {α β} [Iterator α Id β] [Finite α Id]
36+
theorem IterM.toListRev_toIter {α β} [Iterator α Id β] [Finite α Id]
3737
{it : IterM (α := α) Id β} :
38-
it.toPureIter.toListRev = it.toListRev :=
38+
it.toIter.toListRev = it.toListRev :=
3939
rfl
4040

4141
theorem Iter.toList_toArray {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
@@ -55,45 +55,43 @@ theorem Iter.toListRev_eq {α β} [Iterator α Id β] [Finite α Id] [IteratorCo
5555
it.toListRev = it.toList.reverse := by
5656
simp [Iter.toListRev_eq_toListRev_toIterM, Iter.toList_eq_toList_toIterM, IterM.toListRev_eq]
5757

58-
theorem Iter.toArray_of_step {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
58+
theorem Iter.toArray_eq_match_step {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
5959
[LawfulIteratorCollect α Id] {it : Iter (α := α) β} :
6060
it.toArray = match it.step with
6161
| .yield it' out _ => #[out] ++ it'.toArray
6262
| .skip it' _ => it'.toArray
6363
| .done _ => #[] := by
6464
simp only [Iter.toArray_eq_toArray_toIterM, Iter.step]
65-
rw [IterM.toArray_of_step]
65+
rw [IterM.toArray_eq_match_step]
6666
simp only [Id.map_eq, Id.pure_eq, Id.bind_eq, Id.run]
6767
generalize it.toIterM.step = step
68-
cases step.casesHelper <;> simp
68+
cases step using PlausibleIterStep.casesOn <;> simp
6969

70-
theorem Iter.toList_of_step {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
70+
theorem Iter.toList_eq_match_step {α β} [Iterator α Id β] [Finite α Id] [IteratorCollect α Id]
7171
[LawfulIteratorCollect α Id] {it : Iter (α := α) β} :
7272
it.toList = match it.step with
7373
| .yield it' out _ => out :: it'.toList
7474
| .skip it' _ => it'.toList
7575
| .done _ => [] := by
76-
rw [← Iter.toList_toArray, Iter.toArray_of_step]
76+
rw [← Iter.toList_toArray, Iter.toArray_eq_match_step]
7777
split <;> simp [Iter.toList_toArray]
7878

79-
theorem Iter.toListRev_of_step {α β} [Iterator α Id β] [Finite α Id] {it : Iter (α := α) β} :
79+
theorem Iter.toListRev_eq_match_step {α β} [Iterator α Id β] [Finite α Id] {it : Iter (α := α) β} :
8080
it.toListRev = match it.step with
8181
| .yield it' out _ => it'.toListRev ++ [out]
8282
| .skip it' _ => it'.toListRev
8383
| .done _ => [] := by
84-
rw [Iter.toListRev_eq_toListRev_toIterM, IterM.toListRev_of_step, Iter.step]
84+
rw [Iter.toListRev_eq_toListRev_toIterM, IterM.toListRev_eq_match_step, Iter.step]
8585
simp only [Id.map_eq, Id.pure_eq, Id.bind_eq, Id.run]
8686
generalize it.toIterM.step = step
87-
cases step.run.casesHelper <;> simp
87+
cases step using PlausibleIterStep.casesOn <;> simp
8888

8989
theorem Iter.getElem?_toList_eq_seekIdx? {α β}
9090
[Iterator α Id β] [Finite α Id] [IteratorCollect α Id] [LawfulIteratorCollect α Id]
9191
{it : Iter (α := α) β} {k : Nat} :
9292
it.toList[k]? = it.seekIdx? k := by
93-
revert k
94-
induction it using Iter.induct with | step it ihy ihs =>
95-
intro k
96-
rw [toList_of_step, seekIdx?]
93+
induction it using Iter.inductSteps generalizing k with | step it ihy ihs =>
94+
rw [toList_eq_match_step, seekIdx?]
9795
obtain ⟨step, h⟩ := it.step
9896
cases step
9997
· cases k <;> simp [ihy h]

src/Std/Data/Iterators/Lemmas/Consumers/Monadic/Collect.lean

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ theorem IterM.DefaultConsumers.toArrayMapped.go.aux₂ [Monad m] [LawfulMonad m]
3838
rw [List.toArray_cons, IterM.DefaultConsumers.toArrayMapped.go.aux₁, ih]
3939
simp only [Functor.map_map, Array.append_assoc]
4040

41-
theorem IterM.DefaultConsumers.toArrayMapped_of_step [Monad m] [LawfulMonad m]
41+
theorem IterM.DefaultConsumers.toArrayMapped_eq_match_step [Monad m] [LawfulMonad m]
4242
[Iterator α m β] [Finite α m] {it : IterM (α := α) m β} {f : β → m γ} :
4343
IterM.DefaultConsumers.toArrayMapped f it = (do
4444
match ← it.step with
@@ -50,7 +50,7 @@ theorem IterM.DefaultConsumers.toArrayMapped_of_step [Monad m] [LawfulMonad m]
5050
intro step
5151
split <;> simp [IterM.DefaultConsumers.toArrayMapped.go.aux₂]
5252

53-
theorem IterM.toArray_of_step [Monad m] [LawfulMonad m]
53+
theorem IterM.toArray_eq_match_step [Monad m] [LawfulMonad m]
5454
[Iterator α m β] [Finite α m] [IteratorCollect α m] [LawfulIteratorCollect α m]
5555
{it : IterM (α := α) m β} :
5656
it.toArray = (do
@@ -59,7 +59,7 @@ theorem IterM.toArray_of_step [Monad m] [LawfulMonad m]
5959
| .skip it' _ => it'.toArray
6060
| .done _ => return #[]) := by
6161
simp only [IterM.toArray, LawfulIteratorCollect.toArrayMapped_eq]
62-
rw [IterM.DefaultConsumers.toArrayMapped_of_step]
62+
rw [IterM.DefaultConsumers.toArrayMapped_eq_match_step]
6363
simp [bind_pure_comp, pure_bind, toArray]
6464

6565
theorem IterM.toList_toArray [Monad m] [Iterator α m β] [Finite α m] [IteratorCollect α m]
@@ -72,15 +72,15 @@ theorem IterM.toArray_toList [Monad m] [LawfulMonad m] [Iterator α m β] [Finit
7272
List.toArray <$> it.toList = it.toArray := by
7373
simp [IterM.toList]
7474

75-
theorem IterM.toList_of_step [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
75+
theorem IterM.toList_eq_match_step [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
7676
[IteratorCollect α m] [LawfulIteratorCollect α m] {it : IterM (α := α) m β} :
7777
it.toList = (do
7878
match ← it.step with
7979
| .yield it' out _ => return out :: (← it'.toList)
8080
| .skip it' _ => it'.toList
8181
| .done _ => return []) := by
8282
simp [← IterM.toList_toArray]
83-
rw [IterM.toArray_of_step, map_eq_pure_bind, bind_assoc]
83+
rw [IterM.toArray_eq_match_step, map_eq_pure_bind, bind_assoc]
8484
apply bind_congr
8585
intro step
8686
split <;> simp
@@ -105,7 +105,7 @@ theorem IterM.toListRev.go.aux₂ [Monad m] [LawfulMonad m] [Iterator α m β] [
105105
| nil => simp [toListRev]
106106
| cons x xs ih => simp [IterM.toListRev.go.aux₁, ih]
107107

108-
theorem IterM.toListRev_of_step [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
108+
theorem IterM.toListRev_eq_match_step [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
109109
{it : IterM (α := α) m β} :
110110
it.toListRev = (do
111111
match ← it.step with
@@ -116,16 +116,16 @@ theorem IterM.toListRev_of_step [Monad m] [LawfulMonad m] [Iterator α m β] [Fi
116116
rw [toListRev.go]
117117
apply bind_congr
118118
intro step
119-
cases step.casesHelper <;> simp [IterM.toListRev.go.aux₂]
119+
cases step using PlausibleIterStep.casesOn <;> simp [IterM.toListRev.go.aux₂]
120120

121121
theorem IterM.reverse_toListRev [Monad m] [LawfulMonad m] [Iterator α m β] [Finite α m]
122122
[IteratorCollect α m] [LawfulIteratorCollect α m]
123123
{it : IterM (α := α) m β} :
124124
List.reverse <$> it.toListRev = it.toList := by
125125
apply Eq.symm
126-
induction it using IterM.induct
126+
induction it using IterM.inductSteps
127127
rename_i it ihy ihs
128-
rw [toListRev_of_step, toList_of_step, map_eq_pure_bind, bind_assoc]
128+
rw [toListRev_eq_match_step, toList_eq_match_step, map_eq_pure_bind, bind_assoc]
129129
apply bind_congr
130130
intro step
131131
split <;> simp (discharger := assumption) [ihy, ihs]

src/Std/Data/Iterators/Lemmas/Monadic/Basic.lean

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,32 @@ iterator `it` to an element of `motive it` by defining `f it` in terms of the va
1414
the plausible successors of `it'.
1515
-/
1616
@[specialize]
17-
def IterM.induct {α m β} [Iterator α m β] [Finite α m]
17+
def IterM.inductSteps {α m β} [Iterator α m β] [Finite α m]
1818
(motive : IterM (α := α) m β → Sort x)
1919
(step : (it : IterM (α := α) m β) →
2020
(ih_yield : ∀ {it' : IterM (α := α) m β} {out : β},
2121
it.IsPlausibleStep (.yield it' out) → motive it') →
22-
(ih_skip : ∀ {it' : IterM (α := α) m β}, it.IsPlausibleStep (.skip it') → motive it' ) →
22+
(ih_skip : ∀ {it' : IterM (α := α) m β}, it.IsPlausibleStep (.skip it') → motive it') →
2323
motive it)
2424
(it : IterM (α := α) m β) : motive it :=
2525
step it
26-
(fun {it' _} _ => IterM.induct motive step it')
27-
(fun {it'} _ => IterM.induct motive step it')
26+
(fun {it' _} _ => inductSteps motive step it')
27+
(fun {it'} _ => inductSteps motive step it')
2828
termination_by it.finitelyManySteps
2929

30+
/--
31+
Induction principle for productive monadic iterators: One can define a function `f` that maps every
32+
iterator `it` to an element of `motive it` by defining `f it` in terms of the values of `f` on
33+
the plausible skip successors of `it'.
34+
-/
35+
@[specialize]
36+
def IterM.inductSkips {α m β} [Iterator α m β] [Productive α m]
37+
(motive : IterM (α := α) m β → Sort x)
38+
(step : (it : IterM (α := α) m β) →
39+
(ih_skip : ∀ {it' : IterM (α := α) m β}, it.IsPlausibleStep (.skip it') → motive it') →
40+
motive it)
41+
(it : IterM (α := α) m β) : motive it :=
42+
step it (fun {it'} _ => inductSkips motive step it')
43+
termination_by it.finitelyManySkips
44+
3045
end Std.Iterators

src/Std/Data/Iterators/Producers/List.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ namespace Std.Iterators
1717
@[always_inline, inline]
1818
def _root_.List.iter {α : Type w} (l : List α) :
1919
Iter (α := ListIterator α) α :=
20-
((l.iterM Id).toPureIter : Iter α)
20+
((l.iterM Id).toIter : Iter α)
2121

2222
end Std.Iterators

0 commit comments

Comments
 (0)