Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
        private static List <EdgeAggregator> InstantiateToDefinition(CongruentSegments css)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            //
            // Find all the circles for which the two segments are radii.
            //
            List <Circle> circlesCSS1 = Circle.GetFigureCirclesByRadius(css.cs1);
            List <Circle> circlesCSS2 = Circle.GetFigureCirclesByRadius(css.cs2);

            //
            // Since the radii are congruent, the circles are therefore congruent.
            //
            foreach (Circle cc1 in circlesCSS1)
            {
                foreach (Circle cc2 in circlesCSS2)
                {
                    // Avoid generating refexive relationships(?)
                    if (!cc1.StructurallyEquals(cc2))
                    {
                        // For hypergraph
                        List <GroundedClause> antecedent = new List <GroundedClause>();
                        antecedent.Add(css);
                        antecedent.Add(cc1);
                        antecedent.Add(cc2);

                        GeometricCongruentCircles gccs = new GeometricCongruentCircles(cc1, cc2);
                        newGrounded.Add(new EdgeAggregator(antecedent, gccs, annotation));
                    }
                }
            }

            return(newGrounded);
        }
Exemplo n.º 3
0
        //
        // Congruent(Segment(A, M), Segment(M, B)) -> Midpoint(M, Segment(A, B))
        //
        private static List <EdgeAggregator> InstantiateToMidpoint(InMiddle im, CongruentSegments css)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            Point midpoint = css.cs1.SharedVertex(css.cs2);

            // Does this InMiddle relate to the congruent segments?
            if (!im.point.StructurallyEquals(midpoint))
            {
                return(newGrounded);
            }

            // Do the congruent segments combine into a single segment equating to the InMiddle?
            Segment overallSegment = new Segment(css.cs1.OtherPoint(midpoint), css.cs2.OtherPoint(midpoint));

            if (!im.segment.StructurallyEquals(overallSegment))
            {
                return(newGrounded);
            }

            Strengthened newMidpoint = new Strengthened(im, new Midpoint(im));

            // For hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(im);
            antecedent.Add(css);

            newGrounded.Add(new EdgeAggregator(antecedent, newMidpoint, annotation));

            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);
        }
        //     B ---------V---------A
        //                 \
        //                  \
        //                   \
        //                    C
        //
        // Congruent(Segment(B, V), Segment(V, A)), Intersection(V, Segment(B, A), Segment(V, C)) -> SegmentBisector(Segment(V, C), Segment(B, A))
        //
        public static List <EdgeAggregator> InstantiateToSegmentBisector(GroundedClause c)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (c is CongruentSegments)
            {
                CongruentSegments conSegs = c as CongruentSegments;

                // We are not interested in a reflexive relationship
                if (conSegs.IsReflexive())
                {
                    return(newGrounded);
                }

                // The congruent segments need to share an endpoint (adjacent congruent segments)
                Point shared = conSegs.cs1.SharedVertex(conSegs.cs2);
                if (shared == null)
                {
                    return(newGrounded);
                }

                // The segments need to be collinear
                if (!conSegs.cs1.IsCollinearWith(conSegs.cs2))
                {
                    return(newGrounded);
                }

                // Match the congruences with the intersection
                foreach (Intersection inter in candidateIntersection)
                {
                    newGrounded.AddRange(InstantiateToDef(shared, inter, conSegs));
                }

                // Did not unify so add to the candidate list
                candidateCongruent.Add(conSegs);
            }
            else if (c is Intersection)
            {
                Intersection inter = c as Intersection;

                //    /
                //   /
                //  /____
                // If we have a corner situation, we are not interested
                if (inter.StandsOnEndpoint())
                {
                    return(newGrounded);
                }

                foreach (CongruentSegments cs in candidateCongruent)
                {
                    newGrounded.AddRange(InstantiateToDef(cs.cs1.SharedVertex(cs.cs2), inter, cs));
                }

                // Did not unify so add to the candidate list
                candidateIntersection.Add(inter);
            }

            return(newGrounded);
        }
        private static List <EdgeAggregator> InstantiateToRhombus(GroundedClause clause)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is Quadrilateral)
            {
                Quadrilateral quad = clause as Quadrilateral;

                if (!quad.IsStrictQuadrilateral())
                {
                    return(newGrounded);
                }

                foreach (CongruentSegments oldCs in candidateCongruent)
                {
                    foreach (Parallel parallel in candidateParallel)
                    {
                        newGrounded.AddRange(InstantiateToTheorem(quad, oldCs, parallel));
                    }
                }

                candidateQuadrilateral.Add(quad);
            }
            else if (clause is CongruentSegments)
            {
                CongruentSegments newCs = clause as CongruentSegments;

                if (newCs.IsReflexive())
                {
                    return(newGrounded);
                }

                foreach (Quadrilateral quad in candidateQuadrilateral)
                {
                    foreach (Parallel parallel in candidateParallel)
                    {
                        newGrounded.AddRange(InstantiateToTheorem(quad, newCs, parallel));
                    }
                }

                candidateCongruent.Add(newCs);
            }
            else if (clause is Parallel)
            {
                Parallel newParallel = clause as Parallel;

                foreach (Quadrilateral quad in candidateQuadrilateral)
                {
                    foreach (CongruentSegments oldCs in candidateCongruent)
                    {
                        newGrounded.AddRange(InstantiateToTheorem(quad, oldCs, newParallel));
                    }
                }

                candidateParallel.Add(newParallel);
            }

            return(newGrounded);
        }
        private static List <EdgeAggregator> InstantiateToDefinition(Triangle tri, CongruentSegments cs1, CongruentSegments cs2)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // Do these congruences relate one common segment?
            Segment shared = cs1.SharedSegment(cs2);

            if (shared == null)
            {
                return(newGrounded);
            }

            //
            // Do these congruences apply to this triangle?
            //
            if (!tri.HasSegment(cs1.cs1) || !tri.HasSegment(cs1.cs2))
            {
                return(newGrounded);
            }
            if (!tri.HasSegment(cs2.cs1) || !tri.HasSegment(cs2.cs2))
            {
                return(newGrounded);
            }

            //
            // These cannot be reflexive congruences.
            //
            if (cs1.IsReflexive() || cs2.IsReflexive())
            {
                return(newGrounded);
            }

            //
            // Are the non-shared segments unique?
            //
            Segment other1 = cs1.OtherSegment(shared);
            Segment other2 = cs2.OtherSegment(shared);

            if (other1.StructurallyEquals(other2))
            {
                return(newGrounded);
            }

            //
            // Generate the new equialteral clause
            //
            Strengthened newStrengthened = new Strengthened(tri, new EquilateralTriangle(tri));

            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(cs1);
            antecedent.Add(cs2);
            antecedent.Add(tri);

            newGrounded.Add(new EdgeAggregator(antecedent, newStrengthened, annotation));

            return(newGrounded);
        }
