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); }
// // 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); }
private static EdgeAggregator ConstructExteriorRelationship(Triangle tri, Angle extAngle) { // // Acquire the remote angles // Angle remote1 = null; Angle remote2 = null; tri.AcquireRemoteAngles(extAngle.GetVertex(), out remote1, out remote2); // // Construct the new equation // Addition sum = new Addition(remote1, remote2); GeometricAngleEquation eq = new GeometricAngleEquation(extAngle, sum); // // For the hypergraph // List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(tri); antecedent.Add(extAngle); return(new EdgeAggregator(antecedent, eq, annotation)); }
// // 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); }
private static List <EdgeAggregator> InstantiateAngles(Angle angle1, Angle angle2) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // An angle may have multiple names if (angle1.Equates(angle2)) { return(newGrounded); } if (!angle1.GetVertex().Equals(angle2.GetVertex())) { return(newGrounded); } // Determine the shared segment if we have an adjacent situation Segment shared = angle1.IsAdjacentTo(angle2); if (shared == null) { return(newGrounded); } // // If we combine these two angles, the result is a third angle, which, when measured, // would be less than 180; this is contradictory since we measuare angles greedily and no circular angle is measured as > 180 // if (angle1.measure + angle2.measure > 180) { return(newGrounded); } // Angle(A, B, C), Angle(C, B, D) -> Angle(A, B, C) + Angle(C, B, D) = Angle(A, B, D) Point vertex = angle1.GetVertex(); Point exteriorPt1 = angle2.OtherPoint(shared); Point exteriorPt2 = angle1.OtherPoint(shared); Angle newAngle = new Angle(exteriorPt1, vertex, exteriorPt2); Addition sum = new Addition(angle1, angle2); GeometricAngleEquation geoAngEq = new GeometricAngleEquation(sum, newAngle); geoAngEq.MakeAxiomatic(); // This is an axiomatic equation // For hypergraph construction List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(angle1); antecedent.Add(angle2); newGrounded.Add(new EdgeAggregator(antecedent, geoAngEq, annotation)); return(newGrounded); }
// // Complementary(Angle(A, B, C), Angle(D, E, F)) -> Angle(A, B, C) + Angle(D, E, F) = 90 // public static List <EdgeAggregator> InstantiateFromComplementary(Complementary comp) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(comp); GeometricAngleEquation angEq = new GeometricAngleEquation(new Addition(comp.angle1, comp.angle2), new NumericValue(90)); newGrounded.Add(new EdgeAggregator(antecedent, angEq, annotation)); return(newGrounded); }
// // Generate the three pairs of congruent segments. // private static List <EdgeAggregator> InstantiateFromDefinition(EquilateralTriangle tri, GroundedClause original) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // Hypergraph List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(original); // // Create the 3 sets of congruent segments. // for (int s = 0; s < tri.orderedSides.Count; s++) { GeometricCongruentSegments gcs = new GeometricCongruentSegments(tri.orderedSides[s], tri.orderedSides[(s + 1) % tri.orderedSides.Count]); newGrounded.Add(new EdgeAggregator(antecedent, gcs, annotation)); } // // Create the 3 congruent angles. // for (int a = 0; a < tri.angles.Count; a++) { GeometricCongruentAngles gcas = new GeometricCongruentAngles(tri.angles[a], tri.angles[(a + 1) % tri.angles.Count]); newGrounded.Add(new EdgeAggregator(antecedent, gcas, annotation)); } // // Create the 3 equations for the measure of each angle being 60 degrees. // for (int a = 0; a < tri.angles.Count; a++) { GeometricAngleEquation gae = new GeometricAngleEquation(tri.angles[a], new NumericValue(60)); newGrounded.Add(new EdgeAggregator(antecedent, gae, annotation)); } return(newGrounded); }
// // EquilateralTriangle(A, B, C) -> Equation(m \angle ABC = 60), // Equation(m \angle BCA = 60), // Equation(m \angle CAB = 60) // public static List <EdgeAggregator> Instantiate(GroundedClause c) { annotation.active = EngineUIBridge.JustificationSwitch.EQUILATERAL_TRIANGLE_HAS_SIXTY_DEGREE_ANGLES; List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); if (!(c is EquilateralTriangle) && !(c is Strengthened)) { return(newGrounded); } EquilateralTriangle eqTri = c as EquilateralTriangle; if (c is Strengthened) { eqTri = (c as Strengthened).strengthened as EquilateralTriangle; } if (eqTri == null) { return(newGrounded); } // EquilateralTriangle(A, B, C) -> List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(c); // -> Equation(m \angle ABC = 60), // Equation(m \angle BCA = 60), // Equation(m \angle CAB = 60) GeometricAngleEquation eq1 = new GeometricAngleEquation(eqTri.AngleA, new NumericValue(60)); GeometricAngleEquation eq2 = new GeometricAngleEquation(eqTri.AngleB, new NumericValue(60)); GeometricAngleEquation eq3 = new GeometricAngleEquation(eqTri.AngleC, new NumericValue(60)); newGrounded.Add(new EdgeAggregator(antecedent, eq1, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, eq2, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, eq3, 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); }