Ejemplo n.º 1
0
 public virtual ForallExpr VisitForallExpr(ForallExpr node)
 {
     Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <ForallExpr>() != null);
     node = (ForallExpr)this.VisitQuantifierExpr(node);
     return(node);
 }
        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);
        }
Ejemplo n.º 3
0
        public static void AddCheckers(CivlTypeChecker ctc)
        {
            foreach (var action in ctc.AllAtomicActions.Where(a => a.HasPendingAsyncs))
            {
                var requires = action.gate.Select(g => new Requires(false, g.Expr)).ToList();
                var cmds     = new List <Cmd>
                {
                    CmdHelper.CallCmd(
                        action.proc,
                        action.impl.InParams.Select(Expr.Ident).ToList <Expr>(),
                        action.impl.OutParams.Select(Expr.Ident).ToList())
                };
                var blocks = new List <Block>()
                {
                    new Block(Token.NoToken, "init", cmds, CmdHelper.ReturnCmd)
                };

                var PAs     = Expr.Ident(action.impl.OutParams.Last(p => p.TypedIdent.Type.Equals(ctc.pendingAsyncMultisetType)));
                var paBound = VarHelper.BoundVariable("pa", ctc.pendingAsyncType);
                var pa      = Expr.Ident(paBound);

                var nonnegativeExpr =
                    new ForallExpr(Token.NoToken, new List <Variable> {
                    paBound
                },
                                   Expr.Ge(Expr.Select(PAs, pa), Expr.Literal(0)));
                var correctTypeExpr = new ForallExpr(Token.NoToken, new List <Variable> {
                    paBound
                },
                                                     Expr.Imp(
                                                         Expr.Gt(Expr.Select(PAs, pa), Expr.Literal(0)),
                                                         Expr.Or(action.pendingAsyncs.Select(a => ExprHelper.FunctionCall(a.pendingAsyncCtor.membership, pa)))));
                var ensures = new List <Ensures>
                {
                    new Ensures(false, nonnegativeExpr)
                    {
                        ErrorData = $"Action {action.proc.Name} might create negative pending asyncs"
                    },
                    new Ensures(false, correctTypeExpr)
                    {
                        ErrorData = $"Action {action.proc.Name} might create undeclared pending asyncs"
                    },
                };

                CivlUtil.ResolveAndTypecheck(ensures);

                var proc = new Procedure(Token.NoToken, $"PendingAsyncChecker_{action.proc.Name}", new List <TypeVariable>(),
                                         action.impl.InParams, action.impl.OutParams,
                                         requires, action.proc.Modifies, ensures);
                var impl = new Implementation(Token.NoToken, proc.Name, proc.TypeParameters,
                                              proc.InParams, proc.OutParams, new List <Variable>(), blocks)
                {
                    Proc = proc
                };

                ctc.program.AddTopLevelDeclaration(proc);
                ctc.program.AddTopLevelDeclaration(impl);
            }
        }
Ejemplo n.º 4
0
 public void CachedHashCodeForAllExpr()
 {
     var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var y = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var body = Expr.Gt (new IdentifierExpr (Token.NoToken, x, /*immutable=*/true),
         new IdentifierExpr(Token.NoToken, y, /*immutable=*/true));
     var forAll = new ForallExpr(Token.NoToken, new List<Variable> () {x, y }, body, /*immutable=*/ true);
     Assert.AreEqual(forAll.ComputeHashCode(), forAll.GetHashCode());
 }
Ejemplo n.º 5
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;
    }
Ejemplo n.º 6
0
 public override Expr VisitForallExpr(ForallExpr node)
 {
     Contract.Ensures(Contract.Result<Expr>() == node);
     return (ForallExpr)this.VisitQuantifierExpr(node);
 }
Ejemplo n.º 7
0
 public virtual Expr VisitForallExpr(ForallExpr node) {
   Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<Expr>() != null);
   node = (ForallExpr)this.VisitQuantifierExpr(node);
   return node;
 }
