mCRL2
Loading...
Searching...
No Matches
pbesinst_lazy_counter_example.h
Go to the documentation of this file.
1// Author(s): Maurice Laveaux
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/pbesinst_lazy_counter_example.h
10/// \brief A lazy algorithm for instantiating a PBES, ported from bes_deprecated.h.
11
12#ifndef MCRL2_PBES_PBESINST_LAZY_COUNTER_EXAMPLE_H
13#define MCRL2_PBES_PBESINST_LAZY_COUNTER_EXAMPLE_H
14
15#include "mcrl2/pbes/pbesinst_structure_graph.h"
16#include "mcrl2/pbes/pbesinst_structure_graph2.h"
17#include "mcrl2/pbes/replace.h"
18#include "mcrl2/pbes/rewriters/simplify_quantifiers_rewriter.h"
19#include "mcrl2/pbes/structure_graph.h"
20#include "mcrl2/utilities/exception.h"
21#include "mcrl2/utilities/logger.h"
22#include "mcrl2/utilities/math.h"
23
24#include <regex>
25
26namespace mcrl2::pbes_system
27{
28/// \brief For a given X(e) and set of redundant params R, returns a copy of X(e) without redundancy.
29/// \param PVI A propositional variable instantiation X(e).
30/// \param R A set of indices of parameters that are redundant in X(e).
31/// \return A copy of X(e) without redundancy.
32inline
34 const std::unordered_map<std::string, std::set<int>> R)
35{
36 if (R.find(PVI.name()) != R.end())
37 {
38 const std::set<int> Rx = R.at(PVI.name());
39 data::data_expression_vector params(PVI.parameters().begin(), PVI.parameters().end());
40 data::data_expression_vector params_r;
41 for (std::vector<data::data_expression>::size_type i = 0; i < params.size(); i++)
42 {
43 if (Rx.find(static_cast<int>(i)) != Rx.end())
44 {
45 continue; // parameter is redundant
46 }
47 else
48 {
49 params_r.push_back(params[i]);
50 }
51 }
52 return propositional_variable_instantiation(PVI.name(),
53 data::data_expression_list(params_r.begin(), params_r.end()));
54 }
55 else
56 {
57 return PVI;
58 }
59}
60
61namespace detail {
63{
67 bool alpha;
69 const std::unordered_map<std::string, std::set<int>>& R;
70
73 const structure_graph& G,
74 bool alpha,
75 const std::unordered_map<pbes_expression, structure_graph::index_type>& mapping,
76 const std::unordered_map<std::string, std::set<int>>& R)
77 : symbol(symbol),
78 X(X),
79 G(G),
80 alpha(alpha),
82 R(R)
83 {}
84
86 // the rewrite_star substitution is only applicable to closed PVIs.
87 if(!find_free_variables(Y).empty())
88 {
89 mCRL2log(log::trace) << "rewrite_star " << Y << " contains free variables, not applying substitution\n";
90 return Y;
91 }
92
93 std::smatch match;
94
95 // Now we need to find all reachable X --> Y, following vertices that are not ranked.
96 mCRL2log(log::debug) << "X = " << X << std::endl;
97
98 std::unordered_set<pbes_expression> Ys;
99
100 // If X is won by player alpha, i.e. in the winning set W.
101 auto it = mapping.find(rewrite_PVI(X, R));
102 if (it != mapping.end())
103 {
104 structure_graph::index_type index = it->second;
105 std::unordered_set<structure_graph::index_type> todo = {index};
106 std::unordered_set<structure_graph::index_type> done;
107
108 while (!todo.empty())
109 {
110 structure_graph::index_type u = *todo.begin();
111 todo.erase(todo.begin());
112 done.insert(u);
113
114 if (mapping.count(G.find_vertex(u).formula()) != 0)
115 {
116 // If this vertex is won by player even and is decorated with `true`,
117 // then it stems from an equation (\nu X = true), which originally was (\nu X = X) before the default simplification (analogous for player odd).
118 if (G.strategy(u) == undefined_vertex() &&
119 ((!alpha && utilities::is_even(G.rank(u)) && G.decoration(u) == structure_graph::d_true)
120 || (alpha && utilities::is_odd(G.rank(u)) && G.decoration(u) == structure_graph::d_false)))
121 {
122 // We act as if the self-dependency is still there.
123 Ys.insert(G.find_vertex(u).formula());
124 }
125 // This vertex is won by alpha
126 if (G.strategy(u) != undefined_vertex()
127 && ((!alpha && G.decoration(u) == structure_graph::d_disjunction)
128 || (alpha && G.decoration(u) == structure_graph::d_conjunction)))
129 {
130 // The strategy is defined so only explore the strategy edge.
131 auto v = G.strategy(u);
132 if (G.rank(v) == data::undefined_index())
133 {
134 if (!mcrl2::utilities::detail::contains(done, v))
135 {
136 // explore all outgoing edges that are unranked
137 todo.insert(v);
138 }
139 }
140 else if (mapping.count(G.find_vertex(v).formula()) != 0)
141 {
142 // Insert the outgoing edge, but do not add it to the todo set to stop exploring this vertex.
143 Ys.insert(G.find_vertex(v).formula());
144 }
145 }
146 else
147 {
148 // Explore all edges.
149 for (structure_graph::index_type v: G.all_successors(u))
150 {
151 if (G.rank(v) == data::undefined_index())
152 {
153 if (!mcrl2::utilities::detail::contains(done, v))
154 {
155 // explore all outgoing edges that are unranked
156 todo.insert(v);
157 }
158 }
159 else if (mapping.count(G.find_vertex(v).formula()) != 0)
160 {
161 // Insert the outgoing edge, but do not add it to the todo set to stop exploring this vertex.
162 Ys.insert(G.find_vertex(v).formula());
163 }
164 }
165 }
166 }
167 else
168 {
169 // Explore all edges.
170 for (structure_graph::index_type v: G.all_successors(u))
171 {
172 if (G.rank(v) == data::undefined_index())
173 {
174 if (!mcrl2::utilities::detail::contains(done, v))
175 {
176 // explore all outgoing edges that are unranked
177 todo.insert(v);
178 }
179 }
180 else if (mapping.count(G.find_vertex(v).formula()) != 0)
181 {
182 // Insert the outgoing edge, but do not add it to the todo set to stop exploring this vertex.
183 Ys.insert(G.find_vertex(v).formula());
184 }
185 }
186 }
187 }
188 }
189
190 mCRL2log(log::debug) << "Ys := " << core::detail::print_set(Ys) << std::endl;
191
192 if (std::regex_match(static_cast<const std::string&>(Y.name()),
193 match,
194 mcrl2::pbes_system::detail::positive_or_negative))
195 {
196 // If Y in L return Y
197 mCRL2log(log::debug) << "rewrite_star " << Y << " is counter example equation (in L)" << std::endl;
198 return Y;
199 }
200 else
201 {
202 if (mcrl2::utilities::detail::contains(Ys, rewrite_PVI(Y, R)))
203 {
204 mCRL2log(log::debug) << "rewrite_star " << Y << " ( " << rewrite_PVI(Y, R) << ") is reachable"
205 << std::endl;
206 return Y;
207 }
208 else
209 {
210 if (alpha == 0)
211 {
212 // If Y is not reachable, replace it by false
213 mCRL2log(log::debug) << "rewrite_star " << Y << " " << rewrite_PVI(Y, R)
214 << " is not reachable, becomes false" << std::endl;
215 return false_();
216 }
217 else
218 {
219 // If Y is not reachable, replace it by true
220 mCRL2log(log::debug) << "rewrite_star " << Y << " " << rewrite_PVI(Y, R)
221 << " is not reachable, becomes true" << std::endl;
222 return true_();
223 }
224 }
225 }
226 }
227};
228}
229
231{
232public:
234 const pbes& p,
235 const structure_graph& SG,
236 bool _alpha,
237 const std::unordered_map<pbes_expression, structure_graph::index_type>& _mapping,
239 std::optional<data::rewriter> rewriter = std::nullopt,
240 const std::unordered_map<std::string, std::set<int>> R = {})
242 G(SG),
243 alpha(_alpha),
245 R(R)
246 {}
247 // TODO ensure that the PVIs in mapping match the shape of the
248 // vertices in G after they are rewritten with R.
249
251 const std::size_t thread_index,
252 const fixpoint_symbol& symbol,
254 const pbes_expression& phi) override
255 {
256 return compose_substitutions(pbesinst_structure_graph_algorithm::phi_substitution(thread_index, symbol, X, phi),
257 detail::rewrite_star_substitution(symbol, X, G, alpha, mapping, R));
258 }
259
260private:
262 bool alpha;
264 const std::unordered_map<std::string, std::set<int>> R;
265};
266
268{
269public:
271 const pbes& p,
272 const structure_graph& SG,
273 bool _alpha,
274 const std::unordered_map<pbes_expression, structure_graph::index_type>& _mapping,
276 std::optional<data::rewriter> rewriter = std::nullopt,
277 const std::unordered_map<std::string, std::set<int>> R = {})
279 G(SG),
280 alpha(_alpha),
282 R(R)
283 {}
284
286 const std::size_t thread_index,
287 const fixpoint_symbol& symbol,
289 const pbes_expression& phi) override
290 {
291 return compose_substitutions(pbesinst_structure_graph_algorithm::phi_substitution(thread_index, symbol, X, phi),
292 detail::rewrite_star_substitution(symbol, X, G, alpha, mapping, R));
293 }
294
295private:
297 bool alpha;
299 const std::unordered_map<std::string, std::set<int>> R;
300};
301
302} // namespace mcrl2::pbes_system
303
304#endif // MCRL2_PBES_PBESINST_LAZY_COUNTER_EXAMPLE_H
parameterized boolean equation system
Definition pbes.h:54
pbesinst_counter_example_structure_graph_algorithm2(const pbessolve_options &options, const pbes &p, const structure_graph &SG, bool _alpha, const std::unordered_map< pbes_expression, structure_graph::index_type > &_mapping, structure_graph &G, std::optional< data::rewriter > rewriter=std::nullopt, const std::unordered_map< std::string, std::set< int > > R={})
std::function< pbes_expression(const propositional_variable_instantiation &)> phi_substitution(const std::size_t thread_index, const fixpoint_symbol &symbol, const propositional_variable_instantiation &X, const pbes_expression &phi) override
const std::unordered_map< pbes_expression, structure_graph::index_type > & mapping
const std::unordered_map< pbes_expression, structure_graph::index_type > & mapping
std::function< pbes_expression(const propositional_variable_instantiation &)> phi_substitution(const std::size_t thread_index, const fixpoint_symbol &symbol, const propositional_variable_instantiation &X, const pbes_expression &phi) override
pbesinst_counter_example_structure_graph_algorithm(const pbessolve_options &options, const pbes &p, const structure_graph &SG, bool _alpha, const std::unordered_map< pbes_expression, structure_graph::index_type > &_mapping, structure_graph &G, std::optional< data::rewriter > rewriter=std::nullopt, const std::unordered_map< std::string, std::set< int > > R={})
Adds an optimization to pbesinst_structure_graph.
Variant of pbesinst that will compute a structure graph for a PBES. The result will be put in the str...
\brief A propositional variable instantiation
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:393
propositional_variable_instantiation rewrite_PVI(const propositional_variable_instantiation PVI, const std::unordered_map< std::string, std::set< int > > R)
For a given X(e) and set of redundant params R, returns a copy of X(e) without redundancy.
const pbes_expression & true_()
std::set< data::variable > find_free_variables(const pbes_system::pbes_expression &x)
Definition pbes.cpp:54
const pbes_expression & false_()
rewrite_star_substitution(const fixpoint_symbol &symbol, const propositional_variable_instantiation &X, const structure_graph &G, bool alpha, const std::unordered_map< pbes_expression, structure_graph::index_type > &mapping, const std::unordered_map< std::string, std::set< int > > &R)
pbes_expression operator()(const propositional_variable_instantiation &Y) const
const std::unordered_map< pbes_expression, structure_graph::index_type > & mapping