Skip to main content

batuta/falsification/hypothesis_driven/
edd.rs

1//! EDD (Equation-Driven Development) Checks (EDD-01 through EDD-03)
2//!
3//! These checks focus on equation verification and validation:
4//! - Equation verification before implementation
5//! - Equation Model Card (EMC) completeness
6//! - Numerical vs analytical validation
7
8use super::helpers::check_for_pattern;
9use crate::falsification::helpers::{apply_check_outcome, CheckOutcome};
10use crate::falsification::types::{CheckItem, Evidence, EvidenceType, Severity};
11use std::path::Path;
12use std::time::Instant;
13
14/// EDD-01: Equation Verification Before Implementation
15///
16/// **Claim:** Every simulation has analytically verified governing equation.
17///
18/// **Rejection Criteria (Major):**
19/// - Simulation without EMC or analytical derivation
20pub fn check_equation_verification(project_path: &Path) -> CheckItem {
21    let start = Instant::now();
22    let mut item = CheckItem::new(
23        "EDD-01",
24        "Equation Verification Before Implementation",
25        "Simulations have verified governing equations",
26    )
27    .with_severity(Severity::Major)
28    .with_tps("EDD - prove first, implement second");
29
30    // Check for EMC (Equation Model Cards)
31    let has_emc = project_path.join("docs/emc/").exists()
32        || check_for_pattern(project_path, &["equation_model_card", "EMC", "governing_equation"]);
33
34    // Check for mathematical documentation
35    let has_math_docs =
36        check_for_pattern(project_path, &["derivation", "proof", "analytical_solution", "LaTeX"]);
37
38    // Check for simulation code
39    let has_simulation =
40        check_for_pattern(project_path, &["simulate", "Simulator", "physics", "dynamics"]);
41
42    item = item.with_evidence(Evidence {
43        evidence_type: EvidenceType::StaticAnalysis,
44        description: format!(
45            "EDD: emc={}, math_docs={}, simulation={}",
46            has_emc, has_math_docs, has_simulation
47        ),
48        data: None,
49        files: Vec::new(),
50    });
51
52    item = apply_check_outcome(
53        item,
54        &[
55            (!has_simulation, CheckOutcome::Pass),
56            (has_emc && has_math_docs, CheckOutcome::Pass),
57            (has_emc || has_math_docs, CheckOutcome::Partial("Partial equation documentation")),
58            (true, CheckOutcome::Partial("Simulation without equation verification")),
59        ],
60    );
61
62    item.finish_timed(start)
63}
64
65/// EDD-02: Equation Model Card (EMC) Completeness
66///
67/// **Claim:** Every shared simulation includes complete EMC.
68///
69/// **Rejection Criteria (Major):**
70/// - EMC missing required sections
71pub fn check_emc_completeness(project_path: &Path) -> CheckItem {
72    let start = Instant::now();
73    let mut item = CheckItem::new(
74        "EDD-02",
75        "Equation Model Card Completeness",
76        "Simulations include complete EMC",
77    )
78    .with_severity(Severity::Major)
79    .with_tps("Governance - equation traceability");
80
81    // Check for EMC directory
82    let emc_dir = project_path.join("docs/emc/");
83    let has_emc_dir = emc_dir.exists();
84
85    // Check EMC completeness (governing equations, validity, derivation, stability, tests)
86    let required_sections = ["governing", "validity", "derivation", "stability", "verification"];
87
88    let mut sections_found = 0;
89    if let Ok(entries) = glob::glob(&format!("{}/**/*.md", project_path.display())) {
90        for entry in entries.flatten() {
91            if let Ok(content) = std::fs::read_to_string(&entry) {
92                for section in &required_sections {
93                    if content.to_lowercase().contains(section) {
94                        sections_found += 1;
95                    }
96                }
97            }
98        }
99    }
100
101    item = item.with_evidence(Evidence {
102        evidence_type: EvidenceType::StaticAnalysis,
103        description: format!(
104            "EMC: dir={}, sections_found={}/{}",
105            has_emc_dir,
106            sections_found,
107            required_sections.len()
108        ),
109        data: None,
110        files: Vec::new(),
111    });
112
113    let has_simulation = check_for_pattern(project_path, &["simulate", "Simulator"]);
114    item = apply_check_outcome(
115        item,
116        &[
117            (!has_simulation, CheckOutcome::Pass),
118            (has_emc_dir && sections_found >= 4, CheckOutcome::Pass),
119            (sections_found >= 2, CheckOutcome::Partial("Partial EMC documentation")),
120            (true, CheckOutcome::Partial("Missing EMC documentation")),
121        ],
122    );
123
124    item.finish_timed(start)
125}
126
127/// EDD-03: Numerical vs Analytical Validation
128///
129/// **Claim:** Simulation results match analytical solutions within tolerance.
130///
131/// **Rejection Criteria (Major):**
132/// - Numerical-analytical deviation >1e-6
133pub fn check_numerical_analytical_validation(project_path: &Path) -> CheckItem {
134    let start = Instant::now();
135    let mut item = CheckItem::new(
136        "EDD-03",
137        "Numerical vs Analytical Validation",
138        "Simulation matches analytical solutions",
139    )
140    .with_severity(Severity::Major)
141    .with_tps("Verification - known solutions");
142
143    // Check for analytical validation tests
144    let has_analytical_tests = check_for_pattern(
145        project_path,
146        &["analytical_solution", "exact_solution", "closed_form", "validate_against"],
147    );
148
149    // Check for tolerance specification
150    let has_tolerance =
151        check_for_pattern(project_path, &["tolerance", "epsilon", "1e-6", "assert_relative_eq"]);
152
153    // Check for verification test suite
154    let has_verification = check_for_pattern(
155        project_path,
156        &["verification_test", "numerical_validation", "convergence_test"],
157    );
158
159    item = item.with_evidence(Evidence {
160        evidence_type: EvidenceType::StaticAnalysis,
161        description: format!(
162            "Validation: analytical={}, tolerance={}, verification={}",
163            has_analytical_tests, has_tolerance, has_verification
164        ),
165        data: None,
166        files: Vec::new(),
167    });
168
169    let has_simulation = check_for_pattern(project_path, &["simulate", "numerical"]);
170    item = apply_check_outcome(
171        item,
172        &[
173            (!has_simulation, CheckOutcome::Pass),
174            (has_analytical_tests && has_tolerance, CheckOutcome::Pass),
175            (
176                has_verification || has_analytical_tests,
177                CheckOutcome::Partial("Some validation (verify tolerance)"),
178            ),
179            (true, CheckOutcome::Partial("Numerical code without analytical validation")),
180        ],
181    );
182
183    item.finish_timed(start)
184}