Пример #1
0
 public override Expr VisitNAryExpr(NAryExpr node)
 {
     //Contract.Requires(node != null);
       Contract.Ensures(Contract.Result<Expr>() != null);
       CheckTypeParams(node, cce.NonNull(node.TypeParameters));
       return base.VisitNAryExpr(node);
 }
Пример #2
0
        public void FunctionCall()
        {
            var fc = CreateFunctionCall("bv8slt", Microsoft.Boogie.Type.Bool, new List<Microsoft.Boogie.Type>() {
                BasicType.GetBvType(8),
                BasicType.GetBvType(8)
            });

            var constantBv = new LiteralExpr(Token.NoToken, BigNum.FromInt(0) , 8);
            var nary = new NAryExpr(Token.NoToken,fc, new List<Expr>() { constantBv, constantBv} );

            // Get shallow type (this was broken when this test was written)
            Assert.AreEqual(BasicType.Bool, nary.ShallowType);

            // Deep type check (this was not broken before writing this test)
            Assert.IsNull(nary.Type);

            var tc = new TypecheckingContext(this);
            nary.Typecheck(tc);

            Assert.AreEqual(BasicType.Bool, nary.Type);
        }
Пример #3
0
 public override Expr VisitNAryExpr(NAryExpr node) {
   if (node.Fun is BinaryOperator) {
     var op = (BinaryOperator)node.Fun;
     Contract.Assert(node.Args.Count == 2);
     var arg0 = node.Args[0];
     var arg1 = node.Args[1];
     var offset = arg0.Type.IsReal ? 0 : 1;
     BigInteger? k;
     switch (op.Op) {
       case BinaryOperator.Opcode.Eq:
       case BinaryOperator.Opcode.Neq:
         k = AsIntLiteral(arg0);
         if (k != null) {
           var i = (BigInteger)k;
           downs.Add(i - 1);
           downs.Add(i);
           ups.Add(i + 1);
           ups.Add(i + 2);
         }
         k = AsIntLiteral(arg1);
         if (k != null) {
           var i = (BigInteger)k;
           downs.Add(i - 1);
           downs.Add(i);
           ups.Add(i + 1);
           ups.Add(i + 2);
         }
         break;
       case BinaryOperator.Opcode.Le:
         k = AsIntLiteral(arg0);
         if (k != null) {
           var i = (BigInteger)k;
           downs.Add(i - 1);
           downs.Add(i);
         }
         k = AsIntLiteral(arg1);
         if (k != null) {
           var i = (BigInteger)k;
           ups.Add(i + offset);
           ups.Add(i + 1 + offset);
         }
         break;
       case BinaryOperator.Opcode.Lt:
         k = AsIntLiteral(arg0);
         if (k != null) {
           var i = (BigInteger)k;
           downs.Add(i );
           downs.Add(i + 1);
         }
         k = AsIntLiteral(arg1);
         if (k != null) {
           var i = (BigInteger)k;
           ups.Add(i - 1 + offset);
           ups.Add(i + offset);
         }
         break;
       case BinaryOperator.Opcode.Ge:
         { var tmp = arg0; arg0 = arg1; arg1 = tmp; }
         goto case BinaryOperator.Opcode.Le;
       case BinaryOperator.Opcode.Gt:
         { var tmp = arg0; arg0 = arg1; arg1 = tmp; }
         goto case BinaryOperator.Opcode.Lt;
       default:
         break;
     }
   }
   return base.VisitNAryExpr(node);
 }
Пример #4
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;
 }
Пример #5
0
 public override Expr VisitNAryExpr(NAryExpr node)
 {
     node.Args = node.Args.Select(arg => VisitExpr(arg)).ToList();
     return(node);
 }
Пример #6
0
 public override Expr VisitNAryExpr(NAryExpr node)
 {
   if (currentTrigger != null)
   {
     // We found a function call within a trigger of a quantifier expression.
     var funCall = node.Fun as FunctionCall;
     if (funCall != null && funCall.Func != null && funCall.Func.Checksum != null && funCall.Func.Checksum != "stable")
     {
       funCall.Func.AddOtherDefinitionAxiom(currentAxiom);
     }
   }
   return base.VisitNAryExpr(node);
 }
Пример #7
0
 private Expr SubsetExprs(LinearDomain domain, HashSet<Variable> scope, Variable partition, int count, Expr expr)
 {
     foreach (Variable v in scope)
     {
         if (!domain.collectors.ContainsKey(v.TypedIdent.Type)) continue;
         Expr ie = new NAryExpr(Token.NoToken, new FunctionCall(domain.collectors[v.TypedIdent.Type]), new List<Expr> { Expr.Ident(v) });
         expr = Expr.And(SubsetExpr(domain, ie, partition, count), expr);
         count++;
     }
     expr = new ExistsExpr(Token.NoToken, new List<Variable> { partition }, expr);
     expr.Resolve(new ResolutionContext(null));
     expr.Typecheck(new TypecheckingContext(null));
     return expr;
 }
Пример #8
0
            public override Expr VisitNAryExpr(NAryExpr node)
            {
                if (node.Fun is FunctionCall)
                {
                    var collector = new VariableCollector();
                    collector.Visit(node);

                    functionsUsed.Add((node.Fun as FunctionCall).Func);
                }

                return base.VisitNAryExpr(node);
            }
Пример #9
0
 public virtual Expr VisitNAryExpr(NAryExpr node) {
   Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<Expr>() != null);
   node.Args = this.VisitExprSeq(node.Args);
   return node;
 }
        public override List <Cmd> VisitCmdSeq(List <Cmd> cmdSeq)
        {
            List <Cmd> newCmdSeq = new List <Cmd>();

            foreach (Cmd c in cmdSeq)
            {
                //Do special stuff for those whose BAP modeling is broken
                if (c is AssertCmd) //call and return instructions are marked with attributes
                {
                    AssertCmd ac = c as AssertCmd;

                    string attribute_cmdtype = QKeyValue.FindStringAttribute(ac.Attributes, "SlashVerifyCommandType");
                    if (attribute_cmdtype != null && attribute_cmdtype.Equals("btc_rax_1d"))
                    {
                        //BAP has a bug with this. Model it explicitly ourselves.

                        //CF := RAX[30:29];
                        newCmdSeq.Add(new AssignCmd(Token.NoToken,
                                                    new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.CF))
                        },
                                                    new List <Expr>()
                        {
                            new BvExtractExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, this.RAX), 30, 29)
                        }
                                                    ));
                        //RAX := RAX[64:30] ++ NOT(RAX[30:29]) ++ RAX[29:0];
                        Expr e1 = new BvExtractExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, this.RAX), 64, 30);
                        Expr e2 = new NAryExpr(Token.NoToken, new FunctionCall(this.not_1),
                                               new List <Expr>()
                        {
                            new BvExtractExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, this.RAX), 30, 29)
                        });
                        Expr e3 = new BvExtractExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, this.RAX), 29, 0);
                        newCmdSeq.Add(new AssignCmd(Token.NoToken,
                                                    new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.RAX))
                        },
                                                    new List <Expr>()
                        {
                            new BvConcatExpr(Token.NoToken, new BvConcatExpr(Token.NoToken, e1, e2), e3)
                        }
                                                    ));
                    }
                    else if (attribute_cmdtype != null && attribute_cmdtype.Equals("rep_stosb"))
                    {
                        //BAP does not model this either. Model rep stosb as sequence: mem := repstosb(mem, rcx, rdi, al); rdi := rdi + rcx; rcx := 0;

                        //forall i. rdi <= i < rdi + rcx ==> new_mem[i] == al;
                        newCmdSeq.Add(new AssignCmd(Token.NoToken,
                                                    new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.mem))
                        },
                                                    new List <Expr>()
                        {
                            new NAryExpr(Token.NoToken, new FunctionCall(rep_stosb), new List <Expr>()
                            {
                                new IdentifierExpr(Token.NoToken, this.mem),
                                new IdentifierExpr(Token.NoToken, this.RCX),
                                new IdentifierExpr(Token.NoToken, this.RDI),
                                new BvExtractExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, this.RAX), 8, 0)
                            })
                        }
                                                    ));

                        //RDI := RDI + RCX;
                        newCmdSeq.Add(new AssignCmd(Token.NoToken, new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.RDI))
                        },
                                                    new List <Expr>()
                        {
                            new NAryExpr(Token.NoToken, new FunctionCall(this.plus_64), new List <Expr>()
                            {
                                new IdentifierExpr(Token.NoToken, this.RDI), new IdentifierExpr(Token.NoToken, this.RCX)
                            })
                        }
                                                    ));

                        //RCX := 0;
                        newCmdSeq.Add(new AssignCmd(Token.NoToken, new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.RCX))
                        },
                                                    new List <Expr>()
                        {
                            new LiteralExpr(Token.NoToken, BigNum.ZERO, 64)
                        }));
                    }
                }


                //The assert gets placed prior to the original command
                newCmdSeq.Add(c);
            }

            return(base.VisitCmdSeq(newCmdSeq));
        }
        public override List <Cmd> VisitCmdSeq(List <Cmd> cmdSeq)
        {
            List <Cmd> newCmdSeq = new List <Cmd>();

            foreach (Cmd c in cmdSeq)
            {
                if (c is AssignCmd)
                {
                    AssignCmd ac = c as AssignCmd;
                    Utils.Assert(ac.Lhss.Count == 1 && ac.Rhss.Count == 1, "Not handling parallel AssignCmd");
                    List <Tuple <Expr, Expr> > loadAddresses = getNestedLoadAddresses(ac.Rhss[0]);
                    Utils.Assert(loadAddresses.Select(x => x.ToString()).Distinct().Count() < 2,
                                 "Found multiple load expressions in " + ac.Rhss[0].ToString());
                    Tuple <Expr, Expr> load_addr = loadAddresses.Any() ? loadAddresses[0] : null;

                    if (load_addr != null)
                    {
                        Action <NAryExpr, string> RecordAssertion = delegate(NAryExpr assertCondition, string attribute)
                        {
                            AssertCmd assertion = new AssertCmd(Token.NoToken, assertCondition);
                            assertion.Attributes = new QKeyValue(Token.NoToken, "region", new List <object> {
                                attribute
                            }, assertion.Attributes);
                            newCmdSeq.Add(assertion);
                            VCSplitter.Instance.RecordAssertion(this.current_label, ac, assertion, Utils.getSlashVerifyCmdType(ac));
                        };

                        Action RecordStackAssertions = delegate()
                        {
                            NAryExpr condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInStack), new List <Expr> {
                                load_addr.Item2
                            });
                            RecordAssertion(condition, "addrInStack");

                            condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInStack), new List <Expr> {
                                load_addr.Item2
                            });
                            condition = new NAryExpr(Token.NoToken, new UnaryOperator(Token.NoToken, UnaryOperator.Opcode.Not), new List <Expr> {
                                condition
                            });
                            RecordAssertion(condition, "!addrInStack");
                        };

                        Action RecordBitmapAssertions = delegate()
                        {
                            NAryExpr condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInBitmap), new List <Expr> {
                                load_addr.Item2
                            });
                            RecordAssertion(condition, "addrInBitmap");

                            condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInBitmap), new List <Expr> {
                                load_addr.Item2
                            });
                            condition = new NAryExpr(Token.NoToken, new UnaryOperator(Token.NoToken, UnaryOperator.Opcode.Not), new List <Expr> {
                                condition
                            });
                            RecordAssertion(condition, "!addrInBitmap");
                        };

                        if (!this.splitProgram)
                        {
                            RecordStackAssertions();
                            RecordBitmapAssertions();
                        }
                        else
                        {
                            if (load_addr.Item1 is NAryExpr)
                            {
                                List <IdentifierExpr> referencedMemSpaces = Utils.getSplitMemoryAccessSpace(load_addr.Item1 as NAryExpr);
                                foreach (Variable memSpace in referencedMemSpaces.Select(i => i.Decl))
                                {
                                    if (memSpace.Name.Equals("mem_bitmap"))
                                    {
                                        RecordBitmapAssertions();
                                    }
                                    else if (memSpace.Name.Equals("mem_stack"))
                                    {
                                        RecordStackAssertions();
                                    }
                                }
                            }
                        }
                    }
                }

                //The assert gets placed prior to the original command
                newCmdSeq.Add(c);
            }

            return(base.VisitCmdSeq(newCmdSeq));
        }
Пример #12
0
      public override Expr VisitLambdaExpr(LambdaExpr lambda) {
        var baseResult = base.VisitLambdaExpr(lambda);
        lambda = baseResult as LambdaExpr;
        if (lambda == null) {
          return baseResult;  // apparently, the base visitor already turned the lambda into something else
        }

        // We start by getting rid of any use of "old" inside the lambda.  This is done as follows.
        // For each variable "g" occurring inside lambda as "old(... g ...)", create a new name "og".
        // Replace each old occurrence of "g" with "og", removing the enclosing "old" wrappers.
        var oldFinder = new OldFinder();
        oldFinder.Visit(lambda);
        var oldSubst = new Dictionary<Variable, Expr>();  // g -> g0
        var callOldMapping = new Dictionary<Variable, Expr>();  // g0 -> old(g)
        foreach (var v in oldFinder.FreeOldVars) {
          var g = v as GlobalVariable;
          if (g != null) {
            var g0 = new GlobalVariable(g.tok, new TypedIdent(g.tok, g.TypedIdent.Name + "@old", g.TypedIdent.Type));
            oldSubst.Add(g, new IdentifierExpr(g0.tok, g0));
            callOldMapping.Add(g0, new OldExpr(g0.tok, new IdentifierExpr(g.tok, g)));
          }
        }
        var lambdaBody = Substituter.ApplyReplacingOldExprs(
          Substituter.SubstitutionFromHashtable(new Dictionary<Variable,Expr>()),
          Substituter.SubstitutionFromHashtable(oldSubst),
          lambda.Body);
        var lambdaAttrs = Substituter.ApplyReplacingOldExprs(
          Substituter.SubstitutionFromHashtable(new Dictionary<Variable, Expr>()),
          Substituter.SubstitutionFromHashtable(oldSubst),
          lambda.Attributes);

        if (0 < CommandLineOptions.Clo.VerifySnapshots && QKeyValue.FindStringAttribute(lambdaAttrs, "checksum") == null)
        {
          // Attach a dummy checksum to avoid issues in the dependency analysis.
          var checksumAttr = new QKeyValue(lambda.tok, "checksum", new List<object> { "stable" }, null);
          if (lambdaAttrs == null)
          {
            lambdaAttrs = checksumAttr;
          }
          else
          {
            lambdaAttrs.AddLast(checksumAttr);
          }
        }

        // this is ugly, the output will depend on hashing order
        var subst = new Dictionary<Variable, Expr>();
        var substFnAttrs = new Dictionary<Variable, Expr>();
        var formals = new List<Variable>();
        var callArgs = new List<Expr>();
        var axCallArgs = new List<Expr>();
        var dummies = new List<Variable>(lambda.Dummies);
        var freeTypeVars = new List<TypeVariable>();
        var fnTypeVarActuals = new List<Type/*!*/>();
        var freshTypeVars = new List<TypeVariable>();  // these are only used in the lambda@n function's definition

        // compute the free variables of the lambda expression, but with lambdaBody instead of lambda.Body
        Set freeVars = new Set();
        BinderExpr.ComputeBinderFreeVariables(lambda.TypeParameters, lambda.Dummies, lambdaBody, lambdaAttrs, freeVars);

        foreach (object o in freeVars) {
          // 'o' is either a Variable or a TypeVariable.
          if (o is Variable) {
            var v = o as Variable;
            var ti = new TypedIdent(v.TypedIdent.tok, v.TypedIdent.Name, v.TypedIdent.Type);
            var f = new Formal(v.tok, ti, true);
            formals.Add(f);
            substFnAttrs.Add(v, new IdentifierExpr(f.tok, f));
            var b = new BoundVariable(v.tok, ti);
            dummies.Add(b);
            if (callOldMapping.ContainsKey(v)) {
              callArgs.Add(callOldMapping[v]);
            } else {
              callArgs.Add(new IdentifierExpr(v.tok, v));
            }
            Expr id = new IdentifierExpr(b.tok, b);
            subst.Add(v, id);
            axCallArgs.Add(id);
          } else {
            var tv = (TypeVariable)o;
            freeTypeVars.Add(tv);
            fnTypeVarActuals.Add(tv);
            freshTypeVars.Add(new TypeVariable(tv.tok, tv.Name));
          }
        }

        var sw = new System.IO.StringWriter();
        var wr = new TokenTextWriter(sw, true);
        lambda.Emit(wr);
        string lam_str = sw.ToString();

        FunctionCall fcall;
        IToken tok = lambda.tok;
        Formal res = new Formal(tok, new TypedIdent(tok, TypedIdent.NoName, cce.NonNull(lambda.Type)), false);

        if (liftedLambdas.TryGetValue(lambda, out fcall)) {
          if (CommandLineOptions.Clo.TraceVerify) {
            Console.WriteLine("Old lambda: {0}", lam_str);
          }
        } else {
          if (CommandLineOptions.Clo.TraceVerify) {
            Console.WriteLine("New lambda: {0}", lam_str);
          }
          Function fn = new Function(tok, FreshLambdaFunctionName(), freshTypeVars, formals, res, "auto-generated lambda function",
            Substituter.Apply(Substituter.SubstitutionFromHashtable(substFnAttrs), lambdaAttrs));

          fcall = new FunctionCall(new IdentifierExpr(tok, fn.Name));
          fcall.Func = fn;  // resolve here
          liftedLambdas[lambda] = fcall;

          List<Expr/*!*/> selectArgs = new List<Expr/*!*/>();
          foreach (Variable/*!*/ v in lambda.Dummies) {
            Contract.Assert(v != null);
            selectArgs.Add(new IdentifierExpr(v.tok, v));
          }
          NAryExpr axcall = new NAryExpr(tok, fcall, axCallArgs);
          axcall.Type = res.TypedIdent.Type;
          axcall.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals);
          NAryExpr select = Expr.Select(axcall, selectArgs);
          select.Type = lambdaBody.Type;
          List<Type/*!*/> selectTypeParamActuals = new List<Type/*!*/>();
          List<TypeVariable> forallTypeVariables = new List<TypeVariable>();
          foreach (TypeVariable/*!*/ tp in lambda.TypeParameters) {
            Contract.Assert(tp != null);
            selectTypeParamActuals.Add(tp);
            forallTypeVariables.Add(tp);
          }
          forallTypeVariables.AddRange(freeTypeVars);
          select.TypeParameters = SimpleTypeParamInstantiation.From(lambda.TypeParameters, selectTypeParamActuals);

          Expr bb = Substituter.Apply(Substituter.SubstitutionFromHashtable(subst), lambdaBody);
          NAryExpr body = Expr.Eq(select, bb);
          body.Type = Type.Bool;
          body.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
          Trigger trig = new Trigger(select.tok, true, new List<Expr> { select });

          lambdaFunctions.Add(fn);
          lambdaAxioms.Add(new ForallExpr(tok, forallTypeVariables, dummies,
            Substituter.Apply(Substituter.SubstitutionFromHashtable(subst), lambdaAttrs),
            trig, body));
        }

        NAryExpr call = new NAryExpr(tok, fcall, callArgs);
        call.Type = res.TypedIdent.Type;
        call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals);

        return call;
      }
