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

Function normalizeRule

scripts/rubi/extract-rules.ts:164–232  ·  view source on GitHub ↗
(index: number, expr: Json, source: string)

Source from the content-addressed store, hash-verified

162}
163
164function normalizeRule(index: number, expr: Json, source: string): RubiRule {
165 const setDelayed = asCall(expr, 'SetDelayed');
166 if (!setDelayed) throw new Error('rule is not a SetDelayed definition');
167 const [, lhsCall, rhsExpr] = setDelayed;
168
169 const int = asCall(lhsCall, 'Int');
170 if (!int || int.length !== 3) throw new Error('LHS is not Int[…, x_Symbol]');
171 const [, lhs, varPat] = int;
172 // The integration-variable slot is `x_Symbol` or plain `x_`.
173 const blank = asCall(varPat, 'Blank');
174 if (
175 !blank ||
176 typeof blank[1] !== 'string' ||
177 blank[1] === '' ||
178 (blank[2] !== undefined && blank[2] !== 'Symbol')
179 )
180 throw new Error('integration variable is not an x_/x_Symbol pattern');
181 const variable = blank[1];
182
183 // Outer condition: rhs = Condition[body, cond]
184 let body = rhsExpr;
185 let condition: Json | null = null;
186 const outerCond = asCall(body, 'Condition');
187 if (outerCond) {
188 body = outerCond[1];
189 condition = outerCond[2];
190 }
191
192 // With/Module scope (possibly nested) with optional inner condition
193 const bindings: RubiRule['bindings'] = [];
194 let scoped: RubiRule['scoped'] = null;
195 let innerCondition: Json | null = null;
196 for (;;) {
197 const scope = asCall(body, 'With') ?? asCall(body, 'Module');
198 if (!scope) break;
199 if (scope.length !== 3)
200 throw new Error(`${scope[0]} with ${scope.length - 1} arguments`);
201 scoped = scoped ?? ((scope[0] === 'With' ? 'with' : 'module') as const);
202 const locals = asCall(scope[1], 'List');
203 if (!locals) throw new Error(`${scope[0]} locals are not a List`);
204 for (const local of locals.slice(1)) {
205 const set = asCall(local, 'Set');
206 if (set && typeof set[1] === 'string')
207 bindings.push({ name: set[1], value: set[2] });
208 else if (typeof local === 'string')
209 bindings.push({ name: local, value: null });
210 else throw new Error('unsupported local binding form');
211 }
212 body = scope[2];
213 const inner = asCall(body, 'Condition');
214 if (inner) {
215 body = inner[1];
216 innerCondition =
217 innerCondition === null ? inner[2] : ['And', innerCondition, inner[2]];
218 }
219 }
220
221 return {

Callers 1

extractRulesFunction · 0.85

Calls 2

asCallFunction · 0.85
sliceMethod · 0.65

Tested by

no test coverage detected