Example #1
0
    public virtual Statement CloneStmt(Statement stmt) {
      if (stmt == null) {
        return null;
      }

      Statement r;
      if (stmt is AssertStmt) {
        var s = (AssertStmt)stmt;
        r = new AssertStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Expr), null);

      } else if (stmt is AssumeStmt) {
        var s = (AssumeStmt)stmt;
        r = new AssumeStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Expr), null);
      } else if (stmt is TacticInvariantStmt) {
        var s = (TacticInvariantStmt)stmt;
        r = new TacticInvariantStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Expr), null, s.IsObjectLevel);
      } else if (stmt is TacticAssertStmt) {
        var s = (TacticAssertStmt)stmt;
        r = new TacticAssertStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Expr), null, s.IsObjectLevel);
      } else if (stmt is PrintStmt) {
        var s = (PrintStmt)stmt;
        r = new PrintStmt(Tok(s.Tok), Tok(s.EndTok), s.Args.ConvertAll(CloneExpr));
      } else if (stmt is BreakStmt) {
        var s = (BreakStmt)stmt;
        if (s.TargetLabel != null) {
          r = new BreakStmt(Tok(s.Tok), Tok(s.EndTok), s.TargetLabel);
        } else {
          r = new BreakStmt(Tok(s.Tok), Tok(s.EndTok), s.BreakCount);
        }

      } else if (stmt is ReturnStmt) {
        var s = (ReturnStmt)stmt;
        r = new ReturnStmt(Tok(s.Tok), Tok(s.EndTok), s.rhss == null ? null : s.rhss.ConvertAll(CloneRHS));

      } else if (stmt is YieldStmt) {
        var s = (YieldStmt)stmt;
        r = new YieldStmt(Tok(s.Tok), Tok(s.EndTok), s.rhss == null ? null : s.rhss.ConvertAll(CloneRHS));

      } else if (stmt is AssignStmt) {
        var s = (AssignStmt)stmt;
        r = new AssignStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Lhs), CloneRHS(s.Rhs));

      } else if (stmt is BlockStmt) {
        r = CloneBlockStmt((BlockStmt)stmt);

      } else if (stmt is IfStmt) {
        var s = (IfStmt)stmt;
        r = new IfStmt(Tok(s.Tok), Tok(s.EndTok), s.IsExistentialGuard, CloneExpr(s.Guard), CloneBlockStmt(s.Thn), CloneStmt(s.Els));

      } else if (stmt is AlternativeStmt) {
        var s = (AlternativeStmt)stmt;
        r = new AlternativeStmt(Tok(s.Tok), Tok(s.EndTok), s.Alternatives.ConvertAll(CloneGuardedAlternative));

      } else if (stmt is WhileStmt) {
        var s = (WhileStmt)stmt;
        r = new WhileStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Guard), s.Invariants.ConvertAll(CloneMayBeFreeExpr), CloneSpecExpr(s.Decreases), CloneSpecFrameExpr(s.Mod), CloneBlockStmt(s.Body));
        ((WhileStmt)r).TacAps = s.TacAps;
      } else if (stmt is AlternativeLoopStmt) {
        var s = (AlternativeLoopStmt)stmt;
        r = new AlternativeLoopStmt(Tok(s.Tok), Tok(s.EndTok), s.Invariants.ConvertAll(CloneMayBeFreeExpr), CloneSpecExpr(s.Decreases), CloneSpecFrameExpr(s.Mod), s.Alternatives.ConvertAll(CloneGuardedAlternative));

      } else if (stmt is ForallStmt) {
        var s = (ForallStmt)stmt;
        r = new ForallStmt(Tok(s.Tok), Tok(s.EndTok), s.BoundVars.ConvertAll(CloneBoundVar), null, CloneExpr(s.Range), s.Ens.ConvertAll(CloneMayBeFreeExpr), CloneStmt(s.Body));
        if (s.ForallExpressions != null) {
          ((ForallStmt)r).ForallExpressions = s.ForallExpressions.ConvertAll(CloneExpr);
        }
      } else if (stmt is CalcStmt) {
        var s = (CalcStmt)stmt;
        // calc statements have the unusual property that the last line is duplicated.  If that is the case (which
        // we expect it to be here), we share the clone of that line as well.
        var lineCount = s.Lines.Count;
        var lines = new List<Expression>(lineCount);
        for (int i = 0; i < lineCount; i++) {
          lines.Add(i == lineCount - 1 && 2 <= lineCount && s.Lines[i] == s.Lines[i - 1] ? lines[i - 1] : CloneExpr(s.Lines[i]));
        }
        Contract.Assert(lines.Count == lineCount);
        r = new CalcStmt(Tok(s.Tok), Tok(s.EndTok), CloneCalcOp(s.Op), lines, s.Hints.ConvertAll(CloneBlockStmt), s.StepOps.ConvertAll(CloneCalcOp), CloneCalcOp(s.ResultOp), CloneAttributes(s.Attributes));

      } else if (stmt is MatchStmt) {
        var s = (MatchStmt)stmt;
        r = new MatchStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Source),
        s.Cases.ConvertAll(CloneMatchCaseStmt), s.UsesOptionalBraces);

      } else if (stmt is AssignSuchThatStmt) {
        var s = (AssignSuchThatStmt)stmt;
        r = new AssignSuchThatStmt(Tok(s.Tok), Tok(s.EndTok), s.Lhss.ConvertAll(CloneExpr), CloneExpr(s.Expr), s.AssumeToken == null ? null : Tok(s.AssumeToken), null);

      } else if (stmt is UpdateStmt) {
        var s = (UpdateStmt)stmt;
        r = new UpdateStmt(Tok(s.Tok), Tok(s.EndTok), s.Lhss.ConvertAll(CloneExpr), s.Rhss.ConvertAll(CloneRHS), s.CanMutateKnownState);

      } else if (stmt is VarDeclStmt) {
        var s = (VarDeclStmt)stmt;
        var lhss = s.Locals.ConvertAll(c => new LocalVariable(Tok(c.Tok), Tok(c.EndTok), c.Name, CloneType(c.OptionalType), c.IsGhost));
        r = new VarDeclStmt(Tok(s.Tok), Tok(s.EndTok), lhss, (ConcreteUpdateStatement)CloneStmt(s.Update));
      } else if (stmt is LetStmt) {
        var s = (LetStmt)stmt;
        r = new LetStmt(Tok(s.Tok), Tok(s.EndTok), s.LHSs.ConvertAll(CloneCasePattern), s.RHSs.ConvertAll(CloneExpr));
      } else if (stmt is ModifyStmt) {
        var s = (ModifyStmt)stmt;
        var mod = CloneSpecFrameExpr(s.Mod);
        var body = s.Body == null ? null : CloneBlockStmt(s.Body);
        r = new ModifyStmt(Tok(s.Tok), Tok(s.EndTok), mod.Expressions, mod.Attributes, body);
      } else if (stmt is TacnyCasesBlockStmt) {
        var s = (TacnyCasesBlockStmt)stmt;
        var guard = CloneExpr(s.Guard);
        var body = s.Body == null ? null : CloneBlockStmt(s.Body);
        r = new TacnyCasesBlockStmt(Tok(s.Tok), Tok(s.EndTok), guard, body);
      } else if (stmt is TacnyChangedBlockStmt) {
        var s = (TacnyChangedBlockStmt)stmt;
        var body = s.Body == null ? null : CloneBlockStmt(s.Body);
        r = new TacnyChangedBlockStmt(Tok(s.Tok), Tok(s.EndTok), body);
      } else if (stmt is TacnySolvedBlockStmt) {
        var s = (TacnySolvedBlockStmt)stmt;
        var body = s.Body == null ? null : CloneBlockStmt(s.Body);
        r = new TacnySolvedBlockStmt(Tok(s.Tok), Tok(s.EndTok), body);
      } else if (stmt is TacnyTryCatchBlockStmt) {
        var s = (TacnyTryCatchBlockStmt)stmt;
        var body = s.Body == null ? null : CloneBlockStmt(s.Body);
        var c = s.Ctch == null ? null : CloneBlockStmt(s.Ctch);
        r = new TacnyTryCatchBlockStmt(Tok(s.Tok), Tok(s.EndTok), body, c);
      } else if (stmt is TacticVarDeclStmt) {
        var s = (TacticVarDeclStmt)stmt;
        var lhss = s.Locals.ConvertAll(c => new LocalVariable(Tok(c.Tok), Tok(c.EndTok), c.Name, CloneType(c.OptionalType), c.IsGhost));
        r = new TacticVarDeclStmt(Tok(s.Tok), Tok(s.EndTok), lhss, (ConcreteUpdateStatement)CloneStmt(s.Update));
      } else {
        Contract.Assert(false); throw new cce.UnreachableException();  // unexpected statement
      }

      // add labels to the cloned statement
      AddStmtLabels(r, stmt.Labels);
      r.Attributes = CloneAttributes(stmt.Attributes);

      return r;
    }
