src/HOL/Library/List_Prefix.thy
changeset 25355 69c0a39ba028
parent 25322 e2eac0c30ff5
child 25356 059c03630d6e
equal deleted inserted replaced
25354:69560579abf1 25355:69c0a39ba028
   160   apply (simp add: prefix_def)
   160   apply (simp add: prefix_def)
   161   apply (rule_tac x="drop n xs" in exI)
   161   apply (rule_tac x="drop n xs" in exI)
   162   apply simp
   162   apply simp
   163   done
   163   done
   164 
   164 
   165 lemma map_prefixI: 
   165 lemma map_prefixI:
   166   "xs \<le> ys \<Longrightarrow> map f xs \<le> map f ys"
   166   "xs \<le> ys \<Longrightarrow> map f xs \<le> map f ys"
   167   by (clarsimp simp: prefix_def)
   167   by (clarsimp simp: prefix_def)
   168 
   168 
   169 lemma prefix_length_less:
   169 lemma prefix_length_less:
   170   "xs < ys \<Longrightarrow> length xs < length ys"
   170   "xs < ys \<Longrightarrow> length xs < length ys"
   186    apply (case_tac ys, simp_all)[1]
   186    apply (case_tac ys, simp_all)[1]
   187   apply (case_tac xs, simp)
   187   apply (case_tac xs, simp)
   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   and c1: "\<lbrakk> ps \<noteq> []; ls = [] \<rbrakk> \<Longrightarrow> R"
   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   and c2: "\<And>a as x xs. \<lbrakk> ps = a#as; ls = x#xs; x = a; \<not> as \<le> xs\<rbrakk> \<Longrightarrow> R"
   195   and c3: "\<And>a as x xs. \<lbrakk> ps = a#as; ls = x#xs; x \<noteq> a\<rbrakk> \<Longrightarrow> R"
   195   and c3: "\<And>a as x xs. \<lbrakk> ps = a#as; ls = x#xs; x \<noteq> a\<rbrakk> \<Longrightarrow> R"
   196   shows "R"  
   196   shows "R"
   197 proof (cases ps)
   197 proof (cases ps)
   198   case Nil thus ?thesis using pfx by simp
   198   case Nil then show ?thesis using pfx by simp
   199 next
   199 next
   200   case (Cons a as)
   200   case (Cons a as)
   201   
   201   then have c: "ps = a#as" .
   202   hence c: "ps = a#as" .
   202 
   203   
       
   204   show ?thesis
   203   show ?thesis
   205   proof (cases ls)
   204   proof (cases ls)
   206     case Nil thus ?thesis 
   205     case Nil
   207       by (intro c1, simp add: Cons)
   206     have "ps \<noteq> []" by (simp add: Nil Cons)
       
   207     from this and Nil show ?thesis by (rule c1)
   208   next
   208   next
   209     case (Cons x xs)
   209     case (Cons x xs)
   210     show ?thesis
   210     show ?thesis
   211     proof (cases "x = a")
   211     proof (cases "x = a")
   212       case True 
   212       case True
   213       show ?thesis 
   213       have "\<not> as \<le> xs" using pfx c Cons True by simp
   214       proof (intro c2) 
   214       with c Cons True show ?thesis by (rule c2)
   215      	  show "\<not> as \<le> xs" using pfx c Cons True
   215     next
   216 	        by simp
   216       case False
   217       qed
   217       with c Cons show ?thesis by (rule c3)
   218     next 
       
   219       case False 
       
   220       show ?thesis by (rule c3)
       
   221     qed
   218     qed
   222   qed
   219   qed
   223 qed
   220 qed
   224 
   221 
   225 lemma not_prefix_induct [consumes 1, case_names Nil Neq Eq]:
   222 lemma not_prefix_induct [consumes 1, case_names Nil Neq Eq]:
   228   and r1:     "\<And>x xs y ys. x \<noteq> y \<Longrightarrow> P (x#xs) (y#ys)"
   225   and r1:     "\<And>x xs y ys. x \<noteq> y \<Longrightarrow> P (x#xs) (y#ys)"
   229   and r2:     "\<And>x xs y ys. \<lbrakk> x = y; \<not> xs \<le> ys; P xs ys \<rbrakk> \<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)"
   230   shows "P ps ls"
   227   shows "P ps ls"
   231   using np
   228   using np
   232 proof (induct ls arbitrary: ps)
   229 proof (induct ls arbitrary: ps)
   233   case Nil thus ?case  
   230   case Nil then show ?case
   234     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)
   235 next
   232 next
   236   case (Cons y ys)  
   233   case (Cons y ys)
   237   hence npfx: "\<not> ps \<le> (y # ys)" by simp
   234   then have npfx: "\<not> ps \<le> (y # ys)" by simp
   238   then obtain x xs where pv: "ps = x # xs" 
   235   then obtain x xs where pv: "ps = x # xs"
   239     by (rule not_prefix_cases) auto
   236     by (rule not_prefix_cases) auto
   240 
   237 
   241   from Cons
   238   from Cons
   242   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
   243   
   240 
   244   show ?case using npfx
   241   show ?case using npfx
   245     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)
   246 qed
   243 qed
   247 
   244 
   248 subsection {* Parallel lists *}
   245 subsection {* Parallel lists *}
   303   qed
   300   qed
   304 qed
   301 qed
   305 
   302 
   306 lemma parallel_append:
   303 lemma parallel_append:
   307   "a \<parallel> b \<Longrightarrow> a @ c \<parallel> b @ d"
   304   "a \<parallel> b \<Longrightarrow> a @ c \<parallel> b @ d"
   308   by (rule parallelI) 
   305   by (rule parallelI)
   309      (erule parallelE, erule conjE, 
   306      (erule parallelE, erule conjE,
   310             induct rule: not_prefix_induct, simp+)+
   307             induct rule: not_prefix_induct, simp+)+
   311 
   308 
   312 lemma parallel_appendI: 
   309 lemma parallel_appendI:
   313   "\<lbrakk> xs \<parallel> ys; x = xs @ xs' ; y = ys @ ys' \<rbrakk> \<Longrightarrow> x \<parallel> y"
   310   "\<lbrakk> xs \<parallel> ys; x = xs @ xs' ; y = ys @ ys' \<rbrakk> \<Longrightarrow> x \<parallel> y"
   314   by simp (rule parallel_append)
   311   by simp (rule parallel_append)
   315 
   312 
   316 lemma parallel_commute:
   313 lemma parallel_commute:
   317   "(a \<parallel> b) = (b \<parallel> a)" 
   314   "(a \<parallel> b) = (b \<parallel> a)"
   318   unfolding parallel_def by auto
   315   unfolding parallel_def by auto
   319 
   316 
   320 subsection {* Postfix order on lists *}
   317 subsection {* Postfix order on lists *}
   321 
   318 
   322 definition
   319 definition
   387   and     pf: "xs >>= ys"
   384   and     pf: "xs >>= ys"
   388   shows   "distinct ys"
   385   shows   "distinct ys"
   389   using dx pf by (clarsimp elim!: postfixE)
   386   using dx pf by (clarsimp elim!: postfixE)
   390 
   387 
   391 lemma postfix_map:
   388 lemma postfix_map:
   392   assumes pf: "xs >>= ys" 
   389   assumes pf: "xs >>= ys"
   393   shows   "map f xs >>= map f ys"
   390   shows   "map f xs >>= map f ys"
   394   using pf by (auto elim!: postfixE intro: postfixI)
   391   using pf by (auto elim!: postfixE intro: postfixI)
   395 
   392 
   396 lemma postfix_drop:
   393 lemma postfix_drop:
   397   "as >>= drop n as"
   394   "as >>= drop n as"
   400 
   397 
   401 lemma postfix_take:
   398 lemma postfix_take:
   402   "xs >>= ys \<Longrightarrow> xs = take (length xs - length ys) xs @ ys"
   399   "xs >>= ys \<Longrightarrow> xs = take (length xs - length ys) xs @ ys"
   403   by (clarsimp elim!: postfixE)
   400   by (clarsimp elim!: postfixE)
   404 
   401 
   405 lemma parallelD1: 
   402 lemma parallelD1:
   406   "x \<parallel> y \<Longrightarrow> \<not> x \<le> y" by blast
   403   "x \<parallel> y \<Longrightarrow> \<not> x \<le> y" by blast
   407 
   404 
   408 lemma parallelD2: 
   405 lemma parallelD2:
   409   "x \<parallel> y \<Longrightarrow> \<not> y \<le> x" by blast
   406   "x \<parallel> y \<Longrightarrow> \<not> y \<le> x" by blast
   410   
   407 
   411 lemma parallel_Nil1 [simp]: "\<not> x \<parallel> []" 
   408 lemma parallel_Nil1 [simp]: "\<not> x \<parallel> []"
   412   unfolding parallel_def by simp
   409   unfolding parallel_def by simp
   413   
   410 
   414 lemma parallel_Nil2 [simp]: "\<not> [] \<parallel> x"
   411 lemma parallel_Nil2 [simp]: "\<not> [] \<parallel> x"
   415   unfolding parallel_def by simp
   412   unfolding parallel_def by simp
   416 
   413 
   417 lemma Cons_parallelI1:
   414 lemma Cons_parallelI1:
   418   "a \<noteq> b \<Longrightarrow> a # as \<parallel> b # bs" by auto
   415   "a \<noteq> b \<Longrightarrow> a # as \<parallel> b # bs" by auto
   419 
   416 
   420 lemma Cons_parallelI2:
   417 lemma Cons_parallelI2:
   421   "\<lbrakk> a = b; as \<parallel> bs \<rbrakk> \<Longrightarrow> a # as \<parallel> b # bs" 
   418   "\<lbrakk> a = b; as \<parallel> bs \<rbrakk> \<Longrightarrow> a # as \<parallel> b # bs"
   422   apply simp
   419   apply simp
   423   apply (rule parallelI)
   420   apply (rule parallelI)
   424    apply simp
   421    apply simp
   425    apply (erule parallelD1)
   422    apply (erule parallelD1)
   426   apply simp
   423   apply simp
   430 lemma not_equal_is_parallel:
   427 lemma not_equal_is_parallel:
   431   assumes neq: "xs \<noteq> ys"
   428   assumes neq: "xs \<noteq> ys"
   432   and     len: "length xs = length ys"
   429   and     len: "length xs = length ys"
   433   shows   "xs \<parallel> ys"
   430   shows   "xs \<parallel> ys"
   434   using len neq
   431   using len neq
   435 proof (induct rule: list_induct2) 
   432 proof (induct rule: list_induct2)
   436   case 1 thus ?case by simp
   433   case 1 then show ?case by simp
   437 next
   434 next
   438   case (2 a as b bs)
   435   case (2 a as b bs)
   439 
   436   have ih: "as \<noteq> bs \<Longrightarrow> as \<parallel> bs" by fact
   440   have ih: "as \<noteq> bs \<Longrightarrow> as \<parallel> bs" .
   437 
   441   
       
   442   show ?case
   438   show ?case
   443   proof (cases "a = b")
   439   proof (cases "a = b")
   444     case True 
   440     case True
   445     hence "as \<noteq> bs" using 2 by simp
   441     then have "as \<noteq> bs" using 2 by simp
   446    
   442     then show ?thesis by (rule Cons_parallelI2 [OF True ih])
   447     thus ?thesis by (rule Cons_parallelI2 [OF True ih])
       
   448   next
   443   next
   449     case False
   444     case False
   450     thus ?thesis by (rule Cons_parallelI1)
   445     then show ?thesis by (rule Cons_parallelI1)
   451   qed
   446   qed
   452 qed
   447 qed
       
   448 
   453 
   449 
   454 subsection {* Exeuctable code *}
   450 subsection {* Exeuctable code *}
   455 
   451 
   456 lemma less_eq_code [code func]:
   452 lemma less_eq_code [code func]:
   457   "([]\<Colon>'a\<Colon>{eq, ord} list) \<le> xs \<longleftrightarrow> True"
   453   "([]\<Colon>'a\<Colon>{eq, ord} list) \<le> xs \<longleftrightarrow> True"