public override Bpl.Variable CreateEventVariable(IEventDefinition e) { Bpl.Variable v; string fieldName = MemberHelper.GetMemberSignature(e, NameFormattingOptions.DocumentationId); // HACK fieldName = fieldName.Replace("E:", "F:"); fieldName = TranslationHelper.TurnStringIntoValidIdentifier(fieldName); Bpl.IToken tok = e.Token(); Bpl.Type t = this.sink.CciTypeToBoogie(e.Type.ResolvedType); if (e.Adder.ResolvedMethod.IsStatic) { Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldName, t); v = new Bpl.GlobalVariable(tok, tident); } else { Bpl.Type mt = new Bpl.MapType(tok, new List <Bpl.TypeVariable>(), new List <Bpl.Type>(new Bpl.Type[] { this.RefType }), t); Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldName, mt); v = new Bpl.GlobalVariable(tok, tident); } return(v); }
private static Microsoft.Boogie.TypedIdent CopyAndRename(Microsoft.Boogie.TypedIdent TI, string NewName) { // HACK: We need our own TypedIdent apparently so when we print Expr we have the right name for the variable // instead of the name of the origin Variable. var copy = (Microsoft.Boogie.TypedIdent) TI.Clone(); copy.Name = NewName; return copy; }
/// <summary> /// Creates a fresh BPL variable to represent <paramref name="type"/>, deciding /// on its type based on the heap representation. I.e., the value of this /// variable represents the value of the expression "typeof(type)". /// </summary> public Bpl.Variable CreateTypeVariable(ITypeReference type, List <Bpl.ConstantParent> parents) { string typename = TypeHelper.GetTypeName(type, NameFormattingOptions.DocumentationId); typename = TranslationHelper.TurnStringIntoValidIdentifier(typename); Bpl.IToken tok = type.Token(); Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, typename, this.TypeType); Bpl.Constant v = new Bpl.Constant(tok, tident, true /*unique*/, parents, false, null); return(v); }
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)); }
/// <summary> /// Creates a fresh BPL variable to represent <paramref name="field"/>, deciding /// on its type based on the heap representation. /// </summary> public override Bpl.Variable CreateFieldVariable(IFieldReference field) { Bpl.Variable v; string fieldname = MemberHelper.GetMemberSignature(field, NameFormattingOptions.DocumentationId); fieldname = TranslationHelper.TurnStringIntoValidIdentifier(fieldname); Bpl.IToken tok = field.Token(); Bpl.Type t = this.sink.CciTypeToBoogie(field.Type.ResolvedType); if (field.ResolvedField.IsStatic) { Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t); v = new Bpl.GlobalVariable(tok, tident); } else { Bpl.Type mt = new Bpl.MapType(tok, new List<Bpl.TypeVariable>(), new List<Bpl.Type>(new Bpl.Type[] {this.RefType}), t); Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, mt); v = new Bpl.GlobalVariable(tok, tident); } return v; }
/// <summary> /// Creates a fresh BPL variable to represent <paramref name="field"/>, deciding /// on its type based on the heap representation. /// </summary> public override Bpl.Variable CreateFieldVariable(IFieldReference field) { Bpl.Variable v; string fieldname = MemberHelper.GetMemberSignature(field, NameFormattingOptions.DocumentationId); fieldname = TranslationHelper.TurnStringIntoValidIdentifier(fieldname); Bpl.IToken tok = field.Token(); Bpl.Type t = this.sink.CciTypeToBoogie(field.Type.ResolvedType); if (field.ResolvedField.IsStatic) { Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t); v = new Bpl.GlobalVariable(tok, tident); } else { Bpl.Type mt = new Bpl.MapType(tok, new List <Bpl.TypeVariable>(), new List <Bpl.Type>(new Bpl.Type[] { this.RefType }), t); Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, mt); v = new Bpl.GlobalVariable(tok, tident); } return(v); }
public override Bpl.Variable CreateEventVariable(IEventDefinition e) { Bpl.Variable v; string fieldname = MemberHelper.GetMemberSignature(e, NameFormattingOptions.DocumentationId); fieldname = TranslationHelper.TurnStringIntoValidIdentifier(fieldname); Bpl.IToken tok = e.Token(); if (e.Adder.ResolvedMethod.IsStatic) { Bpl.Type t = this.sink.CciTypeToBoogie(e.Type.ResolvedType); Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t); v = new Bpl.GlobalVariable(tok, tident); } else { Bpl.Type t = this.FieldType; Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t); v = new Bpl.Constant(tok, tident, true); } return(v); }
private Variable MakeVar(VCExprVar v){ var foo = new TypedIdent(Token.NoToken,v.Name.ToString(),v.Type); return new BoundVariable(Token.NoToken,foo); }
public Constant(IToken/*!*/ tok, TypedIdent/*!*/ typedIdent, bool unique) : base(tok, typedIdent) { Contract.Requires(tok != null); Contract.Requires(typedIdent != null); Contract.Requires(typedIdent.Name != null && typedIdent.Name.Length > 0); Contract.Requires(typedIdent.WhereExpr == null); this.Unique = unique; this.Parents = null; this.ChildrenComplete = false; }
public override TypedIdent VisitTypedIdent(TypedIdent node) { Contract.Ensures(Contract.Result<TypedIdent>() == node); this.Visit(node.Type); return node; }
void Function(out List<Declaration>/*!*/ ds) { Contract.Ensures(Contract.ValueAtReturn(out ds) != null); ds = new List<Declaration>(); IToken/*!*/ z; IToken/*!*/ typeParamTok; var typeParams = new List<TypeVariable>(); var arguments = new List<Variable>(); TypedIdent/*!*/ tyd; TypedIdent retTyd = null; Bpl.Type/*!*/ retTy; QKeyValue argKv = null; QKeyValue kv = null; Expr definition = null; Expr/*!*/ tmp; Expect(26); while (la.kind == 28) { Attribute(ref kv); } Ident(out z); if (la.kind == 20) { TypeParams(out typeParamTok, out typeParams); } Expect(10); if (StartOf(2)) { VarOrType(out tyd, out argKv); arguments.Add(new Formal(tyd.tok, tyd, true, argKv)); while (la.kind == 13) { Get(); VarOrType(out tyd, out argKv); arguments.Add(new Formal(tyd.tok, tyd, true, argKv)); } } Expect(11); argKv = null; if (la.kind == 27) { Get(); Expect(10); VarOrType(out retTyd, out argKv); Expect(11); } else if (la.kind == 12) { Get(); Type(out retTy); retTyd = new TypedIdent(retTy.tok, TypedIdent.NoName, retTy); } else SynErr(98); if (la.kind == 28) { Get(); Expression(out tmp); definition = tmp; Expect(29); } else if (la.kind == 9) { Get(); } else SynErr(99); if (retTyd == null) { // construct a dummy type for the case of syntax error retTyd = new TypedIdent(t, TypedIdent.NoName, new BasicType(t, SimpleType.Int)); } Function/*!*/ func = new Function(z, z.val, typeParams, arguments, new Formal(retTyd.tok, retTyd, false, argKv), null, kv); Contract.Assert(func != null); ds.Add(func); bool allUnnamed = true; foreach(Formal/*!*/ f in arguments){ Contract.Assert(f != null); if (f.TypedIdent.HasName) { allUnnamed = false; break; } } if (!allUnnamed) { Bpl.Type prevType = null; for (int i = arguments.Count; 0 <= --i; ) { TypedIdent/*!*/ curr = cce.NonNull(arguments[i]).TypedIdent; if (curr.HasName) { // the argument was given as both an identifier and a type prevType = curr.Type; } else { // the argument was given as just one "thing", which syntactically parsed as a type if (prevType == null) { this.errors.SemErr(curr.tok, "the type of the last parameter is unspecified"); break; } Bpl.Type ty = curr.Type; var uti = ty as UnresolvedTypeIdentifier; if (uti != null && uti.Arguments.Count == 0) { // the given "thing" was just an identifier, so let's use it as the name of the parameter curr.Name = uti.Name; curr.Type = prevType; } else { this.errors.SemErr(curr.tok, "expecting an identifier as parameter name"); } } } } if (definition != null) { // generate either an axiom or a function body if (QKeyValue.FindBoolAttribute(kv, "inline")) { func.Body = definition; } else { ds.Add(func.CreateDefinitionAxiom(definition, kv)); } } }
public void GenerateVCsForStratifiedInlining() { Contract.Requires(program != null); foreach (Declaration decl in program.TopLevelDeclarations) { Contract.Assert(decl != null); Implementation impl = decl as Implementation; if (impl == null) continue; Contract.Assert(!impl.Name.StartsWith(recordProcName), "Not allowed to have an implementation for this guy"); Procedure proc = cce.NonNull(impl.Proc); { StratifiedInliningInfo info = new StratifiedInliningInfo(impl, program, boogieContext, QuantifierExpr.GetNextSkolemId()); implName2StratifiedInliningInfo[impl.Name] = info; // We don't need controlFlowVariable for stratified Inlining //impl.LocVars.Add(info.controlFlowVariable); List<Expr> exprs = new List<Expr>(); if (mode != Mode.Boogie && QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint")) { proc.Ensures.Add(new Ensures(Token.NoToken, true, Microsoft.Boogie.Expr.False, "", null)); info.assertExpr = Microsoft.Boogie.Expr.False; // info.isMain = true; } else if (mode == Mode.Corral || proc.FindExprAttribute("inline") != null || proc is LoopProcedure) { foreach (Variable v in program.GlobalVariables()) { Contract.Assert(v != null); exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); } foreach (Variable v in proc.InParams) { Contract.Assert(v != null); exprs.Add(new IdentifierExpr(Token.NoToken, v)); } foreach (Variable v in proc.OutParams) { Contract.Assert(v != null); exprs.Add(new IdentifierExpr(Token.NoToken, v)); } foreach (IdentifierExpr ie in proc.Modifies) { Contract.Assert(ie != null); if (ie.Decl == null) continue; exprs.Add(ie); } Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(info.function), exprs); #if true if(mode == Mode.Corral || mode == Mode.OldCorral) proc.Ensures.Add(new Ensures(Token.NoToken, true, freePostExpr, "", new QKeyValue(Token.NoToken, "si_fcall", new List<object>(), null))); #endif } else // not marked "inline" must be main { Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(info.function), exprs); info.isMain = true; } } } if (mode == Mode.Boogie) return; foreach (var decl in program.TopLevelDeclarations) { var proc = decl as Procedure; if (proc == null) continue; if (!proc.Name.StartsWith(recordProcName)) continue; Contract.Assert(proc.InParams.Count == 1); // Make a new function TypedIdent ti = new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool); Contract.Assert(ti != null); Formal returnVar = new Formal(Token.NoToken, ti, false); Contract.Assert(returnVar != null); // Get record type var argtype = proc.InParams[0].TypedIdent.Type; var ins = new List<Variable>(); ins.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "x", argtype), true)); var recordFunc = new Function(Token.NoToken, proc.Name, ins, returnVar); boogieContext.DeclareFunction(recordFunc, ""); var exprs = new List<Expr>(); exprs.Add(new IdentifierExpr(Token.NoToken, proc.InParams[0])); Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(recordFunc), exprs); proc.Ensures.Add(new Ensures(true, freePostExpr)); } }
public LazyInliningInfo(Implementation impl, Program program, ProverContext ctxt, int uniqueId, GlobalVariable errorVariable) { Contract.Requires(impl != null); Contract.Requires(program != null); Procedure proc = cce.NonNull(impl.Proc); this.impl = impl; this.uniqueId = uniqueId; this.controlFlowVariable = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "cfc", Microsoft.Boogie.Type.Int)); impl.LocVars.Add(controlFlowVariable); List<Variable> interfaceVars = new List<Variable>(); Expr assertExpr = new LiteralExpr(Token.NoToken, true); Contract.Assert(assertExpr != null); foreach (Variable v in program.GlobalVariables()) { Contract.Assert(v != null); interfaceVars.Add(v); if (v.Name == "error") inputErrorVariable = v; } // InParams must be obtained from impl and not proc foreach (Variable v in impl.InParams) { Contract.Assert(v != null); interfaceVars.Add(v); } // OutParams must be obtained from impl and not proc foreach (Variable v in impl.OutParams) { Contract.Assert(v != null); Constant c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type)); interfaceVars.Add(c); Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v)); assertExpr = Expr.And(assertExpr, eqExpr); } if (errorVariable != null) { proc.Modifies.Add(new IdentifierExpr(Token.NoToken, errorVariable)); } foreach (IdentifierExpr e in proc.Modifies) { Contract.Assert(e != null); if (e.Decl == null) continue; Variable v = e.Decl; Constant c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type)); interfaceVars.Add(c); if (v.Name == "error") { outputErrorVariable = c; continue; } Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v)); assertExpr = Expr.And(assertExpr, eqExpr); } this.interfaceVars = interfaceVars; this.assertExpr = Expr.Not(assertExpr); List<Variable> functionInterfaceVars = new List<Variable>(); foreach (Variable v in interfaceVars) { Contract.Assert(v != null); functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, v.Name, v.TypedIdent.Type), true)); } TypedIdent ti = new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool); Contract.Assert(ti != null); Formal returnVar = new Formal(Token.NoToken, ti, false); Contract.Assert(returnVar != null); this.function = new Function(Token.NoToken, proc.Name, functionInterfaceVars, returnVar); ctxt.DeclareFunction(this.function, ""); interfaceVarCopies = new List<List<Variable>>(); int temp = 0; for (int i = 0; i < /* CommandLineOptions.Clo.ProcedureCopyBound */ 0; i++) { interfaceVarCopies.Add(new List<Variable>()); foreach (Variable v in interfaceVars) { Constant constant = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, v.Name + temp++, v.TypedIdent.Type)); interfaceVarCopies[i].Add(constant); //program.TopLevelDeclarations.Add(constant); } } }
public override Bpl.Variable CreateEventVariable(IEventDefinition e) { Bpl.Variable v; string fieldName = MemberHelper.GetMemberSignature(e, NameFormattingOptions.DocumentationId); // HACK fieldName = fieldName.Replace("E:", "F:"); fieldName = TranslationHelper.TurnStringIntoValidIdentifier(fieldName); Bpl.IToken tok = e.Token(); Bpl.Type t = this.sink.CciTypeToBoogie(e.Type.ResolvedType); if (e.Adder.ResolvedMethod.IsStatic) { Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldName, t); v = new Bpl.GlobalVariable(tok, tident); } else { Bpl.Type mt = new Bpl.MapType(tok, new List<Bpl.TypeVariable>(), new List<Bpl.Type>(new Bpl.Type[] {this.RefType}), t); Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldName, mt); v = new Bpl.GlobalVariable(tok, tident); } return v; }
public LocalVariable(IToken tok, TypedIdent typedIdent) : base(tok, typedIdent, null) { Contract.Requires(typedIdent != null); Contract.Requires(tok != null); }
public LocalVariable(IToken tok, TypedIdent typedIdent, QKeyValue kv) : base(tok, typedIdent, kv) { Contract.Requires(typedIdent != null); Contract.Requires(tok != null); }
public Formal(IToken tok, TypedIdent typedIdent, bool incoming) : this(tok, typedIdent, incoming, null) { Contract.Requires(typedIdent != null); Contract.Requires(tok != null); }
public Formal(IToken tok, TypedIdent typedIdent, bool incoming, QKeyValue kv) : base(tok, typedIdent, kv) { Contract.Requires(typedIdent != null); Contract.Requires(tok != null); InComing = incoming; }
public GlobalVariable(IToken/*!*/ tok, TypedIdent/*!*/ typedIdent, QKeyValue kv) : base(tok, typedIdent, kv) { Contract.Requires(tok != null); Contract.Requires(typedIdent != null); }
public Constant(IToken/*!*/ tok, TypedIdent/*!*/ typedIdent, bool unique, List<ConstantParent/*!*/> parents, bool childrenComplete, QKeyValue kv) : base(tok, typedIdent, kv) { Contract.Requires(tok != null); Contract.Requires(typedIdent != null); Contract.Requires(parents == null || cce.NonNullElements(parents)); Contract.Requires(typedIdent.Name != null && typedIdent.Name.Length > 0); Contract.Requires(typedIdent.WhereExpr == null); this.Unique = unique; this.Parents = parents; this.ChildrenComplete = childrenComplete; }
public override Bpl.Variable CreateEventVariable(IEventDefinition e) { Bpl.Variable v; string fieldname = MemberHelper.GetMemberSignature(e, NameFormattingOptions.DocumentationId); fieldname = TranslationHelper.TurnStringIntoValidIdentifier(fieldname); Bpl.IToken tok = e.Token(); if (e.Adder.ResolvedMethod.IsStatic) { Bpl.Type t = this.sink.CciTypeToBoogie(e.Type.ResolvedType); Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t); v = new Bpl.GlobalVariable(tok, tident); } else { Bpl.Type t = this.FieldType; Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t); v = new Bpl.Constant(tok, tident, true); } return v; }
public override Expr VisitLambdaExpr(LambdaExpr lambda) { var baseResult = base.VisitLambdaExpr(lambda); lambda = baseResult as LambdaExpr; if (lambda == null) { return baseResult; // apparently, the base visitor already turned the lambda into something else } // 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.SubstitutionFromHashtable(new Dictionary<Variable,Expr>()), Substituter.SubstitutionFromHashtable(oldSubst), lambda.Body); var lambdaAttrs = Substituter.ApplyReplacingOldExprs( Substituter.SubstitutionFromHashtable(new Dictionary<Variable, Expr>()), Substituter.SubstitutionFromHashtable(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, 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.SubstitutionFromHashtable(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.SubstitutionFromHashtable(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.SubstitutionFromHashtable(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 BoundVariable(IToken tok, TypedIdent typedIdent, QKeyValue kv) : base(tok, typedIdent, kv) { Contract.Requires(typedIdent != null); Contract.Requires(tok != null); Contract.Requires(typedIdent.WhereExpr == null); }
/// <summary> /// Creates a fresh BPL variable to represent <paramref name="type"/>, deciding /// on its type based on the heap representation. I.e., the value of this /// variable represents the value of the expression "typeof(type)". /// </summary> public Bpl.Variable CreateTypeVariable(ITypeReference type, List<Bpl.ConstantParent> parents) { string typename = TypeHelper.GetTypeName(type, NameFormattingOptions.DocumentationId); typename = TranslationHelper.TurnStringIntoValidIdentifier(typename); Bpl.IToken tok = type.Token(); Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, typename, this.TypeType); Bpl.Constant v = new Bpl.Constant(tok, tident, true /*unique*/, parents, false, null); return v; }
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); }
public void AnnotateProcEnsures(Procedure proc, Implementation impl, ProverContext ctxt) { Contract.Requires(impl != null); CurrentLocalVariables = impl.LocVars; // collect the variables needed in the invariant List<Expr> exprs = new List<Expr>(); List<Variable> vars = new List<Variable>(); List<string> names = new List<string>(); foreach (Variable v in program.GlobalVariables()) { vars.Add(v); exprs.Add(new OldExpr(Token.NoToken,new IdentifierExpr(Token.NoToken, v))); names.Add(v.Name); } foreach (IdentifierExpr ie in proc.Modifies) { if (ie.Decl == null) continue; vars.Add(ie.Decl); exprs.Add(ie); names.Add(ie.Decl.Name + "_out"); } foreach (Variable v in proc.InParams) { Contract.Assert(v != null); vars.Add(v); exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); names.Add(v.Name); } foreach (Variable v in proc.OutParams) { Contract.Assert(v != null); vars.Add(v); exprs.Add(new IdentifierExpr(Token.NoToken, v)); names.Add(v.Name); } string name = impl.Name + "_summary"; summaries.Add(name, true); TypedIdent ti = new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool); Contract.Assert(ti != null); Formal returnVar = new Formal(Token.NoToken, ti, false); Contract.Assert(returnVar != null); var function = new Function(Token.NoToken, name, vars, returnVar); ctxt.DeclareFunction(function, ""); Expr invarExpr = new NAryExpr(Token.NoToken, new FunctionCall(function), exprs); proc.Ensures.Add(new Ensures(Token.NoToken, false, invarExpr, "", null)); var info = new AnnotationInfo(); info.filename = proc.tok.filename; info.lineno = proc.Line; info.argnames = names.ToArray(); info.type = AnnotationInfo.AnnotationType.ProcedureSummary; annotationInfo.Add(name, info); }
public Bpl.Variable FindOrCreateFieldVariable(IFieldDefinition field) { Bpl.GlobalVariable v; if (!fieldVarMap.TryGetValue(field, out v)) { string fieldname = field.ContainingTypeDefinition.ToString() + "." + field.Name.Value; Bpl.IToken tok = field.Token(); Bpl.Type t = TranslationHelper.CciTypeToBoogie(field.Type.ResolvedType); Bpl.TypedIdent tident = new Bpl.TypedIdent(tok, fieldname, t); v = new Bpl.GlobalVariable(tok, tident); fieldVarMap.Add(field, v); this.TranslatedProgram.TopLevelDeclarations.Add(new Bpl.Constant(tok, tident, true)); } return v; }
private void AnnotateBlock(Implementation impl, ProverContext ctxt, Block header) { Contract.Assert(header != null); string name = impl.Name + "_" + header.Label + "_invar"; if (annotationInfo.ContainsKey(name)) return; // collect the variables needed in the invariant List<Expr> exprs = new List<Expr>(); List<Variable> vars = new List<Variable>(); List<string> names = new List<string>(); if (style == AnnotationStyle.Flat) { // in flat mode, all live globals should be in live set #if false foreach (Variable v in program.GlobalVariables()) { vars.Add(v); names.Add(v.ToString()); exprs.Add(new IdentifierExpr(Token.NoToken, v)); } #endif foreach (Variable v in /* impl.LocVars */ header.liveVarsBefore) { if (!(v is BoundVariable)) { vars.Add(v); names.Add(v.ToString()); exprs.Add(new IdentifierExpr(Token.NoToken, v)); } } } else { foreach (Variable v in program.GlobalVariables()) { vars.Add(v); names.Add("@old_" + v.ToString()); exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); } foreach (IdentifierExpr ie in impl.Proc.Modifies) { if (ie.Decl == null) continue; vars.Add(ie.Decl); names.Add(ie.Decl.ToString()); exprs.Add(ie); } foreach (Variable v in impl.Proc.InParams) { Contract.Assert(v != null); vars.Add(v); names.Add("@old_" + v.ToString()); exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); } foreach (Variable v in impl.LocVars) { vars.Add(v); names.Add(v.ToString()); exprs.Add(new IdentifierExpr(Token.NoToken, v)); } } TypedIdent ti = new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool); Contract.Assert(ti != null); Formal returnVar = new Formal(Token.NoToken, ti, false); Contract.Assert(returnVar != null); var function = new Function(Token.NoToken, name, vars, returnVar); ctxt.DeclareFunction(function, ""); Expr invarExpr = new NAryExpr(Token.NoToken, new FunctionCall(function), exprs); var invarAssertion = new AssertCmd(Token.NoToken, invarExpr); List<Cmd> newCmds = new List<Cmd>(); newCmds.Add(invarAssertion); // make a record in annotationInfo; var info = new AnnotationInfo(); info.filename = header.tok.filename; info.lineno = header.Line; info.argnames = names.ToArray(); info.type = AnnotationInfo.AnnotationType.LoopInvariant; annotationInfo.Add(name, info); // get file and line info from havoc, if there is... if (header.Cmds.Count > 0) { PredicateCmd bif = header.Cmds[0] as PredicateCmd; if (bif != null) { string foo = QKeyValue.FindStringAttribute(bif.Attributes, "sourcefile"); if (foo != null) info.filename = foo; int bar = QKeyValue.FindIntAttribute(bif.Attributes, "sourceline", -1); if (bar != -1) info.lineno = bar; } } var thing = header; foreach (Cmd c in header.Cmds) { newCmds.Add(c); } header.Cmds = newCmds; }
public Variable(IToken/*!*/ tok, TypedIdent/*!*/ typedIdent) : base(tok, typedIdent.Name) { Contract.Requires(tok != null); Contract.Requires(typedIdent != null); this.TypedIdent = typedIdent; }
void VarOrType(out TypedIdent/*!*/ tyd, out QKeyValue kv) { Contract.Ensures(Contract.ValueAtReturn(out tyd) != null); string/*!*/ varName = TypedIdent.NoName; Bpl.Type/*!*/ ty; IToken/*!*/ tok; kv = null; while (la.kind == 28) { Attribute(ref kv); } Type(out ty); tok = ty.tok; if (la.kind == 12) { Get(); var uti = ty as UnresolvedTypeIdentifier; if (uti != null && uti.Arguments.Count == 0) { varName = uti.Name; } else { this.SemErr("expected identifier before ':'"); } Type(out ty); } tyd = new TypedIdent(tok, varName, ty); }
// We have to give the type explicitly, because the type of the formal "likeThisOne" can contain type variables protected Variable CreateTemporaryVariable(List<Variable> tempVars, Variable likeThisOne, Type ty, TempVarKind kind) { Contract.Requires(ty != null); Contract.Requires(likeThisOne != null); Contract.Requires(tempVars != null); Contract.Ensures(Contract.Result<Variable>() != null); string/*!*/ tempNamePrefix; switch (kind) { case TempVarKind.Formal: tempNamePrefix = "formal@"; break; case TempVarKind.Old: tempNamePrefix = "old@"; break; case TempVarKind.Bound: tempNamePrefix = "forall@"; break; default: { Contract.Assert(false); throw new cce.UnreachableException(); } // unexpected kind } TypedIdent ti = likeThisOne.TypedIdent; TypedIdent newTi = new TypedIdent(ti.tok, "call" + UniqueId + tempNamePrefix + ti.Name, ty); Variable/*!*/ v; if (kind == TempVarKind.Bound) { v = new BoundVariable(likeThisOne.tok, newTi); } else { v = new LocalVariable(likeThisOne.tok, newTi); tempVars.Add(v); } return v; }
public virtual TypedIdent VisitTypedIdent(TypedIdent node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result<TypedIdent>() != null); node.Type = (Type)this.Visit(node.Type); return node; }
public Variable(IToken/*!*/ tok, TypedIdent/*!*/ typedIdent, QKeyValue kv) : base(tok, typedIdent.Name) { Contract.Requires(tok != null); Contract.Requires(typedIdent != null); this.TypedIdent = typedIdent; this.Attributes = kv; }
public override TypedIdent VisitTypedIdent(TypedIdent node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<TypedIdent>() != null); return base.VisitTypedIdent((TypedIdent)node.Clone()); }
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; }