use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ObjectiveKind {
BugFix,
Refactor,
SafetyHardening,
Performance,
Exploration,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ObjectivePolicy {
pub kind: ObjectiveKind,
pub correctness_weight: f64,
pub novelty_weight: f64,
pub stability_weight: f64,
pub allow_scalarization: bool,
pub min_trials_for_stability: u32,
}
impl ObjectivePolicy {
pub fn bug_fix() -> Self {
Self {
kind: ObjectiveKind::BugFix,
correctness_weight: 0.85,
novelty_weight: 0.05,
stability_weight: 0.10,
allow_scalarization: true,
min_trials_for_stability: 3,
}
}
pub fn refactor() -> Self {
Self {
kind: ObjectiveKind::Refactor,
correctness_weight: 0.70,
novelty_weight: 0.20,
stability_weight: 0.10,
allow_scalarization: true,
min_trials_for_stability: 3,
}
}
pub fn safety() -> Self {
Self {
kind: ObjectiveKind::SafetyHardening,
correctness_weight: 0.90,
novelty_weight: 0.0,
stability_weight: 0.10,
allow_scalarization: true,
min_trials_for_stability: 5,
}
}
pub fn performance() -> Self {
Self {
kind: ObjectiveKind::Performance,
correctness_weight: 0.60,
novelty_weight: 0.10,
stability_weight: 0.30,
allow_scalarization: false, min_trials_for_stability: 5,
}
}
pub fn exploration() -> Self {
Self {
kind: ObjectiveKind::Exploration,
correctness_weight: 0.50,
novelty_weight: 0.40,
stability_weight: 0.10,
allow_scalarization: false, min_trials_for_stability: 1,
}
}
pub fn compute_weighted_total(
&self,
correctness: f64,
novelty: f64,
stability: Option<f64>,
trial_count: u32,
) -> Option<f64> {
if !self.allow_scalarization {
return None;
}
let stability_val = if trial_count >= self.min_trials_for_stability {
stability.unwrap_or(0.0)
} else {
0.0 };
Some(
self.correctness_weight * correctness
+ self.novelty_weight * novelty
+ self.stability_weight * stability_val,
)
}
}
impl Default for ObjectivePolicy {
fn default() -> Self {
Self::refactor()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ComparabilityClass {
ComparableCore,
PatchOnlyDiagnostic,
Informational,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PlannedCheck {
pub check_kind: crate::exec::backend::CheckKind,
pub comparability: ComparabilityClass,
pub config_override: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PatchExecutionPlan {
pub checks: Vec<PlannedCheck>,
pub frozen: bool,
}
impl PatchExecutionPlan {
pub fn cargo_default() -> Self {
Self {
checks: vec![
PlannedCheck {
check_kind: crate::exec::backend::CheckKind::Fmt,
comparability: ComparabilityClass::ComparableCore,
config_override: false,
},
PlannedCheck {
check_kind: crate::exec::backend::CheckKind::Clippy,
comparability: ComparabilityClass::ComparableCore,
config_override: false,
},
PlannedCheck {
check_kind: crate::exec::backend::CheckKind::Test,
comparability: ComparabilityClass::ComparableCore,
config_override: false,
},
],
frozen: true,
}
}
pub fn comparable_checks(&self) -> Vec<&PlannedCheck> {
self.checks
.iter()
.filter(|c| c.comparability == ComparabilityClass::ComparableCore)
.collect()
}
}