Exemplo n.º 8
0
        //      A             D
        //      /\           / \
        //     /  \         /   \
        //    /    \       /     \
        //   /______\     /_______\
        //  B        C   E         F
        //
        // In order for two triangles to be congruent, we require the following:
        //    Triangle(A, B, C), Triangle(D, E, F),
        //    Congruent(Segment(A, B), Segment(D, E)),
        //    Congruent(Segment(A, C), Angle(D, F)),
        //    Congruent(Segment(B, C), Segment(E, F)) -> Congruent(Triangle(A, B, C), Triangle(D, E, F)),
        //                                               Congruent(Angle(A, B, C), Angle(D, E, F)),
        //                                               Congruent(Angle(C, A, B), Angle(F, D, E)),
        //                                               Congruent(Angle(B, C, A), Angle(E, F, D)),
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.SSS;

            // The list of new grounded clauses if they are deduced
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is CongruentSegments)
            {
                CongruentSegments newCss = clause as CongruentSegments;

                // Check all combinations of triangles to see if they are congruent
                // This congruence must include the new segment congruence
                for (int i = 0; i < candidateTriangles.Count - 1; i++)
                {
                    for (int j = i + 1; j < candidateTriangles.Count; j++)
                    {
                        for (int m = 0; m < candidateSegments.Count - 1; m++)
                        {
                            for (int n = m + 1; n < candidateSegments.Count; n++)
                            {
                                newGrounded.AddRange(InstantiateSSS(candidateTriangles[i], candidateTriangles[j], candidateSegments[m], candidateSegments[n], newCss));
                            }
                        }
                    }
                }

                // Add this segment to the list of possible clauses to unify later
                candidateSegments.Add(newCss);
            }
            // If this is a new triangle, check for triangles which may be congruent to this new triangle
            else if (clause is Triangle)
            {
                Triangle newTriangle = clause as Triangle;

                // Check all combinations of triangles to see if they are congruent
                // This congruence must include the new segment congruence
                foreach (Triangle oldTri in candidateTriangles)
                {
                    for (int m = 0; m < candidateSegments.Count - 1; m++)
                    {
                        for (int n = m + 1; n < candidateSegments.Count - 1; n++)
                        {
                            for (int p = n + 1; p < candidateSegments.Count - 2; p++)
                            {
                                newGrounded.AddRange(InstantiateSSS(newTriangle, oldTri, candidateSegments[m], candidateSegments[n], candidateSegments[p]));
                            }
                        }
                    }
                }

                candidateTriangles.Add(newTriangle);
            }

            return(newGrounded);
        }
Exemplo n.º 9
0
        //
        // DO NOT generate a new clause, instead, report the result and generate all applicable
        // clauses attributed to this strengthening of a triangle from scalene to isosceles
        //
        private static EdgeAggregator StrengthenToIsosceles(Triangle tri, CongruentSegments ccss)
        {
            Strengthened newStrengthened = new Strengthened(tri, new IsoscelesTriangle(tri));

            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(ccss);
            antecedent.Add(tri);

            return(new EdgeAggregator(antecedent, newStrengthened, annotation));
        }
Exemplo n.º 10
0
        private static List <EdgeAggregator> InstantiateToRhombus(GroundedClause clause)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is Quadrilateral)
            {
                Quadrilateral quad = clause as Quadrilateral;

                if (!quad.IsStrictQuadrilateral())
                {
                    return(newGrounded);
                }

                for (int i = 0; i < candidateCongruent.Count - 1; i++)
                {
                    for (int j = i + 1; j < candidateCongruent.Count; j++)
                    {
                        for (int k = j + 1; k < candidateCongruent.Count; k++)
                        {
                            newGrounded.AddRange(InstantiateToRhombus(quad, candidateCongruent[i], candidateCongruent[j], candidateCongruent[k]));
                        }
                    }
                }

                candidateQuadrilateral.Add(quad);
            }
            else if (clause is CongruentSegments)
            {
                CongruentSegments newCs = clause as CongruentSegments;

                if (newCs.IsReflexive())
                {
                    return(newGrounded);
                }

                foreach (Quadrilateral quad in candidateQuadrilateral)
                {
                    for (int i = 0; i < candidateCongruent.Count - 1; i++)
                    {
                        for (int j = i + 1; j < candidateCongruent.Count; j++)
                        {
                            newGrounded.AddRange(InstantiateToRhombus(quad, newCs, candidateCongruent[i], candidateCongruent[j]));
                        }
                    }
                }

                candidateCongruent.Add(newCs);
            }

            return(newGrounded);
        }
