コード例 #1
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);
        }