forked from leanprover/human-eval-lean
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHumanEval46.lean
More file actions
132 lines (104 loc) · 3.16 KB
/
HumanEval46.lean
File metadata and controls
132 lines (104 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
module
public import Std
open Std Std.Do
set_option mvcgen.warning false
/-! ## Implementation -/
def fib4 (n : Nat) : Nat := Id.run do
let mut lastFour : Vector Nat 4 := #v[0, 0, 2, 0]
for i in *...(n - 3) do
lastFour := lastFour.set (i % 4) (lastFour[0] + lastFour[1] + lastFour[2] + lastFour[3])
return lastFour[n % 4]
/-! ## Tests -/
example : fib4 5 = 4 := by cbv
example : fib4 8 = 28 := by cbv
example : fib4 10 = 104 := by cbv
example : fib4 12 = 386 := by cbv
/-! ## Missing API -/
theorem eq_getElem_append_cons {pref suff : List α} {cur : α} :
(pref ++ cur :: suff)[pref.length]? = cur := by
simp
grind_pattern eq_getElem_append_cons => pref ++ cur :: suff
attribute [grind =] Nat.getElem?_toList_rio
attribute [grind =] Nat.length_toList_rio
/-! ## Verification -/
def fib4Reference : Nat → Nat
| 0 => 0
| 1 => 0
| 2 => 2
| 3 => 0
| k + 4 =>
fib4Reference (k + 3) + fib4Reference (k + 2) + fib4Reference (k + 1) + fib4Reference k
theorem sum_mod_eq_sum {vec : Vector Nat 4} :
∀ i, vec[i % 4] + vec[(i + 1) % 4] + vec[(i + 2) % 4] + vec[(i + 3) % 4] =
vec[0] + vec[1] + vec[2] + vec[3]
| 0 | 1 | 2 | 3 => by grind
| i + 4 => by
have := sum_mod_eq_sum (vec := vec) (i := i)
have : ∀ j, j < 4 → (i + 4 + j) % 4 = (i + j) % 4 := by grind
simp only [Nat.add_mod_right, Nat.reduceLT, this, Nat.lt_add_one]
grind
theorem fib4_eq_fib4Reference :
fib4 n = fib4Reference n := by
generalize hwp : fib4 n = wp
apply Id.of_wp_run_eq hwp
mvcgen
invariants
· ⇓⟨cur, lastFour⟩ => ⌜∀ i, i < 4 → lastFour[(cur.pos + i) % 4] = fib4Reference (cur.pos + i)⌝
case vc1 pref cur suff heq _ _ h =>
simp_all only [List.Cursor.pos_mk, List.length_append, List.length_cons, List.length_nil]
intro i hi
by_cases i = 3
· rename_i hi'
rw [hi', fib4Reference]
simp only [show (pref.length + 1 + 3) % 4 = cur % 4 by grind]
grind [sum_mod_eq_sum, h 0 (by grind), h 1 (by grind), h 2 (by grind), h 3 (by grind),
Vector.getElem_set_self]
· specialize h (i + 1) (by grind)
grind
case vc2 =>
simp only [List.Cursor.pos_mk, Vector.getElem_eq_iff]
decide
case vc3 h =>
by_cases hn : n < 4
· grind
· specialize h 3
grind
/-!
## Prompt
```python3
def fib4(n: int):
"""The Fib4 number sequence is a sequence similar to the Fibbonacci sequnece that's defined as follows:
fib4(0) -> 0
fib4(1) -> 0
fib4(2) -> 2
fib4(3) -> 0
fib4(n) -> fib4(n-1) + fib4(n-2) + fib4(n-3) + fib4(n-4).
Please write a function to efficiently compute the n-th element of the fib4 number sequence. Do not use recursion.
>>> fib4(5)
4
>>> fib4(6)
8
>>> fib4(7)
14
"""
```
## Canonical solution
```python3
results = [0, 0, 2, 0]
if n < 4:
return results[n]
for _ in range(4, n + 1):
results.append(results[-1] + results[-2] + results[-3] + results[-4])
results.pop(0)
return results[-1]
```
## Tests
```python3
METADATA = {}
def check(candidate):
assert candidate(5) == 4
assert candidate(8) == 28
assert candidate(10) == 104
assert candidate(12) == 386
```
-/