Exemplo n.º 11
0
        private static List <EdgeAggregator> InstantiateToMidpoint(GroundedClause clause)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is InMiddle && !(clause is Midpoint))
            {
                InMiddle inMid = clause as InMiddle;

                foreach (CongruentSegments css in candidateCongruent)
                {
                    newGrounded.AddRange(InstantiateToMidpoint(inMid, css));
                }

                // No need to add this InMiddle object to the list since it was added previously in InstantiateFrom
            }
            else if (clause is CongruentSegments)
            {
                CongruentSegments css = clause as CongruentSegments;

                // A reflexive relationship cannot possibly create a midpoint situation
                if (css.IsReflexive())
                {
                    return(newGrounded);
                }

                // The congruence must relate two collinear segments...
                if (!css.cs1.IsCollinearWith(css.cs2))
                {
                    return(newGrounded);
                }

                // ...that share a vertex
                if (css.cs1.SharedVertex(css.cs2) == null)
                {
                    return(newGrounded);
                }

                foreach (InMiddle im in candidateInMiddle)
                {
                    newGrounded.AddRange(InstantiateToMidpoint(im, css));
                }

                candidateCongruent.Add(css);
            }

            return(newGrounded);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Figure out what possible segment combinations are before showing the window.
        /// </summary>
        protected override void OnShow()
        {
            options = new Dictionary <GeometryTutorLib.ConcreteAST.Segment, List <GeometryTutorLib.ConcreteAST.Segment> >();

            //Get a list of all congruent segment givens
            List <GroundedClause> csegs = new List <GroundedClause>();

            foreach (GroundedClause gc in currentGivens)
            {
                CongruentSegments cseg = gc as CongruentSegments;
                if (cseg != null)
                {
                    csegs.Add(cseg);
                }
            }

            //Pick a first segment...
            foreach (GeometryTutorLib.ConcreteAST.Segment s1 in parser.backendParser.implied.segments)
            {
                List <GeometryTutorLib.ConcreteAST.Segment> possible = new List <GeometryTutorLib.ConcreteAST.Segment>();

                //... and see what other segments are viable second options.
                foreach (GeometryTutorLib.ConcreteAST.Segment s2 in parser.backendParser.implied.segments)
                {
                    if (s1.Length == s2.Length)
                    {
                        CongruentSegments cseg = new CongruentSegments(s1, s2);

                        if (!s1.StructurallyEquals(s2) && !StructurallyContains(csegs, cseg))
                        {
                            possible.Add(s2);
                        }
                    }
                }

                //If we found a possible list of combinations, add it to the dictionary
                if (possible.Count > 0)
                {
                    options.Add(s1, possible);
                }
            }

            //Set the options of the segment1 combo box
            segment1.ItemsSource = null; //Graphical refresh
            segment1.ItemsSource = options.Keys;
        }
Exemplo n.º 13
0
        private static List <EdgeAggregator> InstantiateToKite(Quadrilateral quad, CongruentSegments cs1, CongruentSegments cs2)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // The congruences should not share a side.
            if (cs1.SharedSegment(cs2) != null)
            {
                return(newGrounded);
            }

            // The congruent pairs should not also be congruent to each other
            if (cs1.cs1.CoordinateCongruent(cs2.cs1))
            {
                return(newGrounded);
            }

            // Does both set of congruent segments apply to the quadrilateral?
            if (!quad.HasAdjacentCongruentSides(cs1))
            {
                return(newGrounded);
            }
            if (!quad.HasAdjacentCongruentSides(cs2))
            {
                return(newGrounded);
            }

            //
            // Create the new Kite object
            //
            Strengthened newKite = new Strengthened(quad, new Kite(quad));

            // For hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(quad);
            antecedent.Add(cs1);
            antecedent.Add(cs2);

            newGrounded.Add(new EdgeAggregator(antecedent, newKite, annotation));

            return(newGrounded);
        }
        //
        //       A
        //      / \
        //     B---C
        //
        // Triangle(A, B, C), Congruent(Segment(A, B), Segment(A, C)) -> Congruent(\angle ABC, \angle ACB)
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.CONGRUENT_SIDES_IN_TRIANGLE_IMPLY_CONGRUENT_ANGLES;

            // The list of new grounded clauses if they are deduced
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is CongruentSegments)
            {
                CongruentSegments css = clause as CongruentSegments;

                // Only generate or add to possible congruent pairs if this is a non-reflexive relation
                if (css.IsReflexive())
                {
                    return(newGrounded);
                }

                for (int t = 0; t < candTris.Count; t++)
                {
                    newGrounded.AddRange(InstantiateToCongruence(candTris[t], css));
                }

                candSegs.Add(css);
            }
            else if (clause is Triangle)
            {
                Triangle newTriangle = clause as Triangle;

                //
                // Do any of the congruent segment pairs merit calling this new triangle isosceles?
                //
                foreach (CongruentSegments css in candSegs)
                {
                    newGrounded.AddRange(InstantiateToCongruence(newTriangle, css));
                }

                // Add the the list of candidates if it was not determined isosceles now.
                candTris.Add(newTriangle);
            }

            return(newGrounded);
        }
        //
        // Just generate the new angle congruence
        //
        private static List <EdgeAggregator> InstantiateToCongruence(Triangle tri, CongruentSegments css)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (!tri.HasSegment(css.cs1) || !tri.HasSegment(css.cs2))
            {
                return(newGrounded);
            }

            GeometricCongruentAngles newConAngs = new GeometricCongruentAngles(tri.GetOppositeAngle(css.cs1), tri.GetOppositeAngle(css.cs2));

            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(css);
            antecedent.Add(tri);

            newGrounded.Add(new EdgeAggregator(antecedent, newConAngs, annotation));

            return(newGrounded);
        }
Exemplo n.º 16
0
 private static List <EdgeAggregator> ReconfigureAndCheck(Strengthened streng1, Strengthened streng2, CongruentSegments css1, CongruentSegments css2)
 {
     return(CollectAndCheckHL(streng1.strengthened as RightTriangle, streng2.strengthened as RightTriangle, css1, css2, streng1, streng2));
 }
Exemplo n.º 17
0
 //
 // Acquires all of the applicable congruent segments; then checks HL
 //
 private static List <EdgeAggregator> ReconfigureAndCheck(RightTriangle rt1, RightTriangle rt2, CongruentSegments css1, CongruentSegments css2)
 {
     return(CollectAndCheckHL(rt1, rt2, css1, css2, rt1, rt2));
 }
