(* ========================================================================= *) (* Examples of using the Grobner basis procedure. *) (* ========================================================================= *) time COMPLEX_ARITH `!a b c. (a * x pow 2 + b * x + c = Cx(&0)) /\ (a * y pow 2 + b * y + c = Cx(&0)) /\ ~(x = y) ==> (a * (x + y) + b = Cx(&0))`;; time COMPLEX_ARITH `!a b c. (a * x pow 2 + b * x + c = Cx(&0)) /\ (Cx(&2) * a * y pow 2 + Cx(&2) * b * y + Cx(&2) * c = Cx(&0)) /\ ~(x = y) ==> (a * (x + y) + b = Cx(&0))`;; (* ------------------------------------------------------------------------- *) (* Another example. *) (* ------------------------------------------------------------------------- *) time COMPLEX_ARITH `~((y_1 = Cx(&2) * y_3) /\ (y_2 = Cx(&2) * y_4) /\ (y_1 * y_3 = y_2 * y_4) /\ ((y_1 pow 2 - y_2 pow 2) * z = Cx(&1)))`;; time COMPLEX_ARITH `!y_1 y_2 y_3 y_4. (y_1 = Cx(&2) * y_3) /\ (y_2 = Cx(&2) * y_4) /\ (y_1 * y_3 = y_2 * y_4) ==> (y_1 pow 2 = y_2 pow 2)`;; (* ------------------------------------------------------------------------- *) (* Angle at centre vs. angle at circumference. *) (* Formulation from "Real quantifier elimination in practice" paper. *) (* ------------------------------------------------------------------------- *) time COMPLEX_ARITH `~((c pow 2 = a pow 2 + b pow 2) /\ (c pow 2 = x0 pow 2 + (y0 - b) pow 2) /\ (y0 * t1 = a + x0) /\ (y0 * t2 = a - x0) /\ ((Cx(&1) - t1 * t2) * t = t1 + t2) /\ (u * (b * t - a) = Cx(&1)) /\ (v1 * a + v2 * x0 + v3 * y0 = Cx(&1)))`;; time COMPLEX_ARITH `(c pow 2 = a pow 2 + b pow 2) /\ (c pow 2 = x0 pow 2 + (y0 - b) pow 2) /\ (y0 * t1 = a + x0) /\ (y0 * t2 = a - x0) /\ ((Cx(&1) - t1 * t2) * t = t1 + t2) /\ (~(a = Cx(&0)) \/ ~(x0 = Cx(&0)) \/ ~(y0 = Cx(&0))) ==> (b * t = a)`;; time COMPLEX_ARITH `(c pow 2 = a pow 2 + b pow 2) /\ (c pow 2 = x0 pow 2 + (y0 - b) pow 2) /\ (y0 * t1 = a + x0) /\ (y0 * t2 = a - x0) /\ ((Cx(&1) - t1 * t2) * t = t1 + t2) /\ (~(a = Cx(&0)) /\ ~(x0 = Cx(&0)) /\ ~(y0 = Cx(&0))) ==> (b * t = a)`;; (* ------------------------------------------------------------------------- *) (* Another example (note we rule out points 1, 2 or 3 coinciding). *) (* ------------------------------------------------------------------------- *) time COMPLEX_ARITH `((x1 - x0) pow 2 + (y1 - y0) pow 2 = (x2 - x0) pow 2 + (y2 - y0) pow 2) /\ ((x2 - x0) pow 2 + (y2 - y0) pow 2 = (x3 - x0) pow 2 + (y3 - y0) pow 2) /\ ((x1 - x0') pow 2 + (y1 - y0') pow 2 = (x2 - x0') pow 2 + (y2 - y0') pow 2) /\ ((x2 - x0') pow 2 + (y2 - y0') pow 2 = (x3 - x0') pow 2 + (y3 - y0') pow 2) /\ (a12 * (x1 - x2) + b12 * (y1 - y2) = Cx(&1)) /\ (a13 * (x1 - x3) + b13 * (y1 - y3) = Cx(&1)) /\ (a23 * (x2 - x3) + b23 * (y2 - y3) = Cx(&1)) /\ ~((x1 - x0) pow 2 + (y1 - y0) pow 2 = Cx(&0)) ==> (x0' = x0) /\ (y0' = y0)`;; time COMPLEX_ARITH `~(((x1 - x0) pow 2 + (y1 - y0) pow 2 = (x2 - x0) pow 2 + (y2 - y0) pow 2) /\ ((x2 - x0) pow 2 + (y2 - y0) pow 2 = (x3 - x0) pow 2 + (y3 - y0) pow 2) /\ ((x1 - x0') pow 2 + (y1 - y0') pow 2 = (x2 - x0') pow 2 + (y2 - y0') pow 2) /\ ((x2 - x0') pow 2 + (y2 - y0') pow 2 = (x3 - x0') pow 2 + (y3 - y0') pow 2) /\ (a12 * (x1 - x2) + b12 * (y1 - y2) = Cx(&1)) /\ (a13 * (x1 - x3) + b13 * (y1 - y3) = Cx(&1)) /\ (a23 * (x2 - x3) + b23 * (y2 - y3) = Cx(&1)) /\ (z * (x0' - x0) = Cx(&1)) /\ (z' * (y0' - y0) = Cx(&1)) /\ (z'' * ((x1 - x0) pow 2 + (y1 - y0) pow 2) = Cx(&1)) /\ (z''' * ((x1 - x09) pow 2 + (y1 - y09) pow 2) = Cx(&1)))`;; (* ------------------------------------------------------------------------- *) (* These are pure algebraic simplification. *) (* ------------------------------------------------------------------------- *) let LAGRANGE_4 = time COMPLEX_ARITH `(((x1 pow 2) + (x2 pow 2) + (x3 pow 2) + (x4 pow 2)) * ((y1 pow 2) + (y2 pow 2) + (y3 pow 2) + (y4 pow 2))) = ((((((x1*y1) - (x2*y2)) - (x3*y3)) - (x4*y4)) pow 2) + (((((x1*y2) + (x2*y1)) + (x3*y4)) - (x4*y3)) pow 2) + (((((x1*y3) - (x2*y4)) + (x3*y1)) + (x4*y2)) pow 2) + (((((x1*y4) + (x2*y3)) - (x3*y2)) + (x4*y1)) pow 2))`;; let LAGRANGE_8 = time COMPLEX_ARITH `((p1 pow 2 + q1 pow 2 + r1 pow 2 + s1 pow 2 + t1 pow 2 + u1 pow 2 + v1 pow 2 + w1 pow 2) * (p2 pow 2 + q2 pow 2 + r2 pow 2 + s2 pow 2 + t2 pow 2 + u2 pow 2 + v2 pow 2 + w2 pow 2)) = ((p1 * p2 - q1 * q2 - r1 * r2 - s1 * s2 - t1 * t2 - u1 * u2 - v1 * v2 - w1* w2) pow 2 + (p1 * q2 + q1 * p2 + r1 * s2 - s1 * r2 + t1 * u2 - u1 * t2 - v1 * w2 + w1* v2) pow 2 + (p1 * r2 - q1 * s2 + r1 * p2 + s1 * q2 + t1 * v2 + u1 * w2 - v1 * t2 - w1* u2) pow 2 + (p1 * s2 + q1 * r2 - r1 * q2 + s1 * p2 + t1 * w2 - u1 * v2 + v1 * u2 - w1* t2) pow 2 + (p1 * t2 - q1 * u2 - r1 * v2 - s1 * w2 + t1 * p2 + u1 * q2 + v1 * r2 + w1* s2) pow 2 + (p1 * u2 + q1 * t2 - r1 * w2 + s1 * v2 - t1 * q2 + u1 * p2 - v1 * s2 + w1* r2) pow 2 + (p1 * v2 + q1 * w2 + r1 * t2 - s1 * u2 - t1 * r2 + u1 * s2 + v1 * p2 - w1* q2) pow 2 + (p1 * w2 - q1 * v2 + r1 * u2 + s1 * t2 - t1 * s2 - u1 * r2 + v1 * q2 + w1* p2) pow 2)`;; let LIOUVILLE = time COMPLEX_ARITH `((x1 pow 2 + x2 pow 2 + x3 pow 2 + x4 pow 2) pow 2) = (Cx(&1 / &6) * ((x1 + x2) pow 4 + (x1 + x3) pow 4 + (x1 + x4) pow 4 + (x2 + x3) pow 4 + (x2 + x4) pow 4 + (x3 + x4) pow 4) + Cx(&1 / &6) * ((x1 - x2) pow 4 + (x1 - x3) pow 4 + (x1 - x4) pow 4 + (x2 - x3) pow 4 + (x2 - x4) pow 4 + (x3 - x4) pow 4))`;; let FLECK = time COMPLEX_ARITH `((x1 pow 2 + x2 pow 2 + x3 pow 2 + x4 pow 2) pow 3) = (Cx(&1 / &60) * ((x1 + x2 + x3) pow 6 + (x1 + x2 - x3) pow 6 + (x1 - x2 + x3) pow 6 + (x1 - x2 - x3) pow 6 + (x1 + x2 + x4) pow 6 + (x1 + x2 - x4) pow 6 + (x1 - x2 + x4) pow 6 + (x1 - x2 - x4) pow 6 + (x1 + x3 + x4) pow 6 + (x1 + x3 - x4) pow 6 + (x1 - x3 + x4) pow 6 + (x1 - x3 - x4) pow 6 + (x2 + x3 + x4) pow 6 + (x2 + x3 - x4) pow 6 + (x2 - x3 + x4) pow 6 + (x2 - x3 - x4) pow 6) + Cx(&1 / &30) * ((x1 + x2) pow 6 + (x1 - x2) pow 6 + (x1 + x3) pow 6 + (x1 - x3) pow 6 + (x1 + x4) pow 6 + (x1 - x4) pow 6 + (x2 + x3) pow 6 + (x2 - x3) pow 6 + (x2 + x4) pow 6 + (x2 - x4) pow 6 + (x3 + x4) pow 6 + (x3 - x4) pow 6) + Cx(&3 / &5) * (x1 pow 6 + x2 pow 6 + x3 pow 6 + x4 pow 6))`;; let HURWITZ = time COMPLEX_ARITH `!x1 x2 x3 x4. (x1 pow 2 + x2 pow 2 + x3 pow 2 + x4 pow 2) pow 4 = Cx(&1 / &840) * ((x1 + x2 + x3 + x4) pow 8 + (x1 + x2 + x3 - x4) pow 8 + (x1 + x2 - x3 + x4) pow 8 + (x1 + x2 - x3 - x4) pow 8 + (x1 - x2 + x3 + x4) pow 8 + (x1 - x2 + x3 - x4) pow 8 + (x1 - x2 - x3 + x4) pow 8 + (x1 - x2 - x3 - x4) pow 8) + Cx(&1 / &5040) * ((Cx(&2) * x1 + x2 + x3) pow 8 + (Cx(&2) * x1 + x2 - x3) pow 8 + (Cx(&2) * x1 - x2 + x3) pow 8 + (Cx(&2) * x1 - x2 - x3) pow 8 + (Cx(&2) * x1 + x2 + x4) pow 8 + (Cx(&2) * x1 + x2 - x4) pow 8 + (Cx(&2) * x1 - x2 + x4) pow 8 + (Cx(&2) * x1 - x2 - x4) pow 8 + (Cx(&2) * x1 + x3 + x4) pow 8 + (Cx(&2) * x1 + x3 - x4) pow 8 + (Cx(&2) * x1 - x3 + x4) pow 8 + (Cx(&2) * x1 - x3 - x4) pow 8 + (Cx(&2) * x2 + x3 + x4) pow 8 + (Cx(&2) * x2 + x3 - x4) pow 8 + (Cx(&2) * x2 - x3 + x4) pow 8 + (Cx(&2) * x2 - x3 - x4) pow 8 + (x1 + Cx(&2) * x2 + x3) pow 8 + (x1 + Cx(&2) * x2 - x3) pow 8 + (x1 - Cx(&2) * x2 + x3) pow 8 + (x1 - Cx(&2) * x2 - x3) pow 8 + (x1 + Cx(&2) * x2 + x4) pow 8 + (x1 + Cx(&2) * x2 - x4) pow 8 + (x1 - Cx(&2) * x2 + x4) pow 8 + (x1 - Cx(&2) * x2 - x4) pow 8 + (x1 + Cx(&2) * x3 + x4) pow 8 + (x1 + Cx(&2) * x3 - x4) pow 8 + (x1 - Cx(&2) * x3 + x4) pow 8 + (x1 - Cx(&2) * x3 - x4) pow 8 + (x2 + Cx(&2) * x3 + x4) pow 8 + (x2 + Cx(&2) * x3 - x4) pow 8 + (x2 - Cx(&2) * x3 + x4) pow 8 + (x2 - Cx(&2) * x3 - x4) pow 8 + (x1 + x2 + Cx(&2) * x3) pow 8 + (x1 + x2 - Cx(&2) * x3) pow 8 + (x1 - x2 + Cx(&2) * x3) pow 8 + (x1 - x2 - Cx(&2) * x3) pow 8 + (x1 + x2 + Cx(&2) * x4) pow 8 + (x1 + x2 - Cx(&2) * x4) pow 8 + (x1 - x2 + Cx(&2) * x4) pow 8 + (x1 - x2 - Cx(&2) * x4) pow 8 + (x1 + x3 + Cx(&2) * x4) pow 8 + (x1 + x3 - Cx(&2) * x4) pow 8 + (x1 - x3 + Cx(&2) * x4) pow 8 + (x1 - x3 - Cx(&2) * x4) pow 8 + (x2 + x3 + Cx(&2) * x4) pow 8 + (x2 + x3 - Cx(&2) * x4) pow 8 + (x2 - x3 + Cx(&2) * x4) pow 8 + (x2 - x3 - Cx(&2) * x4) pow 8) + Cx(&1 / &84) * ((x1 + x2) pow 8 + (x1 - x2) pow 8 + (x1 + x3) pow 8 + (x1 - x3) pow 8 + (x1 + x4) pow 8 + (x1 - x4) pow 8 + (x2 + x3) pow 8 + (x2 - x3) pow 8 + (x2 + x4) pow 8 + (x2 - x4) pow 8 + (x3 + x4) pow 8 + (x3 - x4) pow 8) + Cx(&1 / &840) * ((Cx(&2) * x1) pow 8 + (Cx(&2) * x2) pow 8 + (Cx(&2) * x3) pow 8 + (Cx(&2) * x4) pow 8)`;; let SCHUR = time COMPLEX_ARITH `Cx(&22680) * (x1 pow 2 + x2 pow 2 + x3 pow 2 + x4 pow 2) pow 5 = Cx(&9) * ((Cx(&2) * x1) pow 10 + (Cx(&2) * x2) pow 10 + (Cx(&2) * x3) pow 10 + (Cx(&2) * x4) pow 10) + Cx(&180) * ((x1 + x2) pow 10 + (x1 - x2) pow 10 + (x1 + x3) pow 10 + (x1 - x3) pow 10 + (x1 + x4) pow 10 + (x1 - x4) pow 10 + (x2 + x3) pow 10 + (x2 - x3) pow 10 + (x2 + x4) pow 10 + (x2 - x4) pow 10 + (x3 + x4) pow 10 + (x3 - x4) pow 10) + ((Cx(&2) * x1 + x2 + x3) pow 10 + (Cx(&2) * x1 + x2 - x3) pow 10 + (Cx(&2) * x1 - x2 + x3) pow 10 + (Cx(&2) * x1 - x2 - x3) pow 10 + (Cx(&2) * x1 + x2 + x4) pow 10 + (Cx(&2) * x1 + x2 - x4) pow 10 + (Cx(&2) * x1 - x2 + x4) pow 10 + (Cx(&2) * x1 - x2 - x4) pow 10 + (Cx(&2) * x1 + x3 + x4) pow 10 + (Cx(&2) * x1 + x3 - x4) pow 10 + (Cx(&2) * x1 - x3 + x4) pow 10 + (Cx(&2) * x1 - x3 - x4) pow 10 + (Cx(&2) * x2 + x3 + x4) pow 10 + (Cx(&2) * x2 + x3 - x4) pow 10 + (Cx(&2) * x2 - x3 + x4) pow 10 + (Cx(&2) * x2 - x3 - x4) pow 10 + (x1 + Cx(&2) * x2 + x3) pow 10 + (x1 + Cx(&2) * x2 - x3) pow 10 + (x1 - Cx(&2) * x2 + x3) pow 10 + (x1 - Cx(&2) * x2 - x3) pow 10 + (x1 + Cx(&2) * x2 + x4) pow 10 + (x1 + Cx(&2) * x2 - x4) pow 10 + (x1 - Cx(&2) * x2 + x4) pow 10 + (x1 - Cx(&2) * x2 - x4) pow 10 + (x1 + Cx(&2) * x3 + x4) pow 10 + (x1 + Cx(&2) * x3 - x4) pow 10 + (x1 - Cx(&2) * x3 + x4) pow 10 + (x1 - Cx(&2) * x3 - x4) pow 10 + (x2 + Cx(&2) * x3 + x4) pow 10 + (x2 + Cx(&2) * x3 - x4) pow 10 + (x2 - Cx(&2) * x3 + x4) pow 10 + (x2 - Cx(&2) * x3 - x4) pow 10 + (x1 + x2 + Cx(&2) * x3) pow 10 + (x1 + x2 - Cx(&2) * x3) pow 10 + (x1 - x2 + Cx(&2) * x3) pow 10 + (x1 - x2 - Cx(&2) * x3) pow 10 + (x1 + x2 + Cx(&2) * x4) pow 10 + (x1 + x2 - Cx(&2) * x4) pow 10 + (x1 - x2 + Cx(&2) * x4) pow 10 + (x1 - x2 - Cx(&2) * x4) pow 10 + (x1 + x3 + Cx(&2) * x4) pow 10 + (x1 + x3 - Cx(&2) * x4) pow 10 + (x1 - x3 + Cx(&2) * x4) pow 10 + (x1 - x3 - Cx(&2) * x4) pow 10 + (x2 + x3 + Cx(&2) * x4) pow 10 + (x2 + x3 - Cx(&2) * x4) pow 10 + (x2 - x3 + Cx(&2) * x4) pow 10 + (x2 - x3 - Cx(&2) * x4) pow 10) + Cx(&9) * ((x1 + x2 + x3 + x4) pow 10 + (x1 + x2 + x3 - x4) pow 10 + (x1 + x2 - x3 + x4) pow 10 + (x1 + x2 - x3 - x4) pow 10 + (x1 - x2 + x3 + x4) pow 10 + (x1 - x2 + x3 - x4) pow 10 + (x1 - x2 - x3 + x4) pow 10 + (x1 - x2 - x3 - x4) pow 10)`;; (* ------------------------------------------------------------------------- *) (* Intersection of diagonals of a parallelogram is their midpoint. *) (* Kapur "...Dixon resultants, Groebner Bases, and Characteristic Sets", 3.1 *) (* ------------------------------------------------------------------------- *) time COMPLEX_ARITH `(x1 = u3) /\ (x1 * (u2 - u1) = x2 * u3) /\ (x4 * (x2 - u1) = x1 * (x3 - u1)) /\ (x3 * u3 = x4 * u2) /\ ~(u1 = Cx(&0)) /\ ~(u3 = Cx(&0)) ==> (x3 pow 2 + x4 pow 2 = (u2 - x3) pow 2 + (u3 - x4) pow 2)`;; (* ------------------------------------------------------------------------- *) (* Chou's formulation of same property. *) (* ------------------------------------------------------------------------- *) time COMPLEX_ARITH `(u1 * x1 - u1 * u3 = Cx(&0)) /\ (u3 * x2 - (u2 - u1) * x1 = Cx(&0)) /\ (x1 * x4 - (x2 - u1) * x3 - u1 * x1 = Cx(&0)) /\ (u3 * x4 - u2 * x3 = Cx(&0)) /\ ~(u1 = Cx(&0)) /\ ~(u3 = Cx(&0)) ==> (Cx(&2) * u2 * x4 + Cx(&2) * u3 * x3 - u3 pow 2 - u2 pow 2 = Cx(&0))`;; (* ------------------------------------------------------------------------- *) (* Perpendicular lines property; from Kapur's earlier paper. *) (* ------------------------------------------------------------------------- *) time COMPLEX_ARITH `(y1 * y3 + x1 * x3 = Cx(&0)) /\ (y3 * (y2 - y3) + (x2 - x3) * x3 = Cx(&0)) /\ ~(x3 = Cx(&0)) /\ ~(y3 = Cx(&0)) ==> (y1 * (x2 - x3) = x1 * (y2 - y3))`;; (* ------------------------------------------------------------------------- *) (* Simson's theorem (Chou, p7). *) (* ------------------------------------------------------------------------- *) time COMPLEX_ARITH `(Cx(&2) * u2 * x2 + Cx(&2) * u3 * x1 - u3 pow 2 - u2 pow 2 = Cx(&0)) /\ (Cx(&2) * u1 * x2 - u1 pow 2 = Cx(&0)) /\ (--(x3 pow 2) + Cx(&2) * x2 * x3 + Cx(&2) * u4 * x1 - u4 pow 2 = Cx(&0)) /\ (u3 * x5 + (--u2 + u1) * x4 - u1 * u3 = Cx(&0)) /\ ((u2 - u1) * x5 + u3 * x4 + (--u2 + u1) * x3 - u3 * u4 = Cx(&0)) /\ (u3 * x7 - u2 * x6 = Cx(&0)) /\ (u2 * x7 + u3 * x6 - u2 * x3 - u3 * u4 = Cx(&0)) /\ ~(Cx(&4) * u1 * u3 = Cx(&0)) /\ ~(Cx(&2) * u1 = Cx(&0)) /\ ~(--(u3 pow 2) - u2 pow 2 + Cx(&2) * u1 * u2 - u1 pow 2 = Cx(&0)) /\ ~(u3 = Cx(&0)) /\ ~(--(u3 pow 2) - u2 pow 2 = Cx(&0)) /\ ~(u2 = Cx(&0)) ==> (x4 * x7 + (--x5 + x3) * x6 - x3 * x4 = Cx(&0))`;; (* ------------------------------------------------------------------------- *) (* Determinants from Coq convex hull paper (some require reals or order). *) (* ------------------------------------------------------------------------- *) let det3 = new_definition `det3(a11,a12,a13, a21,a22,a23, a31,a32,a33) = a11 * (a22 * a33 - a32 * a23) - a12 * (a21 * a33 - a31 * a23) + a13 * (a21 * a32 - a31 * a22)`;; let DET_TRANSPOSE = prove (`det3(a1,b1,c1,a2,b2,c2,a3,b3,c3) = det3(a1,a2,a3,b1,b2,b3,c1,c2,c3)`, REWRITE_TAC[det3] THEN CONV_TAC(time COMPLEX_ARITH));; let sdet3 = new_definition `sdet3(p,q,r) = det3(FST p,SND p,Cx(&1), FST q,SND q,Cx(&1), FST r,SND r,Cx(&1))`;; let SDET3_PERMUTE_1 = prove (`sdet3(p,q,r) = sdet3(q,r,p)`, REWRITE_TAC[sdet3; det3] THEN CONV_TAC(time COMPLEX_ARITH));; let SDET3_PERMUTE_2 = prove (`sdet3(p,q,r) = --(sdet3(p,r,q))`, REWRITE_TAC[sdet3; det3] THEN CONV_TAC(time COMPLEX_ARITH));; let SDET_SUM = prove (`sdet3(p,q,r) - sdet3(t,q,r) - sdet3(p,t,r) - sdet3(p,q,t) = Cx(&0)`, REWRITE_TAC[sdet3; det3] THEN CONV_TAC(time COMPLEX_ARITH));; let SDET_CRAMER = prove (`sdet3(s,t,q) * sdet3(t,p,r) = sdet3(t,q,r) * sdet3(s,t,p) + sdet3(t,p,q) * sdet3(s,t,r)`, REWRITE_TAC[sdet3; det3] THEN CONV_TAC(time COMPLEX_ARITH));; let SDET_NZ = prove (`!p q r. ~(sdet3(p,q,r) = Cx(&0)) ==> ~(p = q) /\ ~(q = r) /\ ~(r = p)`, REWRITE_TAC[FORALL_PAIR_THM; PAIR_EQ; sdet3; det3] THEN CONV_TAC(time COMPLEX_ARITH));; let SDET_LINCOMB = prove (`(FST p * sdet3(i,j,k) = FST i * sdet3(j,k,p) + FST j * sdet3(k,i,p) + FST k * sdet3(i,j,p)) /\ (SND p * sdet3(i,j,k) = SND i * sdet3(j,k,p) + SND j * sdet3(k,i,p) + SND k * sdet3(i,j,p))`, REWRITE_TAC[sdet3; det3] THEN CONV_TAC(time COMPLEX_ARITH));; (***** I'm not sure if this is true; there must be some sufficient degenerate conditions.... let th = prove (`~(~(xp pow 2 + yp pow 2 = Cx(&0)) /\ ~(xq pow 2 + yq pow 2 = Cx(&0)) /\ ~(xr pow 2 + yr pow 2 = Cx(&0)) /\ (det3(xp,yp,Cx(&1), xq,yq,Cx(&1), xr,yr,Cx(&1)) = Cx(&0)) /\ (det3(yp,xp pow 2 + yp pow 2,Cx(&1), yq,xq pow 2 + yq pow 2,Cx(&1), yr,xr pow 2 + yr pow 2,Cx(&1)) = Cx(&0)) /\ (det3(xp,xp pow 2 + yp pow 2,Cx(&1), xq,xq pow 2 + yq pow 2,Cx(&1), xr,xr pow 2 + yr pow 2,Cx(&1)) = Cx(&0)))`, REWRITE_TAC[det3] THEN CONV_TAC(time COMPLEX_ARITH));; ***************) (* ------------------------------------------------------------------------- *) (* Some geometry concepts (just "axiomatic" in this file). *) (* ------------------------------------------------------------------------- *) prioritize_real();; let collinear = new_definition `collinear (a:real#real) b c <=> ((FST a - FST b) * (SND b - SND c) = (SND a - SND b) * (FST b - FST c))`;; let parallel = new_definition `parallel (a,b) (c,d) <=> ((FST a - FST b) * (SND c - SND d) = (SND a - SND b) * (FST c - FST d))`;; let perpendicular = new_definition `perpendicular (a,b) (c,d) <=> ((FST a - FST b) * (FST c - FST d) + (SND a - SND b) * (SND c - SND d) = &0)`;; let oncircle_with_diagonal = new_definition `oncircle_with_diagonal a (b,c) = perpendicular (b,a) (c,a)`;; let length = new_definition `length (a,b) = sqrt((FST a - FST b) pow 2 + (SND a - SND b) pow 2)`;; let lengths_eq = new_definition `lengths_eq (a,b) (c,d) <=> ((FST a - FST b) pow 2 + (SND a - SND b) pow 2 = (FST c - FST d) pow 2 + (SND c - SND d) pow 2)`;; let is_midpoint = new_definition `is_midpoint b (a,c) <=> (&2 * FST b = FST a + FST c) /\ (&2 * SND b = SND a + SND c)`;; (* ------------------------------------------------------------------------- *) (* Chou isn't explicit about this. *) (* ------------------------------------------------------------------------- *) let is_intersection = new_definition `is_intersection p (a,b) (c,d) <=> collinear a p b /\ collinear c p d`;; (* ------------------------------------------------------------------------- *) (* This is used in some degenerate conditions. See Chou, p18. *) (* ------------------------------------------------------------------------- *) let isotropic = new_definition `isotropic (a,b) = perpendicular (a,b) (a,b)`;; (* ------------------------------------------------------------------------- *) (* This increases degree, but sometimes makes complex assertion useful. *) (* ------------------------------------------------------------------------- *) let distinctpairs = new_definition `distinctpairs pprs <=> ~(ITLIST (\(a,b) pr. ((FST a - FST b) pow 2 + (SND a - SND b) pow 2) * pr) pprs (&1) = &0)`;; (* ------------------------------------------------------------------------- *) (* Simple tactic to remove defined concepts and expand coordinates. *) (* ------------------------------------------------------------------------- *) let (EXPAND_COORDS_TAC:tactic) = let complex2_ty = `:real#real` in fun (asl,w) -> (let fvs = filter (fun v -> type_of v = complex2_ty) (frees w) in MAP_EVERY (fun v -> SPEC_TAC(v,v)) fvs THEN GEN_REWRITE_TAC DEPTH_CONV [FORALL_PAIR_THM; EXISTS_PAIR_THM] THEN REPEAT GEN_TAC) (asl,w);; let PAIR_BETA_THM = prove (`(\(x,y). P x y) (a,b) = P a b`, CONV_TAC(LAND_CONV GEN_BETA_CONV) THEN REFL_TAC);; let GEOM_TAC = EXPAND_COORDS_TAC THEN GEN_REWRITE_TAC TOP_DEPTH_CONV [collinear; parallel; perpendicular; oncircle_with_diagonal; length; lengths_eq; is_midpoint; is_intersection; distinctpairs; isotropic; ITLIST; PAIR_BETA_THM; BETA_THM; PAIR_EQ; FST; SND];; (* ------------------------------------------------------------------------- *) (* Centroid (Chou, example 142). *) (* ------------------------------------------------------------------------- *) let CENTROID = time prove (`is_midpoint d (b,c) /\ is_midpoint e (a,c) /\ is_midpoint f (a,b) /\ is_intersection m (b,e) (a,d) ==> collinear c f m`, GEOM_TAC THEN CONV_TAC GROBNER_REAL_ARITH);; (* ------------------------------------------------------------------------- *) (* Gauss's theorem (Chou, example 15). *) (* ------------------------------------------------------------------------- *) let GAUSS = time prove (`collinear x a0 a3 /\ collinear x a1 a2 /\ collinear y a2 a3 /\ collinear y a1 a0 /\ is_midpoint m1 (a1,a3) /\ is_midpoint m2 (a0,a2) /\ is_midpoint m3 (x,y) ==> collinear m1 m2 m3`, GEOM_TAC THEN CONV_TAC GROBNER_REAL_ARITH);; (* ------------------------------------------------------------------------- *) (* Simson's theorem (Chou, example 288). *) (* ------------------------------------------------------------------------- *) (**** These are all hideously slow. At least the first one works. I haven't had the patience to try the rest. let SIMSON = time prove (`lengths_eq (O,a) (O,b) /\ lengths_eq (O,a) (O,c) /\ lengths_eq (d,O) (O,a) /\ perpendicular (e,d) (b,c) /\ collinear e b c /\ perpendicular (f,d) (a,c) /\ collinear f a c /\ perpendicular (g,d) (a,b) /\ collinear g a b /\ ~(collinear a c b) /\ ~(lengths_eq (a,b) (a,a)) /\ ~(lengths_eq (a,c) (a,a)) /\ ~(lengths_eq (b,c) (a,a)) ==> collinear e f g`, GEOM_TAC THEN CONV_TAC GROBNER_REAL_ARITH);; let SIMSON = time prove (`lengths_eq (O,a) (O,b) /\ lengths_eq (O,a) (O,c) /\ lengths_eq (d,O) (O,a) /\ perpendicular (e,d) (b,c) /\ collinear e b c /\ perpendicular (f,d) (a,c) /\ collinear f a c /\ perpendicular (g,d) (a,b) /\ collinear g a b /\ ~(a = b) /\ ~(a = c) /\ ~(a = d) /\ ~(b = c) /\ ~(b = d) /\ ~(c = d) ==> collinear e f g`, GEOM_TAC THEN CONV_TAC GROBNER_REAL_ARITH);; let SIMSON = time prove (`lengths_eq (O,a) (O,b) /\ lengths_eq (O,a) (O,c) /\ lengths_eq (d,O) (O,a) /\ perpendicular (e,d) (b,c) /\ collinear e b c /\ perpendicular (f,d) (a,c) /\ collinear f a c /\ perpendicular (g,d) (a,b) /\ collinear g a b /\ ~(collinear a c b) /\ ~(isotropic (a,b)) /\ ~(isotropic (a,c)) /\ ~(isotropic (b,c)) /\ ~(isotropic (a,d)) /\ ~(isotropic (b,d)) /\ ~(isotropic (c,d)) ==> collinear e f g`, GEOM_TAC THEN CONV_TAC GROBNER_REAL_ARITH);; ****************)