/// <summary>
        /// Converts given theorems to a string, optionally with their proofs.
        /// </summary>
        /// <param name="formatter">The formatter of the configuration where the theorems hold.</param>
        /// <param name="analyzerOutput">The analyzer output to be converted to a string.</param>
        /// <param name="writeProofs">Indicates whether we should format theorem proofs.</param>
        /// <returns>The string representing the analyzer output.</returns>
        private static string AnalyzerOutputToString(OutputFormatter formatter, GeneratedProblemAnalyzerOutputBase analyzerOutput, bool writeProofs)
        {
            // Prepare the result
            var result = "";

            // Prepare a local theorem index
            var localTheoremIndex = 1;

            #region Theorem proofs

            // If we should write proofs and there are any
            if (writeProofs)
            {
                // Get them
                var proofs = ((GeneratedProblemAnalyzerOutputWithProofs)analyzerOutput).TheoremProofs;

                // If there are any
                if (proofs.Any())
                {
                    // Add the header
                    result += $"\n\nProved theorems:\n\n";

                    // Append theorem proofs by taking them
                    result += proofs
                              // Sorting by the statement of the proved theorem
                              .OrderBy(pair => formatter.FormatTheorem(pair.Key))
                              // Write proof for each with a local id
                              .Select(pair => $" {localTheoremIndex}. {formatter.FormatTheoremProof(pair.Value, tag: $"{localTheoremIndex++}.")}")
Example #2
0
        /// <summary>
        /// The entry method of the application.
        /// </summary>
        /// <param name="arguments">The three arguments:
        /// <list type="number">
        /// <item>Path to the inference rule folder.</item>
        /// <item>The extension of the inference rule files.</item>
        /// <item>Path to the object introduction rule file.</item>
        /// </list>
        /// </param>
        private static async Task Main(string[] arguments)
        {
            #region Kernel preparation

            // Prepare the settings for the inference rule provider
            var inferenceRuleProviderSettings = new InferenceRuleProviderSettings(ruleFolderPath: arguments[0], fileExtension: arguments[1]);

            // Prepare the settings for the object introduction rule provider
            var objectIntroductionRuleProviderSettings = new ObjectIntroductionRuleProviderSettings(filePath: arguments[2]);

            // Prepare the kernel
            var kernel = Infrastructure.NinjectUtilities.CreateKernel()
                         // That constructors configurations
                         .AddConstructor()
                         // That can find theorems
                         .AddTheoremFinder(new TheoremFindingSettings
                                           (
                                               // Look for theorems of any type
                                               soughtTheoremTypes: Enum.GetValues(typeof(TheoremType)).Cast <TheoremType>()
                                               // Except for the EqualObjects that don't have a finder
                                               .Except(TheoremType.EqualObjects.ToEnumerable())
                                               // Enumerate
                                               .ToArray(),

                                               // Exclude in-picture tangencies
                                               new TangentCirclesTheoremFinderSettings(excludeTangencyInsidePicture: true),
                                               new LineTangentToCircleTheoremFinderSettings(excludeTangencyInsidePicture: true)
                                           ))
                         // That can prove theorems
                         .AddTheoremProver(new TheoremProvingSettings
                                           (
                                               // Use the provider to find the inference rules
                                               new InferenceRuleManagerData(await new InferenceRuleProvider.InferenceRuleProvider(inferenceRuleProviderSettings).GetInferenceRulesAsync()),

                                               // Use the provider to find the object introduction rules
                                               new ObjectIntroducerData(await new ObjectIntroductionRuleProvider.ObjectIntroductionRuleProvider(objectIntroductionRuleProviderSettings).GetObjectIntroductionRulesAsync()),

                                               // Setup the prover
                                               new TheoremProverSettings
                                               (
                                                   // We will be strict and don't assume simplifiable theorems
                                                   assumeThatSimplifiableTheoremsAreTrue: false,

                                                   // We will find trivial theorems for all objects
                                                   findTrivialTheoremsOnlyForLastObject: false
                                               )
                                           ));

            #endregion

            #region Tests

            // Take the tests
            new[]
            {
                PerpendicularBisectorsAreConcurrent(),
                IncenterAndTangentLine(),
                Midpoints(),
                Parallelogram(),
                HiddenExcenter(),
                HiddenMidpoint(),
                LineTangentToCircle(),
                ConcurrencyViaObjectIntroduction(),
                SimpleLineSegments()
            }
            // Perform each
            .ForEach(configuration =>
            {
                #region Finding theorems

                // Prepare 3 pictures in which the configuration is drawn
                var pictures = kernel.Get <IGeometryConstructor>().ConstructWithUniformLayout(configuration, numberOfPictures: 3).pictures;

                // Prepare a contextual picture
                var contextualPicture = new ContextualPicture(pictures);

                // Find all theorems
                var theorems = kernel.Get <ITheoremFinder>().FindAllTheorems(contextualPicture);

                #endregion

                #region Writing theorems

                // Prepare the formatter of all the output
                var formatter = new OutputFormatter(configuration.AllObjects);

                // Prepare a local function that converts given theorems to a string
                string TheoremString(IEnumerable <Theorem> theorems) =>
                // If there are no theorems
                theorems.IsEmpty()
                // Then return an indication of it
                        ? "nothing"
                // Otherwise format each theorem
                        : theorems.Select(formatter.FormatTheorem)
                // Order alphabetically
                .Ordered()
                // Add the index
                .Select((theoremString, index) => $"[{index + 1}] {theoremString}")
                // Make each on a separate line
                .ToJoinedString("\n");

                // Write the configuration and theorems
                Console.WriteLine($"\nConfiguration:\n\n{formatter.FormatConfiguration(configuration).Indent(2)}\n");
                Console.WriteLine($"Theorems:\n\n{TheoremString(theorems.AllObjects).Indent(2)}\n");

                #endregion

                #region Proving theorems

                // Prepare a timer
                var totalTime = new Stopwatch();

                // Start it
                totalTime.Start();

                // Perform the theorem finding with proofs, without any assumed theorems
                var proverOutput = kernel.Get <ITheoremProver>().ProveTheoremsAndConstructProofs(new TheoremMap(), theorems, contextualPicture);

                // Stop the timer
                totalTime.Stop();

                #endregion

                #region Writing results

                // Get the proofs
                var proofString = proverOutput
                                  // Sort by the statement
                                  .OrderBy(pair => formatter.FormatTheorem(pair.Key))
                                  // Format each
                                  .Select(pair => formatter.FormatTheoremProof(pair.Value))
                                  // Trim
                                  .Select(proofString => proofString.Trim())
                                  // Make an empty line between each
                                  .ToJoinedString("\n\n");

                // Write it
                Console.WriteLine(proofString);

                // Write the unproven theorems too
                Console.WriteLine($"\nUnproved:\n\n{TheoremString(theorems.AllObjects.Except(proverOutput.Keys)).Indent(2)}\n");

                // Report time
                Console.WriteLine($"Total time: {totalTime.ElapsedMilliseconds}");
                Console.WriteLine("----------------------------------------------");

                #endregion
            });

            #endregion
        }