Пример #1
0
        public static bool TryMatchVarPlusConst <Variable, Expression>(this IExpressionDecoder <Variable, Expression> decoder,
                                                                       Expression exp, out Variable var, out int k)
        {
            Contract.Requires(decoder != null);

            if (decoder.IsBinaryExpression(exp) && decoder.OperatorFor(exp) == ExpressionOperator.Addition)
            {
                var left  = decoder.LeftExpressionFor(exp);
                var right = decoder.RightExpressionFor(exp);

                if (decoder.IsConstantInt(left, out k) && decoder.IsVariable(right))
                {
                    var = decoder.UnderlyingVariable(right);

                    return(true);
                }

                if (decoder.IsConstantInt(right, out k) && decoder.IsVariable(left))
                {
                    var = decoder.UnderlyingVariable(left);

                    return(true);
                }
            }

            var = default(Variable);
            k   = default(int);
            return(false);
        }
Пример #2
0
            public static IDictionary <TVar, Sequence <TInterval> > LessThan <TEnv, TVar, TExpr, TInterval>
                (TExpr left, TExpr right, IExpressionDecoder <TVar, TExpr> decoder, TEnv env, out bool isBottom)
                where TEnv : IIntervalEnvironment <TVar, TExpr, TInterval, Rational>
                where TVar : IEquatable <TVar>
                where TInterval : IntervalBase <TInterval, Rational>
            {
                isBottom = false;
                var result = new Dictionary <TVar, Sequence <TInterval> > ();

                var leftIntv  = env.Eval(left);
                var rightIntv = env.Eval(right);

                var rightVar  = decoder.UnderlyingVariable(right);
                var successor = IsFloat(left, decoder) || IsFloat(right, decoder) ? Rational.Zero : Rational.One;

                TInterval refinedIntv;

                if (TryRefineKLessThanRight <TEnv, TVar, TExpr, TInterval> (leftIntv, rightVar, successor, env, out refinedIntv) && !refinedIntv.IsSinglePoint)
                {
                    AddToResult(result, rightVar, refinedIntv);
                }

                if (successor.IsZero)
                {
                    return(result);
                }

                var leftVar = decoder.UnderlyingVariable(left);

                if (TryRefineLessThan <TEnv, TVar, TExpr, TInterval> (leftVar, rightIntv, env, out refinedIntv) && !refinedIntv.IsSinglePoint)
                {
                    AddToResult(result, leftVar, refinedIntv);
                }

                Polynomial <TVar, TExpr> poly;
                Polynomial <TVar, TExpr> leftPoly;
                Polynomial <TVar, TExpr> rightPoly;

                if (Polynomial <TVar, TExpr> .TryBuildFrom(left, decoder, out leftPoly) &&
                    Polynomial <TVar, TExpr> .TryBuildFrom(right, decoder, out rightPoly) &&
                    Polynomial <TVar, TExpr> .TryToPolynomial(ExpressionOperator.LessThan, leftPoly, rightPoly, out poly) &&
                    poly.IsLinear)
                {
                    if (poly.Left.Length == 1)
                    {
                        return(TestTrueLessEqualThan_AxLtK(poly, env, result, out isBottom));
                    }
                    if (poly.Left.Length == 2)
                    {
                        return(TestTrueLessEqualThan_AxByLtK(poly, env, result, out isBottom));
                    }
                }

                return(result);
            }
