Ejemplo n.º 1
0
        public Counterexample ToCounterexample(ProverContext context)
        {
            Contract.Requires(context != null);
            Contract.Ensures(Contract.Result <Counterexample>() != null);

            List <Block> trace = new List <Block>();

            foreach (Block b in blocks)
            {
                Contract.Assert(b != null);
                trace.Add(b);
            }

            foreach (Block b in blocks)
            {
                Contract.Assert(b != null);
                foreach (Cmd c in b.Cmds)
                {
                    Contract.Assert(c != null);
                    if (c is AssertCmd)
                    {
                        return(VCGen.AssertCmdToCounterexample((AssertCmd)c, cce.NonNull(b.TransferCmd), trace, null, null, null, context));
                    }
                }
            }

            Contract.Assume(false);
            throw new cce.UnreachableException();
        }
Ejemplo n.º 2
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();
 }
Ejemplo n.º 3
0
 public Split(List <Block /*!*/> /*!*/ blocks, Dictionary <TransferCmd, ReturnCmd> /*!*/ gotoCmdOrigins,
              VCGen /*!*/ par, Implementation /*!*/ impl)
 {
     Contract.Requires(cce.NonNullElements(blocks));
     Contract.Requires(gotoCmdOrigins != null);
     Contract.Requires(par != null);
     Contract.Requires(impl != null);
     this.blocks         = blocks;
     this.gotoCmdOrigins = gotoCmdOrigins;
     this.parent         = par;
     this.impl           = impl;
     Interlocked.Increment(ref currentId);
 }
Ejemplo n.º 4
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);
            }
        }
Ejemplo n.º 5
0
        List <Cmd> SliceCmds(Block b)
        {
            Contract.Requires(b != null);
            Contract.Ensures(Contract.Result <List <Cmd> >() != null);

            List <Cmd> seq = b.Cmds;

            Contract.Assert(seq != null);
            if (!doingSlice && !ShouldAssumize(b))
            {
                return(seq);
            }
            List <Cmd> res = new List <Cmd>();

            foreach (Cmd c in seq)
            {
                Contract.Assert(c != null);
                AssertCmd a         = c as AssertCmd;
                Cmd       theNewCmd = c;
                bool      swap      = false;
                if (a != null)
                {
                    if (doingSlice)
                    {
                        double cost  = AssertionCost(a);
                        bool   first = (sliceLimit - cost) >= 0 || sliceInitialLimit == sliceLimit;
                        sliceLimit -= cost;
                        swap        = slicePos == first;
                    }
                    else if (assertToAssume)
                    {
                        swap = true;
                    }
                    else
                    {
                        Contract.Assert(false);
                        throw new cce.UnreachableException();
                    }

                    if (swap)
                    {
                        theNewCmd = VCGen.AssertTurnedIntoAssume(a);
                    }
                }

                res.Add(theNewCmd);
            }

            return(res);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Gets the errors and associated metadata after verifying the program.
        /// </summary>
        /// <returns>The metadata of the errors.</returns>
        public IEnumerable <RepairableError> GetErrors()
        {
            List <Error> errors = new List <Error>();

            VCGen gen = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, new List <Checker>());

            foreach (Declaration declaration in program.TopLevelDeclarations)
            {
                if (declaration is Implementation)
                {
                    Implementation        implementation = declaration as Implementation;
                    List <Counterexample> examples;

                    ConditionGeneration.Outcome outcome = gen.VerifyImplementation(implementation, out examples);
                    if (outcome == ConditionGeneration.Outcome.Errors)
                    {
                        foreach (Counterexample example in examples)
                        {
                            errors.AddRange(GenerateErrors(example, implementation));
                        }
                    }
                }
            }

            gen.Close();

            // there are no repairable errors that have a variable assigned to them
            if (!errors.Any(x => x is RepairableError && (x as RepairableError).Barriers.Any()))
            {
                if (errors.Any(x => x.CounterExample is AssertCounterexample))
                {
                    throw new AssertionException("Assertions do not hold!");
                }
                if (errors.Any(x => !(x is RepairableError)))
                {
                    throw new NonBarrierException("The program cannot be repaired since it has errors besides race and divergence errors!");
                }
                if (errors.Any(x => x is RepairableError))
                {
                    throw new RepairException("Encountered a counterexample without any barrier assignments!");
                }
            }

            return(errors.Where(x => x is RepairableError && (x as RepairableError).Barriers.Any())
                   .Select(x => x as RepairableError).ToList());
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
0
 private static ConditionGeneration CreateVCGen(Program program, List<Checker> checkers)
 {
     ConditionGeneration vcgen = null;
       if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed)
       {
     vcgen = new DCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, checkers);
       }
       else if (CommandLineOptions.Clo.FixedPointEngine != null)
       {
     vcgen = new FixedpointVC(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, checkers);
       }
       else if (CommandLineOptions.Clo.StratifiedInlining > 0)
       {
     vcgen = new StratifiedVCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, checkers);
       }
       else if (CommandLineOptions.Clo.SecureVcGen != null)
       {
       vcgen = new SecureVCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, checkers);
       }
       else
       {
       vcgen = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, checkers);
       }
       return vcgen;
 }
