private DisIntervalEnvironment <Variable, Expression> HelperForTestTrueLessThanSignedOrUnsigned(bool isSigned, Expression exp1, Expression exp2)
        {
            bool isBottom;
            var  newConstraints = IntervalInference.InferConstraints_LT(isSigned, exp1, exp2, this.ExpressionManager.Decoder, this, out isBottom);

            if (isBottom)
            {
                return(this.Bottom);
            }

            Assume(newConstraints);

            return(this);
        }
        /// <summary>
        /// We handle just expressions (that after being normalized) become "  a * x \lt b ", where {a, b} are constants and "x" is a variable
        /// </summary>
        private IntervalEnvironment <Variable, Expression> HelperForTestTrueLessThanSignedOrUnsigned(bool isSigned, Expression left, Expression right)
        {
            bool isBottom;
            var  constraints = IntervalInference.InferConstraints_LT(isSigned, left, right, this.ExpressionManager.Decoder, this, out isBottom);

            if (isBottom)
            {
                return(this.Bottom);
            }

            foreach (var pair in constraints)
            {
                this.RefineWith(pair.One, pair.Two);
            }
            return(this);
        }
        public override DisIntervalEnvironment <Variable, Expression> TestNotEqual(Expression e1, Expression e2)
        {
            var v2 = this.Eval(e2);

            if (v2.IsSingleton)
            {
                var notV2 = DisInterval.NotInThisInterval(v2);

                var e1Var = this.ExpressionManager.Decoder.UnderlyingVariable(this.ExpressionManager.Decoder.Stripped(e1));

                this.RefineWith(e1Var, notV2);
            }

            bool isBottomLT, isBottomGT;

            var constraintsLT = IntervalInference.InferConstraints_LT(true, e1, e2, this.ExpressionManager.Decoder, this, out isBottomLT);
            var constraintsGT = IntervalInference.InferConstraints_LT(true, e2, e1, this.ExpressionManager.Decoder, this, out isBottomGT);

            if (isBottomLT)
            {
                // Bottom join Bottom = Bottom
                if (isBottomGT)
                {
                    return(this.Bottom);
                }
                this.TestTrueListOfFacts(constraintsGT);
            }
            else if (isBottomGT)
            {
                this.TestTrueListOfFacts(constraintsLT);
            }
            else
            {
                var join = JoinConstraints(constraintsLT, constraintsGT);

                this.TestTrueListOfFacts(join);
            }

            return(this);
        }