(* ========================================================================= *)
(* (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_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 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;
`;;