// A __________ B // | | // | | // | | // D |__________| C // // Rhombus(A, B, C, D) -> AngleBisector(Angle(A, B, C), Segment(B, D)) // AngleBisector(Angle(A, D, C), Segment(B, D)) // AngleBisector(Angle(B, A, D), Segment(A, C)) // AngleBisector(Angle(B, C, D), Segment(A, C)) // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.DIAGONALS_OF_RHOMBUS_BISECT_ANGLES_OF_RHOMBUS; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Rhombus) { Rhombus rhombus = clause as Rhombus; newGrounded.AddRange(InstantiateToTheorem(rhombus, rhombus)); } else if (clause is Strengthened) { Strengthened streng = clause as Strengthened; if (!(streng.strengthened is Rhombus)) { return(newGrounded); } newGrounded.AddRange(InstantiateToTheorem(streng.strengthened as Rhombus, streng)); } return(newGrounded); }
private static List <EdgeAggregator> InstantiateFromSquare(Square square, GroundedClause original) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // // Determine the parallel opposing sides and output that. // List <Strengthened> newRightAngles = new List <Strengthened>(); foreach (Angle angle in square.angles) { Angle figureAngle = Angle.AcquireFigureAngle(angle); newRightAngles.Add(new Strengthened(figureAngle, new RightAngle(figureAngle))); } // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original); foreach (Strengthened rightAngle in newRightAngles) { newGrounded.Add(new EdgeAggregator(antecedent, rightAngle, annotation)); } return(newGrounded); }
// // Generate Proportional relationships only if those proportions may be used by a figure (in this case, only triangles) // // Triangle(A, B, C), Triangle(D, E, F), // // Congruent(Segment(A, B), Segment(B, C)), Congruent(Segment(D, E), Segment(E, F)) -> Similar(Triangle(A, B, C), Triangle(D, E, F)), // Proportional(Segment(A, B), Segment(D, E)), // Proportional(Segment(A, B), Segment(E, F)), // Proportional(Segment(B, C), Segment(D, E)), // Proportional(Segment(B, C), Segment(E, F)), // public static List <EdgeAggregator> Instantiate(GroundedClause c) { annotation.active = EngineUIBridge.JustificationSwitch.CONGRUENT_SEGMENTS_IMPLY_PROPORTIONAL_SEGMENTS_DEFINITION; // The list of new grounded clauses if they are deduced List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (!(c is Triangle) && !(c is CongruentSegments)) { return(newGrounded); } // If this is a new triangle, check for triangles which may be Similar to this new triangle if (c is Triangle) { Triangle candidateTri = c as Triangle; foreach (Triangle oldTriangle in candidateTriangles) { for (int m = 0; m < candidateCongruentSegments.Count - 1; m++) { for (int n = m + 1; n < candidateCongruentSegments.Count; n++) { newGrounded.AddRange(IfCongruencesApplyToTrianglesGenerate(candidateTri, oldTriangle, candidateCongruentSegments[m], candidateCongruentSegments[n])); } } } // Add this triangle to the list of possible clauses to unify later candidateTriangles.Add(candidateTri); } // // Two sets of congruent segments can lead to proportionality // else if (c is CongruentSegments) { CongruentSegments newCss = c as CongruentSegments; // Avoid reflexive relationships since they will not lead to interesting proportional relationships if (newCss.IsReflexive()) { return(newGrounded); } for (int i = 0; i < candidateTriangles.Count - 1; i++) { for (int j = i + 1; j < candidateTriangles.Count; j++) { foreach (CongruentSegments css in candidateCongruentSegments) { newGrounded.AddRange(IfCongruencesApplyToTrianglesGenerate(candidateTriangles[i], candidateTriangles[j], css, newCss)); } } } candidateCongruentSegments.Add(newCss); } return(newGrounded); }
// // Collinear(A, B, C, D, ...) -> Angle(A, B, C), Angle(A, B, D), Angle(A, C, D), Angle(B, C, D),... // All angles will have measure 180^o // There will be nC3 resulting clauses. // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.STRAIGHT_ANGLE_DEFINITION; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); Collinear cc = clause as Collinear; if (cc == null) { return(newGrounded); } for (int i = 0; i < cc.points.Count - 2; i++) { for (int j = i + 1; j < cc.points.Count - 1; j++) { for (int k = j + 1; k < cc.points.Count; k++) { Angle newAngle = new Angle(cc.points[i], cc.points[j], cc.points[k]); List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(cc); newGrounded.Add(new EdgeAggregator(antecedent, newAngle, annotation)); } } } return(newGrounded); }
public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.RIGHT_TRIANGLE_DEFINITION; // // Instantiating FROM a right triangle // Strengthened streng = clause as Strengthened; if (clause is RightTriangle) { return(InstantiateFromRightTriangle(clause as RightTriangle, clause)); } if (streng != null && streng.strengthened is RightTriangle) { return(InstantiateFromRightTriangle(streng.strengthened as RightTriangle, clause)); } // // Instantiating TO a right triangle // if (clause is RightAngle || clause is Strengthened || clause is Triangle) { return(InstantiateToRightTriangle(clause)); } return(new List <EdgeAggregator>()); }
public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.TWO_INTERCEPTED_ARCS_HAVE_CONGRUENT_ANGLES; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Angle) { Angle angle = clause as Angle; foreach (Angle candCongruentAngle in candidateAngles) { newGrounded.AddRange(InstantiateTheorem(angle, candCongruentAngle)); } candidateAngles.Add(angle); } else if (clause is Circle) { Circle circle = clause as Circle; for (int i = 0; i < candidateAngles.Count; ++i) { for (int j = i + 1; j < candidateAngles.Count; ++j) { newGrounded.AddRange(InstantiateTheorem(candidateAngles[i], candidateAngles[j])); } } } return(newGrounded); }
// A __________ B // / \ // / \ // / \ // D /________________\ C // // Trapezoid(A, B, C, D) -> Parallel(Segment(A, B), Segment(C, D)) // private static List <EdgeAggregator> InstantiateFromIsoscelesTrapezoid(GroundedClause clause) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is IsoscelesTrapezoid) { IsoscelesTrapezoid trapezoid = clause as IsoscelesTrapezoid; newGrounded.AddRange(InstantiateFromIsoscelesTrapezoid(trapezoid, trapezoid)); } else if (clause is Strengthened) { Strengthened streng = clause as Strengthened; // Only interested in strenghthened intersection -> perpendicular or -> perpendicular bisector if (!(streng.strengthened is IsoscelesTrapezoid)) { return(newGrounded); } newGrounded.AddRange(InstantiateFromIsoscelesTrapezoid(streng.strengthened as IsoscelesTrapezoid, streng)); } return(newGrounded); }
// // This implements forward and Backward instantiation // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.PERPENDICULAR_DEFINITION; // FROM Perpendicular if (clause is Perpendicular) { return(InstantiateFromPerpendicular(clause, clause as Perpendicular)); } // TO Perpendicular if (clause is RightAngle || clause is Intersection) { return(InstantiateToPerpendicular(clause)); } // Handle Strengthening; may be a Perpendicular (FROM) or Right Angle (TO) Strengthened streng = clause as Strengthened; if (streng != null) { if (streng.strengthened is Perpendicular && !(streng.strengthened is PerpendicularBisector)) { return(InstantiateFromPerpendicular(clause, streng.strengthened as Perpendicular)); } else if (streng.strengthened is RightAngle) { return(InstantiateToPerpendicular(clause)); } } return(new List <EdgeAggregator>()); }
// A _________________ B // / / // / / // / / // D /________________/ C // // Parallelogram(A, B, C, D) -> SegmentBisector(Segment(A, C), Segment(B, D)), SegmentBisector(Segment(B, D), Segment(A, C)), // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.DIAGONALS_PARALLELOGRAM_BISECT_EACH_OTHER; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Parallelogram) { Parallelogram newPara = clause as Parallelogram; newGrounded.AddRange(InstantiateTheorem(newPara, newPara)); } else if (clause is Strengthened) { Strengthened streng = clause as Strengthened; if (!(streng.strengthened is Parallelogram)) { return(newGrounded); } newGrounded.AddRange(InstantiateTheorem(streng.strengthened as Parallelogram, streng)); } return(newGrounded); }
// // AngleBisector(SegmentA, D), Angle(C, A, B)) -> 2 m\angle CAD = m \angle CAB, // 2 m\angle BAD = m \angle CAB // // A ________________________B // |\ // | \ // | \ // | \ // | \ // C D // public static List <EdgeAggregator> Instantiate(GroundedClause c) { annotation.active = EngineUIBridge.JustificationSwitch.ANGLE_BISECTOR_THEOREM; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (!(c is AngleBisector)) { return(newGrounded); } AngleBisector angleBisector = c as AngleBisector; KeyValuePair <Angle, Angle> adjacentAngles = angleBisector.GetBisectedAngles(); // Construct 2 m\angle CAD Multiplication product1 = new Multiplication(new NumericValue(2), adjacentAngles.Key); // Construct 2 m\angle BAD Multiplication product2 = new Multiplication(new NumericValue(2), adjacentAngles.Value); // 2X = AB GeometricAngleEquation newEq1 = new GeometricAngleEquation(product1, angleBisector.angle); GeometricAngleEquation newEq2 = new GeometricAngleEquation(product2, angleBisector.angle); // For hypergraph List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(angleBisector); newGrounded.Add(new EdgeAggregator(antecedent, newEq1, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, newEq2, annotation)); return(newGrounded); }
public static List <EdgeAggregator> InstantiateFromRightAngle(GroundedClause clause) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); RightAngle ra = null; if (clause is Strengthened) { ra = ((clause as Strengthened).strengthened) as RightAngle; } else if (clause is RightAngle) { ra = clause as RightAngle; } else { return(newGrounded); } // Strengthening may be something else if (ra == null) { return(newGrounded); } GeometricAngleEquation angEq = new GeometricAngleEquation(ra, new NumericValue(90)); List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(clause); newGrounded.Add(new EdgeAggregator(antecedent, angEq, defAnnotation)); return(newGrounded); }
private bool StronglyRelated(GroundedClause firstNode, GroundedClause secondNode) { if (firstNode is SegmentRatio && secondNode is SegmentRatio) { return(true); } if (firstNode is ProportionalAngles && secondNode is ProportionalAngles) { return(true); } if (firstNode is Congruent && secondNode is Congruent) { if (firstNode is CongruentAngles && secondNode is CongruentAngles) { return(true); } if (firstNode is CongruentSegments && secondNode is CongruentSegments) { return(true); } if (firstNode is CongruentTriangles && secondNode is CongruentTriangles) { return(true); } return(false); } if (firstNode is Equation && secondNode is Equation) { if (firstNode is AngleEquation && secondNode is AngleEquation) { return(true); } if (firstNode is SegmentEquation && secondNode is SegmentEquation) { return(true); } return(false); } // // We may strenghthen for many reasons (right triangle, isosceles triangle as well as perpendicular bisector) // Compare those strengthened values for a relationship // if (firstNode is Strengthened && secondNode is Strengthened) { Strengthened streng1 = firstNode as Strengthened; Strengthened streng2 = secondNode as Strengthened; return(StronglyRelated(streng1.strengthened, streng2.strengthened)); } //if (firstNode is Similar) //{ // return secondNode is Similar; //} return(firstNode.GetType() == secondNode.GetType()); }
public static void Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.RIGHT_TRIANGLE_DEFINITION; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // // Instantiating FROM a right triangle // Strengthened streng = clause as Strengthened; if (streng == null) { return; } if (streng.strengthened is RightTriangle) { candidateRight.Add(streng); foreach (Strengthened iso in candidateIsosceles) { InstantiateRightTriangle(streng, iso); } } else if (streng.strengthened is IsoscelesTriangle) { candidateIsosceles.Add(streng); foreach (Strengthened right in candidateRight) { InstantiateRightTriangle(right, streng); } } }
// // 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> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.TWO_INTERSECTING_CHORDS_ANGLE_MEASURE_HALF_SUM_INTERCEPTED_ARCS; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Intersection) { Intersection newInter = clause as Intersection; foreach (Circle circle in candidateCircle) { newGrounded.AddRange(InstantiateTheorem(newInter, circle)); } candidateIntersection.Add(newInter); } else if (clause is Circle) { Circle circle = clause as Circle; foreach (Intersection oldInter in candidateIntersection) { newGrounded.AddRange(InstantiateTheorem(oldInter, circle)); } candidateCircle.Add(circle); } return(newGrounded); }
private static List <EdgeAggregator> InstantiateToTheorem(Rhombus rhombus, GroundedClause original) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // For hypergraph List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(original); // Instantiate this rhombus diagonals ONLY if the original figure has the diagonals drawn. if (rhombus.TopLeftDiagonalIsValid()) { AngleBisector ab1 = new AngleBisector(rhombus.topLeftAngle, rhombus.topLeftBottomRightDiagonal); AngleBisector ab2 = new AngleBisector(rhombus.bottomRightAngle, rhombus.topLeftBottomRightDiagonal); newGrounded.Add(new EdgeAggregator(antecedent, ab1, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, ab2, annotation)); } if (rhombus.BottomRightDiagonalIsValid()) { AngleBisector ab1 = new AngleBisector(rhombus.topRightAngle, rhombus.bottomLeftTopRightDiagonal); AngleBisector ab2 = new AngleBisector(rhombus.bottomLeftAngle, rhombus.bottomLeftTopRightDiagonal); newGrounded.Add(new EdgeAggregator(antecedent, ab1, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, ab2, annotation)); } return(newGrounded); }
public static List <EdgeAggregator> Instantiate(GroundedClause c) { annotation.active = EngineUIBridge.JustificationSwitch.SEGMENT_ADDITION_AXIOM; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); InMiddle im = c as InMiddle; if (im == null) { return(newGrounded); } Segment s1 = new Segment(im.segment.Point1, im.point); Segment s2 = new Segment(im.point, im.segment.Point2); Addition sum = new Addition(s1, s2); GeometricSegmentEquation eq = new GeometricSegmentEquation(sum, im.segment); eq.MakeAxiomatic(); // For hypergraph List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(im); newGrounded.Add(new EdgeAggregator(antecedent, eq, annotation)); return(newGrounded); }
// B ____________________ C // / / // / / // / Circle (center) / // / O / // / / // A /___________________/ D // // Circle(O), Quad(A, B, C, D) -> Supplementary(Angle(ABC), Angle(ADC)), Supplementary(Angle(BAD), Angle(BCD)) // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.INSCRIBED_QUADRILATERAL_OPPOSITE_ANGLES_SUPPLEMENTARY; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); Circle circle = clause as Circle; if (circle == null) { return(newGrounded); } // // For each inscribed quadrilateral, generate accordingly. // foreach (Quadrilateral quad in circle.inscribedPolys[Polygon.QUADRILATERAL_INDEX]) { Supplementary supp1 = new Supplementary(quad.topLeftAngle, quad.bottomRightAngle); Supplementary supp2 = new Supplementary(quad.bottomLeftAngle, quad.topRightAngle); // For hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(circle); antecedent.Add(quad); newGrounded.Add(new EdgeAggregator(antecedent, supp1, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, supp2, annotation)); } return(newGrounded); }
// // 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 // | | // | | // | | // D |________________| C // // Rectangle(A, B, C, D) -> Congruent(Segment(A, C), Segment(B, D)) // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.DIAGONALS_OF_RECTANGLE_ARE_CONGRUENT; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Rectangle) { Rectangle rectangle = clause as Rectangle; newGrounded.AddRange(InstantiateToTheorem(rectangle, rectangle)); } else if (clause is Strengthened) { Strengthened streng = clause as Strengthened; if (!(streng.strengthened is Rectangle)) { return(newGrounded); } newGrounded.AddRange(InstantiateToTheorem(streng.strengthened as Rectangle, streng)); } return(newGrounded); }
// B ---------V---------A // \ // \ // \ // C // // Congruent(Segment(B, V), Segment(V, A)), Intersection(V, Segment(B, A), Segment(V, C)) -> SegmentBisector(Segment(V, C), Segment(B, A)) // public static List <EdgeAggregator> InstantiateToSegmentBisector(GroundedClause c) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (c is CongruentSegments) { CongruentSegments conSegs = c as CongruentSegments; // We are not interested in a reflexive relationship if (conSegs.IsReflexive()) { return(newGrounded); } // The congruent segments need to share an endpoint (adjacent congruent segments) Point shared = conSegs.cs1.SharedVertex(conSegs.cs2); if (shared == null) { return(newGrounded); } // The segments need to be collinear if (!conSegs.cs1.IsCollinearWith(conSegs.cs2)) { return(newGrounded); } // Match the congruences with the intersection foreach (Intersection inter in candidateIntersection) { newGrounded.AddRange(InstantiateToDef(shared, inter, conSegs)); } // Did not unify so add to the candidate list candidateCongruent.Add(conSegs); } else if (c is Intersection) { Intersection inter = c as Intersection; // / // / // /____ // If we have a corner situation, we are not interested if (inter.StandsOnEndpoint()) { return(newGrounded); } foreach (CongruentSegments cs in candidateCongruent) { newGrounded.AddRange(InstantiateToDef(cs.cs1.SharedVertex(cs.cs2), inter, cs)); } // Did not unify so add to the candidate list candidateIntersection.Add(inter); } return(newGrounded); }
private static List <EdgeAggregator> InstantiateToTrapezoid(GroundedClause clause) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Quadrilateral) { Quadrilateral quad = clause as Quadrilateral; if (!quad.IsStrictQuadrilateral()) { return(newGrounded); } foreach (Parallel parallel in candidateParallel) { newGrounded.AddRange(InstantiateToTrapezoid(quad, parallel)); } candidateQuadrilateral.Add(quad); } else if (clause is Parallel) { Parallel parallel = clause as Parallel; foreach (Quadrilateral quad in candidateQuadrilateral) { newGrounded.AddRange(InstantiateToTrapezoid(quad, parallel)); } candidateParallel.Add(parallel); } return(newGrounded); }
// B ---------V---------A // \ // \ // \ // C // // Median(Segment(V, C), Triangle(C, A, B)) -> Midpoint(V, Segment(B, A)) // private static List <EdgeAggregator> InstantiateFromMedian(GroundedClause clause) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is InMiddle && !(clause is Midpoint)) { InMiddle im = clause as InMiddle; foreach (Median median in candidateMedian) { newGrounded.AddRange(InstantiateFromMedian(im, median)); } candidateInMiddle.Add(im); } else if (clause is Median) { Median median = clause as Median; foreach (InMiddle im in candidateInMiddle) { newGrounded.AddRange(InstantiateFromMedian(im, median)); } candidateMedian.Add(median); } return(newGrounded); }
// // Angle(A, B, C), Angle(C, B, D) -> Angle(A, B, C) + Angle(C, B, D) = Angle(A, B, D) // public static List <EdgeAggregator> Instantiate(GroundedClause c) { annotation.active = EngineUIBridge.JustificationSwitch.ANGLE_ADDITION_AXIOM; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (!(c is Angle)) { return(newGrounded); } Angle newAngle = c as Angle; // // Determine if another angle in the candidate unify list can be combined with this new angle // foreach (Angle ang in unifyCandAngles) { newGrounded.AddRange(InstantiateAngles(newAngle, ang)); } // Add this angle to the unifying candidates unifyCandAngles.Add(newAngle); return(newGrounded); }
private static List <EdgeAggregator> InstantiateToDefinition(GroundedClause clause) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Triangle) { // Avoid strengthening an equilateral triangle to an equilateral triangle. if (clause is EquilateralTriangle || (clause as Triangle).provenEquilateral) { return(newGrounded); } candTriangles.Add(clause as Triangle); } else if (clause is CongruentSegments) { CongruentSegments cs = clause as CongruentSegments; foreach (Triangle tri in candTriangles) { for (int s1 = 0; s1 < candCongruent.Count - 1; s1++) { for (int s2 = s1 + 1; s2 < candCongruent.Count; s2++) { newGrounded.AddRange(InstantiateToDefinition(tri, candCongruent[s1], candCongruent[s2])); } } } candCongruent.Add(cs); } return(newGrounded); }
// A _______ B // / \ // Y /_________\ Z // / \ // D /_____________\ C // // Trapezoid(A, B, C, D), Median(Y, Z) -> Parallel(Segment(A, B), Segment(Y, Z)), Parallel(Segment(C, D), Segment(Y, Z)) // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.MEDIAN_TRAPEZOID_PARALLEL_TO_BASE; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Trapezoid) { Trapezoid trapezoid = clause as Trapezoid; newGrounded.AddRange(InstantiateToTheorem(trapezoid, trapezoid)); } else if (clause is Strengthened) { Strengthened streng = clause as Strengthened; if (!(streng.strengthened is Trapezoid)) { return(newGrounded); } newGrounded.AddRange(InstantiateToTheorem(streng.strengthened as Trapezoid, streng)); } return(newGrounded); }
// / A // / |) // / | ) // / | ) // Q------- O---X---) D // \ | ) // \ | ) // \ |) // \ C // // Inscribed Angle(AQC) -> Angle(AQC) = 2 * Arc(AC) // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.MEASURE_INSCRIBED_ANGLE_EQUAL_HALF_INTERCEPTED_ARC; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Angle) { Angle angle = clause as Angle; foreach (Circle circle in candidateCircles) { newGrounded.AddRange(InstantiateTheorem(circle, angle)); } candidateAngles.Add(angle); } else if (clause is Circle) { Circle circle = clause as Circle; foreach (Angle angle in candidateAngles) { newGrounded.AddRange(InstantiateTheorem(circle, angle)); } candidateCircles.Add(circle); } return(newGrounded); }
public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.CORRESPONDING_ANGLES_OF_PARALLEL_LINES; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Parallel) { Parallel parallel = clause as Parallel; for (int i = 0; i < candidateIntersection.Count; i++) { for (int j = i + 1; j < candidateIntersection.Count; j++) { newGrounded.AddRange(InstantiateIntersection(parallel, candidateIntersection[i], candidateIntersection[j])); } } candidateParallel.Add(parallel); } else if (clause is Intersection) { Intersection newInter = clause as Intersection; foreach (Intersection oldInter in candidateIntersection) { foreach (Parallel parallel in candidateParallel) { newGrounded.AddRange(InstantiateIntersection(parallel, newInter, oldInter)); } } candidateIntersection.Add(newInter); } return(newGrounded); }
// // Kite(A, B, C, D) -> Perpendicular(Intersection(Segment(A, C), Segment(B, D)) // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.DIAGONALS_OF_KITE_ARE_PERPENDICULAR; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Kite) { Kite kite = clause as Kite; newGrounded.AddRange(InstantiateToTheorem(kite, kite)); } else if (clause is Strengthened) { Strengthened streng = clause as Strengthened; if (!(streng.strengthened is Kite)) { return(newGrounded); } newGrounded.AddRange(InstantiateToTheorem(streng.strengthened as Kite, streng)); } return(newGrounded); }
// A _________________ B // / / // / / // / / // D /________________/ C // // Parallelogram(A, B, C, D) -> Congruent(Angle(DAB), Angle(BCD)), Congruent(Angle(ADC), Angle(ABC)) // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.OPPOSITE_ANGLES_PARALLELOGRAM_ARE_CONGRUENT; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is Parallelogram) { Parallelogram para = clause as Parallelogram; newGrounded.AddRange(InstantiateTheorem(para, para)); } else if (clause is Strengthened) { Strengthened streng = clause as Strengthened; if (!(streng.strengthened is Parallelogram)) { return(newGrounded); } newGrounded.AddRange(InstantiateTheorem(streng.strengthened as Parallelogram, streng)); } return(newGrounded); }
// A _______ B // / \ // / \ // / \ // D /_____________\ C // // IsoscelesTrapezoid(A, B, C, D) -> Congruent(Angle(A, D, C), Angle(B, C, D)), Congruent(Angle(D, A, B), Angle(C, B, A)) // public static List <EdgeAggregator> Instantiate(GroundedClause clause) { annotation.active = EngineUIBridge.JustificationSwitch.BASE_ANGLES_OF_ISOSCELES_TRAPEZOID_CONGRUENT; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (clause is IsoscelesTrapezoid) { IsoscelesTrapezoid trapezoid = clause as IsoscelesTrapezoid; newGrounded.AddRange(InstantiateToTheorem(trapezoid, trapezoid)); } else if (clause is Strengthened) { Strengthened streng = clause as Strengthened; if (!(streng.strengthened is IsoscelesTrapezoid)) { return(newGrounded); } newGrounded.AddRange(InstantiateToTheorem(streng.strengthened as IsoscelesTrapezoid, streng)); } return(newGrounded); }
// // Collinear(A, B, C, D, ...) -> Angle(A, B, C), Angle(A, B, D), Angle(A, C, D), Angle(B, C, D),... // All angles will have measure 180^o // There will be nC3 resulting clauses. // public static List<KeyValuePair<List<GroundedClause>, GroundedClause>> Instantiate(GroundedClause c) { if (!(c is Intersection)) return null; Intersection pCand = (Intersection)c; List<KeyValuePair<List<GroundedClause>, GroundedClause>> newGrounded = new List<KeyValuePair<List<GroundedClause>, GroundedClause>>(); if (pCand.isPerpendicular == true) { Perpendicular newPerpendicular = new Perpendicular(pCand.lhs,pCand.rhs, NAME); List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(pCand); newGrounded.Add(new KeyValuePair<List<GroundedClause>, GroundedClause>(antecedent, newPerpendicular)); } return newGrounded; }
// Parallel(Segment(A, B), Segment(C, D)) && Parallel(Segment(A, B), Segment(E, F) -> // Parallel(Segment(C, D), Segment(E, F) // public static List<KeyValuePair<List<GroundedClause>, GroundedClause>> Instantiate(GroundedClause c) { //Exit if c is not parallel if (!(c is Parallel)) return new List<KeyValuePair<List<GroundedClause>, GroundedClause>>(); List<Parallel> foundCand = new List<Parallel>(); //Variable holding parallel relations that will used for theorem // The list of new grounded clauses if they are deduced List<KeyValuePair<List<GroundedClause>, GroundedClause>> newGrounded = new List<KeyValuePair<List<GroundedClause>, GroundedClause>>(); if (c is Parallel) { Parallel newParallel = (Parallel)c; candParallel.Add((Parallel)c); //Create a list of all segments part of a parallel set grouped by what other segments they are parallel to var query1 = candParallel.GroupBy(m => m.segment1, m => m.segment2).Concat(candParallel.GroupBy(m => m.segment1, m => m.segment2)); //Iterate through the groups of parallel relations foreach (var group in query1) { foreach (ConcreteSegment segment in group) { //var query2 = candParallel.Where(m => m.segment1 == //Add two parallel sets leading to third parallel set //foundCand.Add() } } } if (foundCand.Count() >= 1) { antecedent.AddRange((IEnumerable<GroundedClause>)(foundCand)); //Add the two intersections to antecedent Parallel newParallel; //new Parallel() //newGrounded.Add(new KeyValuePair<List<GroundedClause>, GroundedClause>(antecedent, newParallel)); } return newGrounded; }
// public static List<KeyValuePair<List<GroundedClause>, GroundedClause>> Instantiate(GroundedClause c) { //Exit if c is neither a parallel set nor an intersection if (!(c is Parallel) && !(c is Intersection)) return new List<KeyValuePair<List<GroundedClause>, GroundedClause>>(); List<Intersection> foundCand = new List<Intersection>(); //Variable holding intersections that will used for theorem // The list of new grounded clauses if they are deduced List<KeyValuePair<List<GroundedClause>, GroundedClause>> newGrounded = new List<KeyValuePair<List<GroundedClause>, GroundedClause>>(); if (c is Parallel) { Parallel newParallel = (Parallel)c; candParallel.Add((Parallel)c); //Create a list of all segments in the intersection list by individual segment and list of intersecting segments var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs)); //Iterate through all segments intersected by each key segment foreach (var group in query1) { if (group.Contains(newParallel.segment1) && group.Contains(newParallel.segment2)) { //If a segment that intersected both parallel lines was found, find the intersection objects. var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key))); var query3 = query2.Where(m => m.lhs.Equals(newParallel.segment1) || m.lhs.Equals(newParallel.segment2) || m.rhs.Equals(newParallel.segment1) || m.rhs.Equals(newParallel.segment2)); if (query3.Any(m => m.isPerpendicular == true) && query3.Any(m => m.isPerpendicular == false)) { //if there exists both an intersection that is labeled perpendicular and an intersection that is not labeled perpendicular foundCand.AddRange(query3); } antecedent = Utilities.MakeList<GroundedClause>(newParallel); //Add parallel set to antecedents } } } else if (c is Intersection) { candIntersection.Add((Intersection)c); Intersection newintersect = (Intersection)c; var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs)); foreach (Parallel p in candParallel) { foreach (var group in query1) { if (group.Contains(p.segment1) && group.Contains(p.segment2)) { //list intersections involving intersecting segement and two paralell segments var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key))); var query3 = query2.Where(m => m.lhs.Equals(p.segment1) || m.lhs.Equals(p.segment2) || m.rhs.Equals(p.segment1) || m.rhs.Equals(p.segment2)); if (query3.Any(m => m.isPerpendicular == true) && query3.Any(m => m.isPerpendicular == false)) { //if there exists both an intersection that is labeled perpendicular and an intersection that is not labeled perpendicular foundCand.AddRange(query3); } antecedent = Utilities.MakeList<GroundedClause>(p); } } } } //TODO: Make sure there will only be one set of intersections found at a time if (foundCand.Count() > 1) { antecedent.AddRange((IEnumerable<GroundedClause>)(foundCand)); //Add the two intersections to antecedent int index; index = (foundCand[0].isPerpendicular == false) ? 0 : 1; foundCand[index].setPerpendicular(true); Perpendicular newPerpendicular = new Perpendicular(foundCand[index].lhs,foundCand[index].rhs, NAME); //Add the new perpendicular set newGrounded.Add(new KeyValuePair<List<GroundedClause>, GroundedClause>(antecedent, newPerpendicular)); } return newGrounded; }
//TODO: this currently describes something else // Intersect(X, Segment(A, B), Segment(C, D)) -> Congruent(Angle(A, X, C), Angle(B, X, D)), // Congruent(Angle(A, X, D), Angle(C, X, B)) // public static List<KeyValuePair<List<GroundedClause>, GroundedClause>> Instantiate(GroundedClause c) { //Exit if c is neither a parallel set nor an intersection if (!(c is Parallel) && !(c is Intersection)) return new List<KeyValuePair<List<GroundedClause>, GroundedClause>>(); List<Intersection> foundCand = new List<Intersection>(); //Variable holding intersections that will used for theorem Parallel foundParallelSet = null; ConcreteSegment foundTransversal; // The list of new grounded clauses if they are deduced List<KeyValuePair<List<GroundedClause>, GroundedClause>> newGrounded = new List<KeyValuePair<List<GroundedClause>, GroundedClause>>(); if (c is Parallel) { Parallel newParallel = (Parallel)c; candParallel.Add((Parallel)c); //Create a list of all segments in the intersection list by individual segment and list of intersecting segments var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs)); //Iterate through all segments intersected by each key segment foreach (var group in query1) { if (group.Contains(newParallel.segment1) && group.Contains(newParallel.segment2)) { //If a segment that intersected both parallel lines was found, find the intersection objects. var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key))); var query3 = candIntersection.Where(m => m.lhs.Equals(newParallel.segment1) || m.lhs.Equals(newParallel.segment2) || m.rhs.Equals(newParallel.segment1) || m.rhs.Equals(newParallel.segment2)); foundCand.AddRange(query3); foundParallelSet = newParallel; foundTransversal = group.Key; antecedent = Utilities.MakeList<GroundedClause>(newParallel); //Add parallel set to antecedents } } } else if (c is Intersection) { candIntersection.Add((Intersection)c); Intersection newintersect = (Intersection)c; var query1 = candIntersection.GroupBy(m => m.lhs, m => m.rhs).Concat(candIntersection.GroupBy(m => m.rhs, m => m.lhs)); foreach (Parallel p in candParallel) { foreach (var group in query1) { if (group.Contains(p.segment1) && group.Contains(p.segment2)) { var query2 = candIntersection.Where(m => m.lhs.Equals(group.Key)).Concat(candIntersection.Where(m => m.rhs.Equals(group.Key))); var query3 = candIntersection.Where(m => m.lhs.Equals(p.segment1) || m.lhs.Equals(p.segment2) || m.rhs.Equals(p.segment1) || m.rhs.Equals(p.segment2)); foundCand.AddRange(query3); foundParallelSet = p; foundTransversal = group.Key; antecedent = Utilities.MakeList<GroundedClause>(p); } } } } if (foundCand.Count() > 1) { antecedent.AddRange((IEnumerable<GroundedClause>)(foundCand)); //Add the two intersections to antecedent ConcreteSupplementaryAngles cca1; ConcreteSupplementaryAngles cca2; int seg1index; int seg2index; //Match first and second intersection points with first and second segments if (foundCand[0].lhs == foundParallelSet.segment1 || foundCand[0].rhs == foundParallelSet.segment1) { seg1index = 0; seg2index = 1; } else { seg1index = 1; seg2index = 0; } ConcreteAngle ang1Seg1 = new ConcreteAngle(foundParallelSet.segment1.Point1, foundCand[seg1index].intersect, foundCand[seg2index].intersect); ConcreteAngle ang2Seg1 = new ConcreteAngle(foundParallelSet.segment1.Point2, foundCand[seg1index].intersect, foundCand[seg2index].intersect); ConcreteAngle ang1Seg2 = new ConcreteAngle(foundParallelSet.segment2.Point1, foundCand[seg2index].intersect, foundCand[seg1index].intersect); ConcreteAngle ang2Seg2 = new ConcreteAngle(foundParallelSet.segment2.Point2, foundCand[seg2index].intersect, foundCand[seg1index].intersect); /* ConcreteAngle ang1Set1 = new ConcreteAngle(foundCand[0].lhs.Point1, foundCand[0].intersect, foundCand[0].rhs.Point1); ConcreteAngle ang2Set1 = new ConcreteAngle(foundCand[0].lhs.Point2, foundCand[0].intersect, foundCand[0].rhs.Point1); ConcreteAngle ang1Set2 = new ConcreteAngle(foundCand[1].lhs.Point1, foundCand[1].intersect, foundCand[1].rhs.Point1); ConcreteAngle ang2Set2 = new ConcreteAngle(foundCand[1].lhs.Point2, foundCand[1].intersect, foundCand[1].rhs.Point1); */ //Supplementary angles will be the matching angles on different segments //TODO: Make sure they're on the same side if (ang1Seg1.measure == ang1Seg2.measure) { cca1 = new ConcreteSupplementaryAngles(ang1Seg1, ang2Seg2, NAME); cca2 = new ConcreteSupplementaryAngles(ang1Seg2, ang2Seg1, NAME); } else { cca1 = new ConcreteSupplementaryAngles(ang1Seg1, ang1Seg2, NAME); cca2 = new ConcreteSupplementaryAngles(ang2Seg1, ang2Seg2, NAME); } //Add the two new supplementary angle sets newGrounded.Add(new KeyValuePair<List<GroundedClause>, GroundedClause>(antecedent, cca1)); newGrounded.Add(new KeyValuePair<List<GroundedClause>, GroundedClause>(antecedent, cca2)); } return newGrounded; }