mdbench 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. mdbench-0.1.0/LICENSE +0 -0
  2. mdbench-0.1.0/PKG-INFO +237 -0
  3. mdbench-0.1.0/README.md +212 -0
  4. mdbench-0.1.0/mdbench.egg-info/PKG-INFO +237 -0
  5. mdbench-0.1.0/mdbench.egg-info/SOURCES.txt +73 -0
  6. mdbench-0.1.0/mdbench.egg-info/dependency_links.txt +1 -0
  7. mdbench-0.1.0/mdbench.egg-info/entry_points.txt +2 -0
  8. mdbench-0.1.0/mdbench.egg-info/requires.txt +17 -0
  9. mdbench-0.1.0/mdbench.egg-info/top_level.txt +1 -0
  10. mdbench-0.1.0/pyproject.toml +41 -0
  11. mdbench-0.1.0/setup.cfg +4 -0
  12. mdbench-0.1.0/src/cli/run.py +69 -0
  13. mdbench-0.1.0/src/core/__init__.py +8 -0
  14. mdbench-0.1.0/src/core/problem.py +81 -0
  15. mdbench-0.1.0/src/core/solution.py +25 -0
  16. mdbench-0.1.0/src/evaluate_result.py +690 -0
  17. mdbench-0.1.0/src/features/__init__.py +21 -0
  18. mdbench-0.1.0/src/features/answer.py +45 -0
  19. mdbench-0.1.0/src/features/evaluation/__init__.py +9 -0
  20. mdbench-0.1.0/src/features/evaluation/evaluation_package.py +103 -0
  21. mdbench-0.1.0/src/features/evaluation/mechanism_trace.py +162 -0
  22. mdbench-0.1.0/src/features/io/__init__.py +10 -0
  23. mdbench-0.1.0/src/features/io/load_problem.py +160 -0
  24. mdbench-0.1.0/src/features/io/load_submission.py +154 -0
  25. mdbench-0.1.0/src/features/io/solve_mechanism_equations.py +281 -0
  26. mdbench-0.1.0/src/features/sampling/__init__.py +5 -0
  27. mdbench-0.1.0/src/features/sampling/range_inferrer.py +45 -0
  28. mdbench-0.1.0/src/features/units/__init__.py +5 -0
  29. mdbench-0.1.0/src/features/units/unit_inference.py +130 -0
  30. mdbench-0.1.0/src/features/validation/__init__.py +14 -0
  31. mdbench-0.1.0/src/features/validation/mechanism_derivation.py +86 -0
  32. mdbench-0.1.0/src/features/validation/mechanism_fundamentality.py +208 -0
  33. mdbench-0.1.0/src/features/visualization/__init__.py +5 -0
  34. mdbench-0.1.0/src/features/visualization/mechanism_graph.py +258 -0
  35. mdbench-0.1.0/src/metrics/__init__.py +20 -0
  36. mdbench-0.1.0/src/metrics/formula_similarity.py +46 -0
  37. mdbench-0.1.0/src/metrics/hybrid_formula_similarity.py +232 -0
  38. mdbench-0.1.0/src/metrics/mechanism_fundamentality.py +116 -0
  39. mdbench-0.1.0/src/metrics/mechanism_similarity.py +225 -0
  40. mdbench-0.1.0/src/metrics/mechanism_simplicity.py +34 -0
  41. mdbench-0.1.0/src/prepare_problem.py +280 -0
  42. mdbench-0.1.0/src/synthetic_data.py +247 -0
  43. mdbench-0.1.0/src/utils/__init__.py +8 -0
  44. mdbench-0.1.0/src/utils/console.py +15 -0
  45. mdbench-0.1.0/src/utils/lazy_loader.py +37 -0
  46. mdbench-0.1.0/src/utils/llm/__init__.py +22 -0
  47. mdbench-0.1.0/src/utils/llm/core.py +69 -0
  48. mdbench-0.1.0/src/utils/llm/deepseek_api.py +111 -0
  49. mdbench-0.1.0/src/utils/llm/gemini_api.py +99 -0
  50. mdbench-0.1.0/src/utils/llm/llm_api.py +159 -0
  51. mdbench-0.1.0/src/utils/llm/manual_api.py +56 -0
  52. mdbench-0.1.0/src/utils/llm/openai_api.py +303 -0
  53. mdbench-0.1.0/src/utils/llm/openrouter_api.py +141 -0
  54. mdbench-0.1.0/src/utils/llm/siliconflow_api.py +175 -0
  55. mdbench-0.1.0/src/utils/llm/tool_call_mixin.py +80 -0
  56. mdbench-0.1.0/src/utils/log_exception.py +12 -0
  57. mdbench-0.1.0/src/utils/logger.py +330 -0
  58. mdbench-0.1.0/src/utils/path_utils.py +28 -0
  59. mdbench-0.1.0/src/utils/tag2ansi.py +165 -0
  60. mdbench-0.1.0/src/utils/unit_parser.py +48 -0
  61. mdbench-0.1.0/src/validate_problem.py +344 -0
  62. mdbench-0.1.0/src/visualize_mechanism.py +48 -0
  63. mdbench-0.1.0/tests/test_evaluation_modes.py +162 -0
  64. mdbench-0.1.0/tests/test_evaluation_trace.py +93 -0
  65. mdbench-0.1.0/tests/test_hybrid_formula_similarity.py +52 -0
  66. mdbench-0.1.0/tests/test_implicit_solver.py +261 -0
  67. mdbench-0.1.0/tests/test_load_problem.py +176 -0
  68. mdbench-0.1.0/tests/test_load_submission.py +140 -0
  69. mdbench-0.1.0/tests/test_mechanism_fundamentality.py +164 -0
  70. mdbench-0.1.0/tests/test_mechanism_graph.py +87 -0
  71. mdbench-0.1.0/tests/test_prepare_and_score.py +281 -0
  72. mdbench-0.1.0/tests/test_structural_mechanism_similarity.py +43 -0
  73. mdbench-0.1.0/tests/test_synthetic_data.py +68 -0
  74. mdbench-0.1.0/tests/test_unit_inference.py +81 -0
  75. mdbench-0.1.0/tests/test_validate_problem.py +154 -0
