8#include <unordered_map>
51 std::vector<int> base_vertex;
53 unsigned long invariant = 0;
54 int trace_position = 0;
55 int base_position = 0;
57 void save(std::vector<int>& s_base_vertex,
coloring &s_c,
unsigned long s_invariant,
int s_trace_position,
58 int s_base_position) {
59 this->base_vertex = s_base_vertex;
61 this->invariant = s_invariant;
62 this->trace_position = s_trace_position;
63 this->base_position = s_base_position;
84 return trace_position;
115 base_info(
int selColor,
int colorSz,
int cellNum,
int touchedColorListPt,
int singletonPt,
int tracePos,
116 unsigned long traceHash) :
158 std::vector<int> internal_compare_singletons;
159 std::vector<int> internal_compare_base_vertex;
160 std::vector<base_info> internal_compare_base;
173 bool diff_diverge =
false;
175 int singleton_pt_start = 0;
179 std::function<type_split_color_hook> my_split_hook;
180 std::function<type_worklist_color_hook> my_worklist_hook;
186 bool s_cell_active =
false;
187 bool s_individualize =
false;
189 bool h_trace_early_out =
false;
190 bool h_deviation_inc_active =
false;
191 int s_deviation_inc_current = 0;
192 int h_deviation_inc = 48;
195 bool h_use_split_limit =
false;
196 int h_split_limit = 0;
204 void touch_initial_colors() {
206 while (i < c->domain_size) {
215 void reset_touched() {
219 touch_initial_colors();
235 bool split_hook(
const int old_color,
const int new_color,
const int new_color_sz) {
251 const bool cont = !h_trace_early_out ||
T->
trace_equal();
252 s_deviation_inc_current += (!cont);
253 const bool deviation_override = h_deviation_inc_active && (s_deviation_inc_current <= h_deviation_inc);
259 const bool continue_split_limit = !h_use_split_limit || (s_splits < h_split_limit);
260 return continue_split_limit && continue_cell_limit && (cont || deviation_override);
263 std::function<type_split_color_hook> self_split_hook() {
265 return [
this](
auto && PH1,
auto && PH2,
auto && PH3) {
return
266 this->split_hook(std::forward<
decltype(PH1)>(PH1), std::forward<
decltype(PH2)>(PH2),
267 std::forward<
decltype(PH3)>(PH3));
270 return std::bind(&controller::split_hook,
this, std::placeholders::_1, std::placeholders::_2,
271 std::placeholders::_3);
279 bool worklist_hook(
const int color,
const int color_sz) {
282 s_cell_active =
false;
295 s_cell_active =
true;
299 std::function<type_worklist_color_hook> self_worklist_hook() {
301 return [
this](
auto && PH1,
auto && PH2) {
302 return this->worklist_hook(std::forward<
decltype(PH1)>(PH1), std::forward<
decltype(PH2)>(PH2));
305 return std::bind(&controller::worklist_hook,
this, std::placeholders::_1, std::placeholders::_2);
313 void add_diff_vertex(
int v) {
315 if(!diff_vertices.
get(v) && !diff_is_singleton.
get(v)) {
316 diff_vertices.
set(v);
318 diff_vertices_list_pt[v] = diff_vertices_list.
cur_pos - 1;
326 void remove_diff_vertex(
int v) {
328 if(diff_vertices.
get(v)) {
329 const int pt = diff_vertices_list_pt[v];
333 const int back_pt = diff_vertices_list.
cur_pos-1;
334 const int back_v = diff_vertices_list[back_pt];
337 diff_vertices_list[pt] = back_v;
339 dej_assert(diff_vertices_list_pt[back_v] == back_pt);
340 diff_vertices_list_pt[back_v] = pt;
341 diff_vertices_list_pt[v] = -1;
343 diff_vertices.
unset(v);
353 void color_fix_difference(
const controller& state,
int col) {
354 const int col_sz =
c->
ptn[col] + 1;
357 add_diff_vertex(state.c->lab[col]);
358 const int v =
c->
lab[col];
359 remove_diff_vertex(v);
360 if(!diff_is_singleton.
get(v)) {
361 diff_is_singleton.
set(v);
367 for(
int i = 0; i < col_sz; ++i) diff_tester.
set(state.c->lab[col + i]);
368 for(
int i = 0; i < col_sz; ++i)
369 if(!diff_tester.
get(
c->
lab[col + i])) add_diff_vertex(
c->
lab[col + i]);
372 for(
int i = 0; i < col_sz; ++i) diff_tester.
set(
c->
lab[col + i]);
373 for(
int i = 0; i < col_sz; ++i)
374 if(!diff_tester.
get(state.c->lab[col + i])) add_diff_vertex(state.c->lab[col + i]);
395 touch_initial_colors();
397 my_split_hook = self_split_hook();
398 my_worklist_hook = self_worklist_hook();
411 singleton_pt_start = 0;
433 internal_compare_base.clear();
434 internal_compare_base_vertex.clear();
435 internal_compare_singletons.clear();
455 const int col_sz =
c->
ptn[col] + 1;
457 if(col_sz == 1)
continue;
460 for(
int j = col; j < col + col_sz; ++j) {
461 const int v =
c->
lab[j];
464 for(
int j = col; j < col + col_sz; ++j) {
466 if(!diff_tester.
get(v))
return true;
479 automorphism->
reset();
482 const int col_sz =
c->
ptn[i] + 1;
492 automorphism->
reset();
514 for(
int i = 0; i < domain_size;) {
516 const int col_sz =
c->
ptn[col] + 1;
520 for(
int j = col; j < col + col_sz; ++j) {
521 const int v =
c->
lab[j];
524 for(
int j = col; j < col + col_sz; ++j) {
526 if(!diff_tester.
get(v))
return true;
543 const int right = diff_vertices_list[0];
548 const int right_col_sz =
c->
ptn[right_col] + 1;
550 for (
int i = 0; i < right_col_sz; ++i) {
551 const int candidate = state.
c->
lab[right_col + i];
552 if(diff_vertices.
get(candidate)) {
557 if(left == -1) left = state.
c->
lab[right_col];
560 return {left, right};
567 diff_vertices.
reset();
568 diff_vertices_list.
reset();
569 diff_is_singleton.
reset();
574 diff_diverge =
false;
585 automorphism.
reset();
586 for(
int i = singleton_pt_start; i < static_cast<int>(
singletons.size()); ++i) {
618 diff_updated_color.
reset();
624 diff_original_size[old_color] = 0;
625 if(!diff_updated_color.
get(old_color)) {
626 diff_updated_color.
set(old_color);
627 diff_previous_color[old_color] = old_color;
629 while(diff_previous_color[old_color] != diff_previous_color[diff_previous_color[old_color]])
630 diff_previous_color[old_color] = diff_previous_color[diff_previous_color[old_color]];
631 diff_updated_color.
set(new_color);
632 diff_previous_color[new_color] = diff_previous_color[old_color];
638 const int old_color = diff_previous_color[new_color];
639 diff_original_size[old_color] = std::max(diff_original_size[old_color],
640 new_color +
c->
ptn[new_color] + 1);
643 diff_updated_color.
reset();
648 if(diff_updated_color.
get(old_color)) {
652 int old_color_end_pt = std::max(old_color +
c->
ptn[old_color] + 1, diff_original_size[old_color]);
656 const int old_color_sz =
c->
ptn[old_color] + 1;
657 const int old_color_sz_other = other_state.
c->
ptn[old_color] + 1;
658 diff_diverge = diff_diverge || (old_color_sz != old_color_sz_other);
659 if(diff_diverge)
break;
662 int largest_fragment = -1;
663 int largest_fragment_sz = -1;
665 for(
int j = old_color; j < old_color_end_pt;) {
666 const int next_color = j;
667 const int next_color_sz =
c->
ptn[next_color] + 1;
668 const int next_color_sz_other = other_state.
c->
ptn[next_color] + 1;
669 diff_diverge = diff_diverge || (next_color_sz != next_color_sz_other);
670 if(next_color_sz > largest_fragment_sz) {
671 largest_fragment = next_color;
672 largest_fragment_sz = next_color_sz;
675 diff_updated_color.
set(next_color);
679 if(diff_diverge)
break;
682 for(
int j = old_color; j < old_color_end_pt;) {
683 const int next_color = j;
684 const int next_color_sz =
c->
ptn[next_color] + 1;
685 if(j != largest_fragment) color_fix_difference(other_state, next_color);
690 if(largest_fragment_sz == 1) color_fix_difference(other_state, largest_fragment);
692 return (diff_vertices_list.
cur_pos != 0) || diff_diverge;
770 return diff_vertices_list.
cur_pos;
787 internal_compare_base =
base;
802 int sqrt_domain = sqrt(domain_size);
803 base.reserve(sqrt_domain);
832 this->h_trace_early_out = trace_early_out;
844 h_deviation_inc_active = deviation_inc_active;
855 h_deviation_inc = deviation_inc;
867 h_split_limit = limit;
875 s_deviation_inc_current = 0;
949 for(
int l = 0; l < g->
v_size; ++l) {
950 const int v =
c->
lab[l];
951 unsigned int inv1 = 0;
952 const int start_pt = g->
v[v];
953 const int end_pt = start_pt + g->
d[v];
954 for(
int pt = start_pt; pt < end_pt; ++pt) {
955 const int other_v = g->
e[pt];
969 for(
int l = 0; l < g->
v_size; l += 4) {
970 const int v =
c->
lab[l];
971 unsigned int inv1 = 0;
972 const int start_pt = g->
v[v];
973 const int end_pt = start_pt + g->
d[v];
974 for(
int pt = start_pt; pt < end_pt; ++pt) {
975 const int other_v = g->
e[pt];
998 const int singleton_pt = (int)
singletons.size();
1001 const unsigned long trace_hash =
T->
get_hash();
1005 const int prev_col_sz =
c->
ptn[prev_col] + 1;
1008 s_individualize =
true;
1011 s_individualize =
false;
1016 R->
refine_coloring(g,
c, init_color_class, -1, &my_split_hook, &my_worklist_hook);
1020 R->
refine_coloring(g,
c, init_color_class, -1, &my_split_hook, &my_worklist_hook);
1026 s_cell_active =
false;
1029 base.emplace_back(prev_col, prev_col_sz,
c->
cells, touched_color_pt, singleton_pt, trace_pos,
1073 const int new_color_sz =
c->
ptn[new_color] + 1;
1074 c->
ptn[old_color] += new_color_sz;
1075 c->
ptn[new_color] = 1;
1077 for (
int j = 0; j < new_color_sz; ++j) {
1078 const int v =
c->
lab[new_color + j];
1086 int const new_singleton_pos =
base.back().singleton_pt;
1124 if(automorphism.
nsupp() == 0)
return true;
1129 automorphism.
supp());
1141 const int locked_lim = 512;
1143 std::vector<int> saved_color_base;
1144 std::vector<int> saved_color_sizes;
1145 std::function<type_selector_hook> dynamic_seletor;
1147 std::vector<int> candidates;
1153 const int d = g->
d[v];
1154 const int ept_st = g->
v[v];
1155 const int ept_end = ept_st + d;
1156 int non_triv_col_d = 1;
1157 for (
int i = ept_st; i < ept_end; ++i) {
1159 if (!test_set.
get(test_col)) {
1160 non_triv_col_d += 1;
1161 test_set.
set(test_col);
1167 static int color_score_size(
controller *state,
int color) {
1171 static int color_score_anti_size(
controller *state,
int color) {
1186 if (base_pos >= 0 && base_pos < (
int) saved_color_base.size() && c->
ptn[saved_color_base[base_pos]] > 0 &&
1187 c->
vertex_to_col[c->
lab[saved_color_base[base_pos]]] == saved_color_base[base_pos] &&
1188 c->
ptn[saved_color_base[base_pos]] + 1 == saved_color_sizes[base_pos]) {
1189 return saved_color_base[base_pos];
1191 int best_score = -1;
1192 int best_color = -1;
1194 if (c->
ptn[i] > best_score && c->
ptn[i] > 0) {
1195 best_score = c->
ptn[i];
1198 if(best_color >= 0)
break;
1209 std::placeholders::_2);
1210 return &dynamic_seletor;
1217 return ir_tree_size_estimate;
1230 const int h_seed,
const int h_budget) {
1233 perturbe = (int) (hash(h_seed) % 256);
1260 ir_tree_size_estimate.
mantissa = 1.0;
1261 ir_tree_size_estimate.
exponent = 0;
1263 saved_color_base.clear();
1264 saved_color_base.reserve(state->
base.size());
1265 for(
auto& bi : state->
base) {
1266 saved_color_base.push_back(bi.color);
1269 saved_color_sizes.clear();
1270 saved_color_sizes.reserve(state->
base.size());
1271 for(
auto& bi : state->
base) {
1272 ir_tree_size_estimate.
multiply(bi.color_sz);
1273 saved_color_sizes.push_back(bi.color_sz);
1286 constexpr int base_lim = 1000;
1287 constexpr int test_lim_pre = 512;
1288 constexpr int test_lim_post = 1;
1292 int prev_color = -1;
1296 int start_test_from = 0;
1297 int start_test_from_inside = 0;
1299 int buffered_col = -1;
1300 int buffered_col_score = -1;
1303 int best_color = -1;
1304 int test_lim = state->
s_base_pos <= base_lim?test_lim_pre:test_lim_post;
1308 best_color = prev_color;
1309 }
else if (prev_color >= 0) {
1311 int i = g->
v[test_vertex] + start_test_from_inside;
1312 const int end_pt = g->
v[test_vertex] + g->
d[test_vertex];
1313 for (; i < end_pt; ++i) {
1314 const int other_vertex = g->
e[i];
1317 best_color = other_color;
1320 ++start_test_from_inside;
1325 start_test_from_inside = 0;
1328 if(best_color == -1 && buffered_col >= 0 && state->
get_coloring()->
ptn[buffered_col] > 0 &&
1329 color_score(g, state, buffered_col) >= buffered_col_score) {
1330 best_color = buffered_col;
1332 buffered_col_score = -1;
1336 if (best_color == -1) {
1337 int best_score = -1;
1339 for (
int i = start_test_from; i < state->
get_coloring()->domain_size && test_lim >= 0;) {
1344 const int test_score = color_score(g, state, i);
1345 if (test_score > best_score) {
1347 best_score = test_score;
1349 buffered_col_score = -1;
1350 }
else if (test_score == best_score) {
1352 buffered_col_score = test_score;
1356 if(col_sz == 0 && start_test_from == i) start_test_from += col_sz + 1;
1363 prev_color = best_color;
1374 int start_test_from = 0;
1377 int best_color = -1;
1381 for (
int i = start_test_from; i < state->
get_coloring()->domain_size && test_lim >= 0;) {
1389 if(col_sz == 0 && start_test_from == i) start_test_from += col_sz + 1;
1411 int prev_color = -1;
1412 int prev_color_sz = 0;
1417 int best_color = -1;
1421 if(prev_color >= 0) {
1422 for (
int i = 0; i < prev_color + prev_color_sz;) {
1431 if (prev_color >= 0 && best_color == -1) {
1433 for (
int i = 0; i < g->
d[test_vertex]; ++i) {
1434 const int other_vertex = g->
e[g->
v[test_vertex] + i];
1437 best_color = other_color;
1443 if (best_color == -1) {
1444 int best_score = -1;
1446 for (
int i = 0; i < state->
get_coloring()->domain_size && test_lim >= 0;) {
1448 int test_score = color_score(g, state, i);
1449 if (test_score > best_score) {
1451 best_score = test_score;
1462 prev_color = best_color;
1481 int best_color = -1;
1485 int best_score = INT32_MIN;
1486 for (
int i = 0; i < state->
get_coloring()->domain_size && test_lim >= 0;) {
1488 int test_score = color_score_anti_size(state, i);
1489 if (test_score > best_score || best_color == -1) {
1491 best_score = test_score;
1493 if(best_score == INT32_MAX - 1)
break;
1512 candidates.reserve(locked_lim);
1518 int best_color = -1;
1522 int best_score = -1;
1523 for (
int i = 0; i < state->
get_coloring()->domain_size;) {
1525 candidates.push_back(i);
1529 while (!candidates.empty()) {
1530 const int test_color = candidates.back();
1531 candidates.pop_back();
1533 int test_score = color_score_size(state, test_color);
1534 if (neighbour_color.
get(test_color)) {
1537 if (test_score >= best_score) {
1538 best_color = test_color;
1539 best_score = test_score;
1562 int prev_color = -1;
1563 int prev_color_sz = 0;
1565 const bool perturbe_flip = perturbe % 2;
1568 int best_color = -1;
1569 int best_score = -1;
1572 if(prev_color >= 0) {
1573 for (
int i = 0; i < prev_color + prev_color_sz;) {
1575 int test_score = color_score_size(state, i);
1576 if (((test_score > best_score) || (perturbe_flip && (test_score >= best_score))) && col_sz > 0) {
1578 best_score = test_score;
1584 if(best_color == -1) {
1586 for (
int i = 0; i < state->
get_coloring()->domain_size;) {
1588 int test_score = color_score_size(state, i);
1589 if (test_score > best_score && col_sz > 0) {
1591 best_score = test_score;
1600 prev_color = best_color;
1617 constexpr int probe_limit = 5;
1619 state_probe->
link(state);
1624 int probe_limit_candidates = 8;
1626 bool use_probing =
true;
1629 int best_color = -1;
1630 int best_score_deviate = -1;
1631 int best_score_cells = -1;
1632 int best_score_size = -1;
1633 int best_test_v = -1;
1635 probe_limit_candidates = std::max(probe_limit_candidates, 2);
1640 const int col_sz = state->
c->
ptn[i] + 1;
1642 candidates.push_back(i);
1644 if (
static_cast<int>(candidates.size()) >= probe_limit_candidates)
break;
1649 for (
int i = 0; i < static_cast<int>(candidates.size()); ++i) {
1650 const int col = candidates[i];
1651 const int col_sz = state->
c->
ptn[col] + 1;
1653 const int probe_lim_col = std::min(probe_limit, col_sz);
1655 const int v_base = state->
get_coloring()->
lab[(col + (perturbe % col_sz))];
1659 #if defined(DEJDEBUG) && !defined(NDEBUG)
1660 const int cells_pre = state->
c->
cells;
1665 const int cells = state->
c->
cells;
1668 for (
int j = 0; j < probe_lim_col; ++j) {
1670 const int v = state_probe->
c->
lab[col + ((j + perturbe) % col_sz)];
1690 if (deviated > best_score_deviate ||
1691 ((deviated == best_score_deviate) && (cells > best_score_cells)) ||
1692 ((deviated == best_score_deviate) && (cells == best_score_cells) &&
1693 (col_sz > best_score_size))) {
1695 best_score_deviate = deviated;
1696 best_score_cells = cells;
1697 best_score_size = col_sz;
1698 best_test_v = v_base;
1699 if (deviated > 0)
break;
1703 if (best_score_deviate > 0) --probe_limit_candidates;
1707 int best_score = -1;
1708 for (
int i = 0; i < state->
get_coloring()->domain_size;) {
1710 candidates.push_back(i);
1714 while (!candidates.empty()) {
1715 const int test_color = candidates.back();
1716 candidates.pop_back();
1718 int test_score = color_score_size(state, test_color);
1719 if (test_score >= best_score) {
1720 best_color = test_color;
1721 best_score = test_score;
1726 if(probe_limit_candidates < 2 || state->s_base_pos > 5) use_probing =
false;
1735 int v = best_test_v;
1736 if(v == -1) v = state->
get_coloring()->
lab[(best_color + (perturbe% col_sz))];
1757 std::unordered_set<unsigned long> map;
1758 int computed_for_base = 0;
1759 int expected_for_base = 0;
1760 bool deviation_done =
false;
1762 void check_finished() {
1763 if(computed_for_base == expected_for_base) deviation_done =
true;
1764 dej_assert(computed_for_base <= expected_for_base);
1768 void start(
const int h_expected_for_base) {
1769 computed_for_base = 0;
1770 expected_for_base = h_expected_for_base;
1773 deviation_done =
false;
1777 map.insert(deviation);
1778 ++computed_for_base;
1779 dej_assert(computed_for_base <= expected_for_base);
1784 ++computed_for_base;
1785 dej_assert(computed_for_base <= expected_for_base);
1790 return !deviation_done || map.find(deviation) != map.end();
1808 memcpy(lab_or_base.
get_array(), arr, arr_sz *
sizeof(
int));
1813 lab_or_base.
allocate((
int) arr.size());
1814 std::copy(arr.begin(), arr.end(), lab_or_base.
get_array());
1815 lab_or_base.
set_size((
int) arr.size());
1823 return lab_or_base.
size();
1842 std::unordered_multimap<unsigned long, stored_leaf*> leaf_store;
1843 std::vector<stored_leaf*> garbage_collector;
1850 leaf_store.reserve(20);
1857 for(
auto & l : garbage_collector) {
1869 auto find = leaf_store.find(hash);
1870 if(find != leaf_store.end()) {
1871 return find->second;
1886 if(leaf_store.find(hash) != leaf_store.end())
return;
1894 leaf_store.insert(std::pair<unsigned long, stored_leaf*>(hash, new_leaf));
1895 garbage_collector.push_back(new_leaf);
1914 bool owns_data =
true;
1917 bool is_base =
false;
1918 bool is_pruned =
false;
1919 unsigned long hash = 0;
1928 this->owns_data = ownsdata;
1929 this->parent = _parent;
1939 this->next = new_next;
1968 if(owns_data)
delete data;
1984 std::vector<tree_node*> tree_data;
1985 std::vector<std::vector<tree_node*>> tree_data_jump_map;
1986 std::vector<int> tree_level_size;
1987 std::vector<tree_node*> garbage_collector;
1988 int finished_up_to = 0;
1990 std::vector<int> current_base;
1992 std::vector<unsigned long> node_invariant;
2007 if(finished_up_to > 1) {
2008 for(
int j = finished_up_to; j >= 1; --j) {
2010 for(
auto node : tree_data_jump_map[j]) {
2011 const int v = node->get_save()->get_base()[0];
2012 unsigned long add_hash = 1;
2013 add_hash = add_to_hash(add_hash, node->get_hash());
2014 add_hash = add_to_hash(add_hash, hash(j));
2016 if(j == finished_up_to) {
2018 for (
auto v_pre: node->get_save()->get_base()) {
2019 node_invariant[v_pre] += add_hash * hash(cnt);
2024 node_invariant[node->get_save()->get_base()[j-1]] += add_hash;
2025 node_invariant[v] += add_hash + 1;
2064 return &node_invariant;
2068 tree_data.resize(base.size() + 1);
2069 tree_level_size.resize(base.size() + 1);
2070 tree_data_jump_map.resize(base.size() + 1);
2073 current_base = base;
2094 for(
int i = 0; i < root->
get_coloring()->domain_size; ++i) node_invariant[i] = 0;
2096 const int old_size = (int) current_base.size();
2097 const int new_size = (int) new_base.size();
2102 for (; keep_until < old_size && keep_until < new_size; ++keep_until) {
2103 if (current_base[keep_until] != new_base[keep_until])
break;
2107 if(keep_until == 0) {
2108 for(
auto t : garbage_collector)
delete t;
2109 garbage_collector.clear();
2113 if(keep_until == new_size && new_size == old_size)
return false;
2115 finished_up_to = std::min(keep_until, finished_up_to);
2118 tree_data.resize(new_size + 1);
2119 tree_level_size.resize(new_size + 1);
2120 tree_data_jump_map.resize(new_size + 1);
2122 for (
int i = keep_until+1; i < new_size+1; ++i) {
2123 tree_data[i] =
nullptr;
2124 tree_level_size[i] = 0;
2125 tree_data_jump_map[i].clear();
2128 if(keep_until == 0) {
2129 tree_level_size[0] = 0;
2130 tree_data_jump_map[0].clear();
2131 tree_data[0] =
nullptr;
2136 current_base = new_base;
2147 missing_nodes.
add(node);
2151 return missing_nodes.
empty();
2155 return missing_nodes.
pop();
2159 if(tree_data[1] ==
nullptr)
return;
2168 }
while (next != first);
2172 node_invariant[v] = inv;
2176 node_invariant[v] += inv;
2181 if(tree_data[level] ==
nullptr) {
2182 tree_level_size[level] = 0;
2183 tree_data[level] =
new tree_node(data,
nullptr, parent, level != 0);
2184 tree_data[level]->set_next(tree_data[level]);
2186 garbage_collector.push_back( tree_data[level]);
2187 if(is_base) tree_data[level]->base();
2191 auto new_node =
new tree_node(data, next_node, parent, level != 0);
2192 garbage_collector.push_back(new_node);
2193 if(is_base) new_node->base();
2195 tree_data[level] = new_node;
2197 ++tree_level_size[level];
2201 if(tree_data_jump_map[level].empty()) {
2203 tree_data_jump_map[level].reserve(tree_level_size[level]);
2207 tree_data_jump_map[level].push_back(next);
2210 }
while (next != first);
2211 tree_level_size[level] = tree_data_jump_map[level].size();
2212 dej_assert(
static_cast<int>(tree_data_jump_map[level].size()) == tree_level_size[level]);
2218 num = num % tree_level_size[level];
2219 return tree_data_jump_map[level][num];
2223 return finished_up_to;
2227 this->finished_up_to = new_finished_up_to;
2231 return tree_data[level];
2235 return tree_level_size[finished_up_to];
2239 return tree_data[finished_up_to]->get_save()->get_trace_position();
2243 return tree_level_size[level];
2247 for(
auto & i : garbage_collector)
delete i;
void multiply(int number)
Vertex coloring for a graph.
void copy_any(coloring *c)
Set specialized for quick resets.
void copy(const markset *other)
void initialize(int size)
void copy(const worklist_t< T > *other)
void set_size(const int size)
void resize(const int size)
dej_nodiscard int size() const
Fixed-size integer array, 0-initialized.
void resize(const int size)
Workspace for sparse automorphisms.
dej_nodiscard int nsupp() const
dej_nodiscard int * p() const
dej_nodiscard int * supp() const
void write_single_map(const int from, const int to)
void initialize(int domain_size)
void find_sparse_optimized_base_recurse(sgraph *g, controller *state, int perturbe)
void find_combinatorial_optimized_base_recurse(sgraph *g, controller *state, int perturbe)
big_number get_ir_size_estimate()
void make_cell_selector(sgraph *g, controller *state, controller *state_probe, const selector_style style, const int h_seed, const int h_budget)
void find_sparse_optimized_base(sgraph *g, controller *state)
void find_first_base(sgraph *g, controller *state)
void find_combinatorial_optimized_base(sgraph *g, controller *state)
std::function< type_selector_hook > * get_selector_hook()
void find_early_trace_deviation_base(sgraph *g, controller *state, controller *state_probe, int perturbe)
void find_small_optimized_base(sgraph *g, controller *state, int perturbe)
int cell_selector(const coloring *c, const int base_pos)
Store deviations for a BFS level.
void record_no_deviation()
bool check_deviation(unsigned long deviation)
void start(const int h_expected_for_base)
void record_deviation(unsigned long deviation)
void save(std::vector< int > &s_base_vertex, coloring &s_c, unsigned long s_invariant, int s_trace_position, int s_base_position)
std::vector< int > & get_base()
coloring * get_coloring()
dej_nodiscard int get_base_position() const
dej_nodiscard int get_trace_position() const
dej_nodiscard unsigned long get_invariant_hash() const
Color refinement and related algorithms.
bool certify_automorphism(sgraph *g, const int *p)
static int individualize_vertex(coloring *c, int v, const std::function< type_split_color_hook > &split_hook=nullptr)
void refine_coloring_first(sgraph *g, coloring *c, int init_color_class=-1)
bool certify_automorphism_sparse(const sgraph *g, const int *p, int supp, const int *supp_arr)
void refine_coloring(sgraph *g, coloring *c, int init_color=-1, int color_limit=-1, const std::function< type_split_color_hook > *split_hook=nullptr, const std::function< type_worklist_color_hook > *worklist_hook=nullptr)
stored_leaf * lookup_leaf(unsigned long hash)
void add_leaf(unsigned long hash, coloring &c, std::vector< int > &base)
int get_current_level_tracepos()
void record_invariant(int v, unsigned long inv)
tree_node * get_level(int level)
void add_node(int level, limited_save *data, tree_node *parent, bool is_base=false)
void make_node_invariant()
void queue_reserve(const int n)
int get_current_level_size()
void queue_missing_node(missing_node node)
int get_level_size(int level)
void initialize(std::vector< int > &base, ir::limited_save *root)
int h_bfs_automorphism_pw
void mark_first_level(markset &marks)
bool queue_missing_node_empty()
deviation_map stored_deviation
shared_tree(int domain_size)
groups::orbit h_bfs_top_level_orbit
bool reset(std::vector< int > &new_base, ir::limited_save *root, bool keep_old)
void set_finished_up_to(const int new_finished_up_to)
std::vector< unsigned long > * get_node_invariant()
void finish_level(int level)
void record_add_invariant(int v, unsigned long inv)
dej_nodiscard int get_finished_up_to() const
ir::tree_node * pick_node_from_level(const int level, int num)
shared_leaves stored_leaves
missing_node queue_missing_node_pop()
@ STORE_LAB
stores coloring of the leaf
@ STORE_BASE
stores only base of the leaf
int get_lab_or_base_size()
const int * get_lab_or_base()
stored_leaf(int *arr, int arr_sz, stored_leaf_type storetype)
stored_leaf(std::vector< int > &arr, stored_leaf_type storetype)
dej_nodiscard stored_leaf_type get_store_type() const
dej_nodiscard int get_position() const
dej_nodiscard unsigned long get_hash() const
void set_record(bool new_record)
void op_refine_cell_end()
void set_position(int new_position)
dej_nodiscard bool trace_equal() const
void set_hash(unsigned long new_hash)
void op_additional_info(int d)
void op_refine_cell_start(int)
void set_compare_trace(trace *new_compare_trace)
void op_individualize(const int ind_color)
void set_compare(bool new_compare)
void op_refine_cell_record(int new_color)
trace * get_compare_trace()
void skip_to_individualization()
void reserve(const int n)
tree_node(limited_save *_data, tree_node *_next, tree_node *_parent, bool ownsdata)
dej_nodiscard bool get_prune() const
dej_nodiscard unsigned long get_hash() const
void set_next(tree_node *new_next)
void add_hash(unsigned long add)
dej_nodiscard bool get_base() const
limited_save * get_save()
Internal graph data structure.
int type_selector_hook(const coloring *, const int)
ir_mode
Mode of trace for IR search.
@ IR_MODE_COMPARE_TRACE_REVERSIBLE
@ IR_MODE_COMPARE_TRACE_IRREVERSIBLE
std::pair< ir::tree_node *, int > missing_node
Tracks information for a base point.
int touched_color_list_pt
base_info(int selColor, int colorSz, int cellNum, int touchedColorListPt, int singletonPt, int tracePos, unsigned long traceHash)
Controls movement in IR tree.
std::vector< int > * compare_base_vertex
std::vector< base_info > * compare_base
std::vector< base_info > base
void singleton_automorphism_base(groups::automorphism_workspace *automorphism)
void link_compare(controller *state)
bool there_is_difference_to_base()
void use_increase_deviation(bool deviation_inc_active)
dej_nodiscard coloring * get_coloring() const
bool update_diff_vertices_last_individualization(const controller &other_state)
std::vector< int > singletons
void link(controller *state)
void save_reduced_state(limited_save &state)
void move_to_child(sgraph *g, int v)
void walk(sgraph *g, ir::limited_save &start_from, std::vector< int > &vertices)
void use_split_limit(bool use_split_limit, int limit=0)
void use_reversible(const bool reversible)
dej_nodiscard int get_diff_diverge() const
void set_increase_deviation(int deviation_inc=48)
dej_nodiscard int get_base_pos() const
void singleton_automorphism(controller &state, groups::automorphism_workspace &automorphism)
void use_trace_early_out(bool trace_early_out)
worklist touched_color_list
void load_reduced_state_without_coloring(limited_save &state)
void move_to_child_no_trace(sgraph *g, int v)
void load_reduced_state(limited_save &state)
void color_diff_automorphism_base(groups::automorphism_workspace *automorphism)
std::vector< int > * compare_singletons
std::pair< int, int > diff_pair(const controller &state)
void write_strong_invariant_quarter(const sgraph *g) const
int get_number_of_splits()
std::vector< int > base_vertex
void write_strong_invariant(const sgraph *g) const
void write_to_trace(const int d) const
controller(refinement *ref, coloring *col)
bool certify(sgraph *g, groups::automorphism_workspace &automorphism)
bool there_is_difference_to_base_including_singles(int domain_size)