Exemplo n.º 18
0
        //
        // Checks for SSS given the 5 values
        //
        private static List <EdgeAggregator> InstantiateSSS(Triangle tri1, Triangle tri2, CongruentSegments css1, CongruentSegments css2, CongruentSegments css3)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            //
            // All congruence pairs must minimally relate the triangles
            //
            if (!css1.LinksTriangles(tri1, tri2))
            {
                return(newGrounded);
            }
            if (!css2.LinksTriangles(tri1, tri2))
            {
                return(newGrounded);
            }
            if (!css3.LinksTriangles(tri1, tri2))
            {
                return(newGrounded);
            }

            Segment seg1Tri1 = tri1.GetSegment(css1);
            Segment seg1Tri2 = tri2.GetSegment(css1);

            Segment seg2Tri1 = tri1.GetSegment(css2);
            Segment seg2Tri2 = tri2.GetSegment(css2);

            Segment seg3Tri1 = tri1.GetSegment(css3);
            Segment seg3Tri2 = tri2.GetSegment(css3);

            //
            // The vertices of both triangles must all be distinct and cover the triangle completely.
            //
            Point vertex1Tri1 = seg1Tri1.SharedVertex(seg2Tri1);
            Point vertex2Tri1 = seg2Tri1.SharedVertex(seg3Tri1);
            Point vertex3Tri1 = seg1Tri1.SharedVertex(seg3Tri1);

            if (vertex1Tri1 == null || vertex2Tri1 == null || vertex3Tri1 == null)
            {
                return(newGrounded);
            }
            if (vertex1Tri1.StructurallyEquals(vertex2Tri1) ||
                vertex1Tri1.StructurallyEquals(vertex3Tri1) ||
                vertex2Tri1.StructurallyEquals(vertex3Tri1))
            {
                return(newGrounded);
            }

            Point vertex1Tri2 = seg1Tri2.SharedVertex(seg2Tri2);
            Point vertex2Tri2 = seg2Tri2.SharedVertex(seg3Tri2);
            Point vertex3Tri2 = seg1Tri2.SharedVertex(seg3Tri2);

            if (vertex1Tri2 == null || vertex2Tri2 == null || vertex3Tri2 == null)
            {
                return(newGrounded);
            }
            if (vertex1Tri2.StructurallyEquals(vertex2Tri2) ||
                vertex1Tri2.StructurallyEquals(vertex3Tri2) ||
                vertex2Tri2.StructurallyEquals(vertex3Tri2))
            {
                return(newGrounded);
            }

            //
            // Construct the corresponding points between the triangles
            //
            List <Point> triangleOne = new List <Point>();
            List <Point> triangleTwo = new List <Point>();

            triangleOne.Add(vertex1Tri1);
            triangleTwo.Add(vertex1Tri2);

            triangleOne.Add(vertex2Tri1);
            triangleTwo.Add(vertex2Tri2);

            triangleOne.Add(vertex3Tri1);
            triangleTwo.Add(vertex3Tri2);

            //
            // Construct the new clauses: congruent triangles and CPCTC
            //
            GeometricCongruentTriangles gcts = new GeometricCongruentTriangles(new Triangle(triangleOne), new Triangle(triangleTwo));

            // Hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(tri1);
            antecedent.Add(tri2);
            antecedent.Add(css1);
            antecedent.Add(css2);
            antecedent.Add(css3);

            newGrounded.Add(new EdgeAggregator(antecedent, gcts, annotation));

            // Add all the corresponding parts as new congruent clauses
            newGrounded.AddRange(CongruentTriangles.GenerateCPCTC(gcts, triangleOne, triangleTwo));

            return(newGrounded);
        }
Exemplo n.º 19
0
        //
        // Checks for SAS given the 5 values
        //
        private static List <EdgeAggregator> InstantiateSAS(Triangle tri1, Triangle tri2, CongruentSegments css1, CongruentSegments css2, CongruentAngles cas)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            //
            // All congruence pairs must minimally relate the triangles
            //
            if (!css1.LinksTriangles(tri1, tri2))
            {
                return(newGrounded);
            }
            if (!css2.LinksTriangles(tri1, tri2))
            {
                return(newGrounded);
            }
            if (!cas.LinksTriangles(tri1, tri2))
            {
                return(newGrounded);
            }

            // Is this angle an 'extension' of the actual triangle angle? If so, acquire the normalized version of
            // the angle, using only the triangle vertices to represent the angle
            Angle angleTri1 = tri1.NormalizeAngle(tri1.AngleBelongs(cas));
            Angle angleTri2 = tri2.NormalizeAngle(tri2.AngleBelongs(cas));

            Segment seg1Tri1 = tri1.GetSegment(css1);
            Segment seg1Tri2 = tri2.GetSegment(css1);

            Segment seg2Tri1 = tri1.GetSegment(css2);
            Segment seg2Tri2 = tri2.GetSegment(css2);

            if (!angleTri1.IsIncludedAngle(seg1Tri1, seg2Tri1) || !angleTri2.IsIncludedAngle(seg1Tri2, seg2Tri2))
            {
                return(newGrounded);
            }

            //
            // Construct the corrsesponding points between the triangles
            //
            List <Point> triangleOne = new List <Point>();
            List <Point> triangleTwo = new List <Point>();

            triangleOne.Add(angleTri1.GetVertex());
            triangleTwo.Add(angleTri2.GetVertex());

            triangleOne.Add(seg1Tri1.OtherPoint(angleTri1.GetVertex()));
            triangleTwo.Add(seg1Tri2.OtherPoint(angleTri2.GetVertex()));

            triangleOne.Add(seg2Tri1.OtherPoint(angleTri1.GetVertex()));
            triangleTwo.Add(seg2Tri2.OtherPoint(angleTri2.GetVertex()));

            //
            // Construct the new clauses: congruent triangles and CPCTC
            //
            GeometricCongruentTriangles gcts = new GeometricCongruentTriangles(new Triangle(triangleOne), new Triangle(triangleTwo));

            // Hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(tri1);
            antecedent.Add(tri2);
            antecedent.Add(css1);
            antecedent.Add(css2);
            antecedent.Add(cas);

            newGrounded.Add(new EdgeAggregator(antecedent, gcts, annotation));

            // Add all the corresponding parts as new congruent clauses
            newGrounded.AddRange(CongruentTriangles.GenerateCPCTC(gcts, triangleOne, triangleTwo));

            return(newGrounded);
        }
