Skip to content

Commit 896709c

Browse files
committed
70
1 parent 03e707c commit 896709c

File tree

1 file changed

+253
-3
lines changed

1 file changed

+253
-3
lines changed

HumanEvalLean/HumanEval70.lean

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

3-
def strange_sort_list : Unit :=
4-
()
3+
def strangeSortArray (xs : Array Int) : Array Int :=
4+
let sorted := xs.toList.mergeSort.toArray
5+
Array.ofFn (n := sorted.size)
6+
(fun i => if i.val % 2 = 0 then sorted[i.val / 2] else sorted[sorted.size - 1 - i.val / 2])
7+
8+
theorem t {xs : List Int} :
9+
xs.min?.all (· ∈ xs) := by
10+
simp only [Option.all_eq_true_iff_get]
11+
grind
12+
13+
grind_pattern t => xs.min?
14+
15+
def strangeSortListSlow (xs : List Int) : List Int :=
16+
match _ : xs.min? with
17+
| some minimum =>
18+
let xs' := xs.erase minimum
19+
minimum :: (strangeSortListSlow xs'.reverse).reverse
20+
| none => []
21+
termination_by xs.length
22+
decreasing_by grind
23+
24+
theorem strangeSortArray_empty :
25+
strangeSortArray #[] = #[] := by
26+
grind [strangeSortArray, List.mergeSort_nil]
27+
28+
theorem strangeSortArray_singleton :
29+
strangeSortArray #[x] = #[x] := by
30+
ext <;> grind [strangeSortArray, List.mergeSort_singleton, Array.size_ofFn, Array.getElem_ofFn]
31+
32+
theorem List.Perm.min_eq [LE α] [Min α] [Std.LawfulOrderMin α] [Std.IsLinearOrder α]
33+
{xs ys : List α} (h_perm : xs.Perm ys) (h : xs ≠ []) :
34+
xs.min h = ys.min (by grind [Perm.eq_nil]) := by
35+
simp only [List.min_eq_iff]
36+
grind
37+
38+
theorem List.Perm.min?_eq [LE α] [Min α] [Std.LawfulOrderMin α] [Std.IsLinearOrder α]
39+
{xs ys : List α} (h_perm : xs.Perm ys) :
40+
xs.min? = ys.min? := by
41+
match xs, ys with
42+
| [], [] => rfl
43+
| x :: xs, y :: ys =>
44+
rw [min?_eq_some_min, min?_eq_some_min, h_perm.min_eq]
45+
simp
46+
| x :: xs, [] | [], y :: ys => grind [Perm.nil_eq, Perm.eq_nil]
47+
48+
theorem List.Perm.max_eq [LE α] [Max α] [Std.LawfulOrderMax α] [Std.IsLinearOrder α]
49+
{xs ys : List α} (h_perm : xs.Perm ys) (h : xs ≠ []) :
50+
xs.max h = ys.max (by grind [Perm.eq_nil]) := by
51+
simp only [List.max_eq_iff]
52+
grind
53+
54+
theorem List.Perm.max?_eq [LE α] [Max α] [Std.LawfulOrderMax α] [Std.IsLinearOrder α]
55+
{xs ys : List α} (h_perm : xs.Perm ys) :
56+
xs.max? = ys.max? := by
57+
match xs, ys with
58+
| [], [] => rfl
59+
| x :: xs, y :: ys =>
60+
rw [max?_eq_some_max, max?_eq_some_max, h_perm.max_eq]
61+
simp
62+
| x :: xs, [] | [], y :: ys => grind [Perm.nil_eq, Perm.eq_nil]
63+
64+
theorem List.foldl_concat [Max α] {xs : List α} :
65+
(xs.concat x).foldl f init = f (xs.foldl f init) x := by
66+
simp
67+
68+
-- theorem List.max?_concat [Max α] {xs : List α} :
69+
-- (xs.concat x).max? = xs.max?.elim x (fun maximum => max maximum x) := by
70+
-- induction xs
71+
-- sorry
72+
73+
-- theorem List.max?_eq_getLast? [Max α] {xs : List α} (hp : xs.Pairwise (fun a b => max a b = b)) :
74+
-- xs.max? = xs.getLast? := by
75+
-- rw [← List.reverse_reverse (as := xs)]
76+
-- generalize xs.reverse = xs
77+
-- induction xs
78+
-- · simp
79+
-- · rename_i x xs ih
80+
-- simp [List.max?_push, List.getLast?_cons]
81+
82+
theorem List.max_eq_getLast [Max α] {xs : List α} (h) (hp : xs.Pairwise (fun a b => max a b = b)) :
83+
xs.max h = xs.getLast h := by
84+
rw [List.max.eq_def]
85+
split
86+
rename_i x xs _
87+
suffices ∀ xs : List α, (x :: xs.reverse).Pairwise (fun a b => max a b = b) → foldl max x xs.reverse = (x :: xs.reverse).getLast (by grind) by
88+
simp +singlePass only [← List.reverse_reverse (as := xs)]
89+
grind
90+
simp [- pairwise_cons]
91+
intro xs hp
92+
induction xs
93+
· simp
94+
· simp
95+
rename_i ih
96+
rw [ih]
97+
rw [List.reverse_cons, ← List.cons_append, pairwise_append] at hp <;> grind
98+
grind -- what's going on?
99+
100+
theorem Array.max_eq_back [Max α] {xs : Array α} (h) (hp : xs.toList.Pairwise (fun a b => max a b = b)) :
101+
xs.max h = xs.back (by grind) := by
102+
rw [← max_toList, List.max_eq_getLast, getLast_toList]
103+
· exact hp
104+
· simp [h]
105+
106+
theorem List.max?_eq_getLast? [Max α] {xs : List α} (hp : xs.Pairwise (fun a b => max a b = b)) :
107+
xs.max? = xs.getLast? := by
108+
cases xs
109+
· simp
110+
· rw [max?_eq_some_max, max_eq_getLast, getLast?_eq_some_getLast]
111+
· simp
112+
· exact hp
113+
114+
theorem Std.min_eq_left_iff [LE α] [Min α] [Std.Refl (α := α) (· ≤ ·)]
115+
[Std.LawfulOrderLeftLeaningMin α] {a b : α} :
116+
min a b = a ↔ a ≤ b := by
117+
by_cases a ≤ b
118+
· grind [Std.LawfulOrderLeftLeaningMin.min_eq_left]
119+
· rename_i h
120+
simp only [Std.LawfulOrderLeftLeaningMin.min_eq_right _ _ h, iff_false, h]
121+
rintro rfl
122+
exact h.elim (Std.Refl.refl _)
123+
124+
theorem Std.max_eq_right_iff [LE α] [Max α] [Std.IsLinearOrder α] [Std.LawfulOrderMax α]
125+
{a b : α} :
126+
max a b = b ↔ a ≤ b := by
127+
open scoped Classical in grind [max_eq_if]
128+
129+
theorem List.getElem_zero_mergeSort {xs : List Int} (h) :
130+
xs.mergeSort[0]'h = xs.min (by grind [length_mergeSort]) := by
131+
rw [(xs.mergeSort_perm (· ≤ ·)).symm.min_eq, List.min_eq_head, List.head_eq_getElem]
132+
simp only [Std.min_eq_left_iff]
133+
simpa using xs.pairwise_mergeSort (by grind) (by grind) (le := (· ≤ ·))
134+
135+
theorem List.getElem_length_sub_one_mergeSort {xs : List Int} (h) :
136+
xs.mergeSort[xs.length - 1]'h = xs.max (by grind [length_mergeSort]) := by
137+
rw [(xs.mergeSort_perm (· ≤ ·)).symm.max_eq, List.max_eq_getLast, List.getLast_eq_getElem]
138+
· simp [List.length_mergeSort]
139+
· simp only [Std.max_eq_right_iff]
140+
simpa using xs.pairwise_mergeSort (by grind) (by grind) (le := (· ≤ ·))
141+
142+
theorem List.max_erase_le_max {xs : List Int} (h) :
143+
(xs.erase x).max h ≤ xs.max (by grind) := by
144+
simp only [List.max_le_iff]
145+
intro b hb
146+
apply List.le_max_of_mem
147+
exact List.mem_of_mem_erase hb
148+
149+
theorem Array.max_erase_le_max {xs : Array Int} {h} :
150+
(xs.erase x).max h ≤ xs.max (by grind) := by
151+
simp only [Array.max_le_iff]
152+
intro b hb
153+
apply Array.le_max_of_mem
154+
exact Array.mem_of_mem_erase hb
155+
156+
theorem List.count_dropLast [BEq α] {xs : List α} {a : α} :
157+
xs.dropLast.count a = xs.count a - if xs.getLast? == some a then 1 else 0 := by
158+
rw [← List.reverse_reverse (as := xs)]
159+
generalize xs.reverse = xs
160+
rw [dropLast_reverse, count_reverse, count_tail, getLast?_reverse, count_reverse]
161+
162+
theorem Array.count_pop [BEq α] {xs : Array α} {a : α} :
163+
xs.pop.count a = xs.count a - if xs.back? == some a then 1 else 0 := by
164+
rw [← count_toList, toList_pop, List.count_dropLast, getLast?_toList, count_toList]
165+
166+
theorem bla {xs : Array Int} {h} :
167+
(xs.erase (xs.max h)).Perm xs.toList.mergeSort.toArray.pop := by
168+
simp only [Array.perm_iff_toList_perm]
169+
simp [List.perm_iff_count, Array.count_toList, - List.pop_toArray, - Array.toList_pop]
170+
intro a
171+
rw [Array.count_erase]
172+
have h_mem : xs.max h ∈ xs := by grind
173+
rw [Array.count_pop, List.count_toArray, List.count_toArray, (List.mergeSort_perm _ _).count_eq,
174+
List.back?_toArray, ← List.max?_eq_getLast?, (List.mergeSort_perm _ _).max?_eq, Array.max?_toList,
175+
Array.max?_eq_some_max]
176+
· simp
177+
· grind
178+
· simp only [Std.max_eq_right_iff]
179+
simpa using List.pairwise_mergeSort (α := Int) (le := (· ≤ ·)) (by grind) (by grind) _
180+
181+
theorem bla' {xs : Array Int} {h} :
182+
(xs.erase (xs.max h)).toList.mergeSort = xs.toList.mergeSort.dropLast := by
183+
apply List.Perm.eq_of_pairwise (le := (· ≤ ·))
184+
· grind
185+
· simpa using List.pairwise_mergeSort (α := Int) (le := (· ≤ ·)) (by grind) (by grind) _
186+
· simp only [List.dropLast_eq_take]
187+
apply List.Pairwise.take
188+
simpa using List.pairwise_mergeSort (α := Int) (le := (· ≤ ·)) (by grind) (by grind) _
189+
· refine List.Perm.trans (List.mergeSort_perm _ _) ?_
190+
rw [← Array.perm_iff_toList_perm]
191+
apply bla
192+
193+
theorem blub' {xs : Array Int} {h} :
194+
(xs.erase (xs.min h)).toList.mergeSort = xs.toList.mergeSort.drop 1 := by
195+
apply List.Perm.eq_of_pairwise (le := (· ≤ ·))
196+
· grind
197+
· simpa using List.pairwise_mergeSort (α := Int) (le := (· ≤ ·)) (by grind) (by grind) _
198+
· apply List.Pairwise.drop
199+
simpa using List.pairwise_mergeSort (α := Int) (le := (· ≤ ·)) (by grind) (by grind) _
200+
· refine List.Perm.trans (List.mergeSort_perm _ _) ?_
201+
rw [← Array.perm_iff_toList_perm]
202+
simp only [Array.perm_iff_toList_perm]
203+
simp [List.perm_iff_count, Array.count_toList, - List.pop_toArray, - Array.toList_pop]
204+
intro a
205+
rw [Array.count_erase]
206+
have h_mem : xs.max h ∈ xs := by grind
207+
rw [List.count_tail, List.count_toArray, (List.mergeSort_perm _ _).count_eq,
208+
← List.min?_eq_head?, (List.mergeSort_perm _ _).min?_eq, Array.min?_toList,
209+
Array.min?_eq_some_min]
210+
· simp
211+
· grind
212+
· simp only [Std.min_eq_left_iff]
213+
simpa using List.pairwise_mergeSort (α := Int) (le := (· ≤ ·)) (by grind) (by grind) _
214+
215+
theorem size_strangeSortArray {xs : Array Int} :
216+
(strangeSortArray xs).size = xs.size := by
217+
simp [strangeSortArray]
218+
219+
theorem strangeSortArray_of_two_le_size (h : 2 ≤ xs.size) :
220+
let minimum := xs.min (by grind)
221+
let withoutMin := xs.erase minimum
222+
let maximum := withoutMin.max (by grind)
223+
let withoutMinMax := withoutMin.erase maximum
224+
strangeSortArray xs = #[minimum, maximum] ++ strangeSortArray withoutMinMax := by
225+
intro minimum withoutMin maximum withoutMinMax
226+
ext
227+
· simp [strangeSortArray]
228+
grind
229+
· rename_i i h₁ h₂
230+
simp [strangeSortArray]
231+
match i with
232+
| 0 => grind [List.getElem_zero_mergeSort]
233+
| 1 =>
234+
simp [← Array.length_toList, List.getElem_length_sub_one_mergeSort, maximum, withoutMin]
235+
rw [Array.max_eq_iff]
236+
constructor
237+
· grind [Array.mem_of_mem_erase]
238+
· intro b hb
239+
by_cases hb' : b = minimum
240+
· cases hb'
241+
simp only [minimum]
242+
apply Array.min_le_of_mem
243+
exact Array.mem_of_mem_erase (Array.max_mem _)
244+
· apply Array.le_max_of_mem
245+
rwa [Array.mem_erase_of_ne]
246+
assumption
247+
| j + 2 =>
248+
have : withoutMinMax.toList.mergeSort = xs.toList.mergeSort.extract 1 (xs.toList.mergeSort.length - 1) := by
249+
simp only [withoutMinMax, maximum, bla']
250+
simp only [withoutMin, minimum, blub']
251+
simp only [List.extract_eq_take_drop, List.dropLast_eq_take]
252+
grind
253+
simp [this]
254+
grind [size_strangeSortArray]
5255

6256
/-!
7257
## Prompt
@@ -52,4 +302,4 @@ def check(candidate):
52302
assert True
53303
54304
```
55-
-/
305+
-/

0 commit comments

Comments
 (0)