This PR moves many constants of the iterator API from `Std.Iterators` to the `Std` namespace in order to make them more convenient to use. These constants include, but are not limited to, `Iter`, `IterM` and `IteratorLoop`. This is a breaking change. If something breaks, try adding `open Std` in order to make these constants available again. If some constants in the `Std.Iterators` namespace cannot be found, they can be found directly in `Std` now.
173 lines
6.1 KiB
Text
173 lines
6.1 KiB
Text
/-
|
||
Copyright (c) 2025 Lean FRO, LLC. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Henrik Böving
|
||
-/
|
||
module
|
||
|
||
prelude
|
||
public import Init.Data.String.Pattern.Basic
|
||
public import Init.Data.Iterators.Internal.Termination
|
||
public import Init.Data.Iterators.Consumers.Monadic.Loop
|
||
import Init.Data.String.Termination
|
||
|
||
set_option doc.verso true
|
||
|
||
/-!
|
||
This module defines the necessary instances to register {lean}`Char → Bool` with the pattern
|
||
framework.
|
||
-/
|
||
|
||
public section
|
||
|
||
namespace String.Slice.Pattern
|
||
|
||
structure ForwardCharPredSearcher (p : Char → Bool) (s : Slice) where
|
||
currPos : s.Pos
|
||
deriving Inhabited
|
||
|
||
namespace ForwardCharPredSearcher
|
||
|
||
@[inline]
|
||
def iter (p : Char → Bool) (s : Slice) : Std.Iter (α := ForwardCharPredSearcher p s) (SearchStep s) :=
|
||
{ internalState := { currPos := s.startPos }}
|
||
|
||
instance (s : Slice) : Std.Iterator (ForwardCharPredSearcher p s) Id (SearchStep s) where
|
||
IsPlausibleStep it
|
||
| .yield it' out =>
|
||
∃ h1 : it.internalState.currPos ≠ s.endPos,
|
||
it'.internalState.currPos = it.internalState.currPos.next h1 ∧
|
||
match out with
|
||
| .matched startPos endPos =>
|
||
it.internalState.currPos = startPos ∧
|
||
it'.internalState.currPos = endPos ∧
|
||
p (it.internalState.currPos.get h1)
|
||
| .rejected startPos endPos =>
|
||
it.internalState.currPos = startPos ∧
|
||
it'.internalState.currPos = endPos ∧
|
||
¬ p (it.internalState.currPos.get h1)
|
||
| .skip _ => False
|
||
| .done => it.internalState.currPos = s.endPos
|
||
step := fun ⟨⟨currPos⟩⟩ =>
|
||
if h1 : currPos = s.endPos then
|
||
pure (.deflate ⟨.done, by simp [h1]⟩)
|
||
else
|
||
let nextPos := currPos.next h1
|
||
let nextIt := ⟨⟨nextPos⟩⟩
|
||
if h2 : p <| currPos.get h1 then
|
||
pure (.deflate ⟨.yield nextIt (.matched currPos nextPos), by simp [h1, h2, nextPos, nextIt]⟩)
|
||
else
|
||
pure (.deflate ⟨.yield nextIt (.rejected currPos nextPos), by simp [h1, h2, nextPos, nextIt]⟩)
|
||
|
||
|
||
def finitenessRelation : Std.Iterators.FinitenessRelation (ForwardCharPredSearcher p s) Id where
|
||
rel := InvImage WellFoundedRelation.rel (fun it => it.internalState.currPos)
|
||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||
subrelation {it it'} h := by
|
||
simp_wf
|
||
obtain ⟨step, h, h'⟩ := h
|
||
cases step
|
||
· cases h
|
||
obtain ⟨_, h2, _⟩ := h'
|
||
simp [h2]
|
||
· cases h'
|
||
· cases h
|
||
|
||
instance : Std.Iterators.Finite (ForwardCharPredSearcher p s) Id :=
|
||
.of_finitenessRelation finitenessRelation
|
||
|
||
instance : Std.IteratorLoop (ForwardCharPredSearcher p s) Id Id :=
|
||
.defaultImplementation
|
||
|
||
@[default_instance]
|
||
instance {p : Char → Bool} : ToForwardSearcher p (ForwardCharPredSearcher p) where
|
||
toSearcher := iter p
|
||
|
||
@[default_instance]
|
||
instance {p : Char → Bool} : ForwardPattern p := .defaultImplementation
|
||
|
||
instance {p : Char → Prop} [DecidablePred p] : ToForwardSearcher p (ForwardCharPredSearcher p) where
|
||
toSearcher := iter (decide <| p ·)
|
||
|
||
instance {p : Char → Prop} [DecidablePred p] : ForwardPattern p :=
|
||
.defaultImplementation
|
||
|
||
end ForwardCharPredSearcher
|
||
|
||
structure BackwardCharPredSearcher (s : Slice) where
|
||
currPos : s.Pos
|
||
needle : Char → Bool
|
||
deriving Inhabited
|
||
|
||
namespace BackwardCharPredSearcher
|
||
|
||
@[inline]
|
||
def iter (c : Char → Bool) (s : Slice) : Std.Iter (α := BackwardCharPredSearcher s) (SearchStep s) :=
|
||
{ internalState := { currPos := s.endPos, needle := c }}
|
||
|
||
instance (s : Slice) : Std.Iterator (BackwardCharPredSearcher s) Id (SearchStep s) where
|
||
IsPlausibleStep it
|
||
| .yield it' out =>
|
||
it.internalState.needle = it'.internalState.needle ∧
|
||
∃ h1 : it.internalState.currPos ≠ s.startPos,
|
||
it'.internalState.currPos = it.internalState.currPos.prev h1 ∧
|
||
match out with
|
||
| .matched startPos endPos =>
|
||
it.internalState.currPos = endPos ∧
|
||
it'.internalState.currPos = startPos ∧
|
||
it.internalState.needle ((it.internalState.currPos.prev h1).get Pos.prev_ne_endPos)
|
||
| .rejected startPos endPos =>
|
||
it.internalState.currPos = endPos ∧
|
||
it'.internalState.currPos = startPos ∧
|
||
¬ it.internalState.needle ((it.internalState.currPos.prev h1).get Pos.prev_ne_endPos)
|
||
| .skip _ => False
|
||
| .done => it.internalState.currPos = s.startPos
|
||
step := fun ⟨currPos, needle⟩ =>
|
||
if h1 : currPos = s.startPos then
|
||
pure (.deflate ⟨.done, by simp [h1]⟩)
|
||
else
|
||
let nextPos := currPos.prev h1
|
||
let nextIt := ⟨nextPos, needle⟩
|
||
if h2 : needle <| nextPos.get Pos.prev_ne_endPos then
|
||
pure (.deflate ⟨.yield nextIt (.matched nextPos currPos), by simp [h1, h2, nextIt, nextPos]⟩)
|
||
else
|
||
pure (.deflate ⟨.yield nextIt (.rejected nextPos currPos), by simp [h1, h2, nextIt, nextPos]⟩)
|
||
|
||
def finitenessRelation : Std.Iterators.FinitenessRelation (BackwardCharPredSearcher s) Id where
|
||
rel := InvImage WellFoundedRelation.rel
|
||
(fun it => it.internalState.currPos.offset.byteIdx)
|
||
wf := InvImage.wf _ WellFoundedRelation.wf
|
||
subrelation {it it'} h := by
|
||
simp_wf
|
||
obtain ⟨step, h, h'⟩ := h
|
||
cases step
|
||
· cases h
|
||
obtain ⟨_, h1, h2, _⟩ := h'
|
||
have h3 := Pos.offset_prev_lt_offset (h := h1)
|
||
simp [Pos.ext_iff, String.Pos.Raw.ext_iff, String.Pos.Raw.lt_iff] at h2 h3
|
||
omega
|
||
· cases h'
|
||
· cases h
|
||
|
||
instance : Std.Iterators.Finite (BackwardCharPredSearcher s) Id :=
|
||
.of_finitenessRelation finitenessRelation
|
||
|
||
instance : Std.IteratorLoop (BackwardCharPredSearcher s) Id Id :=
|
||
.defaultImplementation
|
||
|
||
@[default_instance]
|
||
instance {p : Char → Bool} : ToBackwardSearcher p BackwardCharPredSearcher where
|
||
toSearcher := iter p
|
||
|
||
@[default_instance]
|
||
instance {p : Char → Bool} : BackwardPattern p := ToBackwardSearcher.defaultImplementation
|
||
|
||
instance {p : Char → Prop} [DecidablePred p] : ToBackwardSearcher p BackwardCharPredSearcher where
|
||
toSearcher := iter (decide <| p ·)
|
||
|
||
instance {p : Char → Prop} [DecidablePred p] : BackwardPattern p :=
|
||
ToBackwardSearcher.defaultImplementation
|
||
|
||
end BackwardCharPredSearcher
|
||
|
||
end String.Slice.Pattern
|