Skip to content

Commit 3afddd5

Browse files
committed
18
1 parent 149ec09 commit 3afddd5

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

HumanEvalLean/HumanEval18.lean

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,47 @@
11
module
22

3-
def how_many_times : Unit :=
4-
()
3+
-- This compiles to a tight loop calling `memcpy` a bunch of times
4+
def howManyTimes (string substring : String) : Nat :=
5+
string.positions.filter (fun p => (string.sliceFrom p.1).startsWith substring) |>.length
6+
7+
example : howManyTimes "" "a" = 0 := by native_decide
8+
example : howManyTimes "aaa" "a" = 3 := by native_decide
9+
example : howManyTimes "aaaa" "aa" = 3 := by native_decide
10+
example : howManyTimes "xyxyxyx" "x" = 4 := by native_decide
11+
example : howManyTimes "cacacacac" "cac" = 4 := by native_decide
12+
example : howManyTimes "john doe" "john" = 1 := by native_decide
13+
14+
def howManyTimesSpec [DecidableEq α] (string substring : List α) : Nat :=
15+
((0...=string.length).toList.filter (fun i => (string.drop i).take substring.length = substring)).length
16+
17+
theorem howManyTimes_eq {string substring : String} (h : substring ≠ "") :
18+
howManyTimes string substring = howManyTimesSpec string.toList substring.toList := by
19+
simp only [howManyTimes, ne_eq,
20+
← Std.Iter.length_toList_eq_length, Std.Iter.toList_filter, String.toList_positions,
21+
howManyTimesSpec, String.length_toList, Nat.zero_le, Nat.toList_rcc_eq_append,
22+
List.filter_append, List.filter_cons, decide_eq_true_eq, List.filter_nil, List.length_append]
23+
rw [if_neg (by simpa [← String.length_toList])]
24+
simp only [List.length_nil, Nat.add_zero]
25+
suffices ∀ (p : string.Pos) (t₁ t₂ : String), p.Splits t₁ t₂ →
26+
(List.filter (fun p => (string.sliceFrom p.val).startsWith substring)
27+
(String.Model.positionsFrom p)).length =
28+
(List.filter (fun i => decide (List.take substring.length (List.drop i string.toList) = substring.toList))
29+
(t₁.length...string.length).toList).length by
30+
simpa using this string.startPos "" string
31+
intro p t₁ t₂ ht
32+
induction p using String.Pos.next_induction generalizing t₁ t₂ with
33+
| next p hp ih =>
34+
obtain ⟨t₂, rfl⟩ := ht.exists_eq_singleton_append hp
35+
rw [String.Model.positionsFrom_eq_cons hp, List.filter_cons, Nat.toList_rco_eq_cons]
36+
· rw [List.filter_cons, apply_ite List.length, apply_ite List.length]
37+
simp only [String.Slice.startsWith_string_iff, ne_eq, List.length_cons, ih _ _ ht.next,
38+
String.append_singleton, String.length_push, decide_eq_true_eq]
39+
congr
40+
simp [ht.eq_append, ht.copy_sliceFrom_eq, List.prefix_iff_eq_take, eq_comm]
41+
· have := congrArg String.length ht.eq_append
42+
simp at this
43+
omega
44+
| endPos => simp_all
545

646
/-!
747
## Prompt
@@ -49,4 +89,4 @@ def check(candidate):
4989
assert candidate('cacacacac', 'cac') == 4
5090
assert candidate('john doe', 'john') == 1
5191
```
52-
-/
92+
-/

0 commit comments

Comments
 (0)