12#ifndef MCRL2_PBES_BISIMULATION_H
13#define MCRL2_PBES_BISIMULATION_H
15#include "mcrl2/atermpp/aterm.h"
16#include "mcrl2/data/data_expression.h"
17#include "mcrl2/data/merge_data_specifications.h"
18#include "mcrl2/lps/replace.h"
19#include "mcrl2/pbes/detail/lps2pbes_utility.h"
20#include "mcrl2/pbes/join.h"
51 std::ostringstream out;
52 for (
auto i = l.begin(); i != l.end(); ++i)
54 out << (i != l.begin() ?
"-" :
"") << std::string(i->label().name());
56 std::string result = out.str();
70 auto j = summand_names.find(t);
71 assert(j != summand_names.end());
103 for (
const lps::action_summand& s: p.action_summands())
105 std::string name = generator(action_list_name(s.multi_action().actions()));
106 summand_names[&s] = name;
363 std::vector<pbes_expression> result;
364 for (
auto i = p.action_summands().begin(); i != p.action_summands().end(); ++i)
366 data::data_expression ci = i->condition();
367 const data::variable_list& d = p.process_parameters();
368 data::variable_list e = i->summation_variables();
369 const data::variable_list& d1 = q.process_parameters();
370 pbes_expression expr;
371 optimized_imp(expr, atermpp::down_cast<pbes_expression>(ci), var(Y(p, q, i), d + d1 + e));
372 expr = make_forall_(e, expr);
373 result.push_back(expr);
375 return optimized_join_and(result.begin(), result.end());
385 const data::variable_list& d1 = q.process_parameters();
386 data::data_expression_list gi = i->next_state(p.process_parameters());
389 std::vector<pbes_expression> v;
391 for (
auto j = q.action_summands().begin(); j != q.action_summands().end(); ++j)
397 data::data_expression cj = j->condition();
398 data::variable_list e1 = j->summation_variables();
399 data::data_expression_list gj = j->next_state(q.process_parameters());
400 optimized_and(expr, atermpp::down_cast<pbes_expression>(cj), var(X(p, q), gi + gj));
401 expr = make_exists_(e1, expr);
404 optimized_or(expr, optimized_join_or(v.begin(), v.end()), var(X(p, q), gi + d1));
409 std::vector<pbes_expression> v;
410 for (
auto j = q.action_summands().begin(); j != q.action_summands().end(); ++j)
412 data::data_expression cj = j->condition();
413 data::variable_list e1 = j->summation_variables();
414 data::data_expression_list gj = j->next_state(q.process_parameters());
415 lps::multi_action ai = i->multi_action();
416 lps::multi_action aj = j->multi_action();
417 pbes_expression expr;
418 optimized_and(expr, atermpp::down_cast<pbes_expression>(cj), equals(ai, aj));
419 optimized_and(expr, expr, var(X(p, q), gi + gj));
420 expr = make_exists_(e1, expr);
423 return optimized_join_or(v.begin(), v.end());
434 std::vector<pbes_expression> v;
436 const data::variable_list& d = p.process_parameters();
437 const data::variable_list& d1 = q.process_parameters();
438 data::variable_list e = i->summation_variables();
439 for (
auto j = q.action_summands().begin(); j != q.action_summands().end(); ++j)
445 data::data_expression cj = j->condition();
446 data::variable_list e1 = j->summation_variables();
447 data::data_expression_list gj = j->next_state(q.process_parameters());
448 optimized_and(expr, atermpp::down_cast<pbes_expression>(cj), var(Y(p, q, i),
449 variable_list_to_data_expression_list(d) +
451 data::variable_list_to_data_expression_list(e)));
452 expr = make_exists_(e1, expr);
456 optimized_and(expr, var(X(p, q), d + d1), step(p, q, i));
457 optimized_or(expr, optimized_join_or(v.begin(), v.end()), expr);
473 resolve_name_clashes(model1, spec1,
true);
474 model1.data() = dataspec;
475 spec1.data() = dataspec;
476 lps::normalize_sorts(model1, model1.data());
477 lps::normalize_sorts(spec1, spec1.data());
483 const data::variable_list& d = m.process_parameters();
484 const data::variable_list& d1 = s.process_parameters();
485 std::vector<pbes_equation> equations;
491 equations.emplace_back(nu(), propositional_variable(X(m, s), d + d1), expr);
492 equations.emplace_back(nu(), propositional_variable(X(s, m), d1 + d), var(X(m, s), d + d1));
495 for (
auto i = m.action_summands().begin(); i != m.action_summands().end(); ++i)
497 data::variable_list e = i->summation_variables();
498 pbes_equation e1(mu(), propositional_variable(Y(m, s, i), d + d1 + e), close(m, s, i));
499 equations.push_back(e1);
501 for (
auto i = s.action_summands().begin(); i != s.action_summands().end(); ++i)
503 data::variable_list e = i->summation_variables();
504 pbes_equation e1(mu(), propositional_variable(Y(s, m, i), d1 + d + e), close(s, m, i));
505 equations.push_back(e1);
508 return build_pbes(equations, model1, spec1);
536 std::vector<pbes_expression> result;
537 for (
auto i = p.action_summands().begin(); i != p.action_summands().end(); ++i)
539 data::data_expression ci = i->condition();
540 data::variable_list e = i->summation_variables();
541 pbes_expression expr;
542 optimized_imp(expr, atermpp::down_cast<pbes_expression>(ci), step(p, q, i));
543 expr = make_forall_(e, expr);
544 result.push_back(expr);
546 return optimized_join_and(result.begin(), result.end());
556 data::data_expression_list gi = i->next_state(p.process_parameters());
558 std::vector<pbes_expression> result;
559 for (
auto j = q.action_summands().begin(); j != q.action_summands().end(); ++j)
561 data::data_expression cj = j->condition();
562 data::variable_list e1 = j->summation_variables();
563 data::data_expression_list gj = j->next_state(q.process_parameters());
564 lps::multi_action ai = i->multi_action();
565 lps::multi_action aj = j->multi_action();
566 pbes_expression expr;
567 optimized_and(expr, atermpp::down_cast<pbes_expression>(cj), equals(ai, aj));
568 optimized_and(expr, expr, var(X(p, q), gi + gj));
569 expr = make_exists_(e1, expr);
570 result.push_back(expr);
572 return optimized_join_or(result.begin(), result.end());
582 resolve_name_clashes(model, spec1,
true);
587 const data::variable_list& d = m.process_parameters();
588 const data::variable_list& d1 = s.process_parameters();
589 std::vector<pbes_equation> equations;
595 equations.emplace_back(nu(), propositional_variable(X(m, s), d + d1), expr);
596 equations.emplace_back(nu(), propositional_variable(X(s, m), d1 + d), var(X(m, s), d + d1));
598 return build_pbes(equations, model, spec1);
629 std::vector<pbes_expression> result;
630 for (
auto i = p.action_summands().begin(); i != p.action_summands().end(); ++i)
632 data::data_expression ci = i->condition();
633 const data::variable_list& d = p.process_parameters();
634 data::variable_list e = i->summation_variables();
635 const data::variable_list& d1 = q.process_parameters();
636 pbes_expression expr;
637 optimized_imp(expr, atermpp::down_cast<pbes_expression>(ci), var(Y1(p, q, i), d + d1 + e));
638 expr = make_forall_(e, expr);
639 result.push_back(expr);
641 return optimized_join_and(result.begin(), result.end());
651 const data::variable_list& d1 = q.process_parameters();
652 data::data_expression_list gi = i->next_state(p.process_parameters());
656 return close2(p, q, i, gi, data::data_expression_list(d1.begin(), d1.end()));
660 std::vector<pbes_expression> v;
661 for (
auto j = q.action_summands().begin(); j != q.action_summands().end(); ++j)
663 data::data_expression cj = j->condition();
664 data::variable_list e1 = j->summation_variables();
665 data::data_expression_list gj = j->next_state(q.process_parameters());
666 lps::multi_action aj(j->multi_action().actions());
667 pbes_expression expr;
668 optimized_and(expr, atermpp::down_cast<pbes_expression>(cj), equals(ai, aj)), close2(p, q, i, gi, gj);
669 optimized_and(expr, expr, close2(p, q, i, gi, gj));
670 expr = make_exists_(e1, expr);
673 return optimized_join_or(v.begin(), v.end());
684 std::vector<pbes_expression> v;
686 data::variable_list e = i->summation_variables();
687 const data::variable_list& d = p.process_parameters();
688 const data::variable_list& d1 = q.process_parameters();
689 for (
auto j = q.action_summands().begin(); j != q.action_summands().end(); ++j)
695 data::data_expression cj = j->condition();
696 data::variable_list e1 = j->summation_variables();
697 data::data_expression_list gj = j->next_state(d1);
698 optimized_and(expr, atermpp::down_cast<pbes_expression>(cj), var(Y1(p, q, i),
699 data::variable_list_to_data_expression_list(d) +
701 data::variable_list_to_data_expression_list(e)));
702 expr = make_exists_(e1, expr);
705 optimized_or(expr, optimized_join_or(v.begin(), v.end()), step(p, q, i));
718 const data::variable_list& parameters = q.process_parameters();
719 data::mutable_map_substitution<> sigma;
720 make_substitution(parameters, d1, sigma);
722 for (
const data::variable& v: data::find_free_variables(d1))
724 id_generator.add_identifier(v.name());
727 std::vector<pbes_expression> v;
730 for (
auto j = q.action_summands().begin(); j != q.action_summands().end(); ++j)
738 data::data_expression cj = j->condition();
739 data::data_expression_list gj = j->next_state(q.process_parameters());
740 data::variable_list e1 = j->summation_variables();
743 if (d1 != data::data_expression_list(parameters.begin(), parameters.end()))
745 cj = data::replace_variables_capture_avoiding(cj, sigma, id_generator);
746 gj = data::replace_variables_capture_avoiding(gj, sigma, id_generator);
750 std::vector<data::variable> tmp;
751 for (
const data::variable& w: e1)
753 tmp.emplace_back(m_generator(std::string(w.name())), w.sort());
755 data::variable_list e11(tmp.begin(), tmp.end());
757 data::mutable_map_substitution<> sigma1;
758 make_substitution(e1, e11 | std::views::transform([](
const data::variable& v) {
return atermpp::down_cast<data::data_expression>(v); }), sigma1);
759 for (
const data::variable& w: e11)
761 id_generator.add_identifier(w.name());
763 data::data_expression cj_new = data::replace_variables_capture_avoiding(cj, sigma1, id_generator);
764 data::data_expression_list gj_new = data::replace_variables_capture_avoiding(gj, sigma1, id_generator);
766 optimized_and(expr, atermpp::down_cast<pbes_expression>(cj_new), var(Y2(p, q, i), d + gj_new));
767 expr = make_exists_(e11, expr);
770 optimized_or(expr, var(X(p, q), d + d1), optimized_join_or(v.begin(), v.end()));
781 resolve_name_clashes(model, spec1,
true);
786 m_generator.clear_context();
787 m_generator.add_identifiers(data::function_and_mapping_identifiers(model.data()));
788 m_generator.add_identifiers(data::function_and_mapping_identifiers(spec.data()));
789 m_generator.add_identifiers(lps::find_identifiers(model));
790 m_generator.add_identifiers(lps::find_identifiers(spec));
792 data::variable_list
const& d = m.process_parameters();
793 data::variable_list
const& d1 = s.process_parameters();
794 std::vector<pbes_equation> equations;
799 equations.emplace_back(nu(), propositional_variable(X(m, s), d + d1), expr);
800 equations.emplace_back(nu(), propositional_variable(X(s, m), d1 + d), var(X(m, s), d + d1));
803 for (
auto i = m.action_summands().begin(); i != m.action_summands().end(); ++i)
805 data::variable_list e = i->summation_variables();
806 pbes_equation e1(mu(), propositional_variable(Y1(m, s, i), d + d1 + e), close1(m, s, i));
807 pbes_equation e2(mu(), propositional_variable(Y2(m, s, i), d + d1), close2(m, s, i, data::data_expression_list(d.begin(), d.end()), data::data_expression_list(d1.begin(), d1.end())));
808 equations.push_back(e1);
809 equations.push_back(e2);
811 for (
auto i = s.action_summands().begin(); i != s.action_summands().end(); ++i)
813 data::variable_list e = i->summation_variables();
814 pbes_equation e1(mu(), propositional_variable(Y1(s, m, i), d1 + d + e), close1(s, m, i));
815 pbes_equation e2(mu(), propositional_variable(Y2(s, m, i), d1 + d), close2(s, m, i, data::data_expression_list(d1.begin(), d1.end()), data::data_expression_list(d.begin(), d.end())));
816 equations.push_back(e1);
817 equations.push_back(e2);
820 return build_pbes(equations, model, spec1);
849 resolve_name_clashes(model, spec1,
true);
854 data::variable_list
const& d = m.process_parameters();
855 data::variable_list
const& d1 = s.process_parameters();
856 std::vector<pbes_equation> equations;
861 optimized_and(expr,
match(m, s),
match(s, m));
862 equations.emplace_back(nu(), propositional_variable(X(m, s), d + d1), expr);
863 equations.emplace_back(nu(), propositional_variable(X(s, m), d1 + d), var(X(m, s), d + d1));
866 for (
auto i = m.action_summands().begin(); i != m.action_summands().end(); ++i)
868 data::variable_list e = i->summation_variables();
869 pbes_equation e1(mu(), propositional_variable(Y(m, s, i), d + d1 + e), close(m, s, i));
870 equations.push_back(e1);
872 for (
auto i = s.action_summands().begin(); i != s.action_summands().end(); ++i)
874 data::variable_list e = i->summation_variables();
875 pbes_equation e1(mu(), propositional_variable(Y(s, m, i), d1 + d + e), close(s, m, i));
876 equations.push_back(e1);
879 return build_pbes(equations, model, spec1);
Identifier generator that stores the identifiers of the context in a set. Using the operator()() and ...
LPS summand containing a multi-action.
\brief A timed multi-action
Linear process specification.
Base class for bisimulation algorithms.
const lps::linear_process * model_ptr
Store the address of the model.
name_map summand_names
Maps summands to strings.
std::string process_name(const lps::linear_process &p) const
Returns a name of a linear process.
std::string summand_name(my_iterator i) const
Returns the name of a summand.
bool is_from_model(const lps::linear_process &p) const
Returns true if p is the linear process of the model.
std::string action_list_name(const process::action_list &l) const
Generates a name for an action_list.
void set_summand_names(const lps::linear_process &p)
Used for initializing summand names.
Algorithm class for branching bisimulation.
pbes_expression close(const lps::linear_process &p, const lps::linear_process &q, my_iterator i) const
The close function.
pbes_expression match(const lps::linear_process &p, const lps::linear_process &q) const
The match function.
pbes_expression step(const lps::linear_process &p, const lps::linear_process &q, my_iterator i) const
The step function.
pbes run(const lps::specification &model, const lps::specification &spec)
Returns a pbes that expresses branching bisimulation between two specifications.
Algorithm class for branching simulation equivalence.
pbes run(const lps::specification &model, const lps::specification &spec)
Runs the algorithm.
parameterized boolean equation system
Algorithm class for strong bisimulation.
pbes_expression match(const lps::linear_process &p, const lps::linear_process &q) const
The match function.
pbes_expression step(const lps::linear_process &p, const lps::linear_process &q, my_iterator i) const
The step function.
pbes run(const lps::specification &model, const lps::specification &spec)
Runs the algorithm.
Algorithm class for weak bisimulation.
pbes run(const lps::specification &model, const lps::specification &spec)
Runs the algorithm.
pbes_expression close2(const lps::linear_process &p, const lps::linear_process &q, my_iterator i, const data::data_expression_list &d, const data::data_expression_list &d1) const
The close function.
pbes_expression close1(const lps::linear_process &p, const lps::linear_process &q, my_iterator i) const
The close1 function.
data::set_identifier_generator m_generator
pbes_expression step(const lps::linear_process &p, const lps::linear_process &q, my_iterator i) const
The step function.
pbes_expression match(const lps::linear_process &p, const lps::linear_process &q) const
The match function.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
data_specification merge_data_specifications(const data_specification &dataspec1, const data_specification &dataspec2)
Merges two data specifications. Throws an exception if conflicts are detected.
The main namespace for the LPS library.
pbes strong_bisimulation(const lps::specification &model, const lps::specification &spec)
Returns a pbes that expresses strong bisimulation between two specifications.
pbes branching_simulation_equivalence(const lps::specification &model, const lps::specification &spec)
Returns a pbes that expresses branching simulation equivalence between two specifications.
pbes branching_bisimulation(const lps::specification &model, const lps::specification &spec)
Returns a pbes that expresses branching bisimulation between two specifications.
pbes weak_bisimulation(const lps::specification &model, const lps::specification &spec)
Returns a pbes that expresses weak bisimulation between two specifications.
void optimized_and(pbes_expression &result, const pbes_expression &p, const pbes_expression &q)
Make a conjunction.