@@ -193,7 +193,8 @@ class maxcore : public maxsmt_solver_base {
193193 }
194194
195195 void add (expr* e) {
196- s ().assert_expr (e);
196+ if (!m.is_true (e))
197+ s ().assert_expr (e);
197198 }
198199
199200 void add_soft (expr* e, rational const & w) {
@@ -536,22 +537,89 @@ class maxcore : public maxsmt_solver_base {
536537 }
537538 else {
538539 for (auto const &core : cores) {
539- for (unsigned i = 0 ; i + 1 < core.size (); ++i) {
540- auto [f, def, w] = core[i];
541- add (def);
542- new_assumption (f, w);
543- }
544- auto [f, def, w] = core.back ();
545- add (def);
546- f = mk_not (f);
547- add (f);
548- m_lower += w;
549- trace ();
540+ process_unsatw (core);
550541 }
551542 return l_true;
552543 }
553544 }
554545
546+ void process_unsatw (weighted_softs const & core) {
547+ for (unsigned i = 0 ; i + 1 < core.size (); ++i) {
548+ auto [f, c, d, w] = core[i];
549+ add (c);
550+ add (d);
551+ new_assumption (f, w);
552+ }
553+ auto [f, c, d, w] = core.back ();
554+ add (c);
555+ add (d);
556+ f = mk_not (f);
557+ add (f);
558+ if (core.size () <= 2 )
559+ m_defs.push_back (f);
560+ m_lower += w;
561+ IF_VERBOSE (2 , verbose_stream () << " (opt.maxresw increase-lower-bound " << w << " )\n " );
562+ trace ();
563+ }
564+
565+ weighted_softs core2weighted_soft (exprs const & core) {
566+ weighted_softs soft;
567+ for (expr *e : core) {
568+ rational w = get_weight (e);
569+ expr_ref tt (m.mk_true (), m);
570+ expr_ref s (e, m);
571+ soft.push_back ({s, tt, tt, w});
572+ }
573+ std::sort (soft.begin (), soft.end (), [](auto const &a, auto const &b) { return a.weight > b.weight ; });
574+ remove_soft (core, m_asms);
575+ expr_ref fml (m), conj (m), disj (m), c (m), a (m);
576+ IF_VERBOSE (2 , verbose_stream () << " (opt.maxresw core weights:" ;
577+ for (auto const &[s, c, d, w] : soft) verbose_stream () << " " << w; verbose_stream () << " )\n " ;);
578+ for (unsigned i = 0 ; i + 1 < soft.size (); ++i) {
579+ rational w1 = soft[i].weight ;
580+ rational w2 = soft[i + 1 ].weight ;
581+ auto s1 = soft[i].soft ;
582+ auto s2 = soft[i + 1 ].soft ;
583+ SASSERT (w1 >= w2);
584+ // a => s1 | s2
585+ // c => s1 & s2
586+ // s1 := a
587+ // s2 := c
588+ // assume s1, w1 - w2
589+ // new soft constraints are s1 or s2 : w2, s1 & s2 or s3 : w3, ...
590+ // remove soft constraint of weight w_n
591+ c = mk_fresh_bool (" c" );
592+ a = mk_fresh_bool (" a" );
593+
594+ conj = m.mk_and (s1, s2);
595+ update_model (c, conj);
596+ conj = m.mk_implies (c, conj);
597+
598+ disj = m.mk_or (s1, s2);
599+ update_model (a, disj);
600+ disj = m.mk_implies (a, disj);
601+
602+ soft[i].weight = w2;
603+ soft[i].soft = a;
604+ soft[i + 1 ].soft = c;
605+ soft[i + 1 ].conj = conj;
606+ soft[i + 1 ].disj = disj;
607+ m_defs.push_back (conj);
608+ m_defs.push_back (disj);
609+ if (w1 > w2) {
610+ for (unsigned j = 0 ; j < i; ++j) {
611+ auto [s, conj, disj, w] = soft[j];
612+ if (!m.is_true (conj)) {
613+ add (conj);
614+ soft[j].conj = m.mk_true ();
615+ }
616+ }
617+ new_assumption (s1, w1 - w2);
618+ }
619+ }
620+ return soft;
621+ }
622+
555623 lbool get_cores (vector<weighted_softs>& cores) {
556624 lbool is_sat = l_false;
557625 cores.reset ();
@@ -578,50 +646,8 @@ class maxcore : public maxsmt_solver_base {
578646 return l_true;
579647 }
580648
581- weighted_softs soft;
582- for (expr* e : core) {
583- rational w = get_weight (e);
584- expr_ref fml (m.mk_true (), m);
585- expr_ref s (e, m);
586- soft.push_back ({s, fml, w});
587- }
588- std::sort (soft.begin (), soft.end (),
589- [](auto const & a, auto const & b) {
590- return a.weight > b.weight ;
591- });
592- remove_soft (core, m_asms);
593- expr_ref fml (m), d (m);
594- for (unsigned i = 0 ; i + 1 < soft.size (); ++i) {
595- rational w1 = soft[i].weight ;
596- rational w2 = soft[i + 1 ].weight ;
597- auto s1 = soft[i].soft ;
598- auto s2 = soft[i + 1 ].soft ;
599- // verbose_stream() << "processing softs of weights " << s1 << " " << w1 << " and " << s2 << " " << w2 << "\n";
600- SASSERT (w1 >= w2);
601- // s1 := s1 or s2
602- // d => s1 & s2
603- // s2 := d
604- // assume s1, w1 - w2
605- // new soft constraints are s1 or s2 : w2, s1 & s2 or s3 : w3, ...
606- // remove soft constraint of weight w_n
607- d = mk_fresh_bool (" d" );
608- fml = m.mk_and (s1, s2);
609- update_model (d, fml);
610- soft[i].weight = w2;
611- soft[i].soft = m.mk_or (s1, s2);
612- soft[i + 1 ].soft = d;
613- soft[i + 1 ].def = m.mk_implies (d, fml);
614- if (w1 > w2) {
615- for (unsigned j = 0 ; j < i; ++j) {
616- auto [s, def, w] = soft[j];
617- if (!m.is_true (def)) {
618- add (def);
619- soft[j].def = m.mk_true ();
620- }
621- }
622- new_assumption (s1, w1 - w2);
623- }
624- }
649+ weighted_softs soft = core2weighted_soft (core);
650+
625651 cores.push_back (soft);
626652
627653 if (core.size () >= m_max_core_size)
@@ -687,7 +713,8 @@ class maxcore : public maxsmt_solver_base {
687713 max_resolve_rc2bin (core, w);
688714 break ;
689715 case strategy_t ::s_primalw:
690- UNREACHABLE ();
716+ max_resolve (core, w);
717+ break ;
691718 default :
692719 max_resolve (core, w);
693720 break ;
@@ -1067,6 +1094,18 @@ class maxcore : public maxsmt_solver_base {
10671094 }
10681095
10691096 void relax_cores (vector<expr_ref_vector> const & cores) {
1097+ if (m_st == s_primalw) {
1098+ for (auto const & core : cores) {
1099+ exprs _core (core.size (), core.data ());
1100+ weighted_softs soft = core2weighted_soft (_core);
1101+ IF_VERBOSE (2 , verbose_stream () << " (opt.maxresw relax-core weights:" ;
1102+ for (auto const &[s, c, d, w] : soft) verbose_stream () << " " << w;
1103+ verbose_stream () << " )\n " ;);
1104+ process_unsatw (soft);
1105+ }
1106+ return ;
1107+ }
1108+
10701109 vector<weighted_core> wcores;
10711110 for (auto & core : cores) {
10721111 exprs _core (core.size (), core.data ());
0 commit comments