mCRL2
Loading...
Searching...
No Matches
translate_expression.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_EXPRESSION_H
10#define MCRL2_SMT_TRANSLATE_EXPRESSION_H
11
12#include "mcrl2/smt/translate_sort.h"
13
14namespace mcrl2
15{
16namespace smt
17{
18
19template <typename T, typename OutputStream>
20void translate_data_expression(const T& x,
21 OutputStream& o,
22 std::unordered_map<data::data_expression, std::string>& c,
23 const native_translations& nt);
24
25namespace detail
26{
27
29{
30 std::string f_pp(translate_symbol(f, nt));
31 if (nt.is_ambiguous(f))
32 {
33 std::ostringstream o;
34 translate_sort_expression(f.sort().target_sort(), o, nt);
35 return "(as " + f_pp + " " + o.str() + ")";
36 }
37 else
38 {
39 return f_pp;
40 }
41}
42
43/**
44 * \brief Declare variables to be used in binder such as exists or forall and print the declaration to out
45 * \return An expression that constrains the domains of Pos and Nat variables
46 */
47template <typename OutputStream>
49declare_variables_binder(const data::variable_list& vars, OutputStream& out, const native_translations& nt)
50{
52 out << "(";
53 for (const data::variable& var : vars)
54 {
55 out << "(" << translate_identifier(var.name()) << " ";
56 translate_sort_expression(var.sort(), out, nt);
57 out << ")";
58 if (var.sort() == data::sort_pos::pos())
59 {
60 result = data::lazy::and_(result, greater_equal(var, data::sort_pos::c1()));
61 }
62 else if (var.sort() == data::sort_nat::nat())
63 {
64 result = data::lazy::and_(result, greater_equal(var, data::sort_nat::c0()));
65 }
66 }
67 out << ")";
68 return result;
69}
70
71template <template <class> class Traverser, class OutputStream>
74{
76 using super::apply;
77
78 stack_outstream<OutputStream> out;
81
83 std::unordered_map<data::data_expression, std::string>& cache,
84 const native_translations& nt)
85 : out(out_),
87 m_native(nt)
88 {}
89
90 void apply(const data::data_expression& d)
91 {
92 auto c = m_cache.find(d);
93 if (c == m_cache.end())
94 {
95 out.push();
96 super::apply(d);
97 if (out.top_size() <= 400)
98 {
99 out.copy_top(m_cache[d]);
100 }
101 out.pop();
102 }
103 else
104 {
105 out << c->second;
106 }
107 }
108
109 void apply(const data::application& v)
110 {
111 auto find_result = m_native.find_native_translation(v);
112 if (find_result != m_native.expressions.end())
113 {
114 auto translate_func = [&](const data::data_expression& e)
115 {
116 return apply(e);
117 };
118 auto output_func = [&](const std::string& s)
119 {
120 out << s;
121 };
122 find_result->second(v, output_func, translate_func);
123 out << " ";
124 }
125 else
126 {
127 out << "(";
128 super::apply(v);
129 out << ") ";
130 }
131 }
132
133 void apply(const data::function_symbol& v) { out << translate_symbol_disambiguate(v, m_native) << " "; }
134
135 void apply(const data::variable& v) { out << translate_identifier(v.name()) << " "; }
136
137 void apply(const data::forall& v)
138 {
139 out << "(forall ";
140 data::data_expression vars_conditions = declare_variables_binder(v.variables(), out, m_native);
141 out << " ";
142 apply(data::lazy::implies(vars_conditions, v.body()));
143 out << ")";
144 }
145
146 void apply(const data::exists& v)
147 {
148 out << "(exists ";
149 data::data_expression vars_conditions = declare_variables_binder(v.variables(), out, m_native);
150 out << " ";
151 apply(data::lazy::and_(vars_conditions, v.body()));
152 out << ")";
153 }
154
155 void apply(const data::where_clause& v)
156 {
157 out << "(let (";
158 for (const data::assignment_expression& a : v.declarations())
159 {
160 const data::assignment& as = atermpp::down_cast<data::assignment>(a);
161 out << "(";
162 apply(as.lhs());
163 out << " ";
164 apply(as.rhs());
165 out << ")";
166 }
167 out << ") ";
168 apply(v.body());
169 out << ")";
170 }
171};
172
173} // namespace detail
174
175template <typename T, typename OutputStream>
177 OutputStream& o,
178 std::unordered_map<data::data_expression, std::string>& c,
179 const native_translations& nt)
180{
181 detail::translate_data_expression_traverser<data::data_expression_traverser, OutputStream>(o, c, nt).apply(x);
182}
183
184template <typename T, typename OutputStream>
185void translate_assertion(const T& x,
186 OutputStream& o,
187 std::unordered_map<data::data_expression, std::string>& c,
188 const native_translations& nt)
189{
190 o << "(assert ";
191 translate_data_expression(x, o, c, nt);
192 o << ")\n";
193}
194
195template <typename Container, typename OutputStream>
196void translate_variable_declaration(const Container& vars,
197 OutputStream& o,
198 std::unordered_map<data::data_expression, std::string>& c,
199 const native_translations& nt)
200{
202 for (const data::variable& v : vars)
203 {
204 o << "(declare-fun " << translate_identifier(v.name()) << " (";
205
206 data::sort_expression_list domain = data::is_function_sort(v.sort())
207 ? atermpp::down_cast<data::function_sort>(v.sort()).domain()
208 : data::sort_expression_list();
209 for (const data::sort_expression& s : domain)
210 {
211 translate_sort_expression(s, o, nt);
212 o << " ";
213 // This does not seem to work when translating variables of a function sort.
214 // if(s == data::sort_pos::pos())
215 // {
216 // vars_conditions = data::lazy::and_(vars_conditions, greater_equal(v, data::sort_pos::c1()));
217 // }
218 // else if(s == data::sort_nat::nat())
219 // {
220 // vars_conditions = data::lazy::and_(vars_conditions, greater_equal(v, data::sort_nat::c0()));
221 // }
222 }
223 // Add assertions for positive and natural numbers
225 {
226 vars_conditions = data::lazy::and_(vars_conditions, greater_equal(v, data::sort_pos::c1()));
227 }
229 {
230 vars_conditions = data::lazy::and_(vars_conditions, greater_equal(v, data::sort_nat::c0()));
231 }
232 o << ") ";
233 translate_sort_expression(v.sort().target_sort(), o, nt);
234 o << ")\n";
235 }
236 translate_assertion(vars_conditions, o, c, nt);
237}
238
239} // namespace smt
240} // namespace mcrl2
241
242#endif
bool operator==(const unprotected_aterm_core &t) const
Comparison operator.
Definition aterm_core.h:83
const variable_list & variables() const
Definition abstraction.h:63
const data_expression & body() const
Definition abstraction.h:68
\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
data_expression & operator=(data_expression &&) noexcept=default
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.
existential quantification.
Definition exists.h:26
universal quantification.
Definition forall.h:26
\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
const sort_expression & target_sort() const
Returns the target sort of this expression.
\brief A data variable
Definition variable.h:28
const sort_expression & sort() const
Definition variable.h:43
\brief A where expression
const data_expression & body() const
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.
data_expression and_(data_expression const &p, data_expression const &q)
Returns an expression equivalent to p or 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.
atermpp::term_list< sort_expression > sort_expression_list
\brief list of sort_expressions
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
application greater_equal(const data_expression &arg0, const data_expression &arg1)
Application of function symbol >=.
Definition standard.h:369
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)
std::string translate_symbol_disambiguate(const data::function_symbol &f, const native_translations &nt)
data::data_expression declare_variables_binder(const data::variable_list &vars, OutputStream &out, const native_translations &nt)
Declare variables to be used in binder such as exists or forall and print the declaration to out.
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)
void translate_assertion(const T &x, OutputStream &o, std::unordered_map< data::data_expression, std::string > &c, const native_translations &nt)
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)
void translate_variable_declaration(const Container &vars, OutputStream &o, std::unordered_map< data::data_expression, std::string > &c, const native_translations &nt)
void translate_data_expression(const T &x, OutputStream &o, std::unordered_map< data::data_expression, std::string > &c, const 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
Traverser< translate_data_expression_traverser< Traverser, OutputStream > > super
translate_data_expression_traverser(OutputStream &out_, std::unordered_map< data::data_expression, std::string > &cache, const native_translations &nt)
std::unordered_map< data::data_expression, std::string > & m_cache
bool is_ambiguous(const data::function_symbol &f) const
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