| 142 | // Shared by the warm-up pass and the measured loop, so both exercise the |
| 143 | // identical code path. |
| 144 | function buildOp(ce, kase) { |
| 145 | const input = kase.inputs.ce; |
| 146 | ce.precision = DEFAULT_PRECISION; // reset per case (the N-decimal branch overrides it) |
| 147 | switch (input.op) { |
| 148 | case 'N': |
| 149 | if (kase.verify.kind === 'integer') return () => ce.expr(input.mathjson).evaluate(); |
| 150 | ce.precision = input.precision; |
| 151 | return () => ce.expr(input.mathjson).N(); |
| 152 | case 'simplify': |
| 153 | return () => ce.expr(input.mathjson).simplify(); |
| 154 | case 'diff': |
| 155 | return () => ce.expr(['D', input.mathjson, input.var]).evaluate(); |
| 156 | case 'integrate': |
| 157 | // loadIntegrationRules routes Integrate through Rubi (then falls back to |
| 158 | // the built-in integrator), so a plain evaluate() exercises the full stack. |
| 159 | return () => ce.expr(['Integrate', input.mathjson, ['Tuple', input.var]]).evaluate(); |
| 160 | case 'evaluate': |
| 161 | return () => ce.expr(input.mathjson).evaluate(); |
| 162 | case 'solve': |
| 163 | return () => ce.expr(input.mathjson).solve(input.var); |
| 164 | default: |
| 165 | return null; |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | // Run one case on one engine and return its result object (no id/tool — those |
| 170 | // are added by emit). Precision is reset per call so cases stay independent. |