Exemplo n.º 20
0
        //
        // In order for two triangles to be isosceles, we require the following:
        //
        //    Triangle(A, B, C), Congruent(Segment(A, B), Segment(B, C)) -> IsoscelesTriangle(A, B, C)
        //
        //  This does not generate a new clause explicitly; it simply strengthens the existent object
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.ISOSCELES_TRIANGLE_DEFINITION;

            if (c is IsoscelesTriangle || c is Strengthened)
            {
                return(InstantiateDefinition(c));
            }

            // The list of new grounded clauses if they are deduced
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (!(c is CongruentSegments) && !(c is Triangle))
            {
                return(newGrounded);
            }

            //
            // Unify
            //
            if (c is CongruentSegments)
            {
                CongruentSegments css = c as CongruentSegments;

                // Only generate or add to possible congruent pairs if this is a non-reflexive relation
                if (css.IsReflexive())
                {
                    return(newGrounded);
                }

                for (int t = 0; t < candTris.Count; t++)
                {
                    if (candTris[t].HasSegment(css.cs1) && candTris[t].HasSegment(css.cs2))
                    {
                        newGrounded.Add(StrengthenToIsosceles(candTris[t], css));

                        // There should be only one possible Isosceles triangle from this congruent segments
                        // So we can remove this relationship and triangle from consideration
                        candTris.RemoveAt(t);

                        return(newGrounded);
                    }
                }

                candSegs.Add(css);
            }

            else if (c is Triangle)
            {
                Triangle newTriangle = c as Triangle;

                //
                // Do any of the congruent segment pairs merit calling this new triangle isosceles?
                //
                for (int cs = 0; cs < candSegs.Count; cs++)
                {
                    if (newTriangle.HasSegment(candSegs[cs].cs1) && newTriangle.HasSegment(candSegs[cs].cs2))
                    {
                        newGrounded.Add(StrengthenToIsosceles(newTriangle, candSegs[cs]));

                        return(newGrounded);
                    }
                }

                // Add to the list of candidates if it was not determined isosceles now.
                candTris.Add(newTriangle);
            }

            return(newGrounded);
        }
Exemplo n.º 21
0
        //       A
        //      /\ 
        //     /  \
        //    /    \
        //   /______\
        //  B        C
        //
        // In order for two triangles to be congruent, we require the following:
        //    Triangle(A, B, C), Triangle(D, E, F),
        //    Congruent(Angle(A, B, C), Angle(D, E, F)),
        //    Congruent(Segment(B, C), Segment(E, F)),
        //    Congruent(Angle(A, C, B), Angle(D, F, E)) -> Congruent(Triangle(A, B, C), Triangle(D, E, F)),
        //                                                 Congruent(Segment(A, B), Angle(D, E)),
        //                                                 Congruent(Segment(A, C), Angle(D, F)),
        //                                                 Congruent(Angle(B, A, C), Angle(E, D, F)),
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.ASA;

            // The list of new grounded clauses if they are deduced
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is CongruentSegments)
            {
                CongruentSegments newCss = clause as CongruentSegments;

                // Check all combinations of triangles to see if they are congruent
                // This congruence must include the new segment congruence
                for (int i = 0; i < candidateTriangles.Count - 1; i++)
                {
                    for (int j = i + 1; j < candidateTriangles.Count; j++)
                    {
                        for (int m = 0; m < candidateAngles.Count - 1; m++)
                        {
                            for (int n = m + 1; n < candidateAngles.Count; n++)
                            {
                                newGrounded.AddRange(InstantiateASA(candidateTriangles[i], candidateTriangles[j], candidateAngles[m], candidateAngles[n], newCss));
                            }
                        }
                    }
                }

                // Add this segment to the list of possible clauses to unify later
                candidateSegments.Add(newCss);
            }
            else if (clause is CongruentAngles)
            {
                CongruentAngles newCas = clause as CongruentAngles;

                // Except for reflexive congruent triangle (a triangle and itself), reflexive angles cannot lead to congruency
                if (newCas.IsReflexive())
                {
                    return(newGrounded);
                }

                // Check all combinations of triangles to see if they are congruent
                // This congruence must include the new segment congruence
                for (int i = 0; i < candidateTriangles.Count - 1; i++)
                {
                    for (int j = i + 1; j < candidateTriangles.Count; j++)
                    {
                        foreach (CongruentSegments css in candidateSegments)
                        {
                            foreach (CongruentAngles oldCas in candidateAngles)
                            {
                                newGrounded.AddRange(InstantiateASA(candidateTriangles[i], candidateTriangles[j], oldCas, newCas, css));
                            }
                        }
                    }
                }

                candidateAngles.Add(newCas);
            }
            // If this is a new triangle, check for triangles which may be congruent to this new triangle
            else if (clause is Triangle)
            {
                Triangle newTriangle = clause as Triangle;

                // Check all combinations of triangles to see if they are congruent
                // This congruence must include the new segment congruence
                foreach (Triangle oldTri in candidateTriangles)
                {
                    for (int m = 0; m < candidateAngles.Count - 1; m++)
                    {
                        for (int n = m + 1; n < candidateAngles.Count; n++)
                        {
                            foreach (CongruentSegments css in candidateSegments)
                            {
                                newGrounded.AddRange(InstantiateASA(newTriangle, oldTri, candidateAngles[m], candidateAngles[n], css));
                            }
                        }
                    }
                }

                candidateTriangles.Add(newTriangle);
            }

            return(newGrounded);
        }
Exemplo n.º 22
0
        private static List <EdgeAggregator> InstantiateToIsoscelesTrapezoid(Trapezoid trapezoid, CongruentSegments css, GroundedClause original)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // Does this paralle set apply to this triangle?
            if (!trapezoid.CreatesCongruentLegs(css))
            {
                return(newGrounded);
            }

            //
            // Create the new IsoscelesTrapezoid object
            //
            Strengthened newIsoscelesTrapezoid = new Strengthened(trapezoid, new IsoscelesTrapezoid(trapezoid));

            // For hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(original);
            antecedent.Add(css);

            newGrounded.Add(new EdgeAggregator(antecedent, newIsoscelesTrapezoid, annotation));

            return(newGrounded);
        }
Exemplo n.º 23
0
        private static List <EdgeAggregator> InstantiateToIsoscelesTrapezoid(GroundedClause clause)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is Trapezoid)
            {
                Trapezoid trapezoid = clause as Trapezoid;

                if (trapezoid is IsoscelesTrapezoid)
                {
                    return(newGrounded);
                }

                foreach (CongruentSegments css in candidateCongruent)
                {
                    newGrounded.AddRange(InstantiateToIsoscelesTrapezoid(trapezoid, css, trapezoid));
                }

                candidateTrapezoid.Add(trapezoid);
            }
            else if (clause is Strengthened)
            {
                Strengthened streng = clause as Strengthened;

                if (!(streng.strengthened is Trapezoid))
                {
                    return(newGrounded);
                }
                //Don't strengthen an isosceles trapezoid to an isosceles trapezoid
                if (streng.strengthened is IsoscelesTrapezoid)
                {
                    return(newGrounded);
                }

                foreach (CongruentSegments css in candidateCongruent)
                {
                    newGrounded.AddRange(InstantiateToIsoscelesTrapezoid(streng.strengthened as Trapezoid, css, streng));
                }

                candidateStrengthened.Add(streng);
            }
            else if (clause is CongruentSegments)
            {
                CongruentSegments newCss = clause as CongruentSegments;

                if (newCss.IsReflexive())
                {
                    return(newGrounded);
                }

                foreach (Trapezoid trapezoid in candidateTrapezoid)
                {
                    newGrounded.AddRange(InstantiateToIsoscelesTrapezoid(trapezoid, newCss, trapezoid));
                }

                foreach (Strengthened streng in candidateStrengthened)
                {
                    newGrounded.AddRange(InstantiateToIsoscelesTrapezoid(streng.strengthened as Trapezoid, newCss, streng));
                }

                candidateCongruent.Add(newCss);
            }

            return(newGrounded);
        }
