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