mCRL2
Loading...
Searching...
No Matches
bqnf2ppg_rewriter.h
Go to the documentation of this file.
1// Author(s): Gijs Kant
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/detail/bqnf2ppg_rewriter.h
10/// \brief Rewrites a PBES equation with expressions in Bounded Quantifier Normal Form (BQNF)
11/// to (a sequence of ) Parameterised Parity Game (PPG) equations.
12/// The transformation is described in [Kant & Van de Pol 2012].
13/// Possibly new equations are introduced. The resulting sequence of equations is available
14/// through the result() function.
15///
16/// DEPRECATED
17#ifndef MCRL2_PBES_DETAIL_BQNF2PPG_REWRITER_H
18#define MCRL2_PBES_DETAIL_BQNF2PPG_REWRITER_H
19
20#include "mcrl2/pbes/detail/bqnf_visitor.h"
21
22
23
24
25
26namespace mcrl2::pbes_system::detail {
27
29 {
30 /// \brief The equation type.
31 using equation_type = pbes_equation;
32 /// \brief The expression type of the equation.
33 using term_type = pbes_expression;
34
35 /// \brief The set of variable names already in use.
37 /// \brief A map from variable name prefix to the last suffix that has been added.
39 /// \brief The sequence of equations resulting from the transformation.
41
42 /// \brief Constructor.
43 /// \param p The PBES of which the equation is part. Used to avoid name clashes when introducing new variables.
45 {
46 for (const auto & eqn : p.equations()) {
47 equation_type e = eqn;
48 propositional_variable var = e.variable();
49 variable_names.insert(core::pp(var.name()));
50 }
51 }
52
53 /// \brief Returns the result of the transformation.
54 /// \return the sequence of equations resulting from the transformation.
56 return equations;
57 }
58
59
60 /// \brief Generates a fresh variable name, based on s (extending s).
61 /// \param s A string.
62 /// \return a fresh variable name.
64 std::string base; std::string name;
65 name = base = s;
66 int suffix = 1;
67 while (variable_names.find(name)!=variable_names.end()) {
68 if (variable_name_suffix.find(base) != variable_name_suffix.end()) {
69 suffix = variable_name_suffix[base] + 1;
70 }
71 variable_name_suffix[base] = suffix;
72 std::stringstream ss;
73 ss << base << "_" << suffix;
74 ss >> name;
75 }
76 variable_names.insert(name);
77 return name;
78 }
79
80
81 /// \brief Visits a disjunctive expression qexpr within a bounded universal quantifier expression e.
82 /// Rewrites the expression qexpr to PPG form and adds a universal quantifier over the variables qvars.
83 /// The resulting equations are added to the sequence of result equations.
84 /// \param sigma fixpoint symbol of the parent equation.
85 /// \param var propositional variable of the parent equation.
86 /// \param e the parent PBES expression.
87 /// \param qvars the quantifier variables of the quantifier in the parent expression.
88 /// \param qexpr the PBES expression within the quantifier expression.
89 /// \return true if the expression qexpr conforms to BQNF.
90 virtual bool visit_inner_implies(const fixpoint_symbol& sigma, const propositional_variable& var, const term_type& e, const data::variable_list& qvars, const term_type& qexpr)
91 {
92 bool result = true;
94 if (is_propositional_variable_instantiation(qexpr) || is_simple_expression(qexpr, false)) {
95 // Eqn of the form sigma X(d: D) = Forall l: D . phi => Y(h(d, l)), with phi a simple formula.
96 // Add sigma X(d) = e.
97 equation_type eqn = equation_type(sigma, var, e);
98 equations.push_back(eqn);
99 } else {
100 term_type phi = is_or(qexpr) ? true_() : false_();
101 term_type psi = qexpr;
102 if (is_or(qexpr) || is_imp(qexpr)) {
103 term_type l = pbes_system::accessors::left(qexpr);
104 term_type r = pbes_system::accessors::right(qexpr);
105 if (is_simple_expression(l, false)) {
106 phi = l;
107 psi = r;
108 }
109 }
110 if (is_inner_implies(psi)) {
111 // Eqn of the form sigma X(d: D) = Forall l: D . phi => Y(h(d, l)), with phi a simple formula.
112 // Add sigma X(d) = e.
113 equation_type eqn = equation_type(sigma, var, e);
114 equations.push_back(eqn);
115 } else if (!qvars.empty() || !(is_or(qexpr) ? is_true(phi) : is_false(phi))) {
116 std::string fresh_varname = fresh_variable_name(var.name());
117
118 data::variable_list variable_parameters = var.parameters() + qvars;
119 // Create fresh propositional variable.
120 propositional_variable fresh_var =
121 propositional_variable(fresh_varname, variable_parameters);
122 propositional_variable_instantiation fresh_var_instantiation =
123 propositional_variable_instantiation(fresh_varname, data::data_expression_list(variable_parameters));
124 term_type expr;
125 if (is_or(qexpr)) {
126 if (is_true(phi)) {
127 expr = fresh_var_instantiation;
128 } else {
129 expr = or_(phi, fresh_var_instantiation);
130 }
131 } else {
132 if (is_false(phi)) {
133 expr = fresh_var_instantiation;
134 } else {
135 expr = imp(phi, fresh_var_instantiation);
136 }
137 }
138 if (!qvars.empty()) {
139 expr = optimized_forall(qvars, expr);
140 }
141
142 // Add sigma X(d) = forall (qvars) . phi => fresh_X(d+qvars).
143 equation_type eqn = equation_type(sigma, var, expr);
144 equations.push_back(eqn);
145
146 // Rewrite new equation: sigma fresh_X(d+qvars) = psi.
147 equation_type new_eqn = equation_type(sigma, fresh_var, psi);
149 } else {
150 //std::clog << "visit_inner_implies: false." << std::endl;
151 // qexpr not of the form phi /\ psi
152 result = false;
153 }
154 }
156 return result;
157 }
158
159
160 /// \brief Visits a bounded universal quantifier expression. Rewrites the expression to PPG form by
161 /// collecting quantified variables and calling visit_inner_implies.
162 /// The resulting equations are added to the sequence of result equations.
163 /// \param sigma fixpoint symbol of the parent equation.
164 /// \param var propositional variable of the parent equation.
165 /// \param e a PBES expression.
166 /// \return true if the expression e conforms to BQNF.
167 bool
168 visit_bounded_forall(const fixpoint_symbol& sigma, const propositional_variable& var, const term_type& e) override
169 {
171 assert(is_forall(e));
172 data::variable_list qvars = atermpp::down_cast<forall>(e).variables();
173 term_type qexpr = pbes_system::accessors::arg(e);
174 while (is_forall(qexpr)) {
175 qvars = qvars + atermpp::down_cast<forall>(qexpr).variables();
177 }
178 bool result = visit_inner_implies(sigma, var, e, qvars, qexpr);
179 if (!result) {
180 std::clog << "Unexpected result: expression not in form phi => psi: " << pp(e) << std::endl;
181 throw(std::runtime_error("Unexpected result: expression not in form phi => psi."));
182 }
184 return result;
185 }
186
187
188
189 /// \brief Visits a conjunctive expression qexpr within a bounded existential quantifier expression e.
190 /// Rewrites the expression qexpr to PPG form and adds a existential quantifier over the variables qvars.
191 /// The resulting equations are added to the sequence of result equations.
192 /// \param sigma fixpoint symbol of the parent equation.
193 /// \param var propositional variable of the parent equation.
194 /// \param e the parent PBES expression.
195 /// \param qvars the quantifier variables of the quantifier in the parent expression.
196 /// \param qexpr the PBES expression within the quantifier expression.
197 /// \return true if the expression qexpr conforms to BQNF.
198 virtual bool visit_inner_and_quantified(const fixpoint_symbol& sigma, const propositional_variable& var, const term_type& e, const data::variable_list& qvars, const term_type& qexpr)
199 {
200 bool result = true;
202 if (is_propositional_variable_instantiation(qexpr) || is_simple_expression(qexpr, false)) {
203 // Eqn of the form sigma X(d: D) = Exists l: D . phi && Y(h(d, l)), with phi a simple formula.
204 // Add sigma X(d) = e.
205 equation_type eqn = equation_type(sigma, var, e);
206 equations.push_back(eqn);
207 } else {
208 term_type phi = true_();
209 term_type psi = qexpr;
210 if (is_and(qexpr)) {
211 term_type l = pbes_system::accessors::left(qexpr);
212 term_type r = pbes_system::accessors::right(qexpr);
213 bool l_is_simple = is_simple_expression(l, false);
214 if (l_is_simple) {
215 phi = l;
216 psi = r;
217 }
218 }
219 if (is_inner_and(psi)) {
220 // Eqn of the form sigma X(d: D) = Exists l: D . phi && Y(h(d, l)), with phi a simple formula.
221 // Add sigma X(d) = e.
222 equation_type eqn = equation_type(sigma, var, e);
223 equations.push_back(eqn);
224 } else if (!qvars.empty() || !is_true(phi)) {
225 std::string fresh_varname = fresh_variable_name(var.name());
226 data::variable_list variable_parameters = var.parameters() + qvars;
227 // Create fresh propositional variable.
228 propositional_variable fresh_var =
229 propositional_variable(fresh_varname, variable_parameters);
230 propositional_variable_instantiation fresh_var_instantiation =
231 propositional_variable_instantiation(fresh_varname, data::data_expression_list(variable_parameters));
232 term_type expr;
233 if (is_true(phi)) {
234 expr = fresh_var_instantiation;
235 } else {
236 expr = and_(phi, fresh_var_instantiation);
237 }
238 if (!qvars.empty()) {
239 expr = optimized_exists(qvars, expr);
240 }
241
242 // Add sigma X(d) = exists (qvars) . phi && fresh_X(d+qvars).
243 equation_type eqn = equation_type(sigma, var, expr);
244 equations.push_back(eqn);
245
246 // Rewrite new equation: sigma fresh_X(d+qvars) = psi.
247 equation_type new_eqn = equation_type(sigma, fresh_var, psi);
249 } else {
250 //std::clog << "visit_inner_and: false." << std::endl;
251 // qexpr not of the form phi => psi
252 result = false;
253 }
254 }
256 return result;
257 }
258
259
260 /// \brief Visits a bounded existential quantifier expression. Rewrites the expression to PPG form by
261 /// collecting quantified variables and calling visit_inner_and.
262 /// The resulting equations are added to the sequence of result equations.
263 /// \param sigma fixpoint symbol of the parent equation.
264 /// \param var propositional variable of the parent equation.
265 /// \param e a PBES expression.
266 /// \return true if the expression e conforms to BQNF.
267 bool
268 visit_bounded_exists(const fixpoint_symbol& sigma, const propositional_variable& var, const term_type& e) override
269 {
271 assert(is_exists(e));
272 term_type qexpr = pbes_system::accessors::arg(e);
273 data::variable_list qvars = atermpp::down_cast<exists>(e).variables();
274 while (is_exists(qexpr)) {
275 qvars = qvars + atermpp::down_cast<exists>(qexpr).variables();
277 }
278 bool result = visit_inner_and_quantified(sigma, var, e, qvars, qexpr);
279 if (!result) {
280 std::clog << "Unexpected result: expression not in form phi /\\ psi: " << pp(e) << std::endl;
281 throw(std::runtime_error("Unexpected result: expression not in form phi /\\ psi."));
282 }
284 return result;
285 }
286
287 /// \brief Rewrites an inner bounded universal quantifier expression to PPG form.
288 /// Returns the rewritten expression and possibly a newly introduced equation.
289 /// The new equation is itself not rewritten yet.
290 /// \param sigma fixpoint symbol of the parent equation.
291 /// \param var propositional variable of the parent equation.
292 /// \param e a PBES expression.
293 /// \param dummy dummy equation, returned as equation if no equation is generated.
294 /// \return a pair consisting of the expression that replaces the original expression e
295 /// and an equation that is possibly introduced as result of the transformation (or the
296 /// dummy equation if no new equation is created).
298 {
300 term_type qexpr = e;
301 data::variable_list qvars;
302 while (is_forall(qexpr)) {
303 qvars = qvars + atermpp::down_cast<forall>(qexpr).variables();
305 }
306
307 term_type expr;
308 equation_type eqn = dummy;
309
310 if (is_propositional_variable_instantiation(qexpr) || is_simple_expression(qexpr, false)) {
311 // Eqn of the form phi => Y(h(d, l)), with phi a simple formula.
312 expr = e;
313 } else {
314 term_type phi = is_or(qexpr) ? true_() : false_();
315 term_type psi = qexpr;
316 if (is_or(qexpr) || is_imp(qexpr)) {
317 term_type l = pbes_system::accessors::left(qexpr);
318 term_type r = pbes_system::accessors::right(qexpr);
319 if (is_simple_expression(l, false)) {
320 phi = l;
321 psi = r;
322 }
323 }
324 if (is_inner_implies(psi)) {
325 // Eqn of the form sigma X(d: D) = Forall l: D . phi => Y(h(d, l)), with phi a simple formula.
326 expr = e;
327 } else {
328 std::string fresh_varname = fresh_variable_name(var.name());
329 data::variable_list variable_parameters = var.parameters() + qvars;
330 // Create fresh propositional variable.
331 propositional_variable fresh_var =
332 propositional_variable(fresh_varname, variable_parameters);
333 propositional_variable_instantiation fresh_var_instantiation =
334 propositional_variable_instantiation(fresh_varname, data::data_expression_list(variable_parameters));
335 // expr = forall (qvars) . phi => fresh_X(d+qvars).
336 if (is_or(qexpr)) {
337 if (is_true(phi)) {
338 expr = fresh_var_instantiation;
339 } else {
340 expr = or_(phi, fresh_var_instantiation);
341 }
342 } else {
343 if (is_false(phi)) {
344 expr = fresh_var_instantiation;
345 } else {
346 expr = imp(phi, fresh_var_instantiation);
347 }
348 }
349 if (is_forall(e)) {
350 expr = optimized_forall(qvars, expr);
351 }
352
353 // New equation: sigma fresh_X(d+qvars) = psi.
354 eqn = equation_type(sigma, fresh_var, psi);
355 }
356 }
358 return std::make_pair(expr, eqn);
359 }
360
361 /// \brief Visits a conjunctive expression. Rewrites the expression to PPG form.
362 /// The resulting equations are added to the sequence of result equations.
363 /// \param sigma fixpoint symbol of the parent equation.
364 /// \param var propositional variable of the parent equation.
365 /// \param e a PBES expression.
366 /// \return true if the expression e conforms to BQNF.
367 bool visit_and(const fixpoint_symbol& sigma, const propositional_variable& var, const term_type& e) override
368 {
370 equation_type dummy;
371 term_type conjunction = true_();
372 std::vector<equation_type> new_eqns;
373 std::vector<term_type> conjuncts = split_conjuncts(e);
374 for (auto expr: conjuncts)
375 {
376 std::pair<term_type, equation_type> p = rewrite_inner_bounded_forall(sigma, var, expr, dummy);
377 if (is_true(conjunction)) {
378 conjunction = p.first;
379 } else {
380 conjunction = and_(conjunction, p.first);
381 }
382 if (p.second != dummy) {
383 new_eqns.push_back(p.second);
384 }
385 }
386 // Add conjunction with simplified terms.
387 equation_type eqn = equation_type(sigma, var, conjunction);
388 equations.push_back(eqn);
389 for (const auto& new_eqn: new_eqns)
390 {
391 // Rewrite new equation.
392 visit_bqnf_equation(new_eqn);
393 }
395 return true;
396 }
397
398 /// \brief Rewrites an inner bounded existential quantifier expression to PPG form.
399 /// Returns the rewritten expression and possibly a newly introduced equation.
400 /// The new equation is itself not rewritten yet.
401 /// \param sigma fixpoint symbol of the parent equation.
402 /// \param var propositional variable of the parent equation.
403 /// \param e a PBES expression.
404 /// \param dummy dummy equation, returned as equation if no equation is generated.
405 /// \return a pair consisting of the expression that replaces the original expression e
406 /// and an equation that is possibly introduced as result of the transformation (or the
407 /// dummy equation if no new equation is created).
409 {
411 term_type qexpr = e;
412 data::variable_list qvars;
413 while (is_exists(qexpr)) {
414 qvars = qvars + atermpp::down_cast<exists>(qexpr).variables();
416 }
417
418 term_type expr;
419 equation_type eqn = dummy;
420
421 if (is_propositional_variable_instantiation(qexpr) || is_simple_expression(qexpr, false)) {
422 // Eqn of the form phi && Y(h(d, l)), with phi a simple formula.
423 expr = e;
424 } else {
425 term_type phi = true_();
426 term_type psi = qexpr;
427 if (is_and(qexpr)) {
428 term_type l = pbes_system::accessors::left(qexpr);
429 term_type r = pbes_system::accessors::right(qexpr);
430 if (is_simple_expression(l, false)) {
431 phi = l;
432 psi = r;
433 }
434 }
435 if (is_inner_and(psi)) {
436 // Eqn of the form sigma X(d: D) = Forall l: D . phi => Y(h(d, l)), with phi a simple formula.
437 expr = e;
438 } else {
439 std::string fresh_varname = fresh_variable_name(var.name());
440 data::variable_list variable_parameters = var.parameters() + qvars;
441 // Create fresh propositional variable.
442 propositional_variable fresh_var =
443 propositional_variable(fresh_varname, variable_parameters);
444 propositional_variable_instantiation fresh_var_instantiation =
445 propositional_variable_instantiation(fresh_varname, data::data_expression_list(variable_parameters));
446 // expr = forall (qvars) . phi => fresh_X(d+qvars).
447 if (is_true(phi)) {
448 expr = fresh_var_instantiation;
449 } else {
450 expr = and_(phi, fresh_var_instantiation);
451 }
452 if (is_exists(e)) {
453 expr = optimized_exists(qvars, expr);
454 }
455
456 // New equation: sigma fresh_X(d+qvars) = psi.
457 eqn = equation_type(sigma, fresh_var, psi);
458 }
459 }
461 return std::make_pair(expr, eqn);
462 }
463
464 /// \brief Visits a disjunctive expression. Rewrites the expression to PPG form.
465 /// The resulting equations are added to the sequence of result equations.
466 /// \param sigma fixpoint symbol of the parent equation.
467 /// \param var propositional variable of the parent equation.
468 /// \param e a PBES expression.
469 /// \return true if the expression e conforms to BQNF.
470 bool visit_or(const fixpoint_symbol& sigma, const propositional_variable& var, const term_type& e) override
471 {
473 equation_type dummy;
474 term_type disjunction = false_();
475 std::vector<equation_type> new_eqns;
476 std::vector<term_type> disjuncts = split_disjuncts(e);
477 for (auto expr: disjuncts)
478 {
479 std::pair<term_type, equation_type> p = rewrite_inner_bounded_exists(sigma, var, expr, dummy);
480 if (is_false(disjunction)) {
481 disjunction = p.first;
482 } else {
483 disjunction = or_(disjunction, p.first);
484 }
485 if (p.second != dummy) {
486 new_eqns.push_back(p.second);
487 }
488 }
489 // Add disjunction with simplified terms.
490 equation_type eqn = equation_type(sigma, var, disjunction);
491 equations.push_back(eqn);
492 for (const auto& new_eqn: new_eqns)
493 {
494 // Rewrite new equation.
495 visit_bqnf_equation(new_eqn);
496 }
498 return true;
499 }
500
501 /// \brief Visits a BQNF expression. Rewrites the expression to PPG form.
502 /// The resulting equations are added to the sequence of result equations.
503 /// \param sigma fixpoint symbol of the parent equation.
504 /// \param var propositional variable of the parent equation.
505 /// \param e a PBES expression.
506 /// \return true if the right hand side of the equation is in BQNF.
507 bool
508 visit_bqnf_expression(const fixpoint_symbol& sigma, const propositional_variable& var, const term_type& e) override
509 {
511 if (is_propositional_variable_instantiation(e) || is_simple_expression(e, false)) {
512 // Eqn of the form sigma X(d: D) = phi && Y(h(d, l)), with phi a simple formula.
513 // Add sigma X(d) = e.
514 equation_type eqn = equation_type(sigma, var, e);
515 equations.push_back(eqn);
516 } else if (is_forall(e) || is_exists(e)) {
517 visit_bounded_quantifier(sigma, var, e);
518 } else if (is_or(e) || is_imp(e)) {
519 data::variable_list empty_seq;
520 visit_inner_implies(sigma, var, e, empty_seq, e) || visit_or(sigma, var, e);
521 } else if (is_and(e)) {
522 data::variable_list empty_seq;
523 visit_inner_and_quantified(sigma, var, e, empty_seq, e) || visit_and(sigma, var, e);
524 }
526 return true;
527 }
528
529 /// \brief Visits a BQNF equation. Rewrites the equation to a PPG equation.
530 /// The resulting equations are added to the sequence of result equations.
531 /// \param eqn a PBES equation
532 /// \return true if the right hand side of the equation is in BQNF.
533 bool visit_bqnf_equation(const equation_type& eqn) override
534 {
535 const fixpoint_symbol& sigma = eqn.symbol();
536 const propositional_variable& var = eqn.variable();
537 const term_type& e = eqn.formula();
538 if (is_propositional_variable_instantiation(e) || is_simple_expression(e, false)) {
539 // Eqn of the form sigma X(d: D) = g(d) && Y(h(d)), with g(d) a simple formula
540 // Add eqn
541 equations.push_back(eqn);
542 } else {
543 // Postpone processing of the equation to the next level.
544 visit_bqnf_expression(sigma, var, e);
545 }
546 return true;
547 }
548
549 };
550
551} // namespace mcrl2::pbes_system::detail
552
553
554
555
556
557#endif // MCRL2_PBES_DETAIL_BQNF2PPG_REWRITER_H
\brief The and operator for pbes expressions
and_(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
\brief The implication operator for pbes expressions
imp(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
\brief The or operator for pbes expressions
or_(const pbes_expression &left, const pbes_expression &right)
\brief Constructor Z14.
const pbes_expression & formula() const
Returns the predicate formula on the right hand side of the equation.
pbes_equation(const fixpoint_symbol &symbol, const propositional_variable &variable, const pbes_expression &expr)
Constructor.
const fixpoint_symbol & symbol() const
Returns the fixpoint symbol of the equation.
const propositional_variable & variable() const
Returns the pbes variable of the equation.
pbes_expression & operator=(pbes_expression &&) noexcept=default
pbes_expression & operator=(const pbes_expression &) noexcept=default
parameterized boolean equation system
Definition pbes.h:54
\brief A propositional variable instantiation
\brief A propositional variable declaration
The namespace for accessor functions on pbes expressions.
const pbes_expression & arg(const pbes_expression &t)
Returns the pbes expression argument of expressions of type not, exists and forall.
const pbes_expression & left(const pbes_expression &t)
Returns the left hand side of an expression of type and, or or imp.
const pbes_expression & right(const pbes_expression &t)
Returns the right hand side of an expression of type and, or or imp.
static void inc_indent()
Increases the current indent level.
static void dec_indent()
Decreases the current indent level.
const pbes_expression & true_()
bool is_exists(const atermpp::aterm &x)
bool is_or(const atermpp::aterm &x)
bool is_forall(const atermpp::aterm &x)
bool is_false(const pbes_expression &t)
Test for the value false.
pbes_expression optimized_exists(const data::variable_list &l, const pbes_expression &p, bool remove_variables=false)
Make an existential quantification If l is empty, p is returned.
bool is_propositional_variable_instantiation(const atermpp::aterm &x)
bool is_and(const atermpp::aterm &x)
bool is_imp(const atermpp::aterm &x)
pbes_expression optimized_forall(const data::variable_list &l, const pbes_expression &p, bool remove_variables=false)
Make a universal quantification If l is empty, p is returned.
bool is_true(const pbes_expression &t)
Test for the value true.
const pbes_expression & false_()
bool visit_bqnf_equation(const equation_type &eqn) override
Visits a BQNF equation. Rewrites the equation to a PPG equation. The resulting equations are added to...
virtual bool visit_inner_and_quantified(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e, const data::variable_list &qvars, const term_type &qexpr)
Visits a conjunctive expression qexpr within a bounded existential quantifier expression e....
bool visit_bounded_forall(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e) override
Visits a bounded universal quantifier expression. Rewrites the expression to PPG form by collecting q...
std::set< std::string > variable_names
The set of variable names already in use.
virtual std::vector< equation_type > result()
Returns the result of the transformation.
bool visit_bqnf_expression(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e) override
Visits a BQNF expression. Rewrites the expression to PPG form. The resulting equations are added to t...
bool visit_and(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e) override
Visits a conjunctive expression. Rewrites the expression to PPG form. The resulting equations are add...
virtual std::pair< term_type, equation_type > rewrite_inner_bounded_exists(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e, const equation_type &dummy)
Rewrites an inner bounded existential quantifier expression to PPG form. Returns the rewritten expres...
std::vector< equation_type > equations
The sequence of equations resulting from the transformation.
virtual bool visit_inner_implies(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e, const data::variable_list &qvars, const term_type &qexpr)
Visits a disjunctive expression qexpr within a bounded universal quantifier expression e....
std::map< std::string, int > variable_name_suffix
A map from variable name prefix to the last suffix that has been added.
virtual std::pair< term_type, equation_type > rewrite_inner_bounded_forall(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e, const equation_type &dummy)
Rewrites an inner bounded universal quantifier expression to PPG form. Returns the rewritten expressi...
bool visit_or(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e) override
Visits a disjunctive expression. Rewrites the expression to PPG form. The resulting equations are add...
bool visit_bounded_exists(const fixpoint_symbol &sigma, const propositional_variable &var, const term_type &e) override
Visits a bounded existential quantifier expression. Rewrites the expression to PPG form by collecting...
virtual std::string fresh_variable_name(const std::string &s)
Generates a fresh variable name, based on s (extending s).
A visitor class for PBES equations in BQNF. There is a visit_<node> function for each type of node....
virtual bool visit_bounded_quantifier(const fixpoint_symbol &sigma, const propositional_variable &var, const pbes_expression &e)
Visits a bounded quantifier expression.
static bool is_inner_implies(const pbes_expression &e)
Determines if an expression if of the form phi => psi or of the form phi \/ psi where phi is a simple...
static bool is_inner_and(const pbes_expression &e)
Determines if an expression if of the form phi /\ psi where phi is a simple expression and psi is an ...