52 by (relation "measure (\<lambda>(_,l,r,_). r - l )") auto |
52 by (relation "measure (\<lambda>(_,l,r,_). r - l )") auto |
53 |
53 |
54 declare part1.simps[simp del] |
54 declare part1.simps[simp del] |
55 |
55 |
56 lemma part_permutes: |
56 lemma part_permutes: |
57 assumes "crel (part1 a l r p) h h' rs" |
57 assumes "effect (part1 a l r p) h h' rs" |
58 shows "multiset_of (Array.get h' a) |
58 shows "multiset_of (Array.get h' a) |
59 = multiset_of (Array.get h a)" |
59 = multiset_of (Array.get h a)" |
60 using assms |
60 using assms |
61 proof (induct a l r p arbitrary: h h' rs rule:part1.induct) |
61 proof (induct a l r p arbitrary: h h' rs rule:part1.induct) |
62 case (1 a l r p h h' rs) |
62 case (1 a l r p h h' rs) |
63 thus ?case |
63 thus ?case |
64 unfolding part1.simps [of a l r p] |
64 unfolding part1.simps [of a l r p] |
65 by (elim crel_bindE crel_ifE crel_returnE crel_nthE) (auto simp add: swap_permutes) |
65 by (elim effect_bindE effect_ifE effect_returnE effect_nthE) (auto simp add: swap_permutes) |
66 qed |
66 qed |
67 |
67 |
68 lemma part_returns_index_in_bounds: |
68 lemma part_returns_index_in_bounds: |
69 assumes "crel (part1 a l r p) h h' rs" |
69 assumes "effect (part1 a l r p) h h' rs" |
70 assumes "l \<le> r" |
70 assumes "l \<le> r" |
71 shows "l \<le> rs \<and> rs \<le> r" |
71 shows "l \<le> rs \<and> rs \<le> r" |
72 using assms |
72 using assms |
73 proof (induct a l r p arbitrary: h h' rs rule:part1.induct) |
73 proof (induct a l r p arbitrary: h h' rs rule:part1.induct) |
74 case (1 a l r p h h' rs) |
74 case (1 a l r p h h' rs) |
75 note cr = `crel (part1 a l r p) h h' rs` |
75 note cr = `effect (part1 a l r p) h h' rs` |
76 show ?case |
76 show ?case |
77 proof (cases "r \<le> l") |
77 proof (cases "r \<le> l") |
78 case True (* Terminating case *) |
78 case True (* Terminating case *) |
79 with cr `l \<le> r` show ?thesis |
79 with cr `l \<le> r` show ?thesis |
80 unfolding part1.simps[of a l r p] |
80 unfolding part1.simps[of a l r p] |
81 by (elim crel_bindE crel_ifE crel_returnE crel_nthE) auto |
81 by (elim effect_bindE effect_ifE effect_returnE effect_nthE) auto |
82 next |
82 next |
83 case False (* recursive case *) |
83 case False (* recursive case *) |
84 note rec_condition = this |
84 note rec_condition = this |
85 let ?v = "Array.get h a ! l" |
85 let ?v = "Array.get h a ! l" |
86 show ?thesis |
86 show ?thesis |
87 proof (cases "?v \<le> p") |
87 proof (cases "?v \<le> p") |
88 case True |
88 case True |
89 with cr False |
89 with cr False |
90 have rec1: "crel (part1 a (l + 1) r p) h h' rs" |
90 have rec1: "effect (part1 a (l + 1) r p) h h' rs" |
91 unfolding part1.simps[of a l r p] |
91 unfolding part1.simps[of a l r p] |
92 by (elim crel_bindE crel_nthE crel_ifE crel_returnE) auto |
92 by (elim effect_bindE effect_nthE effect_ifE effect_returnE) auto |
93 from rec_condition have "l + 1 \<le> r" by arith |
93 from rec_condition have "l + 1 \<le> r" by arith |
94 from 1(1)[OF rec_condition True rec1 `l + 1 \<le> r`] |
94 from 1(1)[OF rec_condition True rec1 `l + 1 \<le> r`] |
95 show ?thesis by simp |
95 show ?thesis by simp |
96 next |
96 next |
97 case False |
97 case False |
98 with rec_condition cr |
98 with rec_condition cr |
99 obtain h1 where swp: "crel (swap a l r) h h1 ()" |
99 obtain h1 where swp: "effect (swap a l r) h h1 ()" |
100 and rec2: "crel (part1 a l (r - 1) p) h1 h' rs" |
100 and rec2: "effect (part1 a l (r - 1) p) h1 h' rs" |
101 unfolding part1.simps[of a l r p] |
101 unfolding part1.simps[of a l r p] |
102 by (elim crel_bindE crel_nthE crel_ifE crel_returnE) auto |
102 by (elim effect_bindE effect_nthE effect_ifE effect_returnE) auto |
103 from rec_condition have "l \<le> r - 1" by arith |
103 from rec_condition have "l \<le> r - 1" by arith |
104 from 1(2) [OF rec_condition False rec2 `l \<le> r - 1`] show ?thesis by fastsimp |
104 from 1(2) [OF rec_condition False rec2 `l \<le> r - 1`] show ?thesis by fastsimp |
105 qed |
105 qed |
106 qed |
106 qed |
107 qed |
107 qed |
108 |
108 |
109 lemma part_length_remains: |
109 lemma part_length_remains: |
110 assumes "crel (part1 a l r p) h h' rs" |
110 assumes "effect (part1 a l r p) h h' rs" |
111 shows "Array.length h a = Array.length h' a" |
111 shows "Array.length h a = Array.length h' a" |
112 using assms |
112 using assms |
113 proof (induct a l r p arbitrary: h h' rs rule:part1.induct) |
113 proof (induct a l r p arbitrary: h h' rs rule:part1.induct) |
114 case (1 a l r p h h' rs) |
114 case (1 a l r p h h' rs) |
115 note cr = `crel (part1 a l r p) h h' rs` |
115 note cr = `effect (part1 a l r p) h h' rs` |
116 |
116 |
117 show ?case |
117 show ?case |
118 proof (cases "r \<le> l") |
118 proof (cases "r \<le> l") |
119 case True (* Terminating case *) |
119 case True (* Terminating case *) |
120 with cr show ?thesis |
120 with cr show ?thesis |
121 unfolding part1.simps[of a l r p] |
121 unfolding part1.simps[of a l r p] |
122 by (elim crel_bindE crel_ifE crel_returnE crel_nthE) auto |
122 by (elim effect_bindE effect_ifE effect_returnE effect_nthE) auto |
123 next |
123 next |
124 case False (* recursive case *) |
124 case False (* recursive case *) |
125 with cr 1 show ?thesis |
125 with cr 1 show ?thesis |
126 unfolding part1.simps [of a l r p] swap_def |
126 unfolding part1.simps [of a l r p] swap_def |
127 by (auto elim!: crel_bindE crel_ifE crel_nthE crel_returnE crel_updE) fastsimp |
127 by (auto elim!: effect_bindE effect_ifE effect_nthE effect_returnE effect_updE) fastsimp |
128 qed |
128 qed |
129 qed |
129 qed |
130 |
130 |
131 lemma part_outer_remains: |
131 lemma part_outer_remains: |
132 assumes "crel (part1 a l r p) h h' rs" |
132 assumes "effect (part1 a l r p) h h' rs" |
133 shows "\<forall>i. i < l \<or> r < i \<longrightarrow> Array.get h (a::nat array) ! i = Array.get h' a ! i" |
133 shows "\<forall>i. i < l \<or> r < i \<longrightarrow> Array.get h (a::nat array) ! i = Array.get h' a ! i" |
134 using assms |
134 using assms |
135 proof (induct a l r p arbitrary: h h' rs rule:part1.induct) |
135 proof (induct a l r p arbitrary: h h' rs rule:part1.induct) |
136 case (1 a l r p h h' rs) |
136 case (1 a l r p h h' rs) |
137 note cr = `crel (part1 a l r p) h h' rs` |
137 note cr = `effect (part1 a l r p) h h' rs` |
138 |
138 |
139 show ?case |
139 show ?case |
140 proof (cases "r \<le> l") |
140 proof (cases "r \<le> l") |
141 case True (* Terminating case *) |
141 case True (* Terminating case *) |
142 with cr show ?thesis |
142 with cr show ?thesis |
143 unfolding part1.simps[of a l r p] |
143 unfolding part1.simps[of a l r p] |
144 by (elim crel_bindE crel_ifE crel_returnE crel_nthE) auto |
144 by (elim effect_bindE effect_ifE effect_returnE effect_nthE) auto |
145 next |
145 next |
146 case False (* recursive case *) |
146 case False (* recursive case *) |
147 note rec_condition = this |
147 note rec_condition = this |
148 let ?v = "Array.get h a ! l" |
148 let ?v = "Array.get h a ! l" |
149 show ?thesis |
149 show ?thesis |
150 proof (cases "?v \<le> p") |
150 proof (cases "?v \<le> p") |
151 case True |
151 case True |
152 with cr False |
152 with cr False |
153 have rec1: "crel (part1 a (l + 1) r p) h h' rs" |
153 have rec1: "effect (part1 a (l + 1) r p) h h' rs" |
154 unfolding part1.simps[of a l r p] |
154 unfolding part1.simps[of a l r p] |
155 by (elim crel_bindE crel_nthE crel_ifE crel_returnE) auto |
155 by (elim effect_bindE effect_nthE effect_ifE effect_returnE) auto |
156 from 1(1)[OF rec_condition True rec1] |
156 from 1(1)[OF rec_condition True rec1] |
157 show ?thesis by fastsimp |
157 show ?thesis by fastsimp |
158 next |
158 next |
159 case False |
159 case False |
160 with rec_condition cr |
160 with rec_condition cr |
161 obtain h1 where swp: "crel (swap a l r) h h1 ()" |
161 obtain h1 where swp: "effect (swap a l r) h h1 ()" |
162 and rec2: "crel (part1 a l (r - 1) p) h1 h' rs" |
162 and rec2: "effect (part1 a l (r - 1) p) h1 h' rs" |
163 unfolding part1.simps[of a l r p] |
163 unfolding part1.simps[of a l r p] |
164 by (elim crel_bindE crel_nthE crel_ifE crel_returnE) auto |
164 by (elim effect_bindE effect_nthE effect_ifE effect_returnE) auto |
165 from swp rec_condition have |
165 from swp rec_condition have |
166 "\<forall>i. i < l \<or> r < i \<longrightarrow> Array.get h a ! i = Array.get h1 a ! i" |
166 "\<forall>i. i < l \<or> r < i \<longrightarrow> Array.get h a ! i = Array.get h1 a ! i" |
167 unfolding swap_def |
167 unfolding swap_def |
168 by (elim crel_bindE crel_nthE crel_updE crel_returnE) auto |
168 by (elim effect_bindE effect_nthE effect_updE effect_returnE) auto |
169 with 1(2) [OF rec_condition False rec2] show ?thesis by fastsimp |
169 with 1(2) [OF rec_condition False rec2] show ?thesis by fastsimp |
170 qed |
170 qed |
171 qed |
171 qed |
172 qed |
172 qed |
173 |
173 |
174 |
174 |
175 lemma part_partitions: |
175 lemma part_partitions: |
176 assumes "crel (part1 a l r p) h h' rs" |
176 assumes "effect (part1 a l r p) h h' rs" |
177 shows "(\<forall>i. l \<le> i \<and> i < rs \<longrightarrow> Array.get h' (a::nat array) ! i \<le> p) |
177 shows "(\<forall>i. l \<le> i \<and> i < rs \<longrightarrow> Array.get h' (a::nat array) ! i \<le> p) |
178 \<and> (\<forall>i. rs < i \<and> i \<le> r \<longrightarrow> Array.get h' a ! i \<ge> p)" |
178 \<and> (\<forall>i. rs < i \<and> i \<le> r \<longrightarrow> Array.get h' a ! i \<ge> p)" |
179 using assms |
179 using assms |
180 proof (induct a l r p arbitrary: h h' rs rule:part1.induct) |
180 proof (induct a l r p arbitrary: h h' rs rule:part1.induct) |
181 case (1 a l r p h h' rs) |
181 case (1 a l r p h h' rs) |
182 note cr = `crel (part1 a l r p) h h' rs` |
182 note cr = `effect (part1 a l r p) h h' rs` |
183 |
183 |
184 show ?case |
184 show ?case |
185 proof (cases "r \<le> l") |
185 proof (cases "r \<le> l") |
186 case True (* Terminating case *) |
186 case True (* Terminating case *) |
187 with cr have "rs = r" |
187 with cr have "rs = r" |
188 unfolding part1.simps[of a l r p] |
188 unfolding part1.simps[of a l r p] |
189 by (elim crel_bindE crel_ifE crel_returnE crel_nthE) auto |
189 by (elim effect_bindE effect_ifE effect_returnE effect_nthE) auto |
190 with True |
190 with True |
191 show ?thesis by auto |
191 show ?thesis by auto |
192 next |
192 next |
193 case False (* recursive case *) |
193 case False (* recursive case *) |
194 note lr = this |
194 note lr = this |
195 let ?v = "Array.get h a ! l" |
195 let ?v = "Array.get h a ! l" |
196 show ?thesis |
196 show ?thesis |
197 proof (cases "?v \<le> p") |
197 proof (cases "?v \<le> p") |
198 case True |
198 case True |
199 with lr cr |
199 with lr cr |
200 have rec1: "crel (part1 a (l + 1) r p) h h' rs" |
200 have rec1: "effect (part1 a (l + 1) r p) h h' rs" |
201 unfolding part1.simps[of a l r p] |
201 unfolding part1.simps[of a l r p] |
202 by (elim crel_bindE crel_nthE crel_ifE crel_returnE) auto |
202 by (elim effect_bindE effect_nthE effect_ifE effect_returnE) auto |
203 from True part_outer_remains[OF rec1] have a_l: "Array.get h' a ! l \<le> p" |
203 from True part_outer_remains[OF rec1] have a_l: "Array.get h' a ! l \<le> p" |
204 by fastsimp |
204 by fastsimp |
205 have "\<forall>i. (l \<le> i = (l = i \<or> Suc l \<le> i))" by arith |
205 have "\<forall>i. (l \<le> i = (l = i \<or> Suc l \<le> i))" by arith |
206 with 1(1)[OF False True rec1] a_l show ?thesis |
206 with 1(1)[OF False True rec1] a_l show ?thesis |
207 by auto |
207 by auto |
208 next |
208 next |
209 case False |
209 case False |
210 with lr cr |
210 with lr cr |
211 obtain h1 where swp: "crel (swap a l r) h h1 ()" |
211 obtain h1 where swp: "effect (swap a l r) h h1 ()" |
212 and rec2: "crel (part1 a l (r - 1) p) h1 h' rs" |
212 and rec2: "effect (part1 a l (r - 1) p) h1 h' rs" |
213 unfolding part1.simps[of a l r p] |
213 unfolding part1.simps[of a l r p] |
214 by (elim crel_bindE crel_nthE crel_ifE crel_returnE) auto |
214 by (elim effect_bindE effect_nthE effect_ifE effect_returnE) auto |
215 from swp False have "Array.get h1 a ! r \<ge> p" |
215 from swp False have "Array.get h1 a ! r \<ge> p" |
216 unfolding swap_def |
216 unfolding swap_def |
217 by (auto simp add: Array.length_def elim!: crel_bindE crel_nthE crel_updE crel_returnE) |
217 by (auto simp add: Array.length_def elim!: effect_bindE effect_nthE effect_updE effect_returnE) |
218 with part_outer_remains [OF rec2] lr have a_r: "Array.get h' a ! r \<ge> p" |
218 with part_outer_remains [OF rec2] lr have a_r: "Array.get h' a ! r \<ge> p" |
219 by fastsimp |
219 by fastsimp |
220 have "\<forall>i. (i \<le> r = (i = r \<or> i \<le> r - 1))" by arith |
220 have "\<forall>i. (i \<le> r = (i = r \<or> i \<le> r - 1))" by arith |
221 with 1(2)[OF lr False rec2] a_r show ?thesis |
221 with 1(2)[OF lr False rec2] a_r show ?thesis |
222 by auto |
222 by auto |
237 }" |
237 }" |
238 |
238 |
239 declare partition.simps[simp del] |
239 declare partition.simps[simp del] |
240 |
240 |
241 lemma partition_permutes: |
241 lemma partition_permutes: |
242 assumes "crel (partition a l r) h h' rs" |
242 assumes "effect (partition a l r) h h' rs" |
243 shows "multiset_of (Array.get h' a) |
243 shows "multiset_of (Array.get h' a) |
244 = multiset_of (Array.get h a)" |
244 = multiset_of (Array.get h a)" |
245 proof - |
245 proof - |
246 from assms part_permutes swap_permutes show ?thesis |
246 from assms part_permutes swap_permutes show ?thesis |
247 unfolding partition.simps |
247 unfolding partition.simps |
248 by (elim crel_bindE crel_returnE crel_nthE crel_ifE crel_updE) auto |
248 by (elim effect_bindE effect_returnE effect_nthE effect_ifE effect_updE) auto |
249 qed |
249 qed |
250 |
250 |
251 lemma partition_length_remains: |
251 lemma partition_length_remains: |
252 assumes "crel (partition a l r) h h' rs" |
252 assumes "effect (partition a l r) h h' rs" |
253 shows "Array.length h a = Array.length h' a" |
253 shows "Array.length h a = Array.length h' a" |
254 proof - |
254 proof - |
255 from assms part_length_remains show ?thesis |
255 from assms part_length_remains show ?thesis |
256 unfolding partition.simps swap_def |
256 unfolding partition.simps swap_def |
257 by (elim crel_bindE crel_returnE crel_nthE crel_ifE crel_updE) auto |
257 by (elim effect_bindE effect_returnE effect_nthE effect_ifE effect_updE) auto |
258 qed |
258 qed |
259 |
259 |
260 lemma partition_outer_remains: |
260 lemma partition_outer_remains: |
261 assumes "crel (partition a l r) h h' rs" |
261 assumes "effect (partition a l r) h h' rs" |
262 assumes "l < r" |
262 assumes "l < r" |
263 shows "\<forall>i. i < l \<or> r < i \<longrightarrow> Array.get h (a::nat array) ! i = Array.get h' a ! i" |
263 shows "\<forall>i. i < l \<or> r < i \<longrightarrow> Array.get h (a::nat array) ! i = Array.get h' a ! i" |
264 proof - |
264 proof - |
265 from assms part_outer_remains part_returns_index_in_bounds show ?thesis |
265 from assms part_outer_remains part_returns_index_in_bounds show ?thesis |
266 unfolding partition.simps swap_def |
266 unfolding partition.simps swap_def |
267 by (elim crel_bindE crel_returnE crel_nthE crel_ifE crel_updE) fastsimp |
267 by (elim effect_bindE effect_returnE effect_nthE effect_ifE effect_updE) fastsimp |
268 qed |
268 qed |
269 |
269 |
270 lemma partition_returns_index_in_bounds: |
270 lemma partition_returns_index_in_bounds: |
271 assumes crel: "crel (partition a l r) h h' rs" |
271 assumes effect: "effect (partition a l r) h h' rs" |
272 assumes "l < r" |
272 assumes "l < r" |
273 shows "l \<le> rs \<and> rs \<le> r" |
273 shows "l \<le> rs \<and> rs \<le> r" |
274 proof - |
274 proof - |
275 from crel obtain middle h'' p where part: "crel (part1 a l (r - 1) p) h h'' middle" |
275 from effect obtain middle h'' p where part: "effect (part1 a l (r - 1) p) h h'' middle" |
276 and rs_equals: "rs = (if Array.get h'' a ! middle \<le> Array.get h a ! r then middle + 1 |
276 and rs_equals: "rs = (if Array.get h'' a ! middle \<le> Array.get h a ! r then middle + 1 |
277 else middle)" |
277 else middle)" |
278 unfolding partition.simps |
278 unfolding partition.simps |
279 by (elim crel_bindE crel_returnE crel_nthE crel_ifE crel_updE) simp |
279 by (elim effect_bindE effect_returnE effect_nthE effect_ifE effect_updE) simp |
280 from `l < r` have "l \<le> r - 1" by arith |
280 from `l < r` have "l \<le> r - 1" by arith |
281 from part_returns_index_in_bounds[OF part this] rs_equals `l < r` show ?thesis by auto |
281 from part_returns_index_in_bounds[OF part this] rs_equals `l < r` show ?thesis by auto |
282 qed |
282 qed |
283 |
283 |
284 lemma partition_partitions: |
284 lemma partition_partitions: |
285 assumes crel: "crel (partition a l r) h h' rs" |
285 assumes effect: "effect (partition a l r) h h' rs" |
286 assumes "l < r" |
286 assumes "l < r" |
287 shows "(\<forall>i. l \<le> i \<and> i < rs \<longrightarrow> Array.get h' (a::nat array) ! i \<le> Array.get h' a ! rs) \<and> |
287 shows "(\<forall>i. l \<le> i \<and> i < rs \<longrightarrow> Array.get h' (a::nat array) ! i \<le> Array.get h' a ! rs) \<and> |
288 (\<forall>i. rs < i \<and> i \<le> r \<longrightarrow> Array.get h' a ! rs \<le> Array.get h' a ! i)" |
288 (\<forall>i. rs < i \<and> i \<le> r \<longrightarrow> Array.get h' a ! rs \<le> Array.get h' a ! i)" |
289 proof - |
289 proof - |
290 let ?pivot = "Array.get h a ! r" |
290 let ?pivot = "Array.get h a ! r" |
291 from crel obtain middle h1 where part: "crel (part1 a l (r - 1) ?pivot) h h1 middle" |
291 from effect obtain middle h1 where part: "effect (part1 a l (r - 1) ?pivot) h h1 middle" |
292 and swap: "crel (swap a rs r) h1 h' ()" |
292 and swap: "effect (swap a rs r) h1 h' ()" |
293 and rs_equals: "rs = (if Array.get h1 a ! middle \<le> ?pivot then middle + 1 |
293 and rs_equals: "rs = (if Array.get h1 a ! middle \<le> ?pivot then middle + 1 |
294 else middle)" |
294 else middle)" |
295 unfolding partition.simps |
295 unfolding partition.simps |
296 by (elim crel_bindE crel_returnE crel_nthE crel_ifE crel_updE) simp |
296 by (elim effect_bindE effect_returnE effect_nthE effect_ifE effect_updE) simp |
297 from swap have h'_def: "h' = Array.update a r (Array.get h1 a ! rs) |
297 from swap have h'_def: "h' = Array.update a r (Array.get h1 a ! rs) |
298 (Array.update a rs (Array.get h1 a ! r) h1)" |
298 (Array.update a rs (Array.get h1 a ! r) h1)" |
299 unfolding swap_def |
299 unfolding swap_def |
300 by (elim crel_bindE crel_returnE crel_nthE crel_updE) simp |
300 by (elim effect_bindE effect_returnE effect_nthE effect_updE) simp |
301 from swap have in_bounds: "r < Array.length h1 a \<and> rs < Array.length h1 a" |
301 from swap have in_bounds: "r < Array.length h1 a \<and> rs < Array.length h1 a" |
302 unfolding swap_def |
302 unfolding swap_def |
303 by (elim crel_bindE crel_returnE crel_nthE crel_updE) simp |
303 by (elim effect_bindE effect_returnE effect_nthE effect_updE) simp |
304 from swap have swap_length_remains: "Array.length h1 a = Array.length h' a" |
304 from swap have swap_length_remains: "Array.length h1 a = Array.length h' a" |
305 unfolding swap_def by (elim crel_bindE crel_returnE crel_nthE crel_updE) auto |
305 unfolding swap_def by (elim effect_bindE effect_returnE effect_nthE effect_updE) auto |
306 from `l < r` have "l \<le> r - 1" by simp |
306 from `l < r` have "l \<le> r - 1" by simp |
307 note middle_in_bounds = part_returns_index_in_bounds[OF part this] |
307 note middle_in_bounds = part_returns_index_in_bounds[OF part this] |
308 from part_outer_remains[OF part] `l < r` |
308 from part_outer_remains[OF part] `l < r` |
309 have "Array.get h a ! r = Array.get h1 a ! r" |
309 have "Array.get h a ! r = Array.get h1 a ! r" |
310 by fastsimp |
310 by fastsimp |
311 with swap |
311 with swap |
312 have right_remains: "Array.get h a ! r = Array.get h' a ! rs" |
312 have right_remains: "Array.get h a ! r = Array.get h' a ! rs" |
313 unfolding swap_def |
313 unfolding swap_def |
314 by (auto simp add: Array.length_def elim!: crel_bindE crel_returnE crel_nthE crel_updE) (cases "r = rs", auto) |
314 by (auto simp add: Array.length_def elim!: effect_bindE effect_returnE effect_nthE effect_updE) (cases "r = rs", auto) |
315 from part_partitions [OF part] |
315 from part_partitions [OF part] |
316 show ?thesis |
316 show ?thesis |
317 proof (cases "Array.get h1 a ! middle \<le> ?pivot") |
317 proof (cases "Array.get h1 a ! middle \<le> ?pivot") |
318 case True |
318 case True |
319 with rs_equals have rs_equals: "rs = middle + 1" by simp |
319 with rs_equals have rs_equals: "rs = middle + 1" by simp |
417 |
417 |
418 declare quicksort.simps[simp del] |
418 declare quicksort.simps[simp del] |
419 |
419 |
420 |
420 |
421 lemma quicksort_permutes: |
421 lemma quicksort_permutes: |
422 assumes "crel (quicksort a l r) h h' rs" |
422 assumes "effect (quicksort a l r) h h' rs" |
423 shows "multiset_of (Array.get h' a) |
423 shows "multiset_of (Array.get h' a) |
424 = multiset_of (Array.get h a)" |
424 = multiset_of (Array.get h a)" |
425 using assms |
425 using assms |
426 proof (induct a l r arbitrary: h h' rs rule: quicksort.induct) |
426 proof (induct a l r arbitrary: h h' rs rule: quicksort.induct) |
427 case (1 a l r h h' rs) |
427 case (1 a l r h h' rs) |
428 with partition_permutes show ?case |
428 with partition_permutes show ?case |
429 unfolding quicksort.simps [of a l r] |
429 unfolding quicksort.simps [of a l r] |
430 by (elim crel_ifE crel_bindE crel_assertE crel_returnE) auto |
430 by (elim effect_ifE effect_bindE effect_assertE effect_returnE) auto |
431 qed |
431 qed |
432 |
432 |
433 lemma length_remains: |
433 lemma length_remains: |
434 assumes "crel (quicksort a l r) h h' rs" |
434 assumes "effect (quicksort a l r) h h' rs" |
435 shows "Array.length h a = Array.length h' a" |
435 shows "Array.length h a = Array.length h' a" |
436 using assms |
436 using assms |
437 proof (induct a l r arbitrary: h h' rs rule: quicksort.induct) |
437 proof (induct a l r arbitrary: h h' rs rule: quicksort.induct) |
438 case (1 a l r h h' rs) |
438 case (1 a l r h h' rs) |
439 with partition_length_remains show ?case |
439 with partition_length_remains show ?case |
440 unfolding quicksort.simps [of a l r] |
440 unfolding quicksort.simps [of a l r] |
441 by (elim crel_ifE crel_bindE crel_assertE crel_returnE) auto |
441 by (elim effect_ifE effect_bindE effect_assertE effect_returnE) auto |
442 qed |
442 qed |
443 |
443 |
444 lemma quicksort_outer_remains: |
444 lemma quicksort_outer_remains: |
445 assumes "crel (quicksort a l r) h h' rs" |
445 assumes "effect (quicksort a l r) h h' rs" |
446 shows "\<forall>i. i < l \<or> r < i \<longrightarrow> Array.get h (a::nat array) ! i = Array.get h' a ! i" |
446 shows "\<forall>i. i < l \<or> r < i \<longrightarrow> Array.get h (a::nat array) ! i = Array.get h' a ! i" |
447 using assms |
447 using assms |
448 proof (induct a l r arbitrary: h h' rs rule: quicksort.induct) |
448 proof (induct a l r arbitrary: h h' rs rule: quicksort.induct) |
449 case (1 a l r h h' rs) |
449 case (1 a l r h h' rs) |
450 note cr = `crel (quicksort a l r) h h' rs` |
450 note cr = `effect (quicksort a l r) h h' rs` |
451 thus ?case |
451 thus ?case |
452 proof (cases "r > l") |
452 proof (cases "r > l") |
453 case False |
453 case False |
454 with cr have "h' = h" |
454 with cr have "h' = h" |
455 unfolding quicksort.simps [of a l r] |
455 unfolding quicksort.simps [of a l r] |
456 by (elim crel_ifE crel_returnE) auto |
456 by (elim effect_ifE effect_returnE) auto |
457 thus ?thesis by simp |
457 thus ?thesis by simp |
458 next |
458 next |
459 case True |
459 case True |
460 { |
460 { |
461 fix h1 h2 p ret1 ret2 i |
461 fix h1 h2 p ret1 ret2 i |
462 assume part: "crel (partition a l r) h h1 p" |
462 assume part: "effect (partition a l r) h h1 p" |
463 assume qs1: "crel (quicksort a l (p - 1)) h1 h2 ret1" |
463 assume qs1: "effect (quicksort a l (p - 1)) h1 h2 ret1" |
464 assume qs2: "crel (quicksort a (p + 1) r) h2 h' ret2" |
464 assume qs2: "effect (quicksort a (p + 1) r) h2 h' ret2" |
465 assume pivot: "l \<le> p \<and> p \<le> r" |
465 assume pivot: "l \<le> p \<and> p \<le> r" |
466 assume i_outer: "i < l \<or> r < i" |
466 assume i_outer: "i < l \<or> r < i" |
467 from partition_outer_remains [OF part True] i_outer |
467 from partition_outer_remains [OF part True] i_outer |
468 have "Array.get h a !i = Array.get h1 a ! i" by fastsimp |
468 have "Array.get h a !i = Array.get h1 a ! i" by fastsimp |
469 moreover |
469 moreover |
474 have "Array.get h2 a ! i = Array.get h' a ! i" by auto |
474 have "Array.get h2 a ! i = Array.get h' a ! i" by auto |
475 ultimately have "Array.get h a ! i= Array.get h' a ! i" by simp |
475 ultimately have "Array.get h a ! i= Array.get h' a ! i" by simp |
476 } |
476 } |
477 with cr show ?thesis |
477 with cr show ?thesis |
478 unfolding quicksort.simps [of a l r] |
478 unfolding quicksort.simps [of a l r] |
479 by (elim crel_ifE crel_bindE crel_assertE crel_returnE) auto |
479 by (elim effect_ifE effect_bindE effect_assertE effect_returnE) auto |
480 qed |
480 qed |
481 qed |
481 qed |
482 |
482 |
483 lemma quicksort_is_skip: |
483 lemma quicksort_is_skip: |
484 assumes "crel (quicksort a l r) h h' rs" |
484 assumes "effect (quicksort a l r) h h' rs" |
485 shows "r \<le> l \<longrightarrow> h = h'" |
485 shows "r \<le> l \<longrightarrow> h = h'" |
486 using assms |
486 using assms |
487 unfolding quicksort.simps [of a l r] |
487 unfolding quicksort.simps [of a l r] |
488 by (elim crel_ifE crel_returnE) auto |
488 by (elim effect_ifE effect_returnE) auto |
489 |
489 |
490 lemma quicksort_sorts: |
490 lemma quicksort_sorts: |
491 assumes "crel (quicksort a l r) h h' rs" |
491 assumes "effect (quicksort a l r) h h' rs" |
492 assumes l_r_length: "l < Array.length h a" "r < Array.length h a" |
492 assumes l_r_length: "l < Array.length h a" "r < Array.length h a" |
493 shows "sorted (subarray l (r + 1) a h')" |
493 shows "sorted (subarray l (r + 1) a h')" |
494 using assms |
494 using assms |
495 proof (induct a l r arbitrary: h h' rs rule: quicksort.induct) |
495 proof (induct a l r arbitrary: h h' rs rule: quicksort.induct) |
496 case (1 a l r h h' rs) |
496 case (1 a l r h h' rs) |
497 note cr = `crel (quicksort a l r) h h' rs` |
497 note cr = `effect (quicksort a l r) h h' rs` |
498 thus ?case |
498 thus ?case |
499 proof (cases "r > l") |
499 proof (cases "r > l") |
500 case False |
500 case False |
501 hence "l \<ge> r + 1 \<or> l = r" by arith |
501 hence "l \<ge> r + 1 \<or> l = r" by arith |
502 with length_remains[OF cr] 1(5) show ?thesis |
502 with length_remains[OF cr] 1(5) show ?thesis |
503 by (auto simp add: subarray_Nil subarray_single) |
503 by (auto simp add: subarray_Nil subarray_single) |
504 next |
504 next |
505 case True |
505 case True |
506 { |
506 { |
507 fix h1 h2 p |
507 fix h1 h2 p |
508 assume part: "crel (partition a l r) h h1 p" |
508 assume part: "effect (partition a l r) h h1 p" |
509 assume qs1: "crel (quicksort a l (p - 1)) h1 h2 ()" |
509 assume qs1: "effect (quicksort a l (p - 1)) h1 h2 ()" |
510 assume qs2: "crel (quicksort a (p + 1) r) h2 h' ()" |
510 assume qs2: "effect (quicksort a (p + 1) r) h2 h' ()" |
511 from partition_returns_index_in_bounds [OF part True] |
511 from partition_returns_index_in_bounds [OF part True] |
512 have pivot: "l\<le> p \<and> p \<le> r" . |
512 have pivot: "l\<le> p \<and> p \<le> r" . |
513 note length_remains = length_remains[OF qs2] length_remains[OF qs1] partition_length_remains[OF part] |
513 note length_remains = length_remains[OF qs2] length_remains[OF qs1] partition_length_remains[OF part] |
514 from quicksort_outer_remains [OF qs2] quicksort_outer_remains [OF qs1] pivot quicksort_is_skip[OF qs1] |
514 from quicksort_outer_remains [OF qs2] quicksort_outer_remains [OF qs1] pivot quicksort_is_skip[OF qs1] |
515 have pivot_unchanged: "Array.get h1 a ! p = Array.get h' a ! p" by (cases p, auto) |
515 have pivot_unchanged: "Array.get h1 a ! p = Array.get h' a ! p" by (cases p, auto) |
588 using assms |
588 using assms |
589 proof (induct a l r p arbitrary: h rule: part1.induct) |
589 proof (induct a l r p arbitrary: h rule: part1.induct) |
590 case (1 a l r p) |
590 case (1 a l r p) |
591 thus ?case unfolding part1.simps [of a l r] |
591 thus ?case unfolding part1.simps [of a l r] |
592 apply (auto intro!: success_intros del: success_ifI simp add: not_le) |
592 apply (auto intro!: success_intros del: success_ifI simp add: not_le) |
593 apply (auto intro!: crel_intros crel_swapI) |
593 apply (auto intro!: effect_intros effect_swapI) |
594 done |
594 done |
595 qed |
595 qed |
596 |
596 |
597 lemma success_bindI' [success_intros]: (*FIXME move*) |
597 lemma success_bindI' [success_intros]: (*FIXME move*) |
598 assumes "success f h" |
598 assumes "success f h" |
599 assumes "\<And>h' r. crel f h h' r \<Longrightarrow> success (g r) h'" |
599 assumes "\<And>h' r. effect f h h' r \<Longrightarrow> success (g r) h'" |
600 shows "success (f \<guillemotright>= g) h" |
600 shows "success (f \<guillemotright>= g) h" |
601 using assms(1) proof (rule success_crelE) |
601 using assms(1) proof (rule success_effectE) |
602 fix h' r |
602 fix h' r |
603 assume "crel f h h' r" |
603 assume "effect f h h' r" |
604 moreover with assms(2) have "success (g r) h'" . |
604 moreover with assms(2) have "success (g r) h'" . |
605 ultimately show "success (f \<guillemotright>= g) h" by (rule success_bind_crelI) |
605 ultimately show "success (f \<guillemotright>= g) h" by (rule success_bind_effectI) |
606 qed |
606 qed |
607 |
607 |
608 lemma success_partitionI: |
608 lemma success_partitionI: |
609 assumes "l < r" "l < Array.length h a" "r < Array.length h a" |
609 assumes "l < r" "l < Array.length h a" "r < Array.length h a" |
610 shows "success (partition a l r) h" |
610 shows "success (partition a l r) h" |
611 using assms unfolding partition.simps swap_def |
611 using assms unfolding partition.simps swap_def |
612 apply (auto intro!: success_bindI' success_ifI success_returnI success_nthI success_updI success_part1I elim!: crel_bindE crel_updE crel_nthE crel_returnE simp add:) |
612 apply (auto intro!: success_bindI' success_ifI success_returnI success_nthI success_updI success_part1I elim!: effect_bindE effect_updE effect_nthE effect_returnE simp add:) |
613 apply (frule part_length_remains) |
613 apply (frule part_length_remains) |
614 apply (frule part_returns_index_in_bounds) |
614 apply (frule part_returns_index_in_bounds) |
615 apply auto |
615 apply auto |
616 apply (frule part_length_remains) |
616 apply (frule part_length_remains) |
617 apply (frule part_returns_index_in_bounds) |
617 apply (frule part_returns_index_in_bounds) |