Example #1
0
 public static void CreateProver(string z3exe)
 {
     CommandLineOptions.Clo.Z3ExecutablePath = z3exe;
     CommandLineOptions.Clo.ApplyDefaultOptions();
     CommandLineOptions.Clo.StratifiedInlining = 1;
     prover = ProverInterface.CreateProver(new Program(), "log", CommandLineOptions.Clo.SimplifyLogFileAppend, -1);
 }
Example #2
0
        public ProverInterface.Outcome Verify(ProverInterface proverInterface, Dictionary <Variable, bool> assignment, out List <Counterexample> errors, int taskID = -1)
        {
            collector.examples.Clear();

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

            VCExpr vc = proverInterface.VCExprGen.Implies(BuildAxiom(proverInterface, assignment), conjecture);

            proverInterface.BeginCheck(descriptiveName, vc, handler);
            ProverInterface.Outcome proverOutcome = proverInterface.CheckOutcome(handler, taskID: taskID);

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

            stats.proverTime += queryTime;
            stats.numProverQueries++;
            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Outcome = " + proverOutcome);
                Console.WriteLine("Time taken = " + queryTime);
            }

            errors = collector.examples;
            return(proverOutcome);
        }
Example #3
0
 public static void InitializeVCGen(Program prog)
 {
     //create VC.vcgen/VC.proverInterface
     VC.vcgen = new VCGen(prog, CommandLineOptions.Clo.SimplifyLogFilePath,
                          CommandLineOptions.Clo.SimplifyLogFileAppend, new List <Checker>());
     VC.proverInterface = ProverInterface.CreateProver(prog, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, CommandLineOptions.Clo.ProverKillTime);
     VC.translator      = VC.proverInterface.Context.BoogieExprTranslator;
     VC.exprGen         = VC.proverInterface.Context.ExprGen;
     VC.collector       = new ConditionGeneration.CounterexampleCollector();
 }
Example #4
0
    public StratifiedVCGenBase(Program program, string /*?*/ logFilePath, bool appendLogFile, List<Checker> checkers,
      Action<Implementation> PassiveImplInstrumentation)
      : base(program, logFilePath, appendLogFile, checkers)
    {
      implName2StratifiedInliningInfo = new Dictionary<string, StratifiedInliningInfo>();
      prover = ProverInterface.CreateProver(program, logFilePath, appendLogFile, CommandLineOptions.Clo.TimeLimit);
      foreach (var impl in program.Implementations)
      {
        implName2StratifiedInliningInfo[impl.Name] = new StratifiedInliningInfo(impl, this, PassiveImplInstrumentation);
      }

      GenerateRecordFunctions();
    }
Example #5
0
        public HoudiniSession(Houdini houdini, VCGen vcgen, ProverInterface proverInterface, Program program, Implementation impl, HoudiniStatistics stats, int taskID = -1)
        {
            this.descriptiveName = impl.Name;
            this.stats           = stats;
            collector            = new ConditionGeneration.CounterexampleCollector();
            collector.OnProgress("HdnVCGen", 0, 0, 0.0);

            vcgen.ConvertCFG2DAG(impl, taskID: taskID);
            ModelViewInfo mvInfo;
            var           gotoCmdOrigins = vcgen.PassifyImpl(impl, out mvInfo);

            ExistentialConstantCollector ecollector;

            ExistentialConstantCollector.CollectHoudiniConstants(houdini, impl, out ecollector);
            this.houdiniAssertConstants   = ecollector.houdiniAssertConstants;
            this.houdiniAssumeConstants   = ecollector.houdiniAssumeConstants;
            this.explainConstantsNegative = ecollector.explainNegative;
            this.explainConstantsPositive = ecollector.explainPositive;
            this.constantToControl        = ecollector.constToControl;

            houdiniConstants = new HashSet <Variable>();
            houdiniConstants.UnionWith(houdiniAssertConstants);
            houdiniConstants.UnionWith(houdiniAssumeConstants);

            var    exprGen = proverInterface.Context.ExprGen;
            VCExpr controlFlowVariableExpr = CommandLineOptions.Clo.UseLabels ? null : exprGen.Integer(BigNum.ZERO);

            Dictionary <int, Absy> label2absy;

            conjecture = vcgen.GenerateVC(impl, controlFlowVariableExpr, out label2absy, proverInterface.Context);
            if (!CommandLineOptions.Clo.UseLabels)
            {
                VCExpr controlFlowFunctionAppl = exprGen.ControlFlowFunctionApplication(exprGen.Integer(BigNum.ZERO), exprGen.Integer(BigNum.ZERO));
                VCExpr eqExpr = exprGen.Eq(controlFlowFunctionAppl, exprGen.Integer(BigNum.FromInt(impl.Blocks[0].UniqueId)));
                conjecture = exprGen.Implies(eqExpr, conjecture);
            }

            Macro macro = new Macro(Token.NoToken, descriptiveName, new List <Variable>(), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Type.Bool), false));

            proverInterface.DefineMacro(macro, conjecture);
            conjecture = exprGen.Function(macro);

            if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Local)
            {
                handler = new VCGen.ErrorReporterLocal(gotoCmdOrigins, label2absy, impl.Blocks, vcgen.incarnationOriginMap, collector, mvInfo, proverInterface.Context, program);
            }
            else
            {
                handler = new VCGen.ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, vcgen.incarnationOriginMap, collector, mvInfo, proverInterface.Context, program);
            }
        }
Example #6
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);
        }
Example #7
0
        public void UpdateUnsatCore(ProverInterface proverInterface, Dictionary <Variable, bool> assignment)
        {
            DateTime now = DateTime.UtcNow;

            Boogie2VCExprTranslator exprTranslator = proverInterface.Context.BoogieExprTranslator;

            proverInterface.Push();
            proverInterface.Assert(conjecture, false);
            foreach (var v in assignment.Keys)
            {
                if (assignment[v])
                {
                    continue;
                }
                proverInterface.Assert(exprTranslator.LookupVariable(v), false);
            }

            List <Variable> assumptionVars  = new List <Variable>();
            List <VCExpr>   assumptionExprs = new List <VCExpr>();

            foreach (var v in assignment.Keys)
            {
                if (!assignment[v])
                {
                    continue;
                }
                assumptionVars.Add(v);
                assumptionExprs.Add(exprTranslator.LookupVariable(v));
            }

            List <int> unsatCore;

            ProverInterface.Outcome tmp = proverInterface.CheckAssumptions(assumptionExprs, out unsatCore, handler);
            System.Diagnostics.Debug.Assert(tmp == ProverInterface.Outcome.Valid);
            unsatCoreSet = new HashSet <Variable>();
            foreach (int i in unsatCore)
            {
                unsatCoreSet.Add(assumptionVars[i]);
            }
            proverInterface.Pop();

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

            stats.unsatCoreProverTime += unsatCoreQueryTime;
            stats.numUnsatCoreProverQueries++;
        }
