mCRL2
Loading...
Searching...
No Matches
pbes_explorer.cpp
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 pbes/source/pbes_explorer.cpp
10/// \brief
11#include <climits>
12#include <queue>
13#include <utility>
14
15#include "mcrl2/data/detail/io.h"
16#include "mcrl2/data/representative_generator.h"
17#include "mcrl2/pbes/detail/ppg_visitor.h"
18#include "mcrl2/pbes/io.h"
19#include "mcrl2/pbes/pbes_explorer.h"
20
21
22
23namespace mcrl2::pbes_system
24{
25
26namespace detail
27{
28 template <typename MapContainer>
29 typename MapContainer::mapped_type map_at(const MapContainer& m, typename MapContainer::key_type key)
30 {
31 typename MapContainer::const_iterator i = m.find(key);
32 if (i == m.end())
33 {
34 throw mcrl2::runtime_error("map_at: key is not present in the map: " + key);
35 }
36 return i->second;
37 }
38} // namespace detail
39
40/// lts_type
41
42lts_type::lts_type(int state_length)
43{
44 this->state_length = state_length;
45}
46
47lts_type::~lts_type() = default;
48
50{
51 return this->state_length;
52}
53
54
56{
57 return this->state_type_list.size();
58}
59
60
61int lts_type::get_state_type_no(int part) const
62{
63 return this->state_type_no.at(part);
64}
65
67{
68 return this->state_type_list.at(type_no);
69}
70
72{
73 return state_names;
74}
75
76
78{
79 return state_types;
80}
81
82
84{
85 return this->state_label_names.size();
86}
87
88
90{
91 return state_label_names;
92}
93
94
96{
97 return state_label_types;
98}
99
100
102{
103 return this->edge_label_names.size();
104}
105
106
108{
109 return edge_label_names;
110}
111
112
114{
115 return edge_label_types;
116}
117
118
119void lts_type::add_state(const std::string& name, const std::string& type)
120{
121 //std::clog << "Adding state part " << this->state_names->size() << ": "
122 // << info::get_param_signature(name, type)
123 // << std::endl;
124 this->state_names.push_back(name);
125 this->state_types.push_back(type);
126 int type_index;
127 std::map<std::string,int>::iterator type_index_it = this->state_type_index.find(type);
128 if (type_index_it != this->state_type_index.end()) {
129 type_index = type_index_it->second;
130 } else {
131 this->state_type_list.push_back(type);
132 type_index = static_cast<int>(this->state_type_list.size() - 1);
133 this->state_type_index[type] = type_index;
134 }
135 this->state_type_no.push_back(type_index);
136}
137
138
139void lts_type::add_state_label(const std::string& name,
140 const std::string& type)
141{
142 this->state_label_names.push_back(name);
143 this->state_label_types.push_back(type);
144}
145
146
147void lts_type::add_edge_label(const std::string& name,
148 const std::string& type)
149{
150 this->edge_label_names.push_back(name);
151 this->edge_label_types.push_back(type);
152}
153
154
155
156
157/// lts_info
158
159lts_info::lts_info(pbes& p, detail::pbes_greybox_interface* pgg, bool reset = false, bool always_split = false):
160 p(p),
161 pgg(pgg),
162 reset_option(reset),
163 always_split_option(always_split),
164 type(0)
165{
166 if (!detail::is_ppg(p))
167 {
168 throw std::runtime_error("PBES is not a PPG! Please rewrite with pbesrewr -pppg.");
169 }
173}
174
175
177{
178 mCRL2log(log::log_level_t::verbose) << "Compute LTS type." << std::endl;
179 std::vector<std::string> params;
180 std::map<std::string,std::string> paramtypes;
181 data::representative_generator default_expression_generator(p.data());
182
183 for (const auto& eqn : p.equations())
184 {
185 //std::clog << core::pp((*eqn).symbol()) << " " << (*eqn).variable().name()
186 // << std::endl;
187
188 propositional_variable var = eqn.variable();
189 for (const variable& varparam: var.parameters())
190 {
191 std::string signature = get_param_signature(varparam);
192 bool new_param = true;
193 for (const std::string& param: params)
194 {
195 if (signature == param)
196 {
197 new_param = false;
198 }
199 }
200 if (new_param)
201 {
202 params.push_back(signature);
203 paramtypes[signature] = core::pp(varparam.sort());
204 data_expression e(default_expression_generator(varparam.sort()));
205 pbes_expression e1 = pgg->rewrite_and_simplify_expression(atermpp::down_cast<pbes_expression>(e),false);
206 this->param_default_values.push_back(atermpp::down_cast<const data::data_expression>(e1));
207 }
208 }
209 }
210 this->type = lts_type(static_cast<int>(1 + params.size()));
211 this->type.add_state("var", "string"); // Propositional variable name
212
213 int i = 0;
214 for (const std::string& signature: params) {
215 this->type.add_state(signature, paramtypes[signature]);
216 this->param_index[signature] = i;
217 i++;
218 }
219
220 this->type.add_state_label("priority", "int");
221 this->type.add_state_label("type", "int");
222
223 mCRL2log(log::log_level_t::verbose) << "end of compute_lts_type." << std::endl;
224}
225
226
228{
229 std::string varname = std::string(propvar.name());
230 data::variable_list params = this->variable_parameters[varname];
231 const data::data_expression_list& values = propvar.parameters();
232 if (params.size() != values.size())
233 {
234 return false;
235 }
236 else
237 {
238 data::variable_list::const_iterator param_it = params.begin();
239 for(const auto & value : values)
240 {
241 if (!data::is_variable(value))
242 {
243 return false;
244 }
245 else
246 {
247 data::variable param(*param_it);
248 data::variable param_expr(value);
249 if (param != param_expr)
250 {
251 return false;
252 }
253 }
254 if (param_it != params.end())
255 {
256 ++param_it;
257 }
258 }
259 }
260 if(params != values)
261 {
262 throw mcrl2::runtime_error("is_pass_through_state check failed on " + data::pp(params) + " " + data::pp(values));
263 }
264 return true;
265}
266
267
269{
271 {
272 return 1;
273 }
274 else if (is_and(e) || is_or(e) || is_imp(e))
275 {
278
279 if (a < INT_MAX && b < INT_MAX)
280 {
281 return a + b;
282 }
283 else
284 {
285 return INT_MAX;
286 }
287 }
288 else if (is_forall(e) || is_exists(e))
289 {
291 {
292 return INT_MAX;
293 }
294 else
295 {
296 return 0;
297 }
298 }
299 else if (is_not(e))
300 {
302 }
303 else if (is_data(e))
304 {
305 return 0;
306 }
307 else
308 {
309 throw(std::runtime_error("Unexpected expression: " + pbes_system::pp(e)));
310 }
311}
312
314{
315 std::vector<pbes_expression> result;
316 std::vector<pbes_expression> parts;
317 if (is_simple_expression(e, false))
318 {
319 result.push_back(e);
320 }
322 {
323 result.push_back(e);
324 }
325 else if (is_and(e)) {
326 parts = split_conjuncts(e, true);
327 } else if (is_or(e)) {
328 parts = split_disjuncts(e, true);
329 } else {
330 parts.push_back(e);
331 }
332
333 bool pass_through = true;
334
335 for(std::vector<pbes_expression>::iterator p_it = parts.begin(); pass_through && p_it != parts.end(); ++p_it)
336 {
337 pbes_expression part = *p_it;
338 if (is_propositional_variable_instantiation(part))
339 {
340 // Try to substitute the variable instantiation with the associated expression
341
342 propositional_variable_instantiation propvar = (propositional_variable_instantiation)part;
343 if (is_pass_through_state(propvar))
344 {
345 // The variable instantiation only copies the current parameters and local data variables,
346 // so substitution is safe with respect to that.
347
348 std::string varname = std::string(propvar.name());
349 int priority = this->variable_priority[varname];
350 operation_type type = this->variable_type[varname];
351 pbes_expression expr = this->variable_expression[varname];
352
353 if ((priority == current_priority) &&
354 (current_type == type || is_simple_expression(expr, false) || count_variables(expr) <= 1) &&
355 vars_stack.find(varname) == vars_stack.end())
356 {
357 // The associated equation has the same priority and operation type as the current equation,
358 // so substitution is safe.
359
360 //std::clog << " Substituting variable instantiation: " << pbes_system::pp(part) << std::endl
361 // << " with: " << pbes_system::pp(expr) << std::endl;
362
363 // Recursively try to further substitute variables:
364 // (vars_stack is used to prevent infinite recursion)
365 std::set<std::string> new_vars_stack(vars_stack.begin(), vars_stack.end());
366 new_vars_stack.insert(varname);
367 std::vector<pbes_expression> part_result = split_expression_and_substitute_variables(expr, current_priority, current_type, new_vars_stack);
368 result.insert(result.end(), part_result.begin(), part_result.end());
369 }
370 else
371 {
372 result.push_back(part);
373 }
374 }
375 else
376 {
377 pass_through = false;
378 }
379 }
380 else
381 {
382 pass_through = false;
383 }
384 }
385 if (!pass_through)
386 {
387 if (always_split_option && !parts.empty())
388 {
389 // the old behaviour of the explorer: always split conjunctions and disjunctions
390 // into subexpressions that form groups
391 result = parts;
392 }
393 else
394 {
395 // the new behaviour: only split expressions if every part is a pass-through variable instantiation,
396 // i.e., all values are copied and not changed.
397 result.clear();
398 result.push_back(e);
399 }
400 }
401 return result;
402}
403
404
406{
407 mCRL2log(log::log_level_t::verbose) << "Compute transition groups." << std::endl;
408
409 int group = 0;
410 int priority = 0;
413 detail::ppg_visitor checker;
414
415 std::string name = "true";
416 propositional_variable t{core::identifier_string(name), data::variable_list()};
417 this->variables[name] = t;
418 this->variable_type[name] = type;
419 this->variable_symbol[name] = symbol;
420 this->variable_priority[name] = priority;
421 this->variable_parameters[name] = t.parameters();
422 this->variable_parameter_signatures[name] = get_param_sequence(t.parameters());
423 this->variable_parameter_indices[name] = this->get_param_indices(t.parameters());
424 this->variable_parameter_index_positions[name] = this->get_param_index_positions(t.parameters());
425 this->transition_expression_plain.push_back(true_());
426 this->transition_expression.push_back(pgg->rewrite_and_simplify_expression(true_()));
427 this->transition_variable_name.push_back(name);
428 this->transition_type.push_back(type);
429 group++;
430 priority++;
431
432 name = "false";
435 propositional_variable f{core::identifier_string(name), data::variable_list()};
436 this->variables[name] = f;
437 this->variable_type[name] = type;
438 this->variable_symbol[name] = symbol;
439 this->variable_priority[name] = priority;
440 this->variable_parameters[name] = f.parameters();
441 this->variable_parameter_signatures[name] = get_param_sequence(f.parameters());
442 this->variable_parameter_indices[name] = this->get_param_indices(f.parameters());
443 this->variable_parameter_index_positions[name] = this->get_param_index_positions(f.parameters());
444 this->transition_expression_plain.push_back(false_());
445 this->transition_expression.push_back(pgg->rewrite_and_simplify_expression(false_()));
446 this->transition_variable_name.push_back(name);
447 this->transition_type.push_back(type);
448 group++;
449 priority++;
450
452
453 for (auto & eqn : p.equations()) {
454 pbes_expression expr = pgg->get_pbes_equation(eqn.variable().name()).formula();
455 std::string variable_name = eqn.variable().name();
456 this->variables[variable_name] = eqn.variable();
457 type = pgg->get_expression_operation(expr);
458 this->variable_type[variable_name] = type;
459 this->variable_symbol[variable_name] = eqn.symbol();
460 if (eqn.symbol() != symbol) {
461 priority++;
462 symbol = eqn.symbol();
463 }
464 mCRL2log(log::log_level_t::debug) << "Adding var " << variable_name << ", priority=" << priority << ", symbol=" << symbol << std::endl;
465 this->variable_priority[variable_name] = priority;
466 this->variable_parameters[variable_name] = eqn.variable().parameters();
467 this->variable_parameter_signatures[variable_name] = get_param_sequence(eqn.variable().parameters());
468 this->variable_parameter_indices[variable_name] = this->get_param_indices(eqn.variable().parameters());
469 this->variable_parameter_index_positions[variable_name] = this->get_param_index_positions(eqn.variable().parameters());
470 this->variable_expression[variable_name] = expr;
471 }
472
473 // Skip 'unused' equations....
474 std::set<std::string> variable_set;
475 {
477 std::queue<std::string> variable_queue;
478 variable_queue.push(init.name());
479 variable_set.insert(init.name());
480 while (!variable_queue.empty())
481 {
482 std::string var = variable_queue.front();
483 variable_queue.pop();
484 type = this->variable_type[var];
485 priority = this->variable_priority[var];
486 pbes_expression expr = this->variable_expression[var];
487 std::set<std::string> vars_stack;
488 std::vector<pbes_expression> expression_parts = split_expression_and_substitute_variables(expr, priority, type, vars_stack);
489 for (const auto & expression_part : expression_parts) {
490 std::set<std::string> occ_vars = lts_info::occ(expression_part);
491 for (const auto & var_str : variable_set)
492 {
493 occ_vars.erase(var_str);
494 }
495 for(const auto & occ_var : occ_vars)
496 {
497 variable_queue.push(occ_var);
498 }
499 variable_set.insert(occ_vars.begin(), occ_vars.end());
500 }
501 }
502 mCRL2log(log::log_level_t::debug) << "Set of 'used' variables: " << std::endl;
503 for (const auto & var_str : variable_set)
504 {
505 mCRL2log(log::log_level_t::debug) << " " << var_str << std::endl;
506 }
507 mCRL2log(log::log_level_t::debug) << std::endl;
508 }
509
510 for (auto & eqn : p.equations()) {
511 std::string variable_name = eqn.variable().name();
512 if (variable_set.find(variable_name) != variable_set.end())
513 {
514 type = this->variable_type[variable_name];
515 priority = this->variable_priority[variable_name];
516 pbes_expression expr = this->variable_expression[variable_name];
517 std::set<std::string> vars_stack;
518 mCRL2log(log::log_level_t::debug) << std::endl << "Generating groups for equation " << variable_name << std::endl;
519 std::vector<pbes_expression> expression_parts = split_expression_and_substitute_variables(expr, priority, type, vars_stack);
520 for (const auto & expression_part : expression_parts) {
521 this->transition_expression_plain.push_back(expression_part);
522 this->transition_expression.push_back(pgg->rewrite_and_simplify_expression(expression_part));
523 this->transition_variable_name.push_back(variable_name);
524 this->transition_type.push_back(type);
525 mCRL2log(log::log_level_t::debug) << "Add transition group " << group << ": "
526 << (type==parity_game_generator::operation_type::PGAME_AND ? "AND" : "OR") << " " << variable_name << " "
527 << pbes_system::pp(expression_part) << std::endl;
528 group++;
529 }
530 }
531 }
532 number_of_groups = group;
533 mCRL2log(log::log_level_t::debug) << "end of compute_transition_groups." << std::endl;
534}
535
536
538{
539 mCRL2log(log::log_level_t::verbose) << "Compute dependency matrix." << std::endl;
540 for(int group=0; group < number_of_groups; group++)
541 {
542 std::vector<bool> dep_row;
543 std::vector<bool> read_row;
544 std::vector<bool> write_row;
545 bool r = is_read_dependent_propvar(group);
546 bool w = is_write_dependent_propvar(group);
547 bool d = r || w;
548 dep_row.push_back(d);
549 read_row.push_back(r);
550 write_row.push_back(w);
551 for (int part = 1; part < type.get_state_length(); part++)
552 {
553 r = is_read_dependent_parameter(group, part);
554 w = is_write_dependent_parameter(group, part);
555 d = r || w;
556 dep_row.push_back(d);
557 read_row.push_back(r);
558 write_row.push_back(w);
559 }
560 matrix[group] = dep_row;
561 read_matrix[group] = read_row;
562 write_matrix[group] = write_row;
563 }
564 mCRL2log(log::log_level_t::verbose) << "end of compute_dependency_matrix." << std::endl;
565}
566
567
569{
570 return reset_option;
571}
572
573
575{
576 return number_of_groups;
577}
578
579
581{
582 return transition_expression;
583}
584
585
587{
588 return transition_variable_name;
589}
590
591
593{
594 return transition_type;
595}
596
597
599{
600 return variables;
601}
602
603
605{
606 return variable_type;
607}
608
610{
611 return variable_symbol;
612}
613
614
616{
617 return variable_priority;
618}
619
620
622{
623 return variable_parameters;
624}
625
626
628{
630}
631
632
634{
636}
637
638
640{
642}
643
644
646{
647 return type;
648}
649
650
651const std::map<int,std::vector<bool> >& lts_info::get_dependency_matrix() const
652{
653 return matrix;
654}
655
656
657const std::map<int,std::vector<bool> >& lts_info::get_read_matrix() const
658{
659 return read_matrix;
660}
661
662
663const std::map<int,std::vector<bool> >& lts_info::get_write_matrix() const
664{
665 return write_matrix;
666}
667
668
669int lts_info::get_index(const std::string& signature)
670{
671 return param_index[signature];
672}
673
674
676{
677 return param_default_values.at(index);
678}
679
680
682{
683 return true;
684}
685
686
687bool lts_info::is_read_dependent_parameter(int group, int part)
688{
689 if (group == 0 || group == 1)
690 {
691 return false;
692 }
693 std::string p = type.get_state_names()[part];
694 mCRL2log(log::log_level_t::debug) << "is_read_dependent_parameter (group=" << group << ", part=" << part << " [" << p << "]" << std::endl;
695 pbes_expression phi = transition_expression_plain[group];
696 std::string X = transition_variable_name[group];
697 std::set<std::string> params = lts_info::get_param_set(variable_parameters[X]);
698 if (params.find(p) == params.end())
699 {
700 return false; // Parameter is not in params(X).
701 }
702 else
703 {
704 std::set<std::string> usedSet = used(phi);
705 std::set<std::string> changedSet = changed(phi);
706 std::set<std::string> copySet = copied(phi);
707 std::set<std::string> changedAndCopied;
708 std::set_intersection(changedSet.begin(), changedSet.end(), copySet.begin(), copySet.end(),
709 std::inserter(changedAndCopied, changedAndCopied.end()));
710
711 if (usedSet.find(p) == usedSet.end() && changedAndCopied.find(p) == changedAndCopied.end())
712 {
713 // Parameter is not in used(phi) and not in (changed(phi) /\ copied(phi)).
714 return false; // Parameter is not in used(phi).
715 }
716 else
717 {
718 return true; // Parameter is both in used(phi) and in params(X).
719 }
720 }
721
722}
723
724
726{
727 if (group == 0 || group == 1)
728 {
729 return false;
730 }
731 pbes_expression phi = transition_expression_plain[group];
732 std::string X = transition_variable_name[group];
733 if (lts_info::tf(phi))
734 {
735 return true;
736 }
737 std::set<std::string> occ = lts_info::occ(phi);
738 if (occ.empty())
739 {
740 return false; // Not dependent if occ(phi) == {}.
741 }
742 else if (occ.size() == 1)
743 {
744 bool containsX = occ.find(X) != occ.end();
745 return !containsX; // Not dependent if occ(phi) == {X}.
746 }
747 else
748 {
749 return true; // Dependent, because occ(phi) contains multiple elements.
750 }
751}
752
753
754bool lts_info::is_write_dependent_parameter(int group , int part)
755{
756 if (group == 0 || group == 1)
757 {
758 return false;
759 }
760 std::string p = type.get_state_names().at(part);
761 pbes_expression phi = transition_expression_plain[group];
762 std::string X = transition_variable_name[group];
763 if (this->reset_option) {
764 if (lts_info::tf(phi))
765 {
766 // phi may have boolean result (not only propositional variable instantiations)
767 return true;
768 }
769 std::set<std::string> params = lts_info::get_param_set(variable_parameters[X]);
770 std::set<std::string> resetSet = reset(phi, params);
771 if (resetSet.find(p) != resetSet.end())
772 {
773 return true; // Dependent, because p in reset(phi, params(X)).
774 }
775 }
776 std::set<std::string> changedSet = changed(phi);
777 bool changedSetContainsP = (changedSet.find(p) != changedSet.end());
778 return changedSetContainsP; // Dependent, because p in changed(phi, {}).
779}
780
781
783{
784 std::set<std::string> empty;
785 return changed(phi, empty);
786}
787
788
790{
791 std::set<std::string> result;
792 if (is_not(phi))
793 {
794 result = changed(pbes_system::accessors::arg(phi), L);
795 }
796 else if (is_and(phi) || is_or(phi) || is_imp(phi))
797 {
798 std::set<std::string> l = changed(pbes_system::accessors::left(phi), L);
799 result.insert(l.begin(), l.end());
800 std::set<std::string> r = changed(pbes_system::accessors::right(phi), L);
801 result.insert(r.begin(), r.end());
802 }
803 else if (is_forall(phi) || is_exists(phi))
804 {
805 std::set<std::string> LL;
806 LL.insert(L.begin(), L.end());
807 data::variable_list vars = quantifier_variables(phi);
808 for (const auto& variable: vars)
809 {
810 LL.insert(get_param_signature(variable));
811 }
812 result = changed(pbes_system::accessors::arg(phi), LL);
813 }
815 {
816 std::vector<std::string> var_param_signatures =
817 variable_parameter_signatures[atermpp::down_cast<propositional_variable_instantiation>(phi).name()];
818 data::data_expression_list values = atermpp::down_cast<propositional_variable_instantiation>(phi).parameters();
819 assert(var_param_signatures.size() == values.size());
820 data::data_expression_list::const_iterator val = values.begin();
821 for (auto param_signature : var_param_signatures) {
822 if (data::is_variable(*val))
823 {
824 const variable& value = atermpp::down_cast<variable>(*val);
825 std::string value_signature = get_param_signature(value);
826 if (param_signature != value_signature || L.find(value_signature) != L.end())
827 {
828 result.insert(param_signature);
829 }
830 }
831 else
832 {
833 result.insert(param_signature);
834 }
835 if (val != values.end()) {
836 ++val;
837 }
838 }
839 }
840 return result;
841}
842
843
845{
846 std::set<std::string> result;
847 if (is_not(phi))
848 {
849 result = reset(pbes_system::accessors::arg(phi), d);
850 }
851 else if (is_and(phi) || is_or(phi) || is_imp(phi))
852 {
853 std::set<std::string> l = reset(pbes_system::accessors::left(phi), d);
854 result.insert(l.begin(), l.end());
855 std::set<std::string> r = reset(pbes_system::accessors::right(phi), d);
856 result.insert(r.begin(), r.end());
857 }
858 else if (is_forall(phi) || is_exists(phi))
859 {
860 result = reset(pbes_system::accessors::arg(phi), d);
861 }
863 {
864 std::set<std::string> params;
865 std::vector<std::string> var_params =
866 variable_parameter_signatures[atermpp::down_cast<propositional_variable_instantiation>(phi).name()];
867 for (auto signature : var_params) {
868 params.insert(signature);
869 }
870 for (const auto& signature: d)
871 {
872 if (params.find(signature) == params.end())
873 {
874 result.insert(signature);
875 }
876 }
877 }
878 return result;
879}
880
881
882bool lts_info::tf(const pbes_expression& phi)
883{
884 if (is_not(phi))
885 {
887 }
888 else if (is_and(phi) || is_or(phi) || is_imp(phi))
889 {
891 }
892 else if (is_forall(phi) || is_exists(phi))
893 {
895 }
897 {
898 return false;
899 }
900 return true;
901}
902
903
904std::set<std::string> lts_info::occ(const pbes_expression& expr)
905{
906 std::set<std::string> result;
908 {
909 result.insert(atermpp::down_cast<propositional_variable_instantiation>(expr).name());
910 }
911 else if (is_and(expr) || is_or(expr) ||is_imp(expr))
912 {
913 std::set<std::string> l = occ(pbes_system::accessors::left(expr));
914 result.insert(l.begin(), l.end());
915 std::set<std::string> r = occ(pbes_system::accessors::right(expr));
916 result.insert(r.begin(), r.end());
917 }
918 else if (is_forall(expr) || is_exists(expr) || is_not(expr))
919 {
920 result = occ(pbes_system::accessors::arg(expr));
921 }
922 return result;
923}
924
925
926std::set<std::string> lts_info::free(const pbes_expression& expr)
927{
928 std::set<std::string> result;
929 for (const data::variable& var: pbes_system::find_free_variables(expr))
930 {
931 result.insert(get_param_signature(var));
932 }
933 return result;
934}
935
936
938{
939 std::set<std::string> emptySet;
940 return used(expr, emptySet);
941}
942
943
945{
946 std::set<std::string> result;
947 if (is_data(expr))
948 {
949 std::set<std::string> fv = free(expr);
950 result.insert(fv.begin(), fv.end());
951 }
953 {
954 data::variable_list var_params =
955 variable_parameters[atermpp::down_cast<propositional_variable_instantiation>(expr).name()];
956 data::data_expression_list values = atermpp::down_cast<propositional_variable_instantiation>(expr).parameters();
957 assert(var_params.size() == values.size());
958 data::data_expression_list::const_iterator val = values.begin();
959 for (const auto& parameter: var_params)
960 {
961 std::string param_signature = get_param_signature(parameter);
962 if (data::is_variable(*val))
963 {
964 const variable& value = atermpp::down_cast<variable>(*val);
965 std::string value_signature = get_param_signature(value);
966 if (param_signature != value_signature || L.find(value_signature) != L.end())
967 {
968 result.insert(value_signature);
969 }
970 }
971 else
972 {
973 // add free variables in data expression
974 std::set<std::string> l = used(atermpp::down_cast<pbes_expression>(*val), L);
975 result.insert(l.begin(), l.end());
976 }
977 if (val != values.end())
978 {
979 ++val;
980 }
981 }
982 }
983 else if (is_and(expr) || is_or(expr) || is_imp(expr))
984 {
985 std::set<std::string> l = used(pbes_system::accessors::left(expr), L);
986 result.insert(l.begin(), l.end());
987 std::set<std::string> r = used(pbes_system::accessors::right(expr), L);
988 result.insert(r.begin(), r.end());
989 }
990 else if (is_not(expr))
991 {
992 result = used(pbes_system::accessors::arg(expr), L);
993 }
994 else if (is_forall(expr) || is_exists(expr))
995 {
996 std::set<std::string> LL;
997 LL.insert(L.begin(), L.end());
998 data::variable_list vars = quantifier_variables(expr);
999 for (const auto& variable: vars)
1000 {
1001 LL.insert(get_param_signature(variable));
1002 }
1003 result = used(pbes_system::accessors::arg(expr), LL);
1004 }
1005 return result;
1006}
1007
1008
1010{
1011 std::set<std::string> emptySet;
1012 return copied(expr, emptySet);
1013}
1014
1015
1017{
1018 std::set<std::string> result;
1019 if (is_data(expr))
1020 {
1021 // skip
1022 }
1024 {
1025 data::variable_list var_params =
1026 variable_parameters[atermpp::down_cast<propositional_variable_instantiation>(expr).name()];
1027 data::data_expression_list values = atermpp::down_cast<propositional_variable_instantiation>(expr).parameters();
1028 assert(var_params.size() == values.size());
1029 data::data_expression_list::const_iterator val = values.begin();
1030 for (const auto& parameter: var_params)
1031 {
1032 std::string param_signature = get_param_signature(parameter);
1033 if (data::is_variable(*val))
1034 {
1035 const variable& value = atermpp::down_cast<variable>(*val);
1036 std::string value_signature = get_param_signature(value);
1037 if (param_signature == value_signature && L.find(value_signature) == L.end())
1038 {
1039 result.insert(value_signature);
1040 }
1041 }
1042 if (val != values.end())
1043 {
1044 ++val;
1045 }
1046 }
1047 }
1048 else if (is_and(expr) || is_or(expr) || is_imp(expr))
1049 {
1050 std::set<std::string> l = copied(pbes_system::accessors::left(expr), L);
1051 result.insert(l.begin(), l.end());
1052 std::set<std::string> r = copied(pbes_system::accessors::right(expr), L);
1053 result.insert(r.begin(), r.end());
1054 }
1055 else if (is_not(expr))
1056 {
1057 result = copied(pbes_system::accessors::arg(expr), L);
1058 }
1059 else if (is_forall(expr) || is_exists(expr))
1060 {
1061 std::set<std::string> LL;
1062 LL.insert(L.begin(), L.end());
1063 data::variable_list vars = quantifier_variables(expr);
1064 for (const auto& variable: vars)
1065 {
1066 LL.insert(get_param_signature(variable));
1067 }
1068 result = copied(pbes_system::accessors::arg(expr), LL);
1069 }
1070 return result;
1071}
1072
1073
1075{
1076 std::string result;
1077 std::stringstream ss;
1078 operation_type type = detail::map_at(get_variable_types(), state.get_variable());
1079 ss << (type==parity_game_generator::operation_type::PGAME_AND ? "AND" : "OR");
1080 ss << ":" << state.get_variable();
1081 ss << "(";
1082 const std::vector<data_expression>& param_values = state.get_parameter_values();
1083 std::vector<std::string> param_signatures =
1084 this->variable_parameter_signatures[state.get_variable()];
1085 std::vector<std::string>::const_iterator param_signature =
1086 param_signatures.begin();
1087 for (std::vector<data_expression>::const_iterator param_value =
1088 param_values.begin(); param_value != param_values.end(); ++param_value) {
1089 if (param_value != param_values.begin())
1090 {
1091 ss << ", ";
1092 }
1093 ss << *param_signature << " = ";
1094 ss << *param_value;
1095 if (param_signature != param_signatures.end())
1096 {
1097 ++param_signature;
1098 }
1099 }
1100 ss << ")";
1101 result = ss.str();
1102 return result;
1103}
1104
1105
1106std::set<std::string> lts_info::get_param_set(const data::variable_list& params)
1107{
1108 std::set<std::string> result;
1109 for (const auto& parameter: params)
1110 {
1111 result.insert(get_param_signature(parameter));
1112 }
1113 return result;
1114}
1115
1116
1117std::vector<std::string> lts_info::get_param_sequence(const data::variable_list& params)
1118{
1119 std::vector<std::string> result;
1120 for (const auto& parameter: params)
1121 {
1122 result.push_back(get_param_signature(parameter));
1123 }
1124 return result;
1125}
1126
1127
1129{
1130 std::vector<int> result;
1131 for (const auto& parameter: params)
1132 {
1133 int index = this->get_index(get_param_signature(parameter));
1134 result.push_back(index);
1135 }
1136 return result;
1137}
1138
1139
1141{
1142 std::map<int,int> result;
1143 int i = 0;
1144 for (const auto& parameter: params)
1145 {
1146 int index = this->get_index(get_param_signature(parameter));
1147 result.insert(std::make_pair(index, i));
1148 i++;
1149 }
1150 return result;
1151}
1152
1153
1155
1156
1157std::string lts_info::get_param_signature(const variable& param)
1158{
1159 std::map<variable,std::string>::const_iterator i = variable_signatures.find(param);
1160 if (i == variable_signatures.end())
1161 {
1162 std::string paramname = param.name();
1163 std::string paramtype = core::pp(param.sort());
1164 std::string signature = get_param_signature(paramname, paramtype);
1165 variable_signatures[param] = signature;
1166 return signature;
1167 }
1168 return i->second;
1169}
1170
1171
1172std::string lts_info::get_param_signature(const std::string& paramname,
1173 const std::string& paramtype)
1174{
1175 return paramname + ":" + paramtype;
1176}
1177
1178
1179
1180
1181// ltsmin_state
1182
1183ltsmin_state::ltsmin_state(const std::string& varname)
1184{
1185 this->var = varname;
1186}
1187
1188
1189ltsmin_state::ltsmin_state(const std::string& varname,
1190 const pbes_expression& e)
1191{
1192 data_expression novalue;
1193 this->var = varname;
1195 assert(std::string(atermpp::down_cast<propositional_variable_instantiation>(e).name()) == varname);
1196 const data::data_expression_list& values = atermpp::down_cast<propositional_variable_instantiation>(e).parameters();
1197 for (const auto & value : values)
1198 {
1199 if (value == novalue)
1200 {
1201 throw(std::runtime_error("Error in ltsmin_state: state expression contains NoValue: "
1202 + pp(e)));
1203 }
1204 this->add_parameter_value(value);
1205 }
1206 } else {
1207 throw(std::runtime_error("Not a valid state expression! " + pp(e)));
1208 }
1209}
1210
1211bool ltsmin_state::operator<( const ltsmin_state& other ) const
1212{
1213 if (this->var < other.var)
1214 {
1215 return true;
1216 }
1217 else if (this->var == other.var)
1218 {
1219 if (param_values.size() < other.param_values.size())
1220 {
1221 return true;
1222 }
1223 else if (param_values.size() == other.param_values.size())
1224 {
1225 if (param_values < other.param_values)
1226 {
1227 return true;
1228 }
1229 }
1230 }
1231 return false;
1232}
1233
1234
1235bool ltsmin_state::operator==( const ltsmin_state& other ) const
1236{
1237 return this->var==other.var
1238 && param_values.size()==other.param_values.size()
1239 && param_values == other.param_values;
1240}
1241
1242
1244{
1245 return var;
1246}
1247
1248
1250{
1251 return param_values;
1252}
1253
1254
1256{
1257 param_values.push_back(value);
1258}
1259
1260
1262{
1263 data::data_expression_vector parameter_values;
1264 for (const auto & param_value : param_values) {
1265 parameter_values.push_back(param_value);
1266 }
1267 data::data_expression_list parameter_values_list(parameter_values.begin(), parameter_values.end());
1268 // Create propositional variable instantiation.
1270 propositional_variable_instantiation(core::identifier_string(var), parameter_values_list);
1271 return expr;
1272}
1273
1274
1276{
1277 std::string result;
1278 std::stringstream ss;
1279 ss << (type==parity_game_generator::operation_type::PGAME_AND ? "AND" : "OR");
1280 ss << ":" << var;
1281 ss << "[" << std::endl;
1282 for (std::vector<data_expression>::const_iterator entry =
1283 param_values.begin(); entry != param_values.end(); ++entry) {
1284 if (entry != param_values.begin())
1285 {
1286 ss << std::endl << " value = ";
1287 }
1288 ss << *entry;
1289 }
1290 ss << "]";
1291 result = ss.str();
1292 return result;
1293}
1294
1295
1296
1297
1298/// explorer
1299
1300explorer::explorer(const std::string& filename, const std::string& rewrite_strategy = "jittyc", bool reset_flag = false, bool always_split_flag = false)
1301{
1302 load_pbes(p, filename);
1303 pbes_system::algorithms::normalize(p);
1304 if (!detail::is_ppg(p))
1305 {
1306 mCRL2log(log::log_level_t::info) << "Rewriting to PPG..." << std::endl;
1307 p = detail::to_ppg(p);
1308 mCRL2log(log::log_level_t::info) << "Rewriting done." << std::endl;
1309 }
1310 this->pgg = new detail::pbes_greybox_interface(p, true, true, data::parse_rewrite_strategy(rewrite_strategy));
1311 this->info = new lts_info(p, pgg, reset_flag, always_split_flag);
1312 for (std::size_t i = 0; i < info->get_lts_type().get_number_of_state_types(); ++i) {
1313 std::map<data_expression,int> data2int_map;
1314 this->localmaps_data2int.push_back(data2int_map);
1315 std::vector<data_expression> int2data_map;
1316 this->localmaps_int2data.push_back(int2data_map);
1317 }
1318}
1319
1320
1321explorer::explorer(const pbes& p_, const std::string& rewrite_strategy = "jittyc", bool reset_flag = false, bool always_split_flag = false)
1322{
1323 p = p_;
1324 this->pgg = new detail::pbes_greybox_interface(p, true, true, data::parse_rewrite_strategy(rewrite_strategy));
1325 this->info = new lts_info(p, pgg, reset_flag, always_split_flag);
1326 for (std::size_t i = 0; i < info->get_lts_type().get_number_of_state_types(); i++) {
1327 std::map<data_expression,int> data2int_map;
1328 this->localmaps_data2int.push_back(data2int_map);
1329 std::vector<data_expression> int2data_map;
1330 this->localmaps_int2data.push_back(int2data_map);
1331 }
1332}
1333
1334
1336{
1337 delete info;
1338 delete pgg;
1339}
1340
1341
1343{
1344 return info;
1345}
1346
1347
1349{
1351 return this->get_state(initial_state);
1352}
1353
1354
1355void explorer::initial_state(int* state)
1356{
1357 ltsmin_state initial_state = this->get_initial_state();
1358 ltsmin_state dummy("dummy");
1359 this->to_state_vector(initial_state, state, dummy, nullptr);
1360}
1361
1362
1364{
1366 assert(is_propositional_variable_instantiation(expr) && expr != novalue);
1367 std::string varname = expr.name();
1368 ltsmin_state s(varname, expr);
1369 return s;
1370}
1371
1372
1374{
1375 return ltsmin_state("true");
1376}
1377
1378
1380{
1381 return ltsmin_state("false");
1382}
1383
1384
1386{
1387 atermpp::aterm t = atermpp::read_term_from_string(s);
1388 return atermpp::down_cast<data::data_expression>(data::detail::add_index(static_cast<const atermpp::aterm&>(t)));
1389}
1390
1391
1392int explorer::get_index(int type_no, const std::string& s)
1393{
1394 if (type_no==0)
1395 {
1396 return get_string_index(s);
1397 }
1398 else
1399 {
1400 data_expression value = this->string_to_data(s);
1401 return get_value_index(type_no, value);
1402 }
1403}
1404
1405
1406int explorer::get_string_index(const std::string& s)
1407{
1408 std::map<std::string,int>::iterator it = this->localmap_string2int.find(s);
1409 std::size_t index;
1410 if (it != this->localmap_string2int.end()) {
1411 index = it->second;
1412 } else {
1413 this->localmap_int2string.push_back(s);
1414 index = this->localmap_int2string.size() - 1;
1415 this->localmap_string2int.insert(std::make_pair(s,index));
1416 }
1417 return static_cast<int>(index);
1418}
1419
1420
1421int explorer::get_value_index(int type_no, const data_expression& value)
1422{
1423 std::map<data_expression,int>& data2int_map = this->localmaps_data2int.at(type_no);
1424 std::map<data_expression,int>::iterator it = data2int_map.find(value);
1425 std::size_t index;
1426 if (it != data2int_map.end()) {
1427 index = it->second;
1428 } else {
1429 this->localmaps_int2data.at(type_no).push_back(value);
1430 index = this->localmaps_int2data.at(type_no).size() - 1;
1431 data2int_map.insert(std::make_pair(value,index));
1432 }
1433 return static_cast<int>(index);
1434}
1435
1436
1437void explorer::to_state_vector(const ltsmin_state& dst_state, int* dst, const ltsmin_state& src_state, int* const& src)
1438{
1439
1440 data_expression novalue;
1441 int state_length = info->get_lts_type().get_state_length();
1442
1443 std::string varname = dst_state.get_variable();
1444 std::string src_varname;
1445 bool same_var = false;
1446 if (!(src==nullptr)) {
1447 src_varname = src_state.get_variable();
1448 same_var = (varname==src_varname);
1449 }
1450 int varindex;
1451 if (same_var) {
1452 varindex = src[0];
1453 } else {
1454 varindex = this->get_string_index(varname);
1455 }
1456 dst[0] = varindex;
1457
1458
1459 // data_expression values[state_length]; N.B. This is not portable C++
1460 std::vector < data_expression > values(state_length);
1461
1462 if (info->get_reset_option() || src == nullptr) {
1463 int type_no;
1464 for (int i = 1; i < state_length; i++) {
1465 data_expression default_value = info->get_default_value(i-1);
1466 values[i] = default_value;
1468 dst[i] = this->get_value_index(type_no, values[i]);
1469 }
1470 } else {
1471 for (int i = 1; i < state_length; i++) {
1472 dst[i] = src[i];
1473 }
1474 }
1475 bool error = false;
1476 const std::vector<data_expression>& parameter_values = dst_state.get_parameter_values();
1477 std::vector<int> parameter_indices =
1478 detail::map_at(info->get_variable_parameter_indices(), varname);
1479 std::vector<std::string> parameter_signatures =
1480 detail::map_at(info->get_variable_parameter_signatures(), varname);
1481 std::vector<std::string>::iterator param_signature = parameter_signatures.begin();
1482 int value_index = 0;
1483 for(int & parameter_indice : parameter_indices)
1484 {
1485 int i = parameter_indice + 1;
1486 int type_no = info->get_lts_type().get_state_type_no(i);
1487 values[i] = parameter_values[value_index];
1488 if (values[i]==novalue)
1489 {
1490 error = true;
1491 } else {
1492 if (src==nullptr) {
1493 // no source state available; compute index for value.
1494 dst[i] = this->get_value_index(type_no, values[i]);
1495 }
1496 else
1497 {
1498 // lookup src parameter value
1499 // FIXME: this could be computed statically: a map from src_var, dst_var and part to boolean
1500 std::map<int,int> src_param_index_positions = detail::map_at(info->get_variable_parameter_index_positions(), src_state.get_variable());
1501 std::map<int,int>::iterator src_param_index_position_it = src_param_index_positions.find(parameter_indice);
1502 if ( src_param_index_position_it != src_param_index_positions.end()
1503 && src_state.get_parameter_values()[src_param_index_position_it->second] == values[i])
1504 {
1505 // src value exists and is equal to the dst value.
1506 // save to copy index from src_state
1507 // which has been done earlier
1508 } else {
1509 // parameter value has changed or does not exists in src; compute index for value.
1510 dst[i] = this->get_value_index(type_no, values[i]);
1511 }
1512 }
1513 }
1514 if (param_signature != parameter_signatures.end())
1515 {
1516 ++param_signature;
1517 }
1518 value_index++;
1519 }
1520 if (error)
1521 {
1522 throw(std::runtime_error("Error in to_state_vector: NoValue in parameters of dst_state: "
1523 + info->state_to_string(dst_state) + "."));
1524 }
1525}
1526
1527
1529{
1530 if (type_no==0)
1531 {
1532 return this->get_string_value(index);
1533 }
1534 else
1535 {
1536 data_expression value = get_data_value(type_no, index);
1538 return pp(t);
1539 }
1540}
1541
1542
1544{
1545 if (std::cmp_greater_equal(index ,(localmap_int2string.size())))
1546 {
1547 throw(std::runtime_error("Error in get_string_value: Value not found for index " + std::to_string(index) + "."));
1548 }
1549 return localmap_int2string.at(index);
1550}
1551
1552
1553const data_expression& explorer::get_data_value(int type_no, int index)
1554{
1555 std::vector<data_expression>& int2data_map = this->localmaps_int2data.at(type_no);
1556 if (std::cmp_greater_equal(index ,(int2data_map.size())))
1557 {
1558 throw(std::runtime_error("Error in get_data_value: Value not found for type_no "
1559 + std::to_string(type_no) + " at index " + std::to_string(index) + "."));
1560 }
1561 return int2data_map.at(index);
1562}
1563
1564
1566{
1567 data_expression novalue;
1568 int state_length = info->get_lts_type().get_state_length();
1569
1570 std::string varname = this->get_string_value(src[0]);
1571
1572 bool error = false;
1573
1574 // data_expression values[state_length]; N.B. This is not portable C++
1575 std::vector <data_expression> values(state_length);
1576
1577 int type_no;
1578 for (int i = 1; i < state_length; i++) {
1580 values[i] = this->get_data_value(type_no, src[i]);
1581 }
1582 data::data_expression_vector parameters;
1583 std::vector<int> parameter_indices =
1584 detail::map_at(info->get_variable_parameter_indices(), varname);
1585 for (int & parameter_indice : parameter_indices) {
1586 if (values[parameter_indice+1]==novalue)
1587 {
1588 error = true;
1589 }
1590 parameters.push_back(values[parameter_indice+1]);
1591 }
1592 if (error)
1593 {
1594 throw(std::runtime_error("Error in from_state_vector: NoValue in parameters."));
1595 }
1596 data::data_expression_list paramlist(parameters.begin(), parameters.end());
1597 propositional_variable_instantiation state_expression(varname, paramlist);
1598 ltsmin_state state = this->get_state(state_expression);
1599 return state;
1600}
1601
1602
1604{
1605 std::vector<ltsmin_state> result;
1606
1608 assert(core::detail::check_term_PropVarInst(e));
1609 if (state.get_variable()=="true")
1610 {
1611 // Adding true=true
1612 result.push_back(state);
1613 }
1614 else if (state.get_variable()=="false")
1615 {
1616 // Adding false=false
1617 result.push_back(state);
1618 }
1619 else
1620 {
1621 std::set<pbes_expression> successors
1622 = pgg->get_successors(e);
1623 operation_type type = detail::map_at(info->get_variable_types(), state.get_variable());
1624 for (const auto & successor : successors) {
1625 if (is_propositional_variable_instantiation(successor)) {
1626 result.push_back(get_state(atermpp::down_cast<propositional_variable_instantiation>(successor)));
1627 } else if (is_true(successor)) {
1628 if (type != parity_game_generator::operation_type::PGAME_AND)
1629 {
1630 result.push_back(true_state());
1631 }
1632 } else if (is_false(successor)) {
1633 if (type != parity_game_generator::operation_type::PGAME_OR)
1634 {
1635 result.push_back(false_state());
1636 }
1637 } else {
1638 throw(std::runtime_error("!! Successor is NOT a propvar: " + pbes_system::pp(successor)));
1639 }
1640 }
1641 }
1642 return result;
1643}
1644
1645
1647 int group)
1648{
1649 std::vector<ltsmin_state> result;
1650
1651 if (group == 0 && state.get_variable()=="true")
1652 {
1653 // Adding true=true
1654 result.push_back(state);
1655 }
1656 else if (group == 1 && state.get_variable()=="false")
1657 {
1658 // Adding false=false
1659 result.push_back(state);
1660 }
1661 else
1662 {
1663 std::string varname = state.get_variable();
1664 std::string group_varname = info->get_transition_variable_names()[group];
1665 if (varname==group_varname)
1666 {
1668 std::set<pbes_expression> successors
1669 = pgg->get_successors(e, group_varname,
1670 info->get_transition_expressions()[group]);
1671 operation_type type = detail::map_at(info->get_variable_types(), state.get_variable());
1672 for (const auto & successor : successors) {
1673 if (is_propositional_variable_instantiation(successor)) {
1674 result.push_back(get_state(atermpp::down_cast<propositional_variable_instantiation>(successor)));
1675 } else if (is_true(successor)) {
1676 if (type != parity_game_generator::operation_type::PGAME_AND)
1677 {
1678 result.push_back(true_state());
1679 }
1680 } else if (is_false(successor)) {
1681 if (type != parity_game_generator::operation_type::PGAME_OR)
1682 {
1683 result.push_back(false_state());
1684 }
1685 } else {
1686 throw(std::runtime_error("!! Successor is NOT a propvar: " + pbes_system::pp(successor)));
1687 }
1688 }
1689 }
1690 }
1691 return result;
1692}
1693
1694
1695} // namespace mcrl2::pbes_system
A unordered_map class in which aterms can be stored.
Components for generating an arbitrary element of a sort.
representative_generator(const data_specification &specification)
Constructor with data specification as context.
propositional_variable_instantiation get_initial_state() override
Returns the initial state, rewritten and simplified.
pbes_expression rewrite_and_simplify_expression(const pbes_expression &e, const bool=true)
Rewrites and simplifies an expression.
static ltsmin_state false_state()
Returns the state representing false.
ltsmin_state get_state(const propositional_variable_instantiation &expr) const
Returns a PBES_State object for expr.
std::vector< ltsmin_state > get_successors(const ltsmin_state &state, int group)
Computes successor states for a state as defined in transition group group. Serves as a wrapper aroun...
int get_index(int type_no, const std::string &s)
Returns the index of value in the local store for the data type with number type_no....
ltsmin_state get_initial_state() const
Returns the initial state.
static ltsmin_state true_state()
Returns the state representing true.
void to_state_vector(const ltsmin_state &dst_state, int *dst, const ltsmin_state &src_state, int *const &src)
Transforms a PBES state to a state vector, represented by an array of integers.
std::string get_value(int type_no, int index)
Returns the value at position index in the local store for the data type with number type_no....
int get_value_index(int type_no, const data_expression &value)
Returns the index of value in the local store for the data type with number type_no....
explorer(const std::string &filename, const std::string &rewrite_strategy, bool reset_flag, bool always_split_flag)
Constructor.
explorer(const pbes &p_, const std::string &rewrite_strategy, bool reset_flag, bool always_split_flag)
Constructor.
ltsmin_state from_state_vector(int *const &src)
Transforms a state vector src into a PBES_State object object containing the variable and parameter v...
int get_string_index(const std::string &s)
Returns the index of s in the local store for string values. This store is reserved for the string re...
const std::string & get_string_value(int index)
Returns the string at position index in the local store for string values. An exception is thrown if ...
std::vector< ltsmin_state > get_successors(const ltsmin_state &state)
Computes successor states for a state. Serves as a wrapper around the get_successors function of the ...
data::data_expression string_to_data(const std::string &s)
Returns a data expression for the string representation s.
lts_info * get_info() const
Returns the PBES_Info object.
const data_expression & get_data_value(int type_no, int index)
Returns the value at position index in the local store for the data type with number type_no....
detail::pbes_greybox_interface * pgg
the PBES greybox interface
static fixpoint_symbol nu()
Returns the nu symbol.
fixpoint_symbol & operator=(fixpoint_symbol &&) noexcept=default
static fixpoint_symbol mu()
Returns the mu symbol.
bool is_write_dependent_propvar(int group)
Determines if group is write dependent on the propositional variable. Returns true if propositional v...
bool is_read_dependent_parameter(int group, int part)
Determines if group is read dependent on part part of the state vector. Returns true if the parameter...
std::vector< int > get_param_indices(const data::variable_list &params)
Converts a variable_sequence_type into a sequence of indices of parameter signatures in the list of p...
bool is_pass_through_state(const propositional_variable_instantiation &propvar)
Determines if the propositional variable instantiation is one that only copies parameters from the cu...
const std::map< std::string, fixpoint_symbol > & get_variable_symbols() const
Returns the map from variable names to the fixpoint operator of the equation for the variable.
static std::map< variable, std::string > variable_signatures
const std::map< std::string, data::variable_list > & get_variable_parameters() const
Returns the map from variable names to the sequence of parameters for the variable.
const std::map< std::string, propositional_variable > & get_variables() const
Returns the map from variable names to the variable object for the variable.
int get_index(const std::string &signature)
Returns the index for a parameter signature in the list of parameter signatures for the system.
const lts_type & get_lts_type() const
Returns the LTS Type.
bool get_reset_option() const
Returns if the reset option is set.
std::set< std::string > copied(const pbes_expression &expr, const std::set< std::string > &L)
Computes the free variables which are copied/passed through (to a recursive variable) in an expressio...
const std::vector< pbes_expression > & get_transition_expressions() const
Returns the map from transition group number to the expression of the transition group.
std::set< std::string > copied(const pbes_expression &expr)
Computes the free variables which are copied/passed through (to a recursive variable) in an expressio...
detail::pbes_greybox_interface * pgg
bool is_read_dependent_propvar(int group)
Determines if group is read dependent on the propositional variable. Returns true,...
const std::vector< operation_type > & get_transition_types() const
Returns the map from transition group number to the type of the right hand side of the equation to wh...
std::set< std::string > used(const pbes_expression &expr, const std::set< std::string > &L)
Computes the free variables actually used, not only passed through, in an expression.
std::set< std::string > used(const pbes_expression &expr)
Computes the free variables actually used, not only passed through, in an expression.
const std::map< std::string, operation_type > & get_variable_types() const
Returns the map from variable names to the type of the right hand side of the equation for the variab...
void compute_dependency_matrix()
Computes dependency matrix from PBES.
lts_info(pbes &p, detail::pbes_greybox_interface *pgg, bool reset, bool always_split)
Constructor.
static bool tf(const pbes_expression &phi)
Determines if the term phi contains a branch that directly results in true or false (not a variable).
std::vector< pbes_expression > split_expression_and_substitute_variables(const pbes_expression &e, int current_priority, operation_type current_type, std::set< std::string > vars_stack)
Splits the expression into parts (disjuncts or conjuncts) and recursively tries to substitute the pro...
int get_number_of_groups() const
Returns the number of transition groups.
std::map< int, int > get_param_index_positions(const data::variable_list &params)
Converts a variable_sequence_type into a map from indices of parameter signatures (in the list of par...
int count_variables(const pbes_expression &e)
Counts the number of propositional variables in an expression.
void compute_lts_type()
Computes LTS Type from PBES.
std::set< std::string > changed(const pbes_expression &phi, const std::set< std::string > &L)
Computes the set of parameters changed in the expression.
std::string state_to_string(const ltsmin_state &state)
Returns a string representation for state state.
const std::map< std::string, int > & get_variable_priorities() const
Returns the map from variable names to the priority of the equation for the variable.
const data_expression & get_default_value(int index)
Returns a default value for the sort of a parameter signature.
const std::vector< std::string > & get_transition_variable_names() const
Returns the map from transition group number to the variable name of the equation to which the transi...
std::set< std::string > reset(const pbes_expression &phi, const std::set< std::string > &d)
Computes the set of parameters reset in the expression.
bool is_write_dependent_parameter(int group, int part)
Determines if group is read dependent on part part of the state vector. Returns true if the parameter...
std::set< std::string > changed(const pbes_expression &phi)
Computes the set of parameters changed in the expression.
void compute_transition_groups()
Computes transition groups from PBES.
const std::vector< std::string > & get_edge_label_types() const
Returns the sequence of edge label types.
std::size_t get_number_of_state_types() const
Returns the number of state types.
const std::vector< std::string > & get_edge_labels() const
Returns the sequence of edge labels.
int get_state_type_no(int part) const
Returns the state type index for the state part part.
void add_state(const std::string &name, const std::string &type)
Adds a state part of type type with name name.
void add_state_label(const std::string &name, const std::string &type)
Adds a state label of type type with name name.
lts_type(int state_length)
Contructor.
std::string get_state_type_name(int type_no) const
Returns the name of the state type with number type_no.
int get_state_length() const
Returns the state length.
const std::vector< std::string > & get_state_label_types() const
Returns the sequence of state label types.
std::size_t get_number_of_edge_labels() const
Returns the number of edge labels.
const std::vector< std::string > & get_state_types() const
Returns the sequence of state part types.
void add_edge_label(const std::string &name, const std::string &type)
Adds an edge label of type type with name name.
const std::vector< std::string > & get_state_labels() const
Returns the sequence of state labels.
const std::vector< std::string > & get_state_names() const
Returns the sequence of state part names.
std::size_t get_number_of_state_labels() const
Returns the number of state labels.
void add_parameter_value(const data_expression &)
Adds a parameter value to the list of parameter values.
pbes_expression to_pbes_expression() const
Returns a PBES expression representing the state.
std::string state_to_string() const
Returns a string representation of the state.
bool operator<(const ltsmin_state &other) const
Compares two PBES_State objects. Uses lexicographical ordering on priority, type, variable and parame...
ltsmin_state(const std::string &varname)
Constructor.
bool operator==(const ltsmin_state &other) const
Checks if two PBES_State objects are equal.
ltsmin_state(const std::string &varname, const pbes_expression &e)
Constructor.
std::string get_variable() const
Returns a string representation of the propositional variable of the state.
const std::vector< data_expression > & get_parameter_values() const
Returns the list of parameter values.
Class for generating a BES from a PBES. This BES can be interpreted as a graph corresponding to a par...
operation_type
The operation type of the vertices.
parameterized boolean equation system
Definition pbes.h:54
propositional_variable_instantiation & initial_state()
Returns the initial state.
Definition pbes.h:194
\brief A propositional variable instantiation
const data::data_expression_list & parameters() const
\brief A propositional variable declaration
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:435
atermpp::aterm remove_index(const atermpp::aterm &x)
Definition io.h:50
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.
MapContainer::mapped_type map_at(const MapContainer &m, typename MapContainer::key_type key)
bool is_data(const pbes_expression &t)
Returns true if the term t is a data expression.
const pbes_expression & true_()
bool is_not(const atermpp::aterm &x)
bool is_exists(const atermpp::aterm &x)
bool is_or(const atermpp::aterm &x)
bool is_forall(const atermpp::aterm &x)
bool is_propositional_variable_instantiation(const atermpp::aterm &x)
bool is_and(const atermpp::aterm &x)
bool is_imp(const atermpp::aterm &x)
const pbes_expression & false_()