// // A \ // \ B // \ / // O \/ X // /\ // / \ // C / D // // Two tangents: // Intersection(X, AD, BC), Tangent(Circle(O), BC), Tangent(Circle(O), AD) -> 2 * Angle(AXC) = MajorArc(AC) - MinorArc(AC) // public static List <EdgeAggregator> InstantiateTwoTangentsTheorem(Tangent tangent1, Tangent tangent2, Intersection inter, GroundedClause original1, GroundedClause original2) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); CircleSegmentIntersection tan1 = tangent1.intersection as CircleSegmentIntersection; CircleSegmentIntersection tan2 = tangent2.intersection as CircleSegmentIntersection; if (tan1.StructurallyEquals(tan2)) { return(newGrounded); } // Do the tangents apply to the same circle? if (!tan1.theCircle.StructurallyEquals(tan2.theCircle)) { return(newGrounded); } Circle circle = tan1.theCircle; // Do these tangents work with this intersection? if (!inter.HasSegment(tan1.segment) || !inter.HasSegment(tan2.segment)) { return(newGrounded); } // Overkill? Do the tangents intersect at the same point as the intersection's intersect point? if (!tan1.segment.FindIntersection(tan2.segment).StructurallyEquals(inter.intersect)) { return(newGrounded); } // // Get the arcs // Arc minorArc = new MinorArc(circle, tan1.intersect, tan2.intersect); Arc majorArc = new MajorArc(circle, tan1.intersect, tan2.intersect); Angle theAngle = new Angle(tan1.intersect, inter.intersect, tan2.intersect); // // Construct the new relationship // NumericValue two = new NumericValue(2); GeometricAngleArcEquation gaaeq = new GeometricAngleArcEquation(new Multiplication(two, theAngle), new Subtraction(majorArc, minorArc)); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original1); antecedent.Add(original2); antecedent.Add(inter); antecedent.Add(majorArc); antecedent.Add(minorArc); newGrounded.Add(new EdgeAggregator(antecedent, gaaeq, annotation)); return(newGrounded); }
private static EdgeAggregator CreateClause(Intersection inter, GroundedClause original, Angle theAngle, Arc theArc) { Multiplication product = new Multiplication(new NumericValue(2), theAngle); GeometricAngleArcEquation angArcEq = new GeometricAngleArcEquation(product, theArc); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original); antecedent.Add(inter); return(new EdgeAggregator(antecedent, angArcEq, annotation)); }
// / A // / |) // / | ) // / | ) // Q------- O---X---) D // \ | ) // \ | ) // \ |) // \ C // // Inscribed Angle(AQC) -> Angle(AQC) = 2 * Arc(AC) // private static List <EdgeAggregator> InstantiateTheorem(Circle circle, Angle angle) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // Acquire all circles in which the angle is inscribed List <Circle> circles = Circle.IsInscribedAngle(angle); // // Get this particular inscribed circle. // Circle inscribed = null; foreach (Circle c in circles) { if (circle.StructurallyEquals(c)) { inscribed = c; } } if (inscribed == null) { return(newGrounded); } // Get the intercepted arc Arc intercepted = Arc.GetInterceptedArc(inscribed, angle); // // Create the equation // Multiplication product = new Multiplication(new NumericValue(2), angle); GeometricAngleArcEquation gaaeq = new GeometricAngleArcEquation(product, intercepted); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(circle); antecedent.Add(angle); antecedent.Add(intercepted); newGrounded.Add(new EdgeAggregator(antecedent, gaaeq, annotation)); return(newGrounded); }
// // A \ // \ B // \ / // O \/ X // /\ // / \ // C / D // // One Secant, One Tangent // Intersection(X, AD, BC), Tangent(Circle(O), BC) -> 2 * Angle(AXC) = MajorArc(AC) - MinorArc(AC) // public static List <EdgeAggregator> InstantiateOneSecantOneTangentTheorem(Intersection inter, Tangent tangent, GroundedClause original) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); CircleSegmentIntersection tan = tangent.intersection as CircleSegmentIntersection; // Is the tangent segment part of the intersection? if (!inter.HasSegment(tan.segment)) { return(newGrounded); } // Acquire the chord that the intersection creates. Segment secant = inter.OtherSegment(tan.segment); Circle circle = tan.theCircle; Segment chord = circle.ContainsChord(secant); // Check if this segment never intersects the circle or doesn't create a chord. if (chord == null) { return(newGrounded); } // // Get the near / far points out of the chord // Point closeChordPt = null; Point farChordPt = null; if (Segment.Between(chord.Point1, chord.Point2, inter.intersect)) { closeChordPt = chord.Point1; farChordPt = chord.Point2; } else { closeChordPt = chord.Point2; farChordPt = chord.Point1; } // // Acquire the arcs // // Get the close arc first which we know exactly how it is constructed AND that it's a minor arc. Arc closeArc = Arc.GetFigureMinorArc(circle, closeChordPt, tan.intersect); // The far arc MAY be a major arc; if it is, the first candidate arc will contain the close arc. Arc farArc = Arc.GetFigureMinorArc(circle, farChordPt, tan.intersect); if (farArc.HasMinorSubArc(closeArc)) { farArc = Arc.GetFigureMajorArc(circle, farChordPt, tan.intersect); } Angle theAngle = Angle.AcquireFigureAngle(new Angle(closeChordPt, inter.intersect, tan.intersect)); // // Construct the new relationship // NumericValue two = new NumericValue(2); GeometricAngleArcEquation gaaeq = new GeometricAngleArcEquation(new Multiplication(two, theAngle), new Subtraction(farArc, closeArc)); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original); antecedent.Add(inter); antecedent.Add(closeArc); antecedent.Add(farArc); newGrounded.Add(new EdgeAggregator(antecedent, gaaeq, annotation)); return(newGrounded); }
// // A \ // \ B // \ / // O \/ X // /\ // / \ // C / D // // Two Secants // Intersection(X, AD, BC) -> 2 * Angle(AXC) = MajorArc(AC) - MinorArc(AC) // public static List <EdgeAggregator> InstantiateTwoSecantsTheorem(Intersection inter, Circle circle) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // Is this intersection explicitly outside the circle? That is, the point of intersection exterior? if (!circle.PointIsExterior(inter.intersect)) { return(newGrounded); } // // Get the chords // Segment chord1 = circle.ContainsChord(inter.lhs); Segment chord2 = circle.ContainsChord(inter.rhs); if (chord1 == null || chord2 == null) { return(newGrounded); } Point closeChord1Pt = null; Point closeChord2Pt = null; Point farChord1Pt = null; Point farChord2Pt = null; if (Segment.Between(chord1.Point1, chord1.Point2, inter.intersect)) { closeChord1Pt = chord1.Point1; farChord1Pt = chord1.Point2; } else { closeChord1Pt = chord1.Point2; farChord1Pt = chord1.Point1; } if (Segment.Between(chord2.Point1, chord2.Point2, inter.intersect)) { closeChord2Pt = chord2.Point1; farChord2Pt = chord2.Point2; } else { closeChord2Pt = chord2.Point2; farChord2Pt = chord2.Point1; } // // Get the arcs // Arc closeArc = Arc.GetFigureMinorArc(circle, closeChord1Pt, closeChord2Pt); Arc farArc = Arc.GetFigureMinorArc(circle, farChord1Pt, farChord2Pt); Angle theAngle = Angle.AcquireFigureAngle(new Angle(closeChord1Pt, inter.intersect, closeChord2Pt)); // // Construct the new relationship // NumericValue two = new NumericValue(2); //GeometricAngleEquation gaeq = new GeometricAngleEquation(new Multiplication(two, theAngle), new Subtraction(farArc, closeArc)); GeometricAngleArcEquation gaaeq = new GeometricAngleArcEquation(new Multiplication(two, theAngle), new Subtraction(farArc, closeArc)); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(inter); antecedent.Add(circle); antecedent.Add(closeArc); antecedent.Add(farArc); newGrounded.Add(new EdgeAggregator(antecedent, gaaeq, annotation)); return(newGrounded); }
// // C // /) // / ) // / ) // / ) // A /)_________ B // // Tangent(Circle(O), Segment(AB)), Intersection(Segment(AC), Segment(AB)) -> 2 * Angle(CAB) = Arc(C, B) // public static List <EdgeAggregator> InstantiateTheorem(Intersection inter, Tangent tangent, GroundedClause original) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); CircleSegmentIntersection tan = tangent.intersection as CircleSegmentIntersection; // // Does this tangent apply to this intersection? // if (!inter.intersect.StructurallyEquals(tangent.intersection.intersect)) { return(newGrounded); } Segment secant = null; Segment tanSegment = null; if (tan.HasSegment(inter.lhs)) { secant = inter.rhs; tanSegment = inter.lhs; } else if (tan.HasSegment(inter.rhs)) { secant = inter.lhs; tanSegment = inter.rhs; } else { return(newGrounded); } // // Acquire the angle and intercepted arc. // Segment chord = tan.theCircle.GetChord(secant); if (chord == null) { return(newGrounded); } //Segment chord = tan.theCircle.ContainsChord(secant); // Arc // We want the MINOR ARC only! if (tan.theCircle.DefinesDiameter(chord)) { Arc theArc = null; Point midpt = PointFactory.GeneratePoint(tan.theCircle.Midpoint(chord.Point1, chord.Point2)); Point opp = PointFactory.GeneratePoint(tan.theCircle.OppositePoint(midpt)); Point tanPoint = tanSegment.OtherPoint(inter.intersect); if (tanPoint != null) { // Angle; the smaller angle is always the chosen angle Angle theAngle = new Angle(chord.OtherPoint(inter.intersect), inter.intersect, tanPoint); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, midpt, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, opp, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); } else { // Angle; the smaller angle is always the chosen angle Angle theAngle = new Angle(chord.OtherPoint(inter.intersect), inter.intersect, tanSegment.Point1); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, midpt, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, opp, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); // Angle; the smaller angle is always the chosen angle theAngle = new Angle(chord.OtherPoint(inter.intersect), inter.intersect, tanSegment.Point2); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, midpt, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); theArc = new Semicircle(tan.theCircle, chord.Point1, chord.Point2, opp, chord); newGrounded.Add(CreateClause(inter, original, theAngle, theArc)); } } else { Arc theArc = new MinorArc(tan.theCircle, chord.Point1, chord.Point2); // Angle; the smaller angle is always the chosen angle Point endPnt = (inter.intersect.StructurallyEquals(tanSegment.Point1)) ? tanSegment.Point2 : tanSegment.Point1; Angle theAngle = new Angle(chord.OtherPoint(inter.intersect), inter.intersect, endPnt); if (theAngle.measure > 90) { //If the angle endpoint was already set to Point2, or if the intersect equals Point2, then the smaller angle does not exist //In this case, should we create a major arc or return nothing? if (endPnt.StructurallyEquals(tanSegment.Point2) || inter.intersect.StructurallyEquals(tanSegment.Point2)) { return(newGrounded); } theAngle = new Angle(chord.OtherPoint(inter.intersect), inter.intersect, tanSegment.Point2); } Multiplication product = new Multiplication(new NumericValue(2), theAngle); GeometricAngleArcEquation angArcEq = new GeometricAngleArcEquation(product, theArc); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original); antecedent.Add(inter); antecedent.Add(theArc); antecedent.Add(theAngle); newGrounded.Add(new EdgeAggregator(antecedent, angArcEq, annotation)); } return(newGrounded); }
//private static readonly string NAME = "Simplification"; // // Given an equation, simplify algebraically using the following notions: // A + A = B -> 2A = B // A + B = B + C -> A = C // A + B = 2B + C -> A = B + C // public static Equation Simplify(Equation original) { // Do we have an equation? if (original == null) { throw new ArgumentException(); } // Is the equation 0 = 0? This should be allowed at it indicates a tautology if (original.lhs.Equals(new NumericValue(0)) && original.rhs.Equals(new NumericValue(0))) { throw new ArgumentException("Should not have an equation that is 0 = 0: " + original.ToString()); } // // Ideally, flattening would: // Remove all subtractions -> adding a negative instead // Distribute subtraction or multiplication over addition // // Flatten the equation so that each side is a sum of atomic expressions Equation copyEq = (Equation)original.DeepCopy(); FlatEquation flattened = new FlatEquation(copyEq.lhs.CollectTerms(), copyEq.rhs.CollectTerms()); //Debug.WriteLine("Equation prior to simplification: " + flattened.ToString()); // Combine terms only on each side (do not cross =) FlatEquation combined = CombineLikeTerms(flattened); //Debug.WriteLine("Equation after like terms combined on both sides: " + combined); // Combine terms across the equal sign FlatEquation across = CombineLikeTermsAcrossEqual(combined); //Debug.WriteLine("Equation after simplifying both sides: " + across); FlatEquation constSimplify = SimplifyForMultipliersAndConstants(across); // // Inflate the equation // Equation inflated = null; GroundedClause singleLeftExp = InflateEntireSide(constSimplify.lhsExps); GroundedClause singleRightExp = InflateEntireSide(constSimplify.rhsExps); if (original is AlgebraicSegmentEquation) { inflated = new AlgebraicSegmentEquation(singleLeftExp, singleRightExp); } else if (original is GeometricSegmentEquation) { inflated = new GeometricSegmentEquation(singleLeftExp, singleRightExp); } else if (original is AlgebraicAngleEquation) { inflated = new AlgebraicAngleEquation(singleLeftExp, singleRightExp); } else if (original is GeometricAngleEquation) { inflated = new GeometricAngleEquation(singleLeftExp, singleRightExp); } else if (original is AlgebraicArcEquation) { inflated = new AlgebraicArcEquation(singleLeftExp, singleRightExp); } else if (original is GeometricArcEquation) { inflated = new GeometricArcEquation(singleLeftExp, singleRightExp); } else if (original is AlgebraicAngleArcEquation) { inflated = new AlgebraicAngleArcEquation(singleLeftExp, singleRightExp); } else if (original is GeometricAngleArcEquation) { inflated = new GeometricAngleArcEquation(singleLeftExp, singleRightExp); } // If simplifying didn't do anything, return the original equation if (inflated.Equals(original)) { return(original); } // // 0 = 0 should not be allowable. // if (inflated.lhs.Equals(new NumericValue(0)) && inflated.rhs.Equals(new NumericValue(0))) { return(null); } return(inflated); }
// // A \ / B // \ / // \ / // O \/ X // /\ // / \ // C / \ D // // Intersection(Segment(AD), Segment(BC)) -> 2 * Angle(CXA) = Arc(A, C) + Arc(B, D), // 2 * Angle(BXD) = Arc(A, C) + Arc(B, D), // 2 * Angle(AXB) = Arc(A, B) + Arc(C, D), // 2 * Angle(CXD) = Arc(A, B) + Arc(C, D) // public static List <EdgeAggregator> InstantiateTheorem(Intersection inter, Circle circle) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // Is this intersection explicitly inside the circle? That is, the point of intersection interior? if (!circle.PointIsInterior(inter.intersect)) { return(newGrounded); } // // Get the chords // Segment chord1 = circle.GetChord(inter.lhs); Segment chord2 = circle.GetChord(inter.rhs); if (chord1 == null || chord2 == null) { return(newGrounded); } // // Group 1 // Arc arc1 = Arc.GetFigureMinorArc(circle, chord1.Point1, chord2.Point1); Angle angle1 = Angle.AcquireFigureAngle(new Angle(chord1.Point1, inter.intersect, chord2.Point1)); Arc oppArc1 = Arc.GetFigureMinorArc(circle, chord1.Point2, chord2.Point2); Angle oppAngle1 = Angle.AcquireFigureAngle(new Angle(chord1.Point2, inter.intersect, chord2.Point2)); // // Group 2 // Arc arc2 = Arc.GetFigureMinorArc(circle, chord1.Point1, chord2.Point2); Angle angle2 = Angle.AcquireFigureAngle(new Angle(chord1.Point1, inter.intersect, chord2.Point2)); Arc oppArc2 = Arc.GetFigureMinorArc(circle, chord1.Point2, chord2.Point1); Angle oppAngle2 = Angle.AcquireFigureAngle(new Angle(chord1.Point2, inter.intersect, chord2.Point1)); // // Construct each of the 4 equations. // NumericValue two = new NumericValue(2); GeometricAngleArcEquation gaeq1 = new GeometricAngleArcEquation(new Multiplication(two, angle1), new Addition(arc1, oppArc1)); GeometricAngleArcEquation gaeq2 = new GeometricAngleArcEquation(new Multiplication(two, oppAngle1), new Addition(arc1, oppArc1)); GeometricAngleArcEquation gaeq3 = new GeometricAngleArcEquation(new Multiplication(two, angle2), new Addition(arc2, oppArc2)); GeometricAngleArcEquation gaeq4 = new GeometricAngleArcEquation(new Multiplication(two, oppAngle2), new Addition(arc2, oppArc2)); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(inter); antecedent.Add(circle); newGrounded.Add(new EdgeAggregator(antecedent, gaeq1, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, gaeq2, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, gaeq3, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, gaeq4, annotation)); return(newGrounded); }