src/HOL/Lattices_Big.thy
changeset 80769 77f7aa898ced
parent 80175 200107cdd3ac
child 80770 fe7ffe7eb265
equal deleted inserted replaced
80758:8f96e1329845 80769:77f7aa898ced
   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])
  1046 lemma arg_maxI:
  1038 lemma arg_maxI:
  1047   "P x \<Longrightarrow>
  1039   "P x \<Longrightarrow>
  1048     (\<And>y. P y \<Longrightarrow> \<not> f y > f x) \<Longrightarrow>
  1040     (\<And>y. P y \<Longrightarrow> \<not> f y > f x) \<Longrightarrow>
  1049     (\<And>x. P x \<Longrightarrow> \<forall>y. P y \<longrightarrow> \<not> f y > f x \<Longrightarrow> Q x) \<Longrightarrow>
  1041     (\<And>x. P x \<Longrightarrow> \<forall>y. P y \<longrightarrow> \<not> f y > f x \<Longrightarrow> Q x) \<Longrightarrow>
  1050     Q (arg_max f P)"
  1042     Q (arg_max f P)"
  1051 apply (simp add: arg_max_def is_arg_max_def)
  1043   unfolding arg_max_def is_arg_max_def
  1052 apply (rule someI2_ex)
  1044   by (blast intro!: someI2_ex elim: )
  1053  apply blast
       
  1054 apply blast
       
  1055 done
       
  1056 
  1045 
  1057 lemma arg_max_equality:
  1046 lemma arg_max_equality:
  1058   "\<lbrakk> P k; \<And>x. P x \<Longrightarrow> f x \<le> f k \<rbrakk> \<Longrightarrow> f (arg_max f P) = f k"
  1047   "\<lbrakk> P k; \<And>x. P x \<Longrightarrow> f x \<le> f k \<rbrakk> \<Longrightarrow> f (arg_max f P) = f k"
  1059   for f :: "_ \<Rightarrow> 'a::order"
  1048   for f :: "_ \<Rightarrow> 'a::order"
  1060 apply (rule arg_maxI [where f = f])
  1049 apply (rule arg_maxI [where f = f])
  1084 
  1073 
  1085 lemma arg_max_nat_lemma:
  1074 lemma arg_max_nat_lemma:
  1086   "\<lbrakk> P k;  \<forall>y. P y \<longrightarrow> f y < b \<rbrakk>
  1075   "\<lbrakk> P k;  \<forall>y. P y \<longrightarrow> f y < b \<rbrakk>
  1087   \<Longrightarrow> P (arg_max f P) \<and> (\<forall>y. P y \<longrightarrow> f y \<le> f (arg_max f P))"
  1076   \<Longrightarrow> P (arg_max f P) \<and> (\<forall>y. P y \<longrightarrow> f y \<le> f (arg_max f P))"
  1088   for f :: "'a \<Rightarrow> nat"
  1077   for f :: "'a \<Rightarrow> nat"
  1089 apply (simp add: arg_max_def is_arg_max_linorder)
  1078   unfolding arg_max_def is_arg_max_linorder
  1090 apply (rule someI_ex)
  1079   by (rule someI_ex) (metis ex_has_greatest_nat)
  1091 apply (erule (1) ex_has_greatest_nat)
       
  1092 done
       
  1093 
  1080 
  1094 lemmas arg_max_natI = arg_max_nat_lemma [THEN conjunct1]
  1081 lemmas arg_max_natI = arg_max_nat_lemma [THEN conjunct1]
  1095 
  1082 
  1096 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)"
  1083 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)"
  1097   for f :: "'a \<Rightarrow> nat"
  1084   for f :: "'a \<Rightarrow> nat"
  1098 by (blast dest: arg_max_nat_lemma [THEN conjunct2, THEN spec, of P])
  1085   using arg_max_nat_lemma by metis
  1099 
  1086 
  1100 end
  1087 end