src/HOL/Analysis/Change_Of_Vars.thy
author paulson <lp15@cam.ac.uk>
Fri Apr 20 19:11:17 2018 +0100 (16 months ago)
changeset 68017 e99f9b3962bf
parent 68001 0a2a1b6507c1
child 68046 6aba668aea78
permissions -rw-r--r--
three new theorems
lp15@68017
     1
(*  Title:      HOL/Analysis/Change_Of_Vars.thy
lp15@68017
     2
    Authors:    LC Paulson, based on material from HOL Light
lp15@68017
     3
*)
lp15@68017
     4
lp15@68017
     5
section\<open>Change of Variables Theorems\<close>
lp15@68017
     6
lp15@67998
     7
theory Change_Of_Vars
lp15@67999
     8
  imports Vitali_Covering_Theorem Determinants
lp15@67998
     9
lp15@67998
    10
begin
lp15@67998
    11
lp15@67998
    12
subsection\<open>Induction on matrix row operations\<close>
lp15@67998
    13
lp15@67998
    14
lemma induct_matrix_row_operations:
lp15@67999
    15
  fixes P :: "real^'n^'n \<Rightarrow> bool"
lp15@67998
    16
  assumes zero_row: "\<And>A i. row i A = 0 \<Longrightarrow> P A"
lp15@67998
    17
    and diagonal: "\<And>A. (\<And>i j. i \<noteq> j \<Longrightarrow> A$i$j = 0) \<Longrightarrow> P A"
lp15@67998
    18
    and swap_cols: "\<And>A m n. \<lbrakk>P A; m \<noteq> n\<rbrakk> \<Longrightarrow> P(\<chi> i j. A $ i $ Fun.swap m n id j)"
lp15@67998
    19
    and row_op: "\<And>A m n c. \<lbrakk>P A; m \<noteq> n\<rbrakk>
lp15@67998
    20
                   \<Longrightarrow> P(\<chi> i. if i = m then row m A + c *\<^sub>R row n A else row i A)"
lp15@67998
    21
  shows "P A"
lp15@67998
    22
proof -
lp15@67998
    23
  have "P A" if "(\<And>i j. \<lbrakk>j \<in> -K;  i \<noteq> j\<rbrakk> \<Longrightarrow> A$i$j = 0)" for A K
lp15@67998
    24
  proof -
lp15@67998
    25
    have "finite K"
lp15@67998
    26
      by simp
lp15@67998
    27
    then show ?thesis using that
lp15@67998
    28
    proof (induction arbitrary: A rule: finite_induct)
lp15@67998
    29
      case empty
lp15@67998
    30
      with diagonal show ?case
lp15@67998
    31
        by simp
lp15@67998
    32
    next
lp15@67998
    33
      case (insert k K)
lp15@67998
    34
      note insertK = insert
lp15@67998
    35
      have "P A" if kk: "A$k$k \<noteq> 0"
lp15@67998
    36
        and 0: "\<And>i j. \<lbrakk>j \<in> - insert k K; i \<noteq> j\<rbrakk> \<Longrightarrow> A$i$j = 0"
lp15@67998
    37
               "\<And>i. \<lbrakk>i \<in> -L; i \<noteq> k\<rbrakk> \<Longrightarrow> A$i$k = 0" for A L
lp15@67998
    38
      proof -
lp15@67998
    39
        have "finite L"
lp15@67998
    40
          by simp
lp15@67998
    41
        then show ?thesis using 0 kk
lp15@67998
    42
        proof (induction arbitrary: A rule: finite_induct)
lp15@67998
    43
          case (empty B)
lp15@67998
    44
          show ?case
lp15@67998
    45
          proof (rule insertK)
lp15@67998
    46
            fix i j
lp15@67998
    47
            assume "i \<in> - K" "j \<noteq> i"
lp15@67998
    48
            show "B $ j $ i = 0"
lp15@67998
    49
              using \<open>j \<noteq> i\<close> \<open>i \<in> - K\<close> empty
lp15@67998
    50
              by (metis ComplD ComplI Compl_eq_Diff_UNIV Diff_empty UNIV_I insert_iff)
lp15@67998
    51
          qed
lp15@67998
    52
        next
lp15@67998
    53
          case (insert l L B)
lp15@67998
    54
          show ?case
lp15@67998
    55
          proof (cases "k = l")
lp15@67998
    56
            case True
lp15@67998
    57
            with insert show ?thesis
lp15@67998
    58
              by auto
lp15@67998
    59
          next
lp15@67998
    60
            case False
lp15@67998
    61
            let ?C = "\<chi> i. if i = l then row l B - (B $ l $ k / B $ k $ k) *\<^sub>R row k B else row i B"
lp15@67998
    62
            have 1: "\<lbrakk>j \<in> - insert k K; i \<noteq> j\<rbrakk> \<Longrightarrow> ?C $ i $ j = 0" for j i
lp15@67998
    63
              by (auto simp: insert.prems(1) row_def)
lp15@67998
    64
            have 2: "?C $ i $ k = 0"
lp15@67998
    65
              if "i \<in> - L" "i \<noteq> k" for i
lp15@67998
    66
            proof (cases "i=l")
lp15@67998
    67
              case True
lp15@67998
    68
              with that insert.prems show ?thesis
lp15@67998
    69
                by (simp add: row_def)
lp15@67998
    70
            next
lp15@67998
    71
              case False
lp15@67998
    72
              with that show ?thesis
lp15@67998
    73
                by (simp add: insert.prems(2) row_def)
lp15@67998
    74
            qed
lp15@67998
    75
            have 3: "?C $ k $ k \<noteq> 0"
lp15@67998
    76
              by (auto simp: insert.prems row_def \<open>k \<noteq> l\<close>)
lp15@67998
    77
            have PC: "P ?C"
lp15@67998
    78
              using insert.IH [OF 1 2 3] by auto
lp15@67998
    79
            have eqB: "(\<chi> i. if i = l then row l ?C + (B $ l $ k / B $ k $ k) *\<^sub>R row k ?C else row i ?C) = B"
lp15@67998
    80
              using \<open>k \<noteq> l\<close> by (simp add: vec_eq_iff row_def)
lp15@67998
    81
            show ?thesis
lp15@67998
    82
              using row_op [OF PC, of l k, where c = "B$l$k / B$k$k"] eqB \<open>k \<noteq> l\<close>
lp15@67998
    83
              by (simp add: cong: if_cong)
lp15@67998
    84
          qed
lp15@67998
    85
        qed
lp15@67998
    86
      qed
lp15@67998
    87
      then have nonzero_hyp: "P A"
lp15@67998
    88
        if kk: "A$k$k \<noteq> 0" and zeroes: "\<And>i j. j \<in> - insert k K \<and> i\<noteq>j \<Longrightarrow> A$i$j = 0" for A
lp15@67998
    89
        by (auto simp: intro!: kk zeroes)
lp15@67998
    90
      show ?case
lp15@67998
    91
      proof (cases "row k A = 0")
lp15@67998
    92
        case True
lp15@67998
    93
        with zero_row show ?thesis by auto
lp15@67998
    94
      next
lp15@67998
    95
        case False
lp15@67998
    96
        then obtain l where l: "A$k$l \<noteq> 0"
lp15@67998
    97
          by (auto simp: row_def zero_vec_def vec_eq_iff)
lp15@67998
    98
        show ?thesis
lp15@67998
    99
        proof (cases "k = l")
lp15@67998
   100
          case True
lp15@67998
   101
          with l nonzero_hyp insert.prems show ?thesis
lp15@67998
   102
            by blast
lp15@67998
   103
        next
lp15@67998
   104
          case False
lp15@67998
   105
          have *: "A $ i $ Fun.swap k l id j = 0" if "j \<noteq> k" "j \<notin> K" "i \<noteq> j" for i j
lp15@67998
   106
            using False l insert.prems that
lp15@67998
   107
            by (auto simp: swap_def insert split: if_split_asm)
lp15@67998
   108
          have "P (\<chi> i j. (\<chi> i j. A $ i $ Fun.swap k l id j) $ i $ Fun.swap k l id j)"
lp15@67998
   109
            by (rule swap_cols [OF nonzero_hyp False]) (auto simp: l *)
lp15@67998
   110
          moreover
lp15@67998
   111
          have "(\<chi> i j. (\<chi> i j. A $ i $ Fun.swap k l id j) $ i $ Fun.swap k l id j) = A"
lp15@67998
   112
            by (metis (no_types, lifting) id_apply o_apply swap_id_idempotent vec_lambda_unique vec_lambda_unique)
lp15@67998
   113
          ultimately show ?thesis
lp15@67998
   114
            by simp
lp15@67998
   115
        qed
lp15@67998
   116
      qed
lp15@67998
   117
    qed
lp15@67998
   118
  qed
lp15@67998
   119
  then show ?thesis
lp15@67998
   120
    by blast
lp15@67998
   121
qed
lp15@67998
   122
lp15@67998
   123
lemma induct_matrix_elementary:
lp15@67999
   124
  fixes P :: "real^'n^'n \<Rightarrow> bool"
lp15@67998
   125
  assumes mult: "\<And>A B. \<lbrakk>P A; P B\<rbrakk> \<Longrightarrow> P(A ** B)"
lp15@67998
   126
    and zero_row: "\<And>A i. row i A = 0 \<Longrightarrow> P A"
lp15@67998
   127
    and diagonal: "\<And>A. (\<And>i j. i \<noteq> j \<Longrightarrow> A$i$j = 0) \<Longrightarrow> P A"
lp15@67998
   128
    and swap1: "\<And>m n. m \<noteq> n \<Longrightarrow> P(\<chi> i j. mat 1 $ i $ Fun.swap m n id j)"
lp15@67998
   129
    and idplus: "\<And>m n c. m \<noteq> n \<Longrightarrow> P(\<chi> i j. if i = m \<and> j = n then c else of_bool (i = j))"
lp15@67998
   130
  shows "P A"
lp15@67998
   131
proof -
lp15@67998
   132
  have swap: "P (\<chi> i j. A $ i $ Fun.swap m n id j)"  (is "P ?C")
lp15@67998
   133
    if "P A" "m \<noteq> n" for A m n
lp15@67998
   134
  proof -
lp15@67998
   135
    have "A ** (\<chi> i j. mat 1 $ i $ Fun.swap m n id j) = ?C"
lp15@67998
   136
      by (simp add: matrix_matrix_mult_def mat_def vec_eq_iff if_distrib sum.delta_remove)
lp15@67998
   137
    then show ?thesis
lp15@67998
   138
      using mult swap1 that by metis
lp15@67998
   139
  qed
lp15@67998
   140
  have row: "P (\<chi> i. if i = m then row m A + c *\<^sub>R row n A else row i A)"  (is "P ?C")
lp15@67998
   141
    if "P A" "m \<noteq> n" for A m n c
lp15@67998
   142
  proof -
lp15@67998
   143
    let ?B = "\<chi> i j. if i = m \<and> j = n then c else of_bool (i = j)"
lp15@67998
   144
    have "?B ** A = ?C"
lp15@67998
   145
      using \<open>m \<noteq> n\<close> unfolding matrix_matrix_mult_def row_def of_bool_def
lp15@67998
   146
      by (auto simp: vec_eq_iff if_distrib [of "\<lambda>x. x * y" for y] sum.remove cong: if_cong)
lp15@67998
   147
    then show ?thesis
lp15@67998
   148
      by (rule subst) (auto simp: that mult idplus)
lp15@67998
   149
  qed
lp15@67998
   150
  show ?thesis
lp15@67998
   151
    by (rule induct_matrix_row_operations [OF zero_row diagonal swap row])
lp15@67998
   152
qed
lp15@67998
   153
lp15@67998
   154
lemma induct_matrix_elementary_alt:
lp15@67999
   155
  fixes P :: "real^'n^'n \<Rightarrow> bool"
lp15@67998
   156
  assumes mult: "\<And>A B. \<lbrakk>P A; P B\<rbrakk> \<Longrightarrow> P(A ** B)"
lp15@67998
   157
    and zero_row: "\<And>A i. row i A = 0 \<Longrightarrow> P A"
lp15@67998
   158
    and diagonal: "\<And>A. (\<And>i j. i \<noteq> j \<Longrightarrow> A$i$j = 0) \<Longrightarrow> P A"
lp15@67998
   159
    and swap1: "\<And>m n. m \<noteq> n \<Longrightarrow> P(\<chi> i j. mat 1 $ i $ Fun.swap m n id j)"
lp15@67998
   160
    and idplus: "\<And>m n. m \<noteq> n \<Longrightarrow> P(\<chi> i j. of_bool (i = m \<and> j = n \<or> i = j))"
lp15@67998
   161
  shows "P A"
lp15@67998
   162
proof -
lp15@67998
   163
  have *: "P (\<chi> i j. if i = m \<and> j = n then c else of_bool (i = j))"
lp15@67998
   164
    if "m \<noteq> n" for m n c
lp15@67998
   165
  proof (cases "c = 0")
lp15@67998
   166
    case True
lp15@67998
   167
    with diagonal show ?thesis by auto
lp15@67998
   168
  next
lp15@67998
   169
    case False
lp15@67998
   170
    then have eq: "(\<chi> i j. if i = m \<and> j = n then c else of_bool (i = j)) =
lp15@67998
   171
                      (\<chi> i j. if i = j then (if j = n then inverse c else 1) else 0) **
lp15@67998
   172
                      (\<chi> i j. of_bool (i = m \<and> j = n \<or> i = j)) **
lp15@67998
   173
                      (\<chi> i j. if i = j then if j = n then c else 1 else 0)"
lp15@67998
   174
      using \<open>m \<noteq> n\<close>
lp15@67998
   175
      apply (simp add: matrix_matrix_mult_def vec_eq_iff of_bool_def if_distrib [of "\<lambda>x. y * x" for y] cong: if_cong)
lp15@67998
   176
      apply (simp add: if_if_eq_conj sum.neutral conj_commute cong: conj_cong)
lp15@67998
   177
      done
lp15@67998
   178
    show ?thesis
lp15@67998
   179
      apply (subst eq)
lp15@67998
   180
      apply (intro mult idplus that)
lp15@67998
   181
       apply (auto intro: diagonal)
lp15@67998
   182
      done
lp15@67998
   183
  qed
lp15@67998
   184
  show ?thesis
lp15@67998
   185
    by (rule induct_matrix_elementary) (auto intro: assms *)
lp15@67998
   186
qed
lp15@67998
   187
lp15@67998
   188
lemma induct_linear_elementary:
lp15@67998
   189
  fixes f :: "real^'n \<Rightarrow> real^'n"
lp15@67998
   190
  assumes "linear f"
lp15@67998
   191
    and comp: "\<And>f g. \<lbrakk>linear f; linear g; P f; P g\<rbrakk> \<Longrightarrow> P(f \<circ> g)"
lp15@67998
   192
    and zeroes: "\<And>f i. \<lbrakk>linear f; \<And>x. (f x) $ i = 0\<rbrakk> \<Longrightarrow> P f"
lp15@67998
   193
    and const: "\<And>c. P(\<lambda>x. \<chi> i. c i * x$i)"
lp15@67998
   194
    and swap: "\<And>m n::'n. m \<noteq> n \<Longrightarrow> P(\<lambda>x. \<chi> i. x $ Fun.swap m n id i)"
lp15@67998
   195
    and idplus: "\<And>m n::'n. m \<noteq> n \<Longrightarrow> P(\<lambda>x. \<chi> i. if i = m then x$m + x$n else x$i)"
lp15@67998
   196
  shows "P f"
lp15@67998
   197
proof -
lp15@67998
   198
  have "P (( *v) A)" for A
lp15@67998
   199
  proof (rule induct_matrix_elementary_alt)
lp15@67998
   200
    fix A B
lp15@67998
   201
    assume "P (( *v) A)" and "P (( *v) B)"
lp15@67998
   202
    then show "P (( *v) (A ** B))"
lp15@67998
   203
      by (metis (no_types, lifting) comp linear_compose matrix_compose matrix_eq matrix_vector_mul matrix_vector_mul_linear)
lp15@67998
   204
  next
lp15@67999
   205
    fix A :: "real^'n^'n" and i
lp15@67998
   206
    assume "row i A = 0"
lp15@67998
   207
    then show "P (( *v) A)"
lp15@67998
   208
      by (metis inner_zero_left matrix_vector_mul_component matrix_vector_mul_linear row_def vec_eq_iff vec_lambda_beta zeroes)
lp15@67998
   209
  next
lp15@67999
   210
    fix A :: "real^'n^'n"
lp15@67998
   211
    assume 0: "\<And>i j. i \<noteq> j \<Longrightarrow> A $ i $ j = 0"
lp15@67999
   212
    have "A $ i $ i * x $ i = (\<Sum>j\<in>UNIV. A $ i $ j * x $ j)" for x and i :: "'n"
lp15@67998
   213
      by (simp add: 0 comm_monoid_add_class.sum.remove [where x=i])
lp15@67998
   214
    then have "(\<lambda>x. \<chi> i. A $ i $ i * x $ i) = (( *v) A)"
lp15@67998
   215
      by (auto simp: 0 matrix_vector_mult_def)
lp15@67998
   216
    then show "P (( *v) A)"
lp15@67998
   217
      using const [of "\<lambda>i. A $ i $ i"] by simp
lp15@67998
   218
  next
lp15@67998
   219
    fix m n :: "'n"
lp15@67998
   220
    assume "m \<noteq> n"
lp15@67998
   221
    have eq: "(\<Sum>j\<in>UNIV. if i = Fun.swap m n id j then x $ j else 0) =
lp15@67998
   222
              (\<Sum>j\<in>UNIV. if j = Fun.swap m n id i then x $ j else 0)"
lp15@67999
   223
      for i and x :: "real^'n"
lp15@67998
   224
      unfolding swap_def by (rule sum.cong) auto
lp15@67998
   225
    have "(\<lambda>x::real^'n. \<chi> i. x $ Fun.swap m n id i) = (( *v) (\<chi> i j. if i = Fun.swap m n id j then 1 else 0))"
lp15@67998
   226
      by (auto simp: mat_def matrix_vector_mult_def eq if_distrib [of "\<lambda>x. x * y" for y] cong: if_cong)
lp15@67998
   227
    with swap [OF \<open>m \<noteq> n\<close>] show "P (( *v) (\<chi> i j. mat 1 $ i $ Fun.swap m n id j))"
lp15@67998
   228
      by (simp add: mat_def matrix_vector_mult_def)
lp15@67998
   229
  next
lp15@67998
   230
    fix m n :: "'n"
lp15@67998
   231
    assume "m \<noteq> n"
lp15@67999
   232
    then have "x $ m + x $ n = (\<Sum>j\<in>UNIV. of_bool (j = n \<or> m = j) * x $ j)" for x :: "real^'n"
lp15@67998
   233
      by (auto simp: of_bool_def if_distrib [of "\<lambda>x. x * y" for y] sum.remove cong: if_cong)
lp15@67998
   234
    then have "(\<lambda>x::real^'n. \<chi> i. if i = m then x $ m + x $ n else x $ i) =
lp15@67998
   235
               (( *v) (\<chi> i j. of_bool (i = m \<and> j = n \<or> i = j)))"
lp15@67998
   236
      unfolding matrix_vector_mult_def of_bool_def
lp15@67998
   237
      by (auto simp: vec_eq_iff if_distrib [of "\<lambda>x. x * y" for y] cong: if_cong)
lp15@67998
   238
    then show "P (( *v) (\<chi> i j. of_bool (i = m \<and> j = n \<or> i = j)))"
lp15@67998
   239
      using idplus [OF \<open>m \<noteq> n\<close>] by simp
lp15@67998
   240
  qed
lp15@67998
   241
  then show ?thesis
lp15@67998
   242
    by (metis \<open>linear f\<close> matrix_vector_mul)
lp15@67998
   243
qed
lp15@67998
   244
lp15@67998
   245
lp15@67998
   246
proposition
lp15@67998
   247
  fixes a :: "real^'n"
lp15@67998
   248
  assumes "m \<noteq> n" and ab_ne: "cbox a b \<noteq> {}" and an: "0 \<le> a$n"
lp15@67998
   249
  shows measurable_shear_interval: "(\<lambda>x. \<chi> i. if i = m then x$m + x$n else x$i) ` (cbox a b) \<in> lmeasurable"
lp15@67998
   250
       (is  "?f ` _ \<in> _")
lp15@67998
   251
   and measure_shear_interval: "measure lebesgue ((\<lambda>x. \<chi> i. if i = m then x$m + x$n else x$i) ` cbox a b)
lp15@67998
   252
               = measure lebesgue (cbox a b)" (is "?Q")
lp15@67998
   253
proof -
lp15@67998
   254
  have lin: "linear ?f"
lp15@67998
   255
    by (force simp: plus_vec_def scaleR_vec_def algebra_simps intro: linearI)
lp15@67998
   256
  show fab: "?f ` cbox a b \<in> lmeasurable"
lp15@67998
   257
    by (simp add: lin measurable_linear_image_interval)
lp15@67998
   258
  let ?c = "\<chi> i. if i = m then b$m + b$n else b$i"
lp15@67998
   259
  let ?mn = "axis m 1 - axis n (1::real)"
lp15@67998
   260
  have eq1: "measure lebesgue (cbox a ?c)
lp15@67998
   261
            = measure lebesgue (?f ` cbox a b)
lp15@67998
   262
            + measure lebesgue (cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a$m})
lp15@67998
   263
            + measure lebesgue (cbox a ?c \<inter> {x. ?mn \<bullet> x \<ge> b$m})"
lp15@67998
   264
  proof (rule measure_Un3_negligible)
lp15@67998
   265
    show "cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a$m} \<in> lmeasurable" "cbox a ?c \<inter> {x. ?mn \<bullet> x \<ge> b$m} \<in> lmeasurable"
lp15@67998
   266
      by (auto simp: convex_Int convex_halfspace_le convex_halfspace_ge bounded_Int measurable_convex)
lp15@67998
   267
    have "negligible {x. ?mn \<bullet> x = a$m}"
lp15@67998
   268
      by (metis \<open>m \<noteq> n\<close> axis_index_axis eq_iff_diff_eq_0 negligible_hyperplane)
lp15@67998
   269
    moreover have "?f ` cbox a b \<inter> (cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a $ m}) \<subseteq> {x. ?mn \<bullet> x = a$m}"
