Skip to content

Commit e339545

Browse files
authored
39 (#255)
This PR solves problem 39.
1 parent c0621be commit e339545

File tree

2 files changed

+138
-5
lines changed

2 files changed

+138
-5
lines changed

HumanEvalLean/HumanEval39.lean

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

3-
def prime_fib : Unit :=
4-
()
3+
public import HumanEvalLean.Common.IsPrime
4+
meta import HumanEvalLean.Common.IsPrime
5+
6+
public section
7+
8+
/-! ## Implementation -/
9+
10+
def primeFib (n : Nat) : Nat :=
11+
go 0 1 (n - 1)
12+
where
13+
go (i j n : Nat) : Nat :=
14+
if isPrime j then
15+
match n with
16+
| 0 => j
17+
| n' + 1 => go j (i + j) n'
18+
else
19+
go j (i + j) n
20+
partial_fixpoint
21+
22+
/-! ## Tests -/
23+
24+
example : primeFib 1 = 2 := by native_decide
25+
example : primeFib 2 = 3 := by native_decide
26+
example : primeFib 3 = 5 := by native_decide
27+
example : primeFib 4 = 13 := by native_decide
28+
example : primeFib 5 = 89 := by native_decide
29+
example : primeFib 6 = 233 := by native_decide
30+
example : primeFib 7 = 1597 := by native_decide
31+
example : primeFib 8 = 28657 := by native_decide
32+
example : primeFib 9 = 514229 := by native_decide
33+
example : primeFib 10 = 433494437 := by native_decide
34+
35+
/-! ## Verification -/
36+
37+
noncomputable def fib (n : Nat) :=
38+
match n with
39+
| 0 => 0
40+
| 1 => 1
41+
| n + 2 => fib n + fib (n + 1)
42+
43+
theorem fib_pos {n : Nat} (h : 0 < n) :
44+
0 < fib n := by
45+
induction n using Nat.strongRecOn
46+
rename_i n ih
47+
fun_cases fib n <;> grind
48+
49+
private theorem primeFib_eq_go_fib_fib {n : Nat} :
50+
primeFib n = primeFib.go (fib 0) (fib 1) (n - 1) := by
51+
grind [primeFib, fib]
52+
53+
private theorem primeFibGo_fib_fib {i n : Nat} :
54+
primeFib.go (fib i) (fib (i + 1)) n =
55+
if isPrime (fib (i + 1)) then
56+
match n with
57+
| 0 => fib (i + 1)
58+
| n' + 1 => primeFib.go (fib (i + 1)) (fib (i + 2)) n'
59+
else
60+
primeFib.go (fib (i + 1)) (fib (i + 2)) n := by
61+
grind [primeFib.go.eq_def, fib]
62+
63+
set_option warn.sorry false in
64+
/--
65+
This lemma is a functional induction principle for `primeFib.go` assuming that
66+
there are infinitely many prime Fibonacci numbers, such that the function terminates.
67+
This is a mathematically hard problem, so we don't provide a proof.
68+
-/
69+
theorem primeFib_induction' (motive : Nat → Nat → Prop)
70+
(case1 : ∀ (i : Nat), isPrime (fib (i + 1)) = true → motive i 0)
71+
(case2 : ∀ (i : Nat), isPrime (fib (i + 1)) = true → ∀ (n' : Nat), motive (i + 1) n' → motive i n'.succ)
72+
(case3 : ∀ (i n : Nat), ¬isPrime (fib (i + 1)) = true → motive (i + 1) n → motive i n) (i n : Nat) :
73+
motive i n := by
74+
sorry
75+
76+
/--
77+
`primeFib n` is a prime number.
78+
-/
79+
theorem isPrime_primeFib {n : Nat} :
80+
IsPrime (primeFib n) := by
81+
suffices ∀ (i n : Nat), IsPrime (primeFib.go (fib i) (fib (i + 1)) n) by
82+
grind [primeFib_eq_go_fib_fib]
83+
intro i n
84+
induction i, n using primeFib_induction'
85+
all_goals grind [primeFibGo_fib_fib, isPrime_eq_true_iff_isPrime]
86+
87+
/--
88+
`primeFib n` is a Fibonacci number.
89+
-/
90+
theorem exists_primeFib_eq_fib {n : Nat} :
91+
∃ m, primeFib n = fib m := by
92+
suffices ∀ (i : Nat) (n : Nat), ∃ m, primeFib.go (fib i) (fib (i + 1)) n = fib m by
93+
obtain ⟨m, hm⟩ := this 0 (n - 1)
94+
exact ⟨m, by grind [primeFib_eq_go_fib_fib]⟩
95+
intro i n
96+
induction i, n using primeFib_induction' <;> grind [primeFibGo_fib_fib]
97+
98+
private theorem le_primeFibGo {i n : Nat} :
99+
fib (i + 1) ≤ primeFib.go (fib i) (fib (i + 1)) n := by
100+
induction i, n using primeFib_induction'
101+
all_goals grind [fib, primeFibGo_fib_fib]
102+
103+
/--
104+
`primeFib i` is strictly monotone in `i`,
105+
starting from `i = 1` (`i = 0` is not considered a valid input by the problem description),
106+
-/
107+
theorem primeFib_mono {i j : Nat} (hi : 0 < i) (hj : i < j) :
108+
primeFib i < primeFib j := by
109+
suffices ∀ (i n : Nat), primeFib.go (fib i) (fib (i + 1)) n < primeFib.go (fib i) (fib (i + 1)) (n + 1) by
110+
obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_lt hj
111+
induction k
112+
· specialize this 0 (i - 1)
113+
grind [primeFib_eq_go_fib_fib]
114+
· grind [primeFib_eq_go_fib_fib]
115+
intro i n
116+
induction i, n using primeFib_induction'
117+
all_goals grind [primeFibGo_fib_fib, le_primeFibGo, fib, fib_pos,
118+
isPrime_eq_true_iff_isPrime, IsPrime]
119+
120+
/--
121+
Every prime Fibonacci number is contained in the image of `primeFib`.
122+
-/
123+
theorem exists_eq_primeFib_of_isPrime_fib {n : Nat} (h : IsPrime (fib n)) :
124+
∃ m, primeFib m = fib n := by
125+
suffices ∀ (i : Nat) (hi : i < n), ∃ m, primeFib.go (fib i) (fib (i + 1)) m = fib n by
126+
have hn : 0 < n := by grind [IsPrime, fib]
127+
obtain ⟨m, hm⟩ := this 0 (by grind)
128+
exact ⟨m + 1, by grind [primeFib_eq_go_fib_fib]⟩
129+
intro i hi
130+
induction h : n - i - 1 generalizing i
131+
· exact ⟨0, by grind [primeFibGo_fib_fib, isPrime_eq_true_iff_isPrime]⟩
132+
· rename_i k ih
133+
obtain ⟨m, hm⟩ := ih (i + 1) (by grind) (by grind)
134+
simp +singlePass only [primeFibGo_fib_fib]
135+
split
136+
· exact ⟨m + 1, by grind⟩
137+
· exact ⟨m, by grind⟩
5138

6139
/-!
7140
## Prompt
@@ -67,4 +200,4 @@ def check(candidate):
67200
assert candidate(10) == 433494437
68201
69202
```
70-
-/
203+
-/

HumanEvalLean/HumanEval4.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ theorem mean_spec {xs : Array Rat} :
7575
theorem meanAbsoluteDeviation_spec {xs : Array Rat} :
7676
meanAbsoluteDeviation xs =
7777
mean (xs.map (fun x => (x - mean xs).abs)) := by
78-
-- TODO: get rid of `+instances`, which is not endorsed.
79-
simp +instances [meanAbsoluteDeviation, mean, ← Iter.sum_toList, ← Array.sum_toList]
78+
rw [meanAbsoluteDeviation, ← Iter.sum_toList, Iter.toList_map]
79+
simp [mean, ← Array.sum_toList]
8080

8181
/-!
8282
## Prompt

0 commit comments

Comments
 (0)