Пример #1
0
        private VCExpr ToVcExpr(Expr expr, Dictionary <string, VCExpr> incarnations, VCExpressionGenerator gen)
        {
            if (expr is LiteralExpr)
            {
                var val = (expr as LiteralExpr).Val;
                if (val is bool)
                {
                    if ((bool)val)
                    {
                        return(VCExpressionGenerator.True);
                    }
                    else
                    {
                        return(VCExpressionGenerator.False);
                    }
                }
                else if (val is Microsoft.BaseTypes.BigNum)
                {
                    return(gen.Integer((Microsoft.BaseTypes.BigNum)val));
                }

                throw new NotImplementedException("Cannot handle literals of this type");
            }

            if (expr is IdentifierExpr)
            {
                return(ToVcVar((expr as IdentifierExpr).Name, incarnations, false));
            }

            if (expr is OldExpr)
            {
                var ide = (expr as OldExpr).Expr as IdentifierExpr;
                Debug.Assert(ide != null);

                return(ToVcVar(ide.Name, incarnations, true));
            }

            if (expr is NAryExpr)
            {
                var nary = expr as NAryExpr;
                if (nary.Fun is UnaryOperator)
                {
                    Debug.Assert((nary.Fun as UnaryOperator).Op == UnaryOperator.Opcode.Not);
                    return(gen.Not(ToVcExpr(nary.Args[0], incarnations, gen)));
                }
                if (nary.Fun is BinaryOperator)
                {
                    return(gen.Function(Translate(nary.Fun as BinaryOperator), ToVcExpr(nary.Args[0], incarnations, gen), ToVcExpr(nary.Args[1], incarnations, gen)));
                }
                Debug.Assert(false, "No other op is handled");
            }
            throw new NotImplementedException(string.Format("Expr of type {0} is not handled", expr.GetType().ToString()));
        }
Пример #2
0
        private VCExpr BuildAxiom(ProverInterface proverInterface, Dictionary <Variable, bool> currentAssignment)
        {
            ProverContext           proverContext  = proverInterface.Context;
            Boogie2VCExprTranslator exprTranslator = proverContext.BoogieExprTranslator;
            VCExpressionGenerator   exprGen        = proverInterface.VCExprGen;

            VCExpr expr = VCExpressionGenerator.True;

            foreach (KeyValuePair <Variable, bool> kv in currentAssignment)
            {
                Variable  constant = kv.Key;
                VCExprVar exprVar  = exprTranslator.LookupVariable(constant);
                if (kv.Value)
                {
                    expr = exprGen.And(expr, exprVar);
                }
                else
                {
                    expr = exprGen.And(expr, exprGen.Not(exprVar));
                }
            }

            if (CommandLineOptions.Clo.ExplainHoudini)
            {
                // default values for ExplainHoudini control variables
                foreach (var constant in explainConstantsNegative.Concat(explainConstantsPositive))
                {
                    expr = exprGen.And(expr, exprTranslator.LookupVariable(constant));
                }
            }

            /*
             * foreach (Variable constant in this.houdiniConstants) {
             * VCExprVar exprVar = exprTranslator.LookupVariable(constant);
             * if (currentAssignment[constant]) {
             *  expr = exprGen.And(expr, exprVar);
             * }
             * else {
             *  expr = exprGen.And(expr, exprGen.Not(exprVar));
             * }
             * }
             */

            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Houdini assignment axiom: " + expr);
            }

            return(expr);
        }
