Skip to content

Commit 11998b0

Browse files
committed
chore: merge main
2 parents d87b4cd + 51e6e0d commit 11998b0

File tree

11 files changed

+72
-137
lines changed

11 files changed

+72
-137
lines changed

Batteries/Data/Fin/Lemmas.lean

+52-19
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,23 @@ protected theorem le_antisymm {x y : Fin n} (h1 : x ≤ y) (h2 : y ≤ x) : x =
3737
theorem list_succ (n) : list (n+1) = 0 :: (list n).map Fin.succ := by
3838
apply List.ext_get; simp; intro i; cases i <;> simp
3939

40-
/-! ### foldlM -/
40+
theorem list_succ_last (n) : list (n+1) = (list n).map castSucc ++ [last n] := by
41+
rw [list_succ]
42+
induction n with
43+
| zero => rfl
44+
| succ n ih =>
45+
rw [list_succ, List.map_cons castSucc, ih]
46+
simp [Function.comp_def, succ_castSucc]
47+
48+
theorem list_reverse (n) : (list n).reverse = (list n).map rev := by
49+
induction n with
50+
| zero => rfl
51+
| succ n ih =>
52+
conv => lhs; rw [list_succ_last]
53+
conv => rhs; rw [list_succ]
54+
simp [List.reverse_map, ih, Function.comp_def, rev_succ]
55+
56+
/-! ### foldl -/
4157

4258
theorem foldlM_loop_lt [Monad m] (f : α → Fin n → m α) (x) (h : i < n) :
4359
foldlM.loop n f x i = f x ⟨i, h⟩ >>= (foldlM.loop n f . (i+1)) := by
@@ -75,14 +91,22 @@ theorem foldlM_eq_foldlM_list [Monad m] (f : α → Fin n → m α) (x) :
7591

7692
theorem foldl_eq_foldlM : foldl n f init = foldlM (m:=Id) n f init := rfl
7793

78-
theorem foldl_zero (f : α → Fin 0 → α) (x) : foldl 0 f x = x := rfl
94+
@[simp] theorem foldl_zero (f : α → Fin 0 → α) (x) : foldl 0 f x = x := rfl
7995

8096
theorem foldl_succ (f : α → Fin (n+1) → α) (x) :
8197
foldl (n+1) f x = foldl n (fun x j => f x j.succ) (f x 0) := foldlM_succ ..
8298

83-
theorem foldl_eq_foldl_list (f : α → Fin n → α) (x) :
84-
foldl n f x = (list n).foldl f x :=
85-
by simp only [foldl_eq_foldlM, foldlM_eq_foldlM_list, List.foldl_eq_foldlM]
99+
theorem foldl_succ_last (f : α → Fin (n+1) → α) (x) :
100+
foldl (n+1) f x = f (foldl n (f · ·.castSucc) x) (last n) := by
101+
rw [foldl_succ]
102+
induction n generalizing x with
103+
| zero => rfl
104+
| succ n ih => rw [foldl_succ, ih (f · ·.succ), foldl_succ]; simp [succ_castSucc]
105+
106+
theorem foldl_eq_foldl_list (f : α → Fin n → α) (x) : foldl n f x = (list n).foldl f x := by
107+
induction n generalizing x with
108+
| zero => rfl
109+
| succ n ih => rw [foldl_succ, ih, list_succ, List.foldl_cons, List.foldl_map]
86110

87111
/-! ### foldrM -/
88112

