Ejemplo n.º 1
0
        private bool TryComputeNAryExprs(IdentifierExpr id)
        {
            var toRemove = new HashSet <Expr>();

            foreach (var expr in this.ExpressionMap[id].Keys.ToList())
            {
                if (!(expr is NAryExpr))
                {
                    continue;
                }

                int ixs = 0;

                if (((expr as NAryExpr).Args[0] is IdentifierExpr) &&
                    ((expr as NAryExpr).Args[0] as IdentifierExpr).Name.StartsWith("$M."))
                {
                    toRemove.Add(expr);
                    continue;
                }

                if (PointerAnalysis.ShouldSkipFromAnalysis(expr as NAryExpr))
                {
                    toRemove.Add(expr);
                    continue;
                }

                if (PointerAnalysis.IsArithmeticExpression(expr as NAryExpr))
                {
                    toRemove.Add(expr);
                    continue;
                }

                Expr p = (expr as NAryExpr).Args[0];
                Expr i = (expr as NAryExpr).Args[1];
                Expr s = (expr as NAryExpr).Args[2];

                if (!(i is LiteralExpr && s is LiteralExpr))
                {
                    toRemove.Add(expr);
                    continue;
                }

                ixs = (i as LiteralExpr).asBigNum.ToInt * (s as LiteralExpr).asBigNum.ToInt;

                this.ExpressionMap[id].Add(p, this.ExpressionMap[id][expr] + ixs);
                toRemove.Add(expr);
            }

            foreach (var expr in toRemove)
            {
                this.ExpressionMap[id].Remove(expr);
            }

            if (this.ExpressionMap[id].Any(val => val.Key is NAryExpr))
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 2
0
        internal bool IsAxiom(IdentifierExpr expr)
        {
            bool result = false;

            if (expr == null)
            {
                return(result);
            }

            foreach (var axiom in this.AC.TopLevelDeclarations.OfType <Axiom>())
            {
                Expr axiomExpr = null;
                if (axiom.Expr is NAryExpr)
                {
                    axiomExpr = (axiom.Expr as NAryExpr).Args[0];
                }
                else
                {
                    axiomExpr = axiom.Expr;
                }

                if (axiomExpr.ToString().Equals(expr.Name))
                {
                    result = true;
                    break;
                }
            }

            return(result);
        }
Ejemplo n.º 3
0
        public void SimpleForAllWithTrigger()
        {
            var builder  = GetSimpleBuilder();
            var freeVarX = GetVariable("x", BasicType.Int);
            var xid      = new IdentifierExpr(Token.NoToken, freeVarX);

            var fb       = new FunctionCallBuilder();
            var funcCall = fb.CreateUninterpretedFunctionCall("f", BPLType.Int, new List <BPLType>()
            {
                BPLType.Int
            });
            var body = builder.Gt(builder.UFC(funcCall, xid), xid);

            // Single trigger
            var triggers = new Microsoft.Boogie.Trigger(Token.NoToken,
                                                        /*positive=*/ true,
                                                        new List <Expr>()
            {
                builder.UFC(funcCall, xid)
            }, null);

            var result = builder.ForAll(new List <Variable>()
            {
                freeVarX
            }, body, triggers);

            Assert.AreEqual("(forall x: int :: { f(x) } f(x) > x)", result.ToString());
            CheckIsBoolType(result);
        }
Ejemplo n.º 4
0
 public VarDefinitionStmt(IdentifierExpr name, IdentifierExpr type, bool isConst, Expression initialValue)
 {
     _name         = name;
     _type         = type;
     _isConst      = isConst;
     _initialValue = initialValue;
 }
Ejemplo n.º 5
0
        public override Expr VisitIdentifierExpr(IdentifierExpr node)
        {
            if (node.Decl is GlobalVariable)
            {
                if (!canAccessSharedVars)
                {
                    Error(node, "Shared variable can be accessed only in atomic actions or specifications");
                }
                else if (this.globalVarToSharedVarInfo.ContainsKey(node.Decl))
                {
                    if (this.globalVarToSharedVarInfo[node.Decl].hideLayerNum < minLayerNum)
                    {
                        minLayerNum = this.globalVarToSharedVarInfo[node.Decl].hideLayerNum;
                    }
                    if (this.globalVarToSharedVarInfo[node.Decl].introLayerNum > maxLayerNum)
                    {
                        maxLayerNum = this.globalVarToSharedVarInfo[node.Decl].introLayerNum;
                    }
                }
                else
                {
                    Error(node, "Accessed shared variable must have layer annotation");
                }
            }
            else if (node.Decl is LocalVariable && ghostVars.Contains(node.Decl) && !canAccessGhostVars)
            {
                Error(node, "Ghost variable can be accessed only in assertions");
            }

            return(base.VisitIdentifierExpr(node));
        }
 private Expr ElimPendingAsyncExpr(IdentifierExpr pa)
 {
     return(Expr.And(
                Expr.Or(elim.Keys.Select(a => ExprHelper.FunctionCall(a.pendingAsyncCtor.membership, pa))),
                Expr.Gt(Expr.Select(PAs, pa), Expr.Literal(0))
                ));
 }
Ejemplo n.º 7
0
            public void FunctionCallCallsVisitOnAllParametersPassedTest()
            {
                var target = new EvaluateVisitor();

                var functionName     = RandomGenerator.String();
                var functionNameExpr = new IdentifierExpr(functionName);

                var parameters = new[]
                {
                    new VarDefinitionStmt(new IdentifierExpr("A"), new IdentifierExpr("INT"), false, new ConstantExpr(1)),
                    new VarDefinitionStmt(new IdentifierExpr("B"), new IdentifierExpr("STRING"), false, new ConstantExpr("TEST")),
                    new VarDefinitionStmt(new IdentifierExpr("C"), new IdentifierExpr("BOOL"), false, new ConstantExpr(true))
                };

                var values = new Expression[]
                {
                    new ConstantExpr(1),
                    new ConstantExpr(RandomGenerator.String()),
                    new ConstantExpr(true)
                };

                var returnValue = values[1];

                var functionDefinition = new FunctionDefinitionExpr(functionNameExpr, parameters,
                                                                    new ScopeBlockStmt(new[] { new ReturnStmt(returnValue) }), new IdentifierExpr("String"));

                var expr = new FunctionCallExpr(functionNameExpr, values);

                _scope.DefineIdentifier(functionName, Value.FromObject(functionDefinition));

                var actual = target.Visit(expr, _scope);

                Assert.AreEqual(((ConstantExpr)returnValue).Value, actual.ToObject());
            }
Ejemplo n.º 8
0
        public void IdentifierExprName()
        {
            var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/ true);

            Assert.IsTrue(id.Immutable);
            Assert.Throws(typeof(InvalidOperationException), () => id.Name = "foo2");
        }
Ejemplo n.º 9
0
        public override ILineObject Generate(GenerationEnvironment env)
        {
            List <ILineObject> ret = new List <ILineObject>();

            if (CheckInstance != null && CheckInstance.Length != 0)
            {
                ret.Add(new ControlBlock(ControlBlockType.If,
                                         new BiOpExpr(ActorVariableHelper.GenerateGet(CheckInstance), ThisExpr.Instance.MakeIndex("name"), BiOpExpr.Op.NotEqual),
                                         new ILineObject[] {
                    ThisExpr.Instance.MakeIndex("Release").Call().Statement(),
                }).Statement());
            }

            var ownerActor = new IdentifierExpr("ownerActor");
            var x          = Position.GenerateX(ownerActor, env);
            var y          = Position.GenerateY(ownerActor, env);

            var setRotation = ThisExpr.Instance.MakeIndex("rz").Assign(ownerActor.MakeIndex("rz")).Statement();

            ret.AddRange(new ILineObject[] {
                new LocalVarStatement("ownerActor", ActorVariableHelper.GenerateGet("SYS_parent").MakeIndex("wr")),
                new ControlBlock(ControlBlockType.If, "ownerActor != null", new ILineObject[] {
                    ThisExpr.Instance.MakeIndex("x").Assign(x).Statement(),
                    ThisExpr.Instance.MakeIndex("y").Assign(y).Statement(),
                    IgnoreRotation ? new SimpleLineObject("") : setRotation,
                }).Statement(),
                new ControlBlock(ControlBlockType.Else, new ILineObject[] {
                    ThisExpr.Instance.MakeIndex("Release").Call().Statement(),
                }).Statement(),
            });

            return(new SimpleBlock(ret).Statement());
        }
Ejemplo n.º 10
0
        private void FindUseOfFunctionPointers(InstrumentationRegion region, int regionIndex,
                                               IdentifierExpr constant, HashSet <InstrumentationRegion> alreadyFound)
        {
            if (alreadyFound.Contains(region))
            {
                return;
            }
            alreadyFound.Add(region);

            var id = region.Implementation().InParams[regionIndex];

            if (region.FunctionPointers.Contains(id))
            {
                return;
            }
            region.FunctionPointers.Add(id);

            foreach (var block in region.Blocks())
            {
                for (int idx = 0; idx < block.Cmds.Count; idx++)
                {
                    if (!(block.Cmds[idx] is CallCmd))
                    {
                        continue;
                    }

                    var call         = block.Cmds[idx] as CallCmd;
                    var calleeRegion = this.AC.InstrumentationRegions.Find(val =>
                                                                           val.Implementation().Name.Equals(call.callee));
                    if (calleeRegion == null)
                    {
                        continue;
                    }

                    var indexes = new HashSet <int>();
                    for (int i = 0; i < call.Ins.Count; i++)
                    {
                        if (!(call.Ins[i] is IdentifierExpr))
                        {
                            continue;
                        }

                        if (id.Name.Equals((call.Ins[i] as IdentifierExpr).Name))
                        {
                            indexes.Add(i);
                        }
                    }

                    if (indexes.Count == 0)
                    {
                        continue;
                    }

                    foreach (var index in indexes)
                    {
                        this.FindUseOfFunctionPointers(calleeRegion, index, constant, alreadyFound);
                    }
                }
            }
        }
Ejemplo n.º 11
0
            bool InferSubstitution(Expr x, out Variable var, out Expr expr)
            {
                var  = null;
                expr = null;
                NAryExpr naryExpr = x as NAryExpr;

                if (naryExpr == null || naryExpr.Fun.FunctionName != "==")
                {
                    return(false);
                }
                IdentifierExpr arg0 = naryExpr.Args[0] as IdentifierExpr;

                if (arg0 != null && arg0.Decl is BoundVariable)
                {
                    var  = arg0.Decl;
                    expr = naryExpr.Args[1];
                    return(true);
                }
                IdentifierExpr arg1 = naryExpr.Args[1] as IdentifierExpr;

                if (arg1 != null && arg1.Decl is BoundVariable)
                {
                    var  = arg1.Decl;
                    expr = naryExpr.Args[0];
                    return(true);
                }
                return(false);
            }
Ejemplo n.º 12
0
        public void IdentifierExprName()
        {
            var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/ true);

            Assert.IsTrue(id.Immutable);
            id.Name = "foo2";
        }
Ejemplo n.º 13
0
        private AssertCmd GenBoundCheck(BOUND_TYPE btype, AccessRecord ar, int arrDim, Variable offsetVar)
        {
            Expr           boundExpr     = null;
            IdentifierExpr offsetVarExpr = new IdentifierExpr(Token.NoToken, offsetVar);

            switch (btype)
            {
            case BOUND_TYPE.LOWER:
                boundExpr = verifier.IntRep.MakeSge(offsetVarExpr, verifier.IntRep.GetLiteral(0, verifier.size_t_bits)); break;

            case BOUND_TYPE.UPPER:
                boundExpr = verifier.IntRep.MakeSlt(offsetVarExpr, verifier.IntRep.GetLiteral(arrDim, verifier.size_t_bits)); break;
            }

            return(new AssertCmd(Token.NoToken, boundExpr,
                                 new QKeyValue(Token.NoToken, "array_bounds", new List <object> {
            },
                                               new QKeyValue(Token.NoToken, "sourceloc_num", new List <object> {
                new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(CurrSourceLocNum))
            },
                                                             new QKeyValue(Token.NoToken, "check_id", new List <object> {
                "bounds_check_state_" + ArraySourceID
            },
                                                                           new QKeyValue(Token.NoToken, "array_name", new List <object> {
                ar.v.Name
            },
                                                                                         null))))));
        }
        public InductiveSequentialization(AtomicAction inputAction, AtomicAction outputAction,
                                          AtomicAction invariantAction, Dictionary <AtomicAction, AtomicAction> elim)
        {
            this.inputAction     = inputAction;
            this.outputAction    = outputAction;
            this.invariantAction = invariantAction;
            this.elim            = elim;

            // TODO: check frame computation
            // We could compute a tighter frame per check. For example, base/conclusion checkers
            // don't have to take the eliminated actions into account.
            var frameVars = new List <AtomicAction> {
                invariantAction, outputAction, inputAction
            }
            .Union(elim.Select(kv => kv.Value))
            .SelectMany(a => a.gateUsedGlobalVars.Union(a.modifiedGlobalVars)).Distinct();

            this.frame    = new HashSet <Variable>(frameVars);
            this.modifies = frame.Select(Expr.Ident).ToList();

            newPAs = Expr.Ident(VarHelper.LocalVariable("newPAs", PendingAsyncMultisetType));
            if (HasChoice)
            {
                choice = Expr.Ident(invariantAction.impl.OutParams.Last());
            }
            else
            {
                choice = Expr.Ident(VarHelper.LocalVariable("choice", PendingAsyncType));
            }
        }
