Skip to content

Commit fabc43a

Browse files
committed
Add smt commands
1 parent abff630 commit fabc43a

File tree

12 files changed

+689
-0
lines changed

12 files changed

+689
-0
lines changed

src/solvers/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ SRC = $(BOOLEFORCE_SRC) \
192192
smt2/smt2_parser.cpp \
193193
smt2/smt2_tokenizer.cpp \
194194
smt2/smt2irep.cpp \
195+
smt2_incremental/smt_commands.cpp \
196+
smt2_incremental/smt_logics.cpp \
197+
smt2_incremental/smt_options.cpp \
195198
smt2_incremental/smt_sorts.cpp \
196199
smt2_incremental/smt_terms.cpp \
197200
smt2_incremental/smt2_incremental_decision_procedure.cpp \
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// Author: Diffblue Ltd.
2+
3+
#include <solvers/smt2_incremental/smt_commands.h>
4+
5+
#include <util/range.h>
6+
7+
// Define the irep_idts for commands.
8+
#define COMMAND_ID(the_id) \
9+
const irep_idt ID_smt_##the_id##_command{"smt_" #the_id "_command"};
10+
#include <solvers/smt2_incremental/smt_commands.def>
11+
#undef COMMAND_ID
12+
13+
bool smt_commandt::operator==(const smt_commandt &other) const
14+
{
15+
return irept::operator==(other);
16+
}
17+
18+
bool smt_commandt::operator!=(const smt_commandt &other) const
19+
{
20+
return !(*this == other);
21+
}
22+
23+
smt_assert_commandt::smt_assert_commandt(smt_termt condition)
24+
: smt_commandt{ID_smt_assert_command}
25+
{
26+
INVARIANT(
27+
condition.get_sort() == smt_bool_sortt{},
28+
"Only terms with boolean sorts can be asserted.");
29+
set(ID_cond, upcast(std::move(condition)));
30+
}
31+
32+
const smt_termt &smt_assert_commandt::condition() const
33+
{
34+
return downcast(find(ID_cond));
35+
}
36+
37+
smt_check_sat_commandt::smt_check_sat_commandt()
38+
: smt_commandt{ID_smt_check_sat_command}
39+
{
40+
}
41+
42+
smt_declare_function_commandt::smt_declare_function_commandt(
43+
smt_identifier_termt identifier,
44+
std::vector<smt_sortt> parameter_sorts)
45+
: smt_commandt{ID_smt_declare_function_command}
46+
{
47+
set(ID_identifier, term_storert::upcast(std::move(identifier)));
48+
std::transform(
49+
std::make_move_iterator(parameter_sorts.begin()),
50+
std::make_move_iterator(parameter_sorts.end()),
51+
std::back_inserter(get_sub()),
52+
[](smt_sortt &&parameter_sort) {
53+
return sort_storert::upcast(std::move(parameter_sort));
54+
});
55+
}
56+
57+
const smt_identifier_termt &smt_declare_function_commandt::identifier() const
58+
{
59+
return static_cast<const smt_identifier_termt &>(
60+
term_storert::downcast(find(ID_identifier)));
61+
}
62+
63+
const smt_sortt &smt_declare_function_commandt::return_sort() const
64+
{
65+
return identifier().get_sort();
66+
}
67+
68+
std::vector<std::reference_wrapper<const smt_sortt>>
69+
smt_declare_function_commandt::parameter_sorts() const
70+
{
71+
return make_range(get_sub()).map([](const irept &parameter_sort) {
72+
return std::cref(sort_storert::downcast(parameter_sort));
73+
});
74+
}
75+
76+
smt_exit_commandt::smt_exit_commandt() : smt_commandt{ID_smt_exit_command}
77+
{
78+
}
79+
80+
smt_define_function_commandt::smt_define_function_commandt(
81+
irep_idt identifier,
82+
std::vector<smt_identifier_termt> parameters,
83+
smt_termt definition)
84+
: smt_commandt{ID_smt_define_function_command}
85+
{
86+
set(ID_identifier, identifier);
87+
std::transform(
88+
std::make_move_iterator(parameters.begin()),
89+
std::make_move_iterator(parameters.end()),
90+
std::back_inserter(get_sub()),
91+
[](smt_identifier_termt &&parameter) {
92+
return upcast(std::move(parameter));
93+
});
94+
set(ID_code, upcast(std::move(definition)));
95+
}
96+
97+
const irep_idt &smt_define_function_commandt::identifier() const
98+
{
99+
return get(ID_identifier);
100+
}
101+
102+
std::vector<std::reference_wrapper<const smt_identifier_termt>>
103+
smt_define_function_commandt::parameters() const
104+
{
105+
return make_range(get_sub()).map([](const irept &parameter) {
106+
return std::cref(
107+
static_cast<const smt_identifier_termt &>(downcast((parameter))));
108+
});
109+
}
110+
111+
const smt_sortt &smt_define_function_commandt::return_sort() const
112+
{
113+
return definition().get_sort();
114+
}
115+
116+
const smt_termt &smt_define_function_commandt::definition() const
117+
{
118+
return downcast(find(ID_code));
119+
}
120+
121+
smt_get_value_commandt::smt_get_value_commandt(smt_termt descriptor)
122+
: smt_commandt{ID_smt_get_value_command}
123+
{
124+
set(ID_value, upcast(std::move(descriptor)));
125+
}
126+
127+
const smt_termt &smt_get_value_commandt::descriptor() const
128+
{
129+
return downcast(find(ID_value));
130+
}
131+
132+
smt_push_commandt::smt_push_commandt(std::size_t levels)
133+
: smt_commandt(ID_smt_push_command)
134+
{
135+
set_size_t(ID_value, levels);
136+
}
137+
138+
size_t smt_push_commandt::levels() const
139+
{
140+
return get_size_t(ID_value);
141+
}
142+
143+
smt_pop_commandt::smt_pop_commandt(std::size_t levels)
144+
: smt_commandt(ID_smt_pop_command)
145+
{
146+
set_size_t(ID_value, levels);
147+
}
148+
149+
size_t smt_pop_commandt::levels() const
150+
{
151+
return get_size_t(ID_value);
152+
}
153+
154+
smt_set_logic_commandt::smt_set_logic_commandt(smt_logict logic)
155+
: smt_commandt(ID_smt_set_logic_command)
156+
{
157+
set(ID_value, upcast(std::move(logic)));
158+
}
159+
160+
const smt_logict &smt_set_logic_commandt::logic() const
161+
{
162+
return downcast(find(ID_value));
163+
}
164+
165+
smt_set_option_commandt::smt_set_option_commandt(smt_optiont option)
166+
: smt_commandt(ID_smt_set_option_command)
167+
{
168+
set(ID_value, upcast(std::move(option)));
169+
}
170+
171+
const smt_optiont &smt_set_option_commandt::option() const
172+
{
173+
return downcast(find(ID_value));
174+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/// \file
2+
/// This set of definitions is used as part of the
3+
/// [X-macro](https://en.wikipedia.org/wiki/X_Macro) pattern. These define the
4+
/// set of commands which are implemented and it is used to automate repetitive
5+
/// parts of the implementation. These include -
6+
/// * The constant `irep_idt`s used to identify each of the command classes.
7+
COMMAND_ID(assert)
8+
COMMAND_ID(check_sat)
9+
COMMAND_ID(declare_function)
10+
COMMAND_ID(define_function)
11+
COMMAND_ID(exit)
12+
COMMAND_ID(get_value)
13+
COMMAND_ID(pop)
14+
COMMAND_ID(push)
15+
COMMAND_ID(set_logic)
16+
COMMAND_ID(set_option)
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Author: Diffblue Ltd.
2+
3+
#ifndef CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_COMMANDS_H
4+
#define CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_COMMANDS_H
5+
6+
#include <solvers/smt2_incremental/smt_logics.h>
7+
#include <solvers/smt2_incremental/smt_options.h>
8+
#include <solvers/smt2_incremental/smt_terms.h>
9+
#include <util/irep.h>
10+
11+
class smt_commandt : protected irept
12+
{
13+
public:
14+
// smt_commandt does not support the notion of an empty / null state. Use
15+
// optionalt<smt_commandt> instead if an empty command is required.
16+
smt_commandt() = delete;
17+
18+
using irept::pretty;
19+
20+
bool operator==(const smt_commandt &) const;
21+
bool operator!=(const smt_commandt &) const;
22+
23+
protected:
24+
using irept::irept;
25+
};
26+
27+
class smt_assert_commandt : public smt_commandt,
28+
private smt_termt::storert<smt_assert_commandt>
29+
{
30+
public:
31+
explicit smt_assert_commandt(smt_termt condition);
32+
const smt_termt &condition() const;
33+
};
34+
35+
class smt_check_sat_commandt : public smt_commandt
36+
{
37+
public:
38+
smt_check_sat_commandt();
39+
};
40+
41+
class smt_declare_function_commandt
42+
: public smt_commandt,
43+
private smt_sortt::storert<smt_declare_function_commandt>,
44+
private smt_termt::storert<smt_declare_function_commandt>
45+
{
46+
public:
47+
smt_declare_function_commandt(
48+
smt_identifier_termt identifier,
49+
std::vector<smt_sortt> parameter_sorts);
50+
const smt_identifier_termt &identifier() const;
51+
const smt_sortt &return_sort() const;
52+
std::vector<std::reference_wrapper<const smt_sortt>> parameter_sorts() const;
53+
54+
private:
55+
using sort_storert = smt_sortt::storert<smt_declare_function_commandt>;
56+
using term_storert = smt_termt::storert<smt_declare_function_commandt>;
57+
};
58+
59+
class smt_define_function_commandt
60+
: public smt_commandt,
61+
private smt_termt::storert<smt_define_function_commandt>
62+
{
63+
public:
64+
smt_define_function_commandt(
65+
irep_idt identifier,
66+
std::vector<smt_identifier_termt> parameters,
67+
smt_termt definition);
68+
const irep_idt &identifier() const;
69+
std::vector<std::reference_wrapper<const smt_identifier_termt>>
70+
parameters() const;
71+
const smt_sortt &return_sort() const;
72+
const smt_termt &definition() const;
73+
};
74+
75+
class smt_exit_commandt : public smt_commandt
76+
{
77+
public:
78+
smt_exit_commandt();
79+
};
80+
81+
class smt_get_value_commandt : public smt_commandt,
82+
protected smt_termt::storert<smt_assert_commandt>
83+
{
84+
public:
85+
explicit smt_get_value_commandt(smt_termt descriptor);
86+
const smt_termt &descriptor() const;
87+
};
88+
89+
class smt_push_commandt : public smt_commandt
90+
{
91+
public:
92+
explicit smt_push_commandt(std::size_t levels);
93+
size_t levels() const;
94+
};
95+
96+
class smt_pop_commandt : public smt_commandt
97+
{
98+
public:
99+
explicit smt_pop_commandt(std::size_t levels);
100+
size_t levels() const;
101+
};
102+
103+
class smt_set_logic_commandt
104+
: public smt_commandt,
105+
private smt_logict::storert<smt_set_logic_commandt>
106+
{
107+
public:
108+
explicit smt_set_logic_commandt(smt_logict logic);
109+
const smt_logict &logic() const;
110+
};
111+
112+
class smt_set_option_commandt
113+
: public smt_commandt,
114+
private smt_optiont::storert<smt_set_option_commandt>
115+
{
116+
public:
117+
explicit smt_set_option_commandt(smt_optiont option);
118+
const smt_optiont &option() const;
119+
};
120+
121+
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_COMMANDS_H
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Author: Diffblue Ltd.
2+
3+
#include <solvers/smt2_incremental/smt_logics.h>
4+
5+
// Define the irep_idts for logics.
6+
#define LOGIC_ID(the_id) \
7+
const irep_idt ID_smt_logic_##the_id{"smt_logic_" #the_id};
8+
#include <solvers/smt2_incremental/smt_logics.def>
9+
#undef LOGIC_ID
10+
11+
bool smt_logict::operator==(const smt_logict &other) const
12+
{
13+
return irept::operator==(other);
14+
}
15+
16+
bool smt_logict::operator!=(const smt_logict &other) const
17+
{
18+
return !(*this == other);
19+
}
20+
21+
template <typename visitort>
22+
void accept(const smt_logict &logic, const irep_idt &id, visitort &&visitor)
23+
{
24+
#define LOGIC_ID(the_id) \
25+
if(id == ID_smt_logic_##the_id) \
26+
return visitor.visit(static_cast<const smt_logic_##the_id##t &>(logic));
27+
// The include below is marked as nolint because including the same file
28+
// multiple times is required as part of the x macro pattern.
29+
#include <solvers/smt2_incremental/smt_logics.def> // NOLINT(build/include)
30+
#undef LOGIC_ID
31+
UNREACHABLE;
32+
}
33+
34+
void smt_logict::accept(smt_logic_const_downcast_visitort &visitor) const
35+
{
36+
::accept(*this, id(), visitor);
37+
}
38+
39+
void smt_logict::accept(smt_logic_const_downcast_visitort &&visitor) const
40+
{
41+
::accept(*this, id(), std::move(visitor));
42+
}
43+
44+
smt_logic_quantifier_free_bit_vectorst::smt_logic_quantifier_free_bit_vectorst()
45+
: smt_logict{ID_smt_logic_quantifier_free_bit_vectors}
46+
{
47+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/// \file
2+
/// This set of definitions is used as part of the
3+
/// [X-macro](https://en.wikipedia.org/wiki/X_Macro) pattern. These define the
4+
/// set of options which are implemented and it is used to automate repetitive
5+
/// parts of the implementation. These include -
6+
/// * The constant `irep_idt`s used to identify each of the logic classes.
7+
/// * The member functions of the `smt_logic_const_downcast_visitort` class.
8+
/// * The type of option checks required to implement `smt_logict::accept`.
9+
LOGIC_ID(quantifier_free_bit_vectors)

0 commit comments

Comments
 (0)