示例#1
0
        /// <summary>
        /// Runs the algorithm on the configuration to find old theorems (i.e. those who are true in the configuration
        /// with the last object removed), the new theorems (i.e. those that use the last object), the invalidated old
        /// theorems (see <see cref="ITheoremFinder.FindNewTheorems(ContextualPicture, TheoremMap, out Theorem[])"/>,
        /// and all theorems find via <see cref="ITheoremFinder.FindAllTheorems(ContextualPicture)"/>.
        /// </summary>
        /// <param name="configuration">The configuration where we're looking for theorems.</param>
        /// <returns>The old, new, invalidated all, and all theorems.</returns>
        private static (TheoremMap oldTheorems, TheoremMap newTheorems, Theorem[] invalidOldTheorems, TheoremMap allTheorems) FindTheorems(Configuration configuration)
        {
            // Prepare the kernel
            var kernel = NinjectUtilities.CreateKernel()
                         // With constructor
                         .AddConstructor()
                         // Look for only some types
                         .AddTheoremFinder(new TheoremFindingSettings(soughtTheoremTypes: new[]
            {
                ParallelLines,
                PerpendicularLines,
                EqualLineSegments,
                TangentCircles,
                LineTangentToCircle,
                Incidence,
                ConcurrentLines
            },
                                                                      // No exclusion of inside-picture tangencies
                                                                      tangentCirclesTheoremFinderSettings: new TangentCirclesTheoremFinderSettings(excludeTangencyInsidePicture: false),
                                                                      // Exclusion of inside-picture tangencies
                                                                      lineTangentToCircleTheoremFinderSettings: new LineTangentToCircleTheoremFinderSettings(excludeTangencyInsidePicture: true)));

            // Create the finder
            var finder = kernel.Get <ITheoremFinder>();

            // Create the old configuration, so we can find its theorems
            var oldConfiguration = new Configuration(configuration.LooseObjectsHolder,
                                                     // We just don't want to include the last object
                                                     configuration.ConstructedObjects.Except(new[] { configuration.LastConstructedObject }).ToList());

            // Construct the old configuration
            var oldPictures = kernel.Get <IGeometryConstructor>().ConstructWithUniformLayout(oldConfiguration, numberOfPictures: 5).pictures;

            // Construct the old contextual picture
            var oldContextualPicture = new ContextualPicture(oldPictures);

            // Finally get the old theorems
            var oldTheorems = finder.FindAllTheorems(oldContextualPicture);

            // Create the pictures for the current configuration
            var pictures = kernel.Get <IGeometryConstructor>().ConstructWithUniformLayout(configuration, numberOfPictures: 5).pictures;

            // Create the contextual picture for the current configuration
            var contextualPicture = new ContextualPicture(pictures);

            // Run both algorithms
            var newTheorems = finder.FindNewTheorems(contextualPicture, oldTheorems, out var invalidOldTheorems);
            var allTheorems = finder.FindAllTheorems(contextualPicture);

            // Return everything
            return(oldTheorems, newTheorems, invalidOldTheorems, allTheorems);
        }
