Skip to content

Commit 1d40f21

Browse files
committed
arch: the great renaming part 2
1 parent f419bc4 commit 1d40f21

139 files changed

Lines changed: 2795 additions & 2792 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,48 @@
44

55
This release includes several breaking changes to the public API.
66

7-
The most significant is the restructuring of the `BoxedExpression` class
8-
hierarchy and the introduction of type-guarded role interfaces, which improves
9-
type safety and API ergonomics but requires updates to code that accessed
10-
role-specific properties directly on `BoxedExpression` instances.
7+
The most significant is the restructuring of the `Expression` type hierarchy and
8+
the introduction of type-guarded role interfaces, which improves type safety and
9+
API ergonomics but requires updates to code that accessed role-specific
10+
properties directly on expression instances.
11+
12+
#### Naming Alignment: `Expression`, `MathJsonExpression`, and `ExpressionInput`
13+
14+
- The compute-engine runtime type is now `Expression` (preferred name).
15+
`BoxedExpression` is retained as a deprecated alias for migration.
16+
- The MathJSON type is now `MathJsonExpression` (the old MathJSON `Expression`
17+
name has been removed from the `math-json` entrypoint).
18+
- `SemiBoxedExpression` is now `ExpressionInput` (with a deprecated alias for
19+
migration).
1120

1221
#### Role-Specific Properties Moved to Type-Guarded Interfaces
1322

