5 |
5 |
6 theory Longest_Increasing_Subsequence |
6 theory Longest_Increasing_Subsequence |
7 imports "../../SPARK" |
7 imports "../../SPARK" |
8 begin |
8 begin |
9 |
9 |
10 text {* |
10 text \<open> |
11 Set of all increasing subsequences in a prefix of an array |
11 Set of all increasing subsequences in a prefix of an array |
12 *} |
12 \<close> |
13 |
13 |
14 definition iseq :: "(nat \<Rightarrow> 'a::linorder) \<Rightarrow> nat \<Rightarrow> nat set set" where |
14 definition iseq :: "(nat \<Rightarrow> 'a::linorder) \<Rightarrow> nat \<Rightarrow> nat set set" where |
15 "iseq xs l = {is. (\<forall>i\<in>is. i < l) \<and> |
15 "iseq xs l = {is. (\<forall>i\<in>is. i < l) \<and> |
16 (\<forall>i\<in>is. \<forall>j\<in>is. i \<le> j \<longrightarrow> xs i \<le> xs j)}" |
16 (\<forall>i\<in>is. \<forall>j\<in>is. i \<le> j \<longrightarrow> xs i \<le> xs j)}" |
17 |
17 |
18 text {* |
18 text \<open> |
19 Length of longest increasing subsequence in a prefix of an array |
19 Length of longest increasing subsequence in a prefix of an array |
20 *} |
20 \<close> |
21 |
21 |
22 definition liseq :: "(nat \<Rightarrow> 'a::linorder) \<Rightarrow> nat \<Rightarrow> nat" where |
22 definition liseq :: "(nat \<Rightarrow> 'a::linorder) \<Rightarrow> nat \<Rightarrow> nat" where |
23 "liseq xs i = Max (card ` iseq xs i)" |
23 "liseq xs i = Max (card ` iseq xs i)" |
24 |
24 |
25 text {* |
25 text \<open> |
26 Length of longest increasing subsequence ending at a particular position |
26 Length of longest increasing subsequence ending at a particular position |
27 *} |
27 \<close> |
28 |
28 |
29 definition liseq' :: "(nat \<Rightarrow> 'a::linorder) \<Rightarrow> nat \<Rightarrow> nat" where |
29 definition liseq' :: "(nat \<Rightarrow> 'a::linorder) \<Rightarrow> nat \<Rightarrow> nat" where |
30 "liseq' xs i = Max (card ` (iseq xs (Suc i) \<inter> {is. Max is = i}))" |
30 "liseq' xs i = Max (card ` (iseq xs (Suc i) \<inter> {is. Max is = i}))" |
31 |
31 |
32 lemma iseq_finite: "finite (iseq xs i)" |
32 lemma iseq_finite: "finite (iseq xs i)" |
236 "finite is" "Max is = j" "is \<noteq> {}" |
236 "finite is" "Max is = j" "is \<noteq> {}" |
237 from H j have "card is + 1 = card (is \<union> {i})" |
237 from H j have "card is + 1 = card (is \<union> {i})" |
238 by (simp add: card_insert max_notin) |
238 by (simp add: card_insert max_notin) |
239 moreover { |
239 moreover { |
240 from H j have "xs (Max is) \<le> xs i" by simp |
240 from H j have "xs (Max is) \<le> xs i" by simp |
241 moreover from `j < i` have "Suc j \<le> i" by simp |
241 moreover from \<open>j < i\<close> have "Suc j \<le> i" by simp |
242 with `is \<in> iseq xs (Suc j)` have "is \<in> iseq xs i" |
242 with \<open>is \<in> iseq xs (Suc j)\<close> have "is \<in> iseq xs i" |
243 by (rule iseq_mono) |
243 by (rule iseq_mono) |
244 ultimately have "is \<union> {i} \<in> iseq xs (Suc i)" |
244 ultimately have "is \<union> {i} \<in> iseq xs (Suc i)" |
245 by (rule iseq_insert) |
245 by (rule iseq_insert) |
246 } moreover from H j have "Max (is \<union> {i}) = i" by simp |
246 } moreover from H j have "Max (is \<union> {i}) = i" by simp |
247 moreover have "is \<union> {i} \<noteq> {}" by simp |
247 moreover have "is \<union> {i} \<noteq> {}" by simp |
267 next |
267 next |
268 case False |
268 case False |
269 then have "1 < card is" by simp |
269 then have "1 < card is" by simp |
270 then have "Max (is - {Max is}) < Max is" |
270 then have "Max (is - {Max is}) < Max is" |
271 by (rule Max_diff) |
271 by (rule Max_diff) |
272 from `is \<in> iseq xs (Suc i)` `1 < card is` |
272 from \<open>is \<in> iseq xs (Suc i)\<close> \<open>1 < card is\<close> |
273 have "xs (Max (is - {Max is})) \<le> xs (Max is)" |
273 have "xs (Max (is - {Max is})) \<le> xs (Max is)" |
274 by (rule iseq_nth) |
274 by (rule iseq_nth) |
275 have "card is - 1 = liseq' xs (Max (is - {i}))" |
275 have "card is - 1 = liseq' xs (Max (is - {i}))" |
276 proof (rule liseq'_eq) |
276 proof (rule liseq'_eq) |
277 from `Max is = i` [symmetric] `finite is` `is \<noteq> {}` |
277 from \<open>Max is = i\<close> [symmetric] \<open>finite is\<close> \<open>is \<noteq> {}\<close> |
278 show "card is - 1 = card (is - {i})" by simp |
278 show "card is - 1 = card (is - {i})" by simp |
279 next |
279 next |
280 from `is \<in> iseq xs (Suc i)` `Max is = i` [symmetric] |
280 from \<open>is \<in> iseq xs (Suc i)\<close> \<open>Max is = i\<close> [symmetric] |
281 show "is - {i} \<in> iseq xs (Suc (Max (is - {i})))" |
281 show "is - {i} \<in> iseq xs (Suc (Max (is - {i})))" |
282 by simp (rule iseq_diff) |
282 by simp (rule iseq_diff) |
283 next |
283 next |
284 from `1 < card is` |
284 from \<open>1 < card is\<close> |
285 show "is - {i} \<noteq> {}" by (rule diff_nonempty) |
285 show "is - {i} \<noteq> {}" by (rule diff_nonempty) |
286 next |
286 next |
287 fix js |
287 fix js |
288 assume "js \<in> iseq xs (Suc (Max (is - {i})))" |
288 assume "js \<in> iseq xs (Suc (Max (is - {i})))" |
289 "Max js = Max (is - {i})" "finite js" "js \<noteq> {}" |
289 "Max js = Max (is - {i})" "finite js" "js \<noteq> {}" |
290 from `xs (Max (is - {Max is})) \<le> xs (Max is)` |
290 from \<open>xs (Max (is - {Max is})) \<le> xs (Max is)\<close> |
291 `Max js = Max (is - {i})` `Max is = i` |
291 \<open>Max js = Max (is - {i})\<close> \<open>Max is = i\<close> |
292 have "xs (Max js) \<le> xs i" by simp |
292 have "xs (Max js) \<le> xs i" by simp |
293 moreover from `Max is = i` `Max (is - {Max is}) < Max is` |
293 moreover from \<open>Max is = i\<close> \<open>Max (is - {Max is}) < Max is\<close> |
294 have "Suc (Max (is - {i})) \<le> i" |
294 have "Suc (Max (is - {i})) \<le> i" |
295 by simp |
295 by simp |
296 with `js \<in> iseq xs (Suc (Max (is - {i})))` |
296 with \<open>js \<in> iseq xs (Suc (Max (is - {i})))\<close> |
297 have "js \<in> iseq xs i" |
297 have "js \<in> iseq xs i" |
298 by (rule iseq_mono) |
298 by (rule iseq_mono) |
299 ultimately have "js \<union> {i} \<in> iseq xs (Suc i)" |
299 ultimately have "js \<union> {i} \<in> iseq xs (Suc i)" |
300 by (rule iseq_insert) |
300 by (rule iseq_insert) |
301 moreover from `js \<noteq> {}` `finite js` `Max js = Max (is - {i})` |
301 moreover from \<open>js \<noteq> {}\<close> \<open>finite js\<close> \<open>Max js = Max (is - {i})\<close> |
302 `Max is = i` [symmetric] `Max (is - {Max is}) < Max is` |
302 \<open>Max is = i\<close> [symmetric] \<open>Max (is - {Max is}) < Max is\<close> |
303 have "Max (js \<union> {i}) = i" |
303 have "Max (js \<union> {i}) = i" |
304 by simp |
304 by simp |
305 ultimately have "card (js \<union> {i}) \<le> card is" by (rule R) |
305 ultimately have "card (js \<union> {i}) \<le> card is" by (rule R) |
306 moreover from `Max is = i` [symmetric] `finite js` |
306 moreover from \<open>Max is = i\<close> [symmetric] \<open>finite js\<close> |
307 `Max (is - {Max is}) < Max is` `Max js = Max (is - {i})` |
307 \<open>Max (is - {Max is}) < Max is\<close> \<open>Max js = Max (is - {i})\<close> |
308 have "i \<notin> js" by (simp add: max_notin) |
308 have "i \<notin> js" by (simp add: max_notin) |
309 with `finite js` |
309 with \<open>finite js\<close> |
310 have "card (js \<union> {i}) = card ((js \<union> {i}) - {i}) + 1" |
310 have "card (js \<union> {i}) = card ((js \<union> {i}) - {i}) + 1" |
311 by simp |
311 by simp |
312 ultimately show "card js \<le> card (is - {i})" |
312 ultimately show "card js \<le> card (is - {i})" |
313 using `i \<notin> js` `Max is = i` [symmetric] `is \<noteq> {}` `finite is` |
313 using \<open>i \<notin> js\<close> \<open>Max is = i\<close> [symmetric] \<open>is \<noteq> {}\<close> \<open>finite is\<close> |
314 by simp |
314 by simp |
315 qed simp |
315 qed simp |
316 with H `Max (is - {Max is}) < Max is` |
316 with H \<open>Max (is - {Max is}) < Max is\<close> |
317 `xs (Max (is - {Max is})) \<le> xs (Max is)` |
317 \<open>xs (Max (is - {Max is})) \<le> xs (Max is)\<close> |
318 show ?thesis by auto |
318 show ?thesis by auto |
319 qed |
319 qed |
320 qed |
320 qed |
321 then show "liseq' xs i - 1 \<in> {0} \<union> |
321 then show "liseq' xs i - 1 \<in> {0} \<union> |
322 {liseq' xs j |j. j < i \<and> xs j \<le> xs i}" by simp |
322 {liseq' xs j |j. j < i \<and> xs j \<le> xs i}" by simp |