Пример #13
0
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            // Need to duplicate arguments first (doing post order traversal)
            var newArgs = new List <Expr>();

            foreach (var oldExpr in node.Args)
            {
                var newExpr = (Expr)this.Visit(oldExpr);
                newArgs.Add(newExpr);
            }

            // Now can finally duplicate this node now we've done our children

            if (node.Fun is FunctionCall)
            {
                var    FC        = (FunctionCall)node.Fun;
                string bvbuiltin = QKeyValue.FindStringAttribute(FC.Func.Attributes, "bvbuiltin");
                if (bvbuiltin != null)
                {
                    return(HandleBvBuiltIns(FC, bvbuiltin, newArgs));
                }
                else
                {
                    string builtin = QKeyValue.FindStringAttribute(FC.Func.Attributes, "builtin");
                    if (builtin != null)
                    {
                        return(HandleBuiltIns(FC, builtin, newArgs));
                    }
                }
                // Not a builtin so treat as uninterpreted function call
                return(Builder.UFC(FC, newArgs.ToArray()));
            }
            else if (node.Fun is UnaryOperator)
            {
                var U = (UnaryOperator)node.Fun;
                Debug.Assert(newArgs.Count == 1);
                switch (U.Op)
                {
                case UnaryOperator.Opcode.Neg:
                    return(Builder.Neg(newArgs[0]));

                case UnaryOperator.Opcode.Not:
                    return(Builder.Not(newArgs[0]));

                default:
                    throw new NotImplementedException("Unary operator not supported");
                }
            }
            else if (node.Fun is BinaryOperator)
            {
                var B = (BinaryOperator)node.Fun;
                Debug.Assert(newArgs.Count == 2);
                switch (B.Op)
                {
                // Integer or Real number operators
                case BinaryOperator.Opcode.Add:
                    return(Builder.Add(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Sub:
                    return(Builder.Sub(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Mul:
                    return(Builder.Mul(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Div:
                    return(Builder.Div(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Mod:
                    return(Builder.Mod(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.RealDiv:
                    return(Builder.RealDiv(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Pow:
                    return(Builder.Pow(newArgs[0], newArgs[1]));

                // Comparision operators
                case BinaryOperator.Opcode.Eq:
                    return(Builder.Eq(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Neq:
                    return(Builder.NotEq(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Gt:
                    return(Builder.Gt(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Ge:
                    return(Builder.Ge(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Lt:
                    return(Builder.Lt(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Le:
                    return(Builder.Le(newArgs[0], newArgs[1]));

                // Bool operators
                case BinaryOperator.Opcode.And:
                    return(Builder.And(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Or:
                    return(Builder.Or(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Imp:
                    return(Builder.Imp(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Iff:
                    return(Builder.Iff(newArgs[0], newArgs[1]));

                case BinaryOperator.Opcode.Subtype:
                    throw new NotImplementedException("SubType binary operator support not implemented");

                default:
                    throw new NotSupportedException("Binary operator" + B.Op.ToString() + "not supported!");
                }
            }
            else if (node.Fun is MapStore)
            {
                Debug.Assert(newArgs.Count >= 3);
                // FIXME: We're probably making too many lists/arrays here
                var map     = newArgs[0];
                var value   = newArgs[newArgs.Count - 1]; // Last argument is value to store
                var indices = new List <Expr>();
                for (int index = 1; index < newArgs.Count - 1; ++index)
                {
                    indices.Add(newArgs[index]);
                }
                Debug.Assert(indices.Count + 2 == newArgs.Count);
                return(Builder.MapStore(map, value, indices.ToArray()));
            }
            else if (node.Fun is MapSelect)
            {
                // FIXME: We're probably making too many lists/arrays here
                Debug.Assert(newArgs.Count >= 2);
                var map     = newArgs[0];
                var indices = new List <Expr>();
                for (int index = 1; index < newArgs.Count; ++index)
                {
                    indices.Add(newArgs[index]);
                }
                Debug.Assert(indices.Count + 1 == newArgs.Count);
                return(Builder.MapSelect(map, indices.ToArray()));
            }
            else if (node.Fun is IfThenElse)
            {
                Debug.Assert(newArgs.Count == 3);
                return(Builder.IfThenElse(newArgs[0], newArgs[1], newArgs[2]));
            }
            else if (node.Fun is TypeCoercion)
            {
                // FIXME: Add support for this in the builder
                // I don't want to put this into the IExprBuilder until I know
                // exactly how this operator works and how it should be type checked
                var immutableTC = new NAryExpr(Token.NoToken, node.Fun, newArgs, /*immutable=*/ true);
                immutableTC.Type = node.Type;
                return(immutableTC);
            }
            else if (node.Fun is ArithmeticCoercion)
            {
                Debug.Assert(newArgs.Count == 1);
                var ac = node.Fun as ArithmeticCoercion;
                return(Builder.ArithmeticCoercion(ac.Coercion, newArgs[0]));
            }

            throw new NotSupportedException("Unsupported NAryExpr");
        }
Пример #14
0
        protected Expr HandleNAry(NAryExpr e)
        {
            if (e.Fun is FunctionCall)
            {
                var    FC        = (FunctionCall)e.Fun;
                string bvbuiltin = QKeyValue.FindStringAttribute(FC.Func.Attributes, "bvbuiltin");
                if (bvbuiltin != null)
                {
                    return(HandlerBvBuiltIns(e, bvbuiltin));
                }
                else
                {
                    string builtin = QKeyValue.FindStringAttribute(FC.Func.Attributes, "builtin");
                    if (builtin != null)
                    {
                        return(HandlerBuiltIns(e, builtin));
                    }

                    // Not a bvbuiltin so treat as generic function call.
                    return(Visitor.VisitFunctionCall(e));
                }
            }
            else if (e.Fun is UnaryOperator)
            {
                var U = (UnaryOperator)e.Fun;
                switch (U.Op)
                {
                case UnaryOperator.Opcode.Neg:
                    return(Visitor.VisitNeg(e));

                case UnaryOperator.Opcode.Not:
                    return(Visitor.VisitNot(e));

                default:
                    throw new NotImplementedException("Unary operator not supported");
                }
            }
            else if (e.Fun is BinaryOperator)
            {
                var B = (BinaryOperator)e.Fun;
                switch (B.Op)
                {
                // Integer or Real number operators
                case BinaryOperator.Opcode.Add:
                    return(Visitor.VisitAdd(e));

                case BinaryOperator.Opcode.Sub:
                    return(Visitor.VisitSub(e));

                case BinaryOperator.Opcode.Mul:
                    return(Visitor.VisitMul(e));

                case BinaryOperator.Opcode.Div:
                    return(Visitor.VisitDiv(e));

                case BinaryOperator.Opcode.Mod:
                    return(Visitor.VisitMod(e));

                case BinaryOperator.Opcode.RealDiv:
                    return(Visitor.VisitRealDiv(e));

                case BinaryOperator.Opcode.Pow:
                    return(Visitor.VisitPow(e));

                // Comparision operators
                case BinaryOperator.Opcode.Eq:
                    return(Visitor.VisitEq(e));

                case BinaryOperator.Opcode.Neq:
                    return(Visitor.VisitNeq(e));

                case BinaryOperator.Opcode.Gt:
                    return(Visitor.VisitGt(e));

                case BinaryOperator.Opcode.Ge:
                    return(Visitor.VisitGe(e));

                case BinaryOperator.Opcode.Lt:
                    return(Visitor.VisitLt(e));

                case BinaryOperator.Opcode.Le:
                    return(Visitor.VisitLe(e));

                // Bool operators
                case BinaryOperator.Opcode.And:
                    return(Visitor.VisitAnd(e));

                case BinaryOperator.Opcode.Or:
                    return(Visitor.VisitOr(e));

                case BinaryOperator.Opcode.Imp:
                    return(Visitor.VisitImp(e));

                case BinaryOperator.Opcode.Iff:
                    return(Visitor.VisitIff(e));

                case BinaryOperator.Opcode.Subtype:
                    return(Visitor.VisitSubType(e));

                default:
                    throw new NotImplementedException("Binary operator not supported!");
                }
            }
            else if (e.Fun is MapStore)
            {
                return(Visitor.VisitMapStore(e));
            }
            else if (e.Fun is MapSelect)
            {
                return(Visitor.VisitMapSelect(e));
            }
            else if (e.Fun is IfThenElse)
            {
                return(Visitor.VisitIfThenElse(e));
            }
            else if (e.Fun is TypeCoercion)
            {
                return(Visitor.VisitTypeCoercion(e));
            }
            else if (e.Fun is ArithmeticCoercion)
            {
                return(Visitor.VisitArithmeticCoercion(e));
            }
            else if (e.Fun is DistinctOperator)
            {
                return(Visitor.VisitDistinct(e));
            }

            throw new NotImplementedException("NAry not handled!");
        }
Пример #15
0
        protected Expr HandlerBvBuiltIns(NAryExpr e, string builtin)
        {
            Debug.Assert(builtin.Length > 0);

            // We grab for first word because the bvbuiltin
            // might be "zeroextend 16", we don't care about the number
            string firstWord = builtin.Split(' ')[0];

            Debug.Assert(firstWord.Length > 0);
            switch (firstWord)
            {
            // arithmetic
            case "bvadd":
                return(Visitor.Visit_bvadd(e));

            case "bvsub":
                return(Visitor.Visit_bvsub(e));

            case "bvmul":
                return(Visitor.Visit_bvmul(e));

            case "bvudiv":
                return(Visitor.Visit_bvudiv(e));

            case "bvurem":
                return(Visitor.Visit_bvurem(e));

            case "bvsdiv":
                return(Visitor.Visit_bvsdiv(e));

            case "bvsrem":
                return(Visitor.Visit_bvsrem(e));

            case "bvsmod":
                return(Visitor.Visit_bvsmod(e));

            case "sign_extend":
                return(Visitor.Visit_sign_extend(e));

            case "zero_extend":
                return(Visitor.Visit_zero_extend(e));

            // bitwise logical
            case "bvneg":
                return(Visitor.Visit_bvneg(e));

            case "bvand":
                return(Visitor.Visit_bvand(e));

            case "bvor":
                return(Visitor.Visit_bvor(e));

            case "bvnot":
                return(Visitor.Visit_bvnot(e));

            case "bvxor":
                return(Visitor.Visit_bvxor(e));

            // shift
            case "bvshl":
                return(Visitor.Visit_bvshl(e));

            case "bvlshr":
                return(Visitor.Visit_bvlshr(e));

            case "bvashr":
                return(Visitor.Visit_bvashr(e));

            // Comparison
            case "bvult":
                return(Visitor.Visit_bvult(e));

            case "bvule":
                return(Visitor.Visit_bvule(e));

            case "bvugt":
                return(Visitor.Visit_bvugt(e));

            case "bvuge":
                return(Visitor.Visit_bvuge(e));

            case "bvslt":
                return(Visitor.Visit_bvslt(e));

            case "bvsle":
                return(Visitor.Visit_bvsle(e));

            case "bvsgt":
                return(Visitor.Visit_bvsgt(e));

            case "bvsge":
                return(Visitor.Visit_bvsge(e));

            default:
                throw new NotImplementedException(firstWord + " bvbuiltin not supported!");
            }
        }
Пример #16
0
            public override Expr VisitNAryExpr(NAryExpr node)
            {
                // Simplify the children.
                node = (NAryExpr)base.VisitNAryExpr(node);

                // Simplify constant Boolean and bitvector expressions that
                // occur in assertions when not all arrays are being checked
                // for races. Bitvector expressions are ignored if they were
                // modelled as mathematical integers.
                if (node.Fun is BinaryOperator)
                {
                    var binOp = node.Fun as BinaryOperator;
                    if (binOp.Op == BinaryOperator.Opcode.Imp)
                    {
                        if (node.Args[0] is LiteralExpr)
                        {
                            return(node.Args[0] == Expr.False ? Expr.True : node.Args[1]);
                        }
                        else if (node.Args[1] is LiteralExpr)
                        {
                            return(node.Args[1] == Expr.True ? Expr.True : node.Args[0]);
                        }
                    }
                    else if (binOp.Op == BinaryOperator.Opcode.Neq)
                    {
                        if (node.Args[0] is LiteralExpr && node.Args[1] is LiteralExpr)
                        {
                            return(node.Args[0].Equals(node.Args[1]) ? Expr.False : Expr.True);
                        }
                    }
                    else if (binOp.Op == BinaryOperator.Opcode.Eq)
                    {
                        if (node.Args[0] is LiteralExpr && node.Args[1] is LiteralExpr)
                        {
                            return(node.Args[0].Equals(node.Args[1]) ? Expr.True : Expr.False);
                        }
                    }
                }
                else if (ZextPattern.Match(node.Fun.FunctionName).Success&& node.Type is BvType)
                {
                    if (node.Args[0] is LiteralExpr && node.Type is BvType)
                    {
                        var NewVal = BigNum.FromBigInt(GetBigInt(node.Args[0]));
                        return(new LiteralExpr(Token.NoToken, NewVal, GetBvBits(node)));
                    }
                }
                else if (XorPattern.Match(node.Fun.FunctionName).Success&& node.Type is BvType)
                {
                    if (node.Args[0] is LiteralExpr && node.Args[1] is LiteralExpr)
                    {
                        var NewVal = BigNum.FromBigInt(GetBigInt(node.Args[0]) ^ GetBigInt(node.Args[1]));
                        return(new LiteralExpr(Token.NoToken, NewVal, GetBvBits(node)));
                    }
                }
                else if (AndPattern.Match(node.Fun.FunctionName).Success&& node.Type is BvType)
                {
                    if (node.Args[0] is LiteralExpr && node.Args[1] is LiteralExpr)
                    {
                        var NewVal = BigNum.FromBigInt(GetBigInt(node.Args[0]) & GetBigInt(node.Args[1]));
                        return(new LiteralExpr(Token.NoToken, NewVal, GetBvBits(node)));
                    }
                }
                else if (OrPattern.Match(node.Fun.FunctionName).Success&& node.Type is BvType)
                {
                    if (node.Args[0] is LiteralExpr && node.Args[1] is LiteralExpr)
                    {
                        var NewVal = BigNum.FromBigInt(GetBigInt(node.Args[0]) | GetBigInt(node.Args[1]));
                        return(new LiteralExpr(Token.NoToken, NewVal, GetBvBits(node)));
                    }
                }
                else if (node.Fun is IfThenElse)
                {
                    if (node.Args[0] is LiteralExpr)
                    {
                        return(node.Args[0] == Expr.True ? node.Args[1] : node.Args[2]);
                    }
                }
                return(node);
            }
Пример #17
0
        public static string PrettyPrintBplExpr(Expr e)
        {
            Contract.Requires(e != null);
            Contract.Ensures(Contract.Result <string>() != null);
            // anything that is unknown will just be printed via ToString
            // OldExpr and QuantifierExpr, BvExtractExpr, BvConcatExpr are ignored for now
            // LiteralExpr is printed as itself by ToString
            if (e is IdentifierExpr)
            {
                string s = e.ToString();
                return(Helpers.BeautifyBplString(s));
            }
            else if (e is NAryExpr)
            {
                NAryExpr   ne   = (NAryExpr)e;
                IAppliable fun  = ne.Fun;
                var        eSeq = ne.Args;
                if (fun != null)
                {
                    if ((fun.FunctionName == "$Length" || fun.FunctionName == "$StringLength") && eSeq.Count == 1)
                    {
                        Expr e0 = eSeq[0];
                        if (e0 != null)
                        {
                            string s0 = PrettyPrintBplExpr(e0);
                            return(s0 + ".Length");
                        }
                        //unexpected, just fall outside to the default
                    }
                    else if (fun.FunctionName == "$typeof" && eSeq.Count == 1)
                    {
                        Expr e0 = eSeq[0];
                        if (e0 != null)
                        {
                            string s0 = PrettyPrintBplExpr(e0);
                            return("(the dynamic type of: " + s0 + ")");
                        }
                        //unexpected, just fall outside to the default
                    }
                    else if (fun.FunctionName == "IntArrayGet" && eSeq.Count == 2)
                    {
                        Expr e0 = eSeq[0];
                        Expr e1 = eSeq[1];
                        if (e0 != null && e1 != null)
                        {
                            string s0 = PrettyPrintBplExpr(e0);
                            string s1 = PrettyPrintBplExpr(e1);
                            return(s0 + "[" + s1 + "]");
                        }
                        //unexpected, just fall outside to the default
                    }
                    else if (fun.FunctionName == "$Is" && eSeq.Count == 2)
                    {
                        Expr e0 = eSeq[0];
                        Expr e1 = eSeq[1];
                        if (e0 != null && e1 != null)
                        {
                            string s0 = PrettyPrintBplExpr(e0);
                            string s1 = PrettyPrintBplExpr(e1);
                            return("(" + s0 + " == null || (" + s0 + " is " + s1 + "))");
                        }
                        //unexpected, just fall outside to the default
                    }
                    else if (fun.FunctionName == "$IsNotNull" && eSeq.Count == 2)
                    {
                        Expr e0 = eSeq[0];
                        Expr e1 = eSeq[1];
                        if (e0 != null && e1 != null)
                        {
                            string s0 = PrettyPrintBplExpr(e0);
                            string s1 = PrettyPrintBplExpr(e1);
                            return("(" + s0 + " is " + s1 + ")");
                        }
                        //unexpected, just fall outside to the default
                    }
                    else if (fun is MapSelect && eSeq.Count <= 3)
                    {
                        // only maps with up to two arguments are supported right now (here)
                        if (cce.NonNull(eSeq[0]).ToString() == "$Heap")
                        {
                            //print Index0.Index1, unless Index1 is "$elements", then just print Index0
                            string s0 = PrettyPrintBplExpr(cce.NonNull(eSeq[1]));
                            if (eSeq.Count > 2)
                            {
                                string s1 = PrettyPrintBplExpr(cce.NonNull(eSeq[2]));
                                if (s1 == "$elements")
                                {
                                    return(s0);
                                }
                                else
                                {
                                    if (eSeq[2] is IdentifierExpr)
                                    {
                                        // strip the class name out of a fieldname
                                        s1 = s1.Substring(s1.LastIndexOf('.') + 1);
                                    }
                                    return(s0 + "." + s1);
                                }
                            }
                        }
                        //unexpected, just fall outside to the default
                    }
                    else if (fun is Microsoft.Boogie.BinaryOperator && eSeq.Count == 2)
                    {
                        Microsoft.Boogie.BinaryOperator f = (Microsoft.Boogie.BinaryOperator)fun;
                        Expr e0 = eSeq[0];
                        Expr e1 = eSeq[1];
                        if (e0 != null && e1 != null)
                        {
                            string s0 = PrettyPrintBplExpr(e0);
                            string s1 = PrettyPrintBplExpr(e1);
                            string op = "";
                            switch (f.Op)
                            {
                            case Microsoft.Boogie.BinaryOperator.Opcode.Add:
                                op = " + ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.And:
                                op = " && ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Div:
                                op = " div ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Eq:
                                op = " == ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Ge:
                                op = " >= ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Gt:
                                op = " > ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Iff:
                                op = " <==> ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Imp:
                                op = " ==> ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Le:
                                op = " <= ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Lt:
                                op = " < ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Mod:
                                op = " mod ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Mul:
                                op = " * ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Neq:
                                op = " != ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Or:
                                op = " || ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Pow:
                                op = " ** ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.RealDiv:
                                op = " / ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Sub:
                                op = " - ";
                                break;

                            case Microsoft.Boogie.BinaryOperator.Opcode.Subtype:
                                op = " <: ";
                                break;

                            default:
                                op = " ";
                                break;
                            }
                            return("(" + s0 + op + s1 + ")");
                        }
                        //unexpected, just fall outside to the default
                    }
                    else
                    {
                        string s = fun.FunctionName + "(";
                        for (int i = 0; i < eSeq.Count; i++)
                        {
                            Expr ex = eSeq[i];
                            Contract.Assume(ex != null);
                            if (i > 0)
                            {
                                s += ", ";
                            }
                            string t = PrettyPrintBplExpr(ex);
                            if (t.StartsWith("(") && t.EndsWith(")"))
                            {
                                t = t.Substring(1, t.Length - 2);
                            }
                            s += t;
                        }
                        s += ")";
                        return(s);
                        //unexpected, just fall outside to the default
                    }
                }
            }

            return(e.ToString());
        }
        public override List <Cmd> VisitCmdSeq(List <Cmd> cmdSeq)
        {
            List <Cmd> newCmdSeq = new List <Cmd>();

            Action <NAryExpr, string, AssignCmd> RecordAssertion = delegate(NAryExpr assertCondition, string attribute, AssignCmd memAssignCmd)
            {
                AssertCmd assertion = new AssertCmd(Token.NoToken, assertCondition);
                //we use the attribute in a separate pass within the split memory modeler
                assertion.Attributes = new QKeyValue(Token.NoToken, "region", new List <object> {
                    attribute
                }, assertion.Attributes);
                newCmdSeq.Add(assertion);
                //current_label is the current block, ac is the STORE associated with the assertiion
                VCSplitter.Instance.RecordAssertion(this.current_label, memAssignCmd, assertion, Utils.getSlashVerifyCmdType(memAssignCmd));
            };

            foreach (Cmd c in cmdSeq)
            {
                if (c is AssignCmd)
                {
                    AssignCmd ac = c as AssignCmd;
                    Utils.Assert(ac.Lhss.Count == 1 && ac.Rhss.Count == 1, "Not handling parallel AssignCmd");
                    //Console.Write(".");
                    switch (Utils.getSlashVerifyCmdType(ac))
                    {
                    case SlashVerifyCmdType.Store8:
                    case SlashVerifyCmdType.Store16:
                    case SlashVerifyCmdType.Store32:
                    case SlashVerifyCmdType.Store64:     //mem := store(mem, y, e)
                    {
                        Tuple <Variable, Expr, Expr> storeArgs = Utils.getStoreArgs(ac);
                        Expr store_addr  = storeArgs.Item2;
                        Expr store_value = storeArgs.Item3;

                        if (splitProgram)
                        {
                            newCmdSeq.Add(c);
                            break;
                        }


                        NAryExpr condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInBitmap), new List <Expr> {
                                store_addr
                            });
                        RecordAssertion(condition, "addrInBitmap", ac);

                        condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInStack), new List <Expr> {
                                store_addr
                            });
                        RecordAssertion(condition, "addrInStack", ac);

                        condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInBitmap), new List <Expr> {
                                store_addr
                            });
                        condition = new NAryExpr(Token.NoToken, new UnaryOperator(Token.NoToken, UnaryOperator.Opcode.Not), new List <Expr> {
                                condition
                            });
                        RecordAssertion(condition, "!addrInBitmap", ac);

                        condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInStack), new List <Expr> {
                                store_addr
                            });
                        condition = new NAryExpr(Token.NoToken, new UnaryOperator(Token.NoToken, UnaryOperator.Opcode.Not), new List <Expr> {
                                condition
                            });
                        RecordAssertion(condition, "!addrInStack", ac);

                        //Expr addr_in_mem =
                        //    Expr.And(
                        //        new NAryExpr(Token.NoToken, new FunctionCall(ge_64),
                        //            new List<Expr>() { store_addr, new IdentifierExpr(Token.NoToken, this.stack_low) }),
                        //        new NAryExpr(Token.NoToken, new FunctionCall(lt_64),
                        //            new List<Expr>() { store_addr, new IdentifierExpr(Token.NoToken, this.bitmap_low) }));
                        //RecordAssertion(addr_in_mem, "!addrInStack");

                        break;
                    }

                    case SlashVerifyCmdType.RepStosB:     //x := REP_STOSB(mem, e1, e2, e3)
                    {
                        break;
                    }

                    default:     //x:=e
                    {
                        if (ac.Lhss.First().DeepAssignedVariable.Name.Equals("mem_stack"))
                        {
                            Expr address = Utils.getSplitMemoryOperationAddress(ac);
                            if (address == null)
                            {
                                break;
                            }
                            NAryExpr condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInStack), new List <Expr> {
                                    address
                                });
                            RecordAssertion(condition, "addrInStack", ac);

                            condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInStack), new List <Expr> {
                                    address
                                });
                            condition = new NAryExpr(Token.NoToken, new UnaryOperator(Token.NoToken, UnaryOperator.Opcode.Not), new List <Expr> {
                                    condition
                                });
                            RecordAssertion(condition, "!addrInStack", ac);
                        }
                        else if (ac.Lhss.First().DeepAssignedVariable.Name.Equals("mem_bitmap"))
                        {
                            Expr address = Utils.getSplitMemoryOperationAddress(ac);
                            if (address == null)
                            {
                                break;
                            }
                            NAryExpr condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInBitmap), new List <Expr> {
                                    address
                                });
                            RecordAssertion(condition, "addrInBitmap", ac);

                            condition = new NAryExpr(Token.NoToken, new FunctionCall(addrInBitmap), new List <Expr> {
                                    address
                                });
                            condition = new NAryExpr(Token.NoToken, new UnaryOperator(Token.NoToken, UnaryOperator.Opcode.Not), new List <Expr> {
                                    condition
                                });
                            RecordAssertion(condition, "!addrInBitmap", ac);
                        }
                        break;
                    }
                    }

                    // TODO handle ITE case
                }

                //The assert gets placed prior to the original command
                newCmdSeq.Add(c);
            }

            return(base.VisitCmdSeq(newCmdSeq));
        }
Пример #19
0
            public override Expr VisitNAryExpr(NAryExpr node)
            {
                if (node.Fun is FunctionCall && (node.Fun as FunctionCall).FunctionName.StartsWith("AbsHoudiniConstant"))
                {
                    ahFuncs.Add((node.Fun as FunctionCall).Func);
                    return Expr.True;
                }

                return base.VisitNAryExpr(node);
            }
        //private bool isMemAddress(string label, Cmd c, Dictionary<Tuple<string, Cmd, AssertCmd>, bool> db)
        //{
        //    return isRegionAddress(label, c, "GE_64", db);
        //}

        //takes an expression and substitutes desired mem for each load(mem,..) sub-expression
        private Expr splitMemoryOnAllLoads(Expr e, AddrType addrType, bool notBitmap, bool notStack)
        {
            //takes as input the addr expr of LOAD(mem,addr), and returns the desired expression for mem : ITE(addrInBitmap(.), mem_bitmap, ITE(..))
            Func <Tuple <Expr, Expr>, Expr> getDesiredMemExpr = delegate(Tuple <Expr, Expr> load_info)
            {
                if (addrType == AddrType.StackAddress)
                {
                    return(new IdentifierExpr(Token.NoToken, this.mem_stack));
                }
                if (addrType == AddrType.BitmapAddress)
                {
                    return(new IdentifierExpr(Token.NoToken, this.mem_bitmap));
                }
                Expr          addr = load_info.Item2;
                List <string> targetedMemSpacesNames = this.splitProgram ?
                                                       Utils.getSplitMemoryAccessSpace(load_info.Item1 as NAryExpr).Select(i => i.Decl.Name).ToList() :
                                                       new List <string> {
                    "mem", "mem_bitmap", "mem_stack"
                };
                Expr isAddrInBitmap = new NAryExpr(Token.NoToken, new FunctionCall(this.addrInBitmap), new List <Expr> {
                    addr
                });
                Expr isAddrInStack = new NAryExpr(Token.NoToken, new FunctionCall(this.addrInStack), new List <Expr> {
                    addr
                });

                Expr tmp = new IdentifierExpr(Token.NoToken, mem);
                if (!notBitmap && targetedMemSpacesNames.Contains("mem_bitmap")) //may target the bitmap
                {
                    tmp = new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), new List <Expr> {
                        isAddrInBitmap, new IdentifierExpr(Token.NoToken, this.mem_bitmap), tmp
                    });
                }

                if (!notStack && targetedMemSpacesNames.Contains("mem_stack")) //may target the stack
                {
                    tmp = new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), new List <Expr> {
                        isAddrInStack, new IdentifierExpr(Token.NoToken, this.mem_stack), tmp
                    });
                }
                return(tmp);
            };

            //if there is no load, no point in recursing
            if (!(Utils.getNestedFunctions(e).Any(x => x.FunctionName.Contains("LOAD_LE"))))
            {
                return(e);
            }

            //we have one or more load expressions here. so let's recursively find them and substitute.
            if (e is NAryExpr)
            {
                //this is a load expression
                if ((e as NAryExpr).Fun.FunctionName.Contains("LOAD_LE"))
                {
                    Tuple <Expr, Expr> load_args = Utils.getLoadArgs(e);
                    if (this.splitProgram && load_args.Item1 is IdentifierExpr)
                    {
                        return(e);
                    }
                    Expr desired_mem = getDesiredMemExpr(load_args);
                    //even the address expression can have a load
                    return(new NAryExpr(Token.NoToken, (e as NAryExpr).Fun, new List <Expr> {
                        desired_mem, splitMemoryOnAllLoads(load_args.Item2, addrType, notBitmap, notStack)
                    }));
                }
                else
                {
                    //not a load expression, but we need to recurse
                    List <Expr> new_args = new List <Expr>();
                    foreach (Expr arg in (e as NAryExpr).Args)
                    {
                        new_args.Add(splitMemoryOnAllLoads(arg, addrType, notBitmap, notStack));
                    }
                    return(new NAryExpr(Token.NoToken, (e as NAryExpr).Fun, new_args));
                }
            }
            if (e is BvExtractExpr)
            {
                return(new BvExtractExpr(Token.NoToken,
                                         splitMemoryOnAllLoads((e as BvExtractExpr).Bitvector, addrType, notBitmap, notStack),
                                         (e as BvExtractExpr).End,
                                         (e as BvExtractExpr).Start));
            }
            if (e is BvConcatExpr)
            {
                return(new BvConcatExpr(Token.NoToken,
                                        splitMemoryOnAllLoads((e as BvConcatExpr).E0, addrType, notBitmap, notStack),
                                        splitMemoryOnAllLoads((e as BvConcatExpr).E1, addrType, notBitmap, notStack)));
            }
            if (e is IdentifierExpr)
            {
                return(e); //cant
            }
            if (e is LiteralExpr)
            {
                return(e);
            }
            Utils.Assert(false, "Should not get here");
            return(null);
        }
Пример #21
0
        public override Function VisitFunction(Function node)
        {
            // FIXME we should factor this test into a utility function
            // because its needed in many places.
            // SMTLIBv2 bvbuiltins can't be recursive
            if (QKeyValue.FindStringAttribute(node.Attributes, "bvbuiltin") != null)
            {
                return(node);
            }

            if (QKeyValue.FindStringAttribute(node.Attributes, "builtin") != null)
            {
                return(node);
            }

            // Pop on to stack
            CallStack.Add(node);
            if (node.Body != null)
            {
                base.Visit(node.Body);
            }

            // Explore definition axiom for the form (forall args :: func(args) <==> expr)
            if (node.DefinitionAxiom != null)
            {
                Debug.Assert(node.DefinitionAxiom.Expr is ForallExpr, "Function defintion axiom is not a forall!");
                var forall = node.DefinitionAxiom.Expr as ForallExpr;
                Debug.Assert(forall.Dummies.Count == node.InParams.Count, "Number of arguments do not match");
                Debug.Assert(forall.Body is NAryExpr, "forall body is not an NAryExpr");

                var equality = forall.Body as NAryExpr;
                Debug.Assert(equality.Fun is BinaryOperator, "Forall body is not a BinaryOperator");
                var binaryOperator = equality.Fun as BinaryOperator;
                Debug.Assert(binaryOperator.Op == BinaryOperator.Opcode.Iff || binaryOperator.Op == BinaryOperator.Opcode.Eq,
                             "Binary Operator is not == or <==>");

                // Check == or <==> applies to this function
                // We assume the function is on the lhs
                Debug.Assert(equality.Args[0] is NAryExpr, "lhs is not NAryExpr");
                var lhs = equality.Args[0] as NAryExpr;

                // May need to step through type coercions
                NAryExpr shouldBeFunctionCall = lhs;
                while (shouldBeFunctionCall.Fun is TypeCoercion)
                {
                    Debug.Assert(lhs.Args[0] is NAryExpr, "Hit non NAryExpr whilst traversing TypeCoercion");
                    shouldBeFunctionCall = lhs.Args[0] as NAryExpr;
                }


                Debug.Assert(shouldBeFunctionCall.Fun is FunctionCall, "LHS is not a FunctionCall");
                var lhsFuncCall = shouldBeFunctionCall.Fun as FunctionCall;
                Debug.Assert(lhsFuncCall.Func.Equals(node), "Axiom does not apply to function " + node.Name);

                // The rhs is the Function Expr
                base.Visit(equality.Args[1]);
            }

            // Pop from stack
            CallStack.Remove(node);
            return(node);
        }
        public override List <Cmd> VisitCmdSeq(List <Cmd> cmdSeq)
        {
            if (!Options.splitMemoryModel)
            {
                return(base.VisitCmdSeq(cmdSeq));
            }

            List <Cmd> newCmdSeq = new List <Cmd>();

            foreach (Cmd c in cmdSeq)
            {
                if (c is AssignCmd)
                {
                    AssignCmd ac = c as AssignCmd;
                    Utils.Assert(ac.Lhss.Count == 1 && ac.Rhss.Count == 1, "Not handling parallel AssignCmd");
                    ac = new AssignCmd(Token.NoToken, new List <AssignLhs> {
                        ac.Lhss[0]
                    }, new List <Expr> {
                        transformLoad(this.current_label, c, ac.Rhss[0])
                    });

                    switch (Utils.getSlashVerifyCmdType(ac))
                    {
                    case SlashVerifyCmdType.Store8:
                    case SlashVerifyCmdType.Store16:
                    case SlashVerifyCmdType.Store32:
                    case SlashVerifyCmdType.Store64:     //mem := store(mem, y, e)
                    {
                        Tuple <Variable, Expr, Expr> storeArgs = Utils.getStoreArgs(ac);
                        Expr store_addr  = storeArgs.Item2;
                        Expr store_value = storeArgs.Item3;

                        AddrType addrType = AddrType.Unknown;
                        if (Options.optimizeStoreITE)
                        {
                            if (isStackAddress(this.current_label, c, this.storeAddressRegionDB))
                            {
                                addrType = AddrType.StackAddress;
                            }
                            else if (isBitmapAddress(this.current_label, c, this.storeAddressRegionDB))
                            {
                                addrType = AddrType.BitmapAddress;
                            }
                            //else if (isMemAddress(this.current_label, c, this.storeAddressRegionDB)) { addrType = AddrType.MemAddress; }
                            else
                            {
                                addrType = AddrType.Unknown;
                            }
                        }

                        if (addrType == AddrType.StackAddress)
                        {
                            //adds mem_stack := STORE(mem_stack, addr, value);
                            AssignCmd new_ac = new AssignCmd(Token.NoToken,
                                                             new List <AssignLhs> {
                                    new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.mem_stack))
                                },
                                                             new List <Expr> {
                                    new NAryExpr(Token.NoToken,
                                                 (ac.Rhss[0] as NAryExpr).Fun,
                                                 new List <Expr> {
                                        new IdentifierExpr(Token.NoToken, this.mem_stack),
                                        store_addr,
                                        store_value
                                    })
                                });
                            newCmdSeq.Add(new_ac);
                        }
                        else if (addrType == AddrType.BitmapAddress)
                        {
                            //adds mem_bitmap := STORE(mem_bitmap, addr, value);
                            AssignCmd new_ac = new AssignCmd(Token.NoToken,
                                                             new List <AssignLhs> {
                                    new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.mem_bitmap))
                                },
                                                             new List <Expr> {
                                    new NAryExpr(Token.NoToken,
                                                 (ac.Rhss[0] as NAryExpr).Fun,
                                                 new List <Expr> {
                                        new IdentifierExpr(Token.NoToken, this.mem_bitmap),
                                        store_addr,
                                        store_value
                                    })
                                });
                            newCmdSeq.Add(new_ac);
                        }
                        else
                        {
                            if (this.splitProgram)
                            {
                                if (!isBitmapAddress(this.current_label, c, this.storeAddressRegionDB) &&
                                    !isStackAddress(this.current_label, c, this.storeAddressRegionDB))
                                {
                                    newCmdSeq.Add(ac);
                                }
                                break;
                            }

                            Expr isAddrInBitmap = new NAryExpr(Token.NoToken, new FunctionCall(this.addrInBitmap), new List <Expr> {
                                    store_addr
                                });
                            Expr isAddrInStack = new NAryExpr(Token.NoToken, new FunctionCall(this.addrInStack), new List <Expr> {
                                    store_addr
                                });

                            newCmdSeq.Add(ac);

                            Expr rhs;
                            //may exist an execution such that the stack is written
                            // mem_stack := ITE(isAddrInStack(storeAddr), STORE(mem_stack, addr, value), mem_stack);
                            if (!isNotStackAddress(this.current_label, c, this.storeAddressRegionDB))
                            {
                                rhs = new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), new List <Expr> {
                                        isAddrInStack,
                                        new NAryExpr(Token.NoToken, (ac.Rhss[0] as NAryExpr).Fun, new List <Expr> {
                                            new IdentifierExpr(Token.NoToken, this.mem_stack), store_addr, store_value
                                        }),
                                        new IdentifierExpr(Token.NoToken, this.mem_stack)
                                    });
                                AssignCmd stack_ac = new AssignCmd(Token.NoToken,
                                                                   new List <AssignLhs> {
                                        new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.mem_stack))
                                    },
                                                                   new List <Expr> {
                                        rhs
                                    });
                                newCmdSeq.Add(stack_ac);
                            }

                            //may exist an execution such that the bitmap is written
                            // mem_bitmap := ITE(isAddrInBitmap(storeAddr), STORE(mem_bitmap, addr, value), mem_bitmap);
                            if (!isNotBitmapAddress(this.current_label, c, this.storeAddressRegionDB))
                            {
                                rhs = new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), new List <Expr> {
                                        isAddrInBitmap,
                                        new NAryExpr(Token.NoToken, (ac.Rhss[0] as NAryExpr).Fun, new List <Expr> {
                                            new IdentifierExpr(Token.NoToken, this.mem_bitmap), store_addr, store_value
                                        }),
                                        new IdentifierExpr(Token.NoToken, this.mem_bitmap)
                                    });
                                AssignCmd bitmap_ac = new AssignCmd(Token.NoToken,
                                                                    new List <AssignLhs> {
                                        new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.mem_bitmap))
                                    },
                                                                    new List <Expr> {
                                        rhs
                                    });
                                newCmdSeq.Add(bitmap_ac);
                            }
                        }

                        break;
                    }

                    case SlashVerifyCmdType.RepStosB:
                    {
                        Tuple <Variable, Expr, Expr, Expr> repstosArgs = Utils.getRepStosbArgs(ac);
                        Expr base_addr = repstosArgs.Item3;
                        Expr length    = repstosArgs.Item2;

                        Expr isAddrInBitmap = new NAryExpr(Token.NoToken, new FunctionCall(this.addrInBitmap), new List <Expr> {
                                base_addr
                            });
                        Expr isAddrInStack = new NAryExpr(Token.NoToken, new FunctionCall(this.addrInStack), new List <Expr> {
                                base_addr
                            });

                        Expr rhs = new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), new List <Expr> {
                                isAddrInStack,
                                new NAryExpr(Token.NoToken,
                                             (ac.Rhss[0] as NAryExpr).Fun,
                                             new List <Expr> {
                                    new IdentifierExpr(Token.NoToken, this.mem_stack), repstosArgs.Item2, repstosArgs.Item3, repstosArgs.Item4
                                }),
                                new IdentifierExpr(Token.NoToken, this.mem_stack)
                            });
                        AssignCmd stack_ac = new AssignCmd(Token.NoToken,
                                                           new List <AssignLhs> {
                                new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.mem_stack))
                            },
                                                           new List <Expr> {
                                rhs
                            });

                        rhs = new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), new List <Expr> {
                                isAddrInBitmap,
                                new NAryExpr(Token.NoToken,
                                             (ac.Rhss[0] as NAryExpr).Fun,
                                             new List <Expr> {
                                    new IdentifierExpr(Token.NoToken, this.mem_bitmap), repstosArgs.Item2, repstosArgs.Item3, repstosArgs.Item4
                                }),
                                new IdentifierExpr(Token.NoToken, this.mem_bitmap)
                            });
                        AssignCmd bitmap_ac = new AssignCmd(Token.NoToken,
                                                            new List <AssignLhs>()
                            {
                                new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.mem_bitmap))
                            },
                                                            new List <Expr>()
                            {
                                rhs
                            });

                        newCmdSeq.Add(ac);
                        newCmdSeq.Add(stack_ac);
                        newCmdSeq.Add(bitmap_ac);

                        break;
                    }

                    default:
                    {
                        if (ac.Lhss.First().DeepAssignedVariable.Name.Equals("mem_stack"))
                        {
                            if (isBitmapAddress(this.current_label, c, this.storeAddressRegionDB) ||
                                isNotStackAddress(this.current_label, c, this.storeAddressRegionDB))
                            {
                                break;
                            }
                            else if (isStackAddress(this.current_label, c, this.storeAddressRegionDB))
                            {
                                AssignCmd updateStack = new AssignCmd(Token.NoToken, new List <AssignLhs> {
                                        new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.mem_stack))
                                    }, new List <Expr> {
                                        Utils.getSplitMemoryUpdateExpr(ac)
                                    });
                                newCmdSeq.Add(updateStack);
                                break;
                            }
                        }
                        else if (ac.Lhss.First().DeepAssignedVariable.Name.Equals("mem_bitmap"))
                        {
                            if (isStackAddress(this.current_label, c, this.storeAddressRegionDB) ||
                                isNotBitmapAddress(this.current_label, c, this.storeAddressRegionDB))
                            {
                                break;
                            }
                            else if (isBitmapAddress(this.current_label, c, this.storeAddressRegionDB))
                            {
                                AssignCmd updateBitmap = new AssignCmd(Token.NoToken, new List <AssignLhs> {
                                        new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, this.mem_bitmap))
                                    }, new List <Expr> {
                                        Utils.getSplitMemoryUpdateExpr(ac)
                                    });
                                newCmdSeq.Add(updateBitmap);
                                break;
                            }
                        }
                        newCmdSeq.Add(ac);
                        break;
                    }
                    }
                }
                else
                {
                    newCmdSeq.Add(c);
                }
            }
            return(base.VisitCmdSeq(newCmdSeq));
        }
