internal static string GetTagFromNonCandidateAttributes(QKeyValue Attributes)
 {
   string tag = QKeyValue.FindStringAttribute(Attributes, "staged_houdini_tag");
   return tag;
 }
        private Block Abstract(Block b)
        {
            var newCmds = new List <Cmd>();

            foreach (Cmd c in b.Cmds)
            {
                if (c is CallCmd)
                {
                    var call = c as CallCmd;

                    if (QKeyValue.FindBoolAttribute(call.Attributes, "atomic"))
                    {
                        // Discard the call
                        Debug.Assert(call.Ins.Count >= 1);
                        var ie = call.Ins[0] as IdentifierExpr;
                        Debug.Assert(ie != null);
                        Debug.Assert(verifier.ArrayModelledAdversarially(ie.Decl));
                        continue;
                    }

                    for (int i = 0; i < call.Ins.Count; i++)
                    {
                        ReadCollector rc = new ReadCollector(verifier.KernelArrayInfo);
                        rc.Visit(call.Ins[i]);
                        bool foundAdversarial = false;
                        foreach (AccessRecord ar in rc.NonPrivateAccesses)
                        {
                            if (verifier.ArrayModelledAdversarially(ar.V))
                            {
                                foundAdversarial = true;
                                break;
                            }
                        }

                        if (foundAdversarial)
                        {
                            LocalVariable lv = new LocalVariable(
                                Token.NoToken,
                                new TypedIdent(Token.NoToken, "_abstracted_call_arg_" + abstractedCallArgCounter, call.Ins[i].Type));
                            abstractedCallArgCounter++;
                            newLocalVars.Add(lv);
                            newCmds.Add(new HavocCmd(
                                            Token.NoToken,
                                            new List <IdentifierExpr>(new IdentifierExpr[] { new IdentifierExpr(Token.NoToken, lv) })));
                            call.Ins[i] = new IdentifierExpr(Token.NoToken, lv);
                        }
                    }
                }

                if (c is AssignCmd)
                {
                    AssignCmd assign = c as AssignCmd;

                    var lhss = new List <AssignLhs>();
                    var rhss = new List <Expr>();

                    foreach (var lhsRhs in assign.Lhss.Zip(assign.Rhss))
                    {
                        AssignLhs     lhs = lhsRhs.Item1;
                        Expr          rhs = lhsRhs.Item2;
                        ReadCollector rc  = new ReadCollector(verifier.KernelArrayInfo);
                        rc.Visit(rhs);

                        bool foundAdversarial = false;
                        foreach (AccessRecord ar in rc.NonPrivateAccesses)
                        {
                            if (verifier.ArrayModelledAdversarially(ar.V))
                            {
                                foundAdversarial = true;
                                break;
                            }
                        }

                        if (foundAdversarial)
                        {
                            Debug.Assert(lhs is SimpleAssignLhs);
                            newCmds.Add(new HavocCmd(c.tok, new List <IdentifierExpr>(new IdentifierExpr[] { (lhs as SimpleAssignLhs).AssignedVariable })));
                            continue;
                        }

                        WriteCollector wc = new WriteCollector(verifier.KernelArrayInfo);
                        wc.Visit(lhs);
                        if (wc.FoundNonPrivateWrite())
                        {
                            if (verifier.ArrayModelledAdversarially(wc.GetAccess().V))
                            {
                                continue; // Just remove the write
                            }
                        }

                        lhss.Add(lhs);
                        rhss.Add(rhs);
                    }

                    if (lhss.Count != 0)
                    {
                        newCmds.Add(new AssignCmd(assign.tok, lhss, rhss));
                    }

                    continue;
                }

                newCmds.Add(c);
            }

            b.Cmds = newCmds;
            return(b);
        }
Beispiel #3
0
        public static bool MatchSig(Implementation toMatch, DeclWithFormals dwf, Program boogieProgram, out QKeyValue toMatchAnyParamsAttributes, out int anyParamsPosition, out QKeyValue toMatchAnyParamsAttributesOut, out int anyParamsPositionOut, out Dictionary <Declaration, Expr> paramSubstitution, bool matchPtrs)
        {
            toMatchAnyParamsAttributes    = null;
            anyParamsPosition             = int.MaxValue;
            toMatchAnyParamsAttributesOut = null;
            anyParamsPositionOut          = int.MaxValue;
            paramSubstitution             = new Dictionary <Declaration, Expr>();

            if (!ExprMatchVisitor.AreAttributesASubset(toMatch.Attributes, dwf.Attributes))
            {
                return(false);
            }

            // match procedure name
            // Positive filters: AnyProcedure, NameMatches, ByName
            if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.AnyProcedure, toMatch.Attributes))
            {
                //do nothing
            }
            else if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.NameMatches, toMatch.Attributes))
            {
                var nmAttrParams = BoogieUtil.getAttr(ExprMatchVisitor.BoogieKeyWords.NameMatches, toMatch.Attributes);
                Debug.Assert(nmAttrParams.Count() == 1, "Expecting exactly one #NameMatches attribute, found " + nmAttrParams.Count());
                var regex = nmAttrParams.First().ToString();
                var m     = Regex.Match(dwf.Name, regex);
                if (m.Success)
                {
                    //do nothing
                }
                else
                {
                    return(false);
                }
            }
            else if (toMatch.Name != dwf.Name)
            {
                return(false);
            }

            //Negative filter: NameNotMatches (can be multiple of them)
            if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.NameNotMatches, toMatch.Attributes))
            {
                //get the params from multiple matching key
                var getAttrRepeated = new Func <QKeyValue, string, IList <IList <object> > >((attr, name) =>
                {
                    var ret = new List <IList <object> >();
                    for (; attr != null; attr = attr.Next)
                    {
                        if (attr.Key == name)
                        {
                            ret.Add(attr.Params);
                        }
                    }
                    return(ret);
                });

                var nmAttrParams = getAttrRepeated(toMatch.Attributes, ExprMatchVisitor.BoogieKeyWords.NameNotMatches);
                foreach (var nm in nmAttrParams)
                {
                    if (Regex.Match(dwf.Name, nm.First().ToString()).Success)
                    {
                        return(false);
                    }
                }
            }

            // if the procedure name is matched, it may still be that we are looking only for stubs
            if (BoogieUtil.checkAttrExists(ExprMatchVisitor.BoogieKeyWords.NoImplementation, toMatch.Attributes))
            {
                foreach (var i in boogieProgram.Implementations)
                {
                    if (i.Name == dwf.Name)
                    {
                        return(false);
                    }
                }
            }

            Procedure dwfProc = null;

            if (dwf is Implementation)
            {
                dwfProc = ((Implementation)dwf).Proc;
            }
            else if (dwf is Procedure)
            {
                dwfProc = (Procedure)dwf;
            }

            if (!MatchParams(ref toMatchAnyParamsAttributes, ref anyParamsPosition, paramSubstitution, toMatch.InParams, toMatch.Proc.InParams, dwf.InParams, dwfProc.InParams, matchPtrs))
            {
                return(false);
            }

            if (!MatchParams(ref toMatchAnyParamsAttributesOut, ref anyParamsPositionOut, paramSubstitution, toMatch.OutParams, toMatch.Proc.OutParams, dwf.OutParams, dwfProc.OutParams, matchPtrs))
            {
                return(false);
            }

            return(true);
        }
