private static List<EdgeAggregator> InstantiateTheorem(Angle a1, Angle a2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Acquire all circles in which the angles are inscribed
            List<Circle> circles1 = Circle.IsInscribedAngle(a1);
            List<Circle> circles2 = Circle.IsInscribedAngle(a2);

            //Acquire the common circles in which both angles are inscribed
            List<Circle> circles = (circles1.Intersect(circles2)).ToList();

            //For each common circle, check for equivalent itercepted arcs
            foreach (Circle c in circles)
            {
                Arc i1 = Arc.GetInterceptedArc(c, a1);
                Arc i2 = Arc.GetInterceptedArc(c, a2);

                if (i1.StructurallyEquals(i2))
                {
                    GeometricCongruentAngles gcas = new GeometricCongruentAngles(a1, a2);

                    //For hypergraph
                    List<GroundedClause> antecedent = new List<GroundedClause>();
                    antecedent.Add(c);
                    antecedent.Add(a1);
                    antecedent.Add(a2);
                    antecedent.Add(i1);

                    newGrounded.Add(new EdgeAggregator(antecedent, gcas, annotation));
                }
            }

            return newGrounded;
        }
        public static List<EdgeAggregator> InstantiateTheorem(GroundedClause original, IsoscelesTriangle isoTri)
        {
            GeometricCongruentAngles newCongSegs = new GeometricCongruentAngles(isoTri.baseAngleOppositeLeg1, isoTri.baseAngleOppositeLeg2);

            List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(original);

            return Utilities.MakeList<EdgeAggregator>(new EdgeAggregator(antecedent, newCongSegs, annotation));
        }
        private static List<EdgeAggregator> InstantiateToTheorem(IsoscelesTrapezoid trapezoid, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            GeometricCongruentAngles gcas1 = new GeometricCongruentAngles(trapezoid.bottomLeftBaseAngle, trapezoid.bottomRightBaseAngle);
            GeometricCongruentAngles gcas2 = new GeometricCongruentAngles(trapezoid.topLeftBaseAngle, trapezoid.topRightBaseAngle);

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

            newGrounded.Add(new EdgeAggregator(antecedent, gcas1, annotation));
            newGrounded.Add(new EdgeAggregator(antecedent, gcas2, annotation));

            return newGrounded;
        }
        //      V---------------A
        //     / \
        //    /   \
        //   /     \
        //  B       C
        //
        // AngleBisector(Angle(A, V, B), Segment(V, C)) -> Congruent(Angle, A, V, C), Angle(C, V, B))
        //
        private static List<EdgeAggregator> InstantiateBisector(AngleBisector ab)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Create the two adjacent angles
            Point vertex = ab.angle.GetVertex();
            Point interiorPt = ab.angle.IsOnInteriorExplicitly(ab.bisector.Point1) ? ab.bisector.Point1 : ab.bisector.Point2;
            Angle adj1 = new Angle(ab.angle.ray1.OtherPoint(vertex), vertex, interiorPt);
            Angle adj2 = new Angle(ab.angle.ray2.OtherPoint(vertex), vertex, interiorPt);
            GeometricCongruentAngles cas = new GeometricCongruentAngles(adj1, adj2);

            // For hypergraph
            newGrounded.Add(new EdgeAggregator(Utilities.MakeList<GroundedClause>(ab), cas, annotation));

            return newGrounded;
        }
        private static List<EdgeAggregator> InstantiateTheorem(Parallelogram parallelogram, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Determine the CongruentSegments opposing sides and output that.
            GeometricCongruentAngles gcas1 = new GeometricCongruentAngles(parallelogram.topLeftAngle, parallelogram.bottomRightAngle);
            GeometricCongruentAngles gcas2 = new GeometricCongruentAngles(parallelogram.bottomLeftAngle, parallelogram.topRightAngle);

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

            newGrounded.Add(new EdgeAggregator(antecedent, gcas1, annotation));
            newGrounded.Add(new EdgeAggregator(antecedent, gcas2, annotation));

            return newGrounded;
        }
        //
        // 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<EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.VERTICAL_ANGLES;

            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Intersection inter = c as Intersection;
            if (inter == null) return newGrounded;

            //
            // Verify that this intersection is composed of two overlapping segments
            // That is, we do not allow a segment to stand on another:
            //      \
            //       \
            //        \
            //   ______\_______
            //
            if (inter.StandsOn()) return newGrounded;

            //
            // Congruent(Angle(A, X, C), Angle(B, X, D))
            //
            List<GroundedClause> antecedent1 = Utilities.MakeList<GroundedClause>(inter);
            Angle ang1Set1 = Angle.AcquireFigureAngle(new Angle(inter.lhs.Point1, inter.intersect, inter.rhs.Point1));
            Angle ang2Set1 = Angle.AcquireFigureAngle(new Angle(inter.lhs.Point2, inter.intersect, inter.rhs.Point2));
            antecedent1.Add(ang1Set1);
            antecedent1.Add(ang2Set1);
            GeometricCongruentAngles cca1 = new GeometricCongruentAngles(ang1Set1, ang2Set1);
            cca1.MakeIntrinsic(); // This is an 'obvious' notion so it should be intrinsic to any figure
            newGrounded.Add(new EdgeAggregator(antecedent1, cca1, annotation));

            //
            // Congruent(Angle(A, X, D), Angle(C, X, B))
            //
            List<GroundedClause> antecedent2 = Utilities.MakeList<GroundedClause>(inter);
            Angle ang1Set2 = Angle.AcquireFigureAngle(new Angle(inter.lhs.Point1, inter.intersect, inter.rhs.Point2));
            Angle ang2Set2 = Angle.AcquireFigureAngle(new Angle(inter.lhs.Point2, inter.intersect, inter.rhs.Point1));
            antecedent2.Add(ang1Set2);
            antecedent2.Add(ang2Set2);
            GeometricCongruentAngles cca2 = new GeometricCongruentAngles(ang1Set2, ang2Set2);
            cca2.MakeIntrinsic(); // This is an 'obvious' notion so it should be intrinsic to any figure
            newGrounded.Add(new EdgeAggregator(antecedent2, cca2, annotation));

            return newGrounded;
        }
