(* ========================================================================= *)
(*                (c) Copyright, Bill Richter 2013                           *)
(*          Distributed under the same license as HOL Light                  *)
(*                                                                           *)
(*  Proof of the Bug Puzzle conjecture of the HOL Light tutorial:            *)
(*  Any two triples with the same oriented area can be connected in          *)
(*  5 moves or less (FiveMovesOrLess).  Also a proof that 4 moves is not     *)
(*  enough, with an explicit counterexample.  This result (NOTENOUGH_4)      *)
(*  is due to John Harrison, as is much of the basic vector code, and        *)
(*  the definition of move, which defines a closed subset                    *)
(*    {(A,B,C,A',B',C') | move (A,B,C) (A',B',C')}  subset  R^6 x R^6        *)
(*  and also a result FiveMovesOrLess_STRONG that handles the degenerate     *)
(*  case (the two triples not required to be non-collinear), which has a     *)
(*  very satisfying answer using this "closed" definition of move.           *)
(*                                                                           *)
(*  The mathematical proofs are essentially due to Tom Hales.  The           *)
(*  code is all in miz3, and was an attempt to explore Freek Wiedijk's       *)
(*  vision of mixing the procedural and declarative proof styles.            *)
(* ========================================================================= *)

needs "Multivariate/determinants.ml";;
 
#load "unix.cma";;
loadt "miz3/miz3.ml";;

new_type_abbrev("triple",`:real^2#real^2#real^2`);;

default_prover := ("ya prover",
    fun thl -> REWRITE_TAC thl THEN CONV_TAC (HOL_BY thl));;

horizon := 0;;
timeout := 500;;

let VEC2_TAC =
  SIMP_TAC[CART_EQ; LAMBDA_BETA; FORALL_2; SUM_2; DIMINDEX_2; VECTOR_2;
           vector_add; vec; dot; orthogonal; basis;
           vector_neg; vector_sub; vector_mul; ARITH] THEN
  CONV_TAC REAL_RING;;

let COLLINEAR_3_2Dzero = thm `;
  !y z:real^2. collinear{vec 0,y,z} <=>
                  z$1 * y$2 = y$1 * z$2
  by REWRITE_TAC[COLLINEAR_3_2D] THEN VEC2_TAC;
`;;

let Noncollinear_3ImpliesDistinct = thm `;
  !a b c:real^N. ~collinear {a,b,c}  ==>  ~(a = b) /\ ~(a = c) /\ ~(b = c)
  by COLLINEAR_BETWEEN_CASES, BETWEEN_REFL;
`;;

let collinearSymmetry = thm `;
  let A B C be real^N;
  thus collinear {A,B,C}  ==>  collinear {A,C,B} /\ collinear {B,A,C} /\
  collinear {B,C,A} /\ collinear {C,A,B} /\ collinear {C,B,A}

  proof
    {A,C,B} SUBSET {A,B,C}  /\  {B,A,C} SUBSET {A,B,C}  /\  {B,C,A} SUBSET {A,B,C}  /\
    {C,A,B} SUBSET {A,B,C}  /\  {C,B,A} SUBSET {A,B,C}     by SET_RULE;
  qed     by -, COLLINEAR_SUBSET;
`;;

let Noncollinear_2Span = thm `;
  let u v w be real^2;
  assume ~collinear  {vec 0,v,w}        [H1];
  thus ? s t. s % v + t % w = u

  proof
    !n r. ~(r < n)  /\  r <= MIN n n  ==>  r = n     [easy_arith] by ARITH_RULE;
    ~(w$1 * v$2 = v$1 * w$2)     [H1'] by H1, COLLINEAR_3_2Dzero;
    consider M such that
    M = transp(vector[v;w]):real^2^2     [Mexists];
    det M = v$1 * w$2 - w$1 * v$2     by -, DIMINDEX_2, SUM_2, TRANSP_COMPONENT, VECTOR_2, LAMBDA_BETA, ARITH, CART_EQ, FORALL_2, DET_2;
    ~(det M = &0)     by -, H1', REAL_ARITH;
    consider x s t such that
    M ** x = u /\ s = x$1 /\ t = x$2     by -, easy_arith, DET_EQ_0_RANK, RANK_BOUND, MATRIX_FULL_LINEAR_EQUATIONS;
     v$1 * s + w$1 * t = u$1  /\  v$2 * s + w$2 * t = u$2     by Mexists, -, SIMP_TAC[matrix_vector_mul; DIMINDEX_2; SUM_2; TRANSP_COMPONENT; VECTOR_2; LAMBDA_BETA; ARITH; CART_EQ; FORALL_2] THEN MESON_TAC[];
    s % v + t % w = u     by -, REAL_MUL_SYM, VECTOR_MUL_COMPONENT, VECTOR_ADD_COMPONENT, VEC2_TAC;
  qed     by -;
`;;

let oriented_area = new_definition
  `oriented_area (a:real^2,b:real^2,c:real^2) =
  ((b$1 - a$1) * (c$2 - a$2) - (c$1 - a$1) * (b$2 - a$2)) / &2`;;
let oriented_areaSymmetry = thm `; !A B C A' B' C':real^2. oriented_area (A,B,C) = oriented_area(A',B',C') ==> oriented_area (B,C,A) = oriented_area (B',C',A') /\ oriented_area (C,A,B) = oriented_area (C',A',B') /\ oriented_area (A,C,B) = oriented_area (A',C',B') /\ oriented_area (B,A,C) = oriented_area (B',A',C') /\ oriented_area (C,B,A) = oriented_area (C',B',A') by REWRITE_TAC[oriented_area] THEN VEC2_TAC; `;;
let move = new_definition
  `!A B C A' B' C':real^2. move (A,B,C) (A',B',C') <=>
  (B = B' /\ C = C' /\ collinear {vec 0,C - B,A' - A} \/
  A = A' /\ C = C' /\ collinear {vec 0,C - A,B' - B} \/
  A = A' /\ B = B' /\ collinear {vec 0,B - A,C' - C})`;;
let moveInvariant = thm `; let p p' be triple; assume move p p' [H1]; thus oriented_area p = oriented_area p' proof consider X Y Z X' Y' Z' such that p = X,Y,Z /\ p' = X',Y',Z' [pDef] by PAIR_SURJECTIVE; move (X,Y,Z) (X',Y',Z') by -, H1; oriented_area (X,Y,Z) = oriented_area (X',Y',Z') by -, SIMP_TAC[move; oriented_area; COLLINEAR_3; COLLINEAR_3_2Dzero] THEN VEC2_TAC; qed by -, pDef; `;;
let reachable = new_definition
  `!p p'.
  reachable p p' <=> ?n. ?s.
  s 0 = p /\ s n = p' /\
  (!m. 0 <= m /\ m < n ==> move (s m) (s (SUC m)))`;;
let reachableN = new_definition
  `!p p'. !n.
  reachableN p p' n <=> ?s.
  s 0 = p /\ s n = p' /\
  (!m. 0 <= m /\ m < n ==> move (s m) (s (SUC m)))`;;
let ReachLemma = thm `; !p p'. reachable p p' <=> ?n. reachableN p p' n by reachable, reachableN; `;; let reachableN_CLAUSES = thm `; ! p p'. (reachableN p p' 0 <=> p = p') /\ ! n. reachableN p p' (SUC n) <=> ? q. reachableN p q n /\ move q p' proof let p p' be triple; consider s0 such that s0 = \m:num. p'; reachableN p p' 0 <=> p = p' [0CLAUSE] by -, reachableN, LT, LE_0; ! n. reachableN p p' (SUC n) ==> ? q. reachableN p q n /\ move q p' [Imp1] proof let n be num; assume reachableN p p' (SUC n) [H1]; consider s such that s 0 = p /\ s (SUC n) = p' /\ !m. m < SUC n ==> move (s m) (s (SUC m)) [sDef] by H1, LE_0, reachableN; consider q such that q = s n; qed by sDef, -, LE_0, reachableN, LT; ! n. (? q. reachableN p q n /\ move q p') ==> reachableN p p' (SUC n) proof let n be num; assume ? q. reachableN p q n /\ move q p'; consider q such that reachableN p q n /\ move q p' [qExists] by -; consider s such that s 0 = p /\ s n = q /\ !m. m < n ==> move (s m) (s (SUC m)) [sDef] by -, reachableN, LT, LE_0; consider t such that t = \m. if m < SUC n then s m else p'; t 0 = p /\ t (SUC n) = p' /\ !m. m < SUC n ==> move (t m) (t (SUC m)) [tProp] by qExists, sDef, -, LT_0, LT_REFL, LT, LT_SUC; qed by -, reachableN, LT, LE_0; qed by 0CLAUSE, Imp1, -; `;; let reachableInvariant = thm `; !p p':triple. reachable p p' ==> oriented_area p = oriented_area p' proof !n. !p p'. reachableN p p' n ==> oriented_area p = oriented_area p' by INDUCT_TAC THEN ASM_MESON_TAC[reachableN_CLAUSES; moveInvariant]; qed by -, ReachLemma; `;;
let move2Cond = new_definition
  `move2Cond (A,B,C) (A',B',C')  <=>
  ~collinear {B,A,A'} /\ ~collinear {A',B,B'}   \/
  ~collinear {A,B,B'} /\ ~collinear {B',A,A'}`;;
let reachableN_Two = thm `; !P0 P2:triple. reachableN P0 P2 2 <=> ?P1. move P0 P1 /\ move P1 P2 by ONE, TWO, reachableN_CLAUSES; `;; let reachableN_Three = thm `; !P0 P3:triple. reachableN P0 P3 3 <=> ?P1 P2. move P0 P1 /\ move P1 P2 /\ move P2 P3 proof 3 = SUC 2 by ARITH_RULE; qed by -, reachableN_Two, reachableN_CLAUSES; `;; let reachableN_Four = thm `; !P0 P4:triple. reachableN P0 P4 4 <=> ?P1 P2 P3. move P0 P1 /\ move P1 P2 /\ move P2 P3 /\ move P3 P4 proof 4 = SUC 3 by ARITH_RULE; qed by -, reachableN_Three, reachableN_CLAUSES; `;; let moveSymmetry = thm `; let A B C A' B' C' be real^2; assume move (A,B,C) (A',B',C') [H1]; thus move (B,C,A) (B',C',A') /\ move (C,A,B) (C',A',B') /\ move (A,C,B) (A',C',B') /\ move (B,A,C) (B',A',C') /\ move (C,B,A) (C',B',A') proof !A B C A':real^2. collinear {vec 0, C - B, A' - A} ==> collinear {vec 0, B - C, A' - A} by REWRITE_TAC[COLLINEAR_3_2Dzero] THEN VEC2_TAC; qed by H1, -, move; `;; let reachableNSymmetry = thm `; ! A B C A' B' C' n. reachableN (A,B,C) (A',B',C') n ==> reachableN (B,C,A) (B',C',A') n /\ reachableN (C,A,B) (C',A',B') n /\ reachableN (A,C,B) (A',C',B') n /\ reachableN (B,A,C) (B',A',C') n /\ reachableN (C,B,A) (C',B',A') n proof let A B C be real^2; consider Q such that Q = \n A' B' C'. reachableN (B,C,A) (B',C',A') n /\ reachableN (C,A,B) (C',A',B') n /\ reachableN (A,C,B) (A',C',B') n /\ reachableN (B,A,C) (B',A',C') n /\ reachableN (C,B,A) (C',B',A') n [Qdef]; consider P such that P = \n. ! A' B' C'. reachableN (A,B,C) (A',B',C') n ==> Q n A' B' C' [Pdef]; P 0 [Base] by -, Qdef, reachableN_CLAUSES, PAIR_EQ; !n. P n ==> P (SUC n) proof let n be num; assume P n [Pn]; ! A' B' C'. reachableN (A,B,C) (A',B',C') (SUC n) ==> Q (SUC n) A' B' C' proof let A' B' C' be real^2; assume reachableN (A,B,C) (A',B',C') (SUC n); consider X Y Z such that reachableN (A,B,C) (X,Y,Z) n /\ move (X,Y,Z) (A',B',C') [XYZdef] by -, reachableN_CLAUSES, PAIR_SURJECTIVE; qed by -, Qdef, Pdef, Pn, XYZdef, moveSymmetry, reachableN_CLAUSES; qed by -, Pdef; !n. P n by Base, -, INDUCT_TAC; qed by -, Pdef, Qdef; `;; let ORIENTED_AREA_COLLINEAR_CONG = thm `; let A B C A' B' C' be real^2; assume oriented_area (A,B,C) = oriented_area (A',B',C') [H1]; thus collinear {A,B,C} <=> collinear {A',B',C'} by H1, REWRITE_TAC[COLLINEAR_3_2D; oriented_area] THEN CONV_TAC REAL_RING; `;; let Basic2move_THM = thm `; let A B C A' be real^2; assume ~collinear {A,B,C} [H1]; assume ~collinear {B,A,A'} [H2]; thus ? X. move (A,B,C) (A,B,X) /\ move (A,B,X) (A',B,X) proof !r. r % (A - B) = (--r) % (B - A) /\ r % (A - B) = r % (A - B) + &0 % (C - B) [add0vector_mul] by VEC2_TAC; ~ ? r. A' - A = r % (A - B) [H2'] by H2, COLLINEAR_3, COLLINEAR_LEMMA, -; consider r t such that A' - A = r % (A - B) + t % (C - B) [rExists] by H1, COLLINEAR_3, Noncollinear_2Span; ~(t = &0) [tNonzero] by -, add0vector_mul, H2'; consider s X such that s = r / t /\ X = C + s % (A - B) [Xexists] by rExists; A' - A = (t * s) % (A - B) + t % (C - B) by rExists, -, tNonzero, REAL_DIV_LMUL; A' - A = t % (X - B) [tProp] by -, Xexists, VEC2_TAC; X - C = (-- s) % (B - A) by -, Xexists, VEC2_TAC; collinear {vec 0,B - A,X - C} /\ collinear {vec 0,X - B,A' - A} by -, tProp, COLLINEAR_LEMMA; qed by -, move; `;; let FourStepMoveAB = thm `; let A B C A' B' C' be real^2; assume ~collinear {A,B,C} [H1]; assume ~collinear {B,A,A'} /\ ~collinear {A',B,B'} [H2]; thus ? X Y. move (A,B,C) (A,B,X) /\ move (A,B,X) (A',B,X) /\ move (A',B,X) (A',B,Y) /\ move (A',B,Y) (A',B',Y) proof consider X such that move (A,B,C) (A,B,X) /\ move (A,B,X) (A',B,X) [ABX] by H1, H2, -, Basic2move_THM; ~collinear {A,B,X} /\ ~collinear {A',B,X} by H1, -, moveInvariant, ORIENTED_AREA_COLLINEAR_CONG; ~collinear {B,A',X} by -, collinearSymmetry; consider Y such that move (B,A',X) (B,A',Y) /\ move (B,A',Y) (B',A',Y) by -, H2, Basic2move_THM; move (A',B,X) (A',B,Y) /\ move (A',B,Y) (A',B',Y) by -, moveSymmetry; qed by -, ABX; `;; let FourStepMoveABBAreach = thm `; let A B C A' B' C' be real^2; assume ~collinear {A,B,C} [H1]; assume move2Cond (A,B,C) (A',B',C') [H2]; thus ? Y. reachableN (A,B,C) (A',B',Y) 4 proof cases by H2, move2Cond; suppose ~collinear {B,A,A'} /\ ~collinear {A',B,B'}; qed by H1, -, FourStepMoveAB, reachableN_Four; suppose ~collinear {A,B,B'} /\ ~collinear {B',A,A'} [Case2]; ~collinear {B,A,C} by H1, collinearSymmetry; consider X Y such that move (B,A,C) (B,A,X) /\ move (B,A,X) (B',A,X) /\ move (B',A,X) (B',A,Y) /\ move (B',A,Y) (B',A',Y) by -, Case2, FourStepMoveAB; qed by -, moveSymmetry, reachableN_Four; end; `;; let NotMove2Impliescollinear = thm `; let A B C A' B' C' be real^2; assume ~collinear {A,B,C} /\ ~collinear {A',B',C'} [H1]; assume ~(A = A') /\ ~(B = B') [H2]; assume ~move2Cond (A,B,C) (A',B',C') [H3]; thus collinear {A,B,A',B'} proof ~(A = B) /\ ~(A' = B') [Distinct] by H1, Noncollinear_3ImpliesDistinct; {A,B,A',B'} SUBSET {A,A',B,B'} /\ {A,B,A',B'} SUBSET {B,B',A',A} /\ {A,B,A',B'} SUBSET {A',B',B,A} [set4symmetry] by SET_RULE; cases by H3, move2Cond; suppose collinear {B,A,A'} /\ collinear {A,B,B'}; collinear {A,B,A'} /\ collinear {A,B,B'} by -, collinearSymmetry; qed by Distinct, -, COLLINEAR_4_3; suppose collinear {B,A,A'} /\ collinear {B',A,A'}; collinear {A,A',B} /\ collinear {A,A',B'} by -, collinearSymmetry; collinear {A,A',B,B'} by H2, -, COLLINEAR_4_3; qed by -, set4symmetry, COLLINEAR_SUBSET; suppose collinear {A',B,B'} /\ collinear {A,B,B'}; collinear {B,B',A'} /\ collinear {B,B',A} by -, collinearSymmetry; collinear {B,B',A',A} by H2, -, COLLINEAR_4_3; qed by -, set4symmetry, COLLINEAR_SUBSET; suppose collinear {A',B,B'} /\ collinear {B',A,A'}; collinear {A',B',B} /\ collinear {A',B',A} by -, collinearSymmetry; collinear {A',B',B,A} by Distinct, -, COLLINEAR_4_3; qed by -, set4symmetry, COLLINEAR_SUBSET; end; `;; let DistinctImplies2moveable = thm `; let A B C A' B' C' be real^2; assume ~collinear {A,B,C} /\ ~collinear {A',B',C'} [H1]; assume ~(A = A') /\ ~(B = B') /\ ~(C = C') [H2]; thus move2Cond (A,B,C) (A',B',C') \/ move2Cond (B,C,A) (B',C',A') proof {A, B, B'} SUBSET {A, B, A', B'} /\ {B,B',C} SUBSET {B,C,B',C'} [3subset4] by SET_RULE; ~collinear {B,C,A} /\ ~collinear {B',C',A'} [H1'] by H1, collinearSymmetry; assume ~(move2Cond (A,B,C) (A',B',C') \/ move2Cond (B,C,A) (B',C',A')); ~move2Cond (A,B,C) (A',B',C') /\ ~move2Cond (B,C,A) (B',C',A') by -; collinear {A, B, A', B'} /\ collinear {B,C,B',C'} by H1, H1', -, H2, NotMove2Impliescollinear; collinear {A, B, B'} /\ collinear {B,B',C} by -, 3subset4, COLLINEAR_SUBSET; collinear {A, B, C} by -, H2, COLLINEAR_3_TRANS; qed by -, H1; `;; let SameCdiffAB = thm `; let A B C A' B' C' be real^2; assume ~collinear {A,B,C} /\ ~collinear {A',B',C'} [H1]; assume C = C' /\ ~(A = A') /\ ~(B = B') [H2]; thus ? Y. reachableN (A,B,C) (Y,B',C') 2 \/ reachableN (A,B,C) (A',B',Y) 4 proof {B,B',A} SUBSET {A,B,A',B'} /\ {A,B,C} SUBSET {B,B',A,C} [easy_set] by SET_RULE; cases; suppose ~collinear {C,B,B'}; consider X such that move (B,C,A) (B,C,X) /\ move (B,C,X) (B',C',X) by H1, collinearSymmetry, -, H2, Basic2move_THM; qed by -, reachableN_Two, reachableNSymmetry; suppose move2Cond (A,B,C) (A',B',C'); qed by H1, -, FourStepMoveABBAreach; suppose collinear {C,B,B'} /\ ~move2Cond (A,B,C) (A',B',C'); collinear {B,B',A} /\ collinear {B,B',C} by H1, H2, -, NotMove2Impliescollinear, easy_set, COLLINEAR_SUBSET, collinearSymmetry; qed by -, H2, COLLINEAR_4_3, easy_set, COLLINEAR_SUBSET, H1; end; `;; let FourMovesToCorrectTwo = thm `; let A B C A' B' C' be real^2; assume ~collinear {A,B,C} /\ ~collinear {A',B',C'} [H1]; thus ? n. n < 5 /\ ? Y. reachableN (A,B,C) (A',B',Y) n \/ reachableN (A,B,C) (A',Y,C') n \/ reachableN (A,B,C) (Y,B',C') n proof ~collinear {B,C,A} /\ ~collinear {B',C',A'} /\ ~collinear {C,A,B} /\ ~collinear {C',A',B'} [H1'] by H1, collinearSymmetry; 0 < 5 /\ 2 < 5 /\ 3 < 5 /\ 4 < 5 [easy_arith] by ARITH_RULE; cases; suppose A = A' /\ B = B' /\ C = C' \/ A = A' /\ B = B' /\ ~(C = C') \/ A = A' /\ ~(B = B') /\ C = C' \/ ~(A = A') /\ B = B' /\ C = C'; reachableN (A,B,C) (A',B',C') 0 \/ reachableN (A,B,C) (A',B',C) 0 \/ reachableN (A,B,C) (A',B,C') 0 \/ reachableN (A,B,C) (A,B',C') 0 by -, reachableN_CLAUSES; qed by -, easy_arith; suppose A = A' /\ ~(B = B') /\ ~(C = C') \/ ~(A = A') /\ B = B' /\ ~(C = C') \/ ~(A = A') /\ ~(B = B') /\ C = C'; qed by H1, H1', -, SameCdiffAB, reachableNSymmetry, easy_arith; suppose ~(A = A') /\ ~(B = B') /\ ~(C = C'); move2Cond (A,B,C) (A',B',C') \/ move2Cond (B,C,A) (B',C',A') by H1, -, DistinctImplies2moveable; qed by H1, H1', -, FourStepMoveABBAreach, reachableNSymmetry, reachableN_Four, easy_arith; end; `;; let CorrectFinalPoint = thm `; let A B C A' C' be real^2; assume oriented_area (A,B,C) = oriented_area (A,B,C') [H1]; thus move (A,B,C) (A,B,C') proof ((B$1 - A$1) * (C$2 - A$2) - (C$1 - A$1) * (B$2 - A$2)) / &2 = ((B$1 - A$1) * (C'$2 - A$2) - (C'$1 - A$1) * (B$2 - A$2)) / &2 by H1, oriented_area; (C$1 - C'$1) * (B$2 - A$2) = (B$1 - A$1) * (C$2 - C'$2) by -, REAL_ARITH; (C' - C)$1 * (B - A)$2 = (B - A)$1 * (C' - C)$2 by -, VEC2_TAC; collinear {vec 0, B - A, C' - C} by -, COLLINEAR_3_2Dzero; qed by -, move; `;; let FiveMovesOrLess = thm `; let A B C A' B' C' be real^2; assume ~collinear {A,B,C} [H1]; assume oriented_area (A,B,C) = oriented_area (A',B',C') [H2]; thus ? n. n <= 5 /\ reachableN (A,B,C) (A',B',C') n proof ~collinear {A',B',C'} [H1'] by H1, H2, ORIENTED_AREA_COLLINEAR_CONG; ~(A = B) /\ ~(A = C) /\ ~(B = C) /\ ~(A' = B') /\ ~(A' = C') /\ ~(B' = C') [Distinct] by H1, -, Noncollinear_3ImpliesDistinct; consider n Y such that n < 5 /\ (reachableN (A,B,C) (A',B',Y) n \/ reachableN (A,B,C) (A',Y,C') n \/ reachableN (A,B,C) (Y,B',C') n) [2Correct] by H1, H1', FourMovesToCorrectTwo; cases by 2Correct; suppose reachableN (A,B,C) (A',B',Y) n [Case]; oriented_area (A',B',Y) = oriented_area (A',B',C') by H2, -, ReachLemma, reachableInvariant; move (A',B',Y) (A',B',C') by -, Distinct, CorrectFinalPoint; qed by Case, -, reachableN_CLAUSES, 2Correct, LE_SUC_LT; suppose reachableN (A,B,C) (A',Y,C') n [Case]; oriented_area (A',C',Y) = oriented_area (A',C',B') by H2, -, ReachLemma, reachableInvariant, oriented_areaSymmetry; move (A',Y,C') (A',B',C') by -, Distinct, CorrectFinalPoint, moveSymmetry; qed by Case, -, reachableN_CLAUSES, 2Correct, LE_SUC_LT; suppose reachableN (A,B,C) (Y,B',C') n [Case]; oriented_area (B',C',Y) = oriented_area (B',C',A') by H2, -, ReachLemma, reachableInvariant, oriented_areaSymmetry; move (Y,B',C') (A',B',C') by -, Distinct, CorrectFinalPoint, moveSymmetry; qed by Case, -, reachableN_CLAUSES, 2Correct, LE_SUC_LT; end; `;; let NOTENOUGH_4 = thm `; ?p0 p4. oriented_area p0 = oriented_area p4 /\ ~reachableN p0 p4 4 proof consider p0 p4 such that p0 = vector [&0;&0]:real^2,vector [&0;&1]:real^2,vector [&1;&0]:real^2 /\ p4 = vector [&1;&1]:real^2,vector [&1;&2]:real^2,vector [&2;&1]:real^2 [p04Def]; oriented_area p0 = oriented_area p4 [equal_areas] by -, ASM_REWRITE_TAC[oriented_area] THEN VEC2_TAC; ~reachableN p0 p4 4 by p04Def, ASM_REWRITE_TAC[reachableN_Four; NOT_EXISTS_THM; FORALL_PAIR_THM; move; COLLINEAR_3_2Dzero; FORALL_VECTOR_2] THEN VEC2_TAC; qed by equal_areas, -; `;; let reachableN_Five = thm `; !P0 P5:triple. reachableN P0 P5 5 <=> ?P1 P2 P3 P4. move P0 P1 /\ move P1 P2 /\ move P2 P3 /\ move P3 P4 /\ move P4 P5 proof 5 = SUC 4 by ARITH_RULE; qed by -, reachableN_CLAUSES, reachableN_Four; `;; let EasyCollinearMoves = thm `; (!A A' B:real^2. move (A:real^2,B,B) (A',B,B)) /\ !A B B' C:real^2. collinear {A:real^2,B,C} /\ collinear {A,B',C} ==> move (A,B,C) (A,B',C) by REWRITE_TAC[move; COLLINEAR_3_2D] THEN VEC2_TAC; `;; let FiveMovesOrLess_STRONG = thm `; let A B C A' B' C' be real^2; assume oriented_area (A,B,C) = oriented_area (A',B',C') [H1]; thus ?n. n <= 5 /\ reachableN (A,B,C) (A',B',C') n proof {A,C,C} = {A,C} /\ {B',C,C} = {B',C} /\ {B',B',C} = {B',C} /\ {B',B',C'} = {B',C'} [easy_sets] by SET_RULE; cases; suppose ~collinear {A,B,C}; qed by -, H1, FiveMovesOrLess; suppose collinear {A,B,C} [ABCcol]; collinear {A',B',C'} [A'B'C'col] by -, H1, ORIENTED_AREA_COLLINEAR_CONG; consider P1 P2 P3 P4 such that P1 = A,C,C /\ P2 = B',C,C /\ P3 = B',B',C /\ P4 = B',B',C'; move (A,B,C) P1 /\ move P1 P2 /\ move P2 P3 /\ move P3 P4 /\ move P4 (A',B',C') by -, ABCcol, A'B'C'col, easy_sets, COLLINEAR_2, collinearSymmetry, moveSymmetry, EasyCollinearMoves; qed by -, reachableN_Five, LE_REFL; end; `;;