79 "x >= y \<equiv> y <= x" |
79 "x >= y \<equiv> y <= x" |
80 |
80 |
81 notation (input) |
81 notation (input) |
82 greater_eq (infix "\<ge>" 50) |
82 greater_eq (infix "\<ge>" 50) |
83 |
83 |
|
84 hide const min max |
|
85 |
84 definition |
86 definition |
85 min :: "'a\<Colon>ord \<Rightarrow> 'a \<Rightarrow> 'a" where |
87 min :: "'a\<Colon>ord \<Rightarrow> 'a \<Rightarrow> 'a" where |
86 "min a b = (if a \<le> b then a else b)" |
88 "min a b = (if a \<le> b then a else b)" |
87 |
89 |
88 definition |
90 definition |
89 max :: "'a\<Colon>ord \<Rightarrow> 'a \<Rightarrow> 'a" where |
91 max :: "'a\<Colon>ord \<Rightarrow> 'a \<Rightarrow> 'a" where |
90 "max a b = (if a \<le> b then b else a)" |
92 "max a b = (if a \<le> b then b else a)" |
91 |
93 |
92 lemma min_linorder: |
94 lemma linorder_class_min: |
93 "ord.min (op \<le> \<Colon> 'a\<Colon>ord \<Rightarrow> 'a \<Rightarrow> bool) = min" |
95 "ord.min (op \<le> \<Colon> 'a\<Colon>ord \<Rightarrow> 'a \<Rightarrow> bool) = min" |
94 by rule+ (simp add: min_def ord_class.min_def) |
96 by rule+ (simp add: min_def ord_class.min_def) |
95 |
97 |
96 lemma max_linorder: |
98 lemma linorder_class_max: |
97 "ord.max (op \<le> \<Colon> 'a\<Colon>ord \<Rightarrow> 'a \<Rightarrow> bool) = max" |
99 "ord.max (op \<le> \<Colon> 'a\<Colon>ord \<Rightarrow> 'a \<Rightarrow> bool) = max" |
98 by rule+ (simp add: max_def ord_class.max_def) |
100 by rule+ (simp add: max_def ord_class.max_def) |
99 |
101 |
100 |
102 |
101 subsection {* Partial orders *} |
103 subsection {* Partial orders *} |
191 text {* Transitivity rules for calculational reasoning *} |
193 text {* Transitivity rules for calculational reasoning *} |
192 |
194 |
193 lemma less_asym': "a \<^loc>< b \<Longrightarrow> b \<^loc>< a \<Longrightarrow> P" |
195 lemma less_asym': "a \<^loc>< b \<Longrightarrow> b \<^loc>< a \<Longrightarrow> P" |
194 by (rule less_asym) |
196 by (rule less_asym) |
195 |
197 |
|
198 |
|
199 text {* Reverse order *} |
|
200 |
|
201 lemma order_reverse: |
|
202 "order_pred (\<lambda>x y. y \<^loc>\<le> x) (\<lambda>x y. y \<^loc>< x)" |
|
203 by unfold_locales |
|
204 (simp add: less_le, auto intro: antisym order_trans) |
|
205 |
196 end |
206 end |
197 |
207 |
198 |
208 |
199 subsection {* Linear (total) orders *} |
209 subsection {* Linear (total) orders *} |
200 |
210 |
250 |
260 |
251 (*FIXME inappropriate name (or delete altogether)*) |
261 (*FIXME inappropriate name (or delete altogether)*) |
252 lemma not_leE: "\<not> y \<^loc>\<le> x \<Longrightarrow> x \<^loc>< y" |
262 lemma not_leE: "\<not> y \<^loc>\<le> x \<Longrightarrow> x \<^loc>< y" |
253 unfolding not_le . |
263 unfolding not_le . |
254 |
264 |
|
265 |
|
266 text {* Reverse order *} |
|
267 |
|
268 lemma linorder_reverse: |
|
269 "linorder_pred (\<lambda>x y. y \<^loc>\<le> x) (\<lambda>x y. y \<^loc>< x)" |
|
270 by unfold_locales |
|
271 (simp add: less_le, auto intro: antisym order_trans simp add: linear) |
|
272 |
|
273 |
255 text {* min/max properties *} |
274 text {* min/max properties *} |
256 |
275 |
257 lemma min_le_iff_disj: |
276 lemma min_le_iff_disj: |
258 "min x y \<^loc>\<le> z \<longleftrightarrow> x \<^loc>\<le> z \<or> y \<^loc>\<le> z" |
277 "min x y \<^loc>\<le> z \<longleftrightarrow> x \<^loc>\<le> z \<or> y \<^loc>\<le> z" |
259 unfolding min_def using linear by (auto intro: order_trans) |
278 unfolding min_def using linear by (auto intro: order_trans) |
286 "P (max i j) \<longleftrightarrow> (i \<^loc>\<le> j \<longrightarrow> P j) \<and> (\<not> i \<^loc>\<le> j \<longrightarrow> P i)" |
305 "P (max i j) \<longleftrightarrow> (i \<^loc>\<le> j \<longrightarrow> P j) \<and> (\<not> i \<^loc>\<le> j \<longrightarrow> P i)" |
287 by (simp add: max_def) |
306 by (simp add: max_def) |
288 |
307 |
289 end |
308 end |
290 |
309 |
291 |
310 subsection {* Name duplicates -- including min/max interpretation *} |
292 subsection {* Name duplicates *} |
|
293 |
311 |
294 lemmas order_less_le = less_le |
312 lemmas order_less_le = less_le |
295 lemmas order_eq_refl = order_class.eq_refl |
313 lemmas order_eq_refl = order_class.eq_refl |
296 lemmas order_less_irrefl = order_class.less_irrefl |
314 lemmas order_less_irrefl = order_class.less_irrefl |
297 lemmas order_le_less = order_class.le_less |
315 lemmas order_le_less = order_class.le_less |
328 lemmas linorder_antisym_conv3 = linorder_class.antisym_conv3 |
346 lemmas linorder_antisym_conv3 = linorder_class.antisym_conv3 |
329 lemmas leI = linorder_class.leI |
347 lemmas leI = linorder_class.leI |
330 lemmas leD = linorder_class.leD |
348 lemmas leD = linorder_class.leD |
331 lemmas not_leE = linorder_class.not_leE |
349 lemmas not_leE = linorder_class.not_leE |
332 |
350 |
|
351 lemmas min_le_iff_disj = linorder_class.min_le_iff_disj [unfolded linorder_class_min] |
|
352 lemmas le_max_iff_disj = linorder_class.le_max_iff_disj [unfolded linorder_class_max] |
|
353 lemmas min_less_iff_disj = linorder_class.min_less_iff_disj [unfolded linorder_class_min] |
|
354 lemmas less_max_iff_disj = linorder_class.less_max_iff_disj [unfolded linorder_class_max] |
|
355 lemmas min_less_iff_conj [simp] = linorder_class.min_less_iff_conj [unfolded linorder_class_min] |
|
356 lemmas max_less_iff_conj [simp] = linorder_class.max_less_iff_conj [unfolded linorder_class_max] |
|
357 lemmas split_min = linorder_class.split_min [unfolded linorder_class_min] |
|
358 lemmas split_max = linorder_class.split_max [unfolded linorder_class_max] |
|
359 |
333 |
360 |
334 subsection {* Reasoning tools setup *} |
361 subsection {* Reasoning tools setup *} |
335 |
362 |
336 ML {* |
363 ML {* |
337 local |
364 local |
344 in |
371 in |
345 (* exclude numeric types: linear arithmetic subsumes transitivity *) |
372 (* exclude numeric types: linear arithmetic subsumes transitivity *) |
346 T <> HOLogic.natT andalso T <> HOLogic.intT |
373 T <> HOLogic.natT andalso T <> HOLogic.intT |
347 andalso T <> HOLogic.realT andalso Sign.of_sort thy (T, sort) |
374 andalso T <> HOLogic.realT andalso Sign.of_sort thy (T, sort) |
348 end; |
375 end; |
349 fun dec (Const ("Not", _) $ t) = (case dec t |
376 fun dec (Const (@{const_name Not}, _) $ t) = (case dec t |
350 of NONE => NONE |
377 of NONE => NONE |
351 | SOME (t1, rel, t2) => SOME (t1, "~" ^ rel, t2)) |
378 | SOME (t1, rel, t2) => SOME (t1, "~" ^ rel, t2)) |
352 | dec (Const ("op =", _) $ t1 $ t2) = |
379 | dec (Const (@{const_name "op ="}, _) $ t1 $ t2) = |
353 if of_sort t1 |
380 if of_sort t1 |
354 then SOME (t1, "=", t2) |
381 then SOME (t1, "=", t2) |
355 else NONE |
382 else NONE |
356 | dec (Const ("Orderings.less_eq", _) $ t1 $ t2) = |
383 | dec (Const (@{const_name less_eq}, _) $ t1 $ t2) = |
357 if of_sort t1 |
384 if of_sort t1 |
358 then SOME (t1, "<=", t2) |
385 then SOME (t1, "<=", t2) |
359 else NONE |
386 else NONE |
360 | dec (Const ("Orderings.less", _) $ t1 $ t2) = |
387 | dec (Const (@{const_name less}, _) $ t1 $ t2) = |
361 if of_sort t1 |
388 if of_sort t1 |
362 then SOME (t1, "<", t2) |
389 then SOME (t1, "<", t2) |
363 else NONE |
390 else NONE |
364 | dec _ = NONE; |
391 | dec _ = NONE; |
365 in dec t end; |
392 in dec t end; |
415 |
442 |
416 fun prp t thm = (#prop (rep_thm thm) = t); |
443 fun prp t thm = (#prop (rep_thm thm) = t); |
417 |
444 |
418 fun prove_antisym_le sg ss ((le as Const(_,T)) $ r $ s) = |
445 fun prove_antisym_le sg ss ((le as Const(_,T)) $ r $ s) = |
419 let val prems = prems_of_ss ss; |
446 let val prems = prems_of_ss ss; |
420 val less = Const("Orderings.less",T); |
447 val less = Const (@{const_name less}, T); |
421 val t = HOLogic.mk_Trueprop(le $ s $ r); |
448 val t = HOLogic.mk_Trueprop(le $ s $ r); |
422 in case find_first (prp t) prems of |
449 in case find_first (prp t) prems of |
423 NONE => |
450 NONE => |
424 let val t = HOLogic.mk_Trueprop(HOLogic.Not $ (less $ r $ s)) |
451 let val t = HOLogic.mk_Trueprop(HOLogic.Not $ (less $ r $ s)) |
425 in case find_first (prp t) prems of |
452 in case find_first (prp t) prems of |
430 end |
457 end |
431 handle THM _ => NONE; |
458 handle THM _ => NONE; |
432 |
459 |
433 fun prove_antisym_less sg ss (NotC $ ((less as Const(_,T)) $ r $ s)) = |
460 fun prove_antisym_less sg ss (NotC $ ((less as Const(_,T)) $ r $ s)) = |
434 let val prems = prems_of_ss ss; |
461 let val prems = prems_of_ss ss; |
435 val le = Const("Orderings.less_eq",T); |
462 val le = Const (@{const_name less_eq}, T); |
436 val t = HOLogic.mk_Trueprop(le $ r $ s); |
463 val t = HOLogic.mk_Trueprop(le $ r $ s); |
437 in case find_first (prp t) prems of |
464 in case find_first (prp t) prems of |
438 NONE => |
465 NONE => |
439 let val t = HOLogic.mk_Trueprop(NotC $ (less $ s $ r)) |
466 let val t = HOLogic.mk_Trueprop(NotC $ (less $ s $ r)) |
440 in case find_first (prp t) prems of |
467 in case find_first (prp t) prems of |
519 "ALL x>=y. P" => "ALL x. x >= y \<longrightarrow> P" |
546 "ALL x>=y. P" => "ALL x. x >= y \<longrightarrow> P" |
520 "EX x>=y. P" => "EX x. x >= y \<and> P" |
547 "EX x>=y. P" => "EX x. x >= y \<and> P" |
521 |
548 |
522 print_translation {* |
549 print_translation {* |
523 let |
550 let |
524 val All_binder = Syntax.binder_name @{const_syntax "All"}; |
551 val All_binder = Syntax.binder_name @{const_syntax All}; |
525 val Ex_binder = Syntax.binder_name @{const_syntax "Ex"}; |
552 val Ex_binder = Syntax.binder_name @{const_syntax Ex}; |
526 val impl = @{const_syntax "op -->"}; |
553 val impl = @{const_syntax "op -->"}; |
527 val conj = @{const_syntax "op &"}; |
554 val conj = @{const_syntax "op &"}; |
528 val less = @{const_syntax "less"}; |
555 val less = @{const_syntax less}; |
529 val less_eq = @{const_syntax "less_eq"}; |
556 val less_eq = @{const_syntax less_eq}; |
530 |
557 |
531 val trans = |
558 val trans = |
532 [((All_binder, impl, less), ("_All_less", "_All_greater")), |
559 [((All_binder, impl, less), ("_All_less", "_All_greater")), |
533 ((All_binder, impl, less_eq), ("_All_less_eq", "_All_greater_eq")), |
560 ((All_binder, impl, less_eq), ("_All_less_eq", "_All_greater_eq")), |
534 ((Ex_binder, conj, less), ("_Ex_less", "_Ex_greater")), |
561 ((Ex_binder, conj, less), ("_Ex_less", "_Ex_greater")), |
799 subsection {* Order on bool *} |
826 subsection {* Order on bool *} |
800 |
827 |
801 instance bool :: order |
828 instance bool :: order |
802 le_bool_def: "P \<le> Q \<equiv> P \<longrightarrow> Q" |
829 le_bool_def: "P \<le> Q \<equiv> P \<longrightarrow> Q" |
803 less_bool_def: "P < Q \<equiv> P \<le> Q \<and> P \<noteq> Q" |
830 less_bool_def: "P < Q \<equiv> P \<le> Q \<and> P \<noteq> Q" |
804 by default (auto simp add: le_bool_def less_bool_def) |
831 by intro_classes (auto simp add: le_bool_def less_bool_def) |
805 |
832 |
806 lemma le_boolI: "(P \<Longrightarrow> Q) \<Longrightarrow> P \<le> Q" |
833 lemma le_boolI: "(P \<Longrightarrow> Q) \<Longrightarrow> P \<le> Q" |
807 by (simp add: le_bool_def) |
834 by (simp add: le_bool_def) |
808 |
835 |
809 lemma le_boolI': "P \<longrightarrow> Q \<Longrightarrow> P \<le> Q" |
836 lemma le_boolI': "P \<longrightarrow> Q \<Longrightarrow> P \<le> Q" |
852 apply (simp add: Least_def) |
879 apply (simp add: Least_def) |
853 apply (rule the_equality) |
880 apply (rule the_equality) |
854 apply (auto intro!: order_antisym) |
881 apply (auto intro!: order_antisym) |
855 done |
882 done |
856 |
883 |
857 lemmas min_le_iff_disj = linorder_class.min_le_iff_disj [unfolded min_linorder] |
|
858 lemmas le_max_iff_disj = linorder_class.le_max_iff_disj [unfolded max_linorder] |
|
859 lemmas min_less_iff_disj = linorder_class.min_less_iff_disj [unfolded min_linorder] |
|
860 lemmas less_max_iff_disj = linorder_class.less_max_iff_disj [unfolded max_linorder] |
|
861 lemmas min_less_iff_conj [simp] = linorder_class.min_less_iff_conj [unfolded min_linorder] |
|
862 lemmas max_less_iff_conj [simp] = linorder_class.max_less_iff_conj [unfolded max_linorder] |
|
863 lemmas split_min = linorder_class.split_min [unfolded min_linorder] |
|
864 lemmas split_max = linorder_class.split_max [unfolded max_linorder] |
|
865 |
|
866 lemma min_leastL: "(!!x. least <= x) ==> min least x = least" |
884 lemma min_leastL: "(!!x. least <= x) ==> min least x = least" |
867 by (simp add: min_def) |
885 by (simp add: min_def) |
868 |
886 |
869 lemma max_leastL: "(!!x. least <= x) ==> max least x = x" |
887 lemma max_leastL: "(!!x. least <= x) ==> max least x = x" |
870 by (simp add: max_def) |
888 by (simp add: max_def) |