lp15@67998
   270
      using \<open>m \<noteq> n\<close> antisym_conv by (fastforce simp: algebra_simps mem_box_cart inner_axis')
lp15@67998
   271
    ultimately show "negligible ((?f ` cbox a b) \<inter> (cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a $ m}))"
lp15@67998
   272
      by (rule negligible_subset)
lp15@67998
   273
    have "negligible {x. ?mn \<bullet> x = b$m}"
lp15@67998
   274
      by (metis \<open>m \<noteq> n\<close> axis_index_axis eq_iff_diff_eq_0 negligible_hyperplane)
lp15@67998
   275
    moreover have "(?f ` cbox a b) \<inter> (cbox a ?c \<inter> {x. ?mn \<bullet> x \<ge> b$m}) \<subseteq> {x. ?mn \<bullet> x = b$m}"
lp15@67998
   276
      using \<open>m \<noteq> n\<close> antisym_conv by (fastforce simp: algebra_simps mem_box_cart inner_axis')
lp15@67998
   277
    ultimately show "negligible (?f ` cbox a b \<inter> (cbox a ?c \<inter> {x. ?mn \<bullet> x \<ge> b$m}))"
lp15@67998
   278
      by (rule negligible_subset)
lp15@67998
   279
    have "negligible {x. ?mn \<bullet> x = b$m}"
lp15@67998
   280
      by (metis \<open>m \<noteq> n\<close> axis_index_axis eq_iff_diff_eq_0 negligible_hyperplane)
lp15@67998
   281
    moreover have "(cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a $ m} \<inter> (cbox a ?c \<inter> {x. ?mn \<bullet> x \<ge> b$m})) \<subseteq> {x. ?mn \<bullet> x = b$m}"
lp15@67998
   282
      using \<open>m \<noteq> n\<close> ab_ne
lp15@67998
   283
      apply (auto simp: algebra_simps mem_box_cart inner_axis')
lp15@67998
   284
      apply (drule_tac x=m in spec)+
lp15@67998
   285
      apply simp
lp15@67998
   286
      done
lp15@67998
   287
    ultimately show "negligible (cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a $ m} \<inter> (cbox a ?c \<inter> {x. ?mn \<bullet> x \<ge> b$m}))"
lp15@67998
   288
      by (rule negligible_subset)
lp15@67998
   289
    show "?f ` cbox a b \<union> cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a $ m} \<union> cbox a ?c \<inter> {x. ?mn \<bullet> x \<ge> b$m} = cbox a ?c" (is "?lhs = _")
lp15@67998
   290
    proof
lp15@67998
   291
      show "?lhs \<subseteq> cbox a ?c"
lp15@67998
   292
        by (auto simp: mem_box_cart add_mono) (meson add_increasing2 an order_trans)
lp15@67998
   293
      show "cbox a ?c \<subseteq> ?lhs"
lp15@67998
   294
        apply (auto simp: algebra_simps image_iff inner_axis' lambda_add_Galois [OF \<open>m \<noteq> n\<close>])
lp15@67998
   295
        apply (auto simp: mem_box_cart split: if_split_asm)
lp15@67998
   296
        done
lp15@67998
   297
    qed
lp15@67998
   298
  qed (fact fab)
lp15@67998
   299
  let ?d = "\<chi> i. if i = m then a $ m - b $ m else 0"
lp15@67998
   300
  have eq2: "measure lebesgue (cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a $ m}) + measure lebesgue (cbox a ?c \<inter> {x. ?mn \<bullet> x \<ge> b$m})
lp15@67998
   301
           = measure lebesgue (cbox a (\<chi> i. if i = m then a $ m + b $ n else b $ i))"
lp15@67998
   302
  proof (rule measure_translate_add[of "cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a$m}" "cbox a ?c \<inter> {x. ?mn \<bullet> x \<ge> b$m}"
lp15@67998
   303
     "(\<chi> i. if i = m then a$m - b$m else 0)" "cbox a (\<chi> i. if i = m then a$m + b$n else b$i)"])
lp15@67998
   304
    show "(cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a$m}) \<in> lmeasurable"
lp15@67998
   305
      "cbox a ?c \<inter> {x. ?mn \<bullet> x \<ge> b$m} \<in> lmeasurable"
lp15@67998
   306
      by (auto simp: convex_Int convex_halfspace_le convex_halfspace_ge bounded_Int measurable_convex)
lp15@67998
   307
    have "\<And>x. \<lbrakk>x $ n + a $ m \<le> x $ m\<rbrakk>
lp15@67998
   308
         \<Longrightarrow> x \<in> (+) (\<chi> i. if i = m then a $ m - b $ m else 0) ` {x. x $ n + b $ m \<le> x $ m}"
lp15@67998
   309
      using \<open>m \<noteq> n\<close>
lp15@67998
   310
      by (rule_tac x="x - (\<chi> i. if i = m then a$m - b$m else 0)" in image_eqI)
lp15@67998
   311
         (simp_all add: mem_box_cart)
lp15@67998
   312
    then have imeq: "(+) ?d ` {x. b $ m \<le> ?mn \<bullet> x} = {x. a $ m \<le> ?mn \<bullet> x}"
lp15@67998
   313
      using \<open>m \<noteq> n\<close> by (auto simp: mem_box_cart inner_axis' algebra_simps)
lp15@67998
   314
    have "\<And>x. \<lbrakk>0 \<le> a $ n; x $ n + a $ m \<le> x $ m;
lp15@67998
   315
                \<forall>i. i \<noteq> m \<longrightarrow> a $ i \<le> x $ i \<and> x $ i \<le> b $ i\<rbrakk>
lp15@67998
   316
         \<Longrightarrow> a $ m \<le> x $ m"
lp15@67998
   317
      using \<open>m \<noteq> n\<close>  by force
lp15@67998
   318
    then have "(+) ?d ` (cbox a ?c \<inter> {x. b $ m \<le> ?mn \<bullet> x})
lp15@67998
   319
            = cbox a (\<chi> i. if i = m then a $ m + b $ n else b $ i) \<inter> {x. a $ m \<le> ?mn \<bullet> x}"
lp15@67998
   320
      using an ab_ne
lp15@67998
   321
      apply (simp add: cbox_translation [symmetric] translation_Int interval_ne_empty_cart imeq)
lp15@67998
   322
      apply (auto simp: mem_box_cart inner_axis' algebra_simps if_distrib all_if_distrib)
lp15@67998
   323
      by (metis (full_types) add_mono mult_2_right)
lp15@67998
   324
    then show "cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a $ m} \<union>
lp15@67998
   325
          (+) ?d ` (cbox a ?c \<inter> {x. b $ m \<le> ?mn \<bullet> x}) =
lp15@67998
   326
          cbox a (\<chi> i. if i = m then a $ m + b $ n else b $ i)"  (is "?lhs = ?rhs")
lp15@67998
   327
      using an \<open>m \<noteq> n\<close>
lp15@67998
   328
      apply (auto simp: mem_box_cart inner_axis' algebra_simps if_distrib all_if_distrib, force)
lp15@67998
   329
        apply (drule_tac x=n in spec)+
lp15@67998
   330
      by (meson ab_ne add_mono_thms_linordered_semiring(3) dual_order.trans interval_ne_empty_cart(1))
lp15@67998
   331
    have "negligible{x. ?mn \<bullet> x = a$m}"
lp15@67998
   332
      by (metis \<open>m \<noteq> n\<close> axis_index_axis eq_iff_diff_eq_0 negligible_hyperplane)
lp15@67998
   333
    moreover have "(cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a $ m} \<inter>
lp15@67998
   334
                                 (+) ?d ` (cbox a ?c \<inter> {x. b $ m \<le> ?mn \<bullet> x})) \<subseteq> {x. ?mn \<bullet> x = a$m}"
lp15@67998
   335
      using \<open>m \<noteq> n\<close> antisym_conv by (fastforce simp: algebra_simps mem_box_cart inner_axis')
lp15@67998
   336
    ultimately show "negligible (cbox a ?c \<inter> {x. ?mn \<bullet> x \<le> a $ m} \<inter>
lp15@67998
   337
                                 (+) ?d ` (cbox a ?c \<inter> {x. b $ m \<le> ?mn \<bullet> x}))"
lp15@67998
   338
      by (rule negligible_subset)
lp15@67998
   339
  qed
lp15@67998
   340
  have ac_ne: "cbox a ?c \<noteq> {}"
lp15@67998
   341
    using ab_ne an
lp15@67998
   342
    by (clarsimp simp: interval_eq_empty_cart) (meson add_less_same_cancel1 le_less_linear less_le_trans)
lp15@67998
   343
  have ax_ne: "cbox a (\<chi> i. if i = m then a $ m + b $ n else b $ i) \<noteq> {}"
lp15@67998
   344
    using ab_ne an
lp15@67998
   345
    by (clarsimp simp: interval_eq_empty_cart) (meson add_less_same_cancel1 le_less_linear less_le_trans)
lp15@67998
   346
  have eq3: "measure lebesgue (cbox a ?c) = measure lebesgue (cbox a (\<chi> i. if i = m then a$m + b$n else b$i)) + measure lebesgue (cbox a b)"
lp15@67998
   347
    by (simp add: content_cbox_if_cart ab_ne ac_ne ax_ne algebra_simps prod.delta_remove
lp15@67998
   348
             if_distrib [of "\<lambda>u. u - z" for z] prod.remove)
lp15@67998
   349
  show ?Q
lp15@67998
   350
    using eq1 eq2 eq3
lp15@67998
   351
    by (simp add: algebra_simps)
lp15@67998
   352
qed
lp15@67998
   353
lp15@67998
   354
lp15@67998
   355
proposition
lp15@67998
   356
  fixes S :: "(real^'n) set"
lp15@67998
   357
  assumes "S \<in> lmeasurable"
lp15@67998
   358
  shows measurable_stretch: "((\<lambda>x. \<chi> k. m k * x$k) ` S) \<in> lmeasurable" (is  "?f ` S \<in> _")
lp15@67998
   359
    and measure_stretch: "measure lebesgue ((\<lambda>x. \<chi> k. m k * x$k) ` S) = \<bar>prod m UNIV\<bar> * measure lebesgue S"
lp15@67998
   360
    (is "?MEQ")
lp15@67998
   361
proof -
lp15@67998
   362
  have "(?f ` S) \<in> lmeasurable \<and> ?MEQ"
lp15@67998
   363
  proof (cases "\<forall>k. m k \<noteq> 0")
lp15@67998
   364
    case True
lp15@67998
   365
    have m0: "0 < \<bar>prod m UNIV\<bar>"
lp15@67998
   366
      using True by simp
lp15@67998
   367
    have "(indicat_real (?f ` S) has_integral \<bar>prod m UNIV\<bar> * measure lebesgue S) UNIV"
lp15@67998
   368
    proof (clarsimp simp add: has_integral_alt [where i=UNIV])
lp15@67998
   369
      fix e :: "real"
lp15@67998
   370
      assume "e > 0"
lp15@67998
   371
      have "(indicat_real S has_integral (measure lebesgue S)) UNIV"
lp15@67998
   372
        using assms lmeasurable_iff_has_integral by blast
lp15@67998
   373
      then obtain B where "B>0"
lp15@67998
   374
        and B: "\<And>a b. ball 0 B \<subseteq> cbox a b \<Longrightarrow>
lp15@67998
   375
                        \<exists>z. (indicat_real S has_integral z) (cbox a b) \<and>
lp15@67998
   376
                            \<bar>z - measure lebesgue S\<bar> < e / \<bar>prod m UNIV\<bar>"
lp15@67998
   377
        by (simp add: has_integral_alt [where i=UNIV]) (metis (full_types) divide_pos_pos m0  m0 \<open>e > 0\<close>)
lp15@67998
   378
      show "\<exists>B>0. \<forall>a b. ball 0 B \<subseteq> cbox a b \<longrightarrow>
lp15@67998
   379
                  (\<exists>z. (indicat_real (?f ` S) has_integral z) (cbox a b) \<and>
lp15@67998
   380
                       \<bar>z - \<bar>prod m UNIV\<bar> * measure lebesgue S\<bar> < e)"
lp15@67998
   381
      proof (intro exI conjI allI)
lp15@67998
   382
        let ?C = "Max (range (\<lambda>k. \<bar>m k\<bar>)) * B"
lp15@67998
   383
        show "?C > 0"
lp15@67998
   384
          using True \<open>B > 0\<close> by (simp add: Max_gr_iff)
lp15@67998
   385
        show "ball 0 ?C \<subseteq> cbox u v \<longrightarrow>
lp15@67998
   386
                  (\<exists>z. (indicat_real (?f ` S) has_integral z) (cbox u v) \<and>
lp15@67998
   387
                       \<bar>z - \<bar>prod m UNIV\<bar> * measure lebesgue S\<bar> < e)" for u v
lp15@67998
   388
        proof
lp15@67998
   389
          assume uv: "ball 0 ?C \<subseteq> cbox u v"
lp15@67998
   390
          with \<open>?C > 0\<close> have cbox_ne: "cbox u v \<noteq> {}"
lp15@67998
   391
            using centre_in_ball by blast
lp15@67998
   392
          let ?\<alpha> = "\<lambda>k. u$k / m k"
lp15@67998
   393
          let ?\<beta> = "\<lambda>k. v$k / m k"
lp15@67998
   394
          have invm0: "\<And>k. inverse (m k) \<noteq> 0"
lp15@67998
   395
            using True by auto
lp15@67998
   396
          have "ball 0 B \<subseteq> (\<lambda>x. \<chi> k. x $ k / m k) ` ball 0 ?C"
lp15@67998
   397
          proof clarsimp
lp15@67999
   398
            fix x :: "real^'n"
lp15@67998
   399
            assume x: "norm x < B"
lp15@67998
   400
            have [simp]: "\<bar>Max (range (\<lambda>k. \<bar>m k\<bar>))\<bar> = Max (range (\<lambda>k. \<bar>m k\<bar>))"
lp15@67998
   401
              by (meson Max_ge abs_ge_zero abs_of_nonneg finite finite_imageI order_trans rangeI)
lp15@67998
   402
            have "norm (\<chi> k. m k * x $ k) \<le> norm (Max (range (\<lambda>k. \<bar>m k\<bar>)) *\<^sub>R x)"
lp15@67998
   403
              by (rule norm_le_componentwise_cart) (auto simp: abs_mult intro: mult_right_mono)
lp15@67998
   404
            also have "\<dots> < ?C"
lp15@67998
   405
              using x by simp (metis \<open>B > 0\<close> \<open>?C > 0\<close> mult.commute real_mult_less_iff1 zero_less_mult_pos)
lp15@67998
   406
            finally have "norm (\<chi> k. m k * x $ k) < ?C" .
lp15@67998
   407
            then show "x \<in> (\<lambda>x. \<chi> k. x $ k / m k) ` ball 0 ?C"
lp15@67998
   408
              using stretch_Galois [of "inverse \<circ> m"] True by (auto simp: image_iff field_simps)
lp15@67998
   409
          qed
lp15@67998
   410
          then have Bsub: "ball 0 B \<subseteq> cbox (\<chi> k. min (?\<alpha> k) (?\<beta> k)) (\<chi> k. max (?\<alpha> k) (?\<beta> k))"
lp15@67998
   411
            using cbox_ne uv image_stretch_interval_cart [of "inverse \<circ> m" u v, symmetric]
lp15@67998
   412
            by (force simp: field_simps)
lp15@67998
   413
          obtain z where zint: "(indicat_real S has_integral z) (cbox (\<chi> k. min (?\<alpha> k) (?\<beta> k)) (\<chi> k. max (?\<alpha> k) (?\<beta> k)))"
lp15@67998
   414
                   and zless: "\<bar>z - measure lebesgue S\<bar> < e / \<bar>prod m UNIV\<bar>"
lp15@67998
   415
            using B [OF Bsub] by blast
lp15@67998
   416
          have ind: "indicat_real (?f ` S) = (\<lambda>x. indicator S (\<chi> k. x$k / m k))"
lp15@67998
   417
            using True stretch_Galois [of m] by (force simp: indicator_def)
lp15@67998
   418
          show "\<exists>z. (indicat_real (?f ` S) has_integral z) (cbox u v) \<and>
lp15@67998
   419
                       \<bar>z - \<bar>prod m UNIV\<bar> * measure lebesgue S\<bar> < e"
lp15@67998
   420
          proof (simp add: ind, intro conjI exI)
lp15@67998
   421
            have "((\<lambda>x. indicat_real S (\<chi> k. x $ k/ m k)) has_integral z *\<^sub>R \<bar>prod m UNIV\<bar>)
lp15@67998
   422
                ((\<lambda>x. \<chi> k. x $ k * m k) ` cbox (\<chi> k. min (?\<alpha> k) (?\<beta> k)) (\<chi> k. max (?\<alpha> k) (?\<beta> k)))"
lp15@67998
   423
              using True has_integral_stretch_cart [OF zint, of "inverse \<circ> m"]
lp15@67998
   424
              by (simp add: field_simps prod_dividef)
lp15@67998
   425
            moreover have "((\<lambda>x. \<chi> k. x $ k * m k) ` cbox (\<chi> k. min (?\<alpha> k) (?\<beta> k)) (\<chi> k. max (?\<alpha> k) (?\<beta> k))) = cbox u v"
lp15@67998
   426
              using True image_stretch_interval_cart [of "inverse \<circ> m" u v, symmetric]
lp15@67998
   427
                image_stretch_interval_cart [of "\<lambda>k. 1" u v, symmetric] \<open>cbox u v \<noteq> {}\<close>
lp15@67998
   428
              by (simp add: field_simps image_comp o_def)
lp15@67998
   429
            ultimately show "((\<lambda>x. indicat_real S (\<chi> k. x $ k/ m k)) has_integral z *\<^sub>R \<bar>prod m UNIV\<bar>) (cbox u v)"
lp15@67998
   430
              by simp
lp15@67998
   431
            have "\<bar>z *\<^sub>R \<bar>prod m UNIV\<bar> - \<bar>prod m UNIV\<bar> * measure lebesgue S\<bar>
lp15@67998
   432
                 = \<bar>prod m UNIV\<bar> * \<bar>z - measure lebesgue S\<bar>"
lp15@67998
   433
              by (metis (no_types, hide_lams) abs_abs abs_scaleR mult.commute real_scaleR_def right_diff_distrib')
lp15@67998
   434
            also have "\<dots> < e"
lp15@67998
   435
              using zless True by (simp add: field_simps)
lp15@67998
   436
            finally show "\<bar>z *\<^sub>R \<bar>prod m UNIV\<bar> - \<bar>prod m UNIV\<bar> * measure lebesgue S\<bar> < e" .
lp15@67998
   437
          qed
lp15@67998
   438
        qed
lp15@67998
   439
      qed
lp15@67998
   440
    qed
lp15@67998
   441
    then show ?thesis
lp15@67998
   442
      by (auto simp: has_integral_integrable integral_unique lmeasure_integral_UNIV measurable_integrable)
lp15@67998
   443
  next
lp15@67998
   444
    case False
lp15@67998
   445
    then obtain k where "m k = 0" and prm: "prod m UNIV = 0"
lp15@67998
   446
      by auto
lp15@67998
   447
    have nfS: "negligible (?f ` S)"
lp15@67998
   448
      by (rule negligible_subset [OF negligible_standard_hyperplane_cart]) (use \<open>m k = 0\<close> in auto)
lp15@67998
   449
    then have "(?f ` S) \<in> lmeasurable"
lp15@67998
   450
      by (simp add: negligible_iff_measure)
lp15@67998
   451
    with nfS show ?thesis
lp15@67998
   452
      by (simp add: prm negligible_iff_measure0)
lp15@67998
   453
  qed
lp15@67998
   454
  then show "(?f ` S) \<in> lmeasurable" ?MEQ
lp15@67998
   455
    by metis+
lp15@67998
   456
qed
lp15@67998
   457
lp15@67998
   458
lp15@67998
   459
proposition
lp15@67998
   460
 fixes f :: "real^'n::{finite,wellorder} \<Rightarrow> real^'n::_"
lp15@67998
   461
  assumes "linear f" "S \<in> lmeasurable"
lp15@67998
   462
  shows measurable_linear_image: "(f ` S) \<in> lmeasurable"
lp15@67998
   463
    and measure_linear_image: "measure lebesgue (f ` S) = \<bar>det (matrix f)\<bar> * measure lebesgue S" (is "?Q f S")
lp15@67998
   464
proof -
lp15@67998
   465
  have "\<forall>S \<in> lmeasurable. (f ` S) \<in> lmeasurable \<and> ?Q f S"
lp15@67998
   466
  proof (rule induct_linear_elementary [OF \<open>linear f\<close>]; intro ballI)
lp15@67998
   467
    fix f g and S :: "(real,'n) vec set"
lp15@67998
   468
    assume "linear f" and "linear g"
lp15@67998
   469
      and f [rule_format]: "\<forall>S \<in> lmeasurable. f ` S \<in> lmeasurable \<and> ?Q f S"
lp15@67998
   470
      and g [rule_format]: "\<forall>S \<in> lmeasurable. g ` S \<in> lmeasurable \<and> ?Q g S"
lp15@67998
   471
      and S: "S \<in> lmeasurable"
lp15@67998
   472
    then have gS: "g ` S \<in> lmeasurable"
lp15@67998
   473
      by blast
lp15@67998
   474
    show "(f \<circ> g) ` S \<in> lmeasurable \<and> ?Q (f \<circ> g) S"
lp15@67998
   475
      using f [OF gS] g [OF S] matrix_compose [OF \<open>linear g\<close> \<open>linear f\<close>]
lp15@67998
   476
      by (simp add: o_def image_comp abs_mult det_mul)
lp15@67998
   477
  next
lp15@67999
   478
    fix f :: "real^'n::_ \<Rightarrow> real^'n::_" and i and S :: "(real^'n::_) set"
lp15@67998
   479
    assume "linear f" and 0: "\<And>x. f x $ i = 0" and "S \<in> lmeasurable"
lp15@67998
   480
    then have "\<not> inj f"
lp15@67998
   481
      by (metis (full_types) linear_injective_imp_surjective one_neq_zero surjE vec_component)
lp15@67998
   482
    have detf: "det (matrix f) = 0"
lp15@67998
   483
      by (metis "0" \<open>linear f\<close> invertible_det_nz invertible_right_inverse matrix_right_invertible_surjective matrix_vector_mul surjE vec_component)
lp15@67998
   484
    show "f ` S \<in> lmeasurable \<and> ?Q f S"
lp15@67998
   485
    proof
lp15@67998
   486
      show "f ` S \<in> lmeasurable"
lp15@67998
   487
        using lmeasurable_iff_indicator_has_integral \<open>linear f\<close> \<open>\<not> inj f\<close> negligible_UNIV negligible_linear_singular_image by blast
lp15@67998
   488
      have "measure lebesgue (f ` S) = 0"
lp15@67998
   489
        by (meson \<open>\<not> inj f\<close> \<open>linear f\<close> negligible_imp_measure0 negligible_linear_singular_image)
lp15@67998
   490
      also have "\<dots> = \<bar>det (matrix f)\<bar> * measure lebesgue S"
lp15@67998
   491
        by (simp add: detf)
lp15@67998
   492
      finally show "?Q f S" .
lp15@67998
   493
    qed
lp15@67998
   494
  next
lp15@67999
   495
    fix c and S :: "(real^'n::_) set"
lp15@67998
   496
    assume "S \<in> lmeasurable"
lp15@67998
   497
    show "(\<lambda>a. \<chi> i. c i * a $ i) ` S \<in> lmeasurable \<and> ?Q (\<lambda>a. \<chi> i. c i * a $ i) S"
lp15@67998
   498
    proof
lp15@67998
   499
      show "(\<lambda>a. \<chi> i. c i * a $ i) ` S \<in> lmeasurable"
lp15@67998
   500
        by (simp add: \<open>S \<in> lmeasurable\<close> measurable_stretch)
lp15@67998
   501
      show "?Q (\<lambda>a. \<chi> i. c i * a $ i) S"
lp15@67998
   502
        by (simp add: measure_stretch [OF \<open>S \<in> lmeasurable\<close>, of c] axis_def matrix_def det_diagonal)
lp15@67998
   503
    qed
lp15@67998
   504
  next
lp15@67998
   505
    fix m :: "'n" and n :: "'n" and S :: "(real, 'n) vec set"
lp15@67998
   506
    assume "m \<noteq> n" and "S \<in> lmeasurable"
lp15@67998
   507
    let ?h = "\<lambda>v::(real, 'n) vec. \<chi> i. v $ Fun.swap m n id i"
lp15@67998
   508
    have lin: "linear ?h"
lp15@67998
   509
      by (simp add: plus_vec_def scaleR_vec_def linearI)
lp15@67998
   510
    have meq: "measure lebesgue ((\<lambda>v::(real, 'n) vec. \<chi> i. v $ Fun.swap m n id i) ` cbox a b)
lp15@67998
   511
             = measure lebesgue (cbox a b)" for a b
lp15@67998
   512
    proof (cases "cbox a b = {}")
lp15@67998
   513
      case True then show ?thesis
lp15@67998
   514
        by simp
lp15@67998
   515
    next
lp15@67998
   516
      case False
lp15@67998
   517
      then have him: "?h ` (cbox a b) \<noteq> {}"
lp15@67998
   518
        by blast
lp15@67998
   519
      have eq: "?h ` (cbox a b) = cbox (?h a) (?h b)"
lp15@67998
   520
        by (auto simp: image_iff lambda_swap_Galois mem_box_cart) (metis swap_id_eq)+
lp15@67998
   521
      show ?thesis
lp15@67998
   522
        using him prod.permute [OF permutes_swap_id, where S=UNIV and g="\<lambda>i. (b - a)$i", symmetric]
lp15@67998
   523
        by (simp add: eq content_cbox_cart False)
lp15@67998
   524
    qed
lp15@67998
   525
    have "(\<chi> i j. if Fun.swap m n id i = j then 1 else 0) = (\<chi> i j. if j = Fun.swap m n id i then 1 else (0::real))"
lp15@67998
   526
      by (auto intro!: Cart_lambda_cong)
lp15@67998
   527
    then have "matrix ?h = transpose(\<chi> i j. mat 1 $ i $ Fun.swap m n id j)"
lp15@67998
   528
      by (auto simp: matrix_eq transpose_def axis_def mat_def matrix_def)
lp15@67998
   529
    then have 1: "\<bar>det (matrix ?h)\<bar> = 1"
lp15@67998
   530
      by (simp add: det_permute_columns permutes_swap_id sign_swap_id abs_mult)
lp15@67998
   531
    show "?h ` S \<in> lmeasurable \<and> ?Q ?h S"
lp15@67998
   532
    proof
lp15@67998
   533
      show "?h ` S \<in> lmeasurable" "?Q ?h S"
lp15@67998
   534
        using measure_linear_sufficient [OF lin \<open>S \<in> lmeasurable\<close>] meq 1 by force+
lp15@67998
   535
    qed
lp15@67998
   536
  next
lp15@67999
   537
    fix m n :: "'n" and S :: "(real, 'n) vec set"
lp15@67998
   538
    assume "m \<noteq> n" and "S \<in> lmeasurable"
lp15@67998
   539
    let ?h = "\<lambda>v::(real, 'n) vec. \<chi> i. if i = m then v $ m + v $ n else v $ i"
lp15@67998
   540
    have lin: "linear ?h"
lp15@67998
   541
      by (auto simp: algebra_simps plus_vec_def scaleR_vec_def vec_eq_iff intro: linearI)
lp15@67998
   542
    consider "m < n" | " n < m"
lp15@67998
   543
      using \<open>m \<noteq> n\<close> less_linear by blast
lp15@67998
   544
    then have 1: "det(matrix ?h) = 1"
lp15@67998
   545
    proof cases
lp15@67998
   546
      assume "m < n"
lp15@67998
   547
      have *: "matrix ?h $ i $ j = (0::real)" if "j < i" for i j :: 'n
lp15@67998
   548
      proof -
lp15@67998
   549
        have "axis j 1 = (\<chi> n. if n = j then 1 else (0::real))"
lp15@67998
   550
          using axis_def by blast
lp15@67998
   551
        then have "(\<chi> p q. if p = m then axis q 1 $ m + axis q 1 $ n else axis q 1 $ p) $ i $ j = (0::real)"
lp15@67998
   552
          using \<open>j < i\<close> axis_def \<open>m < n\<close> by auto
lp15@67998
   553
        with \<open>m < n\<close> show ?thesis
lp15@67998
   554
          by (auto simp: matrix_def axis_def cong: if_cong)
lp15@67998
   555
      qed
lp15@67998
   556
      show ?thesis
lp15@67998
   557
        using \<open>m \<noteq> n\<close> by (subst det_upperdiagonal [OF *]) (auto simp: matrix_def axis_def cong: if_cong)
lp15@67998
   558
    next
lp15@67998
   559
      assume "n < m"
lp15@67998
   560
      have *: "matrix ?h $ i $ j = (0::real)" if "j > i" for i j :: 'n
lp15@67998
   561
      proof -
lp15@67998
   562
        have "axis j 1 = (\<chi> n. if n = j then 1 else (0::real))"
lp15@67998
   563
          using axis_def by blast
lp15@67998
   564
        then have "(\<chi> p q. if p = m then axis q 1 $ m + axis q 1 $ n else axis q 1 $ p) $ i $ j = (0::real)"
lp15@67998
   565
          using \<open>j > i\<close> axis_def \<open>m > n\<close> by auto
lp15@67998
   566
        with \<open>m > n\<close> show ?thesis
lp15@67998
   567
          by (auto simp: matrix_def axis_def cong: if_cong)
lp15@67998
   568
      qed
lp15@67998
   569
      show ?thesis
lp15@67998
   570
        using \<open>m \<noteq> n\<close>
lp15@67998
   571
        by (subst det_lowerdiagonal [OF *]) (auto simp: matrix_def axis_def cong: if_cong)
lp15@67998
   572
    qed
lp15@67998
   573
    have meq: "measure lebesgue (?h ` (cbox a b)) = measure lebesgue (cbox a b)" for a b
lp15@67998
   574
    proof (cases "cbox a b = {}")
lp15@67998
   575
      case True then show ?thesis by simp
lp15@67998
   576
    next
lp15@67998
   577
      case False
lp15@67998
   578
      then have ne: "(+) (\<chi> i. if i = n then - a $ n else 0) ` cbox a b \<noteq> {}"
lp15@67998
   579
        by auto
lp15@67998
   580
      let ?v = "\<chi> i. if i = n then - a $ n else 0"
lp15@67998
   581
      have "?h ` cbox a b
lp15@67998
   582
            = (+) (\<chi> i. if i = m \<or> i = n then a $ n else 0) ` ?h ` (+) ?v ` (cbox a b)"
lp15@67998
   583
        using \<open>m \<noteq> n\<close> unfolding image_comp o_def by (force simp: vec_eq_iff)
lp15@67998
   584
      then have "measure lebesgue (?h ` (cbox a b))
lp15@67998
   585
               = measure lebesgue ((\<lambda>v. \<chi> i. if i = m then v $ m + v $ n else v $ i) `
lp15@67998
   586
                                   (+) ?v ` cbox a b)"
lp15@67998
   587
        by (rule ssubst) (rule measure_translation)
lp15@67998
   588
      also have "\<dots> = measure lebesgue ((\<lambda>v. \<chi> i. if i = m then v $ m + v $ n else v $ i) ` cbox (?v +a) (?v + b))"
lp15@67998
   589
        by (metis (no_types, lifting) cbox_translation)
lp15@67998
   590
      also have "\<dots> = measure lebesgue ((+) (\<chi> i. if i = n then - a $ n else 0) ` cbox a b)"
lp15@67998
   591
        apply (subst measure_shear_interval)
lp15@67998
   592
        using \<open>m \<noteq> n\<close> ne apply auto
lp15@67998
   593
        apply (simp add: cbox_translation)
lp15@67998
   594
        by (metis cbox_borel cbox_translation measure_completion sets_lborel)
lp15@67998
   595
      also have "\<dots> = measure lebesgue (cbox a b)"
lp15@67998
   596
        by (rule measure_translation)
lp15@67998
   597
        finally show ?thesis .
lp15@67998
   598
      qed
lp15@67998
   599
    show "?h ` S \<in> lmeasurable \<and> ?Q ?h S"
lp15@67998
   600
      using measure_linear_sufficient [OF lin \<open>S \<in> lmeasurable\<close>] meq 1 by force
lp15@67998
   601
  qed
lp15@67998
   602
  with assms show "(f ` S) \<in> lmeasurable" "?Q f S"
lp15@67998
   603
    by metis+
lp15@67998
   604
qed
lp15@67998
   605
lp15@67998
   606
lp15@67998
   607
lemma
lp15@67998
   608
 fixes f :: "real^'n::{finite,wellorder} \<Rightarrow> real^'n::_"
lp15@67998
   609
  assumes f: "orthogonal_transformation f" and S: "S \<in> lmeasurable"
lp15@67998
   610
  shows measurable_orthogonal_image: "f ` S \<in> lmeasurable"
lp15@67998
   611
    and measure_orthogonal_image: "measure lebesgue (f ` S) = measure lebesgue S"
lp15@67998
   612
proof -
lp15@67998
   613
  have "linear f"
lp15@67998
   614
    by (simp add: f orthogonal_transformation_linear)
lp15@67998
   615
  then show "f ` S \<in> lmeasurable"
lp15@67998
   616
    by (metis S measurable_linear_image)
lp15@67998
   617
  show "measure lebesgue (f ` S) = measure lebesgue S"
lp15@67998
   618
    by (simp add: measure_linear_image \<open>linear f\<close> S f)
lp15@67998
   619
qed
lp15@67998
   620
lp15@67998
   621
subsection\<open>@{text F_sigma} and @{text G_delta} sets.\<close>
lp15@67998
   622
lp15@67998
   623
(*https://en.wikipedia.org/wiki/F\<sigma>_set*)
lp15@67998
   624
inductive fsigma :: "'a::topological_space set \<Rightarrow> bool" where
lp15@67998
   625
  "(\<And>n::nat. closed (F n)) \<Longrightarrow> fsigma (UNION UNIV F)"
lp15@67998
   626
lp15@67998
   627
inductive gdelta :: "'a::topological_space set \<Rightarrow> bool" where
lp15@67998
   628
  "(\<And>n::nat. open (F n)) \<Longrightarrow> gdelta (INTER UNIV F)"
lp15@67998
   629
lp15@67998
   630
lemma fsigma_Union_compact:
lp15@67998
   631
  fixes S :: "'a::{real_normed_vector,heine_borel} set"
lp15@67998
   632
  shows "fsigma S \<longleftrightarrow> (\<exists>F::nat \<Rightarrow> 'a set. range F \<subseteq> Collect compact \<and> S = UNION UNIV F)"
lp15@67998
   633
proof safe
lp15@67998
   634
  assume "fsigma S"
lp15@67998
   635
  then obtain F :: "nat \<Rightarrow> 'a set" where F: "range F \<subseteq> Collect closed" "S = UNION UNIV F"
lp15@67998
   636
    by (meson fsigma.cases image_subsetI mem_Collect_eq)
lp15@67998
   637
  then have "\<exists>D::nat \<Rightarrow> 'a set. range D \<subseteq> Collect compact \<and> UNION UNIV D = F i" for i
lp15@67998
   638
    using closed_Union_compact_subsets [of "F i"]
lp15@67998
   639
    by (metis image_subsetI mem_Collect_eq range_subsetD)
lp15@67998
   640
  then obtain D :: "nat \<Rightarrow> nat \<Rightarrow> 'a set"
lp15@67998
   641
    where D: "\<And>i. range (D i) \<subseteq> Collect compact \<and> UNION UNIV (D i) = F i"
lp15@67998
   642
    by metis
lp15@67998
   643
  let ?DD = "\<lambda>n. (\<lambda>(i,j). D i j) (prod_decode n)"
lp15@67998
   644
  show "\<exists>F::nat \<Rightarrow> 'a set. range F \<subseteq> Collect compact \<and> S = UNION UNIV F"
lp15@67998
   645
  proof (intro exI conjI)
lp15@67998
   646
    show "range ?DD \<subseteq> Collect compact"
lp15@67998
   647
      using D by clarsimp (metis mem_Collect_eq rangeI split_conv subsetCE surj_pair)
lp15@67998
   648
    show "S = UNION UNIV ?DD"
lp15@67998
   649
    proof
lp15@67998
   650
      show "S \<subseteq> UNION UNIV ?DD"
lp15@67998
   651
        using D F
lp15@67998
   652
        by clarsimp (metis UN_iff old.prod.case prod_decode_inverse prod_encode_eq)
lp15@67998
   653
      show "UNION UNIV ?DD \<subseteq> S"
lp15@67998
   654
        using D F  by fastforce
lp15@67998
   655
    qed
lp15@67998
   656
  qed
lp15@67998
   657
next
lp15@67998
   658
  fix F :: "nat \<Rightarrow> 'a set"
lp15@67998
   659
  assume "range F \<subseteq> Collect compact" and "S = UNION UNIV F"
lp15@67998
   660
  then show "fsigma (UNION UNIV F)"
lp15@67998
   661
    by (simp add: compact_imp_closed fsigma.intros image_subset_iff)
lp15@67998
   662
qed
lp15@67998
   663
lp15@67998
   664
lemma gdelta_imp_fsigma: "gdelta S \<Longrightarrow> fsigma (- S)"
lp15@67998
   665
proof (induction rule: gdelta.induct)
lp15@67998
   666
  case (1 F)
lp15@67998
   667
  have "- INTER UNIV F = (\<Union>i. -(F i))"
lp15@67998
   668
    by auto
lp15@67998
   669
  then show ?case
lp15@67998
   670
    by (simp add: fsigma.intros closed_Compl 1)
lp15@67998
   671
qed
lp15@67998
   672
lp15@67998
   673
lemma fsigma_imp_gdelta: "fsigma S \<Longrightarrow> gdelta (- S)"
lp15@67998
   674
proof (induction rule: fsigma.induct)
lp15@67998
   675
  case (1 F)
lp15@67998
   676
  have "- UNION UNIV F = (\<Inter>i. -(F i))"
lp15@67998
   677
    by auto
lp15@67998
   678
  then show ?case
lp15@67998
   679
    by (simp add: 1 gdelta.intros open_closed)
lp15@67998
   680
qed
lp15@67998
   681
lp15@67998
   682
lemma gdelta_complement: "gdelta(- S) \<longleftrightarrow> fsigma S"
lp15@67998
   683
  using fsigma_imp_gdelta gdelta_imp_fsigma by force
lp15@67998
   684
lp15@67998
   685
text\<open>A Lebesgue set is almost an @{text F_sigma} or @{text G_delta}.\<close>
lp15@67998
   686
lemma lebesgue_set_almost_fsigma:
lp15@67998
   687
  assumes "S \<in> sets lebesgue"
lp15@67998
   688
  obtains C T where "fsigma C" "negligible T" "C \<union> T = S" "disjnt C T"
lp15@67998
   689
proof -
lp15@67998
   690
  { fix n::nat
lp15@67998
   691
    have "\<exists>T. closed T \<and> T \<subseteq> S \<and> S - T \<in> lmeasurable \<and> measure lebesgue (S-T) < 1 / Suc n"
lp15@67998
   692
      using sets_lebesgue_inner_closed [OF assms]
lp15@67998
   693
      by (metis divide_pos_pos less_numeral_extra(1) of_nat_0_less_iff zero_less_Suc)
lp15@67998
   694
  }
lp15@67998
   695
  then obtain F where F: "\<And>n::nat. closed (F n) \<and> F n \<subseteq> S \<and> S - F n \<in> lmeasurable \<and> measure lebesgue (S - F n) < 1 / Suc n"
lp15@67998
   696
    by metis
lp15@67998
   697
  let ?C = "UNION UNIV F"
lp15@67998
   698
  show thesis
lp15@67998
   699
  proof
lp15@67998
   700
    show "fsigma ?C"
lp15@67998
   701
      using F by (simp add: fsigma.intros)
lp15@67998
   702
    show "negligible (S - ?C)"
lp15@67998
   703
    proof (clarsimp simp add: negligible_outer_le)
lp15@67998
   704
      fix e :: "real"
lp15@67998
   705
      assume "0 < e"
lp15@67998
   706
      then obtain n where n: "1 / Suc n < e"
lp15@67998
   707
        using nat_approx_posE by metis
lp15@67998
   708
      show "\<exists>T. S - (\<Union>x. F x) \<subseteq> T \<and> T \<in> lmeasurable \<and> measure lebesgue T \<le> e"
lp15@67998
   709
      proof (intro exI conjI)
lp15@67998
   710
        show "measure lebesgue (S - F n) \<le> e"
lp15@67998
   711
          by (meson F n less_trans not_le order.asym)
lp15@67998
   712
      qed (use F in auto)
lp15@67998
   713
    qed
lp15@67998
   714
    show "?C \<union> (S - ?C) = S"
lp15@67998
   715
      using F by blast
lp15@67998
   716
    show "disjnt ?C (S - ?C)"
lp15@67998
   717
      by (auto simp: disjnt_def)
lp15@67998
   718
  qed
lp15@67998
   719
qed
lp15@67998
   720
lp15@67998
   721
lemma lebesgue_set_almost_gdelta:
lp15@67998
   722
  assumes "S \<in> sets lebesgue"
lp15@67998
   723
  obtains C T where "gdelta C" "negligible T" "S \<union> T = C" "disjnt S T"
lp15@67998
   724
proof -
lp15@67998
   725
  have "-S \<in> sets lebesgue"
lp15@67998
   726
    using assms Compl_in_sets_lebesgue by blast
lp15@67998
   727
  then obtain C T where C: "fsigma C" "negligible T" "C \<union> T = -S" "disjnt C T"
lp15@67998
   728
    using lebesgue_set_almost_fsigma by metis
lp15@67998
   729
  show thesis
lp15@67998
   730
  proof
lp15@67998
   731
    show "gdelta (-C)"
lp15@67998
   732
      by (simp add: \<open>fsigma C\<close> fsigma_imp_gdelta)
lp15@67998
   733
    show "S \<union> T = -C" "disjnt S T"
lp15@67998
   734
      using C by (auto simp: disjnt_def)
lp15@67998
   735
  qed (use C in auto)
lp15@67998
   736
qed
lp15@67998
   737
lp15@67998
   738
lp15@67998
   739
proposition measure_semicontinuous_with_hausdist_explicit:
lp15@67998
   740
  assumes "bounded S" and neg: "negligible(frontier S)" and "e > 0"
lp15@67998
   741
  obtains d where "d > 0"
lp15@67998
   742
                  "\<And>T. \<lbrakk>T \<in> lmeasurable; \<And>y. y \<in> T \<Longrightarrow> \<exists>x. x \<in> S \<and> dist x y < d\<rbrakk>
lp15@67998
   743
                        \<Longrightarrow> measure lebesgue T < measure lebesgue S + e"
lp15@67998
   744
proof (cases "S = {}")
lp15@67998
   745
  case True
lp15@67998
   746
  with that \<open>e > 0\<close> show ?thesis by force
lp15@67998
   747
next
lp15@67998
   748
  case False
lp15@67998
   749
  then have frS: "frontier S \<noteq> {}"
lp15@67998
   750
    using \<open>bounded S\<close> frontier_eq_empty not_bounded_UNIV by blast
lp15@67998
   751
  have "S \<in> lmeasurable"
lp15@67998
   752
    by (simp add: \<open>bounded S\<close> measurable_Jordan neg)
lp15@67998
   753
  have null: "(frontier S) \<in> null_sets lebesgue"
lp15@67998
   754
    by (metis neg negligible_iff_null_sets)
lp15@67998
   755
  have "frontier S \<in> lmeasurable" and mS0: "measure lebesgue (frontier S) = 0"
lp15@67998
   756
    using neg negligible_imp_measurable negligible_iff_measure by blast+
lp15@67998
   757
  with \<open>e > 0\<close> lmeasurable_outer_open
lp15@67998
   758
  obtain U where "open U"
lp15@67998
   759
    and U: "frontier S \<subseteq> U" "U - frontier S \<in> lmeasurable" "measure lebesgue (U - frontier S) < e"
lp15@67998
   760
    by (metis fmeasurableD)
lp15@67998
   761
  with null have "U \<in> lmeasurable"
lp15@67998
   762
    by (metis borel_open measurable_Diff_null_set sets_completionI_sets sets_lborel)
lp15@67998
   763
  have "measure lebesgue (U - frontier S) = measure lebesgue U"
lp15@67998
   764
    using mS0 by (simp add: \<open>U \<in> lmeasurable\<close> fmeasurableD measure_Diff_null_set null)
lp15@67998
   765
  with U have mU: "measure lebesgue U < e"
lp15@67998
   766
    by simp
lp15@67998
   767
  show ?thesis
lp15@67998
   768
  proof
lp15@67998
   769
    have "U \<noteq> UNIV"
lp15@67998
   770
      using \<open>U \<in> lmeasurable\<close> by auto
lp15@67998
   771
    then have "- U \<noteq> {}"
lp15@67998
   772
      by blast
lp15@67998
   773
    with \<open>open U\<close> \<open>frontier S \<subseteq> U\<close> show "setdist (frontier S) (- U) > 0"
lp15@67998
   774
      by (auto simp: \<open>bounded S\<close> open_closed compact_frontier_bounded setdist_gt_0_compact_closed frS)
lp15@67998
   775
    fix T
lp15@67998
   776
    assume "T \<in> lmeasurable"
lp15@67998
   777
      and T: "\<And>t. t \<in> T \<Longrightarrow> \<exists>y. y \<in> S \<and> dist y t < setdist (frontier S) (- U)"
lp15@67998
   778
    then have "measure lebesgue T - measure lebesgue S \<le> measure lebesgue (T - S)"
lp15@67998
   779
      by (simp add: \<open>S \<in> lmeasurable\<close> measure_diff_le_measure_setdiff)
lp15@67998
   780
    also have "\<dots>  \<le> measure lebesgue U"
lp15@67998
   781
    proof -
lp15@67998
   782
      have "T - S \<subseteq> U"
lp15@67998
   783
      proof clarify
lp15@67998
   784
        fix x
lp15@67998
   785
        assume "x \<in> T" and "x \<notin> S"
lp15@67998
   786
        then obtain y where "y \<in> S" and y: "dist y x < setdist (frontier S) (- U)"
lp15@67998
   787
          using T by blast
lp15@67998
   788
        have "closed_segment x y \<inter> frontier S \<noteq> {}"
lp15@67998
   789
          using connected_Int_frontier \<open>x \<notin> S\<close> \<open>y \<in> S\<close> by blast
lp15@67998
   790
        then obtain z where z: "z \<in> closed_segment x y" "z \<in> frontier S"
lp15@67998
   791
          by auto
lp15@67998
   792
        with y have "dist z x < setdist(frontier S) (- U)"
lp15@67998
   793
          by (auto simp: dist_commute dest!: dist_in_closed_segment)
lp15@67998
   794
        with z have False if "x \<in> -U"
lp15@67998
   795
          using setdist_le_dist [OF \<open>z \<in> frontier S\<close> that] by auto
lp15@67998
   796
        then show "x \<in> U"
lp15@67998
   797
          by blast
lp15@67998
   798
      qed
lp15@67998
   799
      then show ?thesis
lp15@67998
   800
        by (simp add: \<open>S \<in> lmeasurable\<close> \<open>T \<in> lmeasurable\<close> \<open>U \<in> lmeasurable\<close> fmeasurableD measure_mono_fmeasurable sets.Diff)
lp15@67998
   801
    qed
lp15@67998
   802
    finally have "measure lebesgue T - measure lebesgue S \<le> measure lebesgue U" .
lp15@67998
   803
    with mU show "measure lebesgue T < measure lebesgue S + e"
lp15@67998
   804
      by linarith
lp15@67998
   805
  qed
lp15@67998
   806
qed
lp15@67998
   807
lp15@67998
   808
proposition lebesgue_regular_inner:
lp15@67998
   809
 assumes "S \<in> sets lebesgue"
lp15@67998
   810
 obtains K C where "negligible K" "\<And>n::nat. compact(C n)" "S = (\<Union>n. C n) \<union> K"
lp15@67998
   811
proof -
lp15@67998
   812
  have "\<exists>T. closed T \<and> T \<subseteq> S \<and> (S - T) \<in> lmeasurable \<and> measure lebesgue (S - T) < (1/2)^n" for n
lp15@67998
   813
    using sets_lebesgue_inner_closed assms
lp15@67998
   814
    by (metis sets_lebesgue_inner_closed zero_less_divide_1_iff zero_less_numeral zero_less_power)
lp15@67998
   815
  then obtain C where clo: "\<And>n. closed (C n)" and subS: "\<And>n. C n \<subseteq> S"
lp15@67998
   816
    and mea: "\<And>n. (S - C n) \<in> lmeasurable"
lp15@67998
   817
    and less: "\<And>n. measure lebesgue (S - C n) < (1/2)^n"
lp15@67998
   818
    by metis
lp15@67998
   819
  have "\<exists>F. (\<forall>n::nat. compact(F n)) \<and> (\<Union>n. F n) = C m" for m::nat
lp15@67998
   820
    by (metis clo closed_Union_compact_subsets)
lp15@67998
   821
  then obtain D :: "[nat,nat] \<Rightarrow> 'a set" where D: "\<And>m n. compact(D m n)" "\<And>m. (\<Union>n. D m n) = C m"
lp15@67998
   822
    by metis
lp15@67998
   823
  let ?C = "from_nat_into (\<Union>m. range (D m))"
lp15@67998
   824
  have "countable (\<Union>m. range (D m))"
lp15@67998
   825
    by blast
lp15@67998
   826
  have "range (from_nat_into (\<Union>m. range (D m))) = (\<Union>m. range (D m))"
lp15@67998
   827
    using range_from_nat_into by simp
lp15@67998
   828
  then have CD: "\<exists>m n. ?C k = D m n"  for k
lp15@67998
   829
    by (metis (mono_tags, lifting) UN_iff rangeE range_eqI)
lp15@67998
   830
  show thesis
lp15@67998
   831
  proof
lp15@67998
   832
    show "negligible (S - (\<Union>n. C n))"
lp15@67998
   833
    proof (clarsimp simp: negligible_outer_le)
lp15@67998
   834
      fix e :: "real"
lp15@67998
   835
      assume "e > 0"
lp15@67998
   836
      then obtain n where n: "(1/2)^n < e"
lp15@67998
   837
        using real_arch_pow_inv [of e "1/2"] by auto
lp15@67998
   838
      show "\<exists>T. S - (\<Union>n. C n) \<subseteq> T \<and> T \<in> lmeasurable \<and> measure lebesgue T \<le> e"
lp15@67998
   839
      proof (intro exI conjI)
lp15@67998
   840
        show "S - (\<Union>n. C n) \<subseteq> S - C n"
lp15@67998
   841
          by blast
lp15@67998
   842
        show "S - C n \<in> lmeasurable"
lp15@67998
   843
          by (simp add: mea)
lp15@67998
   844
        show "measure lebesgue (S - C n) \<le> e"
lp15@67998
   845
          using less [of n] n by simp
lp15@67998
   846
      qed
lp15@67998
   847
    qed
lp15@67998
   848
    show "compact (?C n)" for n
lp15@67998
   849
      using CD D by metis
lp15@67998
   850
    show "S = (\<Union>n. ?C n) \<union> (S - (\<Union>n. C n))" (is "_ = ?rhs")
lp15@67998
   851
    proof
lp15@67998
   852
      show "S \<subseteq> ?rhs"
lp15@67998
   853
        using D by fastforce
lp15@67998
   854
      show "?rhs \<subseteq> S"
lp15@67998
   855
        using subS D CD by auto (metis Sup_upper range_eqI subsetCE)
lp15@67998
   856
    qed
lp15@67998
   857
  qed
lp15@67998
   858
qed
lp15@67998
   859
lp15@67998
   860
lp15@67998
   861
lemma sets_lebesgue_continuous_image:
lp15@67998
   862
  assumes T: "T \<in> sets lebesgue" and contf: "continuous_on S f"
lp15@67998
   863
    and negim: "\<And>T. \<lbrakk>negligible T; T \<subseteq> S\<rbrakk> \<Longrightarrow> negligible(f ` T)" and "T \<subseteq> S"
lp15@67998
   864
 shows "f ` T \<in> sets lebesgue"
lp15@67998
   865
proof -
lp15@67998
   866
  obtain K C where "negligible K" and com: "\<And>n::nat. compact(C n)" and Teq: "T = (\<Union>n. C n) \<union> K"
lp15@67998
   867
    using lebesgue_regular_inner [OF T] by metis
lp15@67998
   868
  then have comf: "\<And>n::nat. compact(f ` C n)"
lp15@67998
   869
    by (metis Un_subset_iff Union_upper \<open>T \<subseteq> S\<close> compact_continuous_image contf continuous_on_subset rangeI)
lp15@67998
   870
  have "((\<Union>n. f ` C n) \<union> f ` K) \<in> sets lebesgue"
lp15@67998
   871
  proof (rule sets.Un)
lp15@67998
   872
    have "K \<subseteq> S"
lp15@67998
   873
      using Teq \<open>T \<subseteq> S\<close> by blast
lp15@67998
   874
    show "(\<Union>n. f ` C n) \<in> sets lebesgue"
lp15@67998
   875
    proof (rule sets.countable_Union)
lp15@67998
   876
      show "range (\<lambda>n. f ` C n) \<subseteq> sets lebesgue"
lp15@67998
   877
        using borel_compact comf by (auto simp: borel_compact)
lp15@67998
   878
    qed auto
lp15@67998
   879
    show "f ` K \<in> sets lebesgue"
lp15@67998
   880
      by (simp add: \<open>K \<subseteq> S\<close> \<open>negligible K\<close> negim negligible_imp_sets)
lp15@67998
   881
  qed
lp15@67998
   882
  then show ?thesis
lp15@67998
   883
    by (simp add: Teq image_Un image_Union)
lp15@67998
   884
qed
lp15@67998
   885
lp15@67998
   886
lemma differentiable_image_in_sets_lebesgue:
lp15@67998
   887
  fixes f :: "'m::euclidean_space \<Rightarrow> 'n::euclidean_space"
lp15@67998
   888
  assumes S: "S \<in> sets lebesgue" and dim: "DIM('m) \<le> DIM('n)" and f: "f differentiable_on S"
lp15@67998
   889
  shows "f`S \<in> sets lebesgue"
lp15@67998
   890
proof (rule sets_lebesgue_continuous_image [OF S])
lp15@67998
   891
  show "continuous_on S f"
lp15@67998
   892
    by (meson differentiable_imp_continuous_on f)
lp15@67998
   893
  show "\<And>T. \<lbrakk>negligible T; T \<subseteq> S\<rbrakk> \<Longrightarrow> negligible (f ` T)"
lp15@67998
   894
    using differentiable_on_subset f
lp15@67998
   895
    by (auto simp: intro!: negligible_differentiable_image_negligible [OF dim])
lp15@67998
   896
qed auto
lp15@67998
   897
lp15@67998
   898
lemma sets_lebesgue_on_continuous_image:
lp15@67998
   899
  assumes S: "S \<in> sets lebesgue" and X: "X \<in> sets (lebesgue_on S)" and contf: "continuous_on S f"
lp15@67998
   900
    and negim: "\<And>T. \<lbrakk>negligible T; T \<subseteq> S\<rbrakk> \<Longrightarrow> negligible(f ` T)"
lp15@67998
   901
  shows "f ` X \<in> sets (lebesgue_on (f ` S))"
lp15@67998
   902
proof -
lp15@67998
   903
  have "X \<subseteq> S"
lp15@67998
   904
    by (metis S X sets.Int_space_eq2 sets_restrict_space_iff)
lp15@67998
   905
  moreover have "f ` S \<in> sets lebesgue"
lp15@67998
   906
    using S contf negim sets_lebesgue_continuous_image by blast
lp15@67998
   907
  moreover have "f ` X \<in> sets lebesgue"
lp15@67998
   908
    by (metis S X contf negim sets_lebesgue_continuous_image sets_restrict_space_iff space_restrict_space space_restrict_space2)
lp15@67998
   909
  ultimately show ?thesis
lp15@67998
   910
    by (auto simp: sets_restrict_space_iff)
lp15@67998
   911
qed
lp15@67998
   912
lp15@67998
   913
lemma differentiable_image_in_sets_lebesgue_on:
lp15@67998
   914
  fixes f :: "'m::euclidean_space \<Rightarrow> 'n::euclidean_space"
lp15@67998
   915
  assumes S: "S \<in> sets lebesgue" and X: "X \<in> sets (lebesgue_on S)" and dim: "DIM('m) \<le> DIM('n)"
lp15@67998
   916
       and f: "f differentiable_on S"
lp15@67998
   917
     shows "f ` X \<in> sets (lebesgue_on (f`S))"
lp15@67998
   918
proof (rule sets_lebesgue_on_continuous_image [OF S X])
lp15@67998
   919
  show "continuous_on S f"
lp15@67998
   920
    by (meson differentiable_imp_continuous_on f)
lp15@67998
   921
  show "\<And>T. \<lbrakk>negligible T; T \<subseteq> S\<rbrakk> \<Longrightarrow> negligible (f ` T)"
lp15@67998
   922
    using differentiable_on_subset f
lp15@67998
   923
    by (auto simp: intro!: negligible_differentiable_image_negligible [OF dim])
lp15@67998
   924
qed
lp15@67998
   925
lp15@67998
   926
lp15@67998
   927
proposition
lp15@67998
   928
 fixes f :: "real^'n::{finite,wellorder} \<Rightarrow> real^'n::_"
lp15@67998
   929
  assumes S: "S \<in> lmeasurable"
lp15@67998
   930
  and deriv: "\<And>x. x \<in> S \<Longrightarrow> (f has_derivative f' x) (at x within S)"
lp15@67998
   931
  and int: "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) integrable_on S"
lp15@67998
   932
  and bounded: "\<And>x. x \<in> S \<Longrightarrow> \<bar>det (matrix (f' x))\<bar> \<le> B"
lp15@67998
   933
  shows measurable_bounded_differentiable_image:
lp15@67998
   934
       "f ` S \<in> lmeasurable"
lp15@67998
   935
    and measure_bounded_differentiable_image:
lp15@67998
   936
       "measure lebesgue (f ` S) \<le> B * measure lebesgue S" (is "?M")
lp15@67998
   937
proof -
lp15@67998
   938
  have "f ` S \<in> lmeasurable \<and> measure lebesgue (f ` S) \<le> B * measure lebesgue S"
lp15@67998
   939
  proof (cases "B < 0")
lp15@67998
   940
    case True
lp15@67998
   941
    then have "S = {}"
lp15@67998
   942
      by (meson abs_ge_zero bounded empty_iff equalityI less_le_trans linorder_not_less subsetI)
lp15@67998
   943
    then show ?thesis
lp15@67998
   944
      by auto
lp15@67998
   945
  next
lp15@67998
   946
    case False
lp15@67998
   947
    then have "B \<ge> 0"
lp15@67998
   948
      by arith
lp15@67998
   949
    let ?\<mu> = "measure lebesgue"
lp15@67998
   950
    have f_diff: "f differentiable_on S"
lp15@67998
   951
      using deriv by (auto simp: differentiable_on_def differentiable_def)
lp15@67998
   952
    have eps: "f ` S \<in> lmeasurable" "?\<mu> (f ` S) \<le> (B+e) * ?\<mu> S" (is "?ME")
lp15@67998
   953
              if "e > 0" for e
lp15@67998
   954
    proof -
lp15@67998
   955
      have eps_d: "f ` S \<in> lmeasurable"  "?\<mu> (f ` S) \<le> (B+e) * (?\<mu> S + d)" (is "?MD")
lp15@67998
   956
                  if "d > 0" for d
lp15@67998
   957
      proof -
lp15@67998
   958
        obtain T where "open T" "S \<subseteq> T" and TS: "(T-S) \<in> lmeasurable" and "?\<mu> (T-S) < d"
lp15@67998
   959
          using S \<open>d > 0\<close> lmeasurable_outer_open by blast
lp15@67998
   960
        with S have "T \<in> lmeasurable" and Tless: "?\<mu> T < ?\<mu> S + d"
lp15@67998
   961
          by (auto simp: measurable_measure_Diff dest!: fmeasurable_Diff_D)
lp15@67998
   962
        have "\<exists>r. 0 < r \<and> r < d \<and> ball x r \<subseteq> T \<and> f ` (S \<inter> ball x r) \<in> lmeasurable \<and>
lp15@67998
   963
                  ?\<mu> (f ` (S \<inter> ball x r)) \<le> (B + e) * ?\<mu> (ball x r)"
lp15@67998
   964
          if "x \<in> S" "d > 0" for x d
lp15@67998
   965
        proof -
lp15@67998
   966
          have lin: "linear (f' x)"
lp15@67998
   967
            and lim0: "((\<lambda>y. (f y - (f x + f' x (y - x))) /\<^sub>R norm(y - x)) \<longlongrightarrow> 0) (at x within S)"
lp15@67998
   968
            using deriv \<open>x \<in> S\<close> by (auto simp: has_derivative_within bounded_linear.linear field_simps)
lp15@67998
   969
          have bo: "bounded (f' x ` ball 0 1)"
lp15@67998
   970
            by (simp add: bounded_linear_image linear_linear lin)
lp15@67998
   971
          have neg: "negligible (frontier (f' x ` ball 0 1))"
lp15@67998
   972
            using deriv has_derivative_linear \<open>x \<in> S\<close>
lp15@67998
   973
            by (auto intro!: negligible_convex_frontier [OF convex_linear_image])
lp15@67998
   974
          have 0: "0 < e * unit_ball_vol (real CARD('n))"
lp15@67998
   975
            using  \<open>e > 0\<close> by simp
lp15@67998
   976
          obtain k where "k > 0" and k:
lp15@67998
   977
                  "\<And>U. \<lbrakk>U \<in> lmeasurable; \<And>y. y \<in> U \<Longrightarrow> \<exists>z. z \<in> f' x ` ball 0 1 \<and> dist z y < k\<rbrakk>
lp15@67998
   978
                        \<Longrightarrow> ?\<mu> U < ?\<mu> (f' x ` ball 0 1) + e * unit_ball_vol (CARD('n))"
lp15@67998
   979
            using measure_semicontinuous_with_hausdist_explicit [OF bo neg 0] by blast
lp15@67998
   980
          obtain l where "l > 0" and l: "ball x l \<subseteq> T"
lp15@67998
   981
            using \<open>x \<in> S\<close> \<open>open T\<close> \<open>S \<subseteq> T\<close> openE by blast
lp15@67998
   982
          obtain \<zeta> where "0 < \<zeta>"
lp15@67998
   983
            and \<zeta>: "\<And>y. \<lbrakk>y \<in> S; y \<noteq> x; dist y x < \<zeta>\<rbrakk>
lp15@67998
   984
                        \<Longrightarrow> norm (f y - (f x + f' x (y - x))) / norm (y - x) < k"
lp15@67998
   985
            using lim0 \<open>k > 0\<close> by (force simp: Lim_within field_simps)
lp15@67998
   986
          define r where "r \<equiv> min (min l (\<zeta>/2)) (min 1 (d/2))"
lp15@67998
   987
          show ?thesis
lp15@67998
   988
          proof (intro exI conjI)
lp15@67998
   989
            show "r > 0" "r < d"
lp15@67998
   990
              using \<open>l > 0\<close> \<open>\<zeta> > 0\<close> \<open>d > 0\<close> by (auto simp: r_def)
lp15@67998
   991
            have "r \<le> l"
lp15@67998
   992
              by (auto simp: r_def)
lp15@67998
   993
            with l show "ball x r \<subseteq> T"
lp15@67998
   994
              by auto
lp15@67998
   995
            have ex_lessK: "\<exists>x' \<in> ball 0 1. dist (f' x x') ((f y - f x) /\<^sub>R r) < k"
lp15@67998
   996
              if "y \<in> S" and "dist x y < r" for y
lp15@67998
   997
            proof (cases "y = x")
lp15@67998
   998
              case True
lp15@67998
   999
              with lin linear_0 \<open>k > 0\<close> that show ?thesis
lp15@67998
  1000
                by (rule_tac x=0 in bexI) (auto simp: linear_0)
lp15@67998
  1001
            next
lp15@67998
  1002
              case False
lp15@67998
  1003
              then show ?thesis
lp15@67998
  1004
              proof (rule_tac x="(y - x) /\<^sub>R r" in bexI)
lp15@67998
  1005
                have "f' x ((y - x) /\<^sub>R r) = f' x (y - x) /\<^sub>R r"
lp15@67998
  1006
                  by (simp add: lin linear_cmul)
lp15@67998
  1007
                then have "dist (f' x ((y - x) /\<^sub>R r)) ((f y - f x) /\<^sub>R r) = norm (f' x (y - x) /\<^sub>R r - (f y - f x) /\<^sub>R r)"
lp15@67998
  1008
                  by (simp add: dist_norm)
lp15@67998
  1009
                also have "\<dots> = norm (f' x (y - x) - (f y - f x)) / r"
lp15@67998
  1010
                  using \<open>r > 0\<close> by (simp add: real_vector.scale_right_diff_distrib [symmetric] divide_simps)
lp15@67998
  1011
                also have "\<dots> \<le> norm (f y - (f x + f' x (y - x))) / norm (y - x)"
lp15@67998
  1012
                  using that \<open>r > 0\<close> False by (simp add: algebra_simps divide_simps dist_norm norm_minus_commute mult_right_mono)
lp15@67998
  1013
                also have "\<dots> < k"
lp15@67998
  1014
                  using that \<open>0 < \<zeta>\<close> by (simp add: dist_commute r_def  \<zeta> [OF \<open>y \<in> S\<close> False])
lp15@67998
  1015
                finally show "dist (f' x ((y - x) /\<^sub>R r)) ((f y - f x) /\<^sub>R r) < k" .
lp15@67998
  1016
                show "(y - x) /\<^sub>R r \<in> ball 0 1"
lp15@67998
  1017
                  using that \<open>r > 0\<close> by (simp add: dist_norm divide_simps norm_minus_commute)
lp15@67998
  1018
              qed
lp15@67998
  1019
            qed
lp15@67998
  1020
            let ?rfs = "(\<lambda>x. x /\<^sub>R r) ` (+) (- f x) ` f ` (S \<inter> ball x r)"
lp15@67998
  1021
            have rfs_mble: "?rfs \<in> lmeasurable"
lp15@67998
  1022
            proof (rule bounded_set_imp_lmeasurable)
lp15@67998
  1023
              have "f differentiable_on S \<inter> ball x r"
lp15@67998
  1024
                using f_diff by (auto simp: fmeasurableD differentiable_on_subset)
lp15@67998
  1025
              with S show "?rfs \<in> sets lebesgue"
lp15@67998
  1026
                by (auto simp: sets.Int intro!: lebesgue_sets_translation differentiable_image_in_sets_lebesgue)
lp15@67998
  1027
              let ?B = "(\<lambda>(x, y). x + y) ` (f' x ` ball 0 1 \<times> ball 0 k)"
lp15@67998
  1028
              have "bounded ?B"
lp15@67998
  1029
                by (simp add: bounded_plus [OF bo])
lp15@67998
  1030
              moreover have "?rfs \<subseteq> ?B"
lp15@67998
  1031
                apply (auto simp: dist_norm image_iff dest!: ex_lessK)
lp15@67998
  1032
                by (metis (no_types, hide_lams) add.commute diff_add_cancel dist_0_norm dist_commute dist_norm mem_ball)
lp15@67998
  1033
              ultimately show "bounded (?rfs)"
lp15@67998
  1034
                by (rule bounded_subset)
lp15@67998
  1035
            qed
lp15@67998
  1036
            then have "(\<lambda>x. r *\<^sub>R x) ` ?rfs \<in> lmeasurable"
lp15@67998
  1037
              by (simp add: measurable_linear_image)
lp15@67998
  1038
            with \<open>r > 0\<close> have "(+) (- f x) ` f ` (S \<inter> ball x r) \<in> lmeasurable"
lp15@67998
  1039
              by (simp add: image_comp o_def)
lp15@67998
  1040
            then have "(+) (f x) ` (+) (- f x) ` f ` (S \<inter> ball x r) \<in> lmeasurable"
lp15@67998
  1041
              using  measurable_translation by blast
lp15@67998
  1042
            then show fsb: "f ` (S \<inter> ball x r) \<in> lmeasurable"
lp15@67998
  1043
              by (simp add: image_comp o_def)
lp15@67998
  1044
            have "?\<mu> (f ` (S \<inter> ball x r)) = ?\<mu> (?rfs) * r ^ CARD('n)"
lp15@67998
  1045
              using \<open>r > 0\<close> by (simp add: measure_translation measure_linear_image measurable_translation fsb field_simps)
lp15@67998
  1046
            also have "\<dots> \<le> (\<bar>det (matrix (f' x))\<bar> * unit_ball_vol (CARD('n)) + e * unit_ball_vol (CARD('n))) * r ^ CARD('n)"
lp15@67998
  1047
            proof -
lp15@67998
  1048
              have "?\<mu> (?rfs) < ?\<mu> (f' x ` ball 0 1) + e * unit_ball_vol (CARD('n))"
lp15@67998
  1049
                using rfs_mble by (force intro: k dest!: ex_lessK)
lp15@67998
  1050
              then have "?\<mu> (?rfs) < \<bar>det (matrix (f' x))\<bar> * unit_ball_vol (CARD('n)) + e * unit_ball_vol (CARD('n))"
lp15@67998
  1051
                by (simp add: lin measure_linear_image [of "f' x"] content_ball)
lp15@67998
  1052
              with \<open>r > 0\<close> show ?thesis
lp15@67998
  1053
                by auto
lp15@67998
  1054
            qed
lp15@67998
  1055
            also have "\<dots> \<le> (B + e) * ?\<mu> (ball x r)"
lp15@67998
  1056
              using bounded [OF \<open>x \<in> S\<close>] \<open>r > 0\<close> by (simp add: content_ball algebra_simps)
lp15@67998
  1057
            finally show "?\<mu> (f ` (S \<inter> ball x r)) \<le> (B + e) * ?\<mu> (ball x r)" .
lp15@67998
  1058
          qed
lp15@67998
  1059
        qed
lp15@67998
  1060
        then obtain r where
lp15@67998
  1061
          r0d: "\<And>x d. \<lbrakk>x \<in> S; d > 0\<rbrakk> \<Longrightarrow> 0 < r x d \<and> r x d < d"
lp15@67998
  1062
          and rT: "\<And>x d. \<lbrakk>x \<in> S; d > 0\<rbrakk> \<Longrightarrow> ball x (r x d) \<subseteq> T"
lp15@67998
  1063
          and r: "\<And>x d. \<lbrakk>x \<in> S; d > 0\<rbrakk> \<Longrightarrow>
lp15@67998
  1064
                  (f ` (S \<inter> ball x (r x d))) \<in> lmeasurable \<and>
lp15@67998
  1065
                  ?\<mu> (f ` (S \<inter> ball x (r x d))) \<le> (B + e) * ?\<mu> (ball x (r x d))"
lp15@67998
  1066
          by metis
lp15@67998
  1067
        obtain C where "countable C" and Csub: "C \<subseteq> {(x,r x t) |x t. x \<in> S \<and> 0 < t}"
lp15@67998
  1068
          and pwC: "pairwise (\<lambda>i j. disjnt (ball (fst i) (snd i)) (ball (fst j) (snd j))) C"
lp15@67998
  1069
          and negC: "negligible(S - (\<Union>i \<in> C. ball (fst i) (snd i)))"
lp15@67998
  1070
          apply (rule Vitali_covering_theorem_balls [of S "{(x,r x t) |x t. x \<in> S \<and> 0 < t}" fst snd])
lp15@67998
  1071
           apply auto
lp15@67998
  1072
          by (metis dist_eq_0_iff r0d)
lp15@67998
  1073
        let ?UB = "(\<Union>(x,s) \<in> C. ball x s)"
lp15@67998
  1074
        have eq: "f ` (S \<inter> ?UB) = (\<Union>(x,s) \<in> C. f ` (S \<inter> ball x s))"
lp15@67998
  1075
          by auto
lp15@67998
  1076
        have mle: "?\<mu> (\<Union>(x,s) \<in> K. f ` (S \<inter> ball x s)) \<le> (B + e) * (?\<mu> S + d)"  (is "?l \<le> ?r")
lp15@67998
  1077
          if "K \<subseteq> C" and "finite K" for K
lp15@67998
  1078
        proof -
lp15@67998
  1079
          have gt0: "b > 0" if "(a, b) \<in> K" for a b
lp15@67998
  1080
            using Csub that \<open>K \<subseteq> C\<close> r0d by auto
lp15@67998
  1081
          have inj: "inj_on (\<lambda>(x, y). ball x y) K"
lp15@67998
  1082
            by (force simp: inj_on_def ball_eq_ball_iff dest: gt0)
lp15@67998
  1083
          have disjnt: "disjoint ((\<lambda>(x, y). ball x y) ` K)"
lp15@67998
  1084
            using pwC that
lp15@67998
  1085
            apply (clarsimp simp: pairwise_def case_prod_unfold ball_eq_ball_iff)
lp15@67998
  1086
            by (metis subsetD fst_conv snd_conv)
lp15@67998
  1087
          have "?l \<le> (\<Sum>i\<in>K. ?\<mu> (case i of (x, s) \<Rightarrow> f ` (S \<inter> ball x s)))"
lp15@67998
  1088
          proof (rule measure_UNION_le [OF \<open>finite K\<close>], clarify)
lp15@67998
  1089
            fix x r
lp15@67998
  1090
            assume "(x,r) \<in> K"
lp15@67998
  1091
            then have "x \<in> S"
lp15@67998
  1092
              using Csub \<open>K \<subseteq> C\<close> by auto
lp15@67998
  1093
            show "f ` (S \<inter> ball x r) \<in> sets lebesgue"
lp15@67998
  1094
              by (meson Int_lower1 S differentiable_on_subset f_diff fmeasurableD lmeasurable_ball order_refl sets.Int differentiable_image_in_sets_lebesgue)
lp15@67998
  1095
          qed
lp15@67998
  1096
          also have "\<dots> \<le> (\<Sum>(x,s) \<in> K. (B + e) * ?\<mu> (ball x s))"
lp15@67998
  1097
            apply (rule sum_mono)
lp15@67998
  1098
            using Csub r \<open>K \<subseteq> C\<close> by auto
lp15@67998
  1099
          also have "\<dots> = (B + e) * (\<Sum>(x,s) \<in> K. ?\<mu> (ball x s))"
lp15@67998
  1100
            by (simp add: prod.case_distrib sum_distrib_left)
lp15@67998
  1101
          also have "\<dots> = (B + e) * sum ?\<mu> ((\<lambda>(x, y). ball x y) ` K)"
lp15@67998
  1102
            using \<open>B \<ge> 0\<close> \<open>e > 0\<close> by (simp add: inj sum.reindex prod.case_distrib)
lp15@67998
  1103
          also have "\<dots> = (B + e) * ?\<mu> (\<Union>(x,s) \<in> K. ball x s)"
lp15@67998
  1104
            using \<open>B \<ge> 0\<close> \<open>e > 0\<close> that
lp15@67998
  1105
            by (subst measure_Union') (auto simp: disjnt measure_Union')
lp15@67998
  1106
          also have "\<dots> \<le> (B + e) * ?\<mu> T"
lp15@67998
  1107
            using \<open>B \<ge> 0\<close> \<open>e > 0\<close> that apply simp
lp15@67998
  1108
            apply (rule measure_mono_fmeasurable [OF _ _ \<open>T \<in> lmeasurable\<close>])
lp15@67998
  1109
            using Csub rT by force+
lp15@67998
  1110
          also have "\<dots> \<le> (B + e) * (?\<mu> S + d)"
lp15@67998
  1111
            using \<open>B \<ge> 0\<close> \<open>e > 0\<close> Tless by simp
lp15@67998
  1112
          finally show ?thesis .
lp15@67998
  1113
        qed
lp15@67998
  1114
        have fSUB_mble: "(f ` (S \<inter> ?UB)) \<in> lmeasurable"
lp15@67998
  1115
          unfolding eq using Csub r False \<open>e > 0\<close> that
lp15@67998
  1116
          by (auto simp: intro!: fmeasurable_UN_bound [OF \<open>countable C\<close> _ mle])
lp15@67998
  1117
        have fSUB_meas: "?\<mu> (f ` (S \<inter> ?UB)) \<le> (B + e) * (?\<mu> S + d)"  (is "?MUB")
lp15@67998
  1118
          unfolding eq using Csub r False \<open>e > 0\<close> that
lp15@67998
  1119
          by (auto simp: intro!: measure_UN_bound [OF \<open>countable C\<close> _ mle])
lp15@67998
  1120
        have neg: "negligible ((f ` (S \<inter> ?UB) - f ` S) \<union> (f ` S - f ` (S \<inter> ?UB)))"
lp15@67998
  1121
        proof (rule negligible_subset [OF negligible_differentiable_image_negligible [OF order_refl negC, where f=f]])
lp15@67998
  1122
          show "f differentiable_on S - (\<Union>i\<in>C. ball (fst i) (snd i))"
lp15@67998
  1123
            by (meson DiffE differentiable_on_subset subsetI f_diff)
lp15@67998
  1124
        qed force
lp15@67998
  1125
        show "f ` S \<in> lmeasurable"
lp15@67998
  1126
          by (rule lmeasurable_negligible_symdiff [OF fSUB_mble neg])
lp15@67998
  1127
        show ?MD
lp15@67998
  1128
          using fSUB_meas measure_negligible_symdiff [OF fSUB_mble neg] by simp
lp15@67998
  1129
      qed
lp15@67998
  1130
      show "f ` S \<in> lmeasurable"
lp15@67998
  1131
        using eps_d [of 1] by simp
lp15@67998
  1132
      show ?ME
lp15@67998
  1133
      proof (rule field_le_epsilon)
lp15@67998
  1134
        fix \<delta> :: real
lp15@67998
  1135
        assume "0 < \<delta>"
lp15@67998
  1136
        then show "?\<mu> (f ` S) \<le> (B + e) * ?\<mu> S + \<delta>"
lp15@67998
  1137
          using eps_d [of "\<delta> / (B+e)"] \<open>e > 0\<close> \<open>B \<ge> 0\<close> by (auto simp: divide_simps mult_ac)
lp15@67998
  1138
      qed
lp15@67998
  1139
    qed
lp15@67998
  1140
    show ?thesis
lp15@67998
  1141
    proof (cases "?\<mu> S = 0")
lp15@67998
  1142
      case True
lp15@67998
  1143
      with eps have "?\<mu> (f ` S) = 0"
lp15@67998
  1144
        by (metis mult_zero_right not_le zero_less_measure_iff)
lp15@67998
  1145
      then show ?thesis
lp15@67998
  1146
        using eps [of 1] by (simp add: True)
lp15@67998
  1147
    next
lp15@67998
  1148
      case False
lp15@67998
  1149
      have "?\<mu> (f ` S) \<le> B * ?\<mu> S"
lp15@67998
  1150
      proof (rule field_le_epsilon)
lp15@67998
  1151
        fix e :: real
lp15@67998
  1152
        assume "e > 0"
lp15@67998
  1153
        then show "?\<mu> (f ` S) \<le> B * ?\<mu> S + e"
lp15@67998
  1154
          using eps [of "e / ?\<mu> S"] False by (auto simp: algebra_simps zero_less_measure_iff)
lp15@67998
  1155
      qed
lp15@67998
  1156
      with eps [of 1] show ?thesis by auto
lp15@67998
  1157
    qed
lp15@67998
  1158
  qed
lp15@67998
  1159
  then show "f ` S \<in> lmeasurable" ?M by blast+
lp15@67998
  1160
qed
lp15@67998
  1161
lp15@67998
  1162
lemma
lp15@67998
  1163
 fixes f :: "real^'n::{finite,wellorder} \<Rightarrow> real^'n::_"
lp15@67998
  1164
  assumes S: "S \<in> lmeasurable"
lp15@67998
  1165
    and deriv: "\<And>x. x \<in> S \<Longrightarrow> (f has_derivative f' x) (at x within S)"
lp15@67998
  1166
    and int: "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) integrable_on S"
lp15@67998
  1167
  shows m_diff_image_weak: "f ` S \<in> lmeasurable \<and> measure lebesgue (f ` S) \<le> integral S (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)"
lp15@67998
  1168
proof -
lp15@67998
  1169
  let ?\<mu> = "measure lebesgue"
lp15@67998
  1170
  have aint_S: "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) absolutely_integrable_on S"
lp15@67998
  1171
    using int unfolding absolutely_integrable_on_def by auto
lp15@67998
  1172
  define m where "m \<equiv> integral S (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)"
lp15@67998
  1173
  have *: "f ` S \<in> lmeasurable" "?\<mu> (f ` S) \<le> m + e * ?\<mu> S"
lp15@67998
  1174
    if "e > 0" for e
lp15@67998
  1175
  proof -
lp15@67998
  1176
    define T where "T \<equiv> \<lambda>n. {x \<in> S. n * e \<le> \<bar>det (matrix (f' x))\<bar> \<and>
lp15@67998
  1177
                                     \<bar>det (matrix (f' x))\<bar> < (Suc n) * e}"
lp15@67998
  1178
    have meas_t: "T n \<in> lmeasurable" for n
lp15@67998
  1179
    proof -
lp15@67998
  1180
      have *: "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) \<in> borel_measurable (lebesgue_on S)"
lp15@67998
  1181
        using aint_S by (simp add: S borel_measurable_restrict_space_iff fmeasurableD set_integrable_def)
lp15@67998
  1182
      have [intro]: "x \<in> sets (lebesgue_on S) \<Longrightarrow> x \<in> sets lebesgue" for x
lp15@67998
  1183
        using S sets_restrict_space_subset by blast
lp15@67998
  1184
      have "{x \<in> S. real n * e \<le> \<bar>det (matrix (f' x))\<bar>} \<in> sets lebesgue"
lp15@67998
  1185
        using * by (auto simp: borel_measurable_iff_halfspace_ge space_restrict_space)
lp15@67998
  1186
      then have 1: "{x \<in> S. real n * e \<le> \<bar>det (matrix (f' x))\<bar>} \<in> lmeasurable"
lp15@67998
  1187
        using S by (simp add: fmeasurableI2)
lp15@67998
  1188
      have "{x \<in> S. \<bar>det (matrix (f' x))\<bar> < (1 + real n) * e} \<in> sets lebesgue"
lp15@67998
  1189
        using * by (auto simp: borel_measurable_iff_halfspace_less space_restrict_space)
lp15@67998
  1190
      then have 2: "{x \<in> S. \<bar>det (matrix (f' x))\<bar> < (1 + real n) * e} \<in> lmeasurable"
lp15@67998
  1191
        using S by (simp add: fmeasurableI2)
lp15@67998
  1192
      show ?thesis
lp15@67998
  1193
        using fmeasurable.Int [OF 1 2] by (simp add: T_def Int_def cong: conj_cong)
lp15@67998
  1194
    qed
lp15@67998
  1195
    have aint_T: "\<And>k. (\<lambda>x. \<bar>det (matrix (f' x))\<bar>) absolutely_integrable_on T k"
lp15@67998
  1196
      using set_integrable_subset [OF aint_S] meas_t T_def by blast
lp15@67998
  1197
    have Seq: "S = (\<Union>n. T n)"
lp15@67998
  1198
      apply (auto simp: T_def)
lp15@67998
  1199
      apply (rule_tac x="nat(floor(abs(det(matrix(f' x))) / e))" in exI)
lp15@67998
  1200
      using that apply auto
lp15@67998
  1201
      using of_int_floor_le pos_le_divide_eq apply blast
lp15@67998
  1202
      by (metis add.commute pos_divide_less_eq real_of_int_floor_add_one_gt)
lp15@67998
  1203
    have meas_ft: "f ` T n \<in> lmeasurable" for n
lp15@67998
  1204
    proof (rule measurable_bounded_differentiable_image)
lp15@67998
  1205
      show "T n \<in> lmeasurable"
lp15@67998
  1206
        by (simp add: meas_t)
lp15@67998
  1207
    next
lp15@67998
  1208
      fix x :: "(real,'n) vec"
lp15@67998
  1209
      assume "x \<in> T n"
lp15@67998
  1210
      show "(f has_derivative f' x) (at x within T n)"
lp15@67998
  1211
        by (metis (no_types, lifting) \<open>x \<in> T n\<close> deriv has_derivative_within_subset mem_Collect_eq subsetI T_def)
lp15@67998
  1212
      show "\<bar>det (matrix (f' x))\<bar> \<le> (Suc n) * e"
lp15@67998
  1213
        using \<open>x \<in> T n\<close> T_def by auto
lp15@67998
  1214
    next
lp15@67998
  1215
      show "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) integrable_on T n"
lp15@67998
  1216
        using aint_T absolutely_integrable_on_def by blast
lp15@67998
  1217
    qed
lp15@67998
  1218
    have disT: "disjoint (range T)"
lp15@67998
  1219
      unfolding disjoint_def
lp15@67998
  1220
    proof clarsimp
lp15@67998
  1221
      show "T m \<inter> T n = {}" if "T m \<noteq> T n" for m n
lp15@67998
  1222
        using that
lp15@67998
  1223
      proof (induction m n rule: linorder_less_wlog)
lp15@67998
  1224
        case (less m n)
lp15@67998
  1225
        with \<open>e > 0\<close> show ?case
lp15@67998
  1226
          unfolding T_def
lp15@67998
  1227
          proof (clarsimp simp add: Collect_conj_eq [symmetric])
lp15@67998
  1228
            fix x
lp15@67998
  1229
            assume "e > 0"  "m < n"  "n * e \<le> \<bar>det (matrix (f' x))\<bar>"  "\<bar>det (matrix (f' x))\<bar> < (1 + real m) * e"
lp15@67998
  1230
            then have "n < 1 + real m"
lp15@67998
  1231
              by (metis (no_types, hide_lams) less_le_trans mult.commute not_le real_mult_le_cancel_iff2)
lp15@67998
  1232
            then show "False"
lp15@67998
  1233
              using less.hyps by linarith
lp15@67998
  1234
          qed
lp15@67998
  1235
      qed auto
lp15@67998
  1236
    qed
lp15@67998
  1237
    have injT: "inj_on T ({n. T n \<noteq> {}})"
lp15@67998
  1238
      unfolding inj_on_def
lp15@67998
  1239
    proof clarsimp
lp15@67998
  1240
      show "m = n" if "T m = T n" "T n \<noteq> {}" for m n
lp15@67998
  1241
        using that
lp15@67998
  1242
      proof (induction m n rule: linorder_less_wlog)
lp15@67998
  1243
        case (less m n)
lp15@67998
  1244
        have False if "T n \<subseteq> T m" "x \<in> T n" for x
lp15@67998
  1245
          using \<open>e > 0\<close> \<open>m < n\<close> that
lp15@67998
  1246
          apply (auto simp: T_def  mult.commute intro: less_le_trans dest!: subsetD)
lp15@67998
  1247
          by (metis add.commute less_le_trans nat_less_real_le not_le real_mult_le_cancel_iff2)
lp15@67998
  1248
        then show ?case
lp15@67998
  1249
          using less.prems by blast
lp15@67998
  1250
      qed auto
lp15@67998
  1251
    qed
lp15@67998
  1252
    have sum_eq_Tim: "(\<Sum>k\<le>n. f (T k)) = sum f (T ` {..n})" if "f {} = 0" for f :: "_ \<Rightarrow> real" and n
lp15@67998
  1253
    proof (subst sum.reindex_nontrivial)
lp15@67998
  1254
      fix i j  assume "i \<in> {..n}" "j \<in> {..n}" "i \<noteq> j" "T i = T j"
lp15@67998
  1255
      with that  injT [unfolded inj_on_def] show "f (T i) = 0"
lp15@67998
  1256
        by simp metis
lp15@67998
  1257
    qed (use atMost_atLeast0 in auto)
lp15@67998
  1258
    let ?B = "m + e * ?\<mu> S"
lp15@67998
  1259
    have "(\<Sum>k\<le>n. ?\<mu> (f ` T k)) \<le> ?B" for n
lp15@67998
  1260
    proof -
lp15@67998
  1261
      have "(\<Sum>k\<le>n. ?\<mu> (f ` T k)) \<le> (\<Sum>k\<le>n. ((k+1) * e) * ?\<mu>(T k))"
lp15@67998
  1262
      proof (rule sum_mono [OF measure_bounded_differentiable_image])
lp15@67998
  1263
        show "(f has_derivative f' x) (at x within T k)" if "x \<in> T k" for k x
lp15@67998
  1264
          using that unfolding T_def by (blast intro: deriv has_derivative_within_subset)
lp15@67998
  1265
        show "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) integrable_on T k" for k
lp15@67998
  1266
          using absolutely_integrable_on_def aint_T by blast
lp15@67998
  1267
        show "\<bar>det (matrix (f' x))\<bar> \<le> real (k + 1) * e" if "x \<in> T k" for k x
lp15@67998
  1268
          using T_def that by auto
lp15@67998
  1269
      qed (use meas_t in auto)
lp15@67998
  1270
      also have "\<dots> \<le> (\<Sum>k\<le>n. (k * e) * ?\<mu>(T k)) + (\<Sum>k\<le>n. e * ?\<mu>(T k))"
lp15@67998
  1271
        by (simp add: algebra_simps sum.distrib)
lp15@67998
  1272
      also have "\<dots> \<le> ?B"
lp15@67998
  1273
      proof (rule add_mono)
lp15@67998
  1274
        have "(\<Sum>k\<le>n. real k * e * ?\<mu> (T k)) = (\<Sum>k\<le>n. integral (T k) (\<lambda>x. k * e))"
lp15@67998
  1275
          by (simp add: lmeasure_integral [OF meas_t]
lp15@67998
  1276
                        integral_mult_right [symmetric] integral_mult_left [symmetric]
lp15@67998
  1277
                   del: integral_mult_right integral_mult_left)
lp15@67998
  1278
        also have "\<dots> \<le> (\<Sum>k\<le>n. integral (T k) (\<lambda>x.  (abs (det (matrix (f' x))))))"
lp15@67998
  1279
        proof (rule sum_mono)
lp15@67998
  1280
          fix k
lp15@67998
  1281
          assume "k \<in> {..n}"
lp15@67998
  1282
          show "integral (T k) (\<lambda>x. k * e) \<le> integral (T k) (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)"
lp15@67998
  1283
          proof (rule integral_le [OF integrable_on_const [OF meas_t]])
lp15@67998
  1284
            show "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) integrable_on T k"
lp15@67998
  1285
              using absolutely_integrable_on_def aint_T by blast
lp15@67998
  1286
          next
lp15@67998
  1287
            fix x assume "x \<in> T k"
lp15@67998
  1288
            show "k * e \<le> \<bar>det (matrix (f' x))\<bar>"
lp15@67998
  1289
              using \<open>x \<in> T k\<close> T_def by blast
lp15@67998
  1290
          qed
lp15@67998
  1291
        qed
lp15@67998
  1292
        also have "\<dots> = sum (\<lambda>T. integral T (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)) (T ` {..n})"
lp15@67998
  1293
          by (auto intro: sum_eq_Tim)
lp15@67998
  1294
        also have "\<dots> = integral (\<Union>k\<le>n. T k) (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)"
lp15@67998
  1295
        proof (rule integral_unique [OF has_integral_Union, symmetric])
lp15@67998
  1296
          fix S  assume "S \<in> T ` {..n}"
lp15@67998
  1297
          then show "((\<lambda>x. \<bar>det (matrix (f' x))\<bar>) has_integral integral S (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)) S"
lp15@67998
  1298
          using absolutely_integrable_on_def aint_T by blast
lp15@67998
  1299
        next
lp15@67998
  1300
          show "pairwise (\<lambda>S S'. negligible (S \<inter> S')) (T ` {..n})"
lp15@67998
  1301
            using disT unfolding disjnt_iff by (auto simp: pairwise_def intro!: empty_imp_negligible)
lp15@67998
  1302
        qed auto
lp15@67998
  1303
        also have "\<dots> \<le> m"
lp15@67998
  1304
          unfolding m_def
lp15@67998
  1305
        proof (rule integral_subset_le)
lp15@67998
  1306
          have "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) absolutely_integrable_on (\<Union>k\<le>n. T k)"
lp15@67998
  1307
            apply (rule set_integrable_subset [OF aint_S])
lp15@67998
  1308
             apply (intro measurable meas_t fmeasurableD)
lp15@67998
  1309
            apply (force simp: Seq)
lp15@67998
  1310
            done
lp15@67998
  1311
          then show "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) integrable_on (\<Union>k\<le>n. T k)"
lp15@67998
  1312
            using absolutely_integrable_on_def by blast
lp15@67998
  1313
        qed (use Seq int in auto)
lp15@67998
  1314
        finally show "(\<Sum>k\<le>n. real k * e * ?\<mu> (T k)) \<le> m" .
lp15@67998
  1315
      next
lp15@67998
  1316
        have "(\<Sum>k\<le>n. ?\<mu> (T k)) = sum ?\<mu> (T ` {..n})"
lp15@67998
  1317
          by (auto intro: sum_eq_Tim)
lp15@67998
  1318
        also have "\<dots> = ?\<mu> (\<Union>k\<le>n. T k)"
lp15@67998
  1319
          using S disT by (auto simp: pairwise_def meas_t intro: measure_Union' [symmetric])
lp15@67998
  1320
        also have "\<dots> \<le> ?\<mu> S"
lp15@67998
  1321
          using S by (auto simp: Seq intro: meas_t fmeasurableD measure_mono_fmeasurable)
lp15@67998
  1322
        finally have "(\<Sum>k\<le>n. ?\<mu> (T k)) \<le> ?\<mu> S" .
lp15@67998
  1323
        then show "(\<Sum>k\<le>n. e * ?\<mu> (T k)) \<le> e * ?\<mu> S"
lp15@67998
  1324
          by (metis less_eq_real_def ordered_comm_semiring_class.comm_mult_left_mono sum_distrib_left that)
lp15@67998
  1325
      qed
lp15@67998
  1326
      finally show "(\<Sum>k\<le>n. ?\<mu> (f ` T k)) \<le> ?B" .
lp15@67998
  1327
    qed
lp15@67998
  1328
    moreover have "measure lebesgue (\<Union>k\<le>n. f ` T k) \<le> (\<Sum>k\<le>n. ?\<mu> (f ` T k))" for n
lp15@67998
  1329
      by (simp add: fmeasurableD meas_ft measure_UNION_le)
lp15@67998
  1330
    ultimately have B_ge_m: "?\<mu> (\<Union>k\<le>n. (f ` T k)) \<le> ?B" for n
lp15@67998
  1331
      by (meson order_trans)
lp15@67998
  1332
    have "(\<Union>n. f ` T n) \<in> lmeasurable"
lp15@67998
  1333
      by (rule fmeasurable_countable_Union [OF meas_ft B_ge_m])
lp15@67998
  1334
    moreover have "?\<mu> (\<Union>n. f ` T n) \<le> m + e * ?\<mu> S"
lp15@67998
  1335
      by (rule measure_countable_Union_le [OF meas_ft B_ge_m])
lp15@67998
  1336
    ultimately show "f ` S \<in> lmeasurable" "?\<mu> (f ` S) \<le> m + e * ?\<mu> S"
lp15@67998
  1337
      by (auto simp: Seq image_Union)
lp15@67998
  1338
  qed
lp15@67998
  1339
  show ?thesis
lp15@67998
  1340
  proof
lp15@67998
  1341
    show "f ` S \<in> lmeasurable"
lp15@67998
  1342
      using * linordered_field_no_ub by blast
lp15@67998
  1343
    let ?x = "m - ?\<mu> (f ` S)"
lp15@67998
  1344
    have False if "?\<mu> (f ` S) > integral S (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)"
lp15@67998
  1345
    proof -
lp15@67998
  1346
      have ml: "m < ?\<mu> (f ` S)"
lp15@67998
  1347
        using m_def that by blast
lp15@67998
  1348
      then have "?\<mu> S \<noteq> 0"
lp15@67998
  1349
        using "*"(2) bgauge_existence_lemma by fastforce
lp15@67998
  1350
      with ml have 0: "0 < - (m - ?\<mu> (f ` S))/2 / ?\<mu> S"
lp15@67998
  1351
        using that zero_less_measure_iff by force
lp15@67998
  1352
      then show ?thesis
lp15@67998
  1353
        using * [OF 0] that by (auto simp: divide_simps m_def split: if_split_asm)
lp15@67998
  1354
    qed
lp15@67998
  1355
    then show "?\<mu> (f ` S) \<le> integral S (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)"
lp15@67998
  1356
      by fastforce
lp15@67998
  1357
  qed
lp15@67998
  1358
qed
lp15@67998
  1359
lp15@67998
  1360
lp15@67998
  1361
theorem
lp15@67998
  1362
 fixes f :: "real^'n::{finite,wellorder} \<Rightarrow> real^'n::_"
lp15@67998
  1363
  assumes S: "S \<in> sets lebesgue"
lp15@67998
  1364
    and deriv: "\<And>x. x \<in> S \<Longrightarrow> (f has_derivative f' x) (at x within S)"
lp15@67998
  1365
    and int: "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) integrable_on S"
lp15@67998
  1366
  shows measurable_differentiable_image: "f ` S \<in> lmeasurable"
lp15@67998
  1367
    and measure_differentiable_image:
lp15@67998
  1368
       "measure lebesgue (f ` S) \<le> integral S (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)" (is "?M")
lp15@67998
  1369
proof -
lp15@67998
  1370
  let ?I = "\<lambda>n::nat. cbox (vec (-n)) (vec n) \<inter> S"
lp15@67998
  1371
  let ?\<mu> = "measure lebesgue"
lp15@67998
  1372
  have "x \<in> cbox (vec (- real (nat \<lceil>norm x\<rceil>))) (vec (real (nat \<lceil>norm x\<rceil>)))" for x :: "real^'n::_"
lp15@67998
  1373
    apply (auto simp: mem_box_cart)
lp15@67998
  1374
    apply (metis abs_le_iff component_le_norm_cart minus_le_iff of_nat_ceiling order.trans)
lp15@67998
  1375
    by (meson abs_le_D1 norm_bound_component_le_cart real_nat_ceiling_ge)
lp15@67998
  1376
  then have Seq: "S = (\<Union>n. ?I n)"
lp15@67998
  1377
    by auto
lp15@67998
  1378
  have fIn: "f ` ?I n \<in> lmeasurable"
lp15@67998
  1379
       and mfIn: "?\<mu> (f ` ?I n) \<le> integral S (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)" (is ?MN) for n
lp15@67998
  1380
  proof -
lp15@67998
  1381
    have In: "?I n \<in> lmeasurable"
lp15@67998
  1382
      by (simp add: S bounded_Int bounded_set_imp_lmeasurable sets.Int)
lp15@67998
  1383
    moreover have "\<And>x. x \<in> ?I n \<Longrightarrow> (f has_derivative f' x) (at x within ?I n)"
lp15@67998
  1384
      by (meson Int_iff deriv has_derivative_within_subset subsetI)
lp15@67998
  1385
    moreover have int_In: "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) integrable_on ?I n"
lp15@67998
  1386
    proof -
lp15@67998
  1387
      have "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) absolutely_integrable_on S"
lp15@67998
  1388
        using int absolutely_integrable_integrable_bound by force
lp15@67998
  1389
      then have "(\<lambda>x. \<bar>det (matrix (f' x))\<bar>) absolutely_integrable_on ?I n"
lp15@67998
  1390
        by (metis (no_types) Int_lower1 In fmeasurableD inf_commute set_integrable_subset)
lp15@67998
  1391
      then show ?thesis
lp15@67998
  1392
        using absolutely_integrable_on_def by blast
lp15@67998
  1393
    qed
lp15@67998
  1394
    ultimately have "f ` ?I n \<in> lmeasurable" "?\<mu> (f ` ?I n) \<le> integral (?I n) (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)"
lp15@67998
  1395
      using m_diff_image_weak by metis+
lp15@67998
  1396
    moreover have "integral (?I n) (\<lambda>x. \<bar>det (matrix (f' x))\<bar>) \<le> integral S (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)"
lp15@67998
  1397
      by (simp add: int_In int integral_subset_le)
lp15@67998
  1398
    ultimately show "f ` ?I n \<in> lmeasurable" ?MN
lp15@67998
  1399
      by auto
lp15@67998
  1400
  qed
lp15@67998
  1401
  have "?I k \<subseteq> ?I n" if "k \<le> n" for k n
lp15@67998
  1402
    by (rule Int_mono) (use that in \<open>auto simp: subset_interval_imp_cart\<close>)
lp15@67998
  1403
  then have "(\<Union>k\<le>n. f ` ?I k) = f ` ?I n" for n
lp15@67998
  1404
    by (fastforce simp add:)
lp15@67998
  1405
  with mfIn have "?\<mu> (\<Union>k\<le>n. f ` ?I k) \<le> integral S (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)" for n
lp15@67998
  1406
    by simp
lp15@67998
  1407
  then have "(\<Union>n. f ` ?I n) \<in> lmeasurable" "?\<mu> (\<Union>n. f ` ?I n) \<le> integral S (\<lambda>x. \<bar>det (matrix (f' x))\<bar>)"
lp15@67998
  1408
    by (rule fmeasurable_countable_Union [OF fIn] measure_countable_Union_le [OF fIn])+
lp15@67998
  1409
  then show "f ` S \<in> lmeasurable" ?M
lp15@67998
  1410
    by (metis Seq image_UN)+
lp15@67998
  1411
qed
lp15@67998
  1412
lp15@67998
  1413
lp15@67998
  1414
lemma borel_measurable_simple_function_limit_increasing:
lp15@67998
  1415
  fixes f :: "'a::euclidean_space \<Rightarrow> real"
lp15@67998
  1416
  shows "(f \<in> borel_measurable lebesgue \<and> (\<forall>x. 0 \<le> f x)) \<longleftrightarrow>
lp15@67998
  1417
         (\<exists>g. (\<forall>n x. 0 \<le> g n x \<and> g n x \<le> f x) \<and> (\<forall>n x. g n x \<le> (g(Suc n) x)) \<and>
lp15@67998
  1418
              (\<forall>n. g n \<in> borel_measurable lebesgue) \<and> (\<forall>n. finite(range (g n))) \<and>
lp15@67998
  1419
              (\<forall>x. (\<lambda>n. g n x) \<longlonglongrightarrow> f x))"
lp15@67998
  1420
         (is "?lhs = ?rhs")
lp15@67998
  1421
proof
lp15@67998
  1422
  assume f: ?lhs
lp15@67998
  1423
  have leb_f: "{x. a \<le> f x \<and> f x < b} \<in> sets lebesgue" for a b
lp15@67998
  1424
  proof -
lp15@67998
  1425
    have "{x. a \<le> f x \<and> f x < b} = {x. f x < b} - {x. f x < a}"
lp15@67998
  1426
      by auto
lp15@67998
  1427
    also have "\<dots> \<in> sets lebesgue"
lp15@67998
  1428
      using borel_measurable_vimage_halfspace_component_lt [of f UNIV] f by auto
lp15@67998
  1429
    finally show ?thesis .
lp15@67998
  1430
  qed
lp15@67998
  1431
  have "g n x \<le> f x"
lp15@67998
  1432
        if inc_g: "\<And>n x. 0 \<le> g n x \<and> g n x \<le> g (Suc n) x"
lp15@67998
  1433
           and meas_g: "\<And>n. g n \<in> borel_measurable lebesgue"
lp15@67998
  1434
           and fin: "\<And>n. finite(range (g n))" and lim: "\<And>x. (\<lambda>n. g n x) \<longlonglongrightarrow> f x" for g n x
lp15@67998
  1435
  proof -
lp15@67998
  1436
    have "\<exists>r>0. \<forall>N. \<exists>n\<ge>N. dist (g n x) (f x) \<ge> r" if "g n x > f x"
lp15@67998
  1437
    proof -
lp15@67998
  1438
      have g: "g n x \<le> g (N + n) x" for N
lp15@67998
  1439
        by (rule transitive_stepwise_le) (use inc_g in auto)
lp15@67998
  1440
      have "\<exists>na\<ge>N. g n x - f x \<le> dist (g na x) (f x)" for N
lp15@67998
  1441
        apply (rule_tac x="N+n" in exI)
lp15@67998
  1442
        using g [of N] by (auto simp: dist_norm)
lp15@67998
  1443
      with that show ?thesis
lp15@67998
  1444
        using diff_gt_0_iff_gt by blast
lp15@67998
  1445
    qed
lp15@67998
  1446
    with lim show ?thesis
lp15@67998
  1447
      apply (auto simp: lim_sequentially)
lp15@67998
  1448
      by (meson less_le_not_le not_le_imp_less)
lp15@67998
  1449
  qed
lp15@67998
  1450
  moreover
lp15@67998
  1451
  let ?\<Omega> = "\<lambda>n k. indicator {y. k/2^n \<le> f y \<and> f y < (k+1)/2^n}"
lp15@67998
  1452
  let ?g = "\<lambda>n x. (\<Sum>k::real | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n). k/2^n * ?\<Omega> n k x)"
lp15@67998
  1453
  have "\<exists>g. (\<forall>n x. 0 \<le> g n x \<and> g n x \<le> (g(Suc n) x)) \<and>
lp15@67998
  1454
             (\<forall>n. g n \<in> borel_measurable lebesgue) \<and> (\<forall>n. finite(range (g n))) \<and>(\<forall>x. (\<lambda>n. g n x) \<longlonglongrightarrow> f x)"
lp15@67998
  1455
  proof (intro exI allI conjI)
lp15@67998
  1456
    show "0 \<le> ?g n x" for n x
lp15@67998
  1457
    proof (clarify intro!: ordered_comm_monoid_add_class.sum_nonneg)
lp15@67998
  1458
      fix k::real
lp15@67998
  1459
      assume "k \<in> \<int>" and k: "\<bar>k\<bar> \<le> 2 ^ (2*n)"
lp15@67998
  1460
      show "0 \<le> k/2^n * ?\<Omega> n k x"
lp15@67998
  1461
        using f \<open>k \<in> \<int>\<close> apply (auto simp: indicator_def divide_simps Ints_def)
lp15@67998
  1462
        apply (drule spec [where x=x])
lp15@67998
  1463
        using zero_le_power [of "2::real" n] mult_nonneg_nonneg [of "f x" "2^n"]
lp15@67998
  1464
        by linarith
lp15@67998
  1465
    qed
lp15@67998
  1466
    show "?g n x \<le> ?g (Suc n) x" for n x
lp15@67998
  1467
    proof -
lp15@67998
  1468
      have "?g n x =
lp15@67998
  1469
            (\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n).
lp15@67998
  1470
              k/2^n * (indicator {y. k/2^n \<le> f y \<and> f y < (k+1/2)/2^n} x +
lp15@67998
  1471
              indicator {y. (k+1/2)/2^n \<le> f y \<and> f y < (k+1)/2^n} x))"
lp15@67998
  1472
        by (rule sum.cong [OF refl]) (simp add: indicator_def divide_simps)
lp15@67998
  1473
      also have "\<dots> = (\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n). k/2^n * indicator {y. k/2^n \<le> f y \<and> f y < (k+1/2)/2^n} x) +
lp15@67998
  1474
                       (\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n). k/2^n * indicator {y. (k+1/2)/2^n \<le> f y \<and> f y < (k+1)/2^n} x)"
lp15@67998
  1475
        by (simp add:  comm_monoid_add_class.sum.distrib algebra_simps)
lp15@67998
  1476
      also have "\<dots> = (\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n). (2 * k)/2 ^ Suc n * indicator {y. (2 * k)/2 ^ Suc n \<le> f y \<and> f y < (2 * k+1)/2 ^ Suc n} x) +
lp15@67998
  1477
                       (\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n). (2 * k)/2 ^ Suc n * indicator {y. (2 * k+1)/2 ^ Suc n \<le> f y \<and> f y < ((2 * k+1) + 1)/2 ^ Suc n} x)"
lp15@67998
  1478
        by (force simp: field_simps indicator_def intro: sum.cong)
lp15@67998
  1479
      also have "\<dots> \<le> (\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2 * Suc n). k/2 ^ Suc n * (indicator {y. k/2 ^ Suc n \<le> f y \<and> f y < (k+1)/2 ^ Suc n} x))"
lp15@67998
  1480
                (is "?a + _ \<le> ?b")
lp15@67998
  1481
      proof -
lp15@67998
  1482
        have *: "\<lbrakk>sum f I \<le> sum h I; a + sum h I \<le> b\<rbrakk> \<Longrightarrow> a + sum f I \<le> b" for I a b f and h :: "real\<Rightarrow>real"
lp15@67998
  1483
          by linarith
lp15@67998
  1484
        let ?h = "\<lambda>k. (2*k+1)/2 ^ Suc n *
lp15@67998
  1485
                      (indicator {y. (2 * k+1)/2 ^ Suc n \<le> f y \<and> f y < ((2*k+1) + 1)/2 ^ Suc n} x)"
lp15@67998
  1486
        show ?thesis
lp15@67998
  1487
        proof (rule *)
lp15@67998
  1488
          show "(\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n).
lp15@67998
  1489
                  2 * k/2 ^ Suc n * indicator {y. (2 * k+1)/2 ^ Suc n \<le> f y \<and> f y < (2 * k+1 + 1)/2 ^ Suc n} x)
lp15@67998
  1490
                \<le> sum ?h {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)}"
lp15@67998
  1491
            by (rule sum_mono) (simp add: indicator_def divide_simps)
lp15@67998
  1492
        next
lp15@67998
  1493
          have \<alpha>: "?a = (\<Sum>k \<in> ( *)2 ` {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)}.
lp15@67998
  1494
                         k/2 ^ Suc n * indicator {y. k/2 ^ Suc n \<le> f y \<and> f y < (k+1)/2 ^ Suc n} x)"
lp15@67998
  1495
            by (auto simp: inj_on_def field_simps comm_monoid_add_class.sum.reindex)
lp15@67998
  1496
          have \<beta>: "sum ?h {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)}
lp15@67998
  1497
                   = (\<Sum>k \<in> (\<lambda>x. 2*x + 1) ` {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)}.
lp15@67998
  1498
                      k/2 ^ Suc n * indicator {y. k/2 ^ Suc n \<le> f y \<and> f y < (k+1)/2 ^ Suc n} x)"
lp15@67998
  1499
            by (auto simp: inj_on_def field_simps comm_monoid_add_class.sum.reindex)
lp15@67998
  1500
          have 0: "( *) 2 ` {k \<in> \<int>. P k} \<inter> (\<lambda>x. 2 * x + 1) ` {k \<in> \<int>. P k} = {}" for P :: "real \<Rightarrow> bool"
lp15@67998
  1501
          proof -
lp15@67998
  1502
            have "2 * i \<noteq> 2 * j + 1" for i j :: int by arith
lp15@67998
  1503
            thus ?thesis
lp15@67998
  1504
              unfolding Ints_def by auto (use of_int_eq_iff in fastforce)
lp15@67998
  1505
          qed
lp15@67998
  1506
          have "?a + sum ?h {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)}
lp15@67998
  1507
                = (\<Sum>k \<in> ( *)2 ` {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)} \<union> (\<lambda>x. 2*x + 1) ` {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)}.
lp15@67998
  1508
                  k/2 ^ Suc n * indicator {y. k/2 ^ Suc n \<le> f y \<and> f y < (k+1)/2 ^ Suc n} x)"
lp15@67998
  1509
            unfolding \<alpha> \<beta>
lp15@67998
  1510
            using finite_abs_int_segment [of "2 ^ (2*n)"]
lp15@67998
  1511
            by (subst sum_Un) (auto simp: 0)
lp15@67998
  1512
          also have "\<dots> \<le> ?b"
lp15@67998
  1513
          proof (rule sum_mono2)
lp15@67998
  1514
            show "finite {k::real. k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2 * Suc n)}"
lp15@67998
  1515
              by (rule finite_abs_int_segment)
lp15@67998
  1516
            show "( *) 2 ` {k::real. k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2^(2*n)} \<union> (\<lambda>x. 2*x + 1) ` {k \<in> \<int>. \<bar>k\<bar> \<le> 2^(2*n)} \<subseteq> {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2 * Suc n)}"
lp15@67998
  1517
              apply auto
lp15@67998
  1518
              using one_le_power [of "2::real" "2*n"]  by linarith
lp15@67998
  1519
            have *: "\<lbrakk>x \<in> (S \<union> T) - U; \<And>x. x \<in> S \<Longrightarrow> x \<in> U; \<And>x. x \<in> T \<Longrightarrow> x \<in> U\<rbrakk> \<Longrightarrow> P x" for S T U P
lp15@67998
  1520
              by blast
lp15@67998
  1521
            have "0 \<le> b" if "b \<in> \<int>" "f x * (2 * 2^n) < b + 1" for b
lp15@67998
  1522
            proof -
lp15@67998
  1523
              have "0 \<le> f x * (2 * 2^n)"
lp15@67998
  1524
                by (simp add: f)
lp15@67998
  1525
              also have "\<dots> < b+1"
lp15@67998
  1526
                by (simp add: that)
lp15@67998
  1527
              finally show "0 \<le> b"
lp15@67998
  1528
                using \<open>b \<in> \<int>\<close> by (auto simp: elim!: Ints_cases)
lp15@67998
  1529
            qed
lp15@67998
  1530
            then show "0 \<le> b/2 ^ Suc n * indicator {y. b/2 ^ Suc n \<le> f y \<and> f y < (b + 1)/2 ^ Suc n} x"
lp15@67998
  1531
                  if "b \<in> {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2 * Suc n)} -
lp15@67998
  1532
                          (( *) 2 ` {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)} \<union> (\<lambda>x. 2*x + 1) ` {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)})" for b
lp15@67998
  1533
              using that by (simp add: indicator_def divide_simps)
lp15@67998
  1534
          qed
lp15@67998
  1535
          finally show "?a + sum ?h {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)} \<le> ?b" .
lp15@67998
  1536
        qed
lp15@67998
  1537
      qed
lp15@67998
  1538
      finally show ?thesis .
lp15@67998
  1539
    qed
lp15@67998
  1540
    show "?g n \<in> borel_measurable lebesgue" for n
lp15@67998
  1541
      apply (intro borel_measurable_indicator borel_measurable_times borel_measurable_sum)
lp15@67998
  1542
      using leb_f sets_restrict_UNIV by auto
lp15@67998
  1543
    show "finite (range (?g n))" for n
lp15@67998
  1544
    proof -
lp15@67998
  1545
      have "(\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n). k/2^n * ?\<Omega> n k x)
lp15@67998
  1546
              \<in> (\<lambda>k. k/2^n) ` {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)}" for x
lp15@67998
  1547
      proof (cases "\<exists>k. k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n) \<and> k/2^n \<le> f x \<and> f x < (k+1)/2^n")
lp15@67998
  1548
        case True
lp15@67998
  1549
        then show ?thesis
lp15@67998
  1550
          by (blast intro: indicator_sum_eq)
lp15@67998
  1551
      next
lp15@67998
  1552
        case False
lp15@67998
  1553
        then have "(\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n). k/2^n * ?\<Omega> n k x) = 0"
lp15@67998
  1554
          by auto
lp15@67998
  1555
        then show ?thesis by force
lp15@67998
  1556
      qed
lp15@67998
  1557
      then have "range (?g n) \<subseteq> ((\<lambda>k. (k/2^n)) ` {k. k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n)})"
lp15@67998
  1558
        by auto
lp15@67998
  1559
      moreover have "finite ((\<lambda>k::real. (k/2^n)) ` {k \<in> \<int>. \<bar>k\<bar> \<le> 2 ^ (2*n)})"
lp15@67998
  1560
        by (intro finite_imageI finite_abs_int_segment)
lp15@67998
  1561
      ultimately show ?thesis
lp15@67998
  1562
        by (rule finite_subset)
lp15@67998
  1563
    qed
lp15@67998
  1564
    show "(\<lambda>n. ?g n x) \<longlonglongrightarrow> f x" for x
lp15@67998
  1565
    proof (clarsimp simp add: lim_sequentially)
lp15@67998
  1566
      fix e::real
lp15@67998
  1567
      assume "e > 0"
lp15@67998
  1568
      obtain N1 where N1: "2 ^ N1 > abs(f x)"
lp15@67998
  1569
        using real_arch_pow by fastforce
lp15@67998
  1570
      obtain N2 where N2: "(1/2) ^ N2 < e"
lp15@67998
  1571
        using real_arch_pow_inv \<open>e > 0\<close> by fastforce
lp15@67998
  1572
      have "dist (\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n). k/2^n * ?\<Omega> n k x) (f x) < e" if "N1 + N2 \<le> n" for n
lp15@67998
  1573
      proof -
lp15@67998
  1574
        let ?m = "real_of_int \<lfloor>2^n * f x\<rfloor>"
lp15@67998
  1575
        have "\<bar>?m\<bar> \<le> 2^n * 2^N1"
lp15@67998
  1576
          using N1 apply (simp add: f)
lp15@67998
  1577
          by (meson floor_mono le_floor_iff less_le_not_le mult_le_cancel_left_pos zero_less_numeral zero_less_power)
lp15@67998
  1578
        also have "\<dots> \<le> 2 ^ (2*n)"
lp15@67998
  1579
          by (metis that add_leD1 add_le_cancel_left mult.commute mult_2_right one_less_numeral_iff
lp15@67998
  1580
                    power_add power_increasing_iff semiring_norm(76))
lp15@67998
  1581
        finally have m_le: "\<bar>?m\<bar> \<le> 2 ^ (2*n)" .
lp15@67998
  1582
        have "?m/2^n \<le> f x" "f x < (?m + 1)/2^n"
lp15@67998
  1583
          by (auto simp: mult.commute pos_divide_le_eq mult_imp_less_div_pos)
lp15@67998
  1584
        then have eq: "dist (\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n). k/2^n * ?\<Omega> n k x) (f x)
lp15@67998
  1585
                     = dist (?m/2^n) (f x)"
lp15@67998
  1586
          by (subst indicator_sum_eq [of ?m]) (auto simp: m_le)
lp15@67998
  1587
        have "\<bar>2^n\<bar> * \<bar>?m/2^n - f x\<bar> = \<bar>2^n * (?m/2^n - f x)\<bar>"
lp15@67998
  1588
          by (simp add: abs_mult)
lp15@67998
  1589
        also have "\<dots> < 2 ^ N2 * e"
lp15@67998
  1590
          using N2 by (simp add: divide_simps mult.commute) linarith
lp15@67998
  1591
        also have "\<dots> \<le> \<bar>2^n\<bar> * e"
lp15@67998
  1592
          using that \<open>e > 0\<close> by auto
lp15@67998
  1593
        finally have "dist (?m/2^n) (f x) < e"
lp15@67998
  1594
          by (simp add: dist_norm)
lp15@67998
  1595
        then show ?thesis
lp15@67998
  1596
          using eq by linarith
lp15@67998
  1597
      qed
lp15@67998
  1598
      then show "\<exists>no. \<forall>n\<ge>no. dist (\<Sum>k | k \<in> \<int> \<and> \<bar>k\<bar> \<le> 2 ^ (2*n). k * ?\<Omega> n k x/2^n) (f x) < e"
lp15@67998
  1599
        by force
lp15@67998
  1600
    qed
lp15@67998
  1601
  qed
lp15@67998
  1602
  ultimately show ?rhs
lp15@67998
  1603
    by metis
lp15@67998
  1604
next
lp15@67998
  1605
  assume RHS: ?rhs
lp15@67998
  1606
  with borel_measurable_simple_function_limit [of f UNIV, unfolded borel_measurable_UNIV_eq]
lp15@67998
  1607
  show ?lhs
lp15@67998
  1608
    by (blast intro: order_trans)
lp15@67998
  1609
qed
lp15@67998
  1610
lp15@67998
  1611
subsection\<open>Borel measurable Jacobian determinant\<close>
lp15@67998
  1612
lp15@67998
  1613
lemma lemma_partial_derivatives0:
lp15@67998
  1614
  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
lp15@67998
  1615
  assumes "linear f" and lim0: "((\<lambda>x. f x /\<^sub>R norm x) \<longlongrightarrow> 0) (at 0 within S)"
lp15@67998
  1616
    and lb: "\<And>v. v \<noteq> 0 \<Longrightarrow> (\<exists>k>0. \<forall>e>0. \<exists>x. x \<in> S - {0} \<and> norm x < e \<and> k * norm x \<le> \<bar>v \<bullet> x\<bar>)"
lp15@67998
  1617
  shows "f x = 0"
lp15@67998
  1618
proof -
lp15@67998
  1619
  have "dim {x. f x = 0} \<le> DIM('a)"
lp15@67998
  1620
    using dim_subset_UNIV by blast
lp15@67998
  1621
  moreover have False if less: "dim {x. f x = 0} < DIM('a)"
lp15@67998
  1622
  proof -
lp15@67998
  1623
    obtain d where "d \<noteq> 0" and d: "\<And>y. f y = 0 \<Longrightarrow> d \<bullet> y = 0"
lp15@67998
  1624
      using orthogonal_to_subspace_exists [OF less] orthogonal_def
lp15@67998
  1625
      by (metis (mono_tags, lifting) mem_Collect_eq span_clauses(1))
lp15@67998
  1626
    then obtain k where "k > 0"
lp15@67998
  1627
      and k: "\<And>e. e > 0 \<Longrightarrow> \<exists>y. y \<in> S - {0} \<and> norm y < e \<and> k * norm y \<le> \<bar>d \<bullet> y\<bar>"
lp15@67998
  1628
      using lb by blast
lp15@67998
  1629
    have "\<exists>h. \<forall>n. ((h n \<in> S \<and> h n \<noteq> 0 \<and> k * norm (h n) \<le> \<bar>d \<bullet> h n\<bar>) \<and> norm (h n) < 1 / real (Suc n)) \<and>
lp15@67998
  1630
               norm (h (Suc n)) < norm (h n)"
lp15@67998
  1631
    proof (rule dependent_nat_choice)
lp15@67998
  1632
      show "\<exists>y. (y \<in> S \<and> y \<noteq> 0 \<and> k * norm y \<le> \<bar>d \<bullet> y\<bar>) \<and> norm y < 1 / real (Suc 0)"
lp15@67998
  1633
        by simp (metis DiffE insertCI k not_less not_one_le_zero)
lp15@67998
  1634
    qed (use k [of "min (norm x) (1/(Suc n + 1))" for x n] in auto)
lp15@67998
  1635
    then obtain \<alpha> where \<alpha>: "\<And>n. \<alpha> n \<in> S - {0}" and kd: "\<And>n. k * norm(\<alpha> n) \<le> \<bar>d \<bullet> \<alpha> n\<bar>"
lp15@67998
  1636
         and norm_lt: "\<And>n. norm(\<alpha> n) < 1/(Suc n)"
lp15@67998
  1637
      by force
lp15@67998
  1638
    let ?\<beta> = "\<lambda>n. \<alpha> n /\<^sub>R norm (\<alpha> n)"
lp15@67998
  1639
    have com: "\<And>g. (\<forall>n. g n \<in> sphere (0::'a) 1)
lp15@67998
  1640
              \<Longrightarrow> \<exists>l \<in> sphere 0 1. \<exists>\<rho>::nat\<Rightarrow>nat. strict_mono \<rho> \<and> (g \<circ> \<rho>) \<longlonglongrightarrow> l"
lp15@67998
  1641
      using compact_sphere compact_def by metis
lp15@67998
  1642
    moreover have "\<forall>n. ?\<beta> n \<in> sphere 0 1"
lp15@67998
  1643
      using \<alpha> by auto
lp15@67998
  1644
    ultimately obtain l::'a and \<rho>::"nat\<Rightarrow>nat"
lp15@67998
  1645
       where l: "l \<in> sphere 0 1" and "strict_mono \<rho>" and to_l: "(?\<beta> \<circ> \<rho>) \<longlonglongrightarrow> l"
lp15@67998
  1646
      by meson
lp15@67998
  1647
    moreover have "continuous (at l) (\<lambda>x. (\<bar>d \<bullet> x\<bar> - k))"
lp15@67998
  1648
      by (intro continuous_intros)
lp15@67998
  1649
    ultimately have lim_dl: "((\<lambda>x. (\<bar>d \<bullet> x\<bar> - k)) \<circ> (?\<beta> \<circ> \<rho>)) \<longlonglongrightarrow> (\<bar>d \<bullet> l\<bar> - k)"
lp15@67998
  1650
      by (meson continuous_imp_tendsto)
lp15@67998
  1651
    have "\<forall>\<^sub>F i in sequentially. 0 \<le> ((\<lambda>x. \<bar>d \<bullet> x\<bar> - k) \<circ> ((\<lambda>n. \<alpha> n /\<^sub>R norm (\<alpha> n)) \<circ> \<rho>)) i"
lp15@67998
  1652
      using \<alpha> kd by (auto simp: divide_simps)
lp15@67998
  1653
    then have "k \<le> \<bar>d \<bullet> l\<bar>"
lp15@67998
  1654
      using tendsto_lowerbound [OF lim_dl, of 0] by auto
lp15@67998
  1655
    moreover have "d \<bullet> l = 0"
lp15@67998
  1656
    proof (rule d)
lp15@67998
  1657
      show "f l = 0"
lp15@67998
  1658
      proof (rule LIMSEQ_unique [of "f \<circ> ?\<beta> \<circ> \<rho>"])
lp15@67998
  1659
        have "isCont f l"
lp15@67998
  1660
          using \<open>linear f\<close> linear_continuous_at linear_conv_bounded_linear by blast
lp15@67998
  1661
        then show "(f \<circ> (\<lambda>n. \<alpha> n /\<^sub>R norm (\<alpha> n)) \<circ> \<rho>) \<longlonglongrightarrow> f l"
lp15@67998
  1662
          unfolding comp_assoc
lp15@67998
  1663
          using to_l continuous_imp_tendsto by blast
lp15@67998
  1664
        have "\<alpha> \<longlonglongrightarrow> 0"
lp15@67998
  1665
          using norm_lt LIMSEQ_norm_0 by metis
lp15@67998
  1666
        with \<open>strict_mono \<rho>\<close> have "(\<alpha> \<circ> \<rho>) \<longlonglongrightarrow> 0"
lp15@67998
  1667
          by (metis LIMSEQ_subseq_LIMSEQ)
lp15@67998
  1668
        with lim0 \<alpha> have "((\<lambda>x. f x /\<^sub>R norm x) \<circ> (\<alpha> \<circ> \<rho>)) \<longlonglongrightarrow> 0"
lp15@67998
  1669
          by (force simp: tendsto_at_iff_sequentially)
lp15@67998
  1670
        then show "(f \<circ> (\<lambda>n. \<alpha> n /\<^sub>R norm (\<alpha> n)) \<circ> \<rho>) \<longlonglongrightarrow> 0"
lp15@67998
  1671
          by (simp add: o_def linear_cmul \<open>linear f\<close>)
lp15@67998
  1672
      qed
lp15@67998
  1673
    qed
lp15@67998
  1674
    ultimately show False
lp15@67998
  1675
      using \<open>k > 0\<close> by auto
lp15@67998
  1676
  qed
lp15@67998
  1677
  ultimately have dim: "dim {x. f x = 0} = DIM('a)"
lp15@67998
  1678
    by force
lp15@67998
  1679
  then show ?thesis
lp15@67998
  1680
    by (metis (mono_tags, lifting) UNIV_I assms(1) dim_eq_full linear_eq_0_span mem_Collect_eq)
lp15@67998
  1681
qed
lp15@67998
  1682
lp15@67998
  1683
lemma lemma_partial_derivatives:
lp15@67998
  1684
  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
lp15@67998
  1685
  assumes "linear f" and lim: "((\<lambda>x. f (x - a) /\<^sub>R norm (x - a)) \<longlongrightarrow> 0) (at a within S)"
lp15@67998
  1686
    and lb: "\<And>v. v \<noteq> 0 \<Longrightarrow> (\<exists>k>0.  \<forall>e>0. \<exists>x \<in> S - {a}. norm(a - x) < e \<and> k * norm(a - x) \<le> \<bar>v \<bullet> (x - a)\<bar>)"
lp15@67998
  1687
  shows "f x = 0"
lp15@67998
  1688
proof -
lp15@67998
  1689
  have "((\<lambda>x. f x /\<^sub>R norm x) \<longlongrightarrow> 0) (at 0 within (\<lambda>x. x-a) ` S)"
lp15@67998
  1690
    using lim by (simp add: Lim_within dist_norm)
lp15@67998
  1691
  then show ?thesis
lp15@67998
  1692
  proof (rule lemma_partial_derivatives0 [OF \<open>linear f\<close>])
lp15@67998
  1693
    fix v :: "'a"
lp15@67998
  1694
    assume v: "v \<noteq> 0"
lp15@67998
  1695
    show "\<exists>k>0. \<forall>e>0. \<exists>x. x \<in> (\<lambda>x. x - a) ` S - {0} \<and> norm x < e \<and> k * norm x \<le> \<bar>v \<bullet> x\<bar>"
lp15@67998
  1696
      using lb [OF v] by (force simp:  norm_minus_commute)
lp15@67998
  1697
  qed
lp15@67998
  1698
qed
lp15@67998
  1699
lp15@67998
  1700
lp15@67998
  1701
proposition borel_measurable_partial_derivatives:
lp15@67998
  1702
  fixes f :: "real^'m::{finite,wellorder} \<Rightarrow> real^'n"
lp15@67998
  1703
  assumes S: "S \<in> sets lebesgue"
lp15@67998
  1704
    and f: "\<And>x. x \<in> S \<Longrightarrow> (f has_derivative f' x) (at x within S)"
lp15@67998
  1705
  shows "(\<lambda>x. (matrix(f' x)$m$n)) \<in> borel_measurable (lebesgue_on S)"
lp15@67998
  1706
proof -
lp15@67998
  1707
  have contf: "continuous_on S f"
lp15@67998
  1708
    using continuous_on_eq_continuous_within f has_derivative_continuous by blast
lp15@67998
  1709
  have "{x \<in> S.  (matrix (f' x)$m$n) \<le> b} \<in> sets lebesgue" for b
lp15@67998
  1710
  proof (rule sets_negligible_symdiff)
lp15@67998
  1711
    let ?T = "{x \<in> S. \<forall>e>0. \<exists>d>0. \<exists>A. A$m$n < b \<and> (\<forall>i j. A$i$j \<in> \<rat>) \<and>
lp15@67998
  1712
                       (\<forall>y \<in> S. norm(y - x) < d \<longrightarrow> norm(f y - f x - A *v (y - x)) \<le> e * norm(y - x))}"
