Пример #1
0
        //
        // Main instantiation function for all figures stated in the given list; worklist technique to construct the graph
        //
        public Hypergraph <GroundedClause, Hypergraph.EdgeAnnotation> Instantiate(List <ConcreteAST.GroundedClause> figure, List <ConcreteAST.GroundedClause> givens)
        {
            // The worklist initialized to initial set of ground clauses from the figure
            List <GroundedClause> worklist = new List <GroundedClause>(figure);

            worklist.AddRange(givens);

            // Add all initial elements to the graph
            figure.ForEach(g => { graph.AddNode(g); g.SetID(graph.Size()); });
            givens.ForEach(g => { graph.AddNode(g); g.SetID(graph.Size()); });

            // Indicate all figure-based information is intrinsic; this needs to verified with the UI
            figure.ForEach(f => f.MakeIntrinsic());

            // For problem generation, indicate that all given information is intrinsic
            givens.ForEach(g => g.MakeGiven());

            // Calculates Coverage of the figure
            //HandleAllFigureIntrinsicFacts(figure);

            HandleAllGivens(figure, givens);

            //
            // Process all new clauses until the worklist is empty
            //
            int numSequentialEquations = 0;

            while (worklist.Any())
            {
                // Acquire the first element from the list for processing
                GroundedClause clause = worklist[0];
                worklist.RemoveAt(0);

                if (Utilities.DEBUG)
                {
                    Debug.WriteLine("Working on: " + clause.clauseId + " " + clause.ToString());
                }

                //
                // Cutoff counter; seek a bunch of equations in sequence.
                //
                int NUMEQUATIONS_FOR_CUTOFF = 50;

                if (clause is Equation || clause.IsAlgebraic() || clause is Supplementary)
                {
                    numSequentialEquations++;
                }
                else
                {
                    numSequentialEquations = 0;
                }

                if (numSequentialEquations >= NUMEQUATIONS_FOR_CUTOFF)
                {
                    return(graph);
                }

                if (graph.Size() > 800)
                {
                    return(graph);
                }

                //
                // Apply the clause to all applicable instantiators
                //
                if (clause is Point)
                {
                    Point.Record(clause);
                }
                else if (clause is Angle)
                {
                    // A list of all problem angles
                    Angle.Record(clause);

                    if (clause is RightAngle)
                    {
                        HandleDeducedClauses(worklist, RightAngleDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, PerpendicularDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, ComplementaryDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, RightTriangleDefinition.Instantiate(clause));
                    }
                    HandleDeducedClauses(worklist, ExteriorAngleEqualSumRemoteAngles.Instantiate(clause));
                    // HandleDeducedClauses(worklist, AngleAdditionAxiom.Instantiate(clause));

                    //HandleDeducedClauses(worklist, ConcreteAngle.Instantiate(null, clause));
                    //HandleDeducedClauses(worklist, AngleBisector.Instantiate(clause));

                    HandleDeducedClauses(worklist, PerpendicularImplyCongruentAdjacentAngles.Instantiate(clause));
                    HandleDeducedClauses(worklist, AdjacentAnglesPerpendicularImplyComplementary.Instantiate(clause));

                    // Circle
                    HandleDeducedClauses(worklist, AngleInscribedSemiCircleIsRight.Instantiate(clause));
                    HandleDeducedClauses(worklist, InscribedAngleHalfInterceptedArc.Instantiate(clause));
                    HandleDeducedClauses(worklist, CentralAngleEqualInterceptedArc.Instantiate(clause));
                    HandleDeducedClauses(worklist, ChordTangentAngleHalfInterceptedArc.Instantiate(clause));
                    HandleDeducedClauses(worklist, TwoInterceptedArcsHaveCongruentAngles.Instantiate(clause));
                }
                else if (clause is Arc)
                {
                    Arc.Record(clause);

                    if (clause is Semicircle)
                    {
                        HandleDeducedClauses(worklist, AngleInscribedSemiCircleIsRight.Instantiate(clause));
                    }
                }
                else if (clause is Segment)
                {
                    HandleDeducedClauses(worklist, Segment.Instantiate(clause));
                    HandleDeducedClauses(worklist, AngleBisectorDefinition.Instantiate(clause));
                    Segment.Record(clause);
                }
                else if (clause is InMiddle)
                {
                    HandleDeducedClauses(worklist, SegmentAdditionAxiom.Instantiate(clause));
                    HandleDeducedClauses(worklist, MidpointDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, MedianDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, SegmentBisectorDefinition.Instantiate(clause));
                }
                else if (clause is ArcInMiddle)
                {
                    // HandleDeducedClauses(worklist, ArcAdditionAxiom.Instantiate(clause));
                }
                else if (clause is Intersection)
                {
                    HandleDeducedClauses(worklist, AltitudeDefinition.Instantiate(clause));

                    if (clause is PerpendicularBisector)
                    {
                        HandleDeducedClauses(worklist, PerpendicularBisectorDefinition.Instantiate(clause));
                    }
                    else if (clause is Perpendicular)
                    {
                        HandleDeducedClauses(worklist, PerpendicularImplyCongruentAdjacentAngles.Instantiate(clause));
                        HandleDeducedClauses(worklist, AdjacentAnglesPerpendicularImplyComplementary.Instantiate(clause));
                        HandleDeducedClauses(worklist, TransversalPerpendicularToParallelImplyBothPerpendicular.Instantiate(clause));
                        HandleDeducedClauses(worklist, PerpendicularDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, PerpendicularToRadiusIsTangent.Instantiate(clause));
                    }
                    else
                    {
                        HandleDeducedClauses(worklist, VerticalAnglesTheorem.Instantiate(clause));
                        HandleDeducedClauses(worklist, AltIntCongruentAnglesImplyParallel.Instantiate(clause));
                        HandleDeducedClauses(worklist, SameSideSuppleAnglesImplyParallel.Instantiate(clause));
                        HandleDeducedClauses(worklist, TriangleProportionality.Instantiate(clause));
                        HandleDeducedClauses(worklist, SegmentBisectorDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, CorrespondingAnglesOfParallelLines.Instantiate(clause));
                        HandleDeducedClauses(worklist, CongruentCorrespondingAnglesImplyParallel.Instantiate(clause));
                        HandleDeducedClauses(worklist, CongruentAdjacentAnglesImplyPerpendicular.Instantiate(clause));
                        HandleDeducedClauses(worklist, AngleBisectorIsPerpendicularBisectorInIsosceles.Instantiate(clause));
                        HandleDeducedClauses(worklist, TransversalPerpendicularToParallelImplyBothPerpendicular.Instantiate(clause));
                        HandleDeducedClauses(worklist, ParallelImplyAltIntCongruentAngles.Instantiate(clause));
                        HandleDeducedClauses(worklist, ParallelImplySameSideInteriorSupplementary.Instantiate(clause));
                        HandleDeducedClauses(worklist, PerpendicularDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, MedianDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, SupplementaryDefinition.Instantiate(clause));

                        // Quad Theorems
                        HandleDeducedClauses(worklist, DiagonalsParallelogramBisectEachOther.Instantiate(clause));

                        // Circles
                        HandleDeducedClauses(worklist, ChordTangentAngleHalfInterceptedArc.Instantiate(clause));
                        HandleDeducedClauses(worklist, DiameterPerpendicularToChordBisectsChordAndArc.Instantiate(clause));
                        HandleDeducedClauses(worklist, ExteriorAngleHalfDifferenceInterceptedArcs.Instantiate(clause));
                        HandleDeducedClauses(worklist, TangentPerpendicularToRadius.Instantiate(clause));
                        HandleDeducedClauses(worklist, TangentsToCircleFromPointAreCongruent.Instantiate(clause));
                        HandleDeducedClauses(worklist, TwoChordsAnglesHalfSumInterceptedArc.Instantiate(clause));
                    }
                }
                else if (clause is Complementary)
                {
                    HandleDeducedClauses(worklist, RelationsOfCongruentAnglesAreCongruent.Instantiate(clause));
                    HandleDeducedClauses(worklist, ComplementaryDefinition.Instantiate(clause));
                }
                else if (clause is Altitude)
                {
                    HandleDeducedClauses(worklist, AltitudeDefinition.Instantiate(clause));
                }
                else if (clause is AngleBisector)
                {
                    HandleDeducedClauses(worklist, AngleBisectorDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, AngleBisectorTheorem.Instantiate(clause));
                    HandleDeducedClauses(worklist, AngleBisectorIsPerpendicularBisectorInIsosceles.Instantiate(clause));
                }
                else if (clause is Supplementary)
                {
                    HandleDeducedClauses(worklist, SameSideSuppleAnglesImplyParallel.Instantiate(clause));
                    HandleDeducedClauses(worklist, RelationsOfCongruentAnglesAreCongruent.Instantiate(clause));
                    HandleDeducedClauses(worklist, SupplementaryAndCongruentImplyRightAngles.Instantiate(clause));
                }
                else if (clause is SegmentRatio)
                {
                    HandleDeducedClauses(worklist, TransitiveSubstitution.Instantiate(clause)); // Simplifies as well
                }
                else if (clause is Equation)
                {
                    HandleDeducedClauses(worklist, TransitiveSubstitution.Instantiate(clause)); // Simplifies as well
                    HandleDeducedClauses(worklist, SegmentRatio.InstantiateEquation(clause));
                    if (clause is AngleEquation)
                    {
                        HandleDeducedClauses(worklist, AnglesOfEqualMeasureAreCongruent.Instantiate(clause));
                        HandleDeducedClauses(worklist, ComplementaryDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, RightAngleDefinition.Instantiate(clause));
                    }
                    // If a geometric equation was constructed, it may not have been checked for proportionality
                    if ((clause as Equation).IsGeometric())
                    {
                        HandleDeducedClauses(worklist, ProportionalAngles.Instantiate(clause));
                        HandleDeducedClauses(worklist, SegmentRatio.InstantiateEquation(clause));
                    }
                }
                else if (clause is Midpoint)
                {
                    HandleDeducedClauses(worklist, MidpointDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, MidpointTheorem.Instantiate(clause));
                }
                else if (clause is Collinear)
                {
                    HandleDeducedClauses(worklist, StraightAngleDefinition.Instantiate(clause));
                }
                else if (clause is Median)
                {
                    HandleDeducedClauses(worklist, MedianDefinition.Instantiate(clause));
                }
                else if (clause is SegmentBisector)
                {
                    HandleDeducedClauses(worklist, SegmentBisectorDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, MedianDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, DiagonalsBisectEachOtherImplyParallelogram.Instantiate(clause));
                }
                else if (clause is Parallel)
                {
                    HandleDeducedClauses(worklist, TriangleProportionality.Instantiate(clause));
                    HandleDeducedClauses(worklist, CorrespondingAnglesOfParallelLines.Instantiate(clause));
                    HandleDeducedClauses(worklist, TransversalPerpendicularToParallelImplyBothPerpendicular.Instantiate(clause));
                    HandleDeducedClauses(worklist, ParallelImplyAltIntCongruentAngles.Instantiate(clause));
                    HandleDeducedClauses(worklist, ParallelImplySameSideInteriorSupplementary.Instantiate(clause));

                    // Quadrilaterals
                    HandleDeducedClauses(worklist, ParallelogramDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, TrapezoidDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, OnePairOppSidesCongruentParallelImpliesParallelogram.Instantiate(clause));
                }
                else if (clause is SegmentRatioEquation)
                {
                    HandleDeducedClauses(worklist, SASSimilarity.Instantiate(clause));
                    HandleDeducedClauses(worklist, SSSSimilarity.Instantiate(clause));
                    //                    HandleDeducedClauses(worklist, SegmentRatio.InstantiateProportion(clause));
                    HandleDeducedClauses(worklist, TransitiveSubstitution.Instantiate(clause)); // Simplifies as well
                }
                else if (clause is ProportionalAngles)
                {
                    HandleDeducedClauses(worklist, ProportionalAngles.InstantiateProportion(clause));
                }
                else if (clause is CongruentTriangles)
                {
                    HandleDeducedClauses(worklist, CongruentTriangles.Instantiate(clause));
                    HandleDeducedClauses(worklist, TransitiveCongruentTriangles.Instantiate(clause));
                }
                else if (clause is CongruentAngles)
                {
                    HandleDeducedClauses(worklist, SupplementaryAndCongruentImplyRightAngles.Instantiate(clause));
                    HandleDeducedClauses(worklist, TwoPairsCongruentAnglesImplyThirdPairCongruent.Instantiate(clause));
                    HandleDeducedClauses(worklist, SASCongruence.Instantiate(clause));
                    HandleDeducedClauses(worklist, ASA.Instantiate(clause));
                    HandleDeducedClauses(worklist, AAS.Instantiate(clause));
                    HandleDeducedClauses(worklist, AngleAdditionAxiom.Instantiate(clause));
                    HandleDeducedClauses(worklist, CongruentAnglesInTriangleImplyCongruentSides.Instantiate(clause));
                    HandleDeducedClauses(worklist, SASSimilarity.Instantiate(clause));
                    HandleDeducedClauses(worklist, AASimilarity.Instantiate(clause));
                    HandleDeducedClauses(worklist, AltIntCongruentAnglesImplyParallel.Instantiate(clause));
                    HandleDeducedClauses(worklist, TransitiveSubstitution.Instantiate(clause)); // Simplifies as well
                    HandleDeducedClauses(worklist, CongruentCorrespondingAnglesImplyParallel.Instantiate(clause));
                    HandleDeducedClauses(worklist, CongruentAdjacentAnglesImplyPerpendicular.Instantiate(clause));
                    HandleDeducedClauses(worklist, RelationsOfCongruentAnglesAreCongruent.Instantiate(clause));
                    HandleDeducedClauses(worklist, AngleBisectorDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, RightAngleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, SupplementaryDefinition.Instantiate(clause));

                    // Quadrilaterals
                    HandleDeducedClauses(worklist, BothPairsOppAnglesCongruentImpliesParallelogram.Instantiate(clause));

                    // Circles
                    HandleDeducedClauses(worklist, MinorArcsCongruentIfCentralAnglesCongruent.Instantiate(clause));
                }
                else if (clause is CongruentSegments)
                {
                    HandleDeducedClauses(worklist, SegmentBisectorDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, SSS.Instantiate(clause));
                    HandleDeducedClauses(worklist, SASCongruence.Instantiate(clause));
                    HandleDeducedClauses(worklist, ASA.Instantiate(clause));
                    HandleDeducedClauses(worklist, AAS.Instantiate(clause));
                    HandleDeducedClauses(worklist, HypotenuseLeg.Instantiate(clause));
                    HandleDeducedClauses(worklist, EquilateralTriangleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, IsoscelesTriangleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, MidpointDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, TransitiveSubstitution.Instantiate(clause)); // Simplifies as well
                    HandleDeducedClauses(worklist, CongruentSidesInTriangleImplyCongruentAngles.Instantiate(clause));
                    HandleDeducedClauses(worklist, CongruentSegmentsImplySegmentRatioDefinition.Instantiate(clause));

                    // For quadrilaterals
                    HandleDeducedClauses(worklist, IsoscelesTrapezoidDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, KiteDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, RhombusDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, BothPairsOppSidesCongruentImpliesParallelogram.Instantiate(clause));
                    HandleDeducedClauses(worklist, OnePairOppSidesCongruentParallelImpliesParallelogram.Instantiate(clause));

                    // Circles
                    HandleDeducedClauses(worklist, CongruentCircleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, CongruentArcsHaveCongruentChords.Instantiate(clause));
                }
                else if (clause is Triangle)
                {
                    Triangle.Record(clause);

                    //HandleDeducedClauses(worklist, SumAnglesInTriangle.Instantiate(clause));
                    HandleDeducedClauses(worklist, Angle.InstantiateReflexiveAngles(clause));
                    HandleDeducedClauses(worklist, Triangle.Instantiate(clause));
                    HandleDeducedClauses(worklist, SSS.Instantiate(clause));
                    HandleDeducedClauses(worklist, SASCongruence.Instantiate(clause));
                    HandleDeducedClauses(worklist, ASA.Instantiate(clause));
                    HandleDeducedClauses(worklist, AAS.Instantiate(clause));
                    HandleDeducedClauses(worklist, HypotenuseLeg.Instantiate(clause));
                    HandleDeducedClauses(worklist, EquilateralTriangleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, IsoscelesTriangleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, ExteriorAngleEqualSumRemoteAngles.Instantiate(clause));
                    HandleDeducedClauses(worklist, CongruentAnglesInTriangleImplyCongruentSides.Instantiate(clause));
                    HandleDeducedClauses(worklist, CongruentSidesInTriangleImplyCongruentAngles.Instantiate(clause));
                    HandleDeducedClauses(worklist, SASSimilarity.Instantiate(clause));
                    HandleDeducedClauses(worklist, SSSSimilarity.Instantiate(clause));
                    HandleDeducedClauses(worklist, AASimilarity.Instantiate(clause));
                    HandleDeducedClauses(worklist, TriangleProportionality.Instantiate(clause));
                    HandleDeducedClauses(worklist, AcuteAnglesInRightTriangleComplementary.Instantiate(clause));
                    HandleDeducedClauses(worklist, TwoPairsCongruentAnglesImplyThirdPairCongruent.Instantiate(clause));
                    HandleDeducedClauses(worklist, AltitudeDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, RightTriangleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, MedianDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, CongruentSegmentsImplySegmentRatioDefinition.Instantiate(clause));

                    if (clause is IsoscelesTriangle)
                    {
                        HandleDeducedClauses(worklist, IsoscelesTriangleTheorem.Instantiate(clause));

                        // CTA: Needs to worl with Equilateral Triangles as well
                        HandleDeducedClauses(worklist, AngleBisectorIsPerpendicularBisectorInIsosceles.Instantiate(clause));
                    }

                    if (clause is EquilateralTriangle)
                    {
                        HandleDeducedClauses(worklist, EquilateralTriangleHasSixtyDegreeAngles.Instantiate(clause));
                    }
                }
                else if (clause is Quadrilateral)
                {
                    Quadrilateral.Record(clause);

                    if (clause is Quadrilateral)
                    {
                        if ((clause as Quadrilateral).IsStrictQuadrilateral())
                        {
                            HandleDeducedClauses(worklist, ParallelogramDefinition.Instantiate(clause));
                            HandleDeducedClauses(worklist, RhombusDefinition.Instantiate(clause));
                            HandleDeducedClauses(worklist, SquareDefinition.Instantiate(clause));
                            HandleDeducedClauses(worklist, KiteDefinition.Instantiate(clause));
                            HandleDeducedClauses(worklist, TrapezoidDefinition.Instantiate(clause));

                            HandleDeducedClauses(worklist, BothPairsOppSidesCongruentImpliesParallelogram.Instantiate(clause));
                            HandleDeducedClauses(worklist, OnePairOppSidesCongruentParallelImpliesParallelogram.Instantiate(clause));
                            HandleDeducedClauses(worklist, BothPairsOppAnglesCongruentImpliesParallelogram.Instantiate(clause));
                            HandleDeducedClauses(worklist, DiagonalsBisectEachOtherImplyParallelogram.Instantiate(clause));
                        }
                    }

                    if (clause is Parallelogram)
                    {
                        HandleDeducedClauses(worklist, ParallelogramDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, RectangleDefinition.Instantiate(clause));

                        // Quad Theorems
                        HandleDeducedClauses(worklist, OppositeSidesOfParallelogramAreCongruent.Instantiate(clause));
                        HandleDeducedClauses(worklist, OppositeAnglesOfParallelogramAreCongruent.Instantiate(clause));
                        HandleDeducedClauses(worklist, DiagonalsParallelogramBisectEachOther.Instantiate(clause));
                    }

                    if (clause is Trapezoid)
                    {
                        HandleDeducedClauses(worklist, TrapezoidDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, IsoscelesTrapezoidDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, MedianTrapezoidParallelToBases.Instantiate(clause));
                        HandleDeducedClauses(worklist, MedianTrapezoidHalfSumBases.Instantiate(clause));
                    }

                    if (clause is IsoscelesTrapezoid)
                    {
                        HandleDeducedClauses(worklist, TrapezoidDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, IsoscelesTrapezoidDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, BaseAnglesIsoscelesTrapezoidCongruent.Instantiate(clause));
                    }

                    if (clause is Rhombus)
                    {
                        HandleDeducedClauses(worklist, RhombusDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, SquareDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, DiagonalsOfRhombusArePerpendicular.Instantiate(clause));
                        HandleDeducedClauses(worklist, DiagonalsOfRhombusBisectRhombusAngles.Instantiate(clause));
                    }

                    if (clause is Square)
                    {
                        HandleDeducedClauses(worklist, SquareDefinition.Instantiate(clause));
                    }

                    if (clause is Rectangle)
                    {
                        HandleDeducedClauses(worklist, RectangleDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, DiagonalsOfRectangleAreCongruent.Instantiate(clause));
                    }

                    if (clause is Kite)
                    {
                        HandleDeducedClauses(worklist, KiteDefinition.Instantiate(clause));
                        HandleDeducedClauses(worklist, DiagonalsOfKiteArePerpendicular.Instantiate(clause));
                    }
                }
                else if (clause is Strengthened)
                {
                    HandleDeducedClauses(worklist, IsoscelesTriangleTheorem.Instantiate(clause));
                    HandleDeducedClauses(worklist, IsoscelesTriangleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, EquilateralTriangleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, AcuteAnglesInRightTriangleComplementary.Instantiate(clause));
                    HandleDeducedClauses(worklist, AngleBisectorIsPerpendicularBisectorInIsosceles.Instantiate(clause));
                    HandleDeducedClauses(worklist, EquilateralTriangleHasSixtyDegreeAngles.Instantiate(clause));
                    HandleDeducedClauses(worklist, SASCongruence.Instantiate(clause));
                    HandleDeducedClauses(worklist, HypotenuseLeg.Instantiate(clause));

                    // For strengthening an intersection to a perpendicular
                    HandleDeducedClauses(worklist, PerpendicularImplyCongruentAdjacentAngles.Instantiate(clause));
                    HandleDeducedClauses(worklist, AdjacentAnglesPerpendicularImplyComplementary.Instantiate(clause));
                    HandleDeducedClauses(worklist, AltitudeDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, TransversalPerpendicularToParallelImplyBothPerpendicular.Instantiate(clause));
                    HandleDeducedClauses(worklist, RightTriangleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, PerpendicularDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, PerpendicularBisectorDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, SegmentBisectorDefinition.Instantiate(clause));

                    // InMiddle Strengthened to Midpoint
                    HandleDeducedClauses(worklist, MidpointDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, MidpointTheorem.Instantiate(clause));
                    HandleDeducedClauses(worklist, MedianDefinition.Instantiate(clause));

                    // Right Angle
                    HandleDeducedClauses(worklist, RightAngleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, ComplementaryDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, RightTriangleDefinition.Instantiate(clause));

                    // Correlating isoceles triangles with right triangles.
                    CoordinateRightIsoscelesTriangles.Instantiate(clause);

                    // For quadrilateral definitions
                    HandleDeducedClauses(worklist, TrapezoidDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, IsoscelesTrapezoidDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, SquareDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, KiteDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, ParallelogramDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, RectangleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, RhombusDefinition.Instantiate(clause));

                    // Quad Theorems
                    HandleDeducedClauses(worklist, OppositeSidesOfParallelogramAreCongruent.Instantiate(clause));
                    HandleDeducedClauses(worklist, OppositeAnglesOfParallelogramAreCongruent.Instantiate(clause));
                    HandleDeducedClauses(worklist, DiagonalsParallelogramBisectEachOther.Instantiate(clause));
                    HandleDeducedClauses(worklist, DiagonalsBisectEachOtherImplyParallelogram.Instantiate(clause));
                    HandleDeducedClauses(worklist, DiagonalsOfRectangleAreCongruent.Instantiate(clause));
                    HandleDeducedClauses(worklist, DiagonalsOfKiteArePerpendicular.Instantiate(clause));
                    HandleDeducedClauses(worklist, DiagonalsOfRhombusArePerpendicular.Instantiate(clause));
                    HandleDeducedClauses(worklist, DiagonalsOfRhombusBisectRhombusAngles.Instantiate(clause));
                    HandleDeducedClauses(worklist, BaseAnglesIsoscelesTrapezoidCongruent.Instantiate(clause));
                    HandleDeducedClauses(worklist, MedianTrapezoidParallelToBases.Instantiate(clause));
                    HandleDeducedClauses(worklist, MedianTrapezoidHalfSumBases.Instantiate(clause));

                    // Circle
                    HandleDeducedClauses(worklist, AngleInscribedSemiCircleIsRight.Instantiate(clause));
                    HandleDeducedClauses(worklist, ChordTangentAngleHalfInterceptedArc.Instantiate(clause));
                    HandleDeducedClauses(worklist, DiameterPerpendicularToChordBisectsChordAndArc.Instantiate(clause));
                    HandleDeducedClauses(worklist, ExteriorAngleHalfDifferenceInterceptedArcs.Instantiate(clause));
                    HandleDeducedClauses(worklist, PerpendicularToRadiusIsTangent.Instantiate(clause));
                    HandleDeducedClauses(worklist, TangentPerpendicularToRadius.Instantiate(clause));
                    HandleDeducedClauses(worklist, TangentsToCircleFromPointAreCongruent.Instantiate(clause));
                }
                else if (clause is CircleIntersection)
                {
                    HandleDeducedClauses(worklist, DiameterPerpendicularToChordBisectsChordAndArc.Instantiate(clause));
                    HandleDeducedClauses(worklist, PerpendicularToRadiusIsTangent.Instantiate(clause));
                }
                else if (clause is Tangent)
                {
                    // HandleDeducedClauses(worklist, ChordTangentAngleHalfInterceptedArc.Instantiate(clause));
                    // HandleDeducedClauses(worklist, ExteriorAngleHalfDifferenceInterceptedArcs.Instantiate(clause));
                    HandleDeducedClauses(worklist, TangentPerpendicularToRadius.Instantiate(clause));
                    HandleDeducedClauses(worklist, TangentsToCircleFromPointAreCongruent.Instantiate(clause));
                }
                else if (clause is CongruentArcs)
                {
                    HandleDeducedClauses(worklist, TransitiveSubstitution.Instantiate(clause)); // Simplifies as well
                    HandleDeducedClauses(worklist, CongruentArcsHaveCongruentChords.Instantiate(clause));
                    HandleDeducedClauses(worklist, MinorArcsCongruentIfCentralAnglesCongruent.Instantiate(clause));
                }
                else if (clause is Circle)
                {
                    Circle.Record(clause);

                    HandleDeducedClauses(worklist, CircleDefinition.Instantiate(clause));
                    HandleDeducedClauses(worklist, CentralAngleEqualInterceptedArc.Instantiate(clause));
                    //HandleDeducedClauses(worklist, ExteriorAngleHalfDifferenceInterceptedArcs.Instantiate(clause));
                    HandleDeducedClauses(worklist, InscribedAngleHalfInterceptedArc.Instantiate(clause));
                    //HandleDeducedClauses(worklist, TwoChordsAnglesHalfSumInterceptedArc.Instantiate(clause));
                    HandleDeducedClauses(worklist, InscribedQuadrilateralOppositeSupplementary.Instantiate(clause));
                    HandleDeducedClauses(worklist, TwoInterceptedArcsHaveCongruentAngles.Instantiate(clause));
                }
                else if (clause is CongruentCircles)
                {
                    HandleDeducedClauses(worklist, CongruentCircleDefinition.Instantiate(clause));
                }
            }

            return(graph);
        }
