///|
fn validate_prior(prior : Array[Double], n : Int32) -> Unit raise RunoffError {
  if prior.length() != n {
    raise Shape("prior count differs from triangle order")
  }
  for x in prior {
    nonnegative(x, "priors must be finite and nonnegative")
  }
}

///|
/// Prior is expected ultimate, not premium. No fitted exposure assumptions.
pub fn bornhuetter_ferguson(
  triangle : Triangle,
  pattern : Pattern,
  prior : Array[Double],
) -> Estimate raise RunoffError {
  compatible(triangle, pattern)
  validate_prior(prior, triangle.order())
  let out : Array[Double] = []
  for i in 0.. Estimate raise RunoffError {
  compatible(triangle, pattern)
  validate_prior(prior, triangle.order())
  if iterations < 1 || iterations > 1000 {
    raise Value("Benktander iterations must be 1..1000")
  }
  let mut current = prior.copy()
  for _ in 0..