Ejemplo n.º 8
0
        void QuantifierGuts(out Expression q, bool allowSemi, bool allowLambda)
        {
            Contract.Ensures(Contract.ValueAtReturn(out q) != null); IToken/*!*/ x = Token.NoToken;
            bool univ = false;
            List<BoundVar/*!*/> bvars;
            Attributes attrs;
            Expression range;
            Expression/*!*/ body;

            if (la.kind == 103 || la.kind == 123) {
            Forall();
            x = t;  univ = true;
            } else if (la.kind == 124 || la.kind == 125) {
            Exists();
            x = t;
            } else SynErr(238);
            QuantifierDomain(out bvars, out attrs, out range);
            QSep();
            Expression(out body, allowSemi, allowLambda);
            if (univ) {
             q = new ForallExpr(x, bvars, range, body, attrs);
            } else {
             q = new ExistsExpr(x, bvars, range, body, attrs);
            }
        }
Ejemplo n.º 9
0
    public Axiom CreateDefinitionAxiom(Expr definition, QKeyValue kv = null) {
      Contract.Requires(definition != null);

      List<Variable> dummies = new List<Variable>();
      List<Expr> callArgs = new List<Expr>();
      int i = 0;
      foreach (Formal/*!*/ f in InParams) {
        Contract.Assert(f != null);
        string nm = f.TypedIdent.HasName ? f.TypedIdent.Name : "_" + i;
        dummies.Add(new BoundVariable(f.tok, new TypedIdent(f.tok, nm, f.TypedIdent.Type)));
        callArgs.Add(new IdentifierExpr(f.tok, nm));
        i++;
      }
      List<TypeVariable>/*!*/ quantifiedTypeVars = new List<TypeVariable>();
      foreach (TypeVariable/*!*/ t in TypeParameters) {
        Contract.Assert(t != null);
        quantifiedTypeVars.Add(new TypeVariable(Token.NoToken, t.Name));
      }

      Expr call = new NAryExpr(tok, new FunctionCall(new IdentifierExpr(tok, Name)), callArgs);
      // specify the type of the function, because it might be that
      // type parameters only occur in the output type
      call = Expr.CoerceType(tok, call, (Type)OutParams[0].TypedIdent.Type.Clone());
      Expr def = Expr.Eq(call, definition);
      if (quantifiedTypeVars.Count != 0 || dummies.Count != 0) {
        def = new ForallExpr(tok, quantifiedTypeVars, dummies,
                             kv,
                             new Trigger(tok, true, new List<Expr> { call }, null),
                             def);
      }
      DefinitionAxiom = new Axiom(tok, def);
      return DefinitionAxiom;
    }
