src/HOL/Library/Sublist.thy
changeset 71789 3b6547bdf6e2
parent 68406 6beb45f6cf67
child 73186 ce90865dbaeb
equal deleted inserted replaced
71788:ca3ac5238c41 71789:3b6547bdf6e2
   139   unfolding prefix_def by (metis append_take_drop_id)
   139   unfolding prefix_def by (metis append_take_drop_id)
   140 
   140 
   141 lemma prefixeq_butlast: "prefix (butlast xs) xs"
   141 lemma prefixeq_butlast: "prefix (butlast xs) xs"
   142 by (simp add: butlast_conv_take take_is_prefix)
   142 by (simp add: butlast_conv_take take_is_prefix)
   143 
   143 
       
   144 lemma prefix_map_rightE:
       
   145   assumes "prefix xs (map f ys)"
       
   146   shows   "\<exists>xs'. prefix xs' ys \<and> xs = map f xs'"
       
   147 proof -
       
   148   define n where "n = length xs"
       
   149   have "xs = take n (map f ys)"
       
   150     using assms by (auto simp: prefix_def n_def)
       
   151   thus ?thesis
       
   152     by (intro exI[of _ "take n ys"]) (auto simp: take_map take_is_prefix)
       
   153 qed
       
   154 
   144 lemma map_mono_prefix: "prefix xs ys \<Longrightarrow> prefix (map f xs) (map f ys)"
   155 lemma map_mono_prefix: "prefix xs ys \<Longrightarrow> prefix (map f xs) (map f ys)"
   145 by (auto simp: prefix_def)
   156 by (auto simp: prefix_def)
   146 
   157 
   147 lemma filter_mono_prefix: "prefix xs ys \<Longrightarrow> prefix (filter P xs) (filter P ys)"
   158 lemma filter_mono_prefix: "prefix xs ys \<Longrightarrow> prefix (filter P xs) (filter P ys)"
   148 by (auto simp: prefix_def)
   159 by (auto simp: prefix_def)
   167   case 0
   178   case 0
   168   then show ?case by (cases ys) simp_all
   179   then show ?case by (cases ys) simp_all
   169 next
   180 next
   170   case (Suc n)
   181   case (Suc n)
   171   then show ?case by (metis prefix_order.less_trans strict_prefixI take_is_prefix)
   182   then show ?case by (metis prefix_order.less_trans strict_prefixI take_is_prefix)
       
   183 qed
       
   184 
       
   185 lemma prefix_takeWhile:
       
   186   assumes "prefix xs ys"
       
   187   shows   "prefix (takeWhile P xs) (takeWhile P ys)"
       
   188 proof -
       
   189   from assms obtain zs where ys: "ys = xs @ zs"
       
   190     by (auto simp: prefix_def)
       
   191   have "prefix (takeWhile P xs) (takeWhile P (xs @ zs))"
       
   192     by (induction xs) auto
       
   193   thus ?thesis by (simp add: ys)
       
   194 qed
       
   195 
       
   196 lemma prefix_dropWhile:
       
   197   assumes "prefix xs ys"
       
   198   shows   "prefix (dropWhile P xs) (dropWhile P ys)"
       
   199 proof -
       
   200   from assms obtain zs where ys: "ys = xs @ zs"
       
   201     by (auto simp: prefix_def)
       
   202   have "prefix (dropWhile P xs) (dropWhile P (xs @ zs))"
       
   203     by (induction xs) auto
       
   204   thus ?thesis by (simp add: ys)
       
   205 qed
       
   206 
       
   207 lemma prefix_remdups_adj:
       
   208   assumes "prefix xs ys"
       
   209   shows   "prefix (remdups_adj xs) (remdups_adj ys)"
       
   210   using assms
       
   211 proof (induction "length xs" arbitrary: xs ys rule: less_induct)
       
   212   case (less xs)
       
   213   show ?case
       
   214   proof (cases xs)
       
   215     case [simp]: (Cons x xs')
       
   216     then obtain y ys' where [simp]: "ys = y # ys'"
       
   217       using \<open>prefix xs ys\<close> by (cases ys) auto
       
   218     from less show ?thesis
       
   219       by (auto simp: remdups_adj_Cons' less_Suc_eq_le length_dropWhile_le
       
   220                intro!: less prefix_dropWhile)
       
   221   qed auto
   172 qed
   222 qed
   173 
   223 
   174 lemma not_prefix_cases:
   224 lemma not_prefix_cases:
   175   assumes pfx: "\<not> prefix ps ls"
   225   assumes pfx: "\<not> prefix ps ls"
   176   obtains
   226   obtains
   387 
   437 
   388 lemma Longest_common_prefix_eq_Nil:
   438 lemma Longest_common_prefix_eq_Nil:
   389   "\<lbrakk>x#ys \<in> L; y#zs \<in> L; x \<noteq> y \<rbrakk> \<Longrightarrow> Longest_common_prefix L = []"
   439   "\<lbrakk>x#ys \<in> L; y#zs \<in> L; x \<noteq> y \<rbrakk> \<Longrightarrow> Longest_common_prefix L = []"
   390 by (metis Longest_common_prefix_prefix list.inject prefix_Cons)
   440 by (metis Longest_common_prefix_prefix list.inject prefix_Cons)
   391 
   441 
   392 
       
   393 fun longest_common_prefix :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   442 fun longest_common_prefix :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   394 "longest_common_prefix (x#xs) (y#ys) =
   443 "longest_common_prefix (x#xs) (y#ys) =
   395   (if x=y then x # longest_common_prefix xs ys else [])" |
   444   (if x=y then x # longest_common_prefix xs ys else [])" |
   396 "longest_common_prefix _ _ = []"
   445 "longest_common_prefix _ _ = []"
   397 
   446 
   622   case (Suc n)
   671   case (Suc n)
   623   then show ?case 
   672   then show ?case 
   624     by (cases xs) (auto intro: Suc dest: suffix_ConsD' suffix_order.less_imp_le)
   673     by (cases xs) (auto intro: Suc dest: suffix_ConsD' suffix_order.less_imp_le)
   625 qed
   674 qed
   626 
   675 
       
   676 lemma suffix_map_rightE:
       
   677   assumes "suffix xs (map f ys)"
       
   678   shows   "\<exists>xs'. suffix xs' ys \<and> xs = map f xs'"
       
   679 proof -
       
   680   from assms obtain xs' where xs': "map f ys = xs' @ xs"
       
   681     by (auto simp: suffix_def)
       
   682   define n where "n = length xs'"
       
   683   have "xs = drop n (map f ys)"
       
   684     by (simp add: xs' n_def)
       
   685   thus ?thesis
       
   686     by (intro exI[of _ "drop n ys"]) (auto simp: drop_map suffix_drop)
       
   687 qed
       
   688 
       
   689 lemma suffix_remdups_adj: "suffix xs ys \<Longrightarrow> suffix (remdups_adj xs) (remdups_adj ys)"
       
   690   using prefix_remdups_adj[of "rev xs" "rev ys"]
       
   691   by (simp add: suffix_to_prefix)
       
   692 
   627 lemma not_suffix_cases:
   693 lemma not_suffix_cases:
   628   assumes pfx: "\<not> suffix ps ls"
   694   assumes pfx: "\<not> suffix ps ls"
   629   obtains
   695   obtains
   630     (c1) "ps \<noteq> []" and "ls = []"
   696     (c1) "ps \<noteq> []" and "ls = []"
   631   | (c2) a as x xs where "ps = as@[a]" and "ls = xs@[x]" and "x = a" and "\<not> suffix as xs"
   697   | (c2) a as x xs where "ps = as@[a]" and "ls = xs@[x]" and "x = a" and "\<not> suffix as xs"
   708   next
   774   next
   709     case False
   775     case False
   710     then show ?thesis by (rule Cons_parallelI1)
   776     then show ?thesis by (rule Cons_parallelI1)
   711   qed
   777   qed
   712 qed
   778 qed
       
   779 
   713 
   780 
   714 subsection \<open>Suffixes\<close>
   781 subsection \<open>Suffixes\<close>
   715 
   782 
   716 primrec suffixes where
   783 primrec suffixes where
   717   "suffixes [] = [[]]"
   784   "suffixes [] = [[]]"
  1131 qed
  1198 qed
  1132   
  1199   
  1133   
  1200   
  1134 subsection \<open>Contiguous sublists\<close>
  1201 subsection \<open>Contiguous sublists\<close>
  1135 
  1202 
       
  1203 subsubsection \<open>\<open>sublist\<close>\<close>
       
  1204 
  1136 definition sublist :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" where 
  1205 definition sublist :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" where 
  1137   "sublist xs ys = (\<exists>ps ss. ys = ps @ xs @ ss)"
  1206   "sublist xs ys = (\<exists>ps ss. ys = ps @ xs @ ss)"
  1138   
  1207   
  1139 definition strict_sublist :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" where 
  1208 definition strict_sublist :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" where 
  1140   "strict_sublist xs ys \<longleftrightarrow> sublist xs ys \<and> xs \<noteq> ys"
  1209   "strict_sublist xs ys \<longleftrightarrow> sublist xs ys \<and> xs \<noteq> ys"
  1213   "sublist [] ys \<longleftrightarrow> True"
  1282   "sublist [] ys \<longleftrightarrow> True"
  1214   "sublist (x # xs) [] \<longleftrightarrow> False"
  1283   "sublist (x # xs) [] \<longleftrightarrow> False"
  1215   "sublist (x # xs) (y # ys) \<longleftrightarrow> prefix (x # xs) (y # ys) \<or> sublist (x # xs) ys"
  1284   "sublist (x # xs) (y # ys) \<longleftrightarrow> prefix (x # xs) (y # ys) \<or> sublist (x # xs) ys"
  1216   by (simp_all add: sublist_Cons_right)
  1285   by (simp_all add: sublist_Cons_right)
  1217 
  1286 
  1218 
       
  1219 lemma sublist_append:
  1287 lemma sublist_append:
  1220   "sublist xs (ys @ zs) \<longleftrightarrow> 
  1288   "sublist xs (ys @ zs) \<longleftrightarrow> 
  1221      sublist xs ys \<or> sublist xs zs \<or> (\<exists>xs1 xs2. xs = xs1 @ xs2 \<and> suffix xs1 ys \<and> prefix xs2 zs)"
  1289      sublist xs ys \<or> sublist xs zs \<or> (\<exists>xs1 xs2. xs = xs1 @ xs2 \<and> suffix xs1 ys \<and> prefix xs2 zs)"
  1222   by (auto simp: sublist_altdef prefix_append suffix_append)
  1290 by (auto simp: sublist_altdef prefix_append suffix_append)
  1223 
  1291 
  1224 primrec sublists :: "'a list \<Rightarrow> 'a list list" where
  1292 lemma map_mono_sublist:
  1225   "sublists [] = [[]]"
  1293   assumes "sublist xs ys"
  1226 | "sublists (x # xs) = sublists xs @ map ((#) x) (prefixes xs)"
  1294   shows   "sublist (map f xs) (map f ys)"
  1227 
  1295 proof -
  1228 lemma in_set_sublists [simp]: "xs \<in> set (sublists ys) \<longleftrightarrow> sublist xs ys" 
  1296   from assms obtain xs1 xs2 where ys: "ys = xs1 @ xs @ xs2"
  1229   by (induction ys arbitrary: xs) (auto simp: sublist_Cons_right prefix_Cons)
  1297     by (auto simp: sublist_def)
  1230 
  1298   have "map f ys = map f xs1 @ map f xs @ map f xs2"
  1231 lemma set_sublists_eq: "set (sublists xs) = {ys. sublist ys xs}"
  1299     by (auto simp: ys)
  1232   by auto
  1300   thus ?thesis
  1233 
  1301     by (auto simp: sublist_def)
  1234 lemma length_sublists [simp]: "length (sublists xs) = Suc (length xs * Suc (length xs) div 2)"
  1302 qed
  1235   by (induction xs) simp_all
       
  1236 
  1303 
  1237 lemma sublist_length_le: "sublist xs ys \<Longrightarrow> length xs \<le> length ys"
  1304 lemma sublist_length_le: "sublist xs ys \<Longrightarrow> length xs \<le> length ys"
  1238   by (auto simp add: sublist_def)
  1305   by (auto simp add: sublist_def)
  1239 
  1306 
  1240 lemma set_mono_sublist: "sublist xs ys \<Longrightarrow> set xs \<subseteq> set ys"
  1307 lemma set_mono_sublist: "sublist xs ys \<Longrightarrow> set xs \<subseteq> set ys"
  1290   by (subst (1 2) sublist_rev [symmetric])
  1357   by (subst (1 2) sublist_rev [symmetric])
  1291      (simp del: sublist_rev add: sublist_Cons_right suffix_to_prefix)     
  1358      (simp del: sublist_rev add: sublist_Cons_right suffix_to_prefix)     
  1292      
  1359      
  1293 lemma sublist_imp_subseq [intro]: "sublist xs ys \<Longrightarrow> subseq xs ys"
  1360 lemma sublist_imp_subseq [intro]: "sublist xs ys \<Longrightarrow> subseq xs ys"
  1294   by (auto simp: sublist_def)
  1361   by (auto simp: sublist_def)
       
  1362 
       
  1363 lemma sublist_map_rightE:
       
  1364   assumes "sublist xs (map f ys)"
       
  1365   shows   "\<exists>xs'. sublist xs' ys \<and> xs = map f xs'"
       
  1366 proof -
       
  1367   note takedrop = sublist_take sublist_drop
       
  1368   define n where "n = (length ys - length xs)"
       
  1369   from assms obtain xs1 xs2 where xs12: "map f ys = xs1 @ xs @ xs2"
       
  1370     by (auto simp: sublist_def)
       
  1371   define n where "n = length xs1"
       
  1372   have "xs = take (length xs) (drop n (map f ys))"
       
  1373     by (simp add: xs12 n_def)
       
  1374   thus ?thesis
       
  1375     by (intro exI[of _ "take (length xs) (drop n ys)"])
       
  1376        (auto simp: take_map drop_map intro!: takedrop[THEN sublist_order.order.trans])
       
  1377 qed
       
  1378 
       
  1379 lemma sublist_remdups_adj:
       
  1380   assumes "sublist xs ys"
       
  1381   shows   "sublist (remdups_adj xs) (remdups_adj ys)"
       
  1382 proof -
       
  1383   from assms obtain xs1 xs2 where ys: "ys = xs1 @ xs @ xs2"
       
  1384     by (auto simp: sublist_def)
       
  1385   have "suffix (remdups_adj (xs @ xs2)) (remdups_adj (xs1 @ xs @ xs2))"
       
  1386     by (rule suffix_remdups_adj, rule  suffix_appendI) auto
       
  1387   then obtain zs1 where zs1: "remdups_adj (xs1 @ xs @ xs2) = zs1 @ remdups_adj (xs @ xs2)"
       
  1388     by (auto simp: suffix_def)
       
  1389   have "prefix (remdups_adj xs) (remdups_adj (xs @ xs2))"
       
  1390     by (intro prefix_remdups_adj) auto
       
  1391   then obtain zs2 where zs2: "remdups_adj (xs @ xs2) = remdups_adj xs @ zs2"
       
  1392     by (auto simp: prefix_def)
       
  1393   show ?thesis
       
  1394     by (simp add: ys zs1 zs2)
       
  1395 qed
       
  1396 
       
  1397 subsubsection \<open>\<open>sublists\<close>\<close>
       
  1398 
       
  1399 primrec sublists :: "'a list \<Rightarrow> 'a list list" where
       
  1400   "sublists [] = [[]]"
       
  1401 | "sublists (x # xs) = sublists xs @ map ((#) x) (prefixes xs)"
       
  1402 
       
  1403 lemma in_set_sublists [simp]: "xs \<in> set (sublists ys) \<longleftrightarrow> sublist xs ys" 
       
  1404   by (induction ys arbitrary: xs) (auto simp: sublist_Cons_right prefix_Cons)
       
  1405 
       
  1406 lemma set_sublists_eq: "set (sublists xs) = {ys. sublist ys xs}"
       
  1407   by auto
       
  1408 
       
  1409 lemma length_sublists [simp]: "length (sublists xs) = Suc (length xs * Suc (length xs) div 2)"
       
  1410   by (induction xs) simp_all
       
  1411 
  1295 
  1412 
  1296 subsection \<open>Parametricity\<close>
  1413 subsection \<open>Parametricity\<close>
  1297 
  1414 
  1298 context includes lifting_syntax
  1415 context includes lifting_syntax
  1299 begin    
  1416 begin