3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-10 19:27:06 +00:00

adding dump facility for cancelation , easing dimacs in/out

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2019-01-24 12:21:23 -08:00
parent f7746e2284
commit 498864c582
28 changed files with 653 additions and 518 deletions

View file

@ -163,12 +163,46 @@ extern "C" {
to_solver_ref(s)->set_model_converter(ctx->get_model_converter());
}
static void solver_from_dimacs_stream(Z3_context c, Z3_solver s, std::istream& is) {
init_solver(c, s);
ast_manager& m = to_solver_ref(s)->get_manager();
std::stringstream err;
sat::solver solver(to_solver_ref(s)->get_params(), m.limit());
if (!parse_dimacs(is, err, solver)) {
SET_ERROR_CODE(Z3_PARSER_ERROR, err.str().c_str());
return;
}
sat2goal s2g;
ref<sat2goal::mc> mc;
atom2bool_var a2b(m);
for (unsigned v = 0; v < solver.num_vars(); ++v) {
a2b.insert(m.mk_const(symbol(v), m.mk_bool_sort()), v);
}
goal g(m);
s2g(solver, a2b, to_solver_ref(s)->get_params(), g, mc);
for (unsigned i = 0; i < g.size(); ++i) {
to_solver_ref(s)->assert_expr(g.form(i));
}
}
// DIMACS files start with "p cnf" and number of variables/clauses.
// This is not legal SMT syntax, so use the DIMACS parser.
static bool is_dimacs_string(Z3_string c_str) {
std::cout << c_str << "\n";
return c_str[0] == 'p' && c_str[1] == ' ' && c_str[2] == 'c';
}
void Z3_API Z3_solver_from_string(Z3_context c, Z3_solver s, Z3_string c_str) {
Z3_TRY;
LOG_Z3_solver_from_string(c, s, c_str);
std::string str(c_str);
std::istringstream is(str);
solver_from_stream(c, s, is);
if (is_dimacs_string(c_str)) {
solver_from_dimacs_stream(c, s, is);
}
else {
solver_from_stream(c, s, is);
}
Z3_CATCH;
}
@ -182,24 +216,7 @@ extern "C" {
SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR, nullptr);
}
else if (ext && (std::string("dimacs") == ext || std::string("cnf") == ext)) {
ast_manager& m = to_solver_ref(s)->get_manager();
std::stringstream err;
sat::solver solver(to_solver_ref(s)->get_params(), m.limit());
if (!parse_dimacs(is, err, solver)) {
SET_ERROR_CODE(Z3_PARSER_ERROR, err.str().c_str());
return;
}
sat2goal s2g;
ref<sat2goal::mc> mc;
atom2bool_var a2b(m);
for (unsigned v = 0; v < solver.num_vars(); ++v) {
a2b.insert(m.mk_const(symbol(v), m.mk_bool_sort()), v);
}
goal g(m);
s2g(solver, a2b, to_solver_ref(s)->get_params(), g, mc);
for (unsigned i = 0; i < g.size(); ++i) {
to_solver_ref(s)->assert_expr(g.form(i));
}
solver_from_dimacs_stream(c, s, is);
}
else {
solver_from_stream(c, s, is);
@ -532,6 +549,17 @@ extern "C" {
Z3_CATCH_RETURN("");
}
Z3_string Z3_API Z3_solver_to_dimacs_string(Z3_context c, Z3_solver s) {
Z3_TRY;
LOG_Z3_solver_to_string(c, s);
RESET_ERROR_CODE();
init_solver(c, s);
std::ostringstream buffer;
to_solver_ref(s)->display_dimacs(buffer);
return mk_c(c)->mk_external_string(buffer.str());
Z3_CATCH_RETURN("");
}
Z3_lbool Z3_API Z3_get_implied_equalities(Z3_context c,
Z3_solver s,

View file

@ -2240,6 +2240,8 @@ namespace z3 {
fml));
}
std::string dimacs() const { return std::string(Z3_solver_to_dimacs_string(ctx(), m_solver)); }
param_descrs get_param_descrs() { return param_descrs(ctx(), Z3_solver_get_param_descrs(ctx(), m_solver)); }

View file

@ -6800,6 +6800,10 @@ class Solver(Z3PPObject):
"""
return Z3_solver_to_string(self.ctx.ref(), self.solver)
def dimacs(self):
"""Return a textual representation of the solver in DIMACS format."""
return Z3_solver_to_dimacs_string(self.ctx.ref(), self.solver)
def to_smt2(self):
"""return SMTLIB2 formatted benchmark for solver's assertions"""
es = self.assertions()

View file

