public bool isNonTemplate(bpl.Procedure proc) { if (proc == null) { return(false); } return(!hasAttrKey(proc.Attributes, templateAttr)); }
public ActionInfo(Procedure proc, int createdAtLayerNum, int availableUptoLayerNum) { this.proc = proc; this.createdAtLayerNum = createdAtLayerNum; this.availableUptoLayerNum = availableUptoLayerNum; this.hasImplementation = false; this.isExtern = QKeyValue.FindBoolAttribute(proc.Attributes, "extern"); }
public bool isThreadEntry(bpl.Procedure proc) { if (proc == null) { return(false); } return(hasAttrKey(proc.Attributes, threadEntryAttr)); }
public ActionInfo(Procedure proc, int createdAtLayerNum, int availableUptoLayerNum) { this.proc = proc; this.createdAtLayerNum = createdAtLayerNum; this.availableUptoLayerNum = availableUptoLayerNum; this.hasImplementation = false; this.isExtern = proc.IsExtern(); }
public MyDuplicator(MoverTypeChecker moverTypeChecker, int layerNum) { this.moverTypeChecker = moverTypeChecker; this.layerNum = layerNum; this.enclosingProc = null; this.enclosingImpl = null; this.procMap = new Dictionary<Procedure, Procedure>(); this.absyMap = new Dictionary<Absy, Absy>(); this.implMap = new Dictionary<Implementation, Implementation>(); this.yieldingProcs = new HashSet<Procedure>(); this.impls = new List<Implementation>(); }
private static void CreateDelegateRemoveMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates) { Bpl.Formal a = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "a", sink.Heap.RefType), true); Bpl.Formal b = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "b", sink.Heap.RefType), true); Bpl.Formal c = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false); Bpl.IdentifierExpr aExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, a); Bpl.IdentifierExpr bExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, b); Bpl.IdentifierExpr cExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, c); Bpl.Procedure proc = new Bpl.Procedure( Bpl.Token.NoToken, sink.DelegateRemove(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { a, b }), new List <Bpl.Variable>(new Bpl.Variable[] { c }), new List <Bpl.Requires>(), new List <Bpl.IdentifierExpr>(), new List <Bpl.Ensures>()); proc.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(proc); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { cExpr }))); foreach (IMethodDefinition defn in delegates) { Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn)); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, cExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, sink.ReadMethod(cie, aExpr), Bpl.Expr.Unary(Bpl.Token.NoToken, Bpl.UnaryOperator.Opcode.Not, sink.ReadMethod(cie, bExpr)))))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(cie, cExpr), sink.ReadReceiver(cie, aExpr)))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(cie, cExpr), sink.ReadTypeParameters(cie, aExpr)))); } Bpl.IdentifierExpr nullExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.Heap.NullRef); Bpl.IfCmd ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, bExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, aExpr), stmtBuilder.Collect(Bpl.Token.NoToken)); ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, aExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, nullExpr), ifCmd); Bpl.Implementation impl = new Bpl.Implementation( Bpl.Token.NoToken, sink.DelegateRemove(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { a, b }), new List <Bpl.Variable>(new Bpl.Variable[] { c }), new List <Bpl.Variable>(), BuildStmtList(ifCmd) ); impl.AddAttribute("inline", Bpl.Expr.Literal(1)); impl.Proc = proc; sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
private static void CreateDelegateCreateMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates) { Bpl.Formal method = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Method", Bpl.Type.Int), true); Bpl.Formal receiver = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Receiver", sink.Heap.RefType), true); Bpl.Formal typeParameters = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "TypeParameters", sink.Heap.TypeType), true); Bpl.Formal returnDelegate = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false); Bpl.IdentifierExpr methodExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, method); Bpl.IdentifierExpr receiverExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, receiver); Bpl.IdentifierExpr typeParametersExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, typeParameters); Bpl.IdentifierExpr returnDelegateExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, returnDelegate); Bpl.Procedure proc = new Bpl.Procedure( Bpl.Token.NoToken, sink.DelegateCreate(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }), new List <Bpl.Variable>(new Bpl.Variable[] { returnDelegate }), new List <Bpl.Requires>(), new List <Bpl.IdentifierExpr>(), new List <Bpl.Ensures>()); proc.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(proc); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { returnDelegateExpr }))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(methodExpr, returnDelegateExpr), receiverExpr))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(methodExpr, returnDelegateExpr), typeParametersExpr))); foreach (IMethodDefinition defn in delegates) { Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn)); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, returnDelegateExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, methodExpr, cie)))); } Bpl.Implementation impl = new Bpl.Implementation( Bpl.Token.NoToken, sink.DelegateCreate(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }), new List <Bpl.Variable>(new Bpl.Variable[] { returnDelegate }), new List <Bpl.Variable>(), stmtBuilder.Collect(Bpl.Token.NoToken)); impl.AddAttribute("inline", Bpl.Expr.Literal(1)); impl.Proc = proc; sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
public CivlRefinement(LinearTypeChecker linearTypeChecker, CivlTypeChecker civlTypeChecker, MyDuplicator duplicator) { this.linearTypeChecker = linearTypeChecker; this.civlTypeChecker = civlTypeChecker; this.absyMap = duplicator.absyMap; this.layerNum = duplicator.layerNum; this.implMap = duplicator.implMap; this.yieldingProcs = duplicator.yieldingProcs; Program program = linearTypeChecker.program; globalMods = new List<IdentifierExpr>(); foreach (Variable g in civlTypeChecker.SharedVariables) { globalMods.Add(Expr.Ident(g)); } asyncAndParallelCallDesugarings = new Dictionary<string, Procedure>(); yieldCheckerProcs = new List<Procedure>(); yieldCheckerImpls = new List<Implementation>(); yieldProc = null; }
private void addMethodCalling(Bpl.Procedure proc, Bpl.Program program, Sink sink) { Bpl.Procedure callingProc = new Bpl.Procedure(Bpl.Token.NoToken, "__BOOGIE_CALL_" + proc.Name, new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(), new List <Bpl.Variable>(), new List <Bpl.Requires>(), new List <Bpl.IdentifierExpr>(), new List <Bpl.Ensures>()); sink.TranslatedProgram.AddTopLevelDeclaration(callingProc); Bpl.StmtListBuilder codeBuilder = new Bpl.StmtListBuilder(); List <Bpl.Variable> localVars = new List <Bpl.Variable>(proc.InParams); List <Bpl.IdentifierExpr> identVars = new List <Bpl.IdentifierExpr>(); for (int i = 0; i < localVars.Count; i++) { identVars.Add(new Bpl.IdentifierExpr(Bpl.Token.NoToken, localVars[i])); } codeBuilder.Add(new Bpl.HavocCmd(Bpl.Token.NoToken, identVars)); // FEEDBACK TODO this is possibly too much, I'm guessing sometimes this args might well be null Bpl.Expr notNullExpr; foreach (Bpl.IdentifierExpr idExpr in identVars) { if (idExpr.Type.Equals(sink.Heap.RefType)) { notNullExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, idExpr, Bpl.Expr.Ident(sink.Heap.NullRef)); codeBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, notNullExpr)); } } List <Bpl.Expr> callParams = new List <Bpl.Expr>(); for (int i = 0; i < identVars.Count; i++) { callParams.Add(identVars[i]); } Bpl.CallCmd callCmd = new Bpl.CallCmd(Bpl.Token.NoToken, proc.Name, callParams, new List <Bpl.IdentifierExpr>()); codeBuilder.Add(callCmd); Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, callingProc.Name, new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(), new List <Bpl.Variable>(), localVars, codeBuilder.Collect(Bpl.Token.NoToken)); sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
private void CreateStaticConstructor(ITypeDefinition typeDefinition) { var typename = TypeHelper.GetTypeName(typeDefinition, Microsoft.Cci.NameFormattingOptions.DocumentationId); typename = TranslationHelper.TurnStringIntoValidIdentifier(typename); var proc = new Bpl.Procedure(Bpl.Token.NoToken, typename + ".#cctor", new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(), // in new List <Bpl.Variable>(), // out new List <Bpl.Requires>(), new List <Bpl.IdentifierExpr>(), // modifies new List <Bpl.Ensures>() ); this.sink.TranslatedProgram.AddTopLevelDeclaration(proc); this.sink.BeginMethod(typeDefinition); var stmtTranslator = this.Factory.MakeStatementTraverser(this.sink, this.PdbReader, false); var stmts = new List <IStatement>(); foreach (var f in typeDefinition.Fields) { if (!f.IsStatic) { continue; } stmts.Add( new ExpressionStatement() { Expression = new Assignment() { Source = new DefaultValue() { DefaultValueType = f.Type, Type = f.Type, }, Target = new TargetExpression() { Definition = f, Instance = null, Type = f.Type, }, Type = f.Type, } }); } stmtTranslator.Traverse(stmts); var translatedStatements = stmtTranslator.StmtBuilder.Collect(Bpl.Token.NoToken); List <Bpl.Variable> vars = new List <Bpl.Variable>(); foreach (Bpl.Variable v in this.sink.LocalVarMap.Values) { vars.Add(v); } List <Bpl.Variable> vseq = new List <Bpl.Variable>(vars.ToArray()); Bpl.Implementation impl = new Bpl.Implementation(Bpl.Token.NoToken, proc.Name, new List <Bpl.TypeVariable>(), proc.InParams, proc.OutParams, vseq, translatedStatements ); impl.Proc = proc; this.sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
public override Procedure VisitProcedure(Procedure node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Procedure>() != null); Procedure newProcedure = null; if (OldToNewProcedureMap != null && OldToNewProcedureMap.ContainsKey(node)) { newProcedure = OldToNewProcedureMap[node]; } else { newProcedure = base.VisitProcedure((Procedure) node.Clone()); if (OldToNewProcedureMap != null) OldToNewProcedureMap[node] = newProcedure; } return newProcedure; }
static string UniqueName(Variable variable, Procedure proc) { // TODO(wuestholz): Maybe we should define structural equality for variables instead. var scope = "#global_scope#"; if (proc != null && !(variable is GlobalVariable || variable is Constant)) { scope = proc.Name; } return string.Format("{0}.{1}", scope, variable.Name); }
public override Procedure VisitProcedure(Procedure node) { if (!civlTypeChecker.procToActionInfo.ContainsKey(node)) return node; if (!procMap.ContainsKey(node)) { enclosingProc = node; Procedure proc = (Procedure)node.Clone(); proc.Name = string.Format("{0}_{1}", node.Name, layerNum); proc.InParams = this.VisitVariableSeq(node.InParams); proc.Modifies = this.VisitIdentifierExprSeq(node.Modifies); proc.OutParams = this.VisitVariableSeq(node.OutParams); ActionInfo actionInfo = civlTypeChecker.procToActionInfo[node]; if (actionInfo.createdAtLayerNum < layerNum) { proc.Requires = new List<Requires>(); proc.Ensures = new List<Ensures>(); Implementation impl; AtomicActionInfo atomicActionInfo = actionInfo as AtomicActionInfo; if (atomicActionInfo != null) { CodeExpr action = (CodeExpr)VisitCodeExpr(atomicActionInfo.action); List<Cmd> cmds = new List<Cmd>(); foreach (AssertCmd assertCmd in atomicActionInfo.gate) { cmds.Add(new AssumeCmd(Token.NoToken, (Expr)Visit(assertCmd.Expr))); } Block newInitBlock = new Block(Token.NoToken, "_init", cmds, new GotoCmd(Token.NoToken, new List<string>(new string[] { action.Blocks[0].Label }), new List<Block>(new Block[] { action.Blocks[0] }))); List<Block> newBlocks = new List<Block>(); newBlocks.Add(newInitBlock); newBlocks.AddRange(action.Blocks); impl = new Implementation(Token.NoToken, proc.Name, node.TypeParameters, node.InParams, node.OutParams, action.LocVars, newBlocks); } else { Block newInitBlock = new Block(Token.NoToken, "_init", new List<Cmd>(), new ReturnCmd(Token.NoToken)); List<Block> newBlocks = new List<Block>(); newBlocks.Add(newInitBlock); impl = new Implementation(Token.NoToken, proc.Name, node.TypeParameters, node.InParams, node.OutParams, new List<Variable>(), newBlocks); } impl.Proc = proc; impl.Proc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); impl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); impls.Add(impl); } else { yieldingProcs.Add(proc); proc.Requires = this.VisitRequiresSeq(node.Requires); proc.Ensures = this.VisitEnsuresSeq(node.Ensures); } procMap[node] = proc; proc.Modifies = new List<IdentifierExpr>(); civlTypeChecker.SharedVariables.Iter(x => proc.Modifies.Add(Expr.Ident(x))); } return procMap[node]; }
public string readThreadName(bpl.Procedure proc) { return(getAttrParams(proc.Attributes, threadAttr)[0] as string); }
public override Procedure VisitProcedure(Procedure node) { Contract.Ensures(Contract.Result<Procedure>() == node); this.VisitEnsuresSeq(node.Ensures); this.VisitVariableSeq(node.InParams); this.VisitIdentifierExprSeq(node.Modifies); this.VisitVariableSeq(node.OutParams); this.VisitRequiresSeq(node.Requires); return node; }
public override Procedure VisitProcedure(Procedure node) { currentDeclaration = node; foreach (var param in node.InParams) { if (param.TypedIdent != null && param.TypedIdent.WhereExpr != null) { VisitExpr(param.TypedIdent.WhereExpr); } } var result = base.VisitProcedure(node); node.DependenciesCollected = true; currentDeclaration = null; return result; }
public override Implementation VisitImplementation(Implementation node) { if (!procToActionInfo.ContainsKey(node.Proc)) { return node; } this.enclosingImpl = node; this.enclosingProc = null; return base.VisitImplementation(node); }
public override Procedure VisitProcedure(Procedure node) { dependencies.Add(node); foreach (var param in node.InParams) { if (param.TypedIdent != null && param.TypedIdent.WhereExpr != null) { param.TypedIdent.WhereExpr = VisitExpr(param.TypedIdent.WhereExpr); } } return base.VisitProcedure(node); }
protected static Implementation FindProcImpl(Program program, Procedure proc) { Contract.Requires(program != null); foreach (Declaration decl in program.TopLevelDeclarations) { Implementation impl = decl as Implementation; if (impl != null && impl.Proc == proc) { return impl; } } return null; }
private void CreateNonBlockingChecker(Program program, AtomicActionInfo second) { List<Variable> inputs = new List<Variable>(); inputs.AddRange(second.thisInParams); HashSet<Variable> frame = new HashSet<Variable>(); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List<Requires> requires = new List<Requires>(); requires.Add(DisjointnessRequires(program, second.thisInParams, frame)); foreach (AssertCmd assertCmd in second.thisGate) { requires.Add(new Requires(false, assertCmd.Expr)); } HashSet<Variable> postExistVars = new HashSet<Variable>(); postExistVars.UnionWith(frame); postExistVars.UnionWith(second.thisOutParams); Expr ensuresExpr = (new TransitionRelationComputation(program, second, frame, postExistVars)).TransitionRelationCompute(); Ensures ensureCheck = new Ensures(false, ensuresExpr); ensureCheck.ErrorData = string.Format("{0} is blocking", second.proc.Name); List<Ensures> ensures = new List<Ensures> { ensureCheck }; List<Block> blocks = new List<Block> { new Block(Token.NoToken, "L", new List<Cmd>(), new ReturnCmd(Token.NoToken)) }; string checkerName = string.Format("NonBlockingChecker_{0}", second.proc.Name); List<IdentifierExpr> globalVars = civlTypeChecker.SharedVariables.Select(x => Expr.Ident(x)).ToList(); Procedure proc = new Procedure(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, new List<Variable>(), requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, new List<Variable>(), new List<Variable>(), blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
private void CreateFailurePreservationChecker(Program program, AtomicActionInfo first, AtomicActionInfo second) { if (first.gateUsedGlobalVars.Intersect(second.modifiedGlobalVars).Count() == 0) return; if (!failurePreservationCheckerCache.Add(new Tuple<AtomicActionInfo, AtomicActionInfo>(first, second))) return; List<Variable> inputs = Enumerable.Union(first.thatInParams, second.thisInParams).ToList(); List<Variable> outputs = Enumerable.Union(first.thatOutParams, second.thisOutParams).ToList(); List<Variable> locals = new List<Variable>(second.thisAction.LocVars); List<Block> secondBlocks = CloneBlocks(second.thisAction.Blocks); HashSet<Variable> frame = new HashSet<Variable>(); frame.UnionWith(first.gateUsedGlobalVars); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List<Requires> requires = new List<Requires>(); requires.Add(DisjointnessRequires(program, first.thatInParams.Union(second.thisInParams), frame)); Expr gateExpr = Expr.Not(Expr.And(first.thatGate.Select(a => a.Expr))); gateExpr.Type = Type.Bool; // necessary? requires.Add(new Requires(false, gateExpr)); foreach (AssertCmd assertCmd in second.thisGate) requires.Add(new Requires(false, assertCmd.Expr)); IEnumerable<Expr> linearityAssumes = DisjointnessExpr(program, first.thatInParams.Union(second.thisOutParams), frame); Ensures ensureCheck = new Ensures(false, Expr.Imp(Expr.And(linearityAssumes), gateExpr)); ensureCheck.ErrorData = string.Format("Gate failure of {0} not preserved by {1}", first.proc.Name, second.proc.Name); List<Ensures> ensures = new List<Ensures> { ensureCheck }; string checkerName = string.Format("FailurePreservationChecker_{0}_{1}", first.proc.Name, second.proc.Name); List<IdentifierExpr> globalVars = civlTypeChecker.SharedVariables.Select(x => Expr.Ident(x)).ToList(); Procedure proc = new Procedure(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, locals, secondBlocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
private void CreateCommutativityChecker(Program program, AtomicActionInfo first, AtomicActionInfo second) { if (first == second && first.thatInParams.Count == 0 && first.thatOutParams.Count == 0) return; if (first.CommutesWith(second)) return; if (!commutativityCheckerCache.Add(new Tuple<AtomicActionInfo, AtomicActionInfo>(first, second))) return; List<Variable> inputs = Enumerable.Union(first.thatInParams, second.thisInParams).ToList(); List<Variable> outputs = Enumerable.Union(first.thatOutParams, second.thisOutParams).ToList(); List<Variable> locals = Enumerable.Union(first.thatAction.LocVars, second.thisAction.LocVars).ToList(); List<Block> firstBlocks = CloneBlocks(first.thatAction.Blocks); List<Block> secondBlocks = CloneBlocks(second.thisAction.Blocks); foreach (Block b in firstBlocks.Where(b => b.TransferCmd is ReturnCmd)) { List<Block> bs = new List<Block> { secondBlocks[0] }; List<string> ls = new List<string> { secondBlocks[0].Label }; b.TransferCmd = new GotoCmd(Token.NoToken, ls, bs); } List<Block> blocks = Enumerable.Union(firstBlocks, secondBlocks).ToList(); HashSet<Variable> frame = new HashSet<Variable>(); frame.UnionWith(first.gateUsedGlobalVars); frame.UnionWith(first.actionUsedGlobalVars); frame.UnionWith(second.gateUsedGlobalVars); frame.UnionWith(second.actionUsedGlobalVars); List<Requires> requires = new List<Requires>(); requires.Add(DisjointnessRequires(program, first.thatInParams.Union(second.thisInParams), frame)); foreach (AssertCmd assertCmd in Enumerable.Union(first.thatGate, second.thisGate)) requires.Add(new Requires(false, assertCmd.Expr)); var transitionRelationComputation = new TransitionRelationComputation(program, first, second, frame, new HashSet<Variable>()); Expr transitionRelation = transitionRelationComputation.TransitionRelationCompute(); { List<Block> bs = new List<Block> { blocks[0] }; List<string> ls = new List<string> { blocks[0].Label }; var initBlock = new Block(Token.NoToken, string.Format("{0}_{1}_init", first.proc.Name, second.proc.Name), transitionRelationComputation.TriggerAssumes(), new GotoCmd(Token.NoToken, ls, bs)); blocks.Insert(0, initBlock); } IEnumerable<Expr> linearityAssumes = DisjointnessExpr(program, first.thatOutParams.Union(second.thisInParams), frame).Union(DisjointnessExpr(program, first.thatOutParams.Union(second.thisOutParams), frame)); Ensures ensureCheck = new Ensures(false, Expr.Imp(Expr.And(linearityAssumes), transitionRelation)); ensureCheck.ErrorData = string.Format("Commutativity check between {0} and {1} failed", first.proc.Name, second.proc.Name); List<Ensures> ensures = new List<Ensures> { ensureCheck }; string checkerName = string.Format("CommutativityChecker_{0}_{1}", first.proc.Name, second.proc.Name); List<IdentifierExpr> globalVars = civlTypeChecker.SharedVariables.Select(x => Expr.Ident(x)).ToList(); Procedure proc = new Procedure(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, outputs, locals, blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
private static void CreateDispatchMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates) { Contract.Assert(type.IsDelegate); IMethodDefinition invokeMethod = null; foreach (IMethodDefinition m in type.Methods) { if (m.Name.Value == "Invoke") { invokeMethod = m; break; } } try { IMethodDefinition unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod; Sink.ProcedureInfo invokeProcedureInfo = sink.FindOrCreateProcedure(unspecializedInvokeMethod); Bpl.Procedure invokeProcedure = (Bpl.Procedure)invokeProcedureInfo.Decl; invokeProcedure.AddAttribute("inline", Bpl.Expr.Literal(1)); Bpl.Formal delegateVariable = invokeProcedureInfo.ThisVariable; Bpl.IToken token = invokeMethod.Token(); List <Bpl.Variable> dispatchProcInExprs = new List <Bpl.Variable>(); for (int i = 1; i < invokeProcedure.InParams.Count; i++) { Bpl.Variable v = invokeProcedure.InParams[i]; dispatchProcInExprs.Add(v); } List <Bpl.Variable> dispatchProcOutExprs = new List <Bpl.Variable>(); foreach (Bpl.Variable v in invokeProcedure.OutParams) { dispatchProcOutExprs.Add(v); } List <Bpl.Variable> localVariables = new List <Bpl.Variable>(); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); int localCounter = 0; foreach (IMethodDefinition defn in delegates) { Bpl.Constant c = sink.FindOrCreateDelegateMethodConstant(defn); Sink.ProcedureInfo delegateProcedureInfo = sink.FindOrCreateProcedure(defn); Bpl.Procedure delegateProcedure = (Bpl.Procedure)delegateProcedureInfo.Decl; Bpl.Formal thisVariable = delegateProcedureInfo.ThisVariable; int numArguments = defn.ParameterCount; List <Bpl.Variable> tempInputs = new List <Bpl.Variable>(); List <Bpl.Variable> tempOutputs = new List <Bpl.Variable>(); for (int i = 0; i < defn.ParameterCount; i++) { Bpl.Variable v = delegateProcedure.InParams[(thisVariable == null ? 0 : 1) + i]; Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type)); localVariables.Add(localVariable); tempInputs.Add(localVariable); } for (int i = 0; i < delegateProcedure.OutParams.Count; i++) { Bpl.Variable v = delegateProcedure.OutParams[i]; Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type)); localVariables.Add(localVariable); tempOutputs.Add(localVariable); } List <Bpl.Expr> ins = new List <Bpl.Expr>(); List <Bpl.IdentifierExpr> outs = new List <Bpl.IdentifierExpr>(); if (!defn.IsStatic) { ins.Add(sink.ReadReceiver(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable))); } for (int i = 0; i < tempInputs.Count; i++) { ins.Add(Bpl.Expr.Ident(tempInputs[i])); } if (defn.IsGeneric) { for (int i = 0; i < defn.GenericParameterCount; i++) { ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)), new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) }))); } } if (defn.IsStatic) { int numTypeParameters = Sink.ConsolidatedGenericParameterCount(defn.ContainingType); for (int i = 0; i < numTypeParameters; i++) { ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)), new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) }))); } } for (int i = 0; i < tempOutputs.Count; i++) { outs.Add(Bpl.Expr.Ident(tempOutputs[i])); } Bpl.Expr bexpr = sink.ReadMethod(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)); Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder(); System.Diagnostics.Debug.Assert(tempInputs.Count == dispatchProcInExprs.Count); if (tempInputs.Count > 0) { BuildAssignment(sink, ifStmtBuilder, tempInputs, dispatchProcInExprs); } ifStmtBuilder.Add(EmitDummySourceContext()); ifStmtBuilder.Add(new Bpl.CallCmd(token, delegateProcedure.Name, ins, outs)); System.Diagnostics.Debug.Assert(tempOutputs.Count == dispatchProcOutExprs.Count); if (tempOutputs.Count > 0) { BuildAssignment(sink, ifStmtBuilder, dispatchProcOutExprs, tempOutputs); } stmtBuilder.Add(new Bpl.IfCmd(bexpr.tok, bexpr, ifStmtBuilder.Collect(bexpr.tok), null, null)); } Bpl.Implementation dispatchImpl = new Bpl.Implementation(token, invokeProcedure.Name, new List <Bpl.TypeVariable>(), invokeProcedure.InParams, invokeProcedure.OutParams, localVariables, stmtBuilder.Collect(token) ); dispatchImpl.Proc = invokeProcedure; dispatchImpl.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(dispatchImpl); } catch (TranslationException te) { throw new NotImplementedException(te.ToString()); } catch { throw; } finally { // Maybe this is a good place to add the procedure to the toplevel declarations } }
public override Procedure VisitProcedure(Procedure node) { if (!procToActionInfo.ContainsKey(node)) { return node; } this.enclosingProc = node; this.enclosingImpl = null; return base.VisitProcedure(node); }
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 virtual Procedure VisitProcedure(Procedure node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result<Procedure>() != null); node.Ensures = this.VisitEnsuresSeq(node.Ensures); node.InParams = this.VisitVariableSeq(node.InParams); node.Modifies = this.VisitIdentifierExprSeq(node.Modifies); node.OutParams = this.VisitVariableSeq(node.OutParams); node.Requires = this.VisitRequiresSeq(node.Requires); return node; }
protected static Implementation FindProcImpl(Program program, Procedure proc) { Contract.Requires(program != null); foreach (var impl in program.Implementations) { if (impl.Proc == proc) { return impl; } } return null; }
public static bool CanExpressOldSpecs(Procedure oldProc, Program newProg, bool ignoreModifiesClauses = false) { Contract.Requires(oldProc != null && newProg != null); var funcs = newProg.Functions; var globals = newProg.GlobalVariables; return oldProc.DependenciesCollected && (oldProc.FunctionDependencies == null || oldProc.FunctionDependencies.All(dep => funcs.Any(f => f.Name == dep.Name && f.DependencyChecksum == dep.DependencyChecksum))) && (ignoreModifiesClauses || oldProc.Modifies.All(m => globals.Any(g => g.Name == m.Name))); }
void Procedure(out Procedure/*!*/ proc, out /*maybe null*/ Implementation impl) { Contract.Ensures(Contract.ValueAtReturn(out proc) != null); IToken/*!*/ x; List<TypeVariable>/*!*/ typeParams; List<Variable>/*!*/ ins, outs; List<Requires>/*!*/ pre = new List<Requires>(); List<IdentifierExpr>/*!*/ mods = new List<IdentifierExpr>(); List<Ensures>/*!*/ post = new List<Ensures>(); List<Variable>/*!*/ locals = new List<Variable>(); StmtList/*!*/ stmtList; QKeyValue kv = null; impl = null; Expect(33); ProcSignature(true, out x, out typeParams, out ins, out outs, out kv); if (la.kind == 9) { Get(); while (StartOf(3)) { Spec(pre, mods, post); } } else if (StartOf(4)) { while (StartOf(3)) { Spec(pre, mods, post); } ImplBody(out locals, out stmtList); impl = new Implementation(x, x.val, typeParams, Formal.StripWhereClauses(ins), Formal.StripWhereClauses(outs), locals, stmtList, kv == null ? null : (QKeyValue)kv.Clone(), this.errors); } else SynErr(100); proc = new Procedure(x, x.val, typeParams, ins, outs, pre, mods, post, kv); }
public void DesugarParallelCallCmd(List<Cmd> newCmds, ParCallCmd parCallCmd) { List<string> parallelCalleeNames = new List<string>(); List<Expr> ins = new List<Expr>(); List<IdentifierExpr> outs = new List<IdentifierExpr>(); string procName = "og"; foreach (CallCmd callCmd in parCallCmd.CallCmds) { procName = procName + "_" + callCmd.Proc.Name; ins.AddRange(callCmd.Ins); outs.AddRange(callCmd.Outs); } Procedure proc; if (asyncAndParallelCallDesugarings.ContainsKey(procName)) { proc = asyncAndParallelCallDesugarings[procName]; } else { List<Variable> inParams = new List<Variable>(); List<Variable> outParams = new List<Variable>(); List<Requires> requiresSeq = new List<Requires>(); List<Ensures> ensuresSeq = new List<Ensures>(); int count = 0; foreach (CallCmd callCmd in parCallCmd.CallCmds) { Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); foreach (Variable x in callCmd.Proc.InParams) { Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_{0}_{1}", count, x.Name), x.TypedIdent.Type), true); inParams.Add(y); map[x] = Expr.Ident(y); } foreach (Variable x in callCmd.Proc.OutParams) { Variable y = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_{0}_{1}", count, x.Name), x.TypedIdent.Type), false); outParams.Add(y); map[x] = Expr.Ident(y); } Contract.Assume(callCmd.Proc.TypeParameters.Count == 0); Substitution subst = Substituter.SubstitutionFromHashtable(map); foreach (Requires req in callCmd.Proc.Requires) { requiresSeq.Add(new Requires(req.tok, req.Free, Substituter.Apply(subst, req.Condition), null, req.Attributes)); } foreach (Ensures ens in callCmd.Proc.Ensures) { ensuresSeq.Add(new Ensures(ens.tok, ens.Free, Substituter.Apply(subst, ens.Condition), null, ens.Attributes)); } count++; } proc = new Procedure(Token.NoToken, procName, new List<TypeVariable>(), inParams, outParams, requiresSeq, globalMods, ensuresSeq); asyncAndParallelCallDesugarings[procName] = proc; } CallCmd dummyCallCmd = new CallCmd(parCallCmd.tok, proc.Name, ins, outs, parCallCmd.Attributes); dummyCallCmd.Proc = proc; newCmds.Add(dummyCallCmd); }
public AtomicActionInfo(Procedure proc, Ensures ensures, MoverType moverType, int layerNum, int availableUptoLayerNum) : base(proc, layerNum, availableUptoLayerNum) { this.ensures = ensures; this.moverType = moverType; this.gate = new List<AssertCmd>(); this.action = ensures.Condition as CodeExpr; this.thisGate = new List<AssertCmd>(); this.thisInParams = new List<Variable>(); this.thisOutParams = new List<Variable>(); this.thatGate = new List<AssertCmd>(); this.thatInParams = new List<Variable>(); this.thatOutParams = new List<Variable>(); this.hasAssumeCmd = false; this.thisMap = new Dictionary<Variable, Expr>(); this.thatMap = new Dictionary<Variable, Expr>(); this.triggerFuns = new Dictionary<Variable, Function>(); foreach (Block block in this.action.Blocks) { block.Cmds.ForEach(x => this.hasAssumeCmd = this.hasAssumeCmd || x is AssumeCmd); } foreach (Block block in this.action.Blocks) { if (block.TransferCmd is ReturnExprCmd) { block.TransferCmd = new ReturnCmd(block.TransferCmd.tok); } } var cmds = this.action.Blocks[0].Cmds; for (int i = 0; i < cmds.Count; i++) { AssertCmd assertCmd = cmds[i] as AssertCmd; if (assertCmd == null) break; this.gate.Add(assertCmd); cmds[i] = new AssumeCmd(assertCmd.tok, Expr.True); } foreach (Variable x in proc.InParams) { Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), true, x.Attributes); this.thisInParams.Add(thisx); this.thisMap[x] = Expr.Ident(thisx); Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), true, x.Attributes); this.thatInParams.Add(thatx); this.thatMap[x] = Expr.Ident(thatx); } foreach (Variable x in proc.OutParams) { Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), false, x.Attributes); this.thisOutParams.Add(thisx); this.thisMap[x] = Expr.Ident(thisx); Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false, x.Attributes); this.thatOutParams.Add(thatx); this.thatMap[x] = Expr.Ident(thatx); } List<Variable> thisLocVars = new List<Variable>(); List<Variable> thatLocVars = new List<Variable>(); foreach (Variable x in this.action.LocVars) { Variable thisx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "this_" + x.Name, x.TypedIdent.Type), false); thisMap[x] = Expr.Ident(thisx); thisLocVars.Add(thisx); Variable thatx = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "that_" + x.Name, x.TypedIdent.Type), false); thatMap[x] = Expr.Ident(thatx); thatLocVars.Add(thatx); } Contract.Assume(proc.TypeParameters.Count == 0); Substitution thisSubst = Substituter.SubstitutionFromHashtable(this.thisMap); Substitution thatSubst = Substituter.SubstitutionFromHashtable(this.thatMap); foreach (AssertCmd assertCmd in this.gate) { this.thisGate.Add((AssertCmd)Substituter.Apply(thisSubst, assertCmd)); this.thatGate.Add((AssertCmd)Substituter.Apply(thatSubst, assertCmd)); } this.thisAction = new CodeExpr(thisLocVars, SubstituteBlocks(this.action.Blocks, thisSubst, "this_")); this.thatAction = new CodeExpr(thatLocVars, SubstituteBlocks(this.action.Blocks, thatSubst, "that_")); { VariableCollector collector = new VariableCollector(); collector.Visit(this.action); this.actionUsedGlobalVars = new HashSet<Variable>(collector.usedVars.Where(x => x is GlobalVariable)); } List<Variable> modifiedVars = new List<Variable>(); foreach (Block block in this.action.Blocks) { block.Cmds.ForEach(cmd => cmd.AddAssignedVariables(modifiedVars)); } this.modifiedGlobalVars = new HashSet<Variable>(modifiedVars.Where(x => x is GlobalVariable)); { VariableCollector collector = new VariableCollector(); this.gate.ForEach(assertCmd => collector.Visit(assertCmd)); this.gateUsedGlobalVars = new HashSet<Variable>(collector.usedVars.Where(x => x is GlobalVariable)); } }
private CallCmd CallToYieldProc(IToken tok, Dictionary<Variable, Variable> ogOldGlobalMap, Dictionary<string, Variable> domainNameToLocalVar) { List<Expr> exprSeq = new List<Expr>(); foreach (string domainName in linearTypeChecker.linearDomains.Keys) { exprSeq.Add(Expr.Ident(domainNameToLocalVar[domainName])); } foreach (IdentifierExpr ie in globalMods) { exprSeq.Add(Expr.Ident(ogOldGlobalMap[ie.Decl])); } if (yieldProc == null) { List<Variable> inputs = new List<Variable>(); foreach (string domainName in linearTypeChecker.linearDomains.Keys) { var domain = linearTypeChecker.linearDomains[domainName]; Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "linear_" + domainName + "_in", new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { domain.elementType }, Type.Bool)), true); inputs.Add(f); } foreach (IdentifierExpr ie in globalMods) { Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", ie.Decl.Name), ie.Decl.TypedIdent.Type), true); inputs.Add(f); } yieldProc = new Procedure(Token.NoToken, string.Format("og_yield_{0}", layerNum), new List<TypeVariable>(), inputs, new List<Variable>(), new List<Requires>(), new List<IdentifierExpr>(), new List<Ensures>()); yieldProc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); } CallCmd yieldCallCmd = new CallCmd(Token.NoToken, yieldProc.Name, exprSeq, new List<IdentifierExpr>()); yieldCallCmd.Proc = yieldProc; return yieldCallCmd; }
public override Procedure VisitProcedure(Procedure node) { CivlAttributes.RemoveLayerAttribute(node); return base.VisitProcedure(node); }
private void CreateYieldCheckerImpl(Implementation impl, List<List<Cmd>> yields) { if (yields.Count == 0) return; Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); foreach (Variable local in impl.LocVars) { var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, local.Name, local.TypedIdent.Type)); map[local] = Expr.Ident(copy); } Program program = linearTypeChecker.program; List<Variable> locals = new List<Variable>(); List<Variable> inputs = new List<Variable>(); foreach (IdentifierExpr ie in map.Values) { locals.Add(ie.Decl); } for (int i = 0; i < impl.InParams.Count - linearTypeChecker.linearDomains.Count; i++) { Variable inParam = impl.InParams[i]; Variable copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name, inParam.TypedIdent.Type)); locals.Add(copy); map[impl.InParams[i]] = Expr.Ident(copy); } { int i = impl.InParams.Count - linearTypeChecker.linearDomains.Count; foreach (string domainName in linearTypeChecker.linearDomains.Keys) { Variable inParam = impl.InParams[i]; Variable copy = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name, inParam.TypedIdent.Type), true); inputs.Add(copy); map[impl.InParams[i]] = Expr.Ident(copy); i++; } } for (int i = 0; i < impl.OutParams.Count; i++) { Variable outParam = impl.OutParams[i]; var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, outParam.Name, outParam.TypedIdent.Type)); locals.Add(copy); map[impl.OutParams[i]] = Expr.Ident(copy); } Dictionary<Variable, Expr> ogOldLocalMap = new Dictionary<Variable, Expr>(); Dictionary<Variable, Expr> assumeMap = new Dictionary<Variable, Expr>(map); foreach (IdentifierExpr ie in globalMods) { Variable g = ie.Decl; var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_local_old_{0}", g.Name), g.TypedIdent.Type)); locals.Add(copy); ogOldLocalMap[g] = Expr.Ident(copy); Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", g.Name), g.TypedIdent.Type), true); inputs.Add(f); assumeMap[g] = Expr.Ident(f); } Substitution assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap); Substitution oldSubst = Substituter.SubstitutionFromHashtable(ogOldLocalMap); Substitution subst = Substituter.SubstitutionFromHashtable(map); List<Block> yieldCheckerBlocks = new List<Block>(); List<String> labels = new List<String>(); List<Block> labelTargets = new List<Block>(); Block yieldCheckerBlock = new Block(Token.NoToken, "exit", new List<Cmd>(), new ReturnCmd(Token.NoToken)); labels.Add(yieldCheckerBlock.Label); labelTargets.Add(yieldCheckerBlock); yieldCheckerBlocks.Add(yieldCheckerBlock); int yieldCount = 0; foreach (List<Cmd> cs in yields) { List<Cmd> newCmds = new List<Cmd>(); foreach (Cmd cmd in cs) { PredicateCmd predCmd = (PredicateCmd)cmd; newCmds.Add(new AssumeCmd(Token.NoToken, Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr))); } foreach (Cmd cmd in cs) { PredicateCmd predCmd = (PredicateCmd)cmd; var newExpr = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr); if (predCmd is AssertCmd) { AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes); assertCmd.ErrorData = "Non-interference check failed"; newCmds.Add(assertCmd); } else { newCmds.Add(new AssumeCmd(Token.NoToken, newExpr)); } } newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False)); yieldCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken)); labels.Add(yieldCheckerBlock.Label); labelTargets.Add(yieldCheckerBlock); yieldCheckerBlocks.Add(yieldCheckerBlock); } yieldCheckerBlocks.Insert(0, new Block(Token.NoToken, "enter", new List<Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets))); // Create the yield checker procedure var yieldCheckerName = string.Format("{0}_YieldChecker_{1}", "Impl", impl.Name); var yieldCheckerProc = new Procedure(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List<Variable>(), new List<Requires>(), new List<IdentifierExpr>(), new List<Ensures>()); yieldCheckerProc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); yieldCheckerProcs.Add(yieldCheckerProc); // Create the yield checker implementation var yieldCheckerImpl = new Implementation(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List<Variable>(), locals, yieldCheckerBlocks); yieldCheckerImpl.Proc = yieldCheckerProc; yieldCheckerImpl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); yieldCheckerImpls.Add(yieldCheckerImpl); }
public CivlTypeChecker(Program program) { this.errorCount = 0; this.checkingContext = new CheckingContext(null); this.program = program; this.enclosingProc = null; this.enclosingImpl = null; this.sharedVarsAccessed = null; this.introducedLocalVarsUpperBound = int.MinValue; this.localVarToLocalVariableInfo = new Dictionary<Variable, LocalVariableInfo>(); this.absyToLayerNums = new Dictionary<Absy, HashSet<int>>(); this.globalVarToSharedVarInfo = new Dictionary<Variable, SharedVariableInfo>(); this.procToActionInfo = new Dictionary<Procedure, ActionInfo>(); this.procToAtomicProcedureInfo = new Dictionary<Procedure, AtomicProcedureInfo>(); this.pureCallLayer = new Dictionary<CallCmd, int>(); // Global variables foreach (var g in program.GlobalVariables) { List<int> layerNums = FindLayers(g.Attributes); if (layerNums.Count == 0) { // Inaccessible from yielding and atomic procedures } else if (layerNums.Count == 1) { this.globalVarToSharedVarInfo[g] = new SharedVariableInfo(layerNums[0], int.MaxValue); } else if (layerNums.Count == 2) { this.globalVarToSharedVarInfo[g] = new SharedVariableInfo(layerNums[0], layerNums[1]); } else { Error(g, "Too many layer numbers"); } } }
public static Substitution SubstitutionFromHashtable(Dictionary<Variable, Expr> map, bool fallBackOnName = false, Procedure proc = null) { Contract.Requires(map != null); Contract.Ensures(Contract.Result<Substitution>() != null); // TODO: With Whidbey, could use anonymous functions. return new Substitution(new CreateSubstitutionClosure(map, fallBackOnName, proc).Method); }
public void TypeCheck() { // Pure procedures foreach (var proc in program.Procedures.Where(proc => proc.IsPure())) { if (proc.IsYield()) { Error(proc, "Pure procedure must not yield"); continue; } if (FindLayers(proc.Attributes).Count != 0) { Error(proc, "Pure procedure must not have layers"); continue; } if (proc.Modifies.Count > 0) { Error(proc, "Pure procedure must not modify a global variable"); continue; } procToAtomicProcedureInfo[proc] = new AtomicProcedureInfo(); } // Atomic procedures (not yielding) foreach (var proc in program.Procedures.Where(proc => !proc.IsYield())) { var procLayerNums = FindLayers(proc.Attributes); if (procLayerNums.Count == 0) continue; foreach (IdentifierExpr ie in proc.Modifies) { if (!globalVarToSharedVarInfo.ContainsKey(ie.Decl)) { Error(proc, "Atomic procedure cannot modify a global variable without layer numbers"); continue; } } int lower, upper; if (procLayerNums.Count == 1) { lower = procLayerNums[0]; upper = procLayerNums[0]; } else if (procLayerNums.Count == 2) { lower = procLayerNums[0]; upper = procLayerNums[1]; if (lower >= upper) { Error(proc, "Lower layer must be less than upper layer"); continue; } } else { Error(proc, "Atomic procedure must specify a layer range"); continue; } LayerRange layerRange = new LayerRange(lower, upper); procToAtomicProcedureInfo[proc] = new AtomicProcedureInfo(layerRange); } if (errorCount > 0) return; // Implementations of atomic procedures foreach (Implementation impl in program.Implementations) { AtomicProcedureInfo atomicProcedureInfo; if (!procToAtomicProcedureInfo.TryGetValue(impl.Proc, out atomicProcedureInfo)) continue; if (atomicProcedureInfo.isPure) { this.enclosingImpl = impl; (new PurityChecker(this)).VisitImplementation(impl); } else { this.enclosingImpl = impl; this.sharedVarsAccessed = new HashSet<Variable>(); (new PurityChecker(this)).VisitImplementation(impl); LayerRange upperBound = FindLayerRange(); LayerRange lowerBound = atomicProcedureInfo.layerRange; if (!lowerBound.Subset(upperBound)) { Error(impl, "Atomic procedure cannot access global variable"); } this.sharedVarsAccessed = null; } } if (errorCount > 0) return; // Yielding procedures foreach (var proc in program.Procedures.Where(proc => proc.IsYield())) { int createdAtLayerNum; // must be initialized by the following code, otherwise it is an error int availableUptoLayerNum = int.MaxValue; List<int> attrs = FindLayers(proc.Attributes); if (attrs.Count == 1) { createdAtLayerNum = attrs[0]; } else if (attrs.Count == 2) { createdAtLayerNum = attrs[0]; availableUptoLayerNum = attrs[1]; } else { Error(proc, "Incorrect number of layers"); continue; } foreach (Ensures e in proc.Ensures) { MoverType moverType = GetMoverType(e); if (moverType == MoverType.Top) continue; CodeExpr codeExpr = e.Condition as CodeExpr; if (codeExpr == null) { Error(e, "An atomic action must be a CodeExpr"); continue; } if (procToActionInfo.ContainsKey(proc)) { Error(proc, "A procedure can have at most one atomic action"); continue; } if (availableUptoLayerNum <= createdAtLayerNum) { Error(proc, "Creation layer number must be less than the available upto layer number"); continue; } sharedVarsAccessed = new HashSet<Variable>(); enclosingProc = proc; enclosingImpl = null; base.VisitEnsures(e); LayerRange upperBound = FindLayerRange(); LayerRange lowerBound = new LayerRange(createdAtLayerNum, availableUptoLayerNum); if (lowerBound.Subset(upperBound)) { procToActionInfo[proc] = new AtomicActionInfo(proc, e, moverType, createdAtLayerNum, availableUptoLayerNum); } else { Error(e, "A variable being accessed in this action is unavailable"); } sharedVarsAccessed = null; } if (errorCount > 0) continue; if (!procToActionInfo.ContainsKey(proc)) { if (availableUptoLayerNum < createdAtLayerNum) { Error(proc, "Creation layer number must be no more than the available upto layer number"); continue; } else { procToActionInfo[proc] = new ActionInfo(proc, createdAtLayerNum, availableUptoLayerNum); } } } if (errorCount > 0) return; foreach (var impl in program.Implementations) { if (!procToActionInfo.ContainsKey(impl.Proc)) continue; ActionInfo actionInfo = procToActionInfo[impl.Proc]; procToActionInfo[impl.Proc].hasImplementation = true; if (actionInfo.isExtern) { Error(impl.Proc, "Extern procedure cannot have an implementation"); } } if (errorCount > 0) return; foreach (Procedure proc in procToActionInfo.Keys) { for (int i = 0; i < proc.InParams.Count; i++) { Variable v = proc.InParams[i]; var layer = FindLocalVariableLayer(proc, v, procToActionInfo[proc].createdAtLayerNum); if (layer == int.MinValue) continue; localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer); } for (int i = 0; i < proc.OutParams.Count; i++) { Variable v = proc.OutParams[i]; var layer = FindLocalVariableLayer(proc, v, procToActionInfo[proc].createdAtLayerNum); if (layer == int.MinValue) continue; localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer); } } foreach (Implementation node in program.Implementations) { if (!procToActionInfo.ContainsKey(node.Proc)) continue; foreach (Variable v in node.LocVars) { var layer = FindLocalVariableLayer(node, v, procToActionInfo[node.Proc].createdAtLayerNum); if (layer == int.MinValue) continue; localVarToLocalVariableInfo[v] = new LocalVariableInfo(layer); } for (int i = 0; i < node.Proc.InParams.Count; i++) { Variable v = node.Proc.InParams[i]; if (!localVarToLocalVariableInfo.ContainsKey(v)) continue; var layer = localVarToLocalVariableInfo[v].layer; localVarToLocalVariableInfo[node.InParams[i]] = new LocalVariableInfo(layer); } for (int i = 0; i < node.Proc.OutParams.Count; i++) { Variable v = node.Proc.OutParams[i]; if (!localVarToLocalVariableInfo.ContainsKey(v)) continue; var layer = localVarToLocalVariableInfo[v].layer; localVarToLocalVariableInfo[node.OutParams[i]] = new LocalVariableInfo(layer); } } if (errorCount > 0) return; this.VisitProgram(program); if (errorCount > 0) return; YieldTypeChecker.PerformYieldSafeCheck(this); new LayerEraser().VisitProgram(program); }
public CreateSubstitutionClosure(Dictionary<Variable, Expr> map, bool fallBackOnName = false, Procedure proc = null) : base() { Contract.Requires(map != null); this.map = map; this.proc = proc; if (fallBackOnName && proc != null) { this.nameMap = map.ToDictionary(kv => UniqueName(kv.Key, proc), kv => kv.Value); } }
public void trackCallableMethod(Bpl.Procedure proc) { callableMethods.Add(proc); }