Ejemplo n.º 15
0
        public override Expr VisitIdentifierExpr(IdentifierExpr node)
        {
            IdentifierExpr newNode;

            if (node.Name != node.Decl.Name || node.Name != node.Decl.TypedIdent.Name)
            {
                Console.WriteLine("Inconsistent variable/ident naming on " + node.Name + " " + node.Decl.Name + " " + node.Decl.TypedIdent.Name);
            }

            GlobalVariable g = node.Decl as GlobalVariable;

            if (g == null)
            {
                newNode = null;
            }
            else
            {
                g = GetNewVar(g);
                if (g == null)
                {
                    newNode = null;
                }
                else
                {
                    //newNode = Expr.Ident(g);
                    newNode = new IdentifierExpr(Token.NoToken, g);
                }
            }
            return(base.VisitIdentifierExpr(newNode == null ? node : newNode));
        }
Ejemplo n.º 16
0
        private void LiteralArgumentAnalyser(Procedure p, int arg)
        {
            LiteralExpr literal = null;

            foreach (CallCmd callCmd in CallSites[p])
            {
                if (callCmd.Ins[arg] == null || !(callCmd.Ins[arg] is LiteralExpr))
                {
                    return;
                }

                LiteralExpr l = callCmd.Ins[arg] as LiteralExpr;

                if (literal == null)
                {
                    literal = l;
                }
                else if (!literal.Equals(l))
                {
                    return;
                }
            }

            Expr e;

            e = new IdentifierExpr(Token.NoToken, p.InParams[arg]);
            e = Expr.Eq(e, literal);
            p.Requires.Add(new Requires(false, e));
        }
Ejemplo n.º 17
0
 private Expr CollectBooleanAssignment(IdentifierExpr glob, Variable assignedVar)
 {
     return(new NAryExpr(Token.NoToken, new FunctionCall(collectBoolFunc), new List <Expr>()
     {
         glob, IdentifierExpr.Ident(assignedVar)
     }));
 }
Ejemplo n.º 18
0
        public void ParallelSymbolicAssignment()
        {
            p = LoadProgramFrom(@"
                procedure main()
                {
                    var x:int;
                    var y:int;
                    assert {:symbooglix_bp ""before""} true;
                    x, y := y, x;
                    assert {:symbooglix_bp ""after""} true;
                }
            ", "file.bpl");
            e = GetExecutor(p, new DFSStateScheduler(), GetSolver());

            int            count        = 0;
            IdentifierExpr symbolicForx = null;
            IdentifierExpr symbolicFory = null;

            e.BreakPointReached += delegate(object sender, Executor.BreakPointEventArgs eventArgs)
            {
                switch (eventArgs.Name)
                {
                case "before":
                {
                    var vAndExprForx = e.CurrentState.GetInScopeVariableAndExprByName("x");
                    Assert.IsInstanceOf <IdentifierExpr>(vAndExprForx.Value);
                    Assert.IsInstanceOf <SymbolicVariable>((vAndExprForx.Value as IdentifierExpr).Decl);
                    symbolicForx = vAndExprForx.Value as IdentifierExpr;

                    var vAndExprFory = e.CurrentState.GetInScopeVariableAndExprByName("y");
                    Assert.IsInstanceOf <IdentifierExpr>(vAndExprFory.Value);
                    Assert.IsInstanceOf <SymbolicVariable>((vAndExprFory.Value as IdentifierExpr).Decl);
                    symbolicFory = vAndExprFory.Value as IdentifierExpr;
                }
                break;

                case "after":
                {
                    Assert.IsNotNull(symbolicForx);
                    Assert.IsNotNull(symbolicFory);

                    // Check that swapped happened
                    var vAndExprForNewx = e.CurrentState.GetInScopeVariableAndExprByName("x");
                    Assert.AreSame(symbolicFory, vAndExprForNewx.Value);

                    var vAndExprForNewy = e.CurrentState.GetInScopeVariableAndExprByName("y");
                    Assert.AreSame(symbolicForx, vAndExprForNewy.Value);
                }
                break;

                default:
                    Assert.Fail("unrecognised breakpoint");
                    break;
                }
                ++count;
            };
            e.Run(GetMain(p));
            Assert.AreEqual(2, count);
        }
Ejemplo n.º 19
0
        public QuantifierExpr RewriteMatchingLoops(QuantifierWithTriggers q)
        {
            // rewrite quantifier to avoid mathing loops
            // before:
            //    assert forall i :: 0 <= i < a.Length-1 ==> a[i] <= a[i+1];
            // after:
            //    assert forall i,j :: j == i+1 ==> 0 <= i < a.Length-1 ==> a[i] <= a[i+1];
            substMap = new Dictionary <Expression, IdentifierExpr>();
            usedMap  = new Dictionary <Expression, IdentifierExpr>();
            foreach (var m in q.LoopingMatches)
            {
                var e = m.OriginalExpr;
                if (TriggersCollector.IsPotentialTriggerCandidate(e) && triggersCollector.IsTriggerKiller(e))
                {
                    foreach (var sub in e.SubExpressions)
                    {
                        if (triggersCollector.IsTriggerKiller(sub) && (!TriggersCollector.IsPotentialTriggerCandidate(sub)))
                        {
                            IdentifierExpr ie;
                            if (!substMap.TryGetValue(sub, out ie))
                            {
                                var newBv = new BoundVar(sub.tok, "_t#" + substMap.Count, sub.Type);
                                ie            = new IdentifierExpr(sub.tok, newBv.Name);
                                ie.Var        = newBv;
                                ie.Type       = newBv.Type;
                                substMap[sub] = ie;
                            }
                        }
                    }
                }
            }

            var expr = (QuantifierExpr)q.quantifier;

            if (substMap.Count > 0)
            {
                var s = new Translator.ExprSubstituter(substMap);
                expr = s.Substitute(q.quantifier) as QuantifierExpr;
            }
            else
            {
                // make a copy of the expr
                if (expr is ForallExpr)
                {
                    expr = new ForallExpr(expr.tok, expr.TypeArgs, expr.BoundVars, expr.Range, expr.Term, TriggerUtils.CopyAttributes(expr.Attributes))
                    {
                        Type = expr.Type
                    };
                }
                else
                {
                    expr = new ExistsExpr(expr.tok, expr.TypeArgs, expr.BoundVars, expr.Range, expr.Term, TriggerUtils.CopyAttributes(expr.Attributes))
                    {
                        Type = expr.Type
                    };
                }
            }
            return(expr);
        }
Ejemplo n.º 20
0
 public override Expr VisitIdentifierExpr(IdentifierExpr node)
 {
     if (!inold)
     {
         flag = true;
     }
     return(base.VisitIdentifierExpr(node));
 }
Ejemplo n.º 21
0
 public override Expr VisitIdentifierExpr(IdentifierExpr node)
 {
     if (consts.Keys.Contains(node.ToString()))
     {
         return(consts[node.ToString()]);
     }
     return(base.VisitIdentifierExpr(node));
 }
Ejemplo n.º 22
0
            public override Expr VisitIdentifierExpr(IdentifierExpr node)
            {
                var ie = (IdentifierExpr)base.VisitIdentifierExpr(node);

                // Need to fix up the name, since IdentifierExpr's equality also checks the name
                ie.Name = ie.Decl.TypedIdent.Name;
                return(ie);
            }
Ejemplo n.º 23
0
 public override Expr VisitIdentifierExpr(IdentifierExpr node)
 {
     if (!globals.Contains(node.Name))
     {
         usedVars.Add(node.Name);
     }
     return(node);
 }
Ejemplo n.º 24
0
            public override Expr VisitIdentifierExpr(IdentifierExpr node)
            {
                //Contract.Requires(node != null);
                Contract.Ensures(Contract.Result <Expr>() != null);
                Expr /*?*/ e = subst(cce.NonNull(node.Decl));

                return(e == null?base.VisitIdentifierExpr(node) : e);
            }
Ejemplo n.º 25
0
 public override Expr VisitIdentifierExpr(IdentifierExpr node)
 {
     if (node.Decl == _toSearch)
     {
         Success = true;
     }
     return(base.VisitIdentifierExpr(node));
 }
Ejemplo n.º 26
0
 public override Expr VisitIdentifierExpr(IdentifierExpr node)
 {
     if (AllMaps.Contains(node.Name))
     {
         return(Expr.Ident(U));
     }
     return(node);
 }
 public override Expr VisitIdentifierExpr(IdentifierExpr node)
 {
     if (GetReplacementVariable(node, out var variable))
     {
         return(new IdentifierExpr(variable.tok, variable));
     }
     return(base.VisitIdentifierExpr(node));
 }
Ejemplo n.º 28
0
 public ClassDefinitionStmt(IdentifierExpr name,
                            IEnumerable <VarDefinitionStmt> members,
                            IEnumerable <FunctionExpr> functions)
 {
     _name      = name;
     _members   = members.ToArray();
     _functions = functions.ToArray();
 }
Ejemplo n.º 29
0
 public override Expr VisitIdentifierExpr(IdentifierExpr node)
 {
     if (node.Decl != null)
     {
         node.Decl = this.VisitVariable(node.Decl);
     }
     return(node);
 }
        protected Tuple <Variable, IdentifierExpr> GetBoundVarAndIdExpr(string name, Microsoft.Boogie.Type type)
        {
            var typeIdent = new TypedIdent(Token.NoToken, name, type);
            var v         = new BoundVariable(Token.NoToken, typeIdent);
            var id        = new IdentifierExpr(Token.NoToken, v, /*immutable=*/ true);

            return(new Tuple <Variable, IdentifierExpr>(v, id));
        }
Ejemplo n.º 31
0
        public void CachedHashCodeIdentifierExpr()
        {
            var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/true);
            Assert.AreEqual(id.ComputeHashCode(), id.GetHashCode());

            var variable = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "foo2", BasicType.Int));
            var id2 = new IdentifierExpr(Token.NoToken, variable, /*immutable=*/true);
            Assert.AreEqual(id2.ComputeHashCode(), id2.GetHashCode());
        }
Ejemplo n.º 32
0
            public void FunctionNamePropertyReturnsPassedName()
            {
                var name = new IdentifierExpr(RandomGenerator.String());
                var arguments = new Expression[] { new ConstantExpr(RandomGenerator.Int()), new ConstantExpr(RandomGenerator.Int()) };

                var target = new FunctionCallExpr(name, arguments);

                Assert.AreSame(name.Name, target.FunctionName.Name);
            }
Ejemplo n.º 33
0
    public void SimpleIdentifierExprs() {
      var variable = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "foo", Microsoft.Boogie.Type.GetBvType(8)));
      var idVar = new IdentifierExpr(Token.NoToken, variable);
      var idVar2 = new IdentifierExpr(Token.NoToken, variable);

      Assert.AreNotSame(idVar, idVar2); // These are different references

      Assert.IsTrue(idVar.Equals(idVar2)); // These are "structurally equal"
      Assert.AreEqual(idVar.GetHashCode(), idVar2.GetHashCode()); // If the .Equals() is true then hash codes must be the same
    }
