Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ read first.

| Silent? | What | Was | Is |
|---|---|---|---|
| **Silent** | `"limit(t * b, t, 0)".ToEntity().FreeVariables`, and every limit | `{ t, b }` — the variable it approaches along counted as free | `{ b }` |
| | `Entity.DomainConditionIn(Domain)` | did not exist | the domain of definition for a **stated** reading, through the whole tree |
| | `MathS.Polynomials.Factor("(y * x3 + 1) * (x4 - y3)", "x")`, and bivariate polynomials whose leading coefficient in the main variable is a polynomial | `null` — a refusal | `(x ^ 4 - y ^ 3) * (x ^ 3 * y + 1)` |
| | `MathS.Polynomials.Factor("x7 - y7", "x")`, and bivariate polynomials whose substituted image over-factors | `null` — a refusal | `(x - y) * (x ^ 6 + x ^ 5 * y + … + y ^ 6)` |
Expand Down Expand Up @@ -316,6 +317,29 @@ bracketing for. The change only ever adds `\left(`/`\right)` groups, which CShar
parses, so nothing downstream needs a matching change
([#822](https://github.com/asc-community/AngouriMath/issues/822)).

### A limit binds the variable it approaches along

`FreeVariables` learned about a summation, a product and a definite integral in
[#1045](https://github.com/asc-community/AngouriMath/pull/1045), and about `limit` not at all —
that commit names the indefinite integral and the derivative as deliberate exclusions and does
not mention it.

| | before | now |
|---|---|---|
| `"limit(t * b, t, 0)".ToEntity().FreeVariables` | `{ t, b }` | `{ b }` |
| `"limit(t, t, b)".ToEntity().FreeVariables` | `{ t, b }` | `{ b }` |
| `"limitleft(t * b, t, 0)".ToEntity().FreeVariables` | `{ t, b }` | `{ b }` |
| `"limit(t, t, 0)".ToEntity().FreeVariables` | `{ t }` | `{ }` |

The reason the indefinite integral and the derivative do not bind is exactly what makes a limit
bind: an antiderivative of `t * b` over `t` is `b * t ^ 2 / 2 + C` and `d/dt` denotes a function
of `t`, both still functions of the variable — while **a limit never is**. `lim(t, t, 0)` is `0`,
and no limit's value depends on the name it approaches along. The destination is where the
dependence goes, so it is bound over too: `lim(t, t, b)` is a function of `b` alone.

`Vars` and `VarsAndConsts` are untouched, as they were in #1045 — they mean every name occurring
([#989](https://github.com/asc-community/AngouriMath/issues/989)).

### A leading coefficient that is a polynomial no longer stops the lift

The Hensel lift below declined when the leading coefficient in the main variable was not a
Expand Down
9 changes: 9 additions & 0 deletions Sources/AngouriMath/Core/Entity/Entity.Definition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,15 @@ public IReadOnlyList<Variable> Vars
// on purpose, and a sweep that "fixes" that makes them wrong.
Integralf { Range: { } limits } integral
=> BoundBy(integral.Var, integral.Expression, limits.from, limits.to),
// A limit binds its variable always, and this is the one calculus
// operator of the three for which that is unconditional. The reason the
// two above are conditional does not apply to it: an antiderivative and a
// derivative are still functions of the variable, and a limit never is.
// lim(k, k, 0) is 0, and no limit's value depends on the name it
// approaches along -- the destination is where the dependence goes.
// https://github.com/asc-community/AngouriMath/issues/989
Limitf limit
=> BoundBy(limit.Var, limit.Expression, limit.Destination),
_ => new HashSet<Variable>(@this.DirectChildren.SelectMany(c => c.FreeVariables))
}
,
Expand Down
20 changes: 20 additions & 0 deletions Sources/Tests/UnitTests/Common/FreeVariablesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,26 @@ public void TheIndexIsBoundOverTheBoundsToo()
public void ADefiniteIntegralBindsItsVariable(string exprRaw)
=> Assert.Equal(SeqVar("b"), exprRaw.ToEntity().FreeVariables);

/// <summary>
/// A limit binds its variable <b>always</b>, where the integral above binds only when it
/// has limits to bind between — and the reason the two below do not bind is what makes
/// the difference. An antiderivative and a derivative are still functions of the
/// variable; a limit never is. <c>lim(t, t, 0)</c> is <c>0</c>.
/// </summary>
/// <remarks>
/// The destination is where a limit's dependence goes, so it is bound over as well:
/// <c>lim(t, t, b)</c> is a function of <c>b</c> and of nothing else. A one-sided limit
/// binds the same way — the side is not a variable.
/// <a href="https://github.com/asc-community/AngouriMath/issues/989">#989</a>
/// </remarks>
[Theory]
[InlineData("limit(t * b, t, 0)")]
[InlineData("limit(t, t, b)")]
[InlineData("limitleft(t * b, t, 0)")]
[InlineData("limitright(t * b, t, 0)")]
public void ALimitBindsItsVariable(string exprRaw)
=> Assert.Equal(SeqVar("b"), exprRaw.ToEntity().FreeVariables);

/// <summary>
/// And the two that look like the same shape and are not. The antiderivative of
/// <c>t * b</c> over <c>t</c> is <c>b * t ^ 2 / 2 + C</c>, still a function of <c>t</c>;
Expand Down
Loading