Пример #2
0
        //
        //
        //
        private static List <EdgeAggregator> IfCongruencesApplyToTrianglesGenerate(Triangle ct1, Triangle ct2, CongruentSegments css1, CongruentSegments css2)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

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

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

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

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

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

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

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

            GeometricSegmentRatioEquation newEq = new GeometricSegmentRatioEquation(ratio1, ratio2);

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

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



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

            return(newGrounded);
        }
Пример #3
0
        private static List <EdgeAggregator> CheckAndGenerateProportionality(Triangle tri, Intersection inter1,
                                                                             Intersection inter2, Parallel parallel)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // The two intersections should not be at the same vertex
            if (inter1.intersect.Equals(inter2.intersect))
            {
                return(newGrounded);
            }

            //
            // Do these intersections share a segment? That is, do they share the transversal?
            //
            Segment transversal = inter1.AcquireTransversal(inter2);

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

            //
            // Is the transversal a side of the triangle? It should not be.
            //
            if (tri.LiesOn(transversal))
            {
                return(newGrounded);
            }

            //
            // Determine if one parallel segment is a side of the triangle (which must occur)
            //
            Segment coinciding = tri.DoesParallelCoincideWith(parallel);

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

            // The transversal and common segment must be distinct
            if (coinciding.IsCollinearWith(transversal))
            {
                return(newGrounded);
            }

            //
            // Determine if the simplified transversal is within the parallel relationship.
            //
            Segment parallelTransversal       = parallel.OtherSegment(coinciding);
            Segment simpleParallelTransversal = new Segment(inter1.intersect, inter2.intersect);

            if (!parallelTransversal.IsCollinearWith(simpleParallelTransversal))
            {
                return(newGrounded);
            }

            //            A
            //           /\
            //          /  \
            //         /    \
            //  off1  /------\ off2
            //       /        \
            //    B /__________\ C

            //
            // Both intersections should create a T-shape.
            //
            Point off1 = inter1.CreatesTShape();
            Point off2 = inter2.CreatesTShape();

            if (off1 == null || off2 == null)
            {
                return(newGrounded);
            }

            // Get the intersection segments which should coincide with the triangle sides
            KeyValuePair <Segment, Segment> otherSides = tri.OtherSides(coinciding);

            // The intersections may be outside this triangle
            if (otherSides.Key == null || otherSides.Value == null)
            {
                return(newGrounded);
            }

            Segment side1 = inter1.OtherSegment(transversal);
            Segment side2 = inter2.OtherSegment(transversal);

            // Get the actual sides of the triangle
            Segment triangleSide1 = null;
            Segment triangleSide2 = null;

            if (side1.IsCollinearWith(otherSides.Key) && side2.IsCollinearWith(otherSides.Value))
            {
                triangleSide1 = otherSides.Key;
                triangleSide2 = otherSides.Value;
            }
            else if (side1.IsCollinearWith(otherSides.Value) && side2.IsCollinearWith(otherSides.Key))
            {
                triangleSide1 = otherSides.Value;
                triangleSide2 = otherSides.Key;
            }
            else
            {
                return(newGrounded);
            }

            // Verify the opposing parts of the T are on the opposite sides of the triangle
            if (!triangleSide1.PointLiesOnAndExactlyBetweenEndpoints(off2))
            {
                return(newGrounded);
            }
            if (!triangleSide2.PointLiesOnAndExactlyBetweenEndpoints(off1))
            {
                return(newGrounded);
            }

            //
            // Construct the new proprtional relationship and resultant equation
            //
            Point        sharedVertex = triangleSide1.SharedVertex(triangleSide2);
            SegmentRatio newProp1     = new SegmentRatio(new Segment(sharedVertex, off2), triangleSide1);
            SegmentRatio newProp2     = new SegmentRatio(new Segment(sharedVertex, off1), triangleSide2);

            GeometricSegmentRatioEquation newEq = new GeometricSegmentRatioEquation(newProp1, newProp2);

            // Construct hyperedge
            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(tri);
            antecedent.Add(inter1);
            antecedent.Add(inter2);
            antecedent.Add(parallel);

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

            return(newGrounded);
        }