Ejemplo n.º 34
0
        public static void Predicate(Program p,
            Func<Procedure, bool> useProcedurePredicates = null,
            UniformityAnalyser uni = null)
        {
            useProcedurePredicates = useProcedurePredicates ?? (proc => false);
            if (uni != null) {
              var oldUPP = useProcedurePredicates;
              useProcedurePredicates = proc => oldUPP(proc) && !uni.IsUniform(proc.Name);
            }

            foreach (var decl in p.TopLevelDeclarations.ToList()) {
              if (decl is Procedure || decl is Implementation) {
            var proc = decl as Procedure;
            Implementation impl = null;
            if (proc == null) {
              impl = (Implementation)decl;
              proc = impl.Proc;
            }

            bool upp = useProcedurePredicates(proc);
            if (upp) {
              var dwf = (DeclWithFormals)decl;
              var fpVar = new Formal(Token.NoToken,
                                 new TypedIdent(Token.NoToken, "_P",
                                                Microsoft.Boogie.Type.Bool),
                                 /*incoming=*/true);
              dwf.InParams = new List<Variable>(
            (new Variable[] {fpVar}.Concat(dwf.InParams.Cast<Variable>()))
              .ToArray());

              if (impl == null) {
            var fpIdentifierExpr = new IdentifierExpr(Token.NoToken, fpVar);
            foreach (Requires r in proc.Requires) {
              new EnabledReplacementVisitor(fpIdentifierExpr).VisitExpr(r.Condition);
              if (!QKeyValue.FindBoolAttribute(r.Attributes, "do_not_predicate")) {
                r.Condition = Expr.Imp(fpIdentifierExpr, r.Condition);
              }
            }
            foreach (Ensures e in proc.Ensures) {
              new EnabledReplacementVisitor(new IdentifierExpr(Token.NoToken, fpVar)).VisitExpr(e.Condition);
              if (!QKeyValue.FindBoolAttribute(e.Attributes, "do_not_predicate")) {
                e.Condition = Expr.Imp(fpIdentifierExpr, e.Condition);
              }
            }
              }
            }

            if (impl != null) {
              try {
            new SmartBlockPredicator(p, impl, useProcedurePredicates, uni).PredicateImplementation();
              } catch (Program.IrreducibleLoopException) { }
            }
              }
            }
        }
            public void ReturnTypePropertyReturnsPassedReturnType()
            {
                var name = new IdentifierExpr(RandomGenerator.String());
                var arguments = new VarDefinitionStmt[0];
                var body = new ConstantExpr(RandomGenerator.Int());
                var returnType = new IdentifierExpr(RandomGenerator.String());

                var target = new LambdaDefinitionExpr(name, arguments, body, returnType);

                Assert.AreSame(returnType, target.ReturnType);
            }
            public void BodyPropertyReturnsPassedBody2()
            {
                var name = new IdentifierExpr(RandomGenerator.String());
                var arguments = new VarDefinitionStmt[0];
                var body = new ScopeBlockStmt(new [] { new NoOpStatement()});
                var returnType = new IdentifierExpr(RandomGenerator.String());

                var target = new FunctionDefinitionExpr(name, arguments, body, returnType);

                Assert.AreSame(body, target.Body);
            }
            public void ArgumentsPropertyReturnsPassedArguments()
            {
                var name = new IdentifierExpr(RandomGenerator.String());
                var arguments = new VarDefinitionStmt[0];
                var body = new NoOpStatement();
                var returnType = new IdentifierExpr(RandomGenerator.String());

                var target = new FunctionDefinitionExpr(name, arguments, body, returnType);

                Assert.AreSame(arguments, target.Arguments);
            }
Ejemplo n.º 38
0
            public void AcceptMethodCallsVisitOnVisitorWithThis()
            {
                var name = new IdentifierExpr(RandomGenerator.String());
                var arguments = new Expression[] { new ConstantExpr(RandomGenerator.Int()), new ConstantExpr(RandomGenerator.Int()) };

                var target = new FunctionCallExpr(name, arguments);
                var visitor = new Mock<IExpressionVisitor<string, int>>();

                target.Accept(visitor.Object, 0);

                visitor.Verify(x => x.Visit(target, 0), Times.Once);
            }
Ejemplo n.º 39
0
            public void AcceptMethodCallsOnlyVisitOnVisitorWithThisAndNoOtherVisitMethods()
            {
                var name = new IdentifierExpr(RandomGenerator.String());
                var arguments = new Expression[] { new ConstantExpr(RandomGenerator.Int()), new ConstantExpr(RandomGenerator.Int()) };

                var target = new FunctionCallExpr(name, arguments);
                // throw exception is any other methods called other than the PlusExpr overload.
                var visitor = new Mock<IExpressionVisitor<string, int>>(MockBehavior.Strict);
                visitor.Setup(x => x.Visit(target, 123)).Returns("");

                target.Accept(visitor.Object, 123);
            }
        private List<VarDefinitionStmt> ParseParameterList(Parser parser)
        {
            var parameters = new List<VarDefinitionStmt>();

            if (parser.Peek().Type == "RIGHTPAREN")
                return parameters;

            while (true)
            {
                var name = parser.ParseExpression(0);

                if(!(name is IdentifierExpr))
                    throw new ParseException("Expected parameter name");

                Expression type = null;
                if (parser.ConsumeOptional("COLON"))
                {
                    type = parser.ParseExpression(0);

                    if (!(type is IdentifierExpr))
                        throw new ParseException("Expected parameter type");

                }
                else
                {
                    type = new IdentifierExpr("dynamic");
                }

                parameters.Add(new VarDefinitionStmt((IdentifierExpr)name, (IdentifierExpr)type, false, null));

                if (parser.Peek().Type == "RIGHTPAREN")
                    break;

                parser.Consume("COMMA");
            }

            return parameters;
        }
Ejemplo n.º 41
0
 public void IdentifierExprDecl()
 {
     var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/true);
     Assert.IsTrue(id.Immutable);
     var typedIdent = new TypedIdent(Token.NoToken, "foo2", BasicType.Bool);
     id.Decl = new GlobalVariable(Token.NoToken, typedIdent);
 }
Ejemplo n.º 42
0
 public void IdentifierExprName()
 {
     var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/true);
     Assert.IsTrue(id.Immutable);
     id.Name = "foo2";
 }
Ejemplo n.º 43
0
    /// <summary>
    /// Before calling TrExpr(expr), the caller must have spilled the let variables declared in "expr".
    /// </summary>
    void TrExpr(Expression expr, TextWriter wr, bool inLetExprBody)
    {
      Contract.Requires(expr != null);
      if (expr is LiteralExpr) {
        LiteralExpr e = (LiteralExpr)expr;
        if (e is StaticReceiverExpr) {
          wr.Write(TypeName(e.Type, wr));
        } else if (e.Value == null) {
          wr.Write("({0})null", TypeName(e.Type, wr));
        } else if (e.Value is bool) {
          wr.Write((bool)e.Value ? "true" : "false");
        } else if (e is CharLiteralExpr) {
          wr.Write("'{0}'", (string)e.Value);
        } else if (e is StringLiteralExpr) {
          var str = (StringLiteralExpr)e;
          wr.Write("{0}<char>.FromString({1}\"{2}\")", DafnySeqClass, str.IsVerbatim ? "@" : "", (string)e.Value);
        } else if (AsNativeType(e.Type) != null) {
          wr.Write((BigInteger)e.Value + AsNativeType(e.Type).Suffix);
        } else if (e.Value is BigInteger) {
          BigInteger i = (BigInteger)e.Value;
          if (new BigInteger(int.MinValue) <= i && i <= new BigInteger(int.MaxValue)) {
            wr.Write("new BigInteger({0})", i);
          } else {
            wr.Write("BigInteger.Parse(\"{0}\")", i);
          }
        } else if (e.Value is Basetypes.BigDec) {
          var n = (Basetypes.BigDec)e.Value;
          if (0 <= n.Exponent) {
            wr.Write("new Dafny.BigRational(new BigInteger({0}", n.Mantissa);
            for (int i = 0; i < n.Exponent; i++) {
              wr.Write("0");
            }
            wr.Write("), BigInteger.One)");
          } else {
            wr.Write("new Dafny.BigRational(new BigInteger({0}), new BigInteger(1", n.Mantissa);
            for (int i = n.Exponent; i < 0; i++) {
              wr.Write("0");
            }
            wr.Write("))");
          }
        } else {
          Contract.Assert(false); throw new cce.UnreachableException();  // unexpected literal
        }

      } else if (expr is ThisExpr) {
        wr.Write(enclosingMethod != null && enclosingMethod.IsTailRecursive ? "_this" : "this");

      } else if (expr is IdentifierExpr) {
        var e = (IdentifierExpr)expr;
        if (e.Var is Formal && inLetExprBody && !((Formal)e.Var).InParam) {
          // out param in letExpr body, need to copy it to a temp since
          // letExpr body is translated to an anonymous function that doesn't
          // allow out parameters
          var name = string.Format("_pat_let_tv{0}", GetUniqueAstNumber(e));
          wr.Write("@" + name);
          copyInstrWriter.Append("var @" + name + "= @" + e.Var.CompileName + ";\n");
        } else {
          wr.Write("@" + e.Var.CompileName);
        }
      } else if (expr is SetDisplayExpr) {
        var e = (SetDisplayExpr)expr;
        var elType = e.Type.AsSetType.Arg;
        wr.Write("{0}<{1}>.FromElements", DafnySetClass, TypeName(elType, wr));
        TrExprList(e.Elements, wr, inLetExprBody);

      } else if (expr is MultiSetDisplayExpr) {
        var e = (MultiSetDisplayExpr)expr;
        var elType = e.Type.AsMultiSetType.Arg;
        wr.Write("{0}<{1}>.FromElements", DafnyMultiSetClass, TypeName(elType, wr));
        TrExprList(e.Elements, wr, inLetExprBody);

      } else if (expr is SeqDisplayExpr) {
        var e = (SeqDisplayExpr)expr;
        var elType = e.Type.AsSeqType.Arg;
        wr.Write("{0}<{1}>.FromElements", DafnySeqClass, TypeName(elType, wr));
        TrExprList(e.Elements, wr, inLetExprBody);

      } else if (expr is MapDisplayExpr) {
        MapDisplayExpr e = (MapDisplayExpr)expr;
        wr.Write("{0}.FromElements", TypeName(e.Type, wr));
        TrExprPairList(e.Elements, wr, inLetExprBody);

      } else if (expr is MemberSelectExpr) {
        MemberSelectExpr e = (MemberSelectExpr)expr;
        SpecialField sf = e.Member as SpecialField;
        if (sf != null) {
          wr.Write(sf.PreString);
          TrParenExpr(e.Obj, wr, inLetExprBody);
          wr.Write(".@{0}", sf.CompiledName);
          wr.Write(sf.PostString);
        } else {
          TrExpr(e.Obj, wr, inLetExprBody);
          wr.Write(".@{0}", e.Member.CompileName);
        }

      } else if (expr is SeqSelectExpr) {
        SeqSelectExpr e = (SeqSelectExpr)expr;
        Contract.Assert(e.Seq.Type != null);
        if (e.Seq.Type.IsArrayType) {
          if (e.SelectOne) {
            Contract.Assert(e.E0 != null && e.E1 == null);
            TrParenExpr(e.Seq, wr, inLetExprBody);
            wr.Write("[(int)");
            TrParenExpr(e.E0, wr, inLetExprBody);
            wr.Write("]");
          } else {
            TrParenExpr("Dafny.Helpers.SeqFromArray", e.Seq, wr, inLetExprBody);
            if (e.E1 != null) {
              TrParenExpr(".Take", e.E1, wr, inLetExprBody);
            }
            if (e.E0 != null) {
              TrParenExpr(".Drop", e.E0, wr, inLetExprBody);
            }
          }
        } else if (e.SelectOne) {
          Contract.Assert(e.E0 != null && e.E1 == null);
          TrParenExpr(e.Seq, wr, inLetExprBody);
          TrParenExpr(".Select", e.E0, wr, inLetExprBody);
        } else {
          TrParenExpr(e.Seq, wr, inLetExprBody);
          if (e.E1 != null) {
            TrParenExpr(".Take", e.E1, wr, inLetExprBody);
          }
          if (e.E0 != null) {
            TrParenExpr(".Drop", e.E0, wr, inLetExprBody);
          }
        }
      } else if (expr is MultiSetFormingExpr) {
        var e = (MultiSetFormingExpr)expr;
        wr.Write("{0}<{1}>", DafnyMultiSetClass, TypeName(e.E.Type.AsCollectionType.Arg, wr));
        var eeType = e.E.Type.NormalizeExpand();
        if (eeType is SeqType) {
          TrParenExpr(".FromSeq", e.E, wr, inLetExprBody);
        } else if (eeType is SetType) {
          TrParenExpr(".FromSet", e.E, wr, inLetExprBody);
        } else {
          Contract.Assert(false); throw new cce.UnreachableException();
        }
      } else if (expr is MultiSelectExpr) {
        MultiSelectExpr e = (MultiSelectExpr)expr;
        TrParenExpr(e.Array, wr, inLetExprBody);
        string prefix = "[";
        foreach (Expression idx in e.Indices) {
          wr.Write("{0}(int)", prefix);
          TrParenExpr(idx, wr, inLetExprBody);
          prefix = ", ";
        }
        wr.Write("]");

      } else if (expr is SeqUpdateExpr) {
        SeqUpdateExpr e = (SeqUpdateExpr)expr;
        if (e.ResolvedUpdateExpr != null)
        {
          TrExpr(e.ResolvedUpdateExpr, wr, inLetExprBody);
        }
        else
        {
          TrParenExpr(e.Seq, wr, inLetExprBody);
          wr.Write(".Update(");
          TrExpr(e.Index, wr, inLetExprBody);
          wr.Write(", ");
          TrExpr(e.Value, wr, inLetExprBody);
          wr.Write(")");
        }

      } else if (expr is FunctionCallExpr) {
        FunctionCallExpr e = (FunctionCallExpr)expr;
        CompileFunctionCallExpr(e, wr, wr, inLetExprBody, TrExpr);

      } else if (expr is ApplyExpr) {
        var e = expr as ApplyExpr;
        wr.Write("Dafny.Helpers.Id<");
        wr.Write(TypeName(e.Function.Type, wr));
        wr.Write(">(");
        TrExpr(e.Function, wr, inLetExprBody);
        wr.Write(")");
        TrExprList(e.Args, wr, inLetExprBody);

      } else if (expr is DatatypeValue) {
        DatatypeValue dtv = (DatatypeValue)expr;
        Contract.Assert(dtv.Ctor != null);  // since dtv has been successfully resolved
        var typeParams = dtv.InferredTypeArgs.Count == 0 ? "" : string.Format("<{0}>", TypeNames(dtv.InferredTypeArgs, wr));
        wr.Write("new @{0}{1}(", DtName(dtv.Ctor.EnclosingDatatype), typeParams);
        if (!dtv.IsCoCall) {
          // For an ordinary constructor (that is, one that does not guard any co-recursive calls), generate:
          //   new Dt_Cons<T>( args )
          wr.Write("new {0}(", DtCtorName(dtv.Ctor, dtv.InferredTypeArgs, wr));
          string sep = "";
          for (int i = 0; i < dtv.Arguments.Count; i++) {
            Formal formal = dtv.Ctor.Formals[i];
            if (!formal.IsGhost) {
              wr.Write(sep);
              TrExpr(dtv.Arguments[i], wr, inLetExprBody);
              sep = ", ";
            }
          }
          wr.Write(")");
        } else {
          // In the case of a co-recursive call, generate:
          //     new Dt__Lazy<T>( new Dt__Lazy<T>.ComputerComputer( LAMBDA )() )
          // where LAMBDA is:
          //     () => { var someLocals = eagerlyEvaluatedArguments;
          //             return () => { return Dt_Cons<T>( ...args...using someLocals and including function calls to be evaluated lazily... ); };
          //           }
          wr.Write("new {0}__Lazy{1}", dtv.DatatypeName, typeParams);
          wr.Write("(new {0}__Lazy{1}.ComputerComputer(() => {{ ", dtv.DatatypeName, typeParams);

          // locals
          string args = "";
          string sep = "";
          for (int i = 0; i < dtv.Arguments.Count; i++) {
            Formal formal = dtv.Ctor.Formals[i];
            if (!formal.IsGhost) {
              Expression actual = dtv.Arguments[i].Resolved;
              string arg;
              var fce = actual as FunctionCallExpr;
              if (fce == null || fce.CoCall != FunctionCallExpr.CoCallResolution.Yes) {
                string varName = idGenerator.FreshId("_ac");
                arg = varName;

                wr.Write("var {0} = ", varName);
                TrExpr(actual, wr, inLetExprBody);
                wr.Write("; ");
              } else {
                var sw = new StringWriter();
                CompileFunctionCallExpr(fce, sw, wr, inLetExprBody, (exp, wrr, inLetExpr) => {
                  string varName = idGenerator.FreshId("_ac");
                  sw.Write(varName);

                  wrr.Write("var {0} = ", varName);
                  TrExpr(exp, wrr, inLetExpr);
                  wrr.Write("; ");

                });
                arg = sw.ToString();
              }
              args += sep + arg;
              sep = ", ";
            }
          }

          wr.Write("return () => { return ");

          wr.Write("new {0}({1}", DtCtorName(dtv.Ctor, dtv.InferredTypeArgs, wr), args);
          wr.Write("); }; })())");
        }
        wr.Write(")");

      } else if (expr is OldExpr) {
        Contract.Assert(false); throw new cce.UnreachableException();  // 'old' is always a ghost (right?)

      } else if (expr is UnaryOpExpr) {
        var e = (UnaryOpExpr)expr;
        switch (e.Op) {
          case UnaryOpExpr.Opcode.Not:
            wr.Write("!");
            TrParenExpr(e.E, wr, inLetExprBody);
            break;
          case UnaryOpExpr.Opcode.Cardinality:
            wr.Write("new BigInteger(");
            TrParenExpr(e.E, wr, inLetExprBody);
            wr.Write(".Length)");
            break;
          default:
            Contract.Assert(false); throw new cce.UnreachableException();  // unexpected unary expression
        }

      } else if (expr is ConversionExpr) {
        var e = (ConversionExpr)expr;
        var fromInt = e.E.Type.IsNumericBased(Type.NumericPersuation.Int);
        Contract.Assert(fromInt || e.E.Type.IsNumericBased(Type.NumericPersuation.Real));
        var toInt = e.ToType.IsNumericBased(Type.NumericPersuation.Int);
        Contract.Assert(toInt || e.ToType.IsNumericBased(Type.NumericPersuation.Real));
        Action fromIntAsBigInteger = () => {
          Contract.Assert(fromInt);
          if (AsNativeType(e.E.Type) != null) {
            wr.Write("new BigInteger");
          }
          TrParenExpr(e.E, wr, inLetExprBody);
        };
        Action toIntCast = () => {
          Contract.Assert(toInt);
          if (AsNativeType(e.ToType) != null) {
            wr.Write("(" + AsNativeType(e.ToType).Name + ")");
          }
        };
        if (fromInt && !toInt) {
          // int -> real
          wr.Write("new Dafny.BigRational(");
          fromIntAsBigInteger();
          wr.Write(", BigInteger.One)");
        } else if (!fromInt && toInt) {
          // real -> int
          toIntCast();
          TrParenExpr(e.E, wr, inLetExprBody);
          wr.Write(".ToBigInteger()");
        } else if (AsNativeType(e.ToType) != null) {
          toIntCast();
          LiteralExpr lit = e.E.Resolved as LiteralExpr;
          UnaryOpExpr u = e.E.Resolved as UnaryOpExpr;
          MemberSelectExpr m = e.E.Resolved as MemberSelectExpr;
          if (lit != null && lit.Value is BigInteger) {
            // Optimize constant to avoid intermediate BigInteger
            wr.Write("(" + (BigInteger)lit.Value + AsNativeType(e.ToType).Suffix + ")");
          } else if ((u != null && u.Op == UnaryOpExpr.Opcode.Cardinality) || (m != null && m.MemberName == "Length" && m.Obj.Type.IsArrayType)) {
            // Optimize .Length to avoid intermediate BigInteger
            TrParenExpr((u != null) ? u.E : m.Obj, wr, inLetExprBody);
            if (AsNativeType(e.ToType).UpperBound <= new BigInteger(0x80000000U)) {
              wr.Write(".Length");
            } else {
              wr.Write(".LongLength");
            }
          } else {
            TrParenExpr(e.E, wr, inLetExprBody);
          }
        } else if (e.ToType.IsIntegerType && AsNativeType(e.E.Type) != null) {
          fromIntAsBigInteger();
        } else {
          Contract.Assert(fromInt == toInt);
          Contract.Assert(AsNativeType(e.ToType) == null);
          Contract.Assert(AsNativeType(e.E.Type) == null);
          TrParenExpr(e.E, wr, inLetExprBody);
        }

      } else if (expr is BinaryExpr) {
        BinaryExpr e = (BinaryExpr)expr;
        string opString = null;
        string preOpString = "";
        string callString = null;

        switch (e.ResolvedOp) {
          case BinaryExpr.ResolvedOpcode.Iff:
            opString = "==";  break;
          case BinaryExpr.ResolvedOpcode.Imp:
            preOpString = "!";  opString = "||";  break;
          case BinaryExpr.ResolvedOpcode.Or:
            opString = "||";  break;
          case BinaryExpr.ResolvedOpcode.And:
            opString = "&&";  break;

          case BinaryExpr.ResolvedOpcode.EqCommon: {
            if (e.E0.Type.IsRefType) {
              // Dafny's type rules are slightly different C#, so we may need a cast here.
              // For example, Dafny allows x==y if x:array<T> and y:array<int> and T is some
              // type parameter.
              opString = "== (object)";
            } else if (e.E0.Type.IsDatatype || e.E0.Type.IsTypeParameter || e.E0.Type.SupportsEquality) {
              callString = "Equals";
            } else {
              opString = "==";
            }
            break;
          }
          case BinaryExpr.ResolvedOpcode.NeqCommon: {
            if (e.E0.Type.IsRefType) {
              // Dafny's type rules are slightly different C#, so we may need a cast here.
              // For example, Dafny allows x==y if x:array<T> and y:array<int> and T is some
              // type parameter.
              opString = "!= (object)";
            } else if (e.E0.Type.IsDatatype || e.E0.Type.IsTypeParameter || e.E0.Type.SupportsEquality) {
              preOpString = "!";
              callString = "Equals";
            } else {
              opString = "!=";
            }
            break;
          }

          case BinaryExpr.ResolvedOpcode.Lt:
          case BinaryExpr.ResolvedOpcode.LtChar:
            opString = "<"; break;
          case BinaryExpr.ResolvedOpcode.Le:
          case BinaryExpr.ResolvedOpcode.LeChar:
            opString = "<="; break;
          case BinaryExpr.ResolvedOpcode.Ge:
          case BinaryExpr.ResolvedOpcode.GeChar:
            opString = ">="; break;
          case BinaryExpr.ResolvedOpcode.Gt:
          case BinaryExpr.ResolvedOpcode.GtChar:
            opString = ">"; break;
          case BinaryExpr.ResolvedOpcode.Add:
            opString = "+";  break;
          case BinaryExpr.ResolvedOpcode.Sub:
            opString = "-";  break;
          case BinaryExpr.ResolvedOpcode.Mul:
            opString = "*";  break;
          case BinaryExpr.ResolvedOpcode.Div:
            if (expr.Type.IsIntegerType || (AsNativeType(expr.Type) != null && AsNativeType(expr.Type).LowerBound < BigInteger.Zero)) {
              string suffix = AsNativeType(expr.Type) != null ? ("_" + AsNativeType(expr.Type).Name) : "";
              wr.Write("Dafny.Helpers.EuclideanDivision" + suffix + "(");
              TrParenExpr(e.E0, wr, inLetExprBody);
              wr.Write(", ");
              TrExpr(e.E1, wr, inLetExprBody);
              wr.Write(")");
            } else {
              opString = "/";  // for reals
            }
            break;
          case BinaryExpr.ResolvedOpcode.Mod:
            if (expr.Type.IsIntegerType || (AsNativeType(expr.Type) != null && AsNativeType(expr.Type).LowerBound < BigInteger.Zero)) {
              string suffix = AsNativeType(expr.Type) != null ? ("_" + AsNativeType(expr.Type).Name) : "";
              wr.Write("Dafny.Helpers.EuclideanModulus" + suffix + "(");
              TrParenExpr(e.E0, wr, inLetExprBody);
              wr.Write(", ");
              TrExpr(e.E1, wr, inLetExprBody);
              wr.Write(")");
            } else {
              opString = "%";  // for reals
            }
            break;
          case BinaryExpr.ResolvedOpcode.SetEq:
          case BinaryExpr.ResolvedOpcode.MultiSetEq:
          case BinaryExpr.ResolvedOpcode.SeqEq:
          case BinaryExpr.ResolvedOpcode.MapEq:
            callString = "Equals";  break;
          case BinaryExpr.ResolvedOpcode.SetNeq:
          case BinaryExpr.ResolvedOpcode.MultiSetNeq:
          case BinaryExpr.ResolvedOpcode.SeqNeq:
          case BinaryExpr.ResolvedOpcode.MapNeq:
            preOpString = "!";  callString = "Equals";  break;
          case BinaryExpr.ResolvedOpcode.ProperSubset:
          case BinaryExpr.ResolvedOpcode.ProperMultiSubset:
            callString = "IsProperSubsetOf";  break;
          case BinaryExpr.ResolvedOpcode.Subset:
          case BinaryExpr.ResolvedOpcode.MultiSubset:
            callString = "IsSubsetOf";  break;
          case BinaryExpr.ResolvedOpcode.Superset:
          case BinaryExpr.ResolvedOpcode.MultiSuperset:
            callString = "IsSupersetOf";  break;
          case BinaryExpr.ResolvedOpcode.ProperSuperset:
          case BinaryExpr.ResolvedOpcode.ProperMultiSuperset:
            callString = "IsProperSupersetOf";  break;
          case BinaryExpr.ResolvedOpcode.Disjoint:
          case BinaryExpr.ResolvedOpcode.MultiSetDisjoint:
          case BinaryExpr.ResolvedOpcode.MapDisjoint:
            callString = "IsDisjointFrom";  break;
          case BinaryExpr.ResolvedOpcode.InSet:
          case BinaryExpr.ResolvedOpcode.InMultiSet:
          case BinaryExpr.ResolvedOpcode.InMap:
            TrParenExpr(e.E1, wr, inLetExprBody);
            wr.Write(".Contains(");
            TrExpr(e.E0, wr, inLetExprBody);
            wr.Write(")");
            break;
          case BinaryExpr.ResolvedOpcode.NotInSet:
          case BinaryExpr.ResolvedOpcode.NotInMultiSet:
          case BinaryExpr.ResolvedOpcode.NotInMap:
            wr.Write("!");
            TrParenExpr(e.E1, wr, inLetExprBody);
            wr.Write(".Contains(");
            TrExpr(e.E0, wr, inLetExprBody);
            wr.Write(")");
            break;
          case BinaryExpr.ResolvedOpcode.Union:
          case BinaryExpr.ResolvedOpcode.MultiSetUnion:
            callString = "Union";  break;
          case BinaryExpr.ResolvedOpcode.Intersection:
          case BinaryExpr.ResolvedOpcode.MultiSetIntersection:
            callString = "Intersect";  break;
          case BinaryExpr.ResolvedOpcode.SetDifference:
          case BinaryExpr.ResolvedOpcode.MultiSetDifference:
            callString = "Difference";  break;

          case BinaryExpr.ResolvedOpcode.ProperPrefix:
            callString = "IsProperPrefixOf";  break;
          case BinaryExpr.ResolvedOpcode.Prefix:
            callString = "IsPrefixOf";  break;
          case BinaryExpr.ResolvedOpcode.Concat:
            callString = "Concat";  break;
          case BinaryExpr.ResolvedOpcode.InSeq:
            TrParenExpr(e.E1, wr, inLetExprBody);
            wr.Write(".Contains(");
            TrExpr(e.E0, wr, inLetExprBody);
            wr.Write(")");
            break;
          case BinaryExpr.ResolvedOpcode.NotInSeq:
            wr.Write("!");
            TrParenExpr(e.E1, wr, inLetExprBody);
            wr.Write(".Contains(");
            TrExpr(e.E0, wr, inLetExprBody);
            wr.Write(")");
            break;

          default:
            Contract.Assert(false); throw new cce.UnreachableException();  // unexpected binary expression
        }
        if (opString != null) {
          NativeType nativeType = AsNativeType(e.Type);
          bool needsCast = nativeType != null && nativeType.NeedsCastAfterArithmetic;
          if (needsCast) {
            wr.Write("(" + nativeType.Name + ")(");
          }
          wr.Write(preOpString);
          TrParenExpr(e.E0, wr, inLetExprBody);
          wr.Write(" {0} ", opString);
          TrParenExpr(e.E1, wr, inLetExprBody);
          if (needsCast) {
            wr.Write(")");
          }
        } else if (callString != null) {
          wr.Write(preOpString);
          TrParenExpr(e.E0, wr, inLetExprBody);
          wr.Write(".@{0}(", callString);
          TrExpr(e.E1, wr, inLetExprBody);
          wr.Write(")");
        }

      } else if (expr is TernaryExpr) {
        Contract.Assume(false);  // currently, none of the ternary expressions is compilable

      } else if (expr is LetExpr) {
        var e = (LetExpr)expr;
        if (e.Exact) {
          // The Dafny "let" expression
          //    var Pattern(x,y) := G; E
          // is translated into C# as:
          //    LamLet(G, tmp =>
          //      LamLet(dtorX(tmp), x =>
          //      LamLet(dtorY(tmp), y => E)))
          Contract.Assert(e.LHSs.Count == e.RHSs.Count);  // checked by resolution
          var neededCloseParens = 0;
          for (int i = 0; i < e.LHSs.Count; i++) {
            var lhs = e.LHSs[i];
            if (Contract.Exists(lhs.Vars, bv => !bv.IsGhost)) {
              var rhsName = string.Format("_pat_let{0}_{1}", GetUniqueAstNumber(e), i);
              wr.Write("Dafny.Helpers.Let<");
              wr.Write(TypeName(e.RHSs[i].Type, wr) + "," + TypeName(e.Body.Type, wr));
              wr.Write(">(");
              TrExpr(e.RHSs[i], wr, inLetExprBody);
              wr.Write(", " + rhsName + " => ");
              neededCloseParens++;
              var c = TrCasePattern(lhs, rhsName, e.Body.Type, wr);
              Contract.Assert(c != 0);  // we already checked that there's at least one non-ghost
              neededCloseParens += c;
            }
          }
          
          TrExpr(e.Body, wr, true);
          for (int i = 0; i < neededCloseParens; i++) {
            wr.Write(")");
          }
        } else if (e.BoundVars.All(bv => bv.IsGhost)) {
          // The Dafny "let" expression
          //    ghost var x,y :| Constraint; E
          // is compiled just like E is, because the resolver has already checked that x,y (or other ghost variables, for that matter) don't
          // occur in E (moreover, the verifier has checked that values for x,y satisfying Constraint exist).
          TrExpr(e.Body, wr, inLetExprBody);
        } else {
          // The Dafny "let" expression
          //    var x,y :| Constraint; E
          // is translated into C# as:
          //    LamLet(0, dummy => {  // the only purpose of this construction here is to allow us to add some code inside an expression in C#
          //        var x,y;
          //        // Embark on computation that fills in x,y according to Constraint; the computation stops when the first
          //        // such value is found, but since the verifier checks that x,y follows uniquely from Constraint, this is
          //        // not a source of nondeterminancy.
          //        return E;
          //      })
          Contract.Assert(e.RHSs.Count == 1);  // checked by resolution
          if (e.Constraint_MissingBounds != null) {
            foreach (var bv in e.Constraint_MissingBounds) {
              Error("this let-such-that expression is too advanced for the current compiler; Dafny's heuristics cannot find any bound for variable '{0}' (line {1})", wr, bv.Name, e.tok.line);
            }
          } else {
            wr.Write("Dafny.Helpers.Let<int," + TypeName(e.Body.Type, wr) + ">(0, _let_dummy_" + GetUniqueAstNumber(e) + " => {");
            foreach (var bv in e.BoundVars) {
              wr.Write("{0} @{1}", TypeName(bv.Type, wr), bv.CompileName);
              wr.WriteLine(" = {0};", DefaultValue(bv.Type, wr));
            }
            TrAssignSuchThat(0, new List<IVariable>(e.BoundVars).ConvertAll(bv => (IVariable)bv), e.RHSs[0], e.Constraint_Bounds, e.tok.line, wr, inLetExprBody);
            wr.Write(" return ");
            TrExpr(e.Body, wr, true);
            wr.Write("; })");
          }
        }

      } else  if (expr is MatchExpr) {
        var e = (MatchExpr)expr;
        // new Dafny.Helpers.Function<SourceType, TargetType>(delegate (SourceType _source) {
        //   if (source.is_Ctor0) {
        //     FormalType f0 = ((Dt_Ctor0)source._D).a0;
        //     ...
        //     return Body0;
        //   } else if (...) {
        //     ...
        //   } else if (true) {
        //     ...
        //   }
        // }(src)

        string source = idGenerator.FreshId("_source");
        wr.Write("new Dafny.Helpers.Function<{0}, {1}>(delegate ({0} {2}) {{ ", TypeName(e.Source.Type, wr), TypeName(e.Type, wr), source);

        if (e.Cases.Count == 0) {
          // the verifier would have proved we never get here; still, we need some code that will compile
          wr.Write("throw new System.Exception();");
        } else {
          int i = 0;
          var sourceType = (UserDefinedType)e.Source.Type.NormalizeExpand();
          foreach (MatchCaseExpr mc in e.Cases) {
            MatchCasePrelude(source, sourceType, cce.NonNull(mc.Ctor), mc.Arguments, i, e.Cases.Count, 0, wr);
            wr.Write("return ");
            TrExpr(mc.Body, wr, inLetExprBody);
            wr.Write("; ");
            i++;
          }
          wr.Write("}");
        }
        // We end with applying the source expression to the delegate we just built
        wr.Write("})(");
        TrExpr(e.Source, wr, inLetExprBody);
        wr.Write(")");

      } else if (expr is QuantifierExpr) {
        var e = (QuantifierExpr)expr;

        // Compilation does not check whether a quantifier was split.
        
        Contract.Assert(e.Bounds != null);  // for non-ghost quantifiers, the resolver would have insisted on finding bounds
        var n = e.BoundVars.Count;
        Contract.Assert(e.Bounds.Count == n);
        for (int i = 0; i < n; i++) {
          var bound = e.Bounds[i];
          var bv = e.BoundVars[i];
          // emit:  Dafny.Helpers.QuantX(boundsInformation, isForall, bv => body)
          if (bound is ComprehensionExpr.BoolBoundedPool) {
            wr.Write("Dafny.Helpers.QuantBool(");
          } else if (bound is ComprehensionExpr.CharBoundedPool) {
            wr.Write("Dafny.Helpers.QuantChar(");
          } else if (bound is ComprehensionExpr.IntBoundedPool) {
            var b = (ComprehensionExpr.IntBoundedPool)bound;
            wr.Write("Dafny.Helpers.QuantInt(");
            TrExpr(b.LowerBound, wr, inLetExprBody);
            wr.Write(", ");
            TrExpr(b.UpperBound, wr, inLetExprBody);
            wr.Write(", ");
          } else if (bound is ComprehensionExpr.SetBoundedPool) {
            var b = (ComprehensionExpr.SetBoundedPool)bound;
            wr.Write("Dafny.Helpers.QuantSet(");
            TrExpr(b.Set, wr, inLetExprBody);
            wr.Write(", ");
          } else if (bound is ComprehensionExpr.MapBoundedPool) {
            var b = (ComprehensionExpr.MapBoundedPool)bound;
            wr.Write("Dafny.Helpers.QuantMap(");
            TrExpr(b.Map, wr, inLetExprBody);
            wr.Write(", ");
          } else if (bound is ComprehensionExpr.SeqBoundedPool) {
            var b = (ComprehensionExpr.SeqBoundedPool)bound;
            wr.Write("Dafny.Helpers.QuantSeq(");
            TrExpr(b.Seq, wr, inLetExprBody);
            wr.Write(", ");
          } else if (bound is ComprehensionExpr.DatatypeBoundedPool) {
            var b = (ComprehensionExpr.DatatypeBoundedPool)bound;
            wr.Write("Dafny.Helpers.QuantDatatype(");

            wr.Write("{0}.AllSingletonConstructors, ", DtName(b.Decl));
          } else {
            Contract.Assert(false); throw new cce.UnreachableException();  // unexpected BoundedPool type
          }
          wr.Write("{0}, ", expr is ForallExpr ? "true" : "false");
          wr.Write("@{0} => ", bv.CompileName);
        }
        TrExpr(e.LogicalBody(true), wr, inLetExprBody);
        for (int i = 0; i < n; i++) {
          wr.Write(")");
        }

      } else if (expr is SetComprehension) {
        var e = (SetComprehension)expr;
        // For "set i,j,k,l | R(i,j,k,l) :: Term(i,j,k,l)" where the term has type "G", emit something like:
        // ((ComprehensionDelegate<G>)delegate() {
        //   var _coll = new List<G>();
        //   foreach (L l in sq.Elements) {
        //     foreach (K k in st.Elements) {
        //       for (BigInteger j = Lo; j < Hi; j++) {
        //         for (bool i in Helper.AllBooleans) {
        //           if (R(i,j,k,l)) {
        //             _coll.Add(Term(i,j,k,l));
        //           }
        //         }
        //       }
        //     }
        //   }
        //   return Dafny.Set<G>.FromCollection(_coll);
        // })()
        Contract.Assert(e.Bounds != null);  // the resolver would have insisted on finding bounds
        var typeName = TypeName(e.Type.AsSetType.Arg, wr);
        var collection_name = idGenerator.FreshId("_coll");
        wr.Write("((Dafny.Helpers.ComprehensionDelegate<{0}>)delegate() {{ ", typeName);
        wr.Write("var {0} = new System.Collections.Generic.List<{1}>(); ", collection_name, typeName);
        var n = e.BoundVars.Count;
        Contract.Assert(e.Bounds.Count == n);
        for (int i = 0; i < n; i++) {
          var bound = e.Bounds[i];
          var bv = e.BoundVars[i];
          if (bound is ComprehensionExpr.BoolBoundedPool) {
            wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.CompileName);
          } else if (bound is ComprehensionExpr.CharBoundedPool) {
            wr.Write("foreach (var @{0} in Dafny.Helpers.AllChars) {{ ", bv.CompileName);
          } else if (bound is ComprehensionExpr.IntBoundedPool) {
            var b = (ComprehensionExpr.IntBoundedPool)bound;
            if (AsNativeType(bv.Type) != null) {
              wr.Write("foreach (var @{0} in @{1}.IntegerRange(", bv.CompileName, bv.Type.AsNewtype.FullCompileName);
            } else {
              wr.Write("foreach (var @{0} in Dafny.Helpers.IntegerRange(", bv.CompileName);
            }
            TrExpr(b.LowerBound, wr, inLetExprBody);
            wr.Write(", ");
            TrExpr(b.UpperBound, wr, inLetExprBody);
            wr.Write(")) { ");
          } else if (bound is ComprehensionExpr.SetBoundedPool) {
            var b = (ComprehensionExpr.SetBoundedPool)bound;
            wr.Write("foreach (var @{0} in (", bv.CompileName);
            TrExpr(b.Set, wr, inLetExprBody);
            wr.Write(").Elements) { ");
          } else if (bound is ComprehensionExpr.MapBoundedPool) {
            var b = (ComprehensionExpr.MapBoundedPool)bound;
            wr.Write("foreach (var @{0} in (", bv.CompileName);
            TrExpr(b.Map, wr, inLetExprBody);
            wr.Write(").Domain) { ");
          } else if (bound is ComprehensionExpr.SeqBoundedPool) {
            var b = (ComprehensionExpr.SeqBoundedPool)bound;
            wr.Write("foreach (var @{0} in (", bv.CompileName);
            TrExpr(b.Seq, wr, inLetExprBody);
            wr.Write(").Elements) { ");
          } else if (bound is ComprehensionExpr.DatatypeBoundedPool) {
            var b = (ComprehensionExpr.DatatypeBoundedPool)bound;
            wr.Write("foreach (var @{0} in {1}.AllSingletonConstructors) {{", bv.CompileName, TypeName(bv.Type, wr));
          } else {
            Contract.Assert(false); throw new cce.UnreachableException();  // unexpected BoundedPool type
          }
        }
        wr.Write("if (");
        TrExpr(e.Range, wr, inLetExprBody);
        wr.Write(") {");
        wr.Write("{0}.Add(", collection_name);
        TrExpr(e.Term, wr, inLetExprBody);
        wr.Write("); }");
        for (int i = 0; i < n; i++) {
          wr.Write("}");
        }
        wr.Write("return Dafny.Set<{0}>.FromCollection({1}); ", typeName, collection_name);
        wr.Write("})()");

      } else if (expr is MapComprehension) {
        var e = (MapComprehension)expr;
        // For "map i | R(i) :: Term(i)" where the term has type "V" and i has type "U", emit something like:
        // ((MapComprehensionDelegate<U, V>)delegate() {
        //   var _coll = new List<Pair<U,V>>();
        //   foreach (L l in sq.Elements) {
        //     foreach (K k in st.Elements) {
        //       for (BigInteger j = Lo; j < Hi; j++) {
        //         for (bool i in Helper.AllBooleans) {
        //           if (R(i,j,k,l)) {
        //             _coll.Add(new Pair(i, Term(i));
        //           }
        //         }
        //       }
        //     }
        //   }
        //   return Dafny.Map<U, V>.FromElements(_coll);
        // })()
        Contract.Assert(e.Bounds != null);  // the resolver would have insisted on finding bounds
        var domtypeName = TypeName(e.Type.AsMapType.Domain, wr);
        var rantypeName = TypeName(e.Type.AsMapType.Range, wr);
        var collection_name = idGenerator.FreshId("_coll");
        wr.Write("((Dafny.Helpers.MapComprehensionDelegate<{0},{1}>)delegate() {{ ", domtypeName, rantypeName);
        wr.Write("var {0} = new System.Collections.Generic.List<Dafny.Pair<{1},{2}>>(); ", collection_name, domtypeName, rantypeName);
        var n = e.BoundVars.Count;
        Contract.Assert(e.Bounds.Count == n && n == 1);
        var bound = e.Bounds[0];
        var bv = e.BoundVars[0];
        if (bound is ComprehensionExpr.BoolBoundedPool) {
          wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.CompileName);
        } else if (bound is ComprehensionExpr.CharBoundedPool) {
          wr.Write("foreach (var @{0} in Dafny.Helpers.AllChars) {{ ", bv.CompileName);
        } else if (bound is ComprehensionExpr.IntBoundedPool) {
          var b = (ComprehensionExpr.IntBoundedPool)bound;
          if (AsNativeType(bv.Type) != null) {
            wr.Write("foreach (var @{0} in @{1}.IntegerRange(", bv.CompileName, bv.Type.AsNewtype.FullCompileName);
          } else {
            wr.Write("foreach (var @{0} in Dafny.Helpers.IntegerRange(", bv.CompileName);
          }
          TrExpr(b.LowerBound, wr, inLetExprBody);
          wr.Write(", ");
          TrExpr(b.UpperBound, wr, inLetExprBody);
          wr.Write(")) { ");
        } else if (bound is ComprehensionExpr.SetBoundedPool) {
          var b = (ComprehensionExpr.SetBoundedPool)bound;
          wr.Write("foreach (var @{0} in (", bv.CompileName);
          TrExpr(b.Set, wr, inLetExprBody);
          wr.Write(").Elements) { ");
        } else if (bound is ComprehensionExpr.MapBoundedPool) {
          var b = (ComprehensionExpr.MapBoundedPool)bound;
          wr.Write("foreach (var @{0} in (", bv.CompileName);
          TrExpr(b.Map, wr, inLetExprBody);
          wr.Write(").Domain) { ");
        } else if (bound is ComprehensionExpr.SeqBoundedPool) {
          var b = (ComprehensionExpr.SeqBoundedPool)bound;
          wr.Write("foreach (var @{0} in (", bv.CompileName);
          TrExpr(b.Seq, wr, inLetExprBody);
          wr.Write(").Elements) { ");
        } else {
          // TODO: handle ComprehensionExpr.SubSetBoundedPool
          Contract.Assert(false); throw new cce.UnreachableException();  // unexpected BoundedPool type
        }
        wr.Write("if (");
        TrExpr(e.Range, wr, inLetExprBody);
        wr.Write(") { ");
        wr.Write("{0}.Add(new Dafny.Pair<{1},{2}>(@{3},", collection_name, domtypeName, rantypeName, bv.CompileName);
        TrExpr(e.Term, wr, inLetExprBody);
        wr.Write(")); }");
        wr.Write("}");
        wr.Write("return Dafny.Map<{0},{1}>.FromCollection({2}); ", domtypeName, rantypeName, collection_name);
        wr.Write("})()");

      } else if (expr is LambdaExpr) {
        LambdaExpr e = (LambdaExpr)expr;

        var fvs = Translator.ComputeFreeVariables(expr);
        var sm = new Dictionary<IVariable, Expression>();

        var bvars = new List<BoundVar>();
        var fexprs = new List<Expression>();
        foreach(var fv in fvs) {
          fexprs.Add(new IdentifierExpr(fv.Tok, fv.Name) {
            Var = fv, // resolved here!
            Type = fv.Type
          });
          var bv = new BoundVar(fv.Tok, fv.Name, fv.Type);
          bvars.Add(bv);
          sm[fv] = new IdentifierExpr(bv.Tok, bv.Name) {
            Var = bv, // resolved here!
            Type = bv.Type
          };
        }

        var su = new Translator.Substituter(null, sm, new Dictionary<TypeParameter, Type>(), null);

        BetaRedex(bvars, fexprs, expr.Type, wr, inLetExprBody, () => {
          wr.Write("(");
          wr.Write(Util.Comma(e.BoundVars, bv => "@" + bv.CompileName));
          wr.Write(") => ");
          TrExpr(su.Substitute(e.Body), wr, inLetExprBody);
        });

      } else if (expr is StmtExpr) {
        var e = (StmtExpr)expr;
        TrExpr(e.E, wr, inLetExprBody);

      } else if (expr is ITEExpr) {
        ITEExpr e = (ITEExpr)expr;
        wr.Write("(");
        TrExpr(e.Test, wr, inLetExprBody);
        wr.Write(") ? (");
        TrExpr(e.Thn, wr, inLetExprBody);
        wr.Write(") : (");
        TrExpr(e.Els, wr, inLetExprBody);
        wr.Write(")");

      } else if (expr is ConcreteSyntaxExpression) {
        var e = (ConcreteSyntaxExpression)expr;
        TrExpr(e.ResolvedExpression, wr, inLetExprBody);

      } else if (expr is NamedExpr) {
        TrExpr(((NamedExpr)expr).Body, wr, inLetExprBody);
      } else {
        Contract.Assert(false); throw new cce.UnreachableException();  // unexpected expression
      }
    }
            public void AcceptMethodCallsVisitOnVisitorWithThis()
            {
                var name = new IdentifierExpr(RandomGenerator.String());
                var arguments = new VarDefinitionStmt[0];
                var body = new NoOpStatement();
                var returnType = new IdentifierExpr(RandomGenerator.String());

                var target = new FunctionDefinitionExpr(name, arguments, body, returnType);

                var visitor = new Mock<IExpressionVisitor<string, int>>();

                target.Accept(visitor.Object, 0);

                visitor.Verify(x => x.Visit(target, 0), Times.Once);
            }
