private static List<EdgeAggregator> InstantiateFromAltitude(GroundedClause clause)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            if (clause is Intersection)
            {
                Intersection inter = clause as Intersection;

                // We are only interested in straight-angle type intersections
                if (inter.StandsOnEndpoint()) return newGrounded;
                if (!inter.IsPerpendicular()) return newGrounded;

                foreach (Altitude altitude in candidateAltitude)
                {
                    newGrounded.AddRange(InstantiateFromAltitude(inter, altitude));
                }

                candidateIntersection.Add(inter);
            }
            else if (clause is Altitude)
            {
                Altitude altitude  = clause as Altitude;

                foreach (Intersection inter in candidateIntersection)
                {
                    newGrounded.AddRange(InstantiateFromAltitude(inter, altitude));
                }

                candidateAltitude.Add(altitude);
            }

            return newGrounded;
        }
        public static void Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.RIGHT_TRIANGLE_DEFINITION;

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

            //
            // Instantiating FROM a right triangle
            //
            Strengthened streng = clause as Strengthened;
            if (streng == null) return;

            if (streng.strengthened is RightTriangle)
            {
                candidateRight.Add(streng);

                foreach (Strengthened iso in candidateIsosceles)
                {
                    InstantiateRightTriangle(streng, iso);
                }
            }
            else if (streng.strengthened is IsoscelesTriangle)
            {
                candidateIsosceles.Add(streng);

                foreach (Strengthened right in candidateRight)
                {
                    InstantiateRightTriangle(right, streng);
                }
            }
        }
        //
        // This implements forward and Backward instantiation
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.PERPENDICULAR_DEFINITION;

            // FROM Perpendicular
            if (clause is Perpendicular) return InstantiateFromPerpendicular(clause, clause as Perpendicular);

            // TO Perpendicular
            if (clause is RightAngle || clause is Intersection) return InstantiateToPerpendicular(clause);

            // Handle Strengthening; may be a Perpendicular (FROM) or Right Angle (TO)

            Strengthened streng = clause as Strengthened;
            if (streng != null)
            {
                if (streng.strengthened is Perpendicular && !(streng.strengthened is PerpendicularBisector))
                {
                    return InstantiateFromPerpendicular(clause, streng.strengthened as Perpendicular);
                }
                else if (streng.strengthened is RightAngle)
                {
                    return InstantiateToPerpendicular(clause);
                }
            }

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

            if (clause is Intersection)
            {
                // Since we receive intersections right away in the instantiation process, just store the intersections
                candidateIntersections.Add(clause as Intersection);
            }
            else if (clause is RightAngle)
            {
                RightAngle ra = clause as RightAngle;

                foreach (Intersection inter in candidateIntersections)
                {
                    newGrounded.AddRange(InstantiateToPerpendicular(inter, ra, clause));
                }
            }
            else if (clause is Strengthened)
            {
                Strengthened streng = clause as Strengthened;

                // Only intrerested in right angles
                if (!(streng.strengthened is RightAngle)) return newGrounded;

                foreach (Intersection inter in candidateIntersections)
                {
                    newGrounded.AddRange(InstantiateToPerpendicular(inter, streng.strengthened as RightAngle, clause));
                }
            }

            return newGrounded;
        }