Beispiel #4
0
        public static Program InjectDualityProof(Program program, string DualityProofFile)
        {
            Program DualityProof;

            using (var st = new System.IO.StreamReader(DualityProofFile))
            {
                var s = ParserHelper.Fill(st, new List <string>());
                // replace %i by bound_var_i
                for (int i = 0; i <= 9; i++)
                {
                    s = s.Replace(string.Format("%{0}", i), string.Format("pm_bv_{0}", i));
                }
                var v = Parser.Parse(s, DualityProofFile, out DualityProof);
                if (v != 0)
                {
                    throw new Exception("Failed to parse " + DualityProofFile);
                }
            }


            var implToContracts = new Dictionary <string, List <Expr> >();

            foreach (var proc in DualityProof.TopLevelDeclarations.OfType <Procedure>())
            {
                implToContracts.Add(proc.Name, new List <Expr>());
                foreach (var ens in proc.Ensures)
                {
                    implToContracts[proc.Name].AddRange(GetExprConjunctions(ens.Condition));
                }
            }

            var counter = 0;
            var GetExistentialConstant = new Func <Constant>(() =>
            {
                var c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken,
                                                                   "DualityProofConst" + (counter++), Microsoft.Boogie.Type.Bool), false);
                c.AddAttribute("existential");
                return(c);
            });

            var constsToAdd = new List <Declaration>();

            foreach (var proc in program.TopLevelDeclarations.OfType <Procedure>())
            {
                if (!implToContracts.ContainsKey(proc.Name))
                {
                    continue;
                }
                if (QKeyValue.FindBoolAttribute(proc.Attributes, "nohoudini"))
                {
                    continue;
                }

                foreach (var expr in implToContracts[proc.Name])
                {
                    var c = GetExistentialConstant();
                    constsToAdd.Add(c);
                    proc.Ensures.Add(new Ensures(false,
                                                 Expr.Imp(Expr.Ident(c), expr)));
                }
            }

            program.TopLevelDeclarations.AddRange(constsToAdd);

            return(program);
        }
