Skip to content

Commit 8bf2503

Browse files
Merge pull request #6977 from esteffin/tas/array_functions
Add SMT2 array theory functions
2 parents 22d81fd + 257bfc4 commit 8bf2503

File tree

5 files changed

+162
-0
lines changed

5 files changed

+162
-0
lines changed

src/solvers/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ SRC = $(BOOLEFORCE_SRC) \
197197
smt2_incremental/convert_expr_to_smt.cpp \
198198
smt2_incremental/object_tracking.cpp \
199199
smt2_incremental/type_size_mapping.cpp \
200+
smt2_incremental/smt_array_theory.cpp \
200201
smt2_incremental/smt_bit_vector_theory.cpp \
201202
smt2_incremental/smt_commands.cpp \
202203
smt2_incremental/smt_core_theory.cpp \
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Author: Diffblue Ltd.
2+
3+
#include "smt_array_theory.h"
4+
5+
const char *smt_array_theoryt::selectt::identifier()
6+
{
7+
return "select";
8+
}
9+
10+
smt_sortt smt_array_theoryt::selectt::return_sort(
11+
const smt_termt &array,
12+
const smt_termt &index)
13+
{
14+
return array.get_sort().cast<smt_array_sortt>()->element_sort();
15+
}
16+
17+
void smt_array_theoryt::selectt::validate(
18+
const smt_termt &array,
19+
const smt_termt &index)
20+
{
21+
const auto array_sort = array.get_sort().cast<smt_array_sortt>();
22+
INVARIANT(array_sort, "\"select\" may only select from an array.");
23+
INVARIANT(
24+
array_sort->index_sort() == index.get_sort(),
25+
"Sort of arrays index must match the sort of the index supplied.");
26+
}
27+
28+
const smt_function_application_termt::factoryt<smt_array_theoryt::selectt>
29+
smt_array_theoryt::select{};
30+
31+
const char *smt_array_theoryt::storet::identifier()
32+
{
33+
return "store";
34+
}
35+
smt_sortt smt_array_theoryt::storet::return_sort(
36+
const smt_termt &array,
37+
const smt_termt &index,
38+
const smt_termt &value)
39+
{
40+
return array.get_sort();
41+
}
42+
void smt_array_theoryt::storet::validate(
43+
const smt_termt &array,
44+
const smt_termt &index,
45+
const smt_termt &value)
46+
{
47+
const auto array_sort = array.get_sort().cast<smt_array_sortt>();
48+
INVARIANT(array_sort, "\"store\" may only update an array.");
49+
INVARIANT(
50+
array_sort->index_sort() == index.get_sort(),
51+
"Sort of arrays index must match the sort of the index supplied.");
52+
INVARIANT(
53+
array_sort->element_sort() == value.get_sort(),
54+
"Sort of arrays value must match the sort of the value supplied.");
55+
}
56+
57+
const smt_function_application_termt::factoryt<smt_array_theoryt::storet>
58+
smt_array_theoryt::store{};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Author: Diffblue Ltd.
2+
3+
#ifndef CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_ARRAY_THEORY_H
4+
#define CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_ARRAY_THEORY_H
5+
6+
#include <solvers/smt2_incremental/smt_terms.h>
7+
8+
class smt_array_theoryt
9+
{
10+
public:
11+
struct selectt final
12+
{
13+
static const char *identifier();
14+
static smt_sortt
15+
return_sort(const smt_termt &array, const smt_termt &index);
16+
static void validate(const smt_termt &array, const smt_termt &index);
17+
};
18+
static const smt_function_application_termt::factoryt<selectt> select;
19+
20+
struct storet final
21+
{
22+
static const char *identifier();
23+
static smt_sortt return_sort(
24+
const smt_termt &array,
25+
const smt_termt &index,
26+
const smt_termt &value);
27+
static void validate(
28+
const smt_termt &array,
29+
const smt_termt &index,
30+
const smt_termt &value);
31+
};
32+
static const smt_function_application_termt::factoryt<storet> store;
33+
};
34+
35+
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_ARRAY_THEORY_H

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ SRC += analyses/ai/ai.cpp \
104104
solvers/smt2_incremental/convert_expr_to_smt.cpp \
105105
solvers/smt2_incremental/object_tracking.cpp \
106106
solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp \
107+
solvers/smt2_incremental/smt_array_theory.cpp \
107108
solvers/smt2_incremental/smt_bit_vector_theory.cpp \
108109
solvers/smt2_incremental/smt_commands.cpp \
109110
solvers/smt2_incremental/smt_core_theory.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 <util/mp_arith.h>
4+
5+
#include <solvers/smt2_incremental/smt_array_theory.h>
6+
#include <solvers/smt2_incremental/smt_bit_vector_theory.h>
7+
#include <testing-utils/use_catch.h>
8+
9+
#include "testing-utils/invariant.h"
10+
11+
TEST_CASE("SMT array theory \"select\".", "[core][smt2_incremental]")
12+
{
13+
const smt_identifier_termt index_term("index", smt_bit_vector_sortt(64));
14+
const smt_sortt value_sort(smt_bit_vector_sortt(32));
15+
const smt_identifier_termt array_term(
16+
"array", smt_array_sortt(index_term.get_sort(), value_sort));
17+
const smt_function_application_termt select =
18+
smt_array_theoryt::select(array_term, index_term);
19+
CHECK(select.get_sort() == value_sort);
20+
CHECK(select.function_identifier().identifier() == "select");
21+
REQUIRE(select.arguments().size() == 2);
22+
CHECK(select.arguments()[0].get() == array_term);
23+
CHECK(select.arguments()[1].get() == index_term);
24+
cbmc_invariants_should_throwt invariants_throw;
25+
const smt_bit_vector_constant_termt two{2, 8};
26+
REQUIRE_THROWS_MATCHES(
27+
smt_array_theoryt::select(two, index_term),
28+
invariant_failedt,
29+
invariant_failure_containing("\"select\" may only select from an array."));
30+
REQUIRE_THROWS_MATCHES(
31+
smt_array_theoryt::select(array_term, two),
32+
invariant_failedt,
33+
invariant_failure_containing(
34+
"Sort of arrays index must match the sort of the index supplied."));
35+
}
36+
37+
TEST_CASE("SMT array theory \"store\".", "[core][smt2_incremental]")
38+
{
39+
const smt_identifier_termt index_term("index", smt_bit_vector_sortt(64));
40+
const smt_identifier_termt value_term("value", smt_bit_vector_sortt(32));
41+
const smt_identifier_termt array_term(
42+
"array", smt_array_sortt(index_term.get_sort(), value_term.get_sort()));
43+
const smt_function_application_termt store =
44+
smt_array_theoryt::store(array_term, index_term, value_term);
45+
CHECK(store.get_sort() == array_term.get_sort());
46+
CHECK(store.function_identifier().identifier() == "store");
47+
REQUIRE(store.arguments().size() == 3);
48+
CHECK(store.arguments()[0].get() == array_term);
49+
CHECK(store.arguments()[1].get() == index_term);
50+
CHECK(store.arguments()[2].get() == value_term);
51+
cbmc_invariants_should_throwt invariants_throw;
52+
const smt_bit_vector_constant_termt two{2, 8};
53+
REQUIRE_THROWS_MATCHES(
54+
smt_array_theoryt::store(two, index_term, value_term),
55+
invariant_failedt,
56+
invariant_failure_containing("\"store\" may only update an array."));
57+
REQUIRE_THROWS_MATCHES(
58+
smt_array_theoryt::store(array_term, two, value_term),
59+
invariant_failedt,
60+
invariant_failure_containing(
61+
"Sort of arrays index must match the sort of the index supplied."));
62+
REQUIRE_THROWS_MATCHES(
63+
smt_array_theoryt::store(array_term, index_term, two),
64+
invariant_failedt,
65+
invariant_failure_containing(
66+
"Sort of arrays value must match the sort of the value supplied."));
67+
}

0 commit comments

Comments
 (0)