Beispiel #1
0
        /// <summary>
        /// We only add less equals
        /// </summary>
        public NonRelationalValueAbstraction <Variable, Expression> AssumeInformationFrom <Exp>(INumericalAbstractDomainQuery <Variable, Exp> oracle)
        {
            var result = this;

            if (this.IsNormal())
            {
                #region Update <
                if (this.StrictUpperBounds.IsNormal())
                {
                    var newConstraints = new Set <Variable>(this.StrictUpperBounds.Values);

                    foreach (var x in this.StrictUpperBounds.Values)
                    {
                        // Add S such that x <= S
                        var newBounds = oracle.UpperBoundsFor(x, true).ApplyToAll(oracle.ToVariable);
                        Contract.Assert(newBounds != null);
                        newConstraints.AddRange(newBounds);
                    }

                    result = result.Update(ADomains.StrictUpperBounds, new SetOfConstraints <Variable>(newConstraints, false));
                }
                #endregion

                #region Update <=
                if (this.WeakUpperBounds.IsNormal())
                {
                    var newConstraints = new Set <Variable>(this.WeakUpperBounds.Values);

                    foreach (var x in this.WeakUpperBounds.Values)
                    {
                        // Add S such that x <= S
                        var newBounds = oracle.UpperBoundsFor(x, false).ApplyToAll(oracle.ToVariable);
                        Contract.Assert(newBounds != null);
                        newConstraints.AddRange(newBounds);
                    }

                    result = result.Update(ADomains.WeakUpperBounds, new SetOfConstraints <Variable>(newConstraints, false));
                }
                #endregion
            }

            return(result);
        }
Beispiel #2
0
        private void Helper_Match_kY(
            Expression x, INumericalAbstractDomainQuery <Variable, Expression> oracleDomain, List <Expression> result, Expression y)
        {
            Contract.Requires(result != null);

            Expression ltExp;

            if (oracleDomain.BoundsFor(y).LowerBound >= 1)
            {
                ltExp = expManager.Encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.LessThan, y, x);
                result.Add(ltExp);

                result.AddRange(UpperBounds(y, oracleDomain.UpperBoundsFor(x, false)));
            }
        }
Beispiel #3
0
            public override Set <Expression> VisitShiftRight(Expression left, Expression right, Expression original, INumericalAbstractDomainQuery <Variable, Expression> data)
            {
                if (this.AreInfinities(left, right))
                {
                    return(new Set <Expression>());
                }

                var bounds = data.BoundsFor(right).AsInterval;
                int val;
                Polynomial <Variable, Expression> pol;

                if (bounds.IsFiniteAndInt32Singleton(out val) && val > 0 &&
                    Polynomial <Variable, Expression> .TryToPolynomialForm(left, this.Decoder, out pol) &&
                    pol.IsLinear && !pol.Relation.HasValue && pol.Left.Length <= (1 << val))
                {
                    var ub = null as IEnumerable <Expression>;

                    foreach (var m in pol.Left)
                    {
                        Variable v;
                        if (m.IsVariable(out v) && data.BoundsFor(v).LowerBound >= 0)
                        {
                            var upperbounds = data.UpperBoundsFor(v, true);
                            ub = ub == null ? upperbounds : ub.Intersect(upperbounds);

                            if (ub.Any())
                            {
                                continue;
                            }
                        }
                        return(new Set <Expression>());
                    }

                    // If we reach this point, we have meaningful constraints

                    return(new Set <Expression>(ub.ApplyToAll(exp => expManager.Encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.LessThan, x, exp))));
                }

                return(new Set <Expression>());
            }
Beispiel #4
0
        //[SuppressMessage("Microsoft.Contracts", "Ensures-106-407")]
        public List <Expression> InferConstraints(Expression x, Expression exp, INumericalAbstractDomainQuery <Variable, Expression> adom)
        {
            Contract.Assert(adom != null);

            var xExp   = new Pair <Expression, Expression>(x, exp);
            var result = new List <Expression>();

            Polynomial <Variable, Expression> expAsPol;

            var decoder = expManager.Decoder;
            var encoder = expManager.Encoder;

            if (Polynomial <Variable, Expression> .TryToPolynomialForm(exp, decoder, out expAsPol))
            {
                if (expAsPol.IsLinear)
                {
                    #region The cases
                    Expression leqExp;
                    Variable   y;
                    Rational   k;

                    // If it is in the form y - k, with k constant, then we add the constraint " x <= y "
                    if (expAsPol.TryMatch_YMinusK(out y, out k))
                    {
                        var yExp = encoder.VariableFor(y);

                        leqExp = encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.LessEqualThan, x, yExp);

                        Contract.Assert(leqExp != null);

                        result.Add(leqExp);  // add the constraint x <= y
                    }
                    // If it is in the form y + k, with k constant, we add the constraint "y <= x"
                    else if (expAsPol.TryMatch_YPlusK(out y, out k))
                    {
                        var yExp = encoder.VariableFor(y);

                        leqExp = encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.LessEqualThan, yExp, x);

                        Contract.Assert(leqExp != null);

                        result.Add(leqExp); // As we know x, this is a clever encoding for the constraint y <= x

                        // x = y + 1 then if y < z => x <= z
                        if (k == 1)
                        {
                            result.AddRange(UpperBoundsNonStrict(x, adom.UpperBoundsFor(y, true)));
                        }
                    }
                    // If it is in the form k * y then it add the constaints "y <= x" or "x <= y"
                    else if (expAsPol.TryMatch_kY(out y, out k))
                    {
                        var yExp = encoder.VariableFor(y);

                        Contract.Assert(yExp != null);

                        if (TryHelperFor_MatchkY(x, adom, yExp, k, out leqExp))
                        {
                            // F: this should be some bug, it is not taking into account the postcondition
                            Contract.Assume(leqExp != null);

                            result.Add(leqExp);
                        }
                    }
                    #endregion
                }
            }

            var nonPolynomial = new TreatNonPolynomialCases(x, expManager).Visit(exp, adom);

            Contract.Assert(nonPolynomial != null);

            result.AddRange(nonPolynomial);

            Contract.Assume(Contract.ForAll(result, e => e != null));

            return(result);
        }