Beispiel #5
0
        public static int RealMain(String[] args)
        {
            // Debug log output goes to standard error.
            Debug.Listeners.Add(new ExceptionThrowingTextWritierTraceListener(Console.Error));

            // FIXME: Urgh... we are forced to use Boogie's command line
            // parser becaue the Boogie program resolver/type checker
            // is dependent on the parser being used...EURGH!
            CommandLineOptions.Install(new Microsoft.Boogie.CommandLineOptions());


            var options = new CmdLineOpts();

            if (!CommandLine.Parser.Default.ParseArguments(args, options))
            {
                Console.WriteLine("Failed to parse args");
                ExitWith(ExitCode.COMMAND_LINE_ERROR);
            }

            if (options.boogieProgramPath == null)
            {
                Console.WriteLine("A boogie program must be specified. See --help");
                ExitWith(ExitCode.COMMAND_LINE_ERROR);
            }

            if (!File.Exists(options.boogieProgramPath))
            {
                Console.WriteLine("Boogie program \"" + options.boogieProgramPath + "\" does not exist");
                ExitWith(ExitCode.COMMAND_LINE_ERROR);
            }


            Program program = null;

            if (options.Defines != null)
            {
                foreach (var define in options.Defines)
                {
                    Console.WriteLine("Adding define \"" + define + "\" to Boogie parser");
                }
            }

            int errors = Microsoft.Boogie.Parser.Parse(options.boogieProgramPath, options.Defines, out program);

            if (errors != 0)
            {
                Console.WriteLine("Failed to parse");
                ExitWith(ExitCode.PARSE_ERROR);
            }

            errors = program.Resolve();

            if (errors != 0)
            {
                Console.WriteLine("Failed to resolve.");
                ExitWith(ExitCode.RESOLVE_ERROR);
            }

            if (options.useModSetTransform > 0)
            {
                // This is useful for Boogie Programs produced by the GPUVerify tool that
                // have had instrumentation added that invalidates the modset attached to
                // procedures. By running the analysis we may modify the modsets attached to
                // procedures in the program to be correct so that Boogie's Type checker doesn't
                // produce an error.
                var modsetAnalyser = new ModSetCollector();
                modsetAnalyser.DoModSetAnalysis(program);
            }

            errors = program.Typecheck();

            if (errors != 0)
            {
                Console.WriteLine("Failed to Typecheck.");
                ExitWith(ExitCode.TYPECHECK_ERROR);
            }


            IStateScheduler scheduler = GetScheduler(options);

            // Limit Depth if necessary
            if (options.MaxDepth >= 0)
            {
                scheduler = new LimitExplicitDepthScheduler(scheduler, options.MaxDepth);
                Console.WriteLine("Using Depth limit:{0}", options.MaxDepth);
            }

            if (options.FailureLimit < 0)
            {
                Console.Error.WriteLine("FailureLimit must be >= 0");
                ExitWith(ExitCode.COMMAND_LINE_ERROR);
            }


            Console.WriteLine("Using Scheduler: {0}", scheduler.ToString());

            var           nonSpeculativeterminationCounter = new TerminationCounter(TerminationCounter.CountType.ONLY_NON_SPECULATIVE);
            var           speculativeTerminationCounter    = new TerminationCounter(TerminationCounter.CountType.ONLY_SPECULATIVE);
            IExprBuilder  builder      = new SimpleExprBuilder(/*immutable=*/ true);
            ISymbolicPool symbolicPool = null;

            if (options.useSymbolicPoolCache > 0)
            {
                throw new Exception("DON'T USE THIS. IT'S BROKEN");
                symbolicPool = new CachingSymbolicPool();
            }
            else
            {
                symbolicPool = new SimpleSymbolicPool();
            }

            Console.WriteLine("Using Symbolic Pool: {0}", symbolicPool.ToString());

            if (options.useConstantFolding > 0)
            {
                if (options.ConstantCaching > 0)
                {
                    Console.WriteLine("Using ConstantCachingExprBuilder");
                    builder = new ConstantCachingExprBuilder(builder);
                }

                builder = new ConstantFoldingExprBuilder(builder);
            }

            // Destroy the solver when we stop using it
            using (var solver = BuildSolverChain(options))
            {
                Executor executor = new Executor(program, scheduler, solver, builder, symbolicPool);

                executor.ExecutorTimeoutReached += delegate(object sender, Executor.ExecutorTimeoutReachedArgs eventArgs)
                {
                    TimeoutHit = true; // Record so we can set the exitcode appropriately later
                    Console.Error.WriteLine("Timeout hit. Trying to kill Executor (may wait for solver)");
                };

                // Check all implementations exist and build list of entry points to execute
                var entryPoints = new List <Implementation>();

                // This is specific to GPUVerify
                if (options.gpuverifyEntryPoints)
                {
                    var kernels = program.TopLevelDeclarations.OfType <Implementation>().Where(impl => QKeyValue.FindBoolAttribute(impl.Attributes, "kernel"));
                    foreach (var kernel in kernels)
                    {
                        entryPoints.Add(kernel);
                    }

                    if (entryPoints.Count() == 0)
                    {
                        Console.WriteLine("Could not find any kernel entry points");
                        ExitWith(ExitCode.ENTRY_POINT_NOT_FOUND_ERROR);
                    }
                }
                else
                {
                    // Set main as default.
                    if (options.entryPoints == null)
                    {
                        options.entryPoints = new List <string>()
                        {
                            "main"
                        }
                    }
                    ;

                    foreach (var implString in options.entryPoints)
                    {
                        Implementation entry = program.TopLevelDeclarations.OfType <Implementation>().Where(i => i.Name == implString).FirstOrDefault();
                        if (entry == null)
                        {
                            Console.WriteLine("Could not find implementation \"" + implString + "\" to use as entry point");
                            ExitWith(ExitCode.ENTRY_POINT_NOT_FOUND_ERROR);
                        }
                        entryPoints.Add(entry);
                    }
                }

                if (options.useInstructionPrinter)
                {
                    Console.WriteLine("Installing instruction printer");
                    var instrPrinter = new InstructionPrinter(Console.Out);
                    instrPrinter.Connect(executor);
                }

                if (options.useCallSequencePrinter)
                {
                    Console.WriteLine("Installing call sequence printer");
                    var callPrinter = new CallPrinter(Console.Out);
                    callPrinter.Connect(executor);
                }

                if (options.gotoAssumeLookAhead > 0)
                {
                    executor.UseGotoLookAhead = true;
                }
                else
                {
                    executor.UseGotoLookAhead = false;
                }

                if (options.ForkAtPredicatedAssign)
                {
                    executor.UseForkAtPredicatedAssign = true;
                }

                if (options.CheckEntryRequires > 0)
                {
                    executor.CheckEntryRequires = true;
                }
                else
                {
                    Console.WriteLine("Warning: Requires at the entry point are not being checked");
                    executor.CheckEntryRequires = false;
                }

                if (options.CheckEntryAxioms > 0)
                {
                    executor.CheckEntryAxioms = true;
                }
                else
                {
                    Console.WriteLine("Warning: Axioms are not being checked");
                    executor.CheckEntryAxioms = false;
                }

                if (options.CheckUniqueVariableDecls > 0)
                {
                    executor.CheckUniqueVariableDecls = true;
                }
                else
                {
                    Console.WriteLine("Warning: Unique variables are not being checked");
                    executor.CheckUniqueVariableDecls = false;
                }

                if (options.GlobalDDE > 0)
                {
                    executor.UseGlobalDDE = true;
                    Console.WriteLine("WARNING: Using GlobalDDE. This may remove unsatisfiable axioms");
                }
                else
                {
                    executor.UseGlobalDDE = false;
                }

                // Just print a message about break points for now.
                executor.BreakPointReached += BreakPointPrinter.handleBreakPoint;

                // Write to the console about context changes
                var contextChangeReporter = new ContextChangedReporter();
                contextChangeReporter.Connect(executor);

                var stateHandler = new TerminationConsoleReporter();
                stateHandler.Connect(executor);

                nonSpeculativeterminationCounter.Connect(executor);
                speculativeTerminationCounter.Connect(executor);

                if (options.FileLogging > 0)
                {
                    SetupFileLoggers(options, executor, solver);
                }

                SetupTerminationCatchers(executor);
                ApplyFilters(executor, options);

                if (options.FailureLimit > 0)
                {
                    var failureLimiter = new FailureLimiter(options.FailureLimit);
                    failureLimiter.Connect(executor);
                    Console.WriteLine("Using failure limit of {0}", options.FailureLimit);
                }

                try
                {
                    // Supply our own PassManager for preparation so we can hook into its events
                    executor.PreparationPassManager = GetPassManager(options);

                    foreach (var entryPoint in entryPoints)
                    {
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        Console.WriteLine("Entering Implementation " + entryPoint.Name + " as entry point");
                        Console.ResetColor();
                        executor.Run(entryPoint, options.timeout);
                    }
                }
                catch (InitialStateTerminated)
                {
                    if (options.CatchExceptions == 0)
                    {
                        throw;
                    }
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Error.WriteLine("The initial state terminated. Execution cannot continue");
                    Console.ResetColor();
                    ExitWith(ExitCode.INITIAL_STATE_TERMINATED);
                }
                catch (RecursiveFunctionDetectedException rfdException)
                {
                    if (options.CatchExceptions == 0)
                    {
                        throw;
                    }
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Error.WriteLine("Detected the following recursive functions");
                    foreach (var function in rfdException.Functions)
                    {
                        Console.Error.Write(function.Name + ": ");
                        if (function.Body != null)
                        {
                            Console.Error.WriteLine(function.Body.ToString());
                        }

                        if (function.DefinitionAxiom != null)
                        {
                            Console.Error.WriteLine(function.DefinitionAxiom.Expr.ToString());
                        }
                    }
                    Console.ResetColor();
                    ExitWith(ExitCode.RECURSIVE_FUNCTIONS_FOUND_ERROR);
                }
                catch (OutOfMemoryException e)
                {
                    if (options.CatchExceptions == 0)
                    {
                        throw;
                    }
                    Console.Error.WriteLine("Ran out of memory!");
                    Console.Error.WriteLine(e.ToString());
                    ExitWith(ExitCode.OUT_OF_MEMORY);
                }
                catch (NotImplementedException e)
                {
                    if (options.CatchExceptions == 0)
                    {
                        throw;
                    }
                    Console.Error.WriteLine("Feature not implemented!");
                    Console.Error.WriteLine(e.ToString());
                    ExitWith(ExitCode.NOT_IMPLEMENTED_EXCEPTION);
                }
                catch (NotSupportedException e)
                {
                    if (options.CatchExceptions == 0)
                    {
                        throw;
                    }
                    Console.Error.WriteLine("Feature not supported!");
                    Console.Error.WriteLine(e.ToString());
                    ExitWith(ExitCode.NOT_SUPPORTED_EXCEPTION);
                }


                Console.WriteLine("Finished executing");
                DumpStats(executor, solver, nonSpeculativeterminationCounter, speculativeTerminationCounter);
            }

            if (TimeoutHit)
            {
                ExitWith(nonSpeculativeterminationCounter.NumberOfFailures > 0 ? ExitCode.ERRORS_TIMEOUT : ExitCode.NO_ERRORS_TIMEOUT);
                throw new InvalidOperationException("Unreachable");
            }

            var exitCode = nonSpeculativeterminationCounter.NumberOfFailures > 0 ? ExitCode.ERRORS_NO_TIMEOUT : ExitCode.NO_ERRORS_NO_TIMEOUT;

            if (exitCode == ExitCode.NO_ERRORS_NO_TIMEOUT)
            {
                // If no errors were found we may need to pick a different exit code
                // because path exploration may not have been exhaustive due to speculative paths
                // or hitting a bound. This isn't perfect because we may hit a bound and have speculative
                // paths so we could use either exit code in this case.
                if (nonSpeculativeterminationCounter.DisallowedSpeculativePaths > 0 || speculativeTerminationCounter.NumberOfTerminatedStates > 0)
                {
                    exitCode = ExitCode.NO_ERRORS_NO_TIMEOUT_BUT_FOUND_SPECULATIVE_PATHS;
                    Console.WriteLine("NOTE: Bugs may have been missed!");
                }
                else if (nonSpeculativeterminationCounter.DisallowedPathDepths > 0)
                {
                    exitCode = ExitCode.NO_ERRORS_NO_TIMEOUT_BUT_HIT_BOUND;
                    Console.WriteLine("NOTE: Bugs may have been missed!");
                }
            }
            ExitWith(exitCode);
            return((int)exitCode); // This is required to keep the compiler happy.
        }
