public void GenerateVC() { if (initialized) return; if (CommandLineOptions.Clo.SIBoolControlVC) { GenerateVCBoolControl(); initialized = true; return; } List<Variable> outputVariables = new List<Variable>(); List<Expr> assertConjuncts = new List<Expr>(); foreach (Variable v in impl.OutParams) { Constant c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type)); outputVariables.Add(c); Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v)); assertConjuncts.Add(eqExpr); } foreach (IdentifierExpr e in impl.Proc.Modifies) { 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)); outputVariables.Add(c); Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v)); assertConjuncts.Add(eqExpr); } exitAssertCmd = new AssertCmd(Token.NoToken, Expr.Not(Expr.BinaryTreeAnd(assertConjuncts))); Program program = vcgen.program; ProverInterface proverInterface = vcgen.prover; vcgen.ConvertCFG2DAG(impl); vcgen.PassifyImpl(impl, out mvInfo); VCExpressionGenerator gen = proverInterface.VCExprGen; var exprGen = proverInterface.Context.ExprGen; var translator = proverInterface.Context.BoogieExprTranslator; controlFlowVariable = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "@cfc", Microsoft.Boogie.Type.Int)); VCExpr controlFlowVariableExpr = translator.LookupVariable(controlFlowVariable); vcgen.InstrumentCallSites(impl); if (PassiveImplInstrumentation != null) PassiveImplInstrumentation(impl); label2absy = new Dictionary<int, Absy>(); VCGen.CodeExprConversionClosure cc = new VCGen.CodeExprConversionClosure(label2absy, proverInterface.Context); translator.SetCodeExprConverter(cc.CodeExprToVerificationCondition); vcexpr = gen.Not(vcgen.GenerateVCAux(impl, controlFlowVariableExpr, label2absy, proverInterface.Context)); if (controlFlowVariableExpr != null) { VCExpr controlFlowFunctionAppl = exprGen.ControlFlowFunctionApplication(controlFlowVariableExpr, exprGen.Integer(BigNum.ZERO)); VCExpr eqExpr = exprGen.Eq(controlFlowFunctionAppl, exprGen.Integer(BigNum.FromInt(impl.Blocks[0].UniqueId))); vcexpr = exprGen.And(eqExpr, vcexpr); } callSites = vcgen.CollectCallSites(impl); recordProcCallSites = vcgen.CollectRecordProcedureCallSites(impl); privateExprVars = new List<VCExprVar>(); foreach (Variable v in impl.LocVars) { privateExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in impl.OutParams) { privateExprVars.Add(translator.LookupVariable(v)); } interfaceExprVars = new List<VCExprVar>(); foreach (Variable v in program.GlobalVariables) { interfaceExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in impl.InParams) { interfaceExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in outputVariables) { interfaceExprVars.Add(translator.LookupVariable(v)); } initialized = true; }
public void GenerateVCBoolControl() { Debug.Assert(!initialized); Debug.Assert(CommandLineOptions.Clo.SIBoolControlVC); // fix names for exit variables var outputVariables = new List<Variable>(); var assertConjuncts = new List<Expr>(); foreach (Variable v in impl.OutParams) { Constant c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type)); outputVariables.Add(c); Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v)); assertConjuncts.Add(eqExpr); } foreach (IdentifierExpr e in impl.Proc.Modifies) { 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)); outputVariables.Add(c); Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v)); assertConjuncts.Add(eqExpr); } exitAssertCmd = new AssumeCmd(Token.NoToken, Expr.BinaryTreeAnd(assertConjuncts)); (exitAssertCmd as AssumeCmd).Attributes = new QKeyValue(Token.NoToken, "exitAssert", new List<object>(), null); // no need for label2absy label2absy = new Dictionary<int, Absy>(); // Passify Program program = vcgen.program; ProverInterface proverInterface = vcgen.prover; vcgen.ConvertCFG2DAG(impl); vcgen.PassifyImpl(impl, out mvInfo); VCExpressionGenerator gen = proverInterface.VCExprGen; var exprGen = proverInterface.Context.ExprGen; var translator = proverInterface.Context.BoogieExprTranslator; // add a boolean variable at each call site vcgen.InstrumentCallSites(impl); // typecheck var tc = new TypecheckingContext(null); impl.Typecheck(tc); /////////////////// // Generate the VC /////////////////// // block -> bool variable blockToControlVar = new Dictionary<Block, VCExprVar>(); foreach (var b in impl.Blocks) blockToControlVar.Add(b, gen.Variable(b.Label + "_holds", Bpl.Type.Bool)); vcexpr = VCExpressionGenerator.True; foreach (var b in impl.Blocks) { // conjoin all assume cmds VCExpr c = VCExpressionGenerator.True; foreach (var cmd in b.Cmds) { var acmd = cmd as AssumeCmd; if (acmd == null) { Debug.Assert(cmd is AssertCmd && (cmd as AssertCmd).Expr is LiteralExpr && ((cmd as AssertCmd).Expr as LiteralExpr).IsTrue); continue; } var expr = translator.Translate(acmd.Expr); c = gen.AndSimp(c, expr); } // block implies a disjunction of successors Debug.Assert(!(b.TransferCmd is ReturnExprCmd), "Not supported"); var gc = b.TransferCmd as GotoCmd; if (gc != null) { VCExpr succ = VCExpressionGenerator.False; foreach (var sb in gc.labelTargets) succ = gen.OrSimp(succ, blockToControlVar[sb]); c = gen.AndSimp(c, succ); } else { // nothing to do } vcexpr = gen.AndSimp(vcexpr, gen.Eq(blockToControlVar[b], c)); } // assert start block vcexpr = gen.AndSimp(vcexpr, blockToControlVar[impl.Blocks[0]]); //Console.WriteLine("VC of {0}: {1}", impl.Name, vcexpr); // Collect other information callSites = vcgen.CollectCallSites(impl); recordProcCallSites = vcgen.CollectRecordProcedureCallSites(impl); // record interface variables privateExprVars = new List<VCExprVar>(); foreach (Variable v in impl.LocVars) { privateExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in impl.OutParams) { privateExprVars.Add(translator.LookupVariable(v)); } privateExprVars.AddRange(blockToControlVar.Values); interfaceExprVars = new List<VCExprVar>(); foreach (Variable v in program.GlobalVariables) { interfaceExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in impl.InParams) { interfaceExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in outputVariables) { interfaceExprVars.Add(translator.LookupVariable(v)); } }