(* ========================================================================= *)
(* Cross products in real^3. *)
(* ========================================================================= *)
needs "Multivariate/topology.ml";;
prioritize_vector();;
(* ------------------------------------------------------------------------- *)
(* The definition. *)
(* ------------------------------------------------------------------------- *)
parse_as_infix("cross",(20,"right"));;
let cross = new_definition
`(a:real^3) cross (b:real^3) =
vector [a$2 * b$3 - a$3 * b$2;
a$3 * b$1 - a$1 * b$3;
a$1 * b$2 - a$2 * b$1] :real^3`;;
(* ------------------------------------------------------------------------- *)
(* Some simple automation. *)
(* ------------------------------------------------------------------------- *)
let VEC3_TAC =
SIMP_TAC[CART_EQ; LAMBDA_BETA; FORALL_3; SUM_3; DIMINDEX_3; VECTOR_3;
vector_add; vec; dot; cross; orthogonal; basis; DET_3;
vector_neg; vector_sub; vector_mul; ARITH] THEN
CONV_TAC REAL_RING;;
let VEC3_RULE tm = prove(tm,VEC3_TAC);;
(* ------------------------------------------------------------------------- *)
(* Basic lemmas. *)
(* ------------------------------------------------------------------------- *)
let ORTHOGONAL_CROSS = prove
(`!x y. orthogonal (x cross y) x /\ orthogonal (x cross y) y /\
orthogonal x (x cross y) /\ orthogonal y (x cross y)`,
VEC3_TAC);;
let CROSS_LADD = prove
(`!x y z. (x + y) cross z = (x cross z) + (y cross z)`,
VEC3_TAC);;
let CROSS_RADD = prove
(`!x y z. x cross (y + z) = (x cross y) + (x cross z)`,
VEC3_TAC);;
let CROSS_JACOBI = prove
(`!x y z.
x cross (y cross z) + y cross (z cross x) + z cross (x cross y) = vec 0`,
VEC3_TAC);;
let DOT_CROSS_SELF = prove
(`(!x y. x dot (x cross y) = &0) /\
(!x y. x dot (y cross x) = &0) /\
(!x y. (x cross y) dot y = &0) /\
(!x y. (y cross x) dot y = &0)`,
VEC3_TAC);;
let CROSS_COMPONENTS = prove
(`!x y. (x cross y)$1 = x$2 * y$3 - y$2 * x$3 /\
(x cross y)$2 = x$3 * y$1 - y$3 * x$1 /\
(x cross y)$3 = x$1 * y$2 - y$1 * x$2`,
VEC3_TAC);;
let CROSS_BASIS = prove
(`(basis 1) cross (basis 2) = basis 3 /\
(basis 2) cross (basis 1) = --(basis 3) /\
(basis 2) cross (basis 3) = basis 1 /\
(basis 3) cross (basis 2) = --(basis 1) /\
(basis 3) cross (basis 1) = basis 2 /\
(basis 1) cross (basis 3) = --(basis 2)`,
VEC3_TAC);;
let CROSS_BASIS_NONZERO = prove
(`!u. ~(u = vec 0)
==> ~(u cross basis 1 = vec 0) \/
~(u cross basis 2 = vec 0) \/
~(u cross basis 3 = vec 0)`,
VEC3_TAC);;
let CROSS_CROSS_DET = prove
(`!w x y z. (w cross x) cross (y cross z) =
det(vector[w;x;z]:real^3^3) % y -
det(vector[w;x;y]:real^3^3) % z`,
VEC3_TAC);;
let DOT_CROSS = prove
(`!w x y z. (w cross x) dot (y cross z) =
(w dot y) * (x dot z) - (w dot z) * (x dot y)`,
VEC3_TAC);;
let NORM_CROSS = prove
(`!x y. norm(x cross y) pow 2 =
norm(x) pow 2 * norm(y) pow 2 - (x dot y) pow 2`,
let CROSS_0 = prove
(`(!x. vec 0 cross x = vec 0) /\
(!x. x cross vec 0 = vec 0)`,
VEC3_TAC);;
(* ------------------------------------------------------------------------- *)
(* Preservation by rotation, or other orthogonal transformation up to sign. *)
(* ------------------------------------------------------------------------- *)
let CROSS_LINEAR_IMAGE = prove
(`!f x y. linear f /\ (!x. norm(f x) = norm x) /\ det(matrix f) = &1
==> (f x) cross (f y) = f(x cross y)`,
(* ------------------------------------------------------------------------- *)
(* Continuity. *)
(* ------------------------------------------------------------------------- *)
let CONTINUOUS_CROSS = prove
(`!net:(A)net f g.
f continuous net /\ g continuous net
==> (\x. (f x) cross (g x)) continuous net`,
(* ------------------------------------------------------------------------- *)
(* Prove a weaker variant for more convenient interface with functions *)
(* intended to work in 1 dimension. *)
(* ------------------------------------------------------------------------- *)
let CROSS_LINEAR_IMAGE_WEAK = prove
(`!f x y. linear f /\ (!x. norm(f x) = norm x) /\
(2 <= dimindex(:3) ==> det(matrix f) = &1)
==> (f x) cross (f y) = f(x cross y)`,
add_linear_invariants [CROSS_LINEAR_IMAGE_WEAK];;