src/HOL/Orderings.thy
changeset 21329 7338206d75f1
parent 21259 63ab016c99ca
child 21383 17e6275e13f5
equal deleted inserted replaced
21328:73bb86d0f483 21329:7338206d75f1
     1 (*  Title:      HOL/Orderings.thy
     1 (*  Title:      HOL/Orderings.thy
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Tobias Nipkow, Markus Wenzel, and Larry Paulson
     3     Author:     Tobias Nipkow, Markus Wenzel, and Larry Paulson
     4 *)
     4 *)
     5 
     5 
     6 header {* Abstract orderings *}
     6 header {* Syntactic and abstract orders *}
     7 
     7 
     8 theory Orderings
     8 theory Orderings
     9 imports Code_Generator
     9 imports HOL
    10 begin
    10 begin
    11 
    11 
    12 section {* Abstract orderings *}
    12 section {* Abstract orders *}
    13 
    13 
    14 subsection {* Order signatures *}
    14 subsection {* Order syntax *}
    15 
    15 
    16 class ord =
    16 class ord =
    17   fixes less_eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
    17   fixes less_eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
    18     and less :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
    18     and less :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
    19 begin
    19 begin
    65   
    65   
    66 notation (xsymbols)
    66 notation (xsymbols)
    67   greater_eq  (infix "\<ge>" 50)
    67   greater_eq  (infix "\<ge>" 50)
    68 
    68 
    69 
    69 
    70 subsection {* Partial orderings *}
    70 subsection {* Quasiorders (preorders) *}
    71 
    71 
    72 locale partial_order =
    72 locale preorder =
    73   fixes below :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infixl "\<sqsubseteq>" 50)
    73   fixes below :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infixl "\<sqsubseteq>" 50)
    74   fixes less :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infixl "\<sqsubset>" 50)
    74   fixes less :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infixl "\<sqsubset>" 50)
    75   assumes refl [iff]: "x \<sqsubseteq> x"
    75   assumes refl [iff]: "x \<sqsubseteq> x"
    76   and trans: "x \<sqsubseteq> y \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> x \<sqsubseteq> z"
    76   and trans: "x \<sqsubseteq> y \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> x \<sqsubseteq> z"
    77   and antisym: "x \<sqsubseteq> y \<Longrightarrow> y \<sqsubseteq> x \<Longrightarrow> x = y"
       
    78   and less_le: "x \<sqsubset> y \<longleftrightarrow> x \<sqsubseteq> y \<and> x \<noteq> y"
    77   and less_le: "x \<sqsubset> y \<longleftrightarrow> x \<sqsubseteq> y \<and> x \<noteq> y"
    79 begin
    78 begin
    80 
    79 
    81 abbreviation (input)
    80 abbreviation (input)
    82   greater_eq (infixl "\<sqsupseteq>" 50)
    81   greater_eq (infixl "\<sqsupseteq>" 50)
    83   "x \<sqsupseteq> y \<equiv> y \<sqsubseteq> x"
    82   "x \<sqsupseteq> y \<equiv> y \<sqsubseteq> x"
    84 
    83 
    85 abbreviation (input)
    84 abbreviation (input)
    86   greater (infixl "\<sqsupset>" 50)
    85   greater (infixl "\<sqsupset>" 50)
    87   "x \<sqsupset> y \<equiv> y \<sqsubset> x"
    86   "x \<sqsupset> y \<equiv> y \<sqsubset> x"
       
    87 
       
    88 text {* Reflexivity. *}
       
    89 
       
    90 lemma eq_refl: "x = y \<Longrightarrow> x \<sqsubseteq> y"
       
    91     -- {* This form is useful with the classical reasoner. *}
       
    92   by (erule ssubst) (rule refl)
       
    93 
       
    94 lemma less_irrefl [iff]: "\<not> x \<sqsubset> x"
       
    95   by (simp add: less_le)
       
    96 
       
    97 lemma le_less: "x \<sqsubseteq> y \<longleftrightarrow> x \<sqsubset> y \<or> x = y"
       
    98     -- {* NOT suitable for iff, since it can cause PROOF FAILED. *}
       
    99   by (simp add: less_le) blast
       
   100 
       
   101 lemma le_imp_less_or_eq: "x \<sqsubseteq> y \<Longrightarrow> x \<sqsubset> y \<or> x = y"
       
   102   unfolding less_le by blast
       
   103 
       
   104 lemma less_imp_le: "x \<sqsubset> y \<Longrightarrow> x \<sqsubseteq> y"
       
   105   unfolding less_le by blast
       
   106 
       
   107 lemma less_imp_neq: "x \<sqsubset> y \<Longrightarrow> x \<noteq> y"
       
   108   by (erule contrapos_pn, erule subst, rule less_irrefl)
       
   109 
       
   110 
       
   111 text {* Useful for simplification, but too risky to include by default. *}
       
   112 
       
   113 lemma less_imp_not_eq: "x \<sqsubset> y \<Longrightarrow> (x = y) \<longleftrightarrow> False"
       
   114   by auto
       
   115 
       
   116 lemma less_imp_not_eq2: "x \<sqsubset> y \<Longrightarrow> (y = x) \<longleftrightarrow> False"
       
   117   by auto
       
   118 
       
   119 
       
   120 text {* Transitivity rules for calculational reasoning *}
       
   121 
       
   122 lemma neq_le_trans: "\<lbrakk> a \<noteq> b; a \<sqsubseteq> b \<rbrakk> \<Longrightarrow> a \<sqsubset> b"
       
   123   by (simp add: less_le)
       
   124 
       
   125 lemma le_neq_trans: "\<lbrakk> a \<sqsubseteq> b; a \<noteq> b \<rbrakk> \<Longrightarrow> a \<sqsubset> b"
       
   126   by (simp add: less_le)
       
   127 
       
   128 end
       
   129 
       
   130 
       
   131 subsection {* Partial orderings *}
       
   132 
       
   133 locale partial_order = preorder + 
       
   134   assumes antisym: "x \<sqsubseteq> y \<Longrightarrow> y \<sqsubseteq> x \<Longrightarrow> x = y"
       
   135 
       
   136 context partial_order
       
   137 begin
       
   138 
       
   139 text {* Asymmetry. *}
       
   140 
       
   141 lemma less_not_sym: "x \<sqsubset> y \<Longrightarrow> \<not> (y \<sqsubset> x)"
       
   142   by (simp add: less_le antisym)
       
   143 
       
   144 lemma less_asym: "x \<sqsubset> y \<Longrightarrow> (\<not> P \<Longrightarrow> y \<sqsubset> x) \<Longrightarrow> P"
       
   145   by (drule less_not_sym, erule contrapos_np) simp
       
   146 
       
   147 lemma eq_iff: "x = y \<longleftrightarrow> x \<sqsubseteq> y \<and> y \<sqsubseteq> x"
       
   148   by (blast intro: antisym)
       
   149 
       
   150 lemma antisym_conv: "y \<sqsubseteq> x \<Longrightarrow> x \<sqsubseteq> y \<longleftrightarrow> x = y"
       
   151   by (blast intro: antisym)
       
   152 
       
   153 lemma less_imp_neq: "x \<sqsubset> y \<Longrightarrow> x \<noteq> y"
       
   154   by (erule contrapos_pn, erule subst, rule less_irrefl)
       
   155 
       
   156 
       
   157 text {* Transitivity. *}
       
   158 
       
   159 lemma less_trans: "\<lbrakk> x \<sqsubset> y; y \<sqsubset> z \<rbrakk> \<Longrightarrow> x \<sqsubset> z"
       
   160   by (simp add: less_le) (blast intro: trans antisym)
       
   161 
       
   162 lemma le_less_trans: "\<lbrakk> x \<sqsubseteq> y; y \<sqsubset> z \<rbrakk> \<Longrightarrow> x \<sqsubset> z"
       
   163   by (simp add: less_le) (blast intro: trans antisym)
       
   164 
       
   165 lemma less_le_trans: "\<lbrakk> x \<sqsubset> y; y \<sqsubseteq> z \<rbrakk> \<Longrightarrow> x \<sqsubset> z"
       
   166   by (simp add: less_le) (blast intro: trans antisym)
       
   167 
       
   168 
       
   169 text {* Useful for simplification, but too risky to include by default. *}
       
   170 
       
   171 lemma less_imp_not_less: "x \<sqsubset> y \<Longrightarrow> (\<not> y \<sqsubset> x) \<longleftrightarrow> True"
       
   172   by (blast elim: less_asym)
       
   173 
       
   174 lemma less_imp_triv: "x \<sqsubset> y \<Longrightarrow> (y \<sqsubset> x \<longrightarrow> P) \<longleftrightarrow> True"
       
   175   by (blast elim: less_asym)
       
   176 
       
   177 
       
   178 text {* Transitivity rules for calculational reasoning *}
       
   179 
       
   180 lemma less_asym': "\<lbrakk> a \<sqsubset> b; b \<sqsubset> a \<rbrakk> \<Longrightarrow> P"
       
   181   by (rule less_asym)
    88 
   182 
    89 end
   183 end
    90 
   184 
    91 axclass order < ord
   185 axclass order < ord
    92   order_refl [iff]: "x <= x"
   186   order_refl [iff]: "x <= x"
    94   order_antisym: "x <= y ==> y <= x ==> x = y"
   188   order_antisym: "x <= y ==> y <= x ==> x = y"
    95   order_less_le: "(x < y) = (x <= y & x ~= y)"
   189   order_less_le: "(x < y) = (x <= y & x ~= y)"
    96 
   190 
    97 interpretation order:
   191 interpretation order:
    98   partial_order ["op \<le> \<Colon> 'a\<Colon>order \<Rightarrow> 'a \<Rightarrow> bool" "op < \<Colon> 'a\<Colon>order \<Rightarrow> 'a \<Rightarrow> bool"]
   192   partial_order ["op \<le> \<Colon> 'a\<Colon>order \<Rightarrow> 'a \<Rightarrow> bool" "op < \<Colon> 'a\<Colon>order \<Rightarrow> 'a \<Rightarrow> bool"]
    99 apply(rule partial_order.intro)
   193 apply unfold_locales
   100 apply(rule order_refl, erule (1) order_trans, erule (1) order_antisym, rule order_less_le)
   194 apply (rule order_refl)
       
   195 apply (erule (1) order_trans)
       
   196 apply (rule order_less_le)
       
   197 apply (erule (1) order_antisym)
   101 done
   198 done
   102 
   199 
   103 context partial_order
   200 
   104 begin
   201 subsection {* Linear (total) orders *}
   105 
   202 
   106 text {* Reflexivity. *}
   203 locale linorder = partial_order +
   107 
       
   108 lemma eq_refl: "x = y \<Longrightarrow> x \<sqsubseteq> y"
       
   109     -- {* This form is useful with the classical reasoner. *}
       
   110   by (erule ssubst) (rule refl)
       
   111 
       
   112 lemma less_irrefl [iff]: "\<not> x \<sqsubset> x"
       
   113   by (simp add: less_le)
       
   114 
       
   115 lemma le_less: "x \<sqsubseteq> y \<longleftrightarrow> x \<sqsubset> y \<or> x = y"
       
   116     -- {* NOT suitable for iff, since it can cause PROOF FAILED. *}
       
   117   by (simp add: less_le) blast
       
   118 
       
   119 lemma le_imp_less_or_eq: "x \<sqsubseteq> y \<Longrightarrow> x \<sqsubset> y \<or> x = y"
       
   120   unfolding less_le by blast
       
   121 
       
   122 lemma less_imp_le: "x \<sqsubset> y \<Longrightarrow> x \<sqsubseteq> y"
       
   123   unfolding less_le by blast
       
   124 
       
   125 
       
   126 text {* Asymmetry. *}
       
   127 
       
   128 lemma less_not_sym: "x \<sqsubset> y \<Longrightarrow> \<not> (y \<sqsubset> x)"
       
   129   by (simp add: less_le antisym)
       
   130 
       
   131 lemma less_asym: "x \<sqsubset> y \<Longrightarrow> (\<not> P \<Longrightarrow> y \<sqsubset> x) \<Longrightarrow> P"
       
   132   by (drule less_not_sym, erule contrapos_np) simp
       
   133 
       
   134 lemma eq_iff: "x = y \<longleftrightarrow> x \<sqsubseteq> y \<and> y \<sqsubseteq> x"
       
   135   by (blast intro: antisym)
       
   136 
       
   137 lemma antisym_conv: "y \<sqsubseteq> x \<Longrightarrow> x \<sqsubseteq> y \<longleftrightarrow> x = y"
       
   138   by (blast intro: antisym)
       
   139 
       
   140 lemma less_imp_neq: "x \<sqsubset> y \<Longrightarrow> x \<noteq> y"
       
   141   by (erule contrapos_pn, erule subst, rule less_irrefl)
       
   142 
       
   143 
       
   144 text {* Transitivity. *}
       
   145 
       
   146 lemma less_trans: "\<lbrakk> x \<sqsubset> y; y \<sqsubset> z \<rbrakk> \<Longrightarrow> x \<sqsubset> z"
       
   147   by (simp add: less_le) (blast intro: trans antisym)
       
   148 
       
   149 lemma le_less_trans: "\<lbrakk> x \<sqsubseteq> y; y \<sqsubset> z \<rbrakk> \<Longrightarrow> x \<sqsubset> z"
       
   150   by (simp add: less_le) (blast intro: trans antisym)
       
   151 
       
   152 lemma less_le_trans: "\<lbrakk> x \<sqsubset> y; y \<sqsubseteq> z \<rbrakk> \<Longrightarrow> x \<sqsubset> z"
       
   153   by (simp add: less_le) (blast intro: trans antisym)
       
   154 
       
   155 
       
   156 text {* Useful for simplification, but too risky to include by default. *}
       
   157 
       
   158 lemma less_imp_not_less: "x \<sqsubset> y \<Longrightarrow> (\<not> y \<sqsubset> x) \<longleftrightarrow> True"
       
   159   by (blast elim: less_asym)
       
   160 
       
   161 lemma less_imp_triv: "x \<sqsubset> y \<Longrightarrow> (y \<sqsubset> x \<longrightarrow> P) \<longleftrightarrow> True"
       
   162   by (blast elim: less_asym)
       
   163 
       
   164 lemma less_imp_not_eq: "x \<sqsubset> y \<Longrightarrow> (x = y) \<longleftrightarrow> False"
       
   165   by auto
       
   166 
       
   167 lemma less_imp_not_eq2: "x \<sqsubset> y \<Longrightarrow> (y = x) \<longleftrightarrow> False"
       
   168   by auto
       
   169 
       
   170 
       
   171 text {* Transitivity rules for calculational reasoning *}
       
   172 
       
   173 lemma neq_le_trans: "\<lbrakk> a \<noteq> b; a \<sqsubseteq> b \<rbrakk> \<Longrightarrow> a \<sqsubset> b"
       
   174   by (simp add: less_le)
       
   175 
       
   176 lemma le_neq_trans: "\<lbrakk> a \<sqsubseteq> b; a \<noteq> b \<rbrakk> \<Longrightarrow> a \<sqsubset> b"
       
   177   by (simp add: less_le)
       
   178 
       
   179 lemma less_asym': "\<lbrakk> a \<sqsubset> b; b \<sqsubset> a \<rbrakk> \<Longrightarrow> P"
       
   180   by (rule less_asym)
       
   181 
       
   182 end
       
   183 
       
   184 
       
   185 subsection {* Linear (total) orderings *}
       
   186 
       
   187 locale linear_order = partial_order +
       
   188   assumes linear: "x \<sqsubseteq> y \<or> y \<sqsubseteq> x"
   204   assumes linear: "x \<sqsubseteq> y \<or> y \<sqsubseteq> x"
   189 
   205 
   190 axclass linorder < order
   206 context linorder
   191   linorder_linear: "x <= y | y <= x"
       
   192 
       
   193 interpretation linorder:
       
   194   linear_order ["op \<le> \<Colon> 'a\<Colon>linorder \<Rightarrow> 'a \<Rightarrow> bool" "op < \<Colon> 'a\<Colon>linorder \<Rightarrow> 'a \<Rightarrow> bool"]
       
   195   by unfold_locales (rule linorder_linear)
       
   196 
       
   197 context linear_order
       
   198 begin
   207 begin
   199 
   208 
   200 lemma trichotomy: "x \<sqsubset> y \<or> x = y \<or> y \<sqsubset> x"
   209 lemma trichotomy: "x \<sqsubset> y \<or> x = y \<or> y \<sqsubset> x"
   201   unfolding less_le using less_le linear by blast 
   210   unfolding less_le using less_le linear by blast 
   202 
   211 
   246 (*FIXME inappropriate name (or delete altogether)*)
   255 (*FIXME inappropriate name (or delete altogether)*)
   247 lemma not_leE: "\<not> y \<sqsubseteq> x \<Longrightarrow> x \<sqsubset> y"
   256 lemma not_leE: "\<not> y \<sqsubseteq> x \<Longrightarrow> x \<sqsubset> y"
   248   unfolding not_le .
   257   unfolding not_le .
   249 
   258 
   250 end
   259 end
       
   260 
       
   261 axclass linorder < order
       
   262   linorder_linear: "x <= y | y <= x"
       
   263 
       
   264 interpretation linorder:
       
   265   linorder ["op \<le> \<Colon> 'a\<Colon>linorder \<Rightarrow> 'a \<Rightarrow> bool" "op < \<Colon> 'a\<Colon>linorder \<Rightarrow> 'a \<Rightarrow> bool"]
       
   266   by unfold_locales (rule linorder_linear)
   251 
   267 
   252 
   268 
   253 subsection {* Name duplicates *}
   269 subsection {* Name duplicates *}
   254 
   270 
   255 lemmas order_eq_refl [where 'b = "?'a::order"] = order.eq_refl
   271 lemmas order_eq_refl [where 'b = "?'a::order"] = order.eq_refl