Example #8
0
    public VCExpr Attach(StratifiedVC svc)
    {
      Contract.Assert(interfaceExprs.Count == svc.interfaceExprVars.Count);
      StratifiedInliningInfo info = svc.info;
      ProverInterface prover = info.vcgen.prover;
      VCExpressionGenerator gen = prover.VCExprGen;

      Dictionary<VCExprVar, VCExpr> substDict = new Dictionary<VCExprVar, VCExpr>();
      for (int i = 0; i < svc.interfaceExprVars.Count; i++)
      {
        VCExprVar v = svc.interfaceExprVars[i];
        substDict.Add(v, interfaceExprs[i]);
      }

      VCExprSubstitution subst =
        new VCExprSubstitution(substDict, new Dictionary<TypeVariable, Microsoft.Boogie.Type>());
      SubstitutingVCExprVisitor substVisitor = new SubstitutingVCExprVisitor(prover.VCExprGen);
      svc.vcexpr = substVisitor.Mutate(svc.vcexpr, subst);
      foreach (StratifiedCallSite scs in svc.CallSites)
      {
        List<VCExpr> newInterfaceExprs = new List<VCExpr>();
        foreach (VCExpr expr in scs.interfaceExprs)
        {
          newInterfaceExprs.Add(substVisitor.Mutate(expr, subst));
        }

        scs.interfaceExprs = newInterfaceExprs;
      }

      foreach (StratifiedCallSite scs in svc.RecordProcCallSites)
      {
        List<VCExpr> newInterfaceExprs = new List<VCExpr>();
        foreach (VCExpr expr in scs.interfaceExprs)
        {
          newInterfaceExprs.Add(substVisitor.Mutate(expr, subst));
        }

        scs.interfaceExprs = newInterfaceExprs;
      }

      //return gen.Implies(callSiteExpr, svc.vcexpr);
      return svc.vcexpr;
    }
Example #9
0
        public AbstractHoudini(Program program)
        {
            this.program              = program;
            this.impl2VC              = new Dictionary <string, VCExpr>();
            this.impl2EndStateVars    = new Dictionary <string, List <VCExpr> >();
            this.impl2CalleeSummaries = new Dictionary <string, List <Tuple <string, VCExprNAry> > >();
            this.impl2Summary         = new Dictionary <string, ISummaryElement>();
            this.name2Impl            = BoogieUtil.nameImplMapping(program);

            this.vcgen    = new VCGen(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, new List <Checker>());
            this.prover   = ProverInterface.CreateProver(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, CommandLineOptions.Clo.TimeLimit);
            this.reporter = new AbstractHoudiniErrorReporter();

            var impls = new List <Implementation>(
                program.TopLevelDeclarations.OfType <Implementation>());

            // Create all VCs
            impls
            .Iter(attachEnsures);

            impls
            .Iter(GenVC);
        }
Example #10
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);
            }
        }
Example #11
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;
    }
Example #12
0
    public void GenerateVCBoolControl()
    {
      Debug.Assert(!initialized);
      Debug.Assert(CommandLineOptions.Clo.SIBoolControlVC);

      // fix names for exit variables
      var outputVariables = new List<Variable>();
      var 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 AssumeCmd(Token.NoToken, Expr.BinaryTreeAnd(assertConjuncts));
      (exitAssertCmd as AssumeCmd).Attributes = new QKeyValue(Token.NoToken, "exitAssert", new List<object>(), null);

      // no need for label2absy
      label2absy = new Dictionary<int, Absy>();

      // Passify
      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;

      // add a boolean variable at each call site
      vcgen.InstrumentCallSites(impl);

      // typecheck
      var tc = new TypecheckingContext(null);
      impl.Typecheck(tc);

      ///////////////////
      // Generate the VC
      ///////////////////

      // block -> bool variable
      blockToControlVar = new Dictionary<Block, VCExprVar>();
      foreach (var b in impl.Blocks)
        blockToControlVar.Add(b, gen.Variable(b.Label + "_holds", Bpl.Type.Bool));

      vcexpr = VCExpressionGenerator.True;
      foreach (var b in impl.Blocks)
      {
        // conjoin all assume cmds
        VCExpr c = VCExpressionGenerator.True;
        foreach (var cmd in b.Cmds)
        {
          var acmd = cmd as AssumeCmd;
          if (acmd == null)
          {
            Debug.Assert(cmd is AssertCmd && (cmd as AssertCmd).Expr is LiteralExpr &&
                         ((cmd as AssertCmd).Expr as LiteralExpr).IsTrue);
            continue;
          }

          var expr = translator.Translate(acmd.Expr);
          c = gen.AndSimp(c, expr);
        }

        // block implies a disjunction of successors
        Debug.Assert(!(b.TransferCmd is ReturnExprCmd), "Not supported");
        var gc = b.TransferCmd as GotoCmd;
        if (gc != null)
        {
          VCExpr succ = VCExpressionGenerator.False;
          foreach (var sb in gc.labelTargets)
            succ = gen.OrSimp(succ, blockToControlVar[sb]);
          c = gen.AndSimp(c, succ);
        }
        else
        {
          // nothing to do
        }

        vcexpr = gen.AndSimp(vcexpr, gen.Eq(blockToControlVar[b], c));
      }

      // assert start block
      vcexpr = gen.AndSimp(vcexpr, blockToControlVar[impl.Blocks[0]]);

      //Console.WriteLine("VC of {0}: {1}", impl.Name, vcexpr);
      // Collect other information
      callSites = vcgen.CollectCallSites(impl);
      recordProcCallSites = vcgen.CollectRecordProcedureCallSites(impl);

      // record interface variables
      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));
      }

      privateExprVars.AddRange(blockToControlVar.Values);

      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));
      }
    }
