/// <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); }
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))); } }
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>()); }
//[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); }
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); }