Beispiel #6
0
        public static HashSet <string> RunHoudini(Program program, bool RobustAgainstEvaluate = false)
        {
            HoudiniStats.Reset();
            HoudiniInlining.RobustAgainstEvaluate = DualHoudini? false : RobustAgainstEvaluate;
            if (DualHoudini && CommandLineOptions.Clo.InlineDepth > 0)
            {
                throw new DualHoudiniFail("InlineDepth not supported");
            }

            // Gather existential constants
            var CandidateConstants = new Dictionary <string, Constant>();

            program.TopLevelDeclarations.OfType <Constant>()
            .Where(c => QKeyValue.FindBoolAttribute(c.Attributes, "existential"))
            .Iter(c => CandidateConstants.Add(c.Name, c));

            // Create a function, one for each impl, for book-keeping
            var CandidateFuncsAssumed  = new Dictionary <string, Function>();
            var CandidateFuncsAsserted = new Dictionary <string, Function>();
            var AssumeToAssert         = new Dictionary <Function, Function>();

            program.TopLevelDeclarations.OfType <Implementation>()
            .Iter(impl =>
            {
                var fassumed  = GetCandidateFunc(CandidateFuncPrefix, impl.Name);
                var fasserted = GetCandidateFunc(CandidateFuncAssertedPrefix, impl.Name);
                CandidateFuncsAssumed.Add(impl.Name, fassumed);
                CandidateFuncsAsserted.Add(impl.Name, fasserted);
                AssumeToAssert.Add(fassumed, fasserted);
            });


            // Tag the ensures so we can keep track of them
            var iterimpls = program.TopLevelDeclarations.OfType <Implementation>().ToList();

            iterimpls.Iter(impl => InstrumentEnsures(program, impl, CandidateFuncsAssumed[impl.Name], CandidateConstants));

            //BoogieUtil.PrintProgram(program, "h2.bpl");

            var RewriteAssumedToAssertedAction = new Action <Implementation>(impl =>
            {
                // Rewrite functions that are asserted
                var rewrite = new RewriteFuncs(AssumeToAssert);
                foreach (var blk in impl.Blocks)
                {
                    foreach (var acmd in blk.Cmds.OfType <AssertCmd>())
                    {
                        acmd.Expr = rewrite.VisitExpr(acmd.Expr);
                    }
                }

                var funcs = new HashSet <Function>(CandidateFuncsAssumed.Values);
                // Move call-site constant to the first argument of CandidateFuncs
                foreach (var blk in impl.Blocks)
                {
                    Expr cv = null;
                    // walk backwards
                    for (int i = blk.Cmds.Count - 1; i >= 0; i--)
                    {
                        var acmd = blk.Cmds[i] as AssumeCmd;
                        if (acmd == null)
                        {
                            continue;
                        }

                        if (QKeyValue.FindBoolAttribute(acmd.Attributes, StratifiedVCGenBase.callSiteVarAttr))
                        {
                            cv = acmd.Expr;
                            continue;
                        }

                        InsertControlVar.Apply(acmd.Expr, funcs, cv);
                    }
                }

                //impl.Emit(new TokenTextWriter(Console.Out), 0);
            });

            program.AddTopLevelDeclarations(CandidateFuncsAssumed.Values);
            program.AddTopLevelDeclarations(CandidateFuncsAsserted.Values);

            var callgraph     = BoogieUtil.GetCallGraph(program);
            var impl2Priority = DeterminePriorityOrder(program, callgraph);
            var impls         = new HashSet <string>(impl2Priority.Keys);

            HoudiniStats.Start("VCGen");

            // VC Gen
            var hi = new HoudiniInlining(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, RewriteAssumedToAssertedAction);

            HoudiniStats.Stop("VCGen");

            var worklist = new SortedSet <Tuple <int, string> >();

            impl2Priority.Iter(tup => worklist.Add(Tuple.Create(tup.Value, tup.Key)));

            // Current assignment: set of true constants
            // Initially: everything is true
            var assignment = new HashSet <string>(CandidateConstants.Keys);

            var prover   = hi.prover;
            var reporter = new EmptyErrorReporter();

            // assert true to flush all one-time axioms, decls, etc
            prover.Assert(VCExpressionGenerator.True, true);

            HoudiniStats.Start("MainLoop");

            // worklist algorithm
            while (worklist.Any())
            {
                var implName = worklist.First().Item2;
                worklist.Remove(worklist.First());

                if (dbg)
                {
                    Console.WriteLine("Processing " + implName);
                }
                prover.LogComment("Processing " + implName);

                prover.Push();

                var hvc           = new HoudiniVC(hi.implName2StratifiedInliningInfo[implName], impls, assignment);
                var openCallSites = new HashSet <StratifiedCallSite>(hvc.CallSites);
                prover.Assert(hvc.vcexpr, true);

                var candidates = !DualHoudini ? new HashSet <string>(hvc.constantToAssertedExpr.Keys.Where(k => assignment.Contains(k))) :
                                 new HashSet <string>(hvc.constantToAssumedExpr.Select(t => t.Item1).Where(k => assignment.Contains(k)));

                var provedTrue  = new HashSet <string>();
                var provedFalse = new HashSet <string>();
                var idepth      = Math.Max(0, CommandLineOptions.Clo.InlineDepth);

                // iterate over idepth
                while (true)
                {
                    // Part 1: over-approximate
                    var proved = ProveCandidates(prover, hvc.constantToAssertedExpr, hvc.constantToAssumedExpr, candidates.Difference(provedTrue.Union(provedFalse)));
                    provedTrue.UnionWith(proved);
                    if (dbg)
                    {
                        Console.WriteLine("Proved {0} candiates at depth {1}", proved.Count, CommandLineOptions.Clo.InlineDepth - idepth);
                    }

                    if (idepth == 0 || openCallSites.Count == 0)
                    {
                        break;
                    }

                    // Part 2: under-approximate
                    prover.Push();
                    foreach (var cs in openCallSites)
                    {
                        prover.Assert(cs.callSiteExpr, false);
                    }

                    var remaining = candidates.Difference(provedTrue.Union(provedFalse));
                    proved = ProveCandidates(prover, hvc.constantToAssertedExpr, hvc.constantToAssumedExpr, remaining);
                    provedFalse.UnionWith(remaining.Difference(proved));
                    if (dbg)
                    {
                        Console.WriteLine("Disproved {0} candiates at depth {1}", remaining.Difference(proved).Count, CommandLineOptions.Clo.InlineDepth - idepth);
                    }

                    prover.Pop();

                    // resolved all?
                    if (candidates.Difference(provedTrue.Union(provedFalse)).Count == 0)
                    {
                        break;
                    }

                    // Inline one level
                    idepth--;
                    var nextOpenCallSites = new HashSet <StratifiedCallSite>();
                    foreach (var cs in openCallSites)
                    {
                        var callee   = new HoudiniVC(hi.implName2StratifiedInliningInfo[cs.callSite.calleeName], impls, assignment);
                        var calleevc = cs.Attach(callee);
                        prover.Assert(prover.VCExprGen.Implies(cs.callSiteExpr, calleevc), true);
                        nextOpenCallSites.UnionWith(callee.CallSites);
                    }
                    openCallSites = nextOpenCallSites;
                }

                prover.Pop();

                var failed = candidates.Difference(provedTrue);
                assignment.ExceptWith(failed);

                if (failed.Count != 0)
                {
                    // add dependencies back into the worklist
                    if (!DualHoudini)
                    {
                        foreach (var caller in callgraph.Predecessors(implName))
                        {
                            worklist.Add(Tuple.Create(impl2Priority[caller], caller));
                        }
                    }
                    else
                    {
                        foreach (var caller in callgraph.Successors(implName))
                        {
                            worklist.Add(Tuple.Create(impl2Priority[caller], caller));
                        }
                    }
                }
            }

            HoudiniStats.Stop("MainLoop");

            hi.Close();

            return(assignment);
        }
