///|
pub enum ConstraintStatus {
Satisfied
Violated
Inconclusive
} derive(Debug, Eq)
///|
pub struct GapConstraint {
name : String
minimum : Double
maximum : Double
} derive(Debug)
///|
pub fn GapConstraint::new(
name : String,
minimum : Double,
maximum : Double,
) -> GapConstraint {
if maximum < minimum {
abort("maximum must not be below minimum")
}
{ name, minimum, maximum }
}
///|
pub fn GapConstraint::evaluate(
self : GapConstraint,
result : AnalysisResult,
) -> ConstraintStatus {
if result.lower >= self.minimum && result.upper <= self.maximum {
Satisfied
} else if result.upper < self.minimum || result.lower > self.maximum {
Violated
} else {
Inconclusive
}
}
///|
pub struct ConstraintReport {
passed : Int
failed : Int
inconclusive : Int
statuses : Array[(String, ConstraintStatus)]
} derive(Debug)
///|
pub fn evaluate_constraints(
result : AnalysisResult,
constraints : Array[GapConstraint],
) -> ConstraintReport {
let mut passed = 0
let mut failed = 0
let mut inconclusive = 0
let statuses = constraints.map(c => {
let status = c.evaluate(result)
match status {
Satisfied => passed += 1
Violated => failed += 1
Inconclusive => inconclusive += 1
}
(c.name, status)
})
{ passed, failed, inconclusive, statuses }
}
///|
pub fn interval_contains(result : AnalysisResult, value : Double) -> Bool {
value >= result.lower && value <= result.upper
}
///|
pub fn interval_width(result : AnalysisResult) -> Double {
result.upper - result.lower
}
///|
pub fn result_to_csv(result : AnalysisResult) -> String {
let header = "nominal,lower,upper,mean,standard_deviation,yield_rate\n"
let values = "\{result.nominal},\{result.lower},\{result.upper},\{result.mean},"
let tail = "\{result.standard_deviation},\{result.yield_rate}\n"
header + values + tail
}