mCRL2
Loading...
Searching...
No Matches
replace_capture_avoiding.h
Go to the documentation of this file.
1// Author(s): Wieger Wesselink
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//
11
12#ifndef MCRL2_DATA_REPLACE_CAPTURE_AVOIDING_H
13#define MCRL2_DATA_REPLACE_CAPTURE_AVOIDING_H
14
16#include "mcrl2/data/builder.h"
17#include "mcrl2/data/find.h"
18
19namespace mcrl2 {
20
21namespace data {
22
23namespace detail {
24
25// Wraps a substitution, such that assignments to variables can be added and removed.
26template <typename Substitution>
28{
29 Substitution& sigma;
31 std::map<variable, std::list<variable>> updates;
32
34 : sigma(sigma_), id_generator(id_generator_)
35 {}
36
37 // adds the assignment [v := v'] to sigma, and returns v'
39 {
40 variable v1(id_generator(v.name()), v.sort());
41 updates[v].push_back(v1);
42 return v1;
43 }
44
45 // removes the assignment [v := v'] from sigma
47 {
48 auto i = updates.find(v);
49 id_generator.remove_identifier(i->second.back().name());
50 i->second.pop_back();
51 if (i->second.empty())
52 {
53 updates.erase(i);
54 }
55 }
56
57 // adds the assignments [variables := variables'] to sigma, and returns variables'
58 template <typename VariableContainer>
59 variable_list add_fresh_variable_assignments(const VariableContainer& variables)
60 {
61 return variable_list(
62 variables.begin(),
63 variables.end(),
64 [&](const variable& v)
65 {
66 return add_fresh_variable_assignment(v);
67 }
68 );
69 }
70
71 // removes the assignments [variables := variables'] from sigma
72 template <typename VariableContainer>
73 void remove_fresh_variable_assignments(const VariableContainer& variables)
74 {
75 for (const variable& v: variables)
76 {
78 }
79 }
80
82 {
83 auto i = updates.find(x);
84 if (i != updates.end())
85 {
86 return i->second.back();
87 }
88 else
89 {
90 return sigma(x);
91 }
92 }
93};
94
95template <typename Substitution>
97{
98 std::vector<std::string> updates;
99 for (const auto& p: sigma.updates)
100 {
101 updates.push_back(data::pp(p.first) + " := " + core::detail::print_list(p.second));
102 }
103 return out << sigma.sigma << " with updates " << core::detail::print_list(updates);
104}
105
106template <template <class> class Builder, template <template <class> class, class, class> class Binder, class Substitution>
107struct replace_capture_avoiding_variables_builder: public Binder<Builder, replace_capture_avoiding_variables_builder<Builder, Binder, Substitution>, Substitution>
108{
109 typedef Binder<Builder, replace_capture_avoiding_variables_builder<Builder, Binder, Substitution>, Substitution> super;
110 using super::enter;
111 using super::leave;
112 using super::apply;
113 using super::update;
114
116 : super(sigma)
117 { }
118};
119
120template <template <class> class Builder, template <template <class> class, class, class> class Binder, class Substitution>
121replace_capture_avoiding_variables_builder<Builder, Binder, Substitution>
123{
125}
126
127template <template <class> class Builder, class Derived, class Substitution>
128struct add_capture_avoiding_replacement: public Builder<Derived>
129{
130 typedef Builder<Derived> super;
131 using super::enter;
132 using super::leave;
133 using super::apply;
134 using super::update;
135
137
139 : sigma(sigma_)
140 { }
141
142 // applies the substitution to the right hand sides of the assignments
143 template <class T>
145 {
146 result = assignment_list(
147 x.begin(),
148 x.end(),
149 [&](data::assignment&r, const data::assignment& a)
150 {
151 data::make_assignment(r, a.lhs(), [&](data_expression& r){ apply(r, a.rhs() ); } );
152 }
153 );
154 }
155
156 template <class T>
157 void apply(T& result, const variable& v)
158 {
159 result = sigma(v);
160 }
161
162 template <class T>
163 void apply(T& result, const data::where_clause& x)
164 {
165 const auto& declarations = atermpp::container_cast<data::assignment_list>(x.declarations());
166
167 auto declarations1 = data::assignment_list(
168 declarations.begin(),
169 declarations.end(),
170 [&](const assignment& a)
171 {
172 const data::variable& v = a.lhs();
173 const data_expression& x1 = a.rhs();
174 // add the assignment [v := v'] to sigma
175 data::variable v1 = sigma.add_fresh_variable_assignment(v);
176 data::data_expression rhs;
177 apply(rhs, x1);
178 return assignment(v1, rhs);
179 }
180 );
182 apply(body, x.body());
183 make_where_clause(result, body, declarations1);
184
185 // remove the assignments [v := v'] from sigma
186 for (const assignment& a: declarations)
187 {
188 const variable& v = a.lhs();
189 sigma.remove_fresh_variable_assignment(v);
190 }
191 }
192
193 template <class T>
194 void apply(T& result, const data::forall& x)
195 {
196 variable_list v1 = sigma.add_fresh_variable_assignments(x.variables());
198 apply(body, x.body());
199 data::make_forall(result, v1, body);
200 sigma.remove_fresh_variable_assignments(x.variables());
201 }
202
203 template <class T>
204 void apply(T& result, const data::exists& x)
205 {
206 variable_list v1 = sigma.add_fresh_variable_assignments(x.variables());
208 apply(body, x.body());
209 data::make_exists(result, v1, body);
210 sigma.remove_fresh_variable_assignments(x.variables());
211 }
212
213 template <class T>
214 void apply(T& result, const data::lambda& x)
215 {
216 variable_list v1 = sigma.add_fresh_variable_assignments(x.variables());
218 apply(body, x.body());
219 data::make_lambda(result, v1, body);
220 sigma.remove_fresh_variable_assignments(x.variables());
221 }
222
223 template <class T>
224 void apply(T& /* result */, data_equation& /* x */)
225 {
226 throw mcrl2::runtime_error("not implemented yet");
227 }
228};
229
230} // namespace detail
231
232//--- start generated data replace_capture_avoiding code ---//
237template <typename T, typename Substitution>
239 Substitution& sigma,
240 data::set_identifier_generator& id_generator,
241 typename std::enable_if<!std::is_base_of<atermpp::aterm, T>::value>::type* = nullptr
242)
243{
245 data::detail::apply_replace_capture_avoiding_variables_builder<data::data_expression_builder, data::detail::add_capture_avoiding_replacement>(sigma1).update(x);
246}
247
252template <typename T, typename Substitution>
254 Substitution& sigma,
255 data::set_identifier_generator& id_generator,
256 typename std::enable_if<std::is_base_of<atermpp::aterm, T>::value>::type* = nullptr
257)
258{
260 T result;
261 data::detail::apply_replace_capture_avoiding_variables_builder<data::data_expression_builder, data::detail::add_capture_avoiding_replacement>(sigma1).apply(result, x);
262 return result;
263}
264
268template <typename T, typename Substitution>
270 Substitution& sigma,
271 typename std::enable_if<!std::is_base_of<atermpp::aterm, T>::value>::type* = nullptr
272)
273{
277 {
278 id_generator.add_identifier(v.name());
279 }
281}
282
286template <typename T, typename Substitution>
288 Substitution& sigma,
289 typename std::enable_if<std::is_base_of<atermpp::aterm, T>::value>::type* = nullptr
290)
291{
295 {
296 id_generator.add_identifier(v.name());
297 }
298 return data::replace_variables_capture_avoiding(x, sigma, id_generator);
299}
300//--- end generated data replace_capture_avoiding code ---//
301
302} // namespace data
303
304} // namespace mcrl2
305
306#endif // MCRL2_DATA_REPLACE_CAPTURE_AVOIDING_H
const_iterator end() const
Returns a const_iterator pointing to the end of the term_list.
Definition aterm_list.h:282
const_iterator begin() const
Returns a const_iterator pointing to the beginning of the term_list.
Definition aterm_list.h:275
const variable_list & variables() const
Definition abstraction.h:63
const data_expression & body() const
Definition abstraction.h:68
\brief Assignment of a data expression to a variable
Definition assignment.h:91
const variable & lhs() const
Definition assignment.h:117
\brief A data equation
existential quantification.
Definition exists.h:26
universal quantification.
Definition forall.h:26
void add_identifiers(const std::set< core::identifier_string > &ids)
Add a set of identifiers to the context.
function symbol.
Definition lambda.h:27
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
void remove_identifier(const core::identifier_string &s) override
Removes one occurrence of the identifier s from the context.
void add_identifier(const core::identifier_string &s) override
Adds the identifier s to the context.
\brief A data variable
Definition variable.h:28
const core::identifier_string & name() const
Definition variable.h:38
const sort_expression & sort() const
Definition variable.h:43
\brief A where expression
const data_expression & body() const
const assignment_expression_list & declarations() const
Standard exception class for reporting runtime errors.
Definition exception.h:27
add your file description here.
add your file description here.
Search functions of the data library.
static RewriterCompilingJitty::substitution_type & sigma(RewriterCompilingJitty *this_rewriter)
std::string print_list(const Container &v, const std::string &message="", bool print_index=false, bool boundary_spaces=true)
Creates a string representation of a container.
replace_capture_avoiding_variables_builder< Builder, Binder, Substitution > apply_replace_capture_avoiding_variables_builder(capture_avoiding_substitution_updater< Substitution > &sigma)
std::ostream & operator<<(std::ostream &os, smt_solver_type s)
standard conversion from solvert type to stream
Definition solver_type.h:71
void find_identifiers(const T &x, OutputIterator o)
Definition find.h:359
void make_where_clause(atermpp::aterm &t, const ARGUMENTS &... args)
std::set< data::variable > substitution_variables(const Substitution &)
Returns the variables appearing in the right hand sides of the substitution.
Definition replace.h:161
std::string pp(const abstraction &x)
Definition data.cpp:39
void make_lambda(atermpp::aterm &result, ARGUMENTS... arguments)
Definition lambda.h:78
void make_forall(atermpp::aterm &result, ARGUMENTS... arguments)
Definition forall.h:64
atermpp::term_list< variable > variable_list
\brief list of variables
void replace_variables_capture_avoiding(T &x, Substitution &sigma, data::set_identifier_generator &id_generator, typename std::enable_if<!std::is_base_of< atermpp::aterm, T >::value >::type *=nullptr)
atermpp::term_list< assignment > assignment_list
\brief list of assignments
Definition assignment.h:146
void make_exists(atermpp::aterm &result, ARGUMENTS... arguments)
Definition exists.h:64
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
void apply(atermpp::term_list< T > &result, const assignment_list &x)
capture_avoiding_substitution_updater< Substitution > & sigma
void apply(T &result, const data::where_clause &x)
add_capture_avoiding_replacement(capture_avoiding_substitution_updater< Substitution > &sigma_)
void remove_fresh_variable_assignments(const VariableContainer &variables)
capture_avoiding_substitution_updater(Substitution &sigma_, data::set_identifier_generator &id_generator_)
variable_list add_fresh_variable_assignments(const VariableContainer &variables)
replace_capture_avoiding_variables_builder(capture_avoiding_substitution_updater< Substitution > &sigma)
Binder< Builder, replace_capture_avoiding_variables_builder< Builder, Binder, Substitution >, Substitution > super