933 lemma arg_minI: |
933 lemma arg_minI: |
934 "\<lbrakk> P x; |
934 "\<lbrakk> P x; |
935 \<And>y. P y \<Longrightarrow> \<not> f y < f x; |
935 \<And>y. P y \<Longrightarrow> \<not> f y < f x; |
936 \<And>x. \<lbrakk> P x; \<forall>y. P y \<longrightarrow> \<not> f y < f x \<rbrakk> \<Longrightarrow> Q x \<rbrakk> |
936 \<And>x. \<lbrakk> P x; \<forall>y. P y \<longrightarrow> \<not> f y < f x \<rbrakk> \<Longrightarrow> Q x \<rbrakk> |
937 \<Longrightarrow> Q (arg_min f P)" |
937 \<Longrightarrow> Q (arg_min f P)" |
938 apply (simp add: arg_min_def is_arg_min_def) |
938 unfolding arg_min_def is_arg_min_def |
939 apply (rule someI2_ex) |
939 by (blast intro!: someI2_ex) |
940 apply blast |
|
941 apply blast |
|
942 done |
|
943 |
940 |
944 lemma arg_min_equality: |
941 lemma arg_min_equality: |
945 "\<lbrakk> P k; \<And>x. P x \<Longrightarrow> f k \<le> f x \<rbrakk> \<Longrightarrow> f (arg_min f P) = f k" |
942 "\<lbrakk> P k; \<And>x. P x \<Longrightarrow> f k \<le> f x \<rbrakk> \<Longrightarrow> f (arg_min f P) = f k" |
946 for f :: "_ \<Rightarrow> 'a::order" |
943 for f :: "_ \<Rightarrow> 'a::order" |
947 apply (rule arg_minI) |
944 by (rule arg_minI; force simp: not_less less_le_not_le) |
948 apply assumption |
|
949 apply (simp add: less_le_not_le) |
|
950 by (metis le_less) |
|
951 |
945 |
952 lemma wf_linord_ex_has_least: |
946 lemma wf_linord_ex_has_least: |
953 "\<lbrakk> wf r; \<forall>x y. (x, y) \<in> r\<^sup>+ \<longleftrightarrow> (y, x) \<notin> r\<^sup>*; P k \<rbrakk> |
947 "\<lbrakk> wf r; \<forall>x y. (x, y) \<in> r\<^sup>+ \<longleftrightarrow> (y, x) \<notin> r\<^sup>*; P k \<rbrakk> |
954 \<Longrightarrow> \<exists>x. P x \<and> (\<forall>y. P y \<longrightarrow> (m x, m y) \<in> r\<^sup>*)" |
948 \<Longrightarrow> \<exists>x. P x \<and> (\<forall>y. P y \<longrightarrow> (m x, m y) \<in> r\<^sup>*)" |
955 apply (drule wf_trancl [THEN wf_eq_minimal [THEN iffD1]]) |
949 by (force dest!: wf_trancl [THEN wf_eq_minimal [THEN iffD1, THEN spec], where x = "m ` Collect P"]) |
956 apply (drule_tac x = "m ` Collect P" in spec) |
|
957 by force |
|
958 |
950 |
959 lemma ex_has_least_nat: "P k \<Longrightarrow> \<exists>x. P x \<and> (\<forall>y. P y \<longrightarrow> m x \<le> m y)" |
951 lemma ex_has_least_nat: "P k \<Longrightarrow> \<exists>x. P x \<and> (\<forall>y. P y \<longrightarrow> m x \<le> m y)" |
960 for m :: "'a \<Rightarrow> nat" |
952 for m :: "'a \<Rightarrow> nat" |
961 apply (simp only: pred_nat_trancl_eq_le [symmetric]) |
953 unfolding pred_nat_trancl_eq_le [symmetric] |
962 apply (rule wf_pred_nat [THEN wf_linord_ex_has_least]) |
954 apply (rule wf_pred_nat [THEN wf_linord_ex_has_least]) |
963 apply (simp add: less_eq linorder_not_le pred_nat_trancl_eq_le) |
955 apply (simp add: less_eq linorder_not_le pred_nat_trancl_eq_le) |
964 by assumption |
956 by assumption |
965 |
957 |
966 lemma arg_min_nat_lemma: |
958 lemma arg_min_nat_lemma: |
967 "P k \<Longrightarrow> P(arg_min m P) \<and> (\<forall>y. P y \<longrightarrow> m (arg_min m P) \<le> m y)" |
959 "P k \<Longrightarrow> P(arg_min m P) \<and> (\<forall>y. P y \<longrightarrow> m (arg_min m P) \<le> m y)" |
968 for m :: "'a \<Rightarrow> nat" |
960 for m :: "'a \<Rightarrow> nat" |
969 apply (simp add: arg_min_def is_arg_min_linorder) |
961 unfolding arg_min_def is_arg_min_linorder |
970 apply (rule someI_ex) |
962 apply (rule someI_ex) |
971 apply (erule ex_has_least_nat) |
963 apply (erule ex_has_least_nat) |
972 done |
964 done |
973 |
965 |
974 lemmas arg_min_natI = arg_min_nat_lemma [THEN conjunct1] |
966 lemmas arg_min_natI = arg_min_nat_lemma [THEN conjunct1] |
975 |
967 |
976 lemma is_arg_min_arg_min_nat: fixes m :: "'a \<Rightarrow> nat" |
968 lemma is_arg_min_arg_min_nat: fixes m :: "'a \<Rightarrow> nat" |
977 shows "P x \<Longrightarrow> is_arg_min m P (arg_min m P)" |
969 shows "P x \<Longrightarrow> is_arg_min m P (arg_min m P)" |
978 by (metis arg_min_nat_lemma is_arg_min_linorder) |
970 by (metis arg_min_nat_lemma is_arg_min_linorder) |
979 |
971 |
980 lemma arg_min_nat_le: "P x \<Longrightarrow> m (arg_min m P) \<le> m x" |
972 lemma arg_min_nat_le: "P x \<Longrightarrow> m (arg_min m P) \<le> m x" |
981 for m :: "'a \<Rightarrow> nat" |
973 for m :: "'a \<Rightarrow> nat" |
982 by (rule arg_min_nat_lemma [THEN conjunct2, THEN spec, THEN mp]) |
974 by (rule arg_min_nat_lemma [THEN conjunct2, THEN spec, THEN mp]) |
983 |
975 |
984 lemma ex_min_if_finite: |
976 lemma ex_min_if_finite: |
985 "\<lbrakk> finite S; S \<noteq> {} \<rbrakk> \<Longrightarrow> \<exists>m\<in>S. \<not>(\<exists>x\<in>S. x < (m::'a::order))" |
977 "\<lbrakk> finite S; S \<noteq> {} \<rbrakk> \<Longrightarrow> \<exists>m\<in>S. \<not>(\<exists>x\<in>S. x < (m::'a::order))" |
986 by(induction rule: finite.induct) (auto intro: order.strict_trans) |
978 by(induction rule: finite.induct) (auto intro: order.strict_trans) |
987 |
979 |
988 lemma ex_is_arg_min_if_finite: fixes f :: "'a \<Rightarrow> 'b :: order" |
980 lemma ex_is_arg_min_if_finite: fixes f :: "'a \<Rightarrow> 'b :: order" |
989 shows "\<lbrakk> finite S; S \<noteq> {} \<rbrakk> \<Longrightarrow> \<exists>x. is_arg_min f (\<lambda>x. x \<in> S) x" |
981 shows "\<lbrakk> finite S; S \<noteq> {} \<rbrakk> \<Longrightarrow> \<exists>x. is_arg_min f (\<lambda>x. x \<in> S) x" |
990 unfolding is_arg_min_def |
982 unfolding is_arg_min_def |
991 using ex_min_if_finite[of "f ` S"] |
983 using ex_min_if_finite[of "f ` S"] |
992 by auto |
984 by auto |
993 |
985 |
994 lemma arg_min_SOME_Min: |
986 lemma arg_min_SOME_Min: |
995 "finite S \<Longrightarrow> arg_min_on f S = (SOME y. y \<in> S \<and> f y = Min(f ` S))" |
987 "finite S \<Longrightarrow> arg_min_on f S = (SOME y. y \<in> S \<and> f y = Min(f ` S))" |
996 unfolding arg_min_on_def arg_min_def is_arg_min_linorder |
988 unfolding arg_min_on_def arg_min_def is_arg_min_linorder |
997 apply(rule arg_cong[where f = Eps]) |
989 apply(rule arg_cong[where f = Eps]) |
998 apply (auto simp: fun_eq_iff intro: Min_eqI[symmetric]) |
990 apply (auto simp: fun_eq_iff intro: Min_eqI[symmetric]) |
999 done |
991 done |
1000 |
992 |
1001 lemma arg_min_if_finite: fixes f :: "'a \<Rightarrow> 'b :: order" |
993 lemma arg_min_if_finite: fixes f :: "'a \<Rightarrow> 'b :: order" |
1002 assumes "finite S" "S \<noteq> {}" |
994 assumes "finite S" "S \<noteq> {}" |
1003 shows "arg_min_on f S \<in> S" and "\<not>(\<exists>x\<in>S. f x < f (arg_min_on f S))" |
995 shows "arg_min_on f S \<in> S" and "\<not>(\<exists>x\<in>S. f x < f (arg_min_on f S))" |
1004 using ex_is_arg_min_if_finite[OF assms, of f] |
996 using ex_is_arg_min_if_finite[OF assms, of f] |
1005 unfolding arg_min_on_def arg_min_def is_arg_min_def |
997 unfolding arg_min_on_def arg_min_def is_arg_min_def |
1006 by(auto dest!: someI_ex) |
998 by(auto dest!: someI_ex) |
1007 |
999 |
1008 lemma arg_min_least: fixes f :: "'a \<Rightarrow> 'b :: linorder" |
1000 lemma arg_min_least: fixes f :: "'a \<Rightarrow> 'b :: linorder" |
1009 shows "\<lbrakk> finite S; S \<noteq> {}; y \<in> S \<rbrakk> \<Longrightarrow> f(arg_min_on f S) \<le> f y" |
1001 shows "\<lbrakk> finite S; S \<noteq> {}; y \<in> S \<rbrakk> \<Longrightarrow> f(arg_min_on f S) \<le> f y" |
1010 by(simp add: arg_min_SOME_Min inv_into_def2[symmetric] f_inv_into_f) |
1002 by(simp add: arg_min_SOME_Min inv_into_def2[symmetric] f_inv_into_f) |
1011 |
1003 |
1012 lemma arg_min_inj_eq: fixes f :: "'a \<Rightarrow> 'b :: order" |
1004 lemma arg_min_inj_eq: fixes f :: "'a \<Rightarrow> 'b :: order" |
1013 shows "\<lbrakk> inj_on f {x. P x}; P a; \<forall>y. P y \<longrightarrow> f a \<le> f y \<rbrakk> \<Longrightarrow> arg_min f P = a" |
1005 shows "\<lbrakk> inj_on f {x. P x}; P a; \<forall>y. P y \<longrightarrow> f a \<le> f y \<rbrakk> \<Longrightarrow> arg_min f P = a" |
1014 apply(simp add: arg_min_def is_arg_min_def) |
1006 apply(simp add: arg_min_def is_arg_min_def) |
1015 apply(rule someI2[of _ a]) |
1007 apply(rule someI2[of _ a]) |