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 (* Analogous theorems for set-sums. *)
266 (* ------------------------------------------------------------------------- *)
270 {x + y | x IN s /\ y IN t} = {y + x | y IN t /\ x IN s}`,
271 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN MESON_TAC[VECTOR_ADD_SYM]);;
273 let SUMS_ASSOC = prove
274 (`!s t u:real^N->bool.
275 {w + z | w IN {x + y | x IN s /\ y IN t} /\ z IN u} =
276 {x + v | x IN s /\ v IN {y + z | y IN t /\ z IN u}}`,
277 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN MESON_TAC[VECTOR_ADD_ASSOC]);;
279 (* ------------------------------------------------------------------------- *)
280 (* Infinitude of Euclidean space. *)
281 (* ------------------------------------------------------------------------- *)
283 let EUCLIDEAN_SPACE_INFINITE = prove
284 (`INFINITE(:real^N)`,
285 REWRITE_TAC[INFINITE] THEN DISCH_TAC THEN
286 FIRST_ASSUM(MP_TAC o ISPEC `vec:num->real^N` o
287 MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] FINITE_IMAGE_INJ)) THEN
288 REWRITE_TAC[VEC_EQ; SET_RULE `{x | f x IN UNIV} = UNIV`] THEN
289 REWRITE_TAC[GSYM INFINITE; num_INFINITE]);;
291 (* ------------------------------------------------------------------------- *)
292 (* Properties of the dot product. *)
293 (* ------------------------------------------------------------------------- *)
295 let DOT_SYM = VECTOR_ARITH `!x y. x dot y = y dot x`;;
297 let DOT_LADD = VECTOR_ARITH `!x y z. (x + y) dot z = (x dot z) + (y dot z)`;;
299 let DOT_RADD = VECTOR_ARITH `!x y z. x dot (y + z) = (x dot y) + (x dot z)`;;
301 let DOT_LSUB = VECTOR_ARITH `!x y z. (x - y) dot z = (x dot z) - (y dot z)`;;
303 let DOT_RSUB = VECTOR_ARITH `!x y z. x dot (y - z) = (x dot y) - (x dot z)`;;
305 let DOT_LMUL = VECTOR_ARITH `!c x y. (c % x) dot y = c * (x dot y)`;;
307 let DOT_RMUL = VECTOR_ARITH `!c x y. x dot (c % y) = c * (x dot y)`;;
309 let DOT_LNEG = VECTOR_ARITH `!x y. (--x) dot y = --(x dot y)`;;
311 let DOT_RNEG = VECTOR_ARITH `!x y. x dot (--y) = --(x dot y)`;;
313 let DOT_LZERO = VECTOR_ARITH `!x. (vec 0) dot x = &0`;;
315 let DOT_RZERO = VECTOR_ARITH `!x. x dot (vec 0) = &0`;;
317 let DOT_POS_LE = prove
318 (`!x. &0 <= x dot x`,
319 SIMP_TAC[dot; SUM_POS_LE_NUMSEG; REAL_LE_SQUARE]);;
322 (`!x:real^N. ((x dot x = &0) <=> (x = vec 0))`,
323 REPEAT GEN_TAC THEN EQ_TAC THENL [ALL_TAC; MESON_TAC[DOT_LZERO]] THEN
324 SIMP_TAC[dot; CART_EQ; vec; LAMBDA_BETA] THEN DISCH_TAC THEN
325 ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[REAL_ENTIRE] `x * x = &0`)] THEN
326 MATCH_MP_TAC SUM_POS_EQ_0_NUMSEG THEN ASM_REWRITE_TAC[REAL_LE_SQUARE]);;
328 let DOT_POS_LT = prove
329 (`!x. (&0 < x dot x) <=> ~(x = vec 0)`,
330 REWRITE_TAC[REAL_LT_LE; DOT_POS_LE] THEN MESON_TAC[DOT_EQ_0]);;
332 let FORALL_DOT_EQ_0 = prove
333 (`(!y. (!x. x dot y = &0) <=> y = vec 0) /\
334 (!x. (!y. x dot y = &0) <=> x = vec 0)`,
335 MESON_TAC[DOT_LZERO; DOT_RZERO; DOT_EQ_0]);;
337 (* ------------------------------------------------------------------------- *)
338 (* Introduce norms, but defer many properties till we get square roots. *)
339 (* ------------------------------------------------------------------------- *)
341 make_overloadable "norm" `:A->real`;;
342 overload_interface("norm",`vector_norm:real^N->real`);;
344 let vector_norm = new_definition
345 `norm x = sqrt(x dot x)`;;
347 (* ------------------------------------------------------------------------- *)
348 (* Useful for the special cases of 1 dimension. *)
349 (* ------------------------------------------------------------------------- *)
351 let FORALL_DIMINDEX_1 = prove
352 (`(!i. 1 <= i /\ i <= dimindex(:1) ==> P i) <=> P 1`,
353 MESON_TAC[DIMINDEX_1; LE_ANTISYM]);;
355 (* ------------------------------------------------------------------------- *)
356 (* The collapse of the general concepts to the real line R^1. *)
357 (* ------------------------------------------------------------------------- *)
359 let VECTOR_ONE = prove
360 (`!x:real^1. x = lambda i. x$1`,
361 SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN MESON_TAC[DIMINDEX_1; LE_ANTISYM]);;
363 let FORALL_REAL_ONE = prove
364 (`(!x:real^1. P x) <=> (!x. P(lambda i. x))`,
365 EQ_TAC THEN SIMP_TAC[] THEN DISCH_TAC THEN GEN_TAC THEN
366 FIRST_X_ASSUM(MP_TAC o SPEC `(x:real^1)$1`) THEN
367 REWRITE_TAC[GSYM VECTOR_ONE]);;
369 let NORM_REAL = prove
370 (`!x:real^1. norm(x) = abs(x$1)`,
371 REWRITE_TAC[vector_norm; dot; DIMINDEX_1; SUM_SING_NUMSEG;
372 GSYM REAL_POW_2; POW_2_SQRT_ABS]);;
374 (* ------------------------------------------------------------------------- *)
375 (* Metric function. *)
376 (* ------------------------------------------------------------------------- *)
378 override_interface("dist",`distance:real^N#real^N->real`);;
380 let dist = new_definition
381 `dist(x,y) = norm(x - y)`;;
383 let DIST_REAL = prove
384 (`!x:real^1 y. dist(x,y) = abs(x$1 - y$1)`,
385 SIMP_TAC[dist; NORM_REAL; vector_sub; LAMBDA_BETA; LE_REFL; DIMINDEX_1]);;
387 (* ------------------------------------------------------------------------- *)
388 (* A connectedness or intermediate value lemma with several applications. *)
389 (* ------------------------------------------------------------------------- *)
391 let CONNECTED_REAL_LEMMA = prove
392 (`!f:real->real^N a b e1 e2.
393 a <= b /\ f(a) IN e1 /\ f(b) IN e2 /\
394 (!e x. a <= x /\ x <= b /\ &0 < e
396 !y. abs(y - x) < d ==> dist(f(y),f(x)) < e) /\
397 (!y. y IN e1 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e1) /\
398 (!y. y IN e2 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e2) /\
399 ~(?x. a <= x /\ x <= b /\ f(x) IN e1 /\ f(x) IN e2)
400 ==> ?x. a <= x /\ x <= b /\ ~(f(x) IN e1) /\ ~(f(x) IN e2)`,
401 let tac = ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_TOTAL; REAL_LE_ANTISYM] in
402 REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN
403 MP_TAC(SPEC `\c. !x. a <= x /\ x <= c ==> (f(x):real^N) IN e1`
405 REWRITE_TAC[] THEN ANTS_TAC THENL [tac; ALL_TAC] THEN
406 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real` THEN STRIP_TAC THEN
407 SUBGOAL_THEN `a <= x /\ x <= b` STRIP_ASSUME_TAC THENL [tac; ALL_TAC] THEN
408 ASM_REWRITE_TAC[] THEN
409 SUBGOAL_THEN `!z. a <= z /\ z < x ==> (f(z):real^N) IN e1` ASSUME_TAC THENL
410 [ASM_MESON_TAC[REAL_NOT_LT; REAL_LT_IMP_LE]; ALL_TAC] THEN
411 REPEAT STRIP_TAC THENL
413 `?d. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real^N) IN e1`
414 STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
415 ASM_MESON_TAC[REAL_ARITH `z <= x + e /\ e < d ==> z < x \/ abs(z - x) < d`;
416 REAL_ARITH `&0 < e ==> ~(x + e <= x)`; REAL_DOWN];
418 `?d. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real^N) IN e2`
419 STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
420 MP_TAC(SPECL [`x - a`; `d:real`] REAL_DOWN2) THEN ANTS_TAC THENL
421 [ASM_MESON_TAC[REAL_LT_LE; REAL_SUB_LT]; ALL_TAC] THEN
422 ASM_MESON_TAC[REAL_ARITH `e < x - a ==> a <= x - e`;
423 REAL_ARITH `&0 < e /\ x <= b ==> x - e <= b`;
424 REAL_ARITH `&0 < e /\ e < d ==> x - e < x /\ abs((x - e) - x) < d`]]);;
426 (* ------------------------------------------------------------------------- *)
427 (* One immediately useful corollary is the existence of square roots! *)
428 (* ------------------------------------------------------------------------- *)
430 let SQUARE_BOUND_LEMMA = prove
431 (`!x. x < (&1 + x) * (&1 + x)`,
432 GEN_TAC THEN REWRITE_TAC[REAL_POW_2] THEN
433 MAP_EVERY (fun t -> MP_TAC(SPEC t REAL_LE_SQUARE)) [`x:real`; `&1 + x`] THEN
436 let SQUARE_CONTINUOUS = prove
438 ==> ?d. &0 < d /\ !y. abs(y - x) < d ==> abs(y * y - x * x) < e`,
439 REPEAT STRIP_TAC THEN ASM_CASES_TAC `x = &0` THENL
440 [ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_SUB_RZERO] THEN
441 EXISTS_TAC `inv(&1 + inv(e))` THEN
442 ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_LT_ADD; REAL_LT_01] THEN
443 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
444 EXISTS_TAC `inv(&1 + inv(e)) * inv(&1 + inv(e))` THEN
445 ASM_SIMP_TAC[REAL_ABS_MUL; REAL_LT_MUL2; REAL_ABS_POS] THEN
446 REWRITE_TAC[GSYM REAL_INV_MUL] THEN
447 GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN
448 MATCH_MP_TAC REAL_LE_INV2 THEN
449 ASM_SIMP_TAC[REAL_LT_IMP_LE; SQUARE_BOUND_LEMMA; REAL_LT_INV_EQ];
450 MP_TAC(SPECL [`abs(x)`; `e / (&3 * abs(x))`] REAL_DOWN2)THEN
451 ASM_SIMP_TAC[GSYM REAL_ABS_NZ; REAL_LT_DIV; REAL_LT_MUL; REAL_OF_NUM_LT;
452 ARITH; REAL_LT_RDIV_EQ] THEN
453 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
454 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `y:real` THEN
455 REWRITE_TAC[REAL_ARITH `x * x - y * y = (x - y) * (x + y)`] THEN
456 DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
457 EXISTS_TAC `d * &3 * abs(x)` THEN ASM_REWRITE_TAC[REAL_ABS_MUL] THEN
458 MATCH_MP_TAC REAL_LE_MUL2 THEN
459 ASM_SIMP_TAC[REAL_ABS_POS; REAL_LT_IMP_LE] THEN
460 MAP_EVERY UNDISCH_TAC [`abs (y - x) < d`; `d < abs(x)`] THEN
463 let SQRT_WORKS_GEN = prove
464 (`!x. real_sgn(sqrt x) = real_sgn x /\ sqrt(x) pow 2 = abs x`,
465 GEN_TAC THEN REWRITE_TAC[sqrt] THEN CONV_TAC SELECT_CONV THEN
466 SUBGOAL_THEN `!x. &0 < x ==> ?y. &0 < y /\ y pow 2 = x` ASSUME_TAC THENL
467 [REPEAT STRIP_TAC THEN
468 MP_TAC(ISPECL [`(\u. lambda i. u):real->real^1`; `&0`; `&1 + x`;
469 `{u:real^1 | u$1 * u$1 < x}`; `{u:real^1 | u$1 * u$1 > x}`]
470 CONNECTED_REAL_LEMMA) THEN
471 SIMP_TAC[LAMBDA_BETA; LE_REFL; DIMINDEX_1; DIST_REAL; IN_ELIM_THM] THEN
472 REWRITE_TAC[REAL_POW_2; REAL_ARITH `~(x < y) /\ ~(x > y) <=> x = y`] THEN
473 ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LT_LE; REAL_ENTIRE]] THEN
474 ASM_REWRITE_TAC[real_gt; SQUARE_BOUND_LEMMA; REAL_MUL_LZERO] THEN
475 CONJ_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[REAL_LT_ANTISYM]] THEN
476 MESON_TAC[SQUARE_CONTINUOUS; REAL_SUB_LT;
477 REAL_ARITH `abs(z2 - x2) < y - x2 ==> z2 < y`;
478 REAL_ARITH `abs(z2 - x2) < x2 - y ==> y < z2`];
479 ASM_CASES_TAC `x = &0` THEN
480 ASM_REWRITE_TAC[REAL_SGN_0; REAL_SGN_EQ; UNWIND_THM2] THEN
481 CONV_TAC REAL_RAT_REDUCE_CONV THEN
482 FIRST_X_ASSUM(MP_TAC o SPEC `abs x`) THEN
483 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
484 DISCH_THEN(X_CHOOSE_THEN `y:real` STRIP_ASSUME_TAC) THEN
485 EXISTS_TAC `real_sgn x * y` THEN
486 ASM_REWRITE_TAC[REAL_POW_MUL; GSYM REAL_SGN_POW; REAL_SGN_POW_2] THEN
487 REWRITE_TAC[REAL_SGN_MUL; REAL_SGN_REAL_SGN] THEN
488 ASM_SIMP_TAC[real_sgn; REAL_ARITH `&0 < abs x <=> ~(x = &0)`] THEN
489 REWRITE_TAC[REAL_MUL_LID; REAL_MUL_RID]]);;
491 let SQRT_UNIQUE_GEN = prove
492 (`!x y. real_sgn y = real_sgn x /\ y pow 2 = abs x ==> sqrt x = y`,
494 MP_TAC(GSYM(SPEC `x:real` SQRT_WORKS_GEN)) THEN
495 SIMP_TAC[REAL_RING `x pow 2 = y pow 2 <=> x:real = y \/ x = --y`] THEN
496 DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[IMP_CONJ_ALT] THEN
497 STRIP_TAC THEN ASM_REWRITE_TAC[REAL_SGN_NEG] THEN
498 SIMP_TAC[REAL_ARITH `--x = x <=> x = &0`; REAL_SGN_EQ; REAL_NEG_0; SQRT_0]);;
501 (`!x. sqrt(--x) = --sqrt(x)`,
502 GEN_TAC THEN MATCH_MP_TAC SQRT_UNIQUE_GEN THEN
503 REWRITE_TAC[REAL_SGN_NEG; REAL_POW_NEG; REAL_ABS_NEG; ARITH] THEN
504 REWRITE_TAC[SQRT_WORKS_GEN]);;
506 let REAL_SGN_SQRT = prove
507 (`!x. real_sgn(sqrt x) = real_sgn x`,
508 REWRITE_TAC[SQRT_WORKS_GEN]);;
510 let SQRT_WORKS = prove
511 (`!x. &0 <= x ==> &0 <= sqrt(x) /\ sqrt(x) pow 2 = x`,
512 REPEAT STRIP_TAC THEN MP_TAC(SPEC `x:real` SQRT_WORKS_GEN) THEN
513 REWRITE_TAC[real_sgn] THEN ASM_REAL_ARITH_TAC);;
515 let SQRT_POS_LE = prove
516 (`!x. &0 <= x ==> &0 <= sqrt(x)`,
517 MESON_TAC[SQRT_WORKS]);;
519 let SQRT_POW_2 = prove
520 (`!x. &0 <= x ==> sqrt(x) pow 2 = x`,
521 MESON_TAC[SQRT_WORKS]);;
523 let SQRT_POW2 = prove
524 (`!x. sqrt(x) pow 2 = x <=> &0 <= x`,
525 MESON_TAC[REAL_POW_2; REAL_LE_SQUARE; SQRT_POW_2]);;
528 (`!x y. sqrt(x * y) = sqrt x * sqrt y`,
529 REPEAT GEN_TAC THEN MATCH_MP_TAC SQRT_UNIQUE_GEN THEN
530 REWRITE_TAC[REAL_SGN_MUL; REAL_POW_MUL; SQRT_WORKS_GEN; REAL_ABS_MUL]);;
533 (`!x. sqrt (inv x) = inv(sqrt x)`,
534 GEN_TAC THEN MATCH_MP_TAC SQRT_UNIQUE_GEN THEN
535 REWRITE_TAC[REAL_SGN_INV; REAL_POW_INV; REAL_ABS_INV; SQRT_WORKS_GEN]);;
538 (`!x y. sqrt (x / y) = sqrt x / sqrt y`,
539 REWRITE_TAC[real_div; SQRT_MUL; SQRT_INV]);;
541 let SQRT_LT_0 = prove
542 (`!x. &0 < sqrt x <=> &0 < x`,
543 REWRITE_TAC[GSYM real_gt; GSYM REAL_SGN_EQ; REAL_SGN_SQRT]);;
545 let SQRT_EQ_0 = prove
546 (`!x. sqrt x = &0 <=> x = &0`,
547 ONCE_REWRITE_TAC[GSYM REAL_SGN_EQ] THEN REWRITE_TAC[REAL_SGN_SQRT]);;
549 let SQRT_LE_0 = prove
550 (`!x. &0 <= sqrt x <=> &0 <= x`,
551 REWRITE_TAC[REAL_ARITH `&0 <= x <=> &0 < x \/ x = &0`] THEN
552 REWRITE_TAC[SQRT_LT_0; SQRT_EQ_0]);;
554 let SQRT_MONO_LT = prove
555 (`!x y. x < y ==> sqrt(x) < sqrt(y)`,
556 SUBGOAL_THEN `!x y. &0 <= x /\ x < y ==> sqrt x < sqrt y` ASSUME_TAC THENL
557 [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_POW_LT2_REV THEN
558 EXISTS_TAC `2` THEN ASM_REWRITE_TAC[SQRT_WORKS_GEN; SQRT_LE_0] THEN
560 REPEAT STRIP_TAC THEN ASM_CASES_TAC `&0 <= x` THEN ASM_SIMP_TAC[] THEN
561 ASM_CASES_TAC `&0 <= y` THENL
562 [MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `&0` THEN
563 ASM_REWRITE_TAC[GSYM REAL_NOT_LE; SQRT_LE_0];
564 FIRST_X_ASSUM(MP_TAC o SPECL [`--y:real`; `--x:real`]) THEN
565 REWRITE_TAC[SQRT_NEG] THEN ASM_REAL_ARITH_TAC]]);;
567 let SQRT_MONO_LE = prove
568 (`!x y. x <= y ==> sqrt(x) <= sqrt(y)`,
569 MESON_TAC[REAL_LE_LT; SQRT_MONO_LT]);;
571 let SQRT_MONO_LT_EQ = prove
572 (`!x y. sqrt(x) < sqrt(y) <=> x < y`,
573 MESON_TAC[REAL_NOT_LT; SQRT_MONO_LT; SQRT_MONO_LE]);;
575 let SQRT_MONO_LE_EQ = prove
576 (`!x y. sqrt(x) <= sqrt(y) <=> x <= y`,
577 MESON_TAC[REAL_NOT_LT; SQRT_MONO_LT; SQRT_MONO_LE]);;
580 (`!x y. sqrt(x) = sqrt(y) <=> x = y`,
581 SIMP_TAC[GSYM REAL_LE_ANTISYM; SQRT_MONO_LE_EQ]);;
583 let SQRT_POS_LT = prove
584 (`!x. &0 < x ==> &0 < sqrt(x)`,
585 MESON_TAC[REAL_LT_LE; SQRT_POS_LE; SQRT_EQ_0]);;
587 let REAL_LE_LSQRT = prove
588 (`!x y. &0 <= y /\ x <= y pow 2 ==> sqrt(x) <= y`,
589 MESON_TAC[SQRT_MONO_LE; REAL_POW_LE; POW_2_SQRT]);;
591 let REAL_LE_RSQRT = prove
592 (`!x y. x pow 2 <= y ==> x <= sqrt(y)`,
593 MESON_TAC[REAL_LE_TOTAL; SQRT_MONO_LE; SQRT_POS_LE; REAL_POW_2;
594 REAL_LE_SQUARE; REAL_LE_TRANS; POW_2_SQRT]);;
596 let REAL_LT_LSQRT = prove
597 (`!x y. &0 <= y /\ x < y pow 2 ==> sqrt x < y`,
598 MESON_TAC[SQRT_MONO_LT; REAL_POW_LE; POW_2_SQRT]);;
600 let REAL_LT_RSQRT = prove
601 (`!x y. x pow 2 < y ==> x < sqrt(y)`,
602 REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH `abs x < a ==> x < a`) THEN
603 REWRITE_TAC[GSYM POW_2_SQRT_ABS] THEN MATCH_MP_TAC SQRT_MONO_LT THEN
604 ASM_REWRITE_TAC[REAL_POW_2; REAL_LE_SQUARE]);;
606 let SQRT_EVEN_POW2 = prove
607 (`!n. EVEN n ==> (sqrt(&2 pow n) = &2 pow (n DIV 2))`,
608 SIMP_TAC[EVEN_EXISTS; LEFT_IMP_EXISTS_THM; DIV_MULT; ARITH_EQ] THEN
609 MESON_TAC[SQRT_UNIQUE; REAL_POW_POW; MULT_SYM; REAL_POW_LE; REAL_POS]);;
611 let REAL_DIV_SQRT = prove
612 (`!x. &0 <= x ==> x / sqrt(x) = sqrt(x)`,
613 REWRITE_TAC[REAL_LE_LT] THEN REPEAT STRIP_TAC THENL
614 [ALL_TAC; ASM_MESON_TAC[SQRT_0; real_div; REAL_MUL_LZERO]] THEN
615 ASM_SIMP_TAC[REAL_EQ_LDIV_EQ; SQRT_POS_LT; GSYM REAL_POW_2] THEN
616 ASM_SIMP_TAC[SQRT_POW_2; REAL_LT_IMP_LE]);;
618 let REAL_RSQRT_LE = prove
619 (`!x y. &0 <= x /\ &0 <= y /\ x <= sqrt y ==> x pow 2 <= y`,
620 MESON_TAC[REAL_POW_LE2; SQRT_POW_2]);;
622 let REAL_LSQRT_LE = prove
623 (`!x y. &0 <= x /\ sqrt x <= y ==> x <= y pow 2`,
624 MESON_TAC[REAL_POW_LE2; SQRT_POS_LE; REAL_LE_TRANS; SQRT_POW_2]);;
626 let REAL_SQRT_POW_2 = prove
627 (`!x. sqrt x pow 2 = abs x`,
628 REWRITE_TAC[SQRT_WORKS_GEN]);;
630 (* ------------------------------------------------------------------------- *)
631 (* Hence derive more interesting properties of the norm. *)
632 (* ------------------------------------------------------------------------- *)
636 REWRITE_TAC[vector_norm; DOT_LZERO; SQRT_0]);;
638 let NORM_POS_LE = prove
640 GEN_TAC THEN SIMP_TAC[DOT_POS_LE; vector_norm; SQRT_POS_LE]);;
643 (`!x. norm(--x) = norm x`,
644 REWRITE_TAC[vector_norm; DOT_LNEG; DOT_RNEG; REAL_NEG_NEG]);;
647 (`!x y. norm(x - y) = norm(y - x)`,
648 MESON_TAC[NORM_NEG; VECTOR_NEG_SUB]);;
651 (`!a x. norm(a % x) = abs(a) * norm x`,
652 REWRITE_TAC[vector_norm; DOT_LMUL; DOT_RMUL; REAL_MUL_ASSOC] THEN
653 REWRITE_TAC[SQRT_MUL; GSYM REAL_POW_2; REAL_SQRT_POW_2]);;
655 let NORM_EQ_0_DOT = prove
656 (`!x. (norm x = &0) <=> (x dot x = &0)`,
657 SIMP_TAC[vector_norm; SQRT_EQ_0; DOT_POS_LE]);;
659 let NORM_EQ_0 = prove
660 (`!x. (norm x = &0) <=> (x = vec 0)`,
661 SIMP_TAC[vector_norm; DOT_EQ_0; SQRT_EQ_0; DOT_POS_LE]);;
663 let NORM_POS_LT = prove
664 (`!x. &0 < norm x <=> ~(x = vec 0)`,
665 MESON_TAC[REAL_LT_LE; NORM_POS_LE; NORM_EQ_0]);;
667 let NORM_POW_2 = prove
668 (`!x. norm(x) pow 2 = x dot x`,
669 SIMP_TAC[vector_norm; SQRT_POW_2; DOT_POS_LE]);;
671 let NORM_EQ_0_IMP = prove
672 (`!x. (norm x = &0) ==> (x = vec 0)`,
673 MESON_TAC[NORM_EQ_0]);;
675 let NORM_LE_0 = prove
676 (`!x. norm x <= &0 <=> (x = vec 0)`,
677 MESON_TAC[REAL_LE_ANTISYM; NORM_EQ_0; NORM_POS_LE]);;
679 let VECTOR_MUL_EQ_0 = prove
680 (`!a x. (a % x = vec 0) <=> (a = &0) \/ (x = vec 0)`,
681 REWRITE_TAC[GSYM NORM_EQ_0; NORM_MUL; REAL_ABS_ZERO; REAL_ENTIRE]);;
683 let VECTOR_MUL_LCANCEL = prove
684 (`!a x y. (a % x = a % y) <=> (a = &0) \/ (x = y)`,
685 MESON_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_LDISTRIB; VECTOR_SUB_EQ]);;
687 let VECTOR_MUL_RCANCEL = prove
688 (`!a b x. (a % x = b % x) <=> (a = b) \/ (x = vec 0)`,
689 MESON_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_RDISTRIB; REAL_SUB_0; VECTOR_SUB_EQ]);;
691 let VECTOR_MUL_LCANCEL_IMP = prove
692 (`!a x y. ~(a = &0) /\ (a % x = a % y) ==> (x = y)`,
693 MESON_TAC[VECTOR_MUL_LCANCEL]);;
695 let VECTOR_MUL_RCANCEL_IMP = prove
696 (`!a b x. ~(x = vec 0) /\ (a % x = b % x) ==> (a = b)`,
697 MESON_TAC[VECTOR_MUL_RCANCEL]);;
699 let NORM_CAUCHY_SCHWARZ = prove
700 (`!(x:real^N) y. x dot y <= norm(x) * norm(y)`,
701 REPEAT STRIP_TAC THEN MAP_EVERY ASM_CASES_TAC
702 [`norm(x:real^N) = &0`; `norm(y:real^N) = &0`] THEN
703 ASM_SIMP_TAC[NORM_EQ_0_IMP; DOT_LZERO; DOT_RZERO;
704 REAL_MUL_LZERO; REAL_MUL_RZERO] THEN
705 MP_TAC(ISPEC `norm(y:real^N) % x - norm(x:real^N) % y` DOT_POS_LE) THEN
706 REWRITE_TAC[DOT_RSUB; DOT_LSUB; DOT_LMUL; DOT_RMUL; GSYM NORM_POW_2;
707 REAL_POW_2; REAL_LE_REFL] THEN
708 REWRITE_TAC[DOT_SYM; REAL_ARITH
709 `&0 <= y * (y * x * x - x * d) - x * (y * d - x * y * y) <=>
710 x * y * d <= x * y * x * y`] THEN
711 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_LE; NORM_POS_LE]);;
713 let NORM_CAUCHY_SCHWARZ_ABS = prove
714 (`!x:real^N y. abs(x dot y) <= norm(x) * norm(y)`,
715 REPEAT GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_CAUCHY_SCHWARZ) THEN
716 DISCH_THEN(fun th -> MP_TAC(SPEC `y:real^N` th) THEN
717 MP_TAC(SPEC `--(y:real^N)` th)) THEN
718 REWRITE_TAC[DOT_RNEG; NORM_NEG] THEN REAL_ARITH_TAC);;
720 let REAL_ABS_NORM = prove
721 (`!x. abs(norm x) = norm x`,
722 REWRITE_TAC[NORM_POS_LE; REAL_ABS_REFL]);;
724 let NORM_CAUCHY_SCHWARZ_DIV = prove
725 (`!x:real^N y. abs((x dot y) / (norm x * norm y)) <= &1`,
727 MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN
728 ASM_REWRITE_TAC[NORM_0; REAL_MUL_LZERO; REAL_MUL_RZERO; real_div;
729 REAL_INV_1; DOT_LZERO; DOT_RZERO; REAL_ABS_NUM; REAL_POS] THEN
730 ASM_SIMP_TAC[GSYM real_div; REAL_ABS_DIV; REAL_LE_LDIV_EQ; REAL_LT_MUL;
731 REAL_ABS_INV; NORM_POS_LT; REAL_ABS_MUL; REAL_ABS_NORM] THEN
732 REWRITE_TAC[REAL_MUL_LID; NORM_CAUCHY_SCHWARZ_ABS]);;
734 let NORM_TRIANGLE = prove
735 (`!x y. norm(x + y) <= norm(x) + norm(y)`,
736 REPEAT GEN_TAC THEN REWRITE_TAC[vector_norm] THEN
737 MATCH_MP_TAC REAL_LE_LSQRT THEN
738 SIMP_TAC[GSYM vector_norm; DOT_POS_LE; NORM_POS_LE; REAL_LE_ADD] THEN
739 REWRITE_TAC[DOT_LADD; DOT_RADD; REAL_POW_2; GSYM NORM_POW_2] THEN
740 SIMP_TAC[NORM_CAUCHY_SCHWARZ; DOT_SYM; REAL_ARITH
741 `d <= x * y ==> (x * x + d) + (d + y * y) <= (x + y) * (x + y)`]);;
743 let NORM_TRIANGLE_SUB = prove
744 (`!x y:real^N. norm(x) <= norm(y) + norm(x - y)`,
745 MESON_TAC[NORM_TRIANGLE; VECTOR_SUB_ADD2]);;
747 let NORM_TRIANGLE_LE = prove
748 (`!x y. norm(x) + norm(y) <= e ==> norm(x + y) <= e`,
749 MESON_TAC[REAL_LE_TRANS; NORM_TRIANGLE]);;
751 let NORM_TRIANGLE_LT = prove
752 (`!x y. norm(x) + norm(y) < e ==> norm(x + y) < e`,
753 MESON_TAC[REAL_LET_TRANS; NORM_TRIANGLE]);;
755 let COMPONENT_LE_NORM = prove
756 (`!x:real^N i. abs(x$i) <= norm x`,
757 REPEAT GEN_TAC THEN SUBGOAL_THEN
758 `?k. 1 <= k /\ k <= dimindex(:N) /\ !x:real^N. x$i = x$k`
759 STRIP_ASSUME_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
760 ASM_REWRITE_TAC[] THEN REWRITE_TAC[vector_norm] THEN
761 MATCH_MP_TAC REAL_LE_RSQRT THEN REWRITE_TAC[GSYM REAL_ABS_POW] THEN
762 REWRITE_TAC[real_abs; REAL_POW_2; REAL_LE_SQUARE] THEN
764 `x$k * (x:real^N)$k =
765 sum(1..dimindex(:N)) (\i. if i = k then x$k * x$k else &0)`
767 [REWRITE_TAC[SUM_DELTA] THEN ASM_REWRITE_TAC[IN_NUMSEG]; ALL_TAC] THEN
768 REWRITE_TAC[dot] THEN MATCH_MP_TAC SUM_LE THEN
769 REWRITE_TAC[FINITE_NUMSEG] THEN
770 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
771 ASM_REWRITE_TAC[REAL_LE_REFL; REAL_LE_SQUARE]);;
773 let NORM_BOUND_COMPONENT_LE = prove
774 (`!x:real^N e. norm(x) <= e
775 ==> !i. 1 <= i /\ i <= dimindex(:N) ==> abs(x$i) <= e`,
776 MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS]);;
778 let NORM_BOUND_COMPONENT_LT = prove
779 (`!x:real^N e. norm(x) < e
780 ==> !i. 1 <= i /\ i <= dimindex(:N) ==> abs(x$i) < e`,
781 MESON_TAC[COMPONENT_LE_NORM; REAL_LET_TRANS]);;
783 let NORM_LE_L1 = prove
784 (`!x:real^N. norm x <= sum(1..dimindex(:N)) (\i. abs(x$i))`,
785 REPEAT GEN_TAC THEN REWRITE_TAC[vector_norm; dot] THEN
786 MATCH_MP_TAC REAL_LE_LSQRT THEN REWRITE_TAC[REAL_POW_2] THEN
787 SIMP_TAC[SUM_POS_LE; FINITE_NUMSEG; REAL_LE_SQUARE; REAL_ABS_POS] THEN
788 SPEC_TAC(`dimindex(:N)`,`n:num`) THEN INDUCT_TAC THEN
789 REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH_EQ; ARITH_RULE `1 <= SUC n`] THEN
790 SIMP_TAC[REAL_MUL_LZERO; REAL_LE_REFL] THEN
791 MATCH_MP_TAC(REAL_ARITH
792 `a2 <= a * a /\ &0 <= a * b /\ b2 <= b * b
793 ==> a2 + b2 <= (a + b) * (a + b)`) THEN
794 ASM_SIMP_TAC[SUM_POS_LE; REAL_LE_MUL; REAL_ABS_POS; FINITE_NUMSEG] THEN
795 REWRITE_TAC[GSYM REAL_ABS_MUL] THEN REAL_ARITH_TAC);;
797 let REAL_ABS_SUB_NORM = prove
798 (`abs(norm(x) - norm(y)) <= norm(x - y)`,
799 REWRITE_TAC[REAL_ARITH `abs(x - y) <= a <=> x <= y + a /\ y <= x + a`] THEN
800 MESON_TAC[NORM_TRIANGLE_SUB; NORM_SUB]);;
803 (`!x y. norm(x) <= norm(y) <=> x dot x <= y dot y`,
804 REWRITE_TAC[vector_norm] THEN MESON_TAC[SQRT_MONO_LE_EQ; DOT_POS_LE]);;
807 (`!x y. norm(x) < norm(y) <=> x dot x < y dot y`,
808 REWRITE_TAC[vector_norm] THEN MESON_TAC[SQRT_MONO_LT_EQ; DOT_POS_LE]);;
811 (`!x y. (norm x = norm y) <=> (x dot x = y dot y)`,
812 REWRITE_TAC[GSYM REAL_LE_ANTISYM; NORM_LE]);;
814 let NORM_EQ_1 = prove
815 (`!x. norm(x) = &1 <=> x dot x = &1`,
816 GEN_TAC THEN GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM SQRT_1] THEN
817 SIMP_TAC[vector_norm; SQRT_INJ; DOT_POS_LE; REAL_POS]);;
819 let NORM_LE_COMPONENTWISE = prove
820 (`!x:real^N y:real^N.
821 (!i. 1 <= i /\ i <= dimindex(:N) ==> abs(x$i) <= abs(y$i))
822 ==> norm(x) <= norm(y)`,
823 REPEAT STRIP_TAC THEN REWRITE_TAC[NORM_LE; dot] THEN
824 MATCH_MP_TAC SUM_LE_NUMSEG THEN
825 ASM_SIMP_TAC[GSYM REAL_POW_2; GSYM REAL_LE_SQUARE_ABS]);;
827 let L1_LE_NORM = prove
829 sum(1..dimindex(:N)) (\i. abs(x$i)) <= sqrt(&(dimindex(:N))) * norm x`,
831 (`!x n. &n * sum(1..n) (\i. x i pow 2) - (sum(1..n) x) pow 2 =
832 sum(1..n) (\i. sum(i+1..n) (\j. (x i - x j) pow 2))`,
833 GEN_TAC THEN CONV_TAC(BINDER_CONV SYM_CONV) THEN INDUCT_TAC THEN
834 REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH; ARITH_RULE `1 <= SUC n`] THEN
835 CONV_TAC REAL_RAT_REDUCE_CONV THEN
836 SIMP_TAC[ARITH_RULE `i <= n ==> i + 1 <= SUC n`; SUM_TRIV_NUMSEG;
837 ARITH_RULE `~(n + 1 <= n)`; ARITH_RULE `n < SUC n + 1`] THEN
838 ASM_REWRITE_TAC[SUM_ADD_NUMSEG; REAL_ADD_RID] THEN
839 REWRITE_TAC[REAL_ARITH
840 `(x - y) pow 2 = (x pow 2 + y pow 2) - &2 * x * y`] THEN
841 REWRITE_TAC[SUM_ADD_NUMSEG; SUM_SUB_NUMSEG; SUM_LMUL; SUM_RMUL;
842 GSYM REAL_OF_NUM_SUC; SUM_CONST_NUMSEG; ADD_SUB] THEN
845 MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ abs x <= abs y ==> x <= y`) THEN
846 SIMP_TAC[REAL_LE_MUL; NORM_POS_LE; SQRT_POS_LE; REAL_POS] THEN
847 REWRITE_TAC[REAL_LE_SQUARE_ABS; REAL_POW_MUL] THEN
848 SIMP_TAC[SQRT_POW_2; REAL_POS; NORM_POW_2; dot] THEN
849 REWRITE_TAC[GSYM REAL_POW_2] THEN
850 GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_POW2_ABS] THEN
851 ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN REWRITE_TAC[lemma] THEN
852 SIMP_TAC[SUM_POS_LE_NUMSEG; REAL_LE_POW_2]);;
854 (* ------------------------------------------------------------------------- *)
855 (* Squaring equations and inequalities involving norms. *)
856 (* ------------------------------------------------------------------------- *)
858 let DOT_SQUARE_NORM = prove
859 (`!x. x dot x = norm(x) pow 2`,
860 SIMP_TAC[vector_norm; SQRT_POW_2; DOT_POS_LE]);;
862 let NORM_EQ_SQUARE = prove
863 (`!x:real^N. norm(x) = a <=> &0 <= a /\ x dot x = a pow 2`,
864 REWRITE_TAC[DOT_SQUARE_NORM] THEN
865 ONCE_REWRITE_TAC[REAL_RING `x pow 2 = a pow 2 <=> x = a \/ x + a = &0`] THEN
866 GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_POS_LE) THEN REAL_ARITH_TAC);;
868 let NORM_LE_SQUARE = prove
869 (`!x:real^N. norm(x) <= a <=> &0 <= a /\ x dot x <= a pow 2`,
870 REWRITE_TAC[DOT_SQUARE_NORM; GSYM REAL_LE_SQUARE_ABS] THEN
871 GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_POS_LE) THEN REAL_ARITH_TAC);;
873 let NORM_GE_SQUARE = prove
874 (`!x:real^N. norm(x) >= a <=> a <= &0 \/ x dot x >= a pow 2`,
875 REWRITE_TAC[real_ge; DOT_SQUARE_NORM; GSYM REAL_LE_SQUARE_ABS] THEN
876 GEN_TAC THEN MP_TAC(ISPEC `x:real^N` NORM_POS_LE) THEN REAL_ARITH_TAC);;
878 let NORM_LT_SQUARE = prove
879 (`!x:real^N. norm(x) < a <=> &0 < a /\ x dot x < a pow 2`,
880 REWRITE_TAC[REAL_ARITH `x < a <=> ~(x >= a)`; NORM_GE_SQUARE] THEN
883 let NORM_GT_SQUARE = prove
884 (`!x:real^N. norm(x) > a <=> a < &0 \/ x dot x > a pow 2`,
885 REWRITE_TAC[REAL_ARITH `x > a <=> ~(x <= a)`; NORM_LE_SQUARE] THEN
888 let NORM_LT_SQUARE_ALT = prove
889 (`!x:real^N. norm(x) < a <=> &0 <= a /\ x dot x < a pow 2`,
890 REWRITE_TAC[REAL_ARITH `x < a <=> ~(x >= a)`; NORM_GE_SQUARE] THEN
891 REPEAT GEN_TAC THEN ASM_CASES_TAC `a = &0` THENL
892 [ASM_REWRITE_TAC[real_ge] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
893 REWRITE_TAC[DOT_POS_LE];
894 ASM_REAL_ARITH_TAC]);;
896 (* ------------------------------------------------------------------------- *)
897 (* General linear decision procedure for normed spaces. *)
898 (* ------------------------------------------------------------------------- *)
901 let find_normedterms =
902 let augment_norm b tm acc =
904 Comb(Const("vector_norm",_),v) -> insert (b,v) acc
906 let rec find_normedterms tm acc =
908 Comb(Comb(Const("real_add",_),l),r) ->
909 find_normedterms l (find_normedterms r acc)
910 | Comb(Comb(Const("real_mul",_),c),n) ->
911 if not (is_ratconst c) then acc else
912 augment_norm (rat_of_term c >=/ Int 0) n acc
913 | _ -> augment_norm true tm acc in
915 let lincomb_neg t = mapf minus_num t in
916 let lincomb_cmul c t = if c =/ Int 0 then undefined else mapf (( */ ) c) t in
917 let lincomb_add l r = combine (+/) (fun x -> x =/ Int 0) l r in
918 let lincomb_sub l r = lincomb_add l (lincomb_neg r) in
919 let lincomb_eq l r = lincomb_sub l r = undefined in
920 let rec vector_lincomb tm =
922 Comb(Comb(Const("vector_add",_),l),r) ->
923 lincomb_add (vector_lincomb l) (vector_lincomb r)
924 | Comb(Comb(Const("vector_sub",_),l),r) ->
925 lincomb_sub (vector_lincomb l) (vector_lincomb r)
926 | Comb(Comb(Const("%",_),l),r) ->
927 lincomb_cmul (rat_of_term l) (vector_lincomb r)
928 | Comb(Const("vector_neg",_),t) ->
929 lincomb_neg (vector_lincomb t)
930 | Comb(Const("vec",_),n) when is_numeral n & dest_numeral n =/ Int 0 ->
932 | _ -> (tm |=> Int 1) in
933 let vector_lincombs tms =
935 if can (assoc t) fns then fns else
936 let f = vector_lincomb t in
937 try let _,f' = find (fun (_,f') -> lincomb_eq f f') fns in
939 with Failure _ -> (t,f)::fns) tms [] in
940 let rec replacenegnorms fn tm =
942 Comb(Comb(Const("real_add",_),l),r) ->
943 BINOP_CONV (replacenegnorms fn) tm
944 | Comb(Comb(Const("real_mul",_),c),n) when rat_of_term c </ Int 0 ->
948 if defined eq v then (v |-> minus_num(apply eq v)) eq else eq in
949 let rec allsubsets s =
952 | (a::t) -> let res = allsubsets t in
953 map (fun b -> a::b) res @ res in
954 let evaluate env lin =
955 foldr (fun x c s -> s +/ c */ apply env x) lin (Int 0) in
956 let rec solve (vs,eqs) =
958 [],[] -> (0 |=> Int 1)
960 let v = hd(intersect vs (dom eq)) in
961 let c = apply eq v in
962 let vdef = lincomb_cmul (Int(-1) // c) eq in
964 if not(defined eqn v) then eqn else
965 lincomb_add (lincomb_cmul (apply eqn v) vdef) eqn in
966 let soln = solve (subtract vs [v],map eliminate oeqs) in
967 (v |-> evaluate soln (undefine v vdef)) soln in
968 let rec combinations k l =
969 if k = 0 then [[]] else
972 | h::t -> map (fun c -> h::c) (combinations (k - 1) t) @
974 let vertices vs eqs =
976 let soln = solve(vs,cmb) in
977 map (fun v -> tryapplyd soln v (Int 0)) vs in
978 let rawvs = mapfilter vertex (combinations (length vs) eqs) in
979 let unset = filter (forall (fun c -> c >=/ Int 0)) rawvs in
980 itlist (insert' (forall2 (=/))) unset [] in
981 let subsumes l m = forall2 (fun x y -> abs_num x <=/ abs_num y) l m in
982 let rec subsume todo dun =
985 | v::ovs -> let dun' = if exists (fun w -> subsumes w v) dun then dun
986 else v::(filter (fun w -> not(subsumes v w)) dun) in
989 let MATCH_pth = (MATCH_MP o prove)
990 (`!b x. b >= norm(x) ==> !c. abs(c) * b >= norm(c % x)`,
991 SIMP_TAC[NORM_MUL; real_ge; REAL_LE_LMUL; REAL_ABS_POS]) in
992 fun c th -> ISPEC(term_of_rat c) (MATCH_pth th) in
994 let MATCH_pth = (MATCH_MP o prove)
995 (`!b1 b2 x1 x2. b1 >= norm(x1) /\ b2 >= norm(x2)
996 ==> b1 + b2 >= norm(x1 + x2)`,
997 REWRITE_TAC[real_ge] THEN REPEAT STRIP_TAC THEN
998 MATCH_MP_TAC NORM_TRIANGLE_LE THEN ASM_SIMP_TAC[REAL_LE_ADD2]) in
999 fun th1 th2 -> MATCH_pth (CONJ th1 th2) in
1000 let INEQUALITY_CANON_RULE =
1001 CONV_RULE(LAND_CONV REAL_POLY_CONV) o
1002 CONV_RULE(LAND_CONV REAL_RAT_REDUCE_CONV) o
1003 GEN_REWRITE_RULE I [REAL_ARITH `s >= t <=> s - t >= &0`] in
1004 let NORM_CANON_CONV =
1005 let APPLY_pth1 = GEN_REWRITE_CONV I
1006 [VECTOR_ARITH `x:real^N = &1 % x`]
1007 and APPLY_pth2 = GEN_REWRITE_CONV I
1008 [VECTOR_ARITH `x - y:real^N = x + --y`]
1009 and APPLY_pth3 = GEN_REWRITE_CONV I
1010 [VECTOR_ARITH `--x:real^N = -- &1 % x`]
1011 and APPLY_pth4 = GEN_REWRITE_CONV I
1012 [VECTOR_ARITH `&0 % x:real^N = vec 0`;
1013 VECTOR_ARITH `c % vec 0:real^N = vec 0`]
1014 and APPLY_pth5 = GEN_REWRITE_CONV I
1015 [VECTOR_ARITH `c % (d % x) = (c * d) % x`]
1016 and APPLY_pth6 = GEN_REWRITE_CONV I
1017 [VECTOR_ARITH `c % (x + y) = c % x + c % y`]
1018 and APPLY_pth7 = GEN_REWRITE_CONV I
1019 [VECTOR_ARITH `vec 0 + x = x`;
1020 VECTOR_ARITH `x + vec 0 = x`]
1022 GEN_REWRITE_CONV I [VECTOR_ARITH `c % x + d % x = (c + d) % x`] THENC
1023 LAND_CONV REAL_RAT_ADD_CONV THENC
1024 GEN_REWRITE_CONV TRY_CONV [VECTOR_ARITH `&0 % x = vec 0`]
1027 [VECTOR_ARITH `(c % x + z) + d % x = (c + d) % x + z`;
1028 VECTOR_ARITH `c % x + (d % x + z) = (c + d) % x + z`;
1029 VECTOR_ARITH `(c % x + w) + (d % x + z) = (c + d) % x + (w + z)`] THENC
1030 LAND_CONV(LAND_CONV REAL_RAT_ADD_CONV)
1032 GEN_REWRITE_CONV I [VECTOR_ARITH `&0 % x + y = y`]
1035 [VECTOR_ARITH `c % x + d % y = c % x + d % y`;
1036 VECTOR_ARITH `(c % x + z) + d % y = c % x + (z + d % y)`;
1037 VECTOR_ARITH `c % x + (d % y + z) = c % x + (d % y + z)`;
1038 VECTOR_ARITH `(c % x + w) + (d % y + z) = c % x + (w + (d % y + z))`]
1041 [VECTOR_ARITH `c % x + d % y = d % y + c % x`;
1042 VECTOR_ARITH `(c % x + z) + d % y = d % y + (c % x + z)`;
1043 VECTOR_ARITH `c % x + (d % y + z) = d % y + (c % x + z)`;
1044 VECTOR_ARITH `(c % x + w) + (d % y + z) = d % y + ((c % x + w) + z)`]
1046 GEN_REWRITE_CONV TRY_CONV
1047 [VECTOR_ARITH `x + vec 0 = x`] in
1050 Comb(Comb(Const("vector_add",_),Comb(Comb(Const("%",_),l),v)),r) -> v
1051 | Comb(Comb(Const("%",_),l),v) -> v
1052 | _ -> failwith "headvector: non-canonical term" in
1053 let rec VECTOR_CMUL_CONV tm =
1054 ((APPLY_pth5 THENC LAND_CONV REAL_RAT_MUL_CONV) ORELSEC
1055 (APPLY_pth6 THENC BINOP_CONV VECTOR_CMUL_CONV)) tm
1056 and VECTOR_ADD_CONV tm =
1057 try APPLY_pth7 tm with Failure _ ->
1058 try APPLY_pth8 tm with Failure _ ->
1060 Comb(Comb(Const("vector_add",_),lt),rt) ->
1061 let l = headvector lt and r = headvector rt in
1062 if l < r then (APPLY_pthb THENC
1063 RAND_CONV VECTOR_ADD_CONV THENC
1065 else if r < l then (APPLY_pthc THENC
1066 RAND_CONV VECTOR_ADD_CONV THENC
1069 ((APPLY_ptha THENC VECTOR_ADD_CONV) ORELSEC
1070 RAND_CONV VECTOR_ADD_CONV THENC
1073 let rec VECTOR_CANON_CONV tm =
1075 Comb(Comb(Const("vector_add",_),l),r) ->
1076 let lth = VECTOR_CANON_CONV l and rth = VECTOR_CANON_CONV r in
1077 let th = MK_COMB(AP_TERM (rator(rator tm)) lth,rth) in
1078 CONV_RULE (RAND_CONV VECTOR_ADD_CONV) th
1079 | Comb(Comb(Const("%",_),l),r) ->
1080 let rth = AP_TERM (rator tm) (VECTOR_CANON_CONV r) in
1081 CONV_RULE (RAND_CONV(APPLY_pth4 ORELSEC VECTOR_CMUL_CONV)) rth
1082 | Comb(Comb(Const("vector_sub",_),l),r) ->
1083 (APPLY_pth2 THENC VECTOR_CANON_CONV) tm
1084 | Comb(Const("vector_neg",_),t) ->
1085 (APPLY_pth3 THENC VECTOR_CANON_CONV) tm
1086 | Comb(Const("vec",_),n) when is_numeral n & dest_numeral n =/ Int 0 ->
1088 | _ -> APPLY_pth1 tm in
1091 Comb(Const("vector_norm",_),e) -> RAND_CONV VECTOR_CANON_CONV tm
1092 | _ -> failwith "NORM_CANON_CONV" in
1093 let REAL_VECTOR_COMBO_PROVER =
1094 let pth_zero = prove(`norm(vec 0:real^N) = &0`,REWRITE_TAC[NORM_0])
1095 and tv_n = mk_vartype "N" in
1096 fun translator (nubs,ges,gts) ->
1097 let sources = map (rand o rand o concl) nubs
1098 and rawdests = itlist (find_normedterms o lhand o concl) (ges @ gts) [] in
1099 if not (forall fst rawdests) then failwith "Sanity check" else
1100 let dests = setify (map snd rawdests) in
1101 let srcfuns = map vector_lincomb sources
1102 and destfuns = map vector_lincomb dests in
1103 let vvs = itlist (union o dom) (srcfuns @ destfuns) [] in
1104 let n = length srcfuns in
1106 let srccombs = zip srcfuns nvs in
1108 let coefficients x =
1109 let inp = if defined d x then 0 |=> minus_num(apply d x)
1111 itlist (fun (f,v) g -> if defined f x then (v |-> apply f x) g else g)
1113 let equations = map coefficients vvs
1114 and inequalities = map (fun n -> (n |=> Int 1)) nvs in
1115 let plausiblevertices f =
1116 let flippedequations = map (itlist flip f) equations in
1117 let constraints = flippedequations @ inequalities in
1118 let rawverts = vertices nvs constraints in
1119 let check_solution v =
1120 let f = itlist2 (|->) nvs v (0 |=> Int 1) in
1121 forall (fun e -> evaluate f e =/ Int 0) flippedequations in
1122 let goodverts = filter check_solution rawverts in
1123 let signfixups = map (fun n -> if mem n f then -1 else 1) nvs in
1124 map (map2 (fun s c -> Int s */ c) signfixups) goodverts in
1125 let allverts = itlist (@) (map plausiblevertices (allsubsets nvs)) [] in
1126 subsume allverts [] in
1127 let compute_ineq v =
1128 let ths = mapfilter (fun (v,t) -> if v =/ Int 0 then fail()
1129 else NORM_CMUL_RULE v t)
1131 INEQUALITY_CANON_RULE (end_itlist NORM_ADD_RULE ths) in
1132 let ges' = mapfilter compute_ineq (itlist ((@) o consider) destfuns []) @
1133 map INEQUALITY_CANON_RULE nubs @ ges in
1134 let zerodests = filter
1135 (fun t -> dom(vector_lincomb t) = []) (map snd rawdests) in
1136 REAL_LINEAR_PROVER translator
1137 (map (fun t -> INST_TYPE [last(snd(dest_type(type_of t))),tv_n] pth_zero)
1139 map (CONV_RULE(ONCE_DEPTH_CONV NORM_CANON_CONV THENC
1140 LAND_CONV REAL_POLY_CONV)) ges',
1141 map (CONV_RULE(ONCE_DEPTH_CONV NORM_CANON_CONV THENC
1142 LAND_CONV REAL_POLY_CONV)) gts) in
1143 let REAL_VECTOR_INEQ_PROVER =
1145 (`norm(x) = n ==> norm(x) >= &0 /\ n >= norm(x)`,
1146 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
1147 REWRITE_TAC[real_ge; NORM_POS_LE] THEN REAL_ARITH_TAC) in
1148 let NORM_MP = MATCH_MP pth in
1149 fun translator (ges,gts) ->
1150 let ntms = itlist find_normedterms (map (lhand o concl) (ges @ gts)) [] in
1151 let lctab = vector_lincombs (map snd (filter (not o fst) ntms)) in
1152 let asl = map (fun (t,_) ->
1153 ASSUME(mk_eq(mk_icomb(mk_const("vector_norm",[]),t),
1154 genvar `:real`))) lctab in
1155 let replace_conv = GEN_REWRITE_CONV TRY_CONV asl in
1156 let replace_rule = CONV_RULE (LAND_CONV (replacenegnorms replace_conv)) in
1158 itlist (fun th ths -> CONJUNCT1(NORM_MP th)::ths)
1159 asl (map replace_rule ges)
1160 and gts' = map replace_rule gts
1161 and nubs = map (CONJUNCT2 o NORM_MP) asl in
1162 let th1 = REAL_VECTOR_COMBO_PROVER translator (nubs,ges',gts') in
1164 (map (fun th -> let l,r = dest_eq(concl th) in (l,r)) asl) th1 in
1165 itlist PROVE_HYP (map (REFL o lhand o concl) asl) th2 in
1166 let REAL_VECTOR_PROVER =
1168 GEN_REWRITE_RULE I [REAL_ARITH `x = &0 <=> x >= &0 /\ --x >= &0`] in
1169 let splitequation th acc =
1170 let th1,th2 = CONJ_PAIR(rawrule th) in
1171 th1::CONV_RULE(LAND_CONV REAL_POLY_NEG_CONV) th2::acc in
1172 fun translator (eqs,ges,gts) ->
1173 REAL_VECTOR_INEQ_PROVER translator
1174 (itlist splitequation eqs ges,gts) in
1176 (`(!x y:real^N. x = y <=> norm(x - y) <= &0) /\
1177 (!x y:real^N. ~(x = y) <=> ~(norm(x - y) <= &0))`,
1178 REWRITE_TAC[NORM_LE_0; VECTOR_SUB_EQ]) in
1179 let conv1 = GEN_REWRITE_CONV TRY_CONV [pth] in
1180 let conv2 tm = (conv1 tm,conv1(mk_neg tm)) in
1181 let init = GEN_REWRITE_CONV ONCE_DEPTH_CONV [DECIMAL] THENC
1182 REAL_RAT_REDUCE_CONV THENC
1183 GEN_REWRITE_CONV ONCE_DEPTH_CONV [dist] THENC
1184 GEN_NNF_CONV true (conv1,conv2)
1185 and pure = GEN_REAL_ARITH REAL_VECTOR_PROVER in
1186 fun tm -> let th = init tm in EQ_MP (SYM th) (pure(rand(concl th)));;
1188 let NORM_ARITH_TAC = CONV_TAC NORM_ARITH;;
1190 let ASM_NORM_ARITH_TAC =
1191 REPEAT(FIRST_X_ASSUM(MP_TAC o check (not o is_forall o concl))) THEN
1194 (* ------------------------------------------------------------------------- *)
1195 (* Dot product in terms of the norm rather than conversely. *)
1196 (* ------------------------------------------------------------------------- *)
1198 let DOT_NORM = prove
1199 (`!x y. x dot y = (norm(x + y) pow 2 - norm(x) pow 2 - norm(y) pow 2) / &2`,
1200 REWRITE_TAC[NORM_POW_2; DOT_LADD; DOT_RADD; DOT_SYM] THEN REAL_ARITH_TAC);;
1202 let DOT_NORM_NEG = prove
1203 (`!x y. x dot y = ((norm(x) pow 2 + norm(y) pow 2) - norm(x - y) pow 2) / &2`,
1204 REWRITE_TAC[NORM_POW_2; DOT_LADD; DOT_RADD; DOT_LSUB; DOT_RSUB; DOT_SYM] THEN
1207 let DOT_NORM_SUB = prove
1208 (`!x y. x dot y = ((norm(x) pow 2 + norm(y) pow 2) - norm(x - y) pow 2) / &2`,
1209 REWRITE_TAC[NORM_POW_2; DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REAL_ARITH_TAC);;
1211 (* ------------------------------------------------------------------------- *)
1212 (* Equality of vectors in terms of dot products. *)
1213 (* ------------------------------------------------------------------------- *)
1215 let VECTOR_EQ = prove
1216 (`!x y. (x = y) <=> (x dot x = x dot y) /\ (y dot y = x dot x)`,
1217 REPEAT GEN_TAC THEN EQ_TAC THENL [SIMP_TAC[]; ALL_TAC] THEN
1218 ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
1219 REWRITE_TAC[GSYM DOT_EQ_0] THEN
1220 SIMP_TAC[DOT_LSUB; DOT_RSUB; DOT_SYM] THEN REAL_ARITH_TAC);;
1222 (* ------------------------------------------------------------------------- *)
1223 (* Hence more metric properties. *)
1224 (* ------------------------------------------------------------------------- *)
1226 let DIST_REFL = prove
1227 (`!x. dist(x,x) = &0`,
1230 let DIST_SYM = prove
1231 (`!x y. dist(x,y) = dist(y,x)`,
1234 let DIST_POS_LE = prove
1235 (`!x y. &0 <= dist(x,y)`,
1238 let DIST_TRIANGLE = prove
1239 (`!x:real^N y z. dist(x,z) <= dist(x,y) + dist(y,z)`,
1242 let DIST_TRIANGLE_ALT = prove
1243 (`!x y z. dist(y,z) <= dist(x,y) + dist(x,z)`,
1246 let DIST_EQ_0 = prove
1247 (`!x y. (dist(x,y) = &0) <=> (x = y)`,
1250 let DIST_POS_LT = prove
1251 (`!x y. ~(x = y) ==> &0 < dist(x,y)`,
1255 (`!x y. ~(x = y) <=> &0 < dist(x,y)`,
1258 let DIST_TRIANGLE_LE = prove
1259 (`!x y z e. dist(x,z) + dist(y,z) <= e ==> dist(x,y) <= e`,
1262 let DIST_TRIANGLE_LT = prove
1263 (`!x y z e. dist(x,z) + dist(y,z) < e ==> dist(x,y) < e`,
1266 let DIST_TRIANGLE_HALF_L = prove
1267 (`!x1 x2 y. dist(x1,y) < e / &2 /\ dist(x2,y) < e / &2 ==> dist(x1,x2) < e`,
1270 let DIST_TRIANGLE_HALF_R = prove
1271 (`!x1 x2 y. dist(y,x1) < e / &2 /\ dist(y,x2) < e / &2 ==> dist(x1,x2) < e`,
1274 let DIST_TRIANGLE_ADD = prove
1275 (`!x x' y y'. dist(x + y,x' + y') <= dist(x,x') + dist(y,y')`,
1278 let DIST_MUL = prove
1279 (`!x y c. dist(c % x,c % y) = abs(c) * dist(x,y)`,
1280 REWRITE_TAC[dist; GSYM VECTOR_SUB_LDISTRIB; NORM_MUL]);;
1282 let DIST_TRIANGLE_ADD_HALF = prove
1283 (`!x x' y y':real^N.
1284 dist(x,x') < e / &2 /\ dist(y,y') < e / &2 ==> dist(x + y,x' + y') < e`,
1287 let DIST_LE_0 = prove
1288 (`!x y. dist(x,y) <= &0 <=> x = y`,
1292 (`!w x y z. dist(w,x) = dist(y,z) <=> dist(w,x) pow 2 = dist(y,z) pow 2`,
1293 REWRITE_TAC[dist; NORM_POW_2; NORM_EQ]);;
1296 (`!x. dist(x,vec 0) = norm(x) /\ dist(vec 0,x) = norm(x)`,
1299 (* ------------------------------------------------------------------------- *)
1300 (* Sums of vectors. *)
1301 (* ------------------------------------------------------------------------- *)
1303 let NEUTRAL_VECTOR_ADD = prove
1304 (`neutral(+) = vec 0:real^N`,
1305 REWRITE_TAC[neutral] THEN MATCH_MP_TAC SELECT_UNIQUE THEN
1306 REWRITE_TAC[VECTOR_ARITH `x + y = y <=> x = vec 0`;
1307 VECTOR_ARITH `x + y = x <=> y = vec 0`]);;
1309 let MONOIDAL_VECTOR_ADD = prove
1310 (`monoidal((+):real^N->real^N->real^N)`,
1311 REWRITE_TAC[monoidal; NEUTRAL_VECTOR_ADD] THEN
1312 REPEAT CONJ_TAC THEN VECTOR_ARITH_TAC);;
1314 let vsum = new_definition
1315 `(vsum:(A->bool)->(A->real^N)->real^N) s f = lambda i. sum s (\x. f(x)$i)`;;
1317 let VSUM_CLAUSES = prove
1318 (`(!f. vsum {} f = vec 0) /\
1320 ==> (vsum (x INSERT s) f =
1321 if x IN s then vsum s f else f(x) + vsum s f))`,
1322 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; SUM_CLAUSES] THEN
1323 SIMP_TAC[VEC_COMPONENT] THEN REPEAT STRIP_TAC THEN
1324 COND_CASES_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_COMPONENT]);;
1327 (`!f s. FINITE s ==> vsum s f = iterate (+) s f`,
1328 GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1329 ASM_SIMP_TAC[VSUM_CLAUSES; ITERATE_CLAUSES; MONOIDAL_VECTOR_ADD] THEN
1330 REWRITE_TAC[NEUTRAL_VECTOR_ADD]);;
1332 let VSUM_EQ_0 = prove
1333 (`!f s. (!x:A. x IN s ==> (f(x) = vec 0)) ==> (vsum s f = vec 0)`,
1334 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; vec; SUM_EQ_0]);;
1337 (`vsum s (\x. vec 0) = vec 0`,
1338 SIMP_TAC[VSUM_EQ_0]);;
1340 let VSUM_LMUL = prove
1341 (`!f c s. vsum s (\x. c % f(x)) = c % vsum s f`,
1342 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_MUL_COMPONENT; SUM_LMUL]);;
1344 let VSUM_RMUL = prove
1345 (`!c s v. vsum s (\x. c x % v) = (sum s c) % v`,
1346 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_MUL_COMPONENT; SUM_RMUL]);;
1348 let VSUM_ADD = prove
1349 (`!f g s. FINITE s ==> (vsum s (\x. f x + g x) = vsum s f + vsum s g)`,
1350 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; SUM_ADD]);;
1352 let VSUM_SUB = prove
1353 (`!f g s. FINITE s ==> (vsum s (\x. f x - g x) = vsum s f - vsum s g)`,
1354 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_SUB_COMPONENT; SUM_SUB]);;
1356 let VSUM_CONST = prove
1357 (`!c s. FINITE s ==> (vsum s (\n. c) = &(CARD s) % c)`,
1358 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_CONST; VECTOR_MUL_COMPONENT]);;
1360 let VSUM_COMPONENT = prove
1361 (`!s f i. 1 <= i /\ i <= dimindex(:N)
1362 ==> ((vsum s (f:A->real^N))$i = sum s (\x. f(x)$i))`,
1363 SIMP_TAC[vsum; LAMBDA_BETA]);;
1365 let VSUM_IMAGE = prove
1366 (`!f g s. FINITE s /\ (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
1367 ==> (vsum (IMAGE f s) g = vsum s (g o f))`,
1368 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN REPEAT STRIP_TAC THEN
1369 W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhs o snd) THEN
1370 ASM_REWRITE_TAC[o_DEF]);;
1372 let VSUM_UNION = prove
1373 (`!f s t. FINITE s /\ FINITE t /\ DISJOINT s t
1374 ==> (vsum (s UNION t) f = vsum s f + vsum t f)`,
1375 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_UNION; VECTOR_ADD_COMPONENT]);;
1377 let VSUM_DIFF = prove
1378 (`!f s t. FINITE s /\ t SUBSET s
1379 ==> (vsum (s DIFF t) f = vsum s f - vsum t f)`,
1380 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_DIFF; VECTOR_SUB_COMPONENT]);;
1382 let VSUM_DELETE = prove
1383 (`!f s a. FINITE s /\ a IN s
1384 ==> vsum (s DELETE a) f = vsum s f - f a`,
1385 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_DELETE; VECTOR_SUB_COMPONENT]);;
1387 let VSUM_INCL_EXCL = prove
1388 (`!s t (f:A->real^N).
1389 FINITE s /\ FINITE t
1390 ==> vsum s f + vsum t f = vsum (s UNION t) f + vsum (s INTER t) f`,
1391 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN
1392 SIMP_TAC[SUM_INCL_EXCL]);;
1394 let VSUM_NEG = prove
1395 (`!f s. vsum s (\x. --f x) = --vsum s f`,
1396 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_NEG; VECTOR_NEG_COMPONENT]);;
1399 (`!f g s. (!x. x IN s ==> (f x = g x)) ==> (vsum s f = vsum s g)`,
1400 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN
1401 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC[]);;
1403 let VSUM_SUPERSET = prove
1405 u SUBSET v /\ (!x. x IN v /\ ~(x IN u) ==> (f(x) = vec 0))
1406 ==> (vsum v f = vsum u f)`,
1407 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_SUPERSET]);;
1409 let VSUM_SUPPORT = prove
1410 (`!f:A->real^N s. vsum {x | x IN s /\ ~(f x = vec 0)} f = vsum s f`,
1411 REPEAT GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN
1414 let VSUM_EQ_SUPERSET = prove
1416 FINITE t /\ t SUBSET s /\
1417 (!x. x IN t ==> (f x = g x)) /\
1418 (!x. x IN s /\ ~(x IN t) ==> f(x) = vec 0)
1419 ==> vsum s f = vsum t g`,
1420 MESON_TAC[VSUM_SUPERSET; VSUM_EQ]);;
1422 let VSUM_UNION_RZERO = prove
1424 (!x. x IN v /\ ~(x IN u) ==> (f(x) = vec 0))
1425 ==> (vsum (u UNION v) f = vsum u f)`,
1426 REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_SUPERSET THEN ASM SET_TAC[]);;
1428 let VSUM_UNION_LZERO = prove
1430 (!x. x IN u /\ ~(x IN v) ==> (f(x) = vec 0))
1431 ==> (vsum (u UNION v) f = vsum v f)`,
1432 REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_SUPERSET THEN ASM SET_TAC[]);;
1434 let VSUM_RESTRICT = prove
1435 (`!f s. vsum s (\x. if x IN s then f(x) else vec 0) = vsum s f`,
1436 REPEAT GEN_TAC THEN MATCH_MP_TAC VSUM_EQ THEN SIMP_TAC[]);;
1438 let VSUM_RESTRICT_SET = prove
1439 (`!P s f. vsum {x | x IN s /\ P x} f =
1440 vsum s (\x. if P x then f x else vec 0)`,
1441 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_RESTRICT_SET;
1444 let VSUM_CASES = prove
1445 (`!s P f g. FINITE s
1446 ==> vsum s (\x:A. if P x then (f x):real^N else g x) =
1447 vsum {x | x IN s /\ P x} f + vsum {x | x IN s /\ ~P x} g`,
1448 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT; SUM_CASES;
1451 let VSUM_SING = prove
1452 (`!f x. vsum {x} f = f(x)`,
1453 SIMP_TAC[VSUM_CLAUSES; FINITE_RULES; NOT_IN_EMPTY; VECTOR_ADD_RID]);;
1455 let VSUM_NORM = prove
1456 (`!f s. FINITE s ==> norm(vsum s f) <= sum s (\x. norm(f x))`,
1457 GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1458 SIMP_TAC[SUM_CLAUSES; VSUM_CLAUSES; NORM_0; REAL_LE_REFL] THEN
1461 let VSUM_NORM_LE = prove
1463 FINITE s /\ (!x. x IN s ==> norm(f x) <= g(x))
1464 ==> norm(vsum s f) <= sum s g`,
1465 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
1466 EXISTS_TAC `sum s (\x:A. norm(f x :real^N))` THEN
1467 ASM_SIMP_TAC[VSUM_NORM; SUM_LE]);;
1469 let VSUM_NORM_TRIANGLE = prove
1470 (`!s f b. FINITE s /\ sum s (\a. norm(f a)) <= b ==> norm(vsum s f) <= b`,
1471 MESON_TAC[VSUM_NORM; REAL_LE_TRANS]);;
1473 let VSUM_NORM_BOUND = prove
1474 (`!s f b. FINITE s /\ (!x:A. x IN s ==> norm(f(x)) <= b)
1475 ==> norm(vsum s f) <= &(CARD s) * b`,
1476 SIMP_TAC[GSYM SUM_CONST; VSUM_NORM_LE]);;
1478 let VSUM_CLAUSES_NUMSEG = prove
1479 (`(!m. vsum(m..0) f = if m = 0 then f(0) else vec 0) /\
1480 (!m n. vsum(m..SUC n) f = if m <= SUC n then vsum(m..n) f + f(SUC n)
1481 else vsum(m..n) f)`,
1482 REWRITE_TAC[NUMSEG_CLAUSES] THEN REPEAT STRIP_TAC THEN
1484 ASM_SIMP_TAC[VSUM_SING; VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG] THEN
1485 REWRITE_TAC[ARITH_RULE `~(SUC n <= n)`; VECTOR_ADD_AC]);;
1487 let VSUM_CLAUSES_RIGHT = prove
1488 (`!f m n. 0 < n /\ m <= n ==> vsum(m..n) f = vsum(m..n-1) f + (f n):real^N`,
1489 GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN
1490 SIMP_TAC[LT_REFL; VSUM_CLAUSES_NUMSEG; SUC_SUB1]);;
1492 let VSUM_CMUL_NUMSEG = prove
1493 (`!f c m n. vsum (m..n) (\x. c % f x) = c % vsum (m..n) f`,
1494 SIMP_TAC[VSUM_LMUL; FINITE_NUMSEG]);;
1496 let VSUM_EQ_NUMSEG = prove
1498 (!x. m <= x /\ x <= n ==> (f x = g x))
1499 ==> (vsum(m .. n) f = vsum(m .. n) g)`,
1500 REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
1501 ASM_SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG]);;
1503 let VSUM_IMAGE_GEN = prove
1507 vsum (IMAGE f s) (\y. vsum {x | x IN s /\ (f(x) = y)} g))`,
1508 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_IMAGE_GEN]);;
1510 let VSUM_GROUP = prove
1512 FINITE s /\ IMAGE f s SUBSET t
1513 ==> vsum t (\y. vsum {x | x IN s /\ f(x) = y} g) = vsum s g`,
1514 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; SUM_GROUP]);;
1516 let VSUM_VMUL = prove
1517 (`!f v s. (sum s f) % v = vsum s (\x. f(x) % v)`,
1518 REWRITE_TAC[VSUM_RMUL]);;
1520 let VSUM_DELTA = prove
1521 (`!s a. vsum s (\x. if x = a then b else vec 0) =
1522 if a IN s then b else vec 0`,
1523 SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; COND_COMPONENT] THEN
1524 SIMP_TAC[VEC_COMPONENT; SUM_DELTA]);;
1526 let VSUM_ADD_NUMSEG = prove
1527 (`!f g m n. vsum(m..n) (\i. f i + g i) = vsum(m..n) f + vsum(m..n) g`,
1528 SIMP_TAC[VSUM_ADD; FINITE_NUMSEG]);;
1530 let VSUM_SUB_NUMSEG = prove
1531 (`!f g m n. vsum(m..n) (\i. f i - g i) = vsum(m..n) f - vsum(m..n) g`,
1532 SIMP_TAC[VSUM_SUB; FINITE_NUMSEG]);;
1534 let VSUM_ADD_SPLIT = prove
1536 m <= n + 1 ==> vsum(m..n + p) f = vsum(m..n) f + vsum(n + 1..n + p) f`,
1537 SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; VECTOR_ADD_COMPONENT;
1540 let VSUM_VSUM_PRODUCT = prove
1541 (`!s:A->bool t:A->B->bool x.
1542 FINITE s /\ (!i. i IN s ==> FINITE(t i))
1543 ==> vsum s (\i. vsum (t i) (x i)) =
1544 vsum {i,j | i IN s /\ j IN t i} (\(i,j). x i j)`,
1545 SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; COND_COMPONENT] THEN
1546 SIMP_TAC[SUM_SUM_PRODUCT] THEN REPEAT STRIP_TAC THEN AP_TERM_TAC THEN
1547 REWRITE_TAC[FUN_EQ_THM; FORALL_PAIR_THM]);;
1549 let VSUM_IMAGE_NONZERO = prove
1550 (`!d:B->real^N i:A->B s.
1552 (!x y. x IN s /\ y IN s /\ ~(x = y) /\ i x = i y ==> d(i x) = vec 0)
1553 ==> vsum (IMAGE i s) d = vsum s (d o i)`,
1554 GEN_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN
1555 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1556 SIMP_TAC[IMAGE_CLAUSES; VSUM_CLAUSES; FINITE_IMAGE] THEN
1557 MAP_EVERY X_GEN_TAC [`a:A`; `s:A->bool`] THEN
1558 REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN
1559 SUBGOAL_THEN `vsum s ((d:B->real^N) o (i:A->B)) = vsum (IMAGE i s) d`
1560 SUBST1_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
1561 COND_CASES_TAC THEN ASM_REWRITE_TAC[o_THM] THEN
1562 REWRITE_TAC[VECTOR_ARITH `a = x + a <=> x = vec 0`] THEN
1563 ASM_MESON_TAC[IN_IMAGE]);;
1565 let VSUM_UNION_NONZERO = prove
1566 (`!f s t. FINITE s /\ FINITE t /\ (!x. x IN s INTER t ==> f(x) = vec 0)
1567 ==> vsum (s UNION t) f = vsum s f + vsum t f`,
1568 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN
1569 SIMP_TAC[VEC_COMPONENT; SUM_UNION_NONZERO]);;
1571 let VSUM_UNIONS_NONZERO = prove
1572 (`!f s. FINITE s /\ (!t:A->bool. t IN s ==> FINITE t) /\
1573 (!t1 t2 x. t1 IN s /\ t2 IN s /\ ~(t1 = t2) /\ x IN t1 /\ x IN t2
1575 ==> vsum (UNIONS s) f = vsum s (\t. vsum t f)`,
1576 GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN
1577 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1578 REWRITE_TAC[UNIONS_0; UNIONS_INSERT; VSUM_CLAUSES; IN_INSERT] THEN
1579 MAP_EVERY X_GEN_TAC [`t:A->bool`; `s:(A->bool)->bool`] THEN
1580 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
1581 ONCE_REWRITE_TAC[IMP_CONJ] THEN ASM_SIMP_TAC[VSUM_CLAUSES] THEN
1582 ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN(SUBST_ALL_TAC o SYM)] THEN
1583 STRIP_TAC THEN MATCH_MP_TAC VSUM_UNION_NONZERO THEN
1584 ASM_SIMP_TAC[FINITE_UNIONS; IN_INTER; IN_UNIONS] THEN ASM_MESON_TAC[]);;
1586 let VSUM_CLAUSES_LEFT = prove
1587 (`!f m n. m <= n ==> vsum(m..n) f = f m + vsum(m + 1..n) f`,
1588 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN
1589 SIMP_TAC[VEC_COMPONENT; SUM_CLAUSES_LEFT]);;
1591 let VSUM_DIFFS = prove
1592 (`!m n. vsum(m..n) (\k. f(k) - f(k + 1)) =
1593 if m <= n then f(m) - f(n + 1) else vec 0`,
1594 GEN_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC[VSUM_CLAUSES_NUMSEG; LE] THEN
1595 ASM_CASES_TAC `m = SUC n` THEN
1596 ASM_REWRITE_TAC[ARITH_RULE `~(SUC n <= n)`; VECTOR_ADD_LID] THEN
1597 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
1598 REWRITE_TAC[GSYM ADD1] THEN VECTOR_ARITH_TAC);;
1600 let VSUM_DIFFS_ALT = prove
1601 (`!m n. vsum(m..n) (\k. f(k + 1) - f(k)) =
1602 if m <= n then f(n + 1) - f(m) else vec 0`,
1603 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_NEG_SUB] THEN
1604 SIMP_TAC[VSUM_NEG; VSUM_DIFFS] THEN
1605 COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_NEG_SUB; VECTOR_NEG_0]);;
1607 let VSUM_DELETE_CASES = prove
1610 ==> vsum(s DELETE x) f = if x IN s then vsum s f - f x else vsum s f`,
1611 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
1612 ASM_SIMP_TAC[SET_RULE `~(x IN s) ==> s DELETE x = s`] THEN
1613 FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV)
1614 [MATCH_MP (SET_RULE `x IN s ==> s = x INSERT (s DELETE x)`) th]) THEN
1615 ASM_SIMP_TAC[VSUM_CLAUSES; FINITE_DELETE; IN_DELETE] THEN VECTOR_ARITH_TAC);;
1617 let VSUM_EQ_GENERAL = prove
1618 (`!s:A->bool t:B->bool (f:A->real^N) g h.
1619 (!y. y IN t ==> ?!x. x IN s /\ h x = y) /\
1620 (!x. x IN s ==> h x IN t /\ g(h x) = f x)
1621 ==> vsum s f = vsum t g`,
1622 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN
1623 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_GENERAL THEN
1624 EXISTS_TAC `h:A->B` THEN ASM_MESON_TAC[]);;
1626 let VSUM_EQ_GENERAL_INVERSES = prove
1627 (`!s t (f:A->real^N) (g:B->real^N) h k.
1628 (!y. y IN t ==> k y IN s /\ h (k y) = y) /\
1629 (!x. x IN s ==> h x IN t /\ k (h x) = x /\ g (h x) = f x)
1630 ==> vsum s f = vsum t g`,
1631 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA] THEN
1632 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_GENERAL_INVERSES THEN
1633 MAP_EVERY EXISTS_TAC [`h:A->B`; `k:B->A`] THEN ASM_MESON_TAC[]);;
1635 let VSUM_NORM_ALLSUBSETS_BOUND = prove
1638 (!q. q SUBSET p ==> norm(vsum q f) <= e)
1639 ==> sum p (\x. norm(f x)) <= &2 * &(dimindex(:N)) * e`,
1640 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
1642 `sum p (\x:A. sum (1..dimindex(:N)) (\i. abs((f x:real^N)$i)))` THEN
1644 [MATCH_MP_TAC SUM_LE THEN ASM_SIMP_TAC[NORM_LE_L1]; ALL_TAC] THEN
1645 W(MP_TAC o PART_MATCH (lhand o rand) SUM_SWAP o lhand o snd) THEN
1646 ASM_REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST1_TAC THEN
1647 ONCE_REWRITE_TAC[REAL_ARITH `&2 * &n * e = &n * &2 * e`] THEN
1648 GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o RAND_CONV)
1649 [GSYM CARD_NUMSEG_1] THEN
1650 MATCH_MP_TAC SUM_BOUND THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
1651 X_GEN_TAC `k:num` THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
1652 EXISTS_TAC `sum {x:A | x IN p /\ &0 <= (f x:real^N)$k} (\x. abs((f x)$k)) +
1653 sum {x | x IN p /\ (f x)$k < &0} (\x. abs((f x)$k))` THEN
1655 [MATCH_MP_TAC(REAL_ARITH `a = b ==> b <= a`) THEN
1656 MATCH_MP_TAC SUM_UNION_EQ THEN
1657 ASM_SIMP_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_UNION; IN_ELIM_THM] THEN
1658 CONJ_TAC THEN X_GEN_TAC `x:A` THEN ASM_CASES_TAC `(x:A) IN p` THEN
1659 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
1661 MATCH_MP_TAC(REAL_ARITH `x <= e /\ y <= e ==> x + y <= &2 * e`) THEN
1662 GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_ABS_NEG] THEN
1663 CONJ_TAC THEN MATCH_MP_TAC(REAL_ARITH
1664 `!g. sum s g = sum s f /\ sum s g <= e ==> sum s f <= e`)
1666 [EXISTS_TAC `\x. ((f:A->real^N) x)$k`;
1667 EXISTS_TAC `\x. --(((f:A->real^N) x)$k)`] THEN
1669 [MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[IN_ELIM_THM] THEN REAL_ARITH_TAC;
1671 ASM_SIMP_TAC[GSYM VSUM_COMPONENT; SUM_NEG; FINITE_RESTRICT] THEN
1672 MATCH_MP_TAC(REAL_ARITH `abs(x) <= e ==> x <= e`) THEN
1673 REWRITE_TAC[REAL_ABS_NEG] THEN
1674 MATCH_MP_TAC(REAL_ARITH
1675 `abs((vsum q f)$k) <= norm(vsum q f) /\
1677 ==> abs((vsum q f)$k) <= e`) THEN
1678 ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
1679 FIRST_X_ASSUM MATCH_MP_TAC THEN SET_TAC[]);;
1681 let DOT_LSUM = prove
1682 (`!s f y. FINITE s ==> (vsum s f) dot y = sum s (\x. f(x) dot y)`,
1683 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
1684 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1685 ASM_SIMP_TAC[VSUM_CLAUSES; SUM_CLAUSES; DOT_LZERO; DOT_LADD]);;
1687 let DOT_RSUM = prove
1688 (`!s f x. FINITE s ==> x dot (vsum s f) = sum s (\y. x dot f(y))`,
1689 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
1690 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1691 ASM_SIMP_TAC[VSUM_CLAUSES; SUM_CLAUSES; DOT_RZERO; DOT_RADD]);;
1693 let VSUM_OFFSET = prove
1694 (`!p f m n. vsum(m + p..n + p) f = vsum(m..n) (\i. f (i + p))`,
1695 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_OFFSET]);;
1697 let VSUM_OFFSET_0 = prove
1698 (`!f m n. m <= n ==> vsum(m..n) f = vsum(0..n - m) (\i. f (i + m))`,
1699 SIMP_TAC[vsum; CART_EQ; LAMBDA_BETA; VEC_COMPONENT; SUM_OFFSET_0]);;
1701 let VSUM_TRIV_NUMSEG = prove
1702 (`!f m n. n < m ==> vsum(m..n) f = vec 0`,
1703 SIMP_TAC[GSYM NUMSEG_EMPTY; VSUM_CLAUSES]);;
1705 let VSUM_CONST_NUMSEG = prove
1706 (`!c m n. vsum(m..n) (\n. c) = &((n + 1) - m) % c`,
1707 SIMP_TAC[VSUM_CONST; FINITE_NUMSEG; CARD_NUMSEG]);;
1709 let VSUM_SUC = prove
1710 (`!f m n. vsum (SUC n..SUC m) f = vsum (n..m) (f o SUC)`,
1712 SUBGOAL_THEN `SUC n..SUC m = IMAGE SUC (n..m)` SUBST1_TAC THENL
1713 [REWRITE_TAC [ADD1; NUMSEG_OFFSET_IMAGE] THEN
1714 REWRITE_TAC [ONE; ADD_SUC; ADD_0; ETA_AX];
1715 SIMP_TAC [VSUM_IMAGE; FINITE_NUMSEG; SUC_INJ]]);;
1717 let VSUM_BIJECTION = prove
1718 (`!f:A->real^N p s:A->bool.
1719 (!x. x IN s ==> p(x) IN s) /\
1720 (!y. y IN s ==> ?!x. x IN s /\ p(x) = y)
1721 ==> vsum s f = vsum s (f o p)`,
1722 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
1723 MATCH_MP_TAC VSUM_EQ_GENERAL THEN EXISTS_TAC `p:A->A` THEN
1724 ASM_REWRITE_TAC[o_THM]);;
1726 let VSUM_PARTIAL_SUC = prove
1727 (`!f g:num->real^N m n.
1728 vsum (m..n) (\k. f(k) % (g(k + 1) - g(k))) =
1729 if m <= n then f(n + 1) % g(n + 1) - f(m) % g(m) -
1730 vsum (m..n) (\k. (f(k + 1) - f(k)) % g(k + 1))
1732 GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN INDUCT_TAC THEN
1733 COND_CASES_TAC THEN ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; GSYM NOT_LE] THEN
1734 ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THENL
1735 [COND_CASES_TAC THEN ASM_SIMP_TAC[ARITH] THENL
1736 [VECTOR_ARITH_TAC; ASM_ARITH_TAC];
1738 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LE]) THEN
1739 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
1740 ASM_SIMP_TAC[GSYM NOT_LT; VSUM_TRIV_NUMSEG; ARITH_RULE `n < SUC n`] THEN
1741 ASM_SIMP_TAC[GSYM ADD1; ADD_CLAUSES] THEN VECTOR_ARITH_TAC);;
1743 let VSUM_PARTIAL_PRE = prove
1744 (`!f g:num->real^N m n.
1745 vsum (m..n) (\k. f(k) % (g(k) - g(k - 1))) =
1746 if m <= n then f(n + 1) % g(n) - f(m) % g(m - 1) -
1747 vsum (m..n) (\k. (f(k + 1) - f(k)) % g(k))
1750 MP_TAC(ISPECL [`f:num->real`; `\k. (g:num->real^N)(k - 1)`;
1751 `m:num`; `n:num`] VSUM_PARTIAL_SUC) THEN
1752 REWRITE_TAC[ADD_SUB] THEN DISCH_THEN SUBST1_TAC THEN
1753 COND_CASES_TAC THEN REWRITE_TAC[]);;
1755 let VSUM_COMBINE_L = prove
1757 0 < n /\ m <= n /\ n <= p + 1
1758 ==> vsum(m..n - 1) f + vsum(n..p) f = vsum(m..p) f`,
1759 SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VSUM_COMPONENT; SUM_COMBINE_L]);;
1761 let VSUM_COMBINE_R = prove
1763 m <= n + 1 /\ n <= p
1764 ==> vsum(m..n) f + vsum(n + 1..p) f = vsum(m..p) f`,
1765 SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VSUM_COMPONENT; SUM_COMBINE_R]);;
1767 let VSUM_INJECTION = prove
1770 (!x. x IN s ==> p x IN s) /\
1771 (!x y. x IN s /\ y IN s /\ p x = p y ==> x = y)
1772 ==> vsum s (f o p) = vsum s f`,
1773 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP SUM_INJECTION) THEN
1774 SIMP_TAC[CART_EQ; VSUM_COMPONENT; o_DEF]);;
1776 let VSUM_SWAP = prove
1778 FINITE s /\ FINITE t
1779 ==> vsum s (\i. vsum t (f i)) = vsum t (\j. vsum s (\i. f i j))`,
1780 SIMP_TAC[CART_EQ; VSUM_COMPONENT] THEN REPEAT STRIP_TAC THEN
1781 W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o lhs o snd) THEN
1782 ASM_REWRITE_TAC[]);;
1784 let VSUM_SWAP_NUMSEG = prove
1786 vsum (a..b) (\i. vsum (c..d) (f i)) =
1787 vsum (c..d) (\j. vsum (a..b) (\i. f i j))`,
1788 REPEAT GEN_TAC THEN MATCH_MP_TAC VSUM_SWAP THEN REWRITE_TAC[FINITE_NUMSEG]);;
1790 let VSUM_ADD_GEN = prove
1792 FINITE {x | x IN s /\ ~(f x = vec 0)} /\
1793 FINITE {x | x IN s /\ ~(g x = vec 0)}
1794 ==> vsum s (\x. f x + g x) = vsum s f + vsum s g`,
1795 REPEAT GEN_TAC THEN DISCH_TAC THEN
1796 SIMP_TAC[CART_EQ; vsum; LAMBDA_BETA; VECTOR_ADD_COMPONENT] THEN
1797 REPEAT GEN_TAC THEN DISCH_THEN(K ALL_TAC) THEN
1798 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_ADD_GEN THEN
1799 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN
1800 CONJ_TAC THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] FINITE_SUBSET) THEN
1801 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN GEN_TAC THEN
1802 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[DE_MORGAN_THM] THEN
1803 STRIP_TAC THEN ASM_REWRITE_TAC[VEC_COMPONENT]);;
1805 let VSUM_CASES_1 = prove
1806 (`!s a. FINITE s /\ a IN s
1807 ==> vsum s (\x. if x = a then y else f(x)) = vsum s f + (y - f a)`,
1808 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[VSUM_CASES] THEN
1809 ASM_SIMP_TAC[GSYM DELETE; VSUM_DELETE] THEN
1810 ASM_SIMP_TAC[SET_RULE `a IN s ==> {x | x IN s /\ x = a} = {a}`] THEN
1811 REWRITE_TAC[VSUM_SING] THEN VECTOR_ARITH_TAC);;
1813 let VSUM_SING_NUMSEG = prove
1814 (`vsum(n..n) f = f n`,
1815 REWRITE_TAC[NUMSEG_SING; VSUM_SING]);;
1818 (`vsum(1..1) f = f(1)`,
1819 REWRITE_TAC[VSUM_SING_NUMSEG]);;
1822 (`!t. vsum(1..2) t = t(1) + t(2)`,
1823 REWRITE_TAC[num_CONV `2`; VSUM_CLAUSES_NUMSEG] THEN
1824 REWRITE_TAC[VSUM_SING_NUMSEG; ARITH; REAL_ADD_ASSOC]);;
1827 (`!t. vsum(1..3) t = t(1) + t(2) + t(3)`,
1828 REWRITE_TAC[num_CONV `3`; num_CONV `2`; VSUM_CLAUSES_NUMSEG] THEN
1829 REWRITE_TAC[VSUM_SING_NUMSEG; ARITH; VECTOR_ADD_ASSOC]);;
1832 (`!t. vsum(1..4) t = t(1) + t(2) + t(3) + t(4)`,
1833 SIMP_TAC[num_CONV `4`; num_CONV `3`; num_CONV `2`; VSUM_CLAUSES_NUMSEG] THEN
1834 REWRITE_TAC[VSUM_SING_NUMSEG; ARITH; VECTOR_ADD_ASSOC]);;
1836 let VSUM_PAIR = prove
1837 (`!f:num->real^N m n.
1838 vsum(2*m..2*n+1) f = vsum(m..n) (\i. f(2*i) + f(2*i+1))`,
1839 SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_ADD_COMPONENT; SUM_PAIR]);;
1841 let VSUM_PAIR_0 = prove
1842 (`!f:num->real^N n. vsum(0..2*n+1) f = vsum(0..n) (\i. f(2*i) + f(2*i+1))`,
1844 MP_TAC(ISPECL [`f:num->real^N`; `0`; `n:num`] VSUM_PAIR) THEN
1845 ASM_REWRITE_TAC[ARITH]);;
1847 (* ------------------------------------------------------------------------- *)
1848 (* Add useful congruences to the simplifier. *)
1849 (* ------------------------------------------------------------------------- *)
1852 (`(!f g s. (!x. x IN s ==> f(x) = g(x))
1853 ==> vsum s (\i. f(i)) = vsum s g) /\
1854 (!f g a b. (!i. a <= i /\ i <= b ==> f(i) = g(i))
1855 ==> vsum(a..b) (\i. f(i)) = vsum(a..b) g) /\
1856 (!f g p. (!x. p x ==> f x = g x)
1857 ==> vsum {y | p y} (\i. f(i)) = vsum {y | p y} g)`,
1858 REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
1859 ASM_SIMP_TAC[IN_ELIM_THM; IN_NUMSEG]) in
1860 extend_basic_congs (map SPEC_ALL (CONJUNCTS th));;
1862 (* ------------------------------------------------------------------------- *)
1863 (* A conversion for evaluation of `vsum(m..n) f` for numerals m and n. *)
1864 (* ------------------------------------------------------------------------- *)
1866 let EXPAND_VSUM_CONV =
1867 let [pth_0; pth_1; pth_2] = (CONJUNCTS o prove)
1868 (`(n < m ==> vsum(m..n) (f:num->real^N) = vec 0) /\
1869 vsum(m..m) (f:num->real^N) = f m /\
1870 (m <= n ==> vsum (m..n) (f:num->real^N) = f m + vsum (m + 1..n) f)`,
1871 REWRITE_TAC[VSUM_CLAUSES_LEFT; VSUM_SING_NUMSEG; VSUM_TRIV_NUMSEG])
1872 and ns_tm = `..` and f_tm = `f:num->real^N`
1873 and m_tm = `m:num` and n_tm = `n:num`
1876 let smn,ftm = dest_comb tm in
1877 let s,mn = dest_comb smn in
1878 if not(is_const s & fst(dest_const s) = "vsum")
1879 then failwith "EXPAND_VSUM_CONV" else
1880 let mtm,ntm = dest_binop ns_tm mn in
1881 let m = dest_numeral mtm and n = dest_numeral ntm in
1882 let nty = hd(tl(snd(dest_type(snd(dest_fun_ty(type_of ftm)))))) in
1883 let ilist = [nty,n_ty] in
1884 let ifn = inst ilist and tfn = INST_TYPE ilist in
1886 let th1 = INST [ftm,ifn f_tm; mtm,m_tm; ntm,n_tm] (tfn pth_0) in
1887 MP th1 (EQT_ELIM(NUM_LT_CONV(lhand(concl th1))))
1888 else if n = m then CONV_RULE (RAND_CONV(TRY_CONV BETA_CONV))
1889 (INST [ftm,ifn f_tm; mtm,m_tm] (tfn pth_1))
1891 let th1 = INST [ftm,ifn f_tm; mtm,m_tm; ntm,n_tm] (tfn pth_2) in
1892 let th2 = MP th1 (EQT_ELIM(NUM_LE_CONV(lhand(concl th1)))) in
1893 CONV_RULE (RAND_CONV(COMB2_CONV (RAND_CONV(TRY_CONV BETA_CONV))
1894 (LAND_CONV(LAND_CONV NUM_ADD_CONV) THENC conv))) th2 in
1897 (* ------------------------------------------------------------------------- *)
1898 (* Basis vectors in coordinate directions. *)
1899 (* ------------------------------------------------------------------------- *)
1901 let basis = new_definition
1902 `basis k = lambda i. if i = k then &1 else &0`;;
1904 let NORM_BASIS = prove
1905 (`!k. 1 <= k /\ k <= dimindex(:N)
1906 ==> (norm(basis k :real^N) = &1)`,
1907 REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[basis; dot; vector_norm] THEN
1908 GEN_REWRITE_TAC RAND_CONV [GSYM SQRT_1] THEN AP_TERM_TAC THEN
1909 MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
1910 `sum (1..dimindex(:N)) (\i. if i = k then &1 else &0)` THEN
1912 [MATCH_MP_TAC SUM_EQ_NUMSEG THEN
1913 ASM_SIMP_TAC[LAMBDA_BETA; IN_NUMSEG; EQ_SYM_EQ] THEN
1914 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN REAL_ARITH_TAC;
1915 ASM_REWRITE_TAC[SUM_DELTA; IN_NUMSEG]]);;
1917 let NORM_BASIS_1 = prove
1918 (`norm(basis 1) = &1`,
1919 SIMP_TAC[NORM_BASIS; ARITH_EQ; ARITH_RULE `1 <= k <=> ~(k = 0)`;
1920 DIMINDEX_NONZERO]);;
1922 let VECTOR_CHOOSE_SIZE = prove
1923 (`!c. &0 <= c ==> ?x:real^N. norm(x) = c`,
1924 REPEAT STRIP_TAC THEN EXISTS_TAC `c % basis 1 :real^N` THEN
1925 ASM_REWRITE_TAC[NORM_MUL; real_abs; NORM_BASIS_1; REAL_MUL_RID]);;
1927 let VECTOR_CHOOSE_DIST = prove
1928 (`!x e. &0 <= e ==> ?y:real^N. dist(x,y) = e`,
1929 REPEAT STRIP_TAC THEN
1930 SUBGOAL_THEN `?c:real^N. norm(c) = e` CHOOSE_TAC THENL
1931 [ASM_SIMP_TAC[VECTOR_CHOOSE_SIZE]; ALL_TAC] THEN
1932 EXISTS_TAC `x - c:real^N` THEN REWRITE_TAC[dist] THEN
1933 ASM_REWRITE_TAC[VECTOR_ARITH `x - (x - c) = c:real^N`]);;
1935 let BASIS_INJ = prove
1936 (`!i j. 1 <= i /\ i <= dimindex(:N) /\
1937 1 <= j /\ j <= dimindex(:N) /\
1938 (basis i :real^N = basis j)
1940 SIMP_TAC[basis; CART_EQ; LAMBDA_BETA] THEN REPEAT GEN_TAC THEN
1941 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
1942 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
1943 ASM_SIMP_TAC[REAL_OF_NUM_EQ; ARITH_EQ]);;
1945 let BASIS_INJ_EQ = prove
1946 (`!i j. 1 <= i /\ i <= dimindex(:N) /\ 1 <= j /\ j <= dimindex(:N)
1947 ==> (basis i:real^N = basis j <=> i = j)`,
1948 MESON_TAC[BASIS_INJ]);;
1950 let BASIS_NE = prove
1951 (`!i j. 1 <= i /\ i <= dimindex(:N) /\
1952 1 <= j /\ j <= dimindex(:N) /\
1954 ==> ~(basis i :real^N = basis j)`,
1955 MESON_TAC[BASIS_INJ]);;
1957 let BASIS_COMPONENT = prove
1958 (`!k i. 1 <= i /\ i <= dimindex(:N)
1959 ==> ((basis k :real^N)$i = if i = k then &1 else &0)`,
1960 SIMP_TAC[basis; LAMBDA_BETA] THEN MESON_TAC[]);;
1962 let BASIS_EXPANSION = prove
1963 (`!x:real^N. vsum(1..dimindex(:N)) (\i. x$i % basis i) = x`,
1964 SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN
1965 ONCE_REWRITE_TAC[COND_RAND] THEN REWRITE_TAC[REAL_MUL_RZERO] THEN
1966 REPEAT STRIP_TAC THEN
1967 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
1968 ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; REAL_MUL_RID]);;
1970 let BASIS_EXPANSION_UNIQUE = prove
1971 (`!f x:real^N. (vsum(1..dimindex(:N)) (\i. f(i) % basis i) = x) <=>
1972 (!i. 1 <= i /\ i <= dimindex(:N) ==> f(i) = x$i)`,
1973 SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN
1974 REPEAT GEN_TAC THEN REWRITE_TAC[COND_RAND; REAL_MUL_RZERO; REAL_MUL_RID] THEN
1975 GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o RAND_CONV o LAND_CONV o
1976 ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
1977 SIMP_TAC[SUM_DELTA; IN_NUMSEG]);;
1979 let DOT_BASIS = prove
1981 1 <= i /\ i <= dimindex(:N)
1982 ==> ((basis i) dot x = x$i) /\ (x dot (basis i) = x$i)`,
1983 SIMP_TAC[dot; basis; LAMBDA_BETA] THEN
1984 REWRITE_TAC[COND_RATOR; COND_RAND] THEN
1985 REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO] THEN
1986 SIMP_TAC[SUM_DELTA; IN_NUMSEG; REAL_MUL_LID; REAL_MUL_RID]);;
1988 let DOT_BASIS_BASIS = prove
1989 (`!i j. 1 <= i /\ i <= dimindex(:N) /\
1990 1 <= j /\ j <= dimindex(:N)
1991 ==> (basis i:real^N) dot (basis j) = if i = j then &1 else &0`,
1992 SIMP_TAC[DOT_BASIS; BASIS_COMPONENT]);;
1994 let DOT_BASIS_BASIS_UNEQUAL = prove
1995 (`!i j. ~(i = j) ==> (basis i) dot (basis j) = &0`,
1996 SIMP_TAC[basis; dot; LAMBDA_BETA] THEN ONCE_REWRITE_TAC[COND_RAND] THEN
1997 SIMP_TAC[SUM_0; REAL_MUL_RZERO; REAL_MUL_LZERO; COND_ID]);;
1999 let BASIS_EQ_0 = prove
2000 (`!i. (basis i :real^N = vec 0) <=> ~(i IN 1..dimindex(:N))`,
2001 SIMP_TAC[CART_EQ; BASIS_COMPONENT; VEC_COMPONENT; IN_NUMSEG] THEN
2002 MESON_TAC[REAL_ARITH `~(&1 = &0)`]);;
2004 let BASIS_NONZERO = prove
2005 (`!k. 1 <= k /\ k <= dimindex(:N)
2006 ==> ~(basis k :real^N = vec 0)`,
2007 REWRITE_TAC[BASIS_EQ_0; IN_NUMSEG]);;
2009 let VECTOR_EQ_LDOT = prove
2010 (`!y z. (!x. x dot y = x dot z) <=> y = z`,
2011 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN
2012 REWRITE_TAC[CART_EQ] THEN MESON_TAC[DOT_BASIS]);;
2014 let VECTOR_EQ_RDOT = prove
2015 (`!x y. (!z. x dot z = y dot z) <=> x = y`,
2016 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN
2017 REWRITE_TAC[CART_EQ] THEN MESON_TAC[DOT_BASIS]);;
2019 (* ------------------------------------------------------------------------- *)
2020 (* Orthogonality. *)
2021 (* ------------------------------------------------------------------------- *)
2023 let orthogonal = new_definition
2024 `orthogonal x y <=> (x dot y = &0)`;;
2026 let ORTHOGONAL_0 = prove
2027 (`!x. orthogonal (vec 0) x /\ orthogonal x (vec 0)`,
2028 REWRITE_TAC[orthogonal; DOT_LZERO; DOT_RZERO]);;
2030 let ORTHOGONAL_REFL = prove
2031 (`!x. orthogonal x x <=> x = vec 0`,
2032 REWRITE_TAC[orthogonal; DOT_EQ_0]);;
2034 let ORTHOGONAL_SYM = prove
2035 (`!x y. orthogonal x y <=> orthogonal y x`,
2036 REWRITE_TAC[orthogonal; DOT_SYM]);;
2038 let ORTHOGONAL_LNEG = prove
2039 (`!x y. orthogonal (--x) y <=> orthogonal x y`,
2040 REWRITE_TAC[orthogonal; DOT_LNEG; REAL_NEG_EQ_0]);;
2042 let ORTHOGONAL_RNEG = prove
2043 (`!x y. orthogonal x (--y) <=> orthogonal x y`,
2044 REWRITE_TAC[orthogonal; DOT_RNEG; REAL_NEG_EQ_0]);;
2046 let ORTHOGONAL_MUL = prove
2047 (`(!a x y:real^N. orthogonal (a % x) y <=> a = &0 \/ orthogonal x y) /\
2048 (!a x y:real^N. orthogonal x (a % y) <=> a = &0 \/ orthogonal x y)`,
2049 REWRITE_TAC[orthogonal; DOT_LMUL; DOT_RMUL; REAL_ENTIRE]);;
2051 let ORTHOGONAL_BASIS = prove
2052 (`!x:real^N i. 1 <= i /\ i <= dimindex(:N)
2053 ==> (orthogonal (basis i) x <=> (x$i = &0))`,
2054 REPEAT STRIP_TAC THEN SIMP_TAC[orthogonal; dot; basis; LAMBDA_BETA] THEN
2055 REWRITE_TAC[COND_RAND; COND_RATOR; REAL_MUL_LZERO] THEN
2056 ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; REAL_MUL_LID]);;
2058 let ORTHOGONAL_BASIS_BASIS = prove
2059 (`!i j. 1 <= i /\ i <= dimindex(:N) /\
2060 1 <= j /\ j <= dimindex(:N)
2061 ==> (orthogonal (basis i :real^N) (basis j) <=> ~(i = j))`,
2062 ASM_SIMP_TAC[ORTHOGONAL_BASIS] THEN ASM_SIMP_TAC[BASIS_COMPONENT] THEN
2063 MESON_TAC[REAL_ARITH `~(&1 = &0)`]);;
2065 let ORTHOGONAL_CLAUSES = prove
2066 (`(!a. orthogonal a (vec 0)) /\
2067 (!a x c. orthogonal a x ==> orthogonal a (c % x)) /\
2068 (!a x. orthogonal a x ==> orthogonal a (--x)) /\
2069 (!a x y. orthogonal a x /\ orthogonal a y ==> orthogonal a (x + y)) /\
2070 (!a x y. orthogonal a x /\ orthogonal a y ==> orthogonal a (x - y)) /\
2071 (!a. orthogonal (vec 0) a) /\
2072 (!a x c. orthogonal x a ==> orthogonal (c % x) a) /\
2073 (!a x. orthogonal x a ==> orthogonal (--x) a) /\
2074 (!a x y. orthogonal x a /\ orthogonal y a ==> orthogonal (x + y) a) /\
2075 (!a x y. orthogonal x a /\ orthogonal y a ==> orthogonal (x - y) a)`,
2076 REWRITE_TAC[orthogonal; DOT_RNEG; DOT_RMUL; DOT_RADD; DOT_RSUB;
2077 DOT_LZERO; DOT_RZERO; DOT_LNEG; DOT_LMUL; DOT_LADD; DOT_LSUB] THEN
2078 SIMP_TAC[] THEN REAL_ARITH_TAC);;
2080 let ORTHOGONAL_RVSUM = prove
2083 (!y. y IN s ==> orthogonal x (f y))
2084 ==> orthogonal x (vsum s f)`,
2085 GEN_TAC THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN
2086 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2087 SIMP_TAC[NOT_IN_EMPTY; FORALL_IN_INSERT; ORTHOGONAL_CLAUSES; VSUM_CLAUSES]);;
2089 let ORTHOGONAL_LVSUM = prove
2092 (!x. x IN s ==> orthogonal (f x) y)
2093 ==> orthogonal (vsum s f) y`,
2094 GEN_TAC THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN
2095 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2096 SIMP_TAC[NOT_IN_EMPTY; FORALL_IN_INSERT; ORTHOGONAL_CLAUSES; VSUM_CLAUSES]);;
2098 let NORM_ADD_PYTHAGOREAN = prove
2101 ==> norm(a + b) pow 2 = norm(a) pow 2 + norm(b) pow 2`,
2102 SIMP_TAC[NORM_POW_2; orthogonal; DOT_LADD; DOT_RADD; DOT_SYM] THEN
2105 let NORM_VSUM_PYTHAGOREAN = prove
2107 FINITE k /\ pairwise (\i j. orthogonal (u i) (u j)) k
2108 ==> norm(vsum k u) pow 2 = sum k (\i. norm(u i) pow 2)`,
2109 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN SIMP_TAC[IMP_CONJ] THEN
2110 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2111 SIMP_TAC[VSUM_CLAUSES; SUM_CLAUSES; NORM_0] THEN
2112 CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[PAIRWISE_INSERT] THEN
2113 REWRITE_TAC[pairwise] THEN REPEAT GEN_TAC THEN
2114 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
2115 DISCH_THEN(STRIP_ASSUME_TAC o GSYM) THEN ASM_REWRITE_TAC[] THEN
2116 MATCH_MP_TAC NORM_ADD_PYTHAGOREAN THEN MATCH_MP_TAC ORTHOGONAL_RVSUM THEN
2119 (* ------------------------------------------------------------------------- *)
2120 (* Explicit vector construction from lists. *)
2121 (* ------------------------------------------------------------------------- *)
2123 let VECTOR_1 = prove
2124 (`(vector[x]:A^1)$1 = x`,
2125 SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_1; ARITH; LENGTH; EL; HD; TL]);;
2127 let VECTOR_2 = prove
2128 (`(vector[x;y]:A^2)$1 = x /\
2129 (vector[x;y]:A^2)$2 = y`,
2130 SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_2; ARITH; LENGTH; EL] THEN
2131 REWRITE_TAC[num_CONV `1`; HD; TL; EL]);;
2133 let VECTOR_3 = prove
2134 (`(vector[x;y;z]:A^3)$1 = x /\
2135 (vector[x;y;z]:A^3)$2 = y /\
2136 (vector[x;y;z]:A^3)$3 = z`,
2137 SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_3; ARITH; LENGTH; EL] THEN
2138 REWRITE_TAC[num_CONV `2`; num_CONV `1`; HD; TL; EL]);;
2140 let VECTOR_4 = prove
2141 (`(vector[w;x;y;z]:A^4)$1 = w /\
2142 (vector[w;x;y;z]:A^4)$2 = x /\
2143 (vector[w;x;y;z]:A^4)$3 = y /\
2144 (vector[w;x;y;z]:A^4)$4 = z`,
2145 SIMP_TAC[vector; LAMBDA_BETA; DIMINDEX_4; ARITH; LENGTH; EL] THEN
2146 REWRITE_TAC[num_CONV `3`; num_CONV `2`; num_CONV `1`; HD; TL; EL]);;
2148 let FORALL_VECTOR_1 = prove
2149 (`(!v:A^1. P v) <=> !x. P(vector[x])`,
2150 EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN
2151 FIRST_X_ASSUM(MP_TAC o SPEC `(v:A^1)$1`) THEN
2152 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
2153 REWRITE_TAC[CART_EQ; FORALL_1; VECTOR_1; DIMINDEX_1]);;
2155 let FORALL_VECTOR_2 = prove
2156 (`(!v:A^2. P v) <=> !x y. P(vector[x;y])`,
2157 EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN
2158 FIRST_X_ASSUM(MP_TAC o SPECL [`(v:A^2)$1`; `(v:A^2)$2`]) THEN
2159 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
2160 REWRITE_TAC[CART_EQ; FORALL_2; VECTOR_2; DIMINDEX_2]);;
2162 let FORALL_VECTOR_3 = prove
2163 (`(!v:A^3. P v) <=> !x y z. P(vector[x;y;z])`,
2164 EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN
2165 FIRST_X_ASSUM(MP_TAC o SPECL
2166 [`(v:A^3)$1`; `(v:A^3)$2`; `(v:A^3)$3`]) THEN
2167 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
2168 REWRITE_TAC[CART_EQ; FORALL_3; VECTOR_3; DIMINDEX_3]);;
2170 let FORALL_VECTOR_4 = prove
2171 (`(!v:A^4. P v) <=> !w x y z. P(vector[w;x;y;z])`,
2172 EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN
2173 FIRST_X_ASSUM(MP_TAC o SPECL
2174 [`(v:A^4)$1`; `(v:A^4)$2`; `(v:A^4)$3`; `(v:A^4)$4`]) THEN
2175 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
2176 REWRITE_TAC[CART_EQ; FORALL_4; VECTOR_4; DIMINDEX_4]);;
2178 let EXISTS_VECTOR_1 = prove
2179 (`(?v:A^1. P v) <=> ?x. P(vector[x])`,
2180 REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
2181 REWRITE_TAC[FORALL_VECTOR_1]);;
2183 let EXISTS_VECTOR_2 = prove
2184 (`(?v:A^2. P v) <=> ?x y. P(vector[x;y])`,
2185 REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
2186 REWRITE_TAC[FORALL_VECTOR_2]);;
2188 let EXISTS_VECTOR_3 = prove
2189 (`(?v:A^3. P v) <=> ?x y z. P(vector[x;y;z])`,
2190 REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
2191 REWRITE_TAC[FORALL_VECTOR_3]);;
2193 let EXISTS_VECTOR_4 = prove
2194 (`(?v:A^4. P v) <=> ?w x y z. P(vector[w;x;y;z])`,
2195 REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
2196 REWRITE_TAC[FORALL_VECTOR_4]);;
2198 let VECTOR_EXPAND_1 = prove
2199 (`!x:real^1. x = vector[x$1]`,
2200 SIMP_TAC[CART_EQ; DIMINDEX_1; FORALL_1; VECTOR_1]);;
2202 let VECTOR_EXPAND_2 = prove
2203 (`!x:real^2. x = vector[x$1;x$2]`,
2204 SIMP_TAC[CART_EQ; DIMINDEX_2; FORALL_2; VECTOR_2]);;
2206 let VECTOR_EXPAND_3 = prove
2207 (`!x:real^3. x = vector[x$1;x$2;x$3]`,
2208 SIMP_TAC[CART_EQ; DIMINDEX_3; FORALL_3; VECTOR_3]);;
2210 let VECTOR_EXPAND_4 = prove
2211 (`!x:real^4. x = vector[x$1;x$2;x$3;x$4]`,
2212 SIMP_TAC[CART_EQ; DIMINDEX_4; FORALL_4; VECTOR_4]);;
2214 (* ------------------------------------------------------------------------- *)
2215 (* Linear functions. *)
2216 (* ------------------------------------------------------------------------- *)
2218 let linear = new_definition
2219 `linear (f:real^M->real^N) <=>
2220 (!x y. f(x + y) = f(x) + f(y)) /\
2221 (!c x. f(c % x) = c % f(x))`;;
2223 let LINEAR_COMPOSE_CMUL = prove
2224 (`!f c. linear f ==> linear (\x. c % f(x))`,
2225 SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
2227 let LINEAR_COMPOSE_NEG = prove
2228 (`!f. linear f ==> linear (\x. --(f(x)))`,
2229 SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
2231 let LINEAR_COMPOSE_ADD = prove
2232 (`!f g. linear f /\ linear g ==> linear (\x. f(x) + g(x))`,
2233 SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
2235 let LINEAR_COMPOSE_SUB = prove
2236 (`!f g. linear f /\ linear g ==> linear (\x. f(x) - g(x))`,
2237 SIMP_TAC[linear] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
2239 let LINEAR_COMPOSE = prove
2240 (`!f g. linear f /\ linear g ==> linear (g o f)`,
2241 SIMP_TAC[linear; o_THM]);;
2243 let LINEAR_ID = prove
2245 REWRITE_TAC[linear]);;
2247 let LINEAR_I = prove
2249 REWRITE_TAC[I_DEF; LINEAR_ID]);;
2251 let LINEAR_ZERO = prove
2252 (`linear (\x. vec 0)`,
2253 REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
2255 let LINEAR_NEGATION = prove
2257 REWRITE_TAC[linear] THEN VECTOR_ARITH_TAC);;
2259 let LINEAR_COMPOSE_VSUM = prove
2260 (`!f s. FINITE s /\ (!a. a IN s ==> linear(f a))
2261 ==> linear(\x. vsum s (\a. f a x))`,
2262 GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
2263 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2264 SIMP_TAC[VSUM_CLAUSES; LINEAR_ZERO] THEN
2265 ASM_SIMP_TAC[ETA_AX; IN_INSERT; LINEAR_COMPOSE_ADD]);;
2267 let LINEAR_VMUL_COMPONENT = prove
2268 (`!f:real^M->real^N v k.
2269 linear f /\ 1 <= k /\ k <= dimindex(:N)
2270 ==> linear (\x. f(x)$k % v)`,
2271 SIMP_TAC[linear; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
2272 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
2274 let LINEAR_0 = prove
2275 (`!f. linear f ==> (f(vec 0) = vec 0)`,
2276 MESON_TAC[VECTOR_MUL_LZERO; linear]);;
2278 let LINEAR_CMUL = prove
2279 (`!f c x. linear f ==> (f(c % x) = c % f(x))`,
2282 let LINEAR_NEG = prove
2283 (`!f x. linear f ==> (f(--x) = --(f x))`,
2284 ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN SIMP_TAC[LINEAR_CMUL]);;
2286 let LINEAR_ADD = prove
2287 (`!f x y. linear f ==> (f(x + y) = f(x) + f(y))`,
2290 let LINEAR_SUB = prove
2291 (`!f x y. linear f ==> (f(x - y) = f(x) - f(y))`,
2292 SIMP_TAC[VECTOR_SUB; LINEAR_ADD; LINEAR_NEG]);;
2294 let LINEAR_VSUM = prove
2295 (`!f g s. linear f /\ FINITE s ==> (f(vsum s g) = vsum s (f o g))`,
2296 GEN_TAC THEN GEN_TAC THEN SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
2297 DISCH_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2298 SIMP_TAC[VSUM_CLAUSES] THEN FIRST_ASSUM(fun th ->
2299 SIMP_TAC[MATCH_MP LINEAR_0 th; MATCH_MP LINEAR_ADD th; o_THM]));;
2301 let LINEAR_VSUM_MUL = prove
2303 linear f /\ FINITE s
2304 ==> f(vsum s (\i. c i % v i)) = vsum s (\i. c(i) % f(v i))`,
2305 SIMP_TAC[LINEAR_VSUM; o_DEF; LINEAR_CMUL]);;
2307 let LINEAR_INJECTIVE_0 = prove
2309 ==> ((!x y. (f(x) = f(y)) ==> (x = y)) <=>
2310 (!x. (f(x) = vec 0) ==> (x = vec 0)))`,
2311 REPEAT STRIP_TAC THEN
2312 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM VECTOR_SUB_EQ] THEN
2313 ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN MESON_TAC[VECTOR_SUB_RZERO]);;
2315 let LINEAR_BOUNDED = prove
2316 (`!f:real^M->real^N. linear f ==> ?B. !x. norm(f x) <= B * norm(x)`,
2317 REPEAT STRIP_TAC THEN EXISTS_TAC
2318 `sum(1..dimindex(:M)) (\i. norm((f:real^M->real^N)(basis i)))` THEN
2320 GEN_REWRITE_TAC (LAND_CONV o funpow 2 RAND_CONV) [GSYM BASIS_EXPANSION] THEN
2321 ASM_SIMP_TAC[LINEAR_VSUM; FINITE_NUMSEG] THEN
2322 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
2323 MATCH_MP_TAC VSUM_NORM_LE THEN
2324 SIMP_TAC[FINITE_CROSS; FINITE_NUMSEG; IN_NUMSEG] THEN
2325 ASM_SIMP_TAC[o_DEF; NORM_MUL; LINEAR_CMUL] THEN
2326 ASM_SIMP_TAC[REAL_LE_RMUL; NORM_POS_LE; COMPONENT_LE_NORM]);;
2328 let LINEAR_BOUNDED_POS = prove
2329 (`!f:real^M->real^N. linear f ==> ?B. &0 < B /\ !x. norm(f x) <= B * norm(x)`,
2330 REPEAT STRIP_TAC THEN
2331 FIRST_ASSUM(X_CHOOSE_TAC `B:real` o MATCH_MP LINEAR_BOUNDED) THEN
2332 EXISTS_TAC `abs(B) + &1` THEN CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
2333 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
2334 MATCH_MP_TAC(REAL_ARITH `a <= b ==> x <= a ==> x <= b`) THEN
2335 MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN
2338 let SYMMETRIC_LINEAR_IMAGE = prove
2339 (`!f s. (!x. x IN s ==> --x IN s) /\ linear f
2340 ==> !x. x IN (IMAGE f s) ==> --x IN (IMAGE f s)`,
2341 REWRITE_TAC[FORALL_IN_IMAGE] THEN
2342 SIMP_TAC[GSYM LINEAR_NEG] THEN SET_TAC[]);;
2344 (* ------------------------------------------------------------------------- *)
2345 (* Bilinear functions. *)
2346 (* ------------------------------------------------------------------------- *)
2348 let bilinear = new_definition
2349 `bilinear f <=> (!x. linear(\y. f x y)) /\ (!y. linear(\x. f x y))`;;
2351 let BILINEAR_LADD = prove
2352 (`!h x y z. bilinear h ==> h (x + y) z = (h x z) + (h y z)`,
2353 SIMP_TAC[bilinear; linear]);;
2355 let BILINEAR_RADD = prove
2356 (`!h x y z. bilinear h ==> h x (y + z) = (h x y) + (h x z)`,
2357 SIMP_TAC[bilinear; linear]);;
2359 let BILINEAR_LMUL = prove
2360 (`!h c x y. bilinear h ==> h (c % x) y = c % (h x y)`,
2361 SIMP_TAC[bilinear; linear]);;
2363 let BILINEAR_RMUL = prove
2364 (`!h c x y. bilinear h ==> h x (c % y) = c % (h x y)`,
2365 SIMP_TAC[bilinear; linear]);;
2367 let BILINEAR_LNEG = prove
2368 (`!h x y. bilinear h ==> h (--x) y = --(h x y)`,
2369 ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN SIMP_TAC[BILINEAR_LMUL]);;
2371 let BILINEAR_RNEG = prove
2372 (`!h x y. bilinear h ==> h x (--y) = --(h x y)`,
2373 ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN SIMP_TAC[BILINEAR_RMUL]);;
2375 let BILINEAR_LZERO = prove
2376 (`!h x. bilinear h ==> h (vec 0) x = vec 0`,
2377 ONCE_REWRITE_TAC[VECTOR_ARITH `x = vec 0 <=> x + x = x`] THEN
2378 SIMP_TAC[GSYM BILINEAR_LADD; VECTOR_ADD_LID]);;
2380 let BILINEAR_RZERO = prove
2381 (`!h x. bilinear h ==> h x (vec 0) = vec 0`,
2382 ONCE_REWRITE_TAC[VECTOR_ARITH `x = vec 0 <=> x + x = x`] THEN
2383 SIMP_TAC[GSYM BILINEAR_RADD; VECTOR_ADD_LID]);;
2385 let BILINEAR_LSUB = prove
2386 (`!h x y z. bilinear h ==> h (x - y) z = (h x z) - (h y z)`,
2387 SIMP_TAC[VECTOR_SUB; BILINEAR_LNEG; BILINEAR_LADD]);;
2389 let BILINEAR_RSUB = prove
2390 (`!h x y z. bilinear h ==> h x (y - z) = (h x y) - (h x z)`,
2391 SIMP_TAC[VECTOR_SUB; BILINEAR_RNEG; BILINEAR_RADD]);;
2393 let BILINEAR_VSUM = prove
2394 (`!h:real^M->real^N->real^P.
2395 bilinear h /\ FINITE s /\ FINITE t
2396 ==> h (vsum s f) (vsum t g) = vsum (s CROSS t) (\(i,j). h (f i) (g j))`,
2397 REPEAT GEN_TAC THEN SIMP_TAC[bilinear; ETA_AX] THEN
2398 ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> (a /\ d) /\ (b /\ c)`] THEN
2399 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
2400 ONCE_REWRITE_TAC[LEFT_AND_FORALL_THM] THEN DISCH_TAC THEN
2401 FIRST_ASSUM(MP_TAC o GEN_ALL o MATCH_MP LINEAR_VSUM o SPEC_ALL) THEN
2402 SIMP_TAC[] THEN ASM_SIMP_TAC[LINEAR_VSUM; o_DEF; VSUM_VSUM_PRODUCT] THEN
2403 REWRITE_TAC[GSYM CROSS]);;
2405 let BILINEAR_BOUNDED = prove
2406 (`!h:real^M->real^N->real^P.
2407 bilinear h ==> ?B. !x y. norm(h x y) <= B * norm(x) * norm(y)`,
2408 REPEAT STRIP_TAC THEN
2409 EXISTS_TAC `sum ((1..dimindex(:M)) CROSS (1..dimindex(:N)))
2410 (\(i,j). norm((h:real^M->real^N->real^P)
2411 (basis i) (basis j)))` THEN
2412 REPEAT GEN_TAC THEN GEN_REWRITE_TAC
2413 (LAND_CONV o RAND_CONV o BINOP_CONV) [GSYM BASIS_EXPANSION] THEN
2414 ASM_SIMP_TAC[BILINEAR_VSUM; FINITE_NUMSEG] THEN
2415 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
2416 MATCH_MP_TAC VSUM_NORM_LE THEN
2417 SIMP_TAC[FINITE_CROSS; FINITE_NUMSEG; FORALL_PAIR_THM; IN_CROSS] THEN
2418 REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN
2419 ASM_SIMP_TAC[BILINEAR_LMUL; NORM_MUL] THEN
2420 ASM_SIMP_TAC[BILINEAR_RMUL; NORM_MUL; REAL_MUL_ASSOC] THEN
2421 MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN
2422 ASM_SIMP_TAC[COMPONENT_LE_NORM; REAL_ABS_POS; REAL_LE_MUL2]);;
2424 let BILINEAR_BOUNDED_POS = prove
2426 ==> ?B. &0 < B /\ !x y. norm(h x y) <= B * norm(x) * norm(y)`,
2427 REPEAT STRIP_TAC THEN
2428 FIRST_ASSUM(X_CHOOSE_TAC `B:real` o MATCH_MP BILINEAR_BOUNDED) THEN
2429 EXISTS_TAC `abs(B) + &1` THEN CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
2430 POP_ASSUM MP_TAC THEN REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2431 MATCH_MP_TAC(REAL_ARITH `a <= b ==> x <= a ==> x <= b`) THEN
2432 REPEAT(MATCH_MP_TAC REAL_LE_RMUL THEN
2433 SIMP_TAC[NORM_POS_LE; REAL_LE_MUL]) THEN
2436 let BILINEAR_VSUM_PARTIAL_SUC = prove
2437 (`!f g h:real^M->real^N->real^P m n.
2439 ==> vsum (m..n) (\k. h (f k) (g(k + 1) - g(k))) =
2440 if m <= n then h (f(n + 1)) (g(n + 1)) - h (f m) (g m) -
2441 vsum (m..n) (\k. h (f(k + 1) - f(k)) (g(k + 1)))
2443 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
2444 GEN_TAC THEN INDUCT_TAC THEN
2445 COND_CASES_TAC THEN ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; GSYM NOT_LE] THEN
2446 ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG] THENL
2447 [COND_CASES_TAC THEN ASM_SIMP_TAC[ARITH] THENL
2448 [ASM_SIMP_TAC[BILINEAR_RSUB; BILINEAR_LSUB] THEN VECTOR_ARITH_TAC;
2451 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LE]) THEN
2452 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
2453 ASM_SIMP_TAC[GSYM NOT_LT; VSUM_TRIV_NUMSEG; ARITH_RULE `n < SUC n`] THEN
2454 ASM_SIMP_TAC[GSYM ADD1; ADD_CLAUSES] THEN
2455 ASM_SIMP_TAC[BILINEAR_RSUB; BILINEAR_LSUB] THEN VECTOR_ARITH_TAC);;
2457 let BILINEAR_VSUM_PARTIAL_PRE = prove
2458 (`!f g h:real^M->real^N->real^P m n.
2460 ==> vsum (m..n) (\k. h (f k) (g(k) - g(k - 1))) =
2461 if m <= n then h (f(n + 1)) (g(n)) - h (f m) (g(m - 1)) -
2462 vsum (m..n) (\k. h (f(k + 1) - f(k)) (g(k)))
2464 REPEAT STRIP_TAC THEN
2465 FIRST_ASSUM(MP_TAC o ISPECL [`f:num->real^M`; `\k. (g:num->real^N)(k - 1)`;
2466 `m:num`; `n:num`] o MATCH_MP BILINEAR_VSUM_PARTIAL_SUC) THEN
2467 REWRITE_TAC[ADD_SUB] THEN DISCH_THEN SUBST1_TAC THEN
2468 COND_CASES_TAC THEN REWRITE_TAC[]);;
2470 (* ------------------------------------------------------------------------- *)
2472 (* ------------------------------------------------------------------------- *)
2474 let adjoint = new_definition
2475 `adjoint(f:real^M->real^N) = @f'. !x y. f(x) dot y = x dot f'(y)`;;
2477 let ADJOINT_WORKS = prove
2478 (`!f:real^M->real^N. linear f ==> !x y. f(x) dot y = x dot (adjoint f)(y)`,
2479 GEN_TAC THEN DISCH_TAC THEN SIMP_TAC[adjoint] THEN CONV_TAC SELECT_CONV THEN
2480 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN ONCE_REWRITE_TAC[GSYM SKOLEM_THM] THEN
2481 X_GEN_TAC `y:real^N` THEN
2482 EXISTS_TAC `(lambda i. (f:real^M->real^N) (basis i) dot y):real^M` THEN
2483 X_GEN_TAC `x:real^M` THEN
2484 GEN_REWRITE_TAC (funpow 2 LAND_CONV o RAND_CONV) [GSYM BASIS_EXPANSION] THEN
2485 ASM_SIMP_TAC[LINEAR_VSUM; FINITE_NUMSEG] THEN
2486 SIMP_TAC[dot; LAMBDA_BETA; VSUM_COMPONENT; GSYM SUM_LMUL; GSYM SUM_RMUL] THEN
2487 GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN
2488 ASM_SIMP_TAC[o_THM; VECTOR_MUL_COMPONENT; LINEAR_CMUL; REAL_MUL_ASSOC]);;
2490 let ADJOINT_LINEAR = prove
2491 (`!f:real^M->real^N. linear f ==> linear(adjoint f)`,
2492 REPEAT STRIP_TAC THEN REWRITE_TAC[linear; GSYM VECTOR_EQ_LDOT] THEN
2493 ASM_SIMP_TAC[DOT_RMUL; DOT_RADD; GSYM ADJOINT_WORKS]);;
2495 let ADJOINT_CLAUSES = prove
2496 (`!f:real^M->real^N.
2497 linear f ==> (!x y. x dot (adjoint f)(y) = f(x) dot y) /\
2498 (!x y. (adjoint f)(y) dot x = y dot f(x))`,
2499 MESON_TAC[ADJOINT_WORKS; DOT_SYM]);;
2501 let ADJOINT_ADJOINT = prove
2502 (`!f:real^M->real^N. linear f ==> adjoint(adjoint f) = f`,
2503 SIMP_TAC[FUN_EQ_THM; GSYM VECTOR_EQ_LDOT; ADJOINT_CLAUSES; ADJOINT_LINEAR]);;
2505 let ADJOINT_UNIQUE = prove
2506 (`!f f'. linear f /\ (!x y. f'(x) dot y = x dot f(y))
2507 ==> f' = adjoint f`,
2508 SIMP_TAC[FUN_EQ_THM; GSYM VECTOR_EQ_RDOT; ADJOINT_CLAUSES]);;
2510 let ADJOINT_COMPOSE = prove
2511 (`!f g:real^N->real^N.
2512 linear f /\ linear g ==> adjoint(f o g) = adjoint g o adjoint f`,
2513 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC ADJOINT_UNIQUE THEN
2514 ASM_SIMP_TAC[LINEAR_COMPOSE; o_THM; ADJOINT_CLAUSES]);;
2516 let SELF_ADJOINT_COMPOSE = prove
2517 (`!f g:real^N->real^N.
2518 linear f /\ linear g /\ adjoint f = f /\ adjoint g = g
2519 ==> (adjoint(f o g) = f o g <=> f o g = g o f)`,
2520 SIMP_TAC[ADJOINT_COMPOSE] THEN MESON_TAC[]);;
2522 let SELF_ADJOINT_ORTHOGONAL_EIGENVECTORS = prove
2523 (`!f:real^N->real^N v w a b.
2524 linear f /\ adjoint f = f /\ f v = a % v /\ f w = b % w /\ ~(a = b)
2525 ==> orthogonal v w`,
2526 REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPECL [`v:real^N`; `w:real^N`] o
2527 MATCH_MP ADJOINT_WORKS) THEN
2528 ASM_REWRITE_TAC[DOT_LMUL; DOT_RMUL; orthogonal; REAL_EQ_MUL_RCANCEL]);;
2530 (* ------------------------------------------------------------------------- *)
2531 (* Matrix notation. NB: an MxN matrix is of type real^N^M, not real^M^N. *)
2532 (* We could define a special type if we're going to use them a lot. *)
2533 (* ------------------------------------------------------------------------- *)
2535 overload_interface ("--",`(matrix_neg):real^N^M->real^N^M`);;
2536 overload_interface ("+",`(matrix_add):real^N^M->real^N^M->real^N^M`);;
2537 overload_interface ("-",`(matrix_sub):real^N^M->real^N^M->real^N^M`);;
2539 make_overloadable "**" `:A->B->C`;;
2541 overload_interface ("**",`(matrix_mul):real^N^M->real^P^N->real^P^M`);;
2542 overload_interface ("**",`(matrix_vector_mul):real^N^M->real^N->real^M`);;
2543 overload_interface ("**",`(vector_matrix_mul):real^M->real^N^M->real^N`);;
2545 parse_as_infix("%%",(21,"right"));;
2549 let matrix_cmul = new_definition
2550 `((%%):real->real^N^M->real^N^M) c A = lambda i j. c * A$i$j`;;
2552 let matrix_neg = new_definition
2553 `!A:real^N^M. --A = lambda i j. --(A$i$j)`;;
2555 let matrix_add = new_definition
2556 `!A:real^N^M B:real^N^M. A + B = lambda i j. A$i$j + B$i$j`;;
2558 let matrix_sub = new_definition
2559 `!A:real^N^M B:real^N^M. A - B = lambda i j. A$i$j - B$i$j`;;
2561 let matrix_mul = new_definition
2562 `!A:real^N^M B:real^P^N.
2564 lambda i j. sum(1..dimindex(:N)) (\k. A$i$k * B$k$j)`;;
2566 let matrix_vector_mul = new_definition
2567 `!A:real^N^M x:real^N.
2568 A ** x = lambda i. sum(1..dimindex(:N)) (\j. A$i$j * x$j)`;;
2570 let vector_matrix_mul = new_definition
2571 `!A:real^N^M x:real^M.
2572 x ** A = lambda j. sum(1..dimindex(:M)) (\i. A$i$j * x$i)`;;
2574 let mat = new_definition
2575 `(mat:num->real^N^M) k = lambda i j. if i = j then &k else &0`;;
2577 let transp = new_definition
2578 `(transp:real^N^M->real^M^N) A = lambda i j. A$j$i`;;
2580 let row = new_definition
2581 `(row:num->real^N^M->real^N) i A = lambda j. A$i$j`;;
2583 let column = new_definition
2584 `(column:num->real^N^M->real^M) j A = lambda i. A$i$j`;;
2586 let rows = new_definition
2587 `rows(A:real^N^M) = { row i A | 1 <= i /\ i <= dimindex(:M)}`;;
2589 let columns = new_definition
2590 `columns(A:real^N^M) = { column i A | 1 <= i /\ i <= dimindex(:N)}`;;
2592 let MATRIX_CMUL_COMPONENT = prove
2593 (`!c A:real^N^M i. (c %% A)$i$j = c * A$i$j`,
2595 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
2596 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2597 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
2598 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2599 ASM_SIMP_TAC[matrix_cmul; CART_EQ; LAMBDA_BETA]);;
2601 let MATRIX_ADD_COMPONENT = prove
2602 (`!A B:real^N^M i j. (A + B)$i$j = A$i$j + B$i$j`,
2604 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
2605 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2606 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
2607 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2608 ASM_SIMP_TAC[matrix_add; LAMBDA_BETA]);;
2610 let MATRIX_SUB_COMPONENT = prove
2611 (`!A B:real^N^M i j. (A - B)$i$j = A$i$j - B$i$j`,
2613 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
2614 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2615 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
2616 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2617 ASM_SIMP_TAC[matrix_sub; LAMBDA_BETA]);;
2619 let MATRIX_NEG_COMPONENT = prove
2620 (`!A:real^N^M i j. (--A)$i$j = --(A$i$j)`,
2622 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
2623 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2624 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
2625 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2626 ASM_SIMP_TAC[matrix_neg; LAMBDA_BETA]);;
2628 let TRANSP_COMPONENT = prove
2629 (`!A:real^N^M i j. (transp A)$i$j = A$j$i`,
2631 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\
2632 (!A:real^M^N. A$i = A$k) /\ (!z:real^N. z$i = z$k)`
2633 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE_2]; ALL_TAC] THEN
2634 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:M) /\
2635 (!A:real^N^M. A$j = A$l) /\ (!z:real^M. z$j = z$l)`
2636 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE_2]; ALL_TAC] THEN
2637 ASM_SIMP_TAC[transp; LAMBDA_BETA]);;
2639 let MAT_COMPONENT = prove
2641 1 <= i /\ i <= dimindex(:M) /\
2642 1 <= j /\ j <= dimindex(:N)
2643 ==> (mat n:real^N^M)$i$j = if i = j then &n else &0`,
2644 SIMP_TAC[mat; LAMBDA_BETA]);;
2646 let MAT_0_COMPONENT = prove
2647 (`!i j. (mat 0:real^N^M)$i$j = &0`,
2649 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
2650 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2651 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
2652 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
2653 ASM_SIMP_TAC[mat; COND_ID; LAMBDA_BETA]);;
2655 let MATRIX_CMUL_ASSOC = prove
2656 (`!a b X:real^M^N. a %% (b %% X) = (a * b) %% X`,
2657 SIMP_TAC[CART_EQ; matrix_cmul; LAMBDA_BETA; REAL_MUL_ASSOC]);;
2659 let MATRIX_CMUL_LID = prove
2660 (`!X:real^M^N. &1 %% X = X`,
2661 SIMP_TAC[CART_EQ; matrix_cmul; LAMBDA_BETA; REAL_MUL_LID]);;
2663 let MATRIX_ADD_SYM = prove
2664 (`!A:real^N^M B. A + B = B + A`,
2665 SIMP_TAC[matrix_add; CART_EQ; LAMBDA_BETA; REAL_ADD_AC]);;
2667 let MATRIX_ADD_ASSOC = prove
2668 (`!A:real^N^M B C. A + (B + C) = (A + B) + C`,
2669 SIMP_TAC[matrix_add; CART_EQ; LAMBDA_BETA; REAL_ADD_AC]);;
2671 let MATRIX_ADD_LID = prove
2672 (`!A. mat 0 + A = A`,
2673 SIMP_TAC[matrix_add; mat; COND_ID; CART_EQ; LAMBDA_BETA; REAL_ADD_LID]);;
2675 let MATRIX_ADD_RID = prove
2676 (`!A. A + mat 0 = A`,
2677 SIMP_TAC[matrix_add; mat; COND_ID; CART_EQ; LAMBDA_BETA; REAL_ADD_RID]);;
2679 let MATRIX_ADD_LNEG = prove
2680 (`!A. --A + A = mat 0`,
2681 SIMP_TAC[matrix_neg; matrix_add; mat; COND_ID;
2682 CART_EQ; LAMBDA_BETA; REAL_ADD_LINV]);;
2684 let MATRIX_ADD_RNEG = prove
2685 (`!A. A + --A = mat 0`,
2686 SIMP_TAC[matrix_neg; matrix_add; mat; COND_ID;
2687 CART_EQ; LAMBDA_BETA; REAL_ADD_RINV]);;
2689 let MATRIX_SUB = prove
2690 (`!A:real^N^M B. A - B = A + --B`,
2691 SIMP_TAC[matrix_neg; matrix_add; matrix_sub; CART_EQ; LAMBDA_BETA;
2694 let MATRIX_SUB_REFL = prove
2695 (`!A. A - A = mat 0`,
2696 REWRITE_TAC[MATRIX_SUB; MATRIX_ADD_RNEG]);;
2698 let MATRIX_ADD_LDISTRIB = prove
2699 (`!A:real^N^M B:real^P^N C. A ** (B + C) = A ** B + A ** C`,
2700 SIMP_TAC[matrix_mul; matrix_add; CART_EQ; LAMBDA_BETA;
2701 GSYM SUM_ADD_NUMSEG] THEN
2702 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN
2703 ASM_SIMP_TAC[LAMBDA_BETA; REAL_ADD_LDISTRIB]);;
2705 let MATRIX_MUL_LID = prove
2706 (`!A:real^N^M. mat 1 ** A = A`,
2707 REWRITE_TAC[matrix_mul;
2708 GEN_REWRITE_RULE (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ]
2709 (SPEC_ALL mat)] THEN
2710 SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN REWRITE_TAC[COND_RATOR; COND_RAND] THEN
2711 SIMP_TAC[SUM_DELTA; REAL_MUL_LZERO; IN_NUMSEG; REAL_MUL_LID]);;
2713 let MATRIX_MUL_RID = prove
2714 (`!A:real^N^M. A ** mat 1 = A`,
2715 REWRITE_TAC[matrix_mul; mat] THEN
2716 SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN REWRITE_TAC[COND_RATOR; COND_RAND] THEN
2717 SIMP_TAC[SUM_DELTA; REAL_MUL_RZERO; IN_NUMSEG; REAL_MUL_RID]);;
2719 let MATRIX_MUL_ASSOC = prove
2720 (`!A:real^N^M B:real^P^N C:real^Q^P. A ** B ** C = (A ** B) ** C`,
2722 SIMP_TAC[matrix_mul; CART_EQ; LAMBDA_BETA; GSYM SUM_LMUL; GSYM SUM_RMUL] THEN
2723 REWRITE_TAC[REAL_MUL_ASSOC] THEN REPEAT STRIP_TAC THEN
2724 GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[]);;
2726 let MATRIX_MUL_LZERO = prove
2727 (`!A. (mat 0:real^N^M) ** (A:real^P^N) = mat 0`,
2728 SIMP_TAC[matrix_mul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_LZERO] THEN
2729 REWRITE_TAC[SUM_0]);;
2731 let MATRIX_MUL_RZERO = prove
2732 (`!A. (A:real^N^M) ** (mat 0:real^P^N) = mat 0`,
2733 SIMP_TAC[matrix_mul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_RZERO] THEN
2734 REWRITE_TAC[SUM_0]);;
2736 let MATRIX_ADD_RDISTRIB = prove
2737 (`!A:real^N^M B C:real^P^N. (A + B) ** C = A ** C + B ** C`,
2738 SIMP_TAC[matrix_mul; matrix_add; CART_EQ; LAMBDA_BETA] THEN
2739 REWRITE_TAC[REAL_ADD_RDISTRIB; SUM_ADD_NUMSEG]);;
2741 let MATRIX_SUB_LDISTRIB = prove
2742 (`!A:real^N^M B C:real^P^N. A ** (B - C) = A ** B - A ** C`,
2743 SIMP_TAC[matrix_mul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN
2744 REWRITE_TAC[REAL_SUB_LDISTRIB; SUM_SUB_NUMSEG]);;
2746 let MATRIX_SUB_RDISTRIB = prove
2747 (`!A:real^N^M B C:real^P^N. (A - B) ** C = A ** C - B ** C`,
2748 SIMP_TAC[matrix_mul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN
2749 REWRITE_TAC[REAL_SUB_RDISTRIB; SUM_SUB_NUMSEG]);;
2751 let MATRIX_MUL_LMUL = prove
2752 (`!A:real^N^M B:real^P^N c. (c %% A) ** B = c %% (A ** B)`,
2753 SIMP_TAC[matrix_mul; matrix_cmul; CART_EQ; LAMBDA_BETA] THEN
2754 REWRITE_TAC[GSYM REAL_MUL_ASSOC; SUM_LMUL]);;
2756 let MATRIX_MUL_RMUL = prove
2757 (`!A:real^N^M B:real^P^N c. A ** (c %% B) = c %% (A ** B)`,
2758 SIMP_TAC[matrix_mul; matrix_cmul; CART_EQ; LAMBDA_BETA] THEN
2759 ONCE_REWRITE_TAC[REAL_ARITH `A * c * B:real = c * A * B`] THEN
2760 REWRITE_TAC[SUM_LMUL]);;
2762 let MATRIX_CMUL_ADD_LDISTRIB = prove
2763 (`!A:real^N^M B c. c %% (A + B) = c %% A + c %% B`,
2764 SIMP_TAC[matrix_cmul; matrix_add; CART_EQ; LAMBDA_BETA] THEN
2765 REWRITE_TAC[REAL_ADD_LDISTRIB]);;
2767 let MATRIX_CMUL_SUB_LDISTRIB = prove
2768 (`!A:real^N^M B c. c %% (A - B) = c %% A - c %% B`,
2769 SIMP_TAC[matrix_cmul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN
2770 REWRITE_TAC[REAL_SUB_LDISTRIB]);;
2772 let MATRIX_CMUL_ADD_RDISTRIB = prove
2773 (`!A:real^N^M b c. (b + c) %% A = b %% A + c %% A`,
2774 SIMP_TAC[matrix_cmul; matrix_add; CART_EQ; LAMBDA_BETA] THEN
2775 REWRITE_TAC[REAL_ADD_RDISTRIB]);;
2777 let MATRIX_CMUL_SUB_RDISTRIB = prove
2778 (`!A:real^N^M b c. (b - c) %% A = b %% A - c %% A`,
2779 SIMP_TAC[matrix_cmul; matrix_sub; CART_EQ; LAMBDA_BETA] THEN
2780 REWRITE_TAC[REAL_SUB_RDISTRIB]);;
2782 let MATRIX_CMUL_RZERO = prove
2783 (`!c. c %% mat 0 = mat 0`,
2784 SIMP_TAC[matrix_cmul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_RZERO]);;
2786 let MATRIX_CMUL_LZERO = prove
2787 (`!A. &0 %% A = mat 0`,
2788 SIMP_TAC[matrix_cmul; mat; CART_EQ; LAMBDA_BETA; COND_ID; REAL_MUL_LZERO]);;
2790 let MATRIX_NEG_MINUS1 = prove
2791 (`!A:real^N^M. --A = --(&1) %% A`,
2792 REWRITE_TAC[matrix_cmul; matrix_neg; CART_EQ; LAMBDA_BETA] THEN
2793 REWRITE_TAC[GSYM REAL_NEG_MINUS1]);;
2795 let MATRIX_ADD_AC = prove
2796 (`(A:real^N^M) + B = B + A /\
2797 (A + B) + C = A + (B + C) /\
2798 A + (B + C) = B + (A + C)`,
2799 MESON_TAC[MATRIX_ADD_ASSOC; MATRIX_ADD_SYM]);;
2801 let MATRIX_NEG_ADD = prove
2802 (`!A B:real^N^M. --(A + B) = --A + --B`,
2803 SIMP_TAC[matrix_neg; matrix_add; CART_EQ; LAMBDA_BETA; REAL_NEG_ADD]);;
2805 let MATRIX_NEG_SUB = prove
2806 (`!A B:real^N^M. --(A - B) = B - A`,
2807 SIMP_TAC[matrix_neg; matrix_sub; CART_EQ; LAMBDA_BETA; REAL_NEG_SUB]);;
2809 let MATRIX_NEG_0 = prove
2810 (`--(mat 0) = mat 0`,
2811 SIMP_TAC[CART_EQ; mat; matrix_neg; LAMBDA_BETA; REAL_NEG_0; COND_ID]);;
2813 let MATRIX_SUB_RZERO = prove
2814 (`!A:real^N^M. A - mat 0 = A`,
2815 SIMP_TAC[CART_EQ; mat; matrix_sub; LAMBDA_BETA; REAL_SUB_RZERO; COND_ID]);;
2817 let MATRIX_SUB_LZERO = prove
2818 (`!A:real^N^M. mat 0 - A = --A`,
2819 SIMP_TAC[CART_EQ; mat; matrix_sub; matrix_neg;
2820 LAMBDA_BETA; REAL_SUB_LZERO; COND_ID]);;
2822 let MATRIX_NEG_EQ_0 = prove
2823 (`!A:real^N^M. --A = mat 0 <=> A = mat 0`,
2824 SIMP_TAC[CART_EQ; matrix_neg; mat; LAMBDA_BETA; REAL_NEG_EQ_0; COND_ID]);;
2826 let MATRIX_VECTOR_MUL_ASSOC = prove
2827 (`!A:real^N^M B:real^P^N x:real^P. A ** B ** x = (A ** B) ** x`,
2829 SIMP_TAC[matrix_mul; matrix_vector_mul;
2830 CART_EQ; LAMBDA_BETA; GSYM SUM_LMUL; GSYM SUM_RMUL] THEN
2831 REWRITE_TAC[REAL_MUL_ASSOC] THEN REPEAT STRIP_TAC THEN
2832 GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[]);;
2834 let MATRIX_VECTOR_MUL_LID = prove
2835 (`!x:real^N. mat 1 ** x = x`,
2836 REWRITE_TAC[matrix_vector_mul;
2837 GEN_REWRITE_RULE (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ]
2838 (SPEC_ALL mat)] THEN
2839 SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN REWRITE_TAC[COND_RATOR; COND_RAND] THEN
2840 SIMP_TAC[SUM_DELTA; REAL_MUL_LZERO; IN_NUMSEG; REAL_MUL_LID]);;
2842 let MATRIX_VECTOR_MUL_LZERO = prove
2843 (`!x:real^N. mat 0 ** x = vec 0`,
2844 SIMP_TAC[mat; matrix_vector_mul; CART_EQ; VEC_COMPONENT; LAMBDA_BETA;
2845 COND_ID; REAL_MUL_LZERO; SUM_0]);;
2847 let MATRIX_VECTOR_MUL_RZERO = prove
2848 (`!A:real^M^N. A ** vec 0 = vec 0`,
2849 SIMP_TAC[mat; matrix_vector_mul; CART_EQ; VEC_COMPONENT; LAMBDA_BETA;
2850 COND_ID; REAL_MUL_RZERO; SUM_0]);;
2852 let MATRIX_VECTOR_MUL_ADD_LDISTRIB = prove
2853 (`!A:real^M^N x:real^M y. A ** (x + y) = A ** x + A ** y`,
2854 SIMP_TAC[CART_EQ; matrix_vector_mul; VECTOR_ADD_COMPONENT; LAMBDA_BETA;
2855 SUM_ADD_NUMSEG; REAL_ADD_LDISTRIB]);;
2857 let MATRIX_VECTOR_MUL_SUB_LDISTRIB = prove
2858 (`!A:real^M^N x:real^M y. A ** (x - y) = A ** x - A ** y`,
2859 SIMP_TAC[CART_EQ; matrix_vector_mul; VECTOR_SUB_COMPONENT; LAMBDA_BETA;
2860 SUM_SUB_NUMSEG; REAL_SUB_LDISTRIB]);;
2862 let MATRIX_VECTOR_MUL_ADD_RDISTRIB = prove
2863 (`!A:real^M^N B x. (A + B) ** x = (A ** x) + (B ** x)`,
2864 SIMP_TAC[CART_EQ; matrix_vector_mul; matrix_add; LAMBDA_BETA;
2865 VECTOR_ADD_COMPONENT; REAL_ADD_RDISTRIB; SUM_ADD_NUMSEG]);;
2867 let MATRIX_VECTOR_MUL_SUB_RDISTRIB = prove
2868 (`!A:real^M^N B x. (A - B) ** x = (A ** x) - (B ** x)`,
2869 SIMP_TAC[CART_EQ; matrix_vector_mul; matrix_sub; LAMBDA_BETA;
2870 VECTOR_SUB_COMPONENT; REAL_SUB_RDISTRIB; SUM_SUB_NUMSEG]);;
2872 let MATRIX_VECTOR_MUL_RMUL = prove
2873 (`!A:real^M^N x:real^M c. A ** (c % x) = c % (A ** x)`,
2874 SIMP_TAC[CART_EQ; VECTOR_MUL_COMPONENT; matrix_vector_mul; LAMBDA_BETA] THEN
2875 REWRITE_TAC[GSYM SUM_LMUL] THEN REWRITE_TAC[REAL_MUL_AC]);;
2877 let MATRIX_MUL_LNEG = prove
2878 (`!A:real^N^M B:real^P^N. (--A) ** B = --(A ** B)`,
2879 REWRITE_TAC[MATRIX_NEG_MINUS1; MATRIX_MUL_LMUL]);;
2881 let MATRIX_MUL_RNEG = prove
2882 (`!A:real^N^M B:real^P^N. A ** --B = --(A ** B)`,
2883 REWRITE_TAC[MATRIX_NEG_MINUS1; MATRIX_MUL_RMUL]);;
2885 let MATRIX_NEG_NEG = prove
2886 (`!A:real^N^N. --(--A) = A`,
2887 SIMP_TAC[CART_EQ; MATRIX_NEG_COMPONENT; REAL_NEG_NEG]);;
2889 let MATRIX_TRANSP_MUL = prove
2890 (`!A B. transp(A ** B) = transp(B) ** transp(A)`,
2891 SIMP_TAC[matrix_mul; transp; CART_EQ; LAMBDA_BETA] THEN
2892 REWRITE_TAC[REAL_MUL_AC]);;
2894 let SYMMETRIC_MATRIX_MUL = prove
2896 transp(A) = A /\ transp(B) = B
2897 ==> (transp(A ** B) = A ** B <=> A ** B = B ** A)`,
2898 SIMP_TAC[MATRIX_TRANSP_MUL] THEN MESON_TAC[]);;
2900 let MATRIX_EQ = prove
2901 (`!A:real^N^M B. (A = B) = !x:real^N. A ** x = B ** x`,
2902 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
2903 DISCH_THEN(MP_TAC o GEN `i:num` o SPEC `(basis i):real^N`) THEN
2904 SIMP_TAC[CART_EQ; matrix_vector_mul; LAMBDA_BETA; basis] THEN
2905 SIMP_TAC[SUM_DELTA; COND_RAND; REAL_MUL_RZERO] THEN
2906 REWRITE_TAC[TAUT `(if p then b else T) <=> p ==> b`] THEN
2907 SIMP_TAC[REAL_MUL_RID; IN_NUMSEG]);;
2909 let MATRIX_VECTOR_MUL_COMPONENT = prove
2911 1 <= k /\ k <= dimindex(:M) ==> ((A ** x)$k = (A$k) dot x)`,
2912 SIMP_TAC[matrix_vector_mul; LAMBDA_BETA; dot]);;
2914 let DOT_LMUL_MATRIX = prove
2915 (`!A:real^N^M x:real^M y:real^N. (x ** A) dot y = x dot (A ** y)`,
2916 SIMP_TAC[dot; matrix_vector_mul; vector_matrix_mul; dot; LAMBDA_BETA] THEN
2917 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
2918 REWRITE_TAC[GSYM SUM_RMUL] THEN
2919 GEN_REWRITE_TAC RAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[REAL_MUL_AC]);;
2921 let TRANSP_MATRIX_CMUL = prove
2922 (`!A:real^M^N c. transp(c %% A) = c %% transp A`,
2923 SIMP_TAC[CART_EQ; transp; MATRIX_CMUL_COMPONENT; LAMBDA_BETA]);;
2925 let TRANSP_MATRIX_ADD = prove
2926 (`!A B:real^N^M. transp(A + B) = transp A + transp B`,
2927 SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; matrix_add]);;
2929 let TRANSP_MATRIX_SUB = prove
2930 (`!A B:real^N^M. transp(A - B) = transp A - transp B`,
2931 SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; matrix_sub]);;
2933 let TRANSP_MATRIX_NEG = prove
2934 (`!A:real^N^M. transp(--A) = --(transp A)`,
2935 SIMP_TAC[CART_EQ; transp; LAMBDA_BETA; matrix_neg]);;
2937 let TRANSP_MAT = prove
2938 (`!n. transp(mat n) = mat n`,
2939 SIMP_TAC[transp; mat; LAMBDA_BETA; CART_EQ; EQ_SYM_EQ]);;
2941 let TRANSP_TRANSP = prove
2942 (`!A:real^N^M. transp(transp A) = A`,
2943 SIMP_TAC[CART_EQ; transp; LAMBDA_BETA]);;
2945 let SYMMETRIX_MATRIX_CONJUGATE = prove
2946 (`!A B:real^N^N. transp B = B
2947 ==> transp(transp A ** B ** A) = transp A ** B ** A`,
2948 SIMP_TAC[MATRIX_TRANSP_MUL; TRANSP_TRANSP; MATRIX_MUL_ASSOC]);;
2950 let TRANSP_EQ = prove
2951 (`!A B:real^M^N. transp A = transp B <=> A = B`,
2952 MESON_TAC[TRANSP_TRANSP]);;
2954 let ROW_TRANSP = prove
2956 1 <= i /\ i <= dimindex(:N) ==> row i (transp A) = column i A`,
2957 SIMP_TAC[row; column; transp; CART_EQ; LAMBDA_BETA]);;
2959 let COLUMN_TRANSP = prove
2961 1 <= i /\ i <= dimindex(:M) ==> column i (transp A) = row i A`,
2962 SIMP_TAC[row; column; transp; CART_EQ; LAMBDA_BETA]);;
2964 let ROWS_TRANSP = prove
2965 (`!A:real^N^M. rows(transp A) = columns A`,
2966 REWRITE_TAC[rows; columns; EXTENSION; IN_ELIM_THM] THEN
2967 MESON_TAC[ROW_TRANSP]);;
2969 let COLUMNS_TRANSP = prove
2970 (`!A:real^N^M. columns(transp A) = rows A`,
2971 MESON_TAC[TRANSP_TRANSP; ROWS_TRANSP]);;
2973 let VECTOR_MATRIX_MUL_TRANSP = prove
2974 (`!A:real^M^N x:real^N. x ** A = transp A ** x`,
2975 REWRITE_TAC[matrix_vector_mul; vector_matrix_mul; transp] THEN
2976 SIMP_TAC[LAMBDA_BETA; CART_EQ]);;
2978 let MATRIX_VECTOR_MUL_TRANSP = prove
2979 (`!A:real^M^N x:real^M. A ** x = x ** transp A`,
2980 REWRITE_TAC[VECTOR_MATRIX_MUL_TRANSP; TRANSP_TRANSP]);;
2982 let FINITE_ROWS = prove
2983 (`!A:real^N^M. FINITE(rows A)`,
2984 REWRITE_TAC[rows] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
2985 SIMP_TAC[GSYM numseg; FINITE_IMAGE; FINITE_NUMSEG]);;
2987 let FINITE_COLUMNS = prove
2988 (`!A:real^N^M. FINITE(columns A)`,
2989 REWRITE_TAC[columns] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
2990 SIMP_TAC[GSYM numseg; FINITE_IMAGE; FINITE_NUMSEG]);;
2992 let MATRIX_EQUAL_ROWS = prove
2994 A = B <=> !i. 1 <= i /\ i <= dimindex(:M) ==> row i A = row i B`,
2995 SIMP_TAC[row; CART_EQ; LAMBDA_BETA]);;
2997 let MATRIX_EQUAL_COLUMNS = prove
2999 A = B <=> !i. 1 <= i /\ i <= dimindex(:N) ==> column i A = column i B`,
3000 SIMP_TAC[column; CART_EQ; LAMBDA_BETA] THEN MESON_TAC[]);;
3002 let MATRIX_CMUL_EQ_0 = prove
3003 (`!A:real^M^N c. c %% A = mat 0 <=> c = &0 \/ A = mat 0`,
3004 SIMP_TAC[CART_EQ; MATRIX_CMUL_COMPONENT; MAT_COMPONENT; COND_ID] THEN
3005 REPEAT GEN_TAC THEN ASM_CASES_TAC `c = &0` THEN
3006 ASM_REWRITE_TAC[REAL_ENTIRE]);;
3009 (`!m n. mat m = mat n <=> m = n`,
3010 SIMP_TAC[CART_EQ; MAT_COMPONENT] THEN REPEAT STRIP_TAC THEN
3011 MESON_TAC[REAL_OF_NUM_EQ; DIMINDEX_GE_1; LE_REFL]);;
3013 (* ------------------------------------------------------------------------- *)
3014 (* Two sometimes fruitful ways of looking at matrix-vector multiplication. *)
3015 (* ------------------------------------------------------------------------- *)
3017 let MATRIX_MUL_DOT = prove
3018 (`!A:real^N^M x. A ** x = lambda i. A$i dot x`,
3019 REWRITE_TAC[matrix_vector_mul; dot] THEN SIMP_TAC[CART_EQ; LAMBDA_BETA]);;
3021 let MATRIX_MUL_VSUM = prove
3022 (`!A:real^N^M x. A ** x = vsum(1..dimindex(:N)) (\i. x$i % column i A)`,
3023 SIMP_TAC[matrix_vector_mul; CART_EQ; VSUM_COMPONENT; LAMBDA_BETA;
3024 VECTOR_MUL_COMPONENT; column; REAL_MUL_AC]);;
3026 (* ------------------------------------------------------------------------- *)
3027 (* Slightly gruesome lemmas: better to define sums over vectors really... *)
3028 (* ------------------------------------------------------------------------- *)
3030 let VECTOR_COMPONENTWISE = prove
3032 x = lambda j. sum(1..dimindex(:N))
3033 (\i. x$i * (basis i :real^N)$j)`,
3034 SIMP_TAC[CART_EQ; LAMBDA_BETA; basis] THEN
3035 ONCE_REWRITE_TAC[ARITH_RULE `(m:num = n) <=> (n = m)`] THEN
3036 SIMP_TAC[COND_RAND; REAL_MUL_RZERO; SUM_DELTA; IN_NUMSEG] THEN
3037 REWRITE_TAC[REAL_MUL_RID; COND_ID]);;
3039 let LINEAR_COMPONENTWISE_EXPANSION = prove
3040 (`!f:real^M->real^N.
3042 ==> !x j. 1 <= j /\ j <= dimindex(:N)
3044 sum(1..dimindex(:M)) (\i. x$i * f(basis i)$j))`,
3045 REWRITE_TAC[linear] THEN REPEAT STRIP_TAC THEN
3046 GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV)
3047 [VECTOR_COMPONENTWISE] THEN
3048 SPEC_TAC(`dimindex(:M)`,`n:num`) THEN
3049 INDUCT_TAC THEN REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH] THENL
3050 [REWRITE_TAC[GSYM vec] THEN
3051 GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o RAND_CONV)
3052 [GSYM VECTOR_MUL_LZERO] THEN
3053 ASM_REWRITE_TAC[] THEN REWRITE_TAC[VECTOR_MUL_LZERO] THEN
3054 ASM_SIMP_TAC[vec; LAMBDA_BETA];
3055 REWRITE_TAC[ARITH_RULE `1 <= SUC n`] THEN
3056 ASSUM_LIST(fun thl -> REWRITE_TAC(map GSYM thl)) THEN
3057 SIMP_TAC[GSYM VECTOR_MUL_COMPONENT;
3058 ASSUME `1 <= j`; ASSUME `j <= dimindex(:N)`] THEN
3059 ASSUM_LIST(fun thl -> REWRITE_TAC(map GSYM thl)) THEN
3060 SIMP_TAC[GSYM VECTOR_ADD_COMPONENT;
3061 ASSUME `1 <= j`; ASSUME `j <= dimindex(:N)`] THEN
3062 ASSUM_LIST(fun thl -> REWRITE_TAC(map GSYM thl)) THEN
3063 AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
3064 ASM_SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; LAMBDA_BETA] THEN
3065 SIMP_TAC[VECTOR_MUL_COMPONENT]]);;
3067 (* ------------------------------------------------------------------------- *)
3068 (* Inverse matrices (not necessarily square, but it's vacuous otherwise). *)
3069 (* ------------------------------------------------------------------------- *)
3071 let invertible = new_definition
3072 `invertible(A:real^N^M) <=>
3073 ?A':real^M^N. (A ** A' = mat 1) /\ (A' ** A = mat 1)`;;
3075 let matrix_inv = new_definition
3076 `matrix_inv(A:real^N^M) =
3077 @A':real^M^N. (A ** A' = mat 1) /\ (A' ** A = mat 1)`;;
3079 let MATRIX_INV = prove
3081 invertible A ==> A ** matrix_inv A = mat 1 /\ matrix_inv A ** A = mat 1`,
3082 GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[matrix_inv; invertible] THEN
3083 CONV_TAC SELECT_CONV THEN ASM_REWRITE_TAC[GSYM invertible]);;
3085 let MATRIX_INV_UNIQUE = prove
3086 (`!A:real^N^M B. A ** B = mat 1 /\ B ** A = mat 1 ==> matrix_inv A = B`,
3087 REPEAT STRIP_TAC THEN MP_TAC(ISPEC `A:real^N^M` MATRIX_INV) THEN
3088 ANTS_TAC THENL [ASM_MESON_TAC[invertible]; ALL_TAC] THEN
3090 AP_TERM `(( ** ):real^M^N->real^M^M->real^M^N) B` o CONJUNCT1) THEN
3091 ASM_REWRITE_TAC[MATRIX_MUL_ASSOC; MATRIX_MUL_LID; MATRIX_MUL_RID]);;
3093 let INVERTIBLE_NEG = prove
3094 (`!A:real^N^M. invertible(--A) <=> invertible A`,
3095 REWRITE_TAC[invertible] THEN
3096 MESON_TAC[MATRIX_MUL_LNEG; MATRIX_MUL_RNEG; MATRIX_NEG_NEG]);;
3098 let MATRIX_INV_I = prove
3099 (`matrix_inv(mat 1:real^N^N) = mat 1`,
3100 MATCH_MP_TAC MATRIX_INV_UNIQUE THEN
3101 REWRITE_TAC[MATRIX_MUL_LID]);;
3103 (* ------------------------------------------------------------------------- *)
3104 (* Correspondence between matrices and linear operators. *)
3105 (* ------------------------------------------------------------------------- *)
3107 let matrix = new_definition
3108 `(matrix:(real^M->real^N)->real^M^N) f = lambda i j. f(basis j)$i`;;
3110 let MATRIX_VECTOR_MUL_LINEAR = prove
3111 (`!A:real^N^M. linear(\x. A ** x)`,
3112 REWRITE_TAC[linear; matrix_vector_mul] THEN
3113 SIMP_TAC[CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
3114 VECTOR_MUL_COMPONENT] THEN
3115 REWRITE_TAC[GSYM SUM_ADD_NUMSEG; GSYM SUM_LMUL; REAL_ADD_LDISTRIB] THEN
3116 REWRITE_TAC[REAL_ADD_AC; REAL_MUL_AC]);;
3118 let MATRIX_WORKS = prove
3119 (`!f:real^M->real^N. linear f ==> !x. matrix f ** x = f(x)`,
3120 REWRITE_TAC[matrix; matrix_vector_mul] THEN
3121 SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN GEN_TAC THEN DISCH_TAC THEN
3122 REPEAT GEN_TAC THEN DISCH_TAC THEN
3123 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
3124 ASM_SIMP_TAC[GSYM LINEAR_COMPONENTWISE_EXPANSION]);;
3126 let MATRIX_VECTOR_MUL = prove
3127 (`!f:real^M->real^N. linear f ==> f = \x. matrix f ** x`,
3128 SIMP_TAC[FUN_EQ_THM; MATRIX_WORKS]);;
3130 let MATRIX_OF_MATRIX_VECTOR_MUL = prove
3131 (`!A:real^N^M. matrix(\x. A ** x) = A`,
3132 SIMP_TAC[MATRIX_EQ; MATRIX_VECTOR_MUL_LINEAR; MATRIX_WORKS]);;
3134 let MATRIX_COMPOSE = prove
3135 (`!f g. linear f /\ linear g ==> (matrix(g o f) = matrix g ** matrix f)`,
3136 SIMP_TAC[MATRIX_EQ; MATRIX_WORKS; LINEAR_COMPOSE;
3137 GSYM MATRIX_VECTOR_MUL_ASSOC; o_THM]);;
3139 let MATRIX_VECTOR_COLUMN = prove
3141 A ** x = vsum(1..dimindex(:N)) (\i. x$i % (transp A)$i)`,
3142 REWRITE_TAC[matrix_vector_mul; transp] THEN
3143 SIMP_TAC[CART_EQ; LAMBDA_BETA; VSUM_COMPONENT; VECTOR_MUL_COMPONENT] THEN
3144 REWRITE_TAC[REAL_MUL_AC]);;
3146 let MATRIX_MUL_COMPONENT = prove
3147 (`!i. 1 <= i /\ i <= dimindex(:N)
3148 ==> ((A:real^N^N) ** (B:real^N^N))$i = transp B ** A$i`,
3149 SIMP_TAC[matrix_mul; LAMBDA_BETA; matrix_vector_mul; vector_matrix_mul;
3150 transp; CART_EQ] THEN
3151 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN
3152 REWRITE_TAC[REAL_MUL_AC]);;
3154 let ADJOINT_MATRIX = prove
3155 (`!A:real^N^M. adjoint(\x. A ** x) = (\x. transp A ** x)`,
3156 GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC ADJOINT_UNIQUE THEN
3157 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN REPEAT GEN_TAC THEN
3158 SIMP_TAC[transp; dot; LAMBDA_BETA; matrix_vector_mul;
3159 GSYM SUM_LMUL; GSYM SUM_RMUL] THEN
3160 GEN_REWRITE_TAC LAND_CONV [SUM_SWAP_NUMSEG] THEN REWRITE_TAC[REAL_MUL_AC]);;
3162 let MATRIX_ADJOINT = prove
3163 (`!f. linear f ==> matrix(adjoint f) = transp(matrix f)`,
3164 GEN_TAC THEN DISCH_THEN
3165 (fun th -> GEN_REWRITE_TAC (LAND_CONV o funpow 2 RAND_CONV)
3166 [MATCH_MP MATRIX_VECTOR_MUL th]) THEN
3167 REWRITE_TAC[ADJOINT_MATRIX; MATRIX_OF_MATRIX_VECTOR_MUL]);;
3169 let MATRIX_ID = prove
3170 (`matrix(\x. x) = mat 1`,
3171 SIMP_TAC[MATRIX_EQ; LINEAR_ID; MATRIX_WORKS; MATRIX_VECTOR_MUL_LID]);;
3173 let MATRIX_I = prove
3174 (`matrix I = mat 1`,
3175 REWRITE_TAC[I_DEF; MATRIX_ID]);;
3177 let LINEAR_EQ_MATRIX = prove
3178 (`!f g. linear f /\ linear g /\ matrix f = matrix g ==> f = g`,
3179 REPEAT STRIP_TAC THEN
3180 REPEAT(FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP MATRIX_VECTOR_MUL)) THEN
3181 ASM_REWRITE_TAC[]);;
3183 let MATRIX_SELF_ADJOINT = prove
3184 (`!f. linear f ==> (adjoint f = f <=> transp(matrix f) = matrix f)`,
3185 SIMP_TAC[GSYM MATRIX_ADJOINT] THEN
3186 MESON_TAC[LINEAR_EQ_MATRIX; ADJOINT_LINEAR]);;
3188 let LINEAR_MATRIX_EXISTS = prove
3189 (`!f:real^M->real^N. linear f <=> ?A:real^M^N. f = \x. A ** x`,
3190 GEN_TAC THEN EQ_TAC THEN
3191 SIMP_TAC[MATRIX_VECTOR_MUL_LINEAR; LEFT_IMP_EXISTS_THM] THEN
3192 DISCH_TAC THEN EXISTS_TAC `matrix(f:real^M->real^N)` THEN
3193 ASM_SIMP_TAC[GSYM MATRIX_VECTOR_MUL]);;
3195 let LINEAR_1 = prove
3196 (`!f:real^1->real^1. linear f <=> ?c. f = \x. c % x`,
3197 SIMP_TAC[LINEAR_MATRIX_EXISTS; EXISTS_VECTOR_1] THEN
3198 SIMP_TAC[FUN_EQ_THM; CART_EQ; FORALL_1; DIMINDEX_1; VECTOR_1;
3199 matrix_vector_mul; SUM_1; CART_EQ; LAMBDA_BETA;
3200 VECTOR_MUL_COMPONENT]);;
3202 let SYMMETRIC_MATRIX = prove
3203 (`!A:real^N^N. transp A = A <=> adjoint(\x. A ** x) = \x. A ** x`,
3204 SIMP_TAC[MATRIX_SELF_ADJOINT; MATRIX_VECTOR_MUL_LINEAR] THEN
3205 REWRITE_TAC[MATRIX_OF_MATRIX_VECTOR_MUL]);;
3207 let SYMMETRIC_MATRIX_ORTHOGONAL_EIGENVECTORS = prove
3208 (`!A:real^N^N v w a b.
3209 transp A = A /\ A ** v = a % v /\ A ** w = b % w /\ ~(a = b)
3210 ==> orthogonal v w`,
3211 REPEAT GEN_TAC THEN REWRITE_TAC[SYMMETRIC_MATRIX] THEN
3212 DISCH_THEN(MATCH_MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ_ALT]
3213 SELF_ADJOINT_ORTHOGONAL_EIGENVECTORS)) THEN
3214 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);;
3216 (* ------------------------------------------------------------------------- *)
3217 (* Operator norm. *)
3218 (* ------------------------------------------------------------------------- *)
3220 let onorm = new_definition
3221 `onorm (f:real^M->real^N) = sup { norm(f x) | norm(x) = &1 }`;;
3223 let NORM_BOUND_GENERALIZE = prove
3224 (`!f:real^M->real^N b.
3226 ==> ((!x. (norm(x) = &1) ==> norm(f x) <= b) <=>
3227 (!x. norm(f x) <= b * norm(x)))`,
3228 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
3229 [ALL_TAC; ASM_MESON_TAC[REAL_MUL_RID]] THEN
3230 X_GEN_TAC `x:real^M` THEN ASM_CASES_TAC `x:real^M = vec 0` THENL
3231 [ASM_REWRITE_TAC[NORM_0; REAL_MUL_RZERO] THEN
3232 ASM_MESON_TAC[LINEAR_0; NORM_0; REAL_LE_REFL];
3234 ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; NORM_POS_LT; real_div] THEN
3235 MATCH_MP_TAC(REAL_ARITH `abs(a * b) <= c ==> b * a <= c`) THEN
3236 REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NORM; GSYM NORM_MUL] THEN
3237 FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN
3238 ASM_SIMP_TAC[NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM; REAL_MUL_LINV;
3242 (`!f:real^M->real^N.
3244 ==> (!x. norm(f x) <= onorm f * norm(x)) /\
3245 (!b. (!x. norm(f x) <= b * norm(x)) ==> onorm f <= b)`,
3246 GEN_TAC THEN DISCH_TAC THEN
3247 MP_TAC(SPEC `{ norm((f:real^M->real^N) x) | norm(x) = &1 }` SUP) THEN
3248 SIMP_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
3249 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
3250 REWRITE_TAC[LEFT_FORALL_IMP_THM; RIGHT_EXISTS_AND_THM; EXISTS_REFL] THEN
3251 ASM_SIMP_TAC[NORM_BOUND_GENERALIZE; GSYM onorm; GSYM MEMBER_NOT_EMPTY] THEN
3252 DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
3253 ASM_MESON_TAC[VECTOR_CHOOSE_SIZE; LINEAR_BOUNDED; REAL_POS]);;
3255 let ONORM_POS_LE = prove
3256 (`!f. linear f ==> &0 <= onorm f`,
3257 MESON_TAC[ONORM; VECTOR_CHOOSE_SIZE; REAL_POS; REAL_MUL_RID; NORM_POS_LE;
3260 let ONORM_EQ_0 = prove
3261 (`!f:real^M->real^N. linear f ==> ((onorm f = &0) <=> (!x. f x = vec 0))`,
3262 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
3263 MP_TAC(SPEC `f:real^M->real^N` ONORM) THEN
3264 ASM_SIMP_TAC[GSYM REAL_LE_ANTISYM; ONORM_POS_LE; NORM_0; REAL_MUL_LZERO;
3265 NORM_LE_0; REAL_LE_REFL]);;
3267 let ONORM_CONST = prove
3268 (`!y:real^N. onorm(\x:real^M. y) = norm(y)`,
3269 GEN_TAC THEN REWRITE_TAC[onorm] THEN
3270 MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC `sup {norm(y:real^N)}` THEN
3272 [AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE
3273 `(?x. P x) ==> {f y | x | P x} = {f y}`) THEN
3274 EXISTS_TAC `basis 1 :real^M` THEN
3275 SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL];
3276 MATCH_MP_TAC REAL_SUP_UNIQUE THEN SET_TAC[REAL_LE_REFL]]);;
3278 let ONORM_POS_LT = prove
3279 (`!f. linear f ==> (&0 < onorm f <=> ~(!x. f x = vec 0))`,
3280 SIMP_TAC[GSYM ONORM_EQ_0; ONORM_POS_LE;
3281 REAL_ARITH `(&0 < x <=> ~(x = &0)) <=> &0 <= x`]);;
3283 let ONORM_COMPOSE = prove
3284 (`!f g. linear f /\ linear g ==> onorm(f o g) <= onorm f * onorm g`,
3285 MESON_TAC[ONORM; LINEAR_COMPOSE; o_THM; REAL_MUL_ASSOC; REAL_LE_TRANS; ONORM;
3286 REAL_LE_LMUL; ONORM_POS_LE]);;
3288 let ONORM_NEG_LEMMA = prove
3289 (`!f. linear f ==> onorm(\x. --(f x)) <= onorm f`,
3290 REPEAT STRIP_TAC THEN
3291 FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP ONORM o
3292 MATCH_MP LINEAR_COMPOSE_NEG) THEN
3293 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[NORM_NEG; ONORM]);;
3295 let ONORM_NEG = prove
3296 (`!f:real^M->real^N. linear f ==> (onorm(\x. --(f x)) = onorm f)`,
3297 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
3298 ASM_SIMP_TAC[ONORM_NEG_LEMMA] THEN
3299 SUBGOAL_THEN `f:real^M->real^N = \x. --(--(f x))`
3300 (fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [th]) THEN
3301 ASM_SIMP_TAC[ONORM_NEG_LEMMA; LINEAR_COMPOSE_NEG] THEN
3302 REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);;
3304 let ONORM_TRIANGLE = prove
3305 (`!f:real^M->real^N g.
3306 linear f /\ linear g ==> onorm(\x. f x + g x) <= onorm f + onorm g`,
3307 REPEAT GEN_TAC THEN DISCH_TAC THEN
3308 FIRST_ASSUM(MATCH_MP_TAC o CONJUNCT2 o MATCH_MP ONORM o MATCH_MP
3309 LINEAR_COMPOSE_ADD) THEN
3310 REWRITE_TAC[REAL_ADD_RDISTRIB] THEN
3311 ASM_MESON_TAC[REAL_LE_ADD2; REAL_LE_TRANS; NORM_TRIANGLE; ONORM]);;
3313 let ONORM_TRIANGLE_LE = prove
3314 (`!f g. linear f /\ linear g /\ onorm(f) + onorm(g) <= e
3315 ==> onorm(\x. f x + g x) <= e`,
3316 MESON_TAC[REAL_LE_TRANS; ONORM_TRIANGLE]);;
3318 let ONORM_TRIANGLE_LT = prove
3319 (`!f g. linear f /\ linear g /\ onorm(f) + onorm(g) < e
3320 ==> onorm(\x. f x + g x) < e`,
3321 MESON_TAC[REAL_LET_TRANS; ONORM_TRIANGLE]);;
3323 let ONORM_ID = prove
3324 (`onorm(\x:real^N. x) = &1`,
3325 REWRITE_TAC[onorm] THEN
3326 SUBGOAL_THEN `{norm(x:real^N) | norm x = &1} = {&1}`
3327 (fun th -> REWRITE_TAC[th; SUP_SING]) THEN
3328 SUBGOAL_THEN `norm(basis 1:real^N) = &1` MP_TAC THENL
3329 [SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL]; SET_TAC[]]);;
3332 (`onorm(I:real^N->real^N) = &1`,
3333 REWRITE_TAC[I_DEF; ONORM_ID]);;
3335 (* ------------------------------------------------------------------------- *)
3336 (* It's handy to "lift" from R to R^1 and "drop" from R^1 to R. *)
3337 (* ------------------------------------------------------------------------- *)
3339 let lift = new_definition
3340 `(lift:real->real^1) x = lambda i. x`;;
3342 let drop = new_definition
3343 `(drop:real^1->real) x = x$1`;;
3345 let LIFT_COMPONENT = prove
3346 (`!x. (lift x)$1 = x`,
3347 SIMP_TAC[lift; LAMBDA_BETA; DIMINDEX_1; LE_ANTISYM]);;
3349 let LIFT_DROP = prove
3350 (`(!x. lift(drop x) = x) /\ (!x. drop(lift x) = x)`,
3351 SIMP_TAC[lift; drop; CART_EQ; LAMBDA_BETA; DIMINDEX_1; LE_ANTISYM]);;
3353 let IMAGE_LIFT_DROP = prove
3354 (`(!s. IMAGE (lift o drop) s = s) /\ (!s. IMAGE (drop o lift) s = s)`,
3355 REWRITE_TAC[o_DEF; LIFT_DROP] THEN SET_TAC[]);;
3357 let IN_IMAGE_LIFT_DROP = prove
3358 (`(!x s. x IN IMAGE lift s <=> drop x IN s) /\
3359 (!x s. x IN IMAGE drop s <=> lift x IN s)`,
3360 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);;
3362 let FORALL_LIFT = prove
3363 (`(!x. P x) = (!x. P(lift x))`,
3364 MESON_TAC[LIFT_DROP]);;
3366 let EXISTS_LIFT = prove
3367 (`(?x. P x) = (?x. P(lift x))`,
3368 MESON_TAC[LIFT_DROP]);;
3370 let FORALL_DROP = prove
3371 (`(!x. P x) = (!x. P(drop x))`,
3372 MESON_TAC[LIFT_DROP]);;
3374 let EXISTS_DROP = prove
3375 (`(?x. P x) = (?x. P(drop x))`,
3376 MESON_TAC[LIFT_DROP]);;
3378 let FORALL_LIFT_FUN = prove
3379 (`!P:(A->real^1)->bool. (!f. P f) <=> (!f. P(lift o f))`,
3380 GEN_TAC THEN EQ_TAC THEN SIMP_TAC[] THEN DISCH_TAC THEN
3381 X_GEN_TAC `f:A->real^1` THEN
3382 FIRST_X_ASSUM(MP_TAC o SPEC `drop o (f:A->real^1)`) THEN
3383 REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]);;
3385 let FORALL_DROP_FUN = prove
3386 (`!P:(A->real)->bool. (!f. P f) <=> (!f. P(drop o f))`,
3387 REWRITE_TAC[FORALL_LIFT_FUN; o_DEF; LIFT_DROP; ETA_AX]);;
3389 let EXISTS_LIFT_FUN = prove
3390 (`!P:(A->real^1)->bool. (?f. P f) <=> (?f. P(lift o f))`,
3391 ONCE_REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
3392 REWRITE_TAC[FORALL_LIFT_FUN]);;
3394 let EXISTS_DROP_FUN = prove
3395 (`!P:(A->real)->bool. (?f. P f) <=> (?f. P(drop o f))`,
3396 ONCE_REWRITE_TAC[MESON[] `(?x. P x) <=> ~(!x. ~P x)`] THEN
3397 REWRITE_TAC[FORALL_DROP_FUN]);;
3400 (`!x y. (lift x = lift y) <=> (x = y)`,
3401 MESON_TAC[LIFT_DROP]);;
3404 (`!x y. (drop x = drop y) <=> (x = y)`,
3405 MESON_TAC[LIFT_DROP]);;
3407 let LIFT_IN_IMAGE_LIFT = prove
3408 (`!x s. (lift x) IN (IMAGE lift s) <=> x IN s`,
3409 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);;
3411 let FORALL_LIFT_IMAGE = prove
3412 (`!P. (!s. P s) <=> (!s. P(IMAGE lift s))`,
3413 MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);;
3415 let EXISTS_LIFT_IMAGE = prove
3416 (`!P. (?s. P s) <=> (?s. P(IMAGE lift s))`,
3417 MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);;
3419 let SUBSET_LIFT_IMAGE = prove
3420 (`!s t. IMAGE lift s SUBSET IMAGE lift t <=> s SUBSET t`,
3421 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[IMAGE_SUBSET] THEN
3422 DISCH_THEN(MP_TAC o ISPEC `drop` o MATCH_MP IMAGE_SUBSET) THEN
3423 REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP]);;
3425 let FORALL_DROP_IMAGE = prove
3426 (`!P. (!s. P s) <=> (!s. P(IMAGE drop s))`,
3427 MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);;
3429 let EXISTS_DROP_IMAGE = prove
3430 (`!P. (?s. P s) <=> (?s. P(IMAGE drop s))`,
3431 MESON_TAC[IMAGE_LIFT_DROP; IMAGE_o]);;
3433 let SUBSET_DROP_IMAGE = prove
3434 (`!s t. IMAGE drop s SUBSET IMAGE drop t <=> s SUBSET t`,
3435 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[IMAGE_SUBSET] THEN
3436 DISCH_THEN(MP_TAC o ISPEC `lift` o MATCH_MP IMAGE_SUBSET) THEN
3437 REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP]);;
3439 let DROP_IN_IMAGE_DROP = prove
3440 (`!x s. (drop x) IN (IMAGE drop s) <=> x IN s`,
3441 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);;
3443 let LIFT_NUM = prove
3444 (`!n. lift(&n) = vec n`,
3445 SIMP_TAC[CART_EQ; lift; vec; LAMBDA_BETA]);;
3447 let LIFT_ADD = prove
3448 (`!x y. lift(x + y) = lift x + lift y`,
3449 SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_ADD_COMPONENT]);;
3451 let LIFT_SUB = prove
3452 (`!x y. lift(x - y) = lift x - lift y`,
3453 SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_SUB_COMPONENT]);;
3455 let LIFT_CMUL = prove
3456 (`!x c. lift(c * x) = c % lift(x)`,
3457 SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_MUL_COMPONENT]);;
3459 let LIFT_NEG = prove
3460 (`!x. lift(--x) = --(lift x)`,
3461 SIMP_TAC[CART_EQ; lift; LAMBDA_BETA; VECTOR_NEG_COMPONENT]);;
3463 let LIFT_EQ_CMUL = prove
3464 (`!x. lift x = x % vec 1`,
3465 REWRITE_TAC[GSYM LIFT_NUM; GSYM LIFT_CMUL; REAL_MUL_RID]);;
3467 let SUM_VSUM = prove
3468 (`!f s. sum s f = drop(vsum s(lift o f))`,
3469 SIMP_TAC[vsum; drop; LAMBDA_BETA; DIMINDEX_1; ARITH] THEN
3470 REWRITE_TAC[o_THM; GSYM drop; LIFT_DROP; ETA_AX]);;
3472 let VSUM_REAL = prove
3473 (`!f s. vsum s f = lift(sum s (drop o f))`,
3474 REWRITE_TAC[o_DEF; SUM_VSUM; LIFT_DROP; ETA_AX]);;
3476 let LIFT_SUM = prove
3477 (`!k x. lift(sum k x) = vsum k (lift o x)`,
3478 REWRITE_TAC[SUM_VSUM; LIFT_DROP]);;
3480 let DROP_VSUM = prove
3481 (`!k x. drop(vsum k x) = sum k (drop o x)`,
3482 REWRITE_TAC[VSUM_REAL; LIFT_DROP]);;
3484 let DROP_LAMBDA = prove
3485 (`!x. drop(lambda i. x i) = x 1`,
3486 SIMP_TAC[drop; LAMBDA_BETA; DIMINDEX_1; LE_REFL]);;
3488 let DROP_VEC = prove
3489 (`!n. drop(vec n) = &n`,
3490 MESON_TAC[LIFT_DROP; LIFT_NUM]);;
3492 let DROP_ADD = prove
3493 (`!x y. drop(x + y) = drop x + drop y`,
3494 MESON_TAC[LIFT_DROP; LIFT_ADD]);;
3496 let DROP_SUB = prove
3497 (`!x y. drop(x - y) = drop x - drop y`,
3498 MESON_TAC[LIFT_DROP; LIFT_SUB]);;
3500 let DROP_CMUL = prove
3501 (`!x c. drop(c % x) = c * drop(x)`,
3502 MESON_TAC[LIFT_DROP; LIFT_CMUL]);;
3504 let DROP_NEG = prove
3505 (`!x. drop(--x) = --(drop x)`,
3506 MESON_TAC[LIFT_DROP; LIFT_NEG]);;
3509 (`!x. norm x = abs(drop x)`,
3510 REWRITE_TAC[drop; NORM_REAL]);;
3512 let NORM_1_POS = prove
3513 (`!x. &0 <= drop x ==> norm x = drop x`,
3514 SIMP_TAC[NORM_1; real_abs]);;
3516 let NORM_LIFT = prove
3517 (`!x. norm(lift x) = abs(x)`,
3518 SIMP_TAC[lift; NORM_REAL; LIFT_COMPONENT]);;
3520 let DIST_LIFT = prove
3521 (`!x y. dist(lift x,lift y) = abs(x - y)`,
3522 REWRITE_TAC[DIST_REAL; LIFT_COMPONENT]);;
3524 let ABS_DROP = prove
3525 (`!x. norm x = abs(drop x)`,
3526 REWRITE_TAC[FORALL_LIFT; LIFT_DROP; NORM_LIFT]);;
3528 let LINEAR_VMUL_DROP = prove
3529 (`!f v. linear f ==> linear (\x. drop(f x) % v)`,
3530 SIMP_TAC[drop; LINEAR_VMUL_COMPONENT; DIMINDEX_1; LE_REFL]);;
3532 let LINEAR_FROM_REALS = prove
3533 (`!f:real^1->real^N. linear f ==> f = \x. drop x % column 1 (matrix f)`,
3534 GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
3535 DISCH_THEN(fun th -> REWRITE_TAC[GSYM(MATCH_MP MATRIX_WORKS th)]) THEN
3536 SIMP_TAC[CART_EQ; matrix_vector_mul; vector_mul; LAMBDA_BETA;
3537 DIMINDEX_1; SUM_SING_NUMSEG; drop; column] THEN
3538 REWRITE_TAC[REAL_MUL_AC]);;
3540 let LINEAR_TO_REALS = prove
3541 (`!f:real^N->real^1. linear f ==> f = \x. lift(row 1 (matrix f) dot x)`,
3542 GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
3543 DISCH_THEN(fun th -> REWRITE_TAC[GSYM(MATCH_MP MATRIX_WORKS th)]) THEN
3544 SIMP_TAC[CART_EQ; matrix_vector_mul; dot; LAMBDA_BETA;
3545 DIMINDEX_1; SUM_SING_NUMSEG; lift; row; LE_ANTISYM]);;
3547 let DROP_EQ_0 = prove
3548 (`!x. drop x = &0 <=> x = vec 0`,
3549 REWRITE_TAC[GSYM DROP_EQ; DROP_VEC]);;
3551 let DROP_WLOG_LE = prove
3552 (`(!x y. P x y <=> P y x) /\ (!x y. drop x <= drop y ==> P x y)
3554 MESON_TAC[REAL_LE_TOTAL]);;
3556 let IMAGE_LIFT_UNIV = prove
3557 (`IMAGE lift (:real) = (:real^1)`,
3558 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNIV] THEN MESON_TAC[LIFT_DROP]);;
3560 let IMAGE_DROP_UNIV = prove
3561 (`IMAGE drop (:real^1) = (:real)`,
3562 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNIV] THEN MESON_TAC[LIFT_DROP]);;
3564 let LINEAR_LIFT_DOT = prove
3565 (`!a. linear(\x. lift(a dot x))`,
3566 REWRITE_TAC[linear; DOT_RMUL; DOT_RADD; LIFT_ADD; LIFT_CMUL]);;
3568 let LINEAR_LIFT_COMPONENT = prove
3569 (`!k. linear(\x:real^N. lift(x$k))`,
3571 SUBGOAL_THEN `?j. 1 <= j /\ j <= dimindex(:N) /\ !z:real^N. z$k = z$j`
3573 [REWRITE_TAC[FINITE_INDEX_INRANGE];
3574 MP_TAC(ISPEC `basis j:real^N` LINEAR_LIFT_DOT) THEN
3575 ASM_SIMP_TAC[DOT_BASIS]]);;
3577 let BILINEAR_DROP_MUL = prove
3578 (`bilinear (\x y:real^N. drop x % y)`,
3579 REWRITE_TAC[bilinear; linear] THEN
3580 REWRITE_TAC[DROP_ADD; DROP_CMUL] THEN VECTOR_ARITH_TAC);;
3582 let LINEAR_COMPONENTWISE = prove
3583 (`!f:real^M->real^N.
3585 !i. 1 <= i /\ i <= dimindex(:N) ==> linear(\x. lift(f(x)$i))`,
3586 REPEAT GEN_TAC THEN REWRITE_TAC[linear] THEN
3587 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [CART_EQ] THEN
3588 SIMP_TAC[GSYM LIFT_CMUL; GSYM LIFT_ADD; LIFT_EQ] THEN
3589 REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
3592 (* ------------------------------------------------------------------------- *)
3593 (* Pasting vectors. *)
3594 (* ------------------------------------------------------------------------- *)
3596 let LINEAR_FSTCART = prove
3598 SIMP_TAC[linear; fstcart; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
3599 VECTOR_MUL_COMPONENT; DIMINDEX_FINITE_SUM;
3600 ARITH_RULE `x <= a ==> x <= a + b:num`]);;
3602 let LINEAR_SNDCART = prove
3604 SIMP_TAC[linear; sndcart; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
3605 VECTOR_MUL_COMPONENT; DIMINDEX_FINITE_SUM;
3606 ARITH_RULE `x <= a ==> x <= a + b:num`;
3607 ARITH_RULE `x <= b ==> x + a <= a + b:num`]);;
3609 let FSTCART_VEC = prove
3610 (`!n. fstcart(vec n) = vec n`,
3611 SIMP_TAC[vec; fstcart; LAMBDA_BETA; CART_EQ; DIMINDEX_FINITE_SUM;
3612 ARITH_RULE `m <= n:num ==> m <= n + p`]);;
3614 let FSTCART_ADD = prove
3615 (`!x:real^(M,N)finite_sum y. fstcart(x + y) = fstcart(x) + fstcart(y)`,
3616 REWRITE_TAC[REWRITE_RULE[linear] LINEAR_FSTCART]);;
3618 let FSTCART_CMUL = prove
3619 (`!x:real^(M,N)finite_sum c. fstcart(c % x) = c % fstcart(x)`,
3620 REWRITE_TAC[REWRITE_RULE[linear] LINEAR_FSTCART]);;
3622 let FSTCART_NEG = prove
3623 (`!x:real^(M,N)finite_sum. --(fstcart x) = fstcart(--x)`,
3624 ONCE_REWRITE_TAC[VECTOR_ARITH `--x = --(&1) % x`] THEN
3625 REWRITE_TAC[FSTCART_CMUL]);;
3627 let FSTCART_SUB = prove
3628 (`!x:real^(M,N)finite_sum y. fstcart(x - y) = fstcart(x) - fstcart(y)`,
3629 REWRITE_TAC[VECTOR_SUB; FSTCART_NEG; FSTCART_ADD]);;
3631 let FSTCART_VSUM = prove
3632 (`!k x. FINITE k ==> (fstcart(vsum k x) = vsum k (\i. fstcart(x i)))`,
3633 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
3634 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3635 SIMP_TAC[VSUM_CLAUSES; FINITE_RULES; FSTCART_ADD; FSTCART_VEC]);;
3637 let SNDCART_VEC = prove
3638 (`!n. sndcart(vec n) = vec n`,
3639 SIMP_TAC[vec; sndcart; LAMBDA_BETA; CART_EQ; DIMINDEX_FINITE_SUM;
3640 ARITH_RULE `x <= a ==> x <= a + b:num`;
3641 ARITH_RULE `x <= b ==> x + a <= a + b:num`]);;
3643 let SNDCART_ADD = prove
3644 (`!x:real^(M,N)finite_sum y. sndcart(x + y) = sndcart(x) + sndcart(y)`,
3645 REWRITE_TAC[REWRITE_RULE[linear] LINEAR_SNDCART]);;
3647 let SNDCART_CMUL = prove
3648 (`!x:real^(M,N)finite_sum c. sndcart(c % x) = c % sndcart(x)`,
3649 REWRITE_TAC[REWRITE_RULE[linear] LINEAR_SNDCART]);;
3651 let SNDCART_NEG = prove
3652 (`!x:real^(M,N)finite_sum. --(sndcart x) = sndcart(--x)`,
3653 ONCE_REWRITE_TAC[VECTOR_ARITH `--x = --(&1) % x`] THEN
3654 REWRITE_TAC[SNDCART_CMUL]);;
3656 let SNDCART_SUB = prove
3657 (`!x:real^(M,N)finite_sum y. sndcart(x - y) = sndcart(x) - sndcart(y)`,
3658 REWRITE_TAC[VECTOR_SUB; SNDCART_NEG; SNDCART_ADD]);;
3660 let SNDCART_VSUM = prove
3661 (`!k x. FINITE k ==> (sndcart(vsum k x) = vsum k (\i. sndcart(x i)))`,
3662 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
3663 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3664 SIMP_TAC[VSUM_CLAUSES; FINITE_RULES; SNDCART_ADD; SNDCART_VEC]);;
3666 let PASTECART_VEC = prove
3667 (`!n. pastecart (vec n) (vec n) = vec n`,
3668 REWRITE_TAC[PASTECART_EQ; FSTCART_VEC; SNDCART_VEC;
3669 FSTCART_PASTECART; SNDCART_PASTECART]);;
3671 let PASTECART_ADD = prove
3672 (`!x1 y1 x2:real^M y2:real^N.
3673 pastecart x1 y1 + pastecart x2 y2 = pastecart (x1 + x2) (y1 + y2)`,
3674 REWRITE_TAC[PASTECART_EQ; FSTCART_ADD; SNDCART_ADD;
3675 FSTCART_PASTECART; SNDCART_PASTECART]);;
3677 let PASTECART_CMUL = prove
3678 (`!x1 y1 c. pastecart (c % x1) (c % y1) = c % pastecart x1 y1`,
3679 REWRITE_TAC[PASTECART_EQ; FSTCART_CMUL; SNDCART_CMUL;
3680 FSTCART_PASTECART; SNDCART_PASTECART]);;
3682 let PASTECART_NEG = prove
3683 (`!x:real^M y:real^N. pastecart (--x) (--y) = --(pastecart x y)`,
3684 ONCE_REWRITE_TAC[VECTOR_ARITH `--x = --(&1) % x`] THEN
3685 REWRITE_TAC[PASTECART_CMUL]);;
3687 let PASTECART_SUB = prove
3688 (`!x1 y1 x2:real^M y2:real^N.
3689 pastecart x1 y1 - pastecart x2 y2 = pastecart (x1 - x2) (y1 - y2)`,
3690 REWRITE_TAC[VECTOR_SUB; GSYM PASTECART_NEG; PASTECART_ADD]);;
3692 let PASTECART_VSUM = prove
3693 (`!k x y. FINITE k ==> (pastecart (vsum k x) (vsum k y) =
3694 vsum k (\i. pastecart (x i) (y i)))`,
3695 SIMP_TAC[PASTECART_EQ; FSTCART_VSUM; SNDCART_VSUM;
3696 FSTCART_PASTECART; SNDCART_PASTECART; ETA_AX]);;
3698 let PASTECART_EQ_VEC = prove
3699 (`!x y n. pastecart x y = vec n <=> x = vec n /\ y = vec n`,
3700 REWRITE_TAC[PASTECART_EQ; FSTCART_VEC; SNDCART_VEC;
3701 FSTCART_PASTECART; SNDCART_PASTECART]);;
3703 let NORM_FSTCART = prove
3704 (`!x. norm(fstcart x) <= norm x`,
3706 GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM PASTECART_FST_SND] THEN
3707 SIMP_TAC[SQRT_MONO_LE_EQ; DOT_POS_LE; vector_norm] THEN
3708 SIMP_TAC[pastecart; dot; DIMINDEX_FINITE_SUM; LAMBDA_BETA; DIMINDEX_NONZERO;
3709 SUM_ADD_SPLIT; REAL_LE_ADDR; SUM_POS_LE; FINITE_NUMSEG;
3710 REAL_LE_SQUARE; ARITH_RULE `x <= a ==> x <= a + b:num`;
3711 ARITH_RULE `~(d = 0) ==> 1 <= d + 1`]);;
3713 let DIST_FSTCART = prove
3714 (`!x y. dist(fstcart x,fstcart y) <= dist(x,y)`,
3715 REWRITE_TAC[dist; GSYM FSTCART_SUB; NORM_FSTCART]);;
3717 let NORM_SNDCART = prove
3718 (`!x. norm(sndcart x) <= norm x`,
3720 GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM PASTECART_FST_SND] THEN
3721 SIMP_TAC[SQRT_MONO_LE_EQ; DOT_POS_LE; vector_norm] THEN
3722 SIMP_TAC[pastecart; dot; DIMINDEX_FINITE_SUM; LAMBDA_BETA; DIMINDEX_NONZERO;
3723 SUM_ADD_SPLIT; ARITH_RULE `x <= a ==> x <= a + b:num`;
3724 ARITH_RULE `~(d = 0) ==> 1 <= d + 1`] THEN
3725 ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[NUMSEG_OFFSET_IMAGE] THEN
3726 SIMP_TAC[SUM_IMAGE; FINITE_NUMSEG; EQ_ADD_RCANCEL; o_DEF; ADD_SUB] THEN
3727 SIMP_TAC[ARITH_RULE `1 <= x ==> ~(x + a <= a)`; SUM_POS_LE; FINITE_NUMSEG;
3728 REAL_LE_ADDL; REAL_LE_SQUARE]);;
3730 let DIST_SNDCART = prove
3731 (`!x y. dist(sndcart x,sndcart y) <= dist(x,y)`,
3732 REWRITE_TAC[dist; GSYM SNDCART_SUB; NORM_SNDCART]);;
3734 let DOT_PASTECART = prove
3735 (`!x1 x2 y1 y2. (pastecart x1 x2) dot (pastecart y1 y2) =
3736 x1 dot y1 + x2 dot y2`,
3737 SIMP_TAC[pastecart; dot; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN
3738 SIMP_TAC[SUM_ADD_SPLIT; ARITH_RULE `~(d = 0) ==> 1 <= d + 1`;
3739 DIMINDEX_NONZERO; REAL_LE_LADD] THEN
3740 ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[NUMSEG_OFFSET_IMAGE] THEN
3741 SIMP_TAC[SUM_IMAGE; FINITE_NUMSEG; EQ_ADD_RCANCEL; o_DEF; ADD_SUB] THEN
3742 SIMP_TAC[ARITH_RULE `1 <= x ==> ~(x + a <= a)`; REAL_LE_REFL]);;
3744 let SQNORM_PASTECART = prove
3745 (`!x y. norm(pastecart x y) pow 2 = norm(x) pow 2 + norm(y) pow 2`,
3746 REWRITE_TAC[NORM_POW_2; DOT_PASTECART]);;
3748 let NORM_PASTECART = prove
3749 (`!x y. norm(pastecart x y) = sqrt(norm(x) pow 2 + norm(y) pow 2)`,
3750 REWRITE_TAC[NORM_EQ_SQUARE] THEN
3751 SIMP_TAC[SQRT_POS_LE; SQRT_POW_2; REAL_LE_ADD; REAL_LE_POW_2] THEN
3752 REWRITE_TAC[DOT_PASTECART; NORM_POW_2]);;
3754 let NORM_PASTECART_LE = prove
3755 (`!x y. norm(pastecart x y) <= norm(x) + norm(y)`,
3756 REPEAT GEN_TAC THEN MATCH_MP_TAC TRIANGLE_LEMMA THEN
3757 REWRITE_TAC[NORM_POS_LE; NORM_POW_2; DOT_PASTECART; REAL_LE_REFL]);;
3759 let NORM_LE_PASTECART = prove
3760 (`!x:real^M y:real^N.
3761 norm(x) <= norm(pastecart x y) /\
3762 norm(y) <= norm(pastecart x y)`,
3763 REPEAT GEN_TAC THEN REWRITE_TAC[NORM_PASTECART] THEN CONJ_TAC THEN
3764 MATCH_MP_TAC REAL_LE_RSQRT THEN
3765 REWRITE_TAC[REAL_LE_ADDL; REAL_LE_ADDR; REAL_LE_POW_2]);;
3767 let NORM_PASTECART_0 = prove
3768 (`(!x. norm(pastecart x (vec 0)) = norm x) /\
3769 (!y. norm(pastecart (vec 0) y) = norm y)`,
3770 REWRITE_TAC[NORM_EQ_SQUARE; NORM_POW_2; NORM_POS_LE] THEN
3771 REWRITE_TAC[DOT_PASTECART; DOT_LZERO; REAL_ADD_LID; REAL_ADD_RID]);;
3773 let DIST_PASTECART_CANCEL = prove
3774 (`(!x x' y. dist(pastecart x y,pastecart x' y) = dist(x,x')) /\
3775 (!x y y'. dist(pastecart x y,pastecart x y') = dist(y,y'))`,
3776 REWRITE_TAC[dist; PASTECART_SUB; VECTOR_SUB_REFL; NORM_PASTECART_0]);;
3778 let LINEAR_PASTECART = prove
3779 (`!f:real^M->real^N g:real^M->real^P.
3780 linear f /\ linear g ==> linear (\x. pastecart (f x) (g x))`,
3781 SIMP_TAC[linear; PASTECART_ADD; GSYM PASTECART_CMUL]);;
3783 (* ------------------------------------------------------------------------- *)
3784 (* A bit of linear algebra. *)
3785 (* ------------------------------------------------------------------------- *)
3787 let subspace = new_definition
3790 (!x y. x IN s /\ y IN s ==> (x + y) IN s) /\
3791 (!c x. x IN s ==> (c % x) IN s)`;;
3793 let span = new_definition
3794 `span s = subspace hull s`;;
3796 let dependent = new_definition
3797 `dependent s <=> ?a. a IN s /\ a IN span(s DELETE a)`;;
3799 let independent = new_definition
3800 `independent s <=> ~(dependent s)`;;
3802 (* ------------------------------------------------------------------------- *)
3803 (* Closure properties of subspaces. *)
3804 (* ------------------------------------------------------------------------- *)
3806 let SUBSPACE_UNIV = prove
3807 (`subspace(UNIV:real^N->bool)`,
3808 REWRITE_TAC[subspace; IN_UNIV]);;
3810 let SUBSPACE_IMP_NONEMPTY = prove
3811 (`!s. subspace s ==> ~(s = {})`,
3812 REWRITE_TAC[subspace] THEN SET_TAC[]);;
3814 let SUBSPACE_0 = prove
3815 (`subspace s ==> vec(0) IN s`,
3816 SIMP_TAC[subspace]);;
3818 let SUBSPACE_ADD = prove
3819 (`!x y s. subspace s /\ x IN s /\ y IN s ==> (x + y) IN s`,
3820 SIMP_TAC[subspace]);;
3822 let SUBSPACE_MUL = prove
3823 (`!x c s. subspace s /\ x IN s ==> (c % x) IN s`,
3824 SIMP_TAC[subspace]);;
3826 let SUBSPACE_NEG = prove
3827 (`!x s. subspace s /\ x IN s ==> (--x) IN s`,
3828 SIMP_TAC[VECTOR_ARITH `--x = --(&1) % x`; SUBSPACE_MUL]);;
3830 let SUBSPACE_SUB = prove
3831 (`!x y s. subspace s /\ x IN s /\ y IN s ==> (x - y) IN s`,
3832 SIMP_TAC[VECTOR_SUB; SUBSPACE_ADD; SUBSPACE_NEG]);;
3834 let SUBSPACE_VSUM = prove
3835 (`!s f t. subspace s /\ FINITE t /\ (!x. x IN t ==> f(x) IN s)
3836 ==> (vsum t f) IN s`,
3837 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
3838 GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
3839 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3840 ASM_SIMP_TAC[VSUM_CLAUSES; SUBSPACE_0; IN_INSERT; SUBSPACE_ADD]);;
3842 let SUBSPACE_LINEAR_IMAGE = prove
3843 (`!f s. linear f /\ subspace s ==> subspace(IMAGE f s)`,
3844 REWRITE_TAC[subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
3845 REWRITE_TAC[FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN
3846 MESON_TAC[linear; LINEAR_0]);;
3848 let SUBSPACE_LINEAR_PREIMAGE = prove
3849 (`!f s. linear f /\ subspace s ==> subspace {x | f(x) IN s}`,
3850 REWRITE_TAC[subspace; IN_ELIM_THM] THEN
3851 MESON_TAC[linear; LINEAR_0]);;
3853 let SUBSPACE_TRIVIAL = prove
3854 (`subspace {vec 0}`,
3855 SIMP_TAC[subspace; IN_SING] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
3857 let SUBSPACE_INTER = prove
3858 (`!s t. subspace s /\ subspace t ==> subspace (s INTER t)`,
3859 REWRITE_TAC[subspace; IN_INTER] THEN MESON_TAC[]);;
3861 let SUBSPACE_INTERS = prove
3862 (`!f. (!s. s IN f ==> subspace s) ==> subspace(INTERS f)`,
3863 SIMP_TAC[subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM; IN_INTERS]);;
3865 let LINEAR_INJECTIVE_0_SUBSPACE = prove
3866 (`!f:real^M->real^N s.
3867 linear f /\ subspace s
3868 ==> ((!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) <=>
3869 (!x. x IN s /\ f x = vec 0 ==> x = vec 0))`,
3870 REPEAT STRIP_TAC THEN
3871 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM VECTOR_SUB_EQ] THEN
3872 ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN
3873 ASM_MESON_TAC[VECTOR_SUB_RZERO; SUBSPACE_SUB; SUBSPACE_0]);;
3875 let SUBSPACE_UNION_CHAIN = prove
3876 (`!s t:real^N->bool.
3877 subspace s /\ subspace t /\ subspace(s UNION t)
3878 ==> s SUBSET t \/ t SUBSET s`,
3879 REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE
3880 `s SUBSET t \/ t SUBSET s <=>
3881 ~(?x y. x IN s /\ ~(x IN t) /\ y IN t /\ ~(y IN s))`] THEN
3882 STRIP_TAC THEN SUBGOAL_THEN `(x + y:real^N) IN s UNION t` MP_TAC THENL
3883 [MATCH_MP_TAC SUBSPACE_ADD THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
3884 REWRITE_TAC[IN_UNION; DE_MORGAN_THM] THEN
3885 ASM_MESON_TAC[SUBSPACE_SUB; VECTOR_ARITH
3886 `(x + y) - x:real^N = y /\ (x + y) - y = x`]]);;
3888 let SUBSPACE_PCROSS = prove
3889 (`!s:real^M->bool t:real^N->bool.
3890 subspace s /\ subspace t ==> subspace(s PCROSS t)`,
3891 REWRITE_TAC[subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
3892 REWRITE_TAC[FORALL_IN_PCROSS; GSYM PASTECART_CMUL; PASTECART_ADD] THEN
3893 REWRITE_TAC[GSYM PASTECART_VEC; PASTECART_IN_PCROSS] THEN SIMP_TAC[]);;
3895 let SUBSPACE_PCROSS_EQ = prove
3896 (`!s:real^M->bool t:real^N->bool.
3897 subspace(s PCROSS t) <=> subspace s /\ subspace t`,
3899 ASM_CASES_TAC `s:real^M->bool = {}` THENL
3900 [ASM_MESON_TAC[PCROSS_EMPTY; SUBSPACE_IMP_NONEMPTY]; ALL_TAC] THEN
3901 ASM_CASES_TAC `t:real^N->bool = {}` THENL
3902 [ASM_MESON_TAC[PCROSS_EMPTY; SUBSPACE_IMP_NONEMPTY]; ALL_TAC] THEN
3903 EQ_TAC THEN REWRITE_TAC[SUBSPACE_PCROSS] THEN REPEAT STRIP_TAC THENL
3904 [MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`;
3905 `(s:real^M->bool) PCROSS (t:real^N->bool)`] SUBSPACE_LINEAR_IMAGE) THEN
3906 ASM_REWRITE_TAC[LINEAR_FSTCART];
3907 MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`;
3908 `(s:real^M->bool) PCROSS (t:real^N->bool)`] SUBSPACE_LINEAR_IMAGE) THEN
3909 ASM_REWRITE_TAC[LINEAR_SNDCART]] THEN
3910 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
3911 REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; PASTECART_IN_PCROSS;
3912 FSTCART_PASTECART; SNDCART_PASTECART] THEN
3915 (* ------------------------------------------------------------------------- *)
3917 (* ------------------------------------------------------------------------- *)
3919 let SPAN_SPAN = prove
3920 (`!s. span(span s) = span s`,
3921 REWRITE_TAC[span; HULL_HULL]);;
3923 let SPAN_MONO = prove
3924 (`!s t. s SUBSET t ==> span s SUBSET span t`,
3925 REWRITE_TAC[span; HULL_MONO]);;
3927 let SUBSPACE_SPAN = prove
3928 (`!s. subspace(span s)`,
3929 GEN_TAC THEN REWRITE_TAC[span] THEN MATCH_MP_TAC P_HULL THEN
3930 SIMP_TAC[subspace; IN_INTERS]);;
3932 let SPAN_CLAUSES = prove
3933 (`(!a s. a IN s ==> a IN span s) /\
3934 (vec(0) IN span s) /\
3935 (!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s) /\
3936 (!x c s. x IN span s ==> (c % x) IN span s)`,
3937 MESON_TAC[span; HULL_SUBSET; SUBSET; SUBSPACE_SPAN; subspace]);;
3939 let SPAN_INDUCT = prove
3940 (`!s h. (!x. x IN s ==> x IN h) /\ subspace h ==> !x. x IN span(s) ==> h(x)`,
3941 REWRITE_TAC[span] THEN MESON_TAC[SUBSET; HULL_MINIMAL; IN]);;
3943 let SPAN_EMPTY = prove
3944 (`span {} = {vec 0}`,
3945 REWRITE_TAC[span] THEN MATCH_MP_TAC HULL_UNIQUE THEN
3946 SIMP_TAC[subspace; SUBSET; IN_SING; NOT_IN_EMPTY] THEN
3947 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
3949 let INDEPENDENT_EMPTY = prove
3951 REWRITE_TAC[independent; dependent; NOT_IN_EMPTY]);;
3953 let INDEPENDENT_NONZERO = prove
3954 (`!s. independent s ==> ~(vec 0 IN s)`,
3955 REWRITE_TAC[independent; dependent] THEN MESON_TAC[SPAN_CLAUSES]);;
3957 let INDEPENDENT_MONO = prove
3958 (`!s t. independent t /\ s SUBSET t ==> independent s`,
3959 REWRITE_TAC[independent; dependent] THEN
3960 ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_DELETE]);;
3962 let DEPENDENT_MONO = prove
3963 (`!s t:real^N->bool. dependent s /\ s SUBSET t ==> dependent t`,
3964 ONCE_REWRITE_TAC[TAUT `p /\ q ==> r <=> ~r /\ q ==> ~p`] THEN
3965 REWRITE_TAC[GSYM independent; INDEPENDENT_MONO]);;
3967 let SPAN_SUBSPACE = prove
3968 (`!b s. b SUBSET s /\ s SUBSET (span b) /\ subspace s ==> (span b = s)`,
3969 MESON_TAC[SUBSET_ANTISYM; span; HULL_MINIMAL]);;
3971 let SPAN_INDUCT_ALT = prove
3973 (!c x y. x IN s /\ h(y) ==> h(c % x + y))
3974 ==> !x:real^N. x IN span(s) ==> h(x)`,
3975 REPEAT GEN_TAC THEN DISCH_TAC THEN
3976 FIRST_ASSUM(MP_TAC o prove_inductive_relations_exist o concl) THEN
3977 DISCH_THEN(X_CHOOSE_THEN `g:real^N->bool` STRIP_ASSUME_TAC) THEN
3978 SUBGOAL_THEN `!x:real^N. x IN span(s) ==> g(x)`
3979 (fun th -> ASM_MESON_TAC[th]) THEN
3980 MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[subspace; IN_ELIM_THM] THEN
3981 REWRITE_TAC[IN; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
3982 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
3983 REPEAT CONJ_TAC THEN TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN
3984 REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC] THEN
3985 ASM_MESON_TAC[IN; VECTOR_ADD_LID; VECTOR_ADD_ASSOC; VECTOR_ADD_SYM;
3986 VECTOR_MUL_LID; VECTOR_MUL_RZERO]);;
3988 (* ------------------------------------------------------------------------- *)
3989 (* Individual closure properties. *)
3990 (* ------------------------------------------------------------------------- *)
3992 let SPAN_SUPERSET = prove
3993 (`!x. x IN s ==> x IN span s`,
3994 MESON_TAC[SPAN_CLAUSES]);;
3996 let SPAN_INC = prove
3997 (`!s. s SUBSET span s`,
3998 REWRITE_TAC[SUBSET; SPAN_SUPERSET]);;
4000 let SPAN_UNION_SUBSET = prove
4001 (`!s t. span s UNION span t SUBSET span(s UNION t)`,
4002 REWRITE_TAC[span; HULL_UNION_SUBSET]);;
4004 let SPAN_UNIV = prove
4005 (`span(:real^N) = (:real^N)`,
4006 SIMP_TAC[SPAN_INC; SET_RULE `UNIV SUBSET s ==> s = UNIV`]);;
4009 (`vec(0) IN span s`,
4010 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_0]);;
4012 let SPAN_ADD = prove
4013 (`!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s`,
4014 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_ADD]);;
4016 let SPAN_MUL = prove
4017 (`!x c s. x IN span s ==> (c % x) IN span s`,
4018 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_MUL]);;
4020 let SPAN_MUL_EQ = prove
4021 (`!x:real^N c s. ~(c = &0) ==> ((c % x) IN span s <=> x IN span s)`,
4022 REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN ASM_SIMP_TAC[SPAN_MUL] THEN
4023 SUBGOAL_THEN `(inv(c) % c % x:real^N) IN span s` MP_TAC THENL
4024 [ASM_SIMP_TAC[SPAN_MUL];
4025 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID]]);;
4027 let SPAN_NEG = prove
4028 (`!x s. x IN span s ==> (--x) IN span s`,
4029 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_NEG]);;
4031 let SPAN_NEG_EQ = prove
4032 (`!x s. --x IN span s <=> x IN span s`,
4033 MESON_TAC[SPAN_NEG; VECTOR_NEG_NEG]);;
4035 let SPAN_SUB = prove
4036 (`!x y s. x IN span s /\ y IN span s ==> (x - y) IN span s`,
4037 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_SUB]);;
4039 let SPAN_VSUM = prove
4040 (`!s f t. FINITE t /\ (!x. x IN t ==> f(x) IN span(s))
4041 ==> (vsum t f) IN span(s)`,
4042 MESON_TAC[SUBSPACE_SPAN; SUBSPACE_VSUM]);;
4044 let SPAN_ADD_EQ = prove
4045 (`!s x y. x IN span s ==> ((x + y) IN span s <=> y IN span s)`,
4046 MESON_TAC[SPAN_ADD; SPAN_SUB; VECTOR_ARITH `(x + y) - x:real^N = y`]);;
4048 let SPAN_EQ_SELF = prove
4049 (`!s. span s = s <=> subspace s`,
4050 GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSPACE_SPAN]; ALL_TAC] THEN
4051 DISCH_TAC THEN MATCH_MP_TAC SPAN_SUBSPACE THEN
4052 ASM_REWRITE_TAC[SUBSET_REFL; SPAN_INC]);;
4054 let SPAN_OF_SUBSPACE = prove
4055 (`!s:real^N->bool. subspace s ==> span s = s`,
4056 REWRITE_TAC[SPAN_EQ_SELF]);;
4058 let SPAN_SUBSET_SUBSPACE = prove
4059 (`!s t:real^N->bool. s SUBSET t /\ subspace t ==> span s SUBSET t`,
4060 MESON_TAC[SPAN_MONO; SPAN_EQ_SELF]);;
4062 let SUBSPACE_TRANSLATION_SELF = prove
4063 (`!s a. subspace s /\ a IN s ==> IMAGE (\x. a + x) s = s`,
4064 REPEAT STRIP_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
4065 FIRST_ASSUM(SUBST1_TAC o SYM o GEN_REWRITE_RULE I [GSYM SPAN_EQ_SELF]) THEN
4066 ASM_SIMP_TAC[SPAN_ADD_EQ; SPAN_CLAUSES] THEN
4067 REWRITE_TAC[VECTOR_ARITH `a + x:real^N = y <=> x = y - a`; EXISTS_REFL]);;
4069 let SUBSPACE_TRANSLATION_SELF_EQ = prove
4070 (`!s a:real^N. subspace s ==> (IMAGE (\x. a + x) s = s <=> a IN s)`,
4071 REPEAT STRIP_TAC THEN EQ_TAC THEN
4072 ASM_SIMP_TAC[SUBSPACE_TRANSLATION_SELF] THEN
4073 DISCH_THEN(MP_TAC o AP_TERM `\s. (a:real^N) IN s`) THEN
4074 REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
4075 REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `vec 0:real^N` THEN
4076 ASM_MESON_TAC[subspace; VECTOR_ADD_RID]);;
4078 let SUBSPACE_SUMS = prove
4079 (`!s t. subspace s /\ subspace t
4080 ==> subspace {x + y | x IN s /\ y IN t}`,
4081 REWRITE_TAC[subspace; FORALL_IN_GSPEC; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
4082 REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THENL
4083 [ASM_MESON_TAC[VECTOR_ADD_LID];
4084 ONCE_REWRITE_TAC[VECTOR_ARITH
4085 `(x + y) + (x' + y'):real^N = (x + x') + (y + y')`] THEN
4087 REWRITE_TAC[VECTOR_ADD_LDISTRIB] THEN ASM_MESON_TAC[]]);;
4089 let SPAN_UNION = prove
4090 (`!s t. span(s UNION t) = {x + y:real^N | x IN span s /\ y IN span t}`,
4091 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
4092 [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
4093 SIMP_TAC[SUBSPACE_SUMS; SUBSPACE_SPAN] THEN
4094 REWRITE_TAC[SUBSET; IN_UNION; IN_ELIM_THM] THEN
4095 X_GEN_TAC `x:real^N` THEN STRIP_TAC THENL
4096 [MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN
4097 ASM_SIMP_TAC[SPAN_SUPERSET; SPAN_0; VECTOR_ADD_RID];
4098 MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `x:real^N`] THEN
4099 ASM_SIMP_TAC[SPAN_SUPERSET; SPAN_0; VECTOR_ADD_LID]];
4100 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
4101 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_ADD THEN
4102 ASM_MESON_TAC[SPAN_MONO; SUBSET_UNION; SUBSET]]);;
4104 (* ------------------------------------------------------------------------- *)
4105 (* Mapping under linear image. *)
4106 (* ------------------------------------------------------------------------- *)
4108 let SPAN_LINEAR_IMAGE = prove
4109 (`!f:real^M->real^N s. linear f ==> (span(IMAGE f s) = IMAGE f (span s))`,
4110 REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
4111 X_GEN_TAC `x:real^N` THEN EQ_TAC THENL
4112 [SPEC_TAC(`x:real^N`,`x:real^N`) THEN MATCH_MP_TAC SPAN_INDUCT THEN
4113 REWRITE_TAC[SET_RULE `(\x. x IN s) = s`] THEN
4114 ASM_SIMP_TAC[SUBSPACE_SPAN; SUBSPACE_LINEAR_IMAGE] THEN
4115 REWRITE_TAC[FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN
4116 MESON_TAC[SPAN_SUPERSET; SUBSET];
4117 SPEC_TAC(`x:real^N`,`x:real^N`) THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN
4118 MATCH_MP_TAC SPAN_INDUCT THEN
4119 REWRITE_TAC[SET_RULE `(\x. f x IN span(s)) = {x | f(x) IN span s}`] THEN
4120 ASM_SIMP_TAC[SUBSPACE_LINEAR_PREIMAGE; SUBSPACE_SPAN] THEN
4121 REWRITE_TAC[IN_ELIM_THM] THEN
4122 MESON_TAC[SPAN_SUPERSET; SUBSET; IN_IMAGE]]);;
4124 let DEPENDENT_LINEAR_IMAGE_EQ = prove
4125 (`!f:real^M->real^N s.
4126 linear f /\ (!x y. f x = f y ==> x = y)
4127 ==> (dependent(IMAGE f s) <=> dependent s)`,
4128 REPEAT STRIP_TAC THEN REWRITE_TAC[dependent; EXISTS_IN_IMAGE] THEN
4129 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `a:real^M` THEN
4130 ASM_CASES_TAC `(a:real^M) IN s` THEN ASM_REWRITE_TAC[] THEN
4131 MATCH_MP_TAC EQ_TRANS THEN
4132 EXISTS_TAC `(f:real^M->real^N) a IN span(IMAGE f (s DELETE a))` THEN
4134 [AP_TERM_TAC THEN AP_TERM_TAC THEN ASM SET_TAC[];
4135 ASM_SIMP_TAC[SPAN_LINEAR_IMAGE] THEN ASM SET_TAC[]]);;
4137 let DEPENDENT_LINEAR_IMAGE = prove
4138 (`!f:real^M->real^N s.
4139 linear f /\ (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\
4141 ==> dependent(IMAGE f s)`,
4143 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4144 REWRITE_TAC[dependent; EXISTS_IN_IMAGE] THEN
4145 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^M` THEN
4146 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4147 SUBGOAL_THEN `IMAGE (f:real^M->real^N) s DELETE f a = IMAGE f (s DELETE a)`
4148 (fun th -> ASM_SIMP_TAC[FUN_IN_IMAGE; SPAN_LINEAR_IMAGE; th]) THEN
4151 let INDEPENDENT_LINEAR_IMAGE_EQ = prove
4152 (`!f:real^M->real^N s.
4153 linear f /\ (!x y. f x = f y ==> x = y)
4154 ==> (independent(IMAGE f s) <=> independent s)`,
4155 REWRITE_TAC[independent; TAUT `(~p <=> ~q) <=> (p <=> q)`] THEN
4156 REWRITE_TAC[DEPENDENT_LINEAR_IMAGE_EQ]);;
4158 (* ------------------------------------------------------------------------- *)
4159 (* The key breakdown property. *)
4160 (* ------------------------------------------------------------------------- *)
4162 let SPAN_BREAKDOWN = prove
4164 b IN s /\ a IN span s ==> ?k. (a - k % b) IN span(s DELETE b)`,
4165 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
4166 REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN
4167 REWRITE_TAC[subspace; IN_ELIM_THM] THEN CONJ_TAC THENL
4168 [GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC `a:real^N = b`; ALL_TAC] THEN
4169 ASM_MESON_TAC[SPAN_CLAUSES; IN_DELETE; VECTOR_ARITH
4170 `(a - &1 % a = vec 0) /\ (a - &0 % b = a) /\
4171 ((x + y) - (k1 + k2) % b = (x - k1 % b) + (y - k2 % b)) /\
4172 (c % x - (c * k) % y = c % (x - k % y))`]);;
4174 let SPAN_BREAKDOWN_EQ = prove
4175 (`!a:real^N s. (x IN span(a INSERT s) <=> (?k. (x - k % a) IN span s))`,
4176 REPEAT STRIP_TAC THEN EQ_TAC THENL
4177 [DISCH_THEN(MP_TAC o CONJ(SET_RULE `(a:real^N) IN (a INSERT s)`)) THEN
4178 DISCH_THEN(MP_TAC o MATCH_MP SPAN_BREAKDOWN) THEN
4179 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real` THEN
4180 SPEC_TAC(`x - k % a:real^N`,`y:real^N`) THEN
4181 REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SPAN_MONO THEN SET_TAC[];
4182 DISCH_THEN(X_CHOOSE_TAC `k:real`) THEN
4183 SUBST1_TAC(VECTOR_ARITH `x = (x - k % a) + k % a:real^N`) THEN
4184 MATCH_MP_TAC SPAN_ADD THEN
4185 ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_INSERT; SPAN_CLAUSES]]);;
4187 let SPAN_INSERT_0 = prove
4188 (`!s. span(vec 0 INSERT s) = span s`,
4189 SIMP_TAC[EXTENSION; SPAN_BREAKDOWN_EQ; VECTOR_MUL_RZERO; VECTOR_SUB_RZERO]);;
4191 let SPAN_SING = prove
4192 (`!a. span {a} = {u % a | u IN (:real)}`,
4193 REWRITE_TAC[EXTENSION; IN_ELIM_THM; SPAN_BREAKDOWN_EQ; SPAN_EMPTY] THEN
4194 REWRITE_TAC[IN_UNIV; IN_SING; VECTOR_SUB_EQ]);;
4197 (`!a b. span {a,b} = {u % a + v % b | u IN (:real) /\ v IN (:real)}`,
4198 REWRITE_TAC[EXTENSION; IN_ELIM_THM; SPAN_BREAKDOWN_EQ; SPAN_EMPTY] THEN
4199 REWRITE_TAC[IN_UNIV; IN_SING; VECTOR_SUB_EQ] THEN
4200 REWRITE_TAC[VECTOR_ARITH `x - y:real^N = z <=> x = y + z`]);;
4203 (`!a b c. span {a,b,c} =
4204 {u % a + v % b + w % c | u IN (:real) /\ v IN (:real) /\ w IN (:real)}`,
4205 REWRITE_TAC[EXTENSION; IN_ELIM_THM; SPAN_BREAKDOWN_EQ; SPAN_EMPTY] THEN
4206 REWRITE_TAC[IN_UNIV; IN_SING; VECTOR_SUB_EQ] THEN
4207 REWRITE_TAC[VECTOR_ARITH `x - y:real^N = z <=> x = y + z`]);;
4209 (* ------------------------------------------------------------------------- *)
4210 (* Hence some "reversal" results. *)
4211 (* ------------------------------------------------------------------------- *)
4213 let IN_SPAN_INSERT = prove
4215 a IN span(b INSERT s) /\ ~(a IN span s) ==> b IN span(a INSERT s)`,
4216 REPEAT STRIP_TAC THEN
4217 MP_TAC(ISPECL [`b:real^N`; `(b:real^N) INSERT s`; `a:real^N`]
4218 SPAN_BREAKDOWN) THEN ASM_REWRITE_TAC[IN_INSERT] THEN
4219 DISCH_THEN(X_CHOOSE_THEN `k:real` MP_TAC) THEN ASM_CASES_TAC `k = &0` THEN
4220 ASM_REWRITE_TAC[VECTOR_ARITH `a - &0 % b = a`; DELETE_INSERT] THENL
4221 [ASM_MESON_TAC[SPAN_MONO; SUBSET; DELETE_SUBSET]; ALL_TAC] THEN
4222 DISCH_THEN(MP_TAC o SPEC `inv(k)` o MATCH_MP SPAN_MUL) THEN
4223 ASM_SIMP_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_ASSOC; REAL_MUL_LINV] THEN
4224 DISCH_TAC THEN SUBST1_TAC(VECTOR_ARITH
4225 `b:real^N = inv(k) % a - (inv(k) % a - &1 % b)`) THEN
4226 MATCH_MP_TAC SPAN_SUB THEN
4227 ASM_MESON_TAC[SPAN_CLAUSES; IN_INSERT; SUBSET; IN_DELETE; SPAN_MONO]);;
4229 let IN_SPAN_DELETE = prove
4231 a IN span s /\ ~(a IN span (s DELETE b))
4232 ==> b IN span (a INSERT (s DELETE b))`,
4233 ASM_MESON_TAC[IN_SPAN_INSERT; SPAN_MONO; SUBSET; IN_INSERT; IN_DELETE]);;
4235 let EQ_SPAN_INSERT_EQ = prove
4236 (`!s x y:real^N. (x - y) IN span s ==> span(x INSERT s) = span(y INSERT s)`,
4237 REPEAT STRIP_TAC THEN REWRITE_TAC[SPAN_BREAKDOWN_EQ; EXTENSION] THEN
4238 ASM_MESON_TAC[SPAN_ADD; SPAN_SUB; SPAN_MUL;
4239 VECTOR_ARITH `(z - k % y) - k % (x - y) = z - k % x`;
4240 VECTOR_ARITH `(z - k % x) + k % (x - y) = z - k % y`]);;
4242 (* ------------------------------------------------------------------------- *)
4243 (* Transitivity property. *)
4244 (* ------------------------------------------------------------------------- *)
4246 let SPAN_TRANS = prove
4247 (`!x y:real^N s. x IN span(s) /\ y IN span(x INSERT s) ==> y IN span(s)`,
4248 REPEAT STRIP_TAC THEN
4249 MP_TAC(SPECL [`x:real^N`; `(x:real^N) INSERT s`; `y:real^N`]
4250 SPAN_BREAKDOWN) THEN
4251 ASM_REWRITE_TAC[IN_INSERT] THEN
4252 DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
4253 SUBST1_TAC(VECTOR_ARITH `y:real^N = (y - k % x) + k % x`) THEN
4254 MATCH_MP_TAC SPAN_ADD THEN ASM_SIMP_TAC[SPAN_MUL] THEN
4255 ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_INSERT; IN_DELETE]);;
4257 (* ------------------------------------------------------------------------- *)
4258 (* An explicit expansion is sometimes needed. *)
4259 (* ------------------------------------------------------------------------- *)
4261 let SPAN_EXPLICIT = prove
4262 (`!(p:real^N -> bool).
4264 {y | ?s u. FINITE s /\ s SUBSET p /\
4265 vsum s (\v. u v % v) = y}`,
4266 GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
4268 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
4269 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
4270 MATCH_MP_TAC SPAN_VSUM THEN ASM_REWRITE_TAC[] THEN
4271 ASM_MESON_TAC[SPAN_SUPERSET; SPAN_MUL]] THEN
4272 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
4273 MATCH_MP_TAC SPAN_INDUCT_ALT THEN CONJ_TAC THENL
4274 [EXISTS_TAC `{}:real^N->bool` THEN
4275 REWRITE_TAC[FINITE_RULES; VSUM_CLAUSES; EMPTY_SUBSET; NOT_IN_EMPTY];
4277 MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`; `y:real^N`] THEN
4278 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4279 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
4280 MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `u:real^N->real`] THEN
4281 STRIP_TAC THEN EXISTS_TAC `(x:real^N) INSERT s` THEN
4282 EXISTS_TAC `\y. if y = x then (if x IN s then (u:real^N->real) y + c else c)
4284 ASM_SIMP_TAC[FINITE_INSERT; IN_INSERT; VSUM_CLAUSES] THEN
4285 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
4286 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
4287 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
4288 [FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE
4289 `x IN s ==> s = x INSERT (s DELETE x)`)) THEN
4290 ASM_SIMP_TAC[VSUM_CLAUSES; FINITE_INSERT; FINITE_DELETE; IN_DELETE] THEN
4291 MATCH_MP_TAC(VECTOR_ARITH
4292 `y = z ==> (c + d) % x + y = d % x + c % x + z`);
4294 MATCH_MP_TAC VSUM_EQ THEN ASM_MESON_TAC[IN_DELETE]);;
4296 let DEPENDENT_EXPLICIT = prove
4297 (`!p. dependent (p:real^N -> bool) <=>
4298 ?s u. FINITE s /\ s SUBSET p /\
4299 (?v. v IN s /\ ~(u v = &0)) /\
4300 vsum s (\v. u v % v) = vec 0`,
4301 GEN_TAC THEN REWRITE_TAC[dependent; SPAN_EXPLICIT; IN_ELIM_THM] THEN
4302 REWRITE_TAC[RIGHT_AND_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
4303 EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
4304 [MAP_EVERY X_GEN_TAC [`a:real^N`; `s:real^N->bool`; `u:real^N->real`] THEN
4305 STRIP_TAC THEN MAP_EVERY EXISTS_TAC
4306 [`(a:real^N) INSERT s`;
4307 `\y. if y = a then -- &1 else (u:real^N->real) y`;
4309 ASM_REWRITE_TAC[IN_INSERT; INSERT_SUBSET; FINITE_INSERT] THEN
4310 CONJ_TAC THENL [ASM SET_TAC[]; CONV_TAC REAL_RAT_REDUCE_CONV] THEN
4311 ASM_SIMP_TAC[VSUM_CLAUSES] THEN
4312 COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4313 REWRITE_TAC[VECTOR_ARITH `-- &1 % a + s = vec 0 <=> a = s`] THEN
4314 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [SYM th]) THEN
4315 MATCH_MP_TAC VSUM_EQ THEN ASM SET_TAC[];
4316 MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `u:real^N->real`; `a:real^N`] THEN
4317 STRIP_TAC THEN MAP_EVERY EXISTS_TAC
4318 [`a:real^N`; `s DELETE (a:real^N)`;
4319 `\i. --((u:real^N->real) i) / (u a)`] THEN
4320 ASM_SIMP_TAC[VSUM_DELETE; FINITE_DELETE] THEN
4321 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
4322 REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
4323 ASM_REWRITE_TAC[VECTOR_MUL_LNEG; GSYM VECTOR_MUL_ASSOC; VSUM_LMUL;
4324 VSUM_NEG; VECTOR_MUL_RNEG; VECTOR_MUL_RZERO] THEN
4325 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV] THEN VECTOR_ARITH_TAC]);;
4327 let DEPENDENT_FINITE = prove
4330 ==> (dependent s <=> ?u. (?v. v IN s /\ ~(u v = &0)) /\
4331 vsum s (\v. u(v) % v) = vec 0)`,
4332 REPEAT STRIP_TAC THEN REWRITE_TAC[DEPENDENT_EXPLICIT] THEN EQ_TAC THEN
4333 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
4334 [MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN
4335 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
4336 EXISTS_TAC `\v:real^N. if v IN t then u(v) else &0` THEN
4337 REWRITE_TAC[] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4338 ONCE_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN
4339 ASM_SIMP_TAC[VECTOR_MUL_LZERO; GSYM VSUM_RESTRICT_SET] THEN
4340 ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`];
4341 GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
4342 MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `u:real^N->real`] THEN
4343 ASM_REWRITE_TAC[SUBSET_REFL]]);;
4345 let SPAN_FINITE = prove
4347 FINITE s ==> span s = {y | ?u. vsum s (\v. u v % v) = y}`,
4348 REPEAT STRIP_TAC THEN REWRITE_TAC[SPAN_EXPLICIT; EXTENSION; IN_ELIM_THM] THEN
4349 X_GEN_TAC `y:real^N` THEN EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
4350 [MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN
4351 STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
4352 EXISTS_TAC `\x:real^N. if x IN t then u(x) else &0` THEN
4353 REWRITE_TAC[COND_RAND; COND_RATOR; VECTOR_MUL_LZERO] THEN
4354 ASM_SIMP_TAC[GSYM VSUM_RESTRICT_SET] THEN
4355 ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> {x | x IN s /\ x IN t} = t`];
4356 X_GEN_TAC `u:real^N->real` THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
4357 MAP_EVERY EXISTS_TAC [`s:real^N->bool`; `u:real^N->real`] THEN
4358 ASM_REWRITE_TAC[SUBSET_REFL]]);;
4360 (* ------------------------------------------------------------------------- *)
4361 (* Standard bases are a spanning set, and obviously finite. *)
4362 (* ------------------------------------------------------------------------- *)
4364 let SPAN_STDBASIS = prove
4365 (`span {basis i :real^N | 1 <= i /\ i <= dimindex(:N)} = UNIV`,
4366 REWRITE_TAC[EXTENSION; IN_UNIV] THEN X_GEN_TAC `x:real^N` THEN
4367 GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN
4368 MATCH_MP_TAC SPAN_VSUM THEN SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
4369 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
4370 MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN
4373 let HAS_SIZE_STDBASIS = prove
4374 (`{basis i :real^N | 1 <= i /\ i <= dimindex(:N)} HAS_SIZE
4376 ONCE_REWRITE_TAC[SET_RULE `{f x | P x} = IMAGE f {x | P x}`] THEN
4377 MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN
4378 REWRITE_TAC[GSYM numseg; HAS_SIZE_NUMSEG_1; IN_NUMSEG] THEN
4379 MESON_TAC[BASIS_INJ]);;
4381 let FINITE_STDBASIS = prove
4382 (`FINITE {basis i :real^N | 1 <= i /\ i <= dimindex(:N)}`,
4383 MESON_TAC[HAS_SIZE_STDBASIS; HAS_SIZE]);;
4385 let CARD_STDBASIS = prove
4386 (`CARD {basis i :real^N | 1 <= i /\ i <= dimindex(:N)} =
4388 MESON_TAC[HAS_SIZE_STDBASIS; HAS_SIZE]);;
4390 let IN_SPAN_IMAGE_BASIS = prove
4392 x IN span(IMAGE basis s) <=>
4393 !i. 1 <= i /\ i <= dimindex(:N) /\ ~(i IN s) ==> x$i = &0`,
4394 REPEAT GEN_TAC THEN EQ_TAC THENL
4395 [SPEC_TAC(`x:real^N`,`x:real^N`) THEN MATCH_MP_TAC SPAN_INDUCT THEN
4396 SIMP_TAC[subspace; IN_ELIM_THM; VEC_COMPONENT; VECTOR_ADD_COMPONENT;
4397 VECTOR_MUL_COMPONENT; REAL_MUL_RZERO; REAL_ADD_RID] THEN
4398 SIMP_TAC[FORALL_IN_IMAGE; BASIS_COMPONENT] THEN MESON_TAC[];
4399 DISCH_TAC THEN REWRITE_TAC[SPAN_EXPLICIT; IN_ELIM_THM] THEN
4400 EXISTS_TAC `(IMAGE basis ((1..dimindex(:N)) INTER s)):real^N->bool` THEN
4401 SIMP_TAC[FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN
4402 REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
4403 CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
4404 EXISTS_TAC `\v:real^N. x dot v` THEN
4405 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN
4407 [SIMP_TAC[FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN
4408 REWRITE_TAC[IN_INTER; IN_NUMSEG] THEN MESON_TAC[BASIS_INJ];
4409 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[]] THEN
4410 REWRITE_TAC[o_DEF] THEN
4411 SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_MUL_COMPONENT;
4412 BASIS_COMPONENT] THEN
4413 ONCE_REWRITE_TAC[COND_RAND] THEN
4414 ONCE_REWRITE_TAC[MESON[]
4415 `(if x = y then p else q) = (if y = x then p else q)`] THEN
4416 SIMP_TAC[SUM_DELTA; REAL_MUL_RZERO; IN_INTER; IN_NUMSEG; DOT_BASIS] THEN
4417 ASM_MESON_TAC[REAL_MUL_RID]]);;
4419 let INDEPENDENT_STDBASIS = prove
4420 (`independent {basis i :real^N | 1 <= i /\ i <= dimindex(:N)}`,
4421 REWRITE_TAC[independent; dependent] THEN
4422 ONCE_REWRITE_TAC[SET_RULE `{f x | P x} = IMAGE f {x | P x}`] THEN
4423 REWRITE_TAC[EXISTS_IN_IMAGE] THEN REWRITE_TAC[IN_ELIM_THM] THEN
4424 DISCH_THEN(X_CHOOSE_THEN `k:num` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4426 `IMAGE basis {i | 1 <= i /\ i <= dimindex(:N)} DELETE
4428 IMAGE basis ({i | 1 <= i /\ i <= dimindex(:N)} DELETE k)`
4430 [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DELETE; IN_ELIM_THM] THEN
4431 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4432 ASM_MESON_TAC[BASIS_INJ];
4434 REWRITE_TAC[IN_SPAN_IMAGE_BASIS] THEN DISCH_THEN(MP_TAC o SPEC `k:num`) THEN
4435 ASM_SIMP_TAC[IN_DELETE; BASIS_COMPONENT; REAL_OF_NUM_EQ; ARITH]);;
4437 (* ------------------------------------------------------------------------- *)
4438 (* This is useful for building a basis step-by-step. *)
4439 (* ------------------------------------------------------------------------- *)
4441 let INDEPENDENT_INSERT = prove
4442 (`!a:real^N s. independent(a INSERT s) <=>
4443 if a IN s then independent s
4444 else independent s /\ ~(a IN span s)`,
4445 REPEAT GEN_TAC THEN ASM_CASES_TAC `(a:real^N) IN s` THEN
4446 ASM_SIMP_TAC[SET_RULE `x IN s ==> (x INSERT s = s)`] THEN
4448 [DISCH_TAC THEN CONJ_TAC THENL
4449 [ASM_MESON_TAC[INDEPENDENT_MONO; SUBSET; IN_INSERT];
4450 POP_ASSUM MP_TAC THEN REWRITE_TAC[independent; dependent] THEN
4451 ASM_MESON_TAC[IN_INSERT; SET_RULE
4452 `~(a IN s) ==> ((a INSERT s) DELETE a = s)`]];
4454 REWRITE_TAC[independent; dependent; NOT_EXISTS_THM] THEN
4455 STRIP_TAC THEN X_GEN_TAC `b:real^N` THEN
4456 REWRITE_TAC[IN_INSERT] THEN ASM_CASES_TAC `b:real^N = a` THEN
4457 ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> ((a INSERT s) DELETE a = s)`] THEN
4458 ASM_SIMP_TAC[SET_RULE
4459 `~(a IN s) /\ ~(b = a)
4460 ==> ((a INSERT s) DELETE b = a INSERT (s DELETE b))`] THEN
4461 ASM_MESON_TAC[IN_SPAN_INSERT; SET_RULE
4462 `b IN s ==> (b INSERT (s DELETE b) = s)`]);;
4464 (* ------------------------------------------------------------------------- *)
4465 (* The degenerate case of the Exchange Lemma. *)
4466 (* ------------------------------------------------------------------------- *)
4468 let SPANNING_SUBSET_INDEPENDENT = prove
4469 (`!s t:real^N->bool.
4470 t SUBSET s /\ independent s /\ s SUBSET span(t) ==> (s = t)`,
4471 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
4472 ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET] THEN
4473 X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN
4474 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [independent]) THEN
4475 REWRITE_TAC[dependent; NOT_EXISTS_THM] THEN
4476 DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM_REWRITE_TAC[] THEN
4477 ASM_MESON_TAC[SPAN_MONO; SUBSET; IN_DELETE]);;
4479 (* ------------------------------------------------------------------------- *)
4480 (* The general case of the Exchange Lemma, the key to what follows. *)
4481 (* ------------------------------------------------------------------------- *)
4483 let EXCHANGE_LEMMA = prove
4484 (`!s t:real^N->bool.
4485 FINITE t /\ independent s /\ s SUBSET span t
4486 ==> ?t'. t' HAS_SIZE (CARD t) /\
4487 s SUBSET t' /\ t' SUBSET (s UNION t) /\ s SUBSET (span t')`,
4489 WF_INDUCT_TAC `CARD(t DIFF s :real^N->bool)` THEN
4490 ASM_CASES_TAC `(s:real^N->bool) SUBSET t` THENL
4491 [ASM_MESON_TAC[HAS_SIZE; SUBSET_UNION]; ALL_TAC] THEN
4492 ASM_CASES_TAC `t SUBSET (s:real^N->bool)` THENL
4493 [ASM_MESON_TAC[SPANNING_SUBSET_INDEPENDENT; HAS_SIZE]; ALL_TAC] THEN
4495 FIRST_X_ASSUM(MP_TAC o REWRITE_RULE[SUBSET] o check(is_neg o concl)) THEN
4496 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
4497 DISCH_THEN(X_CHOOSE_THEN `b:real^N` STRIP_ASSUME_TAC) THEN
4498 ASM_CASES_TAC `s SUBSET span(t DELETE (b:real^N))` THENL
4499 [FIRST_X_ASSUM(MP_TAC o
4500 SPECL [`t DELETE (b:real^N)`; `s:real^N->bool`]) THEN
4501 ASM_REWRITE_TAC[SET_RULE `s DELETE a DIFF t = (s DIFF t) DELETE a`] THEN
4502 ASM_SIMP_TAC[CARD_DELETE; FINITE_DIFF; IN_DIFF; FINITE_DELETE;
4503 CARD_EQ_0; ARITH_RULE `n - 1 < n <=> ~(n = 0)`] THEN
4505 [UNDISCH_TAC `~((s:real^N->bool) SUBSET t)` THEN ASM SET_TAC[];
4507 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
4508 EXISTS_TAC `(b:real^N) INSERT u` THEN
4509 ASM_SIMP_TAC[SUBSET_INSERT; INSERT_SUBSET; IN_UNION] THEN CONJ_TAC THENL
4510 [UNDISCH_TAC `(u:real^N->bool) HAS_SIZE CARD(t:real^N->bool) - 1` THEN
4511 SIMP_TAC[HAS_SIZE; FINITE_RULES; CARD_CLAUSES] THEN STRIP_TAC THEN
4512 COND_CASES_TAC THENL
4513 [ASM_MESON_TAC[SUBSET; IN_UNION; IN_DELETE]; ALL_TAC] THEN
4514 ASM_MESON_TAC[ARITH_RULE `~(n = 0) ==> (SUC(n - 1) = n)`;
4515 CARD_EQ_0; MEMBER_NOT_EMPTY];
4518 [UNDISCH_TAC `u SUBSET s UNION t DELETE (b:real^N)` THEN SET_TAC[];
4519 ASM_MESON_TAC[SUBSET; SPAN_MONO; IN_INSERT]];
4521 UNDISCH_TAC `~(s SUBSET span (t DELETE (b:real^N)))` THEN
4522 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SUBSET] THEN
4523 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
4524 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
4525 SUBGOAL_THEN `~(a:real^N = b)` ASSUME_TAC THENL
4526 [ASM_MESON_TAC[]; ALL_TAC] THEN
4527 SUBGOAL_THEN `~((a:real^N) IN t)` ASSUME_TAC THENL
4528 [ASM_MESON_TAC[IN_DELETE; SPAN_CLAUSES]; ALL_TAC] THEN
4529 FIRST_X_ASSUM(MP_TAC o SPECL
4530 [`(a:real^N) INSERT (t DELETE b)`; `s:real^N->bool`]) THEN
4532 [ASM_SIMP_TAC[SET_RULE
4533 `a IN s ==> ((a INSERT (t DELETE b) DIFF s) = (t DIFF s) DELETE b)`] THEN
4534 ASM_SIMP_TAC[CARD_DELETE; FINITE_DELETE; FINITE_DIFF; IN_DIFF] THEN
4535 ASM_SIMP_TAC[ARITH_RULE `n - 1 < n <=> ~(n = 0)`; CARD_EQ_0;
4537 UNDISCH_TAC `~((s:real^N->bool) SUBSET t)` THEN ASM SET_TAC[];
4540 [ASM_SIMP_TAC[FINITE_RULES; FINITE_DELETE] THEN
4541 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN
4542 DISCH_TAC THEN MATCH_MP_TAC SPAN_TRANS THEN EXISTS_TAC `b:real^N` THEN
4543 ASM_MESON_TAC[IN_SPAN_DELETE; SUBSET; SPAN_MONO;
4544 SET_RULE `t SUBSET (b INSERT (a INSERT (t DELETE b)))`];
4546 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `u:real^N->bool` THEN
4547 ASM_SIMP_TAC[HAS_SIZE; CARD_CLAUSES; CARD_DELETE; FINITE_DELETE; IN_DELETE;
4548 ARITH_RULE `(SUC(n - 1) = n) <=> ~(n = 0)`;
4550 UNDISCH_TAC `(b:real^N) IN t` THEN ASM SET_TAC[]);;
4552 (* ------------------------------------------------------------------------- *)
4553 (* This implies corresponding size bounds. *)
4554 (* ------------------------------------------------------------------------- *)
4556 let INDEPENDENT_SPAN_BOUND = prove
4557 (`!s t. FINITE t /\ independent s /\ s SUBSET span(t)
4558 ==> FINITE s /\ CARD(s) <= CARD(t)`,
4559 REPEAT GEN_TAC THEN DISCH_TAC THEN
4560 FIRST_ASSUM(MP_TAC o MATCH_MP EXCHANGE_LEMMA) THEN
4561 ASM_MESON_TAC[HAS_SIZE; CARD_SUBSET; FINITE_SUBSET]);;
4563 let INDEPENDENT_BOUND = prove
4565 independent s ==> FINITE s /\ CARD(s) <= dimindex(:N)`,
4566 REPEAT GEN_TAC THEN DISCH_TAC THEN
4567 ONCE_REWRITE_TAC[GSYM CARD_STDBASIS] THEN
4568 MATCH_MP_TAC INDEPENDENT_SPAN_BOUND THEN
4569 ASM_REWRITE_TAC[FINITE_STDBASIS; SPAN_STDBASIS; SUBSET_UNIV]);;
4571 let DEPENDENT_BIGGERSET = prove
4572 (`!s:real^N->bool. (FINITE s ==> CARD(s) > dimindex(:N)) ==> dependent s`,
4573 MP_TAC INDEPENDENT_BOUND THEN MATCH_MP_TAC MONO_FORALL THEN
4574 REWRITE_TAC[GT; GSYM NOT_LE; independent] THEN MESON_TAC[]);;
4576 let INDEPENDENT_IMP_FINITE = prove
4577 (`!s:real^N->bool. independent s ==> FINITE s`,
4578 SIMP_TAC[INDEPENDENT_BOUND]);;
4580 (* ------------------------------------------------------------------------- *)
4581 (* Explicit formulation of independence. *)
4582 (* ------------------------------------------------------------------------- *)
4584 let INDEPENDENT_EXPLICIT = prove
4588 !c. vsum b (\v. c(v) % v) = vec 0 ==> !v. v IN b ==> c(v) = &0`,
4590 ASM_CASES_TAC `FINITE(b:real^N->bool)` THENL
4591 [ALL_TAC; ASM_MESON_TAC[INDEPENDENT_BOUND]] THEN
4592 ASM_SIMP_TAC[independent; DEPENDENT_FINITE] THEN MESON_TAC[]);;
4594 let INDEPENDENT_SING = prove
4595 (`!x. independent {x} <=> ~(x = vec 0)`,
4596 REWRITE_TAC[INDEPENDENT_INSERT; NOT_IN_EMPTY; SPAN_EMPTY] THEN
4597 REWRITE_TAC[INDEPENDENT_EMPTY] THEN SET_TAC[]);;
4599 let DEPENDENT_SING = prove
4600 (`!x. dependent {x} <=> x = vec 0`,
4601 MESON_TAC[independent; INDEPENDENT_SING]);;
4603 let DEPENDENT_2 = prove
4606 if a = b then a = vec 0
4607 else ?x y. x % a + y % b = vec 0 /\ ~(x = &0 /\ y = &0)`,
4608 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
4609 ASM_REWRITE_TAC[DEPENDENT_SING; SET_RULE `{x,x} = {x}`] THEN
4610 SIMP_TAC[DEPENDENT_FINITE; VSUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN
4611 ASM_REWRITE_TAC[IN_SING; NOT_IN_EMPTY; VECTOR_ADD_RID; EXISTS_IN_INSERT] THEN
4612 EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
4613 [X_GEN_TAC `u:real^N->real` THEN STRIP_TAC THEN
4614 MAP_EVERY EXISTS_TAC [`(u:real^N->real) a`; `(u:real^N->real) b`] THEN
4616 MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN DISCH_TAC THEN EXISTS_TAC
4617 `\v:real^N. if v = a then x else if v = b then y else z:real` THEN
4620 let DEPENDENT_3 = prove
4622 ~(a = b) /\ ~(a = c) /\ ~(b = c)
4623 ==> (dependent {a,b,c} <=>
4624 ?x y z. x % a + y % b + z % c = vec 0 /\
4625 ~(x = &0 /\ y = &0 /\ z = &0))`,
4626 REPEAT STRIP_TAC THEN
4627 SIMP_TAC[DEPENDENT_FINITE; VSUM_CLAUSES; FINITE_INSERT; FINITE_EMPTY] THEN
4628 ASM_REWRITE_TAC[IN_SING; NOT_IN_EMPTY; VECTOR_ADD_RID; IN_INSERT] THEN
4629 EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
4630 [X_GEN_TAC `u:real^N->real` THEN STRIP_TAC THEN MAP_EVERY EXISTS_TAC
4631 [`(u:real^N->real) a`; `(u:real^N->real) b`; `(u:real^N->real) c`];
4632 MAP_EVERY X_GEN_TAC [`x:real`; `y:real`; `z:real`] THEN DISCH_TAC THEN
4634 `\v:real^N. if v = a then x else if v = b then y else z:real`] THEN
4637 let INDEPENDENT_2 = prove
4639 independent{a,b} /\ ~(a = b)
4640 ==> (x % a + y % b = vec 0 <=> x = &0 /\ y = &0)`,
4641 SIMP_TAC[IMP_CONJ_ALT; independent; DEPENDENT_2] THEN
4642 MESON_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID]);;
4644 let INDEPENDENT_3 = prove
4645 (`!a b c:real^N x y z.
4646 independent{a,b,c} /\ ~(a = b) /\ ~(a = c) /\ ~(b = c)
4647 ==> (x % a + y % b + z % c = vec 0 <=> x = &0 /\ y = &0 /\ z = &0)`,
4648 SIMP_TAC[IMP_CONJ_ALT; independent; DEPENDENT_3] THEN
4649 MESON_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID]);;
4651 (* ------------------------------------------------------------------------- *)
4652 (* Hence we can create a maximal independent subset. *)
4653 (* ------------------------------------------------------------------------- *)
4655 let MAXIMAL_INDEPENDENT_SUBSET_EXTEND = prove
4656 (`!s v:real^N->bool.
4657 s SUBSET v /\ independent s
4658 ==> ?b. s SUBSET b /\ b SUBSET v /\ independent b /\
4661 WF_INDUCT_TAC `dimindex(:N) - CARD(s:real^N->bool)` THEN
4662 REPEAT STRIP_TAC THEN
4663 ASM_CASES_TAC `v SUBSET (span(s:real^N->bool))` THENL
4664 [ASM_MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN
4665 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [SUBSET]) THEN
4666 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
4667 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
4668 FIRST_X_ASSUM(MP_TAC o SPEC `(a:real^N) INSERT s`) THEN
4669 REWRITE_TAC[IMP_IMP] THEN ANTS_TAC THENL
4670 [ALL_TAC; MESON_TAC[INSERT_SUBSET]] THEN
4671 SUBGOAL_THEN `independent ((a:real^N) INSERT s)` ASSUME_TAC THENL
4672 [ASM_REWRITE_TAC[INDEPENDENT_INSERT; COND_ID]; ALL_TAC] THEN
4673 ASM_REWRITE_TAC[INSERT_SUBSET] THEN
4674 MATCH_MP_TAC(ARITH_RULE `(b = a + 1) /\ b <= n ==> n - b < n - a`) THEN
4675 ASM_SIMP_TAC[CARD_CLAUSES; INDEPENDENT_BOUND] THEN
4676 ASM_MESON_TAC[SPAN_SUPERSET; ADD1]);;
4678 let MAXIMAL_INDEPENDENT_SUBSET = prove
4679 (`!v:real^N->bool. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b)`,
4680 MP_TAC(SPEC `EMPTY:real^N->bool` MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
4681 REWRITE_TAC[EMPTY_SUBSET; INDEPENDENT_EMPTY]);;
4683 (* ------------------------------------------------------------------------- *)
4684 (* A kind of closed graph property for linearity. *)
4685 (* ------------------------------------------------------------------------- *)
4687 let LINEAR_SUBSPACE_GRAPH = prove
4688 (`!f:real^M->real^N.
4689 linear f <=> subspace {pastecart x (f x) | x IN (:real^M)}`,
4690 REWRITE_TAC[linear; subspace; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
4691 REWRITE_TAC[FORALL_IN_GSPEC; GSYM(SPEC `0` PASTECART_VEC); IN_UNIV] THEN
4692 REWRITE_TAC[IN_ELIM_THM; PASTECART_INJ; UNWIND_THM1; PASTECART_ADD;
4693 GSYM PASTECART_CMUL] THEN
4694 MESON_TAC[VECTOR_MUL_LZERO]);;
4696 (* ------------------------------------------------------------------------- *)
4697 (* Notion of dimension. *)
4698 (* ------------------------------------------------------------------------- *)
4700 let dim = new_definition
4701 `dim v = @n. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\
4704 let BASIS_EXISTS = prove
4705 (`!v. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\
4706 b HAS_SIZE (dim v)`,
4707 GEN_TAC THEN REWRITE_TAC[dim] THEN CONV_TAC SELECT_CONV THEN
4708 MESON_TAC[MAXIMAL_INDEPENDENT_SUBSET; HAS_SIZE; INDEPENDENT_BOUND]);;
4710 let BASIS_EXISTS_FINITE = prove
4711 (`!v. ?b. FINITE b /\
4714 v SUBSET (span b) /\
4715 b HAS_SIZE (dim v)`,
4716 MESON_TAC[BASIS_EXISTS; INDEPENDENT_IMP_FINITE]);;
4718 let BASIS_SUBSPACE_EXISTS = prove
4726 REPEAT STRIP_TAC THEN
4727 MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN
4728 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN
4729 ASM_REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN
4730 ASM_MESON_TAC[SPAN_EQ_SELF; SPAN_MONO; INDEPENDENT_IMP_FINITE]);;
4732 (* ------------------------------------------------------------------------- *)
4733 (* Consequences of independence or spanning for cardinality. *)
4734 (* ------------------------------------------------------------------------- *)
4736 let INDEPENDENT_CARD_LE_DIM = prove
4737 (`!v b:real^N->bool.
4738 b SUBSET v /\ independent b ==> FINITE b /\ CARD(b) <= dim v`,
4739 MESON_TAC[BASIS_EXISTS; INDEPENDENT_SPAN_BOUND; HAS_SIZE;SUBSET_TRANS]);;
4741 let SPAN_CARD_GE_DIM = prove
4742 (`!v b:real^N->bool.
4743 v SUBSET (span b) /\ FINITE b ==> dim(v) <= CARD(b)`,
4744 MESON_TAC[BASIS_EXISTS; INDEPENDENT_SPAN_BOUND; HAS_SIZE;SUBSET_TRANS]);;
4746 let BASIS_CARD_EQ_DIM = prove
4747 (`!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b
4748 ==> FINITE b /\ (CARD b = dim v)`,
4749 MESON_TAC[LE_ANTISYM; INDEPENDENT_CARD_LE_DIM; SPAN_CARD_GE_DIM]);;
4751 let BASIS_HAS_SIZE_DIM = prove
4752 (`!v b. independent b /\ span b = v ==> b HAS_SIZE (dim v)`,
4753 REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_SIZE] THEN
4754 MATCH_MP_TAC BASIS_CARD_EQ_DIM THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN
4755 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[SPAN_INC]);;
4757 let DIM_UNIQUE = prove
4758 (`!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b /\ b HAS_SIZE n
4760 MESON_TAC[BASIS_CARD_EQ_DIM; HAS_SIZE]);;
4762 let DIM_LE_CARD = prove
4763 (`!s. FINITE s ==> dim s <= CARD s`,
4764 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN
4765 ASM_REWRITE_TAC[SPAN_INC; SUBSET_REFL]);;
4767 (* ------------------------------------------------------------------------- *)
4768 (* More lemmas about dimension. *)
4769 (* ------------------------------------------------------------------------- *)
4771 let DIM_UNIV = prove
4772 (`dim(:real^N) = dimindex(:N)`,
4773 MATCH_MP_TAC DIM_UNIQUE THEN
4774 EXISTS_TAC `{basis i :real^N | 1 <= i /\ i <= dimindex(:N)}` THEN
4775 REWRITE_TAC[SUBSET_UNIV; SPAN_STDBASIS; HAS_SIZE_STDBASIS;
4776 INDEPENDENT_STDBASIS]);;
4778 let DIM_SUBSET = prove
4779 (`!s t:real^N->bool. s SUBSET t ==> dim(s) <= dim(t)`,
4780 MESON_TAC[BASIS_EXISTS; INDEPENDENT_SPAN_BOUND; SUBSET; HAS_SIZE]);;
4782 let DIM_SUBSET_UNIV = prove
4783 (`!s:real^N->bool. dim(s) <= dimindex(:N)`,
4784 GEN_TAC THEN REWRITE_TAC[GSYM DIM_UNIV] THEN
4785 MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]);;
4787 let BASIS_HAS_SIZE_UNIV = prove
4788 (`!b. independent b /\ span b = (:real^N) ==> b HAS_SIZE (dimindex(:N))`,
4789 REWRITE_TAC[GSYM DIM_UNIV; BASIS_HAS_SIZE_DIM]);;
4791 (* ------------------------------------------------------------------------- *)
4792 (* Converses to those. *)
4793 (* ------------------------------------------------------------------------- *)
4795 let CARD_GE_DIM_INDEPENDENT = prove
4796 (`!v b:real^N->bool.
4797 b SUBSET v /\ independent b /\ dim v <= CARD(b)
4798 ==> v SUBSET (span b)`,
4799 REPEAT STRIP_TAC THEN
4800 SUBGOAL_THEN `!a:real^N. ~(a IN v /\ ~(a IN span b))` MP_TAC THENL
4801 [ALL_TAC; SET_TAC[]] THEN
4802 X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN
4803 SUBGOAL_THEN `independent((a:real^N) INSERT b)` ASSUME_TAC THENL
4804 [ASM_MESON_TAC[INDEPENDENT_INSERT]; ALL_TAC] THEN
4805 MP_TAC(ISPECL [`v:real^N->bool`; `(a:real^N) INSERT b`]
4806 INDEPENDENT_CARD_LE_DIM) THEN
4807 ASM_SIMP_TAC[INSERT_SUBSET; CARD_CLAUSES; INDEPENDENT_BOUND] THEN
4808 ASM_MESON_TAC[SPAN_SUPERSET; SUBSET; ARITH_RULE
4809 `x <= y ==> ~(SUC y <= x)`]);;
4811 let CARD_LE_DIM_SPANNING = prove
4812 (`!v b:real^N->bool.
4813 v SUBSET (span b) /\ FINITE b /\ CARD(b) <= dim v
4815 REPEAT STRIP_TAC THEN REWRITE_TAC[independent; dependent] THEN
4816 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
4817 SUBGOAL_THEN `dim(v:real^N->bool) <= CARD(b DELETE (a:real^N))` MP_TAC THENL
4819 ASM_SIMP_TAC[CARD_DELETE] THEN MATCH_MP_TAC
4820 (ARITH_RULE `b <= n /\ ~(b = 0) ==> ~(n <= b - 1)`) THEN
4821 ASM_SIMP_TAC[CARD_EQ_0] THEN ASM_MESON_TAC[MEMBER_NOT_EMPTY]] THEN
4822 MATCH_MP_TAC SPAN_CARD_GE_DIM THEN ASM_SIMP_TAC[FINITE_DELETE] THEN
4823 REWRITE_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN
4824 MATCH_MP_TAC SPAN_TRANS THEN EXISTS_TAC `a:real^N` THEN
4825 ASM_SIMP_TAC[SET_RULE `a IN b ==> (a INSERT (b DELETE a) = b)`] THEN
4826 ASM_MESON_TAC[SUBSET]);;
4828 let CARD_EQ_DIM = prove
4829 (`!v b. b SUBSET v /\ b HAS_SIZE (dim v)
4830 ==> (independent b <=> v SUBSET (span b))`,
4831 REWRITE_TAC[HAS_SIZE; GSYM LE_ANTISYM] THEN
4832 MESON_TAC[CARD_LE_DIM_SPANNING; CARD_GE_DIM_INDEPENDENT]);;
4834 (* ------------------------------------------------------------------------- *)
4835 (* More general size bound lemmas. *)
4836 (* ------------------------------------------------------------------------- *)
4838 let INDEPENDENT_BOUND_GENERAL = prove
4839 (`!s:real^N->bool. independent s ==> FINITE s /\ CARD(s) <= dim(s)`,
4840 MESON_TAC[INDEPENDENT_CARD_LE_DIM; INDEPENDENT_BOUND; SUBSET_REFL]);;
4842 let DEPENDENT_BIGGERSET_GENERAL = prove
4843 (`!s:real^N->bool. (FINITE s ==> CARD(s) > dim(s)) ==> dependent s`,
4844 MP_TAC INDEPENDENT_BOUND_GENERAL THEN MATCH_MP_TAC MONO_FORALL THEN
4845 REWRITE_TAC[GT; GSYM NOT_LE; independent] THEN MESON_TAC[]);;
4847 let DIM_SPAN = prove
4848 (`!s:real^N->bool. dim(span s) = dim s`,
4849 GEN_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THENL
4851 MATCH_MP_TAC DIM_SUBSET THEN MESON_TAC[SUBSET; SPAN_SUPERSET]] THEN
4852 MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN
4853 REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN
4854 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
4855 MATCH_MP_TAC SPAN_CARD_GE_DIM THEN ASM_REWRITE_TAC[] THEN
4856 GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_SPAN] THEN
4857 MATCH_MP_TAC SPAN_MONO THEN ASM_REWRITE_TAC[]);;
4859 let DIM_INSERT_0 = prove
4860 (`!s:real^N->bool. dim(vec 0 INSERT s) = dim s`,
4861 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
4862 REWRITE_TAC[SPAN_INSERT_0]);;
4864 let DIM_EQ_CARD = prove
4865 (`!s:real^N->bool. independent s ==> dim s = CARD s`,
4866 REPEAT STRIP_TAC THEN MP_TAC
4867 (ISPECL [`span s:real^N->bool`; `s:real^N->bool`] BASIS_CARD_EQ_DIM) THEN
4868 ASM_SIMP_TAC[SUBSET_REFL; SPAN_INC; DIM_SPAN]);;
4870 let SUBSET_LE_DIM = prove
4871 (`!s t:real^N->bool. s SUBSET (span t) ==> dim s <= dim t`,
4872 MESON_TAC[DIM_SPAN; DIM_SUBSET]);;
4874 let SPAN_EQ_DIM = prove
4875 (`!s t. span s = span t ==> dim s = dim t`,
4876 MESON_TAC[DIM_SPAN]);;
4878 let SPANS_IMAGE = prove
4879 (`!f b v. linear f /\ v SUBSET (span b)
4880 ==> (IMAGE f v) SUBSET span(IMAGE f b)`,
4881 SIMP_TAC[SPAN_LINEAR_IMAGE; IMAGE_SUBSET]);;
4883 let DIM_LINEAR_IMAGE_LE = prove
4884 (`!f:real^M->real^N s. linear f ==> dim(IMAGE f s) <= dim s`,
4885 REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^M->bool` BASIS_EXISTS) THEN
4886 REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN FIRST_ASSUM(SUBST1_TAC o SYM) THEN
4887 MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD(IMAGE (f:real^M->real^N) b)` THEN
4888 ASM_SIMP_TAC[CARD_IMAGE_LE] THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN
4889 ASM_MESON_TAC[SPAN_LINEAR_IMAGE; SPANS_IMAGE; SUBSET_IMAGE; FINITE_IMAGE]);;
4891 (* ------------------------------------------------------------------------- *)
4892 (* Some stepping theorems. *)
4893 (* ------------------------------------------------------------------------- *)
4895 let DIM_EMPTY = prove
4896 (`dim({}:real^N->bool) = 0`,
4897 MATCH_MP_TAC DIM_UNIQUE THEN EXISTS_TAC `{}:real^N->bool` THEN
4898 REWRITE_TAC[SUBSET_REFL; SPAN_EMPTY; INDEPENDENT_EMPTY; HAS_SIZE_0;
4901 let DIM_INSERT = prove
4902 (`!x:real^N s. dim(x INSERT s) = if x IN span s then dim s else dim s + 1`,
4903 REPEAT GEN_TAC THEN COND_CASES_TAC THENL
4904 [MATCH_MP_TAC SPAN_EQ_DIM THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
4905 ASM_MESON_TAC[SPAN_TRANS; SUBSET; SPAN_MONO; IN_INSERT];
4907 X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC
4908 (ISPEC `span s:real^N->bool` BASIS_EXISTS) THEN
4909 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
4910 MATCH_MP_TAC DIM_UNIQUE THEN
4911 EXISTS_TAC `(x:real^N) INSERT b` THEN REPEAT CONJ_TAC THENL
4912 [REWRITE_TAC[INSERT_SUBSET] THEN
4913 ASM_MESON_TAC[SUBSET; SPAN_MONO; IN_INSERT; SPAN_SUPERSET];
4914 REWRITE_TAC[SUBSET; SPAN_BREAKDOWN_EQ] THEN
4915 ASM_MESON_TAC[SUBSET];
4916 REWRITE_TAC[INDEPENDENT_INSERT] THEN
4917 ASM_MESON_TAC[SUBSET; SPAN_SUPERSET; SPAN_MONO; SPAN_SPAN];
4918 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
4919 ASM_SIMP_TAC[HAS_SIZE; CARD_CLAUSES; FINITE_INSERT; ADD1] THEN
4920 ASM_MESON_TAC[SUBSET; SPAN_SUPERSET; SPAN_MONO; SPAN_SPAN]]);;
4922 let DIM_SING = prove
4923 (`!x. dim{x} = if x = vec 0 then 0 else 1`,
4924 REWRITE_TAC[DIM_INSERT; DIM_EMPTY; SPAN_EMPTY; IN_SING; ARITH]);;
4926 let DIM_EQ_0 = prove
4927 (`!s:real^N->bool. dim s = 0 <=> s SUBSET {vec 0}`,
4928 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
4929 [MATCH_MP_TAC(SET_RULE
4930 `~(?b. ~(b = a) /\ {b} SUBSET s) ==> s SUBSET {a}`) THEN
4931 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP DIM_SUBSET);
4932 MATCH_MP_TAC(ARITH_RULE `!m. m = 0 /\ n <= m ==> n = 0`) THEN
4933 EXISTS_TAC `dim{vec 0:real^N}` THEN ASM_SIMP_TAC[DIM_SUBSET]] THEN
4934 ASM_REWRITE_TAC[DIM_SING; ARITH]);;
4936 (* ------------------------------------------------------------------------- *)
4937 (* Choosing a subspace of a given dimension. *)
4938 (* ------------------------------------------------------------------------- *)
4940 let CHOOSE_SUBSPACE_OF_SUBSPACE = prove
4941 (`!s:real^N->bool n.
4942 n <= dim s ==> ?t. subspace t /\ t SUBSET span s /\ dim t = n`,
4943 GEN_TAC THEN INDUCT_TAC THENL
4944 [DISCH_TAC THEN EXISTS_TAC `{vec 0:real^N}` THEN
4945 REWRITE_TAC[SUBSPACE_TRIVIAL; DIM_SING; SING_SUBSET; SPAN_0];
4946 DISCH_THEN(fun th -> POP_ASSUM MP_TAC THEN ASSUME_TAC th) THEN
4947 ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
4948 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
4949 ASM_CASES_TAC `span (s:real^N->bool) SUBSET span t` THENL
4950 [SUBGOAL_THEN `dim(s:real^N->bool) = dim(t:real^N->bool)` MP_TAC THENL
4951 [ALL_TAC; ASM_ARITH_TAC] THEN MATCH_MP_TAC SPAN_EQ_DIM THEN
4952 MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN
4953 MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN ASM_REWRITE_TAC[SUBSPACE_SPAN];
4954 FIRST_ASSUM(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC o MATCH_MP(SET_RULE
4955 `~(s SUBSET t) ==> ?a. a IN s /\ ~(a IN t)`)) THEN
4956 EXISTS_TAC `span((y:real^N) INSERT t)` THEN
4957 REWRITE_TAC[SUBSPACE_SPAN] THEN CONJ_TAC THENL
4958 [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
4959 ASM_REWRITE_TAC[SUBSPACE_SPAN] THEN ASM SET_TAC[];
4960 ASM_REWRITE_TAC[DIM_SPAN; DIM_INSERT; ADD1]]]]);;
4962 (* ------------------------------------------------------------------------- *)
4963 (* Relation between bases and injectivity/surjectivity of map. *)
4964 (* ------------------------------------------------------------------------- *)
4966 let SPANNING_SURJECTIVE_IMAGE = prove
4967 (`!f:real^M->real^N s.
4968 UNIV SUBSET (span s) /\ linear f /\ (!y. ?x. f(x) = y)
4969 ==> UNIV SUBSET span(IMAGE f s)`,
4970 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN
4971 EXISTS_TAC `IMAGE (f:real^M->real^N) UNIV` THEN
4972 ASM_SIMP_TAC[SPANS_IMAGE] THEN
4973 REWRITE_TAC[SUBSET; IN_UNIV; IN_IMAGE] THEN ASM_MESON_TAC[]);;
4975 let INDEPENDENT_INJECTIVE_IMAGE_GEN = prove
4976 (`!f:real^M->real^N s.
4977 independent s /\ linear f /\
4978 (!x y. x IN span s /\ y IN span s /\ f(x) = f(y) ==> x = y)
4979 ==> independent (IMAGE f s)`,
4981 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
4982 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
4983 REWRITE_TAC[independent; DEPENDENT_EXPLICIT] THEN
4984 REWRITE_TAC[CONJ_ASSOC; FINITE_SUBSET_IMAGE] THEN
4986 `(?s u. ((?t. p t /\ s = f t) /\ q s u) /\ r s u) <=>
4987 (?t u. p t /\ q (f t) u /\ r (f t) u)`] THEN
4988 REWRITE_TAC[EXISTS_IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN
4989 MAP_EVERY X_GEN_TAC [`t:real^M->bool`; `u:real^N->real`] THEN
4990 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
4991 MAP_EVERY EXISTS_TAC
4992 [`t:real^M->bool`; `(u:real^N->real) o (f:real^M->real^N)`] THEN
4993 ASM_REWRITE_TAC[o_THM] THEN
4994 FIRST_ASSUM MATCH_MP_TAC THEN REPEAT CONJ_TAC THENL
4995 [MATCH_MP_TAC SPAN_VSUM THEN ASM_REWRITE_TAC[] THEN
4996 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
4997 MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[];
4998 REWRITE_TAC[SPAN_0];
4999 ASM_SIMP_TAC[LINEAR_VSUM] THEN
5000 FIRST_ASSUM(SUBST1_TAC o MATCH_MP LINEAR_0) THEN
5001 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN CONV_TAC SYM_CONV THEN
5002 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN
5003 ASM_SIMP_TAC[o_DEF; LINEAR_CMUL] THEN DISCH_THEN MATCH_MP_TAC THEN
5004 ASM_MESON_TAC[SPAN_SUPERSET; SUBSET]]);;
5006 let INDEPENDENT_INJECTIVE_IMAGE = prove
5007 (`!f:real^M->real^N s.
5008 independent s /\ linear f /\ (!x y. (f(x) = f(y)) ==> (x = y))
5009 ==> independent (IMAGE f s)`,
5010 REPEAT STRIP_TAC THEN MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN
5013 (* ------------------------------------------------------------------------- *)
5014 (* Picking an orthogonal replacement for a spanning set. *)
5015 (* ------------------------------------------------------------------------- *)
5017 let VECTOR_SUB_PROJECT_ORTHOGONAL = prove
5018 (`!b:real^N x. b dot (x - ((b dot x) / (b dot b)) % b) = &0`,
5019 REPEAT GEN_TAC THEN ASM_CASES_TAC `b = vec 0 :real^N` THENL
5020 [ASM_REWRITE_TAC[DOT_LZERO]; ALL_TAC] THEN
5021 ASM_SIMP_TAC[DOT_RSUB; DOT_RMUL] THEN
5022 ASM_SIMP_TAC[REAL_SUB_REFL; REAL_DIV_RMUL; DOT_EQ_0]);;
5024 let BASIS_ORTHOGONAL = prove
5027 ==> ?c. FINITE c /\ CARD c <= CARD b /\
5028 span c = span b /\ pairwise orthogonal c`,
5029 REWRITE_TAC[pairwise; orthogonal] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5031 [EXISTS_TAC `{}:real^N->bool` THEN
5032 REWRITE_TAC[FINITE_RULES; NOT_IN_EMPTY; LE_REFL];
5034 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N->bool`] THEN
5035 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC)
5036 STRIP_ASSUME_TAC) THEN
5037 EXISTS_TAC `(a - vsum c (\x. ((x dot a) / (x dot x)) % x):real^N)
5039 ASM_SIMP_TAC[FINITE_RULES; CARD_CLAUSES] THEN REPEAT CONJ_TAC THENL
5041 REWRITE_TAC[EXTENSION; SPAN_BREAKDOWN_EQ] THEN
5042 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN GEN_TAC THEN
5043 AP_TERM_TAC THEN ABS_TAC THEN REWRITE_TAC[VECTOR_SUB_LDISTRIB] THEN
5044 REWRITE_TAC[VECTOR_ARITH `a - (x - y):real^N = y + (a - x)`] THEN
5045 MATCH_MP_TAC SPAN_ADD_EQ THEN MATCH_MP_TAC SPAN_MUL THEN
5046 MATCH_MP_TAC SPAN_VSUM THEN ASM_REWRITE_TAC[] THEN
5047 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
5048 ASM_SIMP_TAC[SPAN_SUPERSET];
5049 REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THENL
5051 FIRST_X_ASSUM SUBST_ALL_TAC;
5052 FIRST_X_ASSUM SUBST_ALL_TAC;
5053 ASM_MESON_TAC[]] THEN
5054 REWRITE_TAC[DOT_LSUB; DOT_RSUB; REAL_SUB_0] THEN
5055 FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE
5056 `x IN s ==> s = x INSERT (s DELETE x)`)) THEN
5057 ASM_SIMP_TAC[VSUM_CLAUSES; FINITE_DELETE; IN_DELETE] THEN
5058 REWRITE_TAC[DOT_LADD; DOT_RADD; DOT_LMUL; DOT_RMUL] THEN
5059 MATCH_MP_TAC(REAL_ARITH `s = &0 /\ a = b ==> b = a + s`) THEN
5060 ASM_SIMP_TAC[DOT_LSUM; DOT_RSUM; FINITE_DELETE] THEN
5062 [MATCH_MP_TAC SUM_EQ_0 THEN
5063 ASM_SIMP_TAC[DOT_LMUL; DOT_RMUL; IN_DELETE;
5064 REAL_MUL_RZERO; REAL_MUL_LZERO];
5065 W(MP_TAC o PART_MATCH (lhand o rand) REAL_DIV_RMUL o lhand o snd) THEN
5066 REWRITE_TAC[DOT_SYM] THEN
5067 MATCH_MP_TAC(TAUT `(p ==> q) ==> (~p ==> q) ==> q`) THEN
5068 SIMP_TAC[] THEN SIMP_TAC[DOT_EQ_0; DOT_RZERO; DOT_LZERO] THEN
5069 REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO]])]);;
5071 let ORTHOGONAL_BASIS_EXISTS = prove
5073 ?b. independent b /\
5077 pairwise orthogonal b`,
5078 GEN_TAC THEN MP_TAC(ISPEC `v:real^N->bool` BASIS_EXISTS) THEN
5079 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
5080 MP_TAC(SPEC `b:real^N->bool` BASIS_ORTHOGONAL) THEN
5081 ANTS_TAC THENL [ASM_MESON_TAC[HAS_SIZE]; ALL_TAC] THEN
5082 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N->bool` THEN
5083 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
5084 [MATCH_MP_TAC CARD_LE_DIM_SPANNING THEN ASM_REWRITE_TAC[] THEN
5085 EXISTS_TAC `span(v):real^N->bool` THEN CONJ_TAC THENL
5086 [ASM_MESON_TAC[SPAN_SPAN; SPAN_MONO];
5087 ASM_MESON_TAC[LE_TRANS; HAS_SIZE; DIM_SPAN]];
5088 ASM_MESON_TAC[SUBSET_TRANS; SPAN_INC; SPAN_SPAN; SPAN_MONO];
5089 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
5090 ASM_REWRITE_TAC[HAS_SIZE; GSYM LE_ANTISYM] THEN
5091 CONJ_TAC THENL [ASM_MESON_TAC[LE_TRANS]; ALL_TAC] THEN
5092 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN
5093 ASM_REWRITE_TAC[] THEN
5094 ASM_MESON_TAC[SPAN_SPAN; SPAN_MONO; SUBSET_TRANS; SPAN_INC]]);;
5097 (`!s t. span s = span t <=> s SUBSET span t /\ t SUBSET span s`,
5098 REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN
5099 MESON_TAC[SUBSET_TRANS; SPAN_SPAN; SPAN_MONO; SPAN_INC]);;
5101 let SPAN_EQ_INSERT = prove
5102 (`!s x. span(x INSERT s) = span s <=> x IN span s`,
5103 REWRITE_TAC[SPAN_EQ; INSERT_SUBSET] THEN
5104 MESON_TAC[SPAN_INC; SUBSET; SET_RULE `s SUBSET (x INSERT s)`]);;
5106 let SPAN_SPECIAL_SCALE = prove
5108 span((a % x) INSERT s) = if a = &0 then span s else span(x INSERT s)`,
5109 REPEAT GEN_TAC THEN COND_CASES_TAC THEN
5110 ASM_REWRITE_TAC[VECTOR_MUL_LZERO; SPAN_INSERT_0] THEN
5111 REWRITE_TAC[SPAN_EQ; SUBSET; FORALL_IN_INSERT] THEN
5112 SIMP_TAC[SPAN_MUL; SPAN_SUPERSET; IN_INSERT] THEN
5113 REWRITE_TAC[SPAN_BREAKDOWN_EQ] THEN EXISTS_TAC `inv a:real` THEN
5114 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID] THEN
5115 REWRITE_TAC[SPAN_0; VECTOR_SUB_REFL]);;
5117 (* ------------------------------------------------------------------------- *)
5118 (* We can extend a linear basis-basis injection to the whole set. *)
5119 (* ------------------------------------------------------------------------- *)
5121 let LINEAR_INDEP_IMAGE_LEMMA = prove
5122 (`!f b. linear(f:real^M->real^N) /\
5124 independent (IMAGE f b) /\
5125 (!x y. x IN b /\ y IN b /\ (f x = f y) ==> (x = y))
5126 ==> !x. x IN span b ==> (f(x) = vec 0) ==> (x = vec 0)`,
5127 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
5128 GEN_TAC THEN DISCH_TAC THEN
5129 GEN_REWRITE_TAC (BINDER_CONV o RAND_CONV) [IMP_IMP] THEN
5130 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5131 CONJ_TAC THENL [SIMP_TAC[IN_SING; SPAN_EMPTY]; ALL_TAC] THEN
5132 MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M->bool`] THEN STRIP_TAC THEN
5133 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
5135 [ASM_MESON_TAC[INDEPENDENT_MONO; IMAGE_CLAUSES; SUBSET; IN_INSERT];
5137 DISCH_TAC THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
5138 MP_TAC(ISPECL [`a:real^M`; `(a:real^M) INSERT b`; `x:real^M`]
5139 SPAN_BREAKDOWN) THEN
5140 ASM_REWRITE_TAC[IN_INSERT] THEN
5141 SIMP_TAC[ASSUME `~((a:real^M) IN b)`; SET_RULE
5142 `~(a IN b) ==> ((a INSERT b) DELETE a = b)`] THEN
5143 DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN
5144 SUBGOAL_THEN `(f:real^M->real^N)(x - k % a) IN span(IMAGE f b)` MP_TAC THENL
5145 [ASM_MESON_TAC[SPAN_LINEAR_IMAGE; IN_IMAGE]; ALL_TAC] THEN
5146 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_SUB th]) THEN
5147 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_CMUL th]) THEN
5148 ASM_REWRITE_TAC[VECTOR_ARITH `vec 0 - k % x = (--k) % x`] THEN
5149 ASM_CASES_TAC `k = &0` THENL
5150 [ASM_MESON_TAC[VECTOR_ARITH `x - &0 % y = x`]; ALL_TAC] THEN
5151 DISCH_THEN(MP_TAC o SPEC `--inv(k)` o MATCH_MP SPAN_MUL) THEN
5152 REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LNEG; REAL_MUL_RNEG] THEN
5153 SIMP_TAC[REAL_NEGNEG; REAL_MUL_LINV; ASSUME `~(k = &0)`] THEN
5154 REWRITE_TAC[VECTOR_MUL_LID] THEN
5155 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [independent]) THEN
5156 REWRITE_TAC[dependent; NOT_EXISTS_THM] THEN
5157 DISCH_THEN(MP_TAC o SPEC `(f:real^M->real^N) a`) THEN
5159 `IMAGE (f:real^M->real^N) (a INSERT b) DELETE f a =
5160 IMAGE f ((a INSERT b) DELETE a)`
5162 [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DELETE; IN_INSERT] THEN
5163 ASM_MESON_TAC[IN_INSERT];
5165 ASM_REWRITE_TAC[DELETE_INSERT] THEN
5166 SIMP_TAC[SET_RULE `~(a IN b) ==> (b DELETE a = b)`;
5167 ASSUME `~(a:real^M IN b)`] THEN
5168 SIMP_TAC[IMAGE_CLAUSES; IN_INSERT]);;
5170 (* ------------------------------------------------------------------------- *)
5171 (* We can extend a linear mapping from basis. *)
5172 (* ------------------------------------------------------------------------- *)
5174 let LINEAR_INDEPENDENT_EXTEND_LEMMA = prove
5177 ==> ?g:real^M->real^N.
5178 (!x y. x IN span b /\ y IN span b
5179 ==> (g(x + y) = g(x) + g(y))) /\
5180 (!x c. x IN span b ==> (g(c % x) = c % g(x))) /\
5181 (!x. x IN b ==> (g x = f x))`,
5182 GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5183 REWRITE_TAC[NOT_IN_EMPTY; INDEPENDENT_INSERT] THEN CONJ_TAC THENL
5184 [REPEAT STRIP_TAC THEN EXISTS_TAC `(\x. vec 0):real^M->real^N` THEN
5185 SIMP_TAC[SPAN_EMPTY] THEN REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC;
5187 SIMP_TAC[] THEN MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M->bool`] THEN
5188 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
5189 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
5190 DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN
5191 ABBREV_TAC `h = \z:real^M. @k. (z - k % a) IN span b` THEN
5192 SUBGOAL_THEN `!z:real^M. z IN span(a INSERT b)
5193 ==> (z - h(z) % a) IN span(b) /\
5194 !k. (z - k % a) IN span(b) ==> (k = h(z))`
5196 [GEN_TAC THEN DISCH_TAC THEN
5197 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
5198 [EXPAND_TAC "h" THEN CONV_TAC SELECT_CONV THEN
5199 ASM_MESON_TAC[SPAN_BREAKDOWN_EQ];
5201 REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN GEN_TAC THEN
5202 DISCH_THEN(MP_TAC o MATCH_MP SPAN_SUB) THEN
5203 REWRITE_TAC[VECTOR_ARITH `(z - a % v) - (z - b % v) = (b - a) % v`] THEN
5204 ASM_CASES_TAC `k = (h:real^M->real) z` THEN ASM_REWRITE_TAC[] THEN
5205 DISCH_THEN(MP_TAC o SPEC `inv(k - (h:real^M->real) z)` o
5206 MATCH_MP SPAN_MUL) THEN
5207 ASM_SIMP_TAC[REAL_MUL_LINV; VECTOR_MUL_ASSOC; REAL_SUB_0] THEN
5208 ASM_REWRITE_TAC[VECTOR_MUL_LID];
5210 REWRITE_TAC[TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN
5211 REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN
5212 GEN_REWRITE_TAC LAND_CONV [FORALL_AND_THM] THEN STRIP_TAC THEN
5213 EXISTS_TAC `\z:real^M. h(z) % (f:real^M->real^N)(a) + g(z - h(z) % a)` THEN
5214 REPEAT CONJ_TAC THENL
5215 [MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN
5216 SUBGOAL_THEN `(h:real^M->real)(x + y) = h(x) + h(y)` ASSUME_TAC THENL
5217 [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
5218 REWRITE_TAC[VECTOR_ARITH
5219 `(x + y) - (k + l) % a = (x - k % a) + (y - l % a)`] THEN
5220 CONJ_TAC THEN MATCH_MP_TAC SPAN_ADD THEN ASM_REWRITE_TAC[] THEN
5223 ASM_REWRITE_TAC[VECTOR_ARITH
5224 `(x + y) - (k + l) % a = (x - k % a) + (y - l % a)`] THEN
5225 ASM_SIMP_TAC[] THEN VECTOR_ARITH_TAC;
5226 MAP_EVERY X_GEN_TAC [`x:real^M`; `c:real`] THEN STRIP_TAC THEN
5227 SUBGOAL_THEN `(h:real^M->real)(c % x) = c * h(x)` ASSUME_TAC THENL
5228 [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
5229 REWRITE_TAC[VECTOR_ARITH
5230 `c % x - (c * k) % a = c % (x - k % a)`] THEN
5231 CONJ_TAC THEN MATCH_MP_TAC SPAN_MUL THEN ASM_REWRITE_TAC[] THEN
5234 ASM_REWRITE_TAC[VECTOR_ARITH
5235 `c % x - (c * k) % a = c % (x - k % a)`] THEN
5236 ASM_SIMP_TAC[] THEN VECTOR_ARITH_TAC;
5238 X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_INSERT] THEN
5239 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL
5240 [SUBGOAL_THEN `&1 = h(a:real^M)` (SUBST1_TAC o SYM) THENL
5241 [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN
5242 REWRITE_TAC[VECTOR_ARITH `a - &1 % a = vec 0`; SPAN_0] THENL
5243 [ASM_MESON_TAC[SPAN_SUPERSET; SUBSET; IN_INSERT]; ALL_TAC] THEN
5244 FIRST_X_ASSUM(MP_TAC o SPECL [`vec 0:real^M`; `vec 0:real^M`]) THEN
5245 REWRITE_TAC[SPAN_0; VECTOR_ADD_LID] THEN
5246 REWRITE_TAC[VECTOR_ARITH `(a = a + a) <=> (a = vec 0)`] THEN
5247 DISCH_THEN SUBST1_TAC THEN VECTOR_ARITH_TAC;
5249 SUBGOAL_THEN `&0 = h(x:real^M)` (SUBST1_TAC o SYM) THENL
5250 [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN
5251 REWRITE_TAC[VECTOR_ADD_LID; VECTOR_MUL_LZERO; VECTOR_SUB_RZERO] THEN
5252 ASM_MESON_TAC[SUBSET; IN_INSERT; SPAN_SUPERSET]);;
5254 let LINEAR_INDEPENDENT_EXTEND = prove
5255 (`!f b. independent b
5256 ==> ?g:real^M->real^N. linear g /\ (!x. x IN b ==> (g x = f x))`,
5257 REPEAT STRIP_TAC THEN
5258 MP_TAC(ISPECL [`b:real^M->bool`; `(:real^M)`]
5259 MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
5260 ASM_REWRITE_TAC[SUBSET_UNIV; UNIV_SUBSET] THEN
5261 REWRITE_TAC[EXTENSION; IN_UNIV] THEN
5262 DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN
5263 MP_TAC(ISPECL [`f:real^M->real^N`; `c:real^M->bool`]
5264 LINEAR_INDEPENDENT_EXTEND_LEMMA) THEN
5265 ASM_SIMP_TAC[INDEPENDENT_BOUND; linear] THEN
5266 ASM_MESON_TAC[SUBSET]);;
5268 (* ------------------------------------------------------------------------- *)
5269 (* Linear functions are equal on a subspace if they are on a spanning set. *)
5270 (* ------------------------------------------------------------------------- *)
5272 let SUBSPACE_KERNEL = prove
5273 (`!f. linear f ==> subspace {x | f(x) = vec 0}`,
5274 REWRITE_TAC[subspace; IN_ELIM_THM] THEN
5275 SIMP_TAC[LINEAR_ADD; LINEAR_CMUL; VECTOR_ADD_LID; VECTOR_MUL_RZERO] THEN
5276 MESON_TAC[LINEAR_0]);;
5278 let LINEAR_EQ_0_SPAN = prove
5279 (`!f:real^M->real^N b.
5280 linear f /\ (!x. x IN b ==> f(x) = vec 0)
5281 ==> !x. x IN span(b) ==> f(x) = vec 0`,
5282 REPEAT GEN_TAC THEN STRIP_TAC THEN
5283 RULE_ASSUM_TAC(REWRITE_RULE[IN]) THEN
5284 MATCH_MP_TAC SPAN_INDUCT THEN ASM_REWRITE_TAC[IN] THEN
5285 MP_TAC(ISPEC `f:real^M->real^N` SUBSPACE_KERNEL) THEN
5286 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN
5287 AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM]);;
5289 let LINEAR_EQ_0 = prove
5290 (`!f b s. linear f /\ s SUBSET (span b) /\ (!x. x IN b ==> f(x) = vec 0)
5291 ==> !x. x IN s ==> f(x) = vec 0`,
5292 MESON_TAC[LINEAR_EQ_0_SPAN; SUBSET]);;
5294 let LINEAR_EQ = prove
5295 (`!f g b s. linear f /\ linear g /\ s SUBSET (span b) /\
5296 (!x. x IN b ==> f(x) = g(x))
5297 ==> !x. x IN s ==> f(x) = g(x)`,
5298 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
5299 STRIP_TAC THEN MATCH_MP_TAC LINEAR_EQ_0 THEN
5300 ASM_MESON_TAC[LINEAR_COMPOSE_SUB]);;
5302 let LINEAR_EQ_STDBASIS = prove
5303 (`!f:real^M->real^N g.
5304 linear f /\ linear g /\
5305 (!i. 1 <= i /\ i <= dimindex(:M)
5306 ==> f(basis i) = g(basis i))
5308 REPEAT STRIP_TAC THEN
5309 SUBGOAL_THEN `!x. x IN UNIV ==> (f:real^M->real^N) x = g x`
5310 (fun th -> MP_TAC th THEN REWRITE_TAC[FUN_EQ_THM; IN_UNIV]) THEN
5311 MATCH_MP_TAC LINEAR_EQ THEN
5312 EXISTS_TAC `{basis i :real^M | 1 <= i /\ i <= dimindex(:M)}` THEN
5313 ASM_REWRITE_TAC[SPAN_STDBASIS; SUBSET_REFL; IN_ELIM_THM] THEN
5316 let SUBSPACE_LINEAR_FIXED_POINTS = prove
5317 (`!f:real^N->real^N. linear f ==> subspace {x | f(x) = x}`,
5318 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
5319 MATCH_MP_TAC SUBSPACE_KERNEL THEN
5320 ASM_SIMP_TAC[LINEAR_COMPOSE_SUB; LINEAR_ID]);;
5322 (* ------------------------------------------------------------------------- *)
5323 (* Similar results for bilinear functions. *)
5324 (* ------------------------------------------------------------------------- *)
5326 let BILINEAR_EQ = prove
5327 (`!f:real^M->real^N->real^P g b c s.
5328 bilinear f /\ bilinear g /\
5329 s SUBSET (span b) /\ t SUBSET (span c) /\
5330 (!x y. x IN b /\ y IN c ==> f x y = g x y)
5331 ==> !x y. x IN s /\ y IN t ==> f x y = g x y`,
5332 REPEAT STRIP_TAC THEN SUBGOAL_THEN
5333 `!x:real^M. x IN span b
5334 ==> !y:real^N. y IN span c ==> (f x y :real^P = g x y)`
5335 (fun th -> ASM_MESON_TAC[th; SUBSET]) THEN
5336 MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[subspace; IN_ELIM_THM] THEN
5338 [GEN_TAC THEN DISCH_TAC;
5339 ASM_SIMP_TAC[BILINEAR_LADD; BILINEAR_LMUL] THEN
5340 ASM_MESON_TAC[BILINEAR_LZERO]] THEN
5341 MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[subspace; IN_ELIM_THM] THEN
5342 ASM_SIMP_TAC[BILINEAR_RADD; BILINEAR_RMUL] THEN
5343 ASM_MESON_TAC[BILINEAR_RZERO]);;
5345 let BILINEAR_EQ_STDBASIS = prove
5346 (`!f:real^M->real^N->real^P g.
5347 bilinear f /\ bilinear g /\
5348 (!i j. 1 <= i /\ i <= dimindex(:M) /\ 1 <= j /\ j <= dimindex(:N)
5349 ==> f (basis i) (basis j) = g (basis i) (basis j))
5351 REPEAT STRIP_TAC THEN SUBGOAL_THEN
5352 `!x y. x IN UNIV /\ y IN UNIV ==> (f:real^M->real^N->real^P) x y = g x y`
5353 (fun th -> MP_TAC th THEN REWRITE_TAC[FUN_EQ_THM; IN_UNIV]) THEN
5354 MATCH_MP_TAC BILINEAR_EQ THEN
5355 EXISTS_TAC `{basis i :real^M | 1 <= i /\ i <= dimindex(:M)}` THEN
5356 EXISTS_TAC `{basis i :real^N | 1 <= i /\ i <= dimindex(:N)}` THEN
5357 ASM_REWRITE_TAC[SPAN_STDBASIS; SUBSET_REFL; IN_ELIM_THM] THEN
5360 (* ------------------------------------------------------------------------- *)
5361 (* Detailed theorems about left and right invertibility in general case. *)
5362 (* ------------------------------------------------------------------------- *)
5364 let LEFT_INVERTIBLE_TRANSP = prove
5366 (?B:real^N^M. B ** transp A = mat 1) <=> (?B:real^M^N. A ** B = mat 1)`,
5367 MESON_TAC[MATRIX_TRANSP_MUL; TRANSP_MAT; TRANSP_TRANSP]);;
5369 let RIGHT_INVERTIBLE_TRANSP = prove
5371 (?B:real^N^M. transp A ** B = mat 1) <=> (?B:real^M^N. B ** A = mat 1)`,
5372 MESON_TAC[MATRIX_TRANSP_MUL; TRANSP_MAT; TRANSP_TRANSP]);;
5374 let INVERTIBLE_TRANSP = prove
5375 (`!A:real^N^M. invertible(transp A) <=> invertible A`,
5376 GEN_TAC THEN REWRITE_TAC[invertible] THEN
5377 GEN_REWRITE_TAC LAND_CONV [MESON[TRANSP_TRANSP]
5378 `(?A:real^M^N. P A) <=> (?A:real^N^M. P(transp A))`] THEN
5379 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM TRANSP_MAT] THEN
5380 REWRITE_TAC[GSYM MATRIX_TRANSP_MUL; TRANSP_EQ] THEN MESON_TAC[]);;
5382 let LINEAR_INJECTIVE_LEFT_INVERSE = prove
5383 (`!f:real^M->real^N.
5384 linear f /\ (!x y. f x = f y ==> x = y)
5385 ==> ?g. linear g /\ g o f = I`,
5386 REWRITE_TAC[INJECTIVE_LEFT_INVERSE] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN
5387 `?h. linear(h:real^N->real^M) /\
5388 !x. x IN IMAGE (f:real^M->real^N)
5389 {basis i | 1 <= i /\ i <= dimindex(:M)} ==> h x = g x`
5391 [MATCH_MP_TAC LINEAR_INDEPENDENT_EXTEND THEN
5392 MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE THEN
5393 ASM_MESON_TAC[INJECTIVE_LEFT_INVERSE; INDEPENDENT_STDBASIS];
5394 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^N->real^M` THEN
5395 ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN STRIP_TAC THEN
5396 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LINEAR_EQ_STDBASIS THEN
5397 ASM_SIMP_TAC[I_DEF; LINEAR_COMPOSE; LINEAR_ID; o_THM] THEN
5400 let LINEAR_SURJECTIVE_RIGHT_INVERSE = prove
5401 (`!f:real^M->real^N.
5402 linear f /\ (!y. ?x. f x = y) ==> ?g. linear g /\ f o g = I`,
5403 REWRITE_TAC[SURJECTIVE_RIGHT_INVERSE] THEN REPEAT STRIP_TAC THEN SUBGOAL_THEN
5404 `?h. linear(h:real^N->real^M) /\
5405 !x. x IN {basis i | 1 <= i /\ i <= dimindex(:N)} ==> h x = g x`
5407 [MATCH_MP_TAC LINEAR_INDEPENDENT_EXTEND THEN
5408 REWRITE_TAC[INDEPENDENT_STDBASIS];
5409 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `h:real^N->real^M` THEN
5410 ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN STRIP_TAC THEN
5411 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LINEAR_EQ_STDBASIS THEN
5412 ASM_SIMP_TAC[I_DEF; LINEAR_COMPOSE; LINEAR_ID; o_THM] THEN
5415 let MATRIX_LEFT_INVERTIBLE_INJECTIVE = prove
5417 (?B:real^M^N. B ** A = mat 1) <=>
5418 !x y:real^N. A ** x = A ** y ==> x = y`,
5419 GEN_TAC THEN EQ_TAC THENL
5420 [STRIP_TAC THEN REPEAT GEN_TAC THEN
5421 DISCH_THEN(MP_TAC o AP_TERM `\x:real^M. (B:real^M^N) ** x`) THEN
5422 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID];
5423 DISCH_TAC THEN MP_TAC(ISPEC
5424 `\x:real^N. (A:real^N^M) ** x` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
5425 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; FUN_EQ_THM; I_THM; o_THM] THEN
5426 DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN
5427 EXISTS_TAC `matrix(g):real^M^N` THEN
5428 REWRITE_TAC[MATRIX_EQ; MATRIX_VECTOR_MUL_LID] THEN
5429 ASM_MESON_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_WORKS]]);;
5431 let MATRIX_LEFT_INVERTIBLE_KER = prove
5433 (?B:real^M^N. B ** A = mat 1) <=> !x. A ** x = vec 0 ==> x = vec 0`,
5434 GEN_TAC THEN REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_INJECTIVE] THEN
5435 MATCH_MP_TAC LINEAR_INJECTIVE_0 THEN REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);;
5437 let MATRIX_RIGHT_INVERTIBLE_SURJECTIVE = prove
5439 (?B:real^M^N. A ** B = mat 1) <=> !y. ?x. A ** x = y`,
5440 GEN_TAC THEN EQ_TAC THENL
5441 [STRIP_TAC THEN X_GEN_TAC `y:real^M` THEN
5442 EXISTS_TAC `(B:real^M^N) ** (y:real^M)` THEN
5443 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID];
5444 DISCH_TAC THEN MP_TAC(ISPEC
5445 `\x:real^N. (A:real^N^M) ** x` LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN
5446 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR; FUN_EQ_THM; I_THM; o_THM] THEN
5447 DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN
5448 EXISTS_TAC `matrix(g):real^M^N` THEN
5449 REWRITE_TAC[MATRIX_EQ; MATRIX_VECTOR_MUL_LID] THEN
5450 ASM_MESON_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_WORKS]]);;
5452 let MATRIX_LEFT_INVERTIBLE_INDEPENDENT_COLUMNS = prove
5453 (`!A:real^N^M. (?B:real^M^N. B ** A = mat 1) <=>
5454 !c. vsum(1..dimindex(:N)) (\i. c(i) % column i A) = vec 0 ==>
5455 !i. 1 <= i /\ i <= dimindex(:N) ==> c(i) = &0`,
5456 GEN_TAC THEN REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_KER; MATRIX_MUL_VSUM] THEN
5457 EQ_TAC THEN DISCH_TAC THENL
5458 [X_GEN_TAC `c:num->real` THEN DISCH_TAC THEN
5459 FIRST_X_ASSUM(MP_TAC o SPEC `(lambda i. c(i)):real^N`);
5460 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
5461 FIRST_X_ASSUM(MP_TAC o SPEC `\i. (x:real^N)$i`)] THEN
5462 ASM_SIMP_TAC[LAMBDA_BETA; CART_EQ; VEC_COMPONENT]);;
5464 let MATRIX_RIGHT_INVERTIBLE_INDEPENDENT_ROWS = prove
5465 (`!A:real^N^M. (?B:real^M^N. A ** B = mat 1) <=>
5466 !c. vsum(1..dimindex(:M)) (\i. c(i) % row i A) = vec 0 ==>
5467 !i. 1 <= i /\ i <= dimindex(:M) ==> c(i) = &0`,
5468 ONCE_REWRITE_TAC[GSYM LEFT_INVERTIBLE_TRANSP] THEN
5469 REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_INDEPENDENT_COLUMNS] THEN
5470 SIMP_TAC[COLUMN_TRANSP]);;
5472 let MATRIX_RIGHT_INVERTIBLE_SPAN_COLUMNS = prove
5473 (`!A:real^N^M. (?B:real^M^N. A ** B = mat 1) <=> span(columns A) = (:real^M)`,
5474 GEN_TAC THEN REWRITE_TAC[MATRIX_RIGHT_INVERTIBLE_SURJECTIVE] THEN
5475 REWRITE_TAC[MATRIX_MUL_VSUM; EXTENSION; IN_UNIV] THEN
5476 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `y:real^M` THEN
5478 [DISCH_THEN(X_CHOOSE_THEN `x:real^N` (SUBST1_TAC o SYM)) THEN
5479 MATCH_MP_TAC SPAN_VSUM THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
5480 X_GEN_TAC `i:num` THEN STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
5481 MATCH_MP_TAC(CONJUNCT1 SPAN_CLAUSES) THEN
5482 REWRITE_TAC[columns; IN_ELIM_THM] THEN ASM_MESON_TAC[];
5484 SPEC_TAC(`y:real^M`,`y:real^M`) THEN MATCH_MP_TAC SPAN_INDUCT_ALT THEN
5486 [EXISTS_TAC `vec 0 :real^N` THEN
5487 SIMP_TAC[VEC_COMPONENT; VECTOR_MUL_LZERO; VSUM_0];
5489 MAP_EVERY X_GEN_TAC [`c:real`; `y1:real^M`; `y2:real^M`] THEN
5490 REWRITE_TAC[columns; IN_ELIM_THM] THEN DISCH_THEN(CONJUNCTS_THEN2
5491 (X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC)
5492 (X_CHOOSE_THEN `x:real^N` (SUBST1_TAC o SYM))) THEN
5493 EXISTS_TAC `(lambda j. if j = i then c + (x:real^N)$i else x$j):real^N` THEN
5494 SUBGOAL_THEN `1..dimindex(:N) = i INSERT ((1..dimindex(:N)) DELETE i)`
5495 SUBST1_TAC THENL [ASM_MESON_TAC[INSERT_DELETE; IN_NUMSEG]; ALL_TAC] THEN
5496 SIMP_TAC[VSUM_CLAUSES; FINITE_DELETE; FINITE_NUMSEG; IN_DELETE] THEN
5497 ASM_SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_RDISTRIB; VECTOR_ADD_ASSOC] THEN
5498 AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
5499 SIMP_TAC[FINITE_DELETE; IN_DELETE; FINITE_NUMSEG; LAMBDA_BETA; IN_NUMSEG]);;
5501 let MATRIX_LEFT_INVERTIBLE_SPAN_ROWS = prove
5502 (`!A:real^N^M. (?B:real^M^N. B ** A = mat 1) <=> span(rows A) = (:real^N)`,
5503 MESON_TAC[RIGHT_INVERTIBLE_TRANSP; COLUMNS_TRANSP;
5504 MATRIX_RIGHT_INVERTIBLE_SPAN_COLUMNS]);;
5506 (* ------------------------------------------------------------------------- *)
5507 (* An injective map real^N->real^N is also surjective. *)
5508 (* ------------------------------------------------------------------------- *)
5510 let LINEAR_INJECTIVE_IMP_SURJECTIVE = prove
5511 (`!f:real^N->real^N.
5512 linear f /\ (!x y. (f(x) = f(y)) ==> (x = y))
5513 ==> !y. ?x. f(x) = y`,
5514 REPEAT STRIP_TAC THEN
5515 MP_TAC(ISPEC `(:real^N)` BASIS_EXISTS) THEN
5516 REWRITE_TAC[SUBSET_UNIV; HAS_SIZE] THEN
5517 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
5518 SUBGOAL_THEN `UNIV SUBSET span(IMAGE (f:real^N->real^N) b)` MP_TAC THENL
5519 [MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN
5520 ASM_MESON_TAC[INDEPENDENT_INJECTIVE_IMAGE; LE_REFL;
5521 SUBSET_UNIV; CARD_IMAGE_INJ];
5522 ASM_SIMP_TAC[SPAN_LINEAR_IMAGE] THEN
5523 ASM_MESON_TAC[SUBSET; IN_IMAGE; IN_UNIV]]);;
5525 (* ------------------------------------------------------------------------- *)
5526 (* And vice versa. *)
5527 (* ------------------------------------------------------------------------- *)
5529 let LINEAR_SURJECTIVE_IMP_INJECTIVE = prove
5530 (`!f:real^N->real^N.
5531 linear f /\ (!y. ?x. f(x) = y)
5532 ==> !x y. (f(x) = f(y)) ==> (x = y)`,
5533 REPEAT GEN_TAC THEN STRIP_TAC THEN
5534 MP_TAC(ISPEC `(:real^N)` BASIS_EXISTS) THEN
5535 REWRITE_TAC[SUBSET_UNIV; HAS_SIZE] THEN
5536 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
5538 `!x. x IN span b ==> (f:real^N->real^N) x = vec 0 ==> x = vec 0`
5539 (fun th -> ASM_MESON_TAC[th; LINEAR_INJECTIVE_0; SUBSET; IN_UNIV]) THEN
5540 MATCH_MP_TAC LINEAR_INDEP_IMAGE_LEMMA THEN
5541 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
5542 [MATCH_MP_TAC CARD_LE_DIM_SPANNING THEN
5543 EXISTS_TAC `(:real^N)` THEN
5544 ASM_SIMP_TAC[SUBSET_UNIV; FINITE_IMAGE; SPAN_LINEAR_IMAGE] THEN
5545 REWRITE_TAC[SUBSET; IN_UNIV; IN_IMAGE] THEN
5546 ASM_MESON_TAC[CARD_IMAGE_LE; SUBSET; IN_UNIV];
5548 SUBGOAL_THEN `dim(:real^N) <= CARD(IMAGE (f:real^N->real^N) b)`
5550 [MATCH_MP_TAC SPAN_CARD_GE_DIM THEN
5551 ASM_SIMP_TAC[SUBSET_UNIV; FINITE_IMAGE] THEN
5552 ASM_SIMP_TAC[SPAN_LINEAR_IMAGE] THEN MATCH_MP_TAC SUBSET_TRANS THEN
5553 EXISTS_TAC `IMAGE (f:real^N->real^N) UNIV` THEN
5554 ASM_SIMP_TAC[IMAGE_SUBSET] THEN
5555 ASM_REWRITE_TAC[SUBSET; IN_IMAGE; IN_UNIV] THEN ASM_MESON_TAC[];
5557 FIRST_X_ASSUM(MP_TAC o ISPEC `f:real^N->real^N` o
5558 MATCH_MP CARD_IMAGE_LE) THEN
5559 ASM_REWRITE_TAC[IMP_IMP; LE_ANTISYM] THEN DISCH_TAC THEN
5561 [`b:real^N->bool`; `IMAGE (f:real^N->real^N) b`; `f:real^N->real^N`]
5562 SURJECTIVE_IFF_INJECTIVE_GEN) THEN
5563 ASM_SIMP_TAC[FINITE_IMAGE; INDEPENDENT_BOUND; SUBSET_REFL] THEN
5564 REWRITE_TAC[FORALL_IN_IMAGE] THEN MESON_TAC[]);;
5566 let LINEAR_SURJECTIVE_IFF_INJECTIVE = prove
5567 (`!f:real^N->real^N.
5568 linear f ==> ((!y. ?x. f x = y) <=> (!x y. f x = f y ==> x = y))`,
5569 MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE;
5570 LINEAR_SURJECTIVE_IMP_INJECTIVE]);;
5572 (* ------------------------------------------------------------------------- *)
5573 (* Hence either is enough for isomorphism. *)
5574 (* ------------------------------------------------------------------------- *)
5576 let LEFT_RIGHT_INVERSE_EQ = prove
5577 (`!f:A->A g h. f o g = I /\ g o h = I ==> f = h`,
5578 MESON_TAC[o_ASSOC; I_O_ID]);;
5580 let ISOMORPHISM_EXPAND = prove
5581 (`!f g. f o g = I /\ g o f = I <=> (!x. f(g x) = x) /\ (!x. g(f x) = x)`,
5582 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM]);;
5584 let LINEAR_INJECTIVE_ISOMORPHISM = prove
5585 (`!f:real^N->real^N.
5586 linear f /\ (!x y. f x = f y ==> x = y)
5587 ==> ?f'. linear f' /\ (!x. f'(f x) = x) /\ (!x. f(f' x) = x)`,
5588 REPEAT STRIP_TAC THEN
5589 REWRITE_TAC[GSYM ISOMORPHISM_EXPAND] THEN
5590 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN
5591 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
5592 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_IMP_SURJECTIVE) THEN
5593 ASM_REWRITE_TAC[] THEN SIMP_TAC[] THEN MESON_TAC[LEFT_RIGHT_INVERSE_EQ]);;
5595 let LINEAR_SURJECTIVE_ISOMORPHISM = prove
5596 (`!f:real^N->real^N.
5597 linear f /\ (!y. ?x. f x = y)
5598 ==> ?f'. linear f' /\ (!x. f'(f x) = x) /\ (!x. f(f' x) = x)`,
5599 REPEAT STRIP_TAC THEN
5600 REWRITE_TAC[GSYM ISOMORPHISM_EXPAND] THEN
5601 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN
5602 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
5603 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_IMP_INJECTIVE) THEN
5604 ASM_REWRITE_TAC[] THEN SIMP_TAC[] THEN MESON_TAC[LEFT_RIGHT_INVERSE_EQ]);;
5606 (* ------------------------------------------------------------------------- *)
5607 (* Left and right inverses are the same for R^N->R^N. *)
5608 (* ------------------------------------------------------------------------- *)
5610 let LINEAR_INVERSE_LEFT = prove
5611 (`!f:real^N->real^N f'.
5612 linear f /\ linear f' ==> ((f o f' = I) <=> (f' o f = I))`,
5614 `!f:real^N->real^N f'.
5615 linear f /\ linear f' /\ (f o f' = I) ==> (f' o f = I)`
5616 (fun th -> MESON_TAC[th]) THEN
5617 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN REPEAT STRIP_TAC THEN
5618 MP_TAC(ISPEC `f:real^N->real^N` LINEAR_SURJECTIVE_ISOMORPHISM) THEN
5621 (* ------------------------------------------------------------------------- *)
5622 (* Moreover, a one-sided inverse is automatically linear. *)
5623 (* ------------------------------------------------------------------------- *)
5625 let LEFT_INVERSE_LINEAR = prove
5626 (`!f g:real^N->real^N. linear f /\ (g o f = I) ==> linear g`,
5627 REPEAT GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN
5628 STRIP_TAC THEN SUBGOAL_THEN
5629 `?h:real^N->real^N. linear h /\ (!x. h(f x) = x) /\ (!x. f(h x) = x)`
5631 [MATCH_MP_TAC LINEAR_INJECTIVE_ISOMORPHISM THEN ASM_MESON_TAC[];
5632 SUBGOAL_THEN `g:real^N->real^N = h` (fun th -> ASM_REWRITE_TAC[th]) THEN
5633 REWRITE_TAC[FUN_EQ_THM] THEN ASM_MESON_TAC[]]);;
5635 let RIGHT_INVERSE_LINEAR = prove
5636 (`!f g:real^N->real^N. linear f /\ (f o g = I) ==> linear g`,
5637 REPEAT GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN
5638 STRIP_TAC THEN SUBGOAL_THEN
5639 `?h:real^N->real^N. linear h /\ (!x. h(f x) = x) /\ (!x. f(h x) = x)`
5640 CHOOSE_TAC THENL [ASM_MESON_TAC[LINEAR_SURJECTIVE_ISOMORPHISM]; ALL_TAC] THEN
5641 SUBGOAL_THEN `g:real^N->real^N = h` (fun th -> ASM_REWRITE_TAC[th]) THEN
5642 REWRITE_TAC[FUN_EQ_THM] THEN ASM_MESON_TAC[]);;
5644 (* ------------------------------------------------------------------------- *)
5645 (* Without (ostensible) constraints on types, though dimensions must match. *)
5646 (* ------------------------------------------------------------------------- *)
5648 let LEFT_RIGHT_INVERSE_LINEAR = prove
5649 (`!f g:real^M->real^N.
5650 linear f /\ g o f = I /\ f o g = I ==> linear g`,
5651 REWRITE_TAC[linear; FUN_EQ_THM; o_THM; I_THM] THEN MESON_TAC[]);;
5653 let LINEAR_BIJECTIVE_LEFT_RIGHT_INVERSE = prove
5654 (`!f:real^M->real^N.
5655 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
5656 ==> ?g. linear g /\ (!x. g(f x) = x) /\ (!y. f(g y) = y)`,
5657 GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
5658 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BIJECTIVE_LEFT_RIGHT_INVERSE]) THEN
5659 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
5660 MATCH_MP_TAC LEFT_RIGHT_INVERSE_LINEAR THEN
5661 EXISTS_TAC `f:real^M->real^N` THEN
5662 ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM]);;
5664 (* ------------------------------------------------------------------------- *)
5665 (* The same result in terms of square matrices. *)
5666 (* ------------------------------------------------------------------------- *)
5668 let MATRIX_LEFT_RIGHT_INVERSE = prove
5669 (`!A:real^N^N A':real^N^N. (A ** A' = mat 1) <=> (A' ** A = mat 1)`,
5671 `!A:real^N^N A':real^N^N. (A ** A' = mat 1) ==> (A' ** A = mat 1)`
5672 (fun th -> MESON_TAC[th]) THEN
5673 REPEAT STRIP_TAC THEN
5674 MP_TAC(ISPEC `\x:real^N. A:(real^N^N) ** x`
5675 LINEAR_SURJECTIVE_ISOMORPHISM) THEN
5676 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN ANTS_TAC THENL
5677 [X_GEN_TAC `x:real^N` THEN EXISTS_TAC `(A':real^N^N) ** (x:real^N)` THEN
5678 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_ASSOC; MATRIX_VECTOR_MUL_LID];
5680 DISCH_THEN(X_CHOOSE_THEN `f':real^N->real^N` STRIP_ASSUME_TAC) THEN
5681 SUBGOAL_THEN `matrix (f':real^N->real^N) ** (A:real^N^N) = mat 1`
5683 [ASM_SIMP_TAC[MATRIX_EQ; MATRIX_WORKS; GSYM MATRIX_VECTOR_MUL_ASSOC;
5684 MATRIX_VECTOR_MUL_LID];
5686 DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
5687 DISCH_THEN(MP_TAC o AP_TERM `(\m:real^N^N. m ** (A':real^N^N))`) THEN
5688 REWRITE_TAC[GSYM MATRIX_MUL_ASSOC] THEN
5689 ASM_REWRITE_TAC[MATRIX_MUL_RID; MATRIX_MUL_LID] THEN ASM_MESON_TAC[]);;
5691 (* ------------------------------------------------------------------------- *)
5692 (* Invertibility of matrices and corresponding linear functions. *)
5693 (* ------------------------------------------------------------------------- *)
5695 let MATRIX_LEFT_INVERTIBLE = prove
5696 (`!f:real^M->real^N.
5697 linear f ==> ((?B:real^N^M. B ** matrix f = mat 1) <=>
5698 (?g. linear g /\ g o f = I))`,
5699 GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN STRIP_TAC THENL
5700 [EXISTS_TAC `\y:real^N. (B:real^N^M) ** y` THEN
5701 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN
5702 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o RAND_CONV)
5703 [MATCH_MP MATRIX_VECTOR_MUL th]) THEN
5704 ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; MATRIX_VECTOR_MUL_ASSOC;
5705 MATRIX_VECTOR_MUL_LID];
5706 EXISTS_TAC `matrix(g:real^N->real^M)` THEN
5707 ASM_SIMP_TAC[GSYM MATRIX_COMPOSE; MATRIX_I]]);;
5709 let MATRIX_RIGHT_INVERTIBLE = prove
5710 (`!f:real^M->real^N.
5711 linear f ==> ((?B:real^N^M. matrix f ** B = mat 1) <=>
5712 (?g. linear g /\ f o g = I))`,
5713 GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN STRIP_TAC THENL
5714 [EXISTS_TAC `\y:real^N. (B:real^N^M) ** y` THEN
5715 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN
5716 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV)
5717 [MATCH_MP MATRIX_VECTOR_MUL th]) THEN
5718 ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; MATRIX_VECTOR_MUL_ASSOC;
5719 MATRIX_VECTOR_MUL_LID];
5720 EXISTS_TAC `matrix(g:real^N->real^M)` THEN
5721 ASM_SIMP_TAC[GSYM MATRIX_COMPOSE; MATRIX_I]]);;
5723 let INVERTIBLE_LEFT_INVERSE = prove
5724 (`!A:real^N^N. invertible(A) <=> ?B:real^N^N. B ** A = mat 1`,
5725 MESON_TAC[invertible; MATRIX_LEFT_RIGHT_INVERSE]);;
5727 let INVERTIBLE_RIGHT_INVERSE = prove
5728 (`!A:real^N^N. invertible(A) <=> ?B:real^N^N. A ** B = mat 1`,
5729 MESON_TAC[invertible; MATRIX_LEFT_RIGHT_INVERSE]);;
5731 let MATRIX_INVERTIBLE = prove
5732 (`!f:real^N->real^N.
5734 ==> (invertible(matrix f) <=>
5735 ?g. linear g /\ f o g = I /\ g o f = I)`,
5736 SIMP_TAC[INVERTIBLE_LEFT_INVERSE; MATRIX_LEFT_INVERTIBLE] THEN
5737 MESON_TAC[LINEAR_INVERSE_LEFT]);;
5739 let MATRIX_INV_UNIQUE_LEFT = prove
5740 (`!A:real^N^N B. A ** B = mat 1 ==> matrix_inv B = A`,
5741 REPEAT STRIP_TAC THEN MATCH_MP_TAC MATRIX_INV_UNIQUE THEN
5742 ASM_MESON_TAC[MATRIX_LEFT_RIGHT_INVERSE]);;
5744 let MATRIX_INV_UNIQUE_RIGHT = prove
5745 (`!A:real^N^N B. A ** B = mat 1 ==> matrix_inv A = B`,
5746 REPEAT STRIP_TAC THEN MATCH_MP_TAC MATRIX_INV_UNIQUE THEN
5747 ASM_MESON_TAC[MATRIX_LEFT_RIGHT_INVERSE]);;
5749 (* ------------------------------------------------------------------------- *)
5750 (* Left-invertible linear transformation has a lower bound. *)
5751 (* ------------------------------------------------------------------------- *)
5753 let LINEAR_INVERTIBLE_BOUNDED_BELOW_POS = prove
5754 (`!f:real^M->real^N g.
5755 linear f /\ linear g /\ (g o f = I)
5756 ==> ?B. &0 < B /\ !x. B * norm(x) <= norm(f x)`,
5757 REPEAT STRIP_TAC THEN
5758 MP_TAC(ISPEC `g:real^N->real^M` LINEAR_BOUNDED_POS) THEN
5759 ASM_REWRITE_TAC[] THEN
5760 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
5761 EXISTS_TAC `inv B:real` THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN
5762 X_GEN_TAC `x:real^M` THEN MATCH_MP_TAC REAL_LE_TRANS THEN
5763 EXISTS_TAC `inv(B) * norm(((g:real^N->real^M) o (f:real^M->real^N)) x)` THEN
5764 CONJ_TAC THENL [ASM_SIMP_TAC[I_THM; REAL_LE_REFL]; ALL_TAC] THEN
5765 REWRITE_TAC[REAL_ARITH `inv B * x = x / B`] THEN
5766 ASM_SIMP_TAC[o_THM; REAL_LE_LDIV_EQ] THEN
5767 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_REWRITE_TAC[]);;
5769 let LINEAR_INVERTIBLE_BOUNDED_BELOW = prove
5770 (`!f:real^M->real^N g.
5771 linear f /\ linear g /\ (g o f = I)
5772 ==> ?B. !x. B * norm(x) <= norm(f x)`,
5773 MESON_TAC[LINEAR_INVERTIBLE_BOUNDED_BELOW_POS]);;
5775 let LINEAR_INJECTIVE_BOUNDED_BELOW_POS = prove
5776 (`!f:real^M->real^N.
5777 linear f /\ (!x y. f x = f y ==> x = y)
5778 ==> ?B. &0 < B /\ !x. norm(x) * B <= norm(f x)`,
5779 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
5780 MATCH_MP_TAC LINEAR_INVERTIBLE_BOUNDED_BELOW_POS THEN
5781 ASM_MESON_TAC[LINEAR_INJECTIVE_LEFT_INVERSE]);;
5783 (* ------------------------------------------------------------------------- *)
5784 (* Preservation of dimension by injective map. *)
5785 (* ------------------------------------------------------------------------- *)
5787 let DIM_INJECTIVE_LINEAR_IMAGE = prove
5788 (`!f:real^M->real^N s.
5789 linear f /\ (!x y. f x = f y ==> x = y) ==> dim(IMAGE f s) = dim s`,
5790 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN
5791 CONJ_TAC THENL [ASM_MESON_TAC[DIM_LINEAR_IMAGE_LE]; ALL_TAC] THEN
5792 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
5793 ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN
5794 DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN
5795 MATCH_MP_TAC LE_TRANS THEN
5796 EXISTS_TAC `dim(IMAGE (g:real^N->real^M) (IMAGE (f:real^M->real^N) s))` THEN
5798 [ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; LE_REFL];
5799 MATCH_MP_TAC DIM_LINEAR_IMAGE_LE THEN ASM_REWRITE_TAC[]]);;
5801 let LINEAR_INJECTIVE_DIMINDEX_LE = prove
5802 (`!f:real^M->real^N.
5803 linear f /\ (!x y. f x = f y ==> x = y)
5804 ==> dimindex(:M) <= dimindex(:N)`,
5805 REWRITE_TAC[GSYM DIM_UNIV] THEN REPEAT GEN_TAC THEN DISCH_THEN
5806 (SUBST1_TAC o SYM o SPEC `(:real^M)` o
5807 MATCH_MP DIM_INJECTIVE_LINEAR_IMAGE) THEN
5808 MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]);;
5810 let LINEAR_SURJECTIVE_DIMINDEX_LE = prove
5811 (`!f:real^M->real^N.
5812 linear f /\ (!y. ?x. f x = y)
5813 ==> dimindex(:N) <= dimindex(:M)`,
5814 REPEAT GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM
5815 (MP_TAC o MATCH_MP LINEAR_SURJECTIVE_RIGHT_INVERSE) THEN
5816 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM; LEFT_IMP_EXISTS_THM] THEN
5817 X_GEN_TAC `g:real^N->real^M` THEN STRIP_TAC THEN
5818 MATCH_MP_TAC LINEAR_INJECTIVE_DIMINDEX_LE THEN
5819 EXISTS_TAC `g:real^N->real^M` THEN ASM_MESON_TAC[]);;
5821 let LINEAR_BIJECTIVE_DIMINDEX_EQ = prove
5822 (`!f:real^M->real^N.
5823 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
5824 ==> dimindex(:M) = dimindex(:N)`,
5825 REWRITE_TAC[GSYM LE_ANTISYM] THEN REPEAT STRIP_TAC THENL
5826 [MATCH_MP_TAC LINEAR_INJECTIVE_DIMINDEX_LE;
5827 MATCH_MP_TAC LINEAR_SURJECTIVE_DIMINDEX_LE] THEN
5828 EXISTS_TAC `f:real^M->real^N` THEN ASM_REWRITE_TAC[]);;
5830 let INVERTIBLE_IMP_SQUARE_MATRIX = prove
5831 (`!A:real^N^M. invertible A ==> dimindex(:M) = dimindex(:N)`,
5832 GEN_TAC THEN REWRITE_TAC[invertible; LEFT_IMP_EXISTS_THM] THEN
5833 X_GEN_TAC `B:real^M^N` THEN STRIP_TAC THEN
5834 MATCH_MP_TAC LINEAR_BIJECTIVE_DIMINDEX_EQ THEN
5835 EXISTS_TAC `\x:real^M. (B:real^M^N) ** x` THEN
5836 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR;
5837 GSYM MATRIX_LEFT_INVERTIBLE_INJECTIVE;
5838 GSYM MATRIX_RIGHT_INVERTIBLE_SURJECTIVE] THEN
5841 (* ------------------------------------------------------------------------- *)
5842 (* Considering an n-element vector as an n-by-1 or 1-by-n matrix. *)
5843 (* ------------------------------------------------------------------------- *)
5845 let rowvector = new_definition
5846 `(rowvector:real^N->real^N^1) v = lambda i j. v$j`;;
5848 let columnvector = new_definition
5849 `(columnvector:real^N->real^1^N) v = lambda i j. v$i`;;
5851 let TRANSP_COLUMNVECTOR = prove
5852 (`!v. transp(columnvector v) = rowvector v`,
5853 SIMP_TAC[transp; columnvector; rowvector; CART_EQ; LAMBDA_BETA]);;
5855 let TRANSP_ROWVECTOR = prove
5856 (`!v. transp(rowvector v) = columnvector v`,
5857 SIMP_TAC[transp; columnvector; rowvector; CART_EQ; LAMBDA_BETA]);;
5859 let DOT_ROWVECTOR_COLUMNVECTOR = prove
5860 (`!A:real^N^M v:real^N. columnvector(A ** v) = A ** columnvector v`,
5861 REWRITE_TAC[rowvector; columnvector; matrix_mul; matrix_vector_mul] THEN
5862 SIMP_TAC[CART_EQ; LAMBDA_BETA]);;
5864 let DOT_MATRIX_PRODUCT = prove
5865 (`!x y:real^N. x dot y = (rowvector x ** columnvector y)$1$1`,
5866 REWRITE_TAC[matrix_mul; columnvector; rowvector; dot] THEN
5867 SIMP_TAC[LAMBDA_BETA; DIMINDEX_1; LE_REFL]);;
5869 let DOT_MATRIX_VECTOR_MUL = prove
5870 (`!A:real^N^N B:real^N^N x:real^N y:real^N.
5871 (A ** x) dot (B ** y) =
5872 ((rowvector x) ** (transp(A) ** B) ** (columnvector y))$1$1`,
5873 REWRITE_TAC[DOT_MATRIX_PRODUCT] THEN
5874 ONCE_REWRITE_TAC[GSYM TRANSP_COLUMNVECTOR] THEN
5875 REWRITE_TAC[DOT_ROWVECTOR_COLUMNVECTOR; MATRIX_TRANSP_MUL] THEN
5876 REWRITE_TAC[MATRIX_MUL_ASSOC]);;
5878 (* ------------------------------------------------------------------------- *)
5879 (* Rank of a matrix. Equivalence of row and column rank is taken from *)
5880 (* George Mackiw's paper, Mathematics Magazine 1995, p. 285. *)
5881 (* ------------------------------------------------------------------------- *)
5883 let MATRIX_VECTOR_MUL_IN_COLUMNSPACE = prove
5884 (`!A:real^M^N x:real^M. (A ** x) IN span(columns A)`,
5885 REPEAT GEN_TAC THEN REWRITE_TAC[MATRIX_VECTOR_COLUMN; columns] THEN
5886 MATCH_MP_TAC SPAN_VSUM THEN
5887 SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; transp; LAMBDA_BETA] THEN
5888 X_GEN_TAC `k:num` THEN STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
5889 MATCH_MP_TAC SPAN_SUPERSET THEN
5890 REWRITE_TAC[IN_ELIM_THM; column] THEN EXISTS_TAC `k:num` THEN
5891 ASM_REWRITE_TAC[]);;
5893 let SUBSPACE_ORTHOGONAL_TO_VECTOR = prove
5894 (`!x. subspace {y | orthogonal x y}`,
5895 SIMP_TAC[subspace; IN_ELIM_THM; ORTHOGONAL_CLAUSES]);;
5897 let SUBSPACE_ORTHOGONAL_TO_VECTORS = prove
5898 (`!s. subspace {y | (!x. x IN s ==> orthogonal x y)}`,
5899 SIMP_TAC[subspace; IN_ELIM_THM; ORTHOGONAL_CLAUSES]);;
5901 let ORTHOGONAL_TO_SPAN = prove
5902 (`!s x. (!y. y IN s ==> orthogonal x y)
5903 ==> !y. y IN span(s) ==> orthogonal x y`,
5904 REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN
5905 REWRITE_TAC[SET_RULE `(\y. orthogonal x y) = {y | orthogonal x y}`] THEN
5906 ASM_SIMP_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR; IN_ELIM_THM]);;
5908 let ORTHOGONAL_TO_SPAN_EQ = prove
5909 (`!s x. (!y. y IN span(s) ==> orthogonal x y) <=>
5910 (!y. y IN s ==> orthogonal x y)`,
5911 MESON_TAC[SPAN_SUPERSET; ORTHOGONAL_TO_SPAN]);;
5913 let ORTHOGONAL_TO_SPANS_EQ = prove
5914 (`!s t. (!x y. x IN span(s) /\ y IN span(t) ==> orthogonal x y) <=>
5915 (!x y. x IN s /\ y IN t ==> orthogonal x y)`,
5916 MESON_TAC[ORTHOGONAL_TO_SPAN_EQ; ORTHOGONAL_SYM]);;
5918 let ORTHOGONAL_NULLSPACE_ROWSPACE = prove
5919 (`!A:real^M^N x y:real^M.
5920 A ** x = vec 0 /\ y IN span(rows A) ==> orthogonal x y`,
5921 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
5922 REPEAT GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN
5923 REWRITE_TAC[SET_RULE `(\y. orthogonal x y) = {y | orthogonal x y}`] THEN
5924 REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR; rows; FORALL_IN_GSPEC] THEN
5925 X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
5926 FIRST_X_ASSUM(MP_TAC o AP_TERM `\y:real^N. y$k`) THEN
5927 ASM_SIMP_TAC[MATRIX_VECTOR_MUL_COMPONENT; VEC_COMPONENT; row; dot;
5928 orthogonal; LAMBDA_BETA] THEN
5929 REWRITE_TAC[REAL_MUL_SYM]);;
5931 let NULLSPACE_INTER_ROWSPACE = prove
5932 (`!A:real^M^N x:real^M. A ** x = vec 0 /\ x IN span(rows A) <=> x = vec 0`,
5933 REPEAT GEN_TAC THEN EQ_TAC THENL
5934 [MESON_TAC[ORTHOGONAL_NULLSPACE_ROWSPACE; ORTHOGONAL_REFL];
5935 SIMP_TAC[MATRIX_VECTOR_MUL_RZERO; SPAN_0]]);;
5937 let MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE = prove
5938 (`!A:real^M^N x y:real^M.
5939 x IN span(rows A) /\ y IN span(rows A) /\ A ** x = A ** y ==> x = y`,
5940 ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
5941 REWRITE_TAC[GSYM MATRIX_VECTOR_MUL_SUB_LDISTRIB] THEN
5942 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM NULLSPACE_INTER_ROWSPACE] THEN
5943 ASM_SIMP_TAC[SPAN_SUB]);;
5945 let DIM_ROWS_LE_DIM_COLUMNS = prove
5946 (`!A:real^M^N. dim(rows A) <= dim(columns A)`,
5947 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
5948 X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC
5949 (ISPEC `span(rows(A:real^M^N))` BASIS_EXISTS) THEN
5950 SUBGOAL_THEN `FINITE(IMAGE (\x:real^M. (A:real^M^N) ** x) b) /\
5951 CARD (IMAGE (\x:real^M. (A:real^M^N) ** x) b) <=
5952 dim(span(columns A))`
5954 [MATCH_MP_TAC INDEPENDENT_CARD_LE_DIM THEN
5955 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; MATRIX_VECTOR_MUL_IN_COLUMNSPACE] THEN
5956 MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN
5957 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN
5958 SUBGOAL_THEN `span(b) = span(rows(A:real^M^N))` SUBST1_TAC THENL
5959 [ALL_TAC; ASM_MESON_TAC[MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE]] THEN
5960 MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN
5961 GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_SPAN] THEN
5962 ASM_SIMP_TAC[SPAN_MONO];
5963 DISCH_THEN(MP_TAC o CONJUNCT2) THEN MATCH_MP_TAC EQ_IMP THEN
5964 AP_THM_TAC THEN AP_TERM_TAC THEN
5965 FIRST_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM) o
5966 GEN_REWRITE_RULE I [HAS_SIZE]) THEN
5967 MATCH_MP_TAC CARD_IMAGE_INJ THEN ASM_REWRITE_TAC[] THEN
5968 REPEAT STRIP_TAC THEN MATCH_MP_TAC
5969 (ISPEC `A:real^M^N` MATRIX_VECTOR_MUL_INJECTIVE_ON_ROWSPACE) THEN
5972 let rank = new_definition
5973 `rank(A:real^M^N) = dim(columns A)`;;
5975 let RANK_ROW = prove
5976 (`!A:real^M^N. rank(A) = dim(rows A)`,
5977 GEN_TAC THEN REWRITE_TAC[rank] THEN
5978 MP_TAC(ISPEC `A:real^M^N` DIM_ROWS_LE_DIM_COLUMNS) THEN
5979 MP_TAC(ISPEC `transp(A:real^M^N)` DIM_ROWS_LE_DIM_COLUMNS) THEN
5980 REWRITE_TAC[ROWS_TRANSP; COLUMNS_TRANSP] THEN ARITH_TAC);;
5982 let RANK_TRANSP = prove
5983 (`!A:real^M^N. rank(transp A) = rank A`,
5984 GEN_TAC THEN GEN_REWRITE_TAC RAND_CONV [RANK_ROW] THEN
5985 REWRITE_TAC[rank; COLUMNS_TRANSP]);;
5987 let MATRIX_VECTOR_MUL_BASIS = prove
5988 (`!A:real^M^N k. 1 <= k /\ k <= dimindex(:M)
5989 ==> A ** (basis k) = column k A`,
5990 SIMP_TAC[CART_EQ; column; MATRIX_VECTOR_MUL_COMPONENT; DOT_BASIS;
5993 let COLUMNS_IMAGE_BASIS = prove
5995 columns A = IMAGE (\x. A ** x) {basis i | 1 <= i /\ i <= dimindex(:M)}`,
5996 GEN_TAC THEN REWRITE_TAC[columns] THEN
5997 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
5998 REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN
5999 MATCH_MP_TAC(SET_RULE
6000 `(!x. x IN s ==> f x = g x) ==> IMAGE f s = IMAGE g s`) THEN
6001 SIMP_TAC[IN_ELIM_THM; MATRIX_VECTOR_MUL_BASIS]);;
6003 let RANK_DIM_IM = prove
6004 (`!A:real^M^N. rank A = dim(IMAGE (\x. A ** x) (:real^M))`,
6005 GEN_TAC THEN REWRITE_TAC[rank] THEN
6006 MATCH_MP_TAC SPAN_EQ_DIM THEN REWRITE_TAC[COLUMNS_IMAGE_BASIS] THEN
6007 SIMP_TAC[SPAN_LINEAR_IMAGE; MATRIX_VECTOR_MUL_LINEAR] THEN
6008 AP_TERM_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM SPAN_SPAN] THEN
6009 REWRITE_TAC[SPAN_STDBASIS]);;
6011 let DIM_EQ_SPAN = prove
6012 (`!s t:real^N->bool. s SUBSET t /\ dim t <= dim s ==> span s = span t`,
6013 REPEAT STRIP_TAC THEN
6014 X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC
6015 (ISPEC `span s:real^N->bool` BASIS_EXISTS) THEN
6016 MP_TAC(ISPECL [`span t:real^N->bool`; `b:real^N->bool`]
6017 CARD_GE_DIM_INDEPENDENT) THEN
6018 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
6019 ASM_REWRITE_TAC[DIM_SPAN] THEN
6020 ASM_MESON_TAC[SPAN_MONO; SPAN_SPAN; SUBSET_TRANS; SUBSET_ANTISYM]);;
6022 let DIM_EQ_FULL = prove
6023 (`!s:real^N->bool. dim s = dimindex(:N) <=> span s = (:real^N)`,
6024 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN EQ_TAC THEN
6025 SIMP_TAC[DIM_UNIV] THEN DISCH_TAC THEN
6026 GEN_REWRITE_TAC RAND_CONV [GSYM SPAN_UNIV] THEN MATCH_MP_TAC DIM_EQ_SPAN THEN
6027 ASM_REWRITE_TAC[SUBSET_UNIV; DIM_UNIV] THEN
6028 ASM_MESON_TAC[LE_REFL; DIM_SPAN]);;
6030 let DIM_PSUBSET = prove
6031 (`!s t. (span s) PSUBSET (span t) ==> dim s < dim t`,
6032 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
6033 SIMP_TAC[PSUBSET; DIM_SUBSET; LT_LE] THEN
6034 MESON_TAC[EQ_IMP_LE; DIM_EQ_SPAN; SPAN_SPAN]);;
6036 let RANK_BOUND = prove
6037 (`!A:real^M^N. rank(A) <= MIN (dimindex(:M)) (dimindex(:N))`,
6038 GEN_TAC THEN REWRITE_TAC[ARITH_RULE `x <= MIN a b <=> x <= a /\ x <= b`] THEN
6040 [REWRITE_TAC[DIM_SUBSET_UNIV; RANK_ROW];
6041 REWRITE_TAC[DIM_SUBSET_UNIV; rank]]);;
6043 let FULL_RANK_INJECTIVE = prove
6045 rank A = dimindex(:M) <=>
6046 (!x y:real^M. A ** x = A ** y ==> x = y)`,
6047 REWRITE_TAC[GSYM MATRIX_LEFT_INVERTIBLE_INJECTIVE] THEN
6048 REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_SPAN_ROWS] THEN
6049 REWRITE_TAC[RANK_ROW; DIM_EQ_FULL]);;
6051 let FULL_RANK_SURJECTIVE = prove
6053 rank A = dimindex(:N) <=> (!y:real^N. ?x:real^M. A ** x = y)`,
6054 REWRITE_TAC[GSYM MATRIX_RIGHT_INVERTIBLE_SURJECTIVE] THEN
6055 REWRITE_TAC[GSYM LEFT_INVERTIBLE_TRANSP] THEN
6056 REWRITE_TAC[MATRIX_LEFT_INVERTIBLE_INJECTIVE] THEN
6057 REWRITE_TAC[GSYM FULL_RANK_INJECTIVE; RANK_TRANSP]);;
6060 (`rank(mat 1:real^N^N) = dimindex(:N)`,
6061 REWRITE_TAC[FULL_RANK_INJECTIVE; MATRIX_VECTOR_MUL_LID]);;
6063 let MATRIX_FULL_LINEAR_EQUATIONS = prove
6064 (`!A:real^M^N b:real^N.
6065 rank A = dimindex(:N) ==> ?x. A ** x = b`,
6066 SIMP_TAC[FULL_RANK_SURJECTIVE]);;
6068 let MATRIX_NONFULL_LINEAR_EQUATIONS_EQ = prove
6070 (?x. ~(x = vec 0) /\ A ** x = vec 0) <=> ~(rank A = dimindex(:M))`,
6071 REPEAT GEN_TAC THEN REWRITE_TAC[FULL_RANK_INJECTIVE] THEN
6072 SIMP_TAC[LINEAR_INJECTIVE_0; MATRIX_VECTOR_MUL_LINEAR] THEN
6075 let MATRIX_NONFULL_LINEAR_EQUATIONS = prove
6077 ~(rank A = dimindex(:M)) ==> ?x. ~(x = vec 0) /\ A ** x = vec 0`,
6078 REWRITE_TAC[MATRIX_NONFULL_LINEAR_EQUATIONS_EQ]);;
6080 let MATRIX_TRIVIAL_LINEAR_EQUATIONS = prove
6082 dimindex(:N) < dimindex(:M)
6083 ==> ?x. ~(x = vec 0) /\ A ** x = vec 0`,
6084 REPEAT STRIP_TAC THEN MATCH_MP_TAC MATRIX_NONFULL_LINEAR_EQUATIONS THEN
6085 MATCH_MP_TAC(ARITH_RULE
6086 `!a. x <= MIN b a /\ a < b ==> ~(x = b)`) THEN
6087 EXISTS_TAC `dimindex(:N)` THEN ASM_REWRITE_TAC[RANK_BOUND]);;
6089 let RANK_EQ_0 = prove
6090 (`!A:real^M^N. rank A = 0 <=> A = mat 0`,
6091 REWRITE_TAC[RANK_DIM_IM; DIM_EQ_0; SUBSET; FORALL_IN_IMAGE; IN_SING;
6093 GEN_TAC THEN GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [CART_EQ] THEN
6094 SIMP_TAC[CART_EQ; MATRIX_MUL_DOT; VEC_COMPONENT; LAMBDA_BETA; mat] THEN
6095 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
6096 REWRITE_TAC[RIGHT_FORALL_IMP_THM; FORALL_DOT_EQ_0; COND_ID] THEN
6097 REWRITE_TAC[CART_EQ; VEC_COMPONENT]);;
6101 REWRITE_TAC[RANK_EQ_0]);;
6103 let RANK_MUL_LE_RIGHT = prove
6104 (`!A:real^N^M B:real^P^N. rank(A ** B) <= rank(B)`,
6105 REPEAT GEN_TAC THEN MATCH_MP_TAC LE_TRANS THEN
6106 EXISTS_TAC `dim(IMAGE (\y. (A:real^N^M) ** y)
6107 (IMAGE (\x. (B:real^P^N) ** x) (:real^P)))` THEN
6108 REWRITE_TAC[RANK_DIM_IM] THEN CONJ_TAC THENL
6109 [REWRITE_TAC[GSYM IMAGE_o; o_DEF; MATRIX_VECTOR_MUL_ASSOC; LE_REFL];
6110 MATCH_MP_TAC DIM_LINEAR_IMAGE_LE THEN
6111 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]]);;
6113 let RANK_MUL_LE_LEFT = prove
6114 (`!A:real^N^M B:real^P^N. rank(A ** B) <= rank(A)`,
6115 ONCE_REWRITE_TAC[GSYM RANK_TRANSP] THEN
6116 REWRITE_TAC[MATRIX_TRANSP_MUL] THEN
6117 REWRITE_TAC[RANK_MUL_LE_RIGHT]);;
6119 (* ------------------------------------------------------------------------- *)
6120 (* Some bounds on components etc. relative to operator norm. *)
6121 (* ------------------------------------------------------------------------- *)
6123 let NORM_COLUMN_LE_ONORM = prove
6124 (`!A:real^N^M i. norm(column i A) <= onorm(\x. A ** x)`,
6125 REPEAT STRIP_TAC THEN REWRITE_TAC[column] THEN
6126 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$i = z$l`
6127 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6128 MP_TAC(ISPEC `\x:real^N. (A:real^N^M) ** x` ONORM) THEN
6129 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR] THEN
6130 DISCH_THEN(MP_TAC o SPEC `basis l:real^N` o CONJUNCT1) THEN
6131 ASM_SIMP_TAC[MATRIX_VECTOR_MUL_BASIS; NORM_BASIS; column; REAL_MUL_RID]);;
6133 let MATRIX_COMPONENT_LE_ONORM = prove
6134 (`!A:real^N^M i j. abs(A$i$j) <= onorm(\x. A ** x)`,
6136 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:M) /\ !A:real^N^M. A$i = A$k`
6137 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6138 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$j = z$l`
6139 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6140 ASM_REWRITE_TAC[] THEN
6141 MATCH_MP_TAC REAL_LE_TRANS THEN
6142 EXISTS_TAC `norm(column l (A:real^N^M))` THEN
6143 REWRITE_TAC[NORM_COLUMN_LE_ONORM] THEN
6144 MP_TAC(ISPECL [`column l (A:real^N^M)`; `k:num`]
6145 COMPONENT_LE_NORM) THEN
6146 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
6147 ASM_SIMP_TAC[column; LAMBDA_BETA; REAL_LE_REFL]);;
6149 let COMPONENT_LE_ONORM = prove
6150 (`!f:real^M->real^N i j. linear f ==> abs(matrix f$i$j) <= onorm f`,
6151 REPEAT STRIP_TAC THEN
6152 FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o RAND_CONV)
6153 [MATCH_MP MATRIX_VECTOR_MUL th]) THEN
6154 REWRITE_TAC[MATRIX_COMPONENT_LE_ONORM]);;
6156 (* ------------------------------------------------------------------------- *)
6157 (* Basic lemmas about hyperplanes and halfspaces. *)
6158 (* ------------------------------------------------------------------------- *)
6160 let HYPERPLANE_EQ_EMPTY = prove
6161 (`!a:real^N b. {x | a dot x = b} = {} <=> a = vec 0 /\ ~(b = &0)`,
6162 REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN
6163 ASM_CASES_TAC `a:real^N = vec 0` THEN ASM_REWRITE_TAC[DOT_LZERO] THENL
6165 DISCH_THEN(MP_TAC o SPEC `b / (a dot a) % a:real^N`) THEN
6166 ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0]]);;
6168 let HYPERPLANE_EQ_UNIV = prove
6169 (`!a b. {x | a dot x = b} = (:real^N) <=> a = vec 0 /\ b = &0`,
6170 REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_UNIV] THEN
6171 ASM_CASES_TAC `a:real^N = vec 0` THEN ASM_REWRITE_TAC[DOT_LZERO] THENL
6173 DISCH_THEN(MP_TAC o SPEC `(b + &1) / (a dot a) % a:real^N`) THEN
6174 ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0] THEN REAL_ARITH_TAC]);;
6176 let HALFSPACE_EQ_EMPTY_LT = prove
6177 (`!a:real^N b. {x | a dot x < b} = {} <=> a = vec 0 /\ b <= &0`,
6178 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL
6179 [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN
6180 COND_CASES_TAC THEN REWRITE_TAC[UNIV_NOT_EMPTY] THEN ASM_REAL_ARITH_TAC;
6181 ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
6182 EXISTS_TAC `(b - &1) / (a dot a) % a:real^N` THEN
6183 ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0] THEN
6186 let HALFSPACE_EQ_EMPTY_GT = prove
6187 (`!a:real^N b. {x | a dot x > b} = {} <=> a = vec 0 /\ b >= &0`,
6189 MP_TAC(ISPECL [`--a:real^N`; `--b:real`] HALFSPACE_EQ_EMPTY_LT) THEN
6190 SIMP_TAC[real_gt; DOT_LNEG; REAL_LT_NEG2; VECTOR_NEG_EQ_0] THEN
6191 DISCH_TAC THEN AP_TERM_TAC THEN REAL_ARITH_TAC);;
6193 let HALFSPACE_EQ_EMPTY_LE = prove
6194 (`!a:real^N b. {x | a dot x <= b} = {} <=> a = vec 0 /\ b < &0`,
6195 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THENL
6196 [ASM_SIMP_TAC[DOT_LZERO; SET_RULE `{x | p} = if p then UNIV else {}`] THEN
6197 COND_CASES_TAC THEN REWRITE_TAC[UNIV_NOT_EMPTY] THEN ASM_REAL_ARITH_TAC;
6198 ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
6199 EXISTS_TAC `(b - &1) / (a dot a) % a:real^N` THEN
6200 ASM_SIMP_TAC[DOT_RMUL; REAL_DIV_RMUL; DOT_EQ_0] THEN
6203 let HALFSPACE_EQ_EMPTY_GE = prove
6204 (`!a:real^N b. {x | a dot x >= b} = {} <=> a = vec 0 /\ b > &0`,
6206 MP_TAC(ISPECL [`--a:real^N`; `--b:real`] HALFSPACE_EQ_EMPTY_LE) THEN
6207 SIMP_TAC[real_ge; DOT_LNEG; REAL_LE_NEG2; VECTOR_NEG_EQ_0] THEN
6208 DISCH_TAC THEN AP_TERM_TAC THEN REAL_ARITH_TAC);;
6210 (* ------------------------------------------------------------------------- *)
6211 (* A non-injective linear function maps into a hyperplane. *)
6212 (* ------------------------------------------------------------------------- *)
6214 let ADJOINT_INJECTIVE = prove
6215 (`!f:real^M->real^N.
6217 ==> ((!x y. adjoint f x = adjoint f y ==> x = y) <=>
6218 (!y. ?x. f x = y))`,
6219 REPEAT STRIP_TAC THEN
6220 FIRST_ASSUM(ASSUME_TAC o GSYM o MATCH_MP MATRIX_WORKS o MATCH_MP
6221 ADJOINT_LINEAR) THEN
6222 FIRST_ASSUM(ASSUME_TAC o GSYM o MATCH_MP MATRIX_WORKS) THEN
6223 ASM_REWRITE_TAC[GSYM FULL_RANK_INJECTIVE; GSYM FULL_RANK_SURJECTIVE] THEN
6224 ASM_SIMP_TAC[MATRIX_ADJOINT; RANK_TRANSP]);;
6226 let ADJOINT_SURJECTIVE = prove
6227 (`!f:real^M->real^N.
6229 ==> ((!y. ?x. adjoint f x = y) <=> (!x y. f x = f y ==> x = y))`,
6230 REPEAT STRIP_TAC THEN
6231 FIRST_ASSUM(fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV)
6232 [GSYM(MATCH_MP ADJOINT_ADJOINT th)]) THEN
6233 ASM_SIMP_TAC[ADJOINT_INJECTIVE; ADJOINT_LINEAR]);;
6235 let ADJOINT_INJECTIVE_INJECTIVE = prove
6236 (`!f:real^N->real^N.
6238 ==> ((!x y. adjoint f x = adjoint f y ==> x = y) <=>
6239 (!x y. f x = f y ==> x = y))`,
6240 SIMP_TAC[ADJOINT_INJECTIVE] THEN
6241 MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE;
6242 LINEAR_SURJECTIVE_IMP_INJECTIVE]);;
6244 let ADJOINT_INJECTIVE_INJECTIVE_0 = prove
6245 (`!f:real^N->real^N.
6247 ==> ((!x. adjoint f x = vec 0 ==> x = vec 0) <=>
6248 (!x. f x = vec 0 ==> x = vec 0))`,
6249 REPEAT STRIP_TAC THEN
6250 FIRST_ASSUM(MP_TAC o MATCH_MP ADJOINT_INJECTIVE_INJECTIVE) THEN
6251 FIRST_ASSUM(ASSUME_TAC o MATCH_MP ADJOINT_LINEAR) THEN
6252 ASM_MESON_TAC[LINEAR_INJECTIVE_0]);;
6254 let LINEAR_SINGULAR_INTO_HYPERPLANE = prove
6255 (`!f:real^N->real^N.
6257 ==> (~(!x y. f(x) = f(y) ==> x = y) <=>
6258 ?a. ~(a = vec 0) /\ !x. a dot f(x) = &0)`,
6259 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[DOT_SYM] THEN
6260 ASM_SIMP_TAC[ADJOINT_WORKS; FORALL_DOT_EQ_0] THEN
6261 REWRITE_TAC[MESON[] `(?a. ~p a /\ q a) <=> ~(!a. q a ==> p a)`] THEN
6262 ASM_SIMP_TAC[ADJOINT_INJECTIVE_INJECTIVE_0; LINEAR_INJECTIVE_0]);;
6264 let LINEAR_SINGULAR_IMAGE_HYPERPLANE = prove
6265 (`!f:real^N->real^N.
6266 linear f /\ ~(!x y. f(x) = f(y) ==> x = y)
6267 ==> ?a. ~(a = vec 0) /\ !s. IMAGE f s SUBSET {x | a dot x = &0}`,
6268 GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6269 ASM_SIMP_TAC[LINEAR_SINGULAR_INTO_HYPERPLANE] THEN
6270 SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[]);;
6272 let LOWDIM_EXPAND_DIMENSION = prove
6273 (`!s:real^N->bool n.
6274 dim s <= n /\ n <= dimindex(:N)
6275 ==> ?t. dim(t) = n /\ span s SUBSET span t`,
6277 GEN_REWRITE_TAC (BINDER_CONV o LAND_CONV o LAND_CONV) [LE_EXISTS] THEN
6278 SIMP_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN
6279 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
6280 REWRITE_TAC[RIGHT_FORALL_IMP_THM; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
6281 INDUCT_TAC THENL [MESON_TAC[ADD_CLAUSES; SUBSET_REFL]; ALL_TAC] THEN
6282 REWRITE_TAC[ARITH_RULE `s + SUC d <= n <=> s + d < n`] THEN
6283 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
6284 ASM_SIMP_TAC[LT_IMP_LE; LEFT_IMP_EXISTS_THM] THEN
6285 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
6286 REWRITE_TAC[ADD_CLAUSES] THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
6287 SUBGOAL_THEN `~(span t = (:real^N))` MP_TAC THENL
6288 [REWRITE_TAC[GSYM DIM_EQ_FULL] THEN ASM_ARITH_TAC; ALL_TAC] THEN
6289 REWRITE_TAC[EXTENSION; IN_UNIV; NOT_FORALL_THM; LEFT_IMP_EXISTS_THM] THEN
6290 X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN
6291 EXISTS_TAC `(a:real^N) INSERT t` THEN ASM_REWRITE_TAC[DIM_INSERT; ADD1] THEN
6292 MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `span(t:real^N->bool)` THEN
6293 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SPAN_MONO THEN SET_TAC[]);;
6295 let LOWDIM_EXPAND_BASIS = prove
6296 (`!s:real^N->bool n.
6297 dim s <= n /\ n <= dimindex(:N)
6298 ==> ?b. b HAS_SIZE n /\ independent b /\ span s SUBSET span b`,
6299 REPEAT GEN_TAC THEN DISCH_TAC THEN
6300 FIRST_ASSUM(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC o
6301 MATCH_MP LOWDIM_EXPAND_DIMENSION) THEN
6302 MP_TAC(ISPEC `t:real^N->bool` BASIS_EXISTS) THEN
6303 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N->bool` THEN
6304 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
6305 ASM_MESON_TAC[SPAN_SPAN; SUBSET_TRANS; SPAN_MONO]);;
6307 (* ------------------------------------------------------------------------- *)
6308 (* Orthogonal bases, Gram-Schmidt process, and related theorems. *)
6309 (* ------------------------------------------------------------------------- *)
6311 let SPAN_DELETE_0 = prove
6312 (`!s:real^N->bool. span(s DELETE vec 0) = span s`,
6313 GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
6314 SIMP_TAC[DELETE_SUBSET; SPAN_MONO] THEN
6315 MATCH_MP_TAC SUBSET_TRANS THEN
6316 EXISTS_TAC `span((vec 0:real^N) INSERT (s DELETE vec 0))` THEN CONJ_TAC THENL
6317 [MATCH_MP_TAC SPAN_MONO THEN SET_TAC[];
6318 SIMP_TAC[SUBSET; SPAN_BREAKDOWN_EQ; VECTOR_MUL_RZERO; VECTOR_SUB_RZERO]]);;
6320 let SPAN_IMAGE_SCALE = prove
6321 (`!c s. FINITE s /\ (!x. x IN s ==> ~(c x = &0))
6322 ==> span (IMAGE (\x:real^N. c(x) % x) s) = span s`,
6323 GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
6324 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
6325 SIMP_TAC[IMAGE_CLAUSES; SPAN_BREAKDOWN_EQ; EXTENSION; FORALL_IN_INSERT] THEN
6326 MAP_EVERY X_GEN_TAC [`x:real^N`; `t:real^N->bool`] THEN
6327 STRIP_TAC THEN STRIP_TAC THEN X_GEN_TAC `y:real^N` THEN
6328 REWRITE_TAC[VECTOR_MUL_ASSOC] THEN EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
6329 DISCH_THEN(X_CHOOSE_TAC `k:real`) THEN
6330 EXISTS_TAC `k / (c:real^N->real) x` THEN
6331 ASM_SIMP_TAC[REAL_DIV_RMUL]);;
6333 let PAIRWISE_ORTHOGONAL_INDEPENDENT = prove
6335 pairwise orthogonal s /\ ~(vec 0 IN s) ==> independent s`,
6336 REWRITE_TAC[pairwise; orthogonal] THEN REPEAT STRIP_TAC THEN
6337 REWRITE_TAC[independent; dependent] THEN
6338 DISCH_THEN(X_CHOOSE_THEN `a:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6339 REWRITE_TAC[SPAN_EXPLICIT; IN_ELIM_THM; NOT_EXISTS_THM] THEN
6340 MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:real^N->real`] THEN
6341 REWRITE_TAC[SUBSET; IN_DELETE] THEN STRIP_TAC THEN
6342 FIRST_X_ASSUM(MP_TAC o AP_TERM `\x:real^N. a dot x`) THEN
6343 ASM_SIMP_TAC[DOT_RSUM; DOT_RMUL; REAL_MUL_RZERO; SUM_0] THEN
6344 ASM_MESON_TAC[DOT_EQ_0]);;
6346 let PAIRWISE_ORTHOGONAL_IMP_FINITE = prove
6347 (`!s:real^N->bool. pairwise orthogonal s ==> FINITE s`,
6348 REPEAT STRIP_TAC THEN
6349 SUBGOAL_THEN `independent (s DELETE (vec 0:real^N))` MP_TAC THENL
6350 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN
6351 REWRITE_TAC[IN_DELETE] THEN MATCH_MP_TAC PAIRWISE_MONO THEN
6352 EXISTS_TAC `s:real^N->bool` THEN
6353 ASM_SIMP_TAC[SUBSET; IN_DELETE];
6354 DISCH_THEN(MP_TAC o MATCH_MP INDEPENDENT_IMP_FINITE) THEN
6355 REWRITE_TAC[FINITE_DELETE]]);;
6357 let GRAM_SCHMIDT_STEP = prove
6359 pairwise orthogonal s /\ x IN span s
6360 ==> orthogonal x (a - vsum s (\b:real^N. (b dot a) / (b dot b) % b))`,
6361 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
6362 REWRITE_TAC[ONCE_REWRITE_RULE[ORTHOGONAL_SYM] ORTHOGONAL_TO_SPAN_EQ] THEN
6363 X_GEN_TAC `s:real^N->bool` THEN STRIP_TAC THEN
6364 MAP_EVERY X_GEN_TAC [`a:real^N`; `x:real^N`] THEN DISCH_TAC THEN
6365 FIRST_ASSUM(ASSUME_TAC o MATCH_MP PAIRWISE_ORTHOGONAL_IMP_FINITE) THEN
6366 REWRITE_TAC[orthogonal; DOT_RSUB] THEN ASM_SIMP_TAC[DOT_RSUM] THEN
6367 REWRITE_TAC[REAL_SUB_0; DOT_RMUL] THEN MATCH_MP_TAC EQ_TRANS THEN
6368 EXISTS_TAC `sum s (\y:real^N. if y = x then y dot a else &0)` THEN
6369 CONJ_TAC THENL [ASM_SIMP_TAC[SUM_DELTA; DOT_SYM]; ALL_TAC] THEN
6370 MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
6371 RULE_ASSUM_TAC(REWRITE_RULE[pairwise; orthogonal]) THEN
6372 ASM_CASES_TAC `x:real^N = y` THEN ASM_SIMP_TAC[DOT_LMUL; REAL_MUL_RZERO] THEN
6373 ASM_CASES_TAC `y:real^N = vec 0` THEN
6374 ASM_SIMP_TAC[REAL_DIV_RMUL; DOT_EQ_0; DOT_LZERO; REAL_MUL_RZERO]);;
6376 let ORTHOGONAL_EXTENSION = prove
6377 (`!s t:real^N->bool.
6378 pairwise orthogonal s
6379 ==> ?u. pairwise orthogonal (s UNION u) /\
6380 span (s UNION u) = span (s UNION t)`,
6382 (`!t s:real^N->bool.
6383 FINITE t /\ FINITE s /\ pairwise orthogonal s
6384 ==> ?u. pairwise orthogonal (s UNION u) /\
6385 span (s UNION u) = span (s UNION t)`,
6386 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
6387 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN CONJ_TAC THENL
6388 [REPEAT STRIP_TAC THEN EXISTS_TAC `{}:real^N->bool` THEN
6389 ASM_REWRITE_TAC[UNION_EMPTY];
6391 MAP_EVERY X_GEN_TAC [`a:real^N`; `t:real^N->bool`] THEN
6392 REWRITE_TAC[pairwise; orthogonal] THEN REPEAT STRIP_TAC THEN
6393 ABBREV_TAC `a' = a - vsum s (\b:real^N. (b dot a) / (b dot b) % b)` THEN
6394 FIRST_X_ASSUM(MP_TAC o SPEC `(a':real^N) INSERT s`) THEN
6395 ASM_REWRITE_TAC[FINITE_INSERT] THEN ANTS_TAC THENL
6396 [SUBGOAL_THEN `!x:real^N. x IN s ==> a' dot x = &0`
6397 (fun th -> REWRITE_TAC[IN_INSERT] THEN ASM_MESON_TAC[DOT_SYM; th]) THEN
6398 REPEAT STRIP_TAC THEN EXPAND_TAC "a'" THEN
6399 REWRITE_TAC[GSYM orthogonal] THEN ONCE_REWRITE_TAC[ORTHOGONAL_SYM] THEN
6400 MATCH_MP_TAC GRAM_SCHMIDT_STEP THEN
6401 ASM_SIMP_TAC[pairwise; orthogonal; SPAN_CLAUSES];
6402 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
6403 EXISTS_TAC `(a':real^N) INSERT u` THEN
6404 ASM_REWRITE_TAC[SET_RULE `s UNION a INSERT u = a INSERT s UNION u`] THEN
6405 REWRITE_TAC[SET_RULE `(x INSERT s) UNION t = x INSERT (s UNION t)`] THEN
6406 MATCH_MP_TAC EQ_SPAN_INSERT_EQ THEN EXPAND_TAC "a'" THEN
6407 REWRITE_TAC[VECTOR_ARITH `a - x - a:real^N = --x`] THEN
6408 MATCH_MP_TAC SPAN_NEG THEN MATCH_MP_TAC SPAN_VSUM THEN
6409 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
6410 MATCH_MP_TAC SPAN_MUL THEN ASM_SIMP_TAC[SPAN_SUPERSET; IN_UNION]]) in
6411 REPEAT STRIP_TAC THEN
6412 MP_TAC(ISPEC `span t:real^N->bool` BASIS_SUBSPACE_EXISTS) THEN
6413 REWRITE_TAC[SUBSPACE_SPAN; LEFT_IMP_EXISTS_THM] THEN
6414 X_GEN_TAC `b:real^N->bool` THEN STRIP_TAC THEN
6415 MP_TAC(ISPECL [`b:real^N->bool`; `s:real^N->bool`] lemma) THEN
6417 [ASM_MESON_TAC[HAS_SIZE; PAIRWISE_ORTHOGONAL_IMP_FINITE];
6418 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
6419 ASM_REWRITE_TAC[SPAN_UNION]]);;
6421 let ORTHOGONAL_EXTENSION_STRONG = prove
6422 (`!s t:real^N->bool.
6423 pairwise orthogonal s
6424 ==> ?u. DISJOINT u (vec 0 INSERT s) /\
6425 pairwise orthogonal (s UNION u) /\
6426 span (s UNION u) = span (s UNION t)`,
6427 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
6428 SPEC `t:real^N->bool` o MATCH_MP ORTHOGONAL_EXTENSION) THEN
6429 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
6430 EXISTS_TAC `u DIFF ((vec 0:real^N) INSERT s)` THEN REPEAT CONJ_TAC THENL
6432 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6433 PAIRWISE_MONO)) THEN SET_TAC[];
6434 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
6435 GEN_REWRITE_TAC BINOP_CONV [GSYM SPAN_DELETE_0] THEN
6436 AP_TERM_TAC THEN SET_TAC[]]);;
6438 let ORTHONORMAL_EXTENSION = prove
6439 (`!s t:real^N->bool.
6440 pairwise orthogonal s /\ (!x. x IN s ==> norm x = &1)
6441 ==> ?u. DISJOINT u s /\
6442 pairwise orthogonal (s UNION u) /\
6443 (!x. x IN u ==> norm x = &1) /\
6444 span(s UNION u) = span(s UNION t)`,
6445 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
6446 SPEC `t:real^N->bool` o MATCH_MP ORTHOGONAL_EXTENSION_STRONG) THEN
6447 REWRITE_TAC[SET_RULE `DISJOINT u s <=> !x. x IN u ==> ~(x IN s)`] THEN
6448 REWRITE_TAC[IN_INSERT; DE_MORGAN_THM; pairwise] THEN
6449 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
6450 EXISTS_TAC `IMAGE (\x:real^N. inv(norm x) % x) u` THEN
6451 REWRITE_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
6452 REPEAT CONJ_TAC THENL
6453 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
6454 ASM_CASES_TAC `norm(x:real^N) = &1` THEN
6455 ASM_SIMP_TAC[REAL_INV_1; VECTOR_MUL_LID] THEN DISCH_TAC THEN
6456 FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `inv(norm x) % x:real^N`]) THEN
6457 ASM_REWRITE_TAC[IN_UNION; VECTOR_MUL_EQ_0; REAL_SUB_0; REAL_INV_EQ_1;
6458 VECTOR_ARITH `x:real^N = a % x <=> (a - &1) % x = vec 0`] THEN
6459 ASM_CASES_TAC `x:real^N = vec 0` THENL
6460 [ASM_MESON_TAC[VECTOR_MUL_RZERO];
6461 ASM_REWRITE_TAC[orthogonal; DOT_RMUL; REAL_ENTIRE; DOT_EQ_0] THEN
6462 ASM_REWRITE_TAC[REAL_INV_EQ_0; NORM_EQ_0]];
6463 REWRITE_TAC[IN_UNION; IN_IMAGE] THEN REPEAT STRIP_TAC THEN
6464 ASM_SIMP_TAC[orthogonal; DOT_LMUL; DOT_RMUL; REAL_ENTIRE; DOT_EQ_0;
6465 REAL_INV_EQ_0; NORM_EQ_0] THEN
6466 REWRITE_TAC[GSYM orthogonal] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
6467 ASM_REWRITE_TAC[IN_UNION] THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
6469 ASM_SIMP_TAC[NORM_MUL; REAL_MUL_LINV; NORM_EQ_0; REAL_ABS_INV;
6471 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
6472 REWRITE_TAC[SPAN_EQ; UNION_SUBSET] THEN
6473 SIMP_TAC[SUBSET; FORALL_IN_IMAGE; SPAN_SUPERSET; SPAN_MUL; IN_UNION] THEN
6474 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
6475 SUBGOAL_THEN `x:real^N = norm(x) % inv(norm x) % x`
6476 (fun th -> GEN_REWRITE_TAC LAND_CONV [th])
6478 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; NORM_EQ_0; VECTOR_MUL_LID];
6479 MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN
6480 REWRITE_TAC[IN_UNION; IN_IMAGE] THEN ASM_MESON_TAC[]]]);;
6482 let VECTOR_IN_ORTHOGONAL_SPANNINGSET = prove
6483 (`!a. ?s. a IN s /\ pairwise orthogonal s /\ span s = (:real^N)`,
6485 MP_TAC(ISPECL [`{a:real^N}`; `(IMAGE basis (1..dimindex(:N))):real^N->bool`]
6486 ORTHOGONAL_EXTENSION) THEN
6487 REWRITE_TAC[PAIRWISE_SING] THEN
6488 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
6489 EXISTS_TAC `{a:real^N} UNION u` THEN ASM_REWRITE_TAC[IN_UNION; IN_SING] THEN
6490 MATCH_MP_TAC(SET_RULE `!s. s = UNIV /\ s SUBSET t ==> t = UNIV`) THEN
6491 EXISTS_TAC `span {basis i:real^N | 1 <= i /\ i <= dimindex (:N)}` THEN
6492 CONJ_TAC THENL [REWRITE_TAC[SPAN_STDBASIS]; MATCH_MP_TAC SPAN_MONO] THEN
6493 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; GSYM IN_NUMSEG] THEN SET_TAC[]);;
6495 let VECTOR_IN_ORTHOGONAL_BASIS = prove
6497 ==> ?s. a IN s /\ ~(vec 0 IN s) /\
6498 pairwise orthogonal s /\
6500 s HAS_SIZE (dimindex(:N)) /\
6501 span s = (:real^N)`,
6502 REPEAT STRIP_TAC THEN
6503 MP_TAC(ISPEC `a:real^N` VECTOR_IN_ORTHOGONAL_SPANNINGSET) THEN
6504 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
6505 EXISTS_TAC `s DELETE (vec 0:real^N)` THEN ASM_REWRITE_TAC[IN_DELETE] THEN
6506 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6507 [RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6508 ASM_SIMP_TAC[pairwise; IN_DELETE];
6510 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6511 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_SIMP_TAC[IN_DELETE];
6513 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6514 [ASM_MESON_TAC[SPAN_DELETE_0];
6515 DISCH_TAC THEN ASM_SIMP_TAC[BASIS_HAS_SIZE_UNIV]]);;
6517 let VECTOR_IN_ORTHONORMAL_BASIS = prove
6520 pairwise orthogonal s /\
6521 (!x. x IN s ==> norm x = &1) /\
6523 s HAS_SIZE (dimindex(:N)) /\
6524 span s = (:real^N)`,
6525 GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN
6526 ASM_REWRITE_TAC[NORM_0; REAL_OF_NUM_EQ; ARITH_EQ] THEN DISCH_TAC THEN
6527 FIRST_ASSUM(MP_TAC o MATCH_MP VECTOR_IN_ORTHOGONAL_BASIS) THEN
6528 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
6529 EXISTS_TAC `IMAGE (\x:real^N. inv(norm x) % x) s` THEN
6531 [REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `a:real^N` THEN
6532 ASM_REWRITE_TAC[REAL_INV_1; VECTOR_MUL_LID];
6534 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6535 [REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
6536 RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6537 ASM_MESON_TAC[ORTHOGONAL_CLAUSES];
6539 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6540 [REWRITE_TAC[FORALL_IN_IMAGE; NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN
6541 ASM_MESON_TAC[REAL_MUL_LINV; NORM_EQ_0];
6543 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6544 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_REWRITE_TAC[] THEN
6545 REWRITE_TAC[IN_IMAGE] THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN
6546 SIMP_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0; NORM_EQ_0] THEN ASM_MESON_TAC[];
6548 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6549 [ALL_TAC; ASM_SIMP_TAC[BASIS_HAS_SIZE_UNIV]] THEN
6550 UNDISCH_THEN `span s = (:real^N)` (SUBST1_TAC o SYM) THEN
6551 MATCH_MP_TAC SPAN_IMAGE_SCALE THEN
6552 REWRITE_TAC[REAL_INV_EQ_0; NORM_EQ_0] THEN
6553 ASM_MESON_TAC[HAS_SIZE]);;
6555 let BESSEL_INEQUALITY = prove
6557 pairwise orthogonal s /\ (!x. x IN s ==> norm x = &1)
6558 ==> sum s (\e. (e dot x) pow 2) <= norm(x) pow 2`,
6559 REPEAT STRIP_TAC THEN
6560 FIRST_ASSUM(ASSUME_TAC o MATCH_MP PAIRWISE_ORTHOGONAL_IMP_FINITE) THEN
6561 MP_TAC(ISPEC `x - vsum s (\e. (e dot x) % e):real^N` DOT_POS_LE) THEN
6562 REWRITE_TAC[NORM_POW_2; VECTOR_ARITH
6563 `(a - b:real^N) dot (a - b) = a dot a + b dot b - &2 * b dot a`] THEN
6564 ASM_SIMP_TAC[DOT_LSUM; REAL_POW_2; DOT_LMUL] THEN
6565 MATCH_MP_TAC(REAL_ARITH `t = s ==> &0 <= x + t - &2 * s ==> s <= x`) THEN
6566 MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC `e:real^N` THEN DISCH_TAC THEN
6567 ASM_SIMP_TAC[DOT_RSUM] THEN AP_TERM_TAC THEN
6568 MATCH_MP_TAC EQ_TRANS THEN
6569 EXISTS_TAC `sum s (\k:real^N. if k = e then e dot x else &0)` THEN
6570 CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[SUM_DELTA]] THEN
6571 MATCH_MP_TAC SUM_EQ THEN X_GEN_TAC `k:real^N` THEN DISCH_TAC THEN
6572 REWRITE_TAC[DOT_RMUL] THEN COND_CASES_TAC THENL
6573 [ASM_REWRITE_TAC[REAL_RING `a * x = a <=> a = &0 \/ x = &1`] THEN
6574 DISJ2_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e:real^N`) THEN
6575 ASM_REWRITE_TAC[NORM_EQ_SQUARE] THEN REAL_ARITH_TAC;
6576 RULE_ASSUM_TAC(REWRITE_RULE[pairwise; orthogonal]) THEN
6577 ASM_SIMP_TAC[REAL_ENTIRE]]);;
6579 (* ------------------------------------------------------------------------- *)
6580 (* Analogous theorems for existence of orthonormal basis for a subspace. *)
6581 (* ------------------------------------------------------------------------- *)
6583 let ORTHOGONAL_SPANNINGSET_SUBSPACE = prove
6586 ==> ?b. b SUBSET s /\ pairwise orthogonal b /\ span b = s`,
6587 REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^N->bool` BASIS_EXISTS) THEN
6588 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
6589 MP_TAC(ISPECL[`{}:real^N->bool`; `b:real^N->bool`] ORTHOGONAL_EXTENSION) THEN
6590 REWRITE_TAC[PAIRWISE_EMPTY; UNION_EMPTY] THEN
6591 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N->bool` THEN
6592 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
6593 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6594 [MATCH_MP_TAC SPAN_SUBSPACE THEN ASM_REWRITE_TAC[];
6595 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_MESON_TAC[SPAN_INC]]);;
6597 let ORTHOGONAL_BASIS_SUBSPACE = prove
6600 ==> ?b. ~(vec 0 IN b) /\
6602 pairwise orthogonal b /\
6604 b HAS_SIZE (dim s) /\
6606 REPEAT STRIP_TAC THEN
6607 FIRST_ASSUM(MP_TAC o MATCH_MP ORTHOGONAL_SPANNINGSET_SUBSPACE) THEN
6608 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
6609 EXISTS_TAC `b DELETE (vec 0:real^N)` THEN ASM_REWRITE_TAC[IN_DELETE] THEN
6610 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
6611 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6612 [RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6613 ASM_SIMP_TAC[pairwise; IN_DELETE];
6615 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6616 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_SIMP_TAC[IN_DELETE];
6618 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6619 [ASM_MESON_TAC[SPAN_DELETE_0];
6620 DISCH_TAC THEN ASM_SIMP_TAC[BASIS_HAS_SIZE_DIM]]);;
6622 let ORTHONORMAL_BASIS_SUBSPACE = prove
6625 ==> ?b. b SUBSET s /\
6626 pairwise orthogonal b /\
6627 (!x. x IN b ==> norm x = &1) /\
6629 b HAS_SIZE (dim s) /\
6631 REPEAT STRIP_TAC THEN
6632 FIRST_ASSUM(MP_TAC o MATCH_MP ORTHOGONAL_BASIS_SUBSPACE) THEN
6633 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
6634 EXISTS_TAC `IMAGE (\x:real^N. inv(norm x) % x) b` THEN
6636 [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
6637 ASM_MESON_TAC[SPAN_MUL; SPAN_INC; SUBSET];
6639 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6640 [REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
6641 RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6642 ASM_MESON_TAC[ORTHOGONAL_CLAUSES];
6644 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6645 [REWRITE_TAC[FORALL_IN_IMAGE; NORM_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN
6646 ASM_MESON_TAC[REAL_MUL_LINV; NORM_EQ_0];
6648 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6649 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN ASM_REWRITE_TAC[] THEN
6650 REWRITE_TAC[IN_IMAGE] THEN ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN
6651 SIMP_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0; NORM_EQ_0] THEN ASM_MESON_TAC[];
6653 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6654 [ALL_TAC; ASM_SIMP_TAC[BASIS_HAS_SIZE_DIM]] THEN
6655 UNDISCH_THEN `span b = (s:real^N->bool)` (SUBST1_TAC o SYM) THEN
6656 MATCH_MP_TAC SPAN_IMAGE_SCALE THEN
6657 REWRITE_TAC[REAL_INV_EQ_0; NORM_EQ_0] THEN
6658 ASM_MESON_TAC[HAS_SIZE]);;
6660 let ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN = prove
6661 (`!s t:real^N->bool.
6662 span s PSUBSET span t
6663 ==> ?x. ~(x = vec 0) /\ x IN span t /\
6664 (!y. y IN span s ==> orthogonal x y)`,
6665 REPEAT STRIP_TAC THEN
6666 MP_TAC(ISPEC `span s:real^N->bool` ORTHOGONAL_BASIS_SUBSPACE) THEN
6667 REWRITE_TAC[SUBSPACE_SPAN] THEN
6668 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
6669 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
6670 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [PSUBSET_ALT]) THEN
6671 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
6672 (X_CHOOSE_THEN `u:real^N` STRIP_ASSUME_TAC)) THEN
6673 MP_TAC(ISPECL [`b:real^N->bool`; `{u:real^N}`] ORTHOGONAL_EXTENSION) THEN
6674 ASM_REWRITE_TAC[] THEN
6675 DISCH_THEN(X_CHOOSE_THEN `ns:real^N->bool` MP_TAC) THEN
6676 ASM_CASES_TAC `ns SUBSET (vec 0:real^N) INSERT b` THENL
6677 [DISCH_THEN(MP_TAC o AP_TERM `(IN) (u:real^N)` o CONJUNCT2) THEN
6678 SIMP_TAC[SPAN_SUPERSET; IN_UNION; IN_SING] THEN
6679 MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN
6680 SUBGOAL_THEN `~(u IN span (b UNION {vec 0:real^N}))` MP_TAC THENL
6681 [ASM_REWRITE_TAC[SET_RULE `s UNION {a} = a INSERT s`; SPAN_INSERT_0];
6682 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> ~(x IN t) ==> ~(x IN s)`) THEN
6683 MATCH_MP_TAC SPAN_MONO THEN ASM SET_TAC[]];
6685 FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
6686 `~(s SUBSET t) ==> ?z. z IN s /\ ~(z IN t)`)) THEN
6687 REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_INSERT; DE_MORGAN_THM] THEN
6688 X_GEN_TAC `n:real^N` THEN STRIP_TAC THEN
6689 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
6690 REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
6691 DISCH_THEN(MP_TAC o SPEC `n:real^N`) THEN ASM_REWRITE_TAC[IN_UNION] THEN
6692 REWRITE_TAC[IMP_IMP] THEN DISCH_TAC THEN EXISTS_TAC `n:real^N` THEN
6693 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
6694 [SUBGOAL_THEN `(n:real^N) IN span (b UNION ns)` MP_TAC THENL
6695 [MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[];
6696 ASM_REWRITE_TAC[] THEN SPEC_TAC(`n:real^N`,`n:real^N`) THEN
6697 REWRITE_TAC[GSYM SUBSET] THEN
6698 MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN REWRITE_TAC[SUBSPACE_SPAN] THEN
6699 ASM_REWRITE_TAC[SET_RULE
6700 `s UNION {a} SUBSET t <=> s SUBSET t /\ a IN t`] THEN
6701 ASM_MESON_TAC[SPAN_INC; SUBSET_TRANS]];
6702 MATCH_MP_TAC SPAN_INDUCT THEN
6703 REWRITE_TAC[SET_RULE `(\y. orthogonal n y) = {y | orthogonal n y}`] THEN
6704 REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR] THEN ASM SET_TAC[]]);;
6706 let ORTHOGONAL_TO_SUBSPACE_EXISTS = prove
6707 (`!s:real^N->bool. dim s < dimindex(:N)
6708 ==> ?x. ~(x = vec 0) /\ !y. y IN s ==> orthogonal x y`,
6709 REPEAT STRIP_TAC THEN
6710 MP_TAC(ISPECL [`s:real^N->bool`; `(:real^N)`]
6711 ORTHOGONAL_TO_SUBSPACE_EXISTS_GEN) THEN
6712 ANTS_TAC THENL [REWRITE_TAC[PSUBSET]; MESON_TAC[SPAN_SUPERSET]] THEN
6713 REWRITE_TAC[SPAN_UNIV; SUBSET_UNIV] THEN
6714 ASM_MESON_TAC[DIM_SPAN; DIM_UNIV; LT_REFL]);;
6716 let ORTHOGONAL_TO_VECTOR_EXISTS = prove
6717 (`!x:real^N. 2 <= dimindex(:N) ==> ?y. ~(y = vec 0) /\ orthogonal x y`,
6718 REPEAT STRIP_TAC THEN
6719 MP_TAC(ISPEC `{x:real^N}` ORTHOGONAL_TO_SUBSPACE_EXISTS) THEN
6720 SIMP_TAC[DIM_SING; IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
6721 ANTS_TAC THENL [ASM_ARITH_TAC; MESON_TAC[ORTHOGONAL_SYM]]);;
6723 let SPAN_NOT_UNIV_ORTHOGONAL = prove
6724 (`!s. ~(span s = (:real^N))
6725 ==> ?a. ~(a = vec 0) /\ !x. x IN span s ==> a dot x = &0`,
6726 REWRITE_TAC[GSYM DIM_EQ_FULL; GSYM LE_ANTISYM; DIM_SUBSET_UNIV;
6728 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM orthogonal] THEN
6729 MATCH_MP_TAC ORTHOGONAL_TO_SUBSPACE_EXISTS THEN ASM_REWRITE_TAC[DIM_SPAN]);;
6731 let SPAN_NOT_UNIV_SUBSET_HYPERPLANE = prove
6732 (`!s. ~(span s = (:real^N))
6733 ==> ?a. ~(a = vec 0) /\ span s SUBSET {x | a dot x = &0}`,
6734 REWRITE_TAC[SUBSET; IN_ELIM_THM; SPAN_NOT_UNIV_ORTHOGONAL]);;
6736 let LOWDIM_SUBSET_HYPERPLANE = prove
6737 (`!s. dim s < dimindex(:N)
6738 ==> ?a:real^N. ~(a = vec 0) /\ span s SUBSET {x | a dot x = &0}`,
6739 REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_NOT_UNIV_SUBSET_HYPERPLANE THEN
6740 REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET_UNIV] THEN
6741 DISCH_THEN(MP_TAC o MATCH_MP DIM_SUBSET) THEN
6742 ASM_REWRITE_TAC[NOT_LE; DIM_SPAN; DIM_UNIV]);;
6744 let VECTOR_EQ_DOT_SPAN = prove
6746 (!v. v IN b ==> v dot x = v dot y) /\ x IN span b /\ y IN span b
6748 ONCE_REWRITE_TAC[GSYM REAL_SUB_0; GSYM VECTOR_SUB_EQ] THEN
6749 REWRITE_TAC[GSYM DOT_RSUB; GSYM ORTHOGONAL_REFL; GSYM orthogonal] THEN
6750 MESON_TAC[ORTHOGONAL_TO_SPAN; SPAN_SUB; ORTHOGONAL_SYM]);;
6752 let ORTHONORMAL_BASIS_EXPAND = prove
6754 pairwise orthogonal b /\ (!v. v IN b ==> norm v = &1) /\ x IN span b
6755 ==> vsum b (\v. (v dot x) % v) = x`,
6756 REWRITE_TAC[NORM_EQ_1] THEN REPEAT STRIP_TAC THEN
6757 MATCH_MP_TAC VECTOR_EQ_DOT_SPAN THEN EXISTS_TAC `b:real^N->bool` THEN
6758 FIRST_ASSUM(ASSUME_TAC o MATCH_MP PAIRWISE_ORTHOGONAL_IMP_FINITE) THEN
6759 RULE_ASSUM_TAC(REWRITE_RULE[pairwise; orthogonal]) THEN
6760 ASM_SIMP_TAC[SPAN_VSUM; SPAN_MUL; DOT_RSUM; DOT_RMUL; SPAN_SUPERSET] THEN
6761 X_GEN_TAC `v:real^N` THEN DISCH_TAC THEN
6762 TRANS_TAC EQ_TRANS `sum b (\w:real^N. if w = v then v dot x else &0)` THEN
6763 CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[SUM_DELTA]] THEN
6764 MATCH_MP_TAC SUM_EQ THEN ASM_REWRITE_TAC[] THEN
6765 X_GEN_TAC `w:real^N` THEN DISCH_TAC THEN
6766 COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_MUL_RID; REAL_MUL_RZERO]);;
6768 (* ------------------------------------------------------------------------- *)
6769 (* Decomposing a vector into parts in orthogonal subspaces. *)
6770 (* ------------------------------------------------------------------------- *)
6772 let ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE = prove
6773 (`!s t x y x' y':real^N.
6774 (!a b. a IN s /\ b IN t ==> orthogonal a b) /\
6775 x IN span s /\ x' IN span s /\ y IN span t /\ y' IN span t /\
6777 ==> x = x' /\ y = y'`,
6778 REWRITE_TAC[VECTOR_ARITH `x + y:real^N = x' + y' <=> x - x' = y' - y`] THEN
6779 ONCE_REWRITE_TAC[GSYM ORTHOGONAL_TO_SPANS_EQ] THEN
6780 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[VECTOR_ARITH
6781 `x:real^N = x' /\ y:real^N = y' <=> x - x' = vec 0 /\ y' - y = vec 0`] THEN
6782 STRIP_TAC THEN ASM_REWRITE_TAC[GSYM ORTHOGONAL_REFL] THEN
6783 FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC RAND_CONV [SYM th]) THEN
6784 ASM_MESON_TAC[ORTHOGONAL_CLAUSES; ORTHOGONAL_SYM]);;
6786 let ORTHOGONAL_SUBSPACE_DECOMP_EXISTS = prove
6787 (`!s x:real^N. ?y z. y IN span s /\ (!w. w IN span s ==> orthogonal z w) /\
6789 REPEAT STRIP_TAC THEN
6790 MP_TAC(ISPEC `span s:real^N->bool` ORTHOGONAL_BASIS_SUBSPACE) THEN
6791 REWRITE_TAC[SUBSPACE_SPAN; LEFT_IMP_EXISTS_THM] THEN
6792 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
6793 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
6794 EXISTS_TAC `vsum t (\b:real^N. (b dot x) / (b dot b) % b)` THEN
6795 EXISTS_TAC `x - vsum t (\b:real^N. (b dot x) / (b dot b) % b)` THEN
6796 REPEAT CONJ_TAC THENL
6797 [MATCH_MP_TAC SPAN_VSUM THEN
6798 ASM_SIMP_TAC[INDEPENDENT_IMP_FINITE; SPAN_CLAUSES];
6799 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[ORTHOGONAL_SYM] THEN
6800 MATCH_MP_TAC GRAM_SCHMIDT_STEP THEN ASM_SIMP_TAC[];
6801 VECTOR_ARITH_TAC]);;
6803 let ORTHOGONAL_SUBSPACE_DECOMP = prove
6804 (`!s x. ?!(y,z). y IN span s /\
6805 z IN {z:real^N | !x. x IN span s ==> orthogonal z x} /\
6807 REWRITE_TAC[EXISTS_UNIQUE_DEF; IN_ELIM_THM] THEN
6808 REWRITE_TAC[EXISTS_PAIRED_THM; FORALL_PAIRED_THM] THEN
6809 REWRITE_TAC[FORALL_PAIR_THM; ORTHOGONAL_SUBSPACE_DECOMP_EXISTS] THEN
6810 REPEAT STRIP_TAC THEN REWRITE_TAC[PAIR_EQ] THEN
6811 MATCH_MP_TAC ORTHOGONAL_SUBSPACE_DECOMP_UNIQUE THEN
6812 MAP_EVERY EXISTS_TAC
6813 [`s:real^N->bool`; `{z:real^N | !x. x IN span s ==> orthogonal z x}`] THEN
6814 ASM_SIMP_TAC[SPAN_CLAUSES; IN_ELIM_THM] THEN
6815 ASM_MESON_TAC[SPAN_CLAUSES; ORTHOGONAL_SYM]);;
6817 (* ------------------------------------------------------------------------- *)
6818 (* Existence of isometry between subspaces of same dimension. *)
6819 (* ------------------------------------------------------------------------- *)
6821 let ISOMETRY_SUBSET_SUBSPACE = prove
6822 (`!s:real^M->bool t:real^N->bool.
6823 subspace s /\ subspace t /\ dim s <= dim t
6824 ==> ?f. linear f /\ IMAGE f s SUBSET t /\
6825 (!x. x IN s ==> norm(f x) = norm(x))`,
6826 REPEAT STRIP_TAC THEN
6827 MP_TAC(ISPEC `t:real^N->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN
6828 MP_TAC(ISPEC `s:real^M->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN
6829 ASM_REWRITE_TAC[HAS_SIZE] THEN
6830 DISCH_THEN(X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC) THEN
6831 DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN
6832 MP_TAC(ISPECL [`b:real^M->bool`; `c:real^N->bool`] CARD_LE_INJ) THEN
6833 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; INJECTIVE_ON_ALT] THEN
6834 X_GEN_TAC `fb:real^M->real^N` THEN STRIP_TAC THEN
6835 MP_TAC(ISPECL [`fb:real^M->real^N`; `b:real^M->bool`]
6836 LINEAR_INDEPENDENT_EXTEND) THEN
6837 ASM_REWRITE_TAC[IMP_IMP; LEFT_AND_EXISTS_THM; INJECTIVE_ON_ALT] THEN
6838 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN
6839 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
6840 [REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN
6841 ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN
6842 REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN
6843 MATCH_MP_TAC SPAN_MONO THEN ASM SET_TAC[];
6844 UNDISCH_THEN `span b:real^M->bool = s` (SUBST1_TAC o SYM) THEN
6845 ASM_SIMP_TAC[SPAN_FINITE] THEN
6846 REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
6847 MAP_EVERY X_GEN_TAC [`z:real^M`; `u:real^M->real`] THEN
6848 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[LINEAR_VSUM] THEN
6849 REWRITE_TAC[o_DEF; NORM_EQ_SQUARE; NORM_POS_LE; GSYM NORM_POW_2] THEN
6850 ASM_SIMP_TAC[LINEAR_CMUL] THEN
6851 W(MP_TAC o PART_MATCH (lhand o rand)
6852 NORM_VSUM_PYTHAGOREAN o rand o snd) THEN
6853 W(MP_TAC o PART_MATCH (lhand o rand)
6854 NORM_VSUM_PYTHAGOREAN o lhand o rand o snd) THEN
6855 RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6856 ASM_SIMP_TAC[pairwise; ORTHOGONAL_CLAUSES] THEN ANTS_TAC THENL
6857 [REPEAT STRIP_TAC THEN REWRITE_TAC[ORTHOGONAL_MUL] THEN ASM SET_TAC[];
6858 REPEAT(DISCH_THEN SUBST1_TAC) THEN ASM_SIMP_TAC[NORM_MUL] THEN
6859 MATCH_MP_TAC SUM_EQ THEN ASM SET_TAC[]]]);;
6861 let ISOMETRIES_SUBSPACES = prove
6862 (`!s:real^M->bool t:real^N->bool.
6863 subspace s /\ subspace t /\ dim s = dim t
6864 ==> ?f g. linear f /\ linear g /\
6865 IMAGE f s = t /\ IMAGE g t = s /\
6866 (!x. x IN s ==> norm(f x) = norm x) /\
6867 (!y. y IN t ==> norm(g y) = norm y) /\
6868 (!x. x IN s ==> g(f x) = x) /\
6869 (!y. y IN t ==> f(g y) = y)`,
6870 REPEAT STRIP_TAC THEN ABBREV_TAC `n = dim(t:real^N->bool)` THEN
6871 MP_TAC(ISPEC `t:real^N->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN
6872 MP_TAC(ISPEC `s:real^M->bool` ORTHONORMAL_BASIS_SUBSPACE) THEN
6873 ASM_REWRITE_TAC[] THEN
6874 DISCH_THEN(X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC) THEN
6875 DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN
6876 MP_TAC(ISPECL [`b:real^M->bool`; `c:real^N->bool`] CARD_EQ_BIJECTIONS) THEN
6877 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
6878 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
6879 MAP_EVERY X_GEN_TAC [`fb:real^M->real^N`; `gb:real^N->real^M`] THEN
6881 MP_TAC(ISPECL [`gb:real^N->real^M`; `c:real^N->bool`]
6882 LINEAR_INDEPENDENT_EXTEND) THEN
6883 MP_TAC(ISPECL [`fb:real^M->real^N`; `b:real^M->bool`]
6884 LINEAR_INDEPENDENT_EXTEND) THEN
6885 ASM_REWRITE_TAC[IMP_IMP; LEFT_AND_EXISTS_THM] THEN
6886 REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
6887 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN
6888 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN
6889 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
6890 [REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN
6891 ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN
6892 REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN
6893 AP_TERM_TAC THEN ASM SET_TAC[];
6894 REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN
6895 ASM_SIMP_TAC[GSYM SPAN_LINEAR_IMAGE] THEN
6896 REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN
6897 AP_TERM_TAC THEN ASM SET_TAC[];
6898 UNDISCH_THEN `span b:real^M->bool = s` (SUBST1_TAC o SYM) THEN
6899 ASM_SIMP_TAC[SPAN_FINITE] THEN
6900 REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
6901 MAP_EVERY X_GEN_TAC [`z:real^M`; `u:real^M->real`] THEN
6902 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[LINEAR_VSUM] THEN
6903 REWRITE_TAC[o_DEF; NORM_EQ_SQUARE; NORM_POS_LE; GSYM NORM_POW_2] THEN
6904 ASM_SIMP_TAC[LINEAR_CMUL] THEN
6905 W(MP_TAC o PART_MATCH (lhand o rand)
6906 NORM_VSUM_PYTHAGOREAN o rand o snd) THEN
6907 W(MP_TAC o PART_MATCH (lhand o rand)
6908 NORM_VSUM_PYTHAGOREAN o lhand o rand o snd) THEN
6909 RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6910 ASM_SIMP_TAC[pairwise; ORTHOGONAL_CLAUSES] THEN ANTS_TAC THENL
6911 [REPEAT STRIP_TAC THEN REWRITE_TAC[ORTHOGONAL_MUL] THEN ASM SET_TAC[];
6912 REPEAT(DISCH_THEN SUBST1_TAC) THEN
6913 ASM_SIMP_TAC[NORM_MUL]];
6914 UNDISCH_THEN `span c:real^N->bool = t` (SUBST1_TAC o SYM) THEN
6915 ASM_SIMP_TAC[SPAN_FINITE] THEN
6916 REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
6917 MAP_EVERY X_GEN_TAC [`z:real^N`; `u:real^N->real`] THEN
6918 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[LINEAR_VSUM] THEN
6919 REWRITE_TAC[o_DEF; NORM_EQ_SQUARE; NORM_POS_LE; GSYM NORM_POW_2] THEN
6920 ASM_SIMP_TAC[LINEAR_CMUL] THEN
6921 W(MP_TAC o PART_MATCH (lhand o rand)
6922 NORM_VSUM_PYTHAGOREAN o rand o snd) THEN
6923 W(MP_TAC o PART_MATCH (lhand o rand)
6924 NORM_VSUM_PYTHAGOREAN o lhand o rand o snd) THEN
6925 RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
6926 ASM_SIMP_TAC[pairwise; ORTHOGONAL_CLAUSES] THEN ANTS_TAC THENL
6927 [REPEAT STRIP_TAC THEN REWRITE_TAC[ORTHOGONAL_MUL] THEN ASM SET_TAC[];
6928 REPEAT(DISCH_THEN SUBST1_TAC) THEN
6929 ASM_SIMP_TAC[NORM_MUL]];
6930 REWRITE_TAC[SYM(ASSUME `span b:real^M->bool = s`)] THEN
6931 MATCH_MP_TAC SPAN_INDUCT THEN
6932 CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; IN]; ALL_TAC] THEN
6933 REWRITE_TAC[subspace; IN] THEN ASM_MESON_TAC[linear; LINEAR_0];
6934 REWRITE_TAC[SYM(ASSUME `span c:real^N->bool = t`)] THEN
6935 MATCH_MP_TAC SPAN_INDUCT THEN
6936 CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; IN]; ALL_TAC] THEN
6937 REWRITE_TAC[subspace; IN] THEN ASM_MESON_TAC[linear; LINEAR_0]]);;
6939 let ISOMETRY_SUBSPACES = prove
6940 (`!s:real^M->bool t:real^N->bool.
6941 subspace s /\ subspace t /\ dim s = dim t
6942 ==> ?f:real^M->real^N. linear f /\ IMAGE f s = t /\
6943 (!x. x IN s ==> norm(f x) = norm(x))`,
6945 DISCH_THEN(MP_TAC o MATCH_MP ISOMETRIES_SUBSPACES) THEN
6946 MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[]);;
6948 let ISOMETRY_UNIV_SUBSPACE = prove
6949 (`!s. subspace s /\ dimindex(:M) = dim s
6950 ==> ?f:real^M->real^N.
6951 linear f /\ IMAGE f (:real^M) = s /\
6952 (!x. norm(f x) = norm(x))`,
6953 REPEAT STRIP_TAC THEN
6954 MP_TAC(ISPECL [`(:real^M)`; `s:real^N->bool`] ISOMETRY_SUBSPACES) THEN
6955 ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV; DIM_UNIV]);;
6957 let ISOMETRY_UNIV_SUPERSET_SUBSPACE = prove
6958 (`!s. subspace s /\ dim s <= dimindex(:M) /\ dimindex(:M) <= dimindex(:N)
6959 ==> ?f:real^M->real^N.
6960 linear f /\ s SUBSET (IMAGE f (:real^M)) /\
6961 (!x. norm(f x) = norm(x))`,
6962 GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
6963 FIRST_ASSUM(MP_TAC o MATCH_MP LOWDIM_EXPAND_DIMENSION) THEN
6964 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
6965 MP_TAC(ISPECL [`(:real^M)`; `span t:real^N->bool`] ISOMETRY_SUBSPACES) THEN
6966 ASM_REWRITE_TAC[SUBSPACE_SPAN; SUBSPACE_UNIV; DIM_UNIV; DIM_SPAN] THEN
6967 MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[IN_UNIV] THEN
6968 ASM_MESON_TAC[SUBSET; SPAN_INC]);;
6970 let ISOMETRY_UNIV_UNIV = prove
6971 (`dimindex(:M) <= dimindex(:N)
6972 ==> ?f:real^M->real^N. linear f /\ (!x. norm(f x) = norm(x))`,
6974 MP_TAC(ISPEC `{vec 0:real^N}`ISOMETRY_UNIV_SUPERSET_SUBSPACE) THEN
6975 ASM_REWRITE_TAC[SUBSPACE_TRIVIAL] THEN
6976 ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
6977 MATCH_MP_TAC(ARITH_RULE `x = 0 /\ 1 <= y ==> x <= y`) THEN
6978 ASM_REWRITE_TAC[DIM_EQ_0; DIMINDEX_GE_1] THEN SET_TAC[]);;
6980 let SUBSPACE_ISOMORPHISM = prove
6981 (`!s t. subspace s /\ subspace t /\ dim(s) = dim(t)
6982 ==> ?f:real^M->real^N.
6983 linear f /\ (IMAGE f s = t) /\
6984 (!x y. x IN s /\ y IN s /\ f x = f y ==> (x = y))`,
6985 REPEAT GEN_TAC THEN DISCH_TAC THEN
6986 FIRST_ASSUM(MP_TAC o MATCH_MP ISOMETRY_SUBSPACES) THEN
6987 MATCH_MP_TAC MONO_EXISTS THEN
6988 ASM_SIMP_TAC[LINEAR_INJECTIVE_0_SUBSPACE] THEN MESON_TAC[NORM_EQ_0]);;
6990 let ISOMORPHISMS_UNIV_UNIV = prove
6991 (`dimindex(:M) = dimindex(:N)
6992 ==> ?f:real^M->real^N g.
6993 linear f /\ linear g /\
6994 (!x. norm(f x) = norm x) /\ (!y. norm(g y) = norm y) /\
6995 (!x. g(f x) = x) /\ (!y. f(g y) = y)`,
6996 REPEAT STRIP_TAC THEN
6997 EXISTS_TAC `(\x. lambda i. x$i):real^M->real^N` THEN
6998 EXISTS_TAC `(\x. lambda i. x$i):real^N->real^M` THEN
6999 SIMP_TAC[vector_norm; dot; LAMBDA_BETA] THEN
7000 SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
7002 FIRST_ASSUM SUBST1_TAC THEN SIMP_TAC[LAMBDA_BETA] THEN
7003 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN SIMP_TAC[LAMBDA_BETA]);;
7005 (* ------------------------------------------------------------------------- *)
7006 (* Properties of special hyperplanes. *)
7007 (* ------------------------------------------------------------------------- *)
7009 let SUBSPACE_HYPERPLANE = prove
7010 (`!a. subspace {x:real^N | a dot x = &0}`,
7011 SIMP_TAC[subspace; DOT_RADD; DOT_RMUL; IN_ELIM_THM; REAL_ADD_LID;
7012 REAL_MUL_RZERO; DOT_RZERO]);;
7014 let SUBSPACE_SPECIAL_HYPERPLANE = prove
7015 (`!k. subspace {x:real^N | x$k = &0}`,
7016 SIMP_TAC[subspace; IN_ELIM_THM; VEC_COMPONENT;
7017 VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN REAL_ARITH_TAC);;
7019 let SPECIAL_HYPERPLANE_SPAN = prove
7020 (`!k. 1 <= k /\ k <= dimindex(:N)
7021 ==> {x:real^N | x$k = &0} =
7022 span(IMAGE basis ((1..dimindex(:N)) DELETE k))`,
7023 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC SPAN_SUBSPACE THEN
7024 ASM_SIMP_TAC[SUBSPACE_SPECIAL_HYPERPLANE] THEN CONJ_TAC THENL
7025 [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
7026 ASM_SIMP_TAC[BASIS_COMPONENT; IN_DELETE];
7027 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
7028 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7029 GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN
7030 SIMP_TAC[SPAN_FINITE; FINITE_IMAGE; FINITE_DELETE; FINITE_NUMSEG] THEN
7031 REWRITE_TAC[IN_ELIM_THM] THEN
7032 EXISTS_TAC `\v:real^N. x dot v` THEN
7033 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhs o snd) THEN
7035 [REWRITE_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_NUMSEG; IN_DELETE] THEN
7036 MESON_TAC[BASIS_INJ];
7037 DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[o_DEF] THEN
7038 ASM_SIMP_TAC[VSUM_DELETE; FINITE_NUMSEG; IN_NUMSEG; DOT_BASIS] THEN
7039 REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_SUB_RZERO]]]);;
7041 let DIM_SPECIAL_HYPERPLANE = prove
7042 (`!k. 1 <= k /\ k <= dimindex(:N)
7043 ==> dim {x:real^N | x$k = &0} = dimindex(:N) - 1`,
7044 SIMP_TAC[SPECIAL_HYPERPLANE_SPAN] THEN REPEAT STRIP_TAC THEN
7045 MATCH_MP_TAC DIM_UNIQUE THEN
7046 EXISTS_TAC `IMAGE (basis:num->real^N) ((1..dimindex(:N)) DELETE k)` THEN
7047 REWRITE_TAC[SUBSET_REFL; SPAN_INC] THEN CONJ_TAC THENL
7048 [MATCH_MP_TAC INDEPENDENT_MONO THEN
7049 EXISTS_TAC `{basis i:real^N | 1 <= i /\ i <= dimindex(:N)}` THEN
7050 REWRITE_TAC[INDEPENDENT_STDBASIS; SUBSET; FORALL_IN_IMAGE] THEN
7051 REWRITE_TAC[IN_DELETE; IN_NUMSEG; IN_ELIM_THM] THEN MESON_TAC[];
7052 MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN CONJ_TAC THENL
7053 [REWRITE_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_NUMSEG; IN_DELETE] THEN
7054 MESON_TAC[BASIS_INJ];
7055 ASM_SIMP_TAC[HAS_SIZE; FINITE_DELETE; FINITE_NUMSEG; CARD_DELETE;
7056 FINITE_IMAGE; IN_NUMSEG; CARD_NUMSEG_1]]]);;
7058 (* ------------------------------------------------------------------------- *)
7059 (* More theorems about dimensions of different subspaces. *)
7060 (* ------------------------------------------------------------------------- *)
7062 let DIM_IMAGE_KERNEL_GEN = prove
7063 (`!f:real^M->real^N s.
7064 linear f /\ subspace s
7065 ==> dim(IMAGE f s) + dim {x | x IN s /\ f x = vec 0} = dim(s)`,
7066 REPEAT STRIP_TAC THEN MP_TAC
7067 (ISPEC `{x | x IN s /\ (f:real^M->real^N) x = vec 0}` BASIS_EXISTS) THEN
7068 DISCH_THEN(X_CHOOSE_THEN `v:real^M->bool` STRIP_ASSUME_TAC) THEN
7069 MP_TAC(ISPECL [`v:real^M->bool`; `s:real^M->bool`]
7070 MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
7071 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7072 DISCH_THEN(X_CHOOSE_THEN `w:real^M->bool` STRIP_ASSUME_TAC) THEN
7073 SUBGOAL_THEN `span(w:real^M->bool) = s`
7074 (fun th -> GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [SYM th] THEN
7076 THENL [ASM_SIMP_TAC[SPAN_SUBSPACE]; ALL_TAC] THEN
7077 SUBGOAL_THEN `subspace {x | x IN s /\ (f:real^M->real^N) x = vec 0}`
7079 [REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
7080 ASM_SIMP_TAC[SUBSPACE_INTER; SUBSPACE_KERNEL];
7082 SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x = vec 0} = span v`
7084 [ASM_MESON_TAC[SUBSET_ANTISYM; SPAN_SUBSET_SUBSPACE; SUBSPACE_KERNEL];
7086 ASM_SIMP_TAC[DIM_SPAN; DIM_EQ_CARD] THEN
7088 `!x. x IN span(w DIFF v) /\ (f:real^M->real^N) x = vec 0 ==> x = vec 0`
7089 (LABEL_TAC "*") THENL
7090 [MATCH_MP_TAC(SET_RULE
7091 `!t. s SUBSET t /\ (!x. x IN s /\ x IN t /\ P x ==> Q x)
7092 ==> (!x. x IN s /\ P x ==> Q x)`) THEN
7093 EXISTS_TAC `s:real^M->bool` THEN CONJ_TAC THENL
7094 [ASM_MESON_TAC[SPAN_MONO; SUBSET_DIFF]; ALL_TAC] THEN
7095 ASM_SIMP_TAC[SPAN_FINITE; IN_ELIM_THM; IMP_CONJ; FINITE_DIFF;
7096 INDEPENDENT_IMP_FINITE; LEFT_IMP_EXISTS_THM] THEN
7097 GEN_TAC THEN X_GEN_TAC `u:real^M->real` THEN
7098 DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[IMP_IMP] THEN
7099 ONCE_REWRITE_TAC[SET_RULE
7100 `y IN s /\ f y = a <=> y IN {x | x IN s /\ f x = a}`] THEN
7101 ASM_REWRITE_TAC[] THEN
7102 ASM_SIMP_TAC[SPAN_FINITE; INDEPENDENT_IMP_FINITE; IN_ELIM_THM] THEN
7103 DISCH_THEN(X_CHOOSE_TAC `t:real^M->real`) THEN
7104 MP_TAC(ISPEC `w:real^M->bool` INDEPENDENT_EXPLICIT) THEN
7105 ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
7106 DISCH_THEN(MP_TAC o SPEC
7107 `(\x. if x IN w DIFF v then --u x else t x):real^M->real`) THEN
7108 ASM_REWRITE_TAC[COND_RAND] THEN ONCE_REWRITE_TAC[COND_RATOR] THEN
7109 ASM_SIMP_TAC[VSUM_CASES; INDEPENDENT_IMP_FINITE] THEN
7110 REWRITE_TAC[SET_RULE `{x | x IN w /\ x IN (w DIFF v)} = w DIFF v`] THEN
7111 SIMP_TAC[ASSUME `(v:real^M->bool) SUBSET w`; SET_RULE
7112 `v SUBSET w ==> {x | x IN w /\ ~(x IN (w DIFF v))} = v`] THEN
7113 ASM_REWRITE_TAC[VECTOR_MUL_LNEG; VSUM_NEG; VECTOR_ADD_LINV] THEN
7114 DISCH_THEN(fun th -> MATCH_MP_TAC VSUM_EQ_0 THEN MP_TAC th) THEN
7115 REWRITE_TAC[REAL_NEG_EQ_0; VECTOR_MUL_EQ_0; IN_DIFF] THEN MESON_TAC[];
7117 SUBGOAL_THEN `!x y. x IN (w DIFF v) /\ y IN (w DIFF v) /\
7118 (f:real^M->real^N) x = f y ==> x = y`
7120 [REMOVE_THEN "*" MP_TAC THEN
7121 ASM_SIMP_TAC[GSYM LINEAR_INJECTIVE_0_SUBSPACE; SUBSPACE_SPAN] THEN
7122 MP_TAC(ISPEC `w DIFF v:real^M->bool` SPAN_INC) THEN SET_TAC[];
7124 SUBGOAL_THEN `IMAGE (f:real^M->real^N) s = span(IMAGE f (w DIFF v))`
7126 [MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
7128 ASM_MESON_TAC[SUBSPACE_LINEAR_IMAGE; SPAN_MONO; IMAGE_SUBSET;
7129 SUBSET_TRANS; SUBSET_DIFF; SPAN_EQ_SELF]] THEN
7130 SIMP_TAC[SUBSET; FORALL_IN_IMAGE] THEN X_GEN_TAC `x:real^M` THEN
7131 DISCH_TAC THEN UNDISCH_TAC `span w:real^M->bool = s` THEN
7132 REWRITE_TAC[EXTENSION] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
7133 ASM_REWRITE_TAC[] THEN
7134 REMOVE_THEN "*" (MP_TAC o SPEC `x:real^M`) THEN
7135 (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 4)
7136 [IN_UNIV; SPAN_FINITE; INDEPENDENT_IMP_FINITE; IN_ELIM_THM;
7137 FINITE_IMAGE; FINITE_DIFF; ASSUME `independent(w:real^M->bool)`] THEN
7138 REWRITE_TAC[IMP_CONJ; LEFT_IMP_EXISTS_THM] THEN DISCH_TAC THEN
7139 X_GEN_TAC `u:real^M->real` THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
7140 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
7141 DISCH_THEN(X_CHOOSE_TAC `g:real^N->real^M`) THEN
7142 EXISTS_TAC `(u:real^M->real) o (g:real^N->real^M)` THEN
7143 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN
7144 ASM_REWRITE_TAC[] THEN
7145 ASM_SIMP_TAC[FINITE_DIFF; INDEPENDENT_IMP_FINITE; LINEAR_VSUM] THEN
7146 DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[o_DEF] THEN
7147 CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_EQ_SUPERSET THEN
7148 SIMP_TAC[SUBSET_DIFF; FINITE_DIFF; INDEPENDENT_IMP_FINITE;
7149 LINEAR_CMUL; IN_DIFF; TAUT `a /\ ~(a /\ ~b) <=> a /\ b`;
7150 ASSUME `independent(w:real^M->bool)`;
7151 ASSUME `linear(f:real^M->real^N)`] THEN
7152 REWRITE_TAC[VECTOR_MUL_EQ_0] THEN ASM SET_TAC[];
7153 SUBGOAL_THEN `independent(IMAGE (f:real^M->real^N) (w DIFF v))`
7155 [MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN
7156 ASM_SIMP_TAC[LINEAR_INJECTIVE_0_SUBSPACE; SUBSPACE_SPAN] THEN
7157 ASM_MESON_TAC[INDEPENDENT_MONO; SUBSET_DIFF];
7158 ASM_SIMP_TAC[DIM_SPAN; DIM_EQ_CARD] THEN
7159 W(MP_TAC o PART_MATCH (lhs o rand) CARD_IMAGE_INJ o
7160 lhand o lhand o snd) THEN
7161 ASM_REWRITE_TAC[] THEN
7162 ASM_SIMP_TAC[FINITE_DIFF; CARD_DIFF; INDEPENDENT_IMP_FINITE] THEN
7163 DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC SUB_ADD THEN
7164 ASM_MESON_TAC[CARD_SUBSET; INDEPENDENT_IMP_FINITE]]]);;
7166 let DIM_IMAGE_KERNEL = prove
7167 (`!f:real^M->real^N.
7169 ==> dim(IMAGE f (:real^M)) + dim {x | f x = vec 0} = dimindex(:M)`,
7170 REPEAT STRIP_TAC THEN
7171 MP_TAC(ISPECL [`f:real^M->real^N`; `(:real^M)`] DIM_IMAGE_KERNEL_GEN) THEN
7172 ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV; DIM_UNIV]);;
7174 let DIM_SUMS_INTER = prove
7175 (`!s t:real^N->bool.
7176 subspace s /\ subspace t
7177 ==> dim {x + y | x IN s /\ y IN t} + dim(s INTER t) = dim(s) + dim(t)`,
7178 REPEAT STRIP_TAC THEN
7179 MP_TAC(ISPEC `s INTER t:real^N->bool` BASIS_EXISTS) THEN
7180 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
7181 MP_TAC(ISPECL [`b:real^N->bool`; `s:real^N->bool`]
7182 MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
7183 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7184 DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN
7185 MP_TAC(ISPECL [`b:real^N->bool`; `t:real^N->bool`]
7186 MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
7187 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7188 DISCH_THEN(X_CHOOSE_THEN `d:real^N->bool` STRIP_ASSUME_TAC) THEN
7189 SUBGOAL_THEN `(c:real^N->bool) INTER d = b` ASSUME_TAC THENL
7190 [MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[SUBSET_INTER] THEN
7191 REWRITE_TAC[SUBSET; IN_INTER] THEN X_GEN_TAC `x:real^N` THEN
7192 STRIP_TAC THEN MP_TAC(ISPEC `c:real^N->bool` independent) THEN
7193 ASM_REWRITE_TAC[dependent; NOT_EXISTS_THM] THEN
7194 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
7195 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN STRIP_TAC THEN
7197 SUBGOAL_THEN `(x:real^N) IN span b` MP_TAC THENL
7198 [ASM_MESON_TAC[SUBSET; IN_INTER; SPAN_INC];
7199 MP_TAC(ISPECL [`b:real^N->bool`; `c DELETE (x:real^N)`] SPAN_MONO) THEN
7203 `dim (s INTER t:real^N->bool) = CARD(b:real^N->bool) /\
7204 dim s = CARD c /\ dim t = CARD d /\
7205 dim {x + y:real^N | x IN s /\ y IN t} = CARD(c UNION d:real^N->bool)`
7206 (REPEAT_TCL CONJUNCTS_THEN SUBST1_TAC) THENL
7208 ASM_SIMP_TAC[CARD_UNION_GEN; INDEPENDENT_IMP_FINITE] THEN
7209 MATCH_MP_TAC(ARITH_RULE `b:num <= c ==> (c + d) - b + b = c + d`) THEN
7210 ASM_SIMP_TAC[CARD_SUBSET; INDEPENDENT_IMP_FINITE]] THEN
7211 REPEAT CONJ_TAC THEN MATCH_MP_TAC DIM_UNIQUE THENL
7212 [EXISTS_TAC `b:real^N->bool`;
7213 EXISTS_TAC `c:real^N->bool`;
7214 EXISTS_TAC `d:real^N->bool`;
7215 EXISTS_TAC `c UNION d:real^N->bool`] THEN
7216 ASM_SIMP_TAC[HAS_SIZE; INDEPENDENT_IMP_FINITE; FINITE_UNION] THEN
7217 REWRITE_TAC[UNION_SUBSET; GSYM CONJ_ASSOC] THEN
7218 REWRITE_TAC[SUBSET; IN_ELIM_THM; FORALL_IN_GSPEC] THEN REPEAT CONJ_TAC THENL
7219 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7220 MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN
7221 ASM_SIMP_TAC[SUBSPACE_0; VECTOR_ADD_RID] THEN ASM SET_TAC[];
7222 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7223 MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `x:real^N`] THEN
7224 ASM_SIMP_TAC[SUBSPACE_0; VECTOR_ADD_LID] THEN ASM SET_TAC[];
7225 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
7226 MATCH_MP_TAC SPAN_ADD THEN CONJ_TAC THENL
7227 [MP_TAC(ISPECL[`c:real^N->bool`; `c UNION d:real^N->bool`] SPAN_MONO);
7228 MP_TAC(ISPECL[`d:real^N->bool`; `c UNION d:real^N->bool`] SPAN_MONO)] THEN
7229 REWRITE_TAC[SUBSET_UNION] THEN REWRITE_TAC[SUBSET] THEN
7230 DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[];
7232 ASM_SIMP_TAC[INDEPENDENT_EXPLICIT; FINITE_UNION; INDEPENDENT_IMP_FINITE] THEN
7233 X_GEN_TAC `a:real^N->real` THEN
7234 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
7235 [SET_RULE `s UNION t = s UNION (t DIFF s)`] THEN
7236 ASM_SIMP_TAC[VSUM_UNION; SET_RULE `DISJOINT c (d DIFF c)`;
7237 INDEPENDENT_IMP_FINITE; FINITE_DIFF; FINITE_UNION] THEN
7240 `(vsum (d DIFF c) (\v:real^N. a v % v)) IN span b`
7242 [FIRST_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
7243 REWRITE_TAC[IN_INTER] THEN CONJ_TAC THENL
7244 [FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (VECTOR_ARITH
7245 `a + b = vec 0 ==> b = --a`)) THEN
7246 MATCH_MP_TAC SUBSPACE_NEG THEN ASM_REWRITE_TAC[];
7248 MATCH_MP_TAC SUBSPACE_VSUM THEN
7249 ASM_SIMP_TAC[FINITE_DIFF; INDEPENDENT_IMP_FINITE] THEN
7250 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSPACE_MUL THEN
7251 ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
7253 ASM_SIMP_TAC[SPAN_FINITE; INDEPENDENT_IMP_FINITE; IN_ELIM_THM] THEN
7254 DISCH_THEN(X_CHOOSE_TAC `e:real^N->real`) THEN
7255 MP_TAC(ISPEC `c:real^N->bool` INDEPENDENT_EXPLICIT) THEN
7256 ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
7257 (MP_TAC o SPEC `(\x. if x IN b then a x + e x else a x):real^N->real`)) THEN
7258 REWRITE_TAC[] THEN ONCE_REWRITE_TAC[COND_RAND] THEN
7259 ONCE_REWRITE_TAC[COND_RATOR] THEN ASM_SIMP_TAC[VSUM_CASES] THEN
7260 REWRITE_TAC[VECTOR_ADD_RDISTRIB; GSYM DIFF] THEN
7261 ASM_SIMP_TAC[SET_RULE `b SUBSET c ==> {x | x IN c /\ x IN b} = b`] THEN
7262 ASM_SIMP_TAC[VSUM_ADD; INDEPENDENT_IMP_FINITE] THEN
7263 ONCE_REWRITE_TAC[VECTOR_ARITH `(a + b) + c:real^N = (a + c) + b`] THEN
7264 ASM_SIMP_TAC[GSYM VSUM_UNION; FINITE_DIFF; INDEPENDENT_IMP_FINITE;
7265 SET_RULE `DISJOINT b (c DIFF b)`] THEN
7266 ASM_SIMP_TAC[SET_RULE `b SUBSET c ==> b UNION (c DIFF b) = c`] THEN
7268 SUBGOAL_THEN `!v:real^N. v IN (c DIFF b) ==> a v = &0` ASSUME_TAC THENL
7269 [ASM SET_TAC[]; ALL_TAC] THEN
7270 MP_TAC(ISPEC `d:real^N->bool` INDEPENDENT_EXPLICIT) THEN
7271 ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
7272 (MP_TAC o SPEC `a:real^N->real`)) THEN
7273 SUBGOAL_THEN `d:real^N->bool = b UNION (d DIFF c)`
7274 (fun th -> GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [th])
7275 THENL [ASM SET_TAC[]; ALL_TAC] THEN
7276 ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
7277 ASM_SIMP_TAC[VSUM_UNION; FINITE_DIFF; INDEPENDENT_IMP_FINITE;
7278 SET_RULE `c INTER d = b ==> DISJOINT b (d DIFF c)`] THEN
7279 SUBGOAL_THEN `vsum b (\x:real^N. a x % x) = vsum c (\x. a x % x)`
7280 (fun th -> ASM_REWRITE_TAC[th]) THEN
7281 CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN
7282 ASM_SIMP_TAC[VECTOR_MUL_EQ_0] THEN ASM_MESON_TAC[]);;
7284 let DIM_KERNEL_COMPOSE = prove
7285 (`!f:real^M->real^N g:real^N->real^P.
7286 linear f /\ linear g
7287 ==> dim {x | (g o f) x = vec 0} <=
7288 dim {x | f(x) = vec 0} +
7289 dim {y | g(y) = vec 0}`,
7290 REPEAT STRIP_TAC THEN
7291 MP_TAC(ISPEC `{x | (f:real^M->real^N) x = vec 0}` BASIS_EXISTS_FINITE) THEN
7292 DISCH_THEN(X_CHOOSE_THEN `b:real^M->bool` STRIP_ASSUME_TAC) THEN
7295 IMAGE f c SUBSET {y | g(y):real^P = vec 0} /\
7296 independent (IMAGE (f:real^M->real^N) c) /\
7297 IMAGE f (:real^M) INTER {y | g(y) = vec 0} SUBSET span(IMAGE f c) /\
7298 (!x y. x IN c /\ y IN c ==> (f x = f y <=> x = y)) /\
7299 (IMAGE f c) HAS_SIZE dim (IMAGE f (:real^M) INTER {y | g(y) = vec 0})`
7300 STRIP_ASSUME_TAC THENL
7301 [MP_TAC(ISPEC `IMAGE (f:real^M->real^N) (:real^M) INTER
7302 {x | (g:real^N->real^P) x = vec 0}` BASIS_EXISTS_FINITE) THEN
7303 REWRITE_TAC[SUBSET_INTER; GSYM CONJ_ASSOC; EXISTS_FINITE_SUBSET_IMAGE] THEN
7304 DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN
7305 MP_TAC(ISPECL [`f:real^M->real^N`; `c:real^M->bool`]
7306 IMAGE_INJECTIVE_IMAGE_OF_SUBSET) THEN
7307 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->bool` THEN
7308 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
7309 (CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC)) THEN
7310 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[FINITE_SUBSET];
7312 MATCH_MP_TAC LE_TRANS THEN
7313 EXISTS_TAC `dim(span(b UNION c:real^M->bool))` THEN CONJ_TAC THENL
7314 [MATCH_MP_TAC DIM_SUBSET THEN
7315 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; o_THM] THEN
7316 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
7317 SUBGOAL_THEN `(f:real^M->real^N) x IN span(IMAGE f c)` MP_TAC THENL
7318 [ASM SET_TAC[]; ALL_TAC] THEN
7319 ASM_SIMP_TAC[SPAN_LINEAR_IMAGE; IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN
7320 X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN
7321 SUBST1_TAC(VECTOR_ARITH `x:real^M = y + (x - y)`) THEN
7322 MATCH_MP_TAC SPAN_ADD THEN CONJ_TAC THENL
7323 [ASM_MESON_TAC[SUBSET_UNION; SPAN_MONO; SUBSET]; ALL_TAC] THEN
7324 MATCH_MP_TAC(SET_RULE
7325 `!t. x IN t /\ t SUBSET s ==> x IN s`) THEN
7326 EXISTS_TAC `{x | (f:real^M->real^N) x = vec 0}` THEN CONJ_TAC THENL
7327 [REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[LINEAR_SUB; VECTOR_SUB_EQ];
7328 ASM_MESON_TAC[SUBSET_TRANS; SUBSET_UNION; SPAN_MONO]];
7329 REWRITE_TAC[DIM_SPAN] THEN MATCH_MP_TAC LE_TRANS THEN
7330 EXISTS_TAC `CARD(b UNION c:real^M->bool)` THEN
7331 ASM_SIMP_TAC[DIM_LE_CARD; FINITE_UNION; INDEPENDENT_IMP_FINITE] THEN
7332 MATCH_MP_TAC LE_TRANS THEN
7333 EXISTS_TAC `CARD(b:real^M->bool) + CARD(c:real^M->bool)` THEN
7334 ASM_SIMP_TAC[CARD_UNION_LE] THEN MATCH_MP_TAC LE_ADD2 THEN CONJ_TAC THENL
7335 [ASM_SIMP_TAC[GSYM DIM_EQ_CARD; DIM_SUBSET]; ALL_TAC] THEN
7336 MATCH_MP_TAC LE_TRANS THEN
7337 EXISTS_TAC `dim(IMAGE (f:real^M->real^N) c)` THEN CONJ_TAC THENL
7338 [ASM_SIMP_TAC[DIM_EQ_CARD] THEN
7339 ASM_MESON_TAC[CARD_IMAGE_INJ; LE_REFL];
7340 ASM_SIMP_TAC[GSYM DIM_EQ_CARD; DIM_SUBSET]]]);;
7342 let DIM_ORTHOGONAL_SUM = prove
7343 (`!s t:real^N->bool.
7344 (!x y. x IN s /\ y IN t ==> x dot y = &0)
7345 ==> dim(s UNION t) = dim(s) + dim(t)`,
7346 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
7347 REWRITE_TAC[SPAN_UNION] THEN
7348 SIMP_TAC[GSYM DIM_SUMS_INTER; SUBSPACE_SPAN] THEN
7349 REWRITE_TAC[ARITH_RULE `x = x + y <=> y = 0`] THEN
7350 REWRITE_TAC[DIM_EQ_0; SUBSET; IN_INTER] THEN
7352 `!x:real^N. x IN span s ==> !y:real^N. y IN span t ==> x dot y = &0`
7354 [MATCH_MP_TAC SPAN_INDUCT THEN CONJ_TAC THENL
7355 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
7356 MATCH_MP_TAC SPAN_INDUCT THEN ASM_SIMP_TAC[IN_ELIM_THM] THEN
7357 SIMP_TAC[subspace; IN_ELIM_THM; DOT_RMUL; DOT_RADD; DOT_RZERO] THEN
7359 SIMP_TAC[subspace; IN_ELIM_THM; DOT_LMUL; DOT_LADD; DOT_LZERO] THEN
7361 REWRITE_TAC[IN_SING] THEN MESON_TAC[DOT_EQ_0]]);;
7363 let DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS = prove
7364 (`!s t:real^N->bool.
7365 subspace s /\ subspace t /\ s SUBSET t
7366 ==> dim {y | y IN t /\ !x. x IN s ==> orthogonal x y} + dim s = dim t`,
7367 REPEAT STRIP_TAC THEN
7368 W(MP_TAC o PART_MATCH (rand o rand) DIM_ORTHOGONAL_SUM o lhand o snd) THEN
7370 [SIMP_TAC[IN_ELIM_THM; orthogonal] THEN MESON_TAC[DOT_SYM];
7371 DISCH_THEN(SUBST1_TAC o SYM)] THEN
7372 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN AP_TERM_TAC THEN
7373 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
7374 [MATCH_MP_TAC SPAN_MONO THEN ASM SET_TAC[]; ALL_TAC] THEN
7375 MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN REWRITE_TAC[SUBSPACE_SPAN] THEN
7376 REWRITE_TAC[SPAN_UNION; SUBSET; IN_ELIM_THM] THEN
7377 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7378 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
7379 MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`]
7380 ORTHOGONAL_SUBSPACE_DECOMP_EXISTS) THEN
7381 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN
7382 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^N` THEN
7383 STRIP_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_SYM] THEN
7384 MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN CONJ_TAC THENL
7385 [FIRST_ASSUM(SUBST1_TAC o MATCH_MP (VECTOR_ARITH
7386 `x:real^N = y + z ==> z = x - y`)) THEN
7387 MATCH_MP_TAC SUBSPACE_SUB THEN
7388 ASM_MESON_TAC[SUBSET; SPAN_EQ_SELF];
7389 ASM_MESON_TAC[SPAN_SUPERSET; ORTHOGONAL_SYM]]);;
7391 let DIM_SPECIAL_SUBSPACE = prove
7392 (`!k. dim {x:real^N |
7393 !i. 1 <= i /\ i <= dimindex(:N) /\ i IN k ==> x$i = &0} =
7394 CARD((1..dimindex(:N)) DIFF k)`,
7395 GEN_TAC THEN MATCH_MP_TAC DIM_UNIQUE THEN
7396 EXISTS_TAC `IMAGE (basis:num->real^N) ((1..dimindex(:N)) DIFF k)` THEN
7397 REPEAT CONJ_TAC THENL
7398 [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
7399 SIMP_TAC[BASIS_COMPONENT; IN_DIFF; IN_NUMSEG] THEN MESON_TAC[];
7400 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN X_GEN_TAC `x:real^N` THEN
7401 DISCH_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN
7402 MATCH_MP_TAC SPAN_VSUM THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
7403 X_GEN_TAC `j:num` THEN STRIP_TAC THEN
7404 ASM_CASES_TAC `(x:real^N)$j = &0` THEN
7405 ASM_REWRITE_TAC[SPAN_0; VECTOR_MUL_LZERO] THEN
7406 MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN
7407 REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC `j:num` THEN
7408 REWRITE_TAC[IN_NUMSEG; IN_DIFF] THEN ASM_MESON_TAC[];
7409 MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN
7410 REWRITE_TAC[pairwise; IMP_CONJ; RIGHT_FORALL_IMP_THM;
7411 SET_RULE `~(a IN IMAGE f s) <=> (!x. x IN s ==> ~(f x = a))`] THEN
7412 SIMP_TAC[FORALL_IN_IMAGE; ORTHOGONAL_BASIS_BASIS; BASIS_INJ_EQ;
7413 IN_DIFF; IN_NUMSEG; BASIS_NONZERO];
7414 SIMP_TAC[HAS_SIZE; FINITE_IMAGE; FINITE_DIFF; FINITE_NUMSEG] THEN
7415 MATCH_MP_TAC CARD_IMAGE_INJ THEN
7416 SIMP_TAC[FINITE_DIFF; FINITE_NUMSEG; IMP_CONJ; RIGHT_FORALL_IMP_THM;
7417 SET_RULE `~(a IN IMAGE f s) <=> (!x. x IN s ==> ~(f x = a))`] THEN
7418 SIMP_TAC[FORALL_IN_IMAGE; ORTHOGONAL_BASIS_BASIS; BASIS_INJ_EQ;
7419 IN_DIFF; IN_NUMSEG; BASIS_NONZERO]]);;
7421 (* ------------------------------------------------------------------------- *)
7422 (* More injective/surjective versus dimension variants. *)
7423 (* ------------------------------------------------------------------------- *)
7425 let LINEAR_INJECTIVE_IFF_DIM = prove
7426 (`!f:real^M->real^N.
7428 ==> ((!x y. f x = f y ==> x = y) <=>
7429 dim(IMAGE f (:real^M)) = dimindex(:M))`,
7430 REPEAT STRIP_TAC THEN
7431 MP_TAC(ISPEC `f:real^M->real^N` DIM_IMAGE_KERNEL) THEN
7432 ASM_REWRITE_TAC[] THEN
7433 DISCH_THEN(SUBST1_TAC o MATCH_MP (ARITH_RULE
7434 `x + y:num = m ==> (x = m <=> y = 0)`)) THEN
7435 REWRITE_TAC[DIM_EQ_0; SUBSET; IN_ELIM_THM; IN_SING] THEN
7436 ASM_MESON_TAC[LINEAR_INJECTIVE_0]);;
7438 let LINEAR_SURJECTIVE_IFF_DIM = prove
7439 (`!f:real^M->real^N.
7441 ==> ((!y. ?x. f x = y) <=>
7442 dim(IMAGE f (:real^M)) = dimindex(:N))`,
7443 SIMP_TAC[DIM_EQ_FULL; SPAN_LINEAR_IMAGE; SPAN_UNIV] THEN SET_TAC[]);;
7445 let LINEAR_SURJECTIVE_IFF_INJECTIVE_GEN = prove
7446 (`!f:real^M->real^N.
7447 dimindex(:M) = dimindex(:N) /\ linear f
7448 ==> ((!y. ?x. f x = y) <=> (!x y. f x = f y ==> x = y))`,
7449 SIMP_TAC[LINEAR_INJECTIVE_IFF_DIM; LINEAR_SURJECTIVE_IFF_DIM] THEN
7452 (* ------------------------------------------------------------------------- *)
7453 (* More about product spaces. *)
7454 (* ------------------------------------------------------------------------- *)
7456 let PASTECART_AS_ORTHOGONAL_SUM = prove
7457 (`!x:real^M y:real^N.
7458 pastecart x y = pastecart x (vec 0) + pastecart (vec 0) y`,
7459 REWRITE_TAC[PASTECART_ADD; VECTOR_ADD_LID; VECTOR_ADD_RID]);;
7461 let PCROSS_AS_ORTHOGONAL_SUM = prove
7462 (`!s:real^M->bool t:real^N->bool.
7464 {u + v | u IN IMAGE (\x. pastecart x (vec 0)) s /\
7465 v IN IMAGE (\y. pastecart (vec 0) y) t}`,
7466 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN
7467 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
7468 [PASTECART_AS_ORTHOGONAL_SUM] THEN
7471 let DIM_PCROSS = prove
7472 (`!s:real^M->bool t:real^N->bool.
7473 subspace s /\ subspace t ==> dim(s PCROSS t) = dim s + dim t`,
7474 REPEAT STRIP_TAC THEN REWRITE_TAC[PCROSS_AS_ORTHOGONAL_SUM] THEN
7475 W(MP_TAC o PART_MATCH (lhand o lhand o rand) DIM_SUMS_INTER o
7478 [CONJ_TAC THEN MATCH_MP_TAC SUBSPACE_LINEAR_IMAGE;
7479 MATCH_MP_TAC(ARITH_RULE `c = d /\ b = 0 ==> a + b = c ==> a = d`) THEN
7481 [BINOP_TAC THEN MATCH_MP_TAC DIM_INJECTIVE_LINEAR_IMAGE THEN
7482 SIMP_TAC[PASTECART_INJ];
7483 REWRITE_TAC[DIM_EQ_0; SUBSET; IN_INTER; IN_IMAGE; IN_SING] THEN
7484 REWRITE_TAC[PASTECART_EQ; FSTCART_PASTECART; SNDCART_PASTECART] THEN
7485 MESON_TAC[FSTCART_VEC; SNDCART_VEC]]] THEN
7486 ASM_REWRITE_TAC[linear; GSYM PASTECART_VEC] THEN
7487 REWRITE_TAC[PASTECART_ADD; GSYM PASTECART_CMUL; PASTECART_INJ] THEN
7490 let SPAN_PCROSS_SUBSET = prove
7491 (`!s:real^M->bool t:real^N->bool.
7492 span(s PCROSS t) SUBSET (span s) PCROSS (span t)`,
7493 REPEAT GEN_TAC THEN MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
7494 SIMP_TAC[SUBSPACE_PCROSS; SUBSPACE_SPAN; PCROSS_MONO; SPAN_INC]);;
7496 let SPAN_PCROSS = prove
7497 (`!s:real^M->bool t:real^N->bool.
7498 ~(s = {}) /\ ~(t = {}) /\ (vec 0 IN s \/ vec 0 IN t)
7499 ==> span(s PCROSS t) = (span s) PCROSS (span t)`,
7500 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
7501 REWRITE_TAC[SPAN_PCROSS_SUBSET] THEN
7502 REWRITE_TAC[SUBSET; FORALL_IN_PCROSS] THEN
7503 ONCE_REWRITE_TAC[PASTECART_AS_ORTHOGONAL_SUM] THEN
7505 `(!x:real^M. x IN span s ==> pastecart x (vec 0) IN span(s PCROSS t)) /\
7506 (!y:real^N. y IN span t ==> pastecart (vec 0) y IN span(s PCROSS t))`
7507 (fun th -> ASM_MESON_TAC[th; SPAN_ADD]) THEN
7508 CONJ_TAC THEN MATCH_MP_TAC SPAN_INDUCT THEN REWRITE_TAC[IN_ELIM_THM] THEN
7510 [REWRITE_TAC[IN_ELIM_THM] THEN
7511 ASM_SIMP_TAC[SPAN_SUPERSET; PASTECART_IN_PCROSS];
7512 REWRITE_TAC[subspace; IN_ELIM_THM; PASTECART_VEC; SPAN_0] THEN
7513 CONJ_TAC THEN REPEAT GEN_TAC THENL
7514 [DISCH_THEN(MP_TAC o MATCH_MP SPAN_ADD) THEN
7515 REWRITE_TAC[PASTECART_ADD; VECTOR_ADD_LID];
7516 DISCH_THEN(MP_TAC o MATCH_MP SPAN_MUL) THEN
7517 SIMP_TAC[GSYM PASTECART_CMUL; VECTOR_MUL_RZERO]]])
7519 [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
7520 UNDISCH_TAC `~(t:real^N->bool = {})` THEN
7521 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
7522 DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
7524 `pastecart x (vec 0) =
7525 pastecart (x:real^M) (y:real^N) - pastecart (vec 0) y`
7527 [REWRITE_TAC[PASTECART_SUB; PASTECART_INJ] THEN VECTOR_ARITH_TAC;
7528 MATCH_MP_TAC SPAN_SUB THEN
7529 ASM_SIMP_TAC[SPAN_SUPERSET; PASTECART_IN_PCROSS]];
7530 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
7531 UNDISCH_TAC `~(s:real^M->bool = {})` THEN
7532 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
7533 DISCH_THEN(X_CHOOSE_TAC `x:real^M`) THEN
7535 `pastecart (vec 0) y =
7536 pastecart (x:real^M) (y:real^N) - pastecart x (vec 0)`
7538 [REWRITE_TAC[PASTECART_SUB; PASTECART_INJ] THEN VECTOR_ARITH_TAC;
7539 MATCH_MP_TAC SPAN_SUB THEN
7540 ASM_SIMP_TAC[SPAN_SUPERSET; PASTECART_IN_PCROSS]]]);;
7542 let DIM_PCROSS_STRONG = prove
7543 (`!s:real^M->bool t:real^N->bool.
7544 ~(s = {}) /\ ~(t = {}) /\ (vec 0 IN s \/ vec 0 IN t)
7545 ==> dim(s PCROSS t) = dim s + dim t`,
7546 ONCE_REWRITE_TAC[GSYM DIM_SPAN] THEN
7547 SIMP_TAC[SPAN_PCROSS; DIM_PCROSS; SUBSPACE_SPAN]);;
7549 let SPAN_SUMS = prove
7550 (`!s t:real^N->bool.
7551 ~(s = {}) /\ ~(t = {}) /\ vec 0 IN (s UNION t)
7552 ==> span {x + y | x IN s /\ y IN t} =
7553 {x + y | x IN span s /\ y IN span t}`,
7554 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SPAN_UNION] THEN
7555 MATCH_MP_TAC SUBSET_ANTISYM THEN
7556 CONJ_TAC THEN MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
7557 REWRITE_TAC[SUBSPACE_SPAN; SUBSET; FORALL_IN_GSPEC] THEN
7558 SIMP_TAC[SPAN_ADD; IN_UNION; SPAN_SUPERSET] THEN
7559 X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN
7560 FIRST_X_ASSUM(DISJ_CASES_TAC o GEN_REWRITE_RULE I [IN_UNION]) THENL
7561 [UNDISCH_TAC `~(t:real^N->bool = {})` THEN
7562 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
7563 DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
7564 SUBST1_TAC(VECTOR_ARITH `x:real^N = (x + y) - (vec 0 + y)`) THEN
7565 MATCH_MP_TAC SPAN_SUB THEN CONJ_TAC THEN MATCH_MP_TAC SPAN_SUPERSET THEN
7567 MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN
7568 ASM_MESON_TAC[VECTOR_ADD_RID];
7569 MATCH_MP_TAC SPAN_SUPERSET THEN REWRITE_TAC[IN_ELIM_THM] THEN
7570 ASM_MESON_TAC[VECTOR_ADD_LID];
7571 UNDISCH_TAC `~(s:real^N->bool = {})` THEN
7572 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
7573 DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
7574 SUBST1_TAC(VECTOR_ARITH `x:real^N = (y + x) - (y + vec 0)`) THEN
7575 MATCH_MP_TAC SPAN_SUB THEN CONJ_TAC THEN MATCH_MP_TAC SPAN_SUPERSET THEN
7578 (* ------------------------------------------------------------------------- *)
7579 (* More about rank from the rank/nullspace formula. *)
7580 (* ------------------------------------------------------------------------- *)
7582 let RANK_NULLSPACE = prove
7583 (`!A:real^M^N. rank A + dim {x | A ** x = vec 0} = dimindex(:M)`,
7584 GEN_TAC THEN REWRITE_TAC[RANK_DIM_IM] THEN
7585 MATCH_MP_TAC DIM_IMAGE_KERNEL THEN
7586 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);;
7588 let RANK_SYLVESTER = prove
7589 (`!A:real^N^M B:real^P^N.
7590 rank(A) + rank(B) <= rank(A ** B) + dimindex(:N)`,
7591 REPEAT GEN_TAC THEN MATCH_MP_TAC(ARITH_RULE
7597 ==> ra + rb <= rab + n`) THEN
7598 MAP_EVERY EXISTS_TAC
7599 [`dim {x | (A:real^N^M) ** x = vec 0}`;
7600 `dim {x | (B:real^P^N) ** x = vec 0}`;
7601 `dim {x | ((A:real^N^M) ** (B:real^P^N)) ** x = vec 0}`;
7602 `dimindex(:P)`] THEN
7603 REWRITE_TAC[RANK_NULLSPACE] THEN
7604 REWRITE_TAC[GSYM MATRIX_VECTOR_MUL_ASSOC] THEN
7605 ONCE_REWRITE_TAC[ADD_SYM] THEN
7606 MATCH_MP_TAC(REWRITE_RULE[o_DEF] DIM_KERNEL_COMPOSE) THEN
7607 CONJ_TAC THEN GEN_REWRITE_TAC RAND_CONV [GSYM ETA_AX] THEN
7608 REWRITE_TAC[MATRIX_VECTOR_MUL_LINEAR]);;
7610 let RANK_GRAM = prove
7611 (`!A:real^M^N. rank(transp A ** A) = rank A`,
7612 GEN_TAC THEN MATCH_MP_TAC(ARITH_RULE
7613 `!n n' k. r + n:num = k /\ r' + n' = k /\ n = n' ==> r = r'`) THEN
7614 MAP_EVERY EXISTS_TAC
7615 [`dim {x | (transp A ** (A:real^M^N)) ** x = vec 0}`;
7616 `dim {x | (A:real^M^N) ** x = vec 0}`;
7617 `dimindex(:M)`] THEN
7618 REWRITE_TAC[RANK_NULLSPACE] THEN AP_TERM_TAC THEN
7619 MATCH_MP_TAC SUBSET_ANTISYM THEN
7620 SIMP_TAC[SUBSET; IN_ELIM_THM; GSYM MATRIX_VECTOR_MUL_ASSOC;
7621 MATRIX_VECTOR_MUL_RZERO] THEN
7622 X_GEN_TAC `x:real^M` THEN
7623 DISCH_THEN(MP_TAC o AP_TERM `(dot) (x:real^M)`) THEN
7624 ONCE_REWRITE_TAC[GSYM DOT_LMUL_MATRIX] THEN
7625 REWRITE_TAC[VECTOR_MATRIX_MUL_TRANSP; TRANSP_TRANSP; DOT_RZERO] THEN
7626 REWRITE_TAC[DOT_EQ_0]);;
7628 let RANK_TRIANGLE = prove
7629 (`!A B:real^M^N. rank(A + B) <= rank(A) + rank(B)`,
7630 REPEAT GEN_TAC THEN REWRITE_TAC[RANK_DIM_IM] THEN
7631 MP_TAC(ISPECL [`IMAGE (\x. (A:real^M^N) ** x) (:real^M)`;
7632 `IMAGE (\x. (B:real^M^N) ** x) (:real^M)`]
7633 DIM_SUMS_INTER) THEN
7634 ASM_SIMP_TAC[SUBSPACE_LINEAR_IMAGE; SUBSPACE_UNIV;
7635 MATRIX_VECTOR_MUL_LINEAR] THEN
7636 DISCH_THEN(SUBST1_TAC o SYM) THEN
7637 MATCH_MP_TAC(ARITH_RULE `x:num <= y ==> x <= y + z`) THEN
7638 MATCH_MP_TAC DIM_SUBSET THEN
7639 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_UNIV;
7640 MATRIX_VECTOR_MUL_ADD_RDISTRIB] THEN
7641 REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; IN_UNIV] THEN MESON_TAC[]);;
7643 (* ------------------------------------------------------------------------- *)
7644 (* Infinity norm. *)
7645 (* ------------------------------------------------------------------------- *)
7647 let infnorm = define
7648 `infnorm (x:real^N) = sup { abs(x$i) | 1 <= i /\ i <= dimindex(:N) }`;;
7650 let NUMSEG_DIMINDEX_NONEMPTY = prove
7651 (`?i. i IN 1..dimindex(:N)`,
7652 REWRITE_TAC[MEMBER_NOT_EMPTY; NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]);;
7654 let INFNORM_SET_IMAGE = prove
7655 (`{abs(x$i) | 1 <= i /\ i <= dimindex(:N)} =
7656 IMAGE (\i. abs(x$i)) (1..dimindex(:N))`,
7657 REWRITE_TAC[numseg] THEN SET_TAC[]);;
7659 let INFNORM_SET_LEMMA = prove
7660 (`FINITE {abs((x:real^N)$i) | 1 <= i /\ i <= dimindex(:N)} /\
7661 ~({abs(x$i) | 1 <= i /\ i <= dimindex(:N)} = {})`,
7662 SIMP_TAC[INFNORM_SET_IMAGE; FINITE_NUMSEG; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
7663 REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]);;
7665 let INFNORM_POS_LE = prove
7666 (`!x. &0 <= infnorm x`,
7667 REWRITE_TAC[infnorm] THEN
7668 SIMP_TAC[REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN
7669 REWRITE_TAC[INFNORM_SET_IMAGE; NUMSEG_DIMINDEX_NONEMPTY;
7670 EXISTS_IN_IMAGE; REAL_ABS_POS]);;
7672 let INFNORM_TRIANGLE = prove
7673 (`!x y. infnorm(x + y) <= infnorm x + infnorm y`,
7674 REWRITE_TAC[infnorm] THEN
7675 SIMP_TAC[REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN
7676 ONCE_REWRITE_TAC[GSYM REAL_LE_SUB_RADD] THEN
7677 SIMP_TAC[REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN
7678 ONCE_REWRITE_TAC[REAL_ARITH `x - y <= z <=> x - z <= y`] THEN
7679 SIMP_TAC[REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN
7680 REWRITE_TAC[INFNORM_SET_IMAGE; FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
7681 SIMP_TAC[VECTOR_ADD_COMPONENT; GSYM IN_NUMSEG] THEN
7682 MESON_TAC[NUMSEG_DIMINDEX_NONEMPTY;
7683 REAL_ARITH `abs(x + y) - abs(x) <= abs(y)`]);;
7685 let INFNORM_EQ_0 = prove
7686 (`!x. infnorm x = &0 <=> x = vec 0`,
7687 REWRITE_TAC[GSYM REAL_LE_ANTISYM; INFNORM_POS_LE] THEN
7688 SIMP_TAC[infnorm; REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN
7689 SIMP_TAC[FORALL_IN_IMAGE; INFNORM_SET_IMAGE; CART_EQ; VEC_COMPONENT] THEN
7690 REWRITE_TAC[IN_NUMSEG; REAL_ARITH `abs(x) <= &0 <=> x = &0`]);;
7692 let INFNORM_0 = prove
7693 (`infnorm(vec 0) = &0`,
7694 REWRITE_TAC[INFNORM_EQ_0]);;
7696 let INFNORM_NEG = prove
7697 (`!x. infnorm(--x) = infnorm x`,
7698 GEN_TAC THEN REWRITE_TAC[infnorm] THEN AP_TERM_TAC THEN
7699 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
7700 MESON_TAC[REAL_ABS_NEG; VECTOR_NEG_COMPONENT]);;
7702 let INFNORM_SUB = prove
7703 (`!x y. infnorm(x - y) = infnorm(y - x)`,
7704 MESON_TAC[INFNORM_NEG; VECTOR_NEG_SUB]);;
7706 let REAL_ABS_SUB_INFNORM = prove
7707 (`abs(infnorm x - infnorm y) <= infnorm(x - y)`,
7708 MATCH_MP_TAC(REAL_ARITH
7709 `nx <= n + ny /\ ny <= n + nx ==> abs(nx - ny) <= n`) THEN
7710 MESON_TAC[INFNORM_SUB; VECTOR_SUB_ADD2; INFNORM_TRIANGLE; VECTOR_ADD_SYM]);;
7712 let REAL_ABS_INFNORM = prove
7713 (`!x. abs(infnorm x) = infnorm x`,
7714 REWRITE_TAC[real_abs; INFNORM_POS_LE]);;
7716 let COMPONENT_LE_INFNORM = prove
7717 (`!x:real^N i. 1 <= i /\ i <= dimindex (:N) ==> abs(x$i) <= infnorm x`,
7718 REPEAT GEN_TAC THEN REWRITE_TAC[infnorm] THEN
7719 MP_TAC(SPEC `{ abs((x:real^N)$i) | 1 <= i /\ i <= dimindex(:N) }`
7721 REWRITE_TAC[INFNORM_SET_LEMMA] THEN
7722 SIMP_TAC[INFNORM_SET_IMAGE; FORALL_IN_IMAGE; IN_NUMSEG]);;
7724 let INFNORM_MUL_LEMMA = prove
7725 (`!a x. infnorm(a % x) <= abs a * infnorm x`,
7726 REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [infnorm] THEN
7727 SIMP_TAC[REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN
7728 REWRITE_TAC[FORALL_IN_IMAGE; INFNORM_SET_IMAGE] THEN
7729 SIMP_TAC[REAL_ABS_MUL; VECTOR_MUL_COMPONENT; IN_NUMSEG] THEN
7730 SIMP_TAC[COMPONENT_LE_INFNORM; REAL_LE_LMUL; REAL_ABS_POS]);;
7732 let INFNORM_MUL = prove
7733 (`!a x:real^N. infnorm(a % x) = abs a * infnorm x`,
7734 REPEAT GEN_TAC THEN ASM_CASES_TAC `a = &0` THEN
7735 ASM_REWRITE_TAC[VECTOR_MUL_LZERO; INFNORM_0; REAL_ABS_0; REAL_MUL_LZERO] THEN
7736 REWRITE_TAC[GSYM REAL_LE_ANTISYM; INFNORM_MUL_LEMMA] THEN
7737 GEN_REWRITE_TAC (LAND_CONV o funpow 2 RAND_CONV) [GSYM VECTOR_MUL_LID] THEN
7738 FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP REAL_MUL_LINV) THEN
7739 REWRITE_TAC[GSYM VECTOR_MUL_ASSOC] THEN
7740 MATCH_MP_TAC REAL_LE_TRANS THEN
7741 EXISTS_TAC `abs(a) * abs(inv a) * infnorm(a % x:real^N)` THEN
7742 ASM_SIMP_TAC[INFNORM_MUL_LEMMA; REAL_LE_LMUL; REAL_ABS_POS] THEN
7743 ASM_SIMP_TAC[REAL_MUL_ASSOC; GSYM REAL_ABS_MUL; REAL_MUL_RINV] THEN
7746 let INFNORM_POS_LT = prove
7747 (`!x. &0 < infnorm x <=> ~(x = vec 0)`,
7748 MESON_TAC[REAL_LT_LE; INFNORM_POS_LE; INFNORM_EQ_0]);;
7750 (* ------------------------------------------------------------------------- *)
7751 (* Prove that it differs only up to a bound from Euclidean norm. *)
7752 (* ------------------------------------------------------------------------- *)
7754 let INFNORM_LE_NORM = prove
7755 (`!x. infnorm(x) <= norm(x)`,
7756 SIMP_TAC[infnorm; REAL_SUP_LE_FINITE; INFNORM_SET_LEMMA] THEN
7757 REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[COMPONENT_LE_NORM]);;
7759 let NORM_LE_INFNORM = prove
7760 (`!x:real^N. norm(x) <= sqrt(&(dimindex(:N))) * infnorm(x)`,
7761 GEN_TAC THEN GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o funpow 2 RAND_CONV)
7762 [GSYM CARD_NUMSEG_1] THEN
7763 REWRITE_TAC[vector_norm] THEN MATCH_MP_TAC REAL_LE_LSQRT THEN
7764 SIMP_TAC[DOT_POS_LE; SQRT_POS_LE; REAL_POS; REAL_LE_MUL; INFNORM_POS_LE;
7765 SQRT_POW_2; REAL_POW_MUL] THEN
7766 REWRITE_TAC[dot] THEN MATCH_MP_TAC SUM_BOUND THEN
7767 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN REPEAT STRIP_TAC THEN
7768 REWRITE_TAC[GSYM REAL_POW_2] THEN ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN
7769 MATCH_MP_TAC REAL_POW_LE2 THEN REWRITE_TAC[REAL_ABS_POS] THEN
7770 MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs(y)`) THEN
7771 SIMP_TAC[infnorm; REAL_LE_SUP_FINITE; INFNORM_SET_LEMMA] THEN
7772 REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[REAL_LE_REFL]);;
7774 (* ------------------------------------------------------------------------- *)
7775 (* Equality in Cauchy-Schwarz and triangle inequalities. *)
7776 (* ------------------------------------------------------------------------- *)
7778 let NORM_CAUCHY_SCHWARZ_EQ = prove
7779 (`!x:real^N y. x dot y = norm(x) * norm(y) <=> norm(x) % y = norm(y) % x`,
7780 REPEAT STRIP_TAC THEN
7781 MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN
7782 ASM_REWRITE_TAC[NORM_0; REAL_MUL_LZERO; REAL_MUL_RZERO;
7783 DOT_LZERO; DOT_RZERO; VECTOR_MUL_LZERO; VECTOR_MUL_RZERO] THEN
7784 MP_TAC(ISPEC `norm(y:real^N) % x - norm(x:real^N) % y` DOT_EQ_0) THEN
7785 REWRITE_TAC[DOT_RSUB; DOT_LSUB; DOT_LMUL; DOT_RMUL; GSYM NORM_POW_2;
7786 REAL_POW_2; VECTOR_SUB_EQ] THEN
7787 REWRITE_TAC[DOT_SYM; REAL_ARITH
7788 `y * (y * x * x - x * d) - x * (y * d - x * y * y) =
7789 &2 * x * y * (x * y - d)`] THEN
7790 ASM_SIMP_TAC[REAL_ENTIRE; NORM_EQ_0; REAL_SUB_0; REAL_OF_NUM_EQ; ARITH] THEN
7791 REWRITE_TAC[EQ_SYM_EQ]);;
7793 let NORM_CAUCHY_SCHWARZ_ABS_EQ = prove
7794 (`!x:real^N y. abs(x dot y) = norm(x) * norm(y) <=>
7795 norm(x) % y = norm(y) % x \/ norm(x) % y = --norm(y) % x`,
7796 SIMP_TAC[REAL_ARITH `&0 <= a ==> (abs x = a <=> x = a \/ --x = a)`;
7797 REAL_LE_MUL; NORM_POS_LE; GSYM DOT_RNEG] THEN
7799 GEN_REWRITE_TAC (LAND_CONV o funpow 3 RAND_CONV) [GSYM NORM_NEG] THEN
7800 REWRITE_TAC[NORM_CAUCHY_SCHWARZ_EQ] THEN REWRITE_TAC[NORM_NEG] THEN
7801 BINOP_TAC THEN VECTOR_ARITH_TAC);;
7803 let NORM_TRIANGLE_EQ = prove
7804 (`!x y:real^N. norm(x + y) = norm(x) + norm(y) <=> norm(x) % y = norm(y) % x`,
7805 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM NORM_CAUCHY_SCHWARZ_EQ] THEN
7806 MATCH_MP_TAC EQ_TRANS THEN
7807 EXISTS_TAC `norm(x + y:real^N) pow 2 = (norm(x) + norm(y)) pow 2` THEN
7809 [REWRITE_TAC[REAL_RING `x pow 2 = y pow 2 <=> x = y \/ x + y = &0`] THEN
7810 MAP_EVERY (MP_TAC o C ISPEC NORM_POS_LE)
7811 [`x + y:real^N`; `x:real^N`; `y:real^N`] THEN
7813 REWRITE_TAC[NORM_POW_2; DOT_LADD; DOT_RADD; REAL_ARITH
7814 `(x + y) pow 2 = x pow 2 + y pow 2 + &2 * x * y`] THEN
7815 REWRITE_TAC[DOT_SYM] THEN REAL_ARITH_TAC]);;
7817 let DIST_TRIANGLE_EQ = prove
7818 (`!x y z. dist(x,z) = dist(x,y) + dist(y,z) <=>
7819 norm (x - y) % (y - z) = norm (y - z) % (x - y)`,
7820 REWRITE_TAC[GSYM NORM_TRIANGLE_EQ] THEN NORM_ARITH_TAC);;
7822 let NORM_CROSS_MULTIPLY = prove
7824 a % x = b % y /\ &0 < a /\ &0 < b
7825 ==> norm y % x = norm x % y`,
7826 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
7827 ASM_CASES_TAC `y:real^N = vec 0` THEN
7828 ASM_SIMP_TAC[VECTOR_MUL_EQ_0; REAL_LT_IMP_NZ; VECTOR_MUL_RZERO] THEN
7829 DISCH_THEN(MP_TAC o AP_TERM `\x:real^N. inv(a) % x`) THEN
7830 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_LT_IMP_NZ; VECTOR_MUL_LID;
7831 NORM_MUL; REAL_ABS_MUL; REAL_ABS_INV] THEN
7832 ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE; REAL_MUL_AC]);;
7834 (* ------------------------------------------------------------------------- *)
7836 (* ------------------------------------------------------------------------- *)
7838 let collinear = new_definition
7839 `collinear s <=> ?u. !x y. x IN s /\ y IN s ==> ?c. x - y = c % u`;;
7841 let COLLINEAR_SUBSET = prove
7842 (`!s t. collinear t /\ s SUBSET t ==> collinear s`,
7843 REWRITE_TAC[collinear] THEN SET_TAC[]);;
7845 let COLLINEAR_EMPTY = prove
7847 REWRITE_TAC[collinear; NOT_IN_EMPTY]);;
7849 let COLLINEAR_SING = prove
7850 (`!x. collinear {x}`,
7851 SIMP_TAC[collinear; IN_SING; VECTOR_SUB_REFL] THEN
7852 MESON_TAC[VECTOR_MUL_LZERO]);;
7854 let COLLINEAR_2 = prove
7855 (`!x y:real^N. collinear {x,y}`,
7856 REPEAT GEN_TAC THEN REWRITE_TAC[collinear; IN_INSERT; NOT_IN_EMPTY] THEN
7857 EXISTS_TAC `x - y:real^N` THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
7858 [EXISTS_TAC `&0`; EXISTS_TAC `&1`; EXISTS_TAC `-- &1`; EXISTS_TAC `&0`] THEN
7861 let COLLINEAR_SMALL = prove
7862 (`!s. FINITE s /\ CARD s <= 2 ==> collinear s`,
7863 REWRITE_TAC[ARITH_RULE `s <= 2 <=> s = 0 \/ s = 1 \/ s = 2`] THEN
7864 REWRITE_TAC[LEFT_OR_DISTRIB; GSYM HAS_SIZE] THEN
7865 CONV_TAC(ONCE_DEPTH_CONV HAS_SIZE_CONV) THEN
7866 REPEAT STRIP_TAC THEN
7867 ASM_REWRITE_TAC[COLLINEAR_EMPTY; COLLINEAR_SING; COLLINEAR_2]);;
7869 let COLLINEAR_3 = prove
7870 (`!x y z. collinear {x,y,z} <=> collinear {vec 0,x - y,z - y}`,
7872 REWRITE_TAC[collinear; FORALL_IN_INSERT; IMP_CONJ; RIGHT_FORALL_IMP_THM;
7874 AP_TERM_TAC THEN ABS_TAC THEN
7875 MESON_TAC[VECTOR_ARITH `x - y = (x - y) - vec 0`;
7876 VECTOR_ARITH `y - x = vec 0 - (x - y)`;
7877 VECTOR_ARITH `x - z:real^N = (x - y) - (z - y)`]);;
7879 let COLLINEAR_LEMMA = prove
7880 (`!x y:real^N. collinear {vec 0,x,y} <=>
7881 x = vec 0 \/ y = vec 0 \/ ?c. y = c % x`,
7883 MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN
7884 TRY(ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_SING; COLLINEAR_2] THEN NO_TAC) THEN
7885 ASM_REWRITE_TAC[collinear] THEN EQ_TAC THENL
7886 [DISCH_THEN(X_CHOOSE_THEN `u:real^N`
7887 (fun th -> MP_TAC(SPECL [`x:real^N`; `vec 0:real^N`] th) THEN
7888 MP_TAC(SPECL [`y:real^N`; `vec 0:real^N`] th))) THEN
7889 REWRITE_TAC[IN_INSERT; VECTOR_SUB_RZERO] THEN
7890 DISCH_THEN(X_CHOOSE_THEN `e:real` SUBST_ALL_TAC) THEN
7891 DISCH_THEN(X_CHOOSE_THEN `d:real` SUBST_ALL_TAC) THEN
7892 EXISTS_TAC `e / d` THEN REWRITE_TAC[VECTOR_MUL_ASSOC] THEN
7893 RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_MUL_EQ_0; DE_MORGAN_THM]) THEN
7894 ASM_SIMP_TAC[REAL_DIV_RMUL];
7895 STRIP_TAC THEN EXISTS_TAC `x:real^N` THEN ASM_REWRITE_TAC[] THEN
7896 REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN
7897 ASM_REWRITE_TAC[] THENL
7898 [EXISTS_TAC `&0`; EXISTS_TAC `-- &1`; EXISTS_TAC `--c`;
7899 EXISTS_TAC `&1`; EXISTS_TAC `&0`; EXISTS_TAC `&1 - c`;
7900 EXISTS_TAC `c:real`; EXISTS_TAC `c - &1`; EXISTS_TAC `&0`] THEN
7901 VECTOR_ARITH_TAC]);;
7903 let COLLINEAR_LEMMA_ALT = prove
7904 (`!x y. collinear {vec 0,x,y} <=> x = vec 0 \/ ?c. y = c % x`,
7905 REWRITE_TAC[COLLINEAR_LEMMA] THEN MESON_TAC[VECTOR_MUL_LZERO]);;
7907 let NORM_CAUCHY_SCHWARZ_EQUAL = prove
7908 (`!x y:real^N. abs(x dot y) = norm(x) * norm(y) <=> collinear {vec 0,x,y}`,
7909 REPEAT GEN_TAC THEN REWRITE_TAC[NORM_CAUCHY_SCHWARZ_ABS_EQ] THEN
7910 MAP_EVERY ASM_CASES_TAC [`x:real^N = vec 0`; `y:real^N = vec 0`] THEN
7911 TRY(ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_SING; COLLINEAR_2; NORM_0;
7912 VECTOR_MUL_LZERO; VECTOR_MUL_RZERO] THEN NO_TAC) THEN
7913 ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN EQ_TAC THENL
7915 [FIRST_X_ASSUM(MP_TAC o AP_TERM
7916 `(%) (inv(norm(x:real^N))):real^N->real^N`);
7917 FIRST_X_ASSUM(MP_TAC o AP_TERM
7918 `(%) (--inv(norm(x:real^N))):real^N->real^N`)] THEN
7919 ASM_REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LNEG] THEN
7920 ASM_SIMP_TAC[REAL_MUL_LINV; NORM_EQ_0; VECTOR_MUL_LNEG; VECTOR_MUL_LID;
7921 VECTOR_ARITH `--x = --y <=> x:real^N = y`] THEN
7923 STRIP_TAC THEN ASM_REWRITE_TAC[NORM_MUL; VECTOR_MUL_ASSOC] THEN
7924 MATCH_MP_TAC(MESON[]
7925 `t = a \/ t = b ==> t % x = a % x \/ t % x = b % x`) THEN
7926 REWRITE_TAC[GSYM REAL_MUL_LNEG;
7927 REAL_ARITH `x * c = d * x <=> x * (c - d) = &0`] THEN
7928 ASM_REWRITE_TAC[REAL_ENTIRE; NORM_EQ_0] THEN REAL_ARITH_TAC]);;
7930 let DOT_CAUCHY_SCHWARZ_EQUAL = prove
7932 (x dot y) pow 2 = (x dot x) * (y dot y) <=>
7933 collinear {vec 0,x,y}`,
7934 REWRITE_TAC[GSYM NORM_CAUCHY_SCHWARZ_EQUAL] THEN
7935 REPEAT GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH
7936 `&0 <= y /\ (u:real = v <=> x = abs y) ==> (u = v <=> x = y)`) THEN
7937 SIMP_TAC[NORM_POS_LE; REAL_LE_MUL] THEN
7938 REWRITE_TAC[REAL_EQ_SQUARE_ABS] THEN REWRITE_TAC[REAL_POW_MUL; NORM_POW_2]);;
7940 let COLLINEAR_3_EXPAND = prove
7941 (`!a b c:real^N. collinear{a,b,c} <=> a = c \/ ?u. b = u % a + (&1 - u) % c`,
7943 ONCE_REWRITE_TAC[SET_RULE `{a,b,c} = {a,c,b}`] THEN
7944 ONCE_REWRITE_TAC[COLLINEAR_3] THEN
7945 REWRITE_TAC[COLLINEAR_LEMMA; VECTOR_SUB_EQ] THEN
7946 ASM_CASES_TAC `a:real^N = c` THEN ASM_REWRITE_TAC[] THEN
7947 ASM_CASES_TAC `b:real^N = c` THEN
7948 ASM_REWRITE_TAC[VECTOR_ARITH `u % c + (&1 - u) % c = c`] THENL
7949 [EXISTS_TAC `&0` THEN VECTOR_ARITH_TAC;
7950 AP_TERM_TAC THEN ABS_TAC THEN VECTOR_ARITH_TAC]);;
7952 let COLLINEAR_TRIPLES = prove
7955 ==> (collinear(a INSERT b INSERT s) <=>
7956 !x. x IN s ==> collinear{a,b,x})`,
7957 REPEAT STRIP_TAC THEN EQ_TAC THENL
7958 [REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
7959 (REWRITE_RULE[IMP_CONJ] COLLINEAR_SUBSET)) THEN
7961 ONCE_REWRITE_TAC[SET_RULE `{a,b,x} = {a,x,b}`] THEN
7962 ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN DISCH_TAC THEN
7964 `!x:real^N. x IN (a INSERT b INSERT s) ==> ?u. x = u % a + (&1 - u) % b`
7966 [ASM_REWRITE_TAC[FORALL_IN_INSERT] THEN CONJ_TAC THENL
7967 [EXISTS_TAC `&1` THEN VECTOR_ARITH_TAC;
7968 EXISTS_TAC `&0` THEN VECTOR_ARITH_TAC];
7969 POP_ASSUM_LIST(K ALL_TAC) THEN DISCH_TAC THEN
7970 REWRITE_TAC[collinear] THEN EXISTS_TAC `b - a:real^N` THEN
7971 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
7972 FIRST_X_ASSUM(fun th -> MP_TAC(SPEC `x:real^N` th) THEN MP_TAC(SPEC
7973 `y:real^N` th)) THEN
7974 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
7975 ASM_REWRITE_TAC[VECTOR_ARITH
7976 `(u % a + (&1 - u) % b) - (v % a + (&1 - v) % b):real^N =
7977 (v - u) % (b - a)`] THEN
7980 let COLLINEAR_4_3 = prove
7983 ==> (collinear {a,b,c,d} <=> collinear{a,b,c} /\ collinear{a,b,d})`,
7984 REPEAT STRIP_TAC THEN
7985 MP_TAC(ISPECL [`{c:real^N,d}`; `a:real^N`; `b:real^N`]
7986 COLLINEAR_TRIPLES) THEN
7987 ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
7988 REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY]);;
7990 let COLLINEAR_3_TRANS = prove
7992 collinear{a,b,c} /\ collinear{b,c,d} /\ ~(b = c) ==> collinear{a,b,d}`,
7993 REPEAT STRIP_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN
7994 EXISTS_TAC `{b:real^N,c,a,d}` THEN ASM_SIMP_TAC[COLLINEAR_4_3] THEN
7995 CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
7996 REPEAT(POP_ASSUM MP_TAC) THEN SIMP_TAC[INSERT_AC]);;
7998 let ORTHOGONAL_TO_ORTHOGONAL_2D = prove
8000 ~(x = vec 0) /\ orthogonal x y /\ orthogonal x z
8001 ==> collinear {vec 0,y,z}`,
8002 REWRITE_TAC[orthogonal; GSYM DOT_CAUCHY_SCHWARZ_EQUAL; GSYM DOT_EQ_0] THEN
8003 REWRITE_TAC[DOT_2] THEN CONV_TAC REAL_RING);;
8005 let COLLINEAR_3_2D = prove
8006 (`!x y z:real^2. collinear{x,y,z} <=>
8007 (z$1 - x$1) * (y$2 - x$2) = (y$1 - x$1) * (z$2 - x$2)`,
8008 ONCE_REWRITE_TAC[COLLINEAR_3] THEN
8009 REWRITE_TAC[GSYM DOT_CAUCHY_SCHWARZ_EQUAL] THEN
8010 REWRITE_TAC[DOT_2; VECTOR_SUB_COMPONENT] THEN CONV_TAC REAL_RING);;
8012 let COLLINEAR_3_DOT_MULTIPLES = prove
8014 collinear {a,b,c} <=>
8015 ((b - a) dot (b - a)) % (c - a) = ((c - a) dot (b - a)) % (b - a)`,
8016 REWRITE_TAC[VECTOR_SUB_RZERO] THEN
8017 REPEAT GEN_TAC THEN ASM_CASES_TAC `b:real^N = a` THENL
8018 [ASM_REWRITE_TAC[COLLINEAR_2; INSERT_AC; DOT_RZERO; VECTOR_MUL_LZERO;
8020 ONCE_REWRITE_TAC[COLLINEAR_3] THEN
8021 POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
8022 REWRITE_TAC[GSYM DOT_CAUCHY_SCHWARZ_EQUAL; GSYM DOT_EQ_0] THEN
8023 REWRITE_TAC[GSYM DOT_EQ_0; DOT_RSUB; DOT_LSUB; DOT_RMUL; DOT_LMUL] THEN
8024 REWRITE_TAC[DOT_SYM] THEN CONV_TAC REAL_RING]);;
8026 (* ------------------------------------------------------------------------- *)
8028 (* ------------------------------------------------------------------------- *)
8030 let between = new_definition
8031 `between x (a,b) <=> dist(a,b) = dist(a,x) + dist(x,b)`;;
8033 let BETWEEN_REFL = prove
8034 (`!a b. between a (a,b) /\ between b (a,b) /\ between a (a,a)`,
8035 REWRITE_TAC[between] THEN NORM_ARITH_TAC);;
8037 let BETWEEN_REFL_EQ = prove
8038 (`!a x. between x (a,a) <=> x = a`,
8039 REWRITE_TAC[between] THEN NORM_ARITH_TAC);;
8041 let BETWEEN_SYM = prove
8042 (`!a b x. between x (a,b) <=> between x (b,a)`,
8043 REWRITE_TAC[between] THEN NORM_ARITH_TAC);;
8045 let BETWEEN_ANTISYM = prove
8046 (`!a b c. between a (b,c) /\ between b (a,c) ==> a = b`,
8047 REWRITE_TAC[between; DIST_SYM] THEN NORM_ARITH_TAC);;
8049 let BETWEEN_TRANS = prove
8050 (`!a b c d. between a (b,c) /\ between d (a,c) ==> between d (b,c)`,
8051 REWRITE_TAC[between; DIST_SYM] THEN NORM_ARITH_TAC);;
8053 let BETWEEN_TRANS_2 = prove
8054 (`!a b c d. between a (b,c) /\ between d (a,b) ==> between a (c,d)`,
8055 REWRITE_TAC[between; DIST_SYM] THEN NORM_ARITH_TAC);;
8057 let BETWEEN_NORM = prove
8059 between x (a,b) <=> norm(x - a) % (b - x) = norm(b - x) % (x - a)`,
8060 REPEAT GEN_TAC THEN REWRITE_TAC[between; DIST_TRIANGLE_EQ] THEN
8061 REWRITE_TAC[NORM_SUB] THEN VECTOR_ARITH_TAC);;
8063 let BETWEEN_DOT = prove
8065 between x (a,b) <=> (x - a) dot (b - x) = norm(x - a) * norm(b - x)`,
8066 REWRITE_TAC[BETWEEN_NORM; NORM_CAUCHY_SCHWARZ_EQ]);;
8068 let BETWEEN_EXISTS_EXTENSION = prove
8070 between b (a,x) /\ ~(b = a) ==> ?d. &0 <= d /\ x = b + d % (b - a)`,
8071 REPEAT GEN_TAC THEN REWRITE_TAC[BETWEEN_NORM] THEN STRIP_TAC THEN
8072 EXISTS_TAC `norm(x - b:real^N) / norm(b - a)` THEN
8073 SIMP_TAC[REAL_LE_DIV; NORM_POS_LE] THEN FIRST_X_ASSUM
8074 (MP_TAC o AP_TERM `(%) (inv(norm(b - a:real^N))):real^N->real^N`) THEN
8075 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; NORM_EQ_0; VECTOR_SUB_EQ] THEN
8078 let BETWEEN_IMP_COLLINEAR = prove
8079 (`!a b x:real^N. between x (a,b) ==> collinear {a,x,b}`,
8080 REPEAT GEN_TAC THEN MAP_EVERY
8081 (fun t -> ASM_CASES_TAC t THEN
8082 TRY(ASM_REWRITE_TAC[INSERT_AC; COLLINEAR_2] THEN NO_TAC))
8083 [`x:real^N = a`; `x:real^N = b`; `a:real^N = b`] THEN
8084 ONCE_REWRITE_TAC[COLLINEAR_3; BETWEEN_NORM] THEN
8085 DISCH_TAC THEN REWRITE_TAC[COLLINEAR_LEMMA] THEN
8086 REPEAT DISJ2_TAC THEN EXISTS_TAC `--(norm(b - x:real^N) / norm(x - a))` THEN
8087 MATCH_MP_TAC VECTOR_MUL_LCANCEL_IMP THEN EXISTS_TAC `norm(x - a:real^N)` THEN
8088 ASM_REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RNEG] THEN
8089 ASM_SIMP_TAC[REAL_DIV_LMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN
8092 let COLLINEAR_BETWEEN_CASES = prove
8094 collinear {a,b,c} <=>
8095 between a (b,c) \/ between b (c,a) \/ between c (a,b)`,
8096 REPEAT STRIP_TAC THEN EQ_TAC THENL
8097 [REWRITE_TAC[COLLINEAR_3_EXPAND] THEN
8098 ASM_CASES_TAC `c:real^N = a` THEN ASM_REWRITE_TAC[BETWEEN_REFL] THEN
8099 STRIP_TAC THEN ASM_REWRITE_TAC[between; dist] THEN
8100 REWRITE_TAC[VECTOR_ARITH `(u % a + (&1 - u) % c) - c = --u % (c - a)`;
8101 VECTOR_ARITH `(u % a + (&1 - u) % c) - a = (&1 - u) % (c - a)`;
8102 VECTOR_ARITH `c - (u % a + (&1 - u) % c) = u % (c - a)`;
8103 VECTOR_ARITH `a - (u % a + (&1 - u) % c) = (u - &1) % (c - a)`] THEN
8104 REWRITE_TAC[NORM_MUL] THEN
8105 SUBST1_TAC(NORM_ARITH `norm(a - c:real^N) = norm(c - a)`) THEN
8106 REWRITE_TAC[REAL_ARITH `a * c + c = (a + &1) * c`; GSYM REAL_ADD_RDISTRIB;
8107 REAL_ARITH `c + a * c = (a + &1) * c`] THEN
8108 ASM_REWRITE_TAC[REAL_EQ_MUL_RCANCEL;
8109 REAL_RING `n = x * n <=> n = &0 \/ x = &1`] THEN
8110 ASM_REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ] THEN REAL_ARITH_TAC;
8111 DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN (MP_TAC o MATCH_MP
8112 BETWEEN_IMP_COLLINEAR)) THEN
8113 REWRITE_TAC[INSERT_AC]]);;
8115 let COLLINEAR_DIST_BETWEEN = prove
8116 (`!a b x. collinear {x,a,b} /\
8117 dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)
8118 ==> between x (a,b)`,
8119 SIMP_TAC[COLLINEAR_BETWEEN_CASES; between; DIST_SYM] THEN NORM_ARITH_TAC);;
8121 let BETWEEN_COLLINEAR_DIST_EQ = prove
8124 collinear {a, x, b} /\
8125 dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)`,
8126 REPEAT GEN_TAC THEN EQ_TAC THENL
8127 [SIMP_TAC[BETWEEN_IMP_COLLINEAR] THEN REWRITE_TAC[between] THEN
8129 MESON_TAC[COLLINEAR_DIST_BETWEEN; INSERT_AC]]);;
8131 let COLLINEAR_1 = prove
8132 (`!s:real^1->bool. collinear s`,
8133 GEN_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN
8134 EXISTS_TAC `(vec 0:real^1) INSERT (vec 1) INSERT s` THEN
8135 CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
8136 W(MP_TAC o PART_MATCH (lhs o rand) COLLINEAR_TRIPLES o snd) THEN
8137 REWRITE_TAC[VEC_EQ; ARITH_EQ] THEN DISCH_THEN SUBST1_TAC THEN
8138 REWRITE_TAC[COLLINEAR_BETWEEN_CASES] THEN
8139 REWRITE_TAC[between; DIST_REAL; GSYM drop; DROP_VEC; REAL_ABS_NUM] THEN
8142 (* ------------------------------------------------------------------------- *)
8143 (* Midpoint between two points. *)
8144 (* ------------------------------------------------------------------------- *)
8146 let midpoint = new_definition
8147 `midpoint(a,b) = inv(&2) % (a + b)`;;
8149 let MIDPOINT_REFL = prove
8150 (`!x. midpoint(x,x) = x`,
8151 REWRITE_TAC[midpoint] THEN VECTOR_ARITH_TAC);;
8153 let MIDPOINT_SYM = prove
8154 (`!a b. midpoint(a,b) = midpoint(b,a)`,
8155 REWRITE_TAC[midpoint; VECTOR_ADD_SYM]);;
8157 let DIST_MIDPOINT = prove
8158 (`!a b. dist(a,midpoint(a,b)) = dist(a,b) / &2 /\
8159 dist(b,midpoint(a,b)) = dist(a,b) / &2 /\
8160 dist(midpoint(a,b),a) = dist(a,b) / &2 /\
8161 dist(midpoint(a,b),b) = dist(a,b) / &2`,
8162 REWRITE_TAC[midpoint] THEN NORM_ARITH_TAC);;
8164 let MIDPOINT_EQ_ENDPOINT = prove
8165 (`!a b. (midpoint(a,b) = a <=> a = b) /\
8166 (midpoint(a,b) = b <=> a = b) /\
8167 (a = midpoint(a,b) <=> a = b) /\
8168 (b = midpoint(a,b) <=> a = b)`,
8169 REWRITE_TAC[midpoint] THEN NORM_ARITH_TAC);;
8171 let BETWEEN_MIDPOINT = prove
8172 (`!a b. between (midpoint(a,b)) (a,b) /\ between (midpoint(a,b)) (b,a)`,
8173 REWRITE_TAC[between; midpoint] THEN NORM_ARITH_TAC);;
8175 let MIDPOINT_LINEAR_IMAGE = prove
8176 (`!f a b. linear f ==> midpoint(f a,f b) = f(midpoint(a,b))`,
8177 SIMP_TAC[midpoint; LINEAR_ADD; LINEAR_CMUL]);;
8179 let COLLINEAR_MIDPOINT = prove
8180 (`!a b. collinear{a,midpoint(a,b),b}`,
8181 REPEAT GEN_TAC THEN REWRITE_TAC[COLLINEAR_3_EXPAND; midpoint] THEN
8182 DISJ2_TAC THEN EXISTS_TAC `&1 / &2` THEN VECTOR_ARITH_TAC);;
8184 let MIDPOINT_COLLINEAR = prove
8187 ==> (b = midpoint(a,c) <=> collinear{a,b,c} /\ dist(a,b) = dist(b,c))`,
8188 REPEAT STRIP_TAC THEN
8189 MATCH_MP_TAC(TAUT `(a ==> b) /\ (b ==> (a <=> c)) ==> (a <=> b /\ c)`) THEN
8190 SIMP_TAC[COLLINEAR_MIDPOINT] THEN ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN
8191 STRIP_TAC THEN ASM_REWRITE_TAC[midpoint; dist] THEN
8193 [VECTOR_ARITH `a - (u % a + (&1 - u) % c) = (&1 - u) % (a - c)`;
8194 VECTOR_ARITH `(u % a + (&1 - u) % c) - c = u % (a - c)`;
8195 VECTOR_ARITH `u % a + (&1 - u) % c = inv (&2) % (a + c) <=>
8196 (u - &1 / &2) % (a - c) = vec 0`] THEN
8197 ASM_SIMP_TAC[NORM_MUL; REAL_EQ_MUL_RCANCEL; NORM_EQ_0; VECTOR_SUB_EQ;
8198 VECTOR_MUL_EQ_0] THEN
8201 let MIDPOINT_BETWEEN = prove
8203 b = midpoint (a,c) <=> between b (a,c) /\ dist (a,b) = dist (b,c)`,
8204 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = c` THENL
8205 [ASM_SIMP_TAC[BETWEEN_REFL_EQ; MIDPOINT_REFL; DIST_SYM]; ALL_TAC] THEN
8206 EQ_TAC THEN SIMP_TAC[BETWEEN_MIDPOINT; DIST_MIDPOINT] THEN
8207 ASM_MESON_TAC[MIDPOINT_COLLINEAR; BETWEEN_IMP_COLLINEAR]);;
8209 (* ------------------------------------------------------------------------- *)
8210 (* General "one way" lemma for properties preserved by injective map. *)
8211 (* ------------------------------------------------------------------------- *)
8213 let WLOG_LINEAR_INJECTIVE_IMAGE_2 = prove
8214 (`!P Q. (!f s. P s /\ linear f ==> Q(IMAGE f s)) /\
8215 (!g t. Q t /\ linear g ==> P(IMAGE g t))
8216 ==> !f:real^M->real^N.
8217 linear f /\ (!x y. f x = f y ==> x = y)
8218 ==> !s. Q(IMAGE f s) <=> P s`,
8219 REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[] THEN DISCH_TAC THEN
8220 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
8221 ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN
8222 DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN
8223 FIRST_X_ASSUM(MP_TAC o SPECL
8224 [`g:real^N->real^M`; `IMAGE (f:real^M->real^N) s`]) THEN
8225 ASM_REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID]);;
8227 let WLOG_LINEAR_INJECTIVE_IMAGE_2_ALT = prove
8228 (`!P Q f s. (!h u. P u /\ linear h ==> Q(IMAGE h u)) /\
8229 (!g t. Q t /\ linear g ==> P(IMAGE g t)) /\
8230 linear f /\ (!x y. f x = f y ==> x = y)
8231 ==> (Q(IMAGE f s) <=> P s)`,
8232 REPEAT GEN_TAC THEN STRIP_TAC THEN
8233 MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
8234 WLOG_LINEAR_INJECTIVE_IMAGE_2) THEN
8235 ASM_REWRITE_TAC[]);;
8237 let WLOG_LINEAR_INJECTIVE_IMAGE = prove
8238 (`!P. (!f s. P s /\ linear f ==> P(IMAGE f s))
8239 ==> !f:real^N->real^N. linear f /\ (!x y. f x = f y ==> x = y)
8240 ==> !s. P(IMAGE f s) <=> P s`,
8241 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC WLOG_LINEAR_INJECTIVE_IMAGE_2 THEN
8242 ASM_REWRITE_TAC[]);;
8244 let WLOG_LINEAR_INJECTIVE_IMAGE_ALT = prove
8245 (`!P f s. (!g t. P t /\ linear g ==> P(IMAGE g t)) /\
8246 linear f /\ (!x y. f x = f y ==> x = y)
8247 ==> (P(IMAGE f s) <=> P s)`,
8248 REPEAT GEN_TAC THEN STRIP_TAC THEN
8249 MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
8250 WLOG_LINEAR_INJECTIVE_IMAGE) THEN
8251 ASM_REWRITE_TAC[]);;
8253 (* ------------------------------------------------------------------------- *)
8254 (* Inference rule to apply it conveniently. *)
8256 (* |- !f s. P s /\ linear f ==> P(IMAGE f s) [or /\ commuted] *)
8257 (* --------------------------------------------------------------- *)
8258 (* |- !f s. linear f /\ (!x y. f x = f y ==> x = y) *)
8259 (* ==> (Q(IMAGE f s) <=> P s) *)
8260 (* ------------------------------------------------------------------------- *)
8262 let LINEAR_INVARIANT_RULE th =
8263 let [f;s] = fst(strip_forall(concl th)) in
8264 let (rm,rn) = dest_fun_ty (type_of f) in
8265 let m = last(snd(dest_type rm)) and n = last(snd(dest_type rn)) in
8266 let th' = INST_TYPE [m,n; n,m] th in
8267 let th0 = CONJ th th' in
8268 let th1 = try MATCH_MP WLOG_LINEAR_INJECTIVE_IMAGE_2 th0
8270 MATCH_MP WLOG_LINEAR_INJECTIVE_IMAGE_2
8271 (GEN_REWRITE_RULE (BINOP_CONV o ONCE_DEPTH_CONV) [CONJ_SYM] th0) in
8272 GEN_REWRITE_RULE BINDER_CONV [RIGHT_IMP_FORALL_THM] th1;;
8274 (* ------------------------------------------------------------------------- *)
8275 (* Immediate application. *)
8276 (* ------------------------------------------------------------------------- *)
8278 let SUBSPACE_LINEAR_IMAGE_EQ = prove
8279 (`!f s. linear f /\ (!x y. f x = f y ==> x = y)
8280 ==> (subspace (IMAGE f s) <=> subspace s)`,
8281 MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE SUBSPACE_LINEAR_IMAGE));;
8283 (* ------------------------------------------------------------------------- *)
8284 (* Storage of useful "invariance under linear map / translation" theorems. *)
8285 (* ------------------------------------------------------------------------- *)
8287 let invariant_under_linear = ref([]:thm list);;
8289 let invariant_under_translation = ref([]:thm list);;
8291 let scaling_theorems = ref([]:thm list);;
8293 (* ------------------------------------------------------------------------- *)
8294 (* Scaling theorems and derivation from linear invariance. *)
8295 (* ------------------------------------------------------------------------- *)
8297 let LINEAR_SCALING = prove
8298 (`!c. linear(\x:real^N. c % x)`,
8299 REWRITE_TAC[linear] THEN VECTOR_ARITH_TAC);;
8301 let INJECTIVE_SCALING = prove
8302 (`!c. (!x y:real^N. c % x = c % y ==> x = y) <=> ~(c = &0)`,
8303 GEN_TAC THEN REWRITE_TAC[VECTOR_MUL_LCANCEL] THEN
8304 ASM_CASES_TAC `c:real = &0` THEN ASM_REWRITE_TAC[] THEN
8305 DISCH_THEN(MP_TAC o SPECL [`vec 0:real^N`; `vec 1:real^N`]) THEN
8306 REWRITE_TAC[VEC_EQ; ARITH]);;
8308 let SURJECTIVE_SCALING = prove
8309 (`!c. (!y:real^N. ?x. c % x = y) <=> ~(c = &0)`,
8310 ASM_SIMP_TAC[LINEAR_SURJECTIVE_IFF_INJECTIVE; LINEAR_SCALING] THEN
8311 REWRITE_TAC[INJECTIVE_SCALING]);;
8313 let SCALING_INVARIANT =
8314 let pths = (CONJUNCTS o UNDISCH o prove)
8316 ==> linear(\x:real^N. c % x) /\
8317 (!x y:real^N. c % x = c % y ==> x = y) /\
8318 (!y:real^N. ?x. c % x = y)`,
8319 SIMP_TAC[REAL_LT_IMP_NZ; LINEAR_SCALING;
8320 INJECTIVE_SCALING; SURJECTIVE_SCALING])
8321 and sc_tm = `\x:real^N. c % x`
8322 and sa_tm = `&0:real < c`
8323 and c_tm = `c:real` in
8325 let ith = BETA_RULE(ISPEC sc_tm th) in
8326 let avs,bod = strip_forall(concl ith) in
8327 let cjs = conjuncts(lhand bod) in
8328 let cths = map (fun t -> find(fun th -> aconv (concl th) t) pths) cjs in
8329 let oth = MP (SPECL avs ith) (end_itlist CONJ cths) in
8330 GEN c_tm (DISCH sa_tm (GENL avs oth));;
8332 let scaling_theorems = ref([]:thm list);;
8334 (* ------------------------------------------------------------------------- *)
8335 (* Augmentation of the lists. The "add_linear_invariants" also updates *)
8336 (* the scaling theorems automatically, so only a few of those will need *)
8337 (* to be added explicitly. *)
8338 (* ------------------------------------------------------------------------- *)
8340 let add_scaling_theorems thl =
8341 (scaling_theorems := (!scaling_theorems) @ thl);;
8343 let add_linear_invariants thl =
8344 ignore(mapfilter (fun th -> add_scaling_theorems[SCALING_INVARIANT th]) thl);
8345 (invariant_under_linear := (!invariant_under_linear) @ thl);;
8347 let add_translation_invariants thl =
8348 (invariant_under_translation := (!invariant_under_translation) @ thl);;
8350 (* ------------------------------------------------------------------------- *)
8351 (* Start with some basic set equivalences. *)
8352 (* We give them all an injectivity hypothesis even if it's not necessary. *)
8353 (* For just the intersection theorem we add surjectivity (more manageable *)
8354 (* than assuming that the set isn't empty). *)
8355 (* ------------------------------------------------------------------------- *)
8358 (`!f. (!x y. f x = f y ==> x = y)
8359 ==> (if p then f x else f y) = f(if p then x else y) /\
8360 (if p then IMAGE f s else IMAGE f t) =
8361 IMAGE f (if p then s else t) /\
8362 (f x) INSERT (IMAGE f s) = IMAGE f (x INSERT s) /\
8363 (IMAGE f s) DELETE (f x) = IMAGE f (s DELETE x) /\
8364 (IMAGE f s) INTER (IMAGE f t) = IMAGE f (s INTER t) /\
8365 (IMAGE f s) UNION (IMAGE f t) = IMAGE f (s UNION t) /\
8366 UNIONS(IMAGE (IMAGE f) u) = IMAGE f (UNIONS u) /\
8367 (IMAGE f s) DIFF (IMAGE f t) = IMAGE f (s DIFF t) /\
8368 (IMAGE f s (f x) <=> s x) /\
8369 ((f x) IN (IMAGE f s) <=> x IN s) /\
8370 ((f o xs) (n:num) = f(xs n)) /\
8371 ((f o pt) (tt:real^1) = f(pt tt)) /\
8372 (DISJOINT (IMAGE f s) (IMAGE f t) <=> DISJOINT s t) /\
8373 ((IMAGE f s) SUBSET (IMAGE f t) <=> s SUBSET t) /\
8374 ((IMAGE f s) PSUBSET (IMAGE f t) <=> s PSUBSET t) /\
8375 (IMAGE f s = IMAGE f t <=> s = t) /\
8376 ((IMAGE f s) HAS_SIZE n <=> s HAS_SIZE n) /\
8377 (FINITE(IMAGE f s) <=> FINITE s) /\
8378 (INFINITE(IMAGE f s) <=> INFINITE s)`,
8379 REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[IMAGE_UNIONS] THEN
8380 REWRITE_TAC[o_THM; MESON[IN] `IMAGE f s y <=> y IN IMAGE f s`] THEN
8381 REPLICATE_TAC 2 (CONJ_TAC THENL [MESON_TAC[]; ALL_TAC]) THEN
8382 REWRITE_TAC[INFINITE; TAUT `(~p <=> ~q) <=> (p <=> q)`] THEN
8383 REPLICATE_TAC 11 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
8384 REWRITE_TAC[HAS_SIZE] THEN
8385 ASM_MESON_TAC[FINITE_IMAGE_INJ_EQ; CARD_IMAGE_INJ]) in
8386 let f = `f:real^M->real^N`
8387 and imf = `IMAGE (f:real^M->real^N)`
8389 and ima = `IMAGE (\x:real^N. a + x)`
8390 and vth = VECTOR_ARITH `!x y. a + x:real^N = a + y ==> x = y` in
8391 let th1 = UNDISCH(ISPEC f th_sets)
8393 (GEN_REWRITE_RULE LAND_CONV [INJECTIVE_IMAGE] (ISPEC imf th_sets))
8394 and th2 = MATCH_MP th_sets vth
8396 (BETA_RULE(GEN_REWRITE_RULE LAND_CONV [INJECTIVE_IMAGE] (ISPEC ima th_sets)))
8398 let fn a th = GENL (a::subtract (frees(concl th)) [a]) th in
8399 add_linear_invariants(map (fn f o DISCH_ALL) (CONJUNCTS th1 @ CONJUNCTS th1')),
8400 add_translation_invariants(map (fn a) (CONJUNCTS th2 @ CONJUNCTS th2'));;
8403 (`!f:A->B s. (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
8404 ==> INTERS (IMAGE (IMAGE f) s) = IMAGE f (INTERS s)`,
8405 REWRITE_TAC[INTERS_IMAGE] THEN SET_TAC[]) in
8408 INTERS (IMAGE (IMAGE (\x. a + x)) s) = IMAGE (\x. a + x) (INTERS s)`,
8409 REPEAT GEN_TAC THEN MATCH_MP_TAC th_set THEN
8410 REWRITE_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN
8411 REWRITE_TAC[VECTOR_ARITH `a + x:real^N = y <=> x = y - a`; EXISTS_REFL]) in
8412 add_linear_invariants [th_set],add_translation_invariants[th_vec];;
8414 (* ------------------------------------------------------------------------- *)
8415 (* Now add arithmetical equivalences. *)
8416 (* ------------------------------------------------------------------------- *)
8418 let PRESERVES_NORM_PRESERVES_DOT = prove
8419 (`!f:real^M->real^N x y.
8420 linear f /\ (!x. norm(f x) = norm x)
8421 ==> (f x) dot (f y) = x dot y`,
8422 REWRITE_TAC[NORM_EQ] THEN REPEAT STRIP_TAC THEN
8423 FIRST_ASSUM(MP_TAC o SPEC `x + y:real^M`) THEN
8424 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_ADD th]) THEN
8425 ASM_REWRITE_TAC[DOT_LADD; DOT_RADD] THEN
8426 REWRITE_TAC[DOT_SYM] THEN REAL_ARITH_TAC);;
8428 let PRESERVES_NORM_INJECTIVE = prove
8429 (`!f:real^M->real^N.
8430 linear f /\ (!x. norm(f x) = norm x)
8431 ==> !x y. f x = f y ==> x = y`,
8432 SIMP_TAC[LINEAR_INJECTIVE_0; GSYM NORM_EQ_0]);;
8434 let ORTHOGONAL_LINEAR_IMAGE_EQ = prove
8435 (`!f:real^M->real^N x y.
8436 linear f /\ (!x. norm(f x) = norm x)
8437 ==> (orthogonal (f x) (f y) <=> orthogonal x y)`,
8438 SIMP_TAC[orthogonal; PRESERVES_NORM_PRESERVES_DOT]);;
8440 add_linear_invariants
8445 MIDPOINT_LINEAR_IMAGE;
8446 MESON[] `!f:real^M->real^N x.
8447 (!x. norm(f x) = norm x) ==> norm(f x) = norm x`;
8448 PRESERVES_NORM_PRESERVES_DOT;
8449 MESON[dist; LINEAR_SUB]
8450 `!f:real^M->real^N x y.
8451 linear f /\ (!x. norm(f x) = norm x)
8452 ==> dist(f x,f y) = dist(x,y)`;
8453 MESON[] `!f:real^M->real^N x y.
8454 (!x y. f x = f y ==> x = y) ==> (f x = f y <=> x = y)`;
8455 SUBSPACE_LINEAR_IMAGE_EQ;
8456 ORTHOGONAL_LINEAR_IMAGE_EQ;
8458 DEPENDENT_LINEAR_IMAGE_EQ;
8459 INDEPENDENT_LINEAR_IMAGE_EQ;
8460 DIM_INJECTIVE_LINEAR_IMAGE];;
8462 add_translation_invariants
8463 [VECTOR_ARITH `!a x y. a + x:real^N = a + y <=> x = y`;
8464 NORM_ARITH `!a x y. dist(a + x,a + y) = dist(x,y)`;
8465 VECTOR_ARITH `!a x y. &1 / &2 % ((a + x) + (a + y)) = a + &1 / &2 % (x + y)`;
8466 VECTOR_ARITH `!a x y. inv(&2) % ((a + x) + (a + y)) = a + inv(&2) % (x + y)`;
8467 VECTOR_ARITH `!a x y. (a + x) - (a + y):real^N = x - y`;
8468 (EQT_ELIM o (REWRITE_CONV[midpoint] THENC(EQT_INTRO o NORM_ARITH)))
8469 `!a x y. midpoint(a + x,a + y) = a + midpoint(x,y)`;
8470 (EQT_ELIM o (REWRITE_CONV[between] THENC(EQT_INTRO o NORM_ARITH)))
8471 `!a x y z. between (a + x) (a + y,a + z) <=> between x (y,z)`];;
8474 (`!a s b c:real^N. (a + b) + c IN IMAGE (\x. a + x) s <=> (b + c) IN s`,
8475 REWRITE_TAC[IN_IMAGE; VECTOR_ARITH
8476 `(a + b) + c:real^N = a + x <=> x = b + c`] THEN
8478 add_translation_invariants [th];;
8480 (* ------------------------------------------------------------------------- *)
8481 (* A few for lists. *)
8482 (* ------------------------------------------------------------------------- *)
8484 let MEM_TRANSLATION = prove
8485 (`!a:real^N x l. MEM (a + x) (MAP (\x. a + x) l) <=> MEM x l`,
8486 REWRITE_TAC[MEM_MAP; VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN
8489 add_translation_invariants [MEM_TRANSLATION];;
8491 let MEM_LINEAR_IMAGE = prove
8492 (`!f:real^M->real^N x l.
8493 linear f /\ (!x y. f x = f y ==> x = y)
8494 ==> (MEM (f x) (MAP f l) <=> MEM x l)`,
8495 REWRITE_TAC[MEM_MAP] THEN MESON_TAC[]);;
8497 add_linear_invariants [MEM_LINEAR_IMAGE];;
8499 let LENGTH_TRANSLATION = prove
8500 (`!a:real^N l. LENGTH(MAP (\x. a + x) l) = LENGTH l`,
8501 REWRITE_TAC[LENGTH_MAP]) in
8502 add_translation_invariants [LENGTH_TRANSLATION];;
8504 let LENGTH_LINEAR_IMAGE = prove
8505 (`!f:real^M->real^N l. linear f ==> LENGTH(MAP f l) = LENGTH l`,
8506 REWRITE_TAC[LENGTH_MAP]) in
8507 add_linear_invariants [LENGTH_LINEAR_IMAGE];;
8509 let CONS_TRANSLATION = prove
8511 CONS ((\x. a + x) h) (MAP (\x. a + x) t) = MAP (\x. a + x) (CONS h t)`,
8512 REWRITE_TAC[MAP]) in
8513 add_translation_invariants [CONS_TRANSLATION];;
8515 let CONS_LINEAR_IMAGE = prove
8516 (`!f:real^M->real^N h t.
8517 linear f ==> CONS (f h) (MAP f t) = MAP f (CONS h t)`,
8518 REWRITE_TAC[MAP]) in
8519 add_linear_invariants [CONS_LINEAR_IMAGE];;
8521 let APPEND_TRANSLATION = prove
8523 APPEND (MAP (\x. a + x) l1) (MAP (\x. a + x) l2) =
8524 MAP (\x. a + x) (APPEND l1 l2)`,
8525 REWRITE_TAC[MAP_APPEND]) in
8526 add_translation_invariants [APPEND_TRANSLATION];;
8528 let APPEND_LINEAR_IMAGE = prove
8529 (`!f:real^M->real^N l1 l2.
8530 linear f ==> APPEND (MAP f l1) (MAP f l2) = MAP f (APPEND l1 l2)`,
8531 REWRITE_TAC[MAP_APPEND]) in
8532 add_linear_invariants [APPEND_LINEAR_IMAGE];;
8534 let REVERSE_TRANSLATION = prove
8535 (`!a:real^N l. REVERSE(MAP (\x. a + x) l) = MAP (\x. a + x) (REVERSE l)`,
8536 REWRITE_TAC[MAP_REVERSE]) in
8537 add_translation_invariants [REVERSE_TRANSLATION];;
8539 let REVERSE_LINEAR_IMAGE = prove
8540 (`!f:real^M->real^N l. linear f ==> REVERSE(MAP f l) = MAP f (REVERSE l)`,
8541 REWRITE_TAC[MAP_REVERSE]) in
8542 add_linear_invariants [REVERSE_LINEAR_IMAGE];;
8544 (* ------------------------------------------------------------------------- *)
8545 (* A few scaling theorems that don't come from invariance theorems. Most are *)
8546 (* artificially weak with 0 < c hypotheses, so we don't bind them to names. *)
8547 (* ------------------------------------------------------------------------- *)
8549 let DOT_SCALING = prove
8550 (`!c. &0 < c ==> !x y. (c % x) dot (c % y) = c pow 2 * (x dot y)`,
8551 REWRITE_TAC[DOT_LMUL; DOT_RMUL] THEN REAL_ARITH_TAC) in
8552 add_scaling_theorems [DOT_SCALING];;
8554 let DIST_SCALING = prove
8555 (`!c. &0 < c ==> !x y. dist(c % x,c % y) = c * dist(x,y)`,
8556 SIMP_TAC[DIST_MUL; REAL_ARITH `&0 < c ==> abs c = c`]) in
8557 add_scaling_theorems [DIST_SCALING];;
8559 let ORTHOGONAL_SCALING = prove
8560 (`!c. &0 < c ==> !x y. orthogonal (c % x) (c % y) <=> orthogonal x y`,
8561 REWRITE_TAC[orthogonal; DOT_LMUL; DOT_RMUL] THEN CONV_TAC REAL_FIELD) in
8562 add_scaling_theorems [ORTHOGONAL_SCALING];;
8564 let NORM_SCALING = prove
8565 (`!c. &0 < c ==> !x. norm(c % x) = c * norm x`,
8566 SIMP_TAC[NORM_MUL; REAL_ARITH `&0 < c ==> abs c = c`]) in
8567 add_scaling_theorems [NORM_SCALING];;
8569 add_scaling_theorems
8570 [REAL_ARITH `!c. &0 < c ==> !a b. a * c * b = c * a * b`;
8571 REAL_ARITH `!c. &0 < c ==> !a b. c * a + c * b = c * (a + b)`;
8572 REAL_ARITH `!c. &0 < c ==> !a b. c * a - c * b = c * (a - b)`;
8573 REAL_FIELD `!c. &0 < c ==> !a b. c * a = c * b <=> a = b`;
8574 MESON[REAL_LT_LMUL_EQ] `!c. &0 < c ==> !a b. c * a < c * b <=> a < b`;
8575 MESON[REAL_LE_LMUL_EQ] `!c. &0 < c ==> !a b. c * a <= c * b <=> a <= b`;
8576 MESON[REAL_LT_LMUL_EQ; real_gt]
8577 `!c. &0 < c ==> !a b. c * a > c * b <=> a > b`;
8578 MESON[REAL_LE_LMUL_EQ; real_ge]
8579 `!c. &0 < c ==> !a b. c * a >= c * b <=> a >= b`;
8581 `!c. &0 < c ==> !a n. (c * a) pow n = c pow n * a pow n`;
8582 REAL_ARITH `!c. &0 < c ==> !a b n. a * c pow n * b = c pow n * a * b`;
8584 `!c. &0 < c ==> !a b n. c pow n * a + c pow n * b = c pow n * (a + b)`;
8586 `!c. &0 < c ==> !a b n. c pow n * a - c pow n * b = c pow n * (a - b)`;
8587 MESON[REAL_POW_LT; REAL_EQ_LCANCEL_IMP; REAL_LT_IMP_NZ]
8588 `!c. &0 < c ==> !a b n. c pow n * a = c pow n * b <=> a = b`;
8589 MESON[REAL_LT_LMUL_EQ; REAL_POW_LT]
8590 `!c. &0 < c ==> !a b n. c pow n * a < c pow n * b <=> a < b`;
8591 MESON[REAL_LE_LMUL_EQ; REAL_POW_LT]
8592 `!c. &0 < c ==> !a b n. c pow n * a <= c pow n * b <=> a <= b`;
8593 MESON[REAL_LT_LMUL_EQ; real_gt; REAL_POW_LT]
8594 `!c. &0 < c ==> !a b n. c pow n * a > c pow n * b <=> a > b`;
8595 MESON[REAL_LE_LMUL_EQ; real_ge; REAL_POW_LT]
8596 `!c. &0 < c ==> !a b n. c pow n * a >= c pow n * b <=> a >= b`];;
8598 (* ------------------------------------------------------------------------- *)
8599 (* Theorem deducing quantifier mappings from surjectivity. *)
8600 (* ------------------------------------------------------------------------- *)
8602 let QUANTIFY_SURJECTION_THM = prove
8605 ==> ((!P. (!x. P x) <=> (!x. P (f x))) /\
8606 (!P. (?x. P x) <=> (?x. P (f x))) /\
8607 (!Q. (!s. Q s) <=> (!s. Q(IMAGE f s))) /\
8608 (!Q. (?s. Q s) <=> (?s. Q(IMAGE f s)))) /\
8609 (!P. {x | P x} = IMAGE f {x | P(f x)})`,
8610 GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [SURJECTIVE_RIGHT_INVERSE] THEN
8611 DISCH_THEN(X_CHOOSE_TAC `g:B->A`) THEN
8612 SUBGOAL_THEN `!s. IMAGE (f:A->B) (IMAGE g s) = s` ASSUME_TAC THENL
8613 [ASM SET_TAC[]; CONJ_TAC THENL [ASM MESON_TAC[]; ASM SET_TAC[]]]);;
8615 let QUANTIFY_SURJECTION_HIGHER_THM = prove
8618 ==> ((!P. (!x. P x) <=> (!x. P (f x))) /\
8619 (!P. (?x. P x) <=> (?x. P (f x))) /\
8620 (!Q. (!s. Q s) <=> (!s. Q(IMAGE f s))) /\
8621 (!Q. (?s. Q s) <=> (?s. Q(IMAGE f s))) /\
8622 (!Q. (!s. Q s) <=> (!s. Q(IMAGE (IMAGE f) s))) /\
8623 (!Q. (?s. Q s) <=> (?s. Q(IMAGE (IMAGE f) s))) /\
8624 (!P. (!g:real^1->B. P g) <=> (!g. P(f o g))) /\
8625 (!P. (?g:real^1->B. P g) <=> (?g. P(f o g))) /\
8626 (!P. (!g:num->B. P g) <=> (!g. P(f o g))) /\
8627 (!P. (?g:num->B. P g) <=> (?g. P(f o g))) /\
8628 (!Q. (!l. Q l) <=> (!l. Q(MAP f l))) /\
8629 (!Q. (?l. Q l) <=> (?l. Q(MAP f l)))) /\
8630 ((!P. {x | P x} = IMAGE f {x | P(f x)}) /\
8631 (!Q. {s | Q s} = IMAGE (IMAGE f) {s | Q(IMAGE f s)}) /\
8632 (!R. {l | R l} = IMAGE (MAP f) {l | R(MAP f l)}))`,
8633 GEN_TAC THEN DISCH_TAC THEN CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN
8634 ASM_REWRITE_TAC[GSYM SURJECTIVE_FORALL_THM; GSYM SURJECTIVE_EXISTS_THM;
8635 GSYM SURJECTIVE_IMAGE_THM; SURJECTIVE_IMAGE; SURJECTIVE_MAP] THEN
8636 REWRITE_TAC[FUN_EQ_THM; o_THM; GSYM SKOLEM_THM] THEN ASM_MESON_TAC[]);;
8638 (* ------------------------------------------------------------------------- *)
8639 (* Apply such quantifier and set expansions once per level at depth. *)
8640 (* In the PARTIAL version, avoid expanding named variables in list. *)
8641 (* ------------------------------------------------------------------------- *)
8643 let PARTIAL_EXPAND_QUANTS_CONV avoid th =
8644 let ath,sth = CONJ_PAIR th in
8645 let conv1 = GEN_REWRITE_CONV I [ath]
8646 and conv2 = GEN_REWRITE_CONV I [sth] in
8648 let th = conv1 tm in
8649 if mem (fst(dest_var(fst(dest_abs(rand tm))))) avoid
8650 then failwith "Not going to expand this variable" else th in
8652 ((conv1' THENC BINDER_CONV conv) ORELSEC
8654 RAND_CONV(RAND_CONV(ABS_CONV(BINDER_CONV(LAND_CONV conv))))) ORELSEC
8655 SUB_CONV conv) tm in
8658 let EXPAND_QUANTS_CONV = PARTIAL_EXPAND_QUANTS_CONV [];;