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

Function build

src/compute-engine/rubi/rubi-utils.ts:52–108  ·  view source on GitHub ↗
(json: Json, ctx: Ctx)

Source from the content-addressed store, hash-verified

50// ---------------------------------------------------------------------------
51
52/** Structural ReplaceAll: return `u` with every subexpression structurally
53 * equal to `target` replaced by `replacement` (Mathematica `u /. target ->
54 * replacement`). Used by the general form of Rubi's `Subst` (see the Subst
55 * case in build). If `target` does not occur, `u` is returned unchanged — a
56 * safe outcome for the back-substitution rules, whose pre-substitution form
57 * differs from the intended one only by a branch-constant offset in the log
58 * argument (equal on the positive-real verification domain). */
59function replaceSubexpr(
60 u: Expression,
61 target: Expression,
62 replacement: Expression
63): Expression {
64 if (u.isSame(target)) return replacement;
65 const ops = u.ops;
66 if (!ops) return u;
67 let changed = false;
68 const newOps = ops.map((op) => {
69 const r = replaceSubexpr(op, target, replacement);
70 if (r !== op) changed = true;
71 return r;
72 });
73 if (!changed) return u;
74 return u.engine.function(u.operator, newOps);
75}
76
77export function build(json: Json, ctx: Ctx): Expression {
78 const { ce, env } = ctx;
79 if (typeof json === 'number') return ce.number(json);
80 if (typeof json === 'string') {
81 const bound = env.get(json);
82 if (bound !== undefined) return bound;
83 return ce.symbol(json);
84 }
85 const [head, ...args] = json;
86 if (typeof head !== 'string') return fail('non-symbol head in RHS');
87
88 switch (head) {
89 case 'Int': {
90 // Int[f, x] — recursive integration; an unsolved subproblem stays
91 // inert (reduction formulas legitimately leave residual integrals).
92 const f = build(args[0], ctx);
93 return ctx.hooks.int(f) ?? ce._fn('Integrate', [f, ce.symbol(ctx.x)]);
94 }
95 case 'Subst': {
96 // Subst[u, y, v]: integrate/transform u, then substitute y → v.
97 // When u is itself Int[…], a failed inner integration fails the
98 // rule (substituting into an inert integral is not useful).
99 if (args.length !== 3) return fail('Subst arity');
100 let u: Expression;
101 if (Array.isArray(args[0]) && args[0][0] === 'Int') {
102 const f = build((args[0] as Json[])[1], ctx);
103 const F = ctx.hooks.int(f);
104 // a residual inert Integrate inside F would have its integration
105 // variable substituted too, producing a malformed integral
106 if (F === null || F.has('Integrate'))
107 return fail('Subst: inner Int unsolved');
108 u = F;
109 } else u = build(args[0], ctx);

Callers 14

rtFunction · 0.90
rubi-utils.test.tsFile · 0.90
ddFunction · 0.90
fotFunction · 0.90
dispatchMethod · 0.90
eqDeltaFunction · 0.70
rubi-utils.tsFile · 0.70
cmpChainFunction · 0.70
intCmpFunction · 0.70
mapListFunction · 0.70
coeffFunction · 0.70
polyDivFunction · 0.70

Calls 13

failFunction · 0.85
evalConditionFunction · 0.85
intMethod · 0.80
numberMethod · 0.65
getMethod · 0.65
symbolMethod · 0.65
_fnMethod · 0.65
hasMethod · 0.65
evaluateMethod · 0.65
subsMethod · 0.65
exprMethod · 0.65
functionMethod · 0.65

Tested by 3

rtFunction · 0.72
ddFunction · 0.72
fotFunction · 0.72