Пример #23
0
 public override Expr VisitNAryExpr(NAryExpr node)
 {
     BinaryOperator op = node.Fun as BinaryOperator;
       if (op != null && op.Op == BinaryOperator.Opcode.Subtype)
       isMonomorphic = false;
       return base.VisitNAryExpr(node);
 }
Пример #24
0
        /// <summary>
        /// Computes the wlp for an assert or assume command "cmd".
        /// </summary>
        internal static VCExpr Cmd(Block b, Cmd cmd, VCExpr N, VCContext ctxt)
        {
            Contract.Requires(cmd != null);
            Contract.Requires(N != null);
            Contract.Requires(ctxt != null);
            Contract.Ensures(Contract.Result <VCExpr>() != null);

            VCExpressionGenerator gen = ctxt.Ctxt.ExprGen;

            Contract.Assert(gen != null);
            if (cmd is AssertCmd)
            {
                AssertCmd ac = (AssertCmd)cmd;

                var isFullyVerified = false;
                if (ac.VerifiedUnder != null)
                {
                    var litExpr = ac.VerifiedUnder as LiteralExpr;
                    isFullyVerified = litExpr != null && litExpr.IsTrue;
                }

                if (!isFullyVerified)
                {
                    ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext;
                }

                VCExpr C = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr);
                #region proofgeneration
                VCExpr postVC = N;
                VCExpr exprVC = C;
                #endregion

                VCExpr VU = null;
                if (!isFullyVerified)
                {
                    if (ac.VerifiedUnder != null)
                    {
                        VU = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.VerifiedUnder);

                        if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout)
                        {
                            ctxt.Ctxt.TimeoutDiagnosticIDToAssertion[ctxt.Ctxt.TimoutDiagnosticsCount] =
                                new Tuple <AssertCmd, TransferCmd>(ac, b.TransferCmd);
                            VU = gen.Or(VU,
                                        gen.Function(VCExpressionGenerator.TimeoutDiagnosticsOp,
                                                     gen.Integer(BigNum.FromInt(ctxt.Ctxt.TimoutDiagnosticsCount++))));
                        }
                    }
                    else if (CommandLineOptions.Clo.RunDiagnosticsOnTimeout)
                    {
                        ctxt.Ctxt.TimeoutDiagnosticIDToAssertion[ctxt.Ctxt.TimoutDiagnosticsCount] =
                            new Tuple <AssertCmd, TransferCmd>(ac, b.TransferCmd);
                        VU = gen.Function(VCExpressionGenerator.TimeoutDiagnosticsOp,
                                          gen.Integer(BigNum.FromInt(ctxt.Ctxt.TimoutDiagnosticsCount++)));
                    }

                    ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext;
                }

                {
                    var subsumption = Subsumption(ac);
                    if (subsumption == CommandLineOptions.SubsumptionOption.Always ||
                        (subsumption == CommandLineOptions.SubsumptionOption.NotForQuantifiers && !(C is VCExprQuantifier)))
                    {
                        N = gen.ImpliesSimp(C, N, false);
                    }

                    if (isFullyVerified)
                    {
                        throw new NotImplementedException("proof generation does not support this option (caching of verification results)");
                        return(N);
                    }
                    else if (VU != null)
                    {
                        C = gen.OrSimp(VU, C);
                    }

                    int id = ac.UniqueId;
                    if (ctxt.Label2absy != null)
                    {
                        ctxt.Label2absy[id] = ac;
                    }

                    ctxt.AssertionCount++;

                    if (ctxt.ControlFlowVariableExpr == null)
                    {
                        Contract.Assert(ctxt.Label2absy != null);
                        #region proofgeneration

                        ProofGeneration.ProofGenerationLayer.NextVcHintForBlock(
                            cmd,
                            b,
                            exprVC,
                            postVC,
                            gen.AndSimp(C, N),
                            subsumption
                            );

                        #endregion

                        return(gen.AndSimp(C, N));
                    }
                    else
                    {
                        VCExpr controlFlowFunctionAppl = gen.ControlFlowFunctionApplication(ctxt.ControlFlowVariableExpr,
                                                                                            gen.Integer(BigNum.FromInt(b.UniqueId)));
                        Contract.Assert(controlFlowFunctionAppl != null);
                        VCExpr assertFailure = gen.Eq(controlFlowFunctionAppl, gen.Integer(BigNum.FromInt(-ac.UniqueId)));
                        return(gen.AndSimp(gen.Implies(assertFailure, C), N));
                    }
                }
            }
            else if (cmd is AssumeCmd)
            {
                AssumeCmd ac = (AssumeCmd)cmd;

                if (CommandLineOptions.Clo.StratifiedInlining > 0)
                {
                    // Label the assume if it is a procedure call
                    NAryExpr naryExpr = ac.Expr as NAryExpr;
                    if (naryExpr != null)
                    {
                        if (naryExpr.Fun is FunctionCall)
                        {
                            int id = ac.UniqueId;
                            ctxt.Label2absy[id] = ac;
                            return(MaybeWrapWithOptimization(ctxt, gen, ac.Attributes,
                                                             gen.ImpliesSimp(ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr), N)));
                        }
                    }
                }

                var expr = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr);

                var aid = QKeyValue.FindStringAttribute(ac.Attributes, "id");
                if (aid != null)
                {
                    var isTry = QKeyValue.FindBoolAttribute(ac.Attributes, "try");
                    var v     = gen.Variable((isTry ? "try$$" : "assume$$") + aid, Microsoft.Boogie.Type.Bool);
                    expr = gen.Function(VCExpressionGenerator.NamedAssumeOp, v, gen.ImpliesSimp(v, expr));
                }

                var soft       = QKeyValue.FindBoolAttribute(ac.Attributes, "soft");
                var softWeight = QKeyValue.FindIntAttribute(ac.Attributes, "soft", 0);
                if ((soft || 0 < softWeight) && aid != null)
                {
                    var v = gen.Variable("soft$$" + aid, Microsoft.Boogie.Type.Bool);
                    expr = gen.Function(new VCExprSoftOp(Math.Max(softWeight, 1)), v, gen.ImpliesSimp(v, expr));
                }

                #region proofgeneration
                ProofGeneration.ProofGenerationLayer.NextVcHintForBlock(
                    cmd,
                    b,
                    expr,
                    N,
                    gen.ImpliesSimp(expr, N),
                    CommandLineOptions.SubsumptionOption.Never
                    );
                #endregion

                return(MaybeWrapWithOptimization(ctxt, gen, ac.Attributes, gen.ImpliesSimp(expr, N)));
            }
            else
            {
                Console.WriteLine(cmd.ToString());
                Contract.Assert(false);
                throw new cce.UnreachableException(); // unexpected command
            }
        }
