24 const Index index = IndexFromLiteral(literal_ref);
29 if (
var >= tmp_num_occurrences_.size()) {
30 tmp_num_occurrences_.resize(
var + 1, 0);
32 const auto insert = deductions_.insert({{
index,
var}, domain});
39 const Domain& old_domain = insert.first->second;
48 absl::Span<const int> clause) {
49 std::vector<std::pair<int, Domain>> result;
53 for (
const int ref : clause) {
55 if (
index >= something_changed_.
size())
return result;
56 if (something_changed_[
index]) {
60 if (abort)
return result;
63 std::vector<int> to_process;
64 std::vector<int> to_clean;
65 for (
const int ref : clause) {
67 for (
const int var : enforcement_to_vars_[
index]) {
68 if (tmp_num_occurrences_[
var] == 0) {
69 to_clean.push_back(
var);
71 tmp_num_occurrences_[
var]++;
72 if (tmp_num_occurrences_[
var] == clause.size()) {
73 to_process.push_back(
var);
79 for (
const int var : to_clean) {
80 tmp_num_occurrences_[
var] = 0;
84 std::vector<Domain> domains(to_process.size());
85 for (
const int ref : clause) {
87 for (
int i = 0; i < to_process.size(); ++i) {
88 domains[i] = domains[i].UnionWith(
93 for (
int i = 0; i < to_process.size(); ++i) {
94 result.push_back({to_process[i], std::move(domains[i])});
102 template <
typename ProtoWithVarsAndCoeffs>
103 int64 GetVarCoeffAndCopyOtherTerms(
const int var,
104 const ProtoWithVarsAndCoeffs&
proto,
105 std::vector<std::pair<int, int64>>* terms) {
108 const int size =
proto.vars().size();
109 for (
int i = 0; i < size; ++i) {
110 int ref =
proto.vars(i);
123 terms->push_back({ref, coeff});
132 template <
typename ProtoWithVarsAndCoeffs>
133 void SortAndMergeTerms(std::vector<std::pair<int, int64>>* terms,
134 ProtoWithVarsAndCoeffs*
proto) {
136 proto->clear_coeffs();
137 std::sort(terms->begin(), terms->end());
139 int64 current_coeff = 0;
140 for (
const auto entry : *terms) {
142 if (entry.first == current_var) {
143 current_coeff += entry.second;
145 if (current_coeff != 0) {
146 proto->add_vars(current_var);
147 proto->add_coeffs(current_coeff);
149 current_var = entry.first;
150 current_coeff = entry.second;
153 if (current_coeff != 0) {
154 proto->add_vars(current_var);
155 proto->add_coeffs(current_coeff);
161 void AddTermsFromVarDefinition(
const int var,
const int64 var_coeff,
162 const ConstraintProto& definition,
163 std::vector<std::pair<int, int64>>* terms) {
164 const int definition_size = definition.linear().vars().size();
165 for (
int i = 0; i < definition_size; ++i) {
166 int ref = definition.linear().vars(i);
167 int64 coeff = definition.linear().coeffs(i);
176 terms->push_back({ref, -coeff * var_coeff});
183 const ConstraintProto& definition,
184 ConstraintProto*
ct) {
186 CHECK_EQ(std::abs(var_coeff_in_definition), 1);
189 std::vector<std::pair<int, int64>> terms;
190 int64 var_coeff = GetVarCoeffAndCopyOtherTerms(
var,
ct->linear(), &terms);
192 if (var_coeff_in_definition < 0) var_coeff *= -1;
194 AddTermsFromVarDefinition(
var, var_coeff, definition, &terms);
206 SortAndMergeTerms(&terms,
ct->mutable_linear());