mCRL2
Loading...
Searching...
No Matches
translate_specification.h
Go to the documentation of this file.
1// Author(s): Thomas Neele
2// Copyright: see the accompanying file COPYING or copy at
3// https://github.com/mCRL2org/mCRL2/blob/master/COPYING
4//
5// Distributed under the Boost Software License, Version 1.0.
6// (See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt)
8
9#ifndef MCRL2_SMT_TRANSLATE_SPECIFICATION_H
10#define MCRL2_SMT_TRANSLATE_SPECIFICATION_H
11
12#include "mcrl2/atermpp/aterm_io.h"
13#include "mcrl2/core/detail/print_utility.h"
14#include "mcrl2/data/find.h"
15#include "mcrl2/smt/translate_expression.h"
16
17namespace mcrl2
18{
19namespace smt
20{
21namespace detail
22{
23
24template <typename OutputStream>
25inline
26void translate_sort_definition(const std::string& sort_name,
27 const data::sort_expression& s,
28 const data::data_specification& dataspec,
29 OutputStream& out,
30 const native_translations& nt,
31 std::map<data::structured_sort, std::string>& struct_name_map)
32{
33 auto find_result = nt.sorts.find(s);
34 if(find_result != nt.sorts.end())
35 {
36 // Do not output anything for natively defined sorts
37 return;
38 }
39
40 out << "(declare-datatypes () ((" << translate_identifier(sort_name) << " ";
41 for(const data::function_symbol& cons: dataspec.constructors(s))
42 {
43 out << "(" << translate_identifier(cons.name()) << " ";
44 if(data::is_function_sort(cons.sort()))
45 {
46 const data::function_sort& cs = atermpp::down_cast<data::function_sort>(cons.sort());
47 std::size_t index = 0;
48 for(const data::sort_expression& arg: cs.domain())
49 {
50 out << "(" << make_projection_name(cons, index, nt) << " ";
51 translate_sort_expression(arg, out, nt, struct_name_map);
52 out << ") ";
53 index++;
54 }
55 }
56 out << ") ";
57 }
58 out << ")))\n";
59}
60
61template <typename OutputStream>
62inline
64 const data::data_specification& dataspec,
65 OutputStream& out,
66 const native_translations& nt,
67 std::map<data::structured_sort, std::string>& struct_name_map)
68{
69 translate_sort_definition(pp(s.name()), s, dataspec, out, nt, struct_name_map);
70}
71
72// Find the dependencies in the definition of a sort
73static inline
75{
76 std::set<data::sort_expression> dependencies;
77 for(const data::function_symbol& cons: dataspec.constructors(sort))
78 {
79 find_sort_expressions(cons, std::inserter(dependencies, dependencies.end()));
80 }
81
82 std::set<data::sort_expression> result;
83 for(const data::sort_expression& s: dependencies)
84 {
85 if((data::is_basic_sort(s) || data::is_structured_sort(s)) && s != sort)
86 {
87 result.insert(s);
88 }
89 }
90 return result;
91}
92
93// Find all sorts that need to be translated and the dependencies in their definitions
94inline
97{
98 std::map<data::sort_expression, std::set<data::sort_expression>> result;
99 for(const data::sort_expression& s: dataspec.sorts())
100 {
101 if(data::is_function_sort(s))
102 {
103 // SMT-LIB2 does not support function sorts
104 // Hope & pray that nothing breaks later...
105 continue;
106 }
107 auto find_alias = dataspec.sort_alias_map().find(s);
108 if(find_alias != dataspec.sort_alias_map().end() && find_alias->second != s)
109 {
110 if(data::is_structured_sort(s))
111 {
112 struct_name_map[atermpp::down_cast<data::structured_sort>(s)] = pp(find_alias->second);
113 }
114 // translate only the unique representation of a sort
115 continue;
116 }
117
118 result[s] = find_dependencies(dataspec, s);
119 }
120 return result;
121}
122
123template <typename OutputStream>
124inline
126 OutputStream& out,
127 const native_translations& nt,
129 std::map<data::structured_sort, std::string>& struct_name_map)
130{
131 auto sort_dependencies = find_sorts_and_dependencies(dataspec, struct_name_map);
132 // for(const auto& p: sort_dependencies)
133 // {
134 // std::cout << p.first << " := " << core::detail::print_set(p.second) << std::endl;
135 // }
136 auto sorts = topological_sort(sort_dependencies);
137 for(const data::sort_expression& s: sorts)
138 {
139 std::string name(pp(s));
140 if(data::is_structured_sort(s))
141 {
142 // The structured sort is anonymous. Can happen in a specification such as
143 // sort StateList = List(struct s1 | s2);
144 name = pp(id_gen("@struct"));
145 struct_name_map[atermpp::down_cast<data::structured_sort>(s)] = name;
146 }
147 translate_sort_definition(name, s, dataspec, out, nt, struct_name_map);
148 }
149}
150
151
152
153template <typename OutputStream>
154inline
156 OutputStream& out, const native_translations& nt,
157 const std::map<data::structured_sort, std::string>& struct_name_map)
158{
159 out << "(define-sort " << translate_identifier(s.name().name()) << " () ";
160 translate_sort_expression(s.reference(), out, nt, struct_name_map);
161 out << ")\n";
162}
163
164inline
166{
167 const data::sort_expression& s = f.sort();
169 {
170 const data::function_sort& fs = atermpp::down_cast<data::function_sort>(s);
171 for(const data::sort_expression& arg: fs.domain())
172 {
173 if(data::is_function_sort(arg))
174 {
175 return true;
176 }
177 }
178 }
179 return false;
180}
181
182inline
183bool is_higher_order(const data::application& a)
184{
186 {
187 auto& f = atermpp::down_cast<data::function_symbol>(a.head());
188 return is_higher_order(f);
189 }
190 return true;
191}
192
193inline
195{
196 const data::data_expression& lhs = eq.lhs();
198 {
200 }
201 else if(data::is_application(lhs) && data::is_function_symbol(atermpp::down_cast<data::application>(lhs).head()))
202 {
203 return is_higher_order(atermpp::down_cast<data::function_symbol>(atermpp::down_cast<data::application>(lhs).head()));
204 }
205 else
206 {
207 return true;
208 }
209}
210
211template <typename OutputStream>
212inline
213void translate_mapping(const data::function_symbol& f, OutputStream& out, const native_translations& nt,
214 const std::map<data::structured_sort, std::string>& snm, bool check_native = true)
215{
216 if(is_higher_order(f) || (check_native && nt.has_native_definition(f)))
217 {
218 return;
219 }
220
221 out << "(declare-fun " << translate_symbol(f, nt) << " ";
223 {
224 out << "(";
226 for(const data::sort_expression& s: fs.domain())
227 {
228 translate_sort_expression(s, out, nt, snm);
229 out << " ";
230 }
231 out << ") ";
232 translate_sort_expression(fs.codomain(), out, nt, snm);
233 }
234 else
235 {
236 out << "() ";
237 translate_sort_expression(f.sort(), out, nt, snm);
238 }
239 out << ")\n";
240}
241
242template <typename OutputStream>
243inline
244void translate_native_mappings(OutputStream& out,
245 std::unordered_map<data::data_expression, std::string>& c,
246 const native_translations& nt,
247 const std::map<data::structured_sort, std::string>& snm)
248{
249 out << "(define-funs-rec (\n";
250 for(const auto& [mapping, eqn]: nt.mappings)
251 {
252 if(is_higher_order(mapping))
253 {
254 continue;
255 }
256 mCRL2log(log::verbose) << "Outputting " << mapping << ": " << mapping.sort() << " with eqn " << eqn << std::endl;
257
258 out << "(" << translate_symbol(mapping, nt) << " ";
259 data::data_expression condition = declare_variables_binder(eqn.variables(), out, nt);
260 out << " ";
261 translate_sort_expression(mapping.sort().target_sort(), out, nt, snm);
262 out << ")\n";
263 }
264 out << ")\n";
265
266 out << "(\n";
267 for(const auto& [mapping, eqn]: nt.mappings)
268 {
269 if(is_higher_order(mapping))
270 {
271 continue;
272 }
273
274 translate_data_expression(eqn.rhs(), out, c, nt);
275 out << "\n";
276 }
277 out << "))\n";
278}
279
280template <typename OutputStream>
281inline
283 OutputStream& out,
284 std::unordered_map<data::data_expression, std::string>& c,
285 const native_translations& nt)
286{
288 {
289 return;
290 }
291
292 const data::variable_list& vars = eq.variables();
294 data::data_expression definition(vars.empty() ? body : data::forall(vars, body));
295
296 translate_assertion(definition, out, c, nt);
297}
298
299} // namespace detail
300
301template <typename OutputStream>
303 OutputStream& o,
304 std::unordered_map<data::data_expression, std::string>& c,
305 const native_translations& nt)
306{
307 // Generator for new names of projection functions and structs
309 // Inline struct definitions are anonymous, we keep track of a newly-generate name for each
310 std::map<data::structured_sort, std::string> struct_name_map;
311
312 // Translate sorts
313 detail::translate_sort_definitions(dataspec, o, nt, id_gen, struct_name_map);
314 for(const auto& s: dataspec.sort_alias_map())
315 {
316 if(data::is_basic_sort(s.first))
317 {
318 detail::translate_alias(data::alias(atermpp::down_cast<data::basic_sort>(s.first), s.second), o, nt, struct_name_map);
319 }
320 }
321
322 // Translate mappings
323 for(const data::function_symbol& f: dataspec.mappings())
324 {
325 detail::translate_mapping(f, o, nt, struct_name_map);
326 }
327 detail::translate_native_mappings(o, c, nt, struct_name_map);
328
329 // Translate remaining equations
330 for(const data::data_equation& eq: dataspec.equations())
331 {
332 detail::translate_equation(eq, o, c, nt);
333 }
334}
335
336} // namespace smt
337} // namespace mcrl2
338
339#endif
\brief A sort alias
Definition alias.h:26
\brief A basic sort
Definition basic_sort.h:26
\brief A data equation
const data_expression & lhs() const
const data_expression & condition() const
const data_expression & rhs() const
const variable_list & variables() const
sort_expression sort() const
Returns the sort of the data expression.
Definition data.cpp:108
application operator()(const data_expression &e) const
Apply a data expression to a data expression.
\brief A function sort
\brief A function symbol
const sort_expression & sort() const
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
\brief A sort expression
\brief A data variable
Definition variable.h:28
answer solve(const data::variable_list &vars, const data::data_expression &expr, const std::chrono::microseconds &timeout=std::chrono::microseconds::zero())
Definition solver.cpp:54
answer execute_and_check(const std::string &command, const std::chrono::microseconds &timeout) const
Definition solver.cpp:21
smt_solver(const data::data_specification &dataspec)
Definition solver.cpp:45
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:391
The main namespace for the aterm++ library.
Definition algorithm.h:21
A collection of utilities for lazy expression construction.
data_expression implies(data_expression const &p, data_expression const &q)
Returns an expression equivalent to p implies q.
Namespace for system defined sort bool_.
Definition bool.h:32
const basic_sort & bool_()
Constructor for sort expression Bool.
Definition bool.h:44
const function_symbol & implies()
Constructor for function symbol =>.
Definition bool.h:363
const function_symbol & and_()
Constructor for function symbol &&.
Definition bool.h:235
const function_symbol & false_()
Constructor for function symbol false.
Definition bool.h:109
const function_symbol & or_()
Constructor for function symbol ||.
Definition bool.h:299
const function_symbol & not_()
Constructor for function symbol !.
Definition bool.h:173
const function_symbol & true_()
Constructor for function symbol true.
Definition bool.h:77
Namespace for system defined sort int_.
const function_symbol & pos2int()
Constructor for function symbol Pos2Int.
Definition int1.h:360
const function_symbol & int2nat()
Constructor for function symbol Int2Nat.
Definition int1.h:298
const function_symbol & nat2int()
Constructor for function symbol Nat2Int.
Definition int1.h:236
const function_symbol & cneg()
Constructor for function symbol @cNeg.
Definition int1.h:142
const function_symbol & int2pos()
Constructor for function symbol Int2Pos.
Definition int1.h:422
const function_symbol & cint()
Constructor for function symbol @cInt.
Definition int1.h:80
const basic_sort & int_()
Constructor for sort expression Int.
Definition int1.h:47
Namespace for system defined sort nat.
const function_symbol & c0()
Constructor for function symbol @c0.
Definition nat1.h:108
const function_symbol & cnat()
Constructor for function symbol @cNat.
Definition nat1.h:140
const basic_sort & nat()
Constructor for sort expression Nat.
Definition nat1.h:46
const function_symbol & nat2pos()
Constructor for function symbol Nat2Pos.
Definition nat1.h:362
const function_symbol & pos2nat()
Constructor for function symbol Pos2Nat.
Definition nat1.h:300
Namespace for system defined sort pos.
const function_symbol & c1()
Constructor for function symbol @c1.
Definition pos1.h:78
const function_symbol & cdub()
Constructor for function symbol @cDub.
Definition pos1.h:110
const basic_sort & pos()
Constructor for sort expression Pos.
Definition pos1.h:45
Namespace for system defined sort real_.
const function_symbol & creal()
Constructor for function symbol @cReal.
Definition real1.h:107
const function_symbol & pos2real()
Constructor for function symbol Pos2Real.
Definition real1.h:171
const function_symbol & real2nat()
Constructor for function symbol Real2Nat.
Definition real1.h:419
const function_symbol & real2int()
Constructor for function symbol Real2Int.
Definition real1.h:481
const basic_sort & real_()
Constructor for sort expression Real.
Definition real1.h:48
const function_symbol & nat2real()
Constructor for function symbol Nat2Real.
Definition real1.h:233
const function_symbol & int2real()
Constructor for function symbol Int2Real.
Definition real1.h:295
const function_symbol & real2pos()
Constructor for function symbol Real2Pos.
Definition real1.h:357
Namespace for all data library functionality.
Definition data.cpp:22
bool is_application(const data_expression &t)
Returns true if the term t is an application.
bool is_function_symbol(const atermpp::aterm &x)
Returns true if the term t is a function symbol.
atermpp::term_list< variable > variable_list
\brief list of variables
bool is_function_sort(const atermpp::aterm &x)
Returns true if the term t is a function sort.
function_symbol equal_to(const sort_expression &s)
Constructor for function symbol ==.
Definition standard.h:126
application equal_to(const data_expression &arg0, const data_expression &arg1)
Application of function symbol ==.
Definition standard.h:144
void translate_sort_definitions(const data::data_specification &dataspec, OutputStream &out, const native_translations &nt, data::set_identifier_generator &id_gen, std::map< data::structured_sort, std::string > &struct_name_map)
void translate_sort_definition(const std::string &sort_name, const data::sort_expression &s, const data::data_specification &dataspec, OutputStream &out, const native_translations &nt, std::map< data::structured_sort, std::string > &struct_name_map)
void translate_mapping(const data::function_symbol &f, OutputStream &out, const native_translations &nt, const std::map< data::structured_sort, std::string > &snm, bool check_native=true)
static const native_translation_t pp_real_translation
Definition solver.cpp:91
void translate_equation(const data::data_equation &eq, OutputStream &out, std::unordered_map< data::data_expression, std::string > &c, const native_translations &nt)
static const native_translation_t pp_translation
Definition solver.cpp:85
bool is_higher_order(const data::application &a)
bool is_higher_order(const data::function_symbol &f)
std::map< data::sort_expression, std::set< data::sort_expression > > find_sorts_and_dependencies(const data::data_specification &dataspec, std::map< data::structured_sort, std::string > &struct_name_map)
void translate_alias(const data::alias &s, OutputStream &out, const native_translations &nt, const std::map< data::structured_sort, std::string > &struct_name_map)
void translate_sort_definition(const data::basic_sort &s, const data::data_specification &dataspec, OutputStream &out, const native_translations &nt, std::map< data::structured_sort, std::string > &struct_name_map)
static const native_translation_t reconstruct_divmod
Definition solver.cpp:99
static std::set< data::sort_expression > find_dependencies(const data::data_specification &dataspec, const data::sort_expression &sort)
bool is_higher_order(const data::data_equation &eq)
void translate_native_mappings(OutputStream &out, std::unordered_map< data::data_expression, std::string > &c, const native_translations &nt, const std::map< data::structured_sort, std::string > &snm)
native_translations initialise_native_translation(const data::data_specification &dataspec)
Definition solver.cpp:126
void translate_data_specification(const data::data_specification &dataspec, OutputStream &o, std::unordered_map< data::data_expression, std::string > &c, const native_translations &nt)
void unfold_pattern_matching(const data::data_specification &dataspec, native_translations &nt)
std::function< void(data::data_expression, std::function< void(std::string)>, std::function< void(data::data_expression)>)> native_translation_t
@ UNKNOWN
Definition answer.h:24
fixed_string_translation(const std::string &s)
Definition solver.cpp:73
void operator()(const data::data_expression &, const std::function< void(std::string)> &output_func, const std::function< void(data::data_expression)> &) const
Definition solver.cpp:77
void set_native_definition(const data::function_symbol &f)
Record that the mapping and equations for f should not be translated.
bool has_native_definition(const data::function_symbol &f) const
bool has_native_definition(const data::data_equation &eq) const
std::size_t operator()(const atermpp::detail::reference_aterm< T > &t) const