#![deny(rustdoc::broken_intra_doc_links)]

use crate::{
    bounds::{Closed, LowerBound, Open, UpperBound},
    intervals::{
        BoundType, Contains, GetLowerBoundValue, GetUpperBoundValue, Interval,
        IntervalBoundRuntime, IntervalBoundsRuntime, IntervalTrait, LowerBoundRuntime,
        UpperBoundRuntime, ValueWithinBound, operations::IntervalOperations,
    },
};
use duplicate::duplicate_item;
use getset::Getters;
use num_valid::RealScalar;
use serde::{Deserialize, Serialize};
use try_create::New;

///  Container for all intervals with infinite, unbounded length.
///
/// The [`IntervalInfiniteLength`] enum represents intervals that extend infinitely
/// in one or both directions, encompassing the entire spectrum of unbounded interval
/// types. These intervals have infinite measure and are essential for modeling
/// domains that extend beyond any finite boundary.
///
/// ## Mathematical Foundation
///
/// Unbounded intervals are fundamental in mathematical analysis and represent sets
/// that extend infinitely along the real line. They fall into several categories:
///
/// - **Fully unbounded**: The entire real line `(-∞, +∞)`
/// - **Semi-bounded**: Intervals bounded on one side, infinite on the other
///
/// Mathematical properties of infinite-length intervals:
/// - **Infinite measure**: `μ(I) = +∞` for all variants
/// - **Uncountable cardinality**: All intervals contain uncountably infinite points
/// - **Non-compactness**: No infinite interval is compact
/// - **Connectedness**: All intervals are connected sets with non-empty interior
///
/// ## Generic Over Any `RealScalar` Type
///
/// **The [`IntervalInfiniteLength`] enum works seamlessly with any scalar type implementing [`num_valid::RealScalar`]:**
///
/// | Scalar Type | Performance | Validation | Best For |
/// |-------------|-------------|------------|----------|
/// | [`f64`] | ⚡⚡⚡ Maximum | ❌ None | Trusted input, maximum speed |
/// | [`RealNative64StrictFiniteInDebug`](num_valid::RealNative64StrictFiniteInDebug) | ⚡⚡⚡ **Same as f64** | ✅ **Debug only** | **Recommended for most uses** |
/// | [`RealNative64StrictFinite`](num_valid::RealNative64StrictFinite) | ⚡⚡ Small overhead | ✅ Always | Safety-critical applications |
/// | `RealRugStrictFinite` | ⚡ Precision-dependent | ✅ Always | Arbitrary precision needs (available from the [num-valid](https://crates.io/crates/num-valid) crate when compiled with `--features=rug`)|
///
/// ## Enum Variants and Boundary Semantics
///
/// The five variants cover all possible unbounded interval configurations:
///
/// ### [`IntervalInfiniteLength::LowerUnboundedUpperUnbounded`] - `(-∞, +∞)`
/// **The entire real line**
/// - **Mathematical notation**: `(-∞, +∞) = ℝ`
/// - **Boundary behavior**: No finite bounds
/// - **Contains**: Every real number
/// - **Use cases**: Unrestricted domains, entire function spaces, universal sets
///
/// ### [`IntervalInfiniteLength::LowerClosedUpperUnbounded`] - `[a, +∞)`
/// **Lower bound included, extends to positive infinity**
/// - **Mathematical notation**: `[a, +∞) = {x ∈ ℝ : x ≥ a}`
/// - **Boundary behavior**: Includes `a`, no upper limit
/// - **Use cases**: "At least" constraints, cumulative distributions, growth models
///
/// ### [`IntervalInfiniteLength::LowerOpenUpperUnbounded`] - `(a, +∞)`
/// **Lower bound excluded, extends to positive infinity**
/// - **Mathematical notation**: `(a, +∞) = {x ∈ ℝ : x > a}`
/// - **Boundary behavior**: Excludes `a`, no upper limit
/// - **Use cases**: Strict "greater than" constraints, limit domains
///
/// ### [`IntervalInfiniteLength::LowerUnboundedUpperClosed`] - `(-∞, b]`
/// **Extends from negative infinity, upper bound included**
/// - **Mathematical notation**: `(-∞, b] = {x ∈ ℝ : x ≤ b}`
/// - **Boundary behavior**: No lower limit, includes `b`
/// - **Use cases**: "At most" constraints, capacity limits, upper thresholds
///
/// ### [`IntervalInfiniteLength::LowerUnboundedUpperOpen`] - `(-∞, b)`
/// **Extends from negative infinity, upper bound excluded**
/// - **Mathematical notation**: `(-∞, b) = {x ∈ ℝ : x < b}`
/// - **Boundary behavior**: No lower limit, excludes `b`
/// - **Use cases**: Strict "less than" constraints, approach limits
///
/// ## Construction Patterns
///
/// ### From Concrete Interval Types (Recommended)
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::RealNative64StrictFiniteInDebug;
/// use try_create::TryNew;
///
/// // Use the recommended performance-optimal type
/// type Real = RealNative64StrictFiniteInDebug;
///
/// // Create specific unbounded interval types, then convert
/// let lower_bounded = IntervalLowerClosedUpperUnbounded::new(
///     Real::try_new(0.0).unwrap()
/// );
/// let infinite: IntervalInfiniteLength<Real> = lower_bounded.into();
///
/// let upper_bounded = IntervalLowerUnboundedUpperClosed::new(
///     Real::try_new(100.0).unwrap()
/// );
/// let infinite: IntervalInfiniteLength<Real> = upper_bounded.into();
/// ```
///
/// ### Direct Construction (Advanced)
/// ```rust
/// use grid1d::intervals::*;
/// use try_create::New;
///
/// // Build variants directly
/// let unbounded = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
///
/// let lower_closed = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(0.0)
/// );
///
/// let lower_open = IntervalInfiniteLength::LowerOpenUpperUnbounded(
///     IntervalLowerOpenUpperUnbounded::new(1.0)
/// );
///
/// let upper_closed = IntervalInfiniteLength::LowerUnboundedUpperClosed(
///     IntervalLowerUnboundedUpperClosed::new(10.0)
/// );
///
/// let upper_open = IntervalInfiniteLength::LowerUnboundedUpperOpen(
///     IntervalLowerUnboundedUpperOpen::new(5.0)
/// );
/// ```
///
/// ## Core Operations
///
/// All [`IntervalInfiniteLength`] instances support the complete [`IntervalTrait`] interface:
///
/// ### Point Containment Testing
/// ```rust
/// use grid1d::intervals::*;
/// use try_create::New;
///
/// let unbounded = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
/// let lower_bounded = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(0.0)
/// );
/// let upper_bounded = IntervalInfiniteLength::LowerUnboundedUpperClosed(
///     IntervalLowerUnboundedUpperClosed::new(100.0)
/// );
///
/// // Unbounded contains everything
/// assert!(unbounded.contains_point(&-1000.0));
/// assert!(unbounded.contains_point(&0.0));
/// assert!(unbounded.contains_point(&1000.0));
///
/// // Lower bounded includes the bound and everything above
/// assert!(lower_bounded.contains_point(&0.0));    // Boundary included
/// assert!(lower_bounded.contains_point(&50.0));   // Above boundary
/// assert!(!lower_bounded.contains_point(&-1.0));  // Below boundary
///
/// // Upper bounded includes the bound and everything below
/// assert!(upper_bounded.contains_point(&100.0));  // Boundary included
/// assert!(upper_bounded.contains_point(&50.0));   // Below boundary
/// assert!(!upper_bounded.contains_point(&101.0)); // Above boundary
/// ```
///
/// ### Boundary Behavior Differences
/// ```rust
/// use grid1d::intervals::*;
///
/// let lower_closed = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(5.0)
/// );
/// let lower_open = IntervalInfiniteLength::LowerOpenUpperUnbounded(
///     IntervalLowerOpenUpperUnbounded::new(5.0)
/// );
///
/// // Closed includes the boundary point
/// assert!(lower_closed.contains_point(&5.0));    // [5, +∞) includes 5
/// assert!(lower_closed.contains_point(&5.1));    // Above boundary
///
/// // Open excludes the boundary point
/// assert!(!lower_open.contains_point(&5.0));     // (5, +∞) excludes 5
/// assert!(lower_open.contains_point(&5.1));      // Above boundary
///
/// let upper_closed = IntervalInfiniteLength::LowerUnboundedUpperClosed(
///     IntervalLowerUnboundedUpperClosed::new(10.0)
/// );
/// let upper_open = IntervalInfiniteLength::LowerUnboundedUpperOpen(
///     IntervalLowerUnboundedUpperOpen::new(10.0)
/// );
///
/// // Closed includes the boundary point
/// assert!(upper_closed.contains_point(&10.0));   // (-∞, 10] includes 10
/// assert!(upper_closed.contains_point(&9.9));    // Below boundary
///
/// // Open excludes the boundary point
/// assert!(!upper_open.contains_point(&10.0));    // (-∞, 10) excludes 10
/// assert!(upper_open.contains_point(&9.9));      // Below boundary
/// ```
///
/// ### Interval Containment Testing
/// ```rust
/// use grid1d::intervals::*;
/// use try_create::New;
///
/// let unbounded = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
/// let lower_bounded = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(0.0)
/// );
/// let finite = IntervalClosed::new(-10.0, 10.0);
///
/// // Unbounded contains all other intervals
/// assert!(unbounded.contains_interval(&lower_bounded));   // ℝ ⊇ [0, +∞)
/// assert!(unbounded.contains_interval(&finite));          // ℝ ⊇ [-10, 10]
///
/// // Semi-bounded can contain finite intervals
/// let positive_finite = IntervalClosed::new(1.0, 10.0);
/// assert!(lower_bounded.contains_interval(&positive_finite)); // [0, +∞) ⊇ [1, 10]
/// assert!(!lower_bounded.contains_interval(&finite));         // [0, +∞) ⊉ [-10, 10]
///
/// let upper_bounded = IntervalInfiniteLength::LowerUnboundedUpperClosed(
///     IntervalLowerUnboundedUpperClosed::new(100.0)
/// );
/// assert!(!lower_bounded.contains_interval(&upper_bounded)); // [0, +∞) ⊉ (-∞, 100]
/// assert!(!upper_bounded.contains_interval(&lower_bounded)); // (-∞, 100] ⊉ [0, +∞)
///
/// let upper_bounded_2 = IntervalInfiniteLength::LowerUnboundedUpperOpen(
///     IntervalLowerUnboundedUpperOpen::new(200.0)
/// );
/// assert!(!upper_bounded.contains_interval(&upper_bounded_2)); // (-∞, 100] ⊉ (-∞, 200)
/// assert!(upper_bounded_2.contains_interval(&upper_bounded));  // (-∞, 200) ⊇ (-∞, 100]  
/// ```
///
/// ### Intersection Operations
/// ```rust
/// use grid1d::intervals::*;
///
/// let lower_bounded = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(0.0)
/// );
/// let upper_bounded = IntervalInfiniteLength::LowerUnboundedUpperClosed(
///     IntervalLowerUnboundedUpperClosed::new(10.0)
/// );
///
/// if let Some(intersection) = lower_bounded.intersection(&upper_bounded) {
///     // Result: [0, 10] - finite intersection of infinite intervals
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(positive)) => {
///             assert_eq!(positive.length().into_inner(), 10.0);
///             println!("Intersection is finite: [0, 10]");
///         }
///         _ => unreachable!("Expected finite positive-length interval"),
///     }
/// }
///
/// let unbounded = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
/// let semi_bounded = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(5.0)
/// );
///
/// if let Some(intersection) = unbounded.intersection(&semi_bounded) {
///     // Result: [5, +∞) - intersection with universal set gives original
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerClosedUpperUnbounded(interval)) => {
///             assert_eq!(interval.lower_bound_value(), &5.0);
///         }
///         _ => unreachable!("Expected lower-bounded infinite interval"),
///     }
/// }
///
/// // Disjoint infinite intervals
/// let positive = IntervalInfiniteLength::LowerOpenUpperUnbounded(
///     IntervalLowerOpenUpperUnbounded::new(0.0)
/// );
/// let negative = IntervalInfiniteLength::LowerUnboundedUpperOpen(
///     IntervalLowerUnboundedUpperOpen::new(0.0)
/// );
/// assert!(positive.intersection(&negative).is_none()); // (0, +∞) ∩ (-∞, 0) = ∅
/// ```
///
/// ## Pattern Matching and Variant Analysis
///
/// ### Distinguishing Between Unbounded Types
/// ```rust
/// use grid1d::intervals::*;
/// use try_create::New;
///
/// fn analyze_infinite_interval(interval: &IntervalInfiniteLength<f64>) -> String {
///     match interval {
///         IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_) => {
///             "Universal set: (-∞, +∞) - contains all real numbers".to_string()
///         }
///         IntervalInfiniteLength::LowerClosedUpperUnbounded(bounded) => {
///             format!("Lower bounded: [{}, +∞) - at least {}",
///                     bounded.lower_bound_value(), bounded.lower_bound_value())
///         }
///         IntervalInfiniteLength::LowerOpenUpperUnbounded(bounded) => {
///             format!("Lower bounded: ({}, +∞) - strictly greater than {}",
///                     bounded.lower_bound_value(), bounded.lower_bound_value())
///         }
///         IntervalInfiniteLength::LowerUnboundedUpperClosed(bounded) => {
///             format!("Upper bounded: (-∞, {}] - at most {}",
///                     bounded.upper_bound_value(), bounded.upper_bound_value())
///         }
///         IntervalInfiniteLength::LowerUnboundedUpperOpen(bounded) => {
///             format!("Upper bounded: (-∞, {}) - strictly less than {}",
///                     bounded.upper_bound_value(), bounded.upper_bound_value())
///         }
///     }
/// }
///
/// let unbounded = IntervalInfiniteLength::LowerUnboundedUpperUnbounded(
///     IntervalLowerUnboundedUpperUnbounded::<f64>::new());
/// let lower_bounded = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(0.0)
/// );
/// let upper_bounded = IntervalInfiniteLength::LowerUnboundedUpperOpen(
///     IntervalLowerUnboundedUpperOpen::new(100.0)
/// );
///
/// println!("{}", analyze_infinite_interval(&unbounded));
/// // Output: "Universal set: (-∞, +∞) - contains all real numbers"
///
/// println!("{}", analyze_infinite_interval(&lower_bounded));
/// // Output: "Lower bounded: [0, +∞) - at least 0"
///
/// println!("{}", analyze_infinite_interval(&upper_bounded));
/// // Output: "Upper bounded: (-∞, 100) - strictly less than 100"
/// ```
///
/// ### Extracting Bound Information
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::RealScalar;
///
/// fn extract_finite_bounds<RealType: RealScalar>(
///     interval: &IntervalInfiniteLength<RealType>) -> (Option<RealType>, Option<RealType>)
/// {
///     let lower = match interval {
///         IntervalInfiniteLength::LowerClosedUpperUnbounded(bounded) => {
///             Some(bounded.lower_bound_value().clone())
///         },
///         IntervalInfiniteLength::LowerOpenUpperUnbounded(bounded) => {
///             Some(bounded.lower_bound_value().clone())
///         }
///         _ => None,
///     };
///     let upper = match interval {
///         IntervalInfiniteLength::LowerUnboundedUpperClosed(bounded) => {
///             Some(bounded.upper_bound_value().clone())
///         }
///         IntervalInfiniteLength::LowerUnboundedUpperOpen(bounded) => {
///             Some(bounded.upper_bound_value().clone())
///         }
///         _ => None,
///     };
///     
///     (lower, upper)
/// }
///
/// let lower_bounded = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(5.0)
/// );
/// let upper_bounded = IntervalInfiniteLength::LowerUnboundedUpperClosed(
///     IntervalLowerUnboundedUpperClosed::new(10.0)
/// );
/// let unbounded = IntervalInfiniteLength::LowerUnboundedUpperUnbounded(
///     IntervalLowerUnboundedUpperUnbounded::<f64>::new()
/// );
///
/// assert_eq!(extract_finite_bounds(&lower_bounded), (Some(5.0), None));
/// assert_eq!(extract_finite_bounds(&upper_bounded), (None, Some(10.0)));
/// assert_eq!(extract_finite_bounds(&unbounded), (None, None));
/// ```
///
/// ## Mathematical Applications
///
/// ### Optimization and Constraints
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents a constraint in an optimization problem
/// struct Constraint {
///     feasible_region: IntervalInfiniteLength<f64>
/// }
///
/// impl Constraint {
///     fn new_lower_bound(min_value: f64, inclusive: bool) -> Self {
///         let feasible_region = if inclusive {
///             IntervalInfiniteLength::LowerClosedUpperUnbounded(
///                 IntervalLowerClosedUpperUnbounded::new(min_value)
///             )
///         } else {
///             IntervalInfiniteLength::LowerOpenUpperUnbounded(
///                 IntervalLowerOpenUpperUnbounded::new(min_value)
///             )
///         };
///         Self { feasible_region }
///     }
///     
///     fn new_upper_bound(max_value: f64, inclusive: bool) -> Self {
///         let feasible_region = if inclusive {
///             IntervalInfiniteLength::LowerUnboundedUpperClosed(
///                 IntervalLowerUnboundedUpperClosed::new(max_value)
///             )
///         } else {
///             IntervalInfiniteLength::LowerUnboundedUpperOpen(
///                 IntervalLowerUnboundedUpperOpen::new(max_value)
///             )
///         };
///         Self { feasible_region }
///     }
///     
///     fn is_feasible(&self, value: f64) -> bool {
///         self.feasible_region.contains_point(&value)
///     }
///     
///     fn intersect_with(&self, other: &Constraint) -> Option<Interval<f64>> {
///         self.feasible_region.intersection(&other.feasible_region)
///     }
/// }
///
/// // Example: x ≥ 0 AND x ≤ 100
/// let non_negative = Constraint::new_lower_bound(0.0, true);  // x ≥ 0
/// let bounded_above = Constraint::new_upper_bound(100.0, true); // x ≤ 100
///
/// assert!(non_negative.is_feasible(50.0));
/// assert!(!non_negative.is_feasible(-1.0));
///
/// if let Some(combined) = non_negative.intersect_with(&bounded_above) {
///     // Result: [0, 100] - intersection of [0, +∞) and (-∞, 100]
///     match combined {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(positive)) => {
///             assert_eq!(positive.length().into_inner(), 100.0);
///         }
///         _ => unreachable!("Expected finite interval"),
///     }
/// }
/// ```
///
/// ### Probability and Statistics
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents the support of a probability distribution
/// struct DistributionSupport {
///     support: IntervalInfiniteLength<f64>
/// }
///
/// impl DistributionSupport {
///     /// Standard normal distribution: (-∞, +∞)
///     fn standard_normal() -> Self {
///         Self { support: IntervalInfiniteLength::LowerUnboundedUpperUnbounded(
///             IntervalLowerUnboundedUpperUnbounded::new()) }
///     }
///     
///     /// Exponential distribution: [0, +∞)
///     fn exponential() -> Self {
///         Self {
///             support: IntervalInfiniteLength::LowerClosedUpperUnbounded(
///                 IntervalLowerClosedUpperUnbounded::new(0.0)
///             )
///         }
///     }
///     
///     /// Half-normal distribution: [0, +∞)
///     fn half_normal() -> Self {
///         Self {
///             support: IntervalInfiniteLength::LowerClosedUpperUnbounded(
///                 IntervalLowerClosedUpperUnbounded::new(0.0)
///             )
///         }
///     }
///     
///     fn pdf_support(&self, x: f64) -> bool {
///         self.support.contains_point(&x)
///     }
///     
///     fn is_bounded(&self) -> bool {
///         !matches!(self.support, IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_))
///     }
/// }
///
/// let normal = DistributionSupport::standard_normal();
/// let exponential = DistributionSupport::exponential();
///
/// // Normal distribution has support over all reals
/// assert!(normal.pdf_support(-1000.0));
/// assert!(normal.pdf_support(1000.0));
/// assert!(!normal.is_bounded());
///
/// // Exponential distribution has support over non-negative reals
/// assert!(exponential.pdf_support(0.0));
/// assert!(exponential.pdf_support(100.0));
/// assert!(!exponential.pdf_support(-1.0));
/// assert!(exponential.is_bounded()); // Bounded on one side
/// ```
///
/// ### Signal Processing and Control Theory
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents a filter's frequency response domain
/// struct FrequencyDomain {
///     valid_frequencies: IntervalInfiniteLength<f64>
/// }
///
/// impl FrequencyDomain {
///     /// Low-pass filter: (-∞, cutoff_freq]
///     fn low_pass(cutoff_frequency: f64) -> Self {
///         Self {
///             valid_frequencies: IntervalInfiniteLength::LowerUnboundedUpperClosed(
///                 IntervalLowerUnboundedUpperClosed::new(cutoff_frequency)
///             )
///         }
///     }
///     
///     /// High-pass filter: [cutoff_freq, +∞)
///     fn high_pass(cutoff_frequency: f64) -> Self {
///         Self {
///             valid_frequencies: IntervalInfiniteLength::LowerClosedUpperUnbounded(
///                 IntervalLowerClosedUpperUnbounded::new(cutoff_frequency)
///             )
///         }
///     }
///     
///     /// All-pass filter: (-∞, +∞)
///     fn all_pass() -> Self {
///         Self {
///             valid_frequencies: IntervalInfiniteLength::LowerUnboundedUpperUnbounded(
///                 IntervalLowerUnboundedUpperUnbounded::new()
///             )
///         }
///     }
///     
///     fn accepts_frequency(&self, frequency: f64) -> bool {
///         self.valid_frequencies.contains_point(&frequency)
///     }
///     
///     fn combine_with(&self, other: &FrequencyDomain) -> Option<Interval<f64>> {
///         self.valid_frequencies.intersection(&other.valid_frequencies)
///     }
/// }
///
/// let low_pass = FrequencyDomain::low_pass(1000.0);   // (-∞, 1000]
/// let high_pass = FrequencyDomain::high_pass(100.0);  // [100, +∞)
/// let all_pass = FrequencyDomain::all_pass();         // (-∞, +∞)
///
/// assert!(low_pass.accepts_frequency(500.0));   // Below cutoff
/// assert!(!low_pass.accepts_frequency(1500.0)); // Above cutoff
///
/// assert!(high_pass.accepts_frequency(500.0));  // Above cutoff
/// assert!(!high_pass.accepts_frequency(50.0));  // Below cutoff
///
/// assert!(all_pass.accepts_frequency(-1000.0)); // Accepts everything
/// assert!(all_pass.accepts_frequency(1000.0));
///
/// // Band-pass filter: intersection of high-pass and low-pass
/// if let Some(band_pass) = high_pass.combine_with(&low_pass) {
///     // Result: [100, 1000] - finite interval
///     match band_pass {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(positive)) => {
///             assert_eq!(positive.length().into_inner(), 900.0); // 1000 - 100
///         }
///         _ => unreachable!("Expected finite band-pass region"),
///     }
/// }
/// ```
///
/// ## Type Conversion and Specialization
///
/// ### Converting to General Interval Types
/// ```rust
/// use grid1d::intervals::*;
///
/// let infinite = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(0.0)
/// );
///
/// // Convert to general interval enum
/// let general: Interval<f64> = infinite.clone().into();
///
/// // Pattern match to extract specific types
/// match infinite {
///     IntervalInfiniteLength::LowerClosedUpperUnbounded(interval) => {
///         println!("Lower bound: {}", interval.lower_bound_value());
///         // Access lower-bounded-specific methods
///     }
///     IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_) => {
///         println!("Universal set - no finite bounds");
///     }
///     _ => {
///         println!("Other infinite interval type");
///     }
/// }
/// ```
///
/// ### Specialized Bound Access
/// ```rust
/// use grid1d::intervals::*;
///
/// fn get_bound_info(interval: &IntervalInfiniteLength<f64>) -> String {
///     match interval {
///         IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_) => {
///             "No finite bounds".to_string()
///         }
///         IntervalInfiniteLength::LowerClosedUpperUnbounded(bounded)  => {
///             format!("Lower bound: {}", bounded.lower_bound_value())
///         }
///         IntervalInfiniteLength::LowerOpenUpperUnbounded(bounded) => {
///             format!("Lower bound: {}", bounded.lower_bound_value())
///         }
///         IntervalInfiniteLength::LowerUnboundedUpperClosed(bounded)  => {
///             format!("Upper bound: {}", bounded.upper_bound_value())
///         }
///         IntervalInfiniteLength::LowerUnboundedUpperOpen(bounded) => {
///             format!("Upper bound: {}", bounded.upper_bound_value())
///         }
///     }
/// }
///
/// let unbounded = IntervalInfiniteLength::LowerUnboundedUpperUnbounded(
///     IntervalLowerUnboundedUpperUnbounded::<f64>::new());
/// let lower_bounded = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(10.0)
/// );
/// let upper_bounded = IntervalInfiniteLength::LowerUnboundedUpperClosed(
///     IntervalLowerUnboundedUpperClosed::new(100.0)
/// );
///
/// assert_eq!(get_bound_info(&unbounded), "No finite bounds");
/// assert_eq!(get_bound_info(&lower_bounded), "Lower bound: 10");
/// assert_eq!(get_bound_info(&upper_bounded), "Upper bound: 100");
/// ```
///
/// ## Performance Characteristics
///
/// ### Memory Layout
/// - **Unbounded variant**: Zero scalar values (minimal size)
/// - **Semi-bounded variants**: One scalar value + bound type information (8-16 bytes typical)
/// - **Enum overhead**: Small discriminant tag (1-8 bytes depending on alignment)
/// - **Total size**: Typically 8-24 bytes depending on variant and scalar type
///
/// ### Operation Complexity
/// | Operation | Unbounded | Semi-bounded | Notes |
/// |-----------|-----------|--------------|-------|
/// | **Point queries** | O(1) - always true | O(1) - 1 comparison | Constant time for all variants |
/// | **Containment tests** | O(1) - simple logic | O(1) - bound comparison | No significant difference |
/// | **Intersections** | O(1) - identity operation | O(1) - bound arithmetic | May allocate result |
/// | **Pattern matching** | O(1) - compile-time optimized | O(1) - compile-time optimized | No runtime dispatch cost |
/// | **Bound access** | O(1) - N/A | O(1) - direct access | Zero-cost field access |
///
/// ### Scalar Type Performance Impact
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::{RealNative64StrictFiniteInDebug, RealNative64StrictFinite, RealScalar};
///
/// // These have identical performance in release builds:
/// type FastInfiniteInterval = IntervalInfiniteLength<f64>;
/// type OptimalInfiniteInterval = IntervalInfiniteLength<RealNative64StrictFiniteInDebug>;
///
/// // This has small validation overhead:
/// type SafeInfiniteInterval = IntervalInfiniteLength<RealNative64StrictFinite>;
///
/// // Performance test function (generic over scalar type)
/// fn benchmark_infinite_operations<T: RealScalar + Clone>(
///     interval1: &IntervalInfiniteLength<T>,
///     interval2: &IntervalInfiniteLength<T>
/// ) {
///     // All operations compile to identical assembly for f64 and RealNative64StrictFiniteInDebug
///     let _contains = interval1.contains_interval(interval2);
///     let _intersection = interval1.intersection(interval2);
///     
///     // Pattern matching is zero-cost
///     match interval1 {
///         IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_) => { /* fastest - no bounds to check */ }
///         IntervalInfiniteLength::LowerClosedUpperUnbounded(_) => { /* one bound check */ }
///         IntervalInfiniteLength::LowerOpenUpperUnbounded(_) => { /* one bound check */ }
///         IntervalInfiniteLength::LowerUnboundedUpperClosed(_) => { /* one bound check */ }
///         IntervalInfiniteLength::LowerUnboundedUpperOpen(_) => { /* one bound check */ }
///     }
/// }
/// ```
///
/// ## Integration with Library Ecosystem
///
/// ### With Numerical Integration
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Integrate over infinite domains (requires special techniques)
/// fn integrate_infinite_domain(
///     f: impl Fn(f64) -> f64,
///     domain: &IntervalInfiniteLength<f64>
/// ) -> Result<f64, &'static str> {
///     match domain {
///         IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_) => {
///             // Requires transformation or series methods
///             Err("Integration over (-∞, +∞) requires special techniques")
///         }
///         IntervalInfiniteLength::LowerClosedUpperUnbounded(interval) => {
///             // Semi-infinite integration from a to +∞
///             let lower = *interval.lower_bound_value();
///             if lower >= 0.0 {
///                 Ok(approximate_semi_infinite_integral(f, lower, true))
///             } else {
///                 Err("Negative lower bounds require careful handling")
///             }
///         }
///         IntervalInfiniteLength::LowerUnboundedUpperClosed(interval) => {
///             // Semi-infinite integration from -∞ to b
///             let upper = *interval.upper_bound_value();
///             Ok(approximate_semi_infinite_integral(f, upper, false))
///         }
///         _ => Err("This infinite domain type requires specialized methods"),
///     }
/// }
///
/// fn approximate_semi_infinite_integral(
///     f: impl Fn(f64) -> f64,
///     bound: f64,
///     from_bound: bool
/// ) -> f64 {
///     // Placeholder for actual semi-infinite integration
///     // Would use techniques like substitution u = 1/(1+x) or similar
///     0.0
/// }
/// ```
///
/// ### With Function Domains
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Mathematical function with potentially infinite domain
/// struct MathFunction {
///     domain: IntervalInfiniteLength<f64>,
///     // ... function definition
/// }
///
/// impl MathFunction {
///     /// Exponential function: domain is all real numbers
///     fn exponential() -> Self {
///         Self {
///             domain: IntervalInfiniteLength::LowerUnboundedUpperUnbounded(
///                IntervalLowerUnboundedUpperUnbounded::<f64>::new())
///         }
///     }
///     
///     /// Square root function: domain is [0, +∞)
///     fn square_root() -> Self {
///         Self {
///             domain: IntervalInfiniteLength::LowerClosedUpperUnbounded(
///                 IntervalLowerClosedUpperUnbounded::new(0.0)
///             )
///         }
///     }
///     
///     /// Logarithm function: domain is (0, +∞)
///     fn natural_log() -> Self {
///         Self {
///             domain: IntervalInfiniteLength::LowerOpenUpperUnbounded(
///                 IntervalLowerOpenUpperUnbounded::new(0.0)
///             )
///         }
///     }
///     
///     fn evaluate(&self, x: f64) -> Option<f64> {
///         if self.domain.contains_point(&x) {
///             // Evaluate function (simplified examples)
///             match &self.domain {
///                 IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_) => Some(x.exp()),
///                 IntervalInfiniteLength::LowerClosedUpperUnbounded(_) => Some(x.sqrt()),
///                 IntervalInfiniteLength::LowerOpenUpperUnbounded(_) => Some(x.ln()),
///                 _ => Some(x), // Placeholder
///             }
///         } else {
///             None // Out of domain
///         }
///     }
/// }
///
/// let exp_func = MathFunction::exponential();
/// let sqrt_func = MathFunction::square_root();
/// let log_func = MathFunction::natural_log();
///
/// assert!(exp_func.evaluate(-1.0).is_some());  // exp(-1) is defined
/// assert!(sqrt_func.evaluate(4.0).is_some());  // sqrt(4) is defined
/// assert!(sqrt_func.evaluate(-1.0).is_none()); // sqrt(-1) is not defined (in reals)
/// assert!(log_func.evaluate(1.0).is_some());   // ln(1) is defined
/// assert!(log_func.evaluate(0.0).is_none());   // ln(0) is not defined
/// ```
///
/// ## Best Practices and Recommendations
///
/// ### When to Use [`IntervalInfiniteLength`]
/// - **Mathematical modeling**: Functions with naturally infinite domains
/// - **Constraint systems**: Unbounded optimization problems
/// - **Probability theory**: Distributions with infinite support
/// - **Signal processing**: Frequency domains and filter design
/// - **Asymptotic analysis**: Limit behaviors and convergence studies
///
/// ### When to Use Specific Variants
/// - **Unbounded**: Universal domains, unconstrained variables
/// - **LowerBounded**: "At least" constraints, non-negative domains
/// - **UpperBounded**: "At most" constraints, bounded growth models
///
/// ### Recommended Patterns
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::RealNative64StrictFiniteInDebug;
/// use try_create::TryNew;
///
/// // Define type aliases for your domain
/// type Real = RealNative64StrictFiniteInDebug;
/// type InfiniteInterval = IntervalInfiniteLength<Real>;
///
/// // Pattern: Use specific constructors for clarity
/// fn create_constraint_domain(
///     min_value: Option<Real>,
///     max_value: Option<Real>,
///     include_bounds: (bool, bool)
/// ) -> Result<InfiniteInterval, String> {
///     match (min_value, max_value) {
///         (None, None) => {
///             Ok(InfiniteInterval::LowerUnboundedUpperUnbounded(
///                 IntervalLowerUnboundedUpperUnbounded::new()))
///         }
///         (Some(min), None) => {
///             if include_bounds.0 {
///                 Ok(InfiniteInterval::LowerClosedUpperUnbounded(
///                     IntervalLowerClosedUpperUnbounded::new(min)
///                 ))
///             } else {
///                 Ok(InfiniteInterval::LowerOpenUpperUnbounded(
///                     IntervalLowerOpenUpperUnbounded::new(min)
///                 ))
///             }
///         }
///         (None, Some(max)) => {
///             if include_bounds.1 {
///                 Ok(InfiniteInterval::LowerUnboundedUpperClosed(
///                     IntervalLowerUnboundedUpperClosed::new(max)
///                 ))
///             } else {
///                 Ok(InfiniteInterval::LowerUnboundedUpperOpen(
///                     IntervalLowerUnboundedUpperOpen::new(max)
///                 ))
///             }
///         }
///         (Some(_), Some(_)) => {
///             Err("Use finite intervals for bounded domains".to_string())
///         }
///     }
/// }
///
/// // Pattern: Handle intersection results appropriately
/// fn combine_constraints(
///     constraint1: &InfiniteInterval,
///     constraint2: &InfiniteInterval
/// ) -> Option<Interval<Real>> {
///     constraint1.intersection(constraint2)
/// }
/// ```
///
/// ## Mathematical Properties and Guarantees
///
/// ### Measure Theory Properties
/// - **All infinite intervals** have **infinite measure**: `μ(I) = +∞`
/// - **Non-compactness**: No infinite interval is compact
/// - **Translation invariance**: `μ(A + c) = μ(A)` for any constant `c`
/// - **Monotonicity**: If A ⊆ B and A is infinite, then B is infinite
///
/// ### Set Theory Properties
/// - **Uncountable cardinality**: All infinite intervals have cardinality `2^ℵ₀`
/// - **Perfect sets**: All infinite intervals (except possibly at boundaries) are perfect
/// - **Connectedness**: All infinite intervals are connected
/// - **Denseness**: Rationals and irrationals are both dense in any infinite interval
///
/// ### Topological Properties
/// ```rust
/// use grid1d::intervals::*;
///
/// // Interior, closure, and boundary properties
/// fn analyze_topology(interval: &IntervalInfiniteLength<f64>) -> (bool, bool, bool) {
///     let has_interior = true; // All infinite intervals have non-empty interior
///     let is_closed = match interval {
///         IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_) => false, // ℝ is not closed in standard topology
///         IntervalInfiniteLength::LowerClosedUpperUnbounded(_) => false, // [a,+∞) not closed
///         IntervalInfiniteLength::LowerOpenUpperUnbounded(_) => false, // (a,+∞) not closed
///         IntervalInfiniteLength::LowerUnboundedUpperClosed(_) => false, // (-∞,b] not closed
///         IntervalInfiniteLength::LowerUnboundedUpperOpen(_) => false, // (-∞,b) not closed
///     };
///     let is_bounded = false; // No infinite interval is bounded
///     
///     (has_interior, is_closed, is_bounded)
/// }
/// ```
///
/// ## Error Handling and Edge Cases
///
/// ### Construction Validation
/// ```rust,ignore
/// use grid1d::intervals::*;
///
/// // Semi-bounded intervals validate their finite bounds
/// #[cfg(debug_assertions)]
/// {
///     std::panic::catch_unwind(|| {
///         IntervalLowerClosedUpperUnbounded::new(f64::NAN); // Panics in debug
///     }).expect_err("Should panic on NaN bound");
///     
///     std::panic::catch_unwind(|| {
///         IntervalLowerUnboundedUpperClosed::new(f64::INFINITY); // Panics in debug
///     }).expect_err("Should panic on infinite bound");
/// }
/// ```
///
/// ### Intersection Edge Cases
/// ```rust
/// use grid1d::intervals::*;
///
/// // Edge case: semi-bounded intervals with same bound value
/// let lower_closed = IntervalInfiniteLength::LowerClosedUpperUnbounded(
///     IntervalLowerClosedUpperUnbounded::new(0.0)
/// );
/// let upper_open = IntervalInfiniteLength::LowerUnboundedUpperOpen(
///     IntervalLowerUnboundedUpperOpen::new(0.0)
/// );
///
/// // [0, +∞) ∩ (-∞, 0) = ∅ (no intersection)
/// assert!(lower_closed.intersection(&upper_open).is_none());
///
/// let upper_closed = IntervalInfiniteLength::LowerUnboundedUpperClosed(
///     IntervalLowerUnboundedUpperClosed::new(0.0)
/// );
///
/// // [0, +∞) ∩ (-∞, 0] = {0} (singleton intersection)
/// if let Some(intersection) = lower_closed.intersection(&upper_closed) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::ZeroLength(singleton)) => {
///             assert_eq!(singleton.value(), &0.0);
///         }
///         _ => panic!("Expected singleton intersection"),
///     }
/// }
/// ```
///
/// ## Mathematical Correctness Guarantees
///
/// The [`IntervalInfiniteLength`] enum maintains all essential mathematical properties:
///
/// - **Infinite measure**: `μ(I) = +∞` for all variants
/// - **Containment transitivity**: If A ⊆ B and B ⊆ C, then A ⊆ C
/// - **Intersection commutativity**: A ∩ B = B ∩ A
/// - **Intersection associativity**: (A ∩ B) ∩ C = A ∩ (B ∩ C)
/// - **Monotonicity**: If A ⊆ B, then A ∩ C ⊆ B ∩ C
/// - **Boundary consistency**: Containment and intersection respect boundary semantics
/// - **Universal properties**: Unbounded variant contains all other intervals
///
/// These properties are preserved regardless of the scalar type used and are guaranteed
/// by the underlying implementations of the [`IntervalTrait`] and associated methods.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(bound(deserialize = "RealType: for<'a> Deserialize<'a>"))]
pub enum IntervalInfiniteLength<RealType: RealScalar> {
    /// An ***unbounded*** interval `(-∞,+∞)`.
    ///
    /// This variant represents the entire real line, containing every possible real number.
    /// It has infinite extent in both directions and serves as the universal set for
    /// real-valued domains.
    ///
    /// **Mathematical properties:**
    /// - **Universal containment**: Contains every other interval
    /// - **Infinite measure**: `μ(ℝ) = +∞`
    /// - **No finite bounds**: Neither lower nor upper bounds exist
    /// - **Use cases**: Unconstrained domains, universal sets, entire function spaces
    LowerUnboundedUpperUnbounded(IntervalLowerUnboundedUpperUnbounded<RealType>),

    /// An ***unbounded closed-left*** interval `[a,+∞)`.
    ///
    /// This variant represents a semi-infinite interval that includes the lower bound `a`
    /// and extends infinitely in the positive direction. It models "at least `a`" constraints.
    ///
    /// **Mathematical properties:**
    /// - **Lower inclusion**: Contains the bound `a`
    /// - **Infinite upper extent**: No upper limit
    /// - **Use cases**: Non-negative domains, minimum constraints, cumulative distributions
    LowerClosedUpperUnbounded(IntervalLowerClosedUpperUnbounded<RealType>),

    /// An ***unbounded open-left*** interval `(a,+∞)`.
    ///
    /// This variant represents a semi-infinite interval that excludes the lower bound `a`
    /// and extends infinitely in the positive direction. It models "strictly greater than `a`" constraints.
    ///
    /// **Mathematical properties:**
    /// - **Lower exclusion**: Does not contain the bound `a`
    /// - **Infinite upper extent**: No upper limit
    /// - **Use cases**: Strictly positive domains, strict inequalities, limit approaches
    LowerOpenUpperUnbounded(IntervalLowerOpenUpperUnbounded<RealType>),

    /// An ***unbounded closed-right*** interval `(-∞,b]`.
    ///
    /// This variant represents a semi-infinite interval that extends infinitely in the
    /// negative direction and includes the upper bound `b`. It models "at most `b`" constraints.
    ///
    /// **Mathematical properties:**
    /// - **Upper inclusion**: Contains the bound `b`
    /// - **Infinite lower extent**: No lower limit
    /// - **Use cases**: Upper thresholds, capacity limits, bounded growth models
    LowerUnboundedUpperClosed(IntervalLowerUnboundedUpperClosed<RealType>),

    /// An ***unbounded open-right*** interval `(-∞,b)`.
    ///
    /// This variant represents a semi-infinite interval that extends infinitely in the
    /// negative direction and excludes the upper bound `b`. It models "strictly less than `b`" constraints.
    ///
    /// **Mathematical properties:**
    /// - **Upper exclusion**: Does not contain the bound `b`
    /// - **Infinite lower extent**: No lower limit
    /// - **Use cases**: Strict upper bounds, approach limits, convergence criteria
    LowerUnboundedUpperOpen(IntervalLowerUnboundedUpperOpen<RealType>),
}

impl<RealType: RealScalar> IntervalInfiniteLength<RealType> {
    /// Creates an interval unbounded below with a runtime-typed lower bound.
    ///
    /// Automatically selects the appropriate variant based on whether the
    /// upper bound is open or closed.
    ///
    /// # Examples
    /// ```
    /// use grid1d::intervals::*;
    /// use grid1d::bounds::*;
    /// use try_create::New;
    ///
    /// let closed_bound = UpperBoundClosed::new(10.0);
    /// let interval = IntervalInfiniteLength::new_lower_unbounded(closed_bound.into());
    /// // Creates (-∞, 10]
    /// ```
    #[inline(always)]
    pub fn new_lower_unbounded(upper_bound: UpperBoundRuntime<RealType>) -> Self {
        match upper_bound {
            UpperBoundRuntime::Closed(upper_bound) => {
                IntervalLowerUnboundedUpperClosed { upper_bound }.into()
            }
            UpperBoundRuntime::Open(upper_bound) => {
                IntervalLowerUnboundedUpperOpen { upper_bound }.into()
            }
        }
    }

    /// Creates an interval unbounded above with a runtime-typed upper bound.
    ///
    /// Automatically selects the appropriate variant based on whether the
    /// lower bound is open or closed.
    ///
    /// # Examples
    /// ```
    /// use grid1d::intervals::*;
    /// use grid1d::bounds::*;
    /// use try_create::New;
    ///
    /// let closed_bound = LowerBoundClosed::new(0.0);
    /// let interval = IntervalInfiniteLength::new_upper_unbounded(closed_bound.into());
    /// // Creates [0, +∞)
    /// ```
    #[inline(always)]
    pub fn new_upper_unbounded(lower_bound: LowerBoundRuntime<RealType>) -> Self {
        match lower_bound {
            LowerBoundRuntime::Closed(lower_bound) => {
                IntervalLowerClosedUpperUnbounded { lower_bound }.into()
            }
            LowerBoundRuntime::Open(lower_bound) => {
                IntervalLowerOpenUpperUnbounded { lower_bound }.into()
            }
        }
    }
}

impl<RealType: RealScalar> IntervalOperations for IntervalInfiniteLength<RealType> {}

impl<RealType: RealScalar> IntervalBoundsRuntime for IntervalInfiniteLength<RealType> {
    type RealType = RealType;

    fn lower_bound_runtime(&self) -> Option<LowerBoundRuntime<RealType>> {
        match self {
            IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_)
            | IntervalInfiniteLength::LowerUnboundedUpperClosed(_)
            | IntervalInfiniteLength::LowerUnboundedUpperOpen(_) => None,
            IntervalInfiniteLength::LowerClosedUpperUnbounded(interval) => {
                interval.lower_bound_runtime()
            }
            IntervalInfiniteLength::LowerOpenUpperUnbounded(interval) => {
                interval.lower_bound_runtime()
            }
        }
    }

    fn upper_bound_runtime(&self) -> Option<UpperBoundRuntime<RealType>> {
        match self {
            IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_)
            | IntervalInfiniteLength::LowerClosedUpperUnbounded(_)
            | IntervalInfiniteLength::LowerOpenUpperUnbounded(_) => None,
            IntervalInfiniteLength::LowerUnboundedUpperClosed(interval) => {
                interval.upper_bound_runtime()
            }
            IntervalInfiniteLength::LowerUnboundedUpperOpen(interval) => {
                interval.upper_bound_runtime()
            }
        }
    }
}