Ejemplo n.º 10
0
 public override ForallExpr VisitForallExpr(ForallExpr node)
 {
     //Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <ForallExpr>() != null);
     return(base.VisitForallExpr((ForallExpr)node.Clone()));
 }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="methodCall"></param>
    /// <remarks>Stub, This one really needs comments!</remarks>
    public override void TraverseChildren(IMethodCall methodCall) {
      var resolvedMethod = ResolveUnspecializedMethodOrThrow(methodCall.MethodToCall);

      Bpl.IToken methodCallToken = methodCall.Token();

      if (this.sink.Options.getMeHere) {
        // TODO: Get a method reference so this isn't a string comparison?
        var methodName = MemberHelper.GetMethodSignature(methodCall.MethodToCall, NameFormattingOptions.None);
        if (methodName.Equals("GetMeHere.GetMeHere.Assert")) {
          // for now, just translate it as "assert e"
          this.Traverse(methodCall.Arguments.First());
          Bpl.Expr e = this.TranslatedExpressions.Pop();
          this.StmtTraverser.StmtBuilder.Add(new Bpl.AssertCmd(methodCallToken, e));
          return;
        }
      }

      // Handle type equality specially when it is testing against a constant, i.e., o.GetType() == typeof(T)
      if (IsOperator(resolvedMethod) && !IsConversionOperator(resolvedMethod) && 
        TypeHelper.TypesAreEquivalent(resolvedMethod.ContainingType, this.sink.host.PlatformType.SystemType)) {
        // REVIEW: Assume the only operators on System.Type are == and !=
        var typeToTest = methodCall.Arguments.ElementAtOrDefault(0) as ITypeOf;
        IMethodCall callToGetType;
        if (typeToTest == null) {
          typeToTest = methodCall.Arguments.ElementAtOrDefault(1) as ITypeOf;
          callToGetType = methodCall.Arguments.ElementAtOrDefault(0) as IMethodCall;
        } else {
          callToGetType = methodCall.Arguments.ElementAtOrDefault(1) as IMethodCall;
        }
        if (typeToTest != null && callToGetType != null &&
          TypeHelper.TypesAreEquivalent(callToGetType.MethodToCall.ContainingType, this.sink.host.PlatformType.SystemObject) &&
          MemberHelper.GetMethodSignature(callToGetType.MethodToCall).Equals("System.Object.GetType")) {

          IExpression objectToTest = callToGetType.ThisArgument;

          // generate: $TypeConstructor($DynamicType(o)) == TypeConstructorId
          var typeConstructorId = this.sink.FindOrDefineType(typeToTest.TypeToGet.ResolvedType).ConstructorId;
          Contract.Assume(typeConstructorId != null);

          this.Traverse(objectToTest);
          var e = this.TranslatedExpressions.Pop();

          var exprs = new List<Bpl.Expr>(new Bpl.Expr[] {this.sink.Heap.DynamicType(e)});
          Bpl.Expr typeTestExpression = 
              Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, 
                              new Bpl.NAryExpr(methodCallToken, new Bpl.FunctionCall(sink.Heap.TypeConstructorFunction), exprs),
                              Bpl.Expr.Ident(typeConstructorId));
          if (MemberHelper.GetMethodSignature(resolvedMethod).Equals("System.Type.op_Inequality"))
            typeTestExpression = Bpl.Expr.Unary( methodCallToken, Bpl.UnaryOperator.Opcode.Not, typeTestExpression);
          this.TranslatedExpressions.Push(typeTestExpression);
          return;
        }
      }

      // Handle calls to Contract.ForAll and Contract.Exists specially (if they are to the overloads that take two ints and a predicate on ints)
      if (resolvedMethod.ContainingTypeDefinition.InternedKey == this.sink.host.PlatformType.SystemDiagnosticsContractsContract.InternedKey)
      {
          var methodName = resolvedMethod.Name.Value;
          if (methodCall.Arguments.Count() == 3 && (methodName == "ForAll" || methodName == "Exists"))
          {
              var noToken = Bpl.Token.NoToken;

              this.Traverse(methodCall.Arguments.ElementAt(0));
              var lb = this.TranslatedExpressions.Pop();
              this.Traverse(methodCall.Arguments.ElementAt(1));
              var ub = this.TranslatedExpressions.Pop();
              var delegateArgument = methodCall.Arguments.ElementAt(2);
              this.Traverse(delegateArgument);
              var del = this.TranslatedExpressions.Pop();

              var boundVar = new Bpl.LocalVariable(noToken, new Bpl.TypedIdent(noToken, TranslationHelper.GenerateTempVarName(), Bpl.Type.Int));

              var resultVar = new Bpl.LocalVariable(noToken, new Bpl.TypedIdent(noToken, TranslationHelper.GenerateTempVarName(), Bpl.Type.Bool));

              var delegateType = delegateArgument.Type;
              var invokeMethod = delegateType.ResolvedType.GetMembersNamed(this.sink.host.NameTable.GetNameFor("Invoke"), false).First() as IMethodReference;
              var unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod;
              var invokeProcedureInfo = sink.FindOrCreateProcedure(unspecializedInvokeMethod);
              var ins = new List<Bpl.Expr>();
              ins.Add(del);
              var localStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext);

              var secondArg = new Bpl.NAryExpr(noToken, new Bpl.FunctionCall(this.sink.Heap.Int2Union), new List<Bpl.Expr>(new Bpl.Expr[] {Bpl.Expr.Ident(boundVar)}));
              ins.Add(secondArg);
              var outs = new List<Bpl.IdentifierExpr>();
              outs.Add(Bpl.Expr.Ident(resultVar));

              var callCmd = new Bpl.CallCmd(noToken, invokeProcedureInfo.Decl.Name, ins, outs);
              var blockCmds = new List<Bpl.Cmd>();
              blockCmds.Add(
                new Bpl.AssumeCmd(noToken,
                Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq,
                                new Bpl.NAryExpr(noToken, new Bpl.FunctionCall(this.sink.Heap.Union2Int), new List<Bpl.Expr>(new Bpl.Expr[] {secondArg})),
                                Bpl.Expr.Ident(boundVar))));
              blockCmds.Add(callCmd);
              Bpl.Block block = new Bpl.Block(noToken, "A", blockCmds, new Bpl.ReturnExprCmd(noToken, Bpl.Expr.Ident(resultVar)));
              Bpl.Expr body = new Bpl.CodeExpr(new List<Bpl.Variable>(new Bpl.Variable[] {resultVar}), new List<Bpl.Block>{block});


              Bpl.Expr antecedent = Bpl.Expr.And(Bpl.Expr.Le(lb, Bpl.Expr.Ident(boundVar)), Bpl.Expr.Lt(Bpl.Expr.Ident(boundVar), ub));

              Bpl.Expr quantifier;
              if (methodName == "ForAll")
              {
                  body = Bpl.Expr.Imp(antecedent, body);
                  quantifier = new Bpl.ForallExpr(methodCallToken, new List<Bpl.Variable>(new Bpl.Variable[] {boundVar}), body);
              }
              else
              {
                  body = Bpl.Expr.And(antecedent, body);
                  quantifier = new Bpl.ExistsExpr(methodCallToken, new List<Bpl.Variable>(new Bpl.Variable[] {boundVar}), body);
              }
              this.TranslatedExpressions.Push(quantifier);
              return;
          }
      }

      List<Bpl.Expr> inexpr;
      List<Bpl.IdentifierExpr> outvars;
      Bpl.IdentifierExpr thisExpr;
      Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> toBoxed;
      var proc = TranslateArgumentsAndReturnProcedure(methodCallToken, methodCall.MethodToCall, resolvedMethod, methodCall.IsStaticCall ? null : methodCall.ThisArgument, methodCall.Arguments, out inexpr, out outvars, out thisExpr, out toBoxed);
      string methodname = proc.Name;
      var translateAsFunctionCall = proc is Bpl.Function;
      bool isAsync = false;

      // this code structure is quite chaotic, and some code needs to be evaluated regardless, hence the try-finally
      try {
        if (!translateAsFunctionCall) {
          foreach (var a in resolvedMethod.Attributes) {
            if (TypeHelper.GetTypeName(a.Type).EndsWith("AsyncAttribute")) {
                isAsync = true;
            }
          }
        }

        var deferringCtorCall = resolvedMethod.IsConstructor && methodCall.ThisArgument is IThisReference;
        // REVIEW!! Ask Herman: is the above test enough? The following test is used in FindCtorCall.IsDeferringCtor,
        // but it doesn't work when the type is a struct S because then "this" has a type of "&S".
          //&& TypeHelper.TypesAreEquivalent(resolvedMethod.ContainingType, methodCall.ThisArgument.Type);

        if (resolvedMethod.IsConstructor && resolvedMethod.ContainingTypeDefinition.IsStruct && !deferringCtorCall) {
          handleStructConstructorCall(methodCall, methodCallToken, inexpr, outvars, thisExpr, proc);
          return;
        }

        Bpl.CallCmd call;
        bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_");
        bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_");
        if (isEventAdd || isEventRemove) {
          call = translateAddRemoveCall(methodCall, resolvedMethod, methodCallToken, inexpr, outvars, thisExpr, isEventAdd);
        } else {
          if (translateAsFunctionCall) {
            var func = proc as Bpl.Function;
            var exprSeq = new List<Bpl.Expr>();
            foreach (var e in inexpr) {
              exprSeq.Add(e);
            }
            var callFunction = new Bpl.NAryExpr(methodCallToken, new Bpl.FunctionCall(func), exprSeq);
            this.TranslatedExpressions.Push(callFunction);
            return;
          } else {
            EmitLineDirective(methodCallToken);
            call = new Bpl.CallCmd(methodCallToken, methodname, inexpr, outvars);
            call.IsAsync = isAsync;
            this.StmtTraverser.StmtBuilder.Add(call);
          }
        }

        foreach (KeyValuePair<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> kv in toBoxed) {
          var lhs = kv.Key;
          var tuple = kv.Value;
          var rhs = tuple.Item1;
          Bpl.Expr fromUnion = this.sink.Heap.FromUnion(Bpl.Token.NoToken, lhs.Type, rhs, tuple.Item2);
          this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(lhs, fromUnion));
        }

        if (this.sink.Options.modelExceptions == 2
          || (this.sink.Options.modelExceptions == 1 && this.sink.MethodThrowsExceptions(resolvedMethod))) {
          Bpl.Expr expr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef));
          this.StmtTraverser.RaiseException(expr);
        }
      } finally {
        // TODO move away phone related code from the translation, it would be better to have 2 or more translation phases
        if (PhoneCodeHelper.instance().PhonePlugin != null) {
          if (PhoneCodeHelper.instance().PhoneNavigationToggled) {
            if (PhoneCodeHelper.instance().isNavigationCall(methodCall)) {
              Bpl.AssignCmd assignCmd = PhoneCodeHelper.instance().createBoogieNavigationUpdateCmd(sink);
              this.StmtTraverser.StmtBuilder.Add(assignCmd);
            }
          }

          if (PhoneCodeHelper.instance().PhoneFeedbackToggled) {
            if (PhoneCodeHelper.instance().isMethodKnownUIChanger(methodCall)) {
              Bpl.AssumeCmd assumeFalse = new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.LiteralExpr.False);
              this.StmtTraverser.StmtBuilder.Add(assumeFalse);
            }
          }
        }
      }
    }
