(* ========================================================================= *)
(* 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`;;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);;
 
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)`,
 
let CONTINUOUS_CROSS = prove
 (`!net:(A)net f g.
        f continuous net /\ g continuous net
        ==> (\x. (f x) cross (g x)) continuous net`,
 
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)`,