Skip to content

Commit 98a24eb

Browse files
committed
make it compile
1 parent ebeb3d0 commit 98a24eb

File tree

13 files changed

+627
-447
lines changed

13 files changed

+627
-447
lines changed

src/Init/Data/Iterators/Basic.lean

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module
88
prelude
99
public import Init.Classical
1010
public import Init.Ext
11+
public import Init.Internal.MonadAttach
1112

1213
set_option doc.verso true
1314

@@ -393,6 +394,31 @@ abbrev IterM.Step {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator
393394
(it : IterM (α := α) m β) :=
394395
PlausibleIterStep it.IsPlausibleStep
395396

397+
/--
398+
Makes a single step with the given iterator `it`, potentially emitting a value and providing a
399+
succeeding iterator. If this function is used recursively, termination can sometimes be proved with
400+
the termination measures `it.finitelyManySteps` and `it.finitelyManySkips`.
401+
-/
402+
@[always_inline, inline, expose]
403+
def IterM.step {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
404+
(it : IterM (α := α) m β) : m (Shrink it.Step) :=
405+
Iterator.step it
406+
407+
/--
408+
Asserts that certain step is plausibly the successor of a given iterator. What "plausible" means
409+
is up to the `Iterator` instance but it should be strong enough to allow termination proofs.
410+
-/
411+
@[expose]
412+
abbrev IterM.IsPlausibleStepE {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
413+
[MonadAttach m] (it : IterM (α := α) m β) (step : IterStep (IterM (α := α) m β) β) : Prop :=
414+
∃ h, MonadAttach.CanReturn it.step (.deflate ⟨step, h⟩)
415+
416+
theorem IterM.isPlausibleStep_of_isPlausibleStepE {α : Type w} {m : Type w → Type w'} {β : Type w}
417+
[Iterator α m β] [MonadAttach m]
418+
{it : IterM (α := α) m β} {step : IterStep (IterM (α := α) m β) β}
419+
(h : it.IsPlausibleStepE step) : it.IsPlausibleStep step :=
420+
h.choose
421+
396422
/--
397423
Asserts that a certain output value could plausibly be emitted by the given iterator in its next
398424
step.
@@ -411,6 +437,21 @@ def IterM.IsPlausibleSuccessorOf {α : Type w} {m : Type w → Type w'} {β : Ty
411437
(it' it : IterM (α := α) m β) : Prop :=
412438
∃ step, step.successor = some it' ∧ it.IsPlausibleStep step
413439

440+
/--
441+
Asserts that a certain iterator `it'` could plausibly be the directly succeeding iterator of another
442+
given iterator `it`.
443+
-/
444+
@[expose]
445+
def IterM.IsPlausibleSuccessorOfE {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
446+
[MonadAttach m] (it' it : IterM (α := α) m β) : Prop :=
447+
∃ step, step.successor = some it' ∧ it.IsPlausibleStepE step
448+
449+
theorem IterM.isPlausibleSuccessorOf_of_isPlausibleSuccessorOfE {α : Type w} {m : Type w → Type w'}
450+
{β : Type w} [Iterator α m β] [MonadAttach m] {it' it : IterM (α := α) m β}
451+
(h : it'.IsPlausibleSuccessorOfE it) : it'.IsPlausibleSuccessorOf it :=
452+
let ⟨step, hs, hp⟩ := h
453+
⟨step, hs, isPlausibleStep_of_isPlausibleStepE hp⟩
454+
414455
/--
415456
Asserts that a certain iterator `it'` could plausibly be the directly succeeding iterator of another
416457
given iterator `it` while no value is emitted (see `IterStep.skip`).
@@ -420,16 +461,6 @@ def IterM.IsPlausibleSkipSuccessorOf {α : Type w} {m : Type w → Type w'} {β
420461
[Iterator α m β] (it' it : IterM (α := α) m β) : Prop :=
421462
it.IsPlausibleStep (.skip it')
422463

423-
/--
424-
Makes a single step with the given iterator `it`, potentially emitting a value and providing a
425-
succeeding iterator. If this function is used recursively, termination can sometimes be proved with
426-
the termination measures `it.finitelyManySteps` and `it.finitelyManySkips`.
427-
-/
428-
@[always_inline, inline, expose]
429-
def IterM.step {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
430-
(it : IterM (α := α) m β) : m (Shrink it.Step) :=
431-
Iterator.step it
432-
433464
end Monadic
434465

435466
section Pure
@@ -734,7 +765,7 @@ Termination measure to be used in well-founded recursive functions recursing ove
734765
(see also `Finite`).
735766
-/
736767
@[expose]
737-
def IterM.finitelyManyStepsExtrinsic {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
768+
def IterM.finitelyManySteps! {α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
738769
(it : IterM (α := α) m β) : IterM.TerminationMeasures.Finite α m :=
739770
⟨it⟩
740771

src/Init/Data/Iterators/Consumers/Loop.lean

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,8 @@ def Iter.Partial.instForIn' {α : Type w} {β : Type w} {n : Type x → Type x'}
5656
[Iterator α Id β] [IteratorLoop α Id n] :
5757
ForIn' n (Iter.Partial (α := α) β) β ⟨fun it out => it.it.IsPlausibleIndirectOutput out⟩ where
5858
forIn' it init f :=
59-
IteratorLoop.forIn (α := α) (m := Id) (n := n) (fun _ _ f c => f c.run) _
60-
it.it.toIterM init
61-
fun out h acc =>
62-
f out (Iter.isPlausibleIndirectOutput_iff_isPlausibleIndirectOutput_toIterM.mpr h) acc
59+
haveI := @Iter.instForIn'
60+
forIn' it.it init f
6361

6462
instance (α : Type w) (β : Type w) (n : Type x → Type x') [Monad n]
6563
[Iterator α Id β] [IteratorLoop α Id n] :

src/Init/Data/Iterators/Consumers/Monadic/Collect.lean

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ public import Init.Data.Iterators.Consumers.Monadic.Partial
1010
public import Init.Data.Iterators.Consumers.Monadic.Total
1111
public import Init.Data.Iterators.Internal.LawfulMonadLiftFunction
1212
public import Init.Internal.ExtrinsicTermination
13-
public import Init.Internal.MonadAttach
1413

1514
@[expose] public section
1615

@@ -61,6 +60,11 @@ end Typeclasses
6160

6261
section ToArray
6362

63+
def IterM.DefaultConsumers.toArrayMapped.RecursionRel {α β : Type w} {m : Type w → Type w'}
64+
[Iterator α m β] {γ : Type w} (x' x : (_ : IterM (α := α) m β) ×' Array γ) : Prop :=
65+
(∃ out, x.1.IsPlausibleStep (.yield x'.1 out) ∧ ∃ fx, x'.2 = x.2.push fx) ∨
66+
(x.1.IsPlausibleStep (.skip x'.1) ∧ x'.2 = x.2)
67+
6468
/--
6569
This is an internal function used in `IteratorCollect.defaultImplementation`.
6670
@@ -69,7 +73,7 @@ of `f` into an array.
6973
-/
7074
@[always_inline, no_expose]
7175
def IterM.DefaultConsumers.toArrayMapped {α β : Type w} {m : Type w → Type w'}
72-
{n : Type w → Type w''} [Monad n] [MonadAttach n] [Iterator α m β]
76+
{n : Type w → Type w''} [Monad n] [Iterator α m β]
7377
(lift : ⦃α : Type w⦄ → m α → n α) {γ : Type w} (f : β → n γ)
7478
(it : IterM (α := α) m β) : n (Array γ) :=
7579
letI : MonadLift m n := ⟨lift (α := _)⟩
@@ -78,24 +82,43 @@ where
7882
@[always_inline]
7983
go it (acc : Array γ) : n (Array γ) :=
8084
letI : MonadLift m n := ⟨lift (α := _)⟩
81-
extrinsicFix₂ (C₂ := fun _ _ => n (Array γ))
82-
(fun x' x => (∃ out h, MonadAttach.CanReturn (m := n) x.1.step (.deflate <| .yield x'.1 out h) ∧ ∃ fx, MonadAttach.CanReturn (f out) fx ∧ x'.2 = x.2.push fx) ∨ (∃ h, MonadAttach.CanReturn (m := n) x.1.step (.deflate <| .skip x'.1 h) ∧ x'.2 = x.2))
85+
extrinsicFixE₂ (C₂ := fun _ _ => n (Array γ)) (InvImage TerminationMeasures.Finite.Rel (·.1.finitelyManySteps!))
8386
(fun (it : IterM (α := α) m β) acc recur => do
84-
let ⟨step, hs⟩ ← MonadAttach.attach (m := n) it.step
85-
match hs' : step.inflate with
87+
match (← it.step).inflate with
8688
| .yield it' out h =>
87-
let fx ← MonadAttach.attach (f out)
88-
recur it' (acc.push fx.val) (by
89-
apply Or.inl
90-
have : step = .deflate (.yield it' out h) := by simp [← hs']
91-
rw [this] at hs
92-
exact ⟨out, h, hs, fx.val, fx.property, rfl⟩)
93-
| .skip it' h => recur it' acc (by
94-
apply Or.inr
95-
have : step = .deflate (.skip it' h) := by simp [← hs']
96-
rw [this] at hs
97-
exact ⟨h, hs, rfl⟩)
98-
| .done h => return acc) it acc
89+
recur it' (acc.push (← f out)) (by exact TerminationMeasures.Finite.rel_of_yield ‹_›)
90+
| .skip it' h => recur it' acc (by exact TerminationMeasures.Finite.rel_of_skip ‹_›)
91+
| .done _ => return acc) it acc
92+
93+
-- @[always_inline, no_expose]
94+
-- def IterM.DefaultConsumers.toArrayMapped {α β : Type w} {m : Type w → Type w'}
95+
-- {n : Type w → Type w''} [Monad n] [MonadAttach n] [Iterator α m β]
96+
-- (lift : ⦃α : Type w⦄ → m α → n α) {γ : Type w} (f : β → n γ)
97+
-- (it : IterM (α := α) m β) : n (Array γ) :=
98+
-- letI : MonadLift m n := ⟨lift (α := _)⟩
99+
-- go it #[]
100+
-- where
101+
-- @[always_inline]
102+
-- go it (acc : Array γ) : n (Array γ) :=
103+
-- letI : MonadLift m n := ⟨lift (α := _)⟩
104+
-- extrinsicFixE₂ (C₂ := fun _ _ => n (Array γ))
105+
-- (fun x' x => (∃ out, x.1.IsPlausibleStepE (.yield x'.1 out) ∧ ∃ fx, MonadAttach.CanReturn (f out) fx ∧ x'.2 = x.2.push fx) ∨ (∃ h, MonadAttach.CanReturn (m := n) x.1.step (.deflate <| .skip x'.1 h) ∧ x'.2 = x.2))
106+
-- (fun (it : IterM (α := α) m β) acc recur => do
107+
-- let ⟨step, hs⟩ ← MonadAttach.attach (m := n) it.step
108+
-- match hs' : step.inflate with
109+
-- | .yield it' out h =>
110+
-- let fx ← MonadAttach.attach (f out)
111+
-- recur it' (acc.push fx.val) (by
112+
-- apply Or.inl
113+
-- have : step = .deflate (.yield it' out h) := by simp [← hs']
114+
-- rw [this] at hs
115+
-- exact ⟨out, h, hs, fx.val, fx.property, rfl⟩)
116+
-- | .skip it' h => recur it' acc (by
117+
-- apply Or.inr
118+
-- have : step = .deflate (.skip it' h) := by simp [← hs']
119+
-- rw [this] at hs
120+
-- exact ⟨h, hs, rfl⟩)
121+
-- | .done h => return acc) it acc
99122

100123
/--
101124
This is the default implementation of the `IteratorCollect` class.
@@ -105,7 +128,7 @@ used instead.
105128
-/
106129
@[always_inline]
107130
def IteratorCollect.defaultImplementation {α β : Type w} {m : Type w → Type w'}
108-
{n : Type w → Type w''} [Monad n] [MonadAttach n] [Iterator α m β] :
131+
{n : Type w → Type w''} [Monad n] [Iterator α m β] :
109132
IteratorCollect α m n where
110133
toArrayMapped := IterM.DefaultConsumers.toArrayMapped
111134

@@ -115,21 +138,21 @@ Asserts that a given `IteratorCollect` instance is equal to `IteratorCollect.def
115138
(Even though equal, the given instance might be vastly more efficient.)
116139
-/
117140
class LawfulIteratorCollect (α : Type w) (m : Type w → Type w') (n : Type w → Type w'')
118-
{β : Type w} [Monad m] [Monad n] [MonadAttach n] [Iterator α m β] [i : IteratorCollect α m n] where
141+
{β : Type w} [Monad m] [Monad n] [Iterator α m β] [i : IteratorCollect α m n] where
119142
lawful_toArrayMapped : ∀ lift [LawfulMonadLiftFunction lift] [Finite α m],
120143
i.toArrayMapped lift (α := α) (γ := γ)
121144
= IteratorCollect.defaultImplementation.toArrayMapped lift
122145

123146
theorem LawfulIteratorCollect.toArrayMapped_eq {α β γ : Type w} {m : Type w → Type w'}
124-
{n : Type w → Type w''} [Monad m] [Monad n] [MonadAttach n] [Iterator α m β] [Finite α m] [IteratorCollect α m n]
147+
{n : Type w → Type w''} [Monad m] [Monad n] [Iterator α m β] [Finite α m] [IteratorCollect α m n]
125148
[hl : LawfulIteratorCollect α m n] {lift : ⦃δ : Type w⦄ → m δ → n δ}
126149
[LawfulMonadLiftFunction lift]
127150
{f : β → n γ} {it : IterM (α := α) m β} :
128151
IteratorCollect.toArrayMapped lift f it (m := m) =
129152
IterM.DefaultConsumers.toArrayMapped lift f it (m := m) := by
130153
rw [lawful_toArrayMapped]; rfl
131154

132-
instance (α β : Type w) (m : Type w → Type w') (n : Type w → Type w'') [Monad n] [MonadAttach n]
155+
instance (α β : Type w) (m : Type w → Type w') (n : Type w → Type w'') [Monad n]
133156
[Iterator α m β] [Monad m] [Iterator α m β] [Finite α m] :
134157
haveI : IteratorCollect α m n := .defaultImplementation
135158
LawfulIteratorCollect α m n :=
@@ -185,11 +208,12 @@ def IterM.toListRev {α : Type w} {m : Type w → Type w'} [Monad m] {β : Type
185208
where
186209
@[always_inline, inline]
187210
go (it : IterM m β) acc :=
188-
extrinsicFix₂ (fun it acc recur => do
189-
match (← it.step).inflate with
190-
| .yield it' out _ => recur it' (out :: acc)
191-
| .skip it' _ => recur it' acc
192-
| .done _ => return acc) it acc
211+
extrinsicFixE₂ (InvImage TerminationMeasures.Finite.Rel (·.1.finitelyManySteps!))
212+
(fun it acc recur => do
213+
match (← it.step).inflate with
214+
| .yield it' out h => recur it' (out :: acc) (TerminationMeasures.Finite.rel_of_yield h)
215+
| .skip it' h => recur it' acc (TerminationMeasures.Finite.rel_of_skip h)
216+
| .done _ => return acc) it acc
193217

194218
/--
195219
Traverses the given iterator and stores the emitted values in reverse order in a list. Because

src/Init/Data/Iterators/Consumers/Monadic/Loop.lean

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ provided by the standard library.
7171
class IteratorLoop (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β]
7272
(n : Type x → Type x') where
7373
forIn : ∀ (_liftBind : (γ : Type w) → (δ : Type x) → (γ → n δ) → m γ → n δ) (γ : Type x),
74+
(plausible_forInStep : β → γ → ForInStep γ → Prop) →
7475
(it : IterM (α := α) m β) → γ →
75-
((b : β) → it.IsPlausibleIndirectOutput b → (c : γ) → n (ForInStep γ)) → n γ
76+
((b : β) → it.IsPlausibleIndirectOutput b → (c : γ) → n (Subtype (plausible_forInStep b c))) →
77+
n γ
7678

7779
end Typeclasses
7880

@@ -99,18 +101,19 @@ def IterM.DefaultConsumers.forIn' {m : Type w → Type w'} {α : Type w} {β : T
99101
[Iterator α m β]
100102
{n : Type x → Type x'} [Monad n]
101103
(lift : ∀ γ δ, (γ → n δ) → m γ → n δ) (γ : Type x)
104+
(plausible_forInStep : β → γ → ForInStep γ → Prop)
102105
(it : IterM (α := α) m β) (init : γ)
103106
(P : β → Prop) (hP : ∀ b, it.IsPlausibleIndirectOutput b → P b)
104-
(f : (b : β) → P b → (c : γ) → n (ForInStep γ)) : n γ :=
107+
(f : (b : β) → P b → (c : γ) → n (Subtype (plausible_forInStep b c))) : n γ :=
105108
haveI : Nonempty γ := ⟨init⟩
106-
extrinsicFix₃ (C₃ := fun _ _ _ => n γ)
109+
extrinsicFixE₃ (C₃ := fun _ _ _ => n γ) (InvImage (IteratorLoop.rel α m plausible_forInStep) (fun x => (x.1, x.2.1)))
107110
(fun it acc (hP : ∀ b, it.IsPlausibleIndirectOutput b → P b) recur => (lift _ _ · it.step) fun s => do
108111
match s.inflate with
109112
| .yield it' out h =>
110113
match ← f out (hP out <| .direct ⟨_, h⟩) acc with
111-
| .yield c => recur it' c (fun _ h' => hP _ <| .indirect ⟨_, rfl, h⟩ h')
112-
| .done c => return c
113-
| .skip it' h => recur it' acc (fun _ h' => hP _ <| .indirect ⟨_, rfl, h⟩ h')
114+
| .yield c, h'⟩ => recur it' c (fun _ h' => hP _ <| .indirect ⟨_, rfl, h⟩ h') (Or.inl ⟨out, ‹_›, ‹_›⟩)
115+
| .done c, h⟩ => return c
116+
| .skip it' h => recur it' acc (fun _ h' => hP _ <| .indirect ⟨_, rfl, h⟩ h') (Or.inr ⟨‹_›, rfl⟩)
114117
| .done _ => return acc) it init hP
115118

116119
/--
@@ -153,7 +156,7 @@ implementations are possible and should be used instead.
153156
def IteratorLoop.defaultImplementation {α : Type w} {m : Type w → Type w'} {n : Type x → Type x'}
154157
[Monad n] [Iterator α m β] :
155158
IteratorLoop α m n where
156-
forIn lift γ it init := IterM.DefaultConsumers.forIn' lift γ it init _ (fun _ => id)
159+
forIn lift γ Pl it init := IterM.DefaultConsumers.forIn' lift γ Pl it init _ (fun _ => id)
157160

158161
/--
159162
Asserts that a given `IteratorLoop` instance is equal to `IteratorLoop.defaultImplementation`.
@@ -164,8 +167,8 @@ class LawfulIteratorLoop (α : Type w) (m : Type w → Type w') (n : Type x →
164167
lawful lift [LawfulMonadLiftBindFunction lift] γ it init
165168
(Pl : β → γ → ForInStep γ → Prop) (wf : IteratorLoop.WellFounded α m Pl)
166169
(f : (b : β) → it.IsPlausibleIndirectOutput b → (c : γ) → n (Subtype (Pl b c))) :
167-
i.forIn lift γ it init (Subtype.val <$> f · · ·) =
168-
IteratorLoop.defaultImplementation.forIn lift γ it init (Subtype.val <$> f · · ·)
170+
i.forIn lift γ Pl it init f =
171+
IteratorLoop.defaultImplementation.forIn lift γ Pl it init f
169172

170173
instance (α : Type w) (m : Type w → Type w') (n : Type x → Type x')
171174
[Monad m] [Monad n] [Iterator α m β] [Finite α m] :
@@ -196,7 +199,7 @@ def IteratorLoop.finiteForIn' {m : Type w → Type w'} {n : Type x → Type x'}
196199
(lift : ∀ γ δ, (γ → n δ) → m γ → n δ) :
197200
ForIn' n (IterM (α := α) m β) β ⟨fun it out => it.IsPlausibleIndirectOutput out⟩ where
198201
forIn' {γ} it init f :=
199-
IteratorLoop.forIn (α := α) (m := m) lift γ it init (fun out h acc => (f out h acc))
202+
IteratorLoop.forIn (α := α) (m := m) lift γ (fun _ _ _ => True) it init (return ⟨← f · · ·, trivial⟩)
200203

201204
/--
202205
A `ForIn'` instance for iterators. Its generic membership relation is not easy to use,
@@ -221,8 +224,8 @@ instance {m : Type w → Type w'} {n : Type w → Type w''}
221224
def IterM.Partial.instForIn' {m : Type w → Type w'} {n : Type w → Type w''}
222225
{α : Type w} {β : Type w} [Iterator α m β] [IteratorLoop α m n] [MonadLiftT m n] [Monad n] :
223226
ForIn' n (IterM.Partial (α := α) m β) β ⟨fun it out => it.it.IsPlausibleIndirectOutput out⟩ where
224-
forIn' it init f := IteratorLoop.forIn (α := α) (m := m) (n := n)
225-
(fun _ _ f x => monadLift x >>= f) _ it.it init f
227+
forIn' it init f :=
228+
haveI := @IterM.instForIn'; forIn' it.it init f
226229

227230
@[always_inline, inline]
228231
def IterM.Total.instForIn' {m : Type w → Type w'} {n : Type w → Type w''}

src/Init/Data/Iterators/Lemmas/Combinators/Monadic/FilterMap.lean

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,8 @@ instance {α β γ : Type w} {m : Type w → Type w'} {n : Type w → Type w''}
247247
have : it = IterM.mapWithPostcondition _ it.internalState.inner := by rfl
248248
generalize it.internalState.inner = it at *
249249
cases this
250-
simp only [LawfulIteratorCollect.toArrayMapped_eq]
251250
simp only [IteratorCollect.toArrayMapped]
252-
rw [LawfulIteratorCollect.toArrayMapped_eq]
251+
simp only [LawfulIteratorCollect.toArrayMapped_eq]
253252
induction it using IterM.inductSteps with | step it ih_yield ih_skip
254253
rw [IterM.DefaultConsumers.toArrayMapped_eq_match_step]
255254
rw [IterM.DefaultConsumers.toArrayMapped_eq_match_step]

0 commit comments

Comments
 (0)