Line data Source code
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/data/rewriters/simplify_rewriter.h
10 : /// \brief add your file description here.
11 :
12 : #ifndef MCRL2_DATA_REWRITERS_SIMPLIFY_REWRITER_H
13 : #define MCRL2_DATA_REWRITERS_SIMPLIFY_REWRITER_H
14 :
15 : #include "mcrl2/data/builder.h"
16 : #include "mcrl2/data/expression_traits.h"
17 : #include "mcrl2/data/optimized_boolean_operators.h"
18 :
19 : namespace mcrl2 {
20 :
21 : namespace data {
22 :
23 : namespace detail {
24 :
25 : template <typename Derived>
26 : class simplify_rewrite_builder: public data_expression_builder<Derived>
27 : {
28 : public:
29 : typedef data_expression_builder<Derived> super;
30 :
31 : using super::apply;
32 :
33 667 : Derived& derived()
34 : {
35 667 : return static_cast<Derived&>(*this);
36 : }
37 :
38 326 : bool is_not(const data_expression& x) const
39 : {
40 326 : return data::sort_bool::is_not_application(x);
41 : }
42 :
43 323 : bool is_and(const data_expression& x) const
44 : {
45 323 : return data::sort_bool::is_and_application(x);
46 : }
47 :
48 318 : bool is_or(const data_expression& x) const
49 : {
50 318 : return data::sort_bool::is_or_application(x);
51 : }
52 :
53 318 : bool is_imp(const data_expression& x) const
54 : {
55 318 : return data::sort_bool::is_implies_application(x);
56 : }
57 :
58 : bool is_forall(const data_expression& x) const
59 : {
60 : return data::is_forall(x);
61 : }
62 :
63 : bool is_exists(const data_expression& x) const
64 : {
65 : return data::is_exists(x);
66 : }
67 :
68 : template <class T>
69 326 : void apply(T& result, const application& x)
70 : {
71 326 : derived().enter(x);
72 326 : if (is_not(x)) // x = !y
73 : {
74 3 : data_expression y;
75 3 : derived().apply(y, *x.begin());
76 3 : data::optimized_not(result, y);
77 3 : }
78 323 : else if (is_and(x)) // x = y && z
79 : {
80 5 : data_expression y;
81 5 : derived().apply(y, binary_left(x));
82 5 : data_expression z;
83 5 : derived().apply(z, binary_right(x));
84 5 : data::optimized_and(result, y, z);
85 5 : }
86 318 : else if (is_or(x)) // x = y || z
87 : {
88 0 : data_expression y;
89 0 : derived().apply(y, binary_left(x));
90 0 : data_expression z;
91 0 : derived().apply(z, binary_right(x));
92 0 : data::optimized_or(result, y, z);
93 0 : }
94 318 : else if (is_imp(x)) // x = y => z
95 : {
96 0 : data_expression y;
97 0 : derived().apply(y, binary_left(x));
98 0 : data_expression z;
99 0 : derived().apply(z, binary_right(x));
100 0 : data::optimized_imp(result, y, z);
101 0 : }
102 : else
103 : {
104 318 : super::apply(result, x);
105 : }
106 326 : derived().leave(x);
107 326 : }
108 :
109 : template <class T>
110 1 : void apply(T& result, const forall& x) // x = forall d. y
111 : {
112 1 : variable_list d = forall(x).variables();
113 1 : data_expression y;
114 1 : derived().apply(y, forall(x).body());
115 1 : data::optimized_forall(result, d, y, true);
116 1 : }
117 :
118 : template <class T>
119 1 : void apply(T& result, const exists& x) // x = exists d. y
120 : {
121 1 : variable_list d = exists(x).variables();
122 1 : data_expression y;
123 1 : derived().apply(y, exists(x).body());
124 1 : data::optimized_exists(result, d, y, true);
125 1 : }
126 : };
127 :
128 : } // namespace detail
129 :
130 : struct simplify_rewriter
131 : {
132 : using argument_type = data_expression;
133 : using result_type = data_expression;
134 :
135 : void operator()(data_expression& result, const data_expression& x) const
136 : {
137 : core::make_apply_builder<detail::simplify_rewrite_builder>().apply(result, x);
138 : }
139 :
140 221 : data_expression operator()(const data_expression& x) const
141 : {
142 221 : data_expression result;
143 221 : core::make_apply_builder<detail::simplify_rewrite_builder>().apply(result, x);
144 221 : return result;
145 0 : }
146 : };
147 :
148 : template <typename T>
149 : void simplify(T& x, typename std::enable_if< !std::is_base_of< atermpp::aterm, T >::value>::type* = 0)
150 : {
151 : core::make_update_apply_builder<data::data_expression_builder>(simplify_rewriter()).update(x);
152 : }
153 :
154 : template <typename T>
155 109 : T simplify(const T& x, typename std::enable_if< std::is_base_of< atermpp::aterm, T >::value>::type* = nullptr)
156 : {
157 109 : T result;
158 109 : core::make_update_apply_builder<data::data_expression_builder>(simplify_rewriter()).apply(result, x);
159 109 : return result;
160 0 : }
161 :
162 : } // namespace data
163 :
164 : } // namespace mcrl2
165 :
166 : #endif // MCRL2_DATA_REWRITERS_SIMPLIFY_REWRITER_H
167 :
|