mCRL2
Loading...
Searching...
No Matches
application.h
Go to the documentation of this file.
1// Author(s): Jeroen Keiren, 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//
11
12#ifndef MCRL2_DATA_VARIABLE_H
13#include "mcrl2/data/variable.h"
14#endif
15
16#ifndef MCRL2_DATA_APPLICATION_H
17#define MCRL2_DATA_APPLICATION_H
18
19namespace mcrl2
20{
21
22namespace data
23{
24
25namespace detail
26{
27
28// The class and the specialisation below are intended to
29// make the type of the term_appl_prepend_iterator a forward iterator,
30// unless it is based on an input iterator, in which case it should be an
31// input iterator.
32template <class IteratorTag>
34{
35 public:
36 typedef std::forward_iterator_tag iterator_category;
37};
38
39template <>
40class prepend_iterator_tag_convertor<std::input_iterator_tag>
41{
42 public:
43 typedef std::input_iterator_tag iterator_category;
44};
45
46// Iterator for term_appl which prepends a data_expression to a list convertible to data_expressions.
47template <class Iterator >
49{
50 private:
51 typedef std::iterator_traits<int*> traits;
52
53 public:
54 // The value_type.
56 // The reference type.
57 typedef const data_expression& reference;
58 // The pointer type.
59 typedef const data_expression* pointer;
60 // Difference type
61 typedef ptrdiff_t difference_type;
62 // The iterator category.
63 // The iterator category is a forward_iterator, unless Iterator is an input iterator, in which case
64 // it is an input iterator.
66
67 protected:
68 Iterator m_it;
70
71 private:
72 // Prevent the use of the following operators in this class, including the
73 // postfix increment.
84
85 public:
86 // Constructor.
88 pointer prepend=nullptr)
89 : m_it(it), m_prepend(prepend)
90 {}
91
92 // The copy constructor.
94 : m_it(other.m_it),
95 m_prepend(other.m_prepend)
96 {
97 }
98
99 // The assignment operator.
100 // other The term to be assigned.
101 // Returns a reference to the assigned iterator.
103 {
104 m_it=other.m_it;
105 m_prepend=other.m_prepend;
106 return *this;
107 }
108
109 // The dereference operator.
110 // Return the dereferenced term.
112 {
113 if (m_prepend)
114 {
115 return *m_prepend;
116 }
117 return *(this->m_it);
118 }
119
120 // Dereference the current iterator.
121 pointer operator->() const
122 {
123 if (m_prepend)
124 {
125 return m_prepend;
126 }
127 return &*(this->m_it);
128 }
129
130 // Prefix increment.
131 // Returns the iterator after it is incremented.
133 {
134 if (m_prepend)
135 {
136 m_prepend = nullptr;
137 }
138 else
139 {
140 ++(this->m_it);
141 }
142 return *this;
143 }
144
145 // Equality of iterators.
147 {
148 return m_prepend==other.m_prepend && this->m_it==other.m_it;
149 }
150
151 // Inequality of iterators.
153 {
154 return !(*this==other);
155 }
156
157 // Comparison of iterators.
158 bool operator <(const term_appl_prepend_iterator& other) const
159 {
160 return m_prepend < other.m_prepend || (m_prepend==other.m_prepend && this->m_it<other.m_it);
161 }
162
163 // Comparison of iterators.
165 {
166 return m_prepend < other.m_prepend || (m_prepend==other.m_prepend && this->m_it<=other.m_it);
167 }
168
169 // Comparison of iterators.
170 bool operator >(const term_appl_prepend_iterator& other) const
171 {
172 return other<*this;
173 }
174
175 // Comparison of iterators.
177 {
178 return other<=*this;
179 }
180};
181
182// The class below transforms a function that is to be applied to
183// the arguments of an application into a function that is not applied
184// to the head, and only applied to the arguments.
185template <class ArgumentConverter>
187{
188 protected:
189 ArgumentConverter& m_f;
190 std::size_t m_current_index;
191 const bool m_skip_head;
192 public:
193 skip_function_application_to_head(ArgumentConverter&f, const bool skip_head )
194 : m_f(f),
196 m_skip_head(skip_head)
197 {}
198
200 {
201 if (m_skip_head && m_current_index++==0)
202 {
203 return d;
204 }
205 return m_f(d);
206 }
207};
208
209// The class below transforms a function that is to be applied to
210// the arguments of an application into a function that is not applied
211// to the head, and only applied to the arguments.
212template <class ArgumentConverter>
214{
215 protected:
216 ArgumentConverter& m_f;
217 std::size_t m_current_index;
218 const bool m_skip_head;
219 public:
220 skip_function_application_to_head_assignment(ArgumentConverter& f, const bool skip_head )
221 : m_f(f),
223 m_skip_head(skip_head)
224 {}
225
227 {
228 if (m_skip_head && m_current_index++==0)
229 {
230 result=d;
231 return;
232 }
233 m_f(result,d);
234 return;
235 }
236};
237
238
240{
241 if (is_untyped_sort(s))
242 {
243 return true;
244 }
245 if (is_function_sort(s))
246 {
247 const function_sort& fs=atermpp::down_cast<function_sort>(s);
249 {
250 return true;
251 }
252 for(const sort_expression& sd: fs.domain())
253 {
254 if (contains_untyped_sort(sd))
255 {
256 return true;
257 }
258 }
259 }
260 if (is_container_sort(s))
261 {
262 if (contains_untyped_sort(atermpp::down_cast<container_sort>(s).element_sort()))
263 {
264 return true;
265 }
266 }
267 assert(is_structured_sort(s) || is_basic_sort(s));
268 return true;
269}
270
272{
273 return t;
274}
275
276template <class TERM>
278 const TERM& t,
279 typename std::enable_if<std::is_invocable_r<void, TERM, data_expression&>::value>::type* = nullptr)
280{
281 data_expression result;
282 t(result);
283 return result;
284}
285
286template <class TERM >
288 const TERM& t,
289 typename std::enable_if<std::is_invocable_r<const data_expression, TERM, void>::value>::type* = nullptr)
290{
291 return t();
292}
293
294template <class HEAD, class CONTAINER>
295inline bool check_whether_sorts_match(const HEAD& head_lambda, const CONTAINER& l)
296{
298 if (contains_untyped_sort(head.sort()))
299 {
300 // Most likely head is a just parsed, untyped object.
301 return true;
302 }
303 function_sort fs(head.sort());
304 if ((fs.domain().size()==1 && contains_untyped_sort(fs.domain().front())) ||
305 (l.size()==1 && contains_untyped_sort(l.front().sort())))
306 {
307 // This is most likely an application from or to an Rewritten@@term, used in the jitty rewriter
308 // to indicate that a term is in normal form.
309 return true;
310 }
311 // Check that the sorts of the function domain of the head matches those of the arguments.
312 if (fs.domain().size()!=l.size())
313 {
314 return false;
315 }
316 typename CONTAINER::const_iterator i=l.begin();
317 for(const sort_expression& s: fs.domain())
318 {
319 if (!contains_untyped_sort(i->sort()) && s!=i->sort())
320 {
321 return false;
322 }
323 ++i;
324 }
325 return true;
326}
327
329{
330 return data_expression_list();
331}
332
333template <class HEAD, class... ARGUMENTS>
334inline
335data_expression_list get_arguments(const HEAD& h, const ARGUMENTS&... args)
336{
337 data_expression_list result=get_arguments(args...);
339 return result;
340}
341
342/* template <class HEAD, class... CONTAINER>
343inline bool check_whether_sorts_match(const HEAD& head_lambda, const CONTAINER&... l)
344{
345 data_expression_list arguments=get_arguments(l...);
346 return check_whether_sorts_match(head_lambda, arguments);
347} */
348
349} // namespace detail
350
353{
354 public:
357 : data_expression(atermpp::aterm(core::detail::function_symbol_DataAppl(0)))
358 {}
359
361 template<typename ...Terms,
362 typename = std::enable_if_t<std::conjunction_v<std::is_convertible<Terms, data_expression>...>> >
364 const data_expression& arg1,
365 const Terms& ...other_arguments
366 )
368 core::detail::function_symbol_DataAppl(sizeof...(Terms)+2),head,arg1,other_arguments...))
369 {
371 }
372
375 explicit application(const atermpp::aterm& term)
376 : data_expression(term)
377 {
379 }
380
382 template <typename Container>
384 const Container& arguments,
386 : data_expression(atermpp::aterm(core::detail::function_symbol_DataAppl(arguments.size() + 1),
387 detail::term_appl_prepend_iterator<typename Container::const_iterator>(arguments.begin(), &head),
388 detail::term_appl_prepend_iterator<typename Container::const_iterator>(arguments.end())))
389 {
390 assert(arguments.size()>0);
391 assert(detail::check_whether_sorts_match(head,arguments));
392 }
393
394 private:
395 // forbid the use of iterator, which is silently inherited from
396 // aterm. Modifying the arguments of an application through the iterator
397 // is not allowed!
399
400 public:
401
411
413 template <typename FwdIter>
415 FwdIter first,
416 FwdIter last,
417 typename std::enable_if< !std::is_base_of<data_expression, FwdIter>::value>::type* = nullptr)
418 : data_expression(atermpp::aterm(core::detail::function_symbol_DataAppl(std::distance(first, last) + 1),
419 detail::term_appl_prepend_iterator<FwdIter>(first, &head),
420 detail::term_appl_prepend_iterator<FwdIter>(last)))
421 {
422 assert(first!=last);
424 }
425
427 template <typename FwdIter>
428 application(const std::size_t arity,
429 const data_expression& head,
430 FwdIter first,
431 FwdIter last,
432 typename std::enable_if< !std::is_base_of<data_expression, FwdIter>::value>::type* = 0)
433 : data_expression(atermpp::aterm(core::detail::function_symbol_DataAppl(arity + 1),
434 detail::term_appl_prepend_iterator<FwdIter>(first, &head),
435 detail::term_appl_prepend_iterator<FwdIter>(last)))
436 {
437 assert(arity>0);
438 assert(std::distance(first, last)==arity);
440 }
441
442
451 template <typename FwdIter, class ArgumentConverter>
453 FwdIter first,
454 FwdIter last,
455 ArgumentConverter convert_arguments,
456 const bool skip_first_argument=false,
457 typename std::enable_if< !std::is_base_of<data_expression, FwdIter>::value>::type* = nullptr,
458 typename std::enable_if< !std::is_base_of<data_expression, ArgumentConverter>::value>::type* = nullptr )
459 // typename std::enable_if< std::is_convertible<typename std::invoke_result<ArgumentConverter,typename FwdIter::value_type>::type, data_expression>::value>::type* = nullptr)
461 core::detail::function_symbol_DataAppl(std::distance(first, last) + 1),
462 detail::term_appl_prepend_iterator<FwdIter>(first, &head),
463 detail::term_appl_prepend_iterator<FwdIter>(last),
464 detail::skip_function_application_to_head(convert_arguments,skip_first_argument)))
465 {
466 assert(first!=last);
468 }
469
478 template <typename FwdIter, class ArgumentConverter>
480 FwdIter first,
481 FwdIter last,
482 ArgumentConverter convert_arguments,
483 const bool skip_first_argument=false,
484 typename std::enable_if< !std::is_base_of<data_expression, FwdIter>::value>::type* = nullptr,
485 typename std::enable_if< !std::is_base_of<data_expression, ArgumentConverter>::value>::type* = nullptr,
486 typename std::enable_if<std::is_same<typename std::invoke_result<ArgumentConverter,data_expression&,typename FwdIter::value_type>::type, void>::value>::type* = nullptr)
487
489 core::detail::function_symbol_DataAppl(std::distance(first, last) + 1),
490 detail::term_appl_prepend_iterator<FwdIter>(first, &head),
491 detail::term_appl_prepend_iterator<FwdIter>(last),
492 detail::skip_function_application_to_head_assignment(convert_arguments,skip_first_argument)))
493 {
494 assert(first!=last);
496 }
497
499 application(const application&) noexcept = default;
500 application(application&&) noexcept = default;
501 application& operator=(const application&) noexcept = default;
502 application& operator=(application&&) noexcept = default;
503
505 const data_expression& head() const
506 {
507 return atermpp::down_cast<data_expression>(atermpp::aterm::operator[](0));
508 }
509
511 const data_expression& operator[](std::size_t index) const
512 {
513 assert(index<size());
514 return atermpp::down_cast<data_expression>(atermpp::aterm::operator[](index+1));
515 }
516
520 {
521 return atermpp::detail::aterm_appl_iterator_cast<data_expression>(atermpp::aterm::begin()+1);
522 }
523
527 {
528 return atermpp::detail::aterm_appl_iterator_cast<data_expression>(atermpp::aterm::end());
529 }
530
532 std::size_t size() const
533 {
534 return atermpp::aterm::size() - 1;
535 }
536};
537
539inline void swap(application& t1, application& t2)
540{
541 t1.swap(t2);
542}
543
547{
549}
550
551/*
552// ---------------------------------------------------------------------------------
553// ---------------------------- TYPEDEF --------------------------------------------
554// ---------------------------------------------------------------------------------
555template <typename TERM, typename = void>
556struct yields_a_data_expression
557 : public std::false_type
558{
559};
560
561template <typename TERM>
562struct yields_a_data_expression<TERM,
563 typename std::enable_if<std::is_convertible<TERM, data_expression>::type>::type >
564 : public std::true_type
565{}; */
566
569template<typename HEAD, typename TERM, typename ...Terms,
570 typename = std::enable_if_t<
571 std::disjunction<typename std::is_convertible<HEAD, data_expression>,
572 typename std::is_invocable_r<void, HEAD, data_expression&>,
573 typename std::is_invocable_r<const data_expression, HEAD, void> >::value >,
574 typename = std::enable_if_t<std::conjunction_v<
575 std::disjunction<typename std::is_convertible<Terms, data_expression>,
576 typename std::is_invocable_r<void, Terms, data_expression&>,
577 typename std::is_invocable_r<const data_expression, Terms, void> > ...>> >
579 atermpp::aterm& result,
580 const HEAD& head,
581 const TERM& arg1,
582 const Terms& ...other_arguments
583 )
584{
585 assert(detail::check_whether_sorts_match(head, detail::get_arguments(arg1, other_arguments...)));
587 core::detail::function_symbol_DataAppl(sizeof...(Terms)+2),
588 head,
589 arg1,
590 other_arguments...);
591}
592
595template <typename Container>
597 const data_expression& head,
598 const Container& arguments,
600{
601 assert(arguments.size()>0);
602 assert(detail::check_whether_sorts_match(head,arguments));
604 core::detail::function_symbol_DataAppl(arguments.size() + 1),
607}
608
611template <typename FwdIter>
613 const data_expression& head,
614 FwdIter first,
615 FwdIter last,
616 typename std::enable_if< !std::is_base_of<data_expression, FwdIter>::value>::type* = nullptr)
617{
618 assert(first!=last);
620 core::detail::function_symbol_DataAppl(std::distance(first, last) + 1),
624 atermpp::down_cast<application>(result).begin(),
625 atermpp::down_cast<application>(result).end())));
626}
627
630template <typename FwdIter>
632 const std::size_t arity,
633 const data_expression& head,
634 FwdIter first,
635 FwdIter last,
636 typename std::enable_if< !std::is_base_of<data_expression, FwdIter>::value>::type* = 0)
637{
638 assert(arity>0);
639 assert(std::distance(first, last)==arity);
645 atermpp::down_cast<application>(result).begin(),
646 atermpp::down_cast<application>(result).end())));
647}
648
649
659template <typename FwdIter, class ArgumentConverter>
661 const data_expression& head,
662 FwdIter first,
663 FwdIter last,
664 ArgumentConverter convert_arguments,
665 const bool skip_first_argument=false,
666 typename std::enable_if< !std::is_base_of<data_expression, FwdIter>::value>::type* = nullptr,
667 typename std::enable_if< !std::is_base_of<data_expression, ArgumentConverter>::value>::type* = nullptr,
668 typename std::enable_if< std::is_same<typename std::invoke_result<ArgumentConverter,typename FwdIter::value_type>::type, data_expression>::value>::type* = nullptr)
669{
670 assert(first!=last);
672 core::detail::function_symbol_DataAppl(std::distance(first, last) + 1),
675 detail::skip_function_application_to_head(convert_arguments,skip_first_argument));
677 atermpp::down_cast<application>(result).begin(),
678 atermpp::down_cast<application>(result).end())));
679}
680
690template <typename FwdIter, class ArgumentConverter>
691static inline void make_application(
692 atermpp::aterm& result,
693 const data_expression& head,
694 FwdIter first,
695 FwdIter last,
696 ArgumentConverter convert_arguments,
697 const bool skip_first_argument=false,
698 typename std::enable_if< !std::is_base_of<data_expression, FwdIter>::value>::type* = nullptr,
699 typename std::enable_if< !std::is_base_of<data_expression, ArgumentConverter>::value>::type* = nullptr,
700 typename std::enable_if<std::is_same<typename std::invoke_result<ArgumentConverter,data_expression&,typename FwdIter::value_type>::type, void>::value>::type* = nullptr)
701{
703 result,
704 core::detail::function_symbol_DataAppl(std::distance(first, last) + 1),
707 detail::skip_function_application_to_head_assignment(convert_arguments,skip_first_argument));
708}
709
710
711//--- start generated class application ---//
712// prototype declaration
713std::string pp(const application& x);
714
719inline
720std::ostream& operator<<(std::ostream& out, const application& x)
721{
722 return out << data::pp(x);
723}
724//--- end generated class application ---//
725
726inline
728{
729 return x[0];
730}
731
732inline
734{
735 return x[0];
736}
737
738inline
740{
741 return x[1];
742}
743
744inline
746{
747 const application& y = atermpp::down_cast<application>(x);
748 return y[0];
749}
750
751inline
753{
754 const application& y = atermpp::down_cast<application>(x);
755 return y[0];
756}
757
758inline
760{
761 const application& y = atermpp::down_cast<application>(x);
762 return y[1];
763}
764
765} // namespace data
766
767} // namespace mcrl2
768
769#endif // MCRL2_DATA_APPLICATION_H
const_iterator end() const
Returns a const_iterator pointing past the last argument.
Definition aterm.h:172
aterm()
Default constructor.
Definition aterm.h:48
const_iterator begin() const
Returns an iterator pointing to the first argument.
Definition aterm.h:165
size_type size() const
Returns the number of arguments of this term.
Definition aterm.h:151
Iterator for term_appl.
size_type size() const
Returns the size of the term_list.
Definition aterm_list.h:256
const Term & front() const
Returns the first element of the list.
Definition aterm_list.h:239
void push_front(const Term &el)
Inserts a new element at the beginning of the current list.
void swap(unprotected_aterm_core &t) noexcept
Swaps this term with its argument.
Definition aterm_core.h:152
An application of a data expression to a number of arguments.
application(application &&) noexcept=default
const_iterator end() const
Returns an iterator pointing past the last argument of the application.
application(const application &) noexcept=default
Move semantics.
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.
application(const data_expression &head, FwdIter first, FwdIter last, ArgumentConverter convert_arguments, const bool skip_first_argument=false, typename std::enable_if< !std::is_base_of< data_expression, FwdIter >::value >::type *=nullptr, typename std::enable_if< !std::is_base_of< data_expression, ArgumentConverter >::value >::type *=nullptr, typename std::enable_if< std::is_same< typename std::invoke_result< ArgumentConverter, data_expression &, typename FwdIter::value_type >::type, void >::value >::type *=nullptr)
Constructor.
atermpp::term_appl_iterator< data_expression > const_iterator
An iterator to traverse the arguments of an application.
application(const std::size_t arity, const data_expression &head, FwdIter first, FwdIter last, typename std::enable_if< !std::is_base_of< data_expression, FwdIter >::value >::type *=0)
Constructor.
const data_expression & operator[](std::size_t index) const
Get the i-th argument of this expression.
application(const data_expression &head, const Container &arguments, typename atermpp::enable_if_container< Container, data_expression >::type *=nullptr)
Constructor.
application(const atermpp::aterm &term)
Constructor.
application(const data_expression &head, FwdIter first, FwdIter last, typename std::enable_if< !std::is_base_of< data_expression, FwdIter >::value >::type *=nullptr)
Constructor.
application(const data_expression &head, const data_expression &arg1, const Terms &...other_arguments)
Constructor.
application(const data_expression &head, FwdIter first, FwdIter last, ArgumentConverter convert_arguments, const bool skip_first_argument=false, typename std::enable_if< !std::is_base_of< data_expression, FwdIter >::value >::type *=nullptr, typename std::enable_if< !std::is_base_of< data_expression, ArgumentConverter >::value >::type *=nullptr)
Constructor.
std::size_t size() const
application()
Default constructor.
data_expression::iterator iterator
void operator()(data_expression &result, const data_expression &d)
skip_function_application_to_head_assignment(ArgumentConverter &f, const bool skip_head)
data_expression operator()(const data_expression &d)
skip_function_application_to_head(ArgumentConverter &f, const bool skip_head)
prepend_iterator_tag_convertor< traits::iterator_category >::iterator_category iterator_category
Definition application.h:65
term_appl_prepend_iterator(Iterator it, pointer prepend=nullptr)
Definition application.h:87
term_appl_prepend_iterator operator+(difference_type n) const
bool operator!=(const term_appl_prepend_iterator &other) const
term_appl_prepend_iterator & operator--()
term_appl_prepend_iterator(const term_appl_prepend_iterator &other)
Definition application.h:93
difference_type operator-(const term_appl_prepend_iterator &other) const
term_appl_prepend_iterator operator-(difference_type n) const
bool operator<(const term_appl_prepend_iterator &other) const
term_appl_prepend_iterator & operator=(const term_appl_prepend_iterator &other)
reference operator[](difference_type n) const
bool operator<=(const term_appl_prepend_iterator &other) const
term_appl_prepend_iterator & operator++()
bool operator>=(const term_appl_prepend_iterator &other) const
bool operator==(const term_appl_prepend_iterator &other) const
bool operator>(const term_appl_prepend_iterator &other) const
difference_type distance_to(const term_appl_prepend_iterator &other) const
term_appl_prepend_iterator & operator-=(difference_type n)
term_appl_prepend_iterator operator++(int)
term_appl_prepend_iterator & operator--(int)
term_appl_prepend_iterator & operator+=(difference_type n)
\brief A function sort
const sort_expression & codomain() const
const sort_expression_list & domain() const
const sort_expression & sort() const
\brief A sort expression
The main namespace for the aterm++ library.
Definition algorithm.h:21
void make_term_appl(Term &target, const function_symbol &sym, ForwardIterator begin, ForwardIterator end)
Constructor an aterm in a variable based on a function symbol and an forward iterator providing the a...
Definition aterm.h:213
const atermpp::function_symbol & function_symbol_DataAppl(std::size_t i)
bool check_term_DataAppl(const Term &t)
bool contains_untyped_sort(const sort_expression &s)
bool check_whether_sorts_match(const HEAD &head_lambda, const CONTAINER &l)
const data_expression & evaluate_lambda_data_expression(const data_expression &t)
data_expression_list get_arguments()
bool is_structured_sort(const atermpp::aterm &x)
Returns true if the term t is a structured sort.
const data_expression & binary_right(const application &x)
void swap(abstraction &t1, abstraction &t2)
\brief swap overload
const data_expression & arg1(const data_expression &e)
Function for projecting out argument. arg1 from an application.
const data_expression & unary_operand(const application &x)
bool is_untyped_sort(const atermpp::aterm &x)
Returns true if the term t is the unknown sort.
const data_expression & binary_left(const application &x)
std::string pp(const abstraction &x)
Definition data.cpp:39
const data_expression & unary_operand1(const data_expression &x)
bool is_container_sort(const atermpp::aterm &x)
Returns true if the term t is a container sort.
atermpp::term_list< data_expression > data_expression_list
\brief list of data_expressions
bool is_basic_sort(const atermpp::aterm &x)
Returns true if the term t is a basic sort.
const data_expression & binary_right1(const data_expression &x)
bool is_function_sort(const atermpp::aterm &x)
Returns true if the term t is a function sort.
const data_expression & binary_left1(const data_expression &x)
void make_application(atermpp::aterm &result)
Make function for an application.
std::ostream & operator<<(std::ostream &out, const abstraction &x)
Definition abstraction.h:94
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
STL namespace.
The class variable.