src/HOL/Lattices_Big.thy
changeset 65954 431024edc9cf
parent 65952 dec96cb3fbe0
child 65963 ca1e636fa716
equal deleted inserted replaced
65953:440fe0937b92 65954:431024edc9cf
   913 apply(simp add: arg_min_def is_arg_min_def)
   913 apply(simp add: arg_min_def is_arg_min_def)
   914 apply(rule someI2[of _ a])
   914 apply(rule someI2[of _ a])
   915  apply (simp add: less_le_not_le)
   915  apply (simp add: less_le_not_le)
   916 by (metis inj_on_eq_iff less_le mem_Collect_eq)
   916 by (metis inj_on_eq_iff less_le mem_Collect_eq)
   917 
   917 
   918 end
   918 
       
   919 subsection \<open>Arg Max\<close>
       
   920 
       
   921 definition is_arg_max :: "('a \<Rightarrow> 'b::ord) \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> bool" where
       
   922 "is_arg_max f P x = (P x \<and> \<not>(\<exists>y. P y \<and> f y > f x))"
       
   923 
       
   924 definition arg_max :: "('a \<Rightarrow> 'b::ord) \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> 'a" where
       
   925 "arg_max f P = (SOME x. is_arg_max f P x)"
       
   926 
       
   927 abbreviation arg_max_on :: "('a \<Rightarrow> 'b::ord) \<Rightarrow> 'a set \<Rightarrow> 'a" where
       
   928 "arg_max_on f S \<equiv> arg_max f (\<lambda>x. x \<in> S)"
       
   929 
       
   930 syntax
       
   931   "_arg_max" :: "('a \<Rightarrow> 'b) \<Rightarrow> pttrn \<Rightarrow> bool \<Rightarrow> 'a"
       
   932     ("(3ARG'_MAX _ _./ _)" [0, 0, 10] 10)
       
   933 translations
       
   934   "ARG_MAX f x. P" \<rightleftharpoons> "CONST arg_max f (\<lambda>x. P)"
       
   935 
       
   936 lemma is_arg_max_linorder: fixes f :: "'a \<Rightarrow> 'b :: linorder"
       
   937 shows "is_arg_max f P x = (P x \<and> (\<forall>y. P y \<longrightarrow> f x \<ge> f y))"
       
   938 by(auto simp add: is_arg_max_def)
       
   939 
       
   940 lemma arg_maxI:
       
   941   "P x \<Longrightarrow>
       
   942     (\<And>y. P y \<Longrightarrow> \<not> f y > f x) \<Longrightarrow>
       
   943     (\<And>x. P x \<Longrightarrow> \<forall>y. P y \<longrightarrow> \<not> f y > f x \<Longrightarrow> Q x) \<Longrightarrow>
       
   944     Q (arg_max f P)"
       
   945 apply (simp add: arg_max_def is_arg_max_def)
       
   946 apply (rule someI2_ex)
       
   947  apply blast
       
   948 apply blast
       
   949 done
       
   950 
       
   951 lemma arg_max_equality:
       
   952   "\<lbrakk> P k; \<And>x. P x \<Longrightarrow> f x \<le> f k \<rbrakk> \<Longrightarrow> f (arg_max f P) = f k"
       
   953   for f :: "_ \<Rightarrow> 'a::order"
       
   954 apply (rule arg_maxI [where f = f])
       
   955   apply assumption
       
   956  apply (simp add: less_le_not_le)
       
   957 by (metis le_less)
       
   958 
       
   959 lemma ex_has_greatest_nat_lemma:
       
   960   "P k \<Longrightarrow> \<forall>x. P x \<longrightarrow> (\<exists>y. P y \<and> \<not> f y \<le> f x) \<Longrightarrow> \<exists>y. P y \<and> \<not> f y < f k + n"
       
   961   for f :: "'a \<Rightarrow> nat"
       
   962 by (induct n) (force simp: le_Suc_eq)+
       
   963 
       
   964 lemma ex_has_greatest_nat:
       
   965   "P k \<Longrightarrow> \<forall>y. P y \<longrightarrow> f y < b \<Longrightarrow> \<exists>x. P x \<and> (\<forall>y. P y \<longrightarrow> f y \<le> f x)"
       
   966   for f :: "'a \<Rightarrow> nat"
       
   967 apply (rule ccontr)
       
   968 apply (cut_tac P = P and n = "b - f k" in ex_has_greatest_nat_lemma)
       
   969   apply (subgoal_tac [3] "f k \<le> b")
       
   970    apply auto
       
   971 done
       
   972 
       
   973 lemma arg_max_nat_lemma:
       
   974   "\<lbrakk> P k;  \<forall>y. P y \<longrightarrow> f y < b \<rbrakk>
       
   975   \<Longrightarrow> P (arg_max f P) \<and> (\<forall>y. P y \<longrightarrow> f y \<le> f (arg_max f P))"
       
   976   for f :: "'a \<Rightarrow> nat"
       
   977 apply (simp add: arg_max_def is_arg_max_linorder)
       
   978 apply (rule someI_ex)
       
   979 apply (erule (1) ex_has_greatest_nat)
       
   980 done
       
   981 
       
   982 lemmas arg_max_natI = arg_max_nat_lemma [THEN conjunct1]
       
   983 
       
   984 lemma arg_max_nat_le: "P x \<Longrightarrow> \<forall>y. P y \<longrightarrow> f y < b \<Longrightarrow> f x \<le> f (arg_max f P)"
       
   985   for f :: "'a \<Rightarrow> nat"
       
   986 by (blast dest: arg_max_nat_lemma [THEN conjunct2, THEN spec, of P])
       
   987 
       
   988 
       
   989 text \<open>\<^medskip> Specialization to \<open>GREATEST\<close>.\<close>
       
   990 
       
   991 (* LEAST ? *)
       
   992 definition Greatest :: "('a::ord \<Rightarrow> bool) \<Rightarrow> 'a"  (binder "GREATEST " 10)
       
   993 where "Greatest \<equiv> arg_max (\<lambda>x. x)"
       
   994 
       
   995 lemma Greatest_equality:
       
   996   "\<lbrakk> P k;  \<And>x. P x \<Longrightarrow> x \<le> k \<rbrakk> \<Longrightarrow> (Greatest P) = k"
       
   997   for k :: "'a::order"
       
   998 apply (simp add: Greatest_def)
       
   999 apply (erule arg_max_equality)
       
  1000 apply blast
       
  1001 done
       
  1002 
       
  1003 lemma GreatestI: "P k \<Longrightarrow> \<forall>y. P y \<longrightarrow> y < b \<Longrightarrow> P (Greatest P)"
       
  1004   for k :: nat
       
  1005 unfolding Greatest_def by (rule arg_max_natI) auto
       
  1006 
       
  1007 lemma Greatest_le: "P x \<Longrightarrow> \<forall>y. P y \<longrightarrow> y < b \<Longrightarrow> x \<le> (Greatest P)"
       
  1008   for x :: nat
       
  1009 unfolding Greatest_def by (rule arg_max_nat_le) auto
       
  1010 
       
  1011 lemma GreatestI_ex: "\<exists>k::nat. P k \<Longrightarrow> \<forall>y. P y \<longrightarrow> y < b \<Longrightarrow> P (Greatest P)"
       
  1012 apply (erule exE)
       
  1013 apply (erule (1) GreatestI)
       
  1014 done
       
  1015 
       
  1016 end