Exemplo n.º 24
0
        //
        // Acquires all of the applicable congruent segments; then checks HL
        //
        private static List <EdgeAggregator> CollectAndCheckHL(RightTriangle rt1, RightTriangle rt2,
                                                               CongruentSegments css1, CongruentSegments css2,
                                                               GroundedClause original1, GroundedClause original2)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // The Congruence pairs must relate the two triangles
            if (!css1.LinksTriangles(rt1, rt2) || !css2.LinksTriangles(rt1, rt2))
            {
                return(newGrounded);
            }

            // One of the congruence pairs must relate the hypotenuses
            Segment hypotenuse1 = rt1.OtherSide(rt1.rightAngle);
            Segment hypotenuse2 = rt2.OtherSide(rt2.rightAngle);

            // Determine the specific congruence pair that relates the hypotenuses
            CongruentSegments hypotenuseCongruence    = null;
            CongruentSegments nonHypotenuseCongruence = null;

            if (css1.HasSegment(hypotenuse1) && css1.HasSegment(hypotenuse2))
            {
                hypotenuseCongruence    = css1;
                nonHypotenuseCongruence = css2;
            }
            else if (css2.HasSegment(hypotenuse1) && css2.HasSegment(hypotenuse2))
            {
                hypotenuseCongruence    = css2;
                nonHypotenuseCongruence = css1;
            }
            else
            {
                return(newGrounded);
            }

            // Sanity check that the non hypotenuse congruence pair does not contain hypotenuse
            if (nonHypotenuseCongruence.HasSegment(hypotenuse1) || nonHypotenuseCongruence.HasSegment(hypotenuse2))
            {
                return(newGrounded);
            }

            //
            // We now have a hypotenuse leg situation; acquire the point-to-point congruence mapping
            //
            List <Point> triangleOne = new List <Point>();
            List <Point> triangleTwo = new List <Point>();

            // Right angle vertices correspond
            triangleOne.Add(rt1.rightAngle.GetVertex());
            triangleTwo.Add(rt2.rightAngle.GetVertex());

            Point nonRightVertexRt1 = rt1.GetSegment(nonHypotenuseCongruence).SharedVertex(hypotenuse1);
            Point nonRightVertexRt2 = rt2.GetSegment(nonHypotenuseCongruence).SharedVertex(hypotenuse2);

            triangleOne.Add(nonRightVertexRt1);
            triangleTwo.Add(nonRightVertexRt2);

            triangleOne.Add(hypotenuse1.OtherPoint(nonRightVertexRt1));
            triangleTwo.Add(hypotenuse2.OtherPoint(nonRightVertexRt2));

            //
            // Construct the new deduced relationships
            //
            GeometricCongruentTriangles ccts = new GeometricCongruentTriangles(new Triangle(triangleOne),
                                                                               new Triangle(triangleTwo));

            // Hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(original1);
            antecedent.Add(original2);
            antecedent.Add(css1);
            antecedent.Add(css2);

            newGrounded.Add(new EdgeAggregator(antecedent, ccts, annotation));

            // Add all the corresponding parts as new congruent clauses
            newGrounded.AddRange(CongruentTriangles.GenerateCPCTC(ccts, triangleOne, triangleTwo));

            return(newGrounded);
        }
