mirror of
https://github.com/Z3Prover/z3
synced 2025-05-09 00:35: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
170
lib/spc_asserted_literals.cpp
Normal file
170
lib/spc_asserted_literals.cpp
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
spc_asserted_literals.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-02-14.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include"spc_asserted_literals.h"
|
||||
#include"ast_pp.h"
|
||||
|
||||
namespace spc {
|
||||
|
||||
asserted_literals::asserted_literals(ast_manager & m):
|
||||
m_manager(m),
|
||||
m_subst(m),
|
||||
m_tmp_eq1(2),
|
||||
m_tmp_eq2(2) {
|
||||
for (unsigned i = 0; i < 2; i++) {
|
||||
m_st[i] = alloc(substitution_tree, m_manager);
|
||||
m_expr2clause[i] = alloc(expr2clause);
|
||||
}
|
||||
m_subst.reserve_offsets(3);
|
||||
}
|
||||
|
||||
asserted_literals::~asserted_literals() {
|
||||
for (unsigned i = 0; i < 2; i++) {
|
||||
dealloc(m_st[i]);
|
||||
dealloc(m_expr2clause[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void asserted_literals::insert(clause * cls) {
|
||||
if (cls->get_num_literals() == 1) {
|
||||
TRACE("asserted_literals", tout << "inserting clause into asserted_literals index:\n";
|
||||
cls->display(tout, m_manager); tout << "\n";);
|
||||
literal const & l = cls->get_literal(0);
|
||||
unsigned neg = static_cast<unsigned>(l.sign());
|
||||
expr * atom = l.atom();
|
||||
m_st[neg]->insert(to_app(atom));
|
||||
m_expr2clause[neg]->insert(atom, cls);
|
||||
m_subst.reserve_vars(m_st[neg]->get_approx_num_regs());
|
||||
}
|
||||
}
|
||||
|
||||
void asserted_literals::erase(clause * cls) {
|
||||
if (cls->get_num_literals() == 1) {
|
||||
literal const & l = cls->get_literal(0);
|
||||
unsigned neg = static_cast<unsigned>(l.sign());
|
||||
expr * atom = l.atom();
|
||||
m_expr2clause[neg]->erase(atom);
|
||||
m_st[neg]->erase(to_app(atom));
|
||||
}
|
||||
}
|
||||
|
||||
void asserted_literals::reset() {
|
||||
for (unsigned i = 0; i < 2; i++) {
|
||||
m_st[i]->reset();
|
||||
m_expr2clause[i]->reset();
|
||||
}
|
||||
}
|
||||
|
||||
struct asserted_literals_visitor : public st_visitor {
|
||||
expr * m_target;
|
||||
asserted_literals_visitor(substitution & s):st_visitor(s), m_target(0) {}
|
||||
virtual bool operator()(expr * e) {
|
||||
m_target = e;
|
||||
return false; // stop
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Return an unit clause that is a generalization
|
||||
of the given literal.
|
||||
Return 0 if such clause does not exist.
|
||||
*/
|
||||
clause * asserted_literals::gen(expr * atom, bool n) {
|
||||
if (is_app(atom)) {
|
||||
TRACE("asserted_literals", tout << "checking if there is generalizer for: " << n << "\n" <<
|
||||
mk_pp(atom, m_manager) << "\n";);
|
||||
unsigned neg = static_cast<unsigned>(n);
|
||||
m_subst.reset_subst();
|
||||
asserted_literals_visitor visitor(m_subst);
|
||||
TRACE("asserted_literals_bug", tout << "query: " << mk_pp(atom, m_manager) << "\n"; m_st[neg]->display(tout);
|
||||
m_subst.display(tout););
|
||||
m_st[neg]->gen(to_app(atom), visitor);
|
||||
if (visitor.m_target != 0) {
|
||||
clause * cls = 0;
|
||||
m_expr2clause[neg]->find(visitor.m_target, cls);
|
||||
SASSERT(cls);
|
||||
return cls;
|
||||
}
|
||||
if (m_manager.is_eq(atom)) {
|
||||
m_subst.reset();
|
||||
m_tmp_eq1.copy_swapping_args(to_app(atom));
|
||||
m_st[neg]->gen(m_tmp_eq1.get_app(), visitor);
|
||||
if (visitor.m_target != 0) {
|
||||
clause * cls = 0;
|
||||
m_expr2clause[neg]->find(visitor.m_target, cls);
|
||||
SASSERT(cls);
|
||||
return cls;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Return an unit clause that is a generalization
|
||||
of the equality (= lhs rhs)
|
||||
Return 0 if such clause does not exist.
|
||||
*/
|
||||
clause * asserted_literals::gen_eq(expr * lhs, expr * rhs) {
|
||||
expr * args[2] = { lhs, rhs };
|
||||
func_decl_ref eq_decl(m_manager.mk_func_decl(m_manager.get_basic_family_id(), OP_EQ, 0, 0, 2, args), m_manager);
|
||||
m_tmp_eq2.set_decl(eq_decl);
|
||||
m_tmp_eq2.set_arg(0, lhs);
|
||||
m_tmp_eq2.set_arg(1, rhs);
|
||||
return gen(m_tmp_eq2.get_app(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Return a unit equality clause (= s t) that (eq) subsumes (= lhs rhs).
|
||||
That is, lhs and rhs have the form u[s'] and u[t'] and there is
|
||||
a substitution sigma s.t. sigma(s) = s' and sigma(t) = t'.
|
||||
Return 0 if such clause does not exist.
|
||||
*/
|
||||
clause * asserted_literals::subsumes(expr * lhs, expr * rhs) {
|
||||
while (true) {
|
||||
TRACE("eq_subsumption", tout << "eq_subsumption loop:\n" << mk_pp(lhs, m_manager) << "\n" <<
|
||||
mk_pp(rhs, m_manager) << "\n";);
|
||||
clause * subsumer = gen_eq(lhs, rhs);
|
||||
if (subsumer)
|
||||
return subsumer;
|
||||
if (!is_app(lhs) || !is_app(rhs) ||
|
||||
to_app(lhs)->get_decl() != to_app(rhs)->get_decl() ||
|
||||
to_app(lhs)->get_num_args() != to_app(rhs)->get_num_args())
|
||||
return 0;
|
||||
expr * d1 = 0;
|
||||
expr * d2 = 0;
|
||||
unsigned num_args = to_app(lhs)->get_num_args();
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
expr * c1 = to_app(lhs)->get_arg(i);
|
||||
expr * c2 = to_app(rhs)->get_arg(i);
|
||||
if (c1 != c2) {
|
||||
if (d1)
|
||||
return 0;
|
||||
d1 = c1;
|
||||
d2 = c2;
|
||||
}
|
||||
}
|
||||
SASSERT(d1);
|
||||
lhs = d1;
|
||||
rhs = d2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue