mCRL2
Loading...
Searching...
No Matches
if_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/data/rewriters/if_rewriter.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_DATA_REWRITERS_IF_REWRITER_H
13#define MCRL2_DATA_REWRITERS_IF_REWRITER_H
14
15#include "mcrl2/data/rewriter.h"
16#include "mcrl2/data/builder.h"
17#include "mcrl2/data/consistency.h"
18#include "mcrl2/data/standard.h"
19
20namespace mcrl2::data {
21
22namespace detail {
23
24// Returns f(x0, ..., x_i-1, y, x_i+1, ..., xn)
25inline
26application replace_argument(const application& x, std::size_t i, const data_expression& y)
27{
28 std::size_t j = 0;
29 return application(x.head(), x.begin(), x.end(), [&](const data_expression& x_i) { return (j++ == i+1) ? y : x_i; });
30}
31
32inline
33data_expression push_if_outside(const application& x)
34{
35 for (std::size_t i = 0; i < x.size(); i++)
36 {
37 if (is_if_application(x[i]))
38 {
39 const auto& x_i = atermpp::down_cast<application>(x[i]);
40 const data_expression& b = x_i[0];
41 const data_expression& t1 = x_i[1];
42 const data_expression& t2 = x_i[2];
43 return if_(b, push_if_outside(replace_argument(x, i, t1)), push_if_outside(replace_argument(x, i, t2)));
44 }
45 }
46 return x;
47}
48
49template <typename Derived>
51{
52 using super = data_expression_builder<Derived>;
53
54 using super::apply;
55
56 bool is_simple(const data_expression& x) const
57 {
58 return !is_and(x) && !is_or(x) && !is_imp(x) && !is_not(x) && !is_true(x) && !is_false(x);
59 }
60
62 {
63 if (is_true(b))
64 {
65 return t1;
66 }
67 else if (is_false(b))
68 {
69 return t2;
70 }
71 else if (is_and(b))
72 {
73 const data_expression& b1 = binary_left1(b);
74 const data_expression& b2 = binary_right1(b);
75 return if_(b1, if_(b2, t1, t2), t2);
76 }
77 else if (is_or(b))
78 {
79 const data_expression& b1 = binary_left1(b);
80 const data_expression& b2 = binary_right1(b);
81 return if_(b1, t1, if_(b2, t1, t2));
82 }
83 else if (is_imp(b))
84 {
85 const data_expression& b1 = binary_left1(b);
86 const data_expression& b2 = binary_right1(b);
87 return if_(b1, if_(b2, t1, t2), t1);
88 }
89 else if (is_not(b))
90 {
91 const data_expression& b1 = unary_operand1(b);
92 return if_(b1, t2, t1);
93 }
94 else
95 {
96 assert(is_simple(b));
97 if (t1 == t2)
98 {
99 return t1;
100 }
101 else if (is_if_application(t1))
102 {
103 const application& t1_ = atermpp::down_cast<application>(t1);
104 const data_expression& c = t1_[0];
105 const data_expression& u1 = t1_[1];
106 const data_expression& u2 = t1_[2];
107 if (b == c)
108 {
109 return apply_if(b, u1, t2);
110 }
111 else if (b > c) // use the aterm pointer comparison
112 {
113 assert(is_simple(c));
114 return apply_if(c, apply_if(b, u1, t2), apply_if(b, u2, t2));
115 }
116 else
117 {
118 return if_(b, t1, t2);
119 }
120 }
121 else if (is_if_application(t2))
122 {
123 const application& t2_ = atermpp::down_cast<application>(t2);
124 const data_expression& c = t2_[0];
125 const data_expression& u1 = t2_[1];
126 const data_expression& u2 = t2_[2];
127 if (b == c)
128 {
129 return apply_if(b, t1, u2);
130 }
131 else if (b > c) // use the aterm pointer comparison
132 {
133 assert(is_simple(c));
134 return apply_if(c, apply_if(b, t1, u1), apply_if(b, t1, u2));
135 }
136 else
137 {
138 return if_(b, t1, t2);
139 }
140 }
141 else
142 {
143 return if_(b, t1, t2);
144 }
145 }
146 }
147
148 template <class T>
149 void apply(T& result, const application& x)
150 {
151 if (is_if_application(x))
152 {
154 super::apply(b, x[0]);
156 super::apply(t1, x[1]);
158 super::apply(t2, x[2]);
159 result = apply_if(b, t1, t2);
160 }
161 else
162 {
163 super::apply(result, x);
164 result = push_if_outside(atermpp::down_cast<application>(result));
165 }
166 }
167};
168
170{
172 using super::apply;
173 using super::apply_if;
174
176
178 {}
179
180 template <class T>
181 void apply(T& result, const application& x)
182 {
183 if (is_if_application(x))
184 {
186 super::apply(b, x[0]);
188 super::apply(t1, x[1]);
190 super::apply(t2, x[2]);
191 result = apply_if(b, t1, t2);
192 }
193 else
194 {
195 super::apply(result, x);
196 result = push_if_outside(atermpp::down_cast<application>(result));
197 }
198 result = rewr(result);
199 }
200};
201
202} // namespace detail
203
205{
206 using argument_type = data_expression;
207 using result_type = data_expression;
208
210 {
211 data_expression result;
212 core::make_apply_builder<detail::if_rewrite_builder>().apply(result, x);
213 return result;
214 }
215};
216
217template <typename T>
218 requires(!std::is_base_of_v<atermpp::aterm, T>)
220{
222}
223
224template <typename T>
225 requires(std::is_base_of_v<atermpp::aterm, T>)
227{
228 T result;
230 return result;
231}
232
233} // namespace mcrl2::data
234
235
236
237#endif // MCRL2_DATA_REWRITERS_IF_REWRITER_H
Rewriter that operates on data expressions.
Definition rewriter.h:84
application replace_argument(const application &x, std::size_t i, const data_expression &y)
Definition if_rewriter.h:26
data_expression push_if_outside(const application &x)
Definition if_rewriter.h:33
bool is_or(const data_expression &x)
Test if x is a disjunction.
Definition consistency.h:52
bool is_false(const data_expression &x)
Test if x is false.
Definition consistency.h:36
bool is_not(const data_expression &x)
Test if x is a negation.
Definition consistency.h:44
application if_(const data_expression &arg0, const data_expression &arg1, const data_expression &arg2)
Application of function symbol if.
Definition standard.h:215
bool is_true(const data_expression &x)
Test if x is true.
Definition consistency.h:28
bool is_imp(const data_expression &x)
Test if x is an implication.
Definition consistency.h:68
bool is_and(const data_expression &x)
Test if x is a conjunction.
Definition consistency.h:60
bool is_simple(const data_expression &x) const
Definition if_rewriter.h:56
data_expression apply_if(const data_expression &b, const data_expression &t1, const data_expression &t2)
Definition if_rewriter.h:61
void apply(T &result, const application &x)
void apply(T &result, const application &x)
data_expression operator()(const data_expression &x) const