<commit_before>module OpenSolid.Core.Interval
  ( empty
  , whole
  , singleton
  , hullOf
  , fromEndpoints
  , endpoints
  , isEmpty
  , isWhole
  , isFinite
  , width
  , interpolated
  , midpoint
  , contains
  , isInside
  , overlaps
  , hull
  ) where


import OpenSolid.Core exposing (..)
import OpenSolid.Core.Scalar as Scalar


empty: Interval
empty =
  Interval Scalar.notANumber Scalar.notANumber


whole: Interval
whole =
  Interval Scalar.negativeInfinity Scalar.positiveInfinity


singleton: Float -> Interval
singleton value =
  Interval value value


hullOf: List Interval -> Interval
hullOf =
  List.foldl hull empty


fromEndpoints: (Float, Float) -> Interval
fromEndpoints (lowerBound, upperBound) =
  Interval lowerBound upperBound


endpoints: Interval -> (Float, Float)
endpoints (Interval lowerBound upperBound) =
  (lowerBound, upperBound)


isEmpty: Interval -> Bool
isEmpty (Interval lowerBound upperBound) =
  isNaN lowerBound && isNaN upperBound


isWhole: Interval -> Bool
isWhole (Interval lowerBound upperBound) =
  lowerBound == Scalar.negativeInfinity && upperBound == Scalar.positiveInfinity


isFinite: Interval -> Bool
isFinite (Interval lowerBound upperBound) =
  lowerBound > Scalar.negativeInfinity && upperBound < Scalar.positiveInfinity


width: Interval -> Float
width (Interval lowerBound upperBound) =
  upperBound - lowerBound


interpolated: Float -> Interval -> Float
interpolated parameter (Interval lowerBound upperBound as interval) =
  if isFinite interval then
    -- Fast path
    lowerBound + parameter * width interval
  else if isNaN parameter || isEmpty interval then
    Scalar.notANumber
  else if upperBound == Scalar.negativeInfinity then
    -- Interval is singleton negative infinity
    if parameter <= 1 then Scalar.negativeInfinity else Scalar.notANumber
  else if lowerBound == Scalar.positiveInfinity then
    -- Interval is singleton positive infinity
    if parameter >= 0 then Scalar.positiveInfinity else Scalar.notANumber
  else if lowerBound > Scalar.negativeInfinity then
    -- Interval has finite lower bound, infinite upper bound
    if parameter < 0 then
      Scalar.negativeInfinity
    else if parameter > 0 then
      Scalar.positiveInfinity
    else
      lowerBound
  else if upperBound < Scalar.positiveInfinity then
    -- Interval has finite upper bound, infinite lower bound
    if parameter < 1 then
      Scalar.negativeInfinity
    else if parameter > 1 then
      Scalar.positiveInfinity
    else
      upperBound
  else
    -- Interval is the whole interval
    if parameter <= 0 then
      Scalar.negativeInfinity
    else if parameter >= 1 then
      Scalar.positiveInfinity
    else
      Scalar.notANumber


midpoint: Interval -> Float
midpoint =
  interpolated 0.5


contains: Float -> Interval -> Bool
contains value interval =
  Scalar.isInside interval value


isInside: Interval -> Interval -> Bool
isInside (Interval otherLower otherUpper) (Interval lowerBound upperBound) =
  otherLower <= lowerBound && upperBound <= otherUpper


overlaps: Interval -> Interval -> Bool
overlaps (Interval firstLower firstUpper) (Interval secondLower secondUpper) =
  firstLower <= secondUpper && secondLower <= firstUpper


hull: Interval -> Interval -> Interval
hull (Interval firstLower firstUpper as first) (Interval secondLower secondUpper as second) =
  if isEmpty first then
    second
  else if isEmpty second then
    first
  else
    Interval (min secondLower firstLower) (max secondUpper firstUpper)<commit_msg>Eliminate Interval dependence on Scalar<commit_after>module OpenSolid.Core.Interval
  ( empty
  , whole
  , singleton
  , hullOf
  , fromEndpoints
  , endpoints
  , isEmpty
  , isWhole
  , isFinite
  , width
  , interpolated
  , midpoint
  , contains
  , isInside
  , overlaps
  , hull
  ) where