Ejemplo n.º 12
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));
            }
        }
Ejemplo n.º 13
0
        private VCGenOutcome LearnInv(Dictionary<string, int> impl2Priority)
        {
            var worklist = new SortedSet<Tuple<int, string>>();
            name2Impl.Keys.Iter(k => worklist.Add(Tuple.Create(impl2Priority[k], k)));
            
            while (worklist.Any())
            {
                var impl = worklist.First().Item2;
                worklist.Remove(worklist.First());

                #region vcgen

                var gen = prover.VCExprGen;
                var terms = new List<Expr>();
                foreach (var tup in impl2FuncCalls[impl])
                {
                    var controlVar = tup.Item2;
                    var exprVars = tup.Item3;
                    var varList = new List<Expr>();
                    exprVars.Args.OfType<Expr>().Iter(v => varList.Add(v));

                    var args = new List<Expr>();
                    controlVar.InParams.Iter(v => args.Add(Expr.Ident(v)));
                    Expr term = Expr.Eq(new NAryExpr(Token.NoToken, new FunctionCall(controlVar), args),
                                 function2Value[tup.Item1].Gamma(varList));

                    if (controlVar.InParams.Count != 0)
                    {
                        term = new ForallExpr(Token.NoToken, new List<Variable>(controlVar.InParams.ToArray()),
                            new Trigger(Token.NoToken, true, new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(controlVar), args) }),
                            term);
                    }
                    terms.Add(term);

                    /*
                    foreach (var variable in varList)
                    {
                        terms.Add(Expr.Le(variable, Expr.Literal(10)));
                        terms.Add(Expr.Ge(variable, Expr.Literal(-10)));
                    }
                    */
                }
                var env = BinaryTreeAnd(terms, 0, terms.Count - 1);

                env.Typecheck(new TypecheckingContext((IErrorSink)null));
                var envVC = prover.Context.BoogieExprTranslator.Translate(env);
                var vc = gen.Implies(envVC, impl2VC[impl]);

                if (CommandLineOptions.Clo.Trace)
                {
                    Console.WriteLine("Verifying {0}: ", impl);
                    //Console.WriteLine("env: {0}", envVC);
                    var envFuncs = new HashSet<string>();
                    impl2FuncCalls[impl].Iter(tup => envFuncs.Add(tup.Item1));
                    envFuncs.Iter(f => PrintFunction(existentialFunctions[f]));
                }

                #endregion vcgen

                VCExpr finalVC;
                for (int i = 0; i <= bounds4cex.Count(); i++)
                {
#region boundcexvalues
                    /* Last iteration is when there are enforced no bounds on the cex values. */
                    if (i < bounds4cex.Count())
                    {
                        int bound = bounds4cex.ElementAt(i);
                        terms.Clear();
                        foreach (var tup in impl2FuncCalls[impl])
                        {
                            var exprVars = tup.Item3;
                            var varList = new List<Expr>();
                            exprVars.Args.OfType<Expr>().Where(v => v.Type.IsInt).Iter(v => varList.Add(v));
                            foreach (var variable in varList)
                            {
                                terms.Add(Expr.Le(variable, Expr.Literal(bound)));
                                terms.Add(Expr.Ge(variable, Expr.Literal(-1 * bound)));
                                //terms.Add(Expr.Ge(variable, Expr.Literal(0)));
                            }
                        }
                        var boundcex = BinaryTreeAnd(terms, 0, terms.Count - 1);
                        boundcex.Typecheck(new TypecheckingContext((IErrorSink)null));
                        var boundcexVC = prover.Context.BoogieExprTranslator.Translate(boundcex);

                        finalVC = gen.Implies(boundcexVC, vc);
                    }
                    else
                    {
                        //finalVC = vc;
                        
                        
                        int bound = 1000000;
                        terms.Clear();
                        foreach (var tup in impl2FuncCalls[impl])
                        {
                            var exprVars = tup.Item3;
                            var varList = new List<Expr>();
                            exprVars.Args.OfType<Expr>().Where(v => v.Type.IsInt).Iter(v => varList.Add(v));
                            foreach (var variable in varList)
                            {
                                terms.Add(Expr.Le(variable, Expr.Literal(bound)));
                                terms.Add(Expr.Ge(variable, Expr.Literal(-1 * bound)));
                                //terms.Add(Expr.Ge(variable, Expr.Literal(0)));
                            }
                        }
                        var boundcex = BinaryTreeAnd(terms, 0, terms.Count - 1);
                        boundcex.Typecheck(new TypecheckingContext((IErrorSink)null));
                        var boundcexVC = prover.Context.BoogieExprTranslator.Translate(boundcex);

                        finalVC = gen.Implies(boundcexVC, vc);
                         
                    }
#endregion boundcexvalues

                    var handler = impl2ErrorHandler[impl].Item1;
                    var collector = impl2ErrorHandler[impl].Item2;
                    collector.Reset(impl);
                    implicationCounterExamples.Clear();
                    VCisValid = true;   // set to false if control reaches HandleCounterExample
                    //realErrorEncountered = false;
                    //newSamplesAdded = false;
                    //this.posNegCexAdded = false;

                    var start = DateTime.Now;

                    prover.Push();
                    prover.Assert(gen.Not(finalVC), true);
                    prover.FlushAxiomsToTheoremProver();
                    prover.Check();
                    ProverInterface.Outcome proverOutcome = prover.CheckOutcomeCore(handler);

                    var inc = (DateTime.Now - start);
                    proverTime += inc;
                    numProverQueries++;

                    if (CommandLineOptions.Clo.Trace)
                        Console.WriteLine("Prover Time taken = " + inc.TotalSeconds.ToString());

                    if (proverOutcome == ProverInterface.Outcome.TimeOut || proverOutcome == ProverInterface.Outcome.OutOfMemory)
                    {
                        Console.WriteLine("Z3 Prover for implementation {0} times out or runs out of memory !", impl);
                        return new VCGenOutcome(proverOutcome, new List<Counterexample>());
                    }

                    if (!VCisValid)
                    {
                        /* There was a counterexample found and acted upon while proving the method. */
                        if (collector.real_errors.Count > 0)
                        {
                            return new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.real_errors);
                        }

                        if (collector.conjecture_errors.Count == 0)
                        {
                            // No positive or negative counter-example added. Need to add implication counter-examples
                            Debug.Assert(collector.implication_errors.Count > 0);
                            foreach (var cex in implicationCounterExamples)
                            {
                                AddCounterExample(cex);
                            }
                        }

                        //Debug.Assert(newSamplesAdded);
                        HashSet<string> funcsChanged;

                        if (!learn(out funcsChanged))
                        {
                            // learner timed out, ran into some errors, or if there is no consistent conjecture
                            prover.Pop();
                            if(collector.conjecture_errors.Count > 0)
                                return new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.conjecture_errors);
                            else
                                return new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.implication_errors);
                        }
                        // propagate dependent guys back into the worklist, including self
                        var deps = new HashSet<string>();
                        deps.Add(impl);
                        funcsChanged.Iter(f => deps.UnionWith(function2implAssumed[f]));
                        funcsChanged.Iter(f => deps.UnionWith(function2implAsserted[f]));

                        deps.Iter(s => worklist.Add(Tuple.Create(impl2Priority[s], s)));

                        // break out of the loop that iterates over various bounds.
                        prover.Pop();
                        break;
                    }
                    else
                    {
                        prover.Pop();
                    }
                }
            }
            // The program was verified
            return new VCGenOutcome(ProverInterface.Outcome.Valid, new List<Counterexample>());            
        }