mdbench-0.1.0/LICENSE ADDED
File without changes
mdbench-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: mdbench
3
+ Version: 0.1.0
4
+ Summary: A benchmark for discovering scientific mechanisms
5
+ Requires-Python: >=3.12
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Requires-Dist: numpy>=1.24
9
+ Requires-Dist: PyYAML>=6.0
10
+ Requires-Dist: nd2py>=3.2.3
11
+ Requires-Dist: openai>=1.0
12
+ Requires-Dist: google-genai>=1.0
13
+ Requires-Dist: requests>=2.28
14
+ Requires-Dist: python-dotenv>=1.0
15
+ Requires-Dist: sympy>=1.13
16
+ Requires-Dist: scipy>=1.14
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest>=8.0; extra == "dev"
19
+ Requires-Dist: sphinx>=7.0; extra == "dev"
20
+ Requires-Dist: sphinx-book-theme>=1.1; extra == "dev"
21
+ Requires-Dist: myst-parser>=3.0; extra == "dev"
22
+ Requires-Dist: sphinx-autodoc-typehints>=2.0; extra == "dev"
23
+ Requires-Dist: build>=1.2; extra == "dev"
24
+ Dynamic: license-file
25
+
26
+ # MDBench
27
+
28
+ [简体中文](README.zh-CN.md)
29
+
30
+ MDBench evaluates whether an AI system can recover scientific laws and the
31
+ mechanisms that produce them from equations or observations.
32
+
33
+ ## What mechanism discovery means
34
+
35
+ MDBench treats a phenomenological equation as the observable consequence of
36
+ several simple, mutually consistent relationships. The phenomenological law
37
+ describes *what* variables do; a mechanism explains *why* through physical
38
+ relationships, assumptions, and intermediate variables.
39
+
40
+ For example, Kepler's third law for a circular orbit follows from gravitation,
41
+ Newton's second law, and uniform circular motion. See
42
+ [`problems/demo_problem.yaml`](problems/demo_problem.yaml).
43
+
44
+ Each mechanism relationship uses `variable = formula`, where the formula must
45
+ be parseable by [nd2py](https://pypi.org/project/nd2py/). Explicit relationships
46
+ form a DAG:
47
+
48
+ ```text
49
+ a = f1(x)
50
+ b = f2(x, a)
51
+ y = f3(x, a, b)
52
+ ```
53
+
54
+ Implicit systems are also supported. Relationships are collected until the
55
+ unknown variables form a closed system, then solved symbolically or with a
56
+ numerical root finder:
57
+
58
+ ```text
59
+ a = f1(x, a, b)
60
+ b = f2(x, a, b)
61
+ y = f3(x, a, b)
62
+ ```
63
+
64
+ All variables are declared under `variable_description` as `target`, `inputs`,
65
+ `intermediates`, or `auxiliary_inputs`. The latter are external variables used
66
+ only by the mechanism and eliminated from the final law. The original
67
+ relationships remain in `Problem.mechanism`; executable solution steps are
68
+ stored in `Problem.solution`.
69
+
70
+ ## Tasks and evaluation
71
+
72
+ MDBench provides three tasks:
73
+
74
+ 1. **Symbolic regression:** `(X, y) → phenomenological equation`.
75
+ 2. **Mechanism explanation:** phenomenological equation → mechanism equations.
76
+ 3. **Mechanism discovery:** `(X, y) → mechanism equations`.
77
+
78
+ Mechanism evaluation reports independent metrics and deliberately has no
79
+ overall score:
80
+
81
+ - **Prediction accuracy:** for symbolic regression and mechanism discovery,
82
+ Pearson correlation, R², MAE, RMSE, sMAPE, and tolerance accuracy on public
83
+ training data (feedback) or train/ID/OOD data (final).
84
+ - **Derived-equation equivalence:** final-only SymPy, numeric, and LLM
85
+ cross-check against the private phenomenological equation.
86
+ - **Mechanism fundamentality:** LLM assessment dominated by the least
87
+ fundamental submitted relationship; no reference answer is required.
88
+ - **Ground-truth structure recovery:** soft formula-AST and dependency-graph
89
+ matching against the reference mechanism. Variable names and numeric literal
90
+ values are ignored.
91
+ - **Mechanism description complexity:** reference-free mean, maximum, and total
92
+ nd2py AST nodes; lower values describe simpler submitted relationships.
93
+
94
+ Install MDBench with Python 3.12 or newer:
95
+
96
+ ```bash
97
+ pip install -e ".[dev]"
98
+ mdbench --help
99
+ ```
100
+
101
+ The Sphinx documentation lives in [`docs/`](docs/). Build it with:
102
+
103
+ ```bash
104
+ cd docs
105
+ make html
106
+ ```
107
+
108
+ ## Commands
109
+
110
+ All lifecycle commands accept one or more YAML files or directories through
111
+ `--problems`; the default is `./problems`.
112
+
113
+ ### Validate problems
114
+
115
+ Checks schemas, variable usage, units, sampling specifications, explicit and
116
+ implicit equation solving, and derivation of the target law:
117
+
118
+ ```bash
119
+ mdbench validate
120
+ mdbench validate --problems problems/demo_problem.yaml
121
+ ```
122
+
123
+ An optional LLM check evaluates whether every relationship is sufficiently
124
+ fundamental. API or response failures are reported directly and do not fall
125
+ back to heuristics.
126
+
127
+ ```bash
128
+ mdbench validate --check-fundamentality \
129
+ --llm-provider deepseek --llm-model deepseek-v4-flash
130
+ ```
131
+
132
+ ### Generate synthetic data
133
+
134
+ Creates reproducible train, ID-test, and OOD-test splits:
135
+
136
+ ```bash
137
+ mdbench synthetic --problems problems/ --output-dir data/synthetic_data/
138
+ ```
139
+
140
+ Each NPZ stores the three arrays, their row order in `variables`, and a JSON
141
+ `generation_config` containing the seed and sample counts. Auxiliary inputs are
142
+ generated here and may be hidden later during task preparation.
143
+
144
+ ### Prepare tasks
145
+
146
+ Synthetic data must already exist. Answers are private by default:
147
+
148
+ ```bash
149
+ mdbench prepare \
150
+ --problems problems/ \
151
+ --synthetic-data-dir data/synthetic_data/ \
152
+ --task mechanism_discovery \
153
+ --format directory
154
+ ```
155
+
156
+ Use `--save-answer` to include answers and test splits, `--reveal-auxiliary` to
157
+ expose auxiliary inputs in mechanism tasks, and `--force` to approve planned
158
+ overwrites. Existing directories are never cleared; redundant files are
159
+ reported. `--format directory` writes flat files, while `--format file` packs
160
+ the same logical artifacts into one NPZ.
161
+
162
+ ### Evaluate submissions
163
+
164
+ A submission may be an inline formula, semicolon-separated mechanism equations,
165
+ or a plain-text file with one equation per non-empty line. JSON and YAML
166
+ submissions are intentionally unsupported.
167
+
168
+ ```bash
169
+ mdbench evaluate \
170
+ --evaluation-mode feedback \
171
+ --problem data/problem/PREPARED_TASK \
172
+ --submission submission.txt \
173
+ --verbose
174
+ ```
175
+
176
+ Feedback mode uses only the public task and training data. Benchmark operators
177
+ run final evaluation with `--evaluation-mode final --answer answer.json`, which
178
+ also enables hidden ID/OOD tests and reference-mechanism recovery. For Agent
179
+ runs, copy only the prepared public task into an isolated temporary working
180
+ directory and require the Agent to remain there. Without source problem YAML or
181
+ private answer artifacts, the other lifecycle commands and final evaluation
182
+ cannot access the material they require. `--verbose` prints concise equation
183
+ chains for explicit or implicit solution steps.
184
+
185
+ Fundamentality scoring automatically uses the configured external model and
186
+ prints its provider and model:
187
+
188
+ ```bash
189
+ mdbench evaluate \
190
+ --evaluation-mode feedback \
191
+ --problem data/problem/PREPARED_TASK \
192
+ --submission submission.txt \
193
+ --llm-provider deepseek \
194
+ --llm-model deepseek-v4-flash
195
+ ```
196
+
197
+ Standalone entry points with equivalent behavior are available in `scripts/`:
198
+
199
+ ```text
200
+ validate_problem_main.py validate problem definitions
201
+ synthetic_data_main.py generate synthetic datasets
202
+ prepare_problem_main.py prepare public/private task artifacts
203
+ evaluate_result_main.py evaluate a submission
204
+ ```
205
+
206
+ `scripts/visualize_mechanism_main.py` renders a solved mechanism as DOT, SVG,
207
+ PNG, or PDF. Non-DOT formats require Graphviz.
208
+
209
+ ## Directory conventions
210
+
211
+ ```text
212
+ problems/ source problem YAML files
213
+ data/
214
+ synthetic_data/ generated train/ID/OOD datasets
215
+ problem/ prepared benchmark tasks
216
+ src/
217
+ core/ dependency-light data models
218
+ features/ project-specific I/O, solving, validation, sampling
219
+ metrics/ formula and mechanism metrics
220
+ utils/ reusable utilities and LLM clients
221
+ scripts/ standalone command entry points
222
+ tests/ unit tests and validation fixtures
223
+ ```
224
+
225
+ A prepared directory contains:
226
+
227
+ ```text
228
+ problem.json public task description
229
+ data_train.npy public training data
230
+ answer.json optional private answer
231
+ data_id_test.npy optional private ID test data
232
+ data_ood_test.npy optional private OOD test data
233
+ ```
234
+
235
+ Without `--save-answer`, only `problem.json` and `data_train.npy` are written.
236
+ Public interchange types remain simple: units are `Dict[str, int | float]`,
237
+ formulas are nd2py-compatible strings, and arrays use NumPy formats.
@@ -0,0 +1,212 @@
1
+ # MDBench
2
+
3
+ [简体中文](README.zh-CN.md)
4
+
5
+ MDBench evaluates whether an AI system can recover scientific laws and the
6
+ mechanisms that produce them from equations or observations.
7
+
8
+ ## What mechanism discovery means
9
+
10
+ MDBench treats a phenomenological equation as the observable consequence of
11
+ several simple, mutually consistent relationships. The phenomenological law
12
+ describes *what* variables do; a mechanism explains *why* through physical
13
+ relationships, assumptions, and intermediate variables.
14
+
15
+ For example, Kepler's third law for a circular orbit follows from gravitation,
16
+ Newton's second law, and uniform circular motion. See
17
+ [`problems/demo_problem.yaml`](problems/demo_problem.yaml).
18
+
19
+ Each mechanism relationship uses `variable = formula`, where the formula must
20
+ be parseable by [nd2py](https://pypi.org/project/nd2py/). Explicit relationships
21
+ form a DAG:
22
+
23
+ ```text
24
+ a = f1(x)
25
+ b = f2(x, a)
26
+ y = f3(x, a, b)
27
+ ```
28
+
29
+ Implicit systems are also supported. Relationships are collected until the
30
+ unknown variables form a closed system, then solved symbolically or with a
31
+ numerical root finder:
32
+
33
+ ```text
34
+ a = f1(x, a, b)
35
+ b = f2(x, a, b)
36
+ y = f3(x, a, b)
37
+ ```
38
+
39
+ All variables are declared under `variable_description` as `target`, `inputs`,
40
+ `intermediates`, or `auxiliary_inputs`. The latter are external variables used
41
+ only by the mechanism and eliminated from the final law. The original
42
+ relationships remain in `Problem.mechanism`; executable solution steps are
43
+ stored in `Problem.solution`.
44
+
45
+ ## Tasks and evaluation
46
+
47
+ MDBench provides three tasks:
48
+
49
+ 1. **Symbolic regression:** `(X, y) → phenomenological equation`.
50
+ 2. **Mechanism explanation:** phenomenological equation → mechanism equations.
51
+ 3. **Mechanism discovery:** `(X, y) → mechanism equations`.
52
+
53
+ Mechanism evaluation reports independent metrics and deliberately has no
54
+ overall score:
55
+
56
+ - **Prediction accuracy:** for symbolic regression and mechanism discovery,
57
+ Pearson correlation, R², MAE, RMSE, sMAPE, and tolerance accuracy on public
58
+ training data (feedback) or train/ID/OOD data (final).
59
+ - **Derived-equation equivalence:** final-only SymPy, numeric, and LLM
60
+ cross-check against the private phenomenological equation.
61
+ - **Mechanism fundamentality:** LLM assessment dominated by the least
62
+ fundamental submitted relationship; no reference answer is required.
63
+ - **Ground-truth structure recovery:** soft formula-AST and dependency-graph
64
+ matching against the reference mechanism. Variable names and numeric literal
65
+ values are ignored.
66
+ - **Mechanism description complexity:** reference-free mean, maximum, and total
67
+ nd2py AST nodes; lower values describe simpler submitted relationships.
68
+
69
+ Install MDBench with Python 3.12 or newer:
70
+
71
+ ```bash
72
+ pip install -e ".[dev]"
73
+ mdbench --help
74
+ ```
75
+
76
+ The Sphinx documentation lives in [`docs/`](docs/). Build it with:
77
+
78
+ ```bash
79
+ cd docs
80
+ make html
81
+ ```
82
+
83
+ ## Commands
84
+
85
+ All lifecycle commands accept one or more YAML files or directories through
86
+ `--problems`; the default is `./problems`.
87
+
88
+ ### Validate problems
89
+
90
+ Checks schemas, variable usage, units, sampling specifications, explicit and
91
+ implicit equation solving, and derivation of the target law:
92
+
93
+ ```bash
94
+ mdbench validate
95
+ mdbench validate --problems problems/demo_problem.yaml
96
+ ```
97
+
98
+ An optional LLM check evaluates whether every relationship is sufficiently
99
+ fundamental. API or response failures are reported directly and do not fall
100
+ back to heuristics.
101
+
102
+ ```bash
103
+ mdbench validate --check-fundamentality \
104
+ --llm-provider deepseek --llm-model deepseek-v4-flash
105
+ ```
106
+
107
+ ### Generate synthetic data
108
+
109
+ Creates reproducible train, ID-test, and OOD-test splits:
110
+
111
+ ```bash
112
+ mdbench synthetic --problems problems/ --output-dir data/synthetic_data/
113
+ ```
114
+
115
+ Each NPZ stores the three arrays, their row order in `variables`, and a JSON
116
+ `generation_config` containing the seed and sample counts. Auxiliary inputs are
117
+ generated here and may be hidden later during task preparation.
118
+
119
+ ### Prepare tasks
120
+
121
+ Synthetic data must already exist. Answers are private by default:
122
+
123
+ ```bash
124
+ mdbench prepare \
125
+ --problems problems/ \
126
+ --synthetic-data-dir data/synthetic_data/ \
127
+ --task mechanism_discovery \
128
+ --format directory
129
+ ```
130
+
131
+ Use `--save-answer` to include answers and test splits, `--reveal-auxiliary` to
132
+ expose auxiliary inputs in mechanism tasks, and `--force` to approve planned
133
+ overwrites. Existing directories are never cleared; redundant files are
134
+ reported. `--format directory` writes flat files, while `--format file` packs
135
+ the same logical artifacts into one NPZ.
136
+
137
+ ### Evaluate submissions
138
+
139
+ A submission may be an inline formula, semicolon-separated mechanism equations,
140
+ or a plain-text file with one equation per non-empty line. JSON and YAML
141
+ submissions are intentionally unsupported.
142
+
143
+ ```bash
144
+ mdbench evaluate \
145
+ --evaluation-mode feedback \
146
+ --problem data/problem/PREPARED_TASK \
147
+ --submission submission.txt \
148
+ --verbose
149
+ ```
150
+
151
+ Feedback mode uses only the public task and training data. Benchmark operators
152
+ run final evaluation with `--evaluation-mode final --answer answer.json`, which
153
+ also enables hidden ID/OOD tests and reference-mechanism recovery. For Agent
154
+ runs, copy only the prepared public task into an isolated temporary working
155
+ directory and require the Agent to remain there. Without source problem YAML or
156
+ private answer artifacts, the other lifecycle commands and final evaluation
157
+ cannot access the material they require. `--verbose` prints concise equation
158
+ chains for explicit or implicit solution steps.
159
+
160
+ Fundamentality scoring automatically uses the configured external model and
161
+ prints its provider and model:
162
+
163
+ ```bash
164
+ mdbench evaluate \
165
+ --evaluation-mode feedback \
166
+ --problem data/problem/PREPARED_TASK \
167
+ --submission submission.txt \
168
+ --llm-provider deepseek \
169
+ --llm-model deepseek-v4-flash
170
+ ```
171
+
172
+ Standalone entry points with equivalent behavior are available in `scripts/`:
173
+
174
+ ```text
175
+ validate_problem_main.py validate problem definitions
176
+ synthetic_data_main.py generate synthetic datasets
177
+ prepare_problem_main.py prepare public/private task artifacts
178
+ evaluate_result_main.py evaluate a submission
179
+ ```
180
+
181
+ `scripts/visualize_mechanism_main.py` renders a solved mechanism as DOT, SVG,
182
+ PNG, or PDF. Non-DOT formats require Graphviz.
183
+
184
+ ## Directory conventions
185
+
186
+ ```text
187
+ problems/ source problem YAML files
188
+ data/
189
+ synthetic_data/ generated train/ID/OOD datasets
190
+ problem/ prepared benchmark tasks
191
+ src/
192
+ core/ dependency-light data models
193
+ features/ project-specific I/O, solving, validation, sampling
194
+ metrics/ formula and mechanism metrics
195
+ utils/ reusable utilities and LLM clients
196
+ scripts/ standalone command entry points
197
+ tests/ unit tests and validation fixtures
198
+ ```
199
+
200
+ A prepared directory contains:
201
+
202
+ ```text
203
+ problem.json public task description
204
+ data_train.npy public training data
205
+ answer.json optional private answer
206
+ data_id_test.npy optional private ID test data
207
+ data_ood_test.npy optional private OOD test data
208
+ ```
209
+
210
+ Without `--save-answer`, only `problem.json` and `data_train.npy` are written.
211
+ Public interchange types remain simple: units are `Dict[str, int | float]`,
212
+ formulas are nd2py-compatible strings, and arrays use NumPy formats.
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: mdbench
3
+ Version: 0.1.0
4
+ Summary: A benchmark for discovering scientific mechanisms
5
+ Requires-Python: >=3.12
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ Requires-Dist: numpy>=1.24
9
+ Requires-Dist: PyYAML>=6.0
10
+ Requires-Dist: nd2py>=3.2.3
11
+ Requires-Dist: openai>=1.0
12
+ Requires-Dist: google-genai>=1.0
13
+ Requires-Dist: requests>=2.28
14
+ Requires-Dist: python-dotenv>=1.0
15
+ Requires-Dist: sympy>=1.13
16
+ Requires-Dist: scipy>=1.14
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest>=8.0; extra == "dev"
19
+ Requires-Dist: sphinx>=7.0; extra == "dev"
20
+ Requires-Dist: sphinx-book-theme>=1.1; extra == "dev"
21
+ Requires-Dist: myst-parser>=3.0; extra == "dev"
22
+ Requires-Dist: sphinx-autodoc-typehints>=2.0; extra == "dev"
23
+ Requires-Dist: build>=1.2; extra == "dev"
24
+ Dynamic: license-file
25
+
26
+ # MDBench
27
+
28
+ [简体中文](README.zh-CN.md)
29
+
30
+ MDBench evaluates whether an AI system can recover scientific laws and the
31
+ mechanisms that produce them from equations or observations.
32
+
33
+ ## What mechanism discovery means
34
+
35
+ MDBench treats a phenomenological equation as the observable consequence of
36
+ several simple, mutually consistent relationships. The phenomenological law
37
+ describes *what* variables do; a mechanism explains *why* through physical
38
+ relationships, assumptions, and intermediate variables.
39
+
40
+ For example, Kepler's third law for a circular orbit follows from gravitation,
41
+ Newton's second law, and uniform circular motion. See
42
+ [`problems/demo_problem.yaml`](problems/demo_problem.yaml).
43
+
44
+ Each mechanism relationship uses `variable = formula`, where the formula must
45
+ be parseable by [nd2py](https://pypi.org/project/nd2py/). Explicit relationships
46
+ form a DAG:
47
+
48
+ ```text
49
+ a = f1(x)
50
+ b = f2(x, a)
51
+ y = f3(x, a, b)
52
+ ```
53
+
54
+ Implicit systems are also supported. Relationships are collected until the
55
+ unknown variables form a closed system, then solved symbolically or with a
56
+ numerical root finder:
57
+
58
+ ```text
59
+ a = f1(x, a, b)
60
+ b = f2(x, a, b)
61
+ y = f3(x, a, b)
62
+ ```
63
+
64
+ All variables are declared under `variable_description` as `target`, `inputs`,
65
+ `intermediates`, or `auxiliary_inputs`. The latter are external variables used
66
+ only by the mechanism and eliminated from the final law. The original
67
+ relationships remain in `Problem.mechanism`; executable solution steps are
68
+ stored in `Problem.solution`.
69
+
70
+ ## Tasks and evaluation
71
+
72
+ MDBench provides three tasks:
73
+
74
+ 1. **Symbolic regression:** `(X, y) → phenomenological equation`.
75
+ 2. **Mechanism explanation:** phenomenological equation → mechanism equations.
76
+ 3. **Mechanism discovery:** `(X, y) → mechanism equations`.
77
+
78
+ Mechanism evaluation reports independent metrics and deliberately has no
79
+ overall score:
80
+
81
+ - **Prediction accuracy:** for symbolic regression and mechanism discovery,
82
+ Pearson correlation, R², MAE, RMSE, sMAPE, and tolerance accuracy on public
83
+ training data (feedback) or train/ID/OOD data (final).
84
+ - **Derived-equation equivalence:** final-only SymPy, numeric, and LLM
85
+ cross-check against the private phenomenological equation.
86
+ - **Mechanism fundamentality:** LLM assessment dominated by the least
87
+ fundamental submitted relationship; no reference answer is required.
88
+ - **Ground-truth structure recovery:** soft formula-AST and dependency-graph
89
+ matching against the reference mechanism. Variable names and numeric literal
90
+ values are ignored.
91
+ - **Mechanism description complexity:** reference-free mean, maximum, and total
92
+ nd2py AST nodes; lower values describe simpler submitted relationships.
93
+
94
+ Install MDBench with Python 3.12 or newer:
95
+
96
+ ```bash
97
+ pip install -e ".[dev]"
98
+ mdbench --help
99
+ ```
100
+
101
+ The Sphinx documentation lives in [`docs/`](docs/). Build it with:
102
+
103
+ ```bash
104
+ cd docs
105
+ make html
106
+ ```
107
+
108
+ ## Commands
109
+
110
+ All lifecycle commands accept one or more YAML files or directories through
111
+ `--problems`; the default is `./problems`.
112
+
113
+ ### Validate problems
114
+
115
+ Checks schemas, variable usage, units, sampling specifications, explicit and
116
+ implicit equation solving, and derivation of the target law:
117
+
118
+ ```bash
119
+ mdbench validate
120
+ mdbench validate --problems problems/demo_problem.yaml
121
+ ```
122
+
123
+ An optional LLM check evaluates whether every relationship is sufficiently
124
+ fundamental. API or response failures are reported directly and do not fall
125
+ back to heuristics.
126
+
127
+ ```bash
128
+ mdbench validate --check-fundamentality \
129
+ --llm-provider deepseek --llm-model deepseek-v4-flash
130
+ ```
131
+
132
+ ### Generate synthetic data
133
+
134
+ Creates reproducible train, ID-test, and OOD-test splits:
135
+
136
+ ```bash
137
+ mdbench synthetic --problems problems/ --output-dir data/synthetic_data/
138
+ ```
139
+
140
+ Each NPZ stores the three arrays, their row order in `variables`, and a JSON
141
+ `generation_config` containing the seed and sample counts. Auxiliary inputs are
142
+ generated here and may be hidden later during task preparation.
143
+
144
+ ### Prepare tasks
145
+
146
+ Synthetic data must already exist. Answers are private by default:
147
+
148
+ ```bash
149
+ mdbench prepare \
150
+ --problems problems/ \
151
+ --synthetic-data-dir data/synthetic_data/ \
152
+ --task mechanism_discovery \
153
+ --format directory
154
+ ```
155
+
156
+ Use `--save-answer` to include answers and test splits, `--reveal-auxiliary` to
157
+ expose auxiliary inputs in mechanism tasks, and `--force` to approve planned
158
+ overwrites. Existing directories are never cleared; redundant files are
159
+ reported. `--format directory` writes flat files, while `--format file` packs
160
+ the same logical artifacts into one NPZ.
161
+
162
+ ### Evaluate submissions
163
+
164
+ A submission may be an inline formula, semicolon-separated mechanism equations,
165
+ or a plain-text file with one equation per non-empty line. JSON and YAML
166
+ submissions are intentionally unsupported.
167
+
168
+ ```bash
169
+ mdbench evaluate \
170
+ --evaluation-mode feedback \
171
+ --problem data/problem/PREPARED_TASK \
172
+ --submission submission.txt \
173
+ --verbose
174
+ ```
175
+
176
+ Feedback mode uses only the public task and training data. Benchmark operators
177
+ run final evaluation with `--evaluation-mode final --answer answer.json`, which
178
+ also enables hidden ID/OOD tests and reference-mechanism recovery. For Agent
179
+ runs, copy only the prepared public task into an isolated temporary working
180
+ directory and require the Agent to remain there. Without source problem YAML or
181
+ private answer artifacts, the other lifecycle commands and final evaluation
182
+ cannot access the material they require. `--verbose` prints concise equation
183
+ chains for explicit or implicit solution steps.
184
+
185
+ Fundamentality scoring automatically uses the configured external model and
186
+ prints its provider and model:
187
+
188
+ ```bash
189
+ mdbench evaluate \
190
+ --evaluation-mode feedback \
191
+ --problem data/problem/PREPARED_TASK \
192
+ --submission submission.txt \
193
+ --llm-provider deepseek \
194
+ --llm-model deepseek-v4-flash
195
+ ```
196
+
197
+ Standalone entry points with equivalent behavior are available in `scripts/`:
198
+
199
+ ```text
200
+ validate_problem_main.py validate problem definitions
201
+ synthetic_data_main.py generate synthetic datasets
202
+ prepare_problem_main.py prepare public/private task artifacts
203
+ evaluate_result_main.py evaluate a submission
204
+ ```
205
+
206
+ `scripts/visualize_mechanism_main.py` renders a solved mechanism as DOT, SVG,
207
+ PNG, or PDF. Non-DOT formats require Graphviz.
208
+
209
+ ## Directory conventions
210
+
211
+ ```text
212
+ problems/ source problem YAML files
213
+ data/
214
+ synthetic_data/ generated train/ID/OOD datasets
215
+ problem/ prepared benchmark tasks
216
+ src/
217
+ core/ dependency-light data models
218
+ features/ project-specific I/O, solving, validation, sampling
219
+ metrics/ formula and mechanism metrics
220
+ utils/ reusable utilities and LLM clients
221
+ scripts/ standalone command entry points
222
+ tests/ unit tests and validation fixtures
223
+ ```
224
+
225
+ A prepared directory contains:
226
+
227
+ ```text
228
+ problem.json public task description
229
+ data_train.npy public training data
230
+ answer.json optional private answer
231
+ data_id_test.npy optional private ID test data
232
+ data_ood_test.npy optional private OOD test data
233
+ ```
234
+
235
+ Without `--save-answer`, only `problem.json` and `data_train.npy` are written.
236
+ Public interchange types remain simple: units are `Dict[str, int | float]`,
237
+ formulas are nd2py-compatible strings, and arrays use NumPy formats.