mCRL2
Loading...
Searching...
No Matches
type_check_tree.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_DATA_EXPERIMENTAL_TYPE_CHECK_TREE_H
13#define MCRL2_DATA_EXPERIMENTAL_TYPE_CHECK_TREE_H
14
15#include "mcrl2/data/parse.h"
16#include "mcrl2/data/replace.h"
18
19namespace mcrl2 {
20
21namespace data {
22
23typedef std::map<untyped_sort_variable, sort_expression> sort_substitution;
24typedef std::pair<sort_substitution, int> solution; // the second element is the cost of the solution
25
26template <typename T>
27bool has_untyped_sort(const T& x)
28{
30}
31
32template <typename T>
33T replace_untyped_sort(const T& x, const sort_expression& replacement)
34{
35 return data::replace_sort_expressions(x, [&replacement](const sort_expression& x) { return is_untyped_sort(x) ? replacement : x; }, true);
36}
37
38inline
40{
41 return atermpp::down_cast<untyped_sort_variable>(x);
42}
43
45{
47 {
49 auto i = sigma.find(v);
50 if (i != sigma.end())
51 {
52 return i->second;
53 }
54 }
55 return x;
56}
57
58template <typename Container>
59std::string print_node_vector(const std::string& name, const Container& nodes, const std::string& sep = ", ", const std::string& first = "", const std::string& last = "")
60{
61 std::vector<std::string> s;
62 for (auto i = nodes.begin(); i != nodes.end(); ++i)
63 {
64 s.push_back((*i)->print());
65 }
66 std::ostringstream out;
67 out << name << "(" << first;
68 out << utilities::string_join(s, sep);
69 out << last << ")";
70 return out.str();
71}
72
73template <typename Container>
74std::string print_vector(const std::string& name, const Container& nodes)
75{
76 std::ostringstream out;
77 out << name << "(";
78 for (auto i = nodes.begin(); i != nodes.end(); ++i)
79 {
80 if (i != nodes.begin())
81 {
82 out << ", ";
83 }
84 out << *i;
85 }
86 out << ")";
87 return out.str();
88}
89
90struct type_check_node;
91
92typedef std::shared_ptr<type_check_node> type_check_node_ptr;
93
95{
96 std::map<core::identifier_string, sort_expression_list> system_constants;
97 std::map<core::identifier_string, function_sort_list> system_functions;
98 std::map<core::identifier_string, sort_expression> user_constants;
99 std::map<core::identifier_string, function_sort_list> user_functions;
100 std::map<core::identifier_string, std::vector<sort_expression> > declared_variables;
101 mutable std::size_t sort_variable_index;
102
105 {
106 type_checker checker(dataspec);
109 user_constants = checker.user_constants();
110 user_functions = checker.user_functions();
111 }
112
113 // Returns the system defined constants and the user defined constants matching with name
114 std::pair<sort_expression_list, sort_expression_list> find_matching_constants(const std::string& name) const;
115
116 // Returns the system defined functions and the user defined functions matching with (name, arity)
117 // N.B. Untyped sorts are replaced with fresh sort variables.
118 std::pair<function_sort_list, function_sort_list> find_matching_functions(const std::string& name, std::size_t arity) const;
119
120 // Returns the system defined functions and the user defined functions matching with name
121 // N.B. Untyped sorts are replaced with fresh sort variables.
122 std::pair<function_sort_list, function_sort_list> find_matching_functions(const std::string& name) const;
123
124 // Returns the variables matching with name
125 std::vector<sort_expression> find_matching_variables(const std::string& name) const;
126
128 {
130 }
131
133 {
134 declared_variables[v.name()].push_back(v.sort());
135 }
136
138 {
139 for (const variable& v: variables)
140 {
142 }
143 }
144
146 {
147 auto i = declared_variables.find(v.name());
148 if (i->second.size() <= 1)
149 {
150 declared_variables.erase(i);
151 }
152 else
153 {
154 i->second.pop_back();
155 }
156 }
157
159 {
160 for (const variable& v: variables) // N.B. the order of insertion and removal should not matter
161 {
163 }
164 }
165
166protected:
167 // replace occurrences of untyped sort in sorts by fresh sort variables
169 {
170 std::vector<function_sort> result;
171 for (const function_sort& f: sorts)
172 {
173 if (has_untyped_sort(f))
174 {
176 result.push_back(f1);
177 }
178 else
179 {
180 result.push_back(f);
181 }
182 }
183 return function_sort_list(result.begin(), result.end());
184 }
185};
186
187struct type_check_constraint;
188typedef std::shared_ptr<type_check_constraint> constraint_ptr;
190
192{
193 int cost;
194
196 : cost(cost_)
197 {}
198
199 virtual std::string print() const = 0;
200};
201
202constraint_ptr make_and_constraint(const std::vector<constraint_ptr>& alternatives);
203constraint_ptr make_or_constraint(const std::vector<constraint_ptr>& alternatives);
205
207{
210 {}
211
212 std::string print() const override
213 {
214 return "true";
215 }
216};
217
219{
220 std::string message;
221
222 false_constraint(const std::string& message_)
223 : message(message_)
224 {}
225
226 std::string print() const override
227 {
228 return "false(" + message + ")";
229 }
230};
231
232inline
233constraint_ptr make_false_constraint(const std::string& message)
234{
235 return constraint_ptr(new false_constraint(message));
236}
237
238inline
240{
241 return constraint_ptr(new true_constraint(cost));
242}
243
244// The sort of the corresponding data expression should be equal to 'sort'.
246{
248 std::vector<sort_expression> sorts;
249
250 is_element_of_constraint(const untyped_sort_variable& s_, const std::vector<sort_expression>& sorts_, int cost = 0)
251 : type_check_constraint(cost), s(s_), sorts(sorts_)
252 {}
253
254 std::string print() const override
255 {
256 if (sorts.size() == 1)
257 {
258 return data::pp(s) + " = " + data::pp(*sorts.begin());
259 }
260 return data::pp(s) + " in " + core::detail::print_set(sorts);
261 }
262};
263
264inline
266{
267 auto const& domain1 = f1.domain();
268 if (!is_function_sort(s2))
269 {
270 throw mcrl2::runtime_error("could not make function sort constraint");
271 }
272 const function_sort& f2 = atermpp::down_cast<function_sort>(s2);
273 auto const& domain2 = f2.domain();
274 if (domain1.size() != domain1.size())
275 {
276 return make_false_constraint("function sorts do not match");
277 }
278 std::vector<constraint_ptr> alternatives;
279 alternatives.push_back(make_is_equal_to_constraint(f1.codomain(), f2.codomain()));
280 auto i1 = domain1.begin();
281 auto i2 = domain2.begin();
282 for (; i1 != domain1.end(); ++i1, ++i2)
283 {
284 alternatives.push_back(make_is_equal_to_constraint(*i1, *i2));
285 }
286 return make_and_constraint(alternatives);
287}
288
289inline
290constraint_ptr make_is_element_of_constraint(const sort_expression& s, const std::vector<sort_expression>& sorts, int cost = 0)
291{
292 // optimizations
293 if (is_untyped_sort(s))
294 {
295 return make_true_constraint();
296 }
297 if (std::find(sorts.begin(), sorts.end(), untyped_sort()) != sorts.end())
298 {
299 return make_true_constraint();
300 }
301 if (is_function_sort(s))
302 {
303 const function_sort& f1 = atermpp::down_cast<function_sort>(s);
304 std::vector<constraint_ptr> alternatives;
305 for (const sort_expression& s2: sorts)
306 {
307 alternatives.push_back(make_function_sort_constraint(f1, s2));
308 }
309 return make_and_constraint(alternatives);
310 }
311 if (std::find(sorts.begin(), sorts.end(), s) != sorts.end())
312 {
313 return make_true_constraint();
314 }
316}
317
318// The sort of the corresponding data expression should be equal to 'sort'.
320{
323
325 : type_check_constraint(cost), s1(s1_), s2(s2_)
326 {}
327
328 std::string print() const override
329 {
330 return "is_equal_to(" + data::pp(s1) + ", " + data::pp(s2) + ")";
331 }
332};
333
334inline
336 const sort_expression& s2, int /* cost */)
337{
338 if (s1 == s2)
339 {
340 return make_true_constraint();
341 }
342 if (is_untyped_sort(s1) || is_untyped_sort(s2))
343 {
344 return make_true_constraint();
345 }
347 {
348 return make_is_element_of_constraint(s1, { s2 });
349 }
351 {
352 return make_is_element_of_constraint(s2, { s1 });
353 // return constraint_ptr(new is_equal_to_constraint(make_untyped_sort_variable(s2), s1, cost));
354 }
355 throw mcrl2::runtime_error("cannot make is_equal_to constraint");
356}
357
358// The sort variable s1 should be a subsort of s2.
360{
363
365 : type_check_constraint(cost), s1(s1_), s2(s2_)
366 {}
367
368 std::string print() const override
369 {
370 return "subsort(" + data::pp(s1) + ", " + data::pp(s2) + ")";
371 }
372};
373
374inline
376{
377 // optimizations
379 {
380 return make_is_equal_to_constraint(s1, s2, cost);
381 }
382 if (is_untyped_sort(s1) || is_untyped_sort(s2))
383 {
384 return make_true_constraint(cost);
385 }
387 {
388 const container_sort& c1 = atermpp::down_cast<container_sort>(s1);
389 const container_sort& c2 = atermpp::down_cast<container_sort>(s2);
390 if (c1.container_name() == c2.container_name())
391 {
392 return make_subsort_constraint(c1.element_sort(), c2.element_sort());
393 }
394 else
395 {
396 return make_false_constraint("incompatible container sorts");
397 }
398 }
400 {
401 return make_is_equal_to_constraint(s1, s2);
402 }
404 {
405 return make_is_equal_to_constraint(s1, s2);
406 }
407 if (is_function_sort(s1) && is_function_sort(s2))
408 {
409 const function_sort& f1 = atermpp::down_cast<function_sort>(s1);
410 const function_sort& f2 = atermpp::down_cast<function_sort>(s2);
411 auto const& domain1 = f1.domain();
412 auto const& domain2 = f2.domain();
413
414 if (domain1.size() != domain1.size())
415 {
416 return make_false_constraint("function sorts do not match");
417 }
418
419 std::vector<constraint_ptr> alternatives;
420 alternatives.push_back(make_subsort_constraint(f1.codomain(), f2.codomain()));
421 auto i1 = domain1.begin();
422 auto i2 = domain2.begin();
423 for (; i1 != domain1.end(); ++i1, ++i2)
424 {
425 alternatives.push_back(make_subsort_constraint(*i2, *i1));
426 }
427 return make_and_constraint(alternatives);
428 }
429 if (sort_pos::is_pos(s1))
430 {
432 }
433 if (sort_nat::is_nat(s1))
434 {
436 }
437 if (sort_int::is_int(s1))
438 {
440 }
441 if (sort_real::is_real(s1))
442 {
444 }
445 if (sort_pos::is_pos(s2))
446 {
448 }
449 if (sort_nat::is_nat(s2))
450 {
452 }
453 if (sort_int::is_int(s2))
454 {
456 }
457 if (sort_real::is_real(s2))
458 {
460 }
461
462 return constraint_ptr(new subsort_constraint(s1, s2, cost));
463}
464
465// joins disjunctions of is_element_of constraints
466inline
467std::vector<constraint_ptr> join_or_is_element_of_constraints(const std::vector<constraint_ptr>& constraints)
468{
469 std::vector<constraint_ptr> result;
470 std::map<untyped_sort_variable, std::set<sort_expression> > is_element_of_constraints;
471
472 for (const constraint_ptr& p: constraints)
473 {
474 is_element_of_constraint* x_is_element_of = dynamic_cast<is_element_of_constraint*>(p.get());
475 if (x_is_element_of)
476 {
477 is_element_of_constraints[x_is_element_of->s].insert(x_is_element_of->sorts.begin(), x_is_element_of->sorts.end());
478 }
479 else
480 {
481 result.push_back(p);
482 }
483 }
484 for (const auto& i: is_element_of_constraints)
485 {
486 result.push_back(make_is_element_of_constraint(i.first, std::vector<sort_expression>(i.second.begin(), i.second.end())));
487 }
488 return result;
489}
490
492{
493 std::vector<constraint_ptr> alternatives;
494
495 or_constraint(const std::vector<constraint_ptr>& alternatives_)
496 : alternatives(alternatives_)
497 {}
498
499 std::string print() const
500 {
501 return print_node_vector("or", alternatives, "\n ", "\n ", "\n ");
502 }
503};
504
505inline
506constraint_ptr make_or_constraint(const std::vector<constraint_ptr>& alternatives)
507{
508 std::vector<constraint_ptr> v;
509 for (const constraint_ptr& p: alternatives)
510 {
511 true_constraint* x_no = dynamic_cast<true_constraint*>(p.get());
512 if (x_no)
513 {
514 continue;
515 }
516 false_constraint* x_false = dynamic_cast<false_constraint*>(p.get());
517 if (x_false)
518 {
519 continue;
520 }
521 or_constraint* x_or = dynamic_cast<or_constraint*>(p.get());
522 if (x_or)
523 {
524 v.insert(v.end(), x_or->alternatives.begin(), x_or->alternatives.end());
525 continue;
526 }
527 v.push_back(p);
528 }
530 if (v.size() == 0)
531 {
532 return constraint_ptr(new true_constraint());
533 }
534 if (v.size() == 1)
535 {
536 return v.front();
537 }
538 return constraint_ptr(new or_constraint(v));
539}
540
542{
543 std::vector<constraint_ptr> alternatives;
544
545 and_constraint(const std::vector<constraint_ptr>& alternatives_)
546 : alternatives(alternatives_)
547 {}
548
549 std::string print() const override
550 {
551 return print_node_vector("and", alternatives);
552 }
553};
554
555inline
556constraint_ptr make_and_constraint(const std::vector<constraint_ptr>& alternatives)
557{
558 std::vector<constraint_ptr> v;
559 for (constraint_ptr p: alternatives)
560 {
561 false_constraint* x_false = dynamic_cast<false_constraint*>(p.get());
562 if (x_false)
563 {
564 return p;
565 }
566 true_constraint* x_no = dynamic_cast<true_constraint*>(p.get());
567 if (x_no)
568 {
569 continue;
570 }
571 and_constraint* x_and = dynamic_cast<and_constraint*>(p.get());
572 if (x_and)
573 {
574 v.insert(v.end(), x_and->alternatives.begin(), x_and->alternatives.end());
575 continue;
576 }
577 v.push_back(p);
578 }
579 if (v.size() == 0)
580 {
581 return make_true_constraint();
582 }
583 if (v.size() == 1)
584 {
585 return v.front();
586 }
587 return constraint_ptr(new and_constraint(v));
588}
589
591{
593 std::vector<type_check_node_ptr> children;
596
597 type_check_node(type_check_context& context_, const std::vector<type_check_node_ptr>& children_)
598 : context(context_), children(children_), constraint(make_true_constraint())
599 {
601 }
602
603 virtual ~type_check_node() {};
604
605 // Adds a value to the 'sort' attribute
606 // Sets the constraints that apply to this node to 'constraint'
607 virtual void set_constraint(type_check_context& /* context */)
608 {}
609
611 {
612 for (const type_check_node_ptr& child: children)
613 {
614 child->apply_substitution(sigma);
615 }
617 }
618
620 {
621 for (const type_check_node_ptr& child: children)
622 {
623 child->set_constraint(context);
624 }
625 }
626
627 // Throws an exception if the node violates a well typedness rule
628 virtual void check_well_typedness(const type_check_context& /* context */)
629 {}
630
631 virtual std::string print() const = 0;
632};
633
634struct id_node final: public type_check_node
635{
636 std::string value;
637
638 id_node(type_check_context& context, const std::string& value_)
639 : type_check_node(context, {}), value(value_)
640 {}
641
643 {
644 std::vector<constraint_ptr> alternatives;
645
646 // it is a variable
647 std::vector<sort_expression> variable_sorts = context.find_matching_variables(value);
648 if (variable_sorts.size() == 1)
649 {
650 alternatives.push_back(make_is_equal_to_constraint(sort, variable_sorts.front()));
651 }
652
653 // it is a constant
654 std::pair<sort_expression_list, sort_expression_list> p = context.find_matching_constants(value);
655 for (const sort_expression& s: p.first + p.second)
656 {
657 alternatives.push_back(make_is_equal_to_constraint(sort, s));
658 }
659
660 // it is a function
661 std::pair<function_sort_list, function_sort_list> q = context.find_matching_functions(value);
662 for (const function_sort& s: q.first + q.second)
663 {
664 alternatives.push_back(make_is_equal_to_constraint(sort, s));
665 }
666
667 if (alternatives.empty())
668 {
669 constraint = make_false_constraint("The id " + value + " is not declared!");
670 }
671 else
672 {
673 constraint = make_or_constraint(alternatives);
674 }
675 }
676
677 std::string print() const override
678 {
679 return "id(" + value + ")";
680 }
681};
682
683struct number_node final: public type_check_node
684{
685 std::string value;
686
687 number_node(type_check_context& context, const std::string& value_)
688 : type_check_node(context, {}), value(value_)
689 {}
690
691 void set_constraint(type_check_context& /* context */) override
692 {
694 {
696 }
697 else if (detail::is_nat(value))
698 {
700 }
701 else
702 {
703 throw mcrl2::runtime_error("unknown numeric string " + value);
704 }
705 }
706
707 std::string print() const override
708 {
709 return "number(" + value + ")";
710 }
711};
712
714{
715 std::string name;
716
717 constant_node(type_check_context& context, const std::string& name_)
718 : type_check_node(context, {}), name(name_)
719 {}
720
721 virtual ~constant_node() {}
722
724 {
725 std::pair<sort_expression_list, sort_expression_list> p = context.find_matching_constants(name);
726 std::vector<constraint_ptr> alternatives;
727 for (const sort_expression& s: p.first + p.second)
728 {
729 alternatives.push_back(make_subsort_constraint(s, sort));
730 }
731 constraint = make_or_constraint(alternatives);
733 }
734
735 std::string print() const override
736 {
737 return "constant(" + name + ")";
738 }
739};
740
741struct true_node final: public constant_node
742{
744 : constant_node(context, "true")
745 { }
746};
747
748struct false_node final: public constant_node
749{
751 : constant_node(context, "false")
752 { }
753};
754
755struct empty_list_node final: public constant_node
756{
758 : constant_node(context, "[]")
759 { }
760
762 {
763 auto element_sort = context.create_sort_variable();
765 }
766};
767
768struct empty_set_node final: public constant_node
769{
771 : constant_node(context, "{}")
772 { }
773
775 {
776 auto element_sort = context.create_sort_variable();
778 }
779};
780
781struct empty_bag_node final: public constant_node
782{
784 : constant_node(context, "{:}")
785 { }
786
788 {
789 auto element_sort = context.create_sort_variable();
791 }
792};
793
795{
796 list_enumeration_node(type_check_context& context, const std::vector<type_check_node_ptr>& children)
798 {}
799
801 {
802 auto element_sort = context.create_sort_variable();
804
805 std::vector<constraint_ptr> alternatives;
806 alternatives.push_back(make_is_equal_to_constraint(sort, sort_list::list(element_sort)));
807 for (const type_check_node_ptr& child: children)
808 {
809 alternatives.push_back(make_subsort_constraint(element_sort, child->sort));
810 }
811 constraint = make_and_constraint(alternatives);
812 }
813
814 std::string print() const override
815 {
816 return print_node_vector("list_enumeration", children);
817 }
818};
819
821{
822 bag_enumeration_node(type_check_context& context, const std::vector<type_check_node_ptr>& children)
824 {}
825
827 {
828 auto element_sort = context.create_sort_variable();
830
831 std::vector<constraint_ptr> alternatives;
832 alternatives.push_back(make_is_equal_to_constraint(sort, sort_bag::bag(element_sort)));
833 for (std::size_t i = 0; i < children.size(); i++)
834 {
835 if (i % 2 == 0)
836 {
837 alternatives.push_back(make_subsort_constraint(element_sort, children[i]->sort));
838 }
839 else
840 {
841 alternatives.push_back(make_subsort_constraint(sort_nat::nat(), children[i]->sort));
842 }
843 }
844 constraint = make_and_constraint(alternatives);
845 }
846
847 std::string print() const override
848 {
849 return print_node_vector("bag_enumeration", children);
850 }
851};
852
854{
855 set_enumeration_node(type_check_context& context, const std::vector<type_check_node_ptr>& children)
857 {}
858
860 {
861 auto element_sort = context.create_sort_variable();
863
864 std::vector<constraint_ptr> alternatives;
865 alternatives.push_back(make_is_equal_to_constraint(sort, sort_set::set_(element_sort)));
866 for (const type_check_node_ptr& child: children)
867 {
868 alternatives.push_back(make_subsort_constraint(element_sort, child->sort));
869 }
870 constraint = make_and_constraint(alternatives);
871 }
872
873 std::string print() const override
874 {
875 return print_node_vector("set_enumeration", children);
876 }
877};
878
880{
882
884 : type_check_node(context, {}), v(v_)
885 {
886 children.push_back(x);
887 }
888
890 {
893
894 auto element_sort = v.sort();
898 });
899 constraint_ptr bag_constraint = make_and_constraint({
902 });
903 constraint = make_or_constraint({ set_constraint, bag_constraint });
905 }
906
907 std::string print() const override
908 {
909 return print_node_vector("bag_or_set_enumeration", children);
910 }
911};
912
914{
917 {
918 children.push_back(x1);
919 children.push_back(x2);
920 children.push_back(x3);
921 }
922
923 std::string print() const override
924 {
925 return print_node_vector("function_update", children);
926 }
927};
928
930{
931 std::size_t arity;
932
933 application_node(type_check_context& context, type_check_node_ptr head, const std::vector<type_check_node_ptr>& arguments)
934 : type_check_node(context, {}), arity(arguments.size())
935 {
936 children.push_back(head);
937 for (const auto& arg: arguments)
938 {
939 children.push_back(arg);
940 }
941 }
942
944 {
946
947 const sort_expression& codomain = sort;
948 std::vector<constraint_ptr> alternatives;
949 std::vector<sort_expression> domain;
950 for (std::size_t i = 0; i < arity; i++)
951 {
952 domain.push_back(children[i+1]->sort);
953 }
954 alternatives.push_back(make_is_equal_to_constraint(children[0]->sort, function_sort(sort_expression_list(domain.begin(), domain.end()), codomain)));
955
956 // add missing constraints for if application
957 // TODO: handle this in a more structured way
958 if (children[0]->print() == "id(if)")
959 {
960 alternatives.push_back(make_subsort_constraint(codomain, children[1]->sort));
961 alternatives.push_back(make_subsort_constraint(codomain, children[2]->sort));
962 }
963
964 constraint = make_and_constraint(alternatives);
965 }
966
967 std::string print() const override
968 {
969 return print_node_vector("application", children);
970 }
971};
972
974{
975 std::string name;
976
978 : type_check_node(context, { arg }), name(name_)
979 {}
980
982
984 {
986
987 std::pair<function_sort_list, function_sort_list> p = context.find_matching_functions(name, 1);
988 std::vector<constraint_ptr> alternatives;
989 for (const function_sort& s: p.first + p.second)
990 {
991 alternatives.push_back(make_and_constraint({
992 make_subsort_constraint(children[0]->sort, s.domain().front()),
993 make_subsort_constraint(s.codomain(), sort)
994 })
995 );
996 }
997 constraint = make_or_constraint(alternatives);
998 }
999
1000 std::string print() const override
1001 {
1002 std::ostringstream out;
1003 out << "unary_operator(" << name << ", " << children.front()->print() << ")";
1004 return out.str();
1005 }
1006};
1007
1008struct forall_node final: public type_check_node
1009{
1011
1013 : type_check_node(context, { arg }), variables(variables_)
1014 {}
1015
1017 {
1020
1023 }
1024
1025 std::string print() const override
1026 {
1027 std::ostringstream out;
1028 out << "forall(" << data::pp(variables) << ". " << children.front()->print() << ")";
1029 return out.str();
1030 }
1031};
1032
1033struct exists_node final: public type_check_node
1034{
1036
1038 : type_check_node(context, { arg }), variables(variables_)
1039 {}
1040
1042 {
1045
1048 }
1049
1050 std::string print() const override
1051 {
1052 std::ostringstream out;
1053 out << "exists(" << data::pp(variables) << ". " << children.front()->print() << ")";
1054 return out.str();
1055 }
1056};
1057
1059{
1061
1063 : unary_operator_node(context, "lambda", arg), variables(variables_)
1064 {}
1065
1067 {
1070
1073 }
1074
1075 std::string print() const override
1076 {
1077 std::ostringstream out;
1078 out << "lambda(" << data::pp(variables) << ". " << children.front()->print() << ")";
1079 return out.str();
1080 }
1081};
1082
1084{
1085 std::string name;
1086
1088 : type_check_node(context, { left, right }), name(name_)
1089 {}
1090
1092 {
1094
1095 std::pair<function_sort_list, function_sort_list> p = context.find_matching_functions(name, 2);
1096 std::vector<constraint_ptr> alternatives;
1097 for (const function_sort& s: p.first + p.second)
1098 {
1099 auto i = s.domain().begin();
1100 const sort_expression& left = *i++;
1101 const sort_expression& right = *i;
1102 alternatives.push_back(make_and_constraint({
1105 make_subsort_constraint(s.codomain(), sort)
1106 })
1107 );
1108 }
1109 constraint = make_or_constraint(alternatives);
1110 }
1111
1112 std::string print() const override
1113 {
1114 std::ostringstream out;
1115 out << "binary_operator(" << name << ", " << children[0]->print() << ", " << children[1]->print() << ")";
1116 return out.str();
1117 }
1118};
1119
1121{
1122 std::vector<variable> variables;
1123
1124 where_clause_node(type_check_context& context, type_check_node_ptr body, const std::vector<std::pair<std::string, type_check_node_ptr> >& assignments)
1126 {
1127 children.push_back(body);
1128 for (const std::pair<std::string, type_check_node_ptr>& a: assignments)
1129 {
1130 children.push_back(a.second);
1131 variables.push_back(variable(a.first, a.second->sort));
1132 }
1133 }
1134
1136 {
1137 variable_list v(variables.begin(), variables.end());
1141
1142 std::vector<constraint_ptr> constraints;
1143 constraints.push_back(make_is_equal_to_constraint(sort, children[0]->sort));
1144 auto i = variables.begin();
1145 auto j = ++children.begin();
1146 for (; i != variables.end(); ++i, ++j)
1147 {
1148 constraints.push_back(make_is_equal_to_constraint((*j)->sort, i->sort()));
1149 }
1150 constraint = make_and_constraint(constraints);
1151 }
1152
1153 std::string print() const override
1154 {
1155 std::ostringstream out;
1156 return print_node_vector("where_clause", children);
1157 return out.str();
1158 }
1159};
1160
1162{
1164
1166 : data_expression_actions(parser_), context(context_)
1167 {}
1168
1169 std::vector<type_check_node_ptr> parse_DataExprList(const core::parse_node& node) const
1170 {
1171 return parse_vector<type_check_node_ptr>(node, "DataExpr", [&](const core::parse_node& node) { return parse_DataExpr(node); });
1172 }
1173
1174 std::vector<type_check_node_ptr> parse_BagEnumEltList(const core::parse_node& node) const
1175 {
1176 return parse_DataExprList(node);
1177 }
1178
1179 std::pair<std::string, type_check_node_ptr> parse_Assignment(const core::parse_node& node) const
1180 {
1181 return std::make_pair(parse_Id(node.child(0)), parse_DataExpr(node.child(2)));
1182 }
1183
1184 std::vector<std::pair<std::string, type_check_node_ptr> > parse_AssignmentList(const core::parse_node& node) const
1185 {
1186 return parse_vector<std::pair<std::string, type_check_node_ptr> >(node, "Assignment", [&](const core::parse_node& node) { return parse_Assignment(node); });
1187 }
1188
1190 {
1191 assert(symbol_name(node) == "DataExpr");
1192 if ((node.child_count() == 1) && (symbol_name(node.child(0)) == "Id")) { return type_check_node_ptr(new id_node(context, parse_Id(node.child(0)))); }
1193 else if ((node.child_count() == 1) && (symbol_name(node.child(0)) == "Number")) { return type_check_node_ptr(new number_node(context, parse_Number(node.child(0)))); }
1194 else if ((node.child_count() == 1) && (symbol_name(node.child(0)) == "true")) { return type_check_node_ptr(new true_node(context)); }
1195 else if ((node.child_count() == 1) && (symbol_name(node.child(0)) == "false")) { return type_check_node_ptr(new false_node(context)); }
1196 else if ((node.child_count() == 2) && (symbol_name(node.child(0)) == "[") && (symbol_name(node.child(1)) == "]")) { return type_check_node_ptr(new empty_list_node(context)); }
1197 else if ((node.child_count() == 2) && (symbol_name(node.child(0)) == "{") && (symbol_name(node.child(1)) == "}")) { return type_check_node_ptr(new empty_set_node(context)); }
1198 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "{") && (symbol_name(node.child(1)) == ":") && (symbol_name(node.child(2)) == "}")) { return type_check_node_ptr(new empty_bag_node(context)); }
1199 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "[") && (symbol_name(node.child(1)) == "DataExprList") && (symbol_name(node.child(2)) == "]")) { return type_check_node_ptr(new list_enumeration_node(context, parse_DataExprList(node.child(1)))); }
1200 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "{") && (symbol_name(node.child(1)) == "BagEnumEltList") && (symbol_name(node.child(2)) == "}")) { return type_check_node_ptr(new bag_enumeration_node(context, parse_BagEnumEltList(node.child(1)))); }
1201 else if ((node.child_count() == 5) && (symbol_name(node.child(0)) == "{") && (symbol_name(node.child(1)) == "VarDecl") && (symbol_name(node.child(2)) == "|") && (symbol_name(node.child(3)) == "DataExpr") && (symbol_name(node.child(4)) == "}")) { return type_check_node_ptr(new bag_or_set_enumeration_node(context, parse_VarDecl(node.child(1)), parse_DataExpr(node.child(3)))); }
1202 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "{") && (symbol_name(node.child(1)) == "DataExprList") && (symbol_name(node.child(2)) == "}")) { return type_check_node_ptr(new set_enumeration_node(context, parse_DataExprList(node.child(1)))); }
1203 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "(") && (symbol_name(node.child(1)) == "DataExpr") && (symbol_name(node.child(2)) == ")")) { return parse_DataExpr(node.child(1)); }
1204 else if ((node.child_count() == 6) && (symbol_name(node.child(0)) == "DataExpr") && (symbol_name(node.child(1)) == "[") && (symbol_name(node.child(2)) == "DataExpr") && (symbol_name(node.child(3)) == "->") && (symbol_name(node.child(4)) == "DataExpr") && (symbol_name(node.child(5)) == "]")) { return type_check_node_ptr(new function_update_node(context, parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)), parse_DataExpr(node.child(4)))); }
1205 else if ((node.child_count() == 4) && (symbol_name(node.child(0)) == "DataExpr") && (symbol_name(node.child(1)) == "(") && (symbol_name(node.child(2)) == "DataExprList") && (symbol_name(node.child(3)) == ")")) { return type_check_node_ptr(new application_node(context, parse_DataExpr(node.child(0)), parse_DataExprList(node.child(2)))); }
1206 else if ((node.child_count() == 2) && (symbol_name(node.child(0)) == "!") && (symbol_name(node.child(1)) == "DataExpr")) { return type_check_node_ptr(new unary_operator_node(context, "!", parse_DataExpr(node.child(1)))); }
1207 else if ((node.child_count() == 2) && (symbol_name(node.child(0)) == "-") && (symbol_name(node.child(1)) == "DataExpr")) { return type_check_node_ptr(new unary_operator_node(context, "-", parse_DataExpr(node.child(1)))); }
1208 else if ((node.child_count() == 2) && (symbol_name(node.child(0)) == "#") && (symbol_name(node.child(1)) == "DataExpr")) { return type_check_node_ptr(new unary_operator_node(context, "#", parse_DataExpr(node.child(1)))); }
1209 else if ((node.child_count() == 4) && (symbol_name(node.child(0)) == "forall") && (symbol_name(node.child(1)) == "VarsDeclList") && (symbol_name(node.child(2)) == ".") && (symbol_name(node.child(3)) == "DataExpr")) { return type_check_node_ptr(new forall_node(context, parse_VarsDeclList(node.child(1)), parse_DataExpr(node.child(3)))); }
1210 else if ((node.child_count() == 4) && (symbol_name(node.child(0)) == "exists") && (symbol_name(node.child(1)) == "VarsDeclList") && (symbol_name(node.child(2)) == ".") && (symbol_name(node.child(3)) == "DataExpr")) { return type_check_node_ptr(new exists_node(context, parse_VarsDeclList(node.child(1)), parse_DataExpr(node.child(3)))); }
1211 else if ((node.child_count() == 4) && (symbol_name(node.child(0)) == "lambda") && (symbol_name(node.child(1)) == "VarsDeclList") && (symbol_name(node.child(2)) == ".") && (symbol_name(node.child(3)) == "DataExpr")) { return type_check_node_ptr(new lambda_node(context, parse_VarsDeclList(node.child(1)), parse_DataExpr(node.child(3)))); }
1212 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "=>" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "=>" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1213 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "&&" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "&&" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1214 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "||" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "||" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1215 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "==" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "==" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1216 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "!=" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "!=" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1217 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "<" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "<" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1218 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "<=" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "<=" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1219 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == ">=" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, ">=" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1220 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == ">" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, ">" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1221 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "in" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "in" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1222 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "|>" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "|>" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1223 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "<|" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "<|" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1224 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "++" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "++" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1225 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "+" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "+" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1226 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "-" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "-" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1227 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "/" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "/" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1228 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "div") && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "div", parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1229 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "mod") && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "mod", parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1230 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "*" ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "*" , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1231 else if ((node.child_count() == 3) && (symbol_name(node.child(0)) == "DataExpr") && (node.child(1).string() == "." ) && (symbol_name(node.child(2)) == "DataExpr")) { return type_check_node_ptr(new binary_operator_node(context, "." , parse_DataExpr(node.child(0)), parse_DataExpr(node.child(2)))); }
1232 else if ((node.child_count() == 4) && (symbol_name(node.child(0)) == "DataExpr") && (symbol_name(node.child(1)) == "whr") && (symbol_name(node.child(2)) == "AssignmentList") && (symbol_name(node.child(3)) == "end")) { return type_check_node_ptr(new where_clause_node(context, { parse_DataExpr(node.child(0)) }, parse_AssignmentList(node.child(2)))); }
1234 }
1235};
1236
1237inline
1238std::pair<sort_expression_list, sort_expression_list> type_check_context::find_matching_constants(const std::string& name) const
1239{
1240 sort_expression_list system_result;
1241 sort_expression_list user_result;
1242 auto i = system_constants.find(core::identifier_string(name));
1243 if (i != system_constants.end())
1244 {
1245 system_result = i->second;
1246 }
1247 auto j = user_constants.find(core::identifier_string(name));
1248 if (j != user_constants.end())
1249 {
1250 user_result = { j->second };
1251 }
1252 return std::make_pair(system_result, user_result);
1253}
1254
1255inline
1257{
1258 std::vector<function_sort> result;
1259 for (const function_sort& sort: sorts)
1260 {
1261 if (sort.domain().size() == arity)
1262 {
1263 result.push_back(sort);
1264 }
1265 }
1266 return function_sort_list(result.begin(), result.end());
1267}
1268
1269inline
1270std::pair<function_sort_list, function_sort_list> type_check_context::find_matching_functions(const std::string& name, std::size_t arity) const
1271{
1272 function_sort_list system_result;
1273 function_sort_list user_result;
1274 auto i = system_functions.find(core::identifier_string(name));
1275 if (i != system_functions.end())
1276 {
1277 system_result = filter_sorts(i->second, arity);
1278 }
1279 auto j = user_functions.find(core::identifier_string(name));
1280 if (j != user_functions.end())
1281 {
1282 user_result = filter_sorts(j->second, arity);
1283 }
1284 return { replace_untyped_sorts(system_result), user_result };
1285}
1286
1287inline
1288std::pair<function_sort_list, function_sort_list> type_check_context::find_matching_functions(const std::string& name) const
1289{
1290 function_sort_list system_result;
1291 function_sort_list user_result;
1292 auto i = system_functions.find(core::identifier_string(name));
1293 if (i != system_functions.end())
1294 {
1295 system_result = i->second;
1296 }
1297 auto j = user_functions.find(core::identifier_string(name));
1298 if (j != user_functions.end())
1299 {
1300 user_result = j->second;
1301 }
1302 return { replace_untyped_sorts(system_result), user_result };
1303}
1304
1305inline
1306std::vector<sort_expression> type_check_context::find_matching_variables(const std::string& name) const
1307{
1308 std::vector<sort_expression> result;
1309 auto i = declared_variables.find(core::identifier_string(name));
1310 if (i != declared_variables.end())
1311 {
1312 result.push_back(i->second.back());
1313 }
1314 return result;
1315}
1316
1317inline
1319{
1320 std::cout << "\nnode = " << node->print() << std::endl;
1321 std::cout << "sort = " << node->sort << std::endl;
1322 std::cout << "constraint = " << node->constraint->print() << std::endl;
1323 for (const type_check_node_ptr& child: node->children)
1324 {
1325 print_node(child);
1326 }
1327}
1328
1329// TODO: This design is ugly, but for the moment it seems the easiest solution to modify
1330// the constraint tree
1331inline
1333{
1334 {
1335 or_constraint* x = dynamic_cast<or_constraint*>(p.get());
1336 if (x)
1337 {
1338 for (constraint_ptr& q: x->alternatives)
1339 {
1341 }
1342 return p;
1343 }
1344 }
1345 {
1346 and_constraint* x = dynamic_cast<and_constraint*>(p.get());
1347 if (x)
1348 {
1349 for (constraint_ptr& q: x->alternatives)
1350 {
1352 }
1353 return p;
1354 }
1355 }
1356 {
1357 is_equal_to_constraint* x = dynamic_cast<is_equal_to_constraint*>(p.get());
1358 if (x)
1359 {
1362 return make_is_equal_to_constraint(s1, s2);
1363 }
1364 }
1365 return p;
1366}
1367
1368} // namespace data
1369
1370} // namespace mcrl2
1371
1372#endif // MCRL2_DATA_EXPERIMENTAL_TYPE_CHECK_TREE_H
Term containing a string.
\brief A container sort
const container_type & container_name() const
const sort_expression & element_sort() const
\brief A function sort
const sort_expression & codomain() const
const sort_expression_list & domain() const
\brief A sort expression
const std::map< core::identifier_string, sort_expression > & user_constants() const
const std::map< core::identifier_string, sort_expression_list > & system_constants() const
const std::map< core::identifier_string, function_sort_list > & user_functions() const
const std::map< core::identifier_string, function_sort_list > & system_functions() const
\brief Unknown sort expression
\brief A data variable
Definition variable.h:28
const core::identifier_string & name() const
Definition variable.h:38
const sort_expression & sort() const
Definition variable.h:43
Standard exception class for reporting runtime errors.
Definition exception.h:27
Parser for data specifications.
add your file description here.
static RewriterCompilingJitty::substitution_type & sigma(RewriterCompilingJitty *this_rewriter)
std::string print_set(const Container &v, const std::string &message="", bool print_index=false, bool boundary_spaces=true)
Creates a string representation of a container.
bool is_nat(const core::identifier_string &Number)
bool is_pos(const core::identifier_string &Number)
container_sort bag(const sort_expression &s)
Constructor for sort expression Bag(S)
Definition bag1.h:44
bool is_bool(const sort_expression &e)
Recogniser for sort expression Bool.
Definition bool.h:54
const basic_sort & bool_()
Constructor for sort expression Bool.
Definition bool.h:44
bool is_int(const sort_expression &e)
Recogniser for sort expression Int.
Definition int1.h:57
const basic_sort & int_()
Constructor for sort expression Int.
Definition int1.h:47
container_sort list(const sort_expression &s)
Constructor for sort expression List(S)
Definition list1.h:42
const basic_sort & nat()
Constructor for sort expression Nat.
Definition nat1.h:46
bool is_nat(const sort_expression &e)
Recogniser for sort expression Nat.
Definition nat1.h:56
bool is_pos(const sort_expression &e)
Recogniser for sort expression Pos.
Definition pos1.h:55
const basic_sort & pos()
Constructor for sort expression Pos.
Definition pos1.h:45
const basic_sort & real_()
Constructor for sort expression Real.
Definition real1.h:48
bool is_real(const sort_expression &e)
Recogniser for sort expression Real.
Definition real1.h:58
container_sort set_(const sort_expression &s)
Constructor for sort expression Set(S)
Definition set1.h:42
atermpp::term_list< function_sort > function_sort_list
list of function sorts
const untyped_sort_variable & make_untyped_sort_variable(const sort_expression &x)
std::pair< sort_substitution, int > solution
bool has_untyped_sort(const T &x)
constraint_ptr substitute_constraint(constraint_ptr p, const sort_substitution &sigma)
constraint_ptr make_is_element_of_constraint(const sort_expression &s, const std::vector< sort_expression > &sorts, int cost=0)
bool is_untyped_sort(const atermpp::aterm &x)
Returns true if the term t is the unknown sort.
sort_expression substitute(const sort_expression &x, const sort_substitution &sigma)
void print_node(const type_check_node_ptr &node)
constraint_ptr make_true_constraint(int cost=0)
T replace_untyped_sort(const T &x, const sort_expression &replacement)
std::string print_node_vector(const std::string &name, const Container &nodes, const std::string &sep=", ", const std::string &first="", const std::string &last="")
constraint_ptr make_subsort_constraint(const sort_expression &s1, const sort_expression &s2, int cost=0)
atermpp::term_list< sort_expression > sort_expression_list
\brief list of sort_expressions
std::map< untyped_sort_variable, sort_expression > sort_substitution
std::string pp(const abstraction &x)
Definition data.cpp:39
void replace_sort_expressions(T &x, const Substitution &sigma, bool innermost, typename std::enable_if<!std::is_base_of< atermpp::aterm, T >::value >::type *=nullptr)
Definition replace.h:168
bool search_sort_expression(Container const &container, const sort_expression &s)
Returns true if the term has a given sort expression as subterm.
Definition find.h:468
constraint_ptr make_false_constraint(const std::string &message)
constraint_ptr make_or_constraint(const std::vector< constraint_ptr > &alternatives)
std::shared_ptr< type_check_node > type_check_node_ptr
bool is_container_sort(const atermpp::aterm &x)
Returns true if the term t is a container sort.
function_sort_list filter_sorts(const function_sort_list &sorts, std::size_t arity)
constraint_ptr make_and_constraint(const std::vector< constraint_ptr > &alternatives)
bool is_untyped_sort_variable(const atermpp::aterm &x)
constraint_ptr make_is_equal_to_constraint(const sort_expression &s1, const sort_expression &s2, int cost=0)
std::string print_vector(const std::string &name, const Container &nodes)
constraint_ptr make_function_sort_constraint(const function_sort &f1, const sort_expression &s2)
bool is_function_sort(const atermpp::aterm &x)
Returns true if the term t is a function sort.
std::vector< constraint_ptr > join_or_is_element_of_constraints(const std::vector< constraint_ptr > &constraints)
std::shared_ptr< type_check_constraint > constraint_ptr
std::string string_join(const Container &c, const std::string &separator)
Joins a sequence of strings. This is a replacement for boost::algorithm::join, since it gives stack o...
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
core::identifier_string parse_Id(const parse_node &node) const
Definition parse.h:233
core::identifier_string parse_Number(const parse_node &node) const
Definition parse.h:238
Wrapper for D_ParseNode.
Definition dparser.h:86
parse_node child(int i) const
Definition dparser.cpp:43
int child_count() const
Definition dparser.cpp:37
std::string string() const
Definition dparser.cpp:53
std::string symbol_name(const parse_node &node) const
Definition parse.h:205
const parser & m_parser
Definition parse.h:85
Wrapper for D_Parser and its corresponding D_ParserTables.
Definition dparser.h:148
std::string print() const override
and_constraint(const std::vector< constraint_ptr > &alternatives_)
std::vector< constraint_ptr > alternatives
void set_constraint(type_check_context &context) override
application_node(type_check_context &context, type_check_node_ptr head, const std::vector< type_check_node_ptr > &arguments)
std::string print() const override
std::string print() const override
void set_constraint(type_check_context &context) override
bag_enumeration_node(type_check_context &context, const std::vector< type_check_node_ptr > &children)
void set_constraint(type_check_context &context) override
bag_or_set_enumeration_node(type_check_context &context, const variable &v_, type_check_node_ptr x)
void set_constraint(type_check_context &context) override
binary_operator_node(type_check_context &context, const std::string &name_, type_check_node_ptr left, type_check_node_ptr right)
std::string print() const override
constant_node(type_check_context &context, const std::string &name_)
std::string print() const override
void set_constraint(type_check_context &context) override
data::variable_list parse_VarsDeclList(const core::parse_node &node) const
Definition parse_impl.h:204
data_expression_actions(const core::parser &parser_)
Definition parse_impl.h:141
data::variable parse_VarDecl(const core::parse_node &node) const
Definition parse_impl.h:184
empty_bag_node(type_check_context &context)
void set_constraint(type_check_context &context) override
void set_constraint(type_check_context &context) override
empty_list_node(type_check_context &context)
empty_set_node(type_check_context &context)
void set_constraint(type_check_context &context) override
std::string print() const override
void set_constraint(type_check_context &context) override
exists_node(type_check_context &context, const variable_list &variables_, type_check_node_ptr arg)
std::string print() const override
false_constraint(const std::string &message_)
false_node(type_check_context &context)
forall_node(type_check_context &context, const variable_list &variables_, type_check_node_ptr arg)
std::string print() const override
void set_constraint(type_check_context &context) override
function_update_node(type_check_context &context, type_check_node_ptr x1, type_check_node_ptr x2, type_check_node_ptr x3)
std::string print() const override
id_node(type_check_context &context, const std::string &value_)
std::string print() const override
void set_constraint(type_check_context &context) override
std::string print() const override
std::vector< sort_expression > sorts
is_element_of_constraint(const untyped_sort_variable &s_, const std::vector< sort_expression > &sorts_, int cost=0)
is_equal_to_constraint(const untyped_sort_variable &s1_, const sort_expression &s2_, int cost=0)
std::string print() const override
void set_constraint(type_check_context &context) override
std::string print() const override
lambda_node(type_check_context &context, const variable_list &variables_, type_check_node_ptr arg)
list_enumeration_node(type_check_context &context, const std::vector< type_check_node_ptr > &children)
void set_constraint(type_check_context &context) override
std::string print() const override
void set_constraint(type_check_context &) override
number_node(type_check_context &context, const std::string &value_)
std::string print() const override
std::string print() const
or_constraint(const std::vector< constraint_ptr > &alternatives_)
std::vector< constraint_ptr > alternatives
std::string print() const override
set_enumeration_node(type_check_context &context, const std::vector< type_check_node_ptr > &children)
void set_constraint(type_check_context &context) override
subsort_constraint(const sort_expression &s1_, const sort_expression &s2_, int cost=0)
std::string print() const override
std::string print() const override
true_node(type_check_context &context)
virtual std::string print() const =0
void add_context_variable(const variable &v)
std::map< core::identifier_string, std::vector< sort_expression > > declared_variables
void remove_context_variables(const variable_list &variables)
void add_context_variables(const variable_list &variables)
std::pair< sort_expression_list, sort_expression_list > find_matching_constants(const std::string &name) const
std::map< core::identifier_string, sort_expression > user_constants
void remove_context_variable(const variable &v)
std::vector< sort_expression > find_matching_variables(const std::string &name) const
function_sort_list replace_untyped_sorts(const function_sort_list &sorts) const
untyped_sort_variable create_sort_variable() const
std::pair< function_sort_list, function_sort_list > find_matching_functions(const std::string &name, std::size_t arity) const
std::map< core::identifier_string, function_sort_list > user_functions
type_check_context(const data::data_specification &dataspec=data::data_specification())
std::map< core::identifier_string, sort_expression_list > system_constants
std::map< core::identifier_string, function_sort_list > system_functions
virtual void set_constraint(type_check_context &)
std::vector< type_check_node_ptr > children
virtual std::string print() const =0
untyped_sort_variable sort
virtual void apply_substitution(const sort_substitution &sigma)
virtual void check_well_typedness(const type_check_context &)
void set_children_constraints(type_check_context &context)
type_check_context & context
type_check_node(type_check_context &context_, const std::vector< type_check_node_ptr > &children_)
type_check_node_ptr parse_DataExpr(const core::parse_node &node) const
std::vector< std::pair< std::string, type_check_node_ptr > > parse_AssignmentList(const core::parse_node &node) const
type_check_tree_generator(type_check_context &context_, const core::parser &parser_)
std::vector< type_check_node_ptr > parse_DataExprList(const core::parse_node &node) const
std::pair< std::string, type_check_node_ptr > parse_Assignment(const core::parse_node &node) const
std::vector< type_check_node_ptr > parse_BagEnumEltList(const core::parse_node &node) const
unary_operator_node(type_check_context &context, const std::string &name_, type_check_node_ptr arg)
std::string print() const override
void set_constraint(type_check_context &context) override
std::vector< variable > variables
where_clause_node(type_check_context &context, type_check_node_ptr body, const std::vector< std::pair< std::string, type_check_node_ptr > > &assignments)
std::string print() const override
void set_constraint(type_check_context &context) override
add your file description here.