1- def intersection : Unit :=
2- ()
1+ module
2+
3+ import HumanEvalLean.Common.IsPrime
4+ meta import HumanEvalLean.Common.IsPrime -- for `native_decide`
5+
6+ /-!
7+ ## Implementation
8+ -/
9+
10+ def intersection (p : Int × Int) (q : Int × Int) : String :=
11+ let l := max p.1 q.1
12+ let r := min p.2 q.2
13+ let length := r - l
14+ if length > 0 ∧ isPrime length.toNat then "YES" else "NO"
15+
16+ /-!
17+ ## Tests
18+ -/
19+
20+ example : intersection (1 , 2 ) (2 , 3 ) = "NO" := by native_decide
21+ example : intersection (-1 , 1 ) (0 , 4 ) = "NO" := by native_decide
22+ example : intersection (-3 , -1 ) (-5 , 5 ) = "YES" := by native_decide
23+ example : intersection (-2 , 2 ) (-4 , 0 ) = "YES" := by native_decide
24+ example : intersection (-11 , 2 ) (-1 , -1 ) = "NO" := by native_decide
25+ example : intersection (1 , 2 ) (3 , 5 ) = "NO" := by native_decide
26+ example : intersection (1 , 2 ) (1 , 2 ) = "NO" := by native_decide
27+ example : intersection (-2 , -2 ) (-3 , -2 ) = "NO" := by native_decide
28+
29+ /-!
30+ ## Missing API
31+ -/
32+
33+ -- stolen from Init.Data.Range.Polymorphic.Lemmas, which is private
34+ private theorem eq_of_pairwise_lt_of_mem_iff_mem {lt : α → α → Prop } [asymm : Std.Asymm lt]
35+ {l l' : List α} (hl : l.Pairwise lt) (hl' : l'.Pairwise lt)
36+ (h : ∀ a, a ∈ l ↔ a ∈ l') : l = l' := by
37+ induction l generalizing l'
38+ · cases l'
39+ · rfl
40+ · rename_i x xs
41+ specialize h x
42+ simp at h
43+ · rename_i x xs ih
44+ cases l'
45+ · specialize h x
46+ simp at h
47+ · have hx := (h x).mp (List.mem_cons_self)
48+ cases List.mem_cons.mp hx
49+ · rename_i y ys heq
50+ cases heq
51+ simp only [List.cons.injEq, true_and]
52+ apply ih hl.tail hl'.tail
53+ intro a
54+ specialize h a
55+ constructor
56+ · intro haxs
57+ replace h := h.mp (List.mem_cons_of_mem _ haxs)
58+ cases List.mem_cons.mp h
59+ · rename_i heq
60+ cases heq
61+ simp only [List.pairwise_cons] at hl
62+ have := hl.1 x haxs
63+ cases Std.Asymm.asymm _ _ this this
64+ · simp [*]
65+ · intro hays
66+ replace h := h.mpr (List.mem_cons_of_mem _ hays)
67+ cases List.mem_cons.mp h
68+ · rename_i heq
69+ cases heq
70+ simp only [List.pairwise_cons] at hl'
71+ have := hl'.1 x hays
72+ cases Std.Asymm.asymm _ _ this this
73+ · simp [*]
74+ · rename_i y ys hx
75+ simp only [List.pairwise_cons] at hl'
76+ have hlt := hl'.1 _ hx
77+ have hmem : y ∈ x :: xs := (h y).mpr List.mem_cons_self
78+ cases List.mem_cons.mp hmem
79+ · rename_i heq
80+ cases heq
81+ cases Std.Asymm.asymm _ _ hlt hlt
82+ · simp only [List.pairwise_cons] at hl
83+ have hgt := hl.1 y ‹_›
84+ cases Std.Asymm.asymm _ _ hlt hgt
85+
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
130+ apply eq_of_pairwise_lt_of_mem_iff_mem (lt := LT.lt)
131+ · apply Std.Rcc.pairwise_toList_lt
132+ · apply List.Pairwise.filter
133+ apply Std.Rcc.pairwise_toList_lt
134+ · grind [mem_intervalIntersection_iff, Std.Rcc.mem_toList_iff_mem]
135+
136+ end IntervalIntersection
137+
138+ theorem intersection_spec {p q} :
139+ intersection p q = "YES" ↔ IsPrime (intervalLength (intervalIntersection (p.1 ...=p.2 ) (q.1 ...=q.2 ))) := by
140+ simp only [intersection, isPrime_eq_true_iff_isPrime, ite_eq_left_iff]
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
142+ grind [isPrime_iff]
143+ grind [intervalLength, intervalIntersection]
3144
4145/-!
5146## Prompt
@@ -12,7 +153,7 @@ def intersection(interval1, interval2):
12153 The given intervals are closed which means that the interval (start, end)
13154 includes both start and end.
14155 For each given interval, it is assumed that its start is less or equal its end.
15- Your task is to determine whether the length of intersection of these two
156+ Your task is to determine whether the length of intersection of these two
16157 intervals is a prime number.
17158 Example, the intersection of the intervals (1, 3), (2, 4) is (2, 3)
18159 which its length is 1, which not a prime number.
@@ -67,4 +208,4 @@ def check(candidate):
67208 assert candidate((-2, -2), (-3, -2)) == "NO"
68209
69210```
70- -/
211+ -/
0 commit comments