public HoudiniVC(StratifiedInliningInfo siInfo, HashSet <string> procCalls, HashSet <string> currentAssignment) : base(siInfo, procCalls) { var gen = siInfo.vcgen.prover.VCExprGen; // Remove CandiateFunc var fsp = new FindSummaryPred(gen); vcexpr = fsp.Apply(vcexpr); this.constantToAssumedExpr = fsp.constantToAssumedExpr; this.constantToAssertedExpr = fsp.constantToAssertedExpr; if (!HoudiniInlining.DualHoudini) { // Assume current summaries of callees foreach (var tup in constantToAssumedExpr) { if (!currentAssignment.Contains(tup.Item1)) { continue; } vcexpr = gen.And(vcexpr, gen.Implies(tup.Item2, tup.Item3)); } } else { // Assert current post foreach (var tup in constantToAssertedExpr) { if (!currentAssignment.Contains(tup.Key)) { continue; } vcexpr = gen.And(vcexpr, gen.Not(tup.Value)); } } }
public void GetTransformer(StratifiedInliningInfo info) { Term vcTerm = boogieContext.VCExprToTerm(info.vcexpr, linOptions); Term[] paramTerms = info.interfaceExprVars.Select(x => boogieContext.VCExprToTerm(x, linOptions)).ToArray(); var relParams = new List<FuncDecl>(); var nodeParams = new List<RPFP.Node>(); var memo = new TermDict< Term>(); var done = new Dictionary<Term,Term>(); // note this hashes on equality, not reference! vcTerm = CollectParamsRec(memo, vcTerm, relParams, nodeParams,done); // var ops = new Util.ContextOps(ctx); // var foo = ops.simplify_lhs(vcTerm); // vcTerm = foo.Item1; info.F = rpfp.CreateTransformer(relParams.ToArray(), paramTerms, vcTerm); info.edge = rpfp.CreateEdge(info.node, info.F, nodeParams.ToArray()); rpfp.edges.Add(info.edge); // TODO labels[info.edge.number] = foo.Item2; }
private bool EvalToFalse(RPFP rpfp, RPFP.Node root, Term expr,StratifiedInliningInfo info) { Term res = rpfp.Eval(root.Outgoing,expr); return res.Equals(ctx.MkTrue()); }
public bool CodeLabelTrue(RPFP rpfp, RPFP.Node root, Absy code, StratifiedInliningInfo info, string prefix) { string label = CodeLabel(code, info, prefix); if (label == null) throw new LabelNotFound(); return root.Outgoing.labels.Contains(label); }
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 Term CodeLabeledExpr(RPFP rpfp, RPFP.Node root, Absy code, StratifiedInliningInfo info, string prefix) { string label = CodeLabel(code, info, prefix); if (label != null) { var res = labels[label]; return res; } else return null; }
public bool CodeLabelFalse(RPFP rpfp, RPFP.Node root, Absy code, StratifiedInliningInfo info, string prefix) { return CodeLabelTrue(rpfp, root, code, info, prefix); }
public string CodeLabel(Absy code, StratifiedInliningInfo info, string prefix) { if (info.label2absyInv == null) { info.label2absyInv = new Dictionary<Absy, string>(); foreach (int foo in info.label2absy.Keys) { Absy bar = info.label2absy[foo] as Absy; string lbl = foo.ToString(); info.label2absyInv.Add(bar, lbl); } } if (info.label2absyInv.ContainsKey(code)) { string label = info.label2absyInv[code]; return prefix+label; } return null; }
public StateId(RPFP.Edge e, int c, StratifiedInliningInfo i) { edge = e; capturePoint = c; info = i; }
private void GetModelWithStates(Model m, RPFP.Node cex, StratifiedInliningInfo mainInfo, List<StateId> orderedStateIds, Dictionary<int,Dictionary<string,string>> varSubst) { if (m == null) return; var mvInfo = mainInfo.mvInfo; foreach (Variable v in mvInfo.AllVariables) { m.InitialState.AddBinding(v.Name, GetModelValue(m, v, varSubst[cex.Outgoing.number])); } Dictionary<int, RPFP.Edge> edgeNumbering = new Dictionary<int,RPFP.Edge>(); NumberCexEdges(cex, edgeNumbering); int lastCandidate = 0; int lastCapturePoint = CALL; for (int i = 0; i < orderedStateIds.Count; ++i) { var s = orderedStateIds[i]; RPFP.Edge edge = s.edge; int candidate = edge.number; int capturePoint = s.capturePoint; Dictionary<string, string> subst = varSubst[candidate]; string implName = edge.Parent.Name.GetDeclName(); var info = s.info.mvInfo; if (capturePoint == CALL || capturePoint == RETURN) { lastCandidate = candidate; lastCapturePoint = capturePoint; continue; } Contract.Assume(0 <= capturePoint && capturePoint < info.CapturePoints.Count); VC.ModelViewInfo.Mapping map = info.CapturePoints[capturePoint]; var prevInc = (lastCapturePoint != CALL && lastCapturePoint != RETURN && candidate == lastCandidate) ? info.CapturePoints[lastCapturePoint].IncarnationMap : new Dictionary<Variable, Expr>(); var cs = m.MkState(map.Description); foreach (Variable v in info.AllVariables) { var e = (Expr)map.IncarnationMap[v]; if (e == null) { if (lastCapturePoint == CALL || lastCapturePoint == RETURN) { cs.AddBinding(v.Name, GetModelValue(m, v, subst)); } continue; } if (lastCapturePoint != CALL && lastCapturePoint != RETURN && prevInc[v] == e) continue; // skip unchanged variables Model.Element elt; if (e is IdentifierExpr) { IdentifierExpr ide = (IdentifierExpr)e; elt = GetModelValue(m, ide.Decl, subst); } else if (e is LiteralExpr) { LiteralExpr lit = (LiteralExpr)e; elt = m.MkElement(lit.Val.ToString()); } else { Contract.Assume(false); elt = m.MkFunc(e.ToString(), 0).GetConstant(); } cs.AddBinding(v.Name, elt); } lastCandidate = candidate; lastCapturePoint = capturePoint; } return; }
private void GenerateVCForStratifiedInlining(Program program, StratifiedInliningInfo info, Checker checker) { Contract.Requires(program != null); Contract.Requires(info != null); Contract.Requires(checker != null); Contract.Requires(info.impl != null); Contract.Requires(info.impl.Proc != null); Implementation impl = info.impl; if (mode == Mode.Boogie && style == AnnotationStyle.Flat && impl.Name != main_proc_name) return; Contract.Assert(impl != null); ConvertCFG2DAG(impl,edgesCut); VC.ModelViewInfo mvInfo; PassifyImpl(impl, out mvInfo); Dictionary<int, Absy> label2absy = null; VCExpressionGenerator gen = checker.VCExprGen; Contract.Assert(gen != null); VCExpr vcexpr; if(NoLabels){ // int assertionCount = 0; VCExpr startCorrect = null; /* VC.VCGen.LetVC(cce.NonNull(impl.Blocks[0]), null, null, info.blockVariables, info.bindings, info.ctxt, out assertionCount); */ vcexpr = gen.Let(info.bindings, startCorrect); } else vcexpr = GenerateVC(impl, null /* info.controlFlowVariable */, out label2absy, info.ctxt); if(mode != Mode.Boogie) vcexpr = gen.Not(vcexpr); Contract.Assert(vcexpr != null); info.label2absy = label2absy; info.mvInfo = mvInfo; List<VCExpr> interfaceExprs = new List<VCExpr>(); if (true /* was: !info.isMain */) { Boogie2VCExprTranslator translator = checker.TheoremProver.Context.BoogieExprTranslator; Contract.Assert(translator != null); info.privateVars = new List<VCExprVar>(); foreach (Variable v in impl.LocVars) { Contract.Assert(v != null); info.privateVars.Add(translator.LookupVariable(v)); } foreach (Variable v in impl.OutParams) { Contract.Assert(v != null); info.privateVars.Add(translator.LookupVariable(v)); } info.interfaceExprVars = new List<VCExprVar>(); foreach (Variable v in info.interfaceVars) { Contract.Assert(v != null); VCExprVar ev = translator.LookupVariable(v); Contract.Assert(ev != null); info.interfaceExprVars.Add(ev); interfaceExprs.Add(ev); } } Function function = cce.NonNull(info.function); Contract.Assert(function != null); info.funcExpr = gen.Function(function, interfaceExprs); info.vcexpr = vcexpr; if (mode == Mode.Boogie) { Term z3vc = boogieContext.VCExprToTerm(vcexpr, linOptions); FactorVCs(z3vc, DualityVCs); } else { // Index the procedures by relational variable FuncDecl R = boogieContext.VCExprToTerm(info.funcExpr, linOptions).GetAppDecl(); relationToProc.Add(R, info); info.node = rpfp.CreateNode(boogieContext.VCExprToTerm(info.funcExpr, linOptions)); rpfp.nodes.Add(info.node); if (info.isMain || QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint")) info.node.Bound.Formula = ctx.MkFalse(); } }
private Counterexample GenerateTraceRec( RPFP rpfp, RPFP.Node root, List<StateId> orderedStateIds, Block/*!*/ b, List<Block>/*!*/ trace, Dictionary<TraceLocation/*!*/, CalleeCounterexampleInfo/*!*/>/*!*/ calleeCounterexamples, StratifiedInliningInfo info, bool toplevel) { Contract.Requires(b != null); Contract.Requires(trace != null); Contract.Requires(cce.NonNullDictionaryAndValues(calleeCounterexamples)); Stack<RPFP.Node> continuation_stack = new Stack<RPFP.Node>(); // If our block is not present, try diving into precondition // and push a continuation. // TODO: is the precondition always the first child? while (!CodeLabelFalse(rpfp, root, b, info, "+")) { if (root.Outgoing != null && root.Outgoing.Children.Length > 0) { continuation_stack.Push(root); root = root.Outgoing.Children[0]; } else { // can't find our block Contract.Assert(false); return null; } } // After translation, all potential errors come from asserts. while (true) { List<Cmd> cmds = b.Cmds; TransferCmd transferCmd = cce.NonNull(b.TransferCmd); for (int i = 0; i < cmds.Count; i++) { Cmd cmd = cce.NonNull(cmds[i]); // Skip if 'cmd' not contained in the trace or not an assert if (cmd is AssertCmd) { bool is_failed_assertion = false; if (NoLabels) is_failed_assertion = true; // we assume only assertions on else is_failed_assertion = CodeLabelTrue(rpfp, root, cmd, info, "@"); if (is_failed_assertion) { if (continuation_stack.Count == 0) { Counterexample newCounterexample = AssertCmdToCounterexample((AssertCmd)cmd, transferCmd, trace, new Microsoft.Boogie.Model(), info.mvInfo, boogieContext); newCounterexample.AddCalleeCounterexample(calleeCounterexamples); return newCounterexample; } root = continuation_stack.Pop(); } continue; } // Counterexample generation for inlined procedures AssumeCmd assumeCmd = cmd as AssumeCmd; if (assumeCmd == null) continue; NAryExpr naryExpr = assumeCmd.Expr as NAryExpr; if (naryExpr == null) continue; string calleeName = naryExpr.Fun.FunctionName; Contract.Assert(calleeName != null); // what is this crap??? BinaryOperator binOp = naryExpr.Fun as BinaryOperator; if (binOp != null && binOp.Op == BinaryOperator.Opcode.And) { Expr expr = naryExpr.Args[0]; NAryExpr mvStateExpr = expr as NAryExpr; if (mvStateExpr != null && mvStateExpr.Fun.FunctionName == VC.ModelViewInfo.MVState_FunctionDef.Name) { LiteralExpr x = mvStateExpr.Args[1] as LiteralExpr; // Debug.Assert(x != null); int foo = x.asBigNum.ToInt; orderedStateIds.Add(new StateId(root.Outgoing,foo,info)); } } if (calleeName.EndsWith("_summary")) calleeName = calleeName.Substring(0, calleeName.Length - 8); if (!implName2StratifiedInliningInfo.ContainsKey(calleeName) && !calleeName.EndsWith("_summary")) continue; { Term code = CodeLabeledExpr(rpfp, root, cmd, info, "+si_fcall_"); int pos = TransformerArgPosition(rpfp, root, code); if (pos >= 0) { RPFP.Node callee = root.Outgoing.Children[pos]; orderedStateIds.Add(new StateId(callee.Outgoing, CALL,info)); calleeCounterexamples[new TraceLocation(trace.Count - 1, i)] = new CalleeCounterexampleInfo( cce.NonNull(GenerateTrace(rpfp, callee, orderedStateIds, implName2StratifiedInliningInfo[calleeName].impl, false)), new List<object>()); orderedStateIds.Add(new StateId(root.Outgoing, RETURN,info)); } } } GotoCmd gotoCmd = transferCmd as GotoCmd; List<Block> cuts = null; if (edgesCut.ContainsKey(b)) cuts = edgesCut[b]; b = null; if (gotoCmd != null) { foreach (Block bb in cce.NonNull(gotoCmd.labelTargets)) { Contract.Assert(bb != null); if (CodeLabelFalse(rpfp, root, bb, info, "+")) { trace.Add(bb); b = bb; break; } } if (b != null) continue; } // HACK: we have to try edges that were cut in generating the VC if (cuts != null) foreach (var bb in cuts) { if (CodeLabelFalse(rpfp, root, bb, info, "+")) { trace.Add(bb); b = bb; break; } } if (b != null) continue; return null; } }
private void EmitProcSpec(TokenTextWriter twr, Procedure proc, StratifiedInliningInfo info, RPFP.Transformer annot) { // last ensures clause will be the symbolic one if (!info.isMain) { var ens = proc.Ensures[proc.Ensures.Count - 1]; if (ens.Condition != Expr.False) // this is main { var postExpr = ens.Condition as NAryExpr; var args = postExpr.Args; var ind = annot.IndParams; var bound = new Dictionary<VCExpr, Expr>(); for (int i = 0; i < args.Count; i++) { bound[ind[i]] = args[i]; } var new_ens_cond = VCExprToExpr(annot.Formula, bound); if (new_ens_cond != Expr.True) { var new_ens = new Ensures(false, new_ens_cond); var enslist = new List<Ensures>(); enslist.Add(new_ens); var new_proc = new Procedure(proc.tok, proc.Name, proc.TypeParameters, proc.InParams, proc.OutParams, new List<Requires>(), new List<IdentifierExpr>(), enslist); new_proc.Emit(twr, 0); } } } }
private void FixedPointToSpecs(){ if(mode != Mode.Corral || CommandLineOptions.Clo.PrintFixedPoint == null) return; // not implemented for other annotation modes yet var twr = new TokenTextWriter(CommandLineOptions.Clo.PrintFixedPoint, /*pretty=*/ false); Dictionary<string, RPFP.Node> pmap = new Dictionary<string,RPFP.Node> (); foreach (var node in rpfp.nodes) pmap.Add ((node.Name as VCExprBoogieFunctionOp).Func.Name, node); foreach (var impl in program.Implementations) { 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 (pmap.ContainsKey(impl.Name)) { RPFP.Node node = pmap[impl.Name]; var annot = node.Annotation; EmitProcSpec(twr, proc, info, annot); } } } } twr.Close (); }