Example #13
0
        // Prove candidates that hold (using an over-approximation, at the current inline depth).
        // Return the set of candidates proved correct
        static HashSet <string> ProveCandidates(ProverInterface prover, Dictionary <string, VCExpr> constantToAssertedExpr, List <Tuple <string, VCExpr, VCExpr> > constantToAssumedExpr, HashSet <string> candidates)
        {
            var remaining = new HashSet <string>(candidates);
            var reporter  = new EmptyErrorReporter();
            var failed    = new HashSet <string>();

            // for dual houdini, we have to iterate once around to the loop
            // even if remaining is empty
            bool secondtry = false;

            while (true)
            {
                remaining.ExceptWith(failed);

                if (remaining.Count == 0 && (!DualHoudini || secondtry))
                {
                    break;
                }

                if (remaining.Count == 0)
                {
                    secondtry = true;
                }
                else
                {
                    secondtry = false;
                }

                HoudiniStats.ProverCount++;
                HoudiniStats.Start("ProverTime");

                prover.Push();

                var nameToCallSiteVar           = new Dictionary <string, VCExprVar>();
                var callSiteVarToConstantToExpr = new Dictionary <string, Dictionary <string, VCExpr> >();

                if (!DualHoudini)
                {
                    // assert post
                    VCExpr toassert = VCExpressionGenerator.True;
                    foreach (var k in remaining)
                    {
                        toassert = prover.VCExprGen.And(toassert, constantToAssertedExpr[k]);
                    }

                    prover.Assert(toassert, false);
                }
                else
                {
                    // assume post of callees
                    foreach (var tup in constantToAssumedExpr)
                    {
                        if (!remaining.Contains(tup.Item1))
                        {
                            continue;
                        }

                        var csVar = tup.Item2 as VCExprVar;
                        Debug.Assert(csVar != null);
                        if (!nameToCallSiteVar.ContainsKey(csVar.ToString()))
                        {
                            nameToCallSiteVar.Add(csVar.ToString(), csVar);
                        }

                        if (!callSiteVarToConstantToExpr.ContainsKey(csVar.ToString()))
                        {
                            callSiteVarToConstantToExpr.Add(csVar.ToString(), new Dictionary <string, VCExpr>());
                        }
                        callSiteVarToConstantToExpr[csVar.ToString()].Add(tup.Item1, tup.Item3);
                    }

                    foreach (var tup in callSiteVarToConstantToExpr)
                    {
                        var expr = VCExpressionGenerator.False;
                        tup.Value.Values.Iter(e => expr = prover.VCExprGen.Or(expr, e));
                        prover.Assert(prover.VCExprGen.Implies(nameToCallSiteVar[tup.Key], expr), true);
                    }
                }

                Dictionary <string, VCExprVar> recordingBool = null;
                if (RobustAgainstEvaluate)
                {
                    recordingBool = new Dictionary <string, VCExprVar>();
                    VCExpr torecord = VCExpressionGenerator.True;
                    foreach (var k in remaining)
                    {
                        var b = prover.VCExprGen.Variable("recordingVar_" + k, Microsoft.Boogie.Type.Bool);
                        recordingBool.Add(k, b);
                        torecord = prover.VCExprGen.And(torecord, prover.VCExprGen.Eq(b, constantToAssertedExpr[k]));
                    }
                    prover.Assert(torecord, true);
                }

                prover.Check();
                var outcome = prover.CheckOutcomeCore(reporter);

                // check which ones failed
                if (outcome == ProverInterface.Outcome.Invalid || outcome == ProverInterface.Outcome.Undetermined)
                {
                    var removed = 0;
                    if (!DualHoudini)
                    {
                        foreach (var k in remaining)
                        {
                            var b = recordingBool == null ? (bool)prover.Evaluate(constantToAssertedExpr[k])
                                : (bool)prover.Evaluate(recordingBool[k]);

                            if (!b)
                            {
                                failed.Add(k);
                                if (dbg)
                                {
                                    Console.WriteLine("Failed: {0}", k);
                                }
                                removed++;
                            }
                        }
                    }
                    else
                    {
                        foreach (var tup in callSiteVarToConstantToExpr)
                        {
                            if (!(bool)prover.Evaluate(nameToCallSiteVar[tup.Key]))
                            {
                                continue;
                            }
                            // call site taken
                            foreach (var tup2 in tup.Value)
                            {
                                if ((bool)prover.Evaluate(tup2.Value))
                                {
                                    failed.Add(tup2.Key);
                                    if (dbg)
                                    {
                                        Console.WriteLine("Failed: {0}", tup2.Key);
                                    }
                                    removed++;
                                }
                            }
                        }
                        if (removed == 0)
                        {
                            throw new DualHoudiniFail("Nothing to drop");
                        }
                    }
                    Debug.Assert(removed != 0);
                    //if(dbg) Console.WriteLine("Query {0}: Invalid, {1} removed", HoudiniStats.ProverCount, removed);
                }

                HoudiniStats.Stop("ProverTime");
                prover.Pop();


                if (outcome == ProverInterface.Outcome.TimeOut || outcome == ProverInterface.Outcome.OutOfMemory)
                {
                    if (DualHoudini)
                    {
                        throw new DualHoudiniFail("Timeout");
                    }
                    failed.UnionWith(remaining);
                    break;
                }

                if (outcome == ProverInterface.Outcome.Valid)
                {
                    //if(dbg) Console.WriteLine("Query {0}: Valid", HoudiniStats.ProverCount);
                    break;
                }
            }

            remaining.ExceptWith(failed);

            return(remaining);
        }