Пример #25
0
        public void Transform()
        {
            foreach (var impl in program.Implementations)
            {
                Dictionary<string, Variable> domainNameToInputVar = new Dictionary<string, Variable>();
                foreach (string domainName in linearDomains.Keys)
                {
                    var domain = linearDomains[domainName];
                    Formal f = new Formal(
                      Token.NoToken,
                      new TypedIdent(Token.NoToken, 
                        "linear_" + domainName + "_in",
                        new MapType(Token.NoToken, new List<TypeVariable>(), 
                          new List<Type> { domain.elementType }, Type.Bool)), true);
                    impl.InParams.Add(f);
                    domainNameToInputVar[domainName] = f;
                }

                foreach (Block b in impl.Blocks)
                {
                    List<Cmd> newCmds = new List<Cmd>();
                    for (int i = 0; i < b.Cmds.Count; i++)
                    {
                        Cmd cmd = b.Cmds[i];
                        newCmds.Add(cmd);
                        if (cmd is CallCmd)
                        {
                            CallCmd callCmd = cmd as CallCmd;
                            if (callCmd.IsAsync)
                            {
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    var domain = linearDomains[domainName];
                                    var expr = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List<Expr> { Expr.False });
                                    expr.Resolve(new ResolutionContext(null));
                                    expr.Typecheck(new TypecheckingContext(null));
                                    callCmd.Ins.Add(expr);
                                }
                            }
                            else
                            {
                                Dictionary<string, Expr> domainNameToExpr = new Dictionary<string, Expr>();
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    domainNameToExpr[domainName] = Expr.Ident(domainNameToInputVar[domainName]);
                                }
                                foreach (Variable v in AvailableLinearVars(callCmd))
                                {
                                    var domainName = FindDomainName(v);
                                    var domain = linearDomains[domainName];
                                    if (!domain.collectors.ContainsKey(v.TypedIdent.Type)) continue;
                                    Expr ie = new NAryExpr(Token.NoToken, new FunctionCall(domain.collectors[v.TypedIdent.Type]), new List<Expr> { Expr.Ident(v) });
                                    var expr = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapOrBool), new List<Expr> { ie, domainNameToExpr[domainName] });
                                    expr.Resolve(new ResolutionContext(null));
                                    expr.Typecheck(new TypecheckingContext(null));
                                    domainNameToExpr[domainName] = expr;
                                }
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    callCmd.Ins.Add(domainNameToExpr[domainName]);
                                }
                            }
                        }
                        else if (cmd is ParCallCmd)
                        {
                            ParCallCmd parCallCmd = (ParCallCmd)cmd;
                            foreach (CallCmd callCmd in parCallCmd.CallCmds)
                            {
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    var domain = linearDomains[domainName];
                                    var expr = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List<Expr> { Expr.False });
                                    expr.Resolve(new ResolutionContext(null));
                                    expr.Typecheck(new TypecheckingContext(null));
                                    callCmd.Ins.Add(expr);
                                }
                            }
                        }
                        else if (cmd is YieldCmd)
                        {
                            AddDisjointnessExpr(newCmds, cmd, domainNameToInputVar);
                        }
                    }
                    b.Cmds = newCmds;
                }

                {
                    // Loops
                    impl.PruneUnreachableBlocks();
                    impl.ComputePredecessorsForBlocks();
                    GraphUtil.Graph<Block> g = Program.GraphFromImpl(impl);
                    g.ComputeLoops();
                    if (g.Reducible)
                    {
                        foreach (Block header in g.Headers)
                        {
                            List<Cmd> newCmds = new List<Cmd>();
                            AddDisjointnessExpr(newCmds, header, domainNameToInputVar);
                            newCmds.AddRange(header.Cmds);
                            header.Cmds = newCmds;
                        }
                    }
                }
            }

            foreach (var proc in program.Procedures)
            {
                Dictionary<string, HashSet<Variable>> domainNameToInputScope = new Dictionary<string, HashSet<Variable>>();
                Dictionary<string, HashSet<Variable>> domainNameToOutputScope = new Dictionary<string, HashSet<Variable>>();
                foreach (var domainName in linearDomains.Keys)
                {
                    domainNameToInputScope[domainName] = new HashSet<Variable>();
                    domainNameToOutputScope[domainName] = new HashSet<Variable>();
                    
                }
                foreach (Variable v in globalVarToDomainName.Keys)
                {
                    var domainName = globalVarToDomainName[v];
                    domainNameToInputScope[domainName].Add(v);
                    domainNameToOutputScope[domainName].Add(v);
                }
                foreach (Variable v in proc.InParams)
                {
                    var domainName = FindDomainName(v);
                    if (domainName == null) continue;
                    if (!this.linearDomains.ContainsKey(domainName)) continue;
                    domainNameToInputScope[domainName].Add(v);
                }
                foreach (Variable v in proc.OutParams)
                {
                    var domainName = FindDomainName(v);
                    if (domainName == null) continue;
                    if (!this.linearDomains.ContainsKey(domainName)) continue;
                    domainNameToOutputScope[domainName].Add(v);
                }
                foreach (var domainName in linearDomains.Keys)
                {
                    proc.Requires.Add(new Requires(true, DisjointnessExpr(domainName, domainNameToInputScope[domainName])));
                    var domain = linearDomains[domainName];
                    Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "linear_" + domainName + "_in", new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { domain.elementType }, Type.Bool)), true);
                    proc.InParams.Add(f);
                    proc.Ensures.Add(new Ensures(true, DisjointnessExpr(domainName, f, domainNameToOutputScope[domainName])));
                }
            }
            
            foreach (LinearDomain domain in linearDomains.Values)
            {
                program.AddTopLevelDeclaration(domain.mapConstBool);
                program.AddTopLevelDeclaration(domain.mapConstInt);
                program.AddTopLevelDeclaration(domain.mapEqInt);
                program.AddTopLevelDeclaration(domain.mapImpBool);
                program.AddTopLevelDeclaration(domain.mapOrBool);
                foreach (Axiom axiom in domain.axioms)
                {
                    program.AddTopLevelDeclaration(axiom);
                }
            }

            //int oldPrintUnstructured = CommandLineOptions.Clo.PrintUnstructured;
            //CommandLineOptions.Clo.PrintUnstructured = 1;
            //PrintBplFile("lsd.bpl", program, false, false);
            //CommandLineOptions.Clo.PrintUnstructured = oldPrintUnstructured;
        }
Пример #26
0
        public void SimpleMap()
        {
            int  hits = 0;
            Expr nestedMapStoreintermediate = null;
            Expr simpleMapStoreIntermediate = null;

            p = LoadProgramFrom("programs/SimpleMap.bpl");
            e = GetExecutor(p);
            var builderDuplicator = new BuilderDuplicator(new SimpleExprBuilder(/*immutable=*/ true));

            e.BreakPointReached += delegate(object executor, Executor.BreakPointEventArgs data)
            {
                if (data.Name == "check_read_map")
                {
                    var a = e.CurrentState.GetInScopeVariableAndExprByName("a"); // a := symbolic_0[0bv8]
                    Assert.IsInstanceOf <NAryExpr>(a.Value);
                    NAryExpr mapSelect = a.Value as NAryExpr;
                    Assert.IsInstanceOf <MapSelect>(mapSelect.Fun);
                    Assert.AreEqual(2, mapSelect.Args.Count);

                    // [0] should be map Identifier
                    CheckIsSymbolicIdentifier(mapSelect.Args[0], e.CurrentState);

                    // [1] should be offset
                    CheckIsLiteralBVConstWithValue(mapSelect.Args[1], BigNum.FromInt(0));
                }
                else if (data.Name == "check_write_literal")
                {
                    var m = e.CurrentState.GetInScopeVariableAndExprByName("m");         // m := symbolic_0[3bv8 := 12bv32]
                    simpleMapStoreIntermediate = (Expr)builderDuplicator.Visit(m.Value); // Save a copy of the expression for later.
                    Assert.IsInstanceOf <NAryExpr>(m.Value);
                    NAryExpr mapStore = m.Value as NAryExpr;
                    Assert.IsInstanceOf <MapStore>(mapStore.Fun);
                    Assert.AreEqual(3, mapStore.Args.Count);

                    // [0] should be map Identifier
                    CheckIsSymbolicIdentifier(mapStore.Args[0], e.CurrentState);

                    // [1] should be write offset
                    CheckIsLiteralBVConstWithValue(mapStore.Args[1], BigNum.FromInt(3));

                    // [2] should be value written to location in Map
                    CheckIsLiteralBVConstWithValue(mapStore.Args[2], BigNum.FromInt(12));
                }
                else if (data.Name == "check_write_from_map")
                {
                    var m = e.CurrentState.GetInScopeVariableAndExprByName("m");
                    nestedMapStoreintermediate = (Expr)builderDuplicator.Visit(m.Value);  // Save a copy of the expression for later.
                    Assert.IsInstanceOf <NAryExpr>(m.Value);
                    NAryExpr mapStore = m.Value as NAryExpr;
                    Assert.IsInstanceOf <MapStore>(mapStore.Fun); // symbolic_0[3bv8:= 12bv32][1bv8 := symbolic_0[0bv8]]
                    Assert.AreEqual(3, mapStore.Args.Count);

                    // [0] Is Map written to which should we wrote to earlier so should also be MapStore
                    Assert.IsTrue(mapStore.Args[0].Equals(simpleMapStoreIntermediate));


                    // [1] is write offset
                    CheckIsLiteralBVConstWithValue(mapStore.Args[1], BigNum.FromInt(1)); // 1bv8

                    // [2] is value to write which is actually a value inside own map
                    Assert.IsInstanceOf <NAryExpr>(mapStore.Args[2]);
                    NAryExpr WrittenValue = mapStore.Args[2] as NAryExpr; // symbolic_0[0bv8]
                    Assert.IsInstanceOf <MapSelect>(WrittenValue.Fun);


                    {
                        // [0] should be map Identifier
                        CheckIsSymbolicIdentifier(WrittenValue.Args[0], e.CurrentState);

                        // [1] should be offset
                        CheckIsLiteralBVConstWithValue(WrittenValue.Args[1], BigNum.FromInt(0));
                    }
                }
                else if (data.Name == "check_write_symbolic_index")
                {
                    // Expecting m := symbolic_0[3bv8 := 12bv32][1bv8 := symbolic_0[0bv8]][symbolic_2 := 7bv32]
                    var m = e.CurrentState.GetInScopeVariableAndExprByName("m");
                    Assert.IsInstanceOf <NAryExpr>(m.Value);
                    NAryExpr mapStore = m.Value as NAryExpr;
                    Assert.IsInstanceOf <MapStore>(mapStore.Fun); // symbolic_0[3bv8:= 12bv32][1bv8 := symbolic_0[0bv8]]
                    Assert.AreEqual(3, mapStore.Args.Count);

                    // [0] Should be the map written to which should be equivalent to the expression recorded in "intermediate"
                    Assert.IsNotNull(nestedMapStoreintermediate);
                    Assert.IsTrue(nestedMapStoreintermediate.Equals(mapStore.Args[0]));

                    // [1] Write offset which should be symbolic (symbolic_2)
                    CheckIsSymbolicIdentifier(mapStore.Args[1], e.CurrentState);

                    // [2] Value to write (7bv32)
                    CheckIsLiteralBVConstWithValue(mapStore.Args[2], BigNum.FromInt(7));
                }
                else
                {
                    Assert.Fail("Unsupported break point");
                }

                ++hits;
            };
            e.Run(GetMain(p));
            Assert.AreEqual(4, hits);
        }
