Esempio n. 1
0
        public void Test_Line_That_Wasnt_There_Before()
        {
            // Create the objects
            var A  = new LooseConfigurationObject(Point);
            var B  = new LooseConfigurationObject(Point);
            var C  = new LooseConfigurationObject(Point);
            var bc = new ConstructedConfigurationObject(LineFromPoints, B, C);
            var l  = new ConstructedConfigurationObject(PerpendicularLine, A, bc);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, bc, l);

            // Run
            var(newTheorems, allTheorems) = FindTheorems(configuration);

            // Assert new theorems
            newTheorems.OrderlessEquals(new[]
            {
                new Theorem(Incidence, l, A)
            })
            .Should().BeTrue();

            // Assert all theorems
            allTheorems.OrderlessEquals(new[]
            {
                new Theorem(Incidence, l, A),
                new Theorem(Incidence, bc, B),
                new Theorem(Incidence, bc, C)
            })
            .Should().BeTrue();
        }
Esempio n. 2
0
        public void Test_That_Concyclic_Inconsistency_Causes_Inconsistent_Pictures_Exception()
        {
            // Create the objects
            var A = new LooseConfigurationObject(ConfigurationObjectType.Point);
            var B = new LooseConfigurationObject(ConfigurationObjectType.Point);
            var C = new LooseConfigurationObject(ConfigurationObjectType.Point);
            var D = new LooseConfigurationObject(ConfigurationObjectType.Point);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(Quadrilateral, A, B, C, D);

            // Create the action that should cause an exception
            Action action = () => CreatePicture(configuration, new[]
            {
                new IAnalyticObject[]
                {
                    new Point(0, 0),
                    new Point(0, 1),
                    new Point(1, 0),
                    new Point(1, 1)
                },
                new IAnalyticObject[]
                {
                    new Point(0, 0),
                    new Point(0, 1),
                    new Point(1, 0),
                    new Point(2, 1)
                }
            });

            // Assert
            action.Should().Throw <InconsistentPicturesException>("The points are concyclic in one picture and not in the other.");
        }
Esempio n. 3
0
        public void Test_Circle_That_Is_Already_There_Implicitly_With_Its_Point_As_Last_Object()
        {
            // Create the objects
            var A        = new LooseConfigurationObject(Point);
            var B        = new LooseConfigurationObject(Point);
            var C        = new LooseConfigurationObject(Point);
            var thalesBC = new ConstructedConfigurationObject(CircleWithDiameter, B, C);
            var D        = new ConstructedConfigurationObject(ReflectionInLineFromPoints, A, B, C);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(RightTriangle, A, thalesBC, D);

            // Run
            var(newTheorems, allTheorems) = FindTheorems(configuration);

            // Assert new theorems
            newTheorems.OrderlessEquals(new[]
            {
                new Theorem(Incidence, thalesBC, D)
            })
            .Should().BeTrue();

            // Assert all theorems
            allTheorems.OrderlessEquals(new[]
            {
                new Theorem(Incidence, thalesBC, A),
                new Theorem(Incidence, thalesBC, B),
                new Theorem(Incidence, thalesBC, C),
                new Theorem(Incidence, thalesBC, D)
            })
            .Should().BeTrue();
        }
Esempio n. 4
0
        public void Test_Quadrilateral_With_Medium_Partial_Symmetry()
        {
            // Prepare the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new LooseConfigurationObject(Point);
            var P = new ConstructedConfigurationObject(Incenter, A, B, D);
            var Q = new ConstructedConfigurationObject(Incenter, C, B, D);

            // Prepare the configuration
            var configuration = Configuration.DeriveFromObjects(Quadrilateral, P, Q);

            // Prepare the theorem
            // NOTE: I did not really try to make it be true in general
            var theorem = new Theorem(PerpendicularLines, new[]
            {
                new LineTheoremObject(P, Q),
                new LineTheoremObject(B, D)
            });

            // Rank
            var rank = new SymmetryRanker().Rank(theorem, configuration, allTheorems: null);

            // Assert
            rank.Rounded().Should().Be((3d / 9).Rounded());
        }