lp15@67998
  1713
    let ?U = "S \<inter>
lp15@67998
  1714
              (\<Inter>e \<in> {e \<in> \<rat>. e > 0}.
lp15@67998
  1715
                \<Union>A \<in> {A. A$m$n < b \<and> (\<forall>i j. A$i$j \<in> \<rat>)}.
lp15@67998
  1716
                  \<Union>d \<in> {d \<in> \<rat>. 0 < d}.
lp15@67998
  1717
                     S \<inter> (\<Inter>y \<in> S. {x \<in> S. norm(y - x) < d \<longrightarrow> norm(f y - f x - A *v (y - x)) \<le> e * norm(y - x)}))"
lp15@67998
  1718
    have "?T = ?U"
lp15@67998
  1719
    proof (intro set_eqI iffI)
lp15@67998
  1720
      fix x
lp15@67998
  1721
      assume xT: "x \<in> ?T"
lp15@67998
  1722
      then show "x \<in> ?U"
lp15@67998
  1723
      proof (clarsimp simp add:)
lp15@67998
  1724
        fix q :: real
lp15@67998
  1725
        assume "q \<in> \<rat>" "q > 0"
lp15@67998
  1726
        then obtain d A where "d > 0" and A: "A $ m $ n < b" "\<And>i j. A $ i $ j \<in> \<rat>"
