mirror of
https://github.com/Z3Prover/z3
synced 2025-05-10 01:05:47 +00:00
Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
3f9edad676
commit
e9eab22e5c
1186 changed files with 381859 additions and 0 deletions
531
lib/spc_superposition.cpp
Normal file
531
lib/spc_superposition.cpp
Normal file
|
@ -0,0 +1,531 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
spc_superposition.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-02-15.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"spc_superposition.h"
|
||||
#include"ast_pp.h"
|
||||
|
||||
namespace spc {
|
||||
|
||||
superposition::superposition(ast_manager & m, order & o, statistics & s):
|
||||
m_manager(m),
|
||||
m_order(o),
|
||||
m_stats(s),
|
||||
m_subst(m),
|
||||
m_p(m),
|
||||
m_r(m),
|
||||
m_normalize_vars(m),
|
||||
m_spc_fid(m.get_family_id("spc")) {
|
||||
m_subst.reserve_offsets(3);
|
||||
m_deltas[0] = 0;
|
||||
m_deltas[1] = 0;
|
||||
}
|
||||
|
||||
superposition::~superposition() {
|
||||
}
|
||||
|
||||
void superposition::insert_p(clause * cls, expr * lhs, unsigned i) {
|
||||
m_p.insert(lhs);
|
||||
m_subst.reserve_vars(m_p.get_approx_num_regs());
|
||||
m_p2clause_set.insert(clause_pos_pair(cls, i), lhs);
|
||||
}
|
||||
|
||||
void superposition::insert_p(clause * cls, literal & l, unsigned i) {
|
||||
l.set_p_indexed(true);
|
||||
expr * atom = l.atom();
|
||||
if (!m_manager.is_eq(atom))
|
||||
return;
|
||||
if (l.is_oriented())
|
||||
insert_p(cls, l.is_left() ? l.lhs() : l.rhs(), i);
|
||||
else {
|
||||
insert_p(cls, l.lhs(), i);
|
||||
insert_p(cls, l.rhs(), i);
|
||||
}
|
||||
}
|
||||
|
||||
void superposition::insert_r(clause * cls, expr * n, unsigned i, bool lhs) {
|
||||
if (is_app(n)) {
|
||||
unsigned idx = (i << 1) | static_cast<unsigned>(lhs);
|
||||
|
||||
clause_pos_pair new_pair(cls, idx);
|
||||
SASSERT(m_todo.empty());
|
||||
m_todo.push_back(to_app(n));
|
||||
while (!m_todo.empty()) {
|
||||
app * n = m_todo.back();
|
||||
m_todo.pop_back();
|
||||
clause_pos_set * s = m_r2clause_set.get_parents(n);
|
||||
if (s == 0 || !s->contains(new_pair)) {
|
||||
m_r.insert(n);
|
||||
m_r2clause_set.insert(new_pair, n);
|
||||
unsigned num_args = n->get_num_args();
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
expr * c = n->get_arg(i);
|
||||
if (is_app(c))
|
||||
m_todo.push_back(to_app(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void superposition::insert_r(clause * cls, literal & l, unsigned i) {
|
||||
l.set_r_indexed(true);
|
||||
expr * atom = l.atom();
|
||||
if (m_manager.is_eq(atom)) {
|
||||
expr * lhs = l.lhs();
|
||||
expr * rhs = l.rhs();
|
||||
if (l.is_oriented()) {
|
||||
bool left = true;
|
||||
if (!l.is_left()) {
|
||||
left = false;
|
||||
std::swap(lhs, rhs);
|
||||
}
|
||||
insert_r(cls, lhs, i, left);
|
||||
}
|
||||
else {
|
||||
insert_r(cls, lhs, i, true);
|
||||
insert_r(cls, rhs, i, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
insert_r(cls, atom, i, false);
|
||||
}
|
||||
m_subst.reserve_vars(m_r.get_approx_num_regs());
|
||||
}
|
||||
|
||||
void superposition::insert(clause * cls) {
|
||||
unsigned num_lits = cls->get_num_literals();
|
||||
for (unsigned i = 0; i < num_lits; i++) {
|
||||
literal & l = cls->get_literal(i);
|
||||
if (l.is_p_indexed() || cls->is_eligible_for_paramodulation(m_order, l)) {
|
||||
if (!l.sign() && m_manager.is_eq(l.atom()))
|
||||
insert_p(cls, l, i);
|
||||
insert_r(cls, l, i);
|
||||
}
|
||||
else if (l.is_r_indexed() || cls->is_eligible_for_resolution(m_order, l)) {
|
||||
insert_r(cls, l, i);
|
||||
}
|
||||
}
|
||||
TRACE("superposition_detail",
|
||||
tout << "adding clause: "; cls->display(tout, m_manager); tout << "\n";
|
||||
tout << "p index:\n";
|
||||
m_p.display(tout);
|
||||
tout << "r index:\n";
|
||||
m_r.display(tout););
|
||||
}
|
||||
|
||||
void superposition::erase_p(clause * cls, expr * lhs, unsigned i) {
|
||||
m_p2clause_set.erase(clause_pos_pair(cls, i), lhs);
|
||||
if (m_p2clause_set.empty(lhs))
|
||||
m_p.erase(lhs);
|
||||
}
|
||||
|
||||
void superposition::erase_p(clause * cls, literal & l, unsigned i) {
|
||||
expr * atom = l.atom();
|
||||
if (!m_manager.is_eq(atom))
|
||||
return;
|
||||
if (l.is_oriented())
|
||||
erase_p(cls, l.is_left() ? l.lhs() : l.rhs(), i);
|
||||
else {
|
||||
erase_p(cls, l.lhs(), i);
|
||||
erase_p(cls, l.rhs(), i);
|
||||
}
|
||||
}
|
||||
|
||||
void superposition::erase_r(clause * cls, literal & l, unsigned i) {
|
||||
clause_pos_pair pair(cls, i);
|
||||
|
||||
expr * atom = l.atom();
|
||||
SASSERT(is_app(atom));
|
||||
SASSERT(m_todo.empty());
|
||||
m_todo.push_back(to_app(atom));
|
||||
|
||||
while (!m_todo.empty()) {
|
||||
app * n = m_todo.back();
|
||||
m_todo.pop_back();
|
||||
switch (m_r2clause_set.erase(pair, n)) {
|
||||
case 0: // pair is not a parent of n
|
||||
break;
|
||||
case 1: // pair is the last parent of n
|
||||
m_r.erase(n);
|
||||
default:
|
||||
unsigned num_args = n->get_num_args();
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
expr * c = n->get_arg(i);
|
||||
if (is_app(c))
|
||||
m_todo.push_back(to_app(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void superposition::erase(clause * cls) {
|
||||
unsigned num_lits = cls->get_num_literals();
|
||||
for (unsigned i = 0; i < num_lits; i++) {
|
||||
literal & l = cls->get_literal(i);
|
||||
if (l.is_p_indexed())
|
||||
erase_p(cls, l, i);
|
||||
if (l.is_r_indexed())
|
||||
erase_r(cls, l, i);
|
||||
}
|
||||
}
|
||||
|
||||
void superposition::reset() {
|
||||
m_p.reset();
|
||||
m_p2clause_set.reset();
|
||||
m_r.reset();
|
||||
m_r2clause_set.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Copy to result the literals of s except literal at position idx. Apply the substitution m_subst,
|
||||
assuming that the variables of s are in the variable bank offset. The deltas for each bank are
|
||||
stored in m_deltas.
|
||||
*/
|
||||
void superposition::copy_literals(clause * s, unsigned idx, unsigned offset, literal_buffer & result) {
|
||||
unsigned num_lits = s->get_num_literals();
|
||||
for (unsigned i = 0; i < num_lits; i++)
|
||||
if (i != idx) {
|
||||
literal const & l = s->get_literal(i);
|
||||
expr_ref new_atom(m_manager);
|
||||
m_subst.apply(2, m_deltas, expr_offset(l.atom(), offset), new_atom);
|
||||
TRACE("superposition_copy", tout << "i: " << i << ", idx: " << idx << ", offset: " << offset << "\natom:\n";
|
||||
tout << mk_pp(l.atom(), m_manager) << "\nnew_atom:\n" << mk_pp(new_atom, m_manager) << "\n";);
|
||||
result.push_back(literal(new_atom, l.sign()));
|
||||
}
|
||||
}
|
||||
|
||||
void superposition::normalize_literals(unsigned num_lits, literal * lits, literal_buffer & result) {
|
||||
m_normalize_vars.reset();
|
||||
for (unsigned i = 0; i < num_lits; i++) {
|
||||
literal const & l = lits[i];
|
||||
result.push_back(literal(m_normalize_vars(l.atom()), l.sign()));
|
||||
}
|
||||
}
|
||||
|
||||
void superposition::mk_sp_clause(unsigned num_lits, literal * lits, justification * p1, justification * p2) {
|
||||
literal_buffer new_literals(m_manager);
|
||||
normalize_literals(num_lits, lits, new_literals);
|
||||
justification * js = mk_superposition_justification(m_manager, m_spc_fid, p1, p2,
|
||||
new_literals.size(), new_literals.c_ptr(),
|
||||
m_normalize_vars.get_num_vars(), m_normalize_vars.get_vars());
|
||||
clause * new_cls = clause::mk(m_manager, new_literals.size(), new_literals.c_ptr(), js, 0);
|
||||
m_new_clauses->push_back(new_cls);
|
||||
TRACE("superposition", tout << "new superposition clause:\n"; new_cls->display(tout, m_manager); tout << "\n";);
|
||||
m_stats.m_num_superposition++;
|
||||
}
|
||||
|
||||
void superposition::mk_res_clause(unsigned num_lits, literal * lits, justification * p1, justification * p2) {
|
||||
literal_buffer new_literals(m_manager);
|
||||
normalize_literals(num_lits, lits, new_literals);
|
||||
justification * js = mk_resolution_justification(m_manager, m_spc_fid, p1, p2,
|
||||
new_literals.size(), new_literals.c_ptr(),
|
||||
m_normalize_vars.get_num_vars(), m_normalize_vars.get_vars());
|
||||
clause * new_cls = clause::mk(m_manager, new_literals.size(), new_literals.c_ptr(), js, 0);
|
||||
m_new_clauses->push_back(new_cls);
|
||||
TRACE("superposition", tout << "new resolution clause:\n"; new_cls->display(tout, m_manager); tout << "\n";);
|
||||
m_stats.m_num_resolution++;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Given the equation (= lhs rhs) of the clause being
|
||||
added, try to apply resolution where the clause being added
|
||||
is the main clause in the superposition rule.
|
||||
*/
|
||||
void superposition::try_superposition_main(expr * lhs, expr * rhs) {
|
||||
m_lhs = lhs;
|
||||
m_rhs = rhs;
|
||||
m_subst.reset_subst();
|
||||
TRACE("spc_superposition", tout << "try_superposition_main, lhs:\n" << mk_pp(m_lhs, m_manager) << "\nrhs:\n" << mk_pp(m_rhs, m_manager) << "\n";
|
||||
tout << "substitution:\n"; m_subst.display(tout););
|
||||
r_visitor v(*this, m_subst);
|
||||
m_r.unify(lhs, v);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Try to apply superposition rule using the clause
|
||||
being added (m_clause) as main clause, and its literal m_lit
|
||||
as the equation.
|
||||
*/
|
||||
void superposition::try_superposition_main() {
|
||||
expr * lhs = m_lit->lhs();
|
||||
expr * rhs = m_lit->rhs();
|
||||
TRACE("spc_superposition", tout << "trying superposition:\n" << mk_pp(lhs, m_manager) << "\n" << mk_pp(rhs, m_manager) << "\nis_oriented: " << m_lit->is_oriented() << "\n";);
|
||||
if (m_lit->is_oriented()) {
|
||||
if (!m_lit->is_left())
|
||||
std::swap(lhs, rhs);
|
||||
try_superposition_main(lhs, rhs);
|
||||
}
|
||||
else {
|
||||
try_superposition_main(lhs, rhs);
|
||||
try_superposition_main(rhs, lhs);
|
||||
}
|
||||
}
|
||||
|
||||
void superposition::found_r(expr * r) {
|
||||
TRACE("spc_superposition", tout << "found_r:\n" << mk_pp(r, m_manager) << "\n";
|
||||
tout << "substitution:\n"; m_subst.display(tout););
|
||||
if (m_r2clause_set.empty(r))
|
||||
return;
|
||||
TRACE("spc_superposition", tout << "r2clause is not empty.\n";);
|
||||
if (!m_lit->is_oriented() && m_order.greater(m_rhs, m_lhs, &m_subst))
|
||||
return;
|
||||
TRACE("spc_superposition", tout << "order restriction was met.\n";);
|
||||
if (!m_clause->is_eligible_for_paramodulation(m_order, *m_lit, 0, &m_subst))
|
||||
return;
|
||||
TRACE("spc_superposition", tout << "literal is eligible for paramodulation.\n";);
|
||||
r2clause_set::iterator it = m_r2clause_set.begin(r);
|
||||
r2clause_set::iterator end = m_r2clause_set.end(r);
|
||||
for (; it != end; ++it) {
|
||||
clause_pos_pair & p = *it;
|
||||
clause * aux_cls = p.first;
|
||||
unsigned aux_idx = p.second >> 1;
|
||||
//
|
||||
// The following optimization is incorrect (if statement).
|
||||
// For example, it prevents the Z3 from proving the trivial benchmark
|
||||
// c = X,
|
||||
// a != b
|
||||
// using the order a < b < c
|
||||
//
|
||||
// To prove, this example we need to generate the clause Y = X by applying superposition of c = X on itself.
|
||||
// We can see that by renaming the first clause to c = Y, and then, substituting c in the original by Y.
|
||||
//
|
||||
// Actually, this optimization is correct when the set of variables in m_lhs is a superset of the set of variables in m_rhs,
|
||||
// because in this case, the new literal will be equivalent to true. In the example above, this is not the case,
|
||||
// since m_lhs does not contain any variable, and m_rhs contains one.
|
||||
//
|
||||
|
||||
//
|
||||
// if (r == m_lhs && m_clause == aux_cls && m_idx == aux_idx)
|
||||
// continue;
|
||||
//
|
||||
bool in_lhs = (p.second & 1) != 0;
|
||||
TRACE("spc_superposition", tout << "aux_cls:\n"; aux_cls->display(tout, m_manager); tout << "\naux_idx: " << aux_cls << ", in_lhs: " << in_lhs << "\n";);
|
||||
literal & aux_lit = aux_cls->get_literal(aux_idx);
|
||||
if (!aux_cls->is_eligible_for_resolution(m_order, aux_lit, 1, &m_subst))
|
||||
continue;
|
||||
literal_buffer new_literals(m_manager);
|
||||
m_subst.reset_cache();
|
||||
if (m_manager.is_eq(aux_lit.atom())) {
|
||||
expr * lhs = aux_lit.lhs();
|
||||
expr * rhs = aux_lit.rhs();
|
||||
TRACE("spc_superposition", tout << "aux_lit lhs:\n" << mk_pp(lhs, m_manager) << "\nrhs:\n" << mk_pp(rhs, m_manager) << "\n";);
|
||||
if (!in_lhs)
|
||||
std::swap(lhs, rhs);
|
||||
if (!aux_lit.is_oriented() && m_order.greater(rhs, lhs, 1, &m_subst)) {
|
||||
TRACE("spc_superposition", tout << "failed order constraint.\n";);
|
||||
continue;
|
||||
}
|
||||
expr_ref new_lhs(m_manager), new_rhs(m_manager);
|
||||
m_subst.apply(2, m_deltas, expr_offset(lhs, 1), expr_offset(r, 1), expr_offset(m_rhs, 0), new_lhs);
|
||||
m_subst.apply(2, m_deltas, expr_offset(rhs, 1), new_rhs);
|
||||
TRACE("spc_superposition", tout << "aux_lit new_lhs:\n" << mk_pp(new_lhs, m_manager) << "\nnew_rhs:\n" << mk_pp(new_rhs, m_manager) << "\n";);
|
||||
expr * new_eq = m_manager.mk_eq(new_lhs, new_rhs);
|
||||
new_literals.push_back(literal(new_eq, aux_lit.sign()));
|
||||
}
|
||||
else {
|
||||
expr_ref new_atom(m_manager);
|
||||
m_subst.apply(2, m_deltas, expr_offset(aux_lit.atom(), 1), new_atom);
|
||||
new_literals.push_back(literal(new_atom, aux_lit.sign()));
|
||||
}
|
||||
copy_literals(m_clause, m_idx, 0, new_literals);
|
||||
copy_literals(aux_cls, aux_idx, 1, new_literals);
|
||||
TRACE("superposition", tout << "found r target: " << mk_pp(r, m_manager) << " for \n" <<
|
||||
mk_pp(m_lhs, m_manager) << "\nmain clause: "; m_clause->display(tout, m_manager);
|
||||
tout << "\naux clause: "; aux_cls->display(tout, m_manager); tout << "\nat pos: " <<
|
||||
aux_idx << "\n";);
|
||||
mk_sp_clause(new_literals.size(), new_literals.c_ptr(), m_clause->get_justification(), aux_cls->get_justification());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Try to apply superposition rule using the clause
|
||||
being added (m_clause) as the aux clause, and its literal m_lit
|
||||
as the target.
|
||||
*/
|
||||
void superposition::try_superposition_aux() {
|
||||
TRACE("superposition_aux", tout << "superposition aux:\n"; m_clause->display(tout, m_manager);
|
||||
tout << "\nusing literal: " << m_idx << "\n";);
|
||||
if (m_manager.is_eq(m_lit->atom())) {
|
||||
expr * lhs = m_lit->lhs();
|
||||
expr * rhs = m_lit->rhs();
|
||||
if (m_lit->is_oriented()) {
|
||||
if (!m_lit->is_left())
|
||||
std::swap(lhs, rhs);
|
||||
try_superposition_aux(lhs, rhs);
|
||||
}
|
||||
else {
|
||||
try_superposition_aux(lhs, rhs);
|
||||
try_superposition_aux(rhs, lhs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
try_superposition_aux(m_lit->atom(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Use the clause being added as the auxiliary clause in the superposition rule.
|
||||
*/
|
||||
void superposition::try_superposition_aux(expr * lhs, expr * rhs) {
|
||||
TRACE("superposition_aux", tout << "try_superposition_aux\n" << mk_pp(lhs, m_manager) << "\n" << mk_pp(rhs, m_manager) << "\n";);
|
||||
if (is_var(lhs))
|
||||
return;
|
||||
m_lhs = lhs;
|
||||
m_rhs = rhs;
|
||||
SASSERT(m_todo.empty());
|
||||
m_todo.push_back(to_app(lhs));
|
||||
while (!m_todo.empty()) {
|
||||
m_target = m_todo.back();
|
||||
m_todo.pop_back();
|
||||
m_subst.reset_subst();
|
||||
p_visitor v(*this, m_subst);
|
||||
TRACE("superposition_aux", tout << "trying to find unifier for:\n" << mk_pp(m_target, m_manager) << "\n";);
|
||||
m_p.unify(m_target, v);
|
||||
unsigned j = m_target->get_num_args();
|
||||
while (j > 0) {
|
||||
--j;
|
||||
expr * arg = m_target->get_arg(j);
|
||||
if (is_app(arg))
|
||||
m_todo.push_back(to_app(arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void superposition::found_p(expr * p) {
|
||||
TRACE("superposition_found_p", tout << "found p:\n" << mk_pp(p, m_manager) << "\n";);
|
||||
if (m_p2clause_set.empty(p)) {
|
||||
TRACE("superposition_found_p", tout << "clause set is empty.\n";);
|
||||
return;
|
||||
}
|
||||
if (m_rhs && !m_lit->is_oriented() && m_order.greater(m_rhs, m_lhs, &m_subst)) {
|
||||
TRACE("superposition_found_p", tout << "aux clause failed not rhs > lhs constraint.\n";);
|
||||
return;
|
||||
}
|
||||
if (!m_clause->is_eligible_for_resolution(m_order, *m_lit, 0, &m_subst)) {
|
||||
TRACE("superposition_found_p", tout << "aux literal is not eligible for resolution.\n";);
|
||||
return;
|
||||
}
|
||||
p2clause_set::iterator it = m_p2clause_set.begin(p);
|
||||
p2clause_set::iterator end = m_p2clause_set.end(p);
|
||||
for (; it != end; ++it) {
|
||||
clause_pos_pair & pair = *it;
|
||||
clause * main_cls = pair.first;
|
||||
TRACE("superposition_found_p", tout << "p clause:\n"; main_cls->display(tout, m_manager); tout << "\n";);
|
||||
unsigned lit_idx = pair.second;
|
||||
if (p == m_lhs && m_clause == main_cls && m_idx == lit_idx)
|
||||
continue;
|
||||
literal const & main_lit = main_cls->get_literal(lit_idx);
|
||||
SASSERT(m_manager.is_eq(main_lit.atom()));
|
||||
expr * lhs = main_lit.lhs();
|
||||
expr * rhs = main_lit.rhs();
|
||||
if (rhs == p)
|
||||
std::swap(lhs, rhs);
|
||||
SASSERT(lhs == p);
|
||||
TRACE("superposition_found_p", tout << "lhs: " << mk_pp(lhs, m_manager) << "\nrhs: " << mk_pp(rhs, m_manager) << "\n";);
|
||||
if (!main_lit.is_oriented() && m_order.greater(rhs, lhs, 1, &m_subst))
|
||||
continue;
|
||||
if (!main_cls->is_eligible_for_paramodulation(m_order, main_lit, 1, &m_subst))
|
||||
continue;
|
||||
literal_buffer new_literals(m_manager);
|
||||
m_subst.reset_cache();
|
||||
TRACE("superposition_found_p", tout << "creating new_lhs\n";);
|
||||
expr_ref new_lhs(m_manager);
|
||||
m_subst.apply(2, m_deltas, expr_offset(m_lhs, 0), expr_offset(m_target, 0), expr_offset(rhs, 1), new_lhs);
|
||||
// FIX: m_subst.reset_cache();
|
||||
TRACE("superposition_found_p", tout << "new_lhs: " << mk_pp(new_lhs, m_manager) << "\n";
|
||||
m_subst.display(tout););
|
||||
expr * new_atom = 0;
|
||||
if (m_rhs) {
|
||||
TRACE("superposition_found_p", tout << "creating new_rhs\n";);
|
||||
expr_ref new_rhs(m_manager);
|
||||
m_subst.apply(2, m_deltas, expr_offset(m_rhs, 0), new_rhs);
|
||||
TRACE("superposition_found_p", tout << "new_rhs: " << mk_pp(new_rhs, m_manager) << "\n";);
|
||||
new_atom = m_manager.mk_eq(new_lhs, new_rhs);
|
||||
}
|
||||
else
|
||||
new_atom = new_lhs;
|
||||
TRACE("superposition_found_p", tout << "new_atom: " << mk_pp(new_atom, m_manager) << "\n"; m_subst.display(tout););
|
||||
new_literals.push_back(literal(new_atom, m_lit->sign()));
|
||||
TRACE("superposition_found_p", tout << "copying literals\n";);
|
||||
copy_literals(main_cls, lit_idx, 1, new_literals);
|
||||
copy_literals(m_clause, m_idx, 0, new_literals);
|
||||
TRACE("superposition", tout << "found p target: " << mk_pp(p, m_manager) << " for \n" <<
|
||||
mk_pp(m_lhs, m_manager) << "\nmain clause: "; main_cls->display(tout, m_manager);
|
||||
tout << "\naux clause: "; m_clause->display(tout, m_manager); tout << "\n";);
|
||||
mk_sp_clause(new_literals.size(), new_literals.c_ptr(), main_cls->get_justification(), m_clause->get_justification());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Try to apply resolution rule using the clause being added (m_clause).
|
||||
*/
|
||||
void superposition::try_resolution() {
|
||||
m_subst.reset_subst();
|
||||
res_visitor v(*this, m_subst);
|
||||
m_r.unify(m_lit->atom(), v);
|
||||
}
|
||||
|
||||
void superposition::found_res(expr * r) {
|
||||
if (m_r2clause_set.empty(r))
|
||||
return;
|
||||
if (!m_clause->is_eligible_for_resolution(m_order, *m_lit, 0, &m_subst))
|
||||
return;
|
||||
r2clause_set::iterator it = m_r2clause_set.begin(r);
|
||||
r2clause_set::iterator end = m_r2clause_set.end(r);
|
||||
for (; it != end; ++it) {
|
||||
clause_pos_pair & pair = *it;
|
||||
clause * aux_cls = pair.first;
|
||||
unsigned aux_idx = pair.second >> 1;
|
||||
literal const & aux_lit = aux_cls->get_literal(aux_idx);
|
||||
if (aux_lit.sign() == m_lit->sign())
|
||||
continue;
|
||||
if (aux_lit.atom() != r)
|
||||
continue;
|
||||
if (!aux_cls->is_eligible_for_resolution(m_order, aux_lit, 1, &m_subst))
|
||||
continue;
|
||||
literal_buffer new_literals(m_manager);
|
||||
m_subst.reset_cache();
|
||||
copy_literals(m_clause, m_idx, 0, new_literals);
|
||||
copy_literals(aux_cls, aux_idx, 1, new_literals);
|
||||
mk_res_clause(new_literals.size(), new_literals.c_ptr(), m_clause->get_justification(), aux_cls->get_justification());
|
||||
}
|
||||
}
|
||||
|
||||
void superposition::operator()(clause * cls, ptr_vector<clause> & new_clauses) {
|
||||
m_subst.reserve_vars(cls->get_num_vars());
|
||||
m_clause = cls;
|
||||
m_new_clauses = &new_clauses;
|
||||
SASSERT(m_deltas[0] == 0);
|
||||
m_deltas[1] = m_clause->get_num_vars();
|
||||
unsigned num_lits = cls->get_num_literals();
|
||||
for (m_idx = 0; m_idx < num_lits; m_idx++) {
|
||||
m_lit = &(cls->get_literal(m_idx));
|
||||
bool is_eq = m_manager.is_eq(m_lit->atom());
|
||||
if (!m_lit->sign() && m_lit->is_p_indexed() && is_eq)
|
||||
try_superposition_main();
|
||||
if (m_lit->is_r_indexed()) {
|
||||
try_superposition_aux();
|
||||
if (!is_eq)
|
||||
try_resolution();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue