22
33#include " factored_transition_system.h"
44#include " merge_selector.h"
5- #include " merge_tree.h"
6- #include " merge_tree_factory.h"
75#include " transition_system.h"
86
97#include < algorithm>
@@ -16,55 +14,85 @@ namespace merge_and_shrink {
1614MergeStrategySCCs::MergeStrategySCCs (
1715 const FactoredTransitionSystem &fts,
1816 const shared_ptr<MergeSelector> &merge_selector,
19- vector<vector<int >> &&non_singleton_cg_sccs)
17+ vector<vector<int >> &&unfinished_clusters,
18+ bool allow_working_on_all_clusters)
2019 : MergeStrategy(fts),
2120 merge_selector (merge_selector),
22- non_singleton_cg_sccs(move(non_singleton_cg_sccs)) {
21+ unfinished_clusters(move(unfinished_clusters)),
22+ allow_working_on_all_clusters(allow_working_on_all_clusters) {
2323}
2424
2525MergeStrategySCCs::~MergeStrategySCCs () {
2626}
2727
28+ static void compute_merge_candidates (
29+ const vector<int > &indices,
30+ vector<pair<int , int >> &merge_candidates) {
31+ for (size_t i = 0 ; i < indices.size (); ++i) {
32+ int ts_index1 = indices[i];
33+ for (size_t j = i + 1 ; j < indices.size (); ++j) {
34+ int ts_index2 = indices[j];
35+ merge_candidates.emplace_back (ts_index1, ts_index2);
36+ }
37+ }
38+ }
39+
2840pair<int , int > MergeStrategySCCs::get_next () {
29- if (current_ts_indices.empty ()) {
30- /*
31- We are currently not dealing with merging all factors of an SCC, so
32- we need to either get the next one or allow merging any existing
33- factors of the FTS if there is no SCC left.
34- */
35- if (non_singleton_cg_sccs.empty ()) {
36- // We are done dealing with all SCCs, allow merging any factors.
37- current_ts_indices.reserve (fts.get_num_active_entries ());
38- for (int ts_index: fts) {
39- current_ts_indices.push_back (ts_index);
41+ if (unfinished_clusters.empty ()) {
42+ // We merged all clusters.
43+ return merge_selector->select_merge (fts);
44+ } else {
45+ // There are clusters we still have to deal with.
46+ vector<pair<int , int >> merge_candidates;
47+ vector<int > factor_to_cluster;
48+ if (allow_working_on_all_clusters) {
49+ // Compute merge candidate pairs for each cluster.
50+ factor_to_cluster.resize (fts.get_size (), -1 );
51+ for (size_t cluster_index = 0 ; cluster_index < unfinished_clusters.size (); ++cluster_index) {
52+ const vector<int > &cluster = unfinished_clusters[cluster_index];
53+ for (int factor : cluster) {
54+ factor_to_cluster[factor] = cluster_index;
55+ }
56+ compute_merge_candidates (cluster, merge_candidates);
4057 }
4158 } else {
42- /*
43- There is another SCC we have to deal with. Store its factors so
44- that we merge them over the next iterations.
45- */
46- vector<int > ¤t_scc = non_singleton_cg_sccs.front ();
47- assert (current_scc.size () > 1 );
48- current_ts_indices = move (current_scc);
49- non_singleton_cg_sccs.erase (non_singleton_cg_sccs.begin ());
59+ // Deal with first cluster.
60+ vector<int > &cluster = unfinished_clusters.front ();
61+ compute_merge_candidates (cluster, merge_candidates);
5062 }
51- } else {
52- // Add the most recent product to the current index set.
53- current_ts_indices.push_back (fts.get_size () - 1 );
54- }
5563
56- // Select the next merge for the current set of indices.
57- pair<int , int > next_pair = merge_selector->select_merge (fts, current_ts_indices);
64+ // Select the next merge from the allowed merge candidates.
65+ pair<int , int > next_pair = merge_selector->select_merge (
66+ fts, move (merge_candidates));
67+
68+ // Get the cluster from which we selected the next merge.
69+ int affected_cluster_index;
70+ if (allow_working_on_all_clusters) {
71+ affected_cluster_index = factor_to_cluster[next_pair.first ];
72+ assert (affected_cluster_index == factor_to_cluster[next_pair.second ]);
73+ } else {
74+ affected_cluster_index = 0 ;
75+ }
76+
77+ // Remove the two merged indices from that cluster.
78+ vector<int > &affected_cluster = unfinished_clusters[affected_cluster_index];
79+ for (vector<int >::iterator it = affected_cluster.begin ();
80+ it != affected_cluster.end ();) {
81+ if (*it == next_pair.first || *it == next_pair.second ) {
82+ it = affected_cluster.erase (it);
83+ } else {
84+ ++it;
85+ }
86+ }
5887
59- // Remove the two merged indices from the current index set.
60- for (vector<int >::iterator it = current_ts_indices.begin ();
61- it != current_ts_indices.end ();) {
62- if (*it == next_pair.first || *it == next_pair.second ) {
63- it = current_ts_indices.erase (it);
88+ if (affected_cluster.empty ()) {
89+ // If the cluster got empty, remove it.
90+ unfinished_clusters.erase (unfinished_clusters.begin () + affected_cluster_index);
6491 } else {
65- ++it;
92+ // Otherwise, add the index of the to-be-created product factor.
93+ affected_cluster.push_back (fts.get_size ());
6694 }
95+ return next_pair;
6796 }
68- return next_pair;
6997}
7098}
0 commit comments