static bool BoundVariable <TVar, TInterval>
                (IntervalContextBase <TInterval, Rational> ctx, Rational a, TInterval xIntervalOld, TInterval boundingInterval, TVar x,
                IDictionary <TVar, Sequence <TInterval> > result, out bool isBottom,
                Func <Rational, TInterval> upperBounded, Func <Rational, TInterval> lowerBounded)
                where TVar : IEquatable <TVar>
                where TInterval : IntervalBase <TInterval, Rational>
            {
                isBottom = false;
                if (a.IsZero)
                {
                    TInterval boundingForVariable;
                    if (a.Sign > 0L)
                    {
                        boundingForVariable = upperBounded(boundingInterval.UpperBound);
                    }
                    else
                    {
                        boundingForVariable = lowerBounded(boundingInterval.LowerBound);
                    }

                    var refined = xIntervalOld.Meet(boundingForVariable);
                    if (refined.IsBottom)
                    {
                        isBottom = true;
                        return(true);
                    }

                    AddToResult(result, x, refined);
                }
                return(false);
            }
            static IDictionary <TVar, Sequence <TInterval> > TestTrueLessEqualThan_AxByLtK <TEnv, TVar, TExpr, TInterval>
                (Polynomial <TVar, TExpr> poly, TEnv env, IDictionary <TVar, Sequence <TInterval> > result, out bool isBottom)
                where TEnv : IIntervalEnvironment <TVar, TExpr, TInterval, Rational>
                where TVar : IEquatable <TVar>
                where TInterval : IntervalBase <TInterval, Rational>
            {
                // ax + by <= k
                var ax = poly.Left[0];
                var by = poly.Left[1];

                TVar x, y;

                ax.IsSingleVariable(out x);
                by.IsSingleVariable(out y);

                var k = poly.Right[0].Coeff;
                var a = ax.Coeff;
                var b = by.Coeff;

                var aInterval = env.Context.For(a);
                var bInterval = env.Context.For(b);
                var kInterval = env.Context.For(k);

                var xInterval = env.Eval(x);
                var yInterval = env.Eval(y);

                IntervalContextBase <TInterval, Rational> ctx = env.Context;
                Func <Rational, TInterval> upperBounded       =
                    (i) => ctx.For(Rational.MinusInfinity, !i.IsInteger ? i.PreviousInt32 : i - 1L);
                Func <Rational, TInterval> lowerBounded =
                    (i) => ctx.For(!i.IsInteger ? i.NextInt32 : i + 1L, Rational.PlusInfinity);

                // x <= (k - (b * y)) / a;
                var boundingInterval = ctx.Div(ctx.Sub(kInterval, ctx.Mul(bInterval, yInterval)), aInterval);

                if (BoundVariable(ctx, a, xInterval, boundingInterval, x, result, out isBottom, upperBounded, lowerBounded))
                {
                    return(result);
                }

                // y <= (k - (a * x)) / b;
                boundingInterval = ctx.Div(ctx.Sub(kInterval, ctx.Mul(aInterval, xInterval)), bInterval);
                if (BoundVariable(ctx, b, yInterval, boundingInterval, y, result, out isBottom, upperBounded, lowerBounded))
                {
                    return(result);
                }

                return(result);
            }