12namespace elimination_actions {
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 if (variables.size() != 1) {
93 STORM_LOG_THROW(
false, storm::exceptions::NotImplementedException,
"Unfolding variables with circular dependencies is currently implemented");
95 for (
const auto &variable : variables) {
96 if (variable.isGlobal) {
100 STORM_LOG_TRACE(
"\tUnfolding global variable " + variable.janiVariableName);
101 UnfoldAction unfoldAction(autName, variable.janiVariableName, variable.expressionVariableName);
102 unfoldAction.doAction(session);
104 STORM_LOG_TRACE(
"\tUnfolding variable " + variable.janiVariableName +
" (automaton: " + variable.automatonName +
")");
105 UnfoldAction unfoldAction(variable.automatonName, variable.janiVariableName, variable.expressionVariableName);
106 unfoldAction.doAction(session);
109 dependencyGraph.markUnfolded(dependency);
113std::map<std::string, double> AutomaticAction::getAssignmentCountByVariable(JaniLocalEliminator::Session &session, std::string
const &automatonName) {
114 std::map<std::string, double> res;
115 auto automaton = session.getModel().getAutomaton(automatonName);
116 for (
auto edge : automaton.getEdges()) {
117 size_t numDest = edge.getNumberOfDestinations();
121 double factor = 1.0 / numDest;
122 for (
const auto &dest : edge.getDestinations()) {
123 for (
const auto &asg : dest.getOrderedAssignments()) {
124 auto name = asg.getExpressionVariable().getName();
125 if (res.count(name) == 0) {
135boost::optional<uint32_t> AutomaticAction::chooseNextUnfold(JaniLocalEliminator::Session &session, std::string
const &automatonName,
136 UnfoldDependencyGraph &dependencyGraph,
bool onlyPropertyVariables) {
137 std::map<std::string, double> variableOccurrenceCounts = getAssignmentCountByVariable(session, automatonName);
139 auto propertyVariables = session.getProperty().getUsedVariablesAndConstants();
141 if (onlyPropertyVariables) {
142 STORM_LOG_TRACE(
"\tOnly groups containing a variable from the property will be considered");
146 std::set<uint32_t> groupsWithoutDependencies = dependencyGraph.getGroupsWithNoDependencies();
149 uint32_t bestValue = 0;
150 uint32_t bestGroup = 0;
151 for (
auto groupIndex : groupsWithoutDependencies) {
152 bool containsPropertyVariable =
false;
153 UnfoldDependencyGraph::VariableGroup &group = dependencyGraph.variableGroups[groupIndex];
154 double totalOccurrences = 0;
155 for (
const auto &var : group.variables) {
156 if (variableOccurrenceCounts.count(var.expressionVariableName) > 0) {
157 totalOccurrences += variableOccurrenceCounts[var.expressionVariableName];
159 for (
const auto &propertyVar : propertyVariables) {
160 if (propertyVar.getName() == var.expressionVariableName) {
161 containsPropertyVariable =
true;
165 if (onlyPropertyVariables && !containsPropertyVariable) {
168 STORM_LOG_TRACE(
"\t\t{" + group.getVariablesAsString() +
"}: " + std::to_string(totalOccurrences) +
" occurrences");
169 if (dependencyGraph.variableGroups[groupIndex].domainSize < maxDomainSize) {
170 if (totalOccurrences > bestValue) {
171 bestValue = totalOccurrences;
172 bestGroup = groupIndex;
179 if (bestValue == 0) {