Esempio n. 5
0
        public void Test_GetObjectsThatWouldMakeThisConfigurationFullySymmetric_Mix()
        {
            // Create objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new ConstructedConfigurationObject(PointReflection, B, C);
            var E = new ConstructedConfigurationObject(Midpoint, B, C);
            var H = new ConstructedConfigurationObject(Orthocenter, A, B, C);
            var I = new ConstructedConfigurationObject(Incenter, A, B, C);
            var G = new ConstructedConfigurationObject(Centroid, E, I, H);
            var K = new ConstructedConfigurationObject(PointReflection, H, I);

            // Create the configuration and call the method
            Configuration.DeriveFromObjects(Triangle, D, E, H, I, G, K).GetObjectsThatWouldMakeThisConfigurationFullySymmetric()
            // We need lots of objects
            .Should().BeEquivalentTo(new[]
            {
                new ConstructedConfigurationObject(PointReflection, C, B),
                new ConstructedConfigurationObject(PointReflection, A, B),
                new ConstructedConfigurationObject(PointReflection, B, A),
                new ConstructedConfigurationObject(PointReflection, A, C),
                new ConstructedConfigurationObject(PointReflection, C, A),
                new ConstructedConfigurationObject(Midpoint, A, C),
                new ConstructedConfigurationObject(Midpoint, A, B),
                new ConstructedConfigurationObject(Centroid, new ConstructedConfigurationObject(Midpoint, A, C), I, H),
                new ConstructedConfigurationObject(Centroid, new ConstructedConfigurationObject(Midpoint, A, B), I, H),
            });
        }
Esempio n. 6
0
        public void Test_That_Old_Theorem_Invalidation_Happens_With_Concurrent_Lines()
        {
            // Create the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new ConstructedConfigurationObject(Midpoint, B, C);
            var E = new ConstructedConfigurationObject(Midpoint, C, A);
            var F = new ConstructedConfigurationObject(Midpoint, A, B);
            var G = new ConstructedConfigurationObject(Centroid, A, B, C);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, D, E, F, G);

            // Run
            var(oldTheorems, newTheorems, invalidOldTheorems, allTheorems) = FindTheorems(configuration);

            // Assert that old + new - invalidated = all
            oldTheorems.AllObjects.Concat(newTheorems.AllObjects).Except(invalidOldTheorems).OrderlessEquals(allTheorems.AllObjects).Should().BeTrue();

            // Create the invalidated theorem
            var invalidatedTheorem = new Theorem(ConcurrentLines, new[]
            {
                new LineTheoremObject(A, D),
                new LineTheoremObject(B, E),
                new LineTheoremObject(C, F)
            });

            // Assert it is the only one
            invalidOldTheorems.OrderlessEquals(new[] { invalidatedTheorem });

            // Assert it is indeed old
            oldTheorems.AllObjects.Should().Contain(invalidatedTheorem);
        }
Esempio n. 7
0
        public void Test_Quadrilateral_With_Full_Symmetry()
        {
            // Prepare the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new LooseConfigurationObject(Point);
            var P = new ConstructedConfigurationObject(Incenter, A, B, C);
            var Q = new ConstructedConfigurationObject(Incenter, B, C, D);
            var R = new ConstructedConfigurationObject(Incenter, C, D, A);
            var S = new ConstructedConfigurationObject(Incenter, D, A, B);

            // Prepare the configuration
            var configuration = Configuration.DeriveFromObjects(Quadrilateral, P, Q, R, S);

            // Prepare the theorem
            // NOTE: I did not really try to make it be true in general
            var theorem = new Theorem(ConcyclicPoints, P, Q, R, S);

            // Rank
            var rank = new SymmetryRanker().Rank(theorem, configuration, allTheorems: null);

            // Assert
            rank.Should().Be(1);
        }
