// // 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; }
// // 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; }
// // 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; }
public static List <GenericInstantiator.EdgeAggregator> InstantiateProportion(GroundedClause clause) { List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>(); ProportionalAngles propAngs = clause as ProportionalAngles; if (propAngs == null) { return(newGrounded); } // Do not generate equations based on 'forced' proportions if (propAngs.proportion.Key == -1 || propAngs.proportion.Value == -1) { return(newGrounded); } // Create a product on the left hand side Multiplication productLHS = new Multiplication(new NumericValue(propAngs.proportion.Key), propAngs.smallerAngle.DeepCopy()); // Create a product on the right hand side, if it applies. GroundedClause rhs = propAngs.largerAngle.DeepCopy(); if (propAngs.proportion.Value > 1) { rhs = new Multiplication(new NumericValue(propAngs.proportion.Key), rhs); } // // Create the equation // Equation newEquation = null; if (propAngs is AlgebraicProportionalAngles) { newEquation = new AlgebraicAngleEquation(productLHS, rhs); } else if (propAngs is GeometricProportionalAngles) { newEquation = new GeometricAngleEquation(productLHS, rhs); } List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(propAngs); newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newEquation, defAnnotation)); 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 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; }
// // 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 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; }
public static List<GenericInstantiator.EdgeAggregator> InstantiateProportion(GroundedClause clause) { List<GenericInstantiator.EdgeAggregator> newGrounded = new List<GenericInstantiator.EdgeAggregator>(); ProportionalAngles propAngs = clause as ProportionalAngles; if (propAngs == null) return newGrounded; // Do not generate equations based on 'forced' proportions if (propAngs.proportion.Key == -1 || propAngs.proportion.Value == -1) return newGrounded; // Create a product on the left hand side Multiplication productLHS = new Multiplication(new NumericValue(propAngs.proportion.Key), propAngs.smallerAngle.DeepCopy()); // Create a product on the right hand side, if it applies. GroundedClause rhs = propAngs.largerAngle.DeepCopy(); if (propAngs.proportion.Value > 1) { rhs = new Multiplication(new NumericValue(propAngs.proportion.Key), rhs); } // // Create the equation // Equation newEquation = null; if (propAngs is AlgebraicProportionalAngles) { newEquation = new AlgebraicAngleEquation(productLHS, rhs); } else if (propAngs is GeometricProportionalAngles) { newEquation = new GeometricAngleEquation(productLHS, rhs); } List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(propAngs); newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newEquation, defAnnotation)); 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; }
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); }