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//
9/// \file mcrl2/data/replace_capture_avoiding.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_DATA_REPLACE_CAPTURE_AVOIDING_H
13#define MCRL2_DATA_REPLACE_CAPTURE_AVOIDING_H
14
15#include "mcrl2/atermpp/aterm.h"
16#include "mcrl2/core/detail/print_utility.h"
17#include "mcrl2/data/concepts.h"
18#include "mcrl2/data/assignment.h"
19#include "mcrl2/data/builder.h"
20#include "mcrl2/data/find.h"
21
22#include <ranges>
23
24namespace mcrl2::data
25{
26
27namespace detail {
28
29// Wraps a substitution, such that assignments to variables can be added and removed.
30template <typename Substitution>
32{
33 Substitution& sigma;
36
38 : sigma(sigma_), id_generator(id_generator_)
39 {}
40
41 // adds the assignment [v := v'] to sigma, and returns v'
43 {
45 updates[v].push_back(v1);
46 return v1;
47 }
48
49 // removes the assignment [v := v'] from sigma
51 {
52 auto i = updates.find(v);
53 id_generator.remove_identifier(i->second.back().name());
54 i->second.pop_back();
55 if (i->second.empty())
56 {
57 updates.erase(i);
58 }
59 }
60
61 // adds the assignments [variables := variables'] to sigma, and returns variables'
62 template <typename VariableContainer>
63 variable_list add_fresh_variable_assignments(const VariableContainer& variables)
64 {
65 return variable_list(
66 variables.begin(),
67 variables.end(),
68 [&](const variable& v)
69 {
70 return add_fresh_variable_assignment(v);
71 }
72 );
73 }
74
75 // removes the assignments [variables := variables'] from sigma
76 template <typename VariableContainer>
77 void remove_fresh_variable_assignments(const VariableContainer& variables)
78 {
79 for (const variable& v: variables)
80 {
82 }
83 }
84
86 {
87 auto i = updates.find(x);
88 if (i != updates.end())
89 {
90 return i->second.back();
91 }
92 else
93 {
94 return sigma(x);
95 }
96 }
97};
98
99template <typename Substitution>
101{
102 std::vector<std::string> updates;
103 for (const auto& p: sigma.updates)
104 {
105 updates.push_back(data::pp(p.first) + " := " + core::detail::print_list(p.second));
106 }
107 return out << sigma.sigma << " with updates " << core::detail::print_list(updates);
108}
109
110template <template <class> class Builder, template <template <class> class, class, class> class Binder, class Substitution>
112{
113 using super
115 using super::enter;
116 using super::leave;
117 using super::apply;
118 using super::update;
119
121 : super(sigma)
122 { }
123};
124
125template <template <class> class Builder, template <template <class> class, class, class> class Binder, class Substitution>
128{
129 return replace_capture_avoiding_variables_builder<Builder, Binder, Substitution>(sigma);
130}
131
132template <template <class> class Builder, class Derived, class Substitution>
133struct add_capture_avoiding_replacement: public Builder<Derived>
134{
135 using super = Builder<Derived>;
136 using super::enter;
137 using super::leave;
138 using super::apply;
139 using super::update;
140
142
144 : sigma(sigma_)
145 { }
146
147 // applies the substitution to the right hand sides of the assignments
148 template <class T>
149 void apply(atermpp::term_list<T>& result, const assignment_list& x)
150 {
151 result = assignment_list(
152 x.begin(),
153 x.end(),
154 [&](data::assignment&r, const data::assignment& a)
155 {
156 data::make_assignment(r, a.lhs(), [&](data_expression& r){ apply(r, a.rhs() ); } );
157 }
158 );
159 }
160
161 template <class T>
162 void apply(T& result, const variable& v)
163 {
164 result = atermpp::down_cast<T>(sigma(v));
165 }
166
167 template <class T>
168 void apply(T& result, const data::where_clause& x)
169 {
170 const auto& declarations = x.declarations() | std::views::transform([](const assignment_expression& t) { return atermpp::down_cast<assignment>(t); });
171
172 auto declarations1 = data::assignment_list(
173 declarations.begin(),
174 declarations.end(),
175 [&](const assignment& a)
176 {
177 const data::variable& v = a.lhs();
178 const data_expression& x1 = a.rhs();
179 // add the assignment [v := v'] to sigma
180 data::variable v1 = sigma.add_fresh_variable_assignment(v);
181 data::data_expression rhs;
182 apply(rhs, x1);
183 return assignment(v1, rhs);
184 }
185 );
186 data::data_expression body;
187 apply(body, x.body());
188 make_where_clause(result, body, declarations1);
189
190 // remove the assignments [v := v'] from sigma
191 for (const assignment& a : declarations)
192 {
193 const variable& v = a.lhs();
194 sigma.remove_fresh_variable_assignment(v);
195 }
196 }
197
198 template <class T>
199 void apply(T& result, const data::forall& x)
200 {
201 variable_list v1 = sigma.add_fresh_variable_assignments(x.variables());
202 data::data_expression body;
203 apply(body, x.body());
204 data::make_forall(result, v1, body);
205 sigma.remove_fresh_variable_assignments(x.variables());
206 }
207
208 template <class T>
209 void apply(T& result, const data::exists& x)
210 {
211 variable_list v1 = sigma.add_fresh_variable_assignments(x.variables());
212 data::data_expression body;
213 apply(body, x.body());
214 data::make_exists(result, v1, body);
215 sigma.remove_fresh_variable_assignments(x.variables());
216 }
217
218 template <class T>
219 void apply(T& result, const data::lambda& x)
220 {
221 variable_list v1 = sigma.add_fresh_variable_assignments(x.variables());
222 data::data_expression body;
223 apply(body, x.body());
224 data::make_lambda(result, v1, body);
225 sigma.remove_fresh_variable_assignments(x.variables());
226 }
227
228 template <class T>
229 void apply(T& /* result */, data_equation& /* x */)
230 {
231 throw mcrl2::runtime_error("not implemented yet");
232 }
233};
234
235} // namespace detail
236
237//--- start generated data replace_capture_avoiding code ---//
238/// \\brief Applies sigma as a capture avoiding substitution to x.
239/// \\param x The object to which the subsitution is applied.
240/// \\param sigma A substitution.
241/// \\param id_generator An identifier generator that generates names that do not appear in x and sigma
242template <typename T, data::IsSubstitution Substitution>
244 Substitution& sigma,
245 data::set_identifier_generator& id_generator
246)
247 requires (!std::is_base_of_v<atermpp::aterm, T>)
248{
249 data::detail::capture_avoiding_substitution_updater<Substitution> sigma1(sigma, id_generator);
250 data::detail::apply_replace_capture_avoiding_variables_builder<data::data_expression_builder, data::detail::add_capture_avoiding_replacement>(sigma1).update(x);
251}
252
253/// \\brief Applies sigma as a capture avoiding substitution to x.
254/// \\param x The object to which the substiution is applied.
255/// \\param sigma A substitution.
256/// \\param id_generator An identifier generator that generates names that do not appear in x and sigma
257template <typename T, data::IsSubstitution Substitution>
259 Substitution& sigma,
260 data::set_identifier_generator& id_generator
261)
262 requires std::is_base_of_v<atermpp::aterm, T>
263{
265 T result;
267 return result;
268}
269
270/// \\brief Applies sigma as a capture avoiding substitution to x.
271/// \\param x The object to which the subsitution is applied.
272/// \\param sigma A substitution.
273template <typename T, data::IsSubstitution Substitution>
276)
277 requires (!std::is_base_of_v<atermpp::aterm, T>)
278{
282 {
284 }
286}
287
288/// \\brief Applies sigma as a capture avoiding substitution to x.
289/// \\param x The object to which the substiution is applied.
290/// \\param sigma A substitution.
291template <typename T, data::IsSubstitution Substitution>
294)
295 requires std::is_base_of_v<atermpp::aterm, T>
296{
300 {
302 }
304}
305//--- end generated data replace_capture_avoiding code ---//
306
307} // namespace mcrl2::data
308
309#endif // MCRL2_DATA_REPLACE_CAPTURE_AVOIDING_H
A list of aterm objects.
Definition aterm_list.h:26
A unordered_map class in which aterms can be stored.
const variable_list & variables() const
Definition abstraction.h:60
const data_expression & body() const
Definition abstraction.h:65
\brief A sort alias
Definition alias.h:23
\brief Assignment expression
Definition assignment.h:24
\brief Assignment of a data expression to a variable
Definition assignment.h:88
const variable & lhs() const
Definition assignment.h:114
\brief A basic sort
Definition basic_sort.h:25
basic_sort(const atermpp::aterm &term)
Definition basic_sort.h:34
\brief A container sort
const container_type & container_name() const
const sort_expression & element_sort() const
container_sort(const atermpp::aterm &term)
\brief A data equation
data_specification(const basic_sort_vector &sorts, const alias_vector &aliases, const function_symbol_vector &constructors, const function_symbol_vector &user_defined_mappings, const data_equation_vector &user_defined_equations)
Constructor from its members.
bool is_well_typed() const
Returns true if.
bool is_certainly_finite(const sort_expression &s) const
Checks whether a sort is certainly finite.
existential quantification.
Definition exists.h:23
bool is_finite(const container_sort &s)
bool is_finite(const basic_sort &s)
bool is_finite_aux(const sort_expression &s)
bool is_finite(const sort_expression &s)
std::set< sort_expression > m_visiting
bool is_finite(const function_sort &s)
const data_specification & m_specification
finiteness_helper(const data_specification &specification)
bool is_finite(const structured_sort &s)
universal quantification.
Definition forall.h:25
\brief Container type for finite sets
fset_container()
\brief Default constructor X3.
\brief A function sort
const sort_expression & codomain() const
function_sort(const atermpp::aterm &term)
const sort_expression_list & domain() const
\brief A function symbol
function_symbol(const core::identifier_string &name, const sort_expression &sort)
Constructor.
const core::identifier_string & name() const
const sort_expression & sort() const
function symbol.
Definition lambda.h:24
\brief Container type for sets
set_container()
\brief Default constructor X3.
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
\brief A sort expression
sort_expression & operator=(const sort_expression &) noexcept=default
sort_expression(const sort_expression &) noexcept=default
Move semantics.
void add_system_defined_sort(const sort_expression &s)
Adds a sort to this specification, and marks it as system defined.
void sorts_are_not_necessarily_normalised_anymore() const
void import_system_defined_sort(const sort_expression &sort)
Adds the system defined sorts in a sequence. The second argument is used to check which sorts are add...
structured_sort(const atermpp::aterm &term)
\brief A data variable
Definition variable.h:25
const core::identifier_string & name() const
Definition variable.h:35
const sort_expression & sort() const
Definition variable.h:40
\brief A where expression
const data_expression & body() const
const assignment_expression_list & declarations() const
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:393
aterm identity(const aterm &x)
The default transformer that maps each term to itself.
Definition aterm_io.h:26
std::string file_source(const std::string &filename)
Definition load_aterm.h:24
atermpp::aterm load_aterm(std::istream &stream, bool binary=true, const std::string &format="aterm", const std::string &source="", atermpp::aterm_transformer transformer=atermpp::identity)
Attempts to read an aterm from a stream.
Definition load_aterm.h:43
bool check_variable_sorts(const VariableContainer &variables, const SortContainer &sorts)
Returns true if the domain sorts and the range sort of the given variables are contained in sorts.
atermpp::aterm add_index(const atermpp::aterm &x)
Definition io.h:44
bool check_variable_names(variable_list const &variables, const std::set< core::identifier_string > &names)
Returns true if names of the given variables are not contained in names.
atermpp::aterm remove_index(const atermpp::aterm &x)
Definition io.h:50
atermpp::aterm remove_index_impl(const atermpp::aterm &x)
Definition io.h:23
replace_capture_avoiding_variables_builder< Builder, Binder, Substitution > apply_replace_capture_avoiding_variables_builder(capture_avoiding_substitution_updater< Substitution > &sigma)
bool check_assignment_variables(assignment_list const &assignments, variable_list const &variables)
Returns true if the left hand sides of assignments are contained in variables.
bool check_sort(const sort_expression &s, const SortContainer &sorts)
Returns true if the domain sorts and the codomain sort of the given sort s are contained in sorts.
bool check_data_spec_sorts(const Container &container, const SortContainer &sorts)
Returns true if the domain sorts and range sort of the given functions are contained in sorts.
data::sort_expression_list parameter_sorts(const Container &parameters)
Returns the sorts of a sequence of parameters.
std::ostream & operator<<(std::ostream &out, const capture_avoiding_substitution_updater< Substitution > &sigma)
atermpp::aterm add_index_impl(const atermpp::aterm &x)
Definition io.h:33
bool check_sorts(Iterator first, Iterator last, const SortContainer &sorts)
Returns true if the domain sorts and the range sort of the sorts in the sequence [first,...
bool unique_names(const VariableContainer &variables)
Returns true if the names of the given variables are unique.
Namespace for system defined sort bag.
Definition bag1.h:35
bool is_bag(const sort_expression &e)
Recogniser for sort expression Bag(s)
Definition bag1.h:52
Namespace for system defined sort bool_.
Definition bool.h:29
const basic_sort & bool_()
Constructor for sort expression Bool.
Definition bool.h:41
Namespace for system defined sort fbag.
Definition fbag1.h:34
container_sort fbag(const sort_expression &s)
Constructor for sort expression FBag(S)
Definition fbag1.h:40
bool is_fbag(const sort_expression &e)
Recogniser for sort expression FBag(s)
Definition fbag1.h:51
Namespace for system defined sort fset.
Definition fset1.h:32
bool is_fset(const sort_expression &e)
Recogniser for sort expression FSet(s)
Definition fset1.h:49
container_sort fset(const sort_expression &s)
Constructor for sort expression FSet(S)
Definition fset1.h:38
Namespace for system defined sort int_.
const basic_sort & int_()
Constructor for sort expression Int.
Definition int1.h:44
Namespace for system defined sort list.
Definition list1.h:33
bool is_list(const sort_expression &e)
Recogniser for sort expression List(s)
Definition list1.h:50
Namespace for system defined sort nat.
const basic_sort & nat()
Constructor for sort expression Nat.
Definition nat1.h:43
const basic_sort & natpair()
Constructor for sort expression @NatPair.
Definition nat1.h:72
Namespace for system defined sort pos.
const basic_sort & pos()
Constructor for sort expression Pos.
Definition pos1.h:42
Namespace for system defined sort real_.
const basic_sort & real_()
Constructor for sort expression Real.
Definition real1.h:45
Namespace for system defined sort set_.
Definition set1.h:33
bool is_set(const sort_expression &e)
Recogniser for sort expression Set(s)
Definition set1.h:50
container_sort set_(const sort_expression &s)
Constructor for sort expression Set(S)
Definition set1.h:39
bool is_structured_sort(const atermpp::aterm &x)
Returns true if the term t is a structured sort.
static sort_expression find_normal_form(const sort_expression &e, const std::multimap< sort_expression, sort_expression > &map1, std::set< sort_expression > sorts_already_seen=std::set< sort_expression >())
void replace_variables_capture_avoiding(T &x, Substitution &sigma, data::set_identifier_generator &id_generator)
void replace_sort_expressions(T &x, const Substitution &sigma, bool innermost)
Definition replace.h:171
bool is_untyped_possible_sorts(const atermpp::aterm &x)
Returns true if the term t is an expression for multiple possible sorts.
T replace_variables_capture_avoiding(const T &x, Substitution &sigma, data::set_identifier_generator &id_generator)
bool is_untyped_sort(const atermpp::aterm &x)
Returns true if the term t is the unknown sort.
std::set< data::variable > substitution_variables(const Substitution &)
Returns the variables appearing in the right hand sides of the substitution.
Definition replace.h:164
T replace_sort_expressions(const T &x, const Substitution &sigma, bool innermost)
Definition replace.h:181
void register_function_symbol_hooks()
bool is_container_sort(const atermpp::aterm &x)
Returns true if the term t is a container sort.
bool is_basic_sort(const atermpp::aterm &x)
Returns true if the term t is a basic sort.
void on_delete_function_symbol(const atermpp::aterm &t)
bool is_function_sort(const atermpp::aterm &x)
Returns true if the term t is a function sort.
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)