Ejemplo n.º 45
0
 public override Expr VisitIdentifierExpr(IdentifierExpr node) {
   //Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<Expr>() != null);
   return base.VisitIdentifierExpr((IdentifierExpr)node.Clone());
 }
Ejemplo n.º 46
0
 public void ProtectedLambdaExprBody()
 {
     var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var y = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var xId = new IdentifierExpr(Token.NoToken, x, /*immutable=*/true);
     var yId = new IdentifierExpr(Token.NoToken, y, /*immutable=*/true);
     var body = Expr.Gt(xId, yId);
     var lambda = new LambdaExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable>() { x, y},
         null, body, /*immutable=*/true);
     lambda.Body = Expr.Lt(xId, yId); // Changing the body of an immutable ExistsExpr should fail
 }
Ejemplo n.º 47
0
  private void PredicateBlock(Expr pExpr, Block block, List<Block> newBlocks, ref Block prevBlock) {
    var firstBlock = block;

    var oldCmdSeq = block.Cmds;
    block.Cmds = new List<Cmd>();
    newBlocks.Add(block);
    if (prevBlock != null && !((prevBlock.TransferCmd is ReturnCmd) && uni != null && uni.IsUniform(impl.Name, block))) {
      prevBlock.TransferCmd = new GotoCmd(Token.NoToken, new List<Block> { block });
    }

    Block currentBlock = block;
    Expr pCurrentExpr = pExpr;
    while (parentMap.ContainsKey(currentBlock)) {
      Block parent = parentMap[currentBlock];
      Expr pParentExpr = null;
      if (predMap.ContainsKey(parent)) {
        var parentPred = predMap[parent];
        if (parentPred != null) {
          pParentExpr = Expr.Ident(parentPred);
          block.Cmds.Add(new AssertCmd(Token.NoToken,
                                          pCurrentExpr != null ? (Expr)Expr.Imp(pCurrentExpr, pParentExpr)
                                                               : pParentExpr));
        }
      }
      currentBlock = parent;
      pCurrentExpr = pParentExpr;
    }

    Block dominator = FindImmediateDominator(block);
    Expr pDomExpr = Expr.True;
    if (dominator != null && predMap.ContainsKey(dominator))
      pDomExpr = new IdentifierExpr(Token.NoToken, predMap[dominator]);
    var transferCmd = block.TransferCmd;
    foreach (Cmd cmd in oldCmdSeq)
      PredicateCmd(pExpr, pDomExpr, newBlocks, block, cmd, out block);

    if (ownedMap.ContainsKey(firstBlock)) {
      var owned = ownedMap[firstBlock];
      foreach (var v in owned)
        block.Cmds.Add(Cmd.SimpleAssign(Token.NoToken, Expr.Ident(v), Expr.False));
    }

    bool hasPredicatedRegion;
    PredicateTransferCmd(pExpr, block, block.Cmds, transferCmd, out hasPredicatedRegion);

    if (hasPredicatedRegion)
      prevBlock = block;
    else
      prevBlock = null;

    doneBlocks.Add(block);
  }