Example #2
0
    void TacnyCasesBlockStmt(out Statement/*!*/ tacnyCasesStmt, IToken x) {
      Contract.Ensures(Contract.ValueAtReturn(out tacnyCasesStmt) != null);
      Expression guard = null;
      IToken guardEllipsis = null;
      BlockStmt/*!*/ thn;
      Attributes attrs = null;
      IToken bodyStart, bodyEnd, endTok;
      List<GuardedAlternative> alternatives;
      tacnyCasesStmt = dummyStmt;  // to please the compiler

      if(IsAlternative()) {
        AlternativeBlock(true, out alternatives, out endTok);
        tacnyCasesStmt = new AlternativeStmt(x, endTok, alternatives);
      } else if(StartOf(22)) {
        if(StartOf(23)) {
          Guard(out guard);
        } else {
          Get();
          guardEllipsis = t;
        }
        while(IsAttribute()) {
          Attribute(ref attrs);
        }
        BlockStmt(out thn, out bodyStart, out bodyEnd);
        endTok = thn.EndTok;
        if(guardEllipsis != null) {
          tacnyCasesStmt = new SkeletonStatement(new TacnyCasesBlockStmt(x, endTok, guard, attrs, thn), guardEllipsis, null);
        } else {
          tacnyCasesStmt = new TacnyCasesBlockStmt(x, endTok, guard, attrs, thn);
        }

      } else
        SynErr(217);
    }