Beispiel #5
0
        public static List <GenericInstantiator.EdgeAggregator> Instantiate(GroundedClause gc)
        {
            List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>();

            Segment segment = gc as Segment;

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

            // Only generate reflexive if this segment is shared
            if (!segment.isShared())
            {
                return(newGrounded);
            }

            GeometricCongruentSegments ccss = new GeometricCongruentSegments(segment, segment);

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

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

            newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, ccss, reflexAnnotation));

            return(newGrounded);
        }
        //
        // Supplementary(Angle(A, B, D), Angle(B, A, C))
        // Congruent(Angle(A, B, D), Angle(B, A, C)) -> RightAngle(Angle(A, B, D))
        //                                           -> RightAngle(Angle(B, A, C))
        //                            
        //                            C            D
        //                            |            |
        //                            |____________|
        //                            A            B
        //                            
        public static List<EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.CONGRUENT_SUPPLEMENTARY_ANGLES_IMPLY_RIGHT_ANGLES;

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

            if (c is CongruentAngles)
            {
                CongruentAngles conAngles = c as CongruentAngles;

                // We are interested in adjacent angles, not reflexive
                if (conAngles.IsReflexive()) return newGrounded;

                foreach (Supplementary suppAngles in candSupplementary)
                {
                    newGrounded.AddRange(CheckAndGenerateSupplementaryCongruentImplyRightAngles(suppAngles, conAngles));
                }

                candCongruent.Add(conAngles);
            }
            else if (c is Supplementary)
            {
                Supplementary supplementary = c as Supplementary;

                foreach (CongruentAngles cc in candCongruent)
                {
                    newGrounded.AddRange(CheckAndGenerateSupplementaryCongruentImplyRightAngles(supplementary, cc));
                }

                candSupplementary.Add(supplementary);
            }

            return newGrounded;
        }
        //
        // Implements transitivity with Relations (Parallel, Similar)
        // Relation(A, B), Relation(B, C) -> Relation(A, C)
        //
        // Generation of new relations is restricted to the following rules; let G be Geometric and A algebriac
        //     G + G -> A
        //     G + A -> A
        //     A + A -X> A  <- Not allowed
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Do we have appropriate clauses?
            if (!(clause is Parallel) && !(clause is SimilarTriangles)) return newGrounded;

            // Has this clause been generated before?
            // Since generated clauses will eventually be instantiated as well, this will reach a fixed point and stop.
            // Uniqueness of clauses needs to be handled by the class calling this
            if (ClauseHasBeenDeduced(clause)) return newGrounded;

            // A reflexive expression provides no information of interest or consequence.
            if (clause.IsReflexive()) return newGrounded;

            //
            // Process the clause
            //
            if (clause is Parallel)
            {
                newGrounded.AddRange(HandleNewParallelRelation(clause as Parallel));
            }
            else if (clause is SimilarTriangles)
            {
                newGrounded.AddRange(HandleNewSimilarTrianglesRelation(clause as SimilarTriangles));
            }

            // Add the new clause to the right list for later combining
            AddToAppropriateList(clause);

            return newGrounded;
        }
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.CORRESPONDING_ANGLES_OF_PARALLEL_LINES;

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

            if (clause is Parallel)
            {
                Parallel parallel = clause as Parallel;
                for (int i = 0; i < candidateIntersection.Count; i++)
                {
                    for (int j = i + 1; j < candidateIntersection.Count; j++)
                    {
                        newGrounded.AddRange(InstantiateIntersection(parallel, candidateIntersection[i], candidateIntersection[j]));
                    }
                }
                candidateParallel.Add(parallel);
            }
            else if (clause is Intersection)
            {
                Intersection newInter = clause as Intersection;
                foreach (Intersection oldInter in candidateIntersection)
                {
                    foreach (Parallel parallel in candidateParallel)
                    {
                        newGrounded.AddRange(InstantiateIntersection(parallel, newInter, oldInter));
                    }
                }
                candidateIntersection.Add(newInter);
            }

            return newGrounded;
        }
        //
        //    A \      / B
        //       \    /
        //        \  /
        //  O      \/ X
        //         /\
        //        /  \
        //     C /    \ D
        //
        // Intersection(Segment(AD), Segment(BC)) -> 2 * Angle(CXA) = Arc(A, C) + Arc(B, D),
        //                                           2 * Angle(BXD) = Arc(A, C) + Arc(B, D),
        //                                           2 * Angle(AXB) = Arc(A, B) + Arc(C, D),
        //                                           2 * Angle(CXD) = Arc(A, B) + Arc(C, D)
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.TWO_INTERSECTING_CHORDS_ANGLE_MEASURE_HALF_SUM_INTERCEPTED_ARCS;

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

            if (clause is Intersection)
            {
                Intersection newInter = clause as Intersection;

                foreach (Circle circle in candidateCircle)
                {
                    newGrounded.AddRange(InstantiateTheorem(newInter, circle));
                }

                candidateIntersection.Add(newInter);
            }
            else if (clause is Circle)
            {
                Circle circle = clause as Circle;

                foreach (Intersection oldInter in candidateIntersection)
                {
                    newGrounded.AddRange(InstantiateTheorem(oldInter, circle));
                }

                candidateCircle.Add(circle);
            }

            return newGrounded;
        }
Beispiel #10
0
        public override bool CanBeStrengthenedTo(GroundedClause gc)
        {
            Midpoint midpoint = gc as Midpoint;
            if (midpoint == null) return false;

            return this.point.StructurallyEquals(midpoint.point) && this.segment.StructurallyEquals(midpoint.segment);
        }
Beispiel #11
0
        //     B ---------V---------A
        //                 \
        //                  \
        //                   \
        //                    C
        //
        // Median(Segment(V, C), Triangle(C, A, B)) -> Midpoint(V, Segment(B, A))
        //
        private static List<EdgeAggregator> InstantiateFromMedian(GroundedClause clause)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

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

                foreach (Median median in candidateMedian)
                {
                    newGrounded.AddRange(InstantiateFromMedian(im, median));
                }

                candidateInMiddle.Add(im);
            }
            else if (clause is Median)
            {
                Median median = clause as Median;

                foreach (InMiddle im in candidateInMiddle)
                {
                    newGrounded.AddRange(InstantiateFromMedian(im, median));
                }

                candidateMedian.Add(median);
            }

            return newGrounded;
        }
Beispiel #12
0
 public override bool CanBeStrengthenedTo(GroundedClause gc)
 {
     Perpendicular perp = gc as Perpendicular;
     if (perp == null) return false;
     return intersect.Equals(perp.intersect) && ((lhs.StructurallyEquals(perp.lhs) && rhs.StructurallyEquals(perp.rhs)) ||
                                                 (lhs.StructurallyEquals(perp.rhs) && rhs.StructurallyEquals(perp.lhs)));
 }
