sim-incremental-core 0.5.1

Dependency-light incremental query graph with memo cutoff and bounded snapshots.
Documentation
use std::collections::{BTreeMap, BTreeSet};

use sim_kernel::Datum;

use super::*;

const DENOMINATOR: usize = 40;

#[derive(Clone, Copy)]
enum Mutation {
    Declaration(usize),
    Edge(usize, usize),
}

fn fact(value: &str) -> FactId {
    FactId::new(value).unwrap()
}

fn conclusion(index: usize) -> ConclusionId {
    ConclusionId::new(format!("conclusion/{index:02}")).unwrap()
}

fn scenario_fact(index: usize) -> Option<FactId> {
    match index {
        1..=2 => Some(fact("change/private-implementation")),
        3..=10 => Some(fact("change/public-api")),
        11..=13 => Some(fact("change/head-a")),
        14..=16 => Some(fact("change/head-b")),
        17..=19 => Some(fact("change/head-c")),
        20..=22 => Some(fact("change/control-pins")),
        23..=24 => Some(fact("change/proof-code-alpha")),
        25..=26 => Some(fact("change/checker-alpha")),
        _ => None,
    }
}

fn changed_fact_candidates() -> Vec<FactId> {
    [
        "change/private-implementation",
        "change/public-api",
        "change/head-a",
        "change/head-b",
        "change/head-c",
        "change/control-pins",
        "change/proof-code-alpha",
        "change/checker-alpha",
    ]
    .map(fact)
    .to_vec()
}

fn closure(mutation: Option<Mutation>) -> FederatedClosure {
    let mut universe = changed_fact_candidates()
        .into_iter()
        .collect::<BTreeSet<_>>();
    universe.insert(fact("change/dormant"));
    let mut by_owner = BTreeMap::<String, Vec<(ConclusionId, BTreeSet<FactId>)>>::new();
    for index in 1..=DENOMINATOR {
        let base = fact(&format!("stable/{index:02}"));
        universe.insert(base.clone());
        let mut dependencies = BTreeSet::from([base]);
        if let Some(changed) = scenario_fact(index) {
            dependencies.insert(changed);
        }
        match mutation {
            Some(Mutation::Declaration(target)) if target == index => {
                if scenario_fact(index).is_some() {
                    continue;
                }
                dependencies.insert(fact("change/private-implementation"));
            }
            Some(Mutation::Edge(target, edge)) if target == index => {
                let original = dependencies.iter().nth(edge).unwrap().clone();
                dependencies.remove(&original);
                if original.as_str().starts_with("change/") {
                    dependencies.insert(fact("change/dormant"));
                } else {
                    let replacement = changed_fact_candidates()
                        .into_iter()
                        .find(|candidate| !dependencies.contains(candidate))
                        .unwrap();
                    dependencies.insert(replacement);
                }
            }
            _ => {}
        }
        by_owner
            .entry(format!("owner/{:02}", (index - 1) / 10 + 1))
            .or_default()
            .push((conclusion(index), dependencies));
    }
    let graphs = by_owner
        .into_iter()
        .map(|(owner, dependencies)| OwnerProjectionGraph::new(owner, dependencies).unwrap());
    FederatedClosure::seal(universe, graphs).unwrap()
}

fn affected(range: std::ops::RangeInclusive<usize>) -> BTreeSet<ConclusionId> {
    range.map(conclusion).collect()
}

fn expected_rows() -> Vec<ExpectedClosure> {
    vec![
        ExpectedClosure {
            delta: "D1".into(),
            denominator: DENOMINATOR,
            max_affected: 0,
            max_revision_delta: 0,
            carried_state: false,
            affected: BTreeSet::new(),
        },
        ExpectedClosure {
            delta: "D2".into(),
            denominator: DENOMINATOR,
            max_affected: 2,
            max_revision_delta: 1,
            carried_state: false,
            affected: affected(1..=2),
        },
        ExpectedClosure {
            delta: "D3".into(),
            denominator: DENOMINATOR,
            max_affected: 8,
            max_revision_delta: 1,
            carried_state: false,
            affected: affected(3..=10),
        },
        ExpectedClosure {
            delta: "D4".into(),
            denominator: DENOMINATOR,
            max_affected: 12,
            max_revision_delta: 4,
            carried_state: false,
            affected: affected(11..=22),
        },
        ExpectedClosure {
            delta: "D5".into(),
            denominator: DENOMINATOR,
            max_affected: 4,
            max_revision_delta: 2,
            carried_state: false,
            affected: affected(23..=26),
        },
        ExpectedClosure {
            delta: "D6".into(),
            denominator: DENOMINATOR,
            max_affected: 0,
            max_revision_delta: 1,
            carried_state: false,
            affected: BTreeSet::new(),
        },
    ]
}

fn expected() -> ExpectedClosureSet {
    let source = Datum::Bytes(vec![7]).content_id().unwrap();
    ExpectedClosureSet::freeze(source, expected_rows()).unwrap()
}

fn deltas() -> Vec<ControlledDelta> {
    vec![
        ControlledDelta::new("D1", ControlledDeltaClass::NoSemanticChange, [], 0, false).unwrap(),
        ControlledDelta::new(
            "D2",
            ControlledDeltaClass::PrivateImplementation,
            [fact("change/private-implementation")],
            1,
            false,
        )
        .unwrap(),
        ControlledDelta::new(
            "D3",
            ControlledDeltaClass::PublicApi,
            [fact("change/public-api")],
            1,
            false,
        )
        .unwrap(),
        ControlledDelta::new(
            "D4",
            ControlledDeltaClass::PublicHeadsAndPins,
            [
                fact("change/head-a"),
                fact("change/head-b"),
                fact("change/head-c"),
                fact("change/control-pins"),
            ],
            4,
            false,
        )
        .unwrap(),
        ControlledDelta::new(
            "D5",
            ControlledDeltaClass::ProofAndCheckerImplementation,
            [
                fact("change/proof-code-alpha"),
                fact("change/checker-alpha"),
            ],
            2,
            false,
        )
        .unwrap(),
        ControlledDelta::new("D6", ControlledDeltaClass::PresentationOnly, [], 1, false).unwrap(),
    ]
}

