diff --git a/examples/python/rc2.py b/examples/python/rc2.py index 10bd83469..1a07b3bf2 100644 --- a/examples/python/rc2.py +++ b/examples/python/rc2.py @@ -8,6 +8,8 @@ from z3 import * +from z3 import * + def tt(s, f): return is_true(s.model().eval(f)) @@ -38,7 +40,7 @@ class RC2: name = Bool("%s" % fml) self.solver.add(Implies(name, fml)) self.bounds[name] = (S, k) - sel.names[fml] = name + self.names[fml] = name return name def print_cost(self): @@ -51,16 +53,18 @@ class RC2: # sort W, and incrementally add elements of W # in sorted order to prefer cores with high weight. def check(self, Ws): - ws = sorted(list(Ws), lambda f,w : -w) - # print(ws) + def compare(fw): + f, w = fw + return -w + ws = sorted([(k,Ws[k]) for k in Ws], key = compare) i = 0 while i < len(ws): j = i # increment j until making 5% progress or exhausting equal weight entries - while (j < len(ws) and ws[j][1] == ws[i][1]) or (i > 0 and (i - j)*20 < len(ws)): + while (j < len(ws) and ws[j][1] == ws[i][1]) or (i > 0 and (j - i)*20 < len(ws)): j += 1 i = j - r = self.solver.check(ws[j][0] for j in range(i)) + r = self.solver.check([ws[j][0] for j in range(i)]) if r == sat: self.update_max_cost() else: @@ -121,7 +125,7 @@ class RC2: self.min_cost += w self.print_cost() self.update_bounds(Ws, core, w) - return sel.min_cost, { f for f in self.Ws0 if not tt(self.solver, f) } + return self.min_cost, { f for f in self.Ws0 if not tt(self.solver, f) } def from_file(self, file): opt = Optimize() @@ -133,6 +137,14 @@ class RC2: assert(f.arg(1).as_long() == 0) add(Ws, f.arg(0), f.arg(2).as_long()) return self.maxsat(Ws) + + def from_formulas(self, hard, soft): + self.solver.add(hard) + Ws = {} + for f, cost in soft: + add(Ws, f, cost) + return self.maxsat(Ws) + def main(file): s = SolverFor("QF_FD") diff --git a/src/qe/nlqsat.cpp b/src/qe/nlqsat.cpp index 695bac07d..a37aef052 100644 --- a/src/qe/nlqsat.cpp +++ b/src/qe/nlqsat.cpp @@ -149,8 +149,8 @@ namespace qe { } } TRACE("qe", display(tout); - for (unsigned i = 0; i < m_asms.size(); ++i) { - m_solver.display(tout, m_asms[i]); tout << "\n"; + for (nlsat::literal a : m_asms) { + m_solver.display(tout, a) << "\n"; }); save_model(); } @@ -291,7 +291,7 @@ namespace qe { } nlsat::var_vector vs; m_solver.vars(l, vs); - TRACE("qe", m_solver.display(tout, l); tout << "\n";); + TRACE("qe", m_solver.display(tout << vs << " ", l) << "\n";); for (unsigned v : vs) { level.merge(m_rvar2level[v]); } @@ -492,10 +492,10 @@ namespace qe { return; } expr* n1, *n2; - if (a.is_div(n, n1, n2) && a.is_numeral(n2)) { + rational r; + if (a.is_div(n, n1, n2) && a.is_numeral(n2, r) && !r.is_zero()) { return; } - rational r; if (a.is_power(n, n1, n2) && a.is_numeral(n2, r) && r.is_unsigned()) { return; } @@ -511,7 +511,7 @@ namespace qe { bool has_divs() const { return m_has_divs; } }; - void purify(expr_ref& fml, app_ref_vector& pvars, expr_ref_vector& paxioms) { + void purify(expr_ref& fml, div_rewriter_star& rw, expr_ref_vector& paxioms) { is_pure_proc is_pure(*this); { expr_fast_mark1 visited; @@ -519,12 +519,12 @@ namespace qe { } if (is_pure.has_divs()) { arith_util arith(m); - div_rewriter_star rw(*this); proof_ref pr(m); + TRACE("qe", tout << fml << "\n";); rw(fml, fml, pr); + TRACE("qe", tout << fml << "\n";); vector
const& divs = rw.divs(); for (unsigned i = 0; i < divs.size(); ++i) { - pvars.push_back(divs[i].name); paxioms.push_back( m.mk_or(m.mk_eq(divs[i].den, arith.mk_numeral(rational(0), false)), m.mk_eq(divs[i].num, arith.mk_mul(divs[i].den, divs[i].name)))); @@ -540,12 +540,15 @@ namespace qe { void ackermanize_div(bool is_forall, vector& qvars, expr_ref& fml) { app_ref_vector pvars(m); expr_ref_vector paxioms(m); - purify(fml, pvars, paxioms); + div_rewriter_star rw(*this); + purify(fml, rw, paxioms); if (paxioms.empty()) { return; } expr_ref ante = mk_and(paxioms); - qvars[qvars.size()-2].append(pvars); + for (div const& d : rw.divs()) { + qvars[qvars.size()-2].push_back(d.name); + } if (!is_forall) { fml = m.mk_implies(ante, fml); }