batuta/falsification/hypothesis_driven/
edd.rs1use 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
14pub 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 let has_emc = project_path.join("docs/emc/").exists()
32 || check_for_pattern(project_path, &["equation_model_card", "EMC", "governing_equation"]);
33
34 let has_math_docs =
36 check_for_pattern(project_path, &["derivation", "proof", "analytical_solution", "LaTeX"]);
37
38 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
65pub 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 let emc_dir = project_path.join("docs/emc/");
83 let has_emc_dir = emc_dir.exists();
84
85 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
127pub 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 let has_analytical_tests = check_for_pattern(
145 project_path,
146 &["analytical_solution", "exact_solution", "closed_form", "validate_against"],
147 );
148
149 let has_tolerance =
151 check_for_pattern(project_path, &["tolerance", "epsilon", "1e-6", "assert_relative_eq"]);
152
153 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}