/// <summary> /// Insert the statement as is into the state /// </summary> /// <param name="stmt"></param> /// <param name="state"></param> /// <returns></returns> private static IEnumerable <ProofState> DefaultAction(Statement stmt, ProofState state) { Contract.Requires <ArgumentNullException>(stmt != null, "stmt"); Contract.Requires <ArgumentNullException>(state != null, "state"); state.AddStatement(stmt); yield return(state.Copy()); }
private static IEnumerable <ProofState> UpdateLocalValue(UpdateStmt us, ProofState state) { Contract.Requires <ArgumentNullException>(us != null, "stmt"); Contract.Requires <ArgumentNullException>(state != null, "state"); Contract.Requires <ArgumentException>(state.IsLocalAssignment(us), "stmt"); foreach (var item in us.Rhss) { int index = us.Rhss.IndexOf(item); Contract.Assert(us.Lhss.ElementAtOrDefault(index) != null, "register var err"); var exprRhs = item as ExprRhs; if (exprRhs?.Expr is ApplySuffix) { var aps = (ApplySuffix)exprRhs.Expr; var result = SimpExpr.UnfoldTacticProjection(state, aps); state.UpdateTacticVar(((NameSegment)us.Lhss[index]).Name, result); } else if (exprRhs?.Expr is Microsoft.Dafny.LiteralExpr) { state.UpdateTacticVar(((NameSegment)us.Lhss[index]).Name, (Microsoft.Dafny.LiteralExpr)exprRhs?.Expr); } else { throw new NotSupportedException("Not supported update statement"); } } yield return(state.Copy()); }
public static bool CheckTypeTac(UserDefinedType type, string tacName, ProofState state, out string errMsg) { if (state.Tactics.ContainsKey(tacName)) { var tac = state.Tactics[tacName]; if (type.TypeArgs.Count != tac.Ins.Count) { errMsg = "The number of args doesn't match the tactic typ " + type; return(false); } for (var i = 0; i < tac.Ins.Count; i++) { var name = tac.Ins[i].Type.ToString(); if (tac.Ins[i].Type.ToString() != type.TypeArgs[i].ToString()) { errMsg = tacName + " doesn't match the tactic typ " + type; return(false); } } errMsg = ""; return(true); } else { errMsg = tacName + " is not a tactic."; return(false); } }
public static Dictionary <ProofState, MemberDecl> GenerateMembers(ProofState state, Dictionary <ProofState, BlockStmt> bodies) { Contract.Requires <ArgumentNullException>(state != null, "state"); Contract.Requires <ArgumentNullException>(bodies != null, "bodies"); var result = new Dictionary <ProofState, MemberDecl>(); var cl = new Cloner(); foreach (var body in bodies) { var md = cl.CloneMember(state.TargetMethod) as Method; if (md != null) { md.Body.Body.Clear(); md.Body.Body.AddRange(body.Value.Body); if (result.Values.All(x => x.Name != md.Name)) { result.Add(body.Key, md); } else { md = new Method(md.tok, FreshMemberName(md, result.Values.ToList()), md.HasStaticKeyword, md.IsGhost, md.TypeArgs, md.Ins, md.Outs, md.Req, md.Mod, md.Ens, md.Decreases, md.Body, md.Attributes, md.SignatureEllipsis); result.Add(body.Key, md); } } } return(result); }
private CompoundErrorInformation(string msg, ProofState state) : base(new Token(TacnyDriver.TacticCodeTokLine, TacnyDriver.TacticCodeTokLine), msg == "" ? " Exception in: " + StringOfStmt(state) : msg) { ImplementationName = "Impl$$" + state.TargetMethod.FullName; S = state; }
public static List <CompoundErrorInformation> GenerateErrorInfoList(ProofState state, string msg = "") { List <CompoundErrorInformation> errs = new List <CompoundErrorInformation>(); //resolving errors: moving those errors to error info var report = state.GetErrHandler().Reporter; if (report.Count(ErrorLevel.Error) != 0) { foreach (var errMsg in report.AllMessages[ErrorLevel.Error]) { AddErrorInfo(state, errMsg.message); } } // verification error + resolving errors var l = state.GetErrHandler().ErrorList; Console.WriteLine("\n================ Tactic exception: ================"); if (l != null && l.Count > 0) { foreach (var err in l) { errs.Add(new CompoundErrorInformation(msg, err, state)); Console.WriteLine(err.FullMsg); } } var errInfo = new CompoundErrorInformation(msg, state); Console.WriteLine(errInfo.FullMsg); Console.WriteLine("================ End of tactic exception ================"); errs.Add(errInfo); return(errs); }
internal static void AddErrorInfo(ProofState state, string msg) { var errInfo = new CompoundErrorInformation(msg, state); if (state.GetErrHandler().ErrorList == null) { state.GetErrHandler().ErrorList = new List <ErrorInformation>(); } state.GetErrHandler().ErrorList.Add(errInfo); }
private TacnyDriver(Program program, ErrorReporterDelegate erd) { Contract.Requires(Tcce.NonNull(program)); // initialize state GetTimer().Restart(); _state = new ProofState(program); _errorReporterDelegate = erd; _branches = new List <IEnumerable <ProofState> >(); _tacticCalls = 0; }
private static string StringOfStmt(ProofState state) { var writer = new System.IO.StringWriter(); var r = new Printer(writer); r.PrintStatement(state.GetLastStmt(), 0); var str = writer.ToString(); // Console.WriteLine(str); return(str); }
public static void VerifyResolvedProg(ProofState state, Program program, List <TacnyInterpreter.VerifyResult> res, List <int> idx, ErrorReporterDelegate er) { Contract.Requires <ArgumentNullException>(program != null); #if _TACTIC_DEBUG_L1 var printer = new Printer(Console.Out); Console.WriteLine("*********************Verifying Tactic Generated Prog*****************"); printer.PrintProgram(program, true); Console.WriteLine("\n*********************Prog END*****************"); #endif _verificationCount++; Console.WriteLine("Verfication Count: " + _verificationCount); IEnumerable <Tuple <string, Bpl.Program> > boogieProg; // try { boogieProg = Translator.Translate(program, program.reporter, null); foreach (var prog in boogieProg) { PipelineStatistics stats; List <ErrorInformation> errorList; PipelineOutcome tmp = BoogiePipeline(prog.Item2, new List <string> { program.Name }, program.Name, er, out stats, out errorList, program); var curIdx = -1; for (var i = 0; i < errorList.Count; i++) { var err = errorList[i]; if (err.Tok.line < TacnyDriver.TacticCodeTokLine) { curIdx = 0 - err.Tok.line - 2; res[idx[curIdx]] = TacnyInterpreter.VerifyResult.Failed; } } } /* } catch { * Console.WriteLine("execption: set verify result as failed."); * for(var i = 0; i < res.Count; i++) { * res[i] = TacnyInterpreter.VerifyResult.Failed; * } * }*/ }
private static void RemoveUnfoldedTacticCalls(List <Statement> body, ProofState state) { Contract.Requires <ArgumentNullException>(body != null, "body "); for (var i = 0; i < body.Count; i++) { var stmt = body[i]; if (stmt is BlockStmt) { RemoveUnfoldedTacticCalls((stmt as BlockStmt).Body, state); } else if (stmt is WhileStmt) { var whileStmt = stmt as WhileStmt; //remove inv with tac call if (whileStmt.Invariants != null && whileStmt.Invariants.Count > 0) { for (int j = 0; j < whileStmt.Invariants.Count; j++) { var aps = Expr.TacticAppExprFinder.GetTacticAppExpr(state, whileStmt.Invariants[j].E); if (aps != null) { whileStmt.Invariants.RemoveAt(i); } } } //remove var with tac call if (whileStmt.Decreases != null && whileStmt.Decreases.Expressions != null && whileStmt.Decreases.Expressions.Count > 0) { for (int j = 0; j < whileStmt.Decreases.Expressions.Count; j++) { var aps = Expr.TacticAppExprFinder.GetTacticAppExpr(state, whileStmt.Decreases.Expressions[j]); if (aps != null) { whileStmt.Decreases.Expressions.RemoveAt(i); } } } RemoveUnfoldedTacticCalls(whileStmt.Body.Body, state); } else { var aps = Expr.TacticAppExprFinder.GetTacticAppExpr(state, stmt); if (aps != null) { body.RemoveAt(i); } } } }
public static bool CheckTacticArgs(ITactic tac, ApplySuffix aps, ProofState state, out string errMsg) { Contract.Requires(tac != null); Contract.Requires(aps != null); if (aps.Args.Count != tac.Ins.Count) { errMsg = "The number of args doesn't match the tactic definition for " + Printer.ExprToString(aps); return(false); } for (var i = 0; i < tac.Ins.Count; i++) { var name = tac.Ins[i].Type is UserDefinedType ? (tac.Ins[i].Type as UserDefinedType).Name : tac.Ins[i].Type.ToString(); switch (name) { case "bool": case "int": if (!(aps.Args[i] is NameSegment) || tac.Ins[i].Type.ToString() != aps.Args[i].Type.ToString()) { errMsg = "In arg[" + i + "], expect " + tac.Ins[i].Type + " but " + aps.Args[i] + " is found"; return(false); } break; case "term": break; case "tac": if (!CheckTypeTac(tac.Ins[i].Type as UserDefinedType, (aps.Args[i] as NameSegment).Name, state, out errMsg)) { return(false); } break; default: break; } } errMsg = ""; return(true); }
/// <summary> /// Insert generated code into a method /// </summary> /// <param name="state"></param> /// <param name="code"></param> /// <returns></returns> public static BlockStmt InsertCode(ProofState state, Dictionary <Statement, List <Statement> > code) { Contract.Requires <ArgumentNullException>(state != null, "state"); Contract.Requires <ArgumentNullException>(code != null, "code"); var prog = state.GetDafnyProgram(); var tld = prog.DefaultModuleDef.TopLevelDecls.FirstOrDefault(x => x.Name == state.ActiveClass.Name) as ClassDecl; Contract.Assert(tld != null); var member = tld.Members.FirstOrDefault(x => x.Name == state.TargetMethod.Name) as Method; var body = member?.Body; //subst tactic call with generated code foreach (var kvp in code) { InsertCodeInternal(body.Body, kvp.Value, kvp.Key); } //clean up unfolded tactic call RemoveUnfoldedTacticCalls(body.Body, state); return(body); }
public static IEnumerable <ProofState> EvalPredicateStmt(PredicateStmt predicate, ProofState state) { Contract.Requires <ArgumentNullException>(predicate != null, "predicate"); var newPredicate = SimpExpr.SimpTacticExpr(state, predicate); var copy = state.Copy(); copy.AddStatement(newPredicate); copy.NeedVerify = true; yield return(copy); }
public static Program GenerateResolvedProg0(ProofState state) { var prog = state.GetDafnyProgram(); var r = new Resolver(prog); r.ResolveProgram(prog); //get the generated code var results = new Dictionary <Statement, List <Statement> > { { state.TopLevelTacApp, state.GetGeneratedCode().Copy() } }; var body = InsertCode(state, results); // find the membcl in the resoved prog Method destMd = null; foreach (var m in prog.DefaultModuleDef.TopLevelDecls) { if (m.WhatKind == "class") { var defaultClassDecl = m as DefaultClassDecl; if (defaultClassDecl != null) { foreach (var method in defaultClassDecl.Members) { if (method.FullName == state.TargetMethod.FullName) { destMd = (method as Method); if (destMd != null) { destMd.CallsTactic = 0; destMd.Body.Body.Clear(); destMd.Body.Body.AddRange(body.Body); } }// if some other method has tactic call, then empty the body else if (method.CallsTactic != 0) { method.CallsTactic = 0; var o = method as Method; o?.Body.Body.Clear(); SetVerifyFalseAttr(method); } else { //set other memberdecl as verify false SetVerifyFalseAttr(method); } } } } } // #if _TACTIC_DEBUG_L1 Console.WriteLine("********************* Tactic in : " + destMd + " *****************"); var printer = new Printer(Console.Out); //printer.PrintProgram(prog, false); foreach (var stmt in state.GetGeneratedCode()) { printer.PrintStatement(stmt, 0); Console.WriteLine(""); } Console.WriteLine("********************* Stmts END *****************"); #endif // if (destMd != null) { destMd.CallsTactic = 0; r.SetCurClass(destMd.EnclosingClass as ClassDecl); r.ResolveMethodBody(destMd, state.GetDafnyProgram().DefaultModuleDef.Name); } if (prog.reporter.Count(ErrorLevel.Error) != 0) { state.GetErrHandler().Reporter = prog.reporter; #if _TACTIC_DEBUG_L1 Console.Write("Fail to resolve prog, skip verifier ! \n"); #endif return(null); } else { return(prog); } }
public static Program GenerateResolvedProg(ProofState state) { var prog = state.GetDafnyProgram(); var result = TacnyDriver.GetResultList().Where( kvp => kvp.Key.Tok.pos != state.TopLevelTacApp.Tok.pos).ToDictionary(c => c.Key, c => c.Value); result.Add(state.TopLevelTacApp, state.GetGeneratedCode().Copy()); var body = InsertCode(state, result); Method destMd = null; DefaultClassDecl defaultClassDecl = null; foreach (var m in prog.DefaultModuleDef.TopLevelDecls) { if (m.WhatKind == "class") { var classDecl = m as DefaultClassDecl; if (classDecl != null) { foreach (var method in classDecl.Members) { if (method.Name == state.TargetMethod.Name) { destMd = (method as Method); defaultClassDecl = classDecl; } else if (!(method is Tactic)) { method.CallsTactic = 0; var o = method as Method; if (o != null && o.Body != null) { o?.Body.Body.Clear(); } SetVerifyFalseAttr(method); } } } } } destMd.CallsTactic = 0; destMd.Body.Body.Clear(); destMd.Body.Body.AddRange(body.Body); var r = new Resolver(prog); r.ResolveProgram(prog); if (prog.reporter.Count(ErrorLevel.Error) != 0) { state.GetErrHandler().Reporter = prog.reporter; #if _TACTIC_DEBUG_L1 Console.Write("Fail to resolve prog, skip verifier ! \n"); #endif return(null); } else { return(prog); } }
public static IEnumerable <ProofState> RegisterVariable(TacticVarDeclStmt declaration, ProofState state) { var rhs = declaration.Update as UpdateStmt; if (rhs != null) { foreach (var item in rhs.Rhss) { int index = rhs.Rhss.IndexOf(item); Contract.Assert(declaration.Locals.ElementAtOrDefault(index) != null, "register var err"); var exprRhs = item as ExprRhs; var res = EvalExpr.EvalTacticExpression(state, exprRhs?.Expr); if (res != null) { state.AddTacnyVar(declaration.Locals[index], res); yield return(state); } } } else { var stmt = declaration.Update as AssignSuchThatStmt; if (stmt != null) { foreach (var item in declaration.Locals) { state.AddTacnyVar(item, null); } foreach (var item in EvalSuchThatStmt(stmt, state)) { yield return(item); } } else { foreach (var item in declaration.Locals) { if (state.ContainTVal(item.Name)) { state.ReportTacticError(item.Tok, item.Name + " has already been defined in the current scope."); yield break; } else { state.AddTacnyVar(item, null); } } yield return(state); } } }
public static IEnumerable <ProofState> EvalTopLevelTactic(ProofState state, Dictionary <IVariable, Type> variables, Statement tacticApplication, ApplySuffix aps, ErrorReporterDelegate errorDelegate, bool ifPartial) { Contract.Requires <ArgumentNullException>(Tcce.NonNull(variables)); Contract.Requires <ArgumentNullException>(Tcce.NonNull(tacticApplication)); Contract.Requires <ArgumentNullException>(state != null, "state"); Contract.Requires(tacticApplication == null || tacticApplication is UpdateStmt || tacticApplication is InlineTacticBlockStmt); IEnumerable <ProofState> branches; if (state.InitState(tacticApplication, aps, variables, ifPartial) == false) { return(null); } #if !TACNY_DEBUG try { #endif if (state.GetErrHandler().Reporter.Count(ErrorLevel.Error) != 0) { var errs = CompoundErrorInformation.GenerateErrorInfoList(state); if (errorDelegate != null) { foreach (var err in errs) { errorDelegate(err); } } return(null); } branches = GenerateSolution(state, errorDelegate); #if !TACNY_DEBUG } catch (Exception e) { String msg; List <CompoundErrorInformation> errs; try { msg = "Tactic unknown exception: " + e.Message; errs = CompoundErrorInformation.GenerateErrorInfoList(state, msg); } catch (Exception) { msg = "Tactic exception"; errs = new List <CompoundErrorInformation>(); } if (errorDelegate != null) { foreach (var err in errs) { errorDelegate(err); } } return(null); } #endif return(branches); }
/// <summary> /// /// </summary> /// <param name="rootState"></param> /// <param name="errDelegate"></param> to report err back to GUI /// <returns></returns> internal static IEnumerable <ProofState> GenerateSolution(ProofState rootState, ErrorReporterDelegate errDelegate) { var stack = new Stack <IEnumerator <ProofState> >(); ProofState lastSucc = null; // the last verified state, for recovering over-backtracking var discarded = new List <Tuple <ProofState, VerifyResult> >(); // failed ps and its verified status List <ProofState> proofState = new List <ProofState> () { rootState }; var rootBranches = rootState.EvalStep(); if (rootBranches == null) { yield break; } stack.Push(rootBranches.GetEnumerator()); IEnumerator <ProofState> enumerator = null; List <int> backtrackList = null; while (stack.Count > 0) { bool wasNull = false; if (enumerator != null) { try { if (enumerator.Current == null) { wasNull = true; } } catch { wasNull = true; } } if (enumerator == null || !enumerator.MoveNext()) { // check if current is valid, and the enumerator is empty when current is invalid and MoveNext is null if (enumerator != null && wasNull) { //Console.WriteLine("Null eval result is detected !"); foreach (var state in proofState) { discarded.Add(new Tuple <ProofState, VerifyResult>(state, VerifyResult.Unresolved)); } } enumerator = stack.Pop(); if (!enumerator.MoveNext()) { continue; } } var stateCount = 0; proofState.Clear(); while (stateCount < VerifyNProofState) { var current = enumerator.Current; proofState.Add(current); stateCount++; if (backtrackList != null) { current.SetBackTrackCount(backtrackList); } if (current.NeedVerify && proofState[0].GetVerifyN() > 1) { current.DecreaseVerifyN(); current.NeedVerify = false; } if (!enumerator.MoveNext()) { break; } } //should at least one state in the list, use [0] as a typical state; var rep = proofState[0]; backtrackList = rep.GetBackTrackCount(); List <VerifyResult> ress = null; List <bool> returned = null; //check if any new added coded reuqires to call verifier, or reach the last line of code if ((rep.NeedVerify && rep.GetVerifyN() == 1) || rep.IsCurFrameEvaluated()) { foreach (var s in proofState) { s.ResetVerifyN(); s.NeedVerify = false; } bool backtracked = false; ress = VerifyState(proofState); returned = new List <bool>(); for (var i = 0; i < ress.Count; i++) { var res = ress[i]; var ret = false; switch (res) { case VerifyResult.Verified: //check if the frame are evaluated, as well as requiests for backtraking proofState[i].MarkCurFrameAsTerminated(true, out backtracked); if (backtracked) { lastSucc = proofState[i]; discarded.Add(new Tuple <ProofState, VerifyResult>(proofState[i], VerifyResult.Backtracked)); } if (proofState[i].IsTerminated()) { ret = true; yield return(proofState[i]); } returned.Add(ret); break; case VerifyResult.Failed: if (proofState[i].IsCurFrameEvaluated()) { proofState[i].MarkCurFrameAsTerminated(false, out backtracked); if (backtracked) { lastSucc = proofState[i]; discarded.Add(new Tuple <ProofState, VerifyResult>(proofState[i], VerifyResult.Backtracked)); } if (proofState[i].IsTerminated()) { ret = true; yield return(proofState[i]); } } returned.Add(ret); break; case VerifyResult.Unresolved: //Console.WriteLine("in unresolved"); discarded.Add(new Tuple <ProofState, VerifyResult>(proofState[i], VerifyResult.Unresolved)); //discard current branch if fails to resolve returned.Add(false); continue; default: throw new ArgumentOutOfRangeException(); } } } /* * when failed, check if this method is evaluated , i.e. all tstmt are evalauted, * if so, do nothing will dischard this branch and continue with the next one * otherwise, continue to evaluate the next stmt */ if (!rep.IsCurFrameEvaluated()) { //push the current one to the stack stack.Push(enumerator); //move to the next stmt for (var i = 0; i < proofState.Count; i++) { if (returned == null || !returned[i]) { stack.Push(proofState[i].EvalStep().GetEnumerator()); } } enumerator = stack.Pop(); } else { backtrackList = rep.GetBackTrackCount(); // update the current bc count to the list for (var i = 0; i < proofState.Count; i++) { if (returned == null || !returned[i]) { if (proofState[i].InAsserstion) { proofState[i].GetErrHandler().ErrType = TacticBasicErr.ErrorType.Assertion; var patchRes = proofState[i].ApplyPatch(); if (patchRes != null) { stack.Push(enumerator); enumerator = patchRes.GetEnumerator(); } } else { proofState[i].GetErrHandler().ErrType = TacticBasicErr.ErrorType.NotProved; } discarded.Add(new Tuple <ProofState, VerifyResult>(proofState[i], VerifyResult.Failed)); } } } } //check if over-backchecked if (backtrackList != null && backtrackList.Exists(x => x > 0)) { if (lastSucc == null) { Console.WriteLine("!!! No more branch for the request of " + (backtrackList.Last() + 1) + "backtracking, and no branch."); } else { Console.WriteLine("!!! No more branch for the request of " + lastSucc.GetOrignalTopBacktrack() + ", remaining " + (backtrackList.Last() + 1 > lastSucc.GetOrignalTopBacktrack() ? lastSucc.GetOrignalTopBacktrack() : backtrackList.Last() + 1) + " requests, return the last one."); yield return(lastSucc); } } else { // no result is successful ProofState s0; if (discarded.Count > 0) { s0 = discarded[discarded.Count - 1].Item1; //s0.GetErrHandler().ExceptionReport(); } else { s0 = rootState; } s0.ReportTacticError(s0.TopLevelTacApp.Tok, "No solution is found. \n The error message from the last failed branch: "); var errs = CompoundErrorInformation.GenerateErrorInfoList(s0); if (errDelegate != null) { foreach (var err in errs) { errDelegate(err); } } } }
public static IEnumerable <ProofState> EvalStmt(Statement stmt, ProofState state) { Contract.Requires <ArgumentNullException>(state != null, "state"); IEnumerable <ProofState> enumerable = null; var flowctrls = Assembly.GetAssembly(typeof(Language.TacticFrameCtrl)) .GetTypes().Where(t => t.IsSubclassOf(typeof(Language.TacticFrameCtrl))); foreach (var ctrl in flowctrls) { var porjInst = Activator.CreateInstance(ctrl) as Language.TacticFrameCtrl; if (porjInst?.MatchStmt(stmt, state) == true) { //TODO: validate input countx enumerable = porjInst.EvalInit(stmt, state); } } // no frame control is triggered if (enumerable == null) { if (stmt is TacticVarDeclStmt) { enumerable = RegisterVariable(stmt as TacticVarDeclStmt, state); } else if (stmt is AssignSuchThatStmt) { enumerable = EvalSuchThatStmt((AssignSuchThatStmt)stmt, state); } else if (stmt is PredicateStmt) { enumerable = EvalPredicateStmt((PredicateStmt)stmt, state); } else { var updateStmt = stmt as UpdateStmt; if (updateStmt != null) { var us = updateStmt; if (state.IsLocalAssignment(us)) { enumerable = UpdateLocalValue(us, state); } else if (state.IsArgumentApplication(us)) { //TODO: argument application ?? } else { // apply atomic string sig = Util.GetSignature(us); //Firstly, check if this is a projection function var types = Assembly.GetAssembly(typeof(Atomic.Atomic)) .GetTypes() .Where(t => t.IsSubclassOf(typeof(Atomic.Atomic))); foreach (var fType in types) { var porjInst = Activator.CreateInstance(fType) as Atomic.Atomic; if (sig == porjInst?.Signature) { //TODO: validate input countx enumerable = porjInst?.Generate(us, state); } } } } if (enumerable == null) { // default action as macro enumerable = DefaultAction(stmt, state); } } } return(enumerable); }
public static IEnumerable <ProofState> EvalSuchThatStmt(AssignSuchThatStmt stmt, ProofState state) { var evaluator = new Atomic.SuchThatAtomic(); return(evaluator.Generate(stmt, state)); }
private CompoundErrorInformation(string msg, ErrorInformation e, ProofState s) : base(s.TopLevelTacApp.Tok, msg + " " + e.FullMsg) { this.ImplementationName = e.ImplementationName; S = s; }