Пример #1
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);
        }
Пример #2
0
        public override IEnumerable <ProofState> EvalInit(Statement statement, ProofState state)
        {
            Contract.Assume(statement != null);
            Contract.Assume(statement is TacticForallStmt);

            _stmt = statement as TacticForallStmt;

            Contract.Assert(_stmt != null);

            // do basic simplification
            // maybe do a check and throw an error instead?
            // fixme: error returns null!
            //var e = (ForallExpr) SimpTacticExpr.SimpTacExpr(state0, _stmt.Spec);
            var e = (ForallExpr)SimpExpr.SimpTacticExpr(state, _stmt.Spec);

            // var e = _stmt.Spec as ForallExpr;
            // to rename expressions
            RenameVar rn = new RenameVar();
            // to rename in the body of statement
            RenameVar     rnBody   = new RenameVar();
            List <String> usedVars = state.GetAllDafnyVars().Keys.ToList();

            usedVars.AddRange(state.GetAllTVars().Keys.ToList());

            //List<String> tmp = new List<string>();
            AllVars.DeclaredVars(_stmt.Body.Body[0], ref usedVars);



            if (_stmt.Attributes != null && _stmt.Attributes.Name.Equals("vars"))
            {
                var attrs = _stmt.Attributes.Args;
                for (int i = 0; i < attrs.Count; i++)
                {
                    // todo: should really report an errors if first condition does not hold
                    var segment = attrs[i] as NameSegment;
                    if (segment != null && i < e.BoundVars.Count)
                    {
                        NameSegment ns = segment;
                        String      fv;
                        if (GenFreeVar(ns.Name, usedVars, out fv))
                        {
                            rnBody.AddRename(ns.Name, fv);
                        }
                        rn.AddRename(e.BoundVars[i].Name, fv);
                    } // else we should have an error
                    _vars = new List <BoundVar>();
                    foreach (BoundVar bv in e.BoundVars)
                    {
                        _vars.Add(rn.CloneBoundVar(bv));
                    }
                }
            }
            else
            {
                _vars = e.BoundVars;
            }

            foreach (var tmp in _vars)
            {
                state.AddDafnyVar(tmp.Name, new ProofState.VariableData {
                    Variable = tmp, Type = tmp.Type
                });
            }


            // we could even break  _ens into a set of all conjunctions?
            // what about forall x (forall y) x
            var expr = e.Term as BinaryExpr;

            if (expr != null && (expr.Op.Equals(BinaryExpr.Opcode.Imp)))
            {
                var be = expr;
                _range = rn.CloneExpr(be.E0);
                var t = new MaybeFreeExpression(rn.CloneExpr(be.E1));
                var l = new List <MaybeFreeExpression> {
                    t
                };
                _ens = l;
            }
            else
            {
                _range = new LiteralExpr(_stmt.Tok, true);
                var t = new MaybeFreeExpression(rn.CloneExpr(e.Term));
                var l = new List <MaybeFreeExpression> {
                    t
                };
                _ens = l;
            }

            // Note that we do not need to rename variables in the body (unless the variables in vars is changed)
            InitBasicFrameCtrl(new List <Statement>(), state.IsCurFramePartial(), null, VerifyN);

            state.AddNewFrame(this);

            var bodyFrame = new DefaultTacticFrameCtrl();

            var newBody = rnBody.CloneBlockStmt(_stmt.Body);

            bodyFrame.InitBasicFrameCtrl(newBody.Body, state.IsCurFramePartial(), null, VerifyN);
            bodyFrame.IsPartial = IsPartial;
            state.AddNewFrame(bodyFrame);

            yield return(state);
        }