You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0e643f3
Browse filesBrowse the repository at this point in the historyBrowse files
A nested radical comes apart
`sqrt(5 + 2*sqrt(6))` is a radical under a radical, and it is two plain ones
added: `sqrt(3) + sqrt(2)`. So are `sqrt(7 - 4*sqrt(3))`, `sqrt(9 + 4*sqrt(5))`,
`sqrt(11 + 6*sqrt(2))` and `sqrt(6 - 2*sqrt(5))`.
Squaring `sqrt(x) + sqrt(y)` gives `x + y + 2*sqrt(x*y)`, so matching that
against `a + b*sqrt(c)` makes `x` and `y` the roots of `t^2 - a*t + b^2*c/4`.
They are rational exactly when `a^2 - b^2*c` is the square of a rational, and
that is the whole test -- decidable in exact arithmetic rather than a search.
The sign of `b` chooses the sum or the difference, since squaring either gives
`a + |b|*sqrt(c)`.
No condition is attached and none is owed. A non-negative `a` and a
non-negative discriminant are required before anything is built, and together
they make the radicand, `x` and `y` all non-negative -- so what fires is an
identity between real numbers with no branch chosen. A negative `a` is refused
rather than conditioned, which is why the rule is `Sound` and not
`SoundUnderAssumptions`.
The inner root is read however the neighbouring rules have left it. They
gather `2 * sqrt(2)` into `2 ^ (3/2)`, so a reader insisting on a written
`sqrt` declines a radicand it can perfectly well denest; any half-integer
exponent counts, `m ^ (p/2)` being `m ^ ((p-1)/2) * sqrt(m)`.
Written next to `ReduceRadical`, which takes a whole power out from under one
root where this takes a root out from under another, and to the same contract:
one helper answers both the `when` and the replacement, and null means decline.
Both spellings of the rule are added, since `MatchedRulesAgreeWithTheSwitchTest`
holds them to each other and the corpus it runs generates `sqrt` over sums.
Where the denesting is longer, `Simplify` keeps the nested form.
`sqrt(2 + sqrt(3))` does come apart -- to `(sqrt(6) + sqrt(2))/2` -- and the
nested spelling is shorter, so that is what comes back. The rule offers the
alternative and the selection is by size, as everywhere else.
One radicand is recorded as a boundary rather than explained.
`sqrt(3 + 2*sqrt(2))` is answered by the rule -- applying the set gives
`sqrt(2) + 1`, the shorter form -- and `Simplify` returns the nested one
anyway. The obvious suspect was that the perfect-square collapse re-nests the
radicand; measured, `CollapseToPerfectSquare` answers null for it, so that is
ruled out rather than unexamined. The test pins what happens and says the cause
is not established.
The rule census moves by one throughout: `WritingARule.md` and the four test
files that hold the document to it, plus the reversible-rule classification
list. Comparison.md's `radical denesting` cell is left as measured, its note
now naming four moved rows rather than two.
Full suite 9515 passed, 0 failed.
Part of #717.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
Copy file name to clipboardExpand all lines: BREAKING-CHANGES.md
+39Lines changed: 39 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -107,10 +107,49 @@ read first.
107
107
|**Silent**|`"arccotan(-1)".ToEntity().Simplify()`, and every negative argument the inverse-trigonometric table knows |`3/4 * pi` — the textbook range, and **not equal to `arccotan(-1)`**, whose value is `-pi/4`|`-1/4 * pi`|
108
108
||`"e ^ ln(x)".ToEntity().Simplify()`, and every exponential of a natural logarithm |`e ^ ln(x)` — left as written |`x`|
109
109
||`"a => a + 3".ToEntity()`, and every lambda written with an arrow |`UnhandledParseException`|`lambda(a, a + 3)`|
110
+
||`"sqrt(5 + 2 * sqrt(6))".ToEntity().Simplify()`, and every nested radical whose discriminant is a rational square |`sqrt(5 + 2 * sqrt(6))` — left as written |`sqrt(3) + sqrt(2)`|
110
111
||`"sum(k, k, 1, n)".ToEntity().Simplify()`, and every summation whose body is a polynomial in the index |`sum(k, k, 1, n)` — carried |`piecewise((n + n ^ 2) / 2 provided n >= 0, 0)`|
111
112
||`"sum(k, k, 1, 100000)".ToEntity().Simplify()`, and every concrete range past a hundred terms |`sum(k, k, 1, 100000)` — carried |`5000050000`|
112
113
||`"product(k, k, 1, n)".ToEntity().Simplify()`, and every product whose body is a monomial in the index |`product(k, k, 1, n)` — carried |`piecewise(n! provided n >= 1, 1)`|
113
114
115
+
### A nested radical comes apart
116
+
117
+
`sqrt(5 + 2*sqrt(6))` is a radical under a radical, and it is two plain ones added.
118
+
119
+
```
120
+
"sqrt(5 + 2 * sqrt(6))".Simplify() was sqrt(5 + 2 * sqrt(6)) is sqrt(3) + sqrt(2)
121
+
"sqrt(7 - 4 * sqrt(3))".Simplify() was as written is 2 - sqrt(3)
122
+
"sqrt(9 + 4 * sqrt(5))".Simplify() was as written is sqrt(5) + 2
123
+
"sqrt(11 + 6 * sqrt(2))".Simplify() was as written is 3 + sqrt(2)
124
+
"sqrt(6 - 2 * sqrt(5))".Simplify() was as written is sqrt(5) - 1
125
+
```
126
+
127
+
Squaring `sqrt(x) + sqrt(y)` gives `x + y + 2*sqrt(x*y)`, so matching that against
128
+
`a + b*sqrt(c)` makes `x` and `y` the roots of `t^2 - a*t + b^2*c/4`. They are rational exactly
129
+
when `a^2 - b^2*c` is the square of a rational, and that is the whole test — decidable in exact
130
+
arithmetic rather than a search. The sign of `b` chooses the sum or the difference, since squaring
131
+
either gives `a + |b|*sqrt(c)`.
132
+
133
+
**No condition is attached and none is owed.** A non-negative `a` and a non-negative discriminant
134
+
are required before anything is built, and together they make the radicand, `x` and `y` all
135
+
non-negative — so what fires is an identity between real numbers with no branch chosen. A negative
136
+
`a` is refused rather than conditioned.
137
+
138
+
**A radicand with no rational split is left as written**, `sqrt(1 + sqrt(2))` among them, and so
139
+
is anything that is not `a + b*sqrt(c)`.
140
+
141
+
**Where the denesting is longer, `Simplify` keeps the nested form.**`sqrt(2 + sqrt(3))` does come
142
+
apart — to `(sqrt(6) + sqrt(2))/2` — and the nested spelling is the shorter of the two, so that is
143
+
what comes back. The rule offers the alternative; the selection is by size, as it is everywhere
144
+
else.
145
+
146
+
One radicand is a boundary rather than a rule: `sqrt(3 + 2*sqrt(2))` is answered by the rule —
147
+
applying the set gives `sqrt(2) + 1`, the shorter form — and `Simplify` nonetheless returns the
148
+
nested one. There is a test pinning what happens; the cause is not established, and the obvious
0 commit comments