mCRL2
Loading...
Searching...
No Matches
jitty_jittyc.h
Go to the documentation of this file.
1// Author(s): Jan Friso Groote
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
10#ifndef MCRL2_DATA_DETAIL_REWRITE_JITTY_JITTYC_H
11#define MCRL2_DATA_DETAIL_REWRITE_JITTY_JITTYC_H
12
15
16namespace mcrl2
17{
18namespace data
19{
20namespace detail
21{
22
23template <template <class> class Traverser>
24struct double_variable_traverser : public Traverser<double_variable_traverser<Traverser> >
25{
26 typedef Traverser<double_variable_traverser<Traverser> > super;
27 using super::enter;
28 using super::leave;
29 using super::apply;
30
31 std::set<variable> m_seen;
32 std::set<variable> m_doubles;
33
34 void apply(const variable& v)
35 {
36 if (!m_seen.insert(v).second)
37 {
38 m_doubles.insert(v);
39 }
40 }
41
42 const std::set<variable>& result()
43 {
44 return m_doubles;
45 }
46};
47
48
50{
51 const std::set<variable> s = find_free_variables(a);
52 return variable_list(s.begin(), s.end());
53}
54
55inline sort_expression residual_sort(const sort_expression& s, std::size_t no_of_initial_arguments)
56{
57 // Remove no_of_initial_arguments sort from sort s.
58
59 sort_expression result=s;
60 while (no_of_initial_arguments > 0)
61 {
62 assert(is_function_sort(result));
63 const function_sort& sf = atermpp::down_cast<function_sort>(result);
64 assert(sf.domain().size()<=no_of_initial_arguments);
65 no_of_initial_arguments=no_of_initial_arguments-sf.domain().size();
66 result=sf.codomain();
67 }
68
69 return result;
70}
71
72// This function returns <b, arg_i> where arg_i is the i-th argument of the application t and
73// b is a boolean that indicates whether this argument exists.
74// TODO: use the optional class of c++17 when it can be used. The current solution is somewhat ugly.
75// This function yields a pointer to argument_i if it exists. If not it yields the nullptr;
77{
78 // t has the shape t application(....)
79 if (!is_application(t.head()))
80 {
81 const std::size_t arity = t.size();
82 if (arity>i)
83 {
84 return &t[i];
85 }
86 // arity <=i
87 i=i-arity;
88 return nullptr;
89 }
90 const data_expression* p=get_argument_of_higher_order_term_helper(atermpp::down_cast<application>(t.head()),i);
91 if (p!=nullptr)
92 {
93 return p;
94 }
95 const std::size_t arity = t.size();
96 if (arity>i)
97 {
98 return &t[i];
99 }
100 // arity <=i
101 i=i-arity;
102 return nullptr;
103}
104
105// This function returns the i-th argument t_i. NOTE: The first argument has index 1.
106// t is an applicatoin of the shape application(application(...application(f,t1,...tn),tn+1....),tm...).
107// i must be a valid index of an argument.
109{
110 // This first case applies to the majority of cases. Therefore this cheap check is done first, before
111 // going into a recursive algorithm. Furthermore checking that t is a function_symbol, etc. is cheaper
112 // than checking that t is not an application by !is_application(t.head()).
113 const data_expression& head=t.head();
114 if (is_function_symbol(head) ||
115 is_variable(head) ||
116 is_where_clause(head) ||
117 is_abstraction(head))
118 {
119 assert(t.size()>i);
120 return t[i];
121 }
122
124 assert(p!=nullptr);
125 return *p;
126}
127
128inline std::size_t recursive_number_of_args(const data_expression& t)
129{
130 // Checking these cases is together more efficient than
131 // checking whether t is an application.
132 if (is_machine_number(t) ||
134 is_variable(t) ||
135 is_where_clause(t) ||
137 {
138 return 0;
139 }
140
141 assert(is_application(t));
142
143 const application& ta = atermpp::down_cast<application>(t);
144 return ta.size()+recursive_number_of_args(ta.head());
145}
146
147// Return the head symbol, nested within applications.
148// This helper function is used to allow inlining of the function
149// get_nested_head.
151{
152 if (is_application(t.head()))
153 {
154 return get_nested_head_helper(atermpp::down_cast<application>(t.head()));
155 }
156
157 return t.head();
158}
159
160// Return the head symbol, nested within applications.
162{
163 if (is_machine_number(t) ||
165 is_variable(t) ||
166 is_where_clause(t) ||
168 {
169 return t;
170 }
171
172 const application& ta = atermpp::down_cast<application>(t);
173 const data_expression& head=ta.head();
174
175 if (is_machine_number(t) ||
176 is_function_symbol(head) ||
177 is_variable(head) ||
178 is_where_clause(head) ||
179 is_abstraction(head))
180 {
181 return head;
182 }
183 return get_nested_head_helper(atermpp::down_cast<application>(head));
184}
185
186// Replace the recursively nested head symbol in t by head.
188{
189 if (is_application(t))
190 {
191 const application& ta = atermpp::down_cast<application>(t);
192 return application(replace_nested_head(ta.head(),head),ta.begin(),ta.end());
193 }
194
195 return head;
196}
197
198template <class ARGUMENT_REWRITER>
199inline void rewrite_all_arguments(data_expression& result, const application& t, const ARGUMENT_REWRITER rewriter)
200{
201 make_application(result,t.head(),t.begin(),t.end(),rewriter);
202}
203
204}
205}
206}
207
208#endif // REWRITE_JITTY_JITTYC_COMMON_H
size_type size() const
Returns the size of the term_list.
Definition aterm_list.h:256
An application of a data expression to a number of arguments.
const_iterator end() const
Returns an iterator pointing past the last argument of the application.
const_iterator begin() const
Returns an iterator pointing to the first argument of the application.
const data_expression & head() const
Get the function at the head of this expression.
std::size_t size() const
\brief A function sort
const sort_expression & codomain() const
const sort_expression_list & domain() const
Rewriter that operates on data expressions.
Definition rewriter.h:81
\brief A sort expression
\brief A data variable
Definition variable.h:28
The standard sort function_update.
void rewrite_all_arguments(data_expression &result, const application &t, const ARGUMENT_REWRITER rewriter)
const data_expression * get_argument_of_higher_order_term_helper(const application &t, std::size_t &i)
std::size_t recursive_number_of_args(const data_expression &t)
const data_expression & get_nested_head_helper(const application &t)
const data_expression & get_argument_of_higher_order_term(const application &t, std::size_t i)
variable_list get_free_vars(const data_expression &a)
const data_expression replace_nested_head(const data_expression &t, const data_expression &head)
sort_expression residual_sort(const sort_expression &s, std::size_t no_of_initial_arguments)
const data_expression & get_nested_head(const data_expression &t)
bool is_where_clause(const atermpp::aterm &x)
Returns true if the term t is a where clause.
bool is_abstraction(const atermpp::aterm &x)
Returns true if the term t is an abstraction.
bool is_function_symbol(const atermpp::aterm &x)
Returns true if the term t is a function symbol.
std::set< data::variable > find_free_variables(const data::data_expression &x)
Definition data.cpp:99
atermpp::term_list< variable > variable_list
\brief list of variables
bool is_function_sort(const atermpp::aterm &x)
Returns true if the term t is a function sort.
bool is_machine_number(const atermpp::aterm &x)
Returns true if the term t is a machine_number.
bool is_application(const atermpp::aterm &x)
Returns true if the term t is an application.
bool is_variable(const atermpp::aterm &x)
Returns true if the term t is a variable.
void make_application(atermpp::aterm &result)
Make function for an application.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
Traverser< double_variable_traverser< Traverser > > super
const std::set< variable > & result()