33#ifndef CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_TERMS_H
44#define CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_TERMS_H
55
6- #include < solvers/smt2_incremental/smt_sorts.h>
76#include < util/irep.h>
87
8+ #include < solvers/smt2_incremental/smt_index.h>
9+ #include < solvers/smt2_incremental/smt_sorts.h>
10+ #include < solvers/smt2_incremental/type_traits.h>
11+
912#include < functional>
13+ #include < utility>
1014
1115class BigInt ;
1216using mp_integer = BigInt;
@@ -77,7 +81,14 @@ class smt_bool_literal_termt : public smt_termt
7781
7882// / Stores identifiers in unescaped and unquoted form. Any escaping or quoting
7983// / required should be performed during printing.
80- class smt_identifier_termt : public smt_termt
84+ // / \details
85+ // / The SMT-LIB standard Version 2.6 refers to "indexed" identifiers which have
86+ // / 1 or more indices and "simple" identifiers which have no indicies. The
87+ // / internal `smt_identifier_termt` class is used for both kinds of identifier
88+ // / which are distinguished based on whether the collection of `indices` is
89+ // / empty or not.
90+ class smt_identifier_termt : public smt_termt ,
91+ private smt_indext::storert<smt_identifier_termt>
8192{
8293public:
8394 // / \brief Constructs an identifier term with the given \p identifier and
@@ -91,8 +102,14 @@ class smt_identifier_termt : public smt_termt
91102 // / \param sort: The sort which this term will have. All terms in our abstract
92103 // / form must be sorted, even if those sorts are not printed in all
93104 // / contexts.
94- smt_identifier_termt (irep_idt identifier, smt_sortt sort);
105+ // / \param indices: This should be collection of indices for an indexed
106+ // / identifier, or an empty collection for simple (non-indexed) identifiers.
107+ smt_identifier_termt (
108+ irep_idt identifier,
109+ smt_sortt sort,
110+ std::vector<smt_indext> indices = {});
95111 irep_idt identifier () const ;
112+ std::vector<std::reference_wrapper<const smt_indext>> indices () const ;
96113};
97114
98115class smt_bit_vector_constant_termt : public smt_termt
@@ -121,6 +138,44 @@ class smt_function_application_termt : public smt_termt
121138 smt_identifier_termt function_identifier,
122139 std::vector<smt_termt> arguments);
123140
141+ // This is used to detect if \p functiont has an `indicies` member function.
142+ // It will resolve to std::true_type if it does or std::false type otherwise.
143+ template <class functiont , class = void >
144+ struct has_indicest : std::false_type
145+ {
146+ };
147+
148+ template <class functiont >
149+ struct has_indicest <
150+ functiont,
151+ void_t <decltype (std::declval<functiont>().indices())>> : std::true_type
152+ {
153+ };
154+
155+ // / Overload for when \p functiont does not have indices.
156+ template <class functiont >
157+ static std::vector<smt_indext>
158+ indices (const functiont &function, const std::false_type &has_indices)
159+ {
160+ return {};
161+ }
162+
163+ // / Overload for when \p functiont has indices member function.
164+ template <class functiont >
165+ static std::vector<smt_indext>
166+ indices (const functiont &function, const std::true_type &has_indices)
167+ {
168+ return function.indices ();
169+ }
170+
171+ // / Returns `function.indices` if `functiont` has an `indices` member function
172+ // / or returns an empty collection otherwise.
173+ template <class functiont >
174+ static std::vector<smt_indext> indices (const functiont &function)
175+ {
176+ return indices (function, has_indicest<functiont>{});
177+ }
178+
124179public:
125180 const smt_identifier_termt &function_identifier () const ;
126181 std::vector<std::reference_wrapper<const smt_termt>> arguments () const ;
@@ -133,7 +188,7 @@ class smt_function_application_termt : public smt_termt
133188
134189 public:
135190 template <typename ... function_type_argument_typest>
136- explicit factoryt (function_type_argument_typest &&... arguments)
191+ explicit factoryt (function_type_argument_typest &&... arguments) noexcept
137192 : function{std::forward<function_type_argument_typest>(arguments)...}
138193 {
139194 }
@@ -145,7 +200,8 @@ class smt_function_application_termt : public smt_termt
145200 function.validate (arguments...);
146201 auto return_sort = function.return_sort (arguments...);
147202 return smt_function_application_termt{
148- smt_identifier_termt{function.identifier (), std::move (return_sort)},
203+ smt_identifier_termt{
204+ function.identifier (), std::move (return_sort), indices (function)},
149205 {std::forward<argument_typest>(arguments)...}};
150206 }
151207 };
0 commit comments