Skip to content

Commit eb20424

Browse files
Merge pull request #7808 from thomasspriggs/tas/smt_string_literals
Add string literal support to incremental SMT decision procedure
2 parents cafe331 + 3f7e416 commit eb20424

File tree

5 files changed

+91
-1
lines changed

5 files changed

+91
-1
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <assert.h>
2+
#include <stdint.h>
3+
4+
int main()
5+
{
6+
const char *my_string = "hello!";
7+
uint8_t index;
8+
__CPROVER_assume(index < 6);
9+
char element = my_string[index];
10+
assert(element != 'o');
11+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
string_literal.c
3+
--trace
4+
Passing problem to incremental SMT2 solving
5+
line 10 assertion element \!\= \'o\'\: FAILURE
6+
index=4
7+
element='o'
8+
VERIFICATION FAILED
9+
^EXIT=10$
10+
^SIGNAL=0$
11+
--
12+
--
13+
Test of indexing into a string literal.

src/solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <util/nodiscard.h>
99
#include <util/range.h>
1010
#include <util/std_expr.h>
11+
#include <util/string_constant.h>
1112
#include <util/symbol.h>
1213

1314
#include <solvers/smt2_incremental/ast/smt_commands.h>
@@ -74,7 +75,8 @@ static std::vector<exprt> gather_dependent_expressions(const exprt &expr)
7475
can_cast_expr<symbol_exprt>(expr_node) ||
7576
can_cast_expr<array_exprt>(expr_node) ||
7677
can_cast_expr<array_of_exprt>(expr_node) ||
77-
can_cast_expr<nondet_symbol_exprt>(expr_node))
78+
can_cast_expr<nondet_symbol_exprt>(expr_node) ||
79+
can_cast_expr<string_constantt>(expr_node))
7880
{
7981
dependent_expressions.push_back(expr_node);
8082
}
@@ -117,6 +119,13 @@ void smt2_incremental_decision_proceduret::initialize_array_elements(
117119
solver_process->send(elements_definition);
118120
}
119121

122+
void smt2_incremental_decision_proceduret::initialize_array_elements(
123+
const string_constantt &string,
124+
const smt_identifier_termt &array_identifier)
125+
{
126+
initialize_array_elements(string.to_array_expr(), array_identifier);
127+
}
128+
120129
template <typename t_exprt>
121130
void smt2_incremental_decision_proceduret::define_array_function(
122131
const t_exprt &array)
@@ -209,6 +218,11 @@ void smt2_incremental_decision_proceduret::define_dependent_functions(
209218
{
210219
define_array_function(*array_of_expr);
211220
}
221+
else if(
222+
const auto string = expr_try_dynamic_cast<string_constantt>(current))
223+
{
224+
define_array_function(*string);
225+
}
212226
else if(
213227
const auto nondet_symbol =
214228
expr_try_dynamic_cast<nondet_symbol_exprt>(current))

src/solvers/smt2_incremental/smt2_incremental_decision_procedure.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
class namespacet;
2424
class smt_base_solver_processt; // IWYU pragma: keep
25+
class string_constantt;
2526

2627
class smt2_incremental_decision_proceduret final
2728
: public stack_decision_proceduret
@@ -87,6 +88,9 @@ class smt2_incremental_decision_proceduret final
8788
void initialize_array_elements(
8889
const array_of_exprt &array,
8990
const smt_identifier_termt &array_identifier);
91+
void initialize_array_elements(
92+
const string_constantt &string,
93+
const smt_identifier_termt &array_identifier);
9094
/// \brief Defines any functions which \p expr depends on, which have not yet
9195
/// been defined, along with their dependencies in turn.
9296
void define_dependent_functions(const exprt &expr);

unit/solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <util/exception_utils.h>
77
#include <util/make_unique.h>
88
#include <util/namespace.h>
9+
#include <util/string_constant.h>
910
#include <util/symbol_table.h>
1011

1112
#include <solvers/smt2_incremental/ast/smt_commands.h>
@@ -683,6 +684,53 @@ TEST_CASE(
683684
}
684685
}
685686

687+
TEST_CASE(
688+
"smt2_incremental_decision_proceduret string literal commands.",
689+
"[core][smt2_incremental]")
690+
{
691+
auto test = decision_procedure_test_environmentt::make();
692+
const string_constantt constant{"Chips"};
693+
const typet array_type = constant.to_array_expr().type();
694+
const symbolt fish{"fish", array_type, ID_C};
695+
test.symbol_table.insert(fish);
696+
test.sent_commands.clear();
697+
test.procedure.set_to(equal_exprt{fish.symbol_expr(), constant}, true);
698+
const smt_array_sortt expected_sort{
699+
smt_bit_vector_sortt{32}, smt_bit_vector_sortt{8}};
700+
const smt_identifier_termt expected_fish{"fish", expected_sort};
701+
const smt_identifier_termt expected_chips{"array_0", expected_sort};
702+
const std::vector<smt_commandt> expected_commands{
703+
smt_declare_function_commandt{expected_fish, {}},
704+
smt_declare_function_commandt{expected_chips, {}},
705+
smt_assert_commandt{smt_core_theoryt::equal(
706+
smt_array_theoryt::select(
707+
expected_chips, smt_bit_vector_constant_termt{0, 32}),
708+
smt_bit_vector_constant_termt{'C', 8})},
709+
smt_assert_commandt{smt_core_theoryt::equal(
710+
smt_array_theoryt::select(
711+
expected_chips, smt_bit_vector_constant_termt{1, 32}),
712+
smt_bit_vector_constant_termt{'h', 8})},
713+
smt_assert_commandt{smt_core_theoryt::equal(
714+
smt_array_theoryt::select(
715+
expected_chips, smt_bit_vector_constant_termt{2, 32}),
716+
smt_bit_vector_constant_termt{'i', 8})},
717+
smt_assert_commandt{smt_core_theoryt::equal(
718+
smt_array_theoryt::select(
719+
expected_chips, smt_bit_vector_constant_termt{3, 32}),
720+
smt_bit_vector_constant_termt{'p', 8})},
721+
smt_assert_commandt{smt_core_theoryt::equal(
722+
smt_array_theoryt::select(
723+
expected_chips, smt_bit_vector_constant_termt{4, 32}),
724+
smt_bit_vector_constant_termt{'s', 8})},
725+
smt_assert_commandt{smt_core_theoryt::equal(
726+
smt_array_theoryt::select(
727+
expected_chips, smt_bit_vector_constant_termt{5, 32}),
728+
smt_bit_vector_constant_termt{'\0', 8})},
729+
smt_assert_commandt{
730+
smt_core_theoryt::equal(expected_fish, expected_chips)}};
731+
REQUIRE(test.sent_commands == expected_commands);
732+
}
733+
686734
TEST_CASE(
687735
"smt2_incremental_decision_proceduret multi-ary with_exprt introduces "
688736
"correct number of indexes.",

0 commit comments

Comments
 (0)