Пример #3
0
        // MAXSAT
        public void Explain(ProverInterface proverInterface,
                            Dictionary <Variable, bool> assignment, Variable refutedConstant)
        {
            Contract.Assert(CommandLineOptions.Clo.ExplainHoudini);

            collector.examples.Clear();

            // debugging
            houdiniAssertConstants.Iter(v => System.Diagnostics.Debug.Assert(assignment.ContainsKey(v)));
            houdiniAssumeConstants.Iter(v => System.Diagnostics.Debug.Assert(assignment.ContainsKey(v)));
            Contract.Assert(assignment.ContainsKey(refutedConstant));
            Contract.Assert(houdiniAssertConstants.Contains(refutedConstant));

            var hardAssumptions = new List <VCExpr>();
            var softAssumptions = new List <VCExpr>();

            Boogie2VCExprTranslator exprTranslator = proverInterface.Context.BoogieExprTranslator;
            VCExpressionGenerator   exprGen        = proverInterface.VCExprGen;
            var controlExpr = VCExpressionGenerator.True;

            foreach (var tup in assignment)
            {
                Variable  constant = tup.Key;
                VCExprVar exprVar  = exprTranslator.LookupVariable(constant);
                var       val      = tup.Value;

                if (houdiniAssumeConstants.Contains(constant))
                {
                    if (tup.Value)
                    {
                        hardAssumptions.Add(exprVar);
                    }
                    else
                    {
                        // Previously removed assumed candidates are the soft constraints
                        softAssumptions.Add(exprVar);
                    }
                }
                else if (houdiniAssertConstants.Contains(constant))
                {
                    if (constant == refutedConstant)
                    {
                        hardAssumptions.Add(exprVar);
                    }
                    else
                    {
                        hardAssumptions.Add(exprGen.Not(exprVar));
                    }
                }
                else
                {
                    if (tup.Value)
                    {
                        hardAssumptions.Add(exprVar);
                    }
                    else
                    {
                        hardAssumptions.Add(exprGen.Not(exprVar));
                    }
                }

                // For an asserted condition (c ==> \phi),
                // ExplainHoudini's extra control constants (c_pos, c_neg) are used as follows:
                //   (true, true): "assert \phi"
                //   (false, _): "assert false"
                //   (true, false): "assert true"
                if (constant != refutedConstant && constantToControl.ContainsKey(constant.Name))
                {
                    var posControl = constantToControl[constant.Name].Item1;
                    var negControl = constantToControl[constant.Name].Item2;

                    // Handle self-recursion
                    if (houdiniAssertConstants.Contains(constant) && houdiniAssumeConstants.Contains(constant))
                    {
                        // disable this assert
                        controlExpr = exprGen.And(controlExpr, exprGen.And(exprTranslator.LookupVariable(posControl), exprGen.Not(exprTranslator.LookupVariable(negControl))));
                    }
                    else
                    {
                        // default values for control variables
                        controlExpr = exprGen.And(controlExpr, exprGen.And(exprTranslator.LookupVariable(posControl), exprTranslator.LookupVariable(negControl)));
                    }
                }
            }

            hardAssumptions.Add(exprGen.Not(conjecture));

            // default values for control variables
            Contract.Assert(constantToControl.ContainsKey(refutedConstant.Name));
            var pc = constantToControl[refutedConstant.Name].Item1;
            var nc = constantToControl[refutedConstant.Name].Item2;

            var controlExprNoop = exprGen.And(controlExpr,
                                              exprGen.And(exprTranslator.LookupVariable(pc), exprTranslator.LookupVariable(nc)));

            var controlExprFalse = exprGen.And(controlExpr,
                                               exprGen.And(exprGen.Not(exprTranslator.LookupVariable(pc)), exprGen.Not(exprTranslator.LookupVariable(nc))));

            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Verifying (MaxSat) " + descriptiveName);
            }
            DateTime now = DateTime.UtcNow;

            var el = CommandLineOptions.Clo.ProverCCLimit;

            CommandLineOptions.Clo.ProverCCLimit = 1;

            var outcome = ProverInterface.Outcome.Undetermined;

            do
            {
                List <int> unsatisfiedSoftAssumptions;

                hardAssumptions.Add(controlExprNoop);
                outcome = proverInterface.CheckAssumptions(hardAssumptions, softAssumptions, out unsatisfiedSoftAssumptions, handler);
                hardAssumptions.RemoveAt(hardAssumptions.Count - 1);

                if (outcome == ProverInterface.Outcome.TimeOut || outcome == ProverInterface.Outcome.OutOfMemory || outcome == ProverInterface.Outcome.OutOfResource || outcome == ProverInterface.Outcome.Undetermined)
                {
                    break;
                }

                var reason = new HashSet <string>();
                unsatisfiedSoftAssumptions.Iter(i => reason.Add(softAssumptions[i].ToString()));
                if (CommandLineOptions.Clo.Trace)
                {
                    Console.Write("Reason for removal of {0}: ", refutedConstant.Name);
                    reason.Iter(r => Console.Write("{0} ", r));
                    Console.WriteLine();
                }

                // Get rid of those constants from the "reason" that can even make
                // "assert false" pass

                hardAssumptions.Add(controlExprFalse);
                var softAssumptions2 = new List <VCExpr>();
                for (int i = 0; i < softAssumptions.Count; i++)
                {
                    if (unsatisfiedSoftAssumptions.Contains(i))
                    {
                        softAssumptions2.Add(softAssumptions[i]);
                        continue;
                    }
                    hardAssumptions.Add(softAssumptions[i]);
                }

                var unsatisfiedSoftAssumptions2 = new List <int>();
                outcome = proverInterface.CheckAssumptions(hardAssumptions, softAssumptions2, out unsatisfiedSoftAssumptions2, handler);

                if (outcome == ProverInterface.Outcome.TimeOut || outcome == ProverInterface.Outcome.OutOfMemory || outcome == ProverInterface.Outcome.OutOfResource || outcome == ProverInterface.Outcome.Undetermined)
                {
                    break;
                }

                unsatisfiedSoftAssumptions2.Iter(i => reason.Remove(softAssumptions2[i].ToString()));
                var reason1 = new HashSet <string>(); //these are the reasons for inconsistency
                unsatisfiedSoftAssumptions2.Iter(i => reason1.Add(softAssumptions2[i].ToString()));

                if (CommandLineOptions.Clo.Trace)
                {
                    Console.Write("Revised reason for removal of {0}: ", refutedConstant.Name);
                    reason.Iter(r => Console.Write("{0} ", r));
                    Console.WriteLine();
                }
                foreach (var r in reason)
                {
                    Houdini.explainHoudiniDottyFile.WriteLine("{0} -> {1} [ label = \"{2}\" color=red ];", refutedConstant.Name, r, descriptiveName);
                }
                //also add the removed reasons using dotted edges (requires- x != 0, requires- x == 0 ==> assert x != 0)
                foreach (var r in reason1)
                {
                    Houdini.explainHoudiniDottyFile.WriteLine("{0} -> {1} [ label = \"{2}\" color=blue style=dotted ];", refutedConstant.Name, r, descriptiveName);
                }
            } while (false);

            if (outcome == ProverInterface.Outcome.TimeOut || outcome == ProverInterface.Outcome.OutOfMemory || outcome == ProverInterface.Outcome.OutOfResource || outcome == ProverInterface.Outcome.Undetermined)
            {
                Houdini.explainHoudiniDottyFile.WriteLine("{0} -> {1} [ label = \"{2}\" color=red ];", refutedConstant.Name, "TimeOut", descriptiveName);
            }

            CommandLineOptions.Clo.ProverCCLimit = el;

            double queryTime = (DateTime.UtcNow - now).TotalSeconds;

            stats.proverTime += queryTime;
            stats.numProverQueries++;
            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Time taken = " + queryTime);
            }
        }