Beispiel #13
0
        public override bool ContainsClause(GroundedClause clause)
        {
            NumericValue clauseValue = clause as NumericValue;
            if (clauseValue == null) return false;

            return Utilities.CompareValues(value, clauseValue.value);
        }
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.TWO_INTERCEPTED_ARCS_HAVE_CONGRUENT_ANGLES;

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

            if (clause is Angle)
            {
                Angle angle = clause as Angle;

                foreach (Angle candCongruentAngle in candidateAngles)
                {
                    newGrounded.AddRange(InstantiateTheorem(angle, candCongruentAngle));
                }

                candidateAngles.Add(angle);
            }

            else if (clause is Circle)
            {
                Circle circle = clause as Circle;

                for (int i = 0; i < candidateAngles.Count; ++i)
                {
                    for (int j = i + 1; j < candidateAngles.Count; ++j)
                    {
                        newGrounded.AddRange(InstantiateTheorem(candidateAngles[i], candidateAngles[j]));
                    }
                }

            }

            return newGrounded;
        }
Beispiel #15
0
        public static List <GenericInstantiator.EdgeAggregator> Instantiate(GroundedClause clause)
        {
            List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>();

            if (!(clause is AngleEquation))
            {
                return(newGrounded);
            }

            Equation original = clause as Equation;

            Equation     copyEq    = (Equation)original.DeepCopy();
            FlatEquation flattened = new FlatEquation(copyEq.lhs.CollectTerms(), copyEq.rhs.CollectTerms());

            if (flattened.lhsExps.Count == 1 && flattened.rhsExps.Count == 1)
            {
                KeyValuePair <int, int> ratio = Utilities.RationalRatio(flattened.lhsExps[0].multiplier, flattened.rhsExps[0].multiplier);
                if (ratio.Key != -1)
                {
                    if (ratio.Key <= 2 && ratio.Value <= 2)
                    {
                        AlgebraicProportionalAngles prop = new AlgebraicProportionalAngles((Angle)flattened.lhsExps[0].DeepCopy(),
                                                                                           (Angle)flattened.rhsExps[0].DeepCopy());

                        List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(original);
                        newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, prop, atomAnnotation));
                    }
                }
            }

            return(newGrounded);
        }
        //
        // EquilateralTriangle(A, B, C) -> Equation(m \angle ABC = 60),
        //                                 Equation(m \angle BCA = 60),
        //                                 Equation(m \angle CAB = 60)
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.EQUILATERAL_TRIANGLE_HAS_SIXTY_DEGREE_ANGLES;

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

            if (!(c is EquilateralTriangle) && !(c is Strengthened)) return newGrounded;

            EquilateralTriangle eqTri = c as EquilateralTriangle;

            if (c is Strengthened)
            {
                eqTri = (c as Strengthened).strengthened as EquilateralTriangle;
            }

            if (eqTri == null) return newGrounded;

            // EquilateralTriangle(A, B, C) ->
            List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(c);

            //                              -> Equation(m \angle ABC = 60),
            //                                 Equation(m \angle BCA = 60),
            //                                 Equation(m \angle CAB = 60)
            GeometricAngleEquation eq1 = new GeometricAngleEquation(eqTri.AngleA, new NumericValue(60));
            GeometricAngleEquation eq2 = new GeometricAngleEquation(eqTri.AngleB, new NumericValue(60));
            GeometricAngleEquation eq3 = new GeometricAngleEquation(eqTri.AngleC, new NumericValue(60));

            newGrounded.Add(new EdgeAggregator(antecedent, eq1, annotation));
            newGrounded.Add(new EdgeAggregator(antecedent, eq2, annotation));
            newGrounded.Add(new EdgeAggregator(antecedent, eq3, annotation));

            return newGrounded;
        }
        private static List<EdgeAggregator> InstantiateToTheorem(Rhombus rhombus, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

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

            // Instantiate this rhombus diagonals ONLY if the original figure has the diagonals drawn.
            if (rhombus.TopLeftDiagonalIsValid())
            {
                AngleBisector ab1 = new AngleBisector(rhombus.topLeftAngle, rhombus.topLeftBottomRightDiagonal);
                AngleBisector ab2 = new AngleBisector(rhombus.bottomRightAngle, rhombus.topLeftBottomRightDiagonal);
                newGrounded.Add(new EdgeAggregator(antecedent, ab1, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, ab2, annotation));
            }

            if (rhombus.BottomRightDiagonalIsValid())
            {
                AngleBisector ab1 = new AngleBisector(rhombus.topRightAngle, rhombus.bottomLeftTopRightDiagonal);
                AngleBisector ab2 = new AngleBisector(rhombus.bottomLeftAngle, rhombus.bottomLeftTopRightDiagonal);
                newGrounded.Add(new EdgeAggregator(antecedent, ab1, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, ab2, annotation));
            }

            return newGrounded;
        }
