my_list_prefix.thy
changeset 1 dcde836219bc
equal deleted inserted replaced
0:b992684e9ff6 1:dcde836219bc
       
     1 (*<*)
       
     2 theory my_list_prefix
       
     3 imports "List_Prefix"
       
     4 begin
       
     5 (*>*)
       
     6 
       
     7 (* cmp:: 1:complete equal; 2:less; 3:greater; 4: len equal,but ele no equal *)
       
     8 fun cmp :: "'a list \<Rightarrow> 'a list \<Rightarrow> nat"
       
     9 where
       
    10   "cmp [] [] = 1" |                   
       
    11   "cmp [] (e#es) = 2" |
       
    12   "cmp (e#es) [] = 3" |
       
    13   "cmp (e#es) (a#as) = (let r = cmp es as in 
       
    14                             if (e = a) then r else 4)"
       
    15 
       
    16 (* list_com:: fetch the same ele of the same left order into a new list*) 
       
    17 fun list_com :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list"
       
    18 where 
       
    19   "list_com []  ys = []" |
       
    20   "list_com xs [] = []" |
       
    21   "list_com (x#xs) (y#ys) = (if x = y then x#(list_com xs ys) else [])"
       
    22 
       
    23 (* list_com_rev:: by the right order of list_com *)
       
    24 definition list_com_rev :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" (infix "\<bullet>" 50)
       
    25 where
       
    26   "xs \<bullet> ys \<equiv> rev (list_com (rev xs) (rev ys))"
       
    27 
       
    28 (* list_diff:: list substract, once different return tailer *)
       
    29 fun list_diff :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list"
       
    30 where
       
    31   "list_diff []  xs = []" |
       
    32   "list_diff (x#xs) [] = x#xs" |
       
    33   "list_diff (x#xs) (y#ys) = (if x = y then list_diff xs ys else (x#xs))"
       
    34 
       
    35 (* list_diff_rev:: list substract with rev order*)
       
    36 definition list_diff_rev :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" (infix "\<setminus>" 51)
       
    37 where
       
    38    "xs \<setminus> ys \<equiv> rev (list_diff (rev xs) (rev ys))"
       
    39 
       
    40 (* xs <= ys:: \<exists>zs. ys = xs @ zs *)
       
    41 (* no_junior:: xs is ys' tail,or equal *)
       
    42 definition no_junior  :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "\<preceq>" 50)
       
    43 where
       
    44   "xs \<preceq> ys \<equiv> rev xs \<le> rev ys"
       
    45 
       
    46 (* < :: xs <= ys \<and> xs \<noteq> ys *)
       
    47 (* is_ancestor:: xs is ys' tail, but no equal  *)
       
    48 definition is_ancestor :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "\<prec>" 50)
       
    49 where
       
    50   "xs \<prec> ys \<equiv> rev xs < rev ys"
       
    51 
       
    52 lemma list_com_diff [simp]: "(list_com xs  ys) @ (list_diff xs  ys) = xs" (is "?P xs ys")
       
    53   by (rule_tac P = ?P in cmp.induct, simp+)
       
    54 
       
    55 lemma list_com_diff_rev [simp]: "(xs \<setminus> ys) @ (xs \<bullet> ys) = xs"
       
    56   apply (simp only:list_com_rev_def list_diff_rev_def)
       
    57   by (fold rev_append, simp)
       
    58 
       
    59 lemma list_com_commute: "list_com xs ys = list_com ys xs" (is "?P xs ys")
       
    60   by (rule_tac P = ?P in cmp.induct, simp+)
       
    61 
       
    62 lemma list_com_ido: "xs \<le> ys \<longrightarrow> list_com xs ys = xs" (is "?P xs ys")
       
    63   by (rule_tac P = ?P in cmp.induct, simp+)
       
    64 
       
    65 lemma list_com_rev_ido [simp]: "xs \<preceq> ys \<Longrightarrow> xs \<bullet> ys = xs"
       
    66   by (cut_tac list_com_ido, auto simp: no_junior_def list_com_rev_def)
       
    67 
       
    68 lemma list_com_rev_commute [iff]: "(xs \<bullet> ys) = (ys \<bullet> xs)"
       
    69   by (simp only:list_com_rev_def list_com_commute)
       
    70 
       
    71 lemma list_com_rev_ido1 [simp]: "xs \<preceq> ys \<Longrightarrow> ys \<bullet> xs = xs"
       
    72   by simp
       
    73 
       
    74 lemma list_diff_le: "(list_diff xs ys = []) = (xs \<le> ys)" (is "?P xs ys")
       
    75   by (rule_tac P = ?P in cmp.induct, simp+)
       
    76 
       
    77 lemma list_diff_rev_le: "(xs \<setminus> ys = []) = (xs \<preceq> ys)"
       
    78   by (auto simp:list_diff_rev_def no_junior_def list_diff_le)
       
    79 
       
    80 lemma list_diff_lt: "(list_diff xs ys = [] \<and> list_diff ys xs \<noteq> []) = (xs < ys)" (is "?P xs ys")
       
    81   by (rule_tac P = ?P in cmp.induct, simp+)
       
    82 
       
    83 lemma list_diff_rev_lt: "(xs \<setminus> ys = [] \<and> ys \<setminus> xs \<noteq> []) = (xs \<prec> ys)"
       
    84   by (auto simp: list_diff_rev_def list_diff_lt is_ancestor_def)
       
    85 
       
    86 (* xs diff ys result not [] \<Longrightarrow> \<exists> e \<in> xs. a \<in> ys. e \<noteq> a *)
       
    87 lemma list_diff_neq: 
       
    88   "\<forall> e es a as. list_diff xs ys = (e#es) \<and> list_diff ys xs = (a#as) \<longrightarrow> e \<noteq> a" (is "?P xs ys")
       
    89   by (rule_tac P = ?P in cmp.induct, simp+)
       
    90 
       
    91 lemma list_diff_rev_neq_pre: "\<forall> e es a as. xs \<setminus> ys = rev (e#es) \<and> ys \<setminus> xs = rev (a#as) \<longrightarrow> e \<noteq> a"
       
    92   apply (simp only:list_diff_rev_def, clarify)
       
    93   apply (insert list_diff_neq, atomize)
       
    94   by (erule_tac x = "rev xs" in allE, erule_tac x = "rev ys" in allE, blast)
       
    95 
       
    96 lemma list_diff_rev_neq: "\<forall> e es a as. xs \<setminus> ys = es @ [e] \<and> ys \<setminus> xs = as @ [a] \<longrightarrow> e \<noteq> a"
       
    97   apply (rule_tac allI)+
       
    98   apply (insert list_diff_rev_neq_pre, atomize)
       
    99   apply (erule_tac x = "xs" in allE)
       
   100   apply (erule_tac x = "ys" in allE)
       
   101   apply (erule_tac x = "e" in allE)
       
   102   apply (erule_tac x = "rev es" in allE)
       
   103   apply (erule_tac x = "a" in allE)
       
   104   apply (erule_tac x = "rev as" in allE)
       
   105   by auto
       
   106 
       
   107 lemma list_com_self [simp]: "list_com zs zs = zs"
       
   108   by (induct_tac zs, simp+)
       
   109 
       
   110 lemma list_com_rev_self [simp]: "zs \<bullet> zs = zs"
       
   111   by (simp add:list_com_rev_def)
       
   112 
       
   113 lemma list_com_append [simp]: "(list_com (zs @ xs) (zs @ ys)) = (zs @ (list_com xs ys))"
       
   114   by (induct_tac zs, simp+)
       
   115 
       
   116 lemma list_inter_append [simp]: "((xs @ zs) \<bullet> (ys @ zs)) = ((xs \<bullet> ys) @ zs)"
       
   117   by (simp add:list_com_rev_def)
       
   118 
       
   119 lemma list_diff_djoin_pre: 
       
   120   "\<forall> e es a as. list_diff xs ys = e#es \<and>  list_diff ys xs = a#as \<longrightarrow> (\<forall> zs zs'. (list_diff (xs @ zs) (ys @ zs') = [e]@es@zs))" 
       
   121   (is "?P xs ys")
       
   122   by (rule_tac P = ?P in cmp.induct, simp+)
       
   123 
       
   124 lemma list_diff_djoin_rev_pre:
       
   125   "\<forall> e es a as. xs \<setminus> ys = rev (e#es) \<and>  ys \<setminus> xs = rev (a#as)  \<longrightarrow> (\<forall> zs zs'. ((zs @ xs) \<setminus> (zs' @ ys) = rev ([e]@es@rev zs)))"
       
   126   apply (simp only: list_diff_rev_def, clarify)
       
   127   apply (insert list_diff_djoin_pre, atomize)
       
   128   apply (erule_tac x = "rev xs" in allE)
       
   129   apply (erule_tac x = "rev ys" in allE)
       
   130   apply (erule_tac x = "e" in allE)
       
   131   apply (erule_tac x = "es" in allE)
       
   132   apply (erule_tac x = "a" in allE)
       
   133   apply (erule_tac x = "as" in allE)
       
   134   by simp
       
   135 
       
   136 lemma list_diff_djoin_rev:
       
   137   "xs \<setminus> ys = es @ [e] \<and> ys \<setminus> xs = as @ [a] \<Longrightarrow> zs @ xs \<setminus> zs' @ ys = zs @ es @ [e]"
       
   138   apply (insert list_diff_djoin_rev_pre [rule_format, simplified])
       
   139   apply (clarsimp, atomize)
       
   140   apply (erule_tac x = "xs" in allE)
       
   141   apply (erule_tac x = "ys" in allE)
       
   142   apply (erule_tac x = "rev es" in allE)
       
   143   apply (erule_tac x = "e" in allE)
       
   144   apply (erule_tac x = "rev as" in allE)
       
   145   apply (erule_tac x = "a" in allE)
       
   146   by auto
       
   147 
       
   148 lemmas list_diff_djoin_rev_simplified = conjI [THEN list_diff_djoin_rev, simp]
       
   149 
       
   150 lemmas list_diff_djoin = conjI [THEN list_diff_djoin_pre [rule_format], simp]
       
   151 
       
   152 lemma list_diff_ext_left [simp]: "(list_diff (zs @ xs) (zs @ ys) = (list_diff xs ys))"
       
   153   by (induct_tac zs, simp+)
       
   154 
       
   155 lemma list_diff_rev_ext_left [simp]: "((xs @ zs \<setminus> ys @ zs) = (xs \<setminus> ys))"
       
   156   by (auto simp: list_diff_rev_def)
       
   157 
       
   158 declare no_junior_def [simp]
       
   159 
       
   160 lemma no_juniorE: "\<lbrakk>xs \<preceq> ys; \<And> zs. ys = zs @ xs \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
       
   161 proof -
       
   162   assume h: "xs \<preceq> ys"
       
   163     and h1: "\<And> zs. ys = zs @ xs \<Longrightarrow> R"
       
   164   show "R"
       
   165   proof -
       
   166     from h have "rev xs \<le> rev ys" by (simp)
       
   167     from this obtain zs where eq_rev: "rev ys = rev xs @ zs" by (auto simp:prefix_def)
       
   168     show R 
       
   169     proof(rule h1 [where zs = "rev zs"])
       
   170       from rev_rev_ident and eq_rev have "rev (rev (ys)) = rev zs @ rev (rev xs)"
       
   171 	by simp
       
   172       thus "ys = rev zs @ xs" by simp
       
   173     qed
       
   174   qed
       
   175 qed
       
   176 
       
   177 lemma no_juniorI: "\<lbrakk>ys = zs @ xs\<rbrakk> \<Longrightarrow> xs \<preceq> ys"
       
   178   by simp
       
   179 
       
   180 lemma no_junior_ident [simp]: "xs \<preceq> xs"
       
   181   by simp
       
   182 
       
   183 lemma no_junior_expand: "xs \<preceq> ys = ((xs \<prec> ys) \<or> xs = ys)"
       
   184   by (simp only:no_junior_def is_ancestor_def strict_prefix_def, blast)
       
   185 
       
   186 lemma no_junior_same_prefix: " e # \<tau> \<preceq> e' # \<tau>' \<Longrightarrow> \<tau> \<preceq> \<tau>'"
       
   187 apply (simp add:no_junior_def )
       
   188 apply (erule disjE, simp)
       
   189 apply (simp only:prefix_def)
       
   190 by (erule exE, rule_tac x = "[e] @ zs" in exI, auto)
       
   191 
       
   192 lemma no_junior_noteq: "\<lbrakk>\<tau> \<preceq> a # \<tau>'; \<tau> \<noteq> a # \<tau>'\<rbrakk> \<Longrightarrow> \<tau> \<preceq> \<tau>'"
       
   193 apply (erule no_juniorE)
       
   194 by (case_tac zs, simp+)
       
   195 
       
   196 lemma is_ancestor_app [simp]: "xs \<prec> ys \<Longrightarrow> xs \<prec> zs @ ys"
       
   197   by (auto simp:is_ancestor_def strict_prefix_def)
       
   198 
       
   199 lemma is_ancestor_cons [simp]: "xs \<prec> ys \<Longrightarrow> xs \<prec> a # ys"
       
   200   by (auto simp:is_ancestor_def strict_prefix_def)
       
   201 
       
   202 lemma no_junior_app [simp]: "xs \<preceq> ys \<Longrightarrow> xs \<preceq> zs @ ys"
       
   203   by simp
       
   204 
       
   205 lemma is_ancestor_no_junior [simp]: "xs \<prec> ys \<Longrightarrow> xs \<preceq> ys"
       
   206   by (simp add:is_ancestor_def)
       
   207 
       
   208 lemma is_ancestor_y [simp]: "ys \<prec> y#ys"
       
   209   by (simp add:is_ancestor_def strict_prefix_def)
       
   210 
       
   211 lemma no_junior_cons [simp]: "xs \<preceq> ys \<Longrightarrow> xs \<prec> (y#ys)"
       
   212   by (unfold no_junior_expand, auto)
       
   213 
       
   214 lemma no_junior_anti_sym: "\<lbrakk>xs \<preceq> ys; ys \<preceq> xs\<rbrakk> \<Longrightarrow> xs = ys"
       
   215   by simp
       
   216 
       
   217 declare no_junior_def [simp del]
       
   218 
       
   219 (* djoin:: xs and ys is not the other's tail, not equal either *)
       
   220 definition djoin :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "\<asymp>" 50)
       
   221 where
       
   222   "xs \<asymp> ys \<equiv> \<not> (xs \<preceq> ys \<or> ys \<preceq> xs)"
       
   223 
       
   224 (* dinj:: function f's returning list is not tailing when paras not equal *)
       
   225 definition dinj :: "('a \<Rightarrow> 'b list) \<Rightarrow> bool"
       
   226 where
       
   227   "dinj f \<equiv> (\<forall> a b. a \<noteq> b \<longrightarrow> f a \<asymp> f b)"
       
   228 
       
   229 
       
   230 (* list_cmp:: list comparison: one is other's prefix or no equal at some position *)
       
   231 lemma list_cmp: "xs \<le> ys \<or> ys \<le> xs \<or>  (\<exists> zs x y a b. xs = zs @ [a] @ x  \<and> ys = zs @ [b] @ y \<and> a \<noteq> b)"
       
   232 proof(cases "list_diff xs ys")
       
   233   assume " list_diff xs ys = []" with list_diff_le show ?thesis by blast
       
   234 next
       
   235   fix e es
       
   236   assume h: "list_diff xs ys = e # es"
       
   237   show ?thesis
       
   238   proof(cases "list_diff ys xs")
       
   239     assume " list_diff ys xs = []" with list_diff_le show ?thesis by blast
       
   240   next
       
   241     fix a as assume h1: "list_diff ys xs = (a # as)"
       
   242     have "xs = (list_com xs ys) @ [e] @ es \<and> ys = (list_com xs ys) @ [a] @ as \<and> e \<noteq> a"
       
   243       apply (simp, fold h1, fold h)
       
   244       apply (simp,subst list_com_commute, simp)
       
   245       apply (rule_tac list_diff_neq[rule_format])
       
   246       by (insert h1, insert h, blast)
       
   247     thus ?thesis by blast
       
   248   qed
       
   249 qed
       
   250 
       
   251 (* In fact, this is a case split *)
       
   252 lemma list_diff_ind: "\<lbrakk>list_diff xs ys = [] \<Longrightarrow> R; list_diff ys xs = [] \<Longrightarrow> R; 
       
   253                              \<And> e es a as. \<lbrakk>list_diff xs ys = e#es; list_diff ys xs = a#as; e \<noteq> a\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
       
   254 proof -
       
   255   assume h1: "list_diff xs ys = [] \<Longrightarrow> R"
       
   256     and h2: "list_diff ys xs = [] \<Longrightarrow> R"
       
   257     and h3: "\<And> e es a as. \<lbrakk>list_diff xs ys = e#es; list_diff ys xs = a#as; e \<noteq> a\<rbrakk> \<Longrightarrow> R"
       
   258   show R
       
   259   proof(cases "list_diff xs ys")
       
   260     assume "list_diff xs ys = []" from h1 [OF this] show R .
       
   261   next
       
   262     fix e es
       
   263     assume he: "list_diff xs ys = e#es"
       
   264     show R
       
   265     proof(cases "list_diff ys xs")
       
   266       assume "list_diff ys xs = []" from h2 [OF this] show R .
       
   267     next
       
   268       fix a as
       
   269       assume ha: "list_diff ys xs = a#as" show R
       
   270       proof(rule h3 [OF he ha])
       
   271 	from list_diff_neq [rule_format, OF conjI [OF he ha ]]
       
   272 	show "e \<noteq> a" .
       
   273       qed
       
   274     qed
       
   275   qed
       
   276 qed
       
   277 
       
   278 lemma list_diff_rev_ind: 
       
   279   "\<lbrakk>xs \<setminus> ys = [] \<Longrightarrow> R; ys \<setminus> xs = [] \<Longrightarrow> R; \<And> e es a as. \<lbrakk>xs \<setminus> ys = es@[e]; ys \<setminus> xs = as@[a]; e \<noteq> a\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
       
   280 proof -
       
   281   fix xs ys R
       
   282   assume h1: "xs \<setminus> ys = [] \<Longrightarrow> R"
       
   283     and h2: "ys \<setminus> xs = [] \<Longrightarrow> R"
       
   284     and h3: "\<And> e es a as. \<lbrakk>xs \<setminus> ys = es@[e]; ys \<setminus> xs = as@[a]; e \<noteq> a\<rbrakk> \<Longrightarrow> R"
       
   285   show R
       
   286   proof (rule list_diff_ind [where xs = "rev xs" and ys = "rev ys"])
       
   287     assume "list_diff (rev xs) (rev ys) = []" thus R by (auto intro:h1 simp:list_diff_rev_def)
       
   288   next
       
   289     assume "list_diff (rev ys) (rev xs) = []" thus R by (auto intro:h2 simp:list_diff_rev_def)
       
   290   next
       
   291     fix e es a as
       
   292     assume "list_diff (rev xs) (rev ys) = e # es"
       
   293       and "list_diff (rev ys) (rev xs) = a # as" 
       
   294       and " e \<noteq> a"
       
   295     thus R by (auto intro:h3 simp:list_diff_rev_def)
       
   296   qed
       
   297 qed
       
   298 
       
   299 lemma djoin_diff_iff: "(xs \<asymp> ys) = (\<exists> e es a as. list_diff (rev xs) (rev ys) = e#es \<and> list_diff (rev ys) (rev xs) = a#as \<and> a \<noteq> e)"
       
   300 proof (rule list_diff_ind [where xs = "rev xs" and ys = "rev ys"])
       
   301   assume "list_diff (rev xs) (rev ys) = []"
       
   302   hence "xs \<preceq> ys" by (unfold no_junior_def, simp add:list_diff_le)
       
   303   thus ?thesis 
       
   304     apply (auto simp:djoin_def no_junior_def)
       
   305     by (fold list_diff_le, simp)
       
   306 next
       
   307   assume "list_diff (rev ys) (rev xs) = []"
       
   308   hence "ys \<preceq> xs" by (unfold no_junior_def, simp add:list_diff_le)
       
   309   thus ?thesis 
       
   310     apply (auto simp:djoin_def no_junior_def)
       
   311     by (fold list_diff_le, simp)
       
   312 next
       
   313   fix e es a as
       
   314   assume he: "list_diff (rev xs) (rev ys) = e # es"
       
   315     and ha: "list_diff (rev ys) (rev xs) = a # as"
       
   316     and hn: "e \<noteq> a"
       
   317   show ?thesis
       
   318   proof
       
   319     from he ha hn
       
   320     show 
       
   321       "\<exists>e es a as. list_diff (rev xs) (rev ys) = e # es \<and> list_diff (rev ys) (rev xs) = a # as \<and> a \<noteq> e" 
       
   322       by blast
       
   323   next
       
   324     from he ha hn
       
   325     show "xs \<asymp> ys" 
       
   326       by (auto simp:djoin_def no_junior_def, fold list_diff_le, simp+)
       
   327   qed
       
   328 qed
       
   329 
       
   330 lemma djoin_diff_rev_iff: "(xs \<asymp> ys) = (\<exists> e es a as. xs \<setminus> ys = es@[e] \<and> ys \<setminus> xs = as@[a] \<and> a \<noteq> e)"
       
   331   apply (auto simp:djoin_diff_iff list_diff_rev_def)
       
   332   apply (rule_tac x = e in exI, safe)
       
   333   apply (rule_tac x = "rev es" in exI)
       
   334   apply (rule_tac injD[where f = rev], simp+)
       
   335   apply (rule_tac x = "a" in exI, safe)
       
   336   apply (rule_tac x = "rev as" in exI)
       
   337   apply (rule_tac injD[where f = rev], simp+)
       
   338   done
       
   339 
       
   340 lemma djoin_revE: "\<lbrakk>xs \<asymp> ys; \<And>e es a as. \<lbrakk>xs \<setminus> ys = es@[e]; ys \<setminus> xs = as@[a]; a \<noteq> e\<rbrakk> \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R"
       
   341   by (unfold djoin_diff_rev_iff, blast)
       
   342 
       
   343 lemma djoin_append_left[simp, intro]: "xs \<asymp> ys \<Longrightarrow> (zs' @ xs) \<asymp> (zs @ ys)"
       
   344   by (auto simp:djoin_diff_iff intro:list_diff_djoin[simplified])
       
   345 
       
   346 lemma djoin_cons_left[simp]: "xs \<asymp> ys \<Longrightarrow> (e # xs) \<asymp> (a # ys)"
       
   347   by (drule_tac zs' = "[e]" and zs = "[a]" in djoin_append_left, simp)
       
   348 
       
   349 lemma djoin_simp_1 [simp]: "xs \<asymp> ys \<Longrightarrow> xs \<asymp> (zs @ ys)"
       
   350   by (drule_tac djoin_append_left [where zs' = "[]"], simp)
       
   351 
       
   352 lemma djoin_simp_2 [simp]: "xs \<asymp> ys \<Longrightarrow> (zs' @ xs) \<asymp> ys"
       
   353   by (drule_tac djoin_append_left [where zs = "[]"], simp)
       
   354 
       
   355 lemma djoin_append_right[simp]: "xs \<asymp> ys \<Longrightarrow> (xs @ zs) \<asymp> (ys @ zs)"
       
   356   by (simp add:djoin_diff_iff)
       
   357 
       
   358 lemma djoin_cons_append[simp]: "xs \<asymp> ys \<Longrightarrow> (x # xs) \<asymp> (zs @ ys)"
       
   359   by (subgoal_tac "[x] @ xs \<asymp> zs @ ys", simp, blast)
       
   360 
       
   361 lemma djoin_append_cons[simp]: "xs \<asymp> ys \<Longrightarrow> (zs @ xs) \<asymp> (y # ys)"
       
   362   by (subgoal_tac "zs @ xs \<asymp> [y] @ ys", simp, blast)
       
   363 
       
   364 lemma djoin_neq [simp]: "xs \<asymp> ys \<Longrightarrow> xs \<noteq> ys"
       
   365   by (simp only:djoin_diff_iff, clarsimp)
       
   366 
       
   367 lemma djoin_cons [simp]: "e \<noteq> a \<Longrightarrow> e # xs \<asymp> a # xs"
       
   368   by (unfold djoin_diff_iff, simp)
       
   369 
       
   370 lemma djoin_append_e [simp]: "e \<noteq> a \<Longrightarrow> (zs @ [e] @ xs) \<asymp> (zs' @ [a] @ xs)"
       
   371   by (unfold djoin_diff_iff, simp)
       
   372 
       
   373 lemma djoin_mono [simp]: "\<lbrakk>xs \<asymp> ys; xs \<preceq> xs'; ys \<preceq> ys'\<rbrakk> \<Longrightarrow> xs' \<asymp> ys'"
       
   374 proof(erule_tac djoin_revE,unfold djoin_diff_rev_iff)
       
   375   fix e es a as
       
   376   assume hx: "xs \<preceq> xs'"
       
   377     and hy: "ys \<preceq> ys'"
       
   378     and hmx: "xs \<setminus> ys = es @ [e]"
       
   379     and hmy: "ys \<setminus> xs = as @ [a]" 
       
   380     and neq: "a \<noteq> e"
       
   381   have "xs' \<setminus> ys' = ((xs' \<setminus> xs) @ es) @ [e] \<and> ys' \<setminus> xs' = ((ys' \<setminus> ys) @ as) @ [a] \<and> a \<noteq> e"
       
   382   proof -
       
   383     from hx have heqx: "(xs' \<setminus> xs) @ xs = xs'"
       
   384       by (cut_tac list_com_diff_rev [of xs' xs], subgoal_tac "xs' \<bullet> xs = xs", simp+)
       
   385     moreover from hy have heqy: "(ys' \<setminus> ys) @ ys = ys'" 
       
   386       by (cut_tac list_com_diff_rev [of ys' ys], subgoal_tac "ys' \<bullet> ys = ys", simp+)
       
   387     moreover from list_diff_djoin_rev_simplified [OF hmx hmy] 
       
   388     have "((xs' \<setminus> xs) @ xs) \<setminus>  ((ys' \<setminus> ys) @ ys) = (xs' \<setminus> xs) @ es @ [e]" by simp
       
   389     moreover from list_diff_djoin_rev_simplified [OF hmy hmx] 
       
   390     have "((ys' \<setminus> ys) @ ys) \<setminus>  ((xs' \<setminus> xs) @ xs) = (ys' \<setminus> ys) @ as @ [a]" by simp
       
   391     ultimately show ?thesis by (simp add:neq)
       
   392   qed
       
   393   thus "\<exists>e es a as. xs' \<setminus> ys' = es @ [e] \<and> ys' \<setminus> xs' = as @ [a] \<and> a \<noteq> e" by blast
       
   394 qed
       
   395 
       
   396 lemmas djoin_append_e_simplified [simp] = djoin_append_e [simplified]
       
   397 
       
   398 (*<*)
       
   399 end
       
   400 (*>*)