SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
SMTRAT.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Tool.h"
4 
5 #include <regex>
6 #include <initializer_list>
7 
8 namespace benchmax {
9 
11  std::string::const_iterator m_iter;
12  const std::string::const_iterator m_end;
13 
14 public:
15  simple_parser(const std::string& content) : m_iter(content.cbegin()), m_end(content.cend()) {}
16  bool expect(const char c) {
17  bool result = m_iter != m_end && *m_iter == c;
18  if (result) m_iter++;
19  return result;
20  }
21  bool expect_end() {
22  return m_iter == m_end;
23  }
24  void skip_whitespace() {
25  while (m_iter != m_end && isspace(*m_iter)) m_iter++;
26  }
27  void skip_excluding(const char c) {
28  if (m_iter == m_end || *m_iter == c) return;
29  do m_iter++; while (m_iter != m_end && *m_iter != c);
30  }
31  std::optional<std::string> read_until(const char c) {
32  std::stringstream ss;
33  while (m_iter != m_end && *m_iter != c) {
34  ss << *m_iter;
35  m_iter++;
36  }
37  if (m_iter == m_end) return std::nullopt;
38  else return ss.str();
39  }
40  std::optional<std::string> read_until_whitespace() {
41  std::stringstream ss;
42  while (m_iter != m_end && !isspace(*m_iter)) {
43  ss << *m_iter;
44  m_iter++;
45  }
46  if (m_iter == m_end) return std::nullopt;
47  else return ss.str();
48  }
49  std::optional<std::string> read_until_whitespace_or(const std::initializer_list<char> cs) {
50  std::stringstream ss;
51  while (m_iter != m_end && !isspace(*m_iter) && std::find(cs.begin(), cs.end(), *m_iter) == cs.end()) {
52  ss << *m_iter;
53  m_iter++;
54  }
55  if (m_iter == m_end) return std::nullopt;
56  else return ss.str();
57  }
58 };
59 
60 /**
61  * Tool wrapper for SMT-RAT for SMT-LIB.
62  */
63 class SMTRAT: public Tool {
64 public:
65  /// New SMT-RAT tool.
66  SMTRAT(const fs::path& binary, const std::string& arguments): Tool("SMTRAT", binary, arguments) {
67  if (settings_tools().collect_statistics) mArguments += " --stats.print";
68  }
69 
70  /// Only handle .smt2 files.
71  virtual bool canHandle(const fs::path& path) const override {
72  return is_extension(path, ".smt2");
73  }
74 
75  /// Try to parse memouts from stderr.
76  std::string getStatusFromOutput(const BenchmarkResult& result) const {
77  if (result.stderr.find("GNU MP: Cannot allocate memory") != std::string::npos) return "memout";
78  if (result.stderr.find("Minisat::OutOfMemoryException") != std::string::npos) return "memout";
79  return "segfault";
80  }
81 
83  auto first_colon = result.stdout.find(':');
84  if (first_colon == std::string::npos) return true;
85  assert(first_colon>0);
86  first_colon--;
87  auto str = result.stdout.substr(first_colon);
88  simple_parser p(str);
89  p.skip_excluding('(');
90  while (p.expect('(')) {
91  if (!p.expect(':')) return false;
92  auto prefix = p.read_until_whitespace();
93  if (!prefix) return false;
94  p.skip_whitespace();
95  if (!p.expect('(')) return false;
96  p.skip_whitespace();
97  while (p.expect(':')) {
98  auto key = p.read_until_whitespace();
99  if (!key) return false;
100  p.skip_whitespace();
101  auto value = p.read_until_whitespace_or({')', ':'});
102  if (!value) return false;
103  result.additional.emplace(*prefix + "_" + *key, *value);
104  p.skip_whitespace();
105  }
106  if (!p.expect(')')) return false;
107  p.skip_whitespace();
108  if (!p.expect(')')) return false;
109  p.skip_whitespace();
110  }
111  return true;
112  }
113 
114  /// Computes the answer string from the exit code and parses statistics output.
115  virtual void additionalResults(const fs::path&, BenchmarkResult& result) const override {
116  switch (result.exitCode) {
117  case 2: result.answer = "sat"; break;
118  case 3: result.answer = "unsat"; break;
119  case 4: result.answer = "unknown"; break;
120  case 5: result.answer = "wrong"; break;
121  case 9: result.answer = "nosuchfile"; break;
122  case 10: result.answer = "parsererror"; break;
123  case 11: result.answer = "timeout"; break;
124  case 12: result.answer = "memout"; break;
125  default: result.answer = getStatusFromOutput(result);
126  }
127 
128  if (true) {
129  if (settings_tools().collect_statistics && !parse_stats(result)) {
130  BENCHMAX_LOG_WARN("benchmax.tool.SMTRAT", "Error while parsing statistics of result: " << result);
131  }
132  } else {
133  std::regex topRegex("\\(\\:(\\S+)\\s*\\(\\s*((?:\\:\\S+\\s*\\S+\\s*)+)\\)\\)");
134  std::regex subRegex("\\s*\\:(\\S+)\\s*(\\S+)");
135 
136  auto topBegin = std::sregex_iterator(result.stdout.begin(), result.stdout.end(), topRegex);
137  auto topEnd = std::sregex_iterator();
138  for (auto i = topBegin; i != topEnd; ++i) {
139  const std::string& prefix = (*i)[1];
140  const std::string& subStdout = (*i)[2];
141 
142  auto subBegin = std::sregex_iterator(subStdout.begin(), subStdout.end(), subRegex);
143  auto subEnd = std::sregex_iterator();
144  for (auto j = subBegin; j != subEnd; ++j) {
145  std::string name = prefix + "_" + std::string((*j)[1]);
146  result.additional.emplace(name, (*j)[2]);
147  }
148  }
149  }
150  }
151 };
152 
153 }
#define BENCHMAX_LOG_WARN(channel, msg)
Log warnings.
Definition: logging.h:51
Tool wrapper for SMT-RAT for SMT-LIB.
Definition: SMTRAT.h:63
std::string getStatusFromOutput(const BenchmarkResult &result) const
Try to parse memouts from stderr.
Definition: SMTRAT.h:76
virtual bool canHandle(const fs::path &path) const override
Only handle .smt2 files.
Definition: SMTRAT.h:71
SMTRAT(const fs::path &binary, const std::string &arguments)
New SMT-RAT tool.
Definition: SMTRAT.h:66
bool parse_stats(BenchmarkResult &result) const
Definition: SMTRAT.h:82
virtual void additionalResults(const fs::path &, BenchmarkResult &result) const override
Computes the answer string from the exit code and parses statistics output.
Definition: SMTRAT.h:115
Base class for any tool.
Definition: Tool.h:38
std::string name() const
Common name of this tool.
Definition: Tool.h:62
fs::path binary() const
Full path to the binary.
Definition: Tool.h:67
std::string mArguments
Command line arguments that should be passed to the binary.
Definition: Tool.h:45
void skip_excluding(const char c)
Definition: SMTRAT.h:27
void skip_whitespace()
Definition: SMTRAT.h:24
std::optional< std::string > read_until_whitespace_or(const std::initializer_list< char > cs)
Definition: SMTRAT.h:49
std::string::const_iterator m_iter
Definition: SMTRAT.h:11
simple_parser(const std::string &content)
Definition: SMTRAT.h:15
std::optional< std::string > read_until_whitespace()
Definition: SMTRAT.h:40
std::optional< std::string > read_until(const char c)
Definition: SMTRAT.h:31
const std::string::const_iterator m_end
Definition: SMTRAT.h:12
bool expect(const char c)
Definition: SMTRAT.h:16
static bool find(V &ts, const T &t)
Definition: Alg.h:47
bool is_extension(const std::filesystem::path &path, const std::string &extension)
Checks whether the extension of the filename is as specified.
Definition: filesystem.h:60
const auto & settings_tools()
Returns the tool settings.
Definition: Tools.h:59
std::vector< T > prefix(const std::vector< T > vars, std::size_t prefixSize)
Definition: utils.h:349
Results for a single benchmark run.