Beispiel #7
0
        static void removeTemplates(string file, string outfile)
        {
            var program = ParseProgram(file);

            foreach (var proc in program.TopLevelDeclarations.OfType <Procedure>().Where(p => QKeyValue.FindBoolAttribute(p.Attributes, "template")))
            {
                proc.Ensures.RemoveAll(ens => !ens.Free);
            }

            var sw = new StreamWriter(outfile, false);
            var tw = new TokenTextWriter(sw);

            program.Emit(tw);
            sw.Close();
            tw.Close();
        }
Beispiel #8
0
        public void DualiseKernel()
        {
            List <Declaration> newTopLevelDeclarations = new List <Declaration>();

            // This loop really does have to be a "for(i ...)" loop.  The reason is
            // that dualisation may add additional functions to the program, which
            // get put into the program's top level declarations and also need to
            // be dualised.
            var decls = Verifier.Program.TopLevelDeclarations.ToList();

            for (int i = 0; i < UpdateDeclarationsAndCountTotal(decls); i++)
            {
                Declaration d = decls[i];

                if (d is Axiom)
                {
                    VariableDualiser vd1       = new VariableDualiser(1, Verifier, null);
                    VariableDualiser vd2       = new VariableDualiser(2, Verifier, null);
                    Axiom            newAxiom1 = vd1.VisitAxiom(d.Clone() as Axiom);
                    Axiom            newAxiom2 = vd2.VisitAxiom(d.Clone() as Axiom);
                    newTopLevelDeclarations.Add(newAxiom1);

                    // Test whether dualisation had any effect by seeing whether the new
                    // axioms are syntactically indistinguishable.  If they are, then there
                    // is no point adding the second axiom.
                    if (!newAxiom1.ToString().Equals(newAxiom2.ToString()))
                    {
                        newTopLevelDeclarations.Add(newAxiom2);
                    }

                    continue;
                }

                if (d is Procedure)
                {
                    DualiseProcedure(d as Procedure);
                    newTopLevelDeclarations.Add(d);
                    continue;
                }

                if (d is Implementation)
                {
                    DualiseImplementation(d as Implementation);
                    newTopLevelDeclarations.Add(d);
                    continue;
                }

                if (d is Variable &&
                    ((d as Variable).IsMutable ||
                     Verifier.IsThreadLocalIdConstant(d as Variable) ||
                     (Verifier.IsGroupIdConstant(d as Variable) && !GPUVerifyVCGenCommandLineOptions.OnlyIntraGroupRaceChecking)))
                {
                    var v = d as Variable;

                    if (v.Name.Contains("_NOT_ACCESSED_") || v.Name.Contains("_ARRAY_OFFSET"))
                    {
                        newTopLevelDeclarations.Add(v);
                        continue;
                    }

                    if (QKeyValue.FindBoolAttribute(v.Attributes, "atomic_usedmap"))
                    {
                        if (QKeyValue.FindBoolAttribute(v.Attributes, "atomic_group_shared") &&
                            !GPUVerifyVCGenCommandLineOptions.OnlyIntraGroupRaceChecking)
                        {
                            var type = new MapType(
                                Token.NoToken,
                                new List <TypeVariable>(),
                                new List <Microsoft.Boogie.Type> {
                                Microsoft.Boogie.Type.GetBvType(1)
                            },
                                v.TypedIdent.Type);
                            var newV = new GlobalVariable(
                                Token.NoToken, new TypedIdent(Token.NoToken, v.Name, type));
                            newV.Attributes = v.Attributes;
                            newTopLevelDeclarations.Add(newV);
                        }
                        else
                        {
                            newTopLevelDeclarations.Add(v);
                        }

                        continue;
                    }

                    if (Verifier.KernelArrayInfo.GetGlobalArrays(true).Contains(v))
                    {
                        newTopLevelDeclarations.Add(v);
                        continue;
                    }

                    if (Verifier.KernelArrayInfo.GetGroupSharedArrays(true).Contains(v))
                    {
                        if (!GPUVerifyVCGenCommandLineOptions.OnlyIntraGroupRaceChecking)
                        {
                            var type = new MapType(
                                Token.NoToken,
                                new List <TypeVariable>(),
                                new List <Microsoft.Boogie.Type> {
                                Microsoft.Boogie.Type.GetBvType(1)
                            },
                                v.TypedIdent.Type);
                            var newV = new GlobalVariable(
                                Token.NoToken, new TypedIdent(Token.NoToken, v.Name, type));
                            newV.Attributes = v.Attributes;
                            newTopLevelDeclarations.Add(newV);
                        }
                        else
                        {
                            newTopLevelDeclarations.Add(v);
                        }

                        continue;
                    }

                    newTopLevelDeclarations.Add(new VariableDualiser(1, Verifier, null).VisitVariable((Variable)v.Clone()));
                    if (!QKeyValue.FindBoolAttribute(v.Attributes, "race_checking"))
                    {
                        newTopLevelDeclarations.Add(new VariableDualiser(2, Verifier, null).VisitVariable((Variable)v.Clone()));
                    }

                    continue;
                }

                newTopLevelDeclarations.Add(d);
            }

            Verifier.Program.TopLevelDeclarations = newTopLevelDeclarations;
        }