Пример #4
0
    public void GenerateVC()
    {
      if (initialized) return;
      if (CommandLineOptions.Clo.SIBoolControlVC)
      {
        GenerateVCBoolControl();
        initialized = true;
        return;
      }

      List<Variable> outputVariables = new List<Variable>();
      List<Expr> assertConjuncts = new List<Expr>();
      foreach (Variable v in impl.OutParams)
      {
        Constant c = new Constant(Token.NoToken,
          new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type));
        outputVariables.Add(c);
        Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
        assertConjuncts.Add(eqExpr);
      }

      foreach (IdentifierExpr e in impl.Proc.Modifies)
      {
        if (e.Decl == null) continue;
        Variable v = e.Decl;
        Constant c = new Constant(Token.NoToken,
          new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type));
        outputVariables.Add(c);
        Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v));
        assertConjuncts.Add(eqExpr);
      }

      exitAssertCmd = new AssertCmd(Token.NoToken, Expr.Not(Expr.BinaryTreeAnd(assertConjuncts)));

      Program program = vcgen.program;
      ProverInterface proverInterface = vcgen.prover;
      vcgen.ConvertCFG2DAG(impl);
      vcgen.PassifyImpl(impl, out mvInfo);

      VCExpressionGenerator gen = proverInterface.VCExprGen;
      var exprGen = proverInterface.Context.ExprGen;
      var translator = proverInterface.Context.BoogieExprTranslator;

      controlFlowVariable =
        new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "@cfc", Microsoft.Boogie.Type.Int));
      VCExpr controlFlowVariableExpr = translator.LookupVariable(controlFlowVariable);

      vcgen.InstrumentCallSites(impl);

      if (PassiveImplInstrumentation != null)
        PassiveImplInstrumentation(impl);

      label2absy = new Dictionary<int, Absy>();
      VCGen.CodeExprConversionClosure cc = new VCGen.CodeExprConversionClosure(label2absy, proverInterface.Context);
      translator.SetCodeExprConverter(cc.CodeExprToVerificationCondition);
      vcexpr = gen.Not(vcgen.GenerateVCAux(impl, controlFlowVariableExpr, label2absy, proverInterface.Context));

      if (controlFlowVariableExpr != null)
      {
        VCExpr controlFlowFunctionAppl =
          exprGen.ControlFlowFunctionApplication(controlFlowVariableExpr, exprGen.Integer(BigNum.ZERO));
        VCExpr eqExpr = exprGen.Eq(controlFlowFunctionAppl, exprGen.Integer(BigNum.FromInt(impl.Blocks[0].UniqueId)));
        vcexpr = exprGen.And(eqExpr, vcexpr);
      }

      callSites = vcgen.CollectCallSites(impl);
      recordProcCallSites = vcgen.CollectRecordProcedureCallSites(impl);

      privateExprVars = new List<VCExprVar>();
      foreach (Variable v in impl.LocVars)
      {
        privateExprVars.Add(translator.LookupVariable(v));
      }

      foreach (Variable v in impl.OutParams)
      {
        privateExprVars.Add(translator.LookupVariable(v));
      }

      interfaceExprVars = new List<VCExprVar>();
      foreach (Variable v in program.GlobalVariables)
      {
        interfaceExprVars.Add(translator.LookupVariable(v));
      }

      foreach (Variable v in impl.InParams)
      {
        interfaceExprVars.Add(translator.LookupVariable(v));
      }

      foreach (Variable v in outputVariables)
      {
        interfaceExprVars.Add(translator.LookupVariable(v));
      }

      initialized = true;
    }