@@ -104,24 +128,33 @@ theorem foldrM_loop [Monad m] [LawfulMonad m] (f : Fin (n+1) → α → m α) (x
104128
rw [foldrM_loop_succ, foldrM_loop_succ, bind_assoc]
105129
congr; funext; exact ih ..
106130

107-
theorem foldrM_zero [Monad m] (f : Fin 0 → α → m α) (x) : foldrM 0 f x = pure x := rfl
131+
@[simp] theorem foldr_zero (f : Fin 0 → α → α) (x) : foldr 0 f x = x := rfl
108132

109-
theorem foldrM_succ [Monad m] [LawfulMonad m] (f : Fin (n+1) → α → m α) (x) :
110-
foldrM (n+1) f x = foldrM n (fun i => f i.succ) x >>= f 0 := foldrM_loop ..
133+
theorem foldr_succ (f : Fin (n+1) → α → α) (x) :
134+
foldr (n+1) f x = f 0 (foldr n (fun i => f i.succ) x) := foldr_loop ..
111135

112-
theorem foldrM_eq_foldrM_list [Monad m] [LawfulMonad m] (f : Fin n → α → m α) (x) :
113-
foldrM n f x = (list n).foldrM f x := by
114-
induction n with
136+
theorem foldr_succ_last (f : Fin (n+1) → α → α) (x) :
137+
foldr (n+1) f x = foldr n (f ·.castSucc) (f (last n) x) := by
138+
rw [foldr_succ]
139+
induction n generalizing x with
115140
| zero => rfl
116-
| succ n ih => rw [foldrM_succ, ih, list_succ, List.foldrM_cons, List.foldrM_map]
141+
| succ n ih => rw [foldr_succ, ih (f ·.succ), foldr_succ]; simp [succ_castSucc]
117142

118-
theorem foldr_eq_foldrM (f : Fin n → α → α) (init) : foldr n f init = foldrM (m:=Id) n f init := rfl
143+
theorem foldr_eq_foldr_list (f : Fin n → α → α) (x) : foldr n f x = (list n).foldr f x := by
144+
induction n with
145+
| zero => rfl
146+
| succ n ih => rw [foldr_succ, ih, list_succ, List.foldr_cons, List.foldr_map]
119147

120-
theorem foldr_zero (f : Fin 0 → α → α) (x) : foldr 0 f x = x := rfl
148+
/-! ### foldl/foldr -/
121149

122-
theorem foldr_succ (f : Fin (n+1) → α → α) (x) :
123-
foldr (n+1) f x = f 0 (foldr n (fun i => f i.succ) x) := foldrM_loop ..
150+
theorem foldl_rev (f : Fin n → α → α) (x) :
151+
foldl n (fun x i => f i.rev x) x = foldr n f x := by
152+
induction n generalizing x with
153+
| zero => rfl
154+
| succ n ih => rw [foldl_succ, foldr_succ_last, ← ih]; simp [rev_succ]
124155

125-
theorem foldr_eq_foldr_list (f : Fin n → α → α) (x) :
126-
foldr n f x = (list n).foldr f x := by
127-
simp only [foldr_eq_foldrM, foldrM_eq_foldrM_list, List.foldr_eq_foldrM]
156+
theorem foldr_rev (f : α → Fin n → α) (x) :
157+
foldr n (fun i x => f x i.rev) x = foldl n f x := by
158+
induction n generalizing x with
159+
| zero => rfl
160+
| succ n ih => rw [foldl_succ_last, foldr_succ, ← ih]; simp [rev_succ]

Batteries/Data/String.lean

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
import Batteries.Data.String.Basic
22
import Batteries.Data.String.Lemmas
3+
import Batteries.Data.String.Matcher

Batteries/Data/String/Basic.lean

-89
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ Copyright (c) 2022 Jannis Limperg. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Jannis Limperg, James Gallicchio, F. G. Dorais
55
-/
6-
import Batteries.Data.Array.Match
76

87
instance : Coe String Substring := ⟨String.toSubstring⟩
98

@@ -12,63 +11,6 @@ namespace String
1211
protected theorem Pos.ne_zero_of_lt : {a b : Pos} → a < b → b ≠ 0
1312
| _, _, hlt, rfl => Nat.not_lt_zero _ hlt
1413

15-
/-- Knuth-Morris-Pratt matcher type
16-
17-
This type is used to keep data for running the Knuth-Morris-Pratt (KMP) string matching algorithm.
18-
KMP is a linear time algorithm to locate all substrings of a string that match a given pattern.
19-
Generating the algorithm data is also linear in the length of the pattern but the data can be
20-
re-used to match the same pattern over different strings.
21-
22-
The KMP data for a pattern string can be generated using `Matcher.ofString`. Then `Matcher.find?`
23-
and `Matcher.findAll` can be used to run the algorithm on an input string.
24-
```
25-
def m := Matcher.ofString "abba"
26-
27-
#eval Option.isSome <| m.find? "AbbabbA" -- false
28-
#eval Option.isSome <| m.find? "aabbaa" -- true
29-
30-
#eval Array.size <| m.findAll "abbabba" -- 2
31-
#eval Array.size <| m.findAll "abbabbabba" -- 3
32-
```
33-
-/
34-
structure Matcher extends Array.Matcher Char where
35-
/-- The pattern for the matcher -/
36-
pattern : Substring
37-
38-
/-- Make KMP matcher from pattern substring -/
39-
@[inline] def Matcher.ofSubstring (pattern : Substring) : Matcher where
40-
toMatcher := Array.Matcher.ofStream pattern
41-
pattern := pattern
42-
43-
/-- Make KMP matcher from pattern string -/
44-
@[inline] def Matcher.ofString (pattern : String) : Matcher :=
45-
Matcher.ofSubstring pattern
46-
47-
/-- The byte size of the string pattern for the matcher -/
48-
abbrev Matcher.patternSize (m : Matcher) : Nat := m.pattern.bsize
49-
50-
/-- Find all substrings of `s` matching `m.pattern`. -/
51-
partial def Matcher.findAll (m : Matcher) (s : Substring) : Array Substring :=
52-
loop s m.toMatcher #[]
53-
where
54-
/-- Accumulator loop for `String.Matcher.findAll` -/
55-
loop (s : Substring) (am : Array.Matcher Char) (occs : Array Substring) : Array Substring :=
56-
match am.next? s with
57-
| none => occs
58-
| some (s, am) =>
59-
loop s am <| occs.push { s with
60-
startPos := ⟨s.startPos.byteIdx - m.patternSize⟩
61-
stopPos := s.startPos }
62-
63-
/-- Find the first substring of `s` matching `m.pattern`, or `none` if no such substring exists. -/
64-
def Matcher.find? (m : Matcher) (s : Substring) : Option Substring :=
65-
match m.next? s with
66-
| none => none
67-
| some (s, _) =>
68-
some { s with
69-
startPos := ⟨s.startPos.byteIdx - m.patternSize⟩
70-
stopPos := s.startPos }
71-
7214
end String
7315

7416
namespace Substring
@@ -133,41 +75,10 @@ def dropSuffix? (s : Substring) (suff : Substring) : Option Substring :=
13375
else
13476
none
13577

136-
/--
137-
Returns all the substrings of `s` that match `pattern`.
138-
-/
139-
@[inline] def findAllSubstr (s pattern : Substring) : Array Substring :=
140-
(String.Matcher.ofSubstring pattern).findAll s
141-
142-
/--
143-
Returns the first substring of `s` that matches `pattern`,
144-
or `none` if there is no such substring.
145-
-/
146-
@[inline] def findSubstr? (s pattern : Substring) : Option Substring :=
147-
(String.Matcher.ofSubstring pattern).find? s
148-
149-
/--
150-
Returns true iff `pattern` occurs as a substring of `s`.
151-
-/
152-
@[inline] def containsSubstr (s pattern : Substring) : Bool :=
153-
s.findSubstr? pattern |>.isSome
154-
15578
end Substring
15679

15780
namespace String
15881

159-
@[inherit_doc Substring.findAllSubstr]
160-
abbrev findAllSubstr (s : String) (pattern : Substring) : Array Substring :=
161-
(String.Matcher.ofSubstring pattern).findAll s
162-
163-
@[inherit_doc Substring.findSubstr?]
164-
abbrev findSubstr? (s : String) (pattern : Substring) : Option Substring :=
165-
s.toSubstring.findSubstr? pattern
166-
167-
@[inherit_doc Substring.containsSubstr]
168-
abbrev containsSubstr (s : String) (pattern : Substring) : Bool :=
169-
s.toSubstring.containsSubstr pattern
170-
17182
/--
17283
If `pre` is a prefix of `s`, i.e. `s = pre ++ t`, returns the remainder `t`.
17384
-/

Batteries/Lean/Name.lean

+7-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,13 @@ Generally, user code should not explicitly use internal names.
1616
def isInternalDetail : Name → Bool
1717
| .str p s =>
1818
s.startsWith "_"
19-
|| s.startsWith "match_"
20-
|| s.startsWith "proof_"
19+
|| matchPrefix s "eq_"
20+
|| matchPrefix s "match_"
21+
|| matchPrefix s "proof_"
2122
|| p.isInternalOrNum
2223
| .num _ _ => true
2324
| p => p.isInternalOrNum
25+
where
26+
/-- Check that a string begins with the given prefix, and then is only digit characters. -/
27+
matchPrefix (s : String) (pre : String) :=
28+
s.startsWith pre && (s |>.drop pre.length |>.all Char.isDigit)

Batteries/Util/Cache.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ the second will store declarations from imports (and will hopefully be "read-onl
132132
-/
133133
@[reducible] def DiscrTreeCache (α : Type) : Type := DeclCache (DiscrTree α × DiscrTree α)
134134

135-
/-- Discrimation tree settings for the `DiscrTreeCache`. -/
135+
/-- Discrimination tree settings for the `DiscrTreeCache`. -/
136136
def DiscrTreeCache.config : WhnfCoreConfig := {}
137137

138138
/--

Batteries/Util/CheckTactic.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Lean.Elab.Term
99
/-
1010
This file is the home for commands to tactics behave as expected.
1111
12-
It currently includes two tactixs:
12+
It currently includes two tactics:
1313
1414
#check_tactic t ~> res
1515

Batteries/Util/ExtendedBinder.lean

-19
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,3 @@ macro_rules -- TODO: merging the two macro_rules breaks expansion
5252
| `(∀ᵉ _ : $ty:term, $b) => `(∀ _ : $ty:term, $b)
5353
| `(∀ᵉ $x:ident : $ty:term, $b) => `(∀ $x:ident : $ty:term, $b)
5454
| `(∀ᵉ $x:binderIdent $p:binderPred, $b) => `(∀ $x:binderIdent $p:binderPred, $b)
55-
56-
open Parser.Command in
57-
/--
58-
Declares a binder predicate. For example:
59-
```
60-
binder_predicate x " > " y:term => `($x > $y)
61-
```
62-
-/
63-
syntax (name := binderPredicate) (docComment)? (Parser.Term.attributes)? (attrKind)?
64-
"binder_predicate" optNamedName optNamedPrio ppSpace ident (ppSpace macroArg)* " => "
65-
term : command
66-
67-
open Linter.MissingDocs Parser Term in
68-
/-- Missing docs handler for `binder_predicate` -/
69-
@[missing_docs_handler binderPredicate]
70-
def checkBinderPredicate : SimpleHandler := fun stx => do
71-
if stx[0].isNone && stx[2][0][0].getKind != ``«local» then
72-
if stx[4].isNone then lint stx[3] "binder predicate"
73-
else lintNamed stx[4][0][3] "binder predicate"

Batteries/WF.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ end Acc
9191
namespace WellFounded
9292

9393
/-- Attaches to `x` the proof that `x` is accessible in the given well-founded relation.
94-
This can be used in recursive function definitions to explicitly use a differerent relation
94+
This can be used in recursive function definitions to explicitly use a different relation
9595
than the one inferred by default:
9696
9797
```

lean-toolchain

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
leanprover/lean4:v4.8.0-rc2
1+
leanprover/lean4:v4.8.0

scripts/test.lean

+7-3
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,20 @@ def main (args : List String) : IO Unit := do
3636
args := #["env", "lean", t.toString],
3737
env := #[("LEAN_ABORT_ON_PANIC", "1")] }
3838
let mut exitCode := out.exitCode
39+
let stdout := out.stdout
40+
let stderr := "\n".intercalate <|
41+
-- We don't count manifest out of date warnings as noise.
42+
out.stderr.splitOn "\n" |>.filter (!·.startsWith "warning: manifest out of date: ")
3943
if exitCode = 0 then
40-
if out.stdout.isEmpty && out.stderr.isEmpty then
44+
if stdout.isEmpty && stderr.isEmpty then
4145
IO.println s!"Test succeeded: {t}"
4246
else
4347
IO.println s!"Test succeeded with noisy output: {t}"
4448
unless allowNoisy do exitCode := 1
4549
else
4650
IO.eprintln s!"Test failed: `lake env lean {t}` produced:"
47-
unless out.stdout.isEmpty do IO.eprintln out.stdout
48-
unless out.stderr.isEmpty do IO.eprintln out.stderr
51+
unless stdout.isEmpty do IO.eprintln stdout
52+
unless out.stderr.isEmpty do IO.eprintln out.stderr -- We still print the manifest warning.
4953
pure exitCode
5054
-- Wait on all the jobs and exit with 1 if any failed.
5155
let mut exitCode : UInt8 := 0

test/kmp_matcher.lean

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Batteries.Data.String.Basic
1+
import Batteries.Data.String.Matcher
22

33
/-! Tests for Knuth-Morris-Pratt matching algorithm -/
44

0 commit comments

Comments
 (0)