Пример #27
0
 private void AddInitialBlock(Implementation impl, List<Variable> oldPcs, List<Variable> oldOks,
     Dictionary<string, Variable> domainNameToInputVar, Dictionary<string, Variable> domainNameToLocalVar, Dictionary<Variable, Variable> ogOldGlobalMap)
 {
     // Add initial block
     List<AssignLhs> lhss = new List<AssignLhs>();
     List<Expr> rhss = new List<Expr>();
     if (pc != null)
     {
         lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(pc)));
         rhss.Add(Expr.False);
         foreach (Variable oldPc in oldPcs)
         {
             lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(oldPc)));
             rhss.Add(Expr.False);
         }
         lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(ok)));
         rhss.Add(Expr.False);
         foreach (Variable oldOk in oldOks)
         {
             lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(oldOk)));
             rhss.Add(Expr.False);
         }
     }
     Dictionary<string, Expr> domainNameToExpr = new Dictionary<string, Expr>();
     foreach (var domainName in linearTypeChecker.linearDomains.Keys)
     {
         domainNameToExpr[domainName] = Expr.Ident(domainNameToInputVar[domainName]);
     }
     for (int i = 0; i < impl.InParams.Count - linearTypeChecker.linearDomains.Count; i++)
     {
         Variable v = impl.InParams[i];
         var domainName = linearTypeChecker.FindDomainName(v);
         if (domainName == null) continue;
         if (!linearTypeChecker.linearDomains.ContainsKey(domainName)) continue;
         var domain = linearTypeChecker.linearDomains[domainName];
         if (!domain.collectors.ContainsKey(v.TypedIdent.Type)) continue;
         Expr ie = new NAryExpr(Token.NoToken, new FunctionCall(domain.collectors[v.TypedIdent.Type]), new List<Expr> { Expr.Ident(v) });
         domainNameToExpr[domainName] = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapOrBool), new List<Expr> { ie, domainNameToExpr[domainName] });
     }
     foreach (string domainName in linearTypeChecker.linearDomains.Keys)
     {
         lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(domainNameToLocalVar[domainName])));
         rhss.Add(domainNameToExpr[domainName]);
     }
     foreach (Variable g in ogOldGlobalMap.Keys)
     {
         lhss.Add(new SimpleAssignLhs(Token.NoToken, Expr.Ident(ogOldGlobalMap[g])));
         rhss.Add(Expr.Ident(g));
     }
     if (lhss.Count > 0)
     {
         Block initBlock = new Block(Token.NoToken, "og_init", new List<Cmd> { new AssignCmd(Token.NoToken, lhss, rhss) }, new GotoCmd(Token.NoToken, new List<String> { impl.Blocks[0].Label }, new List<Block> { impl.Blocks[0] }));
         impl.Blocks.Insert(0, initBlock);
     }
 }
Пример #28
0
        /// <summary>
        /// Computes the wlp for an assert or assume command "cmd".
        /// </summary>
        public static VCExpr Cmd(Block b, Cmd cmd, VCExpr N, VCContext ctxt)
        {
            Contract.Requires(cmd != null);
            Contract.Requires(N != null);
            Contract.Requires(ctxt != null);
            Contract.Ensures(Contract.Result <VCExpr>() != null);

            VCExpressionGenerator gen = ctxt.Ctxt.ExprGen;

            Contract.Assert(gen != null);
            if (cmd is AssertCmd)
            {
                AssertCmd ac = (AssertCmd)cmd;
                ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext;
                VCExpr C = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr);
                ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext;
                if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed)
                {
                    return(gen.Implies(C, N));
                }
                else
                {
                    int id = ac.UniqueId;
                    if (ctxt.Label2absy != null)
                    {
                        ctxt.Label2absy[id] = ac;
                    }

                    switch (Subsumption(ac))
                    {
                    case CommandLineOptions.SubsumptionOption.Never:
                        break;

                    case CommandLineOptions.SubsumptionOption.Always:
                        N = gen.Implies(C, N);
                        break;

                    case CommandLineOptions.SubsumptionOption.NotForQuantifiers:
                        if (!(C is VCExprQuantifier))
                        {
                            N = gen.Implies(C, N);
                        }
                        break;

                    default:
                        Contract.Assert(false); throw new cce.UnreachableException(); // unexpected case
                    }

                    // (MSchaef) Hack: This line might be useless, but at least it is not harmful
                    // need to test it
                    if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed)
                    {
                        return(gen.Implies(C, N));
                    }

                    ctxt.AssertionCount++;
                    if (ctxt.ControlFlowVariableExpr == null)
                    {
                        Contract.Assert(ctxt.Label2absy != null);
                        return(gen.AndSimp(gen.LabelNeg(cce.NonNull(id.ToString()), C), N));
                    }
                    else
                    {
                        VCExpr controlFlowFunctionAppl = gen.ControlFlowFunctionApplication(ctxt.ControlFlowVariableExpr, gen.Integer(BigNum.FromInt(b.UniqueId)));
                        Contract.Assert(controlFlowFunctionAppl != null);
                        VCExpr assertFailure = gen.Eq(controlFlowFunctionAppl, gen.Integer(BigNum.FromInt(-ac.UniqueId)));
                        if (ctxt.Label2absy == null)
                        {
                            return(gen.AndSimp(gen.Implies(assertFailure, C), N));
                        }
                        else
                        {
                            return(gen.AndSimp(gen.LabelNeg(cce.NonNull(id.ToString()), gen.Implies(assertFailure, C)), N));
                        }
                    }
                }
            }
            else if (cmd is AssumeCmd)
            {
                AssumeCmd ac = (AssumeCmd)cmd;

                if (CommandLineOptions.Clo.StratifiedInlining > 0)
                {
                    var pname = QKeyValue.FindStringAttribute(ac.Attributes, "candidate");
                    if (pname != null)
                    {
                        return(gen.ImpliesSimp(gen.LabelPos("candidate_" + pname.ToString(), ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr)), N));
                    }

                    // Label the assume if it is a procedure call
                    NAryExpr naryExpr = ac.Expr as NAryExpr;
                    if (naryExpr != null)
                    {
                        if (naryExpr.Fun is FunctionCall)
                        {
                            int id = ac.UniqueId;
                            ctxt.Label2absy[id] = ac;
                            return(gen.ImpliesSimp(gen.LabelPos(cce.NonNull("si_fcall_" + id.ToString()), ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr)), N));
                        }
                    }
                }
                return(gen.ImpliesSimp(ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr), N));
            }
            else
            {
                Console.WriteLine(cmd.ToString());
                Contract.Assert(false); throw new cce.UnreachableException(); // unexpected command
            }
        }
Пример #29
0
 public override Expr VisitNAryExpr(NAryExpr node) {
   //Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<Expr>() != null);
   return base.VisitNAryExpr((NAryExpr)node.Clone());
 }
Пример #30
0
        /// <summary>
        /// Computes the wlp for an assert or assume command "cmd".
        /// </summary>
        public static VCExpr P_Cmd(Block b, HashSet <string> constantsAssumed, Cmd cmd, VCExpr N, VCContext ctxt)
        {
            Contract.Requires(cmd != null);
            Contract.Requires(N != null);
            Contract.Requires(ctxt != null);
            Contract.Ensures(Contract.Result <VCExpr>() != null);

            VCExpressionGenerator gen = ctxt.Ctxt.ExprGen;

            Contract.Assert(gen != null);
            if (cmd is AssertCmd)
            {
                AssertCmd ac = (AssertCmd)cmd;
                ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext;
                VCExpr C = ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr);
                ctxt.Ctxt.BoogieExprTranslator.isPositiveContext = !ctxt.Ctxt.BoogieExprTranslator.isPositiveContext;
                if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed)
                {
                    return(gen.Implies(C, N));
                }
                else
                {
                    int id = ac.UniqueId;
                    if (ctxt.Label2absy != null)
                    {
                        ctxt.Label2absy[id] = ac;
                    }

                    switch (Subsumption(ac))
                    {
                    case CommandLineOptions.SubsumptionOption.Never:
                        break;

                    case CommandLineOptions.SubsumptionOption.Always:
                        N = gen.Implies(C, N);
                        break;

                    case CommandLineOptions.SubsumptionOption.NotForQuantifiers:
                        if (!(C is VCExprQuantifier))
                        {
                            N = gen.Implies(C, N);
                        }
                        break;

                    default:
                        Contract.Assert(false); throw new cce.UnreachableException();  // unexpected case
                    }

                    // (MSchaef) Hack: This line might be useless, but at least it is not harmful
                    // need to test it
                    if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed)
                    {
                        return(gen.Implies(C, N));
                    }

                    ctxt.AssertionCount++;
                    if (ctxt.ControlFlowVariableExpr == null)
                    {
                        Contract.Assert(ctxt.Label2absy != null);
                        return(gen.AndSimp(gen.LabelNeg(cce.NonNull(id.ToString()), C), N));
                    }
                    else
                    {
                        VCExpr controlFlowFunctionAppl = gen.ControlFlowFunctionApplication(ctxt.ControlFlowVariableExpr, gen.Integer(BigNum.FromInt(b.UniqueId)));
                        Contract.Assert(controlFlowFunctionAppl != null);
                        VCExpr assertFailure = gen.Eq(controlFlowFunctionAppl, gen.Integer(BigNum.FromInt(-ac.UniqueId)));
                        if (ctxt.Label2absy == null)
                        {
                            return(gen.AndSimp(gen.Implies(assertFailure, C), N));
                        }
                        else
                        {
                            return(gen.AndSimp(gen.LabelNeg(cce.NonNull(id.ToString()), gen.Implies(assertFailure, C)), N));
                        }
                    }
                }
            }
            else if (cmd is AssumeCmd)
            {
                AssumeCmd ac = (AssumeCmd)cmd;

                if (CommandLineOptions.Clo.StratifiedInlining > 0)
                {
                    Contract.Assert(false);
                    throw new System.Exception(string.Format("VC Generation in ICE-learning does not handle stratified inlining"));

                    var pname = QKeyValue.FindStringAttribute(ac.Attributes, "candidate");
                    if (pname != null)
                    {
                        return(gen.ImpliesSimp(gen.LabelPos("candidate_" + pname.ToString(), ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr)), N));
                    }

                    // Label the assume if it is a procedure call
                    NAryExpr naryExpr = ac.Expr as NAryExpr;
                    if (naryExpr != null)
                    {
                        if (naryExpr.Fun is FunctionCall)
                        {
                            int id = ac.UniqueId;
                            ctxt.Label2absy[id] = ac;
                            return(gen.ImpliesSimp(gen.LabelPos(cce.NonNull("si_fcall_" + id.ToString()), ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr)), N));
                        }
                    }
                }
                //return gen.ImpliesSimp(ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr), N);
                else
                {
                    if (constantsAssumed == null)
                    {
                        return(gen.ImpliesSimp(ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr), N));
                    }

                    // check if the assume command contains any of the constantsAssumed (corresponding to existential function calls)?
                    var  funcsUsed             = FunctionCollector.Collect(ac.Expr);
                    bool hasAnyConstantAssumed = false;

                    foreach (var tup in funcsUsed)
                    {
                        var constantFunc = tup.Item1;
                        if (constantsAssumed.Contains(constantFunc.Name))
                        {
                            hasAnyConstantAssumed = true;
                            break;
                        }
                    }

                    if (hasAnyConstantAssumed)
                    {
                        int id = ac.UniqueId;
                        if (ctxt.Label2absy != null)
                        {
                            ctxt.Label2absy[id] = ac;
                        }

                        //ctxt.AssertionCount++;
                        if (ctxt.ControlFlowVariableExpr == null)
                        {
                            Contract.Assert(ctxt.Label2absy != null);
                            return(gen.ImpliesSimp(gen.LabelPos(cce.NonNull(id.ToString()), ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr)), N));
                        }
                        else
                        {
                            return(gen.ImpliesSimp(ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr), N));

                            /*VCExpr controlFlowFunctionAppl = gen.ControlFlowFunctionApplication(ctxt.ControlFlowVariableExpr, gen.Integer(BigNum.FromInt(b.UniqueId)));
                             * Contract.Assert(controlFlowFunctionAppl != null);
                             * VCExpr assumeFailure = gen.Eq(controlFlowFunctionAppl, gen.Integer(BigNum.FromInt(-ac.UniqueId)));
                             * if (ctxt.Label2absy == null)
                             * {
                             *  throw new System.Exception(string.Format("Dont know how to handle labels for the assume cmd"));
                             *  //return gen.ImpliesSimp(gen.LabelPos(cce.NonNull(id.ToString()), gen.Implies(assumeFailure, ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr))), N);
                             * }
                             * else
                             * {
                             *  return gen.ImpliesSimp(gen.LabelPos(cce.NonNull(id.ToString()), gen.Implies(assumeFailure, ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr))), N);
                             * }
                             */
                        }
                    }
                    else
                    {
                        return(gen.ImpliesSimp(ctxt.Ctxt.BoogieExprTranslator.Translate(ac.Expr), N));
                    }
                }
            }
            else
            {
                Console.WriteLine(cmd.ToString());
                Contract.Assert(false); throw new cce.UnreachableException(); // unexpected command
            }
        }
Пример #31
0
    public StratifiedInliningInfo(Implementation implementation, StratifiedVCGenBase stratifiedVcGen,
      Action<Implementation> PassiveImplInstrumentation)
    {
      vcgen = stratifiedVcGen;
      impl = implementation;
      this.PassiveImplInstrumentation = PassiveImplInstrumentation;

      List<Variable> functionInterfaceVars = new List<Variable>();
      foreach (Variable v in vcgen.program.GlobalVariables)
      {
        functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", v.TypedIdent.Type),
          true));
      }

      foreach (Variable v in impl.InParams)
      {
        functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", v.TypedIdent.Type),
          true));
      }

      foreach (Variable v in impl.OutParams)
      {
        functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", v.TypedIdent.Type),
          true));
      }

      foreach (IdentifierExpr e in impl.Proc.Modifies)
      {
        if (e.Decl == null) continue;
        functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", e.Decl.TypedIdent.Type),
          true));
      }

      Formal returnVar = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Bpl.Type.Bool), false);
      function = new Function(Token.NoToken, impl.Name, functionInterfaceVars, returnVar);
      vcgen.prover.Context.DeclareFunction(function, "");

      List<Expr> exprs = new List<Expr>();
      foreach (Variable v in vcgen.program.GlobalVariables)
      {
        Contract.Assert(v != null);
        exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
      }

      foreach (Variable v in impl.Proc.InParams)
      {
        Contract.Assert(v != null);
        exprs.Add(new IdentifierExpr(Token.NoToken, v));
      }

      foreach (Variable v in impl.Proc.OutParams)
      {
        Contract.Assert(v != null);
        exprs.Add(new IdentifierExpr(Token.NoToken, v));
      }

      foreach (IdentifierExpr ie in impl.Proc.Modifies)
      {
        Contract.Assert(ie != null);
        if (ie.Decl == null)
          continue;
        exprs.Add(ie);
      }

      Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(function), exprs);
      impl.Proc.Ensures.Add(new Ensures(Token.NoToken, true, freePostExpr, "",
        new QKeyValue(Token.NoToken, "si_fcall", new List<object>(), null)));

      initialized = false;
    }
Пример #32
0
 // NAryExpr
 public static int GetNumberOfChildren(this NAryExpr e)
 {
     return(e.Args.Count);
 }
