protected Tuple <Variable, IdentifierExpr> GetBoundVarAndIdExpr(string name, Microsoft.Boogie.Type type) { var typeIdent = new TypedIdent(Token.NoToken, name, type); var v = new BoundVariable(Token.NoToken, typeIdent); var id = new IdentifierExpr(Token.NoToken, v, /*immutable=*/ true); return(new Tuple <Variable, IdentifierExpr>(v, id)); }
private void CreateDeviceStructConstant() { var ti = new TypedIdent(Token.NoToken, "device$struct", Microsoft.Boogie.Type.Int); var constant = new Constant(Token.NoToken, ti, true); this.AC.TopLevelDeclarations.Add(constant); this.AC.DeviceStruct = constant; }
public void IdentifierExprDecl() { var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/ true); Assert.IsTrue(id.Immutable); var typedIdent = new TypedIdent(Token.NoToken, "foo2", BasicType.Bool); Assert.Throws(typeof(InvalidOperationException), () => id.Decl = new GlobalVariable(Token.NoToken, typedIdent)); }
public void IdentifierExprDecl() { var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/ true); Assert.IsTrue(id.Immutable); var typedIdent = new TypedIdent(Token.NoToken, "foo2", BasicType.Bool); id.Decl = new GlobalVariable(Token.NoToken, typedIdent); }
// Return a new local variable private LocalVariable getNewLocal(Microsoft.Boogie.Type type) { string name = "dontcare_dummy_var_" + (localVarCount.ToString()); TypedIdent tid = new TypedIdent(Token.NoToken, name, type); LocalVariable lv = new LocalVariable(Token.NoToken, tid); localsToAdd.Add(lv); localVarCount++; return(lv); }
public override TypedIdent VisitTypedIdent(TypedIdent node) { // dropping the where clauses for now - hemr if (node.WhereExpr != null) { node.WhereExpr = null; } node.Type = VisitType(node.Type); return(node); }
public void RemoveNoConstraintsBasedOnVars() { IConstraintManager CM = new ConstraintManager(); IExprBuilder builder = GetBuilder(); // Dummy Boogie variable var bv8TypeIdent = new TypedIdent(Token.NoToken, "bv8", Microsoft.Boogie.Type.GetBvType(8)); var dummyVarBv = new GlobalVariable(Token.NoToken, bv8TypeIdent); // dummyVar needs a programLocation, otherwise SymbolicVariable constructor raises an exception var progLoc = new ProgramLocation(dummyVarBv); dummyVarBv.SetMetadata <ProgramLocation>((int)Symbooglix.Annotation.AnnotationIndex.PROGRAM_LOCATION, progLoc); var s0 = new SymbolicVariable("s0", dummyVarBv).Expr; var s1 = new SymbolicVariable("s1", dummyVarBv).Expr; var s2 = new SymbolicVariable("s2", dummyVarBv).Expr; // Construct some constraints Expr c0 = builder.Eq(builder.BVAND(s0, s1), builder.ConstantBV(0, 8)); Expr c1 = builder.Eq(s2, builder.ConstantBV(1, 8)); CM.AddConstraint(c0, progLoc); CM.AddConstraint(c1, progLoc); var mockSolver = new MockSolver(); var indepenceSolver = new Symbooglix.Solver.ConstraintIndependenceSolver(mockSolver); Expr queryExpr = builder.Eq(builder.BVAND(s1, s2), builder.ConstantBV(0, 8)); indepenceSolver.ComputeSatisfiability(new Solver.Query(CM, new Constraint(queryExpr))); // Check no constraints were removed Assert.AreEqual(2, mockSolver.Constraints.Count); Assert.AreSame(queryExpr, mockSolver.QueryExpr); bool c0Found = false; bool c1Found = false; foreach (var constraint in mockSolver.Constraints) { if (c0 == constraint.Condition) { c0Found = true; } if (c1 == constraint.Condition) { c1Found = true; } } Assert.IsTrue(c0Found); Assert.IsTrue(c1Found); }
public static Variable MakeValueVariable(string name, AccessType access, Type type) { var ident = new TypedIdent(Token.NoToken, MakeValueVariableName(name, access), type); if (RaceCheckingMethod == RaceCheckingMethod.ORIGINAL) { return(new GlobalVariable(Token.NoToken, ident)); } return(new Constant(Token.NoToken, ident, false)); }
public static Variable MakeValueVariable(string Name, AccessType Access, Microsoft.Boogie.Type Type) { var Ident = new TypedIdent(Token.NoToken, MakeValueVariableName(Name, Access), Type); if (RaceCheckingMethod == RaceCheckingMethod.ORIGINAL) { return(new GlobalVariable(Token.NoToken, Ident)); } return(new Constant(Token.NoToken, Ident, false)); }
// FIXME: This copied from the ExprBuilder tests. Refactor this protected Tuple <IdentifierExpr, BPLType> GetMapVariable(string name, BPLType resultTyp, params BPLType[] indices) { var mapType = new MapType(Token.NoToken, new List <Microsoft.Boogie.TypeVariable>(), indices.ToList(), resultTyp); var typeIdent = new TypedIdent(Token.NoToken, name, mapType); var gv = new GlobalVariable(Token.NoToken, typeIdent); var id = new IdentifierExpr(Token.NoToken, gv, /*immutable=*/ true); var result = new Tuple <IdentifierExpr, BPLType>(id, mapType); return(result); }
public bool Initialize(Microsoft.Boogie.Type[] varts) { if (varts.Length != Count || initialized) { return(false); } for (int i = 0; i < Count; i++) { vars[i] = new TypedIdent(Token.NoToken, baseName + i, varts[i]); } return(initialized = true); }
SymbolicVariable GetVar(string name) { // FIXME: THIS IS A HACK! // Dummy Boogie variable var IntTypeIdent = new TypedIdent(Token.NoToken, name, Microsoft.Boogie.Type.Int); var dummyVarBv = new GlobalVariable(Token.NoToken, IntTypeIdent); // dummyVar needs a programLocation, otherwise SymbolicVariable constructor raises an exception var progLoc = new ProgramLocation(dummyVarBv); dummyVarBv.SetMetadata <ProgramLocation>((int)Symbooglix.Annotation.AnnotationIndex.PROGRAM_LOCATION, progLoc); return(new SymbolicVariable(name, dummyVarBv)); }
private void AddAccessWatchdogConstants() { foreach (var mr in this.AC.SharedMemoryRegions) { var ti = new TypedIdent(Token.NoToken, "WATCHED_ACCESS_" + mr.Name, this.AC.MemoryModelType); var watchdog = new Constant(Token.NoToken, ti, false); watchdog.AddAttribute("watchdog", new object[] { }); if (!this.AC.TopLevelDeclarations.OfType <Variable>().Any(val => val.Name.Equals(watchdog.Name))) { this.AC.TopLevelDeclarations.Add(watchdog); } } }
private void AddAccessWatchdogConstants() { for (int i = 0; i < this.MemoryRegions.Count; i++) { var ti = new TypedIdent(Token.NoToken, this.AC.GetAccessWatchdogConstantName(this.MemoryRegions[i].Name), this.AC.MemoryModelType); var watchdog = new Constant(Token.NoToken, ti, false); watchdog.AddAttribute("watchdog", new object[] { }); if (!this.AC.TopLevelDeclarations.OfType <Variable>().Any(val => val.Name.Equals(watchdog.Name))) { this.AC.TopLevelDeclarations.Add(watchdog); } } }
private Variable VarOfKind(TypedIdent x, StateKind k) { switch (k) { case StateKind.Local: return(new LocalVariable(Token.NoToken, x)); case StateKind.Global: return(new GlobalVariable(Token.NoToken, x)); case StateKind.FormalIn: return(new Formal(Token.NoToken, x, true)); case StateKind.FormalOut: return(new Formal(Token.NoToken, x, false)); } return(null); //impossible! }
// FIXME: Taken from SimpleExprBuilderTestBase. This needs to be refactored protected Tuple <Variable, IdentifierExpr> GetVarAndIdExpr(string name, Microsoft.Boogie.Type type, bool isBound = false) { var typeIdent = new TypedIdent(Token.NoToken, name, type); Variable v = null; if (isBound) { v = new BoundVariable(Token.NoToken, typeIdent); } else { v = new GlobalVariable(Token.NoToken, typeIdent); } var id = new IdentifierExpr(Token.NoToken, v, /*immutable=*/ true); return(new Tuple <Variable, IdentifierExpr>(v, id)); }
/// <summary> /// Creates a global variable with the given name. /// </summary> /// <param name="name">The name of the variable.</param> /// <returns>A reference to the variable.</returns> private Variable CreateGlobalVariable(string name) { Dictionary <string, object> attributes = new Dictionary <string, object>(); attributes.Add("repair", null); attributes.Add("race_checking", null); attributes.Add("global", null); attributes.Add("elem_width", Expr.Literal(32)); attributes.Add("source_elem_width", Expr.Literal(32)); attributes.Add("source_dimensions", "*"); TypedIdent ident = new TypedIdent(Token.NoToken, name, Type.Bool); Variable variable = useAxioms ? new Constant(Token.NoToken, ident, false) : new GlobalVariable(Token.NoToken, ident) as Variable; variable.Attributes = ConvertAttributes(attributes); program.AddTopLevelDeclaration(variable); return(variable); }
// Return a new local variable. Also add it to impl if it is not null private static LocalVariable getNewLocal(Microsoft.Boogie.Type type, Implementation impl) { Debug.Assert(type != null); string name = ""; LocalVariable lv = null; do { name = "vslice_dummy_var_" + (localVarCount.ToString()); TypedIdent tid = new TypedIdent(Token.NoToken, name, type); lv = new LocalVariable(Token.NoToken, tid); localVarCount++; } while (impl != null && impl.LocVars.Any(v => v.Name == name)); if (impl != null) { impl.LocVars.Add(lv); } return(lv); }
public void MapWithTypeConstructorTypesNoArguments() { var tcDecl = new TypeCtorDecl(Token.NoToken, "fox", 0); var tc = new CtorType(Token.NoToken, tcDecl, new List <Microsoft.Boogie.Type>()); var tcDecl2 = new TypeCtorDecl(Token.NoToken, "fox_two", 0); var tc2 = new CtorType(Token.NoToken, tcDecl2, new List <Microsoft.Boogie.Type>()); var tcDecl3 = new TypeCtorDecl(Token.NoToken, "fox_three", 0); var tc3 = new CtorType(Token.NoToken, tcDecl3, new List <Microsoft.Boogie.Type>()); var mapType = new MapType( Token.NoToken, new List <Microsoft.Boogie.TypeVariable>(), new List <Microsoft.Boogie.Type>() { tc, tc2 }, tc3); var mapTypeTypeIdent = new TypedIdent(Token.NoToken, "mapx", mapType); var gv = new GlobalVariable(Token.NoToken, mapTypeTypeIdent); // FIXME: The Symbolic constructor shouldn't really need the program location gv.SetMetadata <ProgramLocation>((int)AnnotationIndex.PROGRAM_LOCATION, new ProgramLocation(gv)); var sym = new SymbolicVariable("y", gv); var builder = new SimpleExprBuilder(/*immutable=*/ true); var eq = builder.Eq(sym.Expr, sym.Expr); Assert.IsNotInstanceOf <LiteralExpr>(eq); // Check that it wasn't constant folded using (var writer = new StringWriter()) { var printer = GetPrinter(writer); printer.AddDeclarations(eq); printer.PrintSortDeclarations(); var str = writer.ToString().Trim(); // Check we can see all the sort declarations we expect but don't depend on their order Assert.IsTrue(str.Contains("(declare-sort @fox)")); Assert.IsTrue(str.Contains("(declare-sort @fox_two)")); Assert.IsTrue(str.Contains("(declare-sort @fox_three)")); } }
public void NoArguments() { var tcDecl = new TypeCtorDecl(Token.NoToken, "fox", 0); var tc = new CtorType(Token.NoToken, tcDecl, new List <Microsoft.Boogie.Type>()); var tcTypeIdent = new TypedIdent(Token.NoToken, "fox", tc); var gv = new GlobalVariable(Token.NoToken, tcTypeIdent); // FIXME: The Symbolic constructor shouldn't really need the program location gv.SetMetadata <ProgramLocation>((int)AnnotationIndex.PROGRAM_LOCATION, new ProgramLocation(gv)); var sym = new SymbolicVariable("y", gv); var builder = new SimpleExprBuilder(/*immutable=*/ true); var eq = builder.Eq(sym.Expr, sym.Expr); Assert.IsNotInstanceOf <LiteralExpr>(eq); // Check that it wasn't constant folded using (var writer = new StringWriter()) { var printer = GetPrinter(writer); printer.AddDeclarations(eq); printer.PrintSortDeclarations(); Assert.AreEqual("(declare-sort @fox)", writer.ToString().Trim()); } }
public FreeVariable(TypedIdent ti) : base(Token.NoToken, ti) { }
public void WholeProgram() { var p = new Program(); var t = new TypedIdent(Token.NoToken, "foo", Microsoft.Boogie.Type.Bool); var gv = new GlobalVariable(Token.NoToken, t); p.AddTopLevelDeclaration(gv); string metaDataString = "This is a test"; p.SetMetadata(0, metaDataString); // Now try to clone var p2 = (Program)d.Visit(p); // Check global is a copy int counter = 0; GlobalVariable gv2 = null; foreach (var g in p2.TopLevelDeclarations) { ++counter; Assert.IsInstanceOf <GlobalVariable>(g); gv2 = g as GlobalVariable; } Assert.AreEqual(1, counter); Assert.AreNotSame(gv, gv2); Assert.AreEqual(metaDataString, p2.GetMetadata <string>(0)); // Check Top level declarations list is duplicated properly var t2 = new TypedIdent(Token.NoToken, "bar", Microsoft.Boogie.Type.Bool); var gv3 = new GlobalVariable(Token.NoToken, t2); p2.AddTopLevelDeclaration(gv3); counter = 0; foreach (var g in p2.TopLevelDeclarations) { ++counter; Assert.IsInstanceOf <GlobalVariable>(g); } Assert.AreEqual(2, counter); // The original program should still only have one global variable counter = 0; foreach (var g in p.TopLevelDeclarations) { ++counter; Assert.IsInstanceOf <GlobalVariable>(g); Assert.AreSame(g, gv); } Assert.AreEqual(1, counter); // Change Metadata in p2, this shouldn't affect p string newMetaDataString = "Another test"; p2.SetMetadata(0, newMetaDataString); Assert.AreNotEqual(p2.GetMetadata <string>(0), p.GetMetadata <string>(0)); }
public override TypedIdent VisitTypedIdent(TypedIdent node) { add(node); return(base.VisitTypedIdent(node)); }
public override TypedIdent VisitTypedIdent(TypedIdent node) { return(base.VisitTypedIdent((TypedIdent)node.Clone())); }
public static Variable MakeAsyncHandleVariable(string name, AccessType access, Type type) { var ident = new TypedIdent(Token.NoToken, MakeAsyncHandleVariableName(name, access), type); return(new GlobalVariable(Token.NoToken, ident)); }
public void RemoveOneConstraintBasedOnVarsAndFunctions() { IConstraintManager CM = new ConstraintManager(); var builder = GetBuilder(); // Dummy Boogie variable var bv8Type = Microsoft.Boogie.Type.GetBvType(8); var bv8TypeIdent = new TypedIdent(Token.NoToken, "bv8", bv8Type); var dummyVarBv = new GlobalVariable(Token.NoToken, bv8TypeIdent); // dummyVar needs a programLocation, otherwise SymbolicVariable constructor raises an exception var progLoc = new ProgramLocation(dummyVarBv); dummyVarBv.SetMetadata <ProgramLocation>((int)Symbooglix.Annotation.AnnotationIndex.PROGRAM_LOCATION, progLoc); var s0 = new SymbolicVariable("s0", dummyVarBv).Expr; var s1 = new SymbolicVariable("s1", dummyVarBv).Expr; var s2 = new SymbolicVariable("s2", dummyVarBv).Expr; // Construct some constraints Expr c0 = builder.Eq(builder.BVAND(s0, s1), builder.ConstantBV(0, 8)); Expr c1 = builder.Eq(s2, builder.ConstantBV(1, 8)); var FCB = new FunctionCallBuilder(); var foobarFunc = FCB.CreateUninterpretedFunctionCall("foobar", bv8Type, new List <Microsoft.Boogie.Type>() { bv8Type }); // foobar(0bv8) == 0bv8 Expr c2 = builder.Eq(builder.UFC(foobarFunc, builder.ConstantBV(0, 8)), builder.ConstantBV(0, 8)); CM.AddConstraint(c0, progLoc); CM.AddConstraint(c1, progLoc); CM.AddConstraint(c2, progLoc); var mockSolver = new MockSolver(); var indepenceSolver = new Symbooglix.Solver.ConstraintIndependenceSolver(mockSolver); // The query expression does not use the "foobar" function so we don't need to keep constraints on that function Expr queryExpr = builder.Eq(builder.BVAND(s1, s2), builder.ConstantBV(0, 8)); indepenceSolver.ComputeSatisfiability(new Solver.Query(CM, new Constraint(queryExpr))); // Check no constraints were removed Assert.AreEqual(2, mockSolver.Constraints.Count); Assert.AreSame(queryExpr, mockSolver.QueryExpr); bool c0Found = false; bool c1Found = false; foreach (var constraint in mockSolver.Constraints) { if (c0 == constraint.Condition) { c0Found = true; } if (c1 == constraint.Condition) { c1Found = true; } } Assert.IsTrue(c0Found); Assert.IsTrue(c1Found); }
public override TypedIdent VisitTypedIdent(TypedIdent node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result <TypedIdent>() != null); return(base.VisitTypedIdent((TypedIdent)node.Clone())); }
/// <summary> /// Performs lambda lifting (see <see cref="LambdaHelper.ExpandLambdas"/>) by replacing the lambda's /// free variables with bound ones. /// </summary> /// <param name="lambda">A lambda expression /// <code>(lambda x1: T1 ... x_n: T_n :: t)</code> /// where <c>t</c> contains the free variables <c>y1</c>, ..., <c>y_m</c>. /// </param> /// <returns> /// <list type="bullet"> /// <item> /// A function application <c>f(y1, ..., y_m)</c> where <c>f</c>'s body is defined to be the result of /// replacing the free variables <c>y1</c>, ..., <c>y_m</c> in <c>t</c> with bound variables /// <c>b1</c>, ..., <c>b_m</c>. /// </item> /// <item> /// Adds a definition and axiom for <c>f</c> to <see cref="lambdaFunctions"/> and <see cref="lambdaAxioms"/>. /// Memoizes <c>f</c> as the lifted lambda for <para>lambda</para>. /// </item> /// </list> /// </returns> private Expr LiftLambdaFreeVars(LambdaExpr lambda) { // We start by getting rid of any use of "old" inside the lambda. This is done as follows. // For each variable "g" occurring inside lambda as "old(... g ...)", create a new name "og". // Replace each old occurrence of "g" with "og", removing the enclosing "old" wrappers. var oldFinder = new OldFinder(); oldFinder.Visit(lambda); var oldSubst = new Dictionary<Variable, Expr>(); // g -> g0 var callOldMapping = new Dictionary<Variable, Expr>(); // g0 -> old(g) foreach (var v in oldFinder.FreeOldVars) { var g = v as GlobalVariable; if (g != null) { var g0 = new GlobalVariable(g.tok, new TypedIdent(g.tok, g.TypedIdent.Name + "@old", g.TypedIdent.Type)); oldSubst.Add(g, new IdentifierExpr(g0.tok, g0)); callOldMapping.Add(g0, new OldExpr(g0.tok, new IdentifierExpr(g.tok, g))); } } var lambdaBody = Substituter.ApplyReplacingOldExprs( Substituter.SubstitutionFromDictionary(new Dictionary<Variable, Expr>()), Substituter.SubstitutionFromDictionary(oldSubst), lambda.Body); var lambdaAttrs = Substituter.ApplyReplacingOldExprs( Substituter.SubstitutionFromDictionary(new Dictionary<Variable, Expr>()), Substituter.SubstitutionFromDictionary(oldSubst), lambda.Attributes); if (0 < CommandLineOptions.Clo.VerifySnapshots && QKeyValue.FindStringAttribute(lambdaAttrs, "checksum") == null) { // Attach a dummy checksum to avoid issues in the dependency analysis. var checksumAttr = new QKeyValue(lambda.tok, "checksum", new List<object> {"lambda expression"}, null); if (lambdaAttrs == null) { lambdaAttrs = checksumAttr; } else { lambdaAttrs.AddLast(checksumAttr); } } // this is ugly, the output will depend on hashing order var subst = new Dictionary<Variable, Expr>(); var substFnAttrs = new Dictionary<Variable, Expr>(); var formals = new List<Variable>(); var callArgs = new List<Expr>(); var axCallArgs = new List<Expr>(); var dummies = new List<Variable>(lambda.Dummies); var freeTypeVars = new List<TypeVariable>(); var fnTypeVarActuals = new List<Type /*!*/>(); var freshTypeVars = new List<TypeVariable>(); // these are only used in the lambda@n function's definition // compute the free variables of the lambda expression, but with lambdaBody instead of lambda.Body Set freeVars = new Set(); BinderExpr.ComputeBinderFreeVariables(lambda.TypeParameters, lambda.Dummies, lambdaBody, null, lambdaAttrs, freeVars); foreach (object o in freeVars) { // 'o' is either a Variable or a TypeVariable. if (o is Variable) { var v = o as Variable; var ti = new TypedIdent(v.TypedIdent.tok, v.TypedIdent.Name, v.TypedIdent.Type); var f = new Formal(v.tok, ti, true); formals.Add(f); substFnAttrs.Add(v, new IdentifierExpr(f.tok, f)); var b = new BoundVariable(v.tok, ti); dummies.Add(b); if (callOldMapping.ContainsKey(v)) { callArgs.Add(callOldMapping[v]); } else { callArgs.Add(new IdentifierExpr(v.tok, v)); } Expr id = new IdentifierExpr(b.tok, b); subst.Add(v, id); axCallArgs.Add(id); } else { var tv = (TypeVariable) o; freeTypeVars.Add(tv); fnTypeVarActuals.Add(tv); freshTypeVars.Add(new TypeVariable(tv.tok, tv.Name)); } } var sw = new System.IO.StringWriter(); var wr = new TokenTextWriter(sw, true); lambda.Emit(wr); string lam_str = sw.ToString(); FunctionCall fcall; IToken tok = lambda.tok; Formal res = new Formal(tok, new TypedIdent(tok, TypedIdent.NoName, cce.NonNull(lambda.Type)), false); if (liftedLambdas.TryGetValue(lambda, out fcall)) { if (CommandLineOptions.Clo.TraceVerify) { Console.WriteLine("Old lambda: {0}", lam_str); } } else { if (CommandLineOptions.Clo.TraceVerify) { Console.WriteLine("New lambda: {0}", lam_str); } Function fn = new Function(tok, FreshLambdaFunctionName(), freshTypeVars, formals, res, "auto-generated lambda function", Substituter.Apply(Substituter.SubstitutionFromDictionary(substFnAttrs), lambdaAttrs)); fn.OriginalLambdaExprAsString = lam_str; fcall = new FunctionCall(new IdentifierExpr(tok, fn.Name)); fcall.Func = fn; // resolve here liftedLambdas[lambda] = fcall; List<Expr /*!*/> selectArgs = new List<Expr /*!*/>(); foreach (Variable /*!*/ v in lambda.Dummies) { Contract.Assert(v != null); selectArgs.Add(new IdentifierExpr(v.tok, v)); } NAryExpr axcall = new NAryExpr(tok, fcall, axCallArgs); axcall.Type = res.TypedIdent.Type; axcall.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); NAryExpr select = Expr.Select(axcall, selectArgs); select.Type = lambdaBody.Type; List<Type /*!*/> selectTypeParamActuals = new List<Type /*!*/>(); List<TypeVariable> forallTypeVariables = new List<TypeVariable>(); foreach (TypeVariable /*!*/ tp in lambda.TypeParameters) { Contract.Assert(tp != null); selectTypeParamActuals.Add(tp); forallTypeVariables.Add(tp); } forallTypeVariables.AddRange(freeTypeVars); select.TypeParameters = SimpleTypeParamInstantiation.From(lambda.TypeParameters, selectTypeParamActuals); Expr bb = Substituter.Apply(Substituter.SubstitutionFromDictionary(subst), lambdaBody); NAryExpr body = Expr.Eq(select, bb); body.Type = Type.Bool; body.TypeParameters = SimpleTypeParamInstantiation.EMPTY; Trigger trig = new Trigger(select.tok, true, new List<Expr> {select}); lambdaFunctions.Add(fn); lambdaAxioms.Add(new ForallExpr(tok, forallTypeVariables, dummies, Substituter.Apply(Substituter.SubstitutionFromDictionary(subst), lambdaAttrs), trig, body)); } NAryExpr call = new NAryExpr(tok, fcall, callArgs); call.Type = res.TypedIdent.Type; call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); return call; }
public override Absy Visit(Absy node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Absy>() != null); node = base.Visit(node); LambdaExpr lambda = node as LambdaExpr; if (lambda != null) { IToken/*!*/ tok = lambda.tok; Contract.Assert(tok != null); Set freeVars = new Set(); lambda.ComputeFreeVariables(freeVars); // this is ugly, the output will depend on hashing order Dictionary<Variable, Expr> subst = new Dictionary<Variable, Expr>(); List<Variable> formals = new List<Variable>(); List<Expr> callArgs = new List<Expr>(); List<Expr> axCallArgs = new List<Expr>(); List<Variable> dummies = new List<Variable>(lambda.Dummies); List<TypeVariable> freeTypeVars = new List<TypeVariable>(); List<Type/*!*/> fnTypeVarActuals = new List<Type/*!*/>(); List<TypeVariable> freshTypeVars = new List<TypeVariable>(); // these are only used in the lambda@n function's definition foreach (object o in freeVars) { // 'o' is either a Variable or a TypeVariable. Since the lambda desugaring happens only // at the outermost level of a program (where there are no mutable variables) and, for // procedure bodies, after the statements have been passified (when mutable variables have // been replaced by immutable incarnations), we are interested only in BoundVar's and // TypeVariable's. BoundVariable v = o as BoundVariable; if (v != null) { TypedIdent ti = new TypedIdent(v.TypedIdent.tok, v.TypedIdent.Name, v.TypedIdent.Type); Formal f = new Formal(v.tok, ti, true); formals.Add(f); BoundVariable b = new BoundVariable(v.tok, ti); dummies.Add(b); callArgs.Add(new IdentifierExpr(v.tok, v)); Expr/*!*/ id = new IdentifierExpr(f.tok, b); Contract.Assert(id != null); subst.Add(v, id); axCallArgs.Add(id); } else if (o is TypeVariable) { TypeVariable tv = (TypeVariable)o; freeTypeVars.Add(tv); fnTypeVarActuals.Add(tv); freshTypeVars.Add(new TypeVariable(tv.tok, tv.Name)); } } Formal res = new Formal(tok, new TypedIdent(tok, TypedIdent.NoName, cce.NonNull(lambda.Type)), false); Function fn = new Function(tok, "lambda@" + lambdaid++, freshTypeVars, formals, res, "auto-generated lambda function", lambda.Attributes); lambdaFunctions.Add(fn); FunctionCall fcall = new FunctionCall(new IdentifierExpr(tok, fn.Name)); fcall.Func = fn; // resolve here List<Expr/*!*/> selectArgs = new List<Expr/*!*/>(); foreach (Variable/*!*/ v in lambda.Dummies) { Contract.Assert(v != null); selectArgs.Add(new IdentifierExpr(v.tok, v)); } NAryExpr axcall = new NAryExpr(tok, fcall, axCallArgs); axcall.Type = res.TypedIdent.Type; axcall.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); NAryExpr select = Expr.Select(axcall, selectArgs); select.Type = lambda.Body.Type; List<Type/*!*/> selectTypeParamActuals = new List<Type/*!*/>(); List<TypeVariable> forallTypeVariables = new List<TypeVariable>(); foreach (TypeVariable/*!*/ tp in lambda.TypeParameters) { Contract.Assert(tp != null); selectTypeParamActuals.Add(tp); forallTypeVariables.Add(tp); } forallTypeVariables.AddRange(freeTypeVars); select.TypeParameters = SimpleTypeParamInstantiation.From(lambda.TypeParameters, selectTypeParamActuals); Expr bb = Substituter.Apply(Substituter.SubstitutionFromHashtable(subst), lambda.Body); NAryExpr body = Expr.Eq(select, bb); body.Type = Type.Bool; body.TypeParameters = SimpleTypeParamInstantiation.EMPTY; Trigger trig = new Trigger(select.tok, true, new List<Expr> { select }); lambdaAxioms.Add(new ForallExpr(tok, forallTypeVariables, dummies, lambda.Attributes, trig, body)); NAryExpr call = new NAryExpr(tok, fcall, callArgs); call.Type = res.TypedIdent.Type; call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); return call; } return node; }