///|
pub(all) struct DetailedConstraintAudit {
name : String
target : Double
value : Double
violation : Double
margin : Double
passed : Bool
severity : String
} derive(Debug, Eq, ToJson)
///|
pub(all) struct CandidateAudit {
candidate : DesignCandidate
constraints : Array[DetailedConstraintAudit]
feasible : Bool
total_violation : Double
minimum_margin : Double
status : String
} derive(Debug, Eq, ToJson)
///|
pub fn constraint_target(constraint : DesignConstraint) -> Double {
match constraint.kind {
AtLeast(target~) => target
AtMost(target~) => target
Equal(target~, ..) => target
}
}
///|
pub fn detailed_constraint_margin(
constraint : DesignConstraint,
value : Double,
) -> Double {
match constraint.kind {
AtLeast(target~) => value - target
AtMost(target~) => target - value
Equal(target~, tolerance~) => tolerance - (value - target).abs()
}
}
///|
pub fn audit_constraint(
constraint : DesignConstraint,
value : Double,
) -> DetailedConstraintAudit {
let violation = constraint.violation(value)
let margin = detailed_constraint_margin(constraint, value)
{
name: constraint.name,
target: constraint_target(constraint),
value,
violation,
margin,
passed: violation <= 0.0,
severity: if violation <= 0.0 {
"pass"
} else if violation <= constraint_target(constraint).abs().max(1.0) * 0.05 {
"notice"
} else {
"fail"
},
}
}
///|
pub fn audit_candidate_detailed(
candidate : DesignCandidate,
constraints : ArrayView[DesignConstraint],
) -> CandidateAudit raise @domain.ExtractionError {
if candidate.constraint_values.length() != constraints.length() {
raise @domain.ExtractionError::InvalidArgument(
message="candidate audit dimensions differ",
)
}
let audits = []
let mut minimum = 1.0e30
let mut total = 0.0
let mut feasible = true
for index in 0.. Bool {
audit.feasible && audit.minimum_margin >= minimum_margin
}
///|
pub fn audit_violations(
audit : CandidateAudit,
) -> Array[DetailedConstraintAudit] {
let result = []
for constraint in audit.constraints {
if !constraint.passed {
result.push(constraint)
}
}
result
}
///|
pub fn audit_passed(audit : CandidateAudit) -> Array[DetailedConstraintAudit] {
let result = []
for constraint in audit.constraints {
if constraint.passed {
result.push(constraint)
}
}
result
}
///|
pub fn audit_worst_constraint(
audit : CandidateAudit,
) -> DetailedConstraintAudit? {
if audit.constraints.length() == 0 {
None
} else {
let mut selected = audit.constraints[0]
for constraint in audit.constraints {
if constraint.margin < selected.margin {
selected = constraint
}
}
Some(selected)
}
}
///|
pub fn audit_summary(audit : CandidateAudit) -> String {
"status=" +
audit.status +
",constraints=" +
audit.constraints.length().to_string() +
",passed=" +
audit_passed(audit).length().to_string() +
",violations=" +
audit_violations(audit).length().to_string() +
",total_violation=" +
audit.total_violation.to_string() +
",minimum_margin=" +
audit.minimum_margin.to_string()
}
///|
pub fn audit_markdown(audit : CandidateAudit) -> String {
let lines = [
"| Constraint | Target | Value | Margin | Violation | Passed | Severity |", "|---|---:|---:|---:|---:|---|---|",
]
for constraint in audit.constraints {
lines.push(
"| " +
constraint.name +
" | " +
constraint.target.to_string() +
" | " +
constraint.value.to_string() +
" | " +
constraint.margin.to_string() +
" | " +
constraint.violation.to_string() +
" | " +
constraint.passed.to_string() +
" | " +
constraint.severity +
" |",
)
}
lines.join("\n")
}
///|
pub fn audit_csv(audit : CandidateAudit) -> String {
let lines = ["name,target,value,violation,margin,passed,severity"]
for constraint in audit.constraints {
lines.push(
constraint.name +
"," +
constraint.target.to_string() +
"," +
constraint.value.to_string() +
"," +
constraint.violation.to_string() +
"," +
constraint.margin.to_string() +
"," +
constraint.passed.to_string() +
"," +
constraint.severity,
)
}
lines.join("\n")
}
///|
pub fn candidate_audits(
candidates : ArrayView[DesignCandidate],
constraints : ArrayView[DesignConstraint],
) -> Array[CandidateAudit] raise @domain.ExtractionError {
let result = []
for candidate in candidates {
result.push(audit_candidate_detailed(candidate, constraints))
}
result
}
///|
pub fn feasible_audits(
audits : ArrayView[CandidateAudit],
) -> Array[CandidateAudit] {
let result = []
for audit in audits {
if audit.feasible {
result.push(audit)
}
}
result
}
///|
pub fn robust_audits(
audits : ArrayView[CandidateAudit],
minimum_margin : Double,
) -> Array[CandidateAudit] {
let result = []
for audit in audits {
if audit_is_robust(audit, minimum_margin) {
result.push(audit)
}
}
result
}
///|
pub fn minimum_candidate_margin(audits : ArrayView[CandidateAudit]) -> Double {
if audits.length() == 0 {
return 0.0
}
let mut result = audits[0].minimum_margin
for audit in audits {
result = result.min(audit.minimum_margin)
}
result
}
///|
pub fn maximum_candidate_violation(
audits : ArrayView[CandidateAudit],
) -> Double {
let mut result = 0.0
for audit in audits {
result = result.max(audit.total_violation)
}
result
}
///|
pub fn audit_objective(audit : CandidateAudit) -> Double {
audit.candidate.objective + audit.total_violation * 1.0e6
}
///|
pub fn best_audit(audits : ArrayView[CandidateAudit]) -> CandidateAudit? {
if audits.length() == 0 {
return None
}
let mut best = audits[0]
for audit in audits {
if audit_objective(audit) < audit_objective(best) {
best = audit
}
}
Some(best)
}
///|
pub fn audit_constraint_count(audit : CandidateAudit, passed : Bool) -> Int {
if passed {
audit_passed(audit).length()
} else {
audit_violations(audit).length()
}
}
///|
pub fn audit_margin_vector(audit : CandidateAudit) -> Array[Double] {
[
for constraint in audit.constraints => constraint.margin
]
}
///|
pub fn audit_violation_vector(audit : CandidateAudit) -> Array[Double] {
[
for constraint in audit.constraints => constraint.violation
]
}
///|
pub fn audit_status_code(audit : CandidateAudit) -> Int {
match audit.status {
"feasible" => 0
"near-feasible" => 1
_ => 2
}
}
///|
pub fn audit_has_critical_failure(audit : CandidateAudit) -> Bool {
for constraint in audit.constraints {
if constraint.severity == "fail" {
return true
}
}
false
}
///|
pub fn audit_recommendation(audit : CandidateAudit) -> String {
if audit.feasible && audit.minimum_margin > 0.1 {
"accept"
} else if audit.feasible {
"monitor"
} else if audit.total_violation < 0.05 {
"refine"
} else {
"reject"
}
}