Beispiel #9
0
        private void MakeDual(List <Cmd> cs, Cmd c)
        {
            if (c is CallCmd)
            {
                CallCmd call = c as CallCmd;

                if (QKeyValue.FindBoolAttribute(call.Proc.Attributes, "barrier_invariant"))
                {
                    // There may be a predicate, and there must be an invariant expression and at least one instantiation
                    Debug.Assert(call.Ins.Count >= (2 + (Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1)));
                    var biDescriptor = new UnaryBarrierInvariantDescriptor(
                        Verifier.UniformityAnalyser.IsUniform(call.callee) ? Expr.True : call.Ins[0],
                        Expr.Neq(call.Ins[Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1], Verifier.IntRep.GetZero(Verifier.IntRep.GetIntType(1))),
                        call.Attributes,
                        this,
                        procName,
                        Verifier);

                    for (var i = 1 + (Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1); i < call.Ins.Count; i++)
                    {
                        biDescriptor.AddInstantiationExpr(call.Ins[i]);
                    }

                    barrierInvariantDescriptors.Add(biDescriptor);
                    return;
                }

                if (QKeyValue.FindBoolAttribute(call.Proc.Attributes, "binary_barrier_invariant"))
                {
                    // There may be a predicate, and there must be an invariant expression and at least one pair of
                    // instantiation expressions
                    Debug.Assert(call.Ins.Count >= (3 + (Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1)));
                    var biDescriptor = new BinaryBarrierInvariantDescriptor(
                        Verifier.UniformityAnalyser.IsUniform(call.callee) ? Expr.True : call.Ins[0],
                        Expr.Neq(call.Ins[Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1], Verifier.IntRep.GetZero(Verifier.IntRep.GetIntType(1))),
                        call.Attributes,
                        this,
                        procName,
                        Verifier);

                    for (var i = 1 + (Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1); i < call.Ins.Count; i += 2)
                    {
                        biDescriptor.AddInstantiationExprPair(call.Ins[i], call.Ins[i + 1]);
                    }

                    barrierInvariantDescriptors.Add(biDescriptor);
                    return;
                }

                if (GPUVerifier.IsBarrier(call.Proc))
                {
                    // Assert barrier invariants
                    foreach (var biIDescriptor in barrierInvariantDescriptors)
                    {
                        QKeyValue sourceLocationInfo = biIDescriptor.GetSourceLocationInfo();
                        cs.Add(biIDescriptor.GetAssertCmd());
                        var vd = new VariableDualiser(1, Verifier, procName);
                        if (GPUVerifyVCGenCommandLineOptions.BarrierAccessChecks)
                        {
                            foreach (Expr accessExpr in biIDescriptor.GetAccessedExprs())
                            {
                                var assert = new AssertCmd(Token.NoToken, accessExpr, MakeThreadSpecificAttributes(sourceLocationInfo, 1));
                                assert.Attributes = new QKeyValue(
                                    Token.NoToken, "barrier_invariant_access_check", new List <object> {
                                    Expr.True
                                }, assert.Attributes);
                                cs.Add(vd.VisitAssertCmd(assert));
                            }
                        }
                    }
                }

                List <Expr> uniformNewIns    = new List <Expr>();
                List <Expr> nonUniformNewIns = new List <Expr>();

                for (int i = 0; i < call.Ins.Count; i++)
                {
                    if (Verifier.UniformityAnalyser.knowsOf(call.callee) &&
                        Verifier.UniformityAnalyser.IsUniform(call.callee, Verifier.UniformityAnalyser.GetInParameter(call.callee, i)))
                    {
                        uniformNewIns.Add(call.Ins[i]);
                    }
                    else if (!Verifier.OnlyThread2.Contains(call.callee))
                    {
                        nonUniformNewIns.Add(new VariableDualiser(1, Verifier, procName).VisitExpr(call.Ins[i]));
                    }
                }

                for (int i = 0; i < call.Ins.Count; i++)
                {
                    if (!(Verifier.UniformityAnalyser.knowsOf(call.callee) &&
                          Verifier.UniformityAnalyser.IsUniform(call.callee, Verifier.UniformityAnalyser.GetInParameter(call.callee, i))) &&
                        !Verifier.OnlyThread1.Contains(call.callee))
                    {
                        nonUniformNewIns.Add(new VariableDualiser(2, Verifier, procName).VisitExpr(call.Ins[i]));
                    }
                }

                List <Expr> newIns = uniformNewIns;
                newIns.AddRange(nonUniformNewIns);

                List <IdentifierExpr> uniformNewOuts    = new List <IdentifierExpr>();
                List <IdentifierExpr> nonUniformNewOuts = new List <IdentifierExpr>();
                for (int i = 0; i < call.Outs.Count; i++)
                {
                    if (Verifier.UniformityAnalyser.knowsOf(call.callee) &&
                        Verifier.UniformityAnalyser.IsUniform(call.callee, Verifier.UniformityAnalyser.GetOutParameter(call.callee, i)))
                    {
                        uniformNewOuts.Add(call.Outs[i]);
                    }
                    else
                    {
                        nonUniformNewOuts.Add(new VariableDualiser(1, Verifier, procName).VisitIdentifierExpr(call.Outs[i].Clone() as IdentifierExpr) as IdentifierExpr);
                    }
                }

                for (int i = 0; i < call.Outs.Count; i++)
                {
                    if (!(Verifier.UniformityAnalyser.knowsOf(call.callee) &&
                          Verifier.UniformityAnalyser.IsUniform(call.callee, Verifier.UniformityAnalyser.GetOutParameter(call.callee, i))))
                    {
                        nonUniformNewOuts.Add(new VariableDualiser(2, Verifier, procName).VisitIdentifierExpr(call.Outs[i].Clone() as IdentifierExpr) as IdentifierExpr);
                    }
                }

                List <IdentifierExpr> newOuts = uniformNewOuts;
                newOuts.AddRange(nonUniformNewOuts);

                CallCmd newCallCmd = new CallCmd(call.tok, call.callee, newIns, newOuts);

                newCallCmd.Proc = call.Proc;

                newCallCmd.Attributes = call.Attributes;

                if (newCallCmd.callee.StartsWith("_LOG_ATOMIC"))
                {
                    QKeyValue curr = newCallCmd.Attributes;
                    if (curr.Key.StartsWith("arg"))
                    {
                        newCallCmd.Attributes = new QKeyValue(Token.NoToken, curr.Key, new List <object>(new object[] { Dualise(curr.Params[0] as Expr, 1) }), curr.Next);
                    }

                    for (curr = newCallCmd.Attributes; curr.Next != null; curr = curr.Next)
                    {
                        if (curr.Next.Key.StartsWith("arg"))
                        {
                            curr.Next = new QKeyValue(Token.NoToken, curr.Next.Key, new List <object>(new object[] { Dualise(curr.Next.Params[0] as Expr, 1) }), curr.Next.Next);
                        }
                    }
                }
                else if (newCallCmd.callee.StartsWith("_CHECK_ATOMIC"))
                {
                    QKeyValue curr = newCallCmd.Attributes;
                    if (curr.Key.StartsWith("arg"))
                    {
                        newCallCmd.Attributes = new QKeyValue(Token.NoToken, curr.Key, new List <object>(new object[] { Dualise(curr.Params[0] as Expr, 2) }), curr.Next);
                    }

                    for (curr = newCallCmd.Attributes; curr.Next != null; curr = curr.Next)
                    {
                        if (curr.Next.Key.StartsWith("arg"))
                        {
                            curr.Next = new QKeyValue(Token.NoToken, curr.Next.Key, new List <object>(new object[] { Dualise(curr.Next.Params[0] as Expr, 2) }), curr.Next.Next);
                        }
                    }
                }

                cs.Add(newCallCmd);

                if (GPUVerifier.IsBarrier(call.Proc))
                {
                    foreach (var biDescriptor in barrierInvariantDescriptors)
                    {
                        foreach (var instantiation in biDescriptor.GetInstantiationCmds())
                        {
                            cs.Add(instantiation);
                        }
                    }

                    barrierInvariantDescriptors.Clear();
                }
            }
            else if (c is AssignCmd)
            {
                AssignCmd assign = c as AssignCmd;

                var vd1 = new VariableDualiser(1, Verifier, procName);
                var vd2 = new VariableDualiser(2, Verifier, procName);

                List <AssignLhs> lhss1 = new List <AssignLhs>();
                List <AssignLhs> lhss2 = new List <AssignLhs>();

                List <Expr> rhss1 = new List <Expr>();
                List <Expr> rhss2 = new List <Expr>();

                foreach (var pair in assign.Lhss.Zip(assign.Rhss))
                {
                    if (pair.Item1 is SimpleAssignLhs &&
                        Verifier.UniformityAnalyser.IsUniform(
                            procName, (pair.Item1 as SimpleAssignLhs).AssignedVariable.Name))
                    {
                        lhss1.Add(pair.Item1);
                        rhss1.Add(pair.Item2);
                    }
                    else
                    {
                        lhss1.Add(vd1.Visit(pair.Item1.Clone() as AssignLhs) as AssignLhs);
                        lhss2.Add(vd2.Visit(pair.Item1.Clone() as AssignLhs) as AssignLhs);
                        rhss1.Add(vd1.VisitExpr(pair.Item2.Clone() as Expr));
                        rhss2.Add(vd2.VisitExpr(pair.Item2.Clone() as Expr));
                    }
                }

                Debug.Assert(lhss1.Count > 0);
                cs.Add(new AssignCmd(Token.NoToken, lhss1, rhss1));

                if (lhss2.Count > 0)
                {
                    cs.Add(new AssignCmd(Token.NoToken, lhss2, rhss2));
                }
            }
            else if (c is HavocCmd)
            {
                HavocCmd havoc = c as HavocCmd;
                Debug.Assert(havoc.Vars.Count() == 1);

                HavocCmd newHavoc;

                var idents = new List <IdentifierExpr>
                {
                    (IdentifierExpr) new VariableDualiser(1, Verifier, procName).VisitIdentifierExpr(havoc.Vars[0].Clone() as IdentifierExpr),
                    (IdentifierExpr) new VariableDualiser(2, Verifier, procName).VisitIdentifierExpr(havoc.Vars[0].Clone() as IdentifierExpr)
                };
                newHavoc = new HavocCmd(havoc.tok, idents);

                cs.Add(newHavoc);
            }
            else if (c is AssertCmd)
            {
                AssertCmd a = c as AssertCmd;

                if (QKeyValue.FindBoolAttribute(a.Attributes, "sourceloc") ||
                    QKeyValue.FindBoolAttribute(a.Attributes, "block_sourceloc") ||
                    QKeyValue.FindBoolAttribute(a.Attributes, "array_bounds"))
                {
                    // This is just a location marker, so we do not dualise it
                    cs.Add(new AssertCmd(
                               Token.NoToken,
                               new VariableDualiser(1, Verifier, procName).VisitExpr(a.Expr.Clone() as Expr),
                               (QKeyValue)a.Attributes.Clone()));
                }
                else
                {
                    var isUniform = Verifier.UniformityAnalyser.IsUniform(procName, a.Expr);
                    cs.Add(MakeThreadSpecificAssert(a, 1));
                    if (!GPUVerifyVCGenCommandLineOptions.AsymmetricAsserts && !ContainsAsymmetricExpression(a.Expr) && !isUniform)
                    {
                        cs.Add(MakeThreadSpecificAssert(a, 2));
                    }
                }
            }
            else if (c is AssumeCmd)
            {
                AssumeCmd ass = c as AssumeCmd;

                if (QKeyValue.FindStringAttribute(ass.Attributes, "captureState") != null)
                {
                    cs.Add(c);
                }
                else if (QKeyValue.FindBoolAttribute(ass.Attributes, "backedge"))
                {
                    AssumeCmd newAss = new AssumeCmd(
                        c.tok,
                        Expr.Or(
                            new VariableDualiser(1, Verifier, procName).VisitExpr(ass.Expr.Clone() as Expr),
                            new VariableDualiser(2, Verifier, procName).VisitExpr(ass.Expr.Clone() as Expr)));
                    newAss.Attributes = ass.Attributes;
                    cs.Add(newAss);
                }
                else if (QKeyValue.FindBoolAttribute(ass.Attributes, "atomic_refinement"))
                {
                    // Generate the following:
                    // havoc v$1, v$2;
                    // assume !_USED[offset$1][v$1];
                    // _USED[offset$1][v$1] := true;
                    // assume !_USED[offset$2][v$2];
                    // _USED[offset$2][v$2] := true;
                    Expr variable = QKeyValue.FindExprAttribute(ass.Attributes, "variable");
                    Expr offset   = QKeyValue.FindExprAttribute(ass.Attributes, "offset");

                    List <Expr> offsets =
                        Enumerable.Range(1, 2).Select(x => new VariableDualiser(x, Verifier, procName).VisitExpr(offset.Clone() as Expr)).ToList();
                    List <Expr> vars =
                        Enumerable.Range(1, 2).Select(x => new VariableDualiser(x, Verifier, procName).VisitExpr(variable.Clone() as Expr)).ToList();
                    IdentifierExpr arrayRef =
                        new IdentifierExpr(Token.NoToken, Verifier.FindOrCreateUsedMap(QKeyValue.FindStringAttribute(ass.Attributes, "arrayref"), vars[0].Type));
                    bool isShared = QKeyValue.FindBoolAttribute(arrayRef.Decl.Attributes, "atomic_group_shared");

                    foreach (int i in Enumerable.Range(0, 2))
                    {
                        Expr assumeSelect = arrayRef;

                        if (isShared && !GPUVerifyVCGenCommandLineOptions.OnlyIntraGroupRaceChecking)
                        {
                            assumeSelect = new NAryExpr(
                                Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                                assumeSelect, Verifier.GroupSharedIndexingExpr(i + 1)
                            });
                        }

                        assumeSelect = new NAryExpr(
                            Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                            assumeSelect, offsets[i]
                        });
                        assumeSelect = new NAryExpr(
                            Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                            assumeSelect, vars[i]
                        });
                        AssumeCmd newAssume = new AssumeCmd(c.tok, Expr.Not(assumeSelect));
                        cs.Add(newAssume);

                        AssignLhs lhs = new SimpleAssignLhs(Token.NoToken, arrayRef);

                        if (isShared && !GPUVerifyVCGenCommandLineOptions.OnlyIntraGroupRaceChecking)
                        {
                            lhs = new MapAssignLhs(
                                Token.NoToken, lhs, new List <Expr> {
                                Verifier.GroupSharedIndexingExpr(i + 1)
                            });
                        }

                        lhs = new MapAssignLhs(
                            Token.NoToken, lhs, new List <Expr> {
                            offsets[i]
                        });
                        lhs = new MapAssignLhs(
                            Token.NoToken, lhs, new List <Expr> {
                            vars[i]
                        });
                        AssignCmd assign = new AssignCmd(
                            c.tok, new List <AssignLhs> {
                            lhs
                        }, new List <Expr> {
                            Expr.True
                        });
                        cs.Add(assign);
                    }
                }
                else
                {
                    var       isUniform = Verifier.UniformityAnalyser.IsUniform(procName, ass.Expr);
                    AssumeCmd newAss    = new AssumeCmd(c.tok, new VariableDualiser(1, Verifier, procName).VisitExpr(ass.Expr.Clone() as Expr));
                    if (!ContainsAsymmetricExpression(ass.Expr) && !isUniform)
                    {
                        newAss.Expr = Expr.And(newAss.Expr, new VariableDualiser(2, Verifier, procName).VisitExpr(ass.Expr.Clone() as Expr));
                    }

                    newAss.Attributes = ass.Attributes;
                    cs.Add(newAss);
                }
            }
            else
            {
                Debug.Assert(false);
            }
        }
