1(* Title: HOL/Orderings.thy 2 Author: Tobias Nipkow, Markus Wenzel, and Larry Paulson 3*) 4 5section \<open>Abstract orderings\<close> 6 7theory Orderings 8imports HOL 9keywords "print_orders" :: diag 10begin 11 12ML_file \<open>~~/src/Provers/order.ML\<close> 13 14subsection \<open>Abstract ordering\<close> 15 16locale ordering = 17 fixes less_eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infix "\<^bold>\<le>" 50) 18 and less :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infix "\<^bold><" 50) 19 assumes strict_iff_order: "a \<^bold>< b \<longleftrightarrow> a \<^bold>\<le> b \<and> a \<noteq> b" 20 assumes refl: "a \<^bold>\<le> a" \<comment> \<open>not \<open>iff\<close>: makes problems due to multiple (dual) interpretations\<close> 21 and antisym: "a \<^bold>\<le> b \<Longrightarrow> b \<^bold>\<le> a \<Longrightarrow> a = b" 22 and trans: "a \<^bold>\<le> b \<Longrightarrow> b \<^bold>\<le> c \<Longrightarrow> a \<^bold>\<le> c" 23begin 24 25lemma strict_implies_order: 26 "a \<^bold>< b \<Longrightarrow> a \<^bold>\<le> b" 27 by (simp add: strict_iff_order) 28 29lemma strict_implies_not_eq: 30 "a \<^bold>< b \<Longrightarrow> a \<noteq> b" 31 by (simp add: strict_iff_order) 32 33lemma not_eq_order_implies_strict: 34 "a \<noteq> b \<Longrightarrow> a \<^bold>\<le> b \<Longrightarrow> a \<^bold>< b" 35 by (simp add: strict_iff_order) 36 37lemma order_iff_strict: 38 "a \<^bold>\<le> b \<longleftrightarrow> a \<^bold>< b \<or> a = b" 39 by (auto simp add: strict_iff_order refl) 40 41lemma irrefl: \<comment> \<open>not \<open>iff\<close>: makes problems due to multiple (dual) interpretations\<close> 42 "\<not> a \<^bold>< a" 43 by (simp add: strict_iff_order) 44 45lemma asym: 46 "a \<^bold>< b \<Longrightarrow> b \<^bold>< a \<Longrightarrow> False" 47 by (auto simp add: strict_iff_order intro: antisym) 48 49lemma strict_trans1: 50 "a \<^bold>\<le> b \<Longrightarrow> b \<^bold>< c \<Longrightarrow> a \<^bold>< c" 51 by (auto simp add: strict_iff_order intro: trans antisym) 52 53lemma strict_trans2: 54 "a \<^bold>< b \<Longrightarrow> b \<^bold>\<le> c \<Longrightarrow> a \<^bold>< c" 55 by (auto simp add: strict_iff_order intro: trans antisym) 56 57lemma strict_trans: 58 "a \<^bold>< b \<Longrightarrow> b \<^bold>< c \<Longrightarrow> a \<^bold>< c" 59 by (auto intro: strict_trans1 strict_implies_order) 60 61end 62 63text \<open>Alternative introduction rule with bias towards strict order\<close> 64 65lemma ordering_strictI: 66 fixes less_eq (infix "\<^bold>\<le>" 50) 67 and less (infix "\<^bold><" 50) 68 assumes less_eq_less: "\<And>a b. a \<^bold>\<le> b \<longleftrightarrow> a \<^bold>< b \<or> a = b" 69 assumes asym: "\<And>a b. a \<^bold>< b \<Longrightarrow> \<not> b \<^bold>< a" 70 assumes irrefl: "\<And>a. \<not> a \<^bold>< a" 71 assumes trans: "\<And>a b c. a \<^bold>< b \<Longrightarrow> b \<^bold>< c \<Longrightarrow> a \<^bold>< c" 72 shows "ordering less_eq less" 73proof 74 fix a b 75 show "a \<^bold>< b \<longleftrightarrow> a \<^bold>\<le> b \<and> a \<noteq> b" 76 by (auto simp add: less_eq_less asym irrefl) 77next 78 fix a 79 show "a \<^bold>\<le> a" 80 by (auto simp add: less_eq_less) 81next 82 fix a b c 83 assume "a \<^bold>\<le> b" and "b \<^bold>\<le> c" then show "a \<^bold>\<le> c" 84 by (auto simp add: less_eq_less intro: trans) 85next 86 fix a b 87 assume "a \<^bold>\<le> b" and "b \<^bold>\<le> a" then show "a = b" 88 by (auto simp add: less_eq_less asym) 89qed 90 91lemma ordering_dualI: 92 fixes less_eq (infix "\<^bold>\<le>" 50) 93 and less (infix "\<^bold><" 50) 94 assumes "ordering (\<lambda>a b. b \<^bold>\<le> a) (\<lambda>a b. b \<^bold>< a)" 95 shows "ordering less_eq less" 96proof - 97 from assms interpret ordering "\<lambda>a b. b \<^bold>\<le> a" "\<lambda>a b. b \<^bold>< a" . 98 show ?thesis 99 by standard (auto simp: strict_iff_order refl intro: antisym trans) 100qed 101 102locale ordering_top = ordering + 103 fixes top :: "'a" ("\<^bold>\<top>") 104 assumes extremum [simp]: "a \<^bold>\<le> \<^bold>\<top>" 105begin 106 107lemma extremum_uniqueI: 108 "\<^bold>\<top> \<^bold>\<le> a \<Longrightarrow> a = \<^bold>\<top>" 109 by (rule antisym) auto 110 111lemma extremum_unique: 112 "\<^bold>\<top> \<^bold>\<le> a \<longleftrightarrow> a = \<^bold>\<top>" 113 by (auto intro: antisym) 114 115lemma extremum_strict [simp]: 116 "\<not> (\<^bold>\<top> \<^bold>< a)" 117 using extremum [of a] by (auto simp add: order_iff_strict intro: asym irrefl) 118 119lemma not_eq_extremum: 120 "a \<noteq> \<^bold>\<top> \<longleftrightarrow> a \<^bold>< \<^bold>\<top>" 121 by (auto simp add: order_iff_strict intro: not_eq_order_implies_strict extremum) 122 123end 124 125 126subsection \<open>Syntactic orders\<close> 127 128class ord = 129 fixes less_eq :: "'a \<Rightarrow> 'a \<Rightarrow> bool" 130 and less :: "'a \<Rightarrow> 'a \<Rightarrow> bool" 131begin 132 133notation 134 less_eq ("'(\<le>')") and 135 less_eq ("(_/ \<le> _)" [51, 51] 50) and 136 less ("'(<')") and 137 less ("(_/ < _)" [51, 51] 50) 138 139abbreviation (input) 140 greater_eq (infix "\<ge>" 50) 141 where "x \<ge> y \<equiv> y \<le> x" 142 143abbreviation (input) 144 greater (infix ">" 50) 145 where "x > y \<equiv> y < x" 146 147notation (ASCII) 148 less_eq ("'(<=')") and 149 less_eq ("(_/ <= _)" [51, 51] 50) 150 151notation (input) 152 greater_eq (infix ">=" 50) 153 154end 155 156 157subsection \<open>Quasi orders\<close> 158 159class preorder = ord + 160 assumes less_le_not_le: "x < y \<longleftrightarrow> x \<le> y \<and> \<not> (y \<le> x)" 161 and order_refl [iff]: "x \<le> x" 162 and order_trans: "x \<le> y \<Longrightarrow> y \<le> z \<Longrightarrow> x \<le> z" 163begin 164 165text \<open>Reflexivity.\<close> 166 167lemma eq_refl: "x = y \<Longrightarrow> x \<le> y" 168 \<comment> \<open>This form is useful with the classical reasoner.\<close> 169by (erule ssubst) (rule order_refl) 170 171lemma less_irrefl [iff]: "\<not> x < x" 172by (simp add: less_le_not_le) 173 174lemma less_imp_le: "x < y \<Longrightarrow> x \<le> y" 175by (simp add: less_le_not_le) 176 177 178text \<open>Asymmetry.\<close> 179 180lemma less_not_sym: "x < y \<Longrightarrow> \<not> (y < x)" 181by (simp add: less_le_not_le) 182 183lemma less_asym: "x < y \<Longrightarrow> (\<not> P \<Longrightarrow> y < x) \<Longrightarrow> P" 184by (drule less_not_sym, erule contrapos_np) simp 185 186 187text \<open>Transitivity.\<close> 188 189lemma less_trans: "x < y \<Longrightarrow> y < z \<Longrightarrow> x < z" 190by (auto simp add: less_le_not_le intro: order_trans) 191 192lemma le_less_trans: "x \<le> y \<Longrightarrow> y < z \<Longrightarrow> x < z" 193by (auto simp add: less_le_not_le intro: order_trans) 194 195lemma less_le_trans: "x < y \<Longrightarrow> y \<le> z \<Longrightarrow> x < z" 196by (auto simp add: less_le_not_le intro: order_trans) 197 198 199text \<open>Useful for simplification, but too risky to include by default.\<close> 200 201lemma less_imp_not_less: "x < y \<Longrightarrow> (\<not> y < x) \<longleftrightarrow> True" 202by (blast elim: less_asym) 203 204lemma less_imp_triv: "x < y \<Longrightarrow> (y < x \<longrightarrow> P) \<longleftrightarrow> True" 205by (blast elim: less_asym) 206 207 208text \<open>Transitivity rules for calculational reasoning\<close> 209 210lemma less_asym': "a < b \<Longrightarrow> b < a \<Longrightarrow> P" 211by (rule less_asym) 212 213 214text \<open>Dual order\<close> 215 216lemma dual_preorder: 217 "class.preorder (\<ge>) (>)" 218 by standard (auto simp add: less_le_not_le intro: order_trans) 219 220end 221 222 223subsection \<open>Partial orders\<close> 224 225class order = preorder + 226 assumes antisym: "x \<le> y \<Longrightarrow> y \<le> x \<Longrightarrow> x = y" 227begin 228 229lemma less_le: "x < y \<longleftrightarrow> x \<le> y \<and> x \<noteq> y" 230 by (auto simp add: less_le_not_le intro: antisym) 231 232sublocale order: ordering less_eq less + dual_order: ordering greater_eq greater 233proof - 234 interpret ordering less_eq less 235 by standard (auto intro: antisym order_trans simp add: less_le) 236 show "ordering less_eq less" 237 by (fact ordering_axioms) 238 then show "ordering greater_eq greater" 239 by (rule ordering_dualI) 240qed 241 242text \<open>Reflexivity.\<close> 243 244lemma le_less: "x \<le> y \<longleftrightarrow> x < y \<or> x = y" 245 \<comment> \<open>NOT suitable for iff, since it can cause PROOF FAILED.\<close> 246by (fact order.order_iff_strict) 247 248lemma le_imp_less_or_eq: "x \<le> y \<Longrightarrow> x < y \<or> x = y" 249by (simp add: less_le) 250 251 252text \<open>Useful for simplification, but too risky to include by default.\<close> 253 254lemma less_imp_not_eq: "x < y \<Longrightarrow> (x = y) \<longleftrightarrow> False" 255by auto 256 257lemma less_imp_not_eq2: "x < y \<Longrightarrow> (y = x) \<longleftrightarrow> False" 258by auto 259 260 261text \<open>Transitivity rules for calculational reasoning\<close> 262 263lemma neq_le_trans: "a \<noteq> b \<Longrightarrow> a \<le> b \<Longrightarrow> a < b" 264by (fact order.not_eq_order_implies_strict) 265 266lemma le_neq_trans: "a \<le> b \<Longrightarrow> a \<noteq> b \<Longrightarrow> a < b" 267by (rule order.not_eq_order_implies_strict) 268 269 270text \<open>Asymmetry.\<close> 271 272lemma eq_iff: "x = y \<longleftrightarrow> x \<le> y \<and> y \<le> x" 273by (blast intro: antisym) 274 275lemma antisym_conv: "y \<le> x \<Longrightarrow> x \<le> y \<longleftrightarrow> x = y" 276by (blast intro: antisym) 277 278lemma less_imp_neq: "x < y \<Longrightarrow> x \<noteq> y" 279by (fact order.strict_implies_not_eq) 280 281lemma antisym_conv1: "\<not> x < y \<Longrightarrow> x \<le> y \<longleftrightarrow> x = y" 282 by (simp add: local.le_less) 283 284lemma antisym_conv2: "x \<le> y \<Longrightarrow> \<not> x < y \<longleftrightarrow> x = y" 285 by (simp add: local.less_le) 286 287lemma leD: "y \<le> x \<Longrightarrow> \<not> x < y" 288 by (auto simp: less_le antisym) 289 290text \<open>Least value operator\<close> 291 292definition (in ord) 293 Least :: "('a \<Rightarrow> bool) \<Rightarrow> 'a" (binder "LEAST " 10) where 294 "Least P = (THE x. P x \<and> (\<forall>y. P y \<longrightarrow> x \<le> y))" 295 296lemma Least_equality: 297 assumes "P x" 298 and "\<And>y. P y \<Longrightarrow> x \<le> y" 299 shows "Least P = x" 300unfolding Least_def by (rule the_equality) 301 (blast intro: assms antisym)+ 302 303lemma LeastI2_order: 304 assumes "P x" 305 and "\<And>y. P y \<Longrightarrow> x \<le> y" 306 and "\<And>x. P x \<Longrightarrow> \<forall>y. P y \<longrightarrow> x \<le> y \<Longrightarrow> Q x" 307 shows "Q (Least P)" 308unfolding Least_def by (rule theI2) 309 (blast intro: assms antisym)+ 310 311lemma Least_ex1: 312 assumes "\<exists>!x. P x \<and> (\<forall>y. P y \<longrightarrow> x \<le> y)" 313 shows Least1I: "P (Least P)" and Least1_le: "P z \<Longrightarrow> Least P \<le> z" 314 using theI'[OF assms] 315 unfolding Least_def 316 by auto 317 318text \<open>Greatest value operator\<close> 319 320definition Greatest :: "('a \<Rightarrow> bool) \<Rightarrow> 'a" (binder "GREATEST " 10) where 321"Greatest P = (THE x. P x \<and> (\<forall>y. P y \<longrightarrow> x \<ge> y))" 322 323lemma GreatestI2_order: 324 "\<lbrakk> P x; 325 \<And>y. P y \<Longrightarrow> x \<ge> y; 326 \<And>x. \<lbrakk> P x; \<forall>y. P y \<longrightarrow> x \<ge> y \<rbrakk> \<Longrightarrow> Q x \<rbrakk> 327 \<Longrightarrow> Q (Greatest P)" 328unfolding Greatest_def 329by (rule theI2) (blast intro: antisym)+ 330 331lemma Greatest_equality: 332 "\<lbrakk> P x; \<And>y. P y \<Longrightarrow> x \<ge> y \<rbrakk> \<Longrightarrow> Greatest P = x" 333unfolding Greatest_def 334by (rule the_equality) (blast intro: antisym)+ 335 336end 337 338lemma ordering_orderI: 339 fixes less_eq (infix "\<^bold>\<le>" 50) 340 and less (infix "\<^bold><" 50) 341 assumes "ordering less_eq less" 342 shows "class.order less_eq less" 343proof - 344 from assms interpret ordering less_eq less . 345 show ?thesis 346 by standard (auto intro: antisym trans simp add: refl strict_iff_order) 347qed 348 349lemma order_strictI: 350 fixes less (infix "\<sqsubset>" 50) 351 and less_eq (infix "\<sqsubseteq>" 50) 352 assumes "\<And>a b. a \<sqsubseteq> b \<longleftrightarrow> a \<sqsubset> b \<or> a = b" 353 assumes "\<And>a b. a \<sqsubset> b \<Longrightarrow> \<not> b \<sqsubset> a" 354 assumes "\<And>a. \<not> a \<sqsubset> a" 355 assumes "\<And>a b c. a \<sqsubset> b \<Longrightarrow> b \<sqsubset> c \<Longrightarrow> a \<sqsubset> c" 356 shows "class.order less_eq less" 357 by (rule ordering_orderI) (rule ordering_strictI, (fact assms)+) 358 359context order 360begin 361 362text \<open>Dual order\<close> 363 364lemma dual_order: 365 "class.order (\<ge>) (>)" 366 using dual_order.ordering_axioms by (rule ordering_orderI) 367 368end 369 370 371subsection \<open>Linear (total) orders\<close> 372 373class linorder = order + 374 assumes linear: "x \<le> y \<or> y \<le> x" 375begin 376 377lemma less_linear: "x < y \<or> x = y \<or> y < x" 378unfolding less_le using less_le linear by blast 379 380lemma le_less_linear: "x \<le> y \<or> y < x" 381by (simp add: le_less less_linear) 382 383lemma le_cases [case_names le ge]: 384 "(x \<le> y \<Longrightarrow> P) \<Longrightarrow> (y \<le> x \<Longrightarrow> P) \<Longrightarrow> P" 385using linear by blast 386 387lemma (in linorder) le_cases3: 388 "\<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; 389 \<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" 390by (blast intro: le_cases) 391 392lemma linorder_cases [case_names less equal greater]: 393 "(x < y \<Longrightarrow> P) \<Longrightarrow> (x = y \<Longrightarrow> P) \<Longrightarrow> (y < x \<Longrightarrow> P) \<Longrightarrow> P" 394using less_linear by blast 395 396lemma linorder_wlog[case_names le sym]: 397 "(\<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" 398 by (cases rule: le_cases[of a b]) blast+ 399 400lemma not_less: "\<not> x < y \<longleftrightarrow> y \<le> x" 401 unfolding less_le 402 using linear by (blast intro: antisym) 403 404lemma not_less_iff_gr_or_eq: "\<not>(x < y) \<longleftrightarrow> (x > y \<or> x = y)" 405 by (auto simp add:not_less le_less) 406 407lemma not_le: "\<not> x \<le> y \<longleftrightarrow> y < x" 408 unfolding less_le 409 using linear by (blast intro: antisym) 410 411lemma neq_iff: "x \<noteq> y \<longleftrightarrow> x < y \<or> y < x" 412by (cut_tac x = x and y = y in less_linear, auto) 413 414lemma neqE: "x \<noteq> y \<Longrightarrow> (x < y \<Longrightarrow> R) \<Longrightarrow> (y < x \<Longrightarrow> R) \<Longrightarrow> R" 415by (simp add: neq_iff) blast 416 417lemma antisym_conv3: "\<not> y < x \<Longrightarrow> \<not> x < y \<longleftrightarrow> x = y" 418by (blast intro: antisym dest: not_less [THEN iffD1]) 419 420lemma leI: "\<not> x < y \<Longrightarrow> y \<le> x" 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>\<open>print_orders\<close> 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>\<open>Trueprop\<close> $ 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>\<open>Not\<close>, _) $ 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>\<open>less\<close>, 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 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>\<open>less_eq\<close>, 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 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>\<open>All\<close>; 770 val Ex_binder = Mixfix.binder_name \<^const_syntax>\<open>Ex\<close>; 771 val impl = \<^const_syntax>\<open>HOL.implies\<close>; 772 val conj = \<^const_syntax>\<open>HOL.conj\<close>; 773 val less = \<^const_syntax>\<open>less\<close>; 774 val less_eq = \<^const_syntax>\<open>less_eq\<close>; 775 776 val trans = 777 [((All_binder, impl, less), 778 (\<^syntax_const>\<open>_All_less\<close>, \<^syntax_const>\<open>_All_greater\<close>)), 779 ((All_binder, impl, less_eq), 780 (\<^syntax_const>\<open>_All_less_eq\<close>, \<^syntax_const>\<open>_All_greater_eq\<close>)), 781 ((Ex_binder, conj, less), 782 (\<^syntax_const>\<open>_Ex_less\<close>, \<^syntax_const>\<open>_Ex_greater\<close>)), 783 ((Ex_binder, conj, less_eq), 784 (\<^syntax_const>\<open>_Ex_less_eq\<close>, \<^syntax_const>\<open>_Ex_greater_eq\<close>))]; 785 786 fun matches_bound v t = 787 (case t of 788 Const (\<^syntax_const>\<open>_bound\<close>, _) $ 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>\<open>_bound\<close>, _) $ 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>\<open>bool\<close>\<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>\<open>_ \<Rightarrow> _\<close>\<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 1741 1742end 1743