public static Action ExcuteUntilExitOrCancellation(
            CancellationToken aCancellationToken,
            ShellParameters aShellParameters,
            Action <string> aActOnProcessOutput)
        {
            return(() =>
            {
                using (Process lBackgroundProcess = BackgroundProcesses.SetBackgroundProcessRunning(aShellParameters))
                {
                    // Start a task to read all of STDOUT from the background process.  The process will exit
                    // if and when the process closes STDOUT and this task reads it to the end.
                    Task <string> lReadingStdout = lBackgroundProcess.StandardOutput.ReadToEndAsync();

                    // Wait on the task.  If the task is cancelled, an OperationCanceledException will be raised.
                    // If the task is cancelled, the background process probably hasn't exited, so try to kill it,
                    // else it won't exit.
                    try
                    {
                        lReadingStdout.Wait(aCancellationToken);
                    }
                    catch (System.OperationCanceledException)
                    {
                        BackgroundProcesses.AttemptToKill(lBackgroundProcess);
                    }

                    aActOnProcessOutput(lReadingStdout.Result);
                }
            });
        }
Beispiel #2
0
        public static Result Decide(Matrix aProposition, int aSecondsTimeout)
        {
            string lPositiveInput;
            string lNegativeInput;

            try
            {
                lPositiveInput = aProposition.Prover9Input;
                lNegativeInput = Factory.Not(aProposition).Prover9Input;
            }
            catch (EngineException lException)
            {
                if (lException.Message.Contains("modal"))
                {
                    return(Result.NoDecision);
                }
                else
                {
                    throw lException;
                }
            }

            bool lPositiveCounterexampleFound      = false;
            bool lNegativeCounterexampleFound      = false;
            bool lFoundThatPropositionIsNecessary  = false;
            bool lFoundThatPropositionIsImpossible = false;

            // Time out value for the cancellation tokens. -1 signifies no time out.
            int aMillisecondsTimeout = aSecondsTimeout >= 0
        ? aSecondsTimeout * 1000
        : -1;

            // Time out argument for prover9 and mace4.  Leave blank if the time out is negative.
            string aTimeoutArgument = aSecondsTimeout >= 0
        ? string.Format("-t {0}", aSecondsTimeout)
        : "";

            CancellationTokenSource lPositiveCaseTokenSource = new System.Threading.CancellationTokenSource(aMillisecondsTimeout);
            CancellationTokenSource lNegativeCaseTokenSource = new System.Threading.CancellationTokenSource(aMillisecondsTimeout);

            ParallelOptions lParallelOptions = new System.Threading.Tasks.ParallelOptions();

            lParallelOptions.MaxDegreeOfParallelism = System.Environment.ProcessorCount;

            Parallel.Invoke(
                lParallelOptions,
                // Try to prove that the proposition is necessary.
                BackgroundProcesses.ExcuteUntilExitOrCancellation(
                    lPositiveCaseTokenSource.Token,
                    new ShellParameters(prover9, aTimeoutArgument, lPositiveInput),
                    // If the proposition is proven, set a flag and cancel all other operations.
                    (fOutput) => {
                if (TheoremProved.IsMatch(fOutput))
                {
                    lFoundThatPropositionIsNecessary = true;
                    lPositiveCaseTokenSource.Cancel();
                    lNegativeCaseTokenSource.Cancel();
                }
            }),
                // Try to prove that the proposition is impossible.
                BackgroundProcesses.ExcuteUntilExitOrCancellation(
                    lNegativeCaseTokenSource.Token,
                    new ShellParameters(prover9, aTimeoutArgument, lNegativeInput),
                    // If the negation of the proposition is proven, set a flag and cancel all other operations.
                    (fOutput) => {
                if (TheoremProved.IsMatch(fOutput))
                {
                    lFoundThatPropositionIsImpossible = true;
                    lPositiveCaseTokenSource.Cancel();
                    lNegativeCaseTokenSource.Cancel();
                }
            }),
                // Try to find a counterexample for the proposition.
                BackgroundProcesses.ExcuteUntilExitOrCancellation(
                    lPositiveCaseTokenSource.Token,
                    new ShellParameters(mace4, aTimeoutArgument, lPositiveInput),
                    // If a counterexample is found for the positive case,
                    // set a flag and cancel the attempt to prove that the proposition is necessary.
                    (fOutput) => {
                if (CounterexampleFound.IsMatch(fOutput))
                {
                    lPositiveCounterexampleFound = true;
                    lPositiveCaseTokenSource.Cancel();
                }
            }),
                // Try to find a counterexample to the negative case.
                BackgroundProcesses.ExcuteUntilExitOrCancellation(
                    lNegativeCaseTokenSource.Token,
                    new ShellParameters(mace4, aTimeoutArgument, lNegativeInput),
                    // If a counterexample is found for the negative case,
                    // set a flag and cancel the attempt to prove that the proposition is impossible.
                    (fOutput) => {
                if (CounterexampleFound.IsMatch(fOutput))
                {
                    lNegativeCounterexampleFound = true;
                    lNegativeCaseTokenSource.Cancel();
                }
            })
                );

            if (lPositiveCounterexampleFound && lFoundThatPropositionIsNecessary)
            {
                throw new EngineException("Inconsistent result!");
            }

            if (lNegativeCounterexampleFound && lFoundThatPropositionIsImpossible)
            {
                throw new EngineException("Inconsistent result!");
            }

            if (lFoundThatPropositionIsNecessary && lFoundThatPropositionIsImpossible)
            {
                throw new EngineException("Inconsistent result!");
            }

            if (lFoundThatPropositionIsNecessary)
            {
                return(Result.Necessary);
            }

            if (lFoundThatPropositionIsImpossible)
            {
                return(Result.Impossible);
            }

            if (lPositiveCounterexampleFound && lNegativeCounterexampleFound)
            {
                return(Result.Contingent);
            }

            if (lPositiveCounterexampleFound)
            {
                return(Result.Unnecessary);
            }

            if (lNegativeCounterexampleFound)
            {
                return(Result.Possible);
            }

            return(Result.NoDecision);
        }