CBMC
Loading...
Searching...
No Matches
external_sat.cpp
Go to the documentation of this file.
1
5
6#include "external_sat.h"
7
8#include "dimacs_cnf.h"
9
10#include <util/run.h>
11#include <util/string_utils.h>
12#include <util/tempfile.h>
13
14#include <algorithm>
15#include <cstdlib>
16#include <fstream>
17#include <string>
18
20 : cnf_clause_list_assignmentt(message_handler), solver_cmd(std::move(cmd))
21{
22}
23
24std::string external_satt::solver_text() const
25{
26 return "External SAT solver";
27}
28
33
38
39void external_satt::write_cnf_file(std::string cnf_file, const bvt &assumptions)
40{
41 log.status() << "Writing temporary CNF" << messaget::eom;
42 std::ofstream out(cnf_file);
43
44 // We start counting at 1, thus there is one variable fewer.
45 out << "p cnf " << (no_variables() - 1) << ' '
46 << no_clauses() + assumptions.size() << '\n';
47
48 // output the problem clauses
49 for(auto &c : clauses)
51
52 // output the assumption clauses
53 for(const auto &literal : assumptions)
54 {
55 if(!literal.is_constant())
56 out << literal.dimacs() << " 0\n";
57 }
58
59 out.close();
60}
61
63{
64 log.status() << "Invoking SAT solver" << messaget::eom;
65 std::ostringstream response_ostream;
66 auto cmd_result = run(solver_cmd, {"", cnf_file}, "", response_ostream, "");
67
68 log.status() << "Solver returned code: " << cmd_result << messaget::eom;
69 return response_ostream.str();
70}
71
73{
74 std::istringstream response_istream(solver_output);
75 std::string line;
77 std::vector<bool> assigned_variables(no_variables(), false);
78 assignment.insert(assignment.begin(), no_variables(), tvt::unknown());
79
80 while(getline(response_istream, line))
81 {
82 if(line[0] == 's')
83 {
84 auto parts = split_string(line, ' ');
85 if(parts.size() < 2)
86 {
87 log.error() << "external SAT solver has provided an unexpected "
88 "response in results.\nUnexpected response: "
89 << line << messaget::eom;
90 return resultt::P_ERROR;
91 }
92
93 auto status = parts[1];
94 log.status() << "result:" << status << messaget::eom;
95 if(status == "UNSATISFIABLE")
96 {
98 }
99 if(status == "SATISFIABLE")
100 {
101 result = resultt::P_SATISFIABLE;
102 }
103 if(status == "TIMEOUT")
104 {
105 log.error() << "external SAT solver reports a timeout" << messaget::eom;
106 return resultt::P_ERROR;
107 }
108 }
109
110 if(line[0] == 'v')
111 {
112 auto assignments = split_string(line, ' ', false, true);
113
114 // remove the first element which should be 'v' identifying
115 // the line as the satisfying assignments
116 assignments.erase(assignments.begin());
118 for(auto &assignment_string : assignments)
119 {
120 try
121 {
122 signed long long as_long = std::stoll(assignment_string);
123 size_t index = std::llabs(as_long);
124
125 if(index >= number_of_variables)
126 {
127 log.error() << "SAT assignment " << as_long
128 << " out of range of CBMC largest variable of "
130 return resultt::P_ERROR;
131 }
132 assignment[index] = tvt(as_long >= 0);
133 assigned_variables[index] = true;
134 }
135 catch(...)
136 {
137 log.error() << "SAT assignment " << assignment_string
138 << " caused an exception while processing"
139 << messaget::eom;
140 return resultt::P_ERROR;
141 }
142 }
143 // Assignments can span multiple lines so returning early isn't an option
144 }
145 }
146
147 if(result == resultt::P_SATISFIABLE)
148 {
150 log.debug(), [this, &assigned_variables](messaget::mstreamt &mstream) {
151 // We don't need to check zero
152 for(size_t index = 1; index < no_variables(); index++)
153 {
154 // this may happen when a variable does not appear in any clause
155 if(!assigned_variables[index])
156 {
157 mstream << "No assignment was found for literal: " << index
158 << messaget::eom;
159 }
160 }
161 });
163 }
164
165 log.error() << "external SAT solver has provided an unexpected response"
166 << messaget::eom;
167 return resultt::P_ERROR;
168}
169
171{
172 // are we assuming 'false'?
173 if(
174 std::find(assumptions.begin(), assumptions.end(), const_literal(false)) !=
175 assumptions.end())
176 {
178 }
179
180 // create a temporary file
181 temporary_filet cnf_file("external-sat", ".cnf");
182 write_cnf_file(cnf_file(), assumptions);
183 auto output = execute_solver(cnf_file());
184 return parse_result(output);
185}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
size_t no_clauses() const override
virtual size_t no_variables() const override
Definition cnf.h:42
static void write_dimacs_clause(const bvt &, std::ostream &, bool break_lines)
resultt do_prop_solve(const bvt &assumptions) override
std::string execute_solver(std::string)
external_satt(message_handlert &message_handler, std::string cmd)
std::string solver_cmd
std::string solver_text() const override
void set_assignment(literalt, bool) override
void write_cnf_file(std::string, const bvt &)
bool is_in_conflict(literalt) const override
Returns true if an assumption is in the final conflict.
resultt parse_result(std::string)
mstreamt & error() const
Definition message.h:391
mstreamt & debug() const
Definition message.h:421
void conditional_output(mstreamt &mstream, const std::function< void(mstreamt &)> &output_generator) const
Generate output to message_stream using output_generator if the configured verbosity is at least as h...
Definition message.cpp:139
static eomt eom
Definition message.h:289
mstreamt & status() const
Definition message.h:406
resultt
Definition prop.h:101
messaget log
Definition prop.h:134
Definition threeval.h:20
static tvt unknown()
Definition threeval.h:33
Allows calling an external SAT solver to allow faster integration of newer SAT solvers.
std::vector< literalt > bvt
Definition literal.h:201
literalt const_literal(bool value)
Definition literal.h:188
double log(double x)
Definition math.c:2449
STL namespace.
int run(const std::string &what, const std::vector< std::string > &argv)
Definition run.cpp:48
#define UNIMPLEMENTED
Definition invariant.h:558
void split_string(const std::string &s, char delim, std::vector< std::string > &result, bool strip, bool remove_empty)