impl<RealType: RealScalar> Contains for IntervalInfiniteLength<RealType> {
    /// Returns `true` if the 1D point/coordinate `x` is contained in `self`.
    #[inline(always)]
    fn contains_point(&self, x: &RealType) -> bool {
        match self {
            IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_) => true,
            IntervalInfiniteLength::LowerClosedUpperUnbounded(interval) => {
                interval.contains_point(x)
            }
            IntervalInfiniteLength::LowerOpenUpperUnbounded(interval) => interval.contains_point(x),
            IntervalInfiniteLength::LowerUnboundedUpperClosed(interval) => {
                interval.contains_point(x)
            }
            IntervalInfiniteLength::LowerUnboundedUpperOpen(interval) => interval.contains_point(x),
        }
    }
}

impl<RealType: RealScalar> IntervalTrait for IntervalInfiniteLength<RealType> {}

impl<RealType: RealScalar> IntervalLowerBoundedUpperUnboundedTrait
    for IntervalInfiniteLength<RealType>
where
    Self: IntervalTrait<RealType = RealType> + GetLowerBoundValue<LowerBoundValue = RealType>,
{
}
//--------------------------------------------------------------------------------------------------------------

/// Generic structure for intervals bounded below and extending to positive infinity.
///
/// The [`IntervalLowerBoundedUpperUnbounded`] struct represents semi-infinite intervals
/// that have a finite lower bound but extend infinitely in the positive direction.
/// The lower bound can be either included (closed) or excluded (open) based on the
/// type parameter.
///
/// ## Generic Parameters
///
/// - `RealType`: Must implement [`RealScalar`] for mathematical operations
/// - `LowerBoundType`: Either [`Closed`] or [`Open`] to specify lower boundary inclusion
///
/// ## Boundary Type Combinations
///
/// | Lower | Notation | Mathematical Set |
/// |-------|----------|------------------|
/// | `Closed` | `[a, +∞)` | `{x : x ≥ a}` |
/// | `Open` | `(a, +∞)` | `{x : x > a}` |
///
/// ## Mathematical Properties
///
/// - **Infinite measure**: `μ(I) = +∞` for all variants
/// - **Non-compactness**: Never compact (unbounded)
/// - **Connectedness**: Always connected (no gaps)
/// - **Lower bound**: Always has a finite lower bound
/// - **Upper bound**: No finite upper bound (extends to +∞)
///
/// ## Type Aliases
///
/// The library provides convenient type aliases:
/// - [`IntervalLowerClosedUpperUnbounded`] = `IntervalLowerBoundedUpperUnbounded<RealType, Closed>`
/// - [`IntervalLowerOpenUpperUnbounded`] = `IntervalLowerBoundedUpperUnbounded<RealType, Open>`
///
/// ## Use Cases
///
/// - **Non-negative domains**: Mathematical functions defined for x ≥ 0
/// - **Growth models**: Processes that start from a specific value and grow without bound
/// - **Cumulative distributions**: Where the starting point is included but growth is unlimited
/// - **"At least" constraints**: x ≥ a (closed) or x > a (open)
///
/// ## Construction
///
/// ```rust
/// use grid1d::intervals::*;
///
/// // Using type aliases (recommended)
/// let closed_unbounded = IntervalLowerClosedUpperUnbounded::new(0.0);  // [0, +∞)
/// let open_unbounded = IntervalLowerOpenUpperUnbounded::new(0.0);      // (0, +∞)
///
/// assert!(closed_unbounded.contains_point(&0.0));   // Includes lower bound
/// assert!(!open_unbounded.contains_point(&0.0));    // Excludes lower bound
/// ```
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Getters)]
#[serde(bound(deserialize = "RealType: for<'a> Deserialize<'a>"))]
pub struct IntervalLowerBoundedUpperUnbounded<RealType: RealScalar, LowerBoundType: BoundType> {
    /// The lower bound of the interval, included in the interval.
    ///
    /// This value represents the smallest point contained in the interval.
    /// For a closed lower bound `[a`, any point `x` in the interval satisfies `x ≥ a`.
    /// For an open lower bound `(a`, any point `x` in the interval satisfies `x > a`.
    #[getset(get = "pub")]
    lower_bound: LowerBound<RealType, LowerBoundType>,
}

///  Generic structure for intervals extending from negative infinity with finite upper bound.
///
/// The [`IntervalLowerUnboundedUpperBounded`] struct represents semi-infinite intervals
/// that extend infinitely in the negative direction but have a finite upper bound.
/// The upper bound can be either included (closed) or excluded (open) based on the
/// type parameter.
///
/// ## Generic Parameters
///
/// - `RealType`: Must implement [`RealScalar`] for mathematical operations
/// - `UpperBoundType`: Either [`Closed`] or [`Open`] to specify upper boundary inclusion
///
/// ## Boundary Type Combinations
///
/// | Upper | Notation | Mathematical Set |
/// |-------|----------|------------------|
/// | `Closed` | `(-∞, b]` | `{x : x ≤ b}` |
/// | `Open` | `(-∞, b)` | `{x : x < b}` |
///
/// ## Mathematical Properties
///
/// - **Infinite measure**: `μ(I) = +∞` for all variants
/// - **Non-compactness**: Never compact (unbounded)
/// - **Connectedness**: Always connected (no gaps)
/// - **Lower bound**: No finite lower bound (extends from -∞)
/// - **Upper bound**: Always has a finite upper bound
///
/// ## Type Aliases
///
/// The library provides convenient type aliases:
/// - [`IntervalLowerUnboundedUpperClosed`] = `IntervalLowerUnboundedUpperBounded<RealType, Closed>`
/// - [`IntervalLowerUnboundedUpperOpen`] = `IntervalLowerUnboundedUpperBounded<RealType, Open>`
///
/// ## Use Cases
///
/// - **Capacity limits**: Systems with maximum bounds but no minimum restrictions
/// - **"At most" constraints**: x ≤ b (closed) or x < b (open)
/// - **Temperature limits**: Physical systems with maximum safe temperatures
/// - **Budget constraints**: Financial models with spending limits
/// - **Upper thresholds**: Where values cannot exceed a certain limit
///
/// ## Construction
///
/// ```rust
/// use grid1d::intervals::*;
///
/// // Using type aliases (recommended)
/// let upper_bounded_closed = IntervalLowerUnboundedUpperClosed::new(100.0);  // (-∞, 100]
/// let upper_bounded_open = IntervalLowerUnboundedUpperOpen::new(100.0);      // (-∞, 100)
///
/// assert!(upper_bounded_closed.contains_point(&100.0));   // Includes upper bound
/// assert!(!upper_bounded_open.contains_point(&100.0));    // Excludes upper bound
/// ```
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Getters)]
#[serde(bound(deserialize = "RealType: for<'a> Deserialize<'a>"))]
pub struct IntervalLowerUnboundedUpperBounded<RealType: RealScalar, UpperBoundType: BoundType> {
    /// The upper bound of the interval, included in the interval.
    ///
    /// This value represents the largest point contained in the interval.
    /// For a closed upper bound `b]`, any point `x` in the interval satisfies `x ≤ b`.
    /// For an open upper bound `b)`, any point `x` in the interval satisfies `x < b`.
    #[getset(get = "pub")]
    upper_bound: UpperBound<RealType, UpperBoundType>,
}

