Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/Init/Data/Iterators/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,16 @@ def IterStep.successor : IterStep α β → Option α
| .skip it => some it
| .done => none

@[simp]
theorem IterStep.successor_yield {it : α} {out : β} :
(IterStep.yield it out).successor = some it := rfl

@[simp]
theorem IterStep.successor_skip {it : α} : (IterStep.skip (β := β) it).successor = some it := rfl

@[simp]
theorem IterStep.successor_done : (IterStep.done (α := α) (β := β)).successor = none := rfl

/--
If present, applies `f` to the iterator of an `IterStep` and replaces the iterator
with the result of the application of `f`.
Expand Down Expand Up @@ -543,6 +553,10 @@ def Iter.IsPlausibleSuccessorOf {α : Type w} {β : Type w} [Iterator α Id β]
(it' it : Iter (α := α) β) : Prop :=
it'.toIterM.IsPlausibleSuccessorOf it.toIterM

theorem Iter.isPlausibleSuccessorOf_eq_invImage {α : Type w} {β : Type w} [Iterator α Id β] :
IsPlausibleSuccessorOf (α := α) (β := β) =
InvImage (IterM.IsPlausibleSuccessorOf (α := α) (β := β) (m := Id)) Iter.toIterM := rfl

theorem Iter.isPlausibleSuccessorOf_iff_exists {α : Type w} {β : Type w} [Iterator α Id β]
{it' it : Iter (α := α) β} :
it'.IsPlausibleSuccessorOf it ↔ ∃ step, step.successor = some it' ∧ it.IsPlausibleStep step := by
Expand All @@ -555,6 +569,16 @@ theorem Iter.isPlausibleSuccessorOf_iff_exists {α : Type w} {β : Type w} [Iter
exact ⟨step.mapIterator Iter.toIterM,
by cases step <;> simp_all [IterStep.successor, Iter.IsPlausibleStep]⟩

theorem Iter.IsPlausibleStep.isPlausibleSuccessor_of_yield {α : Type w} {β : Type w}
[Iterator α Id β] {it' it : Iter (α := α) β} {out : β}
(h : it.IsPlausibleStep (.yield it' out)) : it'.IsPlausibleSuccessorOf it := by
simpa [isPlausibleSuccessorOf_iff_exists] using ⟨.yield it' out, by simp [h]⟩

theorem Iter.IsPlausibleStep.isPlausibleSuccessor_of_skip {α : Type w} {β : Type w}
[Iterator α Id β] {it' it : Iter (α := α) β} (h : it.IsPlausibleStep (.skip it')) :
it'.IsPlausibleSuccessorOf it := by
simpa [isPlausibleSuccessorOf_iff_exists] using ⟨.skip it', by simp [h]⟩

/--
Asserts that a certain iterator `it` could plausibly yield the value `out` after an arbitrary
number of steps.
Expand Down Expand Up @@ -656,6 +680,10 @@ Given this typeclass, termination proofs for well-founded recursion over an iter
class Finite (α : Type w) (m : Type w → Type w') {β : Type w} [Iterator α m β] : Prop where
wf : WellFounded (IterM.IsPlausibleSuccessorOf (α := α) (m := m))

theorem Finite.wf_of_id {α : Type w} {β : Type w} [Iterator α Id β] [Finite α Id] :
WellFounded (Iter.IsPlausibleSuccessorOf (α := α)) := by
simpa [Iter.isPlausibleSuccessorOf_eq_invImage] using InvImage.wf _ Finite.wf

/--
This type is a wrapper around `IterM` so that it becomes a useful termination measure for
recursion over finite iterators. See also `IterM.finitelyManySteps` and `Iter.finitelyManySteps`.
Expand Down Expand Up @@ -705,6 +733,12 @@ theorem IterM.TerminationMeasures.Finite.rel_of_skip
Rel ⟨it'⟩ ⟨it⟩ := by
exact .single ⟨_, rfl, h⟩

theorem IterM.TerminationMeasures.Finite.rel_trans
{α : Type w} {m : Type w → Type w'} {β : Type w} [Iterator α m β]
{it it' it'' : TerminationMeasures.Finite α m} :
it.Rel it' → it'.Rel it'' → it.Rel it'' :=
.trans

macro_rules | `(tactic| decreasing_trivial) => `(tactic|
first
| exact IterM.TerminationMeasures.Finite.rel_of_yield ‹_›
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ it.filterMapWithPostcondition ---a'-----c'-------⊥
**Termination properties:**

* `Finite` instance: only if `it` is finite
* `Productive` instance: only if `it` is finite`
* `Productive` instance: only if `it` is finite

For certain mapping functions `f`, the resulting iterator will be finite (or productive) even though
no `Finite` (or `Productive`) instance is provided. For example, if `f` never returns `none`, then
Expand Down
40 changes: 1 addition & 39 deletions src/Init/Data/String/Pattern/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ inductive SearchStep (s : Slice) where
-/
| rejected (startPos endPos : s.Pos)
/--
The subslice starting at {name}`startPos` and ending at {name}`endPos` did not match the pattern.
The subslice starting at {name}`startPos` and ending at {name}`endPos` matches the pattern.
-/
| matched (startPos endPos : s.Pos)
deriving Inhabited
Expand Down Expand Up @@ -99,44 +99,6 @@ where
simp [Pos.Raw.lt_iff] at h ⊢
omega

variable {ρ : Type} {σ : Slice → Type}
variable [∀ s, Std.Iterators.Iterator (σ s) Id (SearchStep s)]
variable [∀ s, Std.Iterators.Finite (σ s) Id]

/--
Tries to skip the {name}`searcher` until the next {name}`SearchStep.matched` and return it. If no
match is found until the end returns {name}`none`.
-/
@[inline]
def nextMatch (searcher : Std.Iter (α := σ s) (SearchStep s)) :
Option (Std.Iter (α := σ s) (SearchStep s) × s.Pos × s.Pos) :=
go searcher
where
go [∀ s, Std.Iterators.Finite (σ s) Id] (searcher : Std.Iter (α := σ s) (SearchStep s)) :
Option (Std.Iter (α := σ s) (SearchStep s) × s.Pos × s.Pos) :=
match searcher.step with
| .yield it (.matched startPos endPos) _ => some (it, startPos, endPos)
| .yield it (.rejected ..) _ | .skip it .. => go it
| .done .. => none
termination_by Std.Iterators.Iter.finitelyManySteps searcher

/--
Tries to skip the {name}`searcher` until the next {name}`SearchStep.rejected` and return it. If no
reject is found until the end returns {name}`none`.
-/
@[inline]
def nextReject (searcher : Std.Iter (α := σ s) (SearchStep s)) :
Option (Std.Iter (α := σ s) (SearchStep s) × s.Pos × s.Pos) :=
go searcher
where
go [∀ s, Std.Iterators.Finite (σ s) Id] (searcher : Std.Iter (α := σ s) (SearchStep s)) :
Option (Std.Iter (α := σ s) (SearchStep s) × s.Pos × s.Pos) :=
match searcher.step with
| .yield it (.rejected startPos endPos) _ => some (it, startPos, endPos)
| .yield it (.matched ..) _ | .skip it .. => go it
| .done .. => none
termination_by Std.Iterators.Iter.finitelyManySteps searcher

end Internal

namespace ForwardPattern
Expand Down
Loading
Loading