diff -r 34d01e9a772e -r 7d9c0ed02b56 My_list_prefix.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/My_list_prefix.thy Fri May 03 08:20:21 2013 +0100 @@ -0,0 +1,402 @@ +(*<*) +theory My_list_prefix +imports List_Prefix +begin +(*>*) + +(* cmp:: 1:complete equal; 2:less; 3:greater; 4: len equal,but ele no equal *) +fun cmp :: "'a list \ 'a list \ nat" +where + "cmp [] [] = 1" | + "cmp [] (e#es) = 2" | + "cmp (e#es) [] = 3" | + "cmp (e#es) (a#as) = (let r = cmp es as in + if (e = a) then r else 4)" + +(* list_com:: fetch the same ele of the same left order into a new list*) +fun list_com :: "'a list \ 'a list \ 'a list" +where + "list_com [] ys = []" | + "list_com xs [] = []" | + "list_com (x#xs) (y#ys) = (if x = y then x#(list_com xs ys) else [])" + +(* list_com_rev:: by the right order of list_com *) +definition list_com_rev :: "'a list \ 'a list \ 'a list" (infix "\" 50) +where + "xs \ ys \ rev (list_com (rev xs) (rev ys))" + +(* list_diff:: list substract, once different return tailer *) +fun list_diff :: "'a list \ 'a list \ 'a list" +where + "list_diff [] xs = []" | + "list_diff (x#xs) [] = x#xs" | + "list_diff (x#xs) (y#ys) = (if x = y then list_diff xs ys else (x#xs))" + +(* list_diff_rev:: list substract with rev order*) +definition list_diff_rev :: "'a list \ 'a list \ 'a list" (infix "\" 51) +where + "xs \ ys \ rev (list_diff (rev xs) (rev ys))" + +(* xs <= ys:: \zs. ys = xs @ zs *) +(* no_junior:: xs is ys' tail,or equal *) +definition no_junior :: "'a list \ 'a list \ bool" (infix "\" 50) +where + "xs \ ys \ rev xs \ rev ys" + +(* < :: xs <= ys \ xs \ ys *) +(* is_ancestor:: xs is ys' tail, but no equal *) +definition is_ancestor :: "'a list \ 'a list \ bool" (infix "\" 50) +where + "xs \ ys \ rev xs < rev ys" + +lemma list_com_diff [simp]: "(list_com xs ys) @ (list_diff xs ys) = xs" (is "?P xs ys") + by (rule_tac P = ?P in cmp.induct, simp+) + +lemma list_com_diff_rev [simp]: "(xs \ ys) @ (xs \ ys) = xs" + apply (simp only:list_com_rev_def list_diff_rev_def) + by (fold rev_append, simp) + +lemma list_com_commute: "list_com xs ys = list_com ys xs" (is "?P xs ys") + by (rule_tac P = ?P in cmp.induct, simp+) + +lemma list_com_ido: "xs \ ys \ list_com xs ys = xs" (is "?P xs ys") + by (rule_tac P = ?P in cmp.induct, auto+) + +lemma list_com_rev_ido [simp]: "xs \ ys \ xs \ ys = xs" + by (cut_tac list_com_ido, auto simp: no_junior_def list_com_rev_def) + +lemma list_com_rev_commute [iff]: "(xs \ ys) = (ys \ xs)" + by (simp only:list_com_rev_def list_com_commute) + +lemma list_com_rev_ido1 [simp]: "xs \ ys \ ys \ xs = xs" + by simp + +lemma list_diff_le: "(list_diff xs ys = []) = (xs \ ys)" (is "?P xs ys") + by (rule_tac P = ?P in cmp.induct, simp+) + + +lemma list_diff_rev_le: "(xs \ ys = []) = (xs \ ys)" + by (auto simp:list_diff_rev_def no_junior_def list_diff_le) + +lemma list_diff_lt: "(list_diff xs ys = [] \ list_diff ys xs \ []) = (xs < ys)" (is "?P xs ys") + by (rule_tac P = ?P in cmp.induct, simp+) + +lemma list_diff_rev_lt: "(xs \ ys = [] \ ys \ xs \ []) = (xs \ ys)" + by (auto simp: list_diff_rev_def list_diff_lt is_ancestor_def) + + +(* xs diff ys result not [] \ \ e \ xs. a \ ys. e \ a *) +lemma list_diff_neq: + "\ e es a as. list_diff xs ys = (e#es) \ list_diff ys xs = (a#as) \ e \ a" (is "?P xs ys") + by (rule_tac P = ?P in cmp.induct, simp+) + +lemma list_diff_rev_neq_pre: "\ e es a as. xs \ ys = rev (e#es) \ ys \ xs = rev (a#as) \ e \ a" + apply (simp only:list_diff_rev_def, clarify) + apply (insert list_diff_neq, atomize) + by (erule_tac x = "rev xs" in allE, erule_tac x = "rev ys" in allE, blast) + +lemma list_diff_rev_neq: "\ e es a as. xs \ ys = es @ [e] \ ys \ xs = as @ [a] \ e \ a" + apply (rule_tac allI)+ + apply (insert list_diff_rev_neq_pre, atomize) + apply (erule_tac x = "xs" in allE) + apply (erule_tac x = "ys" in allE) + apply (erule_tac x = "e" in allE) + apply (erule_tac x = "rev es" in allE) + apply (erule_tac x = "a" in allE) + apply (erule_tac x = "rev as" in allE) + by auto + +lemma list_com_self [simp]: "list_com zs zs = zs" + by (induct_tac zs, simp+) + +lemma list_com_rev_self [simp]: "zs \ zs = zs" + by (simp add:list_com_rev_def) + +lemma list_com_append [simp]: "(list_com (zs @ xs) (zs @ ys)) = (zs @ (list_com xs ys))" + by (induct_tac zs, simp+) + +lemma list_inter_append [simp]: "((xs @ zs) \ (ys @ zs)) = ((xs \ ys) @ zs)" + by (simp add:list_com_rev_def) + +lemma list_diff_djoin_pre: + "\ e es a as. list_diff xs ys = e#es \ list_diff ys xs = a#as \ (\ zs zs'. (list_diff (xs @ zs) (ys @ zs') = [e]@es@zs))" + (is "?P xs ys") + by (rule_tac P = ?P in cmp.induct, simp+) + +lemma list_diff_djoin_rev_pre: + "\ e es a as. xs \ ys = rev (e#es) \ ys \ xs = rev (a#as) \ (\ zs zs'. ((zs @ xs) \ (zs' @ ys) = rev ([e]@es@rev zs)))" + apply (simp only: list_diff_rev_def, clarify) + apply (insert list_diff_djoin_pre, atomize) + apply (erule_tac x = "rev xs" in allE) + apply (erule_tac x = "rev ys" in allE) + apply (erule_tac x = "e" in allE) + apply (erule_tac x = "es" in allE) + apply (erule_tac x = "a" in allE) + apply (erule_tac x = "as" in allE) + by simp + +lemma list_diff_djoin_rev: + "xs \ ys = es @ [e] \ ys \ xs = as @ [a] \ zs @ xs \ zs' @ ys = zs @ es @ [e]" + apply (insert list_diff_djoin_rev_pre [rule_format, simplified]) + apply (clarsimp, atomize) + apply (erule_tac x = "xs" in allE) + apply (erule_tac x = "ys" in allE) + apply (erule_tac x = "rev es" in allE) + apply (erule_tac x = "e" in allE) + apply (erule_tac x = "rev as" in allE) + apply (erule_tac x = "a" in allE) + by auto + +lemmas list_diff_djoin_rev_simplified = conjI [THEN list_diff_djoin_rev, simp] + +lemmas list_diff_djoin = conjI [THEN list_diff_djoin_pre [rule_format], simp] + +lemma list_diff_ext_left [simp]: "(list_diff (zs @ xs) (zs @ ys) = (list_diff xs ys))" + by (induct_tac zs, simp+) + +lemma list_diff_rev_ext_left [simp]: "((xs @ zs \ ys @ zs) = (xs \ ys))" + by (auto simp: list_diff_rev_def) + +declare no_junior_def [simp] + +lemma no_juniorE: "\xs \ ys; \ zs. ys = zs @ xs \ R\ \ R" +proof - + assume h: "xs \ ys" + and h1: "\ zs. ys = zs @ xs \ R" + show "R" + proof - + from h have "rev xs \ rev ys" by (simp) + from this obtain zs where eq_rev: "rev ys = rev xs @ zs" by (auto simp:prefix_def) + show R + proof(rule h1 [where zs = "rev zs"]) + from rev_rev_ident and eq_rev have "rev (rev (ys)) = rev zs @ rev (rev xs)" + by simp + thus "ys = rev zs @ xs" by simp + qed + qed +qed + +lemma no_juniorI: "\ys = zs @ xs\ \ xs \ ys" + by simp + +lemma no_junior_ident [simp]: "xs \ xs" + by simp + +lemma no_junior_expand: "xs \ ys = ((xs \ ys) \ xs = ys)" + by (simp only:no_junior_def is_ancestor_def strict_prefix_def, blast) + +lemma no_junior_same_prefix: " e # \ \ e' # \' \ \ \ \'" +apply (simp add:no_junior_def ) +apply (erule disjE, simp) +apply (simp only:prefix_def) +by (erule exE, rule_tac x = "[e] @ zs" in exI, auto) + +lemma no_junior_noteq: "\\ \ a # \'; \ \ a # \'\ \ \ \ \'" +apply (erule no_juniorE) +by (case_tac zs, simp+) + +lemma is_ancestor_app [simp]: "xs \ ys \ xs \ zs @ ys" + by (auto simp:is_ancestor_def strict_prefix_def) + +lemma is_ancestor_cons [simp]: "xs \ ys \ xs \ a # ys" + by (auto simp:is_ancestor_def strict_prefix_def) + +lemma no_junior_app [simp]: "xs \ ys \ xs \ zs @ ys" + by simp + +lemma is_ancestor_no_junior [simp]: "xs \ ys \ xs \ ys" + by (simp add:is_ancestor_def) + +lemma is_ancestor_y [simp]: "ys \ y#ys" + by (simp add:is_ancestor_def strict_prefix_def) + +lemma no_junior_cons [simp]: "xs \ ys \ xs \ (y#ys)" + by (unfold no_junior_expand, auto) + +lemma no_junior_anti_sym: "\xs \ ys; ys \ xs\ \ xs = ys" + by simp + +declare no_junior_def [simp del] + +(* djoin:: xs and ys is not the other's tail, not equal either *) +definition djoin :: "'a list \ 'a list \ bool" (infix "\" 50) +where + "xs \ ys \ \ (xs \ ys \ ys \ xs)" + +(* dinj:: function f's returning list is not tailing when paras not equal *) +definition dinj :: "('a \ 'b list) \ bool" +where + "dinj f \ (\ a b. a \ b \ f a \ f b)" + + +(* list_cmp:: list comparison: one is other's prefix or no equal at some position *) +lemma list_cmp: "xs \ ys \ ys \ xs \ (\ zs x y a b. xs = zs @ [a] @ x \ ys = zs @ [b] @ y \ a \ b)" +proof(cases "list_diff xs ys") + assume " list_diff xs ys = []" with list_diff_le show ?thesis by blast +next + fix e es + assume h: "list_diff xs ys = e # es" + show ?thesis + proof(cases "list_diff ys xs") + assume " list_diff ys xs = []" with list_diff_le show ?thesis by blast + next + fix a as assume h1: "list_diff ys xs = (a # as)" + have "xs = (list_com xs ys) @ [e] @ es \ ys = (list_com xs ys) @ [a] @ as \ e \ a" + apply (simp, fold h1, fold h) + apply (simp,subst list_com_commute, simp) + apply (rule_tac list_diff_neq[rule_format]) + by (insert h1, insert h, blast) + thus ?thesis by blast + qed +qed + +(* In fact, this is a case split *) +lemma list_diff_ind: "\list_diff xs ys = [] \ R; list_diff ys xs = [] \ R; + \ e es a as. \list_diff xs ys = e#es; list_diff ys xs = a#as; e \ a\ \ R\ \ R" +proof - + assume h1: "list_diff xs ys = [] \ R" + and h2: "list_diff ys xs = [] \ R" + and h3: "\ e es a as. \list_diff xs ys = e#es; list_diff ys xs = a#as; e \ a\ \ R" + show R + proof(cases "list_diff xs ys") + assume "list_diff xs ys = []" from h1 [OF this] show R . + next + fix e es + assume he: "list_diff xs ys = e#es" + show R + proof(cases "list_diff ys xs") + assume "list_diff ys xs = []" from h2 [OF this] show R . + next + fix a as + assume ha: "list_diff ys xs = a#as" show R + proof(rule h3 [OF he ha]) + from list_diff_neq [rule_format, OF conjI [OF he ha ]] + show "e \ a" . + qed + qed + qed +qed + +lemma list_diff_rev_ind: + "\xs \ ys = [] \ R; ys \ xs = [] \ R; \ e es a as. \xs \ ys = es@[e]; ys \ xs = as@[a]; e \ a\ \ R\ \ R" +proof - + fix xs ys R + assume h1: "xs \ ys = [] \ R" + and h2: "ys \ xs = [] \ R" + and h3: "\ e es a as. \xs \ ys = es@[e]; ys \ xs = as@[a]; e \ a\ \ R" + show R + proof (rule list_diff_ind [where xs = "rev xs" and ys = "rev ys"]) + assume "list_diff (rev xs) (rev ys) = []" thus R by (auto intro:h1 simp:list_diff_rev_def) + next + assume "list_diff (rev ys) (rev xs) = []" thus R by (auto intro:h2 simp:list_diff_rev_def) + next + fix e es a as + assume "list_diff (rev xs) (rev ys) = e # es" + and "list_diff (rev ys) (rev xs) = a # as" + and " e \ a" + thus R by (auto intro:h3 simp:list_diff_rev_def) + qed +qed + +lemma djoin_diff_iff: "(xs \ ys) = (\ e es a as. list_diff (rev xs) (rev ys) = e#es \ list_diff (rev ys) (rev xs) = a#as \ a \ e)" +proof (rule list_diff_ind [where xs = "rev xs" and ys = "rev ys"]) + assume "list_diff (rev xs) (rev ys) = []" + hence "xs \ ys" by (unfold no_junior_def, simp add:list_diff_le) + thus ?thesis + apply (auto simp:djoin_def no_junior_def) + by (fold list_diff_le, simp) +next + assume "list_diff (rev ys) (rev xs) = []" + hence "ys \ xs" by (unfold no_junior_def, simp add:list_diff_le) + thus ?thesis + apply (auto simp:djoin_def no_junior_def) + by (fold list_diff_le, simp) +next + fix e es a as + assume he: "list_diff (rev xs) (rev ys) = e # es" + and ha: "list_diff (rev ys) (rev xs) = a # as" + and hn: "e \ a" + show ?thesis + proof + from he ha hn + show + "\e es a as. list_diff (rev xs) (rev ys) = e # es \ list_diff (rev ys) (rev xs) = a # as \ a \ e" + by blast + next + from he ha hn + show "xs \ ys" + by (auto simp:djoin_def no_junior_def, fold list_diff_le, simp+) + qed +qed + +lemma djoin_diff_rev_iff: "(xs \ ys) = (\ e es a as. xs \ ys = es@[e] \ ys \ xs = as@[a] \ a \ e)" + apply (auto simp:djoin_diff_iff list_diff_rev_def) + apply (rule_tac x = e in exI, safe) + apply (rule_tac x = "rev es" in exI) + apply (rule_tac injD[where f = rev], simp+) + apply (rule_tac x = "a" in exI, safe) + apply (rule_tac x = "rev as" in exI) + apply (rule_tac injD[where f = rev], simp+) + done + +lemma djoin_revE: "\xs \ ys; \e es a as. \xs \ ys = es@[e]; ys \ xs = as@[a]; a \ e\ \ R\ \ R" + by (unfold djoin_diff_rev_iff, blast) + +lemma djoin_append_left[simp, intro]: "xs \ ys \ (zs' @ xs) \ (zs @ ys)" + by (auto simp:djoin_diff_iff intro:list_diff_djoin[simplified]) + +lemma djoin_cons_left[simp]: "xs \ ys \ (e # xs) \ (a # ys)" + by (drule_tac zs' = "[e]" and zs = "[a]" in djoin_append_left, simp) + +lemma djoin_simp_1 [simp]: "xs \ ys \ xs \ (zs @ ys)" + by (drule_tac djoin_append_left [where zs' = "[]"], simp) + +lemma djoin_simp_2 [simp]: "xs \ ys \ (zs' @ xs) \ ys" + by (drule_tac djoin_append_left [where zs = "[]"], simp) + +lemma djoin_append_right[simp]: "xs \ ys \ (xs @ zs) \ (ys @ zs)" + by (simp add:djoin_diff_iff) + +lemma djoin_cons_append[simp]: "xs \ ys \ (x # xs) \ (zs @ ys)" + by (subgoal_tac "[x] @ xs \ zs @ ys", simp, blast) + +lemma djoin_append_cons[simp]: "xs \ ys \ (zs @ xs) \ (y # ys)" + by (subgoal_tac "zs @ xs \ [y] @ ys", simp, blast) + +lemma djoin_neq [simp]: "xs \ ys \ xs \ ys" + by (simp only:djoin_diff_iff, clarsimp) + +lemma djoin_cons [simp]: "e \ a \ e # xs \ a # xs" + by (unfold djoin_diff_iff, simp) + +lemma djoin_append_e [simp]: "e \ a \ (zs @ [e] @ xs) \ (zs' @ [a] @ xs)" + by (unfold djoin_diff_iff, simp) + +lemma djoin_mono [simp]: "\xs \ ys; xs \ xs'; ys \ ys'\ \ xs' \ ys'" +proof(erule_tac djoin_revE,unfold djoin_diff_rev_iff) + fix e es a as + assume hx: "xs \ xs'" + and hy: "ys \ ys'" + and hmx: "xs \ ys = es @ [e]" + and hmy: "ys \ xs = as @ [a]" + and neq: "a \ e" + have "xs' \ ys' = ((xs' \ xs) @ es) @ [e] \ ys' \ xs' = ((ys' \ ys) @ as) @ [a] \ a \ e" + proof - + from hx have heqx: "(xs' \ xs) @ xs = xs'" + by (cut_tac list_com_diff_rev [of xs' xs], subgoal_tac "xs' \ xs = xs", simp+) + moreover from hy have heqy: "(ys' \ ys) @ ys = ys'" + by (cut_tac list_com_diff_rev [of ys' ys], subgoal_tac "ys' \ ys = ys", simp+) + moreover from list_diff_djoin_rev_simplified [OF hmx hmy] + have "((xs' \ xs) @ xs) \ ((ys' \ ys) @ ys) = (xs' \ xs) @ es @ [e]" by simp + moreover from list_diff_djoin_rev_simplified [OF hmy hmx] + have "((ys' \ ys) @ ys) \ ((xs' \ xs) @ xs) = (ys' \ ys) @ as @ [a]" by simp + ultimately show ?thesis by (simp add:neq) + qed + thus "\e es a as. xs' \ ys' = es @ [e] \ ys' \ xs' = as @ [a] \ a \ e" by blast +qed + +lemmas djoin_append_e_simplified [simp] = djoin_append_e [simplified] + +(*<*) +end +(*>*) \ No newline at end of file