Beispiel #1
0
        /// <summary>
        /// As a side effect, updates "this.parent.CumulativeAssertionCount".
        /// </summary>
        public void BeginCheck(Checker checker, VerifierCallback callback, ModelViewInfo mvInfo, int no, int timeout, int rlimit)
        {
            Contract.Requires(checker != null);
            Contract.Requires(callback != null);

            splitNum = no;

            impl.Blocks = blocks;

            this.checker = checker;

            Dictionary <int, Absy> label2absy = new Dictionary <int, Absy>();

            ProverContext           ctx = checker.TheoremProver.Context;
            Boogie2VCExprTranslator bet = ctx.BoogieExprTranslator;
            var cc = new VCGen.CodeExprConversionClosure(label2absy, ctx);

            bet.SetCodeExprConverter(cc.CodeExprToVerificationCondition);

            var    exprGen = ctx.ExprGen;
            VCExpr controlFlowVariableExpr = exprGen.Integer(BigNum.ZERO);

            VCExpr vc = parent.GenerateVCAux(impl, controlFlowVariableExpr, label2absy, checker.TheoremProver.Context);

            Contract.Assert(vc != null);

            vc = QuantifierInstantiationEngine.Instantiate(impl, exprGen, bet, vc);

            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)));

            vc       = exprGen.Implies(eqExpr, vc);
            reporter = new VCGen.ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, parent.debugInfos, callback,
                                               mvInfo, this.Checker.TheoremProver.Context, parent.program);

            if (CommandLineOptions.Clo.TraceVerify && no >= 0)
            {
                Console.WriteLine("-- after split #{0}", no);
                Print();
            }

            string desc = cce.NonNull(impl.Name);

            if (no >= 0)
            {
                desc += "_split" + no;
            }
            checker.BeginCheck(desc, vc, reporter, timeout, rlimit, impl.RandomSeed);
        }
Beispiel #2
0
        private void GenVC(Implementation impl)
        {
            ModelViewInfo mvInfo;
            Dictionary<int, Absy> label2absy;
            var collector = new ICEHoudiniCounterexampleCollector(this);
            collector.OnProgress("HdnVCGen", 0, 0, 0.0);

            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Generating VC of {0}", impl.Name);
            }

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

            // Inline functions
            (new InlineFunctionCalls()).VisitBlockList(impl.Blocks);

            ExtractQuantifiedExprs(impl);
            StripOutermostForall(impl);

            //CommandLineOptions.Clo.PrintInstrumented = true;
            //var tt = new TokenTextWriter(Console.Out);
            //impl.Emit(tt, 0);
            //tt.Close();

            // Intercept the FunctionCalls of the existential functions, and replace them with Boolean constants
            var existentialFunctionNames = new HashSet<string>(existentialFunctions.Keys);
            var fv = new ReplaceFunctionCalls(existentialFunctionNames);
            fv.VisitBlockList(impl.Blocks);

            impl2functionsAsserted.Add(impl.Name, fv.functionsAsserted);
            impl2functionsAssumed.Add(impl.Name, fv.functionsAssumed);

            fv.functionsAssumed.Iter(f => function2implAssumed[f].Add(impl.Name));
            fv.functionsAsserted.Iter(f => function2implAsserted[f].Add(impl.Name));

            impl2FuncCalls.Add(impl.Name, fv.functionsUsed);
            fv.functionsUsed.Iter(tup => constant2FuncCall.Add(tup.Item2.Name, tup.Item3));

            HashSet<string> constantsAssumed = new HashSet<string>();
            fv.functionsUsed.Where(tup => impl2functionsAssumed[impl.Name].Contains(tup.Item1)).Iter(tup => constantsAssumed.Add(tup.Item2.Name));

            var gen = prover.VCExprGen;
            VCExpr controlFlowVariableExpr = CommandLineOptions.Clo.UseLabels ? null : gen.Integer(Microsoft.Basetypes.BigNum.ZERO);

            var vcexpr = vcgen.P_GenerateVC(impl, constantsAssumed, controlFlowVariableExpr, out label2absy, prover.Context);
            //var vcexpr = vcgen.GenerateVC(impl, controlFlowVariableExpr, out label2absy, prover.Context);

            if (!CommandLineOptions.Clo.UseLabels)
            {
                VCExpr controlFlowFunctionAppl = gen.ControlFlowFunctionApplication(gen.Integer(Microsoft.Basetypes.BigNum.ZERO), gen.Integer(Microsoft.Basetypes.BigNum.ZERO));
                VCExpr eqExpr = gen.Eq(controlFlowFunctionAppl, gen.Integer(Microsoft.Basetypes.BigNum.FromInt(impl.Blocks[0].UniqueId)));
                vcexpr = gen.Implies(eqExpr, vcexpr);
            }

            ProverInterface.ErrorHandler handler = null;
            if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Local)
                handler = new VCGen.ErrorReporterLocal(gotoCmdOrigins, label2absy, impl.Blocks, vcgen.incarnationOriginMap, collector, mvInfo, prover.Context, program);
            else
                handler = new VCGen.ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, vcgen.incarnationOriginMap, collector, mvInfo, prover.Context, program);

            impl2ErrorHandler.Add(impl.Name, Tuple.Create(handler, collector));

            //Console.WriteLine("VC of {0}: {1}", impl.Name, vcexpr);

            // Create a macro so that the VC can sit with the theorem prover
            Macro macro = new Macro(Token.NoToken, impl.Name + "Macro", new List<Variable>(), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Bpl.Type.Bool), false));
            prover.DefineMacro(macro, vcexpr);

            //Console.WriteLine("Function " + impl.Name + ":\n" + vcexpr.ToString());

            // Store VC
            impl2VC.Add(impl.Name, gen.Function(macro));

            // HACK: push the definitions of constants involved in function calls
            // It is possible that some constants only appear in function calls. Thus, when
            // they are replaced by Boolean constants, it is possible that (get-value) will
            // fail if the expression involves such constants. All we need to do is make sure
            // these constants are declared, because otherwise, semantically we are doing
            // the right thing.
            foreach (var tup in fv.functionsUsed)
            {
                // Ignore ones with bound varibles
                if (tup.Item2.InParams.Count > 0) continue;
                var tt = prover.Context.BoogieExprTranslator.Translate(tup.Item3);
                tt = prover.VCExprGen.Or(VCExpressionGenerator.True, tt);
                prover.Assert(tt, true);
            }
        }
