Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 69 additions & 3 deletions HumanEvalLean/HumanEval8.lean
Original file line number Diff line number Diff line change
@@ -1,5 +1,71 @@
def sum_product : Unit :=
()
import Std.Tactic.Do
open Std.Do
set_option mvcgen.warning false

def List.product (xs : List Int) : Int :=
match xs with
| [] => 1
| x :: xs' => x * (product xs')

def sumProduct (xs : List Int) : Int × Int := (List.sum xs, List.product xs)

def sumProductDo (xs : List Int) : Int × Int := Id.run do
let mut sum := 0
let mut product := 1
for x in xs do
sum := sum + x
product := product * x

return (sum, product)

theorem List.sum_append (xs : List Int) (ys : List Int)
: sum (xs ++ ys) = sum xs + sum ys := by
Comment on lines +21 to +22
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a very minor remark, but in this repository we usually put the colon at the end of the line:

Suggested change
theorem List.sum_append (xs : List Int) (ys : List Int)
: sum (xs ++ ys) = sum xs + sum ys := by
theorem List.sum_append (xs : List Int) (ys : List Int) :
sum (xs ++ ys) = sum xs + sum ys := by

induction xs with
| nil =>
change sum ys = 0 + sum ys
omega
| cons x xs hi =>
change x + sum (xs ++ ys) = x + sum xs + sum ys
rw [hi]
omega

theorem List.product_append (xs : List Int) (ys : List Int)
: product (xs ++ ys) = product xs * product ys := by
Comment on lines +32 to +33
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly:

Suggested change
theorem List.product_append (xs : List Int) (ys : List Int)
: product (xs ++ ys) = product xs * product ys := by
theorem List.product_append (xs : List Int) (ys : List Int) :
product (xs ++ ys) = product xs * product ys := by

induction xs with
| nil =>
change product ys = 1 * product ys
omega
| cons x xs hi =>
change x * product (xs ++ ys) = x * product xs * product ys
rw [hi]
simp only [Int.mul_assoc]

theorem sumProductDo_correct (xs : List Int) : sumProductDo xs = sumProduct xs := by
generalize h : sumProductDo xs = ys
apply Id.of_wp_run_eq h
mvcgen
invariants
· ⇓ ⟨ cur, result ⟩ =>
⌜ result.snd = List.sum cur.prefix ∧ result.fst = List.product cur.prefix ⌝
case vc1.step pref x suff h' result hi =>
obtain ⟨ hi₀, hi₁⟩ := hi
constructor
rw [hi₀, List.sum_append]
change List.sum pref + x = List.sum pref + (x + 0)
omega
rw [hi₁, List.product_append]
change List.product pref * x = List.product pref * (x * 1)
rw [Int.mul_one]
case vc3.a.post.success result h' =>
obtain ⟨ left, right ⟩ := h'
rw [left, right]
rfl
Comment on lines +50 to +62
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want, you could also use grind, which saves you some of the annoying manual changes:

Suggested change
case vc1.step pref x suff h' result hi =>
obtain ⟨ hi₀, hi₁⟩ := hi
constructor
rw [hi₀, List.sum_append]
change List.sum pref + x = List.sum pref + (x + 0)
omega
rw [hi₁, List.product_append]
change List.product pref * x = List.product pref * (x * 1)
rw [Int.mul_one]
case vc3.a.post.success result h' =>
obtain ⟨ left, right ⟩ := h'
rw [left, right]
rfl
case vc1.step pref x suff h' result hi =>
rw [List.sum_append, List.product_append]
grind [List.product]
case vc3.a.post.success result h' =>
grind [sumProduct]


example : sumProductDo [] = (0, 1) := by rfl
example : sumProductDo [1, 1, 1] = (3, 1) := by rfl
example : sumProductDo [100, 0] = (100, 0) := by rfl
example : sumProductDo [3, 5, 7] = (3 + 5 + 7, 3 * 5 * 7) := by rfl
example : sumProductDo [10] = (10, 10) := by rfl

/-!
## Prompt
Expand Down Expand Up @@ -48,4 +114,4 @@ def check(candidate):
assert candidate([3, 5, 7]) == (3 + 5 + 7, 3 * 5 * 7)
assert candidate([10]) == (10, 10)
```
-/
-/