///|
/// Single-round improvement semantics.
///|
pub fn score_snapshot(
snapshot : MetricSnapshot,
policy : ImprovementPolicy,
) -> Double {
let mut score = 0.0
for objective in policy.objectives {
let value = lookup_metric(snapshot.metrics, objective.key)
let oriented = match objective.direction {
Maximize => value
Minimize => -value
}
score = score + oriented * objective.weight
}
score
}
///|
pub fn[T] run_improvement_loop(
baseline : MetricSnapshot,
policy : ImprovementPolicy,
candidates : Array[ImprovementCandidate[T]],
evaluate : (ImprovementCandidate[T], ImprovementContext[T]) -> Result[
MetricSnapshot,
String,
],
update_baseline_on_accept? : Bool = false,
) -> ImprovementReport[T] {
let base_score = score_snapshot(baseline, policy)
let mut current_baseline = baseline
let mut current_baseline_score = base_score
let results : Array[ImprovementResult[T]] = []
let accepted_results : Array[ImprovementResult[T]] = []
for i in 0.. {
let reasons = validate_snapshot(snapshot, policy, current_baseline)
let has_invalid = reasons.contains("invalid_snapshot")
let has_missing = has_missing_metric_reason(reasons)
let score = if has_invalid || has_missing {
None
} else {
Some(score_snapshot(snapshot, policy))
}
let score_delta = match score {
Some(v) => Some(v - current_baseline_score)
None => None
}
match score_delta {
Some(v) =>
if v < policy.min_score_delta {
reasons.push("score_delta_too_small")
}
None => ()
}
let accepted = reasons.length() == 0
let result : ImprovementResult[T] = {
candidate,
accepted,
reasons,
snapshot: Some(snapshot),
score,
score_delta,
error: None,
}
results.push(result)
if accepted {
accepted_results.push(result)
if update_baseline_on_accept {
current_baseline = snapshot
current_baseline_score = match score {
Some(v) => v
None => current_baseline_score
}
}
}
}
Err(message) =>
results.push({
candidate,
accepted: false,
reasons: ["evaluation_error"],
snapshot: None,
score: None,
score_delta: None,
error: Some(message),
})
}
}
let best_accepted = pick_best_accepted(results)
{ policy, baseline, baseline_score: base_score, results, best_accepted }
}
///|
fn lookup_metric(metrics : Map[String, Double], key : String) -> Double {
match metrics.get(key) {
Some(v) => v
None => abort("metric_missing:\{key}")
}
}
///|
fn validate_snapshot(
snapshot : MetricSnapshot,
policy : ImprovementPolicy,
baseline : MetricSnapshot,
) -> Array[String] {
let reasons : Array[String] = []
let mut invalid = false
for entry in snapshot.metrics.to_array() {
let key = entry.0
let value = entry.1
if !is_finite(value) {
invalid = true
reasons.push("invalid_metric:\{key}")
}
}
for objective in policy.objectives {
match snapshot.metrics.get(objective.key) {
Some(v) =>
if !is_finite(v) {
invalid = true
reasons.push("metric_missing:\{objective.key}")
}
None => {
invalid = true
reasons.push("metric_missing:\{objective.key}")
}
}
}
for constraint in policy.constraints {
match snapshot.metrics.get(constraint.key) {
None => {
invalid = true
reasons.push("metric_missing:\{constraint.key}")
}
Some(metric) =>
if !is_finite(metric) {
invalid = true
reasons.push("metric_missing:\{constraint.key}")
} else {
let baseline_value = match baseline.metrics.get(constraint.key) {
Some(v) => v
None => 0.0
}
match
to_constraint_target(constraint.source, metric, baseline_value) {
None => {
invalid = true
reasons.push("invalid_constraint_source:\{constraint.key}")
}
Some(target) =>
if !compare_metric(
target,
constraint.comparator,
constraint.value,
) {
reasons.push("constraint_failed:\{constraint.key}")
}
}
}
}
}
for entry in snapshot.gates.to_array() {
let gate = entry.0
let passed = entry.1
if !passed {
reasons.push("gate_failed:\{gate}")
}
}
if invalid {
let prefixed : Array[String] = ["invalid_snapshot"]
for reason in reasons {
prefixed.push(reason)
}
return dedupe_reasons(prefixed)
}
dedupe_reasons(reasons)
}
///|
fn has_missing_metric_reason(reasons : Array[String]) -> Bool {
for reason in reasons {
if reason.has_prefix("metric_missing:") {
return true
}
}
false
}
///|
fn compare_metric(
value : Double,
comparator : MetricComparator,
expected : Double,
) -> Bool {
match comparator {
Lt => value < expected
Lte => value <= expected
Gt => value > expected
Gte => value >= expected
Eq => value == expected
}
}
///|
fn to_constraint_target(
source : ConstraintSource,
metric : Double,
baseline : Double,
) -> Double? {
match source {
Absolute => Some(metric)
Delta => Some(metric - baseline)
Ratio => if baseline == 0.0 { None } else { Some(metric / baseline) }
DeltaRatio =>
if baseline == 0.0 {
None
} else {
Some((metric - baseline) / baseline)
}
}
}
///|
fn dedupe_reasons(reasons : Array[String]) -> Array[String] {
let seen : Map[String, Bool] = {}
let out : Array[String] = []
for reason in reasons {
if !seen.contains(reason) {
seen.set(reason, true)
out.push(reason)
}
}
out
}
///|
fn[T] pick_best_accepted(
results : Array[ImprovementResult[T]],
) -> ImprovementResult[T]? {
let mut best : ImprovementResult[T]? = None
let mut best_score = -1.0 / 0.0
for row in results {
if !row.accepted {
continue
}
match row.score {
None => ()
Some(score) =>
if score > best_score {
best_score = score
best = Some(row)
}
}
}
best
}
///|
fn is_finite(v : Double) -> Bool {
!v.is_nan() && !v.is_inf()
}