Skip to content

Commit ea065a6

Browse files
committed
Progress on 158
1 parent 3f1553c commit ea065a6

File tree

1 file changed

+100
-3
lines changed

1 file changed

+100
-3
lines changed

HumanEvalLean/HumanEval158.lean

Lines changed: 100 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,102 @@
1-
def find_max : Unit :=
2-
()
1+
import Lean
2+
open Std
3+
4+
def String.numUniqueChars (str : String) : Nat :=
5+
str.foldl (·.insert) (∅ : HashSet _) |>.size
6+
7+
def findMax (strs : List String) : Option String :=
8+
strs.foldl (max? · ·) none
9+
where
10+
max? : Option String → String → String
11+
| none, str => str
12+
| some str₁, str₂ => max str₁ str₂
13+
max (str₁ str₂ : String) : String :=
14+
match compare str₁.numUniqueChars str₂.numUniqueChars with
15+
| .gt => str₁
16+
| .lt => str₂
17+
| .eq => if str₁ < str₂ then str₁ else str₂
18+
19+
example : findMax ["name", "of", "string"] = "string" := by native_decide
20+
example : findMax ["name", "enam", "game"] = "enam" := by native_decide
21+
example : findMax ["aaaaaaa", "bb" ,"cc"] = "aaaaaaa" := by native_decide
22+
example : findMax ["name", "of", "string"] = "string" := by native_decide
23+
example : findMax ["name", "enam", "game"] = "enam" := by native_decide
24+
example : findMax ["aaaaaaa", "bb", "cc"] = "aaaaaaa" := by native_decide
25+
example : findMax ["abc", "cba"] = "abc" := by native_decide
26+
example : findMax ["play", "this", "game", "of","footbott"] = "footbott" := by native_decide
27+
example : findMax ["we", "are", "gonna", "rock"] = "gonna" := by native_decide
28+
example : findMax ["we", "are", "a", "mad", "nation"] = "nation" := by native_decide
29+
example : findMax ["this", "is", "a", "prrk"] = "this" := by native_decide
30+
example : findMax ["b"] = "b" := by native_decide
31+
example : findMax ["play", "play", "play"] = "play" := by native_decide
32+
33+
theorem findMax_mem (h : findMax strs = some m) : m ∈ strs := by
34+
induction strs generalizing m <;> rw [findMax] at h
35+
case nil => contradiction
36+
case cons ih =>
37+
simp [findMax.max?] at h
38+
sorry -- Problem: We can't use IH again, cause we haven't generalized over the fold's init.
39+
-- Can we use `List.foldl_hom`?
40+
41+
theorem findMax_cons : findMax (hd :: tl) = findMax.max? (findMax tl) hd := by
42+
sorry
43+
44+
-- TODO: Does this actually hold? If not, use some sort of lex compare function instead of `<`.
45+
theorem String.le_of_lt {s₁ s₂ : String} (h : s₁ < s₂) : s₁ ≤ s₂ :=
46+
sorry
47+
48+
structure UniqueMax (max : String) (strs : List String) : Prop where
49+
mem : max ∈ strs
50+
max_unique : ∀ str ∈ strs, str.numUniqueChars ≤ max.numUniqueChars
51+
min_lex : ∀ str ∈ strs, str.numUniqueChars = max.numUniqueChars → max ≤ str
52+
53+
namespace UniqueMax
54+
55+
theorem tail (h : UniqueMax m (hd :: tl)) (hm : m ∈ tl) : UniqueMax m tl where
56+
mem := hm
57+
max_unique _ hm := h.max_unique _ (.tail _ hm)
58+
min_lex _ hm := h.min_lex _ (.tail _ hm)
59+
60+
theorem to_findMax_max (h : UniqueMax m strs) (hm : str ∈ strs) : findMax.max m str = m := by
61+
rw [findMax.max]
62+
split <;> (try split) <;> try rfl
63+
next hc =>
64+
rw [Nat.compare_eq_lt] at hc
65+
have := h.max_unique _ hm
66+
omega
67+
next hc hl =>
68+
rw [Nat.compare_eq_eq] at hc
69+
have := h.min_lex _ hm hc.symm
70+
exact String.le_antisymm hl this
71+
72+
theorem to_findMax (h : UniqueMax m strs) : findMax strs = m := by
73+
induction strs <;> cases h.mem
74+
case cons.tail ih hm => simp [findMax_cons, ih (h.tail hm), findMax.max?, h.to_findMax_max]
75+
case cons.head tl ih =>
76+
simp only [findMax_cons, findMax.max?, findMax.max]
77+
split <;> (try split) <;> (try split) <;> try rfl
78+
next hf _ hc =>
79+
rw [Nat.compare_eq_gt] at hc
80+
have := h.max_unique _ (.tail _ <| findMax_mem hf)
81+
omega
82+
next hf _ hc hl =>
83+
rw [Nat.compare_eq_eq] at hc
84+
have := h.min_lex _ (.tail _ <| findMax_mem hf) hc
85+
simp [String.le_antisymm (String.le_of_lt hl) this]
86+
87+
theorem of_findMax (h : findMax strs = some m) : UniqueMax m strs where
88+
mem := findMax_mem h
89+
max_unique str hm := by
90+
induction strs
91+
case nil => sorry
92+
case cons ih => sorry -- Same problem in IH as with `findMax_mem` above.
93+
min_lex := sorry -- Probably by induction with the same problem as commented on above.
94+
95+
theorem iff_findMax : (UniqueMax m strs) ↔ (findMax strs = m) where
96+
mp := to_findMax
97+
mpr := of_findMax
98+
99+
end UniqueMax
3100

4101
/-!
5102
## Prompt
@@ -44,4 +141,4 @@ def check(candidate):
44141
assert (candidate(["play", "play", "play"]) == "play"), 't10'
45142
46143
```
47-
-/
144+
-/

0 commit comments

Comments
 (0)