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

Method int

src/compute-engine/rubi/driver.ts:184–262  ·  view source on GitHub ↗

Integrate `integrand` with respect to `variable`. Returns null when * no rule chain applies (caller decides on inert/fallback). * NOTE: the integrand must be canonical but NOT evaluated — evaluate() * expands products like (a+bx)(c+dx), destroying the structure the * rules match on.

(integrand: Expression, variable: string)

Source from the content-addressed store, hash-verified

182function hasInexactFloat(e: Expression): boolean {
183 if (e.isNumberLiteral) return (e as any).isExact === false;
184 return e.ops?.some(hasInexactFloat) ?? false;
185}
186
187function containsIntegrate(e: Expression): boolean {
188 if (e.operator === 'Integrate') return true;
189 return e.ops?.some(containsIntegrate) ?? false;
190}
191
192/** True if the expression tree contains an `Error` node — a rule RHS that
193 * failed to build a well-formed call (see the reject site in intUncached). */
194function containsError(e: Expression): boolean {
195 if (e.operator === 'Error') return true;
196 return e.ops?.some(containsError) ?? false;
197}
198
199/** All operator heads appearing in the (function nodes of the) expression
200 * tree — the integrand's "skeleton" feature set. Backs the second-level
201 * dispatch screen: a rule whose compiled `requiredHeads` are not all present
202 * here provably cannot match, so it is skipped without pattern-matching (see
203 * `compile.ts` `requiredHeads` for the soundness argument). Cheap: one walk
204 * per top-level integrand shape, reused across the whole rule scan. */
205function collectHeads(e: Expression, out: Set<string>): void {
206 if (!e.ops) return;
207 out.add(e.operator);
208 for (const op of e.ops) collectHeads(op, out);
209}
210
211/** Bottom-up application of the engine's trig simplifier — folds the
212 * `sin(θ+π/2) → cos(θ)` cofunction shifts the cosine→sine normalization
213 * introduces (and other sound trig identities) so results read cleanly. */
214function cleanTrig(ce: ComputeEngine, e: Expression): Expression {
215 if (!e.ops || e.ops.length === 0) return e;
216 const newOps = e.ops.map((o) => cleanTrig(ce, o));
217 const node = newOps.every((o, i) => o === e.ops![i])
218 ? e
219 : ce.function(e.operator, newOps);
220 const step = simplifyTrig(node as any);
221 return (step?.value as Expression) ?? node;
222}
223
224/**
225 * One recorded integration step, captured by the driver only when a `records`
226 * accumulator is threaded through `int()` (i.e. under `explain('Integrate')`).
227 *
228 * - `node` is an inert `Integrate(g, x)` in the driver's INTERNAL
229 * (deactivated / Times-Power normal-form) representation — the placeholder
230 * that this step replaces in the evolving replay state. It is built from the
231 * integrand as it ENTERS `intRec`, so it matches the placeholder the parent
232 * step wrote into its own `replacement`.
233 * - `replacement` is what takes its place: a template that itself contains
234 * inert sub-`Integrate` placeholders (structural / rule steps), or a final
235 * sub-result for opaque steps. `null` means "patch me later" (the template
236 * build failed and the real result is filled in on success).
237 * - `because` is the step id (a `rubi:<rule-id>` or an `integrate.*` phase id).
238 */
239export type IntStepRecord = {
240 node: Expression;
241 replacement: Expression | null;

Callers 6

loadIntegrationRulesFunction · 0.95
mainFunction · 0.95
buildFunction · 0.80
triage.tsFile · 0.80
runProblemFunction · 0.80

Calls 7

intRecMethod · 0.95
getActiveCachesFunction · 0.90
installCachesFunction · 0.90
hasActiveTrigFunction · 0.90
foldLnExponentialEFunction · 0.90
clearMethod · 0.65

Tested by

no test coverage detected