public static bool Match(IExpr /*!*/ expr, IFunctionSymbol /*!*/ f, params Matcher[] /*!*/ subs) { Contract.Requires(subs != null); Contract.Requires(f != null); Contract.Requires(expr != null); IFunApp app = MatchFunctionSymbol(expr, f); if (app != null) { int i = 0; // Note ***0*** foreach (Matcher /*!*/ s in subs) { Contract.Assert(s != null); if (!s(cce.NonNull((IExpr)app.Arguments[i]))) { return(false); } i++; } return(true); } else { return(false); } }
private static bool IsSimpleEquality(IExpr expr, out IVariable left, out IVariable right) { Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out left) != null && Contract.ValueAtReturn(out right) != null); left = null; right = null; // See if we have an equality IFunApp nary = expr as IFunApp; if (nary == null || !nary.FunctionSymbol.Equals(Value.Eq)) { return(false); } // See if it is an equality of two variables IVariable idLeft = nary.Arguments[0] as IVariable; IVariable idRight = nary.Arguments[1] as IVariable; if (idLeft == null || idRight == null) { return(false); } left = idLeft; right = idRight; return(true); }
private static ArrayList /*<IExpr>*//*!*/ FindConjuncts(IExpr e) { Contract.Ensures(Contract.Result <ArrayList>() != null); ArrayList result = new ArrayList(); IFunApp f = e as IFunApp; if (f != null) { if (f.FunctionSymbol.Equals(Prop.And)) { foreach (IExpr arg in f.Arguments) { result.AddRange(FindConjuncts(arg)); } } else if (f.FunctionSymbol.Equals(Prop.Or) || f.FunctionSymbol.Equals(Prop.Implies)) { // Do nothing. } else { result.Add(e); } } else { result.Add(e); } return(result); }
// Ternary Binding public static bool Match(IExpr /*!*/ expr, IFunctionSymbol /*!*/ f, out IExpr arg0, out IExpr arg1, out IExpr arg2, params Matcher[] /*!*/ subs) { Contract.Requires(subs != null); Contract.Requires(f != null); Contract.Requires(expr != null); arg0 = null; arg1 = null; arg2 = null; IFunApp app = MatchFunctionSymbol(expr, f); if (app != null) { arg0 = (IExpr /*!*/)cce.NonNull(app.Arguments[0]); arg1 = (IExpr /*!*/)cce.NonNull(app.Arguments[1]); arg2 = (IExpr /*!*/)cce.NonNull(app.Arguments[2]); int i = 3; // Note ***3*** foreach (Matcher /*!*/ s in subs) { Contract.Assert(s != null); if (!s(cce.NonNull((IExpr /*!*/)app.Arguments[i]))) { return(false); } i++; } return(true); } else { return(false); } }
/// <summary> /// Returns true iff the expression is in the form var == arithmeticExpr /// </summary> private static bool IsArithmeticExpr(IExpr /*!*/ expr) { Contract.Requires(expr != null); // System.Console.WriteLine("\t\tIsArithmetic called with {0} of type {1}", expr, expr.GetType().ToString()); if (expr is IVariable) // expr is a variable { return(true); } else if (expr is IFunApp) // may be ==, +, -, /, % or an integer { IFunApp fun = (IFunApp)expr; if (fun.FunctionSymbol is IntSymbol) // it is an integer { return(true); } else if (fun.FunctionSymbol.Equals(Int.Negate)) // it is an unary minus { return(IsArithmeticExpr((IExpr /*!*/)cce.NonNull(fun.Arguments[0]))); } else if (fun.Arguments.Count != 2) // A function of two or more operands is not arithmetic { return(false); } else { IExpr /*!*/ left = (IExpr /*!*/)cce.NonNull(fun.Arguments[0]); IExpr /*!*/ right = (IExpr /*!*/)cce.NonNull(fun.Arguments[1]); if (!(left is IVariable || right is IVariable)) // At least one of the two operands must be a variable { return(false); } if (fun.FunctionSymbol.Equals(Value.Eq) || fun.FunctionSymbol.Equals(Int.Add) || fun.FunctionSymbol.Equals(Int.Sub) || fun.FunctionSymbol.Equals(Int.Mul) || fun.FunctionSymbol.Equals(Int.Div) || fun.FunctionSymbol.Equals(Int.Mod)) { return(IsArithmeticExpr(left) && IsArithmeticExpr(right)); } else { return(false); } } } else { return(false); } }
/// <summary> /// Yield an expression that is 'inexpr' with 'var' replaced by 'subst'. /// </summary> /// <param name="subst">The expression to substitute.</param> /// <param name="var">The variable to substitute for.</param> /// <param name="inexpr">The expression to substitute into.</param> public static IExpr /*!*/ Substitute(IExpr /*!*/ subst, IVariable /*!*/ var, IExpr /*!*/ inexpr) { Contract.Requires(inexpr != null); Contract.Requires(var != null); Contract.Requires(subst != null); Contract.Ensures(Contract.Result <IExpr>() != null); IExpr result = null; if (inexpr is IVariable) { result = inexpr.Equals(var) ? subst : inexpr; } else if (inexpr is IFunApp) { IFunApp /*!*/ funapp = (IFunApp /*!*/)cce.NonNull(inexpr); IList newargs = null; var x = new System.Collections.Generic.List <IExpr>(); foreach (IExpr arg in funapp.Arguments) { x.Add(Substitute(subst, var, arg)); } newargs = new ArrayList(x); //newargs = new ArrayList{ IExpr/*!*/ arg in funapp.Arguments; Substitute(subst, var, arg) }; result = funapp.CloneWithArguments(newargs); } else if (inexpr is IFunction) { IFunction /*!*/ fun = (IFunction /*!*/)cce.NonNull(inexpr); if (fun.Param.Equals(var)) { result = fun; } else { result = fun.CloneWithBody(Substitute(subst, var, fun.Body)); } } else if (inexpr is IUnknown) { result = inexpr; } else { { Contract.Assert(false); throw new cce.UnreachableException(); } } return(result); }
public override Element /*!*/ EvaluatePredicate(IExpr /*!*/ e) { //Contract.Requires(e != null); Contract.Ensures(Contract.Result <Element>() != null); IFunApp nary = e as IFunApp; if (nary != null) { bool isEq = nary.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Eq); if (isEq || nary.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Subtype)) { IList /*<IExpr!>*//*!*/ args = nary.Arguments; Contract.Assert(args != null); Contract.Assert(args.Count == 2); IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(args[0]); IExpr /*!*/ arg1 = (IExpr /*!*/)cce.NonNull(args[1]); // Look for $typeof(var) == t or t == $typeof(var) or $typeof(var) <: t if (isEq && factory.IsTypeConstant(arg0)) { // swap the arguments IExpr /*!*/ tmp = arg0; arg0 = arg1; arg1 = tmp; } else if (!factory.IsTypeConstant(arg1)) { return(Top); } IFunApp typeofExpr = arg0 as IFunApp; if (typeofExpr != null && typeofExpr.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Typeof)) { Contract.Assert(typeofExpr.Arguments.Count == 1); if (typeofExpr.Arguments[0] is IVariable) { // we have a match return(new Elt(isEq ? What.Exact : What.Bounds, arg1)); } } } } return(Top); }
internal static ISet /*<IVariable!>*//*!*/ VariablesInExpression(IExpr /*!*/ e, ISet /*<IVariable!>*//*!*/ ignoreVars) { Contract.Requires(ignoreVars != null); Contract.Requires(e != null); Contract.Ensures(Contract.Result <ISet>() != null); HashSet s = new HashSet(); IFunApp f = e as IFunApp; IFunction lambda = e as IFunction; if (e is IVariable) { if (!ignoreVars.Contains(e)) { s.Add(e); } } else if (f != null) // e is IFunApp { foreach (IExpr /*!*/ arg in f.Arguments) { Contract.Assert(arg != null); s.AddAll(VariablesInExpression(arg, ignoreVars)); } } else if (lambda != null) { IMutableSet x = new HashSet(1); x.Add(lambda.Param); // Ignore the bound variable s.AddAll(VariablesInExpression(lambda.Body, cce.NonNull(Set.Union(ignoreVars, x)))); } else if (e is IUnknown) { // skip (actually, it would be appropriate to return the universal set of all variables) } else { Debug.Assert(false, "case not handled: " + e); } return(s); }
public override Element /*!*/ EvaluatePredicate(IExpr /*!*/ e) { //Contract.Requires(e != null); Contract.Ensures(Contract.Result <Element>() != null); IFunApp nary = e as IFunApp; if (nary != null) { if (nary.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Eq)) { IList /*<IExpr!>*//*!*/ args = nary.Arguments; Contract.Assert(args != null); Contract.Assert(args.Count == 2); IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(args[0]); IExpr /*!*/ arg1 = (IExpr /*!*/)cce.NonNull(args[1]); // Look for "x == const" or "const == x". try { if (arg0 is IVariable) { BigNum z; if (Fold(arg1, out z)) { return(new Elt(z)); } } else if (arg1 is IVariable) { BigNum z; if (Fold(arg0, out z)) { return(new Elt(z)); } } } catch (System.ArithmeticException) { // fall through and return Top. (Note, an alternative design may // consider returning Bottom.) } } } return(Top); }
private static IFunApp /*?*/ MatchFunctionSymbol(IExpr /*!*/ expr, IFunctionSymbol /*!*/ f) { Contract.Requires(f != null); Contract.Requires(expr != null); IFunApp app = expr as IFunApp; if (app != null) { if (app.FunctionSymbol.Equals(f)) { return(app); } else { return(null); } } else { return(null); } }
public override bool Understands(IFunctionSymbol /*!*/ f, IList /*<IExpr!>*//*!*/ args) { //Contract.Requires(args != null); //Contract.Requires(f != null); bool isEq = f.Equals(Microsoft.AbstractInterpretationFramework.Value.Eq); if (isEq || f.Equals(Microsoft.AbstractInterpretationFramework.Value.Subtype)) { Contract.Assert(args.Count == 2); IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(args[0]); IExpr /*!*/ arg1 = (IExpr /*!*/)cce.NonNull(args[1]); // Look for $typeof(var) == t or t == $typeof(var) or $typeof(var) <: t if (isEq && factory.IsTypeConstant(arg0)) { // swap the arguments IExpr /*!*/ tmp = arg0; arg0 = arg1; arg1 = tmp; } else if (!factory.IsTypeConstant(arg1)) { return(false); } IFunApp typeofExpr = arg0 as IFunApp; if (typeofExpr != null && typeofExpr.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Typeof)) { Contract.Assert(typeofExpr.Arguments.Count == 1); if (typeofExpr.Arguments[0] is IVariable) { // we have a match return(true); } } } return(false); }
/// <summary> /// Evaluate the predicate passed as input according the semantics of intervals and the given state. /// Right now just basic arithmetic operations are supported. A future extension may consider an implementation of boolean predicates /// </summary> public override Element /*!*/ EvaluatePredicateWithState(IExpr /*!*/ pred, IFunctionalMap /* Var -> Element */ state) { //Contract.Requires(pred != null); Contract.Ensures(Contract.Result <Element>() != null); if (pred is IFunApp) { IFunApp fun = (IFunApp)pred; if (fun.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Eq)) // if it is a symbol of equality { IExpr /*!*/ leftArg = (IExpr /*!*/)cce.NonNull(fun.Arguments[0]); IExpr /*!*/ rightArg = (IExpr /*!*/)cce.NonNull(fun.Arguments[1]); if (leftArg is IVariable) { return(Eval(rightArg, state)); } else if (rightArg is IVariable) { return(Eval(leftArg, state)); } } } // otherwise we simply return Top return(IntervalElement.Top); }
public override Element /*!*/ EvaluatePredicate(IExpr /*!*/ e) { //Contract.Requires(e != null); Contract.Ensures(Contract.Result <Element>() != null); IFunApp nary = e as IFunApp; if (nary != null) { bool isEq = nary.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Eq); if (isEq || nary.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Neq)) { IList /*<IExpr!>*//*!*/ args = nary.Arguments; Contract.Assert(args != null); Contract.Assert(args.Count == 2); IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(args[0]); IExpr /*!*/ arg1 = (IExpr /*!*/)cce.NonNull(args[1]); // Look for "x OP null" or "null OP x" where OP is "==" or "!=". IVariable var = null; if (arg0 is IVariable && arg1 is IFunApp && ((IFunApp)arg1).FunctionSymbol == Ref.Null) { var = (IVariable)arg0; } else if (arg1 is IVariable && arg0 is IFunApp && ((IFunApp)arg0).FunctionSymbol == Ref.Null) { var = (IVariable)arg1; } if (var != null) // found the pattern { return(isEq ? Null : NotNull); } } } return(Top); }
public virtual object VisitFunApp(IFunApp/*!*/ funapp){ Contract.Requires(funapp != null); return Default(funapp); }
/// <summary> /// Return a new expression in which each variable has been /// replaced by an expression representing what is known about /// that variable. /// </summary> private IExpr /*!*/ InlineVariables(Elt /*!*/ element, IExpr /*!*/ expr, ISet /*<IVariable!>*//*!*/ notInlineable, OnUnableToInline /*!*/ unableToInline) { Contract.Requires(unableToInline != null); Contract.Requires(notInlineable != null); Contract.Requires(expr != null); Contract.Requires(element != null); Contract.Ensures(Contract.Result <IExpr>() != null); IVariable var = expr as IVariable; if (var != null) { /*MicroLattice*/ Element value = element[var]; if (notInlineable.Contains(var) || value == null || this.microLattice.IsTop(value)) { return(unableToInline(var)); // We don't know anything about this variable. } else { // GetFoldExpr returns null when it can yield an expression that // can be substituted for the variable. IExpr valueExpr = this.microLattice.GetFoldExpr(value); return((valueExpr == null) ? var : valueExpr); } } // else IFunApp fun = expr as IFunApp; if (fun != null) { IList newargs = new ArrayList(); foreach (IExpr /*!*/ arg in fun.Arguments) { Contract.Assert(arg != null); newargs.Add(InlineVariables(element, arg, notInlineable, unableToInline)); } return(fun.CloneWithArguments(newargs)); } // else IFunction lambda = expr as IFunction; if (lambda != null) { IMutableSet x = new HashSet(1); x.Add(lambda.Param); // Don't inline the bound variable return(lambda.CloneWithBody( InlineVariables(element, lambda.Body, cce.NonNull(Set.Union(notInlineable, x)), unableToInline) )); } // else if (expr is IUnknown) { return(expr); } else { throw new System.NotImplementedException("cannot inline identifies in expression " + expr); } }
public override Element /*!*/ Constrain(Element /*!*/ element, IExpr /*!*/ expr) { //Contract.Requires(expr != null); //Contract.Requires(element != null); //Contract.Ensures(Contract.Result<Element>() != null); Elt /*!*/ result = (Elt)element; Contract.Assert(result != null); if (IsBottom(element)) { return(result); // == element } expr = InlineVariables(result, expr, cce.NonNull(Set.Empty), new OnUnableToInline(IdentityVarToExpr)); foreach (IExpr /*!*/ conjunct in FindConjuncts(expr)) { Contract.Assert(conjunct != null); IVariable left, right; if (IsSimpleEquality(conjunct, out left, out right)) { #region The conjunct is a simple equality Contract.Assert(left != null && right != null); Element leftValue = result[left], rightValue = result[right]; if (leftValue == null) { leftValue = this.microLattice.Top; } if (rightValue == null) { rightValue = this.microLattice.Top; } Element newValue = this.microLattice.Meet(leftValue, rightValue); result = AddConstraint(result, left, newValue); result = AddConstraint(result, right, newValue); #endregion } else { ISet /*<IVariable>*/ variablesInvolved = VariablesInExpression(conjunct, Set.Empty); if (variablesInvolved.Count == 1) { #region We have just one variable IVariable var = null; foreach (IVariable /*!*/ v in variablesInvolved) { Contract.Assert(v != null); var = v; } // why is there no better way to get the elements? Contract.Assert(var != null); Element /*!*/ value = this.microLattice.EvaluatePredicate(conjunct); result = AddConstraint(result, var, value); #endregion } else if (IsArithmeticExpr(conjunct) && this.microLattice.UnderstandsBasicArithmetics) { #region We evalaute an arithmetic expression IFunApp fun = (IFunApp)conjunct; if (fun.FunctionSymbol.Equals(Microsoft.AbstractInterpretationFramework.Value.Eq)) // if it is a symbol of equality { // get the variable to be assigned IExpr /*!*/ leftArg = (IExpr /*!*/)cce.NonNull(fun.Arguments[0]); IExpr /*!*/ rightArg = (IExpr /*!*/)cce.NonNull(fun.Arguments[1]); IExpr /*!*/ var = (leftArg is IVariable) ? leftArg : rightArg; Element /*!*/ value = this.microLattice.EvaluatePredicateWithState(conjunct, result.Constraints); Contract.Assert(value != null); result = AddConstraint(result, (IVariable /*!*/)cce.NonNull(var), value); } #endregion } } } return(result); }
public virtual object VisitFunApp(IFunApp /*!*/ funapp) { Contract.Requires(funapp != null); return(Default(funapp)); }
/// <summary> /// Builds a linear expression from "e", if possible; returns null if not possible. /// </summary> /// <param name="e"></param> /// <returns></returns> public static /*maybe null*/ LinearExpr AsExpr(IExpr /*!*/ e) /* throws ArithmeticException */ { Contract.Requires(e != null); if (e is IVariable) { // Note, without a type for the variable, we don't know if the identifier is intended to hold an integer value. // However, it seems that no harm can be caused by here treating the identifier as if it held an // integer value, because other parts of this method will reject the expression as a linear expression // if non-numeric operations other than equality are applied to the identifier. return(new LinearExpr((IVariable)e)); } else if (e is IFunApp) { IFunApp /*!*/ funapp = (IFunApp)e; Contract.Assert(funapp != null); IFunctionSymbol /*!*/ s = funapp.FunctionSymbol; Contract.Assert(s != null); if (s is IntSymbol) { return(new LinearExpr(((IntSymbol)s).Value)); } else if (s.Equals(Int.Negate)) { Contract.Assert(funapp.Arguments.Count == 1); LinearExpr le = AsExpr((IExpr /*!*/)cce.NonNull(funapp.Arguments[0])); if (le != null) { le.Negate(); return(le); } } else if (s.Equals(Int.Add) || s.Equals(Int.Sub) || s.Equals(Int.Mul)) { Contract.Assert(funapp.Arguments.Count == 2); IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(funapp.Arguments[0]); IExpr /*!*/ arg1 = (IExpr /*!*/)cce.NonNull(funapp.Arguments[1]); LinearExpr le0 = AsExpr(arg0); if (le0 == null) { return(null); } LinearExpr le1 = AsExpr(arg1); if (le1 == null) { return(null); } if (s.Equals(Int.Add)) { le0.Add(le1); return(le0); } else if (s.Equals(Int.Sub)) { le1.Negate(); le0.Add(le1); return(le0); } else if (s.Equals(Int.Mul)) { BigNum x; if (le0.AsConstant(out x)) { le1.Multiply(x); return(le1); } else if (le1.AsConstant(out x)) { le0.Multiply(x); return(le0); } } } } return(null); }
static /*maybe null*/ LinearCondition GetCond(IExpr e, bool positive) /* throws ArithmeticException */ { IFunApp funapp = e as IFunApp; if (funapp == null) { return(null); } IFunctionSymbol /*!*/ s = funapp.FunctionSymbol; Contract.Assert(s != null); if ((positive && s.Equals(Prop.False)) || (!positive && s.Equals(Prop.True))) { return(new LCBottom()); } else if (s.Equals(Prop.Not)) { Contract.Assert(funapp.Arguments.Count == 1); return(GetCond((IExpr /*!*/)cce.NonNull(funapp.Arguments[0]), !positive)); } else if (funapp.Arguments.Count == 2) { IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(funapp.Arguments[0]); IExpr /*!*/ arg1 = (IExpr /*!*/)cce.NonNull(funapp.Arguments[1]); LinearExpr le0 = AsExpr(arg0); if (le0 == null) { return(null); } LinearExpr le1 = AsExpr(arg1); if (le1 == null) { return(null); } LinearConstraint constraint = null; bool sense = true; if ((positive && s.Equals(Int.Less)) || (!positive && s.Equals(Int.AtLeast))) { constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.LE, BigNum.ONE); } else if ((positive && s.Equals(Int.AtMost)) || (!positive && s.Equals(Int.Greater))) { constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.LE, BigNum.ZERO); } else if ((positive && s.Equals(Int.AtLeast)) || (!positive && s.Equals(Int.Less))) { constraint = MakeConstraint(le1, le0, LinearConstraint.ConstraintRelation.LE, BigNum.ZERO); } else if ((positive && s.Equals(Int.Greater)) || (!positive && s.Equals(Int.AtMost))) { constraint = MakeConstraint(le1, le0, LinearConstraint.ConstraintRelation.LE, BigNum.ONE); } else if (s.Equals(Int.Eq)) { constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.EQ, BigNum.ZERO); sense = positive; } else if (s.Equals(Int.Neq)) { constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.EQ, BigNum.ZERO); sense = !positive; } if (constraint != null) { if (constraint.coefficients.Count != 0) { return(new LinearConditionLiteral(sense, constraint)); } else if (constraint.IsConstantSatisfiable()) { return(null); } else { return(new LCBottom()); } } } return(null); }
/// <summary> /// Evaluate the expression (that is assured to be an arithmetic expression, in the state passed as a parameter /// </summary> private IntervalElement /*!*/ Eval(IExpr /*!*/ exp, IFunctionalMap /* Var -> Element */ state) { Contract.Requires((exp != null)); Contract.Ensures(Contract.Result <IntervalElement>() != null); IntervalElement /*!*/ retVal = (IntervalElement /*!*/)cce.NonNull(Top); // Eval the expression by structural induction if (exp is IVariable && state != null) // A variable { object lookup = state[exp]; if (lookup is IntervalElement) { retVal = (IntervalElement)lookup; } else { retVal = (IntervalElement)Top; } } else if (exp is IFunApp) { IFunApp fun = (IFunApp)exp; if (fun.FunctionSymbol is IntSymbol) // An integer { IntSymbol intSymb = (IntSymbol)fun.FunctionSymbol; BigNum val = intSymb.Value; retVal = IntervalElement.Factory(val); } else if (fun.FunctionSymbol.Equals(Int.Negate)) // An unary minus { IExpr /*!*/ arg = (IExpr /*!*/)cce.NonNull(fun.Arguments[0]); IntervalElement /*!*/ argEval = Eval(arg, state); Contract.Assert(argEval != null); IntervalElement /*!*/ zero = IntervalElement.Factory(BigNum.ZERO); Contract.Assert(zero != null); retVal = zero - argEval; } else if (fun.Arguments.Count == 2) { IExpr /*!*/ left = (IExpr /*!*/)cce.NonNull(fun.Arguments[0]); IExpr /*!*/ right = (IExpr /*!*/)cce.NonNull(fun.Arguments[1]); IntervalElement /*!*/ leftVal = Eval(left, state); Contract.Assert(leftVal != null); IntervalElement /*!*/ rightVal = Eval(right, state); Contract.Assert(rightVal != null); if (fun.FunctionSymbol.Equals(Int.Add)) { retVal = leftVal + rightVal; } else if (fun.FunctionSymbol.Equals(Int.Sub)) { retVal = leftVal - rightVal; } else if (fun.FunctionSymbol.Equals(Int.Mul)) { retVal = leftVal * rightVal; } else if (fun.FunctionSymbol.Equals(Int.Div)) { retVal = leftVal / rightVal; } else if (fun.FunctionSymbol.Equals(Int.Mod)) { retVal = leftVal % rightVal; } } } return(retVal); }
/// <summary> /// Returns true if "expr" represents a constant integer expressions, in which case /// "z" returns as that integer. Otherwise, returns false, in which case "z" should /// not be used by the caller. /// /// This method throws an System.ArithmeticException in the event that folding the /// constant expression results in an arithmetic overflow or division by zero. /// </summary> private bool Fold(IExpr /*!*/ expr, out BigNum z) { Contract.Requires(expr != null); IFunApp e = expr as IFunApp; if (e == null) { z = BigNum.ZERO; return(false); } if (e.FunctionSymbol is IntSymbol) { z = ((IntSymbol)e.FunctionSymbol).Value; return(true); } else if (e.FunctionSymbol.Equals(Int.Negate)) { IList /*<IExpr!>*//*!*/ args = e.Arguments; Contract.Assert(args != null); Contract.Assert(args.Count == 1); IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(args[0]); if (Fold(arg0, out z)) { z = z.Neg; return(true); } } else if (e.Arguments.Count == 2) { IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(e.Arguments[0]); IExpr /*!*/ arg1 = (IExpr /*!*/)cce.NonNull(e.Arguments[1]); BigNum z0, z1; if (Fold(arg0, out z0) && Fold(arg1, out z1)) { if (e.FunctionSymbol.Equals(Int.Add)) { z = z0 + z1; } else if (e.FunctionSymbol.Equals(Int.Sub)) { z = z0 - z1; } else if (e.FunctionSymbol.Equals(Int.Mul)) { z = z0 * z1; } else if (e.FunctionSymbol.Equals(Int.Div)) { z = z0 / z1; } else if (e.FunctionSymbol.Equals(Int.Mod)) { z = z0 % z1; } else { z = BigNum.ZERO; return(false); } return(true); } } z = BigNum.ZERO; return(false); }