Skip to content

Commit cf4e402

Browse files
committed
avoid usisg indexed_vector for term operations
1 parent 440d78f commit cf4e402

File tree

1 file changed

+64
-48
lines changed

1 file changed

+64
-48
lines changed

src/math/lp/dioph_eq.cpp

+64-48
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,6 @@ namespace lp {
323323
int_solver& lia;
324324
lar_solver& lra;
325325
explanation m_infeas_explanation;
326-
indexed_vector<mpq> m_indexed_work_vector;
327326
bool m_report_branch = false;
328327

329328
// set F
@@ -345,6 +344,32 @@ namespace lp {
345344
}
346345
return r;
347346
}
347+
348+
bool has(unsigned k) const {
349+
return k < m_index.size() && m_index[k] >= 0;
350+
}
351+
352+
const mpq& operator[](unsigned j) const {
353+
SASSERT(j >= 0 && j < m_index.size());
354+
SASSERT(m_index[j] >= 0 && m_index[j] < m_data.size());
355+
return m_data[m_index[j]].coeff();
356+
}
357+
358+
void erase(unsigned k) {
359+
if (k >= m_index.size() || m_index[k] == -1)
360+
return;
361+
362+
unsigned idx = m_index[k];
363+
// If not last element, move last element to idx position
364+
if (idx != m_data.size() - 1) {
365+
m_data[idx] = m_data.back();
366+
m_index[m_data[idx].var()] = idx;
367+
}
368+
369+
m_data.pop_back();
370+
m_index[k] = -1;
371+
SASSERT(invariant());
372+
}
348373
void add(const mpq& a, unsigned j) {
349374
SASSERT(!a.is_zero());
350375
// Expand m_index if needed
@@ -426,7 +451,8 @@ namespace lp {
426451

427452
};
428453

429-
term_with_index m_term_with_index;
454+
term_with_index m_l_terms_workspace;
455+
term_with_index m_substitution_workspace;
430456

431457
bijection m_k2s;
432458
bij_map<lar_term> m_fresh_k2xt_terms;
@@ -881,7 +907,7 @@ namespace lp {
881907
open_l_term_to_work_vector(ei, c);
882908
clear_e_row(ei);
883909
mpq denom(1);
884-
for (const auto & p: m_indexed_work_vector) {
910+
for (const auto & p: m_substitution_workspace.m_data) {
885911
unsigned lj = add_var(p.var());
886912
m_e_matrix.add_columns_up_to(lj);
887913
m_e_matrix.add_new_element(ei, lj, p.coeff());
@@ -1189,31 +1215,30 @@ namespace lp {
11891215
print_term_o(create_term_from_ind_c(), tout) << std::endl;
11901216
tout << "subs with e:";
11911217
print_lar_term_L(e, tout) << std::endl;);
1192-
mpq coeff = - m_indexed_work_vector[k]; // need to copy since it will be zeroed
1193-
m_indexed_work_vector.erase(k); // m_indexed_work_vector[k] = 0;
1218+
mpq coeff = - m_substitution_workspace[k]; // need to copy since it will be zeroed
1219+
m_substitution_workspace.erase(k); // m_work_vector_1[k] = 0;
11941220

11951221
SASSERT(e.get_coeff(k).is_one());
11961222

11971223
for (const auto& p : e) {
11981224
unsigned j = p.var();
11991225
if (j == k)
12001226
continue;
1201-
m_indexed_work_vector.add_value_at_index(j, p.coeff()*coeff);
1227+
m_substitution_workspace.add(p.coeff()*coeff, j);
12021228
// do we need to add j to the queue?
1203-
if (!var_is_fresh(j) && !m_indexed_work_vector[j].is_zero() &&
1204-
can_substitute(j))
1229+
if (!var_is_fresh(j) && m_substitution_workspace.has(j) && can_substitute(j))
12051230
q.push(j);
12061231
}
12071232
// there is no change in m_l_matrix
12081233
TRACE("dioph_eq", tout << "after subs k:" << k << "\n";
12091234
print_term_o(create_term_from_ind_c(), tout) << std::endl;
1210-
tout << "m_term_with_index:{"; print_lar_term_L(m_term_with_index.m_data, tout);
1211-
tout << "}, opened:"; print_ml(m_term_with_index.to_term(), tout) << std::endl;);
1235+
tout << "m_term_with_index:{"; print_lar_term_L(m_l_terms_workspace.m_data, tout);
1236+
tout << "}, opened:"; print_ml(m_l_terms_workspace.to_term(), tout) << std::endl;);
12121237
}
12131238

12141239
void add_l_row_to_term_with_index(const mpq& coeff, unsigned ei) {
12151240
for (const auto & p: m_l_matrix.m_rows[ei]) {
1216-
m_term_with_index.add(coeff * p.coeff(), p.var());
1241+
m_l_terms_workspace.add(coeff * p.coeff(), p.var());
12171242
}
12181243
}
12191244

@@ -1223,8 +1248,8 @@ namespace lp {
12231248
print_term_o(create_term_from_ind_c(), tout) << std::endl;
12241249
tout << "subs with e:";
12251250
print_entry(m_k2s[k], tout) << std::endl;);
1226-
mpq coeff = m_indexed_work_vector[k]; // need to copy since it will be zeroed
1227-
m_indexed_work_vector.erase(k); // m_indexed_work_vector[k] = 0;
1251+
mpq coeff = m_substitution_workspace[k]; // need to copy since it will be zeroed
1252+
m_substitution_workspace.erase(k); // m_work_vector_1[k] = 0;
12281253

12291254
const auto& e_row = m_e_matrix.m_rows[m_k2s[k]];
12301255
auto it = std::find_if(e_row.begin(), e_row.end(),
@@ -1241,18 +1266,18 @@ namespace lp {
12411266
unsigned j = p.var();
12421267
if (j == k)
12431268
continue;
1244-
m_indexed_work_vector.add_value_at_index(j, p.coeff() * coeff);
1269+
m_substitution_workspace.add(p.coeff() * coeff, j);
12451270
// do we need to add j to the queue?
1246-
if (!var_is_fresh(j) && !m_indexed_work_vector[j].is_zero() &&
1271+
if (!var_is_fresh(j) && m_substitution_workspace.has(j) &&
12471272
can_substitute(j))
12481273
q.push(j);
12491274
}
12501275
m_c += coeff * e;
12511276
add_l_row_to_term_with_index(coeff, sub_index(k));
12521277
TRACE("dioph_eq", tout << "after subs k:" << k << "\n";
12531278
print_term_o(create_term_from_ind_c(), tout) << std::endl;
1254-
tout << "m_term_with_index:{"; print_lar_term_L(m_term_with_index.to_term(), tout);
1255-
tout << "}, opened:"; print_ml(m_term_with_index.to_term(), tout) << std::endl;);
1279+
tout << "m_term_with_index:{"; print_lar_term_L(m_l_terms_workspace.to_term(), tout);
1280+
tout << "}, opened:"; print_ml(m_l_terms_workspace.to_term(), tout) << std::endl;);
12561281
}
12571282

12581283
bool is_substituted_by_fresh(unsigned k) const {
@@ -1263,7 +1288,7 @@ namespace lp {
12631288
// the coefficient of x_k in t.
12641289
void subs_front_in_indexed_vector(protected_queue& q) {
12651290
unsigned k = q.pop_front();
1266-
if (m_indexed_work_vector[k].is_zero())
1291+
if (!m_substitution_workspace.has(k))
12671292
return;
12681293
// we might substitute with a term from S or a fresh term
12691294

@@ -1362,25 +1387,23 @@ namespace lp {
13621387

13631388
term_o create_term_from_ind_c() {
13641389
term_o t;
1365-
for (const auto& p : m_indexed_work_vector) {
1390+
for (const auto& p : m_substitution_workspace.m_data) {
13661391
t.add_monomial(p.coeff(), p.var());
13671392
}
13681393
t.c() = m_c;
13691394
return t;
13701395
}
13711396

1372-
void fill_indexed_work_vector_from_term(const lar_term& lar_t) {
1373-
m_indexed_work_vector.clear();
1374-
m_indexed_work_vector.resize(m_e_matrix.column_count());
1397+
void init_substitutions(const lar_term& lar_t) {
1398+
m_substitution_workspace.clear();
13751399
m_c = 0;
1376-
m_term_with_index.clear();
1400+
m_l_terms_workspace.clear();
13771401
for (const auto& p : lar_t) {
13781402
SASSERT(p.coeff().is_int());
13791403
if (is_fixed(p.j()))
13801404
m_c += p.coeff() * lia.lower_bound(p.j()).x;
13811405
else
1382-
m_indexed_work_vector.set_value(p.coeff(),
1383-
lar_solver_to_local(p.j()));
1406+
m_substitution_workspace.add(p.coeff(), lar_solver_to_local(p.j()));
13841407
}
13851408
}
13861409
unsigned lar_solver_to_local(unsigned j) const {
@@ -1404,13 +1427,13 @@ namespace lp {
14041427
}
14051428
TRACE("dioph_eq", tout << "j:" << j << ", t: ";
14061429
print_lar_term_L(term_to_tighten, tout) << std::endl;);
1407-
fill_indexed_work_vector_from_term(term_to_tighten);
1430+
init_substitutions(term_to_tighten);
14081431
TRACE("dioph_eq", tout << "t orig:";
14091432
print_lar_term_L(term_to_tighten, tout) << std::endl;
14101433
tout << "from ind:";
14111434
print_term_o(create_term_from_ind_c(), tout) << std::endl;
14121435
tout << "m_tmp_l:";
1413-
print_lar_term_L(m_term_with_index.to_term(), tout) << std::endl;);
1436+
print_lar_term_L(m_l_terms_workspace.to_term(), tout) << std::endl;);
14141437
subs_indexed_vector_with_S_and_fresh(q);
14151438
// if(
14161439
// fix_vars(term_to_tighten + open_ml(m_tmp_l)) !=
@@ -1421,13 +1444,13 @@ namespace lp {
14211444
print_term_o(create_term_from_ind_c(), tout) << std::endl;
14221445
tout << "term_to_tighten:";
14231446
print_lar_term_L(term_to_tighten, tout) << std::endl;
1424-
tout << "m_tmp_l:"; print_lar_term_L(m_term_with_index.to_term(), tout) << std::endl;
1447+
tout << "m_tmp_l:"; print_lar_term_L(m_l_terms_workspace.to_term(), tout) << std::endl;
14251448
tout << "open_ml:";
1426-
print_lar_term_L(open_ml(m_term_with_index.to_term()), tout) << std::endl;
1449+
print_lar_term_L(open_ml(m_l_terms_workspace.to_term()), tout) << std::endl;
14271450
tout << "term_to_tighten + open_ml:";
1428-
print_term_o(term_to_tighten + open_ml(m_term_with_index.to_term()), tout)
1451+
print_term_o(term_to_tighten + open_ml(m_l_terms_workspace.to_term()), tout)
14291452
<< std::endl;
1430-
term_o ls = fix_vars(term_to_tighten + open_ml(m_term_with_index.to_term()));
1453+
term_o ls = fix_vars(term_to_tighten + open_ml(m_l_terms_workspace.to_term()));
14311454
tout << "ls:"; print_term_o(ls,tout) << std::endl;
14321455
term_o rs = term_to_lar_solver(remove_fresh_vars(create_term_from_ind_c()));
14331456
tout << "rs:"; print_term_o(rs, tout ) << std::endl;
@@ -1438,9 +1461,9 @@ namespace lp {
14381461
);
14391462

14401463
SASSERT(
1441-
fix_vars(term_to_tighten + open_ml(m_term_with_index.to_term())) ==
1464+
fix_vars(term_to_tighten + open_ml(m_l_terms_workspace.to_term())) ==
14421465
term_to_lar_solver(remove_fresh_vars(create_term_from_ind_c())));
1443-
mpq g = gcd_of_coeffs(m_indexed_work_vector, true);
1466+
mpq g = gcd_of_coeffs(m_substitution_workspace.m_data, true);
14441467
TRACE("dioph_eq", tout << "after process_q_with_S\nt:";
14451468
print_term_o(create_term_from_ind_c(), tout) << std::endl;
14461469
tout << "g:" << g << std::endl;
@@ -1474,7 +1497,7 @@ namespace lp {
14741497
if (m_c > rs || (is_strict && m_c == rs)) {
14751498
u_dependency* dep =
14761499
lra.join_deps(explain_fixed(lra.get_term(j)),
1477-
explain_fixed_in_meta_term(m_term_with_index.m_data));
1500+
explain_fixed_in_meta_term(m_l_terms_workspace.m_data));
14781501
dep = lra.join_deps(
14791502
dep, lra.get_bound_constraint_witnesses_for_column(j));
14801503
for (constraint_index ci : lra.flatten(dep)) {
@@ -1487,7 +1510,7 @@ namespace lp {
14871510
if (m_c < rs || (is_strict && m_c == rs)) {
14881511
u_dependency* dep =
14891512
lra.join_deps(explain_fixed(lra.get_term(j)),
1490-
explain_fixed_in_meta_term(m_term_with_index.m_data));
1513+
explain_fixed_in_meta_term(m_l_terms_workspace.m_data));
14911514
dep = lra.join_deps(
14921515
dep, lra.get_bound_constraint_witnesses_for_column(j));
14931516
for (constraint_index ci : lra.flatten(dep)) {
@@ -1497,7 +1520,7 @@ namespace lp {
14971520
}
14981521
}
14991522

1500-
// m_indexed_work_vector contains the coefficients of the term
1523+
// m_work_vector_1 contains the coefficients of the term
15011524
// m_c contains the constant term
15021525
// m_tmp_l is the linear combination of the equations that removes the
15031526
// substituted variables.
@@ -1542,7 +1565,7 @@ namespace lp {
15421565
lconstraint_kind kind =
15431566
upper ? lconstraint_kind::LE : lconstraint_kind::GE;
15441567
u_dependency* dep = prev_dep;
1545-
dep = lra.join_deps(dep, explain_fixed_in_meta_term(m_term_with_index.m_data));
1568+
dep = lra.join_deps(dep, explain_fixed_in_meta_term(m_l_terms_workspace.m_data));
15461569
u_dependency* j_bound_dep = upper
15471570
? lra.get_column_upper_bound_witness(j)
15481571
: lra.get_column_lower_bound_witness(j);
@@ -2192,33 +2215,26 @@ namespace lp {
21922215
return r;
21932216
}
21942217

2195-
void make_space_in_work_vector(unsigned j) {
2196-
if (j >= m_indexed_work_vector.data_size())
2197-
m_indexed_work_vector.resize(j + 1);
2198-
}
2199-
22002218
void open_l_term_to_work_vector(unsigned ei, mpq& c) {
2201-
m_indexed_work_vector.clear();
2219+
m_substitution_workspace.clear();
22022220
for (const auto & p: m_l_matrix.m_rows[ei]) {
22032221
const lar_term& t = lra.get_term(p.var());
22042222
for (const auto & q: t.ext_coeffs()) {
22052223
if (is_fixed(q.var())) {
22062224
c += p.coeff()*q.coeff()*lia.lower_bound(q.var()).x;
22072225
} else {
2208-
make_space_in_work_vector(q.var());
2209-
m_indexed_work_vector.add_value_at_index(q.var(), p.coeff() * q.coeff());
2226+
m_substitution_workspace.add(p.coeff() * q.coeff(), q.var());
22102227
}
22112228
}
22122229
}
22132230
}
22142231

22152232
// it clears the row, and puts the term in the work vector
22162233
void move_row_to_work_vector(unsigned ei) {
2217-
m_indexed_work_vector.clear();
2218-
m_indexed_work_vector.resize(m_e_matrix.column_count());
2234+
m_substitution_workspace.clear();
22192235
auto& row = m_e_matrix.m_rows[ei];
22202236
for (const auto& cell : row)
2221-
m_indexed_work_vector.set_value(cell.coeff(), cell.var());
2237+
m_substitution_workspace.add(cell.coeff(), cell.var());
22222238
clear_e_row(ei);
22232239
}
22242240

0 commit comments

Comments
 (0)