Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package z3 for openSUSE:Factory checked in at 2023-01-23 18:31:50 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/z3 (Old) and /work/SRC/openSUSE:Factory/.z3.new.32243 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "z3" Mon Jan 23 18:31:50 2023 rev:37 rq:1060326 version:4.12.1 Changes: -------- --- /work/SRC/openSUSE:Factory/z3/z3.changes 2023-01-18 13:13:26.633517903 +0100 +++ /work/SRC/openSUSE:Factory/.z3.new.32243/z3.changes 2023-01-23 18:32:10.500147969 +0100 @@ -1,0 +2,7 @@ +Sat Jan 21 17:32:31 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 4.12.1: + * change macos build to use explicit reference to Macos version 11. Hosted + builds are migrating to macos-12 and it broke a user Issue #6539. + +------------------------------------------------------------------- Old: ---- z3-4.12.0.tar.gz New: ---- z3-4.12.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ z3.spec ++++++ --- /var/tmp/diff_new_pack.CTjD4C/_old 2023-01-23 18:32:11.040151706 +0100 +++ /var/tmp/diff_new_pack.CTjD4C/_new 2023-01-23 18:32:11.044151734 +0100 @@ -18,7 +18,7 @@ %define sover 4_12 Name: z3 -Version: 4.12.0 +Version: 4.12.1 Release: 0 Summary: Theorem prover from Microsoft Research License: MIT ++++++ z3-4.12.0.tar.gz -> z3-4.12.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/CMakeLists.txt new/z3-z3-4.12.1/CMakeLists.txt --- old/z3-z3-4.12.0/CMakeLists.txt 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/CMakeLists.txt 2023-01-18 04:10:26.000000000 +0100 @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.4) set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cxx_compiler_flags_overrides.cmake") -project(Z3 VERSION 4.12.0.0 LANGUAGES CXX) +project(Z3 VERSION 4.12.1.0 LANGUAGES CXX) ################################################################################ # Project version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/RELEASE_NOTES.md new/z3-z3-4.12.1/RELEASE_NOTES.md --- old/z3-z3-4.12.0/RELEASE_NOTES.md 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/RELEASE_NOTES.md 2023-01-18 04:10:26.000000000 +0100 @@ -11,6 +11,10 @@ - introduction of simple induction lemmas to handle a limited repertoire of induction proofs. +Version 4.12.1 +============== +- change macos build to use explicit reference to Macos version 11. Hosted builds are migrating to macos-12 and it broke a user Issue #6539. + Version 4.12.0 ============== - add clause logging API. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/scripts/mk_project.py new/z3-z3-4.12.1/scripts/mk_project.py --- old/z3-z3-4.12.0/scripts/mk_project.py 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/scripts/mk_project.py 2023-01-18 04:10:26.000000000 +0100 @@ -8,7 +8,7 @@ from mk_util import * def init_version(): - set_version(4, 12, 0, 0) # express a default build version or pick up ci build version + set_version(4, 12, 1, 0) # express a default build version or pick up ci build version # Z3 Project definition def init_project_def(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/scripts/nightly.yaml new/z3-z3-4.12.1/scripts/nightly.yaml --- old/z3-z3-4.12.0/scripts/nightly.yaml 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/scripts/nightly.yaml 2023-01-18 04:10:26.000000000 +0100 @@ -1,7 +1,7 @@ variables: Major: '4' Minor: '12' - Patch: '0' + Patch: '1' AssemblyVersion: $(Major).$(Minor).$(Patch).$(Build.BuildId) NightlyVersion: $(AssemblyVersion)-$(Build.DefinitionName) @@ -11,7 +11,7 @@ - job: Mac displayName: "Mac Build" pool: - vmImage: "macOS-latest" + vmImage: "macOS-11" steps: - script: python scripts/mk_unix_dist.py --dotnet-key=$(Build.SourcesDirectory)/resources/z3.snk - script: git clone https://github.com/z3prover/z3test z3test @@ -25,7 +25,7 @@ - job: MacArm64 displayName: "Mac ARM64 Build" pool: - vmImage: "macOS-latest" + vmImage: "macOS-11" steps: - script: python scripts/mk_unix_dist.py --dotnet-key=$(Build.SourcesDirectory)/resources/z3.snk --arch=arm64 --os=osx-11.0 - script: git clone https://github.com/z3prover/z3test z3test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/scripts/release.yml new/z3-z3-4.12.1/scripts/release.yml --- old/z3-z3-4.12.0/scripts/release.yml 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/scripts/release.yml 2023-01-18 04:10:26.000000000 +0100 @@ -6,7 +6,7 @@ trigger: none variables: - ReleaseVersion: '4.12.0' + ReleaseVersion: '4.12.1' stages: @@ -17,7 +17,7 @@ - job: MacBuild displayName: "macOS Build" pool: - vmImage: "macOS-latest" + vmImage: "macOS-11" steps: - task: PythonScript@0 displayName: Build @@ -46,7 +46,7 @@ - job: MacBuildArm64 displayName: "macOS ARM64 Build" pool: - vmImage: "macOS-latest" + vmImage: "macOS-11" steps: - script: python scripts/mk_unix_dist.py --dotnet-key=$(Build.SourcesDirectory)/resources/z3.snk --arch=arm64 --os=osx-11.0 - script: git clone https://github.com/z3prover/z3test z3test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/ast/ast.cpp new/z3-z3-4.12.1/src/ast/ast.cpp --- old/z3-z3-4.12.0/src/ast/ast.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/ast/ast.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -1673,6 +1673,7 @@ } void ast_manager::add_lambda_def(func_decl* f, quantifier* q) { + TRACE("model", tout << "add lambda def " << mk_pp(q, *this) << "\n"); m_lambda_defs.insert(f, q); f->get_info()->set_lambda(true); inc_ref(q); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/ast/ast.h new/z3-z3-4.12.1/src/ast/ast.h --- old/z3-z3-4.12.0/src/ast/ast.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/ast/ast.h 2023-01-18 04:10:26.000000000 +0100 @@ -1631,6 +1631,7 @@ void add_lambda_def(func_decl* f, quantifier* q); quantifier* is_lambda_def(func_decl* f); quantifier* is_lambda_def(app* e) { return is_lambda_def(e->get_decl()); } + obj_map<func_decl, quantifier*> const& lambda_defs() const { return m_lambda_defs; } symbol const& lambda_def_qid() const { return m_lambda_def; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/ast/euf/euf_egraph.cpp new/z3-z3-4.12.1/src/ast/euf/euf_egraph.cpp --- old/z3-z3-4.12.0/src/ast/euf/euf_egraph.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/ast/euf/euf_egraph.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -91,9 +91,7 @@ m_scopes.push_back(m_updates.size()); m_region.push_scope(); m_updates.push_back(update_record(m_new_th_eqs_qhead, update_record::new_th_eq_qhead())); - m_updates.push_back(update_record(m_new_lits_qhead, update_record::new_lits_qhead())); } - SASSERT(m_new_lits_qhead <= m_new_lits.size()); SASSERT(m_new_th_eqs_qhead <= m_new_th_eqs.size()); } @@ -156,12 +154,29 @@ } void egraph::add_literal(enode* n, enode* ante) { + /* if (n->bool_var() == sat::null_bool_var) return; - TRACE("euf_verbose", tout << "lit: " << n->get_expr_id() << "\n";); - m_new_lits.push_back(enode_pair(n, ante)); - m_updates.push_back(update_record(update_record::new_lit())); + */ if (!ante) ++m_stats.m_num_eqs; else ++m_stats.m_num_lits; + if (!ante) + m_on_propagate_literal(n, ante); + else if (m.is_true(ante->get_expr()) || m.is_false(ante->get_expr())) { + for (enode* k : enode_class(n)) { + if (k != ante) { + //verbose_stream() << "eq: " << k->value() << " " <<ante->value() << "\n"; + m_on_propagate_literal(k, ante); + } + } + } + else { + for (enode* k : enode_class(n)) { + if (k->value() != ante->value()) { + //verbose_stream() << "eq: " << k->value() << " " <<ante->value() << "\n"; + m_on_propagate_literal(k, ante); + } + } + } } void egraph::new_diseq(enode* n) { @@ -339,7 +354,6 @@ num_scopes -= m_num_scopes; m_num_scopes = 0; - SASSERT(m_new_lits_qhead <= m_new_lits.size()); unsigned old_lim = m_scopes.size() - num_scopes; unsigned num_updates = m_scopes[old_lim]; auto undo_node = [&]() { @@ -378,18 +392,12 @@ SASSERT(p.r1->get_th_var(p.m_th_id) != null_theory_var); p.r1->replace_th_var(p.m_old_th_var, p.m_th_id); break; - case update_record::tag_t::is_new_lit: - m_new_lits.pop_back(); - break; case update_record::tag_t::is_new_th_eq: m_new_th_eqs.pop_back(); break; case update_record::tag_t::is_new_th_eq_qhead: m_new_th_eqs_qhead = p.qhead; break; - case update_record::tag_t::is_new_lits_qhead: - m_new_lits_qhead = p.qhead; - break; case update_record::tag_t::is_inconsistent: m_inconsistent = p.m_inconsistent; break; @@ -424,7 +432,6 @@ m_region.pop_scope(num_scopes); m_to_merge.reset(); - SASSERT(m_new_lits_qhead <= m_new_lits.size()); SASSERT(m_new_th_eqs_qhead <= m_new_th_eqs.size()); // DEBUG_CODE(invariant();); @@ -461,12 +468,6 @@ std::swap(n1, n2); } - if (j.is_congruence() && (m.is_false(r2->get_expr()) || m.is_true(r2->get_expr()))) - add_literal(n1, r2); - if (r2->value() != l_undef && n1->value() == l_undef) - add_literal(n1, r2); - else if (r1->value() != l_undef && n2->value() == l_undef) - add_literal(n2, r1); remove_parents(r1); push_eq(r1, n1, r2->num_parents()); merge_justification(n1, n2, j); @@ -476,6 +477,13 @@ r2->inc_class_size(r1->class_size()); merge_th_eq(r1, r2); reinsert_parents(r1, r2); + if (j.is_congruence() && (m.is_false(r2->get_expr()) || m.is_true(r2->get_expr()))) + add_literal(n1, r2); + else if (n2->value() != l_undef && n1->value() != n2->value()) + add_literal(n1, n2); + else if (n1->value() != l_undef && n2->value() != n1->value()) + add_literal(n2, n1); + for (auto& cb : m_on_merge) cb(r2, r1); } @@ -565,7 +573,6 @@ bool egraph::propagate() { - SASSERT(m_new_lits_qhead <= m_new_lits.size()); SASSERT(m_num_scopes == 0 || m_to_merge.empty()); force_push(); for (unsigned i = 0; i < m_to_merge.size() && m.limit().inc() && !inconsistent(); ++i) { @@ -574,7 +581,6 @@ } m_to_merge.reset(); return - (m_new_lits_qhead < m_new_lits.size()) || (m_new_th_eqs_qhead < m_new_th_eqs.size()) || inconsistent(); } @@ -851,7 +857,6 @@ std::ostream& egraph::display(std::ostream& out) const { out << "updates " << m_updates.size() << "\n"; - out << "newlits " << m_new_lits.size() << " qhead: " << m_new_lits_qhead << "\n"; out << "neweqs " << m_new_th_eqs.size() << " qhead: " << m_new_th_eqs_qhead << "\n"; m_table.display(out); unsigned max_args = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/ast/euf/euf_egraph.h new/z3-z3-4.12.1/src/ast/euf/euf_egraph.h --- old/z3-z3-4.12.0/src/ast/euf/euf_egraph.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/ast/euf/euf_egraph.h 2023-01-18 04:10:26.000000000 +0100 @@ -105,10 +105,8 @@ struct toggle_merge_tf {}; struct add_th_var {}; struct replace_th_var {}; - struct new_lit {}; struct new_th_eq {}; struct new_th_eq_qhead {}; - struct new_lits_qhead {}; struct inconsistent {}; struct value_assignment {}; struct lbl_hash {}; @@ -116,8 +114,8 @@ struct update_children {}; struct set_relevant {}; enum class tag_t { is_set_parent, is_add_node, is_toggle_cgc, is_toggle_merge_tf, is_update_children, - is_add_th_var, is_replace_th_var, is_new_lit, is_new_th_eq, - is_lbl_hash, is_new_th_eq_qhead, is_new_lits_qhead, + is_add_th_var, is_replace_th_var, is_new_th_eq, + is_lbl_hash, is_new_th_eq_qhead, is_inconsistent, is_value_assignment, is_lbl_set, is_set_relevant }; tag_t tag; enode* r1; @@ -145,14 +143,10 @@ tag(tag_t::is_add_th_var), r1(n), n1(nullptr), r2_num_parents(id) {} update_record(enode* n, theory_id id, theory_var v, replace_th_var) : tag(tag_t::is_replace_th_var), r1(n), n1(nullptr), m_th_id(id), m_old_th_var(v) {} - update_record(new_lit) : - tag(tag_t::is_new_lit), r1(nullptr), n1(nullptr), r2_num_parents(0) {} update_record(new_th_eq) : tag(tag_t::is_new_th_eq), r1(nullptr), n1(nullptr), r2_num_parents(0) {} update_record(unsigned qh, new_th_eq_qhead): tag(tag_t::is_new_th_eq_qhead), r1(nullptr), n1(nullptr), qhead(qh) {} - update_record(unsigned qh, new_lits_qhead): - tag(tag_t::is_new_lits_qhead), r1(nullptr), n1(nullptr), qhead(qh) {} update_record(bool inc, inconsistent) : tag(tag_t::is_inconsistent), r1(nullptr), n1(nullptr), m_inconsistent(inc) {} update_record(enode* n, value_assignment) : @@ -187,9 +181,7 @@ enode *m_n1 = nullptr; enode *m_n2 = nullptr; justification m_justification; - unsigned m_new_lits_qhead = 0; unsigned m_new_th_eqs_qhead = 0; - svector<enode_pair> m_new_lits; svector<th_eq> m_new_th_eqs; bool_vector m_th_propagates_diseqs; enode_vector m_todo; @@ -198,7 +190,8 @@ bool m_default_relevant = true; uint64_t m_congruence_timestamp = 0; - std::vector<std::function<void(enode*,enode*)>> m_on_merge; + std::vector<std::function<void(enode*,enode*)>> m_on_merge; + std::function<void(enode*, enode*)> m_on_propagate_literal; std::function<void(enode*)> m_on_make; std::function<void(expr*,expr*,expr*)> m_used_eq; std::function<void(app*,app*)> m_used_cc; @@ -290,11 +283,8 @@ is an equality consequence. */ void add_th_diseq(theory_id id, theory_var v1, theory_var v2, expr* eq); - bool has_literal() const { return m_new_lits_qhead < m_new_lits.size(); } bool has_th_eq() const { return m_new_th_eqs_qhead < m_new_th_eqs.size(); } - enode_pair get_literal() const { return m_new_lits[m_new_lits_qhead]; } th_eq get_th_eq() const { return m_new_th_eqs[m_new_th_eqs_qhead]; } - void next_literal() { force_push(); SASSERT(m_new_lits_qhead < m_new_lits.size()); m_new_lits_qhead++; } void next_th_eq() { force_push(); SASSERT(m_new_th_eqs_qhead < m_new_th_eqs.size()); m_new_th_eqs_qhead++; } void set_lbl_hash(enode* n); @@ -311,6 +301,7 @@ void set_default_relevant(bool b) { m_default_relevant = b; } void set_on_merge(std::function<void(enode* root,enode* other)>& on_merge) { m_on_merge.push_back(on_merge); } + void set_on_propagate(std::function<void(enode* lit,enode* ante)>& on_propagate) { m_on_propagate_literal = on_propagate; } void set_on_make(std::function<void(enode* n)>& on_make) { m_on_make = on_make; } void set_used_eq(std::function<void(expr*,expr*,expr*)>& used_eq) { m_used_eq = used_eq; } void set_used_cc(std::function<void(app*,app*)>& used_cc) { m_used_cc = used_cc; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/ast/simplifiers/dependent_expr_state.cpp new/z3-z3-4.12.1/src/ast/simplifiers/dependent_expr_state.cpp --- old/z3-z3-4.12.0/src/ast/simplifiers/dependent_expr_state.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/ast/simplifiers/dependent_expr_state.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -84,6 +84,23 @@ } /** +* Freeze all functions used in lambda defined declarations +*/ +void dependent_expr_state::freeze_lambda() { + auto& m = m_frozen_trail.get_manager(); + unsigned sz = m.lambda_defs().size(); + if (m_num_lambdas >= sz) + return; + + ast_mark visited; + for (auto const& [f, body] : m.lambda_defs()) + freeze_terms(body, false, visited); + m_trail.push(value_trail(m_num_lambdas)); + m_num_lambdas = sz; +} + + +/** * The current qhead is to be updated to qtail. * Before this update, freeze all functions appearing in formulas. */ @@ -100,8 +117,9 @@ if (m_suffix_frozen) return; m_suffix_frozen = true; - auto& m = m_frozen_trail.get_manager(); freeze_recfun(); + freeze_lambda(); + auto& m = m_frozen_trail.get_manager(); ast_mark visited; ptr_vector<expr> es; for (unsigned i = qhead(); i < qtail(); ++i) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/ast/simplifiers/dependent_expr_state.h new/z3-z3-4.12.1/src/ast/simplifiers/dependent_expr_state.h --- old/z3-z3-4.12.0/src/ast/simplifiers/dependent_expr_state.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/ast/simplifiers/dependent_expr_state.h 2023-01-18 04:10:26.000000000 +0100 @@ -43,14 +43,14 @@ class dependent_expr_state { unsigned m_qhead = 0; bool m_suffix_frozen = false; - unsigned m_num_recfun = 0; + unsigned m_num_recfun = 0, m_num_lambdas = 0; lbool m_has_quantifiers = l_undef; ast_mark m_frozen; func_decl_ref_vector m_frozen_trail; void freeze_prefix(); void freeze_recfun(); + void freeze_lambda(); void freeze_terms(expr* term, bool only_as_array, ast_mark& visited); - void freeze(expr* term); void freeze(func_decl* f); struct thaw : public trail { unsigned sz; @@ -88,6 +88,7 @@ /** * Freeze internal functions */ + void freeze(expr* term); bool frozen(func_decl* f) const { return m_frozen.is_marked(f); } bool frozen(expr* f) const { return is_app(f) && m_frozen.is_marked(to_app(f)->get_decl()); } void freeze_suffix(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/ast/simplifiers/max_bv_sharing.cpp new/z3-z3-4.12.1/src/ast/simplifiers/max_bv_sharing.cpp --- old/z3-z3-4.12.0/src/ast/simplifiers/max_bv_sharing.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/ast/simplifiers/max_bv_sharing.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -22,6 +22,7 @@ #include "ast/rewriter/maximize_ac_sharing.h" #include "ast/simplifiers/dependent_expr_state.h" +#include "ast/rewriter/rewriter_def.h" class max_bv_sharing : public dependent_expr_simplifier { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/ast/simplifiers/model_reconstruction_trail.cpp new/z3-z3-4.12.1/src/ast/simplifiers/model_reconstruction_trail.cpp --- old/z3-z3-4.12.0/src/ast/simplifiers/model_reconstruction_trail.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/ast/simplifiers/model_reconstruction_trail.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -23,11 +23,13 @@ // substitutions that use variables from the dependent expressions. // TODO: add filters to skip sections of the trail that do not touch the current free variables. -void model_reconstruction_trail::replay(unsigned qhead, dependent_expr_state& st) { +void model_reconstruction_trail::replay(unsigned qhead, expr_ref_vector& assumptions, dependent_expr_state& st) { ast_mark free_vars; scoped_ptr<expr_replacer> rp = mk_default_expr_replacer(m, false); - for (unsigned i = qhead; i < st.qtail(); ++i) + for (unsigned i = qhead; i < st.qtail(); ++i) add_vars(st[i], free_vars); + for (expr* a : assumptions) + add_vars(a, free_vars); for (auto& t : m_trail) { if (!t->m_active) @@ -63,7 +65,7 @@ mrp.insert(head, t->m_def, t->m_dep); dependent_expr de(m, t->m_def, nullptr, t->m_dep); add_vars(de, free_vars); - + for (unsigned i = qhead; i < st.qtail(); ++i) { auto [f, p, dep1] = st[i](); expr_ref g(m); @@ -73,6 +75,15 @@ if (f != g) st.update(i, dependent_expr(m, g, nullptr, dep2)); } + for (unsigned i = 0; i < assumptions.size(); ++i) { + expr* a = assumptions.get(i); + expr_ref g(m); + expr_dependency_ref dep(m); + mrp(a, nullptr, g, dep); + if (a != g) + assumptions[i] = g; + // ignore dep. + } continue; } @@ -103,7 +114,15 @@ CTRACE("simplifier", f != g, tout << "updated " << mk_pp(g, m) << "\n"); add_vars(d, free_vars); st.update(i, d); - } + } + + for (unsigned i = 0; i < assumptions.size(); ++i) { + expr* a = assumptions.get(i); + auto [g, dep2] = rp->replace_with_dep(a); + if (a != g) + assumptions[i] = g; + // ignore dep. + } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/ast/simplifiers/model_reconstruction_trail.h new/z3-z3-4.12.1/src/ast/simplifiers/model_reconstruction_trail.h --- old/z3-z3-4.12.0/src/ast/simplifiers/model_reconstruction_trail.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/ast/simplifiers/model_reconstruction_trail.h 2023-01-18 04:10:26.000000000 +0100 @@ -74,13 +74,17 @@ scoped_ptr_vector<entry> m_trail; unsigned m_trail_index = 0; - void add_vars(dependent_expr const& d, ast_mark& free_vars) { - for (expr* t : subterms::all(expr_ref(d.fml(), d.get_manager()))) + void add_vars(expr* e, ast_mark& free_vars) { + for (expr* t : subterms::all(expr_ref(e, m))) free_vars.mark(t, true); } + + void add_vars(dependent_expr const& d, ast_mark& free_vars) { + add_vars(d.fml(), free_vars); + } bool intersects(ast_mark const& free_vars, dependent_expr const& d) { - expr_ref term(d.fml(), d.get_manager()); + expr_ref term(d.fml(), m); auto iter = subterms::all(term); return any_of(iter, [&](expr* t) { return free_vars.is_marked(t); }); } @@ -126,7 +130,7 @@ * register a new depedent expression, update the trail * by removing substitutions that are not equivalence preserving. */ - void replay(unsigned qhead, dependent_expr_state& fmls); + void replay(unsigned qhead, expr_ref_vector& assumptions, dependent_expr_state& fmls); /** * retrieve the current model converter corresponding to chaining substitutions from the trail. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/ast/simplifiers/solve_eqs.cpp new/z3-z3-4.12.1/src/ast/simplifiers/solve_eqs.cpp --- old/z3-z3-4.12.0/src/ast/simplifiers/solve_eqs.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/ast/simplifiers/solve_eqs.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -116,10 +116,10 @@ for (auto const& eq : m_next[j]) { auto const& [orig, v, t, d] = eq; SASSERT(j == var2id(v)); - bool is_safe = true; if (m_fmls.frozen(v)) continue; + bool is_safe = true; unsigned todo_sz = todo.size(); // determine if substitution is safe. @@ -223,6 +223,8 @@ void solve_eqs::reduce() { + m_fmls.freeze_suffix(); + for (extract_eq* ex : m_extract_plugins) ex->pre_process(m_fmls); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/nlsat/tactic/nlsat_tactic.h new/z3-z3-4.12.1/src/nlsat/tactic/nlsat_tactic.h --- old/z3-z3-4.12.0/src/nlsat/tactic/nlsat_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/nlsat/tactic/nlsat_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -13,7 +13,24 @@ Leonardo (leonardo) 2012-01-02 -Notes: +Tactic Documentation: + +## Tactic nlsat + +### Short Description + +(try to) solve goal using a nonlinear arithmetic solver + +### Example + +```z3 +(declare-const x Real) +(declare-const y Real) +(assert (> (* x x) (* y x))) +(assert (> x 0)) +(assert (< y 1)) +(apply (then simplify purify-arith nlsat)) +``` --*/ #pragma once diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/nlsat/tactic/qfnra_nlsat_tactic.h new/z3-z3-4.12.1/src/nlsat/tactic/qfnra_nlsat_tactic.h --- old/z3-z3-4.12.0/src/nlsat/tactic/qfnra_nlsat_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/nlsat/tactic/qfnra_nlsat_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -13,7 +13,26 @@ Leonardo (leonardo) 2012-01-23 -Notes: +Tactic Documentation: + +## Tactic qfnra-nlsat + +### Short Description + +Self-contained tactic that attempts to solve goal using a nonlinear arithmetic solver. +It first applies tactics, such as `purify-arith` to convert the goal into a format +where the `nlsat` tactic applies. + +### Example + +```z3 +(declare-const x Real) +(declare-const y Real) +(assert (> (* x x) (* y x))) +(assert (> x 0)) +(assert (< y 1)) +(apply qfnra-nlsat) +``` --*/ #pragma once diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/qe/qe_tactic.h new/z3-z3-4.12.1/src/qe/qe_tactic.h --- old/z3-z3-4.12.0/src/qe/qe_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/qe/qe_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -13,9 +13,33 @@ Leonardo de Moura (leonardo) 2011-12-28. -Revision History: +Tactic Documentation + +## Tactic qe + +### Short Description + +Apply quantifier elimination on quantified sub-formulas. + +### Long Description + +The tactic applies quantifier elimination procedures on quantified sub-formulas. +It relies on theory plugins that can perform quanifier elimination for selected theories. +These plugins include Booleans, bit-vectors, arithmetic (linear), arrays, and data-types (term algebra). +It performs feasibility checks on cases to throttle the set of sub-formulas where quantifier elimination +is applied. + +### Example + +```z3 +(declare-const x Int) +(declare-const y Int) +(assert (exists ((z Int)) (and (<= x (* 2 z)) (<= (* 3 z) y)))) +(apply qe) +``` --*/ + #pragma once #include "util/params.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/sat/sat_solver/sat_smt_preprocess.cpp new/z3-z3-4.12.1/src/sat/sat_solver/sat_smt_preprocess.cpp --- old/z3-z3-4.12.0/src/sat/sat_solver/sat_smt_preprocess.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/sat/sat_solver/sat_smt_preprocess.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -16,6 +16,7 @@ --*/ +#include "ast/rewriter/rewriter_def.h" #include "ast/simplifiers/bit_blaster.h" #include "ast/simplifiers/max_bv_sharing.h" #include "ast/simplifiers/card2bv.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/sat/sat_solver/sat_smt_solver.cpp new/z3-z3-4.12.1/src/sat/sat_solver/sat_smt_solver.cpp --- old/z3-z3-4.12.0/src/sat/sat_solver/sat_smt_solver.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/sat/sat_solver/sat_smt_solver.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -70,7 +70,7 @@ return out; } void append(generic_model_converter& mc) { model_trail().append(mc); } - void replay(unsigned qhead) { m_reconstruction_trail.replay(qhead, *this); } + void replay(unsigned qhead, expr_ref_vector& assumptions) { m_reconstruction_trail.replay(qhead, assumptions, *this); } void flatten_suffix() override { expr_mark seen; unsigned j = qhead(); @@ -237,8 +237,10 @@ expr_ref_vector assumptions(m); for (unsigned i = 0; i < sz; ++i) assumptions.push_back(ensure_literal(_assumptions[i])); + for (expr* a : assumptions) + m_preprocess_state.freeze(a); TRACE("sat", tout << assumptions << "\n";); - lbool r = internalize_formulas(); + lbool r = internalize_formulas(assumptions); if (r != l_true) return r; @@ -271,7 +273,8 @@ void push() override { try { - internalize_formulas(); + expr_ref_vector none(m); + internalize_formulas(none); } catch (...) { push_internal(); @@ -430,7 +433,7 @@ } expr_ref_vector cube(expr_ref_vector& vs, unsigned backtrack_level) override { - lbool r = internalize_formulas(); + lbool r = internalize_formulas(vs); if (r != l_true) { IF_VERBOSE(0, verbose_stream() << "internalize produced " << r << "\n"); return expr_ref_vector(m); @@ -561,7 +564,8 @@ void convert_internalized() { m_solver.pop_to_base_level(); - internalize_formulas(); + expr_ref_vector none(m); + internalize_formulas(none); if (!is_internalized() || m_internalized_converted) return; sat2goal s2g; @@ -641,9 +645,9 @@ add_assumption(a); } - lbool internalize_formulas() { + lbool internalize_formulas(expr_ref_vector& assumptions) { - if (is_internalized()) + if (is_internalized() && assumptions.empty()) return l_true; unsigned qhead = m_preprocess_state.qhead(); @@ -651,7 +655,7 @@ m_internalized_converted = false; - m_preprocess_state.replay(qhead); + m_preprocess_state.replay(qhead, assumptions); m_preprocess.reduce(); if (!m.inc()) return l_undef; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/sat/smt/arith_diagnostics.cpp new/z3-z3-4.12.1/src/sat/smt/arith_diagnostics.cpp --- old/z3-z3-4.12.0/src/sat/smt/arith_diagnostics.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/sat/smt/arith_diagnostics.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -124,6 +124,19 @@ return m_arith_hint.mk(ctx); } + arith_proof_hint const* solver::explain_conflict(sat::literal_vector const& core, euf::enode_pair_vector const& eqs) { + arith_proof_hint* hint = nullptr; + if (ctx.use_drat()) { + m_arith_hint.set_type(ctx, hint_type::farkas_h); + for (auto lit : core) + m_arith_hint.add_lit(rational::one(), lit); + for (auto const& [a,b] : eqs) + m_arith_hint.add_eq(a, b); + hint = m_arith_hint.mk(ctx); + } + return hint; + } + arith_proof_hint const* solver::explain_implied_eq(lp::explanation const& e, euf::enode* a, euf::enode* b) { if (!ctx.use_drat()) return nullptr; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/sat/smt/arith_solver.cpp new/z3-z3-4.12.1/src/sat/smt/arith_solver.cpp --- old/z3-z3-4.12.0/src/sat/smt/arith_solver.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/sat/smt/arith_solver.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -1196,26 +1196,31 @@ void solver::set_conflict_or_lemma(literal_vector const& core, bool is_conflict) { reset_evidence(); m_core.append(core); - - ++m_num_conflicts; - ++m_stats.m_conflicts; for (auto ev : m_explanation) set_evidence(ev.ci()); + TRACE("arith", tout << "Lemma - " << (is_conflict ? "conflict" : "propagation") << "\n"; for (literal c : m_core) tout << literal2expr(c) << "\n"; for (auto p : m_eqs) tout << ctx.bpp(p.first) << " == " << ctx.bpp(p.second) << "\n";); - DEBUG_CODE( - if (is_conflict) { - for (literal c : m_core) VERIFY(s().value(c) == l_true); - for (auto p : m_eqs) VERIFY(p.first->get_root() == p.second->get_root()); - }); - for (auto const& eq : m_eqs) - m_core.push_back(ctx.mk_literal(m.mk_eq(eq.first->get_expr(), eq.second->get_expr()))); - for (literal& c : m_core) - c.neg(); - add_redundant(m_core, explain(hint_type::farkas_h)); + if (is_conflict) { + DEBUG_CODE( + for (literal c : m_core) VERIFY(s().value(c) == l_true); + for (auto p : m_eqs) VERIFY(p.first->get_root() == p.second->get_root())); + ++m_num_conflicts; + ++m_stats.m_conflicts; + auto* hint = explain_conflict(m_core, m_eqs); + ctx.set_conflict(euf::th_explain::conflict(*this, m_core, m_eqs, hint)); + } + else { + for (auto const& eq : m_eqs) + m_core.push_back(ctx.mk_literal(m.mk_eq(eq.first->get_expr(), eq.second->get_expr()))); + for (literal& c : m_core) + c.neg(); + + add_redundant(m_core, explain(hint_type::farkas_h)); + } } bool solver::is_infeasible() const { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/sat/smt/arith_solver.h new/z3-z3-4.12.1/src/sat/smt/arith_solver.h --- old/z3-z3-4.12.0/src/sat/smt/arith_solver.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/sat/smt/arith_solver.h 2023-01-18 04:10:26.000000000 +0100 @@ -478,6 +478,7 @@ arith_proof_hint const* explain(hint_type ty, sat::literal lit = sat::null_literal); arith_proof_hint const* explain_implied_eq(lp::explanation const& e, euf::enode* a, euf::enode* b); arith_proof_hint const* explain_trichotomy(sat::literal le, sat::literal ge, sat::literal eq); + arith_proof_hint const* explain_conflict(sat::literal_vector const& core, euf::enode_pair_vector const& eqs); void explain_assumptions(lp::explanation const& e); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/sat/smt/euf_solver.cpp new/z3-z3-4.12.1/src/sat/smt/euf_solver.cpp --- old/z3-z3-4.12.0/src/sat/smt/euf_solver.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/sat/smt/euf_solver.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -63,6 +63,11 @@ }; m_egraph.set_display_justification(disp); + std::function<void(euf::enode* n, euf::enode* ante)> on_literal = [&](enode* n, enode* ante) { + propagate_literal(n, ante); + }; + m_egraph.set_on_propagate(on_literal); + if (m_relevancy.enabled()) { std::function<void(euf::enode* root, euf::enode* other)> on_merge = [&](enode* root, enode* other) { @@ -414,7 +419,6 @@ } bool propagated1 = false; if (m_egraph.propagate()) { - propagate_literals(); propagate_th_eqs(); propagated1 = true; } @@ -435,52 +439,52 @@ return propagated; } - void solver::propagate_literals() { - for (; m_egraph.has_literal() && !s().inconsistent() && !m_egraph.inconsistent(); m_egraph.next_literal()) { - auto [n, ante] = m_egraph.get_literal(); - expr* e = n->get_expr(); - expr* a = nullptr, *b = nullptr; - bool_var v = n->bool_var(); - SASSERT(m.is_bool(e)); - size_t cnstr; - literal lit; - if (!ante) { - VERIFY(m.is_eq(e, a, b)); - cnstr = eq_constraint().to_index(); - lit = literal(v, false); - } - else { - // - // There are the following three cases for propagation of literals - // - // 1. n == ante is true from equallity, ante = true/false - // 2. n == ante is true from equality, value(ante) != l_undef - // 3. value(n) != l_undef, ante = true/false, merge_tf is set on n - // - lbool val = ante->value(); - if (val == l_undef) { - SASSERT(m.is_value(ante->get_expr())); - val = m.is_true(ante->get_expr()) ? l_true : l_false; - } - auto& c = lit_constraint(ante); - cnstr = c.to_index(); - lit = literal(v, val == l_false); - } - unsigned lvl = s().scope_lvl(); - - CTRACE("euf", s().value(lit) != l_true, tout << lit << " " << s().value(lit) << "@" << lvl << " " << mk_bounded_pp(a, m) << " = " << mk_bounded_pp(b, m) << "\n";); - if (s().value(lit) == l_false && m_ackerman && a && b) - m_ackerman->cg_conflict_eh(a, b); - switch (s().value(lit)) { - case l_true: - if (n->merge_tf() && !m.is_value(n->get_root()->get_expr())) - m_egraph.merge(n, ante, to_ptr(lit)); - break; - case l_undef: - case l_false: - s().assign(lit, sat::justification::mk_ext_justification(lvl, cnstr)); - break; + + void solver::propagate_literal(enode* n, enode* ante) { + expr* e = n->get_expr(); + expr* a = nullptr, *b = nullptr; + bool_var v = n->bool_var(); + if (v == sat::null_bool_var) + return; + SASSERT(m.is_bool(e)); + size_t cnstr; + literal lit; + if (!ante) { + VERIFY(m.is_eq(e, a, b)); + cnstr = eq_constraint().to_index(); + lit = literal(v, false); + } + else { + // + // There are the following three cases for propagation of literals + // + // 1. n == ante is true from equallity, ante = true/false + // 2. n == ante is true from equality, value(ante) != l_undef + // 3. value(n) != l_undef, ante = true/false, merge_tf is set on n + // + lbool val = ante->value(); + if (val == l_undef) { + SASSERT(m.is_value(ante->get_expr())); + val = m.is_true(ante->get_expr()) ? l_true : l_false; } + auto& c = lit_constraint(ante); + cnstr = c.to_index(); + lit = literal(v, val == l_false); + } + unsigned lvl = s().scope_lvl(); + + CTRACE("euf", s().value(lit) != l_true, tout << lit << " " << s().value(lit) << "@" << lvl << " " << mk_bounded_pp(a, m) << " = " << mk_bounded_pp(b, m) << "\n";); + if (s().value(lit) == l_false && m_ackerman && a && b) + m_ackerman->cg_conflict_eh(a, b); + switch (s().value(lit)) { + case l_true: + if (n->merge_tf() && !m.is_value(n->get_root()->get_expr())) + m_egraph.merge(n, ante, to_ptr(lit)); + break; + case l_undef: + case l_false: + s().assign(lit, sat::justification::mk_ext_justification(lvl, cnstr)); + break; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/sat/smt/euf_solver.h new/z3-z3-4.12.1/src/sat/smt/euf_solver.h --- old/z3-z3-4.12.0/src/sat/smt/euf_solver.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/sat/smt/euf_solver.h 2023-01-18 04:10:26.000000000 +0100 @@ -206,7 +206,7 @@ void validate_model(model& mdl); // solving - void propagate_literals(); + void propagate_literal(enode* n, enode* ante); void propagate_th_eqs(); bool is_self_propagated(th_eq const& e); void get_antecedents(literal l, constraint& j, literal_vector& r, bool probing); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/sat/tactic/sat_tactic.h new/z3-z3-4.12.1/src/sat/tactic/sat_tactic.h --- old/z3-z3-4.12.0/src/sat/tactic/sat_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/sat/tactic/sat_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -13,7 +13,36 @@ Leonardo (leonardo) 2011-10-26 -Notes: +Tactic Documentation: + +## Tactic sat + +### Short Description + +Try to solve goal using a SAT solver + +## Tactic sat-preprocess + +### Short Description + +Apply SAT solver preprocessing procedures (bounded resolution, Boolean constant propagation, 2-SAT, subsumption, subsumption resolution). + +### Example + +```z3 +(declare-const a Bool) +(declare-const b Bool) +(declare-const c Bool) +(declare-const d Bool) +(declare-const e Bool) +(declare-const f Bool) +(declare-fun p (Bool) Bool) +(assert (=> a b)) +(assert (=> b c)) +(assert a) +(assert (not c)) +(apply sat-preprocess) +``` --*/ #pragma once diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/smt/smt_context.cpp new/z3-z3-4.12.1/src/smt/smt_context.cpp --- old/z3-z3-4.12.0/src/smt/smt_context.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/smt/smt_context.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -866,6 +866,7 @@ SASSERT(curr != m_false_enode); bool_var v = enode2bool_var(curr); literal l(v, sign); + CTRACE("propagate", (get_assignment(l) != l_true), tout << enode_pp(curr, *this) << " " << l << "\n"); if (get_assignment(l) != l_true) assign(l, mk_justification(eq_root_propagation_justification(curr))); curr = curr->m_next; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/smt/smt_model_checker.cpp new/z3-z3-4.12.1/src/smt/smt_model_checker.cpp --- old/z3-z3-4.12.0/src/smt/smt_model_checker.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/smt/smt_model_checker.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -82,22 +82,18 @@ app* fresh_term; if (is_app(val) && to_app(val)->get_num_args() > 0) { ptr_buffer<expr> args; - for (expr* arg : *to_app(val)) { + for (expr* arg : *to_app(val)) args.push_back(get_type_compatible_term(arg)); - } fresh_term = m.mk_app(to_app(val)->get_decl(), args.size(), args.data()); } else { expr * sk_term = get_term_from_ctx(val); - if (sk_term != nullptr) { + if (sk_term != nullptr) return sk_term; - } - for (expr* f : m_fresh_exprs) { - if (f->get_sort() == val->get_sort()) { + for (expr* f : m_fresh_exprs) + if (f->get_sort() == val->get_sort()) return f; - } - } fresh_term = m.mk_fresh_const("sk", val->get_sort()); } m_fresh_exprs.push_back(fresh_term); @@ -106,13 +102,16 @@ } void model_checker::init_value2expr() { + if (m_value2expr.empty()) { // populate m_value2expr for (auto const& kv : *m_root2value) { enode * n = kv.m_key; expr * val = kv.m_value; n = n->get_eq_enode_with_min_gen(); - m_value2expr.insert(val, n->get_expr()); + expr* e = n->get_expr(); + if (!m.is_value(e)) + m_value2expr.insert(val, e); } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/smt/smt_model_generator.cpp new/z3-z3-4.12.1/src/smt/smt_model_generator.cpp --- old/z3-z3-4.12.0/src/smt/smt_model_generator.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/smt/smt_model_generator.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -330,27 +330,32 @@ enode * n = curr.get_enode(); SASSERT(n->get_root() == n); TRACE("mg_top_sort", tout << curr << "\n";); - dependencies.reset(); - dependency_values.reset(); - model_value_proc * proc = root2proc[n]; - SASSERT(proc); - proc->get_dependencies(dependencies); - for (model_value_dependency const& d : dependencies) { - if (d.is_fresh_value()) { - CTRACE("mg_top_sort", !d.get_value()->get_value(), - tout << "#" << n->get_owner_id() << " " << mk_pp(n->get_expr(), m) << " -> " << d << "\n";); - SASSERT(d.get_value()->get_value()); - dependency_values.push_back(d.get_value()->get_value()); - } - else { - enode * child = d.get_enode(); - TRACE("mg_top_sort", tout << "#" << n->get_owner_id() << " (" << mk_pp(n->get_expr(), m) << "): " - << mk_pp(child->get_expr(), m) << " " << mk_pp(child->get_root()->get_expr(), m) << "\n";); - child = child->get_root(); - dependency_values.push_back(m_root2value[child]); + app* val = nullptr; + if (m.is_value(n->get_expr())) + val = to_app(n->get_expr()); + else { + dependencies.reset(); + dependency_values.reset(); + model_value_proc * proc = root2proc[n]; + SASSERT(proc); + proc->get_dependencies(dependencies); + for (model_value_dependency const& d : dependencies) { + if (d.is_fresh_value()) { + CTRACE("mg_top_sort", !d.get_value()->get_value(), + tout << "#" << n->get_owner_id() << " " << mk_pp(n->get_expr(), m) << " -> " << d << "\n";); + SASSERT(d.get_value()->get_value()); + dependency_values.push_back(d.get_value()->get_value()); + } + else { + enode * child = d.get_enode(); + TRACE("mg_top_sort", tout << "#" << n->get_owner_id() << " (" << mk_pp(n->get_expr(), m) << "): " + << mk_pp(child->get_expr(), m) << " " << mk_pp(child->get_root()->get_expr(), m) << "\n";); + child = child->get_root(); + dependency_values.push_back(m_root2value[child]); + } } + val = proc->mk_value(*this, dependency_values); } - app * val = proc->mk_value(*this, dependency_values); register_value(val); m_asts.push_back(val); m_root2value.insert(n, val); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/smt/tactic/ctx_solver_simplify_tactic.h new/z3-z3-4.12.1/src/smt/tactic/ctx_solver_simplify_tactic.h --- old/z3-z3-4.12.0/src/smt/tactic/ctx_solver_simplify_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/smt/tactic/ctx_solver_simplify_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -13,7 +13,17 @@ Nikolaj (nbjorner) 2012-3-6 -Notes: +Tactic Documentation: + +## Tactic ctx-solver-simplify + +### Short Description + +A heavy handed version of `ctx-simplify`. It applies SMT checks on sub-formulas to check +if they can be simplified to `true` or `false` within their context. +Note that a sub-formula may occur within multiple contexts due to shared sub-terms. +In this case the tactic is partial and simplifies a limited number of context occurrences. + --*/ #pragma once diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/smt/tactic/unit_subsumption_tactic.h new/z3-z3-4.12.1/src/smt/tactic/unit_subsumption_tactic.h --- old/z3-z3-4.12.0/src/smt/tactic/unit_subsumption_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/smt/tactic/unit_subsumption_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -13,12 +13,20 @@ Nikolaj Bjorner (nbjorner) 2012-9-6 -Notes: +Tactic Documentation: - Background: PDR generates several clauses that subsume each-other. - Simplify a goal assuming it is a conjunction of clauses. - Subsumed clauses are simplified by using unit-propagation - It uses the smt_context for the solver. +## Tactic unit-subsume-simplify + +### Short Description + +implify goal using subsumption based on unit propagation + +### Long Description + +Background: PDR generates several clauses that subsume each-other. +Simplify a goal assuming it is a conjunction of clauses. +Subsumed clauses are simplified by using unit-propagation +It uses the default SMT solver. --*/ #pragma once diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/tactic/arith/arith_bounds_tactic.h new/z3-z3-4.12.1/src/tactic/arith/arith_bounds_tactic.h --- old/z3-z3-4.12.0/src/tactic/arith/arith_bounds_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/tactic/arith/arith_bounds_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -27,6 +27,8 @@ for assembling bounds, but it does not have a way to check for subsumption of atoms. +## Tactic arith-bounds + --*/ #pragma once #include "tactic/tactic.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/tactic/core/cofactor_elim_term_ite.cpp new/z3-z3-4.12.1/src/tactic/core/cofactor_elim_term_ite.cpp --- old/z3-z3-4.12.0/src/tactic/core/cofactor_elim_term_ite.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/tactic/core/cofactor_elim_term_ite.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -128,9 +128,8 @@ fr.m_first = false; bool visited = true; if (is_app(t)) { - unsigned num_args = to_app(t)->get_num_args(); - for (unsigned i = 0; i < num_args; i++) - visit(to_app(t)->get_arg(i), form_ctx, visited); + for (expr* arg : *to_app(t)) + visit(arg, form_ctx, visited); } // ignoring quantifiers if (!visited) @@ -138,16 +137,13 @@ } if (is_app(t)) { - unsigned num_args = to_app(t)->get_num_args(); - unsigned i; - for (i = 0; i < num_args; i++) { - if (m_has_term_ite.is_marked(to_app(t)->get_arg(i))) + for (expr* arg : *to_app(t)) { + if (m_has_term_ite.is_marked(arg)) { + m_has_term_ite.mark(t); + TRACE("cofactor", tout << "saving candidate: " << form_ctx << "\n" << mk_bounded_pp(t, m) << "\n";); + save_candidate(t, form_ctx); break; - } - if (i < num_args) { - m_has_term_ite.mark(t); - TRACE("cofactor", tout << "saving candidate: " << form_ctx << "\n" << mk_bounded_pp(t, m) << "\n";); - save_candidate(t, form_ctx); + } } } else { @@ -284,16 +280,14 @@ } expr * best = nullptr; unsigned best_occs = 0; - obj_map<expr, unsigned>::iterator it = occs.begin(); - obj_map<expr, unsigned>::iterator end = occs.end(); - for (; it != end; ++it) { + for (auto const& [k, v] : occs) { if ((!best) || - (get_depth(it->m_key) < get_depth(best)) || - (get_depth(it->m_key) == get_depth(best) && it->m_value > best_occs) || + (get_depth(k) < get_depth(best)) || + (get_depth(k) == get_depth(best) && v > best_occs) || // break ties by giving preference to equalities - (get_depth(it->m_key) == get_depth(best) && it->m_value == best_occs && m.is_eq(it->m_key) && !m.is_eq(best))) { - best = it->m_key; - best_occs = it->m_value; + (get_depth(k) == get_depth(best) && v == best_occs && m.is_eq(k) && !m.is_eq(best))) { + best = k; + best_occs = v; } } visited.reset(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/tactic/core/cofactor_term_ite_tactic.h new/z3-z3-4.12.1/src/tactic/core/cofactor_term_ite_tactic.h --- old/z3-z3-4.12.0/src/tactic/core/cofactor_term_ite_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/tactic/core/cofactor_term_ite_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -8,13 +8,22 @@ Abstract: Wrap cofactor_elim_term_ite as a tactic. - Eliminate (ground) term if-then-else's using cofactors. Author: Leonardo de Moura (leonardo) 2012-02-20. -Revision History: +Tactic Documentation: + +## Tactic cofactor-term-ite + +### Short Description +Eliminate (ground) term if-then-else's using cofactors. +It hoists nested if-then-else expressions inside terms into the top level of the formula. + +### Notes + +* does not support proofs, does not support cores --*/ #pragma once diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/tactic/core/euf_completion_tactic.h new/z3-z3-4.12.1/src/tactic/core/euf_completion_tactic.h --- old/z3-z3-4.12.0/src/tactic/core/euf_completion_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/tactic/core/euf_completion_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -13,6 +13,22 @@ Nikolaj Bjorner (nbjorner) 2022-10-30 +Tactic Documentation: + +## Tactic euf-completion + +### Short Description + +Uses the ground equalities as a rewrite system. The formulas are simplified +using the rewrite system. + +### Long Description + +The tactic uses congruence closure to represent and orient the rewrite system. Equalities from the formula +are inserted in the an E-graph (congruence closure structure) and then a representative that is most shallow +is extracted. + + --*/ #pragma once diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/tactic/core/reduce_args_tactic.h new/z3-z3-4.12.1/src/tactic/core/reduce_args_tactic.h --- old/z3-z3-4.12.0/src/tactic/core/reduce_args_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/tactic/core/reduce_args_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -34,31 +34,10 @@ Since $f_a$, $f_b$, $f_c$ are new symbols, satisfiability is preserved. This transformation is very similar in spirit to the Ackermman's reduction. +For each function `f` and argument position of `f` it checks if all occurrences of `f` uses a value at position `i`. +The values may be different, but all occurrences have to be values for the reduction to be applicable. +It creates a fresh function for each of the different values at position `i`. -This transformation should work in the following way: - -``` - 1- Create a mapping decl2arg_map from declarations to tuples of booleans, an entry [f -> (true, false, true)] - means that f is a declaration with 3 arguments where the first and third arguments are always values. - 2- Traverse the formula and populate the mapping. - For each function application f(t1, ..., tn) do - a) Create a boolean tuple (is_value(t1), ..., is_value(tn)) and do - the logical-and with the tuple that is already in the mapping. If there is no such tuple - in the mapping, we just add a new entry. - - If all entries are false-tuples, then there is nothing to be done. The transformation is not applicable. - - Now, we create a mapping decl2new_decl from (decl, val_1, ..., val_n) to decls. Note that, n may be different for each entry, - but it is the same for the same declaration. - For example, suppose we have [f -> (true, false, true)] in decl2arg_map, - and applications f(1, a, 2), f(1, b, 2), f(1, b, 3), f(2, b, 3), f(2, c, 3) in the formula. - Then, decl2arg_map would contain - (f, 1, 2) -> f_1_2 - (f, 1, 3) -> f_1_3 - (f, 2, 3) -> f_2_3 - where f_1_2, f_1_3 and f_2_3 are new function symbols. - Using the new map, we can replace the occurrences of f. -``` ### Example diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/tactic/core/tseitin_cnf_tactic.cpp new/z3-z3-4.12.1/src/tactic/core/tseitin_cnf_tactic.cpp --- old/z3-z3-4.12.0/src/tactic/core/tseitin_cnf_tactic.cpp 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/tactic/core/tseitin_cnf_tactic.cpp 2023-01-18 04:10:26.000000000 +0100 @@ -865,11 +865,11 @@ void collect_param_descrs(param_descrs & r) override { insert_max_memory(r); - r.insert("common_patterns", CPK_BOOL, "(default: true) minimize the number of auxiliary variables during CNF encoding by identifing commonly used patterns"); - r.insert("distributivity", CPK_BOOL, "(default: true) minimize the number of auxiliary variables during CNF encoding by applying distributivity over unshared subformulas"); - r.insert("distributivity_blowup", CPK_UINT, "(default: 32) maximum overhead for applying distributivity during CNF encoding"); - r.insert("ite_chaing", CPK_BOOL, "(default: true) minimize the number of auxiliary variables during CNF encoding by identifing if-then-else chains"); - r.insert("ite_extra", CPK_BOOL, "(default: true) add redundant clauses (that improve unit propagation) when encoding if-then-else formulas"); + r.insert("common_patterns", CPK_BOOL, "minimize the number of auxiliary variables during CNF encoding by identifing commonly used patterns", "true"); + r.insert("distributivity", CPK_BOOL, "minimize the number of auxiliary variables during CNF encoding by applying distributivity over unshared subformulas", "true"); + r.insert("distributivity_blowup", CPK_UINT, "maximum overhead for applying distributivity during CNF encoding", "32"); + r.insert("ite_chaing", CPK_BOOL, "minimize the number of auxiliary variables during CNF encoding by identifing if-then-else chains", "true"); + r.insert("ite_extra", CPK_BOOL, "add redundant clauses (that improve unit propagation) when encoding if-then-else formulas", "true"); } void operator()(goal_ref const & in, goal_ref_buffer & result) override { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/tactic/fpa/fpa2bv_tactic.h new/z3-z3-4.12.1/src/tactic/fpa/fpa2bv_tactic.h --- old/z3-z3-4.12.0/src/tactic/fpa/fpa2bv_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/tactic/fpa/fpa2bv_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -5,15 +5,16 @@ fpa2bv_tactic.h -Abstract: - - Tactic that converts floating points to bit-vectors - Author: Christoph (cwinter) 2012-02-09 -Notes: +Tactic Documentation: + +## Tactic fpa2bv + +### Short Description +Converts floating points to bit-vector representation. --*/ #pragma once diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/tactic/fpa/qffp_tactic.h new/z3-z3-4.12.1/src/tactic/fpa/qffp_tactic.h --- old/z3-z3-4.12.0/src/tactic/fpa/qffp_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/tactic/fpa/qffp_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -13,8 +13,17 @@ Christoph (cwinter) 2012-01-16 -Notes: +Tactic Documentation: +## Tactic qffp + +### Short Description +Tactic for QF_FP formulas + +## Tactic qffpbv + +### Short Description +Tactic for QF_FPBV formulas --*/ #pragma once diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/z3-z3-4.12.0/src/tactic/fpa/qffplra_tactic.h new/z3-z3-4.12.1/src/tactic/fpa/qffplra_tactic.h --- old/z3-z3-4.12.0/src/tactic/fpa/qffplra_tactic.h 2023-01-14 15:24:26.000000000 +0100 +++ new/z3-z3-4.12.1/src/tactic/fpa/qffplra_tactic.h 2023-01-18 04:10:26.000000000 +0100 @@ -14,7 +14,8 @@ Christoph (cwinter) 2018-04-24 -Notes: + +## Tactic qffplra --*/