Beispiel #10
0
        /////////////////////////////////////////////////////////////////////////////////////

        public bool Visit(VCExprQuantifier node, LineariserOptions options)
        {
            Contract.Assert(node.TypeParameters.Count == 0);

            UnderQuantifier++;
            Namer.PushScope();
            try
            {
                string kind = node.Quan == Quantifier.ALL ? "forall" : "exists";
                wr.Write("({0} (", kind);

                for (int i = 0; i < node.BoundVars.Count; i++)
                {
                    VCExprVar var = node.BoundVars[i];
                    Contract.Assert(var != null);
                    string printedName = Namer.GetQuotedLocalName(var, var.Name);
                    Contract.Assert(printedName != null);
                    wr.Write("({0} {1}) ", printedName, TypeToString(var.Type));
                }

                wr.Write(") ");

                VCQuantifierInfos infos = node.Infos;
                var weight = QKeyValue.FindIntAttribute(infos.attributes, "weight", 1);
                if (!ProverOptions.UseWeights)
                {
                    weight = 1;
                }
                var hasAttrs = node.Triggers.Count > 0 || infos.qid != null || weight != 1 || infos.uniqueId != -1;

                if (hasAttrs)
                {
                    wr.Write("(! ");
                }

                Linearise(node.Body, options);

                if (hasAttrs)
                {
                    wr.Write("\n");
                    if (infos.qid != null)
                    {
                        wr.Write(" :qid {0}\n", SMTLibNamer.QuoteId(infos.qid));
                    }
                    if (weight != 1)
                    {
                        wr.Write(" :weight {0}\n", weight);
                    }
                    if (infos.uniqueId != -1)
                    {
                        wr.Write(" :skolemid |{0}|\n", infos.uniqueId);
                    }
                    WriteTriggers(node.Triggers, options);

                    wr.Write(")");
                }

                wr.Write(")");

                return(true);
            }
            finally
            {
                UnderQuantifier--;
                Namer.PopScope();
            }
        }
        /////////////////////////////////////////////////////////////////////////////////////

        public bool Visit(VCExprQuantifier node, LineariserOptions options)
        {
            //Contract.Requires(options != null);
            //Contract.Requires(node != null);
            AssertAsFormula(node.Quan.ToString(), options);
            Contract.Assert(node.TypeParameters.Count == 0);

            Namer.PushScope();
            try {
                string kind = node.Quan == Quantifier.ALL ? "FORALL" : "EXISTS";
                wr.Write("({0} (", kind);

                for (int i = 0; i < node.BoundVars.Count; i++)
                {
                    VCExprVar var = node.BoundVars[i];
                    Contract.Assert(var != null);
                    string printedName = Namer.GetLocalName(var, var.Name);
                    Contract.Assert(printedName != null);
                    if (i != 0)
                    {
                        wr.Write(" ");
                    }
                    WriteId(printedName);
                    if (options.UseTypes)
                    {
                        wr.Write(" :TYPE {0}", TypeToString(var.Type));
                    }
                }
                wr.Write(") ");

                WriteTriggers(node.Triggers, options);

                if (options.QuantifierIds)
                {
                    // only needed for Z3
                    VCQuantifierInfos infos = node.Infos;
                    Contract.Assert(infos != null);
                    if (infos.qid != null)
                    {
                        wr.Write("(QID ");
                        wr.Write(infos.qid);
                        wr.Write(") ");
                    }
                    if (0 <= infos.uniqueId)
                    {
                        wr.Write("(SKOLEMID ");
                        wr.Write(infos.uniqueId);
                        wr.Write(") ");
                    }
                }

                if (options.UseWeights)
                {
                    int weight = QKeyValue.FindIntAttribute(node.Infos.attributes, "weight", 1);
                    if (weight != 1)
                    {
                        wr.Write("(WEIGHT ");
                        wr.Write(weight);
                        wr.Write(") ");
                    }
                }

                Linearise(node.Body, options);
                wr.Write(")");

                return(true);
            } finally {
                Namer.PopScope();
            }
        }
Beispiel #12
0
        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: SplitRMT.exe file.bpl");
                return;
            }

            // Initialize
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;

            var program = BoogieUtil.ReadAndResolve(args[0]);

            // check input
            foreach (var proc in program.TopLevelDeclarations.OfType <Procedure>())
            {
                if (proc.Requires.Any(req => !req.Free))
                {
                    Console.WriteLine("Error: non-free requires not yet supported");
                    return;
                }
            }

            var eplist = program.TopLevelDeclarations.OfType <Implementation>()
                         .Where(impl => QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint") || QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "entrypoint"));

            if (eplist.Count() != 1)
            {
                Console.WriteLine("Error: Unique entrypoint not found");
                return;
            }

            var main = eplist.First();

            Console.WriteLine("Entrypoint: {0}", main.Name);

            // entrypoint + all assumes
            MarkAllAssumes(program, args[0]);

            // split on asserted postconditions
            var cnt = Split(program, args[0]);

            Console.WriteLine("Produced {0} file(s) after splitting", cnt);
        }