1191783Srmacklem(* Title: HOL/Orderings.thy 2191783Srmacklem Author: Tobias Nipkow, Markus Wenzel, and Larry Paulson 3191783Srmacklem*) 4191783Srmacklem 5191783Srmacklemsection \<open>Abstract orderings\<close> 6191783Srmacklem 7191783Srmacklemtheory Orderings 8191783Srmacklemimports HOL 9191783Srmacklemkeywords "print_orders" :: diag 10191783Srmacklembegin 11191783Srmacklem 12191783SrmacklemML_file "~~/src/Provers/order.ML" 13191783SrmacklemML_file "~~/src/Provers/quasi.ML" (* FIXME unused? *) 14191783Srmacklem 15191783Srmacklemsubsection \<open>Abstract ordering\<close> 16191783Srmacklem 17191783Srmacklemlocale ordering = 18191783Srmacklem fixes less_eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infix "\<^bold>\<le>" 50) 19191783Srmacklem and less :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infix "\<^bold><" 50) 20191783Srmacklem assumes strict_iff_order: "a \<^bold>< b \<longleftrightarrow> a \<^bold>\<le> b \<and> a \<noteq> b" 21191783Srmacklem assumes refl: "a \<^bold>\<le> a" \<comment> \<open>not \<open>iff\<close>: makes problems due to multiple (dual) interpretations\<close> 22191783Srmacklem and antisym: "a \<^bold>\<le> b \<Longrightarrow> b \<^bold>\<le> a \<Longrightarrow> a = b" 23191783Srmacklem and trans: "a \<^bold>\<le> b \<Longrightarrow> b \<^bold>\<le> c \<Longrightarrow> a \<^bold>\<le> c" 24191783Srmacklembegin 25191783Srmacklem 26191783Srmacklemlemma strict_implies_order: 27191783Srmacklem "a \<^bold>< b \<Longrightarrow> a \<^bold>\<le> b" 28191783Srmacklem by (simp add: strict_iff_order) 29191783Srmacklem 30191783Srmacklemlemma strict_implies_not_eq: 31191783Srmacklem "a \<^bold>< b \<Longrightarrow> a \<noteq> b" 32191783Srmacklem by (simp add: strict_iff_order) 33191783Srmacklem 34191783Srmacklemlemma not_eq_order_implies_strict: 35191783Srmacklem "a \<noteq> b \<Longrightarrow> a \<^bold>\<le> b \<Longrightarrow> a \<^bold>< b" 36191783Srmacklem by (simp add: strict_iff_order) 37191783Srmacklem 38191783Srmacklemlemma order_iff_strict: 39191783Srmacklem "a \<^bold>\<le> b \<longleftrightarrow> a \<^bold>< b \<or> a = b" 40191783Srmacklem by (auto simp add: strict_iff_order refl) 41191783Srmacklem 42191783Srmacklemlemma irrefl: \<comment> \<open>not \<open>iff\<close>: makes problems due to multiple (dual) interpretations\<close> 43191783Srmacklem "\<not> a \<^bold>< a" 44191783Srmacklem by (simp add: strict_iff_order) 45191783Srmacklem 46191783Srmacklemlemma asym: 47191783Srmacklem "a \<^bold>< b \<Longrightarrow> b \<^bold>< a \<Longrightarrow> False" 48244042Srmacklem by (auto simp add: strict_iff_order intro: antisym) 49191783Srmacklem 50191783Srmacklemlemma strict_trans1: 51191783Srmacklem "a \<^bold>\<le> b \<Longrightarrow> b \<^bold>< c \<Longrightarrow> a \<^bold>< c" 52191783Srmacklem by (auto simp add: strict_iff_order intro: trans antisym) 53191783Srmacklem 54244042Srmacklemlemma strict_trans2: 55191783Srmacklem "a \<^bold>< b \<Longrightarrow> b \<^bold>\<le> c \<Longrightarrow> a \<^bold>< c" 56191783Srmacklem by (auto simp add: strict_iff_order intro: trans antisym) 57191783Srmacklem 58191783Srmacklemlemma strict_trans: 59191783Srmacklem "a \<^bold>< b \<Longrightarrow> b \<^bold>< c \<Longrightarrow> a \<^bold>< c" 60191783Srmacklem by (auto intro: strict_trans1 strict_implies_order) 61191783Srmacklem 62191783Srmacklemend 63191783Srmacklem 64191783Srmacklemtext \<open>Alternative introduction rule with bias towards strict order\<close> 65191783Srmacklem 66191783Srmacklemlemma ordering_strictI: 67192121Srmacklem fixes less_eq (infix "\<^bold>\<le>" 50) 68191783Srmacklem and less (infix "\<^bold><" 50) 69191783Srmacklem assumes less_eq_less: "\<And>a b. a \<^bold>\<le> b \<longleftrightarrow> a \<^bold>< b \<or> a = b" 70191783Srmacklem assumes asym: "\<And>a b. a \<^bold>< b \<Longrightarrow> \<not> b \<^bold>< a" 71191783Srmacklem assumes irrefl: "\<And>a. \<not> a \<^bold>< a" 72191783Srmacklem assumes trans: "\<And>a b c. a \<^bold>< b \<Longrightarrow> b \<^bold>< c \<Longrightarrow> a \<^bold>< c" 73191783Srmacklem shows "ordering less_eq less" 74191783Srmacklemproof 75191783Srmacklem fix a b 76191783Srmacklem show "a \<^bold>< b \<longleftrightarrow> a \<^bold>\<le> b \<and> a \<noteq> b" 77191783Srmacklem by (auto simp add: less_eq_less asym irrefl) 78191783Srmacklemnext 79191783Srmacklem fix a 80191783Srmacklem show "a \<^bold>\<le> a" 81191783Srmacklem by (auto simp add: less_eq_less) 82191783Srmacklemnext 83191783Srmacklem fix a b c 84191783Srmacklem assume "a \<^bold>\<le> b" and "b \<^bold>\<le> c" then show "a \<^bold>\<le> c" 85191783Srmacklem by (auto simp add: less_eq_less intro: trans) 86249592Skennext 87191783Srmacklem fix a b 88191783Srmacklem assume "a \<^bold>\<le> b" and "b \<^bold>\<le> a" then show "a = b" 89191783Srmacklem by (auto simp add: less_eq_less asym) 90191783Srmacklemqed 91191783Srmacklem 92191783Srmacklemlemma ordering_dualI: 93191783Srmacklem fixes less_eq (infix "\<^bold>\<le>" 50) 94244042Srmacklem and less (infix "\<^bold><" 50) 95191783Srmacklem assumes "ordering (\<lambda>a b. b \<^bold>\<le> a) (\<lambda>a b. b \<^bold>< a)" 96192121Srmacklem shows "ordering less_eq less" 97191783Srmacklemproof - 98191783Srmacklem from assms interpret ordering "\<lambda>a b. b \<^bold>\<le> a" "\<lambda>a b. b \<^bold>< a" . 99191783Srmacklem show ?thesis 100191783Srmacklem by standard (auto simp: strict_iff_order refl intro: antisym trans) 101191783Srmacklemqed 102192121Srmacklem 103192121Srmacklemlocale ordering_top = ordering + 104191783Srmacklem fixes top :: "'a" ("\<^bold>\<top>") 105191783Srmacklem assumes extremum [simp]: "a \<^bold>\<le> \<^bold>\<top>" 106191783Srmacklembegin 107191783Srmacklem 108191783Srmacklemlemma extremum_uniqueI: 109191783Srmacklem "\<^bold>\<top> \<^bold>\<le> a \<Longrightarrow> a = \<^bold>\<top>" 110191783Srmacklem by (rule antisym) auto 111191783Srmacklem 112191783Srmacklemlemma extremum_unique: 113191783Srmacklem "\<^bold>\<top> \<^bold>\<le> a \<longleftrightarrow> a = \<^bold>\<top>" 114191783Srmacklem by (auto intro: antisym) 115191783Srmacklem 116191783Srmacklemlemma extremum_strict [simp]: 117191783Srmacklem "\<not> (\<^bold>\<top> \<^bold>< a)" 118191783Srmacklem using extremum [of a] by (auto simp add: order_iff_strict intro: asym irrefl) 119191783Srmacklem 120191783Srmacklemlemma not_eq_extremum: 121191783Srmacklem "a \<noteq> \<^bold>\<top> \<longleftrightarrow> a \<^bold>< \<^bold>\<top>" 122191783Srmacklem by (auto simp add: order_iff_strict intro: not_eq_order_implies_strict extremum) 123191783Srmacklem 124191783Srmacklemend 125191783Srmacklem 126191783Srmacklem 127191783Srmacklemsubsection \<open>Syntactic orders\<close> 128191783Srmacklem 129191783Srmacklemclass ord = 130191783Srmacklem fixes less_eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool" 131191783Srmacklem and less :: "'a \<Rightarrow> 'a \<Rightarrow> bool" 132191783Srmacklembegin 133191783Srmacklem 134191783Srmacklemnotation 135191783Srmacklem less_eq ("'(\<le>')") and 136191783Srmacklem less_eq ("(_/ \<le> _)" [51, 51] 50) and 137191783Srmacklem less ("'(<')") and 138244042Srmacklem less ("(_/ < _)" [51, 51] 50) 139191783Srmacklem 140244042Srmacklemabbreviation (input) 141244042Srmacklem greater_eq (infix "\<ge>" 50) 142191783Srmacklem where "x \<ge> y \<equiv> y \<le> x" 143191783Srmacklem 144191783Srmacklemabbreviation (input) 145191783Srmacklem greater (infix ">" 50) 146191783Srmacklem where "x > y \<equiv> y < x" 147191783Srmacklem 148191783Srmacklemnotation (ASCII) 149191783Srmacklem less_eq ("'(<=')") and 150191783Srmacklem less_eq ("(_/ <= _)" [51, 51] 50) 151191783Srmacklem 152191783Srmacklemnotation (input) 153191783Srmacklem greater_eq (infix ">=" 50) 154191783Srmacklem 155191783Srmacklemend 156191783Srmacklem 157191783Srmacklem 158191783Srmacklemsubsection \<open>Quasi orders\<close> 159191783Srmacklem 160191783Srmacklemclass preorder = ord + 161191783Srmacklem assumes less_le_not_le: "x < y \<longleftrightarrow> x \<le> y \<and> \<not> (y \<le> x)" 162191783Srmacklem and order_refl [iff]: "x \<le> x" 163191783Srmacklem and order_trans: "x \<le> y \<Longrightarrow> y \<le> z \<Longrightarrow> x \<le> z" 164191783Srmacklembegin 165191783Srmacklem 166191783Srmacklemtext \<open>Reflexivity.\<close> 167191783Srmacklem 168191783Srmacklemlemma eq_refl: "x = y \<Longrightarrow> x \<le> y" 169191783Srmacklem \<comment> \<open>This form is useful with the classical reasoner.\<close> 170191783Srmacklemby (erule ssubst) (rule order_refl) 171191783Srmacklem 172191783Srmacklemlemma less_irrefl [iff]: "\<not> x < x" 173191783Srmacklemby (simp add: less_le_not_le) 174191783Srmacklem 175191783Srmacklemlemma less_imp_le: "x < y \<Longrightarrow> x \<le> y" 176191783Srmacklemby (simp add: less_le_not_le) 177191783Srmacklem 178191783Srmacklem 179191783Srmacklemtext \<open>Asymmetry.\<close> 180191783Srmacklem 181191783Srmacklemlemma less_not_sym: "x < y \<Longrightarrow> \<not> (y < x)" 182191783Srmacklemby (simp add: less_le_not_le) 183191783Srmacklem 184191783Srmacklemlemma less_asym: "x < y \<Longrightarrow> (\<not> P \<Longrightarrow> y < x) \<Longrightarrow> P" 185191783Srmacklemby (drule less_not_sym, erule contrapos_np) simp 186191783Srmacklem 187191783Srmacklem 188191783Srmacklemtext \<open>Transitivity.\<close> 189191783Srmacklem 190191783Srmacklemlemma less_trans: "x < y \<Longrightarrow> y < z \<Longrightarrow> x < z" 191191783Srmacklemby (auto simp add: less_le_not_le intro: order_trans) 192191783Srmacklem 193191783Srmacklemlemma le_less_trans: "x \<le> y \<Longrightarrow> y < z \<Longrightarrow> x < z" 194191783Srmacklemby (auto simp add: less_le_not_le intro: order_trans) 195191783Srmacklem 196191783Srmacklemlemma less_le_trans: "x < y \<Longrightarrow> y \<le> z \<Longrightarrow> x < z" 197194408Srmacklemby (auto simp add: less_le_not_le intro: order_trans) 198191783Srmacklem 199191783Srmacklem 200191783Srmacklemtext \<open>Useful for simplification, but too risky to include by default.\<close> 201191783Srmacklem 202191783Srmacklemlemma less_imp_not_less: "x < y \<Longrightarrow> (\<not> y < x) \<longleftrightarrow> True" 203191783Srmacklemby (blast elim: less_asym) 204191783Srmacklem 205191783Srmacklemlemma less_imp_triv: "x < y \<Longrightarrow> (y < x \<longrightarrow> P) \<longleftrightarrow> True" 206191783Srmacklemby (blast elim: less_asym) 207191783Srmacklem 208191783Srmacklem 209191783Srmacklemtext \<open>Transitivity rules for calculational reasoning\<close> 210191783Srmacklem 211191783Srmacklemlemma less_asym': "a < b \<Longrightarrow> b < a \<Longrightarrow> P" 212191783Srmacklemby (rule less_asym) 213191783Srmacklem 214191783Srmacklem 215191783Srmacklemtext \<open>Dual order\<close> 216191783Srmacklem 217191783Srmacklemlemma dual_preorder: 218191783Srmacklem "class.preorder (\<ge>) (>)" 219191783Srmacklem by standard (auto simp add: less_le_not_le intro: order_trans) 220191783Srmacklem 221191783Srmacklemend 222191783Srmacklem 223191783Srmacklem 224191783Srmacklemsubsection \<open>Partial orders\<close> 225191783Srmacklem 226191783Srmacklemclass order = preorder + 227191783Srmacklem assumes antisym: "x \<le> y \<Longrightarrow> y \<le> x \<Longrightarrow> x = y" 228191783Srmacklembegin 229191783Srmacklem 230191783Srmacklemlemma less_le: "x < y \<longleftrightarrow> x \<le> y \<and> x \<noteq> y" 231191783Srmacklem by (auto simp add: less_le_not_le intro: antisym) 232191783Srmacklem 233191783Srmacklemsublocale order: ordering less_eq less + dual_order: ordering greater_eq greater 234191783Srmacklemproof - 235191783Srmacklem interpret ordering less_eq less 236191783Srmacklem by standard (auto intro: antisym order_trans simp add: less_le) 237191783Srmacklem show "ordering less_eq less" 238191783Srmacklem by (fact ordering_axioms) 239191783Srmacklem then show "ordering greater_eq greater" 240191783Srmacklem by (rule ordering_dualI) 241191783Srmacklemqed 242191783Srmacklem 243191783Srmacklemtext \<open>Reflexivity.\<close> 244191783Srmacklem 245191783Srmacklemlemma le_less: "x \<le> y \<longleftrightarrow> x < y \<or> x = y" 246223309Srmacklem \<comment> \<open>NOT suitable for iff, since it can cause PROOF FAILED.\<close> 247191783Srmacklemby (fact order.order_iff_strict) 248191783Srmacklem 249191783Srmacklemlemma le_imp_less_or_eq: "x \<le> y \<Longrightarrow> x < y \<or> x = y" 250191783Srmacklemby (simp add: less_le) 251191783Srmacklem 252191783Srmacklem 253191783Srmacklemtext \<open>Useful for simplification, but too risky to include by default.\<close> 254223309Srmacklem 255191783Srmacklemlemma less_imp_not_eq: "x < y \<Longrightarrow> (x = y) \<longleftrightarrow> False" 256191783Srmacklemby auto 257191783Srmacklem 258191783Srmacklemlemma less_imp_not_eq2: "x < y \<Longrightarrow> (y = x) \<longleftrightarrow> False" 259191783Srmacklemby auto 260191783Srmacklem 261191783Srmacklem 262191783Srmacklemtext \<open>Transitivity rules for calculational reasoning\<close> 263191783Srmacklem 264191783Srmacklemlemma neq_le_trans: "a \<noteq> b \<Longrightarrow> a \<le> b \<Longrightarrow> a < b" 265191783Srmacklemby (fact order.not_eq_order_implies_strict) 266191783Srmacklem 267191783Srmacklemlemma le_neq_trans: "a \<le> b \<Longrightarrow> a \<noteq> b \<Longrightarrow> a < b" 268191783Srmacklemby (rule order.not_eq_order_implies_strict) 269191783Srmacklem 270191783Srmacklem 271191783Srmacklemtext \<open>Asymmetry.\<close> 272191783Srmacklem 273191783Srmacklemlemma eq_iff: "x = y \<longleftrightarrow> x \<le> y \<and> y \<le> x" 274191783Srmacklemby (blast intro: antisym) 275191783Srmacklem 276191783Srmacklemlemma antisym_conv: "y \<le> x \<Longrightarrow> x \<le> y \<longleftrightarrow> x = y" 277244042Srmacklemby (blast intro: antisym) 278244042Srmacklem 279244042Srmacklemlemma less_imp_neq: "x < y \<Longrightarrow> x \<noteq> y" 280244042Srmacklemby (fact order.strict_implies_not_eq) 281317524Srmacklem 282317524Srmacklem 283317524Srmacklemtext \<open>Least value operator\<close> 284317524Srmacklem 285317524Srmacklemdefinition (in ord) 286255216Srmacklem Least :: "('a \<Rightarrow> bool) \<Rightarrow> 'a" (binder "LEAST " 10) where 287255216Srmacklem "Least P = (THE x. P x \<and> (\<forall>y. P y \<longrightarrow> x \<le> y))" 288255216Srmacklem 289191783Srmacklemlemma Least_equality: 290255216Srmacklem assumes "P x" 291255216Srmacklem and "\<And>y. P y \<Longrightarrow> x \<le> y" 292255216Srmacklem shows "Least P = x" 293255216Srmacklemunfolding Least_def by (rule the_equality) 294255216Srmacklem (blast intro: assms antisym)+ 295255216Srmacklem 296191783Srmacklemlemma LeastI2_order: 297191783Srmacklem assumes "P x" 298 and "\<And>y. P y \<Longrightarrow> x \<le> y" 299 and "\<And>x. P x \<Longrightarrow> \<forall>y. P y \<longrightarrow> x \<le> y \<Longrightarrow> Q x" 300 shows "Q (Least P)" 301unfolding Least_def by (rule theI2) 302 (blast intro: assms antisym)+ 303 304text \<open>Greatest value operator\<close> 305 306definition Greatest :: "('a \<Rightarrow> bool) \<Rightarrow> 'a" (binder "GREATEST " 10) where 307"Greatest P = (THE x. P x \<and> (\<forall>y. P y \<longrightarrow> x \<ge> y))" 308 309lemma GreatestI2_order: 310 "\<lbrakk> P x; 311 \<And>y. P y \<Longrightarrow> x \<ge> y; 312 \<And>x. \<lbrakk> P x; \<forall>y. P y \<longrightarrow> x \<ge> y \<rbrakk> \<Longrightarrow> Q x \<rbrakk> 313 \<Longrightarrow> Q (Greatest P)" 314unfolding Greatest_def 315by (rule theI2) (blast intro: antisym)+ 316 317lemma Greatest_equality: 318 "\<lbrakk> P x; \<And>y. P y \<Longrightarrow> x \<ge> y \<rbrakk> \<Longrightarrow> Greatest P = x" 319unfolding Greatest_def 320by (rule the_equality) (blast intro: antisym)+ 321 322end 323 324lemma ordering_orderI: 325 fixes less_eq (infix "\<^bold>\<le>" 50) 326 and less (infix "\<^bold><" 50) 327 assumes "ordering less_eq less" 328 shows "class.order less_eq less" 329proof - 330 from assms interpret ordering less_eq less . 331 show ?thesis 332 by standard (auto intro: antisym trans simp add: refl strict_iff_order) 333qed 334 335lemma order_strictI: 336 fixes less (infix "\<sqsubset>" 50) 337 and less_eq (infix "\<sqsubseteq>" 50) 338 assumes "\<And>a b. a \<sqsubseteq> b \<longleftrightarrow> a \<sqsubset> b \<or> a = b" 339 assumes "\<And>a b. a \<sqsubset> b \<Longrightarrow> \<not> b \<sqsubset> a" 340 assumes "\<And>a. \<not> a \<sqsubset> a" 341 assumes "\<And>a b c. a \<sqsubset> b \<Longrightarrow> b \<sqsubset> c \<Longrightarrow> a \<sqsubset> c" 342 shows "class.order less_eq less" 343 by (rule ordering_orderI) (rule ordering_strictI, (fact assms)+) 344 345context order 346begin 347 348text \<open>Dual order\<close> 349 350lemma dual_order: 351 "class.order (\<ge>) (>)" 352 using dual_order.ordering_axioms by (rule ordering_orderI) 353 354end 355 356 357subsection \<open>Linear (total) orders\<close> 358 359class linorder = order + 360 assumes linear: "x \<le> y \<or> y \<le> x" 361begin 362 363lemma less_linear: "x < y \<or> x = y \<or> y < x" 364unfolding less_le using less_le linear by blast 365 366lemma le_less_linear: "x \<le> y \<or> y < x" 367by (simp add: le_less less_linear) 368 369lemma le_cases [case_names le ge]: 370 "(x \<le> y \<Longrightarrow> P) \<Longrightarrow> (y \<le> x \<Longrightarrow> P) \<Longrightarrow> P" 371using linear by blast 372 373lemma (in linorder) le_cases3: 374 "\<lbrakk>\<lbrakk>x \<le> y; y \<le> z\<rbrakk> \<Longrightarrow> P; \<lbrakk>y \<le> x; x \<le> z\<rbrakk> \<Longrightarrow> P; \<lbrakk>x \<le> z; z \<le> y\<rbrakk> \<Longrightarrow> P; 375 \<lbrakk>z \<le> y; y \<le> x\<rbrakk> \<Longrightarrow> P; \<lbrakk>y \<le> z; z \<le> x\<rbrakk> \<Longrightarrow> P; \<lbrakk>z \<le> x; x \<le> y\<rbrakk> \<Longrightarrow> P\<rbrakk> \<Longrightarrow> P" 376by (blast intro: le_cases) 377 378lemma linorder_cases [case_names less equal greater]: 379 "(x < y \<Longrightarrow> P) \<Longrightarrow> (x = y \<Longrightarrow> P) \<Longrightarrow> (y < x \<Longrightarrow> P) \<Longrightarrow> P" 380using less_linear by blast 381 382lemma linorder_wlog[case_names le sym]: 383 "(\<And>a b. a \<le> b \<Longrightarrow> P a b) \<Longrightarrow> (\<And>a b. P b a \<Longrightarrow> P a b) \<Longrightarrow> P a b" 384 by (cases rule: le_cases[of a b]) blast+ 385 386lemma not_less: "\<not> x < y \<longleftrightarrow> y \<le> x" 387apply (simp add: less_le) 388using linear apply (blast intro: antisym) 389done 390 391lemma not_less_iff_gr_or_eq: 392 "\<not>(x < y) \<longleftrightarrow> (x > y \<or> x = y)" 393apply(simp add:not_less le_less) 394apply blast 395done 396 397lemma not_le: "\<not> x \<le> y \<longleftrightarrow> y < x" 398apply (simp add: less_le) 399using linear apply (blast intro: antisym) 400done 401 402lemma neq_iff: "x \<noteq> y \<longleftrightarrow> x < y \<or> y < x" 403by (cut_tac x = x and y = y in less_linear, auto) 404 405lemma neqE: "x \<noteq> y \<Longrightarrow> (x < y \<Longrightarrow> R) \<Longrightarrow> (y < x \<Longrightarrow> R) \<Longrightarrow> R" 406by (simp add: neq_iff) blast 407 408lemma antisym_conv1: "\<not> x < y \<Longrightarrow> x \<le> y \<longleftrightarrow> x = y" 409by (blast intro: antisym dest: not_less [THEN iffD1]) 410 411lemma antisym_conv2: "x \<le> y \<Longrightarrow> \<not> x < y \<longleftrightarrow> x = y" 412by (blast intro: antisym dest: not_less [THEN iffD1]) 413 414lemma antisym_conv3: "\<not> y < x \<Longrightarrow> \<not> x < y \<longleftrightarrow> x = y" 415by (blast intro: antisym dest: not_less [THEN iffD1]) 416 417lemma leI: "\<not> x < y \<Longrightarrow> y \<le> x" 418unfolding not_less . 419 420lemma leD: "y \<le> x \<Longrightarrow> \<not> x < y" 421unfolding not_less . 422 423lemma not_le_imp_less: "\<not> y \<le> x \<Longrightarrow> x < y" 424unfolding not_le . 425 426lemma linorder_less_wlog[case_names less refl sym]: 427 "\<lbrakk>\<And>a b. a < b \<Longrightarrow> P a b; \<And>a. P a a; \<And>a b. P b a \<Longrightarrow> P a b\<rbrakk> \<Longrightarrow> P a b" 428 using antisym_conv3 by blast 429 430text \<open>Dual order\<close> 431 432lemma dual_linorder: 433 "class.linorder (\<ge>) (>)" 434by (rule class.linorder.intro, rule dual_order) (unfold_locales, rule linear) 435 436end 437 438 439text \<open>Alternative introduction rule with bias towards strict order\<close> 440 441lemma linorder_strictI: 442 fixes less_eq (infix "\<^bold>\<le>" 50) 443 and less (infix "\<^bold><" 50) 444 assumes "class.order less_eq less" 445 assumes trichotomy: "\<And>a b. a \<^bold>< b \<or> a = b \<or> b \<^bold>< a" 446 shows "class.linorder less_eq less" 447proof - 448 interpret order less_eq less 449 by (fact \<open>class.order less_eq less\<close>) 450 show ?thesis 451 proof 452 fix a b 453 show "a \<^bold>\<le> b \<or> b \<^bold>\<le> a" 454 using trichotomy by (auto simp add: le_less) 455 qed 456qed 457 458 459subsection \<open>Reasoning tools setup\<close> 460 461ML \<open> 462signature ORDERS = 463sig 464 val print_structures: Proof.context -> unit 465 val order_tac: Proof.context -> thm list -> int -> tactic 466 val add_struct: string * term list -> string -> attribute 467 val del_struct: string * term list -> attribute 468end; 469 470structure Orders: ORDERS = 471struct 472 473(* context data *) 474 475fun struct_eq ((s1: string, ts1), (s2, ts2)) = 476 s1 = s2 andalso eq_list (op aconv) (ts1, ts2); 477 478structure Data = Generic_Data 479( 480 type T = ((string * term list) * Order_Tac.less_arith) list; 481 (* Order structures: 482 identifier of the structure, list of operations and record of theorems 483 needed to set up the transitivity reasoner, 484 identifier and operations identify the structure uniquely. *) 485 val empty = []; 486 val extend = I; 487 fun merge data = AList.join struct_eq (K fst) data; 488); 489 490fun print_structures ctxt = 491 let 492 val structs = Data.get (Context.Proof ctxt); 493 fun pretty_term t = Pretty.block 494 [Pretty.quote (Syntax.pretty_term ctxt t), Pretty.brk 1, 495 Pretty.str "::", Pretty.brk 1, 496 Pretty.quote (Syntax.pretty_typ ctxt (type_of t))]; 497 fun pretty_struct ((s, ts), _) = Pretty.block 498 [Pretty.str s, Pretty.str ":", Pretty.brk 1, 499 Pretty.enclose "(" ")" (Pretty.breaks (map pretty_term ts))]; 500 in 501 Pretty.writeln (Pretty.big_list "order structures:" (map pretty_struct structs)) 502 end; 503 504val _ = 505 Outer_Syntax.command @{command_keyword print_orders} 506 "print order structures available to transitivity reasoner" 507 (Scan.succeed (Toplevel.keep (print_structures o Toplevel.context_of))); 508 509 510(* tactics *) 511 512fun struct_tac ((s, ops), thms) ctxt facts = 513 let 514 val [eq, le, less] = ops; 515 fun decomp thy (@{const Trueprop} $ t) = 516 let 517 fun excluded t = 518 (* exclude numeric types: linear arithmetic subsumes transitivity *) 519 let val T = type_of t 520 in 521 T = HOLogic.natT orelse T = HOLogic.intT orelse T = HOLogic.realT 522 end; 523 fun rel (bin_op $ t1 $ t2) = 524 if excluded t1 then NONE 525 else if Pattern.matches thy (eq, bin_op) then SOME (t1, "=", t2) 526 else if Pattern.matches thy (le, bin_op) then SOME (t1, "<=", t2) 527 else if Pattern.matches thy (less, bin_op) then SOME (t1, "<", t2) 528 else NONE 529 | rel _ = NONE; 530 fun dec (Const (@{const_name Not}, _) $ t) = 531 (case rel t of NONE => 532 NONE 533 | SOME (t1, rel, t2) => SOME (t1, "~" ^ rel, t2)) 534 | dec x = rel x; 535 in dec t end 536 | decomp _ _ = NONE; 537 in 538 (case s of 539 "order" => Order_Tac.partial_tac decomp thms ctxt facts 540 | "linorder" => Order_Tac.linear_tac decomp thms ctxt facts 541 | _ => error ("Unknown order kind " ^ quote s ^ " encountered in transitivity reasoner")) 542 end 543 544fun order_tac ctxt facts = 545 FIRST' (map (fn s => CHANGED o struct_tac s ctxt facts) (Data.get (Context.Proof ctxt))); 546 547 548(* attributes *) 549 550fun add_struct s tag = 551 Thm.declaration_attribute 552 (fn thm => Data.map (AList.map_default struct_eq (s, Order_Tac.empty TrueI) (Order_Tac.update tag thm))); 553fun del_struct s = 554 Thm.declaration_attribute 555 (fn _ => Data.map (AList.delete struct_eq s)); 556 557end; 558\<close> 559 560attribute_setup order = \<open> 561 Scan.lift ((Args.add -- Args.name >> (fn (_, s) => SOME s) || Args.del >> K NONE) --| 562 Args.colon (* FIXME || Scan.succeed true *) ) -- Scan.lift Args.name -- 563 Scan.repeat Args.term 564 >> (fn ((SOME tag, n), ts) => Orders.add_struct (n, ts) tag 565 | ((NONE, n), ts) => Orders.del_struct (n, ts)) 566\<close> "theorems controlling transitivity reasoner" 567 568method_setup order = \<open> 569 Scan.succeed (fn ctxt => SIMPLE_METHOD' (Orders.order_tac ctxt [])) 570\<close> "transitivity reasoner" 571 572 573text \<open>Declarations to set up transitivity reasoner of partial and linear orders.\<close> 574 575context order 576begin 577 578(* The type constraint on @{term (=}) below is necessary since the operation 579 is not a parameter of the locale. *) 580 581declare less_irrefl [THEN notE, order add less_reflE: order "(=) :: 'a \<Rightarrow> 'a \<Rightarrow> bool" "(<=)" "(<)"] 582 583declare order_refl [order add le_refl: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 584 585declare less_imp_le [order add less_imp_le: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 586 587declare antisym [order add eqI: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 588 589declare eq_refl [order add eqD1: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 590 591declare sym [THEN eq_refl, order add eqD2: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 592 593declare less_trans [order add less_trans: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 594 595declare less_le_trans [order add less_le_trans: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 596 597declare le_less_trans [order add le_less_trans: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 598 599declare order_trans [order add le_trans: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 600 601declare le_neq_trans [order add le_neq_trans: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 602 603declare neq_le_trans [order add neq_le_trans: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 604 605declare less_imp_neq [order add less_imp_neq: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 606 607declare eq_neq_eq_imp_neq [order add eq_neq_eq_imp_neq: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 608 609declare not_sym [order add not_sym: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 610 611end 612 613context linorder 614begin 615 616declare [[order del: order "(=) :: 'a => 'a => bool" "(<=)" "(<)"]] 617 618declare less_irrefl [THEN notE, order add less_reflE: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 619 620declare order_refl [order add le_refl: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 621 622declare less_imp_le [order add less_imp_le: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 623 624declare not_less [THEN iffD2, order add not_lessI: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 625 626declare not_le [THEN iffD2, order add not_leI: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 627 628declare not_less [THEN iffD1, order add not_lessD: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 629 630declare not_le [THEN iffD1, order add not_leD: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 631 632declare antisym [order add eqI: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 633 634declare eq_refl [order add eqD1: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 635 636declare sym [THEN eq_refl, order add eqD2: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 637 638declare less_trans [order add less_trans: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 639 640declare less_le_trans [order add less_le_trans: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 641 642declare le_less_trans [order add le_less_trans: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 643 644declare order_trans [order add le_trans: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 645 646declare le_neq_trans [order add le_neq_trans: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 647 648declare neq_le_trans [order add neq_le_trans: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 649 650declare less_imp_neq [order add less_imp_neq: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 651 652declare eq_neq_eq_imp_neq [order add eq_neq_eq_imp_neq: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 653 654declare not_sym [order add not_sym: linorder "(=) :: 'a => 'a => bool" "(<=)" "(<)"] 655 656end 657 658setup \<open> 659 map_theory_simpset (fn ctxt0 => ctxt0 addSolver 660 mk_solver "Transitivity" (fn ctxt => Orders.order_tac ctxt (Simplifier.prems_of ctxt))) 661 (*Adding the transitivity reasoners also as safe solvers showed a slight 662 speed up, but the reasoning strength appears to be not higher (at least 663 no breaking of additional proofs in the entire HOL distribution, as 664 of 5 March 2004, was observed).*) 665\<close> 666 667ML \<open> 668local 669 fun prp t thm = Thm.prop_of thm = t; (* FIXME proper aconv!? *) 670in 671 672fun antisym_le_simproc ctxt ct = 673 (case Thm.term_of ct of 674 (le as Const (_, T)) $ r $ s => 675 (let 676 val prems = Simplifier.prems_of ctxt; 677 val less = Const (@{const_name less}, T); 678 val t = HOLogic.mk_Trueprop(le $ s $ r); 679 in 680 (case find_first (prp t) prems of 681 NONE => 682 let val t = HOLogic.mk_Trueprop(HOLogic.Not $ (less $ r $ s)) in 683 (case find_first (prp t) prems of 684 NONE => NONE 685 | SOME thm => SOME(mk_meta_eq(thm RS @{thm linorder_class.antisym_conv1}))) 686 end 687 | SOME thm => SOME (mk_meta_eq (thm RS @{thm order_class.antisym_conv}))) 688 end handle THM _ => NONE) 689 | _ => NONE); 690 691fun antisym_less_simproc ctxt ct = 692 (case Thm.term_of ct of 693 NotC $ ((less as Const(_,T)) $ r $ s) => 694 (let 695 val prems = Simplifier.prems_of ctxt; 696 val le = Const (@{const_name less_eq}, T); 697 val t = HOLogic.mk_Trueprop(le $ r $ s); 698 in 699 (case find_first (prp t) prems of 700 NONE => 701 let val t = HOLogic.mk_Trueprop (NotC $ (less $ s $ r)) in 702 (case find_first (prp t) prems of 703 NONE => NONE 704 | SOME thm => SOME (mk_meta_eq(thm RS @{thm linorder_class.antisym_conv3}))) 705 end 706 | SOME thm => SOME (mk_meta_eq (thm RS @{thm linorder_class.antisym_conv2}))) 707 end handle THM _ => NONE) 708 | _ => NONE); 709 710end; 711\<close> 712 713simproc_setup antisym_le ("(x::'a::order) \<le> y") = "K antisym_le_simproc" 714simproc_setup antisym_less ("\<not> (x::'a::linorder) < y") = "K antisym_less_simproc" 715 716 717subsection \<open>Bounded quantifiers\<close> 718 719syntax (ASCII) 720 "_All_less" :: "[idt, 'a, bool] => bool" ("(3ALL _<_./ _)" [0, 0, 10] 10) 721 "_Ex_less" :: "[idt, 'a, bool] => bool" ("(3EX _<_./ _)" [0, 0, 10] 10) 722 "_All_less_eq" :: "[idt, 'a, bool] => bool" ("(3ALL _<=_./ _)" [0, 0, 10] 10) 723 "_Ex_less_eq" :: "[idt, 'a, bool] => bool" ("(3EX _<=_./ _)" [0, 0, 10] 10) 724 725 "_All_greater" :: "[idt, 'a, bool] => bool" ("(3ALL _>_./ _)" [0, 0, 10] 10) 726 "_Ex_greater" :: "[idt, 'a, bool] => bool" ("(3EX _>_./ _)" [0, 0, 10] 10) 727 "_All_greater_eq" :: "[idt, 'a, bool] => bool" ("(3ALL _>=_./ _)" [0, 0, 10] 10) 728 "_Ex_greater_eq" :: "[idt, 'a, bool] => bool" ("(3EX _>=_./ _)" [0, 0, 10] 10) 729 730 "_All_neq" :: "[idt, 'a, bool] => bool" ("(3ALL _~=_./ _)" [0, 0, 10] 10) 731 "_Ex_neq" :: "[idt, 'a, bool] => bool" ("(3EX _~=_./ _)" [0, 0, 10] 10) 732 733syntax 734 "_All_less" :: "[idt, 'a, bool] => bool" ("(3\<forall>_<_./ _)" [0, 0, 10] 10) 735 "_Ex_less" :: "[idt, 'a, bool] => bool" ("(3\<exists>_<_./ _)" [0, 0, 10] 10) 736 "_All_less_eq" :: "[idt, 'a, bool] => bool" ("(3\<forall>_\<le>_./ _)" [0, 0, 10] 10) 737 "_Ex_less_eq" :: "[idt, 'a, bool] => bool" ("(3\<exists>_\<le>_./ _)" [0, 0, 10] 10) 738 739 "_All_greater" :: "[idt, 'a, bool] => bool" ("(3\<forall>_>_./ _)" [0, 0, 10] 10) 740 "_Ex_greater" :: "[idt, 'a, bool] => bool" ("(3\<exists>_>_./ _)" [0, 0, 10] 10) 741 "_All_greater_eq" :: "[idt, 'a, bool] => bool" ("(3\<forall>_\<ge>_./ _)" [0, 0, 10] 10) 742 "_Ex_greater_eq" :: "[idt, 'a, bool] => bool" ("(3\<exists>_\<ge>_./ _)" [0, 0, 10] 10) 743 744 "_All_neq" :: "[idt, 'a, bool] => bool" ("(3\<forall>_\<noteq>_./ _)" [0, 0, 10] 10) 745 "_Ex_neq" :: "[idt, 'a, bool] => bool" ("(3\<exists>_\<noteq>_./ _)" [0, 0, 10] 10) 746 747syntax (input) 748 "_All_less" :: "[idt, 'a, bool] => bool" ("(3! _<_./ _)" [0, 0, 10] 10) 749 "_Ex_less" :: "[idt, 'a, bool] => bool" ("(3? _<_./ _)" [0, 0, 10] 10) 750 "_All_less_eq" :: "[idt, 'a, bool] => bool" ("(3! _<=_./ _)" [0, 0, 10] 10) 751 "_Ex_less_eq" :: "[idt, 'a, bool] => bool" ("(3? _<=_./ _)" [0, 0, 10] 10) 752 "_All_neq" :: "[idt, 'a, bool] => bool" ("(3! _~=_./ _)" [0, 0, 10] 10) 753 "_Ex_neq" :: "[idt, 'a, bool] => bool" ("(3? _~=_./ _)" [0, 0, 10] 10) 754 755translations 756 "\<forall>x<y. P" \<rightharpoonup> "\<forall>x. x < y \<longrightarrow> P" 757 "\<exists>x<y. P" \<rightharpoonup> "\<exists>x. x < y \<and> P" 758 "\<forall>x\<le>y. P" \<rightharpoonup> "\<forall>x. x \<le> y \<longrightarrow> P" 759 "\<exists>x\<le>y. P" \<rightharpoonup> "\<exists>x. x \<le> y \<and> P" 760 "\<forall>x>y. P" \<rightharpoonup> "\<forall>x. x > y \<longrightarrow> P" 761 "\<exists>x>y. P" \<rightharpoonup> "\<exists>x. x > y \<and> P" 762 "\<forall>x\<ge>y. P" \<rightharpoonup> "\<forall>x. x \<ge> y \<longrightarrow> P" 763 "\<exists>x\<ge>y. P" \<rightharpoonup> "\<exists>x. x \<ge> y \<and> P" 764 "\<forall>x\<noteq>y. P" \<rightharpoonup> "\<forall>x. x \<noteq> y \<longrightarrow> P" 765 "\<exists>x\<noteq>y. P" \<rightharpoonup> "\<exists>x. x \<noteq> y \<and> P" 766 767print_translation \<open> 768let 769 val All_binder = Mixfix.binder_name @{const_syntax All}; 770 val Ex_binder = Mixfix.binder_name @{const_syntax Ex}; 771 val impl = @{const_syntax HOL.implies}; 772 val conj = @{const_syntax HOL.conj}; 773 val less = @{const_syntax less}; 774 val less_eq = @{const_syntax less_eq}; 775 776 val trans = 777 [((All_binder, impl, less), 778 (@{syntax_const "_All_less"}, @{syntax_const "_All_greater"})), 779 ((All_binder, impl, less_eq), 780 (@{syntax_const "_All_less_eq"}, @{syntax_const "_All_greater_eq"})), 781 ((Ex_binder, conj, less), 782 (@{syntax_const "_Ex_less"}, @{syntax_const "_Ex_greater"})), 783 ((Ex_binder, conj, less_eq), 784 (@{syntax_const "_Ex_less_eq"}, @{syntax_const "_Ex_greater_eq"}))]; 785 786 fun matches_bound v t = 787 (case t of 788 Const (@{syntax_const "_bound"}, _) $ Free (v', _) => v = v' 789 | _ => false); 790 fun contains_var v = Term.exists_subterm (fn Free (x, _) => x = v | _ => false); 791 fun mk x c n P = Syntax.const c $ Syntax_Trans.mark_bound_body x $ n $ P; 792 793 fun tr' q = (q, fn _ => 794 (fn [Const (@{syntax_const "_bound"}, _) $ Free (v, T), 795 Const (c, _) $ (Const (d, _) $ t $ u) $ P] => 796 (case AList.lookup (=) trans (q, c, d) of 797 NONE => raise Match 798 | SOME (l, g) => 799 if matches_bound v t andalso not (contains_var v u) then mk (v, T) l u P 800 else if matches_bound v u andalso not (contains_var v t) then mk (v, T) g t P 801 else raise Match) 802 | _ => raise Match)); 803in [tr' All_binder, tr' Ex_binder] end 804\<close> 805 806 807subsection \<open>Transitivity reasoning\<close> 808 809context ord 810begin 811 812lemma ord_le_eq_trans: "a \<le> b \<Longrightarrow> b = c \<Longrightarrow> a \<le> c" 813 by (rule subst) 814 815lemma ord_eq_le_trans: "a = b \<Longrightarrow> b \<le> c \<Longrightarrow> a \<le> c" 816 by (rule ssubst) 817 818lemma ord_less_eq_trans: "a < b \<Longrightarrow> b = c \<Longrightarrow> a < c" 819 by (rule subst) 820 821lemma ord_eq_less_trans: "a = b \<Longrightarrow> b < c \<Longrightarrow> a < c" 822 by (rule ssubst) 823 824end 825 826lemma order_less_subst2: "(a::'a::order) < b ==> f b < (c::'c::order) ==> 827 (!!x y. x < y ==> f x < f y) ==> f a < c" 828proof - 829 assume r: "!!x y. x < y ==> f x < f y" 830 assume "a < b" hence "f a < f b" by (rule r) 831 also assume "f b < c" 832 finally (less_trans) show ?thesis . 833qed 834 835lemma order_less_subst1: "(a::'a::order) < f b ==> (b::'b::order) < c ==> 836 (!!x y. x < y ==> f x < f y) ==> a < f c" 837proof - 838 assume r: "!!x y. x < y ==> f x < f y" 839 assume "a < f b" 840 also assume "b < c" hence "f b < f c" by (rule r) 841 finally (less_trans) show ?thesis . 842qed 843 844lemma order_le_less_subst2: "(a::'a::order) <= b ==> f b < (c::'c::order) ==> 845 (!!x y. x <= y ==> f x <= f y) ==> f a < c" 846proof - 847 assume r: "!!x y. x <= y ==> f x <= f y" 848 assume "a <= b" hence "f a <= f b" by (rule r) 849 also assume "f b < c" 850 finally (le_less_trans) show ?thesis . 851qed 852 853lemma order_le_less_subst1: "(a::'a::order) <= f b ==> (b::'b::order) < c ==> 854 (!!x y. x < y ==> f x < f y) ==> a < f c" 855proof - 856 assume r: "!!x y. x < y ==> f x < f y" 857 assume "a <= f b" 858 also assume "b < c" hence "f b < f c" by (rule r) 859 finally (le_less_trans) show ?thesis . 860qed 861 862lemma order_less_le_subst2: "(a::'a::order) < b ==> f b <= (c::'c::order) ==> 863 (!!x y. x < y ==> f x < f y) ==> f a < c" 864proof - 865 assume r: "!!x y. x < y ==> f x < f y" 866 assume "a < b" hence "f a < f b" by (rule r) 867 also assume "f b <= c" 868 finally (less_le_trans) show ?thesis . 869qed 870 871lemma order_less_le_subst1: "(a::'a::order) < f b ==> (b::'b::order) <= c ==> 872 (!!x y. x <= y ==> f x <= f y) ==> a < f c" 873proof - 874 assume r: "!!x y. x <= y ==> f x <= f y" 875 assume "a < f b" 876 also assume "b <= c" hence "f b <= f c" by (rule r) 877 finally (less_le_trans) show ?thesis . 878qed 879 880lemma order_subst1: "(a::'a::order) <= f b ==> (b::'b::order) <= c ==> 881 (!!x y. x <= y ==> f x <= f y) ==> a <= f c" 882proof - 883 assume r: "!!x y. x <= y ==> f x <= f y" 884 assume "a <= f b" 885 also assume "b <= c" hence "f b <= f c" by (rule r) 886 finally (order_trans) show ?thesis . 887qed 888 889lemma order_subst2: "(a::'a::order) <= b ==> f b <= (c::'c::order) ==> 890 (!!x y. x <= y ==> f x <= f y) ==> f a <= c" 891proof - 892 assume r: "!!x y. x <= y ==> f x <= f y" 893 assume "a <= b" hence "f a <= f b" by (rule r) 894 also assume "f b <= c" 895 finally (order_trans) show ?thesis . 896qed 897 898lemma ord_le_eq_subst: "a <= b ==> f b = c ==> 899 (!!x y. x <= y ==> f x <= f y) ==> f a <= c" 900proof - 901 assume r: "!!x y. x <= y ==> f x <= f y" 902 assume "a <= b" hence "f a <= f b" by (rule r) 903 also assume "f b = c" 904 finally (ord_le_eq_trans) show ?thesis . 905qed 906 907lemma ord_eq_le_subst: "a = f b ==> b <= c ==> 908 (!!x y. x <= y ==> f x <= f y) ==> a <= f c" 909proof - 910 assume r: "!!x y. x <= y ==> f x <= f y" 911 assume "a = f b" 912 also assume "b <= c" hence "f b <= f c" by (rule r) 913 finally (ord_eq_le_trans) show ?thesis . 914qed 915 916lemma ord_less_eq_subst: "a < b ==> f b = c ==> 917 (!!x y. x < y ==> f x < f y) ==> f a < c" 918proof - 919 assume r: "!!x y. x < y ==> f x < f y" 920 assume "a < b" hence "f a < f b" by (rule r) 921 also assume "f b = c" 922 finally (ord_less_eq_trans) show ?thesis . 923qed 924 925lemma ord_eq_less_subst: "a = f b ==> b < c ==> 926 (!!x y. x < y ==> f x < f y) ==> a < f c" 927proof - 928 assume r: "!!x y. x < y ==> f x < f y" 929 assume "a = f b" 930 also assume "b < c" hence "f b < f c" by (rule r) 931 finally (ord_eq_less_trans) show ?thesis . 932qed 933 934text \<open> 935 Note that this list of rules is in reverse order of priorities. 936\<close> 937 938lemmas [trans] = 939 order_less_subst2 940 order_less_subst1 941 order_le_less_subst2 942 order_le_less_subst1 943 order_less_le_subst2 944 order_less_le_subst1 945 order_subst2 946 order_subst1 947 ord_le_eq_subst 948 ord_eq_le_subst 949 ord_less_eq_subst 950 ord_eq_less_subst 951 forw_subst 952 back_subst 953 rev_mp 954 mp 955 956lemmas (in order) [trans] = 957 neq_le_trans 958 le_neq_trans 959 960lemmas (in preorder) [trans] = 961 less_trans 962 less_asym' 963 le_less_trans 964 less_le_trans 965 order_trans 966 967lemmas (in order) [trans] = 968 antisym 969 970lemmas (in ord) [trans] = 971 ord_le_eq_trans 972 ord_eq_le_trans 973 ord_less_eq_trans 974 ord_eq_less_trans 975 976lemmas [trans] = 977 trans 978 979lemmas order_trans_rules = 980 order_less_subst2 981 order_less_subst1 982 order_le_less_subst2 983 order_le_less_subst1 984 order_less_le_subst2 985 order_less_le_subst1 986 order_subst2 987 order_subst1 988 ord_le_eq_subst 989 ord_eq_le_subst 990 ord_less_eq_subst 991 ord_eq_less_subst 992 forw_subst 993 back_subst 994 rev_mp 995 mp 996 neq_le_trans 997 le_neq_trans 998 less_trans 999 less_asym' 1000 le_less_trans 1001 less_le_trans 1002 order_trans 1003 antisym 1004 ord_le_eq_trans 1005 ord_eq_le_trans 1006 ord_less_eq_trans 1007 ord_eq_less_trans 1008 trans 1009 1010text \<open>These support proving chains of decreasing inequalities 1011 a >= b >= c ... in Isar proofs.\<close> 1012 1013lemma xt1 [no_atp]: 1014 "a = b \<Longrightarrow> b > c \<Longrightarrow> a > c" 1015 "a > b \<Longrightarrow> b = c \<Longrightarrow> a > c" 1016 "a = b \<Longrightarrow> b \<ge> c \<Longrightarrow> a \<ge> c" 1017 "a \<ge> b \<Longrightarrow> b = c \<Longrightarrow> a \<ge> c" 1018 "(x::'a::order) \<ge> y \<Longrightarrow> y \<ge> x \<Longrightarrow> x = y" 1019 "(x::'a::order) \<ge> y \<Longrightarrow> y \<ge> z \<Longrightarrow> x \<ge> z" 1020 "(x::'a::order) > y \<Longrightarrow> y \<ge> z \<Longrightarrow> x > z" 1021 "(x::'a::order) \<ge> y \<Longrightarrow> y > z \<Longrightarrow> x > z" 1022 "(a::'a::order) > b \<Longrightarrow> b > a \<Longrightarrow> P" 1023 "(x::'a::order) > y \<Longrightarrow> y > z \<Longrightarrow> x > z" 1024 "(a::'a::order) \<ge> b \<Longrightarrow> a \<noteq> b \<Longrightarrow> a > b" 1025 "(a::'a::order) \<noteq> b \<Longrightarrow> a \<ge> b \<Longrightarrow> a > b" 1026 "a = f b \<Longrightarrow> b > c \<Longrightarrow> (\<And>x y. x > y \<Longrightarrow> f x > f y) \<Longrightarrow> a > f c" 1027 "a > b \<Longrightarrow> f b = c \<Longrightarrow> (\<And>x y. x > y \<Longrightarrow> f x > f y) \<Longrightarrow> f a > c" 1028 "a = f b \<Longrightarrow> b \<ge> c \<Longrightarrow> (\<And>x y. x \<ge> y \<Longrightarrow> f x \<ge> f y) \<Longrightarrow> a \<ge> f c" 1029 "a \<ge> b \<Longrightarrow> f b = c \<Longrightarrow> (\<And>x y. x \<ge> y \<Longrightarrow> f x \<ge> f y) \<Longrightarrow> f a \<ge> c" 1030 by auto 1031 1032lemma xt2 [no_atp]: 1033 "(a::'a::order) >= f b ==> b >= c ==> (!!x y. x >= y ==> f x >= f y) ==> a >= f c" 1034by (subgoal_tac "f b >= f c", force, force) 1035 1036lemma xt3 [no_atp]: "(a::'a::order) >= b ==> (f b::'b::order) >= c ==> 1037 (!!x y. x >= y ==> f x >= f y) ==> f a >= c" 1038by (subgoal_tac "f a >= f b", force, force) 1039 1040lemma xt4 [no_atp]: "(a::'a::order) > f b ==> (b::'b::order) >= c ==> 1041 (!!x y. x >= y ==> f x >= f y) ==> a > f c" 1042by (subgoal_tac "f b >= f c", force, force) 1043 1044lemma xt5 [no_atp]: "(a::'a::order) > b ==> (f b::'b::order) >= c==> 1045 (!!x y. x > y ==> f x > f y) ==> f a > c" 1046by (subgoal_tac "f a > f b", force, force) 1047 1048lemma xt6 [no_atp]: "(a::'a::order) >= f b ==> b > c ==> 1049 (!!x y. x > y ==> f x > f y) ==> a > f c" 1050by (subgoal_tac "f b > f c", force, force) 1051 1052lemma xt7 [no_atp]: "(a::'a::order) >= b ==> (f b::'b::order) > c ==> 1053 (!!x y. x >= y ==> f x >= f y) ==> f a > c" 1054by (subgoal_tac "f a >= f b", force, force) 1055 1056lemma xt8 [no_atp]: "(a::'a::order) > f b ==> (b::'b::order) > c ==> 1057 (!!x y. x > y ==> f x > f y) ==> a > f c" 1058by (subgoal_tac "f b > f c", force, force) 1059 1060lemma xt9 [no_atp]: "(a::'a::order) > b ==> (f b::'b::order) > c ==> 1061 (!!x y. x > y ==> f x > f y) ==> f a > c" 1062by (subgoal_tac "f a > f b", force, force) 1063 1064lemmas xtrans = xt1 xt2 xt3 xt4 xt5 xt6 xt7 xt8 xt9 1065 1066(* 1067 Since "a >= b" abbreviates "b <= a", the abbreviation "..." stands 1068 for the wrong thing in an Isar proof. 1069 1070 The extra transitivity rules can be used as follows: 1071 1072lemma "(a::'a::order) > z" 1073proof - 1074 have "a >= b" (is "_ >= ?rhs") 1075 sorry 1076 also have "?rhs >= c" (is "_ >= ?rhs") 1077 sorry 1078 also (xtrans) have "?rhs = d" (is "_ = ?rhs") 1079 sorry 1080 also (xtrans) have "?rhs >= e" (is "_ >= ?rhs") 1081 sorry 1082 also (xtrans) have "?rhs > f" (is "_ > ?rhs") 1083 sorry 1084 also (xtrans) have "?rhs > z" 1085 sorry 1086 finally (xtrans) show ?thesis . 1087qed 1088 1089 Alternatively, one can use "declare xtrans [trans]" and then 1090 leave out the "(xtrans)" above. 1091*) 1092 1093 1094subsection \<open>Monotonicity\<close> 1095 1096context order 1097begin 1098 1099definition mono :: "('a \<Rightarrow> 'b::order) \<Rightarrow> bool" where 1100 "mono f \<longleftrightarrow> (\<forall>x y. x \<le> y \<longrightarrow> f x \<le> f y)" 1101 1102lemma monoI [intro?]: 1103 fixes f :: "'a \<Rightarrow> 'b::order" 1104 shows "(\<And>x y. x \<le> y \<Longrightarrow> f x \<le> f y) \<Longrightarrow> mono f" 1105 unfolding mono_def by iprover 1106 1107lemma monoD [dest?]: 1108 fixes f :: "'a \<Rightarrow> 'b::order" 1109 shows "mono f \<Longrightarrow> x \<le> y \<Longrightarrow> f x \<le> f y" 1110 unfolding mono_def by iprover 1111 1112lemma monoE: 1113 fixes f :: "'a \<Rightarrow> 'b::order" 1114 assumes "mono f" 1115 assumes "x \<le> y" 1116 obtains "f x \<le> f y" 1117proof 1118 from assms show "f x \<le> f y" by (simp add: mono_def) 1119qed 1120 1121definition antimono :: "('a \<Rightarrow> 'b::order) \<Rightarrow> bool" where 1122 "antimono f \<longleftrightarrow> (\<forall>x y. x \<le> y \<longrightarrow> f x \<ge> f y)" 1123 1124lemma antimonoI [intro?]: 1125 fixes f :: "'a \<Rightarrow> 'b::order" 1126 shows "(\<And>x y. x \<le> y \<Longrightarrow> f x \<ge> f y) \<Longrightarrow> antimono f" 1127 unfolding antimono_def by iprover 1128 1129lemma antimonoD [dest?]: 1130 fixes f :: "'a \<Rightarrow> 'b::order" 1131 shows "antimono f \<Longrightarrow> x \<le> y \<Longrightarrow> f x \<ge> f y" 1132 unfolding antimono_def by iprover 1133 1134lemma antimonoE: 1135 fixes f :: "'a \<Rightarrow> 'b::order" 1136 assumes "antimono f" 1137 assumes "x \<le> y" 1138 obtains "f x \<ge> f y" 1139proof 1140 from assms show "f x \<ge> f y" by (simp add: antimono_def) 1141qed 1142 1143definition strict_mono :: "('a \<Rightarrow> 'b::order) \<Rightarrow> bool" where 1144 "strict_mono f \<longleftrightarrow> (\<forall>x y. x < y \<longrightarrow> f x < f y)" 1145 1146lemma strict_monoI [intro?]: 1147 assumes "\<And>x y. x < y \<Longrightarrow> f x < f y" 1148 shows "strict_mono f" 1149 using assms unfolding strict_mono_def by auto 1150 1151lemma strict_monoD [dest?]: 1152 "strict_mono f \<Longrightarrow> x < y \<Longrightarrow> f x < f y" 1153 unfolding strict_mono_def by auto 1154 1155lemma strict_mono_mono [dest?]: 1156 assumes "strict_mono f" 1157 shows "mono f" 1158proof (rule monoI) 1159 fix x y 1160 assume "x \<le> y" 1161 show "f x \<le> f y" 1162 proof (cases "x = y") 1163 case True then show ?thesis by simp 1164 next 1165 case False with \<open>x \<le> y\<close> have "x < y" by simp 1166 with assms strict_monoD have "f x < f y" by auto 1167 then show ?thesis by simp 1168 qed 1169qed 1170 1171end 1172 1173context linorder 1174begin 1175 1176lemma mono_invE: 1177 fixes f :: "'a \<Rightarrow> 'b::order" 1178 assumes "mono f" 1179 assumes "f x < f y" 1180 obtains "x \<le> y" 1181proof 1182 show "x \<le> y" 1183 proof (rule ccontr) 1184 assume "\<not> x \<le> y" 1185 then have "y \<le> x" by simp 1186 with \<open>mono f\<close> obtain "f y \<le> f x" by (rule monoE) 1187 with \<open>f x < f y\<close> show False by simp 1188 qed 1189qed 1190 1191lemma mono_strict_invE: 1192 fixes f :: "'a \<Rightarrow> 'b::order" 1193 assumes "mono f" 1194 assumes "f x < f y" 1195 obtains "x < y" 1196proof 1197 show "x < y" 1198 proof (rule ccontr) 1199 assume "\<not> x < y" 1200 then have "y \<le> x" by simp 1201 with \<open>mono f\<close> obtain "f y \<le> f x" by (rule monoE) 1202 with \<open>f x < f y\<close> show False by simp 1203 qed 1204qed 1205 1206lemma strict_mono_eq: 1207 assumes "strict_mono f" 1208 shows "f x = f y \<longleftrightarrow> x = y" 1209proof 1210 assume "f x = f y" 1211 show "x = y" proof (cases x y rule: linorder_cases) 1212 case less with assms strict_monoD have "f x < f y" by auto 1213 with \<open>f x = f y\<close> show ?thesis by simp 1214 next 1215 case equal then show ?thesis . 1216 next 1217 case greater with assms strict_monoD have "f y < f x" by auto 1218 with \<open>f x = f y\<close> show ?thesis by simp 1219 qed 1220qed simp 1221 1222lemma strict_mono_less_eq: 1223 assumes "strict_mono f" 1224 shows "f x \<le> f y \<longleftrightarrow> x \<le> y" 1225proof 1226 assume "x \<le> y" 1227 with assms strict_mono_mono monoD show "f x \<le> f y" by auto 1228next 1229 assume "f x \<le> f y" 1230 show "x \<le> y" proof (rule ccontr) 1231 assume "\<not> x \<le> y" then have "y < x" by simp 1232 with assms strict_monoD have "f y < f x" by auto 1233 with \<open>f x \<le> f y\<close> show False by simp 1234 qed 1235qed 1236 1237lemma strict_mono_less: 1238 assumes "strict_mono f" 1239 shows "f x < f y \<longleftrightarrow> x < y" 1240 using assms 1241 by (auto simp add: less_le Orderings.less_le strict_mono_eq strict_mono_less_eq) 1242 1243end 1244 1245 1246subsection \<open>min and max -- fundamental\<close> 1247 1248definition (in ord) min :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" where 1249 "min a b = (if a \<le> b then a else b)" 1250 1251definition (in ord) max :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" where 1252 "max a b = (if a \<le> b then b else a)" 1253 1254lemma min_absorb1: "x \<le> y \<Longrightarrow> min x y = x" 1255 by (simp add: min_def) 1256 1257lemma max_absorb2: "x \<le> y \<Longrightarrow> max x y = y" 1258 by (simp add: max_def) 1259 1260lemma min_absorb2: "(y::'a::order) \<le> x \<Longrightarrow> min x y = y" 1261 by (simp add:min_def) 1262 1263lemma max_absorb1: "(y::'a::order) \<le> x \<Longrightarrow> max x y = x" 1264 by (simp add: max_def) 1265 1266lemma max_min_same [simp]: 1267 fixes x y :: "'a :: linorder" 1268 shows "max x (min x y) = x" "max (min x y) x = x" "max (min x y) y = y" "max y (min x y) = y" 1269by(auto simp add: max_def min_def) 1270 1271 1272subsection \<open>(Unique) top and bottom elements\<close> 1273 1274class bot = 1275 fixes bot :: 'a ("\<bottom>") 1276 1277class order_bot = order + bot + 1278 assumes bot_least: "\<bottom> \<le> a" 1279begin 1280 1281sublocale bot: ordering_top greater_eq greater bot 1282 by standard (fact bot_least) 1283 1284lemma le_bot: 1285 "a \<le> \<bottom> \<Longrightarrow> a = \<bottom>" 1286 by (fact bot.extremum_uniqueI) 1287 1288lemma bot_unique: 1289 "a \<le> \<bottom> \<longleftrightarrow> a = \<bottom>" 1290 by (fact bot.extremum_unique) 1291 1292lemma not_less_bot: 1293 "\<not> a < \<bottom>" 1294 by (fact bot.extremum_strict) 1295 1296lemma bot_less: 1297 "a \<noteq> \<bottom> \<longleftrightarrow> \<bottom> < a" 1298 by (fact bot.not_eq_extremum) 1299 1300lemma max_bot[simp]: "max bot x = x" 1301by(simp add: max_def bot_unique) 1302 1303lemma max_bot2[simp]: "max x bot = x" 1304by(simp add: max_def bot_unique) 1305 1306lemma min_bot[simp]: "min bot x = bot" 1307by(simp add: min_def bot_unique) 1308 1309lemma min_bot2[simp]: "min x bot = bot" 1310by(simp add: min_def bot_unique) 1311 1312end 1313 1314class top = 1315 fixes top :: 'a ("\<top>") 1316 1317class order_top = order + top + 1318 assumes top_greatest: "a \<le> \<top>" 1319begin 1320 1321sublocale top: ordering_top less_eq less top 1322 by standard (fact top_greatest) 1323 1324lemma top_le: 1325 "\<top> \<le> a \<Longrightarrow> a = \<top>" 1326 by (fact top.extremum_uniqueI) 1327 1328lemma top_unique: 1329 "\<top> \<le> a \<longleftrightarrow> a = \<top>" 1330 by (fact top.extremum_unique) 1331 1332lemma not_top_less: 1333 "\<not> \<top> < a" 1334 by (fact top.extremum_strict) 1335 1336lemma less_top: 1337 "a \<noteq> \<top> \<longleftrightarrow> a < \<top>" 1338 by (fact top.not_eq_extremum) 1339 1340lemma max_top[simp]: "max top x = top" 1341by(simp add: max_def top_unique) 1342 1343lemma max_top2[simp]: "max x top = top" 1344by(simp add: max_def top_unique) 1345 1346lemma min_top[simp]: "min top x = x" 1347by(simp add: min_def top_unique) 1348 1349lemma min_top2[simp]: "min x top = x" 1350by(simp add: min_def top_unique) 1351 1352end 1353 1354 1355subsection \<open>Dense orders\<close> 1356 1357class dense_order = order + 1358 assumes dense: "x < y \<Longrightarrow> (\<exists>z. x < z \<and> z < y)" 1359 1360class dense_linorder = linorder + dense_order 1361begin 1362 1363lemma dense_le: 1364 fixes y z :: 'a 1365 assumes "\<And>x. x < y \<Longrightarrow> x \<le> z" 1366 shows "y \<le> z" 1367proof (rule ccontr) 1368 assume "\<not> ?thesis" 1369 hence "z < y" by simp 1370 from dense[OF this] 1371 obtain x where "x < y" and "z < x" by safe 1372 moreover have "x \<le> z" using assms[OF \<open>x < y\<close>] . 1373 ultimately show False by auto 1374qed 1375 1376lemma dense_le_bounded: 1377 fixes x y z :: 'a 1378 assumes "x < y" 1379 assumes *: "\<And>w. \<lbrakk> x < w ; w < y \<rbrakk> \<Longrightarrow> w \<le> z" 1380 shows "y \<le> z" 1381proof (rule dense_le) 1382 fix w assume "w < y" 1383 from dense[OF \<open>x < y\<close>] obtain u where "x < u" "u < y" by safe 1384 from linear[of u w] 1385 show "w \<le> z" 1386 proof (rule disjE) 1387 assume "u \<le> w" 1388 from less_le_trans[OF \<open>x < u\<close> \<open>u \<le> w\<close>] \<open>w < y\<close> 1389 show "w \<le> z" by (rule *) 1390 next 1391 assume "w \<le> u" 1392 from \<open>w \<le> u\<close> *[OF \<open>x < u\<close> \<open>u < y\<close>] 1393 show "w \<le> z" by (rule order_trans) 1394 qed 1395qed 1396 1397lemma dense_ge: 1398 fixes y z :: 'a 1399 assumes "\<And>x. z < x \<Longrightarrow> y \<le> x" 1400 shows "y \<le> z" 1401proof (rule ccontr) 1402 assume "\<not> ?thesis" 1403 hence "z < y" by simp 1404 from dense[OF this] 1405 obtain x where "x < y" and "z < x" by safe 1406 moreover have "y \<le> x" using assms[OF \<open>z < x\<close>] . 1407 ultimately show False by auto 1408qed 1409 1410lemma dense_ge_bounded: 1411 fixes x y z :: 'a 1412 assumes "z < x" 1413 assumes *: "\<And>w. \<lbrakk> z < w ; w < x \<rbrakk> \<Longrightarrow> y \<le> w" 1414 shows "y \<le> z" 1415proof (rule dense_ge) 1416 fix w assume "z < w" 1417 from dense[OF \<open>z < x\<close>] obtain u where "z < u" "u < x" by safe 1418 from linear[of u w] 1419 show "y \<le> w" 1420 proof (rule disjE) 1421 assume "w \<le> u" 1422 from \<open>z < w\<close> le_less_trans[OF \<open>w \<le> u\<close> \<open>u < x\<close>] 1423 show "y \<le> w" by (rule *) 1424 next 1425 assume "u \<le> w" 1426 from *[OF \<open>z < u\<close> \<open>u < x\<close>] \<open>u \<le> w\<close> 1427 show "y \<le> w" by (rule order_trans) 1428 qed 1429qed 1430 1431end 1432 1433class no_top = order + 1434 assumes gt_ex: "\<exists>y. x < y" 1435 1436class no_bot = order + 1437 assumes lt_ex: "\<exists>y. y < x" 1438 1439class unbounded_dense_linorder = dense_linorder + no_top + no_bot 1440 1441 1442subsection \<open>Wellorders\<close> 1443 1444class wellorder = linorder + 1445 assumes less_induct [case_names less]: "(\<And>x. (\<And>y. y < x \<Longrightarrow> P y) \<Longrightarrow> P x) \<Longrightarrow> P a" 1446begin 1447 1448lemma wellorder_Least_lemma: 1449 fixes k :: 'a 1450 assumes "P k" 1451 shows LeastI: "P (LEAST x. P x)" and Least_le: "(LEAST x. P x) \<le> k" 1452proof - 1453 have "P (LEAST x. P x) \<and> (LEAST x. P x) \<le> k" 1454 using assms proof (induct k rule: less_induct) 1455 case (less x) then have "P x" by simp 1456 show ?case proof (rule classical) 1457 assume assm: "\<not> (P (LEAST a. P a) \<and> (LEAST a. P a) \<le> x)" 1458 have "\<And>y. P y \<Longrightarrow> x \<le> y" 1459 proof (rule classical) 1460 fix y 1461 assume "P y" and "\<not> x \<le> y" 1462 with less have "P (LEAST a. P a)" and "(LEAST a. P a) \<le> y" 1463 by (auto simp add: not_le) 1464 with assm have "x < (LEAST a. P a)" and "(LEAST a. P a) \<le> y" 1465 by auto 1466 then show "x \<le> y" by auto 1467 qed 1468 with \<open>P x\<close> have Least: "(LEAST a. P a) = x" 1469 by (rule Least_equality) 1470 with \<open>P x\<close> show ?thesis by simp 1471 qed 1472 qed 1473 then show "P (LEAST x. P x)" and "(LEAST x. P x) \<le> k" by auto 1474qed 1475 1476\<comment> \<open>The following 3 lemmas are due to Brian Huffman\<close> 1477lemma LeastI_ex: "\<exists>x. P x \<Longrightarrow> P (Least P)" 1478 by (erule exE) (erule LeastI) 1479 1480lemma LeastI2: 1481 "P a \<Longrightarrow> (\<And>x. P x \<Longrightarrow> Q x) \<Longrightarrow> Q (Least P)" 1482 by (blast intro: LeastI) 1483 1484lemma LeastI2_ex: 1485 "\<exists>a. P a \<Longrightarrow> (\<And>x. P x \<Longrightarrow> Q x) \<Longrightarrow> Q (Least P)" 1486 by (blast intro: LeastI_ex) 1487 1488lemma LeastI2_wellorder: 1489 assumes "P a" 1490 and "\<And>a. \<lbrakk> P a; \<forall>b. P b \<longrightarrow> a \<le> b \<rbrakk> \<Longrightarrow> Q a" 1491 shows "Q (Least P)" 1492proof (rule LeastI2_order) 1493 show "P (Least P)" using \<open>P a\<close> by (rule LeastI) 1494next 1495 fix y assume "P y" thus "Least P \<le> y" by (rule Least_le) 1496next 1497 fix x assume "P x" "\<forall>y. P y \<longrightarrow> x \<le> y" thus "Q x" by (rule assms(2)) 1498qed 1499 1500lemma LeastI2_wellorder_ex: 1501 assumes "\<exists>x. P x" 1502 and "\<And>a. \<lbrakk> P a; \<forall>b. P b \<longrightarrow> a \<le> b \<rbrakk> \<Longrightarrow> Q a" 1503 shows "Q (Least P)" 1504using assms by clarify (blast intro!: LeastI2_wellorder) 1505 1506lemma not_less_Least: "k < (LEAST x. P x) \<Longrightarrow> \<not> P k" 1507apply (simp add: not_le [symmetric]) 1508apply (erule contrapos_nn) 1509apply (erule Least_le) 1510done 1511 1512lemma exists_least_iff: "(\<exists>n. P n) \<longleftrightarrow> (\<exists>n. P n \<and> (\<forall>m < n. \<not> P m))" (is "?lhs \<longleftrightarrow> ?rhs") 1513proof 1514 assume ?rhs thus ?lhs by blast 1515next 1516 assume H: ?lhs then obtain n where n: "P n" by blast 1517 let ?x = "Least P" 1518 { fix m assume m: "m < ?x" 1519 from not_less_Least[OF m] have "\<not> P m" . } 1520 with LeastI_ex[OF H] show ?rhs by blast 1521qed 1522 1523end 1524 1525 1526subsection \<open>Order on @{typ bool}\<close> 1527 1528instantiation bool :: "{order_bot, order_top, linorder}" 1529begin 1530 1531definition 1532 le_bool_def [simp]: "P \<le> Q \<longleftrightarrow> P \<longrightarrow> Q" 1533 1534definition 1535 [simp]: "(P::bool) < Q \<longleftrightarrow> \<not> P \<and> Q" 1536 1537definition 1538 [simp]: "\<bottom> \<longleftrightarrow> False" 1539 1540definition 1541 [simp]: "\<top> \<longleftrightarrow> True" 1542 1543instance proof 1544qed auto 1545 1546end 1547 1548lemma le_boolI: "(P \<Longrightarrow> Q) \<Longrightarrow> P \<le> Q" 1549 by simp 1550 1551lemma le_boolI': "P \<longrightarrow> Q \<Longrightarrow> P \<le> Q" 1552 by simp 1553 1554lemma le_boolE: "P \<le> Q \<Longrightarrow> P \<Longrightarrow> (Q \<Longrightarrow> R) \<Longrightarrow> R" 1555 by simp 1556 1557lemma le_boolD: "P \<le> Q \<Longrightarrow> P \<longrightarrow> Q" 1558 by simp 1559 1560lemma bot_boolE: "\<bottom> \<Longrightarrow> P" 1561 by simp 1562 1563lemma top_boolI: \<top> 1564 by simp 1565 1566lemma [code]: 1567 "False \<le> b \<longleftrightarrow> True" 1568 "True \<le> b \<longleftrightarrow> b" 1569 "False < b \<longleftrightarrow> b" 1570 "True < b \<longleftrightarrow> False" 1571 by simp_all 1572 1573 1574subsection \<open>Order on @{typ "_ \<Rightarrow> _"}\<close> 1575 1576instantiation "fun" :: (type, ord) ord 1577begin 1578 1579definition 1580 le_fun_def: "f \<le> g \<longleftrightarrow> (\<forall>x. f x \<le> g x)" 1581 1582definition 1583 "(f::'a \<Rightarrow> 'b) < g \<longleftrightarrow> f \<le> g \<and> \<not> (g \<le> f)" 1584 1585instance .. 1586 1587end 1588 1589instance "fun" :: (type, preorder) preorder proof 1590qed (auto simp add: le_fun_def less_fun_def 1591 intro: order_trans antisym) 1592 1593instance "fun" :: (type, order) order proof 1594qed (auto simp add: le_fun_def intro: antisym) 1595 1596instantiation "fun" :: (type, bot) bot 1597begin 1598 1599definition 1600 "\<bottom> = (\<lambda>x. \<bottom>)" 1601 1602instance .. 1603 1604end 1605 1606instantiation "fun" :: (type, order_bot) order_bot 1607begin 1608 1609lemma bot_apply [simp, code]: 1610 "\<bottom> x = \<bottom>" 1611 by (simp add: bot_fun_def) 1612 1613instance proof 1614qed (simp add: le_fun_def) 1615 1616end 1617 1618instantiation "fun" :: (type, top) top 1619begin 1620 1621definition 1622 [no_atp]: "\<top> = (\<lambda>x. \<top>)" 1623 1624instance .. 1625 1626end 1627 1628instantiation "fun" :: (type, order_top) order_top 1629begin 1630 1631lemma top_apply [simp, code]: 1632 "\<top> x = \<top>" 1633 by (simp add: top_fun_def) 1634 1635instance proof 1636qed (simp add: le_fun_def) 1637 1638end 1639 1640lemma le_funI: "(\<And>x. f x \<le> g x) \<Longrightarrow> f \<le> g" 1641 unfolding le_fun_def by simp 1642 1643lemma le_funE: "f \<le> g \<Longrightarrow> (f x \<le> g x \<Longrightarrow> P) \<Longrightarrow> P" 1644 unfolding le_fun_def by simp 1645 1646lemma le_funD: "f \<le> g \<Longrightarrow> f x \<le> g x" 1647 by (rule le_funE) 1648 1649lemma mono_compose: "mono Q \<Longrightarrow> mono (\<lambda>i x. Q i (f x))" 1650 unfolding mono_def le_fun_def by auto 1651 1652 1653subsection \<open>Order on unary and binary predicates\<close> 1654 1655lemma predicate1I: 1656 assumes PQ: "\<And>x. P x \<Longrightarrow> Q x" 1657 shows "P \<le> Q" 1658 apply (rule le_funI) 1659 apply (rule le_boolI) 1660 apply (rule PQ) 1661 apply assumption 1662 done 1663 1664lemma predicate1D: 1665 "P \<le> Q \<Longrightarrow> P x \<Longrightarrow> Q x" 1666 apply (erule le_funE) 1667 apply (erule le_boolE) 1668 apply assumption+ 1669 done 1670 1671lemma rev_predicate1D: 1672 "P x \<Longrightarrow> P \<le> Q \<Longrightarrow> Q x" 1673 by (rule predicate1D) 1674 1675lemma predicate2I: 1676 assumes PQ: "\<And>x y. P x y \<Longrightarrow> Q x y" 1677 shows "P \<le> Q" 1678 apply (rule le_funI)+ 1679 apply (rule le_boolI) 1680 apply (rule PQ) 1681 apply assumption 1682 done 1683 1684lemma predicate2D: 1685 "P \<le> Q \<Longrightarrow> P x y \<Longrightarrow> Q x y" 1686 apply (erule le_funE)+ 1687 apply (erule le_boolE) 1688 apply assumption+ 1689 done 1690 1691lemma rev_predicate2D: 1692 "P x y \<Longrightarrow> P \<le> Q \<Longrightarrow> Q x y" 1693 by (rule predicate2D) 1694 1695lemma bot1E [no_atp]: "\<bottom> x \<Longrightarrow> P" 1696 by (simp add: bot_fun_def) 1697 1698lemma bot2E: "\<bottom> x y \<Longrightarrow> P" 1699 by (simp add: bot_fun_def) 1700 1701lemma top1I: "\<top> x" 1702 by (simp add: top_fun_def) 1703 1704lemma top2I: "\<top> x y" 1705 by (simp add: top_fun_def) 1706 1707 1708subsection \<open>Name duplicates\<close> 1709 1710lemmas order_eq_refl = preorder_class.eq_refl 1711lemmas order_less_irrefl = preorder_class.less_irrefl 1712lemmas order_less_imp_le = preorder_class.less_imp_le 1713lemmas order_less_not_sym = preorder_class.less_not_sym 1714lemmas order_less_asym = preorder_class.less_asym 1715lemmas order_less_trans = preorder_class.less_trans 1716lemmas order_le_less_trans = preorder_class.le_less_trans 1717lemmas order_less_le_trans = preorder_class.less_le_trans 1718lemmas order_less_imp_not_less = preorder_class.less_imp_not_less 1719lemmas order_less_imp_triv = preorder_class.less_imp_triv 1720lemmas order_less_asym' = preorder_class.less_asym' 1721 1722lemmas order_less_le = order_class.less_le 1723lemmas order_le_less = order_class.le_less 1724lemmas order_le_imp_less_or_eq = order_class.le_imp_less_or_eq 1725lemmas order_less_imp_not_eq = order_class.less_imp_not_eq 1726lemmas order_less_imp_not_eq2 = order_class.less_imp_not_eq2 1727lemmas order_neq_le_trans = order_class.neq_le_trans 1728lemmas order_le_neq_trans = order_class.le_neq_trans 1729lemmas order_antisym = order_class.antisym 1730lemmas order_eq_iff = order_class.eq_iff 1731lemmas order_antisym_conv = order_class.antisym_conv 1732 1733lemmas linorder_linear = linorder_class.linear 1734lemmas linorder_less_linear = linorder_class.less_linear 1735lemmas linorder_le_less_linear = linorder_class.le_less_linear 1736lemmas linorder_le_cases = linorder_class.le_cases 1737lemmas linorder_not_less = linorder_class.not_less 1738lemmas linorder_not_le = linorder_class.not_le 1739lemmas linorder_neq_iff = linorder_class.neq_iff 1740lemmas linorder_neqE = linorder_class.neqE 1741lemmas linorder_antisym_conv1 = linorder_class.antisym_conv1 1742lemmas linorder_antisym_conv2 = linorder_class.antisym_conv2 1743lemmas linorder_antisym_conv3 = linorder_class.antisym_conv3 1744 1745end 1746