| 
44133
 | 
     1  | 
(*  Title:      HOL/Multivariate_Analysis/Linear_Algebra.thy
  | 
| 
 | 
     2  | 
    Author:     Amine Chaieb, University of Cambridge
  | 
| 
 | 
     3  | 
*)
  | 
| 
 | 
     4  | 
  | 
| 
 | 
     5  | 
header {* Elementary linear algebra on Euclidean spaces *}
 | 
| 
 | 
     6  | 
  | 
| 
 | 
     7  | 
theory Linear_Algebra
  | 
| 
 | 
     8  | 
imports
  | 
| 
 | 
     9  | 
  Euclidean_Space
  | 
| 
 | 
    10  | 
  "~~/src/HOL/Library/Infinite_Set"
  | 
| 
 | 
    11  | 
  L2_Norm
  | 
| 
 | 
    12  | 
  "~~/src/HOL/Library/Convex"
  | 
| 
 | 
    13  | 
uses
  | 
| 
 | 
    14  | 
  "~~/src/HOL/Library/positivstellensatz.ML"  (* FIXME duplicate use!? *)
  | 
| 
 | 
    15  | 
  ("normarith.ML")
 | 
| 
 | 
    16  | 
begin
  | 
| 
 | 
    17  | 
  | 
| 
 | 
    18  | 
lemma cond_application_beta: "(if b then f else g) x = (if b then f x else g x)"
  | 
| 
 | 
    19  | 
  by auto
  | 
| 
 | 
    20  | 
  | 
| 
 | 
    21  | 
notation inner (infix "\<bullet>" 70)
  | 
| 
 | 
    22  | 
  | 
| 
 | 
    23  | 
subsection {* A connectedness or intermediate value lemma with several applications. *}
 | 
| 
 | 
    24  | 
  | 
| 
 | 
    25  | 
lemma connected_real_lemma:
  | 
| 
 | 
    26  | 
  fixes f :: "real \<Rightarrow> 'a::metric_space"
  | 
| 
 | 
    27  | 
  assumes ab: "a \<le> b" and fa: "f a \<in> e1" and fb: "f b \<in> e2"
  | 
| 
 | 
    28  | 
  and dst: "\<And>e x. a <= x \<Longrightarrow> x <= b \<Longrightarrow> 0 < e ==> \<exists>d > 0. \<forall>y. abs(y - x) < d \<longrightarrow> dist(f y) (f x) < e"
  | 
| 
 | 
    29  | 
  and e1: "\<forall>y \<in> e1. \<exists>e > 0. \<forall>y'. dist y' y < e \<longrightarrow> y' \<in> e1"
  | 
| 
 | 
    30  | 
  and e2: "\<forall>y \<in> e2. \<exists>e > 0. \<forall>y'. dist y' y < e \<longrightarrow> y' \<in> e2"
  | 
| 
 | 
    31  | 
  and e12: "~(\<exists>x \<ge> a. x <= b \<and> f x \<in> e1 \<and> f x \<in> e2)"
  | 
| 
 | 
    32  | 
  shows "\<exists>x \<ge> a. x <= b \<and> f x \<notin> e1 \<and> f x \<notin> e2" (is "\<exists> x. ?P x")
  | 
| 
 | 
    33  | 
proof-
  | 
| 
 | 
    34  | 
  let ?S = "{c. \<forall>x \<ge> a. x <= c \<longrightarrow> f x \<in> e1}"
 | 
| 
 | 
    35  | 
  have Se: " \<exists>x. x \<in> ?S" apply (rule exI[where x=a]) by (auto simp add: fa)
  | 
| 
 | 
    36  | 
  have Sub: "\<exists>y. isUb UNIV ?S y"
  | 
| 
 | 
    37  | 
    apply (rule exI[where x= b])
  | 
| 
 | 
    38  | 
    using ab fb e12 by (auto simp add: isUb_def setle_def)
  | 
| 
 | 
    39  | 
  from reals_complete[OF Se Sub] obtain l where
  | 
| 
 | 
    40  | 
    l: "isLub UNIV ?S l"by blast
  | 
| 
 | 
    41  | 
  have alb: "a \<le> l" "l \<le> b" using l ab fa fb e12
  | 
| 
 | 
    42  | 
    apply (auto simp add: isLub_def leastP_def isUb_def setle_def setge_def)
  | 
| 
 | 
    43  | 
    by (metis linorder_linear)
  | 
| 
 | 
    44  | 
  have ale1: "\<forall>z \<ge> a. z < l \<longrightarrow> f z \<in> e1" using l
  | 
| 
 | 
    45  | 
    apply (auto simp add: isLub_def leastP_def isUb_def setle_def setge_def)
  | 
| 
 | 
    46  | 
    by (metis linorder_linear not_le)
  | 
| 
 | 
    47  | 
    have th1: "\<And>z x e d :: real. z <= x + e \<Longrightarrow> e < d ==> z < x \<or> abs(z - x) < d" by arith
  | 
| 
 | 
    48  | 
    have th2: "\<And>e x:: real. 0 < e ==> ~(x + e <= x)" by arith
  | 
| 
 | 
    49  | 
    have "\<And>d::real. 0 < d \<Longrightarrow> 0 < d/2 \<and> d/2 < d" by simp
  | 
| 
 | 
    50  | 
    then have th3: "\<And>d::real. d > 0 \<Longrightarrow> \<exists>e > 0. e < d" by blast
  | 
| 
 | 
    51  | 
    {assume le2: "f l \<in> e2"
 | 
| 
 | 
    52  | 
      from le2 fa fb e12 alb have la: "l \<noteq> a" by metis
  | 
| 
 | 
    53  | 
      hence lap: "l - a > 0" using alb by arith
  | 
| 
 | 
    54  | 
      from e2[rule_format, OF le2] obtain e where
  | 
| 
 | 
    55  | 
        e: "e > 0" "\<forall>y. dist y (f l) < e \<longrightarrow> y \<in> e2" by metis
  | 
| 
 | 
    56  | 
      from dst[OF alb e(1)] obtain d where
  | 
| 
 | 
    57  | 
        d: "d > 0" "\<forall>y. \<bar>y - l\<bar> < d \<longrightarrow> dist (f y) (f l) < e" by metis
  | 
| 
 | 
    58  | 
      let ?d' = "min (d/2) ((l - a)/2)"
  | 
| 
 | 
    59  | 
      have "?d' < d \<and> 0 < ?d' \<and> ?d' < l - a" using lap d(1)
  | 
| 
 | 
    60  | 
        by (simp add: min_max.less_infI2)
  | 
| 
 | 
    61  | 
      then have "\<exists>d'. d' < d \<and> d' >0 \<and> l - d' > a" by auto
  | 
| 
 | 
    62  | 
      then obtain d' where d': "d' > 0" "d' < d" "l - d' > a" by metis
  | 
| 
 | 
    63  | 
      from d e have th0: "\<forall>y. \<bar>y - l\<bar> < d \<longrightarrow> f y \<in> e2" by metis
  | 
| 
 | 
    64  | 
      from th0[rule_format, of "l - d'"] d' have "f (l - d') \<in> e2" by auto
  | 
| 
 | 
    65  | 
      moreover
  | 
| 
 | 
    66  | 
      have "f (l - d') \<in> e1" using ale1[rule_format, of "l -d'"] d' by auto
  | 
| 
 | 
    67  | 
      ultimately have False using e12 alb d' by auto}
  | 
| 
 | 
    68  | 
    moreover
  | 
| 
 | 
    69  | 
    {assume le1: "f l \<in> e1"
 | 
| 
 | 
    70  | 
    from le1 fa fb e12 alb have lb: "l \<noteq> b" by metis
  | 
| 
 | 
    71  | 
      hence blp: "b - l > 0" using alb by arith
  | 
| 
 | 
    72  | 
      from e1[rule_format, OF le1] obtain e where
  | 
| 
 | 
    73  | 
        e: "e > 0" "\<forall>y. dist y (f l) < e \<longrightarrow> y \<in> e1" by metis
  | 
| 
 | 
    74  | 
      from dst[OF alb e(1)] obtain d where
  | 
| 
 | 
    75  | 
        d: "d > 0" "\<forall>y. \<bar>y - l\<bar> < d \<longrightarrow> dist (f y) (f l) < e" by metis
  | 
| 
 | 
    76  | 
      have "\<And>d::real. 0 < d \<Longrightarrow> d/2 < d \<and> 0 < d/2" by simp
  | 
| 
 | 
    77  | 
      then have "\<exists>d'. d' < d \<and> d' >0" using d(1) by blast
  | 
| 
 | 
    78  | 
      then obtain d' where d': "d' > 0" "d' < d" by metis
  | 
| 
 | 
    79  | 
      from d e have th0: "\<forall>y. \<bar>y - l\<bar> < d \<longrightarrow> f y \<in> e1" by auto
  | 
| 
 | 
    80  | 
      hence "\<forall>y. l \<le> y \<and> y \<le> l + d' \<longrightarrow> f y \<in> e1" using d' by auto
  | 
| 
 | 
    81  | 
      with ale1 have "\<forall>y. a \<le> y \<and> y \<le> l + d' \<longrightarrow> f y \<in> e1" by auto
  | 
| 
 | 
    82  | 
      with l d' have False
  | 
| 
 | 
    83  | 
        by (auto simp add: isLub_def isUb_def setle_def setge_def leastP_def) }
  | 
| 
 | 
    84  | 
    ultimately show ?thesis using alb by metis
  | 
| 
 | 
    85  | 
qed
  | 
| 
 | 
    86  | 
  | 
| 
 | 
    87  | 
text{* One immediately useful corollary is the existence of square roots! --- Should help to get rid of all the development of square-root for reals as a special case *}
 | 
| 
 | 
    88  | 
  | 
| 
 | 
    89  | 
lemma square_bound_lemma: "(x::real) < (1 + x) * (1 + x)"
  | 
| 
 | 
    90  | 
proof-
  | 
| 
 | 
    91  | 
  have "(x + 1/2)^2 + 3/4 > 0" using zero_le_power2[of "x+1/2"] by arith
  | 
| 
 | 
    92  | 
  thus ?thesis by (simp add: field_simps power2_eq_square)
  | 
| 
 | 
    93  | 
qed
  | 
| 
 | 
    94  | 
  | 
| 
 | 
    95  | 
lemma square_continuous: "0 < (e::real) ==> \<exists>d. 0 < d \<and> (\<forall>y. abs(y - x) < d \<longrightarrow> abs(y * y - x * x) < e)"
  | 
| 
 | 
    96  | 
  using isCont_power[OF isCont_ident, of 2, unfolded isCont_def LIM_eq, rule_format, of e x] apply (auto simp add: power2_eq_square)
  | 
| 
 | 
    97  | 
  apply (rule_tac x="s" in exI)
  | 
| 
 | 
    98  | 
  apply auto
  | 
| 
 | 
    99  | 
  apply (erule_tac x=y in allE)
  | 
| 
 | 
   100  | 
  apply auto
  | 
| 
 | 
   101  | 
  done
  | 
| 
 | 
   102  | 
  | 
| 
 | 
   103  | 
lemma real_le_lsqrt: "0 <= x \<Longrightarrow> 0 <= y \<Longrightarrow> x <= y^2 ==> sqrt x <= y"
  | 
| 
 | 
   104  | 
  using real_sqrt_le_iff[of x "y^2"] by simp
  | 
| 
 | 
   105  | 
  | 
| 
 | 
   106  | 
lemma real_le_rsqrt: "x^2 \<le> y \<Longrightarrow> x \<le> sqrt y"
  | 
| 
 | 
   107  | 
  using real_sqrt_le_mono[of "x^2" y] by simp
  | 
| 
 | 
   108  | 
  | 
| 
 | 
   109  | 
lemma real_less_rsqrt: "x^2 < y \<Longrightarrow> x < sqrt y"
  | 
| 
 | 
   110  | 
  using real_sqrt_less_mono[of "x^2" y] by simp
  | 
| 
 | 
   111  | 
  | 
| 
 | 
   112  | 
lemma sqrt_even_pow2: assumes n: "even n"
  | 
| 
 | 
   113  | 
  shows "sqrt(2 ^ n) = 2 ^ (n div 2)"
  | 
| 
 | 
   114  | 
proof-
  | 
| 
 | 
   115  | 
  from n obtain m where m: "n = 2*m" unfolding even_mult_two_ex ..
  | 
| 
 | 
   116  | 
  from m  have "sqrt(2 ^ n) = sqrt ((2 ^ m) ^ 2)"
  | 
| 
 | 
   117  | 
    by (simp only: power_mult[symmetric] mult_commute)
  | 
| 
 | 
   118  | 
  then show ?thesis  using m by simp
  | 
| 
 | 
   119  | 
qed
  | 
| 
 | 
   120  | 
  | 
| 
 | 
   121  | 
lemma real_div_sqrt: "0 <= x ==> x / sqrt(x) = sqrt(x)"
  | 
| 
 | 
   122  | 
  apply (cases "x = 0", simp_all)
  | 
| 
 | 
   123  | 
  using sqrt_divide_self_eq[of x]
  | 
| 
 | 
   124  | 
  apply (simp add: inverse_eq_divide field_simps)
  | 
| 
 | 
   125  | 
  done
  | 
| 
 | 
   126  | 
  | 
| 
 | 
   127  | 
text{* Hence derive more interesting properties of the norm. *}
 | 
| 
 | 
   128  | 
  | 
| 
 | 
   129  | 
(* FIXME: same as norm_scaleR
  | 
| 
 | 
   130  | 
lemma norm_mul[simp]: "norm(a *\<^sub>R x) = abs(a) * norm x"
  | 
| 
 | 
   131  | 
  by (simp add: norm_vector_def setL2_right_distrib abs_mult)
  | 
| 
 | 
   132  | 
*)
  | 
| 
 | 
   133  | 
  | 
| 
 | 
   134  | 
lemma norm_eq_0_dot: "(norm x = 0) \<longleftrightarrow> (inner x x = (0::real))"
  | 
| 
 | 
   135  | 
  by (simp add: setL2_def power2_eq_square)
  | 
| 
 | 
   136  | 
  | 
| 
 | 
   137  | 
lemma norm_cauchy_schwarz:
  | 
| 
 | 
   138  | 
  shows "inner x y <= norm x * norm y"
  | 
| 
 | 
   139  | 
  using Cauchy_Schwarz_ineq2[of x y] by auto
  | 
| 
 | 
   140  | 
  | 
| 
 | 
   141  | 
lemma norm_cauchy_schwarz_abs:
  | 
| 
 | 
   142  | 
  shows "\<bar>inner x y\<bar> \<le> norm x * norm y"
  | 
| 
 | 
   143  | 
  by (rule Cauchy_Schwarz_ineq2)
  | 
| 
 | 
   144  | 
  | 
| 
 | 
   145  | 
lemma norm_triangle_sub:
  | 
| 
 | 
   146  | 
  fixes x y :: "'a::real_normed_vector"
  | 
| 
 | 
   147  | 
  shows "norm x \<le> norm y  + norm (x - y)"
  | 
| 
 | 
   148  | 
  using norm_triangle_ineq[of "y" "x - y"] by (simp add: field_simps)
  | 
| 
 | 
   149  | 
  | 
| 
 | 
   150  | 
lemma real_abs_norm: "\<bar>norm x\<bar> = norm x"
  | 
| 
 | 
   151  | 
  by (rule abs_norm_cancel)
  | 
| 
 | 
   152  | 
lemma real_abs_sub_norm: "\<bar>norm x - norm y\<bar> <= norm(x - y)"
  | 
| 
 | 
   153  | 
  by (rule norm_triangle_ineq3)
  | 
| 
 | 
   154  | 
lemma norm_le: "norm(x) <= norm(y) \<longleftrightarrow> x \<bullet> x <= y \<bullet> y"
  | 
| 
 | 
   155  | 
  by (simp add: norm_eq_sqrt_inner) 
  | 
| 
 | 
   156  | 
lemma norm_lt: "norm(x) < norm(y) \<longleftrightarrow> x \<bullet> x < y \<bullet> y"
  | 
| 
 | 
   157  | 
  by (simp add: norm_eq_sqrt_inner)
  | 
| 
 | 
   158  | 
lemma norm_eq: "norm(x) = norm (y) \<longleftrightarrow> x \<bullet> x = y \<bullet> y"
  | 
| 
 | 
   159  | 
  apply(subst order_eq_iff) unfolding norm_le by auto
  | 
| 
 | 
   160  | 
lemma norm_eq_1: "norm(x) = 1 \<longleftrightarrow> x \<bullet> x = 1"
  | 
| 
 | 
   161  | 
  unfolding norm_eq_sqrt_inner by auto
  | 
| 
 | 
   162  | 
  | 
| 
 | 
   163  | 
text{* Squaring equations and inequalities involving norms.  *}
 | 
| 
 | 
   164  | 
  | 
| 
 | 
   165  | 
lemma dot_square_norm: "x \<bullet> x = norm(x)^2"
  | 
| 
 | 
   166  | 
  by (simp add: norm_eq_sqrt_inner)
  | 
| 
 | 
   167  | 
  | 
| 
 | 
   168  | 
lemma norm_eq_square: "norm(x) = a \<longleftrightarrow> 0 <= a \<and> x \<bullet> x = a^2"
  | 
| 
 | 
   169  | 
  by (auto simp add: norm_eq_sqrt_inner)
  | 
| 
 | 
   170  | 
  | 
| 
 | 
   171  | 
lemma real_abs_le_square_iff: "\<bar>x\<bar> \<le> \<bar>y\<bar> \<longleftrightarrow> (x::real)^2 \<le> y^2"
  | 
| 
 | 
   172  | 
proof
  | 
| 
 | 
   173  | 
  assume "\<bar>x\<bar> \<le> \<bar>y\<bar>"
  | 
| 
 | 
   174  | 
  then have "\<bar>x\<bar>\<twosuperior> \<le> \<bar>y\<bar>\<twosuperior>" by (rule power_mono, simp)
  | 
| 
 | 
   175  | 
  then show "x\<twosuperior> \<le> y\<twosuperior>" by simp
  | 
| 
 | 
   176  | 
next
  | 
| 
 | 
   177  | 
  assume "x\<twosuperior> \<le> y\<twosuperior>"
  | 
| 
 | 
   178  | 
  then have "sqrt (x\<twosuperior>) \<le> sqrt (y\<twosuperior>)" by (rule real_sqrt_le_mono)
  | 
| 
 | 
   179  | 
  then show "\<bar>x\<bar> \<le> \<bar>y\<bar>" by simp
  | 
| 
 | 
   180  | 
qed
  | 
| 
 | 
   181  | 
  | 
| 
 | 
   182  | 
lemma norm_le_square: "norm(x) <= a \<longleftrightarrow> 0 <= a \<and> x \<bullet> x <= a^2"
  | 
| 
 | 
   183  | 
  apply (simp add: dot_square_norm real_abs_le_square_iff[symmetric])
  | 
| 
 | 
   184  | 
  using norm_ge_zero[of x]
  | 
| 
 | 
   185  | 
  apply arith
  | 
| 
 | 
   186  | 
  done
  | 
| 
 | 
   187  | 
  | 
| 
 | 
   188  | 
lemma norm_ge_square: "norm(x) >= a \<longleftrightarrow> a <= 0 \<or> x \<bullet> x >= a ^ 2"
  | 
| 
 | 
   189  | 
  apply (simp add: dot_square_norm real_abs_le_square_iff[symmetric])
  | 
| 
 | 
   190  | 
  using norm_ge_zero[of x]
  | 
| 
 | 
   191  | 
  apply arith
  | 
| 
 | 
   192  | 
  done
  | 
| 
 | 
   193  | 
  | 
| 
 | 
   194  | 
lemma norm_lt_square: "norm(x) < a \<longleftrightarrow> 0 < a \<and> x \<bullet> x < a^2"
  | 
| 
 | 
   195  | 
  by (metis not_le norm_ge_square)
  | 
| 
 | 
   196  | 
lemma norm_gt_square: "norm(x) > a \<longleftrightarrow> a < 0 \<or> x \<bullet> x > a^2"
  | 
| 
 | 
   197  | 
  by (metis norm_le_square not_less)
  | 
| 
 | 
   198  | 
  | 
| 
 | 
   199  | 
text{* Dot product in terms of the norm rather than conversely. *}
 | 
| 
 | 
   200  | 
  | 
| 
 | 
   201  | 
lemmas inner_simps = inner.add_left inner.add_right inner.diff_right inner.diff_left 
  | 
| 
 | 
   202  | 
inner.scaleR_left inner.scaleR_right
  | 
| 
 | 
   203  | 
  | 
| 
 | 
   204  | 
lemma dot_norm: "x \<bullet> y = (norm(x + y) ^2 - norm x ^ 2 - norm y ^ 2) / 2"
  | 
| 
 | 
   205  | 
  unfolding power2_norm_eq_inner inner_simps inner_commute by auto 
  | 
| 
 | 
   206  | 
  | 
| 
 | 
   207  | 
lemma dot_norm_neg: "x \<bullet> y = ((norm x ^ 2 + norm y ^ 2) - norm(x - y) ^ 2) / 2"
  | 
| 
 | 
   208  | 
  unfolding power2_norm_eq_inner inner_simps inner_commute by(auto simp add:algebra_simps)
  | 
| 
 | 
   209  | 
  | 
| 
 | 
   210  | 
text{* Equality of vectors in terms of @{term "op \<bullet>"} products.    *}
 | 
| 
 | 
   211  | 
  | 
| 
 | 
   212  | 
lemma vector_eq: "x = y \<longleftrightarrow> x \<bullet> x = x \<bullet> y \<and> y \<bullet> y = x \<bullet> x" (is "?lhs \<longleftrightarrow> ?rhs")
  | 
| 
 | 
   213  | 
proof
  | 
| 
 | 
   214  | 
  assume ?lhs then show ?rhs by simp
  | 
| 
 | 
   215  | 
next
  | 
| 
 | 
   216  | 
  assume ?rhs
  | 
| 
 | 
   217  | 
  then have "x \<bullet> x - x \<bullet> y = 0 \<and> x \<bullet> y - y \<bullet> y = 0" by simp
  | 
| 
 | 
   218  | 
  hence "x \<bullet> (x - y) = 0 \<and> y \<bullet> (x - y) = 0" by (simp add: inner_simps inner_commute)
  | 
| 
 | 
   219  | 
  then have "(x - y) \<bullet> (x - y) = 0" by (simp add: field_simps inner_simps inner_commute)
  | 
| 
 | 
   220  | 
  then show "x = y" by (simp)
  | 
| 
 | 
   221  | 
qed
  | 
| 
 | 
   222  | 
  | 
| 
 | 
   223  | 
subsection{* General linear decision procedure for normed spaces. *}
 | 
| 
 | 
   224  | 
  | 
| 
 | 
   225  | 
lemma norm_cmul_rule_thm:
  | 
| 
 | 
   226  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   227  | 
  shows "b >= norm(x) ==> \<bar>c\<bar> * b >= norm(scaleR c x)"
  | 
| 
 | 
   228  | 
  unfolding norm_scaleR
  | 
| 
 | 
   229  | 
  apply (erule mult_left_mono)
  | 
| 
 | 
   230  | 
  apply simp
  | 
| 
 | 
   231  | 
  done
  | 
| 
 | 
   232  | 
  | 
| 
 | 
   233  | 
  (* FIXME: Move all these theorems into the ML code using lemma antiquotation *)
  | 
| 
 | 
   234  | 
lemma norm_add_rule_thm:
  | 
| 
 | 
   235  | 
  fixes x1 x2 :: "'a::real_normed_vector"
  | 
| 
 | 
   236  | 
  shows "norm x1 \<le> b1 \<Longrightarrow> norm x2 \<le> b2 \<Longrightarrow> norm (x1 + x2) \<le> b1 + b2"
  | 
| 
 | 
   237  | 
  by (rule order_trans [OF norm_triangle_ineq add_mono])
  | 
| 
 | 
   238  | 
  | 
| 
 | 
   239  | 
lemma ge_iff_diff_ge_0: "(a::'a::linordered_ring) \<ge> b == a - b \<ge> 0"
  | 
| 
 | 
   240  | 
  by (simp add: field_simps)
  | 
| 
 | 
   241  | 
  | 
| 
 | 
   242  | 
lemma pth_1:
  | 
| 
 | 
   243  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   244  | 
  shows "x == scaleR 1 x" by simp
  | 
| 
 | 
   245  | 
  | 
| 
 | 
   246  | 
lemma pth_2:
  | 
| 
 | 
   247  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   248  | 
  shows "x - y == x + -y" by (atomize (full)) simp
  | 
| 
 | 
   249  | 
  | 
| 
 | 
   250  | 
lemma pth_3:
  | 
| 
 | 
   251  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   252  | 
  shows "- x == scaleR (-1) x" by simp
  | 
| 
 | 
   253  | 
  | 
| 
 | 
   254  | 
lemma pth_4:
  | 
| 
 | 
   255  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   256  | 
  shows "scaleR 0 x == 0" and "scaleR c 0 = (0::'a)" by simp_all
  | 
| 
 | 
   257  | 
  | 
| 
 | 
   258  | 
lemma pth_5:
  | 
| 
 | 
   259  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   260  | 
  shows "scaleR c (scaleR d x) == scaleR (c * d) x" by simp
  | 
| 
 | 
   261  | 
  | 
| 
 | 
   262  | 
lemma pth_6:
  | 
| 
 | 
   263  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   264  | 
  shows "scaleR c (x + y) == scaleR c x + scaleR c y"
  | 
| 
 | 
   265  | 
  by (simp add: scaleR_right_distrib)
  | 
| 
 | 
   266  | 
  | 
| 
 | 
   267  | 
lemma pth_7:
  | 
| 
 | 
   268  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   269  | 
  shows "0 + x == x" and "x + 0 == x" by simp_all
  | 
| 
 | 
   270  | 
  | 
| 
 | 
   271  | 
lemma pth_8:
  | 
| 
 | 
   272  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   273  | 
  shows "scaleR c x + scaleR d x == scaleR (c + d) x"
  | 
| 
 | 
   274  | 
  by (simp add: scaleR_left_distrib)
  | 
| 
 | 
   275  | 
  | 
| 
 | 
   276  | 
lemma pth_9:
  | 
| 
 | 
   277  | 
  fixes x :: "'a::real_normed_vector" shows
  | 
| 
 | 
   278  | 
  "(scaleR c x + z) + scaleR d x == scaleR (c + d) x + z"
  | 
| 
 | 
   279  | 
  "scaleR c x + (scaleR d x + z) == scaleR (c + d) x + z"
  | 
| 
 | 
   280  | 
  "(scaleR c x + w) + (scaleR d x + z) == scaleR (c + d) x + (w + z)"
  | 
| 
 | 
   281  | 
  by (simp_all add: algebra_simps)
  | 
| 
 | 
   282  | 
  | 
| 
 | 
   283  | 
lemma pth_a:
  | 
| 
 | 
   284  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   285  | 
  shows "scaleR 0 x + y == y" by simp
  | 
| 
 | 
   286  | 
  | 
| 
 | 
   287  | 
lemma pth_b:
  | 
| 
 | 
   288  | 
  fixes x :: "'a::real_normed_vector" shows
  | 
| 
 | 
   289  | 
  "scaleR c x + scaleR d y == scaleR c x + scaleR d y"
  | 
| 
 | 
   290  | 
  "(scaleR c x + z) + scaleR d y == scaleR c x + (z + scaleR d y)"
  | 
| 
 | 
   291  | 
  "scaleR c x + (scaleR d y + z) == scaleR c x + (scaleR d y + z)"
  | 
| 
 | 
   292  | 
  "(scaleR c x + w) + (scaleR d y + z) == scaleR c x + (w + (scaleR d y + z))"
  | 
| 
 | 
   293  | 
  by (simp_all add: algebra_simps)
  | 
| 
 | 
   294  | 
  | 
| 
 | 
   295  | 
lemma pth_c:
  | 
| 
 | 
   296  | 
  fixes x :: "'a::real_normed_vector" shows
  | 
| 
 | 
   297  | 
  "scaleR c x + scaleR d y == scaleR d y + scaleR c x"
  | 
| 
 | 
   298  | 
  "(scaleR c x + z) + scaleR d y == scaleR d y + (scaleR c x + z)"
  | 
| 
 | 
   299  | 
  "scaleR c x + (scaleR d y + z) == scaleR d y + (scaleR c x + z)"
  | 
| 
 | 
   300  | 
  "(scaleR c x + w) + (scaleR d y + z) == scaleR d y + ((scaleR c x + w) + z)"
  | 
| 
 | 
   301  | 
  by (simp_all add: algebra_simps)
  | 
| 
 | 
   302  | 
  | 
| 
 | 
   303  | 
lemma pth_d:
  | 
| 
 | 
   304  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   305  | 
  shows "x + 0 == x" by simp
  | 
| 
 | 
   306  | 
  | 
| 
 | 
   307  | 
lemma norm_imp_pos_and_ge:
  | 
| 
 | 
   308  | 
  fixes x :: "'a::real_normed_vector"
  | 
| 
 | 
   309  | 
  shows "norm x == n \<Longrightarrow> norm x \<ge> 0 \<and> n \<ge> norm x"
  | 
| 
 | 
   310  | 
  by atomize auto
  | 
| 
 | 
   311  | 
  | 
| 
 | 
   312  | 
lemma real_eq_0_iff_le_ge_0: "(x::real) = 0 == x \<ge> 0 \<and> -x \<ge> 0" by arith
  | 
| 
 | 
   313  | 
  | 
| 
 | 
   314  | 
lemma norm_pths:
  | 
| 
 | 
   315  | 
  fixes x :: "'a::real_normed_vector" shows
  | 
| 
 | 
   316  | 
  "x = y \<longleftrightarrow> norm (x - y) \<le> 0"
  | 
| 
 | 
   317  | 
  "x \<noteq> y \<longleftrightarrow> \<not> (norm (x - y) \<le> 0)"
  | 
| 
 | 
   318  | 
  using norm_ge_zero[of "x - y"] by auto
  | 
| 
 | 
   319  | 
  | 
| 
 | 
   320  | 
use "normarith.ML"
  | 
| 
 | 
   321  | 
  | 
| 
 | 
   322  | 
