public SymbolicExpressionTracker(Variable slackVar, SetOfConstraints <Expression> symbolicConditions) { Contract.Requires(symbolicConditions != null); this.slackVar = slackVar; this.symbolicConditions = symbolicConditions; }
public SimpleDisequalities <Variable, Expression> TestTrueLessEqualThan(Expression left, Expression right) { SimpleDisequalities <Variable, Expression> result = this; evalConstant.Visit(right); if (evalConstant.HasValue) { Rational v = evalConstant.Result; Variable leftVar = decoder.UnderlyingVariable(left); // left <= k => left != k + 1 (also k+2, k+3, etc. but we do not care ...) SetOfConstraints <Rational> newConstraintsForLeft = this[leftVar].Meet(new SetOfConstraints <Rational>(v + 1)); result[leftVar] = newConstraintsForLeft; } evalConstant.Visit(left); if (evalConstant.HasValue) { Rational v = evalConstant.Result; Variable rightVar = decoder.UnderlyingVariable(right); // k <= right => right != k - 1 (also k - 2, k - 3, etc. but we do not care ...) SetOfConstraints <Rational> newConstraintsForRight = this[rightVar].Meet(new SetOfConstraints <Rational>(v - 1)); result[rightVar] = newConstraintsForRight; } return(result); }
public static INumericalAbstractDomain <Variable, Expression> TestTrueEqual <Variable, Expression>( this INumericalAbstractDomain <Variable, Expression> aState, Expression exp, SetOfConstraints <Variable> equalities, IExpressionEncoder <Variable, Expression> encoder) { Contract.Requires(aState != null); Contract.Requires(exp != null); Contract.Requires(equalities != null); Contract.Requires(encoder != null); Contract.Ensures(Contract.Result <INumericalAbstractDomain <Variable, Expression> >() != null); if (equalities.IsNormal()) { var newSet = new Set <Expression>(); foreach (var v in equalities.Values) { newSet.Add(encoder.VariableFor(v)); } return(aState.TestTrueEqual(exp, newSet)); } else { return(aState); } }
static private SetOfConstraints <Variable>[] ParallelOperation( SetOfConstraints <Variable>[] left, SetOfConstraints <Variable>[] right, Func <SetOfConstraints <Variable>, SetOfConstraints <Variable>, SetOfConstraints <Variable> > op) { Contract.Requires(left != null); Contract.Requires(right != null); Contract.Requires(left.Length == right.Length); Contract.Requires(op != null); Contract.Ensures(Contract.Result <SetOfConstraints <Variable>[]>() != null); Contract.Ensures(Contract.Result <SetOfConstraints <Variable>[]>().Length == left.Length); Contract.Ensures( Contract.ForAll(Contract.Result <SetOfConstraints <Variable>[]>(), el => el != null)); var result = new SetOfConstraints <Variable> [left.Length]; for (var i = 0; i < left.Length; i++) { var r = op(left[i], right[i]); Contract.Assume(r != null); result[i] = r; } return(result); }
public NonRelationalValueAbstraction( DisInterval interval, SymbolicExpressionTracker <Variable, Expression> symbolicConditions, SetOfConstraints <Variable> equalities, SetOfConstraints <Variable> disequalities, SetOfConstraints <Variable> weakUpperBounds, SetOfConstraints <Variable> strictUpperBounds, SetOfConstraints <Variable> existential) { Contract.Requires(interval != null); Contract.Requires(symbolicConditions != null); Contract.Requires(disequalities != null); Contract.Requires(equalities != null); Contract.Requires(weakUpperBounds != null); Contract.Requires(strictUpperBounds != null); Contract.Requires(existential != null); disInterval = interval; this.symbolicConditions = symbolicConditions; weaklyRelationalDomains = new SetOfConstraints <Variable>[WeaklyRelationalDomainsCount] { equalities, disequalities, weakUpperBounds, strictUpperBounds, existential }; }
public override DisjunctiveRefinement Ldelem(APC pc, Type type, Variable dest, Variable array, Variable index, DisjunctiveRefinement data) { this.InferExceptionHandlers(pc); data[new BoxedVariable <Variable>(dest)] = new SetOfConstraints <BoxedExpression>(new BoxedExpression.ArrayIndexExpression <Type>(ToBoxedExpression(pc, array), ToBoxedExpression(pc, index), type)); return(data); }
public NonRelationalValueAbstraction <Variable, Expression> DuplicateMe() { Contract.Ensures(Contract.Result <NonRelationalValueAbstraction <Variable, Expression> >() != null); var newArr = new SetOfConstraints <Variable> [weaklyRelationalDomains.Length]; Array.Copy(weaklyRelationalDomains, newArr, weaklyRelationalDomains.Length); return(new NonRelationalValueAbstraction <Variable, Expression>(disInterval, symbolicConditions, newArr)); }
public static bool IsSingleton <El>(this SetOfConstraints <El> constraints, out El value) { if (constraints == null || !constraints.IsNormal() || constraints.Count < 1) { value = default(El); return(false); } value = constraints.Values.First(); return(true); }
public EnumDefined <Variable, Type, Expression> Rename(Dictionary <Variable, FList <Variable> > renaming) { if (!this.IsNormal()) { return(this); } var newConditions = new Dictionary <Variable, SetOfConstraints <Pair <Type, Variable> > >(); foreach (var pair in conditions.Elements) { FList <Variable> newNames; if (renaming.TryGetValue(pair.Key, out newNames)) { var newPairs = new Set <Pair <Type, Variable> >(); Contract.Assume(pair.Value != null); foreach (var equalities in pair.Value.Values) { FList <Variable> newRight; if (renaming.TryGetValue(equalities.Two, out newRight)) { foreach (var y in newRight.GetEnumerable()) { newPairs.Add(new Pair <Type, Variable>(equalities.One, y)); } } } foreach (var newName in newNames.GetEnumerable()) { newConditions[newName] = new SetOfConstraints <Pair <Type, Variable> >(newPairs); } } } var newDefinitions = new Set <Pair <Type, Variable> >(); foreach (var equalities in defined.Values) { FList <Variable> newRight; if (renaming.TryGetValue(equalities.Two, out newRight)) { foreach (var y in newRight.GetEnumerable()) { newDefinitions.Add(new Pair <Type, Variable>(equalities.One, y)); } } } return(new EnumDefined <Variable, Type, Expression>(newConditions, newDefinitions)); }
public override SimpleDisequalities <Variable, Expression> VisitEqual(Expression left, Expression right, Expression original, SimpleDisequalities <Variable, Expression> data) { evalConstant.Visit(right); Variable leftVar = Decoder.UnderlyingVariable(left); if (data.ContainsKey(leftVar) && data[leftVar].IsNormal() && evalConstant.HasValue) { foreach (Rational r in data[leftVar].Values) { // we know left != r, so we want that intvForRight != r if (r == evalConstant.Result) { return(data.Bottom); } } } evalConstant.Visit(left); Variable rightVar = Decoder.UnderlyingVariable(right); if (data.ContainsKey(rightVar) && data[rightVar].IsNormal() && evalConstant.HasValue) { foreach (Rational r in data[rightVar].Values) { // we know right != r, so we want that intvForLeft != r if (r == evalConstant.Result) { return(data.Bottom); } } } // At this point we know that we do not have simple contraddictions. // Now we can say that left and right have the same inequalities SetOfConstraints <Rational> unionOfConstraints = data[leftVar].Meet(data[rightVar]); if (!unionOfConstraints.IsTop) { data[leftVar] = unionOfConstraints; data[rightVar] = unionOfConstraints; } return(data); }
public ScalarFromArrayTracking( SetOfConstraints <BoxedVariable <Variable> > left, SetOfConstraints <BoxedVariable <Variable> > right, FlatAbstractDomain <bool> isUnmodifiedFromEntry, SymbolicExpressionTracker <BoxedVariable <Variable>, BoxedExpression> conditions) { Contract.Requires(left != null); Contract.Requires(right != null); Contract.Requires(isUnmodifiedFromEntry != null); Contract.Requires(conditions != null); this.left = left; this.right = right; this.isUnmodifiedFromEntry = isUnmodifiedFromEntry; this.conditions = conditions; }
public DisjunctiveRefinement AssignInParallelFunctional( Dictionary <BoxedVariable <Variable>, FList <BoxedVariable <Variable> > > sourcesToTargets, Converter <BoxedVariable <Variable>, BoxedExpression> convert) { // var varsInRenaming = ComputeVarsInRenaming(sourcesToTargets, convert); Dictionary <Variable, HashSet <Variable> > varsInRenaming = null; // We do not use them now, and as the cost of the call is too high, we just gave up if (this.IsNormal()) { var result = this.Factory(); foreach (var pair in this.Elements) { if (pair.Value.IsNormal()) { var renamed = new List <BoxedExpression>(); FList <BoxedVariable <Variable> > newNames; if (sourcesToTargets.TryGetValue(pair.Key, out newNames)) { foreach (var exp in pair.Value.Values) { renamed.AddIfNotNull(exp.Rename(sourcesToTargets)); } if (renamed.Count > 0) { var newConstraints = new SetOfConstraints <BoxedExpression>(renamed); foreach (var newName in newNames.GetEnumerable()) { result[newName] = newConstraints; } } } else { // do nothing -> the variable goes away } } } return(new DisjunctiveRefinement(result, varsInRenaming)); } else { return(new DisjunctiveRefinement(this, varsInRenaming)); } }
private SimpleDisequalities <Variable, Expression> Update(Expression exp, Rational k, SimpleDisequalities <Variable, Expression> data) { var newConstraints = new SetOfConstraints <Rational>(k); SetOfConstraints <Rational> prev; Variable var = Decoder.UnderlyingVariable(exp); if (data.TryGetValue(var, out prev)) { newConstraints = newConstraints.Meet(prev); } data[var] = newConstraints; return(data); }
public override DisjunctiveRefinement Call <TypeList, ArgList>(APC pc, Method method, bool tail, bool virt, TypeList extraVarargs, Variable dest, ArgList args, DisjunctiveRefinement data) { this.InferExceptionHandlers(pc); var asForAll = this.MethodDriver.AsForAllIndexed(pc.Post(), dest); if (asForAll != null) { data[new BoxedVariable <Variable>(dest)] = new SetOfConstraints <BoxedExpression>(asForAll); } else { this.MethodCalls.Add(new MethodCallInfo <Method, Variable>(pc, method, args.Enumerate().ToList())); } return(data); }
/// <summary> /// Adds the constraints x != value.LowerBound-1 and x != value.UpperBound+1 /// </summary> public void AssumeInInterval(Variable x, Interval value) { if (value.IsNormal) { var strictBounds = new Set <Rational>(2); if (!value.LowerBound.IsInfinity) { try { strictBounds.Add(value.LowerBound - 1); } catch (ArithmeticExceptionRational) { // It may be the case that value.UpperBound is too large, so we catch it // and do nothing (i.e. we abstract) } } if (!value.UpperBound.IsInfinity) { try { strictBounds.Add(value.UpperBound + 1); } catch (ArithmeticExceptionRational) { // It may be the case that value.UpperBound is too large, so we catch it // and do nothing (i.e. we abstract) } } // Check if zero is not included. In the case, we want to add the constraint x != 0 if (value.DoesNotInclude(0)) { strictBounds.Add(Rational.For(0)); } // It may be the case that the interval is e.g. [+oo, +oo], so we cannot blindly add the matrixes if (strictBounds.Count > 0) { this[x] = new SetOfConstraints <Rational>(strictBounds); } } }
public override DisjunctiveRefinement Return(APC pc, Variable source, DisjunctiveRefinement data) { this.InferExceptionHandlers(pc); var md = this.MethodDriver; var mdd = md.MetaDataDecoder; BoxedExpression refinedExpWithConnectives; if (!mdd.System_Void.Equals(mdd.ReturnType(md.CurrentMethod)) && TryToBoxedExpressionWithBooleanConnectives(pc, "ret", source, true, TopNumericalDomain <BoxedVariable <Variable>, BoxedExpression> .Singleton, out refinedExpWithConnectives)) { Log("Succeeded. Got {0}", refinedExpWithConnectives.ToString); data[new BoxedVariable <Variable>(source)] = new SetOfConstraints <BoxedExpression>(refinedExpWithConnectives); } return(data); }
public NonRelationalValueAbstraction <Variable, Expression> Update(ADomains what, SetOfConstraints <Variable> value) { #region Contracts Contract.Requires(value != null); Contract.Ensures(Contract.Result <NonRelationalValueAbstraction <Variable, Expression> >() != null); Contract.Assert(Enum.IsDefined(typeof(ADomains), what)); #endregion var copy = new SetOfConstraints <Variable> [weaklyRelationalDomains.Length]; Array.Copy(weaklyRelationalDomains, copy, weaklyRelationalDomains.Length); copy[(int)what] = value; return(new NonRelationalValueAbstraction <Variable, Expression>(disInterval, symbolicConditions, copy)); }
public EnumDefined <Variable, Type, Expression> AssumeTypeIff(Variable condition, Type type, Variable variable) { Contract.Ensures(Contract.Result <EnumDefined <Variable, Type, Expression> >() != null); SetOfConstraints <Pair <Type, Variable> > constraints; if (conditions.TryGetValue(condition, out constraints)) { constraints = constraints.Add(new Pair <Type, Variable>(type, variable)); } else { constraints = new SetOfConstraints <Pair <Type, Variable> >(new Pair <Type, Variable>(type, variable)); } var newConditions = conditions.Add(condition, constraints); return(new EnumDefined <Variable, Type, Expression>(newConditions, defined)); }
public override DisjunctiveRefinement Assume(APC pc, string tag, Variable source, object provenance, DisjunctiveRefinement data) { Contract.Assume(data != null); this.InferExceptionHandlers(pc); var refinedExp = new LazyEval <BoxedExpression>( () => BoxedExpression.Convert(this.Context.ExpressionContext.Refine(pc, source), this.MethodDriver.ExpressionDecoder, MAXDEPTH)); if (tag != "false") { var toRefine = source; // in clousot1 we refine "assume refinedExp". // in clousot2 we refinedExp may be exp != 0 and in this case we refine "assume exp" if (!this.MethodDriver.SyntacticComplexity.TooManyJoinsForBackwardsChecking && refinedExp.Value != null && CanRefineAVariableTruthValue(refinedExp.Value, ref toRefine)) { Log("Trying to refine the variable {0} to one containing logical connectives", refinedExp.Value.UnderlyingVariable.ToString); BoxedExpression refinedExpWithConnectives; if (TryToBoxedExpressionWithBooleanConnectives(pc, tag, toRefine, false, TopNumericalDomain <BoxedVariable <Variable>, BoxedExpression> .Singleton, out refinedExpWithConnectives)) { Log("Succeeded. Got {0}", refinedExpWithConnectives.ToString); data[new BoxedVariable <Variable>(source)] = new SetOfConstraints <BoxedExpression>(refinedExpWithConnectives); } } } APC pcForExpression; if (!this.FirstViewAt.TryGetValue(source, out pcForExpression)) { pcForExpression = pc; } this.Tests.Add(new SyntacticTest(SyntacticTest.Polarity.Assume, pcForExpression, tag, refinedExp)); // We do not call the base Assume as it performs too many things not needed here return(data); }
public override SimpleDisequalities <Variable, Expression> VisitNotEqual(Expression left, Expression right, Expression original, SimpleDisequalities <Variable, Expression> data) { SimpleDisequalities <Variable, Expression> result = data; evalConstant.Visit(Decoder.Stripped(right)); if (evalConstant.HasValue) { // left != k data = Update(left, evalConstant.Result, data); data = Update(Decoder.Stripped(left), evalConstant.Result, data); } evalConstant.Visit(Decoder.Stripped(left)); if (evalConstant.HasValue) { // right != k var newConstraintsForRight = new SetOfConstraints <Rational>(evalConstant.Result); // check if k != 0. If so we add the constraint right != 0 if (!evalConstant.Result.IsZero) { newConstraintsForRight = newConstraintsForRight.Meet(new SetOfConstraints <Rational>(Rational.For(0))); } Variable rightVar = Decoder.UnderlyingVariable(right); SetOfConstraints <Rational> prev; if (result.TryGetValue(rightVar, out prev)) { newConstraintsForRight = newConstraintsForRight.Meet(prev); } result[rightVar] = newConstraintsForRight; } return(result); }
public void AssignInParallel(Dictionary <Variable, FList <Variable> > sourcesToTargets, Converter <Variable, Expression> convert) { var result = new SimpleDisequalities <Variable, Expression>(decoder, encoder); foreach (Variable e in Keys) { if (decoder.IsSlackVariable(e)) { result[e] = this[e]; } } State = AbstractState.Normal; if (sourcesToTargets.Count == 0) { // do nothing... } else { // Update the values foreach (Variable exp in sourcesToTargets.Keys) { SetOfConstraints <Rational> value = this[exp]; foreach (Variable target in sourcesToTargets[exp].GetEnumerable()) { if (!value.IsTop) { result[target] = value; } } } } ClearElements(); foreach (Variable e in result.Keys) { this[e] = result[e]; } }
public override string ToString() { if (IsBottom) { return("_|_"); } if (IsTop) { return("Top (disequalities)"); } var result = new StringBuilder(); foreach (Variable x in Keys) { SetOfConstraints <Rational> value = this[x]; string toAppend = x + " "; if (value.IsBottom) { toAppend += ": _|_,"; } else if (value.IsTop) { toAppend += ": {},"; } else { toAppend += "!= "; foreach (Rational r in value.Values) { toAppend += r + ", "; } } result.AppendLine(toAppend); } return(result.ToString()); }
protected override T To <T>(Variable d, SetOfConstraints <Rational> c, IFactory <T> factory) { if (c.IsBottom) { return(factory.Constant(false)); } if (c.IsTop) { return(factory.Constant(true)); } T result = factory.IdentityForAnd; T x = factory.Variable(d); foreach (Rational r in c.Values) { result = factory.And(result, factory.NotEqualTo(x, factory.Constant(r))); } return(result); }
public override SimpleDisequalities <Variable, Expression> Visit(Expression exp, SimpleDisequalities <Variable, Expression> data) { SimpleDisequalities <Variable, Expression> result = base.Visit(exp, data); // We also know that exp != 0 var expNotZero = new SetOfConstraints <Rational>(Rational.For(0)); SetOfConstraints <Rational> prev; Variable expVar = Decoder.UnderlyingVariable(exp); if (result.TryGetValue(expVar, out prev)) { result[expVar] = prev.Meet(expNotZero); } else { result[expVar] = expNotZero; } return(result); }
private EnumDefined( SimpleImmutableFunctional <Variable, SetOfConstraints <Pair <Type, Variable> > > conditions, SetOfConstraints <Pair <Type, Variable> > defined) { Contract.Requires(conditions != null); Contract.Requires(defined != null); this.conditions = conditions; this.defined = defined; if (conditions.IsBottom || defined.IsBottom) { state = State.Bottom; } else if (conditions.IsTop && defined.IsTop) { state = State.Top; } else { state = State.Normal; } }
public INumericalAbstractDomain <Variable, Expression> RemoveRedundanciesWith( INumericalAbstractDomain <Variable, Expression> oracle) { var result = new SimpleDisequalities <Variable, Expression>(decoder, encoder); if (encoder != null) { foreach (var x_pair in Elements) { SetOfConstraints <Rational> k = x_pair.Value; if (k.IsBottom || k.IsTop) { result[x_pair.Key] = k; } else { Expression xExp = encoder.VariableFor(x_pair.Key); foreach (Rational exp in k.Values) { Expression notEq = encoder.CompoundExpressionFor(ExpressionType.Bool, ExpressionOperator.NotEqual, xExp, exp.ToExpression(encoder)); FlatAbstractDomain <bool> check = oracle.CheckIfHolds(notEq); if (check.IsBottom || check.IsTop || !check.BoxedElement) { // If it is not implied by the oracle, we give up result = result.TestTrue(notEq); } } } } } return(result); }
public NonRelationalValueAbstraction <Variable, Expression> Rename(Dictionary <Variable, FList <Variable> > renaming) { // Rename the symbolic conditions var renamedExpressions = symbolicConditions.Rename(renaming); // Rename the set of constraints var renamedConstraints = new SetOfConstraints <Variable> [weaklyRelationalDomains.Length]; for (var i = 0; i < weaklyRelationalDomains.Length; i++) { var dom = weaklyRelationalDomains[i]; if (dom.IsNormal()) { var renamedStrict = new Set <Variable>(); foreach (var prev in dom.Values) { FList <Variable> targets; if (renaming.TryGetValue(prev, out targets)) { foreach (var next in targets.GetEnumerable()) { renamedStrict.Add(next); } } } renamedConstraints[i] = new SetOfConstraints <Variable>(renamedStrict, false); } else { renamedConstraints[i] = dom; } } return(new NonRelationalValueAbstraction <Variable, Expression>(this.Interval, renamedExpressions, renamedConstraints)); }
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); }
// To be implemented protected override string ToLogicalFormula(Variable d, SetOfConstraints <Rational> c) { return("1"); }