lp15@67998
  1727
          "\<And>y. \<lbrakk>y\<in>S;  norm (y - x) < d\<rbrakk> \<Longrightarrow> norm (f y - f x - A *v (y - x)) \<le> q * norm (y - x)"
lp15@67998
  1728
          using xT by auto
lp15@67998
  1729
        then obtain \<delta> where "d > \<delta>" "\<delta> > 0" "\<delta> \<in> \<rat>"
lp15@67998
  1730
          using Rats_dense_in_real by blast
lp15@67998
  1731
        with A show "\<exists>A. A $ m $ n < b \<and> (\<forall>i j. A $ i $ j \<in> \<rat>) \<and>
lp15@67998
  1732
                         (\<exists>s. s \<in> \<rat> \<and> 0 < s \<and> (\<forall>y\<in>S. norm (y - x) < s \<longrightarrow> norm (f y - f x - A *v (y - x)) \<le> q * norm (y - x)))"
lp15@67998
  1733
          by force
lp15@67998
  1734
      qed
lp15@67998
  1735
    next
lp15@67998
  1736
      fix x
lp15@67998
  1737
      assume xU: "x \<in> ?U"
lp15@67998
  1738
      then show "x \<in> ?T"
lp15@67998
  1739
      proof clarsimp
lp15@67998
  1740
        fix e :: "real"