method_setup norm = {* Scan.succeed (SIMPLE_METHOD' o NormArith.norm_arith_tac)
 | 
| 
 | 
   323  | 
*} "prove simple linear statements about vector norms"
  | 
| 
 | 
   324  | 
  | 
| 
 | 
   325  | 
  | 
| 
 | 
   326  | 
text{* Hence more metric properties. *}
 | 
| 
 | 
   327  | 
  | 
| 
 | 
   328  | 
lemma norm_triangle_half_r:
  | 
| 
 | 
   329  | 
  shows "norm (y - x1) < e / 2 \<Longrightarrow> norm (y - x2) < e / 2 \<Longrightarrow> norm (x1 - x2) < e"
  | 
| 
 | 
   330  | 
  using dist_triangle_half_r unfolding dist_norm[THEN sym] by auto
  | 
| 
 | 
   331  | 
  | 
| 
 | 
   332  | 
lemma norm_triangle_half_l: assumes "norm (x - y) < e / 2" "norm (x' - (y)) < e / 2" 
  | 
| 
 | 
   333  | 
  shows "norm (x - x') < e"
  | 
| 
 | 
   334  | 
  using dist_triangle_half_l[OF assms[unfolded dist_norm[THEN sym]]]
  | 
| 
 | 
   335  | 
  unfolding dist_norm[THEN sym] .
  | 
| 
 | 
   336  | 
  | 
| 
 | 
   337  | 
lemma norm_triangle_le: "norm(x) + norm y <= e ==> norm(x + y) <= e"
  | 
| 
 | 
   338  | 
  by (metis order_trans norm_triangle_ineq)
  | 
| 
 | 
   339  | 
  | 
| 
 | 
   340  | 
lemma norm_triangle_lt: "norm(x) + norm(y) < e ==> norm(x + y) < e"
  | 
| 
 | 
   341  | 
  by (metis basic_trans_rules(21) norm_triangle_ineq)
  | 
| 
 | 
   342  | 
  | 
| 
 | 
   343  | 
lemma dist_triangle_add:
  | 
| 
 | 
   344  | 
  fixes x y x' y' :: "'a::real_normed_vector"
  | 
| 
 | 
   345  | 
  shows "dist (x + y) (x' + y') <= dist x x' + dist y y'"
  | 
| 
 | 
   346  | 
  by norm
  | 
| 
 | 
   347  | 
  | 
| 
 | 
   348  | 
lemma dist_triangle_add_half:
  | 
| 
 | 
   349  | 
  fixes x x' y y' :: "'a::real_normed_vector"
  | 
| 
 | 
   350  | 
  shows "dist x x' < e / 2 \<Longrightarrow> dist y y' < e / 2 \<Longrightarrow> dist(x + y) (x' + y') < e"
  | 
| 
 | 
   351  | 
  by norm
  | 
| 
 | 
   352  | 
  | 
| 
 | 
   353  | 
lemma setsum_clauses:
  | 
| 
 | 
   354  | 
  shows "setsum f {} = 0"
 | 
| 
 | 
   355  | 
  and "finite S \<Longrightarrow> setsum f (insert x S) =
  | 
| 
 | 
   356  | 
                 (if x \<in> S then setsum f S else f x + setsum f S)"
  | 
| 
 | 
   357  | 
  by (auto simp add: insert_absorb)
  | 
| 
 | 
   358  | 
  | 
| 
 | 
   359  | 
lemma setsum_norm:
  | 
| 
 | 
   360  | 
  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  | 
| 
 | 
   361  | 
  assumes fS: "finite S"
  | 
| 
 | 
   362  | 
  shows "norm (setsum f S) <= setsum (\<lambda>x. norm(f x)) S"
  | 
| 
 | 
   363  | 
proof(induct rule: finite_induct[OF fS])
  | 
| 
 | 
   364  | 
  case 1 thus ?case by simp
  | 
| 
 | 
   365  | 
next
  | 
| 
 | 
   366  | 
  case (2 x S)
  | 
| 
 | 
   367  | 
  from "2.hyps" have "norm (setsum f (insert x S)) \<le> norm (f x) + norm (setsum f S)" by (simp add: norm_triangle_ineq)
  | 
| 
 | 
   368  | 
  also have "\<dots> \<le> norm (f x) + setsum (\<lambda>x. norm(f x)) S"
  | 
| 
 | 
   369  | 
    using "2.hyps" by simp
  | 
| 
 | 
   370  | 
  finally  show ?case  using "2.hyps" by simp
  | 
| 
 | 
   371  | 
qed
  | 
| 
 | 
   372  | 
  | 
| 
 | 
   373  | 
lemma setsum_norm_le:
  | 
| 
 | 
   374  | 
  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  | 
| 
 | 
   375  | 
  assumes fS: "finite S"
  | 
| 
 | 
   376  | 
  and fg: "\<forall>x \<in> S. norm (f x) \<le> g x"
  | 
| 
 | 
   377  | 
  shows "norm (setsum f S) \<le> setsum g S"
  | 
| 
 | 
   378  | 
proof-
  | 
| 
 | 
   379  | 
  from fg have "setsum (\<lambda>x. norm(f x)) S <= setsum g S"
  | 
| 
 | 
   380  | 
    by - (rule setsum_mono, simp)
  | 
| 
 | 
   381  | 
  then show ?thesis using setsum_norm[OF fS, of f] fg
  | 
| 
 | 
   382  | 
    by arith
  | 
| 
 | 
   383  | 
qed
  | 
| 
 | 
   384  | 
  | 
| 
 | 
   385  | 
lemma setsum_norm_bound:
  | 
| 
 | 
   386  | 
  fixes f :: "'a \<Rightarrow> 'b::real_normed_vector"
  | 
| 
 | 
   387  | 
  assumes fS: "finite S"
  | 
| 
 | 
   388  | 
  and K: "\<forall>x \<in> S. norm (f x) \<le> K"
  | 
| 
 | 
   389  | 
  shows "norm (setsum f S) \<le> of_nat (card S) * K"
  | 
| 
 | 
   390  | 
  using setsum_norm_le[OF fS K] setsum_constant[symmetric]
  | 
| 
 | 
   391  | 
  by simp
  | 
| 
 | 
   392  | 
  | 
| 
 | 
   393  | 
lemma setsum_group:
  | 
| 
 | 
   394  | 
  assumes fS: "finite S" and fT: "finite T" and fST: "f ` S \<subseteq> T"
  | 
| 
 | 
   395  | 
  shows "setsum (\<lambda>y. setsum g {x. x\<in> S \<and> f x = y}) T = setsum g S"
 | 
| 
 | 
   396  | 
  apply (subst setsum_image_gen[OF fS, of g f])
  | 
| 
 | 
   397  | 
  apply (rule setsum_mono_zero_right[OF fT fST])
  | 
| 
 | 
   398  | 
  by (auto intro: setsum_0')
  | 
| 
 | 
   399  | 
  | 
| 
 | 
   400  | 
lemma dot_lsum: "finite S \<Longrightarrow> setsum f S \<bullet> y = setsum (\<lambda>x. f x \<bullet> y) S "
  | 
| 
 | 
   401  | 
  apply(induct rule: finite_induct) by(auto simp add: inner_simps)
  | 
| 
 | 
   402  | 
  | 
| 
 | 
   403  | 
lemma dot_rsum: "finite S \<Longrightarrow> y \<bullet> setsum f S = setsum (\<lambda>x. y \<bullet> f x) S "
  | 
| 
 | 
   404  | 
  apply(induct rule: finite_induct) by(auto simp add: inner_simps)
  | 
| 
 | 
   405  | 
  | 
| 
 | 
   406  | 
lemma vector_eq_ldot: "(\<forall>x. x \<bullet> y = x \<bullet> z) \<longleftrightarrow> y = z"
  | 
| 
 | 
   407  | 
proof
  | 
| 
 | 
   408  | 
  assume "\<forall>x. x \<bullet> y = x \<bullet> z"
  | 
| 
 | 
   409  | 
  hence "\<forall>x. x \<bullet> (y - z) = 0" by (simp add: inner_simps)
  | 
| 
 | 
   410  | 
  hence "(y - z) \<bullet> (y - z) = 0" ..
  | 
| 
 | 
   411  | 
  thus "y = z" by simp
  | 
| 
 | 
   412  | 
qed simp
  | 
| 
 | 
   413  | 
  | 
| 
 | 
   414  | 
lemma vector_eq_rdot: "(\<forall>z. x \<bullet> z = y \<bullet> z) \<longleftrightarrow> x = y"
  | 
| 
 | 
   415  | 
proof
  | 
| 
 | 
   416  | 
  assume "\<forall>z. x \<bullet> z = y \<bullet> z"
  | 
| 
 | 
   417  | 
  hence "\<forall>z. (x - y) \<bullet> z = 0" by (simp add: inner_simps)
  | 
| 
 | 
   418  | 
  hence "(x - y) \<bullet> (x - y) = 0" ..
  | 
| 
 | 
   419  | 
  thus "x = y" by simp
  | 
| 
 | 
   420  | 
qed simp
  | 
| 
 | 
   421  | 
  | 
| 
 | 
   422  | 
subsection{* Orthogonality. *}
 | 
| 
 | 
   423  | 
  | 
| 
 | 
   424  | 
context real_inner
  | 
| 
 | 
   425  | 
begin
  | 
| 
 | 
   426  | 
  | 
| 
 | 
   427  | 
definition "orthogonal x y \<longleftrightarrow> (x \<bullet> y = 0)"
  | 
| 
 | 
   428  | 
  | 
| 
 | 
   429  | 
lemma orthogonal_clauses:
  | 
| 
 | 
   430  | 
  "orthogonal a 0"
  | 
| 
 | 
   431  | 
  "orthogonal a x \<Longrightarrow> orthogonal a (c *\<^sub>R x)"
  | 
| 
 | 
   432  | 
  "orthogonal a x \<Longrightarrow> orthogonal a (-x)"
  | 
| 
 | 
   433  | 
  "orthogonal a x \<Longrightarrow> orthogonal a y \<Longrightarrow> orthogonal a (x + y)"
  | 
| 
 | 
   434  | 
  "orthogonal a x \<Longrightarrow> orthogonal a y \<Longrightarrow> orthogonal a (x - y)"
  | 
| 
 | 
   435  | 
  "orthogonal 0 a"
  | 
| 
 | 
   436  | 
  "orthogonal x a \<Longrightarrow> orthogonal (c *\<^sub>R x) a"
  | 
| 
 | 
   437  | 
  "orthogonal x a \<Longrightarrow> orthogonal (-x) a"
  | 
| 
 | 
   438  | 
  "orthogonal x a \<Longrightarrow> orthogonal y a \<Longrightarrow> orthogonal (x + y) a"
  | 
| 
 | 
   439  | 
  "orthogonal x a \<Longrightarrow> orthogonal y a \<Longrightarrow> orthogonal (x - y) a"
  | 
| 
 | 
   440  | 
  unfolding orthogonal_def inner_simps inner_add_left inner_add_right inner_diff_left inner_diff_right (*FIXME*) by auto
  | 
| 
 | 
   441  | 
 
  | 
| 
 | 
   442  | 
end
  | 
| 
 | 
   443  | 
  | 
| 
 | 
   444  | 
lemma orthogonal_commute: "orthogonal x y \<longleftrightarrow> orthogonal y x"
  | 
| 
 | 
   445  | 
  by (simp add: orthogonal_def inner_commute)
  | 
| 
 | 
   446  | 
  | 
| 
 | 
   447  | 
subsection{* Linear functions. *}
 | 
| 
 | 
   448  | 
  | 
| 
 | 
   449  | 
definition
  | 
| 
 | 
   450  | 
  linear :: "('a::real_vector \<Rightarrow> 'b::real_vector) \<Rightarrow> bool" where
 | 
| 
 | 
   451  | 
  "linear f \<longleftrightarrow> (\<forall>x y. f(x + y) = f x + f y) \<and> (\<forall>c x. f(c *\<^sub>R x) = c *\<^sub>R f x)"
  | 
| 
 | 
   452  | 
  | 
| 
 | 
   453  | 
lemma linearI: assumes "\<And>x y. f (x + y) = f x + f y" "\<And>c x. f (c *\<^sub>R x) = c *\<^sub>R f x"
  | 
| 
 | 
   454  | 
  shows "linear f" using assms unfolding linear_def by auto
  | 
| 
 | 
   455  | 
  | 
| 
 | 
   456  | 
lemma linear_compose_cmul: "linear f ==> linear (\<lambda>x. c *\<^sub>R f x)"
  | 
| 
 | 
   457  | 
  by (simp add: linear_def algebra_simps)
  | 
| 
 | 
   458  | 
  | 
| 
 | 
   459  | 
lemma linear_compose_neg: "linear f ==> linear (\<lambda>x. -(f(x)))"
  | 
| 
 | 
   460  | 
  by (simp add: linear_def)
  | 
| 
 | 
   461  | 
  | 
| 
 | 
   462  | 
lemma linear_compose_add: "linear f \<Longrightarrow> linear g ==> linear (\<lambda>x. f(x) + g(x))"
  | 
| 
 | 
   463  | 
  by (simp add: linear_def algebra_simps)
  | 
| 
 | 
   464  | 
  | 
| 
 | 
   465  | 
lemma linear_compose_sub: "linear f \<Longrightarrow> linear g ==> linear (\<lambda>x. f x - g x)"
  | 
| 
 | 
   466  | 
  by (simp add: linear_def algebra_simps)
  | 
| 
 | 
   467  | 
  | 
| 
 | 
   468  | 
lemma linear_compose: "linear f \<Longrightarrow> linear g ==> linear (g o f)"
  | 
| 
 | 
   469  | 
  by (simp add: linear_def)
  | 
| 
 | 
   470  | 
  | 
| 
 | 
   471  | 
lemma linear_id: "linear id" by (simp add: linear_def id_def)
  | 
| 
 | 
   472  | 
  | 
| 
 | 
   473  | 
lemma linear_zero: "linear (\<lambda>x. 0)" by (simp add: linear_def)
  | 
| 
 | 
   474  | 
  | 
| 
 | 
   475  | 
lemma linear_compose_setsum:
  | 
| 
 | 
   476  | 
  assumes fS: "finite S" and lS: "\<forall>a \<in> S. linear (f a)"
  | 
| 
 | 
   477  | 
  shows "linear(\<lambda>x. setsum (\<lambda>a. f a x) S)"
  | 
| 
 | 
   478  | 
  using lS
  | 
| 
 | 
   479  | 
  apply (induct rule: finite_induct[OF fS])
  | 
| 
 | 
   480  | 
  by (auto simp add: linear_zero intro: linear_compose_add)
  | 
| 
 | 
   481  | 
  | 
| 
 | 
   482  | 
lemma linear_0: "linear f \<Longrightarrow> f 0 = 0"
  | 
| 
 | 
   483  | 
  unfolding linear_def
  | 
| 
 | 
   484  | 
  apply clarsimp
  | 
| 
 | 
   485  | 
  apply (erule allE[where x="0::'a"])
  | 
| 
 | 
   486  | 
  apply simp
  | 
| 
 | 
   487  | 
  done
  | 
| 
 | 
   488  | 
  | 
| 
 | 
   489  | 
lemma linear_cmul: "linear f ==> f(c *\<^sub>R x) = c *\<^sub>R f x" by (simp add: linear_def)
  | 
| 
 | 
   490  | 
  | 
| 
 | 
   491  | 
lemma linear_neg: "linear f ==> f (-x) = - f x"
  | 
| 
 | 
   492  | 
  using linear_cmul [where c="-1"] by simp
  | 
| 
 | 
   493  | 
  | 
| 
 | 
   494  | 
lemma linear_add: "linear f ==> f(x + y) = f x + f y" by (metis linear_def)
  | 
| 
 | 
   495  | 
  | 
| 
 | 
   496  | 
lemma linear_sub: "linear f ==> f(x - y) = f x - f y"
  | 
| 
 | 
   497  | 
  by (simp add: diff_minus linear_add linear_neg)
  | 
| 
 | 
   498  | 
  | 
| 
 | 
   499  | 
lemma linear_setsum:
  | 
| 
 | 
   500  | 
  assumes lf: "linear f" and fS: "finite S"
  | 
| 
 | 
   501  | 
  shows "f (setsum g S) = setsum (f o g) S"
  | 
| 
 | 
   502  | 
proof (induct rule: finite_induct[OF fS])
  | 
| 
 | 
   503  | 
  case 1 thus ?case by (simp add: linear_0[OF lf])
  | 
| 
 | 
   504  | 
next
  | 
| 
 | 
   505  | 
  case (2 x F)
  | 
| 
 | 
   506  | 
  have "f (setsum g (insert x F)) = f (g x + setsum g F)" using "2.hyps"
  | 
| 
 | 
   507  | 
    by simp
  | 
| 
 | 
   508  | 
  also have "\<dots> = f (g x) + f (setsum g F)" using linear_add[OF lf] by simp
  | 
| 
 | 
   509  | 
  also have "\<dots> = setsum (f o g) (insert x F)" using "2.hyps" by simp
  | 
| 
 | 
   510  | 
  finally show ?case .
  | 
| 
 | 
   511  | 
qed
  | 
| 
 | 
   512  | 
  | 
| 
 | 
   513  | 
lemma linear_setsum_mul:
  | 
| 
 | 
   514  | 
  assumes lf: "linear f" and fS: "finite S"
  | 
| 
 | 
   515  | 
  shows "f (setsum (\<lambda>i. c i *\<^sub>R v i) S) = setsum (\<lambda>i. c i *\<^sub>R f (v i)) S"
  | 
| 
 | 
   516  | 
  using linear_setsum[OF lf fS, of "\<lambda>i. c i *\<^sub>R v i" , unfolded o_def]
  | 
| 
 | 
   517  | 
  linear_cmul[OF lf] by simp
  | 
| 
 | 
   518  | 
  | 
| 
 | 
   519  | 
lemma linear_injective_0:
  | 
| 
 | 
   520  | 
  assumes lf: "linear f"
  | 
| 
 | 
   521  | 
  shows "inj f \<longleftrightarrow> (\<forall>x. f x = 0 \<longrightarrow> x = 0)"
  | 
| 
 | 
   522  | 
proof-
  | 
| 
 | 
   523  | 
  have "inj f \<longleftrightarrow> (\<forall> x y. f x = f y \<longrightarrow> x = y)" by (simp add: inj_on_def)
  | 
| 
 | 
   524  | 
  also have "\<dots> \<longleftrightarrow> (\<forall> x y. f x - f y = 0 \<longrightarrow> x - y = 0)" by simp
  | 
| 
 | 
   525  | 
  also have "\<dots> \<longleftrightarrow> (\<forall> x y. f (x - y) = 0 \<longrightarrow> x - y = 0)"
  | 
| 
 | 
   526  | 
    by (simp add: linear_sub[OF lf])
  | 
| 
 | 
   527  | 
  also have "\<dots> \<longleftrightarrow> (\<forall> x. f x = 0 \<longrightarrow> x = 0)" by auto
  | 
| 
 | 
   528  | 
  finally show ?thesis .
  | 
| 
 | 
   529  | 
qed
  | 
| 
 | 
   530  | 
  | 
| 
 | 
   531  | 
subsection{* Bilinear functions. *}
 | 
| 
 | 
   532  | 
  | 
| 
 | 
   533  | 
definition "bilinear f \<longleftrightarrow> (\<forall>x. linear(\<lambda>y. f x y)) \<and> (\<forall>y. linear(\<lambda>x. f x y))"
  | 
| 
 | 
   534  | 
  | 
| 
 | 
   535  | 
lemma bilinear_ladd: "bilinear h ==> h (x + y) z = (h x z) + (h y z)"
  | 
| 
 | 
   536  | 
  by (simp add: bilinear_def linear_def)
  | 
| 
 | 
   537  | 
lemma bilinear_radd: "bilinear h ==> h x (y + z) = (h x y) + (h x z)"
  | 
| 
 | 
   538  | 
  by (simp add: bilinear_def linear_def)
  | 
| 
 | 
   539  | 
  | 
| 
 | 
   540  | 
lemma bilinear_lmul: "bilinear h ==> h (c *\<^sub>R x) y = c *\<^sub>R (h x y)"
  | 
| 
 | 
   541  | 
  by (simp add: bilinear_def linear_def)
  | 
| 
 | 
   542  | 
  | 
| 
 | 
   543  | 
lemma bilinear_rmul: "bilinear h ==> h x (c *\<^sub>R y) = c *\<^sub>R (h x y)"
  | 
| 
 | 
   544  | 
  by (simp add: bilinear_def linear_def)
  | 
| 
 | 
   545  | 
  | 
| 
 | 
   546  | 
lemma bilinear_lneg: "bilinear h ==> h (- x) y = -(h x y)"
  | 
| 
 | 
   547  | 
  by (simp only: scaleR_minus1_left [symmetric] bilinear_lmul)
  | 
| 
 | 
   548  | 
  | 
| 
 | 
   549  | 
lemma bilinear_rneg: "bilinear h ==> h x (- y) = - h x y"
  | 
| 
 | 
   550  | 
  by (simp only: scaleR_minus1_left [symmetric] bilinear_rmul)
  | 
| 
 | 
   551  | 
  | 
| 
 | 
   552  | 
lemma  (in ab_group_add) eq_add_iff: "x = x + y \<longleftrightarrow> y = 0"
  | 
| 
 | 
   553  | 
  using add_imp_eq[of x y 0] by auto
  | 
| 
 | 
   554  | 
  | 
| 
 | 
   555  | 
lemma bilinear_lzero:
  | 
| 
 | 
   556  | 
  assumes bh: "bilinear h" shows "h 0 x = 0"
  | 
| 
 | 
   557  | 
  using bilinear_ladd[OF bh, of 0 0 x]
  | 
| 
 | 
   558  | 
    by (simp add: eq_add_iff field_simps)
  | 
| 
 | 
   559  | 
  | 
| 
 | 
   560  | 
lemma bilinear_rzero:
  | 
| 
 | 
   561  | 
  assumes bh: "bilinear h" shows "h x 0 = 0"
  | 
| 
 | 
   562  | 
  using bilinear_radd[OF bh, of x 0 0 ]
  | 
| 
 | 
   563  | 
    by (simp add: eq_add_iff field_simps)
  | 
| 
 | 
   564  | 
  | 
| 
 | 
   565  | 
lemma bilinear_lsub: "bilinear h ==> h (x - y) z = h x z - h y z"
  | 
| 
 | 
   566  | 
  by (simp  add: diff_minus bilinear_ladd bilinear_lneg)
  | 
| 
 | 
   567  | 
  | 
| 
 | 
   568  | 
lemma bilinear_rsub: "bilinear h ==> h z (x - y) = h z x - h z y"
  | 
| 
 | 
   569  | 
  by (simp  add: diff_minus bilinear_radd bilinear_rneg)
  | 
| 
 | 
   570  | 
  | 
| 
 | 
   571  | 
lemma bilinear_setsum:
  | 
| 
 | 
   572  | 
  assumes bh: "bilinear h" and fS: "finite S" and fT: "finite T"
  | 
| 
 | 
   573  | 
  shows "h (setsum f S) (setsum g T) = setsum (\<lambda>(i,j). h (f i) (g j)) (S \<times> T) "
  | 
| 
 | 
   574  | 
proof-
  | 
| 
 | 
   575  | 
  have "h (setsum f S) (setsum g T) = setsum (\<lambda>x. h (f x) (setsum g T)) S"
  | 
| 
 | 
   576  | 
    apply (rule linear_setsum[unfolded o_def])
  | 
| 
 | 
   577  | 
    using bh fS by (auto simp add: bilinear_def)
  | 
| 
 | 
   578  | 
  also have "\<dots> = setsum (\<lambda>x. setsum (\<lambda>y. h (f x) (g y)) T) S"
  | 
| 
 | 
   579  | 
    apply (rule setsum_cong, simp)
  | 
| 
 | 
   580  | 
    apply (rule linear_setsum[unfolded o_def])
  | 
| 
 | 
   581  | 
    using bh fT by (auto simp add: bilinear_def)
  | 
| 
 | 
   582  | 
  finally show ?thesis unfolding setsum_cartesian_product .
  | 
| 
 | 
   583  | 
qed
  | 
| 
 | 
   584  | 
  | 
| 
 | 
   585  | 
subsection{* Adjoints. *}
 | 
| 
 | 
   586  | 
  | 
| 
 | 
   587  | 
definition "adjoint f = (SOME f'. \<forall>x y. f x \<bullet> y = x \<bullet> f' y)"
  | 
| 
 | 
   588  | 
  | 
| 
 | 
   589  | 
lemma adjoint_unique:
  | 
| 
 | 
   590  | 
  assumes "\<forall>x y. inner (f x) y = inner x (g y)"
  | 
| 
 | 
   591  | 
  shows "adjoint f = g"
  | 
| 
 | 
   592  | 
unfolding adjoint_def
  | 
| 
 | 
   593  | 
proof (rule some_equality)
  | 
| 
 | 
   594  | 
  show "\<forall>x y. inner (f x) y = inner x (g y)" using assms .
  | 
| 
 | 
   595  | 
next
  | 
| 
 | 
   596  | 
  fix h assume "\<forall>x y. inner (f x) y = inner x (h y)"
  | 
| 
 | 
   597  | 
  hence "\<forall>x y. inner x (g y) = inner x (h y)" using assms by simp
  | 
| 
 | 
   598  | 
  hence "\<forall>x y. inner x (g y - h y) = 0" by (simp add: inner_diff_right)
  | 
| 
 | 
   599  | 
  hence "\<forall>y. inner (g y - h y) (g y - h y) = 0" by simp
  | 
| 
 | 
   600  | 
  hence "\<forall>y. h y = g y" by simp
  | 
| 
 | 
   601  | 
  thus "h = g" by (simp add: ext)
  | 
| 
 | 
   602  | 
qed
  | 
| 
 | 
   603  | 
  | 
| 
 | 
   604  | 
lemma choice_iff: "(\<forall>x. \<exists>y. P x y) \<longleftrightarrow> (\<exists>f. \<forall>x. P x (f x))" by metis
  | 
| 
 | 
   605  | 
  | 
| 
 | 
   606  | 
subsection{* Interlude: Some properties of real sets *}
 | 
| 
 | 
   607  | 
  | 
| 
 | 
   608  | 
lemma seq_mono_lemma: assumes "\<forall>(n::nat) \<ge> m. (d n :: real) < e n" and "\<forall>n \<ge> m. e n <= e m"
  | 
| 
 | 
   609  | 
  shows "\<forall>n \<ge> m. d n < e m"
  | 
| 
 | 
   610  | 
  using assms apply auto
  | 
| 
 | 
   611  | 
  apply (erule_tac x="n" in allE)
  | 
| 
 | 
   612  | 
  apply (erule_tac x="n" in allE)
  | 
| 
 | 
   613  | 
  apply auto
  | 
| 
 | 
   614  | 
  done
  | 
| 
 | 
   615  | 
  | 
| 
 | 
   616  | 
  | 
| 
 | 
   617  | 
lemma infinite_enumerate: assumes fS: "infinite S"
  | 
| 
 | 
   618  | 
  shows "\<exists>r. subseq r \<and> (\<forall>n. r n \<in> S)"
  | 
| 
 | 
   619  | 
unfolding subseq_def
  | 
| 
 | 
   620  | 
using enumerate_in_set[OF fS] enumerate_mono[of _ _ S] fS by auto
  | 
| 
 | 
   621  | 
  | 
| 
 | 
   622  | 
lemma approachable_lt_le: "(\<exists>(d::real)>0. \<forall>x. f x < d \<longrightarrow> P x) \<longleftrightarrow> (\<exists>d>0. \<forall>x. f x \<le> d \<longrightarrow> P x)"
  | 
| 
 | 
   623  | 
apply auto
  | 
| 
 | 
   624  | 
apply (rule_tac x="d/2" in exI)
  | 
| 
 | 
   625  | 
apply auto
  | 
| 
 | 
   626  | 
done
  | 
| 
 | 
   627  | 
  | 
| 
 | 
   628  | 
  | 
| 
 | 
   629  | 
lemma triangle_lemma:
  | 
| 
 | 
   630  | 
  assumes x: "0 <= (x::real)" and y:"0 <= y" and z: "0 <= z" and xy: "x^2 <= y^2 + z^2"
  | 
| 
 | 
   631  | 
  shows "x <= y + z"
  | 
| 
 | 
   632  | 
proof-
  | 
| 
 | 
   633  | 
  have "y^2 + z^2 \<le> y^2 + 2*y*z + z^2" using z y by (simp add: mult_nonneg_nonneg)
  | 
| 
 | 
   634  | 
  with xy have th: "x ^2 \<le> (y+z)^2" by (simp add: power2_eq_square field_simps)
  | 
| 
 | 
   635  | 
  from y z have yz: "y + z \<ge> 0" by arith
  | 
| 
 | 
   636  | 
  from power2_le_imp_le[OF th yz] show ?thesis .
  | 
| 
 | 
   637  | 
qed
  | 
| 
 | 
   638  | 
  | 
| 
 | 
   639  | 
text {* TODO: move to NthRoot *}
 | 
| 
 | 
   640  | 
lemma sqrt_add_le_add_sqrt:
  | 
| 
 | 
   641  | 
  assumes x: "0 \<le> x" and y: "0 \<le> y"
  | 
| 
 | 
   642  | 
  shows "sqrt (x + y) \<le> sqrt x + sqrt y"
  | 
| 
 | 
   643  | 
apply (rule power2_le_imp_le)
  | 
| 
44142
 | 
   644  | 
apply (simp add: real_sum_squared_expand x y)
  | 
| 
44133
 | 
   645  | 
apply (simp add: mult_nonneg_nonneg x y)
  | 
| 
44142
 | 
   646  | 
apply (simp add: x y)
  | 
| 
44133
 | 
   647  | 
done
  | 
| 
 | 
   648  | 
  | 
| 
 | 
   649  | 
subsection {* A generic notion of "hull" (convex, affine, conic hull and closure). *}
 | 
| 
 | 
   650  | 
  | 
| 
 | 
   651  | 
definition hull :: "'a set set \<Rightarrow> 'a set \<Rightarrow> 'a set" (infixl "hull" 75) where
  | 
| 
 | 
   652  | 
  "S hull s = Inter {t. t \<in> S \<and> s \<subseteq> t}"
 | 
| 
 | 
   653  | 
  | 
| 
 | 
   654  | 
lemma hull_same: "s \<in> S \<Longrightarrow> S hull s = s"
  | 
| 
 | 
   655  | 
  unfolding hull_def by auto
  | 
| 
 | 
   656  | 
  | 
| 
 | 
   657  | 
lemma hull_in: "(\<And>T. T \<subseteq> S ==> Inter T \<in> S) ==> (S hull s) \<in> S"
  | 
| 
 | 
   658  | 
unfolding hull_def subset_iff by auto
  | 
| 
 | 
   659  | 
  | 
| 
 | 
   660  | 
lemma hull_eq: "(\<And>T. T \<subseteq> S ==> Inter T \<in> S) ==> (S hull s) = s \<longleftrightarrow> s \<in> S"
  | 
| 
 | 
   661  | 
using hull_same[of s S] hull_in[of S s] by metis
  | 
| 
 | 
   662  | 
  | 
| 
 | 
   663  | 
  | 
| 
 | 
   664  | 
lemma hull_hull: "S hull (S hull s) = S hull s"
  | 
| 
 | 
   665  | 
  unfolding hull_def by blast
  | 
| 
 | 
   666  | 
  | 
| 
 | 
   667  | 
lemma hull_subset[intro]: "s \<subseteq> (S hull s)"
  | 
| 
 | 
   668  | 
  unfolding hull_def by blast
  | 
| 
 | 
   669  | 
  | 
| 
 | 
   670  | 
lemma hull_mono: " s \<subseteq> t ==> (S hull s) \<subseteq> (S hull t)"
  | 
| 
 | 
   671  | 
  unfolding hull_def by blast
  | 
| 
 | 
   672  | 
  | 
| 
 | 
   673  | 
lemma hull_antimono: "S \<subseteq> T ==> (T hull s) \<subseteq> (S hull s)"
  | 
| 
 | 
   674  | 
  unfolding hull_def by blast
  | 
| 
 | 
   675  | 
  | 
| 
 | 
   676  | 
lemma hull_minimal: "s \<subseteq> t \<Longrightarrow> t \<in> S ==> (S hull s) \<subseteq> t"
  | 
| 
 | 
   677  | 
  unfolding hull_def by blast
  | 
| 
 | 
   678  | 
  | 
| 
 | 
   679  | 
lemma subset_hull: "t \<in> S ==> S hull s \<subseteq> t \<longleftrightarrow>  s \<subseteq> t"
  | 
| 
 | 
   680  | 
  unfolding hull_def by blast
  | 
| 
 | 
   681  | 
  | 
| 
 | 
   682  | 
lemma hull_unique: "s \<subseteq> t \<Longrightarrow> t \<in> S \<Longrightarrow> (\<And>t'. s \<subseteq> t' \<Longrightarrow> t' \<in> S ==> t \<subseteq> t')
  | 
| 
 | 
   683  | 
           ==> (S hull s = t)"
  | 
| 
 | 
   684  | 
unfolding hull_def by auto
  | 
| 
 | 
   685  | 
  | 
| 
 | 
   686  | 
lemma hull_induct: "(\<And>x. x\<in> S \<Longrightarrow> P x) \<Longrightarrow> Q {x. P x} \<Longrightarrow> \<forall>x\<in> Q hull S. P x"
 | 
| 
 | 
   687  | 
  using hull_minimal[of S "{x. P x}" Q]
 | 
| 
 | 
   688  | 
  by (auto simp add: subset_eq Collect_def mem_def)
  | 
| 
 | 
   689  | 
  | 
| 
 | 
   690  | 
lemma hull_inc: "x \<in> S \<Longrightarrow> x \<in> P hull S" by (metis hull_subset subset_eq)
  | 
| 
 | 
   691  | 
  | 
| 
 | 
   692  | 
lemma hull_union_subset: "(S hull s) \<union> (S hull t) \<subseteq> (S hull (s \<union> t))"
  | 
| 
 | 
   693  | 
unfolding Un_subset_iff by (metis hull_mono Un_upper1 Un_upper2)
  | 
| 
 | 
   694  | 
  | 
| 
 | 
   695  | 
lemma hull_union: assumes T: "\<And>T. T \<subseteq> S ==> Inter T \<in> S"
  | 
| 
 | 
   696  | 
  shows "S hull (s \<union> t) = S hull (S hull s \<union> S hull t)"
  | 
| 
 | 
   697  | 
apply rule
  | 
| 
 | 
   698  | 
apply (rule hull_mono)
  | 
| 
 | 
   699  | 
unfolding Un_subset_iff
  | 
| 
 | 
   700  | 
apply (metis hull_subset Un_upper1 Un_upper2 subset_trans)
  | 
| 
 | 
   701  | 
apply (rule hull_minimal)
  | 
| 
 | 
   702  | 
apply (metis hull_union_subset)
  | 
| 
 | 
   703  | 
apply (metis hull_in T)
  | 
| 
 | 
   704  | 
done
  | 
| 
 | 
   705  | 
  | 
| 
 | 
   706  | 
lemma hull_redundant_eq: "a \<in> (S hull s) \<longleftrightarrow> (S hull (insert a s) = S hull s)"
  | 
| 
 | 
   707  | 
  unfolding hull_def by blast
  | 
| 
 | 
   708  | 
  | 
| 
 | 
   709  | 
lemma hull_redundant: "a \<in> (S hull s) ==> (S hull (insert a s) = S hull s)"
  | 
| 
 | 
   710  | 
by (metis hull_redundant_eq)
  | 
| 
 | 
   711  | 
  | 
| 
 | 
   712  | 
text{* Archimedian properties and useful consequences. *}
 | 
| 
 | 
   713  | 
  | 
| 
 | 
   714  | 
lemma real_arch_simple: "\<exists>n. x <= real (n::nat)"
  | 
| 
 | 
   715  | 
  using reals_Archimedean2[of x] apply auto by (rule_tac x="Suc n" in exI, auto)
  | 
| 
 | 
   716  | 
lemmas real_arch_lt = reals_Archimedean2
  | 
| 
 | 
   717  | 
  | 
| 
 | 
   718  | 
lemmas real_arch = reals_Archimedean3
  | 
| 
 | 
   719  | 
  | 
| 
 | 
   720  | 
lemma real_arch_inv: "0 < e \<longleftrightarrow> (\<exists>n::nat. n \<noteq> 0 \<and> 0 < inverse (real n) \<and> inverse (real n) < e)"
  | 
| 
 | 
   721  | 
  using reals_Archimedean
  | 
| 
 | 
   722  | 
  apply (auto simp add: field_simps)
  | 
| 
 | 
   723  | 
  apply (subgoal_tac "inverse (real n) > 0")
  | 
| 
 | 
   724  | 
  apply arith
  | 
| 
 | 
   725  | 
  apply simp
  | 
| 
 | 
   726  | 
  done
  | 
| 
 | 
   727  | 
  | 
| 
 | 
   728  | 
lemma real_pow_lbound: "0 <= x ==> 1 + real n * x <= (1 + x) ^ n"
  | 
| 
 | 
   729  | 
proof(induct n)
  | 
| 
 | 
   730  | 
  case 0 thus ?case by simp
  | 
| 
 | 
   731  | 
next
  | 
| 
 | 
   732  | 
  case (Suc n)
  | 
| 
 | 
   733  | 
  hence h: "1 + real n * x \<le> (1 + x) ^ n" by simp
  | 
| 
 | 
   734  | 
  from h have p: "1 \<le> (1 + x) ^ n" using Suc.prems by simp
  | 
| 
 | 
   735  | 
  from h have "1 + real n * x + x \<le> (1 + x) ^ n + x" by simp
  | 
| 
 | 
   736  | 
  also have "\<dots> \<le> (1 + x) ^ Suc n" apply (subst diff_le_0_iff_le[symmetric])
  | 
| 
 | 
   737  | 
    apply (simp add: field_simps)
  | 
| 
 | 
   738  | 
    using mult_left_mono[OF p Suc.prems] by simp
  | 
| 
 | 
   739  | 
  finally show ?case  by (simp add: real_of_nat_Suc field_simps)
  | 
| 
 | 
   740  | 
qed
  | 
| 
 | 
   741  | 
  | 
| 
 | 
   742  | 
lemma real_arch_pow: assumes x: "1 < (x::real)" shows "\<exists>n. y < x^n"
  | 
| 
 | 
   743  | 
proof-
  | 
| 
 | 
   744  | 
  from x have x0: "x - 1 > 0" by arith
  | 
| 
 | 
   745  | 
  from real_arch[OF x0, rule_format, of y]
  | 
| 
 | 
   746  | 
  obtain n::nat where n:"y < real n * (x - 1)" by metis
  | 
| 
 | 
   747  | 
  from x0 have x00: "x- 1 \<ge> 0" by arith
  | 
| 
 | 
   748  | 
  from real_pow_lbound[OF x00, of n] n
  | 
| 
 | 
   749  | 
  have "y < x^n" by auto
  | 
| 
 | 
   750  | 
  then show ?thesis by metis
  | 
| 
 | 
   751  | 
qed
  | 
| 
 | 
   752  | 
  | 
| 
 | 
   753  | 
lemma real_arch_pow2: "\<exists>n. (x::real) < 2^ n"
  | 
| 
 | 
   754  | 
  using real_arch_pow[of 2 x] by simp
  | 
| 
 | 
   755  | 
  | 
| 
 | 
   756  | 
lemma real_arch_pow_inv: assumes y: "(y::real) > 0" and x1: "x < 1"
  | 
| 
 | 
   757  | 
  shows "\<exists>n. x^n < y"
  | 
| 
 | 
   758  | 
proof-
  | 
| 
 | 
   759  | 
  {assume x0: "x > 0"
 | 
| 
 | 
   760  | 
    from x0 x1 have ix: "1 < 1/x" by (simp add: field_simps)
  | 
| 
 | 
   761  | 
    from real_arch_pow[OF ix, of "1/y"]
  | 
| 
 | 
   762  | 
    obtain n where n: "1/y < (1/x)^n" by blast
  | 
| 
 | 
   763  | 
    then
  | 
| 
 | 
   764  | 
    have ?thesis using y x0 by (auto simp add: field_simps power_divide) }
  | 
| 
 | 
   765  | 
  moreover
  | 
| 
 | 
   766  | 
  {assume "\<not> x > 0" with y x1 have ?thesis apply auto by (rule exI[where x=1], auto)}
 | 
| 
 | 
   767  | 
  ultimately show ?thesis by metis
  | 
| 
 | 
   768  | 
qed
  | 
| 
 | 
   769  | 
  | 
| 
 | 
   770  | 
lemma forall_pos_mono: "(\<And>d e::real. d < e \<Longrightarrow> P d ==> P e) \<Longrightarrow> (\<And>n::nat. n \<noteq> 0 ==> P(inverse(real n))) \<Longrightarrow> (\<And>e. 0 < e ==> P e)"
  | 
| 
 | 
   771  | 
  by (metis real_arch_inv)
  | 
| 
 | 
   772  | 
  | 
| 
 | 
   773  | 
lemma forall_pos_mono_1: "(\<And>d e::real. d < e \<Longrightarrow> P d ==> P e) \<Longrightarrow> (\<And>n. P(inverse(real (Suc n)))) ==> 0 < e ==> P e"
  | 
| 
 | 
   774  | 
  apply (rule forall_pos_mono)
  | 
| 
 | 
   775  | 
  apply auto
  | 
| 
 | 
   776  | 
  apply (atomize)
  | 
| 
 | 
   777  | 
  apply (erule_tac x="n - 1" in allE)
  | 
| 
 | 
   778  | 
  apply auto
  | 
| 
 | 
   779  | 
  done
  | 
| 
 | 
   780  | 
  | 
| 
 | 
   781  | 
lemma real_archimedian_rdiv_eq_0: assumes x0: "x \<ge> 0" and c: "c \<ge> 0" and xc: "\<forall>(m::nat)>0. real m * x \<le> c"
  | 
| 
 | 
   782  | 
  shows "x = 0"
  | 
| 
 | 
   783  | 
proof-
  | 
| 
 | 
   784  | 
  {assume "x \<noteq> 0" with x0 have xp: "x > 0" by arith
 | 
| 
 | 
   785  | 
    from real_arch[OF xp, rule_format, of c] obtain n::nat where n: "c < real n * x"  by blast
  | 
| 
 | 
   786  | 
    with xc[rule_format, of n] have "n = 0" by arith
  | 
| 
 | 
   787  | 
    with n c have False by simp}
  | 
| 
 | 
   788  | 
  then show ?thesis by blast
  | 
| 
 | 
   789  | 
qed
  | 
| 
 | 
   790  | 
  | 
| 
 | 
   791  | 
subsection {* Geometric progression *}
 | 
| 
 | 
   792  | 
  | 
| 
 | 
   793  | 
lemma sum_gp_basic: "((1::'a::{field}) - x) * setsum (\<lambda>i. x^i) {0 .. n} = (1 - x^(Suc n))"
 | 
| 
 | 
   794  | 
  (is "?lhs = ?rhs")
  | 
| 
 | 
   795  | 
proof-
  | 
| 
 | 
   796  | 
  {assume x1: "x = 1" hence ?thesis by simp}
 | 
| 
 | 
   797  | 
  moreover
  | 
| 
 | 
   798  | 
  {assume x1: "x\<noteq>1"
 | 
| 
 | 
   799  | 
    hence x1': "x - 1 \<noteq> 0" "1 - x \<noteq> 0" "x - 1 = - (1 - x)" "- (1 - x) \<noteq> 0" by auto
  | 
| 
 | 
   800  | 
    from geometric_sum[OF x1, of "Suc n", unfolded x1']
  | 
| 
 | 
   801  | 
    have "(- (1 - x)) * setsum (\<lambda>i. x^i) {0 .. n} = - (1 - x^(Suc n))"
 | 
| 
 | 
   802  | 
      unfolding atLeastLessThanSuc_atLeastAtMost
  | 
| 
 | 
   803  | 
      using x1' apply (auto simp only: field_simps)
  | 
| 
 | 
   804  | 
      apply (simp add: field_simps)
  | 
| 
 | 
   805  | 
      done
  | 
| 
 | 
   806  | 
    then have ?thesis by (simp add: field_simps) }
  | 
| 
 | 
   807  | 
  ultimately show ?thesis by metis
  | 
| 
 | 
   808  | 
qed
  | 
| 
 | 
   809  | 
  | 
| 
 | 
   810  | 
lemma sum_gp_multiplied: assumes mn: "m <= n"
  | 
| 
 | 
   811  | 
  shows "((1::'a::{field}) - x) * setsum (op ^ x) {m..n} = x^m - x^ Suc n"
 | 
| 
 | 
   812  | 
  (is "?lhs = ?rhs")
  | 
| 
 | 
   813  | 
proof-
  | 
| 
 | 
   814  | 
  let ?S = "{0..(n - m)}"
 | 
| 
 | 
   815  | 
  from mn have mn': "n - m \<ge> 0" by arith
  | 
| 
 | 
   816  | 
  let ?f = "op + m"
  | 
| 
 | 
   817  | 
  have i: "inj_on ?f ?S" unfolding inj_on_def by auto
  | 
| 
 | 
   818  | 
  have f: "?f ` ?S = {m..n}"
 | 
| 
 | 
   819  | 
    using mn apply (auto simp add: image_iff Bex_def) by arith
  | 
| 
 | 
   820  | 
  have th: "op ^ x o op + m = (\<lambda>i. x^m * x^i)"
  | 
| 
 | 
   821  | 
    by (rule ext, simp add: power_add power_mult)
  | 
| 
 | 
   822  | 
  from setsum_reindex[OF i, of "op ^ x", unfolded f th setsum_right_distrib[symmetric]]
  | 
| 
 | 
   823  | 
  have "?lhs = x^m * ((1 - x) * setsum (op ^ x) {0..n - m})" by simp
 | 
| 
 | 
   824  | 
  then show ?thesis unfolding sum_gp_basic using mn
  | 
| 
 | 
   825  | 
    by (simp add: field_simps power_add[symmetric])
  | 
| 
 | 
   826  | 
qed
  | 
| 
 | 
   827  | 
  | 
| 
 | 
   828  | 
lemma sum_gp: "setsum (op ^ (x::'a::{field})) {m .. n} =
 | 
| 
 | 
   829  | 
   (if n < m then 0 else if x = 1 then of_nat ((n + 1) - m)
  | 
| 
 | 
   830  | 
                    else (x^ m - x^ (Suc n)) / (1 - x))"
  | 
| 
 | 
   831  | 
proof-
  | 
| 
 | 
   832  | 
  {assume nm: "n < m" hence ?thesis by simp}
 | 
| 
 | 
   833  | 
  moreover
  | 
| 
 | 
   834  | 
  {assume "\<not> n < m" hence nm: "m \<le> n" by arith
 | 
| 
 | 
   835  | 
    {assume x: "x = 1"  hence ?thesis by simp}
 | 
| 
 | 
   836  | 
    moreover
  | 
| 
 | 
   837  | 
    {assume x: "x \<noteq> 1" hence nz: "1 - x \<noteq> 0" by simp
 | 
| 
 | 
   838  | 
      from sum_gp_multiplied[OF nm, of x] nz have ?thesis by (simp add: field_simps)}
  | 
| 
 | 
   839  | 
    ultimately have ?thesis by metis
  | 
| 
 | 
   840  | 
  }
  | 
| 
 | 
   841  | 
  ultimately show ?thesis by metis
  | 
| 
 | 
   842  | 
qed
  | 
| 
 | 
   843  | 
  | 
| 
 | 
   844  | 
lemma sum_gp_offset: "setsum (op ^ (x::'a::{field})) {m .. m+n} =
 | 
| 
 | 
   845  | 
  (if x = 1 then of_nat n + 1 else x^m * (1 - x^Suc n) / (1 - x))"
  | 
| 
 | 
   846  | 
  unfolding sum_gp[of x m "m + n"] power_Suc
  | 
| 
 | 
   847  | 
  by (simp add: field_simps power_add)
  | 
| 
 | 
   848  | 
  | 
| 
 | 
   849  | 
  | 
| 
 | 
   850  | 
subsection{* A bit of linear algebra. *}
 | 
| 
 | 
   851  | 
  | 
| 
 | 
   852  | 
definition (in real_vector)
  | 
| 
 | 
   853  | 
  subspace :: "'a set \<Rightarrow> bool" where
  | 
| 
 | 
   854  | 
  "subspace S \<longleftrightarrow> 0 \<in> S \<and> (\<forall>x\<in> S. \<forall>y \<in>S. x + y \<in> S) \<and> (\<forall>c. \<forall>x \<in>S. c *\<^sub>R x \<in>S )"
  | 
| 
 | 
   855  | 
  | 
| 
 | 
   856  | 
definition (in real_vector) "span S = (subspace hull S)"
  | 
| 
 | 
   857  | 
definition (in real_vector) "dependent S \<longleftrightarrow> (\<exists>a \<in> S. a \<in> span(S - {a}))"
 | 
| 
 | 
   858  | 
abbreviation (in real_vector) "independent s == ~(dependent s)"
  | 
| 
 | 
   859  | 
  | 
| 
 | 
   860  | 
text {* Closure properties of subspaces. *}
 | 
| 
 | 
   861  | 
  | 
| 
 | 
   862  | 
lemma subspace_UNIV[simp]: "subspace(UNIV)" by (simp add: subspace_def)
  | 
| 
 | 
   863  | 
  | 
| 
 | 
   864  | 
lemma (in real_vector) subspace_0: "subspace S ==> 0 \<in> S" by (metis subspace_def)
  | 
| 
 | 
   865  | 
  | 
| 
 | 
   866  | 
lemma (in real_vector) subspace_add: "subspace S \<Longrightarrow> x \<in> S \<Longrightarrow> y \<in> S ==> x + y \<in> S"
  | 
| 
 | 
   867  | 
  by (metis subspace_def)
  | 
| 
 | 
   868  | 
  | 
| 
 | 
   869  | 
lemma (in real_vector) subspace_mul: "subspace S \<Longrightarrow> x \<in> S \<Longrightarrow> c *\<^sub>R x \<in> S"
  | 
| 
 | 
   870  | 
  by (metis subspace_def)
  | 
| 
 | 
   871  | 
  | 
| 
 | 
   872  | 
lemma subspace_neg: "subspace S \<Longrightarrow> x \<in> S \<Longrightarrow> - x \<in> S"
  | 
| 
 | 
   873  | 
  by (metis scaleR_minus1_left subspace_mul)
  | 
| 
 | 
   874  | 
  | 
| 
 | 
   875  | 
lemma subspace_sub: "subspace S \<Longrightarrow> x \<in> S \<Longrightarrow> y \<in> S \<Longrightarrow> x - y \<in> S"
  | 
| 
 | 
   876  | 
  by (metis diff_minus subspace_add subspace_neg)
  | 
| 
 | 
   877  | 
  | 
| 
 | 
   878  | 
lemma (in real_vector) subspace_setsum:
  | 
| 
 | 
   879  | 
  assumes sA: "subspace A" and fB: "finite B"
  | 
| 
 | 
   880  | 
  and f: "\<forall>x\<in> B. f x \<in> A"
  | 
| 
 | 
   881  | 
  shows "setsum f B \<in> A"
  | 
| 
 | 
   882  | 
  using  fB f sA
  | 
| 
 | 
   883  | 
  apply(induct rule: finite_induct[OF fB])
  | 
| 
 | 
   884  | 
  by (simp add: subspace_def sA, auto simp add: sA subspace_add)
  | 
| 
 | 
   885  | 
  | 
| 
 | 
   886  | 
lemma subspace_linear_image:
  | 
| 
 | 
   887  | 
  assumes lf: "linear f" and sS: "subspace S"
  | 
| 
 | 
   888  | 
  shows "subspace(f ` S)"
  | 
| 
 | 
   889  | 
  using lf sS linear_0[OF lf]
  | 
| 
 | 
   890  | 
  unfolding linear_def subspace_def
  | 
| 
 | 
   891  | 
  apply (auto simp add: image_iff)
  | 
| 
 | 
   892  | 
  apply (rule_tac x="x + y" in bexI, auto)
  | 
| 
 | 
   893  | 
  apply (rule_tac x="c *\<^sub>R x" in bexI, auto)
  | 
| 
 | 
   894  | 
  done
  | 
| 
 | 
   895  | 
  | 
| 
 | 
   896  | 
lemma subspace_linear_preimage: "linear f ==> subspace S ==> subspace {x. f x \<in> S}"
 | 
| 
 | 
   897  | 
  by (auto simp add: subspace_def linear_def linear_0[of f])
  | 
| 
 | 
   898  | 
  | 
| 
 | 
   899  | 
lemma subspace_trivial: "subspace {0}"
 | 
| 
 | 
   900  | 
  by (simp add: subspace_def)
  | 
| 
 | 
   901  | 
  | 
| 
 | 
   902  | 
lemma (in real_vector) subspace_inter: "subspace A \<Longrightarrow> subspace B ==> subspace (A \<inter> B)"
  | 
| 
 | 
   903  | 
  by (simp add: subspace_def)
  | 
| 
 | 
   904  | 
  | 
| 
 | 
   905  | 
lemma (in real_vector) span_mono: "A \<subseteq> B ==> span A \<subseteq> span B"
  | 
| 
 | 
   906  | 
  by (metis span_def hull_mono)
  | 
| 
 | 
   907  | 
  | 
| 
 | 
   908  | 
lemma (in real_vector) subspace_span: "subspace(span S)"
  | 
| 
 | 
   909  | 
  unfolding span_def
  | 
| 
 | 
   910  | 
  apply (rule hull_in[unfolded mem_def])
  | 
| 
 | 
   911  | 
  apply (simp only: subspace_def Inter_iff Int_iff subset_eq)
  | 
| 
 | 
   912  | 
  apply auto
  | 
| 
 | 
   913  | 
  apply (erule_tac x="X" in ballE)
  | 
| 
 | 
   914  | 
  apply (simp add: mem_def)
  | 
| 
 | 
   915  | 
  apply blast
  | 
| 
 | 
   916  | 
  apply (erule_tac x="X" in ballE)
  | 
| 
 | 
   917  | 
  apply (erule_tac x="X" in ballE)
  | 
| 
 | 
   918  | 
  apply (erule_tac x="X" in ballE)
  | 
| 
 | 
   919  | 
  apply (clarsimp simp add: mem_def)
  | 
| 
 | 
   920  | 
  apply simp
  | 
| 
 | 
   921  | 
  apply simp
  | 
| 
 | 
   922  | 
  apply simp
  | 
| 
 | 
   923  | 
  apply (erule_tac x="X" in ballE)
  | 
| 
 | 
   924  | 
  apply (erule_tac x="X" in ballE)
  | 
| 
 | 
   925  | 
  apply (simp add: mem_def)
  | 
| 
 | 
   926  | 
  apply simp
  | 
| 
 | 
   927  | 
  apply simp
  | 
| 
 | 
   928  | 
  done
  | 
| 
 | 
   929  | 
  | 
| 
 | 
   930  | 
lemma (in real_vector) span_clauses:
  | 
| 
 | 
   931  | 
  "a \<in> S ==> a \<in> span S"
  | 
| 
 | 
   932  | 
  "0 \<in> span S"
  | 
| 
 | 
   933  | 
  "x\<in> span S \<Longrightarrow> y \<in> span S ==> x + y \<in> span S"
  | 
| 
 | 
   934  | 
  "x \<in> span S \<Longrightarrow> c *\<^sub>R x \<in> span S"
  | 
| 
 | 
   935  | 
  by (metis span_def hull_subset subset_eq)
  | 
| 
 | 
   936  | 
     (metis subspace_span subspace_def)+
  | 
| 
 | 
   937  | 
  | 
| 
 | 
   938  | 
lemma (in real_vector) span_induct: assumes SP: "\<And>x. x \<in> S ==> P x"
  | 
| 
 | 
   939  | 
  and P: "subspace P" and x: "x \<in> span S" shows "P x"
  | 
| 
 | 
   940  | 
proof-
  | 
| 
 | 
   941  | 
  from SP have SP': "S \<subseteq> P" by (simp add: mem_def subset_eq)
  | 
| 
 | 
   942  | 
  from P have P': "P \<in> subspace" by (simp add: mem_def)
  | 
| 
 | 
   943  | 
  from x hull_minimal[OF SP' P', unfolded span_def[symmetric]]
  | 
| 
 | 
   944  | 
  show "P x" by (metis mem_def subset_eq)
  | 
| 
 | 
   945  | 
qed
  | 
| 
 | 
   946  | 
  | 
| 
 | 
   947  | 
lemma span_empty[simp]: "span {} = {0}"
 | 
| 
 | 
   948  | 
  apply (simp add: span_def)
  | 
| 
 | 
   949  | 
  apply (rule hull_unique)
  | 
| 
 | 
   950  | 
  apply (auto simp add: mem_def subspace_def)
  | 
| 
 | 
   951  | 
  unfolding mem_def[of "0::'a", symmetric]
  | 
| 
 | 
   952  | 
  apply simp
  | 
| 
 | 
   953  | 
  done
  | 
| 
 | 
   954  | 
  | 
| 
 | 
   955  | 
lemma (in real_vector) independent_empty[intro]: "independent {}"
 | 
| 
 | 
   956  | 
  by (simp add: dependent_def)
  | 
| 
 | 
   957  | 
  | 
| 
 | 
   958  | 
lemma dependent_single[simp]:
  | 
| 
 | 
   959  | 
  "dependent {x} \<longleftrightarrow> x = 0"
 | 
| 
 | 
   960  | 
  unfolding dependent_def by auto
  | 
| 
 | 
   961  | 
  | 
| 
 | 
   962  | 
lemma (in real_vector) independent_mono: "independent A \<Longrightarrow> B \<subseteq> A ==> independent B"
  | 
| 
 | 
   963  | 
  apply (clarsimp simp add: dependent_def span_mono)
  | 
| 
 | 
   964  | 
  apply (subgoal_tac "span (B - {a}) \<le> span (A - {a})")
 | 
| 
 | 
   965  | 
  apply force
  | 
| 
 | 
   966  | 
  apply (rule span_mono)
  | 
| 
 | 
   967  | 
  apply auto
  | 
| 
 | 
   968  | 
  done
  | 
| 
 | 
   969  | 
  | 
| 
 | 
   970  | 
lemma (in real_vector) span_subspace: "A \<subseteq> B \<Longrightarrow> B \<le> span A \<Longrightarrow>  subspace B \<Longrightarrow> span A = B"
  | 
| 
 | 
   971  | 
  by (metis order_antisym span_def hull_minimal mem_def)
  | 
| 
 | 
   972  | 
  | 
| 
 | 
   973  | 
lemma (in real_vector) span_induct': assumes SP: "\<forall>x \<in> S. P x"
  | 
| 
 | 
   974  | 
  and P: "subspace P" shows "\<forall>x \<in> span S. P x"
  | 
| 
 | 
   975  | 
  using span_induct SP P by blast
  | 
| 
 | 
   976  | 
  | 
| 
 | 
   977  | 
inductive (in real_vector) span_induct_alt_help for S:: "'a \<Rightarrow> bool"
  | 
| 
 | 
   978  | 
  where
  | 
| 
 | 
   979  | 
  span_induct_alt_help_0: "span_induct_alt_help S 0"
  | 
| 
 | 
   980  | 
  | span_induct_alt_help_S: "x \<in> S \<Longrightarrow> span_induct_alt_help S z \<Longrightarrow> span_induct_alt_help S (c *\<^sub>R x + z)"
  | 
| 
 | 
   981  | 
  | 
| 
 | 
   982  | 
lemma span_induct_alt':
  | 
| 
 | 
   983  | 
  assumes h0: "h 0" and hS: "\<And>c x y. x \<in> S \<Longrightarrow> h y \<Longrightarrow> h (c *\<^sub>R x + y)" shows "\<forall>x \<in> span S. h x"
  | 
| 
 | 
   984  | 
proof-
  | 
| 
 | 
   985  | 
  {fix x:: "'a" assume x: "span_induct_alt_help S x"
 | 
| 
 | 
   986  | 
    have "h x"
  | 
| 
 | 
   987  | 
      apply (rule span_induct_alt_help.induct[OF x])
  | 
| 
 | 
   988  | 
      apply (rule h0)
  | 
| 
 | 
   989  | 
      apply (rule hS, assumption, assumption)
  | 
| 
 | 
   990  | 
      done}
  | 
| 
 | 
   991  | 
  note th0 = this
  | 
| 
 | 
   992  | 
  {fix x assume x: "x \<in> span S"
 | 
| 
 | 
   993  | 
  | 
| 
 | 
   994  | 
    have "span_induct_alt_help S x"
  | 
| 
 | 
   995  | 
      proof(rule span_induct[where x=x and S=S])
  | 
| 
 | 
   996  | 
        show "x \<in> span S" using x .
  | 
| 
 | 
   997  | 
      next
  | 
| 
 | 
   998  | 
        fix x assume xS : "x \<in> S"
  | 
| 
 | 
   999  | 
          from span_induct_alt_help_S[OF xS span_induct_alt_help_0, of 1]
  | 
| 
 | 
  1000  | 
          show "span_induct_alt_help S x" by simp
  | 
| 
 | 
  1001  | 
        next
  | 
| 
 | 
  1002  | 
        have "span_induct_alt_help S 0" by (rule span_induct_alt_help_0)
  | 
| 
 | 
  1003  | 
        moreover
  | 
| 
 | 
  1004  | 
        {fix x y assume h: "span_induct_alt_help S x" "span_induct_alt_help S y"
 | 
| 
 | 
  1005  | 
          from h
  | 
| 
 | 
  1006  | 
          have "span_induct_alt_help S (x + y)"
  | 
| 
 | 
  1007  | 
            apply (induct rule: span_induct_alt_help.induct)
  | 
| 
 | 
  1008  | 
            apply simp
  | 
| 
 | 
  1009  | 
            unfolding add_assoc
  | 
| 
 | 
  1010  | 
            apply (rule span_induct_alt_help_S)
  | 
| 
 | 
  1011  | 
            apply assumption
  | 
| 
 | 
  1012  | 
            apply simp
  | 
| 
 | 
  1013  | 
            done}
  | 
| 
 | 
  1014  | 
        moreover
  | 
| 
 | 
  1015  | 
        {fix c x assume xt: "span_induct_alt_help S x"
 | 
| 
 | 
  1016  | 
          then have "span_induct_alt_help S (c *\<^sub>R x)"
  | 
| 
 | 
  1017  | 
            apply (induct rule: span_induct_alt_help.induct)
  | 
| 
 | 
  1018  | 
            apply (simp add: span_induct_alt_help_0)
  | 
| 
 | 
  1019  | 
            apply (simp add: scaleR_right_distrib)
  | 
| 
 | 
  1020  | 
            apply (rule span_induct_alt_help_S)
  | 
| 
 | 
  1021  | 
            apply assumption
  | 
| 
 | 
  1022  | 
            apply simp
  | 
| 
 | 
  1023  | 
            done
  | 
| 
 | 
  1024  | 
        }
  | 
| 
 | 
  1025  | 
        ultimately show "subspace (span_induct_alt_help S)"
  | 
| 
 | 
  1026  | 
          unfolding subspace_def mem_def Ball_def by blast
  | 
| 
 | 
  1027  | 
      qed}
  | 
| 
 | 
  1028  | 
  with th0 show ?thesis by blast
  | 
| 
 | 
  1029  | 
qed
  | 
| 
 | 
  1030  | 
  | 
| 
 | 
  1031  | 
lemma span_induct_alt:
  | 
| 
 | 
  1032  | 
  assumes h0: "h 0" and hS: "\<And>c x y. x \<in> S \<Longrightarrow> h y \<Longrightarrow> h (c *\<^sub>R x + y)" and x: "x \<in> span S"
  | 
| 
 | 
  1033  | 
  shows "h x"
  | 
| 
 | 
  1034  | 
using span_induct_alt'[of h S] h0 hS x by blast
  | 
| 
 | 
  1035  | 
  | 
| 
 | 
  1036  | 
text {* Individual closure properties. *}
 | 
| 
 | 
  1037  | 
  | 
| 
 | 
  1038  | 
lemma span_span: "span (span A) = span A"
  | 
| 
 | 
  1039  | 
  unfolding span_def hull_hull ..
  | 
| 
 | 
  1040  | 
  | 
| 
 | 
  1041  | 
lemma (in real_vector) span_superset: "x \<in> S ==> x \<in> span S" by (metis span_clauses(1))
  | 
| 
 | 
  1042  | 
  | 
| 
 | 
  1043  | 
lemma (in real_vector) span_0: "0 \<in> span S" by (metis subspace_span subspace_0)
  | 
| 
 | 
  1044  | 
  | 
| 
 | 
  1045  | 
lemma span_inc: "S \<subseteq> span S"
  | 
| 
 | 
  1046  | 
  by (metis subset_eq span_superset)
  | 
| 
 | 
  1047  | 
  | 
| 
 | 
  1048  | 
lemma (in real_vector) dependent_0: assumes "0\<in>A" shows "dependent A"
  | 
| 
 | 
  1049  | 
  unfolding dependent_def apply(rule_tac x=0 in bexI)
  | 
| 
 | 
  1050  | 
  using assms span_0 by auto
  | 
| 
 | 
  1051  | 
  | 
| 
 | 
  1052  | 
lemma (in real_vector) span_add: "x \<in> span S \<Longrightarrow> y \<in> span S ==> x + y \<in> span S"
  | 
| 
 | 
  1053  | 
  by (metis subspace_add subspace_span)
  | 
| 
 | 
  1054  | 
  | 
| 
 | 
  1055  | 
lemma (in real_vector) span_mul: "x \<in> span S ==> (c *\<^sub>R x) \<in> span S"
  | 
| 
 | 
  1056  | 
  by (metis subspace_span subspace_mul)
  | 
| 
 | 
  1057  | 
  | 
| 
 | 
  1058  | 
lemma span_neg: "x \<in> span S ==> - x \<in> span S"
  | 
| 
 | 
  1059  | 
  by (metis subspace_neg subspace_span)
  | 
| 
 | 
  1060  | 
  | 
| 
 | 
  1061  | 
lemma span_sub: "x \<in> span S \<Longrightarrow> y \<in> span S ==> x - y \<in> span S"
  | 
| 
 | 
  1062  | 
  by (metis subspace_span subspace_sub)
  | 
| 
 | 
  1063  | 
  | 
| 
 | 
  1064  | 
lemma (in real_vector) span_setsum: "finite A \<Longrightarrow> \<forall>x \<in> A. f x \<in> span S ==> setsum f A \<in> span S"
  | 
| 
 | 
  1065  | 
  by (rule subspace_setsum, rule subspace_span)
  | 
| 
 | 
  1066  | 
  | 
| 
 | 
  1067  | 
lemma span_add_eq: "x \<in> span S \<Longrightarrow> x + y \<in> span S \<longleftrightarrow> y \<in> span S"
  | 
| 
 | 
  1068  | 
  apply (auto simp only: span_add span_sub)
  | 
| 
 | 
  1069  | 
  apply (subgoal_tac "(x + y) - x \<in> span S", simp)
  | 
| 
 | 
  1070  | 
  by (simp only: span_add span_sub)
  | 
| 
 | 
  1071  | 
  | 
| 
 | 
  1072  | 
text {* Mapping under linear image. *}
 | 
| 
 | 
  1073  | 
  | 
| 
 | 
  1074  | 
lemma span_linear_image: assumes lf: "linear f"
  | 
| 
 | 
  1075  | 
  shows "span (f ` S) = f ` (span S)"
  | 
| 
 | 
  1076  | 
proof-
  | 
| 
 | 
  1077  | 
  {fix x
 | 
| 
 | 
  1078  | 
    assume x: "x \<in> span (f ` S)"
  | 
| 
 | 
  1079  | 
    have "x \<in> f ` span S"
  | 
| 
 | 
  1080  | 
      apply (rule span_induct[where x=x and S = "f ` S"])
  | 
| 
 | 
  1081  | 
      apply (clarsimp simp add: image_iff)
  | 
| 
 | 
  1082  | 
      apply (frule span_superset)
  | 
| 
 | 
  1083  | 
      apply blast
  | 
| 
 | 
  1084  | 
      apply (simp only: mem_def)
  | 
| 
 | 
  1085  | 
      apply (rule subspace_linear_image[OF lf])
  | 
| 
 | 
  1086  | 
      apply (rule subspace_span)
  | 
| 
 | 
  1087  | 
      apply (rule x)
  | 
| 
 | 
  1088  | 
      done}
  | 
| 
 | 
  1089  | 
  moreover
  | 
| 
 | 
  1090  | 
  {fix x assume x: "x \<in> span S"
 | 
| 
 | 
  1091  | 
    have th0:"(\<lambda>a. f a \<in> span (f ` S)) = {x. f x \<in> span (f ` S)}" apply (rule set_eqI)
 | 
| 
 | 
  1092  | 
      unfolding mem_def Collect_def ..
  | 
| 
 | 
  1093  | 
    have "f x \<in> span (f ` S)"
  | 
| 
 | 
  1094  | 
      apply (rule span_induct[where S=S])
  | 
| 
 | 
  1095  | 
      apply (rule span_superset)
  | 
| 
 | 
  1096  | 
      apply simp
  | 
| 
 | 
  1097  | 
      apply (subst th0)
  | 
| 
 | 
  1098  | 
      apply (rule subspace_linear_preimage[OF lf subspace_span, of "f ` S"])
  | 
| 
 | 
  1099  | 
      apply (rule x)
  | 
| 
 | 
  1100  | 
      done}
  | 
| 
 | 
  1101  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  1102  | 
qed
  | 
| 
 | 
  1103  | 
  | 
| 
 | 
  1104  | 
text {* The key breakdown property. *}
 | 
| 
 | 
  1105  | 
  | 
| 
 | 
  1106  | 
lemma span_breakdown:
  | 
| 
 | 
  1107  | 
  assumes bS: "b \<in> S" and aS: "a \<in> span S"
  | 
| 
 | 
  1108  | 
  shows "\<exists>k. a - k *\<^sub>R b \<in> span (S - {b})" (is "?P a")
 | 
| 
 | 
  1109  | 
proof-
  | 
| 
 | 
  1110  | 
  {fix x assume xS: "x \<in> S"
 | 
| 
 | 
  1111  | 
    {assume ab: "x = b"
 | 
| 
 | 
  1112  | 
      then have "?P x"
  | 
| 
 | 
  1113  | 
        apply simp
  | 
| 
 | 
  1114  | 
        apply (rule exI[where x="1"], simp)
  | 
| 
 | 
  1115  | 
        by (rule span_0)}
  | 
| 
 | 
  1116  | 
    moreover
  | 
| 
 | 
  1117  | 
    {assume ab: "x \<noteq> b"
 | 
| 
 | 
  1118  | 
      then have "?P x"  using xS
  | 
| 
 | 
  1119  | 
        apply -
  | 
| 
 | 
  1120  | 
        apply (rule exI[where x=0])
  | 
| 
 | 
  1121  | 
        apply (rule span_superset)
  | 
| 
 | 
  1122  | 
        by simp}
  | 
| 
 | 
  1123  | 
    ultimately have "?P x" by blast}
  | 
| 
 | 
  1124  | 
  moreover have "subspace ?P"
  | 
| 
 | 
  1125  | 
    unfolding subspace_def
  | 
| 
 | 
  1126  | 
    apply auto
  | 
| 
 | 
  1127  | 
    apply (simp add: mem_def)
  | 
| 
 | 
  1128  | 
    apply (rule exI[where x=0])
  | 
| 
 | 
  1129  | 
    using span_0[of "S - {b}"]
 | 
| 
 | 
  1130  | 
    apply (simp add: mem_def)
  | 
| 
 | 
  1131  | 
    apply (clarsimp simp add: mem_def)
  | 
| 
 | 
  1132  | 
    apply (rule_tac x="k + ka" in exI)
  | 
| 
 | 
  1133  | 
    apply (subgoal_tac "x + y - (k + ka) *\<^sub>R b = (x - k*\<^sub>R b) + (y - ka *\<^sub>R b)")
  | 
| 
 | 
  1134  | 
    apply (simp only: )
  | 
| 
 | 
  1135  | 
    apply (rule span_add[unfolded mem_def])
  | 
| 
 | 
  1136  | 
    apply assumption+
  | 
| 
 | 
  1137  | 
    apply (simp add: algebra_simps)
  | 
| 
 | 
  1138  | 
    apply (clarsimp simp add: mem_def)
  | 
| 
 | 
  1139  | 
    apply (rule_tac x= "c*k" in exI)
  | 
| 
 | 
  1140  | 
    apply (subgoal_tac "c *\<^sub>R x - (c * k) *\<^sub>R b = c*\<^sub>R (x - k*\<^sub>R b)")
  | 
| 
 | 
  1141  | 
    apply (simp only: )
  | 
| 
 | 
  1142  | 
    apply (rule span_mul[unfolded mem_def])
  | 
| 
 | 
  1143  | 
    apply assumption
  | 
| 
 | 
  1144  | 
    by (simp add: algebra_simps)
  | 
| 
 | 
  1145  | 
  ultimately show "?P a" using aS span_induct[where S=S and P= "?P"] by metis
  | 
| 
 | 
  1146  | 
qed
  | 
| 
 | 
  1147  | 
  | 
| 
 | 
  1148  | 
lemma span_breakdown_eq:
  | 
| 
 | 
  1149  | 
  "x \<in> span (insert a S) \<longleftrightarrow> (\<exists>k. (x - k *\<^sub>R a) \<in> span S)" (is "?lhs \<longleftrightarrow> ?rhs")
  | 
| 
 | 
  1150  | 
proof-
  | 
| 
 | 
  1151  | 
  {assume x: "x \<in> span (insert a S)"
 | 
| 
 | 
  1152  | 
    from x span_breakdown[of "a" "insert a S" "x"]
  | 
| 
 | 
  1153  | 
    have ?rhs apply clarsimp
  | 
| 
 | 
  1154  | 
      apply (rule_tac x= "k" in exI)
  | 
| 
 | 
  1155  | 
      apply (rule set_rev_mp[of _ "span (S - {a})" _])
 | 
| 
 | 
  1156  | 
      apply assumption
  | 
| 
 | 
  1157  | 
      apply (rule span_mono)
  | 
| 
 | 
  1158  | 
      apply blast
  | 
| 
 | 
  1159  | 
      done}
  | 
| 
 | 
  1160  | 
  moreover
  | 
| 
 | 
  1161  | 
  { fix k assume k: "x - k *\<^sub>R a \<in> span S"
 | 
| 
 | 
  1162  | 
    have eq: "x = (x - k *\<^sub>R a) + k *\<^sub>R a" by simp
  | 
| 
 | 
  1163  | 
    have "(x - k *\<^sub>R a) + k *\<^sub>R a \<in> span (insert a S)"
  | 
| 
 | 
  1164  | 
      apply (rule span_add)
  | 
| 
 | 
  1165  | 
      apply (rule set_rev_mp[of _ "span S" _])
  | 
| 
 | 
  1166  | 
      apply (rule k)
  | 
| 
 | 
  1167  | 
      apply (rule span_mono)
  | 
| 
 | 
  1168  | 
      apply blast
  | 
| 
 | 
  1169  | 
      apply (rule span_mul)
  | 
| 
 | 
  1170  | 
      apply (rule span_superset)
  | 
| 
 | 
  1171  | 
      apply blast
  | 
| 
 | 
  1172  | 
      done
  | 
| 
 | 
  1173  | 
    then have ?lhs using eq by metis}
  | 
| 
 | 
  1174  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  1175  | 
qed
  | 
| 
 | 
  1176  | 
  | 
| 
 | 
  1177  | 
text {* Hence some "reversal" results. *}
 | 
| 
 | 
  1178  | 
  | 
| 
 | 
  1179  | 
lemma in_span_insert:
  | 
| 
 | 
  1180  | 
  assumes a: "a \<in> span (insert b S)" and na: "a \<notin> span S"
  | 
| 
 | 
  1181  | 
  shows "b \<in> span (insert a S)"
  | 
| 
 | 
  1182  | 
proof-
  | 
| 
 | 
  1183  | 
  from span_breakdown[of b "insert b S" a, OF insertI1 a]
  | 
| 
 | 
  1184  | 
  obtain k where k: "a - k*\<^sub>R b \<in> span (S - {b})" by auto
 | 
| 
 | 
  1185  | 
  {assume k0: "k = 0"
 | 
| 
 | 
  1186  | 
    with k have "a \<in> span S"
  | 
| 
 | 
  1187  | 
      apply (simp)
  | 
| 
 | 
  1188  | 
      apply (rule set_rev_mp)
  | 
| 
 | 
  1189  | 
      apply assumption
  | 
| 
 | 
  1190  | 
      apply (rule span_mono)
  | 
| 
 | 
  1191  | 
      apply blast
  | 
| 
 | 
  1192  | 
      done
  | 
| 
 | 
  1193  | 
    with na  have ?thesis by blast}
  | 
| 
 | 
  1194  | 
  moreover
  | 
| 
 | 
  1195  | 
  {assume k0: "k \<noteq> 0"
 | 
| 
 | 
  1196  | 
    have eq: "b = (1/k) *\<^sub>R a - ((1/k) *\<^sub>R a - b)" by simp
  | 
| 
 | 
  1197  | 
    from k0 have eq': "(1/k) *\<^sub>R (a - k*\<^sub>R b) = (1/k) *\<^sub>R a - b"
  | 
| 
 | 
  1198  | 
      by (simp add: algebra_simps)
  | 
| 
 | 
  1199  | 
    from k have "(1/k) *\<^sub>R (a - k*\<^sub>R b) \<in> span (S - {b})"
 | 
| 
 | 
  1200  | 
      by (rule span_mul)
  | 
| 
 | 
  1201  | 
    hence th: "(1/k) *\<^sub>R a - b \<in> span (S - {b})"
 | 
| 
 | 
  1202  | 
      unfolding eq' .
  | 
| 
 | 
  1203  | 
  | 
| 
 | 
  1204  | 
    from k
  | 
| 
 | 
  1205  | 
    have ?thesis
  | 
| 
 | 
  1206  | 
      apply (subst eq)
  | 
| 
 | 
  1207  | 
      apply (rule span_sub)
  | 
| 
 | 
  1208  | 
      apply (rule span_mul)
  | 
| 
 | 
  1209  | 
      apply (rule span_superset)
  | 
| 
 | 
  1210  | 
      apply blast
  | 
| 
 | 
  1211  | 
      apply (rule set_rev_mp)
  | 
| 
 | 
  1212  | 
      apply (rule th)
  | 
| 
 | 
  1213  | 
      apply (rule span_mono)
  | 
| 
 | 
  1214  | 
      using na by blast}
  | 
| 
 | 
  1215  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  1216  | 
qed
  | 
| 
 | 
  1217  | 
  | 
| 
 | 
  1218  | 
lemma in_span_delete:
  | 
| 
 | 
  1219  | 
  assumes a: "a \<in> span S"
  | 
| 
 | 
  1220  | 
  and na: "a \<notin> span (S-{b})"
 | 
| 
 | 
  1221  | 
  shows "b \<in> span (insert a (S - {b}))"
 | 
| 
 | 
  1222  | 
  apply (rule in_span_insert)
  | 
| 
 | 
  1223  | 
  apply (rule set_rev_mp)
  | 
| 
 | 
  1224  | 
  apply (rule a)
  | 
| 
 | 
  1225  | 
  apply (rule span_mono)
  | 
| 
 | 
  1226  | 
  apply blast
  | 
| 
 | 
  1227  | 
  apply (rule na)
  | 
| 
 | 
  1228  | 
  done
  | 
| 
 | 
  1229  | 
  | 
| 
 | 
  1230  | 
text {* Transitivity property. *}
 | 
| 
 | 
  1231  | 
  | 
| 
 | 
  1232  | 
lemma span_trans:
  | 
| 
 | 
  1233  | 
  assumes x: "x \<in> span S" and y: "y \<in> span (insert x S)"
  | 
| 
 | 
  1234  | 
  shows "y \<in> span S"
  | 
| 
 | 
  1235  | 
proof-
  | 
| 
 | 
  1236  | 
  from span_breakdown[of x "insert x S" y, OF insertI1 y]
  | 
| 
 | 
  1237  | 
  obtain k where k: "y -k*\<^sub>R x \<in> span (S - {x})" by auto
 | 
| 
 | 
  1238  | 
  have eq: "y = (y - k *\<^sub>R x) + k *\<^sub>R x" by simp
  | 
| 
 | 
  1239  | 
  show ?thesis
  | 
| 
 | 
  1240  | 
    apply (subst eq)
  | 
| 
 | 
  1241  | 
    apply (rule span_add)
  | 
| 
 | 
  1242  | 
    apply (rule set_rev_mp)
  | 
| 
 | 
  1243  | 
    apply (rule k)
  | 
| 
 | 
  1244  | 
    apply (rule span_mono)
  | 
| 
 | 
  1245  | 
    apply blast
  | 
| 
 | 
  1246  | 
    apply (rule span_mul)
  | 
| 
 | 
  1247  | 
    by (rule x)
  | 
| 
 | 
  1248  | 
qed
  | 
| 
 | 
  1249  | 
  | 
| 
 | 
  1250  | 
lemma span_insert_0[simp]: "span (insert 0 S) = span S"
  | 
| 
 | 
  1251  | 
  using span_mono[of S "insert 0 S"] by (auto intro: span_trans span_0)
  | 
| 
 | 
  1252  | 
  | 
| 
 | 
  1253  | 
text {* An explicit expansion is sometimes needed. *}
 | 
| 
 | 
  1254  | 
  | 
| 
 | 
  1255  | 
lemma span_explicit:
  | 
| 
 | 
  1256  | 
  "span P = {y. \<exists>S u. finite S \<and> S \<subseteq> P \<and> setsum (\<lambda>v. u v *\<^sub>R v) S = y}"
 | 
| 
 | 
  1257  | 
  (is "_ = ?E" is "_ = {y. ?h y}" is "_ = {y. \<exists>S u. ?Q S u y}")
 | 
| 
 | 
  1258  | 
proof-
  | 
| 
 | 
  1259  | 
  {fix x assume x: "x \<in> ?E"
 | 
| 
 | 
  1260  | 
    then obtain S u where fS: "finite S" and SP: "S\<subseteq>P" and u: "setsum (\<lambda>v. u v *\<^sub>R v) S = x"
  | 
| 
 | 
  1261  | 
      by blast
  | 
| 
 | 
  1262  | 
    have "x \<in> span P"
  | 
| 
 | 
  1263  | 
      unfolding u[symmetric]
  | 
| 
 | 
  1264  | 
      apply (rule span_setsum[OF fS])
  | 
| 
 | 
  1265  | 
      using span_mono[OF SP]
  | 
| 
 | 
  1266  | 
      by (auto intro: span_superset span_mul)}
  | 
| 
 | 
  1267  | 
  moreover
  | 
| 
 | 
  1268  | 
  have "\<forall>x \<in> span P. x \<in> ?E"
  | 
| 
 | 
  1269  | 
    unfolding mem_def Collect_def
  | 
| 
 | 
  1270  | 
  proof(rule span_induct_alt')
  | 
| 
 | 
  1271  | 
    show "?h 0"
  | 
| 
 | 
  1272  | 
      apply (rule exI[where x="{}"]) by simp
 | 
| 
 | 
  1273  | 
  next
  | 
| 
 | 
  1274  | 
    fix c x y
  | 
| 
 | 
  1275  | 
    assume x: "x \<in> P" and hy: "?h y"
  | 
| 
 | 
  1276  | 
    from hy obtain S u where fS: "finite S" and SP: "S\<subseteq>P"
  | 
| 
 | 
  1277  | 
      and u: "setsum (\<lambda>v. u v *\<^sub>R v) S = y" by blast
  | 
| 
 | 
  1278  | 
    let ?S = "insert x S"
  | 
| 
 | 
  1279  | 
    let ?u = "\<lambda>y. if y = x then (if x \<in> S then u y + c else c)
  | 
| 
 | 
  1280  | 
                  else u y"
  | 
| 
 | 
  1281  | 
    from fS SP x have th0: "finite (insert x S)" "insert x S \<subseteq> P" by blast+
  | 
| 
 | 
  1282  | 
    {assume xS: "x \<in> S"
 | 
| 
 | 
  1283  | 
      have S1: "S = (S - {x}) \<union> {x}"
 | 
| 
 | 
  1284  | 
        and Sss:"finite (S - {x})" "finite {x}" "(S -{x}) \<inter> {x} = {}" using xS fS by auto
 | 
| 
 | 
  1285  | 
      have "setsum (\<lambda>v. ?u v *\<^sub>R v) ?S =(\<Sum>v\<in>S - {x}. u v *\<^sub>R v) + (u x + c) *\<^sub>R x"
 | 
| 
 | 
  1286  | 
        using xS
  | 
| 
 | 
  1287  | 
        by (simp add: setsum_Un_disjoint[OF Sss, unfolded S1[symmetric]]
  | 
| 
 | 
  1288  | 
          setsum_clauses(2)[OF fS] cong del: if_weak_cong)
  | 
| 
 | 
  1289  | 
      also have "\<dots> = (\<Sum>v\<in>S. u v *\<^sub>R v) + c *\<^sub>R x"
  | 
| 
 | 
  1290  | 
        apply (simp add: setsum_Un_disjoint[OF Sss, unfolded S1[symmetric]])
  | 
| 
 | 
  1291  | 
        by (simp add: algebra_simps)
  | 
| 
 | 
  1292  | 
      also have "\<dots> = c*\<^sub>R x + y"
  | 
| 
 | 
  1293  | 
        by (simp add: add_commute u)
  | 
| 
 | 
  1294  | 
      finally have "setsum (\<lambda>v. ?u v *\<^sub>R v) ?S = c*\<^sub>R x + y" .
  | 
| 
 | 
  1295  | 
    then have "?Q ?S ?u (c*\<^sub>R x + y)" using th0 by blast}
  | 
| 
 | 
  1296  | 
  moreover
  | 
| 
 | 
  1297  | 
  {assume xS: "x \<notin> S"
 | 
| 
 | 
  1298  | 
    have th00: "(\<Sum>v\<in>S. (if v = x then c else u v) *\<^sub>R v) = y"
  | 
| 
 | 
  1299  | 
      unfolding u[symmetric]
  | 
| 
 | 
  1300  | 
      apply (rule setsum_cong2)
  | 
| 
 | 
  1301  | 
      using xS by auto
  | 
| 
 | 
  1302  | 
    have "?Q ?S ?u (c*\<^sub>R x + y)" using fS xS th0
  | 
| 
 | 
  1303  | 
      by (simp add: th00 setsum_clauses add_commute cong del: if_weak_cong)}
  | 
| 
 | 
  1304  | 
  ultimately have "?Q ?S ?u (c*\<^sub>R x + y)"
  | 
| 
 | 
  1305  | 
    by (cases "x \<in> S", simp, simp)
  | 
| 
 | 
  1306  | 
    then show "?h (c*\<^sub>R x + y)"
  | 
| 
 | 
  1307  | 
      apply -
  | 
| 
 | 
  1308  | 
      apply (rule exI[where x="?S"])
  | 
| 
 | 
  1309  | 
      apply (rule exI[where x="?u"]) by metis
  | 
| 
 | 
  1310  | 
  qed
  | 
| 
 | 
  1311  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  1312  | 
qed
  | 
| 
 | 
  1313  | 
  | 
| 
 | 
  1314  | 
lemma dependent_explicit:
  | 
| 
 | 
  1315  | 
  "dependent P \<longleftrightarrow> (\<exists>S u. finite S \<and> S \<subseteq> P \<and> (\<exists>v\<in>S. u v \<noteq> 0 \<and> setsum (\<lambda>v. u v *\<^sub>R v) S = 0))" (is "?lhs = ?rhs")
  | 
| 
 | 
  1316  | 
proof-
  | 
| 
 | 
  1317  | 
  {assume dP: "dependent P"
 | 
| 
 | 
  1318  | 
    then obtain a S u where aP: "a \<in> P" and fS: "finite S"
  | 
| 
 | 
  1319  | 
      and SP: "S \<subseteq> P - {a}" and ua: "setsum (\<lambda>v. u v *\<^sub>R v) S = a"
 | 
| 
 | 
  1320  | 
      unfolding dependent_def span_explicit by blast
  | 
| 
 | 
  1321  | 
    let ?S = "insert a S"
  | 
| 
 | 
  1322  | 
    let ?u = "\<lambda>y. if y = a then - 1 else u y"
  | 
| 
 | 
  1323  | 
    let ?v = a
  | 
| 
 | 
  1324  | 
    from aP SP have aS: "a \<notin> S" by blast
  | 
| 
 | 
  1325  | 
    from fS SP aP have th0: "finite ?S" "?S \<subseteq> P" "?v \<in> ?S" "?u ?v \<noteq> 0" by auto
  | 
| 
 | 
  1326  | 
    have s0: "setsum (\<lambda>v. ?u v *\<^sub>R v) ?S = 0"
  | 
| 
 | 
  1327  | 
      using fS aS
  | 
| 
 | 
  1328  | 
      apply (simp add: setsum_clauses field_simps)
  | 
| 
 | 
  1329  | 
      apply (subst (2) ua[symmetric])
  | 
| 
 | 
  1330  | 
      apply (rule setsum_cong2)
  | 
| 
 | 
  1331  | 
      by auto
  | 
| 
 | 
  1332  | 
    with th0 have ?rhs
  | 
| 
 | 
  1333  | 
      apply -
  | 
| 
 | 
  1334  | 
      apply (rule exI[where x= "?S"])
  | 
| 
 | 
  1335  | 
      apply (rule exI[where x= "?u"])
  | 
| 
 | 
  1336  | 
      by clarsimp}
  | 
| 
 | 
  1337  | 
  moreover
  | 
| 
 | 
  1338  | 
  {fix S u v assume fS: "finite S"
 | 
| 
 | 
  1339  | 
      and SP: "S \<subseteq> P" and vS: "v \<in> S" and uv: "u v \<noteq> 0"
  | 
| 
 | 
  1340  | 
    and u: "setsum (\<lambda>v. u v *\<^sub>R v) S = 0"
  | 
| 
 | 
  1341  | 
    let ?a = v
  | 
| 
 | 
  1342  | 
    let ?S = "S - {v}"
 | 
| 
 | 
  1343  | 
    let ?u = "\<lambda>i. (- u i) / u v"
  | 
| 
 | 
  1344  | 
    have th0: "?a \<in> P" "finite ?S" "?S \<subseteq> P"       using fS SP vS by auto
  | 
| 
 | 
  1345  | 
    have "setsum (\<lambda>v. ?u v *\<^sub>R v) ?S = setsum (\<lambda>v. (- (inverse (u ?a))) *\<^sub>R (u v *\<^sub>R v)) S - ?u v *\<^sub>R v"
  | 
| 
 | 
  1346  | 
      using fS vS uv
  | 
| 
 | 
  1347  | 
      by (simp add: setsum_diff1 divide_inverse field_simps)
  | 
| 
 | 
  1348  | 
    also have "\<dots> = ?a"
  | 
| 
 | 
  1349  | 
      unfolding scaleR_right.setsum [symmetric] u
  | 
| 
 | 
  1350  | 
      using uv by simp
  | 
| 
 | 
  1351  | 
    finally  have "setsum (\<lambda>v. ?u v *\<^sub>R v) ?S = ?a" .
  | 
| 
 | 
  1352  | 
    with th0 have ?lhs
  | 
| 
 | 
  1353  | 
      unfolding dependent_def span_explicit
  | 
| 
 | 
  1354  | 
      apply -
  | 
| 
 | 
  1355  | 
      apply (rule bexI[where x= "?a"])
  | 
| 
 | 
  1356  | 
      apply (simp_all del: scaleR_minus_left)
  | 
| 
 | 
  1357  | 
      apply (rule exI[where x= "?S"])
  | 
| 
 | 
  1358  | 
      by (auto simp del: scaleR_minus_left)}
  | 
| 
 | 
  1359  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  1360  | 
qed
  | 
| 
 | 
  1361  | 
  | 
| 
 | 
  1362  | 
  | 
| 
 | 
  1363  | 
lemma span_finite:
  | 
| 
 | 
  1364  | 
  assumes fS: "finite S"
  | 
| 
 | 
  1365  | 
  shows "span S = {y. \<exists>u. setsum (\<lambda>v. u v *\<^sub>R v) S = y}"
 | 
| 
 | 
  1366  | 
  (is "_ = ?rhs")
  | 
| 
 | 
  1367  | 
proof-
  | 
| 
 | 
  1368  | 
  {fix y assume y: "y \<in> span S"
 | 
| 
 | 
  1369  | 
    from y obtain S' u where fS': "finite S'" and SS': "S' \<subseteq> S" and
  | 
| 
 | 
  1370  | 
      u: "setsum (\<lambda>v. u v *\<^sub>R v) S' = y" unfolding span_explicit by blast
  | 
| 
 | 
  1371  | 
    let ?u = "\<lambda>x. if x \<in> S' then u x else 0"
  | 
| 
 | 
  1372  | 
    have "setsum (\<lambda>v. ?u v *\<^sub>R v) S = setsum (\<lambda>v. u v *\<^sub>R v) S'"
  | 
| 
 | 
  1373  | 
      using SS' fS by (auto intro!: setsum_mono_zero_cong_right)
  | 
| 
 | 
  1374  | 
    hence "setsum (\<lambda>v. ?u v *\<^sub>R v) S = y" by (metis u)
  | 
| 
 | 
  1375  | 
    hence "y \<in> ?rhs" by auto}
  | 
| 
 | 
  1376  | 
  moreover
  | 
| 
 | 
  1377  | 
  {fix y u assume u: "setsum (\<lambda>v. u v *\<^sub>R v) S = y"
 | 
| 
 | 
  1378  | 
    then have "y \<in> span S" using fS unfolding span_explicit by auto}
  | 
| 
 | 
  1379  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  1380  | 
qed
  | 
| 
 | 
  1381  | 
  | 
| 
 | 
  1382  | 
lemma Int_Un_cancel: "(A \<union> B) \<inter> A = A" "(A \<union> B) \<inter> B = B" by auto
  | 
| 
 | 
  1383  | 
  | 
| 
 | 
  1384  | 
lemma span_union: "span (A \<union> B) = (\<lambda>(a, b). a + b) ` (span A \<times> span B)"
  | 
| 
 | 
  1385  | 
proof safe
  | 
| 
 | 
  1386  | 
  fix x assume "x \<in> span (A \<union> B)"
  | 
| 
 | 
  1387  | 
  then obtain S u where S: "finite S" "S \<subseteq> A \<union> B" and x: "x = (\<Sum>v\<in>S. u v *\<^sub>R v)"
  | 
| 
 | 
  1388  | 
    unfolding span_explicit by auto
  | 
| 
 | 
  1389  | 
  | 
| 
 | 
  1390  | 
  let ?Sa = "\<Sum>v\<in>S\<inter>A. u v *\<^sub>R v"
  | 
| 
 | 
  1391  | 
  let ?Sb = "(\<Sum>v\<in>S\<inter>(B - A). u v *\<^sub>R v)"
  | 
| 
 | 
  1392  | 
  show "x \<in> (\<lambda>(a, b). a + b) ` (span A \<times> span B)"
  | 
| 
 | 
  1393  | 
  proof
  | 
| 
 | 
  1394  | 
    show "x = (case (?Sa, ?Sb) of (a, b) \<Rightarrow> a + b)"
  | 
| 
 | 
  1395  | 
      unfolding x using S
  | 
| 
 | 
  1396  | 
      by (simp, subst setsum_Un_disjoint[symmetric]) (auto intro!: setsum_cong)
  | 
| 
 | 
  1397  | 
  | 
| 
 | 
  1398  | 
    from S have "?Sa \<in> span A" unfolding span_explicit
  | 
| 
 | 
  1399  | 
      by (auto intro!: exI[of _ "S \<inter> A"])
  | 
| 
 | 
  1400  | 
    moreover from S have "?Sb \<in> span B" unfolding span_explicit
  | 
| 
 | 
  1401  | 
      by (auto intro!: exI[of _ "S \<inter> (B - A)"])
  | 
| 
 | 
  1402  | 
    ultimately show "(?Sa, ?Sb) \<in> span A \<times> span B" by simp
  | 
| 
 | 
  1403  | 
  qed
  | 
| 
 | 
  1404  | 
next
  | 
| 
 | 
  1405  | 
  fix a b assume "a \<in> span A" and "b \<in> span B"
  | 
| 
 | 
  1406  | 
  then obtain Sa ua Sb ub where span:
  | 
| 
 | 
  1407  | 
    "finite Sa" "Sa \<subseteq> A" "a = (\<Sum>v\<in>Sa. ua v *\<^sub>R v)"
  | 
| 
 | 
  1408  | 
    "finite Sb" "Sb \<subseteq> B" "b = (\<Sum>v\<in>Sb. ub v *\<^sub>R v)"
  | 
| 
 | 
  1409  | 
    unfolding span_explicit by auto
  | 
| 
 | 
  1410  | 
  let "?u v" = "(if v \<in> Sa then ua v else 0) + (if v \<in> Sb then ub v else 0)"
  | 
| 
 | 
  1411  | 
  from span have "finite (Sa \<union> Sb)" "Sa \<union> Sb \<subseteq> A \<union> B"
  | 
| 
 | 
  1412  | 
    and "a + b = (\<Sum>v\<in>(Sa\<union>Sb). ?u v *\<^sub>R v)"
  | 
| 
 | 
  1413  | 
    unfolding setsum_addf scaleR_left_distrib
  | 
| 
 | 
  1414  | 
    by (auto simp add: if_distrib cond_application_beta setsum_cases Int_Un_cancel)
  | 
| 
 | 
  1415  | 
  thus "a + b \<in> span (A \<union> B)"
  | 
| 
 | 
  1416  | 
    unfolding span_explicit by (auto intro!: exI[of _ ?u])
  | 
| 
 | 
  1417  | 
qed
  | 
| 
 | 
  1418  | 
  | 
| 
 | 
  1419  | 
text {* This is useful for building a basis step-by-step. *}
 | 
| 
 | 
  1420  | 
  | 
| 
 | 
  1421  | 
lemma independent_insert:
  | 
| 
 | 
  1422  | 
  "independent(insert a S) \<longleftrightarrow>
  | 
| 
 | 
  1423  | 
      (if a \<in> S then independent S
  | 
| 
 | 
  1424  | 
                else independent S \<and> a \<notin> span S)" (is "?lhs \<longleftrightarrow> ?rhs")
  | 
| 
 | 
  1425  | 
proof-
  | 
| 
 | 
  1426  | 
  {assume aS: "a \<in> S"
 | 
| 
 | 
  1427  | 
    hence ?thesis using insert_absorb[OF aS] by simp}
  | 
| 
 | 
  1428  | 
  moreover
  | 
| 
 | 
  1429  | 
  {assume aS: "a \<notin> S"
 | 
| 
 | 
  1430  | 
    {assume i: ?lhs
 | 
| 
 | 
  1431  | 
      then have ?rhs using aS
  | 
| 
 | 
  1432  | 
        apply simp
  | 
| 
 | 
  1433  | 
        apply (rule conjI)
  | 
| 
 | 
  1434  | 
        apply (rule independent_mono)
  | 
| 
 | 
  1435  | 
        apply assumption
  | 
| 
 | 
  1436  | 
        apply blast
  | 
| 
 | 
  1437  | 
        by (simp add: dependent_def)}
  | 
| 
 | 
  1438  | 
    moreover
  | 
| 
 | 
  1439  | 
    {assume i: ?rhs
 | 
| 
 | 
  1440  | 
      have ?lhs using i aS
  | 
| 
 | 
  1441  | 
        apply simp
  | 
| 
 | 
  1442  | 
        apply (auto simp add: dependent_def)
  | 
| 
 | 
  1443  | 
        apply (case_tac "aa = a", auto)
  | 
| 
 | 
  1444  | 
        apply (subgoal_tac "insert a S - {aa} = insert a (S - {aa})")
 | 
| 
 | 
  1445  | 
        apply simp
  | 
| 
 | 
  1446  | 
        apply (subgoal_tac "a \<in> span (insert aa (S - {aa}))")
 | 
| 
 | 
  1447  | 
        apply (subgoal_tac "insert aa (S - {aa}) = S")
 | 
| 
 | 
  1448  | 
        apply simp
  | 
| 
 | 
  1449  | 
        apply blast
  | 
| 
 | 
  1450  | 
        apply (rule in_span_insert)
  | 
| 
 | 
  1451  | 
        apply assumption
  | 
| 
 | 
  1452  | 
        apply blast
  | 
| 
 | 
  1453  | 
        apply blast
  | 
| 
 | 
  1454  | 
        done}
  | 
| 
 | 
  1455  | 
    ultimately have ?thesis by blast}
  | 
| 
 | 
  1456  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  1457  | 
qed
  | 
| 
 | 
  1458  | 
  | 
| 
 | 
  1459  | 
text {* The degenerate case of the Exchange Lemma. *}
 | 
| 
 | 
  1460  | 
  | 
| 
 | 
  1461  | 
lemma mem_delete: "x \<in> (A - {a}) \<longleftrightarrow> x \<noteq> a \<and> x \<in> A"
 | 
| 
 | 
  1462  | 
  by blast
  | 
| 
 | 
  1463  | 
  | 
| 
 | 
  1464  | 
lemma spanning_subset_independent:
  | 
| 
 | 
  1465  | 
  assumes BA: "B \<subseteq> A" and iA: "independent A"
  | 
| 
 | 
  1466  | 
  and AsB: "A \<subseteq> span B"
  | 
| 
 | 
  1467  | 
  shows "A = B"
  | 
| 
 | 
  1468  | 
proof
  | 
| 
 | 
  1469  | 
  from BA show "B \<subseteq> A" .
  | 
| 
 | 
  1470  | 
next
  | 
| 
 | 
  1471  | 
  from span_mono[OF BA] span_mono[OF AsB]
  | 
| 
 | 
  1472  | 
  have sAB: "span A = span B" unfolding span_span by blast
  | 
| 
 | 
  1473  | 
  | 
| 
 | 
  1474  | 
  {fix x assume x: "x \<in> A"
 | 
| 
 | 
  1475  | 
    from iA have th0: "x \<notin> span (A - {x})"
 | 
| 
 | 
  1476  | 
      unfolding dependent_def using x by blast
  | 
| 
 | 
  1477  | 
    from x have xsA: "x \<in> span A" by (blast intro: span_superset)
  | 
| 
 | 
  1478  | 
    have "A - {x} \<subseteq> A" by blast
 | 
| 
 | 
  1479  | 
    hence th1:"span (A - {x}) \<subseteq> span A" by (metis span_mono)
 | 
| 
 | 
  1480  | 
    {assume xB: "x \<notin> B"
 | 
| 
 | 
  1481  | 
      from xB BA have "B \<subseteq> A -{x}" by blast
 | 
| 
 | 
  1482  | 
      hence "span B \<subseteq> span (A - {x})" by (metis span_mono)
 | 
| 
 | 
  1483  | 
      with th1 th0 sAB have "x \<notin> span A" by blast
  | 
| 
 | 
  1484  | 
      with x have False by (metis span_superset)}
  | 
| 
 | 
  1485  | 
    then have "x \<in> B" by blast}
  | 
| 
 | 
  1486  | 
  then show "A \<subseteq> B" by blast
  | 
| 
 | 
  1487  | 
qed
  | 
| 
 | 
  1488  | 
  | 
| 
 | 
  1489  | 
text {* The general case of the Exchange Lemma, the key to what follows. *}
 | 
| 
 | 
  1490  | 
  | 
| 
 | 
  1491  | 
lemma exchange_lemma:
  | 
| 
 | 
  1492  | 
  assumes f:"finite t" and i: "independent s"
  | 
| 
 | 
  1493  | 
  and sp:"s \<subseteq> span t"
  | 
| 
 | 
  1494  | 
  shows "\<exists>t'. (card t' = card t) \<and> finite t' \<and> s \<subseteq> t' \<and> t' \<subseteq> s \<union> t \<and> s \<subseteq> span t'"
  | 
| 
 | 
  1495  | 
using f i sp
  | 
| 
 | 
  1496  | 
proof(induct "card (t - s)" arbitrary: s t rule: less_induct)
  | 
| 
 | 
  1497  | 
  case less
  | 
| 
 | 
  1498  | 
  note ft = `finite t` and s = `independent s` and sp = `s \<subseteq> span t`
  | 
| 
 | 
  1499  | 
  let ?P = "\<lambda>t'. (card t' = card t) \<and> finite t' \<and> s \<subseteq> t' \<and> t' \<subseteq> s \<union> t \<and> s \<subseteq> span t'"
  | 
| 
 | 
  1500  | 
  let ?ths = "\<exists>t'. ?P t'"
  | 
| 
 | 
  1501  | 
  {assume st: "s \<subseteq> t"
 | 
| 
 | 
  1502  | 
    from st ft span_mono[OF st] have ?ths apply - apply (rule exI[where x=t])
  | 
| 
 | 
  1503  | 
      by (auto intro: span_superset)}
  | 
| 
 | 
  1504  | 
  moreover
  | 
| 
 | 
  1505  | 
  {assume st: "t \<subseteq> s"
 | 
| 
 | 
  1506  | 
  | 
| 
 | 
  1507  | 
    from spanning_subset_independent[OF st s sp]
  | 
| 
 | 
  1508  | 
      st ft span_mono[OF st] have ?ths apply - apply (rule exI[where x=t])
  | 
| 
 | 
  1509  | 
      by (auto intro: span_superset)}
  | 
| 
 | 
  1510  | 
  moreover
  | 
| 
 | 
  1511  | 
  {assume st: "\<not> s \<subseteq> t" "\<not> t \<subseteq> s"
 | 
| 
 | 
  1512  | 
    from st(2) obtain b where b: "b \<in> t" "b \<notin> s" by blast
  | 
| 
 | 
  1513  | 
      from b have "t - {b} - s \<subset> t - s" by blast
 | 
| 
 | 
  1514  | 
      then have cardlt: "card (t - {b} - s) < card (t - s)" using ft
 | 
| 
 | 
  1515  | 
        by (auto intro: psubset_card_mono)
  | 
| 
 | 
  1516  | 
      from b ft have ct0: "card t \<noteq> 0" by auto
  | 
| 
 | 
  1517  | 
    {assume stb: "s \<subseteq> span(t -{b})"
 | 
| 
 | 
  1518  | 
      from ft have ftb: "finite (t -{b})" by auto
 | 
| 
 | 
  1519  | 
      from less(1)[OF cardlt ftb s stb]
  | 
| 
 | 
  1520  | 
      obtain u where u: "card u = card (t-{b})" "s \<subseteq> u" "u \<subseteq> s \<union> (t - {b})" "s \<subseteq> span u" and fu: "finite u" by blast
 | 
| 
 | 
  1521  | 
      let ?w = "insert b u"
  | 
| 
 | 
  1522  | 
      have th0: "s \<subseteq> insert b u" using u by blast
  | 
| 
 | 
  1523  | 
      from u(3) b have "u \<subseteq> s \<union> t" by blast
  | 
| 
 | 
  1524  | 
      then have th1: "insert b u \<subseteq> s \<union> t" using u b by blast
  | 
| 
 | 
  1525  | 
      have bu: "b \<notin> u" using b u by blast
  | 
| 
 | 
  1526  | 
      from u(1) ft b have "card u = (card t - 1)" by auto
  | 
| 
 | 
  1527  | 
      then
  | 
| 
 | 
  1528  | 
      have th2: "card (insert b u) = card t"
  | 
| 
 | 
  1529  | 
        using card_insert_disjoint[OF fu bu] ct0 by auto
  | 
| 
 | 
  1530  | 
      from u(4) have "s \<subseteq> span u" .
  | 
| 
 | 
  1531  | 
      also have "\<dots> \<subseteq> span (insert b u)" apply (rule span_mono) by blast
  | 
| 
 | 
  1532  | 
      finally have th3: "s \<subseteq> span (insert b u)" .
  | 
| 
 | 
  1533  | 
      from th0 th1 th2 th3 fu have th: "?P ?w"  by blast
  | 
| 
 | 
  1534  | 
      from th have ?ths by blast}
  | 
| 
 | 
  1535  | 
    moreover
  | 
| 
 | 
  1536  | 
    {assume stb: "\<not> s \<subseteq> span(t -{b})"
 | 
| 
 | 
  1537  | 
      from stb obtain a where a: "a \<in> s" "a \<notin> span (t - {b})" by blast
 | 
| 
 | 
  1538  | 
      have ab: "a \<noteq> b" using a b by blast
  | 
| 
 | 
  1539  | 
      have at: "a \<notin> t" using a ab span_superset[of a "t- {b}"] by auto
 | 
| 
 | 
  1540  | 
      have mlt: "card ((insert a (t - {b})) - s) < card (t - s)"
 | 
| 
 | 
  1541  | 
        using cardlt ft a b by auto
  | 
| 
 | 
  1542  | 
      have ft': "finite (insert a (t - {b}))" using ft by auto
 | 
| 
 | 
  1543  | 
      {fix x assume xs: "x \<in> s"
 | 
| 
 | 
  1544  | 
        have t: "t \<subseteq> (insert b (insert a (t -{b})))" using b by auto
 | 
| 
 | 
  1545  | 
        from b(1) have "b \<in> span t" by (simp add: span_superset)
  | 
| 
 | 
  1546  | 
        have bs: "b \<in> span (insert a (t - {b}))" apply(rule in_span_delete)
 | 
| 
 | 
  1547  | 
          using  a sp unfolding subset_eq by auto
  | 
| 
 | 
  1548  | 
        from xs sp have "x \<in> span t" by blast
  | 
| 
 | 
  1549  | 
        with span_mono[OF t]
  | 
| 
 | 
  1550  | 
        have x: "x \<in> span (insert b (insert a (t - {b})))" ..
 | 
| 
 | 
  1551  | 
        from span_trans[OF bs x] have "x \<in> span (insert a (t - {b}))"  .}
 | 
| 
 | 
  1552  | 
      then have sp': "s \<subseteq> span (insert a (t - {b}))" by blast
 | 
| 
 | 
  1553  | 
  | 
| 
 | 
  1554  | 
      from less(1)[OF mlt ft' s sp'] obtain u where
  | 
| 
 | 
  1555  | 
        u: "card u = card (insert a (t -{b}))" "finite u" "s \<subseteq> u" "u \<subseteq> s \<union> insert a (t -{b})"
 | 
| 
 | 
  1556  | 
        "s \<subseteq> span u" by blast
  | 
| 
 | 
  1557  | 
      from u a b ft at ct0 have "?P u" by auto
  | 
| 
 | 
  1558  | 
      then have ?ths by blast }
  | 
| 
 | 
  1559  | 
    ultimately have ?ths by blast
  | 
| 
 | 
  1560  | 
  }
  | 
| 
 | 
  1561  | 
  ultimately
  | 
| 
 | 
  1562  | 
  show ?ths  by blast
  | 
| 
 | 
  1563  | 
qed
  | 
| 
 | 
  1564  | 
  | 
| 
 | 
  1565  | 
text {* This implies corresponding size bounds. *}
 | 
| 
 | 
  1566  | 
  | 
| 
 | 
  1567  | 
lemma independent_span_bound:
  | 
| 
 | 
  1568  | 
  assumes f: "finite t" and i: "independent s" and sp:"s \<subseteq> span t"
  | 
| 
 | 
  1569  | 
  shows "finite s \<and> card s \<le> card t"
  | 
| 
 | 
  1570  | 
  by (metis exchange_lemma[OF f i sp] finite_subset card_mono)
  | 
| 
 | 
  1571  | 
  | 
| 
 | 
  1572  | 
  | 
| 
 | 
  1573  | 
lemma finite_Atleast_Atmost_nat[simp]: "finite {f x |x. x\<in> (UNIV::'a::finite set)}"
 | 
| 
 | 
  1574  | 
proof-
  | 
| 
 | 
  1575  | 
  have eq: "{f x |x. x\<in> UNIV} = f ` UNIV" by auto
 | 
| 
 | 
  1576  | 
  show ?thesis unfolding eq
  | 
| 
 | 
  1577  | 
    apply (rule finite_imageI)
  | 
| 
 | 
  1578  | 
    apply (rule finite)
  | 
| 
 | 
  1579  | 
    done
  | 
| 
 | 
  1580  | 
qed
  | 
| 
 | 
  1581  | 
  | 
| 
 | 
  1582  | 
subsection{* Euclidean Spaces as Typeclass*}
 | 
| 
 | 
  1583  | 
  | 
| 
 | 
  1584  | 
lemma independent_eq_inj_on:
  | 
| 
 | 
  1585  | 
  fixes D :: nat and f :: "nat \<Rightarrow> 'c::real_vector" assumes *: "inj_on f {..<D}"
 | 
| 
 | 
  1586  | 
  shows "independent (f ` {..<D}) \<longleftrightarrow> (\<forall>a u. a < D \<longrightarrow> (\<Sum>i\<in>{..<D}-{a}. u (f i) *\<^sub>R f i) \<noteq> f a)"
 | 
| 
 | 
  1587  | 
proof -
  | 
| 
 | 
  1588  | 
  from * have eq: "\<And>i. i < D \<Longrightarrow> f ` {..<D} - {f i} = f`({..<D} - {i})"
 | 
| 
 | 
  1589  | 
    and inj: "\<And>i. inj_on f ({..<D} - {i})"
 | 
| 
 | 
  1590  | 
    by (auto simp: inj_on_def)
  | 
| 
 | 
  1591  | 
  have *: "\<And>i. finite (f ` {..<D} - {i})" by simp
 | 
| 
 | 
  1592  | 
  show ?thesis unfolding dependent_def span_finite[OF *]
  | 
| 
 | 
  1593  | 
    by (auto simp: eq setsum_reindex[OF inj])
  | 
| 
 | 
  1594  | 
qed
  | 
| 
 | 
  1595  | 
  | 
| 
 | 
  1596  | 
lemma independent_basis:
  | 
| 
 | 
  1597  | 
  "independent (basis ` {..<DIM('a)} :: 'a::euclidean_space set)"
 | 
| 
 | 
  1598  | 
  unfolding independent_eq_inj_on [OF basis_inj]
  | 
| 
 | 
  1599  | 
  apply clarify
  | 
| 
 | 
  1600  | 
  apply (drule_tac f="inner (basis a)" in arg_cong)
  | 
| 
 | 
  1601  | 
  apply (simp add: inner_right.setsum dot_basis)
  | 
| 
 | 
  1602  | 
  done
  | 
| 
 | 
  1603  | 
  | 
| 
 | 
  1604  | 
lemma dimensionI:
  | 
| 
 | 
  1605  | 
  assumes "\<And>d. \<lbrakk> 0 < d; basis ` {d..} = {0::'a::euclidean_space};
 | 
| 
 | 
  1606  | 
    independent (basis ` {..<d} :: 'a set);
 | 
| 
 | 
  1607  | 
    inj_on (basis :: nat \<Rightarrow> 'a) {..<d} \<rbrakk> \<Longrightarrow> P d"
 | 
| 
 | 
  1608  | 
  shows "P DIM('a::euclidean_space)"
 | 
| 
 | 
  1609  | 
  using DIM_positive basis_finite independent_basis basis_inj
  | 
| 
 | 
  1610  | 
  by (rule assms)
  | 
| 
 | 
  1611  | 
  | 
| 
 | 
  1612  | 
lemma (in euclidean_space) dimension_eq:
  | 
| 
 | 
  1613  | 
  assumes "\<And>i. i < d \<Longrightarrow> basis i \<noteq> 0"
  | 
| 
 | 
  1614  | 
  assumes "\<And>i. d \<le> i \<Longrightarrow> basis i = 0"
  | 
| 
 | 
  1615  | 
  shows "DIM('a) = d"
 | 
| 
 | 
  1616  | 
proof (rule linorder_cases [of "DIM('a)" d])
 | 
| 
 | 
  1617  | 
  assume "DIM('a) < d"
 | 
| 
 | 
  1618  | 
  hence "basis DIM('a) \<noteq> 0" by (rule assms)
 | 
| 
 | 
  1619  | 
  thus ?thesis by simp
  | 
| 
 | 
  1620  | 
next
  | 
| 
 | 
  1621  | 
  assume "d < DIM('a)"
 | 
| 
 | 
  1622  | 
  hence "basis d \<noteq> 0" by simp
  | 
| 
 | 
  1623  | 
  thus ?thesis by (simp add: assms)
  | 
| 
 | 
  1624  | 
next
  | 
| 
 | 
  1625  | 
  assume "DIM('a) = d" thus ?thesis .
 | 
| 
 | 
  1626  | 
qed
  | 
| 
 | 
  1627  | 
  | 
| 
 | 
  1628  | 
lemma (in euclidean_space) range_basis:
  | 
| 
 | 
  1629  | 
    "range basis = insert 0 (basis ` {..<DIM('a)})"
 | 
| 
 | 
  1630  | 
proof -
  | 
| 
 | 
  1631  | 
  have *: "UNIV = {..<DIM('a)} \<union> {DIM('a)..}" by auto
 | 
| 
 | 
  1632  | 
  show ?thesis unfolding * image_Un basis_finite by auto
  | 
| 
 | 
  1633  | 
qed
  | 
| 
 | 
  1634  | 
  | 
| 
 | 
  1635  | 
lemma (in euclidean_space) range_basis_finite[intro]:
  | 
| 
 | 
  1636  | 
    "finite (range basis)"
  | 
| 
 | 
  1637  | 
  unfolding range_basis by auto
  | 
| 
 | 
  1638  | 
  | 
| 
 | 
  1639  | 
lemma span_basis: "span (range basis) = (UNIV :: 'a::euclidean_space set)"
  | 
| 
 | 
  1640  | 
proof -
  | 
| 
 | 
  1641  | 
  { fix x :: 'a
 | 
| 
 | 
  1642  | 
    have "(\<Sum>i<DIM('a). (x $$ i) *\<^sub>R basis i) \<in> span (range basis :: 'a set)"
 | 
| 
 | 
  1643  | 
      by (simp add: span_setsum span_mul span_superset)
  | 
| 
 | 
  1644  | 
    hence "x \<in> span (range basis)"
  | 
| 
 | 
  1645  | 
      by (simp only: euclidean_representation [symmetric])
  | 
| 
 | 
  1646  | 
  } thus ?thesis by auto
  | 
| 
 | 
  1647  | 
qed
  | 
| 
 | 
  1648  | 
  | 
| 
 | 
  1649  | 
lemma basis_representation:
  | 
| 
 | 
  1650  | 
  "\<exists>u. x = (\<Sum>v\<in>basis ` {..<DIM('a)}. u v *\<^sub>R (v\<Colon>'a\<Colon>euclidean_space))"
 | 
| 
 | 
  1651  | 
proof -
  | 
| 
 | 
  1652  | 
  have "x\<in>UNIV" by auto from this[unfolded span_basis[THEN sym]]
  | 
| 
 | 
  1653  | 
  have "\<exists>u. (\<Sum>v\<in>basis ` {..<DIM('a)}. u v *\<^sub>R v) = x"
 | 
| 
 | 
  1654  | 
    unfolding range_basis span_insert_0 apply(subst (asm) span_finite) by auto
  | 
| 
 | 
  1655  | 
  thus ?thesis by fastsimp
  | 
| 
 | 
  1656  | 
qed
  | 
| 
 | 
  1657  | 
  | 
| 
 | 
  1658  | 
lemma span_basis'[simp]:"span ((basis::nat=>'a) ` {..<DIM('a::euclidean_space)}) = UNIV"
 | 
| 
 | 
  1659  | 
  apply(subst span_basis[symmetric]) unfolding range_basis by auto
  | 
| 
 | 
  1660  | 
  | 
| 
 | 
  1661  | 
lemma card_basis[simp]:"card ((basis::nat=>'a) ` {..<DIM('a::euclidean_space)}) = DIM('a)"
 | 
| 
 | 
  1662  | 
  apply(subst card_image) using basis_inj by auto
  | 
| 
 | 
  1663  | 
  | 
| 
 | 
  1664  | 
lemma in_span_basis: "(x::'a::euclidean_space) \<in> span (basis ` {..<DIM('a)})"
 | 
| 
 | 
  1665  | 
  unfolding span_basis' ..
  | 
| 
 | 
  1666  | 
  | 
| 
 | 
  1667  | 
lemma component_le_norm: "\<bar>x$$i\<bar> \<le> norm (x::'a::euclidean_space)"
  | 
| 
 | 
  1668  | 
  unfolding euclidean_component_def
  | 
| 
 | 
  1669  | 
  apply(rule order_trans[OF real_inner_class.Cauchy_Schwarz_ineq2]) by auto
  | 
| 
 | 
  1670  | 
  | 
| 
 | 
  1671  | 
lemma norm_bound_component_le: "norm (x::'a::euclidean_space) \<le> e \<Longrightarrow> \<bar>x$$i\<bar> <= e"
  | 
| 
 | 
  1672  | 
  by (metis component_le_norm order_trans)
  | 
| 
 | 
  1673  | 
  | 
| 
 | 
  1674  | 
lemma norm_bound_component_lt: "norm (x::'a::euclidean_space) < e \<Longrightarrow> \<bar>x$$i\<bar> < e"
  | 
| 
 | 
  1675  | 
  by (metis component_le_norm basic_trans_rules(21))
  | 
| 
 | 
  1676  | 
  | 
| 
 | 
  1677  | 
lemma norm_le_l1: "norm (x::'a::euclidean_space) \<le> (\<Sum>i<DIM('a). \<bar>x $$ i\<bar>)"
 | 
| 
 | 
  1678  | 
  apply (subst euclidean_representation[of x])
  | 
| 
 | 
  1679  | 
  apply (rule order_trans[OF setsum_norm])
  | 
| 
 | 
  1680  | 
  by (auto intro!: setsum_mono)
  | 
| 
 | 
  1681  | 
  | 
| 
 | 
  1682  | 
lemma setsum_norm_allsubsets_bound:
  | 
| 
 | 
  1683  | 
  fixes f:: "'a \<Rightarrow> 'n::euclidean_space"
  | 
| 
 | 
  1684  | 
  assumes fP: "finite P" and fPs: "\<And>Q. Q \<subseteq> P \<Longrightarrow> norm (setsum f Q) \<le> e"
  | 
| 
 | 
  1685  | 
  shows "setsum (\<lambda>x. norm (f x)) P \<le> 2 * real DIM('n) *  e"
 | 
| 
 | 
  1686  | 
proof-
  | 
| 
 | 
  1687  | 
  let ?d = "real DIM('n)"
 | 
| 
 | 
  1688  | 
  let ?nf = "\<lambda>x. norm (f x)"
  | 
| 
 | 
  1689  | 
  let ?U = "{..<DIM('n)}"
 | 
| 
 | 
  1690  | 
  have th0: "setsum (\<lambda>x. setsum (\<lambda>i. \<bar>f x $$ i\<bar>) ?U) P = setsum (\<lambda>i. setsum (\<lambda>x. \<bar>f x $$ i\<bar>) P) ?U"
  | 
| 
 | 
  1691  | 
    by (rule setsum_commute)
  | 
| 
 | 
  1692  | 
  have th1: "2 * ?d * e = of_nat (card ?U) * (2 * e)" by (simp add: real_of_nat_def)
  | 
| 
 | 
  1693  | 
  have "setsum ?nf P \<le> setsum (\<lambda>x. setsum (\<lambda>i. \<bar>f x $$ i\<bar>) ?U) P"
  | 
| 
 | 
  1694  | 
    apply (rule setsum_mono)    by (rule norm_le_l1)
  | 
| 
 | 
  1695  | 
  also have "\<dots> \<le> 2 * ?d * e"
  | 
| 
 | 
  1696  | 
    unfolding th0 th1
  | 
| 
 | 
  1697  | 
  proof(rule setsum_bounded)
  | 
| 
 | 
  1698  | 
    fix i assume i: "i \<in> ?U"
  | 
| 
 | 
  1699  | 
    let ?Pp = "{x. x\<in> P \<and> f x $$ i \<ge> 0}"
 | 
| 
 | 
  1700  | 
    let ?Pn = "{x. x \<in> P \<and> f x $$ i < 0}"
 | 
| 
 | 
  1701  | 
    have thp: "P = ?Pp \<union> ?Pn" by auto
  | 
| 
 | 
  1702  | 
    have thp0: "?Pp \<inter> ?Pn ={}" by auto
 | 
| 
 | 
  1703  | 
    have PpP: "?Pp \<subseteq> P" and PnP: "?Pn \<subseteq> P" by blast+
  | 
| 
 | 
  1704  | 
    have Ppe:"setsum (\<lambda>x. \<bar>f x $$ i\<bar>) ?Pp \<le> e"
  | 
| 
 | 
  1705  | 
      using component_le_norm[of "setsum (\<lambda>x. f x) ?Pp" i]  fPs[OF PpP]
  | 
| 
 | 
  1706  | 
      unfolding euclidean_component.setsum by(auto intro: abs_le_D1)
  | 
| 
 | 
  1707  | 
    have Pne: "setsum (\<lambda>x. \<bar>f x $$ i\<bar>) ?Pn \<le> e"
  | 
| 
 | 
  1708  | 
      using component_le_norm[of "setsum (\<lambda>x. - f x) ?Pn" i]  fPs[OF PnP]
  | 
| 
 | 
  1709  | 
      unfolding euclidean_component.setsum euclidean_component.minus
  | 
| 
 | 
  1710  | 
      by(auto simp add: setsum_negf intro: abs_le_D1)
  | 
| 
 | 
  1711  | 
    have "setsum (\<lambda>x. \<bar>f x $$ i\<bar>) P = setsum (\<lambda>x. \<bar>f x $$ i\<bar>) ?Pp + setsum (\<lambda>x. \<bar>f x $$ i\<bar>) ?Pn"
  | 
| 
 | 
  1712  | 
      apply (subst thp)
  | 
| 
 | 
  1713  | 
      apply (rule setsum_Un_zero)
  | 
| 
 | 
  1714  | 
      using fP thp0 by auto
  | 
| 
 | 
  1715  | 
    also have "\<dots> \<le> 2*e" using Pne Ppe by arith
  | 
| 
 | 
  1716  | 
    finally show "setsum (\<lambda>x. \<bar>f x $$ i\<bar>) P \<le> 2*e" .
  | 
| 
 | 
  1717  | 
  qed
  | 
| 
 | 
  1718  | 
  finally show ?thesis .
  | 
| 
 | 
  1719  | 
qed
  | 
| 
 | 
  1720  | 
  | 
| 
 | 
  1721  | 
lemma choice_iff': "(\<forall>x<d. \<exists>y. P x y) \<longleftrightarrow> (\<exists>f. \<forall>x<d. P x (f x))" by metis
  | 
| 
 | 
  1722  | 
  | 
| 
 | 
  1723  | 
lemma lambda_skolem': "(\<forall>i<DIM('a::euclidean_space). \<exists>x. P i x) \<longleftrightarrow>
 | 
| 
 | 
  1724  | 
   (\<exists>x::'a. \<forall>i<DIM('a). P i (x$$i))" (is "?lhs \<longleftrightarrow> ?rhs")
 | 
| 
 | 
  1725  | 
proof-
  | 
| 
 | 
  1726  | 
  let ?S = "{..<DIM('a)}"
 | 
| 
 | 
  1727  | 
  {assume H: "?rhs"
 | 
| 
 | 
  1728  | 
    then have ?lhs by auto}
  | 
| 
 | 
  1729  | 
  moreover
  | 
| 
 | 
  1730  | 
  {assume H: "?lhs"
 | 
| 
 | 
  1731  | 
    then obtain f where f:"\<forall>i<DIM('a). P i (f i)" unfolding choice_iff' by metis
 | 
| 
 | 
  1732  | 
    let ?x = "(\<chi>\<chi> i. (f i)) :: 'a"
  | 
| 
 | 
  1733  | 
    {fix i assume i:"i<DIM('a)"
 | 
| 
 | 
  1734  | 
      with f have "P i (f i)" by metis
  | 
| 
 | 
  1735  | 
      then have "P i (?x$$i)" using i by auto
  | 
| 
 | 
  1736  | 
    }
  | 
| 
 | 
  1737  | 
    hence "\<forall>i<DIM('a). P i (?x$$i)" by metis
 | 
| 
 | 
  1738  | 
    hence ?rhs by metis }
  | 
| 
 | 
  1739  | 
  ultimately show ?thesis by metis
  | 
| 
 | 
  1740  | 
qed
  | 
| 
 | 
  1741  | 
  | 
| 
 | 
  1742  | 
subsection {* An ordering on euclidean spaces that will allow us to talk about intervals *}
 | 
| 
 | 
  1743  | 
  | 
| 
 | 
  1744  | 
class ordered_euclidean_space = ord + euclidean_space +
  | 
| 
 | 
  1745  | 
  assumes eucl_le: "x \<le> y \<longleftrightarrow> (\<forall>i < DIM('a). x $$ i \<le> y $$ i)"
 | 
| 
 | 
  1746  | 
  and eucl_less: "x < y \<longleftrightarrow> (\<forall>i < DIM('a). x $$ i < y $$ i)"
 | 
| 
 | 
  1747  | 
  | 
| 
 | 
  1748  | 
lemma eucl_less_not_refl[simp, intro!]: "\<not> x < (x::'a::ordered_euclidean_space)"
  | 
| 
 | 
  1749  | 
  unfolding eucl_less[where 'a='a] by auto
  | 
| 
 | 
  1750  | 
  | 
| 
 | 
  1751  | 
lemma euclidean_trans[trans]:
  | 
| 
 | 
  1752  | 
  fixes x y z :: "'a::ordered_euclidean_space"
  | 
| 
 | 
  1753  | 
  shows "x < y \<Longrightarrow> y < z \<Longrightarrow> x < z"
  | 
| 
 | 
  1754  | 
  and "x \<le> y \<Longrightarrow> y < z \<Longrightarrow> x < z"
  | 
| 
 | 
  1755  | 
  and "x \<le> y \<Longrightarrow> y \<le> z \<Longrightarrow> x \<le> z"
  | 
| 
 | 
  1756  | 
  by (force simp: eucl_less[where 'a='a] eucl_le[where 'a='a])+
  | 
| 
 | 
  1757  | 
  | 
| 
 | 
  1758  | 
subsection {* Linearity and Bilinearity continued *}
 | 
| 
 | 
  1759  | 
  | 
| 
 | 
  1760  | 
lemma linear_bounded:
  | 
| 
 | 
  1761  | 
  fixes f:: "'a::euclidean_space \<Rightarrow> 'b::real_normed_vector"
  | 
| 
 | 
  1762  | 
  assumes lf: "linear f"
  | 
| 
 | 
  1763  | 
  shows "\<exists>B. \<forall>x. norm (f x) \<le> B * norm x"
  | 
| 
 | 
  1764  | 
proof-
  | 
| 
 | 
  1765  | 
  let ?S = "{..<DIM('a)}"
 | 
| 
 | 
  1766  | 
  let ?B = "setsum (\<lambda>i. norm(f(basis i))) ?S"
  | 
| 
 | 
  1767  | 
  have fS: "finite ?S" by simp
  | 
| 
 | 
  1768  | 
  {fix x:: "'a"
 | 
| 
 | 
  1769  | 
    let ?g = "(\<lambda> i. (x$$i) *\<^sub>R (basis i) :: 'a)"
  | 
| 
 | 
  1770  | 
    have "norm (f x) = norm (f (setsum (\<lambda>i. (x$$i) *\<^sub>R (basis i)) ?S))"
  | 
| 
 | 
  1771  | 
      apply(subst euclidean_representation[of x]) ..
  | 
| 
 | 
  1772  | 
    also have "\<dots> = norm (setsum (\<lambda> i. (x$$i) *\<^sub>R f (basis i)) ?S)"
  | 
| 
 | 
  1773  | 
      using linear_setsum[OF lf fS, of ?g, unfolded o_def] linear_cmul[OF lf] by auto
  | 
| 
 | 
  1774  | 
    finally have th0: "norm (f x) = norm (setsum (\<lambda>i. (x$$i) *\<^sub>R f (basis i))?S)" .
  | 
| 
 | 
  1775  | 
    {fix i assume i: "i \<in> ?S"
 | 
| 
 | 
  1776  | 
      from component_le_norm[of x i]
  | 
| 
 | 
  1777  | 
      have "norm ((x$$i) *\<^sub>R f (basis i :: 'a)) \<le> norm (f (basis i)) * norm x"
  | 
| 
 | 
  1778  | 
      unfolding norm_scaleR
  | 
| 
 | 
  1779  | 
      apply (simp only: mult_commute)
  | 
| 
 | 
  1780  | 
      apply (rule mult_mono)
  | 
| 
 | 
  1781  | 
      by (auto simp add: field_simps) }
  | 
| 
 | 
  1782  | 
    then have th: "\<forall>i\<in> ?S. norm ((x$$i) *\<^sub>R f (basis i :: 'a)) \<le> norm (f (basis i)) * norm x" by metis
  | 
| 
 | 
  1783  | 
    from setsum_norm_le[OF fS, of "\<lambda>i. (x$$i) *\<^sub>R (f (basis i))", OF th]
  | 
| 
 | 
  1784  | 
    have "norm (f x) \<le> ?B * norm x" unfolding th0 setsum_left_distrib by metis}
  | 
| 
 | 
  1785  | 
  then show ?thesis by blast
  | 
| 
 | 
  1786  | 
qed
  | 
| 
 | 
  1787  | 
  | 
| 
 | 
  1788  | 
lemma linear_bounded_pos:
  | 
| 
 | 
  1789  | 
  fixes f:: "'a::euclidean_space \<Rightarrow> 'b::real_normed_vector"
  | 
| 
 | 
  1790  | 
  assumes lf: "linear f"
  | 
| 
 | 
  1791  | 
  shows "\<exists>B > 0. \<forall>x. norm (f x) \<le> B * norm x"
  | 
| 
 | 
  1792  | 
proof-
  | 
| 
 | 
  1793  | 
  from linear_bounded[OF lf] obtain B where
  | 
| 
 | 
  1794  | 
    B: "\<forall>x. norm (f x) \<le> B * norm x" by blast
  | 
| 
 | 
  1795  | 
  let ?K = "\<bar>B\<bar> + 1"
  | 
| 
 | 
  1796  | 
  have Kp: "?K > 0" by arith
  | 
| 
 | 
  1797  | 
    { assume C: "B < 0"
 | 
| 
 | 
  1798  | 
      have "((\<chi>\<chi> i. 1)::'a) \<noteq> 0" unfolding euclidean_eq[where 'a='a]
  | 
| 
 | 
  1799  | 
        by(auto intro!:exI[where x=0] simp add:euclidean_component.zero)
  | 
| 
 | 
  1800  | 
      hence "norm ((\<chi>\<chi> i. 1)::'a) > 0" by auto
  | 
| 
 | 
  1801  | 
      with C have "B * norm ((\<chi>\<chi> i. 1)::'a) < 0"
  | 
| 
 | 
  1802  | 
        by (simp add: mult_less_0_iff)
  | 
| 
 | 
  1803  | 
      with B[rule_format, of "(\<chi>\<chi> i. 1)::'a"] norm_ge_zero[of "f ((\<chi>\<chi> i. 1)::'a)"] have False by simp
  | 
| 
 | 
  1804  | 
    }
  | 
| 
 | 
  1805  | 
    then have Bp: "B \<ge> 0" by (metis not_leE)
  | 
| 
 | 
  1806  | 
    {fix x::"'a"
 | 
| 
 | 
  1807  | 
      have "norm (f x) \<le> ?K *  norm x"
  | 
| 
 | 
  1808  | 
      using B[rule_format, of x] norm_ge_zero[of x] norm_ge_zero[of "f x"] Bp
  | 
| 
 | 
  1809  | 
      apply (auto simp add: field_simps split add: abs_split)
  | 
| 
 | 
  1810  | 
      apply (erule order_trans, simp)
  | 
| 
 | 
  1811  | 
      done
  | 
| 
 | 
  1812  | 
  }
  | 
| 
 | 
  1813  | 
  then show ?thesis using Kp by blast
  | 
| 
 | 
  1814  | 
qed
  | 
| 
 | 
  1815  | 
  | 
| 
 | 
  1816  | 
lemma linear_conv_bounded_linear:
  | 
| 
 | 
  1817  | 
  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::real_normed_vector"
  | 
| 
 | 
  1818  | 
  shows "linear f \<longleftrightarrow> bounded_linear f"
  | 
| 
 | 
  1819  | 
proof
  | 
| 
 | 
  1820  | 
  assume "linear f"
  | 
| 
 | 
  1821  | 
  show "bounded_linear f"
  | 
| 
 | 
  1822  | 
  proof
  | 
| 
 | 
  1823  | 
    fix x y show "f (x + y) = f x + f y"
  | 
| 
 | 
  1824  | 
      using `linear f` unfolding linear_def by simp
  | 
| 
 | 
  1825  | 
  next
  | 
| 
 | 
  1826  | 
    fix r x show "f (scaleR r x) = scaleR r (f x)"
  | 
| 
 | 
  1827  | 
      using `linear f` unfolding linear_def by simp
  | 
| 
 | 
  1828  | 
  next
  | 
| 
 | 
  1829  | 
    have "\<exists>B. \<forall>x. norm (f x) \<le> B * norm x"
  | 
| 
 | 
  1830  | 
      using `linear f` by (rule linear_bounded)
  | 
| 
 | 
  1831  | 
    thus "\<exists>K. \<forall>x. norm (f x) \<le> norm x * K"
  | 
| 
 | 
  1832  | 
      by (simp add: mult_commute)
  | 
| 
 | 
  1833  | 
  qed
  | 
| 
 | 
  1834  | 
next
  | 
| 
 | 
  1835  | 
  assume "bounded_linear f"
  | 
| 
 | 
  1836  | 
  then interpret f: bounded_linear f .
  | 
| 
 | 
  1837  | 
  show "linear f"
  | 
| 
 | 
  1838  | 
    by (simp add: f.add f.scaleR linear_def)
  | 
| 
 | 
  1839  | 
qed
  | 
| 
 | 
  1840  | 
  | 
| 
 | 
  1841  | 
lemma bounded_linearI': fixes f::"'a::euclidean_space \<Rightarrow> 'b::real_normed_vector"
  | 
| 
 | 
  1842  | 
  assumes "\<And>x y. f (x + y) = f x + f y" "\<And>c x. f (c *\<^sub>R x) = c *\<^sub>R f x"
  | 
| 
 | 
  1843  | 
  shows "bounded_linear f" unfolding linear_conv_bounded_linear[THEN sym]
  | 
| 
 | 
  1844  | 
  by(rule linearI[OF assms])
  | 
| 
 | 
  1845  | 
  | 
| 
 | 
  1846  | 
  | 
| 
 | 
  1847  | 
lemma bilinear_bounded:
  | 
| 
 | 
  1848  | 
  fixes h:: "'m::euclidean_space \<Rightarrow> 'n::euclidean_space \<Rightarrow> 'k::real_normed_vector"
  | 
| 
 | 
  1849  | 
  assumes bh: "bilinear h"
  | 
| 
 | 
  1850  | 
  shows "\<exists>B. \<forall>x y. norm (h x y) \<le> B * norm x * norm y"
  | 
| 
 | 
  1851  | 
proof-
  | 
| 
 | 
  1852  | 
  let ?M = "{..<DIM('m)}"
 | 
| 
 | 
  1853  | 
  let ?N = "{..<DIM('n)}"
 | 
| 
 | 
  1854  | 
  let ?B = "setsum (\<lambda>(i,j). norm (h (basis i) (basis j))) (?M \<times> ?N)"
  | 
| 
 | 
  1855  | 
  have fM: "finite ?M" and fN: "finite ?N" by simp_all
  | 
| 
 | 
  1856  | 
  {fix x:: "'m" and  y :: "'n"
 | 
| 
 | 
  1857  | 
    have "norm (h x y) = norm (h (setsum (\<lambda>i. (x$$i) *\<^sub>R basis i) ?M) (setsum (\<lambda>i. (y$$i) *\<^sub>R basis i) ?N))" 
  | 
| 
 | 
  1858  | 
      apply(subst euclidean_representation[where 'a='m])
  | 
| 
 | 
  1859  | 
      apply(subst euclidean_representation[where 'a='n]) ..
  | 
| 
 | 
  1860  | 
    also have "\<dots> = norm (setsum (\<lambda> (i,j). h ((x$$i) *\<^sub>R basis i) ((y$$j) *\<^sub>R basis j)) (?M \<times> ?N))"  
  | 
| 
 | 
  1861  | 
      unfolding bilinear_setsum[OF bh fM fN] ..
  | 
| 
 | 
  1862  | 
    finally have th: "norm (h x y) = \<dots>" .
  | 
| 
 | 
  1863  | 
    have "norm (h x y) \<le> ?B * norm x * norm y"
  | 
| 
 | 
  1864  | 
      apply (simp add: setsum_left_distrib th)
  | 
| 
 | 
  1865  | 
      apply (rule setsum_norm_le)
  | 
| 
 | 
  1866  | 
      using fN fM
  | 
| 
 | 
  1867  | 
      apply simp
  | 
| 
 | 
  1868  | 
      apply (auto simp add: bilinear_rmul[OF bh] bilinear_lmul[OF bh] field_simps simp del: scaleR_scaleR)
  | 
| 
 | 
  1869  | 
      apply (rule mult_mono)
  | 
| 
 | 
  1870  | 
      apply (auto simp add: zero_le_mult_iff component_le_norm)
  | 
| 
 | 
  1871  | 
      apply (rule mult_mono)
  | 
| 
 | 
  1872  | 
      apply (auto simp add: zero_le_mult_iff component_le_norm)
  | 
| 
 | 
  1873  | 
      done}
  | 
| 
 | 
  1874  | 
  then show ?thesis by metis
  | 
| 
 | 
  1875  | 
qed
  | 
| 
 | 
  1876  | 
  | 
| 
 | 
  1877  | 
lemma bilinear_bounded_pos:
  | 
| 
 | 
  1878  | 
  fixes h:: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space \<Rightarrow> 'c::real_normed_vector"
  | 
| 
 | 
  1879  | 
  assumes bh: "bilinear h"
  | 
| 
 | 
  1880  | 
  shows "\<exists>B > 0. \<forall>x y. norm (h x y) \<le> B * norm x * norm y"
  | 
| 
 | 
  1881  | 
proof-
  | 
| 
 | 
  1882  | 
  from bilinear_bounded[OF bh] obtain B where
  | 
| 
 | 
  1883  | 
    B: "\<forall>x y. norm (h x y) \<le> B * norm x * norm y" by blast
  | 
| 
 | 
  1884  | 
  let ?K = "\<bar>B\<bar> + 1"
  | 
| 
 | 
  1885  | 
  have Kp: "?K > 0" by arith
  | 
| 
 | 
  1886  | 
  have KB: "B < ?K" by arith
  | 
| 
 | 
  1887  | 
  {fix x::'a and y::'b
 | 
| 
 | 
  1888  | 
    from KB Kp
  | 
| 
 | 
  1889  | 
    have "B * norm x * norm y \<le> ?K * norm x * norm y"
  | 
| 
 | 
  1890  | 
      apply -
  | 
| 
 | 
  1891  | 
      apply (rule mult_right_mono, rule mult_right_mono)
  | 
| 
 | 
  1892  | 
      by auto
  | 
| 
 | 
  1893  | 
    then have "norm (h x y) \<le> ?K * norm x * norm y"
  | 
| 
 | 
  1894  | 
      using B[rule_format, of x y] by simp}
  | 
| 
 | 
  1895  | 
  with Kp show ?thesis by blast
  | 
| 
 | 
  1896  | 
qed
  | 
| 
 | 
  1897  | 
  | 
| 
 | 
  1898  | 
lemma bilinear_conv_bounded_bilinear:
  | 
| 
 | 
  1899  | 
  fixes h :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space \<Rightarrow> 'c::real_normed_vector"
  | 
| 
 | 
  1900  | 
  shows "bilinear h \<longleftrightarrow> bounded_bilinear h"
  | 
| 
 | 
  1901  | 
proof
  | 
| 
 | 
  1902  | 
  assume "bilinear h"
  | 
| 
 | 
  1903  | 
  show "bounded_bilinear h"
  | 
| 
 | 
  1904  | 
  proof
  | 
| 
 | 
  1905  | 
    fix x y z show "h (x + y) z = h x z + h y z"
  | 
| 
 | 
  1906  | 
      using `bilinear h` unfolding bilinear_def linear_def by simp
  | 
| 
 | 
  1907  | 
  next
  | 
| 
 | 
  1908  | 
    fix x y z show "h x (y + z) = h x y + h x z"
  | 
| 
 | 
  1909  | 
      using `bilinear h` unfolding bilinear_def linear_def by simp
  | 
| 
 | 
  1910  | 
  next
  | 
| 
 | 
  1911  | 
    fix r x y show "h (scaleR r x) y = scaleR r (h x y)"
  | 
| 
 | 
  1912  | 
      using `bilinear h` unfolding bilinear_def linear_def
  | 
| 
 | 
  1913  | 
      by simp
  | 
| 
 | 
  1914  | 
  next
  | 
| 
 | 
  1915  | 
    fix r x y show "h x (scaleR r y) = scaleR r (h x y)"
  | 
| 
 | 
  1916  | 
      using `bilinear h` unfolding bilinear_def linear_def
  | 
| 
 | 
  1917  | 
      by simp
  | 
| 
 | 
  1918  | 
  next
  | 
| 
 | 
  1919  | 
    have "\<exists>B. \<forall>x y. norm (h x y) \<le> B * norm x * norm y"
  | 
| 
 | 
  1920  | 
      using `bilinear h` by (rule bilinear_bounded)
  | 
| 
 | 
  1921  | 
    thus "\<exists>K. \<forall>x y. norm (h x y) \<le> norm x * norm y * K"
  | 
| 
 | 
  1922  | 
      by (simp add: mult_ac)
  | 
| 
 | 
  1923  | 
  qed
  | 
| 
 | 
  1924  | 
next
  | 
| 
 | 
  1925  | 
  assume "bounded_bilinear h"
  | 
| 
 | 
  1926  | 
  then interpret h: bounded_bilinear h .
  | 
| 
 | 
  1927  | 
  show "bilinear h"
  | 
| 
 | 
  1928  | 
    unfolding bilinear_def linear_conv_bounded_linear
  | 
| 
 | 
  1929  | 
    using h.bounded_linear_left h.bounded_linear_right
  | 
| 
 | 
  1930  | 
    by simp
  | 
| 
 | 
  1931  | 
qed
  | 
| 
 | 
  1932  | 
  | 
| 
 | 
  1933  | 
subsection {* We continue. *}
 | 
| 
 | 
  1934  | 
  | 
| 
 | 
  1935  | 
lemma independent_bound:
  | 
| 
 | 
  1936  | 
  fixes S:: "('a::euclidean_space) set"
 | 
| 
 | 
  1937  | 
  shows "independent S \<Longrightarrow> finite S \<and> card S <= DIM('a::euclidean_space)"
 | 
| 
 | 
  1938  | 
  using independent_span_bound[of "(basis::nat=>'a) ` {..<DIM('a)}" S] by auto
 | 
| 
 | 
  1939  | 
  | 
| 
 | 
  1940  | 
lemma dependent_biggerset: "(finite (S::('a::euclidean_space) set) ==> card S > DIM('a)) ==> dependent S"
 | 
| 
 | 
  1941  | 
  by (metis independent_bound not_less)
  | 
| 
 | 
  1942  | 
  | 
| 
 | 
  1943  | 
text {* Hence we can create a maximal independent subset. *}
 | 
| 
 | 
  1944  | 
  | 
| 
 | 
  1945  | 
lemma maximal_independent_subset_extend:
  | 
| 
 | 
  1946  | 
  assumes sv: "(S::('a::euclidean_space) set) \<subseteq> V" and iS: "independent S"
 | 
| 
 | 
  1947  | 
  shows "\<exists>B. S \<subseteq> B \<and> B \<subseteq> V \<and> independent B \<and> V \<subseteq> span B"
  | 
| 
 | 
  1948  | 
  using sv iS
  | 
| 
 | 
  1949  | 
proof(induct "DIM('a) - card S" arbitrary: S rule: less_induct)
 | 
| 
 | 
  1950  | 
  case less
  | 
| 
 | 
  1951  | 
  note sv = `S \<subseteq> V` and i = `independent S`
  | 
| 
 | 
  1952  | 
  let ?P = "\<lambda>B. S \<subseteq> B \<and> B \<subseteq> V \<and> independent B \<and> V \<subseteq> span B"
  | 
| 
 | 
  1953  | 
  let ?ths = "\<exists>x. ?P x"
  | 
| 
 | 
  1954  | 
  let ?d = "DIM('a)"
 | 
| 
 | 
  1955  | 
  {assume "V \<subseteq> span S"
 | 
| 
 | 
  1956  | 
    then have ?ths  using sv i by blast }
  | 
| 
 | 
  1957  | 
  moreover
  | 
| 
 | 
  1958  | 
  {assume VS: "\<not> V \<subseteq> span S"
 | 
| 
 | 
  1959  | 
    from VS obtain a where a: "a \<in> V" "a \<notin> span S" by blast
  | 
| 
 | 
  1960  | 
    from a have aS: "a \<notin> S" by (auto simp add: span_superset)
  | 
| 
 | 
  1961  | 
    have th0: "insert a S \<subseteq> V" using a sv by blast
  | 
| 
 | 
  1962  | 
    from independent_insert[of a S]  i a
  | 
| 
 | 
  1963  | 
    have th1: "independent (insert a S)" by auto
  | 
| 
 | 
  1964  | 
    have mlt: "?d - card (insert a S) < ?d - card S"
  | 
| 
 | 
  1965  | 
      using aS a independent_bound[OF th1]
  | 
| 
 | 
  1966  | 
      by auto
  | 
| 
 | 
  1967  | 
  | 
| 
 | 
  1968  | 
    from less(1)[OF mlt th0 th1]
  | 
| 
 | 
  1969  | 
    obtain B where B: "insert a S \<subseteq> B" "B \<subseteq> V" "independent B" " V \<subseteq> span B"
  | 
| 
 | 
  1970  | 
      by blast
  | 
| 
 | 
  1971  | 
    from B have "?P B" by auto
  | 
| 
 | 
  1972  | 
    then have ?ths by blast}
  | 
| 
 | 
  1973  | 
  ultimately show ?ths by blast
  | 
| 
 | 
  1974  | 
qed
  | 
| 
 | 
  1975  | 
  | 
| 
 | 
  1976  | 
lemma maximal_independent_subset:
  | 
| 
 | 
  1977  | 
  "\<exists>(B:: ('a::euclidean_space) set). B\<subseteq> V \<and> independent B \<and> V \<subseteq> span B"
 | 
| 
 | 
  1978  | 
  by (metis maximal_independent_subset_extend[of "{}:: ('a::euclidean_space) set"] empty_subsetI independent_empty)
 | 
| 
 | 
  1979  | 
  | 
| 
 | 
  1980  | 
  | 
| 
 | 
  1981  | 
text {* Notion of dimension. *}
 | 
| 
 | 
  1982  | 
  | 
| 
 | 
  1983  | 
definition "dim V = (SOME n. \<exists>B. B \<subseteq> V \<and> independent B \<and> V \<subseteq> span B \<and> (card B = n))"
  | 
| 
 | 
  1984  | 
  | 
| 
 | 
  1985  | 
lemma basis_exists:  "\<exists>B. (B :: ('a::euclidean_space) set) \<subseteq> V \<and> independent B \<and> V \<subseteq> span B \<and> (card B = dim V)"
 | 
| 
 | 
  1986  | 
unfolding dim_def some_eq_ex[of "\<lambda>n. \<exists>B. B \<subseteq> V \<and> independent B \<and> V \<subseteq> span B \<and> (card B = n)"]
  | 
| 
 | 
  1987  | 
using maximal_independent_subset[of V] independent_bound
  | 
| 
 | 
  1988  | 
by auto
  | 
| 
 | 
  1989  | 
  | 
| 
 | 
  1990  | 
text {* Consequences of independence or spanning for cardinality. *}
 | 
| 
 | 
  1991  | 
  | 
| 
 | 
  1992  | 
lemma independent_card_le_dim: 
  | 
| 
 | 
  1993  | 
  assumes "(B::('a::euclidean_space) set) \<subseteq> V" and "independent B" shows "card B \<le> dim V"
 | 
| 
 | 
  1994  | 
proof -
  | 
| 
 | 
  1995  | 
  from basis_exists[of V] `B \<subseteq> V`
  | 
| 
 | 
  1996  | 
  obtain B' where "independent B'" and "B \<subseteq> span B'" and "card B' = dim V" by blast
  | 
| 
 | 
  1997  | 
  with independent_span_bound[OF _ `independent B` `B \<subseteq> span B'`] independent_bound[of B']
  | 
| 
 | 
  1998  | 
  show ?thesis by auto
  | 
| 
 | 
  1999  | 
qed
  | 
| 
 | 
  2000  | 
  | 
| 
 | 
  2001  | 
lemma span_card_ge_dim:  "(B::('a::euclidean_space) set) \<subseteq> V \<Longrightarrow> V \<subseteq> span B \<Longrightarrow> finite B \<Longrightarrow> dim V \<le> card B"
 | 
| 
 | 
  2002  | 
  by (metis basis_exists[of V] independent_span_bound subset_trans)
  | 
| 
 | 
  2003  | 
  | 
| 
 | 
  2004  | 
lemma basis_card_eq_dim:
  | 
| 
 | 
  2005  | 
  "B \<subseteq> (V:: ('a::euclidean_space) set) \<Longrightarrow> V \<subseteq> span B \<Longrightarrow> independent B \<Longrightarrow> finite B \<and> card B = dim V"
 | 
| 
 | 
  2006  | 
  by (metis order_eq_iff independent_card_le_dim span_card_ge_dim independent_bound)
  | 
| 
 | 
  2007  | 
  | 
| 
 | 
  2008  | 
lemma dim_unique: "(B::('a::euclidean_space) set) \<subseteq> V \<Longrightarrow> V \<subseteq> span B \<Longrightarrow> independent B \<Longrightarrow> card B = n \<Longrightarrow> dim V = n"
 | 
| 
 | 
  2009  | 
  by (metis basis_card_eq_dim)
  | 
| 
 | 
  2010  | 
  | 
| 
 | 
  2011  | 
text {* More lemmas about dimension. *}
 | 
| 
 | 
  2012  | 
  | 
| 
 | 
  2013  | 
lemma dim_UNIV: "dim (UNIV :: ('a::euclidean_space) set) = DIM('a)"
 | 
| 
 | 
  2014  | 
  apply (rule dim_unique[of "(basis::nat=>'a) ` {..<DIM('a)}"])
 | 
| 
 | 
  2015  | 
  using independent_basis by auto
  | 
| 
 | 
  2016  | 
  | 
| 
 | 
  2017  | 
lemma dim_subset:
  | 
| 
 | 
  2018  | 
  "(S:: ('a::euclidean_space) set) \<subseteq> T \<Longrightarrow> dim S \<le> dim T"
 | 
| 
 | 
  2019  | 
  using basis_exists[of T] basis_exists[of S]
  | 
| 
 | 
  2020  | 
  by (metis independent_card_le_dim subset_trans)
  | 
| 
 | 
  2021  | 
  | 
| 
 | 
  2022  | 
lemma dim_subset_UNIV: "dim (S:: ('a::euclidean_space) set) \<le> DIM('a)"
 | 
| 
 | 
  2023  | 
  by (metis dim_subset subset_UNIV dim_UNIV)
  | 
| 
 | 
  2024  | 
  | 
| 
 | 
  2025  | 
text {* Converses to those. *}
 | 
| 
 | 
  2026  | 
  | 
| 
 | 
  2027  | 
lemma card_ge_dim_independent:
  | 
| 
 | 
  2028  | 
  assumes BV:"(B::('a::euclidean_space) set) \<subseteq> V" and iB:"independent B" and dVB:"dim V \<le> card B"
 | 
| 
 | 
  2029  | 
  shows "V \<subseteq> span B"
  | 
| 
 | 
  2030  | 
proof-
  | 
| 
 | 
  2031  | 
  {fix a assume aV: "a \<in> V"
 | 
| 
 | 
  2032  | 
    {assume aB: "a \<notin> span B"
 | 
| 
 | 
  2033  | 
      then have iaB: "independent (insert a B)" using iB aV  BV by (simp add: independent_insert)
  | 
| 
 | 
  2034  | 
      from aV BV have th0: "insert a B \<subseteq> V" by blast
  | 
| 
 | 
  2035  | 
      from aB have "a \<notin>B" by (auto simp add: span_superset)
  | 
| 
 | 
  2036  | 
      with independent_card_le_dim[OF th0 iaB] dVB independent_bound[OF iB] have False by auto }
  | 
| 
 | 
  2037  | 
    then have "a \<in> span B"  by blast}
  | 
| 
 | 
  2038  | 
  then show ?thesis by blast
  | 
| 
 | 
  2039  | 
qed
  | 
| 
 | 
  2040  | 
  | 
| 
 | 
  2041  | 
lemma card_le_dim_spanning:
  | 
| 
 | 
  2042  | 
  assumes BV: "(B:: ('a::euclidean_space) set) \<subseteq> V" and VB: "V \<subseteq> span B"
 | 
| 
 | 
  2043  | 
  and fB: "finite B" and dVB: "dim V \<ge> card B"
  | 
| 
 | 
  2044  | 
  shows "independent B"
  | 
| 
 | 
  2045  | 
proof-
  | 
| 
 | 
  2046  | 
  {fix a assume a: "a \<in> B" "a \<in> span (B -{a})"
 | 
| 
 | 
  2047  | 
    from a fB have c0: "card B \<noteq> 0" by auto
  | 
| 
 | 
  2048  | 
    from a fB have cb: "card (B -{a}) = card B - 1" by auto
 | 
| 
 | 
  2049  | 
    from BV a have th0: "B -{a} \<subseteq> V" by blast
 | 
| 
 | 
  2050  | 
    {fix x assume x: "x \<in> V"
 | 
| 
 | 
  2051  | 
      from a have eq: "insert a (B -{a}) = B" by blast
 | 
| 
 | 
  2052  | 
      from x VB have x': "x \<in> span B" by blast
  | 
| 
 | 
  2053  | 
      from span_trans[OF a(2), unfolded eq, OF x']
  | 
| 
 | 
  2054  | 
      have "x \<in> span (B -{a})" . }
 | 
| 
 | 
  2055  | 
    then have th1: "V \<subseteq> span (B -{a})" by blast
 | 
| 
 | 
  2056  | 
    have th2: "finite (B -{a})" using fB by auto
 | 
| 
 | 
  2057  | 
    from span_card_ge_dim[OF th0 th1 th2]
  | 
| 
 | 
  2058  | 
    have c: "dim V \<le> card (B -{a})" .
 | 
| 
 | 
  2059  | 
    from c c0 dVB cb have False by simp}
  | 
| 
 | 
  2060  | 
  then show ?thesis unfolding dependent_def by blast
  | 
| 
 | 
  2061  | 
qed
  | 
| 
 | 
  2062  | 
  | 
| 
 | 
  2063  | 
lemma card_eq_dim: "(B:: ('a::euclidean_space) set) \<subseteq> V \<Longrightarrow> card B = dim V \<Longrightarrow> finite B \<Longrightarrow> independent B \<longleftrightarrow> V \<subseteq> span B"
 | 
| 
 | 
  2064  | 
  by (metis order_eq_iff card_le_dim_spanning
  | 
| 
 | 
  2065  | 
    card_ge_dim_independent)
  | 
| 
 | 
  2066  | 
  | 
| 
 | 
  2067  | 
text {* More general size bound lemmas. *}
 | 
| 
 | 
  2068  | 
  | 
| 
 | 
  2069  | 
lemma independent_bound_general:
  | 
| 
 | 
  2070  | 
  "independent (S:: ('a::euclidean_space) set) \<Longrightarrow> finite S \<and> card S \<le> dim S"
 | 
| 
 | 
  2071  | 
  by (metis independent_card_le_dim independent_bound subset_refl)
  | 
| 
 | 
  2072  | 
  | 
| 
 | 
  2073  | 
lemma dependent_biggerset_general: "(finite (S:: ('a::euclidean_space) set) \<Longrightarrow> card S > dim S) \<Longrightarrow> dependent S"
 | 
| 
 | 
  2074  | 
  using independent_bound_general[of S] by (metis linorder_not_le)
  | 
| 
 | 
  2075  | 
  | 
| 
 | 
  2076  | 
lemma dim_span: "dim (span (S:: ('a::euclidean_space) set)) = dim S"
 | 
| 
 | 
  2077  | 
proof-
  | 
| 
 | 
  2078  | 
  have th0: "dim S \<le> dim (span S)"
  | 
| 
 | 
  2079  | 
    by (auto simp add: subset_eq intro: dim_subset span_superset)
  | 
| 
 | 
  2080  | 
  from basis_exists[of S]
  | 
| 
 | 
  2081  | 
  obtain B where B: "B \<subseteq> S" "independent B" "S \<subseteq> span B" "card B = dim S" by blast
  | 
| 
 | 
  2082  | 
  from B have fB: "finite B" "card B = dim S" using independent_bound by blast+
  | 
| 
 | 
  2083  | 
  have bSS: "B \<subseteq> span S" using B(1) by (metis subset_eq span_inc)
  | 
| 
 | 
  2084  | 
  have sssB: "span S \<subseteq> span B" using span_mono[OF B(3)] by (simp add: span_span)
  | 
| 
 | 
  2085  | 
  from span_card_ge_dim[OF bSS sssB fB(1)] th0 show ?thesis
  | 
| 
 | 
  2086  | 
    using fB(2)  by arith
  | 
| 
 | 
  2087  | 
qed
  | 
| 
 | 
  2088  | 
  | 
| 
 | 
  2089  | 
lemma subset_le_dim: "(S:: ('a::euclidean_space) set) \<subseteq> span T \<Longrightarrow> dim S \<le> dim T"
 | 
| 
 | 
  2090  | 
  by (metis dim_span dim_subset)
  | 
| 
 | 
  2091  | 
  | 
| 
 | 
  2092  | 
lemma span_eq_dim: "span (S:: ('a::euclidean_space) set) = span T ==> dim S = dim T"
 | 
| 
 | 
  2093  | 
  by (metis dim_span)
  | 
| 
 | 
  2094  | 
  | 
| 
 | 
  2095  | 
lemma spans_image:
  | 
| 
 | 
  2096  | 
  assumes lf: "linear f" and VB: "V \<subseteq> span B"
  | 
| 
 | 
  2097  | 
  shows "f ` V \<subseteq> span (f ` B)"
  | 
| 
 | 
  2098  | 
  unfolding span_linear_image[OF lf]
  | 
| 
 | 
  2099  | 
  by (metis VB image_mono)
  | 
| 
 | 
  2100  | 
  | 
| 
 | 
  2101  | 
lemma dim_image_le:
  | 
| 
 | 
  2102  | 
  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
  | 
| 
 | 
  2103  | 
  assumes lf: "linear f" shows "dim (f ` S) \<le> dim (S)"
  | 
| 
 | 
  2104  | 
proof-
  | 
| 
 | 
  2105  | 
  from basis_exists[of S] obtain B where
  | 
| 
 | 
  2106  | 
    B: "B \<subseteq> S" "independent B" "S \<subseteq> span B" "card B = dim S" by blast
  | 
| 
 | 
  2107  | 
  from B have fB: "finite B" "card B = dim S" using independent_bound by blast+
  | 
| 
 | 
  2108  | 
  have "dim (f ` S) \<le> card (f ` B)"
  | 
| 
 | 
  2109  | 
    apply (rule span_card_ge_dim)
  | 
| 
 | 
  2110  | 
    using lf B fB by (auto simp add: span_linear_image spans_image subset_image_iff)
  | 
| 
 | 
  2111  | 
  also have "\<dots> \<le> dim S" using card_image_le[OF fB(1)] fB by simp
  | 
| 
 | 
  2112  | 
  finally show ?thesis .
  | 
| 
 | 
  2113  | 
qed
  | 
| 
 | 
  2114  | 
  | 
| 
 | 
  2115  | 
text {* Relation between bases and injectivity/surjectivity of map. *}
 | 
| 
 | 
  2116  | 
  | 
| 
 | 
  2117  | 
lemma spanning_surjective_image:
  | 
| 
 | 
  2118  | 
  assumes us: "UNIV \<subseteq> span S"
  | 
| 
 | 
  2119  | 
  and lf: "linear f" and sf: "surj f"
  | 
| 
 | 
  2120  | 
  shows "UNIV \<subseteq> span (f ` S)"
  | 
| 
 | 
  2121  | 
proof-
  | 
| 
 | 
  2122  | 
  have "UNIV \<subseteq> f ` UNIV" using sf by (auto simp add: surj_def)
  | 
| 
 | 
  2123  | 
  also have " \<dots> \<subseteq> span (f ` S)" using spans_image[OF lf us] .
  | 
| 
 | 
  2124  | 
finally show ?thesis .
  | 
| 
 | 
  2125  | 
qed
  | 
| 
 | 
  2126  | 
  | 
| 
 | 
  2127  | 
lemma independent_injective_image:
  | 
| 
 | 
  2128  | 
  assumes iS: "independent S" and lf: "linear f" and fi: "inj f"
  | 
| 
 | 
  2129  | 
  shows "independent (f ` S)"
  | 
| 
 | 
  2130  | 
proof-
  | 
| 
 | 
  2131  | 
  {fix a assume a: "a \<in> S" "f a \<in> span (f ` S - {f a})"
 | 
| 
 | 
  2132  | 
    have eq: "f ` S - {f a} = f ` (S - {a})" using fi
 | 
| 
 | 
  2133  | 
      by (auto simp add: inj_on_def)
  | 
| 
 | 
  2134  | 
    from a have "f a \<in> f ` span (S -{a})"
 | 
| 
 | 
  2135  | 
      unfolding eq span_linear_image[OF lf, of "S - {a}"]  by blast
 | 
| 
 | 
  2136  | 
    hence "a \<in> span (S -{a})" using fi by (auto simp add: inj_on_def)
 | 
| 
 | 
  2137  | 
    with a(1) iS  have False by (simp add: dependent_def) }
  | 
| 
 | 
  2138  | 
  then show ?thesis unfolding dependent_def by blast
  | 
| 
 | 
  2139  | 
qed
  | 
| 
 | 
  2140  | 
  | 
| 
 | 
  2141  | 
text {* Picking an orthogonal replacement for a spanning set. *}
 | 
| 
 | 
  2142  | 
  | 
| 
 | 
  2143  | 
    (* FIXME : Move to some general theory ?*)
  | 
| 
 | 
  2144  | 
definition "pairwise R S \<longleftrightarrow> (\<forall>x \<in> S. \<forall>y\<in> S. x\<noteq>y \<longrightarrow> R x y)"
  | 
| 
 | 
  2145  | 
  | 
| 
 | 
  2146  | 
lemma vector_sub_project_orthogonal: "(b::'a::euclidean_space) \<bullet> (x - ((b \<bullet> x) / (b \<bullet> b)) *\<^sub>R b) = 0"
  | 
| 
 | 
  2147  | 
  unfolding inner_simps by auto
  | 
| 
 | 
  2148  | 
  | 
| 
 | 
  2149  | 
lemma basis_orthogonal:
  | 
| 
 | 
  2150  | 
  fixes B :: "('a::euclidean_space) set"
 | 
| 
 | 
  2151  | 
  assumes fB: "finite B"
  | 
| 
 | 
  2152  | 
  shows "\<exists>C. finite C \<and> card C \<le> card B \<and> span C = span B \<and> pairwise orthogonal C"
  | 
| 
 | 
  2153  | 
  (is " \<exists>C. ?P B C")
  | 
| 
 | 
  2154  | 
proof(induct rule: finite_induct[OF fB])
  | 
| 
 | 
  2155  | 
  case 1 thus ?case apply (rule exI[where x="{}"]) by (auto simp add: pairwise_def)
 | 
| 
 | 
  2156  | 
next
  | 
| 
 | 
  2157  | 
  case (2 a B)
  | 
| 
 | 
  2158  | 
  note fB = `finite B` and aB = `a \<notin> B`
  | 
| 
 | 
  2159  | 
  from `\<exists>C. finite C \<and> card C \<le> card B \<and> span C = span B \<and> pairwise orthogonal C`
  | 
| 
 | 
  2160  | 
  obtain C where C: "finite C" "card C \<le> card B"
  | 
| 
 | 
  2161  | 
    "span C = span B" "pairwise orthogonal C" by blast
  | 
| 
 | 
  2162  | 
  let ?a = "a - setsum (\<lambda>x. (x \<bullet> a / (x \<bullet> x)) *\<^sub>R x) C"
  | 
| 
 | 
  2163  | 
  let ?C = "insert ?a C"
  | 
| 
 | 
  2164  | 
  from C(1) have fC: "finite ?C" by simp
  | 
| 
 | 
  2165  | 
  from fB aB C(1,2) have cC: "card ?C \<le> card (insert a B)" by (simp add: card_insert_if)
  | 
| 
 | 
  2166  | 
  {fix x k
 | 
| 
 | 
  2167  | 
    have th0: "\<And>(a::'a) b c. a - (b - c) = c + (a - b)" by (simp add: field_simps)
  | 
| 
 | 
  2168  | 
    have "x - k *\<^sub>R (a - (\<Sum>x\<in>C. (x \<bullet> a / (x \<bullet> x)) *\<^sub>R x)) \<in> span C \<longleftrightarrow> x - k *\<^sub>R a \<in> span C"
  | 
| 
 | 
  2169  | 
      apply (simp only: scaleR_right_diff_distrib th0)
  | 
| 
 | 
  2170  | 
      apply (rule span_add_eq)
  | 
| 
 | 
  2171  | 
      apply (rule span_mul)
  | 
| 
 | 
  2172  | 
      apply (rule span_setsum[OF C(1)])
  | 
| 
 | 
  2173  | 
      apply clarify
  | 
| 
 | 
  2174  | 
      apply (rule span_mul)
  | 
| 
 | 
  2175  | 
      by (rule span_superset)}
  | 
| 
 | 
  2176  | 
  then have SC: "span ?C = span (insert a B)"
  | 
| 
 | 
  2177  | 
    unfolding set_eq_iff span_breakdown_eq C(3)[symmetric] by auto
  | 
| 
 | 
  2178  | 
  thm pairwise_def
  | 
| 
 | 
  2179  | 
  {fix x y assume xC: "x \<in> ?C" and yC: "y \<in> ?C" and xy: "x \<noteq> y"
 | 
| 
 | 
  2180  | 
    {assume xa: "x = ?a" and ya: "y = ?a"
 | 
| 
 | 
  2181  | 
      have "orthogonal x y" using xa ya xy by blast}
  | 
| 
 | 
  2182  | 
    moreover
  | 
| 
 | 
  2183  | 
    {assume xa: "x = ?a" and ya: "y \<noteq> ?a" "y \<in> C"
 | 
| 
 | 
  2184  | 
      from ya have Cy: "C = insert y (C - {y})" by blast
 | 
| 
 | 
  2185  | 
      have fth: "finite (C - {y})" using C by simp
 | 
| 
 | 
  2186  | 
      have "orthogonal x y"
  | 
| 
 | 
  2187  | 
        using xa ya
  | 
| 
 | 
  2188  | 
        unfolding orthogonal_def xa inner_simps diff_eq_0_iff_eq
  | 
| 
 | 
  2189  | 
        apply simp
  | 
| 
 | 
  2190  | 
        apply (subst Cy)
  | 
| 
 | 
  2191  | 
        using C(1) fth
  | 
| 
 | 
  2192  | 
        apply (simp only: setsum_clauses)
  | 
| 
 | 
  2193  | 
        apply (auto simp add: inner_simps inner_commute[of y a] dot_lsum[OF fth])
  | 
| 
 | 
  2194  | 
        apply (rule setsum_0')
  | 
| 
 | 
  2195  | 
        apply clarsimp
  | 
| 
 | 
  2196  | 
        apply (rule C(4)[unfolded pairwise_def orthogonal_def, rule_format])
  | 
| 
 | 
  2197  | 
        by auto}
  | 
| 
 | 
  2198  | 
    moreover
  | 
| 
 | 
  2199  | 
    {assume xa: "x \<noteq> ?a" "x \<in> C" and ya: "y = ?a"
 | 
| 
 | 
  2200  | 
      from xa have Cx: "C = insert x (C - {x})" by blast
 | 
| 
 | 
  2201  | 
      have fth: "finite (C - {x})" using C by simp
 | 
| 
 | 
  2202  | 
      have "orthogonal x y"
  | 
| 
 | 
  2203  | 
        using xa ya
  | 
| 
 | 
  2204  | 
        unfolding orthogonal_def ya inner_simps diff_eq_0_iff_eq
  | 
| 
 | 
  2205  | 
        apply simp
  | 
| 
 | 
  2206  | 
        apply (subst Cx)
  | 
| 
 | 
  2207  | 
        using C(1) fth
  | 
| 
 | 
  2208  | 
        apply (simp only: setsum_clauses)
  | 
| 
 | 
  2209  | 
        apply (subst inner_commute[of x])
  | 
| 
 | 
  2210  | 
        apply (auto simp add: inner_simps inner_commute[of x a] dot_rsum[OF fth])
  | 
| 
 | 
  2211  | 
        apply (rule setsum_0')
  | 
| 
 | 
  2212  | 
        apply clarsimp
  | 
| 
 | 
  2213  | 
        apply (rule C(4)[unfolded pairwise_def orthogonal_def, rule_format])
  | 
| 
 | 
  2214  | 
        by auto}
  | 
| 
 | 
  2215  | 
    moreover
  | 
| 
 | 
  2216  | 
    {assume xa: "x \<in> C" and ya: "y \<in> C"
 | 
| 
 | 
  2217  | 
      have "orthogonal x y" using xa ya xy C(4) unfolding pairwise_def by blast}
  | 
| 
 | 
  2218  | 
    ultimately have "orthogonal x y" using xC yC by blast}
  | 
| 
 | 
  2219  | 
  then have CPO: "pairwise orthogonal ?C" unfolding pairwise_def by blast
  | 
| 
 | 
  2220  | 
  from fC cC SC CPO have "?P (insert a B) ?C" by blast
  | 
| 
 | 
  2221  | 
  then show ?case by blast
  | 
| 
 | 
  2222  | 
qed
  | 
| 
 | 
  2223  | 
  | 
| 
 | 
  2224  | 
lemma orthogonal_basis_exists:
  | 
| 
 | 
  2225  | 
  fixes V :: "('a::euclidean_space) set"
 | 
| 
 | 
  2226  | 
  shows "\<exists>B. independent B \<and> B \<subseteq> span V \<and> V \<subseteq> span B \<and> (card B = dim V) \<and> pairwise orthogonal B"
  | 
| 
 | 
  2227  | 
proof-
  | 
| 
 | 
  2228  | 
  from basis_exists[of V] obtain B where B: "B \<subseteq> V" "independent B" "V \<subseteq> span B" "card B = dim V" by blast
  | 
| 
 | 
  2229  | 
  from B have fB: "finite B" "card B = dim V" using independent_bound by auto
  | 
| 
 | 
  2230  | 
  from basis_orthogonal[OF fB(1)] obtain C where
  | 
| 
 | 
  2231  | 
    C: "finite C" "card C \<le> card B" "span C = span B" "pairwise orthogonal C" by blast
  | 
| 
 | 
  2232  | 
  from C B
  | 
| 
 | 
  2233  | 
  have CSV: "C \<subseteq> span V" by (metis span_inc span_mono subset_trans)
  | 
| 
 | 
  2234  | 
  from span_mono[OF B(3)]  C have SVC: "span V \<subseteq> span C" by (simp add: span_span)
  | 
| 
 | 
  2235  | 
  from card_le_dim_spanning[OF CSV SVC C(1)] C(2,3) fB
  | 
| 
 | 
  2236  | 
  have iC: "independent C" by (simp add: dim_span)
  | 
| 
 | 
  2237  | 
  from C fB have "card C \<le> dim V" by simp
  | 
| 
 | 
  2238  | 
  moreover have "dim V \<le> card C" using span_card_ge_dim[OF CSV SVC C(1)]
  | 
| 
 | 
  2239  | 
    by (simp add: dim_span)
  | 
| 
 | 
  2240  | 
  ultimately have CdV: "card C = dim V" using C(1) by simp
  | 
| 
 | 
  2241  | 
  from C B CSV CdV iC show ?thesis by auto
  | 
| 
 | 
  2242  | 
qed
  | 
| 
 | 
  2243  | 
  | 
| 
 | 
  2244  | 
lemma span_eq: "span S = span T \<longleftrightarrow> S \<subseteq> span T \<and> T \<subseteq> span S"
  | 
| 
 | 
  2245  | 
  using span_inc[unfolded subset_eq] using span_mono[of T "span S"] span_mono[of S "span T"]
  | 
| 
 | 
  2246  | 
  by(auto simp add: span_span)
  | 
| 
 | 
  2247  | 
  | 
| 
 | 
  2248  | 
text {* Low-dimensional subset is in a hyperplane (weak orthogonal complement). *}
 | 
| 
 | 
  2249  | 
  | 
| 
 | 
  2250  | 
lemma span_not_univ_orthogonal: fixes S::"('a::euclidean_space) set"
 | 
| 
 | 
  2251  | 
  assumes sU: "span S \<noteq> UNIV"
  | 
| 
 | 
  2252  | 
  shows "\<exists>(a::'a). a \<noteq>0 \<and> (\<forall>x \<in> span S. a \<bullet> x = 0)"
  | 
| 
 | 
  2253  | 
proof-
  | 
| 
 | 
  2254  | 
  from sU obtain a where a: "a \<notin> span S" by blast
  | 
| 
 | 
  2255  | 
  from orthogonal_basis_exists obtain B where
  | 
| 
 | 
  2256  | 
    B: "independent B" "B \<subseteq> span S" "S \<subseteq> span B" "card B = dim S" "pairwise orthogonal B"
  | 
| 
 | 
  2257  | 
    by blast
  | 
| 
 | 
  2258  | 
  from B have fB: "finite B" "card B = dim S" using independent_bound by auto
  | 
| 
 | 
  2259  | 
  from span_mono[OF B(2)] span_mono[OF B(3)]
  | 
| 
 | 
  2260  | 
  have sSB: "span S = span B" by (simp add: span_span)
  | 
| 
 | 
  2261  | 
  let ?a = "a - setsum (\<lambda>b. (a \<bullet> b / (b \<bullet> b)) *\<^sub>R b) B"
  | 
| 
 | 
  2262  | 
  have "setsum (\<lambda>b. (a \<bullet> b / (b \<bullet> b)) *\<^sub>R b) B \<in> span S"
  | 
| 
 | 
  2263  | 
    unfolding sSB
  | 
| 
 | 
  2264  | 
    apply (rule span_setsum[OF fB(1)])
  | 
| 
 | 
  2265  | 
    apply clarsimp
  | 
| 
 | 
  2266  | 
    apply (rule span_mul)
  | 
| 
 | 
  2267  | 
    by (rule span_superset)
  | 
| 
 | 
  2268  | 
  with a have a0:"?a  \<noteq> 0" by auto
  | 
| 
 | 
  2269  | 
  have "\<forall>x\<in>span B. ?a \<bullet> x = 0"
  | 
| 
 | 
  2270  | 
  proof(rule span_induct')
  | 
| 
 | 
  2271  | 
    show "subspace (\<lambda>x. ?a \<bullet> x = 0)" by (auto simp add: subspace_def mem_def inner_simps)
  | 
| 
 | 
  2272  | 
next
  | 
| 
 | 
  2273  | 
    {fix x assume x: "x \<in> B"
 | 
| 
 | 
  2274  | 
      from x have B': "B = insert x (B - {x})" by blast
 | 
| 
 | 
  2275  | 
      have fth: "finite (B - {x})" using fB by simp
 | 
| 
 | 
  2276  | 
      have "?a \<bullet> x = 0"
  | 
| 
 | 
  2277  | 
        apply (subst B') using fB fth
  | 
| 
 | 
  2278  | 
        unfolding setsum_clauses(2)[OF fth]
  | 
| 
 | 
  2279  | 
        apply simp unfolding inner_simps
  | 
| 
 | 
  2280  | 
        apply (clarsimp simp add: inner_simps dot_lsum)
  | 
| 
 | 
  2281  | 
        apply (rule setsum_0', rule ballI)
  | 
| 
 | 
  2282  | 
        unfolding inner_commute
  | 
| 
 | 
  2283  | 
        by (auto simp add: x field_simps intro: B(5)[unfolded pairwise_def orthogonal_def, rule_format])}
  | 
| 
 | 
  2284  | 
    then show "\<forall>x \<in> B. ?a \<bullet> x = 0" by blast
  | 
| 
 | 
  2285  | 
  qed
  | 
| 
 | 
  2286  | 
  with a0 show ?thesis unfolding sSB by (auto intro: exI[where x="?a"])
  | 
| 
 | 
  2287  | 
qed
  | 
| 
 | 
  2288  | 
  | 
| 
 | 
  2289  | 
lemma span_not_univ_subset_hyperplane:
  | 
| 
 | 
  2290  | 
  assumes SU: "span S \<noteq> (UNIV ::('a::euclidean_space) set)"
 | 
| 
 | 
  2291  | 
  shows "\<exists> a. a \<noteq>0 \<and> span S \<subseteq> {x. a \<bullet> x = 0}"
 | 
| 
 | 
  2292  | 
  using span_not_univ_orthogonal[OF SU] by auto
  | 
| 
 | 
  2293  | 
  | 
| 
 | 
  2294  | 
lemma lowdim_subset_hyperplane: fixes S::"('a::euclidean_space) set"
 | 
| 
 | 
  2295  | 
  assumes d: "dim S < DIM('a)"
 | 
| 
 | 
  2296  | 
  shows "\<exists>(a::'a). a  \<noteq> 0 \<and> span S \<subseteq> {x. a \<bullet> x = 0}"
 | 
| 
 | 
  2297  | 
proof-
  | 
| 
 | 
  2298  | 
  {assume "span S = UNIV"
 | 
| 
 | 
  2299  | 
    hence "dim (span S) = dim (UNIV :: ('a) set)" by simp
 | 
| 
 | 
  2300  | 
    hence "dim S = DIM('a)" by (simp add: dim_span dim_UNIV)
 | 
| 
 | 
  2301  | 
    with d have False by arith}
  | 
| 
 | 
  2302  | 
  hence th: "span S \<noteq> UNIV" by blast
  | 
| 
 | 
  2303  | 
  from span_not_univ_subset_hyperplane[OF th] show ?thesis .
  | 
| 
 | 
  2304  | 
qed
  | 
| 
 | 
  2305  | 
  | 
| 
 | 
  2306  | 
text {* We can extend a linear basis-basis injection to the whole set. *}
 | 
| 
 | 
  2307  | 
  | 
| 
 | 
  2308  | 
lemma linear_indep_image_lemma:
  | 
| 
 | 
  2309  | 
  assumes lf: "linear f" and fB: "finite B"
  | 
| 
 | 
  2310  | 
  and ifB: "independent (f ` B)"
  | 
| 
 | 
  2311  | 
  and fi: "inj_on f B" and xsB: "x \<in> span B"
  | 
| 
 | 
  2312  | 
  and fx: "f x = 0"
  | 
| 
 | 
  2313  | 
  shows "x = 0"
  | 
| 
 | 
  2314  | 
  using fB ifB fi xsB fx
  | 
| 
 | 
  2315  | 
proof(induct arbitrary: x rule: finite_induct[OF fB])
  | 
| 
44142
 | 
  2316  | 
  case 1 thus ?case by auto
  | 
| 
44133
 | 
  2317  | 
next
  | 
| 
 | 
  2318  | 
  case (2 a b x)
  | 
| 
 | 
  2319  | 
  have fb: "finite b" using "2.prems" by simp
  | 
| 
 | 
  2320  | 
  have th0: "f ` b \<subseteq> f ` (insert a b)"
  | 
| 
 | 
  2321  | 
    apply (rule image_mono) by blast
  | 
| 
 | 
  2322  | 
  from independent_mono[ OF "2.prems"(2) th0]
  | 
| 
 | 
  2323  | 
  have ifb: "independent (f ` b)"  .
  | 
| 
 | 
  2324  | 
  have fib: "inj_on f b"
  | 
| 
 | 
  2325  | 
    apply (rule subset_inj_on [OF "2.prems"(3)])
  | 
| 
 | 
  2326  | 
    by blast
  | 
| 
 | 
  2327  | 
  from span_breakdown[of a "insert a b", simplified, OF "2.prems"(4)]
  | 
| 
 | 
  2328  | 
  obtain k where k: "x - k*\<^sub>R a \<in> span (b -{a})" by blast
 | 
| 
 | 
  2329  | 
  have "f (x - k*\<^sub>R a) \<in> span (f ` b)"
  | 
| 
 | 
  2330  | 
    unfolding span_linear_image[OF lf]
  | 
| 
 | 
  2331  | 
    apply (rule imageI)
  | 
| 
 | 
  2332  | 
    using k span_mono[of "b-{a}" b] by blast
 | 
| 
 | 
  2333  | 
  hence "f x - k*\<^sub>R f a \<in> span (f ` b)"
  | 
| 
 | 
  2334  | 
    by (simp add: linear_sub[OF lf] linear_cmul[OF lf])
  | 
| 
 | 
  2335  | 
  hence th: "-k *\<^sub>R f a \<in> span (f ` b)"
  | 
| 
 | 
  2336  | 
    using "2.prems"(5) by simp
  | 
| 
 | 
  2337  | 
  {assume k0: "k = 0"
 | 
| 
 | 
  2338  | 
    from k0 k have "x \<in> span (b -{a})" by simp
 | 
| 
 | 
  2339  | 
    then have "x \<in> span b" using span_mono[of "b-{a}" b]
 | 
| 
 | 
  2340  | 
      by blast}
  | 
| 
 | 
  2341  | 
  moreover
  | 
| 
 | 
  2342  | 
  {assume k0: "k \<noteq> 0"
 | 
| 
 | 
  2343  | 
    from span_mul[OF th, of "- 1/ k"] k0
  | 
| 
 | 
  2344  | 
    have th1: "f a \<in> span (f ` b)"
  | 
| 
 | 
  2345  | 
      by auto
  | 
| 
 | 
  2346  | 
    from inj_on_image_set_diff[OF "2.prems"(3), of "insert a b " "{a}", symmetric]
 | 
| 
 | 
  2347  | 
    have tha: "f ` insert a b - f ` {a} = f ` (insert a b - {a})" by blast
 | 
| 
 | 
  2348  | 
    from "2.prems"(2) [unfolded dependent_def bex_simps(8), rule_format, of "f a"]
  | 
| 
 | 
  2349  | 
    have "f a \<notin> span (f ` b)" using tha
  | 
| 
 | 
  2350  | 
      using "2.hyps"(2)
  | 
| 
 | 
  2351  | 
      "2.prems"(3) by auto
  | 
| 
 | 
  2352  | 
    with th1 have False by blast
  | 
| 
 | 
  2353  | 
    then have "x \<in> span b" by blast}
  | 
| 
 | 
  2354  | 
  ultimately have xsb: "x \<in> span b" by blast
  | 
| 
 | 
  2355  | 
  from "2.hyps"(3)[OF fb ifb fib xsb "2.prems"(5)]
  | 
| 
 | 
  2356  | 
  show "x = 0" .
  | 
| 
 | 
  2357  | 
qed
  | 
| 
 | 
  2358  | 
  | 
| 
 | 
  2359  | 
text {* We can extend a linear mapping from basis. *}
 | 
| 
 | 
  2360  | 
  | 
| 
 | 
  2361  | 
lemma linear_independent_extend_lemma:
  | 
| 
 | 
  2362  | 
  fixes f :: "'a::real_vector \<Rightarrow> 'b::real_vector"
  | 
| 
 | 
  2363  | 
  assumes fi: "finite B" and ib: "independent B"
  | 
| 
 | 
  2364  | 
  shows "\<exists>g. (\<forall>x\<in> span B. \<forall>y\<in> span B. g (x + y) = g x + g y)
  | 
| 
 | 
  2365  | 
           \<and> (\<forall>x\<in> span B. \<forall>c. g (c*\<^sub>R x) = c *\<^sub>R g x)
  | 
| 
 | 
  2366  | 
           \<and> (\<forall>x\<in> B. g x = f x)"
  | 
| 
 | 
  2367  | 
using ib fi
  | 
| 
 | 
  2368  | 
proof(induct rule: finite_induct[OF fi])
  | 
| 
44142
 | 
  2369  | 
  case 1 thus ?case by auto
  | 
| 
44133
 | 
  2370  | 
next
  | 
| 
 | 
  2371  | 
  case (2 a b)
  | 
| 
 | 
  2372  | 
  from "2.prems" "2.hyps" have ibf: "independent b" "finite b"
  | 
| 
 | 
  2373  | 
    by (simp_all add: independent_insert)
  | 
| 
 | 
  2374  | 
  from "2.hyps"(3)[OF ibf] obtain g where
  | 
| 
 | 
  2375  | 
    g: "\<forall>x\<in>span b. \<forall>y\<in>span b. g (x + y) = g x + g y"
  | 
| 
 | 
  2376  | 
    "\<forall>x\<in>span b. \<forall>c. g (c *\<^sub>R x) = c *\<^sub>R g x" "\<forall>x\<in>b. g x = f x" by blast
  | 
| 
 | 
  2377  | 
  let ?h = "\<lambda>z. SOME k. (z - k *\<^sub>R a) \<in> span b"
  | 
| 
 | 
  2378  | 
  {fix z assume z: "z \<in> span (insert a b)"
 | 
| 
 | 
  2379  | 
    have th0: "z - ?h z *\<^sub>R a \<in> span b"
  | 
| 
 | 
  2380  | 
      apply (rule someI_ex)
  | 
| 
 | 
  2381  | 
      unfolding span_breakdown_eq[symmetric]
  | 
| 
 | 
  2382  | 
      using z .
  | 
| 
 | 
  2383  | 
    {fix k assume k: "z - k *\<^sub>R a \<in> span b"
 | 
| 
 | 
  2384  | 
      have eq: "z - ?h z *\<^sub>R a - (z - k*\<^sub>R a) = (k - ?h z) *\<^sub>R a"
  | 
| 
 | 
  2385  | 
        by (simp add: field_simps scaleR_left_distrib [symmetric])
  | 
| 
 | 
  2386  | 
      from span_sub[OF th0 k]
  | 
| 
 | 
  2387  | 
      have khz: "(k - ?h z) *\<^sub>R a \<in> span b" by (simp add: eq)
  | 
| 
 | 
  2388  | 
      {assume "k \<noteq> ?h z" hence k0: "k - ?h z \<noteq> 0" by simp
 | 
| 
 | 
  2389  | 
        from k0 span_mul[OF khz, of "1 /(k - ?h z)"]
  | 
| 
 | 
  2390  | 
        have "a \<in> span b" by simp
  | 
| 
 | 
  2391  | 
        with "2.prems"(1) "2.hyps"(2) have False
  | 
| 
 | 
  2392  | 
          by (auto simp add: dependent_def)}
  | 
| 
 | 
  2393  | 
      then have "k = ?h z" by blast}
  | 
| 
 | 
  2394  | 
    with th0 have "z - ?h z *\<^sub>R a \<in> span b \<and> (\<forall>k. z - k *\<^sub>R a \<in> span b \<longrightarrow> k = ?h z)" by blast}
  | 
| 
 | 
  2395  | 
  note h = this
  | 
| 
 | 
  2396  | 
  let ?g = "\<lambda>z. ?h z *\<^sub>R f a + g (z - ?h z *\<^sub>R a)"
  | 
| 
 | 
  2397  | 
  {fix x y assume x: "x \<in> span (insert a b)" and y: "y \<in> span (insert a b)"
 | 
| 
 | 
  2398  | 
    have tha: "\<And>(x::'a) y a k l. (x + y) - (k + l) *\<^sub>R a = (x - k *\<^sub>R a) + (y - l *\<^sub>R a)"
  | 
| 
 | 
  2399  | 
      by (simp add: algebra_simps)
  | 
| 
 | 
  2400  | 
    have addh: "?h (x + y) = ?h x + ?h y"
  | 
| 
 | 
  2401  | 
      apply (rule conjunct2[OF h, rule_format, symmetric])
  | 
| 
 | 
  2402  | 
      apply (rule span_add[OF x y])
  | 
| 
 | 
  2403  | 
      unfolding tha
  | 
| 
 | 
  2404  | 
      by (metis span_add x y conjunct1[OF h, rule_format])
  | 
| 
 | 
  2405  | 
    have "?g (x + y) = ?g x + ?g y"
  | 
| 
 | 
  2406  | 
      unfolding addh tha
  | 
| 
 | 
  2407  | 
      g(1)[rule_format,OF conjunct1[OF h, OF x] conjunct1[OF h, OF y]]
  | 
| 
 | 
  2408  | 
      by (simp add: scaleR_left_distrib)}
  | 
| 
 | 
  2409  | 
  moreover
  | 
| 
 | 
  2410  | 
  {fix x:: "'a" and c:: real  assume x: "x \<in> span (insert a b)"
 | 
| 
 | 
  2411  | 
    have tha: "\<And>(x::'a) c k a. c *\<^sub>R x - (c * k) *\<^sub>R a = c *\<^sub>R (x - k *\<^sub>R a)"
  | 
| 
 | 
  2412  | 
      by (simp add: algebra_simps)
  | 
| 
 | 
  2413  | 
    have hc: "?h (c *\<^sub>R x) = c * ?h x"
  | 
| 
 | 
  2414  | 
      apply (rule conjunct2[OF h, rule_format, symmetric])
  | 
| 
 | 
  2415  | 
      apply (metis span_mul x)
  | 
| 
 | 
  2416  | 
      by (metis tha span_mul x conjunct1[OF h])
  | 
| 
 | 
  2417  | 
    have "?g (c *\<^sub>R x) = c*\<^sub>R ?g x"
  | 
| 
 | 
  2418  | 
      unfolding hc tha g(2)[rule_format, OF conjunct1[OF h, OF x]]
  | 
| 
 | 
  2419  | 
      by (simp add: algebra_simps)}
  | 
| 
 | 
  2420  | 
  moreover
  | 
| 
 | 
  2421  | 
  {fix x assume x: "x \<in> (insert a b)"
 | 
| 
 | 
  2422  | 
    {assume xa: "x = a"
 | 
| 
 | 
  2423  | 
      have ha1: "1 = ?h a"
  | 
| 
 | 
  2424  | 
        apply (rule conjunct2[OF h, rule_format])
  | 
| 
 | 
  2425  | 
        apply (metis span_superset insertI1)
  | 
| 
 | 
  2426  | 
        using conjunct1[OF h, OF span_superset, OF insertI1]
  | 
| 
 | 
  2427  | 
        by (auto simp add: span_0)
  | 
| 
 | 
  2428  | 
  | 
| 
 | 
  2429  | 
      from xa ha1[symmetric] have "?g x = f x"
  | 
| 
 | 
  2430  | 
        apply simp
  | 
| 
 | 
  2431  | 
        using g(2)[rule_format, OF span_0, of 0]
  | 
| 
 | 
  2432  | 
        by simp}
  | 
| 
 | 
  2433  | 
    moreover
  | 
| 
 | 
  2434  | 
    {assume xb: "x \<in> b"
 | 
| 
 | 
  2435  | 
      have h0: "0 = ?h x"
  | 
| 
 | 
  2436  | 
        apply (rule conjunct2[OF h, rule_format])
  | 
| 
 | 
  2437  | 
        apply (metis  span_superset x)
  | 
| 
 | 
  2438  | 
        apply simp
  | 
| 
 | 
  2439  | 
        apply (metis span_superset xb)
  | 
| 
 | 
  2440  | 
        done
  | 
| 
 | 
  2441  | 
      have "?g x = f x"
  | 
| 
 | 
  2442  | 
        by (simp add: h0[symmetric] g(3)[rule_format, OF xb])}
  | 
| 
 | 
  2443  | 
    ultimately have "?g x = f x" using x by blast }
  | 
| 
 | 
  2444  | 
  ultimately show ?case apply - apply (rule exI[where x="?g"]) by blast
  | 
| 
 | 
  2445  | 
qed
  | 
| 
 | 
  2446  | 
  | 
| 
 | 
  2447  | 
lemma linear_independent_extend:
  | 
| 
 | 
  2448  | 
  assumes iB: "independent (B:: ('a::euclidean_space) set)"
 | 
| 
 | 
  2449  | 
  shows "\<exists>g. linear g \<and> (\<forall>x\<in>B. g x = f x)"
  | 
| 
 | 
  2450  | 
proof-
  | 
| 
 | 
  2451  | 
  from maximal_independent_subset_extend[of B UNIV] iB
  | 
| 
 | 
  2452  | 
  obtain C where C: "B \<subseteq> C" "independent C" "\<And>x. x \<in> span C" by auto
  | 
| 
 | 
  2453  | 
  | 
| 
 | 
  2454  | 
  from C(2) independent_bound[of C] linear_independent_extend_lemma[of C f]
  | 
| 
 | 
  2455  | 
  obtain g where g: "(\<forall>x\<in> span C. \<forall>y\<in> span C. g (x + y) = g x + g y)
  | 
| 
 | 
  2456  | 
           \<and> (\<forall>x\<in> span C. \<forall>c. g (c*\<^sub>R x) = c *\<^sub>R g x)
  | 
| 
 | 
  2457  | 
           \<and> (\<forall>x\<in> C. g x = f x)" by blast
  | 
| 
 | 
  2458  | 
  from g show ?thesis unfolding linear_def using C
  | 
| 
 | 
  2459  | 
    apply clarsimp by blast
  | 
| 
 | 
  2460  | 
qed
  | 
| 
 | 
  2461  | 
  | 
| 
 | 
  2462  | 
text {* Can construct an isomorphism between spaces of same dimension. *}
 | 
| 
 | 
  2463  | 
  | 
| 
 | 
  2464  | 
lemma card_le_inj: assumes fA: "finite A" and fB: "finite B"
  | 
| 
 | 
  2465  | 
  and c: "card A \<le> card B" shows "(\<exists>f. f ` A \<subseteq> B \<and> inj_on f A)"
  | 
| 
 | 
  2466  | 
using fB c
  | 
| 
 | 
  2467  | 
proof(induct arbitrary: B rule: finite_induct[OF fA])
  | 
| 
 | 
  2468  | 
  case 1 thus ?case by simp
  | 
| 
 | 
  2469  | 
next
  | 
| 
 | 
  2470  | 
  case (2 x s t)
  | 
| 
 | 
  2471  | 
  thus ?case
  | 
| 
 | 
  2472  | 
  proof(induct rule: finite_induct[OF "2.prems"(1)])
  | 
| 
 | 
  2473  | 
    case 1    then show ?case by simp
  | 
| 
 | 
  2474  | 
  next
  | 
| 
 | 
  2475  | 
    case (2 y t)
  | 
| 
 | 
  2476  | 
    from "2.prems"(1,2,5) "2.hyps"(1,2) have cst:"card s \<le> card t" by simp
  | 
| 
 | 
  2477  | 
    from "2.prems"(3) [OF "2.hyps"(1) cst] obtain f where
  | 
| 
 | 
  2478  | 
      f: "f ` s \<subseteq> t \<and> inj_on f s" by blast
  | 
| 
 | 
  2479  | 
    from f "2.prems"(2) "2.hyps"(2) show ?case
  | 
| 
 | 
  2480  | 
      apply -
  | 
| 
 | 
  2481  | 
      apply (rule exI[where x = "\<lambda>z. if z = x then y else f z"])
  | 
| 
 | 
  2482  | 
      by (auto simp add: inj_on_def)
  | 
| 
 | 
  2483  | 
  qed
  | 
| 
 | 
  2484  | 
qed
  | 
| 
 | 
  2485  | 
  | 
| 
 | 
  2486  | 
lemma card_subset_eq: assumes fB: "finite B" and AB: "A \<subseteq> B" and
  | 
| 
 | 
  2487  | 
  c: "card A = card B"
  | 
| 
 | 
  2488  | 
  shows "A = B"
  | 
| 
 | 
  2489  | 
proof-
  | 
| 
 | 
  2490  | 
  from fB AB have fA: "finite A" by (auto intro: finite_subset)
  | 
| 
 | 
  2491  | 
  from fA fB have fBA: "finite (B - A)" by auto
  | 
| 
 | 
  2492  | 
  have e: "A \<inter> (B - A) = {}" by blast
 | 
| 
 | 
  2493  | 
  have eq: "A \<union> (B - A) = B" using AB by blast
  | 
| 
 | 
  2494  | 
  from card_Un_disjoint[OF fA fBA e, unfolded eq c]
  | 
| 
 | 
  2495  | 
  have "card (B - A) = 0" by arith
  | 
| 
 | 
  2496  | 
  hence "B - A = {}" unfolding card_eq_0_iff using fA fB by simp
 | 
| 
 | 
  2497  | 
  with AB show "A = B" by blast
  | 
| 
 | 
  2498  | 
qed
  | 
| 
 | 
  2499  | 
  | 
| 
 | 
  2500  | 
lemma subspace_isomorphism:
  | 
| 
 | 
  2501  | 
  assumes s: "subspace (S:: ('a::euclidean_space) set)"
 | 
| 
 | 
  2502  | 
  and t: "subspace (T :: ('b::euclidean_space) set)"
 | 
| 
 | 
  2503  | 
  and d: "dim S = dim T"
  | 
| 
 | 
  2504  | 
  shows "\<exists>f. linear f \<and> f ` S = T \<and> inj_on f S"
  | 
| 
 | 
  2505  | 
proof-
  | 
| 
 | 
  2506  | 
  from basis_exists[of S] independent_bound obtain B where
  | 
| 
 | 
  2507  | 
    B: "B \<subseteq> S" "independent B" "S \<subseteq> span B" "card B = dim S" and fB: "finite B" by blast
  | 
| 
 | 
  2508  | 
  from basis_exists[of T] independent_bound obtain C where
  | 
| 
 | 
  2509  | 
    C: "C \<subseteq> T" "independent C" "T \<subseteq> span C" "card C = dim T" and fC: "finite C" by blast
  | 
| 
 | 
  2510  | 
  from B(4) C(4) card_le_inj[of B C] d obtain f where
  | 
| 
 | 
  2511  | 
    f: "f ` B \<subseteq> C" "inj_on f B" using `finite B` `finite C` by auto
  | 
| 
 | 
  2512  | 
  from linear_independent_extend[OF B(2)] obtain g where
  | 
| 
 | 
  2513  | 
    g: "linear g" "\<forall>x\<in> B. g x = f x" by blast
  | 
| 
 | 
  2514  | 
  from inj_on_iff_eq_card[OF fB, of f] f(2)
  | 
| 
 | 
  2515  | 
  have "card (f ` B) = card B" by simp
  | 
| 
 | 
  2516  | 
  with B(4) C(4) have ceq: "card (f ` B) = card C" using d
  | 
| 
 | 
  2517  | 
    by simp
  | 
| 
 | 
  2518  | 
  have "g ` B = f ` B" using g(2)
  | 
| 
 | 
  2519  | 
    by (auto simp add: image_iff)
  | 
| 
 | 
  2520  | 
  also have "\<dots> = C" using card_subset_eq[OF fC f(1) ceq] .
  | 
| 
 | 
  2521  | 
  finally have gBC: "g ` B = C" .
  | 
| 
 | 
  2522  | 
  have gi: "inj_on g B" using f(2) g(2)
  | 
| 
 | 
  2523  | 
    by (auto simp add: inj_on_def)
  | 
| 
 | 
  2524  | 
  note g0 = linear_indep_image_lemma[OF g(1) fB, unfolded gBC, OF C(2) gi]
  | 
| 
 | 
  2525  | 
  {fix x y assume x: "x \<in> S" and y: "y \<in> S" and gxy:"g x = g y"
 | 
| 
 | 
  2526  | 
    from B(3) x y have x': "x \<in> span B" and y': "y \<in> span B" by blast+
  | 
| 
 | 
  2527  | 
    from gxy have th0: "g (x - y) = 0" by (simp add: linear_sub[OF g(1)])
  | 
| 
 | 
  2528  | 
    have th1: "x - y \<in> span B" using x' y' by (metis span_sub)
  | 
| 
 | 
  2529  | 
    have "x=y" using g0[OF th1 th0] by simp }
  | 
| 
 | 
  2530  | 
  then have giS: "inj_on g S"
  | 
| 
 | 
  2531  | 
    unfolding inj_on_def by blast
  | 
| 
 | 
  2532  | 
  from span_subspace[OF B(1,3) s]
  | 
| 
 | 
  2533  | 
  have "g ` S = span (g ` B)" by (simp add: span_linear_image[OF g(1)])
  | 
| 
 | 
  2534  | 
  also have "\<dots> = span C" unfolding gBC ..
  | 
| 
 | 
  2535  | 
  also have "\<dots> = T" using span_subspace[OF C(1,3) t] .
  | 
| 
 | 
  2536  | 
  finally have gS: "g ` S = T" .
  | 
| 
 | 
  2537  | 
  from g(1) gS giS show ?thesis by blast
  | 
| 
 | 
  2538  | 
qed
  | 
| 
 | 
  2539  | 
  | 
| 
 | 
  2540  | 
text {* Linear functions are equal on a subspace if they are on a spanning set. *}
 | 
| 
 | 
  2541  | 
  | 
| 
 | 
  2542  | 
lemma subspace_kernel:
  | 
| 
 | 
  2543  | 
  assumes lf: "linear f"
  | 
| 
 | 
  2544  | 
  shows "subspace {x. f x = 0}"
 | 
| 
 | 
  2545  | 
apply (simp add: subspace_def)
  | 
| 
 | 
  2546  | 
by (simp add: linear_add[OF lf] linear_cmul[OF lf] linear_0[OF lf])
  | 
| 
 | 
  2547  | 
  | 
| 
 | 
  2548  | 
lemma linear_eq_0_span:
  | 
| 
 | 
  2549  | 
  assumes lf: "linear f" and f0: "\<forall>x\<in>B. f x = 0"
  | 
| 
 | 
  2550  | 
  shows "\<forall>x \<in> span B. f x = 0"
  | 
| 
 | 
  2551  | 
proof
  | 
| 
 | 
  2552  | 
  fix x assume x: "x \<in> span B"
  | 
| 
 | 
  2553  | 
  let ?P = "\<lambda>x. f x = 0"
  | 
| 
 | 
  2554  | 
  from subspace_kernel[OF lf] have "subspace ?P" unfolding Collect_def .
  | 
| 
 | 
  2555  | 
  with x f0 span_induct[of B "?P" x] show "f x = 0" by blast
  | 
| 
 | 
  2556  | 
qed
  | 
| 
 | 
  2557  | 
  | 
| 
 | 
  2558  | 
lemma linear_eq_0:
  | 
| 
 | 
  2559  | 
  assumes lf: "linear f" and SB: "S \<subseteq> span B" and f0: "\<forall>x\<in>B. f x = 0"
  | 
| 
 | 
  2560  | 
  shows "\<forall>x \<in> S. f x = 0"
  | 
| 
 | 
  2561  | 
  by (metis linear_eq_0_span[OF lf] subset_eq SB f0)
  | 
| 
 | 
  2562  | 
  | 
| 
 | 
  2563  | 
lemma linear_eq:
  | 
| 
 | 
  2564  | 
  assumes lf: "linear f" and lg: "linear g" and S: "S \<subseteq> span B"
  | 
| 
 | 
  2565  | 
  and fg: "\<forall> x\<in> B. f x = g x"
  | 
| 
 | 
  2566  | 
  shows "\<forall>x\<in> S. f x = g x"
  | 
| 
 | 
  2567  | 
proof-
  | 
| 
 | 
  2568  | 
  let ?h = "\<lambda>x. f x - g x"
  | 
| 
 | 
  2569  | 
  from fg have fg': "\<forall>x\<in> B. ?h x = 0" by simp
  | 
| 
 | 
  2570  | 
  from linear_eq_0[OF linear_compose_sub[OF lf lg] S fg']
  | 
| 
 | 
  2571  | 
  show ?thesis by simp
  | 
| 
 | 
  2572  | 
qed
  | 
| 
 | 
  2573  | 
  | 
| 
 | 
  2574  | 
lemma linear_eq_stdbasis:
  | 
| 
 | 
  2575  | 
  assumes lf: "linear (f::'a::euclidean_space \<Rightarrow> _)" and lg: "linear g"
  | 
| 
 | 
  2576  | 
  and fg: "\<forall>i<DIM('a::euclidean_space). f (basis i) = g(basis i)"
 | 
| 
 | 
  2577  | 
  shows "f = g"
  | 
| 
 | 
  2578  | 
proof-
  | 
| 
 | 
  2579  | 
  let ?U = "{..<DIM('a)}"
 | 
| 
 | 
  2580  | 
  let ?I = "(basis::nat=>'a) ` {..<DIM('a)}"
 | 
| 
 | 
  2581  | 
  {fix x assume x: "x \<in> (UNIV :: 'a set)"
 | 
| 
 | 
  2582  | 
    from equalityD2[OF span_basis'[where 'a='a]]
  | 
| 
 | 
  2583  | 
    have IU: " (UNIV :: 'a set) \<subseteq> span ?I" by blast
  | 
| 
 | 
  2584  | 
    have "f x = g x" apply(rule linear_eq[OF lf lg IU,rule_format]) using fg x by auto }
  | 
| 
 | 
  2585  | 
  then show ?thesis by (auto intro: ext)
  | 
| 
 | 
  2586  | 
qed
  | 
| 
 | 
  2587  | 
  | 
| 
 | 
  2588  | 
text {* Similar results for bilinear functions. *}
 | 
| 
 | 
  2589  | 
  | 
| 
 | 
  2590  | 
lemma bilinear_eq:
  | 
| 
 | 
  2591  | 
  assumes bf: "bilinear f"
  | 
| 
 | 
  2592  | 
  and bg: "bilinear g"
  | 
| 
 | 
  2593  | 
  and SB: "S \<subseteq> span B" and TC: "T \<subseteq> span C"
  | 
| 
 | 
  2594  | 
  and fg: "\<forall>x\<in> B. \<forall>y\<in> C. f x y = g x y"
  | 
| 
 | 
  2595  | 
  shows "\<forall>x\<in>S. \<forall>y\<in>T. f x y = g x y "
  | 
| 
 | 
  2596  | 
proof-
  | 
| 
 | 
  2597  | 
  let ?P = "\<lambda>x. \<forall>y\<in> span C. f x y = g x y"
  | 
| 
 | 
  2598  | 
  from bf bg have sp: "subspace ?P"
  | 
| 
 | 
  2599  | 
    unfolding bilinear_def linear_def subspace_def bf bg
  | 
| 
 | 
  2600  | 
    by(auto simp add: span_0 mem_def bilinear_lzero[OF bf] bilinear_lzero[OF bg] span_add Ball_def intro:  bilinear_ladd[OF bf])
  | 
| 
 | 
  2601  | 
  | 
| 
 | 
  2602  | 
  have "\<forall>x \<in> span B. \<forall>y\<in> span C. f x y = g x y"
  | 
| 
 | 
  2603  | 
    apply -
  | 
| 
 | 
  2604  | 
    apply (rule ballI)
  | 
| 
 | 
  2605  | 
    apply (rule span_induct[of B ?P])
  | 
| 
 | 
  2606  | 
    defer
  | 
| 
 | 
  2607  | 
    apply (rule sp)
  | 
| 
 | 
  2608  | 
    apply assumption
  | 
| 
 | 
  2609  | 
    apply (clarsimp simp add: Ball_def)
  | 
| 
 | 
  2610  | 
    apply (rule_tac P="\<lambda>y. f xa y = g xa y" and S=C in span_induct)
  | 
| 
 | 
  2611  | 
    using fg
  | 
| 
 | 
  2612  | 
    apply (auto simp add: subspace_def)
  | 
| 
 | 
  2613  | 
    using bf bg unfolding bilinear_def linear_def
  | 
| 
 | 
  2614  | 
    by(auto simp add: span_0 mem_def bilinear_rzero[OF bf] bilinear_rzero[OF bg] span_add Ball_def intro:  bilinear_ladd[OF bf])
  | 
| 
 | 
  2615  | 
  then show ?thesis using SB TC by (auto intro: ext)
  | 
| 
 | 
  2616  | 
qed
  | 
| 
 | 
  2617  | 
  | 
| 
 | 
  2618  | 
lemma bilinear_eq_stdbasis: fixes f::"'a::euclidean_space \<Rightarrow> 'b::euclidean_space \<Rightarrow> _"
  | 
| 
 | 
  2619  | 
  assumes bf: "bilinear f"
  | 
| 
 | 
  2620  | 
  and bg: "bilinear g"
  | 
| 
 | 
  2621  | 
  and fg: "\<forall>i<DIM('a). \<forall>j<DIM('b). f (basis i) (basis j) = g (basis i) (basis j)"
 | 
| 
 | 
  2622  | 
  shows "f = g"
  | 
| 
 | 
  2623  | 
proof-
  | 
| 
 | 
  2624  | 
  from fg have th: "\<forall>x \<in> (basis ` {..<DIM('a)}). \<forall>y\<in> (basis ` {..<DIM('b)}). f x y = g x y" by blast
 | 
| 
 | 
  2625  | 
  from bilinear_eq[OF bf bg equalityD2[OF span_basis'] equalityD2[OF span_basis'] th]
  | 
| 
 | 
  2626  | 
  show ?thesis by (blast intro: ext)
  | 
| 
 | 
  2627  | 
qed
  | 
| 
 | 
  2628  | 
  | 
| 
 | 
  2629  | 
text {* Detailed theorems about left and right invertibility in general case. *}
 | 
| 
 | 
  2630  | 
  | 
| 
 | 
  2631  | 
lemma linear_injective_left_inverse: fixes f::"'a::euclidean_space => 'b::euclidean_space"
  | 
| 
 | 
  2632  | 
  assumes lf: "linear f" and fi: "inj f"
  | 
| 
 | 
  2633  | 
  shows "\<exists>g. linear g \<and> g o f = id"
  | 
| 
 | 
  2634  | 
proof-
  | 
| 
 | 
  2635  | 
  from linear_independent_extend[OF independent_injective_image, OF independent_basis, OF lf fi]
  | 
| 
 | 
  2636  | 
  obtain h:: "'b => 'a" where h: "linear h"
  | 
| 
 | 
  2637  | 
    " \<forall>x \<in> f ` basis ` {..<DIM('a)}. h x = inv f x" by blast
 | 
| 
 | 
  2638  | 
  from h(2)
  | 
| 
 | 
  2639  | 
  have th: "\<forall>i<DIM('a). (h \<circ> f) (basis i) = id (basis i)"
 | 
| 
 | 
  2640  | 
    using inv_o_cancel[OF fi, unfolded fun_eq_iff id_def o_def]
  | 
| 
 | 
  2641  | 
    by auto
  | 
| 
 | 
  2642  | 
  | 
| 
 | 
  2643  | 
  from linear_eq_stdbasis[OF linear_compose[OF lf h(1)] linear_id th]
  | 
| 
 | 
  2644  | 
  have "h o f = id" .
  | 
| 
 | 
  2645  | 
  then show ?thesis using h(1) by blast
  | 
| 
 | 
  2646  | 
qed
  | 
| 
 | 
  2647  | 
  | 
| 
 | 
  2648  | 
lemma linear_surjective_right_inverse: fixes f::"'a::euclidean_space => 'b::euclidean_space"
  | 
| 
 | 
  2649  | 
  assumes lf: "linear f" and sf: "surj f"
  | 
| 
 | 
  2650  | 
  shows "\<exists>g. linear g \<and> f o g = id"
  | 
| 
 | 
  2651  | 
proof-
  | 
| 
 | 
  2652  | 
  from linear_independent_extend[OF independent_basis[where 'a='b],of "inv f"]
  | 
| 
 | 
  2653  | 
  obtain h:: "'b \<Rightarrow> 'a" where
  | 
| 
 | 
  2654  | 
    h: "linear h" "\<forall> x\<in> basis ` {..<DIM('b)}. h x = inv f x" by blast
 | 
| 
 | 
  2655  | 
  from h(2)
  | 
| 
 | 
  2656  | 
  have th: "\<forall>i<DIM('b). (f o h) (basis i) = id (basis i)"
 | 
| 
 | 
  2657  | 
    using sf by(auto simp add: surj_iff_all)
  | 
| 
 | 
  2658  | 
  from linear_eq_stdbasis[OF linear_compose[OF h(1) lf] linear_id th]
  | 
| 
 | 
  2659  | 
  have "f o h = id" .
  | 
| 
 | 
  2660  | 
  then show ?thesis using h(1) by blast
  | 
| 
 | 
  2661  | 
qed
  | 
| 
 | 
  2662  | 
  | 
| 
 | 
  2663  | 
text {* An injective map @{typ "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"} is also surjective. *}
 | 
| 
 | 
  2664  | 
  | 
| 
 | 
  2665  | 
lemma linear_injective_imp_surjective:  fixes f::"'a::euclidean_space => 'a::euclidean_space"
  | 
| 
 | 
  2666  | 
  assumes lf: "linear f" and fi: "inj f"
  | 
| 
 | 
  2667  | 
  shows "surj f"
  | 
| 
 | 
  2668  | 
proof-
  | 
| 
 | 
  2669  | 
  let ?U = "UNIV :: 'a set"
  | 
| 
 | 
  2670  | 
  from basis_exists[of ?U] obtain B
  | 
| 
 | 
  2671  | 
    where B: "B \<subseteq> ?U" "independent B" "?U \<subseteq> span B" "card B = dim ?U"
  | 
| 
 | 
  2672  | 
    by blast
  | 
| 
 | 
  2673  | 
  from B(4) have d: "dim ?U = card B" by simp
  | 
| 
 | 
  2674  | 
  have th: "?U \<subseteq> span (f ` B)"
  | 
| 
 | 
  2675  | 
    apply (rule card_ge_dim_independent)
  | 
| 
 | 
  2676  | 
    apply blast
  | 
| 
 | 
  2677  | 
    apply (rule independent_injective_image[OF B(2) lf fi])
  | 
| 
 | 
  2678  | 
    apply (rule order_eq_refl)
  | 
| 
 | 
  2679  | 
    apply (rule sym)
  | 
| 
 | 
  2680  | 
    unfolding d
  | 
| 
 | 
  2681  | 
    apply (rule card_image)
  | 
| 
 | 
  2682  | 
    apply (rule subset_inj_on[OF fi])
  | 
| 
 | 
  2683  | 
    by blast
  | 
| 
 | 
  2684  | 
  from th show ?thesis
  | 
| 
 | 
  2685  | 
    unfolding span_linear_image[OF lf] surj_def
  | 
| 
 | 
  2686  | 
    using B(3) by blast
  | 
| 
 | 
  2687  | 
qed
  | 
| 
 | 
  2688  | 
  | 
| 
 | 
  2689  | 
text {* And vice versa. *}
 | 
| 
 | 
  2690  | 
  | 
| 
 | 
  2691  | 
lemma surjective_iff_injective_gen:
  | 
| 
 | 
  2692  | 
  assumes fS: "finite S" and fT: "finite T" and c: "card S = card T"
  | 
| 
 | 
  2693  | 
  and ST: "f ` S \<subseteq> T"
  | 
| 
 | 
  2694  | 
  shows "(\<forall>y \<in> T. \<exists>x \<in> S. f x = y) \<longleftrightarrow> inj_on f S" (is "?lhs \<longleftrightarrow> ?rhs")
  | 
| 
 | 
  2695  | 
proof-
  | 
| 
 | 
  2696  | 
  {assume h: "?lhs"
 | 
| 
 | 
  2697  | 
    {fix x y assume x: "x \<in> S" and y: "y \<in> S" and f: "f x = f y"
 | 
| 
 | 
  2698  | 
      from x fS have S0: "card S \<noteq> 0" by auto
  | 
| 
 | 
  2699  | 
      {assume xy: "x \<noteq> y"
 | 
| 
 | 
  2700  | 
        have th: "card S \<le> card (f ` (S - {y}))"
 | 
| 
 | 
  2701  | 
          unfolding c
  | 
| 
 | 
  2702  | 
          apply (rule card_mono)
  | 
| 
 | 
  2703  | 
          apply (rule finite_imageI)
  | 
| 
 | 
  2704  | 
          using fS apply simp
  | 
| 
 | 
  2705  | 
          using h xy x y f unfolding subset_eq image_iff
  | 
| 
 | 
  2706  | 
          apply auto
  | 
| 
 | 
  2707  | 
          apply (case_tac "xa = f x")
  | 
| 
 | 
  2708  | 
          apply (rule bexI[where x=x])
  | 
| 
 | 
  2709  | 
          apply auto
  | 
| 
 | 
  2710  | 
          done
  | 
| 
 | 
  2711  | 
        also have " \<dots> \<le> card (S -{y})"
 | 
| 
 | 
  2712  | 
          apply (rule card_image_le)
  | 
| 
 | 
  2713  | 
          using fS by simp
  | 
| 
 | 
  2714  | 
        also have "\<dots> \<le> card S - 1" using y fS by simp
  | 
| 
 | 
  2715  | 
        finally have False  using S0 by arith }
  | 
| 
 | 
  2716  | 
      then have "x = y" by blast}
  | 
| 
 | 
  2717  | 
    then have ?rhs unfolding inj_on_def by blast}
  | 
| 
 | 
  2718  | 
  moreover
  | 
| 
 | 
  2719  | 
  {assume h: ?rhs
 | 
| 
 | 
  2720  | 
    have "f ` S = T"
  | 
| 
 | 
  2721  | 
      apply (rule card_subset_eq[OF fT ST])
  | 
| 
 | 
  2722  | 
      unfolding card_image[OF h] using c .
  | 
| 
 | 
  2723  | 
    then have ?lhs by blast}
  | 
| 
 | 
  2724  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  2725  | 
qed
  | 
| 
 | 
  2726  | 
  | 
| 
 | 
  2727  | 
lemma linear_surjective_imp_injective: fixes f::"'a::euclidean_space => 'a::euclidean_space"
  | 
| 
 | 
  2728  | 
  assumes lf: "linear f" and sf: "surj f"
  | 
| 
 | 
  2729  | 
  shows "inj f"
  | 
| 
 | 
  2730  | 
proof-
  | 
| 
 | 
  2731  | 
  let ?U = "UNIV :: 'a set"
  | 
| 
 | 
  2732  | 
  from basis_exists[of ?U] obtain B
  | 
| 
 | 
  2733  | 
    where B: "B \<subseteq> ?U" "independent B" "?U \<subseteq> span B" and d: "card B = dim ?U"
  | 
| 
 | 
  2734  | 
    by blast
  | 
| 
 | 
  2735  | 
  {fix x assume x: "x \<in> span B" and fx: "f x = 0"
 | 
| 
 | 
  2736  | 
    from B(2) have fB: "finite B" using independent_bound by auto
  | 
| 
 | 
  2737  | 
    have fBi: "independent (f ` B)"
  | 
| 
 | 
  2738  | 
      apply (rule card_le_dim_spanning[of "f ` B" ?U])
  | 
| 
 | 
  2739  | 
      apply blast
  | 
| 
 | 
  2740  | 
      using sf B(3)
  | 
| 
 | 
  2741  | 
      unfolding span_linear_image[OF lf] surj_def subset_eq image_iff
  | 
| 
 | 
  2742  | 
      apply blast
  | 
| 
 | 
  2743  | 
      using fB apply blast
  | 
| 
 | 
  2744  | 
      unfolding d[symmetric]
  | 
| 
 | 
  2745  | 
      apply (rule card_image_le)
  | 
| 
 | 
  2746  | 
      apply (rule fB)
  | 
| 
 | 
  2747  | 
      done
  | 
| 
 | 
  2748  | 
    have th0: "dim ?U \<le> card (f ` B)"
  | 
| 
 | 
  2749  | 
      apply (rule span_card_ge_dim)
  | 
| 
 | 
  2750  | 
      apply blast
  | 
| 
 | 
  2751  | 
      unfolding span_linear_image[OF lf]
  | 
| 
 | 
  2752  | 
      apply (rule subset_trans[where B = "f ` UNIV"])
  | 
| 
 | 
  2753  | 
      using sf unfolding surj_def apply blast
  | 
| 
 | 
  2754  | 
      apply (rule image_mono)
  | 
| 
 | 
  2755  | 
      apply (rule B(3))
  | 
| 
 | 
  2756  | 
      apply (metis finite_imageI fB)
  | 
| 
 | 
  2757  | 
      done
  | 
| 
 | 
  2758  | 
  | 
| 
 | 
  2759  | 
    moreover have "card (f ` B) \<le> card B"
  | 
| 
 | 
  2760  | 
      by (rule card_image_le, rule fB)
  | 
| 
 | 
  2761  | 
    ultimately have th1: "card B = card (f ` B)" unfolding d by arith
  | 
| 
 | 
  2762  | 
    have fiB: "inj_on f B"
  | 
| 
 | 
  2763  | 
      unfolding surjective_iff_injective_gen[OF fB finite_imageI[OF fB] th1 subset_refl, symmetric] by blast
  | 
| 
 | 
  2764  | 
    from linear_indep_image_lemma[OF lf fB fBi fiB x] fx
  | 
| 
 | 
  2765  | 
    have "x = 0" by blast}
  | 
| 
 | 
  2766  | 
  note th = this
  | 
| 
 | 
  2767  | 
  from th show ?thesis unfolding linear_injective_0[OF lf]
  | 
| 
 | 
  2768  | 
    using B(3) by blast
  | 
| 
 | 
  2769  | 
qed
  | 
| 
 | 
  2770  | 
  | 
| 
 | 
  2771  | 
text {* Hence either is enough for isomorphism. *}
 | 
| 
 | 
  2772  | 
  | 
| 
 | 
  2773  | 
lemma left_right_inverse_eq:
  | 
| 
 | 
  2774  | 
  assumes fg: "f o g = id" and gh: "g o h = id"
  | 
| 
 | 
  2775  | 
  shows "f = h"
  | 
| 
 | 
  2776  | 
proof-
  | 
| 
 | 
  2777  | 
  have "f = f o (g o h)" unfolding gh by simp
  | 
| 
 | 
  2778  | 
  also have "\<dots> = (f o g) o h" by (simp add: o_assoc)
  | 
| 
 | 
  2779  | 
  finally show "f = h" unfolding fg by simp
  | 
| 
 | 
  2780  | 
qed
  | 
| 
 | 
  2781  | 
  | 
| 
 | 
  2782  | 
lemma isomorphism_expand:
  | 
| 
 | 
  2783  | 
  "f o g = id \<and> g o f = id \<longleftrightarrow> (\<forall>x. f(g x) = x) \<and> (\<forall>x. g(f x) = x)"
  | 
| 
 | 
  2784  | 
  by (simp add: fun_eq_iff o_def id_def)
  | 
| 
 | 
  2785  | 
  | 
| 
 | 
  2786  | 
lemma linear_injective_isomorphism: fixes f::"'a::euclidean_space => 'a::euclidean_space"
  | 
| 
 | 
  2787  | 
  assumes lf: "linear f" and fi: "inj f"
  | 
| 
 | 
  2788  | 
  shows "\<exists>f'. linear f' \<and> (\<forall>x. f' (f x) = x) \<and> (\<forall>x. f (f' x) = x)"
  | 
| 
 | 
  2789  | 
unfolding isomorphism_expand[symmetric]
  | 
| 
 | 
  2790  | 
using linear_surjective_right_inverse[OF lf linear_injective_imp_surjective[OF lf fi]] linear_injective_left_inverse[OF lf fi]
  | 
| 
 | 
  2791  | 
by (metis left_right_inverse_eq)
  | 
| 
 | 
  2792  | 
  | 
| 
 | 
  2793  | 
lemma linear_surjective_isomorphism: fixes f::"'a::euclidean_space => 'a::euclidean_space"
  | 
| 
 | 
  2794  | 
  assumes lf: "linear f" and sf: "surj f"
  | 
| 
 | 
  2795  | 
  shows "\<exists>f'. linear f' \<and> (\<forall>x. f' (f x) = x) \<and> (\<forall>x. f (f' x) = x)"
  | 
| 
 | 
  2796  | 
unfolding isomorphism_expand[symmetric]
  | 
| 
 | 
  2797  | 
using linear_surjective_right_inverse[OF lf sf] linear_injective_left_inverse[OF lf linear_surjective_imp_injective[OF lf sf]]
  | 
| 
 | 
  2798  | 
by (metis left_right_inverse_eq)
  | 
| 
 | 
  2799  | 
  | 
| 
 | 
  2800  | 
text {* Left and right inverses are the same for @{typ "'a::euclidean_space => 'a::euclidean_space"}. *}
 | 
| 
 | 
  2801  | 
  | 
| 
 | 
  2802  | 
lemma linear_inverse_left: fixes f::"'a::euclidean_space => 'a::euclidean_space"
  | 
| 
 | 
  2803  | 
  assumes lf: "linear f" and lf': "linear f'"
  | 
| 
 | 
  2804  | 
  shows "f o f' = id \<longleftrightarrow> f' o f = id"
  | 
| 
 | 
  2805  | 
proof-
  | 
| 
 | 
  2806  | 
  {fix f f':: "'a => 'a"
 | 
| 
 | 
  2807  | 
    assume lf: "linear f" "linear f'" and f: "f o f' = id"
  | 
| 
 | 
  2808  | 
    from f have sf: "surj f"
  | 
| 
 | 
  2809  | 
      apply (auto simp add: o_def id_def surj_def)
  | 
| 
 | 
  2810  | 
      by metis
  | 
| 
 | 
  2811  | 
    from linear_surjective_isomorphism[OF lf(1) sf] lf f
  | 
| 
 | 
  2812  | 
    have "f' o f = id" unfolding fun_eq_iff o_def id_def
  | 
| 
 | 
  2813  | 
      by metis}
  | 
| 
 | 
  2814  | 
  then show ?thesis using lf lf' by metis
  | 
| 
 | 
  2815  | 
qed
  | 
| 
 | 
  2816  | 
  | 
| 
 | 
  2817  | 
text {* Moreover, a one-sided inverse is automatically linear. *}
 | 
| 
 | 
  2818  | 
  | 
| 
 | 
  2819  | 
lemma left_inverse_linear: fixes f::"'a::euclidean_space => 'a::euclidean_space"
  | 
| 
 | 
  2820  | 
  assumes lf: "linear f" and gf: "g o f = id"
  | 
| 
 | 
  2821  | 
  shows "linear g"
  | 
| 
 | 
  2822  | 
proof-
  | 
| 
 | 
  2823  | 
  from gf have fi: "inj f" apply (auto simp add: inj_on_def o_def id_def fun_eq_iff)
  | 
| 
 | 
  2824  | 
    by metis
  | 
| 
 | 
  2825  | 
  from linear_injective_isomorphism[OF lf fi]
  | 
| 
 | 
  2826  | 
  obtain h:: "'a \<Rightarrow> 'a" where
  | 
| 
 | 
  2827  | 
    h: "linear h" "\<forall>x. h (f x) = x" "\<forall>x. f (h x) = x" by blast
  | 
| 
 | 
  2828  | 
  have "h = g" apply (rule ext) using gf h(2,3)
  | 
| 
 | 
  2829  | 
    apply (simp add: o_def id_def fun_eq_iff)
  | 
| 
 | 
  2830  | 
    by metis
  | 
| 
 | 
  2831  | 
  with h(1) show ?thesis by blast
  | 
| 
 | 
  2832  | 
qed
  | 
| 
 | 
  2833  | 
  | 
| 
 | 
  2834  | 
subsection {* Infinity norm *}
 | 
| 
 | 
  2835  | 
  | 
| 
 | 
  2836  | 
definition "infnorm (x::'a::euclidean_space) = Sup {abs(x$$i) |i. i<DIM('a)}"
 | 
| 
 | 
  2837  | 
  | 
| 
 | 
  2838  | 
lemma numseg_dimindex_nonempty: "\<exists>i. i \<in> (UNIV :: 'n set)"
  | 
| 
 | 
  2839  | 
  by auto
  | 
| 
 | 
  2840  | 
  | 
| 
 | 
  2841  | 
lemma infnorm_set_image:
  | 
| 
 | 
  2842  | 
  "{abs((x::'a::euclidean_space)$$i) |i. i<DIM('a)} =
 | 
| 
 | 
  2843  | 
  (\<lambda>i. abs(x$$i)) ` {..<DIM('a)}" by blast
 | 
| 
 | 
  2844  | 
  | 
| 
 | 
  2845  | 
lemma infnorm_set_lemma:
  | 
| 
 | 
  2846  | 
  shows "finite {abs((x::'a::euclidean_space)$$i) |i. i<DIM('a)}"
 | 
| 
 | 
  2847  | 
  and "{abs(x$$i) |i. i<DIM('a::euclidean_space)} \<noteq> {}"
 | 
| 
 | 
  2848  | 
  unfolding infnorm_set_image
  | 
| 
 | 
  2849  | 
  by auto
  | 
| 
 | 
  2850  | 
  | 
| 
 | 
  2851  | 
lemma infnorm_pos_le: "0 \<le> infnorm (x::'a::euclidean_space)"
  | 
| 
 | 
  2852  | 
  unfolding infnorm_def
  | 
| 
 | 
  2853  | 
  unfolding Sup_finite_ge_iff[ OF infnorm_set_lemma]
  | 
| 
 | 
  2854  | 
  unfolding infnorm_set_image
  | 
| 
 | 
  2855  | 
  by auto
  | 
| 
 | 
  2856  | 
  | 
| 
 | 
  2857  | 
lemma infnorm_triangle: "infnorm ((x::'a::euclidean_space) + y) \<le> infnorm x + infnorm y"
  | 
| 
 | 
  2858  | 
proof-
  | 
| 
 | 
  2859  | 
  have th: "\<And>x y (z::real). x - y <= z \<longleftrightarrow> x - z <= y" by arith
  | 
| 
 | 
  2860  | 
  have th1: "\<And>S f. f ` S = { f i| i. i \<in> S}" by blast
 | 
| 
 | 
  2861  | 
  have th2: "\<And>x (y::real). abs(x + y) - abs(x) <= abs(y)" by arith
  | 
| 
 | 
  2862  | 
  have *:"\<And>i. i \<in> {..<DIM('a)} \<longleftrightarrow> i <DIM('a)" by auto
 | 
| 
 | 
  2863  | 
  show ?thesis
  | 
| 
 | 
  2864  | 
  unfolding infnorm_def unfolding  Sup_finite_le_iff[ OF infnorm_set_lemma[where 'a='a]]
  | 
| 
 | 
  2865  | 
  apply (subst diff_le_eq[symmetric])
  | 
| 
 | 
  2866  | 
  unfolding Sup_finite_ge_iff[ OF infnorm_set_lemma]
  | 
| 
 | 
  2867  | 
  unfolding infnorm_set_image bex_simps
  | 
| 
 | 
  2868  | 
  apply (subst th)
  | 
| 
 | 
  2869  | 
  unfolding th1 *
  | 
| 
 | 
  2870  | 
  unfolding Sup_finite_ge_iff[ OF infnorm_set_lemma[where 'a='a]]
  | 
| 
 | 
  2871  | 
  unfolding infnorm_set_image ball_simps bex_simps
  | 
| 
 | 
  2872  | 
  unfolding euclidean_simps by (metis th2)
  | 
| 
 | 
  2873  | 
qed
  | 
| 
 | 
  2874  | 
  | 
| 
 | 
  2875  | 
lemma infnorm_eq_0: "infnorm x = 0 \<longleftrightarrow> (x::_::euclidean_space) = 0"
  | 
| 
 | 
  2876  | 
proof-
  | 
| 
 | 
  2877  | 
  have "infnorm x <= 0 \<longleftrightarrow> x = 0"
  | 
| 
 | 
  2878  | 
    unfolding infnorm_def
  | 
| 
 | 
  2879  | 
    unfolding Sup_finite_le_iff[OF infnorm_set_lemma]
  | 
| 
 | 
  2880  | 
    unfolding infnorm_set_image ball_simps
  | 
| 
 | 
  2881  | 
    apply(subst (1) euclidean_eq) unfolding euclidean_component.zero
  | 
| 
 | 
  2882  | 
    by auto
  | 
| 
 | 
  2883  | 
  then show ?thesis using infnorm_pos_le[of x] by simp
  | 
| 
 | 
  2884  | 
qed
  | 
| 
 | 
  2885  | 
  | 
| 
 | 
  2886  | 
lemma infnorm_0: "infnorm 0 = 0"
  | 
| 
 | 
  2887  | 
  by (simp add: infnorm_eq_0)
  | 
| 
 | 
  2888  | 
  | 
| 
 | 
  2889  | 
lemma infnorm_neg: "infnorm (- x) = infnorm x"
  | 
| 
 | 
  2890  | 
  unfolding infnorm_def
  | 
| 
 | 
  2891  | 
  apply (rule cong[of "Sup" "Sup"])
  | 
| 
 | 
  2892  | 
  apply blast by(auto simp add: euclidean_simps)
  | 
| 
 | 
  2893  | 
  | 
| 
 | 
  2894  | 
lemma infnorm_sub: "infnorm (x - y) = infnorm (y - x)"
  | 
| 
 | 
  2895  | 
proof-
  | 
| 
 | 
  2896  | 
  have "y - x = - (x - y)" by simp
  | 
| 
 | 
  2897  | 
  then show ?thesis  by (metis infnorm_neg)
  | 
| 
 | 
  2898  | 
qed
  | 
| 
 | 
  2899  | 
  | 
| 
 | 
  2900  | 
lemma real_abs_sub_infnorm: "\<bar> infnorm x - infnorm y\<bar> \<le> infnorm (x - y)"
  | 
| 
 | 
  2901  | 
proof-
  | 
| 
 | 
  2902  | 
  have th: "\<And>(nx::real) n ny. nx <= n + ny \<Longrightarrow> ny <= n + nx ==> \<bar>nx - ny\<bar> <= n"
  | 
| 
 | 
  2903  | 
    by arith
  | 
| 
 | 
  2904  | 
  from infnorm_triangle[of "x - y" " y"] infnorm_triangle[of "x - y" "-x"]
  | 
| 
 | 
  2905  | 
  have ths: "infnorm x \<le> infnorm (x - y) + infnorm y"
  | 
| 
 | 
  2906  | 
    "infnorm y \<le> infnorm (x - y) + infnorm x"
  | 
| 
 | 
  2907  | 
    by (simp_all add: field_simps infnorm_neg diff_minus[symmetric])
  | 
| 
 | 
  2908  | 
  from th[OF ths]  show ?thesis .
  | 
| 
 | 
  2909  | 
qed
  | 
| 
 | 
  2910  | 
  | 
| 
 | 
  2911  | 
lemma real_abs_infnorm: " \<bar>infnorm x\<bar> = infnorm x"
  | 
| 
 | 
  2912  | 
  using infnorm_pos_le[of x] by arith
  | 
| 
 | 
  2913  | 
  | 
| 
 | 
  2914  | 
lemma component_le_infnorm:
  | 
| 
 | 
  2915  | 
  shows "\<bar>x$$i\<bar> \<le> infnorm (x::'a::euclidean_space)"
  | 
| 
 | 
  2916  | 
proof(cases "i<DIM('a)")
 | 
| 
 | 
  2917  | 
  case False thus ?thesis using infnorm_pos_le by auto
  | 
| 
 | 
  2918  | 
next case True
  | 
| 
 | 
  2919  | 
  let ?U = "{..<DIM('a)}"
 | 
| 
 | 
  2920  | 
  let ?S = "{\<bar>x$$i\<bar> |i. i<DIM('a)}"
 | 
| 
 | 
  2921  | 
  have fS: "finite ?S" unfolding image_Collect[symmetric]
  | 
| 
 | 
  2922  | 
    apply (rule finite_imageI) by simp
  | 
| 
 | 
  2923  | 
  have S0: "?S \<noteq> {}" by blast
 | 
| 
 | 
  2924  | 
  have th1: "\<And>S f. f ` S = { f i| i. i \<in> S}" by blast
 | 
| 
 | 
  2925  | 
  show ?thesis unfolding infnorm_def  
  | 
| 
 | 
  2926  | 
    apply(subst Sup_finite_ge_iff) using Sup_finite_in[OF fS S0]
  | 
| 
 | 
  2927  | 
    using infnorm_set_image using True by auto
  | 
| 
 | 
  2928  | 
qed
  | 
| 
 | 
  2929  | 
  | 
| 
 | 
  2930  | 
lemma infnorm_mul_lemma: "infnorm(a *\<^sub>R x) <= \<bar>a\<bar> * infnorm x"
  | 
| 
 | 
  2931  | 
  apply (subst infnorm_def)
  | 
| 
 | 
  2932  | 
  unfolding Sup_finite_le_iff[OF infnorm_set_lemma]
  | 
| 
 | 
  2933  | 
  unfolding infnorm_set_image ball_simps euclidean_scaleR abs_mult
  | 
| 
 | 
  2934  | 
  using component_le_infnorm[of x] by(auto intro: mult_mono) 
  | 
| 
 | 
  2935  | 
  | 
| 
 | 
  2936  | 
lemma infnorm_mul: "infnorm(a *\<^sub>R x) = abs a * infnorm x"
  | 
| 
 | 
  2937  | 
proof-
  | 
| 
 | 
  2938  | 
  {assume a0: "a = 0" hence ?thesis by (simp add: infnorm_0) }
 | 
| 
 | 
  2939  | 
  moreover
  | 
| 
 | 
  2940  | 
  {assume a0: "a \<noteq> 0"
 | 
| 
 | 
  2941  | 
    from a0 have th: "(1/a) *\<^sub>R (a *\<^sub>R x) = x" by simp
  | 
| 
 | 
  2942  | 
    from a0 have ap: "\<bar>a\<bar> > 0" by arith
  | 
| 
 | 
  2943  | 
    from infnorm_mul_lemma[of "1/a" "a *\<^sub>R x"]
  | 
| 
 | 
  2944  | 
    have "infnorm x \<le> 1/\<bar>a\<bar> * infnorm (a*\<^sub>R x)"
  | 
| 
 | 
  2945  | 
      unfolding th by simp
  | 
| 
 | 
  2946  | 
    with ap have "\<bar>a\<bar> * infnorm x \<le> \<bar>a\<bar> * (1/\<bar>a\<bar> * infnorm (a *\<^sub>R x))" by (simp add: field_simps)
  | 
| 
 | 
  2947  | 
    then have "\<bar>a\<bar> * infnorm x \<le> infnorm (a*\<^sub>R x)"
  | 
| 
 | 
  2948  | 
      using ap by (simp add: field_simps)
  | 
| 
 | 
  2949  | 
    with infnorm_mul_lemma[of a x] have ?thesis by arith }
  | 
| 
 | 
  2950  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  2951  | 
qed
  | 
| 
 | 
  2952  | 
  | 
| 
 | 
  2953  | 
lemma infnorm_pos_lt: "infnorm x > 0 \<longleftrightarrow> x \<noteq> 0"
  | 
| 
 | 
  2954  | 
  using infnorm_pos_le[of x] infnorm_eq_0[of x] by arith
  | 
| 
 | 
  2955  | 
  | 
| 
 | 
  2956  | 
text {* Prove that it differs only up to a bound from Euclidean norm. *}
 | 
| 
 | 
  2957  | 
  | 
| 
 | 
  2958  | 
lemma infnorm_le_norm: "infnorm x \<le> norm x"
  | 
| 
 | 
  2959  | 
  unfolding infnorm_def Sup_finite_le_iff[OF infnorm_set_lemma]
  | 
| 
 | 
  2960  | 
  unfolding infnorm_set_image  ball_simps
  | 
| 
 | 
  2961  | 
  by (metis component_le_norm)
  | 
| 
 | 
  2962  | 
  | 
| 
 | 
  2963  | 
lemma card_enum: "card {1 .. n} = n" by auto
 | 
| 
 | 
  2964  | 
  | 
| 
 | 
  2965  | 
lemma norm_le_infnorm: "norm(x) <= sqrt(real DIM('a)) * infnorm(x::'a::euclidean_space)"
 | 
| 
 | 
  2966  | 
proof-
  | 
| 
 | 
  2967  | 
  let ?d = "DIM('a)"
 | 
| 
 | 
  2968  | 
  have "real ?d \<ge> 0" by simp
  | 
| 
 | 
  2969  | 
  hence d2: "(sqrt (real ?d))^2 = real ?d"
  | 
| 
 | 
  2970  | 
    by (auto intro: real_sqrt_pow2)
  | 
| 
 | 
  2971  | 
  have th: "sqrt (real ?d) * infnorm x \<ge> 0"
  | 
| 
 | 
  2972  | 
    by (simp add: zero_le_mult_iff infnorm_pos_le)
  | 
| 
 | 
  2973  | 
  have th1: "x \<bullet> x \<le> (sqrt (real ?d) * infnorm x)^2"
  | 
| 
 | 
  2974  | 
    unfolding power_mult_distrib d2
  | 
| 
 | 
  2975  | 
    unfolding real_of_nat_def apply(subst euclidean_inner)
  | 
| 
 | 
  2976  | 
    apply (subst power2_abs[symmetric])
  | 
| 
 | 
  2977  | 
    apply(rule order_trans[OF setsum_bounded[where K="\<bar>infnorm x\<bar>\<twosuperior>"]])
  | 
| 
 | 
  2978  | 
    apply(auto simp add: power2_eq_square[symmetric])
  | 
| 
 | 
  2979  | 
    apply (subst power2_abs[symmetric])
  | 
| 
 | 
  2980  | 
    apply (rule power_mono)
  | 
| 
 | 
  2981  | 
    unfolding infnorm_def  Sup_finite_ge_iff[OF infnorm_set_lemma]
  | 
| 
 | 
  2982  | 
    unfolding infnorm_set_image bex_simps apply(rule_tac x=i in bexI) by auto
  | 
| 
 | 
  2983  | 
  from real_le_lsqrt[OF inner_ge_zero th th1]
  | 
| 
 | 
  2984  | 
  show ?thesis unfolding norm_eq_sqrt_inner id_def .
  | 
| 
 | 
  2985  | 
qed
  | 
| 
 | 
  2986  | 
  | 
| 
 | 
  2987  | 
text {* Equality in Cauchy-Schwarz and triangle inequalities. *}
 | 
| 
 | 
  2988  | 
  | 
| 
 | 
  2989  | 
lemma norm_cauchy_schwarz_eq: "x \<bullet> y = norm x * norm y \<longleftrightarrow> norm x *\<^sub>R y = norm y *\<^sub>R x" (is "?lhs \<longleftrightarrow> ?rhs")
  | 
| 
 | 
  2990  | 
proof-
  | 
| 
 | 
  2991  | 
  {assume h: "x = 0"
 | 
| 
 | 
  2992  | 
    hence ?thesis by simp}
  | 
| 
 | 
  2993  | 
  moreover
  | 
| 
 | 
  2994  | 
  {assume h: "y = 0"
 | 
| 
 | 
  2995  | 
    hence ?thesis by simp}
  | 
| 
 | 
  2996  | 
  moreover
  | 
| 
 | 
  2997  | 
  {assume x: "x \<noteq> 0" and y: "y \<noteq> 0"
 | 
| 
 | 
  2998  | 
    from inner_eq_zero_iff[of "norm y *\<^sub>R x - norm x *\<^sub>R y"]
  | 
| 
 | 
  2999  | 
    have "?rhs \<longleftrightarrow> (norm y * (norm y * norm x * norm x - norm x * (x \<bullet> y)) - norm x * (norm y * (y \<bullet> x) - norm x * norm y * norm y) =  0)"
  | 
| 
 | 
  3000  | 
      using x y
  | 
| 
 | 
  3001  | 
      unfolding inner_simps
  | 
| 
 | 
  3002  | 
      unfolding power2_norm_eq_inner[symmetric] power2_eq_square diff_eq_0_iff_eq apply (simp add: inner_commute)
  | 
| 
 | 
  3003  | 
      apply (simp add: field_simps) by metis
  | 
| 
 | 
  3004  | 
    also have "\<dots> \<longleftrightarrow> (2 * norm x * norm y * (norm x * norm y - x \<bullet> y) = 0)" using x y
  | 
| 
 | 
  3005  | 
      by (simp add: field_simps inner_commute)
  | 
| 
 | 
  3006  | 
    also have "\<dots> \<longleftrightarrow> ?lhs" using x y
  | 
| 
 | 
  3007  | 
      apply simp
  | 
| 
 | 
  3008  | 
      by metis
  | 
| 
 | 
  3009  | 
    finally have ?thesis by blast}
  | 
| 
 | 
  3010  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  3011  | 
qed
  | 
| 
 | 
  3012  | 
  | 
| 
 | 
  3013  | 
lemma norm_cauchy_schwarz_abs_eq:
  | 
| 
 | 
  3014  | 
  shows "abs(x \<bullet> y) = norm x * norm y \<longleftrightarrow>
  | 
| 
 | 
  3015  | 
                norm x *\<^sub>R y = norm y *\<^sub>R x \<or> norm(x) *\<^sub>R y = - norm y *\<^sub>R x" (is "?lhs \<longleftrightarrow> ?rhs")
  | 
| 
 | 
  3016  | 
proof-
  | 
| 
 | 
  3017  | 
  have th: "\<And>(x::real) a. a \<ge> 0 \<Longrightarrow> abs x = a \<longleftrightarrow> x = a \<or> x = - a" by arith
  | 
| 
 | 
  3018  | 
  have "?rhs \<longleftrightarrow> norm x *\<^sub>R y = norm y *\<^sub>R x \<or> norm (- x) *\<^sub>R y = norm y *\<^sub>R (- x)"
  | 
| 
 | 
  3019  | 
    by simp
  | 
| 
 | 
  3020  | 
  also have "\<dots> \<longleftrightarrow>(x \<bullet> y = norm x * norm y \<or>
  | 
| 
 | 
  3021  | 
     (-x) \<bullet> y = norm x * norm y)"
  | 
| 
 | 
  3022  | 
    unfolding norm_cauchy_schwarz_eq[symmetric]
  | 
| 
 | 
  3023  | 
    unfolding norm_minus_cancel norm_scaleR ..
  | 
| 
 | 
  3024  | 
  also have "\<dots> \<longleftrightarrow> ?lhs"
  | 
| 
 | 
  3025  | 
    unfolding th[OF mult_nonneg_nonneg, OF norm_ge_zero[of x] norm_ge_zero[of y]] inner_simps by auto
  | 
| 
 | 
  3026  | 
  finally show ?thesis ..
  | 
| 
 | 
  3027  | 
qed
  | 
| 
 | 
  3028  | 
  | 
| 
 | 
  3029  | 
lemma norm_triangle_eq:
  | 
| 
 | 
  3030  | 
  fixes x y :: "'a::real_inner"
  | 
| 
 | 
  3031  | 
  shows "norm(x + y) = norm x + norm y \<longleftrightarrow> norm x *\<^sub>R y = norm y *\<^sub>R x"
  | 
| 
 | 
  3032  | 
proof-
  | 
| 
 | 
  3033  | 
  {assume x: "x =0 \<or> y =0"
 | 
| 
 | 
  3034  | 
    hence ?thesis by (cases "x=0", simp_all)}
  | 
| 
 | 
  3035  | 
  moreover
  | 
| 
 | 
  3036  | 
  {assume x: "x \<noteq> 0" and y: "y \<noteq> 0"
 | 
| 
 | 
  3037  | 
    hence "norm x \<noteq> 0" "norm y \<noteq> 0"
  | 
| 
 | 
  3038  | 
      by simp_all
  | 
| 
 | 
  3039  | 
    hence n: "norm x > 0" "norm y > 0"
  | 
| 
 | 
  3040  | 
      using norm_ge_zero[of x] norm_ge_zero[of y]
  | 
| 
 | 
  3041  | 
      by arith+
  | 
| 
 | 
  3042  | 
    have th: "\<And>(a::real) b c. a + b + c \<noteq> 0 ==> (a = b + c \<longleftrightarrow> a^2 = (b + c)^2)" by algebra
  | 
| 
 | 
  3043  | 
    have "norm(x + y) = norm x + norm y \<longleftrightarrow> norm(x + y)^ 2 = (norm x + norm y) ^2"
  | 
| 
 | 
  3044  | 
      apply (rule th) using n norm_ge_zero[of "x + y"]
  | 
| 
 | 
  3045  | 
      by arith
  | 
| 
 | 
  3046  | 
    also have "\<dots> \<longleftrightarrow> norm x *\<^sub>R y = norm y *\<^sub>R x"
  | 
| 
 | 
  3047  | 
      unfolding norm_cauchy_schwarz_eq[symmetric]
  | 
| 
 | 
  3048  | 
      unfolding power2_norm_eq_inner inner_simps
  | 
| 
 | 
  3049  | 
      by (simp add: power2_norm_eq_inner[symmetric] power2_eq_square inner_commute field_simps)
  | 
| 
 | 
  3050  | 
    finally have ?thesis .}
  | 
| 
 | 
  3051  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  3052  | 
qed
  | 
| 
 | 
  3053  | 
  | 
| 
 | 
  3054  | 
subsection {* Collinearity *}
 | 
| 
 | 
  3055  | 
  | 
| 
 | 
  3056  | 
definition
  | 
| 
 | 
  3057  | 
  collinear :: "'a::real_vector set \<Rightarrow> bool" where
  | 
| 
 | 
  3058  | 
  "collinear S \<longleftrightarrow> (\<exists>u. \<forall>x \<in> S. \<forall> y \<in> S. \<exists>c. x - y = c *\<^sub>R u)"
  | 
| 
 | 
  3059  | 
  | 
| 
 | 
  3060  | 
lemma collinear_empty:  "collinear {}" by (simp add: collinear_def)
 | 
| 
 | 
  3061  | 
  | 
| 
 | 
  3062  | 
lemma collinear_sing: "collinear {x}"
 | 
| 
 | 
  3063  | 
  by (simp add: collinear_def)
  | 
| 
 | 
  3064  | 
  | 
| 
 | 
  3065  | 
lemma collinear_2: "collinear {x, y}"
 | 
| 
 | 
  3066  | 
  apply (simp add: collinear_def)
  | 
| 
 | 
  3067  | 
  apply (rule exI[where x="x - y"])
  | 
| 
 | 
  3068  | 
  apply auto
  | 
| 
 | 
  3069  | 
  apply (rule exI[where x=1], simp)
  | 
| 
 | 
  3070  | 
  apply (rule exI[where x="- 1"], simp)
  | 
| 
 | 
  3071  | 
  done
  | 
| 
 | 
  3072  | 
  | 
| 
 | 
  3073  | 
lemma collinear_lemma: "collinear {0,x,y} \<longleftrightarrow> x = 0 \<or> y = 0 \<or> (\<exists>c. y = c *\<^sub>R x)" (is "?lhs \<longleftrightarrow> ?rhs")
 | 
| 
 | 
  3074  | 
proof-
  | 
| 
 | 
  3075  | 
  {assume "x=0 \<or> y = 0" hence ?thesis
 | 
| 
 | 
  3076  | 
      by (cases "x = 0", simp_all add: collinear_2 insert_commute)}
  | 
| 
 | 
  3077  | 
  moreover
  | 
| 
 | 
  3078  | 
  {assume x: "x \<noteq> 0" and y: "y \<noteq> 0"
 | 
| 
 | 
  3079  | 
    {assume h: "?lhs"
 | 
| 
 | 
  3080  | 
      then obtain u where u: "\<forall> x\<in> {0,x,y}. \<forall>y\<in> {0,x,y}. \<exists>c. x - y = c *\<^sub>R u" unfolding collinear_def by blast
 | 
| 
 | 
  3081  | 
      from u[rule_format, of x 0] u[rule_format, of y 0]
  | 
| 
 | 
  3082  | 
      obtain cx and cy where
  | 
| 
 | 
  3083  | 
        cx: "x = cx *\<^sub>R u" and cy: "y = cy *\<^sub>R u"
  | 
| 
 | 
  3084  | 
        by auto
  | 
| 
 | 
  3085  | 
      from cx x have cx0: "cx \<noteq> 0" by auto
  | 
| 
 | 
  3086  | 
      from cy y have cy0: "cy \<noteq> 0" by auto
  | 
| 
 | 
  3087  | 
      let ?d = "cy / cx"
  | 
| 
 | 
  3088  | 
      from cx cy cx0 have "y = ?d *\<^sub>R x"
  | 
| 
 | 
  3089  | 
        by simp
  | 
| 
 | 
  3090  | 
      hence ?rhs using x y by blast}
  | 
| 
 | 
  3091  | 
    moreover
  | 
| 
 | 
  3092  | 
    {assume h: "?rhs"
 | 
| 
 | 
  3093  | 
      then obtain c where c: "y = c *\<^sub>R x" using x y by blast
  | 
| 
 | 
  3094  | 
      have ?lhs unfolding collinear_def c
  | 
| 
 | 
  3095  | 
        apply (rule exI[where x=x])
  | 
| 
 | 
  3096  | 
        apply auto
  | 
| 
 | 
  3097  | 
        apply (rule exI[where x="- 1"], simp)
  | 
| 
 | 
  3098  | 
        apply (rule exI[where x= "-c"], simp)
  | 
| 
 | 
  3099  | 
        apply (rule exI[where x=1], simp)
  | 
| 
 | 
  3100  | 
        apply (rule exI[where x="1 - c"], simp add: scaleR_left_diff_distrib)
  | 
| 
 | 
  3101  | 
        apply (rule exI[where x="c - 1"], simp add: scaleR_left_diff_distrib)
  | 
| 
 | 
  3102  | 
        done}
  | 
| 
 | 
  3103  | 
    ultimately have ?thesis by blast}
  | 
| 
 | 
  3104  | 
  ultimately show ?thesis by blast
  | 
| 
 | 
  3105  | 
qed
  | 
| 
 | 
  3106  | 
  | 
| 
 | 
  3107  | 
lemma norm_cauchy_schwarz_equal:
  | 
| 
 | 
  3108  | 
  shows "abs(x \<bullet> y) = norm x * norm y \<longleftrightarrow> collinear {0,x,y}"
 | 
| 
 | 
  3109  | 
unfolding norm_cauchy_schwarz_abs_eq
  | 
| 
 | 
  3110  | 
apply (cases "x=0", simp_all add: collinear_2)
  | 
| 
 | 
  3111  | 
apply (cases "y=0", simp_all add: collinear_2 insert_commute)
  | 
| 
 | 
  3112  | 
unfolding collinear_lemma
  | 
| 
 | 
  3113  | 
apply simp
  | 
| 
 | 
  3114  | 
apply (subgoal_tac "norm x \<noteq> 0")
  | 
| 
 | 
  3115  | 
apply (subgoal_tac "norm y \<noteq> 0")
  | 
| 
 | 
  3116  | 
apply (rule iffI)
  | 
| 
 | 
  3117  | 
apply (cases "norm x *\<^sub>R y = norm y *\<^sub>R x")
  | 
| 
 | 
  3118  | 
apply (rule exI[where x="(1/norm x) * norm y"])
  | 
| 
 | 
  3119  | 
apply (drule sym)
  | 
| 
 | 
  3120  | 
unfolding scaleR_scaleR[symmetric]
  | 
| 
 | 
  3121  | 
apply (simp add: field_simps)
  | 
| 
 | 
  3122  | 
apply (rule exI[where x="(1/norm x) * - norm y"])
  | 
| 
 | 
  3123  | 
apply clarify
  | 
| 
 | 
  3124  | 
apply (drule sym)
  | 
| 
 | 
  3125  | 
unfolding scaleR_scaleR[symmetric]
  | 
| 
 | 
  3126  | 
apply (simp add: field_simps)
  | 
| 
 | 
  3127  | 
apply (erule exE)
  | 
| 
 | 
  3128  | 
apply (erule ssubst)
  | 
| 
 | 
  3129  | 
unfolding scaleR_scaleR
  | 
| 
 | 
  3130  | 
unfolding norm_scaleR
  | 
| 
 | 
  3131  | 
apply (subgoal_tac "norm x * c = \<bar>c\<bar> * norm x \<or> norm x * c = - \<bar>c\<bar> * norm x")
  | 
| 
 | 
  3132  | 
apply (case_tac "c <= 0", simp add: field_simps)
  | 
| 
 | 
  3133  | 
apply (simp add: field_simps)
  | 
| 
 | 
  3134  | 
apply (case_tac "c <= 0", simp add: field_simps)
  | 
| 
 | 
  3135  | 
apply (simp add: field_simps)
  | 
| 
 | 
  3136  | 
apply simp
  | 
| 
 | 
  3137  | 
apply simp
  | 
| 
 | 
  3138  | 
done
  | 
| 
 | 
  3139  | 
  | 
| 
 | 
  3140  | 
subsection "Instantiate @{typ real} and @{typ complex} as typeclass @{text ordered_euclidean_space}."
 | 
| 
 | 
  3141  | 
  | 
| 
 | 
  3142  | 
lemma basis_real_range: "basis ` {..<1} = {1::real}" by auto
 | 
| 
 | 
  3143  | 
  | 
| 
 | 
  3144  | 
instance real::ordered_euclidean_space
  | 
| 
 | 
  3145  | 
  by default (auto simp add: euclidean_component_def)
  | 
| 
 | 
  3146  | 
  | 
| 
 | 
  3147  | 
lemma Eucl_real_simps[simp]:
  | 
| 
 | 
  3148  | 
  "(x::real) $$ 0 = x"
  | 
| 
 | 
  3149  | 
  "(\<chi>\<chi> i. f i) = ((f 0)::real)"
  | 
| 
 | 
  3150  | 
  "\<And>i. i > 0 \<Longrightarrow> x $$ i = 0"
  | 
| 
 | 
  3151  | 
  defer apply(subst euclidean_eq) apply safe
  | 
| 
 | 
  3152  | 
  unfolding euclidean_lambda_beta'
  | 
| 
 | 
  3153  | 
  unfolding euclidean_component_def by auto
  | 
| 
 | 
  3154  | 
  | 
| 
 | 
  3155  | 
lemma complex_basis[simp]:
  | 
| 
 | 
  3156  | 
  shows "basis 0 = (1::complex)" and "basis 1 = ii" and "basis (Suc 0) = ii"
  | 
| 
 | 
  3157  | 
  unfolding basis_complex_def by auto
  | 
| 
 | 
  3158  | 
  | 
| 
 | 
  3159  | 
section {* Products Spaces *}
 | 
| 
 | 
  3160  | 
  | 
| 
 | 
  3161  | 
lemma DIM_prod[simp]: "DIM('a \<times> 'b) = DIM('b::euclidean_space) + DIM('a::euclidean_space)"
 | 
| 
 | 
  3162  | 
  (* FIXME: why this orientation? Why not "DIM('a) + DIM('b)" ? *)
 | 
| 
 | 
  3163  | 
  unfolding dimension_prod_def by (rule add_commute)
  | 
| 
 | 
  3164  | 
  | 
| 
 | 
  3165  | 
instantiation prod :: (ordered_euclidean_space, ordered_euclidean_space) ordered_euclidean_space
  | 
| 
 | 
  3166  | 
begin
  | 
| 
 | 
  3167  | 
  | 
| 
 | 
  3168  | 
definition "x \<le> (y::('a\<times>'b)) \<longleftrightarrow> (\<forall>i<DIM('a\<times>'b). x $$ i \<le> y $$ i)"
 | 
| 
 | 
  3169  | 
definition "x < (y::('a\<times>'b)) \<longleftrightarrow> (\<forall>i<DIM('a\<times>'b). x $$ i < y $$ i)"
 | 
| 
 | 
  3170  | 
  | 
| 
 | 
  3171  | 
instance proof qed (auto simp: less_prod_def less_eq_prod_def)
  | 
| 
 | 
  3172  | 
end
  | 
| 
 | 
  3173  | 
  | 
| 
 | 
  3174  | 
  | 
| 
 | 
  3175  | 
end
  |