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