mCRL2
Loading...
Searching...
No Matches
replace_capture_avoiding_with_an_identifier_generator.h
Go to the documentation of this file.
1// Author(s): Jan Friso Groote
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_WITH_AN_IDENTIFIER_GENERATOR_H
13#define MCRL2_DATA_REPLACE_CAPTURE_AVOIDING_WITH_AN_IDENTIFIER_GENERATOR_H
14
16#include "mcrl2/data/builder.h"
17
18namespace mcrl2 {
19
20namespace data {
21
22namespace detail {
23
24template <typename Substitution, typename IdentifierGenerator>
26{
27 protected:
28 Substitution& m_sigma;
29 IdentifierGenerator& m_id_generator;
30 std::vector<data::assignment> m_undo; // why not a stack datatype?
31
32 public:
33 substitution_updater_with_an_identifier_generator(Substitution& sigma, IdentifierGenerator& id_generator)
34 : m_sigma(sigma), m_id_generator(id_generator)
35 {}
36
37 Substitution& substitution()
38 {
39 return m_sigma;
40 }
41
43 {
44 m_undo.push_back(data::assignment(v, m_sigma(v))); // save the old assignment of m_sigma.
45 if (m_sigma.variable_occurs_in_a_rhs(v)) // v notin FV(m_sigma).
46 {
47 m_sigma[v] = v; // Clear sigma[v].
48 return v;
49 }
50 else
51 {
53 m_sigma[v] = w;
54 return w;
55 }
56 }
57
59 {
60 return bind(v);
61 }
62
63 void pop(const data::variable& )
64 {
65 const data::assignment& a = m_undo.back();
66 m_sigma[a.lhs()] = a.rhs();
67 m_undo.pop_back();
68 }
69
70 template <typename VariableContainer>
71 VariableContainer push(const VariableContainer& container)
72 {
73 std::vector<data::variable> result;
74 for (const variable& v: container)
75 {
76 result.push_back(bind(v));
77 }
78 return VariableContainer(result.begin(), result.end());
79 }
80
81 template <typename VariableContainer>
82 void pop(const VariableContainer& container)
83 {
84 for (const variable& v: container)
85 {
86 pop(v);
87 }
88 }
89};
90
91template <typename Substitution, typename IdentifierGenerator>
92data::variable update_substitution(Substitution& sigma, const data::variable& v, const std::multiset<data::variable>& V, IdentifierGenerator& id_generator)
93{
95 if (!contains(V, v) && sigma(v) == v)
96 {
97 return v;
98 }
99 else
100 {
101 id_generator.add_identifier(v.name());
102 data::variable w(id_generator(v.name()), v.sort());
103
104 while (sigma(w) != w || contains(V, w))
105 {
106 w = data::variable(id_generator(v.name()), v.sort());
107 }
108 sigma[v] = w;
109 return w;
110 }
111}
112
113template <typename Substitution, typename IdentifierGenerator, typename VariableContainer>
114VariableContainer update_substitution(Substitution& sigma, const VariableContainer& v, const std::multiset<data::variable>& V, IdentifierGenerator& id_generator)
115{
116 std::vector<data::variable> result;
117 for (typename VariableContainer::const_iterator i = v.begin(); i != v.end(); ++i)
118 {
119 result.push_back(update_substitution(sigma, *i, V, id_generator));
120 }
121 return VariableContainer(result.begin(), result.end());
122}
123
124// Helper code for replace_capture_avoiding_variables_with_an_identifier_generator.
125template<template<class> class Builder,
126 template<template<class> class, class, class, class> class Binder, class Substitution, class IdentifierGenerator>
128 : public Binder<Builder, replace_capture_avoiding_variables_builder_with_an_identifier_generator<Builder, Binder, Substitution, IdentifierGenerator>, Substitution, IdentifierGenerator>
129{
130 typedef Binder<Builder, replace_capture_avoiding_variables_builder_with_an_identifier_generator<Builder, Binder, Substitution, IdentifierGenerator>, Substitution, IdentifierGenerator> super;
131 using super::enter;
132 using super::leave;
133 using super::apply;
134 using super::update;
135
137 IdentifierGenerator& id_generator)
138 : super(sigma, id_generator)
139 {
140 }
141};
142
143template<template<class> class Builder,
144 template<template<class> class, class, class, class> class Binder, class Substitution, class IdentifierGenerator>
145replace_capture_avoiding_variables_builder_with_an_identifier_generator<Builder, Binder, Substitution, IdentifierGenerator>
147 IdentifierGenerator& id_generator)
148{
150 sigma, id_generator);
151}
152
153// In the class below, the IdentifierGenerator is expected to generate fresh identifiers, not
154// occurring anywhere using the operator (). The enumerator_identifier_generator can do this.
155// The substitution has as property that it provides a method "variables_in_rhs" yielding the
156// variables occurring in the right hand side of assignments. The mutable_indexed_substitution has this
157// method.
158template<template<class> class Builder, class Derived, class Substitution, class IdentifierGenerator>
160{
161 typedef Builder<Derived> super;
162 using super::enter;
163 using super::leave;
164 using super::apply;
165 using super::update;
166
167 protected:
168 substitution_updater_with_an_identifier_generator <Substitution, IdentifierGenerator> update_sigma;
169
170 public:
172 IdentifierGenerator& id_generator_)
173 : update_sigma(sigma_, id_generator_)
174 {
175 }
176
177 template <class T>
178 void apply(T& result, const variable& v)
179 {
180 result = update_sigma.substitution()(v);
181 }
182
183 template <class T>
184 void apply(T& result, const data::where_clause& x)
185 {
186 const auto& assignments = atermpp::container_cast<data::assignment_list>(x.declarations());
187 std::vector<data::variable> tmp;
188 for (const data::assignment& a: assignments)
189 {
190 tmp.push_back(a.lhs());
191 }
192 std::vector<data::variable> v = update_sigma.push(tmp);
193
194 // The updated substitution should be applied to the body.
195 data::data_expression new_body;
196 apply(new_body, x.body());
197 update_sigma.pop(v);
198
199 // The original substitution should be applied to the right hand sides of the assignments.
200 std::vector<data::assignment> a;
201 std::vector<data::variable>::const_iterator j = v.begin();
202 for (data::assignment_list::const_iterator i = assignments.begin(); i != assignments.end(); ++i, ++j)
203 {
205 apply(rhs, i->rhs());
206 a.push_back(data::assignment(*j, rhs));
207 }
208 data::make_where_clause(result, new_body, assignment_list(a.begin(), a.end()));
209 }
210
211 template <class T>
212 void apply(T& result, const data::forall& x)
213 {
214 const data::variable_list v = update_sigma.push(x.variables());
216 apply(body, x.body());
217 data::make_forall(result, v, body);
218 update_sigma.pop(v);
219 }
220
221 template <class T>
222 void apply(T& result, const data::exists& x)
223 {
224 const data::variable_list v = update_sigma.push(x.variables());
226 apply(body, x.body());
227 data::make_exists(result, v, body);
228 update_sigma.pop(v);
229 }
230
231 template <class T>
232 void apply(T& result, const data::lambda& x)
233 {
234 const data::variable_list v = update_sigma.push(x.variables());
236 apply(body, x.body());
237 data::make_lambda(result, v, body);
238 update_sigma.pop(v);
239 }
240
241 template <class T>
242 void apply(T& /* result */, data_equation& /* x */)
243 {
244 throw mcrl2::runtime_error("not implemented yet");
245 }
246};
247
248} // namespace detail
249
250//--- start generated data replace_capture_avoiding_with_identifier_generator code ---//
259
260template <typename T, typename Substitution, typename IdentifierGenerator>
262 Substitution& sigma,
263 IdentifierGenerator& id_generator,
264 typename std::enable_if<!std::is_base_of<atermpp::aterm, T>::value>::type* = nullptr
265 )
266{
267 data::detail::apply_replace_capture_avoiding_variables_builder_with_an_identifier_generator<data::data_expression_builder, data::detail::add_capture_avoiding_replacement_with_an_identifier_generator>(sigma, id_generator).update(x);
268}
269
279template <typename T, typename Substitution, typename IdentifierGenerator>
281 Substitution& sigma,
282 IdentifierGenerator& id_generator,
283 typename std::enable_if<std::is_base_of<atermpp::aterm, T>::value>::type* = nullptr
284 )
285{
286 T result;
287 data::detail::apply_replace_capture_avoiding_variables_builder_with_an_identifier_generator<data::data_expression_builder, data::detail::add_capture_avoiding_replacement_with_an_identifier_generator>(sigma, id_generator).apply(result, x);
288 return result;
289}
290//--- end generated data replace_capture_avoiding_with_identifier_generator code ---//
291
292} // namespace data
293
294} // namespace mcrl2
295
296#endif // MCRL2_DATA_REPLACE_CAPTURE_AVOIDING_WITH_AN_IDENTIFIER_GENERATOR_H
Iterator for term_list.
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 data_expression & rhs() const
Definition assignment.h:122
const variable & lhs() const
Definition assignment.h:117
\brief A data equation
existential quantification.
Definition exists.h:26
universal quantification.
Definition forall.h:26
function symbol.
Definition lambda.h:27
\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.
static RewriterCompilingJitty::substitution_type & sigma(RewriterCompilingJitty *this_rewriter)
data::variable update_substitution(Substitution &sigma, const data::variable &v, const std::multiset< data::variable > &V, IdentifierGenerator &id_generator)
replace_capture_avoiding_variables_builder_with_an_identifier_generator< Builder, Binder, Substitution, IdentifierGenerator > apply_replace_capture_avoiding_variables_builder_with_an_identifier_generator(Substitution &sigma, IdentifierGenerator &id_generator)
void make_where_clause(atermpp::aterm &t, const ARGUMENTS &... args)
void make_lambda(atermpp::aterm &result, ARGUMENTS... arguments)
Definition lambda.h:78
void replace_variables_capture_avoiding_with_an_identifier_generator(T &x, Substitution &sigma, IdentifierGenerator &id_generator, typename std::enable_if<!std::is_base_of< atermpp::aterm, T >::value >::type *=nullptr)
void make_forall(atermpp::aterm &result, ARGUMENTS... arguments)
Definition forall.h:64
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
bool contains(const atermpp::indexed_set< Key, ThreadSafe, Hash, Equals, Allocator, KeyTable > &c, const typename atermpp::indexed_set< Key, ThreadSafe, Hash, Equals, Allocator, KeyTable >::key_type &v, const std::size_t thread_index=0)
Definition indexed_set.h:86
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
substitution_updater_with_an_identifier_generator< Substitution, IdentifierGenerator > update_sigma
Binder< Builder, replace_capture_avoiding_variables_builder_with_an_identifier_generator< Builder, Binder, Substitution, IdentifierGenerator >, Substitution, IdentifierGenerator > super