14-
Properties that were previously on all `BoxedExpression` instances (returning
23+
Properties that were previously on all `Expression` instances (returning
1524
`undefined` when not applicable) have been moved to role interfaces. They are
1625
now only accessible after narrowing with a type guard.
1726

18-
| Removed from `BoxedExpression` | Access via |
19-
| :------------------------------------ | :--------------------------------------------- |
20-
| `.symbol` | `isBoxedSymbol(expr)` then `expr.symbol` |
21-
| `.string` | `isBoxedString(expr)` then `expr.string` |
22-
| `.ops`, `.nops`, `.op1`/`.op2`/`.op3` | `isBoxedFunction(expr)` then `expr.ops` etc. |
23-
| `.numericValue`, `.isNumberLiteral` | `isBoxedNumber(expr)` then `expr.numericValue` |
24-
| `.tensor` | `isBoxedTensor(expr)` then `expr.tensor` |
27+
| Removed from `Expression` | Access via |
28+
| :------------------------------------ | :---------------------------------------- |
29+
| `.symbol` | `isSymbol(expr)` then `expr.symbol` |
30+
| `.string` | `isString(expr)` then `expr.string` |
31+
| `.ops`, `.nops`, `.op1`/`.op2`/`.op3` | `isFunction(expr)` then `expr.ops` etc. |
32+
| `.numericValue`, `.isNumberLiteral` | `isNumber(expr)` then `expr.numericValue` |
33+
| `.tensor` | `isTensor(expr)` then `expr.tensor` |
2534

2635
```ts
2736
// Before
2837
if (expr.symbol !== null) console.log(expr.symbol);
2938

3039
// After
31-
import { isBoxedSymbol, sym } from '@cortex-js/compute-engine';
40+
import { isSymbol, sym } from '@cortex-js/compute-engine';
3241

33-
if (isBoxedSymbol(expr)) console.log(expr.symbol);
42+
if (isSymbol(expr)) console.log(expr.symbol);
3443
// or use the convenience helper:
3544
if (sym(expr) === 'Pi') { /* ... */ }
3645
```
3746

38-
Properties that remain on `BoxedExpression`: `.operator`, `.re`/`.im`, `.shape`,
39-
all arithmetic methods (`.add()`, `.mul()`, etc.), and all numeric predicates
47+
Properties that remain on `Expression`: `.operator`, `.re`/`.im`, `.shape`, all
48+
arithmetic methods (`.add()`, `.mul()`, etc.), and all numeric predicates
4049
(`.isPositive`, `.isInteger`, etc.).
4150

4251
#### Expression Creation: `form` Replaces `canonical`/`structural`
@@ -70,7 +79,7 @@ evaluate('x + 2'); // 5
7079
```
7180

7281
Except for `parse()` (which only accepts a LaTeX string), each function accepts
73-
either a LaTeX string or an existing `BoxedExpression`:
82+
either a LaTeX string or an existing `Expression`:
7483

7584
```ts
7685
const expr = parse('x + x + 1');
@@ -84,7 +93,7 @@ Use `getDefaultEngine()` to access the shared engine for configuration
8493

8594
The `expr.compile()` method has been replaced by a standalone `compile()`
8695
function with a structured `CompilationResult` return type. It accepts either a
87-
LaTeX string or a `BoxedExpression`.
96+
LaTeX string or an `Expression`.
8897

8998
```ts
9099
import { compile } from '@cortex-js/compute-engine';
@@ -109,7 +118,7 @@ Custom compilation targets can be registered and unregistered dynamically via
109118
while `expandAll()` applies it recursively. Both return `null` if the expression
110119
cannot be expanded.
111120

112-
Both accept a LaTeX string or a `BoxedExpression`, consistent with the other free
121+
Both accept a LaTeX string or an `Expression`, consistent with the other free
113122
functions (`simplify`, `evaluate`, `N`).
114123

115124
```ts
@@ -119,7 +128,7 @@ import { expand, expandAll } from '@cortex-js/compute-engine';
119128
expand('(x+1)^2'); // x^2 + 2x + 1
120129
expandAll('(x+1)(x+2) + (a+b)^2'); // recursive expansion
121130

122-
// From a BoxedExpression
131+
// From an Expression
123132
const expr = ce.parse('(x+1)(x+2)');
124133
expand(expr); // x^2 + 3x + 2
125134

@@ -130,25 +139,25 @@ const result = expand(expr) ?? expr;
130139
#### `solve()` Is a Free Function
131140

132141
A new `solve()` free function is available for solving equations without
133-
explicitly creating a `ComputeEngine` instance. Like the other free functions, it
134-
accepts either a LaTeX string or a `BoxedExpression`.
142+
explicitly creating a `ComputeEngine` instance. Like the other free functions,
143+
it accepts either a LaTeX string or an `Expression`.
135144

136145
```ts
137146
import { solve } from '@cortex-js/compute-engine';
138147

139148
// Solve from LaTeX
140149
solve('x^2 - 5x + 6 = 0', 'x'); // [2, 3]
141150

142-
// Solve from a BoxedExpression
151+
// Solve from an Expression
143152
const expr = ce.parse('x^2 - 5x + 6 = 0');
144153
solve(expr, 'x'); // [2, 3]
145154
```
146155

147156
#### `factor()` Is a Free Function
148157

149158
Polynomial factoring functions are now standalone free functions. `factor()`
150-
accepts a LaTeX string or a `BoxedExpression`. The specialized variants
151-
(`factorPolynomial`, `factorQuadratic`, etc.) accept only a `BoxedExpression`.
159+
accepts a LaTeX string or an `Expression`. The specialized variants
160+
(`factorPolynomial`, `factorQuadratic`, etc.) accept only an `Expression`.
152161

153162
```ts
154163
import { factor, factorPolynomial, factorQuadratic } from '@cortex-js/compute-engine';
@@ -404,31 +413,30 @@ ce.simplificationRules.push({
404413

405414
- **Infinity handling for 24+ functions**: `arctan(∞)`, `arccot(±∞)`,
406415
`tanh/coth/sech/csch(±∞)`, `arsinh(-∞)`, `arcosh(-∞)`, `arccoth(±∞)`,
407-
`arcsch(±∞)`, `π^∞`, `∞^n`, `(-∞)^{-n}`, `log_∞(x)`, `log_{0.5}(∞)`,
408-
`√∞`, `∛∞` now all return correct limits.
416+
`arcsch(±∞)`, `π^∞`, `∞^n`, `(-∞)^{-n}`, `log_∞(x)`, `log_{0.5}(∞)`, `√∞`,
417+
`∛∞` now all return correct limits.
409418

410419
- **Root edge cases**: `Root(x, 0) → NaN`, `Root(0, n)`, `Root(1, n)`,
411420
`Root(+∞, n)`, and `Sqrt(+∞)` now handled correctly.
412421

413-
- **Division edge cases**: `a/a → 1` now works for compound expressions
414-
(e.g., `(π+1)/(π+1)`); `2/0 → ComplexInfinity` and `1/(1/0) → 0` propagate
415-
correctly.
422+
- **Division edge cases**: `a/a → 1` now works for compound expressions (e.g.,
423+
`(π+1)/(π+1)`); `2/0 → ComplexInfinity` and `1/(1/0) → 0` propagate correctly.
416424

417-
- **Logarithm edge cases**: Fixed infinity detection in `simplify-log.ts`
418-
(was using `sym()` which fails on `BoxedNumber` infinity values); added
425+
- **Logarithm edge cases**: Fixed infinity detection in `simplify-log.ts` (was
426+
using `sym()` which fails on `BoxedNumber` infinity values); added
419427
`log_∞(∞) → NaN`, base-aware `log_c(0)`, guards for `log_1(x)` and
420428
`log_c(c^x)` evaluation.
421429

422-
- **Absolute value of odd functions**: `|arcsin(x)|`, `|sinh(x)|`, `|arsinh(x)|`,
423-
`|artanh(x)|` now simplify to `f(|x|)`.
430+
- **Absolute value of odd functions**: `|arcsin(x)|`, `|sinh(x)|`,
431+
`|arsinh(x)|`, `|artanh(x)|` now simplify to `f(|x|)`.
424432

425433
- **Even function with abs argument**: `cosh(|x+2|) → cosh(x+2)`.
426434

427435
- **Trig period shifts**: `cot(π+x) → cot(x)`, `csc(π+x) → -csc(x)`.
428436

429-
- **Ln simplification in Add/Multiply operands**: `ln(x^3) − 3·ln(x) → 0`
430-
and `ln(x^√2) → √2·ln(x)` now work; cost function bypassed for log rules
431-
that are mathematically valid but structurally more expensive.
437+
- **Ln simplification in Add/Multiply operands**: `ln(x^3) − 3·ln(x) → 0` and
438+
`ln(x^√2) → √2·ln(x)` now work; cost function bypassed for log rules that are
439+
mathematically valid but structurally more expensive.
432440

433441
- **Preserved function identity**: Removed unconditional expansions of
434442
`sinh/cosh → exp`, `arsinh/arcosh/artanh → ln`, and `arcsin → arctan2` that
@@ -505,7 +513,7 @@ ce.simplificationRules.push({
505513
the `type` property and enables more precise pattern matching and type
506514
discrimination in user code. **Breaking change**: Code that explicitly checks
507515
for `.operator === 'Number'` will need to be updated to check for specific
508-
numeric types or use the `isBoxedNumber()` type guard instead.
516+
numeric types or use the `isNumber()` type guard instead.
509517

510518
- **Non-XIDC Unicode characters in symbol names now encoded correctly**: When
511519
parsing LaTeX symbols containing non-identifier Unicode characters via

src/compute-engine/assume.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { BoxedType } from '../common/type/boxed-type';
44

55
import {
66
AssumeResult,
7-
BoxedExpression,
7+
Expression,
88
IComputeEngine as ComputeEngine,
99
Sign,
1010
} from './global-types';
@@ -32,7 +32,7 @@ import {
3232
*/
3333
function inferTypeFromValue(
3434
ce: ComputeEngine,
35-
value: BoxedExpression
35+
value: Expression
3636
): BoxedType {
3737
// finite_integer, integer, etc. -> integer
3838
if (value.type.matches('integer')) return ce.type('integer');
@@ -73,7 +73,7 @@ function inferTypeFromValue(
7373
*
7474
*/
7575

76-
export function assume(proposition: BoxedExpression): AssumeResult {
76+
export function assume(proposition: Expression): AssumeResult {
7777
if (proposition.operator === 'Element') return assumeElement(proposition);
7878
if (proposition.operator === 'Equal') return assumeEquality(proposition);
7979
if (isInequalityOperator(proposition.operator))
@@ -84,7 +84,7 @@ export function assume(proposition: BoxedExpression): AssumeResult {
8484
);
8585
}
8686

87-
function assumeEquality(proposition: BoxedExpression): AssumeResult {
87+
function assumeEquality(proposition: Expression): AssumeResult {
8888
console.assert(proposition.operator === 'Equal');
8989
// Four cases:
9090
// 1/ proposition contains no unknowns
@@ -181,7 +181,7 @@ function assumeEquality(proposition: BoxedExpression): AssumeResult {
181181
return 'ok';
182182
}
183183

184-
function assumeInequality(proposition: BoxedExpression): AssumeResult {
184+
function assumeInequality(proposition: Expression): AssumeResult {
185185
//
186186
// 1/ lhs is a single **undefined** free var e.g. "x < 0"
187187
// => define a new var, if the domain can be inferred set it, otherwise
@@ -236,8 +236,8 @@ function assumeInequality(proposition: BoxedExpression): AssumeResult {
236236
// Normalize to Less, LessEqual
237237
if (!isFunction(proposition)) return 'internal-error';
238238
let op = '';
239-
let lhs: BoxedExpression;
240-
let rhs: BoxedExpression;
239+
let lhs: Expression;
240+
let rhs: Expression;
241241
if (proposition.operator === 'Less') {
242242
lhs = proposition.op1;
243243
rhs = proposition.op2;
@@ -424,7 +424,7 @@ function assumeInequality(proposition: BoxedExpression): AssumeResult {
424424
return 'ok';
425425
}
426426

427-
function assumeElement(proposition: BoxedExpression): AssumeResult {
427+
function assumeElement(proposition: Expression): AssumeResult {
428428
console.assert(proposition.operator === 'Element');
429429

430430
// Four cases:
@@ -503,7 +503,7 @@ function hasDef(ce: ComputeEngine, s: string): boolean {
503503
return ce.lookupDefinition(s) !== undefined;
504504
}
505505

506-
function undefinedIdentifiers(expr: BoxedExpression): string[] {
506+
function undefinedIdentifiers(expr: Expression): string[] {
507507
return expr.symbols.filter((x) => !hasDef(expr.engine, x));
508508
}
509509

0 commit comments

Comments
 (0)