Skip to content

Commit 8952469

Browse files
committed
Add parameterised function application factory
So that function specific INVARIANTS can be checked.
1 parent b7d5530 commit 8952469

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

src/solvers/smt2_incremental/smt_commands.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,51 @@ void smt_commandt::accept(smt_command_const_downcast_visitort &&visitor) const
198198
{
199199
::accept(*this, id(), std::move(visitor));
200200
}
201+
202+
smt_command_functiont::smt_command_functiont(
203+
const smt_declare_function_commandt &function_declaration)
204+
: _identifier(function_declaration.identifier())
205+
{
206+
const auto sort_references = function_declaration.parameter_sorts();
207+
parameter_sorts =
208+
make_range(sort_references).collect<decltype(parameter_sorts)>();
209+
}
210+
211+
smt_command_functiont::smt_command_functiont(
212+
const smt_define_function_commandt &function_definition)
213+
: _identifier{function_definition.identifier()}
214+
{
215+
const auto parameters = function_definition.parameters();
216+
parameter_sorts =
217+
make_range(parameters)
218+
.map([](const smt_termt &term) { return term.get_sort(); })
219+
.collect<decltype(parameter_sorts)>();
220+
}
221+
222+
irep_idt smt_command_functiont::identifier() const
223+
{
224+
return _identifier.identifier();
225+
}
226+
227+
smt_sortt smt_command_functiont::return_sort(
228+
const std::vector<smt_termt> &arguments) const
229+
{
230+
return _identifier.get_sort();
231+
}
232+
233+
void smt_command_functiont::validate(
234+
const std::vector<smt_termt> &arguments) const
235+
{
236+
INVARIANT(
237+
parameter_sorts.size() == arguments.size(),
238+
"Number of parameters and number of arguments must the the same.");
239+
const auto parameter_sort_arguments =
240+
make_range(parameter_sorts).zip(make_range(arguments));
241+
for(const auto &parameter_sort_argument_pair : parameter_sort_arguments)
242+
{
243+
INVARIANT(
244+
parameter_sort_argument_pair.first ==
245+
parameter_sort_argument_pair.second.get_sort(),
246+
"Sort of argument must have the same sort as the parameter.");
247+
}
248+
}

src/solvers/smt2_incremental/smt_commands.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,22 @@ class smt_command_const_downcast_visitort
132132
#undef COMMAND_ID
133133
};
134134

135+
/// \brief A function generated from a command. Used for validating function
136+
/// application term arguments.
137+
class smt_command_functiont
138+
{
139+
private:
140+
std::vector<smt_sortt> parameter_sorts;
141+
smt_identifier_termt _identifier;
142+
143+
public:
144+
explicit smt_command_functiont(
145+
const smt_declare_function_commandt &function_declaration);
146+
explicit smt_command_functiont(
147+
const smt_define_function_commandt &function_definition);
148+
irep_idt identifier() const;
149+
smt_sortt return_sort(const std::vector<smt_termt> &arguments) const;
150+
void validate(const std::vector<smt_termt> &arguments) const;
151+
};
152+
135153
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_COMMANDS_H

src/solvers/smt2_incremental/smt_terms.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,39 @@ class smt_bit_vector_constant_termt : public smt_termt
121121
class smt_function_application_termt : public smt_termt
122122
{
123123
public:
124+
// Public access is deprecated and will be replaced with the `of` factory
125+
// function which will perform checks relevant to the particular function
126+
// being applied. To be fixed before the end of this PR.
124127
smt_function_application_termt(
125128
smt_identifier_termt function_identifier,
126129
std::vector<smt_termt> arguments);
127130
const smt_identifier_termt &function_identifier() const;
128131
std::vector<std::reference_wrapper<const smt_termt>> arguments() const;
132+
133+
template <typename functiont>
134+
class factoryt
135+
{
136+
private:
137+
functiont function;
138+
139+
public:
140+
template <typename... function_type_argument_typest>
141+
explicit factoryt(function_type_argument_typest &&... arguments)
142+
: function{std::forward<function_type_argument_typest>(arguments)...}
143+
{
144+
}
145+
146+
template <typename... argument_typest>
147+
smt_function_application_termt
148+
operator()(argument_typest &&... arguments) const
149+
{
150+
function.validate(arguments...);
151+
auto return_sort = function.return_sort(arguments...);
152+
return smt_function_application_termt{
153+
smt_identifier_termt{function.identifier(), std::move(return_sort)},
154+
{std::forward<argument_typest>(arguments)...}};
155+
}
156+
};
129157
};
130158

131159
class smt_term_const_downcast_visitort

unit/solvers/smt2_incremental/smt_commands.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,15 @@ TEST_CASE("smt_set_option_commandt getter", "[core][smt2_incremental]")
9494
CHECK(smt_set_option_commandt{models_on}.option() == models_on);
9595
CHECK(smt_set_option_commandt{models_off}.option() == models_off);
9696
}
97+
98+
TEST_CASE("SMT2 function application factory tests", "[core][smt2_incremental]")
99+
{
100+
const smt_identifier_termt arbitary{"arbitary", smt_bool_sortt{}};
101+
const smt_declare_function_commandt function_declaration{
102+
arbitary, std::vector<smt_sortt>{smt_bool_sortt{}, smt_bool_sortt{}}};
103+
const smt_function_application_termt::factoryt<smt_command_functiont> factory{
104+
function_declaration};
105+
const smt_function_application_termt application =
106+
factory(std::vector<smt_termt>{smt_bool_literal_termt{true},
107+
smt_bool_literal_termt{false}});
108+
}

0 commit comments

Comments
 (0)