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);
        }
Beispiel #5
0
        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);
        }
Beispiel #9
0
        //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);
        }