Beispiel #5
0
        public List <Expression> InferConstraints(Expression x, Expression exp, INumericalAbstractDomainQuery <Variable, Expression> oracleDomain)
        {
            Polynomial <Variable, Expression> expAsPol;
            Expression ltExp;

            var result = new List <Expression>();
            var xExp   = new Pair <Expression, Expression>(x, exp);

            #region 0. Fetch the cache
            Cache_Entry <Expression> cached;
            if (cache.TryGetValue(xExp, out cached))
            {
                switch (cached.Match_case)
                {
                case Cache_Entry.MatchCase.YMinusK:
                    result.Add(cached.ResultExpression);
                    result.AddRange(UpperBounds(cached.X, oracleDomain.UpperBoundsFor(cached.Y, false)));
                    break;

                case Cache_Entry.MatchCase.YPlusK:
                    result.Add(cached.ResultExpression);
                    result.AddRange(UpperBounds(cached.Y, oracleDomain.UpperBoundsFor(cached.X, false)));
                    break;

                case Cache_Entry.MatchCase.kY:
                    Helper_Match_kY(cached.X, oracleDomain, result, cached.Y);
                    break;

                case Cache_Entry.MatchCase.NotLinear:
                    // do nothing: this case essentially avoids the computation in the other branchs that we know to be unfruitfull
                    break;

                default:
                    // error?
                    break;
                }
            }
            #endregion

            #region 1. If failed, Try to put the r-exp in a polynomial (with simplifications, etc.)
            else if (Polynomial <Variable, Expression> .TryToPolynomialForm(exp, expManager.Decoder, out expAsPol))
            {
                if (expAsPol.IsLinear)
                {
                    // If it is in the form y - k, with k constant, then we add the constraint
                    Variable y;
                    Rational k;
                    if (expAsPol.TryMatch_YMinusK(out y, out k) && !x.Equals(y))
                    {
                        var yExp = expManager.Encoder.VariableFor(y);

                        ltExp = expManager.Encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.LessThan, x, yExp);
                        result.Add(ltExp);

                        result.AddRange(UpperBounds(x, oracleDomain.UpperBoundsFor(y, false)));

                        // update the cache
                        cache.Add(xExp, Cache_Entry.For(Cache_Entry.MatchCase.YMinusK, x, yExp, k, ltExp));
                    }
                    // If it is in the form y + k, with k constant, we add the constraint "y < x" to the back constraits
                    else if (expAsPol.TryMatch_YPlusK(out y, out k) && !x.Equals(y))
                    {
                        var yExp = expManager.Encoder.VariableFor(y);

                        ltExp = expManager.Encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.LessThan, yExp, x);

                        result.Add(ltExp);
                        result.AddRange(UpperBounds(yExp, oracleDomain.UpperBoundsFor(x, false)));

                        // update the cache
                        cache.Add(xExp, Cache_Entry.For(Cache_Entry.MatchCase.YPlusK, x, yExp, k, ltExp));
                    }
                    // If it is in the form k*y, with k constant, if k > 1 we add the constraint "x > y"
                    else if (expAsPol.TryMatch_kY(out y, out k) && !x.Equals(y))
                    {
                        var yExp = expManager.Encoder.VariableFor(y);
                        if (k > 1)
                        {
                            Helper_Match_kY(x, oracleDomain, result, yExp);
                            cache.Add(xExp, Cache_Entry.For(Cache_Entry.MatchCase.kY, x, yExp, k, default(Expression)));
                        }
                        else
                        {
                            cache.Add(xExp, Cache_Entry.ForNonLinear <Expression>());
                        }
                    }
                }
            }
            #endregion

            #region 2. Special treatment for reminder and non polynomial expressions

            result.AddRange(new TreatNonPolynomialCases(x, expManager).Visit(exp, oracleDomain));

            #endregion

            return(result);
        }