Esempio n. 7
0
        public static GenericInstantiator.EdgeAggregator GenerateAngleCongruence(Triangle tri, Angle angle)
        {
            //
            // If we have already generated a reflexive congruence, avoid regenerating
            //
            foreach (Angle oldSharedAngle in knownSharedAngles)
            {
                if (oldSharedAngle.Equates(angle))
                {
                    return(null);
                }
            }

            // Generate
            GeometricCongruentAngles gcas = new GeometricCongruentAngles(angle, angle);

            // This is an 'obvious' notion so it should be intrinsic to any figure
            gcas.MakeIntrinsic();

            return(new GenericInstantiator.EdgeAggregator(Utilities.MakeList <GroundedClause>(Angle.AcquireFigureAngle(angle)), gcas, reflexAnnotation));
        }
        //
        // Creates a basic S-Shape with standsOnEndpoints
        //
        //                  ______ offThat
        //                 |
        //   offThis ______|
        //
        // Return <offThis, offThat>
        private static List<EdgeAggregator> GenerateSimpleS(Parallel parallel, Intersection inter1, Point offThis, Intersection inter2, Point offThat)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(offThat, inter2.intersect, inter1.intersect),
                                                                        new Angle(offThis, inter1.intersect, inter2.intersect));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        //     leftTop    rightTop
        //         |         |
        //         |_________|
        //         |         |
        //         |         |
        //   leftBottom rightBottom
        //
        private static List<EdgeAggregator> GenerateH(Parallel parallel, Intersection crossingInterLeft, Intersection crossingInterRight)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Segment transversal = crossingInterLeft.AcquireTransversal(crossingInterRight);

            //
            // Find tops and bottoms
            //
            Segment crossingLeftParallel = crossingInterLeft.OtherSegment(transversal);
            Segment crossingRightParallel = crossingInterRight.OtherSegment(transversal);

            //
            // Determine which points are on the same side of the transversal.
            //
            Segment testingCrossSegment = new Segment(crossingLeftParallel.Point1, crossingRightParallel.Point1);
            Point intersection = transversal.FindIntersection(testingCrossSegment);

            Point leftTop = crossingLeftParallel.Point1;
            Point leftBottom = crossingLeftParallel.Point2;

            Point rightTop = null;
            Point rightBottom = null;
            if (transversal.PointLiesOnAndBetweenEndpoints(intersection))
            {
                rightTop = crossingRightParallel.Point2;
                rightBottom = crossingRightParallel.Point1;
            }
            else
            {
                rightTop = crossingRightParallel.Point1;
                rightBottom = crossingRightParallel.Point2;
            }

            //
            // Generate the new congruences
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(leftTop, crossingInterLeft.intersect, crossingInterRight.intersect),
                                                                        new Angle(rightBottom, crossingInterRight.intersect, crossingInterLeft.intersect));
            newAngleRelations.Add(gca);
            gca = new GeometricCongruentAngles(new Angle(rightTop, crossingInterRight.intersect, crossingInterLeft.intersect),
                                               new Angle(leftBottom, crossingInterLeft.intersect, crossingInterRight.intersect));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, crossingInterLeft, crossingInterRight);
        }
        //                 offCross
        //                     |
        // leftCross     ______|______   rightCross
        //                     |
        // leftStands     _____|_____    rightStands
        //
        private static List<EdgeAggregator> GenerateFlying(Parallel parallel, Intersection inter1, Intersection inter2, Point offCross)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine which is the crossing intersection and which stands on the endpoints
            //
            Intersection crossingInter = null;
            Intersection standsInter = null;
            if (inter1.Crossing())
            {
                crossingInter = inter1;
                standsInter = inter2;
            }
            else if (inter2.Crossing())
            {
                crossingInter = inter2;
                standsInter = inter1;
            }

            // Determine the side of the crossing needed for the angle
            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment parallelStands = standsInter.OtherSegment(transversal);
            Segment parallelCrossing = crossingInter.OtherSegment(transversal);

            // Determine point orientation in the plane
            Point leftStands = parallelStands.Point1;
            Point rightStands = parallelStands.Point2;
            Point leftCross = null;
            Point rightCross = null;

            Segment crossingTester = new Segment(leftStands, parallelCrossing.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);
            if (transversal.PointLiesOnAndBetweenEndpoints(intersection))
            {
                leftCross = parallelCrossing.Point2;
                rightCross = parallelCrossing.Point1;
            }
            else
            {
                leftCross = parallelCrossing.Point1;
                rightCross = parallelCrossing.Point2;
            }

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(rightCross, crossingInter.intersect, standsInter.intersect),
                                                                        new Angle(leftStands, standsInter.intersect, crossingInter.intersect));
            newAngleRelations.Add(gca);

            gca = new GeometricCongruentAngles(new Angle(leftCross, crossingInter.intersect, standsInter.intersect),
                                               new Angle(rightStands, standsInter.intersect, crossingInter.intersect));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        private static List<EdgeAggregator> IndirectRelations(CongruentAngles cas, AnglePairRelation relation1, AnglePairRelation relation2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Do we have the same type of relation?
            if (relation1.GetType() != relation2.GetType()) return newGrounded;

            //
            // Determine the shared values amongst the relations
            //
            Angle shared1 = relation1.AngleShared(cas);
            if (shared1 == null) return newGrounded;

            Angle shared2 = cas.OtherAngle(shared1);
            if (!relation2.HasAngle(shared2)) return newGrounded;

            Angle otherAngle1 = relation1.OtherAngle(shared1);
            Angle otherAngle2 = relation2.OtherAngle(shared2);

            // Avoid generating a reflexive relationship
            if (otherAngle1.Equates(otherAngle2)) return newGrounded;

            //
            // Congruent(Angle(1), Angle(3))
            //
            // The other two angles from the relation pairs are then congruent
            GeometricCongruentAngles gcas = new GeometricCongruentAngles(otherAngle1, otherAngle2);

            // Avoid direct cyclic congruent angle generation
            if (cas.StructurallyEquals(gcas)) return newGrounded;

            // Construct hyperedge
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(cas);
            antecedent.Add(relation1);
            antecedent.Add(relation2);

            //
            // AnglePairRelation(Angle(1), Angle(4)),
            // AnglePairRelation(Angle(2), Angle(3)),
            //
            if (relation1 is Complementary && relation2 is Complementary)
            {
                Complementary comp1 = new Complementary(shared1, otherAngle2);
                Complementary comp2 = new Complementary(shared2, otherAngle1);

                newGrounded.Add(new EdgeAggregator(antecedent, comp1, compAnnotation));
                newGrounded.Add(new EdgeAggregator(antecedent, comp2, compAnnotation));
            }
            else if (relation1 is Supplementary && relation2 is Supplementary)
            {
                Supplementary supp1 = new Supplementary(shared1, otherAngle2);
                Supplementary supp2 = new Supplementary(shared2, otherAngle1);

                newGrounded.Add(new EdgeAggregator(antecedent, supp1, suppAnnotation));
                newGrounded.Add(new EdgeAggregator(antecedent, supp2, suppAnnotation));
            }
            else
            {
                throw new ArgumentException("RelationsOfCongruent:: Expected a supplementary or complementary angle, not " + relation1.GetType());
            }

            newGrounded.Add(new EdgeAggregator(antecedent, gcas, relation1 is Complementary ? compAnnotation : suppAnnotation));

            return newGrounded;
        }
        private static List<EdgeAggregator> DirectRelations(AnglePairRelation relation1, AnglePairRelation relation2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Do we have the same type of relation?
            if (relation1.GetType() != relation2.GetType()) return newGrounded;

            // Acquire the shared angle
            Angle shared = relation1.AngleShared(relation2);
            if (shared == null) return newGrounded;

            Angle otherAngle1 = relation1.OtherAngle(shared);
            Angle otherAngle2 = relation2.OtherAngle(shared);

            // Avoid generating a reflexive relationship
            if (otherAngle1.Equates(otherAngle2)) return newGrounded;

            // The other two angles are then congruent
            GeometricCongruentAngles gcas = new GeometricCongruentAngles(otherAngle1, otherAngle2);

            // Construct hyperedge
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(relation1);
            antecedent.Add(relation2);

            newGrounded.Add(new EdgeAggregator(antecedent, gcas, relation1 is Complementary ? compAnnotation : suppAnnotation));

            return newGrounded;
        }
        //     offCross
        //        |
        //  ______|______ rightCrossing
        //        |
        //        |_____  offStands
        //        |
        //        |
        //     bottomStands
        private static List<EdgeAggregator> InstantiateExtendedChairIntersection(Parallel parallel, Intersection inter1, Intersection inter2, Point offCross)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine which is the crossing intersection and which stands on the endpoints
            //
            Intersection crossingInter = null;
            Intersection standsInter = null;
            if (inter1.Crossing())
            {
                crossingInter = inter1;
                standsInter = inter2;
            }
            else if (inter2.Crossing())
            {
                crossingInter = inter2;
                standsInter = inter1;
            }

            //
            // Determination of Points
            //
            Point offStands = standsInter.CreatesTShape();

            Segment transversal = inter1.AcquireTransversal(inter2);
            Segment transversalStands = standsInter.GetCollinearSegment(transversal);

            Point bottomStands = Segment.Between(standsInter.intersect, transversalStands.Point1, crossingInter.intersect) ? transversalStands.Point1 : transversalStands.Point2;

            // Which side for rightCrossing
            Segment parallelCrossing = crossingInter.OtherSegment(transversal);
            Segment crossingTester = new Segment(offStands, parallelCrossing.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);

            Point rightCrossing = transversal.PointLiesOnAndBetweenEndpoints(intersection) ? parallelCrossing.Point2 : parallelCrossing.Point1;

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(bottomStands, standsInter.intersect, offStands),
                                                                        new Angle(standsInter.intersect, crossingInter.intersect, rightCrossing));
            newAngleRelations.Add(gca);

            gca = new GeometricCongruentAngles(new Angle(offStands, standsInter.intersect, crossingInter.intersect),
                                               new Angle(rightCrossing, crossingInter.intersect, offCross));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        //
        // Generate the three pairs of congruent segments.
        //
        private static List<EdgeAggregator> InstantiateFromDefinition(EquilateralTriangle tri, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

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

            //
            // Create the 3 sets of congruent segments.
            //
            for (int s = 0; s < tri.orderedSides.Count; s++)
            {
                GeometricCongruentSegments gcs = new GeometricCongruentSegments(tri.orderedSides[s], tri.orderedSides[(s+1) % tri.orderedSides.Count]);

                newGrounded.Add(new EdgeAggregator(antecedent, gcs, annotation));
            }

            //
            // Create the 3 congruent angles.
            //
            for (int a = 0; a < tri.angles.Count; a++)
            {
                GeometricCongruentAngles gcas = new GeometricCongruentAngles(tri.angles[a], tri.angles[(a + 1) % tri.angles.Count]);

                newGrounded.Add(new EdgeAggregator(antecedent, gcas, annotation));
            }

            //
            // Create the 3 equations for the measure of each angle being 60 degrees.
            //
            for (int a = 0; a < tri.angles.Count; a++)
            {
                GeometricAngleEquation gae = new GeometricAngleEquation(tri.angles[a], new NumericValue(60));

                newGrounded.Add(new EdgeAggregator(antecedent, gae, annotation));
            }

            return newGrounded;
        }
        //
        // 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;
        }
        // Corresponding angles if (we have 8 points here)
        //
        //  InterLeft                        InterRight
        //                |          |
        //      offLeft __|__________|__ offRight
        //                |          |
        //                |          |
        //
        private static List<EdgeAggregator> InstantiateCompleteIntersection(Parallel parallel, Intersection crossingInterLeft, Intersection crossingInterRight)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Segment transversal = crossingInterLeft.AcquireTransversal(crossingInterRight);

            //
            // Find off1 and off2
            //
            Segment crossingLeftParallel = crossingInterLeft.OtherSegment(transversal);
            Segment crossingRightParallel = crossingInterRight.OtherSegment(transversal);

            //
            // Determine which points are on the same side of the transversal.
            //
            Segment testingCrossSegment = new Segment(crossingLeftParallel.Point1, crossingRightParallel.Point1);
            Point intersection = transversal.FindIntersection(testingCrossSegment);

            Point crossingLeftTop = crossingLeftParallel.Point1;
            Point crossingLeftBottom = crossingLeftParallel.Point2;

            Point crossingRightTop = null;
            Point crossingRightBottom = null;
            if (transversal.PointLiesOnAndBetweenEndpoints(intersection))
            {
                crossingRightTop = crossingRightParallel.Point2;
                crossingRightBottom = crossingRightParallel.Point1;
            }
            else
            {
                crossingRightTop = crossingRightParallel.Point1;
                crossingRightBottom = crossingRightParallel.Point2;
            }

            // Point that is outside of the parallel lines and transversal
            Segment leftTransversal = crossingInterLeft.GetCollinearSegment(transversal);
            Segment rightTransversal = crossingInterRight.GetCollinearSegment(transversal);

            Point offCrossingLeft = Segment.Between(crossingInterLeft.intersect, leftTransversal.Point1, crossingInterRight.intersect) ? leftTransversal.Point1 : leftTransversal.Point2;
            Point offCrossingRight = Segment.Between(crossingInterRight.intersect, crossingInterLeft.intersect, rightTransversal.Point1) ? rightTransversal.Point1 : rightTransversal.Point2;

            //
            // Generate the new congruences
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(crossingLeftTop, crossingInterLeft.intersect, crossingInterRight.intersect),
                                                                        new Angle(crossingRightTop, crossingInterRight.intersect, offCrossingRight));
            newAngleRelations.Add(gca);
            gca = new GeometricCongruentAngles(new Angle(crossingLeftTop, crossingInterLeft.intersect, offCrossingLeft),
                                               new Angle(crossingRightTop, crossingInterRight.intersect, crossingInterLeft.intersect));
            newAngleRelations.Add(gca);
            gca = new GeometricCongruentAngles(new Angle(crossingLeftBottom, crossingInterLeft.intersect, offCrossingLeft),
                                               new Angle(crossingRightBottom, crossingInterRight.intersect, crossingInterLeft.intersect));
            newAngleRelations.Add(gca);
            gca = new GeometricCongruentAngles(new Angle(crossingLeftBottom, crossingInterLeft.intersect, crossingInterRight.intersect),
                                               new Angle(crossingRightBottom, crossingInterRight.intersect, offCrossingRight));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, crossingInterLeft, crossingInterRight);
        }
        //                   top
        //                    o
        //  offStands  oooooooe
        //                    e
        //offEndpoint   eeeeeee
        //                    o
        //                 bottom
        //                       Returns: <offEndpoint, offStands>
        private static List<EdgeAggregator> InstantiateSimplePiIntersection(Parallel parallel, Intersection inter1, Intersection inter2, Point offEndpoint, Point offStands)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine which is the endpoint and stands intersections
            //
            Intersection endpointInter = null;
            Intersection standsInter = null;
            if (inter1.StandsOnEndpoint() && inter2.StandsOn())
            {
                endpointInter = inter1;
                standsInter = inter2;
            }
            else if (inter2.StandsOnEndpoint() && inter1.StandsOn())
            {
                endpointInter = inter2;
                standsInter = inter1;
            }
            else return newGrounded;

            //
            // Determine the top and bottom points
            //
            Segment transversal = inter1.AcquireTransversal(inter2);
            Segment transversalStands = standsInter.GetCollinearSegment(transversal);

            Point top = null;
            Point bottom = null;
            if (Segment.Between(standsInter.intersect, transversalStands.Point1, endpointInter.intersect))
            {
                top = transversalStands.Point1;
                bottom = transversalStands.Point2;
            }
            else
            {
                top = transversalStands.Point2;
                bottom = transversalStands.Point1;
            }

            //
            // Generate the new congruences
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(top, standsInter.intersect, offStands),
                                                                        new Angle(standsInter.intersect, endpointInter.intersect, offEndpoint));
            newAngleRelations.Add(gca);
            gca = new GeometricCongruentAngles(new Angle(bottom, endpointInter.intersect, offEndpoint),
                                               new Angle(endpointInter.intersect, standsInter.intersect, offStands));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        // Corresponding angles if:
        //
        //   left _____________ right
        //           |     |
        //           |     |
        //          off1  off2
        //
        //     Inter 1       Inter 2
        //
        private static List<EdgeAggregator> InstantiatePiIntersection(Parallel parallel, Intersection inter1, Point off1, Intersection inter2, Point off2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment nonParallel1 = inter1.GetCollinearSegment(transversal);
            Segment nonParallel2 = inter2.GetCollinearSegment(transversal);

            Point left = Segment.Between(inter1.intersect, nonParallel1.Point1, inter2.intersect) ? nonParallel1.Point1 : nonParallel1.Point2;
            Point right = Segment.Between(inter2.intersect, inter1.intersect, nonParallel2.Point1) ? nonParallel2.Point1 : nonParallel2.Point2;

            //
            // Generate the new congruences
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            // CTA: Hack to avoid an exception being thrown during testing.
            try
            {
                GeometricCongruentAngles gca1 = new GeometricCongruentAngles(new Angle(left, inter1.intersect, off1),
                                                                             new Angle(inter1.intersect, inter2.intersect, off2));
                newAngleRelations.Add(gca1);

                GeometricCongruentAngles gca2 = new GeometricCongruentAngles(new Angle(right, inter2.intersect, off2),
                                                                             new Angle(inter2.intersect, inter1.intersect, off1));
                newAngleRelations.Add(gca2);
            }
            catch (Exception)
            {
                return newGrounded;
            }

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        //
        // Creates a shape like a crazy person flying
        //
        //            top   top
        //             |     |
        // larger      |_____|___ off
        //             |     |
        //             |     |
        //
        // Similar to H-shape with an extended point
        // Returns the 'larger' intersection that contains the point: off
        private static List<EdgeAggregator> InstantiateFlyingIntersection(Parallel parallel, Intersection inter1, Intersection inter2, Intersection larger, Point off)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Intersection smallerInter = inter1.Equals(larger) ? inter2 : inter1;

            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment parallel1 = inter1.OtherSegment(transversal);
            Segment parallel2 = inter2.OtherSegment(transversal);

            Point largerTop = parallel1.Point1;
            Point largerBottom = parallel1.Point2;

            Point otherTop = null;
            Point otherBottom = null;

            Segment crossingTester = new Segment(parallel1.Point1, parallel2.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);
            // opposite sides
            if (transversal.PointLiesOnAndBetweenEndpoints(intersection))
            {
                otherTop = parallel2.Point2;
                otherBottom = parallel2.Point1;
            }
            // same sides
            else
            {
                otherTop = parallel2.Point1;
                otherBottom = parallel2.Point2;
            }

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca1 = new GeometricCongruentAngles(new Angle(off, smallerInter.intersect, otherTop),
                                                                         new Angle(smallerInter.intersect, larger.intersect, largerTop));
            newAngleRelations.Add(gca1);
            GeometricCongruentAngles gca2 = new GeometricCongruentAngles(new Angle(off, smallerInter.intersect, otherBottom),
                                                                         new Angle(smallerInter.intersect, larger.intersect, largerBottom));
            newAngleRelations.Add(gca2);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        // Corresponding angles if:
        //
        //   up  <- may not occur
        //   |_____  offEnd
        //   |
        //   |_____  offStands
        //   |
        //   |
        //  down
        //
        private static List<EdgeAggregator> InstantiateFIntersection(Parallel parallel, Intersection inter1, Point off1, Intersection inter2, Point off2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Point offEnd = null;
            Point offStands = null;
            Intersection endpt = null;
            Intersection stands = null;
            if (inter1.StandsOnEndpoint())
            {
                endpt = inter1;
                offEnd = off1;
                stands = inter2;
                offStands = off2;
            }
            else if (inter2.StandsOnEndpoint())
            {
                endpt = inter2;
                offEnd = off2;
                stands = inter1;
                offStands = off1;
            }

            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment nonParallelEndpt = endpt.GetCollinearSegment(transversal);
            Segment nonParallelStands = stands.GetCollinearSegment(transversal);

            Point down = null;
            Point up = null;
            if (Segment.Between(stands.intersect, nonParallelStands.Point1, endpt.intersect))
            {
                down = nonParallelStands.Point1;
                up = nonParallelStands.Point2;
            }
            else
            {
                down = nonParallelStands.Point2;
                up = nonParallelStands.Point1;
            }

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            if (!down.Equals(stands.intersect))
            {
                GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(offEnd, endpt.intersect, stands.intersect),
                                                                            new Angle(offStands, stands.intersect, down));
                newAngleRelations.Add(gca);
            }

            if (!up.Equals(endpt.intersect))
            {
                GeometricCongruentAngles gcaOptional = new GeometricCongruentAngles(new Angle(up, endpt.intersect, offEnd),
                                                                                    new Angle(endpt.intersect, stands.intersect, offStands));
                newAngleRelations.Add(gcaOptional);
            }

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        //
        // Creates a Topped F-Shape
        //            top
        // oppSide __________       <--- Stands on
        //             |
        //             |_____ off   <--- Stands on
        //             |
        //             |
        //           bottom
        //
        //   Returns: <bottom, off>
        private static List<EdgeAggregator> GenerateToppedFShape(Parallel parallel, Intersection inter1, Intersection inter2, Intersection bottom, Point off)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Intersection top = inter1.Equals(bottom) ? inter2 : inter1;

            // Determine the side of the top intersection needed for the angle
            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment parallelTop = top.OtherSegment(transversal);
            Segment parallelBottom = bottom.OtherSegment(transversal);

            Segment crossingTester = new Segment(off, parallelTop.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);

            Point oppSide = transversal.PointLiesOnAndBetweenEndpoints(intersection) ? parallelTop.Point1 : parallelTop.Point2;

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(off, bottom.intersect, top.intersect),
                                                                        new Angle(oppSide, top.intersect, bottom.intersect));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        //
        // Chair Corresponding
        //
        // |     |                  |
        // |_____|____   leftInter  |_________ tipOfT
        // |                        |     |
        // |                        |     |
        //                         off   tipOfT
        //
        //                                bottomInter
        private static List<EdgeAggregator> InstantiateChairIntersection(Parallel parallel, Intersection inter1, Point off, Intersection inter2, Point bottomTip)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Segment transversal = inter1.AcquireTransversal(inter2);
            Point tipOfT1 = inter1.CreatesTShape();
            Point tipOfT2 = inter2.CreatesTShape();

            Point leftTip = null;
            Intersection leftInter = null;
            Intersection bottomInter = null;

            if (transversal.PointLiesOn(tipOfT1))
            {
                leftInter = inter1;
                bottomInter = inter2;
                leftTip = tipOfT1;
            }
            // thatInter is leftInter
            else if (transversal.PointLiesOn(tipOfT2))
            {
                leftInter = inter2;
                bottomInter = inter1;
                leftTip = tipOfT2;
            }

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            // CTA: Hack fix to alleviate exception thrown from improper congruent constructions.
            GeometricCongruentAngles gca = null;
            try
            {
                gca = new GeometricCongruentAngles(new Angle(leftTip, bottomInter.intersect, bottomTip),
                                                   new Angle(bottomInter.intersect, leftInter.intersect, off));
            }
            catch (Exception e)
            {
                if (Utilities.DEBUG) System.Diagnostics.Debug.WriteLine(e.ToString());

                return newGrounded;
            }

            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        //
        // Creates a shape like an extended t
        //     offCross                          offCross
        //      |                                   |
        // _____|____ sameSide       sameSide ______|______
        //      |                                   |
        //      |_____ offStands     offStands _____|
        //
        // Returns <offStands, offCross>
        private static List<EdgeAggregator> InstantiateCrossedTIntersection(Parallel parallel, Intersection inter1, Intersection inter2, Point offStands, Point offCross)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine which is the crossing intersection and which stands on the endpoints
            //
            Intersection crossingInter = null;
            Intersection standsInter = null;
            if (inter1.Crossing() && inter2.StandsOnEndpoint())
            {
                crossingInter = inter1;
                standsInter = inter2;
            }
            else if (inter2.Crossing() && inter1.StandsOnEndpoint())
            {
                crossingInter = inter2;
                standsInter = inter1;
            }

            // Determine the side of the crossing needed for the angle
            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment parallelStands = standsInter.OtherSegment(transversal);
            Segment parallelCrossing = crossingInter.OtherSegment(transversal);

            Segment crossingTester = new Segment(offStands, parallelCrossing.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);

            Point sameSide = transversal.PointLiesOnAndBetweenEndpoints(intersection) ? parallelCrossing.Point2 : parallelCrossing.Point1;

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(offStands, standsInter.intersect, crossingInter.intersect),
                                                                        new Angle(sameSide, crossingInter.intersect, offCross));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        private static List<EdgeAggregator> CheckAndGeneratePerpendicularImplyCongruentAdjacent(Perpendicular perp, Angle angle1, Angle angle2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            if (!Utilities.CompareValues(angle1.measure, angle2.measure)) return newGrounded;

            // The given angles must belong to the intersection. That is, the vertex must align and all rays must overlay the intersection.
            if (!(perp.InducesNonStraightAngle(angle1) && perp.InducesNonStraightAngle(angle1))) return newGrounded;

            //
            // Now we have perpendicular -> congruent angles scenario
            //
            GeometricCongruentAngles gcas = new GeometricCongruentAngles(angle1, angle2);

            // Construct hyperedge
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(perp);
            antecedent.Add(angle1);
            antecedent.Add(angle2);

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

            return newGrounded;
        }
        // Corresponding angles if:
        //            sameSide offRightEnd
        // standsOn (o)   o       e
        //                o       e    standsOnEndpoint (e)
        // offLeftEnd  eeeoeeeeeeee
        //                o
        //                o
        //
        // Returns <offLeftEnd, offRightEnd>
        //
        private static List<EdgeAggregator> InstantiateSimpleTIntersection(Parallel parallel, Intersection inter1, Intersection inter2, Point offLeftEnd, Point offRightEnd)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine which is the endpoint and stands intersections
            //
            Intersection endpointInter = null;
            Intersection standsInter = null;
            if (inter1.StandsOnEndpoint() && inter2.StandsOn())
            {
                endpointInter = inter1;
                standsInter = inter2;
            }
            else if (inter2.StandsOnEndpoint() && inter1.StandsOn())
            {
                endpointInter = inter2;
                standsInter = inter1;
            }
            else return newGrounded;

            // Determine the sameSide point
            Segment transversal = inter1.AcquireTransversal(inter2);
            Segment parallelStands = standsInter.OtherSegment(transversal);
            Segment crossingTester = new Segment(offRightEnd, parallelStands.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);

            Point sameSide = transversal.PointLiesOnAndBetweenEndpoints(intersection) ? parallelStands.Point2 : parallelStands.Point1;

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(offLeftEnd, standsInter.intersect, sameSide),
                                                                        new Angle(standsInter.intersect, endpointInter.intersect, offRightEnd));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