Пример #5
0
            public VCExpr get(Term arg)
            {
                if (memo.ContainsKey(arg))
                {
                    return(memo[arg]);
                }
                VCExpr res = null;

                switch (arg.GetKind())
                {
                case TermKind.Numeral:
                    var numstr = arg.GetNumeralString();
                    if (arg.GetSort().GetSortKind() == SortKind.Int)
                    {
                        res = gen.Integer(Basetypes.BigNum.FromString(numstr));
                    }
                    else
                    {
                        res = gen.Real(Basetypes.BigDec.FromString(numstr));
                    }
                    break;

                case TermKind.App:
                    var args   = arg.GetAppArgs();
                    var vcargs = new VCExpr[args.Length];
                    for (int i = 0; i < args.Length; i++)
                    {
                        vcargs[i] = get(args[i]);
                    }

                    switch (arg.GetAppDecl().GetKind())
                    {
                    case DeclKind.Add:
                        if (vcargs.Length == 0)
                        {
                            if (arg.GetSort().GetSortKind() == SortKind.Int)
                            {
                                res = gen.Integer(Basetypes.BigNum.ZERO);
                            }
                            else
                            {
                                res = gen.Real(Basetypes.BigDec.ZERO);
                            }
                        }
                        else
                        {
                            res = vcargs[0];
                            for (int k = 1; k < vcargs.Length; k++)
                            {
                                res = gen.Add(res, vcargs[k]);
                            }
                        }
                        break;

                    case DeclKind.And:
                        res = VCExpressionGenerator.True;
                        for (int i = 0; i < vcargs.Length; i++)
                        {
                            res = gen.AndSimp(res, vcargs[i]);
                        }
                        break;

                    case DeclKind.Div:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Function(VCExpressionGenerator.RealDivOp, vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.Eq:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Eq(vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.False:
                        res = VCExpressionGenerator.False;
                        break;

                    case DeclKind.Ge:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Function(VCExpressionGenerator.GeOp, vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.Gt:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Gt(vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.IDiv:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Function(VCExpressionGenerator.DivOp, vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.Iff:
                        Debug.Assert(vcargs.Length == 2);
                        var l = create_let(args[0], vcargs[0]);
                        var r = create_let(args[1], vcargs[1]);
                        return(gen.And(gen.Implies(l, r), gen.Implies(r, l)));

                    case DeclKind.Implies:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Implies(vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.Ite:
                        Debug.Assert(vcargs.Length == 3);
                        res = gen.Function(VCExpressionGenerator.IfThenElseOp, vcargs[0], vcargs[1], vcargs[2]);
                        break;

                    case DeclKind.Le:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Function(VCExpressionGenerator.LeOp, vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.Lt:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Function(VCExpressionGenerator.LtOp, vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.Mod:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Function(VCExpressionGenerator.ModOp, vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.Mul:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Function(VCExpressionGenerator.MulOp, vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.Not:
                        Debug.Assert(vcargs.Length == 1);
                        res = gen.Not(vcargs[0]);
                        break;

                    case DeclKind.Or:
                        res = VCExpressionGenerator.False;
                        for (int i = 0; i < vcargs.Length; i++)
                        {
                            res = gen.OrSimp(res, vcargs[i]);
                        }
                        break;

                    case DeclKind.Select:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Select(vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.Store:
                        Debug.Assert(vcargs.Length == 3);
                        res = gen.Store(vcargs[0], vcargs[1], vcargs[2]);
                        break;

                    case DeclKind.Sub:
                        Debug.Assert(vcargs.Length == 2);
                        res = gen.Function(VCExpressionGenerator.SubOp, vcargs[0], vcargs[1]);
                        break;

                    case DeclKind.True:
                        res = VCExpressionGenerator.True;
                        break;

                    case DeclKind.Uminus:
                        Debug.Assert(vcargs.Length == 1);
                        var argzero = null;
                        if (vcargs[0].Type.IsInt)
                        {
                            argzero = gen.Integer(Basetypes.BigNum.ZERO);
                        }
                        else
                        {
                            argzero = gen.Real(Basetypes.BigDec.ZERO);
                        }
                        res = gen.Function(VCExpressionGenerator.SubOp, argzero, vcargs[0]);
                        break;

                    case DeclKind.ToInt:
                        Debug.Assert(vcargs.Length == 1);
                        res = gen.Function(VCExpressionGenerator.ToIntOp, vcargs[0]);
                        break;

                    case DeclKind.ToReal:
                        Debug.Assert(vcargs.Length == 1);
                        res = gen.Function(VCExpressionGenerator.ToRealOp, vcargs[0]);
                        break;

                    case DeclKind.Uninterpreted:
                        var name = arg.GetAppDecl().GetDeclName();
                        if (args.Length == 0)
                        {     // a 0-ary constant is a VCExprVar
                            if (!constants_inv.TryGetValue(arg, out res))
                            {
                                throw new Exception("Z3 returned unknown constant: " + name);
                            }
                        }
                        else
                        {
                            Function f;
                            if (!functions_inv.TryGetValue(arg.GetAppDecl(), out f))
                            {
                                throw new Exception("Z3 returned unknown function: " + name);
                            }
                            List <VCExpr> vcargsList = new List <VCExpr>(vcargs);
                            res = gen.Function(f, vcargsList);
                        }
                        break;

                    default:
                        throw new Exception("Unknown Z3 operator");
                    }
                    break;

                default:
                    Debug.Assert(false);
                    throw new Exception("Unknown Z3 AST kind");
                }

                memo.Add(arg, res);
                return(res);
            }