@@ -12,178 +12,12 @@ set_option mvcgen.warning false
1212## Missing API
1313-/
1414
15- namespace Array
16-
17- def MergeSort.merge (xs ys : Array α) (le : α → α → Bool := by exact (· ≤ ·)) : Array α :=
18- if hxs : 0 < xs.size then
19- if hys : 0 < ys.size then
20- go xs[*...*] ys[*...*] (by simp only [Array.size_mkSlice_rii]; omega) (by simp only [Array.size_mkSlice_rii]; omega) (Array.emptyWithCapacity (xs.size + ys.size))
21- else
22- xs
23- else
24- ys
25- where
26- go (xs ys : Subarray α) (hxs : 0 < xs.size) (hys : 0 < ys.size) (acc : Array α) : Array α :=
27- let x := xs[0 ]
28- let y := ys[0 ]
29- if le x y then
30- if hi : 1 < xs.size then
31- go (xs.drop 1 ) ys (by simp only [Subarray.size_drop]; omega) hys (acc.push x)
32- else
33- ys.foldl (init := acc.push x) (fun acc y => acc.push y)
34- else
35- if hj : 1 < ys.size then
36- go xs (ys.drop 1 ) hxs (by simp only [Subarray.size_drop]; omega) (acc.push y)
37- else
38- xs.foldl (init := acc.push y) (fun acc x => acc.push x)
39- termination_by xs.size + ys.size
40-
41- def _root_.Subarray.mergeSort (xs : Subarray α) (le : α → α → Bool := by exact (· ≤ ·)) : Array α :=
42- if h : 1 < xs.size then
43- let splitIdx := (xs.size + 1 ) / 2 -- We follow the same splitting convention as `List.mergeSort`
44- let left := xs[*...splitIdx]
45- let right := xs[splitIdx...*]
46- MergeSort.merge (mergeSort left le) (mergeSort right le) le
47- else
48- xs
49- termination_by xs.size
50- decreasing_by
51- · simp only [Subarray.size_mkSlice_rio]; omega
52- · simp only [Subarray.size_mkSlice_rci]; omega
53-
54- def mergeSort (xs : Array α) (le : α → α → Bool := by exact (· ≤ ·)) : Array α :=
55- xs[*...*].mergeSort le
56-
57- end Array
58-
59- theorem Array.MergeSort.merge.go_eq_listMerge {xs ys : Subarray α} {hxs hys le acc} :
60- (Array.MergeSort.merge.go le xs ys hxs hys acc).toList = acc.toList ++ List.merge xs.toList ys.toList le := by
61- fun_induction Array.MergeSort.merge.go le xs ys hxs hys acc
62- · rename_i xs ys _ _ _ _ _ _ _ _
63- rw [List.merge.eq_def]
64- split
65- · have : xs.size = 0 := by simp [← Subarray.length_toList, *]
66- omega
67- · have : ys.size = 0 := by simp [← Subarray.length_toList, *]
68- omega
69- · rename_i x' xs' y' ys' _ _
70- simp +zetaDelta only at *
71- have h₁ : x' = xs[0 ] := by simp [Subarray.getElem_eq_getElem_toList, *]
72- have h₂ : y' = ys[0 ] := by simp [Subarray.getElem_eq_getElem_toList, *]
73- cases h₁
74- cases h₂
75- simp [Subarray.toList_drop, *]
76- · rename_i xs ys _ _ _ _ _ _ _
77- rw [List.merge.eq_def]
78- split
79- · have : xs.size = 0 := by simp [← Subarray.length_toList, *]
80- omega
81- · have : ys.size = 0 := by simp [← Subarray.length_toList, *]
82- omega
83- · rename_i x' xs' y' ys' _ _
84- simp +zetaDelta only at *
85- have h₁ : x' = xs[0 ] := by simp [Subarray.getElem_eq_getElem_toList, *]
86- have h₂ : y' = ys[0 ] := by simp [Subarray.getElem_eq_getElem_toList, *]
87- cases h₁
88- cases h₂
89- simp [*]
90- have : xs.size = xs'.length + 1 := by simp [← Subarray.length_toList, *]
91- have : xs' = [] := List.eq_nil_of_length_eq_zero (by omega)
92- simp [this ]
93- rw [← Subarray.foldl_toList]
94- simp [*]
95- · rename_i xs ys _ _ _ _ _ _ _ _
96- rw [List.merge.eq_def]
97- split
98- · have : xs.size = 0 := by simp [← Subarray.length_toList, *]
99- omega
100- · have : ys.size = 0 := by simp [← Subarray.length_toList, *]
101- omega
102- · rename_i x' xs' y' ys' _ _
103- simp +zetaDelta only at *
104- have h₁ : x' = xs[0 ] := by simp [Subarray.getElem_eq_getElem_toList, *]
105- have h₂ : y' = ys[0 ] := by simp [Subarray.getElem_eq_getElem_toList, *]
106- cases h₁
107- cases h₂
108- simp [Subarray.toList_drop, *]
109- · rename_i xs ys _ _ _ _ _ _ _
110- rw [List.merge.eq_def]
111- split
112- · have : xs.size = 0 := by simp [← Subarray.length_toList, *]
113- omega
114- · have : ys.size = 0 := by simp [← Subarray.length_toList, *]
115- omega
116- · rename_i x' xs' y' ys' _ _
117- simp +zetaDelta only at *
118- have h₁ : x' = xs[0 ] := by simp [Subarray.getElem_eq_getElem_toList, *]
119- have h₂ : y' = ys[0 ] := by simp [Subarray.getElem_eq_getElem_toList, *]
120- cases h₁
121- cases h₂
122- simp [*]
123- have : ys.size = ys'.length + 1 := by simp [← Subarray.length_toList, *]
124- have : ys' = [] := List.eq_nil_of_length_eq_zero (by omega)
125- simp [this ]
126- rw [← Subarray.foldl_toList]
127- simp [*]
128-
129- theorem Array.MergeSort.merge_eq_listMerge {xs ys : Array α} {le} :
130- (Array.MergeSort.merge xs ys le).toList = List.merge xs.toList ys.toList le := by
131- rw [Array.MergeSort.merge]
132- split <;> rename_i heq₁
133- · split <;> rename_i heq₂
134- · simp [Array.MergeSort.merge.go_eq_listMerge]
135- · have : ys.toList = [] := by simp_all
136- simp [this ]
137- · have : xs.toList = [] := by simp_all
138- simp [this ]
139-
140- theorem List.mergeSort_eq_merge_mkSlice {xs : List α} :
141- xs.mergeSort le =
142- if 1 < xs.length then
143- merge (xs[*...((xs.length + 1 ) / 2 )].toList.mergeSort le) (xs[((xs.length + 1 ) / 2 )...*].toList.mergeSort le) le
144- else
145- xs := by
146- fun_cases xs.mergeSort le
147- · simp
148- · simp
149- · rename_i x y ys lr hl hr
150- simp [lr]
151-
152- theorem Subarray.toList_mergeSort {xs : Subarray α} {le : α → α → Bool} :
153- (xs.mergeSort le).toList = xs.toList.mergeSort le := by
154- fun_induction xs.mergeSort le
155- · rw [List.mergeSort_eq_merge_mkSlice]
156- simp +zetaDelta [Array.MergeSort.merge_eq_listMerge, *]
157- · simp [List.mergeSort_eq_merge_mkSlice, *]
158-
159- theorem Array.toList_mergeSort {xs : Array α} {le : α → α → Bool} :
160- (xs.mergeSort le).toList = xs.toList.mergeSort le := by
161- rw [Array.mergeSort, Subarray.toList_mergeSort, Array.toList_mkSlice_rii]
162-
16315theorem Nat.eq_add_of_toList_rio_eq_append_cons {a : Nat} {pref cur suff}
16416 (h : (*...a).toList = pref ++ cur :: suff) :
16517 cur = pref.length := by
16618 have := Rio.eq_succMany?_of_toList_eq_append_cons h
16719 simpa [PRange.UpwardEnumerable.least, PRange.least?] using this
16820
169- @[simp, grind =]
170- theorem Array.size_mergeSort {xs : Array α} :
171- (xs.mergeSort le).size = xs.size := by
172- rw [← length_toList, Array.toList_mergeSort, List.length_mergeSort, length_toList]
173-
174- theorem Array.mergeSort_perm {xs : Array α} :
175- (xs.mergeSort le).Perm xs := by
176- simpa only [perm_iff_toList_perm, Array.toList_mergeSort] using List.mergeSort_perm _ _
177-
178- theorem Array.pairwise_mergeSort
179- (trans : ∀ (a b c : α), le a b → le b c → le a c)
180- (total : ∀ (a b : α), le a b || le b a) :
181- (l : Array α) → (mergeSort l le).toList.Pairwise (le · ·) := by
182- intro xs
183- simpa [toList_mergeSort] using List.pairwise_mergeSort trans total _
184-
185- attribute [simp, grind =] Rio.mem_iff
186-
18721/-!
18822## Implementation
18923-/
0 commit comments