protected ArrayState UpdateArrayAbstractValue(APC pc, BoxedVariable <Variable> arr, NormalizedExpression <BoxedVariable <Variable> > index, NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression> ael, ArrayState prevState) { Contract.Requires(prevState != null); Contract.Ensures(Contract.Result <ArrayState>() != null); ArraySegmentation <NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>, BoxedVariable <Variable>, BoxedExpression> prev, updated; if (prevState.Array.TryGetValue(arr, out prev)) { if (index != null) { IAbstractDomain prevAel; if (prev.TryGetAbstractValue(index, prevState.Numerical, out prevAel) && prevAel is NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression> ) { ael = ael.Meet(prevAel as NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>); } if (prev.TrySetAbstractValue(index, ael, prevState.Numerical, out updated)) { prevState.Array[arr] = updated; } } } return(prevState); }
public static INumericalAbstractDomain <Variable, Expression> TestTrue <Variable, Expression>( this INumericalAbstractDomain <Variable, Expression> aState, Variable v, NonRelationalValueAbstraction <Variable, Expression> nonRelationalValue, IExpressionEncoder <Variable, Expression> encoder) { Contract.Requires(v != null); Contract.Requires(aState != null); Contract.Requires(nonRelationalValue != null); Contract.Requires(encoder != null); Contract.Ensures(Contract.Result <INumericalAbstractDomain <Variable, Expression> >() != null); if (nonRelationalValue.IsBottom) { Contract.Assume(aState.Bottom as INumericalAbstractDomain <Variable, Expression> != null); // F: Adding the assumption as we do not track types return(aState.Bottom as INumericalAbstractDomain <Variable, Expression>); } if (nonRelationalValue.IsTop) { return(aState); } var result = aState; // Assume the interval if (nonRelationalValue.Interval.IsNormal()) { result.AssumeInDisInterval(v, nonRelationalValue.Interval); } var vExp = encoder.VariableFor(v); // Assume the equalities if (nonRelationalValue.Equalities.IsNormal()) { result = result.TestTrueEqual(vExp, nonRelationalValue.Equalities, encoder); } // Assume the strict upper bounds if (nonRelationalValue.StrictUpperBounds.IsNormal()) { result = result.TestTrueLessThan(vExp, nonRelationalValue.StrictUpperBounds, encoder); } // Assume the weak upper bounds if (nonRelationalValue.WeakUpperBounds.IsNormal()) { result = result.TestTrueLessEqualThan(vExp, nonRelationalValue.WeakUpperBounds, encoder); } return(result); }
public override ArrayState Ldelem(APC pc, Type type, Variable dest, Variable array, Variable index, ArrayState data) { var mySubState = Select(data); var bArray = new BoxedVariable <Variable>(array); ArraySegmentation <NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>, BoxedVariable <Variable>, BoxedExpression> existentialSegmentation; var noConstraints = SetOfConstraints <BoxedVariable <Variable> > .Unknown; var newElement = new NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>(DisInterval.UnknownInterval, SymbolicExpressionTracker <BoxedVariable <Variable>, BoxedExpression> .Unknown, new SetOfConstraints <BoxedVariable <Variable> >(new BoxedVariable <Variable>(dest)), noConstraints, noConstraints, noConstraints, noConstraints); if (mySubState.TryGetValue(bArray, out existentialSegmentation)) { if (existentialSegmentation.IsNormal()) { var newSegmentation = new ArraySegmentation <NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>, BoxedVariable <Variable>, BoxedExpression> (new NonNullList <SegmentLimit <BoxedVariable <Variable> > >() { existentialSegmentation.Limits.AsIndexable()[0], existentialSegmentation.LastLimit }, new NonNullList <NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression> >() { newElement }, existentialSegmentation.Elements.AsIndexable()[0].Bottom, this.ExpressionManager); var meet = existentialSegmentation.Meet(newSegmentation); mySubState.Update(bArray, meet); return(data.UpdatePluginAt(this.Id, mySubState)); } } else // materialize { existentialSegmentation = MaterializeArray(this.Context.MethodContext.CFG.Post(pc), mySubState, data.Numerical.CheckIfNonZero, array, newElement, newElement.Bottom); // Segmentation may fail if (existentialSegmentation != null) { mySubState.Update(bArray, existentialSegmentation); return(data.UpdatePluginAt(this.Id, mySubState)); } } return(data); }
protected ArrayState AssumeWithArrayRefinement(APC pc, bool positive, BoxedExpression comparison, ArrayState prevState) { Contract.Requires(comparison != null); Contract.Requires(prevState != null); Contract.Ensures(Contract.Result <ArrayState>() != null); // Default NonRelational values var interval = DisInterval.UnknownInterval; var symbExpression = SymbolicExpressionTracker <BoxedVariable <Variable>, BoxedExpression> .Unknown; var equalities = SetOfConstraints <BoxedVariable <Variable> > .Unknown; var disequalities = SetOfConstraints <BoxedVariable <Variable> > .Unknown; var weakUpperBounds = SetOfConstraints <BoxedVariable <Variable> > .Unknown; var strictUpperBounds = SetOfConstraints <BoxedVariable <Variable> > .Unknown; var existential = SetOfConstraints <BoxedVariable <Variable> > .Unknown; Pair <BoxedVariable <Variable>, BoxedVariable <Variable> > refined; Variable left, right; int k; #region left != right ? if (positive && comparison.IsCheckExp1NotEqExp2(out left, out right)) { // refined.One[refined.Two] != right var b = prevState.CanRefineToArrayLoad(new BoxedVariable <Variable>(left), out refined); if (!b) { // left != refined.One[refined.Two] b = prevState.CanRefineToArrayLoad(new BoxedVariable <Variable>(right), out refined); // Swap roles var tmp = left; left = right; right = tmp; } if (b) { // invariant: "left" is the one to refine. // TODO: right now we are ignoring the case when both are arrays interval = prevState.IntervalIfNotNull(left); var ael = new NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression> (interval, symbExpression, equalities, new SetOfConstraints <BoxedVariable <Variable> >(new BoxedVariable <Variable>(right)), weakUpperBounds, strictUpperBounds, existential); var index = ToBoxedExpression(pc, refined.Two).ToNormalizedExpression <Variable>(); return(UpdateArrayAbstractValue(pc, refined.One, index, ael, prevState)); } } #endregion #region left != k ? BinaryOperator bop; if (comparison.IsCheckExpOpConst(out bop, out left, out k) && prevState.CanRefineToArrayLoad(new BoxedVariable <Variable>(left), out refined)) { switch (bop) { case BinaryOperator.Ceq: { interval = positive ? DisInterval.For(k) : DisInterval.NotInThisInterval(DisInterval.For(k)); break; } case BinaryOperator.Cne_Un: { interval = positive ? DisInterval.NotInThisInterval(DisInterval.For(k)) : DisInterval.For(k); break; } default: { return(prevState); } } var ael = new NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression> (interval, symbExpression, equalities, disequalities, weakUpperBounds, strictUpperBounds, existential); var index = ToBoxedExpression(pc, refined.Two).Stripped().ToNormalizedExpression <Variable>(); return(UpdateArrayAbstractValue(pc, refined.One, index, ael, prevState)); } #endregion #region left == 0 if (comparison.TryGetFrameworkVariable(out left) && prevState.CanRefineToArrayLoad(new BoxedVariable <Variable>(left), out refined)) { interval = !positive ? DisInterval.Zero : DisInterval.NotZero; var ael = new NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression> (interval, symbExpression, equalities, disequalities, weakUpperBounds, strictUpperBounds, existential); var index = ToBoxedExpression(pc, refined.Two).Stripped().ToNormalizedExpression <Variable>(); return(UpdateArrayAbstractValue(pc, refined.One, index, ael, prevState)); } #endregion return(prevState); }
protected bool TryInferNonRelationalProperty(BoxedExpression index, BoxedExpression body, INumericalAbstractDomain <BoxedVariable <Variable>, BoxedExpression> dom, out BoxedExpression array, out NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression> elementsProperty) { Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out array) != null); Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out elementsProperty) != null); BoxedExpression.ArrayIndexExpression <Type> arrayExp; if (body.TryFindArrayExp(index, out arrayExp)) { array = arrayExp.Array; Contract.Assert(array != null); var slackVar = new BoxedVariable <Variable>(true); var slackExp = BoxedExpression.Var(slackVar); var renamedBody = body.Substitute(arrayExp, slackExp); var nonTrivial = false; var symbolicConditions = SymbolicExpressionTracker <BoxedVariable <Variable>, BoxedExpression> .Unknown; var equalities = SetOfConstraints <BoxedVariable <Variable> > .Unknown; var disequalities = SetOfConstraints <BoxedVariable <Variable> > .Unknown; var weakUpperBounds = SetOfConstraints <BoxedVariable <Variable> > .Unknown; var strictUpperBounds = SetOfConstraints <BoxedVariable <Variable> > .Unknown; var existential = SetOfConstraints <BoxedVariable <Variable> > .Unknown; #region Look for an interval var augmentedDom = dom.TestTrue(renamedBody) as INumericalAbstractDomain <BoxedVariable <Variable>, BoxedExpression>; var intv = augmentedDom.BoundsFor(slackVar); if (intv.IsNormal) { nonTrivial = true; } // TODO: upgrade the non-relational values to disintervals, to avoid those checks if (intv.IsTop && augmentedDom.CheckIfNonZero(slackExp).IsTrue()) { intv = DisInterval.For(1); nonTrivial = true; } #endregion #region Look for equalities BoxedExpression left, right; if (renamedBody.IsCheckExp1EqExp2(out left, out right)) { Variable eq; // a[i] == v if ( (left.Equals(slackExp) && right.TryGetFrameworkVariable(out eq)) || (right.Equals(slackExp) && left.TryGetFrameworkVariable(out eq)) ) { equalities = new SetOfConstraints <BoxedVariable <Variable> >(ToBoxedVariable(eq)); nonTrivial = true; } } #endregion if (nonTrivial) { elementsProperty = new NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>( intv, symbolicConditions, equalities, disequalities, weakUpperBounds, strictUpperBounds, existential); return(true); } else { elementsProperty = default(NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>); return(false); } } array = default(BoxedExpression); elementsProperty = default(NonRelationalValueAbstraction <BoxedVariable <Variable>, BoxedExpression>); return(false); }