lean4-htt/src/Init/Data/String/Pattern/Pred.lean
Paul Reichert c79d74d9a1
refactor: move Iter and others from Std.Iterators to Std (#11446)
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.
2025-12-15 08:24:12 +00:00

173 lines
6.1 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
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