Пример #33
0
 public override Expr VisitNAryExpr(NAryExpr node) {
   if (node.Fun is UnaryOperator) {
     var op = (UnaryOperator)node.Fun;
     Contract.Assert(node.Args.Count == 1);
     if (op.Op == UnaryOperator.Opcode.Neg) {
       BigInteger? lo, hi;
       VisitExpr(node.Args[0]);
       lo = Lo; hi = Hi;
       if (hi != null) {
         Lo = node.Type.IsReal ? -hi : 1 - hi;
       } else {
         Lo = null;
       }
       if (lo != null) {
         Hi = node.Type.IsReal ? -lo : 1 - lo;
       } else {
         Hi = null;
       }
     }
     else if (op.Op == UnaryOperator.Opcode.Not) {
       VisitExpr(node.Args[0]);
       Contract.Assert((Lo == null && Hi == null) ||
         (Lo == null && (BigInteger)Hi == 1) ||
         (Hi == null && (BigInteger)Lo == 1));
       var tmp = Lo;
       Lo = Hi;
       Hi = tmp;
     }
   } else if (node.Fun is BinaryOperator) {
     var op = (BinaryOperator)node.Fun;
     Contract.Assert(node.Args.Count == 2);
     BigInteger? lo0, hi0, lo1, hi1;
     VisitExpr(node.Args[0]);
     lo0 = Lo; hi0 = Hi;
     VisitExpr(node.Args[1]);
     lo1 = Lo; hi1 = Hi;
     Lo = Hi = null;
     var isReal = node.Args[0].Type.IsReal;
     switch (op.Op) {
       case BinaryOperator.Opcode.And:
         if (hi0 != null || hi1 != null) {
           // one operand is definitely false, thus so is the result
           Lo = null; Hi = one;
         } else if (lo0 != null && lo1 != null) {
           // both operands are definitely true, thus so is the result
           Lo = one; Hi = null;
         }
         break;
       case BinaryOperator.Opcode.Or:
         if (lo0 != null || lo1 != null) {
           // one operand is definitely true, thus so is the result
           Lo = one; Hi = null;
         } else if (hi0 != null && hi1 != null) {
           // both operands are definitely false, thus so is the result
           Lo = null; Hi = one;
         }
         break;
       case BinaryOperator.Opcode.Imp:
         if (hi0 != null || lo1 != null) {
           // either arg0 false or arg1 is true, so the result is true
           Lo = one; Hi = null;
         } else if (lo0 != null && hi1 != null) {
           // arg0 is true and arg1 is false, so the result is false
           Lo = null; Hi = one;
         }
         break;
       case BinaryOperator.Opcode.Iff:
         if (lo0 != null && lo1 != null) {
           Lo = one; Hi = null;
         } else if (hi0 != null && hi1 != null) {
           Lo = one; Hi = null;
         } else if (lo0 != null && hi1 != null) {
           Lo = null; Hi = one;
         } else if (hi0 != null && lo1 != null) {
           Lo = null; Hi = one;
         }
         if (op.Op == BinaryOperator.Opcode.Neq) {
           var tmp = Lo; Lo = Hi; Hi = tmp;
         }
         break;
       case BinaryOperator.Opcode.Eq:
       case BinaryOperator.Opcode.Neq:
         if (node.Args[0].Type.IsBool) {
           goto case BinaryOperator.Opcode.Iff;
         }
         // For Eq:
         // If the (lo0,hi0) and (lo1,hi1) ranges do not overlap, the answer is false.
         // If both ranges are the same unit range, then the answer is true.
         if (hi0 != null && lo1 != null && (isReal ? hi0 < lo1 : hi0 <= lo1)) {
           // no overlap
           Lo = null; Hi = one;
         } else if (lo0 != null && hi1 != null && (isReal ? hi1 < lo0 : hi1 <= lo0)) {
           Lo = null; Hi = one;
           // no overlaop
         } else if (lo0 != null && hi0 != null && lo1 != null && hi1 != null &&
           lo0 == lo1 && hi0 == hi1 &&  // ranges are the same
           (isReal ? lo0 == hi0 : lo0 + 1 == hi0)) {  // unit range
           // both ranges are the same unit range
           Lo = one; Hi = null;
         }
         if (op.Op == BinaryOperator.Opcode.Neq) {
           var tmp = Lo; Lo = Hi; Hi = tmp;
         }
         break;
       case BinaryOperator.Opcode.Le:
         if (isReal) {
           // If hi0 <= lo1, then the answer is true.
           // If hi1 < lo0, then the answer is false.
           if (hi0 != null && lo1 != null && hi0 <= lo1) {
             Lo = one; Hi = null;
           } else if (hi1 != null && lo0 != null && hi1 < lo0) {
             Lo = null; Hi = one;
           }
         } else {
           // If hi0 - 1 <= lo1, then the answer is true.
           // If hi1 <= lo0, then the answer is false.
           if (hi0 != null && lo1 != null && hi0 - 1 <= lo1) {
             Lo = one; Hi = null;
           } else if (lo0 != null && hi1 != null && hi1 <= lo0) {
             Lo = null; Hi = one;
           }
         }
         break;
       case BinaryOperator.Opcode.Lt:
         if (isReal) {
           // If hi0 < lo1, then the answer is true.
           // If hi1 <= lo0, then the answer is false.
           if (hi0 != null && lo1 != null && hi0 < lo1) {
             Lo = one; Hi = null;
           } else if (hi1 != null && lo0 != null && hi1 <= lo0) {
             Lo = null; Hi = one;
           }
         } else {
           // If hi0 <= lo1, then the answer is true.
           // If hi1 - 1 <= lo0, then the answer is false.
           if (hi0 != null && lo1 != null && hi0 <= lo1) {
             Lo = one; Hi = null;
           } else if (lo0 != null && hi1 != null && hi1 - 1 <= lo0) {
             Lo = null; Hi = one;
           }
         }
         break;
       case BinaryOperator.Opcode.Gt:
         // swap the operands and then continue as Lt
         {
           var tmp = lo0; lo0 = lo1; lo1 = tmp;
           tmp = hi0; hi0 = hi1; hi1 = tmp;
         }
         goto case BinaryOperator.Opcode.Lt;
       case BinaryOperator.Opcode.Ge:
         // swap the operands and then continue as Le
         {
           var tmp = lo0; lo0 = lo1; lo1 = tmp;
           tmp = hi0; hi0 = hi1; hi1 = tmp;
         }
         goto case BinaryOperator.Opcode.Le;
       case BinaryOperator.Opcode.Add:
         if (lo0 != null && lo1 != null) {
           Lo = lo0 + lo1;
         }
         if (hi0 != null && hi1 != null) {
           Hi = isReal ? hi0 + hi1 : hi0 + hi1 - 1;
         }
         break;
       case BinaryOperator.Opcode.Sub:
         if (lo0 != null && hi1 != null) {
           Lo = isReal ? lo0 - hi1 : lo0 - hi1 + 1;
         }
         if (hi0 != null && lo1 != null) {
           Hi = hi0 - lo1;
         }
         break;
       case BinaryOperator.Opcode.Mul:
         // this uses an incomplete approximation that could be tightened up
         if (lo0 != null && lo1 != null) {
           if (0 <= (BigInteger)lo0 && 0 <= (BigInteger)lo1) {
             Lo = lo0 * lo1;
             Hi = hi0 == null || hi1 == null ? null : isReal ? hi0 * hi1 : (hi0 - 1) * (hi1 - 1) + 1;
           } else if ((BigInteger)lo0 < 0 && (BigInteger)lo1 < 0) {
             Lo = null;  // approximation
             Hi = isReal ? lo0 * lo1 : lo0 * lo1 + 1;
           }
         }
         break;
       case BinaryOperator.Opcode.Div:
         // this uses an incomplete approximation that could be tightened up
         if (lo0 != null && lo1 != null && 0 <= (BigInteger)lo0 && 0 <= (BigInteger)lo1) {
           Lo = BigInteger.Zero;
           Hi = hi0;
         }
         break;
       case BinaryOperator.Opcode.Mod:
         // this uses an incomplete approximation that could be tightened up
         if (lo0 != null && lo1 != null && 0 <= (BigInteger)lo0 && 0 <= (BigInteger)lo1) {
           Lo = BigInteger.Zero;
           Hi = hi1;
           if (lo0 < lo1 && hi0 != null && hi0 < lo1) {
             Lo = lo0;
             Hi = hi0;
           }
         }
         break;
       case BinaryOperator.Opcode.RealDiv:
         // this uses an incomplete approximation that could be tightened up
         if (lo0 != null && lo1 != null && 0 <= (BigInteger)lo0 && 0 <= (BigInteger)lo1) {
           Lo = BigInteger.Zero;
           Hi = 1 <= (BigInteger)lo1 ? hi0 : null;
         }
         break;
       case BinaryOperator.Opcode.Pow:
         // this uses an incomplete approximation that could be tightened up
         if (lo0 != null && lo1 != null && 0 <= (BigInteger)lo0 && 0 <= (BigInteger)lo1) {
           Lo = 1 <= (BigInteger)lo1 ? BigInteger.One : BigInteger.Zero;
           Hi = hi1;
         }
         break;
       default:
         break;
     }
   } else if (node.Fun is IfThenElse) {
     var op = (IfThenElse)node.Fun;
     Contract.Assert(node.Args.Count == 3);
     BigInteger? guardLo, guardHi, lo0, hi0, lo1, hi1;
     VisitExpr(node.Args[0]);
     guardLo = Lo; guardHi = Hi;
     VisitExpr(node.Args[1]);
     lo0 = Lo; hi0 = Hi;
     VisitExpr(node.Args[2]);
     lo1 = Lo; hi1 = Hi;
     Contract.Assert(guardLo == null || guardHi == null);  // this is a consequence of the guard being boolean
     if (guardLo != null) {
       // guard is always true
       Lo = lo0; Hi = hi0;
     } else if (guardHi != null) {
       // guard is always false
       Lo = lo1; Hi = hi1;
     } else {
       // we don't know which branch will be taken, so join the information from the two branches
       Lo = Node.Min(lo0, lo1, false);
       Hi = Node.Max(hi0, hi1, false);
     }
   } else if (node.Fun is FunctionCall) {
     var call = (FunctionCall)node.Fun;
     // See if this is an identity function, which we do by checking: that the function has
     // exactly one argument and the function has been marked by the user with the attribute {:identity}
     bool claimsToBeIdentity = false;
     if (call.ArgumentCount == 1 && call.Func.CheckBooleanAttribute("identity", ref claimsToBeIdentity) && claimsToBeIdentity && node.Args[0].Type.Equals(node.Type)) {
       VisitExpr(node.Args[0]);
     }
   }
   return node;
 }
Пример #34
0
 public static void SetChild(this NAryExpr e, int number, Expr NewChild)
 {
     e.Args[number] = NewChild;
 }
Пример #35
0
 public override Expr VisitNAryExpr(NAryExpr node) {
   //Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<Expr>() != null);
   FunctionCall fn = node.Fun as FunctionCall;
   if (fn != null && cce.NonNull(fn.Func).NeverTrigger) {
     parent.Triggers = new Trigger(fn.Func.tok, false, new List<Expr> { node} , parent.Triggers);
   }
   return base.VisitNAryExpr(node);
 }
Пример #36
0
	void ArrayExpression(out Expr/*!*/ e) {
		Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x;
		Expr/*!*/ index0 = dummyExpr; Expr/*!*/ e1;
		bool store; bool bvExtract;
		List<Expr>/*!*/ allArgs = dummyExprSeq;
		
		AtomExpression(out e);
		while (la.kind == 18) {
			Get();
			x = t; allArgs = new List<Expr> ();
			allArgs.Add(e);
			store = false; bvExtract = false; 
			if (StartOf(15)) {
				if (StartOf(9)) {
					Expression(out index0);
					if (index0 is BvBounds)
					 bvExtract = true;
					else
					 allArgs.Add(index0);
					
					while (la.kind == 13) {
						Get();
						Expression(out e1);
						if (bvExtract || e1 is BvBounds)
						 this.SemErr("bitvectors only have one dimension");
						allArgs.Add(e1);
						
					}
					if (la.kind == 51) {
						Get();
						Expression(out e1);
						if (bvExtract || e1 is BvBounds)
						 this.SemErr("assignment to bitvectors is not possible");
						allArgs.Add(e1); store = true;
						
					}
				} else {
					Get();
					Expression(out e1);
					allArgs.Add(e1); store = true; 
				}
			}
			Expect(19);
			if (store)
			 e = new NAryExpr(x, new MapStore(x, allArgs.Count - 2), allArgs);
			else if (bvExtract)
			 e = new BvExtractExpr(x, e,
			                       ((BvBounds)index0).Upper.ToIntSafe,
			                       ((BvBounds)index0).Lower.ToIntSafe);
			else
			 e = new NAryExpr(x, new MapSelect(x, allArgs.Count - 1), allArgs);
			
		}
	}
Пример #37
0
            public override Expr VisitNAryExpr(NAryExpr node)
            {
                if (node.Fun is FunctionCall)
                {
                    var collector = new VariableCollector();
                    collector.Visit(node);

                    if(existentialExpr != null && existentialExpr.Dummies.Intersect(collector.usedVars).Any())
                        functionsUsed.Add(Tuple.Create((node.Fun as FunctionCall).Func, existentialExpr));
                    else
                        functionsUsed.Add(Tuple.Create<Function, ExistsExpr>((node.Fun as FunctionCall).Func, null));
                }

                return base.VisitNAryExpr(node);
            }
Пример #38
0
	void IfThenElseExpression(out Expr/*!*/ e) {
		Contract.Ensures(Contract.ValueAtReturn(out e) != null);
		IToken/*!*/ tok;
		Expr/*!*/ e0, e1, e2;
		e = dummyExpr; 
		Expect(41);
		tok = t; 
		Expression(out e0);
		Expect(88);
		Expression(out e1);
		Expect(42);
		Expression(out e2);
		e = new NAryExpr(tok, new IfThenElse(tok), new List<Expr>{ e0, e1, e2 }); 
	}
Пример #39
0
 public static Expr GetChild(this NAryExpr e, int number)
 {
     return(e.Args[number]);
 }
Пример #40
0
        public static Expr Extract(Expr expr, Program program, List <Axiom> axioms)
        {
            Contract.Requires(expr != null && program != null && !program.TopLevelDeclarationsAreFrozen && axioms != null);

            if (expr is LiteralExpr)
            {
                return(expr);
            }

            var extractor = new FunctionExtractor();

            var body = extractor.VisitExpr(expr);

            var name         = program.FreshExtractedFunctionName();
            var originalVars = extractor.Substitutions.Keys.ToList();
            var formalInArgs = originalVars.Select(v => new Formal(Token.NoToken,
                                                                   new TypedIdent(Token.NoToken, extractor.Substitutions[v].Name, extractor.Substitutions[v].TypedIdent.Type),
                                                                   true)).ToList <Variable>();
            var formalOutArg = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, name + "$result$", expr.Type), false);
            var func         = new Function(Token.NoToken, name, formalInArgs, formalOutArg);

            func.AddAttribute("never_pattern");

            var boundVars = originalVars.Select(k => extractor.Substitutions[k]);
            var axiomCall = new NAryExpr(Token.NoToken, new FunctionCall(func),
                                         boundVars.Select(b => new IdentifierExpr(Token.NoToken, b)).ToList <Expr>());

            axiomCall.Type           = expr.Type;
            axiomCall.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
            var eq = LiteralExpr.Eq(axiomCall, body);

            eq.Type           = body.Type;
            eq.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
            if (0 < formalInArgs.Count)
            {
                var forallExpr = new ForallExpr(Token.NoToken, boundVars.ToList <Variable>(),
                                                new Trigger(Token.NoToken, true, new List <Expr> {
                    axiomCall
                }), eq);
                body = forallExpr;
                forallExpr.Attributes = new QKeyValue(Token.NoToken, "weight",
                                                      new List <object> {
                    new LiteralExpr(Token.NoToken, BaseTypes.BigNum.FromInt(30))
                }, null);
                body.Type = Type.Bool;
            }
            else
            {
                body = eq;
            }

            var axiom = new Axiom(Token.NoToken, body);

            func.DefinitionAxiom = axiom;
            program.AddTopLevelDeclaration(func);
            program.AddTopLevelDeclaration(axiom);
            axioms.Add(axiom);

            var call = new NAryExpr(Token.NoToken, new FunctionCall(func),
                                    originalVars.Select(v => new IdentifierExpr(Token.NoToken, v)).ToList <Expr>());

            call.Type           = expr.Type;
            call.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
            return(call);
        }
Пример #41
0
	void AtomExpression(out Expr/*!*/ e) {
		Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; int n; BigNum bn; BigDec bd; BigFloat bf;
		List<Expr>/*!*/ es;  List<Variable>/*!*/ ds;  Trigger trig;
		List<TypeVariable>/*!*/ typeParams;
		IdentifierExpr/*!*/ id;
		QKeyValue kv;
		e = dummyExpr;
		List<Variable>/*!*/ locals;
		List<Block/*!*/>/*!*/ blocks;
		
		switch (la.kind) {
		case 83: {
			Get();
			e = new LiteralExpr(t, false); 
			break;
		}
		case 84: {
			Get();
			e = new LiteralExpr(t, true); 
			break;
		}
		case 3: {
			Nat(out bn);
			e = new LiteralExpr(t, bn); 
			break;
		}
		case 5: case 6: {
			Dec(out bd);
			e = new LiteralExpr(t, bd); 
			break;
		}
		case 7: {
			Float(out bf);
			e = new LiteralExpr(t, bf); 
			break;
		}
		case 2: {
			BvLit(out bn, out n);
			e = new LiteralExpr(t, bn, n); 
			break;
		}
		case 1: {
			Ident(out x);
			id = new IdentifierExpr(x, x.val);  e = id; 
			if (la.kind == 10) {
				Get();
				if (StartOf(9)) {
					Expressions(out es);
					e = new NAryExpr(x, new FunctionCall(id), es); 
				} else if (la.kind == 11) {
					e = new NAryExpr(x, new FunctionCall(id), new List<Expr>()); 
				} else SynErr(124);
				Expect(11);
			}
			break;
		}
		case 85: {
			Get();
			x = t; 
			Expect(10);
			Expression(out e);
			Expect(11);
			e = new OldExpr(x, e); 
			break;
		}
		case 15: {
			Get();
			x = t; 
			Expect(10);
			Expression(out e);
			Expect(11);
			e = new NAryExpr(x, new ArithmeticCoercion(x, ArithmeticCoercion.CoercionType.ToInt), new List<Expr>{ e }); 
			break;
		}
		case 16: {
			Get();
			x = t; 
			Expect(10);
			Expression(out e);
			Expect(11);
			e = new NAryExpr(x, new ArithmeticCoercion(x, ArithmeticCoercion.CoercionType.ToReal), new List<Expr>{ e }); 
			break;
		}
		case 10: {
			Get();
			if (StartOf(9)) {
				Expression(out e);
				if (e is BvBounds)
				 this.SemErr("parentheses around bitvector bounds " +
				        "are not allowed"); 
			} else if (la.kind == 89 || la.kind == 90) {
				Forall();
				x = t; 
				QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e);
				if (typeParams.Count + ds.Count > 0)
				 e = new ForallExpr(x, typeParams, ds, kv, trig, e); 
			} else if (la.kind == 91 || la.kind == 92) {
				Exists();
				x = t; 
				QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e);
				if (typeParams.Count + ds.Count > 0)
				 e = new ExistsExpr(x, typeParams, ds, kv, trig, e); 
			} else if (la.kind == 93 || la.kind == 94) {
				Lambda();
				x = t; 
				QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e);
				if (trig != null)
				 SemErr("triggers not allowed in lambda expressions");
				if (typeParams.Count + ds.Count > 0)
				 e = new LambdaExpr(x, typeParams, ds, kv, e); 
			} else SynErr(125);
			Expect(11);
			break;
		}
		case 41: {
			IfThenElseExpression(out e);
			break;
		}
		case 86: {
			CodeExpression(out locals, out blocks);
			e = new CodeExpr(locals, blocks); 
			break;
		}
		default: SynErr(126); break;
		}
	}