Exemplo n.º 25
0
        //    A
        //     |\
        //     | \
        //     |_ \
        //     |_|_\
        //    B     C
        // In order for two right triangles to be congruent, we require the following:
        //    RightTriangle(A, B, C), RightTriangle(D, E, F),
        //    Congruent(Segment(A, B), Segment(D, E)),
        //    Congruent(Segment(A, C), Segment(D, F)) -> Congruent(Triangle(A, B, C), Triangle(D, E, F)),
        //                                               Congruent(Segment(A, C), Angle(D, F)),
        //                                               Congruent(Angle(C, A, B), Angle(F, D, E)),
        //                                               Congruent(Angle(B, C, A), Angle(E, F, D)),
        //
        // Note: we need to figure out the proper order of the sides to guarantee congruence
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.HYPOTENUSE_LEG;

            // The list of new grounded clauses if they are deduced
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (clause is CongruentSegments)
            {
                CongruentSegments newCs = clause as CongruentSegments;

                // Check all combinations of strict right triangle objects
                for (int i = 0; i < candidateRightTriangles.Count - 1; i++)
                {
                    for (int j = i + 1; j < candidateRightTriangles.Count; j++)
                    {
                        foreach (CongruentSegments css in candidateSegments)
                        {
                            newGrounded.AddRange(ReconfigureAndCheck(candidateRightTriangles[i], candidateRightTriangles[j], newCs, css));
                        }
                    }
                }

                // Check all combinations of (1) strict right triangle and (2) a strengthened triangle
                foreach (RightTriangle rt in candidateRightTriangles)
                {
                    foreach (Strengthened streng in candidateStrengthened)
                    {
                        foreach (CongruentSegments css in candidateSegments)
                        {
                            newGrounded.AddRange(ReconfigureAndCheck(rt, streng, newCs, css));
                        }
                    }
                }

                // Check all combinations of strengthened triangles
                for (int i = 0; i < candidateStrengthened.Count - 1; i++)
                {
                    for (int j = i + 1; j < candidateStrengthened.Count; j++)
                    {
                        foreach (CongruentSegments css in candidateSegments)
                        {
                            newGrounded.AddRange(ReconfigureAndCheck(candidateStrengthened[i], candidateStrengthened[j], newCs, css));
                        }
                    }
                }

                // Add this segment to the list of possible clauses to unify later
                candidateSegments.Add(newCs);
            }
            //
            // A triangle is either strictly a right triangle object, or a triangle is strengthened to be a right triangle
            //
            else if (clause is RightTriangle)
            {
                RightTriangle newRt = clause as RightTriangle;

                // Check all combinations of strict right triangle objects
                foreach (RightTriangle oldRt in candidateRightTriangles)
                {
                    for (int i = 0; i < candidateSegments.Count - 1; i++)
                    {
                        for (int j = i + 1; j < candidateSegments.Count; j++)
                        {
                            newGrounded.AddRange(ReconfigureAndCheck(newRt, oldRt, candidateSegments[i], candidateSegments[j]));
                        }
                    }
                }

                // Check all combinations of (1) strict right triangle and (2) a strengthened triangle
                foreach (Strengthened streng in candidateStrengthened)
                {
                    for (int i = 0; i < candidateSegments.Count - 1; i++)
                    {
                        for (int j = i + 1; j < candidateSegments.Count; j++)
                        {
                            newGrounded.AddRange(ReconfigureAndCheck(newRt, streng, candidateSegments[i], candidateSegments[j]));
                        }
                    }
                }

                candidateRightTriangles.Add(newRt);
            }
            else if (clause is Strengthened)
            {
                Strengthened newStreng = clause as Strengthened;

                // Only interested in strengthened Right Triangles
                if (!(newStreng.strengthened is RightTriangle))
                {
                    return(newGrounded);
                }

                // Check all combinations of strict right triangle objects
                foreach (RightTriangle oldRt in candidateRightTriangles)
                {
                    for (int i = 0; i < candidateSegments.Count - 1; i++)
                    {
                        for (int j = i + 1; j < candidateSegments.Count; j++)
                        {
                            newGrounded.AddRange(ReconfigureAndCheck(oldRt, newStreng, candidateSegments[i], candidateSegments[j]));
                        }
                    }
                }

                // Check all combinations of (1) strict right triangle and (2) a strengthened triangle
                foreach (Strengthened oldStreng in candidateStrengthened)
                {
                    for (int i = 0; i < candidateSegments.Count - 1; i++)
                    {
                        for (int j = i + 1; j < candidateSegments.Count; j++)
                        {
                            newGrounded.AddRange(ReconfigureAndCheck(newStreng, oldStreng, candidateSegments[i], candidateSegments[j]));
                        }
                    }
                }

                candidateStrengthened.Add(newStreng);
            }

            return(newGrounded);
        }
        //               A
        //              /)
        //             /  )
        //            /    )
        // center:   O      )
        //            \    )
        //             \  )
        //              \)
        //               C
        //
        //               D
        //              /)
        //             /  )
        //            /    )
        // center:   Q      )
        //            \    )
        //             \  )
        //              \)
        //               F
        //
        // Congruent(Segment(AC), Segment(DF)) -> Congruent(Arc(A, C), Arc(D, F))
        //
        private static List <EdgeAggregator> InstantiateForwardPartOfTheorem(CongruentSegments cas)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            //
            // Acquire the circles for which the segments are chords.
            //
            List <Circle> circles1 = Circle.GetChordCircles(cas.cs1);
            List <Circle> circles2 = Circle.GetChordCircles(cas.cs2);

            //
            // Make all possible combinations of arcs congruent
            //
            foreach (Circle circle1 in circles1)
            {
                // Create the appropriate type of arcs from the chord and the circle
                List <Semicircle> c1semi  = null;
                MinorArc          c1minor = null;
                MajorArc          c1major = null;

                if (circle1.DefinesDiameter(cas.cs1))
                {
                    c1semi = CreateSemiCircles(circle1, cas.cs1);
                }
                else
                {
                    c1minor = new MinorArc(circle1, cas.cs1.Point1, cas.cs1.Point2);
                    c1major = new MajorArc(circle1, cas.cs1.Point1, cas.cs1.Point2);
                }

                foreach (Circle circle2 in circles2)
                {
                    //The two circles must be the same or congruent
                    if (circle1.radius == circle2.radius)
                    {
                        List <Semicircle> c2semi  = null;
                        MinorArc          c2minor = null;
                        MajorArc          c2major = null;

                        List <GeometricCongruentArcs> congruencies = new List <GeometricCongruentArcs>();
                        if (circle2.DefinesDiameter(cas.cs2))
                        {
                            c2semi = CreateSemiCircles(circle2, cas.cs2);
                            congruencies.AddRange(EquateSemiCircles(c1semi, c2semi));
                        }
                        else
                        {
                            c2minor = new MinorArc(circle2, cas.cs2.Point1, cas.cs2.Point2);
                            c2major = new MajorArc(circle2, cas.cs2.Point1, cas.cs2.Point2);
                            congruencies.Add(new GeometricCongruentArcs(c1minor, c2minor));
                            congruencies.Add(new GeometricCongruentArcs(c1major, c2major));
                        }

                        // For hypergraph
                        List <GroundedClause> antecedent = new List <GroundedClause>();
                        antecedent.Add(cas.cs1);
                        antecedent.Add(cas.cs2);
                        antecedent.Add(cas);

                        foreach (GeometricCongruentArcs gcas in congruencies)
                        {
                            newGrounded.Add(new EdgeAggregator(antecedent, gcas, forwardAnnotation));
                        }
                    }
                }
            }

            return(newGrounded);
        }
