private SymbolicExpressionTracker <Variable, Expression> RenameInternal(Dictionary <Variable, FList <Variable> > renaming, Variable slackVar) { Contract.Requires(renaming != null); Contract.Ensures(Contract.Result <SymbolicExpressionTracker <Variable, Expression> >() != null); Contract.Ensures(renaming.Count == Contract.OldValue(renaming.Count)); if (symbolicConditions.IsNormal()) { renaming[slackVar] = FList <Variable> .Cons(slackVar, FList <Variable> .Empty); Set <Expression> result = new Set <Expression>(); foreach (var exp in symbolicConditions.Values) { result.AddIfNotNull(expressionRenamer(exp, renaming)); } var renamedExpressions = result.Count != 0 ? new SetOfConstraints <Expression>(result, false) : SetOfConstraints <Expression> .Unknown; renaming.Remove(slackVar); // We should remove the slack variable! return(new SymbolicExpressionTracker <Variable, Expression>(this.slackVar, symbolicConditions)); } else { return(this); } }
private SymbolicExpressionTracker <Variable, Expression> UnifySlackVariableWith(SymbolicExpressionTracker <Variable, Expression> other) { Contract.Requires(other != null); Contract.Ensures(Contract.Result <SymbolicExpressionTracker <Variable, Expression> >() != null); if (!other.IsNormal() || object.Equals(other.slackVar, slackVar)) { return(other); } var result = new Set <Expression>(); foreach (var exp in other.symbolicConditions.Values) { result.AddIfNotNull(variableReplacer(exp, other.slackVar, slackVar)); } return(result.Count != 0 ? new SymbolicExpressionTracker <Variable, Expression>(slackVar, new SetOfConstraints <Expression>(result, false)) : this.Top); }
protected bool TryCreateArraySegment(BoxedExpression low, BoxedExpression upp, Variable arrayLen, AbstractDomain intv, INumericalAbstractDomain <BoxedVariable <Variable>, BoxedExpression> numDom, out ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression> arraySegmentation) { #region Contracts Contract.Requires(low != null); Contract.Requires(upp != null); Contract.Requires(intv != null); Contract.Requires(arrayLen != null); Contract.Requires(numDom != null); Contract.Ensures(!Contract.Result <bool>() || Contract.ValueAtReturn(out arraySegmentation) != null); #endregion var lowerBounds = new Set <NormalizedExpression <BoxedVariable <Variable> > >(); lowerBounds.AddIfNotNull(low.ToNormalizedExpression <Variable>()); var upperBounds = new Set <NormalizedExpression <BoxedVariable <Variable> > >(); upperBounds.AddIfNotNull(upp.ToNormalizedExpression <Variable>()); upperBounds.AddIfNotNull(upp.ToNormalizedExpression <Variable>(true)); upperBounds.AddIfNotNull(upp.Simplify(this.DecoderForMetaData).ToNormalizedExpression <Variable>()); upperBounds.AddIfNotNull(this.Decoder.Stripped(upp).ToNormalizedExpression <Variable>()); if (lowerBounds.Count == 0 || upperBounds.Count == 0) { arraySegmentation = null; return(false); } var segments = new NonNullList <SegmentLimit <BoxedVariable <Variable> > >(); var elements = new NonNullList <AbstractDomain>(); #region Build the prefix // Check if low is zero int lowValue; if (low.IsConstantInt(out lowValue)) { if (lowValue < 0) { arraySegmentation = default(ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression>); return(false); } // { 0 } Top { lowValue } if (lowValue > 0) { segments.Add(new SegmentLimit <BoxedVariable <Variable> >(NormalizedExpression <BoxedVariable <Variable> > .For(0), false)); elements.Add((AbstractDomain)intv.Top); } // .. { lowValue } intv segments.Add(new SegmentLimit <BoxedVariable <Variable> >(lowerBounds, false)); elements.Add(intv); } else if (numDom.CheckIfGreaterEqualThanZero(low).IsTrue()) { // { 0 } Top { low }? segments.Add(new SegmentLimit <BoxedVariable <Variable> >(NormalizedExpression <BoxedVariable <Variable> > .For(0), false)); elements.Add((AbstractDomain)intv.Top); // intv { upp }? segments.Add(new SegmentLimit <BoxedVariable <Variable> >(lowerBounds, true)); // F: we can improve precision by asking if low != 0 elements.Add(intv); } else { arraySegmentation = default(ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression>); return(false); } #endregion #region Build the suffix // ... { upperBounds } if (arrayLen.Equals(upp.UnderlyingVariable) || arrayLen.Equals(this.Decoder.Stripped(upp).UnderlyingVariable)) { segments.Add(new SegmentLimit <BoxedVariable <Variable> >(upperBounds, false)); } else // ... { upperBounds } Top { arrayLen }? { segments.Add(new SegmentLimit <BoxedVariable <Variable> >(upperBounds, false)); elements.Add((AbstractDomain)intv.Top); segments.Add( new SegmentLimit <BoxedVariable <Variable> >( NormalizedExpression <BoxedVariable <Variable> > .For(new BoxedVariable <Variable>(arrayLen)), true)); } #endregion arraySegmentation = new ArraySegmentation <AbstractDomain, BoxedVariable <Variable>, BoxedExpression>( segments, elements, (AbstractDomain)intv.Bottom, this.ExpressionManager); return(true); }