Ejemplo n.º 48
0
  void PredicateImplementation() {
    blockGraph = prog.ProcessLoops(impl);
    sortedBlocks = blockGraph.LoopyTopSort();

    AssignPredicates();
    partInfo = BuildPartitionInfo();

    if (myUseProcedurePredicates)
      fp = Expr.Ident(impl.InParams[0]);

    var newBlocks = new List<Block>();
    Block prevBlock = null;
    foreach (var n in sortedBlocks) {
      if (predMap.ContainsKey(n.Item1)) {
        var p = predMap[n.Item1];
        var pExpr = Expr.Ident(p);

        if (n.Item2) {
          var dominator = FindImmediateDominator(n.Item1);
          if (dominator != null && predMap.ContainsKey(dominator)) {
            AssumeCmd aCmd = new AssumeCmd(Token.NoToken, Expr.True);
            aCmd.Attributes = new QKeyValue(Token.NoToken, "dominator_predicate", new List<object>() { predMap[dominator].ToString() }, aCmd.Attributes);
            aCmd.Attributes = new QKeyValue(Token.NoToken, "predicate", new List<object>() { predMap[n.Item1].ToString() }, aCmd.Attributes);
            n.Item1.Cmds.Insert(0, aCmd);
          }

          var backedgeBlock = new Block();
          newBlocks.Add(backedgeBlock);

          backedgeBlock.Label = n.Item1.Label + ".backedge";
          backedgeBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken, pExpr,
            new QKeyValue(Token.NoToken, "backedge", new List<object>(), null)) };
          backedgeBlock.TransferCmd = new GotoCmd(Token.NoToken,
                                                  new List<Block> { n.Item1 });

          var tailBlock = new Block();
          newBlocks.Add(tailBlock);

          tailBlock.Label = n.Item1.Label + ".tail";
          tailBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken,
                                               Expr.Not(pExpr)) };

          if (uni != null && !uni.IsUniform(impl.Name, n.Item1)) {
            uni.AddNonUniform(impl.Name, backedgeBlock);
            uni.AddNonUniform(impl.Name, tailBlock);
          }

          if (prevBlock != null)
            prevBlock.TransferCmd = new GotoCmd(Token.NoToken,
                                          new List<Block> { backedgeBlock, tailBlock });
          prevBlock = tailBlock;
        } else {
          PredicateBlock(pExpr, n.Item1, newBlocks, ref prevBlock);
        }
      } else {
        if (!n.Item2) {
          PredicateBlock(null, n.Item1, newBlocks, ref prevBlock);
        }
      }
    }

    if (prevBlock != null)
      prevBlock.TransferCmd = new ReturnCmd(Token.NoToken);

    impl.Blocks = newBlocks;
  }