示例#2
0
        /// <summary>
        /// The entry method of the application.
        /// </summary>
        /// <param name="arguments">Expects one argument, the path to the directory with outputs.</param>
        private static void Main(string[] arguments)
        {
            // Get the path to the folder with outputs
            var outputFolder = arguments.FirstOrDefault()
                               // Make aware if it's not been set
                               ?? throw new InvalidOperationException("Expected one argument, the path to the directory with outputs");

            // Setup Serilog so it logs to console
            Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();

            // Log the folder
            Log.Information("Exploring folder {outputFolder}", outputFolder);

            // Start timing
            var stopwatch = Stopwatch.StartNew();

            #region Prepare results folder

            // Create the path to the folder with results
            var resultsFolder = "Results";

            // If it exists, delete it
            if (Directory.Exists(resultsFolder))
            {
                Directory.Delete(resultsFolder, recursive: true);
            }

            // Recreate it
            Directory.CreateDirectory(resultsFolder);

            #endregion

            #region Prepare services

            // Prepare kernel
            var kernel = NinjectUtilities.CreateKernel()
                         // That uses Theorem Sorter
                         .AddTheoremSorter()
                         // And Constructor, needed for Theorem Sorter
                         .AddConstructor()
                         // And Ranked Theorem IO stuff
                         .AddRankedTheoremIO();

            // We will need to create theorem sorters
            var sorterFactory = kernel.Get <ITheoremSorterFactory>();

            // And ranked theorem writers
            var writerFactory = kernel.Get <IRankedTheoremJsonLazyWriterFactory>();

            // And use a reader
            var theoremReader = kernel.Get <IRankedTheoremJsonLazyReader>();
        /// <summary>
        /// Runs the algorithm on the configuration to find new and all theorems.
        /// </summary>
        /// <param name="configuration">The configuration where we're looking for theorems.</param>
        /// <param name="instanceFactory">The factory for creating an instance of the finder. If it's null, the default constructor is used.</param>
        /// <returns>The new and all theorems.</returns>
        protected (List <Theorem> newTheorems, List <Theorem> allTheorems) FindTheorems(Configuration configuration, Func <T> instanceFactory = null)
        {
            // Prepare the kernel with the constructor module
            var kernel = NinjectUtilities.CreateKernel().AddConstructor();

            // Create the pictures
            var pictures = kernel.Get <IGeometryConstructor>().ConstructWithUniformLayout(configuration, numberOfPictures: 5).pictures;

            // Create the contextual picture
            var contextualPicture = new ContextualPicture(pictures);

            // If the instance factory is specified
            var finder = instanceFactory != null?
                         // Invoke it
                         instanceFactory() :
                             // Otherwise use reflection to call the parameterless constructor
                             Activator.CreateInstance <T>();

            // Run both algorithms
            return(finder.FindNewTheorems(contextualPicture).ToList(), finder.FindAllTheorems(contextualPicture).ToList());
        }
示例#4
0
        /// <summary>
        /// Assembles all needed components for the application and performs the <paramref name="applicationCode"/> function.
        /// <para>
        /// <list type="number">
        /// <item>It builds <see cref="JsonConfiguration"/> using either <paramref name="customConfigurationFilePaths"/>, if they
        /// are not empty, or files <see cref="DefaultConfigurationFilePath"/> and <see cref="DevConfigurationFilePath"/>.</item>
        /// <item>Sets up Serilog logging using <see cref="LoggingUtilities.SetupSerilog(JsonConfiguration)"/>.</item>
        /// <item>Constructs an empty Ninject kernel using <see cref="NinjectUtilities.CreateKernel"/>.</item>
        /// <item>Runs the <paramref name="applicationCode"/> and logs its exceptions.</item>
        /// </list>
        /// </para>
        /// </summary>
        /// <param name="customConfigurationFilePaths">The paths to custom configuration files loaded in this order. If no files are
        /// specified, then the files <see cref="DefaultConfigurationFilePath"/> and <see cref="DevConfigurationFilePath"/> are used.</param>
        /// <param name="applicationCode">The function performing the actual application code.</param>
        public static async Task Run(string[] customConfigurationFilePaths, Func <IKernel, JsonConfiguration, Task> applicationCode)
        {
            #region Load JsonConfiguration

            // Prepare the variable for settings
            JsonConfiguration jsonConfiguration;

            try
            {
                // If the custom files are specified...
                jsonConfiguration = customConfigurationFilePaths.Length != 0
                                    // Load the configuration from them
                    ? new JsonConfiguration(customConfigurationFilePaths)
                                    // Otherwise use the default files
                    : new JsonConfiguration(DefaultConfigurationFilePath, DevConfigurationFilePath);
            }
            catch (Exception e)
            {
                // Re-throw
                throw new ConfigurationException($"Cannot set up a JsonConfiguration from arguments: {customConfigurationFilePaths.ToJoinedString()}", e);
            }

            #endregion

            #region Logging

            try
            {
                // Ensure we have logging
                LoggingUtilities.SetupSerilog(jsonConfiguration);
            }
            catch (Exception e)
            {
                // Re-throw
                throw new LoggingException($"Cannot set up Serilog using the configuration loaded from {customConfigurationFilePaths.ToJoinedString()}", e);
            }

            #endregion

            #region Application Code

            try
            {
                // Log start
                Log.Information("The application has started.");

                // Log from where we have the configuration from
                Log.Information("Configuration loaded from files: {files}", jsonConfiguration.LoadedConfigurationFilePaths.ToJoinedString());

                // Prepare a stopwatch
                var stopwatch = Stopwatch.StartNew();

                // Execute the application code with a new empty kernel
                await applicationCode(NinjectUtilities.CreateKernel(), jsonConfiguration);

                // Log end
                Log.Information("The application has finished correctly in {time:F2} sec.\n", stopwatch.ElapsedMilliseconds / 1000d);
            }
            // Catch for any unhandled exception
            catch (Exception e)
            {
                // Log if there is any
                Log.Fatal(e, $"An unexpected exception has occurred.");

                // This is a sad end
                throw;
            }

            #endregion
        }
示例#5
0
        /// <summary>
        /// The entry method of the application.
        /// </summary>
        private static void Main()
        {
            // Setup simple logger
            Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();

            // Initialize the kernel
            _kernel = NinjectUtilities.CreateKernel()
                      // Add the constructor
                      .AddConstructor()
                      // Add the configuration generator that uses fast generation (it does not really matter here)
                      .AddConfigurationGenerator(new GenerationSettings(ConfigurationFilterType.Fast));

            // Bind the generator
            _kernel.Bind <IProblemGenerator>().To <ProblemGenerator.ProblemGenerator>();

            // Add an empty failure tracer
            _kernel.Bind <IGeometryFailureTracer>().To <EmptyGeometryFailureTracer>();

            // Add an empty theorem finder
            _kernel.Bind <ITheoremFinder>().To <EmptyTheoremFinder>();

            // Load the construction file
            _constructions = File.ReadAllLines("constructions.txt")
                             // Each line should be a construction
                             .Select(Parser.ParseConstruction)
                             // Enumerate
                             .ToReadOnlyHashSet();

            // Load the template input file
            _templateInputFile = File.ReadAllText("input_template.txt");

            #region Preparing the results folder

            // Create the path to the folder with inputs
            var resultsFolder = "Results";

            // If the folder exists, clear it
            if (Directory.Exists(resultsFolder))
            {
                Directory.Delete(resultsFolder, recursive: true);
            }

            // Otherwise create it
            else
            {
                Directory.CreateDirectory(resultsFolder);
            }

            #endregion

            // Prepare the stopwatch
            var stopwatch = Stopwatch.StartNew();

            // Prepare the counter of generated inputs
            var counter = 0;

            // Go through the all types of generated input files
            new[]
            {
                Triangle_TwoObjects_PlusThreeObjects(),
                Triangle_FourObjects_OnlyFullySymmetric_PlusTwoObjects(),
                Triangle_FourObjects_TwoLinesAndTwoPoints_OnlySymmetric_OnlyUsedLines_PlusTwoObjects(),
                Triangle_FourObjects_ThreeLinesAndOnePoint_OnlySymmetric_OnlyUsedLines_PlusTwoObjects(),
                Quadrilateral_TwoObjects_PlusTwoObjects()
            }
            // Merge the inputs
            .Flatten()
            // Handle each generated file
            .ForEach(input =>
            {
                // Count the input in
                counter++;

                // Log the count, but not too often
                if (counter % 100 == 0)
                {
                    Log.Information("{count} files after {time} ms.", counter, stopwatch.ElapsedMilliseconds);
                }

                // Prepare the constructions as a single string
                var constructionString = input.Constructions
                                         // For each take the name
                                         .Select(construction => construction.Name)
                                         // Each on a separate line
                                         .ToJoinedString("\n");

                // Prepare the formatted configuration by creating a formatter for it
                var configurationString = new OutputFormatter(input.InitialConfiguration.AllObjects)
                                          // Formatting it
                                          .FormatConfiguration(input.InitialConfiguration)
                                          // Replacing any curly braces in the definitions
                                          .Replace("{", "").Replace("}", "");

                // Prepare the content by taking the template file
                var content = _templateInputFile
                              // Replace the constructions
                              .Replace("{Constructions}", constructionString)
                              // Replace the configuration
                              .Replace("{InitialConfiguration}", configurationString)
                              // Replace the iterations
                              .Replace("{Iterations}", input.NumberOfIterations.ToString())
                              // Replace maximal points
                              .Replace("{MaximalPoints}", input.MaximalNumbersOfObjectsToAdd[Point].ToString())
                              // Replace maximal lines
                              .Replace("{MaximalLines}", input.MaximalNumbersOfObjectsToAdd[Line].ToString())
                              // Replace maximal circles
                              .Replace("{MaximalCircles}", input.MaximalNumbersOfObjectsToAdd[Circle].ToString())
                              // Replace the symmetry generation mode
                              .Replace("{SymmetryGenerationMode}", input.SymmetryGenerationMode.ToString());

                // Create the directory where the file goes
                Directory.CreateDirectory(Path.Combine(resultsFolder, $"input_{counter}"));

                // Write the content
                File.WriteAllText(Path.Combine(resultsFolder, $"input_{counter}/input_{counter}.txt"), content);
            });

            // Log how many files have been created
            Log.Information("Generated {counter} file(s) after {time} ms.", counter, stopwatch.ElapsedMilliseconds);
        }
 /// <summary>
 /// Gets an instance of the generator.
 /// </summary>
 /// <param name="filterType">The type of configuration filter to be used</param>
 private static IConfigurationGenerator GetGenerator(ConfigurationFilterType filterType) => NinjectUtilities.CreateKernel().AddConfigurationGenerator(new GenerationSettings(filterType)).Get <IConfigurationGenerator>();