#[test]
fn six_predictions_match_the_frozen_oracle_and_state_denominators() {
    let closure = closure(None);
    let qualification = PredictedClosureAssay::new(&closure)
        .qualify(&deltas(), &expected())
        .unwrap();
    assert_eq!(qualification.reports.len(), 6);
    let d1 = &qualification.reports[0];
    let d2 = &qualification.reports[1];
    let d3 = &qualification.reports[2];
    let d4 = &qualification.reports[3];
    let d5 = &qualification.reports[4];
    let d6 = &qualification.reports[5];
    assert_eq!((d1.denominator, d1.unaffected_basis_points), (40, 10_000));
    assert_eq!((d2.denominator, d2.unaffected_basis_points), (40, 9_500));
    assert_eq!(d3.affected, affected(3..=10));
    assert_eq!((d4.denominator, d4.unaffected_basis_points), (40, 7_000));
    assert_eq!(d5.affected, affected(23..=26));
    assert_eq!(d1.work.planned_starts, 0);
    assert_eq!(d1.work.journal_records, 0);
    assert_eq!(d6.work.planned_starts, 0);
    assert_eq!(d6.work.journal_records, 0);
    assert_eq!((d1.revision_delta, d1.carried_state), (0, false));
    assert_eq!((d6.revision_delta, d6.carried_state), (1, false));
    assert!(
        qualification
            .reports
            .iter()
            .all(|report| report.denominator == 40)
    );
}

#[test]
fn every_projection_declaration_and_graph_edge_has_a_killing_mutant() {
    let expected = expected();
    let deltas = deltas();
    for declaration in 1..=DENOMINATOR {
        let mutant = closure(Some(Mutation::Declaration(declaration)));
        assert!(
            matches!(
                PredictedClosureAssay::new(&mutant).qualify(&deltas, &expected),
                Err(AssayError::RepairRequired(_))
            ),
            "declaration mutant {declaration} survived"
        );
    }
    for declaration in 1..=DENOMINATOR {
        let edge_count = usize::from(scenario_fact(declaration).is_some()) + 1;
        for edge in 0..edge_count {
            let mutant = closure(Some(Mutation::Edge(declaration, edge)));
            assert!(
                matches!(
                    PredictedClosureAssay::new(&mutant).qualify(&deltas, &expected),
                    Err(AssayError::RepairRequired(_))
                ),
                "edge mutant {declaration}:{edge} survived"
            );
        }
    }
}

#[test]
fn misses_emit_bounded_repairs_and_third_unchanged_epoch_needs_direction() {
    let mutant = closure(Some(Mutation::Declaration(1)));
    let AssayOutcome::Repair { repairs, .. } = PredictedClosureAssay::new(&mutant)
        .predict(&deltas()[1], &expected())
        .unwrap()
    else {
        panic!("mutant unexpectedly passed")
    };
    assert!(
        repairs
            .items
            .contains(&ProjectionRepairItem::Declaration(conclusion(1)))
    );
    let mut tracker = ProjectionRepairTracker::default();
    assert_eq!(tracker.record(&repairs), RepairDisposition::RepairEpoch(1));
    assert_eq!(tracker.record(&repairs), RepairDisposition::RepairEpoch(2));
    assert!(matches!(
        tracker.record(&repairs),
        RepairDisposition::NeedDirection(ArchitectureFaultReview { epochs: 3, .. })
    ));
    assert!(matches!(
        tracker.record(&repairs),
        RepairDisposition::NeedDirection(ArchitectureFaultReview { epochs: 3, .. })
    ));
}

#[test]
fn semantic_no_ops_and_incomplete_suites_fail_closed() {
    assert!(matches!(
        ControlledDelta::new(
            "D6",
            ControlledDeltaClass::PresentationOnly,
            [fact("change/public-api")],
            1,
            false
        ),
        Err(AssayError::SemanticNoOpCarriesChangedFacts(_))
    ));
    let closure = closure(None);
    assert!(matches!(
        PredictedClosureAssay::new(&closure).qualify(&deltas()[..5], &expected()),
        Err(AssayError::IncompleteDeltaSet(_))
    ));

    let mut wrong_class = deltas();
    wrong_class[0].class = ControlledDeltaClass::PrivateImplementation;
    assert!(matches!(
        PredictedClosureAssay::new(&closure).qualify(&wrong_class, &expected()),
        Err(AssayError::RepairRequired(_))
    ));

    let mut unknown_fact = deltas();
    unknown_fact[1]
        .changed_facts
        .insert(fact("change/unsealed"));
    let AssayOutcome::Repair { repairs, .. } = PredictedClosureAssay::new(&closure)
        .predict(&unknown_fact[1], &expected())
        .unwrap()
    else {
        panic!("unsealed changed fact unexpectedly passed")
    };
    assert!(repairs.items.contains(&ProjectionRepairItem::Contract(
        AssayContract::UnknownChangedFact
    )));

    let mut invalid_rows = expected_rows();
    invalid_rows[1].max_affected = 3;
    invalid_rows[1].affected.insert(conclusion(3));
    let source = Datum::Bytes(vec![8]).content_id().unwrap();
    assert!(matches!(
        ExpectedClosureSet::freeze(source, invalid_rows),
        Err(AssayError::InvalidExpectedClosure { .. })
    ));
}