Example #14
0
 public static void CloseProver()
 {
     prover.Close();
     CommandLineOptions.Clo.TheProverFactory.Close();
     prover = null;
 }
Example #15
0
        public ConcurrentHoudini(int id, Program program, HoudiniSession.HoudiniStatistics stats, string cexTraceFile = "houdiniCexTrace.bpl")
        {
            Contract.Assert(id >= 0);

            this.id           = id;
            this.program      = program;
            this.cexTraceFile = cexTraceFile;

            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Collecting existential constants...");
            }
            this.houdiniConstants = CollectExistentialConstants();

            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Building call graph...");
            }
            this.callGraph = Program.BuildCallGraph(program);
            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Number of implementations = {0}", callGraph.Nodes.Count);
            }

            if (CommandLineOptions.Clo.HoudiniUseCrossDependencies)
            {
                if (CommandLineOptions.Clo.Trace)
                {
                    Console.WriteLine("Computing procedure cross dependencies ...");
                }
                this.crossDependencies = new CrossDependencies(this.houdiniConstants);
                this.crossDependencies.Visit(program);
            }

            Inline();

            this.vcgen           = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, new List <Checker>());
            this.proverInterface = ProverInterface.CreateProver(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, CommandLineOptions.Clo.ProverKillTime, id);

            vcgenFailures = new HashSet <Implementation>();
            Dictionary <Implementation, HoudiniSession> houdiniSessions = new Dictionary <Implementation, HoudiniSession>();

            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Beginning VC generation for Houdini...");
            }
            foreach (Implementation impl in callGraph.Nodes)
            {
                try {
                    if (CommandLineOptions.Clo.Trace)
                    {
                        Console.WriteLine("Generating VC for {0}", impl.Name);
                    }
                    HoudiniSession session = new HoudiniSession(this, vcgen, proverInterface, program, impl, stats, taskID: id);
                    houdiniSessions.Add(impl, session);
                }
                catch (VCGenException) {
                    if (CommandLineOptions.Clo.Trace)
                    {
                        Console.WriteLine("VC generation failed");
                    }
                    vcgenFailures.Add(impl);
                }
            }
            this.houdiniSessions = new ReadOnlyDictionary <Implementation, HoudiniSession>(houdiniSessions);

            if (CommandLineOptions.Clo.ExplainHoudini)
            {
                // Print results of ExplainHoudini to a dotty file
                explainHoudiniDottyFile = new StreamWriter("explainHoudini.dot");
                explainHoudiniDottyFile.WriteLine("digraph explainHoudini {");
                foreach (var constant in houdiniConstants)
                {
                    explainHoudiniDottyFile.WriteLine("{0} [ label = \"{0}\" color=black ];", constant.Name);
                }
                explainHoudiniDottyFile.WriteLine("TimeOut [label = \"TimeOut\" color=red ];");
            }
        }
