From dbfa3dd7f1aebbdf1216feb176099852196c9445 Mon Sep 17 00:00:00 2001 From: Hari Govind V K Date: Thu, 30 Apr 2020 17:03:48 -0400 Subject: [PATCH] [spacer] implement spacer::is_clause() (#4170) 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 --- src/muz/spacer/spacer_context.cpp | 6 ++-- src/muz/spacer/spacer_unsat_core_plugin.cpp | 4 +-- src/muz/spacer/spacer_util.cpp | 38 +++++++++++++++++++++ src/muz/spacer/spacer_util.h | 4 +++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/muz/spacer/spacer_context.cpp b/src/muz/spacer/spacer_context.cpp index b32756eb0..a33d7e38d 100644 --- a/src/muz/spacer/spacer_context.cpp +++ b/src/muz/spacer/spacer_context.cpp @@ -926,8 +926,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); diff --git a/src/muz/spacer/spacer_unsat_core_plugin.cpp b/src/muz/spacer/spacer_unsat_core_plugin.cpp index 77e88fb32..e0c5a39f5 100644 --- a/src/muz/spacer/spacer_unsat_core_plugin.cpp +++ b/src/muz/spacer/spacer_unsat_core_plugin.cpp @@ -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); } @@ -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 diff --git a/src/muz/spacer/spacer_util.cpp b/src/muz/spacer/spacer_util.cpp index 606c19e7c..213746239 100644 --- a/src/muz/spacer/spacer_util.cpp +++ b/src/muz/spacer/spacer_util.cpp @@ -69,6 +69,44 @@ Notes: 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); diff --git a/src/muz/spacer/spacer_util.h b/src/muz/spacer/spacer_util.h index b9ab358c0..db59dd0db 100644 --- a/src/muz/spacer/spacer_util.h +++ b/src/muz/spacer/spacer_util.h @@ -136,6 +136,10 @@ namespace spacer { mk_epp(ast *t, ast_manager &m, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = nullptr); void rw(expr *e, expr_ref &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