MCPcopy Create free account
hub / github.com/cortex-js/compute-engine / isValidValueDef

Function isValidValueDef

src/compute-engine/boxed-expression/utils.ts:361–403  ·  view source on GitHub ↗
(def: unknown)

Source from the content-addressed store, hash-verified

359 * `Solve(s = 2, w)` with `s := (9 - w²)/4` saw an equation with no `w` in it
360 * and returned `[]` — which by contract means "proven no solutions". A
361 * coefficient symbol was already resolved further down the pipeline; only a
362 * binding that conceals the unknown was mishandled.
363 *
364 * Reads the *stored* value (`.value`), never `.evaluate()`: evaluating would
365 * resolve the unknown inside that value too (with `w := 7`, `s.evaluate()`
366 * would fold `w` away). `protect` holds the unknowns, so the variable being
367 * solved for is never substituted, and `seen` stops a self-referential or
368 * mutually-referential binding from looping.
369 */
370export function resolveBoundSymbols(
371 expr: Expression,
372 protect: ReadonlySet<string>,
373 seen: Set<string> = new Set()
374): Expression {
375 if (isSymbol(expr)) {
376 const name = expr.symbol;
377 if (protect.has(name) || seen.has(name)) return expr;
378 const def = expr.engine.lookupDefinition(name);
379 if (!isValueDef(def)) return expr;
380 const value = def.value.value;
381 if (value === undefined || value === null) return expr;
382 seen.add(name);
383 const resolved = resolveBoundSymbols(value, protect, seen);
384 seen.delete(name);
385 return resolved;
386 }
387
388 if (!isFunction(expr)) return expr;
389
390 // Binder-awareness: a `Function` literal, `Block`, `Sum`, etc. binds its own
391 // variables. Those must NOT be resolved to a same-named GLOBAL value —
392 // `Simplify(x ↦ x + 1)` with `x := 5` must stay `x ↦ x + 1`, not corrupt the
393 // body's bound `x` into `5`. Extend the protected set with the locally-bound
394 // names before descending. (`localScope` covers `Block`/`Sum`/`Product`/…;
395 // a `Function`'s parameters live in its operand slots, not its scope.)
396 const bound = boundVariableNames(expr);
397 const childProtect = bound.length ? new Set([...protect, ...bound]) : protect;
398
399 const ops = expr.ops;
400 const resolved = ops.map((op) => resolveBoundSymbols(op, childProtect, seen));
401 if (resolved.every((op, i) => op === ops[i])) return expr;
402 return expr.engine.function(expr.operator, resolved);
403}
404
405/**
406 * Replace `At(List(e₁, …, eₙ), k)` by `e_k` — a purely *structural*

Callers 3

declareFnFunction · 0.90
setSymbolDefinitionsFunction · 0.90
updateDefFunction · 0.85

Calls 2

isRecordFunction · 0.70
isExpressionFunction · 0.70

Tested by

no test coverage detected