-
Notifications
You must be signed in to change notification settings - Fork 274
Add bit vector extract operation support to incremental SMT2 solving #6654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
21a0a85
d1c5bf7
d90f98c
79618ce
b4862bd
f520e9e
aac7993
8edd58d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// Author: Diffblue Ltd. | ||
|
||
#include "smt_index.h" | ||
|
||
// Define the irep_idts for kinds of index. | ||
const irep_idt ID_smt_numeral_index{"smt_numeral_index"}; | ||
const irep_idt ID_smt_symbol_index{"smt_symbol_index"}; | ||
|
||
bool smt_indext::operator==(const smt_indext &other) const | ||
{ | ||
return irept::operator==(other); | ||
} | ||
|
||
bool smt_indext::operator!=(const smt_indext &other) const | ||
{ | ||
return !(*this == other); | ||
} | ||
|
||
template <> | ||
const smt_numeral_indext *smt_indext::cast<smt_numeral_indext>() const & | ||
{ | ||
return id() == ID_smt_numeral_index | ||
? static_cast<const smt_numeral_indext *>(this) | ||
: nullptr; | ||
} | ||
|
||
template <> | ||
const smt_symbol_indext *smt_indext::cast<smt_symbol_indext>() const & | ||
{ | ||
return id() == ID_smt_symbol_index | ||
? static_cast<const smt_symbol_indext *>(this) | ||
: nullptr; | ||
} | ||
|
||
void smt_indext::accept(smt_index_const_downcast_visitort &visitor) const | ||
{ | ||
if(const auto numeral = this->cast<smt_numeral_indext>()) | ||
return visitor.visit(*numeral); | ||
if(const auto symbol = this->cast<smt_symbol_indext>()) | ||
return visitor.visit(*symbol); | ||
UNREACHABLE; | ||
} | ||
|
||
smt_numeral_indext::smt_numeral_indext(std::size_t value) | ||
: smt_indext{ID_smt_numeral_index} | ||
{ | ||
set_size_t(ID_value, value); | ||
} | ||
|
||
std::size_t smt_numeral_indext::value() const | ||
{ | ||
return get_size_t(ID_value); | ||
} | ||
|
||
smt_symbol_indext::smt_symbol_indext(irep_idt identifier) | ||
: smt_indext{ID_smt_symbol_index} | ||
{ | ||
set(ID_identifier, identifier); | ||
} | ||
|
||
irep_idt smt_symbol_indext::identifier() const | ||
{ | ||
return get(ID_identifier); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Author: Diffblue Ltd. | ||
|
||
#ifndef CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_INDEX_H | ||
#define CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_INDEX_H | ||
|
||
#include <util/irep.h> | ||
|
||
class smt_index_const_downcast_visitort; | ||
|
||
/// \brief | ||
/// For implementation of indexed identifiers. See SMT-LIB Standard Version 2.6 | ||
/// section 3.3. | ||
class smt_indext : protected irept | ||
{ | ||
public: | ||
// smt_indext does not support the notion of an empty / null state. Use | ||
// optionalt<smt_indext> instead if an empty index is required. | ||
smt_indext() = delete; | ||
|
||
using irept::pretty; | ||
|
||
bool operator==(const smt_indext &) const; | ||
bool operator!=(const smt_indext &) const; | ||
|
||
template <typename sub_classt> | ||
const sub_classt *cast() const &; | ||
|
||
void accept(smt_index_const_downcast_visitort &) const; | ||
|
||
/// \brief Class for adding the ability to up and down cast smt_indext to and | ||
/// from irept. These casts are required by other irept derived classes in | ||
/// order to store instances of smt_termt inside them. | ||
/// \tparam derivedt The type of class which derives from this class and from | ||
/// irept. | ||
template <typename derivedt> | ||
class storert | ||
{ | ||
protected: | ||
storert(); | ||
static irept upcast(smt_indext index); | ||
static const smt_indext &downcast(const irept &); | ||
}; | ||
|
||
protected: | ||
using irept::irept; | ||
}; | ||
|
||
template <typename derivedt> | ||
smt_indext::storert<derivedt>::storert() | ||
{ | ||
static_assert( | ||
std::is_base_of<irept, derivedt>::value && | ||
std::is_base_of<storert<derivedt>, derivedt>::value, | ||
"Only irept based classes need to upcast smt_sortt to store it."); | ||
} | ||
|
||
template <typename derivedt> | ||
irept smt_indext::storert<derivedt>::upcast(smt_indext index) | ||
{ | ||
return static_cast<irept &&>(std::move(index)); | ||
} | ||
|
||
template <typename derivedt> | ||
const smt_indext &smt_indext::storert<derivedt>::downcast(const irept &irep) | ||
{ | ||
return static_cast<const smt_indext &>(irep); | ||
} | ||
|
||
class smt_numeral_indext : public smt_indext | ||
{ | ||
public: | ||
explicit smt_numeral_indext(std::size_t value); | ||
std::size_t value() const; | ||
}; | ||
|
||
class smt_symbol_indext : public smt_indext | ||
{ | ||
public: | ||
explicit smt_symbol_indext(irep_idt identifier); | ||
irep_idt identifier() const; | ||
}; | ||
|
||
class smt_index_const_downcast_visitort | ||
{ | ||
public: | ||
virtual void visit(const smt_numeral_indext &) = 0; | ||
virtual void visit(const smt_symbol_indext &) = 0; | ||
}; | ||
|
||
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_INDEX_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Author: Diffblue Ltd. | ||
|
||
#include <util/optional.h> | ||
|
||
#include <solvers/smt2_incremental/smt_index.h> | ||
#include <testing-utils/use_catch.h> | ||
|
||
TEST_CASE("Test smt_indext.pretty is accessible.", "[core][smt2_incremental]") | ||
{ | ||
const smt_indext index = smt_numeral_indext{42}; | ||
REQUIRE_FALSE(index.pretty().empty()); | ||
} | ||
|
||
TEST_CASE("Test smt_index getters", "[core][smt2_incremental]") | ||
{ | ||
SECTION("Numeral") | ||
{ | ||
REQUIRE(smt_numeral_indext{42}.value() == 42); | ||
} | ||
SECTION("Symbol") | ||
{ | ||
REQUIRE(smt_symbol_indext{"foo"}.identifier() == "foo"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if you create a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then the constructed instant will contain the empty string. Are you suggesting an additional invariant? |
||
} | ||
} | ||
|
||
TEST_CASE("Visiting smt_indext", "[core][smt2_incremental]") | ||
{ | ||
class : public smt_index_const_downcast_visitort | ||
{ | ||
public: | ||
optionalt<std::size_t> numeral_visited{}; | ||
optionalt<irep_idt> symbol_visited{}; | ||
|
||
void visit(const smt_numeral_indext &numeral) override | ||
{ | ||
numeral_visited = numeral.value(); | ||
} | ||
|
||
void visit(const smt_symbol_indext &symbol) override | ||
{ | ||
symbol_visited = symbol.identifier(); | ||
} | ||
} visitor; | ||
SECTION("numeral") | ||
{ | ||
smt_numeral_indext{8}.accept(visitor); | ||
REQUIRE(visitor.numeral_visited); | ||
CHECK(*visitor.numeral_visited == 8); | ||
CHECK_FALSE(visitor.symbol_visited); | ||
} | ||
SECTION("symbol") | ||
{ | ||
smt_symbol_indext{"bar"}.accept(visitor); | ||
CHECK_FALSE(visitor.numeral_visited); | ||
REQUIRE(visitor.symbol_visited); | ||
CHECK(*visitor.symbol_visited == "bar"); | ||
} | ||
} | ||
|
||
TEST_CASE("smt_index equality", "[core][smt2_incremental]") | ||
{ | ||
const smt_symbol_indext foo_index{"foo"}; | ||
CHECK(foo_index == smt_symbol_indext{"foo"}); | ||
CHECK(foo_index != smt_symbol_indext{"bar"}); | ||
const smt_numeral_indext index_42{42}; | ||
CHECK(index_42 == smt_numeral_indext{42}); | ||
CHECK(index_42 != smt_numeral_indext{12}); | ||
CHECK(index_42 != foo_index); | ||
} |
Uh oh!
There was an error while loading. Please reload this page.