Esempio n. 8
0
        public void Test_Circle_That_Wasnt_There_Before()
        {
            // Create the objects
            var A        = new LooseConfigurationObject(Point);
            var B        = new LooseConfigurationObject(Point);
            var C        = new LooseConfigurationObject(Point);
            var abc      = new ConstructedConfigurationObject(Circumcircle, A, B, C);
            var thalesBC = new ConstructedConfigurationObject(CircleWithDiameter, B, C);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, abc, thalesBC);

            // Run
            var(newTheorems, allTheorems) = FindTheorems(configuration);

            // Assert new theorems
            newTheorems.OrderlessEquals(new[]
            {
                new Theorem(Incidence, thalesBC, B),
                new Theorem(Incidence, thalesBC, C)
            })
            .Should().BeTrue();

            // Assert all theorems
            allTheorems.OrderlessEquals(new[]
            {
                new Theorem(Incidence, thalesBC, B),
                new Theorem(Incidence, thalesBC, C),
                new Theorem(Incidence, abc, A),
                new Theorem(Incidence, abc, B),
                new Theorem(Incidence, abc, C)
            })
            .Should().BeTrue();
        }
Esempio n. 9
0
        public void Test_That_Old_Theorem_Invalidation_Happens_With_Line_Tangent_To_Circle()
        {
            // Create the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var c = new ConstructedConfigurationObject(Incircle, A, B, C);
            var I = new ConstructedConfigurationObject(Incenter, A, B, C);
            var D = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, I, B, C);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, c, I, D);

            // Run
            var(oldTheorems, newTheorems, invalidOldTheorems, allTheorems) = FindTheorems(configuration);

            // Assert that old + new - invalidated = all
            oldTheorems.AllObjects.Concat(newTheorems.AllObjects).Except(invalidOldTheorems).OrderlessEquals(allTheorems.AllObjects).Should().BeTrue();

            // Create the invalidated theorem
            var invalidatedTheorem = new Theorem(LineTangentToCircle, new TheoremObject[]
            {
                new LineTheoremObject(B, C),
                new CircleTheoremObject(c)
            });

            // Assert it is the only one
            invalidOldTheorems.OrderlessEquals(new[] { invalidatedTheorem });

            // Assert it is indeed old
            oldTheorems.AllObjects.Should().Contain(invalidatedTheorem);
        }
Esempio n. 10
0
        public void Test_GetUnnecessaryObjects_Midline_Is_Half_Of_Side()
        {
            // Draw configuration with medians
            var A   = new LooseConfigurationObject(Point);
            var B   = new LooseConfigurationObject(Point);
            var C   = new LooseConfigurationObject(Point);
            var mBC = new ConstructedConfigurationObject(Midpoint, B, C);
            var mAC = new ConstructedConfigurationObject(Midpoint, C, A);
            var mAB = new ConstructedConfigurationObject(Midpoint, A, B);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, mBC, mAC, mAB);

            // This can't be stated in a smaller configuration either
            new Theorem(EqualLineSegments, new[]
            {
                new LineSegmentTheoremObject(mAB, mAC),
                new LineSegmentTheoremObject(B, mBC)
            })
            .GetUnnecessaryObjects(configuration).Should().BeEmpty();

            // Analogously this couldn't be stated in a smaller configuration either
            new Theorem(EqualLineSegments, new[]
            {
                new LineSegmentTheoremObject(mAB, mAC),
                new LineSegmentTheoremObject(C, mBC)
            })
            .GetUnnecessaryObjects(configuration).Should().BeEmpty();
        }
Esempio n. 11
0
        public void Test_Triangle_With_Partial_Symmetry()
        {
            // Prepare the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var M = new ConstructedConfigurationObject(Midpoint, A, B);
            var N = new ConstructedConfigurationObject(Midpoint, A, C);

            // Prepare the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C, M, N);

            // Prepare the theorem
            var theorem = new Theorem(ParallelLines, new[]
            {
                new LineTheoremObject(B, C),
                new LineTheoremObject(M, N)
            });

            // Rank
            var rank = new SymmetryRanker().Rank(theorem, configuration, allTheorems: null);

            // Assert
            rank.Rounded().Should().Be((1d / 3).Rounded());
        }
        public void Test_With_Midpoint_Of_Opposite_Arc()
        {
            // Create objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var M = new ConstructedConfigurationObject(MidpointOfOppositeArc, A, B, C);

            // Find the trivial theorems
            Producer.InferTrivialTheoremsFromObject(M)
            // There should be these theorems
            .OrderlessEquals(new[]
            {
                // Equal line segments
                new Theorem(EqualLineSegments, new[]
                {
                    new LineSegmentTheoremObject(B, M),
                    new LineSegmentTheoremObject(C, M)
                }),

                // Concyclic points
                new Theorem(ConcyclicPoints, A, B, C, M),
            })
            .Should().BeTrue();
        }
