///|
/// 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..