src/HOL/Orderings.thy
changeset 22916 8caf6da610e2
parent 22886 cdff6ef76009
child 22997 d4f3b015b50b
equal deleted inserted replaced
22915:bb8a928a6bfa 22916:8caf6da610e2
    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)