mCRL2
Loading...
Searching...
No Matches
resolve_name_clashes.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_MODAL_FORMULA_RESOLVE_NAME_CLASHES_H
13#define MCRL2_MODAL_FORMULA_RESOLVE_NAME_CLASHES_H
14
17
18namespace mcrl2::state_formulas {
19
20namespace detail
21{
22
23template <typename Derived>
25{
26 public:
28
29 using super::enter;
30 using super::leave;
31 using super::apply;
32
33 typedef std::map<core::identifier_string, std::vector<core::identifier_string> > name_map;
34
37
40
42 void pop(const core::identifier_string& name)
43 {
44 m_names[name].pop_back();
45 }
46
48 void push(const core::identifier_string& name)
49 {
50 std::vector<core::identifier_string>& names = m_names[name];
51 if (names.empty())
52 {
53 names.push_back(name);
54 }
55 else
56 {
57 names.push_back(m_generator(std::string(name) + "_"));
58 }
59 }
60
61 void enter(const mu& x)
62 {
63 push(x.name());
64 }
65
66 void leave(const mu& x)
67 {
68 pop(x.name());
69 }
70
71 void enter(const nu& x)
72 {
73 push(x.name());
74 }
75
76 void leave(const nu& x)
77 {
78 pop(x.name());
79 }
80
81 // Rename variable
82 template <class T>
83 void apply(T& result, const mu& x)
84 {
85 enter(x);
86 // N.B. If the two lines below are replace by
87 // state_formula result = mu(m_names[x.name()].back(), x.assignments(), (*this)(x.operand()));
88 // a memory error occurs with the clang and intel compilers!
89 core::identifier_string name = m_names[x.name()].back();
91 apply(f, x.operand());
92 result = mu(name, x.assignments(), f);
93 leave(x);
94 }
95
96 // Rename variable
97 template <class T>
98 void apply(T& result, const nu& x)
99 {
100 enter(x);
101 // N.B. If the two lines below are replace by
102 // state_formula result = nu(m_names[x.name()].back(), x.assignments(), (*this)(x.operand()));
103 // a memory error occurs with the clang and intel compilers!
104 core::identifier_string name = m_names[x.name()].back();
106 apply(f, x.operand());
107 result = nu(name, x.assignments(), f);
108 leave(x);
109 }
110
111 // Rename variable
112 template <class T>
113 void apply(T& result, const variable& x)
114 {
115 result = variable(m_names[x.name()].back(), x.arguments());
116 }
117};
118
119class state_formula_data_variable_name_clash_resolver: public state_formulas::data_expression_builder<state_formula_data_variable_name_clash_resolver>
120{
121 public:
123
124 using super::enter;
125 using super::leave;
126 using super::apply;
127
129 std::multiset<data::variable> bound_variables;
130 std::map<data::variable, std::vector<data::variable>> substitutions;
131
133 : generator(generator_)
134 {}
135
136 void insert(const data::variable& v)
137 {
139 {
140 substitutions[v].push_back(data::variable(generator(v.name()), v.sort()));
141 }
142 bound_variables.insert(v);
143 }
144
145 void erase(const data::variable& v)
146 {
147 // Remove one variable, which must exist. Do not use bound_variables.erase(v) as it removes all variables v.
148 std::multiset<data::variable>::const_iterator var_iter=bound_variables.find(v);
149 assert(var_iter!=bound_variables.end());
150 bound_variables.erase(var_iter);
151
152 auto i = substitutions.find(v);
153 if (i != substitutions.end())
154 {
155 i->second.pop_back();
156 if (i->second.empty())
157 {
158 substitutions.erase(i);
159 }
160 }
161 }
162
164 {
165 auto sigma = [&](const data::variable& v) -> data::data_expression
166 {
167 auto i = substitutions.find(v);
168 if (i == substitutions.end())
169 {
170 return v;
171 }
172 return i->second.back();
173 };
174
175 return data::assignment_list(x.begin(), x.end(), [&](const data::assignment& a)
176 {
177 return data::assignment(atermpp::down_cast<data::variable>(sigma(a.lhs())), data::replace_free_variables(a.rhs(), sigma));
178 }
179 );
180 }
181
183 {
184 auto sigma = [&](const data::variable& v) -> data::data_expression
185 {
186 auto i = substitutions.find(v);
187 if (i == substitutions.end())
188 {
189 return v;
190 }
191 return i->second.back();
192 };
193
194 return data::variable_list(x.begin(), x.end(), [&](const data::variable& v)
195 {
196 return atermpp::down_cast<data::variable>(sigma(v));
197 }
198 );
199 }
200
201 template <class T>
202 void apply(T& result, const mu& x)
203 {
204 for (const data::assignment& a: x.assignments())
205 {
206 insert(a.lhs());
207 }
208 apply(result, x.operand());
209 result = mu(x.name(), apply_assignments(x.assignments()), result);
210 for (const data::assignment& a: x.assignments())
211 {
212 erase(a.lhs());
213 }
214 }
215
216 template <class T>
217 void apply(T& result, const nu& x)
218 {
219 for (const data::assignment& a: x.assignments())
220 {
221 insert(a.lhs());
222 }
223 apply(result, x.operand());
224 result = nu(x.name(), apply_assignments(x.assignments()), result);
225 for (const data::assignment& a: x.assignments())
226 {
227 erase(a.lhs());
228 }
229 }
230
231 template <class T>
232 void apply(T& result, const forall& x)
233 {
234 for (const data::variable& v: x.variables())
235 {
236 insert(v);
237 }
238 apply(result,x.body());
239 result = forall(apply_variables(x.variables()), result);
240 for (const data::variable& v: x.variables())
241 {
242 erase(v);
243 }
244 }
245
246 template <class T>
247 void apply(T& result, const exists& x)
248 {
249 for (const data::variable& v: x.variables())
250 {
251 insert(v);
252 }
253 apply(result, x.body());
254 result = exists(apply_variables(x.variables()), result);
255 for (const data::variable& v: x.variables())
256 {
257 erase(v);
258 }
259 }
260
261 template <class T>
262 void apply(T& result, const action_formulas::forall& x)
263 {
264 for (const data::variable& v: x.variables())
265 {
266 insert(v);
267 }
269 apply(body, x.body());
271 for (const data::variable& v: x.variables())
272 {
273 erase(v);
274 }
275 }
276
277 template <class T>
278 void apply(T& result, const action_formulas::exists& x)
279 {
280 for (const data::variable& v: x.variables())
281 {
282 insert(v);
283 }
285 apply(body, x.body());
287 for (const data::variable& v: x.variables())
288 {
289 erase(v);
290 }
291 }
292
293 template <class T>
294 void apply(T& result, const data::data_expression& x)
295 {
296 auto sigma = [&](const data::variable& v) -> data::data_expression
297 {
298 auto i = substitutions.find(v);
299 if (i == substitutions.end())
300 {
301 return v;
302 }
303 return i->second.back();
304 };
305
307 }
308};
309
310} // namespace detail
311
313inline
315{
316 state_formula result;
317 core::make_apply_builder<detail::state_variable_name_clash_resolver>().apply(result, x);
318 return result;
319}
320
322inline
323state_formula resolve_state_formula_data_variable_name_clashes(const state_formula& x, const std::set<core::identifier_string>& context_ids = std::set<core::identifier_string>())
324{
327 generator.add_identifiers(context_ids);
329 state_formula result;
330 f.apply(result, x);
331 return result;
332}
333
334} // namespace mcrl2::state_formulas
335
336#endif // MCRL2_MODAL_FORMULA_RESOLVE_NAME_CLASHES_H
Term containing a string.
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
\brief The existential quantification operator for action formulas
const data::variable_list & variables() const
const action_formula & body() const
\brief The universal quantification operator for action formulas
const action_formula & body() const
const data::variable_list & variables() const
\brief Assignment of a data expression to a variable
Definition assignment.h:91
void add_identifiers(const std::set< core::identifier_string > &ids)
Add a set of identifiers to the context.
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
\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
state_formulas::data_expression_builder< state_formula_data_variable_name_clash_resolver > super
std::map< data::variable, std::vector< data::variable > > substitutions
data::assignment_list apply_assignments(const data::assignment_list &x)
state_formula_data_variable_name_clash_resolver(data::set_identifier_generator &generator_)
utilities::number_postfix_generator m_generator
Generator for fresh variable names.
std::map< core::identifier_string, std::vector< core::identifier_string > > name_map
state_formulas::state_formula_builder< Derived > super
void pop(const core::identifier_string &name)
Pops the name of the stack.
void push(const core::identifier_string &name)
Pushes name on the stack.
\brief The existential quantification operator for state formulas
const state_formula & body() const
const data::variable_list & variables() const
\brief The universal quantification operator for state formulas
const state_formula & body() const
const data::variable_list & variables() const
\brief The mu operator for state formulas
const core::identifier_string & name() const
const data::assignment_list & assignments() const
const state_formula & operand() const
\brief The nu operator for state formulas
const core::identifier_string & name() const
const state_formula & operand() const
const data::assignment_list & assignments() const
\brief The state formula variable
const core::identifier_string & name() const
const data::data_expression_list & arguments() const
Identifier generator that generates names consisting of a prefix followed by a number....
static RewriterCompilingJitty::substitution_type & sigma(RewriterCompilingJitty *this_rewriter)
add your file description here.
void replace_free_variables(T &x, const Substitution &sigma, typename std::enable_if<!std::is_base_of< atermpp::aterm, T >::value >::type *=nullptr)
Definition replace.h:255
atermpp::term_list< variable > variable_list
\brief list of variables
atermpp::term_list< assignment > assignment_list
\brief list of assignments
Definition assignment.h:146
state_formula resolve_state_formula_data_variable_name_clashes(const state_formula &x, const std::set< core::identifier_string > &context_ids=std::set< core::identifier_string >())
Resolves name clashes in data variables of formula x.
void find_identifiers(const T &x, OutputIterator o)
Definition find.h:366
state_formula resolve_state_variable_name_clashes(const state_formula &x)
Resolves name clashes in state variables of formula x.
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
void apply(T &result, const state_formulas::true_ &x)
Definition builder.h:1569