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

Function getPiTerm

src/compute-engine/boxed-expression/utils.ts:281–321  ·  view source on GitHub ↗
(
  expr: Expression
)

Source from the content-addressed store, hash-verified

279 // opaque) — value-safe, and strictly better than silently corrupting.
280 const binders = collectBinderNames(body);
281 if (binders.size > 0) {
282 for (const name of Object.keys(substitution)) {
283 if (binders.has(name)) return undefined;
284 for (const s of substitution[name].symbols)
285 if (binders.has(s)) return undefined;
286 }
287 }
288
289 return body.subs(substitution);
290}
291
292/** Every name bound by a binder anywhere within `expr` (its own bound names
293 * plus those of every descendant), used to keep lambda inlining capture-safe. */
294export function collectBinderNames(
295 expr: Expression,
296 acc: Set<string> = new Set()
297): Set<string> {
298 if (!isFunction(expr)) return acc;
299 for (const n of boundVariableNames(expr)) acc.add(n);
300 for (const op of expr.ops) collectBinderNames(op, acc);
301 return acc;
302}
303
304/**
305 * Inline applications of user-defined functions throughout `expr`.
306 *
307 * A lazy operator holds its expression operand and takes only `.canonical`,
308 * which binds structure without substituting values. A call to a user-defined
309 * function therefore arrived as an opaque node that the algorithm could not
310 * see into: `Simplify(g(a))` returned `g(a)`, `Integrate(g(t), t)` stayed
311 * inert, and — worst — `Solve(g(x) = 0, x)` returned `[]`, which by contract
312 * means "proven no solutions".
313 *
314 * `budget` bounds the TOTAL number of beta-reductions so a self-recursive
315 * definition (`fact(n) = … fact(n - 1) …`) cannot loop forever, while a finite
316 * self-composition (`g(g(x))` for a non-recursive `g`) still fully expands — an
317 * on-path name guard would wrongly stop the inner `g(x)`, leaving `Solve` an
318 * opaque `g(x)` it reads as "no solutions". `budget` is a single object shared
319 * by reference across every branch of the traversal, so it is one global cap on
320 * the TOTAL number of beta-reductions in the whole tree — sibling calls
321 * (`g(a) + g(b)`) draw down the same counter rather than each getting a fresh
322 * budget. That shared cap is what bounds a self-recursive definition.
323 */
324// Generous enough that no realistic expression (a wide system of many function

Callers 1

canonicalAngleFunction · 0.85

Calls 10

isSymbolFunction · 0.90
isFunctionFunction · 0.90
isNumberFunction · 0.90
numericValueFunction · 0.90
_numericValueMethod · 0.65
negMethod · 0.65
addMethod · 0.65
mulMethod · 0.65
divMethod · 0.65
NMethod · 0.65

Tested by

no test coverage detected