@ -6368,6 +6368,14 @@ extern "C" {
*/
Z3_string Z3_API Z3_solver_to_string(Z3_context c, Z3_solver s);
/**
\brief Convert a solver into a DIMACS formatted string.
\sa Z3_goal_to_diamcs_string for requirements.
def_API('Z3_solver_to_dimacs_string', STRING, (_in(CONTEXT), _in(SOLVER)))
*/
Z3_string Z3_API Z3_solver_to_dimacs_string(Z3_context c, Z3_solver s);
/*@}*/
/** @name Statistics */

View file

@ -17,6 +17,7 @@ z3_add_component(ast
csp_decl_plugin.cpp
datatype_decl_plugin.cpp
decl_collector.cpp
display_dimacs.cpp
dl_decl_plugin.cpp
expr2polynomial.cpp
expr2var.cpp

View file

@ -0,0 +1,81 @@
/*++
Copyright (c) 2019 Microsoft Corporation
Module Name:
display_dimacs.h
Abstract:
Display expressions in DIMACS format.
Author:
Nikolaj Bjorner (nbjorner0 2019-01-24
Revision History:
--*/
#include "ast.h"
#include "display_dimacs.h"
std::ostream& display_dimacs(std::ostream& out, expr_ref_vector const& fmls) {
ast_manager& m = fmls.m();
unsigned_vector expr2var;
ptr_vector<expr> exprs;
unsigned num_vars = 0;
unsigned num_cls = fmls.size();
for (expr * f : fmls) {
unsigned num_lits;
expr * const * lits;
if (m.is_or(f)) {
num_lits = to_app(f)->get_num_args();
lits = to_app(f)->get_args();
}
else {
num_lits = 1;
lits = &f;
}
for (unsigned j = 0; j < num_lits; j++) {
expr * l = lits[j];
if (m.is_not(l))
l = to_app(l)->get_arg(0);
if (expr2var.get(l->get_id(), UINT_MAX) == UINT_MAX) {
num_vars++;
expr2var.setx(l->get_id(), num_vars, UINT_MAX);
exprs.setx(l->get_id(), l, nullptr);
}
}
}
out << "p cnf " << num_vars << " " << num_cls << "\n";
for (expr* f : fmls) {
unsigned num_lits;
expr * const * lits;
if (m.is_or(f)) {
num_lits = to_app(f)->get_num_args();
lits = to_app(f)->get_args();
}
else {
num_lits = 1;
lits = &f;
}
for (unsigned j = 0; j < num_lits; j++) {
expr * l = lits[j];
if (m.is_not(l)) {
out << "-";
l = to_app(l)->get_arg(0);
}
SASSERT(exprs[l->get_id()]);
out << expr2var[l->get_id()] << " ";
}
out << "0\n";
}
for (expr* e : exprs) {
if (e && is_app(e)) {
symbol const& n = to_app(e)->get_decl()->get_name();
out << "c " << expr2var[e->get_id()] << " " << n << "\n";
}
}
return out;
}

26
src/ast/display_dimacs.h Normal file
View file

@ -0,0 +1,26 @@
/*++
Copyright (c) 2019 Microsoft Corporation
Module Name:
display_dimacs.h
Abstract:
Display expressions in DIMACS format.
Author:
Nikolaj Bjorner (nbjorner0 2019-01-24
Revision History:
--*/
#ifndef DISPLAY_DIMACS_H_
#define DISPLAY_DIMACS_H_
#include "ast.h"
std::ostream& display_dimacs(std::ostream& out, expr_ref_vector const& fmls);
#endif /* DISPLAY_DIMACS_H__ */

View file

@ -27,443 +27,426 @@ Notes:
#include "muz/spacer/spacer_iuc_proof.h"
namespace spacer {
void iuc_solver::push ()
{
m_defs.push_back (def_manager (*this));
m_solver.push ();
}
void iuc_solver::pop (unsigned n)
{
m_solver.pop (n);
unsigned lvl = m_defs.size ();
SASSERT (n <= lvl);
unsigned new_lvl = lvl-n;
while (m_defs.size() > new_lvl) {
m_num_proxies -= m_defs.back ().m_defs.size ();
m_defs.pop_back ();
void iuc_solver::push () {
m_defs.push_back (def_manager (*this));
m_solver.push ();
}
}
app* iuc_solver::fresh_proxy ()
{
if (m_num_proxies == m_proxies.size()) {
std::stringstream name;
name << "spacer_proxy!" << m_proxies.size ();
app_ref res(m);
res = m.mk_const (symbol (name.str ().c_str ()),
m.mk_bool_sort ());
m_proxies.push_back (res);
// -- add the new proxy to proxy eliminator
proof_ref pr(m);
pr = m.mk_asserted (m.mk_true ());
m_elim_proxies_sub.insert (res, m.mk_true (), pr);
void iuc_solver::pop (unsigned n) {
m_solver.pop (n);
unsigned lvl = m_defs.size ();
SASSERT (n <= lvl);
unsigned new_lvl = lvl-n;
while (m_defs.size() > new_lvl) {
m_num_proxies -= m_defs.back ().m_defs.size ();
m_defs.pop_back ();
}
}
return m_proxies.get (m_num_proxies++);
}
app* iuc_solver::mk_proxy (expr *v)
{
{
app* iuc_solver::fresh_proxy () {
if (m_num_proxies == m_proxies.size()) {
std::stringstream name;
name << "spacer_proxy!" << m_proxies.size ();
app_ref res(m);
res = m.mk_const (symbol (name.str ().c_str ()),
m.mk_bool_sort ());
m_proxies.push_back (res);
// -- add the new proxy to proxy eliminator
proof_ref pr(m);
pr = m.mk_asserted (m.mk_true ());
m_elim_proxies_sub.insert (res, m.mk_true (), pr);
}
return m_proxies.get (m_num_proxies++);
}
app* iuc_solver::mk_proxy (expr *v) {
expr *e = v;
m.is_not (v, e);
if (is_uninterp_const(e)) { return to_app(v); }
if (is_uninterp_const(e)) {
return to_app(v);
}
def_manager &def = !m_defs.empty() ? m_defs.back () : m_base_defs;
return def.mk_proxy (v);
}
def_manager &def = !m_defs.empty() ? m_defs.back () : m_base_defs;
return def.mk_proxy (v);
}
bool iuc_solver::mk_proxies (expr_ref_vector &v, unsigned from)
{
bool dirty = false;
for (unsigned i = from, sz = v.size(); i < sz; ++i) {
app *p = mk_proxy (v.get (i));
dirty |= (v.get (i) != p);
v[i] = p;
bool iuc_solver::mk_proxies (expr_ref_vector &v, unsigned from) {
bool dirty = false;
for (unsigned i = from, sz = v.size(); i < sz; ++i) {
app *p = mk_proxy (v.get (i));
dirty |= (v.get (i) != p);
v[i] = p;
}
return dirty;
}
return dirty;
}
void iuc_solver::push_bg (expr *e)
{
if (m_assumptions.size () > m_first_assumption)
{ m_assumptions.shrink(m_first_assumption); }
m_assumptions.push_back (e);
m_first_assumption = m_assumptions.size ();
}
void iuc_solver::pop_bg (unsigned n)
{
if (n == 0) { return; }
if (m_assumptions.size () > m_first_assumption) {
void iuc_solver::push_bg (expr *e) {
if (m_assumptions.size () > m_first_assumption) {
m_assumptions.shrink(m_first_assumption);
}
m_assumptions.push_back (e);
m_first_assumption = m_assumptions.size ();
}
void iuc_solver::pop_bg (unsigned n) {
if (n == 0) return;
if (m_assumptions.size () > m_first_assumption) {
m_assumptions.shrink(m_first_assumption);
}
m_first_assumption = m_first_assumption > n ? m_first_assumption - n : 0;
m_assumptions.shrink (m_first_assumption);
}
unsigned iuc_solver::get_num_bg () {
return m_first_assumption;
}
lbool iuc_solver::check_sat_core (unsigned num_assumptions, expr * const *assumptions) {
// -- remove any old assumptions
m_assumptions.shrink(m_first_assumption);
// -- replace theory literals in background assumptions with proxies
mk_proxies (m_assumptions);
// -- in case mk_proxies added new literals, they are all background
m_first_assumption = m_assumptions.size ();
m_assumptions.append (num_assumptions, assumptions);
m_is_proxied = mk_proxies (m_assumptions, m_first_assumption);
return set_status (m_solver.check_sat (m_assumptions));
}
m_first_assumption = m_first_assumption > n ? m_first_assumption - n : 0;
m_assumptions.shrink (m_first_assumption);
}
lbool iuc_solver::check_sat_cc(const expr_ref_vector &cube,
vector<expr_ref_vector> const & clauses) {
if (clauses.empty())
return check_sat(cube.size(), cube.c_ptr());
// -- remove any old assumptions
m_assumptions.shrink(m_first_assumption);
// -- replace theory literals in background assumptions with proxies
mk_proxies(m_assumptions);
// -- in case mk_proxies added new literals, they are all background
m_first_assumption = m_assumptions.size();
m_assumptions.append(cube);
m_is_proxied = mk_proxies(m_assumptions, m_first_assumption);
return set_status (m_solver.check_sat_cc(m_assumptions, clauses));
}
unsigned iuc_solver::get_num_bg () {return m_first_assumption;}
lbool iuc_solver::check_sat (unsigned num_assumptions, expr * const *assumptions)
{
// -- remove any old assumptions
m_assumptions.shrink(m_first_assumption);
// -- replace theory literals in background assumptions with proxies
mk_proxies (m_assumptions);
// -- in case mk_proxies added new literals, they are all background
m_first_assumption = m_assumptions.size ();
m_assumptions.append (num_assumptions, assumptions);
m_is_proxied = mk_proxies (m_assumptions, m_first_assumption);
return set_status (m_solver.check_sat (m_assumptions));
}
lbool iuc_solver::check_sat_cc(const expr_ref_vector &cube,
vector<expr_ref_vector> const & clauses) {
if (clauses.empty())
return check_sat(cube.size(), cube.c_ptr());
// -- remove any old assumptions
m_assumptions.shrink(m_first_assumption);
// -- replace theory literals in background assumptions with proxies
mk_proxies(m_assumptions);
// -- in case mk_proxies added new literals, they are all background
m_first_assumption = m_assumptions.size();
m_assumptions.append(cube);
m_is_proxied = mk_proxies(m_assumptions, m_first_assumption);
return set_status (m_solver.check_sat_cc(m_assumptions, clauses));
}
app* iuc_solver::def_manager::mk_proxy (expr *v)
{
app* r;
if (m_expr2proxy.find(v, r))
return r;
ast_manager &m = m_parent.m;
app* proxy = m_parent.fresh_proxy ();
app* def = m.mk_or (m.mk_not (proxy), v);
m_defs.push_back (def);
m_expr2proxy.insert (v, proxy);
m_proxy2def.insert (proxy, def);
m_parent.assert_expr (def);
return proxy;
}
bool iuc_solver::def_manager::is_proxy (app *k, app_ref &def)
{
app *r = nullptr;
bool found = m_proxy2def.find (k, r);
def = r;
return found;
}
void iuc_solver::def_manager::reset ()
{
m_expr2proxy.reset ();
m_proxy2def.reset ();
m_defs.reset ();
}
bool iuc_solver::def_manager::is_proxy_def (expr *v)
{
// XXX This might not be the most robust way to check
return m_defs.contains (v);
}
bool iuc_solver::is_proxy(expr *e, app_ref &def)
{
if (!is_uninterp_const(e))
return false;
app* a = to_app (e);
for (int i = m_defs.size (); i-- > 0; )
if (m_defs[i].is_proxy (a, def))
return true;
return m_base_defs.is_proxy (a, def);
}
void iuc_solver::collect_statistics (statistics &st) const
{
m_solver.collect_statistics (st);
st.update ("time.iuc_solver.get_iuc", m_iuc_sw.get_seconds());
st.update ("time.iuc_solver.get_iuc.hyp_reduce1", m_hyp_reduce1_sw.get_seconds());
st.update ("time.iuc_solver.get_iuc.hyp_reduce2", m_hyp_reduce2_sw.get_seconds());
st.update ("time.iuc_solver.get_iuc.learn_core", m_learn_core_sw.get_seconds());
st.update("iuc_solver.num_proxies", m_proxies.size());
}
void iuc_solver::reset_statistics ()
{
m_iuc_sw.reset();
m_hyp_reduce1_sw.reset();
m_hyp_reduce2_sw.reset();
m_learn_core_sw.reset();
}
void iuc_solver::get_unsat_core (expr_ref_vector &core) {
m_solver.get_unsat_core (core);
undo_proxies_in_core (core);
}
void iuc_solver::undo_proxies_in_core (expr_ref_vector &r)
{
app_ref e(m);
expr_fast_mark1 bg;
for (unsigned i = 0; i < m_first_assumption; ++i) {
bg.mark(m_assumptions.get(i));
app* iuc_solver::def_manager::mk_proxy (expr *v) {
app* r;
if (m_expr2proxy.find(v, r))
return r;
ast_manager &m = m_parent.m;
app* proxy = m_parent.fresh_proxy ();
app* def = m.mk_or (m.mk_not (proxy), v);
m_defs.push_back (def);
m_expr2proxy.insert (v, proxy);
m_proxy2def.insert (proxy, def);
m_parent.assert_expr (def);
return proxy;
}
// expand proxies
unsigned j = 0;
for (expr* rr : r) {
// skip background assumptions
if (bg.is_marked(rr))
continue;
bool iuc_solver::def_manager::is_proxy (app *k, app_ref &def) {
app *r = nullptr;
bool found = m_proxy2def.find (k, r);
def = r;
return found;
}
void iuc_solver::def_manager::reset () {
m_expr2proxy.reset ();
m_proxy2def.reset ();
m_defs.reset ();
}
// -- undo proxies, but only if they were introduced in check_sat
if (m_is_proxied && is_proxy(rr, e)) {
SASSERT (m.is_or (e));
r[j++] = e->get_arg (1);
bool iuc_solver::def_manager::is_proxy_def (expr *v) {
// XXX This might not be the most robust way to check
return m_defs.contains (v);
}
bool iuc_solver::is_proxy(expr *e, app_ref &def) {
if (!is_uninterp_const(e))
return false;
app* a = to_app (e);
for (int i = m_defs.size (); i-- > 0; )
if (m_defs[i].is_proxy (a, def))
return true;
return m_base_defs.is_proxy (a, def);
}
void iuc_solver::collect_statistics (statistics &st) const {
m_solver.collect_statistics (st);
st.update ("time.iuc_solver.get_iuc", m_iuc_sw.get_seconds());
st.update ("time.iuc_solver.get_iuc.hyp_reduce1", m_hyp_reduce1_sw.get_seconds());
st.update ("time.iuc_solver.get_iuc.hyp_reduce2", m_hyp_reduce2_sw.get_seconds());
st.update ("time.iuc_solver.get_iuc.learn_core", m_learn_core_sw.get_seconds());
st.update("iuc_solver.num_proxies", m_proxies.size());
}
void iuc_solver::reset_statistics () {
m_iuc_sw.reset();
m_hyp_reduce1_sw.reset();
m_hyp_reduce2_sw.reset();
m_learn_core_sw.reset();
}
void iuc_solver::get_unsat_core (expr_ref_vector &core) {
m_solver.get_unsat_core (core);
undo_proxies_in_core (core);
}
void iuc_solver::undo_proxies_in_core (expr_ref_vector &r) {
app_ref e(m);
expr_fast_mark1 bg;
for (unsigned i = 0; i < m_first_assumption; ++i) {
bg.mark(m_assumptions.get(i));
}
// expand proxies
unsigned j = 0;
for (expr* rr : r) {
// skip background assumptions
if (bg.is_marked(rr))
continue;
// -- undo proxies, but only if they were introduced in check_sat
if (m_is_proxied && is_proxy(rr, e)) {
SASSERT (m.is_or (e));
r[j++] = e->get_arg (1);
}
else {
r[j++] = rr;
}
}
r.shrink (j);
}
void iuc_solver::undo_proxies (expr_ref_vector &r) {
app_ref e(m);
// expand proxies
for (unsigned i = 0, sz = r.size (); i < sz; ++i)
if (is_proxy(r.get(i), e)) {
SASSERT (m.is_or (e));
r[i] = e->get_arg (1);
}
}
void iuc_solver::elim_proxies (expr_ref_vector &v) {
expr_ref f = mk_and (v);
scoped_ptr<expr_replacer> rep = mk_expr_simp_replacer (m);
rep->set_substitution (&m_elim_proxies_sub);
(*rep)(f);
v.reset();
flatten_and(f, v);
}
void iuc_solver::get_iuc(expr_ref_vector &core) {
scoped_watch _t_ (m_iuc_sw);
typedef obj_hashtable<expr> expr_set;
expr_set core_lits;
for (unsigned i = m_first_assumption, sz = m_assumptions.size(); i < sz; ++i) {
expr *a = m_assumptions.get (i);
app_ref def(m);
if (is_proxy(a, def)) { core_lits.insert(def.get()); }
core_lits.insert (a);
}
if (m_iuc == 0) {
// ORIGINAL PDR CODE
// AG: deprecated
proof_ref pr(m);
pr = get_proof ();
farkas_learner learner_old;
learner_old.set_split_literals(m_split_literals);
learner_old.get_lemmas (pr, core_lits, core);
elim_proxies (core);
simplify_bounds (core); // XXX potentially redundant
}
else {
r[j++] = rr;
}
}
r.shrink (j);
}
void iuc_solver::undo_proxies (expr_ref_vector &r)
{
app_ref e(m);
// expand proxies
for (unsigned i = 0, sz = r.size (); i < sz; ++i)
if (is_proxy(r.get(i), e)) {
SASSERT (m.is_or (e));
r[i] = e->get_arg (1);
}
}
void iuc_solver::elim_proxies (expr_ref_vector &v)
{
expr_ref f = mk_and (v);
scoped_ptr<expr_replacer> rep = mk_expr_simp_replacer (m);
rep->set_substitution (&m_elim_proxies_sub);
(*rep)(f);
v.reset();
flatten_and(f, v);
}
void iuc_solver::get_iuc(expr_ref_vector &core)
{
scoped_watch _t_ (m_iuc_sw);
typedef obj_hashtable<expr> expr_set;
expr_set core_lits;
for (unsigned i = m_first_assumption, sz = m_assumptions.size(); i < sz; ++i) {
expr *a = m_assumptions.get (i);
app_ref def(m);
if (is_proxy(a, def)) { core_lits.insert(def.get()); }
core_lits.insert (a);
}
if (m_iuc == 0) {
// ORIGINAL PDR CODE
// AG: deprecated
proof_ref pr(m);
pr = get_proof ();
farkas_learner learner_old;
learner_old.set_split_literals(m_split_literals);
learner_old.get_lemmas (pr, core_lits, core);
elim_proxies (core);
simplify_bounds (core); // XXX potentially redundant
}
else {
// NEW IUC
proof_ref res(get_proof(), m);
// -- old hypothesis reducer while the new one is broken
if (m_old_hyp_reducer) {
scoped_watch _t_ (m_hyp_reduce1_sw);
// AG: deprecated
// pre-process proof in order to get a proof which is
// better suited for unsat-core-extraction
if (m_print_farkas_stats) {
iuc_proof iuc_before(m, res.get(), core_lits);
verbose_stream() << "\nOld reduce_hypotheses. Before:";
iuc_before.dump_farkas_stats();
// NEW IUC
proof_ref res(get_proof(), m);
// -- old hypothesis reducer while the new one is broken
if (m_old_hyp_reducer) {
scoped_watch _t_ (m_hyp_reduce1_sw);
// AG: deprecated
// pre-process proof in order to get a proof which is
// better suited for unsat-core-extraction
if (m_print_farkas_stats) {
iuc_proof iuc_before(m, res.get(), core_lits);
verbose_stream() << "\nOld reduce_hypotheses. Before:";
iuc_before.dump_farkas_stats();
}
proof_utils::reduce_hypotheses(res);
proof_utils::permute_unit_resolution(res);
if (m_print_farkas_stats) {
iuc_proof iuc_after(m, res.get(), core_lits);
verbose_stream() << "Old reduce_hypothesis. After:";
iuc_after.dump_farkas_stats();
}
}
proof_utils::reduce_hypotheses(res);
proof_utils::permute_unit_resolution(res);
if (m_print_farkas_stats) {
iuc_proof iuc_after(m, res.get(), core_lits);
verbose_stream() << "Old reduce_hypothesis. After:";
iuc_after.dump_farkas_stats();
}
}
// -- new hypothesis reducer
else
{
// -- new hypothesis reducer
else
{
#if 0
static unsigned bcnt = 0;
static unsigned bcnt = 0;
{
bcnt++;
TRACE("spacer", tout << "Dumping pf bcnt: " << bcnt << "\n";);
if (bcnt == 123) {
std::ofstream ofs;
ofs.open("/tmp/bpf_" + std::to_string(bcnt) + ".dot");
iuc_proof iuc_pf_before(m, res.get(), core_lits);
iuc_pf_before.display_dot(ofs);
ofs.close();
proof_checker pc(m);
expr_ref_vector side(m);
ENSURE(pc.check(res, side));
}
}
#endif
scoped_watch _t_ (m_hyp_reduce2_sw);
// pre-process proof for better iuc extraction
if (m_print_farkas_stats) {
iuc_proof iuc_before(m, res.get(), core_lits);
verbose_stream() << "\n New hypothesis_reducer. Before:";
iuc_before.dump_farkas_stats();
}
proof_ref pr1(m);
{
scoped_watch _t_ (m_hyp_reduce1_sw);
theory_axiom_reducer ta_reducer(m);
pr1 = ta_reducer.reduce (res.get());
}
proof_ref pr2(m);
{
scoped_watch _t_ (m_hyp_reduce2_sw);
hypothesis_reducer hyp_reducer(m);
pr2 = hyp_reducer.reduce(pr1);
}
res = pr2;
if (m_print_farkas_stats) {
iuc_proof iuc_after(m, res.get(), core_lits);
verbose_stream() << "New hypothesis_reducer. After:";
iuc_after.dump_farkas_stats();
}
}
iuc_proof iuc_pf(m, res, core_lits);
#if 0
static unsigned cnt = 0;
{
bcnt++;
TRACE("spacer", tout << "Dumping pf bcnt: " << bcnt << "\n";);
if (bcnt == 123) {
cnt++;
TRACE("spacer", tout << "Dumping pf cnt: " << cnt << "\n";);
if (cnt == 123) {
std::ofstream ofs;
ofs.open("/tmp/bpf_" + std::to_string(bcnt) + ".dot");
iuc_proof iuc_pf_before(m, res.get(), core_lits);
iuc_pf_before.display_dot(ofs);
ofs.open("/tmp/pf_" + std::to_string(cnt) + ".dot");
iuc_pf.display_dot(ofs);
ofs.close();
proof_checker pc(m);
expr_ref_vector side(m);
ENSURE(pc.check(res, side));
}
}
#endif
scoped_watch _t_ (m_hyp_reduce2_sw);
// pre-process proof for better iuc extraction
if (m_print_farkas_stats) {
iuc_proof iuc_before(m, res.get(), core_lits);
verbose_stream() << "\n New hypothesis_reducer. Before:";
iuc_before.dump_farkas_stats();
unsat_core_learner learner(m, iuc_pf);
unsat_core_plugin* plugin;
// -- register iuc plugins
switch (m_iuc_arith) {
case 0:
case 1:
plugin =
alloc(unsat_core_plugin_farkas_lemma,
learner, m_split_literals,
(m_iuc_arith == 1) /* use constants from A */);
learner.register_plugin(plugin);
break;
case 2:
SASSERT(false && "Broken");
plugin = alloc(unsat_core_plugin_farkas_lemma_optimized, learner, m);
learner.register_plugin(plugin);
break;
case 3:
plugin = alloc(unsat_core_plugin_farkas_lemma_bounded, learner, m);
learner.register_plugin(plugin);
break;
default:
UNREACHABLE();
break;
}
proof_ref pr1(m);
switch (m_iuc) {
case 1:
// -- iuc based on the lowest cut in the proof
plugin = alloc(unsat_core_plugin_lemma, learner);
learner.register_plugin(plugin);
break;
case 2:
// -- iuc based on the smallest cut in the proof
plugin = alloc(unsat_core_plugin_min_cut, learner, m);
learner.register_plugin(plugin);
break;
default:
UNREACHABLE();
break;
}
{
scoped_watch _t_ (m_hyp_reduce1_sw);
theory_axiom_reducer ta_reducer(m);
pr1 = ta_reducer.reduce (res.get());
}
proof_ref pr2(m);
{
scoped_watch _t_ (m_hyp_reduce2_sw);
hypothesis_reducer hyp_reducer(m);
pr2 = hyp_reducer.reduce(pr1);
}
res = pr2;
if (m_print_farkas_stats) {
iuc_proof iuc_after(m, res.get(), core_lits);
verbose_stream() << "New hypothesis_reducer. After:";
iuc_after.dump_farkas_stats();
scoped_watch _t_ (m_learn_core_sw);
// compute interpolating unsat core
learner.compute_unsat_core(core);
}
elim_proxies (core);
// AG: this should be taken care of by minimizing the iuc cut
simplify_bounds (core);
}
iuc_proof iuc_pf(m, res, core_lits);
#if 0
static unsigned cnt = 0;
{
cnt++;
TRACE("spacer", tout << "Dumping pf cnt: " << cnt << "\n";);
if (cnt == 123) {
std::ofstream ofs;
ofs.open("/tmp/pf_" + std::to_string(cnt) + ".dot");
iuc_pf.display_dot(ofs);
ofs.close();
proof_checker pc(m);
expr_ref_vector side(m);
ENSURE(pc.check(res, side));
}
}
#endif
unsat_core_learner learner(m, iuc_pf);
unsat_core_plugin* plugin;
// -- register iuc plugins
switch (m_iuc_arith) {
case 0:
case 1:
plugin =
alloc(unsat_core_plugin_farkas_lemma,
learner, m_split_literals,
(m_iuc_arith == 1) /* use constants from A */);
learner.register_plugin(plugin);
break;
case 2:
SASSERT(false && "Broken");
plugin = alloc(unsat_core_plugin_farkas_lemma_optimized, learner, m);
learner.register_plugin(plugin);
break;
case 3:
plugin = alloc(unsat_core_plugin_farkas_lemma_bounded, learner, m);
learner.register_plugin(plugin);
break;
default:
UNREACHABLE();
break;
}
switch (m_iuc) {
case 1:
// -- iuc based on the lowest cut in the proof
plugin = alloc(unsat_core_plugin_lemma, learner);
learner.register_plugin(plugin);
break;
case 2:
// -- iuc based on the smallest cut in the proof
plugin = alloc(unsat_core_plugin_min_cut, learner, m);
learner.register_plugin(plugin);
break;
default:
UNREACHABLE();
break;
}
{
scoped_watch _t_ (m_learn_core_sw);
// compute interpolating unsat core
learner.compute_unsat_core(core);
}
elim_proxies (core);
// AG: this should be taken care of by minimizing the iuc cut
simplify_bounds (core);
IF_VERBOSE(2,
verbose_stream () << "IUC Core:\n" << core << "\n";);
}
IF_VERBOSE(2,
verbose_stream () << "IUC Core:\n" << core << "\n";);
}
void iuc_solver::refresh ()
{
// only refresh in non-pushed state
SASSERT (m_defs.empty());
expr_ref_vector assertions (m);
for (unsigned i = 0, e = m_solver.get_num_assertions(); i < e; ++i) {
expr* a = m_solver.get_assertion (i);
if (!m_base_defs.is_proxy_def(a)) { assertions.push_back(a); }
void iuc_solver::refresh () {
// only refresh in non-pushed state
SASSERT (m_defs.empty());
expr_ref_vector assertions (m);
for (unsigned i = 0, e = m_solver.get_num_assertions(); i < e; ++i) {
expr* a = m_solver.get_assertion (i);
if (!m_base_defs.is_proxy_def(a)) { assertions.push_back(a); }
}
m_base_defs.reset ();
NOT_IMPLEMENTED_YET ();
// solver interface does not have a reset method. need to introduce it somewhere.
// m_solver.reset ();
for (unsigned i = 0, e = assertions.size (); i < e; ++i)
{ m_solver.assert_expr(assertions.get(i)); }
}
m_base_defs.reset ();
NOT_IMPLEMENTED_YET ();
// solver interface does not have a reset method. need to introduce it somewhere.
// m_solver.reset ();
for (unsigned i = 0, e = assertions.size (); i < e; ++i)
{ m_solver.assert_expr(assertions.get(i)); }
}
}

View file

@ -127,7 +127,7 @@ public:
void pop(unsigned n) override;
unsigned get_scope_level() const override { return m_solver.get_scope_level(); }
lbool check_sat(unsigned num_assumptions, expr * const *assumptions) override;
lbool check_sat_core(unsigned num_assumptions, expr * const *assumptions) override;
lbool check_sat_cc(const expr_ref_vector &cube, vector<expr_ref_vector> const & clauses) override;
void set_progress_callback(progress_callback *callback) override {
m_solver.set_progress_callback(callback);

View file

@ -158,7 +158,7 @@ namespace opt {
return m_dump_benchmarks;
}
lbool opt_solver::check_sat_core(unsigned num_assumptions, expr * const * assumptions) {
lbool opt_solver::check_sat_core2(unsigned num_assumptions, expr * const * assumptions) {
TRACE("opt_verbose", {
tout << "context size: " << m_context.size() << "\n";
for (unsigned i = 0; i < m_context.size(); ++i) {

View file

@ -95,7 +95,7 @@ namespace opt {
void assert_expr_core(expr * t) override;
void push_core() override;
void pop_core(unsigned n) override;
lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) override;
lbool check_sat_core2(unsigned num_assumptions, expr * const * assumptions) override;
void get_unsat_core(expr_ref_vector & r) override;
void get_model_core(model_ref & _m) override;
proof * get_proof() override;

View file

@ -166,7 +166,7 @@ public:
(m.is_not(e, e) && is_uninterp_const(e));
}
lbool check_sat(unsigned sz, expr * const * assumptions) override {
lbool check_sat_core(unsigned sz, expr * const * assumptions) override {
m_solver.pop_to_base_level();
m_core.reset();
if (m_solver.inconsistent()) return l_false;

View file

@ -185,7 +185,7 @@ namespace smt {
m_context.pop(n);
}
lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) override {
lbool check_sat_core2(unsigned num_assumptions, expr * const * assumptions) override {
TRACE("solver_na2as", tout << "smt_solver::check_sat_core: " << num_assumptions << "\n";);
return m_context.check(num_assumptions, assumptions);
}

View file

@ -16,5 +16,7 @@ z3_add_component(solver
PYG_FILES
combined_solver_params.pyg
parallel_params.pyg
PYG_FILES
solver_params.pyg
)

View file

@ -218,7 +218,7 @@ public:
return l_undef;
}
lbool check_sat(unsigned num_assumptions, expr * const * assumptions) override {
lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) override {
m_check_sat_executed = true;
m_use_solver1_results = false;
@ -227,13 +227,13 @@ public:
m_ignore_solver1) {
// must use incremental solver
switch_inc_mode();
return m_solver2->check_sat(num_assumptions, assumptions);
return m_solver2->check_sat_core(num_assumptions, assumptions);
}
if (m_inc_mode) {
if (m_inc_timeout == UINT_MAX) {
IF_VERBOSE(PS_VB_LVL, verbose_stream() << "(combined-solver \"using solver 2 (without a timeout)\")\n";);
lbool r = m_solver2->check_sat(num_assumptions, assumptions);
lbool r = m_solver2->check_sat_core(num_assumptions, assumptions);
if (r != l_undef || !use_solver1_when_undef() || get_manager().canceled()) {
return r;
}
@ -244,7 +244,7 @@ public:
lbool r = l_undef;
try {
scoped_timer timer(m_inc_timeout, &eh);
r = m_solver2->check_sat(num_assumptions, assumptions);
r = m_solver2->check_sat_core(num_assumptions, assumptions);
}
catch (z3_exception&) {
if (!eh.m_canceled) {
@ -260,7 +260,7 @@ public:
IF_VERBOSE(PS_VB_LVL, verbose_stream() << "(combined-solver \"using solver 1\")\n";);
m_use_solver1_results = true;
return m_solver1->check_sat(num_assumptions, assumptions);
return m_solver1->check_sat_core(num_assumptions, assumptions);
}
void set_progress_callback(progress_callback * callback) override {

View file

@ -3,7 +3,7 @@ Copyright (c) 2011 Microsoft Corporation
Module Name:
solver.h
solver.cpp
Abstract:
@ -21,25 +21,25 @@ Notes:
#include "ast/ast_util.h"
#include "ast/ast_pp.h"
#include "ast/ast_pp_util.h"
#include "ast/display_dimacs.h"
#include "tactic/model_converter.h"
#include "solver/solver.h"
#include "solver/solver_params.hpp"
#include "model/model_evaluator.h"
unsigned solver::get_num_assertions() const {
NOT_IMPLEMENTED_YET();
UNREACHABLE();
return 0;
}
expr * solver::get_assertion(unsigned idx) const {
NOT_IMPLEMENTED_YET();
UNREACHABLE();
return nullptr;
}
std::ostream& solver::display(std::ostream & out, unsigned n, expr* const* assumptions) const {
expr_ref_vector fmls(get_manager());
stopwatch sw;
sw.start();
get_assertions(fmls);
ast_pp_util visitor(get_manager());
model_converter_ref mc = get_model_converter();
@ -57,6 +57,12 @@ std::ostream& solver::display(std::ostream & out, unsigned n, expr* const* assum
return out;
}
std::ostream& solver::display_dimacs(std::ostream& out) const {
expr_ref_vector fmls(get_manager());
get_assertions(fmls);
return ::display_dimacs(out, fmls);
}
void solver::get_assertions(expr_ref_vector& fmls) const {
unsigned sz = get_num_assertions();
for (unsigned i = 0; i < sz; ++i) {
@ -232,12 +238,16 @@ void solver::collect_param_descrs(param_descrs & r) {
void solver::reset_params(params_ref const & p) {
m_params = p;
m_enforce_model_conversion = m_params.get_bool("solver.enforce_model_conversion", false);
solver_params sp(m_params);
m_enforce_model_conversion = sp.enforce_model_conversion();
m_cancel_backup_file = sp.cancel_backup_file();
}
void solver::updt_params(params_ref const & p) {
m_params.copy(p);
m_enforce_model_conversion = m_params.get_bool("solver.enforce_model_conversion", false);
solver_params sp(m_params);
m_enforce_model_conversion = sp.enforce_model_conversion();
m_cancel_backup_file = sp.cancel_backup_file();
}
@ -309,3 +319,28 @@ expr_ref_vector solver::get_non_units(ast_manager& m) {
}
return result;
}
lbool solver::check_sat(unsigned num_assumptions, expr * const * assumptions) {
lbool r = l_undef;
try {
r = check_sat_core(num_assumptions, assumptions);
}
catch (...) {
if (get_manager().canceled()) {
dump_state(num_assumptions, assumptions);
}
throw;
}
if (r == l_undef && get_manager().canceled()) {
dump_state(num_assumptions, assumptions);
}
return r;
}
void solver::dump_state(unsigned sz, expr* const* assumptions) {
std::string file = m_cancel_backup_file.str();
if (file != "") {
std::ofstream ous(file);
display(ous, sz, assumptions);
}
}

View file

@ -44,8 +44,9 @@ public:
- results based on check_sat_result API
*/
class solver : public check_sat_result {
params_ref m_params;
bool m_enforce_model_conversion;
params_ref m_params;
bool m_enforce_model_conversion;
symbol m_cancel_backup_file;
public:
solver(): m_enforce_model_conversion(false) {}
~solver() override {}
@ -140,7 +141,8 @@ public:
If it is unsatisfiable, and unsat-core generation is enabled. Then, the unsat-core is a subset of these assumptions.
*/
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions) = 0;
lbool check_sat(unsigned num_assumptions, expr * const * assumptions);
lbool check_sat(expr_ref_vector const& asms) { return check_sat(asms.size(), asms.c_ptr()); }
@ -227,6 +229,11 @@ public:
*/
virtual std::ostream& display(std::ostream & out, unsigned n = 0, expr* const* assumptions = nullptr) const;
/**
\brief Display the content of this solver in DIMACS format
*/
std::ostream& display_dimacs(std::ostream & out) const;
/**
\brief expose model converter when solver produces partially reduced set of assertions.
*/
@ -249,14 +256,17 @@ public:
void disable_pop() { m_nopop = true; }
};
virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) = 0;
protected:
virtual lbool get_consequences_core(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences);
void dump_state(unsigned sz, expr* const* assumptions);
bool is_literal(ast_manager& m, expr* e);
};
typedef ref<solver> solver_ref;

View file

@ -61,10 +61,10 @@ struct append_assumptions {
}
};
lbool solver_na2as::check_sat(unsigned num_assumptions, expr * const * assumptions) {
lbool solver_na2as::check_sat_core(unsigned num_assumptions, expr * const * assumptions) {
append_assumptions app(m_assumptions, num_assumptions, assumptions);
TRACE("solver_na2as", display(tout););
return check_sat_core(m_assumptions.size(), m_assumptions.c_ptr());
return check_sat_core2(m_assumptions.size(), m_assumptions.c_ptr());
}
lbool solver_na2as::check_sat_cc(const expr_ref_vector &assumptions, vector<expr_ref_vector> const &clauses) {

View file

@ -35,10 +35,9 @@ public:
~solver_na2as() override;
void assert_expr_core2(expr * t, expr * a) override;
// virtual void assert_expr_core(expr * t) = 0;
// Subclasses of solver_na2as should redefine the following *_core methods instead of these ones.
lbool check_sat(unsigned num_assumptions, expr * const * assumptions) override;
lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) override;
lbool check_sat_cc(const expr_ref_vector &assumptions, vector<expr_ref_vector> const &clauses) override;
void push() override;
void pop(unsigned n) override;
@ -49,7 +48,7 @@ public:
lbool get_consequences(expr_ref_vector const& asms, expr_ref_vector const& vars, expr_ref_vector& consequences) override;
lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes) override;
protected:
virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) = 0;
virtual lbool check_sat_core2(unsigned num_assumptions, expr * const * assumptions) = 0;
virtual lbool check_sat_cc_core(const expr_ref_vector &assumptions, vector<expr_ref_vector> const &clauses) { NOT_IMPLEMENTED_YET(); }
virtual void push_core() = 0;
virtual void pop_core(unsigned n) = 0;

View file

@ -0,0 +1,8 @@
def_module_params('solver',
description='solver parameters',
export=True,
params=(('enforce_model_conversion', BOOL, False, "apply model transformation on new assertions"),
('cancel_backup_file', SYMBOL, '', "file to save partial search state if search is canceled"),
))

View file

@ -119,7 +119,7 @@ public:
}
}
lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) override {
lbool check_sat_core2(unsigned num_assumptions, expr * const * assumptions) override {
SASSERT(!m_pushed || get_scope_level() > 0);
m_proof.reset();
scoped_watch _t_(m_pool.m_check_watch);

View file

@ -62,7 +62,7 @@ public:
void push_core() override;
void pop_core(unsigned n) override;
lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) override;
lbool check_sat_core2(unsigned num_assumptions, expr * const * assumptions) override;
void collect_statistics(statistics & st) const override;
void get_unsat_core(expr_ref_vector & r) override;
@ -136,7 +136,7 @@ void tactic2solver::pop_core(unsigned n) {
m_result = nullptr;
}
lbool tactic2solver::check_sat_core(unsigned num_assumptions, expr * const * assumptions) {
lbool tactic2solver::check_sat_core2(unsigned num_assumptions, expr * const * assumptions) {
if (m_tactic.get() == nullptr)
return l_false;
ast_manager & m = m_assertions.m();

View file

@ -137,9 +137,9 @@ public:
}
}
lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) override {
lbool check_sat_core2(unsigned num_assumptions, expr * const * assumptions) override {
flush_assertions();
return m_solver->check_sat(num_assumptions, assumptions);
return m_solver->check_sat_core(num_assumptions, assumptions);
}
void updt_params(params_ref const & p) override { solver::updt_params(p); m_solver->updt_params(p); }

View file

@ -78,9 +78,9 @@ public:
m_rewriter.pop(n);
}
lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) override {
lbool check_sat_core2(unsigned num_assumptions, expr * const * assumptions) override {
m_solver->updt_params(get_params());
return m_solver->check_sat(num_assumptions, assumptions);
return m_solver->check_sat_core(num_assumptions, assumptions);
}
void updt_params(params_ref const & p) override { solver::updt_params(p); m_solver->updt_params(p); }

View file

@ -75,9 +75,9 @@ public:
m_rewriter.pop(n);
}
lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) override {
lbool check_sat_core2(unsigned num_assumptions, expr * const * assumptions) override {
flush_assertions();
return m_solver->check_sat(num_assumptions, assumptions);
return m_solver->check_sat_core(num_assumptions, assumptions);
}
void updt_params(params_ref const & p) override { solver::updt_params(p); m_rewriter.updt_params(p); m_solver->updt_params(p); }

View file

@ -20,6 +20,7 @@ Revision History:
#include "ast/ast_smt2_pp.h"
#include "ast/for_each_expr.h"
#include "ast/well_sorted.h"
#include "ast/display_dimacs.h"
#include "tactic/goal.h"
goal::precision goal::mk_union(precision p1, precision p2) {
@ -262,14 +263,14 @@ void goal::assert_expr(expr * f, expr_dependency * d) {
assert_expr(f, proofs_enabled() ? m().mk_asserted(f) : nullptr, d);
}
void goal::get_formulas(ptr_vector<expr> & result) {
void goal::get_formulas(ptr_vector<expr> & result) const {
unsigned sz = size();
for (unsigned i = 0; i < sz; i++) {
result.push_back(form(i));
}
}
void goal::get_formulas(expr_ref_vector & result) {
void goal::get_formulas(expr_ref_vector & result) const {
unsigned sz = size();
for (unsigned i = 0; i < sz; i++) {
result.push_back(form(i));
@ -434,63 +435,9 @@ void goal::display_ll(std::ostream & out) const {
\brief Assumes that the formula is already in CNF.
*/
void goal::display_dimacs(std::ostream & out) const {
unsigned_vector expr2var;
ptr_vector<expr> exprs;
unsigned num_vars = 0;
unsigned num_cls = size();
for (unsigned i = 0; i < num_cls; i++) {
expr * f = form(i);
unsigned num_lits;
expr * const * lits;
if (m().is_or(f)) {
num_lits = to_app(f)->get_num_args();
lits = to_app(f)->get_args();
}
else {
num_lits = 1;
lits = &f;
}
for (unsigned j = 0; j < num_lits; j++) {
expr * l = lits[j];
if (m().is_not(l))
l = to_app(l)->get_arg(0);
if (expr2var.get(l->get_id(), UINT_MAX) == UINT_MAX) {
num_vars++;
expr2var.setx(l->get_id(), num_vars, UINT_MAX);
exprs.setx(l->get_id(), l, nullptr);
}
}
}
out << "p cnf " << num_vars << " " << num_cls << "\n";
for (unsigned i = 0; i < num_cls; i++) {
expr * f = form(i);
unsigned num_lits;
expr * const * lits;
if (m().is_or(f)) {
num_lits = to_app(f)->get_num_args();
lits = to_app(f)->get_args();
}
else {
num_lits = 1;
lits = &f;
}
for (unsigned j = 0; j < num_lits; j++) {
expr * l = lits[j];
if (m().is_not(l)) {
out << "-";
l = to_app(l)->get_arg(0);
}
SASSERT(exprs[l->get_id()]);
out << expr2var[l->get_id()] << " ";
}
out << "0\n";
}
for (expr* e : exprs) {
if (e && is_app(e)) {
symbol const& n = to_app(e)->get_decl()->get_name();
out << "c " << expr2var[e->get_id()] << " " << n << "\n";
}
}
expr_ref_vector fmls(m());
get_formulas(fmls);
::display_dimacs(out, fmls);
}
unsigned goal::num_exprs() const {

View file

@ -126,8 +126,8 @@ public:
void update(unsigned i, expr * f, proof * pr = nullptr, expr_dependency * dep = nullptr);
void get_formulas(ptr_vector<expr> & result);
void get_formulas(expr_ref_vector & result);
void get_formulas(ptr_vector<expr> & result) const;
void get_formulas(expr_ref_vector & result) const;
void elim_true();
void elim_redundancies();

View file

@ -32,6 +32,7 @@ Revision History:
#include "util/debug.h"
#include "util/trace.h"
#include "util/tptr.h"
#include "util/util.h"
#ifdef Z3DEBUG
#include "util/hashtable.h"
#endif