import OpenSolid.Core exposing (..)


positiveInfinity =
  1 / 0


negativeInfinity =
  -1 / 0


notANumber =
  0 / 0


empty: Interval
empty =
  Interval notANumber notANumber


whole: Interval
whole =
  Interval negativeInfinity positiveInfinity


singleton: Float -> Interval
singleton value =
  Interval value value


hullOf: List Interval -> Interval
hullOf =
  List.foldl hull empty


fromEndpoints: (Float, Float) -> Interval
fromEndpoints (lowerBound, upperBound) =
  Interval lowerBound upperBound


endpoints: Interval -> (Float, Float)
endpoints (Interval lowerBound upperBound) =
  (lowerBound, upperBound)


isEmpty: Interval -> Bool
isEmpty (Interval lowerBound upperBound) =
  isNaN lowerBound && isNaN upperBound


isWhole: Interval -> Bool
isWhole (Interval lowerBound upperBound) =
  lowerBound == negativeInfinity && upperBound == positiveInfinity


isFinite: Interval -> Bool
isFinite (Interval lowerBound upperBound) =
  negativeInfinity < lowerBound && upperBound < positiveInfinity


width: Interval -> Float
width (Interval lowerBound upperBound) =
  upperBound - lowerBound


interpolated: Float -> Interval -> Float
interpolated parameter (Interval lowerBound upperBound as interval) =
  if isFinite interval then
    -- Fast path
    lowerBound + parameter * width interval
  else if isNaN parameter || isEmpty interval then
    notANumber
  else if upperBound == negativeInfinity then
    -- Interval is singleton negative infinity
    if parameter <= 1 then negativeInfinity else notANumber
  else if lowerBound == positiveInfinity then
    -- Interval is singleton positive infinity
    if parameter >= 0 then positiveInfinity else notANumber
  else if lowerBound > negativeInfinity then
    -- Interval has finite lower bound, infinite upper bound
    if parameter < 0 then
      negativeInfinity
    else if parameter > 0 then
      positiveInfinity
    else
      lowerBound
  else if upperBound < positiveInfinity then
    -- Interval has finite upper bound, infinite lower bound
    if parameter < 1 then
      negativeInfinity
    else if parameter > 1 then
      positiveInfinity
    else
      upperBound
  else
    -- Interval is the whole interval
    if parameter <= 0 then
      negativeInfinity
    else if parameter >= 1 then
      positiveInfinity
    else
      notANumber


midpoint: Interval -> Float
midpoint =
  interpolated 0.5


contains: Float -> Interval -> Bool
contains value (Interval lowerBound upperBound) =
  lowerBound <= value && value <= upperBound


isInside: Interval -> Interval -> Bool
isInside (Interval otherLower otherUpper) (Interval lowerBound upperBound) =
  otherLower <= lowerBound && upperBound <= otherUpper


overlaps: Interval -> Interval -> Bool
overlaps (Interval firstLower firstUpper) (Interval secondLower secondUpper) =
  firstLower <= secondUpper && secondLower <= firstUpper


hull: Interval -> Interval -> Interval
hull (Interval firstLower firstUpper as first) (Interval secondLower secondUpper as second) =
  if isEmpty first then
    second
  else if isEmpty second then
    first
  else
    Interval (min secondLower firstLower) (max secondUpper firstUpper)
{'fraction_non_alphanumeric': 0.06353313209716832, 'fraction_numerical': 0.003737243064539313, 'mean_word_length': 3.6604152712659075, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1984501', 'n_tokens_mistral': 2022, 'n_tokens_neox': 1875, 'n_words': 671}