1 (* ========================================================================= *)
2 (* Real vectors in Euclidean space, and elementary linear algebra. *)
4 (* (c) Copyright, John Harrison 1998-2008 *)
5 (* ========================================================================= *)
7 needs "Multivariate/misc.ml";;
9 (* ------------------------------------------------------------------------- *)
10 (* Some common special cases. *)
11 (* ------------------------------------------------------------------------- *)
14 (`(!i. 1 <= i /\ i <= 1 ==> P i) <=> P 1`,
15 MESON_TAC[LE_ANTISYM]);;
18 (`!P. (!i. 1 <= i /\ i <= 2 ==> P i) <=> P 1 /\ P 2`,
19 MESON_TAC[ARITH_RULE `1 <= i /\ i <= 2 <=> i = 1 \/ i = 2`]);;
22 (`!P. (!i. 1 <= i /\ i <= 3 ==> P i) <=> P 1 /\ P 2 /\ P 3`,
23 MESON_TAC[ARITH_RULE `1 <= i /\ i <= 3 <=> i = 1 \/ i = 2 \/ i = 3`]);;
26 (`!P. (!i. 1 <= i /\ i <= 4 ==> P i) <=> P 1 /\ P 2 /\ P 3 /\ P 4`,
27 MESON_TAC[ARITH_RULE `1 <= i /\ i <= 4 <=>
28 i = 1 \/ i = 2 \/ i = 3 \/ i = 4`]);;
31 (`sum(1..1) f = f(1)`,
32 REWRITE_TAC[SUM_SING_NUMSEG]);;
35 (`!t. sum(1..2) t = t(1) + t(2)`,
36 REWRITE_TAC[num_CONV `2`; SUM_CLAUSES_NUMSEG] THEN
37 REWRITE_TAC[SUM_SING_NUMSEG; ARITH; REAL_ADD_ASSOC]);;
40 (`!t. sum(1..3) t = t(1) + t(2) + t(3)`,
41 REWRITE_TAC[num_CONV `3`; num_CONV `2`; SUM_CLAUSES_NUMSEG] THEN
42 REWRITE_TAC[SUM_SING_NUMSEG; ARITH; REAL_ADD_ASSOC]);;
45 (`!t. sum(1..4) t = t(1) + t(2) + t(3) + t(4)`,
46 SIMP_TAC[num_CONV `4`; num_CONV `3`; num_CONV `2`; SUM_CLAUSES_NUMSEG] THEN
47 REWRITE_TAC[SUM_SING_NUMSEG; ARITH; REAL_ADD_ASSOC]);;
49 (* ------------------------------------------------------------------------- *)
50 (* Basic componentwise operations on vectors. *)
51 (* ------------------------------------------------------------------------- *)
53 let vector_add = new_definition
54 `(vector_add:real^N->real^N->real^N) x y = lambda i. x$i + y$i`;;
56 let vector_sub = new_definition
57 `(vector_sub:real^N->real^N->real^N) x y = lambda i. x$i - y$i`;;
59 let vector_neg = new_definition
60 `(vector_neg:real^N->real^N) x = lambda i. --(x$i)`;;
62 overload_interface ("+",`(vector_add):real^N->real^N->real^N`);;
63 overload_interface ("-",`(vector_sub):real^N->real^N->real^N`);;
64 overload_interface ("--",`(vector_neg):real^N->real^N`);;
68 let prioritize_vector = let ty = `:real^N` in
69 fun () -> prioritize_overload ty;;
71 (* ------------------------------------------------------------------------- *)
72 (* Also the scalar-vector multiplication. *)
73 (* ------------------------------------------------------------------------- *)
75 parse_as_infix("%",(21,"right"));;
77 let vector_mul = new_definition
78 `((%):real->real^N->real^N) c x = lambda i. c * x$i`;;
80 (* ------------------------------------------------------------------------- *)
81 (* Vectors corresponding to small naturals. Perhaps should overload "&"? *)
82 (* ------------------------------------------------------------------------- *)
84 let vec = new_definition
85 `(vec:num->real^N) n = lambda i. &n`;;
87 (* ------------------------------------------------------------------------- *)
89 (* ------------------------------------------------------------------------- *)
91 parse_as_infix("dot",(20,"right"));;
93 let dot = new_definition
94 `(x:real^N) dot (y:real^N) = sum(1..dimindex(:N)) (\i. x$i * y$i)`;;
97 (`(x:real^1) dot (y:real^1) = x$1 * y$1`,
98 REWRITE_TAC[dot; DIMINDEX_1; SUM_1]);;
101 (`(x:real^2) dot (y:real^2) = x$1 * y$1 + x$2 * y$2`,
102 REWRITE_TAC[dot; DIMINDEX_2; SUM_2]);;
105 (`(x:real^3) dot (y:real^3) = x$1 * y$1 + x$2 * y$2 + x$3 * y$3`,
106 REWRITE_TAC[dot; DIMINDEX_3; SUM_3]);;
109 (`(x:real^4) dot (y:real^4) = x$1 * y$1 + x$2 * y$2 + x$3 * y$3 + x$4 * y$4`,
110 REWRITE_TAC[dot; DIMINDEX_4; SUM_4]);;
112 (* ------------------------------------------------------------------------- *)
113 (* A naive proof procedure to lift really trivial arithmetic stuff from R. *)
114 (* ------------------------------------------------------------------------- *)
116 let VECTOR_ARITH_TAC =
117 let RENAMED_LAMBDA_BETA th =
118 if fst(dest_fun_ty(type_of(funpow 3 rand (concl th)))) = aty
119 then INST_TYPE [aty,bty; bty,aty] LAMBDA_BETA else LAMBDA_BETA in
120 POP_ASSUM_LIST(K ALL_TAC) THEN
121 REPEAT(GEN_TAC ORELSE CONJ_TAC ORELSE DISCH_TAC ORELSE EQ_TAC) THEN
122 REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
123 REWRITE_TAC[dot; GSYM SUM_ADD_NUMSEG; GSYM SUM_SUB_NUMSEG;
124 GSYM SUM_LMUL; GSYM SUM_RMUL; GSYM SUM_NEG] THEN
125 (MATCH_MP_TAC SUM_EQ_NUMSEG ORELSE MATCH_MP_TAC SUM_EQ_0_NUMSEG ORELSE
126 GEN_REWRITE_TAC ONCE_DEPTH_CONV [CART_EQ]) THEN
127 REWRITE_TAC[AND_FORALL_THM] THEN TRY EQ_TAC THEN
128 TRY(MATCH_MP_TAC MONO_FORALL) THEN GEN_TAC THEN
129 REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`;
130 TAUT `(a ==> b) \/ (a ==> c) <=> a ==> b \/ c`] THEN
131 TRY(MATCH_MP_TAC(TAUT `(a ==> b ==> c) ==> (a ==> b) ==> (a ==> c)`)) THEN
132 REWRITE_TAC[vector_add; vector_sub; vector_neg; vector_mul; vec] THEN
133 DISCH_THEN(fun th -> REWRITE_TAC[MATCH_MP(RENAMED_LAMBDA_BETA th) th]) THEN
136 let VECTOR_ARITH tm = prove(tm,VECTOR_ARITH_TAC);;
138 (* ------------------------------------------------------------------------- *)
139 (* Obvious "component-pushing". *)
140 (* ------------------------------------------------------------------------- *)
142 let VEC_COMPONENT = prove
143 (`!k i. (vec k :real^N)$i = &k`,
145 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k`
147 [REWRITE_TAC[FINITE_INDEX_INRANGE];
148 ASM_SIMP_TAC[vec; CART_EQ; LAMBDA_BETA]]);;
150 let VECTOR_ADD_COMPONENT = prove
151 (`!x:real^N y i. (x + y)$i = x$i + y$i`,
153 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k`
155 [REWRITE_TAC[FINITE_INDEX_INRANGE];
156 ASM_SIMP_TAC[vector_add; CART_EQ; LAMBDA_BETA]]);;
158 let VECTOR_SUB_COMPONENT = prove
159 (`!x:real^N y i. (x - y)$i = x$i - y$i`,
161 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k`
163 [REWRITE_TAC[FINITE_INDEX_INRANGE];
164 ASM_SIMP_TAC[vector_sub; CART_EQ; LAMBDA_BETA]]);;
166 let VECTOR_NEG_COMPONENT = prove
167 (`!x:real^N i. (--x)$i = --(x$i)`,
169 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k`
171 [REWRITE_TAC[FINITE_INDEX_INRANGE];
172 ASM_SIMP_TAC[vector_neg; CART_EQ; LAMBDA_BETA]]);;
174 let VECTOR_MUL_COMPONENT = prove
175 (`!c x:real^N i. (c % x)$i = c * x$i`,
177 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !z:real^N. z$i = z$k`
179 [REWRITE_TAC[FINITE_INDEX_INRANGE];
180 ASM_SIMP_TAC[vector_mul; CART_EQ; LAMBDA_BETA]]);;
182 let COND_COMPONENT = prove
183 (`(if b then x else y)$i = if b then x$i else y$i`,
186 (* ------------------------------------------------------------------------- *)
187 (* Some frequently useful arithmetic lemmas over vectors. *)
188 (* ------------------------------------------------------------------------- *)
190 let VECTOR_ADD_SYM = VECTOR_ARITH `!x y:real^N. x + y = y + x`;;
192 let VECTOR_ADD_LID = VECTOR_ARITH `!x. vec 0 + x = x`;;
194 let VECTOR_ADD_RID = VECTOR_ARITH `!x. x + vec 0 = x`;;
196 let VECTOR_SUB_REFL = VECTOR_ARITH `!x. x - x = vec 0`;;
198 let VECTOR_ADD_LINV = VECTOR_ARITH `!x. --x + x = vec 0`;;
200 let VECTOR_ADD_RINV = VECTOR_ARITH `!x. x + --x = vec 0`;;
202 let VECTOR_SUB_RADD = VECTOR_ARITH `!x y. x - (x + y) = --y:real^N`;;
204 let VECTOR_NEG_SUB = VECTOR_ARITH `!x:real^N y. --(x - y) = y - x`;;
206 let VECTOR_SUB_EQ = VECTOR_ARITH `!x y. (x - y = vec 0) <=> (x = y)`;;
208 let VECTOR_MUL_ASSOC = VECTOR_ARITH `!a b x. a % (b % x) = (a * b) % x`;;
210 let VECTOR_MUL_LID = VECTOR_ARITH `!x. &1 % x = x`;;
212 let VECTOR_MUL_LZERO = VECTOR_ARITH `!x. &0 % x = vec 0`;;
214 let VECTOR_SUB_ADD = VECTOR_ARITH `(x - y) + y = x:real^N`;;
216 let VECTOR_SUB_ADD2 = VECTOR_ARITH `y + (x - y) = x:real^N`;;
218 let VECTOR_ADD_LDISTRIB = VECTOR_ARITH `c % (x + y) = c % x + c % y`;;
220 let VECTOR_SUB_LDISTRIB = VECTOR_ARITH `c % (x - y) = c % x - c % y`;;
222 let VECTOR_ADD_RDISTRIB = VECTOR_ARITH `(a + b) % x = a % x + b % x`;;
224 let VECTOR_SUB_RDISTRIB = VECTOR_ARITH `(a - b) % x = a % x - b % x`;;
226 let VECTOR_ADD_SUB = VECTOR_ARITH `(x + y:real^N) - x = y`;;
228 let VECTOR_EQ_ADDR = VECTOR_ARITH `(x + y = x) <=> (y = vec 0)`;;
230 let VECTOR_SUB = VECTOR_ARITH `x - y = x + --(y:real^N)`;;
232 let VECTOR_SUB_RZERO = VECTOR_ARITH `x - vec 0 = x`;;
234 let VECTOR_MUL_RZERO = VECTOR_ARITH `c % vec 0 = vec 0`;;
236 let VECTOR_NEG_MINUS1 = VECTOR_ARITH `--x = (--(&1)) % x`;;
238 let VECTOR_ADD_ASSOC = VECTOR_ARITH `(x:real^N) + y + z = (x + y) + z`;;
240 let VECTOR_SUB_LZERO = VECTOR_ARITH `vec 0 - x = --x`;;
242 let VECTOR_NEG_NEG = VECTOR_ARITH `--(--(x:real^N)) = x`;;
244 let VECTOR_MUL_LNEG = VECTOR_ARITH `--c % x = --(c % x)`;;
246 let VECTOR_MUL_RNEG = VECTOR_ARITH `c % --x = --(c % x)`;;
248 let VECTOR_NEG_0 = VECTOR_ARITH `--(vec 0) = vec 0`;;
250 let VECTOR_NEG_EQ_0 = VECTOR_ARITH `--x = vec 0 <=> x = vec 0`;;
252 let VECTOR_EQ_NEG2 = VECTOR_ARITH `!x y:real^N. --x = --y <=> x = y`;;
254 let VECTOR_ADD_AC = VECTOR_ARITH
255 `(m + n = n + m:real^N) /\
256 ((m + n) + p = m + n + p) /\
257 (m + n + p = n + m + p)`;;
260 (`!m n. (vec m = vec n) <=> (m = n)`,
261 SIMP_TAC[CART_EQ; VEC_COMPONENT; REAL_OF_NUM_EQ] THEN
262 MESON_TAC[LE_REFL; DIMINDEX_GE_1]);;
264 (* ------------------------------------------------------------------------- *)
265 (* Infinitude of Euclidean space. *)
266 (* ------------------------------------------------------------------------- *)
268 let EUCLIDEAN_SPACE_INFINITE = prove
269 (`INFINITE(:real^N)`,
270 REWRITE_TAC[INFINITE] THEN DISCH_TAC THEN
271 FIRST_ASSUM(MP_TAC o ISPEC `vec:num->real^N` o
272 MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] FINITE_IMAGE_INJ)) THEN
273 REWRITE_TAC[VEC_EQ; SET_RULE `{x | f x IN UNIV} = UNIV`] THEN
274 REWRITE_TAC[GSYM INFINITE; num_INFINITE]);;
276 (* ------------------------------------------------------------------------- *)
277 (* Properties of the dot product. *)
278 (* ------------------------------------------------------------------------- *)
280 let DOT_SYM = VECTOR_ARITH `!x y. x dot y = y dot x`;;
282 let DOT_LADD = VECTOR_ARITH `!x y z. (x + y) dot z = (x dot z) + (y dot z)`;;
284 let DOT_RADD = VECTOR_ARITH `!x y z. x dot (y + z) = (x dot y) + (x dot z)`;;
286 let DOT_LSUB = VECTOR_ARITH `!x y z. (x - y) dot z = (x dot z) - (y dot z)`;;
288 let DOT_RSUB = VECTOR_ARITH `!x y z. x dot (y - z) = (x dot y) - (x dot z)`;;
290 let DOT_LMUL = VECTOR_ARITH `!c x y. (c % x) dot y = c * (x dot y)`;;
292 let DOT_RMUL = VECTOR_ARITH `!c x y. x dot (c % y) = c * (x dot y)`;;
294 let DOT_LNEG = VECTOR_ARITH `!x y. (--x) dot y = --(x dot y)`;;
296 let DOT_RNEG = VECTOR_ARITH `!x y. x dot (--y) = --(x dot y)`;;
298 let DOT_LZERO = VECTOR_ARITH `!x. (vec 0) dot x = &0`;;
300 let DOT_RZERO = VECTOR_ARITH `!x. x dot (vec 0) = &0`;;
302 let DOT_POS_LE = prove
303 (`!x. &0 <= x dot x`,
304 SIMP_TAC[dot; SUM_POS_LE_NUMSEG; REAL_LE_SQUARE]);;
307 (`!x:real^N. ((x dot x = &0) <=> (x = vec 0))`,
308 REPEAT GEN_TAC THEN EQ_TAC THENL [ALL_TAC; MESON_TAC[DOT_LZERO]] THEN
309 SIMP_TAC[dot; CART_EQ; vec; LAMBDA_BETA] THEN DISCH_TAC THEN
310 ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[REAL_ENTIRE] `x * x = &0`)] THEN
311 MATCH_MP_TAC SUM_POS_EQ_0_NUMSEG THEN ASM_REWRITE_TAC[REAL_LE_SQUARE]);;
313 let DOT_POS_LT = prove
314 (`!x. (&0 < x dot x) <=> ~(x = vec 0)`,
315 REWRITE_TAC[REAL_LT_LE; DOT_POS_LE] THEN MESON_TAC[DOT_EQ_0]);;
317 let FORALL_DOT_EQ_0 = prove
318 (`(!y. (!x. x dot y = &0) <=> y = vec 0) /\
319 (!x. (!y. x dot y = &0) <=> x = vec 0)`,
320 MESON_TAC[DOT_LZERO; DOT_RZERO; DOT_EQ_0]);;
322 (* ------------------------------------------------------------------------- *)
323 (* Introduce norms, but defer many properties till we get square roots. *)
324 (* ------------------------------------------------------------------------- *)
326 make_overloadable "norm" `:A->real`;;
327 overload_interface("norm",`vector_norm:real^N->real`);;
329 let vector_norm = new_definition
330 `norm x = sqrt(x dot x)`;;
332 (* ------------------------------------------------------------------------- *)
333 (* Useful for the special cases of 1 dimension. *)
334 (* ------------------------------------------------------------------------- *)
336 let FORALL_DIMINDEX_1 = prove
337 (`(!i. 1 <= i /\ i <= dimindex(:1) ==> P i) <=> P 1`,
338 MESON_TAC[DIMINDEX_1; LE_ANTISYM]);;
340 (* ------------------------------------------------------------------------- *)
341 (* The collapse of the general concepts to the real line R^1. *)
342 (* ------------------------------------------------------------------------- *)
344 let VECTOR_ONE = prove
345 (`!x:real^1. x = lambda i. x$1`,
346 SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN MESON_TAC[DIMINDEX_1; LE_ANTISYM]);;
348 let FORALL_REAL_ONE = prove
349 (`(!x:real^1. P x) <=> (!x. P(lambda i. x))`,
350 EQ_TAC THEN SIMP_TAC[] THEN DISCH_TAC THEN GEN_TAC THEN
351 FIRST_X_ASSUM(MP_TAC o SPEC `(x:real^1)$1`) THEN
352 REWRITE_TAC[GSYM VECTOR_ONE]);;
354 let NORM_REAL = prove
355 (`!x:real^1. norm(x) = abs(x$1)`,
356 REWRITE_TAC[vector_norm; dot; DIMINDEX_1; SUM_SING_NUMSEG;
357 GSYM REAL_POW_2; POW_2_SQRT_ABS]);;
359 (* ------------------------------------------------------------------------- *)
360 (* Metric function. *)
361 (* ------------------------------------------------------------------------- *)
363 override_interface("dist",`distance:real^N#real^N->real`);;
365 let dist = new_definition
366 `dist(x,y) = norm(x - y)`;;
368 let DIST_REAL = prove
369 (`!x:real^1 y. dist(x,y) = abs(x$1 - y$1)`,
370 SIMP_TAC[dist; NORM_REAL; vector_sub; LAMBDA_BETA; LE_REFL; DIMINDEX_1]);;
372 (* ------------------------------------------------------------------------- *)
373 (* A connectedness or intermediate value lemma with several applications. *)
374 (* ------------------------------------------------------------------------- *)
376 let CONNECTED_REAL_LEMMA = prove
377 (`!f:real->real^N a b e1 e2.
378 a <= b /\ f(a) IN e1 /\ f(b) IN e2 /\
379 (!e x. a <= x /\ x <= b /\ &0 < e
381 !y. abs(y - x) < d ==> dist(f(y),f(x)) < e) /\
382 (!y. y IN e1 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e1) /\
383 (!y. y IN e2 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e2) /\
384 ~(?x. a <= x /\ x <= b /\ f(x) IN e1 /\ f(x) IN e2)
385 ==> ?x. a <= x /\ x <= b /\ ~(f(x) IN e1) /\ ~(f(x) IN e2)`,
386 let tac = ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_TOTAL; REAL_LE_ANTISYM] in
387 REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN
388 MP_TAC(SPEC `\c. !x. a <= x /\ x <= c ==> (f(x):real^N) IN e1`
390 REWRITE_TAC[] THEN ANTS_TAC THENL [tac; ALL_TAC] THEN
391 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real` THEN STRIP_TAC THEN
392 SUBGOAL_THEN `a <= x /\ x <= b` STRIP_ASSUME_TAC THENL [tac; ALL_TAC] THEN
393 ASM_REWRITE_TAC[] THEN
394 SUBGOAL_THEN `!z. a <= z /\ z < x ==> (f(z):real^N) IN e1` ASSUME_TAC THENL
395 [ASM_MESON_TAC[REAL_NOT_LT; REAL_LT_IMP_LE]; ALL_TAC] THEN
396 REPEAT STRIP_TAC THENL
398 `?d. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real^N) IN e1`
399 STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
400 ASM_MESON_TAC[REAL_ARITH `z <= x + e /\ e < d ==> z < x \/ abs(z - x) < d`;
401 REAL_ARITH `&0 < e ==> ~(x + e <= x)`; REAL_DOWN];
403 `?d. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real^N) IN e2`
404 STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
405 MP_TAC(SPECL [`x - a`; `d:real`] REAL_DOWN2) THEN ANTS_TAC THENL
406 [ASM_MESON_TAC[REAL_LT_LE; REAL_SUB_LT]; ALL_TAC] THEN
407 ASM_MESON_TAC[REAL_ARITH `e < x - a ==> a <= x - e`;
408 REAL_ARITH `&0 < e /\ x <= b ==> x - e <= b`;
409 REAL_ARITH `&0 < e /\ e < d ==> x - e < x /\ abs((x - e) - x) < d`]]);;
411 (* ------------------------------------------------------------------------- *)
412 (* One immediately useful corollary is the existence of square roots! *)
413 (* ------------------------------------------------------------------------- *)
415 let SQUARE_BOUND_LEMMA = prove
416 (`!x. x < (&1 + x) * (&1 + x)`,
417 GEN_TAC THEN REWRITE_TAC[REAL_POW_2] THEN
418 MAP_EVERY (fun t -> MP_TAC(SPEC t REAL_LE_SQUARE)) [`x:real`; `&1 + x`] THEN
421 let SQUARE_CONTINUOUS = prove
423 ==> ?d. &0 < d /\ !y. abs(y - x) < d ==> abs(y * y - x * x) < e`,
424 REPEAT STRIP_TAC THEN ASM_CASES_TAC `x = &0` THENL
425 [ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_SUB_RZERO] THEN
426 EXISTS_TAC `inv(&1 + inv(e))` THEN
427 ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_LT_ADD; REAL_LT_01] THEN
428 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
429 EXISTS_TAC `inv(&1 + inv(e)) * inv(&1 + inv(e))` THEN
430 ASM_SIMP_TAC[REAL_ABS_MUL; REAL_LT_MUL2; REAL_ABS_POS] THEN
431 REWRITE_TAC[GSYM REAL_INV_MUL] THEN
432 GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN
433 MATCH_MP_TAC REAL_LE_INV2 THEN
434 ASM_SIMP_TAC[REAL_LT_IMP_LE; SQUARE_BOUND_LEMMA; REAL_LT_INV_EQ];
435 MP_TAC(SPECL [`abs(x)`; `e / (&3 * abs(x))`] REAL_DOWN2)THEN
436 ASM_SIMP_TAC[GSYM REAL_ABS_NZ; REAL_LT_DIV; REAL_LT_MUL; REAL_OF_NUM_LT;
437 ARITH; REAL_LT_RDIV_EQ] THEN
438 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
439 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `y:real` THEN
440 REWRITE_TAC[REAL_ARITH `x * x - y * y = (x - y) * (x + y)`] THEN
441 DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
442 EXISTS_TAC `d * &3 * abs(x)` THEN ASM_REWRITE_TAC[REAL_ABS_MUL] THEN
443 MATCH_MP_TAC REAL_LE_MUL2 THEN
444 ASM_SIMP_TAC[REAL_ABS_POS; REAL_LT_IMP_LE] THEN
445 MAP_EVERY UNDISCH_TAC [`abs (y - x) < d`; `d < abs(x)`] THEN
448 let SQRT_WORKS = prove
449 (`!x. &0 <= x ==> &0 <= sqrt(x) /\ (sqrt(x) pow 2 = x)`,
450 GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [REAL_LE_LT] THEN STRIP_TAC THENL
452 ASM_MESON_TAC[SQRT_0; REAL_POW_2; REAL_LE_REFL; REAL_MUL_LZERO]] THEN
453 REWRITE_TAC[sqrt] THEN CONV_TAC SELECT_CONV THEN
454 MP_TAC(ISPECL [`(\u. lambda i. u):real->real^1`; `&0`; `&1 + x`;
455 `{u:real^1 | u$1 * u$1 < x}`; `{u:real^1 | u$1 * u$1 > x}`]
456 CONNECTED_REAL_LEMMA) THEN
457 SIMP_TAC[LAMBDA_BETA; LE_REFL; DIMINDEX_1; DIST_REAL;
458 EXTENSION; IN_INTER; IN_ELIM_THM; NOT_IN_EMPTY;
459 REAL_MUL_LZERO; FORALL_REAL_ONE; real_gt] THEN
460 ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_POW_2; REAL_LT_TOTAL]] THEN
461 ASM_SIMP_TAC[REAL_LT_ANTISYM; REAL_ARITH `&0 < x ==> &0 <= &1 + x`] THEN
462 REWRITE_TAC[SQUARE_BOUND_LEMMA] THEN
463 MESON_TAC[SQUARE_CONTINUOUS; REAL_SUB_LT;
464 REAL_ARITH `abs(z2 - x2) < y - x2 ==> z2 < y`;
465 REAL_ARITH `abs(z2 - x2) < x2 - y ==> y < z2`]);;
467 let SQRT_POS_LE = prove
468 (`!x. &0 <= x ==> &0 <= sqrt(x)`,
469 MESON_TAC[SQRT_WORKS]);;
471 let SQRT_POW_2 = prove
472 (`!x. &0 <= x ==> (sqrt(x) pow 2 = x)`,
473 MESON_TAC[SQRT_WORKS]);;
476 (`!x y. &0 <= x /\ &0 <= y
477 ==> (sqrt(x * y) = sqrt x * sqrt y)`,
478 ASM_MESON_TAC[REAL_POW_2; SQRT_WORKS; REAL_LE_MUL; SQRT_UNIQUE;
479 REAL_ARITH `(x * y) * (x * y) = (x * x) * y * y`]);;
482 (`!x. &0 <= x ==> (sqrt (inv x) = inv(sqrt x))`,
483 MESON_TAC[SQRT_UNIQUE; SQRT_WORKS; REAL_POW_INV; REAL_LE_INV_EQ]);;
486 (`!x y. &0 <= x /\ &0 <= y ==> (sqrt (x / y) = sqrt x / sqrt y)`,
487 SIMP_TAC[real_div; SQRT_MUL; SQRT_INV; REAL_LE_INV_EQ]);;
489 let SQRT_POW2 = prove
490 (`!x. (sqrt(x) pow 2 = x) <=> &0 <= x`,
491 MESON_TAC[REAL_POW_2; REAL_LE_SQUARE; SQRT_POW_2]);;
493 let SQRT_MONO_LT = prove
494 (`!x y. &0 <= x /\ x < y ==> sqrt(x) < sqrt(y)`,
495 REWRITE_TAC[GSYM REAL_NOT_LE] THEN
496 MESON_TAC[REAL_LT_IMP_LE; REAL_NOT_LE; REAL_LE_TRANS;
497 REAL_POW_LE2; SQRT_WORKS]);;
499 let SQRT_MONO_LE = prove
500 (`!x y. &0 <= x /\ x <= y ==> sqrt(x) <= sqrt(y)`,
501 MESON_TAC[REAL_LE_LT; SQRT_MONO_LT]);;
503 let SQRT_MONO_LT_EQ = prove
504 (`!x y. &0 <= x /\ &0 <= y ==> (sqrt(x) < sqrt(y) <=> x < y)`,
505 MESON_TAC[REAL_NOT_LT; SQRT_MONO_LT; SQRT_MONO_LE]);;
507 let SQRT_MONO_LE_EQ = prove
508 (`!x y. &0 <= x /\ &0 <= y ==> (sqrt(x) <= sqrt(y) <=> x <= y)`,
509 MESON_TAC[REAL_NOT_LT; SQRT_MONO_LT; SQRT_MONO_LE]);;
512 (`!x y. &0 <= x /\ &0 <= y ==> ((sqrt(x) = sqrt(y)) <=> (x = y))`,
513 SIMP_TAC[GSYM REAL_LE_ANTISYM; SQRT_MONO_LE_EQ]);;
515 let SQRT_LT_0 = prove
516 (`!x. &0 <= x ==> (&0 < sqrt x <=> &0 < x)`,
517 MESON_TAC[SQRT_0; REAL_LE_REFL; SQRT_MONO_LT_EQ]);;
519 let SQRT_EQ_0 = prove
520 (`!x. &0 <= x ==> ((sqrt x = &0) <=> (x = &0))`,
521 MESON_TAC[SQRT_INJ; SQRT_0; REAL_LE_REFL]);;
523 let SQRT_POS_LT = prove
524 (`!x. &0 < x ==> &0 < sqrt(x)`,
525 MESON_TAC[REAL_LT_LE; SQRT_POS_LE; SQRT_EQ_0]);;
527 let REAL_LE_LSQRT = prove
528 (`!x y. &0 <= x /\ &0 <= y /\ x <= y pow 2 ==> sqrt(x) <= y`,
529 MESON_TAC[SQRT_MONO_LE; REAL_POW_LE; POW_2_SQRT]);;
531 let REAL_LE_RSQRT = prove
532 (`!x y. x pow 2 <= y ==> x <= sqrt(y)`,
533 MESON_TAC[REAL_LE_TOTAL; SQRT_MONO_LE; SQRT_POS_LE; REAL_POW_2;
534 REAL_LE_SQUARE; REAL_LE_TRANS; POW_2_SQRT]);;
536 let REAL_LT_LSQRT = prove
537 (`!x y. &0 <= x /\ &0 <= y /\ x < y pow 2 ==> sqrt x < y`,
538 MESON_TAC[SQRT_MONO_LT; REAL_POW_LE; POW_2_SQRT]);;
540 let REAL_LT_RSQRT = prove
541 (`!x y. x pow 2 < y ==> x < sqrt(y)`,
542 REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH `abs x < a ==> x < a`) THEN
543 REWRITE_TAC[GSYM POW_2_SQRT_ABS] THEN MATCH_MP_TAC SQRT_MONO_LT THEN
544 ASM_REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE]);;
546 let SQRT_EVEN_POW2 = prove
547 (`!n. EVEN n ==> (sqrt(&2 pow n) = &2 pow (n DIV 2))`,
548 SIMP_TAC[EVEN_EXISTS; LEFT_IMP_EXISTS_THM; DIV_MULT; ARITH_EQ] THEN
549 MESON_TAC[SQRT_UNIQUE; REAL_POW_POW; MULT_SYM; REAL_POW_LE; REAL_POS]);;
551 let REAL_DIV_SQRT = prove
552 (`!x. &0 <= x ==> (x / sqrt(x) = sqrt(x))`,
553 REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THENL
554 [ALL_TAC; ASM_MESON_TAC[SQRT_0; real_div; REAL_MUL_LZERO]] THEN
555 ASM_SIMP_TAC[REAL_EQ_LDIV_EQ; SQRT_POS_LT; GSYM REAL_POW_2] THEN
556 ASM_SIMP_TAC[SQRT_POW_2; REAL_LT_IMP_LE]);;
558 let REAL_RSQRT_LE = prove
559 (`!x y. &0 <= x /\ &0 <= y /\ x <= sqrt y ==> x pow 2 <= y`,
560 MESON_TAC[REAL_POW_LE2; SQRT_POW_2]);;
562 let REAL_LSQRT_LE = prove
563 (`!x y. &0 <= x /\ sqrt x <= y ==> x <= y pow 2`,
564 MESON_TAC[REAL_POW_LE2; SQRT_POS_LE; REAL_LE_TRANS; SQRT_POW_2]);;
566 (* ------------------------------------------------------------------------- *)
567 (* Hence derive more interesting properties of the norm. *)
568 (* ------------------------------------------------------------------------- *)
572 REWRITE_TAC[vector_norm; DOT_LZERO; SQRT_0]);;
574 let NORM_POS_LE = prove
576 GEN_TAC THEN SIMP_TAC[DOT_POS_LE; vector_norm; SQRT_POS_LE]);;
579 (`!x. norm(--x) = norm x`,
580 REWRITE_TAC[vector_norm; DOT_LNEG; DOT_RNEG; REAL_NEG_NEG]);;
583 (`!x y. norm(x - y) = norm(y - x)`,
584 MESON_TAC[NORM_NEG; VECTOR_NEG_SUB]);;
587 (`!a x. norm(a % x) = abs(a) * norm x`,
588 REWRITE_TAC[vector_norm; DOT_LMUL; DOT_RMUL; REAL_MUL_ASSOC] THEN
589 SIMP_TAC[SQRT_MUL; SQRT_POS_LE; DOT_POS_LE; REAL_LE_SQUARE] THEN
590 REWRITE_TAC[GSYM REAL_POW_2; POW_2_SQRT_ABS]);;
592 let NORM_EQ_0_DOT = prove
593 (`!x. (norm x = &0) <=> (x dot x = &0)`,
594 SIMP_TAC[vector_norm; SQRT_EQ_0; DOT_POS_LE]);;
596 let NORM_EQ_0 = prove
597 (`!x. (norm x = &0) <=> (x = vec 0)`,
598 SIMP_TAC[vector_norm; DOT_EQ_0; SQRT_EQ_0; DOT_POS_LE]);;
600 let NORM_POS_LT = prove
601 (`!x. &0 < norm x <=> ~(x = vec 0)`,
602 MESON_TAC[REAL_LT_LE; NORM_POS_LE; NORM_EQ_0]);;
604 let NORM_POW_2 = prove
605 (`!x. norm(x) pow 2 = x dot x`,
606 SIMP_TAC[vector_norm; SQRT_POW_2; DOT_POS_LE]);;
608 let NORM_EQ_0_IMP = prove
609 (`!x. (norm x = &0) ==> (x = vec 0)`,
610 MESON_TAC[NORM_EQ_0]);;
612 let NORM_LE_0 = prove
613 (`!x. norm x <= &0 <=> (x = vec 0)`,
614 MESON_TAC[REAL_LE_ANTISYM; NORM_EQ_0; NORM_POS_LE]);;
616 let VECTOR_MUL_EQ_0 = prove
617 (`!a x. (a % x = vec 0) <=> (a = &0) \/ (x = vec 0)`,
618 REWRITE_TAC[GSYM NORM_EQ_0; NORM_MUL; REAL_ABS_ZERO; REAL_ENTIRE]);;
620 let VECTOR_MUL_LCANCEL = prove
621 (`!a x y. (a % x = a % y) <=> (a = &0) \/ (x = y)`,
622 MESON_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_LDISTRIB; VECTOR_SUB_EQ]);;
624 let VECTOR_MUL_RCANCEL = prove
625 (`!a b x. (a % x = b % x) <=> (a = b) \/ (x = vec 0)`,
626 MESON_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_RDISTRIB; REAL_SUB_0; VECTOR_SUB_EQ]);;
628 let VECTOR_MUL_LCANCEL_IMP = prove
629 (`!a x y. ~(a = &0) /\ (a % x = a % y) ==> (x = y)`,
630 MESON_TAC[VECTOR_MUL_LCANCEL]);;
632 let VECTOR_MUL_RCANCEL_IMP = prove
633 (`!a b x. ~(x = vec 0) /\ (a % x = b % x) ==> (a = b)`,
634 MESON_TAC[VECTOR_MUL_RCANCEL]);;
636 let NORM_CAUCHY_SCHWARZ = prove
637 (`!(x:real^N) y. x dot y <= norm(x) * norm(y)`,
638 REPEAT STRIP_TAC THEN MAP_EVERY ASM_CASES_TAC
639 [`norm(x:real^N) = &0`; `norm(y:real^N) = &0`] THEN
640 ASM_SIMP_TAC[NORM_EQ_0_IMP; DOT_LZERO; DOT_RZERO;
641 REAL_MUL_LZERO; REAL_MUL_RZERO] THEN
642 MP_TAC(ISPEC `norm(y:real^N) % x - norm(x:real^N) % y` DOT_POS_LE) THEN
643 REWRITE_TAC[DOT_RSUB; DOT_LSUB; DOT_LMUL; DOT_RMUL; GSYM NORM_POW_2;
644 REAL_POW_2; REAL_LE_REFL] THEN
645 REWRITE_TAC[DOT_SYM; REAL_ARITH
646 `&0 <= y * (y * x * x - x * d) - x * (y * d - x * y * y) <=>
647 x * y * d <= x * y * x * y`] THEN
648 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_LE; NORM_POS_LE]);;
650 let NORM_CAUCHY_SCHWARZ_ABS = prove
651 (`!x:real^N y. abs(x dot y) <= norm(x) * norm(y)`,
652 REPEAT GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_CAUCHY_SCHWARZ) THEN
653 DISCH_THEN(fun th -> MP_TAC(SPEC `y:real^N` th) THEN
654 MP_TAC(SPEC `--(y:real^N)` th)) THEN
655 REWRITE_TAC[DOT_RNEG; NORM_NEG] THEN REAL_ARITH_TAC);;
657 let REAL_ABS_NORM = prove
658 (`!x. abs(norm x) = norm x`,
659 REWRITE_TAC[NORM_POS_LE; REAL_ABS_REFL]);;
661 let NORM_CAUCHY_SCHWARZ_DIV = prove
662 (`!x:real^N y. abs((x dot y) / (norm x * norm y)) <= &1`,
664 MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN
665 ASM_REWRITE_TAC[NORM_0; REAL_MUL_LZERO; REAL_MUL_RZERO; real_div;
666 REAL_INV_1; DOT_LZERO; DOT_RZERO; REAL_ABS_NUM; REAL_POS] THEN
667 ASM_SIMP_TAC[GSYM real_div; REAL_ABS_DIV; REAL_LE_LDIV_EQ; REAL_LT_MUL;
668 REAL_ABS_INV; NORM_POS_LT; REAL_ABS_MUL; REAL_ABS_NORM] THEN
669 REWRITE_TAC[REAL_MUL_LID; NORM_CAUCHY_SCHWARZ_ABS]);;
671 let NORM_TRIANGLE = prove
672 (`!x y. norm(x + y) <= norm(x) + norm(y)`,
673 REPEAT GEN_TAC THEN REWRITE_TAC[vector_norm] THEN
674 MATCH_MP_TAC REAL_LE_LSQRT THEN
675 SIMP_TAC[GSYM vector_norm; DOT_POS_LE; NORM_POS_LE; REAL_LE_ADD] THEN
676 REWRITE_TAC[DOT_LADD; DOT_RADD; REAL_POW_2; GSYM NORM_POW_2] THEN
677 SIMP_TAC[NORM_CAUCHY_SCHWARZ; DOT_SYM; REAL_ARITH
678 `d <= x * y ==> (x * x + d) + (d + y * y) <= (x + y) * (x + y)`]);;
680 let NORM_TRIANGLE_SUB = prove
681 (`!x y:real^N. norm(x) <= norm(y) + norm(x - y)`,
682 MESON_TAC[NORM_TRIANGLE; VECTOR_SUB_ADD2]);;
684 let NORM_TRIANGLE_LE = prove
685 (`!x y. norm(x) + norm(y) <= e ==> norm(x + y) <= e`,
686 MESON_TAC[REAL_LE_TRANS; NORM_TRIANGLE]);;
688 let NORM_TRIANGLE_LT = prove
689 (`!x y. norm(x) + norm(y) < e ==> norm(x + y) < e`,
690 MESON_TAC[REAL_LET_TRANS; NORM_TRIANGLE]);;
692 let COMPONENT_LE_NORM = prove
693 (`!x:real^N i. 1 <= i /\ i <= dimindex(:N)
694 ==> abs(x$i) <= norm x`,
695 REPEAT STRIP_TAC THEN REWRITE_TAC[vector_norm] THEN
696 MATCH_MP_TAC REAL_LE_RSQRT THEN REWRITE_TAC[GSYM REAL_ABS_POW] THEN
697 REWRITE_TAC[real_abs; REAL_POW_2; REAL_LE_SQUARE] THEN
699 `x$i * (x:real^N)$i =
700 sum(1..dimindex(:N)) (\k. if k = i then x$i * x$i else &0)`
702 [REWRITE_TAC[SUM_DELTA] THEN ASM_REWRITE_TAC[IN_NUMSEG]; ALL_TAC] THEN
703 REWRITE_TAC[dot] THEN MATCH_MP_TAC SUM_LE THEN
704 REWRITE_TAC[FINITE_NUMSEG] THEN
705 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
706 ASM_REWRITE_TAC[REAL_LE_REFL; REAL_LE_SQUARE]);;
708 let NORM_BOUND_COMPONENT_LE = prove
709 (`!x:real^N e. norm(x) <= e
710 ==> !i. 1 <= i /\ i <= dimindex(:N) ==> abs(x$i) <= e`,
711 MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS]);;
713 let NORM_BOUND_COMPONENT_LT = prove
714 (`!x:real^N e. norm(x) < e
715 ==> !i. 1 <= i /\ i <= dimindex(:N) ==> abs(x$i) < e`,
716 MESON_TAC[COMPONENT_LE_NORM; REAL_LET_TRANS]);;
718 let NORM_LE_L1 = prove
719 (`!x:real^N. norm x <= sum(1..dimindex(:N)) (\i. abs(x$i))`,
720 REPEAT GEN_TAC THEN REWRITE_TAC[vector_norm; dot] THEN
721 MATCH_MP_TAC REAL_LE_LSQRT THEN REWRITE_TAC[REAL_POW_2] THEN
722 SIMP_TAC[SUM_POS_LE; FINITE_NUMSEG; REAL_LE_SQUARE; REAL_ABS_POS] THEN
723 SPEC_TAC(`dimindex(:N)`,`n:num`) THEN INDUCT_TAC THEN
724 REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH_EQ; ARITH_RULE `1 <= SUC n`] THEN
725 SIMP_TAC[REAL_MUL_LZERO; REAL_LE_REFL] THEN
726 MATCH_MP_TAC(REAL_ARITH
727 `a2 <= a * a /\ &0 <= a * b /\ b2 <= b * b
728 ==> a2 + b2 <= (a + b) * (a + b)`) THEN
729 ASM_SIMP_TAC[SUM_POS_LE; REAL_LE_MUL; REAL_ABS_POS; FINITE_NUMSEG] THEN
730 REWRITE_TAC[GSYM REAL_ABS_MUL] THEN REAL_ARITH_TAC);;
732 let REAL_ABS_SUB_NORM = prove
733 (`abs(norm(x) - norm(y)) <= norm(x - y)`,
734 REWRITE_TAC[REAL_ARITH `abs(x - y) <= a <=> x <= y + a /\ y <= x + a`] THEN
735 MESON_TAC[NORM_TRIANGLE_SUB; NORM_SUB]);;
738 (`!x y. norm(x) <= norm(y) <=> x dot x <= y dot y`,
739 REWRITE_TAC[vector_norm] THEN MESON_TAC[SQRT_MONO_LE_EQ; DOT_POS_LE]);;
742 (`!x y. norm(x) < norm(y) <=> x dot x < y dot y`,
743 REWRITE_TAC[vector_norm] THEN MESON_TAC[SQRT_MONO_LT_EQ; DOT_POS_LE]);;
746 (`!x y. (norm x = norm y) <=> (x dot x = y dot y)`,
747 REWRITE_TAC[GSYM REAL_LE_ANTISYM; NORM_LE]);;
749 let NORM_EQ_1 = prove
750 (`!x. norm(x) = &1 <=> x dot x = &1`,
751 GEN_TAC THEN GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM SQRT_1] THEN
752 SIMP_TAC[vector_norm; SQRT_INJ; DOT_POS_LE; REAL_POS]);;
754 let NORM_LE_COMPONENTWISE = prove
755 (`!x:real^N y:real^N.
756 (!i. 1 <= i /\ i <= dimindex(:N) ==> abs(x$i) <= abs(y$i))
757 ==> norm(x) <= norm(y)`,
758 REPEAT STRIP_TAC THEN REWRITE_TAC[NORM_LE; dot] THEN
759 MATCH_MP_TAC SUM_LE_NUMSEG THEN
760 ASM_SIMP_TAC[GSYM REAL_POW_2; GSYM REAL_LE_SQUARE_ABS]);;
762 let L1_LE_NORM = prove
764 sum(1..dimindex(:N)) (\i. abs(x$i)) <= sqrt(&(dimindex(:N))) * norm x`,
766 (`!x n. &n * sum(1..n) (\i. x i pow 2) - (sum(1..n) x) pow 2 =
767 sum(1..n) (\i. sum(i+1..n) (\j. (x i - x j) pow 2))`,
768 GEN_TAC THEN CONV_TAC(BINDER_CONV SYM_CONV) THEN INDUCT_TAC THEN
769 REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH; ARITH_RULE `1 <= SUC n`] THEN
770 CONV_TAC REAL_RAT_REDUCE_CONV THEN
771 SIMP_TAC[ARITH_RULE `i <= n ==> i + 1 <= SUC n`; SUM_TRIV_NUMSEG;
772 ARITH_RULE `~(n + 1 <= n)`; ARITH_RULE `n < SUC n + 1`] THEN
773 ASM_REWRITE_TAC[SUM_ADD_NUMSEG; REAL_ADD_RID] THEN
774 REWRITE_TAC[REAL_ARITH
775 `(x - y) pow 2 = (x pow 2 + y pow 2) - &2 * x * y`] THEN
776 REWRITE_TAC[SUM_ADD_NUMSEG; SUM_SUB_NUMSEG; SUM_LMUL; SUM_RMUL;
777 GSYM REAL_OF_NUM_SUC; SUM_CONST_NUMSEG; ADD_SUB] THEN
780 MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ abs x <= abs y ==> x <= y`) THEN
781 SIMP_TAC[REAL_LE_MUL; NORM_POS_LE; SQRT_POS_LE; REAL_POS] THEN
782 REWRITE_TAC[REAL_LE_SQUARE_ABS; REAL_POW_MUL] THEN
783 SIMP_TAC[SQRT_POW_2; REAL_POS; NORM_POW_2; dot] THEN
784 REWRITE_TAC[GSYM REAL_POW_2] THEN
785 GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_POW2_ABS] THEN
786 ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN REWRITE_TAC[lemma] THEN
787 SIMP_TAC[SUM_POS_LE_NUMSEG; REAL_LE_POW_2]);;
789 (* ------------------------------------------------------------------------- *)
790 (* Squaring equations and inequalities involving norms. *)
791 (* ------------------------------------------------------------------------- *)
793 let DOT_SQUARE_NORM = prove
794 (`!x. x dot x = norm(x) pow 2`,
795 SIMP_TAC[vector_norm; SQRT_POW_2; DOT_POS_LE]);;
797 let NORM_EQ_SQUARE = prove
798 (`!x:real^N. norm(x) = a <=> &0 <= a /\ x dot x = a pow 2`,
799 REWRITE_TAC[DOT_SQUARE_NORM] THEN
800 ONCE_REWRITE_TAC[REAL_RING `x pow 2 = a pow 2 <=> x = a \/ x + a = &0`] THEN
801 GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_POS_LE) THEN REAL_ARITH_TAC);;
803 let NORM_LE_SQUARE = prove
804 (`!x:real^N. norm(x) <= a <=> &0 <= a /\ x dot x <= a pow 2`,
805 REWRITE_TAC[DOT_SQUARE_NORM; GSYM REAL_LE_SQUARE_ABS] THEN
806 GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_POS_LE) THEN REAL_ARITH_TAC);;
808 let NORM_GE_SQUARE = prove
809 (`!x:real^N. norm(x) >= a <=> a <= &0 \/ x dot x >= a pow 2`,
810 REWRITE_TAC[real_ge; DOT_SQUARE_NORM; GSYM REAL_LE_SQUARE_ABS] THEN
811 GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_POS_LE) THEN REAL_ARITH_TAC);;
813 let NORM_LT_SQUARE = prove
814 (`!x:real^N. norm(x) < a <=> &0 < a /\ x dot x < a pow 2`,
815 REWRITE_TAC[REAL_ARITH `x < a <=> ~(x >= a)`; NORM_GE_SQUARE] THEN
818 let NORM_GT_SQUARE = prove
819 (`!x:real^N. norm(x) > a <=> a < &0 \/ x dot x > a pow 2`,
820 REWRITE_TAC[REAL_ARITH `x > a <=> ~(x <= a)`; NORM_LE_SQUARE] THEN
823 let NORM_LT_SQUARE_ALT = prove
824 (`!x:real^N. norm(x) < a <=> &0 <= a /\ x dot x < a pow 2`,
825 REWRITE_TAC[REAL_ARITH `x < a <=> ~(x >= a)`; NORM_GE_SQUARE] THEN
826 REPEAT GEN_TAC THEN ASM_CASES_TAC `a = &0` THENL
827 [ASM_REWRITE_TAC[real_ge] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
828 REWRITE_TAC[DOT_POS_LE];
829 ASM_REAL_ARITH_TAC]);;
831 (* ------------------------------------------------------------------------- *)
832 (* General linear decision procedure for normed spaces. *)
833 (* ------------------------------------------------------------------------- *)
836 let find_normedterms =
837 let augment_norm b tm acc =
839 Comb(Const("vector_norm",_),v) -> insert (b,v) acc
841 let rec find_normedterms tm acc =
843 Comb(Comb(Const("real_add",_),l),r) ->
844 find_normedterms l (find_normedterms r acc)
845 | Comb(Comb(Const("real_mul",_),c),n) ->
846 if not (is_ratconst c) then acc else
847 augment_norm (rat_of_term c >=/ Int 0) n acc
848 | _ -> augment_norm true tm acc in
850 let lincomb_neg t = mapf minus_num t in
851 let lincomb_cmul c t = if c =/ Int 0 then undefined else mapf (( */ ) c) t in
852 let lincomb_add l r = combine (+/) (fun x -> x =/ Int 0) l r in
853 let lincomb_sub l r = lincomb_add l (lincomb_neg r) in
854 let lincomb_eq l r = lincomb_sub l r = undefined in
855 let rec vector_lincomb tm =
857 Comb(Comb(Const("vector_add",_),l),r) ->
858 lincomb_add (vector_lincomb l) (vector_lincomb r)
859 | Comb(Comb(Const("vector_sub",_),l),r) ->
860 lincomb_sub (vector_lincomb l) (vector_lincomb r)
861 | Comb(Comb(Const("%",_),l),r) ->
862 lincomb_cmul (rat_of_term l) (vector_lincomb r)
863 | Comb(Const("vector_neg",_),t) ->
864 lincomb_neg (vector_lincomb t)
865 | Comb(Const("vec",_),n) when is_numeral n & dest_numeral n =/ Int 0 ->
867 | _ -> (tm |=> Int 1) in
868 let vector_lincombs tms =
870 if can (assoc t) fns then fns else
871 let f = vector_lincomb t in
872 try let _,f' = find (fun (_,f') -> lincomb_eq f f') fns in
874 with Failure _ -> (t,f)::fns) tms [] in
875 let rec replacenegnorms fn tm =
877 Comb(Comb(Const("real_add",_),l),r) ->
878 BINOP_CONV (replacenegnorms fn) tm
879 | Comb(Comb(Const("real_mul",_),c),n) when rat_of_term c </ Int 0 ->
883 if defined eq v then (v |-> minus_num(apply eq v)) eq else eq in
884 let rec allsubsets s =
887 | (a::t) -> let res = allsubsets t in
888 map (fun b -> a::b) res @ res in
889 let evaluate env lin =
890 foldr (fun x c s -> s +/ c */ apply env x) lin (Int 0) in
891 let rec solve (vs,eqs) =
893 [],[] -> (0 |=> Int 1)
895 let v = hd(intersect vs (dom eq)) in
896 let c = apply eq v in
897 let vdef = lincomb_cmul (Int(-1) // c) eq in
899 if not(defined eqn v) then eqn else
900 lincomb_add (lincomb_cmul (apply eqn v) vdef) eqn in
901 let soln = solve (subtract vs [v],map eliminate oeqs) in
902 (v |-> evaluate soln (undefine v vdef)) soln in
903 let rec combinations k l =
904 if k = 0 then [[]] else
907 | h::t -> map (fun c -> h::c) (combinations (k - 1) t) @
909 let vertices vs eqs =
911 let soln = solve(vs,cmb) in
912 map (fun v -> tryapplyd soln v (Int 0)) vs in
913 let rawvs = mapfilter vertex (combinations (length vs) eqs) in
914 let unset = filter (forall (fun c -> c >=/ Int 0)) rawvs in
915 itlist (insert' (forall2 (=/))) unset [] in
916 let subsumes l m = forall2 (fun x y -> abs_num x <=/ abs_num y) l m in
917 let rec subsume todo dun =
920 | v::ovs -> let dun' = if exists (fun w -> subsumes w v) dun then dun
921 else v::(filter (fun w -> not(subsumes v w)) dun) in
924 let MATCH_pth = (MATCH_MP o prove)
925 (`!b x. b >= norm(x) ==> !c. abs(c) * b >= norm(c % x)`,
926 SIMP_TAC[NORM_MUL; real_ge; REAL_LE_LMUL; REAL_ABS_POS]) in
927 fun c th -> ISPEC(term_of_rat c) (MATCH_pth th) in
929 let MATCH_pth = (MATCH_MP o prove)
930 (`!b1 b2 x1 x2. b1 >= norm(x1) /\ b2 >= norm(x2)
931 ==> b1 + b2 >= norm(x1 + x2)`,
932 REWRITE_TAC[real_ge] THEN REPEAT STRIP_TAC THEN
933 MATCH_MP_TAC NORM_TRIANGLE_LE THEN ASM_SIMP_TAC[REAL_LE_ADD2]) in
934 fun th1 th2 -> MATCH_pth (CONJ th1 th2) in
935 let INEQUALITY_CANON_RULE =
936 CONV_RULE(LAND_CONV REAL_POLY_CONV) o
937 CONV_RULE(LAND_CONV REAL_RAT_REDUCE_CONV) o
938 GEN_REWRITE_RULE I [REAL_ARITH `s >= t <=> s - t >= &0`] in
939 let NORM_CANON_CONV =
940 let APPLY_pth1 = GEN_REWRITE_CONV I
941 [VECTOR_ARITH `x:real^N = &1 % x`]
942 and APPLY_pth2 = GEN_REWRITE_CONV I
943 [VECTOR_ARITH `x - y:real^N = x + --y`]
944 and APPLY_pth3 = GEN_REWRITE_CONV I
945 [VECTOR_ARITH `--x:real^N = -- &1 % x`]
946 and APPLY_pth4 = GEN_REWRITE_CONV I
947 [VECTOR_ARITH `&0 % x:real^N = vec 0`;
948 VECTOR_ARITH `c % vec 0:real^N = vec 0`]
949 and APPLY_pth5 = GEN_REWRITE_CONV I
950 [VECTOR_ARITH `c % (d % x) = (c * d) % x`]
951 and APPLY_pth6 = GEN_REWRITE_CONV I
952 [VECTOR_ARITH `c % (x + y) = c % x + c % y`]
953 and APPLY_pth7 = GEN_REWRITE_CONV I
954 [VECTOR_ARITH `vec 0 + x = x`;
955 VECTOR_ARITH `x + vec 0 = x`]
957 GEN_REWRITE_CONV I [VECTOR_ARITH `c % x + d % x = (c + d) % x`] THENC
958 LAND_CONV REAL_RAT_ADD_CONV THENC
959 GEN_REWRITE_CONV TRY_CONV [VECTOR_ARITH `&0 % x = vec 0`]
962 [VECTOR_ARITH `(c % x + z) + d % x = (c + d) % x + z`;
963 VECTOR_ARITH `c % x + (d % x + z) = (c + d) % x + z`;
964 VECTOR_ARITH `(c % x + w) + (d % x + z) = (c + d) % x + (w + z)`] THENC
965 LAND_CONV(LAND_CONV REAL_RAT_ADD_CONV)
967 GEN_REWRITE_CONV I [VECTOR_ARITH `&0 % x + y = y`]
970 [VECTOR_ARITH `c % x + d % y = c % x + d % y`;
971 VECTOR_ARITH `(c % x + z) + d % y = c % x + (z + d % y)`;
972 VECTOR_ARITH `c % x + (d % y + z) = c % x + (d % y + z)`;
973 VECTOR_ARITH `(c % x + w) + (d % y + z) = c % x + (w + (d % y + z))`]
976 [VECTOR_ARITH `c % x + d % y = d % y + c % x`;
977 VECTOR_ARITH `(c % x + z) + d % y = d % y + (c % x + z)`;
978 VECTOR_ARITH `c % x + (d % y + z) = d % y + (c % x + z)`;
979 VECTOR_ARITH `(c % x + w) + (d % y + z) = d % y + ((c % x + w) + z)`]
981 GEN_REWRITE_CONV TRY_CONV
982 [VECTOR_ARITH `x + vec 0 = x`] in
985 Comb(Comb(Const("vector_add",_),Comb(Comb(Const("%",_),l),v)),r) -> v
986 | Comb(Comb(Const("%",_),l),v) -> v
987 | _ -> failwith "headvector: non-canonical term" in
988 let rec VECTOR_CMUL_CONV tm =
989 ((APPLY_pth5 THENC LAND_CONV REAL_RAT_MUL_CONV) ORELSEC
990 (APPLY_pth6 THENC BINOP_CONV VECTOR_CMUL_CONV)) tm
991 and VECTOR_ADD_CONV tm =
992 try APPLY_pth7 tm with Failure _ ->
993 try APPLY_pth8 tm with Failure _ ->
995 Comb(Comb(Const("vector_add",_),lt),rt) ->
996 let l = headvector lt and r = headvector rt in
997 if l < r then (APPLY_pthb THENC
998 RAND_CONV VECTOR_ADD_CONV THENC
1000 else if r < l then (APPLY_pthc THENC
1001 RAND_CONV VECTOR_ADD_CONV THENC
1004 ((APPLY_ptha THENC VECTOR_ADD_CONV) ORELSEC
1005 RAND_CONV VECTOR_ADD_CONV THENC
1008 let rec VECTOR_CANON_CONV tm =
1010 Comb(Comb(Const("vector_add",_),l),r) ->
1011 let lth = VECTOR_CANON_CONV l and rth = VECTOR_CANON_CONV r in
1012 let th = MK_COMB(AP_TERM (rator(rator tm)) lth,rth) in
1013 CONV_RULE (RAND_CONV VECTOR_ADD_CONV) th
1014 | Comb(Comb(Const("%",_),l),r) ->
1015 let rth = AP_TERM (rator tm) (VECTOR_CANON_CONV r) in
1016 CONV_RULE (RAND_CONV(APPLY_pth4 ORELSEC VECTOR_CMUL_CONV)) rth
1017 | Comb(Comb(Const("vector_sub",_),l),r) ->
1018 (APPLY_pth2 THENC VECTOR_CANON_CONV) tm
1019 | Comb(Const("vector_neg",_),t) ->
1020 (APPLY_pth3 THENC VECTOR_CANON_CONV) tm
1021 | Comb(Const("vec",_),n) when is_numeral n & dest_numeral n =/ Int 0 ->
1023 | _ -> APPLY_pth1 tm in
1026 Comb(Const("vector_norm",_),e) -> RAND_CONV VECTOR_CANON_CONV tm
1027 | _ -> failwith "NORM_CANON_CONV" in
1028 let REAL_VECTOR_COMBO_PROVER =
1029 let pth_zero = prove(`norm(vec 0:real^N) = &0`,REWRITE_TAC[NORM_0])
1030 and tv_n = mk_vartype "N" in
1031 fun translator (nubs,ges,gts) ->
1032 let sources = map (rand o rand o concl) nubs
1033 and rawdests = itlist (find_normedterms o lhand o concl) (ges @ gts) [] in
1034 if not (forall fst rawdests) then failwith "Sanity check" else
1035 let dests = setify (map snd rawdests) in
1036 let srcfuns = map vector_lincomb sources
1037 and destfuns = map vector_lincomb dests in
1038 let vvs = itlist (union o dom) (srcfuns @ destfuns) [] in
1039 let n = length srcfuns in
1041 let srccombs = zip srcfuns nvs in
1043 let coefficients x =
1044 let inp = if defined d x then 0 |=> minus_num(apply d x)
1046 itlist (fun (f,v) g -> if defined f x then (v |-> apply f x) g else g)
1048 let equations = map coefficients vvs
1049 and inequalities = map (fun n -> (n |=> Int 1)) nvs in
1050 let plausiblevertices f =
1051 let flippedequations = map (itlist flip f) equations in
1052 let constraints = flippedequations @ inequalities in
1053 let rawverts = vertices nvs constraints in
1054 let check_solution v =
1055 let f = itlist2 (|->) nvs v (0 |=> Int 1) in
1056 forall (fun e -> evaluate f e =/ Int 0) flippedequations in
1057 let goodverts = filter check_solution rawverts in
1058 let signfixups = map (fun n -> if mem n f then -1 else 1) nvs in
1059 map (map2 (fun s c -> Int s */ c) signfixups) goodverts in
1060 let allverts = itlist (@) (map plausiblevertices (allsubsets nvs)) [] in
1061 subsume allverts [] in
1062 let compute_ineq v =
1063 let ths = mapfilter (fun (v,t) -> if v =/ Int 0 then fail()
1064 else NORM_CMUL_RULE v t)
1066 INEQUALITY_CANON_RULE (end_itlist NORM_ADD_RULE ths) in
1067 let ges' = mapfilter compute_ineq (itlist ((@) o consider) destfuns []) @
1068 map INEQUALITY_CANON_RULE nubs @ ges in
1069 let zerodests = filter
1070 (fun t -> dom(vector_lincomb t) = []) (map snd rawdests) in
1071 REAL_LINEAR_PROVER translator
1072 (map (fun t -> INST_TYPE [last(snd(dest_type(type_of t))),tv_n] pth_zero)
1074 map (CONV_RULE(ONCE_DEPTH_CONV NORM_CANON_CONV THENC
1075 LAND_CONV REAL_POLY_CONV)) ges',
1076 map (CONV_RULE(ONCE_DEPTH_CONV NORM_CANON_CONV THENC
1077 LAND_CONV REAL_POLY_CONV)) gts) in
1078 let REAL_VECTOR_INEQ_PROVER =
1080 (`norm(x) = n ==> norm(x) >= &0 /\ n >= norm(x)`,
1081 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
1082 REWRITE_TAC[real_ge; NORM_POS_LE] THEN REAL_ARITH_TAC) in
1083 let NORM_MP = MATCH_MP pth in
1084 fun translator (ges,gts) ->
1085 let ntms = itlist find_normedterms (map (lhand o concl) (ges @ gts)) [] in
1086 let lctab = vector_lincombs (map snd (filter (not o fst) ntms)) in
1087 let asl = map (fun (t,_) ->
1088 ASSUME(mk_eq(mk_icomb(mk_const("vector_norm",[]),t),
1089 genvar `:real`))) lctab in
1090 let replace_conv = GEN_REWRITE_CONV TRY_CONV asl in
1091 let replace_rule = CONV_RULE (LAND_CONV (replacenegnorms replace_conv)) in
1093 itlist (fun th ths -> CONJUNCT1(NORM_MP th)::ths)
1094 asl (map replace_rule ges)
1095 and gts' = map replace_rule gts
1096 and nubs = map (CONJUNCT2 o NORM_MP) asl in
1097 let th1 = REAL_VECTOR_COMBO_PROVER translator (nubs,ges',gts') in
1099 (map (fun th -> let l,r = dest_eq(concl th) in (l,r)) asl) th1 in
1100 itlist PROVE_HYP (map (REFL o lhand o concl) asl) th2 in
1101 let REAL_VECTOR_PROVER =
1103 GEN_REWRITE_RULE I [REAL_ARITH `x = &0 <=> x >= &0 /\ --x >= &0`] in
1104 let splitequation th acc =
1105 let th1,th2 = CONJ_PAIR(rawrule th) in
1106 th1::CONV_RULE(LAND_CONV REAL_POLY_NEG_CONV) th2::acc in
1107 fun translator (eqs,ges,gts) ->
1108 REAL_VECTOR_INEQ_PROVER translator
1109 (itlist splitequation eqs ges,gts) in
1111 (`(!x y:real^N. x = y <=> norm(x - y) <= &0) /\
1112 (!x y:real^N. ~(x = y) <=> ~(norm(x - y) <= &0))`,
1113 REWRITE_TAC[NORM_LE_0; VECTOR_SUB_EQ]) in
1114 let conv1 = GEN_REWRITE_CONV TRY_CONV [pth] in
1115 let conv2 tm = (conv1 tm,conv1(mk_neg tm)) in
1116 let init = GEN_REWRITE_CONV ONCE_DEPTH_CONV [DECIMAL] THENC
1117 REAL_RAT_REDUCE_CONV THENC
1118 GEN_REWRITE_CONV ONCE_DEPTH_CONV [dist] THENC
1119 GEN_NNF_CONV true (conv1,conv2)
1120 and pure = GEN_REAL_ARITH REAL_VECTOR_PROVER in
1121 fun tm -> let th = init tm in EQ_MP (SYM th) (pure(rand(concl th)));;
1123 let NORM_ARITH_TAC = CONV_TAC NORM_ARITH;;
1125 let ASM_NORM_ARITH_TAC =
1126 REPEAT(FIRST_X_ASSUM(MP_TAC o check (not o is_forall o concl))) THEN
1129 (* ------------------------------------------------------------------------- *)
1130 (* Dot product in terms of the norm rather than conversely. *)
1131 (* ------------------------------------------------------------------------- *)
1133 let DOT_NORM = prove
1134 (`!x y. x dot y = (norm(x + y) pow 2 - norm(x) pow 2 - norm(y) pow 2) / &2`,
1135 REWRITE_TAC[NORM_POW_2; DOT_LADD; DOT_RADD; DOT_SYM] THEN REAL_ARITH_TAC);;
1137 let DOT_NORM_NEG = prove
1138 (`!x y. x dot y = ((norm(x) pow 2 + norm(y) pow 2) - norm(x - y) pow 2) / &2`,
1139 REWRITE_TAC[NORM_POW_2; DOT_LADD; DOT_RADD; DOT_LSUB; DOT_RSUB; DOT_SYM] THEN
1142 let DOT_NORM_SUB = prove
1143 (`!x y. x dot y = ((norm(x) pow 2 + norm(y) pow 2) - norm(x - y) pow 2) / &2`,
1144 REWRITE_TAC[NORM_POW_2; DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REAL_ARITH_TAC);;
1146 (* ------------------------------------------------------------------------- *)
1147 (* Equality of vectors in terms of dot products. *)
1148 (* ------------------------------------------------------------------------- *)
1150 let VECTOR_EQ = prove
1151 (`!x y. (x = y) <=> (x dot x = x dot y) /\ (y dot y = x dot x)`,
1152 REPEAT GEN_TAC THEN EQ_TAC THENL [SIMP_TAC[]; ALL_TAC] THEN
1153 ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
1154 REWRITE_TAC[GSYM DOT_EQ_0] THEN
1155 SIMP_TAC[DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REAL_ARITH_TAC);;
1157 (* ------------------------------------------------------------------------- *)
1158 (* Hence more metric properties. *)
1159 (* ------------------------------------------------------------------------- *)
1161 let DIST_REFL = prove
1162 (`!x. dist(x,x) = &0`,
1165 let DIST_SYM = prove
1166 (`!x y. dist(x,y) = dist(y,x)`,
1169 let DIST_POS_LE = prove
1170 (`!x y. &0 <= dist(x,y)`,
1173 let DIST_TRIANGLE = prove
1174 (`!x:real^N y z. dist(x,z) <= dist(x,y) + dist(y,z)`,
1177 let DIST_TRIANGLE_ALT = prove
1178 (`!x y z. dist(y,z) <= dist(x,y) + dist(x,z)`,
1181 let DIST_EQ_0 = prove
1182 (`!x y. (dist(x,y) = &0) <=> (x = y)`,
1185 let DIST_POS_LT = prove
1186 (`!x y. ~(x = y) ==> &0 < dist(x,y)`,
1190 (`!x y. ~(x = y) <=> &0 < dist(x,y)`,
1193 let DIST_TRIANGLE_LE = prove
1194 (`!x y z e. dist(x,z) + dist(y,z) <= e ==> dist(x,y) <= e`,
1197 let DIST_TRIANGLE_LT = prove
1198 (`!x y z e. dist(x,z) + dist(y,z) < e ==> dist(x,y) < e`,
1201 let DIST_TRIANGLE_HALF_L = prove
1202 (`!x1 x2 y. dist(x1,y) < e / &2 /\ dist(x2,y) < e / &2 ==> dist(x1,x2) < e`,
1205 let DIST_TRIANGLE_HALF_R = prove
1206 (`!x1 x2 y. dist(y,x1) < e / &2 /\ dist(y,x2) < e / &2 ==> dist(x1,x2) < e`,
1209 let DIST_TRIANGLE_ADD = prove
1210 (`!x x' y y'. dist(x + y,x' + y') <= dist(x,x') + dist(y,y')`,
1213 let DIST_MUL = prove
1214 (`!x y c. dist(c % x,c % y) = abs(c) * dist(x,y)`,
1215 REWRITE_TAC[dist; GSYM VECTOR_SUB_LDISTRIB; NORM_MUL]);;
1217 let DIST_TRIANGLE_ADD_HALF = prove
1218 (`!x x' y y':real^N.
1219 dist(x,x') < e / &2 /\ dist(y,y') < e / &2 ==> dist(x + y,x' + y') < e`,
1222 let DIST_LE_0 = prove
1223 (`!x y. dist(x,y) <= &0 <=> x = y`,
1227 (`!w x y z. dist(w,x) = dist(y,z) <=> dist(w,x) pow 2 = dist(y,z) pow 2`,
1228 REWRITE_TAC[dist; NORM_POW_2; NORM_EQ]);;
1231 (`!x. dist(x,vec 0) = norm(x) /\ dist(vec 0,x) = norm(x)`,
1234 (* ------------------------------------------------------------------------- *)
1235 (* Sums of vectors. *)
1236 (* ------------------------------------------------------------------------- *)
1238 let NEUTRAL_VECTOR_ADD = prove
1239 (`neutral(+) = vec 0:real^N`,
1240 REWRITE_TAC[neutral] THEN MATCH_MP_TAC SELECT_UNIQUE THEN
1241 REWRITE_TAC[VECTOR_ARITH `x + y = y <=> x = vec 0`;
1242 VECTOR_ARITH `x + y = x <=> y = vec 0`]);;
1244 let MONOIDAL_VECTOR_ADD = prove
1245 (`monoidal((+):real^N->real^N->real^N)`,
1246 REWRITE_TAC[monoidal; NEUTRAL_VECTOR_ADD] THEN
1247 REPEAT CONJ_TAC THEN VECTOR_ARITH_TAC);;
1249 let vsum = new_definition
1250 `(vsum:(A->bool)->(A->real^N)->real^N) s f = lambda i. sum s (\x. f(x)$i)`;;
1252 let VSUM_CLAUSES = prove
1253 (`(!f. vsum {} f = vec 0) /\
1255 ==> (vsum (x INSERT s) f =
1256 if x IN s then vsum s f else f(x) + vsum s f))`,
1257 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; SUM_CLAUSES] THEN
1258 SIMP_TAC[VEC_COMPONENT] THEN REPEAT STRIP_TAC THEN
1259 COND_CASES_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_COMPONENT]);;
1262 (`!f s. FINITE s ==> vsum s f = iterate (+) s f`,
1263 GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1264 ASM_SIMP_TAC[VSUM_CLAUSES; ITERATE_CLAUSES; MONOIDAL_VECTOR_ADD] THEN
1265 REWRITE_TAC[NEUTRAL_VECTOR_ADD]);;
1267 let VSUM_EQ_0 = prove
1268 (`!f s. (!x:A. x IN s ==> (f(x) = vec 0)) ==> (vsum s f = vec 0)`,
1269 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; vec; SUM_EQ_0]);;
1272 (`vsum s (\x. vec 0) = vec 0`,
1273 SIMP_TAC[VSUM_EQ_0]);;
1275 let VSUM_LMUL = prove
1276 (`!f c s. vsum s (\x. c % f(x)) = c % vsum s f`,
1277 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_MUL_COMPONENT; SUM_LMUL]);;
1279 let VSUM_RMUL = prove
1280 (`!c s v. vsum s (\x. c x % v) = (sum s c) % v`,
1281 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_MUL_COMPONENT; SUM_RMUL]);;
1283 let VSUM_ADD = prove
1284 (`!f g s. FINITE s ==> (vsum s (\x. f x + g x) = vsum s f + vsum s g)`,
1285 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; SUM_ADD]);;
1287 let VSUM_SUB = prove
1288 (`!f g s. FINITE s ==> (vsum s (\x. f x - g x) = vsum s f - vsum s g)`,
1289 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_SUB_COMPONENT; SUM_SUB]);;
1291 let VSUM_CONST = prove
1292 (`!c s. FINITE s ==> (vsum s (\n. c) = &(CARD s) % c)`,
1293 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_CONST; VECTOR_MUL_COMPONENT]);;
1295 let VSUM_COMPONENT = prove
1296 (`!s f i. 1 <= i /\ i <= dimindex(:N)
1297 ==> ((vsum s (f:A->real^N))$i = sum s (\x. f(x)$i))`,
1298 SIMP_TAC[vsum; LAMBDA_BETA]);;
1300 let VSUM_IMAGE = prove
1301 (`!f g s. FINITE s /\ (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
1302 ==> (vsum (IMAGE f s) g = vsum s (g o f))`,
1303 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN REPEAT STRIP_TAC THEN
1304 W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhs o snd) THEN
1305 ASM_REWRITE_TAC[o_DEF]);;
1307 let VSUM_UNION = prove
1308 (`!f s t. FINITE s /\ FINITE t /\ DISJOINT s t
1309 ==> (vsum (s UNION t) f = vsum s f + vsum t f)`,
1310 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_UNION; VECTOR_ADD_COMPONENT]);;
1312 let VSUM_DIFF = prove
1313 (`!f s t. FINITE s /\ t SUBSET s
1314 ==> (vsum (s DIFF t) f = vsum s f - vsum t f)`,
1315 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_DIFF; VECTOR_SUB_COMPONENT]);;
1317 let VSUM_DELETE = prove
1318 (`!f s a. FINITE s /\ a IN s
1319 ==> vsum (s DELETE a) f = vsum s f - f a`,
1320 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_DELETE; VECTOR_SUB_COMPONENT]);;
1322 let VSUM_INCL_EXCL = prove
1323 (`!s t (f:A->real^N).
1324 FINITE s /\ FINITE t
1325 ==> vsum s f + vsum t f = vsum (s UNION t) f + vsum (s INTER t) f`,
1326 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN
1327 SIMP_TAC[SUM_INCL_EXCL]);;
1329 let VSUM_NEG = prove
1330 (`!f s. vsum s (\x. --f x) = --vsum s f`,
1331 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_NEG; VECTOR_NEG_COMPONENT]);;
1334 (`!f g s. (!x. x IN s ==> (f x = g x)) ==> (vsum s f = vsum s g)`,
1335 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN
1336 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC[]);;
1338 let VSUM_SUPERSET = prove
1340 u SUBSET v /\ (!x. x IN v /\ ~(x IN u) ==> (f(x) = vec 0))
1341 ==> (vsum v f = vsum u f)`,
1342 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_SUPERSET]);;
1344 let VSUM_EQ_SUPERSET = prove
1346 FINITE t /\ t SUBSET s /\
1347 (!x. x IN t ==> (f x = g x)) /\
1348 (!x. x IN s /\ ~(x IN t) ==> f(x) = vec 0)
1349 ==> vsum s f = vsum t g`,
1350 MESON_TAC[VSUM_SUPERSET; VSUM_EQ]);;
1352 let VSUM_UNION_RZERO = prove
1354 FINITE u /\ (!x. x IN v /\ ~(x IN u) ==> (f(x) = vec 0))
1355 ==> (vsum (u UNION v) f = vsum u f)`,
1356 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_UNION_RZERO]);;
1358 let VSUM_UNION_LZERO = prove
1360 FINITE v /\ (!x. x IN u /\ ~(x IN v) ==> (f(x) = vec 0))
1361 ==> (vsum (u UNION v) f = vsum v f)`,
1362 MESON_TAC[VSUM_UNION_RZERO; UNION_COMM]);;
1364 let VSUM_RESTRICT = prove
1366 ==> (vsum s (\x. if x IN s then f(x) else vec 0) = vsum s f)`,
1367 REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ THEN ASM_SIMP_TAC[]);;
1369 let VSUM_RESTRICT_SET = prove
1370 (`!P s f. vsum {x | x IN s /\ P x} f =
1371 vsum s (\x. if P x then f x else vec 0)`,
1372 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_RESTRICT_SET;
1375 let VSUM_CASES = prove
1376 (`!s P f g. FINITE s
1377 ==> vsum s (\x:A. if P x then (f x):real^N else g x) =
1378 vsum {x | x IN s /\ P x} f + vsum {x | x IN s /\ ~P x} g`,
1379 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; SUM_CASES;
1382 let VSUM_SING = prove
1383 (`!f x. vsum {x} f = f(x)`,
1384 SIMP_TAC[VSUM_CLAUSES; FINITE_RULES; NOT_IN_EMPTY; VECTOR_ADD_RID]);;
1386 let VSUM_NORM = prove
1387 (`!f s. FINITE s ==> norm(vsum s f) <= sum s (\x. norm(f x))`,
1388 GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1389 SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; NORM_0; REAL_LE_REFL] THEN
1392 let VSUM_NORM_LE = prove
1394 FINITE s /\ (!x. x IN s ==> norm(f x) <= g(x))
1395 ==> norm(vsum s f) <= sum s g`,
1396 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
1397 EXISTS_TAC `sum s (\x:A. norm(f x :real^N))` THEN
1398 ASM_SIMP_TAC[VSUM_NORM; SUM_LE]);;
1400 let VSUM_NORM_TRIANGLE = prove
1401 (`!s f b. FINITE s /\ sum s (\a. norm(f a)) <= b
1402 ==> norm(vsum s f) <= b`,
1403 MESON_TAC[VSUM_NORM; REAL_LE_TRANS]);;
1405 let VSUM_NORM_BOUND = prove
1406 (`!s f b. FINITE s /\ (!x:A. x IN s ==> norm(f(x)) <= b)
1407 ==> norm(vsum s f) <= &(CARD s) * b`,
1408 SIMP_TAC[GSYM SUM_CONST; VSUM_NORM_LE]);;
1410 let VSUM_CLAUSES_NUMSEG = prove
1411 (`(!m. vsum(m..0) f = if m = 0 then f(0) else vec 0) /\
1412 (!m n. vsum(m..SUC n) f = if m <= SUC n then vsum(m..n) f + f(SUC n)
1413 else vsum(m..n) f)`,
1414 REWRITE_TAC[NUMSEG_CLAUSES] THEN REPEAT STRIP_TAC THEN
1416 ASM_SIMP_TAC[VSUM_SING; VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG] THEN
1417 REWRITE_TAC[ARITH_RULE `~(SUC n <= n)`; VECTOR_ADD_AC]);;
1419 let VSUM_CLAUSES_RIGHT = prove
1420 (`!f m n. 0 < n /\ m <= n ==> vsum(m..n) f = vsum(m..n-1) f + (f n):real^N`,
1421 GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN
1422 SIMP_TAC[LT_REFL; VSUM_CLAUSES_NUMSEG; SUC_SUB1]);;
1424 let VSUM_CMUL_NUMSEG = prove
1425 (`!f c m n. vsum (m..n) (\x. c % f x) = c % vsum (m..n) f`,
1426 SIMP_TAC[VSUM_LMUL; FINITE_NUMSEG]);;
1428 let VSUM_EQ_NUMSEG = prove
1430 (!x. m <= x /\ x <= n ==> (f x = g x))
1431 ==> (vsum(m .. n) f = vsum(m .. n) g)`,
1432 REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
1433 ASM_SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG]);;
1435 let VSUM_IMAGE_GEN = prove
1439 vsum (IMAGE f s) (\y. vsum {x | x IN s /\ (f(x) = y)} g))`,
1440 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_IMAGE_GEN]);;
1442 let VSUM_GROUP = prove
1444 FINITE s /\ IMAGE f s SUBSET t
1445 ==> vsum t (\y. vsum {x | x IN s /\ f(x) = y} g) = vsum s g`,
1446 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_GROUP]);;
1448 let VSUM_VMUL = prove
1449 (`!f v s. FINITE s ==> ((sum s f) % v = vsum s (\x. f(x) % v))`,
1450 GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1451 ASM_SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES] THEN
1452 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_RDISTRIB] THEN
1455 let VSUM_DELTA = prove
1456 (`!s a. vsum s (\x. if x = a then b else vec 0) =
1457 if a IN s then b else vec 0`,
1458 SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; COND_COMPONENT] THEN
1459 SIMP_TAC[VEC_COMPONENT; SUM_DELTA]);;
1461 let VSUM_ADD_NUMSEG = prove
1462 (`!f g m n. vsum(m..n) (\i. f i + g i) = vsum(m..n) f + vsum(m..n) g`,
1463 SIMP_TAC[VSUM_ADD; FINITE_NUMSEG]);;
1465 let VSUM_SUB_NUMSEG = prove
1466 (`!f g m n. vsum(m..n) (\i. f i - g i) = vsum(m..n) f - vsum(m..n) g`,
1467 SIMP_TAC[VSUM_SUB; FINITE_NUMSEG]);;
1469 let VSUM_ADD_SPLIT = prove
1471 m <= n + 1 ==> vsum(m..n + p) f = vsum(m..n) f + vsum(n + 1..n + p) f`,
1472 SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; VECTOR_ADD_COMPONENT;
1475 let VSUM_VSUM_PRODUCT = prove
1476 (`!s:A->bool t:A->B->bool x.
1477 FINITE s /\ (!i. i IN s ==> FINITE(t i))
1478 ==> vsum s (\i. vsum (t i) (x i)) =
1479 vsum {i,j | i IN s /\ j IN t i} (\(i,j). x i j)`,
1480 SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; COND_COMPONENT] THEN
1481 SIMP_TAC[SUM_SUM_PRODUCT] THEN REPEAT STRIP_TAC THEN AP_TERM_TAC THEN
1482 REWRITE_TAC[FUN_EQ_THM; FORALL_PAIR_THM]);;
1484 let VSUM_IMAGE_NONZERO = prove
1485 (`!d:B->real^N i:A->B s.
1487 (!x y. x IN s /\ y IN s /\ ~(x = y) /\ i x = i y ==> d(i x) = vec 0)
1488 ==> vsum (IMAGE i s) d = vsum s (d o i)`,
1489 GEN_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN
1490 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1491 SIMP_TAC[IMAGE_CLAUSES; VSUM_CLAUSES; FINITE_IMAGE] THEN
1492 MAP_EVERY X_GEN_TAC [`a:A`; `s:A->bool`] THEN
1493 REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN
1494 SUBGOAL_THEN `vsum s ((d:B->real^N) o (i:A->B)) = vsum (IMAGE i s) d`
1495 SUBST1_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
1496 COND_CASES_TAC THEN ASM_REWRITE_TAC[o_THM] THEN
1497 REWRITE_TAC[VECTOR_ARITH `a = x + a <=> x = vec 0`] THEN
1498 ASM_MESON_TAC[IN_IMAGE]);;
1500 let VSUM_UNION_NONZERO = prove
1501 (`!f s t. FINITE s /\ FINITE t /\ (!x. x IN s INTER t ==> f(x) = vec 0)
1502 ==> vsum (s UNION t) f = vsum s f + vsum t f`,
1503 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN
1504 SIMP_TAC[VEC_COMPONENT; SUM_UNION_NONZERO]);;
1506 let VSUM_UNIONS_NONZERO = prove
1507 (`!f s. FINITE s /\ (!t:A->bool. t IN s ==> FINITE t) /\
1508 (!t1 t2 x. t1 IN s /\ t2 IN s /\ ~(t1 = t2) /\ x IN t1 /\ x IN t2
1510 ==> vsum (UNIONS s) f = vsum s (\t. vsum t f)`,
1511 GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN
1512 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1513 REWRITE_TAC[UNIONS_0; UNIONS_INSERT; VSUM_CLAUSES; IN_INSERT] THEN
1514 MAP_EVERY X_GEN_TAC [`t:A->bool`; `s:(A->bool)->bool`] THEN
1515 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
1516 ONCE_REWRITE_TAC[IMP_CONJ] THEN ASM_SIMP_TAC[VSUM_CLAUSES] THEN
1517 ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN(SUBST_ALL_TAC o SYM)] THEN
1518 STRIP_TAC THEN MATCH_MP_TAC VSUM_UNION_NONZERO THEN
1519 ASM_SIMP_TAC[FINITE_UNIONS; IN_INTER; IN_UNIONS] THEN ASM_MESON_TAC[]);;
1521 let VSUM_CLAUSES_LEFT = prove
1522 (`!f m n. m <= n ==> vsum(m..n) f = f m + vsum(m + 1..n) f`,
1523 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN
1524 SIMP_TAC[VEC_COMPONENT; SUM_CLAUSES_LEFT]);;
1526 let VSUM_DIFFS = prove
1527 (`!m n. vsum(m..n) (\k. f(k) - f(k + 1)) =
1528 if m <= n then f(m) - f(n + 1) else vec 0`,
1529 GEN_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC[VSUM_CLAUSES_NUMSEG; LE] THEN
1530 ASM_CASES_TAC `m = SUC n` THEN
1531 ASM_REWRITE_TAC[ARITH_RULE `~(SUC n <= n)`; VECTOR_ADD_LID] THEN
1532 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
1533 REWRITE_TAC[GSYM ADD1] THEN VECTOR_ARITH_TAC);;
1535 let VSUM_DIFFS_ALT = prove
1536 (`!m n. vsum(m..n) (\k. f(k + 1) - f(k)) =
1537 if m <= n then f(n + 1) - f(m) else vec 0`,
1538 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_NEG_SUB] THEN
1539 SIMP_TAC[VSUM_NEG; VSUM_DIFFS] THEN
1540 COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_NEG_SUB; VECTOR_NEG_0]);;
1542 let VSUM_DELETE_CASES = prove
1545 ==> vsum(s DELETE x) f = if x IN s then vsum s f - f x else vsum s f`,
1546 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
1547 ASM_SIMP_TAC[SET_RULE `~(x IN s) ==> s DELETE x = s`] THEN
1548 FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV)
1549 [MATCH_MP (SET_RULE `x IN s ==> s = x INSERT (s DELETE x)`) th]) THEN
1550 ASM_SIMP_TAC[VSUM_CLAUSES; FINITE_DELETE; IN_DELETE] THEN VECTOR_ARITH_TAC);;
1552 let VSUM_EQ_GENERAL = prove
1553 (`!s:A->bool t:B->bool (f:A->real^N) g h.
1554 (!y. y IN t ==> ?!x. x IN s /\ h x = y) /\
1555 (!x. x IN s ==> h x IN t /\ g(h x) = f x)
1556 ==> vsum s f = vsum t g`,
1557 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN
1558 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_GENERAL THEN
1559 EXISTS_TAC `h:A->B` THEN ASM_MESON_TAC[]);;
1561 let VSUM_EQ_GENERAL_INVERSES = prove
1562 (`!s t (f:A->real^N) (g:B->real^N) h k.
1563 (!y. y IN t ==> k y IN s /\ h (k y) = y) /\
1564 (!x. x IN s ==> h x IN t /\ k (h x) = x /\ g (h x) = f x)
1565 ==> vsum s f = vsum t g`,
1566 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN
1567 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_GENERAL_INVERSES THEN
1568 MAP_EVERY EXISTS_TAC [`h:A->B`; `k:B->A`] THEN ASM_MESON_TAC[]);;
1570 let VSUM_NORM_ALLSUBSETS_BOUND = prove
1573 (!q. q SUBSET p ==> norm(vsum q f) <= e)
1574 ==> sum p (\x. norm(f x)) <= &2 * &(dimindex(:N)) * e`,
1575 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
1577 `sum p (\x:A. sum (1..dimindex(:N)) (\i. abs((f x:real^N)$i)))` THEN
1579 [MATCH_MP_TAC SUM_LE THEN ASM_SIMP_TAC[NORM_LE_L1]; ALL_TAC] THEN
1580 W(MP_TAC o PART_MATCH (lhand o rand) SUM_SWAP o lhand o snd) THEN
1581 ASM_REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST1_TAC THEN
1582 ONCE_REWRITE_TAC[REAL_ARITH `&2 * &n * e = &n * &2 * e`] THEN
1583 GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o RAND_CONV)
1584 [GSYM CARD_NUMSEG_1] THEN
1585 MATCH_MP_TAC SUM_BOUND THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
1586 X_GEN_TAC `k:num` THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
1587 EXISTS_TAC `sum {x:A | x IN p /\ &0 <= (f x:real^N)$k} (\x. abs((f x)$k)) +
1588 sum {x | x IN p /\ (f x)$k < &0} (\x. abs((f x)$k))` THEN
1590 [MATCH_MP_TAC(REAL_ARITH `a = b ==> b <= a`) THEN
1591 MATCH_MP_TAC SUM_UNION_EQ THEN
1592 ASM_SIMP_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_UNION; IN_ELIM_THM] THEN
1593 CONJ_TAC THEN X_GEN_TAC `x:A` THEN ASM_CASES_TAC `(x:A) IN p` THEN
1594 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
1596 MATCH_MP_TAC(REAL_ARITH `x <= e /\ y <= e ==> x + y <= &2 * e`) THEN
1597 GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_ABS_NEG] THEN
1598 CONJ_TAC THEN MATCH_MP_TAC(REAL_ARITH
1599 `!g. sum s g = sum s f /\ sum s g <= e ==> sum s f <= e`)
1601 [EXISTS_TAC `\x. ((f:A->real^N) x)$k`;
1602 EXISTS_TAC `\x. --(((f:A->real^N) x)$k)`] THEN
1604 [MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[IN_ELIM_THM] THEN REAL_ARITH_TAC;
1606 ASM_SIMP_TAC[GSYM VSUM_COMPONENT; SUM_NEG; FINITE_RESTRICT] THEN
1607 MATCH_MP_TAC(REAL_ARITH `abs(x) <= e ==> x <= e`) THEN
1608 REWRITE_TAC[REAL_ABS_NEG] THEN
1609 MATCH_MP_TAC(REAL_ARITH
1610 `abs((vsum q f)$k) <= norm(vsum q f) /\
1612 ==> abs((vsum q f)$k) <= e`) THEN
1613 ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
1614 FIRST_X_ASSUM MATCH_MP_TAC THEN SET_TAC[]);;
1616 let DOT_LSUM = prove
1617 (`!s f y. FINITE s ==> (vsum s f) dot y = sum s (\x. f(x) dot y)`,
1618 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
1619 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1620 ASM_SIMP_TAC[VSUM_CLAUSES; SUM_CLAUSES; DOT_LZERO; DOT_LADD]);;
1622 let DOT_RSUM = prove
1623 (`!s f x. FINITE s ==> x dot (vsum s f) = sum s (\y. x dot f(y))`,
1624 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
1625 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1626 ASM_SIMP_TAC[VSUM_CLAUSES; SUM_CLAUSES; DOT_RZERO; DOT_RADD]);;
1628 let VSUM_OFFSET = prove
1629 (`!f m p. vsum(m + p..n + p) f = vsum(m..n) (\i. f (i + p))`,
1630 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_OFFSET]);;
1632 let VSUM_OFFSET_0 = prove
1633 (`!f m n. m <= n ==> vsum(m..n) f = vsum(0..n - m) (\i. f (i + m))`,
1634 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_OFFSET_0]);;
1636 let VSUM_TRIV_NUMSEG = prove
1637 (`!f m n. n < m ==> vsum(m..n) f = vec 0`,
1638 SIMP_TAC[GSYM NUMSEG_EMPTY; VSUM_CLAUSES]);;
1640 let VSUM_CONST_NUMSEG = prove
1641 (`!c m n. vsum(m..n) (\n. c) = &((n + 1) - m) % c`,
1642 SIMP_TAC[VSUM_CONST; FINITE_NUMSEG; CARD_NUMSEG]);;
1644 let VSUM_SUC = prove
1645 (`!f m n. vsum (SUC n..SUC m) f = vsum (n..m) (f o SUC)`,
1647 SUBGOAL_THEN `SUC n..SUC m = IMAGE SUC (n..m)` SUBST1_TAC THENL
1648 [REWRITE_TAC [ADD1; NUMSEG_OFFSET_IMAGE] THEN
1649 REWRITE_TAC [ONE; ADD_SUC; ADD_0; ETA_AX];
1650 SIMP_TAC [VSUM_IMAGE; FINITE_NUMSEG; SUC_INJ]]);;
1652 let VSUM_BIJECTION = prove
1653 (`!f:A->real^N p s:A->bool.
1654 (!x. x IN s ==> p(x) IN s) /\
1655 (!y. y IN s ==> ?!x. x IN s /\ p(x) = y)
1656 ==> vsum s f = vsum s (f o p)`,
1657 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
1658 MATCH_MP_TAC VSUM_EQ_GENERAL THEN EXISTS_TAC `p:A->A` THEN
1659 ASM_REWRITE_TAC[o_THM]);;
1661 let VSUM_PARTIAL_SUC = prove
1662 (`!f g:num->real^N m n.
1663 vsum (m..n) (\k. f(k) % (g(k + 1) - g(k))) =
1664 if m <= n then f(n + 1) % g(n + 1) - f(m) % g(m) -
1665 vsum (m..n) (\k. (f(k + 1) - f(k)) % g(k + 1))
1667 GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN
1668 COND_CASES_TAC THEN ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; GSYM NOT_LE] THEN
1669 ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THENL
1670 [COND_CASES_TAC THEN ASM_SIMP_TAC[ARITH] THENL
1671 [VECTOR_ARITH_TAC; ASM_ARITH_TAC];
1673 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LE]) THEN
1674 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
1675 ASM_SIMP_TAC[GSYM NOT_LT; VSUM_TRIV_NUMSEG; ARITH_RULE `n < SUC n`] THEN
1676 ASM_SIMP_TAC[GSYM ADD1; ADD_CLAUSES] THEN VECTOR_ARITH_TAC);;
1678 let VSUM_PARTIAL_PRE = prove
1679 (`!f g:num->real^N m n.
1680 vsum (m..n) (\k. f(k) % (g(k) - g(k - 1))) =
1681 if m <= n then f(n + 1) % g(n) - f(m) % g(m - 1) -
1682 vsum (m..n) (\k. (f(k + 1) - f(k)) % g(k))
1685 MP_TAC(ISPECL [`f:num->real`; `\k. (g:num->real^N)(k - 1)`;
1686 `m:num`; `n:num`] VSUM_PARTIAL_SUC) THEN
1687 REWRITE_TAC[ADD_SUB] THEN DISCH_THEN SUBST1_TAC THEN
1688 COND_CASES_TAC THEN REWRITE_TAC[]);;
1690 let VSUM_COMBINE_L = prove
1692 0 < n /\ m <= n /\ n <= p + 1
1693 ==> vsum(m..n - 1) f + vsum(n..p) f = vsum(m..p) f`,
1694 SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VSUM_COMPONENT; SUM_COMBINE_L]);;
1696 let VSUM_COMBINE_R = prove
1698 m <= n + 1 /\ n <= p
1699 ==> vsum(m..n) f + vsum(n + 1..p) f = vsum(m..p) f`,
1700 SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VSUM_COMPONENT; SUM_COMBINE_R]);;
1702 let VSUM_INJECTION = prove
1705 (!x. x IN s ==> p x IN s) /\
1706 (!x y. x IN s /\ y IN s /\ p x = p y ==> x = y)
1707 ==> vsum s (f o p) = vsum s f`,
1708 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP SUM_INJECTION) THEN
1709 SIMP_TAC[CART_EQ; VSUM_COMPONENT; o_DEF]);;
1711 let VSUM_SWAP = prove
1713 FINITE s /\ FINITE t
1714 ==> vsum s (\i. vsum t (f i)) = vsum t (\j. vsum s (\i. f i j))`,
1715 SIMP_TAC[CART_EQ; VSUM_COMPONENT] THEN REPEAT STRIP_TAC THEN
1716 W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o lhs o snd) THEN
1717 ASM_REWRITE_TAC[]);;
1719 let VSUM_SWAP_NUMSEG = prove
1721 vsum (a..b) (\i. vsum (c..d) (f i)) =
1722 vsum (c..d) (\j. vsum (a..b) (\i. f i j))`,
1723 REPEAT GEN_TAC THEN MATCH_MP_TAC VSUM_SWAP THEN REWRITE_TAC[FINITE_NUMSEG]);;
1725 let VSUM_ADD_GEN = prove
1727 FINITE {x | x IN s /\ ~(f x = vec 0)} /\
1728 FINITE {x | x IN s /\ ~(g x = vec 0)}
1729 ==> vsum s (\x. f x + g x) = vsum s f + vsum s g`,
1730 REPEAT GEN_TAC THEN DISCH_TAC THEN
1731 SIMP_TAC[CART_EQ; vsum; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN
1732 REPEAT GEN_TAC THEN DISCH_THEN(K ALL_TAC) THEN
1733 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_ADD_GEN THEN
1734 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN
1735 CONJ_TAC THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] FINITE_SUBSET) THEN
1736 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN GEN_TAC THEN
1737 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[DE_MORGAN_THM] THEN
1738 STRIP_TAC THEN ASM_REWRITE_TAC[VEC_COMPONENT]);;
1740 let VSUM_CASES_1 = prove
1741 (`!s a. FINITE s /\ a IN s
1742 ==> vsum s (\x. if x = a then y else f(x)) = vsum s f + (y - f a)`,
1743 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[VSUM_CASES] THEN
1744 ASM_SIMP_TAC[GSYM DELETE; VSUM_DELETE] THEN
1745 ASM_SIMP_TAC[SET_RULE `a IN s ==> {x | x IN s /\ x = a} = {a}`] THEN
1746 REWRITE_TAC[VSUM_SING] THEN VECTOR_ARITH_TAC);;
1748 let VSUM_SING_NUMSEG = prove
1749 (`vsum(n..n) f = f n`,
1750 REWRITE_TAC[NUMSEG_SING; VSUM_SING]);;
1753 (`vsum(1..1) f = f(1)`,
1754 REWRITE_TAC[VSUM_SING_NUMSEG]);;
1757 (`!t. vsum(1..2) t = t(1) + t(2)`,
1758 REWRITE_TAC[num_CONV `2`; VSUM_CLAUSES_NUMSEG] THEN
1759 REWRITE_TAC[VSUM_SING_NUMSEG; ARITH; REAL_ADD_ASSOC]);;
1762 (`!t. vsum(1..3) t = t(1) + t(2) + t(3)`,
1763 REWRITE_TAC[num_CONV `3`; num_CONV `2`; VSUM_CLAUSES_NUMSEG] THEN
1764 REWRITE_TAC[VSUM_SING_NUMSEG; ARITH; VECTOR_ADD_ASSOC]);;
1767 (`!t. vsum(1..4) t = t(1) + t(2) + t(3) + t(4)`,
1768 SIMP_TAC[num_CONV `4`; num_CONV `3`; num_CONV `2`; VSUM_CLAUSES_NUMSEG] THEN
1769 REWRITE_TAC[VSUM_SING_NUMSEG; ARITH; VECTOR_ADD_ASSOC]);;
1771 let VSUM_PAIR = prove
1772 (`!f:num->real^N m n.
1773 vsum(2*m..2*n+1) f = vsum(m..n) (\i. f(2*i) + f(2*i+1))`,
1774 SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_ADD_COMPONENT; SUM_PAIR]);;
1776 let VSUM_PAIR_0 = prove
1777 (`!f:num->real^N n. vsum(0..2*n+1) f = vsum(0..n) (\i. f(2*i) + f(2*i+1))`,
1779 MP_TAC(ISPECL [`f:num->real^N`; `0`; `n:num`] VSUM_PAIR) THEN
1780 ASM_REWRITE_TAC[ARITH]);;
1782 (* ------------------------------------------------------------------------- *)
1783 (* Add useful congruences to the simplifier. *)
1784 (* ------------------------------------------------------------------------- *)
1787 (`(!f g s. (!x. x IN s ==> f(x) = g(x))
1788 ==> vsum s (\i. f(i)) = vsum s g) /\
1789 (!f g a b. (!i. a <= i /\ i <= b ==> f(i) = g(i))
1790 ==> vsum(a..b) (\i. f(i)) = vsum(a..b) g) /\
1791 (!f g p. (!x. p x ==> f x = g x)
1792 ==> vsum {y | p y} (\i. f(i)) = vsum {y | p y} g)`,
1793 REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
1794 ASM_SIMP_TAC[IN_ELIM_THM; IN_NUMSEG]) in
1795 extend_basic_congs (map SPEC_ALL (CONJUNCTS th));;
1797 (* ------------------------------------------------------------------------- *)
1798 (* A conversion for evaluation of `vsum(m..n) f` for numerals m and n. *)
1799 (* ------------------------------------------------------------------------- *)
1801 let EXPAND_VSUM_CONV =
1802 let pth_0,pth_1 = (CONJ_PAIR o prove)
1803 (`vsum(0..0) (f:num->real^N) = f(0) /\
1804 vsum(0..SUC n) f = vsum(0..n) f + f(SUC n)`,
1805 REWRITE_TAC[VSUM_CLAUSES_NUMSEG; LE_0; VECTOR_ADD_AC]) in
1806 let conv_0 = REWR_CONV pth_0 and conv_1 = REWR_CONV pth_1 in
1808 try (LAND_CONV(RAND_CONV num_CONV) THENC conv_1 THENC
1809 NUM_REDUCE_CONV THENC LAND_CONV conv) tm
1810 with Failure _ -> conv_0 tm in
1812 (REDEPTH_CONV BETA_CONV) THENC
1813 GEN_REWRITE_CONV TOP_DEPTH_CONV [GSYM VECTOR_ADD_ASSOC];;
1815 (* ------------------------------------------------------------------------- *)
1816 (* Basis vectors in coordinate directions. *)
1817 (* ------------------------------------------------------------------------- *)
1819 let basis = new_definition
1820 `basis k = lambda i. if i = k then &1 else &0`;;
1822 let NORM_BASIS = prove
1823 (`!k. 1 <= k /\ k <= dimindex(:N)
1824 ==> (norm(basis k :real^N) = &1)`,
1825 REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[basis; dot; vector_norm] THEN
1826 GEN_REWRITE_TAC RAND_CONV [GSYM SQRT_1] THEN AP_TERM_TAC THEN
1827 MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
1828 `sum (1..dimindex(:N)) (\i. if i = k then &1 else &0)` THEN
1830 [MATCH_MP_TAC SUM_EQ_NUMSEG THEN
1831 ASM_SIMP_TAC[LAMBDA_BETA; IN_NUMSEG; EQ_SYM_EQ] THEN
1832 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN REAL_ARITH_TAC;
1833 ASM_REWRITE_TAC[SUM_DELTA; IN_NUMSEG]]);;
1835 let NORM_BASIS_1 = prove
1836 (`norm(basis 1) = &1`,
1837 SIMP_TAC[NORM_BASIS; ARITH_EQ; ARITH_RULE `1 <= k <=> ~(k = 0)`;
1838 DIMINDEX_NONZERO]);;
1840 let VECTOR_CHOOSE_SIZE = prove
1841 (`!c. &0 <= c ==> ?x:real^N. norm(x) = c`,
1842 REPEAT STRIP_TAC THEN EXISTS_TAC `c % basis 1 :real^N` THEN
1843 ASM_REWRITE_TAC[NORM_MUL; real_abs; NORM_BASIS_1; REAL_MUL_RID]);;
1845 let VECTOR_CHOOSE_DIST = prove
1846 (`!x e. &0 <= e ==> ?y:real^N. dist(x,y) = e`,
1847 REPEAT STRIP_TAC THEN
1848 SUBGOAL_THEN `?c:real^N. norm(c) = e` CHOOSE_TAC THENL
1849 [ASM_SIMP_TAC[VECTOR_CHOOSE_SIZE]; ALL_TAC] THEN
1850 EXISTS_TAC `x - c:real^N` THEN REWRITE_TAC[dist] THEN
1851 ASM_REWRITE_TAC[VECTOR_ARITH `x - (x - c) = c:real^N`]);;
1853 let BASIS_INJ = prove
1854 (`!i j. 1 <= i /\ i <= dimindex(:N) /\
1855 1 <= j /\ j <= dimindex(:N) /\
1856 (basis i :real^N = basis j)
1858 SIMP_TAC[basis; CART_EQ; LAMBDA_BETA] THEN REPEAT GEN_TAC THEN
1859 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
1860 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
1861 ASM_SIMP_TAC[REAL_OF_NUM_EQ; ARITH_EQ]);;
1863 let BASIS_INJ_EQ = prove
1864 (`!i j. 1 <= i /\ i <= dimindex(:N) /\ 1 <= j /\ j <= dimindex(:N)
1865 ==> (basis i:real^N = basis j <=> i = j)`,
1866 MESON_TAC[BASIS_INJ]);;
1868 let BASIS_NE = prove
1869 (`!i j. 1 <= i /\ i <= dimindex(:N) /\
1870 1 <= j /\ j <= dimindex(:N) /\
1872 ==> ~(basis i :real^N = basis j)`,
1873 MESON_TAC[BASIS_INJ]);;
1875 let BASIS_COMPONENT = prove
1876 (`!k i. 1 <= i /\ i <= dimindex(:N)
1877 ==> ((basis k :real^N)$i = if i = k then &1 else &0)`,
1878 SIMP_TAC[basis; LAMBDA_BETA] THEN MESON_TAC[]);;
1880 let BASIS_EXPANSION = prove
1881 (`!x:real^N. vsum(1..dimindex(:N)) (\i. x$i % basis i) = x`,
1882 SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN
1883 ONCE_REWRITE_TAC[COND_RAND] THEN REWRITE_TAC[REAL_MUL_RZERO] THEN
1884 REPEAT STRIP_TAC THEN
1885 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
1886 ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; REAL_MUL_RID]);;
1888 let BASIS_EXPANSION_UNIQUE = prove
1889 (`!f x:real^N. (vsum(1..dimindex(:N)) (\i. f(i) % basis i) = x) <=>
1890 (!i. 1 <= i /\ i <= dimindex(:N) ==> f(i) = x$i)`,
1891 SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN
1892 REPEAT GEN_TAC THEN REWRITE_TAC[COND_RAND; REAL_MUL_RZERO; REAL_MUL_RID] THEN
1893 GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o RAND_CONV o LAND_CONV o
1894 ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
1895 SIMP_TAC[SUM_DELTA; IN_NUMSEG]);;
1897 let DOT_BASIS = prove
1899 1 <= i /\ i <= dimindex(:N)
1900 ==> ((basis i) dot x = x$i) /\ (x dot (basis i) = x$i)`,
1901 SIMP_TAC[dot; basis; LAMBDA_BETA] THEN
1902 REWRITE_TAC[COND_RATOR; COND_RAND] THEN
1903 REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO] THEN
1904 SIMP_TAC[SUM_DELTA; IN_NUMSEG; REAL_MUL_LID; REAL_MUL_RID]);;
1906 let DOT_BASIS_BASIS = prove
1907 (`!i j. 1 <= i /\ i <= dimindex(:N) /\
1908 1 <= j /\ j <= dimindex(:N)
1909 ==> (basis i:real^N) dot (basis j) = if i = j then &1 else &0`,
1910 SIMP_TAC[DOT_BASIS; BASIS_COMPONENT]);;
1912 let DOT_BASIS_BASIS_UNEQUAL = prove
1913 (`!i j. ~(i = j) ==> (basis i) dot (basis j) = &0`,
1914 SIMP_TAC[basis; dot; LAMBDA_BETA] THEN ONCE_REWRITE_TAC[COND_RAND] THEN
1915 SIMP_TAC[SUM_0; REAL_MUL_RZERO; REAL_MUL_LZERO; COND_ID]);;
1917 let BASIS_EQ_0 = prove
1918 (`!i. (basis i :real^N = vec 0) <=> ~(i IN 1..dimindex(:N))`,
1919 SIMP_TAC[CART_EQ; BASIS_COMPONENT; VEC_COMPONENT; IN_NUMSEG] THEN
1920 MESON_TAC[REAL_ARITH `~(&1 = &0)`]);;
1922 let BASIS_NONZERO = prove
1923 (`!k. 1 <= k /\ k <= dimindex(:N)
1924 ==> ~(basis k :real^N = vec 0)`,
1925 REWRITE_TAC[BASIS_EQ_0; IN_NUMSEG]);;
1927 let VECTOR_EQ_LDOT = prove
1928 (`!y z. (!x. x dot y = x dot z) <=> y = z`,
1929 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN
1930 REWRITE_TAC[CART_EQ] THEN MESON_TAC[DOT_BASIS]);;
1932 let VECTOR_EQ_RDOT = prove
1933 (`!x y. (!z. x dot z = y dot z) <=> x = y`,
1934 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN
1935 REWRITE_TAC[CART_EQ] THEN MESON_TAC[DOT_BASIS]);;
1937 (* ------------------------------------------------------------------------- *)
1938 (* Orthogonality. *)
1939 (* ------------------------------------------------------------------------- *)
1941 let orthogonal = new_definition
1942 `orthogonal x y <=> (x dot y = &0)`;;
1944 let ORTHOGONAL_0 = prove
1945 (`!x. orthogonal (vec 0) x /\ orthogonal x (vec 0)`,
1946 REWRITE_TAC[orthogonal; DOT_LZERO; DOT_RZERO]);;
1948 let ORTHOGONAL_REFL = prove
1949 (`!x. orthogonal x x <=> x = vec 0`,
1950 REWRITE_TAC[orthogonal; DOT_EQ_0]);;
1952 let ORTHOGONAL_SYM = prove
1953 (`!x y. orthogonal x y <=> orthogonal y x`,
1954 REWRITE_TAC[orthogonal; DOT_SYM]);;
1956 let ORTHOGONAL_LNEG = prove
1957 (`!x y. orthogonal (--x) y <=> orthogonal x y`,
1958 REWRITE_TAC[orthogonal; DOT_LNEG; REAL_NEG_EQ_0]);;
1960 let ORTHOGONAL_RNEG = prove
1961 (`!x y. orthogonal x (--y) <=> orthogonal x y`,
1962 REWRITE_TAC[orthogonal; DOT_RNEG; REAL_NEG_EQ_0]);;
1964 let ORTHOGONAL_MUL = prove
1965 (`(!a x y:real^N. orthogonal (a % x) y <=> a = &0 \/ orthogonal x y) /\
1966 (!a x y:real^N. orthogonal x (a % y) <=> a = &0 \/ orthogonal x y)`,
1967 REWRITE_TAC[orthogonal; DOT_LMUL; DOT_RMUL; REAL_ENTIRE]);;
1969 let ORTHOGONAL_BASIS = prove
1970 (`!x:real^N i. 1 <= i /\ i <= dimindex(:N)
1971 ==> (orthogonal (basis i) x <=> (x$i = &0))`,
1972 REPEAT STRIP_TAC THEN SIMP_TAC[orthogonal; dot; basis; LAMBDA_BETA] THEN
1973 REWRITE_TAC[COND_RAND; COND_RATOR; REAL_MUL_LZERO] THEN
1974 ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; REAL_MUL_LID]);;
1976 let ORTHOGONAL_BASIS_BASIS = prove
1977 (`!i j. 1 <= i /\ i <= dimindex(:N) /\
1978 1 <= j /\ j <= dimindex(:N)
1979 ==> (orthogonal (basis i :real^N) (basis j) <=> ~(i = j))`,
1980 ASM_SIMP_TAC[ORTHOGONAL_BASIS] THEN ASM_SIMP_TAC[BASIS_COMPONENT] THEN
1981 MESON_TAC[REAL_ARITH `~(&1 = &0)`]);;
1983 let ORTHOGONAL_CLAUSES = prove
1984 (`(!a. orthogonal a (vec 0)) /\
1985 (!a x c. orthogonal a x ==> orthogonal a (c % x)) /\
1986 (!a x. orthogonal a x ==> orthogonal a (--x)) /\
1987 (!a x y. orthogonal a x /\ orthogonal a y ==> orthogonal a (x + y)) /\
1988 (!a x y. orthogonal a x /\ orthogonal a y ==> orthogonal a (x - y)) /\
1989 (!a. orthogonal (vec 0) a) /\
1990 (!a x c. orthogonal x a ==> orthogonal (c % x) a) /\
1991 (!a x. orthogonal x a ==> orthogonal (--x) a) /\
1992 (!a x y. orthogonal x a /\ orthogonal y a ==> orthogonal (x + y) a) /\
1993 (!a x y. orthogonal x a /\ orthogonal y a ==> orthogonal (x - y) a)`,
1994 REWRITE_TAC[orthogonal; DOT_RNEG; DOT_RMUL; DOT_RADD; DOT_RSUB;
1995 DOT_LZERO; DOT_RZERO; DOT_LNEG; DOT_LMUL; DOT_LADD; DOT_LSUB] THEN
1996 SIMP_TAC[] THEN REAL_ARITH_TAC);;
1998 let ORTHOGONAL_RVSUM = prove
2001 (!y. y IN s ==> orthogonal x (f y))
2002 ==> orthogonal x (vsum s f)`,
2003 GEN_TAC THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN
2004 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2005 SIMP_TAC[NOT_IN_EMPTY; FORALL_IN_INSERT; ORTHOGONAL_CLAUSES; VSUM_CLAUSES]);;
2007 let ORTHOGONAL_LVSUM = prove
2010 (!x. x IN s ==> orthogonal (f x) y)
2011 ==> orthogonal (vsum s f) y`,
2012 GEN_TAC THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN
2013 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2014 SIMP_TAC[NOT_IN_EMPTY; FORALL_IN_INSERT; ORTHOGONAL_CLAUSES; VSUM_CLAUSES]);;
2016 let NORM_ADD_PYTHAGOREAN = prove
2019 ==> norm(a + b) pow 2 = norm(a) pow 2 + norm(b) pow 2`,
2020 SIMP_TAC[NORM_POW_2; orthogonal; DOT_LADD; DOT_RADD; DOT_SYM] THEN
2023 let NORM_VSUM_PYTHAGOREAN = prove
2025 FINITE k /\ pairwise (\i j. orthogonal (u i) (u j)) k
2026 ==> norm(vsum k u) pow 2 = sum k (\i. norm(u i) pow 2)`,
2027 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN SIMP_TAC[IMP_CONJ] THEN
2028 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2029 SIMP_TAC[VSUM_CLAUSES; SUM_CLAUSES; NORM_0] THEN
2030 CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[PAIRWISE_INSERT] THEN
2031 REWRITE_TAC[pairwise] THEN REPEAT GEN_TAC THEN
2032 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
2033 DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN ASM_REWRITE_TAC[] THEN
2034 MATCH_MP_TAC NORM_ADD_PYTHAGOREAN THEN MATCH_MP_TAC ORTHOGONAL_RVSUM THEN
2037 (* ------------------------------------------------------------------------- *)
2038 (* Explicit vector construction from lists. *)
2039 (* ------------------------------------------------------------------------- *)
2041 let VECTOR_1 = prove
2042 (`(vector[x]:A^1)$1 = x`,
2043 SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_1; ARITH; LENGTH; EL; HD; TL]);;
2045 let VECTOR_2 = prove
2046 (`(vector[x;y]:A^2)$1 = x /\
2047 (vector[x;y]:A^2)$2 = y`,
2048 SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_2; ARITH; LENGTH; EL] THEN
2049 REWRITE_TAC[num_CONV `1`; HD; TL; EL]);;
2051 let VECTOR_3 = prove
2052 (`(vector[x;y;z]:A^3)$1 = x /\
2053 (vector[x;y;z]:A^3)$2 = y /\
2054 (vector[x;y;z]:A^3)$3 = z`,
2055 SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_3; ARITH; LENGTH; EL] THEN
2056 REWRITE_TAC[num_CONV `2`; num_CONV `1`; HD; TL; EL]);;
2058 let VECTOR_4 = prove
2059 (`(vector[w;x;y;z]:A^4)$1 = w /\
2060 (vector[w;x;y;z]:A^4)$2 = x /\
2061 (vector[w;x;y;z]:A^4)$3 = y /\
2062 (vector[w;x;y;z]:A^4)$4 = z`,
2063 SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_4; ARITH; LENGTH; EL] THEN
2064 REWRITE_TAC[num_CONV `3`; num_CONV `2`; num_CONV `1`; HD; TL; EL]);;
2066 let FORALL_VECTOR_1 = prove
2067 (`(!v:A^1. P v) <=> !x. P(vector[x])`,
2068 EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN
2069 FIRST_X_ASSUM(MP_TAC o SPEC `(v:A^1)$1`) THEN
2070 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
2071 REWRITE_TAC[CART_EQ; FORALL_1; VECTOR_1; DIMINDEX_1]);;
2073 let FORALL_VECTOR_2 = prove
2074 (`(!v:A^2. P v) <=> !x y. P(vector[x;y])`,
2075 EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN
2076 FIRST_X_ASSUM(MP_TAC o SPECL [`(v:A^2)$1`; `(v:A^2)$2`]) THEN
2077 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
2078 REWRITE_TAC[CART_EQ; FORALL_2; VECTOR_2; DIMINDEX_2]);;
2080 let FORALL_VECTOR_3 = prove
2081 (`(!v:A^3. P v) <=> !x y z. P(vector[x;y;z])`,
2082 EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN
2083 FIRST_X_ASSUM(MP_TAC o SPECL
2084 [`(v:A^3)$1`; `(v:A^3)$2`; `(v:A^3)$3`]) THEN
2085 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
2086 REWRITE_TAC[CART_EQ; FORALL_3; VECTOR_3; DIMINDEX_3]);;
2088 let FORALL_VECTOR_4 = prove
2089 (`(!v:A^4. P v) <=> !w x y z. P(vector[w;x;y;z])`,
2090 EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN
2091 FIRST_X_ASSUM(MP_TAC o SPECL
2092 [`(v:A^4)$1`; `(v:A^4)$2`; `(v:A^4)$3`; `(v:A^4)$4`]) THEN
2093 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
2094 REWRITE_TAC[CART_EQ; FORALL_4; VECTOR_4; DIMINDEX_4]);;
2096 let EXISTS_VECTOR_1 = prove
2097 (`(?v:A^1. P v) <=> ?x. P(vector[x])`,
2098 REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
2099 REWRITE_TAC[FORALL_VECTOR_1]);;
2101 let EXISTS_VECTOR_2 = prove
2102 (`(?v:A^2. P v) <=> ?x y. P(vector[x;y])`,
2103 REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
2104 REWRITE_TAC[FORALL_VECTOR_2]);;
2106 let EXISTS_VECTOR_3 = prove
2107 (`(?v:A^3. P v) <=> ?x y z. P(vector[x;y;z])`,
2108 REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
2109 REWRITE_TAC[FORALL_VECTOR_3]);;
2111 let EXISTS_VECTOR_4 = prove
2112 (`(?v:A^4. P v) <=> ?w x y z. P(vector[w;x;y;z])`,
2113 REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
2114 REWRITE_TAC[FORALL_VECTOR_4]);;
2116 let VECTOR_EXPAND_1 = prove
2117 (`!x:real^1. x = vector[x$1]`,
2118 SIMP_TAC[CART_EQ; DIMINDEX_1; FORALL_1; VECTOR_1]);;
2120 let VECTOR_EXPAND_2 = prove
2121 (`!x:real^2. x = vector[x$1;x$2]`,
2122 SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2]);;
2124 let VECTOR_EXPAND_3 = prove
2125 (`!x:real^3. x = vector[x$1;x$2;x$3]`,
2126 SIMP_TAC[CART_EQ; DIMINDEX_3; FORALL_3; VECTOR_3]);;
2128 let VECTOR_EXPAND_4 = prove
2129 (`!x:real^4. x = vector[x$1;x$2;x$3;x$4]`,
2130 SIMP_TAC[CART_EQ; DIMINDEX_4; FORALL_4; VECTOR_4]);;
2132 (* ------------------------------------------------------------------------- *)
2133 (* Linear functions. *)
2134 (* ------------------------------------------------------------------------- *)
2136 let linear = new_definition
2137 `linear (f:real^M->real^N) <=>
2138 (!x y. f(x + y) = f(x) + f(y)) /\
2139 (!c x. f(c % x) = c % f(x))`;;
2141 let LINEAR_COMPOSE_CMUL = prove
2142 (`!f c. linear f ==> linear (\x. c % f(x))`,
2143 SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
2145 let LINEAR_COMPOSE_NEG = prove
2146 (`!f. linear f ==> linear (\x. --(f(x)))`,
2147 SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
2149 let LINEAR_COMPOSE_ADD = prove
2150 (`!f g. linear f /\ linear g ==> linear (\x. f(x) + g(x))`,
2151 SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
2153 let LINEAR_COMPOSE_SUB = prove
2154 (`!f g. linear f /\ linear g ==> linear (\x. f(x) - g(x))`,
2155 SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
2157 let LINEAR_COMPOSE = prove
2158 (`!f g. linear f /\ linear g ==> linear (g o f)`,
2159 SIMP_TAC[linear; o_THM]);;
2161 let LINEAR_ID = prove
2163 REWRITE_TAC[linear]);;
2165 let LINEAR_I = prove
2167 REWRITE_TAC[I_DEF; LINEAR_ID]);;
2169 let LINEAR_ZERO = prove
2170 (`linear (\x. vec 0)`,
2171 REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
2173 let LINEAR_NEGATION = prove
2175 REWRITE_TAC[linear] THEN VECTOR_ARITH_TAC);;
2177 let LINEAR_COMPOSE_VSUM = prove
2178 (`!f s. FINITE s /\ (!a. a IN s ==> linear(f a))
2179 ==> linear(\x. vsum s (\a. f a x))`,
2180 GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
2181 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2182 SIMP_TAC[VSUM_CLAUSES; LINEAR_ZERO] THEN
2183 ASM_SIMP_TAC[ETA_AX; IN_INSERT; LINEAR_COMPOSE_ADD]);;
2185 let LINEAR_VMUL_COMPONENT = prove
2186 (`!f:real^M->real^N v k.
2187 linear f /\ 1 <= k /\ k <= dimindex(:N)
2188 ==> linear (\x. f(x)$k % v)`,
2189 SIMP_TAC[linear; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
2190 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
2192 let LINEAR_0 = prove
2193 (`!f. linear f ==> (f(vec 0) = vec 0)`,
2194 MESON_TAC[VECTOR_MUL_LZERO; linear]);;
2196 let LINEAR_CMUL = prove
2197 (`!f c x. linear f ==> (f(c % x) = c % f(x))`,
2200 let LINEAR_NEG = prove
2201 (`!f x. linear f ==> (f(--x) = --(f x))`,
2202 ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN SIMP_TAC[LINEAR_CMUL]);;
2204 let LINEAR_ADD = prove
2205 (`!f x y. linear f ==> (f(x + y) = f(x) + f(y))`,
2208 let LINEAR_SUB = prove
2209 (`!f x y. linear f ==> (f(x - y) = f(x) - f(y))`,
2210 SIMP_TAC[VECTOR_SUB; LINEAR_ADD; LINEAR_NEG]);;
2212 let LINEAR_VSUM = prove
2213 (`!f g s. linear f /\ FINITE s ==> (f(vsum s g) = vsum s (f o g))`,
2214 GEN_TAC THEN GEN_TAC THEN SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
2215 DISCH_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2216 SIMP_TAC[VSUM_CLAUSES] THEN FIRST_ASSUM(fun th ->
2217 SIMP_TAC[MATCH_MP LINEAR_0 th; MATCH_MP LINEAR_ADD th; o_THM]));;
2219 let LINEAR_VSUM_MUL = prove
2221 linear f /\ FINITE s
2222 ==> f(vsum s (\i. c i % v i)) = vsum s (\i. c(i) % f(v i))`,
2223 SIMP_TAC[LINEAR_VSUM; o_DEF; LINEAR_CMUL]);;
2225 let LINEAR_INJECTIVE_0 = prove
2227 ==> ((!x y. (f(x) = f(y)) ==> (x = y)) <=>
2228 (!x. (f(x) = vec 0) ==> (x = vec 0)))`,
2229 REPEAT STRIP_TAC THEN
2230 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM VECTOR_SUB_EQ] THEN
2231 ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN MESON_TAC[VECTOR_SUB_RZERO]);;
2233 let LINEAR_BOUNDED = prove
2234 (`!f:real^M->real^N. linear f ==> ?B. !x. norm(f x) <= B * norm(x)`,
2235 REPEAT STRIP_TAC THEN EXISTS_TAC
2236 `sum(1..dimindex(:M)) (\i. norm((f:real^M->real^N)(basis i)))` THEN
2238 GEN_REWRITE_TAC (LAND_CONV o funpow 2 RAND_CONV) [GSYM BASIS_EXPANSION] THEN
2239 ASM_SIMP_TAC[LINEAR_VSUM; FINITE_NUMSEG] THEN
2240 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
2241 MATCH_MP_TAC VSUM_NORM_LE THEN
2242 SIMP_TAC[FINITE_CROSS; FINITE_NUMSEG; IN_NUMSEG] THEN
2243 ASM_SIMP_TAC[o_DEF; NORM_MUL; LINEAR_CMUL] THEN
2244 ASM_SIMP_TAC[REAL_LE_RMUL; NORM_POS_LE; COMPONENT_LE_NORM]);;
2246 let LINEAR_BOUNDED_POS = prove
2247 (`!f:real^M->real^N. linear f ==> ?B. &0 < B /\ !x. norm(f x) <= B * norm(x)`,
2248 REPEAT STRIP_TAC THEN
2249 FIRST_ASSUM(X_CHOOSE_TAC `B:real` o MATCH_MP LINEAR_BOUNDED) THEN
2250 EXISTS_TAC `abs(B) + &1` THEN CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
2251 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
2252 MATCH_MP_TAC(REAL_ARITH `a <= b ==> x <= a ==> x <= b`) THEN
2253 MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN
2256 let SYMMETRIC_LINEAR_IMAGE = prove
2257 (`!f s. (!x. x IN s ==> --x IN s) /\ linear f
2258 ==> !x. x IN (IMAGE f s) ==> --x IN (IMAGE f s)`,
2259 REWRITE_TAC[FORALL_IN_IMAGE] THEN
2260 SIMP_TAC[GSYM LINEAR_NEG] THEN SET_TAC[]);;
2262 (* ------------------------------------------------------------------------- *)
2263 (* Bilinear functions. *)
2264 (* ------------------------------------------------------------------------- *)
2266 let bilinear = new_definition
2267 `bilinear f <=> (!x. linear(\y. f x y)) /\ (!y. linear(\x. f x y))`;;
2269 let BILINEAR_LADD = prove
2270 (`!h x y z. bilinear h ==> h (x + y) z = (h x z) + (h y z)`,
2271 SIMP_TAC[bilinear; linear]);;
2273 let BILINEAR_RADD = prove
2274 (`!h x y z. bilinear h ==> h x (y + z) = (h x y) + (h x z)`,
2275 SIMP_TAC[bilinear; linear]);;
2277 let BILINEAR_LMUL = prove
2278 (`!h c x y. bilinear h ==> h (c % x) y = c % (h x y)`,
2279 SIMP_TAC[bilinear; linear]);;
2281 let BILINEAR_RMUL = prove
2282 (`!h c x y. bilinear h ==> h x (c % y) = c % (h x y)`,
2283 SIMP_TAC[bilinear; linear]);;
2285 let BILINEAR_LNEG = prove
2286 (`!h x y. bilinear h ==> h (--x) y = --(h x y)`,
2287 ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN SIMP_TAC[BILINEAR_LMUL]);;
2289 let BILINEAR_RNEG = prove
2290 (`!h x y. bilinear h ==> h x (--y) = --(h x y)`,
2291 ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN SIMP_TAC[BILINEAR_RMUL]);;
2293 let BILINEAR_LZERO = prove
2294 (`!h x. bilinear h ==> h (vec 0) x = vec 0`,
2295 ONCE_REWRITE_TAC[VECTOR_ARITH `x = vec 0 <=> x + x = x`] THEN
2296 SIMP_TAC[GSYM BILINEAR_LADD; VECTOR_ADD_LID]);;
2298 let BILINEAR_RZERO = prove
2299 (`!h x. bilinear h ==> h x (vec 0) = vec 0`,
2300 ONCE_REWRITE_TAC[VECTOR_ARITH `x = vec 0 <=> x + x = x`] THEN
2301 SIMP_TAC[GSYM BILINEAR_RADD; VECTOR_ADD_LID]);;
2303 let BILINEAR_LSUB = prove
2304 (`!h x y z. bilinear h ==> h (x - y) z = (h x z) - (h y z)`,
2305 SIMP_TAC[VECTOR_SUB; BILINEAR_LNEG; BILINEAR_LADD]);;
2307 let BILINEAR_RSUB = prove
2308 (`!h x y z. bilinear h ==> h x (y - z) = (h x y) - (h x z)`,
2309 SIMP_TAC[VECTOR_SUB; BILINEAR_RNEG; BILINEAR_RADD]);;
2311 let BILINEAR_VSUM = prove
2312 (`!h:real^M->real^N->real^P.
2313 bilinear h /\ FINITE s /\ FINITE t
2314 ==> h (vsum s f) (vsum t g) = vsum (s CROSS t) (\(i,j). h (f i) (g j))`,
2315 REPEAT GEN_TAC THEN SIMP_TAC[bilinear; ETA_AX] THEN
2316 ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> (a /\ d) /\ (b /\ c)`] THEN
2317 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
2318 ONCE_REWRITE_TAC[LEFT_AND_FORALL_THM] THEN DISCH_TAC THEN
2319 FIRST_ASSUM(MP_TAC o GEN_ALL o MATCH_MP LINEAR_VSUM o SPEC_ALL) THEN
2320 SIMP_TAC[] THEN ASM_SIMP_TAC[LINEAR_VSUM; o_DEF; VSUM_VSUM_PRODUCT] THEN
2321 REWRITE_TAC[GSYM CROSS]);;
2323 let BILINEAR_BOUNDED = prove
2324 (`!h:real^M->real^N->real^P.
2325 bilinear h ==> ?B. !x y. norm(h x y) <= B * norm(x) * norm(y)`,
2326 REPEAT STRIP_TAC THEN
2327 EXISTS_TAC `sum ((1..dimindex(:M)) CROSS (1..dimindex(:N)))
2328 (\(i,j). norm((h:real^M->real^N->real^P)
2329 (basis i) (basis j)))` THEN
2330 REPEAT GEN_TAC THEN GEN_REWRITE_TAC
2331 (LAND_CONV o RAND_CONV o BINOP_CONV) [GSYM BASIS_EXPANSION] THEN
2332 ASM_SIMP_TAC[BILINEAR_VSUM; FINITE_NUMSEG] THEN
2333 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
2334 MATCH_MP_TAC VSUM_NORM_LE THEN
2335 SIMP_TAC[FINITE_CROSS; FINITE_NUMSEG; FORALL_PAIR_THM; IN_CROSS] THEN
2336 REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN
2337 ASM_SIMP_TAC[BILINEAR_LMUL; NORM_MUL] THEN
2338 ASM_SIMP_TAC[BILINEAR_RMUL; NORM_MUL; REAL_MUL_ASSOC] THEN
2339 MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN
2340 ASM_SIMP_TAC[COMPONENT_LE_NORM; REAL_ABS_POS; REAL_LE_MUL2]);;
2342 let BILINEAR_BOUNDED_POS = prove
2344 ==> ?B. &0 < B /\ !x y. norm(h x y) <= B * norm(x) * norm(y)`,
2345 REPEAT STRIP_TAC THEN
2346 FIRST_ASSUM(X_CHOOSE_TAC `B:real` o MATCH_MP BILINEAR_BOUNDED) THEN
2347 EXISTS_TAC `abs(B) + &1` THEN CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
2348 POP_ASSUM MP_TAC THEN REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2349 MATCH_MP_TAC(REAL_ARITH `a <= b ==> x <= a ==> x <= b`) THEN
2350 REPEAT(MATCH_MP_TAC REAL_LE_RMUL THEN
2351 SIMP_TAC[NORM_POS_LE; REAL_LE_MUL]) THEN
2354 let BILINEAR_VSUM_PARTIAL_SUC = prove
2355 (`!f g h:real^M->real^N->real^P m n.
2357 ==> vsum (m..n) (\k. h (f k) (g(k + 1) - g(k))) =
2358 if m <= n then h (f(n + 1)) (g(n + 1)) - h (f m) (g m) -
2359 vsum (m..n) (\k. h (f(k + 1) - f(k)) (g(k + 1)))
2361 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
2362 GEN_TAC THEN INDUCT_TAC THEN
2363 COND_CASES_TAC THEN ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; GSYM NOT_LE] THEN
2364 ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THENL
2365 [COND_CASES_TAC THEN ASM_SIMP_TAC[ARITH] THENL
2366 [ASM_SIMP_TAC[BILINEAR_RSUB; BILINEAR_LSUB] THEN VECTOR_ARITH_TAC;
2369 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LE]) THEN
2370 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
2371 ASM_SIMP_TAC[GSYM NOT_LT; VSUM_TRIV_NUMSEG; ARITH_RULE `n < SUC n`] THEN
2372 ASM_SIMP_TAC[GSYM ADD1; ADD_CLAUSES] THEN
2373 ASM_SIMP_TAC[BILINEAR_RSUB; BILINEAR_LSUB] THEN VECTOR_ARITH_TAC);;
2375 let BILINEAR_VSUM_PARTIAL_PRE = prove
2376 (`!f g h:real^M->real^N->real^P m n.
2378 ==> vsum (m..n) (\k. h (f k) (g(k) - g(k - 1))) =
2379 if m <= n then h (f(n + 1)) (g(n)) - h (f m) (g(m - 1)) -
2380 vsum (m..n) (\k. h (f(k + 1) - f(k)) (g(k)))
2382 REPEAT STRIP_TAC THEN
2383 FIRST_ASSUM(MP_TAC o ISPECL [`f:num->real^M`; `\k. (g:num->real^N)(k - 1)`;
2384 `m:num`; `n:num`] o MATCH_MP BILINEAR_VSUM_PARTIAL_SUC) THEN
2385 REWRITE_TAC[ADD_SUB] THEN DISCH_THEN SUBST1_TAC THEN
2386 COND_CASES_TAC THEN REWRITE_TAC[]);;
2388 (* ------------------------------------------------------------------------- *)
2390 (* ------------------------------------------------------------------------- *)
2392 let adjoint = new_definition
2393 `adjoint(f:real^M->real^N) = @f'. !x y. f(x) dot y = x dot f'(y)`;;
2395 let ADJOINT_WORKS = prove
2396 (`!f:real^M->real^N. linear f ==> !x y. f(x) dot y = x dot (adjoint f)(y)`,
2397 GEN_TAC THEN DISCH_TAC THEN SIMP_TAC[adjoint] THEN CONV_TAC SELECT_CONV THEN
2398 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN ONCE_REWRITE_TAC[GSYM SKOLEM_THM] THEN
2399 X_GEN_TAC `y:real^N` THEN
2400 EXISTS_TAC `(lambda i. (f:real^M->real^N) (basis i) dot y):real^M` THEN
2401 X_GEN_TAC `x:real^M` THEN
2402 GEN_REWRITE_TAC (funpow 2 LAND_CONV o RAND_CONV) [GSYM BASIS_EXPANSION] THEN
2403 ASM_SIMP_TAC[LINEAR_VSUM; FINITE_NUMSEG] THEN
2404 SIMP_TAC[dot; LAMBDA_BETA; VSUM_COMPONENT; GSYM SUM_LMUL; GSYM SUM_RMUL] THEN
2405 GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN
2406 ASM_SIMP_TAC[o_THM; VECTOR_MUL_COMPONENT; LINEAR_CMUL; REAL_MUL_ASSOC]);;
2408 let ADJOINT_LINEAR = prove
2409 (`!f:real^M->real^N. linear f ==> linear(adjoint f)`,
2410 REPEAT STRIP_TAC THEN REWRITE_TAC[linear; GSYM VECTOR_EQ_LDOT] THEN
2411 ASM_SIMP_TAC[DOT_RMUL; DOT_RADD; GSYM ADJOINT_WORKS]);;
2413 let ADJOINT_CLAUSES = prove
2414 (`!f:real^M->real^N.
2415 linear f ==> (!x y. x dot (adjoint f)(y) = f(x) dot y) /\
2416 (!x y. (adjoint f)(y) dot x = y dot f(x))`,
2417 MESON_TAC[ADJOINT_WORKS; DOT_SYM]);;
2419 let ADJOINT_ADJOINT = prove
2420 (`!f:real^M->real^N. linear f ==> adjoint(adjoint f) = f`,
2421 SIMP_TAC[FUN_EQ_THM; GSYM VECTOR_EQ_LDOT; ADJOINT_CLAUSES; ADJOINT_LINEAR]);;
2423 let ADJOINT_UNIQUE = prove
2424 (`!f f'. linear f /\ (!x y. f'(x) dot y = x dot f(y))
2425 ==> f' = adjoint f`,
2426 SIMP_TAC[FUN_EQ_THM; GSYM VECTOR_EQ_RDOT; ADJOINT_CLAUSES]);;
2428 let ADJOINT_COMPOSE = prove
2429 (`!f g:real^N->real^N.
2430 linear f /\ linear g ==> adjoint(f o g) = adjoint g o adjoint f`,
2431 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC ADJOINT_UNIQUE THEN
2432 ASM_SIMP_TAC[LINEAR_COMPOSE; o_THM; ADJOINT_CLAUSES]);;
2434 let SELF_ADJOINT_COMPOSE = prove
2435 (`!f g:real^N->real^N.
2436 linear f /\ linear g /\ adjoint f = f /\ adjoint g = g
2437 ==> (adjoint(f o g) = f o g <=> f o g = g o f)`,
2438 SIMP_TAC[ADJOINT_COMPOSE] THEN MESON_TAC[]);;
2440 let SELF_ADJOINT_ORTHOGONAL_EIGENVECTORS = prove
2441 (`!f:real^N->real^N v w a b.
2442 linear f /\ adjoint f = f /\ f v = a % v /\ f w = b % w /\ ~(a = b)
2443 ==> orthogonal v w`,
2444 REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPECL [`v:real^N`; `w:real^N`] o
2445 MATCH_MP ADJOINT_WORKS) THEN
2446 ASM_REWRITE_TAC[DOT_LMUL; DOT_RMUL; orthogonal; REAL_EQ_MUL_RCANCEL]);;
2448 (* ------------------------------------------------------------------------- *)
2449 (* Matrix notation. NB: an MxN matrix is of type real^N^M, not real^M^N. *)
2450 (* We could define a special type if we're going to use them a lot. *)
2451 (* ------------------------------------------------------------------------- *)
2453 overload_interface ("--",`(matrix_neg):real^N^M->real^N^M`);;
2454 overload_interface ("+",`(matrix_add):real^N^M->real^N^M->real^N^M`);;
2455 overload_interface ("-",`(matrix_sub):real^N^M->real^N^M->real^N^M`);;
2457 make_overloadable "**" `:A->B->C`;;
2459 overload_interface ("**",`(matrix_mul):real^N^M->real^P^N->real^P^M`);;
2460 overload_interface ("**",`(matrix_vector_mul):real^N^M->real^N->real^M`);;
2461 overload_interface ("**",`(vector_matrix_mul):real^M->real^N^M->real^N`);;
2463 parse_as_infix("%%",(21,"right"));;
2467 let matrix_cmul = new_definition
2468 `((%%):real->real^N^M->real^N^M) c A = lambda i j. c * A$i$j`;;
2470 let matrix_neg = new_definition
2471 `!A:real^N^M. --A = lambda i j. --(A$i$j)`;;
2473 let matrix_add = new_definition
2474 `!A:real^N^M B:real^N^M. A + B = lambda i j. A$i$j + B$i$j`;;
2476 let matrix_sub = new_definition
2477 `!A:real^N^M B:real^N^M. A - B = lambda i j. A$i$j - B$i$j`;;
2479 let matrix_mul = new_definition
2480 `!A:real^N^M B:real^P^N.
2482 lambda i j. sum(1..dimindex(:N)) (\k. A$i$k * B$k$j)`;;
2484 let matrix_vector_mul = new_definition
2485 `!A:real^N^M x:real^N.
2486 A ** x = lambda i. sum(1..dimindex(:N)) (\j. A$i$j * x$j)`;;
2488 let vector_matrix_mul = new_definition
2489 `!A:real^N^M x:real^M.
2490 x ** A = lambda j. sum(1..dimindex(:M)) (\i. A$i$j * x$i)`;;
2492 let mat = new_definition
2493 `(mat:num->real^N^M) k = lambda i j. if i = j then &k else &0`;;
2495 let transp = new_definition
2496 `(transp:real^N^M->real^M^N) A = lambda i j. A$j$i`;;
2498 let row = new_definition
2499 `(row:num->real^N^M->real^N) i A = lambda j. A$i$j`;;
2501 let column = new_definition
2502 `(column:num->real^N^M->real^M) j A = lambda i. A$i$j`;;
2504 let rows = new_definition
2505 `rows(A:real^N^M) = { row i A | 1 <= i /\ i <= dimindex(:M)}`;;
2507 let columns = new_definition
2508 `columns(A:real^N^M) = { column i A | 1 <= i /\ i <= dimindex(:N)}`;;
2510 let MATRIX_CMUL_COMPONENT = prove
2511 (`!c A:real^N^M i. (c %% A)$i$j = c * A$i$j`,
2513 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
2514 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2515 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
2516 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2517 ASM_SIMP_TAC[matrix_cmul; CART_EQ; LAMBDA_BETA]);;
2519 let MATRIX_ADD_COMPONENT = prove
2520 (`!A B:real^N^M i j. (A + B)$i$j = A$i$j + B$i$j`,
2522 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
2523 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2524 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
2525 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2526 ASM_SIMP_TAC[matrix_add; LAMBDA_BETA]);;
2528 let MATRIX_SUB_COMPONENT = prove
2529 (`!A B:real^N^M i j. (A - B)$i$j = A$i$j - B$i$j`,
2531 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
2532 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2533 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
2534 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2535 ASM_SIMP_TAC[matrix_sub; LAMBDA_BETA]);;
2537 let MATRIX_NEG_COMPONENT = prove
2538 (`!A:real^N^M i j. (--A)$i$j = --(A$i$j)`,
2540 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
2541 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2542 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
2543 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2544 ASM_SIMP_TAC[matrix_neg; LAMBDA_BETA]);;
2546 let TRANSP_COMPONENT = prove
2547 (`!A:real^N^M i j. (transp A)$i$j = A$j$i`,
2549 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\
2550 (!A:real^M^N. A$i = A$k) /\ (!z:real^N. z$i = z$k)`
2551 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE_2]; ALL_TAC] THEN
2552 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:M) /\
2553 (!A:real^N^M. A$j = A$l) /\ (!z:real^M. z$j = z$l)`
2554 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE_2]; ALL_TAC] THEN
2555 ASM_SIMP_TAC[transp; LAMBDA_BETA]);;
2557 let MAT_COMPONENT = prove
2559 1 <= i /\ i <= dimindex(:M) /\
2560 1 <= j /\ j <= dimindex(:N)
2561 ==> (mat n:real^N^M)$i$j = if i = j then &n else &0`,
2562 SIMP_TAC[mat; LAMBDA_BETA]);;
2564 let MAT_0_COMPONENT = prove
2565 (`!i j. (mat 0:real^N^M)$i$j = &0`,
2567 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
2568 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2569 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
2570 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2571 ASM_SIMP_TAC[mat; COND_ID; LAMBDA_BETA]);;
2573 let MATRIX_CMUL_ASSOC = prove
2574 (`!a b X:real^M^N. a %% (b %% X) = (a * b) %% X`,
2575 SIMP_TAC[CART_EQ; matrix_cmul; LAMBDA_BETA; REAL_MUL_ASSOC]);;
2577 let MATRIX_CMUL_LID = prove
2578 (`!X:real^M^N. &1 %% X = X`,
2579 SIMP_TAC[CART_EQ; matrix_cmul; LAMBDA_BETA; REAL_MUL_LID]);;
2581 let MATRIX_ADD_SYM = prove
2582 (`!A:real^N^M B. A + B = B + A`,
2583 SIMP_TAC[matrix_add; CART_EQ; LAMBDA_BETA; REAL_ADD_AC]);;
2585 let MATRIX_ADD_ASSOC = prove
2586 (`!A:real^N^M B C. A + (B + C) = (A + B) + C`,
2587 SIMP_TAC[matrix_add; CART_EQ; LAMBDA_BETA; REAL_ADD_AC]);;
2589 let MATRIX_ADD_LID = prove
2590 (`!A. mat 0 + A = A`,
2591 SIMP_TAC[matrix_add; mat; COND_ID; CART_EQ; LAMBDA_BETA; REAL_ADD_LID]);;
2593 let MATRIX_ADD_RID = prove
2594 (`!A. A + mat 0 = A`,
2595 SIMP_TAC[matrix_add; mat; COND_ID; CART_EQ; LAMBDA_BETA; REAL_ADD_RID]);;
2597 let MATRIX_ADD_LNEG = prove
2598 (`!A. --A + A = mat 0`,
2599 SIMP_TAC[matrix_neg; matrix_add; mat; COND_ID;
2600 CART_EQ; LAMBDA_BETA; REAL_ADD_LINV]);;
2602 let MATRIX_ADD_RNEG = prove
2603 (`!A. A + --A = mat 0`,
2604 SIMP_TAC[matrix_neg; matrix_add; mat; COND_ID;
2605 CART_EQ; LAMBDA_BETA; REAL_ADD_RINV]);;
2607 let MATRIX_SUB = prove
2608 (`!A:real^N^M B. A - B = A + --B`,
2609 SIMP_TAC[matrix_neg; matrix_add; matrix_sub; CART_EQ; LAMBDA_BETA;
2612 let MATRIX_SUB_REFL = prove
2613 (`!A. A - A = mat 0`,
2614 REWRITE_TAC[MATRIX_SUB; MATRIX_ADD_RNEG]);;
2616 let MATRIX_ADD_LDISTRIB = prove
2617 (`!A:real^N^M B:real^P^N C. A ** (B + C) = A ** B + A ** C`,
2618 SIMP_TAC[matrix_mul; matrix_add; CART_EQ; LAMBDA_BETA;
2619 GSYM SUM_ADD_NUMSEG] THEN
2620 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN
2621 ASM_SIMP_TAC[LAMBDA_BETA; REAL_ADD_LDISTRIB]);;
2623 let MATRIX_MUL_LID = prove
2624 (`!A:real^N^M. mat 1 ** A = A`,
2625 REWRITE_TAC[matrix_mul;
2626 GEN_REWRITE_RULE (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ]
2627 (SPEC_ALL mat)] THEN
2628 SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN REWRITE_TAC[COND_RATOR; COND_RAND] THEN
2629 SIMP_TAC[SUM_DELTA; REAL_MUL_LZERO; IN_NUMSEG; REAL_MUL_LID]);;
2631 let MATRIX_MUL_RID = prove
2632 (`!A:real^N^M. A ** mat 1 = A`,
2633 REWRITE_TAC[matrix_mul; mat] THEN
2634 SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN REWRITE_TAC[COND_RATOR; COND_RAND] THEN
2635 SIMP_TAC[SUM_DELTA; REAL_MUL_RZERO; IN_NUMSEG; REAL_MUL_RID]);;
2637 let MATRIX_MUL_ASSOC = prove
2638 (`!A:real^N^M B:real^P^N C:real^Q^P. A ** B ** C = (A ** B) ** C`,
2640 SIMP_TAC[matrix_mul; CART_EQ; LAMBDA_BETA; GSYM SUM_LMUL; GSYM SUM_RMUL] THEN
2641 REWRITE_TAC[REAL_MUL_ASSOC] THEN REPEAT STRIP_TAC THEN
2642 GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[]);;
2644 let MATRIX_MUL_LZERO = prove
2645 (`!A. (mat 0:real^N^M) ** (A:real^P^N) = mat 0`,
2646 SIMP_TAC[matrix_mul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_LZERO] THEN
2647 REWRITE_TAC[SUM_0]);;
2649 let MATRIX_MUL_RZERO = prove
2650 (`!A. (A:real^N^M) ** (mat 0:real^P^N) = mat 0`,
2651 SIMP_TAC[matrix_mul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_RZERO] THEN
2652 REWRITE_TAC[SUM_0]);;
2654 let MATRIX_ADD_RDISTRIB = prove
2655 (`!A:real^N^M B C:real^P^N. (A + B) ** C = A ** C + B ** C`,
2656 SIMP_TAC[matrix_mul; matrix_add; CART_EQ; LAMBDA_BETA] THEN
2657 REWRITE_TAC[REAL_ADD_RDISTRIB; SUM_ADD_NUMSEG]);;
2659 let MATRIX_SUB_LDISTRIB = prove
2660 (`!A:real^N^M B C:real^P^N. A ** (B - C) = A ** B - A ** C`,
2661 SIMP_TAC[matrix_mul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN
2662 REWRITE_TAC[REAL_SUB_LDISTRIB; SUM_SUB_NUMSEG]);;
2664 let MATRIX_SUB_RDISTRIB = prove
2665 (`!A:real^N^M B C:real^P^N. (A - B) ** C = A ** C - B ** C`,
2666 SIMP_TAC[matrix_mul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN
2667 REWRITE_TAC[REAL_SUB_RDISTRIB; SUM_SUB_NUMSEG]);;
2669 let MATRIX_MUL_LMUL = prove
2670 (`!A:real^N^M B:real^P^N c. (c %% A) ** B = c %% (A ** B)`,
2671 SIMP_TAC[matrix_mul; matrix_cmul; CART_EQ; LAMBDA_BETA] THEN
2672 REWRITE_TAC[GSYM REAL_MUL_ASSOC; SUM_LMUL]);;
2674 let MATRIX_MUL_RMUL = prove
2675 (`!A:real^N^M B:real^P^N c. A ** (c %% B) = c %% (A ** B)`,
2676 SIMP_TAC[matrix_mul; matrix_cmul; CART_EQ; LAMBDA_BETA] THEN
2677 ONCE_REWRITE_TAC[REAL_ARITH `A * c * B:real = c * A * B`] THEN
2678 REWRITE_TAC[SUM_LMUL]);;
2680 let MATRIX_CMUL_ADD_LDISTRIB = prove
2681 (`!A:real^N^M B c. c %% (A + B) = c %% A + c %% B`,
2682 SIMP_TAC[matrix_cmul; matrix_add; CART_EQ; LAMBDA_BETA] THEN
2683 REWRITE_TAC[REAL_ADD_LDISTRIB]);;
2685 let MATRIX_CMUL_SUB_LDISTRIB = prove
2686 (`!A:real^N^M B c. c %% (A - B) = c %% A - c %% B`,
2687 SIMP_TAC[matrix_cmul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN
2688 REWRITE_TAC[REAL_SUB_LDISTRIB]);;
2690 let MATRIX_CMUL_ADD_RDISTRIB = prove
2691 (`!A:real^N^M b c. (b + c) %% A = b %% A + c %% A`,
2692 SIMP_TAC[matrix_cmul; matrix_add; CART_EQ; LAMBDA_BETA] THEN
2693 REWRITE_TAC[REAL_ADD_RDISTRIB]);;
2695 let MATRIX_CMUL_SUB_RDISTRIB = prove
2696 (`!A:real^N^M b c. (b - c) %% A = b %% A - c %% A`,
2697 SIMP_TAC[matrix_cmul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN
2698 REWRITE_TAC[REAL_SUB_RDISTRIB]);;
2700 let MATRIX_CMUL_RZERO = prove
2701 (`!c. c %% mat 0 = mat 0`,
2702 SIMP_TAC[matrix_cmul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_RZERO]);;
2704 let MATRIX_CMUL_LZERO = prove
2705 (`!A. &0 %% A = mat 0`,
2706 SIMP_TAC[matrix_cmul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_LZERO]);;
2708 let MATRIX_NEG_MINUS1 = prove
2709 (`!A:real^N^M. --A = --(&1) %% A`,
2710 REWRITE_TAC[matrix_cmul; matrix_neg; CART_EQ; LAMBDA_BETA] THEN
2711 REWRITE_TAC[GSYM REAL_NEG_MINUS1]);;
2713 let MATRIX_ADD_AC = prove
2714 (`(A:real^N^M) + B = B + A /\
2715 (A + B) + C = A + (B + C) /\
2716 A + (B + C) = B + (A + C)`,
2717 MESON_TAC[MATRIX_ADD_ASSOC; MATRIX_ADD_SYM]);;
2719 let MATRIX_NEG_ADD = prove
2720 (`!A B:real^N^M. --(A + B) = --A + --B`,
2721 SIMP_TAC[matrix_neg; matrix_add; CART_EQ; LAMBDA_BETA; REAL_NEG_ADD]);;
2723 let MATRIX_NEG_SUB = prove
2724 (`!A B:real^N^M. --(A - B) = B - A`,
2725 SIMP_TAC[matrix_neg; matrix_sub; CART_EQ; LAMBDA_BETA; REAL_NEG_SUB]);;
2727 let MATRIX_NEG_0 = prove
2728 (`--(mat 0) = mat 0`,
2729 SIMP_TAC[CART_EQ; mat; matrix_neg; LAMBDA_BETA; REAL_NEG_0; COND_ID]);;
2731 let MATRIX_SUB_RZERO = prove
2732 (`!A:real^N^M. A - mat 0 = A`,
2733 SIMP_TAC[CART_EQ; mat; matrix_sub; LAMBDA_BETA; REAL_SUB_RZERO; COND_ID]);;
2735 let MATRIX_SUB_LZERO = prove
2736 (`!A:real^N^M. mat 0 - A = --A`,
2737 SIMP_TAC[CART_EQ; mat; matrix_sub; matrix_neg;
2738 LAMBDA_BETA; REAL_SUB_LZERO; COND_ID]);;
2740 let MATRIX_NEG_EQ_0 = prove
2741 (`!A:real^N^M. --A = mat 0 <=> A = mat 0`,
2742 SIMP_TAC[CART_EQ; matrix_neg; mat; LAMBDA_BETA; REAL_NEG_EQ_0; COND_ID]);;
2744 let MATRIX_VECTOR_MUL_ASSOC = prove
2745 (`!A:real^N^M B:real^P^N x:real^P. A ** B ** x = (A ** B) ** x`,
2747 SIMP_TAC[matrix_mul; matrix_vector_mul;
2748 CART_EQ; LAMBDA_BETA; GSYM SUM_LMUL; GSYM SUM_RMUL] THEN
2749 REWRITE_TAC[REAL_MUL_ASSOC] THEN REPEAT STRIP_TAC THEN
2750 GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[]);;
2752 let MATRIX_VECTOR_MUL_LID = prove
2753 (`!x:real^N. mat 1 ** x = x`,
2754 REWRITE_TAC[matrix_vector_mul;
2755 GEN_REWRITE_RULE (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ]
2756 (SPEC_ALL mat)] THEN
2757 SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN REWRITE_TAC[COND_RATOR; COND_RAND] THEN
2758 SIMP_TAC[SUM_DELTA; REAL_MUL_LZERO; IN_NUMSEG; REAL_MUL_LID]);;
2760 let MATRIX_VECTOR_MUL_LZERO = prove
2761 (`!x:real^N. mat 0 ** x = vec 0`,
2762 SIMP_TAC[mat; matrix_vector_mul; CART_EQ; VEC_COMPONENT; LAMBDA_BETA;
2763 COND_ID; REAL_MUL_LZERO; SUM_0]);;
2765 let MATRIX_VECTOR_MUL_RZERO = prove
2766 (`!A:real^M^N. A ** vec 0 = vec 0`,
2767 SIMP_TAC[mat; matrix_vector_mul; CART_EQ; VEC_COMPONENT; LAMBDA_BETA;
2768 COND_ID; REAL_MUL_RZERO; SUM_0]);;
2770 let MATRIX_VECTOR_MUL_ADD_LDISTRIB = prove
2771 (`!A:real^M^N x:real^M y. A ** (x + y) = A ** x + A ** y`,
2772 SIMP_TAC[CART_EQ; matrix_vector_mul; VECTOR_ADD_COMPONENT; LAMBDA_BETA;
2773 SUM_ADD_NUMSEG; REAL_ADD_LDISTRIB]);;
2775 let MATRIX_VECTOR_MUL_SUB_LDISTRIB = prove
2776 (`!A:real^M^N x:real^M y. A ** (x - y) = A ** x - A ** y`,
2777 SIMP_TAC[CART_EQ; matrix_vector_mul; VECTOR_SUB_COMPONENT; LAMBDA_BETA;
2778 SUM_SUB_NUMSEG; REAL_SUB_LDISTRIB]);;
2780 let MATRIX_VECTOR_MUL_ADD_RDISTRIB = prove
2781 (`!A:real^M^N B x. (A + B) ** x = (A ** x) + (B ** x)`,
2782 SIMP_TAC[CART_EQ; matrix_vector_mul; matrix_add; LAMBDA_BETA;
2783 VECTOR_ADD_COMPONENT; REAL_ADD_RDISTRIB; SUM_ADD_NUMSEG]);;
2785 let MATRIX_VECTOR_MUL_SUB_RDISTRIB = prove
2786 (`!A:real^M^N B x. (A - B) ** x = (A ** x) - (B ** x)`,
2787 SIMP_TAC[CART_EQ; matrix_vector_mul; matrix_sub; LAMBDA_BETA;
2788 VECTOR_SUB_COMPONENT; REAL_SUB_RDISTRIB; SUM_SUB_NUMSEG]);;
2790 let MATRIX_VECTOR_MUL_RMUL = prove
2791 (`!A:real^M^N x:real^M c. A ** (c % x) = c % (A ** x)`,
2792 SIMP_TAC[CART_EQ; VECTOR_MUL_COMPONENT; matrix_vector_mul; LAMBDA_BETA] THEN
2793 REWRITE_TAC[GSYM SUM_LMUL] THEN REWRITE_TAC[REAL_MUL_AC]);;
2795 let MATRIX_MUL_LNEG = prove
2796 (`!A:real^N^M B:real^P^N. (--A) ** B = --(A ** B)`,
2797 REWRITE_TAC[MATRIX_NEG_MINUS1; MATRIX_MUL_LMUL]);;
2799 let MATRIX_MUL_RNEG = prove
2800 (`!A:real^N^M B:real^P^N. A ** --B = --(A ** B)`,
2801 REWRITE_TAC[MATRIX_NEG_MINUS1; MATRIX_MUL_RMUL]);;
2803 let MATRIX_NEG_NEG = prove
2804 (`!A:real^N^N. --(--A) = A`,
2805 SIMP_TAC[CART_EQ; MATRIX_NEG_COMPONENT; REAL_NEG_NEG]);;
2807 let MATRIX_TRANSP_MUL = prove
2808 (`!A B. transp(A ** B) = transp(B) ** transp(A)`,
2809 SIMP_TAC[matrix_mul; transp; CART_EQ; LAMBDA_BETA] THEN
2810 REWRITE_TAC[REAL_MUL_AC]);;
2812 let SYMMETRIC_MATRIX_MUL = prove
2814 transp(A) = A /\ transp(B) = B
2815 ==> (transp(A ** B) = A ** B <=> A ** B = B ** A)`,
2816 SIMP_TAC[MATRIX_TRANSP_MUL] THEN MESON_TAC[]);;
2818 let MATRIX_EQ = prove
2819 (`!A:real^N^M B. (A = B) = !x:real^N. A ** x = B ** x`,
2820 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
2821 DISCH_THEN(MP_TAC o GEN `i:num` o SPEC `(basis i):real^N`) THEN
2822 SIMP_TAC[CART_EQ; matrix_vector_mul; LAMBDA_BETA; basis] THEN
2823 SIMP_TAC[SUM_DELTA; COND_RAND; REAL_MUL_RZERO] THEN
2824 REWRITE_TAC[TAUT `(if p then b else T) <=> p ==> b`] THEN
2825 SIMP_TAC[REAL_MUL_RID; IN_NUMSEG]);;
2827 let MATRIX_VECTOR_MUL_COMPONENT = prove
2829 1 <= k /\ k <= dimindex(:M) ==> ((A ** x)$k = (A$k) dot x)`,
2830 SIMP_TAC[matrix_vector_mul; LAMBDA_BETA; dot]);;
2832 let DOT_LMUL_MATRIX = prove
2833 (`!A:real^N^M x:real^M y:real^N. (x ** A) dot y = x dot (A ** y)`,
2834 SIMP_TAC[dot; matrix_vector_mul; vector_matrix_mul; dot; LAMBDA_BETA] THEN
2835 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
2836 REWRITE_TAC[GSYM SUM_RMUL] THEN
2837 GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[REAL_MUL_AC]);;
2839 let TRANSP_MATRIX_CMUL = prove
2840 (`!A:real^M^N c. transp(c %% A) = c %% transp A`,
2841 SIMP_TAC[CART_EQ; transp; MATRIX_CMUL_COMPONENT; LAMBDA_BETA]);;
2843 let TRANSP_MATRIX_ADD = prove
2844 (`!A B:real^N^M. transp(A + B) = transp A + transp B`,
2845 SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; matrix_add]);;
2847 let TRANSP_MATRIX_SUB = prove
2848 (`!A B:real^N^M. transp(A - B) = transp A - transp B`,
2849 SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; matrix_sub]);;
2851 let TRANSP_MATRIX_NEG = prove
2852 (`!A:real^N^M. transp(--A) = --(transp A)`,
2853 SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; matrix_neg]);;
2855 let TRANSP_MAT = prove
2856 (`!n. transp(mat n) = mat n`,
2857 SIMP_TAC[transp; mat; LAMBDA_BETA; CART_EQ; EQ_SYM_EQ]);;
2859 let TRANSP_TRANSP = prove
2860 (`!A:real^N^M. transp(transp A) = A`,
2861 SIMP_TAC[CART_EQ; transp; LAMBDA_BETA]);;
2863 let SYMMETRIX_MATRIX_CONJUGATE = prove
2864 (`!A B:real^N^N. transp B = B
2865 ==> transp(transp A ** B ** A) = transp A ** B ** A`,
2866 SIMP_TAC[MATRIX_TRANSP_MUL; TRANSP_TRANSP; MATRIX_MUL_ASSOC]);;
2868 let TRANSP_EQ = prove
2869 (`!A B:real^M^N. transp A = transp B <=> A = B`,
2870 MESON_TAC[TRANSP_TRANSP]);;
2872 let ROW_TRANSP = prove
2874 1 <= i /\ i <= dimindex(:N) ==> row i (transp A) = column i A`,
2875 SIMP_TAC[row; column; transp; CART_EQ; LAMBDA_BETA]);;
2877 let COLUMN_TRANSP = prove
2879 1 <= i /\ i <= dimindex(:M) ==> column i (transp A) = row i A`,
2880 SIMP_TAC[row; column; transp; CART_EQ; LAMBDA_BETA]);;
2882 let ROWS_TRANSP = prove
2883 (`!A:real^N^M. rows(transp A) = columns A`,
2884 REWRITE_TAC[rows; columns; EXTENSION; IN_ELIM_THM] THEN
2885 MESON_TAC[ROW_TRANSP]);;
2887 let COLUMNS_TRANSP = prove
2888 (`!A:real^N^M. columns(transp A) = rows A`,
2889 MESON_TAC[TRANSP_TRANSP; ROWS_TRANSP]);;
2891 let VECTOR_MATRIX_MUL_TRANSP = prove
2892 (`!A:real^M^N x:real^N. x ** A = transp A ** x`,
2893 REWRITE_TAC[matrix_vector_mul; vector_matrix_mul; transp] THEN
2894 SIMP_TAC[LAMBDA_BETA; CART_EQ]);;
2896 let MATRIX_VECTOR_MUL_TRANSP = prove
2897 (`!A:real^M^N x:real^M. A ** x = x ** transp A`,
2898 REWRITE_TAC[VECTOR_MATRIX_MUL_TRANSP; TRANSP_TRANSP]);;
2900 let FINITE_ROWS = prove
2901 (`!A:real^N^M. FINITE(rows A)`,
2902 REWRITE_TAC[rows] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
2903 SIMP_TAC[GSYM numseg; FINITE_IMAGE; FINITE_NUMSEG]);;
2905 let FINITE_COLUMNS = prove
2906 (`!A:real^N^M. FINITE(columns A)`,
2907 REWRITE_TAC[columns] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
2908 SIMP_TAC[GSYM numseg; FINITE_IMAGE; FINITE_NUMSEG]);;
2910 let MATRIX_EQUAL_ROWS = prove
2912 A = B <=> !i. 1 <= i /\ i <= dimindex(:M) ==> row i A = row i B`,
2913 SIMP_TAC[row; CART_EQ; LAMBDA_BETA]);;
2915 let MATRIX_EQUAL_COLUMNS = prove
2917 A = B <=> !i. 1 <= i /\ i <= dimindex(:N) ==> column i A = column i B`,
2918 SIMP_TAC[column; CART_EQ; LAMBDA_BETA] THEN MESON_TAC[]);;
2920 (* ------------------------------------------------------------------------- *)
2921 (* Two sometimes fruitful ways of looking at matrix-vector multiplication. *)
2922 (* ------------------------------------------------------------------------- *)
2924 let MATRIX_MUL_DOT = prove
2925 (`!A:real^N^M x. A ** x = lambda i. A$i dot x`,
2926 REWRITE_TAC[matrix_vector_mul; dot] THEN SIMP_TAC[CART_EQ; LAMBDA_BETA]);;
2928 let MATRIX_MUL_VSUM = prove
2929 (`!A:real^N^M x. A ** x = vsum(1..dimindex(:N)) (\i. x$i % column i A)`,
2930 SIMP_TAC[matrix_vector_mul; CART_EQ; VSUM_COMPONENT; LAMBDA_BETA;
2931 VECTOR_MUL_COMPONENT; column; REAL_MUL_AC]);;
2933 (* ------------------------------------------------------------------------- *)
2934 (* Slightly gruesome lemmas: better to define sums over vectors really... *)
2935 (* ------------------------------------------------------------------------- *)
2937 let VECTOR_COMPONENTWISE = prove
2939 x = lambda j. sum(1..dimindex(:N))
2940 (\i. x$i * (basis i :real^N)$j)`,
2941 SIMP_TAC[CART_EQ; LAMBDA_BETA; basis] THEN
2942 ONCE_REWRITE_TAC[ARITH_RULE `(m:num = n) <=> (n = m)`] THEN
2943 SIMP_TAC[COND_RAND; REAL_MUL_RZERO; SUM_DELTA; IN_NUMSEG] THEN
2944 REWRITE_TAC[REAL_MUL_RID; COND_ID]);;
2946 let LINEAR_COMPONENTWISE_EXPANSION = prove
2947 (`!f:real^M->real^N.
2949 ==> !x j. 1 <= j /\ j <= dimindex(:N)
2951 sum(1..dimindex(:M)) (\i. x$i * f(basis i)$j))`,
2952 REWRITE_TAC[linear] THEN REPEAT STRIP_TAC THEN
2953 GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV)
2954 [VECTOR_COMPONENTWISE] THEN
2955 SPEC_TAC(`dimindex(:M)`,`n:num`) THEN
2956 INDUCT_TAC THEN REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH] THENL
2957 [REWRITE_TAC[GSYM vec] THEN
2958 GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV)
2959 [GSYM VECTOR_MUL_LZERO] THEN
2960 ASM_REWRITE_TAC[] THEN REWRITE_TAC[VECTOR_MUL_LZERO] THEN
2961 ASM_SIMP_TAC[vec; LAMBDA_BETA];
2962 REWRITE_TAC[ARITH_RULE `1 <= SUC n`] THEN
2963 ASSUM_LIST(fun thl -> REWRITE_TAC(map GSYM thl)) THEN
2964 SIMP_TAC[GSYM VECTOR_MUL_COMPONENT;
2965 ASSUME `1 <= j`; ASSUME `j <= dimindex(:N)`] THEN
2966 ASSUM_LIST(fun thl -> REWRITE_TAC(map GSYM thl)) THEN
2967 SIMP_TAC[GSYM VECTOR_ADD_COMPONENT;
2968 ASSUME `1 <= j`; ASSUME `j <= dimindex(:N)`] THEN
2969 ASSUM_LIST(fun thl -> REWRITE_TAC(map GSYM thl)) THEN
2970 AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
2971 ASM_SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; LAMBDA_BETA] THEN
2972 SIMP_TAC[VECTOR_MUL_COMPONENT]]);;
2974 (* ------------------------------------------------------------------------- *)
2975 (* Inverse matrices (not necessarily square, but it's vacuous otherwise). *)
2976 (* ------------------------------------------------------------------------- *)
2978 let invertible = new_definition
2979 `invertible(A:real^N^M) <=>
2980 ?A':real^M^N. (A ** A' = mat 1) /\ (A' ** A = mat 1)`;;
2982 let matrix_inv = new_definition
2983 `matrix_inv(A:real^N^M) =
2984 @A':real^M^N. (A ** A' = mat 1) /\ (A' ** A = mat 1)`;;
2986 let MATRIX_INV = prove
2988 invertible A ==> A ** matrix_inv A = mat 1 /\ matrix_inv A ** A = mat 1`,
2989 GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[matrix_inv; invertible] THEN
2990 CONV_TAC SELECT_CONV THEN ASM_REWRITE_TAC[GSYM invertible]);;
2992 let MATRIX_INV_UNIQUE = prove
2993 (`!A:real^N^M B. A ** B = mat 1 /\ B ** A = mat 1 ==> matrix_inv A = B`,
2994 REPEAT STRIP_TAC THEN MP_TAC(ISPEC `A:real^N^M` MATRIX_INV) THEN
2995 ANTS_TAC THENL [ASM_MESON_TAC[invertible]; ALL_TAC] THEN
2997 AP_TERM `(( ** ):real^M^N->real^M^M->real^M^N) B` o CONJUNCT1) THEN
2998 ASM_REWRITE_TAC[MATRIX_MUL_ASSOC; MATRIX_MUL_LID; MATRIX_MUL_RID]);;
3000 let INVERTIBLE_NEG = prove
3001 (`!A:real^N^M. invertible(--A) <=> invertible A`,
3002 REWRITE_TAC[invertible] THEN
3003 MESON_TAC[MATRIX_MUL_LNEG; MATRIX_MUL_RNEG; MATRIX_NEG_NEG]);;
3005 let MATRIX_INV_I = prove
3006 (`matrix_inv(mat 1:real^N^N) = mat 1`,
3007 MATCH_MP_TAC MATRIX_INV_UNIQUE THEN
3008 REWRITE_TAC[MATRIX_MUL_LID]);;
3010 (* ------------------------------------------------------------------------- *)
3011 (* Correspondence between matrices and linear operators. *)
3012 (* ------------------------------------------------------------------------- *)
3014 let matrix = new_definition
3015 `(matrix:(real^M->real^N)->real^M^N) f = lambda i j. f(basis j)$i`;;
3017 let MATRIX_VECTOR_MUL_LINEAR = prove
3018 (`!A:real^N^M. linear(\x. A ** x)`,
3019 REWRITE_TAC[linear; matrix_vector_mul] THEN
3020 SIMP_TAC[CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
3021 VECTOR_MUL_COMPONENT] THEN
3022 REWRITE_TAC[GSYM SUM_ADD_NUMSEG; GSYM SUM_LMUL; REAL_ADD_LDISTRIB] THEN
3023 REWRITE_TAC[REAL_ADD_AC; REAL_MUL_AC]);;
3025 let MATRIX_WORKS = prove
3026 (`!f:real^M->real^N. linear f ==> !x. matrix f ** x = f(x)`,
3027 REWRITE_TAC[matrix; matrix_vector_mul] THEN
3028 SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN GEN_TAC THEN DISCH_TAC THEN
3029 REPEAT GEN_TAC THEN DISCH_TAC THEN
3030 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
3031 ASM_SIMP_TAC[GSYM LINEAR_COMPONENTWISE_EXPANSION]);;
3033 let MATRIX_VECTOR_MUL = prove
3034 (`!f:real^M->real^N. linear f ==> f = \x. matrix f ** x`,
3035 SIMP_TAC[FUN_EQ_THM; MATRIX_WORKS]);;
3037 let MATRIX_OF_MATRIX_VECTOR_MUL = prove
3038 (`!A:real^N^M. matrix(\x. A ** x) = A`,
3039 SIMP_TAC[MATRIX_EQ; MATRIX_VECTOR_MUL_LINEAR; MATRIX_WORKS]);;
3041 let MATRIX_COMPOSE = prove
3042 (`!f g. linear f /\ linear g ==> (matrix(g o f) = matrix g ** matrix f)`,
3043 SIMP_TAC[MATRIX_EQ; MATRIX_WORKS; LINEAR_COMPOSE;
3044 GSYM MATRIX_VECTOR_MUL_ASSOC; o_THM]);;
3046 let MATRIX_VECTOR_COLUMN = prove
3048 A ** x = vsum(1..dimindex(:N)) (\i. x$i % (transp A)$i)`,
3049 REWRITE_TAC[matrix_vector_mul; transp] THEN
3050 SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; VECTOR_MUL_COMPONENT] THEN
3051 REWRITE_TAC[REAL_MUL_AC]);;
3053 let MATRIX_MUL_COMPONENT = prove
3054 (`!i. 1 <= i /\ i <= dimindex(:N)
3055 ==> ((A:real^N^N) ** (B:real^N^N))$i = transp B ** A$i`,
3056 SIMP_TAC[matrix_mul; LAMBDA_BETA; matrix_vector_mul; vector_matrix_mul;
3057 transp; CART_EQ] THEN
3058 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN
3059 REWRITE_TAC[REAL_MUL_AC]);;
3061 let ADJOINT_MATRIX = prove
3062 (`!A:real^N^M. adjoint(\x. A ** x) = (\x. transp A ** x)`,
3063 GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC ADJOINT_UNIQUE THEN
3064 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN REPEAT GEN_TAC THEN
3065 SIMP_TAC[transp; dot; LAMBDA_BETA; matrix_vector_mul;
3066 GSYM SUM_LMUL; GSYM SUM_RMUL] THEN
3067 GEN_REWRITE_TAC LAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[REAL_MUL_AC]);;
3069 let MATRIX_ADJOINT = prove
3070 (`!f. linear f ==> matrix(adjoint f) = transp(matrix f)`,
3071 GEN_TAC THEN DISCH_THEN
3072 (fun th -> GEN_REWRITE_TAC (LAND_CONV o funpow 2 RAND_CONV)
3073 [MATCH_MP MATRIX_VECTOR_MUL th]) THEN
3074 REWRITE_TAC[ADJOINT_MATRIX; MATRIX_OF_MATRIX_VECTOR_MUL]);;
3076 let MATRIX_ID = prove
3077 (`matrix(\x. x) = mat 1`,
3078 SIMP_TAC[MATRIX_EQ; LINEAR_ID; MATRIX_WORKS; MATRIX_VECTOR_MUL_LID]);;
3080 let MATRIX_I = prove
3081 (`matrix I = mat 1`,
3082 REWRITE_TAC[I_DEF; MATRIX_ID]);;
3084 let LINEAR_EQ_MATRIX = prove
3085 (`!f g. linear f /\ linear g /\ matrix f = matrix g ==> f = g`,
3086 REPEAT STRIP_TAC THEN
3087 REPEAT(FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP MATRIX_VECTOR_MUL)) THEN
3088 ASM_REWRITE_TAC[]);;
3090 let MATRIX_SELF_ADJOINT = prove
3091 (`!f. linear f ==> (adjoint f = f <=> transp(matrix f) = matrix f)`,
3092 SIMP_TAC[GSYM MATRIX_ADJOINT] THEN
3093 MESON_TAC[LINEAR_EQ_MATRIX; ADJOINT_LINEAR]);;
3095 let LINEAR_MATRIX_EXISTS = prove
3096 (`!f:real^M->real^N. linear f <=> ?A:real^M^N. f = \x. A ** x`,
3097 GEN_TAC THEN EQ_TAC THEN
3098 SIMP_TAC[MATRIX_VECTOR_MUL_LINEAR; LEFT_IMP_EXISTS_THM] THEN
3099 DISCH_TAC THEN EXISTS_TAC `matrix(f:real^M->real^N)` THEN
3100 ASM_SIMP_TAC[GSYM MATRIX_VECTOR_MUL]);;
3102 let LINEAR_1 = prove
3103 (`!f:real^1->real^1. linear f <=> ?c. f = \x. c % x`,
3104 SIMP_TAC[LINEAR_MATRIX_EXISTS; EXISTS_VECTOR_1] THEN
3105 SIMP_TAC[FUN_EQ_THM; CART_EQ; FORALL_1; DIMINDEX_1; VECTOR_1;
3106 matrix_vector_mul; SUM_1; CART_EQ; LAMBDA_BETA;
3107 VECTOR_MUL_COMPONENT]);;
3109 let SYMMETRIC_MATRIX = prove
3110 (`!A:real^N^N. transp A = A <=> adjoint(\x. A ** x) = \x. A ** x`,
3111 SIMP_TAC[MATRIX_SELF_ADJOINT; MATRIX_VECTOR_MUL_LINEAR] THEN
3112 REWRITE_TAC[MATRIX_OF_MATRIX_VECTOR_MUL]);;
3114 let SYMMETRIC_MATRIX_ORTHOGONAL_EIGENVECTORS = prove
3115 (`!A:real^N^N v w a b.
3116 transp A = A /\ A ** v = a % v /\ A ** w = b % w /\ ~(a = b)
3117 ==> orthogonal v w`,
3118 REPEAT GEN_TAC THEN REWRITE_TAC[SYMMETRIC_MATRIX] THEN
3119 DISCH_THEN(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT]
3120 SELF_ADJOINT_ORTHOGONAL_EIGENVECTORS)) THEN
3121 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);;
3123 (* ------------------------------------------------------------------------- *)
3124 (* Operator norm. *)
3125 (* ------------------------------------------------------------------------- *)
3127 let onorm = new_definition
3128 `onorm (f:real^M->real^N) = sup { norm(f x) | norm(x) = &1 }`;;
3130 let NORM_BOUND_GENERALIZE = prove
3131 (`!f:real^M->real^N b.
3133 ==> ((!x. (norm(x) = &1) ==> norm(f x) <= b) <=>
3134 (!x. norm(f x) <= b * norm(x)))`,
3135 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
3136 [ALL_TAC; ASM_MESON_TAC[REAL_MUL_RID]] THEN
3137 X_GEN_TAC `x:real^M` THEN ASM_CASES_TAC `x:real^M = vec 0` THENL
3138 [ASM_REWRITE_TAC[NORM_0; REAL_MUL_RZERO] THEN
3139 ASM_MESON_TAC[LINEAR_0; NORM_0; REAL_LE_REFL];
3141 ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; NORM_POS_LT; real_div] THEN
3142 MATCH_MP_TAC(REAL_ARITH `abs(a * b) <= c ==> b * a <= c`) THEN
3143 REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NORM; GSYM NORM_MUL] THEN
3144 FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN
3145 ASM_SIMP_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM; REAL_MUL_LINV;
3149 (`!f:real^M->real^N.
3151 ==> (!x. norm(f x) <= onorm f * norm(x)) /\
3152 (!b. (!x. norm(f x) <= b * norm(x)) ==> onorm f <= b)`,
3153 GEN_TAC THEN DISCH_TAC THEN
3154 MP_TAC(SPEC `{ norm((f:real^M->real^N) x) | norm(x) = &1 }` SUP) THEN
3155 SIMP_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
3156 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
3157 REWRITE_TAC[LEFT_FORALL_IMP_THM; RIGHT_EXISTS_AND_THM; EXISTS_REFL] THEN
3158 ASM_SIMP_TAC[NORM_BOUND_GENERALIZE; GSYM onorm; GSYM MEMBER_NOT_EMPTY] THEN
3159 DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
3160 ASM_MESON_TAC[VECTOR_CHOOSE_SIZE; LINEAR_BOUNDED; REAL_POS]);;
3162 let ONORM_POS_LE = prove
3163 (`!f. linear f ==> &0 <= onorm f`,
3164 MESON_TAC[ONORM; VECTOR_CHOOSE_SIZE; REAL_POS; REAL_MUL_RID; NORM_POS_LE;
3167 let ONORM_EQ_0 = prove
3168 (`!f:real^M->real^N. linear f ==> ((onorm f = &0) <=> (!x. f x = vec 0))`,
3169 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
3170 MP_TAC(SPEC `f:real^M->real^N` ONORM) THEN
3171 ASM_SIMP_TAC[GSYM REAL_LE_ANTISYM; ONORM_POS_LE; NORM_0; REAL_MUL_LZERO;
3172 NORM_LE_0; REAL_LE_REFL]);;
3174 let ONORM_CONST = prove
3175 (`!y:real^N. onorm(\x:real^M. y) = norm(y)`,
3176 GEN_TAC THEN REWRITE_TAC[onorm] THEN
3177 MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `sup {norm(y:real^N)}` THEN
3179 [AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE
3180 `(?x. P x) ==> {f y | x | P x} = {f y}`) THEN
3181 EXISTS_TAC `basis 1 :real^M` THEN
3182 SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL];
3183 MATCH_MP_TAC REAL_SUP_UNIQUE THEN SET_TAC[REAL_LE_REFL]]);;
3185 let ONORM_POS_LT = prove
3186 (`!f. linear f ==> (&0 < onorm f <=> ~(!x. f x = vec 0))`,
3187 SIMP_TAC[GSYM ONORM_EQ_0; ONORM_POS_LE;
3188 REAL_ARITH `(&0 < x <=> ~(x = &0)) <=> &0 <= x`]);;
3190 let ONORM_COMPOSE = prove
3191 (`!f g. linear f /\ linear g ==> onorm(f o g) <= onorm f * onorm g`,
3192 MESON_TAC[ONORM; LINEAR_COMPOSE; o_THM; REAL_MUL_ASSOC; REAL_LE_TRANS; ONORM;
3193 REAL_LE_LMUL; ONORM_POS_LE]);;
3195 let ONORM_NEG_LEMMA = prove
3196 (`!f. linear f ==> onorm(\x. --(f x)) <= onorm f`,
3197 REPEAT STRIP_TAC THEN
3198 FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP ONORM o
3199 MATCH_MP LINEAR_COMPOSE_NEG) THEN
3200 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[NORM_NEG; ONORM]);;
3202 let ONORM_NEG = prove
3203 (`!f:real^M->real^N. linear f ==> (onorm(\x. --(f x)) = onorm f)`,
3204 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
3205 ASM_SIMP_TAC[ONORM_NEG_LEMMA] THEN
3206 SUBGOAL_THEN `f:real^M->real^N = \x. --(--(f x))`
3207 (fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN
3208 ASM_SIMP_TAC[ONORM_NEG_LEMMA; LINEAR_COMPOSE_NEG] THEN
3209 REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);;
3211 let ONORM_TRIANGLE = prove
3212 (`!f:real^M->real^N g.
3213 linear f /\ linear g ==> onorm(\x. f x + g x) <= onorm f + onorm g`,
3214 REPEAT GEN_TAC THEN DISCH_TAC THEN
3215 FIRST_ASSUM(MATCH_MP_TAC o CONJUNCT2 o MATCH_MP ONORM o MATCH_MP
3216 LINEAR_COMPOSE_ADD) THEN
3217 REWRITE_TAC[REAL_ADD_RDISTRIB] THEN
3218 ASM_MESON_TAC[REAL_LE_ADD2; REAL_LE_TRANS; NORM_TRIANGLE; ONORM]);;
3220 let ONORM_TRIANGLE_LE = prove
3221 (`!f g. linear f /\ linear g /\ onorm(f) + onorm(g) <= e
3222 ==> onorm(\x. f x + g x) <= e`,
3223 MESON_TAC[REAL_LE_TRANS; ONORM_TRIANGLE]);;
3225 let ONORM_TRIANGLE_LT = prove
3226 (`!f g. linear f /\ linear g /\ onorm(f) + onorm(g) < e
3227 ==> onorm(\x. f x + g x) < e`,
3228 MESON_TAC[REAL_LET_TRANS; ONORM_TRIANGLE]);;
3230 let ONORM_ID = prove
3231 (`onorm(\x:real^N. x) = &1`,
3232 REWRITE_TAC[onorm] THEN
3233 SUBGOAL_THEN `{norm(x:real^N) | norm x = &1} = {&1}`
3234 (fun th -> REWRITE_TAC[th; SUP_SING]) THEN
3235 SUBGOAL_THEN `norm(basis 1:real^N) = &1` MP_TAC THENL
3236 [SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL]; SET_TAC[]]);;
3239 (`onorm(I:real^N->real^N) = &1`,
3240 REWRITE_TAC[I_DEF; ONORM_ID]);;
3242 (* ------------------------------------------------------------------------- *)
3243 (* It's handy to "lift" from R to R^1 and "drop" from R^1 to R. *)
3244 (* ------------------------------------------------------------------------- *)
3246 let lift = new_definition
3247 `(lift:real->real^1) x = lambda i. x`;;
3249 let drop = new_definition
3250 `(drop:real^1->real) x = x$1`;;
3252 let LIFT_COMPONENT = prove
3253 (`!x. (lift x)$1 = x`,
3254 SIMP_TAC[lift; LAMBDA_BETA; DIMINDEX_1; LE_ANTISYM]);;
3256 let LIFT_DROP = prove
3257 (`(!x. lift(drop x) = x) /\ (!x. drop(lift x) = x)`,
3258 SIMP_TAC[lift; drop; CART_EQ; LAMBDA_BETA; DIMINDEX_1; LE_ANTISYM]);;
3260 let IMAGE_LIFT_DROP = prove
3261 (`(!s. IMAGE (lift o drop) s = s) /\ (!s. IMAGE (drop o lift) s = s)`,
3262 REWRITE_TAC[o_DEF; LIFT_DROP] THEN SET_TAC[]);;
3264 let IN_IMAGE_LIFT_DROP = prove
3265 (`(!x s. x IN IMAGE lift s <=> drop x IN s) /\
3266 (!x s. x IN IMAGE drop s <=> lift x IN s)`,
3267 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);;
3269 let FORALL_LIFT = prove
3270 (`(!x. P x) = (!x. P(lift x))`,
3271 MESON_TAC[LIFT_DROP]);;
3273 let EXISTS_LIFT = prove
3274 (`(?x. P x) = (?x. P(lift x))`,
3275 MESON_TAC[LIFT_DROP]);;
3277 let FORALL_DROP = prove
3278 (`(!x. P x) = (!x. P(drop x))`,
3279 MESON_TAC[LIFT_DROP]);;
3281 let EXISTS_DROP = prove
3282 (`(?x. P x) = (?x. P(drop x))`,
3283 MESON_TAC[LIFT_DROP]);;
3285 let FORALL_LIFT_FUN = prove
3286 (`!P:(A->real^1)->bool. (!f. P f) <=> (!f. P(lift o f))`,
3287 GEN_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN DISCH_TAC THEN
3288 X_GEN_TAC `f:A->real^1` THEN
3289 FIRST_X_ASSUM(MP_TAC o SPEC `drop o (f:A->real^1)`) THEN
3290 REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]);;
3292 let FORALL_DROP_FUN = prove
3293 (`!P:(A->real)->bool. (!f. P f) <=> (!f. P(drop o f))`,
3294 REWRITE_TAC[FORALL_LIFT_FUN; o_DEF; LIFT_DROP; ETA_AX]);;
3296 let EXISTS_LIFT_FUN = prove
3297 (`!P:(A->real^1)->bool. (?f. P f) <=> (?f. P(lift o f))`,
3298 ONCE_REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
3299 REWRITE_TAC[FORALL_LIFT_FUN]);;
3301 let EXISTS_DROP_FUN = prove
3302 (`!P:(A->real)->bool. (?f. P f) <=> (?f. P(drop o f))`,
3303 ONCE_REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
3304 REWRITE_TAC[FORALL_DROP_FUN]);;
3307 (`!x y. (lift x = lift y) <=> (x = y)`,
3308 MESON_TAC[LIFT_DROP]);;
3311 (`!x y. (drop x = drop y) <=> (x = y)`,
3312 MESON_TAC[LIFT_DROP]);;
3314 let LIFT_IN_IMAGE_LIFT = prove
3315 (`!x s. (lift x) IN (IMAGE lift s) <=> x IN s`,
3316 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);;
3318 let FORALL_LIFT_IMAGE = prove
3319 (`!P. (!s. P s) <=> (!s. P(IMAGE lift s))`,
3320 MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);;
3322 let EXISTS_LIFT_IMAGE = prove
3323 (`!P. (?s. P s) <=> (?s. P(IMAGE lift s))`,
3324 MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);;
3326 let SUBSET_LIFT_IMAGE = prove
3327 (`!s t. IMAGE lift s SUBSET IMAGE lift t <=> s SUBSET t`,
3328 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[IMAGE_SUBSET] THEN
3329 DISCH_THEN(MP_TAC o ISPEC `drop` o MATCH_MP IMAGE_SUBSET) THEN
3330 REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP]);;
3332 let FORALL_DROP_IMAGE = prove
3333 (`!P. (!s. P s) <=> (!s. P(IMAGE drop s))`,
3334 MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);;
3336 let EXISTS_DROP_IMAGE = prove
3337 (`!P. (?s. P s) <=> (?s. P(IMAGE drop s))`,
3338 MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);;
3340 let SUBSET_DROP_IMAGE = prove
3341 (`!s t. IMAGE drop s SUBSET IMAGE drop t <=> s SUBSET t`,
3342 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[IMAGE_SUBSET] THEN
3343 DISCH_THEN(MP_TAC o ISPEC `lift` o MATCH_MP IMAGE_SUBSET) THEN
3344 REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP]);;
3346 let DROP_IN_IMAGE_DROP = prove
3347 (`!x s. (drop x) IN (IMAGE drop s) <=> x IN s`,
3348 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);;
3350 let LIFT_NUM = prove
3351 (`!n. lift(&n) = vec n`,
3352 SIMP_TAC[CART_EQ; lift; vec; LAMBDA_BETA]);;
3354 let LIFT_ADD = prove
3355 (`!x y. lift(x + y) = lift x + lift y`,
3356 SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_ADD_COMPONENT]);;
3358 let LIFT_SUB = prove
3359 (`!x y. lift(x - y) = lift x - lift y`,
3360 SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_SUB_COMPONENT]);;
3362 let LIFT_CMUL = prove
3363 (`!x c. lift(c * x) = c % lift(x)`,
3364 SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_MUL_COMPONENT]);;
3366 let LIFT_NEG = prove
3367 (`!x. lift(--x) = --(lift x)`,
3368 SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_NEG_COMPONENT]);;
3370 let LIFT_EQ_CMUL = prove
3371 (`!x. lift x = x % vec 1`,
3372 REWRITE_TAC[GSYM LIFT_NUM; GSYM LIFT_CMUL; REAL_MUL_RID]);;
3374 let LIFT_SUM = prove
3375 (`!k x. FINITE k ==> (lift(sum k x) = vsum k (lift o x))`,
3376 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
3377 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3378 SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; o_THM; LIFT_ADD; LIFT_NUM]);;
3380 let DROP_LAMBDA = prove
3381 (`!x. drop(lambda i. x i) = x 1`,
3382 SIMP_TAC[drop; LAMBDA_BETA; DIMINDEX_1; LE_REFL]);;
3384 let DROP_VEC = prove
3385 (`!n. drop(vec n) = &n`,
3386 MESON_TAC[LIFT_DROP; LIFT_NUM]);;
3388 let DROP_ADD = prove
3389 (`!x y. drop(x + y) = drop x + drop y`,
3390 MESON_TAC[LIFT_DROP; LIFT_ADD]);;
3392 let DROP_SUB = prove
3393 (`!x y. drop(x - y) = drop x - drop y`,
3394 MESON_TAC[LIFT_DROP; LIFT_SUB]);;
3396 let DROP_CMUL = prove
3397 (`!x c. drop(c % x) = c * drop(x)`,
3398 MESON_TAC[LIFT_DROP; LIFT_CMUL]);;
3400 let DROP_NEG = prove
3401 (`!x. drop(--x) = --(drop x)`,
3402 MESON_TAC[LIFT_DROP; LIFT_NEG]);;
3404 let DROP_VSUM = prove
3405 (`!k x. FINITE k ==> (drop(vsum k x) = sum k (drop o x))`,
3406 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
3407 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3408 SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; o_THM; DROP_ADD; DROP_VEC]);;
3411 (`!x. norm x = abs(drop x)`,
3412 REWRITE_TAC[drop; NORM_REAL]);;
3414 let NORM_1_POS = prove
3415 (`!x. &0 <= drop x ==> norm x = drop x`,
3416 SIMP_TAC[NORM_1; real_abs]);;
3418 let NORM_LIFT = prove
3419 (`!x. norm(lift x) = abs(x)`,
3420 SIMP_TAC[lift; NORM_REAL; LIFT_COMPONENT]);;
3422 let DIST_LIFT = prove
3423 (`!x y. dist(lift x,lift y) = abs(x - y)`,
3424 REWRITE_TAC[DIST_REAL; LIFT_COMPONENT]);;
3426 let ABS_DROP = prove
3427 (`!x. norm x = abs(drop x)`,
3428 REWRITE_TAC[FORALL_LIFT; LIFT_DROP; NORM_LIFT]);;
3430 let LINEAR_VMUL_DROP = prove
3431 (`!f v. linear f ==> linear (\x. drop(f x) % v)`,
3432 SIMP_TAC[drop; LINEAR_VMUL_COMPONENT; DIMINDEX_1; LE_REFL]);;
3434 let LINEAR_FROM_REALS = prove
3435 (`!f:real^1->real^N. linear f ==> f = \x. drop x % column 1 (matrix f)`,
3436 GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
3437 DISCH_THEN(fun th -> REWRITE_TAC[GSYM(MATCH_MP MATRIX_WORKS th)]) THEN
3438 SIMP_TAC[CART_EQ; matrix_vector_mul; vector_mul; LAMBDA_BETA;
3439 DIMINDEX_1; SUM_SING_NUMSEG; drop; column] THEN
3440 REWRITE_TAC[REAL_MUL_AC]);;
3442 let LINEAR_TO_REALS = prove
3443 (`!f:real^N->real^1. linear f ==> f = \x. lift(row 1 (matrix f) dot x)`,
3444 GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
3445 DISCH_THEN(fun th -> REWRITE_TAC[GSYM(MATCH_MP MATRIX_WORKS th)]) THEN
3446 SIMP_TAC[CART_EQ; matrix_vector_mul; dot; LAMBDA_BETA;
3447 DIMINDEX_1; SUM_SING_NUMSEG; lift; row; LE_ANTISYM]);;
3449 let DROP_EQ_0 = prove
3450 (`!x. drop x = &0 <=> x = vec 0`,
3451 REWRITE_TAC[GSYM DROP_EQ; DROP_VEC]);;
3453 let VSUM_REAL = prove
3454 (`!f s. FINITE s ==> vsum s f = lift(sum s (drop o f))`,
3455 SIMP_TAC[LIFT_SUM; o_DEF; LIFT_DROP; ETA_AX]);;
3457 let DROP_WLOG_LE = prove
3458 (`(!x y. P x y <=> P y x) /\ (!x y. drop x <= drop y ==> P x y)
3460 MESON_TAC[REAL_LE_TOTAL]);;
3462 let IMAGE_LIFT_UNIV = prove
3463 (`IMAGE lift (:real) = (:real^1)`,
3464 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNIV] THEN MESON_TAC[LIFT_DROP]);;
3466 let IMAGE_DROP_UNIV = prove
3467 (`IMAGE drop (:real^1) = (:real)`,
3468 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNIV] THEN MESON_TAC[LIFT_DROP]);;
3470 let SUM_VSUM = prove
3471 (`!f s. FINITE s ==> sum s f = drop(vsum s (lift o f))`,
3472 SIMP_TAC[VSUM_REAL; o_DEF; LIFT_DROP; ETA_AX]);;
3474 let LINEAR_LIFT_DOT = prove
3475 (`!a. linear(\x. lift(a dot x))`,
3476 REWRITE_TAC[linear; DOT_RMUL; DOT_RADD; LIFT_ADD; LIFT_CMUL]);;
3478 let LINEAR_LIFT_COMPONENT = prove
3479 (`!k. linear(\x:real^N. lift(x$k))`,
3481 SUBGOAL_THEN `?j. 1 <= j /\ j <= dimindex(:N) /\ !z:real^N. z$k = z$j`
3483 [REWRITE_TAC[FINITE_INDEX_INRANGE];
3484 MP_TAC(ISPEC `basis j:real^N` LINEAR_LIFT_DOT) THEN
3485 ASM_SIMP_TAC[DOT_BASIS]]);;
3487 let BILINEAR_DROP_MUL = prove
3488 (`bilinear (\x y:real^N. drop x % y)`,
3489 REWRITE_TAC[bilinear; linear] THEN
3490 REWRITE_TAC[DROP_ADD; DROP_CMUL] THEN VECTOR_ARITH_TAC);;
3492 let LINEAR_COMPONENTWISE = prove
3493 (`!f:real^M->real^N.
3495 !i. 1 <= i /\ i <= dimindex(:N) ==> linear(\x. lift(f(x)$i))`,
3496 REPEAT GEN_TAC THEN REWRITE_TAC[linear] THEN
3497 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [CART_EQ] THEN
3498 SIMP_TAC[GSYM LIFT_CMUL; GSYM LIFT_ADD; LIFT_EQ] THEN
3499 REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
3502 (* ------------------------------------------------------------------------- *)
3503 (* Pasting vectors. *)
3504 (* ------------------------------------------------------------------------- *)
3506 let LINEAR_FSTCART = prove
3508 SIMP_TAC[linear; fstcart; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
3509 VECTOR_MUL_COMPONENT; DIMINDEX_FINITE_SUM;
3510 ARITH_RULE `x <= a ==> x <= a + b:num`]);;
3512 let LINEAR_SNDCART = prove
3514 SIMP_TAC[linear; sndcart; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
3515 VECTOR_MUL_COMPONENT; DIMINDEX_FINITE_SUM;
3516 ARITH_RULE `x <= a ==> x <= a + b:num`;
3517 ARITH_RULE `x <= b ==> x + a <= a + b:num`]);;
3519 let FSTCART_VEC = prove
3520 (`!n. fstcart(vec n) = vec n`,
3521 SIMP_TAC[vec; fstcart; LAMBDA_BETA; CART_EQ; DIMINDEX_FINITE_SUM;
3522 ARITH_RULE `m <= n:num ==> m <= n + p`]);;
3524 let FSTCART_ADD = prove
3525 (`!x:real^(M,N)finite_sum y. fstcart(x + y) = fstcart(x) + fstcart(y)`,
3526 REWRITE_TAC[REWRITE_RULE[linear] LINEAR_FSTCART]);;
3528 let FSTCART_CMUL = prove
3529 (`!x:real^(M,N)finite_sum c. fstcart(c % x) = c % fstcart(x)`,
3530 REWRITE_TAC[REWRITE_RULE[linear] LINEAR_FSTCART]);;
3532 let FSTCART_NEG = prove
3533 (`!x:real^(M,N)finite_sum. --(fstcart x) = fstcart(--x)`,
3534 ONCE_REWRITE_TAC[VECTOR_ARITH `--x = --(&1) % x`] THEN
3535 REWRITE_TAC[FSTCART_CMUL]);;
3537 let FSTCART_SUB = prove
3538 (`!x:real^(M,N)finite_sum y. fstcart(x - y) = fstcart(x) - fstcart(y)`,
3539 REWRITE_TAC[VECTOR_SUB; FSTCART_NEG; FSTCART_ADD]);;
3541 let FSTCART_VSUM = prove
3542 (`!k x. FINITE k ==> (fstcart(vsum k x) = vsum k (\i. fstcart(x i)))`,
3543 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
3544 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3545 SIMP_TAC[VSUM_CLAUSES; FINITE_RULES; FSTCART_ADD; FSTCART_VEC]);;
3547 let SNDCART_VEC = prove
3548 (`!n. sndcart(vec n) = vec n`,
3549 SIMP_TAC[vec; sndcart; LAMBDA_BETA; CART_EQ; DIMINDEX_FINITE_SUM;
3550 ARITH_RULE `x <= a ==> x <= a + b:num`;
3551 ARITH_RULE `x <= b ==> x + a <= a + b:num`]);;
3553 let SNDCART_ADD = prove
3554 (`!x:real^(M,N)finite_sum y. sndcart(x + y) = sndcart(x) + sndcart(y)`,
3555 REWRITE_TAC[REWRITE_RULE[linear] LINEAR_SNDCART]);;
3557 let SNDCART_CMUL = prove
3558 (`!x:real^(M,N)finite_sum c. sndcart(c % x) = c % sndcart(x)`,
3559 REWRITE_TAC[REWRITE_RULE[linear] LINEAR_SNDCART]);;
3561 let SNDCART_NEG = prove
3562 (`!x:real^(M,N)finite_sum. --(sndcart x) = sndcart(--x)`,
3563 ONCE_REWRITE_TAC[VECTOR_ARITH `--x = --(&1) % x`] THEN
3564 REWRITE_TAC[SNDCART_CMUL]);;
3566 let SNDCART_SUB = prove
3567 (`!x:real^(M,N)finite_sum y. sndcart(x - y) = sndcart(x) - sndcart(y)`,
3568 REWRITE_TAC[VECTOR_SUB; SNDCART_NEG; SNDCART_ADD]);;
3570 let SNDCART_VSUM = prove
3571 (`!k x. FINITE k ==> (sndcart(vsum k x) = vsum k (\i. sndcart(x i)))`,
3572 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
3573 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3574 SIMP_TAC[VSUM_CLAUSES; FINITE_RULES; SNDCART_ADD; SNDCART_VEC]);;
3576 let PASTECART_VEC = prove
3577 (`!n. pastecart (vec n) (vec n) = vec n`,
3578 REWRITE_TAC[PASTECART_EQ; FSTCART_VEC; SNDCART_VEC;
3579 FSTCART_PASTECART; SNDCART_PASTECART]);;
3581 let PASTECART_ADD = prove
3582 (`!x1 y1 x2:real^M y2:real^N.
3583 pastecart x1 y1 + pastecart x2 y2 = pastecart (x1 + x2) (y1 + y2)`,
3584 REWRITE_TAC[PASTECART_EQ; FSTCART_ADD; SNDCART_ADD;
3585 FSTCART_PASTECART; SNDCART_PASTECART]);;
3587 let PASTECART_CMUL = prove
3588 (`!x1 y1 c. pastecart (c % x1) (c % y1) = c % pastecart x1 y1`,
3589 REWRITE_TAC[PASTECART_EQ; FSTCART_CMUL; SNDCART_CMUL;
3590 FSTCART_PASTECART; SNDCART_PASTECART]);;
3592 let PASTECART_NEG = prove
3593 (`!x:real^M y:real^N. pastecart (--x) (--y) = --(pastecart x y)`,
3594 ONCE_REWRITE_TAC[VECTOR_ARITH `--x = --(&1) % x`] THEN
3595 REWRITE_TAC[PASTECART_CMUL]);;
3597 let PASTECART_SUB = prove
3598 (`!x1 y1 x2:real^M y2:real^N.
3599 pastecart x1 y1 - pastecart x2 y2 = pastecart (x1 - x2) (y1 - y2)`,
3600 REWRITE_TAC[VECTOR_SUB; GSYM PASTECART_NEG; PASTECART_ADD]);;
3602 let PASTECART_VSUM = prove
3603 (`!k x y. FINITE k ==> (pastecart (vsum k x) (vsum k y) =
3604 vsum k (\i. pastecart (x i) (y i)))`,
3605 SIMP_TAC[PASTECART_EQ; FSTCART_VSUM; SNDCART_VSUM;
3606 FSTCART_PASTECART; SNDCART_PASTECART; ETA_AX]);;
3608 let PASTECART_EQ_VEC = prove
3609 (`!x y n. pastecart x y = vec n <=> x = vec n /\ y = vec n`,
3610 REWRITE_TAC[PASTECART_EQ; FSTCART_VEC; SNDCART_VEC;
3611 FSTCART_PASTECART; SNDCART_PASTECART]);;
3613 let NORM_FSTCART = prove
3614 (`!x. norm(fstcart x) <= norm x`,
3616 GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM PASTECART_FST_SND] THEN
3617 SIMP_TAC[SQRT_MONO_LE_EQ; DOT_POS_LE; vector_norm] THEN
3618 SIMP_TAC[pastecart; dot; DIMINDEX_FINITE_SUM; LAMBDA_BETA; DIMINDEX_NONZERO;
3619 SUM_ADD_SPLIT; REAL_LE_ADDR; SUM_POS_LE; FINITE_NUMSEG;
3620 REAL_LE_SQUARE; ARITH_RULE `x <= a ==> x <= a + b:num`;
3621 ARITH_RULE `~(d = 0) ==> 1 <= d + 1`]);;
3623 let DIST_FSTCART = prove
3624 (`!x y. dist(fstcart x,fstcart y) <= dist(x,y)`,
3625 REWRITE_TAC[dist; GSYM FSTCART_SUB; NORM_FSTCART]);;
3627 let NORM_SNDCART = prove
3628 (`!x. norm(sndcart x) <= norm x`,
3630 GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM PASTECART_FST_SND] THEN
3631 SIMP_TAC[SQRT_MONO_LE_EQ; DOT_POS_LE; vector_norm] THEN
3632 SIMP_TAC[pastecart; dot; DIMINDEX_FINITE_SUM; LAMBDA_BETA; DIMINDEX_NONZERO;
3633 SUM_ADD_SPLIT; ARITH_RULE `x <= a ==> x <= a + b:num`;
3634 ARITH_RULE `~(d = 0) ==> 1 <= d + 1`] THEN
3635 ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[NUMSEG_OFFSET_IMAGE] THEN
3636 SIMP_TAC[SUM_IMAGE; FINITE_NUMSEG; EQ_ADD_RCANCEL; o_DEF; ADD_SUB] THEN
3637 SIMP_TAC[ARITH_RULE `1 <= x ==> ~(x + a <= a)`; SUM_POS_LE; FINITE_NUMSEG;
3638 REAL_LE_ADDL; REAL_LE_SQUARE]);;
3640 let DIST_SNDCART = prove
3641 (`!x y. dist(sndcart x,sndcart y) <= dist(x,y)`,
3642 REWRITE_TAC[dist; GSYM SNDCART_SUB; NORM_SNDCART]);;
3644 let DOT_PASTECART = prove
3645 (`!x1 x2 y1 y2. (pastecart x1 x2) dot (pastecart y1 y2) =
3646 x1 dot y1 + x2 dot y2`,
3647 SIMP_TAC[pastecart; dot; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN
3648 SIMP_TAC[SUM_ADD_SPLIT; ARITH_RULE `~(d = 0) ==> 1 <= d + 1`;
3649 DIMINDEX_NONZERO; REAL_LE_LADD] THEN
3650 ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[NUMSEG_OFFSET_IMAGE] THEN
3651 SIMP_TAC[SUM_IMAGE; FINITE_NUMSEG; EQ_ADD_RCANCEL; o_DEF; ADD_SUB] THEN
3652 SIMP_TAC[ARITH_RULE `1 <= x ==> ~(x + a <= a)`; REAL_LE_REFL]);;
3654 let SQNORM_PASTECART = prove
3655 (`!x y. norm(pastecart x y) pow 2 = norm(x) pow 2 + norm(y) pow 2`,
3656 REWRITE_TAC[NORM_POW_2; DOT_PASTECART]);;
3658 let NORM_PASTECART = prove
3659 (`!x y. norm(pastecart x y) = sqrt(norm(x) pow 2 + norm(y) pow 2)`,
3660 REWRITE_TAC[NORM_EQ_SQUARE] THEN
3661 SIMP_TAC[SQRT_POS_LE; SQRT_POW_2; REAL_LE_ADD; REAL_LE_POW_2] THEN
3662 REWRITE_TAC[DOT_PASTECART; NORM_POW_2]);;
3664 let NORM_PASTECART_LE = prove
3665 (`!x y. norm(pastecart x y) <= norm(x) + norm(y)`,
3666 REPEAT GEN_TAC THEN MATCH_MP_TAC TRIANGLE_LEMMA THEN
3667 REWRITE_TAC[NORM_POS_LE; NORM_POW_2; DOT_PASTECART; REAL_LE_REFL]);;
3669 let NORM_LE_PASTECART = prove
3670 (`!x:real^M y:real^N.
3671 norm(x) <= norm(pastecart x y) /\
3672 norm(y) <= norm(pastecart x y)`,
3673 REPEAT GEN_TAC THEN REWRITE_TAC[NORM_PASTECART] THEN CONJ_TAC THEN
3674 MATCH_MP_TAC REAL_LE_RSQRT THEN
3675 REWRITE_TAC[REAL_LE_ADDL; REAL_LE_ADDR; REAL_LE_POW_2]);;
3677 let NORM_PASTECART_0 = prove
3678 (`(!x. norm(pastecart x (vec 0)) = norm x) /\
3679 (!y. norm(pastecart (vec 0) y) = norm y)`,
3680 REWRITE_TAC[NORM_EQ_SQUARE; NORM_POW_2; NORM_POS_LE] THEN
3681 REWRITE_TAC[DOT_PASTECART; DOT_LZERO; REAL_ADD_LID; REAL_ADD_RID]);;
3683 let DIST_PASTECART_CANCEL = prove
3684 (`(!x x' y. dist(pastecart x y,pastecart x' y) = dist(x,x')) /\
3685 (!x y y'. dist(pastecart x y,pastecart x y') = dist(y,y'))`,
3686 REWRITE_TAC[dist; PASTECART_SUB; VECTOR_SUB_REFL; NORM_PASTECART_0]);;
3688 let LINEAR_PASTECART = prove
3689 (`!f:real^M->real^N g:real^M->real^P.
3690 linear f /\ linear g ==> linear (\x. pastecart (f x) (g x))`,
3691 SIMP_TAC[linear; PASTECART_ADD; GSYM PASTECART_CMUL]);;
3693 (* ------------------------------------------------------------------------- *)
3694 (* A bit of linear algebra. *)
3695 (* ------------------------------------------------------------------------- *)
3697 let subspace = new_definition
3700 (!x y. x IN s /\ y IN s ==> (x + y) IN s) /\
3701 (!c x. x IN s ==> (c % x) IN s)`;;
3703 let span = new_definition
3704 `span s = subspace hull s`;;
3706 let dependent = new_definition
3707 `dependent s <=> ?a. a IN s /\ a IN span(s DELETE a)`;;
3709 let independent = new_definition
3710 `independent s <=> ~(dependent s)`;;
3712 (* ------------------------------------------------------------------------- *)
3713 (* Closure properties of subspaces. *)
3714 (* ------------------------------------------------------------------------- *)
3716 let SUBSPACE_UNIV = prove
3717 (`subspace(UNIV:real^N->bool)`,
3718 REWRITE_TAC[subspace; IN_UNIV]);;
3720 let SUBSPACE_IMP_NONEMPTY = prove
3721 (`!s. subspace s ==> ~(s = {})`,
3722 REWRITE_TAC[subspace] THEN SET_TAC[]);;
3724 let SUBSPACE_0 = prove
3725 (`subspace s ==> vec(0) IN s`,
3726 SIMP_TAC[subspace]);;
3728 let SUBSPACE_ADD = prove
3729 (`!x y s. subspace s /\ x IN s /\ y IN s ==> (x + y) IN s`,
3730 SIMP_TAC[subspace]);;
3732 let SUBSPACE_MUL = prove
3733 (`!x c s. subspace s /\ x IN s ==> (c % x) IN s`,
3734 SIMP_TAC[subspace]);;
3736 let SUBSPACE_NEG = prove
3737 (`!x s. subspace s /\ x IN s ==> (--x) IN s`,
3738 SIMP_TAC[VECTOR_ARITH `--x = --(&1) % x`; SUBSPACE_MUL]);;
3740 let SUBSPACE_SUB = prove
3741 (`!x y s. subspace s /\ x IN s /\ y IN s ==> (x - y) IN s`,
3742 SIMP_TAC[VECTOR_SUB; SUBSPACE_ADD; SUBSPACE_NEG]);;
3744 let SUBSPACE_VSUM = prove
3745 (`!s f t. subspace s /\ FINITE t /\ (!x. x IN t ==> f(x) IN s)
3746 ==> (vsum t f) IN s`,
3747 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
3748 GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
3749 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3750 ASM_SIMP_TAC[VSUM_CLAUSES; SUBSPACE_0; IN_INSERT; SUBSPACE_ADD]);;
3752 let SUBSPACE_LINEAR_IMAGE = prove
3753 (`!f s. linear f /\ subspace s ==> subspace(IMAGE f s)`,
3754 REWRITE_TAC[subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
3755 REWRITE_TAC[FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN
3756 MESON_TAC[linear; LINEAR_0]);;
3758 let SUBSPACE_LINEAR_PREIMAGE = prove
3759 (`!f s. linear f /\ subspace s ==> subspace {x | f(x) IN s}`,
3760 REWRITE_TAC[subspace; IN_ELIM_THM] THEN
3761 MESON_TAC[linear; LINEAR_0]);;
3763 let SUBSPACE_TRIVIAL = prove
3764 (`subspace {vec 0}`,
3765 SIMP_TAC[subspace; IN_SING] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
3767 let SUBSPACE_INTER = prove
3768 (`!s t. subspace s /\ subspace t ==> subspace (s INTER t)`,
3769 REWRITE_TAC[subspace; IN_INTER] THEN MESON_TAC[]);;
3771 let SUBSPACE_INTERS = prove
3772 (`!f. (!s. s IN f ==> subspace s) ==> subspace(INTERS f)`,
3773 SIMP_TAC[subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM; IN_INTERS]);;
3775 let LINEAR_INJECTIVE_0_SUBSPACE = prove
3776 (`!f:real^M->real^N s.
3777 linear f /\ subspace s
3778 ==> ((!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) <=>
3779 (!x. x IN s /\ f x = vec 0 ==> x = vec 0))`,
3780 REPEAT STRIP_TAC THEN
3781 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM VECTOR_SUB_EQ] THEN
3782 ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN
3783 ASM_MESON_TAC[VECTOR_SUB_RZERO; SUBSPACE_SUB; SUBSPACE_0]);;
3785 let SUBSPACE_UNION_CHAIN = prove
3786 (`!s t:real^N->bool.
3787 subspace s /\ subspace t /\ subspace(s UNION t)
3788 ==> s SUBSET t \/ t SUBSET s`,
3789 REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE
3790 `s SUBSET t \/ t SUBSET s <=>
3791 ~(?x y. x IN s /\ ~(x IN t) /\ y IN t /\ ~(y IN s))`] THEN
3792 STRIP_TAC THEN SUBGOAL_THEN `(x + y:real^N) IN s UNION t` MP_TAC THENL
3793 [MATCH_MP_TAC SUBSPACE_ADD THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
3794 REWRITE_TAC[IN_UNION; DE_MORGAN_THM] THEN
3795 ASM_MESON_TAC[SUBSPACE_SUB; VECTOR_ARITH
3796 `(x + y) - x:real^N = y /\ (x + y) - y = x`]]);;
3798 let SUBSPACE_PCROSS = prove
3799 (`!s:real^M->bool t:real^N->bool.
3800 subspace s /\ subspace t ==> subspace(s PCROSS t)`,
3801 REWRITE_TAC[subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
3802 REWRITE_TAC[FORALL_IN_PCROSS; GSYM PASTECART_CMUL; PASTECART_ADD] THEN
3803 REWRITE_TAC[GSYM PASTECART_VEC; PASTECART_IN_PCROSS] THEN SIMP_TAC[]);;
3805 let SUBSPACE_PCROSS_EQ = prove
3806 (`!s:real^M->bool t:real^N->bool.
3807 subspace(s PCROSS t) <=> subspace s /\ subspace t`,
3809 ASM_CASES_TAC `s:real^M->bool = {}` THENL
3810 [ASM_MESON_TAC[PCROSS_EMPTY; SUBSPACE_IMP_NONEMPTY]; ALL_TAC] THEN
3811 ASM_CASES_TAC `t:real^N->bool = {}` THENL
3812 [ASM_MESON_TAC[PCROSS_EMPTY; SUBSPACE_IMP_NONEMPTY]; ALL_TAC] THEN
3813 EQ_TAC THEN REWRITE_TAC[SUBSPACE_PCROSS] THEN REPEAT STRIP_TAC THENL
3814 [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`;
3815 `(s:real^M->bool) PCROSS (t:real^N->bool)`] SUBSPACE_LINEAR_IMAGE) THEN
3816 ASM_REWRITE_TAC[LINEAR_FSTCART];
3817 MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`;
3818 `(s:real^M->bool) PCROSS (t:real^N->bool)`] SUBSPACE_LINEAR_IMAGE) THEN
3819 ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN
3820 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
3821 REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS;
3822 FSTCART_PASTECART; SNDCART_PASTECART] THEN
3825 (* ------------------------------------------------------------------------- *)
3827 (* ------------------------------------------------------------------------- *)
3829 let SPAN_SPAN = prove
3830 (`!s. span(span s) = span s`,
3831 REWRITE_TAC[span; HULL_HULL]);;
3833 let SPAN_MONO = prove
3834 (`!s t. s SUBSET t ==> span s SUBSET span t`,
3835 REWRITE_TAC[span; HULL_MONO]);;
3837 let SUBSPACE_SPAN = prove
3838 (`!s. subspace(span s)`,
3839 GEN_TAC THEN REWRITE_TAC[span] THEN MATCH_MP_TAC P_HULL THEN
3840 SIMP_TAC[subspace; IN_INTERS]);;
3842 let SPAN_CLAUSES = prove
3843 (`(!a s. a IN s ==> a IN span s) /\
3844 (vec(0) IN span s) /\
3845 (!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s) /\
3846 (!x c s. x IN span s ==> (c % x) IN span s)`,
3847 MESON_TAC[span; HULL_SUBSET; SUBSET; SUBSPACE_SPAN; subspace]);;
3849 let SPAN_INDUCT = prove
3850 (`!s h. (!x. x IN s ==> x IN h) /\ subspace h ==> !x. x IN span(s) ==> h(x)`,
3851 REWRITE_TAC[span] THEN MESON_TAC[SUBSET; HULL_MINIMAL; IN]);;
3853 let SPAN_EMPTY = prove
3854 (`span {} = {vec 0}`,
3855 REWRITE_TAC[span] THEN MATCH_MP_TAC HULL_UNIQUE THEN
3856 SIMP_TAC[subspace; SUBSET; IN_SING; NOT_IN_EMPTY] THEN
3857 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
3859 let INDEPENDENT_EMPTY = prove
3861 REWRITE_TAC[independent; dependent; NOT_IN_EMPTY]);;
3863 let INDEPENDENT_NONZERO = prove
3864 (`!s. independent s ==> ~(vec 0 IN s)`,
3865 REWRITE_TAC[independent; dependent] THEN MESON_TAC[SPAN_CLAUSES]);;
3867 let INDEPENDENT_MONO = prove
3868 (`!s t. independent t /\ s SUBSET t ==> independent s`,
3869 REWRITE_TAC[independent; dependent] THEN
3870 ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_DELETE]);;
3872 let DEPENDENT_MONO = prove
3873 (`!s t:real^N->bool. dependent s /\ s SUBSET t ==> dependent t`,
3874 ONCE_REWRITE_TAC[TAUT `p /\ q ==> r <=> ~r /\ q ==> ~p`] THEN
3875 REWRITE_TAC[GSYM independent; INDEPENDENT_MONO]);;
3877 let SPAN_SUBSPACE = prove
3878 (`!b s. b SUBSET s /\ s SUBSET (span b) /\ subspace s ==> (span b = s)`,
3879 MESON_TAC[SUBSET_ANTISYM; span; HULL_MINIMAL]);;
3881 let SPAN_INDUCT_ALT = prove
3883 (!c x y. x IN s /\ h(y) ==> h(c % x + y))
3884 ==> !x:real^N. x IN span(s) ==> h(x)`,
3885 REPEAT GEN_TAC THEN DISCH_TAC THEN
3886 FIRST_ASSUM(MP_TAC o prove_inductive_relations_exist o concl) THEN
3887 DISCH_THEN(X_CHOOSE_THEN `g:real^N->bool` STRIP_ASSUME_TAC) THEN
3888 SUBGOAL_THEN `!x:real^N. x IN span(s) ==> g(x)`
3889 (fun th -> ASM_MESON_TAC[th]) THEN
3890 MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[subspace; IN_ELIM_THM] THEN
3891 REWRITE_TAC[IN; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
3892 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
3893 REPEAT CONJ_TAC THEN TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN
3894 REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN
3895 ASM_MESON_TAC[IN; VECTOR_ADD_LID; VECTOR_ADD_ASSOC; VECTOR_ADD_SYM;
3896 VECTOR_MUL_LID; VECTOR_MUL_RZERO]);;
3898 (* ------------------------------------------------------------------------- *)
3899 (* Individual closure properties. *)
3900 (* ------------------------------------------------------------------------- *)
3902 let SPAN_SUPERSET = prove
3903 (`!x. x IN s ==> x IN span s`,
3904 MESON_TAC[SPAN_CLAUSES]);;
3906 let SPAN_INC = prove
3907 (`!s. s SUBSET span s`,
3908 REWRITE_TAC[SUBSET; SPAN_SUPERSET]);;
3910 let SPAN_UNION_SUBSET = prove
3911 (`!s t. span s UNION span t SUBSET span(s UNION t)`,
3912 REWRITE_TAC[span; HULL_UNION_SUBSET]);;
3914 let SPAN_UNIV = prove
3915 (`span(:real^N) = (:real^N)`,
3916 SIMP_TAC[SPAN_INC; SET_RULE `UNIV SUBSET s ==> s = UNIV`]);;
3919 (`vec(0) IN span s`,
3920 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_0]);;
3922 let SPAN_ADD = prove
3923 (`!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s`,
3924 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_ADD]);;
3926 let SPAN_MUL = prove
3927 (`!x c s. x IN span s ==> (c % x) IN span s`,
3928 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_MUL]);;
3930 let SPAN_MUL_EQ = prove
3931 (`!x:real^N c s. ~(c = &0) ==> ((c % x) IN span s <=> x IN span s)`,
3932 REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN ASM_SIMP_TAC[SPAN_MUL] THEN
3933 SUBGOAL_THEN `(inv(c) % c % x:real^N) IN span s` MP_TAC THENL
3934 [ASM_SIMP_TAC[SPAN_MUL];
3935 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID]]);;
3937 let SPAN_NEG = prove
3938 (`!x s. x IN span s ==> (--x) IN span s`,
3939 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_NEG]);;
3941 let SPAN_NEG_EQ = prove
3942 (`!x s. --x IN span s <=> x IN span s`,
3943 MESON_TAC[SPAN_NEG; VECTOR_NEG_NEG]);;
3945 let SPAN_SUB = prove
3946 (`!x y s. x IN span s /\ y IN span s ==> (x - y) IN span s`,
3947 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_SUB]);;
3949 let SPAN_VSUM = prove
3950 (`!s f t. FINITE t /\ (!x. x IN t ==> f(x) IN span(s))
3951 ==> (vsum t f) IN span(s)`,
3952 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_VSUM]);;
3954 let SPAN_ADD_EQ = prove
3955 (`!s x y. x IN span s ==> ((x + y) IN span s <=> y IN span s)`,
3956 MESON_TAC[SPAN_ADD; SPAN_SUB; VECTOR_ARITH `(x + y) - x:real^N = y`]);;
3958 let SPAN_EQ_SELF = prove
3959 (`!s. span s = s <=> subspace s`,
3960 GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSPACE_SPAN]; ALL_TAC] THEN
3961 DISCH_TAC THEN MATCH_MP_TAC SPAN_SUBSPACE THEN
3962 ASM_REWRITE_TAC[SUBSET_REFL; SPAN_INC]);;
3964 let SPAN_OF_SUBSPACE = prove
3965 (`!s:real^N->bool. subspace s ==> span s = s`,
3966 REWRITE_TAC[SPAN_EQ_SELF]);;
3968 let SPAN_SUBSET_SUBSPACE = prove
3969 (`!s t:real^N->bool. s SUBSET t /\ subspace t ==> span s SUBSET t`,
3970 MESON_TAC[SPAN_MONO; SPAN_EQ_SELF]);;
3972 let SUBSPACE_TRANSLATION_SELF = prove
3973 (`!s a. subspace s /\ a IN s ==> IMAGE (\x. a + x) s = s`,
3974 REPEAT STRIP_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
3975 FIRST_ASSUM(SUBST1_TAC o SYM o GEN_REWRITE_RULE I [GSYM SPAN_EQ_SELF]) THEN
3976 ASM_SIMP_TAC[SPAN_ADD_EQ; SPAN_CLAUSES] THEN
3977 REWRITE_TAC[VECTOR_ARITH `a + x:real^N = y <=> x = y - a`; EXISTS_REFL]);;
3979 let SUBSPACE_TRANSLATION_SELF_EQ = prove
3980 (`!s a:real^N. subspace s ==> (IMAGE (\x. a + x) s = s <=> a IN s)`,
3981 REPEAT STRIP_TAC THEN EQ_TAC THEN
3982 ASM_SIMP_TAC[SUBSPACE_TRANSLATION_SELF] THEN
3983 DISCH_THEN(MP_TAC o AP_TERM `\s. (a:real^N) IN s`) THEN
3984 REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
3985 REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `vec 0:real^N` THEN
3986 ASM_MESON_TAC[subspace; VECTOR_ADD_RID]);;
3988 let SUBSPACE_SUMS = prove
3989 (`!s t. subspace s /\ subspace t
3990 ==> subspace {x + y | x IN s /\ y IN t}`,
3991 REWRITE_TAC[subspace; FORALL_IN_GSPEC; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
3992 REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THENL
3993 [ASM_MESON_TAC[VECTOR_ADD_LID];
3994 ONCE_REWRITE_TAC[VECTOR_ARITH
3995 `(x + y) + (x' + y'):real^N = (x + x') + (y + y')`] THEN
3997 REWRITE_TAC[VECTOR_ADD_LDISTRIB] THEN ASM_MESON_TAC[]]);;
3999 let SPAN_UNION = prove
4000 (`!s t. span(s UNION t) = {x + y:real^N | x IN span s /\ y IN span t}`,
4001 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
4002 [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
4003 SIMP_TAC[SUBSPACE_SUMS; SUBSPACE_SPAN] THEN
4004 REWRITE_TAC[SUBSET; IN_UNION; IN_ELIM_THM] THEN
4005 X_GEN_TAC `x:real^N` THEN STRIP_TAC THENL
4006 [MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN
4007 ASM_SIMP_TAC[SPAN_SUPERSET; SPAN_0; VECTOR_ADD_RID];
4008 MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `x:real^N`] THEN
4009 ASM_SIMP_TAC[SPAN_SUPERSET; SPAN_0; VECTOR_ADD_LID]];
4010 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
4011 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_ADD THEN
4012 ASM_MESON_TAC[SPAN_MONO; SUBSET_UNION; SUBSET]]);;
4014 (* ------------------------------------------------------------------------- *)
4015 (* Mapping under linear image. *)
4016 (* ------------------------------------------------------------------------- *)
4018 let SPAN_LINEAR_IMAGE = prove
4019 (`!f:real^M->real^N s. linear f ==> (span(IMAGE f s) = IMAGE f (span s))`,
4020 REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
4021 X_GEN_TAC `x:real^N` THEN EQ_TAC THENL
4022 [SPEC_TAC(`x:real^N`,`x:real^N`) THEN MATCH_MP_TAC SPAN_INDUCT THEN
4023 REWRITE_TAC[SET_RULE `(\x. x IN s) = s`] THEN
4024 ASM_SIMP_TAC[SUBSPACE_SPAN; SUBSPACE_LINEAR_IMAGE] THEN
4025 REWRITE_TAC[FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN
4026 MESON_TAC[SPAN_SUPERSET; SUBSET];
4027 SPEC_TAC(`x:real^N`,`x:real^N`) THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN
4028 MATCH_MP_TAC SPAN_INDUCT THEN
4029 REWRITE_TAC[SET_RULE `(\x. f x IN span(s)) = {x | f(x) IN span s}`] THEN
4030 ASM_SIMP_TAC[SUBSPACE_LINEAR_PREIMAGE; SUBSPACE_SPAN] THEN
4031 REWRITE_TAC[IN_ELIM_THM] THEN
4032 MESON_TAC[SPAN_SUPERSET; SUBSET; IN_IMAGE]]);;
4034 let DEPENDENT_LINEAR_IMAGE_EQ = prove
4035 (`!f:real^M->real^N s.
4036 linear f /\ (!x y. f x = f y ==> x = y)
4037 ==> (dependent(IMAGE f s) <=> dependent s)`,
4038 REPEAT STRIP_TAC THEN REWRITE_TAC[dependent; EXISTS_IN_IMAGE] THEN
4039 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `a:real^M` THEN
4040 ASM_CASES_TAC `(a:real^M) IN s` THEN ASM_REWRITE_TAC[] THEN
4041 MATCH_MP_TAC EQ_TRANS THEN
4042 EXISTS_TAC `(f:real^M->real^N) a IN span(IMAGE f (s DELETE a))` THEN
4044 [AP_TERM_TAC THEN AP_TERM_TAC THEN ASM SET_TAC[];
4045 ASM_SIMP_TAC[SPAN_LINEAR_IMAGE] THEN ASM SET_TAC[]]);;
4047 let DEPENDENT_LINEAR_IMAGE = prove
4048 (`!f:real^M->real^N s.
4049 linear f /\ (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\
4051 ==> dependent(IMAGE f s)`,
4053 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4054 REWRITE_TAC[dependent; EXISTS_IN_IMAGE] THEN
4055 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^M` THEN
4056 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4057 SUBGOAL_THEN `IMAGE (f:real^M->real^N) s DELETE f a = IMAGE f (s DELETE a)`
4058 (fun th -> ASM_SIMP_TAC[FUN_IN_IMAGE; SPAN_LINEAR_IMAGE; th]) THEN
4061 let INDEPENDENT_LINEAR_IMAGE_EQ = prove
4062 (`!f:real^M->real^N s.
4063 linear f /\ (!x y. f x = f y ==> x = y)
4064 ==> (independent(IMAGE f s) <=> independent s)`,
4065 REWRITE_TAC[independent; TAUT `(~p <=> ~q) <=> (p <=> q)`] THEN
4066 REWRITE_TAC[DEPENDENT_LINEAR_IMAGE_EQ]);;
4068 (* ------------------------------------------------------------------------- *)
4069 (* The key breakdown property. *)
4070 (* ------------------------------------------------------------------------- *)
4072 let SPAN_BREAKDOWN = prove
4074 b IN s /\ a IN span s ==> ?k. (a - k % b) IN span(s DELETE b)`,
4075 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
4076 REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN
4077 REWRITE_TAC[subspace; IN_ELIM_THM] THEN CONJ_TAC THENL
4078 [GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC `a:real^N = b`; ALL_TAC] THEN
4079 ASM_MESON_TAC[SPAN_CLAUSES; IN_DELETE; VECTOR_ARITH
4080 `(a - &1 % a = vec 0) /\ (a - &0 % b = a) /\
4081 ((x + y) - (k1 + k2) % b = (x - k1 % b) + (y - k2 % b)) /\
4082 (c % x - (c * k) % y = c % (x - k % y))`]);;
4084 let SPAN_BREAKDOWN_EQ = prove
4085 (`!a:real^N s. (x IN span(a INSERT s) <=> (?k. (x - k % a) IN span s))`,
4086 REPEAT STRIP_TAC THEN EQ_TAC THENL
4087 [DISCH_THEN(MP_TAC o CONJ(SET_RULE `(a:real^N) IN (a INSERT s)`)) THEN
4088 DISCH_THEN(MP_TAC o MATCH_MP SPAN_BREAKDOWN) THEN
4089 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real` THEN
4090 SPEC_TAC(`x - k % a:real^N`,`y:real^N`) THEN
4091 REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SPAN_MONO THEN SET_TAC[];
4092 DISCH_THEN(X_CHOOSE_TAC `k:real`) THEN
4093 SUBST1_TAC(VECTOR_ARITH `x = (x - k % a) + k % a:real^N`) THEN
4094 MATCH_MP_TAC SPAN_ADD THEN
4095 ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_INSERT; SPAN_CLAUSES]]);;
4097 let SPAN_INSERT_0 = prove
4098 (`!s. span(vec 0 INSERT s) = span s`,
4099 SIMP_TAC[EXTENSION; SPAN_BREAKDOWN_EQ; VECTOR_MUL_RZERO; VECTOR_SUB_RZERO]);;
4101 let SPAN_SING = prove
4102 (`!a. span {a} = {u % a | u IN (:real)}`,
4103 REWRITE_TAC[EXTENSION; IN_ELIM_THM; SPAN_BREAKDOWN_EQ; SPAN_EMPTY] THEN
4104 REWRITE_TAC[IN_UNIV; IN_SING; VECTOR_SUB_EQ]);;
4107 (`!a b. span {a,b} = {u % a + v % b | u IN (:real) /\ v IN (:real)}`,
4108 REWRITE_TAC[EXTENSION; IN_ELIM_THM; SPAN_BREAKDOWN_EQ; SPAN_EMPTY] THEN
4109 REWRITE_TAC[IN_UNIV; IN_SING; VECTOR_SUB_EQ] THEN
4110 REWRITE_TAC[VECTOR_ARITH `x - y:real^N = z <=> x = y + z`]);;
4113 (`!a b c. span {a,b,c} =
4114 {u % a + v % b + w % c | u IN (:real) /\ v IN (:real) /\ w IN (:real)}`,
4115 REWRITE_TAC[EXTENSION; IN_ELIM_THM; SPAN_BREAKDOWN_EQ; SPAN_EMPTY] THEN
4116 REWRITE_TAC[IN_UNIV; IN_SING; VECTOR_SUB_EQ] THEN
4117 REWRITE_TAC[VECTOR_ARITH `x - y:real^N = z <=> x = y + z`]);;
4119 (* ------------------------------------------------------------------------- *)
4120 (* Hence some "reversal" results. *)
4121 (* ------------------------------------------------------------------------- *)
4123 let IN_SPAN_INSERT = prove
4125 a IN span(b INSERT s) /\ ~(a IN span s) ==> b IN span(a INSERT s)`,
4126 REPEAT STRIP_TAC THEN
4127 MP_TAC(ISPECL [`b:real^N`; `(b:real^N) INSERT s`; `a:real^N`]
4128 SPAN_BREAKDOWN) THEN ASM_REWRITE_TAC[IN_INSERT] THEN
4129 DISCH_THEN(X_CHOOSE_THEN `k:real` MP_TAC) THEN ASM_CASES_TAC `k = &0` THEN
4130 ASM_REWRITE_TAC[VECTOR_ARITH `a - &0 % b = a`; DELETE_INSERT] THENL
4131 [ASM_MESON_TAC[SPAN_MONO; SUBSET; DELETE_SUBSET]; ALL_TAC] THEN
4132 DISCH_THEN(MP_TAC o SPEC `inv(k)` o MATCH_MP SPAN_MUL) THEN
4133 ASM_SIMP_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_ASSOC; REAL_MUL_LINV] THEN
4134 DISCH_TAC THEN SUBST1_TAC(VECTOR_ARITH
4135 `b:real^N = inv(k) % a - (inv(k) % a - &1 % b)`) THEN
4136 MATCH_MP_TAC SPAN_SUB THEN
4137 ASM_MESON_TAC[SPAN_CLAUSES; IN_INSERT; SUBSET; IN_DELETE; SPAN_MONO]);;
4139 let IN_SPAN_DELETE = prove
4141 a IN span s /\ ~(a IN span (s DELETE b))
4142 ==> b IN span (a INSERT (s DELETE b))`,
4143 ASM_MESON_TAC[IN_SPAN_INSERT; SPAN_MONO; SUBSET; IN_INSERT; IN_DELETE]);;
4145 let EQ_SPAN_INSERT_EQ = prove
4146 (`!s x y:real^N. (x - y) IN span s ==> span(x INSERT s) = span(y INSERT s)`,
4147 REPEAT STRIP_TAC THEN REWRITE_TAC[SPAN_BREAKDOWN_EQ; EXTENSION] THEN
4148 ASM_MESON_TAC[SPAN_ADD; SPAN_SUB; SPAN_MUL;
4149 VECTOR_ARITH `(z - k % y) - k % (x - y) = z - k % x`;
4150 VECTOR_ARITH `(z - k % x) + k % (x - y) = z - k % y`]);;
4152 (* ------------------------------------------------------------------------- *)
4153 (* Transitivity property. *)
4154 (* ------------------------------------------------------------------------- *)
4156 let SPAN_TRANS = prove
4157 (`!x y:real^N s. x IN span(s) /\ y IN span(x INSERT s) ==> y IN span(s)`,
4158 REPEAT STRIP_TAC THEN
4159 MP_TAC(SPECL [`x:real^N`; `(x:real^N) INSERT s`; `y:real^N`]
4160 SPAN_BREAKDOWN) THEN
4161 ASM_REWRITE_TAC[IN_INSERT] THEN
4162 DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
4163 SUBST1_TAC(VECTOR_ARITH `y:real^N = (y - k % x) + k % x`) THEN
4164 MATCH_MP_TAC SPAN_ADD THEN ASM_SIMP_TAC[SPAN_MUL] THEN
4165 ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_INSERT; IN_DELETE]);;
4167 (* ------------------------------------------------------------------------- *)
4168 (* An explicit expansion is sometimes needed. *)
4169 (* ------------------------------------------------------------------------- *)
4171 let SPAN_EXPLICIT = prove
4172 (`!(p:real^N -> bool).
4174 {y | ?s u. FINITE s /\ s SUBSET p /\
4175 vsum s (\v. u v % v) = y}`,
4176 GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
4178 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
4179 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
4180 MATCH_MP_TAC SPAN_VSUM THEN ASM_REWRITE_TAC[] THEN
4181 ASM_MESON_TAC[SPAN_SUPERSET; SPAN_MUL]] THEN
4182 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
4183 MATCH_MP_TAC SPAN_INDUCT_ALT THEN CONJ_TAC THENL
4184 [EXISTS_TAC `{}:real^N->bool` THEN
4185 REWRITE_TAC[FINITE_RULES; VSUM_CLAUSES; EMPTY_SUBSET; NOT_IN_EMPTY];
4187 MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`; `y:real^N`] THEN
4188 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4189 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
4190 MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `u:real^N->real`] THEN
4191 STRIP_TAC THEN EXISTS_TAC `(x:real^N) INSERT s` THEN
4192 EXISTS_TAC `\y. if y = x then (if x IN s then (u:real^N->real) y + c else c)
4194 ASM_SIMP_TAC[FINITE_INSERT; IN_INSERT; VSUM_CLAUSES] THEN
4195 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
4196 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
4197 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
4198 [FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE
4199 `x IN s ==> s = x INSERT (s DELETE x)`)) THEN
4200 ASM_SIMP_TAC[VSUM_CLAUSES; FINITE_INSERT; FINITE_DELETE; IN_DELETE] THEN
4201 MATCH_MP_TAC(VECTOR_ARITH
4202 `y = z ==> (c + d) % x + y = d % x + c % x + z`);
4204 MATCH_MP_TAC VSUM_EQ THEN ASM_MESON_TAC[IN_DELETE]);;
4206 let DEPENDENT_EXPLICIT = prove
4207 (`!p. dependent (p:real^N -> bool) <=>
4208 ?s u. FINITE s /\ s SUBSET p /\
4209 (?v. v IN s /\ ~(u v = &0)) /\
4210 vsum s (\v. u v % v) = vec 0`,
4211 GEN_TAC THEN REWRITE_TAC[dependent; SPAN_EXPLICIT; IN_ELIM_THM] THEN
4212 REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
4213 EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
4214 [MAP_EVERY X_GEN_TAC [`a:real^N`; `s:real^N->bool`; `u:real^N->real`] THEN
4215 STRIP_TAC THEN MAP_EVERY EXISTS_TAC
4216 [`(a:real^N) INSERT s`;
4217 `\y. if y = a then -- &1 else (u:real^N->real) y`;
4219 ASM_REWRITE_TAC[IN_INSERT; INSERT_SUBSET; FINITE_INSERT] THEN
4220 CONJ_TAC THENL [ASM SET_TAC[]; CONV_TAC REAL_RAT_REDUCE_CONV] THEN
4221 ASM_SIMP_TAC[VSUM_CLAUSES] THEN
4222 COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4223 REWRITE_TAC[VECTOR_ARITH `-- &1 % a + s = vec 0 <=> a = s`] THEN
4224 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
4225 MATCH_MP_TAC VSUM_EQ THEN ASM SET_TAC[];
4226 MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `u:real^N->real`; `a:real^N`] THEN
4227 STRIP_TAC THEN MAP_EVERY EXISTS_TAC
4228 [`a:real^N`; `s DELETE (a:real^N)`;
4229 `\i. --((u:real^N->real) i) / (u a)`] THEN
4230 ASM_SIMP_TAC[VSUM_DELETE; FINITE_DELETE] THEN
4231 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
4232 REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
4233 ASM_REWRITE_TAC[VECTOR_MUL_LNEG; GSYM VECTOR_MUL_ASSOC; VSUM_LMUL;
4234 VSUM_NEG; VECTOR_MUL_RNEG; VECTOR_MUL_RZERO] THEN
4235 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV] THEN VECTOR_ARITH_TAC]);;
4237 let DEPENDENT_FINITE = prove
4240 ==> (dependent s <=> ?u. (?v. v IN s /\ ~(u v = &0)) /\
4241 vsum s (\v. u(v) % v) = vec 0)`,
4242 REPEAT STRIP_TAC THEN REWRITE_TAC[DEPENDENT_EXPLICIT] THEN EQ_TAC THEN
4243 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
4244 [MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN
4245 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
4246 EXISTS_TAC `\v:real^N. if v IN t then u(v) else &0` THEN
4247 REWRITE_TAC[] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4248 ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN
4249 ASM_SIMP_TAC[VECTOR_MUL_LZERO; GSYM VSUM_RESTRICT_SET] THEN
4250 ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`];
4251 GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
4252 MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `u:real^N->real`] THEN
4253 ASM_REWRITE_TAC[SUBSET_REFL]]);;
4255 let SPAN_FINITE = prove
4257 FINITE s ==> span s = {y | ?u. vsum s (\v. u v % v) = y}`,
4258 REPEAT STRIP_TAC THEN REWRITE_TAC[SPAN_EXPLICIT; EXTENSION; IN_ELIM_THM] THEN
4259 X_GEN_TAC `y:real^N` THEN EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
4260 [MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN
4261 STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
4262 EXISTS_TAC `\x:real^N. if x IN t then u(x) else &0` THEN
4263 REWRITE_TAC[COND_RAND; COND_RATOR; VECTOR_MUL_LZERO] THEN
4264 ASM_SIMP_TAC[GSYM VSUM_RESTRICT_SET] THEN
4265 ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`];
4266 X_GEN_TAC `u:real^N->real` THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
4267 MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `u:real^N->real`] THEN
4268 ASM_REWRITE_TAC[SUBSET_REFL]]);;
4270 (* ------------------------------------------------------------------------- *)
4271 (* Standard bases are a spanning set, and obviously finite. *)
4272 (* ------------------------------------------------------------------------- *)
4274 let SPAN_STDBASIS = prove
4275 (`span {basis i :real^N | 1 <= i /\ i <= dimindex(:N)} = UNIV`,
4276 REWRITE_TAC[EXTENSION; IN_UNIV] THEN X_GEN_TAC `x:real^N` THEN
4277 GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN
4278 MATCH_MP_TAC SPAN_VSUM THEN SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
4279 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
4280 MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN
4283 let HAS_SIZE_STDBASIS = prove
4284 (`{basis i :real^N | 1 <= i /\ i <= dimindex(:N)} HAS_SIZE
4286 ONCE_REWRITE_TAC[SET_RULE `{f x | P x} = IMAGE f {x | P x}`] THEN
4287 MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN
4288 REWRITE_TAC[GSYM numseg; HAS_SIZE_NUMSEG_1; IN_NUMSEG] THEN
4289 MESON_TAC[BASIS_INJ]);;
4291 let FINITE_STDBASIS = prove
4292 (`FINITE {basis i :real^N | 1 <= i /\ i <= dimindex(:N)}`,
4293 MESON_TAC[HAS_SIZE_STDBASIS; HAS_SIZE]);;
4295 let CARD_STDBASIS = prove
4296 (`CARD {basis i :real^N | 1 <= i /\ i <= dimindex(:N)} =
4298 MESON_TAC[HAS_SIZE_STDBASIS; HAS_SIZE]);;
4300 let IN_SPAN_IMAGE_BASIS = prove
4302 x IN span(IMAGE basis s) <=>
4303 !i. 1 <= i /\ i <= dimindex(:N) /\ ~(i IN s) ==> x$i = &0`,
4304 REPEAT GEN_TAC THEN EQ_TAC THENL
4305 [SPEC_TAC(`x:real^N`,`x:real^N`) THEN MATCH_MP_TAC SPAN_INDUCT THEN
4306 SIMP_TAC[subspace; IN_ELIM_THM; VEC_COMPONENT; VECTOR_ADD_COMPONENT;
4307 VECTOR_MUL_COMPONENT; REAL_MUL_RZERO; REAL_ADD_RID] THEN
4308 SIMP_TAC[FORALL_IN_IMAGE; BASIS_COMPONENT] THEN MESON_TAC[];
4309 DISCH_TAC THEN REWRITE_TAC[SPAN_EXPLICIT; IN_ELIM_THM] THEN
4310 EXISTS_TAC `(IMAGE basis ((1..dimindex(:N)) INTER s)):real^N->bool` THEN
4311 SIMP_TAC[FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN
4312 REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
4313 CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
4314 EXISTS_TAC `\v:real^N. x dot v` THEN
4315 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN
4317 [SIMP_TAC[FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN
4318 REWRITE_TAC[IN_INTER; IN_NUMSEG] THEN MESON_TAC[BASIS_INJ];
4319 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[]] THEN
4320 REWRITE_TAC[o_DEF] THEN
4321 SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_MUL_COMPONENT;
4322 BASIS_COMPONENT] THEN
4323 ONCE_REWRITE_TAC[COND_RAND] THEN
4324 ONCE_REWRITE_TAC[MESON[]
4325 `(if x = y then p else q) = (if y = x then p else q)`] THEN
4326 SIMP_TAC[SUM_DELTA; REAL_MUL_RZERO; IN_INTER; IN_NUMSEG; DOT_BASIS] THEN
4327 ASM_MESON_TAC[REAL_MUL_RID]]);;
4329 let INDEPENDENT_STDBASIS = prove
4330 (`independent {basis i :real^N | 1 <= i /\ i <= dimindex(:N)}`,
4331 REWRITE_TAC[independent; dependent] THEN
4332 ONCE_REWRITE_TAC[SET_RULE `{f x | P x} = IMAGE f {x | P x}`] THEN
4333 REWRITE_TAC[EXISTS_IN_IMAGE] THEN REWRITE_TAC[IN_ELIM_THM] THEN
4334 DISCH_THEN(X_CHOOSE_THEN `k:num` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4336 `IMAGE basis {i | 1 <= i /\ i <= dimindex(:N)} DELETE
4338 IMAGE basis ({i | 1 <= i /\ i <= dimindex(:N)} DELETE k)`
4340 [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DELETE; IN_ELIM_THM] THEN
4341 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4342 ASM_MESON_TAC[BASIS_INJ];
4344 REWRITE_TAC[IN_SPAN_IMAGE_BASIS] THEN DISCH_THEN(MP_TAC o SPEC `k:num`) THEN
4345 ASM_SIMP_TAC[IN_DELETE; BASIS_COMPONENT; REAL_OF_NUM_EQ; ARITH]);;
4347 (* ------------------------------------------------------------------------- *)
4348 (* This is useful for building a basis step-by-step. *)
4349 (* ------------------------------------------------------------------------- *)
4351 let INDEPENDENT_INSERT = prove
4352 (`!a:real^N s. independent(a INSERT s) <=>
4353 if a IN s then independent s
4354 else independent s /\ ~(a IN span s)`,
4355 REPEAT GEN_TAC THEN ASM_CASES_TAC `(a:real^N) IN s` THEN
4356 ASM_SIMP_TAC[SET_RULE `x IN s ==> (x INSERT s = s)`] THEN
4358 [DISCH_TAC THEN CONJ_TAC THENL
4359 [ASM_MESON_TAC[INDEPENDENT_MONO; SUBSET; IN_INSERT];
4360 POP_ASSUM MP_TAC THEN REWRITE_TAC[independent; dependent] THEN
4361 ASM_MESON_TAC[IN_INSERT; SET_RULE
4362 `~(a IN s) ==> ((a INSERT s) DELETE a = s)`]];
4364 REWRITE_TAC[independent; dependent; NOT_EXISTS_THM] THEN
4365 STRIP_TAC THEN X_GEN_TAC `b:real^N` THEN
4366 REWRITE_TAC[IN_INSERT] THEN ASM_CASES_TAC `b:real^N = a` THEN
4367 ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> ((a INSERT s) DELETE a = s)`] THEN
4368 ASM_SIMP_TAC[SET_RULE
4369 `~(a IN s) /\ ~(b = a)
4370 ==> ((a INSERT s) DELETE b = a INSERT (s DELETE b))`] THEN
4371 ASM_MESON_TAC[IN_SPAN_INSERT; SET_RULE
4372 `b IN s ==> (b INSERT (s DELETE b) = s)`]);;
4374 (* ------------------------------------------------------------------------- *)
4375 (* The degenerate case of the Exchange Lemma. *)
4376 (* ------------------------------------------------------------------------- *)
4378 let SPANNING_SUBSET_INDEPENDENT = prove
4379 (`!s t:real^N->bool.
4380 t SUBSET s /\ independent s /\ s SUBSET span(t) ==> (s = t)`,
4381 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
4382 ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET] THEN
4383 X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN
4384 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [independent]) THEN
4385 REWRITE_TAC[dependent; NOT_EXISTS_THM] THEN
4386 DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM_REWRITE_TAC[] THEN
4387 ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_DELETE]);;
4389 (* ------------------------------------------------------------------------- *)
4390 (* The general case of the Exchange Lemma, the key to what follows. *)
4391 (* ------------------------------------------------------------------------- *)
4393 let EXCHANGE_LEMMA = prove
4394 (`!s t:real^N->bool.
4395 FINITE t /\ independent s /\ s SUBSET span t
4396 ==> ?t'. t' HAS_SIZE (CARD t) /\
4397 s SUBSET t' /\ t' SUBSET (s UNION t) /\ s SUBSET (span t')`,
4399 WF_INDUCT_TAC `CARD(t DIFF s :real^N->bool)` THEN
4400 ASM_CASES_TAC `(s:real^N->bool) SUBSET t` THENL
4401 [ASM_MESON_TAC[HAS_SIZE; SUBSET_UNION]; ALL_TAC] THEN
4402 ASM_CASES_TAC `t SUBSET (s:real^N->bool)` THENL
4403 [ASM_MESON_TAC[SPANNING_SUBSET_INDEPENDENT; HAS_SIZE]; ALL_TAC] THEN
4405 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE[SUBSET] o check(is_neg o concl)) THEN
4406 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
4407 DISCH_THEN(X_CHOOSE_THEN `b:real^N` STRIP_ASSUME_TAC) THEN
4408 ASM_CASES_TAC `s SUBSET span(t DELETE (b:real^N))` THENL
4409 [FIRST_X_ASSUM(MP_TAC o
4410 SPECL [`t DELETE (b:real^N)`; `s:real^N->bool`]) THEN
4411 ASM_REWRITE_TAC[SET_RULE `s DELETE a DIFF t = (s DIFF t) DELETE a`] THEN
4412 ASM_SIMP_TAC[CARD_DELETE; FINITE_DIFF; IN_DIFF; FINITE_DELETE;
4413 CARD_EQ_0; ARITH_RULE `n - 1 < n <=> ~(n = 0)`] THEN
4415 [UNDISCH_TAC `~((s:real^N->bool) SUBSET t)` THEN ASM SET_TAC[];
4417 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
4418 EXISTS_TAC `(b:real^N) INSERT u` THEN
4419 ASM_SIMP_TAC[SUBSET_INSERT; INSERT_SUBSET; IN_UNION] THEN CONJ_TAC THENL
4420 [UNDISCH_TAC `(u:real^N->bool) HAS_SIZE CARD(t:real^N->bool) - 1` THEN
4421 SIMP_TAC[HAS_SIZE; FINITE_RULES; CARD_CLAUSES] THEN STRIP_TAC THEN
4422 COND_CASES_TAC THENL
4423 [ASM_MESON_TAC[SUBSET; IN_UNION; IN_DELETE]; ALL_TAC] THEN
4424 ASM_MESON_TAC[ARITH_RULE `~(n = 0) ==> (SUC(n - 1) = n)`;
4425 CARD_EQ_0; MEMBER_NOT_EMPTY];
4428 [UNDISCH_TAC `u SUBSET s UNION t DELETE (b:real^N)` THEN SET_TAC[];
4429 ASM_MESON_TAC[SUBSET; SPAN_MONO; IN_INSERT]];
4431 UNDISCH_TAC `~(s SUBSET span (t DELETE (b:real^N)))` THEN
4432 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SUBSET] THEN
4433 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
4434 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
4435 SUBGOAL_THEN `~(a:real^N = b)` ASSUME_TAC THENL
4436 [ASM_MESON_TAC[]; ALL_TAC] THEN
4437 SUBGOAL_THEN `~((a:real^N) IN t)` ASSUME_TAC THENL
4438 [ASM_MESON_TAC[IN_DELETE; SPAN_CLAUSES]; ALL_TAC] THEN
4439 FIRST_X_ASSUM(MP_TAC o SPECL
4440 [`(a:real^N) INSERT (t DELETE b)`; `s:real^N->bool`]) THEN
4442 [ASM_SIMP_TAC[SET_RULE
4443 `a IN s ==> ((a INSERT (t DELETE b) DIFF s) = (t DIFF s) DELETE b)`] THEN
4444 ASM_SIMP_TAC[CARD_DELETE; FINITE_DELETE; FINITE_DIFF; IN_DIFF] THEN
4445 ASM_SIMP_TAC[ARITH_RULE `n - 1 < n <=> ~(n = 0)`; CARD_EQ_0;
4447 UNDISCH_TAC `~((s:real^N->bool) SUBSET t)` THEN ASM SET_TAC[];
4450 [ASM_SIMP_TAC[FINITE_RULES; FINITE_DELETE] THEN
4451 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN
4452 DISCH_TAC THEN MATCH_MP_TAC SPAN_TRANS THEN EXISTS_TAC `b:real^N` THEN
4453 ASM_MESON_TAC[IN_SPAN_DELETE; SUBSET; SPAN_MONO;
4454 SET_RULE `t SUBSET (b INSERT (a INSERT (t DELETE b)))`];
4456 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^N->bool` THEN
4457 ASM_SIMP_TAC[HAS_SIZE; CARD_CLAUSES; CARD_DELETE; FINITE_DELETE; IN_DELETE;
4458 ARITH_RULE `(SUC(n - 1) = n) <=> ~(n = 0)`;
4460 UNDISCH_TAC `(b:real^N) IN t` THEN ASM SET_TAC[]);;
4462 (* ------------------------------------------------------------------------- *)
4463 (* This implies corresponding size bounds. *)
4464 (* ------------------------------------------------------------------------- *)
4466 let INDEPENDENT_SPAN_BOUND = prove
4467 (`!s t. FINITE t /\ independent s /\ s SUBSET span(t)
4468 ==> FINITE s /\ CARD(s) <= CARD(t)`,
4469 REPEAT GEN_TAC THEN DISCH_TAC THEN
4470 FIRST_ASSUM(MP_TAC o MATCH_MP EXCHANGE_LEMMA) THEN
4471 ASM_MESON_TAC[HAS_SIZE; CARD_SUBSET; FINITE_SUBSET]);;
4473 let INDEPENDENT_BOUND = prove
4475 independent s ==> FINITE s /\ CARD(s) <= dimindex(:N)`,
4476 REPEAT GEN_TAC THEN DISCH_TAC THEN
4477 ONCE_REWRITE_TAC[GSYM CARD_STDBASIS] THEN
4478 MATCH_MP_TAC INDEPENDENT_SPAN_BOUND THEN
4479 ASM_REWRITE_TAC[FINITE_STDBASIS; SPAN_STDBASIS; SUBSET_UNIV]);;
4481 let DEPENDENT_BIGGERSET = prove
4482 (`!s:real^N->bool. (FINITE s ==> CARD(s) > dimindex(:N)) ==> dependent s`,
4483 MP_TAC INDEPENDENT_BOUND THEN MATCH_MP_TAC MONO_FORALL THEN
4484 REWRITE_TAC[GT; GSYM NOT_LE; independent] THEN MESON_TAC[]);;
4486 let INDEPENDENT_IMP_FINITE = prove
4487 (`!s:real^N->bool. independent s ==> FINITE s`,
4488 SIMP_TAC[INDEPENDENT_BOUND]);;
4490 (* ------------------------------------------------------------------------- *)
4491 (* Explicit formulation of independence. *)
4492 (* ------------------------------------------------------------------------- *)
4494 let INDEPENDENT_EXPLICIT = prove
4498 !c. vsum b (\v. c(v) % v) = vec 0 ==> !v. v IN b ==> c(v) = &0`,
4500 ASM_CASES_TAC `FINITE(b:real^N->bool)` THENL
4501 [ALL_TAC; ASM_MESON_TAC[INDEPENDENT_BOUND]] THEN
4502 ASM_SIMP_TAC[independent; DEPENDENT_FINITE] THEN MESON_TAC[]);;
4504 let INDEPENDENT_SING = prove
4505 (`!x. independent {x} <=> ~(x = vec 0)`,
4506 REWRITE_TAC[INDEPENDENT_INSERT; NOT_IN_EMPTY; SPAN_EMPTY] THEN
4507 REWRITE_TAC[INDEPENDENT_EMPTY] THEN SET_TAC[]);;
4509 let DEPENDENT_SING = prove
4510 (`!x. dependent {x} <=> x = vec 0`,
4511 MESON_TAC[independent; INDEPENDENT_SING]);;
4513 let DEPENDENT_2 = prove
4516 if a = b then a = vec 0
4517 else ?x y. x % a + y % b = vec 0 /\ ~(x = &0 /\ y = &0)`,
4518 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
4519 ASM_REWRITE_TAC[DEPENDENT_SING; SET_RULE `{x,x} = {x}`] THEN
4520 SIMP_TAC[DEPENDENT_FINITE; VSUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN
4521 ASM_REWRITE_TAC[IN_SING; NOT_IN_EMPTY; VECTOR_ADD_RID; EXISTS_IN_INSERT] THEN
4522 EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
4523 [X_GEN_TAC `u:real^N->real` THEN STRIP_TAC THEN
4524 MAP_EVERY EXISTS_TAC [`(u:real^N->real) a`; `(u:real^N->real) b`] THEN
4526 MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN DISCH_TAC THEN EXISTS_TAC
4527 `\v:real^N. if v = a then x else if v = b then y else z:real` THEN
4530 let DEPENDENT_3 = prove
4532 ~(a = b) /\ ~(a = c) /\ ~(b = c)
4533 ==> (dependent {a,b,c} <=>
4534 ?x y z. x % a + y % b + z % c = vec 0 /\
4535 ~(x = &0 /\ y = &0 /\ z = &0))`,
4536 REPEAT STRIP_TAC THEN
4537 SIMP_TAC[DEPENDENT_FINITE; VSUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN
4538 ASM_REWRITE_TAC[IN_SING; NOT_IN_EMPTY; VECTOR_ADD_RID; IN_INSERT] THEN
4539 EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
4540 [X_GEN_TAC `u:real^N->real` THEN STRIP_TAC THEN MAP_EVERY EXISTS_TAC
4541 [`(u:real^N->real) a`; `(u:real^N->real) b`; `(u:real^N->real) c`];
4542 MAP_EVERY X_GEN_TAC [`x:real`; `y:real`; `z:real`] THEN DISCH_TAC THEN
4544 `\v:real^N. if v = a then x else if v = b then y else z:real`] THEN
4547 let INDEPENDENT_2 = prove
4549 independent{a,b} /\ ~(a = b)
4550 ==> (x % a + y % b = vec 0 <=> x = &0 /\ y = &0)`,
4551 SIMP_TAC[IMP_CONJ_ALT; independent; DEPENDENT_2] THEN
4552 MESON_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID]);;
4554 let INDEPENDENT_3 = prove
4555 (`!a b c:real^N x y z.
4556 independent{a,b,c} /\ ~(a = b) /\ ~(a = c) /\ ~(b = c)
4557 ==> (x % a + y % b + z % c = vec 0 <=> x = &0 /\ y = &0 /\ z = &0)`,
4558 SIMP_TAC[IMP_CONJ_ALT; independent; DEPENDENT_3] THEN
4559 MESON_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID]);;
4561 (* ------------------------------------------------------------------------- *)
4562 (* Hence we can create a maximal independent subset. *)
4563 (* ------------------------------------------------------------------------- *)
4565 let MAXIMAL_INDEPENDENT_SUBSET_EXTEND = prove
4566 (`!s v:real^N->bool.
4567 s SUBSET v /\ independent s
4568 ==> ?b. s SUBSET b /\ b SUBSET v /\ independent b /\
4571 WF_INDUCT_TAC `dimindex(:N) - CARD(s:real^N->bool)` THEN
4572 REPEAT STRIP_TAC THEN
4573 ASM_CASES_TAC `v SUBSET (span(s:real^N->bool))` THENL
4574 [ASM_MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN
4575 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [SUBSET]) THEN
4576 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
4577 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
4578 FIRST_X_ASSUM(MP_TAC o SPEC `(a:real^N) INSERT s`) THEN
4579 REWRITE_TAC[IMP_IMP] THEN ANTS_TAC THENL
4580 [ALL_TAC; MESON_TAC[INSERT_SUBSET]] THEN
4581 SUBGOAL_THEN `independent ((a:real^N) INSERT s)` ASSUME_TAC THENL
4582 [ASM_REWRITE_TAC[INDEPENDENT_INSERT; COND_ID]; ALL_TAC] THEN
4583 ASM_REWRITE_TAC[INSERT_SUBSET] THEN
4584 MATCH_MP_TAC(ARITH_RULE `(b = a + 1) /\ b <= n ==> n - b < n - a`) THEN
4585 ASM_SIMP_TAC[CARD_CLAUSES; INDEPENDENT_BOUND] THEN
4586 ASM_MESON_TAC[SPAN_SUPERSET; ADD1]);;
4588 let MAXIMAL_INDEPENDENT_SUBSET = prove
4589 (`!v:real^N->bool. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b)`,
4590 MP_TAC(SPEC `EMPTY:real^N->bool` MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
4591 REWRITE_TAC[EMPTY_SUBSET; INDEPENDENT_EMPTY]);;
4593 (* ------------------------------------------------------------------------- *)
4594 (* A kind of closed graph property for linearity. *)
4595 (* ------------------------------------------------------------------------- *)
4597 let LINEAR_SUBSPACE_GRAPH = prove
4598 (`!f:real^M->real^N.
4599 linear f <=> subspace {pastecart x (f x) | x IN (:real^M)}`,
4600 REWRITE_TAC[linear; subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
4601 REWRITE_TAC[FORALL_IN_GSPEC; GSYM(SPEC `0` PASTECART_VEC); IN_UNIV] THEN
4602 REWRITE_TAC[IN_ELIM_THM; PASTECART_INJ; UNWIND_THM1; PASTECART_ADD;
4603 GSYM PASTECART_CMUL] THEN
4604 MESON_TAC[VECTOR_MUL_LZERO]);;
4606 (* ------------------------------------------------------------------------- *)
4607 (* Notion of dimension. *)
4608 (* ------------------------------------------------------------------------- *)
4610 let dim = new_definition
4611 `dim v = @n. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\
4614 let BASIS_EXISTS = prove
4615 (`!v. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\
4616 b HAS_SIZE (dim v)`,
4617 GEN_TAC THEN REWRITE_TAC[dim] THEN CONV_TAC SELECT_CONV THEN
4618 MESON_TAC[MAXIMAL_INDEPENDENT_SUBSET; HAS_SIZE; INDEPENDENT_BOUND]);;
4620 let BASIS_EXISTS_FINITE = prove
4621 (`!v. ?b. FINITE b /\
4624 v SUBSET (span b) /\
4625 b HAS_SIZE (dim v)`,
4626 MESON_TAC[BASIS_EXISTS; INDEPENDENT_IMP_FINITE]);;
4628 let BASIS_SUBSPACE_EXISTS = prove
4636 REPEAT STRIP_TAC THEN
4637 MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN
4638 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN
4639 ASM_REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN
4640 ASM_MESON_TAC[SPAN_EQ_SELF; SPAN_MONO; INDEPENDENT_IMP_FINITE]);;
4642 (* ------------------------------------------------------------------------- *)
4643 (* Consequences of independence or spanning for cardinality. *)
4644 (* ------------------------------------------------------------------------- *)
4646 let INDEPENDENT_CARD_LE_DIM = prove
4647 (`!v b:real^N->bool.
4648 b SUBSET v /\ independent b ==> FINITE b /\ CARD(b) <= dim v`,
4649 MESON_TAC[BASIS_EXISTS; INDEPENDENT_SPAN_BOUND; HAS_SIZE;SUBSET_TRANS]);;
4651 let SPAN_CARD_GE_DIM = prove
4652 (`!v b:real^N->bool.
4653 v SUBSET (span b) /\ FINITE b ==> dim(v) <= CARD(b)`,
4654 MESON_TAC[BASIS_EXISTS; INDEPENDENT_SPAN_BOUND; HAS_SIZE;SUBSET_TRANS]);;
4656 let BASIS_CARD_EQ_DIM = prove
4657 (`!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b
4658 ==> FINITE b /\ (CARD b = dim v)`,
4659 MESON_TAC[LE_ANTISYM; INDEPENDENT_CARD_LE_DIM; SPAN_CARD_GE_DIM]);;
4661 let BASIS_HAS_SIZE_DIM = prove
4662 (`!v b. independent b /\ span b = v ==> b HAS_SIZE (dim v)`,
4663 REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_SIZE] THEN
4664 MATCH_MP_TAC BASIS_CARD_EQ_DIM THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN
4665 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[SPAN_INC]);;
4667 let DIM_UNIQUE = prove
4668 (`!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b /\ b HAS_SIZE n
4670 MESON_TAC[BASIS_CARD_EQ_DIM; HAS_SIZE]);;
4672 let DIM_LE_CARD = prove
4673 (`!s. FINITE s ==> dim s <= CARD s`,
4674 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN
4675 ASM_REWRITE_TAC[SPAN_INC; SUBSET_REFL]);;
4677 (* ------------------------------------------------------------------------- *)
4678 (* More lemmas about dimension. *)
4679 (* ------------------------------------------------------------------------- *)
4681 let DIM_UNIV = prove
4682 (`dim(:real^N) = dimindex(:N)`,
4683 MATCH_MP_TAC DIM_UNIQUE THEN
4684 EXISTS_TAC `{basis i :real^N | 1 <= i /\ i <= dimindex(:N)}` THEN
4685 REWRITE_TAC[SUBSET_UNIV; SPAN_STDBASIS; HAS_SIZE_STDBASIS;
4686 INDEPENDENT_STDBASIS]);;
4688 let DIM_SUBSET = prove
4689 (`!s t:real^N->bool. s SUBSET t ==> dim(s) <= dim(t)`,
4690 MESON_TAC[BASIS_EXISTS; INDEPENDENT_SPAN_BOUND; SUBSET; HAS_SIZE]);;
4692 let DIM_SUBSET_UNIV = prove
4693 (`!s:real^N->bool. dim(s) <= dimindex(:N)`,
4694 GEN_TAC THEN REWRITE_TAC[GSYM DIM_UNIV] THEN
4695 MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]);;
4697 let BASIS_HAS_SIZE_UNIV = prove
4698 (`!b. independent b /\ span b = (:real^N) ==> b HAS_SIZE (dimindex(:N))`,
4699 REWRITE_TAC[GSYM DIM_UNIV; BASIS_HAS_SIZE_DIM]);;
4701 (* ------------------------------------------------------------------------- *)
4702 (* Converses to those. *)
4703 (* ------------------------------------------------------------------------- *)
4705 let CARD_GE_DIM_INDEPENDENT = prove
4706 (`!v b:real^N->bool.
4707 b SUBSET v /\ independent b /\ dim v <= CARD(b)
4708 ==> v SUBSET (span b)`,
4709 REPEAT STRIP_TAC THEN
4710 SUBGOAL_THEN `!a:real^N. ~(a IN v /\ ~(a IN span b))` MP_TAC THENL
4711 [ALL_TAC; SET_TAC[]] THEN
4712 X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN
4713 SUBGOAL_THEN `independent((a:real^N) INSERT b)` ASSUME_TAC THENL
4714 [ASM_MESON_TAC[INDEPENDENT_INSERT]; ALL_TAC] THEN
4715 MP_TAC(ISPECL [`v:real^N->bool`; `(a:real^N) INSERT b`]
4716 INDEPENDENT_CARD_LE_DIM) THEN
4717 ASM_SIMP_TAC[INSERT_SUBSET; CARD_CLAUSES; INDEPENDENT_BOUND] THEN
4718 ASM_MESON_TAC[SPAN_SUPERSET; SUBSET; ARITH_RULE
4719 `x <= y ==> ~(SUC y <= x)`]);;
4721 let CARD_LE_DIM_SPANNING = prove
4722 (`!v b:real^N->bool.
4723 v SUBSET (span b) /\ FINITE b /\ CARD(b) <= dim v
4725 REPEAT STRIP_TAC THEN REWRITE_TAC[independent; dependent] THEN
4726 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
4727 SUBGOAL_THEN `dim(v:real^N->bool) <= CARD(b DELETE (a:real^N))` MP_TAC THENL
4729 ASM_SIMP_TAC[CARD_DELETE] THEN MATCH_MP_TAC
4730 (ARITH_RULE `b <= n /\ ~(b = 0) ==> ~(n <= b - 1)`) THEN
4731 ASM_SIMP_TAC[CARD_EQ_0] THEN ASM_MESON_TAC[MEMBER_NOT_EMPTY]] THEN
4732 MATCH_MP_TAC SPAN_CARD_GE_DIM THEN ASM_SIMP_TAC[FINITE_DELETE] THEN
4733 REWRITE_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN
4734 MATCH_MP_TAC SPAN_TRANS THEN EXISTS_TAC `a:real^N` THEN
4735 ASM_SIMP_TAC[SET_RULE `a IN b ==> (a INSERT (b DELETE a) = b)`] THEN
4736 ASM_MESON_TAC[SUBSET]);;
4738 let CARD_EQ_DIM = prove
4739 (`!v b. b SUBSET v /\ b HAS_SIZE (dim v)
4740 ==> (independent b <=> v SUBSET (span b))`,
4741 REWRITE_TAC[HAS_SIZE; GSYM LE_ANTISYM] THEN
4742 MESON_TAC[CARD_LE_DIM_SPANNING; CARD_GE_DIM_INDEPENDENT]);;
4744 (* ------------------------------------------------------------------------- *)
4745 (* More general size bound lemmas. *)
4746 (* ------------------------------------------------------------------------- *)
4748 let INDEPENDENT_BOUND_GENERAL = prove
4749 (`!s:real^N->bool. independent s ==> FINITE s /\ CARD(s) <= dim(s)`,
4750 MESON_TAC[INDEPENDENT_CARD_LE_DIM; INDEPENDENT_BOUND; SUBSET_REFL]);;
4752 let DEPENDENT_BIGGERSET_GENERAL = prove
4753 (`!s:real^N->bool. (FINITE s ==> CARD(s) > dim(s)) ==> dependent s`,
4754 MP_TAC INDEPENDENT_BOUND_GENERAL THEN MATCH_MP_TAC MONO_FORALL THEN
4755 REWRITE_TAC[GT; GSYM NOT_LE; independent] THEN MESON_TAC[]);;
4757 let DIM_SPAN = prove
4758 (`!s:real^N->bool. dim(span s) = dim s`,
4759 GEN_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THENL
4761 MATCH_MP_TAC DIM_SUBSET THEN MESON_TAC[SUBSET; SPAN_SUPERSET]] THEN
4762 MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN
4763 REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN
4764 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
4765 MATCH_MP_TAC SPAN_CARD_GE_DIM THEN ASM_REWRITE_TAC[] THEN
4766 GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_SPAN] THEN
4767 MATCH_MP_TAC SPAN_MONO THEN ASM_REWRITE_TAC[]);;
4769 let DIM_INSERT_0 = prove
4770 (`!s:real^N->bool. dim(vec 0 INSERT s) = dim s`,
4771 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
4772 REWRITE_TAC[SPAN_INSERT_0]);;
4774 let DIM_EQ_CARD = prove
4775 (`!s:real^N->bool. independent s ==> dim s = CARD s`,
4776 REPEAT STRIP_TAC THEN MP_TAC
4777 (ISPECL [`span s:real^N->bool`; `s:real^N->bool`] BASIS_CARD_EQ_DIM) THEN
4778 ASM_SIMP_TAC[SUBSET_REFL; SPAN_INC; DIM_SPAN]);;
4780 let SUBSET_LE_DIM = prove
4781 (`!s t:real^N->bool. s SUBSET (span t) ==> dim s <= dim t`,
4782 MESON_TAC[DIM_SPAN; DIM_SUBSET]);;
4784 let SPAN_EQ_DIM = prove
4785 (`!s t. span s = span t ==> dim s = dim t`,
4786 MESON_TAC[DIM_SPAN]);;
4788 let SPANS_IMAGE = prove
4789 (`!f b v. linear f /\ v SUBSET (span b)
4790 ==> (IMAGE f v) SUBSET span(IMAGE f b)`,
4791 SIMP_TAC[SPAN_LINEAR_IMAGE; IMAGE_SUBSET]);;
4793 let DIM_LINEAR_IMAGE_LE = prove
4794 (`!f:real^M->real^N s. linear f ==> dim(IMAGE f s) <= dim s`,
4795 REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^M->bool` BASIS_EXISTS) THEN
4796 REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN FIRST_ASSUM(SUBST1_TAC o SYM) THEN
4797 MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD(IMAGE (f:real^M->real^N) b)` THEN
4798 ASM_SIMP_TAC[CARD_IMAGE_LE] THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN
4799 ASM_MESON_TAC[SPAN_LINEAR_IMAGE; SPANS_IMAGE; SUBSET_IMAGE; FINITE_IMAGE]);;
4801 (* ------------------------------------------------------------------------- *)
4802 (* Some stepping theorems. *)
4803 (* ------------------------------------------------------------------------- *)
4805 let DIM_EMPTY = prove
4806 (`dim({}:real^N->bool) = 0`,
4807 MATCH_MP_TAC DIM_UNIQUE THEN EXISTS_TAC `{}:real^N->bool` THEN
4808 REWRITE_TAC[SUBSET_REFL; SPAN_EMPTY; INDEPENDENT_EMPTY; HAS_SIZE_0;
4811 let DIM_INSERT = prove
4812 (`!x:real^N s. dim(x INSERT s) = if x IN span s then dim s else dim s + 1`,
4813 REPEAT GEN_TAC THEN COND_CASES_TAC THENL
4814 [MATCH_MP_TAC SPAN_EQ_DIM THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
4815 ASM_MESON_TAC[SPAN_TRANS; SUBSET; SPAN_MONO; IN_INSERT];
4817 X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC
4818 (ISPEC `span s:real^N->bool` BASIS_EXISTS) THEN
4819 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
4820 MATCH_MP_TAC DIM_UNIQUE THEN
4821 EXISTS_TAC `(x:real^N) INSERT b` THEN REPEAT CONJ_TAC THENL
4822 [REWRITE_TAC[INSERT_SUBSET] THEN
4823 ASM_MESON_TAC[SUBSET; SPAN_MONO; IN_INSERT; SPAN_SUPERSET];
4824 REWRITE_TAC[SUBSET; SPAN_BREAKDOWN_EQ] THEN
4825 ASM_MESON_TAC[SUBSET];
4826 REWRITE_TAC[INDEPENDENT_INSERT] THEN
4827 ASM_MESON_TAC[SUBSET; SPAN_SUPERSET; SPAN_MONO; SPAN_SPAN];
4828 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
4829 ASM_SIMP_TAC[HAS_SIZE; CARD_CLAUSES; FINITE_INSERT; ADD1] THEN
4830 ASM_MESON_TAC[SUBSET; SPAN_SUPERSET; SPAN_MONO; SPAN_SPAN]]);;
4832 let DIM_SING = prove
4833 (`!x. dim{x} = if x = vec 0 then 0 else 1`,
4834 REWRITE_TAC[DIM_INSERT; DIM_EMPTY; SPAN_EMPTY; IN_SING; ARITH]);;
4836 let DIM_EQ_0 = prove
4837 (`!s:real^N->bool. dim s = 0 <=> s SUBSET {vec 0}`,
4838 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
4839 [MATCH_MP_TAC(SET_RULE
4840 `~(?b. ~(b = a) /\ {b} SUBSET s) ==> s SUBSET {a}`) THEN
4841 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP DIM_SUBSET);
4842 MATCH_MP_TAC(ARITH_RULE `!m. m = 0 /\ n <= m ==> n = 0`) THEN
4843 EXISTS_TAC `dim{vec 0:real^N}` THEN ASM_SIMP_TAC[DIM_SUBSET]] THEN
4844 ASM_REWRITE_TAC[DIM_SING; ARITH]);;
4846 (* ------------------------------------------------------------------------- *)
4847 (* Choosing a subspace of a given dimension. *)
4848 (* ------------------------------------------------------------------------- *)
4850 let CHOOSE_SUBSPACE_OF_SUBSPACE = prove
4851 (`!s:real^N->bool n.
4852 n <= dim s ==> ?t. subspace t /\ t SUBSET span s /\ dim t = n`,
4853 GEN_TAC THEN INDUCT_TAC THENL
4854 [DISCH_TAC THEN EXISTS_TAC `{vec 0:real^N}` THEN
4855 REWRITE_TAC[SUBSPACE_TRIVIAL; DIM_SING; SING_SUBSET; SPAN_0];
4856 DISCH_THEN(fun th -> POP_ASSUM MP_TAC THEN ASSUME_TAC th) THEN
4857 ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
4858 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
4859 ASM_CASES_TAC `span (s:real^N->bool) SUBSET span t` THENL
4860 [SUBGOAL_THEN `dim(s:real^N->bool) = dim(t:real^N->bool)` MP_TAC THENL
4861 [ALL_TAC; ASM_ARITH_TAC] THEN MATCH_MP_TAC SPAN_EQ_DIM THEN
4862 MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN
4863 MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN ASM_REWRITE_TAC[SUBSPACE_SPAN];
4864 FIRST_ASSUM(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC o MATCH_MP(SET_RULE
4865 `~(s SUBSET t) ==> ?a. a IN s /\ ~(a IN t)`)) THEN
4866 EXISTS_TAC `span((y:real^N) INSERT t)` THEN
4867 REWRITE_TAC[SUBSPACE_SPAN] THEN CONJ_TAC THENL
4868 [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
4869 ASM_REWRITE_TAC[SUBSPACE_SPAN] THEN ASM SET_TAC[];
4870 ASM_REWRITE_TAC[DIM_SPAN; DIM_INSERT; ADD1]]]]);;
4872 (* ------------------------------------------------------------------------- *)
4873 (* Relation between bases and injectivity/surjectivity of map. *)
4874 (* ------------------------------------------------------------------------- *)
4876 let SPANNING_SURJECTIVE_IMAGE = prove
4877 (`!f:real^M->real^N s.
4878 UNIV SUBSET (span s) /\ linear f /\ (!y. ?x. f(x) = y)
4879 ==> UNIV SUBSET span(IMAGE f s)`,
4880 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN
4881 EXISTS_TAC `IMAGE (f:real^M->real^N) UNIV` THEN
4882 ASM_SIMP_TAC[SPANS_IMAGE] THEN
4883 REWRITE_TAC[SUBSET; IN_UNIV; IN_IMAGE] THEN ASM_MESON_TAC[]);;
4885 let INDEPENDENT_INJECTIVE_IMAGE_GEN = prove
4886 (`!f:real^M->real^N s.
4887 independent s /\ linear f /\
4888 (!x y. x IN span s /\ y IN span s /\ f(x) = f(y) ==> x = y)
4889 ==> independent (IMAGE f s)`,
4891 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
4892 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
4893 REWRITE_TAC[independent; DEPENDENT_EXPLICIT] THEN
4894 REWRITE_TAC[CONJ_ASSOC; FINITE_SUBSET_IMAGE] THEN
4896 `(?s u. ((?t. p t /\ s = f t) /\ q s u) /\ r s u) <=>
4897 (?t u. p t /\ q (f t) u /\ r (f t) u)`] THEN
4898 REWRITE_TAC[EXISTS_IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN
4899 MAP_EVERY X_GEN_TAC [`t:real^M->bool`; `u:real^N->real`] THEN
4900 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
4901 MAP_EVERY EXISTS_TAC
4902 [`t:real^M->bool`; `(u:real^N->real) o (f:real^M->real^N)`] THEN
4903 ASM_REWRITE_TAC[o_THM] THEN
4904 FIRST_ASSUM MATCH_MP_TAC THEN REPEAT CONJ_TAC THENL
4905 [MATCH_MP_TAC SPAN_VSUM THEN ASM_REWRITE_TAC[] THEN
4906 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
4907 MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[];
4908 REWRITE_TAC[SPAN_0];
4909 ASM_SIMP_TAC[LINEAR_VSUM] THEN
4910 FIRST_ASSUM(SUBST1_TAC o MATCH_MP LINEAR_0) THEN
4911 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN CONV_TAC SYM_CONV THEN
4912 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN
4913 ASM_SIMP_TAC[o_DEF; LINEAR_CMUL] THEN DISCH_THEN MATCH_MP_TAC THEN
4914 ASM_MESON_TAC[SPAN_SUPERSET; SUBSET]]);;
4916 let INDEPENDENT_INJECTIVE_IMAGE = prove
4917 (`!f:real^M->real^N s.
4918 independent s /\ linear f /\ (!x y. (f(x) = f(y)) ==> (x = y))
4919 ==> independent (IMAGE f s)`,
4920 REPEAT STRIP_TAC THEN MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN
4923 (* ------------------------------------------------------------------------- *)
4924 (* Picking an orthogonal replacement for a spanning set. *)
4925 (* ------------------------------------------------------------------------- *)
4927 let VECTOR_SUB_PROJECT_ORTHOGONAL = prove
4928 (`!b:real^N x. b dot (x - ((b dot x) / (b dot b)) % b) = &0`,
4929 REPEAT GEN_TAC THEN ASM_CASES_TAC `b = vec 0 :real^N` THENL
4930 [ASM_REWRITE_TAC[DOT_LZERO]; ALL_TAC] THEN
4931 ASM_SIMP_TAC[DOT_RSUB; DOT_RMUL] THEN
4932 ASM_SIMP_TAC[REAL_SUB_REFL; REAL_DIV_RMUL; DOT_EQ_0]);;
4934 let BASIS_ORTHOGONAL = prove
4937 ==> ?c. FINITE c /\ CARD c <= CARD b /\
4938 span c = span b /\ pairwise orthogonal c`,
4939 REWRITE_TAC[pairwise; orthogonal] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
4941 [EXISTS_TAC `{}:real^N->bool` THEN
4942 REWRITE_TAC[FINITE_RULES; NOT_IN_EMPTY; LE_REFL];
4944 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N->bool`] THEN
4945 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC)
4946 STRIP_ASSUME_TAC) THEN
4947 EXISTS_TAC `(a - vsum c (\x. ((x dot a) / (x dot x)) % x):real^N)
4949 ASM_SIMP_TAC[FINITE_RULES; CARD_CLAUSES] THEN REPEAT CONJ_TAC THENL
4951 REWRITE_TAC[EXTENSION; SPAN_BREAKDOWN_EQ] THEN
4952 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN GEN_TAC THEN
4953 AP_TERM_TAC THEN ABS_TAC THEN REWRITE_TAC[VECTOR_SUB_LDISTRIB] THEN
4954 REWRITE_TAC[VECTOR_ARITH `a - (x - y):real^N = y + (a - x)`] THEN
4955 MATCH_MP_TAC SPAN_ADD_EQ THEN MATCH_MP_TAC SPAN_MUL THEN
4956 MATCH_MP_TAC SPAN_VSUM THEN ASM_REWRITE_TAC[] THEN
4957 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
4958 ASM_SIMP_TAC[SPAN_SUPERSET];
4959 REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THENL
4961 FIRST_X_ASSUM SUBST_ALL_TAC;
4962 FIRST_X_ASSUM SUBST_ALL_TAC;
4963 ASM_MESON_TAC[]] THEN
4964 REWRITE_TAC[DOT_LSUB; DOT_RSUB; REAL_SUB_0] THEN
4965 FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE
4966 `x IN s ==> s = x INSERT (s DELETE x)`)) THEN
4967 ASM_SIMP_TAC[VSUM_CLAUSES; FINITE_DELETE; IN_DELETE] THEN
4968 REWRITE_TAC[DOT_LADD; DOT_RADD; DOT_LMUL; DOT_RMUL] THEN
4969 MATCH_MP_TAC(REAL_ARITH `s = &0 /\ a = b ==> b = a + s`) THEN
4970 ASM_SIMP_TAC[DOT_LSUM; DOT_RSUM; FINITE_DELETE] THEN
4972 [MATCH_MP_TAC SUM_EQ_0 THEN
4973 ASM_SIMP_TAC[DOT_LMUL; DOT_RMUL; IN_DELETE;
4974 REAL_MUL_RZERO; REAL_MUL_LZERO];
4975 W(MP_TAC o PART_MATCH (lhand o rand) REAL_DIV_RMUL o lhand o snd) THEN
4976 REWRITE_TAC[DOT_SYM] THEN
4977 MATCH_MP_TAC(TAUT `(p ==> q) ==> (~p ==> q) ==> q`) THEN
4978 SIMP_TAC[] THEN SIMP_TAC[DOT_EQ_0; DOT_RZERO; DOT_LZERO] THEN
4979 REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO]])]);;
4981 let ORTHOGONAL_BASIS_EXISTS = prove
4983 ?b. independent b /\
4987 pairwise orthogonal b`,
4988 GEN_TAC THEN MP_TAC(ISPEC `v:real^N->bool` BASIS_EXISTS) THEN
4989 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
4990 MP_TAC(SPEC `b:real^N->bool` BASIS_ORTHOGONAL) THEN
4991 ANTS_TAC THENL [ASM_MESON_TAC[HAS_SIZE]; ALL_TAC] THEN
4992 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N->bool` THEN
4993 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
4994 [MATCH_MP_TAC CARD_LE_DIM_SPANNING THEN ASM_REWRITE_TAC[] THEN
4995 EXISTS_TAC `span(v):real^N->bool` THEN CONJ_TAC THENL
4996 [ASM_MESON_TAC[SPAN_SPAN; SPAN_MONO];
4997 ASM_MESON_TAC[LE_TRANS; HAS_SIZE; DIM_SPAN]];
4998 ASM_MESON_TAC[SUBSET_TRANS; SPAN_INC; SPAN_SPAN; SPAN_MONO];
4999 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
5000 ASM_REWRITE_TAC[HAS_SIZE; GSYM LE_ANTISYM] THEN
5001 CONJ_TAC THENL [ASM_MESON_TAC[LE_TRANS]; ALL_TAC] THEN
5002 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN
5003 ASM_REWRITE_TAC[] THEN
5004 ASM_MESON_TAC[SPAN_SPAN; SPAN_MONO; SUBSET_TRANS; SPAN_INC]]);;
5007 (`!s t. span s = span t <=> s SUBSET span t /\ t SUBSET span s`,
5008 REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN
5009 MESON_TAC[SUBSET_TRANS; SPAN_SPAN; SPAN_MONO; SPAN_INC]);;
5011 let SPAN_EQ_INSERT = prove
5012 (`!s x. span(x INSERT s) = span s <=> x IN span s`,
5013 REWRITE_TAC[SPAN_EQ; INSERT_SUBSET] THEN
5014 MESON_TAC[SPAN_INC; SUBSET; SET_RULE `s SUBSET (x INSERT s)`]);;
5016 (* ------------------------------------------------------------------------- *)
5017 (* We can extend a linear basis-basis injection to the whole set. *)
5018 (* ------------------------------------------------------------------------- *)
5020 let LINEAR_INDEP_IMAGE_LEMMA = prove
5021 (`!f b. linear(f:real^M->real^N) /\
5023 independent (IMAGE f b) /\
5024 (!x y. x IN b /\ y IN b /\ (f x = f y) ==> (x = y))
5025 ==> !x. x IN span b ==> (f(x) = vec 0) ==> (x = vec 0)`,
5026 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
5027 GEN_TAC THEN DISCH_TAC THEN
5028 GEN_REWRITE_TAC (BINDER_CONV o RAND_CONV) [IMP_IMP] THEN
5029 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5030 CONJ_TAC THENL [SIMP_TAC[IN_SING; SPAN_EMPTY]; ALL_TAC] THEN
5031 MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M->bool`] THEN STRIP_TAC THEN
5032 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
5034 [ASM_MESON_TAC[INDEPENDENT_MONO; IMAGE_CLAUSES; SUBSET; IN_INSERT];
5036 DISCH_TAC THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
5037 MP_TAC(ISPECL [`a:real^M`; `(a:real^M) INSERT b`; `x:real^M`]
5038 SPAN_BREAKDOWN) THEN
5039 ASM_REWRITE_TAC[IN_INSERT] THEN
5040 SIMP_TAC[ASSUME `~((a:real^M) IN b)`; SET_RULE
5041 `~(a IN b) ==> ((a INSERT b) DELETE a = b)`] THEN
5042 DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN
5043 SUBGOAL_THEN `(f:real^M->real^N)(x - k % a) IN span(IMAGE f b)` MP_TAC THENL
5044 [ASM_MESON_TAC[SPAN_LINEAR_IMAGE; IN_IMAGE]; ALL_TAC] THEN
5045 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_SUB th]) THEN
5046 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_CMUL th]) THEN
5047 ASM_REWRITE_TAC[VECTOR_ARITH `vec 0 - k % x = (--k) % x`] THEN
5048 ASM_CASES_TAC `k = &0` THENL
5049 [ASM_MESON_TAC[VECTOR_ARITH `x - &0 % y = x`]; ALL_TAC] THEN
5050 DISCH_THEN(MP_TAC o SPEC `--inv(k)` o MATCH_MP SPAN_MUL) THEN
5051 REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LNEG; REAL_MUL_RNEG] THEN
5052 SIMP_TAC[REAL_NEGNEG; REAL_MUL_LINV; ASSUME `~(k = &0)`] THEN
5053 REWRITE_TAC[VECTOR_MUL_LID] THEN
5054 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [independent]) THEN
5055 REWRITE_TAC[dependent; NOT_EXISTS_THM] THEN
5056 DISCH_THEN(MP_TAC o SPEC `(f:real^M->real^N) a`) THEN
5058 `IMAGE (f:real^M->real^N) (a INSERT b) DELETE f a =
5059 IMAGE f ((a INSERT b) DELETE a)`
5061 [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DELETE; IN_INSERT] THEN
5062 ASM_MESON_TAC[IN_INSERT];
5064 ASM_REWRITE_TAC[DELETE_INSERT] THEN
5065 SIMP_TAC[SET_RULE `~(a IN b) ==> (b DELETE a = b)`;
5066 ASSUME `~(a:real^M IN b)`] THEN
5067 SIMP_TAC[IMAGE_CLAUSES; IN_INSERT]);;
5069 (* ------------------------------------------------------------------------- *)
5070 (* We can extend a linear mapping from basis. *)
5071 (* ------------------------------------------------------------------------- *)
5073 let LINEAR_INDEPENDENT_EXTEND_LEMMA = prove
5076 ==> ?g:real^M->real^N.
5077 (!x y. x IN span b /\ y IN span b
5078 ==> (g(x + y) = g(x) + g(y))) /\
5079 (!x c. x IN span b ==> (g(c % x) = c % g(x))) /\
5080 (!x. x IN b ==> (g x = f x))`,
5081 GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5082 REWRITE_TAC[NOT_IN_EMPTY; INDEPENDENT_INSERT] THEN CONJ_TAC THENL
5083 [REPEAT STRIP_TAC THEN EXISTS_TAC `(\x. vec 0):real^M->real^N` THEN
5084 SIMP_TAC[SPAN_EMPTY] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC;
5086 SIMP_TAC[] THEN MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M->bool`] THEN
5087 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
5088 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
5089 DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN
5090 ABBREV_TAC `h = \z:real^M. @k. (z - k % a) IN span b` THEN
5091 SUBGOAL_THEN `!z:real^M. z IN span(a INSERT b)
5092 ==> (z - h(z) % a) IN span(b) /\
5093 !k. (z - k % a) IN span(b) ==> (k = h(z))`
5095 [GEN_TAC THEN DISCH_TAC THEN
5096 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
5097 [EXPAND_TAC "h" THEN CONV_TAC SELECT_CONV THEN
5098 ASM_MESON_TAC[SPAN_BREAKDOWN_EQ];
5100 REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN GEN_TAC THEN
5101 DISCH_THEN(MP_TAC o MATCH_MP SPAN_SUB) THEN
5102 REWRITE_TAC[VECTOR_ARITH `(z - a % v) - (z - b % v) = (b - a) % v`] THEN
5103 ASM_CASES_TAC `k = (h:real^M->real) z` THEN ASM_REWRITE_TAC[] THEN
5104 DISCH_THEN(MP_TAC o SPEC `inv(k - (h:real^M->real) z)` o
5105 MATCH_MP SPAN_MUL) THEN
5106 ASM_SIMP_TAC[REAL_MUL_LINV; VECTOR_MUL_ASSOC; REAL_SUB_0] THEN
5107 ASM_REWRITE_TAC[VECTOR_MUL_LID];
5109 REWRITE_TAC[TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN
5110 REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN
5111 GEN_REWRITE_TAC LAND_CONV [FORALL_AND_THM] THEN STRIP_TAC THEN
5112 EXISTS_TAC `\z:real^M. h(z) % (f:real^M->real^N)(a) + g(z - h(z) % a)` THEN
5113 REPEAT CONJ_TAC THENL
5114 [MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN
5115 SUBGOAL_THEN `(h:real^M->real)(x + y) = h(x) + h(y)` ASSUME_TAC THENL
5116 [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
5117 REWRITE_TAC[VECTOR_ARITH
5118 `(x + y) - (k + l) % a = (x - k % a) + (y - l % a)`] THEN
5119 CONJ_TAC THEN MATCH_MP_TAC SPAN_ADD THEN ASM_REWRITE_TAC[] THEN
5122 ASM_REWRITE_TAC[VECTOR_ARITH
5123 `(x + y) - (k + l) % a = (x - k % a) + (y - l % a)`] THEN
5124 ASM_SIMP_TAC[] THEN VECTOR_ARITH_TAC;
5125 MAP_EVERY X_GEN_TAC [`x:real^M`; `c:real`] THEN STRIP_TAC THEN
5126 SUBGOAL_THEN `(h:real^M->real)(c % x) = c * h(x)` ASSUME_TAC THENL
5127 [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
5128 REWRITE_TAC[VECTOR_ARITH
5129 `c % x - (c * k) % a = c % (x - k % a)`] THEN
5130 CONJ_TAC THEN MATCH_MP_TAC SPAN_MUL THEN ASM_REWRITE_TAC[] THEN
5133 ASM_REWRITE_TAC[VECTOR_ARITH
5134 `c % x - (c * k) % a = c % (x - k % a)`] THEN
5135 ASM_SIMP_TAC[] THEN VECTOR_ARITH_TAC;
5137 X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_INSERT] THEN
5138 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL
5139 [SUBGOAL_THEN `&1 = h(a:real^M)` (SUBST1_TAC o SYM) THENL
5140 [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN
5141 REWRITE_TAC[VECTOR_ARITH `a - &1 % a = vec 0`; SPAN_0] THENL
5142 [ASM_MESON_TAC[SPAN_SUPERSET; SUBSET; IN_INSERT]; ALL_TAC] THEN
5143 FIRST_X_ASSUM(MP_TAC o SPECL [`vec 0:real^M`; `vec 0:real^M`]) THEN
5144 REWRITE_TAC[SPAN_0; VECTOR_ADD_LID] THEN
5145 REWRITE_TAC[VECTOR_ARITH `(a = a + a) <=> (a = vec 0)`] THEN
5146 DISCH_THEN SUBST1_TAC THEN VECTOR_ARITH_TAC;
5148 SUBGOAL_THEN `&0 = h(x:real^M)` (SUBST1_TAC o SYM) THENL
5149 [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN
5150 REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LZERO; VECTOR_SUB_RZERO] THEN
5151 ASM_MESON_TAC[SUBSET; IN_INSERT; SPAN_SUPERSET]);;
5153 let LINEAR_INDEPENDENT_EXTEND = prove
5154 (`!f b. independent b
5155 ==> ?g:real^M->real^N. linear g /\ (!x. x IN b ==> (g x = f x))`,
5156 REPEAT STRIP_TAC THEN
5157 MP_TAC(ISPECL [`b:real^M->bool`; `(:real^M)`]
5158 MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
5159 ASM_REWRITE_TAC[SUBSET_UNIV; UNIV_SUBSET] THEN
5160 REWRITE_TAC[EXTENSION; IN_UNIV] THEN
5161 DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN
5162 MP_TAC(ISPECL [`f:real^M->real^N`; `c:real^M->bool`]
5163 LINEAR_INDEPENDENT_EXTEND_LEMMA) THEN
5164 ASM_SIMP_TAC[INDEPENDENT_BOUND; linear] THEN
5165 ASM_MESON_TAC[SUBSET]);;
5167 (* ------------------------------------------------------------------------- *)
5168 (* Linear functions are equal on a subspace if they are on a spanning set. *)
5169 (* ------------------------------------------------------------------------- *)
5171 let SUBSPACE_KERNEL = prove
5172 (`!f. linear f ==> subspace {x | f(x) = vec 0}`,
5173 REWRITE_TAC[subspace; IN_ELIM_THM] THEN
5174 SIMP_TAC[LINEAR_ADD; LINEAR_CMUL; VECTOR_ADD_LID; VECTOR_MUL_RZERO] THEN
5175 MESON_TAC[LINEAR_0]);;
5177 let LINEAR_EQ_0_SPAN = prove
5178 (`!f:real^M->real^N b.
5179 linear f /\ (!x. x IN b ==> f(x) = vec 0)
5180 ==> !x. x IN span(b) ==> f(x) = vec 0`,
5181 REPEAT GEN_TAC THEN STRIP_TAC THEN
5182 RULE_ASSUM_TAC(REWRITE_RULE[IN]) THEN
5183 MATCH_MP_TAC SPAN_INDUCT THEN ASM_REWRITE_TAC[IN] THEN
5184 MP_TAC(ISPEC `f:real^M->real^N` SUBSPACE_KERNEL) THEN
5185 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN
5186 AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM]);;
5188 let LINEAR_EQ_0 = prove
5189 (`!f b s. linear f /\ s SUBSET (span b) /\ (!x. x IN b ==> f(x) = vec 0)
5190 ==> !x. x IN s ==> f(x) = vec 0`,
5191 MESON_TAC[LINEAR_EQ_0_SPAN; SUBSET]);;
5193 let LINEAR_EQ = prove
5194 (`!f g b s. linear f /\ linear g /\ s SUBSET (span b) /\
5195 (!x. x IN b ==> f(x) = g(x))
5196 ==> !x. x IN s ==> f(x) = g(x)`,
5197 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
5198 STRIP_TAC THEN MATCH_MP_TAC LINEAR_EQ_0 THEN
5199 ASM_MESON_TAC[LINEAR_COMPOSE_SUB]);;
5201 let LINEAR_EQ_STDBASIS = prove
5202 (`!f:real^M->real^N g.
5203 linear f /\ linear g /\
5204 (!i. 1 <= i /\ i <= dimindex(:M)
5205 ==> f(basis i) = g(basis i))
5207 REPEAT STRIP_TAC THEN
5208 SUBGOAL_THEN `!x. x IN UNIV ==> (f:real^M->real^N) x = g x`
5209 (fun th -> MP_TAC th THEN REWRITE_TAC[FUN_EQ_THM; IN_UNIV]) THEN
5210 MATCH_MP_TAC LINEAR_EQ THEN
5211 EXISTS_TAC `{basis i :real^M | 1 <= i /\ i <= dimindex(:M)}` THEN
5212 ASM_REWRITE_TAC[SPAN_STDBASIS; SUBSET_REFL; IN_ELIM_THM] THEN
5215 let SUBSPACE_LINEAR_FIXED_POINTS = prove
5216 (`!f:real^N->real^N. linear f ==> subspace {x | f(x) = x}`,
5217 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
5218 MATCH_MP_TAC SUBSPACE_KERNEL THEN
5219 ASM_SIMP_TAC[LINEAR_COMPOSE_SUB; LINEAR_ID]);;
5221 (* ------------------------------------------------------------------------- *)
5222 (* Similar results for bilinear functions. *)
5223 (* ------------------------------------------------------------------------- *)
5225 let BILINEAR_EQ = prove
5226 (`!f:real^M->real^N->real^P g b c s.
5227 bilinear f /\ bilinear g /\
5228 s SUBSET (span b) /\ t SUBSET (span c) /\
5229 (!x y. x IN b /\ y IN c ==> f x y = g x y)
5230 ==> !x y. x IN s /\ y IN t ==> f x y = g x y`,
5231 REPEAT STRIP_TAC THEN SUBGOAL_THEN
5232 `!x:real^M. x IN span b
5233 ==> !y:real^N. y IN span c ==> (f x y :real^P = g x y)`
5234 (fun th -> ASM_MESON_TAC[th; SUBSET]) THEN
5235 MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[subspace; IN_ELIM_THM] THEN
5237 [GEN_TAC THEN DISCH_TAC;
5238 ASM_SIMP_TAC[BILINEAR_LADD; BILINEAR_LMUL] THEN
5239 ASM_MESON_TAC[BILINEAR_LZERO]] THEN
5240 MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[subspace; IN_ELIM_THM] THEN
5241 ASM_SIMP_TAC[BILINEAR_RADD; BILINEAR_RMUL] THEN
5242 ASM_MESON_TAC[BILINEAR_RZERO]);;
5244 let BILINEAR_EQ_STDBASIS = prove
5245 (`!f:real^M->real^N->real^P g.
5246 bilinear f /\ bilinear g /\
5247 (!i j. 1 <= i /\ i <= dimindex(:M) /\ 1 <= j /\ j <= dimindex(:N)
5248 ==> f (basis i) (basis j) = g (basis i) (basis j))
5250 REPEAT STRIP_TAC THEN SUBGOAL_THEN
5251 `!x y. x IN UNIV /\ y IN UNIV ==> (f:real^M->real^N->real^P) x y = g x y`
5252 (fun th -> MP_TAC th THEN REWRITE_TAC[FUN_EQ_THM; IN_UNIV]) THEN
5253 MATCH_MP_TAC BILINEAR_EQ THEN
5254 EXISTS_TAC `{basis i :real^M | 1 <= i /\ i <= dimindex(:M)}` THEN
5255 EXISTS_TAC `{basis i :real^N | 1 <= i /\ i <= dimindex(:N)}` THEN
5256 ASM_REWRITE_TAC[SPAN_STDBASIS; SUBSET_REFL; IN_ELIM_THM] THEN
5259 (* ------------------------------------------------------------------------- *)
5260 (* Detailed theorems about left and right invertibility in general case. *)
5261 (* ------------------------------------------------------------------------- *)
5263 let LEFT_INVERTIBLE_TRANSP = prove
5265 (?B:real^N^M. B ** transp A = mat 1) <=> (?B:real^M^N. A ** B = mat 1)`,
5266 MESON_TAC[MATRIX_TRANSP_MUL; TRANSP_MAT; TRANSP_TRANSP]);;
5268 let RIGHT_INVERTIBLE_TRANSP = prove
5270 (?B:real^N^M. transp A ** B = mat 1) <=> (?B:real^M^N. B ** A = mat 1)`,
5271 MESON_TAC[MATRIX_TRANSP_MUL; TRANSP_MAT; TRANSP_TRANSP]);;
5273 let INVERTIBLE_TRANSP = prove
5274 (`!A:real^N^M. invertible(transp A) <=> invertible A`,
5275 GEN_TAC THEN REWRITE_TAC[invertible] THEN
5276 GEN_REWRITE_TAC LAND_CONV [MESON[TRANSP_TRANSP]
5277 `(?A:real^M^N. P A) <=> (?A:real^N^M. P(transp A))`] THEN
5278 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM TRANSP_MAT] THEN
5279 REWRITE_TAC[GSYM MATRIX_TRANSP_MUL; TRANSP_EQ] THEN MESON_TAC[]);;
5281 let LINEAR_INJECTIVE_LEFT_INVERSE = prove
5282 (`!f:real^M->real^N.
5283 linear f /\ (!x y. f x = f y ==> x = y)
5284 ==> ?g. linear g /\ g o f = I`,
5285 REWRITE_TAC[INJECTIVE_LEFT_INVERSE] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN
5286 `?h. linear(h:real^N->real^M) /\
5287 !x. x IN IMAGE (f:real^M->real^N)
5288 {basis i | 1 <= i /\ i <= dimindex(:M)} ==> h x = g x`
5290 [MATCH_MP_TAC LINEAR_INDEPENDENT_EXTEND THEN
5291 MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE THEN
5292 ASM_MESON_TAC[INJECTIVE_LEFT_INVERSE; INDEPENDENT_STDBASIS];
5293 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^N->real^M` THEN
5294 ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN STRIP_TAC THEN
5295 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LINEAR_EQ_STDBASIS THEN
5296 ASM_SIMP_TAC[I_DEF; LINEAR_COMPOSE; LINEAR_ID; o_THM] THEN
5299 let LINEAR_SURJECTIVE_RIGHT_INVERSE = prove
5300 (`!f:real^M->real^N.
5301 linear f /\ (!y. ?x. f x = y) ==> ?g. linear g /\ f o g = I`,
5302 REWRITE_TAC[SURJECTIVE_RIGHT_INVERSE] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN
5303 `?h. linear(h:real^N->real^M) /\
5304 !x. x IN {basis i | 1 <= i /\ i <= dimindex(:N)} ==> h x = g x`
5306 [MATCH_MP_TAC LINEAR_INDEPENDENT_EXTEND THEN
5307 REWRITE_TAC[INDEPENDENT_STDBASIS];
5308 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^N->real^M` THEN
5309 ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN STRIP_TAC THEN
5310 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LINEAR_EQ_STDBASIS THEN
5311 ASM_SIMP_TAC[I_DEF; LINEAR_COMPOSE; LINEAR_ID; o_THM] THEN
5314 let MATRIX_LEFT_INVERTIBLE_INJECTIVE = prove
5316 (?B:real^M^N. B ** A = mat 1) <=>
5317 !x y:real^N. A ** x = A ** y ==> x = y`,
5318 GEN_TAC THEN EQ_TAC THENL
5319 [STRIP_TAC THEN REPEAT GEN_TAC THEN
5320 DISCH_THEN(MP_TAC o AP_TERM `\x:real^M. (B:real^M^N) ** x`) THEN
5321 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID];
5322 DISCH_TAC THEN MP_TAC(ISPEC
5323 `\x:real^N. (A:real^N^M) ** x` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
5324 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; FUN_EQ_THM; I_THM; o_THM] THEN
5325 DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN
5326 EXISTS_TAC `matrix(g):real^M^N` THEN
5327 REWRITE_TAC[MATRIX_EQ; MATRIX_VECTOR_MUL_LID] THEN
5328 ASM_MESON_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_WORKS]]);;
5330 let MATRIX_LEFT_INVERTIBLE_KER = prove
5332 (?B:real^M^N. B ** A = mat 1) <=> !x. A ** x = vec 0 ==> x = vec 0`,
5333 GEN_TAC THEN REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_INJECTIVE] THEN
5334 MATCH_MP_TAC LINEAR_INJECTIVE_0 THEN REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);;
5336 let MATRIX_RIGHT_INVERTIBLE_SURJECTIVE = prove
5338 (?B:real^M^N. A ** B = mat 1) <=> !y. ?x. A ** x = y`,
5339 GEN_TAC THEN EQ_TAC THENL
5340 [STRIP_TAC THEN X_GEN_TAC `y:real^M` THEN
5341 EXISTS_TAC `(B:real^M^N) ** (y:real^M)` THEN
5342 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID];
5343 DISCH_TAC THEN MP_TAC(ISPEC
5344 `\x:real^N. (A:real^N^M) ** x` LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN
5345 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; FUN_EQ_THM; I_THM; o_THM] THEN
5346 DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN
5347 EXISTS_TAC `matrix(g):real^M^N` THEN
5348 REWRITE_TAC[MATRIX_EQ; MATRIX_VECTOR_MUL_LID] THEN
5349 ASM_MESON_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_WORKS]]);;
5351 let MATRIX_LEFT_INVERTIBLE_INDEPENDENT_COLUMNS = prove
5352 (`!A:real^N^M. (?B:real^M^N. B ** A = mat 1) <=>
5353 !c. vsum(1..dimindex(:N)) (\i. c(i) % column i A) = vec 0 ==>
5354 !i. 1 <= i /\ i <= dimindex(:N) ==> c(i) = &0`,
5355 GEN_TAC THEN REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_KER; MATRIX_MUL_VSUM] THEN
5356 EQ_TAC THEN DISCH_TAC THENL
5357 [X_GEN_TAC `c:num->real` THEN DISCH_TAC THEN
5358 FIRST_X_ASSUM(MP_TAC o SPEC `(lambda i. c(i)):real^N`);
5359 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
5360 FIRST_X_ASSUM(MP_TAC o SPEC `\i. (x:real^N)$i`)] THEN
5361 ASM_SIMP_TAC[LAMBDA_BETA; CART_EQ; VEC_COMPONENT]);;
5363 let MATRIX_RIGHT_INVERTIBLE_INDEPENDENT_ROWS = prove
5364 (`!A:real^N^M. (?B:real^M^N. A ** B = mat 1) <=>
5365 !c. vsum(1..dimindex(:M)) (\i. c(i) % row i A) = vec 0 ==>
5366 !i. 1 <= i /\ i <= dimindex(:M) ==> c(i) = &0`,
5367 ONCE_REWRITE_TAC[GSYM LEFT_INVERTIBLE_TRANSP] THEN
5368 REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_INDEPENDENT_COLUMNS] THEN
5369 SIMP_TAC[COLUMN_TRANSP]);;
5371 let MATRIX_RIGHT_INVERTIBLE_SPAN_COLUMNS = prove
5372 (`!A:real^N^M. (?B:real^M^N. A ** B = mat 1) <=> span(columns A) = (:real^M)`,
5373 GEN_TAC THEN REWRITE_TAC[MATRIX_RIGHT_INVERTIBLE_SURJECTIVE] THEN
5374 REWRITE_TAC[MATRIX_MUL_VSUM; EXTENSION; IN_UNIV] THEN
5375 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `y:real^M` THEN
5377 [DISCH_THEN(X_CHOOSE_THEN `x:real^N` (SUBST1_TAC o SYM)) THEN
5378 MATCH_MP_TAC SPAN_VSUM THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
5379 X_GEN_TAC `i:num` THEN STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
5380 MATCH_MP_TAC(CONJUNCT1 SPAN_CLAUSES) THEN
5381 REWRITE_TAC[columns; IN_ELIM_THM] THEN ASM_MESON_TAC[];
5383 SPEC_TAC(`y:real^M`,`y:real^M`) THEN MATCH_MP_TAC SPAN_INDUCT_ALT THEN
5385 [EXISTS_TAC `vec 0 :real^N` THEN
5386 SIMP_TAC[VEC_COMPONENT; VECTOR_MUL_LZERO; VSUM_0];
5388 MAP_EVERY X_GEN_TAC [`c:real`; `y1:real^M`; `y2:real^M`] THEN
5389 REWRITE_TAC[columns; IN_ELIM_THM] THEN DISCH_THEN(CONJUNCTS_THEN2
5390 (X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC)
5391 (X_CHOOSE_THEN `x:real^N` (SUBST1_TAC o SYM))) THEN
5392 EXISTS_TAC `(lambda j. if j = i then c + (x:real^N)$i else x$j):real^N` THEN
5393 SUBGOAL_THEN `1..dimindex(:N) = i INSERT ((1..dimindex(:N)) DELETE i)`
5394 SUBST1_TAC THENL [ASM_MESON_TAC[INSERT_DELETE; IN_NUMSEG]; ALL_TAC] THEN
5395 SIMP_TAC[VSUM_CLAUSES; FINITE_DELETE; FINITE_NUMSEG; IN_DELETE] THEN
5396 ASM_SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_RDISTRIB; VECTOR_ADD_ASSOC] THEN
5397 AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
5398 SIMP_TAC[FINITE_DELETE; IN_DELETE; FINITE_NUMSEG; LAMBDA_BETA; IN_NUMSEG]);;
5400 let MATRIX_LEFT_INVERTIBLE_SPAN_ROWS = prove
5401 (`!A:real^N^M. (?B:real^M^N. B ** A = mat 1) <=> span(rows A) = (:real^N)`,
5402 MESON_TAC[RIGHT_INVERTIBLE_TRANSP; COLUMNS_TRANSP;
5403 MATRIX_RIGHT_INVERTIBLE_SPAN_COLUMNS]);;
5405 (* ------------------------------------------------------------------------- *)
5406 (* An injective map real^N->real^N is also surjective. *)
5407 (* ------------------------------------------------------------------------- *)
5409 let LINEAR_INJECTIVE_IMP_SURJECTIVE = prove
5410 (`!f:real^N->real^N.
5411 linear f /\ (!x y. (f(x) = f(y)) ==> (x = y))
5412 ==> !y. ?x. f(x) = y`,
5413 REPEAT STRIP_TAC THEN
5414 MP_TAC(ISPEC `(:real^N)` BASIS_EXISTS) THEN
5415 REWRITE_TAC[SUBSET_UNIV; HAS_SIZE] THEN
5416 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
5417 SUBGOAL_THEN `UNIV SUBSET span(IMAGE (f:real^N->real^N) b)` MP_TAC THENL
5418 [MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN
5419 ASM_MESON_TAC[INDEPENDENT_INJECTIVE_IMAGE; LE_REFL;
5420 SUBSET_UNIV; CARD_IMAGE_INJ];
5421 ASM_SIMP_TAC[SPAN_LINEAR_IMAGE] THEN
5422 ASM_MESON_TAC[SUBSET; IN_IMAGE; IN_UNIV]]);;
5424 (* ------------------------------------------------------------------------- *)
5425 (* And vice versa. *)
5426 (* ------------------------------------------------------------------------- *)
5428 let LINEAR_SURJECTIVE_IMP_INJECTIVE = prove
5429 (`!f:real^N->real^N.
5430 linear f /\ (!y. ?x. f(x) = y)
5431 ==> !x y. (f(x) = f(y)) ==> (x = y)`,
5432 REPEAT GEN_TAC THEN STRIP_TAC THEN
5433 MP_TAC(ISPEC `(:real^N)` BASIS_EXISTS) THEN
5434 REWRITE_TAC[SUBSET_UNIV; HAS_SIZE] THEN
5435 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
5437 `!x. x IN span b ==> (f:real^N->real^N) x = vec 0 ==> x = vec 0`
5438 (fun th -> ASM_MESON_TAC[th; LINEAR_INJECTIVE_0; SUBSET; IN_UNIV]) THEN
5439 MATCH_MP_TAC LINEAR_INDEP_IMAGE_LEMMA THEN
5440 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
5441 [MATCH_MP_TAC CARD_LE_DIM_SPANNING THEN
5442 EXISTS_TAC `(:real^N)` THEN
5443 ASM_SIMP_TAC[SUBSET_UNIV; FINITE_IMAGE; SPAN_LINEAR_IMAGE] THEN
5444 REWRITE_TAC[SUBSET; IN_UNIV; IN_IMAGE] THEN
5445 ASM_MESON_TAC[CARD_IMAGE_LE; SUBSET; IN_UNIV];
5447 SUBGOAL_THEN `dim(:real^N) <= CARD(IMAGE (f:real^N->real^N) b)`
5449 [MATCH_MP_TAC SPAN_CARD_GE_DIM THEN
5450 ASM_SIMP_TAC[SUBSET_UNIV; FINITE_IMAGE] THEN
5451 ASM_SIMP_TAC[SPAN_LINEAR_IMAGE] THEN MATCH_MP_TAC SUBSET_TRANS THEN
5452 EXISTS_TAC `IMAGE (f:real^N->real^N) UNIV` THEN
5453 ASM_SIMP_TAC[IMAGE_SUBSET] THEN
5454 ASM_REWRITE_TAC[SUBSET; IN_IMAGE; IN_UNIV] THEN ASM_MESON_TAC[];
5456 FIRST_X_ASSUM(MP_TAC o ISPEC `f:real^N->real^N` o
5457 MATCH_MP CARD_IMAGE_LE) THEN
5458 ASM_REWRITE_TAC[IMP_IMP; LE_ANTISYM] THEN DISCH_TAC THEN
5460 [`b:real^N->bool`; `IMAGE (f:real^N->real^N) b`; `f:real^N->real^N`]
5461 SURJECTIVE_IFF_INJECTIVE_GEN) THEN
5462 ASM_SIMP_TAC[FINITE_IMAGE; INDEPENDENT_BOUND; SUBSET_REFL] THEN
5463 REWRITE_TAC[FORALL_IN_IMAGE] THEN MESON_TAC[]);;
5465 let LINEAR_SURJECTIVE_IFF_INJECTIVE = prove
5466 (`!f:real^N->real^N.
5467 linear f ==> ((!y. ?x. f x = y) <=> (!x y. f x = f y ==> x = y))`,
5468 MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE;
5469 LINEAR_SURJECTIVE_IMP_INJECTIVE]);;
5471 (* ------------------------------------------------------------------------- *)
5472 (* Hence either is enough for isomorphism. *)
5473 (* ------------------------------------------------------------------------- *)
5475 let LEFT_RIGHT_INVERSE_EQ = prove
5476 (`!f:A->A g h. f o g = I /\ g o h = I ==> f = h`,
5477 MESON_TAC[o_ASSOC; I_O_ID]);;
5479 let ISOMORPHISM_EXPAND = prove
5480 (`!f g. f o g = I /\ g o f = I <=> (!x. f(g x) = x) /\ (!x. g(f x) = x)`,
5481 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM]);;
5483 let LINEAR_INJECTIVE_ISOMORPHISM = prove
5484 (`!f:real^N->real^N.
5485 linear f /\ (!x y. f x = f y ==> x = y)
5486 ==> ?f'. linear f' /\ (!x. f'(f x) = x) /\ (!x. f(f' x) = x)`,
5487 REPEAT STRIP_TAC THEN
5488 REWRITE_TAC[GSYM ISOMORPHISM_EXPAND] THEN
5489 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN
5490 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
5491 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_IMP_SURJECTIVE) THEN
5492 ASM_REWRITE_TAC[] THEN SIMP_TAC[] THEN MESON_TAC[LEFT_RIGHT_INVERSE_EQ]);;
5494 let LINEAR_SURJECTIVE_ISOMORPHISM = prove
5495 (`!f:real^N->real^N.
5496 linear f /\ (!y. ?x. f x = y)
5497 ==> ?f'. linear f' /\ (!x. f'(f x) = x) /\ (!x. f(f' x) = x)`,
5498 REPEAT STRIP_TAC THEN
5499 REWRITE_TAC[GSYM ISOMORPHISM_EXPAND] THEN
5500 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN
5501 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
5502 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_IMP_INJECTIVE) THEN
5503 ASM_REWRITE_TAC[] THEN SIMP_TAC[] THEN MESON_TAC[LEFT_RIGHT_INVERSE_EQ]);;
5505 (* ------------------------------------------------------------------------- *)
5506 (* Left and right inverses are the same for R^N->R^N. *)
5507 (* ------------------------------------------------------------------------- *)
5509 let LINEAR_INVERSE_LEFT = prove
5510 (`!f:real^N->real^N f'.
5511 linear f /\ linear f' ==> ((f o f' = I) <=> (f' o f = I))`,
5513 `!f:real^N->real^N f'.
5514 linear f /\ linear f' /\ (f o f' = I) ==> (f' o f = I)`
5515 (fun th -> MESON_TAC[th]) THEN
5516 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN REPEAT STRIP_TAC THEN
5517 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_ISOMORPHISM) THEN
5520 (* ------------------------------------------------------------------------- *)
5521 (* Moreover, a one-sided inverse is automatically linear. *)
5522 (* ------------------------------------------------------------------------- *)
5524 let LEFT_INVERSE_LINEAR = prove
5525 (`!f g:real^N->real^N. linear f /\ (g o f = I) ==> linear g`,
5526 REPEAT GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN
5527 STRIP_TAC THEN SUBGOAL_THEN
5528 `?h:real^N->real^N. linear h /\ (!x. h(f x) = x) /\ (!x. f(h x) = x)`
5530 [MATCH_MP_TAC LINEAR_INJECTIVE_ISOMORPHISM THEN ASM_MESON_TAC[];
5531 SUBGOAL_THEN `g:real^N->real^N = h` (fun th -> ASM_REWRITE_TAC[th]) THEN
5532 REWRITE_TAC[FUN_EQ_THM] THEN ASM_MESON_TAC[]]);;
5534 let RIGHT_INVERSE_LINEAR = prove
5535 (`!f g:real^N->real^N. linear f /\ (f o g = I) ==> linear g`,
5536 REPEAT GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN
5537 STRIP_TAC THEN SUBGOAL_THEN
5538 `?h:real^N->real^N. linear h /\ (!x. h(f x) = x) /\ (!x. f(h x) = x)`
5539 CHOOSE_TAC THENL [ASM_MESON_TAC[LINEAR_SURJECTIVE_ISOMORPHISM]; ALL_TAC] THEN
5540 SUBGOAL_THEN `g:real^N->real^N = h` (fun th -> ASM_REWRITE_TAC[th]) THEN
5541 REWRITE_TAC[FUN_EQ_THM] THEN ASM_MESON_TAC[]);;
5543 (* ------------------------------------------------------------------------- *)
5544 (* Without (ostensible) constraints on types, though dimensions must match. *)
5545 (* ------------------------------------------------------------------------- *)
5547 let LEFT_RIGHT_INVERSE_LINEAR = prove
5548 (`!f g:real^M->real^N.
5549 linear f /\ g o f = I /\ f o g = I ==> linear g`,
5550 REWRITE_TAC[linear; FUN_EQ_THM; o_THM; I_THM] THEN MESON_TAC[]);;
5552 let LINEAR_BIJECTIVE_LEFT_RIGHT_INVERSE = prove
5553 (`!f:real^M->real^N.
5554 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
5555 ==> ?g. linear g /\ (!x. g(f x) = x) /\ (!y. f(g y) = y)`,
5556 GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
5557 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BIJECTIVE_LEFT_RIGHT_INVERSE]) THEN
5558 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
5559 MATCH_MP_TAC LEFT_RIGHT_INVERSE_LINEAR THEN
5560 EXISTS_TAC `f:real^M->real^N` THEN
5561 ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM]);;
5563 (* ------------------------------------------------------------------------- *)
5564 (* The same result in terms of square matrices. *)
5565 (* ------------------------------------------------------------------------- *)
5567 let MATRIX_LEFT_RIGHT_INVERSE = prove
5568 (`!A:real^N^N A':real^N^N. (A ** A' = mat 1) <=> (A' ** A = mat 1)`,
5570 `!A:real^N^N A':real^N^N. (A ** A' = mat 1) ==> (A' ** A = mat 1)`
5571 (fun th -> MESON_TAC[th]) THEN
5572 REPEAT STRIP_TAC THEN
5573 MP_TAC(ISPEC `\x:real^N. A:(real^N^N) ** x`
5574 LINEAR_SURJECTIVE_ISOMORPHISM) THEN
5575 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN ANTS_TAC THENL
5576 [X_GEN_TAC `x:real^N` THEN EXISTS_TAC `(A':real^N^N) ** (x:real^N)` THEN
5577 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID];
5579 DISCH_THEN(X_CHOOSE_THEN `f':real^N->real^N` STRIP_ASSUME_TAC) THEN
5580 SUBGOAL_THEN `matrix (f':real^N->real^N) ** (A:real^N^N) = mat 1`
5582 [ASM_SIMP_TAC[MATRIX_EQ; MATRIX_WORKS; GSYM MATRIX_VECTOR_MUL_ASSOC;
5583 MATRIX_VECTOR_MUL_LID];
5585 DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
5586 DISCH_THEN(MP_TAC o AP_TERM `(\m:real^N^N. m ** (A':real^N^N))`) THEN
5587 REWRITE_TAC[GSYM MATRIX_MUL_ASSOC] THEN
5588 ASM_REWRITE_TAC[MATRIX_MUL_RID; MATRIX_MUL_LID] THEN ASM_MESON_TAC[]);;
5590 (* ------------------------------------------------------------------------- *)
5591 (* Invertibility of matrices and corresponding linear functions. *)
5592 (* ------------------------------------------------------------------------- *)
5594 let MATRIX_LEFT_INVERTIBLE = prove
5595 (`!f:real^M->real^N.
5596 linear f ==> ((?B:real^N^M. B ** matrix f = mat 1) <=>
5597 (?g. linear g /\ g o f = I))`,
5598 GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN STRIP_TAC THENL
5599 [EXISTS_TAC `\y:real^N. (B:real^N^M) ** y` THEN
5600 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN
5601 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV)
5602 [MATCH_MP MATRIX_VECTOR_MUL th]) THEN
5603 ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; MATRIX_VECTOR_MUL_ASSOC;
5604 MATRIX_VECTOR_MUL_LID];
5605 EXISTS_TAC `matrix(g:real^N->real^M)` THEN
5606 ASM_SIMP_TAC[GSYM MATRIX_COMPOSE; MATRIX_I]]);;
5608 let MATRIX_RIGHT_INVERTIBLE = prove
5609 (`!f:real^M->real^N.
5610 linear f ==> ((?B:real^N^M. matrix f ** B = mat 1) <=>
5611 (?g. linear g /\ f o g = I))`,
5612 GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN STRIP_TAC THENL
5613 [EXISTS_TAC `\y:real^N. (B:real^N^M) ** y` THEN
5614 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN
5615 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV)
5616 [MATCH_MP MATRIX_VECTOR_MUL th]) THEN
5617 ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; MATRIX_VECTOR_MUL_ASSOC;
5618 MATRIX_VECTOR_MUL_LID];
5619 EXISTS_TAC `matrix(g:real^N->real^M)` THEN
5620 ASM_SIMP_TAC[GSYM MATRIX_COMPOSE; MATRIX_I]]);;
5622 let INVERTIBLE_LEFT_INVERSE = prove
5623 (`!A:real^N^N. invertible(A) <=> ?B:real^N^N. B ** A = mat 1`,
5624 MESON_TAC[invertible; MATRIX_LEFT_RIGHT_INVERSE]);;
5626 let INVERTIBLE_RIGHT_INVERSE = prove
5627 (`!A:real^N^N. invertible(A) <=> ?B:real^N^N. A ** B = mat 1`,
5628 MESON_TAC[invertible; MATRIX_LEFT_RIGHT_INVERSE]);;
5630 let MATRIX_INVERTIBLE = prove
5631 (`!f:real^N->real^N.
5633 ==> (invertible(matrix f) <=>
5634 ?g. linear g /\ f o g = I /\ g o f = I)`,
5635 SIMP_TAC[INVERTIBLE_LEFT_INVERSE; MATRIX_LEFT_INVERTIBLE] THEN
5636 MESON_TAC[LINEAR_INVERSE_LEFT]);;
5638 let MATRIX_INV_UNIQUE_LEFT = prove
5639 (`!A:real^N^N B. A ** B = mat 1 ==> matrix_inv B = A`,
5640 REPEAT STRIP_TAC THEN MATCH_MP_TAC MATRIX_INV_UNIQUE THEN
5641 ASM_MESON_TAC[MATRIX_LEFT_RIGHT_INVERSE]);;
5643 let MATRIX_INV_UNIQUE_RIGHT = prove
5644 (`!A:real^N^N B. A ** B = mat 1 ==> matrix_inv A = B`,
5645 REPEAT STRIP_TAC THEN MATCH_MP_TAC MATRIX_INV_UNIQUE THEN
5646 ASM_MESON_TAC[MATRIX_LEFT_RIGHT_INVERSE]);;
5648 (* ------------------------------------------------------------------------- *)
5649 (* Left-invertible linear transformation has a lower bound. *)
5650 (* ------------------------------------------------------------------------- *)
5652 let LINEAR_INVERTIBLE_BOUNDED_BELOW_POS = prove
5653 (`!f:real^M->real^N g.
5654 linear f /\ linear g /\ (g o f = I)
5655 ==> ?B. &0 < B /\ !x. B * norm(x) <= norm(f x)`,
5656 REPEAT STRIP_TAC THEN
5657 MP_TAC(ISPEC `g:real^N->real^M` LINEAR_BOUNDED_POS) THEN
5658 ASM_REWRITE_TAC[] THEN
5659 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
5660 EXISTS_TAC `inv B:real` THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN
5661 X_GEN_TAC `x:real^M` THEN MATCH_MP_TAC REAL_LE_TRANS THEN
5662 EXISTS_TAC `inv(B) * norm(((g:real^N->real^M) o (f:real^M->real^N)) x)` THEN
5663 CONJ_TAC THENL [ASM_SIMP_TAC[I_THM; REAL_LE_REFL]; ALL_TAC] THEN
5664 REWRITE_TAC[REAL_ARITH `inv B * x = x / B`] THEN
5665 ASM_SIMP_TAC[o_THM; REAL_LE_LDIV_EQ] THEN
5666 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_REWRITE_TAC[]);;
5668 let LINEAR_INVERTIBLE_BOUNDED_BELOW = prove
5669 (`!f:real^M->real^N g.
5670 linear f /\ linear g /\ (g o f = I)
5671 ==> ?B. !x. B * norm(x) <= norm(f x)`,
5672 MESON_TAC[LINEAR_INVERTIBLE_BOUNDED_BELOW_POS]);;
5674 let LINEAR_INJECTIVE_BOUNDED_BELOW_POS = prove
5675 (`!f:real^M->real^N.
5676 linear f /\ (!x y. f x = f y ==> x = y)
5677 ==> ?B. &0 < B /\ !x. norm(x) * B <= norm(f x)`,
5678 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
5679 MATCH_MP_TAC LINEAR_INVERTIBLE_BOUNDED_BELOW_POS THEN
5680 ASM_MESON_TAC[LINEAR_INJECTIVE_LEFT_INVERSE]);;
5682 (* ------------------------------------------------------------------------- *)
5683 (* Preservation of dimension by injective map. *)
5684 (* ------------------------------------------------------------------------- *)
5686 let DIM_INJECTIVE_LINEAR_IMAGE = prove
5687 (`!f:real^M->real^N s.
5688 linear f /\ (!x y. f x = f y ==> x = y) ==> dim(IMAGE f s) = dim s`,
5689 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN
5690 CONJ_TAC THENL [ASM_MESON_TAC[DIM_LINEAR_IMAGE_LE]; ALL_TAC] THEN
5691 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
5692 ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN
5693 DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN
5694 MATCH_MP_TAC LE_TRANS THEN
5695 EXISTS_TAC `dim(IMAGE (g:real^N->real^M) (IMAGE (f:real^M->real^N) s))` THEN
5697 [ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; LE_REFL];
5698 MATCH_MP_TAC DIM_LINEAR_IMAGE_LE THEN ASM_REWRITE_TAC[]]);;
5700 let LINEAR_INJECTIVE_DIMINDEX_LE = prove
5701 (`!f:real^M->real^N.
5702 linear f /\ (!x y. f x = f y ==> x = y)
5703 ==> dimindex(:M) <= dimindex(:N)`,
5704 REWRITE_TAC[GSYM DIM_UNIV] THEN REPEAT GEN_TAC THEN DISCH_THEN
5705 (SUBST1_TAC o SYM o SPEC `(:real^M)` o
5706 MATCH_MP DIM_INJECTIVE_LINEAR_IMAGE) THEN
5707 MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]);;
5709 let LINEAR_SURJECTIVE_DIMINDEX_LE = prove
5710 (`!f:real^M->real^N.
5711 linear f /\ (!y. ?x. f x = y)
5712 ==> dimindex(:N) <= dimindex(:M)`,
5713 REPEAT GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM
5714 (MP_TAC o MATCH_MP LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN
5715 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; LEFT_IMP_EXISTS_THM] THEN
5716 X_GEN_TAC `g:real^N->real^M` THEN STRIP_TAC THEN
5717 MATCH_MP_TAC LINEAR_INJECTIVE_DIMINDEX_LE THEN
5718 EXISTS_TAC `g:real^N->real^M` THEN ASM_MESON_TAC[]);;
5720 let LINEAR_BIJECTIVE_DIMINDEX_EQ = prove
5721 (`!f:real^M->real^N.
5722 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
5723 ==> dimindex(:M) = dimindex(:N)`,
5724 REWRITE_TAC[GSYM LE_ANTISYM] THEN REPEAT STRIP_TAC THENL
5725 [MATCH_MP_TAC LINEAR_INJECTIVE_DIMINDEX_LE;
5726 MATCH_MP_TAC LINEAR_SURJECTIVE_DIMINDEX_LE] THEN
5727 EXISTS_TAC `f:real^M->real^N` THEN ASM_REWRITE_TAC[]);;
5729 let INVERTIBLE_IMP_SQUARE_MATRIX = prove
5730 (`!A:real^N^M. invertible A ==> dimindex(:M) = dimindex(:N)`,
5731 GEN_TAC THEN REWRITE_TAC[invertible; LEFT_IMP_EXISTS_THM] THEN
5732 X_GEN_TAC `B:real^M^N` THEN STRIP_TAC THEN
5733 MATCH_MP_TAC LINEAR_BIJECTIVE_DIMINDEX_EQ THEN
5734 EXISTS_TAC `\x:real^M. (B:real^M^N) ** x` THEN
5735 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR;
5736 GSYM MATRIX_LEFT_INVERTIBLE_INJECTIVE;
5737 GSYM MATRIX_RIGHT_INVERTIBLE_SURJECTIVE] THEN
5740 (* ------------------------------------------------------------------------- *)
5741 (* Considering an n-element vector as an n-by-1 or 1-by-n matrix. *)
5742 (* ------------------------------------------------------------------------- *)
5744 let rowvector = new_definition
5745 `(rowvector:real^N->real^N^1) v = lambda i j. v$j`;;
5747 let columnvector = new_definition
5748 `(columnvector:real^N->real^1^N) v = lambda i j. v$i`;;
5750 let TRANSP_COLUMNVECTOR = prove
5751 (`!v. transp(columnvector v) = rowvector v`,
5752 SIMP_TAC[transp; columnvector; rowvector; CART_EQ; LAMBDA_BETA]);;
5754 let TRANSP_ROWVECTOR = prove
5755 (`!v. transp(rowvector v) = columnvector v`,
5756 SIMP_TAC[transp; columnvector; rowvector; CART_EQ; LAMBDA_BETA]);;
5758 let DOT_ROWVECTOR_COLUMNVECTOR = prove
5759 (`!A:real^N^M v:real^N. columnvector(A ** v) = A ** columnvector v`,
5760 REWRITE_TAC[rowvector; columnvector; matrix_mul; matrix_vector_mul] THEN
5761 SIMP_TAC[CART_EQ; LAMBDA_BETA]);;
5763 let DOT_MATRIX_PRODUCT = prove
5764 (`!x y:real^N. x dot y = (rowvector x ** columnvector y)$1$1`,
5765 REWRITE_TAC[matrix_mul; columnvector; rowvector; dot] THEN
5766 SIMP_TAC[LAMBDA_BETA; DIMINDEX_1; LE_REFL]);;
5768 let DOT_MATRIX_VECTOR_MUL = prove
5769 (`!A:real^N^N B:real^N^N x:real^N y:real^N.
5770 (A ** x) dot (B ** y) =
5771 ((rowvector x) ** (transp(A) ** B) ** (columnvector y))$1$1`,
5772 REWRITE_TAC[DOT_MATRIX_PRODUCT] THEN
5773 ONCE_REWRITE_TAC[GSYM TRANSP_COLUMNVECTOR] THEN
5774 REWRITE_TAC[DOT_ROWVECTOR_COLUMNVECTOR; MATRIX_TRANSP_MUL] THEN
5775 REWRITE_TAC[MATRIX_MUL_ASSOC]);;
5777 (* ------------------------------------------------------------------------- *)
5778 (* Rank of a matrix. Equivalence of row and column rank is taken from *)
5779 (* George Mackiw's paper, Mathematics Magazine 1995, p. 285. *)
5780 (* ------------------------------------------------------------------------- *)
5782 let MATRIX_VECTOR_MUL_IN_COLUMNSPACE = prove
5783 (`!A:real^M^N x:real^M. (A ** x) IN span(columns A)`,
5784 REPEAT GEN_TAC THEN REWRITE_TAC[MATRIX_VECTOR_COLUMN; columns] THEN
5785 MATCH_MP_TAC SPAN_VSUM THEN
5786 SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; transp; LAMBDA_BETA] THEN
5787 X_GEN_TAC `k:num` THEN STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
5788 MATCH_MP_TAC SPAN_SUPERSET THEN
5789 REWRITE_TAC[IN_ELIM_THM; column] THEN EXISTS_TAC `k:num` THEN
5790 ASM_REWRITE_TAC[]);;
5792 let SUBSPACE_ORTHOGONAL_TO_VECTOR = prove
5793 (`!x. subspace {y | orthogonal x y}`,
5794 SIMP_TAC[subspace; IN_ELIM_THM; ORTHOGONAL_CLAUSES]);;
5796 let SUBSPACE_ORTHOGONAL_TO_VECTORS = prove
5797 (`!s. subspace {y | (!x. x IN s ==> orthogonal x y)}`,
5798 SIMP_TAC[subspace; IN_ELIM_THM; ORTHOGONAL_CLAUSES]);;
5800 let ORTHOGONAL_TO_SPAN = prove
5801 (`!s x. (!y. y IN s ==> orthogonal x y)
5802 ==> !y. y IN span(s) ==> orthogonal x y`,
5803 REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN
5804 REWRITE_TAC[SET_RULE `(\y. orthogonal x y) = {y | orthogonal x y}`] THEN
5805 ASM_SIMP_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR; IN_ELIM_THM]);;
5807 let ORTHOGONAL_TO_SPAN_EQ = prove
5808 (`!s x. (!y. y IN span(s) ==> orthogonal x y) <=>
5809 (!y. y IN s ==> orthogonal x y)`,
5810 MESON_TAC[SPAN_SUPERSET; ORTHOGONAL_TO_SPAN]);;
5812 let ORTHOGONAL_TO_SPANS_EQ = prove
5813 (`!s t. (!x y. x IN span(s) /\ y IN span(t) ==> orthogonal x y) <=>
5814 (!x y. x IN s /\ y IN t ==> orthogonal x y)`,
5815 MESON_TAC[ORTHOGONAL_TO_SPAN_EQ; ORTHOGONAL_SYM]);;
5817 let ORTHOGONAL_NULLSPACE_ROWSPACE = prove
5818 (`!A:real^M^N x y:real^M.
5819 A ** x = vec 0 /\ y IN span(rows A) ==> orthogonal x y`,
5820 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
5821 REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN
5822 REWRITE_TAC[SET_RULE `(\y. orthogonal x y) = {y | orthogonal x y}`] THEN
5823 REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR; rows; FORALL_IN_GSPEC] THEN
5824 X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
5825 FIRST_X_ASSUM(MP_TAC o AP_TERM `\y:real^N. y$k`) THEN
5826 ASM_SIMP_TAC[MATRIX_VECTOR_MUL_COMPONENT; VEC_COMPONENT; row; dot;
5827 orthogonal; LAMBDA_BETA] THEN
5828 REWRITE_TAC[REAL_MUL_SYM]);;
5830 let NULLSPACE_INTER_ROWSPACE = prove
5831 (`!A:real^M^N x:real^M. A ** x = vec 0 /\ x IN span(rows A) <=> x = vec 0`,
5832 REPEAT GEN_TAC THEN EQ_TAC THENL
5833 [MESON_TAC[ORTHOGONAL_NULLSPACE_ROWSPACE; ORTHOGONAL_REFL];
5834 SIMP_TAC[MATRIX_VECTOR_MUL_RZERO; SPAN_0]]);;
5836 let MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE = prove
5837 (`!A:real^M^N x y:real^M.
5838 x IN span(rows A) /\ y IN span(rows A) /\ A ** x = A ** y ==> x = y`,
5839 ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
5840 REWRITE_TAC[GSYM MATRIX_VECTOR_MUL_SUB_LDISTRIB] THEN
5841 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM NULLSPACE_INTER_ROWSPACE] THEN
5842 ASM_SIMP_TAC[SPAN_SUB]);;
5844 let DIM_ROWS_LE_DIM_COLUMNS = prove
5845 (`!A:real^M^N. dim(rows A) <= dim(columns A)`,
5846 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
5847 X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC
5848 (ISPEC `span(rows(A:real^M^N))` BASIS_EXISTS) THEN
5849 SUBGOAL_THEN `FINITE(IMAGE (\x:real^M. (A:real^M^N) ** x) b) /\
5850 CARD (IMAGE (\x:real^M. (A:real^M^N) ** x) b) <=
5851 dim(span(columns A))`
5853 [MATCH_MP_TAC INDEPENDENT_CARD_LE_DIM THEN
5854 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; MATRIX_VECTOR_MUL_IN_COLUMNSPACE] THEN
5855 MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN
5856 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN
5857 SUBGOAL_THEN `span(b) = span(rows(A:real^M^N))` SUBST1_TAC THENL
5858 [ALL_TAC; ASM_MESON_TAC[MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE]] THEN
5859 MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN
5860 GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_SPAN] THEN
5861 ASM_SIMP_TAC[SPAN_MONO];
5862 DISCH_THEN(MP_TAC o CONJUNCT2) THEN MATCH_MP_TAC EQ_IMP THEN
5863 AP_THM_TAC THEN AP_TERM_TAC THEN
5864 FIRST_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM) o
5865 GEN_REWRITE_RULE I [HAS_SIZE]) THEN
5866 MATCH_MP_TAC CARD_IMAGE_INJ THEN ASM_REWRITE_TAC[] THEN
5867 REPEAT STRIP_TAC THEN MATCH_MP_TAC
5868 (ISPEC `A:real^M^N` MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE) THEN
5871 let rank = new_definition
5872 `rank(A:real^M^N) = dim(columns A)`;;
5874 let RANK_ROW = prove
5875 (`!A:real^M^N. rank(A) = dim(rows A)`,
5876 GEN_TAC THEN REWRITE_TAC[rank] THEN
5877 MP_TAC(ISPEC `A:real^M^N` DIM_ROWS_LE_DIM_COLUMNS) THEN
5878 MP_TAC(ISPEC `transp(A:real^M^N)` DIM_ROWS_LE_DIM_COLUMNS) THEN
5879 REWRITE_TAC[ROWS_TRANSP; COLUMNS_TRANSP] THEN ARITH_TAC);;
5881 let RANK_TRANSP = prove
5882 (`!A:real^M^N. rank(transp A) = rank A`,
5883 GEN_TAC THEN GEN_REWRITE_TAC RAND_CONV [RANK_ROW] THEN
5884 REWRITE_TAC[rank; COLUMNS_TRANSP]);;
5886 let MATRIX_VECTOR_MUL_BASIS = prove
5887 (`!A:real^M^N k. 1 <= k /\ k <= dimindex(:M)
5888 ==> A ** (basis k) = column k A`,
5889 SIMP_TAC[CART_EQ; column; MATRIX_VECTOR_MUL_COMPONENT; DOT_BASIS;
5892 let COLUMNS_IMAGE_BASIS = prove
5894 columns A = IMAGE (\x. A ** x) {basis i | 1 <= i /\ i <= dimindex(:M)}`,
5895 GEN_TAC THEN REWRITE_TAC[columns] THEN
5896 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
5897 REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN
5898 MATCH_MP_TAC(SET_RULE
5899 `(!x. x IN s ==> f x = g x) ==> IMAGE f s = IMAGE g s`) THEN
5900 SIMP_TAC[IN_ELIM_THM; MATRIX_VECTOR_MUL_BASIS]);;
5902 let RANK_DIM_IM = prove
5903 (`!A:real^M^N. rank A = dim(IMAGE (\x. A ** x) (:real^M))`,
5904 GEN_TAC THEN REWRITE_TAC[rank] THEN
5905 MATCH_MP_TAC SPAN_EQ_DIM THEN REWRITE_TAC[COLUMNS_IMAGE_BASIS] THEN
5906 SIMP_TAC[SPAN_LINEAR_IMAGE; MATRIX_VECTOR_MUL_LINEAR] THEN
5907 AP_TERM_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM SPAN_SPAN] THEN
5908 REWRITE_TAC[SPAN_STDBASIS]);;
5910 let DIM_EQ_SPAN = prove
5911 (`!s t:real^N->bool. s SUBSET t /\ dim t <= dim s ==> span s = span t`,
5912 REPEAT STRIP_TAC THEN
5913 X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC
5914 (ISPEC `span s:real^N->bool` BASIS_EXISTS) THEN
5915 MP_TAC(ISPECL [`span t:real^N->bool`; `b:real^N->bool`]
5916 CARD_GE_DIM_INDEPENDENT) THEN
5917 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
5918 ASM_REWRITE_TAC[DIM_SPAN] THEN
5919 ASM_MESON_TAC[SPAN_MONO; SPAN_SPAN; SUBSET_TRANS; SUBSET_ANTISYM]);;
5921 let DIM_EQ_FULL = prove
5922 (`!s:real^N->bool. dim s = dimindex(:N) <=> span s = (:real^N)`,
5923 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN EQ_TAC THEN
5924 SIMP_TAC[DIM_UNIV] THEN DISCH_TAC THEN
5925 GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_UNIV] THEN MATCH_MP_TAC DIM_EQ_SPAN THEN
5926 ASM_REWRITE_TAC[SUBSET_UNIV; DIM_UNIV] THEN
5927 ASM_MESON_TAC[LE_REFL; DIM_SPAN]);;
5929 let DIM_PSUBSET = prove
5930 (`!s t. (span s) PSUBSET (span t) ==> dim s < dim t`,
5931 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
5932 SIMP_TAC[PSUBSET; DIM_SUBSET; LT_LE] THEN
5933 MESON_TAC[EQ_IMP_LE; DIM_EQ_SPAN; SPAN_SPAN]);;
5935 let RANK_BOUND = prove
5936 (`!A:real^M^N. rank(A) <= MIN (dimindex(:M)) (dimindex(:N))`,
5937 GEN_TAC THEN REWRITE_TAC[ARITH_RULE `x <= MIN a b <=> x <= a /\ x <= b`] THEN
5939 [REWRITE_TAC[DIM_SUBSET_UNIV; RANK_ROW];
5940 REWRITE_TAC[DIM_SUBSET_UNIV; rank]]);;
5942 let FULL_RANK_INJECTIVE = prove
5944 rank A = dimindex(:M) <=>
5945 (!x y:real^M. A ** x = A ** y ==> x = y)`,
5946 REWRITE_TAC[GSYM MATRIX_LEFT_INVERTIBLE_INJECTIVE] THEN
5947 REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_SPAN_ROWS] THEN
5948 REWRITE_TAC[RANK_ROW; DIM_EQ_FULL]);;
5950 let FULL_RANK_SURJECTIVE = prove
5952 rank A = dimindex(:N) <=> (!y:real^N. ?x:real^M. A ** x = y)`,
5953 REWRITE_TAC[GSYM MATRIX_RIGHT_INVERTIBLE_SURJECTIVE] THEN
5954 REWRITE_TAC[GSYM LEFT_INVERTIBLE_TRANSP] THEN
5955 REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_INJECTIVE] THEN
5956 REWRITE_TAC[GSYM FULL_RANK_INJECTIVE; RANK_TRANSP]);;
5959 (`rank(mat 1:real^N^N) = dimindex(:N)`,
5960 REWRITE_TAC[FULL_RANK_INJECTIVE; MATRIX_VECTOR_MUL_LID]);;
5962 let MATRIX_FULL_LINEAR_EQUATIONS = prove
5963 (`!A:real^M^N b:real^N.
5964 rank A = dimindex(:N) ==> ?x. A ** x = b`,
5965 SIMP_TAC[FULL_RANK_SURJECTIVE]);;
5967 let MATRIX_NONFULL_LINEAR_EQUATIONS_EQ = prove
5969 (?x. ~(x = vec 0) /\ A ** x = vec 0) <=> ~(rank A = dimindex(:M))`,
5970 REPEAT GEN_TAC THEN REWRITE_TAC[FULL_RANK_INJECTIVE] THEN
5971 SIMP_TAC[LINEAR_INJECTIVE_0; MATRIX_VECTOR_MUL_LINEAR] THEN
5974 let MATRIX_NONFULL_LINEAR_EQUATIONS = prove
5976 ~(rank A = dimindex(:M)) ==> ?x. ~(x = vec 0) /\ A ** x = vec 0`,
5977 REWRITE_TAC[MATRIX_NONFULL_LINEAR_EQUATIONS_EQ]);;
5979 let MATRIX_TRIVIAL_LINEAR_EQUATIONS = prove
5981 dimindex(:N) < dimindex(:M)
5982 ==> ?x. ~(x = vec 0) /\ A ** x = vec 0`,
5983 REPEAT STRIP_TAC THEN MATCH_MP_TAC MATRIX_NONFULL_LINEAR_EQUATIONS THEN
5984 MATCH_MP_TAC(ARITH_RULE
5985 `!a. x <= MIN b a /\ a < b ==> ~(x = b)`) THEN
5986 EXISTS_TAC `dimindex(:N)` THEN ASM_REWRITE_TAC[RANK_BOUND]);;
5988 let RANK_EQ_0 = prove
5989 (`!A:real^M^N. rank A = 0 <=> A = mat 0`,
5990 REWRITE_TAC[RANK_DIM_IM; DIM_EQ_0; SUBSET; FORALL_IN_IMAGE; IN_SING;
5992 GEN_TAC THEN GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [CART_EQ] THEN
5993 SIMP_TAC[CART_EQ; MATRIX_MUL_DOT; VEC_COMPONENT; LAMBDA_BETA; mat] THEN
5994 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
5995 REWRITE_TAC[RIGHT_FORALL_IMP_THM; FORALL_DOT_EQ_0; COND_ID] THEN
5996 REWRITE_TAC[CART_EQ; VEC_COMPONENT]);;
6000 REWRITE_TAC[RANK_EQ_0]);;
6002 let RANK_MUL_LE_RIGHT = prove
6003 (`!A:real^N^M B:real^P^N. rank(A ** B) <= rank(B)`,
6004 REPEAT GEN_TAC THEN MATCH_MP_TAC LE_TRANS THEN
6005 EXISTS_TAC `dim(IMAGE (\y. (A:real^N^M) ** y)
6006 (IMAGE (\x. (B:real^P^N) ** x) (:real^P)))` THEN
6007 REWRITE_TAC[RANK_DIM_IM] THEN CONJ_TAC THENL
6008 [REWRITE_TAC[GSYM IMAGE_o; o_DEF; MATRIX_VECTOR_MUL_ASSOC; LE_REFL];
6009 MATCH_MP_TAC DIM_LINEAR_IMAGE_LE THEN
6010 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]]);;
6012 let RANK_MUL_LE_LEFT = prove
6013 (`!A:real^N^M B:real^P^N. rank(A ** B) <= rank(A)`,
6014 ONCE_REWRITE_TAC[GSYM RANK_TRANSP] THEN
6015 REWRITE_TAC[MATRIX_TRANSP_MUL] THEN
6016 REWRITE_TAC[RANK_MUL_LE_RIGHT]);;
6018 (* ------------------------------------------------------------------------- *)
6019 (* Basic lemmas about hyperplanes and halfspaces. *)
6020 (* ------------------------------------------------------------------------- *)
6022 let HYPERPLANE_EQ_EMPTY = prove
6023 (`!a:real^N b. {x | a dot x = b} = {} <=> a = vec 0 /\ ~(b = &0)`,
6024 REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN
6025 ASM_CASES_TAC `a:real^N = vec 0` THEN ASM_REWRITE_TAC[DOT_LZERO] THENL
6027 DISCH_THEN(MP_TAC o SPEC `b / (a dot a) % a:real^N`) THEN
6028 ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0]]);;
6030 let HYPERPLANE_EQ_UNIV = prove
6031 (`!a b. {x | a dot x = b} = (:real^N) <=> a = vec 0 /\ b = &0`,
6032 REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_UNIV] THEN
6033 ASM_CASES_TAC `a:real^N = vec 0` THEN ASM_REWRITE_TAC[DOT_LZERO] THENL
6035 DISCH_THEN(MP_TAC o SPEC `(b + &1) / (a dot a) % a:real^N`) THEN
6036 ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0] THEN REAL_ARITH_TAC]);;
6038 let HALFSPACE_EQ_EMPTY_LT = prove
6039 (`!a:real^N b. {x | a dot x < b} = {} <=> a = vec 0 /\ b <= &0`,
6040 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL
6041 [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN
6042 COND_CASES_TAC THEN REWRITE_TAC[UNIV_NOT_EMPTY] THEN ASM_REAL_ARITH_TAC;
6043 ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
6044 EXISTS_TAC `(b - &1) / (a dot a) % a:real^N` THEN
6045 ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0] THEN
6048 let HALFSPACE_EQ_EMPTY_GT = prove
6049 (`!a:real^N b. {x | a dot x > b} = {} <=> a = vec 0 /\ b >= &0`,
6051 MP_TAC(ISPECL [`--a:real^N`; `--b:real`] HALFSPACE_EQ_EMPTY_LT) THEN
6052 SIMP_TAC[real_gt; DOT_LNEG; REAL_LT_NEG2; VECTOR_NEG_EQ_0] THEN
6053 DISCH_TAC THEN AP_TERM_TAC THEN REAL_ARITH_TAC);;
6055 let HALFSPACE_EQ_EMPTY_LE = prove
6056 (`!a:real^N b. {x | a dot x <= b} = {} <=> a = vec 0 /\ b < &0`,
6057 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL
6058 [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN
6059 COND_CASES_TAC THEN REWRITE_TAC[UNIV_NOT_EMPTY] THEN ASM_REAL_ARITH_TAC;
6060 ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
6061 EXISTS_TAC `(b - &1) / (a dot a) % a:real^N` THEN
6062 ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0] THEN
6065 let HALFSPACE_EQ_EMPTY_GE = prove
6066 (`!a:real^N b. {x | a dot x >= b} = {} <=> a = vec 0 /\ b > &0`,
6068 MP_TAC(ISPECL [`--a:real^N`; `--b:real`] HALFSPACE_EQ_EMPTY_LE) THEN
6069 SIMP_TAC[real_ge; DOT_LNEG; REAL_LE_NEG2; VECTOR_NEG_EQ_0] THEN
6070 DISCH_TAC THEN AP_TERM_TAC THEN REAL_ARITH_TAC);;
6072 (* ------------------------------------------------------------------------- *)
6073 (* A non-injective linear function maps into a hyperplane. *)
6074 (* ------------------------------------------------------------------------- *)
6076 let ADJOINT_INJECTIVE = prove
6077 (`!f:real^M->real^N.
6079 ==> ((!x y. adjoint f x = adjoint f y ==> x = y) <=>
6080 (!y. ?x. f x = y))`,
6081 REPEAT STRIP_TAC THEN
6082 FIRST_ASSUM(ASSUME_TAC o GSYM o MATCH_MP MATRIX_WORKS o MATCH_MP
6083 ADJOINT_LINEAR) THEN
6084 FIRST_ASSUM(ASSUME_TAC o GSYM o MATCH_MP MATRIX_WORKS) THEN
6085 ASM_REWRITE_TAC[GSYM FULL_RANK_INJECTIVE; GSYM FULL_RANK_SURJECTIVE] THEN
6086 ASM_SIMP_TAC[MATRIX_ADJOINT; RANK_TRANSP]);;
6088 let ADJOINT_SURJECTIVE = prove
6089 (`!f:real^M->real^N.
6091 ==> ((!y. ?x. adjoint f x = y) <=> (!x y. f x = f y ==> x = y))`,
6092 REPEAT STRIP_TAC THEN
6093 FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV)
6094 [GSYM(MATCH_MP ADJOINT_ADJOINT th)]) THEN
6095 ASM_SIMP_TAC[ADJOINT_INJECTIVE; ADJOINT_LINEAR]);;
6097 let ADJOINT_INJECTIVE_INJECTIVE = prove
6098 (`!f:real^N->real^N.
6100 ==> ((!x y. adjoint f x = adjoint f y ==> x = y) <=>
6101 (!x y. f x = f y ==> x = y))`,
6102 SIMP_TAC[ADJOINT_INJECTIVE] THEN
6103 MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE;
6104 LINEAR_SURJECTIVE_IMP_INJECTIVE]);;
6106 let ADJOINT_INJECTIVE_INJECTIVE_0 = prove
6107 (`!f:real^N->real^N.
6109 ==> ((!x. adjoint f x = vec 0 ==> x = vec 0) <=>
6110 (!x. f x = vec 0 ==> x = vec 0))`,
6111 REPEAT STRIP_TAC THEN
6112 FIRST_ASSUM(MP_TAC o MATCH_MP ADJOINT_INJECTIVE_INJECTIVE) THEN
6113 FIRST_ASSUM(ASSUME_TAC o MATCH_MP ADJOINT_LINEAR) THEN
6114 ASM_MESON_TAC[LINEAR_INJECTIVE_0]);;
6116 let LINEAR_SINGULAR_INTO_HYPERPLANE = prove
6117 (`!f:real^N->real^N.
6119 ==> (~(!x y. f(x) = f(y) ==> x = y) <=>
6120 ?a. ~(a = vec 0) /\ !x. a dot f(x) = &0)`,
6121 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[DOT_SYM] THEN
6122 ASM_SIMP_TAC[ADJOINT_WORKS; FORALL_DOT_EQ_0] THEN
6123 REWRITE_TAC[MESON[] `(?a. ~p a /\ q a) <=> ~(!a. q a ==> p a)`] THEN
6124 ASM_SIMP_TAC[ADJOINT_INJECTIVE_INJECTIVE_0; LINEAR_INJECTIVE_0]);;
6126 let LINEAR_SINGULAR_IMAGE_HYPERPLANE = prove
6127 (`!f:real^N->real^N.
6128 linear f /\ ~(!x y. f(x) = f(y) ==> x = y)
6129 ==> ?a. ~(a = vec 0) /\ !s. IMAGE f s SUBSET {x | a dot x = &0}`,
6130 GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6131 ASM_SIMP_TAC[LINEAR_SINGULAR_INTO_HYPERPLANE] THEN
6132 SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[]);;
6134 let LOWDIM_EXPAND_DIMENSION = prove
6135 (`!s:real^N->bool n.
6136 dim s <= n /\ n <= dimindex(:N)
6137 ==> ?t. dim(t) = n /\ span s SUBSET span t`,
6139 GEN_REWRITE_TAC (BINDER_CONV o LAND_CONV o LAND_CONV) [LE_EXISTS] THEN
6140 SIMP_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN
6141 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
6142 REWRITE_TAC[RIGHT_FORALL_IMP_THM; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
6143 INDUCT_TAC THENL [MESON_TAC[ADD_CLAUSES; SUBSET_REFL]; ALL_TAC] THEN
6144 REWRITE_TAC[ARITH_RULE `s + SUC d <= n <=> s + d < n`] THEN
6145 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
6146 ASM_SIMP_TAC[LT_IMP_LE; LEFT_IMP_EXISTS_THM] THEN
6147 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
6148 REWRITE_TAC[ADD_CLAUSES] THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
6149 SUBGOAL_THEN `~(span t = (:real^N))` MP_TAC THENL
6150 [REWRITE_TAC[GSYM DIM_EQ_FULL] THEN ASM_ARITH_TAC; ALL_TAC] THEN
6151 REWRITE_TAC[EXTENSION; IN_UNIV; NOT_FORALL_THM; LEFT_IMP_EXISTS_THM] THEN
6152 X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN
6153 EXISTS_TAC `(a:real^N) INSERT t` THEN ASM_REWRITE_TAC[DIM_INSERT; ADD1] THEN
6154 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `span(t:real^N->bool)` THEN
6155 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SPAN_MONO THEN SET_TAC[]);;
6157 let LOWDIM_EXPAND_BASIS = prove
6158 (`!s:real^N->bool n.
6159 dim s <= n /\ n <= dimindex(:N)
6160 ==> ?b. b HAS_SIZE n /\ independent b /\ span s SUBSET span b`,
6161 REPEAT GEN_TAC THEN DISCH_TAC THEN
6162 FIRST_ASSUM(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC o
6163 MATCH_MP LOWDIM_EXPAND_DIMENSION) THEN
6164 MP_TAC(ISPEC `t:real^N->bool` BASIS_EXISTS) THEN
6165 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N->bool` THEN
6166 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
6167 ASM_MESON_TAC[SPAN_SPAN; SUBSET_TRANS; SPAN_MONO]);;
6169 (* ------------------------------------------------------------------------- *)
6170 (* Orthogonal bases, Gram-Schmidt process, and related theorems. *)
6171 (* ------------------------------------------------------------------------- *)
6173 let SPAN_DELETE_0 = prove
6174 (`!s:real^N->bool. span(s DELETE vec 0) = span s`,
6175 GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
6176 SIMP_TAC[DELETE_SUBSET; SPAN_MONO] THEN
6177 MATCH_MP_TAC SUBSET_TRANS THEN
6178 EXISTS_TAC `span((vec 0:real^N) INSERT (s DELETE vec 0))` THEN CONJ_TAC THENL
6179 [MATCH_MP_TAC SPAN_MONO THEN SET_TAC[];
6180 SIMP_TAC[SUBSET; SPAN_BREAKDOWN_EQ; VECTOR_MUL_RZERO; VECTOR_SUB_RZERO]]);;
6182 let SPAN_IMAGE_SCALE = prove
6183 (`!c s. FINITE s /\ (!x. x IN s ==> ~(c x = &0))
6184 ==> span (IMAGE (\x:real^N. c(x) % x) s) = span s`,
6185 GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
6186 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
6187 SIMP_TAC[IMAGE_CLAUSES; SPAN_BREAKDOWN_EQ; EXTENSION; FORALL_IN_INSERT] THEN
6188 MAP_EVERY X_GEN_TAC [`x:real^N`; `t:real^N->bool`] THEN
6189 STRIP_TAC THEN STRIP_TAC THEN X_GEN_TAC `y:real^N` THEN
6190 REWRITE_TAC[VECTOR_MUL_ASSOC] THEN EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
6191 DISCH_THEN(X_CHOOSE_TAC `k:real`) THEN
6192 EXISTS_TAC `k / (c:real^N->real) x` THEN
6193 ASM_SIMP_TAC[REAL_DIV_RMUL]);;
6195 let PAIRWISE_ORTHOGONAL_INDEPENDENT = prove
6197 pairwise orthogonal s /\ ~(vec 0 IN s) ==> independent s`,
6198 REWRITE_TAC[pairwise; orthogonal] THEN REPEAT STRIP_TAC THEN
6199 REWRITE_TAC[independent; dependent] THEN
6200 DISCH_THEN(X_CHOOSE_THEN `a:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6201 REWRITE_TAC[SPAN_EXPLICIT; IN_ELIM_THM; NOT_EXISTS_THM] THEN
6202 MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN
6203 REWRITE_TAC[SUBSET; IN_DELETE] THEN STRIP_TAC THEN
6204 FIRST_X_ASSUM(MP_TAC o AP_TERM `\x:real^N. a dot x`) THEN
6205 ASM_SIMP_TAC[DOT_RSUM; DOT_RMUL; REAL_MUL_RZERO; SUM_0] THEN
6206 ASM_MESON_TAC[DOT_EQ_0]);;
6208 let PAIRWISE_ORTHOGONAL_IMP_FINITE = prove
6209 (`!s:real^N->bool. pairwise orthogonal s ==> FINITE s`,
6210 REPEAT STRIP_TAC THEN
6211 SUBGOAL_THEN `independent (s DELETE (vec 0:real^N))` MP_TAC THENL
6212 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN
6213 REWRITE_TAC[IN_DELETE] THEN MATCH_MP_TAC PAIRWISE_MONO THEN
6214 EXISTS_TAC `s:real^N->bool` THEN
6215 ASM_SIMP_TAC[SUBSET; IN_DELETE];
6216 DISCH_THEN(MP_TAC o MATCH_MP INDEPENDENT_IMP_FINITE) THEN
6217 REWRITE_TAC[FINITE_DELETE]]);;
6219 let GRAM_SCHMIDT_STEP = prove
6221 pairwise orthogonal s /\ x IN span s
6222 ==> orthogonal x (a - vsum s (\b:real^N. (b dot a) / (b dot b) % b))`,
6223 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
6224 REWRITE_TAC[ONCE_REWRITE_RULE[ORTHOGONAL_SYM] ORTHOGONAL_TO_SPAN_EQ] THEN
6225 X_GEN_TAC `s:real^N->bool` THEN STRIP_TAC THEN
6226 MAP_EVERY X_GEN_TAC [`a:real^N`; `x:real^N`] THEN DISCH_TAC THEN
6227 FIRST_ASSUM(ASSUME_TAC o MATCH_MP PAIRWISE_ORTHOGONAL_IMP_FINITE) THEN
6228 REWRITE_TAC[orthogonal; DOT_RSUB] THEN ASM_SIMP_TAC[DOT_RSUM] THEN
6229 REWRITE_TAC[REAL_SUB_0; DOT_RMUL] THEN MATCH_MP_TAC EQ_TRANS THEN
6230 EXISTS_TAC `sum s (\y:real^N. if y = x then y dot a else &0)` THEN
6231 CONJ_TAC THENL [ASM_SIMP_TAC[SUM_DELTA; DOT_SYM]; ALL_TAC] THEN
6232 MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
6233 RULE_ASSUM_TAC(REWRITE_RULE[pairwise; orthogonal]) THEN
6234 ASM_CASES_TAC `x:real^N = y` THEN ASM_SIMP_TAC[DOT_LMUL; REAL_MUL_RZERO] THEN
6235 ASM_CASES_TAC `y:real^N = vec 0` THEN
6236 ASM_SIMP_TAC[REAL_DIV_RMUL; DOT_EQ_0; DOT_LZERO; REAL_MUL_RZERO]);;
6238 let ORTHOGONAL_EXTENSION = prove
6239 (`!s t:real^N->bool.
6240 pairwise orthogonal s
6241 ==> ?u. pairwise orthogonal (s UNION u) /\
6242 span (s UNION u) = span (s UNION t)`,
6244 (`!t s:real^N->bool.
6245 FINITE t /\ FINITE s /\ pairwise orthogonal s
6246 ==> ?u. pairwise orthogonal (s UNION u) /\
6247 span (s UNION u) = span (s UNION t)`,
6248 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
6249 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN CONJ_TAC THENL
6250 [REPEAT STRIP_TAC THEN EXISTS_TAC `{}:real^N->bool` THEN
6251 ASM_REWRITE_TAC[UNION_EMPTY];
6253 MAP_EVERY X_GEN_TAC [`a:real^N`; `t:real^N->bool`] THEN
6254 REWRITE_TAC[pairwise; orthogonal] THEN REPEAT STRIP_TAC THEN
6255 ABBREV_TAC `a' = a - vsum s (\b:real^N. (b dot a) / (b dot b) % b)` THEN
6256 FIRST_X_ASSUM(MP_TAC o SPEC `(a':real^N) INSERT s`) THEN
6257 ASM_REWRITE_TAC[FINITE_INSERT] THEN ANTS_TAC THENL
6258 [SUBGOAL_THEN `!x:real^N. x IN s ==> a' dot x = &0`
6259 (fun th -> REWRITE_TAC[IN_INSERT] THEN ASM_MESON_TAC[DOT_SYM; th]) THEN
6260 REPEAT STRIP_TAC THEN EXPAND_TAC "a'" THEN
6261 REWRITE_TAC[GSYM orthogonal] THEN ONCE_REWRITE_TAC[ORTHOGONAL_SYM] THEN
6262 MATCH_MP_TAC GRAM_SCHMIDT_STEP THEN
6263 ASM_SIMP_TAC[pairwise; orthogonal; SPAN_CLAUSES];
6264 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
6265 EXISTS_TAC `(a':real^N) INSERT u` THEN
6266 ASM_REWRITE_TAC[SET_RULE `s UNION a INSERT u = a INSERT s UNION u`] THEN
6267 REWRITE_TAC[SET_RULE `(x INSERT s) UNION t = x INSERT (s UNION t)`] THEN
6268 MATCH_MP_TAC EQ_SPAN_INSERT_EQ THEN EXPAND_TAC "a'" THEN
6269 REWRITE_TAC[VECTOR_ARITH `a - x - a:real^N = --x`] THEN
6270 MATCH_MP_TAC SPAN_NEG THEN MATCH_MP_TAC SPAN_VSUM THEN
6271 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
6272 MATCH_MP_TAC SPAN_MUL THEN ASM_SIMP_TAC[SPAN_SUPERSET; IN_UNION]]) in
6273 REPEAT STRIP_TAC THEN
6274 MP_TAC(ISPEC `span t:real^N->bool` BASIS_SUBSPACE_EXISTS) THEN
6275 REWRITE_TAC[SUBSPACE_SPAN; LEFT_IMP_EXISTS_THM] THEN
6276 X_GEN_TAC `b:real^N->bool` THEN STRIP_TAC THEN
6277 MP_TAC(ISPECL [`b:real^N->bool`; `s:real^N->bool`] lemma) THEN
6279 [ASM_MESON_TAC[HAS_SIZE; PAIRWISE_ORTHOGONAL_IMP_FINITE];
6280 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
6281 ASM_REWRITE_TAC[SPAN_UNION]]);;
6283 let ORTHOGONAL_EXTENSION_STRONG = prove
6284 (`!s t:real^N->bool.
6285 pairwise orthogonal s
6286 ==> ?u. DISJOINT u (vec 0 INSERT s) /\
6287 pairwise orthogonal (s UNION u) /\
6288 span (s UNION u) = span (s UNION t)`,
6289 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
6290 SPEC `t:real^N->bool` o MATCH_MP ORTHOGONAL_EXTENSION) THEN
6291 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
6292 EXISTS_TAC `u DIFF ((vec 0:real^N) INSERT s)` THEN REPEAT CONJ_TAC THENL
6294 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6295 PAIRWISE_MONO)) THEN SET_TAC[];
6296 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
6297 GEN_REWRITE_TAC BINOP_CONV [GSYM SPAN_DELETE_0] THEN
6298 AP_TERM_TAC THEN SET_TAC[]]);;
6300 let ORTHONORMAL_EXTENSION = prove
6301 (`!s t:real^N->bool.
6302 pairwise orthogonal s /\ (!x. x IN s ==> norm x = &1)
6303 ==> ?u. DISJOINT u s /\
6304 pairwise orthogonal (s UNION u) /\
6305 (!x. x IN u ==> norm x = &1) /\
6306 span(s UNION u) = span(s UNION t)`,
6307 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
6308 SPEC `t:real^N->bool` o MATCH_MP ORTHOGONAL_EXTENSION_STRONG) THEN
6309 REWRITE_TAC[SET_RULE `DISJOINT u s <=> !x. x IN u ==> ~(x IN s)`] THEN
6310 REWRITE_TAC[IN_INSERT; DE_MORGAN_THM; pairwise] THEN
6311 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
6312 EXISTS_TAC `IMAGE (\x:real^N. inv(norm x) % x) u` THEN
6313 REWRITE_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
6314 REPEAT CONJ_TAC THENL
6315 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
6316 ASM_CASES_TAC `norm(x:real^N) = &1` THEN
6317 ASM_SIMP_TAC[REAL_INV_1; VECTOR_MUL_LID] THEN DISCH_TAC THEN
6318 FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `inv(norm x) % x:real^N`]) THEN
6319 ASM_REWRITE_TAC[IN_UNION; VECTOR_MUL_EQ_0; REAL_SUB_0; REAL_INV_EQ_1;
6320 VECTOR_ARITH `x:real^N = a % x <=> (a - &1) % x = vec 0`] THEN
6321 ASM_CASES_TAC `x:real^N = vec 0` THENL
6322 [ASM_MESON_TAC[VECTOR_MUL_RZERO];
6323 ASM_REWRITE_TAC[orthogonal; DOT_RMUL; REAL_ENTIRE; DOT_EQ_0] THEN
6324 ASM_REWRITE_TAC[REAL_INV_EQ_0; NORM_EQ_0]];
6325 REWRITE_TAC[IN_UNION; IN_IMAGE] THEN REPEAT STRIP_TAC THEN
6326 ASM_SIMP_TAC[orthogonal; DOT_LMUL; DOT_RMUL; REAL_ENTIRE; DOT_EQ_0;
6327 REAL_INV_EQ_0; NORM_EQ_0] THEN
6328 REWRITE_TAC[GSYM orthogonal] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
6329 ASM_REWRITE_TAC[IN_UNION] THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
6331 ASM_SIMP_TAC[NORM_MUL; REAL_MUL_LINV; NORM_EQ_0; REAL_ABS_INV;
6333 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
6334 REWRITE_TAC[SPAN_EQ; UNION_SUBSET] THEN
6335 SIMP_TAC[SUBSET; FORALL_IN_IMAGE; SPAN_SUPERSET; SPAN_MUL; IN_UNION] THEN
6336 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
6337 SUBGOAL_THEN `x:real^N = norm(x) % inv(norm x) % x`
6338 (fun th -> GEN_REWRITE_TAC LAND_CONV [th])
6340 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; NORM_EQ_0; VECTOR_MUL_LID];
6341 MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN
6342 REWRITE_TAC[IN_UNION; IN_IMAGE] THEN ASM_MESON_TAC[]]]);;
6344 let VECTOR_IN_ORTHOGONAL_SPANNINGSET = prove
6345 (`!a. ?s. a IN s /\ pairwise orthogonal s /\ span s = (:real^N)`,
6347 MP_TAC(ISPECL [`{a:real^N}`; `(IMAGE basis (1..dimindex(:N))):real^N->bool`]
6348 ORTHOGONAL_EXTENSION) THEN
6349 REWRITE_TAC[PAIRWISE_SING] THEN
6350 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
6351 EXISTS_TAC `{a:real^N} UNION u` THEN ASM_REWRITE_TAC[IN_UNION; IN_SING] THEN
6352 MATCH_MP_TAC(SET_RULE `!s. s = UNIV /\ s SUBSET t ==> t = UNIV`) THEN
6353 EXISTS_TAC `span {basis i:real^N | 1 <= i /\ i <= dimindex (:N)}` THEN
6354 CONJ_TAC THENL [REWRITE_TAC[SPAN_STDBASIS]; MATCH_MP_TAC SPAN_MONO] THEN
6355 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; GSYM IN_NUMSEG] THEN SET_TAC[]);;
6357 let VECTOR_IN_ORTHOGONAL_BASIS = prove
6359 ==> ?s. a IN s /\ ~(vec 0 IN s) /\
6360 pairwise orthogonal s /\
6362 s HAS_SIZE (dimindex(:N)) /\
6363 span s = (:real^N)`,
6364 REPEAT STRIP_TAC THEN
6365 MP_TAC(ISPEC `a:real^N` VECTOR_IN_ORTHOGONAL_SPANNINGSET) THEN
6366 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
6367 EXISTS_TAC `s DELETE (vec 0:real^N)` THEN ASM_REWRITE_TAC[IN_DELETE] THEN
6368 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6369 [RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6370 ASM_SIMP_TAC[pairwise; IN_DELETE];
6372 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6373 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_SIMP_TAC[IN_DELETE];
6375 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6376 [ASM_MESON_TAC[SPAN_DELETE_0];
6377 DISCH_TAC THEN ASM_SIMP_TAC[BASIS_HAS_SIZE_UNIV]]);;
6379 let VECTOR_IN_ORTHONORMAL_BASIS = prove
6382 pairwise orthogonal s /\
6383 (!x. x IN s ==> norm x = &1) /\
6385 s HAS_SIZE (dimindex(:N)) /\
6386 span s = (:real^N)`,
6387 GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN
6388 ASM_REWRITE_TAC[NORM_0; REAL_OF_NUM_EQ; ARITH_EQ] THEN DISCH_TAC THEN
6389 FIRST_ASSUM(MP_TAC o MATCH_MP VECTOR_IN_ORTHOGONAL_BASIS) THEN
6390 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
6391 EXISTS_TAC `IMAGE (\x:real^N. inv(norm x) % x) s` THEN
6393 [REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `a:real^N` THEN
6394 ASM_REWRITE_TAC[REAL_INV_1; VECTOR_MUL_LID];
6396 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6397 [REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
6398 RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6399 ASM_MESON_TAC[ORTHOGONAL_CLAUSES];
6401 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6402 [REWRITE_TAC[FORALL_IN_IMAGE; NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN
6403 ASM_MESON_TAC[REAL_MUL_LINV; NORM_EQ_0];
6405 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6406 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_REWRITE_TAC[] THEN
6407 REWRITE_TAC[IN_IMAGE] THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN
6408 SIMP_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0; NORM_EQ_0] THEN ASM_MESON_TAC[];
6410 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6411 [ALL_TAC; ASM_SIMP_TAC[BASIS_HAS_SIZE_UNIV]] THEN
6412 UNDISCH_THEN `span s = (:real^N)` (SUBST1_TAC o SYM) THEN
6413 MATCH_MP_TAC SPAN_IMAGE_SCALE THEN
6414 REWRITE_TAC[REAL_INV_EQ_0; NORM_EQ_0] THEN
6415 ASM_MESON_TAC[HAS_SIZE]);;
6417 let BESSEL_INEQUALITY = prove
6419 pairwise orthogonal s /\ (!x. x IN s ==> norm x = &1)
6420 ==> sum s (\e. (e dot x) pow 2) <= norm(x) pow 2`,
6421 REPEAT STRIP_TAC THEN
6422 FIRST_ASSUM(ASSUME_TAC o MATCH_MP PAIRWISE_ORTHOGONAL_IMP_FINITE) THEN
6423 MP_TAC(ISPEC `x - vsum s (\e. (e dot x) % e):real^N` DOT_POS_LE) THEN
6424 REWRITE_TAC[NORM_POW_2; VECTOR_ARITH
6425 `(a - b:real^N) dot (a - b) = a dot a + b dot b - &2 * b dot a`] THEN
6426 ASM_SIMP_TAC[DOT_LSUM; REAL_POW_2; DOT_LMUL] THEN
6427 MATCH_MP_TAC(REAL_ARITH `t = s ==> &0 <= x + t - &2 * s ==> s <= x`) THEN
6428 MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC `e:real^N` THEN DISCH_TAC THEN
6429 ASM_SIMP_TAC[DOT_RSUM] THEN AP_TERM_TAC THEN
6430 MATCH_MP_TAC EQ_TRANS THEN
6431 EXISTS_TAC `sum s (\k:real^N. if k = e then e dot x else &0)` THEN
6432 CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[SUM_DELTA]] THEN
6433 MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC `k:real^N` THEN DISCH_TAC THEN
6434 REWRITE_TAC[DOT_RMUL] THEN COND_CASES_TAC THENL
6435 [ASM_REWRITE_TAC[REAL_RING `a * x = a <=> a = &0 \/ x = &1`] THEN
6436 DISJ2_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e:real^N`) THEN
6437 ASM_REWRITE_TAC[NORM_EQ_SQUARE] THEN REAL_ARITH_TAC;
6438 RULE_ASSUM_TAC(REWRITE_RULE[pairwise; orthogonal]) THEN
6439 ASM_SIMP_TAC[REAL_ENTIRE]]);;
6441 (* ------------------------------------------------------------------------- *)
6442 (* Analogous theorems for existence of orthonormal basis for a subspace. *)
6443 (* ------------------------------------------------------------------------- *)
6445 let ORTHOGONAL_SPANNINGSET_SUBSPACE = prove
6448 ==> ?b. b SUBSET s /\ pairwise orthogonal b /\ span b = s`,
6449 REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN
6450 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
6451 MP_TAC(ISPECL[`{}:real^N->bool`; `b:real^N->bool`] ORTHOGONAL_EXTENSION) THEN
6452 REWRITE_TAC[PAIRWISE_EMPTY; UNION_EMPTY] THEN
6453 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N->bool` THEN
6454 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
6455 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6456 [MATCH_MP_TAC SPAN_SUBSPACE THEN ASM_REWRITE_TAC[];
6457 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_MESON_TAC[SPAN_INC]]);;
6459 let ORTHOGONAL_BASIS_SUBSPACE = prove
6462 ==> ?b. ~(vec 0 IN b) /\
6464 pairwise orthogonal b /\
6466 b HAS_SIZE (dim s) /\
6468 REPEAT STRIP_TAC THEN
6469 FIRST_ASSUM(MP_TAC o MATCH_MP ORTHOGONAL_SPANNINGSET_SUBSPACE) THEN
6470 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
6471 EXISTS_TAC `b DELETE (vec 0:real^N)` THEN ASM_REWRITE_TAC[IN_DELETE] THEN
6472 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
6473 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6474 [RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6475 ASM_SIMP_TAC[pairwise; IN_DELETE];
6477 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6478 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_SIMP_TAC[IN_DELETE];
6480 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6481 [ASM_MESON_TAC[SPAN_DELETE_0];
6482 DISCH_TAC THEN ASM_SIMP_TAC[BASIS_HAS_SIZE_DIM]]);;
6484 let ORTHONORMAL_BASIS_SUBSPACE = prove
6487 ==> ?b. b SUBSET s /\
6488 pairwise orthogonal b /\
6489 (!x. x IN b ==> norm x = &1) /\
6491 b HAS_SIZE (dim s) /\
6493 REPEAT STRIP_TAC THEN
6494 FIRST_ASSUM(MP_TAC o MATCH_MP ORTHOGONAL_BASIS_SUBSPACE) THEN
6495 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
6496 EXISTS_TAC `IMAGE (\x:real^N. inv(norm x) % x) b` THEN
6498 [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
6499 ASM_MESON_TAC[SPAN_MUL; SPAN_INC; SUBSET];
6501 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6502 [REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
6503 RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6504 ASM_MESON_TAC[ORTHOGONAL_CLAUSES];
6506 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6507 [REWRITE_TAC[FORALL_IN_IMAGE; NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN
6508 ASM_MESON_TAC[REAL_MUL_LINV; NORM_EQ_0];
6510 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6511 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_REWRITE_TAC[] THEN
6512 REWRITE_TAC[IN_IMAGE] THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN
6513 SIMP_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0; NORM_EQ_0] THEN ASM_MESON_TAC[];
6515 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6516 [ALL_TAC; ASM_SIMP_TAC[BASIS_HAS_SIZE_DIM]] THEN
6517 UNDISCH_THEN `span b = (s:real^N->bool)` (SUBST1_TAC o SYM) THEN
6518 MATCH_MP_TAC SPAN_IMAGE_SCALE THEN
6519 REWRITE_TAC[REAL_INV_EQ_0; NORM_EQ_0] THEN
6520 ASM_MESON_TAC[HAS_SIZE]);;
6522 let ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN = prove
6523 (`!s t:real^N->bool.
6524 span s PSUBSET span t
6525 ==> ?x. ~(x = vec 0) /\ x IN span t /\
6526 (!y. y IN span s ==> orthogonal x y)`,
6527 REPEAT STRIP_TAC THEN
6528 MP_TAC(ISPEC `span s:real^N->bool` ORTHOGONAL_BASIS_SUBSPACE) THEN
6529 REWRITE_TAC[SUBSPACE_SPAN] THEN
6530 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
6531 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
6532 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [PSUBSET_ALT]) THEN
6533 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
6534 (X_CHOOSE_THEN `u:real^N` STRIP_ASSUME_TAC)) THEN
6535 MP_TAC(ISPECL [`b:real^N->bool`; `{u:real^N}`] ORTHOGONAL_EXTENSION) THEN
6536 ASM_REWRITE_TAC[] THEN
6537 DISCH_THEN(X_CHOOSE_THEN `ns:real^N->bool` MP_TAC) THEN
6538 ASM_CASES_TAC `ns SUBSET (vec 0:real^N) INSERT b` THENL
6539 [DISCH_THEN(MP_TAC o AP_TERM `(IN) (u:real^N)` o CONJUNCT2) THEN
6540 SIMP_TAC[SPAN_SUPERSET; IN_UNION; IN_SING] THEN
6541 MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN
6542 SUBGOAL_THEN `~(u IN span (b UNION {vec 0:real^N}))` MP_TAC THENL
6543 [ASM_REWRITE_TAC[SET_RULE `s UNION {a} = a INSERT s`; SPAN_INSERT_0];
6544 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> ~(x IN t) ==> ~(x IN s)`) THEN
6545 MATCH_MP_TAC SPAN_MONO THEN ASM SET_TAC[]];
6547 FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
6548 `~(s SUBSET t) ==> ?z. z IN s /\ ~(z IN t)`)) THEN
6549 REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_INSERT; DE_MORGAN_THM] THEN
6550 X_GEN_TAC `n:real^N` THEN STRIP_TAC THEN
6551 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
6552 REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
6553 DISCH_THEN(MP_TAC o SPEC `n:real^N`) THEN ASM_REWRITE_TAC[IN_UNION] THEN
6554 REWRITE_TAC[IMP_IMP] THEN DISCH_TAC THEN EXISTS_TAC `n:real^N` THEN
6555 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
6556 [SUBGOAL_THEN `(n:real^N) IN span (b UNION ns)` MP_TAC THENL
6557 [MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[];
6558 ASM_REWRITE_TAC[] THEN SPEC_TAC(`n:real^N`,`n:real^N`) THEN
6559 REWRITE_TAC[GSYM SUBSET] THEN
6560 MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN REWRITE_TAC[SUBSPACE_SPAN] THEN
6561 ASM_REWRITE_TAC[SET_RULE
6562 `s UNION {a} SUBSET t <=> s SUBSET t /\ a IN t`] THEN
6563 ASM_MESON_TAC[SPAN_INC; SUBSET_TRANS]];
6564 MATCH_MP_TAC SPAN_INDUCT THEN
6565 REWRITE_TAC[SET_RULE `(\y. orthogonal n y) = {y | orthogonal n y}`] THEN
6566 REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR] THEN ASM SET_TAC[]]);;
6568 let ORTHOGONAL_TO_SUBSPACE_EXISTS = prove
6569 (`!s:real^N->bool. dim s < dimindex(:N)
6570 ==> ?x. ~(x = vec 0) /\ !y. y IN s ==> orthogonal x y`,
6571 REPEAT STRIP_TAC THEN
6572 MP_TAC(ISPECL [`s:real^N->bool`; `(:real^N)`]
6573 ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN) THEN
6574 ANTS_TAC THENL [REWRITE_TAC[PSUBSET]; MESON_TAC[SPAN_SUPERSET]] THEN
6575 REWRITE_TAC[SPAN_UNIV; SUBSET_UNIV] THEN
6576 ASM_MESON_TAC[DIM_SPAN; DIM_UNIV; LT_REFL]);;
6578 let ORTHOGONAL_TO_VECTOR_EXISTS = prove
6579 (`!x:real^N. 2 <= dimindex(:N) ==> ?y. ~(y = vec 0) /\ orthogonal x y`,
6580 REPEAT STRIP_TAC THEN
6581 MP_TAC(ISPEC `{x:real^N}` ORTHOGONAL_TO_SUBSPACE_EXISTS) THEN
6582 SIMP_TAC[DIM_SING; IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
6583 ANTS_TAC THENL [ASM_ARITH_TAC; MESON_TAC[ORTHOGONAL_SYM]]);;
6585 let SPAN_NOT_UNIV_ORTHOGONAL = prove
6586 (`!s. ~(span s = (:real^N))
6587 ==> ?a. ~(a = vec 0) /\ !x. x IN span s ==> a dot x = &0`,
6588 REWRITE_TAC[GSYM DIM_EQ_FULL; GSYM LE_ANTISYM; DIM_SUBSET_UNIV;
6590 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM orthogonal] THEN
6591 MATCH_MP_TAC ORTHOGONAL_TO_SUBSPACE_EXISTS THEN ASM_REWRITE_TAC[DIM_SPAN]);;
6593 let SPAN_NOT_UNIV_SUBSET_HYPERPLANE = prove
6594 (`!s. ~(span s = (:real^N))
6595 ==> ?a. ~(a = vec 0) /\ span s SUBSET {x | a dot x = &0}`,
6596 REWRITE_TAC[SUBSET; IN_ELIM_THM; SPAN_NOT_UNIV_ORTHOGONAL]);;
6598 let LOWDIM_SUBSET_HYPERPLANE = prove
6599 (`!s. dim s < dimindex(:N)
6600 ==> ?a:real^N. ~(a = vec 0) /\ span s SUBSET {x | a dot x = &0}`,
6601 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_NOT_UNIV_SUBSET_HYPERPLANE THEN
6602 REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET_UNIV] THEN
6603 DISCH_THEN(MP_TAC o MATCH_MP DIM_SUBSET) THEN
6604 ASM_REWRITE_TAC[NOT_LE; DIM_SPAN; DIM_UNIV]);;
6606 let VECTOR_EQ_DOT_SPAN = prove
6608 (!v. v IN b ==> v dot x = v dot y) /\ x IN span b /\ y IN span b
6610 ONCE_REWRITE_TAC[GSYM REAL_SUB_0; GSYM VECTOR_SUB_EQ] THEN
6611 REWRITE_TAC[GSYM DOT_RSUB; GSYM ORTHOGONAL_REFL; GSYM orthogonal] THEN
6612 MESON_TAC[ORTHOGONAL_TO_SPAN; SPAN_SUB; ORTHOGONAL_SYM]);;
6614 let ORTHONORMAL_BASIS_EXPAND = prove
6616 pairwise orthogonal b /\ (!v. v IN b ==> norm v = &1) /\ x IN span b
6617 ==> vsum b (\v. (v dot x) % v) = x`,
6618 REWRITE_TAC[NORM_EQ_1] THEN REPEAT STRIP_TAC THEN
6619 MATCH_MP_TAC VECTOR_EQ_DOT_SPAN THEN EXISTS_TAC `b:real^N->bool` THEN
6620 FIRST_ASSUM(ASSUME_TAC o MATCH_MP PAIRWISE_ORTHOGONAL_IMP_FINITE) THEN
6621 RULE_ASSUM_TAC(REWRITE_RULE[pairwise; orthogonal]) THEN
6622 ASM_SIMP_TAC[SPAN_VSUM; SPAN_MUL; DOT_RSUM; DOT_RMUL; SPAN_SUPERSET] THEN
6623 X_GEN_TAC `v:real^N` THEN DISCH_TAC THEN
6624 TRANS_TAC EQ_TRANS `sum b (\w:real^N. if w = v then v dot x else &0)` THEN
6625 CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[SUM_DELTA]] THEN
6626 MATCH_MP_TAC SUM_EQ THEN ASM_REWRITE_TAC[] THEN
6627 X_GEN_TAC `w:real^N` THEN DISCH_TAC THEN
6628 COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_MUL_RID; REAL_MUL_RZERO]);;
6630 (* ------------------------------------------------------------------------- *)
6631 (* Decomposing a vector into parts in orthogonal subspaces. *)
6632 (* ------------------------------------------------------------------------- *)
6634 let ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE = prove
6635 (`!s t x y x' y':real^N.
6636 (!a b. a IN s /\ b IN t ==> orthogonal a b) /\
6637 x IN span s /\ x' IN span s /\ y IN span t /\ y' IN span t /\
6639 ==> x = x' /\ y = y'`,
6640 REWRITE_TAC[VECTOR_ARITH `x + y:real^N = x' + y' <=> x - x' = y' - y`] THEN
6641 ONCE_REWRITE_TAC[GSYM ORTHOGONAL_TO_SPANS_EQ] THEN
6642 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[VECTOR_ARITH
6643 `x:real^N = x' /\ y:real^N = y' <=> x - x' = vec 0 /\ y' - y = vec 0`] THEN
6644 STRIP_TAC THEN ASM_REWRITE_TAC[GSYM ORTHOGONAL_REFL] THEN
6645 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN
6646 ASM_MESON_TAC[ORTHOGONAL_CLAUSES; ORTHOGONAL_SYM]);;
6648 let ORTHOGONAL_SUBSPACE_DECOMP_EXISTS = prove
6649 (`!s x:real^N. ?y z. y IN span s /\ (!w. w IN span s ==> orthogonal z w) /\
6651 REPEAT STRIP_TAC THEN
6652 MP_TAC(ISPEC `span s:real^N->bool` ORTHOGONAL_BASIS_SUBSPACE) THEN
6653 REWRITE_TAC[SUBSPACE_SPAN; LEFT_IMP_EXISTS_THM] THEN
6654 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
6655 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
6656 EXISTS_TAC `vsum t (\b:real^N. (b dot x) / (b dot b) % b)` THEN
6657 EXISTS_TAC `x - vsum t (\b:real^N. (b dot x) / (b dot b) % b)` THEN
6658 REPEAT CONJ_TAC THENL
6659 [MATCH_MP_TAC SPAN_VSUM THEN
6660 ASM_SIMP_TAC[INDEPENDENT_IMP_FINITE; SPAN_CLAUSES];
6661 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[ORTHOGONAL_SYM] THEN
6662 MATCH_MP_TAC GRAM_SCHMIDT_STEP THEN ASM_SIMP_TAC[];
6663 VECTOR_ARITH_TAC]);;
6665 let ORTHOGONAL_SUBSPACE_DECOMP = prove
6666 (`!s x. ?!(y,z). y IN span s /\
6667 z IN {z:real^N | !x. x IN span s ==> orthogonal z x} /\
6669 REWRITE_TAC[EXISTS_UNIQUE_DEF; IN_ELIM_THM] THEN
6670 REWRITE_TAC[EXISTS_PAIRED_THM; FORALL_PAIRED_THM] THEN
6671 REWRITE_TAC[FORALL_PAIR_THM; ORTHOGONAL_SUBSPACE_DECOMP_EXISTS] THEN
6672 REPEAT STRIP_TAC THEN REWRITE_TAC[PAIR_EQ] THEN
6673 MATCH_MP_TAC ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE THEN
6674 MAP_EVERY EXISTS_TAC
6675 [`s:real^N->bool`; `{z:real^N | !x. x IN span s ==> orthogonal z x}`] THEN
6676 ASM_SIMP_TAC[SPAN_CLAUSES; IN_ELIM_THM] THEN
6677 ASM_MESON_TAC[SPAN_CLAUSES; ORTHOGONAL_SYM]);;
6679 (* ------------------------------------------------------------------------- *)
6680 (* Existence of isometry between subspaces of same dimension. *)
6681 (* ------------------------------------------------------------------------- *)
6683 let ISOMETRY_SUBSET_SUBSPACE = prove
6684 (`!s:real^M->bool t:real^N->bool.
6685 subspace s /\ subspace t /\ dim s <= dim t
6686 ==> ?f. linear f /\ IMAGE f s SUBSET t /\
6687 (!x. x IN s ==> norm(f x) = norm(x))`,
6688 REPEAT STRIP_TAC THEN
6689 MP_TAC(ISPEC `t:real^N->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN
6690 MP_TAC(ISPEC `s:real^M->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN
6691 ASM_REWRITE_TAC[HAS_SIZE] THEN
6692 DISCH_THEN(X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC) THEN
6693 DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN
6694 MP_TAC(ISPECL [`b:real^M->bool`; `c:real^N->bool`] CARD_LE_INJ) THEN
6695 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; INJECTIVE_ON_ALT] THEN
6696 X_GEN_TAC `fb:real^M->real^N` THEN STRIP_TAC THEN
6697 MP_TAC(ISPECL [`fb:real^M->real^N`; `b:real^M->bool`]
6698 LINEAR_INDEPENDENT_EXTEND) THEN
6699 ASM_REWRITE_TAC[IMP_IMP; LEFT_AND_EXISTS_THM; INJECTIVE_ON_ALT] THEN
6700 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN
6701 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
6702 [REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN
6703 ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN
6704 REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN
6705 MATCH_MP_TAC SPAN_MONO THEN ASM SET_TAC[];
6706 UNDISCH_THEN `span b:real^M->bool = s` (SUBST1_TAC o SYM) THEN
6707 ASM_SIMP_TAC[SPAN_FINITE] THEN
6708 REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
6709 MAP_EVERY X_GEN_TAC [`z:real^M`; `u:real^M->real`] THEN
6710 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[LINEAR_VSUM] THEN
6711 REWRITE_TAC[o_DEF; NORM_EQ_SQUARE; NORM_POS_LE; GSYM NORM_POW_2] THEN
6712 ASM_SIMP_TAC[LINEAR_CMUL] THEN
6713 W(MP_TAC o PART_MATCH (lhand o rand)
6714 NORM_VSUM_PYTHAGOREAN o rand o snd) THEN
6715 W(MP_TAC o PART_MATCH (lhand o rand)
6716 NORM_VSUM_PYTHAGOREAN o lhand o rand o snd) THEN
6717 RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6718 ASM_SIMP_TAC[pairwise; ORTHOGONAL_CLAUSES] THEN ANTS_TAC THENL
6719 [REPEAT STRIP_TAC THEN REWRITE_TAC[ORTHOGONAL_MUL] THEN ASM SET_TAC[];
6720 REPEAT(DISCH_THEN SUBST1_TAC) THEN ASM_SIMP_TAC[NORM_MUL] THEN
6721 MATCH_MP_TAC SUM_EQ THEN ASM SET_TAC[]]]);;
6723 let ISOMETRIES_SUBSPACES = prove
6724 (`!s:real^M->bool t:real^N->bool.
6725 subspace s /\ subspace t /\ dim s = dim t
6726 ==> ?f g. linear f /\ linear g /\
6727 IMAGE f s = t /\ IMAGE g t = s /\
6728 (!x. x IN s ==> norm(f x) = norm x) /\
6729 (!y. y IN t ==> norm(g y) = norm y) /\
6730 (!x. x IN s ==> g(f x) = x) /\
6731 (!y. y IN t ==> f(g y) = y)`,
6732 REPEAT STRIP_TAC THEN ABBREV_TAC `n = dim(t:real^N->bool)` THEN
6733 MP_TAC(ISPEC `t:real^N->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN
6734 MP_TAC(ISPEC `s:real^M->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN
6735 ASM_REWRITE_TAC[] THEN
6736 DISCH_THEN(X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC) THEN
6737 DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN
6738 MP_TAC(ISPECL [`b:real^M->bool`; `c:real^N->bool`] CARD_EQ_BIJECTIONS) THEN
6739 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
6740 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
6741 MAP_EVERY X_GEN_TAC [`fb:real^M->real^N`; `gb:real^N->real^M`] THEN
6743 MP_TAC(ISPECL [`gb:real^N->real^M`; `c:real^N->bool`]
6744 LINEAR_INDEPENDENT_EXTEND) THEN
6745 MP_TAC(ISPECL [`fb:real^M->real^N`; `b:real^M->bool`]
6746 LINEAR_INDEPENDENT_EXTEND) THEN
6747 ASM_REWRITE_TAC[IMP_IMP; LEFT_AND_EXISTS_THM] THEN
6748 REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
6749 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN
6750 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN
6751 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
6752 [REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN
6753 ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN
6754 REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN
6755 AP_TERM_TAC THEN ASM SET_TAC[];
6756 REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN
6757 ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN
6758 REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN
6759 AP_TERM_TAC THEN ASM SET_TAC[];
6760 UNDISCH_THEN `span b:real^M->bool = s` (SUBST1_TAC o SYM) THEN
6761 ASM_SIMP_TAC[SPAN_FINITE] THEN
6762 REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
6763 MAP_EVERY X_GEN_TAC [`z:real^M`; `u:real^M->real`] THEN
6764 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[LINEAR_VSUM] THEN
6765 REWRITE_TAC[o_DEF; NORM_EQ_SQUARE; NORM_POS_LE; GSYM NORM_POW_2] THEN
6766 ASM_SIMP_TAC[LINEAR_CMUL] THEN
6767 W(MP_TAC o PART_MATCH (lhand o rand)
6768 NORM_VSUM_PYTHAGOREAN o rand o snd) THEN
6769 W(MP_TAC o PART_MATCH (lhand o rand)
6770 NORM_VSUM_PYTHAGOREAN o lhand o rand o snd) THEN
6771 RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6772 ASM_SIMP_TAC[pairwise; ORTHOGONAL_CLAUSES] THEN ANTS_TAC THENL
6773 [REPEAT STRIP_TAC THEN REWRITE_TAC[ORTHOGONAL_MUL] THEN ASM SET_TAC[];
6774 REPEAT(DISCH_THEN SUBST1_TAC) THEN
6775 ASM_SIMP_TAC[NORM_MUL]];
6776 UNDISCH_THEN `span c:real^N->bool = t` (SUBST1_TAC o SYM) THEN
6777 ASM_SIMP_TAC[SPAN_FINITE] THEN
6778 REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
6779 MAP_EVERY X_GEN_TAC [`z:real^N`; `u:real^N->real`] THEN
6780 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[LINEAR_VSUM] THEN
6781 REWRITE_TAC[o_DEF; NORM_EQ_SQUARE; NORM_POS_LE; GSYM NORM_POW_2] THEN
6782 ASM_SIMP_TAC[LINEAR_CMUL] THEN
6783 W(MP_TAC o PART_MATCH (lhand o rand)
6784 NORM_VSUM_PYTHAGOREAN o rand o snd) THEN
6785 W(MP_TAC o PART_MATCH (lhand o rand)
6786 NORM_VSUM_PYTHAGOREAN o lhand o rand o snd) THEN
6787 RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6788 ASM_SIMP_TAC[pairwise; ORTHOGONAL_CLAUSES] THEN ANTS_TAC THENL
6789 [REPEAT STRIP_TAC THEN REWRITE_TAC[ORTHOGONAL_MUL] THEN ASM SET_TAC[];
6790 REPEAT(DISCH_THEN SUBST1_TAC) THEN
6791 ASM_SIMP_TAC[NORM_MUL]];
6792 REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN
6793 MATCH_MP_TAC SPAN_INDUCT THEN
6794 CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; IN]; ALL_TAC] THEN
6795 REWRITE_TAC[subspace; IN] THEN ASM_MESON_TAC[linear; LINEAR_0];
6796 REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN
6797 MATCH_MP_TAC SPAN_INDUCT THEN
6798 CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; IN]; ALL_TAC] THEN
6799 REWRITE_TAC[subspace; IN] THEN ASM_MESON_TAC[linear; LINEAR_0]]);;
6801 let ISOMETRY_SUBSPACES = prove
6802 (`!s:real^M->bool t:real^N->bool.
6803 subspace s /\ subspace t /\ dim s = dim t
6804 ==> ?f:real^M->real^N. linear f /\ IMAGE f s = t /\
6805 (!x. x IN s ==> norm(f x) = norm(x))`,
6807 DISCH_THEN(MP_TAC o MATCH_MP ISOMETRIES_SUBSPACES) THEN
6808 MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]);;
6810 let ISOMETRY_UNIV_SUBSPACE = prove
6811 (`!s. subspace s /\ dimindex(:M) = dim s
6812 ==> ?f:real^M->real^N.
6813 linear f /\ IMAGE f (:real^M) = s /\
6814 (!x. norm(f x) = norm(x))`,
6815 REPEAT STRIP_TAC THEN
6816 MP_TAC(ISPECL [`(:real^M)`; `s:real^N->bool`] ISOMETRY_SUBSPACES) THEN
6817 ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV; DIM_UNIV]);;
6819 let ISOMETRY_UNIV_SUPERSET_SUBSPACE = prove
6820 (`!s. subspace s /\ dim s <= dimindex(:M) /\ dimindex(:M) <= dimindex(:N)
6821 ==> ?f:real^M->real^N.
6822 linear f /\ s SUBSET (IMAGE f (:real^M)) /\
6823 (!x. norm(f x) = norm(x))`,
6824 GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
6825 FIRST_ASSUM(MP_TAC o MATCH_MP LOWDIM_EXPAND_DIMENSION) THEN
6826 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
6827 MP_TAC(ISPECL [`(:real^M)`; `span t:real^N->bool`] ISOMETRY_SUBSPACES) THEN
6828 ASM_REWRITE_TAC[SUBSPACE_SPAN; SUBSPACE_UNIV; DIM_UNIV; DIM_SPAN] THEN
6829 MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[IN_UNIV] THEN
6830 ASM_MESON_TAC[SUBSET; SPAN_INC]);;
6832 let ISOMETRY_UNIV_UNIV = prove
6833 (`dimindex(:M) <= dimindex(:N)
6834 ==> ?f:real^M->real^N. linear f /\ (!x. norm(f x) = norm(x))`,
6836 MP_TAC(ISPEC `{vec 0:real^N}`ISOMETRY_UNIV_SUPERSET_SUBSPACE) THEN
6837 ASM_REWRITE_TAC[SUBSPACE_TRIVIAL] THEN
6838 ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
6839 MATCH_MP_TAC(ARITH_RULE `x = 0 /\ 1 <= y ==> x <= y`) THEN
6840 ASM_REWRITE_TAC[DIM_EQ_0; DIMINDEX_GE_1] THEN SET_TAC[]);;
6842 let SUBSPACE_ISOMORPHISM = prove
6843 (`!s t. subspace s /\ subspace t /\ dim(s) = dim(t)
6844 ==> ?f:real^M->real^N.
6845 linear f /\ (IMAGE f s = t) /\
6846 (!x y. x IN s /\ y IN s /\ f x = f y ==> (x = y))`,
6847 REPEAT GEN_TAC THEN DISCH_TAC THEN
6848 FIRST_ASSUM(MP_TAC o MATCH_MP ISOMETRY_SUBSPACES) THEN
6849 MATCH_MP_TAC MONO_EXISTS THEN
6850 ASM_SIMP_TAC[LINEAR_INJECTIVE_0_SUBSPACE] THEN MESON_TAC[NORM_EQ_0]);;
6852 let ISOMORPHISMS_UNIV_UNIV = prove
6853 (`dimindex(:M) = dimindex(:N)
6854 ==> ?f:real^M->real^N g.
6855 linear f /\ linear g /\
6856 (!x. norm(f x) = norm x) /\ (!y. norm(g y) = norm y) /\
6857 (!x. g(f x) = x) /\ (!y. f(g y) = y)`,
6858 REPEAT STRIP_TAC THEN
6859 EXISTS_TAC `(\x. lambda i. x$i):real^M->real^N` THEN
6860 EXISTS_TAC `(\x. lambda i. x$i):real^N->real^M` THEN
6861 SIMP_TAC[vector_norm; dot; LAMBDA_BETA] THEN
6862 SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
6864 FIRST_ASSUM SUBST1_TAC THEN SIMP_TAC[LAMBDA_BETA] THEN
6865 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN SIMP_TAC[LAMBDA_BETA]);;
6867 (* ------------------------------------------------------------------------- *)
6868 (* Properties of special hyperplanes. *)
6869 (* ------------------------------------------------------------------------- *)
6871 let SUBSPACE_HYPERPLANE = prove
6872 (`!a. subspace {x:real^N | a dot x = &0}`,
6873 SIMP_TAC[subspace; DOT_RADD; DOT_RMUL; IN_ELIM_THM; REAL_ADD_LID;
6874 REAL_MUL_RZERO; DOT_RZERO]);;
6876 let SUBSPACE_SPECIAL_HYPERPLANE = prove
6877 (`!k. subspace {x:real^N | x$k = &0}`,
6878 SIMP_TAC[subspace; IN_ELIM_THM; VEC_COMPONENT;
6879 VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN REAL_ARITH_TAC);;
6881 let SPECIAL_HYPERPLANE_SPAN = prove
6882 (`!k. 1 <= k /\ k <= dimindex(:N)
6883 ==> {x:real^N | x$k = &0} =
6884 span(IMAGE basis ((1..dimindex(:N)) DELETE k))`,
6885 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC SPAN_SUBSPACE THEN
6886 ASM_SIMP_TAC[SUBSPACE_SPECIAL_HYPERPLANE] THEN CONJ_TAC THENL
6887 [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
6888 ASM_SIMP_TAC[BASIS_COMPONENT; IN_DELETE];
6889 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
6890 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
6891 GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN
6892 SIMP_TAC[SPAN_FINITE; FINITE_IMAGE; FINITE_DELETE; FINITE_NUMSEG] THEN
6893 REWRITE_TAC[IN_ELIM_THM] THEN
6894 EXISTS_TAC `\v:real^N. x dot v` THEN
6895 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhs o snd) THEN
6897 [REWRITE_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_NUMSEG; IN_DELETE] THEN
6898 MESON_TAC[BASIS_INJ];
6899 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[o_DEF] THEN
6900 ASM_SIMP_TAC[VSUM_DELETE; FINITE_NUMSEG; IN_NUMSEG; DOT_BASIS] THEN
6901 REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_SUB_RZERO]]]);;
6903 let DIM_SPECIAL_HYPERPLANE = prove
6904 (`!k. 1 <= k /\ k <= dimindex(:N)
6905 ==> dim {x:real^N | x$k = &0} = dimindex(:N) - 1`,
6906 SIMP_TAC[SPECIAL_HYPERPLANE_SPAN] THEN REPEAT STRIP_TAC THEN
6907 MATCH_MP_TAC DIM_UNIQUE THEN
6908 EXISTS_TAC `IMAGE (basis:num->real^N) ((1..dimindex(:N)) DELETE k)` THEN
6909 REWRITE_TAC[SUBSET_REFL; SPAN_INC] THEN CONJ_TAC THENL
6910 [MATCH_MP_TAC INDEPENDENT_MONO THEN
6911 EXISTS_TAC `{basis i:real^N | 1 <= i /\ i <= dimindex(:N)}` THEN
6912 REWRITE_TAC[INDEPENDENT_STDBASIS; SUBSET; FORALL_IN_IMAGE] THEN
6913 REWRITE_TAC[IN_DELETE; IN_NUMSEG; IN_ELIM_THM] THEN MESON_TAC[];
6914 MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN CONJ_TAC THENL
6915 [REWRITE_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_NUMSEG; IN_DELETE] THEN
6916 MESON_TAC[BASIS_INJ];
6917 ASM_SIMP_TAC[HAS_SIZE; FINITE_DELETE; FINITE_NUMSEG; CARD_DELETE;
6918 FINITE_IMAGE; IN_NUMSEG; CARD_NUMSEG_1]]]);;
6920 (* ------------------------------------------------------------------------- *)
6921 (* More theorems about dimensions of different subspaces. *)
6922 (* ------------------------------------------------------------------------- *)
6924 let DIM_IMAGE_KERNEL_GEN = prove
6925 (`!f:real^M->real^N s.
6926 linear f /\ subspace s
6927 ==> dim(IMAGE f s) + dim {x | x IN s /\ f x = vec 0} = dim(s)`,
6928 REPEAT STRIP_TAC THEN MP_TAC
6929 (ISPEC `{x | x IN s /\ (f:real^M->real^N) x = vec 0}` BASIS_EXISTS) THEN
6930 DISCH_THEN(X_CHOOSE_THEN `v:real^M->bool` STRIP_ASSUME_TAC) THEN
6931 MP_TAC(ISPECL [`v:real^M->bool`; `s:real^M->bool`]
6932 MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
6933 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
6934 DISCH_THEN(X_CHOOSE_THEN `w:real^M->bool` STRIP_ASSUME_TAC) THEN
6935 SUBGOAL_THEN `span(w:real^M->bool) = s`
6936 (fun th -> GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [SYM th] THEN
6938 THENL [ASM_SIMP_TAC[SPAN_SUBSPACE]; ALL_TAC] THEN
6939 SUBGOAL_THEN `subspace {x | x IN s /\ (f:real^M->real^N) x = vec 0}`
6941 [REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
6942 ASM_SIMP_TAC[SUBSPACE_INTER; SUBSPACE_KERNEL];
6944 SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x = vec 0} = span v`
6946 [ASM_MESON_TAC[SUBSET_ANTISYM; SPAN_SUBSET_SUBSPACE; SUBSPACE_KERNEL];
6948 ASM_SIMP_TAC[DIM_SPAN; DIM_EQ_CARD] THEN
6950 `!x. x IN span(w DIFF v) /\ (f:real^M->real^N) x = vec 0 ==> x = vec 0`
6951 (LABEL_TAC "*") THENL
6952 [MATCH_MP_TAC(SET_RULE
6953 `!t. s SUBSET t /\ (!x. x IN s /\ x IN t /\ P x ==> Q x)
6954 ==> (!x. x IN s /\ P x ==> Q x)`) THEN
6955 EXISTS_TAC `s:real^M->bool` THEN CONJ_TAC THENL
6956 [ASM_MESON_TAC[SPAN_MONO; SUBSET_DIFF]; ALL_TAC] THEN
6957 ASM_SIMP_TAC[SPAN_FINITE; IN_ELIM_THM; IMP_CONJ; FINITE_DIFF;
6958 INDEPENDENT_IMP_FINITE; LEFT_IMP_EXISTS_THM] THEN
6959 GEN_TAC THEN X_GEN_TAC `u:real^M->real` THEN
6960 DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[IMP_IMP] THEN
6961 ONCE_REWRITE_TAC[SET_RULE
6962 `y IN s /\ f y = a <=> y IN {x | x IN s /\ f x = a}`] THEN
6963 ASM_REWRITE_TAC[] THEN
6964 ASM_SIMP_TAC[SPAN_FINITE; INDEPENDENT_IMP_FINITE; IN_ELIM_THM] THEN
6965 DISCH_THEN(X_CHOOSE_TAC `t:real^M->real`) THEN
6966 MP_TAC(ISPEC `w:real^M->bool` INDEPENDENT_EXPLICIT) THEN
6967 ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6968 DISCH_THEN(MP_TAC o SPEC
6969 `(\x. if x IN w DIFF v then --u x else t x):real^M->real`) THEN
6970 ASM_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN
6971 ASM_SIMP_TAC[VSUM_CASES; INDEPENDENT_IMP_FINITE] THEN
6972 REWRITE_TAC[SET_RULE `{x | x IN w /\ x IN (w DIFF v)} = w DIFF v`] THEN
6973 SIMP_TAC[ASSUME `(v:real^M->bool) SUBSET w`; SET_RULE
6974 `v SUBSET w ==> {x | x IN w /\ ~(x IN (w DIFF v))} = v`] THEN
6975 ASM_REWRITE_TAC[VECTOR_MUL_LNEG; VSUM_NEG; VECTOR_ADD_LINV] THEN
6976 DISCH_THEN(fun th -> MATCH_MP_TAC VSUM_EQ_0 THEN MP_TAC th) THEN
6977 REWRITE_TAC[REAL_NEG_EQ_0; VECTOR_MUL_EQ_0; IN_DIFF] THEN MESON_TAC[];
6979 SUBGOAL_THEN `!x y. x IN (w DIFF v) /\ y IN (w DIFF v) /\
6980 (f:real^M->real^N) x = f y ==> x = y`
6982 [REMOVE_THEN "*" MP_TAC THEN
6983 ASM_SIMP_TAC[GSYM LINEAR_INJECTIVE_0_SUBSPACE; SUBSPACE_SPAN] THEN
6984 MP_TAC(ISPEC `w DIFF v:real^M->bool` SPAN_INC) THEN SET_TAC[];
6986 SUBGOAL_THEN `IMAGE (f:real^M->real^N) s = span(IMAGE f (w DIFF v))`
6988 [MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
6990 ASM_MESON_TAC[SUBSPACE_LINEAR_IMAGE; SPAN_MONO; IMAGE_SUBSET;
6991 SUBSET_TRANS; SUBSET_DIFF; SPAN_EQ_SELF]] THEN
6992 SIMP_TAC[SUBSET; FORALL_IN_IMAGE] THEN X_GEN_TAC `x:real^M` THEN
6993 DISCH_TAC THEN UNDISCH_TAC `span w:real^M->bool = s` THEN
6994 REWRITE_TAC[EXTENSION] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
6995 ASM_REWRITE_TAC[] THEN
6996 REMOVE_THEN "*" (MP_TAC o SPEC `x:real^M`) THEN
6997 (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 4)
6998 [IN_UNIV; SPAN_FINITE; INDEPENDENT_IMP_FINITE; IN_ELIM_THM;
6999 FINITE_IMAGE; FINITE_DIFF; ASSUME `independent(w:real^M->bool)`] THEN
7000 REWRITE_TAC[IMP_CONJ; LEFT_IMP_EXISTS_THM] THEN DISCH_TAC THEN
7001 X_GEN_TAC `u:real^M->real` THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
7002 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
7003 DISCH_THEN(X_CHOOSE_TAC `g:real^N->real^M`) THEN
7004 EXISTS_TAC `(u:real^M->real) o (g:real^N->real^M)` THEN
7005 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN
7006 ASM_REWRITE_TAC[] THEN
7007 ASM_SIMP_TAC[FINITE_DIFF; INDEPENDENT_IMP_FINITE; LINEAR_VSUM] THEN
7008 DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[o_DEF] THEN
7009 CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_EQ_SUPERSET THEN
7010 SIMP_TAC[SUBSET_DIFF; FINITE_DIFF; INDEPENDENT_IMP_FINITE;
7011 LINEAR_CMUL; IN_DIFF; TAUT `a /\ ~(a /\ ~b) <=> a /\ b`;
7012 ASSUME `independent(w:real^M->bool)`;
7013 ASSUME `linear(f:real^M->real^N)`] THEN
7014 REWRITE_TAC[VECTOR_MUL_EQ_0] THEN ASM SET_TAC[];
7015 SUBGOAL_THEN `independent(IMAGE (f:real^M->real^N) (w DIFF v))`
7017 [MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN
7018 ASM_SIMP_TAC[LINEAR_INJECTIVE_0_SUBSPACE; SUBSPACE_SPAN] THEN
7019 ASM_MESON_TAC[INDEPENDENT_MONO; SUBSET_DIFF];
7020 ASM_SIMP_TAC[DIM_SPAN; DIM_EQ_CARD] THEN
7021 W(MP_TAC o PART_MATCH (lhs o rand) CARD_IMAGE_INJ o
7022 lhand o lhand o snd) THEN
7023 ASM_REWRITE_TAC[] THEN
7024 ASM_SIMP_TAC[FINITE_DIFF; CARD_DIFF; INDEPENDENT_IMP_FINITE] THEN
7025 DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC SUB_ADD THEN
7026 ASM_MESON_TAC[CARD_SUBSET; INDEPENDENT_IMP_FINITE]]]);;
7028 let DIM_IMAGE_KERNEL = prove
7029 (`!f:real^M->real^N.
7031 ==> dim(IMAGE f (:real^M)) + dim {x | f x = vec 0} = dimindex(:M)`,
7032 REPEAT STRIP_TAC THEN
7033 MP_TAC(ISPECL [`f:real^M->real^N`; `(:real^M)`] DIM_IMAGE_KERNEL_GEN) THEN
7034 ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV; DIM_UNIV]);;
7036 let DIM_SUMS_INTER = prove
7037 (`!s t:real^N->bool.
7038 subspace s /\ subspace t
7039 ==> dim {x + y | x IN s /\ y IN t} + dim(s INTER t) = dim(s) + dim(t)`,
7040 REPEAT STRIP_TAC THEN
7041 MP_TAC(ISPEC `s INTER t:real^N->bool` BASIS_EXISTS) THEN
7042 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
7043 MP_TAC(ISPECL [`b:real^N->bool`; `s:real^N->bool`]
7044 MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
7045 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7046 DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN
7047 MP_TAC(ISPECL [`b:real^N->bool`; `t:real^N->bool`]
7048 MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
7049 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7050 DISCH_THEN(X_CHOOSE_THEN `d:real^N->bool` STRIP_ASSUME_TAC) THEN
7051 SUBGOAL_THEN `(c:real^N->bool) INTER d = b` ASSUME_TAC THENL
7052 [MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[SUBSET_INTER] THEN
7053 REWRITE_TAC[SUBSET; IN_INTER] THEN X_GEN_TAC `x:real^N` THEN
7054 STRIP_TAC THEN MP_TAC(ISPEC `c:real^N->bool` independent) THEN
7055 ASM_REWRITE_TAC[dependent; NOT_EXISTS_THM] THEN
7056 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
7057 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN STRIP_TAC THEN
7059 SUBGOAL_THEN `(x:real^N) IN span b` MP_TAC THENL
7060 [ASM_MESON_TAC[SUBSET; IN_INTER; SPAN_INC];
7061 MP_TAC(ISPECL [`b:real^N->bool`; `c DELETE (x:real^N)`] SPAN_MONO) THEN
7065 `dim (s INTER t:real^N->bool) = CARD(b:real^N->bool) /\
7066 dim s = CARD c /\ dim t = CARD d /\
7067 dim {x + y:real^N | x IN s /\ y IN t} = CARD(c UNION d:real^N->bool)`
7068 (REPEAT_TCL CONJUNCTS_THEN SUBST1_TAC) THENL
7070 ASM_SIMP_TAC[CARD_UNION_GEN; INDEPENDENT_IMP_FINITE] THEN
7071 MATCH_MP_TAC(ARITH_RULE `b:num <= c ==> (c + d) - b + b = c + d`) THEN
7072 ASM_SIMP_TAC[CARD_SUBSET; INDEPENDENT_IMP_FINITE]] THEN
7073 REPEAT CONJ_TAC THEN MATCH_MP_TAC DIM_UNIQUE THENL
7074 [EXISTS_TAC `b:real^N->bool`;
7075 EXISTS_TAC `c:real^N->bool`;
7076 EXISTS_TAC `d:real^N->bool`;
7077 EXISTS_TAC `c UNION d:real^N->bool`] THEN
7078 ASM_SIMP_TAC[HAS_SIZE; INDEPENDENT_IMP_FINITE; FINITE_UNION] THEN
7079 REWRITE_TAC[UNION_SUBSET; GSYM CONJ_ASSOC] THEN
7080 REWRITE_TAC[SUBSET; IN_ELIM_THM; FORALL_IN_GSPEC] THEN REPEAT CONJ_TAC THENL
7081 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7082 MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN
7083 ASM_SIMP_TAC[SUBSPACE_0; VECTOR_ADD_RID] THEN ASM SET_TAC[];
7084 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7085 MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `x:real^N`] THEN
7086 ASM_SIMP_TAC[SUBSPACE_0; VECTOR_ADD_LID] THEN ASM SET_TAC[];
7087 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
7088 MATCH_MP_TAC SPAN_ADD THEN CONJ_TAC THENL
7089 [MP_TAC(ISPECL[`c:real^N->bool`; `c UNION d:real^N->bool`] SPAN_MONO);
7090 MP_TAC(ISPECL[`d:real^N->bool`; `c UNION d:real^N->bool`] SPAN_MONO)] THEN
7091 REWRITE_TAC[SUBSET_UNION] THEN REWRITE_TAC[SUBSET] THEN
7092 DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[];
7094 ASM_SIMP_TAC[INDEPENDENT_EXPLICIT; FINITE_UNION; INDEPENDENT_IMP_FINITE] THEN
7095 X_GEN_TAC `a:real^N->real` THEN
7096 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
7097 [SET_RULE `s UNION t = s UNION (t DIFF s)`] THEN
7098 ASM_SIMP_TAC[VSUM_UNION; SET_RULE `DISJOINT c (d DIFF c)`;
7099 INDEPENDENT_IMP_FINITE; FINITE_DIFF; FINITE_UNION] THEN
7102 `(vsum (d DIFF c) (\v:real^N. a v % v)) IN span b`
7104 [FIRST_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
7105 REWRITE_TAC[IN_INTER] THEN CONJ_TAC THENL
7106 [FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (VECTOR_ARITH
7107 `a + b = vec 0 ==> b = --a`)) THEN
7108 MATCH_MP_TAC SUBSPACE_NEG THEN ASM_REWRITE_TAC[];
7110 MATCH_MP_TAC SUBSPACE_VSUM THEN
7111 ASM_SIMP_TAC[FINITE_DIFF; INDEPENDENT_IMP_FINITE] THEN
7112 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSPACE_MUL THEN
7113 ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
7115 ASM_SIMP_TAC[SPAN_FINITE; INDEPENDENT_IMP_FINITE; IN_ELIM_THM] THEN
7116 DISCH_THEN(X_CHOOSE_TAC `e:real^N->real`) THEN
7117 MP_TAC(ISPEC `c:real^N->bool` INDEPENDENT_EXPLICIT) THEN
7118 ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
7119 (MP_TAC o SPEC `(\x. if x IN b then a x + e x else a x):real^N->real`)) THEN
7120 REWRITE_TAC[] THEN ONCE_REWRITE_TAC[COND_RAND] THEN
7121 ONCE_REWRITE_TAC[COND_RATOR] THEN ASM_SIMP_TAC[VSUM_CASES] THEN
7122 REWRITE_TAC[VECTOR_ADD_RDISTRIB; GSYM DIFF] THEN
7123 ASM_SIMP_TAC[SET_RULE `b SUBSET c ==> {x | x IN c /\ x IN b} = b`] THEN
7124 ASM_SIMP_TAC[VSUM_ADD; INDEPENDENT_IMP_FINITE] THEN
7125 ONCE_REWRITE_TAC[VECTOR_ARITH `(a + b) + c:real^N = (a + c) + b`] THEN
7126 ASM_SIMP_TAC[GSYM VSUM_UNION; FINITE_DIFF; INDEPENDENT_IMP_FINITE;
7127 SET_RULE `DISJOINT b (c DIFF b)`] THEN
7128 ASM_SIMP_TAC[SET_RULE `b SUBSET c ==> b UNION (c DIFF b) = c`] THEN
7130 SUBGOAL_THEN `!v:real^N. v IN (c DIFF b) ==> a v = &0` ASSUME_TAC THENL
7131 [ASM SET_TAC[]; ALL_TAC] THEN
7132 MP_TAC(ISPEC `d:real^N->bool` INDEPENDENT_EXPLICIT) THEN
7133 ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
7134 (MP_TAC o SPEC `a:real^N->real`)) THEN
7135 SUBGOAL_THEN `d:real^N->bool = b UNION (d DIFF c)`
7136 (fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [th])
7137 THENL [ASM SET_TAC[]; ALL_TAC] THEN
7138 ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
7139 ASM_SIMP_TAC[VSUM_UNION; FINITE_DIFF; INDEPENDENT_IMP_FINITE;
7140 SET_RULE `c INTER d = b ==> DISJOINT b (d DIFF c)`] THEN
7141 SUBGOAL_THEN `vsum b (\x:real^N. a x % x) = vsum c (\x. a x % x)`
7142 (fun th -> ASM_REWRITE_TAC[th]) THEN
7143 CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN
7144 ASM_SIMP_TAC[VECTOR_MUL_EQ_0] THEN ASM_MESON_TAC[]);;
7146 let DIM_KERNEL_COMPOSE = prove
7147 (`!f:real^M->real^N g:real^N->real^P.
7148 linear f /\ linear g
7149 ==> dim {x | (g o f) x = vec 0} <=
7150 dim {x | f(x) = vec 0} +
7151 dim {y | g(y) = vec 0}`,
7152 REPEAT STRIP_TAC THEN
7153 MP_TAC(ISPEC `{x | (f:real^M->real^N) x = vec 0}` BASIS_EXISTS_FINITE) THEN
7154 DISCH_THEN(X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC) THEN
7157 IMAGE f c SUBSET {y | g(y):real^P = vec 0} /\
7158 independent (IMAGE (f:real^M->real^N) c) /\
7159 IMAGE f (:real^M) INTER {y | g(y) = vec 0} SUBSET span(IMAGE f c) /\
7160 (!x y. x IN c /\ y IN c ==> (f x = f y <=> x = y)) /\
7161 (IMAGE f c) HAS_SIZE dim (IMAGE f (:real^M) INTER {y | g(y) = vec 0})`
7162 STRIP_ASSUME_TAC THENL
7163 [MP_TAC(ISPEC `IMAGE (f:real^M->real^N) (:real^M) INTER
7164 {x | (g:real^N->real^P) x = vec 0}` BASIS_EXISTS_FINITE) THEN
7165 REWRITE_TAC[SUBSET_INTER; GSYM CONJ_ASSOC; EXISTS_FINITE_SUBSET_IMAGE] THEN
7166 DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN
7167 MP_TAC(ISPECL [`f:real^M->real^N`; `c:real^M->bool`]
7168 IMAGE_INJECTIVE_IMAGE_OF_SUBSET) THEN
7169 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->bool` THEN
7170 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
7171 (CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC)) THEN
7172 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[FINITE_SUBSET];
7174 MATCH_MP_TAC LE_TRANS THEN
7175 EXISTS_TAC `dim(span(b UNION c:real^M->bool))` THEN CONJ_TAC THENL
7176 [MATCH_MP_TAC DIM_SUBSET THEN
7177 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; o_THM] THEN
7178 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
7179 SUBGOAL_THEN `(f:real^M->real^N) x IN span(IMAGE f c)` MP_TAC THENL
7180 [ASM SET_TAC[]; ALL_TAC] THEN
7181 ASM_SIMP_TAC[SPAN_LINEAR_IMAGE; IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN
7182 X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN
7183 SUBST1_TAC(VECTOR_ARITH `x:real^M = y + (x - y)`) THEN
7184 MATCH_MP_TAC SPAN_ADD THEN CONJ_TAC THENL
7185 [ASM_MESON_TAC[SUBSET_UNION; SPAN_MONO; SUBSET]; ALL_TAC] THEN
7186 MATCH_MP_TAC(SET_RULE
7187 `!t. x IN t /\ t SUBSET s ==> x IN s`) THEN
7188 EXISTS_TAC `{x | (f:real^M->real^N) x = vec 0}` THEN CONJ_TAC THENL
7189 [REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[LINEAR_SUB; VECTOR_SUB_EQ];
7190 ASM_MESON_TAC[SUBSET_TRANS; SUBSET_UNION; SPAN_MONO]];
7191 REWRITE_TAC[DIM_SPAN] THEN MATCH_MP_TAC LE_TRANS THEN
7192 EXISTS_TAC `CARD(b UNION c:real^M->bool)` THEN
7193 ASM_SIMP_TAC[DIM_LE_CARD; FINITE_UNION; INDEPENDENT_IMP_FINITE] THEN
7194 MATCH_MP_TAC LE_TRANS THEN
7195 EXISTS_TAC `CARD(b:real^M->bool) + CARD(c:real^M->bool)` THEN
7196 ASM_SIMP_TAC[CARD_UNION_LE] THEN MATCH_MP_TAC LE_ADD2 THEN CONJ_TAC THENL
7197 [ASM_SIMP_TAC[GSYM DIM_EQ_CARD; DIM_SUBSET]; ALL_TAC] THEN
7198 MATCH_MP_TAC LE_TRANS THEN
7199 EXISTS_TAC `dim(IMAGE (f:real^M->real^N) c)` THEN CONJ_TAC THENL
7200 [ASM_SIMP_TAC[DIM_EQ_CARD] THEN
7201 ASM_MESON_TAC[CARD_IMAGE_INJ; LE_REFL];
7202 ASM_SIMP_TAC[GSYM DIM_EQ_CARD; DIM_SUBSET]]]);;
7204 let DIM_ORTHOGONAL_SUM = prove
7205 (`!s t:real^N->bool.
7206 (!x y. x IN s /\ y IN t ==> x dot y = &0)
7207 ==> dim(s UNION t) = dim(s) + dim(t)`,
7208 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
7209 REWRITE_TAC[SPAN_UNION] THEN
7210 SIMP_TAC[GSYM DIM_SUMS_INTER; SUBSPACE_SPAN] THEN
7211 REWRITE_TAC[ARITH_RULE `x = x + y <=> y = 0`] THEN
7212 REWRITE_TAC[DIM_EQ_0; SUBSET; IN_INTER] THEN
7214 `!x:real^N. x IN span s ==> !y:real^N. y IN span t ==> x dot y = &0`
7216 [MATCH_MP_TAC SPAN_INDUCT THEN CONJ_TAC THENL
7217 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
7218 MATCH_MP_TAC SPAN_INDUCT THEN ASM_SIMP_TAC[IN_ELIM_THM] THEN
7219 SIMP_TAC[subspace; IN_ELIM_THM; DOT_RMUL; DOT_RADD; DOT_RZERO] THEN
7221 SIMP_TAC[subspace; IN_ELIM_THM; DOT_LMUL; DOT_LADD; DOT_LZERO] THEN
7223 REWRITE_TAC[IN_SING] THEN MESON_TAC[DOT_EQ_0]]);;
7225 let DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS = prove
7226 (`!s t:real^N->bool.
7227 subspace s /\ subspace t /\ s SUBSET t
7228 ==> dim {y | y IN t /\ !x. x IN s ==> orthogonal x y} + dim s = dim t`,
7229 REPEAT STRIP_TAC THEN
7230 W(MP_TAC o PART_MATCH (rand o rand) DIM_ORTHOGONAL_SUM o lhand o snd) THEN
7232 [SIMP_TAC[IN_ELIM_THM; orthogonal] THEN MESON_TAC[DOT_SYM];
7233 DISCH_THEN(SUBST1_TAC o SYM)] THEN
7234 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN AP_TERM_TAC THEN
7235 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
7236 [MATCH_MP_TAC SPAN_MONO THEN ASM SET_TAC[]; ALL_TAC] THEN
7237 MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN REWRITE_TAC[SUBSPACE_SPAN] THEN
7238 REWRITE_TAC[SPAN_UNION; SUBSET; IN_ELIM_THM] THEN
7239 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7240 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
7241 MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`]
7242 ORTHOGONAL_SUBSPACE_DECOMP_EXISTS) THEN
7243 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN
7244 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^N` THEN
7245 STRIP_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_SYM] THEN
7246 MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL
7247 [FIRST_ASSUM(SUBST1_TAC o MATCH_MP (VECTOR_ARITH
7248 `x:real^N = y + z ==> z = x - y`)) THEN
7249 MATCH_MP_TAC SUBSPACE_SUB THEN
7250 ASM_MESON_TAC[SUBSET; SPAN_EQ_SELF];
7251 ASM_MESON_TAC[SPAN_SUPERSET; ORTHOGONAL_SYM]]);;
7253 let DIM_SPECIAL_SUBSPACE = prove
7254 (`!k. dim {x:real^N |
7255 !i. 1 <= i /\ i <= dimindex(:N) /\ i IN k ==> x$i = &0} =
7256 CARD((1..dimindex(:N)) DIFF k)`,
7257 GEN_TAC THEN MATCH_MP_TAC DIM_UNIQUE THEN
7258 EXISTS_TAC `IMAGE (basis:num->real^N) ((1..dimindex(:N)) DIFF k)` THEN
7259 REPEAT CONJ_TAC THENL
7260 [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
7261 SIMP_TAC[BASIS_COMPONENT; IN_DIFF; IN_NUMSEG] THEN MESON_TAC[];
7262 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN X_GEN_TAC `x:real^N` THEN
7263 DISCH_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN
7264 MATCH_MP_TAC SPAN_VSUM THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
7265 X_GEN_TAC `j:num` THEN STRIP_TAC THEN
7266 ASM_CASES_TAC `(x:real^N)$j = &0` THEN
7267 ASM_REWRITE_TAC[SPAN_0; VECTOR_MUL_LZERO] THEN
7268 MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN
7269 REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `j:num` THEN
7270 REWRITE_TAC[IN_NUMSEG; IN_DIFF] THEN ASM_MESON_TAC[];
7271 MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN
7272 REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM;
7273 SET_RULE `~(a IN IMAGE f s) <=> (!x. x IN s ==> ~(f x = a))`] THEN
7274 SIMP_TAC[FORALL_IN_IMAGE; ORTHOGONAL_BASIS_BASIS; BASIS_INJ_EQ;
7275 IN_DIFF; IN_NUMSEG; BASIS_NONZERO];
7276 SIMP_TAC[HAS_SIZE; FINITE_IMAGE; FINITE_DIFF; FINITE_NUMSEG] THEN
7277 MATCH_MP_TAC CARD_IMAGE_INJ THEN
7278 SIMP_TAC[FINITE_DIFF; FINITE_NUMSEG; IMP_CONJ; RIGHT_FORALL_IMP_THM;
7279 SET_RULE `~(a IN IMAGE f s) <=> (!x. x IN s ==> ~(f x = a))`] THEN
7280 SIMP_TAC[FORALL_IN_IMAGE; ORTHOGONAL_BASIS_BASIS; BASIS_INJ_EQ;
7281 IN_DIFF; IN_NUMSEG; BASIS_NONZERO]]);;
7283 (* ------------------------------------------------------------------------- *)
7284 (* More about product spaces. *)
7285 (* ------------------------------------------------------------------------- *)
7287 let PASTECART_AS_ORTHOGONAL_SUM = prove
7288 (`!x:real^M y:real^N.
7289 pastecart x y = pastecart x (vec 0) + pastecart (vec 0) y`,
7290 REWRITE_TAC[PASTECART_ADD; VECTOR_ADD_LID; VECTOR_ADD_RID]);;
7292 let PCROSS_AS_ORTHOGONAL_SUM = prove
7293 (`!s:real^M->bool t:real^N->bool.
7295 {u + v | u IN IMAGE (\x. pastecart x (vec 0)) s /\
7296 v IN IMAGE (\y. pastecart (vec 0) y) t}`,
7297 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN
7298 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
7299 [PASTECART_AS_ORTHOGONAL_SUM] THEN
7302 let DIM_PCROSS = prove
7303 (`!s:real^M->bool t:real^N->bool.
7304 subspace s /\ subspace t ==> dim(s PCROSS t) = dim s + dim t`,
7305 REPEAT STRIP_TAC THEN REWRITE_TAC[PCROSS_AS_ORTHOGONAL_SUM] THEN
7306 W(MP_TAC o PART_MATCH (lhand o lhand o rand) DIM_SUMS_INTER o
7309 [CONJ_TAC THEN MATCH_MP_TAC SUBSPACE_LINEAR_IMAGE;
7310 MATCH_MP_TAC(ARITH_RULE `c = d /\ b = 0 ==> a + b = c ==> a = d`) THEN
7312 [BINOP_TAC THEN MATCH_MP_TAC DIM_INJECTIVE_LINEAR_IMAGE THEN
7313 SIMP_TAC[PASTECART_INJ];
7314 REWRITE_TAC[DIM_EQ_0; SUBSET; IN_INTER; IN_IMAGE; IN_SING] THEN
7315 REWRITE_TAC[PASTECART_EQ; FSTCART_PASTECART; SNDCART_PASTECART] THEN
7316 MESON_TAC[FSTCART_VEC; SNDCART_VEC]]] THEN
7317 ASM_REWRITE_TAC[linear; GSYM PASTECART_VEC] THEN
7318 REWRITE_TAC[PASTECART_ADD; GSYM PASTECART_CMUL; PASTECART_INJ] THEN
7321 let SPAN_PCROSS_SUBSET = prove
7322 (`!s:real^M->bool t:real^N->bool.
7323 span(s PCROSS t) SUBSET (span s) PCROSS (span t)`,
7324 REPEAT GEN_TAC THEN MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
7325 SIMP_TAC[SUBSPACE_PCROSS; SUBSPACE_SPAN; PCROSS_MONO; SPAN_INC]);;
7327 let SPAN_PCROSS = prove
7328 (`!s:real^M->bool t:real^N->bool.
7329 ~(s = {}) /\ ~(t = {}) /\ (vec 0 IN s \/ vec 0 IN t)
7330 ==> span(s PCROSS t) = (span s) PCROSS (span t)`,
7331 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
7332 REWRITE_TAC[SPAN_PCROSS_SUBSET] THEN
7333 REWRITE_TAC[SUBSET; FORALL_IN_PCROSS] THEN
7334 ONCE_REWRITE_TAC[PASTECART_AS_ORTHOGONAL_SUM] THEN
7336 `(!x:real^M. x IN span s ==> pastecart x (vec 0) IN span(s PCROSS t)) /\
7337 (!y:real^N. y IN span t ==> pastecart (vec 0) y IN span(s PCROSS t))`
7338 (fun th -> ASM_MESON_TAC[th; SPAN_ADD]) THEN
7339 CONJ_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[IN_ELIM_THM] THEN
7341 [REWRITE_TAC[IN_ELIM_THM] THEN
7342 ASM_SIMP_TAC[SPAN_SUPERSET; PASTECART_IN_PCROSS];
7343 REWRITE_TAC[subspace; IN_ELIM_THM; PASTECART_VEC; SPAN_0] THEN
7344 CONJ_TAC THEN REPEAT GEN_TAC THENL
7345 [DISCH_THEN(MP_TAC o MATCH_MP SPAN_ADD) THEN
7346 REWRITE_TAC[PASTECART_ADD; VECTOR_ADD_LID];
7347 DISCH_THEN(MP_TAC o MATCH_MP SPAN_MUL) THEN
7348 SIMP_TAC[GSYM PASTECART_CMUL; VECTOR_MUL_RZERO]]])
7350 [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
7351 UNDISCH_TAC `~(t:real^N->bool = {})` THEN
7352 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
7353 DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
7355 `pastecart x (vec 0) =
7356 pastecart (x:real^M) (y:real^N) - pastecart (vec 0) y`
7358 [REWRITE_TAC[PASTECART_SUB; PASTECART_INJ] THEN VECTOR_ARITH_TAC;
7359 MATCH_MP_TAC SPAN_SUB THEN
7360 ASM_SIMP_TAC[SPAN_SUPERSET; PASTECART_IN_PCROSS]];
7361 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
7362 UNDISCH_TAC `~(s:real^M->bool = {})` THEN
7363 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
7364 DISCH_THEN(X_CHOOSE_TAC `x:real^M`) THEN
7366 `pastecart (vec 0) y =
7367 pastecart (x:real^M) (y:real^N) - pastecart x (vec 0)`
7369 [REWRITE_TAC[PASTECART_SUB; PASTECART_INJ] THEN VECTOR_ARITH_TAC;
7370 MATCH_MP_TAC SPAN_SUB THEN
7371 ASM_SIMP_TAC[SPAN_SUPERSET; PASTECART_IN_PCROSS]]]);;
7373 let DIM_PCROSS_STRONG = prove
7374 (`!s:real^M->bool t:real^N->bool.
7375 ~(s = {}) /\ ~(t = {}) /\ (vec 0 IN s \/ vec 0 IN t)
7376 ==> dim(s PCROSS t) = dim s + dim t`,
7377 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
7378 SIMP_TAC[SPAN_PCROSS; DIM_PCROSS; SUBSPACE_SPAN]);;
7380 let SPAN_SUMS = prove
7381 (`!s t:real^N->bool.
7382 ~(s = {}) /\ ~(t = {}) /\ vec 0 IN (s UNION t)
7383 ==> span {x + y | x IN s /\ y IN t} =
7384 {x + y | x IN span s /\ y IN span t}`,
7385 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SPAN_UNION] THEN
7386 MATCH_MP_TAC SUBSET_ANTISYM THEN
7387 CONJ_TAC THEN MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
7388 REWRITE_TAC[SUBSPACE_SPAN; SUBSET; FORALL_IN_GSPEC] THEN
7389 SIMP_TAC[SPAN_ADD; IN_UNION; SPAN_SUPERSET] THEN
7390 X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN
7391 FIRST_X_ASSUM(DISJ_CASES_TAC o GEN_REWRITE_RULE I [IN_UNION]) THENL
7392 [UNDISCH_TAC `~(t:real^N->bool = {})` THEN
7393 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
7394 DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
7395 SUBST1_TAC(VECTOR_ARITH `x:real^N = (x + y) - (vec 0 + y)`) THEN
7396 MATCH_MP_TAC SPAN_SUB THEN CONJ_TAC THEN MATCH_MP_TAC SPAN_SUPERSET THEN
7398 MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN
7399 ASM_MESON_TAC[VECTOR_ADD_RID];
7400 MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN
7401 ASM_MESON_TAC[VECTOR_ADD_LID];
7402 UNDISCH_TAC `~(s:real^N->bool = {})` THEN
7403 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
7404 DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
7405 SUBST1_TAC(VECTOR_ARITH `x:real^N = (y + x) - (y + vec 0)`) THEN
7406 MATCH_MP_TAC SPAN_SUB THEN CONJ_TAC THEN MATCH_MP_TAC SPAN_SUPERSET THEN
7409 (* ------------------------------------------------------------------------- *)
7410 (* More about rank from the rank/nullspace formula. *)
7411 (* ------------------------------------------------------------------------- *)
7413 let RANK_NULLSPACE = prove
7414 (`!A:real^M^N. rank A + dim {x | A ** x = vec 0} = dimindex(:M)`,
7415 GEN_TAC THEN REWRITE_TAC[RANK_DIM_IM] THEN
7416 MATCH_MP_TAC DIM_IMAGE_KERNEL THEN
7417 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);;
7419 let RANK_SYLVESTER = prove
7420 (`!A:real^N^M B:real^P^N.
7421 rank(A) + rank(B) <= rank(A ** B) + dimindex(:N)`,
7422 REPEAT GEN_TAC THEN MATCH_MP_TAC(ARITH_RULE
7428 ==> ra + rb <= rab + n`) THEN
7429 MAP_EVERY EXISTS_TAC
7430 [`dim {x | (A:real^N^M) ** x = vec 0}`;
7431 `dim {x | (B:real^P^N) ** x = vec 0}`;
7432 `dim {x | ((A:real^N^M) ** (B:real^P^N)) ** x = vec 0}`;
7433 `dimindex(:P)`] THEN
7434 REWRITE_TAC[RANK_NULLSPACE] THEN
7435 REWRITE_TAC[GSYM MATRIX_VECTOR_MUL_ASSOC] THEN
7436 ONCE_REWRITE_TAC[ADD_SYM] THEN
7437 MATCH_MP_TAC(REWRITE_RULE[o_DEF] DIM_KERNEL_COMPOSE) THEN
7438 CONJ_TAC THEN GEN_REWRITE_TAC RAND_CONV [GSYM ETA_AX] THEN
7439 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);;
7441 let RANK_GRAM = prove
7442 (`!A:real^M^N. rank(transp A ** A) = rank A`,
7443 GEN_TAC THEN MATCH_MP_TAC(ARITH_RULE
7444 `!n n' k. r + n:num = k /\ r' + n' = k /\ n = n' ==> r = r'`) THEN
7445 MAP_EVERY EXISTS_TAC
7446 [`dim {x | (transp A ** (A:real^M^N)) ** x = vec 0}`;
7447 `dim {x | (A:real^M^N) ** x = vec 0}`;
7448 `dimindex(:M)`] THEN
7449 REWRITE_TAC[RANK_NULLSPACE] THEN AP_TERM_TAC THEN
7450 MATCH_MP_TAC SUBSET_ANTISYM THEN
7451 SIMP_TAC[SUBSET; IN_ELIM_THM; GSYM MATRIX_VECTOR_MUL_ASSOC;
7452 MATRIX_VECTOR_MUL_RZERO] THEN
7453 X_GEN_TAC `x:real^M` THEN
7454 DISCH_THEN(MP_TAC o AP_TERM `(dot) (x:real^M)`) THEN
7455 ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN
7456 REWRITE_TAC[VECTOR_MATRIX_MUL_TRANSP; TRANSP_TRANSP; DOT_RZERO] THEN
7457 REWRITE_TAC[DOT_EQ_0]);;
7459 let RANK_TRIANGLE = prove
7460 (`!A B:real^M^N. rank(A + B) <= rank(A) + rank(B)`,
7461 REPEAT GEN_TAC THEN REWRITE_TAC[RANK_DIM_IM] THEN
7462 MP_TAC(ISPECL [`IMAGE (\x. (A:real^M^N) ** x) (:real^M)`;
7463 `IMAGE (\x. (B:real^M^N) ** x) (:real^M)`]
7464 DIM_SUMS_INTER) THEN
7465 ASM_SIMP_TAC[SUBSPACE_LINEAR_IMAGE; SUBSPACE_UNIV;
7466 MATRIX_VECTOR_MUL_LINEAR] THEN
7467 DISCH_THEN(SUBST1_TAC o SYM) THEN
7468 MATCH_MP_TAC(ARITH_RULE `x:num <= y ==> x <= y + z`) THEN
7469 MATCH_MP_TAC DIM_SUBSET THEN
7470 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV;
7471 MATRIX_VECTOR_MUL_ADD_RDISTRIB] THEN
7472 REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; IN_UNIV] THEN MESON_TAC[]);;
7474 (* ------------------------------------------------------------------------- *)
7475 (* Infinity norm. *)
7476 (* ------------------------------------------------------------------------- *)
7478 let infnorm = define
7479 `infnorm (x:real^N) = sup { abs(x$i) | 1 <= i /\ i <= dimindex(:N) }`;;
7481 let NUMSEG_DIMINDEX_NONEMPTY = prove
7482 (`?i. i IN 1..dimindex(:N)`,
7483 REWRITE_TAC[MEMBER_NOT_EMPTY; NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]);;
7485 let INFNORM_SET_IMAGE = prove
7486 (`{abs(x$i) | 1 <= i /\ i <= dimindex(:N)} =
7487 IMAGE (\i. abs(x$i)) (1..dimindex(:N))`,
7488 REWRITE_TAC[numseg] THEN SET_TAC[]);;
7490 let INFNORM_SET_LEMMA = prove
7491 (`FINITE {abs((x:real^N)$i) | 1 <= i /\ i <= dimindex(:N)} /\
7492 ~({abs(x$i) | 1 <= i /\ i <= dimindex(:N)} = {})`,
7493 SIMP_TAC[INFNORM_SET_IMAGE; FINITE_NUMSEG; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
7494 REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]);;
7496 let INFNORM_POS_LE = prove
7497 (`!x. &0 <= infnorm x`,
7498 REWRITE_TAC[infnorm] THEN
7499 SIMP_TAC[REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN
7500 REWRITE_TAC[INFNORM_SET_IMAGE; NUMSEG_DIMINDEX_NONEMPTY;
7501 EXISTS_IN_IMAGE; REAL_ABS_POS]);;
7503 let INFNORM_TRIANGLE = prove
7504 (`!x y. infnorm(x + y) <= infnorm x + infnorm y`,
7505 REWRITE_TAC[infnorm] THEN
7506 SIMP_TAC[REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN
7507 ONCE_REWRITE_TAC[GSYM REAL_LE_SUB_RADD] THEN
7508 SIMP_TAC[REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN
7509 ONCE_REWRITE_TAC[REAL_ARITH `x - y <= z <=> x - z <= y`] THEN
7510 SIMP_TAC[REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN
7511 REWRITE_TAC[INFNORM_SET_IMAGE; FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
7512 SIMP_TAC[VECTOR_ADD_COMPONENT; GSYM IN_NUMSEG] THEN
7513 MESON_TAC[NUMSEG_DIMINDEX_NONEMPTY;
7514 REAL_ARITH `abs(x + y) - abs(x) <= abs(y)`]);;
7516 let INFNORM_EQ_0 = prove
7517 (`!x. infnorm x = &0 <=> x = vec 0`,
7518 REWRITE_TAC[GSYM REAL_LE_ANTISYM; INFNORM_POS_LE] THEN
7519 SIMP_TAC[infnorm; REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN
7520 SIMP_TAC[FORALL_IN_IMAGE; INFNORM_SET_IMAGE; CART_EQ; VEC_COMPONENT] THEN
7521 REWRITE_TAC[IN_NUMSEG; REAL_ARITH `abs(x) <= &0 <=> x = &0`]);;
7523 let INFNORM_0 = prove
7524 (`infnorm(vec 0) = &0`,
7525 REWRITE_TAC[INFNORM_EQ_0]);;
7527 let INFNORM_NEG = prove
7528 (`!x. infnorm(--x) = infnorm x`,
7529 GEN_TAC THEN REWRITE_TAC[infnorm] THEN AP_TERM_TAC THEN
7530 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
7531 MESON_TAC[REAL_ABS_NEG; VECTOR_NEG_COMPONENT]);;
7533 let INFNORM_SUB = prove
7534 (`!x y. infnorm(x - y) = infnorm(y - x)`,
7535 MESON_TAC[INFNORM_NEG; VECTOR_NEG_SUB]);;
7537 let REAL_ABS_SUB_INFNORM = prove
7538 (`abs(infnorm x - infnorm y) <= infnorm(x - y)`,
7539 MATCH_MP_TAC(REAL_ARITH
7540 `nx <= n + ny /\ ny <= n + nx ==> abs(nx - ny) <= n`) THEN
7541 MESON_TAC[INFNORM_SUB; VECTOR_SUB_ADD2; INFNORM_TRIANGLE; VECTOR_ADD_SYM]);;
7543 let REAL_ABS_INFNORM = prove
7544 (`!x. abs(infnorm x) = infnorm x`,
7545 REWRITE_TAC[real_abs; INFNORM_POS_LE]);;
7547 let COMPONENT_LE_INFNORM = prove
7548 (`!x:real^N i. 1 <= i /\ i <= dimindex (:N) ==> abs(x$i) <= infnorm x`,
7549 REPEAT GEN_TAC THEN REWRITE_TAC[infnorm] THEN
7550 MP_TAC(SPEC `{ abs((x:real^N)$i) | 1 <= i /\ i <= dimindex(:N) }`
7552 REWRITE_TAC[INFNORM_SET_LEMMA] THEN
7553 SIMP_TAC[INFNORM_SET_IMAGE; FORALL_IN_IMAGE; IN_NUMSEG]);;
7555 let INFNORM_MUL_LEMMA = prove
7556 (`!a x. infnorm(a % x) <= abs a * infnorm x`,
7557 REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [infnorm] THEN
7558 SIMP_TAC[REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN
7559 REWRITE_TAC[FORALL_IN_IMAGE; INFNORM_SET_IMAGE] THEN
7560 SIMP_TAC[REAL_ABS_MUL; VECTOR_MUL_COMPONENT; IN_NUMSEG] THEN
7561 SIMP_TAC[COMPONENT_LE_INFNORM; REAL_LE_LMUL; REAL_ABS_POS]);;
7563 let INFNORM_MUL = prove
7564 (`!a x:real^N. infnorm(a % x) = abs a * infnorm x`,
7565 REPEAT GEN_TAC THEN ASM_CASES_TAC `a = &0` THEN
7566 ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INFNORM_0; REAL_ABS_0; REAL_MUL_LZERO] THEN
7567 REWRITE_TAC[GSYM REAL_LE_ANTISYM; INFNORM_MUL_LEMMA] THEN
7568 GEN_REWRITE_TAC (LAND_CONV o funpow 2 RAND_CONV) [GSYM VECTOR_MUL_LID] THEN
7569 FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP REAL_MUL_LINV) THEN
7570 REWRITE_TAC[GSYM VECTOR_MUL_ASSOC] THEN
7571 MATCH_MP_TAC REAL_LE_TRANS THEN
7572 EXISTS_TAC `abs(a) * abs(inv a) * infnorm(a % x:real^N)` THEN
7573 ASM_SIMP_TAC[INFNORM_MUL_LEMMA; REAL_LE_LMUL; REAL_ABS_POS] THEN
7574 ASM_SIMP_TAC[REAL_MUL_ASSOC; GSYM REAL_ABS_MUL; REAL_MUL_RINV] THEN
7577 let INFNORM_POS_LT = prove
7578 (`!x. &0 < infnorm x <=> ~(x = vec 0)`,
7579 MESON_TAC[REAL_LT_LE; INFNORM_POS_LE; INFNORM_EQ_0]);;
7581 (* ------------------------------------------------------------------------- *)
7582 (* Prove that it differs only up to a bound from Euclidean norm. *)
7583 (* ------------------------------------------------------------------------- *)
7585 let INFNORM_LE_NORM = prove
7586 (`!x. infnorm(x) <= norm(x)`,
7587 SIMP_TAC[infnorm; REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN
7588 REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[COMPONENT_LE_NORM]);;
7590 let NORM_LE_INFNORM = prove
7591 (`!x:real^N. norm(x) <= sqrt(&(dimindex(:N))) * infnorm(x)`,
7592 GEN_TAC THEN GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o funpow 2 RAND_CONV)
7593 [GSYM CARD_NUMSEG_1] THEN
7594 REWRITE_TAC[vector_norm] THEN MATCH_MP_TAC REAL_LE_LSQRT THEN
7595 SIMP_TAC[DOT_POS_LE; SQRT_POS_LE; REAL_POS; REAL_LE_MUL; INFNORM_POS_LE;
7596 SQRT_POW_2; REAL_POW_MUL] THEN
7597 REWRITE_TAC[dot] THEN MATCH_MP_TAC SUM_BOUND THEN
7598 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN REPEAT STRIP_TAC THEN
7599 REWRITE_TAC[GSYM REAL_POW_2] THEN ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN
7600 MATCH_MP_TAC REAL_POW_LE2 THEN REWRITE_TAC[REAL_ABS_POS] THEN
7601 MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs(y)`) THEN
7602 SIMP_TAC[infnorm; REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN
7603 REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[REAL_LE_REFL]);;
7605 (* ------------------------------------------------------------------------- *)
7606 (* Equality in Cauchy-Schwarz and triangle inequalities. *)
7607 (* ------------------------------------------------------------------------- *)
7609 let NORM_CAUCHY_SCHWARZ_EQ = prove
7610 (`!x:real^N y. x dot y = norm(x) * norm(y) <=> norm(x) % y = norm(y) % x`,
7611 REPEAT STRIP_TAC THEN
7612 MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN
7613 ASM_REWRITE_TAC[NORM_0; REAL_MUL_LZERO; REAL_MUL_RZERO;
7614 DOT_LZERO; DOT_RZERO; VECTOR_MUL_LZERO; VECTOR_MUL_RZERO] THEN
7615 MP_TAC(ISPEC `norm(y:real^N) % x - norm(x:real^N) % y` DOT_EQ_0) THEN
7616 REWRITE_TAC[DOT_RSUB; DOT_LSUB; DOT_LMUL; DOT_RMUL; GSYM NORM_POW_2;
7617 REAL_POW_2; VECTOR_SUB_EQ] THEN
7618 REWRITE_TAC[DOT_SYM; REAL_ARITH
7619 `y * (y * x * x - x * d) - x * (y * d - x * y * y) =
7620 &2 * x * y * (x * y - d)`] THEN
7621 ASM_SIMP_TAC[REAL_ENTIRE; NORM_EQ_0; REAL_SUB_0; REAL_OF_NUM_EQ; ARITH] THEN
7622 REWRITE_TAC[EQ_SYM_EQ]);;
7624 let NORM_CAUCHY_SCHWARZ_ABS_EQ = prove
7625 (`!x:real^N y. abs(x dot y) = norm(x) * norm(y) <=>
7626 norm(x) % y = norm(y) % x \/ norm(x) % y = --norm(y) % x`,
7627 SIMP_TAC[REAL_ARITH `&0 <= a ==> (abs x = a <=> x = a \/ --x = a)`;
7628 REAL_LE_MUL; NORM_POS_LE; GSYM DOT_RNEG] THEN
7630 GEN_REWRITE_TAC (LAND_CONV o funpow 3 RAND_CONV) [GSYM NORM_NEG] THEN
7631 REWRITE_TAC[NORM_CAUCHY_SCHWARZ_EQ] THEN REWRITE_TAC[NORM_NEG] THEN
7632 BINOP_TAC THEN VECTOR_ARITH_TAC);;
7634 let NORM_TRIANGLE_EQ = prove
7635 (`!x y:real^N. norm(x + y) = norm(x) + norm(y) <=> norm(x) % y = norm(y) % x`,
7636 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM NORM_CAUCHY_SCHWARZ_EQ] THEN
7637 MATCH_MP_TAC EQ_TRANS THEN
7638 EXISTS_TAC `norm(x + y:real^N) pow 2 = (norm(x) + norm(y)) pow 2` THEN
7640 [REWRITE_TAC[REAL_RING `x pow 2 = y pow 2 <=> x = y \/ x + y = &0`] THEN
7641 MAP_EVERY (MP_TAC o C ISPEC NORM_POS_LE)
7642 [`x + y:real^N`; `x:real^N`; `y:real^N`] THEN
7644 REWRITE_TAC[NORM_POW_2; DOT_LADD; DOT_RADD; REAL_ARITH
7645 `(x + y) pow 2 = x pow 2 + y pow 2 + &2 * x * y`] THEN
7646 REWRITE_TAC[DOT_SYM] THEN REAL_ARITH_TAC]);;
7648 let DIST_TRIANGLE_EQ = prove
7649 (`!x y z. dist(x,z) = dist(x,y) + dist(y,z) <=>
7650 norm (x - y) % (y - z) = norm (y - z) % (x - y)`,
7651 REWRITE_TAC[GSYM NORM_TRIANGLE_EQ] THEN NORM_ARITH_TAC);;
7653 let NORM_CROSS_MULTIPLY = prove
7655 a % x = b % y /\ &0 < a /\ &0 < b
7656 ==> norm y % x = norm x % y`,
7657 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
7658 ASM_CASES_TAC `y:real^N = vec 0` THEN
7659 ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ; VECTOR_MUL_RZERO] THEN
7660 DISCH_THEN(MP_TAC o AP_TERM `\x:real^N. inv(a) % x`) THEN
7661 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_LT_IMP_NZ; VECTOR_MUL_LID;
7662 NORM_MUL; REAL_ABS_MUL; REAL_ABS_INV] THEN
7663 ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE; REAL_MUL_AC]);;
7665 (* ------------------------------------------------------------------------- *)
7667 (* ------------------------------------------------------------------------- *)
7669 let collinear = new_definition
7670 `collinear s <=> ?u. !x y. x IN s /\ y IN s ==> ?c. x - y = c % u`;;
7672 let COLLINEAR_SUBSET = prove
7673 (`!s t. collinear t /\ s SUBSET t ==> collinear s`,
7674 REWRITE_TAC[collinear] THEN SET_TAC[]);;
7676 let COLLINEAR_EMPTY = prove
7678 REWRITE_TAC[collinear; NOT_IN_EMPTY]);;
7680 let COLLINEAR_SING = prove
7681 (`!x. collinear {x}`,
7682 SIMP_TAC[collinear; IN_SING; VECTOR_SUB_REFL] THEN
7683 MESON_TAC[VECTOR_MUL_LZERO]);;
7685 let COLLINEAR_2 = prove
7686 (`!x y:real^N. collinear {x,y}`,
7687 REPEAT GEN_TAC THEN REWRITE_TAC[collinear; IN_INSERT; NOT_IN_EMPTY] THEN
7688 EXISTS_TAC `x - y:real^N` THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
7689 [EXISTS_TAC `&0`; EXISTS_TAC `&1`; EXISTS_TAC `-- &1`; EXISTS_TAC `&0`] THEN
7692 let COLLINEAR_SMALL = prove
7693 (`!s. FINITE s /\ CARD s <= 2 ==> collinear s`,
7694 REWRITE_TAC[ARITH_RULE `s <= 2 <=> s = 0 \/ s = 1 \/ s = 2`] THEN
7695 REWRITE_TAC[LEFT_OR_DISTRIB; GSYM HAS_SIZE] THEN
7696 CONV_TAC(ONCE_DEPTH_CONV HAS_SIZE_CONV) THEN
7697 REPEAT STRIP_TAC THEN
7698 ASM_REWRITE_TAC[COLLINEAR_EMPTY; COLLINEAR_SING; COLLINEAR_2]);;
7700 let COLLINEAR_3 = prove
7701 (`!x y z. collinear {x,y,z} <=> collinear {vec 0,x - y,z - y}`,
7703 REWRITE_TAC[collinear; FORALL_IN_INSERT; IMP_CONJ; RIGHT_FORALL_IMP_THM;
7705 AP_TERM_TAC THEN ABS_TAC THEN
7706 MESON_TAC[VECTOR_ARITH `x - y = (x - y) - vec 0`;
7707 VECTOR_ARITH `y - x = vec 0 - (x - y)`;
7708 VECTOR_ARITH `x - z:real^N = (x - y) - (z - y)`]);;
7710 let COLLINEAR_LEMMA = prove
7711 (`!x y:real^N. collinear {vec 0,x,y} <=>
7712 x = vec 0 \/ y = vec 0 \/ ?c. y = c % x`,
7714 MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN
7715 TRY(ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_SING; COLLINEAR_2] THEN NO_TAC) THEN
7716 ASM_REWRITE_TAC[collinear] THEN EQ_TAC THENL
7717 [DISCH_THEN(X_CHOOSE_THEN `u:real^N`
7718 (fun th -> MP_TAC(SPECL [`x:real^N`; `vec 0:real^N`] th) THEN
7719 MP_TAC(SPECL [`y:real^N`; `vec 0:real^N`] th))) THEN
7720 REWRITE_TAC[IN_INSERT; VECTOR_SUB_RZERO] THEN
7721 DISCH_THEN(X_CHOOSE_THEN `e:real` SUBST_ALL_TAC) THEN
7722 DISCH_THEN(X_CHOOSE_THEN `d:real` SUBST_ALL_TAC) THEN
7723 EXISTS_TAC `e / d` THEN REWRITE_TAC[VECTOR_MUL_ASSOC] THEN
7724 RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_MUL_EQ_0; DE_MORGAN_THM]) THEN
7725 ASM_SIMP_TAC[REAL_DIV_RMUL];
7726 STRIP_TAC THEN EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[] THEN
7727 REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN
7728 ASM_REWRITE_TAC[] THENL
7729 [EXISTS_TAC `&0`; EXISTS_TAC `-- &1`; EXISTS_TAC `--c`;
7730 EXISTS_TAC `&1`; EXISTS_TAC `&0`; EXISTS_TAC `&1 - c`;
7731 EXISTS_TAC `c:real`; EXISTS_TAC `c - &1`; EXISTS_TAC `&0`] THEN
7732 VECTOR_ARITH_TAC]);;
7734 let COLLINEAR_LEMMA_ALT = prove
7735 (`!x y. collinear {vec 0,x,y} <=> x = vec 0 \/ ?c. y = c % x`,
7736 REWRITE_TAC[COLLINEAR_LEMMA] THEN MESON_TAC[VECTOR_MUL_LZERO]);;
7738 let NORM_CAUCHY_SCHWARZ_EQUAL = prove
7739 (`!x y:real^N. abs(x dot y) = norm(x) * norm(y) <=> collinear {vec 0,x,y}`,
7740 REPEAT GEN_TAC THEN REWRITE_TAC[NORM_CAUCHY_SCHWARZ_ABS_EQ] THEN
7741 MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN
7742 TRY(ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_SING; COLLINEAR_2; NORM_0;
7743 VECTOR_MUL_LZERO; VECTOR_MUL_RZERO] THEN NO_TAC) THEN
7744 ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN EQ_TAC THENL
7746 [FIRST_X_ASSUM(MP_TAC o AP_TERM
7747 `(%) (inv(norm(x:real^N))):real^N->real^N`);
7748 FIRST_X_ASSUM(MP_TAC o AP_TERM
7749 `(%) (--inv(norm(x:real^N))):real^N->real^N`)] THEN
7750 ASM_REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LNEG] THEN
7751 ASM_SIMP_TAC[REAL_MUL_LINV; NORM_EQ_0; VECTOR_MUL_LNEG; VECTOR_MUL_LID;
7752 VECTOR_ARITH `--x = --y <=> x:real^N = y`] THEN
7754 STRIP_TAC THEN ASM_REWRITE_TAC[NORM_MUL; VECTOR_MUL_ASSOC] THEN
7755 MATCH_MP_TAC(MESON[]
7756 `t = a \/ t = b ==> t % x = a % x \/ t % x = b % x`) THEN
7757 REWRITE_TAC[GSYM REAL_MUL_LNEG;
7758 REAL_ARITH `x * c = d * x <=> x * (c - d) = &0`] THEN
7759 ASM_REWRITE_TAC[REAL_ENTIRE; NORM_EQ_0] THEN REAL_ARITH_TAC]);;
7761 let DOT_CAUCHY_SCHWARZ_EQUAL = prove
7763 (x dot y) pow 2 = (x dot x) * (y dot y) <=>
7764 collinear {vec 0,x,y}`,
7765 REWRITE_TAC[GSYM NORM_CAUCHY_SCHWARZ_EQUAL] THEN
7766 REPEAT GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH
7767 `&0 <= y /\ (u:real = v <=> x = abs y) ==> (u = v <=> x = y)`) THEN
7768 SIMP_TAC[NORM_POS_LE; REAL_LE_MUL] THEN
7769 REWRITE_TAC[REAL_EQ_SQUARE_ABS] THEN REWRITE_TAC[REAL_POW_MUL; NORM_POW_2]);;
7771 let COLLINEAR_3_EXPAND = prove
7772 (`!a b c:real^N. collinear{a,b,c} <=> a = c \/ ?u. b = u % a + (&1 - u) % c`,
7774 ONCE_REWRITE_TAC[SET_RULE `{a,b,c} = {a,c,b}`] THEN
7775 ONCE_REWRITE_TAC[COLLINEAR_3] THEN
7776 REWRITE_TAC[COLLINEAR_LEMMA; VECTOR_SUB_EQ] THEN
7777 ASM_CASES_TAC `a:real^N = c` THEN ASM_REWRITE_TAC[] THEN
7778 ASM_CASES_TAC `b:real^N = c` THEN
7779 ASM_REWRITE_TAC[VECTOR_ARITH `u % c + (&1 - u) % c = c`] THENL
7780 [EXISTS_TAC `&0` THEN VECTOR_ARITH_TAC;
7781 AP_TERM_TAC THEN ABS_TAC THEN VECTOR_ARITH_TAC]);;
7783 let COLLINEAR_TRIPLES = prove
7786 ==> (collinear(a INSERT b INSERT s) <=>
7787 !x. x IN s ==> collinear{a,b,x})`,
7788 REPEAT STRIP_TAC THEN EQ_TAC THENL
7789 [REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
7790 (REWRITE_RULE[IMP_CONJ] COLLINEAR_SUBSET)) THEN
7792 ONCE_REWRITE_TAC[SET_RULE `{a,b,x} = {a,x,b}`] THEN
7793 ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN DISCH_TAC THEN
7795 `!x:real^N. x IN (a INSERT b INSERT s) ==> ?u. x = u % a + (&1 - u) % b`
7797 [ASM_REWRITE_TAC[FORALL_IN_INSERT] THEN CONJ_TAC THENL
7798 [EXISTS_TAC `&1` THEN VECTOR_ARITH_TAC;
7799 EXISTS_TAC `&0` THEN VECTOR_ARITH_TAC];
7800 POP_ASSUM_LIST(K ALL_TAC) THEN DISCH_TAC THEN
7801 REWRITE_TAC[collinear] THEN EXISTS_TAC `b - a:real^N` THEN
7802 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
7803 FIRST_X_ASSUM(fun th -> MP_TAC(SPEC `x:real^N` th) THEN MP_TAC(SPEC
7804 `y:real^N` th)) THEN
7805 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
7806 ASM_REWRITE_TAC[VECTOR_ARITH
7807 `(u % a + (&1 - u) % b) - (v % a + (&1 - v) % b):real^N =
7808 (v - u) % (b - a)`] THEN
7811 let COLLINEAR_4_3 = prove
7814 ==> (collinear {a,b,c,d} <=> collinear{a,b,c} /\ collinear{a,b,d})`,
7815 REPEAT STRIP_TAC THEN
7816 MP_TAC(ISPECL [`{c:real^N,d}`; `a:real^N`; `b:real^N`]
7817 COLLINEAR_TRIPLES) THEN
7818 ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
7819 REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY]);;
7821 let COLLINEAR_3_TRANS = prove
7823 collinear{a,b,c} /\ collinear{b,c,d} /\ ~(b = c) ==> collinear{a,b,d}`,
7824 REPEAT STRIP_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN
7825 EXISTS_TAC `{b:real^N,c,a,d}` THEN ASM_SIMP_TAC[COLLINEAR_4_3] THEN
7826 CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
7827 REPEAT(POP_ASSUM MP_TAC) THEN SIMP_TAC[INSERT_AC]);;
7829 let ORTHOGONAL_TO_ORTHOGONAL_2D = prove
7831 ~(x = vec 0) /\ orthogonal x y /\ orthogonal x z
7832 ==> collinear {vec 0,y,z}`,
7833 REWRITE_TAC[orthogonal; GSYM DOT_CAUCHY_SCHWARZ_EQUAL; GSYM DOT_EQ_0] THEN
7834 REWRITE_TAC[DOT_2] THEN CONV_TAC REAL_RING);;
7836 let COLLINEAR_3_2D = prove
7837 (`!x y z:real^2. collinear{x,y,z} <=>
7838 (z$1 - x$1) * (y$2 - x$2) = (y$1 - x$1) * (z$2 - x$2)`,
7839 ONCE_REWRITE_TAC[COLLINEAR_3] THEN
7840 REWRITE_TAC[GSYM DOT_CAUCHY_SCHWARZ_EQUAL] THEN
7841 REWRITE_TAC[DOT_2; VECTOR_SUB_COMPONENT] THEN CONV_TAC REAL_RING);;
7843 let COLLINEAR_3_DOT_MULTIPLES = prove
7845 collinear {a,b,c} <=>
7846 ((b - a) dot (b - a)) % (c - a) = ((c - a) dot (b - a)) % (b - a)`,
7847 REWRITE_TAC[VECTOR_SUB_RZERO] THEN
7848 REPEAT GEN_TAC THEN ASM_CASES_TAC `b:real^N = a` THENL
7849 [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC; DOT_RZERO; VECTOR_MUL_LZERO;
7851 ONCE_REWRITE_TAC[COLLINEAR_3] THEN
7852 POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
7853 REWRITE_TAC[GSYM DOT_CAUCHY_SCHWARZ_EQUAL; GSYM DOT_EQ_0] THEN
7854 REWRITE_TAC[GSYM DOT_EQ_0; DOT_RSUB; DOT_LSUB; DOT_RMUL; DOT_LMUL] THEN
7855 REWRITE_TAC[DOT_SYM] THEN CONV_TAC REAL_RING]);;
7857 (* ------------------------------------------------------------------------- *)
7859 (* ------------------------------------------------------------------------- *)
7861 let between = new_definition
7862 `between x (a,b) <=> dist(a,b) = dist(a,x) + dist(x,b)`;;
7864 let BETWEEN_REFL = prove
7865 (`!a b. between a (a,b) /\ between b (a,b) /\ between a (a,a)`,
7866 REWRITE_TAC[between] THEN NORM_ARITH_TAC);;
7868 let BETWEEN_REFL_EQ = prove
7869 (`!a x. between x (a,a) <=> x = a`,
7870 REWRITE_TAC[between] THEN NORM_ARITH_TAC);;
7872 let BETWEEN_SYM = prove
7873 (`!a b x. between x (a,b) <=> between x (b,a)`,
7874 REWRITE_TAC[between] THEN NORM_ARITH_TAC);;
7876 let BETWEEN_ANTISYM = prove
7877 (`!a b c. between a (b,c) /\ between b (a,c) ==> a = b`,
7878 REWRITE_TAC[between; DIST_SYM] THEN NORM_ARITH_TAC);;
7880 let BETWEEN_TRANS = prove
7881 (`!a b c d. between a (b,c) /\ between d (a,c) ==> between d (b,c)`,
7882 REWRITE_TAC[between; DIST_SYM] THEN NORM_ARITH_TAC);;
7884 let BETWEEN_TRANS_2 = prove
7885 (`!a b c d. between a (b,c) /\ between d (a,b) ==> between a (c,d)`,
7886 REWRITE_TAC[between; DIST_SYM] THEN NORM_ARITH_TAC);;
7888 let BETWEEN_NORM = prove
7890 between x (a,b) <=> norm(x - a) % (b - x) = norm(b - x) % (x - a)`,
7891 REPEAT GEN_TAC THEN REWRITE_TAC[between; DIST_TRIANGLE_EQ] THEN
7892 REWRITE_TAC[NORM_SUB] THEN VECTOR_ARITH_TAC);;
7894 let BETWEEN_DOT = prove
7896 between x (a,b) <=> (x - a) dot (b - x) = norm(x - a) * norm(b - x)`,
7897 REWRITE_TAC[BETWEEN_NORM; NORM_CAUCHY_SCHWARZ_EQ]);;
7899 let BETWEEN_EXISTS_EXTENSION = prove
7901 between b (a,x) /\ ~(b = a) ==> ?d. &0 <= d /\ x = b + d % (b - a)`,
7902 REPEAT GEN_TAC THEN REWRITE_TAC[BETWEEN_NORM] THEN STRIP_TAC THEN
7903 EXISTS_TAC `norm(x - b:real^N) / norm(b - a)` THEN
7904 SIMP_TAC[REAL_LE_DIV; NORM_POS_LE] THEN FIRST_X_ASSUM
7905 (MP_TAC o AP_TERM `(%) (inv(norm(b - a:real^N))):real^N->real^N`) THEN
7906 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; NORM_EQ_0; VECTOR_SUB_EQ] THEN
7909 let BETWEEN_IMP_COLLINEAR = prove
7910 (`!a b x:real^N. between x (a,b) ==> collinear {a,x,b}`,
7911 REPEAT GEN_TAC THEN MAP_EVERY
7912 (fun t -> ASM_CASES_TAC t THEN
7913 TRY(ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2] THEN NO_TAC))
7914 [`x:real^N = a`; `x:real^N = b`; `a:real^N = b`] THEN
7915 ONCE_REWRITE_TAC[COLLINEAR_3; BETWEEN_NORM] THEN
7916 DISCH_TAC THEN REWRITE_TAC[COLLINEAR_LEMMA] THEN
7917 REPEAT DISJ2_TAC THEN EXISTS_TAC `--(norm(b - x:real^N) / norm(x - a))` THEN
7918 MATCH_MP_TAC VECTOR_MUL_LCANCEL_IMP THEN EXISTS_TAC `norm(x - a:real^N)` THEN
7919 ASM_REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RNEG] THEN
7920 ASM_SIMP_TAC[REAL_DIV_LMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN
7923 let COLLINEAR_BETWEEN_CASES = prove
7925 collinear {a,b,c} <=>
7926 between a (b,c) \/ between b (c,a) \/ between c (a,b)`,
7927 REPEAT STRIP_TAC THEN EQ_TAC THENL
7928 [REWRITE_TAC[COLLINEAR_3_EXPAND] THEN
7929 ASM_CASES_TAC `c:real^N = a` THEN ASM_REWRITE_TAC[BETWEEN_REFL] THEN
7930 STRIP_TAC THEN ASM_REWRITE_TAC[between; dist] THEN
7931 REWRITE_TAC[VECTOR_ARITH `(u % a + (&1 - u) % c) - c = --u % (c - a)`;
7932 VECTOR_ARITH `(u % a + (&1 - u) % c) - a = (&1 - u) % (c - a)`;
7933 VECTOR_ARITH `c - (u % a + (&1 - u) % c) = u % (c - a)`;
7934 VECTOR_ARITH `a - (u % a + (&1 - u) % c) = (u - &1) % (c - a)`] THEN
7935 REWRITE_TAC[NORM_MUL] THEN
7936 SUBST1_TAC(NORM_ARITH `norm(a - c:real^N) = norm(c - a)`) THEN
7937 REWRITE_TAC[REAL_ARITH `a * c + c = (a + &1) * c`; GSYM REAL_ADD_RDISTRIB;
7938 REAL_ARITH `c + a * c = (a + &1) * c`] THEN
7939 ASM_REWRITE_TAC[REAL_EQ_MUL_RCANCEL;
7940 REAL_RING `n = x * n <=> n = &0 \/ x = &1`] THEN
7941 ASM_REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ] THEN REAL_ARITH_TAC;
7942 DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN (MP_TAC o MATCH_MP
7943 BETWEEN_IMP_COLLINEAR)) THEN
7944 REWRITE_TAC[INSERT_AC]]);;
7946 let COLLINEAR_DIST_BETWEEN = prove
7947 (`!a b x. collinear {x,a,b} /\
7948 dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)
7949 ==> between x (a,b)`,
7950 SIMP_TAC[COLLINEAR_BETWEEN_CASES; between; DIST_SYM] THEN NORM_ARITH_TAC);;
7952 let BETWEEN_COLLINEAR_DIST_EQ = prove
7955 collinear {a, x, b} /\
7956 dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)`,
7957 REPEAT GEN_TAC THEN EQ_TAC THENL
7958 [SIMP_TAC[BETWEEN_IMP_COLLINEAR] THEN REWRITE_TAC[between] THEN
7960 MESON_TAC[COLLINEAR_DIST_BETWEEN; INSERT_AC]]);;
7962 let COLLINEAR_1 = prove
7963 (`!s:real^1->bool. collinear s`,
7964 GEN_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN
7965 EXISTS_TAC `(vec 0:real^1) INSERT (vec 1) INSERT s` THEN
7966 CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
7967 W(MP_TAC o PART_MATCH (lhs o rand) COLLINEAR_TRIPLES o snd) THEN
7968 REWRITE_TAC[VEC_EQ; ARITH_EQ] THEN DISCH_THEN SUBST1_TAC THEN
7969 REWRITE_TAC[COLLINEAR_BETWEEN_CASES] THEN
7970 REWRITE_TAC[between; DIST_REAL; GSYM drop; DROP_VEC; REAL_ABS_NUM] THEN
7973 (* ------------------------------------------------------------------------- *)
7974 (* Midpoint between two points. *)
7975 (* ------------------------------------------------------------------------- *)
7977 let midpoint = new_definition
7978 `midpoint(a,b) = inv(&2) % (a + b)`;;
7980 let MIDPOINT_REFL = prove
7981 (`!x. midpoint(x,x) = x`,
7982 REWRITE_TAC[midpoint] THEN VECTOR_ARITH_TAC);;
7984 let MIDPOINT_SYM = prove
7985 (`!a b. midpoint(a,b) = midpoint(b,a)`,
7986 REWRITE_TAC[midpoint; VECTOR_ADD_SYM]);;
7988 let DIST_MIDPOINT = prove
7989 (`!a b. dist(a,midpoint(a,b)) = dist(a,b) / &2 /\
7990 dist(b,midpoint(a,b)) = dist(a,b) / &2 /\
7991 dist(midpoint(a,b),a) = dist(a,b) / &2 /\
7992 dist(midpoint(a,b),b) = dist(a,b) / &2`,
7993 REWRITE_TAC[midpoint] THEN NORM_ARITH_TAC);;
7995 let MIDPOINT_EQ_ENDPOINT = prove
7996 (`!a b. (midpoint(a,b) = a <=> a = b) /\
7997 (midpoint(a,b) = b <=> a = b) /\
7998 (a = midpoint(a,b) <=> a = b) /\
7999 (b = midpoint(a,b) <=> a = b)`,
8000 REWRITE_TAC[midpoint] THEN NORM_ARITH_TAC);;
8002 let BETWEEN_MIDPOINT = prove
8003 (`!a b. between (midpoint(a,b)) (a,b) /\ between (midpoint(a,b)) (b,a)`,
8004 REWRITE_TAC[between; midpoint] THEN NORM_ARITH_TAC);;
8006 let MIDPOINT_LINEAR_IMAGE = prove
8007 (`!f a b. linear f ==> midpoint(f a,f b) = f(midpoint(a,b))`,
8008 SIMP_TAC[midpoint; LINEAR_ADD; LINEAR_CMUL]);;
8010 let COLLINEAR_MIDPOINT = prove
8011 (`!a b. collinear{a,midpoint(a,b),b}`,
8012 REPEAT GEN_TAC THEN REWRITE_TAC[COLLINEAR_3_EXPAND; midpoint] THEN
8013 DISJ2_TAC THEN EXISTS_TAC `&1 / &2` THEN VECTOR_ARITH_TAC);;
8015 let MIDPOINT_COLLINEAR = prove
8018 ==> (b = midpoint(a,c) <=> collinear{a,b,c} /\ dist(a,b) = dist(b,c))`,
8019 REPEAT STRIP_TAC THEN
8020 MATCH_MP_TAC(TAUT `(a ==> b) /\ (b ==> (a <=> c)) ==> (a <=> b /\ c)`) THEN
8021 SIMP_TAC[COLLINEAR_MIDPOINT] THEN ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN
8022 STRIP_TAC THEN ASM_REWRITE_TAC[midpoint; dist] THEN
8024 [VECTOR_ARITH `a - (u % a + (&1 - u) % c) = (&1 - u) % (a - c)`;
8025 VECTOR_ARITH `(u % a + (&1 - u) % c) - c = u % (a - c)`;
8026 VECTOR_ARITH `u % a + (&1 - u) % c = inv (&2) % (a + c) <=>
8027 (u - &1 / &2) % (a - c) = vec 0`] THEN
8028 ASM_SIMP_TAC[NORM_MUL; REAL_EQ_MUL_RCANCEL; NORM_EQ_0; VECTOR_SUB_EQ;
8029 VECTOR_MUL_EQ_0] THEN
8032 let MIDPOINT_BETWEEN = prove
8034 b = midpoint (a,c) <=> between b (a,c) /\ dist (a,b) = dist (b,c)`,
8035 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = c` THENL
8036 [ASM_SIMP_TAC[BETWEEN_REFL_EQ; MIDPOINT_REFL; DIST_SYM]; ALL_TAC] THEN
8037 EQ_TAC THEN SIMP_TAC[BETWEEN_MIDPOINT; DIST_MIDPOINT] THEN
8038 ASM_MESON_TAC[MIDPOINT_COLLINEAR; BETWEEN_IMP_COLLINEAR]);;
8040 (* ------------------------------------------------------------------------- *)
8041 (* General "one way" lemma for properties preserved by injective map. *)
8042 (* ------------------------------------------------------------------------- *)
8044 let WLOG_LINEAR_INJECTIVE_IMAGE_2 = prove
8045 (`!P Q. (!f s. P s /\ linear f ==> Q(IMAGE f s)) /\
8046 (!g t. Q t /\ linear g ==> P(IMAGE g t))
8047 ==> !f:real^M->real^N.
8048 linear f /\ (!x y. f x = f y ==> x = y)
8049 ==> !s. Q(IMAGE f s) <=> P s`,
8050 REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN
8051 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
8052 ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN
8053 DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN
8054 FIRST_X_ASSUM(MP_TAC o SPECL
8055 [`g:real^N->real^M`; `IMAGE (f:real^M->real^N) s`]) THEN
8056 ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID]);;
8058 let WLOG_LINEAR_INJECTIVE_IMAGE_2_ALT = prove
8059 (`!P Q f s. (!h u. P u /\ linear h ==> Q(IMAGE h u)) /\
8060 (!g t. Q t /\ linear g ==> P(IMAGE g t)) /\
8061 linear f /\ (!x y. f x = f y ==> x = y)
8062 ==> (Q(IMAGE f s) <=> P s)`,
8063 REPEAT GEN_TAC THEN STRIP_TAC THEN
8064 MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
8065 WLOG_LINEAR_INJECTIVE_IMAGE_2) THEN
8066 ASM_REWRITE_TAC[]);;
8068 let WLOG_LINEAR_INJECTIVE_IMAGE = prove
8069 (`!P. (!f s. P s /\ linear f ==> P(IMAGE f s))
8070 ==> !f:real^N->real^N. linear f /\ (!x y. f x = f y ==> x = y)
8071 ==> !s. P(IMAGE f s) <=> P s`,
8072 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC WLOG_LINEAR_INJECTIVE_IMAGE_2 THEN
8073 ASM_REWRITE_TAC[]);;
8075 let WLOG_LINEAR_INJECTIVE_IMAGE_ALT = prove
8076 (`!P f s. (!g t. P t /\ linear g ==> P(IMAGE g t)) /\
8077 linear f /\ (!x y. f x = f y ==> x = y)
8078 ==> (P(IMAGE f s) <=> P s)`,
8079 REPEAT GEN_TAC THEN STRIP_TAC THEN
8080 MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
8081 WLOG_LINEAR_INJECTIVE_IMAGE) THEN
8082 ASM_REWRITE_TAC[]);;
8084 (* ------------------------------------------------------------------------- *)
8085 (* Inference rule to apply it conveniently. *)
8087 (* |- !f s. P s /\ linear f ==> P(IMAGE f s) [or /\ commuted] *)
8088 (* --------------------------------------------------------------- *)
8089 (* |- !f s. linear f /\ (!x y. f x = f y ==> x = y) *)
8090 (* ==> (Q(IMAGE f s) <=> P s) *)
8091 (* ------------------------------------------------------------------------- *)
8093 let LINEAR_INVARIANT_RULE th =
8094 let [f;s] = fst(strip_forall(concl th)) in
8095 let (rm,rn) = dest_fun_ty (type_of f) in
8096 let m = last(snd(dest_type rm)) and n = last(snd(dest_type rn)) in
8097 let th' = INST_TYPE [m,n; n,m] th in
8098 let th0 = CONJ th th' in
8099 let th1 = try MATCH_MP WLOG_LINEAR_INJECTIVE_IMAGE_2 th0
8101 MATCH_MP WLOG_LINEAR_INJECTIVE_IMAGE_2
8102 (GEN_REWRITE_RULE (BINOP_CONV o ONCE_DEPTH_CONV) [CONJ_SYM] th0) in
8103 GEN_REWRITE_RULE BINDER_CONV [RIGHT_IMP_FORALL_THM] th1;;
8105 (* ------------------------------------------------------------------------- *)
8106 (* Immediate application. *)
8107 (* ------------------------------------------------------------------------- *)
8109 let SUBSPACE_LINEAR_IMAGE_EQ = prove
8110 (`!f s. linear f /\ (!x y. f x = f y ==> x = y)
8111 ==> (subspace (IMAGE f s) <=> subspace s)`,
8112 MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE SUBSPACE_LINEAR_IMAGE));;
8114 (* ------------------------------------------------------------------------- *)
8115 (* Storage of useful "invariance under linear map / translation" theorems. *)
8116 (* ------------------------------------------------------------------------- *)
8118 let invariant_under_linear = ref([]:thm list);;
8120 let invariant_under_translation = ref([]:thm list);;
8122 let scaling_theorems = ref([]:thm list);;
8124 (* ------------------------------------------------------------------------- *)
8125 (* Scaling theorems and derivation from linear invariance. *)
8126 (* ------------------------------------------------------------------------- *)
8128 let LINEAR_SCALING = prove
8129 (`!c. linear(\x:real^N. c % x)`,
8130 REWRITE_TAC[linear] THEN VECTOR_ARITH_TAC);;
8132 let INJECTIVE_SCALING = prove
8133 (`!c. (!x y:real^N. c % x = c % y ==> x = y) <=> ~(c = &0)`,
8134 GEN_TAC THEN REWRITE_TAC[VECTOR_MUL_LCANCEL] THEN
8135 ASM_CASES_TAC `c:real = &0` THEN ASM_REWRITE_TAC[] THEN
8136 DISCH_THEN(MP_TAC o SPECL [`vec 0:real^N`; `vec 1:real^N`]) THEN
8137 REWRITE_TAC[VEC_EQ; ARITH]);;
8139 let SURJECTIVE_SCALING = prove
8140 (`!c. (!y:real^N. ?x. c % x = y) <=> ~(c = &0)`,
8141 ASM_SIMP_TAC[LINEAR_SURJECTIVE_IFF_INJECTIVE; LINEAR_SCALING] THEN
8142 REWRITE_TAC[INJECTIVE_SCALING]);;
8144 let SCALING_INVARIANT =
8145 let pths = (CONJUNCTS o UNDISCH o prove)
8147 ==> linear(\x:real^N. c % x) /\
8148 (!x y:real^N. c % x = c % y ==> x = y) /\
8149 (!y:real^N. ?x. c % x = y)`,
8150 SIMP_TAC[REAL_LT_IMP_NZ; LINEAR_SCALING;
8151 INJECTIVE_SCALING; SURJECTIVE_SCALING])
8152 and sc_tm = `\x:real^N. c % x`
8153 and sa_tm = `&0:real < c`
8154 and c_tm = `c:real` in
8156 let ith = BETA_RULE(ISPEC sc_tm th) in
8157 let avs,bod = strip_forall(concl ith) in
8158 let cjs = conjuncts(lhand bod) in
8159 let cths = map (fun t -> find(fun th -> aconv (concl th) t) pths) cjs in
8160 let oth = MP (SPECL avs ith) (end_itlist CONJ cths) in
8161 GEN c_tm (DISCH sa_tm (GENL avs oth));;
8163 let scaling_theorems = ref([]:thm list);;
8165 (* ------------------------------------------------------------------------- *)
8166 (* Augmentation of the lists. The "add_linear_invariants" also updates *)
8167 (* the scaling theorems automatically, so only a few of those will need *)
8168 (* to be added explicitly. *)
8169 (* ------------------------------------------------------------------------- *)
8171 let add_scaling_theorems thl =
8172 (scaling_theorems := (!scaling_theorems) @ thl);;
8174 let add_linear_invariants thl =
8175 ignore(mapfilter (fun th -> add_scaling_theorems[SCALING_INVARIANT th]) thl);
8176 (invariant_under_linear := (!invariant_under_linear) @ thl);;
8178 let add_translation_invariants thl =
8179 (invariant_under_translation := (!invariant_under_translation) @ thl);;
8181 (* ------------------------------------------------------------------------- *)
8182 (* Start with some basic set equivalences. *)
8183 (* We give them all an injectivity hypothesis even if it's not necessary. *)
8184 (* For just the intersection theorem we add surjectivity (more manageable *)
8185 (* than assuming that the set isn't empty). *)
8186 (* ------------------------------------------------------------------------- *)
8189 (`!f. (!x y. f x = f y ==> x = y)
8190 ==> (if p then f x else f y) = f(if p then x else y) /\
8191 (if p then IMAGE f s else IMAGE f t) =
8192 IMAGE f (if p then s else t) /\
8193 (f x) INSERT (IMAGE f s) = IMAGE f (x INSERT s) /\
8194 (IMAGE f s) DELETE (f x) = IMAGE f (s DELETE x) /\
8195 (IMAGE f s) INTER (IMAGE f t) = IMAGE f (s INTER t) /\
8196 (IMAGE f s) UNION (IMAGE f t) = IMAGE f (s UNION t) /\
8197 UNIONS(IMAGE (IMAGE f) u) = IMAGE f (UNIONS u) /\
8198 (IMAGE f s) DIFF (IMAGE f t) = IMAGE f (s DIFF t) /\
8199 (IMAGE f s (f x) <=> s x) /\
8200 ((f x) IN (IMAGE f s) <=> x IN s) /\
8201 ((f o xs) (n:num) = f(xs n)) /\
8202 ((f o pt) (tt:real^1) = f(pt tt)) /\
8203 (DISJOINT (IMAGE f s) (IMAGE f t) <=> DISJOINT s t) /\
8204 ((IMAGE f s) SUBSET (IMAGE f t) <=> s SUBSET t) /\
8205 ((IMAGE f s) PSUBSET (IMAGE f t) <=> s PSUBSET t) /\
8206 (IMAGE f s = IMAGE f t <=> s = t) /\
8207 ((IMAGE f s) HAS_SIZE n <=> s HAS_SIZE n) /\
8208 (FINITE(IMAGE f s) <=> FINITE s) /\
8209 (INFINITE(IMAGE f s) <=> INFINITE s)`,
8210 REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[IMAGE_UNIONS] THEN
8211 REWRITE_TAC[o_THM; MESON[IN] `IMAGE f s y <=> y IN IMAGE f s`] THEN
8212 REPLICATE_TAC 2 (CONJ_TAC THENL [MESON_TAC[]; ALL_TAC]) THEN
8213 REWRITE_TAC[INFINITE; TAUT `(~p <=> ~q) <=> (p <=> q)`] THEN
8214 REPLICATE_TAC 11 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
8215 REWRITE_TAC[HAS_SIZE] THEN
8216 ASM_MESON_TAC[FINITE_IMAGE_INJ_EQ; CARD_IMAGE_INJ]) in
8217 let f = `f:real^M->real^N`
8218 and imf = `IMAGE (f:real^M->real^N)`
8220 and ima = `IMAGE (\x:real^N. a + x)`
8221 and vth = VECTOR_ARITH `!x y. a + x:real^N = a + y ==> x = y` in
8222 let th1 = UNDISCH(ISPEC f th_sets)
8224 (GEN_REWRITE_RULE LAND_CONV [INJECTIVE_IMAGE] (ISPEC imf th_sets))
8225 and th2 = MATCH_MP th_sets vth
8227 (BETA_RULE(GEN_REWRITE_RULE LAND_CONV [INJECTIVE_IMAGE] (ISPEC ima th_sets)))
8229 let fn a th = GENL (a::subtract (frees(concl th)) [a]) th in
8230 add_linear_invariants(map (fn f o DISCH_ALL) (CONJUNCTS th1 @ CONJUNCTS th1')),
8231 add_translation_invariants(map (fn a) (CONJUNCTS th2 @ CONJUNCTS th2'));;
8234 (`!f:A->B s. (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
8235 ==> INTERS (IMAGE (IMAGE f) s) = IMAGE f (INTERS s)`,
8236 REWRITE_TAC[INTERS_IMAGE] THEN SET_TAC[]) in
8239 INTERS (IMAGE (IMAGE (\x. a + x)) s) = IMAGE (\x. a + x) (INTERS s)`,
8240 REPEAT GEN_TAC THEN MATCH_MP_TAC th_set THEN
8241 REWRITE_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN
8242 REWRITE_TAC[VECTOR_ARITH `a + x:real^N = y <=> x = y - a`; EXISTS_REFL]) in
8243 add_linear_invariants [th_set],add_translation_invariants[th_vec];;
8245 (* ------------------------------------------------------------------------- *)
8246 (* Now add arithmetical equivalences. *)
8247 (* ------------------------------------------------------------------------- *)
8249 let PRESERVES_NORM_PRESERVES_DOT = prove
8250 (`!f:real^M->real^N x y.
8251 linear f /\ (!x. norm(f x) = norm x)
8252 ==> (f x) dot (f y) = x dot y`,
8253 REWRITE_TAC[NORM_EQ] THEN REPEAT STRIP_TAC THEN
8254 FIRST_ASSUM(MP_TAC o SPEC `x + y:real^M`) THEN
8255 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_ADD th]) THEN
8256 ASM_REWRITE_TAC[DOT_LADD; DOT_RADD] THEN
8257 REWRITE_TAC[DOT_SYM] THEN REAL_ARITH_TAC);;
8259 let PRESERVES_NORM_INJECTIVE = prove
8260 (`!f:real^M->real^N.
8261 linear f /\ (!x. norm(f x) = norm x)
8262 ==> !x y. f x = f y ==> x = y`,
8263 SIMP_TAC[LINEAR_INJECTIVE_0; GSYM NORM_EQ_0]);;
8265 let ORTHOGONAL_LINEAR_IMAGE_EQ = prove
8266 (`!f:real^M->real^N x y.
8267 linear f /\ (!x. norm(f x) = norm x)
8268 ==> (orthogonal (f x) (f y) <=> orthogonal x y)`,
8269 SIMP_TAC[orthogonal; PRESERVES_NORM_PRESERVES_DOT]);;
8271 add_linear_invariants
8276 MIDPOINT_LINEAR_IMAGE;
8277 MESON[] `!f:real^M->real^N x.
8278 (!x. norm(f x) = norm x) ==> norm(f x) = norm x`;
8279 PRESERVES_NORM_PRESERVES_DOT;
8280 MESON[dist; LINEAR_SUB]
8281 `!f:real^M->real^N x y.
8282 linear f /\ (!x. norm(f x) = norm x)
8283 ==> dist(f x,f y) = dist(x,y)`;
8284 MESON[] `!f:real^M->real^N x y.
8285 (!x y. f x = f y ==> x = y) ==> (f x = f y <=> x = y)`;
8286 SUBSPACE_LINEAR_IMAGE_EQ;
8287 ORTHOGONAL_LINEAR_IMAGE_EQ;
8289 DEPENDENT_LINEAR_IMAGE_EQ;
8290 INDEPENDENT_LINEAR_IMAGE_EQ;
8291 DIM_INJECTIVE_LINEAR_IMAGE];;
8293 add_translation_invariants
8294 [VECTOR_ARITH `!a x y. a + x:real^N = a + y <=> x = y`;
8295 NORM_ARITH `!a x y. dist(a + x,a + y) = dist(x,y)`;
8296 VECTOR_ARITH `!a x y. &1 / &2 % ((a + x) + (a + y)) = a + &1 / &2 % (x + y)`;
8297 VECTOR_ARITH `!a x y. inv(&2) % ((a + x) + (a + y)) = a + inv(&2) % (x + y)`;
8298 VECTOR_ARITH `!a x y. (a + x) - (a + y):real^N = x - y`;
8299 (EQT_ELIM o (REWRITE_CONV[midpoint] THENC(EQT_INTRO o NORM_ARITH)))
8300 `!a x y. midpoint(a + x,a + y) = a + midpoint(x,y)`;
8301 (EQT_ELIM o (REWRITE_CONV[between] THENC(EQT_INTRO o NORM_ARITH)))
8302 `!a x y z. between (a + x) (a + y,a + z) <=> between x (y,z)`];;
8305 (`!a s b c:real^N. (a + b) + c IN IMAGE (\x. a + x) s <=> (b + c) IN s`,
8306 REWRITE_TAC[IN_IMAGE; VECTOR_ARITH
8307 `(a + b) + c:real^N = a + x <=> x = b + c`] THEN
8309 add_translation_invariants [th];;
8311 (* ------------------------------------------------------------------------- *)
8312 (* A few for lists. *)
8313 (* ------------------------------------------------------------------------- *)
8315 let MEM_TRANSLATION = prove
8316 (`!a:real^N x l. MEM (a + x) (MAP (\x. a + x) l) <=> MEM x l`,
8317 REWRITE_TAC[MEM_MAP; VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN
8320 add_translation_invariants [MEM_TRANSLATION];;
8322 let MEM_LINEAR_IMAGE = prove
8323 (`!f:real^M->real^N x l.
8324 linear f /\ (!x y. f x = f y ==> x = y)
8325 ==> (MEM (f x) (MAP f l) <=> MEM x l)`,
8326 REWRITE_TAC[MEM_MAP] THEN MESON_TAC[]);;
8328 add_linear_invariants [MEM_LINEAR_IMAGE];;
8330 let LENGTH_TRANSLATION = prove
8331 (`!a:real^N l. LENGTH(MAP (\x. a + x) l) = LENGTH l`,
8332 REWRITE_TAC[LENGTH_MAP]) in
8333 add_translation_invariants [LENGTH_TRANSLATION];;
8335 let LENGTH_LINEAR_IMAGE = prove
8336 (`!f:real^M->real^N l. linear f ==> LENGTH(MAP f l) = LENGTH l`,
8337 REWRITE_TAC[LENGTH_MAP]) in
8338 add_linear_invariants [LENGTH_LINEAR_IMAGE];;
8340 let CONS_TRANSLATION = prove
8342 CONS ((\x. a + x) h) (MAP (\x. a + x) t) = MAP (\x. a + x) (CONS h t)`,
8343 REWRITE_TAC[MAP]) in
8344 add_translation_invariants [CONS_TRANSLATION];;
8346 let CONS_LINEAR_IMAGE = prove
8347 (`!f:real^M->real^N h t.
8348 linear f ==> CONS (f h) (MAP f t) = MAP f (CONS h t)`,
8349 REWRITE_TAC[MAP]) in
8350 add_linear_invariants [CONS_LINEAR_IMAGE];;
8352 let APPEND_TRANSLATION = prove
8354 APPEND (MAP (\x. a + x) l1) (MAP (\x. a + x) l2) =
8355 MAP (\x. a + x) (APPEND l1 l2)`,
8356 REWRITE_TAC[MAP_APPEND]) in
8357 add_translation_invariants [APPEND_TRANSLATION];;
8359 let APPEND_LINEAR_IMAGE = prove
8360 (`!f:real^M->real^N l1 l2.
8361 linear f ==> APPEND (MAP f l1) (MAP f l2) = MAP f (APPEND l1 l2)`,
8362 REWRITE_TAC[MAP_APPEND]) in
8363 add_linear_invariants [APPEND_LINEAR_IMAGE];;
8365 let REVERSE_TRANSLATION = prove
8366 (`!a:real^N l. REVERSE(MAP (\x. a + x) l) = MAP (\x. a + x) (REVERSE l)`,
8367 REWRITE_TAC[MAP_REVERSE]) in
8368 add_translation_invariants [REVERSE_TRANSLATION];;
8370 let REVERSE_LINEAR_IMAGE = prove
8371 (`!f:real^M->real^N l. linear f ==> REVERSE(MAP f l) = MAP f (REVERSE l)`,
8372 REWRITE_TAC[MAP_REVERSE]) in
8373 add_linear_invariants [REVERSE_LINEAR_IMAGE];;
8375 (* ------------------------------------------------------------------------- *)
8376 (* A few scaling theorems that don't come from invariance theorems. Most are *)
8377 (* artificially weak with 0 < c hypotheses, so we don't bind them to names. *)
8378 (* ------------------------------------------------------------------------- *)
8380 let DOT_SCALING = prove
8381 (`!c. &0 < c ==> !x y. (c % x) dot (c % y) = c pow 2 * (x dot y)`,
8382 REWRITE_TAC[DOT_LMUL; DOT_RMUL] THEN REAL_ARITH_TAC) in
8383 add_scaling_theorems [DOT_SCALING];;
8385 let DIST_SCALING = prove
8386 (`!c. &0 < c ==> !x y. dist(c % x,c % y) = c * dist(x,y)`,
8387 SIMP_TAC[DIST_MUL; REAL_ARITH `&0 < c ==> abs c = c`]) in
8388 add_scaling_theorems [DIST_SCALING];;
8390 let ORTHOGONAL_SCALING = prove
8391 (`!c. &0 < c ==> !x y. orthogonal (c % x) (c % y) <=> orthogonal x y`,
8392 REWRITE_TAC[orthogonal; DOT_LMUL; DOT_RMUL] THEN CONV_TAC REAL_FIELD) in
8393 add_scaling_theorems [ORTHOGONAL_SCALING];;
8395 let NORM_SCALING = prove
8396 (`!c. &0 < c ==> !x. norm(c % x) = c * norm x`,
8397 SIMP_TAC[NORM_MUL; REAL_ARITH `&0 < c ==> abs c = c`]) in
8398 add_scaling_theorems [NORM_SCALING];;
8400 add_scaling_theorems
8401 [REAL_ARITH `!c. &0 < c ==> !a b. a * c * b = c * a * b`;
8402 REAL_ARITH `!c. &0 < c ==> !a b. c * a + c * b = c * (a + b)`;
8403 REAL_ARITH `!c. &0 < c ==> !a b. c * a - c * b = c * (a - b)`;
8404 REAL_FIELD `!c. &0 < c ==> !a b. c * a = c * b <=> a = b`;
8405 MESON[REAL_LT_LMUL_EQ] `!c. &0 < c ==> !a b. c * a < c * b <=> a < b`;
8406 MESON[REAL_LE_LMUL_EQ] `!c. &0 < c ==> !a b. c * a <= c * b <=> a <= b`;
8407 MESON[REAL_LT_LMUL_EQ; real_gt]
8408 `!c. &0 < c ==> !a b. c * a > c * b <=> a > b`;
8409 MESON[REAL_LE_LMUL_EQ; real_ge]
8410 `!c. &0 < c ==> !a b. c * a >= c * b <=> a >= b`;
8412 `!c. &0 < c ==> !a n. (c * a) pow n = c pow n * a pow n`;
8413 REAL_ARITH `!c. &0 < c ==> !a b n. a * c pow n * b = c pow n * a * b`;
8415 `!c. &0 < c ==> !a b n. c pow n * a + c pow n * b = c pow n * (a + b)`;
8417 `!c. &0 < c ==> !a b n. c pow n * a - c pow n * b = c pow n * (a - b)`;
8418 MESON[REAL_POW_LT; REAL_EQ_LCANCEL_IMP; REAL_LT_IMP_NZ]
8419 `!c. &0 < c ==> !a b n. c pow n * a = c pow n * b <=> a = b`;
8420 MESON[REAL_LT_LMUL_EQ; REAL_POW_LT]
8421 `!c. &0 < c ==> !a b n. c pow n * a < c pow n * b <=> a < b`;
8422 MESON[REAL_LE_LMUL_EQ; REAL_POW_LT]
8423 `!c. &0 < c ==> !a b n. c pow n * a <= c pow n * b <=> a <= b`;
8424 MESON[REAL_LT_LMUL_EQ; real_gt; REAL_POW_LT]
8425 `!c. &0 < c ==> !a b n. c pow n * a > c pow n * b <=> a > b`;
8426 MESON[REAL_LE_LMUL_EQ; real_ge; REAL_POW_LT]
8427 `!c. &0 < c ==> !a b n. c pow n * a >= c pow n * b <=> a >= b`];;
8429 (* ------------------------------------------------------------------------- *)
8430 (* Theorem deducing quantifier mappings from surjectivity. *)
8431 (* ------------------------------------------------------------------------- *)
8433 let QUANTIFY_SURJECTION_THM = prove
8436 ==> ((!P. (!x. P x) <=> (!x. P (f x))) /\
8437 (!P. (?x. P x) <=> (?x. P (f x))) /\
8438 (!Q. (!s. Q s) <=> (!s. Q(IMAGE f s))) /\
8439 (!Q. (?s. Q s) <=> (?s. Q(IMAGE f s)))) /\
8440 (!P. {x | P x} = IMAGE f {x | P(f x)})`,
8441 GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [SURJECTIVE_RIGHT_INVERSE] THEN
8442 DISCH_THEN(X_CHOOSE_TAC `g:B->A`) THEN
8443 SUBGOAL_THEN `!s. IMAGE (f:A->B) (IMAGE g s) = s` ASSUME_TAC THENL
8444 [ASM SET_TAC[]; CONJ_TAC THENL [ASM MESON_TAC[]; ASM SET_TAC[]]]);;
8446 let QUANTIFY_SURJECTION_HIGHER_THM = prove
8449 ==> ((!P. (!x. P x) <=> (!x. P (f x))) /\
8450 (!P. (?x. P x) <=> (?x. P (f x))) /\
8451 (!Q. (!s. Q s) <=> (!s. Q(IMAGE f s))) /\
8452 (!Q. (?s. Q s) <=> (?s. Q(IMAGE f s))) /\
8453 (!Q. (!s. Q s) <=> (!s. Q(IMAGE (IMAGE f) s))) /\
8454 (!Q. (?s. Q s) <=> (?s. Q(IMAGE (IMAGE f) s))) /\
8455 (!P. (!g:real^1->B. P g) <=> (!g. P(f o g))) /\
8456 (!P. (?g:real^1->B. P g) <=> (?g. P(f o g))) /\
8457 (!P. (!g:num->B. P g) <=> (!g. P(f o g))) /\
8458 (!P. (?g:num->B. P g) <=> (?g. P(f o g))) /\
8459 (!Q. (!l. Q l) <=> (!l. Q(MAP f l))) /\
8460 (!Q. (?l. Q l) <=> (?l. Q(MAP f l)))) /\
8461 ((!P. {x | P x} = IMAGE f {x | P(f x)}) /\
8462 (!Q. {s | Q s} = IMAGE (IMAGE f) {s | Q(IMAGE f s)}) /\
8463 (!R. {l | R l} = IMAGE (MAP f) {l | R(MAP f l)}))`,
8464 GEN_TAC THEN DISCH_TAC THEN CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN
8465 ASM_REWRITE_TAC[GSYM SURJECTIVE_FORALL_THM; GSYM SURJECTIVE_EXISTS_THM;
8466 GSYM SURJECTIVE_IMAGE_THM; SURJECTIVE_IMAGE; SURJECTIVE_MAP] THEN
8467 REWRITE_TAC[FUN_EQ_THM; o_THM; GSYM SKOLEM_THM] THEN ASM_MESON_TAC[]);;
8469 (* ------------------------------------------------------------------------- *)
8470 (* Apply such quantifier and set expansions once per level at depth. *)
8471 (* In the PARTIAL version, avoid expanding named variables in list. *)
8472 (* ------------------------------------------------------------------------- *)
8474 let PARTIAL_EXPAND_QUANTS_CONV avoid th =
8475 let ath,sth = CONJ_PAIR th in
8476 let conv1 = GEN_REWRITE_CONV I [ath]
8477 and conv2 = GEN_REWRITE_CONV I [sth] in
8479 let th = conv1 tm in
8480 if mem (fst(dest_var(fst(dest_abs(rand tm))))) avoid
8481 then failwith "Not going to expand this variable" else th in
8483 ((conv1' THENC BINDER_CONV conv) ORELSEC
8485 RAND_CONV(RAND_CONV(ABS_CONV(BINDER_CONV(LAND_CONV conv))))) ORELSEC
8486 SUB_CONV conv) tm in
8489 let EXPAND_QUANTS_CONV = PARTIAL_EXPAND_QUANTS_CONV [];;