mCRL2
Loading...
Searching...
No Matches
stategraph_simplify_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/detail/stategraph_simplify_rewriter.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_PBES_DETAIL_STATEGRAPH_SIMPLIFY_REWRITER_H
13#define MCRL2_PBES_DETAIL_STATEGRAPH_SIMPLIFY_REWRITER_H
14
15#include "mcrl2/data/consistency.h"
16#include "mcrl2/data/rewriters/simplify_rewriter.h"
17#include "mcrl2/pbes/detail/stategraph_split.h"
18#include "mcrl2/pbes/rewriters/simplify_quantifiers_rewriter.h"
19
20
21
22
23
24namespace mcrl2::pbes_system::detail {
25
26inline
28{
29 if (is_data(x))
30 {
31 const data::data_expression& x1 = atermpp::down_cast<data::data_expression>(x);
32 if (data::is_not(x1))
33 {
34 return atermpp::down_cast<pbes_expression>(data::unary_operand1(x1));
35 }
36 else if (data::is_not_equal_to(x1))
37 {
38 const data::data_expression& left = data::binary_left1(x1);
39 const data::data_expression& right = data::binary_right1(x1);
40 return atermpp::down_cast<pbes_expression>(data::equal_to(left, right));
41 }
42 else if (data::is_equal_to(x1))
43 {
44 const data::data_expression& left = data::binary_left1(x1);
45 const data::data_expression& right = data::binary_right1(x1);
46 return atermpp::down_cast<pbes_expression>(data::not_equal_to(left, right));
47 }
48 else
49 {
50 return atermpp::down_cast<pbes_expression>(data::not_(x1));
51 }
52 }
53 return not_(x);
54}
55
56inline
58{
59 if (is_data(x) && is_data(y))
60 {
61 return atermpp::down_cast<pbes_expression>(data::and_(atermpp::down_cast<data::data_expression>(x), atermpp::down_cast<data::data_expression>(y)));
62 }
63 return and_(x, y);
64}
65
66inline
68{
69 if (is_data(x) && is_data(y))
70 {
71 return atermpp::down_cast<pbes_expression>(data::or_(atermpp::down_cast<data::data_expression>(x), atermpp::down_cast<data::data_expression>(y)));
72 }
73 return or_(x, y);
74}
75
76template <typename Derived, typename DataRewriter, typename SubstitutionFunction>
77struct stategraph_simplify_builder: public simplify_quantifiers_data_rewriter_builder<Derived, DataRewriter, SubstitutionFunction>
78{
79 using super = simplify_quantifiers_data_rewriter_builder<Derived, DataRewriter, SubstitutionFunction>;
80 using super::apply;
81
82 /// \brief Constructor.
83 /// \param rewr A data rewriter
84 stategraph_simplify_builder(const DataRewriter& R, SubstitutionFunction& sigma)
85 : super(R, sigma)
86 { }
87
88 Derived& derived()
89 {
90 return static_cast<Derived&>(*this);
91 }
92
93 // returns the argument of a not expression (pbes or data)
95 {
96 if (is_data(x))
97 {
98 return atermpp::down_cast<pbes_expression>(*data::application(x).begin());
99 }
100 else
101 {
102 return atermpp::down_cast<not_>(x).operand();
103 }
104 }
105
106 pbes_expression stategraph_join_or(const std::vector<pbes_expression>& terms) const
107 {
108 const pbes_expression& F = false_();
109 return utilities::detail::join(terms.begin(), terms.end(), smart_or, F);
110 }
111
112 pbes_expression stategraph_join_and(const std::vector<pbes_expression>& terms) const
113 {
114 const pbes_expression& T = true_();
115 return utilities::detail::join(terms.begin(), terms.end(), smart_and, T);
116 }
117
118 // apply de Morgan rules
120 {
121 pbes_expression result = x;
122
124 {
125 const pbes_expression& arg = not_arg(x);
126
127 // replace !(x1 \/ ... \/ xn) by !x1 /\ ... /\ !xn
128 if (is_universal_or(arg))
129 {
130 std::vector<pbes_expression> terms;
131 detail::stategraph_split_or(arg, terms);
132 for (pbes_expression& term: terms)
133 {
134 term = stategraph_not(term);
135 }
136 result = stategraph_join_and(terms);
137 }
138 // replace !(x1 /\ ... /\ xn) by !x1 \/ ... \/ !xn
139 else if (is_universal_and(arg))
140 {
141 std::vector<pbes_expression> terms;
142 detail::stategraph_split_and(arg, terms);
143 for (pbes_expression& term: terms)
144 {
145 term = stategraph_not(term);
146 }
147 result = stategraph_join_or(terms);
148 }
149 else
150 {
151 result = stategraph_not(arg);
152 }
153 }
154 mCRL2log(log::log_level_t::trace) << " simplify-postprocess " << x << " -> " << result << std::endl;
155 return result;
156 }
157
158 template <class T>
159 void apply(T& result, const data::data_expression& x)
160 {
161 super::apply(result, data::simplify(x));
162 result = post_process(result);
163 }
164
165 template <class T>
166 void apply(T& result, const not_& x)
167 {
168 super::apply(result, x);
169 result = post_process(result);
170 }
171
172 template <class T>
173 void apply(T& result, const and_& x)
174 {
175
176 super::apply(result, x);
177 result = post_process(result);
178 }
179
180 template <class T>
181 void apply(T& result, const or_& x)
182 {
183 super::apply(result, x);
184 result = post_process(result);
185 }
186
187 template <class T>
188 void apply(T& result, const imp& x)
189 {
190 derived().apply(result, or_(not_(x.left()), x.right()));
191 }
192
193 template <class T>
194 void apply(T& result, const forall& x)
195 {
196 super::apply(result, x);
197 result = post_process(result);
198 }
199
200 template <class T>
201 void apply(T& result, const exists& x)
202 {
203 super::apply(result, x);
204 result = post_process(result);
205 }
206
207 template <class T>
209 {
210 super::apply(result, x);
211 result = post_process(result);
212 }
213};
214
215/// \brief A rewriter that simplifies expressions that simplifies quantifiers.
216template <typename DataRewriter>
218{
219 protected:
220 /// \brief The data rewriter
221 const DataRewriter& m_rewriter;
222
223 public:
224 /// \brief The term type
225 using term_type = pbes_expression;
226
227 /// \brief The variable type
228 using variable_type = data::variable;
229
230 /// \brief Constructor
231 /// \param rewriter A data rewriter
232 stategraph_simplify_rewriter(const DataRewriter& rewriter)
233 : m_rewriter(rewriter)
234 {}
235
236 /// \brief Rewrites a pbes expression.
237 /// \param x A term
238 /// \return The rewrite result.
240 {
241 data::no_substitution sigma;
242 pbes_expression result;
243 detail::make_apply_rewriter_builder<stategraph_simplify_builder>(m_rewriter, sigma).apply(result, x);
244 return result;
245 }
246
247 /// \brief Rewrites a pbes expression.
248 /// \param x A term
249 /// \param sigma A substitution function
250 /// \return The rewrite result.
251 template <typename SubstitutionFunction>
252 pbes_expression operator()(const pbes_expression& x, SubstitutionFunction& sigma) const
253 {
254 pbes_expression result;
255 detail::make_apply_rewriter_builder<stategraph_simplify_builder>(m_rewriter, sigma).apply(result, x);
256 return result;
257 }
258};
259
260} // namespace mcrl2::pbes_system::detail
261
262
263
264
265
266#endif // MCRL2_PBES_DETAIL_STATEGRAPH_SIMPLIFY_REWRITER_H
\brief A data variable
Definition variable.h:25
\brief The and operator for pbes expressions
and_(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
A rewriter that simplifies expressions that simplifies quantifiers.
pbes_expression operator()(const pbes_expression &x, SubstitutionFunction &sigma) const
Rewrites a pbes expression.
stategraph_simplify_rewriter(const DataRewriter &rewriter)
Constructor.
pbes_expression operator()(const pbes_expression &x) const
Rewrites a pbes expression.
\brief The existential quantification operator for pbes expressions
\brief The universal quantification operator for pbes expressions
\brief The implication operator for pbes expressions
const pbes_expression & left() const
const pbes_expression & right() const
\brief The not operator for pbes expressions
not_(const pbes_expression &operand)
\brief Constructor Z14.
\brief The or operator for pbes expressions
or_(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
pbes_expression & operator=(pbes_expression &&) noexcept=default
\brief A propositional variable instantiation
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:435
bool is_not(const data_expression &x)
Test if x is a negation.
Definition consistency.h:44
bool is_not_equal_to(const data_expression &x)
Test if x is an inequality.
Definition consistency.h:84
bool is_equal_to(const data_expression &x)
Test if x is an equality.
Definition consistency.h:76
pbes_expression smart_and(const pbes_expression &x, const pbes_expression &y)
pbes_expression smart_or(const pbes_expression &x, const pbes_expression &y)
pbes_expression stategraph_not(const pbes_expression &x)
bool is_universal_or(const pbes_expression &t)
Test for a disjunction.
bool is_data(const pbes_expression &t)
Returns true if the term t is a data expression.
bool is_universal_and(const pbes_expression &t)
Test for a conjunction.
const pbes_expression & true_()
bool is_universal_not(const pbes_expression &t)
Test for a conjunction.
const pbes_expression & false_()
An empty struct that is used to denote the absence of a substitution. Used for rewriters.
pbes_expression stategraph_join_and(const std::vector< pbes_expression > &terms) const
void apply(T &result, const propositional_variable_instantiation &x)
const pbes_expression & not_arg(const pbes_expression &x)
stategraph_simplify_builder(const DataRewriter &R, SubstitutionFunction &sigma)
Constructor.
void apply(T &result, const data::data_expression &x)
pbes_expression stategraph_join_or(const std::vector< pbes_expression > &terms) const