src/HOL/Library/List_Prefix.thy
changeset 25356 059c03630d6e
parent 25355 69c0a39ba028
child 25564 4ca31a3706a4
equal deleted inserted replaced
25355:69c0a39ba028 25356:059c03630d6e
   188   apply (case_tac ys, simp_all)
   188   apply (case_tac ys, simp_all)
   189   done
   189   done
   190 
   190 
   191 lemma not_prefix_cases:
   191 lemma not_prefix_cases:
   192   assumes pfx: "\<not> ps \<le> ls"
   192   assumes pfx: "\<not> ps \<le> ls"
   193   and c1: "\<lbrakk> ps \<noteq> []; ls = [] \<rbrakk> \<Longrightarrow> R"
   193   obtains
   194   and c2: "\<And>a as x xs. \<lbrakk> ps = a#as; ls = x#xs; x = a; \<not> as \<le> xs\<rbrakk> \<Longrightarrow> R"
   194     (c1) "ps \<noteq> []" and "ls = []"
   195   and c3: "\<And>a as x xs. \<lbrakk> ps = a#as; ls = x#xs; x \<noteq> a\<rbrakk> \<Longrightarrow> R"
   195   | (c2) a as x xs where "ps = a#as" and "ls = x#xs" and "x = a" and "\<not> as \<le> xs"
   196   shows "R"
   196   | (c3) a as x xs where "ps = a#as" and "ls = x#xs" and "x \<noteq> a"
   197 proof (cases ps)
   197 proof (cases ps)
   198   case Nil then show ?thesis using pfx by simp
   198   case Nil
       
   199   then show ?thesis using pfx by simp
   199 next
   200 next
   200   case (Cons a as)
   201   case (Cons a as)
   201   then have c: "ps = a#as" .
   202   then have c: "ps = a#as" .
   202 
   203 
   203   show ?thesis
   204   show ?thesis
   219   qed
   220   qed
   220 qed
   221 qed
   221 
   222 
   222 lemma not_prefix_induct [consumes 1, case_names Nil Neq Eq]:
   223 lemma not_prefix_induct [consumes 1, case_names Nil Neq Eq]:
   223   assumes np: "\<not> ps \<le> ls"
   224   assumes np: "\<not> ps \<le> ls"
   224   and base:   "\<And>x xs. P (x#xs) []"
   225     and base: "\<And>x xs. P (x#xs) []"
   225   and r1:     "\<And>x xs y ys. x \<noteq> y \<Longrightarrow> P (x#xs) (y#ys)"
   226     and r1: "\<And>x xs y ys. x \<noteq> y \<Longrightarrow> P (x#xs) (y#ys)"
   226   and r2:     "\<And>x xs y ys. \<lbrakk> x = y; \<not> xs \<le> ys; P xs ys \<rbrakk> \<Longrightarrow> P (x#xs) (y#ys)"
   227     and r2: "\<And>x xs y ys. \<lbrakk> x = y; \<not> xs \<le> ys; P xs ys \<rbrakk> \<Longrightarrow> P (x#xs) (y#ys)"
   227   shows "P ps ls"
   228   shows "P ps ls" using np
   228   using np
       
   229 proof (induct ls arbitrary: ps)
   229 proof (induct ls arbitrary: ps)
   230   case Nil then show ?case
   230   case Nil then show ?case
   231     by (auto simp: neq_Nil_conv elim!: not_prefix_cases intro!: base)
   231     by (auto simp: neq_Nil_conv elim!: not_prefix_cases intro!: base)
   232 next
   232 next
   233   case (Cons y ys)
   233   case (Cons y ys)
   239   have ih: "\<And>ps. \<not>ps \<le> ys \<Longrightarrow> P ps ys" by simp
   239   have ih: "\<And>ps. \<not>ps \<le> ys \<Longrightarrow> P ps ys" by simp
   240 
   240 
   241   show ?case using npfx
   241   show ?case using npfx
   242     by (simp only: pv) (erule not_prefix_cases, auto intro: r1 r2 ih)
   242     by (simp only: pv) (erule not_prefix_cases, auto intro: r1 r2 ih)
   243 qed
   243 qed
       
   244 
   244 
   245 
   245 subsection {* Parallel lists *}
   246 subsection {* Parallel lists *}
   246 
   247 
   247 definition
   248 definition
   248   parallel :: "'a list => 'a list => bool"  (infixl "\<parallel>" 50) where
   249   parallel :: "'a list => 'a list => bool"  (infixl "\<parallel>" 50) where
   308 
   309 
   309 lemma parallel_appendI:
   310 lemma parallel_appendI:
   310   "\<lbrakk> xs \<parallel> ys; x = xs @ xs' ; y = ys @ ys' \<rbrakk> \<Longrightarrow> x \<parallel> y"
   311   "\<lbrakk> xs \<parallel> ys; x = xs @ xs' ; y = ys @ ys' \<rbrakk> \<Longrightarrow> x \<parallel> y"
   311   by simp (rule parallel_append)
   312   by simp (rule parallel_append)
   312 
   313 
   313 lemma parallel_commute:
   314 lemma parallel_commute: "(a \<parallel> b) = (b \<parallel> a)"
   314   "(a \<parallel> b) = (b \<parallel> a)"
       
   315   unfolding parallel_def by auto
   315   unfolding parallel_def by auto
       
   316 
   316 
   317 
   317 subsection {* Postfix order on lists *}
   318 subsection {* Postfix order on lists *}
   318 
   319 
   319 definition
   320 definition
   320   postfix :: "'a list => 'a list => bool"  ("(_/ >>= _)" [51, 50] 50) where
   321   postfix :: "'a list => 'a list => bool"  ("(_/ >>= _)" [51, 50] 50) where
   378   then have "xs = rev zs @ ys" by simp
   379   then have "xs = rev zs @ ys" by simp
   379   then show "xs >>= ys" ..
   380   then show "xs >>= ys" ..
   380 qed
   381 qed
   381 
   382 
   382 lemma distinct_postfix:
   383 lemma distinct_postfix:
   383   assumes dx: "distinct xs"
   384   assumes "distinct xs"
   384   and     pf: "xs >>= ys"
   385     and "xs >>= ys"
   385   shows   "distinct ys"
   386   shows "distinct ys"
   386   using dx pf by (clarsimp elim!: postfixE)
   387   using assms by (clarsimp elim!: postfixE)
   387 
   388 
   388 lemma postfix_map:
   389 lemma postfix_map:
   389   assumes pf: "xs >>= ys"
   390   assumes "xs >>= ys"
   390   shows   "map f xs >>= map f ys"
   391   shows "map f xs >>= map f ys"
   391   using pf by (auto elim!: postfixE intro: postfixI)
   392   using assms by (auto elim!: postfixE intro: postfixI)
   392 
   393 
   393 lemma postfix_drop:
   394 lemma postfix_drop: "as >>= drop n as"
   394   "as >>= drop n as"
       
   395   unfolding postfix_def
   395   unfolding postfix_def
   396   by (rule exI [where x = "take n as"]) simp
   396   by (rule exI [where x = "take n as"]) simp
   397 
   397 
   398 lemma postfix_take:
   398 lemma postfix_take:
   399   "xs >>= ys \<Longrightarrow> xs = take (length xs - length ys) xs @ ys"
   399     "xs >>= ys \<Longrightarrow> xs = take (length xs - length ys) xs @ ys"
   400   by (clarsimp elim!: postfixE)
   400   by (clarsimp elim!: postfixE)
   401 
   401 
   402 lemma parallelD1:
   402 lemma parallelD1: "x \<parallel> y \<Longrightarrow> \<not> x \<le> y"
   403   "x \<parallel> y \<Longrightarrow> \<not> x \<le> y" by blast
   403   by blast
   404 
   404 
   405 lemma parallelD2:
   405 lemma parallelD2: "x \<parallel> y \<Longrightarrow> \<not> y \<le> x"
   406   "x \<parallel> y \<Longrightarrow> \<not> y \<le> x" by blast
   406   by blast
   407 
   407 
   408 lemma parallel_Nil1 [simp]: "\<not> x \<parallel> []"
   408 lemma parallel_Nil1 [simp]: "\<not> x \<parallel> []"
   409   unfolding parallel_def by simp
   409   unfolding parallel_def by simp
   410 
   410 
   411 lemma parallel_Nil2 [simp]: "\<not> [] \<parallel> x"
   411 lemma parallel_Nil2 [simp]: "\<not> [] \<parallel> x"
   424   apply (erule parallelD2)
   424   apply (erule parallelD2)
   425  done
   425  done
   426 
   426 
   427 lemma not_equal_is_parallel:
   427 lemma not_equal_is_parallel:
   428   assumes neq: "xs \<noteq> ys"
   428   assumes neq: "xs \<noteq> ys"
   429   and     len: "length xs = length ys"
   429     and len: "length xs = length ys"
   430   shows   "xs \<parallel> ys"
   430   shows "xs \<parallel> ys"
   431   using len neq
   431   using len neq
   432 proof (induct rule: list_induct2)
   432 proof (induct rule: list_induct2)
   433   case 1 then show ?case by simp
   433   case 1
       
   434   then show ?case by simp
   434 next
   435 next
   435   case (2 a as b bs)
   436   case (2 a as b bs)
   436   have ih: "as \<noteq> bs \<Longrightarrow> as \<parallel> bs" by fact
   437   have ih: "as \<noteq> bs \<Longrightarrow> as \<parallel> bs" by fact
   437 
   438 
   438   show ?case
   439   show ?case
   445     then show ?thesis by (rule Cons_parallelI1)
   446     then show ?thesis by (rule Cons_parallelI1)
   446   qed
   447   qed
   447 qed
   448 qed
   448 
   449 
   449 
   450 
   450 subsection {* Exeuctable code *}
   451 subsection {* Executable code *}
   451 
   452 
   452 lemma less_eq_code [code func]:
   453 lemma less_eq_code [code func]:
   453   "([]\<Colon>'a\<Colon>{eq, ord} list) \<le> xs \<longleftrightarrow> True"
   454     "([]\<Colon>'a\<Colon>{eq, ord} list) \<le> xs \<longleftrightarrow> True"
   454   "(x\<Colon>'a\<Colon>{eq, ord}) # xs \<le> [] \<longleftrightarrow> False"
   455     "(x\<Colon>'a\<Colon>{eq, ord}) # xs \<le> [] \<longleftrightarrow> False"
   455   "(x\<Colon>'a\<Colon>{eq, ord}) # xs \<le> y # ys \<longleftrightarrow> x = y \<and> xs \<le> ys"
   456     "(x\<Colon>'a\<Colon>{eq, ord}) # xs \<le> y # ys \<longleftrightarrow> x = y \<and> xs \<le> ys"
   456   by simp_all
   457   by simp_all
   457 
   458 
   458 lemma less_code [code func]:
   459 lemma less_code [code func]:
   459   "xs < ([]\<Colon>'a\<Colon>{eq, ord} list) \<longleftrightarrow> False"
   460     "xs < ([]\<Colon>'a\<Colon>{eq, ord} list) \<longleftrightarrow> False"
   460   "[] < (x\<Colon>'a\<Colon>{eq, ord})# xs \<longleftrightarrow> True"
   461     "[] < (x\<Colon>'a\<Colon>{eq, ord})# xs \<longleftrightarrow> True"
   461   "(x\<Colon>'a\<Colon>{eq, ord}) # xs < y # ys \<longleftrightarrow> x = y \<and> xs < ys"
   462     "(x\<Colon>'a\<Colon>{eq, ord}) # xs < y # ys \<longleftrightarrow> x = y \<and> xs < ys"
   462   unfolding strict_prefix_def by auto
   463   unfolding strict_prefix_def by auto
   463 
   464 
   464 lemmas [code func] = postfix_to_prefix
   465 lemmas [code func] = postfix_to_prefix
   465 
   466 
   466 end
   467 end