( entries: ReadonlyArray<Entry>, declarations: Declarations )
| 1361 | }; |
| 1362 | |
| 1363 | return dfs(0) ? seed : null; |
| 1364 | } |
| 1365 | |
| 1366 | // --------------------------------------------------------------------------- |
| 1367 | // Pipeline |
| 1368 | // --------------------------------------------------------------------------- |
| 1369 | |
| 1370 | function referencesCompatHead(formula: MathJSON): boolean { |
| 1371 | const symbols = collectSymbols(formula); |
| 1372 | return Object.keys(COMPAT_OVERRIDES).some((h) => symbols.has(h)); |
| 1373 | } |
| 1374 | |
| 1375 | /** Create the scratch engine: stock CE + shells referenced by the entries (no compat widening). */ |
| 1376 | export function createScratchEngine( |
| 1377 | entries: ReadonlyArray<Entry>, |
| 1378 | declarations: Declarations |
| 1379 | ): ComputeEngine { |
| 1380 | const ce = new ComputeEngine(); |
| 1381 | ce.pushScope(undefined, 'fungrim-shells'); |
| 1382 | const referenced = new Set<string>(); |
| 1383 | for (const e of entries) { |
| 1384 | collectSymbols(e.formula, referenced); |
| 1385 | collectSymbols(e.assumptions, referenced); |
| 1386 | } |
| 1387 | for (const name of Object.keys(declarations.declarations).sort()) { |
| 1388 | if (!referenced.has(name)) continue; |
| 1389 | // Never shadow an engine built-in: a shell declaration in this scope |
| 1390 | // would hide the built-in's numeric evaluator and signature, making the |
| 1391 | // self-test environment diverge from the loader's (which skips shells |
| 1392 | // for already-defined names). Heads promoted to built-ins after the |
no test coverage detected