public Counterexample CreateBoogieCounterExample(RPFP rpfp, RPFP.Node root, Implementation mainImpl) { FindLabels(); var orderedStateIds = new List<StateId>(); Counterexample newCounterexample = GenerateTrace(rpfp, root, orderedStateIds, mainImpl,true); if (CommandLineOptions.Clo.ModelViewFile != null) { Model m = root.owner.GetBackgroundModel(); GetModelWithStates(m, root, implName2StratifiedInliningInfo[mainImpl.Name], orderedStateIds, varSubst); newCounterexample.Model = m; newCounterexample.ModelHasStatesAlready = true; } return newCounterexample; }
public bool CodeLabelFalse(RPFP rpfp, RPFP.Node root, Absy code, StratifiedInliningInfo info, string prefix) { return CodeLabelTrue(rpfp, root, code, info, prefix); }
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 StateId(RPFP.Edge e, int c, StratifiedInliningInfo i) { edge = e; capturePoint = c; info = i; }
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 virtual Outcome CheckRPFP(string descriptiveName, RPFP vc, ErrorHandler handler, out RPFP.Node cex, Dictionary<int, Dictionary<string, string>> varSubst, Dictionary<string,int> extra_bound = null) { throw new System.NotImplementedException(); }
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 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 NumberCexEdges(RPFP.Node node, Dictionary<int,RPFP.Edge> map) { if (node.Outgoing == null) return; // shouldn't happen RPFP.Edge edge = node.Outgoing; map[edge.number] = edge; foreach (var c in edge.Children) NumberCexEdges(c, map); }
private Counterexample GenerateTrace(RPFP rpfp, RPFP.Node root, List<StateId> orderedStateIds, Implementation procImpl, bool toplevel) { Contract.Requires(procImpl != null); Contract.Assert(!rpfp.Empty(root)); var info = implName2StratifiedInliningInfo[procImpl.Name]; Block entryBlock = cce.NonNull(procImpl.Blocks[0]); Contract.Assert(entryBlock != null); List<Block> trace = new List<Block>(); trace.Add(entryBlock); var calleeCounterexamples = new Dictionary<TraceLocation, CalleeCounterexampleInfo>(); Counterexample newCounterexample = GenerateTraceRec(rpfp, root, orderedStateIds, entryBlock, trace, calleeCounterexamples, info, toplevel); return newCounterexample; }
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; } }
public override Outcome CheckRPFP(string descriptiveName, RPFP _rpfp, ErrorHandler handler, out RPFP.Node cex, Dictionary<int, Dictionary<string, string>> varSubst, Dictionary<string, int> extra_bound) { //Contract.Requires(descriptiveName != null); //Contract.Requires(vc != null); //Contract.Requires(handler != null); rpfp = _rpfp; cex = null; if (options.SeparateLogFiles) CloseLogFile(); // shouldn't really happen if (options.LogFilename != null && currentLogFile == null) { currentLogFile = OpenOutputFile(descriptiveName); currentLogFile.Write(common.ToString()); } PrepareCommon(); Push(); SendThisVC("(fixedpoint-push)"); foreach (var node in rpfp.nodes) { DeclCollector.RegisterRelation((node.Name as VCExprBoogieFunctionOp).Func); } LineariserOptions.Default.LabelsBelowQuantifiers = true; List<string> ruleStrings = new List<string>(); var recursion_bound = CommandLineOptions.Clo.RecursionBound; foreach (var edge in rpfp.edges) { string node_name = (edge.Parent.Name as VCExprBoogieFunctionOp).Func.Name; string rule_name = "rule_" + edge.number.ToString(); string rec_bound = ""; if(extra_bound != null && extra_bound.ContainsKey(node_name)) rec_bound = (recursion_bound + extra_bound[node_name]).ToString(); string ruleString = "(rule " + QuantifiedVCExpr2String(rpfp.GetRule(edge)) + " " + rule_name + " " + rec_bound + "\n)"; ruleStrings.Add(ruleString); } string queryString = "(query " + QuantifiedVCExpr2String(rpfp.GetQuery()) + "\n :engine duality\n :print-certificate true\n"; #if true if (CommandLineOptions.Clo.StratifiedInlining != 0) queryString += " :stratified-inlining true\n"; if (CommandLineOptions.Clo.RecursionBound > 0) queryString += " :recursion-bound " + Convert.ToString(CommandLineOptions.Clo.RecursionBound) + "\n"; #endif queryString += ")"; LineariserOptions.Default.LabelsBelowQuantifiers = false; FlushAxioms(); PossiblyRestart(); SendThisVC("(set-info :boogie-vc-id " + SMTLibNamer.QuoteId(descriptiveName) + ")"); foreach(var rs in ruleStrings) SendThisVC(rs); FlushLogFile(); if (Process != null) { Process.PingPong(); // flush any errors #if false // TODO: this is not going to work if (Process.Inspector != null) Process.Inspector.NewProblem(descriptiveName, vc, handler); #endif } SendThisVC(queryString); FlushLogFile(); var result = Outcome.Undetermined; if (Process != null) { var resp = Process.GetProverResponse(); if (proverErrors.Count > 0) { result = Outcome.Undetermined; foreach (var err in proverErrors) { if (err.Contains("canceled")) { result = Outcome.TimeOut; } } } else if(resp == null) HandleProverError("Prover did not respond"); else switch (resp.Name) { case "unsat": result = Outcome.Valid; break; case "sat": result = Outcome.Invalid; break; case "unknown": result = Outcome.Invalid; break; case "bounded": result = Outcome.Bounded; break; case "error": if (resp.ArgCount > 0 && resp.Arguments[0].Name.Contains("canceled")) { result = Outcome.TimeOut; } else { HandleProverError("Prover error: " + resp.Arguments[0]); result = Outcome.Undetermined; } break; default: HandleProverError("Unexpected prover response: " + resp.ToString()); break; } switch (result) { case Outcome.Invalid: { resp = Process.GetProverResponse(); if (resp.Name == "derivation") { cex = SExprToCex(resp, handler,varSubst); } else HandleProverError("Unexpected prover response: " + resp.ToString()); resp = Process.GetProverResponse(); if (resp.Name == "model") { var model = SExprToModel(resp, handler); cex.owner.SetBackgroundModel(model); } else HandleProverError("Unexpected prover response: " + resp.ToString()); break; } case Outcome.Valid: case Outcome.Bounded: { resp = Process.GetProverResponse(); if (resp.Name == "fixedpoint") { // only get the response if we need it if(CommandLineOptions.Clo.PrintFixedPoint != null) SExprToSoln(resp, varSubst); } else HandleProverError("Unexpected prover response: " + resp.ToString()); break; } default: break; } #if false while (true) { resp = Process.GetProverResponse(); if (resp == null || Process.IsPong(resp)) break; HandleProverError("Unexpected prover response: " + resp.ToString()); } #endif } SendThisVC("(fixedpoint-pop)"); Pop(); AxiomsAreSetup = false; if (CommandLineOptions.Clo.PrintConjectures != null) { ReadConjectures(CommandLineOptions.Clo.PrintConjectures); } return result; }
private void GetDefun(SExpr line, out string pname, out RPFP.Transformer annot) { if (line.Name != "define-fun") { HandleProverError("Prover error: expected define-fun but got:" + line.Name); throw new BadExprFromProver(); } if (line.ArgCount != 4) { HandleProverError("Prover error: define-fun has wrong number of arguments"); throw new BadExprFromProver(); } pname = StripCruft(line.Arguments[0].Name); var pvars = line.Arguments[1]; var pbody = line.Arguments[3]; // range has to be Bool var binding = new Dictionary<string, VCExpr>(); var pvs = new List<VCExpr>(); foreach (var b in pvars.Arguments) { var e = SExprToVar(b); pvs.Add(e); binding.Add(StripCruft(b.Name), e); } VCExpr bexpr = SExprToVCExpr(pbody, binding); annot = rpfp.CreateRelation(pvs.ToArray(), bexpr); }
public override void BeginCheck(string descriptiveName, VCExpr vc, ErrorHandler handler) { //Contract.Requires(descriptiveName != null); //Contract.Requires(vc != null); //Contract.Requires(handler != null); rpfp = null; if (options.SeparateLogFiles) CloseLogFile(); // shouldn't really happen if (options.LogFilename != null && currentLogFile == null) { currentLogFile = OpenOutputFile(descriptiveName); currentLogFile.Write(common.ToString()); } PrepareCommon(); OptimizationRequests.Clear(); string vcString = "(assert (not\n" + VCExpr2String(vc, 1) + "\n))"; FlushAxioms(); PossiblyRestart(); SendThisVC("(push 1)"); SendThisVC("(set-info :boogie-vc-id " + SMTLibNamer.QuoteId(descriptiveName) + ")"); SendThisVC(vcString); SendOptimizationRequests(); FlushLogFile(); if (Process != null) { Process.PingPong(); // flush any errors if (Process.Inspector != null) Process.Inspector.NewProblem(descriptiveName, vc, handler); } SendCheckSat(); FlushLogFile(); }
public FixedpointVC( Program _program, string/*?*/ logFilePath, bool appendLogFile, List<Checker> checkers) : base(_program, logFilePath, appendLogFile, checkers) { switch (CommandLineOptions.Clo.FixedPointMode) { case CommandLineOptions.FixedPointInferenceMode.Corral: mode = Mode.Corral; style = AnnotationStyle.Procedure; break; case CommandLineOptions.FixedPointInferenceMode.OldCorral: mode = Mode.OldCorral; style = AnnotationStyle.Procedure; break; case CommandLineOptions.FixedPointInferenceMode.Flat: mode = Mode.Boogie; style = AnnotationStyle.Flat; break; case CommandLineOptions.FixedPointInferenceMode.Procedure: mode = Mode.Boogie; style = AnnotationStyle.Procedure; break; case CommandLineOptions.FixedPointInferenceMode.Call: mode = Mode.Boogie; style = AnnotationStyle.Call; break; } ctx = new Context(); // TODO is this right? rpfp = new RPFP(RPFP.CreateLogicSolver(ctx)); program = _program; gen = ctx; if(old_checker == null) checker = new Checker(this, program, logFilePath, appendLogFile, CommandLineOptions.Clo.ProverKillTime, null); else { checker = old_checker; checker.RetargetWithoutReset(program,checker.TheoremProver.Context); } old_checker = checker; boogieContext = checker.TheoremProver.Context; linOptions = null; // new Microsoft.Boogie.Z3.Z3LineariserOptions(false, options, new List<VCExprVar>()); }
// TODO: this is a bit cheesy. Rather than finding the argument position // of a relational term in a transformer by linear search, better to index this // somewhere, but where? private int TransformerArgPosition(RPFP rpfp, RPFP.Node root, Term expr) { FuncDecl rel = expr.GetAppDecl(); string relname = rel.GetDeclName(); var rps = root.Outgoing.F.RelParams; for (int i = 0; i < rps.Length; i++) { string thisname = rps[i].GetDeclName(); if (thisname == relname) return i; } return -1; }
private bool EvalToFalse(RPFP rpfp, RPFP.Node root, Term expr,StratifiedInliningInfo info) { Term res = rpfp.Eval(root.Outgoing,expr); return res.Equals(ctx.MkTrue()); }
/** Check the RPFP, and return a counterexample if there is one. */ public RPFP.LBool Check(ref RPFP.Node cexroot) { var start = DateTime.Now; ErrorHandler handler = new ErrorHandler(); RPFP.Node cex; varSubst = new Dictionary<int,Dictionary<string,string>>(); ProverInterface.Outcome outcome = checker.TheoremProver.CheckRPFP("name", rpfp, handler, out cex, varSubst); cexroot = cex; Console.WriteLine("solve: {0}s", (DateTime.Now - start).TotalSeconds); switch(outcome) { case ProverInterface.Outcome.Valid: return RPFP.LBool.False; case ProverInterface.Outcome.Invalid: return RPFP.LBool.True; default: return RPFP.LBool.Undef; } }
public virtual Outcome CheckRPFP(string descriptiveName, RPFP vc, ErrorHandler handler, out RPFP.Node cex, Dictionary <int, Dictionary <string, string> > varSubst, Dictionary <string, int> extra_bound = null) { throw new System.NotImplementedException(); }
/** Check the RPFP, and return a counterexample if there is one. */ public VC.ConditionGeneration.Outcome Check(ref RPFP.Node cexroot) { var start = DateTime.Now; ErrorHandler handler = new ErrorHandler(); RPFP.Node cex; varSubst = new Dictionary<int,Dictionary<string,string>>(); #if false int origRecursionBound = CommandLineOptions.Clo.RecursionBound; if (CommandLineOptions.Clo.RecursionBound > 0 && extraRecBound != null) { int maxExtra = 0; foreach (string s in extraRecBound.Keys) { int extra = extraRecBound[s]; if (extra > maxExtra) maxExtra = extra; } CommandLineOptions.Clo.RecursionBound += maxExtra; } #endif ProverInterface.Outcome outcome = checker.TheoremProver.CheckRPFP("name", rpfp, handler, out cex, varSubst, extraRecBound); cexroot = cex; #if false CommandLineOptions.Clo.RecursionBound = origRecursionBound; #endif Console.WriteLine("solve: {0}s", (DateTime.Now - start).TotalSeconds); switch(outcome) { case ProverInterface.Outcome.Valid: return VC.ConditionGeneration.Outcome.Correct; case ProverInterface.Outcome.Bounded: return VC.ConditionGeneration.Outcome.ReachedBound; case ProverInterface.Outcome.Invalid: return VC.ConditionGeneration.Outcome.Errors; case ProverInterface.Outcome.TimeOut: return VC.ConditionGeneration.Outcome.TimedOut; default: return VC.ConditionGeneration.Outcome.Inconclusive; } }