Skip to content

Commit 84c57af

Browse files
committed
early return
1 parent bfe074c commit 84c57af

File tree

1 file changed

+74
-20
lines changed

1 file changed

+74
-20
lines changed

HumanEvalLean/HumanEval59.lean

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@ def largestPrimeFactor (n : Nat) : Nat := Id.run do
3232
let mut m : { m : Nat // 0 < m } := ⟨n, hn⟩
3333
let mut mostRecentFactor := 1
3434
for hd : d in 2...=n do
35-
if d ∣ m.val then
36-
mostRecentFactor := d
37-
m := dividePower m d (by grind [Rcc.mem_iff])
35+
if d * d ≤ m then
36+
if d ∣ m.val then
37+
mostRecentFactor := d
38+
m := dividePower m d (by grind [Rcc.mem_iff])
39+
else
40+
return max mostRecentFactor m
3841
return mostRecentFactor
3942
else
4043
return 1
@@ -87,7 +90,7 @@ theorem largestPrimeFactor_dvd :
8790
apply Id.of_wp_run_eq hwp
8891
mvcgen
8992
invariants
90-
· ⇓⟨cur, m, factor⟩ => ⌜factor ∣ n ∧ m.val ∣ n⌝
93+
· .withEarlyReturn (fun curm, factor⟩ => ⌜factor ∣ n ∧ m.val ∣ n⌝) (fun ret ⟨m, factor⟩ => ⌜ret ∣ n⌝)
9194
with grind [dividePower_dvd, Nat.dvd_trans, Nat.dvd_refl]
9295

9396
theorem dvd_or_dvd_of_dvd_self_div_dividePower {e : Nat} (h : m.val ∣ n)
@@ -123,30 +126,34 @@ theorem isPrime_largestPrimeFactor (h : 1 < n) :
123126
apply Id.of_wp_run_eq hwp
124127
mvcgen
125128
invariants
126-
· ⇓⟨cur, m, factor⟩ =>
129+
· .withEarlyReturn
130+
(fun cur ⟨m, factor⟩ =>
127131
let i := cur.pos + 2;
128132
factor < i ∧
129133
m.val ∣ n ∧
130134
(if m.val = n then factor = 1 else IsPrime factor ∧ ∀ e : Nat, e ∣ n / m → IsPrime e → e ≤ factor) ∧
131-
∀ e : Nat, e ∣ m → e = 1 ∨ i ≤ e⌝
132-
case vc1 pref cur suf _ _ m _ _ ih =>
133-
refine ⟨?_, ?_, ?_, ?_⟩
135+
∀ e : Nat, e ∣ m → e = 1 ∨ i ≤ e⌝)
136+
(fun ret ⟨m, factor⟩ => ⌜IsPrime ret ∧ ∀ d : Nat, d ∣ n → IsPrime d → d ≤ ret⌝)
137+
case vc1 pref cur suf _ _ _ m _ _ _ ih =>
138+
simp only [reduceCtorEq, false_and, exists_false, or_false]
139+
refine ⟨?_, ?_, ?_, ?_, ?_⟩
140+
· grind
134141
· grind
135142
· grind [dividePower_dvd, Nat.dvd_trans]
136143
· simp at *
137144
have : (dividePower m cur (by grind)).val < m.val := dividePower_lt (by grind)
138-
have : m.val ≤ n := Nat.le_of_dvd ‹0 < n› ih.2.1
145+
have : m.val ≤ n := Nat.le_of_dvd ‹0 < n› ih.2.2.1
139146
rw [if_neg (by grind)]
140147
constructor
141148
· rw [IsPrime]
142149
constructor
143150
· grind
144151
· intro d hd
145-
have := ih.2.2.2 d (by grind [Nat.dvd_trans])
152+
have := ih.2.2.2.2 d (by grind [Nat.dvd_trans])
146153
have : d ≤ cur := Nat.le_of_dvd (by grind) hd
147154
grind
148155
· intro e he hep
149-
have := ih.2.2.1
156+
have := ih.2.2.2.1
150157
replace he := dvd_or_dvd_of_dvd_self_div_dividePower (by grind) he hep
151158
split at this
152159
· have : m = ⟨n, ‹_›⟩ := by grind
@@ -159,20 +166,24 @@ theorem isPrime_largestPrimeFactor (h : 1 < n) :
159166
cases he
160167
· grind
161168
· exact Nat.le_of_dvd (by grind) ‹_›
162-
· intro e he
169+
· simp at *
170+
intro e he
163171
have : e ≠ cur := by grind [not_dvd_dividePower]
164-
replace ih := ih.2.2.2 e
172+
replace ih := ih.2.2.2.2 e
165173
grind [dividePower_dvd, Nat.dvd_trans]
166-
case vc2 pref cur suf _ _ _ _ _ ih =>
174+
case vc2 pref cur suf _ _ _ _ _ _ _ ih =>
175+
simp only [List.Cursor.pos_mk, true_and, reduceCtorEq, false_and, exists_const, or_false]
176+
simp only [List.Cursor.pos_mk, reduceCtorEq, false_and, and_false, exists_const, or_false] at ih
167177
refine ⟨?_, ?_, ?_, ?_⟩
168178
· grind
169179
· grind
170180
· grind
171181
· intro e he
172182
have : e ≠ cur := by grind
173-
replace ih := ih.2.2.2 e
183+
replace ih := ih.2.2.2.2 e
174184
grind
175-
case vc3 =>
185+
case vc4 =>
186+
simp only [List.Cursor.pos_mk, true_and, reduceCtorEq, false_and, exists_const, or_false]
176187
refine ⟨?_, ?_, ?_, ?_⟩
177188
· grind
178189
· grind [Nat.dvd_refl]
@@ -181,15 +192,58 @@ theorem isPrime_largestPrimeFactor (h : 1 < n) :
181192
intro e he
182193
have : 0 < e := Nat.pos_of_dvd_of_pos he ‹0 < n›
183194
grind
184-
case vc4 r ih =>
195+
case vc5 r _ ih =>
185196
simp at *
197+
simp_all
186198
have := ih.2.2.2 _ (Nat.dvd_refl _)
187-
have : r.fst.val ≤ n := Nat.le_of_dvd ‹0 < n› ih.2.1
188-
have : r.fst.val = 1 := by grind
199+
have : r.2.1.val ≤ n := Nat.le_of_dvd ‹0 < n› ih.2.1
200+
have : r.2.1.val = 1 := by grind
189201
have := ih.2.2.1
190202
rw [if_neg (by grind)] at this
191203
simpa [*] using this
192-
case vc5 => grind
204+
case vc7 => grind
205+
-- Early return verification conditions:
206+
case vc3 pref cur suff _ _ _ m _ hlt ih =>
207+
simp_all
208+
rw [max_eq_if]
209+
split
210+
· constructor
211+
· grind
212+
· intro d hd hdp
213+
rw [if_neg (by grind)] at ih
214+
rw [← show n / m.val * m.val = n from Nat.div_mul_cancel (by grind)] at hd
215+
rw [hdp.dvd_mul_iff] at hd
216+
cases hd
217+
· grind
218+
· have := ih.2.2.2.2 d ‹_›
219+
cases this
220+
· grind
221+
· have : cur ≤ d := by grind
222+
have : m.val / d ∣ m.val := Nat.div_dvd_of_dvd ‹_›
223+
have : m.val / d < cur := by
224+
rw [Nat.div_lt_iff_lt_mul (by grind)]
225+
exact Nat.lt_of_lt_of_le hlt (Nat.mul_le_mul_left cur ‹_›)
226+
have := ih.2.2.2.2 (m.val / d) ‹_›
227+
cases this
228+
· rename_i h
229+
rw [Nat.div_eq_iff_eq_mul_left (by grind) (by grind)] at h
230+
grind
231+
· grind
232+
· constructor
233+
· rw [isPrime_iff_mul_self]
234+
constructor
235+
· grind [IsPrime]
236+
· intro e he he'
237+
refine Nat.lt_of_lt_of_le hlt ?_
238+
have := ih.2.2.2.2 e he'
239+
exact Nat.mul_self_le_mul_self (by grind)
240+
· intro d hd hdp
241+
rw [← show n / m.val * m.val = n from Nat.div_mul_cancel (by grind)] at hd
242+
rw [hdp.dvd_mul_iff] at hd
243+
cases hd
244+
· grind [Nat.div_self, Nat.dvd_one]
245+
· exact Nat.le_of_dvd (by grind) ‹_›
246+
case vc6 => grind
193247

194248
/-!
195249
## Prompt

0 commit comments

Comments
 (0)