Exemplo n.º 27
0
        private static List <EdgeAggregator> InstantiateToRhombus(Quadrilateral quad, CongruentSegments cs1, CongruentSegments cs2, CongruentSegments cs3)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            //
            // The 3 congruent segments pairs must relate; one pair must link the two others.
            // Determine the link segments as well as the opposite sides.
            //
            CongruentSegments link = null;
            CongruentSegments opp1 = null;
            CongruentSegments opp2 = null;

            if (cs1.SharedSegment(cs2) != null && cs1.SharedSegment(cs3) != null)
            {
                link = cs1;
                opp1 = cs2;
                opp2 = cs3;
            }
            else if (cs2.SharedSegment(cs1) != null && cs2.SharedSegment(cs3) != null)
            {
                link = cs2;
                opp1 = cs1;
                opp2 = cs3;
            }
            else if (cs3.SharedSegment(cs1) != null && cs3.SharedSegment(cs2) != null)
            {
                link = cs3;
                opp1 = cs1;
                opp2 = cs2;
            }
            else
            {
                return(newGrounded);
            }

            // Are the pairs on the opposite side of this quadrilateral?
            if (!quad.HasOppositeCongruentSides(opp1))
            {
                return(newGrounded);
            }
            if (!quad.HasOppositeCongruentSides(opp2))
            {
                return(newGrounded);
            }

            //
            // Create the new Rhombus object
            //
            Strengthened newRhombus = new Strengthened(quad, new Rhombus(quad));

            // For hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(quad);
            antecedent.Add(cs1);
            antecedent.Add(cs2);
            antecedent.Add(cs3);

            newGrounded.Add(new EdgeAggregator(antecedent, newRhombus, annotation));

            return(newGrounded);
        }
        private static List <EdgeAggregator> InstantiateToTheorem(Quadrilateral quad, CongruentSegments cs1, CongruentSegments cs2)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // Are the pairs on the opposite side of this quadrilateral?
            if (!quad.HasOppositeCongruentSides(cs1))
            {
                return(newGrounded);
            }
            if (!quad.HasOppositeCongruentSides(cs2))
            {
                return(newGrounded);
            }

            //
            // Create the new Rhombus object
            //
            Strengthened newParallelogram = new Strengthened(quad, new Parallelogram(quad));

            // For hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(quad);
            antecedent.Add(cs1);
            antecedent.Add(cs2);

            newGrounded.Add(new EdgeAggregator(antecedent, newParallelogram, annotation));

            return(newGrounded);
        }
Exemplo n.º 29
0
        //
        // Take the angle congruence and bisector and create the AngleBisector relation
        //              \
        //               \
        //     B ---------V---------A
        //                 \
        //                  \
        //                   C
        //
        private static List <EdgeAggregator> InstantiateToDef(Point intersectionPoint, Intersection inter, CongruentSegments cs)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // Does the given point of intersection apply to this actual intersection object
            if (!intersectionPoint.Equals(inter.intersect))
            {
                return(newGrounded);
            }

            // The entire segment AB
            Segment overallSegment = new Segment(cs.cs1.OtherPoint(intersectionPoint), cs.cs2.OtherPoint(intersectionPoint));

            // The segment must align completely with one of the intersection segments
            Segment interCollinearSegment = inter.GetCollinearSegment(overallSegment);

            if (interCollinearSegment == null)
            {
                return(newGrounded);
            }

            // Does this intersection have the entire segment AB
            if (!inter.HasSegment(overallSegment))
            {
                return(newGrounded);
            }

            Segment bisector        = inter.OtherSegment(overallSegment);
            Segment bisectedSegment = inter.GetCollinearSegment(overallSegment);

            // Check if the bisected segment extends is the exact same segment as the overall segment AB
            if (!bisectedSegment.StructurallyEquals(overallSegment))
            {
                if (overallSegment.PointLiesOnAndBetweenEndpoints(bisectedSegment.Point1) &&
                    overallSegment.PointLiesOnAndBetweenEndpoints(bisectedSegment.Point2))
                {
                    return(newGrounded);
                }
            }

            SegmentBisector newSB = new SegmentBisector(inter, bisector);

            // For hypergraph
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(inter);
            antecedent.Add(cs);

            newGrounded.Add(new EdgeAggregator(antecedent, newSB, annotation));
            return(newGrounded);
        }
Exemplo n.º 30
0
        //
        //
        //
        private static List <EdgeAggregator> IfCongruencesApplyToTrianglesGenerate(Triangle ct1, Triangle ct2, CongruentSegments css1, CongruentSegments css2)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            //
            // The congruent relationships need to link the given triangles
            //
            if (!css1.LinksTriangles(ct1, ct2))
            {
                return(newGrounded);
            }
            if (!css2.LinksTriangles(ct1, ct2))
            {
                return(newGrounded);
            }

            Segment seg1Tri1 = ct1.GetSegment(css1);
            Segment seg2Tri1 = ct1.GetSegment(css2);

            Segment seg1Tri2 = ct2.GetSegment(css1);
            Segment seg2Tri2 = ct2.GetSegment(css2);

            // Avoid redundant segments, if it arises
            if (seg1Tri1.StructurallyEquals(seg2Tri1))
            {
                return(newGrounded);
            }
            if (seg1Tri2.StructurallyEquals(seg2Tri2))
            {
                return(newGrounded);
            }

            //
            // Proportional Segments (we generate only as needed to avoid bloat in the hypergraph (assuming they are used by both triangles)
            // We avoid generating proportions if they are truly congruences.
            //
            List <GroundedClause> propAntecedent = new List <GroundedClause>();

            propAntecedent.Add(css1);
            propAntecedent.Add(css2);

            SegmentRatio ratio1 = new SegmentRatio(seg1Tri1, seg1Tri2);
            SegmentRatio ratio2 = new SegmentRatio(seg2Tri1, seg2Tri2);

            GeometricSegmentRatioEquation newEq = new GeometricSegmentRatioEquation(ratio1, ratio2);

            newGrounded.Add(new EdgeAggregator(propAntecedent, newEq, annotation));

            ////
            //// Only generate if ratios are not 1.
            ////



            //GeometricSegmentRatio newProp = null;
            //if (!Utilities.CompareValues(seg1Tri1.Length, seg1Tri2.Length))
            //{
            //    newProp = new GeometricSegmentRatio(seg1Tri1, seg1Tri2);
            //    newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation));
            //}
            //if (!Utilities.CompareValues(seg1Tri1.Length, seg2Tri2.Length))
            //{
            //    newProp = new GeometricSegmentRatio(seg1Tri1, seg2Tri2);
            //    newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation));
            //}
            //if (!Utilities.CompareValues(seg2Tri1.Length, seg1Tri2.Length))
            //{
            //    newProp = new GeometricSegmentRatio(seg2Tri1, seg1Tri2);
            //    newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation));
            //}
            //if (!Utilities.CompareValues(seg2Tri1.Length, seg2Tri2.Length))
            //{
            //    newProp = new GeometricSegmentRatio(seg2Tri1, seg2Tri2);
            //    newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation));
            //}

            return(newGrounded);
        }