//------------------------------------------------------------------------------------------------
/// The universal unbounded interval `(-∞, +∞)` representing the entire real line.
///
/// The [`IntervalLowerUnboundedUpperUnbounded`] represents the most general interval possible -
/// the entire set of real numbers with no restrictions whatsoever. This interval contains every
/// real number and serves as the universal set for real-valued mathematical operations.
///
/// ## Mathematical Properties
///
/// - **Notation**: `(-∞, +∞)` or `ℝ` (the real numbers)
/// - **Definition**: `{x ∈ ℝ : x ∈ ℝ}` - every real number
/// - **Lower boundary**: None (extends to negative infinity)
/// - **Upper boundary**: None (extends to positive infinity)
/// - **Measure**: `+∞` (infinite length)
/// - **Topology**: Neither open nor closed in the standard topology on ℝ
/// - **Cardinality**: Uncountably infinite (cardinality `2^ℵ₀`)
/// - **Compactness**: Never compact (unbounded)
/// - **Connectedness**: Connected (no gaps)
///
/// ## Use Cases
///
/// The unbounded interval is essential when:
/// - **Universal domains**: Functions defined over all real numbers
/// - **Unconstrained optimization**: Problems without domain restrictions
/// - **Mathematical analysis**: Working with the entire real line
/// - **Default domains**: When no specific restrictions apply
/// - **Set theory**: Representing the universal set of reals
/// - **Function spaces**: Domains for functions like polynomials, exponentials
/// - **Physics modeling**: Quantities that can take any real value
///
/// ## Comparison with Other Interval Types
///
/// | Property | `(-∞,+∞)` | `[a,+∞)` | `(-∞,b]` | `[a,b]` |
/// |----------|-----------|----------|----------|---------|
/// | Contains any real `x` | ✓ | Only if `x ≥ a` | Only if `x ≤ b` | Only if `a ≤ x ≤ b` |
/// | Length | `+∞` | `+∞` | `+∞` | `b - a` |
/// | Compactness | Never | Never | Never | Always |
/// | Lower bound | None | `a` | None | `a` |
/// | Upper bound | None | None | `b` | `b` |
/// | Universal containment | ✓ | ✗ | ✗ | ✗ |
///
/// ## Construction
///
/// ### Safe Construction (Recommended)
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::RealNative64StrictFiniteInDebug;
///
/// // Use the recommended performance-optimal type
/// type Real = RealNative64StrictFiniteInDebug;
///
/// // Create the universal interval
/// let universal = IntervalLowerUnboundedUpperUnbounded::<Real>::new();
/// ```
///
/// ### Raw Construction
/// ```rust
/// use grid1d::intervals::*;
///
/// // Direct construction with any RealScalar type
/// let universal = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
/// ```
///
/// ## Key Operations
///
/// ### Point Containment (Always True)
/// ```rust
/// use grid1d::intervals::*;
///
/// let universal = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
///
/// // Contains every possible real number
/// assert!(universal.contains_point(&0.0));
/// assert!(universal.contains_point(&-1000000.0));
/// assert!(universal.contains_point(&1000000.0));
/// assert!(universal.contains_point(&std::f64::consts::PI));
/// assert!(universal.contains_point(&std::f64::consts::E));
/// assert!(universal.contains_point(&f64::MIN));
/// assert!(universal.contains_point(&f64::MAX));
///
/// // There is no real number that is NOT contained
/// // (This is a mathematical guarantee)
/// ```
///
/// ### Universal Containment Property
/// ```rust
/// use grid1d::intervals::*;
/// use try_create::New;
///
/// let universal = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
///
/// // Contains every other interval type
/// let closed = IntervalClosed::new(-10.0, 10.0);
/// let open = IntervalOpen::new(-100.0, 100.0);
/// let singleton = IntervalSingleton::new(42.0);
/// let lower_bounded = IntervalLowerClosedUpperUnbounded::new(0.0);
/// let upper_bounded = IntervalLowerUnboundedUpperClosed::new(1000.0);
///
/// // Universal interval contains all other intervals
/// assert!(universal.contains_interval(&closed));        // ℝ ⊇ [-10, 10] ✓
/// assert!(universal.contains_interval(&open));          // ℝ ⊇ (-100, 100) ✓
/// assert!(universal.contains_interval(&singleton));     // ℝ ⊇ {42} ✓
/// assert!(universal.contains_interval(&lower_bounded)); // ℝ ⊇ [0, +∞) ✓
/// assert!(universal.contains_interval(&upper_bounded)); // ℝ ⊇ (-∞, 1000] ✓
///
/// // But no other interval can contain the universal interval
/// assert!(!closed.contains_interval(&universal));        // [-10, 10] ⊉ ℝ ✗
/// assert!(!lower_bounded.contains_interval(&universal)); // [0, +∞) ⊉ ℝ ✗
/// ```
///
/// ### No Bounds to Access
/// ```rust
/// use grid1d::intervals::*;
///
/// let universal = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
///
/// // This interval has no finite bounds to access
/// // It doesn't implement GetLowerBoundValue or GetUpperBoundValue traits
/// // because it has no finite bounds
///
/// // This is mathematically correct - the real line has no endpoints
/// ```
///
/// ## Intersection Examples
///
/// ### Universal with Any Interval (Identity Operation)
/// ```rust
/// use grid1d::intervals::*;
///
/// let universal = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
/// let any_interval = IntervalClosed::new(-5.0, 5.0);
///
/// if let Some(intersection) = universal.intersection(&any_interval) {
///     // ℝ ∩ I = I for any interval I
///     // The intersection is always the other interval
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(positive)) => {
///             assert_eq!(positive.length().into_inner(), 10.0); // 5 - (-5) = 10
///         }
///         _ => unreachable!("Expected the original finite interval"),
///     }
/// }
///
/// // This property holds for all interval types
/// let open_interval = IntervalOpen::new(1.0, 2.0);
/// let intersection = universal.intersection(&open_interval).unwrap();
///
/// // Result should be equivalent to the original open interval
/// match intersection {
///     Interval::FiniteLength(IntervalFiniteLength::PositiveLength(
///         IntervalFinitePositiveLength::Open(recovered_open)
///     )) => {
///         assert_eq!(recovered_open.lower_bound_value(), &1.0);
///         assert_eq!(recovered_open.upper_bound_value(), &2.0);
///     }
///     _ => unreachable!("Expected open interval"),
/// }
/// ```
///
/// ### Universal with Universal (Self-Intersection)
/// ```rust
/// use grid1d::intervals::*;
///
/// let universal1 = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
/// let universal2 = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
///
/// if let Some(intersection) = universal1.intersection(&universal2) {
///     // ℝ ∩ ℝ = ℝ
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_)) => {
///             // This is correct - intersection of universal sets is universal
///         }
///         _ => unreachable!("Expected universal interval"),
///     }
/// }
/// ```
///
/// ### Universal as Identity Element
/// ```rust
/// use grid1d::intervals::*;
/// use try_create::New;
///
/// /// Demonstrate that the universal interval acts as an identity element for intersection
/// fn demonstrate_intersection_identity() {
///     let universal = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
///     
///     let test_intervals = vec![
///         Interval::from(IntervalClosed::new(0.0, 1.0)),
///         Interval::from(IntervalOpen::new(-1.0, 1.0)),
///         Interval::from(IntervalSingleton::new(0.5)),
///         Interval::from(IntervalLowerClosedUpperUnbounded::new(0.0)),
///         Interval::from(IntervalLowerUnboundedUpperClosed::new(10.0)),
///     ];
///     
///     for interval in test_intervals {
///         let intersection = universal.intersection(&interval).unwrap();
///         
///         // The intersection should be "equivalent" to the original interval
///         // (they should contain the same points)
///         for test_point in [-100.0, -1.0, 0.0, 0.5, 1.0, 10.0, 100.0] {
///             assert_eq!(
///                 interval.contains_point(&test_point),
///                 intersection.contains_point(&test_point)
///             );
///         }
///     }
/// }
///
/// demonstrate_intersection_identity();
/// ```
///
/// ## Advanced Usage Patterns
///
/// ### Universal Domain for Mathematical Functions
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents a mathematical function with universal domain
/// struct UniversalFunction {
///     domain: IntervalLowerUnboundedUpperUnbounded<f64>
/// }
///
/// impl UniversalFunction {
///     fn new() -> Self {
///         Self {
///             domain: IntervalLowerUnboundedUpperUnbounded::new()
///         }
///     }
///     
///     /// Check if a value is in the domain (always true for universal functions)
///     fn is_defined_at(&self, x: f64) -> bool {
///         self.domain.contains_point(&x)
///     }
///     
///     /// Evaluate polynomial: f(x) = x³ - 2x² + x - 1 (defined everywhere)
///     fn evaluate_polynomial(&self, x: f64) -> f64 {
///         // Polynomials are defined for all real numbers
///         x.powi(3) - 2.0 * x.powi(2) + x - 1.0
///     }
///     
///     /// Evaluate exponential: f(x) = eˣ (defined everywhere)
///     fn evaluate_exponential(&self, x: f64) -> f64 {
///         // Exponential function is defined for all real numbers
///         x.exp()
///     }
///     
///     /// Evaluate sine: f(x) = sin(x) (defined everywhere)
///     fn evaluate_sine(&self, x: f64) -> f64 {
///         // Trigonometric functions are defined for all real numbers
///         x.sin()
///     }
/// }
///
/// let universal_func = UniversalFunction::new();
///
/// // These functions are defined for any real input
/// assert!(universal_func.is_defined_at(0.0));
/// assert!(universal_func.is_defined_at(-1000.0));
/// assert!(universal_func.is_defined_at(1000.0));
/// assert!(universal_func.is_defined_at(std::f64::consts::PI));
///
/// // Evaluate at various points
/// println!("Polynomial at x=2: {}", universal_func.evaluate_polynomial(2.0));
/// println!("Exponential at x=1: {}", universal_func.evaluate_exponential(1.0));
/// println!("Sine at π: {}", universal_func.evaluate_sine(std::f64::consts::PI));
/// ```
///
/// ### Unconstrained Optimization Problems
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents an unconstrained optimization problem
/// struct UnconstrainedOptimization {
///     feasible_region: IntervalLowerUnboundedUpperUnbounded<f64>
/// }
///
/// impl UnconstrainedOptimization {
///     fn new() -> Self {
///         Self {
///             feasible_region: IntervalLowerUnboundedUpperUnbounded::new()
///         }
///     }
///     
///     /// Check if a point is feasible (always true for unconstrained problems)
///     fn is_feasible(&self, x: f64) -> bool {
///         self.feasible_region.contains_point(&x)
///     }
///     
///     /// Objective function: f(x) = x² - 4x + 3 (quadratic with minimum at x=2)
///     fn objective(&self, x: f64) -> f64 {
///         x * x - 4.0 * x + 3.0
///     }
///     
///     /// Gradient: f'(x) = 2x - 4
///     fn gradient(&self, x: f64) -> f64 {
///         2.0 * x - 4.0
///     }
///     
///     /// Find critical points (where gradient = 0)
///     fn find_critical_points(&self) -> Vec<f64> {
///         // 2x - 4 = 0 => x = 2
///         vec![2.0]
///     }
///     
///     /// Check if the problem is globally bounded below
///     fn is_bounded_below(&self) -> bool {
///         // This quadratic opens upward, so it's bounded below
///         true
///     }
/// }
///
/// let optimization = UnconstrainedOptimization::new();
///
/// // All real numbers are feasible
/// assert!(optimization.is_feasible(-1000.0));
/// assert!(optimization.is_feasible(0.0));
/// assert!(optimization.is_feasible(1000.0));
///
/// // Find and evaluate critical points
/// let critical_points = optimization.find_critical_points();
/// assert_eq!(critical_points, vec![2.0]);
///
/// let optimal_value = optimization.objective(2.0);
/// assert_eq!(optimal_value, -1.0); // f(2) = 4 - 8 + 3 = -1
///
/// // Verify this is indeed a minimum
/// assert!(optimization.objective(1.0) > optimal_value);
/// assert!(optimization.objective(3.0) > optimal_value);
/// ```
///
/// ### Set Theory and Universal Operations
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Demonstrate universal set properties
/// struct UniversalSetOperations {
///     universal: IntervalLowerUnboundedUpperUnbounded<f64>
/// }
///
/// impl UniversalSetOperations {
///     fn new() -> Self {
///         Self {
///             universal: IntervalLowerUnboundedUpperUnbounded::new()
///         }
///     }
///     
///     /// Union with universal set is always universal set
///     fn union_with_any<I>(&self, other: &I) -> Interval<f64>
///     where
///         I: IntervalTrait<RealType = f64>,
///         Interval<f64>: From<IntervalLowerUnboundedUpperUnbounded<f64>>,
///     {
///         // U ∪ A = U for any set A (universal property)
///         self.universal.clone().into()
///     }
///     
///     /// Intersection with universal set is identity operation
///     fn intersection_with_any<I>(&self, other: &I) -> Option<Interval<f64>>
///     where
///         I: IntervalTrait<RealType = f64>,
///     {
///         // U ∩ A = A for any set A (identity property)
///         self.universal.intersection(other)
///     }
///     
///     /// Check if any interval is a subset of universal (always true)
///     fn contains_any_interval<I>(&self, other: &I) -> bool
///     where
///         I: IntervalTrait<RealType = f64>,
///     {
///         // A ⊆ U for any set A (universal containment)
///         self.universal.contains_interval(other)
///     }
/// }
///
/// let universal_ops = UniversalSetOperations::new();
/// let test_interval = IntervalClosed::new(-5.0, 5.0);
///
/// // Demonstrate universal set properties
/// assert!(universal_ops.contains_any_interval(&test_interval));
///
/// // Union property: U ∪ A = U
/// let union_result = universal_ops.union_with_any(&test_interval);
/// match union_result {
///     Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_)) => {
///         // Correct: union with universal is universal
///     }
///     _ => unreachable!("Union with universal should be universal"),
/// }
///
/// // Identity property: U ∩ A = A
/// let intersection_result = universal_ops.intersection_with_any(&test_interval).unwrap();
/// // The result should behave identically to the original interval for containment
/// for test_point in [-10.0, -5.0, 0.0, 5.0, 10.0] {
///     assert_eq!(
///         test_interval.contains_point(&test_point),
///         intersection_result.contains_point(&test_point)
///     );
/// }
/// ```
///
/// ### Physics and Engineering Applications
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Model a physical quantity that can take any real value
/// struct UnboundedPhysicalQuantity {
///     valid_range: IntervalLowerUnboundedUpperUnbounded<f64>,
///     unit: String,
/// }
///
/// impl UnboundedPhysicalQuantity {
///     fn new(unit: String) -> Self {
///         Self {
///             valid_range: IntervalLowerUnboundedUpperUnbounded::new(),
///             unit,
///         }
///     }
///     
///     /// Check if a measurement is physically valid (always true for unbounded quantities)
///     fn is_valid_measurement(&self, value: f64) -> bool {
///         self.valid_range.contains_point(&value)
///     }
///     
///     /// Get the theoretical range of the quantity
///     fn theoretical_range(&self) -> String {
///         format!("(-∞, +∞) {}", self.unit)
///     }
/// }
///
/// // Examples of unbounded physical quantities
///
/// /// Electric potential (voltage) - can be any real value
/// let voltage = UnboundedPhysicalQuantity::new("V".to_string());
/// assert!(voltage.is_valid_measurement(-1000.0)); // Negative voltage
/// assert!(voltage.is_valid_measurement(0.0));     // Ground potential
/// assert!(voltage.is_valid_measurement(1000.0));  // Positive voltage
/// assert_eq!(voltage.theoretical_range(), "(-∞, +∞) V");
///
/// /// Temperature difference - can be any real value
/// let temp_difference = UnboundedPhysicalQuantity::new("K".to_string());
/// assert!(temp_difference.is_valid_measurement(-273.15)); // Large negative difference
/// assert!(temp_difference.is_valid_measurement(0.0));     // No difference
/// assert!(temp_difference.is_valid_measurement(1000.0));  // Large positive difference
///
/// /// Displacement in mechanics - can be any real value
/// let displacement = UnboundedPhysicalQuantity::new("m".to_string());
/// assert!(displacement.is_valid_measurement(-1e6));  // 1000 km backwards
/// assert!(displacement.is_valid_measurement(0.0));   // No displacement
/// assert!(displacement.is_valid_measurement(1e6));   // 1000 km forwards
/// ```
///
/// ## Performance Characteristics
///
/// ### Memory Layout
/// - **Storage**: Zero scalar values (phantom data only)
/// - **Size**: Minimal - typically 0-1 bytes (phantom marker)
/// - **Alignment**: No alignment requirements
/// - **No heap allocation**: Most memory-efficient interval type
///
/// ### Operation Complexity
/// | Operation | Time Complexity | Space Complexity | Notes |
/// |-----------|----------------|------------------|-------|
/// | Point containment | O(1) | O(1) | Always returns `true` - fastest possible |
/// | Interval containment | O(1) | O(1) | Always returns `true` - universal property |
/// | Intersection | O(1) | O(1) | Identity operation - returns other interval |
/// | Construction | O(1) | O(1) | No data to initialize |
///
/// ### Scalar Type Performance Impact
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::{RealNative64StrictFiniteInDebug, RealNative64StrictFinite, RealScalar};
///
/// // All these have identical performance (zero data stored):
/// type FastUniversal = IntervalLowerUnboundedUpperUnbounded<f64>;
/// type OptimalUniversal = IntervalLowerUnboundedUpperUnbounded<RealNative64StrictFiniteInDebug>;
/// type SafeUniversal = IntervalLowerUnboundedUpperUnbounded<RealNative64StrictFinite>;
///
/// // Performance test function (generic over any universal interval)
/// fn benchmark_universal_operations<T: RealScalar + Clone>(
///     universal: &IntervalLowerUnboundedUpperUnbounded<T>
/// ) {
///     // All operations are extremely fast - no bounds to check
///     let _contains_zero = universal.contains_point(&T::zero());      // Always true
///     let _contains_large = universal.contains_point(&T::try_from_f64(1e6).unwrap()); // Always true
///     
///     // These operations compile to nearly no-op in optimized builds
/// }
/// ```
///
/// ## Integration with Other Traits
///
/// ### No Bound Traits (By Design)
/// ```rust
/// use grid1d::intervals::*;
///
/// // The universal interval does NOT implement GetLowerBoundValue or GetUpperBoundValue
/// // This is mathematically correct - it has no finite bounds
///
/// let universal = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
///
/// // This won't compile (and shouldn't):
/// // let lower = universal.lower_bound_value(); // ERROR: method not available
/// // let upper = universal.upper_bound_value(); // ERROR: method not available
///
/// // This is the correct way to handle universal intervals in generic code:
/// fn handle_any_interval(interval: &Interval<f64>) -> String {
///     match interval {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_)) => {
///             "Universal interval: no finite bounds".to_string()
///         }
///         Interval::InfiniteLength(infinite) => {
///             // Other infinite intervals have at least one finite bound
///             "Semi-infinite interval".to_string()
///         }
///         Interval::FiniteLength(_) => {
///             "Finite interval".to_string()
///         }
///     }
/// }
/// ```
///
/// ### Universal Container Property
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::RealScalar;
///
/// /// Demonstrate universal containment for any interval type and scalar type
/// fn verify_universal_containment<T, I>(
///     universal: &IntervalLowerUnboundedUpperUnbounded<T>,
///     any_interval: &I
/// ) -> bool
/// where
///     T: RealScalar,
///     I: IntervalTrait<RealType = T>,
/// {
///     // The universal interval contains every other interval
///     universal.contains_interval(any_interval)
/// }
///
/// // This property holds for all scalar types and interval types
/// let universal_f64 = IntervalLowerUnboundedUpperUnbounded::<f64>::new();
/// let finite_f64 = IntervalClosed::new(-1.0, 1.0);
/// assert!(verify_universal_containment(&universal_f64, &finite_f64));
///
/// // Works with validated scalar types too
/// use num_valid::RealNative64StrictFinite;
/// use try_create::TryNew;
/// type ValidatedReal = RealNative64StrictFinite;
///
/// let universal_validated = IntervalLowerUnboundedUpperUnbounded::<ValidatedReal>::new();
/// let finite_validated = IntervalClosed::new(
///     ValidatedReal::try_new(-1.0).unwrap(),
///     ValidatedReal::try_new(1.0).unwrap()
/// );
/// assert!(verify_universal_containment(&universal_validated, &finite_validated));
/// ```
///
/// ## Best Practices and Recommendations
///
/// ### When to Use [`IntervalLowerUnboundedUpperUnbounded`]
/// - **Mathematical functions**: Polynomials, exponentials, trigonometric functions
/// - **Unconstrained optimization**: Problems without domain restrictions
/// - **Universal domains**: When no constraints apply to the variable
/// - **Set theory**: Representing the universal set of real numbers
/// - **Default cases**: When other intervals are too restrictive
/// - **Physics**: Quantities that can theoretically take any real value
///
/// ### When NOT to Use [`IntervalLowerUnboundedUpperUnbounded`]
/// - **Physical constraints**: Real-world quantities usually have practical limits
/// - **Numerical algorithms**: May need bounded domains for convergence
/// - **Integration**: Infinite domains require special techniques
/// - **Probability**: Probability values are bounded between 0 and 1
/// - **Performance-critical code**: When you know the actual bounds
///
/// ### Recommended Patterns
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::{RealScalar, RealNative64StrictFiniteInDebug, functions::Pow};
///
/// // Define type aliases for your application
/// type Real = RealNative64StrictFiniteInDebug;
/// type UniversalInterval = IntervalLowerUnboundedUpperUnbounded<Real>;
///
/// // Pattern: Use as default/fallback domain
/// fn create_function_domain(constraints: Option<(Real, Real)>) -> Interval<Real> {
///     match constraints {
///         Some((lower, upper)) => {
///             IntervalClosed::new(lower, upper).into()
///         }
///         None => {
///             // No constraints - use universal domain
///             UniversalInterval::new().into()
///         }
///     }
/// }
///
/// // Pattern: Handle universal case explicitly in generic code
/// fn analyze_domain(interval: &Interval<Real>) -> String {
///     match interval {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperUnbounded(_)) => {
///             "Unrestricted domain (all real numbers)".to_string()
///         }
///         Interval::InfiniteLength(_) => {
///             "Semi-infinite domain".to_string()
///         }
///         Interval::FiniteLength(_) => {
///             "Bounded domain".to_string()
///         }
///     }
/// }
///
/// // Pattern: Use for mathematical modeling
/// fn model_polynomial_function() -> (UniversalInterval, impl Fn(Real) -> Real) {
///     let domain = UniversalInterval::new();
///     let function = |x: Real| {
///         // Polynomial: f(x) = x³ - 2x² + x - 1
///         x.clone().pow(3) - Real::try_from_f64(2.0).unwrap() * x.clone().pow(2) + x.clone() - Real::try_from_f64(1.0).unwrap()
///     };
///     (domain, function)
/// }
/// ```
///
/// ## Common Use Cases
///
/// ### Mathematical Analysis
/// - **Function domains**: Polynomials, exponentials, trigonometric functions
/// - **Real analysis**: Working with the complete real line
/// - **Set operations**: Universal set for intersection and union operations
///
/// ### Optimization and Control Theory
/// - **Unconstrained optimization**: Problems without domain restrictions
/// - **Control variables**: Variables that can take any real value
/// - **State space**: When state variables are unrestricted
///
/// ### Physics and Engineering
/// - **Theoretical models**: Quantities without practical bounds
/// - **Mathematical physics**: Working with abstract real-valued fields
/// - **Signal processing**: Signals that can have any amplitude
///
/// ## Mathematical Properties and Guarantees
///
/// The [`IntervalLowerUnboundedUpperUnbounded`] struct maintains these mathematical properties:
///
/// - **Universal containment**: Contains every real number and every other interval
/// - **Identity element**: Intersection with any interval yields that interval
/// - **Absorption element**: Union with any interval yields the universal interval
/// - **No bounds**: Has no finite lower or upper bounds
/// - **Maximum cardinality**: Contains uncountably infinite points
/// - **Translation invariance**: Shifting has no effect (already contains everything)
/// - **Scale invariance**: Scaling has no effect (already contains everything)
///
/// These properties are fundamental to the real number system and are guaranteed
/// by the mathematical definition of the universal interval regardless of the
/// scalar type used.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct IntervalLowerUnboundedUpperUnbounded<RealType: RealScalar> {
    _phantom: std::marker::PhantomData<RealType>,
}

impl<RealType: RealScalar> IntervalLowerUnboundedUpperUnbounded<RealType> {
    /// Creates a new unbounded interval.
    ///
    /// This is a placeholder type that represents an interval with no bounds.
    pub fn new() -> Self {
        Self {
            _phantom: std::marker::PhantomData,
        }
    }
}