Esempio n. 13
0
        public void Test_Triangle_With_Full_Symmetry()
        {
            // Prepare the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var P = new ConstructedConfigurationObject(Midpoint, B, C);
            var Q = new ConstructedConfigurationObject(Midpoint, C, A);
            var R = new ConstructedConfigurationObject(Midpoint, A, B);

            // Prepare the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C, P, Q, R);

            // Prepare the theorem
            var theorem = new Theorem(ConcurrentLines, new[]
            {
                new LineTheoremObject(A, P),
                new LineTheoremObject(B, Q),
                new LineTheoremObject(C, R)
            });

            // Rank
            var rank = new SymmetryRanker().Rank(theorem, configuration, allTheorems: null);

            // Assert
            rank.Should().Be(1);
        }
        public void Test_Triangle_And_Midpoint_With_Initial_Objects(int iterations, int expectedCount)
        {
            // Prepare the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var P = new ConstructedConfigurationObject(Midpoint, A, B);
            var Q = new ConstructedConfigurationObject(Midpoint, B, C);
            var R = new ConstructedConfigurationObject(Midpoint, C, A);

            // Prepare the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C, P, Q, R);

            // Prepare the input with just the midpoint construction
            var input = new ConfigurationGeneratorInput
                        (
                initialConfiguration: configuration,
                constructions: new HashSet <Construction> {
                Midpoint
            }.ToReadOnlyHashSet(),
                numberOfIterations: iterations,
                maximalNumbersOfObjectsToAdd: new Dictionary <ConfigurationObjectType, int>
            {
                { Point, int.MaxValue }
            },
                configurationFilter: _ => true
                        );

            // Assert counts (can be verified by hand)
            GetGenerator(ConfigurationFilterType.Fast).Generate(input).ToArray().Length.Should().Be(expectedCount);
            GetGenerator(ConfigurationFilterType.MemoryEfficient).Generate(input).ToArray().Length.Should().Be(expectedCount);
        }
        public void Test_Triangle_And_Various_Constructions_With_Limiting_Number_Of_Objects()
        {
            // Prepare the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);

            // Prepare the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C);

            // Prepare the input with just the midpoint construction
            var input = new ConfigurationGeneratorInput
                        (
                initialConfiguration: configuration,
                constructions: new HashSet <Construction> {
                Midpoint, LineFromPoints, Circumcircle
            }.ToReadOnlyHashSet(),
                numberOfIterations: 42,
                maximalNumbersOfObjectsToAdd: new Dictionary <ConfigurationObjectType, int>
            {
                { Point, 1 },
                { Line, 1 },
                { Circle, 0 },
            },
                configurationFilter: _ => true
                        );

            // Assert counts (can be verified by hand)
            GetGenerator(ConfigurationFilterType.Fast).Generate(input).ToArray().Length.Should().Be(6);
            GetGenerator(ConfigurationFilterType.MemoryEfficient).Generate(input).ToArray().Length.Should().Be(6);
        }
Esempio n. 16
0
        public void Test_That_Simplification_Does_Not_Happen_When_It_Would_Add_More_Objects()
        {
            // Create the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new ConstructedConfigurationObject(Incenter, A, B, C);
            var E = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, D, B, C);
            var F = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, D, A, C);
            var G = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, D, A, B);
            var l = new ConstructedConfigurationObject(ParallelLineToLineFromPoints, A, E, F);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C, l);

            // Create the theorem
            var theorem = new Theorem(ConcurrentLines, new[]
            {
                new LineTheoremObject(C, D),
                new LineTheoremObject(E, G),
                new LineTheoremObject(l)
            });

            // Let it be simplified. Theoretically speaking, CD is the angle bisector and it could be applied,
            // but neither C nor D could be removed from the configuration, i.e. we would have all the objects
            // + angle bisector after applying the rule. We don't want that
            var result = Simplify(theorem, configuration);

            // Assert it couldn't be done
            result.Should().BeNull();
        }
