/// <summary> /// Find all theorems that hold true for the loose objects and the construction output of a given composed construction. /// </summary> /// <param name="composedConstruction">The composed construction to be examined.</param> /// <returns>The theorems holding true for the loose objects and the construction output.</returns> private IReadOnlyList <Theorem> FindTheoremsForComposedConstruction(ComposedConstruction composedConstruction) { // Local function that throws an exception void ThrowIncorrectConstructionException(string message, Exception innerException = null) // informing about the examination failure => throw new TheoremProverException($"Cannot examine construction {composedConstruction.Name}. {message}", innerException); // Create a helper constructed object that simulates the composed construction var helperConstructedObject = new ConstructedConfigurationObject(composedConstruction, // Its arguments will be the loose objects of the composed construction's configuration composedConstruction.Configuration.LooseObjects.Cast <ConfigurationObject>().ToArray()); // Prepare the configuration that simulates the composed construction var helperConfiguration = new Configuration(composedConstruction.Configuration.LooseObjectsHolder, new[] { helperConstructedObject }); // Safely execute var(pictures, data) = GeneralUtilities.TryExecute( // Construction of the new configuration () => _constructor.ConstructWithUniformLayout(helperConfiguration, NumberOfPicturesForFindingTrivialTheorems), // While making sure any exception is caught and re-thrown (InconsistentPicturesException e) => ThrowIncorrectConstructionException("The defining configuration couldn't be drawn.", e)); // Make sure it has no inconstructible objects if (data.InconstructibleObject != default) { ThrowIncorrectConstructionException("The defining configuration contains an inconstructible object."); } // Make sure it has no duplicates if (data.Duplicates != default) { ThrowIncorrectConstructionException("The defining configuration contains duplicate objects."); } // Safely execute var contextualPicture = GeneralUtilities.TryExecute( // Construction of the contextual picture () => new ContextualPicture(pictures), // While making sure any exception is caught and re-thrown (InconsistentPicturesException e) => ThrowIncorrectConstructionException("The contextual picture for the defining configuration couldn't be drawn.", e)); // Find the theorems return(_finder.FindAllTheorems(contextualPicture).AllObjects // Take those that say something about the last object // (there might be theorems in the layout as well, for example in RightTriangle) .Where(theorem => theorem.GetInnerConfigurationObjects().Contains(helperConstructedObject)) // We need to remap the helper constructed object to the one from the underlying configuration .Select(theorem => { // Prepare the mapping dictionary var mapping = new Dictionary <ConfigurationObject, ConfigurationObject> { // That already has the helper object remapped to the construction output { helperConstructedObject, composedConstruction.ConstructionOutput } }; // Add the loose objects to the mapping as identities composedConstruction.Configuration.LooseObjects.ForEach(looseObject => mapping.Add(looseObject, looseObject)); // Do the mapping return theorem.Remap(mapping); }) // Enumerate .ToList()); }
/// <summary> /// Initializes a new instance of the <see cref="ComposedConstructor"/> class. /// </summary> /// <param name="construction">The composed construction performed by the constructor.</param> /// <param name="constructionResolver">The resolver of constructors used while constructing the internal configuration of the composed construction.</param> /// <param name="tracer">The tracer for unexpected analytic exceptions.</param> public ComposedConstructor(ComposedConstruction construction, IConstructorResolver constructionResolver, IConstructorFailureTracer tracer) : base(tracer) { _construction = construction ?? throw new ArgumentNullException(nameof(construction)); _constructionResolver = constructionResolver ?? throw new ArgumentNullException(nameof(constructionResolver)); }