public PentagonsPlus( WeakUpperBoundsEqual <Variable, Expression> left, Pentagons <Variable, Expression> right, ExpressionManagerWithEncoder <Variable, Expression> expManager) : base(left, right, expManager) { Contract.Requires(left != null); Contract.Requires(right != null); Contract.Requires(expManager != null); }
public Pentagons <Variable, Expression> TestTrueLessThan(Expression exp1, Expression exp2, WeakUpperBoundsEqual <Variable, Expression> oracleDomain) { Contract.Requires(exp1 != null); Contract.Requires(exp2 != null); Contract.Requires(oracleDomain != null); Contract.Ensures(Contract.Result <Pentagons <Variable, Expression> >() != null); var newLeft = this.Left.TestTrueLessThan(exp1, exp2); var newRight = this.Right.TestTrueLessThan(exp1, exp2, oracleDomain); return(this.FactoryOfPentagons(newLeft, newRight)); }
private void AssignInParallel (WeakUpperBoundsEqual <Variable, Expression> wubeq, WeakUpperBounds <Variable, Expression> wub, Dictionary <Variable, FList <Variable> > sourcesToTargets, INumericalAbstractDomain <Variable, Expression> oracleDomain) { Contract.Requires(wubeq != null); Contract.Requires(wub != null); // adding the domain-generated variables to the map as identity var oldToNewMap = new Dictionary <Variable, FList <Variable> >(sourcesToTargets); if (!wubeq.IsTop) { foreach (var e in wubeq.SlackVariables) { oldToNewMap[e] = FList <Variable> .Cons(e, FList <Variable> .Empty); } } if (!wub.IsTop) { foreach (var e in wub.SlackVariables) { oldToNewMap[e] = FList <Variable> .Cons(e, FList <Variable> .Empty); } } // when x has several targets including itself, the canonical element shouldn't be itself foreach (var sourceToTargets in sourcesToTargets) { var source = sourceToTargets.Key; var targets = sourceToTargets.Value; Contract.Assume(targets != null); if (targets.Length() > 1 && targets.Head.Equals(source)) { var tail = targets.Tail; Contract.Assert(tail != null); var newTargets = FList <Variable> .Cons(tail.Head, FList <Variable> .Cons(source, tail.Tail)); oldToNewMap[source] = newTargets; } } AssignInParallelWUBSpecific(wub, oldToNewMap); AssignInParallelWUBEQSpecific(wubeq, sourcesToTargets, oldToNewMap); }
Factory(WeakUpperBoundsEqual <Variable, Expression> left, Pentagons <Variable, Expression> right) { Contract.Ensures(Contract.Result <ReducedCartesianAbstractDomain <WeakUpperBoundsEqual <Variable, Expression>, Pentagons <Variable, Expression> > >() != null); return(new PentagonsPlus <Variable, Expression>(left, right, this.ExpressionManager)); }
Reduce(WeakUpperBoundsEqual <Variable, Expression> left, Pentagons <Variable, Expression> right) { return(this.Factory(left, right)); }
private void AssignInParallelWUBEQSpecific( WeakUpperBoundsEqual <Variable, Expression> wubeq, Dictionary <Variable, FList <Variable> > sourcesToTargets, Dictionary <Variable, FList <Variable> > oldToNewMap) { Contract.Requires(wubeq != null); Contract.Requires(sourcesToTargets != null); Contract.Requires(oldToNewMap != null); var newMappings = new Dictionary <Variable, List <Variable> >(wubeq.Count); foreach (var oldLeft_Pair in wubeq.Elements) { FList <Variable> targets; if (oldToNewMap.TryGetValue(oldLeft_Pair.Key, out targets)) { Contract.Assume(targets != null); var oldBounds = oldLeft_Pair.Value; if (!oldBounds.IsNormal()) { continue; } var newLeft = targets.Head; // our canonical element foreach (var oldRight in oldBounds.Values) { FList <Variable> olds; if (oldToNewMap.TryGetValue(oldRight, out olds)) { Contract.Assume(olds != null); var newRight = olds.Head; // our canonical element AddUpperBound(newLeft, newRight, newMappings); } } } } // Precision improvements: // // Consider: // if (x < y) x = y; // Debug.Assert(x >= y); // // This is an example where at the end of the then branch, we have a single old variable being assigned to new new variables: // x := y' and y := y' // Since in this branch, we obviously have y' => y', the new renamed state should have y => x and x => y. That way, at the join, // the constraint x >= y is retained. // foreach (var pair in sourcesToTargets) { var targets = pair.Value; Contract.Assume(targets != null); var newCanonical = targets.Head; targets = targets.Tail; while (targets != null) { // make all other targets equal to canonical (rather than n^2 combinations) AddUpperBound(newCanonical, targets.Head, newMappings); AddUpperBound(targets.Head, newCanonical, newMappings); targets = targets.Tail; } } var result = new List <Pair <Variable, SetOfConstraints <Variable> > >(); // now add the new mappings foreach (var pair in newMappings) { var bounds = pair.Value; Contract.Assume(bounds != null); if (bounds.Count == 0) { continue; } var newBoundsFromClosure = new Set <Variable>(bounds); foreach (var upp in bounds) { List <Variable> values; if (!upp.Equals(pair.Key) && newMappings.TryGetValue(upp, out values)) { Contract.Assume(values != null); newBoundsFromClosure.AddRange(values); } } result.Add(pair.Key, new SetOfConstraints <Variable>(newBoundsFromClosure, false)); } wubeq.SetElements(result); }