// Add bindings to a formula using an implication or // conjunction. The bindings themselves will be flattened as well, // which might introduce further bindings private VCExpr AddBindings(List <VCExprLetBinding /*!*/> /*!*/ bindings, VCExpr body, FlattenerState state) { Contract.Requires(body != null); Contract.Requires(cce.NonNullElements(bindings)); Contract.Requires((body.Type.IsBool)); Contract.Ensures(Contract.Result <VCExpr>() != null); List <VCExprLetBinding /*!*/> /*!*/ mutatedBindings = FlattenBindings(bindings, state); Contract.Assert(mutatedBindings != null); VCExpr /*!*/ bindingEquations = Gen.AsEquations(mutatedBindings); Contract.Assert(bindingEquations != null); switch (state.Polarity) { case 1: return(Gen.Implies(bindingEquations, body)); case -1: return(Gen.And(bindingEquations, body)); case 0: // also add explicit quantifiers for the bound variables List <VCExprVar /*!*/> /*!*/ vars = new List <VCExprVar /*!*/> (); foreach (VCExprLetBinding /*!*/ binding in mutatedBindings) { Contract.Assert(binding != null); vars.Add(binding.V); } return(Gen.Forall(vars, new List <VCTrigger /*!*/>(), Gen.Implies(bindingEquations, body))); } Contract.Assert(false); throw new cce.UnreachableException(); }