/// <summary> /// Finds all options for changing the definition of a given old theorem object based on the new (last) /// configuration object, which might have geometric properties related to this old object (for example, /// if the new object is a point and the old one is a line/circle, then it might lie on it). This includes /// even an option of not changing the definition at all, i.e. returning the original old object. /// </summary> /// <param name="oldTheoremObject">The old theorem object for which we're looking for definition change options.</param> /// <param name="contextualPicture">The contextual picture that represents the configuration.</param> /// <returns>The enumeration of all possible definition changes, including no change.</returns> private static IEnumerable <TheoremObject> FindDefinitionChangeOptions(TheoremObject oldTheoremObject, ContextualPicture contextualPicture) { // Find the new object of the configuration var newConfigurationObject = contextualPicture.Pictures.Configuration.LastConstructedObject; // Find its geometric version var newGeometricObject = contextualPicture.GetGeometricObject(newConfigurationObject); // Switch based on the type of old object switch (oldTheoremObject) { // If we have a point or line segment (internally consisting of points...) case PointTheoremObject _: case LineSegmentTheoremObject _: // Then there is no way to find a new definition of the object, // i.e. we return the 'no change of definition' option return(new[] { oldTheoremObject }); // If we have an object with points... case TheoremObjectWithPoints objectWithPoints: #region Find its geometric version // We're going to find the corresponding geometric version DefinableByPoints geometricObjectWithPoints = default; // If our object is defined explicitly if (objectWithPoints.DefinedByExplicitObject) { // Use the internal configuration object to get the definition directly geometricObjectWithPoints = (DefinableByPoints)contextualPicture.GetGeometricObject(objectWithPoints.ConfigurationObject); } // Otherwise it's defined by points else { // Get the points corresponding to its points var geometricPoints = objectWithPoints.Points // For each find the geometric point .Select(contextualPicture.GetGeometricObject) // We know they're points .Cast <PointObject>() // Enumerate .ToArray(); // Find the right object based on the type of the theorem object with points geometricObjectWithPoints = (objectWithPoints switch { // Looking for the line that contains our points // It certainly passes through the first point LineTheoremObject _ => geometricPoints[0].Lines.First(line => line.ContainsAll(geometricPoints)) as DefinableByPoints, // Looking for the circle that contains our points // It certainly passes through the first point CircleTheoremObject _ => geometricPoints[0].Circles.First(circle => circle.ContainsAll(geometricPoints)), // Unhandled cases _ => throw new TheoremFinderException($"Unhandled type of {nameof(TheoremObjectWithPoints)}: {objectWithPoints.GetType()}") }); }
/// <summary> /// Initializes a new instance of the <see cref="SimplificationRule"/> class. /// </summary> /// <param name="simplifableObject">The template of an object that can be simplified.</param> /// <param name="simplifiedObject">The template of the simplification of <see cref="SimplifiedObject"/>.</param> public SimplificationRule(TheoremObject simplifableObject, TheoremObject simplifiedObject) { SimplifableObject = simplifableObject ?? throw new ArgumentNullException(nameof(simplifableObject)); SimplifiedObject = simplifiedObject ?? throw new ArgumentNullException(nameof(simplifiedObject)); }