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); } } }
private static GenKillWeight getWeight(Cmd cmd, Implementation impl, Program prog) { Contract.Requires(cmd != null); Contract.Ensures(Contract.Result<GenKillWeight>() != null); if (weightCache.ContainsKey(cmd)) return weightCache[cmd]; HashSet<Variable/*!*/>/*!*/ gen = new HashSet<Variable/*!*/>(); HashSet<Variable/*!*/>/*!*/ kill = new HashSet<Variable/*!*/>(); GenKillWeight/*!*/ ret; if (cmd is AssignCmd) { AssignCmd/*!*/ assignCmd = (AssignCmd)cmd; Contract.Assert(cmd != null); // I must first iterate over all the targets and remove the live ones. // After the removals are done, I must add the variables referred on // the right side of the removed targets foreach (AssignLhs/*!*/ lhs in assignCmd.Lhss) { Contract.Assert(lhs != null); Variable var = lhs.DeepAssignedVariable; if (var != null) { if (lhs is SimpleAssignLhs) { // we should only remove non-map target variables because there is an implicit // read of a map variable in an assignment to it kill.Add(var); } } } int index = 0; foreach (Expr/*!*/ expr in assignCmd.Rhss) { Contract.Assert(expr != null); VariableCollector/*!*/ collector = new VariableCollector(); collector.Visit(expr); gen.UnionWith(collector.usedVars); AssignLhs lhs = assignCmd.Lhss[index]; if (lhs is MapAssignLhs) { // If the target is a map, then all indices are also read MapAssignLhs malhs = (MapAssignLhs)lhs; foreach (Expr e in malhs.Indexes) { VariableCollector/*!*/ c = new VariableCollector(); c.Visit(e); gen.UnionWith(c.usedVars); } } index++; } ret = new GenKillWeight(gen, kill); } else if (cmd is HavocCmd) { HavocCmd/*!*/ havocCmd = (HavocCmd)cce.NonNull(cmd); foreach (IdentifierExpr/*!*/ expr in havocCmd.Vars) { Contract.Assert(expr != null); if (expr.Decl != null) { kill.Add(expr.Decl); } } ret = new GenKillWeight(gen, kill); } else if (cmd is PredicateCmd) { Contract.Assert((cmd is AssertCmd || cmd is AssumeCmd)); PredicateCmd/*!*/ predicateCmd = (PredicateCmd)cce.NonNull(cmd); if (predicateCmd.Expr is LiteralExpr && prog != null && impl != null) { LiteralExpr le = (LiteralExpr)predicateCmd.Expr; if (le.IsFalse) { List<GlobalVariable/*!*/>/*!*/ globals = prog.GlobalVariables(); Contract.Assert(cce.NonNullElements(globals)); foreach (Variable/*!*/ v in globals) { Contract.Assert(v != null); kill.Add(v); } foreach (Variable/*!*/ v in impl.LocVars) { Contract.Assert(v != null); kill.Add(v); } foreach (Variable/*!*/ v in impl.OutParams) { Contract.Assert(v != null); kill.Add(v); } } } else { VariableCollector/*!*/ collector = new VariableCollector(); collector.Visit(predicateCmd.Expr); gen.UnionWith(collector.usedVars); } ret = new GenKillWeight(gen, kill); } else if (cmd is CommentCmd) { ret = new GenKillWeight(gen, kill); // comments are just for debugging and don't affect verification } else if (cmd is SugaredCmd) { SugaredCmd/*!*/ sugCmd = (SugaredCmd)cmd; Contract.Assert(sugCmd != null); ret = getWeight(sugCmd.Desugaring, impl, prog); } else if (cmd is StateCmd) { StateCmd/*!*/ stCmd = (StateCmd)cmd; Contract.Assert(stCmd != null); List<Cmd>/*!*/ cmds = stCmd.Cmds; Contract.Assert(cmds != null); int len = cmds.Count; ret = GenKillWeight.one(); for (int i = len - 1; i >= 0; i--) { GenKillWeight/*!*/ w = getWeight(cmds[i], impl, prog); Contract.Assert(w != null); ret = GenKillWeight.extend(w, ret); } foreach (Variable/*!*/ v in stCmd.Locals) { Contract.Assert(v != null); kill.Add(v); } ret = GenKillWeight.extend(new GenKillWeight(gen, kill), ret); } else { { Contract.Assert(false); throw new cce.UnreachableException(); } } weightCache[cmd] = ret; return ret; }
public MoverTypeChecker(Program program) { this.qedGlobalVariables = new HashSet<Variable>(); foreach (var g in program.GlobalVariables()) { if (QKeyValue.FindBoolAttribute(g.Attributes, "qed")) { this.qedGlobalVariables.Add(g); g.Attributes = OwickiGries.RemoveQedAttribute(g.Attributes); } } this.procToActionInfo = new Dictionary<Procedure, ActionInfo>(); this.assertionPhaseNums = new HashSet<int>(); this.errorCount = 0; this.checkingContext = new CheckingContext(null); this.program = program; this.enclosingProcPhaseNum = int.MaxValue; this.inAtomicSpecification = false; }
/*!*/ public static HashSet<Variable/*!*/> GetVarsLiveAtExit(Implementation impl, Program prog) { Contract.Requires(prog != null); Contract.Requires(impl != null); Contract.Ensures(cce.NonNullElements(Contract.Result<HashSet<Variable>>())); if (varsLiveAtExit.ContainsKey(impl.Name)) { return varsLiveAtExit[impl.Name]; } // Return default: all globals and out params HashSet<Variable/*!*/>/*!*/ lv = new HashSet<Variable/*!*/>(); foreach (Variable/*!*/ v in prog.GlobalVariables()) { Contract.Assert(v != null); lv.Add(v); } foreach (Variable/*!*/ v in impl.OutParams) { Contract.Assert(v != null); lv.Add(v); } return lv; }
private List<Requires> DisjointnessRequires(Program program, ActionInfo first, ActionInfo second) { List<Requires> requires = new List<Requires>(); Dictionary<string, HashSet<Variable>> domainNameToScope = new Dictionary<string, HashSet<Variable>>(); foreach (var domainName in linearTypeChecker.linearDomains.Keys) { domainNameToScope[domainName] = new HashSet<Variable>(); } foreach (Variable v in program.GlobalVariables()) { var domainName = linearTypeChecker.FindDomainName(v); if (domainName == null) continue; domainNameToScope[domainName].Add(v); } foreach (Variable v in first.thisInParams) { var domainName = linearTypeChecker.FindDomainName(v); if (domainName == null) continue; domainNameToScope[domainName].Add(v); } for (int i = 0; i < second.thatInParams.Count; i++) { var domainName = linearTypeChecker.FindDomainName(second.thisInParams[i]); if (domainName == null) continue; domainNameToScope[domainName].Add(second.thatInParams[i]); } foreach (string domainName in domainNameToScope.Keys) { requires.Add(new Requires(false, linearTypeChecker.DisjointnessExpr(domainName, domainNameToScope[domainName]))); } return requires; }
private void CreateGatePreservationChecker(Program program, ActionInfo first, ActionInfo second) { Tuple<ActionInfo, ActionInfo> actionPair = new Tuple<ActionInfo, ActionInfo>(first, second); if (gatePreservationCheckerCache.Contains(actionPair)) return; gatePreservationCheckerCache.Add(actionPair); List<Variable> inputs = new List<Variable>(); inputs.AddRange(first.thisInParams); inputs.AddRange(second.thatInParams); List<Variable> outputs = new List<Variable>(); outputs.AddRange(first.thisOutParams); outputs.AddRange(second.thatOutParams); List<Variable> locals = new List<Variable>(); locals.AddRange(second.thatAction.LocVars); List<Block> secondBlocks = CloneBlocks(second.thatAction.Blocks); List<Requires> requires = DisjointnessRequires(program, first, second); List<Ensures> ensures = new List<Ensures>(); foreach (AssertCmd assertCmd in first.thisGate) { requires.Add(new Requires(false, assertCmd.Expr)); ensures.Add(new Ensures(false, assertCmd.Expr)); } string checkerName = string.Format("GatePreservationChecker_{0}_{1}", first.proc.Name, second.proc.Name); List<IdentifierExpr> globalVars = new List<IdentifierExpr>(); program.GlobalVariables().Iter(x => globalVars.Add(new IdentifierExpr(Token.NoToken, x))); 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 CreateFailurePreservationChecker(Program program, ActionInfo first, ActionInfo second) { Tuple<ActionInfo, ActionInfo> actionPair = new Tuple<ActionInfo, ActionInfo>(first, second); if (failurePreservationCheckerCache.Contains(actionPair)) return; failurePreservationCheckerCache.Add(actionPair); List<Variable> inputs = new List<Variable>(); inputs.AddRange(first.thisInParams); inputs.AddRange(second.thatInParams); Expr transitionRelation = (new TransitionRelationComputation(program, second)).Compute(); Expr expr = Expr.True; foreach (AssertCmd assertCmd in first.thisGate) { expr = Expr.And(assertCmd.Expr, expr); } List<Requires> requires = DisjointnessRequires(program, first, second); requires.Add(new Requires(false, Expr.Not(expr))); foreach (AssertCmd assertCmd in second.thatGate) { requires.Add(new Requires(false, assertCmd.Expr)); } Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); Dictionary<Variable, Expr> oldMap = new Dictionary<Variable, Expr>(); List<Variable> boundVars = new List<Variable>(); foreach (Variable v in program.GlobalVariables()) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); map[v] = new IdentifierExpr(Token.NoToken, bv); } foreach (Variable v in second.thatOutParams) { { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); map[v] = new IdentifierExpr(Token.NoToken, bv); } { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); oldMap[v] = new IdentifierExpr(Token.NoToken, bv); } } foreach (Variable v in second.thatAction.LocVars) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); oldMap[v] = new IdentifierExpr(Token.NoToken, bv); } Expr ensuresExpr = Expr.And(transitionRelation, Expr.Not(expr)); if (boundVars.Count > 0) { Substitution subst = Substituter.SubstitutionFromHashtable(map); Substitution oldSubst = Substituter.SubstitutionFromHashtable(oldMap); ensuresExpr = new ExistsExpr(Token.NoToken, boundVars, (Expr)new MySubstituter(subst, oldSubst).Visit(ensuresExpr)); } List<Ensures> ensures = new List<Ensures>(); ensures.Add(new Ensures(false, ensuresExpr)); List<Block> blocks = new List<Block>(); blocks.Add(new Block(Token.NoToken, "L", new List<Cmd>(), new ReturnCmd(Token.NoToken))); string checkerName = string.Format("FailurePreservationChecker_{0}_{1}", first.proc.Name, second.proc.Name); List<IdentifierExpr> globalVars = new List<IdentifierExpr>(); program.GlobalVariables().Iter(x => globalVars.Add(new IdentifierExpr(Token.NoToken, x))); 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 CreateCommutativityChecker(Program program, ActionInfo first, ActionInfo second) { Tuple<ActionInfo, ActionInfo> actionPair = new Tuple<ActionInfo, ActionInfo>(first, second); if (commutativityCheckerCache.Contains(actionPair)) return; commutativityCheckerCache.Add(actionPair); List<Variable> inputs = new List<Variable>(); inputs.AddRange(first.thisInParams); inputs.AddRange(second.thatInParams); List<Variable> outputs = new List<Variable>(); outputs.AddRange(first.thisOutParams); outputs.AddRange(second.thatOutParams); List<Variable> locals = new List<Variable>(); locals.AddRange(first.thisAction.LocVars); locals.AddRange(second.thatAction.LocVars); List<Block> firstBlocks = CloneBlocks(first.thisAction.Blocks); List<Block> secondBlocks = CloneBlocks(second.thatAction.Blocks); foreach (Block b in firstBlocks) { if (b.TransferCmd is ReturnCmd) { List<Block> bs = new List<Block>(); bs.Add(secondBlocks[0]); List<string> ls = new List<string>(); ls.Add(secondBlocks[0].Label); b.TransferCmd = new GotoCmd(Token.NoToken, ls, bs); } } List<Block> blocks = new List<Block>(); blocks.AddRange(firstBlocks); blocks.AddRange(secondBlocks); List<Requires> requires = DisjointnessRequires(program, first, second); List<Ensures> ensures = new List<Ensures>(); Expr transitionRelation = (new TransitionRelationComputation(program, first, second)).Compute(); ensures.Add(new Ensures(false, transitionRelation)); string checkerName = string.Format("CommutativityChecker_{0}_{1}", first.proc.Name, second.proc.Name); List<IdentifierExpr> globalVars = new List<IdentifierExpr>(); program.GlobalVariables().Iter(x => globalVars.Add(new IdentifierExpr(Token.NoToken, x))); 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); }