// Remove all let-bindings from the field bindings whose rhs // contains any of the specified variables private List <VCExprLetBinding /*!*/> /*!*/ RemoveBindingsWithVars(List <VCExprVar /*!*/> /*!*/ boundVars, List <TypeVariable /*!*/> /*!*/ boundTypeVars) { Contract.Requires(cce.NonNullElements(boundTypeVars)); Contract.Requires(cce.NonNullElements(boundVars)); Contract.Ensures(cce.NonNullElements(Contract.Result <List <VCExprLetBinding> >())); List <VCExprLetBinding /*!*/> /*!*/ res = new List <VCExprLetBinding /*!*/>(); FreeVariableCollector /*!*/ coll = new FreeVariableCollector(); foreach (KeyValuePair <VCExpr, VCExprVar> pair in Bindings) { Contract.Assert(cce.NonNullElements(pair)); coll.Collect(pair.Key); if (boundVars.Any(var => coll.FreeTermVars.ContainsKey(var)) || boundTypeVars.Any(var => coll.FreeTypeVars.Contains(var))) { res.Add(Gen.LetBinding(pair.Value, pair.Key)); } coll.Reset(); } foreach (VCExprLetBinding b in res) { Contract.Assert(b != null); Bindings.Remove(b.E); } return(res); }
//////////////////////////////////////////////////////////////////////////// public override VCExpr Visit(VCExprQuantifier node, VariableBindings oldBindings) { Contract.Requires(oldBindings != null); Contract.Requires(node != null); Contract.Ensures(Contract.Result<VCExpr>() != null); VariableBindings bindings = oldBindings.Clone(); // determine the bound vars that actually occur in the body or // in any of the triggers (if some variables do not occur, we // need to take special care of type parameters that only occur // in the types of such variables) FreeVariableCollector coll = new FreeVariableCollector(); coll.Collect(node.Body); foreach (VCTrigger trigger in node.Triggers) { if (trigger.Pos) foreach (VCExpr/*!*/ e in trigger.Exprs) { Contract.Assert(e != null); coll.Collect(e); } } List<VCExprVar/*!*/> occurringVars = new List<VCExprVar/*!*/>(node.BoundVars.Count); foreach (VCExprVar var in node.BoundVars) if (coll.FreeTermVars.ContainsKey(var)) occurringVars.Add(var); occurringVars.TrimExcess(); // bound term variables are replaced with bound term variables typed in // a simpler way List<VCExprVar/*!*/>/*!*/ newBoundVars = BoundVarsAfterErasure(occurringVars, bindings); Contract.Assert(cce.NonNullElements(newBoundVars)); VCExpr/*!*/ newNode = HandleQuantifier(node, occurringVars, newBoundVars, bindings); Contract.Assert(newNode != null); if (!(newNode is VCExprQuantifier) || !IsUniversalQuantifier(node)) return newNode; VariableBindings bindings2; if (!RedoQuantifier(node, (VCExprQuantifier)newNode, occurringVars, oldBindings, out bindings2, out newBoundVars)) return newNode; return HandleQuantifier(node, occurringVars, newBoundVars, bindings2); }