Ejemplo n.º 49
0
        void PredicateImplementation()
        {
            blockGraph = prog.ProcessLoops(impl);
            var sortedBlocks = blockGraph.LoopyTopSort();

            int blockId = 0;
            foreach (var block in impl.Blocks)
              blockIds[block] = Expr.Literal(blockId++);
            returnBlockId = Expr.Literal(blockId++);

            curVar = new LocalVariable(Token.NoToken,
                               new TypedIdent(Token.NoToken, "cur",
                                              Microsoft.Boogie.Type.Int));
            impl.LocVars.Add(curVar);
            cur = Expr.Ident(curVar);

            pVar = new LocalVariable(Token.NoToken,
                             new TypedIdent(Token.NoToken, "p",
                                            Microsoft.Boogie.Type.Bool));
            impl.LocVars.Add(pVar);
            p = Expr.Ident(pVar);

            if (useProcedurePredicates)
              fp = Expr.Ident(impl.InParams[0]);

            var newBlocks = new List<Block>();

            Block entryBlock = new Block();
            entryBlock.Label = "entry";
            entryBlock.Cmds = new List<Cmd> { Cmd.SimpleAssign(Token.NoToken, cur,
                        CreateIfFPThenElse(blockIds[sortedBlocks[0].Item1],
                                           returnBlockId)) };
            newBlocks.Add(entryBlock);

            var prevBlock = entryBlock;
            foreach (var n in sortedBlocks) {
              if (n.Item2) {
            var backedgeBlock = new Block();
            newBlocks.Add(backedgeBlock);

            backedgeBlock.Label = n.Item1.Label + ".backedge";
            backedgeBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken,
              Expr.Eq(cur, blockIds[n.Item1]),
              new QKeyValue(Token.NoToken, "backedge", new List<object>(), null)) };
            backedgeBlock.TransferCmd = new GotoCmd(Token.NoToken,
                                                new List<Block> { n.Item1 });

            var tailBlock = new Block();
            newBlocks.Add(tailBlock);

            tailBlock.Label = n.Item1.Label + ".tail";
            tailBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken,
                                             Expr.Neq(cur, blockIds[n.Item1])) };

            prevBlock.TransferCmd = new GotoCmd(Token.NoToken,
                                        new List<Block> { backedgeBlock, tailBlock });
            prevBlock = tailBlock;
              } else {
            var runBlock = n.Item1;
            var oldCmdSeq = runBlock.Cmds;
            runBlock.Cmds = new List<Cmd>();
            newBlocks.Add(runBlock);
            prevBlock.TransferCmd = new GotoCmd(Token.NoToken,
                                            new List<Block> { runBlock });

            pExpr = Expr.Eq(cur, blockIds[runBlock]);
            if (createCandidateInvariants && blockGraph.Headers.Contains(runBlock)) {
              AddUniformCandidateInvariant(runBlock.Cmds, runBlock);
              AddNonUniformCandidateInvariant(runBlock.Cmds, runBlock);
            }
            runBlock.Cmds.Add(Cmd.SimpleAssign(Token.NoToken, p, pExpr));
            var transferCmd = runBlock.TransferCmd;
            foreach (Cmd cmd in oldCmdSeq)
              PredicateCmd(newBlocks, runBlock, cmd, out runBlock);
            PredicateTransferCmd(runBlock.Cmds, transferCmd);

            prevBlock = runBlock;
            doneBlocks.Add(runBlock);
              }
            }

            prevBlock.TransferCmd = new ReturnCmd(Token.NoToken);
            impl.Blocks = newBlocks;
        }
Ejemplo n.º 50
0
    public override Cmd VisitCallCmd(CallCmd node)
    {
      var result = base.VisitCallCmd(node);

      var oldProc = programInCachedSnapshot.FindProcedure(node.Proc.Name);
      if (oldProc != null
          && oldProc.DependencyChecksum != node.Proc.DependencyChecksum
          && node.AssignedAssumptionVariable == null)
      {
        var before = new List<Cmd>();
        var beforePrecondtionCheck = new List<Cmd>();
        var after = new List<Cmd>();
        var axioms = new List<Axiom>();
        Expr assumedExpr = new LiteralExpr(Token.NoToken, false);
        // TODO(wuestholz): Try out two alternatives: only do this for low priority implementations or not at all.
        var canUseSpecs = DependencyCollector.CanExpressOldSpecs(oldProc, Program);
        if (canUseSpecs && oldProc.SignatureEquals(node.Proc))
        {
          var desugaring = node.Desugaring;
          Contract.Assert(desugaring != null);
          var precond = node.CheckedPrecondition(oldProc, Program, e => FunctionExtractor.Extract(e, Program, axioms));
          if (precond != null)
          {
            var assume = new AssumeCmd(node.tok, precond, new QKeyValue(Token.NoToken, "precondition_previous_snapshot", new List<object>(), null));
            assume.IrrelevantForChecksumComputation = true;
            beforePrecondtionCheck.Add(assume);
          }

          var unmods = node.UnmodifiedBefore(oldProc);
          var eqs = new List<Expr>();
          foreach (var unmod in unmods)
          {
            var oldUnmod = new LocalVariable(Token.NoToken,
              new TypedIdent(Token.NoToken, string.Format("{0}##old##{1}", unmod.Name, FreshTemporaryVariableName), unmod.Type));
            var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, oldUnmod));
            var rhs = new IdentifierExpr(Token.NoToken, unmod.Decl);
            var cmd = new AssignCmd(Token.NoToken, new List<AssignLhs> { lhs }, new List<Expr> { rhs });
            cmd.IrrelevantForChecksumComputation = true;
            before.Add(cmd);
            var eq = LiteralExpr.Eq(new IdentifierExpr(Token.NoToken, oldUnmod), new IdentifierExpr(Token.NoToken, unmod.Decl));
            eq.Type = Type.Bool;
            eq.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
            eqs.Add(eq);
          }

          var mods = node.ModifiedBefore(oldProc);
          var oldSubst = new Dictionary<Variable, Expr>();
          foreach (var mod in mods)
          {
            var oldMod = new LocalVariable(Token.NoToken,
              new TypedIdent(Token.NoToken, string.Format("{0}##old##{1}", mod.Name, FreshTemporaryVariableName), mod.Type));
            oldSubst[mod.Decl] = new IdentifierExpr(Token.NoToken, oldMod);
            var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, oldMod));
            var rhs = new IdentifierExpr(Token.NoToken, mod.Decl);
            var cmd = new AssignCmd(Token.NoToken, new List<AssignLhs> { lhs }, new List<Expr> { rhs });
            cmd.IrrelevantForChecksumComputation = true;
            before.Add(cmd);
          }
          
          assumedExpr = node.Postcondition(oldProc, eqs, oldSubst, Program, e => FunctionExtractor.Extract(e, Program, axioms));
          if (assumedExpr == null)
          {
            assumedExpr = new LiteralExpr(Token.NoToken, true);
          }
        }

        if (assumedExpr != null)
        {
          var lv = new LocalVariable(Token.NoToken,
            new TypedIdent(Token.NoToken, string.Format("a##cached##{0}", FreshAssumptionVariableName), Type.Bool),
            new QKeyValue(Token.NoToken, "assumption", new List<object>(), null));
          node.AssignedAssumptionVariable = lv;
          currentImplementation.InjectAssumptionVariable(lv, !canUseSpecs);
          var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, lv));
          var rhs = LiteralExpr.And(new IdentifierExpr(Token.NoToken, lv), assumedExpr);
          var assumed = new AssignCmd(node.tok, new List<AssignLhs> { lhs }, new List<Expr> { rhs });
          assumed.IrrelevantForChecksumComputation = true;
          after.Add(assumed);
        }

        node.ExtendDesugaring(before, beforePrecondtionCheck, after);
        if (CommandLineOptions.Clo.TraceCachingForTesting || CommandLineOptions.Clo.TraceCachingForBenchmarking)
        {
          using (var tokTxtWr = new TokenTextWriter("<console>", Console.Out, false, false))
          {
            var loc = node.tok != null && node.tok != Token.NoToken ? string.Format("{0}({1},{2})", node.tok.filename, node.tok.line, node.tok.col) : "<unknown location>";
            Console.Out.WriteLine("Processing call to procedure {0} in implementation {1} (at {2}):", node.Proc.Name, currentImplementation.Name, loc);
            foreach (var a in axioms)
            {
              Console.Out.Write("  >>> added axiom: ");
              a.Expr.Emit(tokTxtWr);
              Console.Out.WriteLine();
            }
            foreach (var b in before)
            {
              Console.Out.Write("  >>> added before: ");
              b.Emit(tokTxtWr, 0);
            }
            foreach (var b in beforePrecondtionCheck)
            {
              Console.Out.Write("  >>> added before precondition check: ");
              b.Emit(tokTxtWr, 0);
            }
            foreach (var a in after)
            {
              Console.Out.Write("  >>> added after: ");
              a.Emit(tokTxtWr, 0);
            }
          }
        }
      }

      return result;
    }
            public void AcceptMethodCallsOnlyVisitOnVisitorWithThisAndNoOtherVisitMethods()
            {
                var name = new IdentifierExpr(RandomGenerator.String());
                var arguments = new VarDefinitionStmt[0];
                var body = new NoOpStatement();
                var returnType = new IdentifierExpr(RandomGenerator.String());

                var target = new FunctionDefinitionExpr(name, arguments, body, returnType);

                // throw exception is any other methods called other than the PlusExpr overload.
                var visitor = new Mock<IExpressionVisitor<string, int>>(MockBehavior.Strict);
                visitor.Setup(x => x.Visit(target, 1234)).Returns("");

                target.Accept(visitor.Object, 1234);
            }
Ejemplo n.º 52
0
 private NAryExpr GetUnTypedImmutableNAry()
 {
     var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/true);
     Assert.IsTrue(id.Immutable);
     Assert.IsTrue(id.Type.IsBool);
     var e = new NAryExpr(Token.NoToken, new BinaryOperator(Token.NoToken, BinaryOperator.Opcode.And), new List<Expr>() {
         id,
         id
     }, /*immutable=*/true);
     Assert.IsNull(e.Type);
     Assert.IsTrue(e.Immutable);
     return e;
 }
Ejemplo n.º 53
0
 public void ProtectedForAllExprBody()
 {
     var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var y = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var xId = new IdentifierExpr(Token.NoToken, x, /*immutable=*/true);
     var yId = new IdentifierExpr(Token.NoToken, y, /*immutable=*/true);
     var body = Expr.Gt(xId, yId);
     var forAll = new ForallExpr(Token.NoToken, new List<Variable> () { x, y }, body, /*immutable=*/true);
     forAll.Body = Expr.Lt(xId, yId); // Changing the body of an immutable ForAllExpr should fail
 }
Ejemplo n.º 54
0
  void PredicateCmd(Expr p, Expr pDom, List<Cmd> cmdSeq, Cmd cmd) {
    if (cmd is CallCmd) {
      var cCmd = (CallCmd)cmd;
      Debug.Assert(useProcedurePredicates(cCmd.Proc));
      cCmd.Ins.Insert(0, p != null ? p : Expr.True);
      cmdSeq.Add(cCmd);
    } else if (p == null) {
      new EnabledReplacementVisitor(Expr.True, pDom).Visit(cmd);
      cmdSeq.Add(cmd);
    } else if (cmd is AssignCmd) {
      var aCmd = (AssignCmd)cmd;
      cmdSeq.Add(new AssignCmd(Token.NoToken, aCmd.Lhss,
                   new List<Expr>(aCmd.Lhss.Zip(aCmd.Rhss, (lhs, rhs) =>
                     new NAryExpr(Token.NoToken,
                       new IfThenElse(Token.NoToken),
                       new List<Expr> { p, rhs, lhs.AsExpr })))));
    } else if (cmd is AssertCmd) {
      var aCmd = (AssertCmd)cmd;
      Expr newExpr = new EnabledReplacementVisitor(p, pDom).VisitExpr(aCmd.Expr);
      aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(p, newExpr);
      cmdSeq.Add(aCmd);
    } else if (cmd is AssumeCmd) {
      var aCmd = (AssumeCmd)cmd;
      Expr newExpr = new EnabledReplacementVisitor(p, pDom).VisitExpr(aCmd.Expr);
      aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(p, newExpr);
      cmdSeq.Add(aCmd);
    } else if (cmd is HavocCmd) {
      var hCmd = (HavocCmd)cmd;
      foreach (IdentifierExpr v in hCmd.Vars) {
        Microsoft.Boogie.Type type = v.Decl.TypedIdent.Type;
        Contract.Assert(type != null);

        IdentifierExpr havocTempExpr;
        if (havocVars.ContainsKey(type)) {
          havocTempExpr = havocVars[type];
        } else {
          var havocVar = new LocalVariable(Token.NoToken,
                             new TypedIdent(Token.NoToken,
                                            "_HAVOC_" + type.ToString(), type));
          impl.LocVars.Add(havocVar);
          havocVars[type] = havocTempExpr =
            new IdentifierExpr(Token.NoToken, havocVar);
        }
        cmdSeq.Add(new HavocCmd(Token.NoToken,
                                new List<IdentifierExpr> { havocTempExpr }));
        cmdSeq.Add(Cmd.SimpleAssign(Token.NoToken, v,
                                    new NAryExpr(Token.NoToken,
                                      new IfThenElse(Token.NoToken),
                                      new List<Expr> { p, havocTempExpr, v })));
      }
    } else if (cmd is CommentCmd) {
      // skip
    } else if (cmd is StateCmd) {
      var sCmd = (StateCmd)cmd;
      var newCmdSeq = new List<Cmd>();
      foreach (Cmd c in sCmd.Cmds)
        PredicateCmd(p, pDom, newCmdSeq, c);
      sCmd.Cmds = newCmdSeq;
      cmdSeq.Add(sCmd);
    } else {
      Console.WriteLine("Unsupported cmd: " + cmd.GetType().ToString());
    }
  }
