public BigLiteralAbstracter(VCExpressionGenerator gen) : base(gen) { Contract.Requires(gen != null); DummyVar = gen.Variable("x", Type.Int); IncAxioms = new List <VCExpr>(); Literals = new List <KeyValuePair <BigNum, VCExprVar> >(); }
private VCExpr create_let(Term t, VCExpr u) { var name = "$x" + let_ctr.ToString(); let_ctr++; var sym = gen.Variable(name, u.Type); memo.Remove(t); memo.Add(t, sym); lets.Add(gen.LetBinding(sym, u)); return(sym); }
//////////////////////////////////////////////////////////////////////////// private VCExprVar AbstractWithVariable(VCExpr s, VCExpr t) { Contract.Requires(t != null); Contract.Requires(s != null); Contract.Requires((s.Type.Equals(t.Type))); Contract.Ensures(Contract.Result<VCExprVar>() != null); ExprPair pair = new ExprPair(s, t); if (!Representation.TryGetValue(pair, out var repr)) { repr = Gen.Variable("abs" + Representation.Count, s.Type); Representation.Add(pair, repr); } return cce.NonNull(repr); }
/// <summary> /// Computes the wlp for an assert or assume command "cmd". /// </summary> internal static VCExpr Cmd(Block b, Cmd cmd, VCExpr N, VCContext ctxt) { Contract.Requires(cmd != null); Contract.Requires(N != null); Contract.Requires(ctxt != null); Contract.Ensures(Contract.Result <VCExpr>() != null); VCExpressionGenerator gen = ctxt.Ctxt.ExprGen; Contract.Assert(gen != null); if (cmd is AssertCmd) { AssertCmd ac = (AssertCmd)cmd; var isFullyVerified = false; if (ac.VerifiedUnder != null) { var litExpr = ac.VerifiedUnder as LiteralExpr; isFullyVerified = litExpr != null && litExpr.IsTrue; } if (!isFullyVerified) { ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext; } VCExpr C = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr); VCExpr VU = null; if (!isFullyVerified) { if (ac.VerifiedUnder != null) { VU = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.VerifiedUnder); if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout) { ctxt.Ctxt.TimeoutDiagnosticIDToAssertion[ctxt.Ctxt.TimeoutDiagnosticsCount] = new Tuple <AssertCmd, TransferCmd>(ac, b.TransferCmd); VU = gen.Or(VU, gen.Function(VCExpressionGenerator.TimeoutDiagnosticsOp, gen.Integer(BigNum.FromInt(ctxt.Ctxt.TimeoutDiagnosticsCount++)))); } } else if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout) { ctxt.Ctxt.TimeoutDiagnosticIDToAssertion[ctxt.Ctxt.TimeoutDiagnosticsCount] = new Tuple <AssertCmd, TransferCmd>(ac, b.TransferCmd); VU = gen.Function(VCExpressionGenerator.TimeoutDiagnosticsOp, gen.Integer(BigNum.FromInt(ctxt.Ctxt.TimeoutDiagnosticsCount++))); } ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext; } { var subsumption = Subsumption(ac); if (subsumption == CommandLineOptions.SubsumptionOption.Always || (subsumption == CommandLineOptions.SubsumptionOption.NotForQuantifiers && !(C is VCExprQuantifier))) { N = gen.ImpliesSimp(C, N, false); } if (isFullyVerified) { return(N); } else if (VU != null) { C = gen.OrSimp(VU, C); } int id = ac.UniqueId; if (ctxt.Label2absy != null) { ctxt.Label2absy[id] = ac; } ctxt.AssertionCount++; if (ctxt.ControlFlowVariableExpr == null) { Contract.Assert(ctxt.Label2absy != null); return(gen.AndSimp(C, N)); } else { VCExpr controlFlowFunctionAppl = gen.ControlFlowFunctionApplication(ctxt.ControlFlowVariableExpr, gen.Integer(BigNum.FromInt(b.UniqueId))); Contract.Assert(controlFlowFunctionAppl != null); VCExpr assertFailure = gen.Eq(controlFlowFunctionAppl, gen.Integer(BigNum.FromInt(-ac.UniqueId))); return(gen.AndSimp(gen.Implies(assertFailure, C), N)); } } } else if (cmd is AssumeCmd) { AssumeCmd ac = (AssumeCmd)cmd; if (CommandLineOptions.Clo.StratifiedInlining > 0) { // Label the assume if it is a procedure call NAryExpr naryExpr = ac.Expr as NAryExpr; if (naryExpr != null) { if (naryExpr.Fun is FunctionCall) { int id = ac.UniqueId; ctxt.Label2absy[id] = ac; return(MaybeWrapWithOptimization(ctxt, gen, ac.Attributes, gen.ImpliesSimp(ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr), N))); } } } var expr = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr); var aid = QKeyValue.FindStringAttribute(ac.Attributes, "id"); if (aid != null) { var isTry = QKeyValue.FindBoolAttribute(ac.Attributes, "try"); var v = gen.Variable((isTry ? "try$$" : "assume$$") + aid, Microsoft.Boogie.Type.Bool); expr = gen.Function(VCExpressionGenerator.NamedAssumeOp, v, gen.ImpliesSimp(v, expr)); } var soft = QKeyValue.FindBoolAttribute(ac.Attributes, "soft"); var softWeight = QKeyValue.FindIntAttribute(ac.Attributes, "soft", 0); if ((soft || 0 < softWeight) && aid != null) { var v = gen.Variable("soft$$" + aid, Microsoft.Boogie.Type.Bool); expr = gen.Function(new VCExprSoftOp(Math.Max(softWeight, 1)), v, gen.ImpliesSimp(v, expr)); } return(MaybeWrapWithOptimization(ctxt, gen, ac.Attributes, gen.ImpliesSimp(expr, N))); } else { Console.WriteLine(cmd.ToString()); Contract.Assert(false); throw new cce.UnreachableException(); // unexpected command } }
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)); } }
VCExpr LetVC(Block block, Dictionary <int, Absy> label2absy, Hashtable /*<Block, VCExprVar!>*/ blockVariables, List <VCExprLetBinding> bindings, ProverContext proverCtxt, out int assertionCount) { Contract.Requires(label2absy != null); Contract.Requires(blockVariables != null); Contract.Requires(proverCtxt != null); Contract.Requires(cce.NonNullElements(bindings)); Contract.Ensures(Contract.Result <VCExpr>() != null); assertionCount = 0; VCExpressionGenerator gen = proverCtxt.ExprGen; Contract.Assert(gen != null); VCExprVar v = (VCExprVar)blockVariables[block]; if (v == null) { /* * For block A (= block), generate: * LET_binding A_correct = wp(A_body, (/\ S \in Successors(A) :: S_correct)) * with the side effect of adding the let bindings to "bindings" for any * successor not yet visited. */ VCExpr SuccCorrect; GotoCmd gotocmd = block.TransferCmd as GotoCmd; if (gotocmd == null) { if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed) { SuccCorrect = VCExpressionGenerator.False; } else { SuccCorrect = VCExpressionGenerator.True; } } else { Contract.Assert(gotocmd.labelTargets != null); List <VCExpr> SuccCorrectVars = new List <VCExpr>(gotocmd.labelTargets.Count); foreach (Block successor in gotocmd.labelTargets) { Contract.Assert(successor != null); int ac; VCExpr s = LetVC(successor, label2absy, blockVariables, bindings, proverCtxt, out ac); assertionCount += ac; SuccCorrectVars.Add(s); } SuccCorrect = gen.NAry(VCExpressionGenerator.AndOp, SuccCorrectVars); } VCContext context = new VCContext(label2absy, proverCtxt); // m_Context = context; VCExpr vc = Wlp.Block(block, SuccCorrect, context); assertionCount += context.AssertionCount; v = gen.Variable(block.Label + "_correct", Microsoft.Boogie.Type.Bool); bindings.Add(gen.LetBinding(v, vc)); blockVariables.Add(block, v); } return(v); }