//  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);
        }
示例#2
0
        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);
        }
示例#3
0
        //
        // 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);
        }
示例#4
0
        //
        // 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>());
        }
示例#6
0
        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);
        }
示例#7
0
        //     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);
        }
示例#8
0
        //
        // 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);
        }
示例#10
0
        //
        // 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);
        }
示例#11
0
        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);
        }
示例#12
0
        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());
        }
示例#13
0
        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);
        }
示例#16
0
        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);
        }
示例#17
0
        //         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);
        }
示例#18
0
        //
        // 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);
        }
示例#19
0
        //  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);
        }
示例#21
0
        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);
        }
示例#22
0
        //     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);
        }
示例#23
0
        //
        // 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);
        }
示例#25
0
        //  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);
        }
示例#26
0
        //     /        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);
        }
示例#27
0
        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);
        }
示例#30
0
        //  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);
        }
示例#31
0
        //
        // 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;
        }