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