16 : locationLimit(locationLimit), newTransitionLimit(newTransitionLimit), maxDomainSize(maxDomainSize), flatten(flatten) {}
19 return "AutomaticAction";
29 processAutomaton(session, autName);
31 for (uint64_t i = 0; i < session.
getModel().getNumberOfAutomata(); i++) {
34 processAutomaton(session, autName);
51 auto nextUnfold = chooseNextUnfold(session, autName, dependencyGraph,
true);
56 unfoldGroupAndDependencies(session, autName, dependencyGraph, nextUnfold.get());
61 eliminatePropertyAction.doAction(session);
63 RebuildWithoutUnreachableAction rebuildAfterPropertyAction;
64 rebuildAfterPropertyAction.doAction(session);
67 nextUnfold = chooseNextUnfold(session, autName, dependencyGraph,
false);
72 unfoldGroupAndDependencies(session, autName, dependencyGraph, nextUnfold.get());
74 RebuildWithoutUnreachableAction rebuildAfterUnfoldingAction;
75 rebuildAfterUnfoldingAction.doAction(session);
79 eliminateAction.doAction(session);
81 RebuildWithoutUnreachableAction rebuildAfterEliminationAction;
82 rebuildAfterEliminationAction.doAction(session);
86void AutomaticAction::unfoldGroupAndDependencies(JaniLocalEliminator::Session &session,
const std::string &autName,
UnfoldDependencyGraph &dependencyGraph,
87 uint32_t groupIndex) {
88 auto orderedDependencies = dependencyGraph.getOrderedDependencies(groupIndex,
true);
89 STORM_LOG_TRACE(
"Unfolding " + dependencyGraph.variableGroups[groupIndex].getVariablesAsString() +
" and their dependencies");
90 for (
auto dependency : orderedDependencies) {
91 auto variables = dependencyGraph.variableGroups[dependency].variables;
92 STORM_LOG_THROW(variables.size() == 1, storm::exceptions::NotImplementedException,
93 "Unfolding variables with circular dependencies is currently not implemented.");
94 for (
const auto &variable : variables) {
95 if (variable.isGlobal) {
99 STORM_LOG_TRACE(
"\tUnfolding global variable " + variable.janiVariableName);
100 UnfoldAction unfoldAction(autName, variable.janiVariableName, variable.expressionVariableName);
101 unfoldAction.doAction(session);
103 STORM_LOG_TRACE(
"\tUnfolding variable " + variable.janiVariableName +
" (automaton: " + variable.automatonName +
")");
104 UnfoldAction unfoldAction(variable.automatonName, variable.janiVariableName, variable.expressionVariableName);
105 unfoldAction.doAction(session);
108 dependencyGraph.markUnfolded(dependency);
112std::map<std::string, double> AutomaticAction::getAssignmentCountByVariable(JaniLocalEliminator::Session &session, std::string
const &automatonName) {
113 std::map<std::string, double> res;
114 auto automaton = session.
getModel().getAutomaton(automatonName);
115 for (
auto edge : automaton.getEdges()) {
116 size_t numDest = edge.getNumberOfDestinations();
120 double factor = 1.0 / numDest;
121 for (
const auto &dest : edge.getDestinations()) {
122 for (
const auto &asg : dest.getOrderedAssignments()) {
123 auto name = asg.getExpressionVariable().getName();
124 if (res.count(name) == 0) {
134boost::optional<uint32_t> AutomaticAction::chooseNextUnfold(JaniLocalEliminator::Session &session, std::string
const &automatonName,
136 std::map<std::string, double> variableOccurrenceCounts = getAssignmentCountByVariable(session, automatonName);
138 auto propertyVariables = session.
getProperty().getUsedVariablesAndConstants();
140 if (onlyPropertyVariables) {
141 STORM_LOG_TRACE(
"\tOnly groups containing a variable from the property will be considered");
145 std::set<uint32_t> groupsWithoutDependencies = dependencyGraph.getGroupsWithNoDependencies();
148 uint32_t bestValue = 0;
149 uint32_t bestGroup = 0;
150 for (
auto groupIndex : groupsWithoutDependencies) {
151 bool containsPropertyVariable =
false;
152 UnfoldDependencyGraph::VariableGroup &group = dependencyGraph.variableGroups[groupIndex];
153 double totalOccurrences = 0;
154 for (
const auto &var : group.variables) {
155 if (variableOccurrenceCounts.count(var.expressionVariableName) > 0) {
156 totalOccurrences += variableOccurrenceCounts[var.expressionVariableName];
158 for (
const auto &propertyVar : propertyVariables) {
159 if (propertyVar.getName() == var.expressionVariableName) {
160 containsPropertyVariable =
true;
164 if (onlyPropertyVariables && !containsPropertyVariable) {
167 STORM_LOG_TRACE(
"\t\t{" + group.getVariablesAsString() +
"}: " + std::to_string(totalOccurrences) +
" occurrences");
168 if (dependencyGraph.variableGroups[groupIndex].domainSize < maxDomainSize) {
169 if (totalOccurrences > bestValue) {
170 bestValue = totalOccurrences;
171 bestGroup = groupIndex;
178 if (bestValue == 0) {