src/HOL/SPARK/Examples/Liseq/Longest_Increasing_Subsequence.thy
changeset 63167 0909deb8059b
parent 58130 5e9170812356
child 66453 cc19f7ca2ed6
equal deleted inserted replaced
63166:143f58bb34f9 63167:0909deb8059b
     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
   513   apply (cut_tac i=j' and A=A in liseq'_limit)
   513   apply (cut_tac i=j' and A=A in liseq'_limit)
   514   apply simp
   514   apply simp
   515   done
   515   done
   516 
   516 
   517 
   517 
   518 text {* Proof functions *}
   518 text \<open>Proof functions\<close>
   519 
   519 
   520 abbreviation (input)
   520 abbreviation (input)
   521   "arr_conv a \<equiv> (\<lambda>n. a (int n))"
   521   "arr_conv a \<equiv> (\<lambda>n. a (int n))"
   522 
   522 
   523 lemma idx_conv_suc:
   523 lemma idx_conv_suc:
   537   liseq_ends_at = "liseq_ends_at' :: (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> int"
   537   liseq_ends_at = "liseq_ends_at' :: (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> int"
   538   liseq_prfx = "liseq_prfx' :: (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> int"
   538   liseq_prfx = "liseq_prfx' :: (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> int"
   539   max_ext = "max_ext' :: (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int"
   539   max_ext = "max_ext' :: (int \<Rightarrow> int) \<Rightarrow> int \<Rightarrow> int \<Rightarrow> int"
   540 
   540 
   541 
   541 
   542 text {* The verification conditions *}
   542 text \<open>The verification conditions\<close>
   543 
   543 
   544 spark_open "liseq/liseq_length"
   544 spark_open "liseq/liseq_length"
   545 
   545 
   546 spark_vc procedure_liseq_length_5
   546 spark_vc procedure_liseq_length_5
   547   by (simp_all add: liseq_singleton liseq'_singleton)
   547   by (simp_all add: liseq_singleton liseq'_singleton)