SplitState filterPartitionStackByUnorderedListFunction(PartitionStack* ps, F f) { debug_out(3, "filterUnListFun", "prestate " << ps->printCurrentPartition()); int cellCount = ps->cellCount(); // first of all, we need to try to distinguish as many values of F as possible. std::map<typename F::result_type::value_type, HashType> full_hash; for(int i : range1(cellCount)) { typedef std::map<typename F::result_type::value_type, unsigned> map_type; map_type count_map; for(int val : ps->cellRange(i)) { for(const auto& val2 : f(val)) count_map[val2]++; } for(const auto& val : count_map) { full_hash[val.first] = hash_combine(full_hash[val.first], i, val.second); } } SplitState ret = filterPartitionStackByFunction(ps, IndirectVecCollapseFunction(MapToFunction(&full_hash), f)); debug_out(3, "filterUnListFun", "poststate " << ps->printCurrentPartition()); return ret; }
SplitState filterPartitionStackByUnorderedFunction(PartitionStack* ps, F f) { debug_out(3, "filterUnFun", "prestate " << ps->printCurrentPartition()); int cellCount = ps->cellCount(); // first of all, we need to try to distinguish as many values of F as possible. std::map<typename F::result_type, HashType> full_hash; for(int i : range1(cellCount)) { typedef std::map<typename F::result_type, unsigned> map_type; map_type count_map; for(int x : ps->cellRange(i)) { count_map[f(x)]++; } for(const auto& m : count_map) { full_hash[m.first] = hash_combine(full_hash[m.first], i, m.second); } } debug_out(3, "filter", "Hash:" << full_hash); debug_out(3, "filter", "Function:" << f); SplitState ret = filterPartitionStackByFunction(ps, IndirectFunction(MapToFunction(&full_hash), f)); debug_out(3, "filterUnFun", "poststate " << ps->printCurrentPartition()); return ret; }
SplitState fix_buildingRBase(const vec1<int>& fixed_values, bool useOrbits, bool useBlocks, bool useOrbitals, bool rootCall = false) { debug_out(3, "scpg", "last depth " << last_depth.get() << " new depth " << fixed_values.size()); D_ASSERT(fixed_values.size() > last_depth.get()); last_depth.set(fixed_values.size()); if(useOrbits) { doCacheCheck(config.useOrbits, tracking_first_found_orbits, [this](const vec1<int>& v){ return this->fillRBaseOrbitPartitionCache(v); }, fixed_values, "orbits"); } if(useBlocks) { doCacheCheck(config.useBlocks, tracking_first_found_blocks, [this](const vec1<int>& v){ return this->fillRBaseBlocksCache(v); }, fixed_values, "blocks"); } if(useOrbitals) { doCacheCheck(config.useOrbitals, tracking_first_found_orbitals, [this](const vec1<int>& v){ return this->fillRBaseOrbitalsCache(v); }, fixed_values, "orbitals"); } SplitState ss(true); int fixed_size = fixed_values.size(); if(useOrbits) { const vec1<int>* part = 0; if(tracking_first_found_orbits.get() >= 0) part = this->getRBaseOrbitPartition_cached(tracking_first_found_orbits.get()); else part = this->getRBaseOrbitPartition_cached(fixed_size); debug_out(3, "scpg", "fix_rBase:orbits"); if(!part->empty()) ss = filterPartitionStackByFunction(ps, SquareBrackToFunction(part)); if(ss.hasFailed()) return ss; } if( ( StabChainConfig::doConsiderIfNonTrivial(config.useOrbitals) && fixed_size == tracking_first_found_orbitals.get() ) || ( config.useOrbitals == StabChainConfig::always ) || ( rootCall ) ) { return signal_changed_generic(range1(ps->cellCount()), identityPermutation()); } return ss; }
SplitState signal_start() { return filterPartitionStackByFunction(ps, SquareBrackToFunction(&inv_points)); }
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; }