示例#1
0
        /// <summary>
        /// Tries to find the object corresponding to a given one with respect to a given mapping.
        /// If the object is not present in the mapping, it assumed the passed object is
        /// a constructed one and tries to construct it by remapping its arguments. If it fails,
        /// a <see cref="GeoGenException"/> is thrown. (This is a helper method used by implementations
        /// of <see cref="Remap(IReadOnlyDictionary{ConfigurationObject, ConfigurationObject})"/>).
        /// </summary>
        /// <param name="configurationObject">The configuration object to be mapped.</param>
        /// <param name="mapping">The dictionary representing the mapping.</param>
        /// <returns>The remapped configuration object, or null, if mapping would yield a new incorrect constructed object.</returns>
        protected static ConfigurationObject Map(ConfigurationObject configurationObject, IReadOnlyDictionary <ConfigurationObject, ConfigurationObject> mapping)
        {
            // If the object is directly present in the map, return it
            if (mapping.ContainsKey(configurationObject))
            {
                return(mapping[configurationObject]);
            }

            // Otherwise we assume the passed object is a constructed one
            var constructedObject = configurationObject as ConstructedConfigurationObject
                                    // If not, make aware
                                    ?? throw new GeoGenException("Cannot do the mapping, because the passed object is not in the map, nor it's constructed.");

            // Convert the individual passed objects
            var mappedObjects = constructedObject.PassedArguments.FlattenedList
                                // Look for the inner objects in the mapping
                                .Select(innerObject => mapping.GetValueOrDefault(innerObject)
                                // They must be there
                                        ?? throw new GeoGenException("Cannot do the mapping, because not all the arguments of the passed object are in the map."))
                                // Enumerate
                                .ToArray();

            // If the objects are not same, the mapping cannot be done
            if (mappedObjects.AnyDuplicates())
            {
                return(null);
            }

            // Otherwise construct the remapped object
            return(new ConstructedConfigurationObject(constructedObject.Construction, mappedObjects));
        }
示例#2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PointTheoremObject"/> class.
 /// </summary>
 /// <param name="configurationObject">The configuration object whose type must be <see cref="ConfigurationObjectType.Point"/>.</param>
 public PointTheoremObject(ConfigurationObject configurationObject)
     : base(configurationObject)
 {
     // Make sure the object is not null
     if (configurationObject == null)
     {
         throw new GeoGenException("A point theorem object must have its configuration object set.");
     }
 }
示例#3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TheoremObjectWithPoints"/> class
 /// defining by a <see cref="ConfigurationObject"/>.
 /// </summary>
 /// <param name="configurationObject">The configuration object representing this theorem object.</param>
 protected TheoremObjectWithPoints(ConfigurationObject configurationObject)
     : base(configurationObject)
 {
     // Make sure the defining object exists
     if (configurationObject == null)
     {
         throw new GeoGenException("The defining configuration object cannot be null.");
     }
 }
示例#4
0
        /// <summary>
        /// Gets the string definition of a passed configuration object. Loose objects have only
        /// names as their definition, whereas constructed objects have the construction and arguments.
        /// </summary>
        /// <param name="configurationObject">The object that we're formatting.</param>
        /// <returns>The string representing the object.</returns>
        public string FormatConfigurationObject(ConfigurationObject configurationObject)
        {
            // Switch based on the object
            return(configurationObject switch
            {
                // Loose objects have their names as the definition
                LooseConfigurationObject _ => _objectNames[configurationObject],

                // For constructed objects we include the construction and arguments
                ConstructedConfigurationObject constructedObject => $"{constructedObject.Construction.Name}({constructedObject.PassedArguments.Select(FormatArgument).ToJoinedString()})",

                // Unhandled cases
                _ => throw new GeoGenException($"Unhandled type of {nameof(ConfigurationObject)}: {configurationObject.GetType()}")
            });
示例#5
0
 /// <summary>
 /// Finds the objects that define this object, in an order in which they can be constructed, including this one.
 /// </summary>
 /// <param name="configurationObject">The configuration object.</param>
 /// <returns>The collection of the defining objects.</returns>
 public static IReadOnlyList <ConfigurationObject> GetDefiningObjects(this ConfigurationObject configurationObject) => configurationObject.ToEnumerable().GetDefiningObjects();
示例#6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LineTheoremObject"/>
 /// class defined by points.
 /// </summary>
 /// <param name="point1">A point of the line.</param>
 /// <param name="point2">A point of the line.</param>
 public LineTheoremObject(ConfigurationObject point1, ConfigurationObject point2)
     : base(point1, point2)
 {
 }
示例#7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LineTheoremObject"/> class
 /// defined by a line configuration object.
 /// </summary>
 /// <param name="lineObject">The configuration line object representing this theorem object.</param>
 public LineTheoremObject(ConfigurationObject lineObject)
     : base(lineObject)
 {
 }
示例#8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CircleTheoremObject"/>
 /// class defined by points.
 /// </summary>
 /// <param name="point1">A point of the circle.</param>
 /// <param name="point2">A point of the circle.</param>
 /// <param name="point3">A point of the circle.</param>
 public CircleTheoremObject(ConfigurationObject point1, ConfigurationObject point2, ConfigurationObject point3)
     : base(point1, point2, point3)
 {
 }
示例#9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CircleTheoremObject"/> class
 /// defined by a circle configuration object.
 /// </summary>
 /// <param name="circleObject">The configuration circle object representing this theorem object.</param>
 public CircleTheoremObject(ConfigurationObject circleObject)
     : base(circleObject)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ObjectConstructionArgument"/> class.
 /// </summary>
 /// <param name="passedObject">The configuration object that is passed as an argument.</param>
 public ObjectConstructionArgument(ConfigurationObject passedObject)
 {
     PassedObject = passedObject ?? throw new ArgumentNullException(nameof(passedObject));
 }
示例#11
0
 /// <inheritdoc/>
 public override int GetHashCode() => ConfigurationObject.GetHashCode();
示例#12
0
 /// <inheritdoc/>
 public override IEnumerable <ConfigurationObject> GetInnerConfigurationObjects() => ConfigurationObject.ToEnumerable();
 /// <summary>
 /// Initializes a new instance of the <see cref="LineSegmentTheoremObject"/> class.
 /// </summary>
 /// <param name="point1">The first point of the line segment.</param>
 /// <param name="point2">The second line of the line segment.</param>
 public LineSegmentTheoremObject(ConfigurationObject point1, ConfigurationObject point2)
     : this(new PointTheoremObject(point1), new PointTheoremObject(point2))
 {
 }