add predicate version of lexicographic order on lists
authorAndreas Lochbihler
Wed, 20 Nov 2013 10:59:12 +0100
changeset 559668c0a27b9c1bd
parent 55881 4bc48d713602
child 55967 a2d1522cdd54
add predicate version of lexicographic order on lists
src/HOL/List.thy
     1.1 --- a/src/HOL/List.thy	Wed Nov 20 08:56:54 2013 +0100
     1.2 +++ b/src/HOL/List.thy	Wed Nov 20 10:59:12 2013 +0100
     1.3 @@ -5390,6 +5390,176 @@
     1.4    apply (rule allI, case_tac x, simp, simp) 
     1.5    by blast
     1.6  
     1.7 +text {*
     1.8 +  Predicate version of lexicographic order integrated with Isabelle's order type classes.
     1.9 +  Author: Andreas Lochbihler
    1.10 +*}
    1.11 +
    1.12 +thm not_less
    1.13 +context ord begin
    1.14 +
    1.15 +inductive lexordp :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool"
    1.16 +where
    1.17 +  Nil: "lexordp [] (y # ys)"
    1.18 +| Cons: "x < y \<Longrightarrow> lexordp (x # xs) (y # ys)"
    1.19 +| Cons_eq:
    1.20 +  "\<lbrakk> \<not> x < y; \<not> y < x; lexordp xs ys \<rbrakk> \<Longrightarrow> lexordp (x # xs) (y # ys)"
    1.21 +
    1.22 +lemma lexordp_simps [simp]:
    1.23 +  "lexordp [] ys = (ys \<noteq> [])"
    1.24 +  "lexordp xs [] = False"
    1.25 +  "lexordp (x # xs) (y # ys) \<longleftrightarrow> x < y \<or> \<not> y < x \<and> lexordp xs ys"
    1.26 +by(subst lexordp.simps, fastforce simp add: neq_Nil_conv)+
    1.27 +
    1.28 +inductive lexordp_eq :: "'a list \<Rightarrow> 'a list \<Rightarrow> bool" where
    1.29 +  Nil: "lexordp_eq [] ys"
    1.30 +| Cons: "x < y \<Longrightarrow> lexordp_eq (x # xs) (y # ys)"
    1.31 +| Cons_eq: "\<lbrakk> \<not> x < y; \<not> y < x; lexordp_eq xs ys \<rbrakk> \<Longrightarrow> lexordp_eq (x # xs) (y # ys)"
    1.32 +
    1.33 +lemma lexordp_eq_simps [simp]:
    1.34 +  "lexordp_eq [] ys = True"
    1.35 +  "lexordp_eq xs [] \<longleftrightarrow> xs = []"
    1.36 +  "lexordp_eq (x # xs) [] = False"
    1.37 +  "lexordp_eq (x # xs) (y # ys) \<longleftrightarrow> x < y \<or> \<not> y < x \<and> lexordp_eq xs ys"
    1.38 +by(subst lexordp_eq.simps, fastforce)+
    1.39 +
    1.40 +lemma lexordp_append_rightI: "ys \<noteq> Nil \<Longrightarrow> lexordp xs (xs @ ys)"
    1.41 +by(induct xs)(auto simp add: neq_Nil_conv)
    1.42 +
    1.43 +lemma lexordp_append_left_rightI: "x < y \<Longrightarrow> lexordp (us @ x # xs) (us @ y # ys)"
    1.44 +by(induct us) auto
    1.45 +
    1.46 +lemma lexordp_eq_refl: "lexordp_eq xs xs"
    1.47 +by(induct xs) simp_all
    1.48 +
    1.49 +lemma lexordp_append_leftI: "lexordp us vs \<Longrightarrow> lexordp (xs @ us) (xs @ vs)"
    1.50 +by(induct xs) auto
    1.51 +
    1.52 +lemma lexordp_append_leftD: "\<lbrakk> lexordp (xs @ us) (xs @ vs); \<forall>a. \<not> a < a \<rbrakk> \<Longrightarrow> lexordp us vs"
    1.53 +by(induct xs) auto
    1.54 +
    1.55 +lemma lexordp_irreflexive: 
    1.56 +  assumes irrefl: "\<forall>x. \<not> x < x"
    1.57 +  shows "\<not> lexordp xs xs"
    1.58 +proof
    1.59 +  assume "lexordp xs xs"
    1.60 +  thus False by(induct xs ys\<equiv>xs)(simp_all add: irrefl)
    1.61 +qed
    1.62 +
    1.63 +lemma lexordp_into_lexordp_eq:
    1.64 +  assumes "lexordp xs ys"
    1.65 +  shows "lexordp_eq xs ys"
    1.66 +using assms by induct simp_all
    1.67 +
    1.68 +end
    1.69 +
    1.70 +declare ord.lexordp_simps [simp, code]
    1.71 +declare ord.lexordp_eq_simps [code, simp]
    1.72 +
    1.73 +lemma lexord_code [code, code_unfold]: "lexordp = ord.lexordp less"
    1.74 +unfolding lexordp_def ord.lexordp_def ..
    1.75 +
    1.76 +context order begin
    1.77 +
    1.78 +lemma lexordp_antisym:
    1.79 +  assumes "lexordp xs ys" "lexordp ys xs"
    1.80 +  shows False
    1.81 +using assms by induct auto
    1.82 +
    1.83 +lemma lexordp_irreflexive': "\<not> lexordp xs xs"
    1.84 +by(rule lexordp_irreflexive) simp
    1.85 +
    1.86 +end
    1.87 +
    1.88 +context linorder begin
    1.89 +
    1.90 +lemma lexordp_cases [consumes 1, case_names Nil Cons Cons_eq, cases pred: lexordp]:
    1.91 +  assumes "lexordp xs ys"
    1.92 +  obtains (Nil) y ys' where "xs = []" "ys = y # ys'"
    1.93 +  | (Cons) x xs' y ys' where "xs = x # xs'" "ys = y # ys'" "x < y"
    1.94 +  | (Cons_eq) x xs' ys' where "xs = x # xs'" "ys = x # ys'" "lexordp xs' ys'"
    1.95 +using assms by cases (fastforce simp add: not_less_iff_gr_or_eq)+
    1.96 +
    1.97 +lemma lexordp_induct [consumes 1, case_names Nil Cons Cons_eq, induct pred: lexordp]:
    1.98 +  assumes major: "lexordp xs ys"
    1.99 +  and Nil: "\<And>y ys. P [] (y # ys)"
   1.100 +  and Cons: "\<And>x xs y ys. x < y \<Longrightarrow> P (x # xs) (y # ys)"
   1.101 +  and Cons_eq: "\<And>x xs ys. \<lbrakk> lexordp xs ys; P xs ys \<rbrakk> \<Longrightarrow> P (x # xs) (x # ys)"
   1.102 +  shows "P xs ys"
   1.103 +using major by induct (simp_all add: Nil Cons not_less_iff_gr_or_eq Cons_eq)
   1.104 +
   1.105 +lemma lexordp_iff:
   1.106 +  "lexordp xs ys \<longleftrightarrow> (\<exists>x vs. ys = xs @ x # vs) \<or> (\<exists>us a b vs ws. a < b \<and> xs = us @ a # vs \<and> ys = us @ b # ws)"
   1.107 +  (is "?lhs = ?rhs")
   1.108 +proof
   1.109 +  assume ?lhs thus ?rhs
   1.110 +  proof induct
   1.111 +    case Cons_eq thus ?case by simp (metis append.simps(2))
   1.112 +  qed(fastforce intro: disjI2 del: disjCI intro: exI[where x="[]"])+
   1.113 +next
   1.114 +  assume ?rhs thus ?lhs
   1.115 +    by(auto intro: lexordp_append_leftI[where us="[]", simplified] lexordp_append_leftI)
   1.116 +qed
   1.117 +
   1.118 +lemma lexordp_conv_lexord:
   1.119 +  "lexordp xs ys \<longleftrightarrow> (xs, ys) \<in> lexord {(x, y). x < y}"
   1.120 +by(simp add: lexordp_iff lexord_def)
   1.121 +
   1.122 +lemma lexordp_eq_antisym: 
   1.123 +  assumes "lexordp_eq xs ys" "lexordp_eq ys xs" 
   1.124 +  shows "xs = ys"
   1.125 +using assms by induct simp_all
   1.126 +
   1.127 +lemma lexordp_eq_trans:
   1.128 +  assumes "lexordp_eq xs ys" and "lexordp_eq ys zs"
   1.129 +  shows "lexordp_eq xs zs"
   1.130 +using assms
   1.131 +apply(induct arbitrary: zs)
   1.132 +apply(case_tac [2-3] zs)
   1.133 +apply auto
   1.134 +done
   1.135 +
   1.136 +lemma lexordp_trans:
   1.137 +  assumes "lexordp xs ys" "lexordp ys zs"
   1.138 +  shows "lexordp xs zs"
   1.139 +using assms
   1.140 +apply(induct arbitrary: zs)
   1.141 +apply(case_tac [2-3] zs)
   1.142 +apply auto
   1.143 +done
   1.144 +
   1.145 +lemma lexordp_linear: "lexordp xs ys \<or> xs = ys \<or> lexordp ys xs"
   1.146 +proof(induct xs arbitrary: ys)
   1.147 +  case Nil thus ?case by(cases ys) simp_all
   1.148 +next
   1.149 +  case Cons thus ?case by(cases ys) auto
   1.150 +qed
   1.151 +
   1.152 +lemma lexordp_conv_lexordp_eq: "lexordp xs ys \<longleftrightarrow> lexordp_eq xs ys \<and> \<not> lexordp_eq ys xs"
   1.153 +  (is "?lhs \<longleftrightarrow> ?rhs")
   1.154 +proof
   1.155 +  assume ?lhs
   1.156 +  moreover hence "\<not> lexordp_eq ys xs" by induct simp_all
   1.157 +  ultimately show ?rhs by(simp add: lexordp_into_lexordp_eq)
   1.158 +next
   1.159 +  assume ?rhs
   1.160 +  hence "lexordp_eq xs ys" "\<not> lexordp_eq ys xs" by simp_all
   1.161 +  thus ?lhs by induct simp_all
   1.162 +qed
   1.163 +
   1.164 +lemma lexordp_eq_conv_lexord: "lexordp_eq xs ys \<longleftrightarrow> xs = ys \<or> lexordp xs ys"
   1.165 +by(auto simp add: lexordp_conv_lexordp_eq lexordp_eq_refl dest: lexordp_eq_antisym)
   1.166 +
   1.167 +lemma lexordp_eq_linear: "lexordp_eq xs ys \<or> lexordp_eq ys xs"
   1.168 +apply(induct xs arbitrary: ys)
   1.169 +apply(case_tac [!] ys)
   1.170 +apply auto
   1.171 +done
   1.172 +
   1.173 +lemma lexordp_linorder: "class.linorder lexordp_eq lexordp"
   1.174 +by unfold_locales(auto simp add: lexordp_conv_lexordp_eq lexordp_eq_refl lexordp_eq_antisym intro: lexordp_eq_trans del: disjCI intro: lexordp_eq_linear)
   1.175 +
   1.176 +end
   1.177  
   1.178  subsubsection {* Lexicographic combination of measure functions *}
   1.179