private static List<EdgeAggregator> InstantiateToDefinition(CongruentSegments css) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // // Find all the circles for which the two segments are radii. // List<Circle> circlesCSS1 = Circle.GetFigureCirclesByRadius(css.cs1); List<Circle> circlesCSS2 = Circle.GetFigureCirclesByRadius(css.cs2); // // Since the radii are congruent, the circles are therefore congruent. // foreach (Circle cc1 in circlesCSS1) { foreach (Circle cc2 in circlesCSS2) { // Avoid generating refexive relationships(?) if (!cc1.StructurallyEquals(cc2)) { // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(css); antecedent.Add(cc1); antecedent.Add(cc2); GeometricCongruentCircles gccs = new GeometricCongruentCircles(cc1, cc2); newGrounded.Add(new EdgeAggregator(antecedent, gccs, annotation)); } } } return newGrounded; }
// Return the shared segment in both congruences public Segment SegmentShared(CongruentSegments thatCC) { if (SharesNumClauses(thatCC) != 1) { return(null); } return(smallerSegment.Equals(thatCC.cs1) || smallerSegment.Equals(thatCC.cs2) ? smallerSegment : largerSegment); }
// Return the shared segment in both congruences public Segment SegmentShared(CongruentSegments thatCC) { if (SharesNumClauses(thatCC) != 1) { return(null); } return(cs1.Equals(thatCC.cs1) || cs1.Equals(thatCC.cs2) ? cs1 : cs2); }
public static bool AcquireCongruences(KnownMeasurementsAggregator known, List <GroundedClause> clauses) { bool addedKnown = false; foreach (GeometryTutorLib.ConcreteAST.GroundedClause clause in clauses) { GeometryTutorLib.ConcreteAST.CongruentSegments cs = clause as GeometryTutorLib.ConcreteAST.CongruentSegments; if (cs != null && !cs.IsReflexive()) { double length1 = known.GetSegmentLength(cs.cs1); double length2 = known.GetSegmentLength(cs.cs2); if (length1 >= 0 && length2 < 0) { if (known.AddSegmentLength(cs.cs2, length1)) { addedKnown = true; } } if (length1 <= 0 && length2 > 0) { if (known.AddSegmentLength(cs.cs1, length2)) { addedKnown = true; } } // else: both known } GeometryTutorLib.ConcreteAST.CongruentAngles cas = clause as GeometryTutorLib.ConcreteAST.CongruentAngles; if (cas != null && !cas.IsReflexive()) { double measure1 = known.GetAngleMeasure(cas.ca1); double measure2 = known.GetAngleMeasure(cas.ca2); if (measure1 >= 0 && measure2 < 0) { if (known.AddAngleMeasureDegree(cas.ca2, measure1)) { addedKnown = true; } } if (measure1 <= 0 && measure2 > 0) { if (known.AddAngleMeasureDegree(cas.ca1, measure2)) { addedKnown = true; } } // else: both known } } return(addedKnown); }
public override bool Equals(Object obj) { CongruentSegments ccs = obj as CongruentSegments; if (ccs == null) { return(false); } return((cs1.Equals(ccs.cs1) && cs2.Equals(ccs.cs2)) || (cs1.Equals(ccs.cs2) && cs2.Equals(ccs.cs1)) && base.Equals(obj)); }
// Return the number of shared segments in both congruences public int SharesNumClauses(CongruentSegments thatCS) { //CongruentSegments css = thatPS as CongruentSegments; //if (css == null) return 0; int numShared = smallerSegment.Equals(thatCS.cs1) || smallerSegment.Equals(thatCS.cs2) ? 1 : 0; numShared += largerSegment.Equals(thatCS.cs1) || largerSegment.Equals(thatCS.cs2) ? 1 : 0; return(numShared); }
public override bool StructurallyEquals(Object obj) { CongruentSegments ccs = obj as CongruentSegments; if (ccs == null) { return(false); } return((cs1.StructurallyEquals(ccs.cs1) && cs2.StructurallyEquals(ccs.cs2)) || (cs1.StructurallyEquals(ccs.cs2) && cs2.StructurallyEquals(ccs.cs1))); }
public Segment SharedSegment(CongruentSegments ccs) { if (ccs.cs1.StructurallyEquals(this.cs1) || ccs.cs2.StructurallyEquals(this.cs1)) { return(this.cs1); } if (ccs.cs1.StructurallyEquals(this.cs2) || ccs.cs2.StructurallyEquals(this.cs2)) { return(this.cs2); } return(null); }
// // Are the legs congruent (for an isosceles trapezoid)? // public bool CreatesCongruentLegs(CongruentSegments css) { if (leftLeg.StructurallyEquals(css.cs1) && rightLeg.StructurallyEquals(css.cs2)) { return(true); } if (leftLeg.StructurallyEquals(css.cs2) && rightLeg.StructurallyEquals(css.cs1)) { return(true); } return(false); }
// Return the number of shared segments in both congruences public override int SharesNumClauses(Congruent thatCC) { CongruentSegments ccss = thatCC as CongruentSegments; if (ccss == null) { return(0); } int numShared = cs1.Equals(ccss.cs1) || cs1.Equals(ccss.cs2) ? 1 : 0; numShared += cs2.Equals(ccss.cs1) || cs2.Equals(ccss.cs2) ? 1 : 0; return(numShared); }
// // Just generate the new angle congruence // private static List<EdgeAggregator> InstantiateToCongruence(Triangle tri, CongruentSegments css) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); if (!tri.HasSegment(css.cs1) || !tri.HasSegment(css.cs2)) return newGrounded; GeometricCongruentAngles newConAngs = new GeometricCongruentAngles(tri.GetOppositeAngle(css.cs1), tri.GetOppositeAngle(css.cs2)); List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(css); antecedent.Add(tri); newGrounded.Add(new EdgeAggregator(antecedent, newConAngs, annotation)); return newGrounded; }
public static List <GenericInstantiator.EdgeAggregator> CreateTransitiveCongruence(Congruent congruent1, Congruent congruent2) { List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>(); // // Create the antecedent clauses // List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(congruent1); antecedent.Add(congruent2); // // Create the consequent clause // Congruent newCC = null; if (congruent1 is CongruentSegments) { CongruentSegments css1 = congruent1 as CongruentSegments; CongruentSegments css2 = congruent2 as CongruentSegments; Segment shared = css1.SegmentShared(css2); newCC = new AlgebraicCongruentSegments(css1.OtherSegment(shared), css2.OtherSegment(shared)); } else if (congruent1 is CongruentAngles) { CongruentAngles cas1 = congruent1 as CongruentAngles; CongruentAngles cas2 = congruent2 as CongruentAngles; Angle shared = cas1.AngleShared(cas2); newCC = new AlgebraicCongruentAngles(cas1.OtherAngle(shared), cas2.OtherAngle(shared)); } if (newCC == null) { System.Diagnostics.Debug.WriteLine(""); throw new NullReferenceException("Unexpected Problem in Atomic substitution..."); } newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newCC, annotation)); return(newGrounded); }
// // Are the legs congruent (for an isosceles trapezoid)? // public bool CreatesCongruentLegs(CongruentSegments css) { if (leftLeg.StructurallyEquals(css.cs1) && rightLeg.StructurallyEquals(css.cs2)) return true; if (leftLeg.StructurallyEquals(css.cs2) && rightLeg.StructurallyEquals(css.cs1)) return true; return false; }
public bool SharedVertex(CongruentSegments ccs) { return(ccs.cs1.SharedVertex(cs1) != null || ccs.cs1.SharedVertex(cs2) != null || ccs.cs2.SharedVertex(cs1) != null || ccs.cs2.SharedVertex(cs2) != null); }
// // Does this congruent pair apply to this quadrilateral? // public bool HasOppositeCongruentSides(CongruentSegments cs) { return(AreOppositeSides(cs.cs1, cs.cs2)); }
// A // /) // / ) // / ) // center: O ) // \ ) // \ ) // \) // C // // D // /) // / ) // / ) // center: Q ) // \ ) // \ ) // \) // F // // Congruent(Segment(AC), Segment(DF)) -> Congruent(Arc(A, C), Arc(D, F)) // private static List<EdgeAggregator> InstantiateForwardPartOfTheorem(CongruentSegments cas) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // // Acquire the circles for which the segments are chords. // List<Circle> circles1 = Circle.GetChordCircles(cas.cs1); List<Circle> circles2 = Circle.GetChordCircles(cas.cs2); // // Make all possible combinations of arcs congruent // foreach (Circle circle1 in circles1) { // Create the appropriate type of arcs from the chord and the circle List<Semicircle> c1semi = null; MinorArc c1minor = null; MajorArc c1major = null; if (circle1.DefinesDiameter(cas.cs1)) { c1semi = CreateSemiCircles(circle1, cas.cs1); } else { c1minor = new MinorArc(circle1, cas.cs1.Point1, cas.cs1.Point2); c1major = new MajorArc(circle1, cas.cs1.Point1, cas.cs1.Point2); } foreach (Circle circle2 in circles2) { //The two circles must be the same or congruent if (circle1.radius == circle2.radius) { List<Semicircle> c2semi = null; MinorArc c2minor = null; MajorArc c2major = null; List<GeometricCongruentArcs> congruencies = new List<GeometricCongruentArcs>(); if (circle2.DefinesDiameter(cas.cs2)) { c2semi = CreateSemiCircles(circle2, cas.cs2); congruencies.AddRange(EquateSemiCircles(c1semi, c2semi)); } else { c2minor = new MinorArc(circle2, cas.cs2.Point1, cas.cs2.Point2); c2major = new MajorArc(circle2, cas.cs2.Point1, cas.cs2.Point2); congruencies.Add(new GeometricCongruentArcs(c1minor, c2minor)); congruencies.Add(new GeometricCongruentArcs(c1major, c2major)); } // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(cas.cs1); antecedent.Add(cas.cs2); antecedent.Add(cas); foreach (GeometricCongruentArcs gcas in congruencies) { newGrounded.Add(new EdgeAggregator(antecedent, gcas, forwardAnnotation)); } } } } return newGrounded; }
// // Does this congruent pair apply to this quadrilateral? // public bool HasOppositeCongruentSides(CongruentSegments cs) { return AreOppositeSides(cs.cs1, cs.cs2); }
// // Acquires all of the applicable congruent segments; then checks HL // private static List<EdgeAggregator> ReconfigureAndCheck(RightTriangle rt1, RightTriangle rt2, CongruentSegments css1, CongruentSegments css2) { return CollectAndCheckHL(rt1, rt2, css1, css2, rt1, rt2); }
private static List<EdgeAggregator> InstantiateToIsoscelesTrapezoid(Trapezoid trapezoid, CongruentSegments css, GroundedClause original) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Does this paralle set apply to this triangle? if (!trapezoid.CreatesCongruentLegs(css)) return newGrounded; // // Create the new IsoscelesTrapezoid object // Strengthened newIsoscelesTrapezoid = new Strengthened(trapezoid, new IsoscelesTrapezoid(trapezoid)); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(original); antecedent.Add(css); newGrounded.Add(new EdgeAggregator(antecedent, newIsoscelesTrapezoid, annotation)); return newGrounded; }
// Of the congruent pair, return the segment that applies to this triangle public Segment GetSegment(CongruentSegments ccss) { if (HasSegment(ccss.cs1)) return ccss.cs1; if (HasSegment(ccss.cs2)) return ccss.cs2; return null; }
// Return the number of shared segments in both congruences public int SharesNumClauses(CongruentSegments thatCS) { //CongruentSegments css = thatPS as CongruentSegments; //if (css == null) return 0; int numShared = smallerSegment.Equals(thatCS.cs1) || smallerSegment.Equals(thatCS.cs2) ? 1 : 0; numShared += largerSegment.Equals(thatCS.cs1) || largerSegment.Equals(thatCS.cs2) ? 1 : 0; return numShared; }
// // Take the angle congruence and bisector and create the AngleBisector relation // \ // \ // B ---------V---------A // \ // \ // C // private static List<EdgeAggregator> InstantiateToDef(Point intersectionPoint, Intersection inter, CongruentSegments cs) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Does the given point of intersection apply to this actual intersection object if (!intersectionPoint.Equals(inter.intersect)) return newGrounded; // The entire segment AB Segment overallSegment = new Segment(cs.cs1.OtherPoint(intersectionPoint), cs.cs2.OtherPoint(intersectionPoint)); // The segment must align completely with one of the intersection segments Segment interCollinearSegment = inter.GetCollinearSegment(overallSegment); if (interCollinearSegment == null) return newGrounded; // Does this intersection have the entire segment AB if (!inter.HasSegment(overallSegment)) return newGrounded; Segment bisector = inter.OtherSegment(overallSegment); Segment bisectedSegment = inter.GetCollinearSegment(overallSegment); // Check if the bisected segment extends is the exact same segment as the overall segment AB if (!bisectedSegment.StructurallyEquals(overallSegment)) { if (overallSegment.PointLiesOnAndBetweenEndpoints(bisectedSegment.Point1) && overallSegment.PointLiesOnAndBetweenEndpoints(bisectedSegment.Point2)) return newGrounded; } SegmentBisector newSB = new SegmentBisector(inter, bisector); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(inter); antecedent.Add(cs); newGrounded.Add(new EdgeAggregator(antecedent, newSB, annotation)); return newGrounded; }
// Return the shared segment in both congruences public Segment SegmentShared(CongruentSegments thatCC) { if (SharesNumClauses(thatCC) != 1) return null; return smallerSegment.Equals(thatCC.cs1) || smallerSegment.Equals(thatCC.cs2) ? smallerSegment : largerSegment; }
private static List<EdgeAggregator> InstantiateToDefinition(Triangle tri, CongruentSegments cs1, CongruentSegments cs2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Do these congruences relate one common segment? Segment shared = cs1.SharedSegment(cs2); if (shared == null) return newGrounded; // // Do these congruences apply to this triangle? // if (!tri.HasSegment(cs1.cs1) || !tri.HasSegment(cs1.cs2)) return newGrounded; if (!tri.HasSegment(cs2.cs1) || !tri.HasSegment(cs2.cs2)) return newGrounded; // // These cannot be reflexive congruences. // if (cs1.IsReflexive() || cs2.IsReflexive()) return newGrounded; // // Are the non-shared segments unique? // Segment other1 = cs1.OtherSegment(shared); Segment other2 = cs2.OtherSegment(shared); if (other1.StructurallyEquals(other2)) return newGrounded; // // Generate the new equialteral clause // Strengthened newStrengthened = new Strengthened(tri, new EquilateralTriangle(tri)); List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(cs1); antecedent.Add(cs2); antecedent.Add(tri); newGrounded.Add(new EdgeAggregator(antecedent, newStrengthened, annotation)); return newGrounded; }
// // Congruent(Segment(A, M), Segment(M, B)) -> Midpoint(M, Segment(A, B)) // private static List<EdgeAggregator> InstantiateToMidpoint(InMiddle im, CongruentSegments css) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); Point midpoint = css.cs1.SharedVertex(css.cs2); // Does this InMiddle relate to the congruent segments? if (!im.point.StructurallyEquals(midpoint)) return newGrounded; // Do the congruent segments combine into a single segment equating to the InMiddle? Segment overallSegment = new Segment(css.cs1.OtherPoint(midpoint), css.cs2.OtherPoint(midpoint)); if (!im.segment.StructurallyEquals(overallSegment)) return newGrounded; Strengthened newMidpoint = new Strengthened(im, new Midpoint(im)); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(im); antecedent.Add(css); newGrounded.Add(new EdgeAggregator(antecedent, newMidpoint, annotation)); return newGrounded; }
// // // private static List<EdgeAggregator> IfCongruencesApplyToTrianglesGenerate(Triangle ct1, Triangle ct2, CongruentSegments css1, CongruentSegments css2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // // The congruent relationships need to link the given triangles // if (!css1.LinksTriangles(ct1, ct2)) return newGrounded; if (!css2.LinksTriangles(ct1, ct2)) return newGrounded; Segment seg1Tri1 = ct1.GetSegment(css1); Segment seg2Tri1 = ct1.GetSegment(css2); Segment seg1Tri2 = ct2.GetSegment(css1); Segment seg2Tri2 = ct2.GetSegment(css2); // Avoid redundant segments, if it arises if (seg1Tri1.StructurallyEquals(seg2Tri1)) return newGrounded; if (seg1Tri2.StructurallyEquals(seg2Tri2)) return newGrounded; // // Proportional Segments (we generate only as needed to avoid bloat in the hypergraph (assuming they are used by both triangles) // We avoid generating proportions if they are truly congruences. // List<GroundedClause> propAntecedent = new List<GroundedClause>(); propAntecedent.Add(css1); propAntecedent.Add(css2); SegmentRatio ratio1 = new SegmentRatio(seg1Tri1, seg1Tri2); SegmentRatio ratio2 = new SegmentRatio(seg2Tri1, seg2Tri2); GeometricSegmentRatioEquation newEq = new GeometricSegmentRatioEquation(ratio1, ratio2); newGrounded.Add(new EdgeAggregator(propAntecedent, newEq, annotation)); //// //// Only generate if ratios are not 1. //// //GeometricSegmentRatio newProp = null; //if (!Utilities.CompareValues(seg1Tri1.Length, seg1Tri2.Length)) //{ // newProp = new GeometricSegmentRatio(seg1Tri1, seg1Tri2); // newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation)); //} //if (!Utilities.CompareValues(seg1Tri1.Length, seg2Tri2.Length)) //{ // newProp = new GeometricSegmentRatio(seg1Tri1, seg2Tri2); // newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation)); //} //if (!Utilities.CompareValues(seg2Tri1.Length, seg1Tri2.Length)) //{ // newProp = new GeometricSegmentRatio(seg2Tri1, seg1Tri2); // newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation)); //} //if (!Utilities.CompareValues(seg2Tri1.Length, seg2Tri2.Length)) //{ // newProp = new GeometricSegmentRatio(seg2Tri1, seg2Tri2); // newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation)); //} return newGrounded; }
private static List<EdgeAggregator> InstantiateToTheorem(Quadrilateral quad, CongruentSegments cs, Parallel parallel) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Are the pairs on the opposite side of this quadrilateral? if (!quad.HasOppositeCongruentSides(cs)) return newGrounded; if (!quad.HasOppositeParallelSides(parallel)) return newGrounded; // Do the congruent segments coincide with these parallel segments? if (!parallel.segment1.HasSubSegment(cs.cs1) && !parallel.segment2.HasSubSegment(cs.cs1)) return newGrounded; if (!parallel.segment1.HasSubSegment(cs.cs2) && !parallel.segment2.HasSubSegment(cs.cs2)) return newGrounded; // // Create the new Rhombus object // Strengthened newParallelogram = new Strengthened(quad, new Parallelogram(quad)); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(quad); antecedent.Add(cs); antecedent.Add(parallel); newGrounded.Add(new EdgeAggregator(antecedent, newParallelogram, annotation)); return newGrounded; }
// // Does this parallel set apply to this quadrilateral? // public bool HasAdjacentCongruentSides(CongruentSegments cs) { return AreAdjacentSides(cs.cs1, cs.cs2); }
public Segment SharedSegment(CongruentSegments ccs) { if (ccs.cs1.StructurallyEquals(this.cs1) || ccs.cs2.StructurallyEquals(this.cs1)) return this.cs1; if (ccs.cs1.StructurallyEquals(this.cs2) || ccs.cs2.StructurallyEquals(this.cs2)) return this.cs2; return null; }
// // Acquires all of the applicable congruent segments; then checks HL // private static List<EdgeAggregator> CollectAndCheckHL(RightTriangle rt1, RightTriangle rt2, CongruentSegments css1, CongruentSegments css2, GroundedClause original1, GroundedClause original2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // The Congruence pairs must relate the two triangles if (!css1.LinksTriangles(rt1, rt2) || !css2.LinksTriangles(rt1, rt2)) return newGrounded; // One of the congruence pairs must relate the hypotenuses Segment hypotenuse1 = rt1.OtherSide(rt1.rightAngle); Segment hypotenuse2 = rt2.OtherSide(rt2.rightAngle); // Determine the specific congruence pair that relates the hypotenuses CongruentSegments hypotenuseCongruence = null; CongruentSegments nonHypotenuseCongruence = null; if (css1.HasSegment(hypotenuse1) && css1.HasSegment(hypotenuse2)) { hypotenuseCongruence = css1; nonHypotenuseCongruence = css2; } else if (css2.HasSegment(hypotenuse1) && css2.HasSegment(hypotenuse2)) { hypotenuseCongruence = css2; nonHypotenuseCongruence = css1; } else return newGrounded; // Sanity check that the non hypotenuse congruence pair does not contain hypotenuse if (nonHypotenuseCongruence.HasSegment(hypotenuse1) || nonHypotenuseCongruence.HasSegment(hypotenuse2)) return newGrounded; // // We now have a hypotenuse leg situation; acquire the point-to-point congruence mapping // List<Point> triangleOne = new List<Point>(); List<Point> triangleTwo = new List<Point>(); // Right angle vertices correspond triangleOne.Add(rt1.rightAngle.GetVertex()); triangleTwo.Add(rt2.rightAngle.GetVertex()); Point nonRightVertexRt1 = rt1.GetSegment(nonHypotenuseCongruence).SharedVertex(hypotenuse1); Point nonRightVertexRt2 = rt2.GetSegment(nonHypotenuseCongruence).SharedVertex(hypotenuse2); triangleOne.Add(nonRightVertexRt1); triangleTwo.Add(nonRightVertexRt2); triangleOne.Add(hypotenuse1.OtherPoint(nonRightVertexRt1)); triangleTwo.Add(hypotenuse2.OtherPoint(nonRightVertexRt2)); // // Construct the new deduced relationships // GeometricCongruentTriangles ccts = new GeometricCongruentTriangles(new Triangle(triangleOne), new Triangle(triangleTwo)); // Hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(original1); antecedent.Add(original2); antecedent.Add(css1); antecedent.Add(css2); newGrounded.Add(new EdgeAggregator(antecedent, ccts, annotation)); // Add all the corresponding parts as new congruent clauses newGrounded.AddRange(CongruentTriangles.GenerateCPCTC(ccts, triangleOne, triangleTwo)); return newGrounded; }
public bool SharedVertex(CongruentSegments ccs) { return ccs.cs1.SharedVertex(cs1) != null || ccs.cs1.SharedVertex(cs2) != null || ccs.cs2.SharedVertex(cs1) != null || ccs.cs2.SharedVertex(cs2) != null; }
private static List<EdgeAggregator> ReconfigureAndCheck(Strengthened streng1, Strengthened streng2, CongruentSegments css1, CongruentSegments css2) { return CollectAndCheckHL(streng1.strengthened as RightTriangle, streng2.strengthened as RightTriangle, css1, css2, streng1, streng2); }
// Return the shared segment in both congruences public Segment SegmentShared(CongruentSegments thatCC) { if (SharesNumClauses(thatCC) != 1) return null; return cs1.Equals(thatCC.cs1) || cs1.Equals(thatCC.cs2) ? cs1 : cs2; }
// // Does this parallel set apply to this quadrilateral? // public bool HasAdjacentCongruentSides(CongruentSegments cs) { return(AreAdjacentSides(cs.cs1, cs.cs2)); }
// // Checks for ASA given the 5 values // private static List<EdgeAggregator> InstantiateAAS(Triangle tri1, Triangle tri2, CongruentAngles cas1, CongruentAngles cas2, CongruentSegments css) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // // All congruence pairs must minimally relate the triangles // if (!cas1.LinksTriangles(tri1, tri2)) return newGrounded; if (!cas2.LinksTriangles(tri1, tri2)) return newGrounded; if (!css.LinksTriangles(tri1, tri2)) return newGrounded; // Is this angle an 'extension' of the actual triangle angle? If so, acquire the normalized version of // the angle, using only the triangle vertices to represent the angle Angle angle1Tri1 = tri1.NormalizeAngle(tri1.AngleBelongs(cas1)); Angle angle1Tri2 = tri2.NormalizeAngle(tri2.AngleBelongs(cas1)); Angle angle2Tri1 = tri1.NormalizeAngle(tri1.AngleBelongs(cas2)); Angle angle2Tri2 = tri2.NormalizeAngle(tri2.AngleBelongs(cas2)); // The angles for each triangle must be distinct if (angle1Tri1.Equals(angle2Tri1) || angle1Tri2.Equals(angle2Tri2)) return newGrounded; Segment segTri1 = tri1.GetSegment(css); Segment segTri2 = tri2.GetSegment(css); // ASA situations if (segTri1.IsIncludedSegment(angle1Tri1, angle2Tri1)) return newGrounded; if (segTri2.IsIncludedSegment(angle1Tri2, angle2Tri2)) return newGrounded; // The segments for each triangle must be corresponding if (segTri1.Equals(tri1.OtherSide(angle1Tri1)) && segTri2.Equals(tri2.OtherSide(angle2Tri2))) return newGrounded; if (segTri1.Equals(tri1.OtherSide(angle2Tri1)) && segTri2.Equals(tri2.OtherSide(angle1Tri2))) return newGrounded; // // Construct the corrsesponding points between the triangles // List<Point> triangleOne = new List<Point>(); List<Point> triangleTwo = new List<Point>(); triangleOne.Add(angle1Tri1.GetVertex()); triangleTwo.Add(angle1Tri2.GetVertex()); triangleOne.Add(angle2Tri1.GetVertex()); triangleTwo.Add(angle2Tri2.GetVertex()); // We know the segment endpoint mappings above, now acquire the opposite point triangleOne.Add(tri1.OtherPoint(angle1Tri1.GetVertex(), angle2Tri1.GetVertex())); triangleTwo.Add(tri2.OtherPoint(angle1Tri2.GetVertex(), angle2Tri2.GetVertex())); // // Construct the new clauses: congruent triangles and CPCTC // GeometricCongruentTriangles gcts = new GeometricCongruentTriangles(new Triangle(triangleOne), new Triangle(triangleTwo)); // Hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(tri1); antecedent.Add(tri2); antecedent.Add(cas1); antecedent.Add(cas2); antecedent.Add(css); newGrounded.Add(new EdgeAggregator(antecedent, gcts, annotation)); // Add all the corresponding parts as new congruent clauses newGrounded.AddRange(CongruentTriangles.GenerateCPCTC(gcts, triangleOne, triangleTwo)); return newGrounded; }
private static List<EdgeAggregator> InstantiateToKite(Quadrilateral quad, CongruentSegments cs1, CongruentSegments cs2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // The congruences should not share a side. if (cs1.SharedSegment(cs2) != null) return newGrounded; // The congruent pairs should not also be congruent to each other if (cs1.cs1.CoordinateCongruent(cs2.cs1)) return newGrounded; // Does both set of congruent segments apply to the quadrilateral? if (!quad.HasAdjacentCongruentSides(cs1)) return newGrounded; if (!quad.HasAdjacentCongruentSides(cs2)) return newGrounded; // // Create the new Kite object // Strengthened newKite = new Strengthened(quad, new Kite(quad)); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(quad); antecedent.Add(cs1); antecedent.Add(cs2); newGrounded.Add(new EdgeAggregator(antecedent, newKite, annotation)); return newGrounded; }
private static List<EdgeAggregator> InstantiateToRhombus(Quadrilateral quad, CongruentSegments cs1, CongruentSegments cs2, CongruentSegments cs3) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // // The 3 congruent segments pairs must relate; one pair must link the two others. // Determine the link segments as well as the opposite sides. // CongruentSegments link = null; CongruentSegments opp1 = null; CongruentSegments opp2 = null; if (cs1.SharedSegment(cs2) != null && cs1.SharedSegment(cs3) != null) { link = cs1; opp1 = cs2; opp2 = cs3; } else if (cs2.SharedSegment(cs1) != null && cs2.SharedSegment(cs3) != null) { link = cs2; opp1 = cs1; opp2 = cs3; } else if (cs3.SharedSegment(cs1) != null && cs3.SharedSegment(cs2) != null) { link = cs3; opp1 = cs1; opp2 = cs2; } else return newGrounded; // Are the pairs on the opposite side of this quadrilateral? if (!quad.HasOppositeCongruentSides(opp1)) return newGrounded; if (!quad.HasOppositeCongruentSides(opp2)) return newGrounded; // // Create the new Rhombus object // Strengthened newRhombus = new Strengthened(quad, new Rhombus(quad)); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(quad); antecedent.Add(cs1); antecedent.Add(cs2); antecedent.Add(cs3); newGrounded.Add(new EdgeAggregator(antecedent, newRhombus, annotation)); return newGrounded; }
/// <summary> /// Figure out what possible segment combinations are before showing the window. /// </summary> protected override void OnShow() { options = new Dictionary<GeometryTutorLib.ConcreteAST.Segment, List<GeometryTutorLib.ConcreteAST.Segment>>(); //Get a list of all congruent segment givens List<GroundedClause> csegs = new List<GroundedClause>(); foreach (GroundedClause gc in currentGivens) { CongruentSegments cseg = gc as CongruentSegments; if (cseg != null) { csegs.Add(cseg); } } //Pick a first segment... foreach (GeometryTutorLib.ConcreteAST.Segment s1 in parser.backendParser.implied.segments) { List<GeometryTutorLib.ConcreteAST.Segment> possible = new List<GeometryTutorLib.ConcreteAST.Segment>(); //... and see what other segments are viable second options. foreach (GeometryTutorLib.ConcreteAST.Segment s2 in parser.backendParser.implied.segments) { if (s1.Length == s2.Length) { CongruentSegments cseg = new CongruentSegments(s1, s2); if (!s1.StructurallyEquals(s2) && !StructurallyContains(csegs, cseg)) { possible.Add(s2); } } } //If we found a possible list of combinations, add it to the dictionary if (possible.Count > 0) { options.Add(s1, possible); } } //Set the options of the segment1 combo box segment1.ItemsSource = null; //Graphical refresh segment1.ItemsSource = options.Keys; }
// // Checks for SSS given the 5 values // private static List<EdgeAggregator> InstantiateSSS(Triangle tri1, Triangle tri2, CongruentSegments css1, CongruentSegments css2, CongruentSegments css3) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // // All congruence pairs must minimally relate the triangles // if (!css1.LinksTriangles(tri1, tri2)) return newGrounded; if (!css2.LinksTriangles(tri1, tri2)) return newGrounded; if (!css3.LinksTriangles(tri1, tri2)) return newGrounded; Segment seg1Tri1 = tri1.GetSegment(css1); Segment seg1Tri2 = tri2.GetSegment(css1); Segment seg2Tri1 = tri1.GetSegment(css2); Segment seg2Tri2 = tri2.GetSegment(css2); Segment seg3Tri1 = tri1.GetSegment(css3); Segment seg3Tri2 = tri2.GetSegment(css3); // // The vertices of both triangles must all be distinct and cover the triangle completely. // Point vertex1Tri1 = seg1Tri1.SharedVertex(seg2Tri1); Point vertex2Tri1 = seg2Tri1.SharedVertex(seg3Tri1); Point vertex3Tri1 = seg1Tri1.SharedVertex(seg3Tri1); if (vertex1Tri1 == null || vertex2Tri1 == null || vertex3Tri1 == null) return newGrounded; if (vertex1Tri1.StructurallyEquals(vertex2Tri1) || vertex1Tri1.StructurallyEquals(vertex3Tri1) || vertex2Tri1.StructurallyEquals(vertex3Tri1)) return newGrounded; Point vertex1Tri2 = seg1Tri2.SharedVertex(seg2Tri2); Point vertex2Tri2 = seg2Tri2.SharedVertex(seg3Tri2); Point vertex3Tri2 = seg1Tri2.SharedVertex(seg3Tri2); if (vertex1Tri2 == null || vertex2Tri2 == null || vertex3Tri2 == null) return newGrounded; if (vertex1Tri2.StructurallyEquals(vertex2Tri2) || vertex1Tri2.StructurallyEquals(vertex3Tri2) || vertex2Tri2.StructurallyEquals(vertex3Tri2)) return newGrounded; // // Construct the corresponding points between the triangles // List<Point> triangleOne = new List<Point>(); List<Point> triangleTwo = new List<Point>(); triangleOne.Add(vertex1Tri1); triangleTwo.Add(vertex1Tri2); triangleOne.Add(vertex2Tri1); triangleTwo.Add(vertex2Tri2); triangleOne.Add(vertex3Tri1); triangleTwo.Add(vertex3Tri2); // // Construct the new clauses: congruent triangles and CPCTC // GeometricCongruentTriangles gcts = new GeometricCongruentTriangles(new Triangle(triangleOne), new Triangle(triangleTwo)); // Hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(tri1); antecedent.Add(tri2); antecedent.Add(css1); antecedent.Add(css2); antecedent.Add(css3); newGrounded.Add(new EdgeAggregator(antecedent, gcts, annotation)); // Add all the corresponding parts as new congruent clauses newGrounded.AddRange(CongruentTriangles.GenerateCPCTC(gcts, triangleOne, triangleTwo)); return newGrounded; }
// // DO NOT generate a new clause, instead, report the result and generate all applicable // clauses attributed to this strengthening of a triangle from scalene to isosceles // private static EdgeAggregator StrengthenToIsosceles(Triangle tri, CongruentSegments ccss) { Strengthened newStrengthened = new Strengthened(tri, new IsoscelesTriangle(tri)); List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(ccss); antecedent.Add(tri); return new EdgeAggregator(antecedent, newStrengthened, annotation); }
private static List<EdgeAggregator> InstantiateToTheorem(Quadrilateral quad, CongruentSegments cs1, CongruentSegments cs2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Are the pairs on the opposite side of this quadrilateral? if (!quad.HasOppositeCongruentSides(cs1)) return newGrounded; if (!quad.HasOppositeCongruentSides(cs2)) return newGrounded; // // Create the new Rhombus object // Strengthened newParallelogram = new Strengthened(quad, new Parallelogram(quad)); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(quad); antecedent.Add(cs1); antecedent.Add(cs2); newGrounded.Add(new EdgeAggregator(antecedent, newParallelogram, annotation)); return newGrounded; }