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;
        }
Beispiel #2
0
        // Return the shared segment in both congruences
        public Segment SegmentShared(CongruentSegments thatCC)
        {
            if (SharesNumClauses(thatCC) != 1)
            {
                return(null);
            }

            return(smallerSegment.Equals(thatCC.cs1) || smallerSegment.Equals(thatCC.cs2) ? smallerSegment : largerSegment);
        }
Beispiel #3
0
        // Return the shared segment in both congruences
        public Segment SegmentShared(CongruentSegments thatCC)
        {
            if (SharesNumClauses(thatCC) != 1)
            {
                return(null);
            }

            return(cs1.Equals(thatCC.cs1) || cs1.Equals(thatCC.cs2) ? cs1 : cs2);
        }
        public static bool AcquireCongruences(KnownMeasurementsAggregator known, List <GroundedClause> clauses)
        {
            bool addedKnown = false;

            foreach (GeometryTutorLib.ConcreteAST.GroundedClause clause in clauses)
            {
                GeometryTutorLib.ConcreteAST.CongruentSegments cs = clause as GeometryTutorLib.ConcreteAST.CongruentSegments;
                if (cs != null && !cs.IsReflexive())
                {
                    double length1 = known.GetSegmentLength(cs.cs1);
                    double length2 = known.GetSegmentLength(cs.cs2);

                    if (length1 >= 0 && length2 < 0)
                    {
                        if (known.AddSegmentLength(cs.cs2, length1))
                        {
                            addedKnown = true;
                        }
                    }
                    if (length1 <= 0 && length2 > 0)
                    {
                        if (known.AddSegmentLength(cs.cs1, length2))
                        {
                            addedKnown = true;
                        }
                    }
                    // else: both known
                }

                GeometryTutorLib.ConcreteAST.CongruentAngles cas = clause as GeometryTutorLib.ConcreteAST.CongruentAngles;
                if (cas != null && !cas.IsReflexive())
                {
                    double measure1 = known.GetAngleMeasure(cas.ca1);
                    double measure2 = known.GetAngleMeasure(cas.ca2);

                    if (measure1 >= 0 && measure2 < 0)
                    {
                        if (known.AddAngleMeasureDegree(cas.ca2, measure1))
                        {
                            addedKnown = true;
                        }
                    }
                    if (measure1 <= 0 && measure2 > 0)
                    {
                        if (known.AddAngleMeasureDegree(cas.ca1, measure2))
                        {
                            addedKnown = true;
                        }
                    }
                    // else: both known
                }
            }

            return(addedKnown);
        }
Beispiel #5
0
        public override bool Equals(Object obj)
        {
            CongruentSegments ccs = obj as CongruentSegments;

            if (ccs == null)
            {
                return(false);
            }

            return((cs1.Equals(ccs.cs1) && cs2.Equals(ccs.cs2)) || (cs1.Equals(ccs.cs2) && cs2.Equals(ccs.cs1)) && base.Equals(obj));
        }
Beispiel #6
0
        // Return the number of shared segments in both congruences
        public int SharesNumClauses(CongruentSegments thatCS)
        {
            //CongruentSegments css = thatPS as CongruentSegments;

            //if (css == null) return 0;

            int numShared = smallerSegment.Equals(thatCS.cs1) || smallerSegment.Equals(thatCS.cs2) ? 1 : 0;

            numShared += largerSegment.Equals(thatCS.cs1) || largerSegment.Equals(thatCS.cs2) ? 1 : 0;

            return(numShared);
        }
Beispiel #7
0
        public override bool StructurallyEquals(Object obj)
        {
            CongruentSegments ccs = obj as CongruentSegments;

            if (ccs == null)
            {
                return(false);
            }

            return((cs1.StructurallyEquals(ccs.cs1) && cs2.StructurallyEquals(ccs.cs2)) ||
                   (cs1.StructurallyEquals(ccs.cs2) && cs2.StructurallyEquals(ccs.cs1)));
        }
Beispiel #8
0
        public Segment SharedSegment(CongruentSegments ccs)
        {
            if (ccs.cs1.StructurallyEquals(this.cs1) || ccs.cs2.StructurallyEquals(this.cs1))
            {
                return(this.cs1);
            }
            if (ccs.cs1.StructurallyEquals(this.cs2) || ccs.cs2.StructurallyEquals(this.cs2))
            {
                return(this.cs2);
            }

            return(null);
        }
Beispiel #9
0
        //
        // Are the legs congruent (for an isosceles trapezoid)?
        //
        public bool CreatesCongruentLegs(CongruentSegments css)
        {
            if (leftLeg.StructurallyEquals(css.cs1) && rightLeg.StructurallyEquals(css.cs2))
            {
                return(true);
            }
            if (leftLeg.StructurallyEquals(css.cs2) && rightLeg.StructurallyEquals(css.cs1))
            {
                return(true);
            }

            return(false);
        }
