Beispiel #1
0
            public IQueryResult ComputeSatisfiability(Query query)
            {
                // FIXME: Optimise the case where only the query expression has changed
                Printer.ClearDeclarations();
                foreach (var constraint in query.Constraints.Constraints)
                {
                    Printer.AddDeclarations(constraint);
                }
                Printer.AddDeclarations(query.QueryExpr);


                Printer.PrintCommentLine("Query " + UseCounter + " Begin");
                PrintDeclarationsAndConstraints(query.Constraints);
                Printer.PrintCommentLine("Query Expr:" + query.QueryExpr.Origin.ToString());
                Printer.PrintAssert(query.QueryExpr.Condition);
                Printer.PrintCheckSat();

                var result = UnderlyingImpl.ComputeSatisfiability(query);

                Printer.PrintCommentLine("Result : " + result.Satisfiability);

                Printer.PrintExit();
                Printer.PrintCommentLine("End of Query " + (UseCounter));
                ++UseCounter;
                return(result);
            }
Beispiel #2
0
            public IQueryResult ComputeSatisfiability(Query query)
            {
                lock (ComputeSatisfiabilityLock)
                {
                    Interrupted    = false;
                    ReceivedResult = false;
                    ReceivedError  = false;
                    SolverResult   = Result.UNKNOWN;
                    bool timeoutOccured = false;

                    try
                    {
                        // FIXME: This is only needed for PersistentProcess mode but we need
                        // to initialise it before we could get a response from the solver other we might race.
                        // In fact there still might be a race here...
                        using (ReceivedResultEvent = new CountdownEvent(1))
                        {
                            ReadExprTimer.Start();
                            Printer.ClearDeclarations();

                            // Let the printer find the declarations
                            foreach (var constraint in query.Constraints.Constraints)
                            {
                                Printer.AddDeclarations(constraint);
                            }
                            Printer.AddDeclarations(query.QueryExpr);
                            ReadExprTimer.Stop();

                            // Assume the process has already been setup
                            PrintExprTimer.Start();

                            // Set options if the current process hasn't been given them before or if we're using (reset)
                            if (!SolverOptionsSet || UseReset)
                            {
                                SetSolverOptions();
                                SolverOptionsSet = true;
                            }

                            if (PersistentProcess && !UseReset)
                            {
                                Printer.PrintPushDeclStack(1);
                            }

                            PrintDeclarationsAndConstraints(query.Constraints);
                            Printer.PrintAssert(query.QueryExpr.Condition);

                            // Start the timer for the process now. The solver should start processing as soon as we write (check-sat)
                            SolverProcessTimer.Start();

                            Printer.PrintCheckSat();
                            PrintExprTimer.Stop();

                            // Handle result
                            if (PersistentProcess)
                            {
                                // In persistent mode try to avoid killing the solver process so have to use
                                // a different synchronisation method to check if we've received a result

                                // Wait for result
                                if (Timeout > 0)
                                {
                                    timeoutOccured = !ReceivedResultEvent.Wait(Timeout * 1000);
                                }
                                else
                                {
                                    ReceivedResultEvent.Wait();
                                }

                                bool processExited = false;
                                try
                                {
                                    processExited = TheProcess.HasExited;
                                }
                                catch (InvalidOperationException)
                                {
                                    processExited = true;
                                }

                                if (ReceivedError && !Interrupted)
                                {
                                    throw new SolverErrorException(SolverErrorMsg);
                                }

                                if (!ReceivedResult || processExited || ReceivedResultEvent.CurrentCount > 0)
                                {
                                    // We don't know what state the process is in so we should kill it and make a fresh process
                                    SolverResult = Result.UNKNOWN;
                                    CreateNewProcess();
                                }
                                else
                                {
                                    // Clear all the declarations and assertions, ready for the next query
                                    if (UseReset)
                                    {
                                        Printer.PrintReset();
                                    }
                                    else
                                    {
                                        Printer.PrintPopDeclStack(1);
                                        Printer.Reset();
                                    }
                                }

                                if (SolverProcessTimer.IsRunning)
                                {
                                    SolverProcessTimer.Stop();
                                }
                            }
                            else
                            {
                                // Non-persistent process mode. We create and destroy a process for every query
                                if (Timeout > 0)
                                {
                                    timeoutOccured = !TheProcess.WaitForExit(Timeout * 1000);
                                }
                                else
                                {
                                    TheProcess.WaitForExit();
                                }

                                if (!ReceivedResult)
                                {
                                    Console.Error.WriteLine("Failed to get solver result!");
                                    SolverResult = Result.UNKNOWN;
                                }

                                if (ReceivedError && !Interrupted)
                                {
                                    throw new SolverErrorException(SolverErrorMsg);
                                }

                                if (SolverProcessTimer.IsRunning)
                                {
                                    SolverProcessTimer.Stop();
                                }

                                CreateNewProcess(); // For next invocation
                            }
                        }
                    }
                    catch (System.IO.IOException)
                    {
                        // This might happen if the process gets killed whilst we are trying to write
                        if (!ReceivedResult)
                        {
                            Console.Error.WriteLine("Failed to get solver result!");
                            SolverResult = Result.UNKNOWN;
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        Console.Error.WriteLine("Warning hit ObjectDisposedException. Assuming we are being disposed of!");
                        // Race condition, We got killed while trying to print. Just give up!
                        SolverResult = Result.UNKNOWN;
                    }
                    catch (UnauthorizedAccessException)
                    {
                        Console.Error.WriteLine("Warning hit UnauthorizedAccessException. Just returning unknown");
                        SolverResult = Result.UNKNOWN;
                    }
                    catch (System.NotSupportedException excep)
                    {
                        if (!Interrupted)
                        {
                            throw excep;
                        }
                        // Apparently this can be thrown if the process gets killed whilst writing
                        // System.NotSupportedException: Stream does not support writing
                        Console.Error.WriteLine("Warning hit System.NotSupportedException. Just returning unknown");
                        SolverResult = Result.UNKNOWN;
                    }

                    ReceivedResultEvent = null;

                    if (timeoutOccured)
                    {
                        ++InternalStatistics.TimeoutCount;
                    }

                    // FIXME: We need to implement our own class so we can support assignments and the unsat core
                    return(new SimpleQueryResult(SolverResult));
                }
            }