| 607 | expect(sameNumerically(sp, p)).toBe(true); |
| 608 | |
| 609 | const binom = ce.box(['Add', 2, ['Multiply', 3, ['sec', arg]]] as any); // 2 + 3·sec |
| 610 | const sb = cofunctionShift(ce, binom, 'x'); |
| 611 | expect(sb.toString().includes('csc')).toBe(true); |
| 612 | expect(sameNumerically(sb, binom)).toBe(true); |
| 613 | }); |
| 614 | |
| 615 | test('composes with deactivateTrig: active Sec deactivates + reflects to csc', () => { |
| 616 | const active = ce.box(['Power', ['Sec', arg], 3] as any); // Sec[a+b x]^3 |
| 617 | const shifted = cofunctionShift(ce, deactivateTrig(ce, active), 'x'); |
| 618 | expect(shifted.toString().includes('csc')).toBe(true); |
| 619 | expect(sameNumerically(shifted, active)).toBe(true); |
| 620 | }); |
| 621 | |
| 622 | test('leaves a MIXED cross-pair integrand (sin·sec) untouched', () => { |
| 623 | // sin co-present ⇒ uniform +π/2 would desync arguments; unifyInertTrig owns it |
| 624 | const mixed = ce.box(['Multiply', ['sin', arg], ['sec', arg]] as any); |
| 625 | expect(cofunctionShift(ce, mixed, 'x')).toBe(mixed); |