Beispiel #10
0
        // Return the number of shared segments in both congruences
        public override int SharesNumClauses(Congruent thatCC)
        {
            CongruentSegments ccss = thatCC as CongruentSegments;

            if (ccss == null)
            {
                return(0);
            }

            int numShared = cs1.Equals(ccss.cs1) || cs1.Equals(ccss.cs2) ? 1 : 0;

            numShared += cs2.Equals(ccss.cs1) || cs2.Equals(ccss.cs2) ? 1 : 0;

            return(numShared);
        }
        //
        // 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;
        }
Beispiel #12
0
        public static List <GenericInstantiator.EdgeAggregator> CreateTransitiveCongruence(Congruent congruent1, Congruent congruent2)
        {
            List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>();

            //
            // Create the antecedent clauses
            //
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(congruent1);
            antecedent.Add(congruent2);

            //
            // Create the consequent clause
            //
            Congruent newCC = null;

            if (congruent1 is CongruentSegments)
            {
                CongruentSegments css1 = congruent1 as CongruentSegments;
                CongruentSegments css2 = congruent2 as CongruentSegments;

                Segment shared = css1.SegmentShared(css2);

                newCC = new AlgebraicCongruentSegments(css1.OtherSegment(shared), css2.OtherSegment(shared));
            }
            else if (congruent1 is CongruentAngles)
            {
                CongruentAngles cas1 = congruent1 as CongruentAngles;
                CongruentAngles cas2 = congruent2 as CongruentAngles;

                Angle shared = cas1.AngleShared(cas2);

                newCC = new AlgebraicCongruentAngles(cas1.OtherAngle(shared), cas2.OtherAngle(shared));
            }

            if (newCC == null)
            {
                System.Diagnostics.Debug.WriteLine("");
                throw new NullReferenceException("Unexpected Problem in Atomic substitution...");
            }

            newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newCC, annotation));

            return(newGrounded);
        }
Beispiel #13
0
        //
        // Are the legs congruent (for an isosceles trapezoid)?
        //
        public bool CreatesCongruentLegs(CongruentSegments css)
        {
            if (leftLeg.StructurallyEquals(css.cs1) && rightLeg.StructurallyEquals(css.cs2)) return true;
            if (leftLeg.StructurallyEquals(css.cs2) && rightLeg.StructurallyEquals(css.cs1)) return true;

            return false;
        }
Beispiel #14
0
 public bool SharedVertex(CongruentSegments ccs)
 {
     return(ccs.cs1.SharedVertex(cs1) != null || ccs.cs1.SharedVertex(cs2) != null ||
            ccs.cs2.SharedVertex(cs1) != null || ccs.cs2.SharedVertex(cs2) != null);
 }
Beispiel #15
0
 //
 // Does this congruent pair apply to this quadrilateral?
 //
 public bool HasOppositeCongruentSides(CongruentSegments cs)
 {
     return(AreOppositeSides(cs.cs1, cs.cs2));
 }
        //               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;
        }
Beispiel #17
0
 //
 // Does this congruent pair apply to this quadrilateral?
 //
 public bool HasOppositeCongruentSides(CongruentSegments cs)
 {
     return AreOppositeSides(cs.cs1, cs.cs2);
 }
Beispiel #18
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);
 }
        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;
        }
Beispiel #20
0
        // Of the congruent pair, return the segment that applies to this triangle
        public Segment GetSegment(CongruentSegments ccss)
        {
            if (HasSegment(ccss.cs1)) return ccss.cs1;
            if (HasSegment(ccss.cs2)) return ccss.cs2;

            return null;
        }
Beispiel #21
0
        // Return the number of shared segments in both congruences
        public int SharesNumClauses(CongruentSegments thatCS)
        {
            //CongruentSegments css = thatPS as CongruentSegments;

            //if (css == null) return 0;

            int numShared = smallerSegment.Equals(thatCS.cs1) || smallerSegment.Equals(thatCS.cs2) ? 1 : 0;
            numShared += largerSegment.Equals(thatCS.cs1) || largerSegment.Equals(thatCS.cs2) ? 1 : 0;

            return numShared;
        }
        //
        // 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;
        }
