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