Ejemplo n.º 55
0
        void PredicateCmd(List<Cmd> cmdSeq, Cmd cmd)
        {
            if (cmd is AssignCmd) {
              var aCmd = (AssignCmd)cmd;
              cmdSeq.Add(new AssignCmd(Token.NoToken, aCmd.Lhss,
                   new List<Expr>(aCmd.Lhss.Zip(aCmd.Rhss, (lhs, rhs) =>
                     new NAryExpr(Token.NoToken,
                       new IfThenElse(Token.NoToken),
                       new List<Expr> { p, rhs, lhs.AsExpr })))));
            } else if (cmd is AssertCmd) {
              var aCmd = (AssertCmd)cmd;
              if (cmdSeq.Last() is AssignCmd &&
              cmdSeq.Cast<Cmd>().SkipEnd(1).All(c => c is AssertCmd)) {
            // This may be a loop invariant.  Make sure it continues to appear as
            // the first statement in the block.
            var assign = cmdSeq.Last();
            cmdSeq.RemoveAt(cmdSeq.Count-1);
            Expr newExpr = new EnabledReplacementVisitor(pExpr).VisitExpr(aCmd.Expr);
            aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(pExpr, newExpr);
            cmdSeq.Add(aCmd);
            // cmdSeq.Add(new AssertCmd(aCmd.tok, Expr.Imp(pExpr, aCmd.Expr)));
            cmdSeq.Add(assign);
              } else {
            aCmd.Expr = Expr.Imp(p, aCmd.Expr);
            cmdSeq.Add(aCmd);
            // cmdSeq.Add(new AssertCmd(aCmd.tok, Expr.Imp(p, aCmd.Expr)));
              }
            } else if (cmd is AssumeCmd) {
              var aCmd = (AssumeCmd)cmd;
              cmdSeq.Add(new AssumeCmd(Token.NoToken, Expr.Imp(p, aCmd.Expr)));
            } else if (cmd is HavocCmd) {
              var hCmd = (HavocCmd)cmd;
              foreach (IdentifierExpr v in hCmd.Vars) {
            Microsoft.Boogie.Type type = v.Decl.TypedIdent.Type;
            Contract.Assert(type != null);

            IdentifierExpr havocTempExpr;
            if (havocVars.ContainsKey(type)) {
              havocTempExpr = havocVars[type];
            } else {
              var havocVar = new LocalVariable(Token.NoToken,
                             new TypedIdent(Token.NoToken,
                                            "_HAVOC_" + type.ToString(), type));
              impl.LocVars.Add(havocVar);
              havocVars[type] = havocTempExpr =
            new IdentifierExpr(Token.NoToken, havocVar);
            }
            cmdSeq.Add(new HavocCmd(Token.NoToken,
                                new List<IdentifierExpr> { havocTempExpr }));
            cmdSeq.Add(Cmd.SimpleAssign(Token.NoToken, v,
                                    new NAryExpr(Token.NoToken,
                                      new IfThenElse(Token.NoToken),
                                      new List<Expr> { p, havocTempExpr, v })));
              }
            } else if (cmd is CallCmd) {
              Debug.Assert(useProcedurePredicates);
              var cCmd = (CallCmd)cmd;
              cCmd.Ins.Insert(0, p);
              cmdSeq.Add(cCmd);
            }
            else if (cmd is CommentCmd) {
              // skip
            }
            else if (cmd is StateCmd) {
              var sCmd = (StateCmd)cmd;
              var newCmdSeq = new List<Cmd>();
              foreach (Cmd c in sCmd.Cmds)
            PredicateCmd(newCmdSeq, c);
              sCmd.Cmds = newCmdSeq;
              cmdSeq.Add(sCmd);
            }
            else {
              Console.WriteLine("Unsupported cmd: " + cmd.GetType().ToString());
            }
        }
Ejemplo n.º 56
0
 public static IdentifierExpr MakeIdentifierExpr(string name, Type type, bool isGhost)
 {
     Util.Assert(type != null);
     IdentifierExpr id = new IdentifierExpr(Bpl.Token.NoToken, name);
     id.Type = type;
     id.Var = new LocalVariable(Bpl.Token.NoToken, Bpl.Token.NoToken, name, type, isGhost);
     return id;
 }
Ejemplo n.º 57
0
      public override Expr VisitIdentifierExpr(IdentifierExpr node) {
        //Contract.Requires(node != null);
        Contract.Ensures(Contract.Result<Expr>() != null);
        Expr/*?*/ e = null;

        if (insideOldExpr) {
          e = forold(cce.NonNull(node.Decl));
        }

        if (e == null) {
          e = always(cce.NonNull(node.Decl));
        }

        return e == null ? base.VisitIdentifierExpr(node) : e;
      }
Ejemplo n.º 58
0
 public override void Visit(IdentifierExpr identifierNode)
 {
     identifierNode.ExprValue = SymbolTable.GetSymbolValue(identifierNode.IdentifierName);
 }
Ejemplo n.º 59
0
 public Tuple<Method,TypeApply> GetSeqBuildMethod(Type t, SeqTree tree, List<bool> elemDimensions)
 {
     
     
     if (elemDimensions.Count == 0)
     {
         return GetSeqMethod(t, "seq_Empty");
     }
     if (elemDimensions.Count == 2 && elemDimensions[0] && elemDimensions[1])
     {
         return GetSeqMethod(t, "seq_Append");
     }
     string op = "seq_" + SeqTree.TreeName(tree);
     DatatypeDecl seqDecl = FindDatatype("Seq");
     var tok = new Bpl.Token(0, 0);
     tok.filename = @"!\Seq.dfy";
     TypeApply tApp = Compile_SeqType((SeqType)t);
     Type dataType = new UserDefinedType(tok, "Seq", seqDecl, new List<Type> { ((SeqType)t).Arg });
     Type elemType = ((SeqType)t).Arg;
     Func<string,Type,Expression> idExpr = (x, typ) => {
         var e = new IdentifierExpr(tok, x);
         e.Type = typ;
         e.Var = new LocalVariable(tok, tok, x, typ, false);
         return e;
     };
     Func<string,List<Expression>,FunctionCallExpr> seqCall = (x, args) => {
         var seqOp = GetSeqOperation(t, x);
         FunctionCallExpr callExpr = new FunctionCallExpr(
             tok, "Seq_Empty", new ThisExpr(tok), tok, args);
         callExpr.Function = seqOp.Item1;
         callExpr.TypeArgumentSubstitutions = seqOp.Item2.typeArgs;
         return callExpr;
     };
     Expression empty = seqCall("Seq_Empty", new List<Expression> {});
     int varCount = 0;
     Func<SeqTree,Expression> resultRec = null;
     resultRec = (subtree) =>
     {
         if (subtree == null)
         {
             return idExpr("s" + (varCount++), dataType);
         }
         if (subtree.buildCount >= 0)
         {
             Expression build = empty;
             for (int i = 0; i < subtree.buildCount; i++)
             {
                 build = seqCall("Seq_Build", new List<Expression>
                     { build, idExpr("a" + (varCount++), elemType) });
             }
             return build;
         }
         else
         {
             return seqCall("Seq_Append", new List<Expression>
                 { resultRec(subtree.left), resultRec(subtree.right) });
         }
     };
     Expression result = resultRec(tree);
     Expression post = seqCall("Seq_Equal", new List<Expression> { idExpr("s", dataType), result });
     List<Statement> stmts = new List<Statement>();
     for (int i = elemDimensions.Count; i > 0;)
     {
         bool isFirst = (i == elemDimensions.Count);
         i--;
         if (elemDimensions[i])
         {
             if (isFirst)
             {
                 
                 stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType),
                     new ExprRhs(idExpr("s" + i, dataType))));
             }
             else
             {
                 // s := seq_Append(s9, s);
                 var selectExpr = new MemberSelectExpr(tok, new ThisExpr(tok), "seq_Append");
                 selectExpr.Member = FindMethod(selectExpr.MemberName);  // Manually resolve here
                 selectExpr.TypeApplication = new List<Type>() { elemType }; // Manually resolve here
                 selectExpr.Type = new InferredTypeProxy();  // Manually resolve here
                 
                 CallStmt callStmt = new CallStmt(tok, tok,
                     new List<Expression> {idExpr("s", dataType)},
                     selectExpr, new List<Expression>
                         { idExpr("s" + i, dataType), idExpr("s", dataType) });                                                        
                 stmts.Add(callStmt);
             }
         }
         else
         {
             if (isFirst)
             {
                 
                 DatatypeValue nil = new DatatypeValue(tok, "Seq", "Nil", new List<Expression>() {});
                 nil.Type = dataType;
                 nil.InferredTypeArgs = new List<Type> { elemType };
                 nil.Ctor = seqDecl.Ctors[0];
                 Util.Assert(nil.Ctor.Name == "Seq_Nil");
                 stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType), new ExprRhs(nil)));
             }
             // lemma_Seq_Cons(ai, s);
             var selectExpr = new MemberSelectExpr(tok, new ThisExpr(tok), "lemma_Seq_Cons");                
             selectExpr.Member = FindMethod(selectExpr.MemberName);   // Manually resolve here
             selectExpr.TypeApplication = new List<Type>() { elemType }; // Manually resolve here
             selectExpr.Type = new InferredTypeProxy();  // Manually resolve here
             
             CallStmt callStmt = new CallStmt(tok, tok,
                 new List<Expression> {},
                 selectExpr, new List<Expression>
                     { idExpr("a" + i, elemType), idExpr("s", dataType) });                                
             callStmt.IsGhost = true;
             stmts.Add(callStmt);
             
             DatatypeValue cons = new DatatypeValue(tok, "Seq", "Cons", new List<Expression>()
                 { idExpr("a" + i, elemType), idExpr("s", dataType) });
             cons.Type = dataType;
             cons.InferredTypeArgs = new List<Type> { elemType };
             cons.Ctor = seqDecl.Ctors[1];
             Util.Assert(cons.Ctor.Name == "Seq_Cons");
             stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType), new ExprRhs(cons)));
         }
     }
     BlockStmt body = new BlockStmt(tok, tok, stmts);
     List<Formal> ins = new List<Formal>();
     for (int i = 0; i < elemDimensions.Count; i++)
     {
         bool isSeq = elemDimensions[i];
         ins.Add(new Formal(tok, (isSeq ? "s" : "a") + i, isSeq ? dataType : elemType, true, false));
     }
     List<Formal> outs = new List<Formal> { new Formal(tok, "s", dataType, false, false) };
     List<MaybeFreeExpression> reqs = new List<MaybeFreeExpression>();
     List<MaybeFreeExpression> enss = new List<MaybeFreeExpression> { new MaybeFreeExpression(post) };
     Specification<FrameExpression> mods = new Specification<FrameExpression>(new List<FrameExpression>(), null);
     Specification<Expression> decs = new Specification<Expression>(new List<Expression>(), null);
     Attributes attrs = new Attributes("dafnycc_conservative_seq_triggers", new List<Expression>(), null);
     Method m = new Method(tok, op, true, false, tApp.typeParams, ins, outs, reqs, mods, enss, decs, body, attrs, tok);
     m.EnclosingClass = GetSeqMethod(t, "seq_Append").Item1.EnclosingClass;
     return Tuple.Create(m, Compile_Method(m, tApp.typeArgs));
 }
Ejemplo n.º 60
0
 public override Expr VisitIdentifierExpr(IdentifierExpr node)
 {
   if (node.Decl == null || !(node.Decl is LocalVariable || node.Decl is Formal || node.Decl is GlobalVariable))
   {
     return node;
   }
   else
   {
     BoundVariable boundVar;
     if (!Substitutions.TryGetValue(node.Decl, out boundVar))
     {
       boundVar = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, node.Name, node.Type));
       Substitutions[node.Decl] = boundVar;
     }
     return new IdentifierExpr(node.tok, boundVar);
   }
 }