Esempio n. 26
0
        public static GenericInstantiator.EdgeAggregator GenerateAngleCongruence(Triangle tri, Angle angle)
        {
            //
            // If we have already generated a reflexive congruence, avoid regenerating
            //
            foreach (Angle oldSharedAngle in knownSharedAngles)
            {
                if (oldSharedAngle.Equates(angle)) return null;
            }

            // Generate
            GeometricCongruentAngles gcas = new GeometricCongruentAngles(angle, angle);

            // This is an 'obvious' notion so it should be intrinsic to any figure
            gcas.MakeIntrinsic();

            return new GenericInstantiator.EdgeAggregator(Utilities.MakeList<GroundedClause>(Angle.AcquireFigureAngle(angle)), gcas, reflexAnnotation);
        }
        //               A
        //              /)
        //             /  )
        //            /    )
        // center:   O      )
        //            \    )
        //             \  )
        //              \)
        //               C
        //
        //               D
        //              /)
        //             /  )
        //            /    )
        // center:   Q      )
        //            \    )
        //             \  )
        //              \)
        //               F
        //
        // Congruent(Arc(A, C), Arc(D, F)) -> Congruent(Angle(AOC), Angle(DQF))
        //
        private static List<EdgeAggregator> InstantiateConversePartOfTheorem(CongruentArcs cas)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Get the radii (and determine if the exist in the figure)
            //
            Segment radius11;
            Segment radius12;
            cas.ca1.GetRadii(out radius11, out radius12);

            if (radius11 == null || radius12 == null) return newGrounded;

            Segment radius21;
            Segment radius22;
            cas.ca2.GetRadii(out radius21, out radius22);

            if (radius21 == null || radius22 == null) return newGrounded;

            //
            // Acquire the central angles from the respoitory
            //
            Angle central1 = Angle.AcquireFigureAngle(new Angle(radius11, radius12));
            Angle central2 = Angle.AcquireFigureAngle(new Angle(radius21, radius22));

            if (central1 == null || central2 == null) return newGrounded;

            GeometricCongruentAngles gcas = new GeometricCongruentAngles(central1, central2);

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

            newGrounded.Add(new EdgeAggregator(antecedent, gcas, converseAnnotation));

            return newGrounded;
        }