// // 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); }
// // // private static List <EdgeAggregator> IfCongruencesApplyToTrianglesGenerate(Triangle ct1, Triangle ct2, CongruentSegments css1, CongruentSegments css2) { List <EdgeAggregator> newGrounded = new List <EdgeAggregator>(); // // The congruent relationships need to link the given triangles // if (!css1.LinksTriangles(ct1, ct2)) { return(newGrounded); } if (!css2.LinksTriangles(ct1, ct2)) { return(newGrounded); } Segment seg1Tri1 = ct1.GetSegment(css1); Segment seg2Tri1 = ct1.GetSegment(css2); Segment seg1Tri2 = ct2.GetSegment(css1); Segment seg2Tri2 = ct2.GetSegment(css2); // Avoid redundant segments, if it arises if (seg1Tri1.StructurallyEquals(seg2Tri1)) { return(newGrounded); } if (seg1Tri2.StructurallyEquals(seg2Tri2)) { return(newGrounded); } // // Proportional Segments (we generate only as needed to avoid bloat in the hypergraph (assuming they are used by both triangles) // We avoid generating proportions if they are truly congruences. // List <GroundedClause> propAntecedent = new List <GroundedClause>(); propAntecedent.Add(css1); propAntecedent.Add(css2); SegmentRatio ratio1 = new SegmentRatio(seg1Tri1, seg1Tri2); SegmentRatio ratio2 = new SegmentRatio(seg2Tri1, seg2Tri2); GeometricSegmentRatioEquation newEq = new GeometricSegmentRatioEquation(ratio1, ratio2); newGrounded.Add(new EdgeAggregator(propAntecedent, newEq, annotation)); //// //// Only generate if ratios are not 1. //// //GeometricSegmentRatio newProp = null; //if (!Utilities.CompareValues(seg1Tri1.Length, seg1Tri2.Length)) //{ // newProp = new GeometricSegmentRatio(seg1Tri1, seg1Tri2); // newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation)); //} //if (!Utilities.CompareValues(seg1Tri1.Length, seg2Tri2.Length)) //{ // newProp = new GeometricSegmentRatio(seg1Tri1, seg2Tri2); // newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation)); //} //if (!Utilities.CompareValues(seg2Tri1.Length, seg1Tri2.Length)) //{ // newProp = new GeometricSegmentRatio(seg2Tri1, seg1Tri2); // newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation)); //} //if (!Utilities.CompareValues(seg2Tri1.Length, seg2Tri2.Length)) //{ // newProp = new GeometricSegmentRatio(seg2Tri1, seg2Tri2); // newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation)); //} return(newGrounded); }
private static List <EdgeAggregator> 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); }
// // 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); }