Пример #3
0
            public static void NotEqual <TEnv, TVar, TExpr, TInterval>
                (TExpr left, TExpr right, IExpressionDecoder <TVar, TExpr> decoder, TEnv env, out InferenceResult <TVar, TInterval> resultLeft,
                out InferenceResult <TVar, TInterval> resultRight) where TInterval : IntervalBase <TInterval, Rational>
                where TEnv : IIntervalEnvironment <TVar, TExpr, TInterval, Rational>
                where TVar : IEquatable <TVar>
            {
                resultLeft  = InferenceResult <TVar, TInterval> .Empty;
                resultRight = InferenceResult <TVar, TInterval> .Empty;

                var leftIntv  = env.Eval(left);
                var rightIntv = env.Eval(right);

                var leftVar  = decoder.UnderlyingVariable(left);
                var rightVar = decoder.UnderlyingVariable(right);

                var successor = IsFloat(left, decoder) || IsFloat(right, decoder) ? Rational.Zero : Rational.One;

                // l != r <==> l < r && r < l
                LessThanRefinement <TEnv, TVar, TExpr, TInterval> (successor, env, leftIntv, rightIntv, leftVar, rightVar, ref resultLeft);
                LessThanRefinement <TEnv, TVar, TExpr, TInterval> (successor, env, rightIntv, leftIntv, rightVar, leftVar, ref resultRight);
            }
        static public void InferConstraints_NotEq <Variable, Expression, IType>(
            Expression left, Expression right,
            IExpressionDecoder <Variable, Expression> decoder,
            ISetOfNumbersAbstraction <Variable, Expression, Rational, IType> iquery,
            out List <Pair <Variable, IType> > resultLeft,
            out List <Pair <Variable, IType> > resultRight,
            out bool isBottomLeft,
            out bool isBottomRight)
            where IType : IntervalBase <IType, Rational>
        {
            isBottomLeft  = false; // False untils someone proves the contrary
            isBottomRight = false;

            resultLeft  = new List <Pair <Variable, IType> >();
            resultRight = new List <Pair <Variable, IType> >();

            var kLeft  = iquery.Eval(left);
            var kRight = iquery.Eval(right);

            var rightVar = decoder.UnderlyingVariable(right);
            var leftVar  = decoder.UnderlyingVariable(left);

            var succ = IsFloat(left, decoder) || IsFloat(right, decoder) ? Rational.For(0) : Rational.For(1);

            NewMethod <Variable, Expression, IType>(succ, iquery, kLeft, kRight, rightVar, leftVar, resultLeft);
            NewMethod <Variable, Expression, IType>(succ, iquery, kRight, kLeft, leftVar, rightVar, resultRight);

            // Try to infer some more fact
            Polynomial <Variable, Expression> tmpLeftPoly, tmpRightPoly;

            if (Polynomial <Variable, Expression> .TryToPolynomialForm(left, decoder, out tmpLeftPoly) &&
                Polynomial <Variable, Expression> .TryToPolynomialForm(right, decoder, out tmpRightPoly))
            {
                NewMethod2 <Variable, Expression, IType>(tmpLeftPoly, tmpRightPoly, iquery, ref isBottomLeft, resultLeft);
                NewMethod2 <Variable, Expression, IType>(tmpRightPoly, tmpLeftPoly, iquery, ref isBottomRight, resultRight);
            }
        }
Пример #5
0
            public static IDictionary <TVar, Sequence <TInterval> > GreaterEqualThanZero <TEnv, TVar, TExpr, TInterval>
                (TExpr expr, IExpressionDecoder <TVar, TExpr> decoder, TEnv env)
                where TEnv : IIntervalEnvironment <TVar, TExpr, TInterval, Rational>
                where TVar : IEquatable <TVar>
                where TInterval : IntervalBase <TInterval, Rational>
            {
                var result   = new Dictionary <TVar, Sequence <TInterval> > ();
                var variable = decoder.UnderlyingVariable(expr);

                AddToResult(result, variable, env.Eval(expr).Meet(env.Context.Positive));

                if (!decoder.IsVariable(expr))
                {
                    Polynomial <TVar, TExpr> zeroPoly;                    // poly(0)
                    if (!Polynomial <TVar, TExpr> .TryToPolynomial(new[] { Monomial <TVar> .From(Rational.Zero) }, out zeroPoly))
                    {
                        throw new AbstractInterpretationException(
                                  "It can never be the case that the conversion of a list of monomials into a polynomial fails.");
                    }

                    Polynomial <TVar, TExpr> exprPoly;                    // poly(expr)
                    Polynomial <TVar, TExpr> fullPoly;                    // '0 <= poly(expr)' polynome
                    if (Polynomial <TVar, TExpr> .TryBuildFrom(expr, decoder, out exprPoly) &&
                        Polynomial <TVar, TExpr> .TryToPolynomial(ExpressionOperator.LessEqualThan, zeroPoly, exprPoly, out fullPoly) &&
                        fullPoly.IsIntervalForm)
                    {
                        var  k = fullPoly.Left[0].Coeff;                        // k != 0
                        TVar x;
                        fullPoly.Left[0].IsSingleVariable(out x);

                        Rational constraint;
                        if (Rational.TryDivide(fullPoly.Right[0].Coeff, k, out constraint))
                        {
                            TInterval interval;
                            if (k > 0L)                             // +x <= constraint
                            {
                                interval = env.Eval(x).Meet(env.Context.For(Rational.MinusInfinity, constraint));
                            }
                            else                             // -x <= -constraint ==> x >= constraint
                            {
                                interval = env.Eval(x).Meet(env.Context.For(constraint, Rational.PlusInfinity));
                            }

                            AddToResult(result, x, interval);
                        }
                    }
                }
                return(result);
            }