Example #3
0
        private Solution GenerateVerifiedStmt(DatatypeDecl datatype, NameSegment casesGuard, TacnyCasesBlockStmt st)
        {
            bool[] ctorFlags;
            int    ctor; // current active match case

            InitCtorFlags(datatype, out ctorFlags);
            List <Solution> ctorBodies = RepeatedDefault <Solution>(datatype.Ctors.Count);
            // find the first failing case
            MatchStmt ms       = GenerateMatchStmt(DynamicContext.tac_call.Tok.line, Util.Copy.CopyNameSegment(casesGuard), datatype, ctorBodies);
            Solution  solution = CreateSolution(this, ms);

            if (!ResolveAndVerify(solution))
            {
                ctor = 0;
            }
            else
            {
                ctor = GetErrorIndex(StaticContext.program.GetErrorToken(), ms);
                // the error is occuring outside the match stmt
                if (ctor == -1)
                {
                    ms = GenerateMatchStmt(DynamicContext.tac_call.Tok.line, Util.Copy.CopyNameSegment(casesGuard), datatype, ctorBodies);
                    return(CreateSolution(this, ms));
                }
                ctorFlags[ctor] = true;
                _oldToken       = StaticContext.program.GetErrorToken();
            }
            while (ctor < datatype.Ctors.Count)
            {
                if (!StaticContext.program.HasError())
                {
                    break;
                }
                RegisterLocals(datatype, ctor, _ctorTypes);

                // if nothing was generated for the cases body move on to the next one
                foreach (var result in ResolveBody(st.Body))
                {
                    ctorBodies[ctor] = result;
                    ms       = GenerateMatchStmt(DynamicContext.tac_call.Tok.line, Util.Copy.CopyNameSegment(casesGuard), datatype, ctorBodies);
                    solution = CreateSolution(this, ms);
                    // if the program fails tro resolve skip
                    if (!ResolveAndVerify(solution))
                    {
                        continue;
                    }

                    if (!StaticContext.program.HasError())
                    {
                        break;
                    }
                    if (CheckError(ms, ref ctorFlags, ctor))
                    {
                        // if the ctor does not require a body null the value
                        if (!ctorFlags[ctor])
                        {
                            ctorBodies[ctor] = null;
                        }
                        break;
                    }
                }
                // clear local var
                RemoveLocals(datatype, ctor);
                ctor++;
            }

            ms = GenerateMatchStmt(DynamicContext.tac_call.Tok.line, Util.Copy.CopyNameSegment(casesGuard), datatype, ctorBodies);
            return(CreateSolution(this, ms));
        }
