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
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,21 @@ internal static Set IntersectIntervalAndInterval(Interval A, Interval B)
{
if (A.Left == B.Left && A.Right == B.Right)
return new Interval(A.Left, A.LeftClosed && B.LeftClosed, A.Right, A.RightClosed && B.RightClosed);
if (A.Left is not Real aLeft ||
A.Right is not Real aRight ||
B.Left is not Real bLeft ||
B.Right is not Real bRight)
// Compared by what the endpoints are worth, not by whether they are written as
// bare numbers. (sqrt(33) - 3) / 6 is a Divf and never a Real, so an interval
// written with one was given up on -- which is
// https://github.com/asc-community/AngouriMath/issues/415. The bounds of the result
// are taken from the original expressions, so the answer keeps them exact
// rather than turning them into a hundred decimal places.
if (A.Left.Evaled is not Real aLeft ||
A.Right.Evaled is not Real aRight ||
B.Left.Evaled is not Real bLeft ||
B.Right.Evaled is not Real bRight)
return A.Intersect(B);
if (aLeft == bRight)
return A.LeftClosed && B.RightClosed ? new FiniteSet(aLeft) : Empty;
return A.LeftClosed && B.RightClosed ? new FiniteSet(A.Left) : Empty;
if (bLeft == aRight)
return A.RightClosed && B.LeftClosed ? new FiniteSet(bLeft) : Empty;
return A.RightClosed && B.LeftClosed ? new FiniteSet(B.Left) : Empty;
if (aLeft >= aRight)
return B;
if (bLeft >= bRight)
Expand All @@ -49,12 +55,12 @@ B.Left is not Real bLeft ||
return Empty;
var (left, leftClosed) =
aLeft == bLeft ?
(aLeft, A.LeftClosed && B.LeftClosed) :
(bLeft < aLeft ? (aLeft, A.LeftClosed) : (bLeft, B.LeftClosed));
(A.Left, A.LeftClosed && B.LeftClosed) :
(bLeft < aLeft ? (A.Left, A.LeftClosed) : (B.Left, B.LeftClosed));
var (right, rightClosed) =
aRight == bRight ?
(aRight, A.RightClosed && B.RightClosed) :
(bRight > aRight ? (aRight, A.RightClosed) : (bRight, B.RightClosed));
(A.Right, A.RightClosed && B.RightClosed) :
(bRight > aRight ? (A.Right, A.RightClosed) : (B.Right, B.RightClosed));
return new Interval(left, leftClosed, right, rightClosed);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ internal static partial class Patterns
internal static Entity SetOperatorRules(Entity x) => x switch
{
Intersectionf(var any1, var any1a) when any1 == any1a => any1,

// A /\ (B \/ C) = (A /\ B) \/ (A /\ C). Without this, an intersection whose
// other side is a union is left as written however simple each piece is, which
// is half of https://github.com/asc-community/AngouriMath/issues/415.
Intersectionf(Set setA, Unionf(Set setB, Set setC)) =>
setA.Intersect(setB).Unite(setA.Intersect(setC)),
Intersectionf(Unionf(Set setB, Set setC), Set setA) =>
setB.Intersect(setA).Unite(setC.Intersect(setA)),
Unionf(var any1, var any1a) when any1 == any1a => any1,
SetMinusf(var any1, var any1a) when any1 == any1a => Empty,
ConditionalSet(var var1, Inf(var var1a, var set)) when var1 == var1a => set,
Expand Down
45 changes: 31 additions & 14 deletions Sources/Tests/UnitTests/Common/AlreadyFixedIssuesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,15 @@ private static T Terminates<T>(System.Func<T> work, string what)
[Fact]
public void Issue263_InnerSimplifyTerminates() =>
Terminates(() => Issue263Quotient.ToEntity().InnerSimplified,
"InnerSimplify of the #263 quotient");
"InnerSimplify of the quotient from https://github.com/asc-community/AngouriMath/issues/263");

// The limit is what the quotient was written for, so its value is asserted rather
// than only that it comes back. Reported on the issue, this is 15*14/2 * 3^13.
[Fact]
public void Issue263_LimitTerminates() =>
Terminates(() => Issue263Quotient.ToEntity().Limit("x", 3, ApproachFrom.Left),
"the #263 limit");
public void Issue263_LimitIsComputed() =>
Assert.Equal(Entity.Number.Integer.Create(167403915),
Terminates(() => Issue263Quotient.ToEntity().Limit("x", 3, ApproachFrom.Left).Simplify(),
"the limit from https://github.com/asc-community/AngouriMath/issues/263"));

// https://github.com/asc-community/AngouriMath/issues/347
// Taking a limit of a boolean expression overflowed the stack. It is still not
Expand All @@ -66,23 +69,37 @@ public void Issue362_CoefficientsAreCollected() =>
Assert.Equal("(-2) * d * t", "(-1/2d-3/2d)t".ToEntity().Simplify().Stringize());

// https://github.com/asc-community/AngouriMath/issues/424
// Piecewise was to become compileable.
// Piecewise was to become compileable. These are piecewise() nodes: the earlier
// version of this test used `provided`, which is a Providedf and a different node
// altogether, so it was not testing the issue at all.
[Theory]
[InlineData("5 provided x = 3", 3.0, 5.0)]
[InlineData("x provided true", 7.0, 7.0)]
[InlineData("2 * x provided x > 0", 4.0, 8.0)]
[InlineData("piecewise(2 * x provided x > 0, -x provided true)", 3.0, 6.0)]
[InlineData("piecewise(2 * x provided x > 0, -x provided true)", -4.0, 4.0)]
[InlineData("piecewise(1 provided x > 10, 2 provided x > 5, 3 provided true)", 12.0, 1.0)]
[InlineData("piecewise(1 provided x > 10, 2 provided x > 5, 3 provided true)", 7.0, 2.0)]
[InlineData("piecewise(1 provided x > 10, 2 provided x > 5, 3 provided true)", 1.0, 3.0)]
public void Issue424_PiecewiseCompiles(string expression, double argument, double expected) =>
Assert.Equal(expected, expression.ToEntity().Compile<double, double>("x")(argument), 9);

// https://github.com/asc-community/AngouriMath/issues/415
// Intersections and unions of intervals were to be simplified.
// The example in the issue's screenshot, which is what it asks for. It needed two
// things: an intersection has to distribute over a union, and endpoints have to be
// compared by what they are worth rather than by whether they are written as bare
// numbers -- (sqrt(33) - 3) / 6 is a division and never a Real.
[Fact]
public void Issue415_IntervalsIntersect() =>
Assert.Equal(@"[3; 5]".ToEntity(), @"[1; 5] /\ [3; 8]".ToEntity().Simplify());
public void Issue415_TheScreenshottedExample() =>
Assert.Equal(@"(-1; (sqrt(33) - 3) / 6)".ToEntity().Simplify(),
@"(-1; 1) /\ (((-(sqrt(33) + 3) / 6; (sqrt(33) - 3) / 6) \/ (1; +oo)))"
.ToEntity().Simplify());

[Fact]
public void Issue415_IntervalsUnite() =>
Assert.Equal(@"[1; 8]".ToEntity(), @"[1; 5] \/ [3; 8]".ToEntity().Simplify());
[Theory]
[InlineData(@"[1; 5] /\ [3; 8]", "[3; 5]")]
[InlineData(@"[1; 5] \/ [3; 8]", "[1; 8]")]
[InlineData(@"(-1; 1) /\ ((0; 3) \/ (5; 7))", "(0; 1)")]
[InlineData(@"(-1; 1) /\ (-2; sqrt(2) / 4)", "(-1; sqrt(2) / 4)")]
[InlineData(@"(-1; 1) /\ (1; +oo)", "{ }")]
public void Issue415_IntervalsSimplify(string input, string expected) =>
Assert.Equal(expected.ToEntity().Simplify(), input.ToEntity().Simplify());

// https://github.com/asc-community/AngouriMath/issues/550
// The reporter's small system did not solve. The 25x26 one from the same report
Expand Down
Loading