///|
/// Exact FCFS response tail for M/M/c: an exponential service time plus
/// a mixture of zero wait and exponential delayed wait. Not GI/G/c.
pub fn Mmc::response_survival(
  self : Mmc,
  time : Double,
) -> Double raise QueueError {
  nonnegative(time, "response threshold")
  let metrics = self.analyze()
  let spare = self.service * self.servers.to_double() - self.arrival
  let a = spare.min(self.service)
  let d = (spare - self.service).abs()
  let at = a * time
  if at > 750.0 {
    return 0.0
  }
  let x = d * time
  let extra = if x < 0.0001 {
    at * (1.0 - x / 2.0 + x * x / 6.0 - x * x * x / 24.0)
  } else {
    a / d * (1.0 - @math.exp(-x))
  }
  let conditional = @math.exp(-at) * (1.0 + extra)
  let result = (1.0 - metrics.delay_probability) *
    @math.exp(-self.service * time) +
    metrics.delay_probability * conditional
  finite(result, "response survival")
  result.max(0.0).min(1.0)
}

///|
/// Response quantile from the exact continuous tail. The unit quantile is
/// infinite even with zero load because exponential service is unbounded.
pub fn Mmc::response_quantile(
  self : Mmc,
  p : Double,
) -> Double raise QueueError {
  probability(p, "response quantile")
  let metrics = self.analyze()
  if p == 1.0 {
    raise Invalid("unit response quantile is infinite")
  }
  if p == 0.0 {
    return 0.0
  }
  let target = 1.0 - p
  let mut hi = metrics.mean_response
  for _ in 0..<1024 {
    if self.response_survival(hi) <= target {
      break
    }
    hi *= 2.0
    finite(hi, "response quantile bracket")
  }
  if self.response_survival(hi) > target {
    raise Numerical("response quantile could not be bracketed")
  }
  let mut lo = 0.0
  for _ in 0..<100 {
    let mid = lo + (hi - lo) * 0.5
    if self.response_survival(mid) > target {
      lo = mid
    } else {
      hi = mid
    }
  }
  hi
}