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 |