1#if !(defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
7#include "mcrl2/data/detail/prover/smt_lib_solver.h"
9using namespace mcrl2::log;
16template <
typename T >
19 std::array<
int, 2> pipe_stdin;
20 std::array<
int, 2> pipe_stdout;
21 std::array<
int, 2> pipe_stderr;
24 if (::pipe(&pipe_stdin[0]) < 0)
26 throw mcrl2::runtime_error(
"failed to create pipe");
29 if (::pipe(&pipe_stdout[0]) < 0)
31 throw mcrl2::runtime_error(
"failed to create pipe");
34 if (::pipe(&pipe_stderr[0]) < 0)
36 throw mcrl2::runtime_error(
"failed to create pipe");
44 ::dup2(pipe_stdin[0], STDIN_FILENO);
45 ::dup2(pipe_stdout[1], STDOUT_FILENO);
46 ::dup2(pipe_stderr[1], STDERR_FILENO);
48 ::close(pipe_stdin[1]);
49 ::close(pipe_stdout[0]);
50 ::close(pipe_stderr[0]);
58 mCRL2log(log_level_t::error) << strerror(errno) << std::endl;
60 ::close(pipe_stdin[0]);
61 ::close(pipe_stdin[1]);
62 ::close(pipe_stdout[0]);
63 ::close(pipe_stdout[1]);
64 ::close(pipe_stderr[0]);
65 ::close(pipe_stderr[1]);
71 if(::write(pipe_stdin[1], benchmark.c_str(), benchmark.size()) < 0)
73 throw mcrl2::runtime_error(
"failed to write benchmark");
76 ::close(pipe_stdin[0]);
77 ::close(pipe_stdin[1]);
78 ::close(pipe_stdout[1]);
79 ::close(pipe_stderr[1]);
81 std::array<
char, 64> output;
86 if (0 < ::read(pipe_stdout[0], output.data(), 8))
88 if (strncmp(output.data(),
"sat", 3) == 0)
90 mCRL2log(log_level_t::verbose) <<
"The formula is satisfiable" << std::endl;
92 ::close(pipe_stdout[0]);
93 ::close(pipe_stderr[0]);
95 ::wait(&return_status);
99 else if (strncmp(output.data(),
"unsat", 5) == 0)
101 mCRL2log(log_level_t::verbose) <<
"The formula is unsatisfiable" << std::endl;
103 else if (strncmp(output.data(),
"unknown", 7) == 0)
105 mCRL2log(log_level_t::verbose) << T::name() <<
" cannot determine whether this formula is satisfiable or not." << std::endl;
112 while (ssize_t i = ::read(pipe_stderr[0], output.data(), 64))
114 message.append(output.data(),
static_cast<std::size_t>(i));
117 throw mcrl2::runtime_error(std::string(
"The SMT prover ") + T::name() +
" does not work properly. " + message );
120 ::close(pipe_stdout[0]);
121 ::close(pipe_stderr[0]);
123 ::wait(&return_status);
130
131
132template <
typename T >
135 if (!binary_smt_solver::execute(
"(benchmark nameless :formula true)"))
137 throw mcrl2::runtime_error(std::string(
"The SMT solver ") + T::name() +
" is not available. \n" +
138 "Consult the manual of the tool you are using for instructions on how to obtain " + T::name() +
".");
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.