mCRL2
Loading...
Searching...
No Matches
absinthe.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_PBES_ABSINTHE_H
13#define MCRL2_PBES_ABSINTHE_H
14
15#define MCRL2_ABSINTHE_CHECK_EXPRESSIONS
16
19#include "mcrl2/pbes/builder.h"
21
22#ifdef MCRL2_ABSINTHE_CHECK_EXPRESSIONS
24#endif
25
26namespace mcrl2 {
27
28namespace pbes_system {
29
30 template <typename Term>
31 std::string print_term(const Term& x)
32 {
33 return data::pp(x) + " " + data::pp(x);
34 }
35
36 template <typename Term>
37 std::string print_symbol(const Term& x)
38 {
39 return data::pp(x) + ": " + data::pp(x.sort());
40 }
41
42namespace detail {
43
44 inline
46 {
47 static data::data_specification dataspec;
48 return dataspec;
49 }
50
51#ifdef MCRL2_ABSINTHE_CHECK_EXPRESSIONS
52 template <typename T>
53 inline void absinthe_check_expression(const T& x)
54 {
56 }
57#else
58 template <typename T>
59 inline void absinthe_check_expression(const T&)
60 {}
61#endif
62
63 // Returns true if f appears as a structured sort constructor in dataspec.
64 inline
66 {
67 for (const data::alias& a: dataspec.user_defined_aliases())
68 {
69 if (f.sort() != a.name())
70 {
71 continue;
72 }
73 const data::sort_expression& s = a.reference();
75 {
76 const auto& ss = atermpp::down_cast<data::structured_sort>(s);
77 for (const data::function_symbol& g: ss.constructor_functions())
78 {
79 if (f.name() == g.name())
80 {
81 return true;
82 }
83 }
84 }
85 }
86 return false;
87 }
88
89 inline
91 {
92 mCRL2log(log::debug) << "--- used function symbols ---" << std::endl;
94 {
95 mCRL2log(log::debug) << print_symbol(f) << std::endl;
96 }
97 }
98
99 // TODO: Is this correct if s has the shape A -> (B -> C)? Should the result be (B -> C) or C?
100 inline
102 {
103 if (data::is_basic_sort(s))
104 {
105 return s;
106 }
107 else if (data::is_function_sort(s))
108 {
109 const auto& fs = atermpp::down_cast<data::function_sort>(s);
110 return fs.codomain();
111 }
112 else if (data::is_container_sort(s))
113 {
114 return s;
115 }
116 throw mcrl2::runtime_error("target_sort: unsupported sort " + print_term(s) + " detected!");
117 return data::sort_expression();
118 }
119
120} // namespace detail
121
123{
124 typedef std::map<data::sort_expression, data::sort_expression> sort_expression_substitution_map;
125 typedef std::map<data::function_symbol, data::function_symbol> function_symbol_substitution_map;
126 typedef std::map<data::sort_expression, data::function_symbol> abstraction_map;
127
128 // Used for generating variables of sort comprehensions.
130
131 struct absinthe_sort_expression_builder: public sort_expression_builder<absinthe_sort_expression_builder>
132 {
134 using super::apply;
135
140
145 )
146 : sigmaH(sigmaA_),
147 sigmaS(sigmaS_),
148 sigmaF(sigmaF_),
149 generator(generator_)
150 {}
151
152 template <class T>
153 void apply(T& result, const data::sort_expression& x)
154 {
155 auto i = sigmaS.find(x);
156 if (i == sigmaS.end())
157 {
158 super::apply(result, x);
159 //pbes_system::detail::absinthe_check_expression(result);
160 }
161 else
162 {
163 result = i->second;
164 //pbes_system::detail::absinthe_check_expression(result);
165 }
166 }
167
168 template <class T>
169 void apply(T& result, const data::function_symbol& x)
170 {
171 auto i = sigmaF.find(x);
172 if (i != sigmaF.end())
173 {
174 //pbes_system::detail::absinthe_check_expression(i->second);
175 result = i->second;
176 return;
177 }
178 throw mcrl2::runtime_error("function symbol " + print_symbol(x) + " not present in the function symbol mapping!");
179 }
180
181 template <class T>
182 void apply(T& result, const data::application& x)
183 {
184 if (data::is_variable(x.head()))
185 {
186 data::variable v = atermpp::down_cast<data::variable>(x.head());
188 super::apply(sort, v.sort());
189 v = data::variable(v.name(), sort);
191 return;
192 }
193 else if (data::is_function_symbol(x.head()))
194 {
195 super::apply(result, x);
196 return;
197 }
198 else
199 {
200 throw mcrl2::runtime_error("don't know how to handle arbitrary expression as head: " + data::pp(x));
201 }
202 }
203
204 template <class T>
205 void apply(T& result, const data::lambda& x)
206 {
208 super::apply(body, x);
209 //pbes_system::detail::absinthe_check_expression(body);
210 data::sort_expression s = body.sort();
212 data::variable v(generator("v"), s);
214 //pbes_system::detail::absinthe_check_expression(result);
215 }
216
217 template <class T>
218 void apply(T& result, const data::data_expression& x)
219 {
220 if (data::is_variable(x))
221 {
222 super::apply(result, x);
223 result = data::detail::create_finite_set(result);
224 //pbes_system::detail::absinthe_check_expression(result);
225 }
226 else
227 {
228 // check if it is a "ground term", i.e. it does not contain any variables
229 auto i = sigmaH.find(x.sort());
230 if (i != sigmaH.end() && data::find_all_variables(x).empty())
231 {
232 data::data_expression_list args = { x };
233 result = data::detail::create_finite_set(data::application(i->second, args));
234 //pbes_system::detail::absinthe_check_expression(result);
235 }
236 else
237 {
238 // first apply the sort and function symbol transformations
239 super::apply(result, x);
240 //pbes_system::detail::absinthe_check_expression(result);
241 }
242 }
243 }
244 };
245
246 // Applies sigmaS to a sort expression
248 {
251
253
258 )
259 : f(sigmaH, sigmaS, sigmaF, generator)
260 {}
261
263 {
265 f.apply(sort, x);
266 return sort;
267 }
268 };
269
270 struct absinthe_data_expression_builder: public pbes_expression_builder<absinthe_data_expression_builder>
271 {
273 using super::apply;
274 using super::update;
275
277 {
278 std::vector<data::variable> result;
279 std::size_t i = 0;
280 for (auto j = x.begin(); j != x.end(); ++i, ++j)
281 {
282 result.emplace_back(hint + utilities::number2string(i), sigma(j->sort()));
283 }
284 return data::variable_list(result.begin(), result.end());
285 }
286
292
294 {
297 return result;
298 }
299
301 {
304 return result;
305 }
306
308 {
309 data::variable_list result;
311 return result;
312 }
313
315 {
318 return result;
319 }
320
325 bool is_over_approximation)
326 : sigmaH(sigmaA_),
327 sigmaS(sigmaS_),
328 sigmaF(sigmaF_),
329 generator(generator_),
330 m_is_over_approximation(is_over_approximation)
331 {}
332
333 template <class T>
334 void apply(T& result, const data::data_expression& x)
335 {
338 {
340 }
341 else
342 {
344 }
345 }
346
347 template <class T>
349 {
353 data::variable_list::iterator j = variables.begin();
355 for (; i != e.end(); ++i, ++j)
356 {
357 z.push_back(data::detail::create_set_in(*j, *i));
358 }
359 data::data_expression q = data::lazy::join_and(z.begin(), z.end());
361 {
362 result = make_exists_(variables, and_(q, propositional_variable_instantiation(x.name(), atermpp::container_cast<data::data_expression_list>(variables))));
363 }
364 else
365 {
366 result = make_forall_(variables, imp(q, propositional_variable_instantiation(x.name(), atermpp::container_cast<data::data_expression_list>(variables))));
367 }
368 }
369
370 template <class T>
371 void apply(T& result, const pbes_system::forall& x)
372 {
374 super::apply(body, x.body());
375 result = make_forall_(lift(x.variables()), body);
376 }
377
378 template <class T>
379 void apply(T& result, const pbes_system::exists& x)
380 {
382 super::apply(body, x.body());
383 result = make_exists_(lift(x.variables()), body);
384 }
385
387 {
388 x.variable() = lift(x.variable());
390 super::apply(result, x.formula());
391 x.formula() = result;
392 }
393
395 {
397 pbes_expression kappa;
398 apply(kappa, x.initial_state());
399 core::identifier_string name("GeneratedZ");
401 x.equations().emplace_back(fixpoint_symbol::mu(), Z, kappa);
403 }
404 };
405
407 {
409
410 for (const std::string& line: utilities::regex_split(text, "\\n"))
411 {
412 std::vector<std::string> words = utilities::regex_split(line, ":=");
413 if (words.size() == 2)
414 {
415 data::sort_expression lhs = data::parse_sort_expression(words[0], dataspec);
416 data::sort_expression rhs = data::parse_sort_expression(words[1], dataspec);
417 result[lhs] = rhs;
418 }
419 }
420 return result;
421 }
422
423 // Parse the right hand sides of the function symbol mapping in text, and add them to dataspec if needed
424 void parse_right_hand_sides(const std::string& text, data::data_specification& dataspec)
425 {
426 std::string dataspec_text = data::pp(dataspec);
427 for (const std::string& line: utilities::regex_split(text, "\\n"))
428 {
429 std::vector<std::string> words = utilities::regex_split(line, ":=");
430 if (words.size() == 2)
431 {
432 data::function_symbol f = data::parse_function_symbol(words[1], dataspec_text);
434 {
435 dataspec.add_mapping(f);
436 }
437 }
438 }
439 }
440
442 {
444 std::string dataspec_text = data::pp(dataspec);
445
446 for (const std::string& line: utilities::regex_split(text, "\\n"))
447 {
448 std::vector<std::string> words = utilities::regex_split(line, ":=");
449 if (words.size() == 2)
450 {
451 data::function_symbol lhs = data::parse_function_symbol(words[0], dataspec_text);
452 std::string s = words[1];
453 s = utilities::regex_replace(";\\s*$", "", s);
455 result[lhs] = rhs;
456 }
457 }
458 return result;
459 }
460
461 // text is a data_specification; extract the user defined mappings
462 abstraction_map parse_abstraction_map(const std::string& text)
463 {
464 abstraction_map result;
466 for (const data::function_symbol& i: dataspec.user_defined_mappings())
467 {
468 const auto& f = atermpp::down_cast<data::function_sort>(i.sort());
469 if (f.domain().size() != 1)
470 {
471 throw mcrl2::runtime_error("cannot abstract the function " + data::pp(i) + " since the arity of the domain is not equal to one!");
472 }
473 result[f.domain().front()] = i;
474 }
475 return result;
476 }
477
478 // creates a finite set containing one data expression
480 {
482 {
485 result = data::sort_fset::cons_(s, x, result);
486 return result;
487 }
488 };
489
490 // transforms the sort expression s to Set(s)
491 struct make_set
492 {
494 {
495 return data::sort_set::set_(s);
496 }
497 };
498
499 // function that transforms a function symbol
501 {
502 std::map<std::string, std::string> unprintable;
503 std::set<std::string> suffix_with_sort;
504
506 {
507 unprintable["&&"] = "and";
508 unprintable["||"] = "or";
509 unprintable["!"] = "not";
510 unprintable["#"] = "len";
511 unprintable["."] = "element_at";
512 unprintable["+"] = "plus";
513 unprintable["-"] = "minus";
514 unprintable[">"] = "greater";
515 unprintable["<"] = "less";
516 unprintable[">="] = "ge";
517 unprintable["<="] = "le";
518 unprintable["=="] = "eq";
519 unprintable["!="] = "neq";
520 unprintable["[]"] = "emptylist";
521 unprintable["++"] = "concat";
522 unprintable["<|"] = "snoc";
523 unprintable["|>"] = "cons";
524 unprintable["@cNat"] = "cNat";
525 unprintable["@cDub"] = "cDub";
526 unprintable["@c0"] = "c0";
527 unprintable["@c1"] = "c1";
528 unprintable["@func_update"] = "func_update";
529 unprintable["@cInt"] = "cInt";
530 unprintable["@cNeg"] = "cNeg";
531
532 suffix_with_sort.insert("[]");
533 suffix_with_sort.insert("|>");
534 }
535
536 std::string print_cleaned(const data::sort_expression& s) const
537 {
538 std::string result = data::pp(s);
539 result = utilities::regex_replace("\\(", "_", result);
540 result = utilities::regex_replace("\\)", "_", result);
541 result = utilities::regex_replace("#", "_", result);
542 result = utilities::regex_replace("->", "_", result);
543 result = utilities::remove_whitespace(result);
544 return result;
545 }
546
547
549 {
551
552 //mCRL2log(log::debug) << "lift_function_symbol_1_2 f = " << print_symbol(f) << std::endl;
553 std::string name = std::string(f.name());
554
555 bool print_sort = contains(suffix_with_sort, std::string(f.name()));
556 auto i = unprintable.find(name);
557 if (i != unprintable.end())
558 {
559 name = i->second;
560 }
561 name = "Generated_" + name;
562 if (print_sort)
563 {
564 name = name + print_cleaned(f.sort());
565 }
566
567 const data::sort_expression& s = f.sort();
568 if (data::is_basic_sort(s))
569 {
570 return data::function_symbol(name, sigma(s));
571 }
572 else if (data::is_function_sort(s))
573 {
574 // Apply sigmaS recursively to s
575 // f: tail: List(Nat) -> List(Nat)
576 // result: generated_tail: List(AbsNat) -> Set(List(AbsNat))
577 data::function_sort fs = atermpp::down_cast<data::function_sort>(sigma(s));
579 }
580 else if (data::is_container_sort(s))
581 {
582 // Apply sigmaS recursively to s
583 // Example: List(Nat) -> List(AbsNat)
584 return data::function_symbol(name, sigma(s));
585 }
586 throw mcrl2::runtime_error("absinthe algorithm: unsupported sort " + print_term(s) + " detected!");
587 return data::function_symbol();
588 }
589 };
590
591 // function that lifts a function symbol
593 {
595 {
596 using namespace data;
597 //mCRL2log(log::debug) << "lift_function_symbol_2_3 f = " << print_symbol(f) << std::endl;
598 std::string name = "Lift" + utilities::trim_copy(std::string(f.name()));
599 const sort_expression &s = f.sort();
600 if (is_basic_sort(s))
601 {
602 return function_symbol(name, make_set()(s));
603 }
604 else if (is_function_sort(s))
605 {
606 const auto& fs = atermpp::down_cast<data::function_sort>(s);
607 const sort_expression_list& sl = fs.domain();
608 return function_symbol(name, function_sort(sort_expression_list(sl.begin(),sl.end(), make_set()), fs.codomain()));
609 }
610 else if (is_container_sort(s))
611 {
612 return data::function_symbol(name, make_set()(s));
613 }
614 throw mcrl2::runtime_error("absinthe algorithm (lift): unsupported sort " + print_term(s) + " detected!");
615 }
616 };
617
618 // function that generates an equation from a function symbol and it's corresponding 'generated' version
620 {
621 lift_equation_1_2() = default;
622
623 std::vector<data::variable> make_variables(const data::sort_expression_list& sorts, const std::string& hint, sort_function sigma) const
624 {
625 std::vector<data::variable> result;
626 std::size_t i = 0;
627 for (auto j = sorts.begin(); j != sorts.end(); ++i, ++j)
628 {
629 result.emplace_back(hint + utilities::number2string(i), sigma(*j));
630 }
631 return result;
632 }
633
634 // sigmaH is used for checking consistency of the user input
636 {
637 mCRL2log(log::debug) << "lift_equation_1_2 f1 = " << print_symbol(f1) << " f2 = " << print_symbol(f2) << std::endl;
638 data::variable_list variables;
639 const data::data_expression& condition = data::true_();
642
643 data::sort_expression s1 = f1.sort();
644 //data::function_symbol f1a(f1.name(), sigma(s1));
645
646 if (data::is_basic_sort(s1))
647 {
648 lhs = f2;
649 data::function_symbol f1_sigma(f1.name(), sigma(f1.sort()));
650
651 auto i = sigmaH.find(f1.sort());
652 if (i == sigmaH.end())
653 {
654 rhs = f1_sigma;
655 }
656 else
657 {
658 data::function_symbol h = i->second;
659 rhs = data::application(h, f1);
660 //pbes_system::detail::absinthe_check_expression(rhs);
661 }
662 }
663 else if (data::is_function_sort(s1))
664 {
665 data::function_sort fs1(f1.sort());
666 data::function_sort fs2(f2.sort());
667
668 // check validity
670 {
671 // TODO: add check that the domain of the updated function does not contain abstraction sorts
672 }
673 else if (fs1.domain() != fs2.domain())
674 {
675 throw std::runtime_error("can not generalize functions with abstraction sorts in the domain: " + data::pp(f1) + ": " + data::pp(s1));
676 }
677
679 variables = data::variable_list(x.begin(),x.end());
680 lhs = data::application(f2, x.begin(), x.end());
681 data::application f_x(f1, x.begin(), x.end());
682
683 data::function_symbol f1_sigma(f1.name(), sigma(f1.sort()));
684
685 auto i = sigmaH.find(detail::target_sort(f1.sort()));
686 if (i == sigmaH.end())
687 {
688 data::application f1_sigma_x(f1_sigma, x.begin(), x.end());
690 //pbes_system::detail::absinthe_check_expression(rhs);
691 }
692 else
693 {
694 data::function_symbol h = i->second;
696 //pbes_system::detail::absinthe_check_expression(rhs);
697 }
698 }
699 else if (data::is_container_sort(s1))
700 {
701 // Example:
702 // f1: [] : List(Nat)
703 // f2: generated_emptylist : List(AbsNat)
704 // eqn: generated_emptylist = [] met [] : List(AbsNat)
705 // tail: List(AbsNat) -> List(Nat)
706 lhs = f2;
707 data::function_symbol f1_sigma(f1.name(), sigma(f1.sort()));
708 rhs = f1_sigma;
709 //pbes_system::detail::absinthe_check_expression(rhs);
710 }
711 else
712 {
713 throw mcrl2::runtime_error("absinthe algorithm (lift_equation_1_2): unsupported sort " + print_term(s1) + " detected!");
714 }
715
716 if (lhs.sort() != rhs.sort())
717 {
718 throw mcrl2::runtime_error("absinthe algorithm (lift_equation_1_2): lhs.sort() and rhs.sort are not equal: " + data::pp(lhs.sort()) + " <-> " + data::pp(rhs.sort()));
719 }
720
721 return data::data_equation(variables, condition, lhs, rhs);
722 }
723 };
724
725 // function that generates an equation from a function symbol and it's corresponding lifted version
727 {
728 lift_equation_2_3() = default;
729
730 std::vector<data::variable> make_variables(const data::sort_expression_list& sorts, const std::string& hint, sort_function sigma) const
731 {
732 std::vector<data::variable> result;
733 std::size_t i = 0;
734 for (auto j = sorts.begin(); j != sorts.end(); ++i, ++j)
735 {
736 result.emplace_back(hint + utilities::number2string(i), sigma(*j));
737 }
738 return result;
739 }
740
741 // Let x = [x1:D1, ..., xn:Dn] and X = [X1:Set(D1), ..., Xn:Set(Dn)]. Returns the expression
742 //
743 // (x1 in X1 /\ ... /\ xn in Xn)
744 data::data_expression enumerate_domain(const std::vector<data::variable>& x, const std::vector<data::variable>& X) const
745 {
746 std::vector<data::data_expression> a;
747 auto i = x.begin();
748 auto j = X.begin();
749 for (; i != x.end(); ++i, ++j)
750 {
751 a.push_back(data::detail::create_set_in(*i, *j));
752 }
753 data::data_expression body = data::lazy::join_and(a.begin(), a.end());
754 return body;
755 }
756
758 {
759 //mCRL2log(log::debug) << "lift_equation_2_3 f2 = " << print_symbol(f2) << " f3 = " << print_symbol(f3) << std::endl;
760 data::variable_list variables;
761 const data::data_expression& condition = data::true_();
764
765 const data::sort_expression& s2 = f2.sort();
766
767 if (data::is_basic_sort(s2))
768 {
769 lhs = f3;
771 }
772 else if (data::is_function_sort(s2))
773 {
774 data::function_sort fs2(f2.sort());
775 data::function_sort fs3(f3.sort());
776
778 {
779 throw mcrl2::runtime_error("The codomain " + data::pp(fs2.codomain()) + " of function " + data::pp(f2.name()) + " should be a container sort!");
780 }
781
782 // TODO: generate these variables in a proper way
783 std::vector<data::variable> x = make_variables(fs2.domain(), "x", sigma);
784 std::vector<data::variable> X = make_variables(fs3.domain(), "X", sigma);
785
786 variables = data::variable_list(X.begin(), X.end());
787 lhs = data::application(f3, X.begin(), X.end());
788 data::variable y("y", data::detail::get_set_sort(atermpp::down_cast<data::container_sort>(fs2.codomain())));
789 data::data_expression Y = data::application(f2, x.begin(), x.end());
792 }
793 else if (data::is_container_sort(s2))
794 {
795 lhs = f3;
797 }
798 else
799 {
800 throw mcrl2::runtime_error("absinthe algorithm (lift_equation_2_3): unsupported sort " + print_term(s2) + " detected!");
801 }
802 return data::data_equation(variables, condition, lhs, rhs);
803 }
804 };
805
806 template <typename Map>
807 std::string print_mapping(const Map& m)
808 {
809 std::ostringstream out;
810 for (auto i = m.begin(); i != m.end(); ++i)
811 {
812 out << i->first << " -> " << i->second << std::endl;
813 }
814 return out.str();
815 }
816
818 {
819 sort_expression_substitution_map::const_iterator i = sigmaS.find(s);
820 if (i != sigmaS.end() && i->second != t)
821 {
822 throw mcrl2::runtime_error("inconsistent abstraction " + data::pp(s) + " := " + data::pp(t) + " detected in the abstraction of " + print_symbol(f) + " (elsewhere it is abstracted as " + data::pp(s) + " := " + data::pp(i->second) + ").");
823 }
824 else
825 {
826 sigmaS[s] = t;
827 }
828 }
829
830 // Let f1: s1 x ... sn -> s and f2: t1 x ... tn -> t
831 // This function checks if the correspondence si -> ti conflicts with sigmaS.
833 {
834 const data::sort_expression& s1 = f1.sort();
835 const data::sort_expression& s2 = f2.sort();
836
837 if (data::is_basic_sort(s1))
838 {
839 check_consistency(s1, s2, f1, sigmaS);
840 }
841 else if (data::is_function_sort(s1))
842 {
843 data::function_sort fs1(s1);
844 data::function_sort fs2(s2);
845
846 const data::sort_expression_list& domain1 = fs1.domain();
847 const data::sort_expression_list& domain2 = fs2.domain();
848
851
852 for (; i1 != domain1.end(); ++i1, ++i2)
853 {
854 check_consistency(*i1, *i2, f1, sigmaS);
855 }
856 // check_consistency(fs1.codomain(), fs2.codomain(), f1, sigmaS);
857 }
858// else if (data::is_container_sort(s1))
859// {
860// }
861 }
862
863 // add lifted mappings and equations to the data specification
865 {
867
868 sort_expression_substitution_map sigmaS_consistency = sigmaS; // is only used for consistency checking
869 sort_function sigma(sigmaH, sigmaS, sigmaF, m_generator);
870
871 // add lifted versions of used function symbols that are not specified by the user to sigmaF, and adds them to the data specification as well
872 std::set<data::function_symbol> used_function_symbols = pbes_system::find_function_symbols(p);
873
874 // add List containers for user defined sorts, since they are used in the translation
875 const data::basic_sort_vector& sorts = dataspec.user_defined_sorts();
876 for (const data::basic_sort& sort: sorts)
877 {
879 dataspec.add_context_sort(s);
880 }
881
882 // add constructor functions of List containers of abstracted sorts to sigmaF
883 for (const auto& i: sigmaH)
884 {
886 dataspec.add_context_sort(s);
887 data::function_symbol_vector list_constructors = dataspec.constructors(s);
888 for (const data::function_symbol& f1: list_constructors)
889 {
891 sigmaF[f1] = f2;
892 dataspec.add_mapping(f2);
893 mCRL2log(log::debug) << "adding list constructor " << f1 << " to sigmaF" << std::endl;
894 }
895 }
896
897 for (const data::function_symbol& f1: used_function_symbols)
898 {
899 mCRL2log(log::debug) << "lifting function symbol: " << f1 << std::endl;
900 if (!has_key(sigmaF, f1))
901 {
903 mCRL2log(log::debug) << "lifted function symbol: " << f1 << " to " << f2 << std::endl;
904 check_consistency(f1, f2, sigmaS_consistency);
905 sigmaF[f1] = f2;
906 dataspec.add_mapping(f2);
907
908 data::data_equation eq = lift_equation_1_2()(f1, f2, sigma, sigmaH);
909 mCRL2log(log::debug) << "adding equation: " << eq << std::endl;
910 dataspec.add_equation(eq);
911 }
912 }
913
914 for (auto& i : sigmaF)
915 {
916 // data::function_symbol f1 = i->first;
917 data::function_symbol f2 = i.second;
919
920 mCRL2log(log::debug) << "adding mapping: " << f3 << " " << f3.sort() << std::endl;
921 dataspec.add_mapping(f3);
922
923 // update sigmaF
924 i.second = f3;
925
926 // make an equation for the lifted function symbol f
928 mCRL2log(log::debug) << "adding equation: " << eq << std::endl;
929 dataspec.add_equation(eq);
930 }
931 }
932
933 void print_fsvec(const data::function_symbol_vector& v, const std::string& msg) const
934 {
935 mCRL2log(log::debug) << "--- " << msg << std::endl;
936 for (const data::function_symbol& f: v)
937 {
938 mCRL2log(log::debug) << print_symbol(f) << std::endl;
939 }
940 }
941
942 void print_fsmap(const function_symbol_substitution_map& v, const std::string& msg) const
943 {
944 mCRL2log(log::debug) << "--- " << msg << std::endl;
945 for (const auto& i: v)
946 {
947 mCRL2log(log::debug) << print_symbol(i.first) << " --> " << print_symbol(i.second) << std::endl;
948 }
949 }
950
952 {
954 }
955
956 void run(pbes& p, const std::string& abstraction_text, bool is_over_approximation)
957 {
958 // split the string abstraction_text into four different parts
959 std::string function_symbol_mapping_text;
960 std::string user_sorts_text;
961 std::string user_equations_text;
962 std::string abstraction_mapping_text;
963 std::string pbes_sorts_text;
964
965 std::string text = abstraction_text;
966 std::vector<std::string> all_keywords = { "sort", "var", "eqn", "map", "cons", "absfunc", "absmap" };
967 std::pair<std::string, std::string> q;
968
969 q = utilities::detail::separate_keyword_section(text, "sort", all_keywords);
970 user_sorts_text = q.first;
971 text = q.second;
972
973 q = utilities::detail::separate_keyword_section(text, "absmap", all_keywords);
974
975 abstraction_mapping_text = q.first;
976 text = q.second;
977
978 // must be the last one!
979 q = utilities::detail::separate_keyword_section(text, "absfunc", all_keywords);
980 function_symbol_mapping_text = q.first;
981 user_equations_text = q.second;
982
983 // extract pbes sorts
984 std::string ptext = data::pp(p.data());
985 q = utilities::detail::separate_keyword_section(ptext, "sort", all_keywords);
986 pbes_sorts_text = q.first;
987
988 // 0) split user_dataspec_text into user_sorts_text and user_equations_text
989 mCRL2log(log::debug) << "--- user sorts ---\n" << user_sorts_text << std::endl;
990 mCRL2log(log::debug) << "--- user equations ---\n" << user_equations_text << std::endl;
991 mCRL2log(log::debug) << "--- function mapping ---\n" << function_symbol_mapping_text << std::endl;
992 mCRL2log(log::debug) << "--- abstraction mapping ---\n" << abstraction_mapping_text << std::endl;
993 mCRL2log(log::debug) << "--- pbes sorts ---\n" << pbes_sorts_text << std::endl;
994
995 if (abstraction_mapping_text.find("absmap") != 0)
996 {
997 throw mcrl2::runtime_error("the abstraction mapping may not be empty!");
998 }
999
1000 // 1) create the data specification dataspec, which consists of user_sorts_text, abstract_mapping_text and p.data()
1001 data::data_specification dataspec = data::parse_data_specification(data::pp(p.data()) + "\n" + user_sorts_text + "\n" + abstraction_mapping_text.substr(3));
1002 mCRL2log(log::debug) << "--- data specification 1) ---\n" << dataspec << std::endl;
1003
1004 // 2) parse the right hand sides of the function symbol mapping, and add them to dataspec
1005 parse_right_hand_sides(function_symbol_mapping_text, dataspec);
1006 mCRL2log(log::debug) << "--- data specification 2) ---\n" << dataspec << std::endl;
1007
1008 // 3) add user_equations_text to dataspec
1009 dataspec = data::parse_data_specification(data::pp(dataspec) + "\n" + user_equations_text);
1010 mCRL2log(log::debug) << "--- data specification 3) ---\n" << dataspec << std::endl;
1011
1012 // abstraction functions (specified by the user)
1013 abstraction_map sigmaH = parse_abstraction_map(pbes_sorts_text + "\n" + user_sorts_text + "\n" + abstraction_mapping_text.substr(3));
1014
1015 // sort expressions replacements (extracted from sigmaH)
1017 for (auto i = sigmaH.begin(); i != sigmaH.end(); ++i)
1018 {
1019 data::function_symbol f = i->second;
1020 const data::function_sort& fs = atermpp::down_cast<data::function_sort>(f.sort());
1021 sigmaS[i->first] = fs.codomain();
1022 }
1023 mCRL2log(log::debug) << "\n--- sort expression mapping ---\n" << print_mapping(sigmaS) << std::endl;
1024
1025 // function symbol replacements (specified by the user)
1026 function_symbol_substitution_map sigmaF = parse_function_symbol_mapping(function_symbol_mapping_text, dataspec);
1027 mCRL2log(log::debug) << "\n--- function symbol mapping ---\n" << print_mapping(sigmaF) << std::endl;
1028
1031
1032 // 4) add lifted sorts, mappings and equations to dataspec
1033 // before: the mapping sigmaF is f1 -> f2
1034 // after: the mapping sigmaF is f1 -> f3
1035 // after: f2 and f3 have been added to dataspec
1036 // after: equations for f3 have been added to dataspec
1037 // generate mapping f1 -> f2 for missing function symbols
1038 lift_data_specification(p, sigmaH, sigmaS, sigmaF, dataspec);
1039 mCRL2log(log::debug) << "--- data specification 4) ---\n" << dataspec << std::endl;
1040
1041 mCRL2log(log::debug) << "\n--- function symbol mapping after lifting ---\n" << print_mapping(sigmaF) << std::endl;
1042
1043 mCRL2log(log::debug) << "--- pbes before ---\n" << p << std::endl;
1044
1045 p.data() = dataspec;
1046
1047 // then transform the data expressions and the propositional variable instantiations
1048 absinthe_data_expression_builder(sigmaH, sigmaS, sigmaF, m_generator, is_over_approximation).update(p);
1049
1050 mCRL2log(log::debug) << "--- pbes after ---\n" << p << std::endl;
1051 }
1052};
1053
1054} // namespace pbes_system
1055
1056} // namespace mcrl2
1057
1058#endif // MCRL2_PBES_ABSINTHE_H
Term containing a string.
Iterator for term_list.
const_iterator end() const
Returns a const_iterator pointing to the end of the term_list.
Definition aterm_list.h:282
const_iterator begin() const
Returns a const_iterator pointing to the beginning of the term_list.
Definition aterm_list.h:275
\brief A sort alias
Definition alias.h:26
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.
\brief A basic sort
Definition basic_sort.h:26
\brief A container sort
\brief A data equation
sort_expression sort() const
Returns the sort of the data expression.
Definition data.cpp:108
const_iterator begin() const
void add_mapping(const function_symbol &f)
Adds a mapping to this specification.
void add_equation(const data_equation &e)
Adds an equation to this specification.
const function_symbol_vector & user_defined_mappings() const
Gets all user defined mappings in this specification.
const function_symbol_vector & constructors() const
Gets all constructors including those that are system defined.
existential quantification.
Definition exists.h:26
\brief A function sort
const sort_expression & codomain() const
const sort_expression_list & domain() const
\brief A function symbol
const core::identifier_string & name() const
const sort_expression & sort() const
void add_identifiers(const std::set< core::identifier_string > &ids)
Add a set of identifiers to the context.
function symbol.
Definition lambda.h:27
\brief Container type for lists
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
\brief A sort expression
const basic_sort_vector & user_defined_sorts() const
Gets all sorts defined by a user (excluding the system defined sorts).
void add_context_sort(const sort_expression &s)
Adds the sort s to the context sorts.
const alias_vector & user_defined_aliases() const
Gets the user defined aliases.
\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
static void set_reporting_level(const log_level_t level)
Set reporting level.
Definition logger.h:210
\brief The and operator for pbes expressions
\brief The existential quantification operator for pbes expressions
const data::variable_list & variables() const
const pbes_expression & body() const
static fixpoint_symbol mu()
Returns the mu symbol.
\brief The universal quantification operator for pbes expressions
const pbes_expression & body() const
const data::variable_list & variables() const
\brief The implication operator for pbes expressions
const pbes_expression & formula() const
Returns the predicate formula on the right hand side of the equation.
const propositional_variable & variable() const
Returns the pbes variable of the equation.
parameterized boolean equation system
Definition pbes.h:58
const data::data_specification & data() const
Returns the data specification.
Definition pbes.h:150
const propositional_variable_instantiation & initial_state() const
Returns the initial state.
Definition pbes.h:192
const std::vector< pbes_equation > & equations() const
Returns the equations.
Definition pbes.h:164
\brief A propositional variable instantiation
const data::data_expression_list & parameters() const
\brief A propositional variable declaration
Standard exception class for reporting runtime errors.
Definition exception.h:27
This file contains some functions that are present in all libraries except the data library....
add your file description here.
static RewriterCompilingJitty::substitution_type & sigma(RewriterCompilingJitty *this_rewriter)
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:391
sort_expression get_set_sort(const container_sort &x)
Returns the sort s of Set(s).
data_expression create_finite_set(const data_expression &x)
Create the finite set { x }, with x a data expression.
void print_parse_check(const sort_expression &x, const data_specification &dataspec=data_specification())
data_expression create_set_in(const data_expression &x, const data_expression &X)
Create the predicate 'x in X', with X a set.
data_expression create_set_comprehension(const variable &x, const data_expression &phi)
Create the set { x | phi }, with phi a predicate that may depend on the variable x.
data_expression join_and(ForwardTraversalIterator first, ForwardTraversalIterator last)
Returns and applied to the sequence of data expressions [first, last)
function_symbol cons_(const sort_expression &s)
Constructor for function symbol @fset_cons.
Definition fset1.h:207
function_symbol empty(const sort_expression &s)
Constructor for function symbol {}.
Definition fset1.h:75
container_sort set_(const sort_expression &s)
Constructor for sort expression Set(S)
Definition set1.h:42
bool is_structured_sort(const atermpp::aterm &x)
Returns true if the term t is a structured sort.
void find_identifiers(const T &x, OutputIterator o)
Definition find.h:359
data_expression not_(const data_expression &x)
std::set< data::variable > find_all_variables(const data::data_expression &x)
Definition data.cpp:94
sort_expression parse_sort_expression(std::istream &in, const data_specification &data_spec=detail::default_specification())
Parses and type checks a sort expression.
Definition parse.h:380
data_specification parse_data_specification(std::istream &in)
Parses a and type checks a data specification.
Definition parse.h:62
data_expression and_(const data_expression &x, const data_expression &y)
std::vector< variable > variable_vector
\brief vector of variables
Definition variable.h:89
const data_expression & false_()
Definition consistency.h:99
const data_expression & true_()
Definition consistency.h:92
std::vector< data_expression > data_expression_vector
\brief vector of data_expressions
data::function_symbol parse_function_symbol(const std::string &text, const std::string &dataspec_text="")
Definition parse.h:410
std::string pp(const abstraction &x)
Definition data.cpp:39
bool is_container_sort(const atermpp::aterm &x)
Returns true if the term t is a container sort.
bool is_function_symbol(const atermpp::aterm &x)
Returns true if the term t is a function symbol.
bool is_basic_sort(const atermpp::aterm &x)
Returns true if the term t is a basic sort.
atermpp::term_list< variable > variable_list
\brief list of variables
std::set< core::identifier_string > function_and_mapping_identifiers(const data_specification &dataspec)
Returns the names of functions and mappings that occur in a data specification.
bool is_function_sort(const atermpp::aterm &x)
Returns true if the term t is a function sort.
function_symbol equal_to(const sort_expression &s)
Constructor for function symbol ==.
Definition standard.h:126
bool is_function_update_application(const atermpp::aterm &e)
Recogniser for application of @func_update.
std::vector< basic_sort > basic_sort_vector
vector of basic sorts
Definition basic_sort.h:94
std::vector< function_symbol > function_symbol_vector
\brief vector of function_symbols
bool is_variable(const atermpp::aterm &x)
Returns true if the term t is a variable.
void absinthe_check_expression(const T &x)
Definition absinthe.h:53
data::data_specification & absinthe_data_specification()
Definition absinthe.h:45
void print_used_function_symbols(const pbes &p)
Definition absinthe.h:90
bool is_structured_sort_constructor(const data::data_specification &dataspec, const data::function_symbol &f)
Definition absinthe.h:65
data::sort_expression target_sort(const data::sort_expression &s)
Definition absinthe.h:101
pbes_expression make_exists_(const data::variable_list &l, const pbes_expression &p)
Make an existential quantification. It checks for an empty variable list, which is not allowed.
std::string print_term(const Term &x)
Definition absinthe.h:31
std::string print_symbol(const Term &x)
Definition absinthe.h:37
void find_function_symbols(const T &x, OutputIterator o)
Definition find.h:173
pbes_expression make_forall_(const data::variable_list &l, const pbes_expression &p)
Make a universal quantification. It checks for an empty variable list, which is not allowed.
bool contains(const atermpp::indexed_set< Key, ThreadSafe, Hash, Equals, Allocator, KeyTable > &c, const typename atermpp::indexed_set< Key, ThreadSafe, Hash, Equals, Allocator, KeyTable >::key_type &v, const std::size_t thread_index=0)
Definition indexed_set.h:86
std::pair< std::string, std::string > separate_keyword_section(const std::string &text1, const std::string &keyword, const std::vector< std::string > &all_keywords, bool repeat_keyword=false)
bool has_key(const std::map< Key, T > &c, const Key &v)
Returns the value corresponding to the given key in the set m. If the key is not present,...
void number2string(std::size_t number, std::string &buffer, std::size_t start_position)
Convert a number to a string in the buffer starting at position start_position.
std::string regex_replace(const std::string &src, const std::string &dest, const std::string &text)
Regular expression replacement in a string.
std::vector< std::string > regex_split(const std::string &text, const std::string &sep)
Split a string using a regular expression separator.
std::string trim_copy(const std::string &text)
Remove all trailing and leading spaces from the input.
std::string remove_whitespace(const std::string &text)
Removes whitespace from a string.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Definition indexed_set.h:72
add your file description here.
add your file description here.
add your file description here.
void apply(T &result, const data::data_expression &x)
Definition absinthe.h:334
pbes_system::propositional_variable lift(const pbes_system::propositional_variable &x)
Definition absinthe.h:314
data::variable_list lift(const data::variable_list &x)
Definition absinthe.h:307
data::data_expression lift(const data::data_expression &x)
Definition absinthe.h:293
void apply(T &result, const pbes_system::exists &x)
Definition absinthe.h:379
void apply(T &result, const propositional_variable_instantiation &x)
Definition absinthe.h:348
pbes_expression_builder< absinthe_data_expression_builder > super
Definition absinthe.h:272
void apply(T &result, const pbes_system::forall &x)
Definition absinthe.h:371
data::data_expression_list lift(const data::data_expression_list &x)
Definition absinthe.h:300
absinthe_data_expression_builder(const abstraction_map &sigmaA_, const sort_expression_substitution_map &sigmaS_, const function_symbol_substitution_map &sigmaF_, data::set_identifier_generator &generator_, bool is_over_approximation)
Definition absinthe.h:321
data::variable_list make_variables(const data::data_expression_list &x, const std::string &hint, sort_function sigma) const
Definition absinthe.h:276
void apply(T &result, const data::data_expression &x)
Definition absinthe.h:218
void apply(T &result, const data::function_symbol &x)
Definition absinthe.h:169
void apply(T &result, const data::sort_expression &x)
Definition absinthe.h:153
sort_expression_builder< absinthe_sort_expression_builder > super
Definition absinthe.h:133
absinthe_sort_expression_builder(const abstraction_map &sigmaA_, const sort_expression_substitution_map &sigmaS_, const function_symbol_substitution_map &sigmaF_, data::set_identifier_generator &generator_)
Definition absinthe.h:141
data::data_equation operator()(const data::function_symbol &f1, const data::function_symbol &f2, sort_function sigma, const abstraction_map &sigmaH) const
Definition absinthe.h:635
std::vector< data::variable > make_variables(const data::sort_expression_list &sorts, const std::string &hint, sort_function sigma) const
Definition absinthe.h:623
std::vector< data::variable > make_variables(const data::sort_expression_list &sorts, const std::string &hint, sort_function sigma) const
Definition absinthe.h:730
data::data_expression enumerate_domain(const std::vector< data::variable > &x, const std::vector< data::variable > &X) const
Definition absinthe.h:744
data::data_equation operator()(const data::function_symbol &f2, const data::function_symbol &f3, sort_function sigma) const
Definition absinthe.h:757
std::string print_cleaned(const data::sort_expression &s) const
Definition absinthe.h:536
data::function_symbol operator()(const data::function_symbol &f, sort_function sigma) const
Definition absinthe.h:548
data::function_symbol operator()(const data::function_symbol &f) const
Definition absinthe.h:594
data::data_expression operator()(const data::data_expression &x) const
Definition absinthe.h:481
data::sort_expression operator()(const data::sort_expression &s) const
Definition absinthe.h:493
data::sort_expression operator()(const data::sort_expression &x)
Definition absinthe.h:262
sort_function(const abstraction_map &sigmaH, const sort_expression_substitution_map &sigmaS, const function_symbol_substitution_map &sigmaF, data::set_identifier_generator &generator)
Definition absinthe.h:254
sort_expression_substitution_map parse_sort_expression_mapping(const std::string &text, const data::data_specification &dataspec)
Definition absinthe.h:406
void print_fsvec(const data::function_symbol_vector &v, const std::string &msg) const
Definition absinthe.h:933
void run(pbes &p, const std::string &abstraction_text, bool is_over_approximation)
Definition absinthe.h:956
void parse_right_hand_sides(const std::string &text, data::data_specification &dataspec)
Definition absinthe.h:424
void check_consistency(const data::sort_expression &s, const data::sort_expression &t, const data::function_symbol &f, sort_expression_substitution_map &sigmaS) const
Definition absinthe.h:817
void lift_data_specification(const pbes &p, const abstraction_map &sigmaH, const sort_expression_substitution_map &sigmaS, function_symbol_substitution_map &sigmaF, data::data_specification &dataspec)
Definition absinthe.h:864
std::map< data::function_symbol, data::function_symbol > function_symbol_substitution_map
Definition absinthe.h:125
function_symbol_substitution_map parse_function_symbol_mapping(const std::string &text, const data::data_specification &dataspec)
Definition absinthe.h:441
std::map< data::sort_expression, data::function_symbol > abstraction_map
Definition absinthe.h:126
data::set_identifier_generator m_generator
Definition absinthe.h:129
std::map< data::sort_expression, data::sort_expression > sort_expression_substitution_map
Definition absinthe.h:124
void print_fsmap(const function_symbol_substitution_map &v, const std::string &msg) const
Definition absinthe.h:942
void check_consistency(const data::function_symbol &f1, const data::function_symbol &f2, sort_expression_substitution_map &sigmaS) const
Definition absinthe.h:832
abstraction_map parse_abstraction_map(const std::string &text)
Definition absinthe.h:462
std::string print_mapping(const Map &m)
Definition absinthe.h:807
void update(pbes_system::pbes_equation &x)
Definition builder.h:527
void apply(T &result, const pbes_system::propositional_variable_instantiation &x)
Definition builder.h:544
void apply(T &result, const pbes_system::propositional_variable &x)
Definition builder.h:53