mCRL2
Loading...
Searching...
No Matches
simplify_quantifiers_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//
9/// \file mcrl2/pbes/rewriters/simplify_quantifiers_rewriter.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_PBES_REWRITERS_SIMPLIFY_QUANTIFIERS_REWRITER_H
13#define MCRL2_PBES_REWRITERS_SIMPLIFY_QUANTIFIERS_REWRITER_H
14
15#include "mcrl2/pbes/rewriters/simplify_rewriter.h"
16
17namespace mcrl2::pbes_system {
18
19namespace detail {
20
21template <template <class> class Builder, class Derived>
22struct add_simplify_quantifiers: public Builder<Derived>
23{
24 using super = Builder<Derived>;
25 using super::apply;
26
27 template <class T>
28 void apply(T& result, const forall& x)
29 {
30 pbes_expression body;
31 super::apply(body, x.body());
32 const data::variable_list& variables = x.variables();
33
34 if (is_not(body))
35 {
36 pbes_system::make_optimized_exists(result, variables, atermpp::down_cast<not_>(body).operand(), true);
38 }
39 if (is_and(body))
40 {
41 const pbes_expression& left = atermpp::down_cast<and_>(body).left();
42 const pbes_expression& right = atermpp::down_cast<and_>(body).right();
43 pbes_system::make_optimized_forall(result, variables, left, true);
44 pbes_expression result_right;
45 pbes_system::make_optimized_forall(result_right, variables, right, true);
46 pbes_system::make_optimized_and(result, result, result_right);
47 }
48 else if (is_or(body))
49 {
50 const pbes_expression& left = atermpp::down_cast<or_>(body).left();
51 const pbes_expression& right = atermpp::down_cast<or_>(body).right();
52 data::variable_list lv = data::detail::set_intersection(variables, find_free_variables(left));
53 data::variable_list rv = data::detail::set_intersection(variables, find_free_variables(right));
54 if (lv.empty())
55 {
56 pbes_system::make_optimized_forall(result, rv, right, true);
57 pbes_system::make_optimized_or(result, left, result);
58 }
59 else if (rv.empty())
60 {
61 pbes_system::make_optimized_forall(result, lv, left, true);
62 pbes_system::make_optimized_or(result, result, right);
63 }
64 else
65 {
66 pbes_system::make_optimized_forall(result, variables, body, true);
67 }
68 }
69 else
70 {
71 pbes_system::make_optimized_forall(result, variables, body, true);
72 }
73 }
74
75 template <class T>
76 void apply(T& result, const exists& x)
77 {
78 pbes_expression body;
79 super::apply(body, x.body());
80 const data::variable_list& variables = x.variables();
81
82 if (is_not(body))
83 {
84 pbes_system::make_optimized_forall(result, variables, atermpp::down_cast<not_>(body).operand(), true);
86 }
87 if (is_or(body))
88 {
89 const pbes_expression& left = atermpp::down_cast<or_>(body).left();
90 const pbes_expression& right = atermpp::down_cast<or_>(body).right();
91 pbes_system::make_optimized_exists(result, variables, left, true);
92 pbes_expression result_right;
93 pbes_system::make_optimized_exists(result_right, variables, right, true);
94 pbes_system::make_optimized_or(result, result, result_right);
95 }
96 else if (is_and(body))
97 {
98 const pbes_expression& left = atermpp::down_cast<and_>(body).left();
99 const pbes_expression& right = atermpp::down_cast<and_>(body).right();
100 data::variable_list lv = data::detail::set_intersection(variables, find_free_variables(left));
101 data::variable_list rv = data::detail::set_intersection(variables, find_free_variables(right));
102 if (lv.empty())
103 {
104 pbes_system::make_optimized_exists(result, rv, right, true);
105 pbes_system::make_optimized_and(result, left, result);
106 }
107 else if (rv.empty())
108 {
109 pbes_system::make_optimized_exists(result, lv, left, true);
110 pbes_system::make_optimized_and(result, right, result);
111 }
112 else
113 {
114 pbes_system::make_optimized_exists(result, variables, body, true);
115 }
116 }
117 else
118 {
119 pbes_system::make_optimized_exists(result, variables, body, true);
120 }
121 }
122};
123
124template <typename Derived>
126{ };
127
128template <typename Derived, typename DataRewriter, typename SubstitutionFunction>
130{
132 Derived,
135 using super::enter;
136 using super::leave;
137
138 simplify_quantifiers_data_rewriter_builder(const DataRewriter& R, SubstitutionFunction& sigma)
139 : super(R, sigma)
140 {}
141};
142
143} // namespace detail
144
145/// \brief A rewriter that simplifies boolean expressions and quantifiers.
147{
148 using term_type = pbes_expression;
149 using variable_type = data::variable;
150
152 {
153 pbes_expression result;
154 core::make_apply_builder<detail::simplify_quantifiers_builder>().apply(result, x);
155 return result;
156 }
157};
158
159/// \brief A rewriter that simplifies boolean expressions and quantifiers, and rewrites data expressions.
160template <typename DataRewriter>
162{
163 using term_type = pbes_expression;
164 using variable_type = data::variable;
165
166 const DataRewriter& R;
167
169 : R(R_)
170 {}
171
173 {
174 data::no_substitution sigma;
175 pbes_expression result;
176 detail::make_apply_rewriter_builder<detail::simplify_quantifiers_data_rewriter_builder>(R, sigma).apply(result, x);
177 return result;
178 }
179
180 template <typename SubstitutionFunction>
181 pbes_expression operator()(const pbes_expression& x, SubstitutionFunction& sigma) const
182 {
183 pbes_expression result;
184 detail::make_apply_rewriter_builder<detail::simplify_quantifiers_data_rewriter_builder>(R, sigma).apply(result, x);
185 return result;
186 }
187};
188
189} // namespace mcrl2::pbes_system
190
191
192
193#endif // MCRL2_PBES_REWRITERS_SIMPLIFY_QUANTIFIERS_REWRITER_H
\brief A data variable
Definition variable.h:25
\brief The existential quantification operator for pbes expressions
const data::variable_list & variables() const
const pbes_expression & body() const
\brief The universal quantification operator for pbes expressions
const pbes_expression & body() const
const data::variable_list & variables() const
void make_optimized_and(pbes_expression &result, const pbes_expression &p, const pbes_expression &q)
Make a conjunction.
bool is_not(const atermpp::aterm &x)
bool is_or(const atermpp::aterm &x)
void make_optimized_forall(pbes_expression &result, const data::variable_list &l, const pbes_expression &p, bool remove_variables=false)
Make a universal quantification If l is empty, p is returned.
void make_optimized_not(pbes_expression &result, const pbes_expression &p)
Make a negation.
void make_optimized_or(pbes_expression &result, const pbes_expression &p, const pbes_expression &q)
Make a disjunction.
void make_optimized_exists(pbes_expression &result, const data::variable_list &l, const pbes_expression &p, bool remove_variables=false)
Make an optimized existential quantification. If l is empty, p is returned.
bool is_and(const atermpp::aterm &x)
An empty struct that is used to denote the absence of a substitution. Used for rewriters.
simplify_quantifiers_data_rewriter_builder(const DataRewriter &R, SubstitutionFunction &sigma)
A rewriter that simplifies boolean expressions and quantifiers, and rewrites data expressions.
pbes_expression operator()(const pbes_expression &x, SubstitutionFunction &sigma) const
pbes_expression operator()(const pbes_expression &x) const
A rewriter that simplifies boolean expressions and quantifiers.
pbes_expression operator()(const pbes_expression &x) const