Beispiel #18
0
        //
        // In an attempt to avoid issues, all terms collected are copies of the originals.
        //
        public override List <GroundedClause> CollectTerms()
        {
            List <GroundedClause> list = new List <GroundedClause>();

            if (leftExp is NumericValue && rightExp is NumericValue)
            {
                list.Add(new NumericValue((leftExp as NumericValue).DoubleValue * (rightExp as NumericValue).DoubleValue));
                return(list);
            }

            if (leftExp is NumericValue)
            {
                foreach (GroundedClause gc in rightExp.CollectTerms())
                {
                    GroundedClause copyGC = gc.DeepCopy();

                    copyGC.multiplier *= ((NumericValue)leftExp).IntValue;
                    list.Add(copyGC);
                }
            }

            if (rightExp is NumericValue)
            {
                foreach (GroundedClause gc in leftExp.CollectTerms())
                {
                    GroundedClause copyGC = gc.DeepCopy();

                    copyGC.multiplier *= ((NumericValue)rightExp).IntValue;
                    list.Add(copyGC);
                }
            }

            return(list);
        }
        //         B ____________________ C
        //          /                   /
        //         /                   /
        //        / Circle (center)   /
        //       /        O          /
        //      /                   /
        //   A /___________________/ D
        //
        // Circle(O), Quad(A, B, C, D) -> Supplementary(Angle(ABC), Angle(ADC)), Supplementary(Angle(BAD), Angle(BCD))
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.INSCRIBED_QUADRILATERAL_OPPOSITE_ANGLES_SUPPLEMENTARY;

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

            Circle circle = clause as Circle;

            if (circle == null) return newGrounded;

            //
            // For each inscribed quadrilateral, generate accordingly.
            //
            foreach (Quadrilateral quad in circle.inscribedPolys[Polygon.QUADRILATERAL_INDEX])
            {
                Supplementary supp1 = new Supplementary(quad.topLeftAngle, quad.bottomRightAngle);
                Supplementary supp2 = new Supplementary(quad.bottomLeftAngle, quad.topRightAngle);

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

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

            return newGrounded;
        }
        //
        // In order for two triangles to be congruent, we require the following:
        //    RightTriangle(A, B, C) -> Complementary(Angle(B, A, C), Angle(A, C, B))
        //     A
        //    | \
        //    |  \
        //    |   \
        //    |    \
        //    |_____\
        //    B      C
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.ACUTE_ANGLES_IN_RIGHT_TRIANGLE_ARE_COMPLEMENTARY;

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

            if (!(c is Triangle) && !(c is Strengthened)) return newGrounded;

            if (c is Triangle)
            {
                Triangle tri = c as Triangle;

                if (!(tri is RightTriangle))
                {
                    if (!tri.provenRight) return newGrounded;
                }
                newGrounded.AddRange(InstantiateRightTriangle(tri, c));
            }

            if (c is Strengthened)
            {
                Strengthened streng = c as Strengthened;

                if (!(streng.strengthened is RightTriangle)) return newGrounded;

                newGrounded.AddRange(InstantiateRightTriangle(streng.strengthened as RightTriangle, c));
            }

            return newGrounded;
        }
        //     /        A
        //    /         |)
        //   /          | )
        //  /           |  )
        // Q------- O---X---) D
        //   \          |  )
        //    \         | )
        //     \        |)
        //      \        C
        //
        // Inscribed Angle(AQC) -> Angle(AQC) = 2 * Arc(AC)
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.MEASURE_INSCRIBED_ANGLE_EQUAL_HALF_INTERCEPTED_ARC;

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

            if (clause is Angle)
            {
                Angle angle = clause as Angle;

                foreach (Circle circle in candidateCircles)
                {
                    newGrounded.AddRange(InstantiateTheorem(circle, angle));
                }

                candidateAngles.Add(angle);
            }
            else if (clause is Circle)
            {
                Circle circle = clause as Circle;

                foreach (Angle angle in candidateAngles)
                {
                    newGrounded.AddRange(InstantiateTheorem(circle, angle));
                }

                candidateCircles.Add(circle);
            }

            return newGrounded;
        }
        //
        // AngleBisector(SegmentA, D), Angle(C, A, B)) -> 2 m\angle CAD = m \angle CAB,
        //                                                2 m\angle BAD = m \angle CAB
        //
        //   A ________________________B
        //    |\
        //    | \
        //    |  \
        //    |   \
        //    |    \
        //    C     D
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.ANGLE_BISECTOR_THEOREM;

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

            if (!(c is AngleBisector)) return newGrounded;

            AngleBisector angleBisector = c as AngleBisector;
            KeyValuePair<Angle, Angle> adjacentAngles = angleBisector.GetBisectedAngles();

            // Construct 2 m\angle CAD
            Multiplication product1 = new Multiplication(new NumericValue(2), adjacentAngles.Key);
            // Construct 2 m\angle BAD
            Multiplication product2 = new Multiplication(new NumericValue(2), adjacentAngles.Value);

            // 2X = AB
            GeometricAngleEquation newEq1 = new GeometricAngleEquation(product1, angleBisector.angle);
            GeometricAngleEquation newEq2 = new GeometricAngleEquation(product2, angleBisector.angle);

            // For hypergraph
            List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(angleBisector);

            newGrounded.Add(new EdgeAggregator(antecedent, newEq1, annotation));
            newGrounded.Add(new EdgeAggregator(antecedent, newEq2, annotation));

            return newGrounded;
        }
        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));
        }