Пример #4
0
        //
        // Of all the congruent segment pairs, choose a subset of 3. Exhaustively check all; if they work, return the set.
        //
        private static List <EdgeAggregator> CheckForSSS(Triangle ct1, Triangle ct2, SegmentRatioEquation sre1, SegmentRatioEquation sre2)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            //
            // The proportional relationships need to link the given triangles
            //
            if (!sre1.LinksTriangles(ct1, ct2))
            {
                return(newGrounded);
            }
            if (!sre2.LinksTriangles(ct1, ct2))
            {
                return(newGrounded);
            }

            //
            // Both equations must share a fraction (ratio)
            //
            if (!sre1.SharesRatio(sre2))
            {
                return(newGrounded);
            }

            //
            // Collect all of the applicable segments
            //
            SegmentRatio shared = sre1.GetSharedRatio(sre2);
            SegmentRatio other1 = sre1.GetOtherRatio(shared);
            SegmentRatio other2 = sre2.GetOtherRatio(shared);

            Segment seg1Tri1 = ct1.GetSegment(shared);
            Segment seg2Tri1 = ct1.GetSegment(other1);
            Segment seg3Tri1 = ct1.GetSegment(other2);

            if (seg1Tri1 == null || seg2Tri1 == null || seg3Tri1 == null)
            {
                return(newGrounded);
            }

            Segment seg1Tri2 = ct2.GetSegment(shared);
            Segment seg2Tri2 = ct2.GetSegment(other1);
            Segment seg3Tri2 = ct2.GetSegment(other2);

            if (seg1Tri2 == null || seg2Tri2 == null || seg3Tri2 == null)
            {
                return(newGrounded);
            }

            // Avoid redundant segments, if they arise
            if (seg1Tri1.StructurallyEquals(seg2Tri1) || seg1Tri1.StructurallyEquals(seg3Tri1) || seg2Tri1.StructurallyEquals(seg3Tri1))
            {
                return(newGrounded);
            }
            if (seg1Tri2.StructurallyEquals(seg2Tri2) || seg1Tri2.StructurallyEquals(seg3Tri2) || seg2Tri2.StructurallyEquals(seg3Tri2))
            {
                return(newGrounded);
            }

            //
            // Collect the corresponding points
            //
            List <KeyValuePair <Point, Point> > pointPairs = new List <KeyValuePair <Point, Point> >();

            pointPairs.Add(new KeyValuePair <Point, Point>(seg1Tri1.SharedVertex(seg2Tri1), seg1Tri2.SharedVertex(seg2Tri2)));
            pointPairs.Add(new KeyValuePair <Point, Point>(seg1Tri1.SharedVertex(seg3Tri1), seg1Tri2.SharedVertex(seg3Tri2)));
            pointPairs.Add(new KeyValuePair <Point, Point>(seg2Tri1.SharedVertex(seg3Tri1), seg2Tri2.SharedVertex(seg3Tri2)));

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

            simTriAntecedent.Add(ct1);
            simTriAntecedent.Add(ct2);
            simTriAntecedent.Add(sre1);
            simTriAntecedent.Add(sre2);

            newGrounded.AddRange(SASSimilarity.GenerateCorrespondingParts(pointPairs, simTriAntecedent, annotation));

            return(newGrounded);
        }