Пример #42
0
        public void Transform()
        {
            foreach (var decl in program.TopLevelDeclarations)
            {
                Implementation impl = decl as Implementation;
                if (impl == null)
                {
                    continue;
                }
                Dictionary <string, Variable> domainNameToInputVar = new Dictionary <string, Variable>();
                foreach (string domainName in linearDomains.Keys)
                {
                    var    domain = linearDomains[domainName];
                    Formal f      = new Formal(
                        Token.NoToken,
                        new TypedIdent(Token.NoToken,
                                       "linear_" + domainName + "_in",
                                       new MapType(Token.NoToken, new List <TypeVariable>(),
                                                   new List <Type> {
                        domain.elementType
                    }, Type.Bool)), true);
                    impl.InParams.Add(f);
                    domainNameToInputVar[domainName] = f;
                }

                foreach (Block b in impl.Blocks)
                {
                    List <Cmd> newCmds = new List <Cmd>();
                    for (int i = 0; i < b.Cmds.Count; i++)
                    {
                        Cmd cmd = b.Cmds[i];
                        newCmds.Add(cmd);
                        if (cmd is CallCmd)
                        {
                            CallCmd callCmd = cmd as CallCmd;
                            if (callCmd.IsAsync)
                            {
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    var domain = linearDomains[domainName];
                                    var expr   = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List <Expr> {
                                        Expr.False
                                    });
                                    expr.Resolve(new ResolutionContext(null));
                                    expr.Typecheck(new TypecheckingContext(null));
                                    callCmd.Ins.Add(expr);
                                }
                            }
                            else
                            {
                                Dictionary <string, Expr> domainNameToExpr = new Dictionary <string, Expr>();
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    domainNameToExpr[domainName] = new IdentifierExpr(Token.NoToken, domainNameToInputVar[domainName]);
                                }
                                foreach (Variable v in availableLinearVars[callCmd])
                                {
                                    var            domainName = FindDomainName(v);
                                    var            domain     = linearDomains[domainName];
                                    IdentifierExpr ie         = new IdentifierExpr(Token.NoToken, v);
                                    var            expr       = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapOrBool),
                                                                             new List <Expr> {
                                        v.TypedIdent.Type is MapType ? ie : Singleton(ie, domainName), domainNameToExpr[domainName]
                                    });
                                    expr.Resolve(new ResolutionContext(null));
                                    expr.Typecheck(new TypecheckingContext(null));
                                    domainNameToExpr[domainName] = expr;
                                }
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    callCmd.Ins.Add(domainNameToExpr[domainName]);
                                }
                            }
                        }
                        else if (cmd is ParCallCmd)
                        {
                            ParCallCmd parCallCmd = (ParCallCmd)cmd;
                            foreach (CallCmd callCmd in parCallCmd.CallCmds)
                            {
                                foreach (var domainName in linearDomains.Keys)
                                {
                                    var domain = linearDomains[domainName];
                                    var expr   = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List <Expr> {
                                        Expr.False
                                    });
                                    expr.Resolve(new ResolutionContext(null));
                                    expr.Typecheck(new TypecheckingContext(null));
                                    callCmd.Ins.Add(expr);
                                }
                            }
                        }
                        else if (cmd is YieldCmd)
                        {
                            AddDisjointnessExpr(newCmds, cmd, domainNameToInputVar);
                        }
                    }
                    b.Cmds = newCmds;
                }

                {
                    // Loops
                    impl.PruneUnreachableBlocks();
                    impl.ComputePredecessorsForBlocks();
                    GraphUtil.Graph <Block> g = Program.GraphFromImpl(impl);
                    g.ComputeLoops();
                    if (g.Reducible)
                    {
                        foreach (Block header in g.Headers)
                        {
                            List <Cmd> newCmds = new List <Cmd>();
                            AddDisjointnessExpr(newCmds, header, domainNameToInputVar);
                            newCmds.AddRange(header.Cmds);
                            header.Cmds = newCmds;
                        }
                    }
                }
            }

            foreach (var decl in program.TopLevelDeclarations)
            {
                Procedure proc = decl as Procedure;
                if (proc == null)
                {
                    continue;
                }

                Dictionary <string, HashSet <Variable> > domainNameToInputScope  = new Dictionary <string, HashSet <Variable> >();
                Dictionary <string, HashSet <Variable> > domainNameToOutputScope = new Dictionary <string, HashSet <Variable> >();
                foreach (var domainName in linearDomains.Keys)
                {
                    domainNameToInputScope[domainName]  = new HashSet <Variable>();
                    domainNameToOutputScope[domainName] = new HashSet <Variable>();
                }
                foreach (Variable v in globalVarToDomainName.Keys)
                {
                    var domainName = globalVarToDomainName[v];
                    domainNameToInputScope[domainName].Add(v);
                    domainNameToOutputScope[domainName].Add(v);
                }
                foreach (Variable v in proc.InParams)
                {
                    var domainName = FindDomainName(v);
                    if (domainName == null)
                    {
                        continue;
                    }
                    domainNameToInputScope[domainName].Add(v);
                }
                foreach (Variable v in proc.OutParams)
                {
                    var domainName = FindDomainName(v);
                    if (domainName == null)
                    {
                        continue;
                    }
                    domainNameToOutputScope[domainName].Add(v);
                }
                foreach (var domainName in linearDomains.Keys)
                {
                    proc.Requires.Add(new Requires(true, DisjointnessExpr(domainName, domainNameToInputScope[domainName])));
                    var    domain = linearDomains[domainName];
                    Formal f      = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "linear_" + domainName + "_in", new MapType(Token.NoToken, new List <TypeVariable>(), new List <Type> {
                        domain.elementType
                    }, Type.Bool)), true);
                    proc.InParams.Add(f);
                    domainNameToOutputScope[domainName].Add(f);
                    proc.Ensures.Add(new Ensures(true, DisjointnessExpr(domainName, domainNameToOutputScope[domainName])));
                }
            }

            foreach (LinearDomain domain in linearDomains.Values)
            {
                program.TopLevelDeclarations.Add(domain.mapConstBool);
                program.TopLevelDeclarations.Add(domain.mapConstInt);
                program.TopLevelDeclarations.Add(domain.mapEqInt);
                program.TopLevelDeclarations.Add(domain.mapImpBool);
                program.TopLevelDeclarations.Add(domain.mapOrBool);
                foreach (Axiom axiom in domain.axioms)
                {
                    program.TopLevelDeclarations.Add(axiom);
                }
            }

            //int oldPrintUnstructured = CommandLineOptions.Clo.PrintUnstructured;
            //CommandLineOptions.Clo.PrintUnstructured = 1;
            //PrintBplFile("lsd.bpl", program, false, false);
            //CommandLineOptions.Clo.PrintUnstructured = oldPrintUnstructured;
        }
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            var funCall = node.Fun as FunctionCall;
              if (funCall != null)
              {
            var visited = dependencies.Contains(funCall.Func);
            if (!visited)
            {
              funCall.Func = VisitFunction(funCall.Func);
            }
              }

              return base.VisitNAryExpr(node);
        }
Пример #44
0
        public LinearDomain(Program program, string domainName, Type elementType)
        {
            this.elementType = elementType;
            this.axioms      = new List <Axiom>();

            MapType mapTypeBool = new MapType(Token.NoToken, new List <TypeVariable>(), new List <Type> {
                this.elementType
            }, Type.Bool);
            MapType mapTypeInt = new MapType(Token.NoToken, new List <TypeVariable>(), new List <Type> {
                this.elementType
            }, Type.Int);

            this.mapOrBool = new Function(Token.NoToken, "linear_" + domainName + "_MapOr",
                                          new List <Variable> {
                new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true),
                new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true)
            },
                                          new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false));
            if (CommandLineOptions.Clo.UseArrayTheory)
            {
                this.mapOrBool.AddAttribute("builtin", "MapOr");
            }
            else
            {
                BoundVariable  a           = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool));
                IdentifierExpr aie         = new IdentifierExpr(Token.NoToken, a);
                BoundVariable  b           = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool));
                IdentifierExpr bie         = new IdentifierExpr(Token.NoToken, b);
                BoundVariable  x           = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType));
                IdentifierExpr xie         = new IdentifierExpr(Token.NoToken, x);
                var            mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapOrBool), new List <Expr> {
                    aie, bie
                });
                var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                    mapApplTerm, xie
                });
                var rhsTerm = Expr.Binary(BinaryOperator.Opcode.Or,
                                          new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                    aie, xie
                }),
                                          new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                    bie, xie
                }));
                var axiomExpr = new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> {
                    a, b
                }, null,
                                               new Trigger(Token.NoToken, true, new List <Expr> {
                    mapApplTerm
                }),
                                               new ForallExpr(Token.NoToken, new List <Variable> {
                    x
                }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm)));
                axiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, axiomExpr));
            }

            this.mapImpBool = new Function(Token.NoToken, "linear_" + domainName + "_MapImp",
                                           new List <Variable> {
                new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true),
                new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true)
            },
                                           new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false));
            if (CommandLineOptions.Clo.UseArrayTheory)
            {
                this.mapImpBool.AddAttribute("builtin", "MapImp");
            }
            else
            {
                BoundVariable  a           = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool));
                IdentifierExpr aie         = new IdentifierExpr(Token.NoToken, a);
                BoundVariable  b           = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool));
                IdentifierExpr bie         = new IdentifierExpr(Token.NoToken, b);
                BoundVariable  x           = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType));
                IdentifierExpr xie         = new IdentifierExpr(Token.NoToken, x);
                var            mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapImpBool), new List <Expr> {
                    aie, bie
                });
                var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                    mapApplTerm, xie
                });
                var rhsTerm = Expr.Binary(BinaryOperator.Opcode.Imp,
                                          new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                    aie, xie
                }),
                                          new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                    bie, xie
                }));
                var axiomExpr = new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> {
                    a, b
                }, null,
                                               new Trigger(Token.NoToken, true, new List <Expr> {
                    mapApplTerm
                }),
                                               new ForallExpr(Token.NoToken, new List <Variable> {
                    x
                }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm)));
                axiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, axiomExpr));
            }

            this.mapConstBool = new Function(Token.NoToken, "linear_" + domainName + "_MapConstBool",
                                             new List <Variable> {
                new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Bool), true)
            },
                                             new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false));
            if (CommandLineOptions.Clo.UseArrayTheory)
            {
                this.mapConstBool.AddAttribute("builtin", "MapConst");
            }
            else
            {
                BoundVariable  x        = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType));
                IdentifierExpr xie      = new IdentifierExpr(Token.NoToken, x);
                var            trueTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1),
                                                       new List <Expr> {
                    new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List <Expr> {
                        Expr.True
                    }), xie
                });
                var trueAxiomExpr = new ForallExpr(Token.NoToken, new List <Variable> {
                    x
                }, trueTerm);
                trueAxiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, trueAxiomExpr));
                var falseTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1),
                                             new List <Expr> {
                    new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List <Expr> {
                        Expr.False
                    }), xie
                });
                var falseAxiomExpr = new ForallExpr(Token.NoToken, new List <Variable> {
                    x
                }, Expr.Unary(Token.NoToken, UnaryOperator.Opcode.Not, falseTerm));
                falseAxiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, falseAxiomExpr));
            }

            this.mapEqInt = new Function(Token.NoToken, "linear_" + domainName + "_MapEq",
                                         new List <Variable> {
                new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt), true),
                new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt), true)
            },
                                         new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false));
            if (CommandLineOptions.Clo.UseArrayTheory)
            {
                this.mapEqInt.AddAttribute("builtin", "MapEq");
            }
            else
            {
                BoundVariable  a           = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt));
                IdentifierExpr aie         = new IdentifierExpr(Token.NoToken, a);
                BoundVariable  b           = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt));
                IdentifierExpr bie         = new IdentifierExpr(Token.NoToken, b);
                BoundVariable  x           = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType));
                IdentifierExpr xie         = new IdentifierExpr(Token.NoToken, x);
                var            mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapEqInt), new List <Expr> {
                    aie, bie
                });
                var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                    mapApplTerm, xie
                });
                var rhsTerm = Expr.Binary(BinaryOperator.Opcode.Eq,
                                          new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                    aie, xie
                }),
                                          new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                    bie, xie
                }));
                var axiomExpr = new ForallExpr(Token.NoToken, new List <TypeVariable>(), new List <Variable> {
                    a, b
                }, null,
                                               new Trigger(Token.NoToken, true, new List <Expr> {
                    mapApplTerm
                }),
                                               new ForallExpr(Token.NoToken, new List <Variable> {
                    x
                }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm)));
                axiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, axiomExpr));
            }

            this.mapConstInt = new Function(Token.NoToken, "linear_" + domainName + "_MapConstInt",
                                            new List <Variable> {
                new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Int), true)
            },
                                            new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeInt), false));
            if (CommandLineOptions.Clo.UseArrayTheory)
            {
                this.mapConstInt.AddAttribute("builtin", "MapConst");
            }
            else
            {
                BoundVariable  a       = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", Type.Int));
                IdentifierExpr aie     = new IdentifierExpr(Token.NoToken, a);
                BoundVariable  x       = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType));
                IdentifierExpr xie     = new IdentifierExpr(Token.NoToken, x);
                var            lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                    new NAryExpr(Token.NoToken, new FunctionCall(mapConstInt), new List <Expr> {
                        aie
                    }), xie
                });
                var axiomExpr = new ForallExpr(Token.NoToken, new List <Variable> {
                    a, x
                }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, aie));
                axiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, axiomExpr));
            }

            foreach (var axiom in axioms)
            {
                axiom.Expr.Resolve(new ResolutionContext(null));
                axiom.Expr.Typecheck(new TypecheckingContext(null));
            }
        }
Пример #45
0
 public override Expr VisitNAryExpr(NAryExpr node)
 {
     Contract.Ensures(Contract.Result<Expr>() == node);
     this.VisitExprSeq(node.Args);
     return node;
 }
Пример #46
0
        public void GenerateVCsForStratifiedInlining()
        {
            Contract.Requires(program != null);
            foreach (Declaration decl in program.TopLevelDeclarations)
            {
                Contract.Assert(decl != null);
                Implementation impl = decl as Implementation;
                if (impl == null)
                    continue;
                Contract.Assert(!impl.Name.StartsWith(recordProcName), "Not allowed to have an implementation for this guy");

                Procedure proc = cce.NonNull(impl.Proc);

                {
                    StratifiedInliningInfo info = new StratifiedInliningInfo(impl, program, boogieContext, QuantifierExpr.GetNextSkolemId());
                    implName2StratifiedInliningInfo[impl.Name] = info;
                    // We don't need controlFlowVariable for stratified Inlining
                    //impl.LocVars.Add(info.controlFlowVariable);
                    List<Expr> exprs = new List<Expr>();

                    if (mode != Mode.Boogie && QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint"))
                    {
                        proc.Ensures.Add(new Ensures(Token.NoToken, true, Microsoft.Boogie.Expr.False, "", null));
                        info.assertExpr = Microsoft.Boogie.Expr.False;
                        // info.isMain = true;
                    }
                    else if (mode == Mode.Corral || proc.FindExprAttribute("inline") != null || proc is LoopProcedure)
                    {
                        foreach (Variable v in program.GlobalVariables())
                        {
                            Contract.Assert(v != null);
                            exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
                        }
                        foreach (Variable v in proc.InParams)
                        {
                            Contract.Assert(v != null);
                            exprs.Add(new IdentifierExpr(Token.NoToken, v));
                        }
                        foreach (Variable v in proc.OutParams)
                        {
                            Contract.Assert(v != null);
                            exprs.Add(new IdentifierExpr(Token.NoToken, v));
                        }
                        foreach (IdentifierExpr ie in proc.Modifies)
                        {
                            Contract.Assert(ie != null);
                            if (ie.Decl == null)
                                continue;
                            exprs.Add(ie);
                        }
                        Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(info.function), exprs);
            #if true
                        if(mode == Mode.Corral || mode == Mode.OldCorral)
                            proc.Ensures.Add(new Ensures(Token.NoToken, true, freePostExpr, "", new QKeyValue(Token.NoToken, "si_fcall", new List<object>(), null)));
            #endif
                    }
                    else // not marked "inline" must be main
                    {
                        Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(info.function), exprs);
                        info.isMain = true;
                    }
                }
            }

            if (mode == Mode.Boogie) return;

            foreach (var decl in program.TopLevelDeclarations)
            {
                var proc = decl as Procedure;
                if (proc == null) continue;
                if (!proc.Name.StartsWith(recordProcName)) continue;
                Contract.Assert(proc.InParams.Count == 1);

                // Make a new function
                TypedIdent ti = new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool);
                Contract.Assert(ti != null);
                Formal returnVar = new Formal(Token.NoToken, ti, false);
                Contract.Assert(returnVar != null);

                // Get record type
                var argtype = proc.InParams[0].TypedIdent.Type;

                var ins = new List<Variable>();
                ins.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "x", argtype), true));

                var recordFunc = new Function(Token.NoToken, proc.Name, ins, returnVar);
                boogieContext.DeclareFunction(recordFunc, "");

                var exprs = new List<Expr>();
                exprs.Add(new IdentifierExpr(Token.NoToken, proc.InParams[0]));

                Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(recordFunc), exprs);
                proc.Ensures.Add(new Ensures(true, freePostExpr));
            }
        }
Пример #47
0
    public static Expr Extract(Expr expr, Program program, List<Axiom> axioms)
    {
      Contract.Requires(expr != null && program != null && !program.TopLevelDeclarationsAreFrozen && axioms != null);
      
      if (expr is LiteralExpr)
      {
        return expr;
      }

      var extractor = new FunctionExtractor();

      var body = extractor.VisitExpr(expr);

      var name = program.FreshExtractedFunctionName();
      var originalVars = extractor.Substitutions.Keys.ToList();
      var formalInArgs = originalVars.Select(v => new Formal(Token.NoToken, new TypedIdent(Token.NoToken, extractor.Substitutions[v].Name, extractor.Substitutions[v].TypedIdent.Type), true)).ToList<Variable>();
      var formalOutArg = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, name + "$result$", expr.Type), false);
      var func = new Function(Token.NoToken, name, formalInArgs, formalOutArg);
      func.AddAttribute("never_pattern");

      var boundVars = originalVars.Select(k => extractor.Substitutions[k]);
      var axiomCall = new NAryExpr(Token.NoToken, new FunctionCall(func), boundVars.Select(b => new IdentifierExpr(Token.NoToken, b)).ToList<Expr>());
      axiomCall.Type = expr.Type;
      axiomCall.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
      var eq = LiteralExpr.Eq(axiomCall, body);
      eq.Type = body.Type;
      eq.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
      if (0 < formalInArgs.Count)
      {
        var forallExpr = new ForallExpr(Token.NoToken, boundVars.ToList<Variable>(), new Trigger(Token.NoToken, true, new List<Expr> { axiomCall }), eq);
        body = forallExpr;
        forallExpr.Attributes = new QKeyValue(Token.NoToken, "weight", new List<object> { new LiteralExpr(Token.NoToken, Basetypes.BigNum.FromInt(30)) }, null);
        body.Type = Type.Bool;
      }
      else
      {
        body = eq;
      }

      var axiom = new Axiom(Token.NoToken, body);
      func.DefinitionAxiom = axiom;
      program.AddTopLevelDeclaration(func);
      program.AddTopLevelDeclaration(axiom);
      axioms.Add(axiom);

      var call = new NAryExpr(Token.NoToken, new FunctionCall(func), originalVars.Select(v => new IdentifierExpr(Token.NoToken, v)).ToList<Expr>());
      call.Type = expr.Type;
      call.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
      return call;
    }
Пример #48
0
        private void AnnotateBlock(Implementation impl, ProverContext ctxt, Block header)
        {
            Contract.Assert(header != null);

            string name = impl.Name + "_" + header.Label + "_invar";
            if (annotationInfo.ContainsKey(name))
                return;

            // collect the variables needed in the invariant
            List<Expr> exprs = new List<Expr>();
            List<Variable> vars = new List<Variable>();
            List<string> names = new List<string>();

            if (style == AnnotationStyle.Flat)
            {
                // in flat mode, all live globals should be in live set
            #if false
                foreach (Variable v in program.GlobalVariables())
                {
                    vars.Add(v);
                    names.Add(v.ToString());
                    exprs.Add(new IdentifierExpr(Token.NoToken, v));
                }
            #endif
                foreach (Variable v in /* impl.LocVars */ header.liveVarsBefore)
                {
                    if (!(v is BoundVariable))
                    {
                        vars.Add(v);
                        names.Add(v.ToString());
                        exprs.Add(new IdentifierExpr(Token.NoToken, v));
                    }
                }
            }
            else
            {
                foreach (Variable v in program.GlobalVariables())
                {
                    vars.Add(v);
                    names.Add("@old_" + v.ToString());
                    exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
                }
                foreach (IdentifierExpr ie in impl.Proc.Modifies)
                {
                    if (ie.Decl == null)
                        continue;
                    vars.Add(ie.Decl);
                    names.Add(ie.Decl.ToString());
                    exprs.Add(ie);
                }
                foreach (Variable v in impl.Proc.InParams)
                {
                    Contract.Assert(v != null);
                    vars.Add(v);
                    names.Add("@old_" + v.ToString());
                    exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
                }
                foreach (Variable v in impl.LocVars)
                {
                    vars.Add(v);
                    names.Add(v.ToString());
                    exprs.Add(new IdentifierExpr(Token.NoToken, v));
                }
            }

            TypedIdent ti = new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool);
            Contract.Assert(ti != null);
            Formal returnVar = new Formal(Token.NoToken, ti, false);
            Contract.Assert(returnVar != null);
            var function = new Function(Token.NoToken, name, vars, returnVar);
            ctxt.DeclareFunction(function, "");

            Expr invarExpr = new NAryExpr(Token.NoToken, new FunctionCall(function), exprs);
            var invarAssertion = new AssertCmd(Token.NoToken, invarExpr);
            List<Cmd> newCmds = new List<Cmd>();
            newCmds.Add(invarAssertion);

            // make a record in annotationInfo;
            var info = new AnnotationInfo();
            info.filename = header.tok.filename;
            info.lineno = header.Line;
            info.argnames = names.ToArray();
            info.type = AnnotationInfo.AnnotationType.LoopInvariant;
            annotationInfo.Add(name, info);
            // get file and line info from havoc, if there is...
            if (header.Cmds.Count > 0)
            {
                PredicateCmd bif = header.Cmds[0] as PredicateCmd;
                if (bif != null)
                {
                    string foo = QKeyValue.FindStringAttribute(bif.Attributes, "sourcefile");
                    if (foo != null)
                        info.filename = foo;
                    int bar = QKeyValue.FindIntAttribute(bif.Attributes, "sourceline", -1);
                    if (bar != -1)
                        info.lineno = bar;
                }
            }
            var thing = header;
            foreach (Cmd c in header.Cmds)
            {
                newCmds.Add(c);
            }
            header.Cmds = newCmds;
        }
