/// <summary> /// Initializes a new instance of the <see cref="Theorem"/> object. /// </summary> /// <param name="type">The type of the theorem.</param> /// <param name="involvedObjects">The theorem objects that this theorem is about.</param> public Theorem(TheoremType type, IEnumerable <TheoremObject> involvedObjects) { Type = type; InvolvedObjects = involvedObjects?.ToReadOnlyHashSet() ?? throw new ArgumentNullException(nameof(involvedObjects)); // Get the list version of the objects InvolvedObjectsList = InvolvedObjects.ToList(); // Ensure the number of objects is correct if (InvolvedObjects.Count != type.GetNumberOfNeededObjects()) { throw new GeoGenException($"Cannot create theorem of type '{type}', incorrect number of objects: {InvolvedObjects.Count}"); } }
/// <summary> /// Initializes a new instance of the <see cref="Theorem"/> object. /// </summary> /// <param name="type">The type of the theorem.</param> /// <param name="involvedObjects">The list of theorem objects that will be wrapped directly in particular theorem objects.</param> public Theorem(TheoremType type, params ConfigurationObject[] objects) { Type = type; // Create involved objects InvolvedObjects = objects.Select(configurationObject => configurationObject.ObjectType switch { // Point case ConfigurationObjectType.Point => new PointTheoremObject(configurationObject) as TheoremObject, // Line case ConfigurationObjectType.Line => new LineTheoremObject(configurationObject), // Circle case ConfigurationObjectType.Circle => new CircleTheoremObject(configurationObject), // Unhandled cases _ => throw new GeoGenException($"Unhandled value of {nameof(ConfigurationObjectType)}: {configurationObject.ObjectType}"), })
/// <summary> /// Initializes a new instance of the <see cref="AnalyticTheorem"/> class. /// </summary> /// <param name="theorem">The theorem that should be drawn analytically.</param> /// <param name="picture">The picture where the inner objects of the theorem are drawn.</param> public AnalyticTheorem(Theorem theorem, Picture picture) { // Set the type _type = theorem.Type; // Set the content by switching on the type _content = _type switch { // These types can be compared as object sets TheoremType.CollinearPoints or TheoremType.ConcyclicPoints or TheoremType.ConcurrentLines or TheoremType.ParallelLines or TheoremType.PerpendicularLines or TheoremType.TangentCircles or TheoremType.LineTangentToCircle or TheoremType.Incidence => // Take the inner objects theorem.InvolvedObjects // We know they are base .Cast <BaseTheoremObject>() // And therefore constructible .Select(picture.Construct) // Enumerate them to a read-only hash set .ToReadOnlyHashSet(), // In this case we have two line segment objects TheoremType.EqualLineSegments => // Take the inner objects theorem.InvolvedObjects // We know they are line segments .Cast <LineSegmentTheoremObject>() // From each create their point set .Select(segment => segment.PointSet.Select(picture.Construct).ToReadOnlyHashSet()) // Enumerate them to a read-only hash set .ToReadOnlyHashSet(), // Unhandled cases _ => throw new TheoremSorterException($"Unhandled value of {nameof(TheoremType)}: {_type}"), }; }
/// <summary> /// Gets the number of <see cref="TheoremObject"/> that are required for a theorem of this type. /// </summary> /// <param name="type">The theorem type.</param> /// <returns>The needed number of numbers.</returns> public static int GetNumberOfNeededObjects(this TheoremType type) => type switch {
/// <summary> /// Initializes a new instance of the <see cref="TheoremFinderBase"/> class. /// </summary> protected TheoremFinderBase() { // Find the type Type = FindTypeFromClassName(); }