11module
22
33import 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
2627example : 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
4534private 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
106138theorem 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
0 commit comments