Beispiel #24
0
 public void AddGeneralPredecessor(GroundedClause gc)
 {
     if (gc.clauseId == -1)
     {
         Debug.WriteLine("ERROR: id is -1: " + gc.ToString());
     }
     Utilities.AddUnique(generalPredecessors, gc.clauseId);
 }
Beispiel #25
0
 public static void Record(GroundedClause clause)
 {
     // Record uniquely? For right angles, etc?
     if (clause is Quadrilateral)
     {
         figureQuadrilaterals.Add(clause as Quadrilateral);
     }
 }
Beispiel #26
0
 public static void Record(GroundedClause clause)
 {
     // Record uniquely? For right angles, etc?
     if (clause is Point)
     {
         figurePoints.Add(clause as Point);
     }
 }
        //
        // Given a list of grounded clauses, get the structurally unique.
        //
        public GroundedClause Get(GroundedClause clause)
        {
            if (clause is GeometryTutorLib.ConcreteAST.Point)
            {
                return GeometryTutorLib.Utilities.GetStructurally<GeometryTutorLib.ConcreteAST.Point>(implied.points, clause as GeometryTutorLib.ConcreteAST.Point);
            }
            else if (clause is GeometryTutorLib.ConcreteAST.Segment)
            {
                return GeometryTutorLib.Utilities.GetStructurally<GeometryTutorLib.ConcreteAST.Segment>(implied.segments, clause as GeometryTutorLib.ConcreteAST.Segment);
            }
            else if (clause is Intersection)
            {
                return GeometryTutorLib.Utilities.GetStructurally<Intersection>(implied.ssIntersections, clause as Intersection);
            }
            else if (clause is CircleCircleIntersection)
            {
                return GeometryTutorLib.Utilities.GetStructurally<CircleCircleIntersection>(implied.ccIntersections, clause as CircleCircleIntersection);
            }
            else if (clause is CircleSegmentIntersection)
            {
                return GeometryTutorLib.Utilities.GetStructurally<CircleSegmentIntersection>(implied.csIntersections, clause as CircleSegmentIntersection);
            }
            else if (clause is Angle)
            {
                return GeometryTutorLib.Utilities.GetStructurally<Angle>(implied.angles, clause as Angle);
            }
            else if (clause is InMiddle)
            {
                return GeometryTutorLib.Utilities.GetStructurally<InMiddle>(implied.inMiddles, clause as InMiddle);
            }
            else if (clause is MinorArc)
            {
                return GeometryTutorLib.Utilities.GetStructurally<MinorArc>(implied.minorArcs, clause as MinorArc);
            }
            else if (clause is Semicircle)
            {
                return GeometryTutorLib.Utilities.GetStructurally<Semicircle>(implied.semiCircles, clause as Semicircle);
            }
            else if (clause is MajorArc)
            {
                return GeometryTutorLib.Utilities.GetStructurally<MajorArc>(implied.majorArcs, clause as MajorArc);
            }
            else if (clause is ArcInMiddle)
            {
                return GeometryTutorLib.Utilities.GetStructurally<ArcInMiddle>(implied.arcInMiddle, clause as ArcInMiddle);
            }

            else if (clause is Triangle)
            {
                return GeometryTutorLib.Utilities.GetStructurally<GeometryTutorLib.ConcreteAST.Polygon>(implied.polygons[GeometryTutorLib.ConcreteAST.Polygon.TRIANGLE_INDEX], clause as GeometryTutorLib.ConcreteAST.Polygon);
            }
            else if (clause is Quadrilateral)
            {
                return GeometryTutorLib.Utilities.GetStructurally<GeometryTutorLib.ConcreteAST.Polygon>(implied.polygons[GeometryTutorLib.ConcreteAST.Polygon.QUADRILATERAL_INDEX], clause as GeometryTutorLib.ConcreteAST.Polygon);
            }

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

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

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

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

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

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

                candidateTriangles.Add(newTriangle);
            }

            return newGrounded;
        }
Beispiel #29
0
        public override bool Equals(object obj)
        {
            GroundedClause that = obj as GroundedClause;

            if (that == null)
            {
                return(false);
            }
            return(multiplier == that.multiplier); // && clauseId == that.clauseId;
        }
