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) |
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 |