@@ -1440,3 +1440,147 @@ ce.assume(ce.box(['Less', 'x', 0])); // → 'contradiction' (x > 4 contradi
14401440
14411441- ` test/compute-engine/assumptions.test.ts ` - Enabled "TAUTOLOGY AND
14421442 CONTRADICTION DETECTION" describe block (4 tests)
1443+
1444+ ---
1445+
1446+ ### 23. Replace Method Auto-Wildcards Fix ✅
1447+
1448+ ** FIXED:** The ` .replace() ` method no longer auto-converts single-character
1449+ symbols to wildcards when using object rules. This fixes issue #23 .
1450+
1451+ ** Problem:** When using ` .replace({match: 'a', replace: 2}) ` , the symbol ` 'a' `
1452+ was being auto-converted to wildcard ` '_a' ` , causing it to match ANY expression
1453+ instead of just the literal symbol ` a ` .
1454+
1455+ ** Solution:** Added ` autoWildcard ` parameter to ` parseRulePart() ` . Auto-wildcarding
1456+ is now only enabled when parsing string rules (like ` "a*x -> 2*x" ` ), not when
1457+ parsing object rules.
1458+
1459+ ** Examples that now work correctly:**
1460+
1461+ ``` typescript
1462+ const expr = ce .box ([' Add' , [' Multiply' , ' a' , ' x' ], ' b' ]);
1463+
1464+ // Object rules: literal matching
1465+ expr .replace ({match: ' a' , replace: 2 }, {recursive: true });
1466+ // → 2x + b (was: 2 - incorrectly matched entire expression)
1467+
1468+ // String rules: still auto-wildcard
1469+ expr .replace (' a*x -> 5*x' , {recursive: true });
1470+ // → 5x + b (works as before)
1471+
1472+ // Explicit wildcards in object rules still work
1473+ expr .replace ({match: [' Multiply' , ' _a' , ' x' ], replace: 10 }, {recursive: true });
1474+ // → 10 + b
1475+ ```
1476+
1477+ ** Files modified:**
1478+
1479+ - ` src/compute-engine/boxed-expression/rules.ts ` - Added ` autoWildcard ` parameter
1480+ to ` parseRulePart() ` , defaults to ` false ` for object rules
1481+ - ` test/compute-engine/rules.test.ts ` - Added 5 new tests in "OBJECT RULES
1482+ LITERAL MATCHING" describe block
1483+
1484+ ---
1485+
1486+ ### 15. Extended Sqrt Pattern 4: Nested Sqrt Equations ✅
1487+
1488+ ** IMPLEMENTED:** The solver now handles nested sqrt equations of the form
1489+ ` √(x + √x) = a ` and similar patterns where √x appears inside the argument of an
1490+ outer sqrt.
1491+
1492+ ** Problem:** Equations like ` √(x + 2√x) = 3 ` or ` √(x - √x) = 1 ` were not being
1493+ solved because they require a substitution approach.
1494+
1495+ ** Solution:** Added ` solveNestedSqrtEquation() ` function that:
1496+
1497+ 1 . Detects patterns where √x appears inside the argument of an outer √
1498+ 2 . Uses substitution u = √x, so x = u²
1499+ 3 . Transforms the equation: ` √(u² + ku) = a ` → ` u² + ku = a² `
1500+ 4 . Solves the resulting quadratic for u
1501+ 5 . Filters out negative u values (since u = √x ≥ 0)
1502+ 6 . Returns x = u² for valid u values
1503+
1504+ ** Key implementation details:**
1505+
1506+ - Uses a unique internal symbol ` __internalU ` to avoid wildcard interpretation
1507+ - Must replace √x with u BEFORE replacing x with u², otherwise √x becomes √(u²)
1508+ - Uses ` isNegative ` property on the evaluated u value for filtering
1509+ - Integrates with ` validateRoots() ` for additional extraneous root filtering
1510+
1511+ ** Examples that now work:**
1512+
1513+ ``` typescript
1514+ ce .parse (" \s qrt{x + 2\s qrt{x}} = 3" ).solve (" x" ) // → [11 - 2√10] ≈ 4.675
1515+ // u² + 2u - 9 = 0 → u = -1 ± √10
1516+ // u = -1 + √10 ≈ 2.16 (valid), u = -1 - √10 ≈ -4.16 (filtered)
1517+ // x = (−1 + √10)² = 11 - 2√10
1518+
1519+ ce .parse (" \s qrt{x + \s qrt{x}} = 2" ).solve (" x" ) // → [9/2 - √17/2] ≈ 2.438
1520+ // u² + u - 4 = 0 → u = (-1 ± √17)/2
1521+ // Only u = (-1 + √17)/2 ≈ 1.56 is valid
1522+
1523+ ce .parse (" \s qrt{x - \s qrt{x}} = 1" ).solve (" x" ) // → [φ²] ≈ 2.618
1524+ // u² - u - 1 = 0 → u = (1 ± √5)/2
1525+ // Only u = φ (golden ratio) ≈ 1.618 is valid
1526+ ```
1527+
1528+ ** Files modified:**
1529+
1530+ - ` src/compute-engine/boxed-expression/solve.ts ` - Added ` solveNestedSqrtEquation() `
1531+ function and integration in ` findUnivariateRoots() `
1532+ - ` test/compute-engine/solve.test.ts ` - Added 3 new tests in "NESTED SQRT
1533+ EQUATIONS (Pattern 4)" describe block
1534+ - ` requirements/TODO.md ` - Updated Pattern 4 as implemented
1535+
1536+ ---
1537+
1538+ ### 15. Extended Sqrt Pattern 3: Two Sqrt Terms ✅
1539+
1540+ ** IMPLEMENTED:** The solver now handles equations with two sqrt terms of the
1541+ form ` √(f(x)) + √(g(x)) = e ` using double squaring.
1542+
1543+ ** Problem:** Equations like ` √(x+1) + √(x+4) = 3 ` or ` √(x+5) - √(x-3) = 2 ` were
1544+ not being solved because they require squaring twice to eliminate both sqrts.
1545+
1546+ ** Solution:** Added ` solveTwoSqrtEquation() ` function that:
1547+
1548+ 1 . Detects equations with exactly two sqrt terms and a constant
1549+ 2 . Isolates one sqrt: ` √(f(x)) = e - √(g(x)) `
1550+ 3 . Squares both sides: ` f(x) = e² - 2e√(g(x)) + g(x) `
1551+ 4 . Isolates remaining sqrt: ` f(x) - e² - g(x) = -2e√(g(x)) `
1552+ 5 . Squares again: ` (f(x) - e² - g(x))² = 4e²·g(x) `
1553+ 6 . Solves the resulting polynomial equation
1554+ 7 . Validates each solution by checking:
1555+ - ` f(x) ≥ 0 ` and ` g(x) ≥ 0 ` (for real sqrts)
1556+ - The original equation holds numerically
1557+
1558+ ** Key implementation details:**
1559+
1560+ - Handles both addition (` √f + √g = e ` ) and subtraction (` √f - √g = e ` )
1561+ - Handles negated sqrt terms (` -√f + √g = e ` )
1562+ - Validates solutions numerically with tolerance of 1e-9
1563+ - Filters out extraneous roots introduced by squaring
1564+
1565+ ** Examples that now work:**
1566+
1567+ ``` typescript
1568+ ce .parse (" \s qrt{x+1} + \s qrt{x+4} = 3" ).solve (" x" ) // → [0]
1569+ // Verify: √1 + √4 = 1 + 2 = 3 ✓
1570+
1571+ ce .parse (" \s qrt{x} + \s qrt{x+7} = 7" ).solve (" x" ) // → [9]
1572+ // Verify: √9 + √16 = 3 + 4 = 7 ✓
1573+
1574+ ce .parse (" \s qrt{x+5} - \s qrt{x-3} = 2" ).solve (" x" ) // → [4]
1575+ // Verify: √9 - √1 = 3 - 1 = 2 ✓
1576+
1577+ ce .parse (" \s qrt{2x+1} + \s qrt{x-1} = 4" ).solve (" x" ) // → [46 - 8√29] ≈ 2.919
1578+ ```
1579+
1580+ ** Files modified:**
1581+
1582+ - ` src/compute-engine/boxed-expression/solve.ts ` - Added ` solveTwoSqrtEquation() `
1583+ and ` solveTwoSqrtEquationCore() ` functions, integrated into ` findUnivariateRoots() `
1584+ - ` test/compute-engine/solve.test.ts ` - Added 5 new tests in "TWO SQRT EQUATIONS
1585+ (Pattern 3)" describe block
1586+ - ` requirements/TODO.md ` - Updated Pattern 3 as implemented
0 commit comments