Ejemplo n.º 14
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));
            }
        }
Ejemplo n.º 15
0
        private ICEOutcome LearnInvFromTemplate(Dictionary<string, int> impl2Priority, Template t, int range, out VCGenOutcome overallOutcome)
        {
            overallOutcome = null;

            // create a new z3 context
            if (z3Context != null)
            {
                z3Context.context.Dispose();
                z3Context.config.Dispose();
            }
            z3Context = new Z3Context();

            foreach (var func in existentialFunctions.Values)
            {
                // initialize function to an "Octagons" instance with the given template "t".
                function2Value[func.Name] = ICEDomainFactory.GetInstance("Octagons", t, ref z3Context, func.Name, range);
            }

            // add counterexamples into the z3Context. These are obtained from the earlier iterations of the template.
            foreach (var cex in counterExamples)
            {
                AddCounterExampleToZ3Context(cex);
            }

            var worklist = new SortedSet<Tuple<int, string>>();
            name2Impl.Keys.Iter(k => worklist.Add(Tuple.Create(impl2Priority[k], k)));

            while (worklist.Any())
            {
                var impl = worklist.First().Item2;
                worklist.Remove(worklist.First());

                #region vcgen

                var gen = prover.VCExprGen;
                var terms = new List<Expr>();
                foreach (var tup in impl2FuncCalls[impl])
                {
                    var controlVar = tup.Item2;
                    var exprVars = tup.Item3;
                    var varList = new List<Expr>();
                    exprVars.Args.OfType<Expr>().Iter(v => varList.Add(v));

                    var args = new List<Expr>();
                    controlVar.InParams.Iter(v => args.Add(Expr.Ident(v)));
                    Expr term = Expr.Eq(new NAryExpr(Token.NoToken, new FunctionCall(controlVar), args),
                                 function2Value[tup.Item1].Gamma(varList));

                    if (controlVar.InParams.Count != 0)
                    {
                        term = new ForallExpr(Token.NoToken, new List<Variable>(controlVar.InParams.ToArray()),
                            new Trigger(Token.NoToken, true, new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(controlVar), args) }),
                            term);
                    }
                    terms.Add(term);
                }
                var env = BinaryTreeAnd(terms, 0, terms.Count - 1);

                env.Typecheck(new TypecheckingContext((IErrorSink)null));
                var envVC = prover.Context.BoogieExprTranslator.Translate(env);

                var vc = gen.Implies(envVC, impl2VC[impl]);

                if (CommandLineOptions.Clo.Trace)
                {
                    Console.WriteLine("Verifying {0}: ", impl);
                    //Console.WriteLine("env: {0}", envVC);
                    var envFuncs = new HashSet<string>();
                    impl2FuncCalls[impl].Iter(tup => envFuncs.Add(tup.Item1));
                    envFuncs.Iter(f => PrintFunction(existentialFunctions[f]));
                }

                #endregion vcgen

                VCExpr finalVC;

                #region bound_value_of_cexs
            #if false
                finalVC = vc;

            #else
                int bound = 1000000;
                terms.Clear();
                foreach (var tup in impl2FuncCalls[impl])
                {
                    var exprVars = tup.Item3;
                    var varList = new List<Expr>();
                    exprVars.Args.OfType<Expr>().Where(v => v.Type.IsInt).Iter(v => varList.Add(v));
                    foreach (var variable in varList)
                    {
                        terms.Add(Expr.Le(variable, Expr.Literal(bound)));
                        terms.Add(Expr.Ge(variable, Expr.Literal(-1 * bound)));
                        //terms.Add(Expr.Ge(variable, Expr.Literal(0)));
                    }
                }
                var boundcex = BinaryTreeAnd(terms, 0, terms.Count - 1);
                boundcex.Typecheck(new TypecheckingContext((IErrorSink)null));
                var boundcexVC = prover.Context.BoogieExprTranslator.Translate(boundcex);

                finalVC = gen.Implies(boundcexVC, vc);
            #endif
                #endregion bound_value_of_cexs

                var handler = impl2ErrorHandler[impl].Item1;
                var collector = impl2ErrorHandler[impl].Item2;
                collector.Reset(impl);
                VCisValid = true;   // set to false if control reaches HandleCounterExample
                realErrorEncountered = false;
                newSamplesAdded = false;

                var start = DateTime.Now;

                prover.Push();
                prover.Assert(gen.Not(finalVC), true);
                prover.FlushAxiomsToTheoremProver();
                prover.Check();
                ProverInterface.Outcome proverOutcome = prover.CheckOutcomeCore(handler);

                //prover.BeginCheck(impl, vc, handler);
                //ProverInterface.Outcome proverOutcome = prover.CheckOutcomeCore(handler);

                var inc = (DateTime.Now - start);
                proverTime += inc;
                numProverQueries++;

                if (CommandLineOptions.Clo.Trace)
                    Console.WriteLine("Prover Time taken = " + inc.TotalSeconds.ToString());

                if (proverOutcome == ProverInterface.Outcome.TimeOut || proverOutcome == ProverInterface.Outcome.OutOfMemory)
                {
                    Console.WriteLine("Z3 Prover for implementation {0} times out or runs out of memory !", impl);
                    z3Context.context.Dispose();
                    z3Context.config.Dispose();

                    overallOutcome = new VCGenOutcome(proverOutcome, new List<Counterexample>());
                    return ICEOutcome.Timeout;
                }

                if (CommandLineOptions.Clo.Trace)
                    Console.WriteLine(!VCisValid ? "SAT" : "UNSAT");

                if (!VCisValid)
                {
                    if (realErrorEncountered)
                    {
                        overallOutcome = new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.real_errors);
                        return ICEOutcome.ErrorFound;
                    }

                    Debug.Assert(newSamplesAdded);
                    HashSet<string> funcsChanged;
                    if (!learn(out funcsChanged))
                    {
                        // learner timed out or there is no valid conjecture in the current given template
                        overallOutcome = new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.conjecture_errors);
                        prover.Pop();
                        return ICEOutcome.InvariantNotFound;
                    }
                    // propagate dependent guys back into the worklist, including self
                    var deps = new HashSet<string>();
                    deps.Add(impl);
                    funcsChanged.Iter(f => deps.UnionWith(function2implAssumed[f]));
                    funcsChanged.Iter(f => deps.UnionWith(function2implAsserted[f]));

                    deps.Iter(s => worklist.Add(Tuple.Create(impl2Priority[s], s)));
                }

                prover.Pop();
            }
            // The program was verified with the current template!
            overallOutcome = new VCGenOutcome(ProverInterface.Outcome.Valid, new List<Counterexample>());
            return ICEOutcome.InvariantFound;
        }
