Skip to content

Commit

Permalink
[spacer] implement spacer::is_clause() (Z3Prover#4170)
Browse files Browse the repository at this point in the history
Spacer has a different defintion of is_clause() than ast_util.
It is currently only used in assertions.

Main difference:
  x=y
where x and y are Bool atoms is considered to be an atom, so that
(or (= x y) (not (= z y)))
is a literal

Co-authored-by: Arie Gurfinkel <arie.gurfinkel@uwaterloo.ca>
  • Loading branch information
hgvk94 and agurfinkel committed May 22, 2020
1 parent e708603 commit 530d44f
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 4 deletions.
6 changes: 4 additions & 2 deletions src/muz/spacer/spacer_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -941,8 +941,10 @@ void pred_transformer::add_lemma_core(lemma* lemma, bool ground_only)
SASSERT(!lemma->is_background());
unsigned lvl = lemma->level();
expr* l = lemma->get_expr();
SASSERT(!lemma->is_ground() || is_clause(m, l));
SASSERT(!is_quantifier(l) || is_clause(m, to_quantifier(l)->get_expr()));
CTRACE("spacer", !spacer::is_clause(m, l),
tout << "Lemma not a clause: " << mk_pp(l, m) << "\n";);
SASSERT(!lemma->is_ground() || spacer::is_clause(m, l));
SASSERT(!is_quantifier(l) || spacer::is_clause(m, to_quantifier(l)->get_expr()));

get_context().log_add_lemma(*this, *lemma);

Expand Down
4 changes: 2 additions & 2 deletions src/muz/spacer/spacer_unsat_core_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ namespace spacer {
// the current step needs to be interpolated:
expr* fact = m.get_fact(pf);
// if we trust the current step and we are able to use it
if (m_ctx.is_b_pure (pf) && (m.is_asserted(pf) || is_literal(m, fact))) {
if (m_ctx.is_b_pure (pf) && (m.is_asserted(pf) || spacer::is_literal(m, fact))) {
// just add it to the core
m_ctx.add_lemma_to_core(fact);
}
Expand Down Expand Up @@ -558,7 +558,7 @@ namespace spacer {
// if we trust the current step and we are able to use it
if (m_ctx.is_b_pure (current) &&
(m.is_asserted(current) ||
is_literal(m, m.get_fact(current))))
spacer::is_literal(m, m.get_fact(current))))
{
// we found a leaf of the subproof, so
// 1) we add corresponding edges
Expand Down
38 changes: 38 additions & 0 deletions src/muz/spacer/spacer_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,44 @@ Revision History:

namespace spacer {

bool is_clause(ast_manager &m, expr *n) {
if (spacer::is_literal(m, n))
return true;
if (m.is_or(n)) {
for (expr *arg : *to_app(n)){
if (!spacer::is_literal(m, arg))
return false;
return true;
}
}
return false;
}

bool is_literal(ast_manager &m, expr *n) {
return spacer::is_atom(m, n) || (m.is_not(n) && spacer::is_atom(m, to_app(n)->get_arg(0)));
}

bool is_atom(ast_manager &m, expr *n) {
if (is_quantifier(n) || !m.is_bool(n))
return false;
if (is_var(n))
return true;
SASSERT(is_app(n));
if (to_app(n)->get_family_id() != m.get_basic_family_id()) {
return true;
}

if ((m.is_eq(n) && !m.is_bool(to_app(n)->get_arg(0))) ||
m.is_true(n) || m.is_false(n))
return true;

// x=y is atomic if x and y are Bool and atomic
expr *e1, *e2;
if (m.is_eq(n, e1, e2) && spacer::is_atom(m, e1) && spacer::is_atom(m, e2))
return true;
return false;
}

void subst_vars(ast_manager& m,
app_ref_vector const& vars, model& mdl, expr_ref& fml) {
model::scoped_model_completion _sc_(mdl, true);
Expand Down
3 changes: 3 additions & 0 deletions src/muz/spacer/spacer_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ namespace spacer {
/// Returns number of free variables in a given expression
unsigned get_num_vars(expr *e);
void get_uninterp_consts(expr *a, expr_ref_vector &out);
bool is_clause(ast_manager &m, expr *n);
bool is_literal(ast_manager &m, expr *n);
bool is_atom(ast_manager &m, expr *n);
}

#endif

0 comments on commit 530d44f

Please sign in to comment.