Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
    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;
            }
          }
        }
      }
    }
Beispiel #4
0
        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);
                        }
                    }
                }
            }
        }
Beispiel #5
0
        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);
            }
        }