mCRL2
Loading...
Searching...
No Matches
one_point_rule_rewriter.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//
9/// \file mcrl2/pbes/rewriters/one_point_rule_rewriter.h
10/// \brief add your file description here.
11
12#ifndef MCRL2_PBES_REWRITERS_ONE_POINT_RULE_REWRITER_H
13#define MCRL2_PBES_REWRITERS_ONE_POINT_RULE_REWRITER_H
14
15#include "mcrl2/data/consistency.h"
16#include "mcrl2/data/rewriters/one_point_rule_rewriter.h"
17#include "mcrl2/pbes/find_equalities.h"
18#include "mcrl2/pbes/replace.h"
19
20
21
22namespace mcrl2::pbes_system {
23
24/// \cond INTERNAL_DOCS
25namespace detail {
26
27template <typename Derived>
28struct one_point_rule_rewrite_builder: public pbes_system::pbes_expression_builder<Derived>
29{
30 using super = pbes_system::pbes_expression_builder<Derived>;
31 using super::apply;
32
33 Derived& derived()
34 {
35 return static_cast<Derived&>(*this);
36 }
37
38 template <class T>
39 void apply(T& result, const data::data_expression& x)
40 {
42 result = atermpp::down_cast<T>(r(x));
43 }
44
45 template <class T>
46 void apply(T& result, const forall& x)
47 {
48 pbes_expression body;
49 derived().apply(body, forall(x).body());
50
51 std::map<data::variable, std::set<data::data_expression> > inequalities = find_inequalities(body);
52 mCRL2log(log::log_level_t::debug) << "x = " << x << std::endl;
53 mCRL2log(log::log_level_t::debug) << "\ninequalities(body) = " << data::print_inequalities(inequalities) << std::endl;
54 if (!inequalities.empty())
55 {
56 auto p = data::make_one_point_rule_substitution(inequalities, x.variables());
57 data::mutable_map_substitution<>& sigma = p.first;
58 const std::vector<data::variable>& remaining_variables = p.second;
59 if (remaining_variables.size() != x.variables().size()) // one or more substitutions were found
60 {
61 mCRL2log(log::log_level_t::debug) << "Apply substitution sigma = " << sigma << " to x = " << body << std::endl;
62 body = pbes_system::replace_variables_capture_avoiding(body, sigma);
63 mCRL2log(log::log_level_t::debug) << "sigma(x) = " << body << std::endl;
64 if (remaining_variables.empty())
65 {
66 mCRL2log(log::log_level_t::debug) << "Replaced " << x << "\nwith " << body << std::endl;
67 result = body;
68 return;
69 }
70 data::variable_list v(remaining_variables.begin(), remaining_variables.end());
71 mCRL2log(log::log_level_t::debug) << "Replaced " << x << "\nwith " << forall(v, body) << std::endl;
72 pbes_system::make_forall(result, v, body);
73 return;
74 }
75 }
76 pbes_system::make_forall(result, x.variables(), body);
77 }
78
79 template <class T>
80 void apply(T& result, const exists& x)
81 {
82 pbes_expression body;
83 derived().apply(body, exists(x).body());
84
85 std::map<data::variable, std::set<data::data_expression> > equalities = find_equalities(body);
86 mCRL2log(log::log_level_t::debug) << "x = " << body << "\nequalities(x) = " << data::print_inequalities(equalities) << std::endl;
87 if (!equalities.empty())
88 {
89 auto p = data::make_one_point_rule_substitution(equalities, x.variables());
90 data::mutable_map_substitution<>& sigma = p.first;
91 const std::vector<data::variable>& remaining_variables = p.second;
92 if (remaining_variables.size() != x.variables().size()) // one or more substitutions were found
93 {
94 mCRL2log(log::log_level_t::debug) << "Apply substitution sigma = " << sigma << " to x = " << body << std::endl;
95 body = pbes_system::replace_variables_capture_avoiding(body, sigma);
96 mCRL2log(log::log_level_t::debug) << "sigma(x) = " << body << std::endl;
97 if (remaining_variables.empty())
98 {
99 mCRL2log(log::log_level_t::debug) << "Replaced " << x << "\nwith " << body << std::endl;
100 result = body;
101 return;
102 }
103 data::variable_list v(remaining_variables.begin(), remaining_variables.end());
104 mCRL2log(log::log_level_t::debug) << "Replaced " << x << "\nwith " << exists(v, body) << std::endl;
105 pbes_system::make_exists(result, v, body);
106 return;
107 }
108 }
109 pbes_system::make_exists(result, x.variables(), body);
110 }
111
112 // TODO: This case was added to prevent a data not to be transformed into a PBES not.
113 // It should not be necessary to do this, but otherwise a PFNF test case fails.
114 template <class T>
115 void apply(T& result, const not_& x)
116 {
117 pbes_expression operand;
118 derived().apply(operand, x.operand());
120 {
121 result = atermpp::down_cast<T>(data::not_(atermpp::down_cast<data::data_expression>(operand)));
122 }
123 else
124 {
125 result = not_(operand);
126 }
127 }
128};
129
130} // namespace detail
131/// \endcond
132
133/// \brief A rewriter that applies one point rule quantifier elimination to a PBES.
135{
136 public:
137 /// \brief The term type
138 using term_type = pbes_expression;
139
140 /// \brief The variable type
141 using variable_type = data::variable;
142
143 /// \brief Rewrites a pbes expression.
144 /// \param x A term
145 /// \return The rewrite result.
147 {
148 pbes_expression result;
149 core::make_apply_builder<detail::one_point_rule_rewrite_builder>().apply(result, x);
150 return result;
151 }
152};
153
154} // namespace mcrl2::pbes_system
155
156
157
158#endif // MCRL2_PBES_REWRITERS_ONE_POINT_RULE_REWRITER_H
\brief A data variable
Definition variable.h:25
\brief The existential quantification operator for pbes expressions
const data::variable_list & variables() const
exists(const exists &) noexcept=default
Move semantics.
const pbes_expression & body() const
\brief The universal quantification operator for pbes expressions
const pbes_expression & body() const
const data::variable_list & variables() const
forall(const forall &) noexcept=default
Move semantics.
\brief The not operator for pbes expressions
not_(const pbes_expression &operand)
\brief Constructor Z14.
const pbes_expression & operand() const
A rewriter that applies one point rule quantifier elimination to a PBES.
pbes_expression operator()(const pbes_expression &x) const
Rewrites a pbes expression.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:435
bool is_data_expression(const atermpp::aterm &x)
Test for a data_expression expression.