( ce: ComputeEngine, e: Entry, shellNames: Set<string>, seed: number )
| 229 | function hasErrorExpr(e: BoxedExpression): boolean { |
| 230 | if (e.operator === 'Error') return true; |
| 231 | if (isFunction(e)) return e.ops.some(hasErrorExpr); |
| 232 | return false; |
| 233 | } |
| 234 | |
| 235 | export function numericCheckEntry( |
| 236 | ce: ComputeEngine, |
| 237 | e: Entry, |
| 238 | shellNames: Set<string>, |
| 239 | seed: number |
| 240 | ): EntryNumericResult { |
| 241 | const t0 = Date.now(); |
| 242 | const base: EntryNumericResult = { |
| 243 | id: e.id, |
| 244 | topic: e.topic, |
| 245 | class: e.class, |
| 246 | guardLevel: e.guardLevel, |
| 247 | instances: [], |
| 248 | elapsedMs: 0, |
| 249 | }; |
| 250 | |
| 251 | // c·∞ passthrough evaluates to NaN by design — excluded (SPIKE §5) |
| 252 | if (e.directedInfinity) { |
| 253 | base.skipped = 'directed-infinity'; |
| 254 | base.elapsedMs = Date.now() - t0; |
| 255 | return base; |
| 256 | } |
| 257 | // Shell heads have no numeric kernel: nothing can evaluate |
| 258 | if (e.heads.some((h) => shellNames.has(h))) { |
| 259 | base.skipped = 'shell-head'; |
| 260 | base.elapsedMs = Date.now() - t0; |
| 261 | return base; |
| 262 | } |
| 263 | |
| 264 | return withEntryScope(ce, e, () => { |
| 265 | let formula: BoxedExpression; |
| 266 | let assumptions: BoxedExpression | null = null; |
| 267 | try { |
| 268 | formula = ce.expr(e.formula as any).canonical; |
| 269 | if (e.assumptions != null) |
| 270 | assumptions = ce.expr(e.assumptions as any).canonical; |
| 271 | // Without the Stage-1 compat widenings some entries don't box here |
| 272 | if (hasErrorExpr(formula) || (assumptions && hasErrorExpr(assumptions))) { |
| 273 | base.skipped = 'box-error'; |
| 274 | base.elapsedMs = Date.now() - t0; |
| 275 | return base; |
| 276 | } |
| 277 | } catch { |
| 278 | base.skipped = 'box-error'; |
| 279 | base.elapsedMs = Date.now() - t0; |
| 280 | return base; |
| 281 | } |
| 282 | |
| 283 | const domains = variableDomains(e); |
| 284 | const candidates = generateAssignments( |
| 285 | e.variables, |
| 286 | domains as Record<string, Json>, |
| 287 | (seed ^ hashString(e.id)) >>> 0, |
| 288 | MAX_CANDIDATES |
no test coverage detected