Esempio n. 17
0
        public void Test_Quadrilateral_With_Very_Strong_Partial_Symmetry()
        {
            // Prepare the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new LooseConfigurationObject(Point);
            var P = new ConstructedConfigurationObject(Midpoint, A, B);
            var Q = new ConstructedConfigurationObject(Midpoint, B, C);
            var R = new ConstructedConfigurationObject(Midpoint, C, D);
            var S = new ConstructedConfigurationObject(Midpoint, D, A);

            // Prepare the configuration
            var configuration = Configuration.DeriveFromObjects(Quadrilateral, P, Q, R, S);

            // Prepare the theorem
            // NOTE: I did not really try to make it be true in general
            var theorem = new Theorem(PerpendicularLines, new[]
            {
                new LineTheoremObject(P, R),
                new LineTheoremObject(Q, S)
            });

            // Rank
            var rank = new SymmetryRanker().Rank(theorem, configuration, allTheorems: null);

            // Assert
            rank.Rounded().Should().Be((5d / 9).Rounded());
        }
Esempio n. 18
0
        public void Test_InferTheoremsFromSymmetry_PartialSymmetry()
        {
            // Draw configuration with medians
            var A   = new LooseConfigurationObject(Point);
            var B   = new LooseConfigurationObject(Point);
            var C   = new LooseConfigurationObject(Point);
            var mAC = new ConstructedConfigurationObject(Midpoint, A, C);
            var mAB = new ConstructedConfigurationObject(Midpoint, A, B);
            var D   = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, A, B, C);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, mAC, mAB, D);

            // Create the theorem
            var theorem = new Theorem(ParallelLines, new[]
            {
                new LineTheoremObject(B, D),
                new LineTheoremObject(mAB, mAC)
            });

            // We can infer one other isomorphic theorem
            theorem.InferTheoremsFromSymmetry(configuration).Should().BeEquivalentTo(new[]
            {
                new Theorem(ParallelLines, new[]
                {
                    new LineTheoremObject(C, D),
                    new LineTheoremObject(mAB, mAC)
                })
            });
        }
Esempio n. 19
0
        public void Test_That_Old_Theorem_Invalidation_Does_Not_Happen_With_Tangent_Circles()
        {
            // Create the objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var l = new ConstructedConfigurationObject(TangentLine, A, B, C);
            var D = new ConstructedConfigurationObject(PerpendicularProjection, B, l);
            var E = new ConstructedConfigurationObject(PerpendicularProjection, C, l);
            var F = new ConstructedConfigurationObject(ReflectionInLineFromPoints, D, B, C);
            var G = new ConstructedConfigurationObject(ReflectionInLineFromPoints, E, B, C);
            var P = new ConstructedConfigurationObject(IntersectionOfLineAndLineFromPoints, l, B, C);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, F, G, P);

            // Run
            var(oldTheorems, newTheorems, invalidOldTheorems, allTheorems) = FindTheorems(configuration);

            // Assert that old + new - invalidated = all
            oldTheorems.AllObjects.Concat(newTheorems.AllObjects).Except(invalidOldTheorems).OrderlessEquals(allTheorems.AllObjects).Should().BeTrue();

            // Assert only concurrencies have been invalidated
            invalidOldTheorems.OrderlessEquals(new[]
            {
                new Theorem(ConcurrentLines, new[]
                {
                    new LineTheoremObject(F, G),
                    new LineTheoremObject(B, C),
                    new LineTheoremObject(l)
                }),
                new Theorem(ConcurrentLines, new[]
                {
                    new LineTheoremObject(F, G),
                    new LineTheoremObject(B, C),
                    new LineTheoremObject(D, E)
                }),
                new Theorem(ConcurrentLines, new[]
                {
                    new LineTheoremObject(F, G),
                    new LineTheoremObject(B, C),
                    new LineTheoremObject(A, D)
                }),
                new Theorem(ConcurrentLines, new[]
                {
                    new LineTheoremObject(F, G),
                    new LineTheoremObject(B, C),
                    new LineTheoremObject(A, E)
                })
            })
            .Should().BeTrue();

            // Assert there is an old tangency
            oldTheorems.AllObjects.Should().Contain(new Theorem(TangentCircles, new[]
            {
                new CircleTheoremObject(B, D, F),
                new CircleTheoremObject(C, E, G)
            }));
        }
