/////////////////////////////////////////////////////////////////////////// public override VCExpr VisitEqOp(VCExprNAry node, VariableBindings bindings) { Contract.Requires((bindings != null)); Contract.Requires((node != null)); Contract.Ensures(Contract.Result <VCExpr>() != null); // we also have to state that the types are equal, because the // translation does not contain any information about the // relationship between values and types return(Gen.AndSimp(base.VisitEqOp(node, bindings), EqualTypes(node[0].Type, node[1].Type, bindings))); }
private VCExpr /*!*/ GenMapAxiom1(Function /*!*/ select, Function /*!*/ store, // bound type variables in the map // type int mapTypeParamNum, // free type variables in the map // type (abstraction) int mapAbstractionVarNum) { Contract.Requires(select != null); Contract.Requires(store != null); Contract.Ensures(Contract.Result <VCExpr>() != null); int arity = select.InParams.Count - 1 - mapTypeParamNum - mapAbstractionVarNum; List <VCExprVar /*!*/> /*!*/ freeTypeVars = HelperFuns.VarVector("u", mapAbstractionVarNum, AxBuilder.T, Gen); List <VCExprVar /*!*/> /*!*/ boundTypeVars0 = HelperFuns.VarVector("s", mapTypeParamNum, AxBuilder.T, Gen); List <VCExprVar /*!*/> /*!*/ boundTypeVars1 = HelperFuns.VarVector("t", mapTypeParamNum, AxBuilder.T, Gen); List <VCExprVar /*!*/> /*!*/ types0 = new List <VCExprVar /*!*/>(boundTypeVars0); types0.AddRange(freeTypeVars); List <VCExprVar /*!*/> /*!*/ types1 = new List <VCExprVar /*!*/>(boundTypeVars1); types1.AddRange(freeTypeVars); List <Type /*!*/> indexTypes = new List <Type /*!*/>(); for (int i = mapTypeParamNum + mapAbstractionVarNum + 1; i < select.InParams.Count; i++) { indexTypes.Add(cce.NonNull(select.InParams[i]).TypedIdent.Type); } Contract.Assert(arity == indexTypes.Count); List <VCExprVar /*!*/> /*!*/ indexes0 = HelperFuns.VarVector("x", indexTypes, Gen); List <VCExprVar /*!*/> /*!*/ indexes1 = HelperFuns.VarVector("y", indexTypes, Gen); VCExprVar /*!*/ m = Gen.Variable("m", AxBuilder.U); Contract.Assert(m != null); VCExprVar /*!*/ val = Gen.Variable("val", cce.NonNull(select.OutParams[0]).TypedIdent.Type); Contract.Assert(val != null); VCExpr /*!*/ storeExpr = Store(store, types0, m, indexes0, val); Contract.Assert(storeExpr != null); VCExpr /*!*/ selectWithoutStoreExpr = Select(select, types1, m, indexes1); Contract.Assert(selectWithoutStoreExpr != null); VCExpr /*!*/ selectExpr = Select(select, types1, storeExpr, indexes1); Contract.Assert(selectExpr != null); VCExpr /*!*/ selectEq = Gen.Eq(selectExpr, selectWithoutStoreExpr); Contract.Assert(selectEq != null); List <VCExprVar /*!*/> /*!*/ quantifiedVars = new List <VCExprVar /*!*/>(); quantifiedVars.AddRange(freeTypeVars); quantifiedVars.AddRange(boundTypeVars0); quantifiedVars.AddRange(boundTypeVars1); quantifiedVars.Add(val); quantifiedVars.Add(m); quantifiedVars.AddRange(indexes0); quantifiedVars.AddRange(indexes1); List <VCTrigger /*!*/> /*!*/ triggers = new List <VCTrigger /*!*/>(); // different value arguments or different type arguments are sufficient // to conclude that that value of the map at some point (after an update) // has not changed List <VCExpr /*!*/> /*!*/ indexEqs = new List <VCExpr /*!*/>(); for (int i = 0; i < mapTypeParamNum; ++i) { indexEqs.Add(Gen.Eq(boundTypeVars0[i], boundTypeVars1[i])); } for (int i = 0; i < arity; ++i) { indexEqs.Add(Gen.Eq(indexes0[i], indexes1[i])); } VCExpr /*!*/ axiom = VCExpressionGenerator.True; int n = 0; foreach (VCExpr /*!*/ indexesEq in indexEqs) { Contract.Assert(indexesEq != null); VCExpr /*!*/ matrix = Gen.Or(indexesEq, selectEq); Contract.Assert(matrix != null); VCExpr /*!*/ conjunct = Gen.Forall(quantifiedVars, triggers, "mapAx1:" + select.Name + ":" + n, 0, matrix); Contract.Assert(conjunct != null); axiom = Gen.AndSimp(axiom, conjunct); n = n + 1; } return(axiom); }