Program Listing for File component_management.cpp¶
↰ Return to documentation for file (src/component_management.cpp
)
#include <algorithm>
#include "component_management.h"
void ComponentManager::initialize(LiteralIndexedVector<Literal> & literals,
std::vector<LiteralID> &lit_pool, bool quiet) {
ana_.initialize(literals, lit_pool);
// BEGIN CACHE INIT
CacheableComponent::adjustPackSize(ana_.max_variable_id(), ana_.max_clause_id());
// Prevent a memory leak
for (auto &i : component_stack_)
delete i;
component_stack_.clear();
component_stack_.reserve(ana_.max_variable_id() + 2);
component_stack_.push_back(new Component());
component_stack_.push_back(new Component());
assert(component_stack_.size() == 2);
component_stack_.back()->createAsDummyComponent(ana_.max_variable_id(),
ana_.max_clause_id());
if (config_.perform_random_sampling_)
cached_vars_.clear();
cache_.init(*component_stack_.back(), quiet);
}
void ComponentManager::removeAllCachePollutionsOf(StackLevel &top) {
// all processed components are found in
// [top.currentRemainingComponent(), component_stack_.size())
// first, remove the list of descendants from the father
assert(top.remaining_components_ofs() <= component_stack_.size());
assert(top.super_component() != 0);
assert(cache_.hasEntry(super_component(top).id()));
if (top.remaining_components_ofs() == component_stack_.size())
return;
for (unsigned u = top.remaining_components_ofs(); u < component_stack_.size();
u++) {
assert(cache_.hasEntry(component_stack_[u]->id()));
cache_.cleanPollutionsInvolving(component_stack_[u]->id());
}
#ifdef DEBUG
cache_.test_descendantstree_consistency();
#endif
}
std::vector<VariableIndex> ComponentManager::buildFreedVariableList(const StackLevel & top,
const std::vector<LiteralID> &literal_stack) {
Component * descendant_comp, *ref_comp = component_stack_[top.super_component()];
const VariableIndex original_var_count = ref_comp->num_variables();
VariableIndex num_unused_vars = original_var_count;
std::vector<bool> var_in_descendants(original_var_count, false);
std::vector<ComponentVarAndCls> descendant_vars, ref_vars = ref_comp->getData();
for (unsigned comp_id=top.remaining_components_ofs();
comp_id < top.unprocessed_components_end(); comp_id++) {
descendant_comp = component_stack_[comp_id];
descendant_vars = descendant_comp->getData();
UpdateVarDescedantsList(ref_vars, ref_comp->num_variables(), var_in_descendants,
descendant_vars, descendant_comp->num_variables());
num_unused_vars -= descendant_comp->num_variables();
}
// Build a list of all literals assigned in the last round
const long list_stack_ofs = top.literal_stack_ofs();
VariableIndex num_lits_assigned = literal_stack.size() - list_stack_ofs;
std::vector<ComponentVarAndCls> assigned_stack_vars;
assigned_stack_vars.reserve(num_lits_assigned);
for (VariableIndex stack_i = 0; stack_i < num_lits_assigned; stack_i++)
assigned_stack_vars.push_back(literal_stack[list_stack_ofs + stack_i].var());
// Sort the vector and exclude the assigned literals
sort(assigned_stack_vars.begin(), assigned_stack_vars.end());
num_unused_vars -= UpdateVarDescedantsList(ref_vars, ref_comp->num_variables(),
var_in_descendants, assigned_stack_vars,
num_lits_assigned);
// Skip the cached variables
num_unused_vars -= UpdateVarDescedantsList(ref_vars, ref_comp->num_variables(),
var_in_descendants,
cached_vars_, cached_vars_.size());
// If a variable does not appear in the descendant nor in the cache and is not on
// top of the literal stack, it was freed.
std::vector<VariableIndex> freed_vars;
freed_vars.reserve(num_unused_vars);
for (VariableIndex ref_i = 0; ref_i < ref_comp->num_variables(); ref_i++) {
if (!var_in_descendants[ref_i])
freed_vars.push_back(ref_vars[ref_i]);
}
assert(num_unused_vars == freed_vars.size());
return freed_vars;
}
VariableIndex UpdateVarDescedantsList(const std::vector<ComponentVarAndCls> &ref_vars,
VariableIndex ref_num_vars,
std::vector<bool> &varInDescendants,
std::vector<ComponentVarAndCls> descendant_vars,
VariableIndex desc_num_vars) {
if (desc_num_vars == 0)
return 0;
VariableIndex varsRemoved = 0;
VariableIndex ref_i, desc_i = 0;
for (ref_i = 0; ref_i < ref_num_vars; ref_i++) {
// Reference list is always a superset and since both are sorted, go to the next
if (ref_vars[ref_i] < descendant_vars[desc_i])
continue;
if (ref_vars[ref_i] > descendant_vars[desc_i])
desc_i++;
if (desc_i >= desc_num_vars)
break;
// If the descendant and reference match, the var is present
if (ref_vars[ref_i] == descendant_vars[desc_i]) {
// DebugZH - A variable should only be in a single descedent
assert(!varInDescendants[ref_i]);
varInDescendants[ref_i] = true;
varsRemoved++;
}
}
return varsRemoved;
}