mirror of
https://github.com/Z3Prover/z3
synced 2025-04-07 09:55:19 +00:00
checkpoint
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
3e6bddbad1
commit
6195ed7c66
|
@ -18,6 +18,7 @@ def init_project_def():
|
||||||
add_lib('subpaving', ['interval'], 'math/subpaving')
|
add_lib('subpaving', ['interval'], 'math/subpaving')
|
||||||
add_lib('ast', ['util', 'polynomial'])
|
add_lib('ast', ['util', 'polynomial'])
|
||||||
add_lib('rewriter', ['ast', 'polynomial'], 'ast/rewriter')
|
add_lib('rewriter', ['ast', 'polynomial'], 'ast/rewriter')
|
||||||
|
add_lib('normal_forms', ['rewriter'], 'ast/normal_forms')
|
||||||
add_lib('model', ['rewriter'])
|
add_lib('model', ['rewriter'])
|
||||||
add_lib('tactic', ['ast', 'model'])
|
add_lib('tactic', ['ast', 'model'])
|
||||||
add_lib('substitution', ['ast'], 'ast/substitution')
|
add_lib('substitution', ['ast'], 'ast/substitution')
|
||||||
|
@ -30,7 +31,6 @@ def init_project_def():
|
||||||
# Simplifier module will be deleted in the future.
|
# Simplifier module will be deleted in the future.
|
||||||
# It has been replaced with rewriter module.
|
# It has been replaced with rewriter module.
|
||||||
add_lib('simplifier', ['rewriter', 'front_end_params'], 'ast/simplifier')
|
add_lib('simplifier', ['rewriter', 'front_end_params'], 'ast/simplifier')
|
||||||
add_lib('normal_forms', ['rewriter', 'front_end_params'], 'ast/normal_forms')
|
|
||||||
add_lib('core_tactics', ['tactic', 'normal_forms'], 'tactic/core')
|
add_lib('core_tactics', ['tactic', 'normal_forms'], 'tactic/core')
|
||||||
add_lib('sat_tactic', ['tactic', 'sat'], 'sat/tactic')
|
add_lib('sat_tactic', ['tactic', 'sat'], 'sat/tactic')
|
||||||
add_lib('arith_tactics', ['core_tactics', 'sat'], 'tactic/arith')
|
add_lib('arith_tactics', ['core_tactics', 'sat'], 'tactic/arith')
|
||||||
|
|
|
@ -17,6 +17,7 @@ Revision History:
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#include"cnf.h"
|
#include"cnf.h"
|
||||||
|
#include"cnf_params.hpp"
|
||||||
#include"var_subst.h"
|
#include"var_subst.h"
|
||||||
#include"ast_util.h"
|
#include"ast_util.h"
|
||||||
#include"ast_pp.h"
|
#include"ast_pp.h"
|
||||||
|
@ -159,7 +160,7 @@ inline bool cnf::is_too_expensive(approx_nat approx_result_size, ptr_buffer<expr
|
||||||
// (OR A (AND B C)) is always considered cheap.
|
// (OR A (AND B C)) is always considered cheap.
|
||||||
if (args.size() == 2 && (!m_manager.is_and(args[0]) || !m_manager.is_and(args[1])))
|
if (args.size() == 2 && (!m_manager.is_and(args[0]) || !m_manager.is_and(args[1])))
|
||||||
return false;
|
return false;
|
||||||
return !(approx_result_size < m_params.m_cnf_factor);
|
return !(approx_result_size < m_cnf_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -265,13 +266,13 @@ void cnf::reduce1_or(app * n, bool in_q) {
|
||||||
get_args(n, in_q, new_args, new_arg_prs);
|
get_args(n, in_q, new_args, new_arg_prs);
|
||||||
expr * r;
|
expr * r;
|
||||||
proof * pr = 0;
|
proof * pr = 0;
|
||||||
if (in_q || m_params.m_cnf_mode == CNF_OPPORTUNISTIC || m_params.m_cnf_mode == CNF_FULL) {
|
if (in_q || m_cnf_mode == CNF_OPPORTUNISTIC || m_cnf_mode == CNF_FULL) {
|
||||||
ptr_buffer<expr> f_args;
|
ptr_buffer<expr> f_args;
|
||||||
flat_args(n->get_decl(), new_args, f_args);
|
flat_args(n->get_decl(), new_args, f_args);
|
||||||
TRACE("cnf_or", for (unsigned i = 0; i < f_args.size(); i++) tout << mk_pp(f_args[i], m_manager) << "\n";);
|
TRACE("cnf_or", for (unsigned i = 0; i < f_args.size(); i++) tout << mk_pp(f_args[i], m_manager) << "\n";);
|
||||||
approx_nat result_size = approx_result_size_for_disj(f_args);
|
approx_nat result_size = approx_result_size_for_disj(f_args);
|
||||||
TRACE("cnf_or", tout << mk_pp(n, m_manager) << "\napprox. result: " << result_size << "\n";);
|
TRACE("cnf_or", tout << mk_pp(n, m_manager) << "\napprox. result: " << result_size << "\n";);
|
||||||
if (m_params.m_cnf_mode != CNF_OPPORTUNISTIC || result_size < m_params.m_cnf_factor) {
|
if (m_cnf_mode != CNF_OPPORTUNISTIC || result_size < m_cnf_factor) {
|
||||||
expr_ref_buffer cheap_args(m_manager);
|
expr_ref_buffer cheap_args(m_manager);
|
||||||
proof_ref_buffer cheap_args_pr(m_manager);
|
proof_ref_buffer cheap_args_pr(m_manager);
|
||||||
if (is_too_expensive(result_size, f_args)) {
|
if (is_too_expensive(result_size, f_args)) {
|
||||||
|
@ -354,7 +355,7 @@ void cnf::reduce1_and(app * n, bool in_q) {
|
||||||
get_args(n, in_q, new_args, new_arg_prs);
|
get_args(n, in_q, new_args, new_arg_prs);
|
||||||
app * r;
|
app * r;
|
||||||
proof * pr = 0;
|
proof * pr = 0;
|
||||||
if (in_q || m_params.m_cnf_mode == CNF_OPPORTUNISTIC || m_params.m_cnf_mode == CNF_FULL) {
|
if (in_q || m_cnf_mode == CNF_OPPORTUNISTIC || m_cnf_mode == CNF_FULL) {
|
||||||
ptr_buffer<expr> f_args;
|
ptr_buffer<expr> f_args;
|
||||||
flat_args(n->get_decl(), new_args, f_args);
|
flat_args(n->get_decl(), new_args, f_args);
|
||||||
r = m_manager.mk_and(f_args.size(), f_args.c_ptr());
|
r = m_manager.mk_and(f_args.size(), f_args.c_ptr());
|
||||||
|
@ -379,7 +380,7 @@ void cnf::reduce1_label(app * n, bool in_q) {
|
||||||
expr * new_arg;
|
expr * new_arg;
|
||||||
proof * new_arg_pr;
|
proof * new_arg_pr;
|
||||||
get_cached(n->get_arg(0), true, new_arg, new_arg_pr);
|
get_cached(n->get_arg(0), true, new_arg, new_arg_pr);
|
||||||
if (in_q || m_params.m_cnf_mode == CNF_FULL) {
|
if (in_q || m_cnf_mode == CNF_FULL) {
|
||||||
// TODO: in the current implementation, labels are removed during CNF translation.
|
// TODO: in the current implementation, labels are removed during CNF translation.
|
||||||
// This is satisfactory for Boogie, since it does not use labels inside quantifiers,
|
// This is satisfactory for Boogie, since it does not use labels inside quantifiers,
|
||||||
// and we only need CNF_QUANT for Superposition Calculus.
|
// and we only need CNF_QUANT for Superposition Calculus.
|
||||||
|
@ -439,8 +440,7 @@ void cnf::reduce1_quantifier(quantifier * q, bool in_q) {
|
||||||
TRACE("cnf_quant", tout << mk_pp(q, m_manager) << "\n" << mk_pp(r, m_manager) << "\n";);
|
TRACE("cnf_quant", tout << mk_pp(q, m_manager) << "\n" << mk_pp(r, m_manager) << "\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
cnf::cnf(ast_manager & m, defined_names & n, cnf_params & params):
|
cnf::cnf(ast_manager & m, defined_names & n, params_ref const & params):
|
||||||
m_params(params),
|
|
||||||
m_manager(m),
|
m_manager(m),
|
||||||
m_defined_names(n),
|
m_defined_names(n),
|
||||||
m_pull(m),
|
m_pull(m),
|
||||||
|
@ -448,6 +448,9 @@ cnf::cnf(ast_manager & m, defined_names & n, cnf_params & params):
|
||||||
m_todo_defs(m),
|
m_todo_defs(m),
|
||||||
m_todo_proofs(m),
|
m_todo_proofs(m),
|
||||||
m_coarse_proofs(m) {
|
m_coarse_proofs(m) {
|
||||||
|
cnf_params p(params);
|
||||||
|
m_cnf_mode = static_cast<cnf_mode>(p.mode());
|
||||||
|
m_cnf_factor = p.factor();
|
||||||
}
|
}
|
||||||
|
|
||||||
cnf::~cnf() {
|
cnf::~cnf() {
|
||||||
|
@ -488,7 +491,7 @@ void cnf::reduce(expr * n, expr_ref & r, proof_ref & pr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void cnf::operator()(expr * n, expr_ref_vector & new_defs, proof_ref_vector & new_def_proofs, expr_ref & r, proof_ref & pr) {
|
void cnf::operator()(expr * n, expr_ref_vector & new_defs, proof_ref_vector & new_def_proofs, expr_ref & r, proof_ref & pr) {
|
||||||
if (m_params.m_cnf_mode == CNF_DISABLED) {
|
if (m_cnf_mode == CNF_DISABLED) {
|
||||||
r = n;
|
r = n;
|
||||||
pr = m_manager.mk_reflexivity(n);
|
pr = m_manager.mk_reflexivity(n);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -19,11 +19,29 @@ Revision History:
|
||||||
#ifndef _CNF_H_
|
#ifndef _CNF_H_
|
||||||
#define _CNF_H_
|
#define _CNF_H_
|
||||||
|
|
||||||
#include"cnf_params.h"
|
|
||||||
#include"pull_quant.h"
|
#include"pull_quant.h"
|
||||||
#include"nnf.h"
|
#include"nnf.h"
|
||||||
#include"approx_nat.h"
|
#include"approx_nat.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief CNF translation mode. The cheapest mode is CNF_QUANT, and
|
||||||
|
the most expensive is CNF_FULL.
|
||||||
|
*/
|
||||||
|
enum cnf_mode {
|
||||||
|
CNF_DISABLED, /* CNF translator is disabled.
|
||||||
|
This mode is sufficient when using E-matching.
|
||||||
|
*/
|
||||||
|
CNF_QUANT, /* A subformula is put into CNF if it is inside of a
|
||||||
|
quantifier.
|
||||||
|
|
||||||
|
This mode is sufficient when using Superposition
|
||||||
|
Calculus.
|
||||||
|
*/
|
||||||
|
CNF_OPPORTUNISTIC, /* a subformula is also put in CNF if it is cheap. */
|
||||||
|
CNF_FULL /* Everything is put into CNF, new names are introduced
|
||||||
|
if it is too expensive. */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Entry into the todo list of the CNF translator. It is also used as the key in the CNF cache.
|
\brief Entry into the todo list of the CNF translator. It is also used as the key in the CNF cache.
|
||||||
*/
|
*/
|
||||||
|
@ -71,7 +89,6 @@ public:
|
||||||
*/
|
*/
|
||||||
class cnf {
|
class cnf {
|
||||||
typedef std::pair<expr *, bool> expr_bool_pair;
|
typedef std::pair<expr *, bool> expr_bool_pair;
|
||||||
cnf_params & m_params;
|
|
||||||
ast_manager & m_manager;
|
ast_manager & m_manager;
|
||||||
defined_names & m_defined_names;
|
defined_names & m_defined_names;
|
||||||
pull_quant m_pull;
|
pull_quant m_pull;
|
||||||
|
@ -83,6 +100,9 @@ class cnf {
|
||||||
ptr_vector<proof> m_result_def_proofs;
|
ptr_vector<proof> m_result_def_proofs;
|
||||||
proof_ref_vector m_coarse_proofs;
|
proof_ref_vector m_coarse_proofs;
|
||||||
|
|
||||||
|
cnf_mode m_cnf_mode;
|
||||||
|
unsigned m_cnf_factor;
|
||||||
|
|
||||||
void cache_result(expr * e, bool in_q, expr * r, proof * pr);
|
void cache_result(expr * e, bool in_q, expr * r, proof * pr);
|
||||||
void get_cached(expr * n, bool in_q, expr * & r, proof * & pr) const { m_cache.get(cnf_entry(n, true, in_q), r, pr); }
|
void get_cached(expr * n, bool in_q, expr * & r, proof * & pr) const { m_cache.get(cnf_entry(n, true, in_q), r, pr); }
|
||||||
bool is_cached(expr * n, bool in_q) const { return m_cache.contains(cnf_entry(n, true, in_q)); }
|
bool is_cached(expr * n, bool in_q) const { return m_cache.contains(cnf_entry(n, true, in_q)); }
|
||||||
|
@ -105,7 +125,7 @@ class cnf {
|
||||||
|
|
||||||
void reduce(expr * n, expr_ref & r, proof_ref & pr);
|
void reduce(expr * n, expr_ref & r, proof_ref & pr);
|
||||||
public:
|
public:
|
||||||
cnf(ast_manager & m, defined_names & n, cnf_params & params);
|
cnf(ast_manager & m, defined_names & n, params_ref const & p = params_ref());
|
||||||
~cnf();
|
~cnf();
|
||||||
void operator()(expr * n, // [IN] expression that should be put into CNF
|
void operator()(expr * n, // [IN] expression that should be put into CNF
|
||||||
expr_ref_vector & new_defs, // [OUT] new definitions
|
expr_ref_vector & new_defs, // [OUT] new definitions
|
||||||
|
|
4
src/ast/normal_forms/cnf_params.pyg
Normal file
4
src/ast/normal_forms/cnf_params.pyg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
def_module_params('cnf',
|
||||||
|
export=True,
|
||||||
|
params=(('mode', UINT, 0, 'CNF translation mode: 0 - disabled, 1 - quantifiers in CNF, 2 - opportunistic, 3 - full'),
|
||||||
|
('factor', UINT, 4, 'the maximum number of clauses that can be created when converting a subformula')))
|
|
@ -18,6 +18,7 @@ Notes:
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
#include"nnf.h"
|
#include"nnf.h"
|
||||||
|
#include"nnf_params.hpp"
|
||||||
#include"warning.h"
|
#include"warning.h"
|
||||||
#include"used_vars.h"
|
#include"used_vars.h"
|
||||||
#include"well_sorted.h"
|
#include"well_sorted.h"
|
||||||
|
@ -29,6 +30,40 @@ Notes:
|
||||||
|
|
||||||
#include"ast_smt2_pp.h"
|
#include"ast_smt2_pp.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief NNF translation mode. The cheapest mode is NNF_SKOLEM, and
|
||||||
|
the most expensive is NNF_FULL.
|
||||||
|
*/
|
||||||
|
enum nnf_mode {
|
||||||
|
NNF_SKOLEM, /* A subformula is put into NNF only if it contains
|
||||||
|
quantifiers or labels. The result of the
|
||||||
|
transformation will be in skolem normal form.
|
||||||
|
If a formula is too expensive to be put into NNF,
|
||||||
|
then nested quantifiers and labels are renamed.
|
||||||
|
|
||||||
|
This mode is sufficient when using E-matching.
|
||||||
|
*/
|
||||||
|
NNF_QUANT, /* A subformula is put into NNF if it contains
|
||||||
|
quantifiers, labels, or is in the scope of a
|
||||||
|
quantifier. The result of the transformation will be
|
||||||
|
in skolem normal form, and the body of quantifiers
|
||||||
|
will be in NNF. If a ground formula is too expensive to
|
||||||
|
be put into NNF, then nested quantifiers and labels
|
||||||
|
are renamed.
|
||||||
|
|
||||||
|
This mode is sufficient when using Superposition
|
||||||
|
Calculus.
|
||||||
|
|
||||||
|
Remark: If the problem does not contain quantifiers,
|
||||||
|
then NNF_QUANT is identical to NNF_SKOLEM.
|
||||||
|
*/
|
||||||
|
NNF_OPPORTUNISTIC, /* Similar to NNF_QUANT, but a subformula is
|
||||||
|
also put into NNF, if it is
|
||||||
|
cheap. Otherwise, the nested quantifiers and
|
||||||
|
labels are renamed. */
|
||||||
|
NNF_FULL /* Everything is put into NNF. */
|
||||||
|
};
|
||||||
|
|
||||||
class skolemizer {
|
class skolemizer {
|
||||||
typedef act_cache cache;
|
typedef act_cache cache;
|
||||||
|
|
||||||
|
@ -113,20 +148,16 @@ class skolemizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
skolemizer(ast_manager & m, params_ref const & p):
|
skolemizer(ast_manager & m):
|
||||||
m_manager(m),
|
m_manager(m),
|
||||||
m_sk_hack("sk_hack"),
|
m_sk_hack("sk_hack"),
|
||||||
|
m_sk_hack_enabled(false),
|
||||||
m_cache(m),
|
m_cache(m),
|
||||||
m_cache_pr(m) {
|
m_cache_pr(m) {
|
||||||
updt_params(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updt_params(params_ref const & p) {
|
void set_sk_hack(bool f) {
|
||||||
m_sk_hack_enabled = p.get_bool("sk_hack", false);
|
m_sk_hack_enabled = f;
|
||||||
}
|
|
||||||
|
|
||||||
static void get_param_descrs(param_descrs & r) {
|
|
||||||
r.insert("sk_hack", CPK_BOOL, "(default: false) hack for VCC");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_manager & m() const { return m_manager; }
|
ast_manager & m() const { return m_manager; }
|
||||||
|
@ -220,8 +251,6 @@ struct nnf::imp {
|
||||||
name_exprs * m_name_nested_formulas;
|
name_exprs * m_name_nested_formulas;
|
||||||
name_exprs * m_name_quant;
|
name_exprs * m_name_quant;
|
||||||
|
|
||||||
symbol m_skolem;
|
|
||||||
|
|
||||||
volatile bool m_cancel;
|
volatile bool m_cancel;
|
||||||
unsigned long long m_max_memory; // in bytes
|
unsigned long long m_max_memory; // in bytes
|
||||||
|
|
||||||
|
@ -231,10 +260,9 @@ struct nnf::imp {
|
||||||
m_todo_defs(m),
|
m_todo_defs(m),
|
||||||
m_todo_proofs(m),
|
m_todo_proofs(m),
|
||||||
m_result_pr_stack(m),
|
m_result_pr_stack(m),
|
||||||
m_skolemizer(m, p),
|
m_skolemizer(m),
|
||||||
m_skolem("skolem"),
|
|
||||||
m_cancel(false) {
|
m_cancel(false) {
|
||||||
updt_local_params(p);
|
updt_params(p);
|
||||||
for (unsigned i = 0; i < 4; i++) {
|
for (unsigned i = 0; i < 4; i++) {
|
||||||
m_cache[i] = alloc(act_cache, m);
|
m_cache[i] = alloc(act_cache, m);
|
||||||
if (m.proofs_enabled())
|
if (m.proofs_enabled())
|
||||||
|
@ -258,14 +286,10 @@ struct nnf::imp {
|
||||||
del_name_exprs(m_name_quant);
|
del_name_exprs(m_name_quant);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updt_params(params_ref const & p) {
|
void updt_params(params_ref const & _p) {
|
||||||
updt_local_params(p);
|
nnf_params p(_p);
|
||||||
m_skolemizer.updt_params(p);
|
symbol mode_sym = p.mode();
|
||||||
}
|
if (mode_sym == "skolem")
|
||||||
|
|
||||||
void updt_local_params(params_ref const & p) {
|
|
||||||
symbol mode_sym = p.get_sym("mode", m_skolem);
|
|
||||||
if (mode_sym == m_skolem)
|
|
||||||
m_mode = NNF_SKOLEM;
|
m_mode = NNF_SKOLEM;
|
||||||
else if (mode_sym == "full")
|
else if (mode_sym == "full")
|
||||||
m_mode = NNF_FULL;
|
m_mode = NNF_FULL;
|
||||||
|
@ -273,23 +297,17 @@ struct nnf::imp {
|
||||||
m_mode = NNF_QUANT;
|
m_mode = NNF_QUANT;
|
||||||
else
|
else
|
||||||
throw nnf_params_exception("invalid NNF mode");
|
throw nnf_params_exception("invalid NNF mode");
|
||||||
|
|
||||||
|
TRACE("nnf", tout << "nnf-mode: " << m_mode << " " << mode_sym << "\n" << _p << "\n";);
|
||||||
|
|
||||||
TRACE("nnf", tout << "nnf-mode: " << m_mode << " " << mode_sym << "\n" << p << "\n";);
|
m_ignore_labels = p.ignore_labels();
|
||||||
|
m_skolemize = p.skolemize();
|
||||||
m_ignore_labels = p.get_bool("ignore_labels", false);
|
m_max_memory = megabytes_to_bytes(p.max_memory());
|
||||||
m_skolemize = p.get_bool("skolemize", true);
|
m_skolemizer.set_sk_hack(p.sk_hack());
|
||||||
m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_param_descrs(param_descrs & r) {
|
static void get_param_descrs(param_descrs & r) {
|
||||||
insert_max_memory(r);
|
nnf_params::collect_param_descrs(r);
|
||||||
r.insert("mode", CPK_SYMBOL,
|
|
||||||
"(default: skolem) NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full");
|
|
||||||
r.insert("ignore_labels", CPK_BOOL,
|
|
||||||
"(default: false) remove/ignore labels in the input formula, this option is ignored if proofs are enabled");
|
|
||||||
r.insert("skolemize", CPK_BOOL,
|
|
||||||
"(default: true) skolemize (existential force) quantifiers");
|
|
||||||
skolemizer::get_param_descrs(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
|
@ -881,21 +899,6 @@ nnf::nnf(ast_manager & m, defined_names & n, params_ref const & p) {
|
||||||
m_imp = alloc(imp, m, n, p);
|
m_imp = alloc(imp, m, n, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
nnf::nnf(ast_manager & m, defined_names & n, nnf_params & np) {
|
|
||||||
params_ref p;
|
|
||||||
if (np.m_nnf_mode == NNF_FULL)
|
|
||||||
p.set_sym("mode", symbol("full"));
|
|
||||||
else if (np.m_nnf_mode == NNF_QUANT)
|
|
||||||
p.set_sym("mode", symbol("quantifiers"));
|
|
||||||
|
|
||||||
if (np.m_nnf_ignore_labels)
|
|
||||||
p.set_bool("ignore_labels", true);
|
|
||||||
|
|
||||||
if (np.m_nnf_sk_hack)
|
|
||||||
p.set_bool("sk_hack", true);
|
|
||||||
m_imp = alloc(imp, m, n, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
nnf::~nnf() {
|
nnf::~nnf() {
|
||||||
dealloc(m_imp);
|
dealloc(m_imp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ Notes:
|
||||||
#define _NNF_H_
|
#define _NNF_H_
|
||||||
|
|
||||||
#include"ast.h"
|
#include"ast.h"
|
||||||
#include"nnf_params.h"
|
|
||||||
#include"params.h"
|
#include"params.h"
|
||||||
#include"defined_names.h"
|
#include"defined_names.h"
|
||||||
|
|
||||||
|
@ -30,7 +29,6 @@ class nnf {
|
||||||
imp * m_imp;
|
imp * m_imp;
|
||||||
public:
|
public:
|
||||||
nnf(ast_manager & m, defined_names & n, params_ref const & p = params_ref());
|
nnf(ast_manager & m, defined_names & n, params_ref const & p = params_ref());
|
||||||
nnf(ast_manager & m, defined_names & n, nnf_params & params); // for backward compatibility
|
|
||||||
~nnf();
|
~nnf();
|
||||||
|
|
||||||
void operator()(expr * n, // [IN] expression that should be put into NNF
|
void operator()(expr * n, // [IN] expression that should be put into NNF
|
||||||
|
|
8
src/ast/normal_forms/nnf_params.pyg
Normal file
8
src/ast/normal_forms/nnf_params.pyg
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
def_module_params('nnf',
|
||||||
|
export=True,
|
||||||
|
params=(max_memory_param(),
|
||||||
|
('sk_hack', BOOL, False, 'hack for VCC'),
|
||||||
|
('mode', SYMBOL, 'skolem',
|
||||||
|
'NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full'),
|
||||||
|
('ignore_labels', BOOL, False, 'remove/ignore labels in the input formula, this option is ignored if proofs are enabled'),
|
||||||
|
('skolemize', BOOL, True, 'skolemize (existential force) quantifiers')))
|
|
@ -1,26 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2006 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
cnf_params.cpp
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
<abstract>
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2008-01-23.
|
|
||||||
|
|
||||||
Revision History:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
|
|
||||||
#include"cnf_params.h"
|
|
||||||
|
|
||||||
void cnf_params::register_params(ini_params & p) {
|
|
||||||
p.register_unsigned_param("cnf_factor", m_cnf_factor, "the maximum number of clauses that can be created when converting a subformula");
|
|
||||||
p.register_int_param("cnf_mode", 0, 3, reinterpret_cast<int&>(m_cnf_mode), "CNF translation mode: 0 - disabled, 1 - quantifiers in CNF, 2 - 0 + opportunistic, 3 - full");
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2006 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
cnf_params.h
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
<abstract>
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2008-01-23.
|
|
||||||
|
|
||||||
Revision History:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
#ifndef _CNF_PARAMS_H_
|
|
||||||
#define _CNF_PARAMS_H_
|
|
||||||
|
|
||||||
#include"ini_file.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief CNF translation mode. The cheapest mode is CNF_QUANT, and
|
|
||||||
the most expensive is CNF_FULL.
|
|
||||||
*/
|
|
||||||
enum cnf_mode {
|
|
||||||
CNF_DISABLED, /* CNF translator is disabled.
|
|
||||||
This mode is sufficient when using E-matching.
|
|
||||||
*/
|
|
||||||
CNF_QUANT, /* A subformula is put into CNF if it is inside of a
|
|
||||||
quantifier.
|
|
||||||
|
|
||||||
This mode is sufficient when using Superposition
|
|
||||||
Calculus.
|
|
||||||
*/
|
|
||||||
CNF_OPPORTUNISTIC, /* a subformula is also put in CNF if it is cheap. */
|
|
||||||
CNF_FULL /* Everything is put into CNF, new names are introduced
|
|
||||||
if it is too expensive. */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cnf_params {
|
|
||||||
cnf_mode m_cnf_mode;
|
|
||||||
unsigned m_cnf_factor;
|
|
||||||
cnf_params():
|
|
||||||
m_cnf_mode(CNF_DISABLED),
|
|
||||||
m_cnf_factor(4) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_params(ini_params & p);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _CNF_PARAMS_H_ */
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2006 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
nnf_params.cpp
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
<abstract>
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2008-01-14.
|
|
||||||
|
|
||||||
Revision History:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
#include"nnf_params.h"
|
|
||||||
|
|
||||||
void nnf_params::register_params(ini_params & p) {
|
|
||||||
p.register_unsigned_param("nnf_factor", m_nnf_factor, "the maximum growth factor during NNF translation (auxiliary definitions are introduced if the threshold is reached)");
|
|
||||||
p.register_int_param("nnf_mode", 0, 3, reinterpret_cast<int&>(m_nnf_mode), "NNF translation mode: 0 - skolem normal form, 1 - 0 + quantifiers in NNF, 2 - 1 + opportunistic, 3 - full");
|
|
||||||
p.register_bool_param("nnf_ignore_labels", m_nnf_ignore_labels, "remove/ignore labels in the input formula, this option is ignored if proofs are enabled");
|
|
||||||
p.register_bool_param("nnf_sk_hack", m_nnf_sk_hack, "hack for VCC");
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2006 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
nnf_params.h
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
<abstract>
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2008-01-14.
|
|
||||||
|
|
||||||
Revision History:
|
|
||||||
|
|
||||||
--*/
|
|
||||||
#ifndef _NNF_PARAMS_H_
|
|
||||||
#define _NNF_PARAMS_H_
|
|
||||||
|
|
||||||
#include"ini_file.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief NNF translation mode. The cheapest mode is NNF_SKOLEM, and
|
|
||||||
the most expensive is NNF_FULL.
|
|
||||||
*/
|
|
||||||
enum nnf_mode {
|
|
||||||
NNF_SKOLEM, /* A subformula is put into NNF only if it contains
|
|
||||||
quantifiers or labels. The result of the
|
|
||||||
transformation will be in skolem normal form.
|
|
||||||
If a formula is too expensive to be put into NNF,
|
|
||||||
then nested quantifiers and labels are renamed.
|
|
||||||
|
|
||||||
This mode is sufficient when using E-matching.
|
|
||||||
*/
|
|
||||||
NNF_QUANT, /* A subformula is put into NNF if it contains
|
|
||||||
quantifiers, labels, or is in the scope of a
|
|
||||||
quantifier. The result of the transformation will be
|
|
||||||
in skolem normal form, and the body of quantifiers
|
|
||||||
will be in NNF. If a ground formula is too expensive to
|
|
||||||
be put into NNF, then nested quantifiers and labels
|
|
||||||
are renamed.
|
|
||||||
|
|
||||||
This mode is sufficient when using Superposition
|
|
||||||
Calculus.
|
|
||||||
|
|
||||||
Remark: If the problem does not contain quantifiers,
|
|
||||||
then NNF_QUANT is identical to NNF_SKOLEM.
|
|
||||||
*/
|
|
||||||
NNF_OPPORTUNISTIC, /* Similar to NNF_QUANT, but a subformula is
|
|
||||||
also put into NNF, if it is
|
|
||||||
cheap. Otherwise, the nested quantifiers and
|
|
||||||
labels are renamed. */
|
|
||||||
NNF_FULL /* Everything is put into NNF. */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nnf_params {
|
|
||||||
nnf_mode m_nnf_mode;
|
|
||||||
unsigned m_nnf_factor;
|
|
||||||
bool m_nnf_ignore_labels;
|
|
||||||
bool m_nnf_sk_hack;
|
|
||||||
nnf_params():
|
|
||||||
m_nnf_mode(NNF_SKOLEM),
|
|
||||||
m_nnf_factor(4),
|
|
||||||
m_nnf_ignore_labels(false),
|
|
||||||
m_nnf_sk_hack(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_params(ini_params & p);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _NNF_PARAMS_H_ */
|
|
||||||
|
|
|
@ -19,8 +19,6 @@ Revision History:
|
||||||
#ifndef _PREPROCESSOR_PARAMS_H_
|
#ifndef _PREPROCESSOR_PARAMS_H_
|
||||||
#define _PREPROCESSOR_PARAMS_H_
|
#define _PREPROCESSOR_PARAMS_H_
|
||||||
|
|
||||||
#include"nnf_params.h"
|
|
||||||
#include"cnf_params.h"
|
|
||||||
#include"pattern_inference_params.h"
|
#include"pattern_inference_params.h"
|
||||||
#include"bit_blaster_params.h"
|
#include"bit_blaster_params.h"
|
||||||
#include"bv_simplifier_params.h"
|
#include"bv_simplifier_params.h"
|
||||||
|
@ -31,7 +29,7 @@ enum lift_ite_kind {
|
||||||
LI_FULL
|
LI_FULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct preprocessor_params : public nnf_params, public cnf_params, public pattern_inference_params,
|
struct preprocessor_params : public pattern_inference_params,
|
||||||
public bit_blaster_params, public bv_simplifier_params {
|
public bit_blaster_params, public bv_simplifier_params {
|
||||||
lift_ite_kind m_lift_ite;
|
lift_ite_kind m_lift_ite;
|
||||||
lift_ite_kind m_ng_lift_ite; // lift ite for non ground terms
|
lift_ite_kind m_ng_lift_ite; // lift ite for non ground terms
|
||||||
|
@ -79,8 +77,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_params(ini_params & p) {
|
void register_params(ini_params & p) {
|
||||||
nnf_params::register_params(p);
|
|
||||||
cnf_params::register_params(p);
|
|
||||||
pattern_inference_params::register_params(p);
|
pattern_inference_params::register_params(p);
|
||||||
bit_blaster_params::register_params(p);
|
bit_blaster_params::register_params(p);
|
||||||
bv_simplifier_params::register_params(p);
|
bv_simplifier_params::register_params(p);
|
||||||
|
|
|
@ -31,7 +31,6 @@ void smt_params::register_params(ini_params & p) {
|
||||||
p.register_bool_param("display_proof", m_display_proof);
|
p.register_bool_param("display_proof", m_display_proof);
|
||||||
p.register_bool_param("display_dot_proof", m_display_dot_proof);
|
p.register_bool_param("display_dot_proof", m_display_dot_proof);
|
||||||
p.register_bool_param("display_unsat_core", m_display_unsat_core);
|
p.register_bool_param("display_unsat_core", m_display_unsat_core);
|
||||||
p.register_bool_param("internalizer_nnf", m_internalizer_nnf);
|
|
||||||
p.register_bool_param("eq_propagation", m_eq_propagation);
|
p.register_bool_param("eq_propagation", m_eq_propagation);
|
||||||
p.register_bool_param("bin_clauses", m_binary_clause_opt);
|
p.register_bool_param("bin_clauses", m_binary_clause_opt);
|
||||||
p.register_unsigned_param("relevancy", m_relevancy_lvl, "relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant", true);
|
p.register_unsigned_param("relevancy", m_relevancy_lvl, "relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant", true);
|
||||||
|
|
|
@ -72,7 +72,6 @@ struct smt_params : public dyn_ack_params, public qi_params, public theory_arith
|
||||||
bool m_display_dot_proof;
|
bool m_display_dot_proof;
|
||||||
bool m_display_unsat_core;
|
bool m_display_unsat_core;
|
||||||
bool m_check_proof;
|
bool m_check_proof;
|
||||||
bool m_internalizer_nnf;
|
|
||||||
bool m_eq_propagation;
|
bool m_eq_propagation;
|
||||||
bool m_binary_clause_opt;
|
bool m_binary_clause_opt;
|
||||||
unsigned m_relevancy_lvl;
|
unsigned m_relevancy_lvl;
|
||||||
|
@ -193,7 +192,6 @@ struct smt_params : public dyn_ack_params, public qi_params, public theory_arith
|
||||||
m_display_dot_proof(false),
|
m_display_dot_proof(false),
|
||||||
m_display_unsat_core(false),
|
m_display_unsat_core(false),
|
||||||
m_check_proof(false),
|
m_check_proof(false),
|
||||||
m_internalizer_nnf(false),
|
|
||||||
m_eq_propagation(true),
|
m_eq_propagation(true),
|
||||||
m_binary_clause_opt(true),
|
m_binary_clause_opt(true),
|
||||||
m_relevancy_lvl(2),
|
m_relevancy_lvl(2),
|
||||||
|
|
|
@ -25,12 +25,12 @@ Revision History:
|
||||||
#include"bv_simplifier_plugin.h"
|
#include"bv_simplifier_plugin.h"
|
||||||
#include"for_each_expr.h"
|
#include"for_each_expr.h"
|
||||||
#include"well_sorted.h"
|
#include"well_sorted.h"
|
||||||
|
#include"pull_quant.h"
|
||||||
#include"pull_ite_tree.h"
|
#include"pull_ite_tree.h"
|
||||||
#include"push_app_ite.h"
|
#include"push_app_ite.h"
|
||||||
#include"elim_term_ite.h"
|
#include"elim_term_ite.h"
|
||||||
#include"pattern_inference.h"
|
#include"pattern_inference.h"
|
||||||
#include"nnf.h"
|
#include"nnf.h"
|
||||||
#include"cnf.h"
|
|
||||||
#include"bv_elim.h"
|
#include"bv_elim.h"
|
||||||
#include"inj_axiom.h"
|
#include"inj_axiom.h"
|
||||||
#include"der.h"
|
#include"der.h"
|
||||||
|
@ -86,22 +86,6 @@ void asserted_formulas::setup() {
|
||||||
|
|
||||||
if (m_params.m_relevancy_lvl == 0)
|
if (m_params.m_relevancy_lvl == 0)
|
||||||
m_params.m_relevancy_lemma = false;
|
m_params.m_relevancy_lemma = false;
|
||||||
|
|
||||||
switch (m_params.m_cnf_mode) {
|
|
||||||
case CNF_QUANT:
|
|
||||||
if (m_params.m_nnf_mode == NNF_SKOLEM)
|
|
||||||
m_params.m_nnf_mode = NNF_QUANT;
|
|
||||||
break;
|
|
||||||
case CNF_OPPORTUNISTIC:
|
|
||||||
if (m_params.m_nnf_mode == NNF_SKOLEM)
|
|
||||||
m_params.m_nnf_mode = NNF_QUANT;
|
|
||||||
break;
|
|
||||||
case CNF_FULL:
|
|
||||||
m_params.m_nnf_mode = NNF_FULL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void asserted_formulas::setup_simplifier_plugins(simplifier & s, basic_simplifier_plugin * & bsimp, arith_simplifier_plugin * & asimp, bv_simplifier_plugin * & bvsimp) {
|
void asserted_formulas::setup_simplifier_plugins(simplifier & s, basic_simplifier_plugin * & bsimp, arith_simplifier_plugin * & asimp, bv_simplifier_plugin * & bvsimp) {
|
||||||
|
@ -439,13 +423,10 @@ void asserted_formulas::apply_quasi_macros() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void asserted_formulas::nnf_cnf() {
|
void asserted_formulas::nnf_cnf() {
|
||||||
IF_IVERBOSE(10, verbose_stream() << "applying nnf&cnf...\n";);
|
IF_IVERBOSE(10, verbose_stream() << "applying nnf...\n";);
|
||||||
nnf apply_nnf(m_manager, m_defined_names, m_params);
|
nnf apply_nnf(m_manager, m_defined_names);
|
||||||
cnf apply_cnf(m_manager, m_defined_names, m_params);
|
|
||||||
expr_ref_vector new_exprs(m_manager);
|
expr_ref_vector new_exprs(m_manager);
|
||||||
proof_ref_vector new_prs(m_manager);
|
proof_ref_vector new_prs(m_manager);
|
||||||
expr_ref_vector cnf_todo(m_manager);
|
|
||||||
proof_ref_vector cnf_todo_prs(m_manager);
|
|
||||||
expr_ref_vector push_todo(m_manager);
|
expr_ref_vector push_todo(m_manager);
|
||||||
proof_ref_vector push_todo_prs(m_manager);
|
proof_ref_vector push_todo_prs(m_manager);
|
||||||
|
|
||||||
|
@ -456,60 +437,33 @@ void asserted_formulas::nnf_cnf() {
|
||||||
expr * n = m_asserted_formulas.get(i);
|
expr * n = m_asserted_formulas.get(i);
|
||||||
TRACE("nnf_bug", tout << "processing:\n" << mk_pp(n, m_manager) << "\n";);
|
TRACE("nnf_bug", tout << "processing:\n" << mk_pp(n, m_manager) << "\n";);
|
||||||
proof * pr = m_asserted_formula_prs.get(i, 0);
|
proof * pr = m_asserted_formula_prs.get(i, 0);
|
||||||
cnf_todo.reset();
|
|
||||||
cnf_todo_prs.reset();
|
|
||||||
expr_ref r1(m_manager);
|
expr_ref r1(m_manager);
|
||||||
proof_ref pr1(m_manager);
|
proof_ref pr1(m_manager);
|
||||||
CASSERT("well_sorted",is_well_sorted(m_manager, n));
|
CASSERT("well_sorted",is_well_sorted(m_manager, n));
|
||||||
apply_nnf(n, cnf_todo, cnf_todo_prs, r1, pr1);
|
apply_nnf(n, push_todo, push_todo_prs, r1, pr1);
|
||||||
CASSERT("well_sorted",is_well_sorted(m_manager, r1));
|
CASSERT("well_sorted",is_well_sorted(m_manager, r1));
|
||||||
pr = m_manager.mk_modus_ponens(pr, pr1);
|
pr = m_manager.mk_modus_ponens(pr, pr1);
|
||||||
cnf_todo.push_back(r1);
|
push_todo.push_back(r1);
|
||||||
cnf_todo_prs.push_back(pr);
|
push_todo_prs.push_back(pr);
|
||||||
|
|
||||||
if (canceled()) {
|
if (canceled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
unsigned sz2 = push_todo.size();
|
||||||
unsigned sz1 = cnf_todo.size();
|
for (unsigned k = 0; k < sz2; k++) {
|
||||||
for (unsigned j = 0; j < sz1; j++) {
|
expr * n = push_todo.get(k);
|
||||||
push_todo.reset();
|
proof * pr = 0;
|
||||||
push_todo_prs.reset();
|
m_simplifier(n, r1, pr1);
|
||||||
|
CASSERT("well_sorted",is_well_sorted(m_manager, r1));
|
||||||
if (canceled()) {
|
if (canceled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr * n = cnf_todo.get(j);
|
if (m_manager.proofs_enabled())
|
||||||
proof * pr = m_manager.proofs_enabled() ? cnf_todo_prs.get(j) : 0;
|
pr = m_manager.mk_modus_ponens(push_todo_prs.get(k), pr1);
|
||||||
|
else
|
||||||
CASSERT("well_sorted",is_well_sorted(m_manager, n));
|
pr = 0;
|
||||||
apply_cnf(n, push_todo, push_todo_prs, r1, pr1);
|
push_assertion(r1, pr, new_exprs, new_prs);
|
||||||
CASSERT("well_sorted",is_well_sorted(m_manager, r1));
|
|
||||||
|
|
||||||
push_todo.push_back(r1);
|
|
||||||
|
|
||||||
if (m_manager.proofs_enabled()) {
|
|
||||||
pr = m_manager.mk_modus_ponens(pr, pr1);
|
|
||||||
push_todo_prs.push_back(pr);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned sz2 = push_todo.size();
|
|
||||||
for (unsigned k = 0; k < sz2; k++) {
|
|
||||||
expr * n = push_todo.get(k);
|
|
||||||
proof * pr = 0;
|
|
||||||
m_simplifier(n, r1, pr1);
|
|
||||||
CASSERT("well_sorted",is_well_sorted(m_manager, r1));
|
|
||||||
if (canceled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_manager.proofs_enabled())
|
|
||||||
pr = m_manager.mk_modus_ponens(push_todo_prs.get(k), pr1);
|
|
||||||
else
|
|
||||||
pr = 0;
|
|
||||||
push_assertion(r1, pr, new_exprs, new_prs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
swap_asserted_formulas(new_exprs, new_prs);
|
swap_asserted_formulas(new_exprs, new_prs);
|
||||||
|
|
|
@ -654,10 +654,6 @@ namespace smt {
|
||||||
protected:
|
protected:
|
||||||
unsigned m_generation; //!< temporary variable used during internalization
|
unsigned m_generation; //!< temporary variable used during internalization
|
||||||
|
|
||||||
bool expand_pos_def_only() const {
|
|
||||||
return m_fparams.m_nnf_mode == NNF_FULL && m_fparams.m_internalizer_nnf;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool binary_clause_opt_enabled() const {
|
bool binary_clause_opt_enabled() const {
|
||||||
return !m_manager.proofs_enabled() && m_fparams.m_binary_clause_opt;
|
return !m_manager.proofs_enabled() && m_fparams.m_binary_clause_opt;
|
||||||
|
|
|
@ -1566,9 +1566,7 @@ namespace smt {
|
||||||
mk_gate_clause(~l, l_arg);
|
mk_gate_clause(~l, l_arg);
|
||||||
buffer.push_back(~l_arg);
|
buffer.push_back(~l_arg);
|
||||||
}
|
}
|
||||||
if (!expand_pos_def_only()) {
|
mk_gate_clause(buffer.size(), buffer.c_ptr());
|
||||||
mk_gate_clause(buffer.size(), buffer.c_ptr());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void context::mk_or_cnstr(app * n) {
|
void context::mk_or_cnstr(app * n) {
|
||||||
|
@ -1578,8 +1576,7 @@ namespace smt {
|
||||||
unsigned num_args = n->get_num_args();
|
unsigned num_args = n->get_num_args();
|
||||||
for (unsigned i = 0; i < num_args; i++) {
|
for (unsigned i = 0; i < num_args; i++) {
|
||||||
literal l_arg = get_literal(n->get_arg(i));
|
literal l_arg = get_literal(n->get_arg(i));
|
||||||
if (!expand_pos_def_only())
|
mk_gate_clause(l, ~l_arg);
|
||||||
mk_gate_clause(l, ~l_arg);
|
|
||||||
buffer.push_back(l_arg);
|
buffer.push_back(l_arg);
|
||||||
}
|
}
|
||||||
mk_gate_clause(buffer.size(), buffer.c_ptr());
|
mk_gate_clause(buffer.size(), buffer.c_ptr());
|
||||||
|
|
Loading…
Reference in a new issue