mCRL2
Loading...
Searching...
No Matches
quantifiers_inside_rewriter.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_REWRITERS_QUANTIFIERS_INSIDE_REWRITER_H
13#define MCRL2_DATA_REWRITERS_QUANTIFIERS_INSIDE_REWRITER_H
14
15#include <tuple>
16#include "mcrl2/data/builder.h"
17#include "mcrl2/data/join.h"
19
20namespace mcrl2 {
21
22namespace data {
23
24namespace detail {
25
26data_expression quantifiers_inside(const data_expression& x);
27data_expression quantifiers_inside_forall(const std::set<variable>& variables, const data_expression& x);
28data_expression quantifiers_inside_exists(const std::set<variable>& variables, const data_expression& x);
29
30inline
31std::set<variable> make_variable_set(const variable_list& x)
32{
33 return std::set<variable>(x.begin(), x.end());
34}
35
36inline
37variable_list make_variable_list(const std::set<variable>& x)
38{
39 return variable_list(x.begin(), x.end());
40}
41
42template <typename BinaryOperation>
43std::tuple<data_expression, data_expression> compute_Phi_Psi(const std::vector<data_expression>& X, const std::set<variable>& V, BinaryOperation op, data_expression empty_sequence_result)
44{
47
48 std::vector<std::set<data::variable>> vars; // free variables
49 for (const data_expression& x_j: X)
50 {
51 vars.push_back(set_intersection(find_free_variables(x_j), V));
52 }
53 auto j = std::min_element(vars.begin(), vars.end(),
54 [&](const std::set<data::variable>& x, const std::set<data::variable>& y)
55 {
56 return x.size() < y.size();
57 }
58 );
59 const std::set<data::variable>& Z = *j;
60
61 std::vector<data_expression> phi;
62 std::vector<data_expression> psi;
63 for (std::size_t i = 0; i < X.size(); i++)
64 {
65 if (std::includes(Z.begin(), Z.end(), vars[i].begin(), vars[i].end()))
66 {
67 phi.push_back(X[i]);
68 }
69 else
70 {
71 psi.push_back(X[i]);
72 }
73 }
74 data_expression Phi = utilities::detail::join(phi.begin(), phi.end(), op, empty_sequence_result);
75 data_expression Psi = utilities::detail::join(psi.begin(), psi.end(), op, empty_sequence_result);
76 return { Phi, Psi };
77}
78
79struct quantifiers_inside_builder: public data_expression_builder<quantifiers_inside_builder>
80{
82 using super::apply;
83
84 template <class T>
85 void apply(T& result, const forall& x)
86 {
87 const data_expression& phi = x.body();
88 std::set<variable> W = make_variable_set(x.variables());
89 apply(result, phi);
90 result = quantifiers_inside_forall(W, result);
91 }
92
93 template <class T>
94 void apply(T& result, const exists& x)
95 {
96 const data_expression& phi = x.body();
97 std::set<variable> W = make_variable_set(x.variables());
98 apply(result, phi);
99 result = quantifiers_inside_exists(W, result);
100 }
101};
102
103struct quantifiers_inside_forall_builder: public data_expression_builder<quantifiers_inside_forall_builder>
104{
106 using super::apply;
107
108 const std::set<variable>& V;
109
110 explicit quantifiers_inside_forall_builder(const std::set<variable>& V_)
111 : V(V_)
112 {}
113
115 {
116 return vars.empty() ? body : forall(vars,body);
117 }
118
119 template <class T>
120 void apply(T& result, const forall& x)
121 {
123 std::set<variable> W = make_variable_set(x.variables());
124 result = quantifiers_inside_forall(set_union(V, W), x.body());
125 }
126
127 // default case
128 template <typename T>
130 {
132 std::set<variable> W = set_intersection(V, find_free_variables(x));
133 return make_forall_(variable_list(W.begin(), W.end()), x);
134 }
135
136 template <class T>
137 void apply(T& result, const data_expression& x)
138 {
140 {
141 data_expression const& phi = sort_bool::arg(x);
143 return;
144 }
146 {
147 const data_expression& phi = sort_bool::left(x);
148 const data_expression& psi = sort_bool::right(x);
150 return;
151 }
153 {
157
158 std::vector<data_expression> X;
159 utilities::detail::split(x, std::back_inserter(X), tr::is_or, tr::left, tr::right);
160 const auto [Phi, Psi] = compute_Phi_Psi(X, V, tr::or_, tr::false_());
162 {
164 return;
165 }
166 std::set<variable> vars_Phi = find_free_variables(Phi);
167 std::set<variable> vars_Psi = find_free_variables(Psi);
168 result = make_forall_(make_variable_list(set_intersection(V, set_intersection(vars_Phi, vars_Psi))),
169 lazy::or_(
172 )
173 );
174 return;
175 }
177 {
178 const data_expression& left = sort_bool::left(x);
179 const data_expression& right = sort_bool::right(x);
181 return;
182 }
183 else
184 {
185 result = apply_default(x);
186 return;
187 }
188 }
189};
190
191struct quantifiers_inside_exists_builder: public data_expression_builder<quantifiers_inside_exists_builder>
192{
194 using super::apply;
195
196 const std::set<variable>& V;
197
198 quantifiers_inside_exists_builder(const std::set<variable>& V_)
199 : V(V_)
200 {}
201
203 {
204 return vars.empty() ? body : exists(vars,body);
205 }
206
207 template <class T>
208 void apply(T& result, const exists& x)
209 {
211 std::set<variable> W = make_variable_set(x.variables());
212 result = quantifiers_inside_exists(set_union(V, W), x.body());
213 }
214
215 // default case
216 template <typename T>
218 {
220 std::set<variable> W = set_intersection(V, find_free_variables(x));
221 return make_exists_(variable_list(W.begin(), W.end()), x);
222 }
223
224 template <class T>
225 void apply(T& result, const forall& x)
226 {
227 result = apply_default(x);
228 }
229
230 template <class T>
231 void apply(T& result, const data_expression& x)
232 {
234 {
235 data_expression const& phi = sort_bool::arg(x);
237 return;
238 }
240 {
244
245 std::vector<data_expression> X;
246 utilities::detail::split(x, std::back_inserter(X), tr::is_and, tr::left, tr::right);
247 const auto [Phi, Psi] = compute_Phi_Psi(X, V, tr::and_, tr::true_());
249 {
251 return;
252 }
253 std::set<variable> vars_Phi = find_free_variables(Phi);
254 std::set<variable> vars_Psi = find_free_variables(Psi);
255 result = make_exists_(make_variable_list(set_intersection(V, set_intersection(vars_Phi, vars_Psi))),
259 )
260 );
261 return;
262 }
264 {
265 data_expression const& phi = sort_bool::left(x);
266 data_expression const& psi = sort_bool::right(x);
268 return;
269 }
271 {
272 const data_expression& left = sort_bool::left(x);
273 const data_expression& right = sort_bool::right(x);
275 return;
276 }
277 result = apply_default(x);
278 return;
279 }
280};
281
282inline
284{
286 data_expression result;
287 f.apply(result, x);
288 return result;
289}
290
291inline
292data_expression quantifiers_inside_forall(const std::set<variable>& variables, const data_expression& x)
293{
295 data_expression result;
296 f.apply(result, x);
297 return result;
298}
299
300inline
301data_expression quantifiers_inside_exists(const std::set<variable>& variables, const data_expression& x)
302{
304 data_expression result;
305 f.apply(result, x);
306 return result;
307}
308
309} // namespace detail
310
312{
315
317 {
319 }
320};
321
322template <typename T>
323void quantifiers_inside_rewrite(T& x, typename std::enable_if< !std::is_base_of< atermpp::aterm, T >::value>::type* = 0)
324{
325 core::make_update_apply_builder<data_expression_builder>(quantifiers_inside_rewriter()).update(x);
326}
327
328template <typename T>
329T quantifiers_inside_rewrite(const T& x, typename std::enable_if< std::is_base_of< atermpp::aterm, T >::value>::type* = 0)
330{
331 T result;
332 core::make_update_apply_builder<data_expression_builder>(quantifiers_inside_rewriter()).apply(result, x);
333 return result;
334}
335
336} // namespace data
337
338} // namespace mcrl2
339
340#endif // MCRL2_DATA_REWRITERS_QUANTIFIERS_INSIDE_REWRITER_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
bool empty() const
Returns true if the list's size is 0.
Definition aterm_list.h:268
const variable_list & variables() const
Definition abstraction.h:63
const data_expression & body() const
Definition abstraction.h:68
existential quantification.
Definition exists.h:26
universal quantification.
Definition forall.h:26
add your file description here.
Join and split functions for data expressions.
data_expression quantifiers_inside_forall(const std::set< variable > &variables, const data_expression &x)
variable_list set_intersection(const variable_list &x, const variable_list &y)
Returns the intersection of two unordered sets, that are stored in ATerm lists.
data_expression quantifiers_inside_exists(const std::set< variable > &variables, const data_expression &x)
variable_list make_variable_list(const std::set< variable > &x)
std::set< variable > make_variable_set(const variable_list &x)
data_expression quantifiers_inside(const data_expression &x)
variable_list set_difference(const variable_list &x, const variable_list &y)
Returns the difference of two unordered sets, that are stored in aterm lists.
std::tuple< data_expression, data_expression > compute_Phi_Psi(const std::vector< data_expression > &X, const std::set< variable > &V, BinaryOperation op, data_expression empty_sequence_result)
data_expression and_(data_expression const &p, data_expression const &q)
Returns an expression equivalent to p or q.
data_expression or_(data_expression const &p, data_expression const &q)
Returns an expression equivalent to p and q.
bool is_false_function_symbol(const atermpp::aterm &e)
Recogniser for function false.
Definition bool.h:119
const data_expression & arg(const data_expression &e)
Function for projecting out argument. arg from an application.
Definition bool.h:469
bool is_or_application(const atermpp::aterm &e)
Recogniser for application of ||.
Definition bool.h:345
const data_expression & right(const data_expression &e)
Function for projecting out argument. right from an application.
Definition bool.h:493
bool is_implies_application(const atermpp::aterm &e)
Recogniser for application of =>.
Definition bool.h:409
const function_symbol & and_()
Constructor for function symbol &&.
Definition bool.h:235
bool is_and_application(const atermpp::aterm &e)
Recogniser for application of &&.
Definition bool.h:281
const function_symbol & or_()
Constructor for function symbol ||.
Definition bool.h:299
bool is_true_function_symbol(const atermpp::aterm &e)
Recogniser for function true.
Definition bool.h:87
bool is_not_application(const atermpp::aterm &e)
Recogniser for application of !.
Definition bool.h:217
const function_symbol & not_()
Constructor for function symbol !.
Definition bool.h:173
const data_expression & left(const data_expression &e)
Function for projecting out argument. left from an application.
Definition bool.h:481
std::set< data::variable > find_free_variables(const data::data_expression &x)
Definition data.cpp:99
atermpp::term_list< variable > variable_list
\brief list of variables
void quantifiers_inside_rewrite(T &x, typename std::enable_if< !std::is_base_of< atermpp::aterm, T >::value >::type *=0)
T join(FwdIt first, FwdIt last, BinaryOperation op, T empty_sequence_result)
Given a sequence [t1, t2, ..., tn] of elements of type T, returns op(t1, op(t2, .....
Definition join.h:55
std::set< T > set_union(const std::set< T > &x, const std::set< T > &y)
Returns the union of two sets.
void split(const T &t, OutputIterator i, MatchFunction match, AccessorFunction1 lhs, AccessorFunction2 rhs)
Splits a binary tree T into a sequence, and writes the result to the output range given by an output ...
Definition join.h:34
std::set< T > set_intersection(const std::set< T > &x, const std::set< T > &y)
Returns the intersection of two sets.
std::set< T > set_difference(const std::set< T > &x, const std::set< T > &y)
Returns the difference of two sets.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
add your file description here.
Contains type information for terms.
Definition term_traits.h:24
void apply(T &result, const data::variable &x)
Definition builder.h:443
data_expression_builder< quantifiers_inside_builder > super
data_expression make_exists_(const variable_list &vars, const data_expression &body)
data_expression_builder< quantifiers_inside_exists_builder > super
static data_expression make_forall_(const variable_list &vars, const data_expression &body)
data_expression_builder< quantifiers_inside_forall_builder > super
data_expression operator()(const data_expression &x) const