SplitState filterCellByUnorderedFunction(PartitionStack* ps, int cell, F f) { // First, gather up counts. std::map<int, int> m; int cellBegin = ps->cellStartPos(cell); int cellEnd = ps->cellEndPos(cell); for(int pos = cellBegin; pos < cellEnd; ++pos) { m[ps->val(pos)]++; } abort(); PartitionStack::cellit cellPtrBegin = ps->cellStartPtr(cell); PartitionStack::cellit cellPtrEnd = ps->cellEndPtr(cell); std::sort(cellPtrBegin, cellPtrEnd, IndirectSorter(f)); ps->fixCellInverses(cell); // Start at the end, because then the cell we pass to // split remains the same. for(int pos = cellEnd - 2; pos >= cellBegin; --pos) { if(f(ps->val(pos)) != f(ps->val(pos+1))) { if(ps->split(cell, pos+1).hasFailed()) return SplitState(false); } } return SplitState(true); }
inline SplitState filterCellByFunction_withSortData(PartitionStack* ps, int cell, F f, const SortEvent& se) { debug_out(3, "filter", "Start filter"); D_ASSERT(se.hash_starts.size() > 1); if(!indirect_data_sorter(cell, ps, f, se)) return SplitState(false); ps->fixCellInverses(cell); return SplitState(true); }
SplitState filterPartitionStackByFunction_withSortData(PartitionStack* ps, F f) { PartitionEvent& pe = ps->getAbstractQueue()->getPartitionEvent(); int len = 0; for(auto it = pe.order.begin(); it != pe.order.end(); ++it) { len++; if(it->change) { int cell = pe.change_cells[it->index].first; bool sorter = indirect_data_sorter(cell, ps, f, pe.change_cells[it->index].second); ps->fixCellInverses(cell); if(!sorter) { debug_out(3, "filterPSBF_WSD", "failed " << cell); pe.order.promote(it); return SplitState(false); } } else { if(!validateFixedCell(ps, pe.no_change_cells[it->index].first, pe.no_change_cells[it->index].second, f)) { pe.order.promote(it); debug_out(3, "filterPSBF_WSD", "failed validate fixed cell"); return SplitState(false); } } } // Finally, do the splits for(int i : range1(pe.change_cells.size())) { int cell = pe.change_cells[i].first; const SortEvent& se = pe.change_cells[i].second; for(int j = 1; j < se.hash_starts.size(); ++j) { if(ps->split(cell, se.hash_starts[j].startPos).hasFailed()) { abort(); } } } return SplitState(true); }
SplitState filterPartitionStackByFunctionWithCells_noSortData(PartitionStack* ps, F f, const Cells& cells) { PartitionEvent pe; for(int c : cells) filterCell(ps, f, c, &pe); pe.finalise(); ps->getAbstractQueue()->addPartitionEvent(std::move(pe)); return SplitState(true); }
SplitState filterPartitionStackByFunction_noSortData(PartitionStack* ps, F f) { PartitionEvent pe; int cellCount = ps->cellCount(); for(int i : range1(cellCount)) { filterCell(ps, f, i, &pe); } pe.finalise(); ps->getAbstractQueue()->addPartitionEvent(std::move(pe)); return SplitState(true); }
virtual SplitState signal_fix() { debug_out(3, "scpg", "signal_fix"); const vec1<int>& new_fix_cells = ps->fixed_values(); Permutation perm(last_permutation.back()); int old_depth = last_depth.get(); // We have to do this, as new_fix_cells changes as the function progresses int new_depth = new_fix_cells.size(); D_ASSERT(new_depth > old_depth); #ifndef NO_DEBUG for(int i : range1(old_depth)) { (void)i; D_ASSERT(perm[new_fix_cells[i]] == (rb->value_ordering)[i]); } #endif PermutationStack perm_stack(perm); for(int i = old_depth + 1; i <= new_depth; ++i) { if(scc.hasUnpackedLevel(i)) { StabChainLevel& scl = scc.getUnpackedLevel(i); D_ASSERT(scl.base_value == (rb->value_ordering)[i]); debug_out(3, "scpg", "Trying to map "<<new_fix_cells[i]<<" to "<<(rb->value_ordering)[i]); int image = perm_stack[new_fix_cells[i]]; debug_out(3, "scpg", "Pre-image of "<<new_fix_cells[i]<<" is "<<image); if(!scl.exists_perm_to(image)) { debug_out(3, "scpg", "No perm exists to map to image"); return SplitState(false); } const optional<Permutation>& p = scl.perm_mapping_from(image); if(!p) { debug_out(3, "scpg", "No perm mapping from image?"); return SplitState(false); } D_ASSERT((*p)[image] == (rb->value_ordering)[i]); debug_out(3, "scpg", "Old stack: " << perm_stack.getPerm()); perm_stack.addPerm((*p)); debug_out(3, "scpg", "New perm: " << *p << " added to stack gives " << perm_stack.getPerm()); D_ASSERT(perm_stack[new_fix_cells[i]] == (rb->value_ordering)[i]); } else { if(perm_stack[new_fix_cells[i]] != (rb->value_ordering)[i]) return SplitState(false); } } perm = perm_stack.getPerm(); last_permutation.push_back(perm); last_depth.set(new_depth); // Check our permutation maps known points in the right way. #ifndef NO_DEBUG for(int i : range1(new_depth)) { (void)i; D_ASSERT(perm[new_fix_cells[i]] == (rb->value_ordering)[i]); } #endif SplitState ss(true); if(StabChainConfig::doConsiderEveryNode(config.useOrbits)) { auto level = getDepthLevel(new_depth, tracking_first_found_orbits.get(), config.useOrbits); if(!level.skip) { const vec1<int>* part = getRBaseOrbitPartition_cached(level.depth); debug_out(3, "scpg", "fix:orbits" << part << " by " << perm); if(!part->empty()) ss = filterPartitionStackByFunction(ps, FunctionByPerm(SquareBrackToFunction(part), perm)); if(ss.hasFailed()) return ss; } } if( ( StabChainConfig::doConsiderIfNonTrivial(config.useOrbitals) && new_depth == tracking_first_found_orbitals.get() ) || ( config.useOrbitals == StabChainConfig::always ) ) { return signal_changed_generic(range1(ps->cellCount()), perm); } return ss; }