mCRL2
Loading...
Searching...
No Matches
representative_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_REPRESENTATIVE_GENERATOR_H
13#define MCRL2_DATA_REPRESENTATIVE_GENERATOR_H
14
16
17namespace mcrl2
18{
19
20namespace data
21{
51
53{
54
55 protected:
56
59
61 std::map< sort_expression, data_expression > m_representatives_cache;
62
63 protected:
64
68 void set_representative(const sort_expression& sort, const data_expression& representative)
69 {
70 assert(sort==representative.sort());
71 m_representatives_cache[sort] = representative;
72 }
73
77 // an infinite circular search through the sorts.
82 const function_symbol& symbol,
83 std::set < sort_expression >& visited_sorts,
84 data_expression& result)
85 {
86 assert(is_function_sort(symbol.sort()));
87
88 data_expression_vector arguments;
89
90 for (const sort_expression& s: static_cast<const function_sort&>(symbol.sort()).domain())
91 {
92 data_expression representative;
93 if (find_representative(s, visited_sorts, representative))
94 {
95 arguments.push_back(representative);
96 }
97 else
98 {
99 // a representative for this argument could not be found.
100 return false;
101 }
102 }
103
104 // a suitable set of arguments is found
105 result=application(symbol, arguments);
106 return true;
107 }
108
110 const sort_expression& sort,
111 const std::vector<function_symbol>& function_symbols)
112 {
113 bool function_symbol_found=false;
114 for (const function_symbol& f: function_symbols)
115 {
116 if (f.sort()==sort)
117 {
118 if (function_symbol_found)
119 {
120 if (static_cast<const std::string&>(f.name())<static_cast<const std::string&>(f_result.name()))
121 {
122 f_result=f;
123 }
124 }
125 else
126 {
127 f_result=f;
128 function_symbol_found=true;
129 }
130 }
131 }
132 return function_symbol_found;
133 }
134
138 // an infinite circular search through the sorts.
142 const sort_expression& sort,
143 std::set < sort_expression >& visited_sorts,
144 data_expression& result)
145 {
146 if (visited_sorts.count(sort)>0)
147 {
148 // This sort is already visited. We are looking to find a representative term of this sort
149 // within the scope of finding a term of this sort. If this is to be succesful, a more compact
150 // term can be found. Hence, stop searching further.
151 return false;
152 }
153
154 const std::map< sort_expression, data_expression >::iterator i=m_representatives_cache.find(sort);
155 if (i!=m_representatives_cache.end())
156 {
157 assert(i->second.sort()==sort);
158 result=i->second;
159 return true;
160 }
161
162 if (is_function_sort(sort))
163 {
164 // s is a function sort.
165 // First search for a lexicographically minimal mapping with sort s (constructors with sort s cannot exist).
166 function_symbol minimal_f;
167 const function_sort& fs=atermpp::down_cast<function_sort>(sort);
169 {
170 result=minimal_f;
171 set_representative(sort, result);
172 return true;
173 }
174
175 // If no explicit constant is found of this sort, we know that its shape is "s0#..#sn -> s".
176 // We search a term t of sort s and if found, construct a lambda term of the shape
177 // lambda x0:s0,...,xn:sn.t. Note that this can be strengthened slightly by incorporating
178 // the variables xi in generating t, e.g. generating for D->D the reprentant lambd d:D.d.
179 // Incorporating the variables in the generation of terms requires adapting all algorithms,
180 // and is not done. Until now the need for such representant generators has not been felt.
181
182 const sort_expression& s2=fs.codomain();
184 if (find_representative(s2, visited_sorts, t))
185 {
186 variable_vector bound_variables;
187 std::size_t variable_index=0;
188 for(const sort_expression& s: fs.domain())
189 {
190 bound_variables.emplace_back("x" + std::to_string(variable_index), s);
191 variable_index++;
192 }
193 result=abstraction(lambda_binder(),variable_list(bound_variables.begin(),bound_variables.end()),t);
194 return true;
195 }
196 }
197 else
198 {
199 // s is a constant (not a function sort).
200 // check if there is a constant constructor for s
201
202 function_symbol minimal_c;
204 {
205 result=minimal_c;
206 set_representative(sort, result);
207 return true;
208 }
209
210 visited_sorts.insert(sort);
211
212 // Check whether there is a representative f(t1,...,tn) for s, where f is a constructor function.
213 // We prefer this over a constant mapping, as a constant mapping generally does not have appropriate
214 // rewrite rules.
215
216 // recursively traverse constructor functions of the form f:s1#...#sn -> sort.
217 // operators with f:s1#...#sn->G where G is a complex sort expression are ignored
218
219 for (const function_symbol& f: m_specification.constructors(sort))
220 {
221 if (find_representative(f, visited_sorts, result))
222 {
223 set_representative(sort, result);
224 visited_sorts.erase(sort);
225 return true;
226 }
227 }
228
229 // check if there is a constant mapping for s
230 for (const function_symbol& f: m_specification.mappings(sort))
231 {
232 if (f.sort()==sort)
233 {
234 result=f;
235 set_representative(sort, result);
236 visited_sorts.erase(sort);
237 return true;
238 }
239 }
240
241 // Try to check whether there is a representative f(t1,...,tn) where f is a mapping.
242 for (const function_symbol& f: m_specification.mappings(sort))
243 {
244 if (find_representative(f, visited_sorts, result))
245 {
246 set_representative(sort, result);
247 visited_sorts.erase(sort);
248 return true;
249 }
250 }
251
252 visited_sorts.erase(sort);
253
254 }
255
256 // No representative has been found.
257 return false;
258 }
259
260 public:
261
263 representative_generator(const data_specification& specification) : m_specification(specification)
264 {
265 }
266
270 {
271 // First see whether a term of this sort has already been constructed and resides in the representatives_cache. If yes return it.
272 const std::map< sort_expression, data_expression >::iterator i=m_representatives_cache.find(sort);
273 if (i!=m_representatives_cache.end())
274 {
275 return i->second;
276 }
277
278 data_expression result;
279 std::set<sort_expression> visited_sorts;
280 if (find_representative(sort, visited_sorts, result))
281 {
282 // A term of the requested sort is found. Return it.
283 return result;
284 }
285 else
286 {
287 throw mcrl2::runtime_error("Cannot find a term of sort " + data::pp(sort));
288 }
289
290 }
291};
292
293} // namespace data
294} // namespace mcrl2
295#endif
296
An abstraction expression.
Definition abstraction.h:26
An application of a data expression to a number of arguments.
sort_expression sort() const
Returns the sort of the data expression.
Definition data.cpp:108
const function_symbol_vector & constructors() const
Gets all constructors including those that are system defined.
const function_symbol_vector & mappings() const
Gets all mappings in this specification including those that are system defined.
\brief A function sort
const sort_expression & codomain() const
const sort_expression_list & domain() const
\brief A function symbol
const core::identifier_string & name() const
const sort_expression & sort() const
\brief Binder for lambda abstraction
Components for generating an arbitrary element of a sort.
bool find_representative(const function_symbol &symbol, std::set< sort_expression > &visited_sorts, data_expression &result)
Finds a representative of the form f(t1,...,tn) where f is the function symbol.
std::map< sort_expression, data_expression > m_representatives_cache
Serves as a cache for later find operations.
const data_specification & m_specification
Data specification context.
bool search_for_lexicographically_minimal_symbol(function_symbol &f_result, const sort_expression &sort, const std::vector< function_symbol > &function_symbols)
bool find_representative(const sort_expression &sort, std::set< sort_expression > &visited_sorts, data_expression &result)
Finds a representative element for an arbitrary sort expression.
data_expression operator()(const sort_expression &sort)
Returns a representative of a sort.
representative_generator(const data_specification &specification)
Constructor with data specification as context.
void set_representative(const sort_expression &sort, const data_expression &representative)
Sets a data expression as representative of the sort.
\brief A sort expression
Standard exception class for reporting runtime errors.
Definition exception.h:27
The class data_specification.
std::vector< variable > variable_vector
\brief vector of variables
Definition variable.h:89
std::vector< data_expression > data_expression_vector
\brief vector of data_expressions
std::string pp(const abstraction &x)
Definition data.cpp:39
atermpp::term_list< variable > variable_list
\brief list of variables
bool is_function_sort(const atermpp::aterm &x)
Returns true if the term t is a function sort.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72