xlog-logic 0.9.2

Parser, compiler, and optimizer for XLOG logic programs
Documentation
use xlog_logic::{
    diagnose_module_boundaries, CandidateSourceKind, ModuleBoundaryInput, ModuleDeclaration,
    ModuleManifest, ModuleRole, ModuleViolationKind,
};

#[test]
fn adapter_only_fact_modules_pass_boundary_diagnostics() {
    let report = diagnose_module_boundaries(ModuleBoundaryInput {
        modules: vec![
            ModuleManifest::new("bfo", ModuleRole::FrozenKernel, ["entity", "root_cause"]),
            ModuleManifest::new("cyber", ModuleRole::AdapterOnly, ["cyber_fact"])
                .with_held_out(false),
        ],
        declarations: vec![
            ModuleDeclaration::fact("cyber", "cyber_fact"),
            ModuleDeclaration::candidate_source(
                "cyber",
                "cyber_fact",
                CandidateSourceKind::TrainingEvidence,
            ),
        ],
    });

    assert!(report.passed());
    assert!(report.violations.is_empty());
}

#[test]
fn diagnostics_fail_when_adapter_mutates_frozen_kernel_or_leaks_held_out_labels() {
    let report = diagnose_module_boundaries(ModuleBoundaryInput {
        modules: vec![
            ModuleManifest::new("bfo", ModuleRole::FrozenKernel, ["entity", "root_cause"]),
            ModuleManifest::new("heldout", ModuleRole::AdapterOnly, ["heldout_fact"])
                .with_held_out(true),
        ],
        declarations: vec![
            ModuleDeclaration::rule("heldout", "root_cause"),
            ModuleDeclaration::candidate_source(
                "heldout",
                "root_cause",
                CandidateSourceKind::HeldOutLabel,
            ),
        ],
    });

    assert!(!report.passed());
    assert!(report
        .violations
        .iter()
        .any(|v| v.kind == ModuleViolationKind::FrozenKernelMutation));
    assert!(report
        .violations
        .iter()
        .any(|v| v.kind == ModuleViolationKind::HeldOutLeakage));
}