impl<RealType: RealScalar> Default for IntervalLowerUnboundedUpperUnbounded<RealType> {
    fn default() -> Self {
        Self::new()
    }
}

impl<RealType: RealScalar> IntervalOperations for IntervalLowerUnboundedUpperUnbounded<RealType> {
    fn intersection<IntervalType: IntervalTrait<RealType = Self::RealType>>(
        &self,
        other: &IntervalType,
    ) -> Option<Interval<RealType>> {
        // For unbounded intervals, intersection with any interval is that interval
        let lb = other.lower_bound_runtime();
        let ub = other.upper_bound_runtime();

        Some(Interval::try_new(lb, ub).expect(
            "Failed to create an Interval from its bounds in intersection with unbounded interval!",
        ))
    }
}

impl<RealType: RealScalar> Contains for IntervalLowerUnboundedUpperUnbounded<RealType> {
    #[inline(always)]
    fn contains_point(&self, _x: &RealType) -> bool {
        // An unbounded interval contains all points
        true
    }

    #[inline(always)]
    fn contains_interval<IntervalType: IntervalTrait<RealType = RealType>>(
        &self,
        _other: &IntervalType,
    ) -> bool {
        // An unbounded interval contains any other interval
        true
    }
}

impl<RealType: RealScalar> IntervalTrait for IntervalLowerUnboundedUpperUnbounded<RealType> {}
//------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------
/// Common interface for intervals with finite lower bounds extending to positive infinity.
///
/// The [`IntervalLowerBoundedUpperUnboundedTrait`] trait provides a unified interface for interval
/// types that have a finite lower bound but extend infinitely in the positive direction.
///
/// ## Implementing Types
///
/// - [`IntervalLowerClosedUpperUnbounded`]: `[a, +∞)` - Lower bound included
/// - [`IntervalLowerOpenUpperUnbounded`]: `(a, +∞)` - Lower bound excluded
///
/// ## Required Method
///
/// - [`lower_bound_value`](GetLowerBoundValue::lower_bound_value): Access the finite lower bound
///
/// ## Mathematical Foundation
///
/// - **Mathematical notation**: `[a, +∞)` or `(a, +∞)` where `a` is finite
/// - **Infinite measure**: `μ(I) = +∞` for all implementing intervals
/// - **Non-compactness**: Semi-infinite intervals are never compact
///
/// ## Usage Examples
///
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealScalar;
///
/// fn analyze_lower_bounded<I, T>(interval: &I) -> String
/// where
///     I: IntervalLowerBoundedUpperUnboundedTrait<RealType = T>,
///     T: RealScalar + std::fmt::Display,
/// {
///     format!(
///         "Semi-infinite interval extending from {} to positive infinity",
///         interval.lower_bound_value()
///     )
/// }
///
/// let closed_unbounded = IntervalLowerClosedUpperUnbounded::new(5.0);
/// let open_unbounded = IntervalLowerOpenUpperUnbounded::new(-2.0);
///
/// println!("{}", analyze_lower_bounded(&closed_unbounded));
/// println!("{}", analyze_lower_bounded(&open_unbounded));
/// ```
pub trait IntervalLowerBoundedUpperUnboundedTrait:
    IntervalTrait + GetLowerBoundValue<LowerBoundValue = Self::RealType>
{
}

/// Common interface for intervals extending from negative infinity with finite upper bounds.
///
/// The [`IntervalLowerUnboundedUpperBoundedTrait`] trait provides a unified interface for interval
/// types that extend infinitely in the negative direction but have a finite upper bound.
///
/// ## Implementing Types
///
/// - [`IntervalLowerUnboundedUpperClosed`]: `(-∞, b]` - Upper bound included
/// - [`IntervalLowerUnboundedUpperOpen`]: `(-∞, b)` - Upper bound excluded
///
/// ## Required Method
///
/// - [`upper_bound_value`](GetUpperBoundValue::upper_bound_value): Access the finite upper bound
///
/// ## Mathematical Foundation
///
/// - **Mathematical notation**: `(-∞, b]` or `(-∞, b)` where `b` is finite
/// - **Infinite measure**: `μ(I) = +∞` for all implementing intervals
/// - **Non-compactness**: Semi-infinite intervals are never compact
///
/// ## Usage Examples
///
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealScalar;
///
/// fn analyze_upper_bounded<I, T>(interval: &I) -> String
/// where
///     I: IntervalLowerUnboundedUpperBoundedTrait<RealType = T>,
///     T: RealScalar + std::fmt::Display,
/// {
///     format!(
///         "Semi-infinite interval extending from negative infinity to {}",
///         interval.upper_bound_value()
///     )
/// }
///
/// let closed_upper_bounded = IntervalLowerUnboundedUpperClosed::new(100.0);
/// let open_upper_bounded = IntervalLowerUnboundedUpperOpen::new(-50.0);
///
/// println!("{}", analyze_upper_bounded(&closed_upper_bounded));
/// println!("{}", analyze_upper_bounded(&open_upper_bounded));
/// ```
pub trait IntervalLowerUnboundedUpperBoundedTrait:
    IntervalTrait + GetUpperBoundValue<UpperBoundValue = Self::RealType>
{
}

impl<RealType: RealScalar, UpperBoundType: BoundType> IntervalLowerUnboundedUpperBoundedTrait
    for IntervalLowerUnboundedUpperBounded<RealType, UpperBoundType>
