cprover
Toggle main menu visibility
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
19
external_satt::external_satt
(
message_handlert
&message_handler, std::string cmd)
20
:
cnf_clause_list_assignmentt
(message_handler),
solver_cmd
(
std
::move(cmd))
21
{
22
}
23
24
std::string
external_satt::solver_text
()
const
25
{
26
return
"External SAT solver"
;
27
}
28
29
bool
external_satt::is_in_conflict
(
literalt
)
const
30
{
31
UNIMPLEMENTED
;
32
}
33
34
void
external_satt::set_assignment
(
literalt
,
bool
)
35
{
36
UNIMPLEMENTED
;
37
}
38
39
void
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
)
50
dimacs_cnft::write_dimacs_clause
(c, out,
false
);
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
62
std::string
external_satt::execute_solver
(std::string cnf_file)
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
72
external_satt::resultt
external_satt::parse_result
(std::string solver_output)
73
{
74
std::istringstream response_istream(solver_output);
75
std::string line;
76
external_satt::resultt
result =
resultt::P_ERROR
;
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
{
97
return
resultt::P_UNSATISFIABLE
;
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());
117
auto
number_of_variables =
no_variables
();
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 "
129
<< (number_of_variables - 1) <<
messaget::eom
;
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
{
149
log
.conditional_output(
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
});
162
return
resultt::P_SATISFIABLE
;
163
}
164
165
log.error() <<
"external SAT solver has provided an unexpected response"
166
<<
messaget::eom
;
167
return
resultt::P_ERROR;
168
}
169
170
external_satt::resultt
external_satt::do_prop_solve
(
const
bvt
&assumptions)
171
{
172
// are we assuming 'false'?
173
if
(
174
std::find(assumptions.begin(), assumptions.end(),
const_literal
(
false
)) !=
175
assumptions.end())
176
{
177
return
resultt::P_UNSATISFIABLE
;
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
}
cnf_clause_list_assignmentt::assignment
assignmentt assignment
Definition
cnf_clause_list.h:126
cnf_clause_list_assignmentt::cnf_clause_list_assignmentt
cnf_clause_list_assignmentt(message_handlert &message_handler)
Definition
cnf_clause_list.h:94
cnf_clause_listt::no_clauses
size_t no_clauses() const override
Definition
cnf_clause_list.h:42
cnf_clause_listt::clauses
clausest clauses
Definition
cnf_clause_list.h:85
cnft::no_variables
virtual size_t no_variables() const override
Definition
cnf.h:42
dimacs_cnft::write_dimacs_clause
static void write_dimacs_clause(const bvt &, std::ostream &, bool break_lines)
Definition
dimacs_cnf.cpp:51
external_satt::do_prop_solve
resultt do_prop_solve(const bvt &assumptions) override
Definition
external_sat.cpp:170
external_satt::execute_solver
std::string execute_solver(std::string)
Definition
external_sat.cpp:62
external_satt::external_satt
external_satt(message_handlert &message_handler, std::string cmd)
Definition
external_sat.cpp:19
external_satt::solver_cmd
std::string solver_cmd
Definition
external_sat.h:31
external_satt::solver_text
std::string solver_text() const override
Definition
external_sat.cpp:24
external_satt::set_assignment
void set_assignment(literalt, bool) override
Definition
external_sat.cpp:34
external_satt::write_cnf_file
void write_cnf_file(std::string, const bvt &)
Definition
external_sat.cpp:39
external_satt::is_in_conflict
bool is_in_conflict(literalt) const override
Returns true if an assumption is in the final conflict.
Definition
external_sat.cpp:29
external_satt::parse_result
resultt parse_result(std::string)
Definition
external_sat.cpp:72
literalt
Definition
literal.h:26
message_handlert
Definition
message.h:27
messaget::mstreamt
Definition
message.h:216
messaget::eom
static eomt eom
Definition
message.h:289
propt::resultt
resultt
Definition
prop.h:101
propt::resultt::P_UNSATISFIABLE
@ P_UNSATISFIABLE
Definition
prop.h:101
propt::resultt::P_SATISFIABLE
@ P_SATISFIABLE
Definition
prop.h:101
propt::resultt::P_ERROR
@ P_ERROR
Definition
prop.h:101
propt::log
messaget log
Definition
prop.h:134
temporary_filet
Definition
tempfile.h:24
tvt
Definition
threeval.h:20
tvt::unknown
static tvt unknown()
Definition
threeval.h:33
dimacs_cnf.h
external_sat.h
Allows calling an external SAT solver to allow faster integration of newer SAT solvers.
bvt
std::vector< literalt > bvt
Definition
literal.h:201
const_literal
literalt const_literal(bool value)
Definition
literal.h:188
std
STL namespace.
run
int run(const std::string &what, const std::vector< std::string > &argv)
Definition
run.cpp:49
run.h
UNIMPLEMENTED
#define UNIMPLEMENTED
Definition
invariant.h:558
split_string
void split_string(const std::string &s, char delim, std::vector< std::string > &result, bool strip, bool remove_empty)
Definition
string_utils.cpp:39
string_utils.h
tempfile.h
solvers
sat
external_sat.cpp
Generated by
1.17.0