Skip to content

Commit c6cd38a

Browse files
committed
Overhaul definitions
1 parent c33ec7f commit c6cd38a

File tree

1 file changed

+64
-53
lines changed

1 file changed

+64
-53
lines changed

HumanEvalLean/HumanEval155.lean

Lines changed: 64 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,70 @@
1-
def Int.toDigits (i : Int) : List Char :=
2-
i.natAbs.toDigits (base := 10)
3-
4-
def evenOddCount (num : Int) : Nat × Nat :=
5-
num.toDigits.foldl countDigit (0, 0)
6-
where
7-
countDigit (evenOdd : Nat × Nat) : Char → Nat × Nat
8-
| '0' | '2' | '4' | '6' | '8' => (evenOdd.fst + 1, evenOdd.snd)
9-
| _ => (evenOdd.fst, evenOdd.snd + 1)
10-
11-
example : evenOddCount (-12) = (1, 1) := rfl
12-
example : evenOddCount 123 = (1, 2) := rfl
13-
example : evenOddCount 7 = (0, 1) := rfl
14-
example : evenOddCount (-78) = (1, 1) := rfl
15-
example : evenOddCount 3452 = (2, 2) := rfl
16-
example : evenOddCount 346211 = (3, 3) := rfl
17-
example : evenOddCount (-345821) = (3, 3) := rfl
18-
example : evenOddCount (-2) = (1, 0) := rfl
19-
example : evenOddCount (-45347) = (2, 3) := rfl
20-
example : evenOddCount 0 = (1, 0) := rfl
21-
22-
def Prod.sum : (Nat × Nat) → Nat
23-
| (n₁, n₂) => n₁ + n₂
24-
25-
instance : Add (Nat × Nat) where
26-
add | (l₁, r₁), (l₂, r₂) => (l₁ + l₂, r₁ + r₂)
27-
28-
instance : Sub (Nat × Nat) where
29-
sub | (l₁, r₁), (l₂, r₂) => (l₁ - l₂, r₁ - r₂)
30-
31-
-- Applying `evenOddCount.countDigit` increases the total digit count by `1`.
32-
theorem evenOddCount.countDigit_sum (evenOdd : Nat × Nat) (d : Char) :
33-
(evenOddCount.countDigit evenOdd d).sum = evenOdd.sum + 1 := by
34-
unfold evenOddCount.countDigit
35-
split <;> simp +arith [Prod.sum]
36-
37-
-- Folding `evenOddCount.countDigit` over a given digit count `init` produces the same total digit
38-
-- count as folding `evenOddCount.countDigit` over `(0, 0)` and adding that to `init`.
39-
theorem evenOddCount.countDigit_sum_foldl (ds : List Char) (init : Nat × Nat) :
40-
(ds.foldl evenOddCount.countDigit init).sum =
41-
(ds.foldl evenOddCount.countDigit (0, 0)).sum + init.sum := by
42-
induction ds generalizing init
43-
case nil => simp [Prod.sum]
44-
case cons ih => simp +arith only [List.foldl_cons, ih (countDigit _ _), countDigit_sum]; rfl
1+
-- https://github.com/leanprover-community/batteries/pull/1267
2+
theorem Nat.isDigit_digitChar_iff_lt : n.digitChar.isDigit ↔ (n < 10) := sorry
3+
theorem Nat.mem_toDigits_base_10_isDigit (h : c ∈ toDigits 10 n) : c.isDigit := sorry
4+
5+
abbrev Digit := { c : Char // c.isDigit }
6+
7+
def Int.digits (i : Int) : List Digit :=
8+
i.natAbs
9+
|>.toDigits (base := 10)
10+
|>.attach
11+
|>.map fun ⟨j, h⟩ => ⟨j, Nat.mem_toDigits_base_10_isDigit h⟩
12+
13+
structure Tally where
14+
even : Nat
15+
odd : Nat
16+
deriving Inhabited
17+
18+
namespace Tally
4519

46-
-- The total digit count produced by `evenOddCount` matches the number of digits in the input.
47-
theorem evenOddCount_sum_eq_length : (evenOddCount i).sum = i.toDigits.length := by
48-
rw [evenOddCount]
49-
generalize i.toDigits = ds
20+
instance : Add Tally where
21+
add t₁ t₂ := { even := t₁.even + t₂.even, odd := t₁.odd + t₂.odd }
22+
23+
def total (t : Tally) : Nat :=
24+
t.even + t.odd
25+
26+
def log (t : Tally) (d : Digit) : Tally :=
27+
match d.val with
28+
| '0' | '2' | '4' | '6' | '8' => { t with even := t.even + 1 }
29+
| _ => { t with odd := t.odd + 1 }
30+
31+
-- Applying `log` increases a tally's total by `1`.
32+
theorem log_total (d : Digit) (t : Tally) : (t.log d).total = t.total + 1 := by
33+
rw [log]
34+
split <;> simp +arith [total]
35+
36+
-- Folding `log` over a given tally `init` produces the same total digit count as folding `log` over
37+
-- `⟨0, 0⟩` and adding that to `init`.
38+
theorem log_total_foldl {ds : List Digit} (init : Tally) :
39+
(ds.foldl log init).total = (ds.foldl log ⟨0, 0⟩).total + init.total := by
40+
induction ds generalizing init
41+
case' cons hd _ ih => simp +arith only [List.foldl_cons, ih (log _ hd), log_total]
42+
all_goals simp [total]
43+
44+
def count (i : Int) : Tally :=
45+
i.digits.foldl log ⟨0, 0
46+
47+
example : count (-12) = ⟨1, 1⟩ := rfl
48+
example : count 123 = ⟨1, 2⟩ := rfl
49+
example : count 7 = ⟨0, 1⟩ := rfl
50+
example : count (-78) = ⟨1, 1⟩ := rfl
51+
example : count 3452 = ⟨2, 2⟩ := rfl
52+
example : count 346211 = ⟨3, 3⟩ := rfl
53+
example : count (-345821) = ⟨3, 3⟩ := rfl
54+
example : count (-2) = ⟨1, 0⟩ := rfl
55+
example : count (-45347) = ⟨2, 3⟩ := rfl
56+
example : count 0 = ⟨1, 0⟩ := rfl
57+
58+
-- The tally total produced by `count` matches the number of digits in the input.
59+
theorem count_total_eq_length : (count i).total = i.digits.length := by
60+
rw [count]
61+
generalize i.digits = ds
5062
induction ds
51-
case nil => rfl
52-
case cons ih => rw [List.foldl_cons, List.length_cons, evenOddCount.countDigit_sum_foldl, ih,
53-
evenOddCount.countDigit_sum, Prod.sum]
63+
case nil => rfl
64+
case cons ih => rw [List.foldl_cons, List.length_cons, log_total_foldl, ih, log_total]; rfl
5465

55-
theorem evenOddCount_decompose :
56-
evenOddCount (10 * n + d) = evenOddCount n + evenOddCount (d % 10) - (1, 0) :=
66+
theorem count_decompose {d : Nat} (hd : d < 10) :
67+
count (10 * n + d) = count n + d % 2, 1 - d % 2⟩ := by
5768
sorry
5869

5970
/-!

0 commit comments

Comments
 (0)