@@ -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\n t:" ;
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