Beispiel #30
0
        //
        // Midpoint(M, Segment(A, B)) -> 2AM = AB, 2BM = AB          A ------------- M ------------- B
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.MIDPOINT_THEOREM;

            if (clause is Midpoint) return InstantiateMidpointTheorem(clause, clause as Midpoint);

            if ((clause as Strengthened).strengthened is Midpoint) return InstantiateMidpointTheorem(clause, (clause as Strengthened).strengthened as Midpoint);

            return new List<EdgeAggregator>();
        }
Beispiel #31
0
        public AngleArcEquation(GroundedClause l, GroundedClause r) : base(l, r)
        {
            double sumL = SumSide(l.CollectTerms());
            double sumR = SumSide(r.CollectTerms());

            if (!Utilities.CompareValues(sumL, sumR))
            {
                throw new ArgumentException("Angle-Arc equation is inaccurate; sums differ: " + l + " " + r);
            }
        }
        //
        // This implements forward and Backward instantiation
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.SEGMENT_BISECTOR_DEFINITION;

            if (clause is SegmentBisector || clause is Strengthened || clause is InMiddle) return InstantiateFromSegmentBisector(clause);

            if (clause is Intersection || clause is CongruentSegments) return InstantiateToSegmentBisector(clause);

            return new List<EdgeAggregator>();
        }
        //
        // This implements forward and Backward instantiation
        // Forward is Midpoint -> Congruent Clause
        // Backward is Congruent -> Midpoint Clause
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.ANGLE_BISECTOR_DEFINITION;

            if (c is AngleBisector) return InstantiateBisector(c as AngleBisector);

            if (c is CongruentAngles || c is Segment) return InstantiateCongruent(c);

            return new List<EdgeAggregator>();
        }
Beispiel #34
0
        public AngleEquation(GroundedClause l, GroundedClause r)
            : base(l, r)
        {
            double sumL = SumSide(l.CollectTerms());
            double sumR = SumSide(r.CollectTerms());

            if (!Utilities.CompareValues(sumL, sumR))
            {
                throw new ArgumentException("Angle equation is inaccurate; sums differ: " + l + " " + r);
            }
        }
Beispiel #35
0
        public override bool ContainsClause(GroundedClause clause)
        {
            NumericValue clauseValue = clause as NumericValue;

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

            return(Utilities.CompareValues(value, clauseValue.value));
        }
        //
        // This implements forward and Backward instantiation
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            if (clause is Complementary) return InstantiateFromComplementary(clause as Complementary);

            if (clause is RightAngle || clause is Strengthened || clause is AngleEquation)
            {
                return InstantiateToComplementary(clause);
            }

            return new List<EdgeAggregator>();
        }
Beispiel #37
0
        public override bool CanBeStrengthenedTo(GroundedClause gc)
        {
            Perpendicular perp = gc as Perpendicular;

            if (perp == null)
            {
                return(false);
            }
            return(intersect.Equals(perp.intersect) && ((lhs.StructurallyEquals(perp.lhs) && rhs.StructurallyEquals(perp.rhs)) ||
                                                        (lhs.StructurallyEquals(perp.rhs) && rhs.StructurallyEquals(perp.lhs))));
        }
Beispiel #38
0
        public override bool CanBeStrengthenedTo(GroundedClause gc)
        {
            Midpoint midpoint = gc as Midpoint;

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

            return(this.point.StructurallyEquals(midpoint.point) && this.segment.StructurallyEquals(midpoint.segment));
        }
Beispiel #39
0
        public override bool CanBeStrengthenedTo(GroundedClause gc)
        {
            RightAngle ra = gc as RightAngle;

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

            return(this.StructurallyEquals(ra));
        }
        //
        // Generate Proportional relationships only if those proportions may be used by a figure (in this case, only triangles)
        //
        //    Triangle(A, B, C), Triangle(D, E, F),
        //    
        //    Congruent(Segment(A, B), Segment(B, C)), Congruent(Segment(D, E), Segment(E, F)) -> Similar(Triangle(A, B, C), Triangle(D, E, F)),
        //                                                  Proportional(Segment(A, B), Segment(D, E)),
        //                                                  Proportional(Segment(A, B), Segment(E, F)),
        //                                                  Proportional(Segment(B, C), Segment(D, E)),
        //                                                  Proportional(Segment(B, C), Segment(E, F)),
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.CONGRUENT_SEGMENTS_IMPLY_PROPORTIONAL_SEGMENTS_DEFINITION;

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

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

            // If this is a new triangle, check for triangles which may be Similar to this new triangle
            if (c is Triangle)
            {
                Triangle candidateTri = c as Triangle;

                foreach (Triangle oldTriangle in candidateTriangles)
                {
                    for (int m = 0; m < candidateCongruentSegments.Count - 1; m++)
                    {
                        for (int n = m + 1; n < candidateCongruentSegments.Count; n++)
                        {
                            newGrounded.AddRange(IfCongruencesApplyToTrianglesGenerate(candidateTri, oldTriangle, candidateCongruentSegments[m], candidateCongruentSegments[n]));
                        }
                    }
                }

                // Add this triangle to the list of possible clauses to unify later
                candidateTriangles.Add(candidateTri);
            }
            //
            // Two sets of congruent segments can lead to proportionality
            //
            else if (c is CongruentSegments)
            {
                CongruentSegments newCss = c as CongruentSegments;

                // Avoid reflexive relationships since they will not lead to interesting proportional relationships
                if (newCss.IsReflexive()) return newGrounded;

                for (int i = 0; i < candidateTriangles.Count - 1; i++)
                {
                    for (int j = i + 1; j < candidateTriangles.Count; j++)
                    {
                        foreach (CongruentSegments css in candidateCongruentSegments)
                        {
                            newGrounded.AddRange(IfCongruencesApplyToTrianglesGenerate(candidateTriangles[i], candidateTriangles[j], css, newCss));
                        }
                    }
                }

                candidateCongruentSegments.Add(newCss);
            }

            return newGrounded;
        }