Esempio n. 20
0
        public void Test_Getting_Defining_Objects()
        {
            // Initialize some objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new ConstructedConfigurationObject(Midpoint, A, B);
            var E = new ConstructedConfigurationObject(Midpoint, B, C);
            var F = new ConstructedConfigurationObject(Midpoint, C, A);
            var G = new ConstructedConfigurationObject(IntersectionOfLinesFromPoints, B, F, C, D);
            var c = new ConstructedConfigurationObject(Circumcircle, E, F, G);
            var X = new ConstructedConfigurationObject(Circumcenter, A, B, C);
            var Y = new ConstructedConfigurationObject(Midpoint, X, G);

            // Check loose object
            A.GetDefiningObjects().Should().BeEquivalentTo(A);

            // Check simple constructed object
            D.GetDefiningObjects().Should().BeEquivalentTo(A, B, D)
            .And.ContainInOrder(A, D)
            .And.HaveElementSucceeding(B, D);

            // Check complex constructed object
            c.GetDefiningObjects().Should().BeEquivalentTo(A, B, C, D, E, F, G, c)
            .And.ContainInOrder(E, c)
            .And.ContainInOrder(F, c)
            .And.ContainInOrder(G, c)
            .And.ContainInOrder(B, E)
            .And.ContainInOrder(C, E)
            .And.ContainInOrder(C, F)
            .And.ContainInOrder(A, F)
            .And.ContainInOrder(B, G)
            .And.ContainInOrder(F, G)
            .And.ContainInOrder(C, G)
            .And.ContainInOrder(D, G)
            .And.ContainInOrder(A, D)
            .And.ContainInOrder(B, D);

            // Check calling on more objects
            new[] { X, Y, c }.GetDefiningObjects().Should().BeEquivalentTo(A, B, C, D, E, F, G, c, X, Y)
            .And.ContainInOrder(E, c)
            .And.ContainInOrder(F, c)
            .And.ContainInOrder(G, c)
            .And.ContainInOrder(B, E)
            .And.ContainInOrder(C, E)
            .And.ContainInOrder(C, F)
            .And.ContainInOrder(A, F)
            .And.ContainInOrder(B, G)
            .And.ContainInOrder(F, G)
            .And.ContainInOrder(C, G)
            .And.ContainInOrder(D, G)
            .And.ContainInOrder(A, D)
            .And.ContainInOrder(B, D)
            .And.ContainInOrder(A, X)
            .And.ContainInOrder(B, X)
            .And.ContainInOrder(C, X)
            .And.ContainInOrder(X, Y)
            .And.ContainInOrder(G, Y);
        }
Esempio n. 21
0
        private static IEnumerable <ProblemGeneratorInput> Triangle_FourObjects_ThreeLinesAndOnePoint_OnlySymmetric_OnlyUsedLines_PlusTwoObjects()
        {
            // Create the loose objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);

            // Create the initial configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C);

            // Create the dictionary with the counts of objects to be added
            var maximalNumbersOfObjectsObjectsToAdd = new Dictionary <ConfigurationObjectType, int>
            {
                { Point, 1 },
                { Line, 3 },
                { Circle, 0 }
            };

            // Prepare the generator input that takes only fully symmetric configurations
            var problemGeneratorInput = new ProblemGeneratorInput(configuration, _constructions, numberOfIterations: 4, maximalNumbersOfObjectsObjectsToAdd, SymmetryGenerationMode.GenerateOnlySymmetric);

            // Prepare the generator settings
            var settings = new ProblemGeneratorSettings(numberOfPictures: 2);

            // Return the generation enumerable by taking the generator
            return(_kernel.Get <IProblemGenerator>(new ConstructorArgument("settings", settings))
                   // Pass the input to it
                   .Generate(problemGeneratorInput)
                   // Unwrap the enumerable
                   .generationOutputs
                   // Take the configuration
                   .Select(output => output.Configuration)
                   // That is on the last iteration
                   .Where(configuration => configuration.IterationIndex == 4)
                   // Exclude those where there is a hanging line
                   .Where(configuration => !configuration.ObjectMap.GetObjectsForKeys(Line).Any(line
                                                                                                // We don't want a line that is not used in a construction
                                                                                                => configuration.ConstructedObjects.All(constructedObject => !constructedObject.PassedArguments.FlattenedList.Contains(line))))
                   // Every generated configuration makes an input file
                   .Select(configuration => new ProblemGeneratorInput(configuration, _constructions,
                                                                      // We will want 2 iterations
                                                                      numberOfIterations: 2,
                                                                      // Set maximal numbers of objects to be added
                                                                      new Dictionary <ConfigurationObjectType, int>
            {
                // Points and lines are not limited
                { Point, 2 },
                { Line, 2 },

                // We want at most 2 circles in total. More are not necessary, since circles
                // never appear as construction arguments, only in theorems itself, and at most
                // two of them (when we have two tangent circles)
                { Circle, 2 - configuration.ObjectMap.GetObjectsForKeys(Circle).Count() }
            },
                                                                      // We will want only symmetric results
                                                                      symmetryGenerationMode: SymmetryGenerationMode.GenerateOnlySymmetric)));
        }
