src/HOL/Library/Sublist.thy
changeset 65956 639eb3617a86
parent 65954 431024edc9cf
child 65957 558ba6b37f5c
equal deleted inserted replaced
65955:0616ba637b14 65956:639eb3617a86
     1 (*  Title:      HOL/Library/Sublist.thy
     1 (*  Title:      HOL/Library/Sublist.thy
     2     Author:     Tobias Nipkow and Markus Wenzel, TU Muenchen
     2     Author:     Tobias Nipkow and Markus Wenzel, TU München
     3     Author:     Christian Sternagel, JAIST
     3     Author:     Christian Sternagel, JAIST
       
     4     Author:     Manuel Eberl, TU München
     4 *)
     5 *)
     5 
     6 
     6 section \<open>List prefixes, suffixes, and homeomorphic embedding\<close>
     7 section \<open>List prefixes, suffixes, and homeomorphic embedding\<close>
     7 
     8 
     8 theory Sublist
     9 theory Sublist
   212 qed
   213 qed
   213 
   214 
   214 
   215 
   215 subsection \<open>Prefixes\<close>
   216 subsection \<open>Prefixes\<close>
   216 
   217 
   217 fun prefixes where
   218 primrec prefixes where
   218 "prefixes [] = [[]]" |
   219 "prefixes [] = [[]]" |
   219 "prefixes (x#xs) = [] # map (op # x) (prefixes xs)"
   220 "prefixes (x#xs) = [] # map (op # x) (prefixes xs)"
   220 
   221 
   221 lemma in_set_prefixes[simp]: "xs \<in> set (prefixes ys) \<longleftrightarrow> prefix xs ys"
   222 lemma in_set_prefixes[simp]: "xs \<in> set (prefixes ys) \<longleftrightarrow> prefix xs ys"
   222 proof (induct xs arbitrary: ys)
   223 proof (induct xs arbitrary: ys)
   698   qed
   699   qed
   699 qed
   700 qed
   700 
   701 
   701 subsection \<open>Suffixes\<close>
   702 subsection \<open>Suffixes\<close>
   702 
   703 
   703 fun suffixes where
   704 primrec suffixes where
   704   "suffixes [] = [[]]"
   705   "suffixes [] = [[]]"
   705 | "suffixes (x#xs) = suffixes xs @ [x # xs]"
   706 | "suffixes (x#xs) = suffixes xs @ [x # xs]"
   706 
   707 
   707 lemma in_set_suffixes [simp]: "xs \<in> set (suffixes ys) \<longleftrightarrow> suffix xs ys"
   708 lemma in_set_suffixes [simp]: "xs \<in> set (suffixes ys) \<longleftrightarrow> suffix xs ys"
   708   by (induction ys) (auto simp: suffix_def Cons_eq_append_conv)
   709   by (induction ys) (auto simp: suffix_def Cons_eq_append_conv)
   917 lemma list_emb_code [code]:
   918 lemma list_emb_code [code]:
   918   "list_emb P [] ys \<longleftrightarrow> True"
   919   "list_emb P [] ys \<longleftrightarrow> True"
   919   "list_emb P (x#xs) [] \<longleftrightarrow> False"
   920   "list_emb P (x#xs) [] \<longleftrightarrow> False"
   920   "list_emb P (x#xs) (y#ys) \<longleftrightarrow> (if P x y then list_emb P xs ys else list_emb P (x#xs) ys)"
   921   "list_emb P (x#xs) (y#ys) \<longleftrightarrow> (if P x y then list_emb P xs ys else list_emb P (x#xs) ys)"
   921   by simp_all
   922   by simp_all
       
   923     
       
   924 
       
   925 subsection \<open>Subsequences (special case of homeomorphic embedding)\<close>
       
   926 
       
   927 abbreviation subseq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"
       
   928   where "subseq xs ys \<equiv> list_emb (op =) xs ys"
   922   
   929   
   923 
   930 definition strict_subseq where "strict_subseq xs ys \<longleftrightarrow> xs \<noteq> ys \<and> subseq xs ys"
   924 
   931 
   925 subsection \<open>Sublists (special case of homeomorphic embedding)\<close>
   932 lemma subseq_Cons2: "subseq xs ys \<Longrightarrow> subseq (x#xs) (x#ys)" by auto
   926 
   933 
   927 abbreviation sublisteq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"
   934 lemma subseq_same_length:
   928   where "sublisteq xs ys \<equiv> list_emb (op =) xs ys"
   935   assumes "subseq xs ys" and "length xs = length ys" shows "xs = ys"
   929   
       
   930 definition strict_sublist where "strict_sublist xs ys \<longleftrightarrow> xs \<noteq> ys \<and> sublisteq xs ys"
       
   931 
       
   932 lemma sublisteq_Cons2: "sublisteq xs ys \<Longrightarrow> sublisteq (x#xs) (x#ys)" by auto
       
   933 
       
   934 lemma sublisteq_same_length:
       
   935   assumes "sublisteq xs ys" and "length xs = length ys" shows "xs = ys"
       
   936   using assms by (induct) (auto dest: list_emb_length)
   936   using assms by (induct) (auto dest: list_emb_length)
   937 
   937 
   938 lemma not_sublisteq_length [simp]: "length ys < length xs \<Longrightarrow> \<not> sublisteq xs ys"
   938 lemma not_subseq_length [simp]: "length ys < length xs \<Longrightarrow> \<not> subseq xs ys"
   939   by (metis list_emb_length linorder_not_less)
   939   by (metis list_emb_length linorder_not_less)
   940 
   940 
   941 lemma sublisteq_Cons': "sublisteq (x#xs) ys \<Longrightarrow> sublisteq xs ys"
   941 lemma subseq_Cons': "subseq (x#xs) ys \<Longrightarrow> subseq xs ys"
   942   by (induct xs, simp, blast dest: list_emb_ConsD)
   942   by (induct xs, simp, blast dest: list_emb_ConsD)
   943 
   943 
   944 lemma sublisteq_Cons2':
   944 lemma subseq_Cons2':
   945   assumes "sublisteq (x#xs) (x#ys)" shows "sublisteq xs ys"
   945   assumes "subseq (x#xs) (x#ys)" shows "subseq xs ys"
   946   using assms by (cases) (rule sublisteq_Cons')
   946   using assms by (cases) (rule subseq_Cons')
   947 
   947 
   948 lemma sublisteq_Cons2_neq:
   948 lemma subseq_Cons2_neq:
   949   assumes "sublisteq (x#xs) (y#ys)"
   949   assumes "subseq (x#xs) (y#ys)"
   950   shows "x \<noteq> y \<Longrightarrow> sublisteq (x#xs) ys"
   950   shows "x \<noteq> y \<Longrightarrow> subseq (x#xs) ys"
   951   using assms by (cases) auto
   951   using assms by (cases) auto
   952 
   952 
   953 lemma sublisteq_Cons2_iff [simp]:
   953 lemma subseq_Cons2_iff [simp]:
   954   "sublisteq (x#xs) (y#ys) = (if x = y then sublisteq xs ys else sublisteq (x#xs) ys)"
   954   "subseq (x#xs) (y#ys) = (if x = y then subseq xs ys else subseq (x#xs) ys)"
   955   by simp
   955   by simp
   956 
   956 
   957 lemma sublisteq_append': "sublisteq (zs @ xs) (zs @ ys) \<longleftrightarrow> sublisteq xs ys"
   957 lemma subseq_append': "subseq (zs @ xs) (zs @ ys) \<longleftrightarrow> subseq xs ys"
   958   by (induct zs) simp_all
   958   by (induct zs) simp_all
   959     
   959     
   960 interpretation sublist_order: order sublisteq strict_sublist
   960 interpretation subseq_order: order subseq strict_subseq
   961 proof
   961 proof
   962   fix xs ys :: "'a list"
   962   fix xs ys :: "'a list"
   963   {
   963   {
   964     assume "sublisteq xs ys" and "sublisteq ys xs"
   964     assume "subseq xs ys" and "subseq ys xs"
   965     thus "xs = ys"
   965     thus "xs = ys"
   966     proof (induct)
   966     proof (induct)
   967       case list_emb_Nil
   967       case list_emb_Nil
   968       from list_emb_Nil2 [OF this] show ?case by simp
   968       from list_emb_Nil2 [OF this] show ?case by simp
   969     next
   969     next
   970       case list_emb_Cons2
   970       case list_emb_Cons2
   971       thus ?case by simp
   971       thus ?case by simp
   972     next
   972     next
   973       case list_emb_Cons
   973       case list_emb_Cons
   974       hence False using sublisteq_Cons' by fastforce
   974       hence False using subseq_Cons' by fastforce
   975       thus ?case ..
   975       thus ?case ..
   976     qed
   976     qed
   977   }
   977   }
   978   thus "strict_sublist xs ys \<longleftrightarrow> (sublisteq xs ys \<and> \<not>sublisteq ys xs)"
   978   thus "strict_subseq xs ys \<longleftrightarrow> (subseq xs ys \<and> \<not>subseq ys xs)"
   979     by (auto simp: strict_sublist_def)
   979     by (auto simp: strict_subseq_def)
   980 qed (auto simp: list_emb_refl intro: list_emb_trans)
   980 qed (auto simp: list_emb_refl intro: list_emb_trans)
   981 
   981 
   982 lemma in_set_sublists [simp]: "xs \<in> set (sublists ys) \<longleftrightarrow> sublisteq xs ys"
   982 lemma in_set_subseqs [simp]: "xs \<in> set (subseqs ys) \<longleftrightarrow> subseq xs ys"
   983 proof
   983 proof
   984   assume "xs \<in> set (sublists ys)"
   984   assume "xs \<in> set (subseqs ys)"
   985   thus "sublisteq xs ys"
   985   thus "subseq xs ys"
   986     by (induction ys arbitrary: xs) (auto simp: Let_def)
   986     by (induction ys arbitrary: xs) (auto simp: Let_def)
   987 next
   987 next
   988   have [simp]: "[] \<in> set (sublists ys)" for ys :: "'a list" 
   988   have [simp]: "[] \<in> set (subseqs ys)" for ys :: "'a list" 
   989     by (induction ys) (auto simp: Let_def)
   989     by (induction ys) (auto simp: Let_def)
   990   assume "sublisteq xs ys"
   990   assume "subseq xs ys"
   991   thus "xs \<in> set (sublists ys)"
   991   thus "xs \<in> set (subseqs ys)"
   992     by (induction xs ys rule: list_emb.induct) (auto simp: Let_def)
   992     by (induction xs ys rule: list_emb.induct) (auto simp: Let_def)
   993 qed
   993 qed
   994 
   994 
   995 lemma set_sublists_eq: "set (sublists ys) = {xs. sublisteq xs ys}"
   995 lemma set_subseqs_eq: "set (subseqs ys) = {xs. subseq xs ys}"
   996   by auto
   996   by auto
   997 
   997 
   998 lemma sublisteq_append_le_same_iff: "sublisteq (xs @ ys) ys \<longleftrightarrow> xs = []"
   998 lemma subseq_append_le_same_iff: "subseq (xs @ ys) ys \<longleftrightarrow> xs = []"
   999   by (auto dest: list_emb_length)
   999   by (auto dest: list_emb_length)
  1000 
  1000 
  1001 lemma sublisteq_singleton_left: "sublisteq [x] ys \<longleftrightarrow> x \<in> set ys"
  1001 lemma subseq_singleton_left: "subseq [x] ys \<longleftrightarrow> x \<in> set ys"
  1002   by (fastforce dest: list_emb_ConsD split_list_last)
  1002   by (fastforce dest: list_emb_ConsD split_list_last)
  1003 
  1003 
  1004 lemma list_emb_append_mono:
  1004 lemma list_emb_append_mono:
  1005   "\<lbrakk> list_emb P xs xs'; list_emb P ys ys' \<rbrakk> \<Longrightarrow> list_emb P (xs@ys) (xs'@ys')"
  1005   "\<lbrakk> list_emb P xs xs'; list_emb P ys ys' \<rbrakk> \<Longrightarrow> list_emb P (xs@ys) (xs'@ys')"
  1006   apply (induct rule: list_emb.induct)
  1006   apply (induct rule: list_emb.induct)
  1010   done
  1010   done
  1011 
  1011 
  1012 
  1012 
  1013 subsection \<open>Appending elements\<close>
  1013 subsection \<open>Appending elements\<close>
  1014 
  1014 
  1015 lemma sublisteq_append [simp]:
  1015 lemma subseq_append [simp]:
  1016   "sublisteq (xs @ zs) (ys @ zs) \<longleftrightarrow> sublisteq xs ys" (is "?l = ?r")
  1016   "subseq (xs @ zs) (ys @ zs) \<longleftrightarrow> subseq xs ys" (is "?l = ?r")
  1017 proof
  1017 proof
  1018   { fix xs' ys' xs ys zs :: "'a list" assume "sublisteq xs' ys'"
  1018   { fix xs' ys' xs ys zs :: "'a list" assume "subseq xs' ys'"
  1019     then have "xs' = xs @ zs & ys' = ys @ zs \<longrightarrow> sublisteq xs ys"
  1019     then have "xs' = xs @ zs & ys' = ys @ zs \<longrightarrow> subseq xs ys"
  1020     proof (induct arbitrary: xs ys zs)
  1020     proof (induct arbitrary: xs ys zs)
  1021       case list_emb_Nil show ?case by simp
  1021       case list_emb_Nil show ?case by simp
  1022     next
  1022     next
  1023       case (list_emb_Cons xs' ys' x)
  1023       case (list_emb_Cons xs' ys' x)
  1024       { assume "ys=[]" then have ?case using list_emb_Cons(1) by auto }
  1024       { assume "ys=[]" then have ?case using list_emb_Cons(1) by auto }
  1036       ultimately show ?case using \<open>op = x y\<close> by (auto simp: Cons_eq_append_conv)
  1036       ultimately show ?case using \<open>op = x y\<close> by (auto simp: Cons_eq_append_conv)
  1037     qed }
  1037     qed }
  1038   moreover assume ?l
  1038   moreover assume ?l
  1039   ultimately show ?r by blast
  1039   ultimately show ?r by blast
  1040 next
  1040 next
  1041   assume ?r then show ?l by (metis list_emb_append_mono sublist_order.order_refl)
  1041   assume ?r then show ?l by (metis list_emb_append_mono subseq_order.order_refl)
  1042 qed
  1042 qed
  1043 
  1043 
  1044 lemma sublisteq_append_iff: 
  1044 lemma subseq_append_iff: 
  1045   "sublisteq xs (ys @ zs) \<longleftrightarrow> (\<exists>xs1 xs2. xs = xs1 @ xs2 \<and> sublisteq xs1 ys \<and> sublisteq xs2 zs)"
  1045   "subseq xs (ys @ zs) \<longleftrightarrow> (\<exists>xs1 xs2. xs = xs1 @ xs2 \<and> subseq xs1 ys \<and> subseq xs2 zs)"
  1046   (is "?lhs = ?rhs")
  1046   (is "?lhs = ?rhs")
  1047 proof
  1047 proof
  1048   assume ?lhs thus ?rhs
  1048   assume ?lhs thus ?rhs
  1049   proof (induction xs "ys @ zs" arbitrary: ys zs rule: list_emb.induct)
  1049   proof (induction xs "ys @ zs" arbitrary: ys zs rule: list_emb.induct)
  1050     case (list_emb_Cons xs ws y ys zs)
  1050     case (list_emb_Cons xs ws y ys zs)
  1056        and list_emb_Cons2(1,2,4)
  1056        and list_emb_Cons2(1,2,4)
  1057     show ?case by (cases ys) (auto simp: Cons_eq_append_conv)
  1057     show ?case by (cases ys) (auto simp: Cons_eq_append_conv)
  1058   qed auto
  1058   qed auto
  1059 qed (auto intro: list_emb_append_mono)
  1059 qed (auto intro: list_emb_append_mono)
  1060 
  1060 
  1061 lemma sublisteq_appendE [case_names append]: 
  1061 lemma subseq_appendE [case_names append]: 
  1062   assumes "sublisteq xs (ys @ zs)"
  1062   assumes "subseq xs (ys @ zs)"
  1063   obtains xs1 xs2 where "xs = xs1 @ xs2" "sublisteq xs1 ys" "sublisteq xs2 zs"
  1063   obtains xs1 xs2 where "xs = xs1 @ xs2" "subseq xs1 ys" "subseq xs2 zs"
  1064   using assms by (subst (asm) sublisteq_append_iff) auto
  1064   using assms by (subst (asm) subseq_append_iff) auto
  1065 
  1065 
  1066 lemma sublisteq_drop_many: "sublisteq xs ys \<Longrightarrow> sublisteq xs (zs @ ys)"
  1066 lemma subseq_drop_many: "subseq xs ys \<Longrightarrow> subseq xs (zs @ ys)"
  1067   by (induct zs) auto
  1067   by (induct zs) auto
  1068 
  1068 
  1069 lemma sublisteq_rev_drop_many: "sublisteq xs ys \<Longrightarrow> sublisteq xs (ys @ zs)"
  1069 lemma subseq_rev_drop_many: "subseq xs ys \<Longrightarrow> subseq xs (ys @ zs)"
  1070   by (metis append_Nil2 list_emb_Nil list_emb_append_mono)
  1070   by (metis append_Nil2 list_emb_Nil list_emb_append_mono)
  1071 
  1071 
  1072 
  1072 
  1073 subsection \<open>Relation to standard list operations\<close>
  1073 subsection \<open>Relation to standard list operations\<close>
  1074 
  1074 
  1075 lemma sublisteq_map:
  1075 lemma subseq_map:
  1076   assumes "sublisteq xs ys" shows "sublisteq (map f xs) (map f ys)"
  1076   assumes "subseq xs ys" shows "subseq (map f xs) (map f ys)"
  1077   using assms by (induct) auto
  1077   using assms by (induct) auto
  1078 
  1078 
  1079 lemma sublisteq_filter_left [simp]: "sublisteq (filter P xs) xs"
  1079 lemma subseq_filter_left [simp]: "subseq (filter P xs) xs"
  1080   by (induct xs) auto
  1080   by (induct xs) auto
  1081 
  1081 
  1082 lemma sublisteq_filter [simp]:
  1082 lemma subseq_filter [simp]:
  1083   assumes "sublisteq xs ys" shows "sublisteq (filter P xs) (filter P ys)"
  1083   assumes "subseq xs ys" shows "subseq (filter P xs) (filter P ys)"
  1084   using assms by induct auto
  1084   using assms by induct auto
  1085 
  1085 
  1086 lemma "sublisteq xs ys \<longleftrightarrow> (\<exists>N. xs = sublist ys N)" (is "?L = ?R")
  1086 lemma subseq_conv_nths: 
       
  1087   "subseq xs ys \<longleftrightarrow> (\<exists>N. xs = nths ys N)" (is "?L = ?R")
  1087 proof
  1088 proof
  1088   assume ?L
  1089   assume ?L
  1089   then show ?R
  1090   then show ?R
  1090   proof (induct)
  1091   proof (induct)
  1091     case list_emb_Nil show ?case by (metis sublist_empty)
  1092     case list_emb_Nil show ?case by (metis nths_empty)
  1092   next
  1093   next
  1093     case (list_emb_Cons xs ys x)
  1094     case (list_emb_Cons xs ys x)
  1094     then obtain N where "xs = sublist ys N" by blast
  1095     then obtain N where "xs = nths ys N" by blast
  1095     then have "xs = sublist (x#ys) (Suc ` N)"
  1096     then have "xs = nths (x#ys) (Suc ` N)"
  1096       by (clarsimp simp add:sublist_Cons inj_image_mem_iff)
  1097       by (clarsimp simp add: nths_Cons inj_image_mem_iff)
  1097     then show ?case by blast
  1098     then show ?case by blast
  1098   next
  1099   next
  1099     case (list_emb_Cons2 x y xs ys)
  1100     case (list_emb_Cons2 x y xs ys)
  1100     then obtain N where "xs = sublist ys N" by blast
  1101     then obtain N where "xs = nths ys N" by blast
  1101     then have "x#xs = sublist (x#ys) (insert 0 (Suc ` N))"
  1102     then have "x#xs = nths (x#ys) (insert 0 (Suc ` N))"
  1102       by (clarsimp simp add:sublist_Cons inj_image_mem_iff)
  1103       by (clarsimp simp add: nths_Cons inj_image_mem_iff)
  1103     moreover from list_emb_Cons2 have "x = y" by simp
  1104     moreover from list_emb_Cons2 have "x = y" by simp
  1104     ultimately show ?case by blast
  1105     ultimately show ?case by blast
  1105   qed
  1106   qed
  1106 next
  1107 next
  1107   assume ?R
  1108   assume ?R
  1108   then obtain N where "xs = sublist ys N" ..
  1109   then obtain N where "xs = nths ys N" ..
  1109   moreover have "sublisteq (sublist ys N) ys"
  1110   moreover have "subseq (nths ys N) ys"
  1110   proof (induct ys arbitrary: N)
  1111   proof (induct ys arbitrary: N)
  1111     case Nil show ?case by simp
  1112     case Nil show ?case by simp
  1112   next
  1113   next
  1113     case Cons then show ?case by (auto simp: sublist_Cons)
  1114     case Cons then show ?case by (auto simp: nths_Cons)
  1114   qed
  1115   qed
  1115   ultimately show ?L by simp
  1116   ultimately show ?L by simp
  1116 qed
  1117 qed
       
  1118   
       
  1119   
       
  1120 subsection \<open>Contiguous sublists\<close>
       
  1121 
       
  1122 definition sublist :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" where 
       
  1123   "sublist xs ys = (\<exists>ps ss. ys = ps @ xs @ ss)"
       
  1124   
       
  1125 definition strict_sublist :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" where 
       
  1126   "strict_sublist xs ys \<longleftrightarrow> sublist xs ys \<and> xs \<noteq> ys"
       
  1127 
       
  1128 interpretation sublist_order: order sublist strict_sublist
       
  1129 proof
       
  1130   fix xs ys zs :: "'a list"
       
  1131   assume "sublist xs ys" "sublist ys zs"
       
  1132   then obtain xs1 xs2 ys1 ys2 where "ys = xs1 @ xs @ xs2" "zs = ys1 @ ys @ ys2"
       
  1133     by (auto simp: sublist_def)
       
  1134   hence "zs = (ys1 @ xs1) @ xs @ (xs2 @ ys2)" by simp
       
  1135   thus "sublist xs zs" unfolding sublist_def by blast
       
  1136 next
       
  1137   fix xs ys :: "'a list"
       
  1138   {
       
  1139     assume "sublist xs ys" "sublist ys xs"
       
  1140     then obtain as bs cs ds 
       
  1141       where xs: "xs = as @ ys @ bs" and ys: "ys = cs @ xs @ ds" 
       
  1142       by (auto simp: sublist_def)
       
  1143     have "xs = as @ cs @ xs @ ds @ bs" by (subst xs, subst ys) auto
       
  1144     also have "length \<dots> = length as + length cs + length xs + length bs + length ds" 
       
  1145       by simp
       
  1146     finally have "as = []" "bs = []" by simp_all
       
  1147     with xs show "xs = ys" by simp
       
  1148   }
       
  1149   thus "strict_sublist xs ys \<longleftrightarrow> (sublist xs ys \<and> \<not>sublist ys xs)"
       
  1150     by (auto simp: strict_sublist_def)
       
  1151 qed (auto simp: strict_sublist_def sublist_def intro: exI[of _ "[]"])
       
  1152   
       
  1153 lemma sublist_Nil_left [simp, intro]: "sublist [] ys"
       
  1154   by (auto simp: sublist_def)
       
  1155     
       
  1156 lemma sublist_Cons_Nil [simp]: "\<not>sublist (x#xs) []"
       
  1157   by (auto simp: sublist_def)
       
  1158     
       
  1159 lemma sublist_Nil_right [simp]: "sublist xs [] \<longleftrightarrow> xs = []"
       
  1160   by (cases xs) auto
       
  1161     
       
  1162 lemma sublist_appendI [simp, intro]: "sublist xs (ps @ xs @ ss)"
       
  1163   by (auto simp: sublist_def)
       
  1164     
       
  1165 lemma sublist_append_leftI [simp, intro]: "sublist xs (ps @ xs)"
       
  1166   by (auto simp: sublist_def intro: exI[of _ "[]"])
       
  1167     
       
  1168 lemma sublist_append_rightI [simp, intro]: "sublist xs (xs @ ss)"
       
  1169   by (auto simp: sublist_def intro: exI[of _ "[]"]) 
       
  1170 
       
  1171 lemma sublist_altdef: "sublist xs ys \<longleftrightarrow> (\<exists>ys'. prefix ys' ys \<and> suffix xs ys')"
       
  1172 proof safe
       
  1173   assume "sublist xs ys"
       
  1174   then obtain ps ss where "ys = ps @ xs @ ss" by (auto simp: sublist_def)
       
  1175   thus "\<exists>ys'. prefix ys' ys \<and> suffix xs ys'"
       
  1176     by (intro exI[of _ "ps @ xs"] conjI suffix_appendI) auto
       
  1177 next
       
  1178   fix ys'
       
  1179   assume "prefix ys' ys" "suffix xs ys'"
       
  1180   thus "sublist xs ys" by (auto simp: prefix_def suffix_def)
       
  1181 qed
       
  1182   
       
  1183 lemma sublist_altdef': "sublist xs ys \<longleftrightarrow> (\<exists>ys'. suffix ys' ys \<and> prefix xs ys')"
       
  1184 proof safe
       
  1185   assume "sublist xs ys"
       
  1186   then obtain ps ss where "ys = ps @ xs @ ss" by (auto simp: sublist_def)
       
  1187   thus "\<exists>ys'. suffix ys' ys \<and> prefix xs ys'"
       
  1188     by (intro exI[of _ "xs @ ss"] conjI suffixI) auto
       
  1189 next
       
  1190   fix ys'
       
  1191   assume "suffix ys' ys" "prefix xs ys'"
       
  1192   thus "sublist xs ys" by (auto simp: prefix_def suffix_def)
       
  1193 qed
       
  1194 
       
  1195 lemma sublist_Cons_right: "sublist xs (y # ys) \<longleftrightarrow> prefix xs (y # ys) \<or> sublist xs ys"
       
  1196   by (auto simp: sublist_def prefix_def Cons_eq_append_conv)
       
  1197     
       
  1198 lemma sublist_code [code]:
       
  1199   "sublist [] ys \<longleftrightarrow> True"
       
  1200   "sublist (x # xs) [] \<longleftrightarrow> False"
       
  1201   "sublist (x # xs) (y # ys) \<longleftrightarrow> prefix (x # xs) (y # ys) \<or> sublist (x # xs) ys"
       
  1202   by (simp_all add: sublist_Cons_right)
       
  1203 
       
  1204 
       
  1205 lemma sublist_append:
       
  1206   "sublist xs (ys @ zs) \<longleftrightarrow> 
       
  1207      sublist xs ys \<or> sublist xs zs \<or> (\<exists>xs1 xs2. xs = xs1 @ xs2 \<and> suffix xs1 ys \<and> prefix xs2 zs)"
       
  1208   by (auto simp: sublist_altdef prefix_append suffix_append)
       
  1209 
       
  1210 primrec sublists :: "'a list \<Rightarrow> 'a list list" where
       
  1211   "sublists [] = [[]]"
       
  1212 | "sublists (x # xs) = sublists xs @ map (op # x) (prefixes xs)"
       
  1213 
       
  1214 lemma in_set_sublists [simp]: "xs \<in> set (sublists ys) \<longleftrightarrow> sublist xs ys" 
       
  1215   by (induction ys arbitrary: xs) (auto simp: sublist_Cons_right prefix_Cons)
       
  1216 
       
  1217 lemma set_sublists_eq: "set (sublists xs) = {ys. sublist ys xs}"
       
  1218   by auto
       
  1219 
       
  1220 lemma length_sublists [simp]: "length (sublists xs) = Suc (length xs * Suc (length xs) div 2)"
       
  1221   by (induction xs) simp_all
       
  1222 
       
  1223 lemma sublist_length_le: "sublist xs ys \<Longrightarrow> length xs \<le> length ys"
       
  1224   by (auto simp add: sublist_def)
       
  1225 
       
  1226 lemma set_mono_sublist: "sublist xs ys \<Longrightarrow> set xs \<subseteq> set ys"
       
  1227   by (auto simp add: sublist_def)
       
  1228     
       
  1229 lemma prefix_imp_sublist [simp, intro]: "prefix xs ys \<Longrightarrow> sublist xs ys"
       
  1230   by (auto simp: sublist_def prefix_def intro: exI[of _ "[]"])
       
  1231     
       
  1232 lemma suffix_imp_sublist [simp, intro]: "suffix xs ys \<Longrightarrow> sublist xs ys"
       
  1233   by (auto simp: sublist_def suffix_def intro: exI[of _ "[]"])
       
  1234 
       
  1235 lemma sublist_take [simp, intro]: "sublist (take n xs) xs"
       
  1236   by (rule prefix_imp_sublist) (simp_all add: take_is_prefix)
       
  1237 
       
  1238 lemma sublist_drop [simp, intro]: "sublist (drop n xs) xs"
       
  1239   by (rule suffix_imp_sublist) (simp_all add: suffix_drop)
       
  1240     
       
  1241 lemma sublist_tl [simp, intro]: "sublist (tl xs) xs"
       
  1242   by (rule suffix_imp_sublist) (simp_all add: suffix_drop)
       
  1243     
       
  1244 lemma sublist_butlast [simp, intro]: "sublist (butlast xs) xs"
       
  1245   by (rule prefix_imp_sublist) (simp_all add: prefixeq_butlast)
       
  1246     
       
  1247 lemma sublist_rev [simp]: "sublist (rev xs) (rev ys) = sublist xs ys"
       
  1248 proof
       
  1249   assume "sublist (rev xs) (rev ys)"
       
  1250   then obtain as bs where "rev ys = as @ rev xs @ bs"
       
  1251     by (auto simp: sublist_def)
       
  1252   also have "rev \<dots> = rev bs @ xs @ rev as" by simp
       
  1253   finally show "sublist xs ys" by simp
       
  1254 next
       
  1255   assume "sublist xs ys"
       
  1256   then obtain as bs where "ys = as @ xs @ bs"
       
  1257     by (auto simp: sublist_def)
       
  1258   also have "rev \<dots> = rev bs @ rev xs @ rev as" by simp
       
  1259   finally show "sublist (rev xs) (rev ys)" by simp
       
  1260 qed
       
  1261     
       
  1262 lemma sublist_rev_left: "sublist (rev xs) ys = sublist xs (rev ys)"
       
  1263   by (subst sublist_rev [symmetric]) (simp only: rev_rev_ident)
       
  1264     
       
  1265 lemma sublist_rev_right: "sublist xs (rev ys) = sublist (rev xs) ys"
       
  1266   by (subst sublist_rev [symmetric]) (simp only: rev_rev_ident)
       
  1267 
       
  1268 lemma snoc_sublist_snoc: 
       
  1269   "sublist (xs @ [x]) (ys @ [y]) \<longleftrightarrow> 
       
  1270      (x = y \<and> suffix xs ys \<or> sublist (xs @ [x]) ys) "
       
  1271   by (subst (1 2) sublist_rev [symmetric])
       
  1272      (simp del: sublist_rev add: sublist_Cons_right suffix_to_prefix)
       
  1273 
       
  1274 lemma sublist_snoc:
       
  1275   "sublist xs (ys @ [y]) \<longleftrightarrow> suffix xs (ys @ [y]) \<or> sublist xs ys"
       
  1276   by (subst (1 2) sublist_rev [symmetric])
       
  1277      (simp del: sublist_rev add: sublist_Cons_right suffix_to_prefix)     
       
  1278 
       
  1279 subsection \<open>Parametricity\<close>
       
  1280 
       
  1281 context includes lifting_syntax
       
  1282 begin    
       
  1283   
       
  1284 private lemma prefix_primrec:
       
  1285   "prefix = rec_list (\<lambda>xs. True) (\<lambda>x xs xsa ys.
       
  1286               case ys of [] \<Rightarrow> False | y # ys \<Rightarrow> x = y \<and> xsa ys)"
       
  1287 proof (intro ext, goal_cases)
       
  1288   case (1 xs ys)
       
  1289   show ?case by (induction xs arbitrary: ys) (auto simp: prefix_Cons split: list.splits)
       
  1290 qed
       
  1291 
       
  1292 private lemma sublist_primrec:
       
  1293   "sublist = (\<lambda>xs ys. rec_list (\<lambda>xs. xs = []) (\<lambda>y ys ysa xs. prefix xs (y # ys) \<or> ysa xs) ys xs)"
       
  1294 proof (intro ext, goal_cases)
       
  1295   case (1 xs ys)
       
  1296   show ?case by (induction ys) (auto simp: sublist_Cons_right)
       
  1297 qed
       
  1298 
       
  1299 private lemma list_emb_primrec:
       
  1300   "list_emb = (\<lambda>uu uua uuaa. rec_list (\<lambda>P xs. List.null xs) (\<lambda>y ys ysa P xs. case xs of [] \<Rightarrow> True 
       
  1301      | x # xs \<Rightarrow> if P x y then ysa P xs else ysa P (x # xs)) uuaa uu uua)"
       
  1302 proof (intro ext, goal_cases)
       
  1303   case (1 P xs ys)
       
  1304   show ?case
       
  1305     by (induction ys arbitrary: xs)
       
  1306        (auto simp: list_emb_code List.null_def split: list.splits)
       
  1307 qed
       
  1308 
       
  1309 lemma prefix_transfer [transfer_rule]:
       
  1310   assumes [transfer_rule]: "bi_unique A"
       
  1311   shows   "(list_all2 A ===> list_all2 A ===> op =) prefix prefix"  
       
  1312   unfolding prefix_primrec by transfer_prover
       
  1313     
       
  1314 lemma suffix_transfer [transfer_rule]:
       
  1315   assumes [transfer_rule]: "bi_unique A"
       
  1316   shows   "(list_all2 A ===> list_all2 A ===> op =) suffix suffix"  
       
  1317   unfolding suffix_to_prefix [abs_def] by transfer_prover
       
  1318 
       
  1319 lemma sublist_transfer [transfer_rule]:
       
  1320   assumes [transfer_rule]: "bi_unique A"
       
  1321   shows   "(list_all2 A ===> list_all2 A ===> op =) sublist sublist"
       
  1322   unfolding sublist_primrec by transfer_prover
       
  1323 
       
  1324 lemma parallel_transfer [transfer_rule]:
       
  1325   assumes [transfer_rule]: "bi_unique A"
       
  1326   shows   "(list_all2 A ===> list_all2 A ===> op =) parallel parallel"
       
  1327   unfolding parallel_def by transfer_prover
       
  1328     
       
  1329 
       
  1330 
       
  1331 lemma list_emb_transfer [transfer_rule]:
       
  1332   "((A ===> A ===> op =) ===> list_all2 A ===> list_all2 A ===> op =) list_emb list_emb"
       
  1333   unfolding list_emb_primrec by transfer_prover
       
  1334 
       
  1335 lemma strict_prefix_transfer [transfer_rule]:
       
  1336   assumes [transfer_rule]: "bi_unique A"
       
  1337   shows   "(list_all2 A ===> list_all2 A ===> op =) strict_prefix strict_prefix"  
       
  1338   unfolding strict_prefix_def by transfer_prover
       
  1339     
       
  1340 lemma strict_suffix_transfer [transfer_rule]:
       
  1341   assumes [transfer_rule]: "bi_unique A"
       
  1342   shows   "(list_all2 A ===> list_all2 A ===> op =) strict_suffix strict_suffix"  
       
  1343   unfolding strict_suffix_def by transfer_prover
       
  1344     
       
  1345 lemma strict_subseq_transfer [transfer_rule]:
       
  1346   assumes [transfer_rule]: "bi_unique A"
       
  1347   shows   "(list_all2 A ===> list_all2 A ===> op =) strict_subseq strict_subseq"  
       
  1348   unfolding strict_subseq_def by transfer_prover
       
  1349     
       
  1350 lemma strict_sublist_transfer [transfer_rule]:
       
  1351   assumes [transfer_rule]: "bi_unique A"
       
  1352   shows   "(list_all2 A ===> list_all2 A ===> op =) strict_sublist strict_sublist"  
       
  1353   unfolding strict_sublist_def by transfer_prover
       
  1354 
       
  1355 lemma prefixes_transfer [transfer_rule]:
       
  1356   assumes [transfer_rule]: "bi_unique A"
       
  1357   shows   "(list_all2 A ===> list_all2 (list_all2 A)) prefixes prefixes"
       
  1358   unfolding prefixes_def by transfer_prover
       
  1359     
       
  1360 lemma suffixes_transfer [transfer_rule]:
       
  1361   assumes [transfer_rule]: "bi_unique A"
       
  1362   shows   "(list_all2 A ===> list_all2 (list_all2 A)) suffixes suffixes"
       
  1363   unfolding suffixes_def by transfer_prover
       
  1364     
       
  1365 lemma sublists_transfer [transfer_rule]:
       
  1366   assumes [transfer_rule]: "bi_unique A"
       
  1367   shows   "(list_all2 A ===> list_all2 (list_all2 A)) sublists sublists"
       
  1368   unfolding sublists_def by transfer_prover
  1117 
  1369 
  1118 end
  1370 end
       
  1371 
       
  1372 end