Beispiel #41
0
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.CIRCLE_DEFINITION;

            if (clause is Circle)
            {
                return InstantiateFromDefinition(clause as Circle);
            }

            return new List<EdgeAggregator>();
        }
Beispiel #42
0
        //
        // This implements forward and Backward instantiation
        //
        public static List<EdgeAggregator> Instantiate(GroundedClause clause)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.MEDIAN_DEFINITION;

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

            if (clause is Median || clause is InMiddle) newGrounded.AddRange(InstantiateFromMedian(clause));

            if (clause is SegmentBisector || clause is Triangle || clause is Strengthened) newGrounded.AddRange(InstantiateToMedian(clause));

            return newGrounded;
        }
Beispiel #43
0
        public SegmentEquation(GroundedClause l, GroundedClause r) : base(l, r)
        {
            double sumL = SumSide(l.CollectTerms());
            double sumR = SumSide(r.CollectTerms());

            //if (!Utilities.CompareValues(sumL, sumR))
            //{
            //    throw new ArgumentException("Segment equation is inaccurate; sums differ: " + l + " = " + r);
            //}
            if (Utilities.CompareValues(sumL, 0) && Utilities.CompareValues(sumR, 0))
            {
                throw new ArgumentException("Should not have an equation that is 0 = 0: " + this.ToString());
            }
        }
Beispiel #44
0
        public override List <GroundedClause> CollectTerms()
        {
            List <GroundedClause> list = new List <GroundedClause>();

            list.AddRange(leftExp.CollectTerms());

            foreach (GroundedClause gc in rightExp.CollectTerms())
            {
                GroundedClause copyGC = gc.DeepCopy();

                list.Add(copyGC);
            }

            return(list);
        }
Beispiel #45
0
 public static void Record(GroundedClause clause)
 {
     if (clause is MinorArc)
     {
         figureMinorArcs.Add(clause as MinorArc);
     }
     if (clause is MajorArc)
     {
         figureMajorArcs.Add(clause as MajorArc);
     }
     if (clause is Semicircle)
     {
         figureSemicircles.Add(clause as Semicircle);
     }
 }
Beispiel #46
0
        public static List <GenericInstantiator.EdgeAggregator> InstantiateProportion(GroundedClause clause)
        {
            List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>();

            ProportionalAngles propAngs = clause as ProportionalAngles;

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

            // Do not generate equations based on 'forced' proportions
            if (propAngs.proportion.Key == -1 || propAngs.proportion.Value == -1)
            {
                return(newGrounded);
            }

            // Create a product on the left hand side
            Multiplication productLHS = new Multiplication(new NumericValue(propAngs.proportion.Key), propAngs.smallerAngle.DeepCopy());

            // Create a product on the right hand side, if it applies.
            GroundedClause rhs = propAngs.largerAngle.DeepCopy();

            if (propAngs.proportion.Value > 1)
            {
                rhs = new Multiplication(new NumericValue(propAngs.proportion.Key), rhs);
            }

            //
            // Create the equation
            //
            Equation newEquation = null;

            if (propAngs is AlgebraicProportionalAngles)
            {
                newEquation = new AlgebraicAngleEquation(productLHS, rhs);
            }
            else if (propAngs is GeometricProportionalAngles)
            {
                newEquation = new GeometricAngleEquation(productLHS, rhs);
            }

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

            newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newEquation, defAnnotation));

            return(newGrounded);
        }
Beispiel #47
0
        //public Equation(GroundedClause l, GroundedClause r, string just) : base()
        //{
        //    lhs = l;
        //    rhs = r;
        //    justification = just;
        //}

        public override void Substitute(GroundedClause toFind, GroundedClause toSub)
        {
            if (lhs.Equals(toFind))
            {
                lhs = toSub.DeepCopy();
            }
            else
            {
                lhs.Substitute(toFind, toSub);
            }

            if (rhs.Equals(toFind))
            {
                rhs = toSub.DeepCopy();
            }
            else
            {
                rhs.Substitute(toFind, toSub);
            }
        }
