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
15 changes: 15 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,21 @@ names are keywords now, and were names.
| `preimage(x^2, x in RR, {1})` | `UnhandledParseException` | `{ 1, -1 }` |
| `{ x in ZZ : x^2 in {1, 4} }` | `{ x in ZZ : x ^ 2 in { 1, 4 } }` — left as written | `{ 1, -1, 2, -2 }` |

### An infinite base has its whole powers, and surjectivity is decided through the image

`(-oo)^3` was `NaN` — a claim that the value does not exist — and so were `(-oo)^2` and
`(-oo)^(-1)`, while `(+oo)^2` was `+oo`: the finite-base arms did not apply and the polar form
had nothing to say. They are the extended reals' powers now, `-oo`, `+oo` and `0`, so the image of
`(-oo; +oo)` under a cube is `(-oo; +oo)`; and `forall b in B : exists a in A : f(a) = b` — surjectivity
onto `B`, Def 7.4.1 of the reference of [#1409](https://github.com/asc-community/AngouriMath/issues/1409)
— is decided as `B` lying in the image of `A` under `f` where that image evaluates.

| Input | Was (2.5.0) | Now |
|---|---|---|
| `(-oo)^3` | `NaN` — wrong | `-oo` |
| `(-oo)^2` | `NaN` — wrong | `+oo` |
| `forall b in RR : exists a in RR : a^3 = b` | `UnhandledParseException` (quantifiers are new since; left as written when they arrived) | `True` |
| `forall b in RR : exists a in RR : e^a = b` | `UnhandledParseException` | `False` |
### The binomial coefficient's identities, and its sums in closed form

Pascal's rule, the chairperson identity and the symmetry are rewrite rules, each in the direction
Expand Down
3 changes: 3 additions & 0 deletions Sources/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[AngouriMath/Functions/NumberTheory/ResidueClasses.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

[Tests/UnitTests/Core/SurjectivityTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

[Tests/UnitTests/Core/BinomialIdentityTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

Expand Down
11 changes: 11 additions & 0 deletions Sources/AngouriMath/Core/Entity/Continuous/Number/Operators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,17 @@ static Complex BinaryIntPow(Complex num, EInteger val)
&& decimalPower.IsInteger() && decimalPower.Abs().CompareTo(EDecimal.FromInt32(1 << 20)) <= 0 => decimalPower.ToEInteger(),
_ => null,
};
// An infinite real base to a whole power: (+oo)^n is +oo, (-oo)^n is +oo or -oo by
// the parity of n, and either to a negative power is 0 -- the extended reals'
// arithmetic, which the product of infinities already follows. It fell through
// to the polar form and came back NaN, so the image of (-oo; +oo) under a cube
// had no ends. https://github.com/asc-community/AngouriMath/issues/1409
if (@base is Real { EDecimal: var infinite } && infinite.IsInfinity() && pow is { } wholeOfInfinity && !wholeOfInfinity.IsZero)
{
if (wholeOfInfinity.Sign < 0)
return Integer.Zero;
return infinite.IsNegative && !wholeOfInfinity.IsEven ? Real.NegativeInfinity : Real.PositiveInfinity;
}
if (@base.IsFinite && pow is { })
{
// A real base that is not exact -- a decimal, which is what a numerical
Expand Down
12 changes: 12 additions & 0 deletions Sources/AngouriMath/Functions/Boolean/Quantifiers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ internal enum Kind { All, Some, Unique }
set = new FiniteSet(Entity.Boolean.True, Entity.Boolean.False);
if (!body.ContainsNode(x))
return Closed(kind, set, body);
// forall b in B : exists a in A : f(a) = b is the statement that B lies in the image
// of A under f -- surjectivity onto B (the reference's Def 7.4.1) -- and the image is
// a set the library computes: listed over a listed A, an interval by interval
// arithmetic, so the subset decision settles it where the image evaluates.
// https://github.com/asc-community/AngouriMath/issues/1409
if (kind == Kind.All && body is Existsf(Variable a, Set domain, Equalsf(var lhs, var rhs))
&& (lhs == x && !rhs.ContainsNode(x) && rhs.ContainsNode(a) ? rhs : rhs == x && !lhs.ContainsNode(x) && lhs.ContainsNode(a) ? lhs : null) is { } map)
{
var image = new IndexedUnionf(a, domain, new FiniteSet(map)).InnerSimplified(isExact);
if (image is not IndexedUnionf && image is Set imageSet && Core.Sets.SetOperators.Subset(set, imageSet, isExact) is { } covered)
return covered;
}
// An equation whose two sides differ by a polynomial that expands to nothing holds
// at every member, whatever the set: (x + 1)^2 = x^2 + 2 x + 1 is True of each.
if (body is Equalsf(var left, var right) && IsIdentity(left, right))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,11 @@ protected override Entity InnerSimplify(bool isExact)
// one occurrence and the operations it has images for (#1423): the
// reference's 9c/5 + 32 on (0, 100) is (32, 212). Where the arithmetic has
// no image the substitution leaves an expression, and the family stays.
if (this is IndexedUnionf && over is Interval && body is FiniteSet { Count: 1 } image
// The reals are the interval (-oo; +oo) for this purpose.
var overAsInterval = over is SpecialSet.Reals ? new Interval(Real.NegativeInfinity, false, Real.PositiveInfinity, false) : over;
if (this is IndexedUnionf && overAsInterval is Interval && body is FiniteSet { Count: 1 } image
&& image.First() is var f && f.Nodes.Count(node => node == Var) == 1
&& f.Substitute(Var, over).InnerSimplified(isExact) is Set imaged)
&& f.Substitute(Var, overAsInterval).InnerSimplified(isExact) is Set imaged)
return imaged;
if (over is FiniteSet indices)
{
Expand Down
50 changes: 50 additions & 0 deletions Sources/Tests/UnitTests/Core/SurjectivityTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// Copyright (c) 2019-2026 Angouri.
// AngouriMath is licensed under MIT.
// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
// Website: https://am.angouri.org.
//

using AngouriMath;
using AngouriMath.Extensions;
using Xunit;
using static AngouriMath.Entity;

namespace AngouriMath.Tests.Core
{
/// <summary>
/// <c>forall b in B : exists a in A : f(a) = b</c> -- surjectivity onto <c>B</c>, Def 7.4.1 of the
/// reference (Sullivan and Mackey) -- is the statement that <c>B</c> lies in the image of
/// <c>A</c> under <c>f</c>, and is decided where the image evaluates: listed over a listed
/// <c>A</c>, an interval by interval arithmetic. The cube is onto the reals because
/// <c>(-oo; +oo)^3</c> is <c>(-oo; +oo)</c>, which needed <c>(-oo)^3</c> to be <c>-oo</c>
/// rather than <c>NaN</c>. <see href="https://github.com/asc-community/AngouriMath/issues/1409"/>
/// </summary>
[Trait("Area", "Core")]
public sealed class SurjectivityTest
{
[Theory]
[InlineData("forall b in RR : exists a in RR : a^3 = b", "True")]
[InlineData("forall b in RR : exists a in RR : 2 a + 1 = b", "True")]
[InlineData("forall b in RR : exists a in RR : a^2 = b", "False")]
[InlineData("forall b in [0; +oo) : exists a in RR : a^2 = b", "True")]
[InlineData("forall b in RR : exists a in RR : e^a = b", "False")]
[InlineData("forall b in (0; +oo) : exists a in RR : e^a = b", "True")]
[InlineData("forall b in ZZ : exists a in ZZ : 2 a = b", "False")]
[InlineData("forall b in {1, 4, 9} : exists a in {1, 2, 3} : a^2 = b", "True")]
[InlineData("forall b in {1, 4, 9, 16} : exists a in {1, 2, 3} : a^2 = b", "False")]
public void SurjectivityIsTheImageCoveringTheCodomain(string statement, string expected)
=> Assert.Equal(expected.ToEntity(), statement.ToEntity().Evaled);

/// <summary>The extended reals' whole powers: by parity for <c>-oo</c>, and <c>0</c> for a negative exponent. Each was <c>NaN</c>.</summary>
[Theory]
[InlineData("(-oo)^3", "-oo")]
[InlineData("(-oo)^2", "+oo")]
[InlineData("(-oo)^(-1)", "0")]
[InlineData("(+oo)^3", "+oo")]
[InlineData("(-oo; +oo)^3", "(-oo; +oo)")]
[InlineData("image(x^3, x in RR)", "(-oo; +oo)")]
public void AnInfiniteBaseHasItsWholePowers(string expression, string expected)
=> Assert.Equal(expected.ToEntity().Evaled, expression.ToEntity().Evaled);
}
}
Loading