Ejemplo n.º 9
0
        public static List <Split /*!*/> FindManualSplits(Implementation /*!*/ impl,
                                                          Dictionary <TransferCmd, ReturnCmd> /*!*/ gotoCmdOrigins, VCGen /*!*/ par)
        {
            Contract.Requires(impl != null);
            Contract.Ensures(Contract.Result <List <Split> >() == null || cce.NonNullElements(Contract.Result <List <Split> >()));

            var splitPoints = new Dictionary <Block, int>();

            foreach (var b in impl.Blocks)
            {
                foreach (Cmd c in b.Cmds)
                {
                    var p = c as PredicateCmd;
                    if (p != null && QKeyValue.FindBoolAttribute(p.Attributes, "split_here"))
                    {
                        int count;
                        splitPoints.TryGetValue(b, out count);
                        splitPoints[b] = count + 1;
                    }
                }
            }

            if (splitPoints.Count() == 0)
            {
                // No manual split points here
                return(null);
            }

            List <Split> splits         = new List <Split>();
            Block        entryPoint     = impl.Blocks[0];
            var          newEntryBlocks = DoManualSplit(impl.Blocks, entryPoint, -1, splitPoints.Keys.Contains(entryPoint),
                                                        splitPoints.Keys);

            splits.Add(new Split(newEntryBlocks, gotoCmdOrigins, par,
                                 impl)); // REVIEW: Does gotoCmdOrigins need to be changed at all?

            foreach (KeyValuePair <Block, int> pair in splitPoints)
            {
                for (int i = 0; i < pair.Value; i++)
                {
                    bool blockInternalSplit =
                        i < pair.Value - 1; // There's at least one more split, after this one, in the current block
                    var   newBlocks = DoManualSplit(impl.Blocks, pair.Key, i, blockInternalSplit, splitPoints.Keys);
                    Split s         = new Split(newBlocks, gotoCmdOrigins, par,
                                                impl); // REVIEW: Does gotoCmdOrigins need to be changed at all?
                    splits.Add(s);
                }
            }

            return(splits);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Starting from the 0-index "split_here" annotation in begin, verifies until it reaches a subsequent "split_here" annotation
        /// Returns a list of blocks where all code not verified has asserts converted into assumes
        /// </summary>
        /// <param name="blocks">Implementation's collection of blocks</param>
        /// <param name="begin">Block containing the first split_here from which to start verifying</param>
        /// <param name="beginSplitId">0-based ID of the "split_here" annotation within begin at which to start verifying</param>
        /// <param name="blockInternalSplit">True if the entire split is contained within block begin</param>
        /// <param name="endPoints">Set of all blocks containing a "split_here" annotation</param>
        /// <returns></returns>
        // Note: Current implementation may over report errors.
        //       For example, if the control flow graph is a diamond (e.g., A -> B, C, B->D, C->D),
        //       and there is a split in B and an error in D, then D will be verified twice and hence report the error twice.
        //       Best solution may be to memoize blocks that have been fully verified and be sure not to verify them again
        private static List <Block> DoManualSplit(List <Block> blocks, Block begin, int beginSplitId,
                                                  bool blockInternalSplit, IEnumerable <Block> endPoints)
        {
            // Compute the set of blocks reachable from begin but not included in endPoints.  These will be verified in their entirety.
            var blocksToVerifyEntirely = new HashSet <Block>();
            var reachableEndPoints     =
                new HashSet <Block>(); // Reachable end points will be verified up to their first split point
            var todo = new Stack <Block>();

            todo.Push(begin);
            while (todo.Count > 0)
            {
                var currentBlock = todo.Pop();
                if (blocksToVerifyEntirely.Contains(currentBlock))
                {
                    continue;
                }
                blocksToVerifyEntirely.Add(currentBlock);
                var exit = currentBlock.TransferCmd as GotoCmd;
                if (exit != null)
                {
                    foreach (Block targetBlock in exit.labelTargets)
                    {
                        if (!endPoints.Contains(targetBlock))
                        {
                            todo.Push(targetBlock);
                        }
                        else
                        {
                            reachableEndPoints.Add(targetBlock);
                        }
                    }
                }
            }

            blocksToVerifyEntirely.Remove(begin);

            // Convert assumes to asserts in "unreachable" blocks, including portions of blocks containing "split_here"
            var newBlocks        = new List <Block>(blocks.Count()); // Copies of the original blocks
            var duplicator       = new Duplicator();
            var oldToNewBlockMap =
                new Dictionary <Block, Block>(blocks.Count()); // Maps original blocks to their new copies in newBlocks

            foreach (var currentBlock in blocks)
            {
                var newBlock = (Block)duplicator.VisitBlock(currentBlock);
                oldToNewBlockMap[currentBlock] = newBlock;
                newBlocks.Add(newBlock);

                if (!blockInternalSplit && blocksToVerifyEntirely.Contains(currentBlock))
                {
                    continue; // All reachable blocks must be checked in their entirety, so don't change anything
                }
                // Otherwise, we only verify a portion of the current block, so we'll need to look at each of its commands

                // !verify -> convert assert to assume
                var verify =
                    (currentBlock == begin &&
                     beginSplitId == -1
                    ) || // -1 tells us to start verifying from the very beginning (i.e., there is no split in the begin block)
                    (
                        reachableEndPoints
                        .Contains(currentBlock) && // This endpoint is reachable from begin, so we verify until we hit the first split point
                        !blockInternalSplit); // Don't bother verifying if all of the splitting is within the begin block
                var newCmds        = new List <Cmd>();
                var splitHereCount = 0;

                foreach (Cmd c in currentBlock.Cmds)
                {
                    var p = c as PredicateCmd;
                    if (p != null && QKeyValue.FindBoolAttribute(p.Attributes, "split_here"))
                    {
                        if (currentBlock == begin)
                        {
                            // Verify everything between the beginSplitId we were given and the next split
                            if (splitHereCount == beginSplitId)
                            {
                                verify = true;
                            }
                            else if (splitHereCount == beginSplitId + 1)
                            {
                                verify = false;
                            }
                        }
                        else
                        {
                            // We're in an endpoint so we stop verifying as soon as we hit a "split_here"
                            verify = false;
                        }

                        splitHereCount++;
                    }

                    var asrt = c as AssertCmd;
                    if (verify || asrt == null)
                    {
                        newCmds.Add(c);
                    }
                    else
                    {
                        newCmds.Add(VCGen.AssertTurnedIntoAssume(asrt));
                    }
                }

                newBlock.Cmds = newCmds;
            }

            // Patch the edges between the new blocks
            foreach (var oldBlock in blocks)
            {
                if (oldBlock.TransferCmd is ReturnCmd)
                {
                    continue;
                }

                var gotoCmd         = (GotoCmd)oldBlock.TransferCmd;
                var newLabelTargets = new List <Block>(gotoCmd.labelTargets.Count());
                var newLabelNames   = new List <string>(gotoCmd.labelTargets.Count());
                foreach (var target in gotoCmd.labelTargets)
                {
                    newLabelTargets.Add(oldToNewBlockMap[target]);
                    newLabelNames.Add(oldToNewBlockMap[target].Label);
                }

                oldToNewBlockMap[oldBlock].TransferCmd = new GotoCmd(gotoCmd.tok, newLabelNames, newLabelTargets);
            }

            return(newBlocks);
        }
Ejemplo n.º 11
0
        public ICEHoudini(Program program, string defaultDomainName, string filename)
        {
            this.program = program;
            this.impl2VC = new Dictionary<string, VCExpr>();
            this.impl2FuncCalls = new Dictionary<string, List<Tuple<string, Function, NAryExpr>>>();
            this.existentialFunctions = new Dictionary<string, Function>();
            this.name2Impl = new Dictionary<string, Implementation>();
            this.impl2functionsAsserted = new Dictionary<string, HashSet<string>>();
            this.impl2functionsAssumed = new Dictionary<string, HashSet<string>>();
            this.function2implAsserted = new Dictionary<string, HashSet<string>>();
            this.function2implAssumed = new Dictionary<string, HashSet<string>>();
            this.impl2ErrorHandler = new Dictionary<string, Tuple<ProverInterface.ErrorHandler, ICEHoudiniCounterexampleCollector>>();
            this.constant2FuncCall = new Dictionary<string, NAryExpr>();

            // Find the existential functions
            foreach (var func in program.TopLevelDeclarations.OfType<Function>()
                .Where(f => QKeyValue.FindBoolAttribute(f.Attributes, "existential")))
                existentialFunctions.Add(func.Name, func);

            // extract the constants in the program to determine the range for the template domain elements
            var extractConstants = new ExtractConstants();
            extractConstants.Visit(program);
            constantRange = extractConstants.maxConst + 1;

            TemplateParser.DSInit();
            this.function2Value = new Dictionary<string, ICEDomain>();
            counterExamples = new HashSet<Tuple<List<Tuple<string, List<Model.Element>>>, List<Tuple<string, List<Model.Element>>>>>();

            existentialFunctions.Keys.Iter(f => function2implAssumed.Add(f, new HashSet<string>()));
            existentialFunctions.Keys.Iter(f => function2implAsserted.Add(f, new HashSet<string>()));

            // type check
            existentialFunctions.Values.Iter(func =>
                {
                    if (func.OutParams.Count != 1 || !func.OutParams[0].TypedIdent.Type.IsBool)
                        throw new ICEHoudiniInternalError(string.Format("Existential function {0} must return bool", func.Name));
                    if(func.Body != null)
                        throw new ICEHoudiniInternalError(string.Format("Existential function {0} should not have a body", func.Name));
                    func.InParams.Iter(v =>
                    {
                        if (!v.TypedIdent.Type.IsInt)
                        {
                            throw new ICEHoudiniInternalError("TypeError: Illegal tpe, expecting int");
                        }
                    });
                });

            //if (CommandLineOptions.Clo.ProverKillTime > 0)
            //    CommandLineOptions.Clo.ProverOptions.Add(string.Format("TIME_LIMIT={0}", CommandLineOptions.Clo.ProverKillTime));

            Inline();

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

            this.proverTime = TimeSpan.Zero;
            this.numProverQueries = 0;
            this.z3LearnerTime = TimeSpan.Zero;
            this.numZ3LearnerQueries = 0;

            this.numPosExamples = 0;
            this.numNegCounterExamples = 0;
            this.numImplications = 0;

            #if C5
            this.C5index = 0;
            this.C5implications = new List<Tuple<int, int>>();
            this.C5samplePointToClassAttr = new Dictionary<dataPoint, int>();
            this.C5samplePointToIndex = new Dictionary<dataPoint, int>();
            this.C5repeatedPoints = 0;
            #endif
            this.filename = filename;

            var impls = program.TopLevelDeclarations.OfType<Implementation>().Where(
                    impl => impl != null && CommandLineOptions.Clo.UserWantsToCheckRoutine(cce.NonNull(impl.Name)) && !impl.SkipVerification);

            /*
            program.TopLevelDeclarations.OfType<Implementation>()
                .Where(impl => !impl.SkipVerification)
                .Iter(impl => name2Impl.Add(impl.Name, impl));
            */

            impls.Iter(impl => name2Impl.Add(impl.Name, impl));

            // Let's do VC Gen (and also build dependencies)
            name2Impl.Values.Iter(GenVC);
        }
Ejemplo n.º 12
0
        //bool realErrorEncountered;
        //bool newSamplesAdded;   // tracks whether new ICE samples added in a round or not?

        public MLHoudini(Program program, string config, string filename)
        {
            this.program = program;
            this.impl2VC = new Dictionary<string, VCExpr>();
            this.impl2FuncCalls = new Dictionary<string, List<Tuple<string, Function, NAryExpr>>>();
            this.existentialFunctions = new Dictionary<string, Function>();
            this.name2Impl = new Dictionary<string, Implementation>();
            this.impl2functionsAsserted = new Dictionary<string, HashSet<string>>();
            this.impl2functionsAssumed = new Dictionary<string, HashSet<string>>();
            this.function2implAsserted = new Dictionary<string, HashSet<string>>();
            this.function2implAssumed = new Dictionary<string, HashSet<string>>();
            this.impl2ErrorHandler = new Dictionary<string, Tuple<ProverInterface.ErrorHandler, MLHoudiniCounterexampleCollector>>();
            this.constant2FuncCall = new Dictionary<string, NAryExpr>();

            // Find the existential functions
            foreach (var func in program.TopLevelDeclarations.OfType<Function>()
                .Where(f => QKeyValue.FindBoolAttribute(f.Attributes, "existential")))
                existentialFunctions.Add(func.Name, func);

            // extract the constants in the program to determine the range for the template domain elements
            this.function2Value = new Dictionary<string, MLICEDomain>();
            foreach (var func in existentialFunctions.Values)
            {
                function2Value[func.Name] = new C5Domain(func.InParams);
            }

            counterExamples = new HashSet<Tuple<List<Tuple<string, List<Model.Element>>>, List<Tuple<string, List<Model.Element>>>>>();
            implicationCounterExamples = new HashSet<Tuple<List<Tuple<string, List<Model.Element>>>, List<Tuple<string, List<Model.Element>>>>>();
            bounds4cex = new List<int>();
            this.filename = filename;
            this.config = config;

            // config = alg1, alg2, alg3, alg4, smallcex_alg1, smallcex_alg2, ...
#if false
            int posOfUnderScore = this.config.IndexOf("_", 0);
            if (posOfUnderScore != -1)
            {
                // The teacher has to preferentially return small counter-examples
                Debug.Assert(posOfUnderScore == 8);
                //bounds4cex.Add(50);
                bounds4cex.Add(2);
                bounds4cex.Add(5);
                bounds4cex.Add(10);
                
                this.config = this.config.Substring(posOfUnderScore + 1);                
            }
            // else this.config remains unchanged
#else
            
            bounds4cex.Add(2);
            bounds4cex.Add(5);
            bounds4cex.Add(10);
            
#endif
            existentialFunctions.Keys.Iter(f => function2implAssumed.Add(f, new HashSet<string>()));
            existentialFunctions.Keys.Iter(f => function2implAsserted.Add(f, new HashSet<string>()));

            // type check
            existentialFunctions.Values.Iter(func =>
                {
                    if (func.OutParams.Count != 1 || !func.OutParams[0].TypedIdent.Type.IsBool)
                        throw new MLHoudiniInternalError(string.Format("Existential function {0} must return bool", func.Name));
                    if (func.Body != null)
                        throw new MLHoudiniInternalError(string.Format("Existential function {0} should not have a body", func.Name));
                    func.InParams.Iter(v =>
                    {
                        if (!v.TypedIdent.Type.IsInt && !v.TypedIdent.Type.IsBool)
                        {
                            throw new MLHoudiniInternalError("TypeError: Illegal tpe, expecting int or bool");
                        }
                    });
                });
           
            Inline();

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

            this.proverTime = TimeSpan.Zero;
            this.numProverQueries = 0;
            this.c5LearnerTime = TimeSpan.Zero;
            this.c5LearnerQueries = 0;
            this.totaltime = TimeSpan.Zero;
            this.jsontime = TimeSpan.Zero;

            this.numPosExamples = 0;
            this.numNegCounterExamples = 0;
            this.numImplications = 0;
            this.total_falsefalse_implications = 0;
            this.total_falsetrue_implications = 0;
            this.total_truetrue_implications = 0;
            this.totalTreeSize = 0;
            this.last_falsefalse_implications = 0;
            this.last_falsetrue_implications = 0;
            this.last_truetrue_implications = 0;
            this.lastTreeSize = 0;
            //this.posNegCexAdded = false;

#if C5
            this.c5DataPointsIndex = 0;
            this.c5samplePointToClassAttr = new Dictionary<dataPoint, int>();
            this.c5samplePointToIndex = new Dictionary<dataPoint, int>();
            this.c5implications = new List<Tuple<int, int>>();
#endif


            var impls = program.TopLevelDeclarations.OfType<Implementation>().Where(
                    impl => impl != null && CommandLineOptions.Clo.UserWantsToCheckRoutine(cce.NonNull(impl.Name)) && !impl.SkipVerification);

            /*
            program.TopLevelDeclarations.OfType<Implementation>()
                .Where(impl => !impl.SkipVerification)
                .Iter(impl => name2Impl.Add(impl.Name, impl));
            */

            impls.Iter(impl => name2Impl.Add(impl.Name, impl));

            // Call setupC5 only after the filename has been initialized!
            setupC5();

            // Let's do VC Gen (and also build dependencies)
            name2Impl.Values.Iter(GenVC);
        }
Ejemplo n.º 13
0
        private static ResultCounter VerifyProgram(Program program)
        {
            var counters = new ResultCounter();

            ConditionGeneration vcgen = null;

            try {
                vcgen = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, new List <Checker>());
            }
            catch (ProverException e) {
                GVUtil.IO.ErrorWriteLine("Fatal Error: ProverException: {0}", e);
                return(ResultCounter.GetNewCounterWithInternalError());
            }

            // operate on a stable copy, in case it gets updated while we're running
            var decls = program.TopLevelDeclarations.ToArray();

            foreach (Declaration decl in decls)
            {
                Contract.Assert(decl != null);

                int prevAssertionCount = vcgen.CumulativeAssertionCount;

                Implementation impl = decl as Implementation;
                if (impl != null && CommandLineOptions.Clo.UserWantsToCheckRoutine(cce.NonNull(impl.Name)) && !impl.SkipVerification)
                {
                    List <Counterexample /*!*/> /*?*/ errors;

                    DateTime start = new DateTime(); // to please compiler's definite assignment rules
                    if (CommandLineOptions.Clo.Trace)
                    {
                        start = DateTime.UtcNow;
                        if (CommandLineOptions.Clo.Trace)
                        {
                            Console.WriteLine();
                            Console.WriteLine("Verifying {0} ...", impl.Name);
                        }
                    }

                    VCGen.Outcome outcome;
                    try {
                        outcome = vcgen.VerifyImplementation(impl, out errors);
                    }
                    catch (VCGenException e) {
                        GVUtil.IO.ReportBplError(impl, string.Format("Error BP5010: {0}  Encountered in implementation {1}.", e.Message, impl.Name), true, true);
                        errors  = null;
                        outcome = VCGen.Outcome.Inconclusive;
                    }
                    catch (UnexpectedProverOutputException upo) {
                        GVUtil.IO.AdvisoryWriteLine("Advisory: {0} SKIPPED because of internal error: unexpected prover output: {1}", impl.Name, upo.Message);
                        errors  = null;
                        outcome = VCGen.Outcome.Inconclusive;
                    }

                    string   timeIndication = "";
                    DateTime end            = DateTime.UtcNow;
                    TimeSpan elapsed        = end - start;
                    if (CommandLineOptions.Clo.Trace)
                    {
                        int poCount = vcgen.CumulativeAssertionCount - prevAssertionCount;
                        timeIndication = string.Format("  [{0:F3} s, {1} proof obligation{2}]  ", elapsed.TotalSeconds, poCount, poCount == 1 ? "" : "s");
                    }
                    KernelAnalyser.ProcessOutcome(program, impl.Name, outcome, errors, timeIndication, ref counters);

                    if (outcome == VCGen.Outcome.Errors || CommandLineOptions.Clo.Trace)
                    {
                        Console.Out.Flush();
                    }
                }
            }

            vcgen.Close();
            cce.NonNull(CommandLineOptions.Clo.TheProverFactory).Close();

            GVUtil.IO.WriteTrailer(counters);
            return(counters);
        }
Ejemplo n.º 14
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);
              }
        }