where
    Self: IntervalBoundsRuntime<RealType = RealType>,
    UpperBound<RealType, UpperBoundType>: ValueWithinBound<RealType = RealType>,
{
}
//------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------
/// A lower closed, upper unbounded interval `[a, +∞)` where the lower endpoint is included and extends to positive infinity.
///
/// The [`IntervalLowerClosedUpperUnbounded`] represents intervals of the form `[a, +∞)` where the lower bound `a`
/// is part of the interval and the upper extent is infinite. This type of interval is fundamental
/// in mathematical analysis, particularly for "at least" constraints, non-negative domains, cumulative
/// distribution functions, and mathematical constructions where you need to include a starting point
/// while extending infinitely upward.
///
/// ## Mathematical Properties
///
/// - **Notation**: `[a, +∞)` or `[a, +∞[`
/// - **Definition**: `{x ∈ ℝ : x ≥ a}` where `a` is finite
/// - **Lower boundary**: Included (closed)
/// - **Upper boundary**: Infinite (unbounded)
/// - **Measure**: `+∞` (infinite length)
/// - **Topology**: Neither open nor closed (half-open, half-unbounded)
/// - **Cardinality**: Uncountably infinite points
/// - **Compactness**: Never compact (unbounded)
///
/// ## Use Cases
///
/// Lower closed, upper unbounded intervals are ideal when:
/// - **"At least" constraints**: Domains where `x ≥ a` (inclusive minimum)
/// - **Non-negative domains**: Mathematical functions defined for `x ≥ 0`
/// - **Cumulative distributions**: CDF domains that include the starting point
/// - **Growth models**: Unbounded growth starting from a specific value (included)
/// - **Optimization**: Feasible regions with inclusive lower bounds and no upper limits
/// - **Physical quantities**: Measurements that have a minimum value but no maximum
///
/// ## Comparison with Other Interval Types
///
/// | Property | `[a,+∞)` | `(a,+∞)` | `(-∞,b]` | `[a,b]` |
/// |----------|----------|----------|----------|---------|
/// | Contains `a` | ✓ | ✗ | N/A | ✓ |
/// | Contains values > `a` | ✓ | ✓ | Depends on `b` | Depends on `b` |
/// | Length | `+∞` | `+∞` | `+∞` | `b - a` |
/// | Compactness | Never | Never | Never | Always |
/// | Lower bound achieved | ✓ | ✗ | N/A | ✓ |
/// | Upper bound | None | None | ✓ | ✓ |
/// | Infimum | `a` (achieved) | `a` (not achieved) | N/A | `a` (achieved) |
///
/// ## Construction
///
/// ### Safe Construction (Recommended)
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::RealNative64StrictFiniteInDebug;
/// use try_create::TryNew;
///
/// // Use the recommended performance-optimal type
/// type Real = RealNative64StrictFiniteInDebug;
///
/// // Create with validated scalar
/// let interval = IntervalLowerClosedUpperUnbounded::new(
///     Real::try_new(0.0).unwrap()
/// );
/// assert_eq!(interval.lower_bound_value(), &0.0);
/// ```
///
/// ### Raw Construction (Use with Caution)
/// ```rust
/// use grid1d::intervals::*;
///
/// // Direct construction with raw f64 - only when you trust your data
/// let interval = IntervalLowerClosedUpperUnbounded::new(5.0);
/// assert_eq!(interval.lower_bound_value(), &5.0);
/// ```
///
/// ## Key Operations
///
/// ### Point Containment (Lower Included, Upper Infinite)
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerClosedUpperUnbounded::new(0.0);  // [0, +∞)
///
/// // Lower boundary is included
/// assert!(interval.contains_point(&0.0));    // Lower bound included
///
/// // All values above lower bound are included
/// assert!(interval.contains_point(&0.1));    // Just above lower bound
/// assert!(interval.contains_point(&1.0));    // Above lower bound
/// assert!(interval.contains_point(&1000.0)); // Far above lower bound
///
/// // Values below lower bound are excluded
/// assert!(!interval.contains_point(&-1.0));  // Below lower bound
/// assert!(!interval.contains_point(&-0.1));  // Just below lower bound
/// ```
///
/// ### Boundary Behavior Analysis
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerClosedUpperUnbounded::new(5.0);  // [5, +∞)
///
/// // Test boundary inclusion
/// assert!(interval.contains_point(&5.0));     // Lower bound included
///
/// // Test points near lower boundary
/// assert!(interval.contains_point(&5.0001));  // Just above lower bound
/// assert!(!interval.contains_point(&4.9999)); // Just below lower bound
///
/// // Test large values (always included)
/// assert!(interval.contains_point(&1e6));     // Very large positive value
/// assert!(interval.contains_point(&f64::MAX)); // Floating-point limits
/// ```
///
/// ### Accessing the Lower Bound
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerClosedUpperUnbounded::new(-10.0);
///
/// // Access the finite lower bound
/// assert_eq!(interval.lower_bound_value(), &-10.0);
///
/// // The lower bound itself is included in the interval
/// assert!(interval.contains_point(interval.lower_bound_value()));
///
/// // Values above the lower bound are included
/// assert!(interval.contains_point(&(-10.0 + 1.0)));
/// ```
///
/// ## Interval Containment and Set Operations
///
/// ### Containment Testing
/// ```rust
/// use grid1d::intervals::*;
///
/// let outer = IntervalLowerClosedUpperUnbounded::new(0.0);   // [0, +∞)
/// let inner = IntervalLowerClosedUpperUnbounded::new(1.0);   // [1, +∞)
/// let boundary = IntervalLowerClosedUpperUnbounded::new(0.0); // [0, +∞)
///
/// // Intervals with lower bounds can contain those with higher lower bounds
/// assert!(outer.contains_interval(&inner));           // [0, +∞) ⊇ [1, +∞) ✓
/// assert!(!inner.contains_interval(&outer));          // [1, +∞) ⊉ [0, +∞) ✗
///
/// // Same intervals contain themselves
/// assert!(outer.contains_interval(&boundary));        // [0, +∞) ⊇ [0, +∞) ✓
///
/// // Cross-type containment
/// let finite = IntervalClosed::new(1.0, 100.0);               // [1, 100]
/// let open_unbounded = IntervalLowerOpenUpperUnbounded::new(0.5); // (0.5, +∞)
/// let upper_bounded = IntervalLowerUnboundedUpperClosed::new(50.0); // (-∞, 50]
///
/// assert!(outer.contains_interval(&finite));          // [0, +∞) ⊇ [1, 100] ✓
/// assert!(outer.contains_interval(&open_unbounded));  // [0, +∞) ⊇ (0.5, +∞) ✓
/// assert!(!outer.contains_interval(&upper_bounded));  // [0, +∞) ⊉ (-∞, 50] ✗
/// assert!(!upper_bounded.contains_interval(&outer));  // (-∞, 50] ⊉ [0, +∞) ✗
/// ```
///
/// ## Intersection Examples
///
/// ### Closed Unbounded with Closed Unbounded
/// ```rust
/// use grid1d::intervals::*;
///
/// let a = IntervalLowerClosedUpperUnbounded::new(0.0);  // [0, +∞)
/// let b = IntervalLowerClosedUpperUnbounded::new(1.0);  // [1, +∞)
///
/// if let Some(intersection) = a.intersection(&b) {
///     // Result: [1, +∞) - takes the more restrictive (higher) lower bound
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerClosedUpperUnbounded(result)) => {
///             assert_eq!(result.lower_bound_value(), &1.0);
///         }
///         _ => unreachable!("Expected closed unbounded interval"),
///     }
/// }
/// ```
///
/// ### Closed Unbounded with Finite Intervals
/// ```rust
/// use grid1d::intervals::*;
///
/// let unbounded = IntervalLowerClosedUpperUnbounded::new(0.0);  // [0, +∞)
/// let closed = IntervalClosed::new(1.0, 10.0);                  // [1, 10]
/// let open = IntervalOpen::new(-1.0, 5.0);                      // (-1, 5)
///
/// // Intersection of [0, +∞) with [1, 10]
/// // Result: [1, 10]
/// if let Some(intersection) = unbounded.intersection(&closed) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(positive)) => {
///             assert_eq!(positive.length().into_inner(), 9.0); // 10 - 1 = 9
///         }
///         _ => unreachable!("Expected finite positive interval"),
///     }
/// }
///
/// // Intersection of [0, +∞) with (-1, 5)
/// // Result: [0, 5)
/// if let Some(intersection) = unbounded.intersection(&open) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(
///             IntervalFinitePositiveLength::LowerClosedUpperOpen(result)
///         )) => {
///             assert_eq!(result.lower_bound_value(), &0.0);
///             assert_eq!(result.upper_bound_value(), &5.0);
///         }
///         _ => unreachable!("Expected right half-open finite interval"),
///     }
/// }
/// ```
///
/// ### Closed Unbounded with Other Unbounded Types
/// ```rust
/// use grid1d::intervals::*;
///
/// let closed_unbounded = IntervalLowerClosedUpperUnbounded::new(0.0);       // [0, +∞)
/// let open_unbounded = IntervalLowerOpenUpperUnbounded::new(1.0);           // (1, +∞)
/// let upper_bounded = IntervalLowerUnboundedUpperClosed::new(10.0);         // (-∞, 10]
/// let fully_unbounded = IntervalLowerUnboundedUpperUnbounded::<f64>::new(); // (-∞, +∞)
///
/// // Intersection of [0, +∞) with (1, +∞)
/// // Result: (1, +∞)
/// if let Some(intersection) = closed_unbounded.intersection(&open_unbounded) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerOpenUpperUnbounded(result)) => {
///             assert_eq!(result.lower_bound_value(), &1.0);
///         }
///         _ => unreachable!("Expected open unbounded interval"),
///     }
/// }
///
/// // Intersection of [0, +∞) with (-∞, 10]
/// // Result: [0, 10]
/// if let Some(intersection) = closed_unbounded.intersection(&upper_bounded) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(
///             IntervalFinitePositiveLength::Closed(result)
///         )) => {
///             assert_eq!(result.lower_bound_value(), &0.0);
///             assert_eq!(result.upper_bound_value(), &10.0);
///         }
///         _ => unreachable!("Expected closed finite interval"),
///     }
/// }
///
/// // Intersection of [0, +∞) with (-∞, +∞)
/// // Result: [0, +∞)
/// if let Some(intersection) = closed_unbounded.intersection(&fully_unbounded) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerClosedUpperUnbounded(result)) => {
///             assert_eq!(result.lower_bound_value(), &0.0);
///         }
///         _ => unreachable!("Expected closed unbounded interval"),
///     }
/// }
/// ```
///
/// ### Edge Cases: Boundary Cases
/// ```rust
/// use grid1d::intervals::*;
///
/// let non_negative = IntervalLowerClosedUpperUnbounded::new(0.0);      // [0, +∞)
/// let negative = IntervalLowerUnboundedUpperOpen::new(0.0);            // (-∞, 0)
/// let zero_included = IntervalLowerUnboundedUpperClosed::new(0.0);     // (-∞, 0]
/// let at_boundary = IntervalLowerOpenUpperUnbounded::new(0.0);         // (0, +∞)
///
/// // Disjoint intervals
/// assert!(non_negative.intersection(&negative).is_none());     // [0, +∞) ∩ (-∞, 0) = ∅
///
/// // Boundary touching with singleton intersection
/// if let Some(intersection) = non_negative.intersection(&zero_included) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::ZeroLength(singleton)) => {
///             assert_eq!(singleton.value(), &0.0);
///         }
///         _ => unreachable!("Expected singleton intersection"),
///     }
/// }
///
/// // [0, +∞) ∩ (0, +∞) = (0, +∞) - the open interval wins at boundary
/// if let Some(intersection) = non_negative.intersection(&at_boundary) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerOpenUpperUnbounded(result)) => {
///             assert_eq!(result.lower_bound_value(), &0.0);
///         }
///         _ => unreachable!("Expected open unbounded interval"),
///     }
/// }
/// ```
///
/// ## Advanced Usage Patterns
///
/// ### Non-Negativity Constraints
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents a non-negative domain constraint
/// struct NonNegativeDomain {
///     domain: IntervalLowerClosedUpperUnbounded<f64>
/// }
///
/// impl NonNegativeDomain {
///     fn new() -> Self {
///         Self {
///             domain: IntervalLowerClosedUpperUnbounded::new(0.0)
///         }
///     }
///     
///     /// Check if a value is non-negative
///     fn is_valid(&self, x: f64) -> bool {
///         self.domain.contains_point(&x)
///     }
///     
///     /// Project a value onto the non-negative domain
///     fn project(&self, x: f64) -> f64 {
///         x.max(0.0)  // Clamp to zero if negative
///     }
///     
///     /// Get the minimum allowed value
///     fn minimum_value(&self) -> f64 {
///         *self.domain.lower_bound_value()
///     }
/// }
///
/// let domain = NonNegativeDomain::new();
///
/// assert!(domain.is_valid(0.0));       // Zero is valid
/// assert!(domain.is_valid(5.0));       // Positive values are valid
/// assert!(!domain.is_valid(-1.0));     // Negative values are invalid
///
/// assert_eq!(domain.project(-5.0), 0.0); // Project negative to zero
/// assert_eq!(domain.project(3.0), 3.0);  // Positive values unchanged
/// assert_eq!(domain.minimum_value(), 0.0);
/// ```
///
/// ### Growth Models and Accumulative Processes
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Models a quantity that grows without bound from a starting value (included)
/// struct GrowthModel {
///     valid_range: IntervalLowerClosedUpperUnbounded<f64>,
///     initial_value: f64,
/// }
///
/// impl GrowthModel {
///     fn new(initial_value: f64) -> Self {
///         Self {
///             valid_range: IntervalLowerClosedUpperUnbounded::new(initial_value),
///             initial_value,
///         }
///     }
///     
///     /// Check if a value is achievable by the growth process
///     fn is_achievable(&self, value: f64) -> bool {
///         self.valid_range.contains_point(&value)
///     }
///     
///     /// Get the starting value of the growth process
///     fn initial_value(&self) -> f64 {
///         self.initial_value
///     }
///     
///     /// Calculate growth from initial value
///     fn growth_amount(&self, current_value: f64) -> Option<f64> {
///         if self.is_achievable(current_value) {
///             Some(current_value - self.initial_value)
///         } else {
///             None  // Value is not achievable
///         }
///     }
///     
///     /// Model exponential growth: V(t) = V₀ * e^(rt)
///     fn exponential_value(&self, time: f64, growth_rate: f64) -> f64 {
///         self.initial_value * (growth_rate * time).exp()
///     }
/// }
///
/// let growth = GrowthModel::new(100.0);  // Growth starting from 100
///
/// assert!(growth.is_achievable(100.0));  // Initial value is achievable
/// assert!(growth.is_achievable(250.0));  // Values above initial value
/// assert!(!growth.is_achievable(50.0));  // Values below initial value
///
/// assert_eq!(growth.initial_value(), 100.0);
/// assert_eq!(growth.growth_amount(150.0), Some(50.0));  // 150 - 100 = 50
/// assert_eq!(growth.growth_amount(75.0), None);         // Not achievable
///
/// // Exponential growth: 100 * e^(0.1 * 5) ≈ 164.87
/// let future_value = growth.exponential_value(5.0, 0.1);
/// assert!((future_value - 164.87).abs() < 0.1);
/// ```
///
/// ### Probability Theory: Support of Distributions
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Half-normal distribution with support [0, +∞)
/// struct HalfNormalDistribution {
///     support: IntervalLowerClosedUpperUnbounded<f64>,
///     scale: f64,
/// }
///
/// impl HalfNormalDistribution {
///     fn new(scale: f64) -> Self {
///         Self {
///             support: IntervalLowerClosedUpperUnbounded::new(0.0),
///             scale,
///         }
///     }
///     
///     /// Probability density function
///     fn pdf(&self, x: f64) -> f64 {
///         if self.support.contains_point(&x) {
///             let sqrt_2_over_pi = (2.0 / std::f64::consts::PI).sqrt();
///             (sqrt_2_over_pi / self.scale) * (-x.powi(2) / (2.0 * self.scale.powi(2))).exp()
///         } else {
///             0.0  // Outside support
///         }
///     }
///     
///     /// Cumulative distribution function
///     fn cdf(&self, x: f64) -> f64 {
///         if x <= 0.0 {
///             0.0
///         } else if self.support.contains_point(&x) {
///             // Using error function approximation (simplified)
///             let z = x / (self.scale * std::f64::consts::SQRT_2);
///             // This is a placeholder - real implementation would use erf function
///             z.tanh()  // Rough approximation
///         } else {
///             unreachable!() // Should not happen for this distribution
///         }
///     }
///     
///     /// Check if value is in distribution support
///     fn in_support(&self, x: f64) -> bool {
///         self.support.contains_point(&x)
///     }
///     
///     /// Mean of half-normal distribution
///     fn mean(&self) -> f64 {
///         self.scale * (2.0 / std::f64::consts::PI).sqrt()
///     }
/// }
///
/// let half_normal = HalfNormalDistribution::new(1.0);
///
/// assert!(half_normal.in_support(0.0));       // Includes zero
/// assert!(half_normal.in_support(2.0));       // Positive values
/// assert!(!half_normal.in_support(-1.0));     // Excludes negative values
///
/// assert!(half_normal.pdf(0.0) > 0.0);        // Positive density at zero
/// assert!(half_normal.pdf(1.0) > 0.0);        // Positive density for positive values
/// assert_eq!(half_normal.pdf(-1.0), 0.0);     // Zero density outside support
/// assert_eq!(half_normal.cdf(0.0), 0.0);      // CDF starts at zero
/// ```
///
/// ### Financial Mathematics: Asset Pricing
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Models asset prices that cannot go below zero but can grow without bound
/// struct AssetPrice {
///     valid_prices: IntervalLowerClosedUpperUnbounded<f64>,
///     current_price: f64,
/// }
///
/// impl AssetPrice {
///     fn new(initial_price: f64) -> Self {
///         assert!(initial_price >= 0.0, "Asset price must be non-negative");
///         Self {
///             valid_prices: IntervalLowerClosedUpperUnbounded::new(0.0),
///             current_price: initial_price,
///         }
///     }
///     
///     /// Check if a price is valid
///     fn is_valid_price(&self, price: f64) -> bool {
///         self.valid_prices.contains_point(&price)
///     }
///     
///     /// Update the current price (must be non-negative)
///     fn update_price(&mut self, new_price: f64) -> Result<(), String> {
///         if self.is_valid_price(new_price) {
///             self.current_price = new_price;
///             Ok(())
///         } else {
///             Err(format!("Invalid price: {}. Must be non-negative.", new_price))
///         }
///     }
///     
///     /// Calculate return from a previous price
///     fn calculate_return(&self, previous_price: f64) -> Option<f64> {
///         if self.is_valid_price(previous_price) && previous_price > 0.0 {
///             Some((self.current_price - previous_price) / previous_price)
///         } else {
///             None  // Cannot calculate return from invalid or zero price
///         }
///     }
///     
///     /// Apply a return to get new price
///     fn apply_return(&self, return_rate: f64) -> f64 {
///         let new_price = self.current_price * (1.0 + return_rate);
///         new_price.max(0.0)  // Ensure non-negative (limited liability)
///     }
/// }
///
/// let mut asset = AssetPrice::new(100.0);
///
/// assert!(asset.is_valid_price(0.0));     // Zero price is valid (bankruptcy)
/// assert!(asset.is_valid_price(150.0));   // Higher prices are valid
/// assert!(!asset.is_valid_price(-10.0));  // Negative prices are invalid
///
/// // Update price successfully
/// assert!(asset.update_price(120.0).is_ok());
///
/// // Try to update with invalid price
/// assert!(asset.update_price(-5.0).is_err());
///
/// // Calculate return: (120 - 100) / 100 = 0.2 = 20%
/// assert_eq!(asset.calculate_return(100.0), Some(0.2));
///
/// // Apply negative return that would make price negative
/// let crashed_price = asset.apply_return(-2.0);  // -100% return
/// assert_eq!(crashed_price, 0.0);  // Limited to zero (limited liability)
/// ```
///
/// ## Performance Characteristics
///
/// ### Memory Layout
/// - **Storage**: Single scalar value for the lower bound (8 bytes for f64)
/// - **Alignment**: Natural alignment of the scalar type
/// - **No heap allocation**: All data stored inline
/// - **Compact representation**: Most memory-efficient for semi-infinite intervals
///
/// ### Operation Complexity
/// | Operation | Time Complexity | Space Complexity | Notes |
/// |-----------|----------------|------------------|-------|
/// | [`lower_bound_value`](IntervalLowerClosedUpperUnbounded::lower_bound_value) | O(1) | O(1) | Direct field access |
/// | Point containment | O(1) | O(1) | Single comparison (`x >= lower_bound`) |
/// | Interval operations | O(1) | O(1) | Efficient boundary logic |
/// | Construction | O(1) | O(1) | Single validation check in debug mode |
///
/// ### Scalar Type Performance Impact
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::{RealNative64StrictFiniteInDebug, RealNative64StrictFinite, RealScalar};
///
/// // These have identical performance in release builds:
/// type FastClosedUnbounded = IntervalLowerClosedUpperUnbounded<f64>;
/// type OptimalClosedUnbounded = IntervalLowerClosedUpperUnbounded<RealNative64StrictFiniteInDebug>;
///
/// // This has small validation overhead:
/// type SafeClosedUnbounded = IntervalLowerClosedUpperUnbounded<RealNative64StrictFinite>;
///
/// // Performance test function (generic over any closed unbounded interval)
/// fn benchmark_closed_unbounded_operations<T: RealScalar + Clone>(
///     interval: &IntervalLowerClosedUpperUnbounded<T>
/// ) {
///     // All operations compile to identical assembly for f64 and RealNative64StrictFiniteInDebug
///     let _lower = interval.lower_bound_value(); // O(1) field access
///     
///     // Point containment is a single comparison: x >= lower_bound
///     let test_value = T::zero();
///     let _contains = interval.contains_point(&test_value);
/// }
/// ```
///
/// ## Integration with Other Traits
///
/// ### Combined with [`IntervalTrait`]
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealScalar;
///
/// /// Generic function working with closed unbounded intervals
/// fn analyze_closed_unbounded_interval<I, T>(interval: &I) -> (T, bool, bool)
/// where
///     I: IntervalLowerBoundedUpperUnboundedTrait<RealType = T> + IntervalTrait<RealType = T>,
///     T: RealScalar + Clone,
/// {
///     let lower_bound = interval.lower_bound_value().clone();
///     let includes_lower = interval.contains_point(&lower_bound); // Should be true for closed
///     let contains_large_value = interval.contains_point(&T::try_from_f64(1000.0).unwrap());
///     
///     (lower_bound, includes_lower, contains_large_value)
/// }
///
/// let closed_interval = IntervalLowerClosedUpperUnbounded::new(5.0);
/// let open_interval = IntervalLowerOpenUpperUnbounded::new(5.0);
///
/// let (lower1, includes1, large1) = analyze_closed_unbounded_interval(&closed_interval);
/// let (lower2, includes2, large2) = analyze_closed_unbounded_interval(&open_interval);
///
/// assert_eq!(lower1, 5.0);
/// assert_eq!(lower2, 5.0);
/// assert!(includes1);   // [5, +∞) includes 5
/// assert!(!includes2);  // (5, +∞) excludes 5
/// assert!(large1);      // Both include large values
/// assert!(large2);
/// ```
///
/// ### With Constraint Systems
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealScalar;
///
/// /// Combine multiple inclusive lower constraints
/// fn combine_inclusive_lower_constraints<I1, I2, T>(
///     constraint1: &I1,
///     constraint2: &I2
/// ) -> Option<T>
/// where
///     I1: IntervalLowerBoundedUpperUnboundedTrait<RealType = T>,
///     I2: IntervalLowerBoundedUpperUnboundedTrait<RealType = T>,
///     T: RealScalar + PartialOrd + Clone,
/// {
///     let lower1 = constraint1.lower_bound_value();
///     let lower2 = constraint2.lower_bound_value();
///     
///     // The effective lower bound is the maximum of the two
///     if lower1 >= lower2 {
///         Some(lower1.clone())
///     } else {
///         Some(lower2.clone())
///     }
/// }
///
/// let constraint1 = IntervalLowerClosedUpperUnbounded::new(0.0);   // x ≥ 0
/// let constraint2 = IntervalLowerClosedUpperUnbounded::new(5.0);   // x ≥ 5
///
/// let combined_lower = combine_inclusive_lower_constraints(&constraint1, &constraint2).unwrap();
/// assert_eq!(combined_lower, 5.0);  // More restrictive constraint wins
/// ```
///
/// ## Best Practices and Recommendations
///
/// ### When to Use [`IntervalLowerClosedUpperUnbounded`]
/// - **"At least" constraints**: When you need `x ≥ a` (inclusive minimum)
/// - **Non-negative domains**: Mathematical functions defined for `x ≥ 0`
/// - **Asset pricing**: Financial models where prices cannot be negative
/// - **Growth processes**: Models starting from a specific included value
/// - **Cumulative functions**: Where the starting point should be included
/// - **Physical quantities**: Measurements with natural minimum values
///
/// ### When NOT to Use [`IntervalLowerClosedUpperUnbounded`]
/// - **Strict inequalities**: When you need `x > a`, use [`IntervalLowerOpenUpperUnbounded`]
/// - **Finite domains**: Use bounded intervals like [`IntervalClosed`](crate::intervals::bounded::IntervalClosed)
/// - **Upper limits**: When there's a maximum value, use bounded or upper-bounded intervals
/// - **Discrete domains**: Use appropriate discrete interval types
///
/// ### Recommended Patterns
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealNative64StrictFiniteInDebug;
/// use try_create::TryNew;
///
/// // Define type aliases for your application
/// type Real = RealNative64StrictFiniteInDebug;
/// type ClosedUnboundedInterval = IntervalLowerClosedUpperUnbounded<Real>;
///
/// // Pattern: Use for non-negative domains
/// fn create_non_negative_domain() -> ClosedUnboundedInterval {
///     ClosedUnboundedInterval::new(Real::try_new(0.0).unwrap())
/// }
///
/// // Pattern: Validate values against the constraint
/// fn validate_against_minimum<I>(interval: &I, value: &Real) -> bool
/// where
///     I: IntervalLowerBoundedUpperUnboundedTrait<RealType = Real> + IntervalTrait<RealType = Real>,
/// {
///     interval.contains_point(value)
/// }
///
/// // Pattern: Project values onto feasible region
/// fn project_to_feasible<I>(interval: &I, value: Real) -> Real
/// where
///     I: IntervalLowerBoundedUpperUnboundedTrait<RealType = Real>,
/// {
///     let lower_bound = interval.lower_bound_value();
///     if value >= *lower_bound {
///         value
///     } else {
///         lower_bound.clone()
///     }
/// }
/// ```
///
/// ## Common Use Cases
///
/// ### Mathematical Analysis
/// - **Function domains**: When functions are defined for `x ≥ a`
/// - **Optimization**: Feasible regions with inclusive lower bounds
/// - **Growth models**: Modeling processes that start from specific values
///
/// ### Financial Mathematics
/// - **Asset pricing**: Stock prices, bond values, commodity prices
/// - **Portfolio values**: Investment portfolios with limited liability
/// - **Interest rates**: Non-negative rate models
///
/// ### Physical Sciences
/// - **Temperature scales**: Absolute temperature (T ≥ 0 K)
/// - **Concentrations**: Chemical concentrations (c ≥ 0)
/// - **Distances**: Physical distances and lengths
///
/// ## Mathematical Properties and Guarantees
///
/// The [`IntervalLowerClosedUpperUnbounded`] struct maintains these mathematical properties:
///
/// - **Lower bound inclusion**: `lower_bound_value() ∈ interval` always holds
/// - **Infinite upper extent**: No finite upper bound exists
/// - **Inclusive inequality**: Point containment requires `x ≥ lower_bound`
/// - **Monotonicity**: If interval A has lower bound ≤ interval B's lower bound, then A ⊇ B
/// - **Translation invariance**: Shifting the lower bound preserves the closed unbounded structure
/// - **Intersection correctness**: Results follow standard interval arithmetic with proper boundary handling
///
/// These properties are preserved regardless of the scalar type used and are guaranteed
/// by the underlying implementations of the [`IntervalTrait`] and [`IntervalLowerBoundedUpperUnboundedTrait`].
pub type IntervalLowerClosedUpperUnbounded<RealType> =
    IntervalLowerBoundedUpperUnbounded<RealType, Closed>;

impl<RealType: RealScalar, LowerBoundType: BoundType>
    IntervalLowerBoundedUpperUnbounded<RealType, LowerBoundType>
{
    /// Creates a new interval with the specified lower bound and unbounded upper end.
    ///
    /// # Parameters
    ///
    /// - `lower_bound`: The finite lower bound of the interval. The boundary type
    ///   (open or closed) is determined by the `LowerBoundType` parameter.
    ///
    /// # Panics
    ///
    /// In debug builds, panics if `lower_bound` is not finite (i.e., if it's NaN or infinite).
    ///
    /// # Examples
    ///
    /// ```rust
    /// use grid1d::intervals::{IntervalLowerClosedUpperUnbounded, IntervalLowerOpenUpperUnbounded, Contains};
    ///
    /// let closed_unbounded = IntervalLowerClosedUpperUnbounded::new(0.0);
    /// let open_unbounded = IntervalLowerOpenUpperUnbounded::new(0.0);
    ///
    /// assert!(closed_unbounded.contains_point(&0.0));
    /// assert!(!open_unbounded.contains_point(&0.0));
    /// assert!(closed_unbounded.contains_point(&1e100));
    /// ```
    pub fn new(lower_bound: RealType) -> Self {
        debug_assert!(
            lower_bound.is_finite(),
            "Detected non-finite value: {lower_bound}!"
        );
        Self {
            lower_bound: LowerBound::<RealType, LowerBoundType>::new(lower_bound),
        }
    }
}

impl<RealType: RealScalar, LowerBoundType: BoundType> IntervalOperations
    for IntervalLowerBoundedUpperUnbounded<RealType, LowerBoundType>
where
    Self: IntervalBoundsRuntime<RealType = RealType>,
    LowerBound<RealType, LowerBoundType>: ValueWithinBound<RealType = RealType>,
{
}

impl<RealType: RealScalar, LowerBoundType: BoundType> Contains
    for IntervalLowerBoundedUpperUnbounded<RealType, LowerBoundType>
where
    Self: IntervalBoundsRuntime<RealType = RealType>,
    LowerBound<RealType, LowerBoundType>: ValueWithinBound<RealType = RealType>,
{
    /// Returns `true` if the 1D point/coordinate `x` is contained in the current **unbounded closed-left interval** `[a,+∞)`.
    #[inline(always)]
    fn contains_point(&self, x: &RealType) -> bool {
        self.lower_bound.value_within_bound(x)
    }
}

impl<RealType: RealScalar, LowerBoundType: BoundType> IntervalTrait
    for IntervalLowerBoundedUpperUnbounded<RealType, LowerBoundType>
where
    Self: IntervalBoundsRuntime<RealType = RealType>,
    LowerBound<RealType, LowerBoundType>: ValueWithinBound<RealType = RealType>,
{
}

impl<RealType: RealScalar, LowerBoundType: BoundType> IntervalLowerBoundedUpperUnboundedTrait
    for IntervalLowerBoundedUpperUnbounded<RealType, LowerBoundType>
where
    Self: IntervalBoundsRuntime<RealType = RealType>,
    LowerBound<RealType, LowerBoundType>: ValueWithinBound<RealType = RealType>,
{
}

//------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------
/// An upper bounded interval `(-∞, b]` extending from negative infinity with the upper endpoint included.
///
/// The [`IntervalLowerUnboundedUpperClosed`] represents intervals of the form `(-∞, b]` where the upper bound `b`
/// is part of the interval and the lower extent is infinite. This type of interval is fundamental
/// in mathematical analysis, particularly for "at most" constraints, capacity limits, cumulative
/// distribution functions from the left, and mathematical constructions where you need an inclusive
/// upper threshold while extending infinitely in the negative direction.
///
/// ## Mathematical Properties
///
/// - **Notation**: `(-∞, b]` or `]-∞, b]`
/// - **Definition**: `{x ∈ ℝ : x ≤ b}` where `b` is finite
/// - **Lower boundary**: Infinite (unbounded)
/// - **Upper boundary**: Included (closed)
/// - **Measure**: `+∞` (infinite length)
/// - **Topology**: Neither open nor closed (half-open, half-unbounded)
/// - **Cardinality**: Uncountably infinite points
/// - **Compactness**: Never compact (unbounded)
///
/// ## Use Cases
///
/// Lower unbounded, upper closed intervals are ideal when:
/// - **"At most" constraints**: Domains where `x ≤ b` (inclusive maximum)
/// - **Capacity limits**: Systems with maximum bounds but no minimum restrictions
/// - **Upper thresholds**: Mathematical functions with inclusive upper limits
/// - **Budget constraints**: Financial models with spending limits
/// - **Temperature limits**: Physical systems with maximum safe temperatures
/// - **Cumulative processes**: Where the endpoint represents an inclusive maximum
///
/// ## Comparison with Other Interval Types
///
/// | Property | `(-∞,b]` | `(-∞,b)` | `[a,+∞)` | `[a,b]` |
/// |----------|----------|----------|----------|---------|
/// | Contains `b` | ✓ | ✗ | N/A | ✓ |
/// | Contains values < `b` | ✓ | ✓ | Depends on `a` | ✓ |
/// | Length | `+∞` | `+∞` | `+∞` | `b - a` |
/// | Compactness | Never | Never | Never | Always |
/// | Lower bound | None | None | ✓ | ✓ |
/// | Upper bound achieved | ✓ | ✗ | N/A | ✓ |
/// | Supremum | `b` (achieved) | `b` (not achieved) | N/A | `b` (achieved) |
///
/// ## Construction
///
/// ### Safe Construction (Recommended)
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::RealNative64StrictFiniteInDebug;
/// use try_create::TryNew;
///
/// // Use the recommended performance-optimal type
/// type Real = RealNative64StrictFiniteInDebug;
///
/// // Create with validated scalar
/// let interval = IntervalLowerUnboundedUpperClosed::new(
///     Real::try_new(100.0).unwrap()
/// );
/// assert_eq!(interval.upper_bound_value(), &100.0);
/// ```
///
/// ### Raw Construction (Use with Caution)
/// ```rust
/// use grid1d::intervals::*;
///
/// // Direct construction with raw f64 - only when you trust your data
/// let interval = IntervalLowerUnboundedUpperClosed::new(50.0);
/// assert_eq!(interval.upper_bound_value(), &50.0);
/// ```
///
/// ## Key Operations
///
/// ### Point Containment (Lower Infinite, Upper Included)
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerUnboundedUpperClosed::new(10.0);  // (-∞, 10]
///
/// // Upper boundary is included
/// assert!(interval.contains_point(&10.0));    // Upper bound included
///
/// // All values below upper bound are included
/// assert!(interval.contains_point(&9.9));     // Just below upper bound
/// assert!(interval.contains_point(&0.0));     // Below upper bound
/// assert!(interval.contains_point(&-1000.0)); // Far below upper bound
///
/// // Values above upper bound are excluded
/// assert!(!interval.contains_point(&10.1));   // Above upper bound
/// assert!(!interval.contains_point(&100.0));  // Far above upper bound
/// ```
///
/// ### Boundary Behavior Analysis
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerUnboundedUpperClosed::new(0.0);  // (-∞, 0]
///
/// // Test boundary inclusion
/// assert!(interval.contains_point(&0.0));     // Upper bound included
///
/// // Test points near upper boundary
/// assert!(interval.contains_point(&-0.0001)); // Just below upper bound
/// assert!(!interval.contains_point(&0.0001)); // Just above upper bound
///
/// // Test large negative values (always included)
/// assert!(interval.contains_point(&-1e6));    // Very large negative value
/// assert!(interval.contains_point(&f64::MIN)); // Floating-point limits
/// ```
///
/// ### Accessing the Upper Bound
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerUnboundedUpperClosed::new(25.0);
///
/// // Access the finite upper bound
/// assert_eq!(interval.upper_bound_value(), &25.0);
///
/// // The upper bound itself is included in the interval
/// assert!(interval.contains_point(interval.upper_bound_value()));
///
/// // Values below the upper bound are included
/// assert!(interval.contains_point(&(25.0 - 1.0)));
/// ```
///
/// ## Interval Containment and Set Operations
///
/// ### Containment Testing
/// ```rust
/// use grid1d::intervals::*;
///
/// let outer = IntervalLowerUnboundedUpperClosed::new(100.0);  // (-∞, 100]
/// let inner = IntervalLowerUnboundedUpperClosed::new(50.0);   // (-∞, 50]
/// let boundary = IntervalLowerUnboundedUpperClosed::new(100.0); // (-∞, 100]
///
/// // Intervals with higher upper bounds can contain those with lower upper bounds
/// assert!(outer.contains_interval(&inner));           // (-∞, 100] ⊇ (-∞, 50] ✓
/// assert!(!inner.contains_interval(&outer));          // (-∞, 50] ⊉ (-∞, 100] ✗
///
/// // Same intervals contain themselves
/// assert!(outer.contains_interval(&boundary));        // (-∞, 100] ⊇ (-∞, 100] ✓
///
/// // Cross-type containment
/// let finite = IntervalClosed::new(-50.0, 100.0);             // [-50, 100]
/// let lower_bounded = IntervalLowerClosedUpperUnbounded::new(0.0); // [0, +∞)
/// let lower_open = IntervalLowerUnboundedUpperOpen::new(100.0);    // (-∞, 100)
///
/// assert!(outer.contains_interval(&finite));          // (-∞, 100] ⊇ [-50, 100] ✓
/// assert!(!outer.contains_interval(&lower_bounded));  // (-∞, 100] ⊉ [0, +∞) ✗
/// assert!(outer.contains_interval(&lower_open));      // (-∞, 100] ⊇ (-∞, 100) ✓
/// ```
///
/// ## Intersection Examples
///
/// ### Upper Bounded with Upper Bounded
/// ```rust
/// use grid1d::intervals::*;
///
/// let a = IntervalLowerUnboundedUpperClosed::new(100.0);  // (-∞, 100]
/// let b = IntervalLowerUnboundedUpperClosed::new(50.0);   // (-∞, 50]
///
/// if let Some(intersection) = a.intersection(&b) {
///     // Result: (-∞, 50] - takes the more restrictive (lower) upper bound
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperClosed(result)) => {
///             assert_eq!(result.upper_bound_value(), &50.0);
///         }
///         _ => unreachable!("Expected upper bounded interval"),
///     }
/// }
/// ```
///
/// ### Upper Bounded with Finite Intervals
/// ```rust
/// use grid1d::intervals::*;
///
/// let unbounded = IntervalLowerUnboundedUpperClosed::new(10.0);  // (-∞, 10]
/// let closed = IntervalClosed::new(5.0, 15.0);                   // [5, 15]
/// let open = IntervalOpen::new(-5.0, 8.0);                       // (-5, 8)
///
/// // Intersection of (-∞, 10] with [5, 15]
/// // Result: [5, 10]
/// if let Some(intersection) = unbounded.intersection(&closed) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(positive)) => {
///             assert_eq!(positive.length().into_inner(), 5.0); // 10 - 5 = 5
///         }
///         _ => unreachable!("Expected finite positive interval"),
///     }
/// }
///
/// // Intersection of (-∞, 10] with (-5, 8)
/// // Result: (-5, 8)
/// if let Some(intersection) = unbounded.intersection(&open) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(
///             IntervalFinitePositiveLength::Open(result)
///         )) => {
///             assert_eq!(result.lower_bound_value(), &-5.0);
///             assert_eq!(result.upper_bound_value(), &8.0);
///         }
///         _ => unreachable!("Expected open finite interval"),
///     }
/// }
/// ```
///
/// ### Upper Bounded with Other Unbounded Types
/// ```rust
/// use grid1d::intervals::*;
///
/// let upper_bounded = IntervalLowerUnboundedUpperClosed::new(10.0); // (-∞, 10]
/// let lower_bounded = IntervalLowerClosedUpperUnbounded::new(5.0);  // [5, +∞)
/// let upper_open = IntervalLowerUnboundedUpperOpen::new(15.0);      // (-∞, 15)
/// let fully_unbounded = IntervalInfiniteLength::LowerUnboundedUpperUnbounded(
///     IntervalLowerUnboundedUpperUnbounded::<f64>::new());          // (-∞, +∞)
///
/// // Intersection of (-∞, 10] with [5, +∞)
/// // Result: [5, 10]
/// if let Some(intersection) = upper_bounded.intersection(&lower_bounded) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(
///             IntervalFinitePositiveLength::Closed(result)
///         )) => {
///             assert_eq!(result.lower_bound_value(), &5.0);
///             assert_eq!(result.upper_bound_value(), &10.0);
///         }
///         _ => unreachable!("Expected closed finite interval"),
///     }
/// }
///
/// // Intersection of (-∞, 10] with (-∞, 15)
/// // Result: (-∞, 10]
/// if let Some(intersection) = upper_bounded.intersection(&upper_open) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperClosed(result)) => {
///             assert_eq!(result.upper_bound_value(), &10.0);
///         }
///         _ => unreachable!("Expected upper bounded interval"),
///     }
/// }
///
/// // Intersection of (-∞, 10] with (-∞, +∞)
/// // Result: (-∞, 10]
/// if let Some(intersection) = upper_bounded.intersection(&fully_unbounded) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperClosed(result)) => {
///             assert_eq!(result.upper_bound_value(), &10.0);
///         }
///         _ => unreachable!("Expected upper bounded interval"),
///     }
/// }
/// ```
///
/// ### Edge Cases: Boundary Cases
/// ```rust
/// use grid1d::intervals::*;
///
/// let non_positive = IntervalLowerUnboundedUpperClosed::new(0.0);     // (-∞, 0]
/// let positive = IntervalLowerClosedUpperUnbounded::new(0.0);         // [0, +∞)
/// let negative = IntervalLowerUnboundedUpperOpen::new(0.0);           // (-∞, 0)
/// let at_boundary = IntervalLowerOpenUpperUnbounded::new(0.0);        // (0, +∞)
///
/// // Intersection at boundary point
/// if let Some(intersection) = non_positive.intersection(&positive) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::ZeroLength(singleton)) => {
///             assert_eq!(singleton.value(), &0.0);
///         }
///         _ => unreachable!("Expected singleton intersection"),
///     }
/// }
///
/// // Disjoint intervals
/// assert!(non_positive.intersection(&negative).is_some()); // (-∞, 0] ∩ (-∞, 0) = (-∞, 0)
/// assert!(non_positive.intersection(&at_boundary).is_none()); // (-∞, 0] ∩ (0, +∞) = ∅
/// ```
///
/// ## Advanced Usage Patterns
///
/// ### Capacity and Resource Modeling
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents a system with maximum capacity constraints
/// struct CapacityConstraint {
///     valid_range: IntervalLowerUnboundedUpperClosed<f64>
/// }
///
/// impl CapacityConstraint {
///     fn new(max_capacity: f64) -> Self {
///         Self {
///             valid_range: IntervalLowerUnboundedUpperClosed::new(max_capacity)
///         }
///     }
///     
///     /// Check if a demand is within capacity
///     fn can_handle_demand(&self, demand: f64) -> bool {
///         self.valid_range.contains_point(&demand)
///     }
///     
///     /// Get the maximum capacity
///     fn max_capacity(&self) -> f64 {
///         *self.valid_range.upper_bound_value()
///     }
///     
///     /// Calculate spare capacity
///     fn spare_capacity(&self, current_demand: f64) -> Option<f64> {
///         if self.can_handle_demand(current_demand) {
///             Some(self.max_capacity() - current_demand)
///         } else {
///             None // Demand exceeds capacity
///         }
///     }
///     
///     /// Project demand onto feasible region
///     fn project_demand(&self, demand: f64) -> f64 {
///         demand.min(self.max_capacity())
///     }
/// }
///
/// let capacity = CapacityConstraint::new(1000.0);  // Max capacity 1000 units
///
/// assert!(capacity.can_handle_demand(800.0));    // 800 ≤ 1000
/// assert!(capacity.can_handle_demand(1000.0));   // Exactly at capacity
/// assert!(!capacity.can_handle_demand(1200.0));  // Exceeds capacity
/// assert!(capacity.can_handle_demand(-100.0));   // Negative demand is allowed
///
/// assert_eq!(capacity.spare_capacity(700.0), Some(300.0)); // 1000 - 700 = 300
/// assert_eq!(capacity.spare_capacity(1200.0), None);       // Over capacity
/// assert_eq!(capacity.max_capacity(), 1000.0);
/// assert_eq!(capacity.project_demand(1200.0), 1000.0);     // Clamped to max
/// ```
///
/// ### Budget and Financial Constraints
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Models a budget constraint with maximum spending limit
/// struct BudgetLimit {
///     affordable_range: IntervalLowerUnboundedUpperClosed<f64>
/// }
///
/// impl BudgetLimit {
///     fn new(budget_limit: f64) -> Self {
///         Self {
///             affordable_range: IntervalLowerUnboundedUpperClosed::new(budget_limit)
///         }
///     }
///     
///     /// Check if an expense is within budget
///     fn is_affordable(&self, expense: f64) -> bool {
///         self.affordable_range.contains_point(&expense)
///     }
///     
///     /// Get the budget limit
///     fn budget_limit(&self) -> f64 {
///         *self.affordable_range.upper_bound_value()
///     }
///     
///     /// Calculate remaining budget after expenses
///     fn remaining_budget(&self, total_expenses: f64) -> f64 {
///         (self.budget_limit() - total_expenses).max(0.0)
///     }
///     
///     /// Check if additional expense fits in budget
///     fn can_afford_additional(&self, current_expenses: f64, additional_expense: f64) -> bool {
///         let total = current_expenses + additional_expense;
///         self.is_affordable(total)
///     }
/// }
///
/// let budget = BudgetLimit::new(5000.0);  // Budget limit $5000
///
/// assert!(budget.is_affordable(4500.0));   // $4500 ≤ $5000
/// assert!(budget.is_affordable(5000.0));   // Exactly at budget limit
/// assert!(!budget.is_affordable(5500.0));  // Exceeds budget
/// assert!(budget.is_affordable(-100.0));   // Income/refunds allowed
///
/// assert_eq!(budget.remaining_budget(3000.0), 2000.0); // $5000 - $3000 = $2000
/// assert_eq!(budget.remaining_budget(6000.0), 0.0);    // Over budget, no remaining
/// assert!(budget.can_afford_additional(4000.0, 500.0)); // $4000 + $500 ≤ $5000
/// assert!(!budget.can_afford_additional(4000.0, 1500.0)); // $4000 + $1500 > $5000
/// ```
///
/// ### Temperature and Safety Limits
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Models a temperature safety constraint
/// struct TemperatureSafetyLimit {
///     safe_range: IntervalLowerUnboundedUpperClosed<f64>
/// }
///
/// impl TemperatureSafetyLimit {
///     fn new(max_safe_temperature: f64) -> Self {
///         Self {
///             safe_range: IntervalLowerUnboundedUpperClosed::new(max_safe_temperature)
///         }
///     }
///     
///     /// Check if temperature is within safe limits
///     fn is_safe(&self, temperature: f64) -> bool {
///         self.safe_range.contains_point(&temperature)
///     }
///     
///     /// Get the maximum safe temperature
///     fn max_safe_temperature(&self) -> f64 {
///         *self.safe_range.upper_bound_value()
///     }
///     
///     /// Calculate safety margin
///     fn safety_margin(&self, current_temperature: f64) -> f64 {
///         self.max_safe_temperature() - current_temperature
///     }
///     
///     /// Check if temperature increase is safe
///     fn safe_to_increase(&self, current_temp: f64, increase: f64) -> bool {
///         let new_temp = current_temp + increase;
///         self.is_safe(new_temp)
///     }
/// }
///
/// let temp_limit = TemperatureSafetyLimit::new(85.0);  // Max safe: 85°C
///
/// assert!(temp_limit.is_safe(70.0));     // 70°C is safe
/// assert!(temp_limit.is_safe(85.0));     // Exactly at limit
/// assert!(!temp_limit.is_safe(90.0));    // Exceeds safe limit
/// assert!(temp_limit.is_safe(-20.0));    // Cold temperatures are safe
///
/// assert_eq!(temp_limit.safety_margin(80.0), 5.0);     // 85 - 80 = 5°C margin
/// assert_eq!(temp_limit.safety_margin(90.0), -5.0);    // Over limit by 5°C
/// assert!(temp_limit.safe_to_increase(75.0, 5.0));     // 75 + 5 = 80 ≤ 85
/// assert!(!temp_limit.safe_to_increase(75.0, 15.0));   // 75 + 15 = 90 > 85
/// ```
///
/// ### Probability Theory: Distribution Support
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents a distribution with upper bounded support
/// struct UpperBoundedDistribution {
///     support: IntervalLowerUnboundedUpperClosed<f64>,
///     scale_parameter: f64,
/// }
///
/// impl UpperBoundedDistribution {
///     fn new(max_value: f64, scale: f64) -> Self {
///         Self {
///             support: IntervalLowerUnboundedUpperClosed::new(max_value),
///             scale_parameter: scale,
///         }
///     }
///     
///     /// Probability density function (simplified example)
///     fn pdf(&self, x: f64) -> f64 {
///         if self.support.contains_point(&x) {
///             let max_val = *self.support.upper_bound_value();
///             // Simplified triangular-like distribution
///             let normalized = (max_val - x) / max_val;
///             normalized / self.scale_parameter
///         } else {
///             0.0 // Outside support
///         }
///     }
///     
///     /// Cumulative distribution function
///     fn cdf(&self, x: f64) -> f64 {
///         let max_val = *self.support.upper_bound_value();
///         if x >= max_val {
///             1.0
///         } else if self.support.contains_point(&x) {
///             // Simplified: assume linear growth
///             (x - (max_val - 2.0 * self.scale_parameter)).max(0.0) / (2.0 * self.scale_parameter)
///         } else {
///             0.0
///         }
///     }
///     
///     /// Check if value is in distribution support
///     fn in_support(&self, x: f64) -> bool {
///         self.support.contains_point(&x)
///     }
///     
///     /// Get maximum value
///     fn max_value(&self) -> f64 {
///         *self.support.upper_bound_value()
///     }
/// }
///
/// let dist = UpperBoundedDistribution::new(10.0, 2.0);
///
/// assert!(dist.in_support(5.0));     // Within support
/// assert!(dist.in_support(10.0));    // At maximum (included)
/// assert!(!dist.in_support(15.0));   // Above maximum
/// assert!(dist.in_support(-100.0));  // No lower bound
///
/// assert_eq!(dist.max_value(), 10.0);
/// assert!(dist.pdf(5.0) > 0.0);      // Positive density in support
/// assert_eq!(dist.pdf(15.0), 0.0);   // Zero density outside support
/// assert_eq!(dist.cdf(10.0), 1.0);   // CDF = 1 at maximum
/// ```
///
/// ## Performance Characteristics
///
/// ### Memory Layout
/// - **Storage**: Single scalar value for the upper bound (8 bytes for f64)
/// - **Alignment**: Natural alignment of the scalar type
/// - **No heap allocation**: All data stored inline
/// - **Compact representation**: Most memory-efficient for semi-infinite intervals
///
/// ### Operation Complexity
/// | Operation | Time Complexity | Space Complexity | Notes |
/// |-----------|----------------|------------------|-------|
/// | [`upper_bound_value`](IntervalLowerUnboundedUpperClosed::upper_bound_value) | O(1) | O(1) | Direct field access |
/// | Point containment | O(1) | O(1) | Single comparison (`x ≤ upper_bound`) |
/// | Interval operations | O(1) | O(1) | Efficient boundary logic |
/// | Construction | O(1) | O(1) | Single validation check in debug mode |
///
/// ### Scalar Type Performance Impact
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::{RealNative64StrictFiniteInDebug, RealNative64StrictFinite, RealScalar};
///
/// // These have identical performance in release builds:
/// type FastUpperBounded = IntervalLowerUnboundedUpperClosed<f64>;
/// type OptimalUpperBounded = IntervalLowerUnboundedUpperClosed<RealNative64StrictFiniteInDebug>;
///
/// // This has small validation overhead:
/// type SafeUpperBounded = IntervalLowerUnboundedUpperClosed<RealNative64StrictFinite>;
///
/// // Performance test function (generic over any upper bounded interval)
/// fn benchmark_upper_bounded_operations<T: RealScalar + Clone>(
///     interval: &IntervalLowerUnboundedUpperClosed<T>
/// ) {
///     // All operations compile to identical assembly for f64 and RealNative64StrictFiniteInDebug
///     let _upper = interval.upper_bound_value(); // O(1) field access
///     
///     // Point containment is a single comparison: x <= upper_bound
///     let test_value = T::zero();
///     let _contains = interval.contains_point(&test_value);
/// }
/// ```
///
/// ## Integration with Other Traits
///
/// ### Combined with [`IntervalTrait`]
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealScalar;
///
/// /// Generic function working with upper bounded intervals
/// fn analyze_upper_bounded_interval<I, T>(interval: &I) -> (T, bool, bool)
/// where
///     I: IntervalLowerUnboundedUpperBoundedTrait<RealType = T> + IntervalTrait<RealType = T>,
///     T: RealScalar + Clone,
/// {
///     let upper_bound = interval.upper_bound_value().clone();
///     let includes_upper = interval.contains_point(&upper_bound); // Should be true for closed
///     let contains_large_negative = interval.contains_point(&T::try_from_f64(-1000.0).unwrap());
///     
///     (upper_bound, includes_upper, contains_large_negative)
/// }
///
/// let closed_interval = IntervalLowerUnboundedUpperClosed::new(5.0);
/// let open_interval = IntervalLowerUnboundedUpperOpen::new(5.0);
///
/// let (upper1, includes1, negative1) = analyze_upper_bounded_interval(&closed_interval);
/// let (upper2, includes2, negative2) = analyze_upper_bounded_interval(&open_interval);
///
/// assert_eq!(upper1, 5.0);
/// assert_eq!(upper2, 5.0);
/// assert!(includes1);   // (-∞, 5] includes 5
/// assert!(!includes2);  // (-∞, 5) excludes 5
/// assert!(negative1);   // Both include large negative values
/// assert!(negative2);
/// ```
///
/// ### With Constraint Systems
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealScalar;
///
/// /// Combine multiple upper bounded constraints
/// fn combine_upper_constraints<I1, I2, T>(
///     constraint1: &I1,
///     constraint2: &I2
/// ) -> Option<T>
/// where
///     I1: IntervalLowerUnboundedUpperBoundedTrait<RealType = T>,
///     I2: IntervalLowerUnboundedUpperBoundedTrait<RealType = T>,
///     T: RealScalar + PartialOrd + Clone,
/// {
///     let upper1 = constraint1.upper_bound_value();
///     let upper2 = constraint2.upper_bound_value();
///     
///     // The effective upper bound is the minimum of the two
///     if upper1 <= upper2 {
///         Some(upper1.clone())
///     } else {
///         Some(upper2.clone())
///     }
/// }
///
/// let constraint1 = IntervalLowerUnboundedUpperClosed::new(100.0);  // x ≤ 100
/// let constraint2 = IntervalLowerUnboundedUpperClosed::new(50.0);   // x ≤ 50
///
/// let combined_upper = combine_upper_constraints(&constraint1, &constraint2).unwrap();
/// assert_eq!(combined_upper, 50.0);  // More restrictive constraint wins
/// ```
///
/// ## Best Practices and Recommendations
///
/// ### When to Use [`IntervalLowerUnboundedUpperClosed`]
/// - **"At most" constraints**: When you need `x ≤ b` (inclusive maximum)
/// - **Capacity modeling**: Systems with maximum limits but no minimum restrictions
/// - **Budget constraints**: Financial models with spending limits
/// - **Safety thresholds**: Physical systems with maximum safe operating parameters
/// - **Resource management**: When modeling limited resources or capacity
/// - **Temperature controls**: Systems with maximum temperature limits
///
/// ### When NOT to Use [`IntervalLowerUnboundedUpperClosed`]
/// - **Strict inequalities**: When you need `x < b`, use [`IntervalLowerUnboundedUpperOpen`]
/// - **Physical measurements**: Real-world quantities often have natural lower bounds
/// - **Probability ranges**: Probabilities typically have both lower (0) and upper (1) bounds
/// - **Finite domains**: Use bounded intervals when both limits are known
///
/// ### Recommended Patterns
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealNative64StrictFiniteInDebug;
/// use try_create::TryNew;
///
/// // Define type aliases for your application
/// type Real = RealNative64StrictFiniteInDebug;
/// type UpperBoundedInterval = IntervalLowerUnboundedUpperClosed<Real>;
///
/// // Pattern: Use for capacity and limit modeling
/// fn create_capacity_limit(max_capacity: Real) -> UpperBoundedInterval {
///     UpperBoundedInterval::new(max_capacity)
/// }
///
/// // Pattern: Validate values against the constraint
/// fn validate_against_maximum<I>(interval: &I, value: &Real) -> bool
/// where
///     I: IntervalLowerUnboundedUpperBoundedTrait<RealType = Real> + IntervalTrait<RealType = Real>,
/// {
///     interval.contains_point(value)
/// }
///
/// // Pattern: Project values onto feasible region
/// fn project_to_feasible<I>(interval: &I, value: Real) -> Real
/// where
///     I: IntervalLowerUnboundedUpperBoundedTrait<RealType = Real>,
/// {
///     let upper_bound = interval.upper_bound_value();
///     if value <= *upper_bound {
///         value
///     } else {
///         upper_bound.clone()
///     }
/// }
/// ```
///
/// ## Common Use Cases
///
/// ### Resource Management and Capacity Planning
/// - **Memory limits**: Maximum memory usage constraints
/// - **Bandwidth caps**: Maximum data transfer rates
/// - **Storage limits**: Maximum storage capacity constraints
///
/// ### Financial and Economic Modeling
/// - **Budget constraints**: Maximum spending limits
/// - **Credit limits**: Maximum borrowing capacity
/// - **Investment caps**: Maximum investment amounts
///
/// ### Engineering and Safety Systems
/// - **Safety margins**: Maximum safe operating parameters
/// - **Load limits**: Maximum structural loads
/// - **Temperature limits**: Maximum operating temperatures
///
/// ## Mathematical Properties and Guarantees
///
/// The [`IntervalLowerUnboundedUpperClosed`] struct maintains these mathematical properties:
///
/// - **Upper bound inclusion**: `upper_bound_value() ∈ interval` always holds
/// - **Infinite lower extent**: No finite lower bound exists
/// - **Inclusive inequality**: Point containment requires `x ≤ upper_bound`
/// - **Monotonicity**: If interval A has upper bound ≥ interval B's upper bound, then A ⊇ B
/// - **Translation invariance**: Shifting the upper bound preserves the unbounded closed structure
/// - **Intersection correctness**: Results follow standard interval arithmetic with proper boundary handling
///
/// These properties are preserved regardless of the scalar type used and are guaranteed
/// by the underlying implementations of the [`IntervalTrait`] and [`IntervalLowerUnboundedUpperBoundedTrait`].
pub type IntervalLowerUnboundedUpperClosed<RealType> =
    IntervalLowerUnboundedUpperBounded<RealType, Closed>;

impl<RealType: RealScalar, UpperBoundType: BoundType>
    IntervalLowerUnboundedUpperBounded<RealType, UpperBoundType>
{
    /// Build and return a new instance of [`IntervalLowerUnboundedUpperBounded`] from the upper bound of the interval.
    pub fn new(upper_bound: RealType) -> Self {
        debug_assert!(
            upper_bound.is_finite(),
            "Detected non-finite value: {upper_bound}!"
        );
        Self {
            upper_bound: UpperBound::<RealType, UpperBoundType>::new(upper_bound),
        }
    }
}

impl<RealType: RealScalar, UpperBoundType: BoundType> IntervalOperations
    for IntervalLowerUnboundedUpperBounded<RealType, UpperBoundType>
where
    Self: IntervalBoundsRuntime<RealType = RealType>,
    UpperBound<RealType, UpperBoundType>: ValueWithinBound<RealType = RealType>,
{
}

impl<RealType: RealScalar, UpperBoundType: BoundType> Contains
    for IntervalLowerUnboundedUpperBounded<RealType, UpperBoundType>
where
    Self: IntervalBoundsRuntime<RealType = RealType>,
    UpperBound<RealType, UpperBoundType>: ValueWithinBound<RealType = RealType>,
{
    #[inline(always)]
    fn contains_point(&self, x: &RealType) -> bool {
        self.upper_bound.value_within_bound(x)
    }
}

impl<RealType: RealScalar, UpperBoundType: BoundType> IntervalTrait
    for IntervalLowerUnboundedUpperBounded<RealType, UpperBoundType>
where
    Self: IntervalBoundsRuntime<RealType = RealType>,
    UpperBound<RealType, UpperBoundType>: ValueWithinBound<RealType = RealType>,
{
}
//------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------
/// An unbounded open-right interval `(-∞, b)` extending from negative infinity with the upper endpoint excluded.
///
/// The [`IntervalLowerUnboundedUpperOpen`] represents intervals of the form `(-∞, b)` where the upper bound `b`
/// is not part of the interval and the lower extent is infinite. This type of interval is fundamental
/// in mathematical analysis, particularly for strict "less than" constraints, limit approaches from below,
/// and mathematical constructions where you need to exclude the target value while extending infinitely
/// in the negative direction.
///
/// ## Mathematical Properties
///
/// - **Notation**: `(-∞, b)` or `]-∞, b[`
/// - **Definition**: `{x ∈ ℝ : x < b}` where `b` is finite
/// - **Lower boundary**: Infinite (unbounded)
/// - **Upper boundary**: Excluded (open)
/// - **Measure**: `+∞` (infinite length)
/// - **Topology**: Neither open nor closed (half-open, half-unbounded)
/// - **Cardinality**: Uncountably infinite points
/// - **Compactness**: Never compact (unbounded)
///
/// ## Use Cases
///
/// Lower unbounded, upper open intervals are ideal when:
/// - **Strict "less than" constraints**: Domains where `x < b` but not `x ≤ b`
/// - **Approach limits**: Where values approach but never reach the upper bound
/// - **Convergence criteria**: Mathematical analysis where the limit point is excluded
/// - **Optimization**: Strict upper bound constraints without lower limits
/// - **Asymptotic behavior**: Functions with vertical asymptotes at the upper bound
/// - **Mathematical analysis**: When the upper bound represents a singularity or discontinuity
///
/// ## Comparison with Other Interval Types
///
/// | Property | `(-∞,b)` | `(-∞,b]` | `[a,+∞)` | `[a,b]` |
/// |----------|----------|----------|----------|---------|
/// | Contains `b` | ✗ | ✓ | N/A | ✓ |
/// | Contains values < `b` | ✓ | ✓ | Depends on `a` | ✓ |
/// | Length | `+∞` | `+∞` | `+∞` | `b - a` |
/// | Compactness | Never | Never | Never | Always |
/// | Lower bound | None | None | ✓ | ✓ |
/// | Upper bound achieved | ✗ | ✓ | N/A | ✓ |
/// | Supremum | `b` (not achieved) | `b` (achieved) | N/A | `b` (achieved) |
///
/// ## Construction
///
/// ### Safe Construction (Recommended)
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::RealNative64StrictFiniteInDebug;
/// use try_create::TryNew;
///
/// // Use the recommended performance-optimal type
/// type Real = RealNative64StrictFiniteInDebug;
///
/// // Create with validated scalar
/// let interval = IntervalLowerUnboundedUpperOpen::new(
///     Real::try_new(100.0).unwrap()
/// );
/// assert_eq!(interval.upper_bound_value(), &100.0);
/// ```
///
/// ### Raw Construction (Use with Caution)
/// ```rust
/// use grid1d::intervals::*;
///
/// // Direct construction with raw f64 - only when you trust your data
/// let interval = IntervalLowerUnboundedUpperOpen::new(50.0);
/// assert_eq!(interval.upper_bound_value(), &50.0);
/// ```
///
/// ## Key Operations
///
/// ### Point Containment (Lower Infinite, Upper Excluded)
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerUnboundedUpperOpen::new(10.0);  // (-∞, 10)
///
/// // Upper boundary is excluded
/// assert!(!interval.contains_point(&10.0));   // Upper bound excluded
///
/// // All values below upper bound are included
/// assert!(interval.contains_point(&9.9));     // Just below upper bound
/// assert!(interval.contains_point(&0.0));     // Below upper bound
/// assert!(interval.contains_point(&-1000.0)); // Far below upper bound
///
/// // Values above upper bound are excluded
/// assert!(!interval.contains_point(&10.1));   // Above upper bound
/// assert!(!interval.contains_point(&100.0));  // Far above upper bound
/// ```
///
/// ### Boundary Behavior Analysis
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerUnboundedUpperOpen::new(0.0);  // (-∞, 0)
///
/// // Test boundary exclusion
/// assert!(!interval.contains_point(&0.0));    // Upper bound excluded
///
/// // Test points near upper boundary
/// assert!(interval.contains_point(&-0.0001)); // Just below upper bound
/// assert!(!interval.contains_point(&0.0001)); // Just above upper bound
///
/// // Test large negative values (always included)
/// assert!(interval.contains_point(&-1e6));    // Very large negative value
/// assert!(interval.contains_point(&f64::NEG_INFINITY)); // Conceptually included
/// ```
///
/// ### Accessing the Upper Bound
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerUnboundedUpperOpen::new(25.0);
///
/// // Access the finite upper bound
/// assert_eq!(interval.upper_bound_value(), &25.0);
///
/// // The upper bound itself is not included in the interval
/// assert!(!interval.contains_point(interval.upper_bound_value()));
///
/// // Values below the upper bound are included
/// assert!(interval.contains_point(&(25.0 - 1.0)));
/// ```
///
/// ## Interval Containment and Set Operations
///
/// ### Containment Testing
/// ```rust
/// use grid1d::intervals::*;
///
/// let outer = IntervalLowerUnboundedUpperOpen::new(100.0);  // (-∞, 100)
/// let inner = IntervalLowerUnboundedUpperOpen::new(50.0);   // (-∞, 50)
/// let boundary = IntervalLowerUnboundedUpperOpen::new(100.0); // (-∞, 100)
///
/// // Intervals with higher upper bounds can contain those with lower upper bounds
/// assert!(outer.contains_interval(&inner));           // (-∞, 100) ⊇ (-∞, 50) ✓
/// assert!(!inner.contains_interval(&outer));          // (-∞, 50) ⊉ (-∞, 100) ✗
///
/// // Same intervals contain themselves
/// assert!(outer.contains_interval(&boundary));        // (-∞, 100) ⊇ (-∞, 100) ✓
///
/// // Cross-type containment
/// let finite = IntervalClosed::new(-50.0, 99.0);              // [-50, 99]
/// let lower_bounded = IntervalLowerClosedUpperUnbounded::new(0.0); // [0, +∞)
/// let upper_closed = IntervalLowerUnboundedUpperClosed::new(100.0); // (-∞, 100]
///
/// assert!(outer.contains_interval(&finite));          // (-∞, 100) ⊇ [-50, 99] ✓
/// assert!(!outer.contains_interval(&lower_bounded));  // (-∞, 100) ⊉ [0, +∞) ✗
/// assert!(!outer.contains_interval(&upper_closed));   // (-∞, 100) ⊉ (-∞, 100] ✗ (boundary)
/// assert!(upper_closed.contains_interval(&outer));    // (-∞, 100] ⊇ (-∞, 100) ✓
/// ```
///
/// ## Intersection Examples
///
/// ### Upper Open with Upper Open
/// ```rust
/// use grid1d::intervals::*;
///
/// let a = IntervalLowerUnboundedUpperOpen::new(100.0);  // (-∞, 100)
/// let b = IntervalLowerUnboundedUpperOpen::new(50.0);   // (-∞, 50)
///
/// if let Some(intersection) = a.intersection(&b) {
///     // Result: (-∞, 50) - takes the more restrictive (lower) upper bound
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperOpen(result)) => {
///             assert_eq!(result.upper_bound_value(), &50.0);
///         }
///         _ => unreachable!("Expected upper open interval"),
///     }
/// }
/// ```
///
/// ### Upper Open with Finite Intervals
/// ```rust
/// use grid1d::intervals::*;
///
/// let unbounded = IntervalLowerUnboundedUpperOpen::new(10.0);  // (-∞, 10)
/// let closed = IntervalClosed::new(5.0, 15.0);                // [5, 15]
/// let open = IntervalOpen::new(-5.0, 8.0);                    // (-5, 8)
///
/// // Intersection of (-∞, 10) with [5, 15]
/// // Result: [5, 10)
/// if let Some(intersection) = unbounded.intersection(&closed) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(positive)) => {
///             assert_eq!(positive.length().into_inner(), 5.0); // 10 - 5 = 5
///         }
///         _ => unreachable!("Expected finite positive interval"),
///     }
/// }
///
/// // Intersection of (-∞, 10) with (-5, 8)
/// // Result: (-5, 8)
/// if let Some(intersection) = unbounded.intersection(&open) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(
///             IntervalFinitePositiveLength::Open(result)
///         )) => {
///             assert_eq!(result.lower_bound_value(), &-5.0);
///             assert_eq!(result.upper_bound_value(), &8.0);
///         }
///         _ => unreachable!("Expected open finite interval"),
///     }
/// }
/// ```
///
/// ### Upper Open with Other Unbounded Types
/// ```rust
/// use grid1d::intervals::*;
///
/// let upper_open = IntervalLowerUnboundedUpperOpen::new(10.0);      // (-∞, 10)
/// let lower_bounded = IntervalLowerClosedUpperUnbounded::new(5.0);  // [5, +∞)
/// let upper_closed = IntervalLowerUnboundedUpperClosed::new(15.0);  // (-∞, 15]
/// let fully_unbounded = IntervalInfiniteLength::LowerUnboundedUpperUnbounded(
///     IntervalLowerUnboundedUpperUnbounded::<f64>::new());          // (-∞, +∞)
///
/// // Intersection of (-∞, 10) with [5, +∞)
/// // Result: [5, 10)
/// if let Some(intersection) = upper_open.intersection(&lower_bounded) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(
///             IntervalFinitePositiveLength::LowerClosedUpperOpen(result)
///         )) => {
///             assert_eq!(result.lower_bound_value(), &5.0);
///             assert_eq!(result.upper_bound_value(), &10.0);
///         }
///         _ => unreachable!("Expected left-closed right-open finite interval"),
///     }
/// }
///
/// // Intersection of (-∞, 10) with (-∞, 15]
/// // Result: (-∞, 10)
/// if let Some(intersection) = upper_open.intersection(&upper_closed) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperOpen(result)) => {
///             assert_eq!(result.upper_bound_value(), &10.0);
///         }
///         _ => unreachable!("Expected upper open interval"),
///     }
/// }
///
/// // Intersection of (-∞, 10) with (-∞, +∞)
/// // Result: (-∞, 10)
/// if let Some(intersection) = upper_open.intersection(&fully_unbounded) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperOpen(result)) => {
///             assert_eq!(result.upper_bound_value(), &10.0);
///         }
///         _ => unreachable!("Expected upper open interval"),
///     }
/// }
/// ```
///
/// ### Edge Cases: Disjoint and Boundary Cases
/// ```rust
/// use grid1d::intervals::*;
///
/// let negative_open = IntervalLowerUnboundedUpperOpen::new(0.0);     // (-∞, 0)
/// let positive = IntervalLowerClosedUpperUnbounded::new(0.0);        // [0, +∞)
/// let negative_closed = IntervalLowerUnboundedUpperClosed::new(0.0); // (-∞, 0]
/// let positive_open = IntervalLowerOpenUpperUnbounded::new(0.0);     // (0, +∞)
///
/// // Disjoint intervals
/// assert!(negative_open.intersection(&positive).is_none());      // (-∞, 0) ∩ [0, +∞) = ∅
/// assert!(negative_open.intersection(&positive_open).is_none()); // (-∞, 0) ∩ (0, +∞) = ∅
///
/// // Boundary touching with singleton intersection
/// if let Some(intersection) = negative_open.intersection(&negative_closed) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerUnboundedUpperOpen(result)) => {
///             assert_eq!(result.upper_bound_value(), &0.0);
///         }
///         _ => unreachable!("Expected (-∞, 0) as intersection of (-∞, 0) and (-∞, 0]"),
///     }
/// }
/// ```
///
/// ## Advanced Usage Patterns
///
/// ### Asymptotic Analysis and Limit Behavior
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents a function's domain approaching an asymptote from below
/// struct AsymptoticBehaviorFromBelow {
///     domain: IntervalLowerUnboundedUpperOpen<f64>,
///     asymptote_location: f64,
/// }
///
/// impl AsymptoticBehaviorFromBelow {
///     fn new(asymptote_at: f64) -> Self {
///         Self {
///             domain: IntervalLowerUnboundedUpperOpen::new(asymptote_at),
///             asymptote_location: asymptote_at,
///         }
///     }
///     
///     /// Check if a value is in the function's domain
///     fn is_defined_at(&self, x: f64) -> bool {
///         self.domain.contains_point(&x)
///     }
///     
///     /// Evaluate function: f(x) = 1/(asymptote - x) for x < asymptote
///     fn evaluate(&self, x: f64) -> Option<f64> {
///         if self.is_defined_at(x) {
///             Some(1.0 / (self.asymptote_location - x))
///         } else {
///             None // Undefined at or above asymptote
///         }
///     }
///     
///     /// Check distance from asymptote (always positive for valid inputs)
///     fn distance_from_asymptote(&self, x: f64) -> Option<f64> {
///         if self.is_defined_at(x) {
///             Some(self.asymptote_location - x)
///         } else {
///             None
///         }
///     }
/// }
///
/// let func = AsymptoticBehaviorFromBelow::new(0.0);  // f(x) = 1/(0 - x) = -1/x for x < 0
///
/// assert!(!func.is_defined_at(0.0));       // Undefined at asymptote
/// assert!(!func.is_defined_at(1.0));       // Undefined for positive values
/// assert!(func.is_defined_at(-0.1));       // Defined for negative values
///
/// assert_eq!(func.evaluate(-1.0), Some(1.0));         // f(-1) = -1/(-1) = 1
/// assert_eq!(func.evaluate(-0.5), Some(2.0));         // f(-0.5) = -1/(-0.5) = 2
/// assert_eq!(func.evaluate(0.0), None);               // Undefined
/// assert_eq!(func.distance_from_asymptote(-0.1), Some(0.1)); // Distance = 0 - (-0.1) = 0.1
/// ```
///
/// ### Optimization with Strict Upper Bounds
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Optimization problem with strict upper bound constraint
/// struct StrictUpperBoundOptimization {
///     feasible_region: IntervalLowerUnboundedUpperOpen<f64>
/// }
///
/// impl StrictUpperBoundOptimization {
///     /// Create optimization problem: minimize f(x) subject to x < upper_bound
///     fn new(strict_upper_bound: f64) -> Self {
///         Self {
///             feasible_region: IntervalLowerUnboundedUpperOpen::new(strict_upper_bound)
///         }
///     }
///     
///     /// Check if a point satisfies the strict constraint
///     fn is_feasible(&self, x: f64) -> bool {
///         self.feasible_region.contains_point(&x)
///     }
///     
///     /// Get the constraint boundary (not included in feasible region)
///     fn constraint_boundary(&self) -> f64 {
///         *self.feasible_region.upper_bound_value()
///     }
///     
///     /// Objective function: f(x) = (x - boundary)²
///     fn objective(&self, x: f64) -> Option<f64> {
///         if self.is_feasible(x) {
///             let boundary = self.constraint_boundary();
///             Some((x - boundary).powi(2))
///         } else {
///             None // Infeasible point
///         }
///     }
///     
///     /// Find a feasible point (boundary - epsilon)
///     fn get_feasible_point(&self, epsilon: f64) -> f64 {
///         self.constraint_boundary() - epsilon.abs()
///     }
/// }
///
/// let optimizer = StrictUpperBoundOptimization::new(10.0);  // x < 10
///
/// assert!(!optimizer.is_feasible(10.0));     // Boundary point not feasible
/// assert!(!optimizer.is_feasible(10.5));     // Above boundary
/// assert!(optimizer.is_feasible(9.9));       // Below boundary
/// assert!(optimizer.is_feasible(-1000.0));   // Far below boundary
///
/// assert_eq!(optimizer.constraint_boundary(), 10.0);
/// assert_eq!(optimizer.objective(8.0), Some(4.0));    // (8-10)² = 4
/// assert_eq!(optimizer.objective(10.0), None);        // Infeasible
///
/// let feasible = optimizer.get_feasible_point(0.01);
/// assert_eq!(feasible, 9.99);
/// assert!(optimizer.is_feasible(feasible));
/// ```
///
/// ### Probability Theory: Distribution Support
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents a distribution with strict upper bounded support
/// struct StrictUpperBoundedDistribution {
///     support: IntervalLowerUnboundedUpperOpen<f64>,
///     scale_parameter: f64,
/// }
///
/// impl StrictUpperBoundedDistribution {
///     fn new(max_value: f64, scale: f64) -> Self {
///         Self {
///             support: IntervalLowerUnboundedUpperOpen::new(max_value),
///             scale_parameter: scale,
///         }
///     }
///     
///     /// Probability density function (simplified example)
///     fn pdf(&self, x: f64) -> f64 {
///         if self.support.contains_point(&x) {
///             let max_val = *self.support.upper_bound_value();
///             // Simplified: density increases as we approach upper bound
///             let distance_from_max = max_val - x;
///             if distance_from_max > 0.0 {
///                 1.0 / (self.scale_parameter * distance_from_max)
///             } else {
///                 0.0
///             }
///         } else {
///             0.0 // Outside support
///         }
///     }
///     
///     /// Cumulative distribution function
///     fn cdf(&self, x: f64) -> f64 {
///         let max_val = *self.support.upper_bound_value();
///         if x >= max_val {
///             1.0
///         } else if self.support.contains_point(&x) {
///             // Simplified CDF calculation
///             let normalized = (x + 10.0 * self.scale_parameter) / (max_val + 10.0 * self.scale_parameter);
///             normalized.max(0.0).min(1.0)
///         } else {
///             1.0 // x >= max_val, probability 1
///         }
///     }
///     
///     /// Check if value is in distribution support
///     fn in_support(&self, x: f64) -> bool {
///         self.support.contains_point(&x)
///     }
///     
///     /// Get maximum value (excluded from support)
///     fn max_value(&self) -> f64 {
///         *self.support.upper_bound_value()
///     }
/// }
///
/// let dist = StrictUpperBoundedDistribution::new(10.0, 2.0);
///
/// assert!(dist.in_support(5.0));     // Within support
/// assert!(!dist.in_support(10.0));   // At maximum (excluded)
/// assert!(!dist.in_support(15.0));   // Above maximum
/// assert!(dist.in_support(-100.0));  // No lower bound
///
/// assert_eq!(dist.max_value(), 10.0);
/// assert!(dist.pdf(5.0) > 0.0);      // Positive density in support
/// assert_eq!(dist.pdf(10.0), 0.0);   // Zero density outside support
/// assert_eq!(dist.cdf(10.0), 1.0);   // CDF = 1 at maximum (and above)
/// ```
///
/// ### Control Theory: Stability Analysis
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
///
/// /// Models a stability constraint where parameter must be below critical value
/// struct StabilityConstraint {
///     stable_region: IntervalLowerUnboundedUpperOpen<f64>
/// }
///
/// impl StabilityConstraint {
///     fn new(critical_value: f64) -> Self {
///         Self {
///             stable_region: IntervalLowerUnboundedUpperOpen::new(critical_value)
///         }
///     }
///     
///     /// Check if parameter value maintains stability
///     fn is_stable(&self, parameter: f64) -> bool {
///         self.stable_region.contains_point(&parameter)
///     }
///     
///     /// Get the critical stability boundary
///     fn critical_value(&self) -> f64 {
///         *self.stable_region.upper_bound_value()
///     }
///     
///     /// Calculate stability margin (how far from instability)
///     fn stability_margin(&self, parameter: f64) -> f64 {
///         self.critical_value() - parameter
///     }
///     
///     /// Check if parameter increase is safe
///     fn safe_to_increase(&self, current_param: f64, increase: f64) -> bool {
///         let new_param = current_param + increase;
///         self.is_stable(new_param)
///     }
/// }
///
/// let stability = StabilityConstraint::new(1.0);  // Stable for param < 1.0
///
/// assert!(stability.is_stable(0.5));     // 0.5 < 1.0 (stable)
/// assert!(!stability.is_stable(1.0));    // 1.0 ≮ 1.0 (not stable)
/// assert!(stability.is_stable(-100.0));  // Very negative (very stable)
///
/// assert_eq!(stability.critical_value(), 1.0);
/// assert!((stability.stability_margin(0.8) - 0.2).abs() < 1.0e-15); // 1.0 - 0.8 = 0.2
/// assert!((stability.stability_margin(1.2) + 0.2).abs() < 1.0e-15); // 1.0 - 1.2 = -0.2 (unstable)
/// assert!(stability.safe_to_increase(0.7, 0.2));       // 0.7 + 0.2 = 0.9 < 1.0
/// assert!(!stability.safe_to_increase(0.7, 0.5));      // 0.7 + 0.5 = 1.2 > 1.0
/// ```
///
/// ## Performance Characteristics
///
/// ### Memory Layout
/// - **Storage**: Single scalar value for the upper bound (8 bytes for f64)
/// - **Alignment**: Natural alignment of the scalar type
/// - **No heap allocation**: All data stored inline
/// - **Compact representation**: Most memory-efficient for semi-infinite intervals
///
/// ### Operation Complexity
/// | Operation | Time Complexity | Space Complexity | Notes |
/// |-----------|----------------|------------------|-------|
/// | [`upper_bound_value`](IntervalLowerUnboundedUpperOpen::upper_bound_value) | O(1) | O(1) | Direct field access |
/// | Point containment | O(1) | O(1) | Single strict comparison (`x < upper_bound`) |
/// | Interval operations | O(1) | O(1) | Efficient boundary logic |
/// | Construction | O(1) | O(1) | Single validation check in debug mode |
///
/// ### Scalar Type Performance Impact
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::{RealNative64StrictFiniteInDebug, RealNative64StrictFinite, RealScalar};
///
/// // These have identical performance in release builds:
/// type FastUpperOpen = IntervalLowerUnboundedUpperOpen<f64>;
/// type OptimalUpperOpen = IntervalLowerUnboundedUpperOpen<RealNative64StrictFiniteInDebug>;
///
/// // This has small validation overhead:
/// type SafeUpperOpen = IntervalLowerUnboundedUpperOpen<RealNative64StrictFinite>;
///
/// // Performance test function (generic over any upper open interval)
/// fn benchmark_upper_open_operations<T: RealScalar + Clone>(
///     interval: &IntervalLowerUnboundedUpperOpen<T>
/// ) {
///     // All operations compile to identical assembly for f64 and RealNative64StrictFiniteInDebug
///     let _upper = interval.upper_bound_value(); // O(1) field access
///     
///     // Point containment is a single strict comparison: x < upper_bound
///     let test_value = T::zero();
///     let _contains = interval.contains_point(&test_value);
/// }
/// ```
///
/// ## Integration with Other Traits
///
/// ### Combined with [`IntervalTrait`]
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealScalar;
///
/// /// Generic function working with upper open intervals
/// fn analyze_upper_open_interval<I, T>(interval: &I) -> (T, bool, bool)
/// where
///     I: IntervalLowerUnboundedUpperBoundedTrait<RealType = T> + IntervalTrait<RealType = T>,
///     T: RealScalar + Clone,
/// {
///     let upper_bound = interval.upper_bound_value().clone();
///     let excludes_upper = !interval.contains_point(&upper_bound); // Should be true for open
///     let contains_large_negative = interval.contains_point(&T::try_from_f64(-1000.0).unwrap());
///     
///     (upper_bound, excludes_upper, contains_large_negative)
/// }
///
/// let open_interval = IntervalLowerUnboundedUpperOpen::new(5.0);
/// let closed_interval = IntervalLowerUnboundedUpperClosed::new(5.0);
///
/// let (upper1, excludes1, negative1) = analyze_upper_open_interval(&open_interval);
/// let (upper2, excludes2, negative2) = analyze_upper_open_interval(&closed_interval);
///
/// assert_eq!(upper1, 5.0);
/// assert_eq!(upper2, 5.0);
/// assert!(excludes1);   // (-∞, 5) excludes 5
/// assert!(!excludes2);  // (-∞, 5] includes 5
/// assert!(negative1);   // Both include large negative values
/// assert!(negative2);
/// ```
///
/// ### With Constraint Systems
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealScalar;
///
/// /// Combine multiple strict upper constraints
/// fn combine_strict_upper_constraints<I1, I2, T>(
///     constraint1: &I1,
///     constraint2: &I2
/// ) -> Option<T>
/// where
///     I1: IntervalLowerUnboundedUpperBoundedTrait<RealType = T>,
///     I2: IntervalLowerUnboundedUpperBoundedTrait<RealType = T>,
///     T: RealScalar,
/// {
///     let upper1 = constraint1.upper_bound_value();
///     let upper2 = constraint2.upper_bound_value();
///     
///     // The effective upper bound is the minimum of the two
///     if upper1 <= upper2 {
///         Some(upper1.clone())
///     } else {
///         Some(upper2.clone())
///     }
/// }
///
/// let constraint1 = IntervalLowerUnboundedUpperOpen::new(100.0);  // x < 100
/// let constraint2 = IntervalLowerUnboundedUpperOpen::new(50.0);   // x < 50
///
/// let combined_upper = combine_strict_upper_constraints(&constraint1, &constraint2).unwrap();
/// assert_eq!(combined_upper, 50.0);  // More restrictive constraint wins
/// ```
///
/// ## Best Practices and Recommendations
///
/// ### When to Use [`IntervalLowerUnboundedUpperOpen`]
/// - **Strict inequalities**: When you need `x < b` rather than `x ≤ b`
/// - **Asymptotic analysis**: Functions with singularities or discontinuities at the upper bound
/// - **Optimization**: Interior-point methods where upper boundary points are excluded
/// - **Mathematical modeling**: When the upper bound represents a limit that cannot be reached
/// - **Control theory**: Stability regions where the boundary represents instability
/// - **Convergence criteria**: When approaching a limit from below
///
/// ### When NOT to Use [`IntervalLowerUnboundedUpperOpen`]
/// - **Inclusive constraints**: When you need `x ≤ b`, use [`IntervalLowerUnboundedUpperClosed`]
/// - **Physical measurements**: Real-world constraints often include boundary values
/// - **Integration**: Definite integrals usually want closed intervals at finite bounds
/// - **Discrete domains**: Use finite intervals for countable sets
///
/// ### Recommended Patterns
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::{RealNative64StrictFiniteInDebug, functions::Abs};
/// use try_create::TryNew;
///
/// // Define type aliases for your application
/// type Real = RealNative64StrictFiniteInDebug;
/// type UpperOpenInterval = IntervalLowerUnboundedUpperOpen<Real>;
///
/// // Pattern: Always verify boundary exclusion when it matters
/// fn validate_strict_upper_constraint<I>(interval: &I, test_value: &Real) -> bool
/// where
///     I: IntervalLowerUnboundedUpperBoundedTrait<RealType = Real> + IntervalTrait<RealType = Real>,
/// {
///     let boundary = interval.upper_bound_value();
///     
///     // For open intervals, ensure boundary is excluded
///     test_value < boundary && interval.contains_point(test_value)
/// }
///
/// // Pattern: Use epsilon for getting close to but not touching the boundary
/// fn get_point_near_upper_boundary(interval: &UpperOpenInterval, epsilon: Real) -> Real {
///     interval.upper_bound_value().clone() - epsilon.abs()
/// }
///
/// // Pattern: Check feasibility with proper boundary handling
/// fn is_strictly_below_bound<I>(interval: &I, value: &Real) -> bool
/// where
///     I: IntervalLowerUnboundedUpperBoundedTrait<RealType = Real> + IntervalTrait<RealType = Real>,
/// {
///     // Ensure value is strictly less than upper bound
///     value < interval.upper_bound_value() && interval.contains_point(value)
/// }
/// ```
///
/// ## Common Use Cases
///
/// ### Mathematical Analysis
/// - **Function domains**: When functions have singularities or discontinuities at specific points
/// - **Asymptotic behavior**: Studying limits as variables approach boundary values from below
/// - **Convergence analysis**: Modeling approach to limits without reaching them
///
/// ### Optimization and Constraints
/// - **Strict inequality constraints**: `x < b` constraints in optimization problems
/// - **Interior-point methods**: Algorithms that require staying strictly inside feasible regions
/// - **Barrier methods**: Optimization techniques that approach but never reach constraint boundaries
///
/// ### Control and Systems Theory
/// - **Stability regions**: Parameter ranges where systems remain stable
/// - **Control margins**: Safe operating regions with strict upper bounds
/// - **Performance constraints**: System limits that must not be exceeded
///
/// ## Mathematical Properties and Guarantees
///
/// The [`IntervalLowerUnboundedUpperOpen`] struct maintains these mathematical properties:
///
/// - **Upper bound exclusion**: `upper_bound_value() ∉ interval` always holds
/// - **Infinite lower extent**: No finite lower bound exists
/// - **Strict inequality**: Point containment requires `x < upper_bound`
/// - **Monotonicity**: If interval A has upper bound ≥ interval B's upper bound, then A ⊇ B
/// - **Translation invariance**: Shifting the upper bound preserves the unbounded open structure
/// - **Intersection correctness**: Results follow standard interval arithmetic with proper boundary handling
///
/// These properties are preserved regardless of the scalar type used and are guaranteed
/// by the underlying implementations of the [`IntervalTrait`] and [`IntervalLowerUnboundedUpperBoundedTrait`].
pub type IntervalLowerUnboundedUpperOpen<RealType> =
    IntervalLowerUnboundedUpperBounded<RealType, Open>;
//------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------
/// An unbounded open-left interval `(a, +∞)` where the lower endpoint is excluded and extends to positive infinity.
///
/// The [`IntervalLowerOpenUpperUnbounded`] represents intervals of the form `(a, +∞)` where the lower bound `a`
/// is not part of the interval and the upper extent is infinite. This type of interval is fundamental
/// in mathematical analysis, particularly for strict inequality constraints, limit approaches, and
/// mathematical constructions where you need to exclude the starting point while extending infinitely upward.
///
/// ## Mathematical Properties
///
/// - **Notation**: `(a, +∞)` or `]a, +∞[`
/// - **Definition**: `{x ∈ ℝ : x > a}` where `a` is finite
/// - **Lower boundary**: Excluded (open)
/// - **Upper boundary**: Infinite (unbounded)
/// - **Measure**: `+∞` (infinite length)
/// - **Topology**: Open on the left, unbounded on the right
/// - **Cardinality**: Uncountably infinite points
/// - **Compactness**: Never compact (unbounded)
///
/// ## Use Cases
///
/// Open-left unbounded intervals are ideal when:
/// - **Strict inequalities**: Domains where `x > a` but not `x ≥ a`
/// - **Limit approaches**: Where values approach but never reach the lower bound
/// - **Asymptotic analysis**: Functions with vertical asymptotes at the lower bound
/// - **Optimization**: Strict lower bound constraints without upper limits
/// - **Growth models**: Unbounded growth starting strictly above a threshold
/// - **Mathematical analysis**: Domains where the lower bound represents a singularity or discontinuity
///
/// ## Comparison with Other Interval Types
///
/// | Property | `(a,+∞)` | `[a,+∞)` | `(-∞,b]` | `[a,b]` |
/// |----------|----------|----------|----------|---------|
/// | Contains `a` | ✗ | ✓ | N/A | ✓ |
/// | Contains values > `a` | ✓ | ✓ | Depends on `b` | Depends on `b` |
/// | Length | `+∞` | `+∞` | `+∞` | `b - a` |
/// | Compactness | Never | Never | Never | Always |
/// | Lower bound achieved | ✗ | ✓ | N/A | ✓ |
/// | Upper bound | None | None | ✓ | ✓ |
///
/// ## Construction
///
/// ### Safe Construction (Recommended)
/// ```rust
/// use grid1d::intervals::*;
/// use num_valid::RealNative64StrictFiniteInDebug;
/// use try_create::TryNew;
///
/// // Use the recommended performance-optimal type
/// type Real = RealNative64StrictFiniteInDebug;
///
/// // Create with validated scalar
/// let interval = IntervalLowerOpenUpperUnbounded::new(
///     Real::try_new(0.0).unwrap()
/// );
/// assert_eq!(interval.lower_bound_value(), &0.0);
/// ```
///
/// ### Raw Construction (Use with Caution)
/// ```rust
/// use grid1d::intervals::*;
///
/// // Direct construction with raw f64 - only when you trust your data
/// let interval = IntervalLowerOpenUpperUnbounded::new(5.0);
/// assert_eq!(interval.lower_bound_value(), &5.0);
/// ```
///
/// ## Key Operations
///
/// ### Point Containment (Lower Excluded, Upper Infinite)
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerOpenUpperUnbounded::new(0.0);  // (0, +∞)
///
/// // Lower boundary is excluded
/// assert!(!interval.contains_point(&0.0));   // Excluded lower bound
///
/// // All values above lower bound are included
/// assert!(interval.contains_point(&0.1));    // Just above lower bound
/// assert!(interval.contains_point(&1.0));    // Above lower bound
/// assert!(interval.contains_point(&1000.0)); // Far above lower bound
///
/// // Values below lower bound are excluded
/// assert!(!interval.contains_point(&-1.0));  // Below lower bound
/// assert!(!interval.contains_point(&-0.1));  // Just below lower bound
/// ```
///
/// ### Boundary Behavior Analysis
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerOpenUpperUnbounded::new(5.0);  // (5, +∞)
///
/// // Test boundary exclusion
/// assert!(!interval.contains_point(&5.0));    // Lower bound excluded
///
/// // Test points near lower boundary
/// assert!(interval.contains_point(&5.0001));  // Just above lower bound
/// assert!(!interval.contains_point(&4.9999)); // Just below lower bound
///
/// // Test large values (always included)
/// assert!(interval.contains_point(&1e6));     // Very large positive value
/// assert!(interval.contains_point(&f64::MAX)); // Floating-point limits
/// ```
///
/// ### Accessing the Lower Bound
/// ```rust
/// use grid1d::intervals::*;
///
/// let interval = IntervalLowerOpenUpperUnbounded::new(-10.0);
///
/// // Access the finite lower bound
/// assert_eq!(interval.lower_bound_value(), &-10.0);
///
/// // The lower bound itself is not in the interval
/// assert!(!interval.contains_point(interval.lower_bound_value()));
///
/// // But values arbitrarily close (but greater) are included
/// let epsilon = 1e-10;
/// assert!(interval.contains_point(&(-10.0 + epsilon)));
/// ```
///
/// ## Interval Containment and Set Operations
///
/// ### Containment Testing
/// ```rust
/// use grid1d::intervals::*;
///
/// let outer = IntervalLowerOpenUpperUnbounded::new(0.0);   // (0, +∞)
/// let inner = IntervalLowerOpenUpperUnbounded::new(1.0);   // (1, +∞)
/// let boundary = IntervalLowerOpenUpperUnbounded::new(0.0); // (0, +∞)
///
/// // Intervals with lower bounds can contain those with higher lower bounds
/// assert!(outer.contains_interval(&inner));           // (0, +∞) ⊇ (1, +∞) ✓
/// assert!(!inner.contains_interval(&outer));          // (1, +∞) ⊉ (0, +∞) ✗
///
/// // Same intervals contain themselves
/// assert!(outer.contains_interval(&boundary));        // (0, +∞) ⊇ (0, +∞) ✓
///
/// // Cross-type containment
/// let finite = IntervalClosed::new(1.0, 100.0);               // [1, 100]
/// let lower_closed = IntervalLowerClosedUpperUnbounded::new(0.5); // [0.5, +∞)
/// let upper_bounded = IntervalLowerUnboundedUpperClosed::new(50.0); // (-∞, 50]
///
/// assert!(outer.contains_interval(&finite));          // (0, +∞) ⊇ [1, 100] ✓
/// assert!(outer.contains_interval(&lower_closed));    // (0, +∞) ⊇ [0.5, +∞) ✓
/// assert!(!outer.contains_interval(&upper_bounded));  // (0, +∞) ⊉ (-∞, 50] ✗
/// assert!(!upper_bounded.contains_interval(&outer));  // (-∞, 50] ⊉ (0, +∞) ✗
/// ```
///
/// ## Intersection Examples
///
/// ### Open Unbounded with Open Unbounded
/// ```rust
/// use grid1d::intervals::*;
///
/// let a = IntervalLowerOpenUpperUnbounded::new(0.0);  // (0, +∞)
/// let b = IntervalLowerOpenUpperUnbounded::new(1.0);  // (1, +∞)
///
/// if let Some(intersection) = a.intersection(&b) {
///     // Result: (1, +∞) - takes the more restrictive (higher) lower bound
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerOpenUpperUnbounded(result)) => {
///             assert_eq!(result.lower_bound_value(), &1.0);
///         }
///         _ => unreachable!("Expected open unbounded interval"),
///     }
/// }
/// ```
///
/// ### Open Unbounded with Finite Intervals
/// ```rust
/// use grid1d::intervals::*;
///
/// let unbounded = IntervalLowerOpenUpperUnbounded::new(0.0);  // (0, +∞)
/// let closed = IntervalClosed::new(1.0, 10.0);                // [1, 10]
/// let open = IntervalOpen::new(-1.0, 5.0);                    // (-1, 5)
///
/// // Intersection of (0, +∞) with [1, 10]
/// // Result: [1, 10]
/// if let Some(intersection) = unbounded.intersection(&closed) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(positive)) => {
///             assert_eq!(positive.length().into_inner(), 9.0); // 10 - 1 = 9
///         }
///         _ => unreachable!("Expected finite positive interval"),
///     }
/// }
///
/// // Intersection of (0, +∞) with (-1, 5)
/// // Result: (0, 5)
/// if let Some(intersection) = unbounded.intersection(&open) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(
///             IntervalFinitePositiveLength::Open(result)
///         )) => {
///             assert_eq!(result.lower_bound_value(), &0.0);
///             assert_eq!(result.upper_bound_value(), &5.0);
///         }
///         _ => unreachable!("Expected open finite interval"),
///     }
/// }
/// ```
///
/// ### Open Unbounded with Other Unbounded Types
/// ```rust
/// use grid1d::intervals::*;
///
/// let open_unbounded = IntervalLowerOpenUpperUnbounded::new(0.0);     // (0, +∞)
/// let closed_unbounded = IntervalLowerClosedUpperUnbounded::new(1.0); // [1, +∞)
/// let upper_bounded = IntervalLowerUnboundedUpperClosed::new(10.0);   // (-∞, 10]
/// let fully_unbounded = IntervalLowerUnboundedUpperUnbounded::<f64>::new(); // (-∞, +∞)
///
/// // Intersection of (0, +∞) with [1, +∞)
/// // Result: [1, +∞)
/// if let Some(intersection) = open_unbounded.intersection(&closed_unbounded) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerClosedUpperUnbounded(result)) => {
///             assert_eq!(result.lower_bound_value(), &1.0);
///         }
///         _ => unreachable!("Expected closed unbounded interval"),
///     }
/// }
///
/// // Intersection of (0, +∞) with (-∞, 10]
/// // Result: (0, 10]
/// if let Some(intersection) = open_unbounded.intersection(&upper_bounded) {
///     match intersection {
///         Interval::FiniteLength(IntervalFiniteLength::PositiveLength(
///             IntervalFinitePositiveLength::LowerOpenUpperClosed(result)
///         )) => {
///             assert_eq!(result.lower_bound_value(), &0.0);
///             assert_eq!(result.upper_bound_value(), &10.0);
///         }
///         _ => unreachable!("Expected left-open finite interval"),
///     }
/// }
///
/// // Intersection of (0, +∞) with (-∞, +∞)
/// // Result: (0, +∞)
/// if let Some(intersection) = open_unbounded.intersection(&fully_unbounded) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerOpenUpperUnbounded(result)) => {
///             assert_eq!(result.lower_bound_value(), &0.0);
///         }
///         _ => unreachable!("Expected open unbounded interval"),
///     }
/// }
/// ```
///
/// ### Edge Cases: Disjoint and Boundary Cases
/// ```rust
/// use grid1d::intervals::*;
///
/// let positive = IntervalLowerOpenUpperUnbounded::new(0.0);           // (0, +∞)
/// let negative = IntervalLowerUnboundedUpperOpen::new(0.0);           // (-∞, 0)
/// let zero_right = IntervalLowerUnboundedUpperClosed::new(0.0);       // (-∞, 0]
/// let at_boundary = IntervalLowerClosedUpperUnbounded::new(0.0);      // [0, +∞)
///
/// // Disjoint intervals
/// assert!(positive.intersection(&negative).is_none());     // (0, +∞) ∩ (-∞, 0) = ∅
/// assert!(positive.intersection(&zero_right).is_none());   // (0, +∞) ∩ (-∞, 0] = ∅
///
/// // Boundary touching but no intersection due to open boundary
/// // (0, +∞) ∩ [0, +∞) = (0, +∞) - the open interval wins
/// if let Some(intersection) = positive.intersection(&at_boundary) {
///     match intersection {
///         Interval::InfiniteLength(IntervalInfiniteLength::LowerOpenUpperUnbounded(result)) => {
///             assert_eq!(result.lower_bound_value(), &0.0);
///         }
///         _ => unreachable!("Expected open unbounded interval"),
///     }
/// }
/// ```
///
/// ## Advanced Usage Patterns
///
/// ### Asymptotic Analysis and Limit Behavior
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Represents a function's domain near a vertical asymptote
/// struct AsymptoticFunction {
///     domain: IntervalLowerOpenUpperUnbounded<f64>,
///     asymptote_location: f64,
/// }
///
/// impl AsymptoticFunction {
///     fn new(asymptote_at: f64) -> Self {
///         Self {
///             domain: IntervalLowerOpenUpperUnbounded::new(asymptote_at),
///             asymptote_location: asymptote_at,
///         }
///     }
///     
///     /// Check if a value is in the function's domain
///     fn is_defined_at(&self, x: f64) -> bool {
///         self.domain.contains_point(&x)
///     }
///     
///     /// Evaluate function: f(x) = 1/(x - asymptote)
///     fn evaluate(&self, x: f64) -> Option<f64> {
///         if self.is_defined_at(x) {
///             Some(1.0 / (x - self.asymptote_location))
///         } else {
///             None // Undefined at or below asymptote
///         }
///     }
///     
///     /// Check if we're approaching the asymptote from the right
///     fn distance_from_asymptote(&self, x: f64) -> Option<f64> {
///         if self.is_defined_at(x) {
///             Some(x - self.asymptote_location)
///         } else {
///             None
///         }
///     }
/// }
///
/// let func = AsymptoticFunction::new(0.0);  // f(x) = 1/x for x > 0
///
/// assert!(!func.is_defined_at(0.0));       // Undefined at asymptote
/// assert!(!func.is_defined_at(-1.0));      // Undefined for negative values
/// assert!(func.is_defined_at(0.1));        // Defined for positive values
///
/// assert_eq!(func.evaluate(1.0), Some(1.0));         // f(1) = 1
/// assert_eq!(func.evaluate(0.5), Some(2.0));         // f(0.5) = 2
/// assert_eq!(func.evaluate(0.0), None);              // Undefined
/// assert_eq!(func.distance_from_asymptote(0.1), Some(0.1)); // Distance = 0.1
/// ```
///
/// ### Optimization with Strict Lower Bounds
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Optimization problem with strict lower bound constraint
/// struct StrictLowerBoundOptimization {
///     feasible_region: IntervalLowerOpenUpperUnbounded<f64>
/// }
///
/// impl StrictLowerBoundOptimization {
///     /// Create optimization problem: minimize f(x) subject to x > lower_bound
///     fn new(strict_lower_bound: f64) -> Self {
///         Self {
///             feasible_region: IntervalLowerOpenUpperUnbounded::new(strict_lower_bound)
///         }
///     }
///     
///     /// Check if a point satisfies the strict constraint
///     fn is_feasible(&self, x: f64) -> bool {
///         self.feasible_region.contains_point(&x)
///     }
///     
///     /// Get the constraint boundary (not included in feasible region)
///     fn constraint_boundary(&self) -> f64 {
///         *self.feasible_region.lower_bound_value()
///     }
///     
///     /// Objective function: f(x) = (x - boundary)²
///     fn objective(&self, x: f64) -> Option<f64> {
///         if self.is_feasible(x) {
///             let boundary = self.constraint_boundary();
///             Some((x - boundary).powi(2))
///         } else {
///             None // Infeasible point
///         }
///     }
///     
///     /// Find a feasible starting point (boundary + epsilon)
///     fn get_feasible_start_point(&self, epsilon: f64) -> f64 {
///         self.constraint_boundary() + epsilon.abs()
///     }
/// }
///
/// let optimizer = StrictLowerBoundOptimization::new(1.0);  // x > 1
///
/// assert!(!optimizer.is_feasible(1.0));      // Boundary point not feasible
/// assert!(!optimizer.is_feasible(0.5));      // Below boundary
/// assert!(optimizer.is_feasible(1.1));       // Above boundary
///
/// assert_eq!(optimizer.constraint_boundary(), 1.0);
/// assert_eq!(optimizer.objective(2.0), Some(1.0));    // (2-1)² = 1
/// assert_eq!(optimizer.objective(1.0), None);         // Infeasible
///
/// let start = optimizer.get_feasible_start_point(0.01);
/// assert_eq!(start, 1.01);
/// assert!(optimizer.is_feasible(start));
/// ```
///
/// ### Probability Theory: Support of Distributions
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Pareto distribution with support (x_min, +∞)
/// /// Note: Some Pareto formulations use [x_min, +∞), but this version excludes x_min
/// struct StrictParetoDistribution {
///     support: IntervalLowerOpenUpperUnbounded<f64>,
///     shape: f64,
///     scale: f64,
/// }
///
/// impl StrictParetoDistribution {
///     fn new(x_min: f64, shape: f64) -> Self {
///         Self {
///             support: IntervalLowerOpenUpperUnbounded::new(x_min),
///             shape,
///             scale: x_min,
///         }
///     }
///     
///     /// Probability density function
///     fn pdf(&self, x: f64) -> f64 {
///         if self.support.contains_point(&x) {
///             let x_min = self.scale;
///             self.shape * x_min.powf(self.shape) / x.powf(self.shape + 1.0)
///         } else {
///             0.0 // Outside support
///         }
///     }
///     
///     /// Cumulative distribution function
///     fn cdf(&self, x: f64) -> f64 {
///         if x <= self.scale {
///             0.0
///         } else if self.support.contains_point(&x) {
///             1.0 - (self.scale / x).powf(self.shape)
///         } else {
///             unreachable!() // Should not happen for this distribution
///         }
///     }
///     
///     /// Check if value is in distribution support
///     fn in_support(&self, x: f64) -> bool {
///         self.support.contains_point(&x)
///     }
///     
///     /// Get the scale parameter (excluded lower bound)
///     fn scale_parameter(&self) -> f64 {
///         *self.support.lower_bound_value()
///     }
/// }
///
/// let pareto = StrictParetoDistribution::new(1.0, 2.0);
///
/// assert!(!pareto.in_support(1.0));       // Scale parameter excluded
/// assert!(!pareto.in_support(0.5));       // Below scale parameter
/// assert!(pareto.in_support(1.1));        // Above scale parameter
/// assert!(pareto.in_support(10.0));       // Well above scale parameter
///
/// assert_eq!(pareto.scale_parameter(), 1.0);
/// assert_eq!(pareto.pdf(1.0), 0.0);        // Zero density outside support
/// assert!(pareto.pdf(2.0) > 0.0);          // Positive density in support
/// assert_eq!(pareto.cdf(1.0), 0.0);        // Zero CDF at boundary
/// assert!(pareto.cdf(2.0) > 0.0);          // Positive CDF in support
/// ```
///
/// ### Growth Models and Time Series
/// ```rust
/// use grid1d::intervals::*;
///
/// /// Models unbounded exponential growth starting strictly after time t₀
/// struct ExponentialGrowthModel {
///     valid_times: IntervalLowerOpenUpperUnbounded<f64>,
///     growth_rate: f64,
///     initial_time: f64,
/// }
///
/// impl ExponentialGrowthModel {
///     fn new(start_time: f64, growth_rate: f64) -> Self {
///         Self {
///             valid_times: IntervalLowerOpenUpperUnbounded::new(start_time),
///             growth_rate,
///             initial_time: start_time,
///         }
///     }
///     
///     /// Check if time is in the valid domain
///     fn is_valid_time(&self, t: f64) -> bool {
///         self.valid_times.contains_point(&t)
///     }
///     
///     /// Evaluate growth: f(t) = exp(r * (t - t₀)) for t > t₀
///     fn evaluate(&self, t: f64) -> Option<f64> {
///         if self.is_valid_time(t) {
///             let elapsed = t - self.initial_time;
///             Some((self.growth_rate * elapsed).exp())
///         } else {
///             None // Outside valid time domain
///         }
///     }
///     
///     /// Find time when growth reaches target value
///     fn time_to_reach(&self, target_value: f64) -> Option<f64> {
///         if target_value > 1.0 && self.growth_rate > 0.0 {
///             let time = self.initial_time + target_value.ln() / self.growth_rate;
///             if self.is_valid_time(time) {
///                 Some(time)
///             } else {
///                 None
///             }
///         } else {
///             None // Invalid target or growth rate
///         }
///     }
/// }
///
/// let growth = ExponentialGrowthModel::new(0.0, 0.1); // Growth starts after t=0
///
/// assert!(!growth.is_valid_time(0.0));     // Start time excluded
/// assert!(!growth.is_valid_time(-1.0));    // Before start time
/// assert!(growth.is_valid_time(0.1));      // After start time
/// assert!(growth.is_valid_time(10.0));     // Far in the future
///
/// assert_eq!(growth.evaluate(0.0), None);              // Undefined at start
/// assert_eq!(growth.evaluate(0.1), Some((0.01_f64).exp())); // e^(0.1*0.1)
///
/// // Time to reach e^1 ≈ 2.718
/// let target_time = growth.time_to_reach(std::f64::consts::E);
/// assert!(target_time.is_some());
/// let t = target_time.unwrap();
/// assert!((t - 10.0).abs() < 1e-10); // Should be t₀ + ln(e)/0.1 = 0 + 1/0.1 = 10
/// ```
///
/// ## Performance Characteristics
///
/// ### Memory Layout
/// - **Storage**: Single scalar value for the lower bound (8 bytes for f64)
/// - **Alignment**: Natural alignment of the scalar type
/// - **No heap allocation**: All data stored inline
/// - **Compact representation**: Most memory-efficient for semi-infinite intervals
///
/// ### Operation Complexity
/// | Operation | Time Complexity | Space Complexity | Notes |
/// |-----------|----------------|------------------|-------|
/// | [`lower_bound_value`](IntervalLowerOpenUpperUnbounded::lower_bound_value) | O(1) | O(1) | Direct field access |
/// | Point containment | O(1) | O(1) | Single strict comparison |
/// | Interval operations | O(1) | O(1) | Efficient boundary logic |
/// | Construction | O(1) | O(1) | Single validation check in debug mode |
///
/// ### Scalar Type Performance Impact
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::{RealNative64StrictFiniteInDebug, RealNative64StrictFinite, RealScalar};
///
/// // These have identical performance in release builds:
/// type FastOpenUnbounded = IntervalLowerOpenUpperUnbounded<f64>;
/// type OptimalOpenUnbounded = IntervalLowerOpenUpperUnbounded<RealNative64StrictFiniteInDebug>;
///
/// // This has small validation overhead:
/// type SafeOpenUnbounded = IntervalLowerOpenUpperUnbounded<RealNative64StrictFinite>;
///
/// // Performance test function (generic over any open unbounded interval)
/// fn benchmark_open_unbounded_operations<T: RealScalar + Clone>(interval: &IntervalLowerOpenUpperUnbounded<T>) {
///     // All operations compile to identical assembly for f64 and RealNative64StrictFiniteInDebug
///     let _lower = interval.lower_bound_value(); // O(1) field access
///     
///     // Point containment is a single strict comparison: x > lower_bound
///     let test_value = T::zero();
///     let _contains = interval.contains_point(&test_value);
/// }
/// ```
///
/// ## Integration with Other Traits
///
/// ### Combined with [`IntervalTrait`]
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealScalar;
///
/// /// Generic function working with open unbounded intervals
/// fn analyze_open_unbounded_interval<I, T>(interval: &I) -> (T, bool, bool)
/// where
///     I: IntervalLowerBoundedUpperUnboundedTrait<RealType = T> + IntervalTrait<RealType = T>,
///     T: RealScalar + Clone,
/// {
///     let lower_bound = interval.lower_bound_value().clone();
///     let excludes_lower = !interval.contains_point(&lower_bound); // Should be true for open
///     let contains_large_value = interval.contains_point(&T::try_from_f64(1000.0).unwrap());
///     
///     (lower_bound, excludes_lower, contains_large_value)
/// }
///
/// let open_interval = IntervalLowerOpenUpperUnbounded::new(5.0);
/// let closed_interval = IntervalLowerClosedUpperUnbounded::new(5.0);
///
/// let (lower1, excludes1, large1) = analyze_open_unbounded_interval(&open_interval);
/// let (lower2, excludes2, large2) = analyze_open_unbounded_interval(&closed_interval);
///
/// assert_eq!(lower1, 5.0);
/// assert_eq!(lower2, 5.0);
/// assert!(excludes1);   // (5, +∞) excludes 5
/// assert!(!excludes2);  // [5, +∞) includes 5
/// assert!(large1);      // Both include large values
/// assert!(large2);
/// ```
///
/// ### With Constraint Systems
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::RealScalar;
///
/// /// Combine multiple strict lower constraints
/// fn combine_strict_lower_constraints<I1, I2, T>(
///     constraint1: &I1,
///     constraint2: &I2
/// ) -> Option<T>
/// where
///     I1: IntervalLowerBoundedUpperUnboundedTrait<RealType = T>,
///     I2: IntervalLowerBoundedUpperUnboundedTrait<RealType = T>,
///     T: RealScalar + PartialOrd + Clone,
/// {
///     let lower1 = constraint1.lower_bound_value();
///     let lower2 = constraint2.lower_bound_value();
///     
///     // The effective lower bound is the maximum of the two
///     if lower1 >= lower2 {
///         Some(lower1.clone())
///     } else {
///         Some(lower2.clone())
///     }
/// }
///
/// let constraint1 = IntervalLowerOpenUpperUnbounded::new(0.0);   // x > 0
/// let constraint2 = IntervalLowerOpenUpperUnbounded::new(5.0);   // x > 5
///
/// let combined_lower = combine_strict_lower_constraints(&constraint1, &constraint2).unwrap();
/// assert_eq!(combined_lower, 5.0);  // More restrictive constraint wins
/// ```
///
/// ## Best Practices and Recommendations
///
/// ### When to Use [`IntervalLowerOpenUpperUnbounded`]
/// - **Strict inequalities**: When you need `x > a` rather than `x ≥ a`
/// - **Asymptotic analysis**: Functions with singularities or discontinuities at the lower bound
/// - **Optimization**: Interior-point methods where boundary points are excluded
/// - **Mathematical modeling**: When the lower bound represents a physical or mathematical limit that cannot be reached
/// - **Probability theory**: Distributions where the support excludes the boundary value
///
/// ### When NOT to Use [`IntervalLowerOpenUpperUnbounded`]
/// - **Inclusive constraints**: When you need `x ≥ a`, use [`IntervalLowerClosedUpperUnbounded`]
/// - **Physical measurements**: Real-world constraints often include boundary values
/// - **Integration**: Definite integrals usually want closed intervals at finite bounds
/// - **Discrete domains**: Use finite intervals for countable sets
///
/// ### Recommended Patterns
/// ```rust
/// use grid1d::intervals::{*, unbounded::*};
/// use num_valid::{RealNative64StrictFiniteInDebug, functions::Abs};
/// use try_create::TryNew;
///
/// // Define type aliases for your application
/// type Real = RealNative64StrictFiniteInDebug;
/// type OpenUnboundedInterval = IntervalLowerOpenUpperUnbounded<Real>;
///
/// // Pattern: Always verify boundary exclusion when it matters
/// fn validate_strict_constraint<I>(interval: &I, test_value: &Real) -> bool
/// where
///     I: IntervalLowerBoundedUpperUnboundedTrait<RealType = Real> + IntervalTrait<RealType = Real>,
/// {
///     let boundary = interval.lower_bound_value();
///     
///     // For open intervals, ensure boundary is excluded
///     test_value > boundary && interval.contains_point(test_value)
/// }
///
/// // Pattern: Use epsilon for getting close to but not touching the boundary
/// fn get_point_near_boundary(interval: &OpenUnboundedInterval, epsilon: Real) -> Real {
///     interval.lower_bound_value().clone() + epsilon.abs()
/// }
///
/// // Pattern: Check feasibility with proper boundary handling
/// fn is_strictly_feasible<I>(interval: &I, value: &Real) -> bool
/// where
///     I: IntervalLowerBoundedUpperUnboundedTrait<RealType = Real> + IntervalTrait<RealType = Real>,
/// {
///     // Ensure value is strictly greater than lower bound
///     value > interval.lower_bound_value() && interval.contains_point(value)
/// }
/// ```
///
/// ## Common Use Cases
///
/// ### Mathematical Analysis
/// - **Function domains**: When functions have singularities or discontinuities at specific points
/// - **Asymptotic behavior**: Studying limits as variables approach boundary values from one side
/// - **Growth models**: Modeling unlimited growth starting after a specific threshold
///
/// ### Optimization and Constraints
/// - **Strict inequality constraints**: `x > a` constraints in optimization problems
/// - **Interior-point methods**: Algorithms that require staying strictly inside feasible regions
/// - **Barrier methods**: Optimization techniques that approach but never reach constraint boundaries
///
/// ### Probability and Statistics
/// - **Distribution supports**: Random variables with strict lower bounds
/// - **Survival analysis**: Modeling times strictly after a certain event
/// - **Extreme value theory**: Distributions with support starting strictly above thresholds
///
/// ## Mathematical Properties and Guarantees
///
/// The [`IntervalLowerOpenUpperUnbounded`] struct maintains these mathematical properties:
///
/// - **Lower bound exclusion**: `lower_bound_value() ∉ interval` always holds
/// - **Infinite upper extent**: No finite upper bound exists
/// - **Strict inequality**: Point containment requires `x > lower_bound`
/// - **Monotonicity**: If interval A has lower bound ≤ interval B's lower bound, then A ⊇ B
/// - **Translation invariance**: Shifting the lower bound preserves the open unbounded structure
/// - **Intersection correctness**: Results follow standard interval arithmetic with proper boundary handling
///
/// These properties are preserved regardless of the scalar type used and are guaranteed
/// by the underlying implementations of the [`IntervalTrait`] and [`IntervalLowerBoundedUpperUnboundedTrait`].
pub type IntervalLowerOpenUpperUnbounded<RealType> =
    IntervalLowerBoundedUpperUnbounded<RealType, Open>;
//------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------
#[duplicate_item(
    interval_type                       lower_bound_type;
    [IntervalLowerClosedUpperUnbounded] [Closed];
    [IntervalLowerOpenUpperUnbounded]   [Open];
)]
impl<RealType: RealScalar> IntervalBoundsRuntime for interval_type<RealType> {
    type RealType = RealType;

