///|
/// Verify a caller-supplied report against source and enzyme models.
/// Replays recognition evidence, but checks fragments by coordinate traversal,
/// not by invoking the fragment generator. Does not certify biological behavior.
pub fn verify_digest(
  dna : Dna,
  enzymes : Array[Enzyme],
  report : Digest,
) -> Unit raise RestrictError {
  if report.source_length != dna.length() || report.topology != dna.topology {
    raise InvalidInput("VERIFY_SOURCE")
  }
  if report.fragments.length() > 10001 ||
    report.sites.length() > 10000 ||
    report.cuts.length() > 10000 {
    raise LimitExceeded("VERIFY_SIZE")
  }
  let reference = digest_many(dna, enzymes, policy=report.policy)
  if reference.sites != report.sites || reference.cuts != report.cuts {
    raise InvalidInput("VERIFY_EVIDENCE")
  }
  let boundaries : Array[Int] = []
  if dna.topology == Linear {
    boundaries.push(0)
    for cut in report.cuts {
      if cut.top > 0 && cut.top < dna.length() {
        boundaries.push(cut.top)
      }
    }
    boundaries.push(dna.length())
  } else if report.cuts.is_empty() {
    boundaries.push(0)
    boundaries.push(dna.length())
  } else {
    for cut in report.cuts {
      boundaries.push(cut.top)
    }
    boundaries.push(report.cuts[0].top + dna.length())
  }
  if report.fragments.length() != boundaries.length() - 1 {
    raise InvalidInput("VERIFY_FRAGMENT_COUNT")
  }
  let mut total = 0
  for i in 0..