Пример #1
0
        public static bool Match_E1aritopE2eq0 <Variable, Expression>(
            this IExpressionDecoder <Variable, Expression> decoder,
            Expression e1, Expression e2,
            out ExpressionOperator op, out Expression e11, out Expression e12)
        {
            Contract.Requires(decoder != null);

            Int32 value;

            if (decoder.IsConstantInt(e2, out value) && value == 0)
            {
                op = decoder.OperatorFor(e1);
                if (op.Equals(ExpressionOperator.Addition) || op.Equals(ExpressionOperator.Subtraction))
                {
                    e11 = decoder.LeftExpressionFor(e1);
                    e12 = decoder.RightExpressionFor(e1);
                    return(true);
                }
            }

            op  = default(ExpressionOperator);
            e11 = e12 = default(Expression);

            return(false);
        }
Пример #2
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);
        }
        static bool IsVariableEqConstant(Expression guard, IExpressionDecoder <Variable, Expression> decoder)
        {
            switch (decoder.OperatorFor(guard))
            {
            case ExpressionOperator.Equal:
            case ExpressionOperator.Equal_Obj:
                Expression left  = decoder.LeftExpressionFor(guard);
                Expression right = decoder.RightExpressionFor(guard);

                return((decoder.IsVariable(left) && decoder.IsConstant(right)) || (decoder.IsVariable(right) && decoder.IsConstant(right)));

            default:
                return(false);
            }
        }
Пример #4
0
 static public Exp <E> Box <E>(E exp, IExpressionDecoder <E> decoder)
 {
     if (decoder.IsVariable(exp))
     {
         return(new Var <E>(exp, decoder));
     }
     else
     {
         switch (decoder.OperatorFor(exp))
         {
         case ExpressionOperator.ConvertToInt32:
         case ExpressionOperator.ConvertToUInt16:
         case ExpressionOperator.ConvertToUInt32:
         case ExpressionOperator.ConvertToUInt8:
             return(Box(decoder.LeftExpressionFor(exp), decoder));
         }
         return(new Exp <E>(exp, decoder));
     }
 }
Пример #5
0
        private IStringAbstraction Eval(Expression /*!*/ exp)
        {
            IStringAbstraction result;

            switch (decoder.OperatorFor(exp))
            {
            case ExpressionOperator.Constant:
                result = EvalConstant(exp);
                break;

            case ExpressionOperator.Variable:
                var v = decoder.UnderlyingVariable(exp);
                result = EvalVariable(v);
                break;

            default:
                result = topString;
                break;
            }

            return(result);
        }
Пример #6
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();
            }
        }
Пример #7
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
                }
            }
        }
        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);
        }