Esempio n. 22
0
        private static IEnumerable <ProblemGeneratorInput> Quadrilateral_TwoObjects_PlusTwoObjects()
        {
            // Create the loose objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new LooseConfigurationObject(Point);

            // Create the initial configuration
            var configuration = Configuration.DeriveFromObjects(Quadrilateral, A, B, C, D);

            // Create the dictionary with the counts of objects to be added
            var maximalNumbersOfObjectsObjectsToAdd = new Dictionary <ConfigurationObjectType, int>
            {
                { Point, 2 },
                { Line, 2 },
                { Circle, 2 }
            };

            // Prepare the generator input that doesn't exclude asymmetric configurations
            var problemGeneratorInput = new ProblemGeneratorInput(configuration, _constructions, numberOfIterations: 2, maximalNumbersOfObjectsObjectsToAdd, SymmetryGenerationMode.GenerateBothSymmetricAndAsymmetric);

            // Prepare the generator settings
            var settings = new ProblemGeneratorSettings(numberOfPictures: 2);

            // Return the generation enumerable by taking the generator
            return(_kernel.Get <IProblemGenerator>(new ConstructorArgument("settings", settings))
                   // Pass the input to it
                   .Generate(problemGeneratorInput)
                   // Unwrap the enumerable
                   .generationOutputs
                   // Take the configuration
                   .Select(output => output.Configuration)
                   // That is on the last iteration
                   .Where(configuration => configuration.IterationIndex == 2)
                   // Every generated configuration makes an input file
                   .Select(configuration => new ProblemGeneratorInput(configuration, _constructions,
                                                                      // We will want plus 2 objects
                                                                      numberOfIterations: 2,
                                                                      // Set maximal numbers of objects to be added
                                                                      new Dictionary <ConfigurationObjectType, int>
            {
                // Points and lines are not limited
                { Point, 2 },
                { Line, 2 },

                // We want at most 2 circles in total. More are not necessary, since circles
                // never appear as construction arguments, only in theorems itself, and at most
                // two of them (when we have two tangent circles)
                { Circle, 2 - configuration.ObjectMap.GetObjectsForKeys(Circle).Count() }
            },
                                                                      // We will want only symmetric results
                                                                      symmetryGenerationMode: SymmetryGenerationMode.GenerateOnlySymmetric)));
        }
Esempio n. 23
0
        private static Configuration Parallelogram()
        {
            // Create objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new ConstructedConfigurationObject(PointReflection, B, A);
            var E = new ConstructedConfigurationObject(PointReflection, C, A);

            // Return the configuration
            return(Configuration.DeriveFromObjects(Triangle, D, E));
        }
Esempio n. 24
0
        private static Configuration HiddenExcenter()
        {
            // Create objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new ConstructedConfigurationObject(Incenter, A, B, C);
            var E = new ConstructedConfigurationObject(OppositePointOnCircumcircle, D, B, C);

            // Return the configuration
            return(Configuration.DeriveFromObjects(Triangle, E));
        }
Esempio n. 25
0
        private static Configuration HiddenMidpoint()
        {
            // Create objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new ConstructedConfigurationObject(Median, A, B, C);
            var E = new ConstructedConfigurationObject(IntersectionOfLineAndLineFromPoints, D, B, C);

            // Return the configuration
            return(Configuration.DeriveFromObjects(Triangle, D, E));
        }