Пример #49
0
    public override Expr VisitNAryExpr(NAryExpr node)
    {
      var funCall = node.Fun as FunctionCall;
      if (funCall != null)
      {
        if (currentDeclaration != null)
        {
          currentDeclaration.AddFunctionDependency(funCall.Func);
        }
        if (currentAxiom != null)
        {
          currentAxiom.AddFunctionDependency(funCall.Func);
        }
      }

      return base.VisitNAryExpr(node);
    }
Пример #50
0
        /// <summary>
        /// Compute $pa(p, i, s) == p + i * s);
        /// </summary>
        /// <returns>The root pointer.</returns>
        /// <param name="impl">Implementation</param>
        /// <param name="label">Root block label</param>
        /// <param name="id">Identifier expression</param>
        public static Expr ComputeRootPointer(Implementation impl, string label, Expr id)
        {
            if (id is LiteralExpr)
            {
                return(id);
            }
            if (id is NAryExpr && (id as NAryExpr).Args.Count == 1 &&
                (id as NAryExpr).Fun.FunctionName.Equals("-"))
            {
                return(id);
            }

            NAryExpr root = PointerArithmeticAnalyser.GetPointerArithmeticExpr(impl, id) as NAryExpr;

            if (root == null)
            {
                return(id);
            }

            Expr result     = root;
            Expr resolution = result;
            int  ixs        = 0;

            var alreadyVisited = new HashSet <Tuple <string, Expr> >();

            do
            {
                if (result is NAryExpr)
                {
                    if (((result as NAryExpr).Args[0] is IdentifierExpr) &&
                        ((result as NAryExpr).Args[0] as IdentifierExpr).Name.StartsWith("$M."))
                    {
                        return(id);
                    }

                    if (PointerArithmeticAnalyser.TryPerformCast(ref result))
                    {
                        continue;
                    }

                    if (PointerArithmeticAnalyser.ShouldSkipFromAnalysis(result as NAryExpr))
                    {
                        return(id);
                    }

                    if (alreadyVisited.Any(v => v.Item1.Equals(label) && v.Item2.Equals(result)))
                    {
                        return(id);
                    }

                    alreadyVisited.Add(new Tuple <string, Expr>(label, result));

                    if (PointerArithmeticAnalyser.IsArithmeticExpression(result as NAryExpr))
                    {
                        return(id);
                    }

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

                    if ((i is LiteralExpr) && (s is LiteralExpr))
                    {
                        ixs += (i as LiteralExpr).asBigNum.ToInt * (s as LiteralExpr).asBigNum.ToInt;
                    }
                    else
                    {
                        return(id);
                    }

                    result = p;
                }
                else
                {
                    resolution = PointerArithmeticAnalyser.GetPointerArithmeticExpr(impl, result);
                    if (resolution != null)
                    {
                        result = resolution;
                    }
                }
            }while (resolution != null);

            return(Expr.Add(result, new LiteralExpr(Token.NoToken, BigNum.FromInt(ixs))));
        }
Пример #51
0
 private Expr SubsetExpr(LinearDomain domain, Expr ie, Variable partition, int partitionCount)
 {
     Expr e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstInt), new List<Expr> { new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(partitionCount)) });
     e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapEqInt), new List<Expr> { Expr.Ident(partition), e });
     e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapImpBool), new List<Expr> { ie, e });
     e = Expr.Eq(e, new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List<Expr> { Expr.True }));
     return e;
 }
Пример #52
0
 public override Expr VisitNAryExpr(NAryExpr node)
 {
     add(node);
     return(base.VisitNAryExpr(node));
 }
Пример #53
0
        public LinearDomain(Program program, string domainName, Dictionary<Type, Function> collectors)
        {
            this.axioms = new List<Axiom>();
            this.collectors = collectors;
            MapType setType = (MapType)collectors.First().Value.OutParams[0].TypedIdent.Type;
            this.elementType = setType.Arguments[0];
            MapType mapTypeBool = new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { this.elementType }, Type.Bool);
            MapType mapTypeInt = new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { this.elementType }, Type.Int);
            this.mapOrBool = new Function(Token.NoToken, "linear_" + domainName + "_MapOr",
                                          new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true),
                                                          new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true) },
                                          new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false));
            if (CommandLineOptions.Clo.UseArrayTheory)
            {
                this.mapOrBool.AddAttribute("builtin", "MapOr");
            }
            else
            {
                BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool));
                IdentifierExpr aie = Expr.Ident(a);
                BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool));
                IdentifierExpr bie = Expr.Ident(b);
                BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType));
                IdentifierExpr xie = Expr.Ident(x);
                var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapOrBool), new List<Expr> { aie, bie } );
                var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { mapApplTerm, xie } );
                var rhsTerm = Expr.Or(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { aie, xie } ),
                                      new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { bie, xie} ));
                var axiomExpr = new ForallExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable> { a, b }, null, 
                                               new Trigger(Token.NoToken, true, new List<Expr> { mapApplTerm }), 
                                               new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm)));
                axiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, axiomExpr));
            }

            this.mapImpBool = new Function(Token.NoToken, "linear_" + domainName + "_MapImp",
                                              new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true),
                                                              new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true) },
                                              new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false));
            if (CommandLineOptions.Clo.UseArrayTheory)
            {
                this.mapImpBool.AddAttribute("builtin", "MapImp");
            }
            else
            {
                BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool));
                IdentifierExpr aie = Expr.Ident(a);
                BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool));
                IdentifierExpr bie = Expr.Ident(b);
                BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType));
                IdentifierExpr xie = Expr.Ident(x);
                var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapImpBool), new List<Expr> { aie, bie });
                var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { mapApplTerm, xie });
                var rhsTerm = Expr.Imp(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { aie, xie }),
                                       new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { bie, xie }));
                var axiomExpr = new ForallExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable> { a, b }, null,
                                               new Trigger(Token.NoToken, true, new List<Expr> { mapApplTerm }), 
                                               new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm)));
                axiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, axiomExpr));
            }

            this.mapConstBool = new Function(Token.NoToken, "linear_" + domainName + "_MapConstBool",
                                              new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Bool), true) },
                                              new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false));
            if (CommandLineOptions.Clo.UseArrayTheory)
            {
                this.mapConstBool.AddAttribute("builtin", "MapConst");
            }
            else
            {
                BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType));
                IdentifierExpr xie = Expr.Ident(x);
                var trueTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), 
                                           new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List<Expr> { Expr.True }), xie });
                var trueAxiomExpr = new ForallExpr(Token.NoToken, new List<Variable> { x }, trueTerm);
                trueAxiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, trueAxiomExpr));
                var falseTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1),
                                           new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List<Expr> { Expr.False }), xie }); 
                var falseAxiomExpr = new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Unary(Token.NoToken, UnaryOperator.Opcode.Not, falseTerm));
                falseAxiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, falseAxiomExpr));
            }

            this.mapEqInt = new Function(Token.NoToken, "linear_" + domainName + "_MapEq",
                                              new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt), true),
                                                              new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt), true) },
                                              new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false));
            if (CommandLineOptions.Clo.UseArrayTheory)
            {
                this.mapEqInt.AddAttribute("builtin", "MapEq");
            }
            else
            {
                BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt));
                IdentifierExpr aie = Expr.Ident(a);
                BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt));
                IdentifierExpr bie = Expr.Ident(b);
                BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType));
                IdentifierExpr xie = Expr.Ident(x);
                var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapEqInt), new List<Expr> { aie, bie });
                var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { mapApplTerm, xie });
                var rhsTerm = Expr.Eq(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { aie, xie }),
                                      new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { bie, xie }));
                var axiomExpr = new ForallExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable> { a, b }, null, 
                                               new Trigger(Token.NoToken, true, new List<Expr> { mapApplTerm }), 
                                               new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm)));
                axiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, axiomExpr));
            }

            this.mapConstInt = new Function(Token.NoToken, "linear_" + domainName + "_MapConstInt",
                                          new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Int), true) },
                                          new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeInt), false));
            if (CommandLineOptions.Clo.UseArrayTheory)
            {
                this.mapConstInt.AddAttribute("builtin", "MapConst");
            }
            else
            {
                BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", Type.Int));
                IdentifierExpr aie = Expr.Ident(a);
                BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType));
                IdentifierExpr xie = Expr.Ident(x);
                var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstInt), new List<Expr> { aie }), xie });
                var axiomExpr = new ForallExpr(Token.NoToken, new List<Variable> { a, x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, aie));
                axiomExpr.Typecheck(new TypecheckingContext(null));
                axioms.Add(new Axiom(Token.NoToken, axiomExpr));
            }

            foreach (var axiom in axioms)
            {
                axiom.Expr.Resolve(new ResolutionContext(null));
                axiom.Expr.Typecheck(new TypecheckingContext(null));
            }
        }
Пример #54
0
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            //start with some negative cases
            if (!Matches ||
                _toConsume.Count == 0)
            {
                Matches = false;
                return(base.VisitNAryExpr(node));
            }

            //idea: if in anyExprMode, toConsume does not change --> we eat up any NaryExpr
            // if any of the  arguments matches, the whole thing matches
            // nothing fancier now, because we only need IdentifierExpr and LiteralExpr
            if (_anyExprMode)
            {
                var anyMatches = false;
                var dispatched = new List <Expr>();
                foreach (var a in node.Args)
                {
                    Matches = true;
                    dispatched.Add(VisitExpr(a));
                    anyMatches |= Matches;
                }
                Matches = anyMatches;
                return(new NAryExpr(node.tok, node.Fun, dispatched));
            }

            // check if we need to switch to anyExprMode
            if (_toConsume.Peek() is NAryExpr &&
                (((NAryExpr)_toConsume.Peek()).Fun) is FunctionCall &&
                ((FunctionCall)((NAryExpr)_toConsume.Peek()).Fun).Func != null &&
                BoogieUtil.checkAttrExists(BoogieKeyWords.AnyExpr, ((FunctionCall)((NAryExpr)_toConsume.Peek()).Fun).Func.Attributes))
            {
                _anyExprMode = true;

                _toConsume.Pop();
                ((NAryExpr)_toConsume.Peek()).Args.Reverse().Iter(arg => _toConsume.Push(arg));
                var result = VisitNAryExpr(node);

                _anyExprMode = false;

                return(result);
            }

            if (!(_toConsume.Peek() is NAryExpr))
            {
                //may still be an IdentifierExp intended to match any exp
                if (_toConsume.First() is IdentifierExpr &&
                    ((IdentifierExpr)_toConsume.Peek()).Decl != null &&
                    !BoogieUtil.checkAttrExists(BoogieKeyWords.IdExpr, ((IdentifierExpr)_toConsume.Peek()).Decl.Attributes))
                {
                    Substitution.Add(((IdentifierExpr)_toConsume.Peek()).Decl, node);
                    _toConsume.Pop();
                    return(node);
                }
                Matches = false;
                return(base.VisitNAryExpr(node));
            }

            var naeToConsume = (NAryExpr)_toConsume.Peek();

            if (((NAryExpr)_toConsume.Peek()).Args.Count != node.Args.Count)
            {
                Matches = false;
                return(base.VisitNAryExpr(node));
            }

            // now the positive cases

            // the same function is used
            if (naeToConsume.Fun.FunctionName == node.Fun.FunctionName)
            {
                _toConsume.Pop();
                naeToConsume.Args.Reverse().Iter(arg => _toConsume.Push(arg));
                return(base.VisitNAryExpr(node));
            }
            // the function in toConsume has a declaration in TemplateVariables
            if (naeToConsume.Fun is FunctionCall &&
                ((FunctionCall)naeToConsume.Fun).Func != null &&
                naeToConsume.Fun.ArgumentCount == node.Fun.ArgumentCount &&
                ((FunctionCall)naeToConsume.Fun).Func.InParams.Count == ((FunctionCall)node.Fun).Func.InParams.Count &&
                ((FunctionCall)naeToConsume.Fun).Func.OutParams.Count == ((FunctionCall)node.Fun).Func.OutParams.Count &&
                node.Fun is FunctionCall &&
                AreAttributesASubset(
                    ((FunctionCall)naeToConsume.Fun).Func.Attributes,
                    ((FunctionCall)node.Fun).Func.Attributes))
            {
                // do the argument types match?
                var tcFunc   = ((FunctionCall)naeToConsume.Fun).Func;
                var nodeFunc = ((FunctionCall)node.Fun).Func;
                for (var i = 0; i < tcFunc.InParams.Count; i++)
                {
                    if (!Equals(tcFunc.InParams[i].TypedIdent.Type, nodeFunc.InParams[i].TypedIdent.Type))
                    {
                        Matches = false;
                        return(base.VisitNAryExpr(node));
                    }
                }
                for (var i = 0; i < tcFunc.OutParams.Count; i++)
                {
                    if (!Equals(tcFunc.OutParams[i].TypedIdent.Type, nodeFunc.OutParams[i].TypedIdent.Type))
                    {
                        Matches = false;
                        return(base.VisitNAryExpr(node));
                    }
                }


                FunctionSubstitution.Add(naeToConsume.Fun.FunctionName, node.Fun);

                _toConsume.Pop();
                naeToConsume.Args.Reverse().Iter(arg => _toConsume.Push(arg));
                return(base.VisitNAryExpr(node));
            }
            Matches = false;
            return(base.VisitNAryExpr(node));
        }
Пример #55
0
 private Dictionary<string, Expr> ComputeAvailableExprs(IEnumerable<Variable> availableLinearVars, Dictionary<string, Variable> domainNameToInputVar)
 {
     Dictionary<string, Expr> domainNameToExpr = new Dictionary<string, Expr>();
     foreach (var domainName in linearTypeChecker.linearDomains.Keys)
     {
         var expr = Expr.Ident(domainNameToInputVar[domainName]);
         expr.Resolve(new ResolutionContext(null));
         expr.Typecheck(new TypecheckingContext(null));
         domainNameToExpr[domainName] = expr;
     }
     foreach (Variable v in availableLinearVars)
     {
         var domainName = linearTypeChecker.FindDomainName(v);
         if (!linearTypeChecker.linearDomains.ContainsKey(domainName)) continue;
         var domain = linearTypeChecker.linearDomains[domainName];
         if (!domain.collectors.ContainsKey(v.TypedIdent.Type)) continue;
         Expr ie = new NAryExpr(Token.NoToken, new FunctionCall(domain.collectors[v.TypedIdent.Type]), new List<Expr> { Expr.Ident(v) });
         var expr = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapOrBool), new List<Expr> { ie, domainNameToExpr[domainName] });
         expr.Resolve(new ResolutionContext(null));
         expr.Typecheck(new TypecheckingContext(null));
         domainNameToExpr[domainName] = expr;
     }
     return domainNameToExpr;
 }
Пример #56
0
 public override Expr VisitNAryExpr(NAryExpr node)
 {
     funcsUsed.Add(node.Fun.FunctionName);
     return(base.VisitNAryExpr(node));
 }
Пример #57
0
 public void CachedHashCodeNAryExpr()
 {
     var nary = new NAryExpr(Token.NoToken, new UnaryOperator(Token.NoToken, UnaryOperator.Opcode.Not), new List<Expr>() { Expr.True }, /*immutable=*/true);
     Assert.AreEqual(nary.ComputeHashCode(), nary.GetHashCode());
 }
Пример #58
0
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            // Try to do direct map indexing
            // FIXME: If there are nested mapselects but they don't end on a variable
            // then we'll do a lot of unnecessary work every time we traverse into a map select down.
            var asMapSelect = ExprUtil.AsMapSelect(node);

            if (asMapSelect != null)
            {
                // Gather the indices. They will be backwards as we traversing top down so have to
                // reverse at the end.
                //
                // Here's an example showing this:
                //
                // var m:[int][int]bool;
                // y:= m[0][1]
                //
                // The indicies we want are [0][1], but when traverse we will visit them backwards as
                // we start at the root of the expression tree.
                //
                // The structure of this is
                //
                //            mapselect
                //            /        \
                //    mapselect        1
                //    /      \
                //  m        0
                var  indices  = new List <Expr>();
                Expr firstArg = null;
                do
                {
                    // Traverse multi-arity arguments in reverse because later on we reverse them.
                    for (int index = asMapSelect.Args.Count - 1; index >= 1; --index)
                    {
                        // Don't do index variable mapping here because we might
                        // need to throw away what we've done
                        indices.Add(asMapSelect.Args[index]);
                    }
                    firstArg    = asMapSelect.Args[0];
                    asMapSelect = ExprUtil.AsMapSelect(firstArg);
                } while (asMapSelect != null);

                // Hopefully a map variable we can write to
                var asId = ExprUtil.AsIdentifer(firstArg);

                if (asId != null && asId.Decl.TypedIdent.Type.IsMap)
                {
                    // Do a remapping if necessary
                    // FIXME: This sucks. Fix boogie instead!
                    Variable V = null;
                    if (preReplacementReMap.ContainsKey(asId.Decl))
                    {
                        V = preReplacementReMap[asId.Decl];
                    }
                    else
                    {
                        V = asId.Decl;
                    }

                    // We need to make sure that the map variable isn't bound and that
                    // Note: that map is being fully indexed into and not partially
                    if ((!BoundVariables.Contains(V)) &&
                        indices.Count == MapProxy.ComputeIndicesRequireToDirectlyIndex(asId.Decl.TypedIdent.Type))
                    {
                        // Put indices in correct order
                        indices.Reverse();

                        // Expand the indices so variables are mapped
                        var expandedIndices = new List <Expr>();
                        foreach (var index in indices)
                        {
                            expandedIndices.Add((Expr)this.Visit(index));
                        }

                        var valueFromMap = State.ReadMapVariableInScopeAt(V, expandedIndices);
                        return(valueFromMap);
                    }
                }
            }

            // Handle all other NAryExpr and fall back when we encounter a mapselect we can't support
            // (e.g. the map variable being used is not known).
            return(base.VisitNAryExpr(node));
        }
Пример #59
0
 public override Expr VisitNAryExpr(NAryExpr node)
 {
   var result = base.VisitNAryExpr(node);
   var nAryExpr = result as NAryExpr;
   if (nAryExpr != null)
   {
     var funCall = nAryExpr.Fun as FunctionCall;
     if (funCall != null)
     {
       funCall.Func = Program.FindFunction(funCall.FunctionName);
     }
   }
   return result;
 }
Пример #60
0
 public override Expr VisitNAryExpr(NAryExpr node)
 {
     //Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <Expr>() != null);
     return(base.VisitNAryExpr((NAryExpr)node.Clone()));
 }