예제 #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 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);
        }
예제 #3
0
        private static bool IsConstantTrueOrFalse <Variable, Expression>(
            Expression e, bool t, IExpressionDecoder <Variable, Expression> decoder)
        {
            Contract.Requires(decoder != null);

            bool  boolValue;
            Int32 intValue;

            if (decoder.IsConstant(e))
            {
                if (decoder.TryValueOf <bool>(e, ExpressionType.Bool, out boolValue))
                {
                    return(boolValue == t);
                }
                else if (decoder.IsConstantInt(e, out intValue))
                {
                    return((intValue != 0) == t);
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
예제 #4
0
        /// <summary>
        /// Construct left - right, or left iff right == 0
        /// </summary>
        public static Expression SmartSubtraction <Variable, Expression>(this IExpressionEncoder <Variable, Expression> encoder,
                                                                         Expression left, Expression right, IExpressionDecoder <Variable, Expression> decoder)
        {
            Contract.Requires(decoder != null);
            Contract.Requires(encoder != null);

            int value;

            if (decoder.IsConstantInt(right, out value) && value == 0)
            {
                return(left);
            }

            return(encoder.CompoundExpressionFor(ExpressionType.Int32, ExpressionOperator.Subtraction, left, right));
        }
예제 #5
0
        public TInterval Eval(TExpr expr)
        {
            int intValue;

            if (Decoder.IsConstantInt(expr, out intValue))
            {
                return(Context.For(intValue));
            }

            var evaluator = new EvaluateExpressionVisitor <IntervalEnvironmentBase <TVar, TExpr, TInterval, TNumeric>, TVar, TExpr, TInterval, TNumeric> (Decoder);
            var interval  = evaluator.Visit(expr, new Counter <IntervalEnvironmentBase <TVar, TExpr, TInterval, TNumeric> > (this));

            if (evaluator.DuplicatedOccurences.Length() >= 1)
            {
                var       noDuplicates = true;
                TInterval result       = null;
                foreach (var var in evaluator.DuplicatedOccurences.AsEnumerable())
                {
                    TInterval intv;
                    if (TryGetValue(var, out intv) && intv.IsFinite &&
                        Context.IsGreaterEqualThanZero(intv.LowerBound))
                    {
                        var extreme = EvalWithExtremes(expr, var, intv);
                        if (noDuplicates)
                        {
                            noDuplicates = false;
                            result       = extreme;
                        }
                        else
                        {
                            result = result.Join(extreme);
                        }
                    }
                }

                if (!noDuplicates)
                {
                    interval = result;
                }
            }

            return(interval);
        }
        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);
        }