From e6ea81546eb78b6ad1e5920954796f6d1c2074e4 Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Sat, 8 Apr 2023 17:14:39 -0700 Subject: [PATCH] fix #6662 --- src/ast/special_relations_decl_plugin.cpp | 1 + src/ast/special_relations_decl_plugin.h | 5 +++++ src/smt/smt_model_checker.cpp | 23 ++++++++++++++++++++++- src/smt/smt_model_checker.h | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ast/special_relations_decl_plugin.cpp b/src/ast/special_relations_decl_plugin.cpp index b45778d2f83..24a756bf79e 100644 --- a/src/ast/special_relations_decl_plugin.cpp +++ b/src/ast/special_relations_decl_plugin.cpp @@ -47,6 +47,7 @@ func_decl * special_relations_decl_plugin::mk_func_decl( if (!m_manager->is_bool(range)) { m_manager->raise_exception("range type is expected to be Boolean for special relations"); } + m_has_special_relation = true; func_decl_info info(m_family_id, k, num_parameters, parameters); symbol name; switch(k) { diff --git a/src/ast/special_relations_decl_plugin.h b/src/ast/special_relations_decl_plugin.h index 0c437786421..c422cbcdc01 100644 --- a/src/ast/special_relations_decl_plugin.h +++ b/src/ast/special_relations_decl_plugin.h @@ -37,6 +37,7 @@ class special_relations_decl_plugin : public decl_plugin { symbol m_plo; symbol m_to; symbol m_tc; + bool m_has_special_relation = false; public: special_relations_decl_plugin(); @@ -50,6 +51,8 @@ class special_relations_decl_plugin : public decl_plugin { void get_op_names(svector & op_names, symbol const & logic) override; sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) override { return nullptr; } + + bool has_special_relation() const { return m_has_special_relation; } }; enum sr_property { @@ -82,6 +85,8 @@ class special_relations_util { } public: special_relations_util(ast_manager& m) : m(m), m_fid(null_family_id) { } + + bool has_special_relation() const { return static_cast(m.get_plugin(m.mk_family_id("specrels")))->has_special_relation(); } bool is_special_relation(func_decl* f) const { return f->get_family_id() == fid(); } bool is_special_relation(app* e) const { return is_special_relation(e->get_decl()); } diff --git a/src/smt/smt_model_checker.cpp b/src/smt/smt_model_checker.cpp index e555088538c..2d23504945a 100644 --- a/src/smt/smt_model_checker.cpp +++ b/src/smt/smt_model_checker.cpp @@ -28,6 +28,7 @@ Revision History: #include "ast/rewriter/rewriter_def.h" #include "ast/ast_pp.h" #include "ast/array_decl_plugin.h" +#include "ast/special_relations_decl_plugin.h" #include "ast/ast_smt2_pp.h" #include "smt/smt_model_checker.h" #include "smt/smt_context.h" @@ -358,7 +359,7 @@ namespace smt { TRACE("model_checker", tout << "[complete] model-checker result: " << to_sat_str(r) << "\n";); if (r != l_true) { - return r == l_false; // quantifier is satisfied by m_curr_model + return is_safe_for_mbqi(q) && r == l_false; // quantifier is satisfied by m_curr_model } model_ref complete_cex; @@ -398,6 +399,26 @@ namespace smt { return false; } + bool model_checker::is_safe_for_mbqi(quantifier * q) const { + special_relations_util sp(m); + if (!sp.has_special_relation()) + return true; + ast_fast_mark1 visited; + struct proc { + special_relations_util& sp; + bool found = false; + proc(special_relations_util& sp):sp(sp) {} + void operator()(app* f) { + found |= sp.is_special_relation(f); + } + void operator()(expr* e) {} + }; + proc p(sp); + quick_for_each_expr(p, visited, q); + return !p.found; + } + + void model_checker::init_aux_context() { if (!m_fparams) { m_fparams = alloc(smt_params, m_context->get_fparams()); diff --git a/src/smt/smt_model_checker.h b/src/smt/smt_model_checker.h index 6332a890e83..46d51f9a015 100644 --- a/src/smt/smt_model_checker.h +++ b/src/smt/smt_model_checker.h @@ -87,6 +87,7 @@ namespace smt { expr_mark m_visited; bool contains_model_value(expr * e); void add_instance(quantifier * q, expr_ref_vector const & bindings, unsigned max_generation, expr * def); + bool is_safe_for_mbqi(quantifier * q) const; public: model_checker(ast_manager & m, qi_params const & p, model_finder & mf);