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 mcrl2/pbes/pbes_explorer.cpp
10/// \brief
11#include <climits>
12#include <queue>
13
14#include "mcrl2/data/detail/io.h"
15#include "mcrl2/data/representative_generator.h"
16#include "mcrl2/pbes/detail/ppg_visitor.h"
17#include "mcrl2/pbes/io.h"
18#include "mcrl2/pbes/pbes_explorer.h"
19
20
21namespace mcrl2
22{
23
24namespace pbes_system
25{
26
27namespace detail
28{
29 template <typename MapContainer>
30 typename MapContainer::mapped_type map_at(const MapContainer& m, typename MapContainer::key_type key)
31 {
32 typename MapContainer::const_iterator i = m.find(key);
33 if (i == m.end())
34 {
35 throw mcrl2::runtime_error("map_at: key is not present in the map: " + key);
36 }
37 return i->second;
38 }
39} // namespace detail
40
41/// lts_type
42
43lts_type::lts_type(int state_length)
44{
45 this->state_length = state_length;
46}
47
48
50{}
51
52
54{
55 return this->state_length;
56}
57
58
60{
61 return this->state_type_list.size();
62}
63
64
65int lts_type::get_state_type_no(int part) const
66{
67 return this->state_type_no.at(part);
68}
69
70std::string lts_type::get_state_type_name(int type_no) const
71{
72 return this->state_type_list.at(type_no);
73}
74
76{
77 return state_names;
78}
79
80
82{
83 return state_types;
84}
85
86
88{
89 return this->state_label_names.size();
90}
91
92
94{
95 return state_label_names;
96}
97
98
100{
101 return state_label_types;
102}
103
104
106{
107 return this->edge_label_names.size();
108}
109
110
112{
113 return edge_label_names;
114}
115
116
118{
119 return edge_label_types;
120}
121
122
123void lts_type::add_state(const std::string& name, const std::string& type)
124{
125 //std::clog << "Adding state part " << this->state_names->size() << ": "
126 // << info::get_param_signature(name, type)
127 // << std::endl;
128 this->state_names.push_back(name);
129 this->state_types.push_back(type);
130 std::size_t type_index;
131 std::map<std::string,int>::iterator type_index_it = this->state_type_index.find(type);
132 if (type_index_it != this->state_type_index.end()) {
133 type_index = type_index_it->second;
134 } else {
135 this->state_type_list.push_back(type);
136 type_index = this->state_type_list.size() - 1;
137 this->state_type_index[type] = type_index;
138 }
139 this->state_type_no.push_back(type_index);
140 //std::clog << " type_no = " << type_index << ": " << this->state_type_list->at(type_index) << std::endl;
141}
142
143
144void lts_type::add_state_label(const std::string& name,
145 const std::string& type)
146{
147 this->state_label_names.push_back(name);
148 this->state_label_types.push_back(type);
149}
150
151
152void lts_type::add_edge_label(const std::string& name,
153 const std::string& type)
154{
155 this->edge_label_names.push_back(name);
156 this->edge_label_types.push_back(type);
157}
158
159
160
161
162/// lts_info
163
164lts_info::lts_info(pbes& p, detail::pbes_greybox_interface* pgg, bool reset = false, bool always_split = false):
165 p(p),
166 pgg(pgg),
167 reset_option(reset),
168 always_split_option(always_split),
169 type(0)
170{
171 if (!detail::is_ppg(p))
172 {
173 throw std::runtime_error("PBES is not a PPG! Please rewrite with pbesrewr -pppg.");
174 }
175 //std::clog << "info: resetOption = " << (this->resetOption ? "true":"false") << ", reset = " << reset << std::endl;
179}
180
181
183{
184 //std::clog << "pbes_type:" << std::endl;
185 mCRL2log(log::verbose) << "Compute LTS type." << std::endl;
186 std::vector<std::string> params;
187 std::map<std::string,std::string> paramtypes;
188 data::representative_generator default_expression_generator(p.data());
189
190 for (const auto& eqn : p.equations())
191 {
192 //std::clog << core::pp((*eqn).symbol()) << " " << (*eqn).variable().name()
193 // << std::endl;
194
195 propositional_variable var = eqn.variable();
196 for (const variable& varparam: var.parameters())
197 {
198 std::string signature = get_param_signature(varparam);
199 bool new_param = true;
200 for (auto & param : params) {
201 if (signature == param) new_param = false;
202 }
203 if (new_param) {
204 params.push_back(signature);
205 paramtypes[signature] = core::pp(varparam.sort());
206 //std::clog << "paramtypes[" << signature << "] = " << paramtypes[signature] << std::endl;
207 data_expression e(default_expression_generator(varparam.sort()));
208 pbes_expression e1 = pgg->rewrite_and_simplify_expression(e,false);
209 this->param_default_values.push_back(atermpp::down_cast<const data::data_expression>(e1));
210 }
211 }
212 //params.sort();
213 }
214 this->type = lts_type(1 + params.size());
215 this->type.add_state("var", "string"); // Propositional variable name
216
217 int i = 0;
218 for (const std::string& signature: params) {
219 this->type.add_state(signature, paramtypes[signature]);
220 this->param_index[signature] = i;
221 i++;
222 }
223
224 this->type.add_state_label("priority", "int");
225 this->type.add_state_label("type", "int");
226
227 //this->type->add_edge_label("", "");
228 //std::clog << "-- end of pbes_type." << std::endl;
229 mCRL2log(log::verbose) << "end of compute_lts_type." << std::endl;
230}
231
232
234{
235 std::string varname = std::string(propvar.name());
236 data::variable_list params = this->variable_parameters[varname];
237 const data::data_expression_list& values = propvar.parameters();
238 if (params.size() != values.size())
239 {
240 return false;
241 }
242 else
243 {
244 data::variable_list::const_iterator param_it = params.begin();
245 for(const auto & value : values)
246 {
247 if (!data::is_variable(value))
248 {
249 return false;
250 }
251 else
252 {
253 data::variable param(*param_it);
254 data::variable param_expr(value);
255 if (param != param_expr)
256 {
257 return false;
258 }
259 }
260 if (param_it != params.end())
261 {
262 ++param_it;
263 }
264 }
265 }
266 if(params != values)
267 {
268 throw mcrl2::runtime_error("is_pass_through_state check failed on " + data::pp(params) + " " + data::pp(values));
269 }
270 return true;
271}
272
273
275{
277 {
278 return 1;
279 }
280 else if (is_and(e) || is_or(e) || is_imp(e))
281 {
284
285 if (a < INT_MAX && b < INT_MAX)
286 {
287 return a + b;
288 }
289 else
290 {
291 return INT_MAX;
292 }
293 }
294 else if (is_forall(e) || is_exists(e))
295 {
297 {
298 return INT_MAX;
299 }
300 else
301 {
302 return 0;
303 }
304 }
305 else if (is_not(e))
306 {
308 }
309 else if (is_data(e))
310 {
311 return 0;
312 }
313 else
314 {
315 throw(std::runtime_error("Unexpected expression: " + pbes_system::pp(e)));
316 }
317}
318
320{
321 std::vector<pbes_expression> result;
322 std::vector<pbes_expression> parts;
323 if (is_simple_expression(e))
324 {
325 result.push_back(e);
326 }
328 {
329 result.push_back(e);
330 }
331 else if (is_and(e)) {
332 parts = split_conjuncts(e, true);
333 } else if (is_or(e)) {
334 parts = split_disjuncts(e, true);
335 } else {
336 parts.push_back(e);
337 }
338
339 bool pass_through = true;
340
341 for(std::vector<pbes_expression>::iterator p_it = parts.begin(); pass_through && p_it != parts.end(); ++p_it)
342 {
343 pbes_expression part = *p_it;
344 if (is_propositional_variable_instantiation(part))
345 {
346 // Try to substitute the variable instantiation with the associated expression
347
348 propositional_variable_instantiation propvar = (propositional_variable_instantiation)part;
349 if (is_pass_through_state(propvar))
350 {
351 // The variable instantiation only copies the current parameters and local data variables,
352 // so substitution is safe with respect to that.
353
354 std::string varname = std::string(propvar.name());
355 int priority = this->variable_priority[varname];
356 operation_type type = this->variable_type[varname];
357 pbes_expression expr = this->variable_expression[varname];
358
359 if ((priority == current_priority) &&
360 (current_type == type || is_simple_expression(expr) || count_variables(expr) <= 1) &&
361 vars_stack.find(varname) == vars_stack.end())
362 {
363 // The associated equation has the same priority and operation type as the current equation,
364 // so substitution is safe.
365
366 //std::clog << " Substituting variable instantiation: " << pbes_system::pp(part) << std::endl
367 // << " with: " << pbes_system::pp(expr) << std::endl;
368
369 // Recursively try to further substitute variables:
370 // (vars_stack is used to prevent infinite recursion)
371 std::set<std::string> new_vars_stack(vars_stack.begin(), vars_stack.end());
372 new_vars_stack.insert(varname);
373 std::vector<pbes_expression> part_result = split_expression_and_substitute_variables(expr, current_priority, current_type, new_vars_stack);
374 result.insert(result.end(), part_result.begin(), part_result.end());
375 }
376 else
377 {
378 result.push_back(part);
379 }
380 }
381 else
382 {
383 pass_through = false;
384 }
385 }
386 else
387 {
388 pass_through = false;
389 }
390 }
391 if (!pass_through)
392 {
393 if (always_split_option && !parts.empty())
394 {
395 // the old behaviour of the explorer: always split conjunctions and disjunctions
396 // into subexpressions that form groups
397 result = parts;
398 }
399 else
400 {
401 // the new behaviour: only split expressions if every part is a pass-through variable instantiation,
402 // i.e., all values are copied and not changed.
403 result.clear();
404 result.push_back(e);
405 }
406 }
407 return result;
408}
409
410
412{
413 mCRL2log(log::verbose) << "Compute transition groups." << std::endl;
414
415 int group = 0;
416 int priority = 0;
417 operation_type type = parity_game_generator::PGAME_AND;
419 detail::ppg_visitor checker;
420
421 std::string name = "true";
422 propositional_variable t{core::identifier_string(name), data::variable_list()};
423 this->variables[name] = t;
424 this->variable_type[name] = type;
425 this->variable_symbol[name] = symbol;
426 this->variable_priority[name] = priority;
427 this->variable_parameters[name] = t.parameters();
428 this->variable_parameter_signatures[name] = get_param_sequence(t.parameters());
429 this->variable_parameter_indices[name] = this->get_param_indices(t.parameters());
430 this->variable_parameter_index_positions[name] = this->get_param_index_positions(t.parameters());
431 this->transition_expression_plain.push_back(true_());
432 this->transition_expression.push_back(pgg->rewrite_and_simplify_expression(true_()));
433 this->transition_variable_name.push_back(name);
434 this->transition_type.push_back(type);
435 group++;
436 priority++;
437
438 name = "false";
441 propositional_variable f{core::identifier_string(name), data::variable_list()};
442 this->variables[name] = f;
443 this->variable_type[name] = type;
444 this->variable_symbol[name] = symbol;
445 this->variable_priority[name] = priority;
446 this->variable_parameters[name] = f.parameters();
447 this->variable_parameter_signatures[name] = get_param_sequence(f.parameters());
448 this->variable_parameter_indices[name] = this->get_param_indices(f.parameters());
449 this->variable_parameter_index_positions[name] = this->get_param_index_positions(f.parameters());
450 this->transition_expression_plain.push_back(false_());
451 this->transition_expression.push_back(pgg->rewrite_and_simplify_expression(false_()));
452 this->transition_variable_name.push_back(name);
453 this->transition_type.push_back(type);
454 group++;
455 priority++;
456
458
459 for (auto & eqn : p.equations()) {
460 pbes_expression expr = pgg->get_pbes_equation(eqn.variable().name()).formula();
461 std::string variable_name = eqn.variable().name();
462 this->variables[variable_name] = eqn.variable();
463 type = pgg->get_expression_operation(expr);
464 this->variable_type[variable_name] = type;
465 this->variable_symbol[variable_name] = eqn.symbol();
466 if (eqn.symbol() != symbol) {
467 priority++;
468 symbol = eqn.symbol();
469 }
470 mCRL2log(log::debug) << "Adding var " << variable_name << ", priority=" << priority << ", symbol=" << symbol << std::endl;
471 this->variable_priority[variable_name] = priority;
472 this->variable_parameters[variable_name] = eqn.variable().parameters();
473 this->variable_parameter_signatures[variable_name] = get_param_sequence(eqn.variable().parameters());
474 this->variable_parameter_indices[variable_name] = this->get_param_indices(eqn.variable().parameters());
475 this->variable_parameter_index_positions[variable_name] = this->get_param_index_positions(eqn.variable().parameters());
476 this->variable_expression[variable_name] = expr;
477 }
478
479 // Skip 'unused' equations....
480 std::set<std::string> variable_set;
481 {
483 std::queue<std::string> variable_queue;
484 variable_queue.push(init.name());
485 variable_set.insert(init.name());
486 while (!variable_queue.empty())
487 {
488 std::string var = variable_queue.front();
489 variable_queue.pop();
490 type = this->variable_type[var];
491 priority = this->variable_priority[var];
492 pbes_expression expr = this->variable_expression[var];
493 std::set<std::string> vars_stack;
494 std::vector<pbes_expression> expression_parts = split_expression_and_substitute_variables(expr, priority, type, vars_stack);
495 for (std::vector<pbes_expression>::const_iterator e =
496 expression_parts.begin(); e != expression_parts.end(); ++e) {
497 std::set<std::string> occ_vars = lts_info::occ(*e);
498 for (const auto & var_str : variable_set)
499 {
500 occ_vars.erase(var_str);
501 }
502 for(const auto & occ_var : occ_vars)
503 {
504 variable_queue.push(occ_var);
505 }
506 variable_set.insert(occ_vars.begin(), occ_vars.end());
507 }
508 }
509 mCRL2log(log::debug) << "Set of 'used' variables: " << std::endl;
510 for (const auto & var_str : variable_set)
511 {
512 mCRL2log(log::debug) << " " << var_str << std::endl;
513 }
514 mCRL2log(log::debug) << std::endl;
515 }
516
517 for (auto & eqn : p.equations()) {
518 std::string variable_name = eqn.variable().name();
519 if (variable_set.find(variable_name) != variable_set.end())
520 {
521 type = this->variable_type[variable_name];
522 priority = this->variable_priority[variable_name];
523 pbes_expression expr = this->variable_expression[variable_name];
524 std::set<std::string> vars_stack;
525 mCRL2log(log::debug) << std::endl << "Generating groups for equation " << variable_name << std::endl;
526 std::vector<pbes_expression> expression_parts = split_expression_and_substitute_variables(expr, priority, type, vars_stack);
527 for (std::vector<pbes_expression>::const_iterator e =
528 expression_parts.begin(); e != expression_parts.end(); ++e) {
529 this->transition_expression_plain.push_back(*e);
530 this->transition_expression.push_back(pgg->rewrite_and_simplify_expression(*e));
531 this->transition_variable_name.push_back(variable_name);
532 this->transition_type.push_back(type);
533 mCRL2log(log::debug) << "Add transition group " << group << ": "
534 << (type==parity_game_generator::PGAME_AND ? "AND" : "OR") << " " << variable_name << " "
535 << pbes_system::pp(*e) << std::endl;
536 group++;
537 }
538 }
539 }
540 number_of_groups = group;
541 //std::clog << "Added " << group << " transition groups." << std::endl;
542 mCRL2log(log::debug) << "end of compute_transition_groups." << std::endl;
543}
544
545
547{
548 mCRL2log(log::verbose) << "Compute dependency matrix." << std::endl;
549 for(int group=0; group < number_of_groups; group++)
550 {
551 std::vector<bool> dep_row;
552 std::vector<bool> read_row;
553 std::vector<bool> write_row;
554 bool r = is_read_dependent_propvar(group);
555 bool w = is_write_dependent_propvar(group);
556 bool d = r || w;
557 dep_row.push_back(d);
558 read_row.push_back(r);
559 write_row.push_back(w);
560 for (int part = 1; part < type.get_state_length(); part++)
561 {
562 r = is_read_dependent_parameter(group, part);
563 w = is_write_dependent_parameter(group, part);
564 d = r || w;
565 dep_row.push_back(d);
566 read_row.push_back(r);
567 write_row.push_back(w);
568 }
569 matrix[group] = dep_row;
570 read_matrix[group] = read_row;
571 write_matrix[group] = write_row;
572 }
573 mCRL2log(log::verbose) << "end of compute_dependency_matrix." << std::endl;
574}
575
576
578{
579 return reset_option;
580}
581
582
584{
585 return number_of_groups;
586}
587
588
590{
591 return transition_expression;
592}
593
594
596{
597 return transition_variable_name;
598}
599
600
602{
603 return transition_type;
604}
605
606
608{
609 return variables;
610}
611
612
614{
615 return variable_type;
616}
617
619{
620 return variable_symbol;
621}
622
623
625{
626 return variable_priority;
627}
628
629
631{
632 return variable_parameters;
633}
634
635
637{
638 return variable_parameter_signatures;
639}
640
641
643{
644 return variable_parameter_indices;
645}
646
647
649{
650 return variable_parameter_index_positions;
651}
652
653
655{
656 return type;
657}
658
659
660const std::map<int,std::vector<bool> >& lts_info::get_dependency_matrix() const
661{
662 return matrix;
663}
664
665
666const std::map<int,std::vector<bool> >& lts_info::get_read_matrix() const
667{
668 return read_matrix;
669}
670
671
672const std::map<int,std::vector<bool> >& lts_info::get_write_matrix() const
673{
674 return write_matrix;
675}
676
677
678int lts_info::get_index(const std::string& signature)
679{
680 return param_index[signature];
681}
682
683
685{
686 return param_default_values.at(index);
687}
688
689
691{
692 return true;
693}
694
695
696bool lts_info::is_read_dependent_parameter(int group, int part)
697{
698 if (group==0 || group==1) return false;
699 std::string p = type.get_state_names()[part];
700 mCRL2log(log::debug) << "is_read_dependent_parameter (group=" << group << ", part=" << part << " [" << p << "]" << std::endl;
701 pbes_expression phi = transition_expression_plain[group];
702 std::string X = transition_variable_name[group];
703 std::set<std::string> params = lts_info::get_param_set(variable_parameters[X]);
704 if (params.find(p) == params.end())
705 {
706 return false; // Parameter is not in params(X).
707 }
708 else
709 {
710 std::set<std::string> usedSet = used(phi);
711 std::set<std::string> changedSet = changed(phi);
712 std::set<std::string> copySet = copied(phi);
713 std::set<std::string> changedAndCopied;
714 std::set_intersection(changedSet.begin(), changedSet.end(), copySet.begin(), copySet.end(),
715 std::inserter(changedAndCopied, changedAndCopied.end()));
716
717 if (usedSet.find(p) == usedSet.end() && changedAndCopied.find(p) == changedAndCopied.end())
718 {
719 // Parameter is not in used(phi) and not in (changed(phi) /\ copied(phi)).
720 return false; // Parameter is not in used(phi).
721 }
722 else
723 {
724 return true; // Parameter is both in used(phi) and in params(X).
725 }
726 }
727
728}
729
730
732{
733 if (group==0 || group==1) return false;
734 pbes_expression phi = transition_expression_plain[group];
735 std::string X = transition_variable_name[group];
736 if (lts_info::tf(phi))
737 {
738 return true;
739 }
740 std::set<std::string> occ = lts_info::occ(phi);
741 if (occ.empty())
742 {
743 return false; // Not dependent if occ(phi) == {}.
744 }
745 else if (occ.size() == 1)
746 {
747 bool containsX = occ.find(X) != occ.end();
748 return !containsX; // Not dependent if occ(phi) == {X}.
749 }
750 else
751 {
752 return true; // Dependent, because occ(phi) contains multiple elements.
753 }
754}
755
756
757bool lts_info::is_write_dependent_parameter(int group , int part)
758{
759 if (group==0 || group==1) return false;
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 (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 (std::vector<std::string>::const_iterator param =
822 var_param_signatures.begin(); param != var_param_signatures.end(); ++param) {
823 std::string param_signature = *param;
824 if (data::is_variable(*val))
825 {
826 const variable& value = atermpp::down_cast<variable>(*val);
827 std::string value_signature = get_param_signature(value);
828 if (param_signature != value_signature || L.find(value_signature) != L.end())
829 {
830 result.insert(param_signature);
831 }
832 }
833 else
834 {
835 result.insert(param_signature);
836 }
837 if (val != values.end()) {
838 ++val;
839 }
840 }
841 }
842 return result;
843}
844
845
847{
848 std::set<std::string> result;
849 if (is_not(phi))
850 {
851 result = reset(pbes_system::accessors::arg(phi), d);
852 }
853 else if (is_and(phi) || is_or(phi) || is_imp(phi))
854 {
855 std::set<std::string> l = reset(pbes_system::accessors::left(phi), d);
856 result.insert(l.begin(), l.end());
857 std::set<std::string> r = reset(pbes_system::accessors::right(phi), d);
858 result.insert(r.begin(), r.end());
859 }
860 else if (is_forall(phi) || is_exists(phi))
861 {
862 result = reset(pbes_system::accessors::arg(phi), d);
863 }
865 {
866 std::set<std::string> params;
867 std::vector<std::string> var_params =
868 variable_parameter_signatures[atermpp::down_cast<propositional_variable_instantiation>(phi).name()];
869 for (std::vector<std::string>::const_iterator param =
870 var_params.begin(); param != var_params.end(); ++param) {
871 std::string signature = *param;
872 params.insert(signature);
873 }
874 for (auto signature : d) {
875 if (params.find(signature) == params.end())
876 {
877 result.insert(signature);
878 }
879 }
880 }
881 return result;
882}
883
884
885bool lts_info::tf(const pbes_expression& phi)
886{
887 if (is_not(phi))
888 {
890 }
891 else if (is_and(phi) || is_or(phi) || is_imp(phi))
892 {
894 }
895 else if (is_forall(phi) || is_exists(phi))
896 {
898 }
900 {
901 return false;
902 }
903 return true;
904}
905
906
907std::set<std::string> lts_info::occ(const pbes_expression& expr)
908{
909 std::set<std::string> result;
911 {
912 result.insert(atermpp::down_cast<propositional_variable_instantiation>(expr).name());
913 }
914 else if (is_and(expr) || is_or(expr) ||is_imp(expr))
915 {
916 std::set<std::string> l = occ(pbes_system::accessors::left(expr));
917 result.insert(l.begin(), l.end());
918 std::set<std::string> r = occ(pbes_system::accessors::right(expr));
919 result.insert(r.begin(), r.end());
920 }
921 else if (is_forall(expr) || is_exists(expr) || is_not(expr))
922 {
923 result = occ(pbes_system::accessors::arg(expr));
924 }
925 return result;
926}
927
928
929std::set<std::string> lts_info::free(const pbes_expression& expr)
930{
931 std::set<std::string> result;
932 for (const data::variable& var: pbes_system::find_free_variables(expr))
933 {
934 result.insert(get_param_signature(var));
935 }
936 return result;
937}
938
939
941{
942 std::set<std::string> emptySet;
943 return used(expr, emptySet);
944}
945
946
948{
949 //std::clog << "lts_info::used(" << bqnf_visitor<equation_type, term_type>::print_brief(expr) << ", L)" << std::endl;
950 std::set<std::string> result;
951 if (is_data(expr))
952 {
953 std::set<std::string> fv = free(expr);
954 result.insert(fv.begin(), fv.end());
955 }
957 {
958 data::variable_list var_params =
959 variable_parameters[atermpp::down_cast<propositional_variable_instantiation>(expr).name()];
960 data::data_expression_list values = atermpp::down_cast<propositional_variable_instantiation>(expr).parameters();
961 assert(var_params.size() == values.size());
962 data::data_expression_list::const_iterator val = values.begin();
963 for (auto parameter : var_params) {
964 std::string param_signature = get_param_signature(parameter);
965 if (data::is_variable(*val))
966 {
967 const variable& value = atermpp::down_cast<variable>(*val);
968 std::string value_signature = get_param_signature(value);
969 if (param_signature != value_signature || L.find(value_signature) != L.end())
970 {
971 result.insert(value_signature);
972 }
973 }
974 else
975 {
976 // add free variables in data expression
977 std::set<std::string> l = used(*val, L);
978 result.insert(l.begin(), l.end());
979 }
980 if (val != values.end()) {
981 ++val;
982 }
983 }
984 }
985 else if (is_and(expr) || is_or(expr) || is_imp(expr))
986 {
987 std::set<std::string> l = used(pbes_system::accessors::left(expr), L);
988 result.insert(l.begin(), l.end());
989 std::set<std::string> r = used(pbes_system::accessors::right(expr), L);
990 result.insert(r.begin(), r.end());
991 }
992 else if (is_not(expr))
993 {
994 result = used(pbes_system::accessors::arg(expr), L);
995 }
996 else if (is_forall(expr) || is_exists(expr))
997 {
998 std::set<std::string> LL;
999 LL.insert(L.begin(), L.end());
1000 data::variable_list vars = quantifier_variables(expr);
1001 for (auto variable : vars)
1002 {
1003 LL.insert(get_param_signature(variable));
1004 }
1005 result = used(pbes_system::accessors::arg(expr), LL);
1006 }
1007 return result;
1008}
1009
1010
1012{
1013 std::set<std::string> emptySet;
1014 return copied(expr, emptySet);
1015}
1016
1017
1019{
1020 //std::clog << "lts_info::copied(" << bqnf_visitor<equation_type, term_type>::print_brief(expr) << ", L)" << std::endl;
1021 std::set<std::string> result;
1022 if (is_data(expr))
1023 {
1024 // skip
1025 }
1027 {
1028 data::variable_list var_params =
1029 variable_parameters[atermpp::down_cast<propositional_variable_instantiation>(expr).name()];
1030 data::data_expression_list values = atermpp::down_cast<propositional_variable_instantiation>(expr).parameters();
1031 assert(var_params.size() == values.size());
1032 data::data_expression_list::const_iterator val = values.begin();
1033 for (auto parameter : var_params) {
1034 std::string param_signature = get_param_signature(parameter);
1035 if (data::is_variable(*val))
1036 {
1037 const variable& value = atermpp::down_cast<variable>(*val);
1038 std::string value_signature = get_param_signature(value);
1039 if (param_signature == value_signature && L.find(value_signature) == L.end())
1040 {
1041 result.insert(value_signature);
1042 }
1043 }
1044 if (val != values.end()) {
1045 ++val;
1046 }
1047 }
1048 }
1049 else if (is_and(expr) || is_or(expr) || is_imp(expr))
1050 {
1051 std::set<std::string> l = copied(pbes_system::accessors::left(expr), L);
1052 result.insert(l.begin(), l.end());
1053 std::set<std::string> r = copied(pbes_system::accessors::right(expr), L);
1054 result.insert(r.begin(), r.end());
1055 }
1056 else if (is_not(expr))
1057 {
1058 result = copied(pbes_system::accessors::arg(expr), L);
1059 }
1060 else if (is_forall(expr) || is_exists(expr))
1061 {
1062 std::set<std::string> LL;
1063 LL.insert(L.begin(), L.end());
1064 data::variable_list vars = quantifier_variables(expr);
1065 for (auto variable : vars)
1066 {
1067 LL.insert(get_param_signature(variable));
1068 }
1069 result = copied(pbes_system::accessors::arg(expr), LL);
1070 }
1071 return result;
1072}
1073
1074
1076{
1077 //std::clog << "info::to_string" << std::endl;
1078 std::string result;
1079 std::stringstream ss;
1080 operation_type type = detail::map_at(get_variable_types(), state.get_variable());
1081 ss << (type==parity_game_generator::PGAME_AND ? "AND" : "OR");
1082 ss << ":" << state.get_variable();
1083 ss << "(";
1084 const std::vector<data_expression>& param_values = state.get_parameter_values();
1085 std::vector<std::string> param_signatures =
1086 this->variable_parameter_signatures[state.get_variable()];
1087 std::vector<std::string>::const_iterator param_signature =
1088 param_signatures.begin();
1089 for (std::vector<data_expression>::const_iterator param_value =
1090 param_values.begin(); param_value != param_values.end(); ++param_value) {
1091 if (param_value != param_values.begin())
1092 ss << ", ";
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 (auto parameter : params) {
1110 result.insert(get_param_signature(parameter));
1111 }
1112 return result;
1113}
1114
1115
1116std::vector<std::string> lts_info::get_param_sequence(const data::variable_list& params)
1117{
1118 std::vector<std::string> result;
1119 for (auto parameter : params) {
1120 result.push_back(get_param_signature(parameter));
1121 }
1122 return result;
1123}
1124
1125
1127{
1128 std::vector<int> result;
1129 for (auto parameter : params) {
1130 int index = this->get_index(get_param_signature(parameter));
1131 result.push_back(index);
1132 }
1133 return result;
1134}
1135
1136
1138{
1139 std::map<int,int> result;
1140 int i = 0;
1141 for (auto parameter : params) {
1142 int index = this->get_index(get_param_signature(parameter));
1143 result.insert(std::make_pair(index,i));
1144 i++;
1145 }
1146 return result;
1147}
1148
1149
1151
1152
1154{
1155 std::map<variable,std::string>::const_iterator i = variable_signatures.find(param);
1156 if (i == variable_signatures.end())
1157 {
1158 std::string paramname = param.name();
1159 std::string paramtype = core::pp(param.sort());
1160 std::string signature = get_param_signature(paramname, paramtype);
1161 variable_signatures[param] = signature;
1162 return signature;
1163 }
1164 return i->second;
1165}
1166
1167
1168std::string lts_info::get_param_signature(const std::string& paramname,
1169 const std::string& paramtype)
1170{
1171 return paramname + ":" + paramtype;
1172}
1173
1174
1175
1176
1177// ltsmin_state
1178
1179ltsmin_state::ltsmin_state(const std::string& varname)
1180{
1181 this->var = varname;
1182}
1183
1184
1185ltsmin_state::ltsmin_state(const std::string& varname,
1186 const pbes_expression& e)
1187{
1188 data_expression novalue;
1189 //std::clog << "ltsmin_state v = " << pp(v) << std::endl;
1190 this->var = varname;
1192 assert(std::string(atermpp::down_cast<propositional_variable_instantiation>(e).name()) == varname);
1193 //std::clog << "ltsmin_state: var = " << atermpp::down_cast<propositional_variable_instantiation>(e).name() << std::endl;
1194 const data::data_expression_list& values = atermpp::down_cast<propositional_variable_instantiation>(e).parameters();
1195 for (const auto & value : values)
1196 {
1197 if (value == novalue)
1198 {
1199 throw(std::runtime_error("Error in ltsmin_state: state expression contains NoValue: "
1200 + pp(e)));
1201 }
1202 this->add_parameter_value(value);
1203 //std::clog << "ltsmin_state: " << *val << std::endl;
1204 }
1205 //std::clog << std::endl;
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) return true;
1214 else if (this->var == other.var)
1215 {
1216 if (param_values.size() < other.param_values.size()) return true;
1217 else if (param_values.size() == other.param_values.size())
1218 {
1219 if (param_values < other.param_values) return true;
1220 }
1221 }
1222 return false;
1223}
1224
1225
1226bool ltsmin_state::operator==( const ltsmin_state& other ) const
1227{
1228 return this->var==other.var
1229 && param_values.size()==other.param_values.size()
1230 && param_values == other.param_values;
1231}
1232
1233
1235{
1236 return var;
1237}
1238
1239
1241{
1242 return param_values;
1243}
1244
1245
1247{
1248 param_values.push_back(value);
1249}
1250
1251
1253{
1254 data::data_expression_vector parameter_values;
1255 for (const auto & param_value : param_values) {
1256 parameter_values.push_back(param_value);
1257 }
1258 data::data_expression_list parameter_values_list(parameter_values.begin(), parameter_values.end());
1259 // Create propositional variable instantiation.
1261 propositional_variable_instantiation(core::identifier_string(var), parameter_values_list);
1262 return workaround::return_std_move(expr);
1263}
1264
1265
1267{
1268 std::string result;
1269 std::stringstream ss;
1270 ss << (type==parity_game_generator::PGAME_AND ? "AND" : "OR");
1271 ss << ":" << var;
1272 ss << "[" << std::endl;
1273 for (std::vector<data_expression>::const_iterator entry =
1274 param_values.begin(); entry != param_values.end(); ++entry) {
1275 if (entry != param_values.begin())
1276 ss << std::endl << " value = ";
1277 ss << *entry;
1278 }
1279 ss << "]";
1280 result = ss.str();
1281 return result;
1282}
1283
1284
1285
1286
1287/// explorer
1288
1289explorer::explorer(const std::string& filename, const std::string& rewrite_strategy = "jittyc", bool reset_flag = false, bool always_split_flag = false)
1290{
1291 load_pbes(p, filename);
1292 for (auto & eqn : p.equations()) {
1293 std::string variable_name = eqn.variable().name();
1294 //std::clog << "varname = " << variable_name << std::endl;
1295 }
1296 pbes_system::algorithms::normalize(p);
1297 if (!detail::is_ppg(p))
1298 {
1299 mCRL2log(log::info) << "Rewriting to PPG..." << std::endl;
1300 p = detail::to_ppg(p);
1301 mCRL2log(log::info) << "Rewriting done." << std::endl;
1302 }
1303 this->pgg = new detail::pbes_greybox_interface(p, true, true, data::parse_rewrite_strategy(rewrite_strategy));
1304 this->info = new lts_info(p, pgg, reset_flag, always_split_flag);
1305 //std::clog << "explorer" << std::endl;
1306 for (std::size_t i = 0; i < info->get_lts_type().get_number_of_state_types(); ++i) {
1307 std::map<data_expression,int> data2int_map;
1308 this->localmaps_data2int.push_back(data2int_map);
1309 std::vector<data_expression> int2data_map;
1310 this->localmaps_int2data.push_back(int2data_map);
1311 }
1312 //std::clog << "-- end of explorer." << std::endl;
1313}
1314
1315
1316explorer::explorer(const pbes& p_, const std::string& rewrite_strategy = "jittyc", bool reset_flag = false, bool always_split_flag = false)
1317{
1318 p = p_;
1319 this->pgg = new detail::pbes_greybox_interface(p, true, true, data::parse_rewrite_strategy(rewrite_strategy));
1320 this->info = new lts_info(p, pgg, reset_flag, always_split_flag);
1321 //std::clog << "explorer" << std::endl;
1322 for (std::size_t i = 0; i < info->get_lts_type().get_number_of_state_types(); i++) {
1323 std::map<data_expression,int> data2int_map;
1324 this->localmaps_data2int.push_back(data2int_map);
1325 std::vector<data_expression> int2data_map;
1326 this->localmaps_int2data.push_back(int2data_map);
1327 }
1328 //std::clog << "-- end of explorer." << std::endl;
1329}
1330
1331
1333{
1334 delete info;
1335 delete pgg;
1336}
1337
1338
1340{
1341 return info;
1342}
1343
1344
1346{
1348 return this->get_state(initial_state);
1349}
1350
1351
1352void explorer::initial_state(int* state)
1353{
1354 ltsmin_state initial_state = this->get_initial_state();
1355 ltsmin_state dummy("dummy");
1356 this->to_state_vector(initial_state, state, dummy, nullptr);
1357}
1358
1359
1361{
1362 //std::clog << "-- get_state --" << std::endl;
1363 //std::clog << " expr = " << expr << std::endl;
1365 assert(is_propositional_variable_instantiation(expr) && expr != novalue);
1366 std::string varname = expr.name();
1367 //std::clog << " varname = " << varname << std::endl;
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{
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 {
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 //std::clog << "[" << getpid() << "] get_string_index DEBUG push_back " << index << ": " << s << std::endl;
1416 this->localmap_string2int.insert(std::make_pair(s,index));
1417 }
1418 //std::clog << "get_string_index result =" << index << " (" << this->localmap_int2string->size() << ")" << std::endl;
1419 return index;
1420}
1421
1422
1423int explorer::get_value_index(int type_no, const data_expression& value)
1424{
1425 //std::clog << " get_value_index type_no=" << type_no << " (" << info->get_lts_type().get_number_of_state_types() << ")" << std::endl;
1426 //std::clog << " type=" << info->get_lts_type().get_state_type_name(type_no) << std::endl;
1427 //std::clog << " value=" << value << std::endl;
1428 std::map<data_expression,int>& data2int_map = this->localmaps_data2int.at(type_no);
1429 std::map<data_expression,int>::iterator it = data2int_map.find(value);
1430 std::size_t index;
1431 if (it != data2int_map.end()) {
1432 index = it->second;
1433 } else {
1434 this->localmaps_int2data.at(type_no).push_back(value);
1435 index = this->localmaps_int2data.at(type_no).size() - 1;
1436 data2int_map.insert(std::make_pair(value,index));
1437 }
1438 return index;
1439}
1440
1441
1442void explorer::to_state_vector(const ltsmin_state& dst_state, int* dst, const ltsmin_state& src_state, int* const& src)
1443{
1444 //std::clog << "to_state_vector: " << dst_state.to_string() << std::endl;
1445
1446 data_expression novalue;
1447 //std::clog << "-- to_state_vector -- " << std::endl;
1448 int state_length = info->get_lts_type().get_state_length();
1449
1450 std::string varname = dst_state.get_variable();
1451 std::string src_varname;
1452 bool same_var = false;
1453 if (!(src==nullptr)) {
1454 src_varname = src_state.get_variable();
1455 same_var = (varname==src_varname);
1456 }
1457 int varindex;
1458 if (same_var) {
1459 varindex = src[0];
1460 } else {
1461 varindex = this->get_string_index(varname);
1462 }
1463 dst[0] = varindex;
1464 //std::clog << " to_state_vector: DEBUG: varname = " << varname << " index = " << varindex << (same_var ? " SAME VAR": "") << std::endl;
1465
1466
1467 // data_expression values[state_length]; N.B. This is not portable C++
1468 std::vector < data_expression > values(state_length);
1469
1470 if (info->get_reset_option() || src == nullptr) {
1471 int type_no;
1472 for (int i = 1; i < state_length; i++) {
1473 data_expression default_value = info->get_default_value(i-1);
1474 values[i] = default_value;
1476 dst[i] = this->get_value_index(type_no, values[i]);
1477 }
1478 } else {
1479 for (int i = 1; i < state_length; i++) {
1480 dst[i] = src[i];
1481 }
1482 }
1483 bool error = false;
1484 const std::vector<data_expression>& parameter_values = dst_state.get_parameter_values();
1485 std::vector<int> parameter_indices =
1486 detail::map_at(info->get_variable_parameter_indices(), varname);
1487 std::vector<std::string> parameter_signatures =
1488 detail::map_at(info->get_variable_parameter_signatures(), varname);
1489 std::vector<std::string>::iterator param_signature = parameter_signatures.begin();
1490 int value_index = 0;
1491 for(int & parameter_indice : parameter_indices)
1492 {
1493 int i = parameter_indice + 1;
1494 int type_no = info->get_lts_type().get_state_type_no(i);
1495 values[i] = parameter_values[value_index];
1496 if (values[i]==novalue)
1497 {
1498 error = true;
1499 } else {
1500 if (src==nullptr) {
1501 // no source state available; compute index for value.
1502 dst[i] = this->get_value_index(type_no, values[i]);
1503 }
1504 else
1505 {
1506 // lookup src parameter value
1507 // FIXME: this could be computed statically: a map from src_var, dst_var and part to boolean
1508 std::map<int,int> src_param_index_positions = detail::map_at(info->get_variable_parameter_index_positions(), src_state.get_variable());
1509 std::map<int,int>::iterator src_param_index_position_it = src_param_index_positions.find(parameter_indice);
1510 if ( src_param_index_position_it != src_param_index_positions.end()
1511 && src_state.get_parameter_values()[src_param_index_position_it->second] == values[i])
1512 {
1513 // src value exists and is equal to the dst value.
1514 // save to copy index from src_state
1515 // which has been done earlier
1516 } else {
1517 // parameter value has changed or does not exists in src; compute index for value.
1518 dst[i] = this->get_value_index(type_no, values[i]);
1519 }
1520 }
1521 }
1522 if (param_signature != parameter_signatures.end())
1523 {
1524 ++param_signature;
1525 }
1526 value_index++;
1527 }
1528 if (error)
1529 {
1530 throw(std::runtime_error("Error in to_state_vector: NoValue in parameters of dst_state: "
1531 + info->state_to_string(dst_state) + "."));
1532 }
1533 //std::clog << "-- to_state_vector: done --" << std::endl;
1534}
1535
1536
1537std::string explorer::get_value(int type_no, int index)
1538{
1539 //std::clog << "get_value type_no = " << type_no << " index = " << index << std::endl;
1540 if (type_no==0)
1541 {
1542 return this->get_string_value(index);
1543 }
1544 else
1545 {
1546 data_expression value = get_data_value(type_no, index);
1547 //std::stringstream os;
1548 //write_term_to_text_stream(value, os);
1549 //std::string s = atermpp::pp(value);
1550 //return os.str();
1552 return pp(t);
1553 }
1554}
1555
1556
1557const std::string& explorer::get_string_value(int index)
1558{
1559 if (index >= (int)(localmap_int2string.size()))
1560 {
1561 throw(std::runtime_error("Error in get_string_value: Value not found for index " + std::to_string(index) + "."));
1562 }
1563 return localmap_int2string.at(index);
1564}
1565
1566
1567const data_expression& explorer::get_data_value(int type_no, int index)
1568{
1569 std::vector<data_expression>& int2data_map = this->localmaps_int2data.at(type_no);
1570 if (index >= (int)(int2data_map.size()))
1571 {
1572 throw(std::runtime_error("Error in get_data_value: Value not found for type_no "
1573 + std::to_string(type_no) + " at index " + std::to_string(index) + "."));
1574 }
1575 return int2data_map.at(index);
1576}
1577
1578
1580{
1581 //std::clog << "-- from_state_vector(model, src) --" << std::endl;
1582 data_expression novalue;
1583 int state_length = info->get_lts_type().get_state_length();
1584
1585 std::string varname = this->get_string_value(src[0]);
1586 //std::clog << "from_state_vector: varname = " << varname << std::endl;
1587
1588 bool error = false;
1589
1590 // data_expression values[state_length]; N.B. This is not portable C++
1591 std::vector <data_expression> values(state_length);
1592
1593 int type_no;
1594 for (int i = 1; i < state_length; i++) {
1595 //std::clog << "from_state_vector: values: " << i << " (" << src[i] << "): " << std::endl;
1597 values[i] = this->get_data_value(type_no, src[i]);
1598 //std::clog << "from_state_vector: " << values[i].to_string() << std::endl;
1599 }
1600 //std::clog << "from_state_vector: values done." << std::endl;
1601 data::data_expression_vector parameters;
1602 std::vector<int> parameter_indices =
1603 detail::map_at(info->get_variable_parameter_indices(), varname);
1604 for (int & parameter_indice : parameter_indices) {
1605 if (values[parameter_indice+1]==novalue)
1606 {
1607 error = true;
1608 //std::clog << "from_state_vector: varname = " << varname << ", values[" << *param_index+1 << "] = " << values[*param_index+1].to_string() << "(" << src[*param_index+1] << ")" << std::endl;
1609 }
1610 parameters.push_back(values[parameter_indice+1]);
1611 }
1612 if (error)
1613 {
1614 throw(std::runtime_error("Error in from_state_vector: NoValue in parameters."));
1615 }
1616 data::data_expression_list paramlist(parameters.begin(), parameters.end());
1617 propositional_variable_instantiation state_expression(varname, paramlist);
1618 //std::clog << "from_state_vector: state_expression = " << state_expression.to_string() << std::endl;
1619 ltsmin_state state = this->get_state(state_expression);
1620 //std::clog << "from_state_vector: state = " << state->to_string() << std::endl;
1621 return state;
1622}
1623
1624
1626{
1627 //std::cout << "get_successors: " << state->to_string() << std::endl;
1628 std::vector<ltsmin_state> result;
1629
1631 assert(core::detail::check_term_PropVarInst(e));
1632 if (state.get_variable()=="true")
1633 {
1634 // Adding true=true
1635 result.push_back(state);
1636 }
1637 else if (state.get_variable()=="false")
1638 {
1639 // Adding false=false
1640 result.push_back(state);
1641 }
1642 else
1643 {
1644 std::set<pbes_expression> successors
1645 = pgg->get_successors(e);
1646 operation_type type = detail::map_at(info->get_variable_types(), state.get_variable());
1647 for (const auto & successor : successors) {
1648 if (is_propositional_variable_instantiation(successor)) {
1649 result.push_back(get_state(atermpp::down_cast<propositional_variable_instantiation>(successor)));
1650 } else if (is_true(successor)) {
1651 if (type != parity_game_generator::PGAME_AND)
1652 {
1653 result.push_back(true_state());
1654 }
1655 } else if (is_false(successor)) {
1656 if (type != parity_game_generator::PGAME_OR)
1657 {
1658 result.push_back(false_state());
1659 }
1660 } else {
1661 throw(std::runtime_error("!! Successor is NOT a propvar: " + pbes_system::pp(successor)));
1662 }
1663 }
1664 }
1665 return result;
1666}
1667
1668
1670 int group)
1671{
1672 //std::clog << "get_successors: group=" << group << std::endl;
1673 std::vector<ltsmin_state> result;
1674
1675 if (group == 0 && state.get_variable()=="true")
1676 {
1677 // Adding true=true
1678 result.push_back(state);
1679 }
1680 else if (group == 1 && state.get_variable()=="false")
1681 {
1682 // Adding false=false
1683 result.push_back(state);
1684 }
1685 else
1686 {
1687 std::string varname = state.get_variable();
1688 std::string group_varname = info->get_transition_variable_names()[group];
1689 if (varname==group_varname)
1690 {
1692 std::set<pbes_expression> successors
1693 = pgg->get_successors(e, group_varname,
1694 info->get_transition_expressions()[group]);
1695 operation_type type = detail::map_at(info->get_variable_types(), state.get_variable());
1696 for (const auto & successor : successors) {
1697 //std::clog << " * successor: " << pp(*expr) << std::endl;
1698 if (is_propositional_variable_instantiation(successor)) {
1699 result.push_back(get_state(atermpp::down_cast<propositional_variable_instantiation>(successor)));
1700 } else if (is_true(successor)) {
1701 if (type != parity_game_generator::PGAME_AND)
1702 {
1703 result.push_back(true_state());
1704 }
1705 } else if (is_false(successor)) {
1706 if (type != parity_game_generator::PGAME_OR)
1707 {
1708 result.push_back(false_state());
1709 }
1710 } else {
1711 throw(std::runtime_error("!! Successor is NOT a propvar: " + pbes_system::pp(successor)));
1712 }
1713 }
1714 }
1715 }
1716 return result;
1717}
1718
1719
1720} // namespace pbes_system
1721
1722} // namespace mcrl2
aterm_string(const std::string &s)
Constructor that allows construction from a string.
bool operator!=(const unprotected_aterm_core &t) const
Inequality operator on two unprotected aterms.
Definition aterm_core.h:92
Components for generating an arbitrary element of a sort.
representative_generator(const data_specification &specification)
Constructor with data specification as context.
\brief A data variable
Definition variable.h:28
const core::identifier_string & name() const
Definition variable.h:38
const sort_expression & sort() const
Definition variable.h:43
logger(const log_level_t l)
Default constructor.
Definition logger.h:164
propositional_variable_instantiation get_initial_state()
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...
const std::map< std::string, std::map< int, int > > & get_variable_parameter_index_positions() const
Returns the map from variable names to the map from indices of parameter signatures for the variable ...
const std::map< int, std::vector< bool > > & get_read_matrix() const
Returns the read dependency matrix.
const std::map< int, std::vector< bool > > & get_write_matrix() const
Returns the write dependency matrix.
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, std::vector< std::string > > & get_variable_parameter_signatures() const
Returns the map from variable names to the list of parameters signatures 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::map< int, std::vector< bool > > & get_dependency_matrix() const
Returns the dependency matrix.
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.
static std::string get_param_signature(const variable &param)
Returns a signature for parameter param.
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.
static std::string get_param_signature(const std::string &paramname, const std::string &paramtype)
Returns a signature using name and type of a parameter.
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::map< std::string, std::vector< int > > & get_variable_parameter_indices() const
Returns the map from variable names to the list of indices of the parameters signatures for the varia...
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 the player or type of the state (And/Or, Abelard/Eloise, Odd/Even).
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 the priority for the state, which depends on the fixpoint operator of the equation of the pro...
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...
parameterized boolean equation system
Definition pbes.h:58
propositional_variable_instantiation & initial_state()
Returns the initial state.
Definition pbes.h:199
\brief A propositional variable instantiation
const data::data_expression_list & parameters() const
\brief A propositional variable declaration
const data::variable_list & parameters() const
propositional_variable(const core::identifier_string &name, const data::variable_list &parameters)
\brief Constructor Z12.
Standard exception class for reporting runtime errors.
Definition exception.h:27
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:391
The main namespace for the aterm++ library.
Definition algorithm.h:21
std::string pp(const atermpp::aterm &t)
Transform an aterm to an ascii string.
Definition aterm.h:440
aterm read_term_from_string(const std::string &s)
Reads an aterm from a string. The string can be in either binary or text format.
atermpp::aterm_string identifier_string
String type of the LPS library. Identifier strings are represented internally as ATerms.
atermpp::aterm add_index(const atermpp::aterm &x)
Definition io.h:55
atermpp::aterm remove_index(const atermpp::aterm &x)
Definition io.h:61
Namespace for all data library functionality.
Definition data.cpp:22
std::vector< data_expression > data_expression_vector
\brief vector of data_expressions
atermpp::term_list< data_expression > data_expression_list
\brief list of data_expressions
atermpp::term_list< variable > variable_list
\brief list of variables
@ verbose
Definition logger.h:37
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)
The main namespace for the PBES library.
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)
std::string pp(const pbes_system::pbes_expression &x)
Definition pbes.cpp:44
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_()
std::size_t operator()(const atermpp::detail::reference_aterm< T > &t) const