// // Since we are cutting segments into sections, there is a direct relationship between the split side lengths for each side. // protected void GetGranularMidpointEquations(out List <Equation> eqs, out List <Congruent> congs) { eqs = new List <Equation>(); congs = new List <Congruent>(); // // Each sub-segment is equal to each other on each side. // for (int side = 0; side < sideSubsegments.Length; side++) { for (int s1 = 0; s1 < sideSubsegments[side].Count - 1; s1++) { for (int s2 = s1 + 1; s2 < sideSubsegments[side].Count; s2++) { congs.Add(new GeometricCongruentSegments(sideSubsegments[side][s1], sideSubsegments[side][s2])); } } } // // Each sub-segment is equation to a fraction of the side length. // int factor = (int)Math.Pow(2, NUM_MID_SEGMENT_POINTS); NumericValue factorVal = new NumericValue(factor); if (factor != sideSubsegments[0].Count) { throw new Exception("Disagreement with the number of sub-segments in polygon"); } for (int side = 0; side < sideSubsegments.Length; side++) { foreach (Segment subSeg in sideSubsegments[side]) { // Factor * sub-segment = whole side eqs.Add(new GeometricSegmentEquation(new Multiplication(factorVal, subSeg), orderedSides[side])); } } }
// // Triangle(A, B, C) -> m\angle ABC + m\angle CAB + m\angle BCA = 180^o // public static List<EdgeAggregator> Instantiate(GroundedClause c) { annotation.active = EngineUIBridge.JustificationSwitch.SUM_ANGLES_IN_TRIANGLE_180; List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); Triangle tri = c as Triangle; if (tri == null) return newGrounded; // Generate, by definition the sum of the three angles equal 180^o Angle a1 = new Angle(tri.Point1, tri.Point2, tri.Point3); Angle a2 = new Angle(tri.Point3, tri.Point1, tri.Point2); Angle a3 = new Angle(tri.Point2, tri.Point3, tri.Point1); Addition add = new Addition(a1, a2); Addition overallAdd = new Addition(add, a3); NumericValue value = new NumericValue(180); // Sum is 180^o GeometricAngleEquation eq = new GeometricAngleEquation(overallAdd, value); List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(tri); newGrounded.Add(new EdgeAggregator(antecedent, eq, annotation)); return newGrounded; }
// // 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; }
// // 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; }
// // 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; }
// // Check for (basically) atomic equations involving one unknown and constants otherwise. // private static FlatEquation SimplifyForMultipliersAndConstants(FlatEquation inEq) { if (inEq.lhsExps.Count != 1 || inEq.rhsExps.Count != 1) return inEq; // // Figure out what we're looking at. // NumericValue value = null; GroundedClause unknown = null; if (inEq.lhsExps[0] is NumericValue) { value = inEq.lhsExps[0] as NumericValue; unknown = inEq.rhsExps[0]; } else if (inEq.rhsExps[0] is NumericValue) { value = inEq.rhsExps[0] as NumericValue; unknown = inEq.lhsExps[0]; } // Not the type of equation we were looking for. else return inEq; // // Divide both sides to simplify. // if (unknown.multiplier != 1) { NumericValue newValue = new NumericValue(value.DoubleValue / unknown.multiplier); // reset the multiplier unknown.multiplier = 1; return new FlatEquation(Utilities.MakeList<GroundedClause>(unknown), Utilities.MakeList<GroundedClause>(newValue)); } // Nothing happened so return original return inEq; }
// // 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; }