Beispiel #23
0
        // Return the shared segment in both congruences
        public Segment SegmentShared(CongruentSegments thatCC)
        {
            if (SharesNumClauses(thatCC) != 1) return null;

            return smallerSegment.Equals(thatCC.cs1) || smallerSegment.Equals(thatCC.cs2) ? smallerSegment : largerSegment;
        }
        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;
        }
        //
        // 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> 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;
        }
        private static List<EdgeAggregator> InstantiateToTheorem(Quadrilateral quad, CongruentSegments cs, Parallel parallel)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Are the pairs on the opposite side of this quadrilateral?
            if (!quad.HasOppositeCongruentSides(cs)) return newGrounded;
            if (!quad.HasOppositeParallelSides(parallel)) return newGrounded;

            // Do the congruent segments coincide with these parallel segments?
            if (!parallel.segment1.HasSubSegment(cs.cs1) && !parallel.segment2.HasSubSegment(cs.cs1)) return newGrounded;
            if (!parallel.segment1.HasSubSegment(cs.cs2) && !parallel.segment2.HasSubSegment(cs.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(cs);
            antecedent.Add(parallel);

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

            return newGrounded;
        }
Beispiel #28
0
 //
 // Does this parallel set apply to this quadrilateral?
 //
 public bool HasAdjacentCongruentSides(CongruentSegments cs)
 {
     return AreAdjacentSides(cs.cs1, cs.cs2);
 }
Beispiel #29
0
        public Segment SharedSegment(CongruentSegments ccs)
        {
            if (ccs.cs1.StructurallyEquals(this.cs1) || ccs.cs2.StructurallyEquals(this.cs1)) return this.cs1;
            if (ccs.cs1.StructurallyEquals(this.cs2) || ccs.cs2.StructurallyEquals(this.cs2)) return this.cs2;

            return null;
        }
Beispiel #30
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;
        }
Beispiel #31
0
 public bool SharedVertex(CongruentSegments ccs)
 {
     return ccs.cs1.SharedVertex(cs1) != null || ccs.cs1.SharedVertex(cs2) != null ||
            ccs.cs2.SharedVertex(cs1) != null || ccs.cs2.SharedVertex(cs2) != null;
 }
Beispiel #32
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);
 }
Beispiel #33
0
        // Return the shared segment in both congruences
        public Segment SegmentShared(CongruentSegments thatCC)
        {
            if (SharesNumClauses(thatCC) != 1) return null;

            return cs1.Equals(thatCC.cs1) || cs1.Equals(thatCC.cs2) ? cs1 : cs2;
        }
Beispiel #34
0
 //
 // Does this parallel set apply to this quadrilateral?
 //
 public bool HasAdjacentCongruentSides(CongruentSegments cs)
 {
     return(AreAdjacentSides(cs.cs1, cs.cs2));
 }
Beispiel #35
0
        //
        // Checks for ASA given the 5 values
        //
        private static List<EdgeAggregator> InstantiateAAS(Triangle tri1, Triangle tri2,
                                                                                               CongruentAngles cas1, CongruentAngles cas2, CongruentSegments css)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // All congruence pairs must minimally relate the triangles
            //
            if (!cas1.LinksTriangles(tri1, tri2)) return newGrounded;
            if (!cas2.LinksTriangles(tri1, tri2)) return newGrounded;
            if (!css.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 angle1Tri1 = tri1.NormalizeAngle(tri1.AngleBelongs(cas1));
            Angle angle1Tri2 = tri2.NormalizeAngle(tri2.AngleBelongs(cas1));

            Angle angle2Tri1 = tri1.NormalizeAngle(tri1.AngleBelongs(cas2));
            Angle angle2Tri2 = tri2.NormalizeAngle(tri2.AngleBelongs(cas2));

            // The angles for each triangle must be distinct
            if (angle1Tri1.Equals(angle2Tri1) || angle1Tri2.Equals(angle2Tri2)) return newGrounded;

            Segment segTri1 = tri1.GetSegment(css);
            Segment segTri2 = tri2.GetSegment(css);

            // ASA situations
            if (segTri1.IsIncludedSegment(angle1Tri1, angle2Tri1)) return newGrounded;
            if (segTri2.IsIncludedSegment(angle1Tri2, angle2Tri2)) return newGrounded;

            // The segments for each triangle must be corresponding
            if (segTri1.Equals(tri1.OtherSide(angle1Tri1)) && segTri2.Equals(tri2.OtherSide(angle2Tri2))) return newGrounded;
            if (segTri1.Equals(tri1.OtherSide(angle2Tri1)) && segTri2.Equals(tri2.OtherSide(angle1Tri2))) return newGrounded;

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

            triangleOne.Add(angle1Tri1.GetVertex());
            triangleTwo.Add(angle1Tri2.GetVertex());

            triangleOne.Add(angle2Tri1.GetVertex());
            triangleTwo.Add(angle2Tri2.GetVertex());

            // We know the segment endpoint mappings above, now acquire the opposite point
            triangleOne.Add(tri1.OtherPoint(angle1Tri1.GetVertex(), angle2Tri1.GetVertex()));
            triangleTwo.Add(tri2.OtherPoint(angle1Tri2.GetVertex(), angle2Tri2.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(cas1);
            antecedent.Add(cas2);
            antecedent.Add(css);

            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;
        }
Beispiel #36
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;
        }
Beispiel #37
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;
        }
        /// <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;
        }
Beispiel #39
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;
        }
        //
        // 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);
        }
        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;
        }