Example #16
0
        protected override bool UpdateAssignmentWorkList(ProverInterface.Outcome outcome,
            List<Counterexample> errors)
        {
            Contract.Assume(currentHoudiniState.Implementation != null);
              bool dequeue = true;

              switch (outcome) {
            case ProverInterface.Outcome.Valid:
            //yeah, dequeue
            break;

            case ProverInterface.Outcome.Invalid:
            Contract.Assume(errors != null);

            foreach (Counterexample error in errors) {
              RefutedAnnotation refutedAnnotation = ExtractRefutedAnnotation(error);
              // some candidate annotation removed
              if (refutedAnnotation != null) {
            refutedSharedAnnotations.TryAdd(refutedAnnotation.Constant.Name, refutedAnnotation);
            AddRelatedToWorkList(refutedAnnotation);
            UpdateAssignment(refutedAnnotation);
            dequeue = false;

            #region Extra debugging output
            if (CommandLineOptions.Clo.Trace) {
              using (var cexWriter = new System.IO.StreamWriter(cexTraceFile, true)) {
                cexWriter.WriteLine("Counter example for " + refutedAnnotation.Constant);
                cexWriter.Write(error.ToString());
                cexWriter.WriteLine();
                using (var writer = new Microsoft.Boogie.TokenTextWriter(cexWriter))
                  foreach (Microsoft.Boogie.Block blk in error.Trace)
                    blk.Emit(writer, 15);
                //cexWriter.WriteLine();
              }
            }
            #endregion
              }
            }

            if (ExchangeRefutedAnnotations()) dequeue = false;

            break;
            default:
            if (CommandLineOptions.Clo.Trace) {
              Console.WriteLine("Timeout/Spaceout while verifying " + currentHoudiniState.Implementation.Name);
            }

            HoudiniSession houdiniSession;
            houdiniSessions.TryGetValue(currentHoudiniState.Implementation, out houdiniSession);

            foreach (Variable v in houdiniSession.houdiniAssertConstants) {
              if (CommandLineOptions.Clo.Trace) {
            Console.WriteLine("Removing " + v);
              }
              currentHoudiniState.Assignment.Remove(v);
              currentHoudiniState.Assignment.Add(v, false);
              this.NotifyConstant(v.Name);
            }

            currentHoudiniState.addToBlackList(currentHoudiniState.Implementation.Name);
            break;
              }

              return dequeue;
        }