diff --git a/Sources/AngouriMath/Functions/Continuous/Limits/Limit.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Limits/Limit.Definition.cs
index 1754e1d61..1c3ffb1da 100644
--- a/Sources/AngouriMath/Functions/Continuous/Limits/Limit.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Limits/Limit.Definition.cs
@@ -140,12 +140,29 @@ public Entity Limit(Variable x, Entity destination)
/// the same or related type, until these become simple enough to be solved
/// directly. The solutions to the sub-problems are then combined to give a
/// solution to the original problem.
+ ///
+ /// Here we try to compute the limit for each child and then merge them into the limit
+ /// of the whole expression. Theoretically, for cases such as limit (x -> -1) 1 / (x + 1)
+ /// this method will return NaN, but thanks to replacement of x by a non-definite
+ /// expression, it is somehow compensated.
///
- // here we try to compute limit for each children and then merge them into limit of whole expression
- // theoretically, for cases such limit (x -> -1) 1 / (x + 1)
- // this method will return NaN, but thanks to replacement of x to an non-definite expression,
- // it is somehow compensated
+ ///
+ /// Null, not . This used to hand back
+ /// new Limitf(this, ...), which reads as the honest "I could not settle this"
+ /// and is in fact a cycle: the caller evaluates the node to compare it, evaluating a
+ /// computes the limit, and computing arrives back here. That
+ /// overflows the stack, which kills the process rather than raising anything a caller
+ /// can catch — the exact failure AGENTS.md names, with this exact expression as its
+ /// example.
+ ///
+ /// It made every node without an override a landmine, since inheriting the default
+ /// was enough to crash: floor, ceil, round, min, max, gcd and phi all did.
+ /// Returning null reads the same to every caller here — they all test with
+ /// is { } — and terminates.
+ /// https://github.com/asc-community/AngouriMath/issues/829
+ /// https://github.com/asc-community/AngouriMath/issues/833
+ ///
internal virtual Entity? ComputeLimitDivideEtImpera(Variable x, Entity dist, ApproachFrom side)
- => new Limitf(this, x, dist, side);
+ => null;
}
}
\ No newline at end of file
diff --git a/Sources/Tests/UnitTests/Calculus/LimitTerminatesOnEveryNodeTest.cs b/Sources/Tests/UnitTests/Calculus/LimitTerminatesOnEveryNodeTest.cs
new file mode 100644
index 000000000..3ff00033c
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/LimitTerminatesOnEveryNodeTest.cs
@@ -0,0 +1,112 @@
+//
+// 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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using AngouriMath;
+using AngouriMath.Core;
+using AngouriMath.Extensions;
+using Xunit;
+
+namespace AngouriMath.Tests.Calculus
+{
+ ///
+ /// A limit over any node terminates.
+ ///
+ ///
+ ///
+ /// used to default to
+ /// new Limitf(this, ...), so a node that did not override it crashed the process:
+ /// the caller evaluates the returned node to compare it, evaluating a Limitf
+ /// computes the limit, and computing arrives back at the default. Seven node types
+ /// inherited it and every one of them overflowed the stack —
+ /// floor, ceil, round, min, max, gcd and
+ /// phi.
+ ///
+ ///
+ /// The per-node regression tests could not have caught it, because the defect is in what
+ /// a node inherits by not being mentioned. So this enumerates the node types
+ /// instead of listing them: a node added tomorrow is covered on the day it is added,
+ /// which is the only shape of test that fixes this class of bug rather than its
+ /// instances.
+ ///
+ ///
+ /// Termination is the assertion, not the answer. Most of these have no limit this
+ /// library can compute and come back unevaluated, which is the honest result; what is
+ /// forbidden is not returning at all.
+ ///
+ /// https://github.com/asc-community/AngouriMath/issues/829
+ /// https://github.com/asc-community/AngouriMath/issues/833
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class LimitTerminatesOnEveryNodeTest
+ {
+ ///
+ /// One instance of every concrete node type under that can be
+ /// built from a variable, so that the limit has something to descend into.
+ ///
+ public static IEnumerable