Ejemplo n.º 16
0
 public void ProtectedForAllExprBody()
 {
     var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var y = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int));
     var xId = new IdentifierExpr(Token.NoToken, x, /*immutable=*/true);
     var yId = new IdentifierExpr(Token.NoToken, y, /*immutable=*/true);
     var body = Expr.Gt(xId, yId);
     var forAll = new ForallExpr(Token.NoToken, new List<Variable> () { x, y }, body, /*immutable=*/true);
     forAll.Body = Expr.Lt(xId, yId); // Changing the body of an immutable ForAllExpr should fail
 }
Ejemplo n.º 17
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;
		}
	}
Ejemplo n.º 18
0
 public override Expr VisitForallExpr(ForallExpr node) {
   //Contract.Requires(node != null);
   Contract.Ensures(Contract.Result<Expr>() != null);
   return base.VisitForallExpr((ForallExpr)node.Clone());
 }
Ejemplo n.º 19
0
    public void SimpleForAll() {
      var boundVar = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken,"foo",Microsoft.Boogie.Type.Bool));
      var id = new IdentifierExpr(Token.NoToken, boundVar);
      var forall = new ForallExpr(Token.NoToken, new List<Variable>() { boundVar }, id);

      var id2 = new IdentifierExpr(Token.NoToken, boundVar);
      var forall2 = new ForallExpr(Token.NoToken, new List<Variable>() { boundVar }, id2);

      Assert.AreNotSame(forall, forall2); // These are different references

      Assert.IsTrue(forall.Equals(forall2)); // These are "structurally equal"
      Assert.AreEqual(forall.GetHashCode(), forall2.GetHashCode()); // If the .Equals() is true then hash codes must be the same
    }