Skip to content

Commit 6c4a5b9

Browse files
committed
use closed intervals to match problem semantics
1 parent 79d5e62 commit 6c4a5b9

File tree

2 files changed

+55
-22
lines changed

2 files changed

+55
-22
lines changed

HumanEvalLean/HumanEval127.lean

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

33
import HumanEvalLean.Common.IsPrime
4+
meta import HumanEvalLean.Common.IsPrime -- for `native_decide`
45

56
/-!
67
## Implementation
@@ -26,21 +27,9 @@ example : intersection (1, 2) (1, 2) = "NO" := by native_decide
2627
example : intersection (-2, -2) (-3, -2) = "NO" := by native_decide
2728

2829
/-!
29-
## Verification
30+
## Missing API
3031
-/
3132

32-
theorem intersection_swap {p q} :
33-
intersection p q = intersection q p := by
34-
grind [intersection]
35-
36-
theorem intersection_mem {p q} :
37-
intersection p q ∈ ["YES", "NO"] := by
38-
grind [intersection]
39-
40-
theorem Int.mem_filter_mem_rco_toList_rco {l₁ r₁ l₂ r₂ : Int} {x : Int} :
41-
x ∈ (l₁...r₁).toList.filter (· ∈ l₂...r₂) ↔ x ∈ ((max l₁ l₂)...(min r₁ r₂)) := by
42-
grind [Std.Rco.mem_toList_iff_mem, Std.Rco.mem_iff]
43-
4433
-- stolen from Init.Data.Range.Polymorphic.Lemmas, which is private
4534
private theorem eq_of_pairwise_lt_of_mem_iff_mem {lt : α → α → Prop} [asymm : Std.Asymm lt]
4635
{l l' : List α} (hl : l.Pairwise lt) (hl' : l'.Pairwise lt)
@@ -94,21 +83,64 @@ private theorem eq_of_pairwise_lt_of_mem_iff_mem {lt : α → α → Prop} [asym
9483
have hgt := hl.1 y ‹_›
9584
cases Std.Asymm.asymm _ _ hlt hgt
9685

97-
-- not @[grind =] because `(· ∈ l₂...r₂)` cannot part of the discrimination key
98-
theorem Int.filter_mem_rco_toList_rco {l₁ r₁ l₂ r₂ : Int} :
99-
(l₁...r₁).toList.filter (· ∈ l₂...r₂) = ((max l₁ l₂)...(min r₁ r₂)).toList := by
86+
deriving instance DecidableEq for Std.Rcc
87+
88+
/-!
89+
## Verification
90+
-/
91+
92+
theorem intersection_swap {p q} :
93+
intersection p q = intersection q p := by
94+
grind [intersection]
95+
96+
theorem intersection_mem {p q} :
97+
intersection p q ∈ ["YES", "NO"] := by
98+
grind [intersection]
99+
100+
/--
101+
According to the problem description, the length of a range is the difference of its bounds.
102+
Caution: This is different from the size of the range, a.k.a. `r.size` and `r.toList.length`.
103+
-/
104+
def intervalLength (r : Std.Rcc Int) : Nat :=
105+
(r.upper - r.lower).toNat
106+
107+
example : intervalLength (2...=3) = 1 := by decide -- example from the problem description
108+
example : intervalLength (2...=2) = 0 := by decide
109+
example : intervalLength (5...=0) = 0 := by decide
110+
111+
section IntervalIntersection
112+
113+
def intervalIntersection (r s : Std.Rcc Int) : Std.Rcc Int :=
114+
(max r.lower s.lower)...=(min r.upper s.upper)
115+
116+
example : intervalIntersection (1...=3) (2...=4) = (2...=3) := by native_decide
117+
118+
/-! The following three lemmas justify the name `intervalIntersection`. -/
119+
120+
theorem mem_intervalIntersection_iff {l₁ r₁ l₂ r₂ x} :
121+
x ∈ intervalIntersection (l₁...=r₁) (l₂...=r₂) ↔ x ∈ (l₁...=r₁) ∧ x ∈ (l₂...=r₂) := by
122+
grind [intervalIntersection, Std.Rcc.mem_iff]
123+
124+
theorem intervalIntersection_swap {r s} :
125+
intervalIntersection r s = intervalIntersection s r := by
126+
grind [intervalIntersection]
127+
128+
theorem toList_intervalIntersection_eq_filter_mem_rcc_toList_rcc {l₁ r₁ l₂ r₂} :
129+
(intervalIntersection (l₁...=r₁) (l₂...=r₂)).toList = (l₁...=r₁).toList.filter (· ∈ l₂...=r₂) := by
100130
apply eq_of_pairwise_lt_of_mem_iff_mem (lt := LT.lt)
131+
· apply Std.Rcc.pairwise_toList_lt
101132
· apply List.Pairwise.filter
102-
apply Std.Rco.pairwise_toList_lt
103-
· apply Std.Rco.pairwise_toList_lt
104-
· grind [mem_filter_mem_rco_toList_rco, Std.Rco.mem_toList_iff_mem]
133+
apply Std.Rcc.pairwise_toList_lt
134+
· grind [mem_intervalIntersection_iff, Std.Rcc.mem_toList_iff_mem]
135+
136+
end IntervalIntersection
105137

106138
theorem intersection_spec {p q} :
107-
intersection p q = "YES" ↔ IsPrime ((p.1...p.2).toList.filter (· ∈ q.1...q.2)).length := by
139+
intersection p q = "YES" ↔ IsPrime (intervalLength (intervalIntersection (p.1...=p.2) (q.1...=q.2))) := by
108140
simp only [intersection, isPrime_eq_true_iff_isPrime, ite_eq_left_iff]
109-
suffices h : (min p.2 q.2 - max p.1 q.1).toNat = ((p.1...p.2).toList.filter (· ∈ q.1...q.2)).length by
141+
suffices h : (min p.2 q.2 - max p.1 q.1).toNat = intervalLength (intervalIntersection (p.1...=p.2) (q.1...=q.2)) by
110142
grind [isPrime_iff]
111-
simp [Int.filter_mem_rco_toList_rco]
143+
grind [intervalLength, intervalIntersection]
112144

113145
/-!
114146
## Prompt

HumanEvalLean/HumanEval150.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Init.Notation
55
import Std.Tactic.Do
66

77
import HumanEvalLean.Common.IsPrime
8+
meta import HumanEvalLean.Common.IsPrime -- for `native_decide`
89

910
open Std
1011

0 commit comments

Comments
 (0)