Esempio n. 26
0
        private static Configuration Midpoints()
        {
            // Create objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new ConstructedConfigurationObject(Midpoint, A, B);
            var E = new ConstructedConfigurationObject(Midpoint, B, C);
            var F = new ConstructedConfigurationObject(Midpoint, C, A);

            // Return the configuration
            return(Configuration.DeriveFromObjects(Triangle, D, E, F));
        }
Esempio n. 27
0
        private static Configuration PerpendicularBisectorsAreConcurrent()
        {
            // Create objects
            var A  = new LooseConfigurationObject(Point);
            var B  = new LooseConfigurationObject(Point);
            var C  = new LooseConfigurationObject(Point);
            var l1 = new ConstructedConfigurationObject(PerpendicularBisector, B, C);
            var l2 = new ConstructedConfigurationObject(PerpendicularBisector, C, A);
            var l3 = new ConstructedConfigurationObject(PerpendicularBisector, A, B);

            // Return the configuration
            return(Configuration.DeriveFromObjects(Triangle, A, B, C, l1, l2, l3));
        }
Esempio n. 28
0
        public void Test_Triangle_With_Midpoints_And_Feets_Of_Altitudes_Which_Should_Be_Concyclic()
        {
            // Create the objects
            var A = new LooseConfigurationObject(ConfigurationObjectType.Point);
            var B = new LooseConfigurationObject(ConfigurationObjectType.Point);
            var C = new LooseConfigurationObject(ConfigurationObjectType.Point);
            var D = new ConstructedConfigurationObject(Midpoint, B, C);
            var E = new ConstructedConfigurationObject(Midpoint, A, C);
            var F = new ConstructedConfigurationObject(Midpoint, A, B);
            var G = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, A, B, C);
            var H = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, B, C, A);
            var I = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, C, A, B);

            // Create the configuration
            var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C, D, E, F, G, H, I);

            // Create the picture
            var picture = CreatePicture(configuration, new[]
            {
                new IAnalyticObject[]
                {
                    new Point(0, 5),
                    new Point(-2, 1),
                    new Point(6, 1),
                    new Point(2, 1),
                    new Point(3, 3),
                    new Point(-1, 3),
                    new Point(0, 1),
                    new Point(6.0 / 13, 61.0 / 13),
                    new Point(-0.4, 4.2)
                },
                new IAnalyticObject[]
                {
                    new Point(0, 3),
                    new Point(-2, 1),
                    new Point(6, 1),
                    new Point(2, 1),
                    new Point(3, 2),
                    new Point(-1, 2),
                    new Point(0, 1),
                    new Point(-1.2, 3.4),
                    new Point(2, 5)
                }
            });

            // Test that there is one circle which passes through 6 points (Feurbach circle)
            picture.AllCircles.Count(circle => circle.Points.Count == 6).Should().Be(1);

            // Test the number of circles passing through 4 points
            picture.AllCircles.Count(circle => circle.Points.Count == 4).Should().Be(3, "two vertices and corresponding feet are concyclic");
        }
Esempio n. 29
0
        private static Configuration LineTangentToCircle()
        {
            // Create objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new ConstructedConfigurationObject(Incenter, A, B, C);
            var E = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, D, B, C);
            var F = new ConstructedConfigurationObject(PointReflection, E, D);
            var G = new ConstructedConfigurationObject(ReflectionInLineFromPoints, F, A, D);

            // Return the configuration
            return(Configuration.DeriveFromObjects(Triangle, A, B, C, D, E, F, G));
        }
Esempio n. 30
0
        private static Configuration ConcurrencyViaObjectIntroduction()
        {
            // Create objects
            var A = new LooseConfigurationObject(Point);
            var B = new LooseConfigurationObject(Point);
            var C = new LooseConfigurationObject(Point);
            var D = new ConstructedConfigurationObject(Orthocenter, A, B, C);
            var E = new ConstructedConfigurationObject(Circumcenter, B, C, D);
            var F = new ConstructedConfigurationObject(ParallelogramPoint, A, B, C);
            var G = new ConstructedConfigurationObject(Incenter, B, C, E);

            // Return the configuration
            return(Configuration.DeriveFromObjects(Triangle, A, B, C, D, E, F, G));
        }