private Expression makeMapWriteMap(FAE fae) { Debug.Assert(fae.function is MapWrite); Debug.Assert(fae.arguments[0].type is MapType); var mu = fae.function as MapWrite; Expression result; if (!versionMap.TryGetValue(fae.ToString(), out result)) { var ot = fae.arguments[0].type as MapType; Debug.Assert(ot != null); var s = new TypeParameterInstantiation(ot.typeParameters, mu.typeArguments.Skip(1).ToArray()); // var ots = new MapType(new TypeVariable[0], (from m in ot.domain select m.substitute(s)).ToArray(), ot.range.substitute(s)); Expression m = fae.arguments[0]; Expression[] i = fae.arguments.Take(fae.arguments.count - 1).Skip(1).ToArray(); if (fae.freeVariables.Count > 0) { //m(fv)[i(fv):=x(fv)] ==> v(fv) (assume v(fv)[i]==x, assume forall fv : forall j : j!=i(fv) ==> v(fv)[j] == m(fv)[j] var fvt = TypeTuple.make(from fv in fae.freeVariables select fv.type); string fn = getFreshMUName("mu"); var ft = new BFunctionTemplate(fn, "", new TypeVariable[0], new BasicFunctionSignature(ot, fvt), null); Function f = ft.getInstance(); IEnumerable <BasicBoundVariableExpression> fve = from fv in fae.freeVariables select new BasicBoundVariableExpression(fv); result = new BasicFAE(f, new ExpressionList(fve)); } else { //m[i:=x] ==> v (assume v[i]==x, assume forall j : j!=i ==> v[j] == m[j] string nvn = getFreshMUName("mu"); var nv = new ProgramVariable(nvn, ot, false, false, false, false); procedure.addVariable(nv); result = new BasicProgramVariableExpression(nv); } Expression[] j = (from e in i select new BasicBoundVariableExpression(makeBoundVariable(e.type))).ToArray(); //forall j : j!=i ==> v[j]==m[j] addConditionalMapEqualityAxiom(i, result, m, mu.typeArguments); //v[i]==x; Expression x = fae.arguments.Last(); addEqualityAxiom(ml(result, i, mu.typeArguments.Skip(1).ToArray(), x.type), fae.arguments.Last()); } return(result); }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private Function makeFreshPredicate(List <BoundVariable> list) { string name = "P$TQ_" + predicateIndex.ToString(); predicateIndex++; var ft = new BFunctionTemplate( name, "", new TypeVariable[0], new BasicFunctionSignature( BooleanType.booleanType, (from bv in list select bv.type).ToArray() ), null ); procedure.parentScope.addFunctionTemplate( ft ); return(ft.getInstance()); }