Skip to content

Commit 1a0620f

Browse files
committed
Implement construction of exprt booleans from smt terms
1 parent e3719e3 commit 1a0620f

File tree

5 files changed

+130
-0
lines changed

5 files changed

+130
-0
lines changed

src/solvers/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ SRC = $(BOOLEFORCE_SRC) \
193193
smt2/smt2_parser.cpp \
194194
smt2/smt2_tokenizer.cpp \
195195
smt2/smt2irep.cpp \
196+
smt2_incremental/construct_value_expr_from_smt.cpp \
196197
smt2_incremental/convert_expr_to_smt.cpp \
197198
smt2_incremental/smt_bit_vector_theory.cpp \
198199
smt2_incremental/smt_commands.cpp \
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Author: Diffblue Ltd.
2+
3+
#include <solvers/smt2_incremental/construct_value_expr_from_smt.h>
4+
5+
#include <solvers/smt2_incremental/smt_terms.h>
6+
7+
#include <util/std_expr.h>
8+
#include <util/std_types.h>
9+
#include <util/type.h>
10+
11+
class value_expr_from_smt_factoryt : public smt_term_const_downcast_visitort
12+
{
13+
private:
14+
const typet &type_to_construct;
15+
optionalt<exprt> result;
16+
17+
explicit value_expr_from_smt_factoryt(const typet &type_to_construct)
18+
: type_to_construct{type_to_construct}, result{}
19+
{
20+
}
21+
22+
void visit(const smt_bool_literal_termt &bool_literal) override
23+
{
24+
INVARIANT(
25+
type_to_construct == bool_typet{},
26+
"Bool terms may only be used to construct bool typed expressions.");
27+
result = bool_literal.value() ? (exprt)true_exprt{} : false_exprt{};
28+
}
29+
30+
void visit(const smt_identifier_termt &identifier_term) override
31+
{
32+
INVARIANT(
33+
false, "Unexpected conversion of identifier to value expression.");
34+
}
35+
36+
void visit(const smt_bit_vector_constant_termt &bit_vector_constant) override
37+
{
38+
UNIMPLEMENTED;
39+
}
40+
41+
void
42+
visit(const smt_function_application_termt &function_application) override
43+
{
44+
INVARIANT(
45+
false,
46+
"Unexpected conversion of function application to value expression.");
47+
}
48+
49+
public:
50+
/// \brief This function is complete the external interface to this class. All
51+
/// construction of this class and construction of expressions should be
52+
/// carried out via this function.
53+
static exprt make(const smt_termt &value_term, const typet &type_to_construct)
54+
{
55+
value_expr_from_smt_factoryt factory{type_to_construct};
56+
value_term.accept(factory);
57+
INVARIANT(factory.result.has_value(), "Factory must result in expr value.");
58+
return *factory.result;
59+
}
60+
};
61+
62+
exprt construct_value_expr_from_smt(
63+
const smt_termt &value_term,
64+
const typet &type_to_construct)
65+
{
66+
return value_expr_from_smt_factoryt::make(value_term, type_to_construct);
67+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Author: Diffblue Ltd.
2+
3+
#ifndef CPROVER_SOLVERS_SMT2_INCREMENTAL_CONSTRUCT_VALUE_EXPR_FROM_SMT_H
4+
#define CPROVER_SOLVERS_SMT2_INCREMENTAL_CONSTRUCT_VALUE_EXPR_FROM_SMT_H
5+
6+
#include <util/expr.h>
7+
8+
class smt_termt;
9+
class typet;
10+
11+
/// \brief Given a \p value_term and a \p type_to_construct, this function
12+
/// constructs a value exprt with a value based on \p value_term and a type of
13+
/// \p type_to_construct.
14+
/// \param value_term
15+
/// This must be a "simple" term encoding a value. It must not be a term
16+
/// requiring any kind of further evaluation to get a value, such as would be
17+
/// the case for identifiers or function applications.
18+
/// \param type_to_construct
19+
/// The type which the constructed expr returned is expected to have. This
20+
/// type must be compatible with the sort of \p value_term.
21+
/// \note The type is required separately in order to carry out this conversion,
22+
/// because the smt value term does not contain all the required information.
23+
/// For example an 8 bit, bit vector with a value of 255 could be used to
24+
/// construct an `unsigned char` with the value 255 or alternatively a
25+
/// `signed char` with the value -1. So these alternatives are disambiguated
26+
/// using the type.
27+
exprt construct_value_expr_from_smt(
28+
const smt_termt &value_term,
29+
const typet &type_to_construct);
30+
31+
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_CONSTRUCT_VALUE_EXPR_FROM_SMT_H

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ SRC += analyses/ai/ai.cpp \
100100
solvers/sat/satcheck_minisat2.cpp \
101101
solvers/smt2/smt2_conv.cpp \
102102
solvers/smt2/smt2irep.cpp \
103+
solvers/smt2_incremental/construct_value_expr_from_smt.cpp \
103104
solvers/smt2_incremental/convert_expr_to_smt.cpp \
104105
solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp \
105106
solvers/smt2_incremental/smt_bit_vector_theory.cpp \
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Author: Diffblue Ltd.
2+
3+
#include <testing-utils/use_catch.h>
4+
5+
#include <solvers/smt2_incremental/construct_value_expr_from_smt.h>
6+
7+
#include <solvers/smt2_incremental/smt_terms.h>
8+
#include <solvers/smt2_incremental/smt_to_smt2_string.h>
9+
10+
#include <util/std_expr.h>
11+
#include <util/std_types.h>
12+
13+
TEST_CASE("Value expr construction from smt.", "[core][smt2_incremental]")
14+
{
15+
optionalt<smt_termt> input_term;
16+
optionalt<exprt> expected_result;
17+
18+
using rowt = std::pair<smt_termt, exprt>;
19+
std::tie(input_term, expected_result) = GENERATE(
20+
rowt{smt_bool_literal_termt{true}, true_exprt{}},
21+
rowt{smt_bool_literal_termt{false}, false_exprt{}});
22+
SECTION(
23+
"Construction of \"" + id2string(expected_result->type().id()) +
24+
"\" from \"" + smt_to_smt2_string(*input_term) + "\"")
25+
{
26+
REQUIRE(
27+
construct_value_expr_from_smt(*input_term, expected_result->type()) ==
28+
*expected_result);
29+
}
30+
}

0 commit comments

Comments
 (0)