lp15@67998
  1741
        assume "e > 0"
lp15@67998
  1742
        then obtain \<epsilon> where \<epsilon>: "e > \<epsilon>" "\<epsilon> > 0" "\<epsilon> \<in> \<rat>"
lp15@67998
  1743
          using Rats_dense_in_real by blast
lp15@67998
  1744
        with xU obtain A r where "x \<in> S" and Ar: "A $ m $ n < b" "\<forall>i j. A $ i $ j \<in> \<rat>" "r \<in> \<rat>" "r > 0"
lp15@67998
  1745
          and "\<forall>y\<in>S. norm (y - x) < r \<longrightarrow> norm (f y - f x - A *v (y - x)) \<le> \<epsilon> * norm (y - x)"
lp15@67998
  1746
          by (auto simp: split: if_split_asm)
lp15@67998
  1747
        then have "\<forall>y\<in>S. norm (y - x) < r \<longrightarrow> norm (f y - f x - A *v (y - x)) \<le> e * norm (y - x)"
lp15@67998
  1748
          by (meson \<open>e > \<epsilon>\<close> less_eq_real_def mult_right_mono norm_ge_zero order_trans)
lp15@67998
  1749
        then show "\<exists>d>0. \<exists>A. A $ m $ n < b \<and> (\<forall>i j. A $ i $ j \<in> \<rat>) \<and> (\<forall>y\<in>S. norm (y - x) < d \<longrightarrow> norm (f y - f x - A *v (y - x)) \<le> e * norm (y - x))"