Example #4
0
        private IEnumerable <Solution> GenerateMatch(TacnyCasesBlockStmt st)
        {
            NameSegment     casesGuard;
            UserDefinedType datatypeType = null;
            var             isElement    = false;

            var guard = st.Guard as ParensExpression;

            if (guard == null)
            {
                casesGuard = st.Guard as NameSegment;
            }
            else
            {
                casesGuard = guard.E as NameSegment;
            }

            Contract.Assert(casesGuard != null, Error.MkErr(st, 2));

            IVariable tacInput = GetLocalKeyByName(casesGuard);

            Contract.Assert(tacInput != null, Error.MkErr(st, 9, casesGuard.Name));


            if (!(tacInput is Formal))
            {
                tacInput = GetLocalValueByName(casesGuard) as IVariable;
                Contract.Assert(tacInput != null, Error.MkErr(st, 9, casesGuard.Name));
                // the original
                if (tacInput != null)
                {
                    casesGuard = new NameSegment(tacInput.Tok, tacInput.Name, null);
                }
            }
            else
            {
                // get the original declaration inside the method
                casesGuard = GetLocalValueByName(tacInput) as NameSegment;
            }
            string datatypeName = tacInput?.Type.ToString();

            /**
             * TODO cleanup
             * if datatype is Element lookup the formal in global variable registry
             */

            if (datatypeName == "Element")
            {
                isElement = true;
                var val  = GetLocalValueByName(tacInput.Name);
                var decl = val as NameSegment;
                Contract.Assert(decl != null, Error.MkErr(st, 9, tacInput.Name));

                var originalDecl = StaticContext.GetGlobalVariable(decl?.Name);
                if (originalDecl != null)
                {
                    datatypeType = originalDecl.Type as UserDefinedType;
                    datatypeName = datatypeType != null ? datatypeType.Name : originalDecl.Type.ToString();
                }
                else
                {
                    Contract.Assert(false, Error.MkErr(st, 9, tacInput.Name));
                }
            }

            if (!StaticContext.ContainsGlobalKey(datatypeName))
            {
                Contract.Assert(false, Error.MkErr(st, 12, datatypeName));
            }

            var datatype = StaticContext.GetGlobal(datatypeName);

            if (datatype.TypeArgs != null)
            {
                _ctorTypes = new Dictionary <string, Type>();

                if (datatype.TypeArgs.Count == datatypeType.TypeArgs.Count)
                {
                    for (int i = 0; i < datatype.TypeArgs.Count; i++)
                    {
                        var genericType = datatype.TypeArgs[i];
                        var definedType = datatypeType.TypeArgs[i];
                        _ctorTypes.Add(genericType.Name, definedType);
                    }
                }
            }

            if (isElement)
            {
                yield return(GenerateVerifiedStmt(datatype, casesGuard, st));
            }
            else
            {
                foreach (var item in GenerateStmt(datatype, casesGuard, st))
                {
                    yield return(item);
                }
            }
        }
Example #5
0
        /// <summary>
        /// TODO: Resolve the bodies lazily
        /// </summary>
        /// <param name="datatype"></param>
        /// <param name="casesGuard"></param>
        /// <param name="st"></param>
        /// <returns></returns>
        private IEnumerable <Solution> GenerateStmt(DatatypeDecl datatype, NameSegment casesGuard, TacnyCasesBlockStmt st)
        {
            List <List <Solution> > allCtorBodies = Repeated(new List <Solution>(), datatype.Ctors.Count);
            int ctor = 0;

            foreach (var list in allCtorBodies)
            {
                list.Add(null);

                RegisterLocals(datatype, ctor);
                foreach (var result in ResolveBody(st.Body))
                {
                    list.Add(result);
                }

                RemoveLocals(datatype, ctor);
                ctor++;
            }

            foreach (var stmt in GenerateAllMatchStmt(DynamicContext.tac_call.Tok.line, 0, Util.Copy.CopyNameSegment(casesGuard), datatype, allCtorBodies, new List <Solution>()))
            {
                yield return(CreateSolution(this, stmt));
            }
        }