(* ========================================================================= *)
(* Proof that Tarski's axioms for geometry hold in Euclidean space.          *)
(* ========================================================================= *)
needs "Multivariate/convex.ml";;
(* ------------------------------------------------------------------------- *)
(* Axiom 1 (reflexivity for equidistance).                                   *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Axiom 2 (transitivity for equidistance).                                  *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Axiom 3 (identity for equidistance).                                      *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Axiom 4 (segment construction).                                           *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Axiom 5 (five-segments axiom).                                            *)
(* ------------------------------------------------------------------------- *)
let TARSKI_AXIOM_5_EUCLIDEAN = prove
 (`!a b c x:real^2 a' b' c' x':real^2.
        ~(a = b) /\
        dist(a,b) = dist(a',b') /\
        dist(a,c) = dist(a',c') /\
        dist(b,c) = dist(b',c') /\
        between b (a,x) /\ between b' (a',x') /\ dist(b,x) = dist(b',x')
        ==> dist(c,x) = dist(c',x')`,
  let lemma = prove
   (`!a b x y:real^N.
      ~(b = a) /\ between b (a,x) /\ between b (a,y) /\ dist(b,x) = dist(b,y)
      ==> x = y`,
    REPEAT STRIP_TAC THEN REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE
     [IMP_CONJ] BETWEEN_EXISTS_EXTENSION))) THEN ASM_SIMP_TAC[] THEN
    REPEAT STRIP_TAC THEN UNDISCH_TAC `dist(b:real^N,x) = dist(b,y)` THEN
    ASM_REWRITE_TAC[NORM_ARITH `dist(b:real^N,b + x) = norm x`; NORM_MUL] THEN
    ASM_SIMP_TAC[REAL_EQ_MUL_RCANCEL; NORM_EQ_0; real_abs; VECTOR_SUB_EQ]) in
  REPEAT STRIP_TAC THEN MP_TAC(ISPECL
   [`a:real^2`; `b:real^2`; `c:real^2`; `a':real^2`; `b':real^2`; `c':real^2`]
   RIGID_TRANSFORMATION_BETWEEN_3) THEN
  ANTS_TAC THENL [ASM_MESON_TAC[DIST_EQ_0; DIST_SYM]; ALL_TAC] THEN
  DISCH_THEN(X_CHOOSE_THEN `k:real^2`
   (X_CHOOSE_THEN `f:real^2->real^2` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))) THEN
  DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN SUBST_ALL_TAC) THEN
  SUBGOAL_THEN `x' = k + (f:real^2->real^2) x` SUBST1_TAC THENL
   [MATCH_MP_TAC lemma THEN MAP_EVERY EXISTS_TAC
      [`k + (f:real^2->real^2) a`; `k + (f:real^2->real^2) b`];
    ALL_TAC] THEN
  ASM_REWRITE_TAC[NORM_ARITH `dist(a + x:real^N,a + y) = dist(x,y)`;
    BETWEEN_TRANSLATION; VECTOR_ARITH `a + x:real^N = a + y <=> x = y`] THEN
  ASM_MESON_TAC[BETWEEN_TRANSLATION; orthogonal_transformation;
                NORM_ARITH `dist(a + x:real^N,a + y) = dist(x,y)`;
                ORTHOGONAL_TRANSFORMATION_ISOMETRY; BETWEEN_LINEAR_IMAGE_EQ;
                DIST_EQ_0; ORTHOGONAL_TRANSFORMATION_INJECTIVE]);;  
 
(* ------------------------------------------------------------------------- *)
(* Axiom 6 (identity for between-ness).                                      *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Axiom 7 (Pasch's axiom).                                                  *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Axiom 8 (lower 2-dimensional axiom).                                      *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Axiom 9 (upper 2-dimensional axiom).                                      *)
(* ------------------------------------------------------------------------- *)
let TARSKI_AXIOM_9_EUCLIDEAN = prove
 (`!p q a b c:real^2.
        ~(p = q) /\
        dist(a,p) = dist(a,q) /\ dist(b,p) = dist(b,q) /\ dist(c,p) = dist(c,q)
        ==> between b (a,c) \/ between c (b,a) \/ between a (c,b)`,
 
 
(* ------------------------------------------------------------------------- *)
(* Axiom 10 (Euclidean axiom).                                               *)
(* ------------------------------------------------------------------------- *)
let TARSKI_AXIOM_10_EUCLIDEAN = prove
 (`!a b c d t:real^N.
        between d (a,t) /\ between d (b,c) /\ ~(a = d)
        ==> ?x y. between b (a,x) /\ between c (a,y) /\ between t (x,y)`,
  REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT STRIP_TAC THEN
  MP_TAC(ISPECL [`vec 0:real^N`; `d:real^N`; `t:real^N`]
        
BETWEEN_EXISTS_EXTENSION) THEN
  ASM_REWRITE_TAC[
LEFT_IMP_EXISTS_THM; VECTOR_ARITH
   `d + u % (d - vec 0):real^N = (&1 + u) % d`] THEN
  X_GEN_TAC `u:real` THEN STRIP_TAC THEN
  MAP_EVERY EXISTS_TAC [`(&1 + u) % b:real^N`; `(&1 + u) % c:real^N`] THEN
  ASM_REWRITE_TAC[between; dist; GSYM 
VECTOR_SUB_LDISTRIB] THEN
  ASM_REWRITE_TAC[
VECTOR_SUB_LZERO; 
NORM_NEG;
                  VECTOR_ARITH `b - (&1 + u) % b:real^N = --(u % b)`] THEN
  ASM_SIMP_TAC[
NORM_MUL; 
REAL_LE_ADD; 
REAL_POS; 
real_abs] THEN
  REWRITE_TAC[GSYM REAL_ADD_LDISTRIB; 
REAL_EQ_MUL_LCANCEL] THEN
  ASM_REWRITE_TAC[GSYM dist; GSYM between] THEN REAL_ARITH_TAC);;
 
 
(* ------------------------------------------------------------------------- *)
(* Axiom 11 (Continuity).                                                    *)
(* ------------------------------------------------------------------------- *)