mCRL2
Loading...
Searching...
No Matches
maximal_closed_subformula.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_MODAL_FORMULA_MAXIMAL_CLOSED_SUBFORMULA_H
13#define MCRL2_MODAL_FORMULA_MAXIMAL_CLOSED_SUBFORMULA_H
14
16
17namespace mcrl2 {
18
19namespace state_formulas {
20
21namespace detail {
22
23inline
24std::size_t child_count(const state_formula& x)
25{
26 if (data::is_data_expression(x)) { return 0; }
27 else if (state_formulas::is_true(x)) { return 0; }
28 else if (state_formulas::is_false(x)) { return 0; }
29 else if (state_formulas::is_not(x)) { return 1; }
30 else if (state_formulas::is_and(x)) { return 2; }
31 else if (state_formulas::is_or(x)) { return 2; }
32 else if (state_formulas::is_imp(x)) { return 2; }
33 else if (state_formulas::is_forall(x)) { return 1; }
34 else if (state_formulas::is_exists(x)) { return 1; }
35 else if (state_formulas::is_must(x)) { return 1; }
36 else if (state_formulas::is_may(x)) { return 1; }
37 else if (state_formulas::is_yaled(x)) { return 0; }
38 else if (state_formulas::is_yaled_timed(x)) { return 0; }
39 else if (state_formulas::is_delay(x)) { return 0; }
40 else if (state_formulas::is_delay_timed(x)) { return 0; }
41 else if (state_formulas::is_variable(x)) { return 0; }
42 else if (state_formulas::is_nu(x)) { return 1; }
43 else if (state_formulas::is_mu(x)) { return 1; }
44 throw mcrl2::runtime_error("child_count: unknown argument");
45 return 0;
46}
47
48template <template <class> class Traverser, class Node, class Derived>
49struct bottom_up_traverser: public Traverser<Derived>
50{
51 typedef Traverser<Derived> super;
52 using super::enter;
53 using super::apply;
54
55 Derived& derived()
56 {
57 return static_cast<Derived&>(*this);
58 }
59
60 // Maintain a stack with nodes, used to store intermediate results
61 std::vector<Node> node_stack;
62 typedef typename std::vector<Node>::const_iterator node_iterator;
63
64 // Push a node to node_stack
65 void push(const Node& node)
66 {
67 node_stack.push_back(node);
68 mCRL2log(log::debug) << "<push>" << node << std::endl;
69 }
70
71 // Pop the top element of node_stack and return it
72 Node pop()
73 {
74 Node result = node_stack.back();
75 node_stack.pop_back();
76 return result;
77 }
78
79 // Return the top element of node_stack
80 Node& top()
81 {
82 return node_stack.back();
83 }
84
85 // Return the top element of node_stack
86 const Node& top() const
87 {
88 return node_stack.back();
89 }
90
91 template <typename T>
92 void join(const T& /* x */, node_iterator /* first */, node_iterator /* last */, Node& /* result */)
93 {
94 }
95
96 // Override the leave function, such that it combines the results of child nodes
97 template <typename T>
98 void leave(const T& x)
99 {
100 Node result;
101 std::size_t n = child_count(x);
102 derived().join(x, node_stack.end() - n, node_stack.end(), result);
103 node_stack.erase(node_stack.end() - n, node_stack.end());
104 push(result);
105 }
106
107 // This leave function needs to be disabled.
108 // TODO: It seems more logical that the call to this leave function is not generated in
109 // the traverser, to avoid that the same term is visited twice.
111 {
112 }
113};
114
116{
117 std::set<data::variable> variables;
118
119 free_variables_node(const std::set<data::variable>& variables_ = std::set<data::variable>())
120 : variables(variables_)
121 { }
122};
123
125{
126 std::set<state_formulas::state_formula> formulas;
127
128 maximal_closed_subformula_node(const std::set<data::variable>& variables = std::set<data::variable>(),
129 const std::set<state_formulas::state_formula>& formulas_ = std::set<state_formulas::state_formula>()
130 )
132 formulas(formulas_)
133 { }
134};
135
136std::ostream& operator<<(std::ostream& out, const maximal_closed_subformula_node& node)
137{
138 out << "<node>variables = ";
139 for (const data::variable& v: node.variables)
140 {
141 out << v << " ";
142 }
143 out << " formulas = ";
144 for (const state_formula& f: node.formulas)
145 {
146 out << f << " ";
147 }
148 return out;
149}
150
151template <typename Derived>
152struct maximal_closed_subformula_traverser: public bottom_up_traverser<state_formulas::state_formula_traverser, maximal_closed_subformula_node, Derived>
153{
155 using super::enter;
156 using super::leave;
157 using super::apply;
158 using super::push;
159 using super::pop;
160 using super::top;
161 using super::node_stack;
162
164
165 Derived& derived()
166 {
167 return static_cast<Derived&>(*this);
168 }
169
170 template <typename T>
171 void update_free_variables(const T& /* x */, maximal_closed_subformula_node& /* result */)
172 { }
173
175 {
176 data::find_free_variables(x, std::inserter(result.variables, result.variables.end()));
177 }
178
180 {
181 for (const data::variable& v: x.variables())
182 {
183 result.variables.erase(v);
184 }
185 }
186
188 {
189 for (const data::variable& v: x.variables())
190 {
191 result.variables.erase(v);
192 }
193 }
194
196 {
197 for (const data::data_expression& e: x.arguments())
198 {
199 data::find_free_variables(e, std::inserter(result.variables, result.variables.end()));
200 }
201 }
202
203 template <typename T>
205 {
206 if (result.variables.empty())
207 {
208 result.formulas.clear();
209 result.formulas.insert(x);
210 }
211 }
212
213 template <typename T>
214 void join(const T& x, node_iterator first, node_iterator last, maximal_closed_subformula_node& result)
215 {
216 for (node_iterator i = first; i != last; ++i)
217 {
218 result.variables.insert(i->variables.begin(), i->variables.end());
219 }
220 update_free_variables(x, result);
221 if (result.variables.empty())
222 {
223 result.formulas.insert(x);
224 }
225 else
226 {
227 for (node_iterator i = first; i != last; ++i)
228 {
229 result.formulas.insert(i->formulas.begin(), i->formulas.end());
230 }
231 }
232 }
233};
234
235struct apply_maximal_closed_subformula_traverser: public maximal_closed_subformula_traverser<apply_maximal_closed_subformula_traverser>
236{
238 using super::enter;
239 using super::leave;
240 using super::apply;
241 using super::top;
242};
243
244}; // namespace detail
245
246inline
247std::set<state_formulas::state_formula> maximal_closed_subformulas(const state_formula& x)
248{
250 f.apply(x);
251 return f.top().formulas;
252}
253
254} // namespace state_formulas
255
256} // namespace mcrl2
257
258#endif // MCRL2_MODAL_FORMULA_MAXIMAL_CLOSED_SUBFORMULA_H
\brief A data variable
Definition variable.h:28
Standard exception class for reporting runtime errors.
Definition exception.h:27
\brief The existential quantification operator for state formulas
const data::variable_list & variables() const
\brief The universal quantification operator for state formulas
const data::variable_list & variables() const
\brief The state formula variable
const data::data_expression_list & arguments() const
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:391
add your file description here.
bool is_data_expression(const atermpp::aterm &x)
Test for a data_expression expression.
std::set< data::variable > find_free_variables(const data::data_expression &x)
Definition data.cpp:99
std::ostream & operator<<(std::ostream &out, const maximal_closed_subformula_node &node)
std::size_t child_count(const state_formula &x)
bool is_and(const atermpp::aterm &x)
bool is_delay_timed(const atermpp::aterm &x)
bool is_exists(const atermpp::aterm &x)
bool is_not(const atermpp::aterm &x)
bool is_must(const atermpp::aterm &x)
std::set< state_formulas::state_formula > maximal_closed_subformulas(const state_formula &x)
bool is_yaled(const atermpp::aterm &x)
bool is_true(const atermpp::aterm &x)
bool is_variable(const atermpp::aterm &x)
bool is_may(const atermpp::aterm &x)
bool is_yaled_timed(const atermpp::aterm &x)
bool is_imp(const atermpp::aterm &x)
bool is_nu(const atermpp::aterm &x)
bool is_delay(const atermpp::aterm &x)
bool is_false(const atermpp::aterm &x)
bool is_mu(const atermpp::aterm &x)
bool is_forall(const atermpp::aterm &x)
bool is_or(const atermpp::aterm &x)
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
maximal_closed_subformula_traverser< apply_maximal_closed_subformula_traverser > super
void leave(const state_formulas::state_formula &)
void join(const T &, node_iterator, node_iterator, Node &)
free_variables_node(const std::set< data::variable > &variables_=std::set< data::variable >())
maximal_closed_subformula_node(const std::set< data::variable > &variables=std::set< data::variable >(), const std::set< state_formulas::state_formula > &formulas_=std::set< state_formulas::state_formula >())
void update_free_variables(const data::data_expression &x, maximal_closed_subformula_node &result)
bottom_up_traverser< state_formulas::state_formula_traverser, maximal_closed_subformula_node, Derived > super
void join(const T &x, node_iterator first, node_iterator last, maximal_closed_subformula_node &result)
void update_free_variables(const T &, maximal_closed_subformula_node &)
void update_free_variables(const state_formulas::exists &x, maximal_closed_subformula_node &result)
void update_maximal_closed_formulas(const T &x, maximal_closed_subformula_node &result)
void update_free_variables(const state_formulas::variable &x, maximal_closed_subformula_node &result)
void update_free_variables(const state_formulas::forall &x, maximal_closed_subformula_node &result)