lp15@67998
  1750
          using \<open>x \<in> S\<close> Ar by blast
lp15@67998
  1751
      qed
lp15@67998
  1752
    qed
lp15@67998
  1753
    moreover have "?U \<in> sets lebesgue"
lp15@67998
  1754
    proof -
lp15@67998
  1755
      have coQ: "countable {e \<in> \<rat>. 0 < e}"
lp15@67998
  1756
        using countable_Collect countable_rat by blast
lp15@67998
  1757
      have ne: "{e \<in> \<rat>. (0::real) < e} \<noteq> {}"
lp15@67998
  1758
        using zero_less_one Rats_1 by blast
lp15@67998
  1759
      have coA: "countable {A. A $ m $ n < b \<and> (\<forall>i j. A $ i $ j \<in> \<rat>)}"
lp15@67998
  1760
      proof (rule countable_subset)
lp15@67998
  1761
        show "countable {A. \<forall>i j. A $ i $ j \<in> \<rat>}"
lp15@67998
  1762
          using countable_vector [OF countable_vector, of "\<lambda>i j. \<rat>"] by (simp add: countable_rat)
lp15@67998
  1763
      qed blast
lp15@67998
  1764
      have *: "\<lbrakk>U \<noteq> {} \<Longrightarrow> closedin (subtopology euclidean S) (S \<inter> \<Inter> U)\<rbrakk>
lp15@67998
  1765
               \<Longrightarrow> closedin (subtopology euclidean S) (S \<inter> \<Inter> U)" for U
lp15@67998
  1766
        by fastforce
lp15@67998
  1767
      have eq: "{x::(real,'m)vec. P x \<and> (Q x \<longrightarrow> R x)} = {x. P x \<and> \<not> Q x} \<union> {x. P x \<and> R x}" for P Q R
lp15@67998
  1768
        by auto
lp15@67998
  1769
      have sets: "S \<inter> (\<Inter>y\<in>S. {x \<in> S. norm (y - x) < d \<longrightarrow> norm (f y - f x - A *v (y - x)) \<le> e * norm (y - x)})
lp15@67998
  1770
                  \<in> sets lebesgue" for e A d
lp15@67998
  1771
      proof -
lp15@67998
  1772
        have clo: "closedin (subtopology euclidean S)
lp15@67998
  1773
                     {x \<in> S. norm (y - x) < d \<longrightarrow> norm (f y - f x - A *v (y - x)) \<le> e * norm (y - x)}"
lp15@67998
  1774
          for y
lp15@67998
  1775
        proof -
lp15@67998
  1776
          have cont1: "continuous_on S (\<lambda>x. norm (y - x))"
lp15@67998
  1777
          and  cont2: "continuous_on S (\<lambda>x. e * norm (y - x) - norm (f y - f x - (A *v y - A *v x)))"
lp15@67998
  1778
            by (force intro: contf continuous_intros)+
lp15@67998
  1779
          have clo1: "closedin (subtopology euclidean S) {x \<in> S. d \<le> norm (y - x)}"
lp15@67998
  1780
            using continuous_closedin_preimage [OF cont1, of "{d..}"] by (simp add: vimage_def Int_def)
lp15@67998
  1781
          have clo2: "closedin (subtopology euclidean S)
lp15@67998
  1782
                       {x \<in> S. norm (f y - f x - (A *v y - A *v x)) \<le> e * norm (y - x)}"
lp15@67998
  1783
            using continuous_closedin_preimage [OF cont2, of "{0..}"] by (simp add: vimage_def Int_def)
lp15@67998
  1784
          show ?thesis
lp15@67998
  1785
            by (auto simp: eq not_less matrix_vector_mult_diff_distrib intro: clo1 clo2)
lp15@67998
  1786
        qed
lp15@67998
  1787
        show ?thesis
lp15@67998
  1788
          by (rule lebesgue_closedin [of S]) (force intro: * S clo)+
lp15@67998
  1789
      qed
lp15@67998
  1790
      show ?thesis
lp15@67998
  1791
        by (intro sets sets.Int S sets.countable_UN'' sets.countable_INT'' coQ coA) auto
lp15@67998
  1792
    qed
lp15@67998
  1793
    ultimately show "?T \<in> sets lebesgue"
lp15@67998
  1794
      by simp
lp15@67998
  1795
    let ?M = "(?T - {x \<in> S. matrix (f' x) $ m $ n \<le> b} \<union> ({x \<in> S. matrix (f' x) $ m $ n \<le> b} - ?T))"
lp15@67998
  1796
    let ?\<Theta> = "\<lambda>x v. \<forall>\<xi>>0. \<exists>e>0. \<forall>y \<in> S-{x}. norm (x - y) < e \<longrightarrow> \<bar>v \<bullet> (y - x)\<bar> < \<xi> * norm (x - y)"
lp15@67998
  1797
    have nN: "negligible {x \<in> S. \<exists>v\<noteq>0. ?\<Theta> x v}"
lp15@67998
  1798
      unfolding negligible_eq_zero_density
lp15@67998
  1799
    proof clarsimp
lp15@67998
  1800
      fix x v and r e :: "real"
lp15@67998
  1801
      assume "x \<in> S" "v \<noteq> 0" "r > 0" "e > 0"
lp15@67998
  1802
      and Theta [rule_format]: "?\<Theta> x v"
lp15@67998
  1803
      moreover have "(norm v * e / 2) / CARD('m) ^ CARD('m) > 0"
lp15@67998
  1804
        by (simp add: \<open>v \<noteq> 0\<close> \<open>e > 0\<close>)
lp15@67998
  1805
      ultimately obtain d where "d > 0"
lp15@67998
  1806
         and dless: "\<And>y. \<lbrakk>y \<in> S - {x}; norm (x - y) < d\<rbrakk> \<Longrightarrow>
lp15@67998
  1807
                        \<bar>v \<bullet> (y - x)\<bar> < ((norm v * e / 2) / CARD('m) ^ CARD('m)) * norm (x - y)"
lp15@67998
  1808
        by metis
lp15@67998
  1809
      let ?W = "ball x (min d r) \<inter> {y. \<bar>v \<bullet> (y - x)\<bar> < (norm v * e/2 * min d r) / CARD('m) ^ CARD('m)}"
lp15@67998
  1810
      have "open {x. \<bar>v \<bullet> (x - a)\<bar> < b}" for a b
lp15@67998
  1811
        by (intro open_Collect_less continuous_intros)
lp15@67998
  1812
      show "\<exists>d>0. d \<le> r \<and>
lp15@67998
  1813
            (\<exists>U. {x' \<in> S. \<exists>v\<noteq>0. ?\<Theta> x' v} \<inter> ball x d \<subseteq> U \<and>
lp15@67998
  1814
                 U \<in> lmeasurable \<and> measure lebesgue U < e * content (ball x d))"
lp15@67998
  1815
      proof (intro exI conjI)
lp15@67998
  1816
        show "0 < min d r" "min d r \<le> r"
lp15@67998
  1817
          using \<open>r > 0\<close> \<open>d > 0\<close> by auto
lp15@67998
  1818
        show "{x' \<in> S. \<exists>v. v \<noteq> 0 \<and> (\<forall>\<xi>>0. \<exists>e>0. \<forall>z\<in>S - {x'}. norm (x' - z) < e \<longrightarrow> \<bar>v \<bullet> (z - x')\<bar> < \<xi> * norm (x' - z))} \<inter> ball x (min d r) \<subseteq> ?W"
lp15@67998
  1819
          proof (clarsimp simp: dist_norm norm_minus_commute)
lp15@68001
  1820
            fix y w
lp15@67998
  1821
            assume "y \<in> S" "w \<noteq> 0"
lp15@67998
  1822
              and less [rule_format]:
lp15@67998
  1823
                    "\<forall>\<xi>>0. \<exists>e>0. \<forall>z\<in>S - {y}. norm (y - z) < e \<longrightarrow> \<bar>w \<bullet> (z - y)\<bar> < \<xi> * norm (y - z)"
lp15@67998
  1824
              and d: "norm (y - x) < d" and r: "norm (y - x) < r"
lp15@67998
  1825
            show "\<bar>v \<bullet> (y - x)\<bar> < norm v * e * min d r / (2 * real CARD('m) ^ CARD('m))"
lp15@67998
  1826
            proof (cases "y = x")
lp15@67998
  1827
              case True
lp15@67998
  1828
              with \<open>r > 0\<close> \<open>d > 0\<close> \<open>e > 0\<close> \<open>v \<noteq> 0\<close> show ?thesis
lp15@67998
  1829
                by simp
lp15@67998
  1830
            next
lp15@67998
  1831
              case False
lp15@67998
  1832
              have "\<bar>v \<bullet> (y - x)\<bar> < norm v * e / 2 / real (CARD('m) ^ CARD('m)) * norm (x - y)"
lp15@67998
  1833
                apply (rule dless)
lp15@67998
  1834
                using False \<open>y \<in> S\<close> d by (auto simp: norm_minus_commute)
lp15@67998
  1835
              also have "\<dots> \<le> norm v * e * min d r / (2 * real CARD('m) ^ CARD('m))"
lp15@67998
  1836
                using d r \<open>e > 0\<close> by (simp add: field_simps norm_minus_commute mult_left_mono)
lp15@67998
  1837
              finally show ?thesis .
lp15@67998
  1838
            qed
lp15@67998
  1839
          qed
lp15@67998
  1840
          show "?W \<in> lmeasurable"
lp15@67998
  1841
            by (simp add: fmeasurable_Int_fmeasurable borel_open)
lp15@67998
  1842
          obtain k::'m where True
lp15@67998
  1843
            by metis
lp15@67998
  1844
          obtain T where T: "orthogonal_transformation T" and v: "v = T(norm v *\<^sub>R axis k (1::real))"
lp15@67998
  1845
            using rotation_rightward_line by metis
lp15@67998
  1846
          define b where "b \<equiv> norm v"
lp15@67998
  1847
          have "b > 0"
lp15@67998
  1848
            using \<open>v \<noteq> 0\<close> by (auto simp: b_def)
lp15@67998
  1849
          obtain eqb: "inv T v = b *\<^sub>R axis k (1::real)" and "inj T" "bij T" and invT: "orthogonal_transformation (inv T)"
lp15@67998
  1850
            by (metis UNIV_I b_def  T v bij_betw_inv_into_left orthogonal_transformation_inj orthogonal_transformation_bij orthogonal_transformation_inv)
lp15@67998
  1851
          let ?v = "\<chi> i. min d r / CARD('m)"