    #[inline(always)]
    fn lower_bound_runtime(&self) -> Option<LowerBoundRuntime<RealType>> {
        Some(IntervalBoundRuntime::lower_bound_type(
            self.lower_bound().clone(),
        ))
    }

    #[inline(always)]
    fn upper_bound_runtime(&self) -> Option<UpperBoundRuntime<RealType>> {
        None
    }
}

#[duplicate_item(
    interval_type                       upper_bound_type;
    [IntervalLowerUnboundedUpperClosed] [Closed];
    [IntervalLowerUnboundedUpperOpen]   [Open];
)]
impl<RealType: RealScalar> IntervalBoundsRuntime for interval_type<RealType> {
    type RealType = RealType;

    #[inline(always)]
    fn lower_bound_runtime(&self) -> Option<LowerBoundRuntime<RealType>> {
        None
    }

    #[inline(always)]
    fn upper_bound_runtime(&self) -> Option<UpperBoundRuntime<RealType>> {
        Some(IntervalBoundRuntime::upper_bound_type(
            self.upper_bound().clone(),
        ))
    }
}

impl<RealType: RealScalar> IntervalBoundsRuntime
    for IntervalLowerUnboundedUpperUnbounded<RealType>
{
    type RealType = RealType;

    #[inline(always)]
    fn lower_bound_runtime(&self) -> Option<LowerBoundRuntime<RealType>> {
        None
    }

    #[inline(always)]
    fn upper_bound_runtime(&self) -> Option<UpperBoundRuntime<RealType>> {
        None
    }
}
//------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------
impl<RealType: RealScalar, LowerBoundType: BoundType> GetLowerBoundValue
    for IntervalLowerBoundedUpperUnbounded<RealType, LowerBoundType>
{
    type LowerBoundValue = RealType;

    #[inline(always)]
    fn lower_bound_value(&self) -> &RealType {
        &self.lower_bound.value
    }

    fn is_lower_bound_closed(&self) -> bool {
        LowerBoundType::is_closed()
    }
}

impl<RealType: RealScalar, UpperBoundType: BoundType> GetUpperBoundValue
    for IntervalLowerUnboundedUpperBounded<RealType, UpperBoundType>
{
    type UpperBoundValue = RealType;

    #[inline(always)]
    fn upper_bound_value(&self) -> &RealType {
        &self.upper_bound.value
    }

    #[inline(always)]
    fn is_upper_bound_closed(&self) -> bool {
        UpperBoundType::is_closed()
    }
}
//------------------------------------------------------------------------------------------------
