Skip to content

Commit b57bb30

Browse files
committed
Adding unit tests to external sat solveR
1 parent 7751b37 commit b57bb30

File tree

3 files changed

+134
-2
lines changed

3 files changed

+134
-2
lines changed

src/solvers/sat/external_sat.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ external_satt::resultt external_satt::parse_result(std::string solver_output)
7070
std::string line;
7171
external_satt::resultt result = resultt::P_ERROR;
7272
std::vector<bool> assigned_variables(no_variables(), false);
73+
assignment.insert(assignment.begin(), no_variables(), tvt(false));
74+
7375
while(getline(response_istream, line))
7476
{
7577
if(line[0] == 's')
@@ -92,7 +94,6 @@ external_satt::resultt external_satt::parse_result(std::string solver_output)
9294
if(status == "SATISFIABLE")
9395
{
9496
result = resultt::P_SATISFIABLE;
95-
assignment.insert(assignment.begin(), no_variables() - 1, tvt(false));
9697
}
9798
if(status == "TIMEOUT")
9899
{
@@ -101,7 +102,7 @@ external_satt::resultt external_satt::parse_result(std::string solver_output)
101102
}
102103
}
103104

104-
if(line[0] == 'v' && result == resultt::P_SATISFIABLE)
105+
if(line[0] == 'v')
105106
{
106107
auto assignments = split_string(line, ' ');
107108

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ SRC += analyses/ai/ai.cpp \
5858
solvers/floatbv/float_utils.cpp \
5959
solvers/lowering/byte_operators.cpp \
6060
solvers/prop/bdd_expr.cpp \
61+
solvers/sat/external_sat.cpp \
6162
solvers/sat/satcheck_minisat2.cpp \
6263
solvers/strings/array_pool/array_pool.cpp \
6364
solvers/strings/string_constraint_generator_valueof/calculate_max_string_length.cpp \

unit/solvers/sat/external_sat.cpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/// \file
2+
/// Unit tests for calling external SAT solver
3+
/// \author Francis Botero <[email protected]>
4+
5+
#include <solvers/prop/literal.h>
6+
#include <solvers/sat/external_sat.h>
7+
#include <solvers/sat/satcheck_minisat2.h>
8+
#include <testing-utils/use_catch.h>
9+
#include <util/cout_message.h>
10+
11+
class external_sat_test : public external_satt
12+
{
13+
public:
14+
external_sat_test(message_handlert &message_handler, std::string cmd)
15+
: external_satt(message_handler, cmd)
16+
{
17+
}
18+
19+
resultt parse_result(std::string result)
20+
{
21+
return external_satt::parse_result(result);
22+
}
23+
};
24+
25+
SCENARIO("external_sat", "[core][solvers][sat][external_sat]")
26+
{
27+
console_message_handlert message_handler;
28+
29+
GIVEN("External SAT solver is used")
30+
{
31+
external_sat_test satcheck(message_handler, "cmd");
32+
AND_GIVEN("the output is malformed")
33+
{
34+
auto result = GENERATE(
35+
as<std::string>(),
36+
"c comment line\nc another comment\n",
37+
"c no results but assignments present\nv 1 2 3 4\n",
38+
"c too many assignments\ns SATISFIABLE\nv 1 2 3 4",
39+
"v_starts the line but is malformed",
40+
"s_starts the line but is malformed",
41+
"s SOMETHING STRANGE",
42+
"another result");
43+
WHEN("the solver output contains:\n" << result)
44+
{
45+
THEN("the result is set to error")
46+
{
47+
REQUIRE(satcheck.parse_result(result) == propt::resultt::P_ERROR);
48+
}
49+
}
50+
}
51+
52+
AND_GIVEN("the output is malformed")
53+
{
54+
auto result = "c too few assignments\ns SATISFIABLE\nv 1 2 3 4";
55+
WHEN("the solver output contains:\n" << result)
56+
{
57+
THEN("the result is set to error")
58+
{
59+
satcheck.set_no_variables(100);
60+
REQUIRE(satcheck.parse_result(result) == propt::resultt::P_ERROR);
61+
}
62+
}
63+
}
64+
65+
AND_GIVEN("SAT instance is unsatisfiable")
66+
{
67+
std::string unsat_result = GENERATE(
68+
as<std::string>(),
69+
"s UNSATISFIABLE",
70+
"s UNSATISFIABLE\ns SATISFIABLE",
71+
"s SATISFIABLE\ns UNSATISFIABLE");
72+
WHEN("the solver output contains:\n" << unsat_result)
73+
{
74+
THEN("the result is set to unsatisfiable")
75+
{
76+
REQUIRE(
77+
satcheck.parse_result(unsat_result) ==
78+
propt::resultt::P_UNSATISFIABLE);
79+
}
80+
}
81+
}
82+
83+
AND_GIVEN("SAT instance is satisfiable")
84+
{
85+
auto gen = GENERATE(
86+
std::make_tuple(
87+
"s SATISFIABLE\nv 1 2 3 4",
88+
std::vector<bool>{true, true, true, true}),
89+
std::make_tuple(
90+
"s SATISFIABLE\nv 1 2 -3 -4",
91+
std::vector<bool>{true, true, false, false}),
92+
std::make_tuple(
93+
"s SATISFIABLE\nv 1 -2 3 -4",
94+
std::vector<bool>{true, false, true, false}),
95+
std::make_tuple(
96+
"s SATISFIABLE\nv -1 2 -3 4",
97+
std::vector<bool>{false, true, false, true}),
98+
std::make_tuple(
99+
"s SATISFIABLE\nv -1 -2 -3 -4",
100+
std::vector<bool>{false, false, false, false}),
101+
std::make_tuple(
102+
"v 4\ns SATISFIABLE\nv -1\nv 2\nv -3\n",
103+
std::vector<bool>{false, true, false, true}));
104+
WHEN("the solver output contains:\n" << std::get<0>(gen))
105+
{
106+
THEN("the result is set to satisfiable")
107+
{
108+
auto arr = std::get<1>(gen);
109+
// add false to the start for element at 0
110+
arr.insert(arr.begin(), false);
111+
satcheck.set_no_variables(arr.size());
112+
auto results_vector =
113+
std::vector<bool>(satcheck.no_variables(), false);
114+
REQUIRE(
115+
satcheck.parse_result(std::get<0>(gen)) ==
116+
propt::resultt::P_SATISFIABLE);
117+
AND_THEN("has correct assignments")
118+
{
119+
auto assignments = satcheck.get_assignment();
120+
for(size_t i = 1; i < satcheck.no_variables(); i++)
121+
{
122+
results_vector[i] = assignments[i].is_true();
123+
}
124+
REQUIRE_THAT(results_vector, Catch::Equals(arr));
125+
}
126+
}
127+
}
128+
}
129+
}
130+
}

0 commit comments

Comments
 (0)