public override Expression Generate(Expression expr, ProofState proofState) { if (expr is ExprDotName) { var src = Expr.SimpExpr.SimpTacticExpr(proofState, (expr as ExprDotName).Lhs); if (src is NameSegment && proofState.ContainDafnyVar(src as NameSegment)) { var type = proofState.GetDafnyVarType((src as NameSegment).Name); if (type is UserDefinedType) { return(new LiteralExpr(new Boogie.Token(TacnyDriver.TacticCodeTokLine, 0), true)); } } return(new LiteralExpr(new Boogie.Token(TacnyDriver.TacticCodeTokLine, 0), false)); } else { proofState.ReportTacticError(expr.tok, "Illform for \"const?\", expect form in the shape of *.const?"); return(null); } }
public override IEnumerable <ProofState> EvalInit(Statement statement, ProofState state) { Contract.Assume(statement != null); Contract.Assume(statement is TacticCasesBlockStmt); var stmt = statement as TacticCasesBlockStmt; NameSegment caseVar; //get guards Debug.Assert(stmt != null, "stmt != null"); var guard = stmt.Guard as ParensExpression; if (guard == null) { caseVar = stmt.Guard as NameSegment; } else { caseVar = guard.E as NameSegment; } var srcVar = SimpExpr.SimpTacticExpr(state, caseVar) as NameSegment; if (srcVar == null) { state.ReportTacticError(statement.Tok, Printer.ExprToString(caseVar) + " is not a valid variable."); yield break; } var datatype = state.GetDafnyVarType(srcVar.Name).AsDatatype; if (datatype == null) { state.ReportTacticError(statement.Tok, Printer.ExprToString(caseVar) + " is not an inductive datatype variable."); yield break; } if (statement.Attributes != null && statement.Attributes.Name.Equals("vars")) { _nameVars = new List <string>(); var attrs = statement.Attributes.Args; foreach (var attr in attrs) { var segment = attr as NameSegment; if (segment != null && !state.ContainDafnyVar(segment)) { _nameVars.Add(segment.Name); } } } //generate a test program to check which cases need to apply tacny bool[] ctorFlags; InitCtorFlags(datatype, out ctorFlags); List <Func <int, List <Statement> > > fList = new List <Func <int, List <Statement> > >(); int i; for (i = 0; i < datatype.Ctors.Count; i++) { fList.Add(GenerateAssumeFalseStmtAsStmtList); } //var matchStmt = GenerateMatchStmt(state.TacticApplication.Tok.line, srcVar.Copy(), datatype, fList); var matchStmt = GenerateMatchStmt(TacnyDriver.TacticCodeTokLine, srcVar.Copy(), datatype, fList); _matchStmt = matchStmt; var matchCtrl = this; //use a dummystmt to creat a frame for match, note that this stmts is never be evaluated var dummystmt = new List <Statement>(); dummystmt.Add(stmt); dummystmt.Add(stmt); _matchStmt = matchStmt; matchCtrl.InitBasicFrameCtrl(dummystmt, state.IsCurFramePartial(), null, VerifyN); state.AddNewFrame(matchCtrl); //push a frame for the first case var caseCtrl = new DefaultTacticFrameCtrl(); caseCtrl.InitBasicFrameCtrl(stmt.Body.Body, state.IsCurFramePartial(), null, VerifyN); state.AddNewFrame(caseCtrl); foreach (var tmp in matchStmt.Cases[0].CasePatterns) { state.AddDafnyVar(tmp.Var.Name, new ProofState.VariableData { Variable = tmp.Var, Type = tmp.Var.Type }); } //with this flag set to true, dafny will check the case brnach before evaluates any tacny code state.NeedVerify = true; yield return(state); }
public override IEnumerable<ProofState> Generate(Statement statement, ProofState state) { List<List<IVariable>> args = new List<List<IVariable>>(); List<IVariable> mdIns = new List<IVariable>(); List<Expression> callArguments; IVariable lv; InitArgs(state, statement, out lv, out callArguments); state.IfVerify = true; //TODO: implement this properly //var members = state.GetLocalValue(callArguments[0] as NameSegment) as IEnumerable<MemberDecl>; //evaluate the argument (methods/lemma) var members0 = Interpreter.EvalTacnyExpression(state, callArguments[0]).GetEnumerator(); members0.MoveNext(); var members = members0.Current as List<MemberDecl>; if (members == null){ yield break; } foreach(var member in members) { MemberDecl md; mdIns.Clear(); args.Clear(); if(member is NameSegment) { //TODO: Console.WriteLine("double check this"); md = null; // md = state.GetDafnyProgram(). Members.FirstOrDefault(i => i.Key == (member as NameSegment)?.Name).Value; } else { md = member as MemberDecl; } // take the membed decl parameters var method = md as Method; if(method != null) mdIns.AddRange(method.Ins); else if(md is Microsoft.Dafny.Function) mdIns.AddRange(((Microsoft.Dafny.Function)md).Formals); else Contract.Assert(false, "In Explore Atomic call," + callArguments[0] + "is neither a Method or a Function"); //evaluate the arguemnts for the lemma to be called var instArgs = Interpreter.EvalTacnyExpression(state, callArguments[1]); foreach(var ovars in instArgs) { Contract.Assert(ovars != null, "In Explore Atomic call," + callArguments[1] + "is not variable"); List<IVariable> vars = ovars as List<IVariable> ?? new List<IVariable>(); //Contract.Assert(vars != null, Util.Error.MkErr(call_arguments[0], 1, typeof(List<IVariable>))); //for the case when no args, just add an empty list if (mdIns.Count == 0){ args.Add(new List<IVariable>()); } for(int i = 0; i < mdIns.Count; i++) { var item = mdIns[i]; args.Add(new List<IVariable>()); foreach(var arg in vars) { // get variable type Type type = state.GetDafnyVarType(arg.Name); if(type != null) { if(type is UserDefinedType && item.Type is UserDefinedType) { var udt1 = type as UserDefinedType; var udt2 = item.Type as UserDefinedType; if(udt1.Name == udt2.Name) args[i].Add(arg); } else { // if variable type and current argument types match, or the type is yet to be inferred if(item.Type.ToString() == type.ToString() || type is InferredTypeProxy) args[i].Add(arg); } } else args[i].Add(arg); } /** * if no type correct variables have been added we can safely return * because we won't be able to generate valid calls */ if(args[i].Count == 0) { Debug.WriteLine("No type matching variables were found"); yield break; } } foreach(var result in PermuteArguments(args, 0, new List<NameSegment>())) { // create new fresh list of items to remove multiple references to the same object List<Expression> newList = result.Cast<Expression>().ToList().Copy(); //TODO: need to double check wirh Vito, why can't use copy ? //Util.Copy.CopyExpressionList(result.Cast<Expression>().ToList()); ApplySuffix aps = new ApplySuffix(callArguments[0].tok, new NameSegment(callArguments[0].tok, md.Name, null), newList); if(lv != null) { var newState = state.Copy(); newState.AddTacnyVar(lv, aps); yield return newState; } else { var newState = state.Copy(); UpdateStmt us = new UpdateStmt(aps.tok, aps.tok, new List<Expression>(), new List<AssignmentRhs> { new ExprRhs(aps) }); //Printer p = new Printer(Console.Out); //p.PrintStatement(us,0); newState.AddStatement(us); yield return newState; } } } } }
public override IEnumerable <ProofState> Generate(Statement statement, ProofState state) { List <List <IVariable> > args = new List <List <IVariable> >(); List <IVariable> mdIns = new List <IVariable>(); List <Expression> callArguments; IVariable lv; InitArgs(state, statement, out lv, out callArguments); state.IfVerify = true; //TODO: implement this properly //var members = state.GetLocalValue(callArguments[0] as NameSegment) as IEnumerable<MemberDecl>; //evaluate the argument (methods/lemma) var members0 = Interpreter.EvalTacnyExpression(state, callArguments[0]).GetEnumerator(); members0.MoveNext(); var members = members0.Current as List <MemberDecl>; if (members == null) { yield break; } foreach (var member in members) { MemberDecl md; mdIns.Clear(); args.Clear(); if (member is NameSegment) { //TODO: Console.WriteLine("double check this"); md = null; // md = state.GetDafnyProgram(). Members.FirstOrDefault(i => i.Key == (member as NameSegment)?.Name).Value; } else { md = member as MemberDecl; } // take the membed decl parameters var method = md as Method; if (method != null) { mdIns.AddRange(method.Ins); } else if (md is Microsoft.Dafny.Function) { mdIns.AddRange(((Microsoft.Dafny.Function)md).Formals); } else { Contract.Assert(false, "In Explore Atomic call," + callArguments[0] + "is neither a Method or a Function"); } //evaluate the arguemnts for the lemma to be called var instArgs = Interpreter.EvalTacnyExpression(state, callArguments[1]); foreach (var ovars in instArgs) { Contract.Assert(ovars != null, "In Explore Atomic call," + callArguments[1] + "is not variable"); List <IVariable> vars = ovars as List <IVariable> ?? new List <IVariable>(); //Contract.Assert(vars != null, Util.Error.MkErr(call_arguments[0], 1, typeof(List<IVariable>))); //for the case when no args, just add an empty list if (mdIns.Count == 0) { args.Add(new List <IVariable>()); } for (int i = 0; i < mdIns.Count; i++) { var item = mdIns[i]; args.Add(new List <IVariable>()); foreach (var arg in vars) { // get variable type Type type = state.GetDafnyVarType(arg.Name); if (type != null) { if (type is UserDefinedType && item.Type is UserDefinedType) { var udt1 = type as UserDefinedType; var udt2 = item.Type as UserDefinedType; if (udt1.Name == udt2.Name) { args[i].Add(arg); } } else { // if variable type and current argument types match, or the type is yet to be inferred if (item.Type.ToString() == type.ToString() || type is InferredTypeProxy) { args[i].Add(arg); } } } else { args[i].Add(arg); } } /** * if no type correct variables have been added we can safely return * because we won't be able to generate valid calls */ if (args[i].Count == 0) { Debug.WriteLine("No type matching variables were found"); yield break; } } foreach (var result in PermuteArguments(args, 0, new List <NameSegment>())) { // create new fresh list of items to remove multiple references to the same object List <Expression> newList = result.Cast <Expression>().ToList().Copy(); //TODO: need to double check wirh Vito, why can't use copy ? //Util.Copy.CopyExpressionList(result.Cast<Expression>().ToList()); ApplySuffix aps = new ApplySuffix(callArguments[0].tok, new NameSegment(callArguments[0].tok, md.Name, null), newList); if (lv != null) { var newState = state.Copy(); newState.AddTacnyVar(lv, aps); yield return(newState); } else { var newState = state.Copy(); UpdateStmt us = new UpdateStmt(aps.tok, aps.tok, new List <Expression>(), new List <AssignmentRhs> { new ExprRhs(aps) }); //Printer p = new Printer(Console.Out); //p.PrintStatement(us,0); newState.AddStatement(us); yield return(newState); } } } } }
public override IEnumerable <ProofState> Generate(Statement statement, ProofState state) { List <List <IVariable> > args = new List <List <IVariable> >(); List <IVariable> mdIns = new List <IVariable>(); List <Expression> callArguments; bool branchGenerated = false; state.NeedVerify = true; InitArgs(state, statement, out callArguments); /********************** * init lemmas **********************/ //check the number of arguments if (callArguments == null || callArguments.Count != 2) { state.ReportTacticError(statement.Tok, " The number of arguments for explore is not correct, expect 2."); yield break; } // get the first arg: a sequence of lemmas var members0 = EvalExpr.EvalTacticExpression(state, callArguments[0]) as SeqDisplayExpr; if (members0 == null) { state.ReportTacticError(statement.Tok, Printer.ExprToString(callArguments[0]) + " is not a sequence."); yield break; } List <MemberDecl> members = new List <MemberDecl>(); foreach (var mem in members0.Elements) { if (!(mem is TacticLiteralExpr)) { state.ReportTacticError(statement.Tok, "In " + Printer.ExprToString(callArguments[0]) + Printer.ExprToString(mem) + " is not a lemma."); yield break; } var key = (string)(mem as TacticLiteralExpr).Value; if (state.Members.ContainsKey(key)) { members.Add(state.Members[key]); } else { state.ReportTacticError(statement.Tok, "In " + Printer.ExprToString(callArguments[0]) + ", " + key + " is not a lemma."); yield break; } } if (members.Count == 0) { branchGenerated = true; yield return(state); yield break; } foreach (var member in members) { mdIns.Clear(); args.Clear(); var md = (MemberDecl)member; // take the membed decl parameters var method = md as Method; if (method != null) { mdIns.AddRange(method.Ins); } else if (md is Function) { mdIns.AddRange(((Function)md).Formals); } else { state.ReportTacticError(statement.Tok, Printer.ExprToString(callArguments[0]) + " is neither a Method or a Function"); yield break; } /********************** * init args for lemmas **********************/ var ovars = EvalExpr.EvalTacticExpression(state, callArguments[1]) as SeqDisplayExpr; if (ovars == null) { state.ReportTacticError(statement.Tok, Printer.ExprToString(callArguments[1]) + " is not a sequence."); yield break; } List <IVariable> vars = new List <IVariable>(); foreach (var var in ovars.Elements) { string key; if (var is TacticLiteralExpr) { key = (string)(var as TacticLiteralExpr).Value; } else if (var is NameSegment) { key = (var as NameSegment).Name; } else { state.ReportTacticError(statement.Tok, "In " + Printer.ExprToString(callArguments[1]) + ", " + Printer.ExprToString(var) + " is not a dafny variable."); yield break; } if (state.GetAllDafnyVars().ContainsKey(key)) { vars.Add(state.GetAllDafnyVars()[key].Variable); } else { state.ReportTacticError(statement.Tok, "In " + Printer.ExprToString(callArguments[1]) + ", " + key + " is not in scope."); yield break; } } //for the case of no args, just add an empty list if (mdIns.Count == 0) { args.Add(new List <IVariable>()); } //if any of the arguements is not valid, set it to false. bool flag = true; for (int i = 0; i < mdIns.Count; i++) { var item = mdIns[i]; args.Add(new List <IVariable>()); foreach (var arg in vars) { // get variable type Type type = state.GetDafnyVarType(arg.Name); if (type != null) { if (type is UserDefinedType && item.Type is UserDefinedType) { var udt1 = type as UserDefinedType; var udt2 = (UserDefinedType)item.Type; if (udt1.Name == udt2.Name) { args[i].Add(arg); } } else { // if variable type and current argument types match, or the type is yet to be inferred if (item.Type.ToString() == type.ToString() || type is InferredTypeProxy) { args[i].Add(arg); } } } else { args[i].Add(arg); } } /** * if no type correct variables have been added we can return * because we won't be able to generate valid calls */ if (args[i].Count == 0) { flag = false; } } // permute lemma call for the current lemma if (flag) { foreach (var result in PermuteArguments(args, 0, new List <NameSegment>())) { // create new fresh list of items to remove multiple references to the same object List <Expression> newList = result.Cast <Expression>().ToList().Copy(); ApplySuffix aps = new ApplySuffix(callArguments[0].tok, new NameSegment(callArguments[0].tok, md.Name, null), newList); var newState = state.Copy(); UpdateStmt us = new UpdateStmt(aps.tok, aps.tok, new List <Expression>(), new List <AssignmentRhs> { new ExprRhs(aps) }); newState.AddStatement(us); branchGenerated = true; yield return(newState); } } } // for the case when no lemma call is generated. if (!branchGenerated) { yield return(state); } }