Пример #6
0
 public void Add(TExpr e)
 {
     Add(decoder.UnderlyingVariable(e));
 }
Пример #7
0
        public virtual Out Visit(Expr expr, In data)
        {
            var op = Decoder.OperatorFor(expr);

            switch (op)
            {
            case Op.Constant:
                return(VisitConstant(expr, data));

            case Op.Variable:
                return(VisitVariable(Decoder.UnderlyingVariable(expr), expr, data));

            case Op.Not:
                return(DispatchVisitNot(Decoder.LeftExpressionFor(expr), data));

            case Op.And:
                return(VisitAnd(Decoder.LeftExpressionFor(expr), Decoder.RightExpressionFor(expr),
                                expr, data));

            case Op.Or:
                return(VisitOr(Decoder.LeftExpressionFor(expr), Decoder.RightExpressionFor(expr),
                               expr, data));

            case Op.Xor:
                return(VisitXor(Decoder.LeftExpressionFor(expr), Decoder.RightExpressionFor(expr),
                                expr, data));

            case Op.LogicalAnd:
                return(VisitLogicalAnd(Decoder.LeftExpressionFor(expr),
                                       Decoder.RightExpressionFor(expr), expr, data));

            case Op.LogicalOr:
                return(VisitLogicalOr(Decoder.LeftExpressionFor(expr),
                                      Decoder.RightExpressionFor(expr), expr, data));

            case Op.NotEqual:
                return(VisitNotEqual(Decoder.LeftExpressionFor(expr),
                                     Decoder.RightExpressionFor(expr), expr, data));

            case Op.Equal:
            case Op.Equal_Obj:
                return(DispatchVisitEqual(op, Decoder.LeftExpressionFor(expr),
                                          Decoder.RightExpressionFor(expr), expr, data));

            case Op.LessThan:
                return(DispatchCompare(VisitLessThan, Decoder.LeftExpressionFor(expr),
                                       Decoder.RightExpressionFor(expr), expr, data));

            case Op.LessEqualThan:
                return(DispatchCompare(VisitLessEqualThan, Decoder.LeftExpressionFor(expr),
                                       Decoder.RightExpressionFor(expr), expr, data));

            case Op.GreaterThan:
                return(DispatchCompare(VisitGreaterThan, Decoder.LeftExpressionFor(expr),
                                       Decoder.RightExpressionFor(expr), expr, data));

            case Op.GreaterEqualThan:
                return(DispatchCompare(VisitGreaterEqualThan, Decoder.LeftExpressionFor(expr),
                                       Decoder.RightExpressionFor(expr), expr, data));

            case Op.Add:
                return(VisitAddition(Decoder.LeftExpressionFor(expr),
                                     Decoder.RightExpressionFor(expr), expr, data));

            case Op.Div:
                return(VisitDivision(Decoder.LeftExpressionFor(expr),
                                     Decoder.RightExpressionFor(expr), expr, data));

            case Op.Sub:
                return(VisitSubtraction(Decoder.LeftExpressionFor(expr),
                                        Decoder.RightExpressionFor(expr), expr, data));

            case Op.Mod:
                return(VisitModulus(Decoder.LeftExpressionFor(expr), Decoder.RightExpressionFor(expr),
                                    expr, data));

            case Op.Mult:
                return(VisitMultiply(Decoder.LeftExpressionFor(expr),
                                     Decoder.RightExpressionFor(expr), expr, data));

            case Op.SizeOf:
                return(VisitSizeOf(Decoder.LeftExpressionFor(expr), data));

            case Op.UnaryMinus:
                return(VisitUnaryMinus(Decoder.LeftExpressionFor(expr), expr, data));

            case Op.LogicalNot:
                return(VisitLogicalNot(Decoder.LeftExpressionFor(expr), expr, data));

            case Op.Unknown:
                return(VisitUnknown(expr, data));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #8
0
        private static string ToString <Variable, Expression>(Expression exp, IExpressionDecoder <Variable, Expression> decoder, int height)
        {
            Contract.Requires(decoder != null);
            Contract.Requires(height >= 0);
            Contract.Ensures(Contract.Result <string>() != null);

            if (height > MaxHeight)
            {
                return("<too deep in the exp>");
            }
            else
            {
                switch (decoder.OperatorFor(exp))
                {
                    #region All the cases...
                case ExpressionOperator.Addition:
                    return(BinaryPrint("+", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.And:
                    return(BinaryPrint("&", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.Constant:
                    return(ConstantPrint(exp, decoder, height + 1));

                case ExpressionOperator.ConvertToInt32:
                    return(UnaryPrint("(int32)", decoder.LeftExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.ConvertToUInt8:
                    return(UnaryPrint("(uint8)", decoder.LeftExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.ConvertToUInt16:
                    return(UnaryPrint("(uint16)", decoder.LeftExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.ConvertToUInt32:
                    return(UnaryPrint("(uint32)", decoder.LeftExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.ConvertToFloat32:
                    return(UnaryPrint("(Single)", decoder.LeftExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.ConvertToFloat64:
                    return(UnaryPrint("(Double)", decoder.LeftExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.Division:
                    return(BinaryPrint("/", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.Equal:
                    return(BinaryPrint("==", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.Equal_Obj:
                    return(BinaryPrint("=Equals=", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.GreaterEqualThan:
                    return(BinaryPrint(">=", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.GreaterEqualThan_Un:
                    return(BinaryPrint(">=_un", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.GreaterThan:
                    return(BinaryPrint(">", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.GreaterThan_Un:
                    return(BinaryPrint(">_un", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.LessEqualThan:
                    return(BinaryPrint("<=", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.LessEqualThan_Un:
                    return(BinaryPrint("<=_un", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.LessThan:
                    return(BinaryPrint("<", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.LessThan_Un:
                    return(BinaryPrint("<_un", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.LogicalAnd:
                    return(BinaryPrint("&&", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.LogicalNot:
                    return(UnaryPrint("!", decoder.LeftExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.LogicalOr:
                    return(BinaryPrint("||", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.Modulus:
                    return(BinaryPrint("%", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.Multiplication:
                    return(BinaryPrint("*", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.Not:
                    return(UnaryPrint("!", decoder.LeftExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.NotEqual:
                    return(BinaryPrint("!=", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.Or:
                    return(BinaryPrint("|", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.Xor:
                    return(BinaryPrint("^", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.ShiftLeft:
                    return(BinaryPrint("<<", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.ShiftRight:
                    return(BinaryPrint(">>", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.SizeOf:
                    return(SizeOfPrint(exp, decoder, height + 1));

                case ExpressionOperator.Subtraction:
                    return(BinaryPrint("-", decoder.LeftExpressionFor(exp), decoder.RightExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.UnaryMinus:
                    return(UnaryPrint("-", decoder.LeftExpressionFor(exp), decoder, height + 1));

                case ExpressionOperator.Variable:
                    return(VariablePrint(decoder.UnderlyingVariable(exp), decoder, height + 1));

                case ExpressionOperator.WritableBytes:
                    return(exp.ToString());

                // return UnaryPrint("WritableBytes", decoder.LeftExpressionFor(exp), decoder, height + 1);
                case ExpressionOperator.Unknown:
                    return("<Unknown expression>");

                default:
                    throw new AbstractInterpretationException("Error, unknown case!!!!" + decoder.OperatorFor(exp));
                    #endregion
                }
            }
        }
Пример #9
0
 public void Assign(Expression x, Expression exp)
 {
     this.State = AbstractState.Normal;
     this[decoder.UnderlyingVariable(x)] = Eval(exp);
 }
        static public List <Pair <Variable, IType> > InferConstraints_LT <Variable, Expression, IType>(
            bool isSignedComparison,
            Expression left, Expression right,
            IExpressionDecoder <Variable, Expression> decoder,
            ISetOfNumbersAbstraction <Variable, Expression, Rational, IType> iquery,
            out bool isBottom)
            where IType : IntervalBase <IType, Rational>
        {
            Contract.Ensures(Contract.Result <List <Pair <Variable, IType> > >() != null);

            isBottom = false; // False untils someone proves the contrary

            var result = new List <Pair <Variable, IType> >();

            var kLeft  = iquery.Eval(left);
            var kRight = iquery.Eval(right);

            if (!isSignedComparison && !IsFloat(left, decoder) && !IsFloat(right, decoder))
            {
                kLeft  = kLeft.ToUnsigned();
                kRight = kRight.ToUnsigned();
            }

            IType refinedIntv;
            var   rightVar = decoder.UnderlyingVariable(right);

            var succ = IsFloat(left, decoder) || IsFloat(right, decoder) ? Rational.For(0) : Rational.For(1);

            if (TryRefine_KLessThanRight(isSignedComparison, kLeft, rightVar, succ, iquery, out refinedIntv))
            {
                // If it is an unsigned comparison, and it is a constant, then we should avoid generating the constraint
                // Example: left <{un} right, with right == -1 then we do not want to generate the constraint right == 2^{32}-1 which is wrong!

                // unsigned ==> right is not a constant
                if (isSignedComparison || !kRight.IsSingleton)
                {
                    result.Add(rightVar, refinedIntv);
                }
            }

            if (IsFloat(left, decoder) || IsFloat(right, decoder))
            {
                return(result);
            }

            var leftVar = decoder.UnderlyingVariable(left);

            if (TryRefine_LeftLessThanK(isSignedComparison, leftVar, kRight, iquery, out refinedIntv))
            {
                // As above
                // unsigned ==> right is not a constant
                if (isSignedComparison || !kLeft.IsSingleton)
                {
                    result.Add(leftVar, refinedIntv);
                }
            }

            if (isSignedComparison)
            {
                // Try to infer some more fact
                Polynomial <Variable, Expression> guardInCanonicalForm;
                if (Polynomial <Variable, Expression> .TryToPolynomialForm(ExpressionOperator.LessThan, left, right, decoder, out guardInCanonicalForm) &&
                    guardInCanonicalForm.IsLinear)
                {
                    // First, we consider only the case when there is at MOST one variable on the left, i.e. a * x < b
                    {
                        if (guardInCanonicalForm.Left.Length == 1)
                        {
                            result = HelperFortestTrueLessThan_AxLtK(guardInCanonicalForm, iquery, result, out isBottom);
                        }
                        // Then, we consider the case when it is in the form a*x + b*y < k
                        else if (guardInCanonicalForm.Left.Length == 2)
                        {
                            return(HelperFortestTrueLessThan_AxByLtK(guardInCanonicalForm, iquery, result, out isBottom));
                        }
                    }
                }
                else
                {
                    #region Try to infer something else...
                    switch (decoder.OperatorFor(left))
                    {
                    case ExpressionOperator.And: // case "(leftLeft && leftRight) < right
                        var leftRight = decoder.RightExpressionFor(left);

                        Int32 valueLeft;
                        if (decoder.IsConstantInt(leftRight, out valueLeft))
                        {
                            if (IsPowerOfTwoMinusOne(valueLeft))
                            { // add the constraint " 0 <= right < valueLeft "
                                var oldVal  = iquery.Eval(right);
                                var evalVal = iquery.Eval(left);
                                var newVal  = iquery.For(Rational.For(0), Rational.For(valueLeft - 1)); //  [0, valueLeft-1], "-1" as we know it is an integer

                                result.Add(rightVar, oldVal.Meet(newVal).Meet(evalVal));
                            }
                        }
                        break;

                    default:
                        // do nothing...
                        break;
                    }

                    #endregion
                }
            }
            return(result);
        }
        static public List <Pair <Variable, IType> > InferConstraints_Leq <Variable, Expression, IType>(
            bool isSignedComparison,
            Expression left, Expression right,
            IExpressionDecoder <Variable, Expression> decoder,
            ISetOfNumbersAbstraction <Variable, Expression, Rational, IType> iquery,
            out bool isBottom)
            where IType : IntervalBase <IType, Rational>
        {
            Contract.Requires(iquery != null);
            Contract.Ensures(Contract.Result <List <Pair <Variable, IType> > >() != null);

            isBottom = false; // false, unless someine proves the contrary

            var result = new List <Pair <Variable, IType> >();

            if (IsFloat(left, decoder) || IsFloat(right, decoder))
            {
                return(result);
            }

            var kLeft  = iquery.Eval(left);
            var kRight = iquery.Eval(right);

            // We have to take into account the polymorphism of constants
            if (!isSignedComparison)
            {
                kLeft  = kLeft.ToUnsigned();
                kRight = kRight.ToUnsigned();
            }

            //AssumeKLessEqualThanRight(kLeft, this.Decoder.UnderlyingVariable(right))

            IType refinedIntv;
            var   rightVar = decoder.UnderlyingVariable(right);

            if (IntervalInference.TryRefine_KLessEqualThanRight(isSignedComparison, kLeft, rightVar, iquery, out refinedIntv))
            {
                // If it is an unsigned comparison, and it is a constant, then we should avoid generating the constraint
                // Example: left <={un} right, with right == -1 then we do not want to generate the constraint right == 2^{32}-1 which is wrong!

                // unsigned ==> right is not a constant
                if (isSignedComparison || !kRight.IsSingleton)
                {
                    result.Add(rightVar, refinedIntv);
                }
            }

            //AssumeLeftLessEqualThanK(this.Decoder.UnderlyingVariable(left), kRight);
            var leftVar = decoder.UnderlyingVariable(left);

            if (IntervalInference.TryRefine_LeftLessEqualThanK(isSignedComparison, leftVar, kRight, iquery, out refinedIntv))
            {
                // unsigned ==> left is not a constant
                if (isSignedComparison || !kLeft.IsSingleton)
                {
                    result.Add(leftVar, refinedIntv);
                }
            }

            if (isSignedComparison)
            {
                Polynomial <Variable, Expression> guardInCanonicalForm;

                if (Polynomial <Variable, Expression> .TryToPolynomialForm(ExpressionOperator.LessEqualThan, left, right, decoder, out guardInCanonicalForm) &&
                    guardInCanonicalForm.IsLinear)
                {
                    // We consider only the case when there is at MOST one variable on the left, i.e. a * x \leq b, or TWO, i.e. a*x +b*y <= c
                    if (guardInCanonicalForm.Left.Length == 1)
                    {
                        return(HelperFortestTrueLessEqualThan_AxLeqK(guardInCanonicalForm, iquery, result, out isBottom));
                    }
                    else if (guardInCanonicalForm.Left.Length == 2)
                    {
                        return(HelperFortestTrueLessEqualThan_AxByLtK(guardInCanonicalForm, iquery, result, out isBottom));
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// Infer exp \in [0, +oo], and if exp is a compound expression also some other constraints
        /// </summary>
        static public List <Pair <Variable, IType> > InferConstraints_GeqZero <Variable, Expression, IType>(
            Expression exp, IExpressionDecoder <Variable, Expression> decoder,
            ISetOfNumbersAbstraction <Variable, Expression, Rational, IType> iquery)
            where IType : IntervalBase <IType, Rational>
        {
            Contract.Requires(decoder != null);
            Contract.Requires(iquery != null);

            Contract.Ensures(Contract.Result <List <Pair <Variable, IType> > >() != null);

            var result = new List <Pair <Variable, IType> >();

            var expVar = decoder.UnderlyingVariable(exp);

            result.Add(expVar, iquery.Eval(exp).Meet(iquery.Interval_Positive));

            if (!decoder.IsVariable(exp))
            {
                Polynomial <Variable, Expression> zero; // = 0

                if (!Polynomial <Variable, Expression> .TryToPolynomialForm(new Monomial <Variable>[] { new Monomial <Variable>(0) }, out zero))
                {
                    throw new AbstractInterpretationException("It can never be the case that the conversion of a list of monomials into a polynomial fails");
                }

                Polynomial <Variable, Expression> expAsPolynomial, newPolynomial;

                if (Polynomial <Variable, Expression> .TryToPolynomialForm(exp, decoder, out expAsPolynomial) &&
                    Polynomial <Variable, Expression> .TryToPolynomialForm(ExpressionOperator.LessEqualThan, zero, expAsPolynomial, out newPolynomial)) // 0 <= exp
                {
                    if (newPolynomial.IsIntervalForm)
                    { // if it is in the form of k1 * x <= k2
                        var k1 = newPolynomial.Left[0].K;
                        var x  = newPolynomial.Left[0].VariableAt(0);

                        var k2 = newPolynomial.Right[0].K;

                        Rational bound;
                        if (Rational.TryDiv(k2, k1, out bound)) //var bound = k2 / k1;
                        {
                            if (k1 > 0)
                            {
                                var intv = iquery.Eval(x).Meet(iquery.IntervalLeftOpen(bound));
                                result.Add(x, intv);
                            }
                            else if (k1 < 0)
                            {
                                var intv = iquery.Eval(x).Meet(iquery.IntervalRightOpen(bound));
                                result.Add(x, intv);
                            }
                            else
                            {
                                throw new AbstractInterpretationException("Impossible case");
                            }
                        }
                    }
                }
            }

            return(result);
        }
Пример #13
0
 public IntervalEnvironmentBase <TVar, TExpr, TInterval, TNumeric> AssumeTrue(TExpr guard)
 {
     Assumer.AssumeNotEqualToZero(Decoder.UnderlyingVariable(guard), this);
     return(new IntervalTestVisitor(Decoder).VisitTrue(guard, this));
 }