lp15@67998
  1852
          let ?v' = "\<chi> i. if i = k then (e/2 * min d r) / CARD('m) ^ CARD('m) else min d r"
lp15@67998
  1853
          let ?x' = "inv T x"
lp15@67998
  1854
          let ?W' = "(ball ?x' (min d r) \<inter> {y. \<bar>(y - ?x')$k\<bar> < e * min d r / (2 * CARD('m) ^ CARD('m))})"
lp15@67998
  1855
          have abs: "x - e \<le> y \<and> y \<le> x + e \<longleftrightarrow> abs(y - x) \<le> e" for x y e::real
lp15@67998
  1856
            by auto
lp15@67998
  1857
          have "?W = T ` ?W'"
lp15@67998
  1858
          proof -
lp15@67998
  1859
            have 1: "T ` (ball (inv T x) (min d r)) = ball x (min d r)"
lp15@67998
  1860
              by (simp add: T image_orthogonal_transformation_ball orthogonal_transformation_surj surj_f_inv_f)
lp15@67998
  1861
            have 2: "{y. \<bar>v \<bullet> (y - x)\<bar> < b * e * min d r / (2 * real CARD('m) ^ CARD('m))} =
lp15@67998
  1862
                      T ` {y. \<bar>y $ k - ?x' $ k\<bar> < e * min d r / (2 * real CARD('m) ^ CARD('m))}"
lp15@67998
  1863
            proof -
lp15@67998
  1864
              have *: "\<bar>T (b *\<^sub>R axis k 1) \<bullet> (y - x)\<bar> = b * \<bar>inv T y $ k - ?x' $ k\<bar>" for y
lp15@67998
  1865
              proof -
lp15@67998
  1866
                have "\<bar>T (b *\<^sub>R axis k 1) \<bullet> (y - x)\<bar> = \<bar>(b *\<^sub>R axis k 1) \<bullet> inv T (y - x)\<bar>"
lp15@67998
  1867
                  by (metis (no_types, hide_lams) b_def eqb invT orthogonal_transformation_def v)
lp15@67998
  1868
                also have "\<dots> = b * \<bar>(axis k 1) \<bullet> inv T (y - x)\<bar>"
lp15@67998
  1869
                  using \<open>b > 0\<close> by (simp add: abs_mult)
lp15@67998
  1870
                also have "\<dots> = b * \<bar>inv T y $ k - ?x' $ k\<bar>"
lp15@67998
  1871
                  using orthogonal_transformation_linear [OF invT]
lp15@67998
  1872
                  by (simp add: inner_axis' linear_diff)
lp15@67998
  1873
                finally show ?thesis
lp15@67998
  1874
                  by simp
lp15@67998
  1875
              qed
lp15@67998
  1876
              show ?thesis
lp15@67998
  1877
                using v b_def [symmetric]
lp15@67998
  1878
                using \<open>b > 0\<close> by (simp add: * bij_image_Collect_eq [OF \<open>bij T\<close>] mult_less_cancel_left_pos times_divide_eq_right [symmetric] del: times_divide_eq_right)
lp15@67998
  1879
            qed
lp15@67998
  1880
            show ?thesis
lp15@67998
  1881
              using \<open>b > 0\<close> by (simp add: image_Int \<open>inj T\<close> 1 2 b_def [symmetric])
lp15@67998
  1882
          qed
lp15@67998
  1883
          moreover have "?W' \<in> lmeasurable"
lp15@67998
  1884
            by (auto intro: fmeasurable_Int_fmeasurable)
lp15@67998
  1885
          ultimately have "measure lebesgue ?W = measure lebesgue ?W'"
lp15@67998
  1886
            by (metis measure_orthogonal_image T)
lp15@67998
  1887
          also have "\<dots> \<le> measure lebesgue (cbox (?x' - ?v') (?x' + ?v'))"
lp15@67998
  1888
          proof (rule measure_mono_fmeasurable)
lp15@67998
  1889
            show "?W' \<subseteq> cbox (?x' - ?v') (?x' + ?v')"
lp15@67998
  1890
              apply (clarsimp simp add: mem_box_cart abs dist_norm norm_minus_commute simp del: min_less_iff_conj min.bounded_iff)
lp15@67998
  1891
              by (metis component_le_norm_cart less_eq_real_def le_less_trans vector_minus_component)
lp15@67998
  1892
          qed auto
lp15@67998
  1893
          also have "\<dots> \<le> e/2 * measure lebesgue (cbox (?x' - ?v) (?x' + ?v))"
lp15@67998
  1894
          proof -
lp15@67998
  1895
            have "cbox (?x' - ?v) (?x' + ?v) \<noteq> {}"
lp15@67998
  1896
              using \<open>r > 0\<close> \<open>d > 0\<close> by (auto simp: interval_eq_empty_cart divide_less_0_iff)
lp15@67998
  1897
            with \<open>r > 0\<close> \<open>d > 0\<close> \<open>e > 0\<close> show ?thesis
lp15@67998
  1898
              apply (simp add: content_cbox_if_cart mem_box_cart)
lp15@67998
  1899
              apply (auto simp: prod_nonneg)
lp15@67998
  1900
              apply (simp add: abs if_distrib prod.delta_remove prod_constant field_simps power_diff split: if_split_asm)
lp15@67998
  1901
              done
lp15@67998
  1902
          qed
lp15@67998
  1903
          also have "\<dots> \<le> e/2 * measure lebesgue (cball ?x' (min d r))"
lp15@67998
  1904
          proof (rule mult_left_mono [OF measure_mono_fmeasurable])
lp15@67998
  1905
            have *: "norm (?x' - y) \<le> min d r"
lp15@67998
  1906
              if y: "\<And>i. \<bar>?x' $ i - y $ i\<bar> \<le> min d r / real CARD('m)" for y
lp15@67998
  1907
            proof -
lp15@67998
  1908
              have "norm (?x' - y) \<le> (\<Sum>i\<in>UNIV. \<bar>(?x' - y) $ i\<bar>)"
lp15@67998
  1909
                by (rule norm_le_l1_cart)
lp15@67998
  1910
              also have "\<dots> \<le> real CARD('m) * (min d r / real CARD('m))"
lp15@67998
  1911
                by (rule sum_bounded_above) (use y in auto)
lp15@67998
  1912
              finally show ?thesis
lp15@67998
  1913
                by simp
lp15@67998
  1914
            qed
lp15@67998
  1915
            show "cbox (?x' - ?v) (?x' + ?v) \<subseteq> cball ?x' (min d r)"
lp15@67998
  1916
              apply (clarsimp simp only: mem_box_cart dist_norm mem_cball intro!: *)
lp15@67998
  1917
              by (simp add: abs_diff_le_iff abs_minus_commute)
lp15@67998
  1918
          qed (use \<open>e > 0\<close> in auto)
lp15@67998
  1919
          also have "\<dots> < e * content (cball ?x' (min d r))"
lp15@67998
  1920
            using \<open>r > 0\<close> \<open>d > 0\<close> \<open>e > 0\<close> by auto
lp15@67998
  1921
          also have "\<dots> = e * content (ball x (min d r))"
lp15@67998
  1922
            using \<open>r > 0\<close> \<open>d > 0\<close> by (simp add: content_cball content_ball)
lp15@67998
  1923
          finally show "measure lebesgue ?W < e * content (ball x (min d r))" .
lp15@67998
  1924
      qed
lp15@67998
  1925
    qed
lp15@67998
  1926
    have *: "(\<And>x. (x \<notin> S) \<Longrightarrow> (x \<in> T \<longleftrightarrow> x \<in> U)) \<Longrightarrow> (T - U) \<union> (U - T) \<subseteq> S" for S T U :: "(real,'m) vec set"
lp15@67998
  1927
      by blast
lp15@67998
  1928
    have MN: "?M \<subseteq> {x \<in> S. \<exists>v\<noteq>0. ?\<Theta> x v}"
lp15@67998
  1929
    proof (rule *)
lp15@67998
  1930
      fix x
lp15@67998
  1931
      assume x: "x \<notin> {x \<in> S. \<exists>v\<noteq>0. ?\<Theta> x v}"
lp15@67998
  1932
      show "(x \<in> ?T) \<longleftrightarrow> (x \<in> {x \<in> S. matrix (f' x) $ m $ n \<le> b})"
lp15@67998
  1933
      proof (cases "x \<in> S")
lp15@67998
  1934
        case True
lp15@67998
  1935
        then have x: "\<not> ?\<Theta> x v" if "v \<noteq> 0" for v
lp15@67998
  1936
          using x that by force
lp15@67998
  1937
        show ?thesis
lp15@67998
  1938
        proof (rule iffI; clarsimp)
lp15@67998
  1939
          assume b: "\<forall>e>0. \<exists>d>0. \<exists>A. A $ m $ n < b \<and> (\<forall>i j. A $ i $ j \<in> \<rat>) \<and>
lp15@67998
  1940
                                    (\<forall>y\<in>S. norm (y - x) < d \<longrightarrow> norm (f y - f x - A *v (y - x)) \<le> e * norm (y - x))"
lp15@67998
  1941
                     (is "\<forall>e>0. \<exists>d>0. \<exists>A. ?\<Phi> e d A")
lp15@67998
  1942
          then have "\<forall>k. \<exists>d>0. \<exists>A. ?\<Phi> (1 / Suc k) d A"
lp15@67998
  1943
            by (metis (no_types, hide_lams) less_Suc_eq_0_disj of_nat_0_less_iff zero_less_divide_1_iff)
lp15@67998
  1944
          then obtain \<delta> A where \<delta>: "\<And>k. \<delta> k > 0"
lp15@67998
  1945
                           and Ab: "\<And>k. A k $ m $ n < b"
lp15@67998
  1946
                           and A: "\<And>k y. \<lbrakk>y \<in> S; norm (y - x) < \<delta> k\<rbrakk> \<Longrightarrow>
lp15@67998
  1947
                                          norm (f y - f x - A k *v (y - x)) \<le> 1/(Suc k) * norm (y - x)"
lp15@67998
  1948
            by metis
lp15@67998
  1949
          have "\<forall>i j. \<exists>a. (\<lambda>n. A n $ i $ j) \<longlonglongrightarrow> a"
lp15@67998
  1950
          proof (intro allI)
lp15@67998
  1951
            fix i j
lp15@67998
  1952
            have vax: "(A n *v axis j 1) $ i = A n $ i $ j" for n
lp15@67998
  1953
              by (metis cart_eq_inner_axis matrix_vector_mul_component)
lp15@67998
  1954
            let ?CA = "{x. Cauchy (\<lambda>n. (A n) *v x)}"
lp15@67998
  1955
            have "subspace ?CA"
lp15@67998
  1956
              unfolding subspace_def convergent_eq_Cauchy [symmetric]
lp15@67998
  1957
                by (force simp: algebra_simps intro: tendsto_intros)
lp15@67998
  1958
            then have CA_eq: "?CA = span ?CA"
lp15@67998
  1959
              by (metis span_eq)
lp15@67998
  1960
            also have "\<dots> = UNIV"
lp15@67998
  1961
            proof -
lp15@67998
  1962
              have "dim ?CA \<le> CARD('m)"
lp15@67998
  1963
                by (rule dim_subset_UNIV_cart)
lp15@67998
  1964
              moreover have "False" if less: "dim ?CA < CARD('m)"
lp15@67998
  1965
              proof -
lp15@67998
  1966
                obtain d where "d \<noteq> 0" and d: "\<And>y. y \<in> span ?CA \<Longrightarrow> orthogonal d y"
lp15@67998
  1967
                  using less by (force intro: orthogonal_to_subspace_exists [of ?CA])
lp15@67998
  1968
                with x [OF \<open>d \<noteq> 0\<close>] obtain \<xi> where "\<xi> > 0"
lp15@67998
  1969
                  and \<xi>: "\<And>e. e > 0 \<Longrightarrow> \<exists>y \<in> S - {x}. norm (x - y) < e \<and> \<xi> * norm (x - y) \<le> \<bar>d \<bullet> (y - x)\<bar>"
lp15@67998
  1970
                  by (fastforce simp: not_le Bex_def)
lp15@67998
  1971
                obtain \<gamma> z where \<gamma>Sx: "\<And>i. \<gamma> i \<in> S - {x}"
lp15@67998
  1972
                           and \<gamma>le:   "\<And>i. \<xi> * norm(\<gamma> i - x) \<le> \<bar>d \<bullet> (\<gamma> i - x)\<bar>"
lp15@67998
  1973
                           and \<gamma>x:    "\<gamma> \<longlonglongrightarrow> x"
lp15@67998
  1974
                           and z:     "(\<lambda>n. (\<gamma> n - x) /\<^sub>R norm (\<gamma> n - x)) \<longlonglongrightarrow> z"
lp15@67998
  1975
                proof -
lp15@67998
  1976
                  have "\<exists>\<gamma>. (\<forall>i. (\<gamma> i \<in> S - {x} \<and>
lp15@67998
  1977
                                  \<xi> * norm(\<gamma> i - x) \<le> \<bar>d \<bullet> (\<gamma> i - x)\<bar> \<and> norm(\<gamma> i - x) < 1/Suc i) \<and>
lp15@67998
  1978
                                 norm(\<gamma>(Suc i) - x) < norm(\<gamma> i - x))"
lp15@67998
  1979
                  proof (rule dependent_nat_choice)
lp15@67998
  1980
                    show "\<exists>y. y \<in> S - {x} \<and> \<xi> * norm (y - x) \<le> \<bar>d \<bullet> (y - x)\<bar> \<and> norm (y - x) < 1 / Suc 0"
lp15@67998
  1981
                      using \<xi> [of 1] by (auto simp: dist_norm norm_minus_commute)
lp15@67998
  1982
                  next
lp15@67998
  1983
                    fix y i
lp15@67998
  1984
                    assume "y \<in> S - {x} \<and> \<xi> * norm (y - x) \<le> \<bar>d \<bullet> (y - x)\<bar> \<and> norm (y - x) < 1/Suc i"
lp15@67998
  1985
                    then have "min (norm(y - x)) (1/((Suc i) + 1)) > 0"
lp15@67998
  1986
                      by auto
lp15@67998
  1987
                    then obtain y' where "y' \<in> S - {x}" and y': "norm (x - y') < min (norm (y - x)) (1/((Suc i) + 1))"
lp15@67998
  1988
                                         "\<xi> * norm (x - y') \<le> \<bar>d \<bullet> (y' - x)\<bar>"
lp15@67998
  1989
                      using \<xi> by metis
lp15@67998
  1990
                    with \<xi> show "\<exists>y'. (y' \<in> S - {x} \<and> \<xi> * norm (y' - x) \<le> \<bar>d \<bullet> (y' - x)\<bar> \<and>
lp15@67998
  1991
                              norm (y' - x) < 1/(Suc (Suc i))) \<and> norm (y' - x) < norm (y - x)"
lp15@67998
  1992
                      by (auto simp: dist_norm norm_minus_commute)
lp15@67998
  1993
                  qed
lp15@67998
  1994
                  then obtain \<gamma> where
lp15@67998
  1995
                        \<gamma>Sx: "\<And>i. \<gamma> i \<in> S - {x}"
lp15@67998
  1996
                        and \<gamma>le: "\<And>i. \<xi> * norm(\<gamma> i - x) \<le> \<bar>d \<bullet> (\<gamma> i - x)\<bar>"
lp15@67998
  1997
                        and \<gamma>conv: "\<And>i. norm(\<gamma> i - x) < 1/(Suc i)"
lp15@67998
  1998
                    by blast
lp15@67998
  1999
                  let ?f = "\<lambda>i. (\<gamma> i - x) /\<^sub>R norm (\<gamma> i - x)"
lp15@67998
  2000
                  have "?f i \<in> sphere 0 1" for i
lp15@67998
  2001
                    using \<gamma>Sx by auto
lp15@67998
  2002
                  then obtain l \<rho> where "l \<in> sphere 0 1" "strict_mono \<rho>" and l: "(?f \<circ> \<rho>) \<longlonglongrightarrow> l"
lp15@67998
  2003
                    using compact_sphere [of "0::(real,'m) vec" 1]  unfolding compact_def by meson
lp15@67998
  2004
                  show thesis
lp15@67998
  2005
                  proof
lp15@67998
  2006
                    show "(\<gamma> \<circ> \<rho>) i \<in> S - {x}" "\<xi> * norm ((\<gamma> \<circ> \<rho>) i - x) \<le> \<bar>d \<bullet> ((\<gamma> \<circ> \<rho>) i - x)\<bar>" for i
lp15@67998
  2007
                      using \<gamma>Sx \<gamma>le by auto
lp15@67998
  2008
                    have "\<gamma> \<longlonglongrightarrow> x"
lp15@67998
  2009
                    proof (clarsimp simp add: LIMSEQ_def dist_norm)
lp15@67998
  2010
                      fix r :: "real"
lp15@67998
  2011
                      assume "r > 0"
lp15@67998
  2012
                      with real_arch_invD obtain no where "no \<noteq> 0" "real no > 1/r"
lp15@67998
  2013
                        by (metis divide_less_0_1_iff not_less_iff_gr_or_eq of_nat_0_eq_iff reals_Archimedean2)
lp15@67998
  2014
                      with \<gamma>conv show "\<exists>no. \<forall>n\<ge>no. norm (\<gamma> n - x) < r"
lp15@67998
  2015
                        by (metis \<open>r > 0\<close> add.commute divide_inverse inverse_inverse_eq inverse_less_imp_less less_trans mult.left_neutral nat_le_real_less of_nat_Suc)
lp15@67998
  2016
                    qed
lp15@67998
  2017
                    with \<open>strict_mono \<rho>\<close> show "(\<gamma> \<circ> \<rho>) \<longlonglongrightarrow> x"
lp15@67998
  2018
                      by (metis LIMSEQ_subseq_LIMSEQ)
lp15@67998
  2019
                    show "(\<lambda>n. ((\<gamma> \<circ> \<rho>) n - x) /\<^sub>R norm ((\<gamma> \<circ> \<rho>) n - x)) \<longlonglongrightarrow> l"
lp15@67998
  2020
                      using l by (auto simp: o_def)
lp15@67998
  2021
                  qed
lp15@67998
  2022
                qed
lp15@67998
  2023
                have "isCont (\<lambda>x. (\<bar>d \<bullet> x\<bar> - \<xi>)) z"
lp15@67998
  2024
                  by (intro continuous_intros)
lp15@67998
  2025
                from isCont_tendsto_compose [OF this z]
lp15@67998
  2026
                have lim: "(\<lambda>y. \<bar>d \<bullet> ((\<gamma> y - x) /\<^sub>R norm (\<gamma> y - x))\<bar> - \<xi>) \<longlonglongrightarrow> \<bar>d \<bullet> z\<bar> - \<xi>"
lp15@67998
  2027
                  by auto
lp15@67998
  2028
                moreover have "\<forall>\<^sub>F i in sequentially. 0 \<le> \<bar>d \<bullet> ((\<gamma> i - x) /\<^sub>R norm (\<gamma> i - x))\<bar> - \<xi>"
lp15@67998
  2029
                proof (rule eventuallyI)
lp15@67998
  2030
                  fix n
lp15@67998
  2031
                  show "0 \<le> \<bar>d \<bullet> ((\<gamma> n - x) /\<^sub>R norm (\<gamma> n - x))\<bar> - \<xi>"
lp15@67998
  2032
                  using \<gamma>le [of n] \<gamma>Sx by (auto simp: abs_mult divide_simps)
lp15@67998
  2033
                qed
lp15@67998
  2034
                ultimately have "\<xi> \<le> \<bar>d \<bullet> z\<bar>"
lp15@67998
  2035
                  using tendsto_lowerbound [where a=0] by fastforce
lp15@67998
  2036
                have "Cauchy (\<lambda>n. (A n) *v z)"
lp15@67998
  2037
                proof (clarsimp simp add: Cauchy_def)
lp15@67998
  2038
                  fix \<epsilon> :: "real"
lp15@67998
  2039
                  assume "0 < \<epsilon>"
lp15@67998
  2040
                  then obtain N::nat where "N > 0" and N: "\<epsilon>/2 > 1/N"
lp15@67998
  2041
                    by (metis half_gt_zero inverse_eq_divide neq0_conv real_arch_inverse)
lp15@67998
  2042
                  show "\<exists>M. \<forall>m\<ge>M. \<forall>n\<ge>M. dist (A m *v z) (A n *v z) < \<epsilon>"
lp15@67998
  2043
                  proof (intro exI allI impI)
lp15@67998
  2044
                    fix i j
lp15@67998
  2045
                    assume ij: "N \<le> i" "N \<le> j"
lp15@67998
  2046
                    let ?V = "\<lambda>i k. A i *v ((\<gamma> k - x) /\<^sub>R norm (\<gamma> k - x))"
lp15@67998
  2047
                    have "\<forall>\<^sub>F k in sequentially. dist (\<gamma> k) x < min (\<delta> i) (\<delta> j)"
lp15@67998
  2048
                      using \<gamma>x [unfolded tendsto_iff] by (meson min_less_iff_conj \<delta>)
lp15@67998
  2049
                    then have even: "\<forall>\<^sub>F k in sequentially. norm (?V i k - ?V j k) - 2 / N \<le> 0"
lp15@67998
  2050
                    proof (rule eventually_mono, clarsimp)
lp15@67998
  2051
                      fix p
lp15@67998
  2052
                      assume p: "dist (\<gamma> p) x < \<delta> i" "dist (\<gamma> p) x < \<delta> j"
lp15@67998
  2053
                      let ?C = "\<lambda>k. f (\<gamma> p) - f x - A k *v (\<gamma> p - x)"
lp15@67998
  2054
                      have "norm ((A i - A j) *v (\<gamma> p - x)) = norm (?C j - ?C i)"
lp15@67998
  2055
                        by (simp add: algebra_simps)
lp15@67998
  2056
                      also have "\<dots> \<le> norm (?C j) + norm (?C i)"
lp15@67998
  2057
                        using norm_triangle_ineq4 by blast
lp15@67998
  2058
                      also have "\<dots> \<le> 1/(Suc j) * norm (\<gamma> p - x) + 1/(Suc i) * norm (\<gamma> p - x)"
lp15@67998
  2059
                        by (metis A Diff_iff \<gamma>Sx dist_norm p add_mono)
lp15@67998
  2060
                      also have "\<dots> \<le> 1/N * norm (\<gamma> p - x) + 1/N * norm (\<gamma> p - x)"
lp15@67998
  2061
                        apply (intro add_mono mult_right_mono)
lp15@67998
  2062
                        using ij \<open>N > 0\<close> by (auto simp: field_simps)
lp15@67998
  2063
                      also have "\<dots> = 2 / N * norm (\<gamma> p - x)"
lp15@67998
  2064
                        by simp
lp15@67998
  2065
                      finally have no_le: "norm ((A i - A j) *v (\<gamma> p - x)) \<le> 2 / N * norm (\<gamma> p - x)" .
lp15@67998
  2066
                      have "norm (?V i p - ?V j p) =
lp15@67998
  2067
                            norm ((A i - A j) *v ((\<gamma> p - x) /\<^sub>R norm (\<gamma> p - x)))"
lp15@67998
  2068
                        by (simp add: algebra_simps)
lp15@67998
  2069
                      also have "\<dots> = norm ((A i - A j) *v (\<gamma> p - x)) / norm (\<gamma> p - x)"
lp15@67998
  2070
                        by (simp add: divide_inverse matrix_vector_mult_scaleR)
lp15@67998
  2071
                      also have "\<dots> \<le> 2 / N"
lp15@67998
  2072
                        using no_le by (auto simp: divide_simps)
lp15@67998
  2073
                      finally show "norm (?V i p - ?V j p) \<le> 2 / N" .
lp15@67998
  2074
                    qed
lp15@67998
  2075
                    have "isCont (\<lambda>w. (norm(A i *v w - A j *v w) - 2 / N)) z"
lp15@67998
  2076
                      by (intro continuous_intros)
lp15@67998
  2077
                    from isCont_tendsto_compose [OF this z]
lp15@67998
  2078
                    have lim: "(\<lambda>w. norm (A i *v ((\<gamma> w - x) /\<^sub>R norm (\<gamma> w - x)) -
lp15@67998
  2079
                                    A j *v ((\<gamma> w - x) /\<^sub>R norm (\<gamma> w - x))) - 2 / N)
lp15@67998
  2080
                               \<longlonglongrightarrow> norm (A i *v z - A j *v z) - 2 / N"
lp15@67998
  2081
                      by auto
lp15@67998
  2082
                    have "dist (A i *v z) (A j *v z) \<le> 2 / N"
lp15@67998
  2083
                      using tendsto_upperbound [OF lim even] by (auto simp: dist_norm)
lp15@67998
  2084
                    with N show "dist (A i *v z) (A j *v z) < \<epsilon>"
lp15@67998
  2085
                      by linarith
lp15@67998
  2086
                  qed
lp15@67998
  2087
                qed
lp15@67998
  2088
                then have "d \<bullet> z = 0"
lp15@67998
  2089
                  using CA_eq d orthogonal_def by auto
lp15@67998
  2090
                then show False
lp15@67998
  2091
                  using \<open>0 < \<xi>\<close> \<open>\<xi> \<le> \<bar>d \<bullet> z\<bar>\<close> by auto
lp15@67998
  2092
              qed
lp15@67998
  2093
              ultimately show ?thesis
lp15@67998
  2094
                using dim_eq_full by fastforce
lp15@67998
  2095
            qed
lp15@67998
  2096
            finally have "?CA = UNIV" .
lp15@67998
  2097
            then have "Cauchy (\<lambda>n. (A n) *v axis j 1)"
lp15@67998
  2098
              by auto
lp15@67998
  2099
            then obtain L where "(\<lambda>n. A n *v axis j 1) \<longlonglongrightarrow> L"
lp15@67998
  2100
              by (auto simp: Cauchy_convergent_iff convergent_def)
lp15@67998
  2101
            then have "(\<lambda>x. (A x *v axis j 1) $ i) \<longlonglongrightarrow> L $ i"
lp15@67998
  2102
              by (rule tendsto_vec_nth)
lp15@67998
  2103
            then show "\<exists>a. (\<lambda>n. A n $ i $ j) \<longlonglongrightarrow> a"
lp15@67998
  2104
              by (force simp: vax)
lp15@67998
  2105
          qed
lp15@67998
  2106
          then obtain B where B: "\<And>i j. (\<lambda>n. A n $ i $ j) \<longlonglongrightarrow> B $ i $ j"
lp15@67998
  2107
            by (auto simp: lambda_skolem)
lp15@67998
  2108
          have lin_df: "linear (f' x)"
lp15@67998
  2109
               and lim_df: "((\<lambda>y. (1 / norm (y - x)) *\<^sub>R (f y - (f x + f' x (y - x)))) \<longlongrightarrow> 0) (at x within S)"
lp15@67998
  2110
            using \<open>x \<in> S\<close> assms by (auto simp: has_derivative_within linear_linear)
lp15@67998
  2111
          moreover have "(matrix (f' x) - B) *v w = 0" for w
lp15@67998
  2112
          proof (rule lemma_partial_derivatives [of "( *v) (matrix (f' x) - B)"])
lp15@67998
  2113
            show "linear (( *v) (matrix (f' x) - B))"
lp15@67998
  2114
              by (rule matrix_vector_mul_linear)
lp15@67998
  2115
            have "((\<lambda>y. ((f x + f' x (y - x)) - f y) /\<^sub>R norm (y - x)) \<longlongrightarrow> 0) (at x within S)"
lp15@67998
  2116
              using tendsto_minus [OF lim_df] by (simp add: algebra_simps divide_simps)
lp15@67998
  2117
            then show "((\<lambda>y. (matrix (f' x) - B) *v (y - x) /\<^sub>R norm (y - x)) \<longlongrightarrow> 0) (at x within S)"
lp15@67998
  2118
            proof (rule Lim_transform)
lp15@67998
  2119
              have "((\<lambda>y. ((f y + B *v x - (f x + B *v y)) /\<^sub>R norm (y - x))) \<longlongrightarrow> 0) (at x within S)"
lp15@67998
  2120
              proof (clarsimp simp add: Lim_within dist_norm)
lp15@67998
  2121
                fix e :: "real"
lp15@67998
  2122
                assume "e > 0"
lp15@67998
  2123
                then obtain q::nat where "q \<noteq> 0" and qe2: "1/q < e/2"
lp15@67998
  2124
                  by (metis divide_pos_pos inverse_eq_divide real_arch_inverse zero_less_numeral)
lp15@67998
  2125
                let ?g = "\<lambda>p. sum  (\<lambda>i. sum (\<lambda>j. abs((A p - B)$i$j)) UNIV) UNIV"
lp15@67998
  2126
                have "(\<lambda>k. onorm (\<lambda>y. (A k - B) *v y)) \<longlonglongrightarrow> 0"
lp15@67998
  2127
                proof (rule Lim_null_comparison)
lp15@67998
  2128
                  show "\<forall>\<^sub>F k in sequentially. norm (onorm (\<lambda>y. (A k - B) *v y)) \<le> ?g k"
lp15@67998
  2129
                  proof (rule eventually_sequentiallyI)
lp15@67998
  2130
                    fix k :: "nat"
lp15@67998
  2131
                    assume "0 \<le> k"
lp15@67998
  2132
                    have "0 \<le> onorm (( *v) (A k - B))"
lp15@67998
  2133
                      by (simp add: linear_linear onorm_pos_le matrix_vector_mul_linear)
lp15@67998
  2134
                    then show "norm (onorm (( *v) (A k - B))) \<le> (\<Sum>i\<in>UNIV. \<Sum>j\<in>UNIV. \<bar>(A k - B) $ i $ j\<bar>)"
lp15@67998
  2135
                      by (simp add: onorm_le_matrix_component_sum del: vector_minus_component)
lp15@67998
  2136
                  qed
lp15@67998
  2137
                next
lp15@67998
  2138
                  show "?g \<longlonglongrightarrow> 0"
lp15@67998
  2139
                    using B Lim_null tendsto_rabs_zero_iff by (fastforce intro!: tendsto_null_sum)
lp15@67998
  2140
                qed
lp15@67998
  2141
                with \<open>e > 0\<close> obtain p where "\<And>n. n \<ge> p \<Longrightarrow> \<bar>onorm (( *v) (A n - B))\<bar> < e/2"
lp15@67998
  2142
                  unfolding lim_sequentially by (metis diff_zero dist_real_def divide_pos_pos zero_less_numeral)
lp15@67998
  2143
                then have pqe2: "\<bar>onorm (( *v) (A (p + q) - B))\<bar> < e/2" (*17 [`abs (onorm (\y. A (p + q) ** y - B ** y)) < e / &2`]*)
lp15@67998
  2144
                  using le_add1 by blast
lp15@67998
  2145
                show "\<exists>d>0. \<forall>y\<in>S. y \<noteq> x \<and> norm (y - x) < d \<longrightarrow>
lp15@67998
  2146
                           inverse (norm (y - x)) * norm (f y + B *v x - (f x + B *v y)) < e"
lp15@67998
  2147
                proof (intro exI, safe)
lp15@67998
  2148
                  show "0 < \<delta>(p + q)"
lp15@67998
  2149
                    by (simp add: \<delta>)
lp15@67998
  2150
                next
lp15@67998
  2151
                  fix y
lp15@67998
  2152
                  assume y: "y \<in> S" "norm (y - x) < \<delta>(p + q)" and "y \<noteq> x"
lp15@67998
  2153
                  have *: "\<lbrakk>norm(b - c) < e - d; norm(y - x - b) \<le> d\<rbrakk> \<Longrightarrow> norm(y - x - c) < e"
lp15@67998
  2154
                    for b c d e x and y:: "real^'n"
lp15@67998
  2155
                    using norm_triangle_ineq2 [of "y - x - c" "y - x - b"] by simp
lp15@67998
  2156
                  have "norm (f y - f x - B *v (y - x)) < e * norm (y - x)"
lp15@67998
  2157
                  proof (rule *)
lp15@67998
  2158
                    show "norm (f y - f x - A (p + q) *v (y - x)) \<le> norm (y - x) / (Suc (p + q))"
lp15@67998
  2159
                      using A [OF y] by simp
lp15@67998
  2160
                    have "norm (A (p + q) *v (y - x) - B *v (y - x)) \<le> onorm(\<lambda>x. (A(p + q) - B) *v x) * norm(y - x)"
lp15@67998
  2161
                      by (metis linear_linear matrix_vector_mul_linear matrix_vector_mult_diff_rdistrib onorm)
lp15@67998
  2162
                    also have "\<dots> < (e/2) * norm (y - x)"
lp15@67998
  2163
                      using \<open>y \<noteq> x\<close> pqe2 by auto
lp15@67998
  2164
                    also have "\<dots> \<le> (e - 1 / (Suc (p + q))) * norm (y - x)"
lp15@67998
  2165
                    proof (rule mult_right_mono)
lp15@67998
  2166
                      have "1 / Suc (p + q) \<le> 1 / q"
lp15@67998
  2167
                        using \<open>q \<noteq> 0\<close> by (auto simp: divide_simps)
lp15@67998
  2168
                      also have "\<dots> < e/2"
lp15@67998
  2169
                        using qe2 by auto
lp15@67998
  2170
                      finally show "e / 2 \<le> e - 1 / real (Suc (p + q))"
lp15@67998
  2171
                        by linarith
lp15@67998
  2172
                    qed auto
lp15@67998
  2173
                    finally show "norm (A (p + q) *v (y - x) - B *v (y - x)) < e * norm (y - x) - norm (y - x) / real (Suc (p + q))"
lp15@67998
  2174
                      by (simp add: algebra_simps)
lp15@67998
  2175
                  qed
lp15@67998
  2176
                  then show "inverse (norm (y - x)) * norm (f y + B *v x - (f x + B *v y)) < e"
lp15@67998
  2177
                    using \<open>y \<noteq> x\<close> by (simp add: divide_simps algebra_simps)
lp15@67998
  2178
                qed
lp15@67998
  2179
              qed
lp15@67998
  2180
              then show "((\<lambda>y. (matrix (f' x) - B) *v (y - x) /\<^sub>R
lp15@67998
  2181
                           norm (y - x) - (f x + f' x (y - x) - f y) /\<^sub>R norm (y - x)) \<longlongrightarrow> 0)
lp15@67998
  2182
                          (at x within S)"
lp15@67998
  2183
                by (simp add: algebra_simps lin_df linear_diff matrix_vector_mul_linear)
lp15@67998
  2184
            qed
lp15@67998
  2185
          qed (use x in \<open>simp; auto simp: not_less\<close>)
lp15@67998
  2186
          ultimately have "f' x = ( *v) B"
lp15@67998
  2187
            by (force simp: algebra_simps)
lp15@67998
  2188
          show "matrix (f' x) $ m $ n \<le> b"
lp15@67998
  2189
          proof (rule tendsto_upperbound [of "\<lambda>i. (A i $ m $ n)" _ sequentially])
lp15@67998
  2190
            show "(\<lambda>i. A i $ m $ n) \<longlonglongrightarrow> matrix (f' x) $ m $ n"
lp15@67998
  2191
              by (simp add: B \<open>f' x = ( *v) B\<close>)
lp15@67998
  2192
            show "\<forall>\<^sub>F i in sequentially. A i $ m $ n \<le> b"
lp15@67998
  2193
              by (simp add: Ab less_eq_real_def)
lp15@67998
  2194
          qed auto
lp15@67998
  2195
        next
lp15@67998
  2196
          fix e :: "real"
lp15@67998
  2197
          assume "x \<in> S" and b: "matrix (f' x) $ m $ n \<le> b" and "e > 0"
lp15@67998
  2198
          then obtain d where "d>0"
lp15@67998
  2199
            and d: "\<And>y. y\<in>S \<Longrightarrow> 0 < dist y x \<and> dist y x < d \<longrightarrow> norm (f y - f x - f' x (y - x)) / (norm (y - x))
lp15@67998
  2200
                  < e/2"
lp15@67998
  2201
            using f [OF \<open>x \<in> S\<close>] unfolding Deriv.has_derivative_at_within Lim_within
lp15@67998
  2202
            by (auto simp: field_simps dest: spec [of _ "e/2"])
lp15@67998
  2203
          let ?A = "matrix(f' x) - (\<chi> i j. if i = m \<and> j = n then e / 4 else 0)"
lp15@67998
  2204
          obtain B where BRats: "\<And>i j. B$i$j \<in> \<rat>" and Bo_e6: "onorm(( *v) (?A - B)) < e/6"
lp15@67998
  2205
            using matrix_rational_approximation \<open>e > 0\<close>
lp15@67998
  2206
            by (metis zero_less_divide_iff zero_less_numeral)
lp15@67998
  2207
          show "\<exists>d>0. \<exists>A. A $ m $ n < b \<and> (\<forall>i j. A $ i $ j \<in> \<rat>) \<and>
lp15@67998
  2208
                (\<forall>y\<in>S. norm (y - x) < d \<longrightarrow> norm (f y - f x - A *v (y - x)) \<le> e * norm (y - x))"
lp15@67998
  2209
          proof (intro exI conjI ballI allI impI)
lp15@67998
  2210
            show "d>0"
lp15@67998
  2211
              by (rule \<open>d>0\<close>)
lp15@67998
  2212
            show "B $ m $ n < b"
lp15@67998
  2213
            proof -
lp15@67998
  2214
              have "\<bar>matrix (( *v) (?A - B)) $ m $ n\<bar> \<le> onorm (( *v) (?A - B))"
lp15@67998
  2215
                using component_le_onorm [OF matrix_vector_mul_linear, of _ m n] by metis
lp15@67998
  2216
              then show ?thesis
lp15@67998
  2217
                using b Bo_e6 by simp
lp15@67998
  2218
            qed
lp15@67998
  2219
            show "B $ i $ j \<in> \<rat>" for i j
lp15@67998
  2220
              using BRats by auto
lp15@67998
  2221
            show "norm (f y - f x - B *v (y - x)) \<le> e * norm (y - x)"
lp15@67998
  2222
              if "y \<in> S" and y: "norm (y - x) < d" for y
lp15@67998
  2223
            proof (cases "y = x")
lp15@67998
  2224
              case True then show ?thesis
lp15@67998
  2225
                by simp
lp15@67998
  2226
            next
lp15@67998
  2227
              case False
lp15@67998
  2228
              have *: "norm(d' - d) \<le> e/2 \<Longrightarrow> norm(y - (x + d')) < e/2 \<Longrightarrow> norm(y - x - d) \<le> e" for d d' e and x y::"real^'n"
lp15@67998
  2229
                using norm_triangle_le [of "d' - d" "y - (x + d')"] by simp
lp15@67998
  2230
              show ?thesis
lp15@67998
  2231
              proof (rule *)
lp15@67998
  2232
                have split246: "\<lbrakk>norm y \<le> e / 6; norm(x - y) \<le> e / 4\<rbrakk> \<Longrightarrow> norm x \<le> e/2" if "e > 0" for e and x y :: "real^'n"
lp15@67998
  2233
                  using norm_triangle_le [of y "x-y" "e/2"] \<open>e > 0\<close> by simp
lp15@67998
  2234
                have "linear (f' x)"
lp15@67998
  2235
                  using True f has_derivative_linear by blast
lp15@67998
  2236
                then have "norm (f' x (y - x) - B *v (y - x)) = norm ((matrix (f' x) - B) *v (y - x))"
lp15@67998
  2237
                  by (metis matrix_vector_mul matrix_vector_mult_diff_rdistrib)
lp15@67998
  2238
                also have "\<dots> \<le> (e * norm (y - x)) / 2"
lp15@67998
  2239
                proof (rule split246)
lp15@67998
  2240
                  have "norm ((?A - B) *v (y - x)) / norm (y - x) \<le> onorm(\<lambda>x. (?A - B) *v x)"
lp15@67998
  2241
                    by (simp add: le_onorm linear_linear matrix_vector_mul_linear)
lp15@67998
  2242
                  also have  "\<dots> < e/6"
lp15@67998
  2243
                    by (rule Bo_e6)
lp15@67998
  2244
                  finally have "norm ((?A - B) *v (y - x)) / norm (y - x) < e / 6" .
lp15@67998
  2245
                  then show "norm ((?A - B) *v (y - x)) \<le> e * norm (y - x) / 6"
lp15@67998
  2246
                    by (simp add: divide_simps False)
lp15@67998
  2247
                  have "norm ((matrix (f' x) - B) *v (y - x) - ((?A - B) *v (y - x))) = norm ((\<chi> i j. if i = m \<and> j = n then e / 4 else 0) *v (y - x))"
lp15@67998
  2248
                    by (simp add: algebra_simps)
lp15@67998
  2249
                  also have "\<dots> = norm((e/4) *\<^sub>R (y - x)$n *\<^sub>R axis m (1::real))"
lp15@67998
  2250
                  proof -
lp15@67998
  2251
                    have "(\<Sum>j\<in>UNIV. (if i = m \<and> j = n then e / 4 else 0) * (y $ j - x $ j)) * 4 = e * (y $ n - x $ n) * axis m 1 $ i" for i
lp15@67998
  2252
                    proof (cases "i=m")
lp15@67998
  2253
                      case True then show ?thesis
lp15@67998
  2254
                        by (auto simp: if_distrib [of "\<lambda>z. z * _"] cong: if_cong)
lp15@67998
  2255
                    next
lp15@67998
  2256
                      case False then show ?thesis
lp15@67998
  2257
                        by (simp add: axis_def)
lp15@67998
  2258
                    qed
lp15@67998
  2259
                    then have "(\<chi> i j. if i = m \<and> j = n then e / 4 else 0) *v (y - x) = (e/4) *\<^sub>R (y - x)$n *\<^sub>R axis m (1::real)"
lp15@67998
  2260
                      by (auto simp: vec_eq_iff matrix_vector_mult_def)
lp15@67998
  2261
                    then show ?thesis
lp15@67998
  2262
                      by metis
lp15@67998
  2263
                  qed
lp15@67998
  2264
                  also have "\<dots> \<le> e * norm (y - x) / 4"
lp15@67998
  2265
                    using \<open>e > 0\<close> apply (simp add: norm_mult abs_mult)
lp15@67998
  2266
                    by (metis component_le_norm_cart vector_minus_component)
lp15@67998
  2267
                  finally show "norm ((matrix (f' x) - B) *v (y - x) - ((?A - B) *v (y - x))) \<le> e * norm (y - x) / 4" .
lp15@67998
  2268
                  show "0 < e * norm (y - x)"
lp15@67998
  2269
                    by (simp add: False \<open>e > 0\<close>)
lp15@67998
  2270
                qed
lp15@67998
  2271
                finally show "norm (f' x (y - x) - B *v (y - x)) \<le> (e * norm (y - x)) / 2" .
lp15@67998
  2272
                show "norm (f y - (f x + f' x (y - x))) < (e * norm (y - x)) / 2"
lp15@67998
  2273
                  using False d [OF \<open>y \<in> S\<close>] y by (simp add: dist_norm field_simps)
lp15@67998
  2274
              qed
lp15@67998
  2275
            qed
lp15@67998
  2276
          qed
lp15@67998
  2277
        qed
lp15@67998
  2278
      qed auto
lp15@67998
  2279
    qed
lp15@67998
  2280
    show "negligible ?M"
lp15@67998
  2281
      using negligible_subset [OF nN MN] .
lp15@67998
  2282
  qed
lp15@67998
  2283
  then show ?thesis
lp15@67998
  2284
    by (simp add: borel_measurable_vimage_halfspace_component_le sets_restrict_space_iff assms)
lp15@67998
  2285
qed
lp15@67998
  2286
lp15@67998
  2287
lp15@67998
  2288
theorem borel_measurable_det_Jacobian:
lp15@67998
  2289
 fixes f :: "real^'n::{finite,wellorder} \<Rightarrow> real^'n::_"
lp15@67998
  2290
  assumes S: "S \<in> sets lebesgue" and f: "\<And>x. x \<in> S \<Longrightarrow> (f has_derivative f' x) (at x within S)"
lp15@67998
  2291
  shows "(\<lambda>x. det(matrix(f' x))) \<in> borel_measurable (lebesgue_on S)"
lp15@67998
  2292
  unfolding det_def
lp15@67998
  2293
  by (intro measurable) (auto intro: f borel_measurable_partial_derivatives [OF S])
lp15@67998
  2294
lp15@68001
  2295
text\<open>The localisation wrt S uses the same argument for many similar results.\<close>
lp15@68001
  2296
(*See HOL Light's MEASURABLE_ON_LEBESGUE_MEASURABLE_PREIMAGE_BOREL, etc.*)
lp15@67998
  2297
lemma borel_measurable_lebesgue_on_preimage_borel:
lp15@67998
  2298
  fixes f :: "'a::euclidean_space \<Rightarrow> 'b::euclidean_space"
lp15@67998
  2299
  assumes "S \<in> sets lebesgue"
lp15@67998
  2300
  shows "f \<in> borel_measurable (lebesgue_on S) \<longleftrightarrow>
lp15@67998
  2301
         (\<forall>T. T \<in> sets borel \<longrightarrow> {x \<in> S. f x \<in> T} \<in> sets lebesgue)"
lp15@67998
  2302
proof -
lp15@67998
  2303
  have "{x. (if x \<in> S then f x else 0) \<in> T} \<in> sets lebesgue \<longleftrightarrow> {x \<in> S. f x \<in> T} \<in> sets lebesgue"
lp15@67998
  2304
         if "T \<in> sets borel" for T
lp15@67998
  2305
    proof (cases "0 \<in> T")
lp15@67998
  2306
      case True
lp15@67998
  2307
      then have "{x \<in> S. f x \<in> T} = {x. (if x \<in> S then f x else 0) \<in> T} \<inter> S"
lp15@67998
  2308
                "{x. (if x \<in> S then f x else 0) \<in> T} = {x \<in> S. f x \<in> T} \<union> -S"
lp15@67998
  2309
        by auto
lp15@67998
  2310
      then show ?thesis
lp15@67998
  2311
        by (metis (no_types, lifting) Compl_in_sets_lebesgue assms sets.Int sets.Un)
lp15@67998
  2312
    next
lp15@67998
  2313
      case False
lp15@67998
  2314
      then have "{x. (if x \<in> S then f x else 0) \<in> T} = {x \<in> S. f x \<in> T}"
lp15@67998
  2315
        by auto
lp15@67998
  2316
      then show ?thesis
lp15@67998
  2317
        by auto
lp15@67998
  2318
    qed
lp15@67998
  2319
    then show ?thesis
lp15@67998
  2320
      unfolding borel_measurable_lebesgue_preimage_borel borel_measurable_UNIV [OF assms, symmetric]
lp15@67998
  2321
      by blast
lp15@67998
  2322
qed
lp15@67998
  2323
lp15@67998
  2324
lemma sets_lebesgue_almost_borel:
lp15@67998
  2325
  assumes "S \<in> sets lebesgue"
lp15@67998
  2326
  obtains B N where "B \<in> sets borel" "negligible N" "B \<union> N = S"
lp15@67998
  2327
proof -
lp15@67998
  2328
  obtain T N N' where "S = T \<union> N" "N \<subseteq> N'" "N' \<in> null_sets lborel" "T \<in> sets borel"
lp15@67998
  2329
    using sets_completionE [OF assms] by auto
lp15@67998
  2330
  then show thesis
lp15@67998
  2331
    by (metis negligible_iff_null_sets negligible_subset null_sets_completionI that)
lp15@67998
  2332
qed
lp15@67998
  2333
lp15@67998
  2334
lemma double_lebesgue_sets:
lp15@67998
  2335
 assumes S: "S \<in> sets lebesgue" and T: "T \<in> sets lebesgue" and fim: "f ` S \<subseteq> T"
lp15@67998
  2336
 shows "(\<forall>U. U \<in> sets lebesgue \<and> U \<subseteq> T \<longrightarrow> {x \<in> S. f x \<in> U} \<in> sets lebesgue) \<longleftrightarrow>
lp15@67998
  2337
          f \<in> borel_measurable (lebesgue_on S) \<and>
lp15@67998
  2338
          (\<forall>U. negligible U \<and> U \<subseteq> T \<longrightarrow> {x \<in> S. f x \<in> U} \<in> sets lebesgue)"
lp15@67998
  2339
         (is "?lhs \<longleftrightarrow> _ \<and> ?rhs")
lp15@67998
  2340
  unfolding borel_measurable_lebesgue_on_preimage_borel [OF S]
lp15@67998
  2341
proof (intro iffI allI conjI impI, safe)
lp15@67998
  2342
  fix V :: "'b set"
lp15@67998
  2343
  assume *: "\<forall>U. U \<in> sets lebesgue \<and> U \<subseteq> T \<longrightarrow> {x \<in> S. f x \<in> U} \<in> sets lebesgue"
lp15@67998
  2344
    and "V \<in> sets borel"
lp15@67998
  2345
  then have V: "V \<in> sets lebesgue"
lp15@67998
  2346
    by simp
lp15@67998
  2347
  have "{x \<in> S. f x \<in> V} = {x \<in> S. f x \<in> T \<inter> V}"
lp15@67998
  2348
    using fim by blast
lp15@67998
  2349
  also have "{x \<in> S. f x \<in> T \<inter> V} \<in> sets lebesgue"
lp15@67998
  2350
    using T V * le_inf_iff by blast
lp15@67998
  2351
  finally show "{x \<in> S. f x \<in> V} \<in> sets lebesgue" .
lp15@67998
  2352
next
lp15@67998
  2353
  fix U :: "'b set"
lp15@67998
  2354
  assume "\<forall>U. U \<in> sets lebesgue \<and> U \<subseteq> T \<longrightarrow> {x \<in> S. f x \<in> U} \<in> sets lebesgue"
lp15@67998
  2355
         "negligible U" "U \<subseteq> T"
lp15@67998
  2356
  then show "{x \<in> S. f x \<in> U} \<in> sets lebesgue"
lp15@67998
  2357
    using negligible_imp_sets by blast
lp15@67998
  2358
next
lp15@67998
  2359
  fix U :: "'b set"
lp15@67998
  2360
  assume 1 [rule_format]: "(\<forall>T. T \<in> sets borel \<longrightarrow> {x \<in> S. f x \<in> T} \<in> sets lebesgue)"
lp15@67998
  2361
     and 2 [rule_format]: "\<forall>U. negligible U \<and> U \<subseteq> T \<longrightarrow> {x \<in> S. f x \<in> U} \<in> sets lebesgue"
lp15@67998
  2362
     and "U \<in> sets lebesgue" "U \<subseteq> T"
lp15@67998
  2363
  then obtain C N where C: "C \<in> sets borel \<and> negligible N \<and> C \<union> N = U"
lp15@67998
  2364
    using sets_lebesgue_almost_borel
lp15@67998
  2365
    by metis
lp15@67998
  2366
  then have "{x \<in> S. f x \<in> C} \<in> sets lebesgue"
lp15@67998
  2367
    by (blast intro: 1)
lp15@67998
  2368
  moreover have "{x \<in> S. f x \<in> N} \<in> sets lebesgue"
lp15@67998
  2369
    using C \<open>U \<subseteq> T\<close> by (blast intro: 2)
lp15@67998
  2370
  moreover have "{x \<in> S. f x \<in> C \<union> N} = {x \<in> S. f x \<in> C} \<union> {x \<in> S. f x \<in> N}"
lp15@67998
  2371
    by auto
lp15@67998
  2372
  ultimately show "{x \<in> S. f x \<in> U} \<in> sets lebesgue"
lp15@67998
  2373
    using C by auto
lp15@67998
  2374
qed
lp15@67998
  2375
lp15@67998
  2376
lp15@67998
  2377
subsection\<open>Simplest case of Sard's theorem (we don't need continuity of derivative)\<close>
lp15@67998
  2378
lp15@67998
  2379
lemma Sard_lemma00:
lp15@67998
  2380
  fixes P :: "'b::euclidean_space set"
lp15@67998
  2381
  assumes "a \<ge> 0" and a: "a *\<^sub>R i \<noteq> 0" and i: "i \<in> Basis"
lp15@67998
  2382
    and P: "P \<subseteq> {x. a *\<^sub>R i \<bullet> x = 0}"
lp15@67998
  2383
    and "0 \<le> m" "0 \<le> e"
lp15@67998
  2384
 obtains S where "S \<in> lmeasurable"
lp15@67998
  2385
            and "{z. norm z \<le> m \<and> (\<exists>t \<in> P. norm(z - t) \<le> e)} \<subseteq> S"
lp15@67998
  2386
            and "measure lebesgue S \<le> (2 * e) * (2 * m) ^ (DIM('b) - 1)"
lp15@67998
  2387
proof -
lp15@67998
  2388
  have "a > 0"
lp15@67998
  2389
    using assms by simp
lp15@67998
  2390
  let ?v = "(\<Sum>j\<in>Basis. (if j = i then e else m) *\<^sub>R j)"
lp15@67998
  2391
  show thesis
lp15@67998
  2392
  proof
lp15@67998
  2393
    have "- e \<le> x \<bullet> i" "x \<bullet> i \<le> e"
lp15@67998
  2394
      if "t \<in> P" "norm (x - t) \<le> e" for x t
lp15@67998
  2395
      using \<open>a > 0\<close> that Basis_le_norm [of i "x-t"] P i
lp15@67998
  2396
      by (auto simp: inner_commute algebra_simps)
lp15@67998
  2397
    moreover have "- m \<le> x \<bullet> j" "x \<bullet> j \<le> m"
lp15@67998
  2398
      if "norm x \<le> m" "t \<in> P" "norm (x - t) \<le> e" "j \<in> Basis" and "j \<noteq> i"
lp15@67998
  2399
      for x t j
lp15@67998
  2400
      using that Basis_le_norm [of j x] by auto
lp15@67998
  2401
    ultimately
lp15@67998
  2402
    show "{z. norm z \<le> m \<and> (\<exists>t\<in>P. norm (z - t) \<le> e)} \<subseteq> cbox (-?v) ?v"
lp15@67998
  2403
      by (auto simp: mem_box)
lp15@67998
  2404
    have *: "\<forall>k\<in>Basis. - ?v \<bullet> k \<le> ?v \<bullet> k"
lp15@67998
  2405
      using \<open>0 \<le> m\<close> \<open>0 \<le> e\<close> by (auto simp: inner_Basis)
lp15@67998
  2406
    have 2: "2 ^ DIM('b) = 2 * 2 ^ (DIM('b) - Suc 0)"
lp15@67998
  2407
      by (metis DIM_positive Suc_pred power_Suc)
lp15@67998
  2408
    show "measure lebesgue (cbox (-?v) ?v) \<le> 2 * e * (2 * m) ^ (DIM('b) - 1)"
lp15@67998
  2409
      using \<open>i \<in> Basis\<close>
lp15@67998
  2410
      by (simp add: content_cbox [OF *] prod.distrib prod.If_cases Diff_eq [symmetric] 2)
lp15@67998
  2411
  qed blast
lp15@67998
  2412
qed
lp15@67998
  2413
lp15@68001
  2414
text\<open>As above, but reorienting the vector (HOL Light's @text{GEOM\_BASIS\_MULTIPLE\_TAC})\<close>
lp15@67998
  2415
lemma Sard_lemma0:
lp15@67998
  2416
  fixes P :: "(real^'n::{finite,wellorder}) set"
lp15@67998
  2417
  assumes "a \<noteq> 0"
lp15@67998
  2418
    and P: "P \<subseteq> {x. a \<bullet> x = 0}" and "0 \<le> m" "0 \<le> e"
lp15@67998
  2419
  obtains S where "S \<in> lmeasurable"
lp15@67998
  2420
    and "{z. norm z \<le> m \<and> (\<exists>t \<in> P. norm(z - t) \<le> e)} \<subseteq> S"
lp15@67998
  2421
    and "measure lebesgue S \<le> (2 * e) * (2 * m) ^ (CARD('n) - 1)"
lp15@67998
  2422
proof -
lp15@67998
  2423
  obtain T and k::'n where T: "orthogonal_transformation T" and a: "a = T (norm a *\<^sub>R axis k (1::real))"
lp15@67998
  2424
    using rotation_rightward_line by metis
lp15@67998
  2425
  have Tinv [simp]: "T (inv T x) = x" for x
lp15@67998
  2426
    by (simp add: T orthogonal_transformation_surj surj_f_inv_f)
lp15@67998
  2427
  obtain S where S: "S \<in> lmeasurable"
lp15@67998
  2428
    and subS: "{z. norm z \<le> m \<and> (\<exists>t \<in> T-`P. norm(z - t) \<le> e)} \<subseteq> S"
lp15@67998
  2429
    and mS: "measure lebesgue S \<le> (2 * e) * (2 * m) ^ (CARD('n) - 1)"
lp15@67998
  2430
  proof (rule Sard_lemma00 [of "norm a" "axis k (1::real)" "T-`P" m e])
lp15@67998
  2431
    have "norm a *\<^sub>R axis k 1 \<bullet> x = 0" if "T x \<in> P" for x
lp15@67998
  2432
    proof -
lp15@67998
  2433
      have "a \<bullet> T x = 0"
lp15@67998
  2434
        using P that by blast
lp15@67998
  2435
      then show ?thesis
lp15@67998
  2436
        by (metis (no_types, lifting) T a orthogonal_orthogonal_transformation orthogonal_def)
lp15@67998
  2437
    qed
lp15@67998
  2438
    then show "T -` P \<subseteq> {x. norm a *\<^sub>R axis k 1 \<bullet> x = 0}"
lp15@67998
  2439
      by auto
lp15@67998
  2440
  qed (use assms T in auto)
lp15@67998
  2441
  show thesis
lp15@67998
  2442
  proof