Beispiel #48
0
        public override void Substitute(GroundedClause toFind, GroundedClause toSub)
        {
            if (leftExp.Equals(toFind))
            {
                leftExp = toSub;
            }
            else
            {
                leftExp.Substitute(toFind, toSub);
            }

            if (rightExp.Equals(toFind))
            {
                rightExp = toSub;
            }
            else
            {
                rightExp.Substitute(toFind, toSub);
            }
        }
Beispiel #49
0
        public static List <GenericInstantiator.EdgeAggregator> Instantiate(GroundedClause pred, GroundedClause c)
        {
            List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>();

            if (c is Angle)
            {
                return(newGrounded);
            }

            //Angle angle = c as Angle;

            //if (IsSpecialAngle(angle.measure))
            //{
            //    GeometricAngleEquation angEq = new GeometricAngleEquation(angle, new NumericValue((int)angle.measure), "Given:tbd");
            //    List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(pred);
            //    newClauses.Add(new EdgeAggregator(antecedent, angEq));
            //}

            return(newGrounded);
        }
        //
        // Generate all corresponding conngruent components.
        // Ensure vertices correpsond appropriately.
        //
        public static List <GenericInstantiator.EdgeAggregator> Instantiate(GroundedClause clause)
        {
            List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>();

            CongruentTriangles conTris = clause as CongruentTriangles;

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

            List <Point> orderedTriOnePts = new List <Point>();
            List <Point> orderedTriTwoPts = new List <Point>();

            if (!conTris.VerifyCongruentTriangles(out orderedTriOnePts, out orderedTriTwoPts))
            {
                return(newGrounded);
            }

            return(GenerateCPCTC(conTris, orderedTriOnePts, orderedTriTwoPts));
        }
        //
        // Modify the given information to account for redundancy in stated nodes
        // That is, does given information strengthen a figure node?
        //
        private List <ConcreteAST.GroundedClause> DoGivensStrengthenFigure()
        {
            List <ConcreteAST.GroundedClause> modifiedGivens = new List <ConcreteAST.GroundedClause>();

            ConcreteAST.GroundedClause currentGiven = null;

            foreach (ConcreteAST.GroundedClause given in givens)
            {
                currentGiven = given;
                foreach (ConcreteAST.GroundedClause component in figure)
                {
                    if (component.CanBeStrengthenedTo(given))
                    {
                        currentGiven = new ConcreteAST.Strengthened(component, given);
                        break;
                    }
                }
                modifiedGivens.Add(currentGiven);
            }

            return(modifiedGivens);
        }
 public GeometricSegmentEquation(GroundedClause l, GroundedClause r) : base(l, r)
 {
 }
Beispiel #53
0
 public override bool ContainsClause(GroundedClause target)
 {
     // If a composite node, check accordingly; this will return false if they are atomic
     return(lhs.ContainsClause(target) || rhs.ContainsClause(target));
 }
Beispiel #54
0
 public Subtraction(GroundedClause l, GroundedClause r) : base(l, r)
 {
 }
Beispiel #55
0
 public Equation(GroundedClause l, GroundedClause r) : base()
 {
     lhs = l;
     rhs = r;
 }
 public AlgebraicSegmentEquation(GroundedClause l, GroundedClause r) : base(l, r)
 {
 }
Beispiel #57
0
 public override bool ContainsClause(GroundedClause target)
 {
     return(this.Equals(target));
 }
Beispiel #58
0
        // Acquire the index of the clause in the hypergraph based only on structure
        public static int StructuralIndex(Hypergraph.Hypergraph <ConcreteAST.GroundedClause, Hypergraph.EdgeAnnotation> graph, ConcreteAST.GroundedClause g)
        {
            //
            // Handle general case
            //
            List <Hypergraph.HyperNode <ConcreteAST.GroundedClause, Hypergraph.EdgeAnnotation> > vertices = graph.vertices;

            for (int v = 0; v < vertices.Count; v++)
            {
                if (vertices[v].data.StructurallyEquals(g))
                {
                    return(v);
                }

                if (vertices[v].data is ConcreteAST.Strengthened)
                {
                    if ((vertices[v].data as ConcreteAST.Strengthened).strengthened.StructurallyEquals(g))
                    {
                        return(v);
                    }
                }
            }

            //
            // Handle strengthening by seeing if the clause is found without a 'strengthening' component
            //
            ConcreteAST.Strengthened streng = g as ConcreteAST.Strengthened;
            if (streng != null)
            {
                int index = StructuralIndex(graph, streng.strengthened);
                if (index != -1)
                {
                    return(index);
                }
            }

            return(-1);
        }
Beispiel #59
0
 public Multiplication(GroundedClause l, GroundedClause r) : base(l, r)
 {
 }
Beispiel #60
0
 public GeometricArcEquation(GroundedClause l, GroundedClause r) : base(l, r)
 {
 }