Beispiel #3
0
        /// <summary>
        /// As a side effect, updates "this.parent.CumulativeAssertionCount".
        /// </summary>
        public void BeginCheck(Checker checker, VerifierCallback callback, ModelViewInfo mvInfo, int no, int timeout, int rlimit)
        {
            Contract.Requires(checker != null);
            Contract.Requires(callback != null);

            splitNo = no;

            impl.Blocks = blocks;

            this.checker = checker;

            Dictionary <int, Absy> label2absy = new Dictionary <int, Absy>();

            ProverContext           ctx = checker.TheoremProver.Context;
            Boogie2VCExprTranslator bet = ctx.BoogieExprTranslator;
            var cc = new VCGen.CodeExprConversionClosure(label2absy, ctx);

            bet.SetCodeExprConverter(cc.CodeExprToVerificationCondition);

            var    exprGen = ctx.ExprGen;
            VCExpr controlFlowVariableExpr = exprGen.Integer(BigNum.ZERO);

            #region proofgen
            TypePremiseEraserFactory typePremiseEraserFactory;
            switch (CommandLineOptions.Clo.TypeEncodingMethod)
            {
            case CommandLineOptions.TypeEncoding.Predicates:
                typePremiseEraserFactory = new TypePremiseEraserFactory(checker.VCExprGen, bet, true);
                break;

            case CommandLineOptions.TypeEncoding.Monomorphic:
                typePremiseEraserFactory = new TypePremiseEraserFactory(checker.VCExprGen, bet, false);
                break;

            default:
                throw new NotImplementedException();
            }
            ProofGenerationLayer.SetTypeEraserFactory(typePremiseEraserFactory);
            #endregion

            /* PROOF GEN: we pass "null" as the control flow variable expression, such that labels are not produced as they are
             * not relevant for proof generation of programs that verify */
            VCExpr vc = parent.GenerateVCAux(impl, null, label2absy, checker.TheoremProver.Context);
            Contract.Assert(vc != null);

            #region proofgen
            if (!(ctx is DeclFreeProverContext))
            {
                throw new NotImplementedException("Proof Generation only supports DeclFreeProverContext as context.");
            }

            var declFreeProverContext = ctx as DeclFreeProverContext;
            var premiseEraserProvider = typePremiseEraserFactory?.NewEraser();

            VCExpr eraseVC(VCExpr vc, int polarity)
            {
                return(!premiseEraserProvider.ProgramIsPolymorphic ? vc : premiseEraserProvider.EraseAndSortLet(vc, polarity));
            }

            VCExpr erasedVC     = eraseVC(vc, 1);
            VCExpr erasedAxioms = eraseVC(declFreeProverContext.Axioms, -1);

            VCExpr             typeAxioms   = null;
            List <VCAxiomInfo> vcAxiomsInfo = null;
            if (premiseEraserProvider.ProgramIsPolymorphic)
            {
                typeAxioms = premiseEraserProvider.AxiomBuilder.GetNewAxiomsAndInfo(out vcAxiomsInfo);
            }

            ProofGenerationLayer.VCGenerateAllProofs(
                erasedVC,
                erasedAxioms,
                typeAxioms,
                vcAxiomsInfo,
                checker.TheoremProver.VCExprGen,
                checker.TheoremProver.Context.BoogieExprTranslator,
                premiseEraserProvider?.AxiomBuilder);
            #endregion

            /* PROOF GEN: comment out label specific parts
             * 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)));
             * vc = exprGen.Implies(eqExpr, vc);
             */
            reporter = new VCGen.ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, parent.debugInfos, callback,
                                               mvInfo, this.Checker.TheoremProver.Context, parent.program);

            if (CommandLineOptions.Clo.TraceVerify && no >= 0)
            {
                Console.WriteLine("-- after split #{0}", no);
                Print();
            }

            string desc = cce.NonNull(impl.Name);
            if (no >= 0)
            {
                desc += "_split" + no;
            }
            checker.BeginCheck(desc, vc, reporter, timeout, rlimit, impl.RandomSeed);
        }